From 764ecca262669df5e3f30ba7d37b6ec43ba3d025 Mon Sep 17 00:00:00 2001 From: Jonathan Dawson Date: Sun, 10 Nov 2019 13:07:42 -0600 Subject: [PATCH] completely change the logic. keydown events and controls don't work --- inject.js | 235 ++++++------------------------------------------------ 1 file changed, 24 insertions(+), 211 deletions(-) diff --git a/inject.js b/inject.js index 3f64587..8e4ee3d 100644 --- a/inject.js +++ b/inject.js @@ -446,218 +446,31 @@ initializeWhenReady(childDocument); }); - // 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 - //look for video in shadowRoot for apple tv - if (document.querySelector('apple-tv-plus-player')) { - shadowMutations('apple-tv-plus-player', mutationCallback, {childList: true, subtree: true}) + function deepActiveElement() { + let a = document.activeElement; + while (a && a.shadowRoot && a.shadowRoot.activeElement) { + a = a.shadowRoot.activeElement; + } + return a; + } + var apple_tv = document.querySelector('apple-tv-plus-player') + if (apple_tv) { + var observer = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + if (mutation.attributeName == 'aria-hidden' && (apple_tv.getAttribute('aria-hidden') == 'false')) { + setTimeout(() => { + var node = deepActiveElement() + checkForVideo(node, node.parentNode || mutation.target, true); + }, 2000) + } + }); + }); + + observer.observe(apple_tv, { + attributes: true + }); + } }