Skip to content

Commit

Permalink
fix: clipboard getImage, review comments
Browse files Browse the repository at this point in the history
implement getImage for offscreen requests
move offscreen files, offscreen prep is done in sw prep
update permissions document for offscreen
rearrange permissions
  • Loading branch information
web-flow committed Oct 21, 2023
1 parent e39d18a commit bd86f4d
Showing 7 changed files with 61 additions and 63 deletions.
26 changes: 16 additions & 10 deletions dev/data/manifest-variants.json
Original file line number Diff line number Diff line change
@@ -82,7 +82,8 @@
"unlimitedStorage",
"webRequest",
"declarativeNetRequest",
"scripting"
"scripting",
"offscreen"
],
"optional_permissions": [
"clipboardRead",
@@ -167,15 +168,6 @@
"pattern": "^(.*)(?:\\.\\s*)?$",
"patternFlags": "",
"replacement": "$1. This is a development build."
},
{
"action": "add",
"path": [
"permissions"
],
"items": [
"offscreen"
]
}
]
},
@@ -263,6 +255,13 @@
"permissions"
],
"item": "declarativeNetRequest"
},
{
"action": "remove",
"path": [
"permissions"
],
"item": "offscreen"
}
],
"excludeFiles": [
@@ -337,6 +336,13 @@
],
"item": "webRequestBlocking"
},
{
"action": "remove",
"path": [
"permissions"
],
"item": "offscreen"
},
{
"action": "delete",
"path": [
5 changes: 5 additions & 0 deletions docs/permissions.md
Original file line number Diff line number Diff line change
@@ -23,6 +23,11 @@
Yomichan will sometimes need to inject stylesheets into webpages in order to
properly display the search popup.

* `offscreen` __(Manifest v3 only)_ <br>
Yomitan uses this permission to create a secondary backend document that has access to the DOM, given that Manifest v3
service workers do not have access it. Service workers can then reach out to out to this document in order to complete
actions that require access to DOM APIs, such as any that require clipboard access.

* `clipboardWrite` <br>
Yomichan supports simulating the `Ctrl+C` (copy to clipboard) keyboard shortcut
when a definitions popup is open and focused.
30 changes: 0 additions & 30 deletions ext/css/offscreen.css

This file was deleted.

52 changes: 32 additions & 20 deletions ext/js/background/backend.js
Original file line number Diff line number Diff line change
@@ -58,16 +58,18 @@ class Backend {
this._anki = new AnkiConnect();
this._mecab = new Mecab();

this._clipboardReader = {
getText: this._getTextOffscreen.bind(this)
};
if (!chrome || !chrome.offscreen) {
if (!chrome.offscreen) {
this._clipboardReader = new ClipboardReader({
// eslint-disable-next-line no-undef
document: (typeof document === 'object' && document !== null ? document : null),
pasteTargetSelector: '#clipboard-paste-target',
richContentPasteTargetSelector: '#clipboard-rich-content-paste-target'
});
} else {
this._clipboardReader = {
getText: this._getTextOffscreen.bind(this),
getImage: this._getImageOffscreen.bind(this)
};
}

this._clipboardMonitor = new ClipboardMonitor({
@@ -227,6 +229,9 @@ class Backend {

await this._requestBuilder.prepare();
await this._environment.prepare();
if (chrome.offscreen) {
await this._setupOffscreenDocument();
}
this._clipboardReader.browser = this._environment.getInfo().browser;

try {
@@ -566,21 +571,6 @@ class Backend {
return this._clipboardReader.getText(false);
}

async _getTextOffscreen(useRichText) {
await this._setupOffscreenDocument();
return new Promise((resolve, reject) => {
const callback = (response) => {
try {
resolve(this._getMessageResponseResult(response));
} catch (error) {
reject(error);
}
};

chrome.runtime.sendMessage({action: 'clipboardGetOffscreen', params: {useRichText}}, callback);
});
}

async _onApiGetDisplayTemplatesHtml() {
return await this._fetchAsset('/display-templates.html');
}
@@ -1634,6 +1624,20 @@ class Backend {
return await (json ? response.json() : response.text());
}

_sendMessagePromise(...args) {
return new Promise((resolve, reject) => {
const callback = (response) => {
try {
resolve(this._getMessageResponseResult(response));
} catch (error) {
reject(error);
}
};

chrome.runtime.sendMessage(...args, callback);
});
}

_sendMessageIgnoreResponse(...args) {
const callback = () => this._checkLastError(chrome.runtime.lastError);
chrome.runtime.sendMessage(...args, callback);
@@ -2244,6 +2248,14 @@ class Backend {
return results;
}

async _getTextOffscreen(useRichText) {
return this._sendMessagePromise({action: 'clipboardGetTextOffscreen', params: {useRichText}});
}

async _getImageOffscreen() {
return this._sendMessagePromise({action: 'clipboardGetImageOffscreen'});
}

_onApiOpenCrossFramePort({targetTabId, targetFrameId}, sender) {
const sourceTabId = (sender && sender.tab ? sender.tab.id : null);
if (typeof sourceTabId !== 'number') {
@@ -2300,7 +2312,7 @@ class Backend {
this._creatingOffscreen = chrome.offscreen.createDocument({
url: 'offscreen.html',
reasons: ['CLIPBOARD'],
justification: 'reason for needing the document'
justification: 'Access to the clipboard'
});
await this._creatingOffscreen;
this._creatingOffscreen = null;
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -37,7 +37,8 @@ class Offscreen {
});

this._messageHandlers = new Map([
['clipboardGetOffscreen', {async: true, contentScript: true, handler: this._getTextHandler.bind(this)}]
['clipboardGetTextOffscreen', {async: true, contentScript: true, handler: this._getTextHandler.bind(this)}],
['clipboardGetImageOffscreen', {async: true, contentScript: true, handler: this._getImageHandler.bind(this)}]
]);

const onMessage = this._onMessage.bind(this);
@@ -48,6 +49,10 @@ class Offscreen {
return this._clipboardReader.getText(useRichText);
}

_getImageHandler() {
return this._clipboardReader.getImage();
}

_onMessage({action, params}, sender, callback) {
const messageHandler = this._messageHandlers.get(action);
if (typeof messageHandler === 'undefined') { return false; }
4 changes: 2 additions & 2 deletions ext/offscreen.html
Original file line number Diff line number Diff line change
@@ -24,8 +24,8 @@

<script src="/js/comm/clipboard-reader.js"></script>

<script src="/js/offscreen/offscreen.js"></script>
<script src="/js/offscreen/offscreen-main.js"></script>
<script src="/js/background/offscreen.js"></script>
<script src="/js/background/offscreen-main.js"></script>

<!--
Due to a Firefox bug, this next element is purposefully terminated incorrectly.

0 comments on commit bd86f4d

Please sign in to comment.