mirror of
https://github.com/webrecorder/pywb.git
synced 2025-03-15 08:04:49 +01:00
191 lines
5.9 KiB
JavaScript
191 lines
5.9 KiB
JavaScript
|
import get from 'lodash-es/get';
|
||
|
|
||
|
/**
|
||
|
* @type {TestOverwatch}
|
||
|
*/
|
||
|
window.TestOverwatch = class TestOverwatch {
|
||
|
/**
|
||
|
* @param {Object} domStructure
|
||
|
*/
|
||
|
constructor(domStructure) {
|
||
|
/**
|
||
|
* @type {{document: Document, window: Window}}
|
||
|
*/
|
||
|
this.ownContextWinDoc = { window, document };
|
||
|
this.wbMessages = { load: false };
|
||
|
this.domStructure = domStructure;
|
||
|
|
||
|
/**
|
||
|
* @type {HTMLIFrameElement}
|
||
|
*/
|
||
|
this.sandbox = domStructure.sandbox;
|
||
|
window.addEventListener(
|
||
|
'message',
|
||
|
event => {
|
||
|
if (event.data) {
|
||
|
const { data } = event;
|
||
|
switch (data.wb_type) {
|
||
|
case 'load':
|
||
|
this.wbMessages.load =
|
||
|
this.wbMessages.load || data.readyState === 'complete';
|
||
|
this.domStructure.load.url.data = data.url;
|
||
|
this.domStructure.load.title.data = data.title;
|
||
|
this.domStructure.load.readyState.data = data.readyState;
|
||
|
break;
|
||
|
case 'replace-url':
|
||
|
this.wbMessages['replace-url'] = data;
|
||
|
this.domStructure.replaceURL.url.data = data.url;
|
||
|
this.domStructure.replaceURL.title.data = data.title;
|
||
|
break;
|
||
|
case 'title':
|
||
|
this.wbMessages.title = data.title;
|
||
|
this.domStructure.titleMsg.data = data.title;
|
||
|
break;
|
||
|
case 'hashchange':
|
||
|
this.domStructure.hashchange.data = data.title;
|
||
|
this.wbMessages.hashchange = data.hash;
|
||
|
break;
|
||
|
case 'cookie':
|
||
|
this.domStructure.cookie.domain = data.domain;
|
||
|
this.domStructure.cookie.cookie = data.cookie;
|
||
|
this.wbMessages.cookie = data;
|
||
|
break;
|
||
|
default:
|
||
|
this.domStructure.unknown.data = JSON.stringify(data);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
false
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* This function initializes the wombat in the sandbox and ads a single
|
||
|
* additional property to the sandbox's window WombatTestUtil, an object that provides
|
||
|
* any functionality required for tests. This is done in order to ensure testing
|
||
|
* environment purity.
|
||
|
*/
|
||
|
initSandbox() {
|
||
|
this.domStructure.reset();
|
||
|
this.wbMessages = { load: false };
|
||
|
this.sandbox.contentWindow._WBWombatInit(this.sandbox.contentWindow.wbinfo);
|
||
|
this.sandbox.contentWindow.WombatTestUtil = {
|
||
|
didWombatSendTheLoadMsg: () => this.wbMessages.load,
|
||
|
wombatSentTitleUpdate: () => this.wbMessages.title,
|
||
|
wombatSentReplaceUrlMsg: () => this.wbMessages['replace-url'],
|
||
|
createUntamperedWithElement: init => this.createElement(init),
|
||
|
getElementPropertyAsIs: (elem, prop) =>
|
||
|
this.getElementPropertyAsIs(elem, prop),
|
||
|
getElementNSPropertyAsIs: (elem, ns, prop) =>
|
||
|
this.getElementNSPropertyAsIs(elem, ns, prop),
|
||
|
getOriginalWinDomViaPath: objectPath =>
|
||
|
this.getOriginalWinDomViaPath(objectPath),
|
||
|
getViaPath: (obj, objectPath) => get(obj, objectPath),
|
||
|
getOriginalPropertyDescriptorFor: (elem, prop) =>
|
||
|
this.ownContextWinDoc.window.Reflect.getOwnPropertyDescriptor(
|
||
|
elem,
|
||
|
prop
|
||
|
),
|
||
|
getStylePropertyAsIs: (elem, prop) =>
|
||
|
this.getStylePropertyAsIs(elem, prop),
|
||
|
getCSSPropertyAsIs: (elem, prop) => this.getCSSPropertyAsIs(elem, prop)
|
||
|
};
|
||
|
}
|
||
|
|
||
|
maybeInitSandbox() {
|
||
|
if (this.sandbox.contentWindow.WB_wombat_location != null) return;
|
||
|
this.initSandbox();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Creates a DOM element(s) based on the supplied creation options.
|
||
|
* @param {Object} init - Options for new element creation
|
||
|
* @return {HTMLElement|Node} - The newly created element
|
||
|
*/
|
||
|
createElement(init) {
|
||
|
if (typeof init === 'string') {
|
||
|
return this.ownContextWinDoc.document.createElement(init);
|
||
|
}
|
||
|
if (init.tag === 'textNode') {
|
||
|
var tn = this.ownContextWinDoc.document.createTextNode(init.value || '');
|
||
|
if (init.ref) init.ref(tn);
|
||
|
return tn;
|
||
|
}
|
||
|
var elem = this.ownContextWinDoc.document.createElement(init.tag);
|
||
|
if (init.id) elem.id = init.id;
|
||
|
if (init.className) elem.className = init.className;
|
||
|
if (init.style) elem.style = init.style;
|
||
|
if (init.innerText) elem.innerText = init.innerText;
|
||
|
if (init.innerHTML) elem.innerHTML = init.innerHTML;
|
||
|
if (init.attributes) {
|
||
|
var atts = init.attributes;
|
||
|
for (var attributeName in atts) {
|
||
|
elem.setAttribute(attributeName, atts[attributeName]);
|
||
|
}
|
||
|
}
|
||
|
if (init.dataset) {
|
||
|
var dataset = init.dataset;
|
||
|
for (var dataName in dataset) {
|
||
|
elem.dataset[dataName] = dataset[dataName];
|
||
|
}
|
||
|
}
|
||
|
if (init.events) {
|
||
|
var events = init.events;
|
||
|
for (var eventName in events) {
|
||
|
elem.addEventListener(eventName, events[eventName]);
|
||
|
}
|
||
|
}
|
||
|
if (init.child) {
|
||
|
elem.appendChild(this.createElement(init.child));
|
||
|
}
|
||
|
if (init.children) {
|
||
|
var kids = init.children;
|
||
|
for (var i = 0; i < kids.length; i++) {
|
||
|
elem.appendChild(this.createElement(kids[i]));
|
||
|
}
|
||
|
}
|
||
|
if (init.ref) init.ref(elem);
|
||
|
return elem;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the value of an elements property bypassing wombat rewriting
|
||
|
* @param {Node} elem
|
||
|
* @param {string} prop
|
||
|
* @return {*}
|
||
|
*/
|
||
|
getElementPropertyAsIs(elem, prop) {
|
||
|
return this.ownContextWinDoc.window.Element.prototype.getAttribute.call(
|
||
|
elem,
|
||
|
prop
|
||
|
);
|
||
|
}
|
||
|
|
||
|
getElementNSPropertyAsIs(elem, ns, prop) {
|
||
|
return this.ownContextWinDoc.window.Element.prototype.getAttributeNS.call(
|
||
|
elem,
|
||
|
ns,
|
||
|
prop
|
||
|
);
|
||
|
}
|
||
|
|
||
|
getStylePropertyAsIs(elem, prop) {
|
||
|
var getter = this.ownContextWinDoc.window.CSSStyleDeclaration.prototype.__lookupGetter__(
|
||
|
prop
|
||
|
);
|
||
|
return getter.call(elem, prop);
|
||
|
}
|
||
|
|
||
|
getCSSPropertyAsIs(elem, prop) {
|
||
|
return this.ownContextWinDoc.window.CSSStyleDeclaration.prototype.getPropertyValue.call(
|
||
|
elem,
|
||
|
prop
|
||
|
);
|
||
|
}
|
||
|
|
||
|
getOriginalWinDomViaPath(objectPath) {
|
||
|
return get(this.ownContextWinDoc, objectPath);
|
||
|
}
|
||
|
};
|