Display fixes (#1033)

* Fix an entry not always being focused

* Fix typo

* Fix copy action not working on Firefox
This commit is contained in:
toasted-nutbread 2020-11-14 21:47:43 -05:00 committed by GitHub
parent 4b1c7b1e26
commit c387898902
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 8 deletions

View File

@ -29,6 +29,8 @@ class DisplayFloat extends Display {
this._windowMessageHandlers = new Map([ this._windowMessageHandlers = new Map([
['extensionUnloaded', {async: false, handler: this._onMessageExtensionUnloaded.bind(this)}] ['extensionUnloaded', {async: false, handler: this._onMessageExtensionUnloaded.bind(this)}]
]); ]);
this._browser = null;
this._copyTextarea = null;
this.registerActions([ this.registerActions([
['copyHostSelection', () => this._copySelection()] ['copyHostSelection', () => this._copySelection()]
@ -43,6 +45,9 @@ class DisplayFloat extends Display {
async prepare() { async prepare() {
await super.prepare(); await super.prepare();
const {browser} = await api.getEnvironmentInfo();
this._browser = browser;
this.registerDirectMessageHandlers([ this.registerDirectMessageHandlers([
['configure', {async: true, handler: this._onMessageConfigure.bind(this)}], ['configure', {async: true, handler: this._onMessageConfigure.bind(this)}],
['setContentScale', {async: false, handler: this._onMessageSetContentScale.bind(this)}] ['setContentScale', {async: false, handler: this._onMessageSetContentScale.bind(this)}]
@ -150,10 +155,47 @@ class DisplayFloat extends Display {
_copySelection() { _copySelection() {
if (window.getSelection().toString()) { return false; } if (window.getSelection().toString()) { return false; }
this._invokeOwner('copySelection'); this._copyHostSelection();
return true; return true;
} }
async _copyHostSelection() {
switch (this._browser) {
case 'firefox':
case 'firefox-mobile':
{
let text;
try {
text = await this._invokeOwner('getSelectionText');
} catch (e) {
break;
}
this._copyText(text);
}
break;
default:
this._invokeOwner('copySelection');
break;
}
}
_copyText(text) {
const parent = document.body;
if (parent === null) { return; }
let textarea = this._copyTextarea;
if (textarea === null) {
textarea = document.createElement('textarea');
this._copyTextarea = textarea;
}
textarea.value = text;
parent.appendChild(textarea);
textarea.select();
document.execCommand('copy');
parent.removeChild(textarea);
}
_setContentScale(scale) { _setContentScale(scale) {
const body = document.body; const body = document.body;
if (body === null) { return; } if (body === null) { return; }

View File

@ -115,6 +115,7 @@ class Frontend {
['getUrl', {async: false, handler: this._onApiGetUrl.bind(this)}], ['getUrl', {async: false, handler: this._onApiGetUrl.bind(this)}],
['closePopup', {async: false, handler: this._onApiClosePopup.bind(this)}], ['closePopup', {async: false, handler: this._onApiClosePopup.bind(this)}],
['copySelection', {async: false, handler: this._onApiCopySelection.bind(this)}], ['copySelection', {async: false, handler: this._onApiCopySelection.bind(this)}],
['getSelectionText', {async: false, handler: this._onApiGetSelectionText.bind(this)}],
['getPopupInfo', {async: false, handler: this._onApiGetPopupInfo.bind(this)}], ['getPopupInfo', {async: false, handler: this._onApiGetPopupInfo.bind(this)}],
['getDocumentInformation', {async: false, handler: this._onApiGetDocumentInformation.bind(this)}] ['getDocumentInformation', {async: false, handler: this._onApiGetDocumentInformation.bind(this)}]
]); ]);
@ -168,9 +169,14 @@ class Frontend {
} }
_onApiCopySelection() { _onApiCopySelection() {
// This will not work on Firefox if a popup has focus, which is usually the case when this function is called.
document.execCommand('copy'); document.execCommand('copy');
} }
_onApiGetSelectionText() {
return document.getSelection().toString();
}
_onApiGetPopupInfo() { _onApiGetPopupInfo() {
return { return {
popupId: (this._popup !== null ? this._popup.id : null) popupId: (this._popup !== null ? this._popup.id : null)

View File

@ -466,7 +466,7 @@ class Display extends EventDispatcher {
this._closePopups(); this._closePopups();
this._setEventListenersActive(false); this._setEventListenersActive(false);
let asigned = false; let assigned = false;
const eventArgs = {type, urlSearchParams, token}; const eventArgs = {type, urlSearchParams, token};
this._historyHasChanged = true; this._historyHasChanged = true;
this._contentType = type; this._contentType = type;
@ -476,7 +476,7 @@ class Display extends EventDispatcher {
case 'kanji': case 'kanji':
{ {
const isTerms = (type === 'terms'); const isTerms = (type === 'terms');
asigned = await this._setContentTermsOrKanji(token, isTerms, urlSearchParams, eventArgs); assigned = await this._setContentTermsOrKanji(token, isTerms, urlSearchParams, eventArgs);
} }
break; break;
case 'unloaded': case 'unloaded':
@ -485,14 +485,14 @@ class Display extends EventDispatcher {
eventArgs.content = content; eventArgs.content = content;
this.trigger('contentUpdating', eventArgs); this.trigger('contentUpdating', eventArgs);
this._setContentExtensionUnloaded(); this._setContentExtensionUnloaded();
asigned = true; assigned = true;
} }
break; break;
} }
const stale = (this._setContentToken !== token); const stale = (this._setContentToken !== token);
if (!stale) { if (!stale) {
if (!asigned) { if (!assigned) {
type = 'clear'; type = 'clear';
this._contentType = type; this._contentType = type;
const {content} = this._history; const {content} = this._history;
@ -910,9 +910,7 @@ class Display extends EventDispatcher {
container.appendChild(entry); container.appendChild(entry);
} }
if (typeof focusEntry === 'number') { this._focusEntry(typeof focusEntry === 'number' ? focusEntry : 0, false);
this._focusEntry(focusEntry, false);
}
if (typeof scrollX === 'number' || typeof scrollY === 'number') { if (typeof scrollX === 'number' || typeof scrollY === 'number') {
let {x, y} = this._windowScroll; let {x, y} = this._windowScroll;
if (typeof scrollX === 'number') { x = scrollX; } if (typeof scrollX === 'number') { x = scrollX; }