summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortoasted-nutbread <toasted-nutbread@users.noreply.github.com>2021-08-07 12:40:51 -0400
committerGitHub <noreply@github.com>2021-08-07 12:40:51 -0400
commit5d4141a429dad23d78238f67ef61baabd251e67c (patch)
tree7e9875b3fb576d714204bb42e9c9ce862ec3c0a0
parentad31b70b67be6a8a3d53769dacc748aa850330bc (diff)
Google Docs accessibility (#1875)
* Add accessibility option for forcing Google Docs HTML-based rendering * Update settings * Send a documentStart message at document start * Add accessibility script for Google Docs * Set up accessibility * Update tests
-rw-r--r--.eslintrc.json2
-rw-r--r--dev/data/manifest-variants.json16
-rw-r--r--ext/data/schemas/options-schema.json15
-rw-r--r--ext/js/accessibility/google-docs.js27
-rw-r--r--ext/js/background/backend.js36
-rw-r--r--ext/js/data/options-util.js14
-rw-r--r--ext/js/document-start.js18
-rw-r--r--ext/manifest.json16
-rw-r--r--ext/settings.html34
-rw-r--r--test/test-options-util.js5
10 files changed, 177 insertions, 6 deletions
diff --git a/.eslintrc.json b/.eslintrc.json
index 4ec8f0f6..48746bdb 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -120,6 +120,7 @@
"files": ["ext/**/*.js"],
"excludedFiles": [
"ext/js/core.js",
+ "ext/js/document-start.js",
"ext/js/**/sandbox/**/*.js"
],
"globals": {
@@ -146,6 +147,7 @@
"files": ["ext/**/*.js"],
"excludedFiles": [
"ext/js/core.js",
+ "ext/js/document-start.js",
"ext/js/yomichan.js",
"ext/js/**/sandbox/**/*.js"
],
diff --git a/dev/data/manifest-variants.json b/dev/data/manifest-variants.json
index 52581350..0de348b9 100644
--- a/dev/data/manifest-variants.json
+++ b/dev/data/manifest-variants.json
@@ -33,11 +33,14 @@
},
"content_scripts": [
{
+ "run_at": "document_idle",
"matches": [
"http://*/*",
"https://*/*",
"file://*/*"
],
+ "match_about_blank": true,
+ "all_frames": true,
"js": [
"js/core.js",
"js/yomichan.js",
@@ -59,9 +62,20 @@
"js/language/text-scanner.js",
"js/script/dynamic-loader.js",
"js/app/content-script-main.js"
+ ]
+ },
+ {
+ "run_at": "document_start",
+ "matches": [
+ "http://*/*",
+ "https://*/*",
+ "file://*/*"
],
"match_about_blank": true,
- "all_frames": true
+ "all_frames": true,
+ "js": [
+ "js/document-start.js"
+ ]
}
],
"minimum_chrome_version": "57.0.0.0",
diff --git a/ext/data/schemas/options-schema.json b/ext/data/schemas/options-schema.json
index 1565cfe6..d1fb28ad 100644
--- a/ext/data/schemas/options-schema.json
+++ b/ext/data/schemas/options-schema.json
@@ -72,7 +72,8 @@
"anki",
"sentenceParsing",
"inputs",
- "clipboard"
+ "clipboard",
+ "accessibility"
],
"properties": {
"general": {
@@ -1109,6 +1110,18 @@
"minimum": 0
}
}
+ },
+ "accessibility": {
+ "type": "object",
+ "required": [
+ "forceGoogleDocsHtmlRendering"
+ ],
+ "properties": {
+ "forceGoogleDocsHtmlRendering": {
+ "type": "boolean",
+ "default": false
+ }
+ }
}
}
}
diff --git a/ext/js/accessibility/google-docs.js b/ext/js/accessibility/google-docs.js
new file mode 100644
index 00000000..f9ba0f7f
--- /dev/null
+++ b/ext/js/accessibility/google-docs.js
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2021 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
+ * 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/>.
+ */
+
+(() => {
+ let parent = document.head;
+ if (parent === null) {
+ parent = document.documentElement;
+ if (parent === null) { return; }
+ }
+ const script = document.createElement('script');
+ script.textContent = 'window._docs_force_html_by_ext = true;';
+ parent.appendChild(script);
+})();
diff --git a/ext/js/background/backend.js b/ext/js/background/backend.js
index 623f3612..b4b9bc27 100644
--- a/ext/js/background/backend.js
+++ b/ext/js/background/backend.js
@@ -124,7 +124,8 @@ class Backend {
['isTabSearchPopup', {async: true, contentScript: true, handler: this._onApiIsTabSearchPopup.bind(this)}],
['triggerDatabaseUpdated', {async: false, contentScript: true, handler: this._onApiTriggerDatabaseUpdated.bind(this)}],
['testMecab', {async: true, contentScript: true, handler: this._onApiTestMecab.bind(this)}],
- ['textHasJapaneseCharacters', {async: false, contentScript: true, handler: this._onApiTextHasJapaneseCharacters.bind(this)}]
+ ['textHasJapaneseCharacters', {async: false, contentScript: true, handler: this._onApiTextHasJapaneseCharacters.bind(this)}],
+ ['documentStart', {async: false, contentScript: true, handler: this._onDocumentStart.bind(this)}]
]);
this._messageHandlersWithProgress = new Map([
]);
@@ -745,6 +746,12 @@ class Backend {
return this._japaneseUtil.isStringPartiallyJapanese(text);
}
+ _onDocumentStart(params, sender) {
+ const {tab, frameId, url} = sender;
+ if (typeof url !== 'string' || typeof tab !== 'object' || tab === null) { return; }
+ this._updateTabAccessibility(url, tab, frameId);
+ }
+
// Command handlers
async _onCommandOpenSearchPage(params) {
@@ -2207,4 +2214,31 @@ class Backend {
// NOP
}
}
+
+ _updateTabAccessibility(url, tab, frameId) {
+ let file = null;
+
+ switch (new URL(url).hostname) {
+ case 'docs.google.com':
+ {
+ const optionsContext = {depth: 0, url};
+ const options = this._getProfileOptions(optionsContext);
+ if (!options.accessibility.forceGoogleDocsHtmlRendering) { return; }
+ file = 'js/accessibility/google-docs.js';
+ }
+ break;
+ }
+
+ if (file === null) { return; }
+
+ const details = {
+ allFrames: false,
+ frameId,
+ file,
+ matchAboutBlank: true,
+ runAt: 'document_start'
+ };
+ const callback = () => this._checkLastError(chrome.runtime.lastError);
+ chrome.tabs.executeScript(tab.id, details, callback);
+ }
}
diff --git a/ext/js/data/options-util.js b/ext/js/data/options-util.js
index 42d8a93a..30ffadb1 100644
--- a/ext/js/data/options-util.js
+++ b/ext/js/data/options-util.js
@@ -462,7 +462,8 @@ class OptionsUtil {
{async: true, update: this._updateVersion10.bind(this)},
{async: false, update: this._updateVersion11.bind(this)},
{async: true, update: this._updateVersion12.bind(this)},
- {async: true, update: this._updateVersion13.bind(this)}
+ {async: true, update: this._updateVersion13.bind(this)},
+ {async: false, update: this._updateVersion14.bind(this)}
];
if (typeof targetVersion === 'number' && targetVersion < result.length) {
result.splice(targetVersion);
@@ -864,4 +865,15 @@ class OptionsUtil {
}
return options;
}
+
+ _updateVersion14(options) {
+ // Version 14 changes:
+ // Added accessibility options.
+ for (const profile of options.profiles) {
+ profile.options.accessibility = {
+ forceGoogleDocsHtmlRendering: false
+ };
+ }
+ return options;
+ }
}
diff --git a/ext/js/document-start.js b/ext/js/document-start.js
new file mode 100644
index 00000000..de1c2403
--- /dev/null
+++ b/ext/js/document-start.js
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2021 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
+ * 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/>.
+ */
+
+chrome.runtime.sendMessage({action: 'documentStart'}, () => void chrome.runtime.lastError);
diff --git a/ext/manifest.json b/ext/manifest.json
index dd0f31c9..35f7b18e 100644
--- a/ext/manifest.json
+++ b/ext/manifest.json
@@ -32,11 +32,14 @@
},
"content_scripts": [
{
+ "run_at": "document_idle",
"matches": [
"http://*/*",
"https://*/*",
"file://*/*"
],
+ "match_about_blank": true,
+ "all_frames": true,
"js": [
"js/core.js",
"js/yomichan.js",
@@ -58,9 +61,20 @@
"js/language/text-scanner.js",
"js/script/dynamic-loader.js",
"js/app/content-script-main.js"
+ ]
+ },
+ {
+ "run_at": "document_start",
+ "matches": [
+ "http://*/*",
+ "https://*/*",
+ "file://*/*"
],
"match_about_blank": true,
- "all_frames": true
+ "all_frames": true,
+ "js": [
+ "js/document-start.js"
+ ]
}
],
"minimum_chrome_version": "57.0.0.0",
diff --git a/ext/settings.html b/ext/settings.html
index cd9231c1..fbf041ad 100644
--- a/ext/settings.html
+++ b/ext/settings.html
@@ -37,6 +37,7 @@
<a href="#!clipboard" class="button outline-item"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="clipboard"></span></span><span class="outline-item-label">Clipboard</span></a>
<a href="#!shortcuts" class="button outline-item"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="keyboard"></span></span><span class="outline-item-label">Shortcuts</span></a>
<a href="#!backup" class="button outline-item"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="backup"></span></span><span class="outline-item-label">Backup</span></a>
+ <a href="#!accessibility" class="button outline-item advanced-only"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="accessibility"></span></span><span class="outline-item-label">Accessibility</span></a>
<a href="#!security" class="button outline-item advanced-only"><span class="outline-item-left"><span class="outline-item-icon icon" data-icon="lock"></span></span><span class="outline-item-label">Security</span></a>
</div>
<div class="sidebar-bottom">
@@ -1816,6 +1817,39 @@
</div></div>
</div>
+ <!-- Accessibility -->
+ <div class="heading-container advanced-only">
+ <div class="heading-container-icon"><span class="icon" data-icon="accessibility"></span></div>
+ <div class="heading-container-left"><h2 id="accessibility"><a href="#!accessibility">Accessibility</a></h2></div>
+ </div>
+ <div class="settings-group advanced-only">
+ <div class="settings-item">
+ <div class="settings-item-inner">
+ <div class="settings-item-left">
+ <div class="settings-item-label">
+ Force HTML-based rendering for Google Docs
+ <a class="more-toggle more-only" data-parent-distance="4">(?)</a>
+ </div>
+ </div>
+ <div class="settings-item-right">
+ <label class="toggle"><input type="checkbox" data-setting="accessibility.forceGoogleDocsHtmlRendering"><span class="toggle-body"><span class="toggle-track"></span><span class="toggle-knob"></span></span></label>
+ </div>
+ </div>
+ <div class="settings-item-children more" hidden>
+ <p>
+ Google Docs is moving from HTML-based rendering to
+ <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas" target="_blank" rel="noopener noreferrer">canvas-based</a>
+ rendering to display content<sup><a href="https://workspaceupdates.googleblog.com/2021/05/Google-Docs-Canvas-Based-Rendering-Update.html" target="_blank" rel="noopener noreferrer">[2]</a></sup>,
+ which prevents Yomichan from being able to scan text.
+ Enabling this option will force HTML-based rendering to be used.
+ </p>
+ <p>
+ <a class="more-toggle" data-parent-distance="3">Less&hellip;</a>
+ </p>
+ </div>
+ </div>
+ </div>
+
<!-- Security -->
<div class="heading-container advanced-only">
<div class="heading-container-icon"><span class="icon" data-icon="lock"></span></div>
diff --git a/test/test-options-util.js b/test/test-options-util.js
index 255b6a27..0feeb21c 100644
--- a/test/test-options-util.js
+++ b/test/test-options-util.js
@@ -503,6 +503,9 @@ function createProfileOptionsUpdatedTestData1() {
enableSearchPageMonitor: false,
autoSearchContent: true,
maximumSearchLength: 1000
+ },
+ accessibility: {
+ forceGoogleDocsHtmlRendering: false
}
};
}
@@ -590,7 +593,7 @@ function createOptionsUpdatedTestData1() {
}
],
profileCurrent: 0,
- version: 13,
+ version: 14,
global: {
database: {
prefixWildcardsSupported: false