mirror of
https://github.com/mgerb/mywebsite
synced 2026-01-13 03:02:49 +00:00
138 lines
3.4 KiB
JavaScript
138 lines
3.4 KiB
JavaScript
"use strict";
|
|
const hasOwnProp = Object.prototype.hasOwnProperty;
|
|
const namedPropertiesTracker = require("../named-properties-tracker");
|
|
const NODE_TYPE = require("./node-type");
|
|
const createHTMLCollection = require("./html-collection").create;
|
|
const treeOrderSorter = require("../utils").treeOrderSorter;
|
|
|
|
function isNamedPropertyElement(element) {
|
|
// (for the name attribute)
|
|
|
|
// use hasOwnProperty to make sure contentWindow comes from the prototype,
|
|
// and is not set directly on the node by a script.
|
|
if ("contentWindow" in element && !hasOwnProp.call(element, "contentWindow")) {
|
|
return true;
|
|
}
|
|
|
|
switch (element.nodeName) {
|
|
case "A":
|
|
case "APPLET":
|
|
case "AREA":
|
|
case "EMBED":
|
|
case "FORM":
|
|
case "FRAMESET":
|
|
case "IMG":
|
|
case "OBJECT":
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function namedPropertyResolver(HTMLCollection, window, name, values) {
|
|
function getResult() {
|
|
const results = [];
|
|
|
|
for (const node of values().keys()) {
|
|
if (node.nodeType !== NODE_TYPE.ELEMENT_NODE) {
|
|
continue;
|
|
}
|
|
|
|
if (node.getAttribute("id") === name) {
|
|
results.push(node);
|
|
} else if (node.getAttribute("name") === name && isNamedPropertyElement(node)) {
|
|
results.push(node);
|
|
}
|
|
}
|
|
|
|
results.sort(treeOrderSorter);
|
|
|
|
return results;
|
|
}
|
|
|
|
const document = window._document;
|
|
const objects = createHTMLCollection(document.documentElement, getResult);
|
|
|
|
const length = objects.length;
|
|
for (let i = 0; i < length; ++i) {
|
|
const node = objects[i];
|
|
|
|
if ("contentWindow" in node && !hasOwnProp.call(node, "contentWindow")) {
|
|
return node.contentWindow;
|
|
}
|
|
}
|
|
|
|
if (length === 0) {
|
|
return undefined;
|
|
}
|
|
|
|
if (length === 1) {
|
|
return objects[0];
|
|
}
|
|
|
|
return objects;
|
|
}
|
|
|
|
exports.initializeWindow = function (window, HTMLCollection) {
|
|
namedPropertiesTracker.create(window, namedPropertyResolver.bind(null, HTMLCollection));
|
|
};
|
|
|
|
exports.elementAttributeModified = function (element, name, value, oldValue) {
|
|
if (!element._attached) {
|
|
return;
|
|
}
|
|
|
|
const useName = isNamedPropertyElement(element);
|
|
|
|
if (name === "id" || (name === "name" && useName)) {
|
|
const tracker = namedPropertiesTracker.get(element._ownerDocument._global);
|
|
|
|
// (tracker will be null if the document has no Window)
|
|
if (tracker) {
|
|
if (name === "id" && (!useName || element.getAttribute("name") !== oldValue)) {
|
|
tracker.untrack(oldValue, element);
|
|
}
|
|
|
|
if (name === "name" && element.getAttribute("id") !== oldValue) {
|
|
tracker.untrack(oldValue, element);
|
|
}
|
|
|
|
tracker.track(value, element);
|
|
}
|
|
}
|
|
};
|
|
|
|
exports.nodeAttachedToDocument = function (node) {
|
|
if (node.nodeType !== NODE_TYPE.ELEMENT_NODE) {
|
|
return;
|
|
}
|
|
|
|
const tracker = namedPropertiesTracker.get(node._ownerDocument._global);
|
|
if (!tracker) {
|
|
return;
|
|
}
|
|
|
|
tracker.track(node.getAttribute("id"), node);
|
|
|
|
if (isNamedPropertyElement(node)) {
|
|
tracker.track(node.getAttribute("name"), node);
|
|
}
|
|
};
|
|
|
|
exports.nodeDetachedFromDocument = function (node) {
|
|
if (node.nodeType !== NODE_TYPE.ELEMENT_NODE) {
|
|
return;
|
|
}
|
|
|
|
const tracker = namedPropertiesTracker.get(node._ownerDocument._global);
|
|
if (!tracker) {
|
|
return;
|
|
}
|
|
|
|
tracker.untrack(node.getAttribute("id"), node);
|
|
|
|
if (isNamedPropertyElement(node)) {
|
|
tracker.untrack(node.getAttribute("name"), node);
|
|
}
|
|
};
|