diff options
author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2023-12-29 00:01:11 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-29 05:01:11 +0000 |
commit | 0a68020771fc5b9dd437a90d5aac5e8a0c66719b (patch) | |
tree | 48a0c4c25977343dd15da06e19807f332ca62ddb /ext/js | |
parent | d90d408279938d389019a8bed15c5eb95af7c8bc (diff) |
Fix google docs (#473)
* Add support for content script execution world
* Update manifest version to support world parameter in Chromium browsers
* Update google docs injection
* Reuse code for registration
* Add info
Diffstat (limited to 'ext/js')
-rw-r--r-- | ext/js/accessibility/accessibility-controller.js | 37 | ||||
-rw-r--r-- | ext/js/accessibility/google-docs-xray.js | 30 | ||||
-rw-r--r-- | ext/js/accessibility/google-docs.js | 61 | ||||
-rw-r--r-- | ext/js/background/script-manager.js | 5 |
4 files changed, 66 insertions, 67 deletions
diff --git a/ext/js/accessibility/accessibility-controller.js b/ext/js/accessibility/accessibility-controller.js index 2b352948..4dced51b 100644 --- a/ext/js/accessibility/accessibility-controller.js +++ b/ext/js/accessibility/accessibility-controller.js @@ -86,14 +86,13 @@ export class AccessibilityController { try { if (forceGoogleDocsHtmlRenderingAny) { if (await isContentScriptRegistered(id)) { return; } - /** @type {import('script-manager').RegistrationDetails} */ - const details = { - allFrames: true, - matches: ['*://docs.google.com/*'], - runAt: 'document_start', - js: ['js/accessibility/google-docs.js'] - }; - await registerContentScript(id, details); + try { + await this._registerGoogleDocsContentScript(id, false); + } catch (e) { + // Firefox doesn't support `world` field and will throw an error. + // In this case, use the xray vision version. + await this._registerGoogleDocsContentScript(id, true); + } } else { await unregisterContentScript(id); } @@ -101,5 +100,25 @@ export class AccessibilityController { log.error(e); } } -} + /** + * @param {string} id + * @param {boolean} xray + * @returns {Promise<void>} + */ + _registerGoogleDocsContentScript(id, xray) { + /** @type {import('script-manager').RegistrationDetails} */ + const details = { + allFrames: true, + matches: ['*://docs.google.com/*'], + runAt: 'document_start', + js: [ + xray ? + 'js/accessibility/google-docs-xray.js' : + 'js/accessibility/google-docs.js' + ] + }; + if (!xray) { details.world = 'MAIN'; } + return registerContentScript(id, details); + } +} diff --git a/ext/js/accessibility/google-docs-xray.js b/ext/js/accessibility/google-docs-xray.js new file mode 100644 index 00000000..ef293933 --- /dev/null +++ b/ext/js/accessibility/google-docs-xray.js @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2023 Yomitan Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +/** Entry point. */ +function main() { + /** @type {Window} */ + // @ts-expect-error - Firefox Xray vision + const window2 = window.wrappedJSObject; + if (!(typeof window2 === 'object' && window2 !== null)) { return; } + // The extension ID below is on an allow-list that is used on the Google Docs webpage. + // @ts-expect-error - Adding a property to the global object + // eslint-disable-next-line no-underscore-dangle + window2._docs_annotate_canvas_by_ext = 'ogmnaimimemjmbakcfefmnahgdfhfami'; +} + +main();
\ No newline at end of file diff --git a/ext/js/accessibility/google-docs.js b/ext/js/accessibility/google-docs.js index 4bc398ff..00266bb6 100644 --- a/ext/js/accessibility/google-docs.js +++ b/ext/js/accessibility/google-docs.js @@ -1,6 +1,5 @@ /* * Copyright (C) 2023 Yomitan Authors - * Copyright (C) 2021-2022 Yomichan Authors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,59 +15,7 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -(async () => { - // Reentrant check - // @ts-expect-error - Checking a property to the global object - if (self.googleDocsAccessibilitySetup) { return; } - // @ts-expect-error - Adding a property to the global object - self.googleDocsAccessibilitySetup = true; - - /** - * @template {import('api').ApiNames} TAction - * @template {import('api').ApiParams<TAction>} TParams - * @param {TAction} action - * @param {TParams} params - * @returns {Promise<import('api').ApiReturn<TAction>>} - */ - const invokeApi = (action, params) => { - return new Promise((resolve, reject) => { - chrome.runtime.sendMessage({action, params}, (response) => { - void chrome.runtime.lastError; - if (typeof response !== 'object' || response === null) { - reject(new Error('Unexpected response')); - } else if (typeof response.error !== 'undefined') { - reject(new Error('Invalid response')); - } else { - resolve(response.result); - } - }); - }); - }; - - const optionsContext = {depth: 0, url: location.href}; - /** @type {import('api').ApiReturn<'optionsGet'>} */ - let options; - try { - options = await invokeApi('optionsGet', {optionsContext}); - } catch (e) { - return; - } - - if (!options.accessibility.forceGoogleDocsHtmlRendering) { return; } - - // The extension ID below is on an allow-list that is used on the Google Docs webpage. - /* eslint-disable */ - // @ts-expect-error : Adding a property to the global object - const inject = () => { window._docs_annotate_canvas_by_ext = 'ogmnaimimemjmbakcfefmnahgdfhfami'; }; - /* eslint-enable */ - - let parent = document.head; - if (parent === null) { - parent = document.documentElement; - if (parent === null) { return; } - } - const script = document.createElement('script'); - script.textContent = `(${inject.toString()})();`; - parent.appendChild(script); - parent.removeChild(script); -})(); +// The extension ID below is on an allow-list that is used on the Google Docs webpage. +// @ts-expect-error - Adding a property to the global object +// eslint-disable-next-line no-underscore-dangle +window._docs_annotate_canvas_by_ext = 'ogmnaimimemjmbakcfefmnahgdfhfami'; diff --git a/ext/js/background/script-manager.js b/ext/js/background/script-manager.js index 1142121f..353c50e3 100644 --- a/ext/js/background/script-manager.js +++ b/ext/js/background/script-manager.js @@ -129,7 +129,7 @@ export async function unregisterContentScript(id) { * @returns {chrome.scripting.RegisteredContentScript} */ function createContentScriptRegistrationOptions(details, id) { - const {css, js, allFrames, matches, runAt} = details; + const {css, js, allFrames, matches, runAt, world} = details; /** @type {chrome.scripting.RegisteredContentScript} */ const options = { id: id, @@ -150,5 +150,8 @@ function createContentScriptRegistrationOptions(details, id) { if (typeof runAt !== 'undefined') { options.runAt = runAt; } + if (typeof world !== 'undefined') { + options.world = world; + } return options; } |