imported shadowMutations from ally.js

This commit is contained in:
Jonathan Dawson
2019-11-09 12:38:18 -06:00
parent 71c11ddeb8
commit f5280b44af

209
inject.js
View File

@@ -449,6 +449,215 @@
if (document.querySelector('apple-tv-plus-player')) {
console.log('Congratulations. There is the apple-tv-plus-player.')
}
// start of ally.js/src/observe/shadow-mutations.js
// import nodeArray from '../util/node-array';
// input may be undefined, selector-tring, Node, NodeList, HTMLCollection, array of Nodes
// yes, to some extent this is a bad replica of jQuery's constructor function
function nodeArray(input) {
if (!input) {
return [];
}
if (Array.isArray(input)) {
return input;
}
// instanceof Node - does not work with iframes
if (input.nodeType !== undefined) {
return [input];
}
if (typeof input === 'string') {
input = document.querySelectorAll(input);
}
if (input.length !== undefined) {
return [].slice.call(input, 0);
}
throw new TypeError('unexpected input ' + String(input));
}
//import queryShadowHosts from '../query/shadow-hosts';
//import contextToElement from '../util/context-to-element';
//import nodeArray from '../util/node-array'; already imported
function contextToElement({
context,
label = 'context-to-element',
resolveDocument,
defaultToDocument,
}) {
let element = nodeArray(context)[0];
if (resolveDocument && element && element.nodeType === Node.DOCUMENT_NODE) {
element = element.documentElement;
}
if (!element && defaultToDocument) {
return document.documentElement;
}
if (!element) {
throw new TypeError(label + ' requires valid options.context');
}
if (element.nodeType !== Node.ELEMENT_NODE && element.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) {
throw new TypeError(label + ' requires options.context to be an Element');
}
return element;
}
//import getDocument from '../util/get-document';
function getDocument(node) {
if (!node) {
return document;
}
if (node.nodeType === Node.DOCUMENT_NODE) {
return node;
}
return node.ownerDocument || document;
}
// see https://developer.mozilla.org/en-US/docs/Web/API/NodeFilter
const filter = function(node) {
if (node.shadowRoot) {
return NodeFilter.FILTER_ACCEPT;
}
return NodeFilter.FILTER_SKIP;
};
// IE requires a function, Browsers require {acceptNode: function}
// see http://www.bennadel.com/blog/2607-finding-html-comment-nodes-in-the-dom-using-treewalker.htm
filter.acceptNode = filter;
function queryShadowHosts({ context } = {}) {
const element = contextToElement({
label: 'query/shadow-hosts',
resolveDocument: true,
defaultToDocument: true,
context,
});
const _document = getDocument(context);
// see https://developer.mozilla.org/en-US/docs/Web/API/Document/createTreeWalker
const walker = _document.createTreeWalker(
// root element to start search in
element,
// element type filter
NodeFilter.SHOW_ELEMENT,
// custom NodeFilter filter
filter,
// deprecated, but IE requires it
false
);
let list = [];
if (element.shadowRoot) {
// TreeWalker does not run the filter on the context element
list.push(element);
list = list.concat(queryShadowHosts({
context: element.shadowRoot,
}));
}
while (walker.nextNode()) {
list.push(walker.currentNode);
list = list.concat(queryShadowHosts({
context: walker.currentNode.shadowRoot,
}));
}
return list;
}
//import contextToElement from '../util/context-to-element'; already imported
const shadowObserverConfig = {
childList: true,
subtree: true,
};
class ShadowMutationObserver {
constructor({context, callback, config} = {}) {
this.config = config;
this.disengage = this.disengage.bind(this);
this.clientObserver = new MutationObserver(callback);
this.hostObserver = new MutationObserver(mutations => mutations.forEach(this.handleHostMutation, this));
this.observeContext(context);
this.observeShadowHosts(context);
}
disengage() {
this.clientObserver && this.clientObserver.disconnect();
this.clientObserver = null;
this.hostObserver && this.hostObserver.disconnect();
this.hostObserver = null;
}
observeShadowHosts(context) {
const hosts = queryShadowHosts({
context,
});
hosts.forEach(element => this.observeContext(element.shadowRoot));
}
observeContext(context) {
this.clientObserver.observe(context, this.config);
this.hostObserver.observe(context, shadowObserverConfig);
}
handleHostMutation(mutation) {
if (mutation.type !== 'childList') {
return;
}
const addedElements = nodeArray(mutation.addedNodes).filter(element => element.nodeType === Node.ELEMENT_NODE);
addedElements.forEach(this.observeShadowHosts, this);
}
}
function shadowMutations(context, callback, config) {
if (typeof callback !== 'function') {
throw new TypeError('observe/shadow-mutations requires options.callback to be a function');
}
if (typeof config !== 'object') {
throw new TypeError('observe/shadow-mutations requires options.config to be an object');
}
if (!window.MutationObserver) {
// not supporting IE10 via Mutation Events, because they're too expensive
// https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Mutation_events
return {
disengage: function() {},
};
}
const element = contextToElement({
label: 'observe/shadow-mutations',
resolveDocument: true,
defaultToDocument: true,
context,
});
const service = new ShadowMutationObserver({
context: element,
callback,
config,
});
return {
disengage: service.disengage,
};
}
//end of ally.js/src/observe/shadow-mutations.js
}
function runAction(action, document, value, e) {