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

519 lines
26 KiB
JavaScript
Raw Permalink Normal View History

"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;