/*
 * Copyright (c) 2018, 2026, Oracle and/or its affiliates.
 * Licensed under The Universal Permissive License (UPL), Version 1.0
 * as shown at https://oss.oracle.com/licenses/upl/
 */
const NodeType=require("./NodeTypes");const BAD_TAGS=["=","'","\"",",",".","/","\\",";",":","&","%","$","#","@","*"];var HtmlTree=function(nodeDeps,appContext,HtmlParser,domUtils){this._HtmlParser=HtmlParser;this._Dom=null;this._elemStack=[];this._DomUtils=domUtils;this._tabs=null;this._nodeDeps=nodeDeps;this._appContext=appContext;this._error=appContext.error;this._assert=appContext.assert;this._utils=this._appContext.utils};HtmlTree.prototype.walk=function(cb){var dom=this._Dom;var i;if(dom){for(i=0;i<dom.length;i++){this._walk2(dom[i],cb)}}cb.onEnd()};HtmlTree.prototype._walk2=function(node,cb){var tagName,attr,nt,nodePushed,inJsScript,i;if(this.isScriptTypescript(node)){return}nt=node.type;if(nt===NodeType.TAG||nt===NodeType.STYLE||nt===NodeType.SCRIPT){if(BAD_TAGS.includes(node.name.charAt(0))){return}this._elemStack.push(node);nodePushed=true;tagName=node.name;cb.onOpenTagname(node,tagName);inJsScript=this.isScriptExecutable(node);if(node.attribs){for(attr in node.attribs){cb.onAttribute(node,attr,node.attribs[attr])}}}else if(nt===NodeType.TEXT){cb.onText(node,node.data)}else if(nt===NodeType.COMMENT){cb.onComment(node,node.data)}else if(nt===NodeType.DIRECTIVE){if(node.data.charAt(0)==="?"){cb.onProcessingInstruction(node,node.data)}else{cb.onDirective(node,node.data)}}if(!inJsScript&&tagName!=="pre"&&nt!==NodeType.TEXT){if(node.children){for(i=0;i<node.children.length;i++){this._walk2(node.children[i],cb)}}}if(nodePushed){this._elemStack.pop()}};HtmlTree.prototype.getElemStack=function(){return this._elemStack};HtmlTree.prototype.dumpElemStack=function(){var i,s="",indent="  ";for(i=0;i<this._elemStack.length;i++){s+=i>0?"\n"+indent.repeat(i):"";s+=this._elemStack[i].name}return s};HtmlTree.prototype.getFirstTagNode=function(){var dom=this._Dom;var i,node,ret=null;if(dom){for(i=0;i<dom.length;i++){node=this._getFirstTagNode2(dom[i]);if(node){return node}}}return ret};HtmlTree.prototype._getFirstTagNode2=function(node){var nt,i;nt=node.type;if(nt===NodeType.TAG||nt===NodeType.STYLE||nt===NodeType.SCRIPT){return node}if(node.children){for(i=0;i<node.children.length;i++){node=this._getFirstTagNode2(node.children[i]);if(node){return node}}}return null};HtmlTree.prototype.getTopNode=function(){return this._Dom&&this._Dom.length>0?this._Dom[0]:null};HtmlTree.prototype.parse=function(pageText){var _self=this;this._Dom=null;this._data=pageText;var DomHandler=new this._HtmlParser.DomHandler(function(error,dom){if(error){_self._error("Parse Html tree error : "+error);return}else{_self._Dom=dom;_self._DomUtils.setDom(dom)}},{xmlMode:true,withStartIndices:true,withEndIndices:true,recognizeSelfClosing:true});var treeParser=new this._HtmlParser.Parser(DomHandler,{xmlMode:true,withStartIndices:true,withEndIndices:true,lowerCaseTags:false,lowerCaseAttributeNames:false,recognizeSelfClosing:true});treeParser.write(pageText);treeParser.end();this._applyParserFix1();this._applyParserFix2()};HtmlTree.prototype._applyParserFix1=function(){if(!this._Dom||this._Dom.length<2){return}if(this._Dom[0].type===NodeType.TEXT&&this._Dom[1].type===NodeType.DIRECTIVE){this._Dom[1].startIndex=this._Dom[0].endIndex}};HtmlTree.prototype._applyParserFix2=function(){var node;if(!this._Dom||this._Dom.length<1){return}node=this._Dom[0];if(node.type===NodeType.DIRECTIVE&&node.endIndex===null){node.endIndex=node.data.length}};HtmlTree.prototype.isScriptExecutable=function(scriptNode){var attribs=scriptNode.attribs;return scriptNode.type==NodeType.TAG&&scriptNode.name===NodeType.SCRIPT&&(!attribs||!attribs.type||attribs.type.indexOf("html")<0&&attribs.type.indexOf("typescript")<0)};HtmlTree.prototype.isScriptJSLink=function(scriptNode){var ret=null;var attribs=scriptNode.attribs;if(attribs.src){ret=attribs.src.toLowerCase().endsWith("js")?attribs.src:null}return ret};HtmlTree.prototype.isScriptTypescript=function(scriptNode){var attribs=scriptNode.attribs;return scriptNode.name===NodeType.SCRIPT&&attribs&&attribs.type&&attribs.type.indexOf("typescript")>=0};module.exports=HtmlTree;