mirror of
https://github.com/SoPat712/videospeed.git
synced 2025-08-22 02:18:45 -04:00
imported shadowMutations from ally.js
This commit is contained in:
209
inject.js
209
inject.js
@@ -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) {
|
||||
|
Reference in New Issue
Block a user