Innovenergy_trunk/frontend/node_modules/testcafe-hammerhead/lib/processing/dom/index.js

519 lines
26 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
// -------------------------------------------------------------
// WARNING: this file is used by both the client and the server.
// Do not use any browser or node-specific API!
// -------------------------------------------------------------
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const internal_attributes_1 = __importDefault(require("../../processing/dom/internal-attributes"));
const class_name_1 = __importDefault(require("../../shadow-ui/class-name"));
const script_1 = require("../script");
const style_1 = __importDefault(require("../../processing/style"));
const url_1 = require("../../utils/url");
const string_trim_1 = __importDefault(require("../../utils/string-trim"));
const builtin_header_names_1 = __importDefault(require("../../request-pipeline/builtin-header-names"));
const namespaces_1 = require("./namespaces");
const attributes_1 = require("./attributes");
const CDATA_REG_EX = /^(\s)*\/\/<!\[CDATA\[([\s\S]*)\/\/\]\]>(\s)*$/;
const HTML_COMMENT_POSTFIX_REG_EX = /(\/\/[^\n]*|\n\s*)-->[^\n]*([\n\s]*)?$/;
const HTML_COMMENT_PREFIX_REG_EX = /^(\s)*<!--[^\n]*\n/;
const HTML_COMMENT_SIMPLE_POSTFIX_REG_EX = /-->\s*$/;
const JAVASCRIPT_PROTOCOL_REG_EX = /^\s*javascript\s*:/i;
const EXECUTABLE_SCRIPT_TYPES_REG_EX = /^\s*(application\/(x-)?(ecma|java)script|text\/(javascript(1\.[0-5])?|((x-)?ecma|x-java|js|live)script)|module)\s*$/i;
const SVG_XLINK_HREF_TAGS = [
'animate', 'animateColor', 'animateMotion', 'animateTransform', 'mpath', 'set',
'linearGradient', 'radialGradient', 'stop',
'a', 'altglyph', 'color-profile', 'cursor', 'feimage', 'filter', 'font-face-uri', 'glyphref', 'image',
'mpath', 'pattern', 'script', 'textpath', 'use', 'tref',
];
const INTEGRITY_ATTR_TAGS = ['script', 'link'];
const IFRAME_FLAG_TAGS = ['a', 'form', 'area', 'input', 'button'];
const PROCESSED_PRELOAD_LINK_CONTENT_TYPE = 'script';
const MODULE_PRELOAD_LINK_REL = 'modulepreload';
const ELEMENT_PROCESSED = 'hammerhead|element-processed';
const AUTOCOMPLETE_ATTRIBUTE_ABSENCE_MARKER = 'hammerhead|autocomplete-attribute-absence-marker';
class DomProcessor {
constructor(adapter) {
this.adapter = adapter;
this.HTML_PROCESSING_REQUIRED_EVENT = 'hammerhead|event|html-processing-required';
this.SVG_XLINK_HREF_TAGS = SVG_XLINK_HREF_TAGS;
this.AUTOCOMPLETE_ATTRIBUTE_ABSENCE_MARKER = AUTOCOMPLETE_ATTRIBUTE_ABSENCE_MARKER;
this.PROCESSED_PRELOAD_LINK_CONTENT_TYPE = PROCESSED_PRELOAD_LINK_CONTENT_TYPE;
this.MODULE_PRELOAD_LINK_REL = MODULE_PRELOAD_LINK_REL;
this.forceProxySrcForImage = false;
this.allowMultipleWindows = false;
this.proxyless = false;
this.EVENTS = this.adapter.EVENTS;
this.elementProcessorPatterns = this._createProcessorPatterns(this.adapter);
}
static isTagWithTargetAttr(tagName) {
return !!tagName && attributes_1.TARGET_ATTR_TAGS.target.indexOf(tagName) > -1;
}
static isTagWithFormTargetAttr(tagName) {
return !!tagName && attributes_1.TARGET_ATTR_TAGS.formtarget.indexOf(tagName) > -1;
}
static isTagWithIntegrityAttr(tagName) {
return !!tagName && INTEGRITY_ATTR_TAGS.indexOf(tagName) !== -1;
}
static isIframeFlagTag(tagName) {
return !!tagName && IFRAME_FLAG_TAGS.indexOf(tagName) !== -1;
}
static isAddedAutocompleteAttr(attrName, storedAttrValue) {
return attrName === 'autocomplete' && storedAttrValue === AUTOCOMPLETE_ATTRIBUTE_ABSENCE_MARKER;
}
static processJsAttrValue(value, { isJsProtocol, isEventAttr }) {
if (isJsProtocol)
value = value.replace(JAVASCRIPT_PROTOCOL_REG_EX, '');
value = (0, script_1.processScript)(value, false, isJsProtocol && !isEventAttr, void 0);
if (isJsProtocol)
value = 'javascript:' + value; // eslint-disable-line no-script-url
return value;
}
static getStoredAttrName(attr) {
return attr + internal_attributes_1.default.storedAttrPostfix;
}
static isJsProtocol(value) {
return JAVASCRIPT_PROTOCOL_REG_EX.test(value);
}
static _isHtmlImportLink(tagName, relAttr) {
return !!tagName && !!relAttr && tagName === 'link' && relAttr === 'import';
}
static isElementProcessed(el) {
// @ts-ignore
return el[ELEMENT_PROCESSED];
}
static setElementProcessed(el, processed) {
// @ts-ignore
el[ELEMENT_PROCESSED] = processed;
}
_getRelAttribute(el) {
return String(this.adapter.getAttr(el, 'rel')).toLowerCase();
}
_getAsAttribute(el) {
return String(this.adapter.getAttr(el, 'as')).toLowerCase();
}
_createProcessorPatterns(adapter) {
const selectors = {
HAS_HREF_ATTR: (el) => this.isUrlAttr(el, 'href'),
HAS_SRC_ATTR: (el) => this.isUrlAttr(el, 'src'),
HAS_SRCSET_ATTR: (el) => this.isUrlAttr(el, 'srcset'),
HAS_ACTION_ATTR: (el) => this.isUrlAttr(el, 'action'),
HAS_FORMACTION_ATTR: (el) => this.isUrlAttr(el, 'formaction'),
HAS_FORMTARGET_ATTR: (el) => {
return DomProcessor.isTagWithFormTargetAttr(adapter.getTagName(el)) && adapter.hasAttr(el, 'formtarget');
},
HAS_MANIFEST_ATTR: (el) => this.isUrlAttr(el, 'manifest'),
HAS_DATA_ATTR: (el) => this.isUrlAttr(el, 'data'),
HAS_SRCDOC_ATTR: (el) => {
const tagName = this.adapter.getTagName(el);
return (tagName === 'iframe' || tagName === 'frame') && adapter.hasAttr(el, 'srcdoc');
},
HTTP_EQUIV_META: (el) => {
const tagName = adapter.getTagName(el);
return tagName === 'meta' && adapter.hasAttr(el, 'http-equiv');
},
ALL: () => true,
IS_SCRIPT: (el) => adapter.getTagName(el) === 'script',
IS_LINK: (el) => adapter.getTagName(el) === 'link',
IS_INPUT: (el) => adapter.getTagName(el) === 'input',
IS_FILE_INPUT: (el) => {
return adapter.getTagName(el) === 'input' &&
adapter.hasAttr(el, 'type') &&
adapter.getAttr(el, 'type').toLowerCase() === 'file';
},
IS_STYLE: (el) => adapter.getTagName(el) === 'style',
HAS_EVENT_HANDLER: (el) => adapter.hasEventHandler(el),
IS_SANDBOXED_IFRAME: (el) => {
const tagName = adapter.getTagName(el);
return (tagName === 'iframe' || tagName === 'frame') && adapter.hasAttr(el, 'sandbox');
},
IS_SVG_ELEMENT_WITH_XLINK_HREF_ATTR: (el) => {
return adapter.isSVGElement(el) &&
adapter.hasAttr(el, 'xlink:href') &&
SVG_XLINK_HREF_TAGS.indexOf(adapter.getTagName(el)) !== -1;
},
IS_SVG_ELEMENT_WITH_XML_BASE_ATTR: (el) => adapter.isSVGElement(el) && adapter.hasAttr(el, 'xml:base'),
};
return [
{
selector: selectors.HAS_FORMTARGET_ATTR,
targetAttr: 'formtarget',
elementProcessors: [this._processTargetBlank],
},
{
selector: selectors.HAS_HREF_ATTR,
urlAttr: 'href',
targetAttr: 'target',
elementProcessors: [this._processTargetBlank, this._processUrlAttrs, this._processUrlJsAttr],
},
{
selector: selectors.HAS_SRC_ATTR,
urlAttr: 'src',
targetAttr: 'target',
elementProcessors: [this._processTargetBlank, this._processUrlAttrs, this._processUrlJsAttr],
},
{
selector: selectors.HAS_SRCSET_ATTR,
urlAttr: 'srcset',
targetAttr: 'target',
elementProcessors: [this._processTargetBlank, this._processUrlAttrs, this._processUrlJsAttr],
},
{
selector: selectors.HAS_ACTION_ATTR,
urlAttr: 'action',
targetAttr: 'target',
elementProcessors: [this._processTargetBlank, this._processUrlAttrs, this._processUrlJsAttr],
},
{
selector: selectors.HAS_FORMACTION_ATTR,
urlAttr: 'formaction',
targetAttr: 'formtarget',
elementProcessors: [this._processUrlAttrs, this._processUrlJsAttr],
},
{
selector: selectors.HAS_MANIFEST_ATTR,
urlAttr: 'manifest',
elementProcessors: [this._processUrlAttrs, this._processUrlJsAttr],
},
{
selector: selectors.HAS_DATA_ATTR,
urlAttr: 'data',
elementProcessors: [this._processUrlAttrs, this._processUrlJsAttr],
},
{
selector: selectors.HAS_SRCDOC_ATTR,
elementProcessors: [this._processSrcdocAttr],
},
{
selector: selectors.HTTP_EQUIV_META,
urlAttr: 'content',
elementProcessors: [this._processMetaElement],
},
{
selector: selectors.IS_SCRIPT,
elementProcessors: [this._processScriptElement, this._processIntegrityAttr],
},
{ selector: selectors.ALL, elementProcessors: [this._processStyleAttr] },
{
selector: selectors.IS_LINK,
relAttr: 'rel',
elementProcessors: [this._processIntegrityAttr, this._processRelPrefetch],
},
{ selector: selectors.IS_STYLE, elementProcessors: [this._processStylesheetElement] },
{ selector: selectors.IS_INPUT, elementProcessors: [this._processAutoComplete] },
{ selector: selectors.IS_FILE_INPUT, elementProcessors: [this._processRequired] },
{ selector: selectors.HAS_EVENT_HANDLER, elementProcessors: [this._processEvtAttr] },
{ selector: selectors.IS_SANDBOXED_IFRAME, elementProcessors: [this._processSandboxedIframe] },
{
selector: selectors.IS_SVG_ELEMENT_WITH_XLINK_HREF_ATTR,
urlAttr: 'xlink:href',
elementProcessors: [this._processSVGXLinkHrefAttr, this._processUrlAttrs],
},
{
selector: selectors.IS_SVG_ELEMENT_WITH_XML_BASE_ATTR,
urlAttr: 'xml:base',
elementProcessors: [this._processUrlAttrs],
},
];
}
// API
processElement(el, urlReplacer) {
if (DomProcessor.isElementProcessed(el))
return;
for (const pattern of this.elementProcessorPatterns) {
if (pattern.selector(el) && !this._isShadowElement(el)) {
for (const processor of pattern.elementProcessors)
processor.call(this, el, urlReplacer, pattern);
DomProcessor.setElementProcessed(el, true);
}
}
}
// Utils
getElementResourceType(el) {
const tagName = this.adapter.getTagName(el);
if (tagName === 'link' && (this._getAsAttribute(el) === PROCESSED_PRELOAD_LINK_CONTENT_TYPE ||
this._getRelAttribute(el) === MODULE_PRELOAD_LINK_REL))
return (0, url_1.getResourceTypeString)({ isScript: true });
return (0, url_1.getResourceTypeString)({
isIframe: tagName === 'iframe' || tagName === 'frame' || this._isOpenLinkInIframe(el),
isForm: tagName === 'form' || tagName === 'input' || tagName === 'button',
isScript: tagName === 'script',
isHtmlImport: tagName === 'link' && this._getRelAttribute(el) === 'import',
isObject: tagName === 'object',
});
}
isUrlAttr(el, attr, ns) {
const tagName = this.adapter.getTagName(el);
attr = attr ? attr.toLowerCase() : attr;
// @ts-ignore
if (attributes_1.URL_ATTR_TAGS[attr] && attributes_1.URL_ATTR_TAGS[attr].indexOf(tagName) !== -1)
return true;
return this.adapter.isSVGElement(el) && (attr === 'xml:base' || attr === 'base' && ns === namespaces_1.XML_NAMESPACE);
}
getUrlAttr(el) {
const tagName = this.adapter.getTagName(el);
for (const urlAttr of attributes_1.URL_ATTRS) {
// @ts-ignore
if (attributes_1.URL_ATTR_TAGS[urlAttr].indexOf(tagName) !== -1)
return urlAttr;
}
return null;
}
getTargetAttr(el) {
const tagName = this.adapter.getTagName(el);
for (const targetAttr of attributes_1.TARGET_ATTRS) {
// @ts-ignore
if (attributes_1.TARGET_ATTR_TAGS[targetAttr].indexOf(tagName) > -1)
return targetAttr;
}
return null;
}
_isOpenLinkInIframe(el) {
const tagName = this.adapter.getTagName(el);
const targetAttr = this.getTargetAttr(el);
const target = targetAttr ? this.adapter.getAttr(el, targetAttr) : null;
const rel = this._getRelAttribute(el);
if (target !== '_top') {
const isImageInput = tagName === 'input' && this.adapter.getAttr(el, 'type') === 'image';
const mustProcessTag = !isImageInput && DomProcessor.isIframeFlagTag(tagName) ||
DomProcessor._isHtmlImportLink(tagName, rel);
const isNameTarget = target ? target[0] !== '_' : false;
if (target === '_parent')
return mustProcessTag && !this.adapter.isTopParentIframe(el);
if (mustProcessTag && (this.adapter.hasIframeParent(el) || isNameTarget && this.adapter.isExistingTarget(target, el)))
return true;
}
return false;
}
_isShadowElement(el) {
const className = this.adapter.getClassName(el);
return typeof className === 'string' && className.indexOf(class_name_1.default.postfix) > -1;
}
// Element processors
_processAutoComplete(el) {
const storedUrlAttr = DomProcessor.getStoredAttrName('autocomplete');
const processed = this.adapter.hasAttr(el, storedUrlAttr);
const attrValue = this.adapter.getAttr(el, processed ? storedUrlAttr : 'autocomplete');
if (!processed) {
this.adapter.setAttr(el, storedUrlAttr, attrValue || attrValue ===
''
? attrValue
: AUTOCOMPLETE_ATTRIBUTE_ABSENCE_MARKER);
}
this.adapter.setAttr(el, 'autocomplete', 'off');
}
_processRequired(el) {
const storedRequired = DomProcessor.getStoredAttrName('required');
const processed = this.adapter.hasAttr(el, storedRequired);
if (!processed && this.adapter.hasAttr(el, 'required')) {
const attrValue = this.adapter.getAttr(el, 'required');
this.adapter.setAttr(el, storedRequired, attrValue);
this.adapter.removeAttr(el, 'required');
}
}
// NOTE: We simply remove the 'integrity' attribute because its value will not be relevant after the script
// content changes (http://www.w3.org/TR/SRI/). If this causes problems in the future, we will need to generate
// the correct SHA for the changed script.
// In addition, we create stored 'integrity' attribute with the current 'integrity' attribute value. (GH-235)
_processIntegrityAttr(el) {
const storedIntegrityAttr = DomProcessor.getStoredAttrName('integrity');
const processed = this.adapter.hasAttr(el, storedIntegrityAttr) && !this.adapter.hasAttr(el, 'integrity');
const attrValue = this.adapter.getAttr(el, processed ? storedIntegrityAttr : 'integrity');
if (attrValue)
this.adapter.setAttr(el, storedIntegrityAttr, attrValue);
if (!processed)
this.adapter.removeAttr(el, 'integrity');
}
// NOTE: We simply remove the 'rel' attribute if rel='prefetch' and use stored 'rel' attribute, because the prefetch
// resource type is unknown. https://github.com/DevExpress/testcafe/issues/2528
_processRelPrefetch(el, _urlReplacer, pattern) {
if (!pattern.relAttr)
return;
const storedRelAttr = DomProcessor.getStoredAttrName(pattern.relAttr);
const processed = this.adapter.hasAttr(el, storedRelAttr) && !this.adapter.hasAttr(el, pattern.relAttr);
const attrValue = this.adapter.getAttr(el, processed ? storedRelAttr : pattern.relAttr);
if (attrValue) {
const formatedValue = (0, string_trim_1.default)(attrValue.toLowerCase());
if (formatedValue === 'prefetch') {
this.adapter.setAttr(el, storedRelAttr, attrValue);
if (!processed)
this.adapter.removeAttr(el, pattern.relAttr);
}
}
}
_processJsAttr(el, attrName, { isJsProtocol, isEventAttr }) {
const storedUrlAttr = DomProcessor.getStoredAttrName(attrName);
const processed = this.adapter.hasAttr(el, storedUrlAttr);
const attrValue = this.adapter.getAttr(el, processed ? storedUrlAttr : attrName) || '';
const processedValue = DomProcessor.processJsAttrValue(attrValue, { isJsProtocol, isEventAttr });
if (attrValue !== processedValue) {
this.adapter.setAttr(el, storedUrlAttr, attrValue);
this.adapter.setAttr(el, attrName, processedValue);
}
}
_processEvtAttr(el) {
const events = this.adapter.EVENTS;
for (let i = 0; i < events.length; i++) {
const attrValue = this.adapter.getAttr(el, events[i]);
if (attrValue) {
this._processJsAttr(el, events[i], {
isJsProtocol: DomProcessor.isJsProtocol(attrValue),
isEventAttr: true,
});
}
}
}
_processMetaElement(el, urlReplacer, pattern) {
const httpEquivAttrValue = (this.adapter.getAttr(el, 'http-equiv') || '').toLowerCase();
if (httpEquivAttrValue === builtin_header_names_1.default.refresh && pattern.urlAttr) {
let attr = this.adapter.getAttr(el, pattern.urlAttr) || '';
attr = (0, url_1.processMetaRefreshContent)(attr, urlReplacer);
this.adapter.setAttr(el, pattern.urlAttr, attr);
}
// TODO: remove after https://github.com/DevExpress/testcafe-hammerhead/issues/244 implementation
else if (httpEquivAttrValue === builtin_header_names_1.default.contentSecurityPolicy) {
this.adapter.removeAttr(el, 'http-equiv');
this.adapter.removeAttr(el, 'content');
}
}
_processSandboxedIframe(el) {
let attrValue = this.adapter.getAttr(el, 'sandbox') || '';
const allowSameOrigin = attrValue.indexOf('allow-same-origin') !== -1;
const allowScripts = attrValue.indexOf('allow-scripts') !== -1;
const storedAttr = DomProcessor.getStoredAttrName('sandbox');
this.adapter.setAttr(el, storedAttr, attrValue);
if (!allowSameOrigin || !allowScripts) {
attrValue += !allowSameOrigin ? ' allow-same-origin' : '';
attrValue += !allowScripts ? ' allow-scripts' : '';
}
this.adapter.setAttr(el, 'sandbox', attrValue);
}
_processScriptElement(script, urlReplacer) {
const scriptContent = this.adapter.getScriptContent(script);
if (!scriptContent || !this.adapter.needToProcessContent(script))
return;
const scriptProcessedOnServer = (0, script_1.isScriptProcessed)(scriptContent);
if (scriptProcessedOnServer)
return;
// NOTE: We do not process scripts that are not executed during page load. We process scripts of types like
// text/javascript, application/javascript etc. (a complete list of MIME types is specified in the w3c.org
// html5 specification). If the type is not set, it is considered 'text/javascript' by default.
const scriptType = this.adapter.getAttr(script, 'type');
const isExecutableScript = !scriptType || EXECUTABLE_SCRIPT_TYPES_REG_EX.test(scriptType);
if (isExecutableScript) {
let result = scriptContent;
let commentPrefix = '';
const commentPrefixMatch = result.match(HTML_COMMENT_PREFIX_REG_EX);
let commentPostfix = '';
let commentPostfixMatch = null;
const hasCDATA = CDATA_REG_EX.test(result);
if (commentPrefixMatch) {
commentPrefix = commentPrefixMatch[0];
commentPostfixMatch = result.match(HTML_COMMENT_POSTFIX_REG_EX);
if (commentPostfixMatch)
commentPostfix = commentPostfixMatch[0];
else if (!HTML_COMMENT_SIMPLE_POSTFIX_REG_EX.test(commentPrefix))
commentPostfix = '//-->';
result = result.replace(commentPrefix, '').replace(commentPostfix, '');
}
if (hasCDATA)
result = result.replace(CDATA_REG_EX, '$2');
result = commentPrefix + (0, script_1.processScript)(result, true, false, urlReplacer) + commentPostfix;
if (hasCDATA)
result = '\n//<![CDATA[\n' + result + '//]]>';
this.adapter.setScriptContent(script, result);
}
}
_processStyleAttr(el, urlReplacer) {
const style = this.adapter.getAttr(el, 'style');
if (style)
this.adapter.setAttr(el, 'style', style_1.default.process(style, urlReplacer, false));
}
_processStylesheetElement(el, urlReplacer) {
let content = this.adapter.getStyleContent(el);
if (content && urlReplacer && this.adapter.needToProcessContent(el)) {
content = style_1.default.process(content, urlReplacer, true);
this.adapter.setStyleContent(el, content);
}
}
_processTargetBlank(el, _urlReplacer, pattern) {
if (this.allowMultipleWindows || !pattern.targetAttr)
return;
const storedTargetAttr = DomProcessor.getStoredAttrName(pattern.targetAttr);
const processed = this.adapter.hasAttr(el, storedTargetAttr);
if (processed)
return;
let attrValue = this.adapter.getAttr(el, pattern.targetAttr);
// NOTE: Value may have whitespace.
attrValue = attrValue && attrValue.replace(/\s/g, '');
if (attrValue === '_blank') {
this.adapter.setAttr(el, pattern.targetAttr, '_top');
this.adapter.setAttr(el, storedTargetAttr, attrValue);
}
}
_processUrlAttrs(el, urlReplacer, pattern) {
if (!pattern.urlAttr || this.proxyless)
return;
const storedUrlAttr = DomProcessor.getStoredAttrName(pattern.urlAttr);
const resourceUrl = this.adapter.getAttr(el, pattern.urlAttr);
const isSpecialPageUrl = !!resourceUrl && (0, url_1.isSpecialPage)(resourceUrl);
const processedOnServer = this.adapter.hasAttr(el, storedUrlAttr);
if ((!resourceUrl && resourceUrl !== '' || processedOnServer) || //eslint-disable-line @typescript-eslint/no-extra-parens
!(0, url_1.isSupportedProtocol)(resourceUrl) && !isSpecialPageUrl)
return;
const elTagName = this.adapter.getTagName(el);
const isIframe = elTagName === 'iframe' || elTagName === 'frame';
const isScript = elTagName === 'script';
const isAnchor = elTagName === 'a';
const isUrlsSet = pattern.urlAttr === 'srcset';
const target = pattern.targetAttr ? this.adapter.getAttr(el, pattern.targetAttr) : null;
// NOTE: Elements with target=_parent shouldnt be processed on the server,because we don't
// know what is the parent of the processed page (an iframe or the top window).
if (!this.adapter.needToProcessUrl(elTagName, target || ''))
return;
const resourceType = this.getElementResourceType(el) || '';
const parsedResourceUrl = (0, url_1.parseUrl)(resourceUrl);
const isRelativePath = parsedResourceUrl.protocol !== 'file:' && !parsedResourceUrl.host;
const charsetAttrValue = isScript && this.adapter.getAttr(el, 'charset') || '';
const isImgWithoutSrc = elTagName === 'img' && resourceUrl === '';
const isIframeWithEmptySrc = isIframe && resourceUrl === '';
const parsedProxyUrl = (0, url_1.parseProxyUrl)(urlReplacer('/'));
let isCrossDomainSrc = false;
let proxyUrl = resourceUrl;
// NOTE: Only a non-relative iframe src can be cross-domain.
if (isIframe && !isSpecialPageUrl && !isRelativePath && parsedProxyUrl)
isCrossDomainSrc = !this.adapter.sameOriginCheck(parsedProxyUrl.destUrl, resourceUrl);
if ((!isSpecialPageUrl || isAnchor) && !isImgWithoutSrc && !isIframeWithEmptySrc) {
proxyUrl = elTagName === 'img' && !this.forceProxySrcForImage && !isUrlsSet
? (0, url_1.resolveUrlAsDest)(resourceUrl, urlReplacer)
: urlReplacer(resourceUrl, resourceType, charsetAttrValue, isCrossDomainSrc, isUrlsSet);
}
this.adapter.setAttr(el, storedUrlAttr, resourceUrl);
this.adapter.setAttr(el, pattern.urlAttr, proxyUrl);
}
_processSrcdocAttr(el) {
const storedAttr = DomProcessor.getStoredAttrName('srcdoc');
const html = this.adapter.getAttr(el, 'srcdoc') || '';
const processedHtml = this.adapter.processSrcdocAttr(html);
this.adapter.setAttr(el, storedAttr, html);
this.adapter.setAttr(el, 'srcdoc', processedHtml);
}
_processUrlJsAttr(el, _urlReplacer, pattern) {
if (pattern.urlAttr && DomProcessor.isJsProtocol(this.adapter.getAttr(el, pattern.urlAttr) || ''))
this._processJsAttr(el, pattern.urlAttr, { isJsProtocol: true, isEventAttr: false });
}
_processSVGXLinkHrefAttr(el, _urlReplacer, pattern) {
if (!pattern.urlAttr)
return;
const attrValue = this.adapter.getAttr(el, pattern.urlAttr) || '';
if (url_1.HASH_RE.test(attrValue)) {
const storedUrlAttr = DomProcessor.getStoredAttrName(pattern.urlAttr);
this.adapter.setAttr(el, storedUrlAttr, attrValue);
}
}
}
exports.default = DomProcessor;module.exports = exports.default;