"use strict"; const vm = require("vm"); const whatwgEncoding = require("whatwg-encoding"); const HTMLElementImpl = require("./HTMLElement-impl").implementation; const reflectURLAttribute = require("../../utils").reflectURLAttribute; const resourceLoader = require("../../browser/resource-loader"); const reportException = require("../helpers/runtime-script-errors"); const domSymbolTree = require("../helpers/internal-constants").domSymbolTree; const nodeTypes = require("../node-type"); const jsMIMETypes = new Set([ "application/ecmascript", "application/javascript", "application/x-ecmascript", "application/x-javascript", "text/ecmascript", "text/javascript", "text/javascript1.0", "text/javascript1.1", "text/javascript1.2", "text/javascript1.3", "text/javascript1.4", "text/javascript1.5", "text/jscript", "text/livescript", "text/x-ecmascript", "text/x-javascript" ]); class HTMLScriptElementImpl extends HTMLElementImpl { _attach() { super._attach(); if (this.src) { resourceLoader.load( this, this.src, { defaultEncoding: whatwgEncoding.labelToName(this.getAttribute("charset")) || this._ownerDocument._encoding }, this._eval ); } else if (this.text.trim().length > 0) { resourceLoader.enqueue(this, this._ownerDocument.URL, this._eval)(null, this.text); } } _attrModified(name, value, oldValue) { super._attrModified(name, value, oldValue); if (this._attached && name === "src" && oldValue === null && value !== null) { resourceLoader.load( this, this.src, { defaultEncoding: whatwgEncoding.labelToName(this.getAttribute("charset")) || this._ownerDocument._encoding }, this._eval ); } } _eval(text, filename) { const typeString = this._getTypeString(); if (this._ownerDocument.implementation._hasFeature("ProcessExternalResources", "script") && jsMIMETypes.has(typeString.toLowerCase())) { this._ownerDocument._writeAfterElement = this; processJavaScript(this, text, filename); delete this._ownerDocument._writeAfterElement; } } _getTypeString() { const typeAttr = this.getAttribute("type"); const langAttr = this.getAttribute("language"); if (typeAttr === "") { return "text/javascript"; } if (typeAttr === null && langAttr === "") { return "text/javascript"; } if (typeAttr === null && langAttr === null) { return "text/javascript"; } if (typeAttr !== null) { return typeAttr.trim(); } if (langAttr !== null) { return "text/" + langAttr; } return null; } get text() { let text = ""; for (const child of domSymbolTree.childrenIterator(this)) { if (child.nodeType === nodeTypes.TEXT_NODE) { text += child.nodeValue; } } return text; } set text(text) { this.textContent = text; } get src() { return reflectURLAttribute(this, "src"); } set src(V) { this.setAttribute("src", V); } } function processJavaScript(element, code, filename) { const document = element.ownerDocument; const window = document && document._global; if (window) { document._currentScript = element; try { vm.runInContext(code, window, { filename, displayErrors: false }); } catch (e) { reportException(window, e, filename); } finally { document._currentScript = null; } } } module.exports = { implementation: HTMLScriptElementImpl };