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"],
|
"files": ["ext/**/*.js"],
|
||||||
"excludedFiles": [
|
"excludedFiles": [
|
||||||
"ext/js/core.js",
|
"ext/js/core.js",
|
||||||
|
"ext/js/document-start.js",
|
||||||
"ext/js/**/sandbox/**/*.js"
|
"ext/js/**/sandbox/**/*.js"
|
||||||
],
|
],
|
||||||
"globals": {
|
"globals": {
|
||||||
@ -146,6 +147,7 @@
|
|||||||
"files": ["ext/**/*.js"],
|
"files": ["ext/**/*.js"],
|
||||||
"excludedFiles": [
|
"excludedFiles": [
|
||||||
"ext/js/core.js",
|
"ext/js/core.js",
|
||||||
|
"ext/js/document-start.js",
|
||||||
"ext/js/yomichan.js",
|
"ext/js/yomichan.js",
|
||||||
"ext/js/**/sandbox/**/*.js"
|
"ext/js/**/sandbox/**/*.js"
|
||||||
],
|
],
|
||||||
|
@ -33,11 +33,14 @@
|
|||||||
},
|
},
|
||||||
"content_scripts": [
|
"content_scripts": [
|
||||||
{
|
{
|
||||||
|
"run_at": "document_idle",
|
||||||
"matches": [
|
"matches": [
|
||||||
"http://*/*",
|
"http://*/*",
|
||||||
"https://*/*",
|
"https://*/*",
|
||||||
"file://*/*"
|
"file://*/*"
|
||||||
],
|
],
|
||||||
|
"match_about_blank": true,
|
||||||
|
"all_frames": true,
|
||||||
"js": [
|
"js": [
|
||||||
"js/core.js",
|
"js/core.js",
|
||||||
"js/yomichan.js",
|
"js/yomichan.js",
|
||||||
@ -59,9 +62,20 @@
|
|||||||
"js/language/text-scanner.js",
|
"js/language/text-scanner.js",
|
||||||
"js/script/dynamic-loader.js",
|
"js/script/dynamic-loader.js",
|
||||||
"js/app/content-script-main.js"
|
"js/app/content-script-main.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"run_at": "document_start",
|
||||||
|
"matches": [
|
||||||
|
"http://*/*",
|
||||||
|
"https://*/*",
|
||||||
|
"file://*/*"
|
||||||
],
|
],
|
||||||
"match_about_blank": true,
|
"match_about_blank": true,
|
||||||
"all_frames": true
|
"all_frames": true,
|
||||||
|
"js": [
|
||||||
|
"js/document-start.js"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"minimum_chrome_version": "57.0.0.0",
|
"minimum_chrome_version": "57.0.0.0",
|
||||||
|
@ -72,7 +72,8 @@
|
|||||||
"anki",
|
"anki",
|
||||||
"sentenceParsing",
|
"sentenceParsing",
|
||||||
"inputs",
|
"inputs",
|
||||||
"clipboard"
|
"clipboard",
|
||||||
|
"accessibility"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"general": {
|
"general": {
|
||||||
@ -1109,6 +1110,18 @@
|
|||||||
"minimum": 0
|
"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)}],
|
['isTabSearchPopup', {async: true, contentScript: true, handler: this._onApiIsTabSearchPopup.bind(this)}],
|
||||||
['triggerDatabaseUpdated', {async: false, contentScript: true, handler: this._onApiTriggerDatabaseUpdated.bind(this)}],
|
['triggerDatabaseUpdated', {async: false, contentScript: true, handler: this._onApiTriggerDatabaseUpdated.bind(this)}],
|
||||||
['testMecab', {async: true, contentScript: true, handler: this._onApiTestMecab.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([
|
this._messageHandlersWithProgress = new Map([
|
||||||
]);
|
]);
|
||||||
@ -745,6 +746,12 @@ class Backend {
|
|||||||
return this._japaneseUtil.isStringPartiallyJapanese(text);
|
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
|
// Command handlers
|
||||||
|
|
||||||
async _onCommandOpenSearchPage(params) {
|
async _onCommandOpenSearchPage(params) {
|
||||||
@ -2207,4 +2214,31 @@ class Backend {
|
|||||||
// NOP
|
// 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: true, update: this._updateVersion10.bind(this)},
|
||||||
{async: false, update: this._updateVersion11.bind(this)},
|
{async: false, update: this._updateVersion11.bind(this)},
|
||||||
{async: true, update: this._updateVersion12.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) {
|
if (typeof targetVersion === 'number' && targetVersion < result.length) {
|
||||||
result.splice(targetVersion);
|
result.splice(targetVersion);
|
||||||
@ -864,4 +865,15 @@ class OptionsUtil {
|
|||||||
}
|
}
|
||||||
return options;
|
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": [
|
"content_scripts": [
|
||||||
{
|
{
|
||||||
|
"run_at": "document_idle",
|
||||||
"matches": [
|
"matches": [
|
||||||
"http://*/*",
|
"http://*/*",
|
||||||
"https://*/*",
|
"https://*/*",
|
||||||
"file://*/*"
|
"file://*/*"
|
||||||
],
|
],
|
||||||
|
"match_about_blank": true,
|
||||||
|
"all_frames": true,
|
||||||
"js": [
|
"js": [
|
||||||
"js/core.js",
|
"js/core.js",
|
||||||
"js/yomichan.js",
|
"js/yomichan.js",
|
||||||
@ -58,9 +61,20 @@
|
|||||||
"js/language/text-scanner.js",
|
"js/language/text-scanner.js",
|
||||||
"js/script/dynamic-loader.js",
|
"js/script/dynamic-loader.js",
|
||||||
"js/app/content-script-main.js"
|
"js/app/content-script-main.js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"run_at": "document_start",
|
||||||
|
"matches": [
|
||||||
|
"http://*/*",
|
||||||
|
"https://*/*",
|
||||||
|
"file://*/*"
|
||||||
],
|
],
|
||||||
"match_about_blank": true,
|
"match_about_blank": true,
|
||||||
"all_frames": true
|
"all_frames": true,
|
||||||
|
"js": [
|
||||||
|
"js/document-start.js"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"minimum_chrome_version": "57.0.0.0",
|
"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="#!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="#!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="#!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>
|
<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>
|
||||||
<div class="sidebar-bottom">
|
<div class="sidebar-bottom">
|
||||||
@ -1816,6 +1817,39 @@
|
|||||||
</div></div>
|
</div></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 -->
|
<!-- Security -->
|
||||||
<div class="heading-container advanced-only">
|
<div class="heading-container advanced-only">
|
||||||
<div class="heading-container-icon"><span class="icon" data-icon="lock"></span></div>
|
<div class="heading-container-icon"><span class="icon" data-icon="lock"></span></div>
|
||||||
|
@ -503,6 +503,9 @@ function createProfileOptionsUpdatedTestData1() {
|
|||||||
enableSearchPageMonitor: false,
|
enableSearchPageMonitor: false,
|
||||||
autoSearchContent: true,
|
autoSearchContent: true,
|
||||||
maximumSearchLength: 1000
|
maximumSearchLength: 1000
|
||||||
|
},
|
||||||
|
accessibility: {
|
||||||
|
forceGoogleDocsHtmlRendering: false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -590,7 +593,7 @@ function createOptionsUpdatedTestData1() {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
profileCurrent: 0,
|
profileCurrent: 0,
|
||||||
version: 13,
|
version: 14,
|
||||||
global: {
|
global: {
|
||||||
database: {
|
database: {
|
||||||
prefixWildcardsSupported: false
|
prefixWildcardsSupported: false
|
||||||
|
Loading…
Reference in New Issue
Block a user