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
This commit is contained in:
parent
ad31b70b67
commit
5d4141a429
@ -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"
|
||||
],
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
27
ext/js/accessibility/google-docs.js
Normal file
27
ext/js/accessibility/google-docs.js
Normal file
@ -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);
|
||||
})();
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
18
ext/js/document-start.js
Normal file
18
ext/js/document-start.js
Normal file
@ -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);
|
@ -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",
|
||||
|
@ -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…</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>
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user