Skip to content

Commit

Permalink
Merge pull request #209 from praschke/firefox-fixes
Browse files Browse the repository at this point in the history
Firefox fixes
  • Loading branch information
djahandarie authored Aug 19, 2023
2 parents a59d0c8 + 07333a2 commit a00a56c
Show file tree
Hide file tree
Showing 8 changed files with 43 additions and 111 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ Required licensing notices for this project follow below:
Yomitan uses several third-party libraries to function. Below are links to homepages, snapshots, and licenses of the exact
versions packaged.

* Handlebars: [homepage](https://handlebarsjs.com/) - [snapshot](https://s3.amazonaws.com/builds.handlebarsjs.com/handlebars.min-v4.7.7.js) - [license](https://github.com/handlebars-lang/handlebars.js/blob/v4.7.7/LICENSE)
* Handlebars: To retain Handlebars templating without unsafe-eval, a fork of handlebars by Kibana is being used. [homepage](https://github.com/Aquafina-water-bottle/handlebars-noeval) - [snapshot](https://raw.githubusercontent.com/Aquafina-water-bottle/handlebars-noeval/10efaac28d8d2e8d7e503347281eff1a90aa3f31/handlebars.min.js) - [license](https://github.com/Aquafina-water-bottle/handlebars-noeval/blob/10efaac28d8d2e8d7e503347281eff1a90aa3f31/src/hb/LICENSE)
* JSZip: [homepage](https://stuk.github.io/jszip/) - [snapshot](https://github.com/Stuk/jszip/blob/v3.9.1/dist/jszip.min.js) - [license](https://github.com/Stuk/jszip/blob/v3.9.1/LICENSE.markdown)
* WanaKana: [homepage](https://wanakana.com/) - [snapshot](https://unpkg.com/wanakana@4.0.2/umd/wanakana.min.js) - [license](https://github.com/WaniKani/WanaKana/blob/4.0.2/LICENSE)
* parse5: [homepage](https://github.com/inikulin/parse5) - [snapshot](https://github.com/inikulin/parse5/tree/v7.1.2/packages/parse5) - [license](https://github.com/inikulin/parse5/blob/v7.1.2/LICENSE) _(Only used in MV3 build)_
18 changes: 16 additions & 2 deletions dev/data/manifest-variants.json
Original file line number Diff line number Diff line change
Expand Up @@ -205,13 +205,20 @@
"sandbox"
]
},
{
"action": "delete",
"path": [
"content_security_policy",
"sandbox"
]
},
{
"action": "set",
"path": [
"content_security_policy",
"extension_pages"
],
"value": "default-src 'self'; script-src 'self' 'unsafe-eval'; img-src blob: 'self'; style-src 'self' 'unsafe-inline'; media-src *; connect-src *"
"value": "default-src 'self'; script-src 'self'; img-src blob: 'self'; style-src 'self' 'unsafe-inline'; media-src *; connect-src *"
},
{
"action": "set",
Expand All @@ -221,7 +228,7 @@
"value": {
"gecko": {
"id": "{cb7c0bec-7085-4f84-8422-7b55a7c4467c}",
"strict_min_version": "101.0"
"strict_min_version": "102.0"
}
}
},
Expand All @@ -240,6 +247,13 @@
"items": [
"nativeMessaging"
]
},
{
"action": "remove",
"path": [
"permissions"
],
"item": "declarativeNetRequest"
}
],
"excludeFiles": [
Expand Down
4 changes: 2 additions & 2 deletions ext/js/background/backend.js
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ class Backend {
async _onApiInjectStylesheet({type, value}, sender) {
const {frameId, tab} = sender;
if (!isObject(tab)) { throw new Error('Invalid tab'); }
return await this._scriptManager.injectStylesheet(type, value, tab.id, frameId, false, true, 'document_start');
return await this._scriptManager.injectStylesheet(type, value, tab.id, frameId, false);
}

async _onApiGetStylesheetContent({url}) {
Expand Down Expand Up @@ -790,7 +790,7 @@ class Backend {
if (typeof tabId !== 'number') { throw new Error('Sender has invalid tab ID'); }
const {frameId} = sender;
for (const file of files) {
await this._scriptManager.injectScript(file, tabId, frameId, false, true, 'document_start');
await this._scriptManager.injectScript(file, tabId, frameId, false);
}
}

Expand Down
1 change: 0 additions & 1 deletion ext/js/background/request-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ class RequestBuilder {
* @returns {Promise<Response>} The response of the `fetch` call.
*/
async fetchAnonymous(url, init) {
fetch(1, 2);
if (isObject(chrome.declarativeNetRequest)) {
return await this._fetchAnonymousDeclarative(url, init);
}
Expand Down
115 changes: 13 additions & 102 deletions ext/js/background/script-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,10 @@ class ScriptManager {
* @param {number} tabId The id of the tab to inject into.
* @param {number} [frameId] The id of the frame to inject into.
* @param {boolean} [allFrames] Whether or not the stylesheet should be injected into all frames.
* @param {boolean} [matchAboutBlank] Whether or not the stylesheet should be injected into about:blank frames.
* @param {string} [runAt] The time to inject the stylesheet at.
* @returns {Promise<void>}
*/
injectStylesheet(type, content, tabId, frameId, allFrames, matchAboutBlank, runAt) {
if (isObject(chrome.tabs) && typeof chrome.tabs.insertCSS === 'function') {
return this._injectStylesheetMV2(type, content, tabId, frameId, allFrames, matchAboutBlank, runAt);
} else if (isObject(chrome.scripting) && typeof chrome.scripting.insertCSS === 'function') {
injectStylesheet(type, content, tabId, frameId, allFrames) {
if (isObject(chrome.scripting) && typeof chrome.scripting.insertCSS === 'function') {
return this._injectStylesheetMV3(type, content, tabId, frameId, allFrames);
} else {
return Promise.reject(new Error('Stylesheet injection not supported'));
Expand All @@ -56,14 +52,10 @@ class ScriptManager {
* @param {number} tabId The id of the tab to inject into.
* @param {number} [frameId] The id of the frame to inject into.
* @param {boolean} [allFrames] Whether or not the script should be injected into all frames.
* @param {boolean} [matchAboutBlank] Whether or not the script should be injected into about:blank frames.
* @param {string} [runAt] The time to inject the script at.
* @returns {Promise<{frameId: number, result: object}>} The id of the frame and the result of the script injection.
*/
injectScript(file, tabId, frameId, allFrames, matchAboutBlank, runAt) {
if (isObject(chrome.tabs) && typeof chrome.tabs.executeScript === 'function') {
return this._injectScriptMV2(file, tabId, frameId, allFrames, matchAboutBlank, runAt);
} else if (isObject(chrome.scripting) && typeof chrome.scripting.executeScript === 'function') {
injectScript(file, tabId, frameId, allFrames) {
if (isObject(chrome.scripting) && typeof chrome.scripting.executeScript === 'function') {
return this._injectScriptMV3(file, tabId, frameId, allFrames);
} else {
return Promise.reject(new Error('Script injection not supported'));
Expand Down Expand Up @@ -122,19 +114,6 @@ class ScriptManager {
throw new Error('Registration already exists');
}

// Firefox
if (
typeof browser === 'object' && browser !== null &&
isObject(browser.contentScripts) &&
typeof browser.contentScripts.register === 'function'
) {
const details2 = this._convertContentScriptRegistrationDetails(details, id, true);
const registration = await browser.contentScripts.register(details2);
this._contentScriptRegistrations.set(id, registration);
return;
}

// Chrome
if (isObject(chrome.scripting) && typeof chrome.scripting.registerContentScripts === 'function') {
const details2 = this._convertContentScriptRegistrationDetails(details, id, false);
await new Promise((resolve, reject) => {
Expand All @@ -161,18 +140,17 @@ class ScriptManager {
* @returns {Promise<boolean>} `true` if the content script was unregistered, `false` otherwise.
*/
async unregisterContentScript(id) {
// Chrome
if (isObject(chrome.scripting) && typeof chrome.scripting.unregisterContentScripts === 'function') {
this._contentScriptRegistrations.delete(id);
try {
await this._unregisterContentScriptChrome(id);
await this._unregisterContentScriptMV3(id);
return true;
} catch (e) {
return false;
}
}

// Firefox or fallback
// Fallback
const registration = this._contentScriptRegistrations.get(id);
if (typeof registration === 'undefined') { return false; }
this._contentScriptRegistrations.delete(id);
Expand All @@ -187,19 +165,7 @@ class ScriptManager {
* @returns {string[]} An array of the required permissions, which may be empty.
*/
getRequiredContentScriptRegistrationPermissions() {
if (
// Firefox
(
typeof browser === 'object' && browser !== null &&
isObject(browser.contentScripts) &&
typeof browser.contentScripts.register === 'function'
) ||
// Chrome
(
isObject(chrome.scripting) &&
typeof chrome.scripting.registerContentScripts === 'function'
)
) {
if (isObject(chrome.scripting) && typeof chrome.scripting.registerContentScripts === 'function') {
return [];
}

Expand All @@ -209,45 +175,12 @@ class ScriptManager {

// Private

_injectStylesheetMV2(type, content, tabId, frameId, allFrames, matchAboutBlank, runAt) {
return new Promise((resolve, reject) => {
const details = (
type === 'file' ?
{
file: content,
runAt,
cssOrigin: 'author',
allFrames,
matchAboutBlank
} :
{
code: content,
runAt,
cssOrigin: 'user',
allFrames,
matchAboutBlank
}
);
if (typeof frameId === 'number') {
details.frameId = frameId;
}
chrome.tabs.insertCSS(tabId, details, () => {
const e = chrome.runtime.lastError;
if (e) {
reject(new Error(e.message));
} else {
resolve();
}
});
});
}

_injectStylesheetMV3(type, content, tabId, frameId, allFrames) {
return new Promise((resolve, reject) => {
const details = (
type === 'file' ?
{origin: chrome.scripting.StyleOrigin.AUTHOR, files: [content]} :
{origin: chrome.scripting.StyleOrigin.USER, css: content}
{origin: 'AUTHOR', files: [content]} :
{origin: 'USER', css: content}
);
details.target = {
tabId,
Expand All @@ -267,27 +200,6 @@ class ScriptManager {
});
}

_injectScriptMV2(file, tabId, frameId, allFrames, matchAboutBlank, runAt) {
return new Promise((resolve, reject) => {
const details = {
allFrames,
frameId,
file,
matchAboutBlank,
runAt
};
chrome.tabs.executeScript(tabId, details, (results) => {
const e = chrome.runtime.lastError;
if (e) {
reject(new Error(e.message));
} else {
const result = results[0];
resolve({frameId, result});
}
});
});
}

_injectScriptMV3(file, tabId, frameId, allFrames) {
return new Promise((resolve, reject) => {
const details = {
Expand All @@ -310,7 +222,7 @@ class ScriptManager {
});
}

_unregisterContentScriptChrome(id) {
_unregisterContentScriptMV3(id) {
return new Promise((resolve, reject) => {
chrome.scripting.unregisterContentScripts({ids: [id]}, () => {
const e = chrome.runtime.lastError;
Expand Down Expand Up @@ -407,7 +319,7 @@ class ScriptManager {
const {urlRegex} = details;
if (urlRegex !== null && !urlRegex.test(url)) { return; }

let {allFrames, css, js, matchAboutBlank, runAt} = details;
let {allFrames, css, js, runAt} = details;

if (isWebNavigation) {
if (allFrames) {
Expand All @@ -425,14 +337,13 @@ class ScriptManager {

const promises = [];
if (Array.isArray(css)) {
const runAtCss = (typeof runAt === 'string' ? runAt : 'document_start');
for (const file of css) {
promises.push(this.injectStylesheet('file', file, tabId, frameId, allFrames, matchAboutBlank, runAtCss));
promises.push(this.injectStylesheet('file', file, tabId, frameId, allFrames));
}
}
if (Array.isArray(js)) {
for (const file of js) {
promises.push(this.injectScript(file, tabId, frameId, allFrames, matchAboutBlank, runAt));
promises.push(this.injectScript(file, tabId, frameId, allFrames));
}
}
await Promise.all(promises);
Expand Down
3 changes: 2 additions & 1 deletion ext/js/language/text-scanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ class TextScanner extends EventDispatcher {

if (value) {
this._hookEvents();
this._userHasNotSelectedAnythingManually = window.getSelection().isCollapsed;
const selection = window.getSelection();
this._userHasNotSelectedAnythingManually = (selection === null) ? true : selection.isCollapsed;
}
}

Expand Down
7 changes: 7 additions & 0 deletions ext/lib/handlebars.min.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions ext/permissions.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ <h2 id="permissions"></h2>
</div>
</div>
</div></div>
<div class="settings-item" data-hide-for-manifest-version="3"><div class="settings-item-inner">
<div class="settings-item" data-show-for-browser="firefox firefox-mobile"><div class="settings-item-inner">
<div class="settings-item-left">
<div class="settings-item-label"><code>webRequest</code> and <code>webRequestBlocking</code></div>
<div class="settings-item-description">
Expand All @@ -62,7 +62,7 @@ <h2 id="permissions"></h2>
</div>
</div>
</div></div>
<div class="settings-item" data-show-for-manifest-version="3"><div class="settings-item-inner">
<div class="settings-item" data-show-for-browser="chrome edge"><div class="settings-item-inner">
<div class="settings-item-left">
<div class="settings-item-label"><code>declarativeNetRequest</code></div>
<div class="settings-item-description">
Expand Down

0 comments on commit a00a56c

Please sign in to comment.