From 1f564b94cb01c3ef6630dbd897ed640f4ac9cc18 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sat, 22 Aug 2020 13:03:35 -0400 Subject: [PATCH] XMLDocument handling (#738) * Add tests for SVGs * Add more null checks for Frontend._popup * Use null popup when on an XMLDocument --- ext/fg/js/frontend.js | 47 +++++++++++----- test/data/html/test-document2-frame2.svg | 15 ++++++ test/data/html/test-document2-script.js | 4 ++ test/data/html/test-document2.html | 68 +++++++++++++++++++++--- 4 files changed, 116 insertions(+), 18 deletions(-) create mode 100644 test/data/html/test-document2-frame2.svg diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 36b1898b..e7fb7f47 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -167,6 +167,7 @@ class Frontend { // Message handlers _onMessagePopupSetVisibleOverride({visible}) { + if (this._popup === null) { return; } this._popup.setVisibleOverride(visible); } @@ -226,15 +227,17 @@ class Frontend { } _onClearSelection({passive}) { - this._popup.hide(!passive); - this._popup.clearAutoPlayTimer(); + if (this._popup !== null) { + this._popup.hide(!passive); + this._popup.clearAutoPlayTimer(); + } this._updatePendingOptions(); } async _onActiveModifiersChanged({modifiers}) { if (areSetsEqual(modifiers, this._activeModifiers)) { return; } this._activeModifiers = modifiers; - if (await this._popup.isVisible()) { + if (this._popup !== null && await this._popup.isVisible()) { this._optionsUpdatePending = true; return; } @@ -311,7 +314,9 @@ class Frontend { const popup = await popupPromise; const optionsContext = await this.getOptionsContext(); if (this._updatePopupToken !== token) { return; } - await popup.setOptionsContext(optionsContext, this._id); + if (popup !== null) { + await popup.setOptionsContext(optionsContext, this._id); + } if (this._updatePopupToken !== token) { return; } if (this._isSearchPage) { @@ -323,6 +328,11 @@ class Frontend { } async _getDefaultPopup() { + const isXmlDocument = (typeof XMLDocument !== 'undefined' && document instanceof XMLDocument); + if (isXmlDocument) { + return null; + } + return this._popupFactory.getOrCreatePopup({depth: this._depth, ownerFrameId: this._frameId}); } @@ -335,7 +345,12 @@ class Frontend { async _getIframeProxyPopup() { const targetFrameId = 0; // Root frameId await this._waitForFrontendReady(targetFrameId); + const {popupId} = await api.crossFrame.invoke(targetFrameId, 'getPopupInfo'); + if (popupId === null) { + return null; + } + const popup = new PopupProxy(popupId, 0, null, targetFrameId, this._frameId, this._frameOffsetForwarder); popup.on('offsetNotFound', () => { this._allowRootFramePopupProxy = false; @@ -368,6 +383,10 @@ class Frontend { } async _search(textSource, cause) { + if (this._popup === null) { + return null; + } + await this._updatePendingOptions(); let results = null; @@ -466,14 +485,18 @@ class Frontend { } _showPopupContent(textSource, optionsContext, details=null) { - this._lastShowPromise = this._popup.showContent( - { - source: this._id, - optionsContext, - elementRect: textSource.getRect(), - writingMode: textSource.getWritingMode() - }, - details + this._lastShowPromise = ( + this._popup !== null ? + this._popup.showContent( + { + source: this._id, + optionsContext, + elementRect: textSource.getRect(), + writingMode: textSource.getWritingMode() + }, + details + ) : + Promise.resolve() ); this._lastShowPromise.catch((error) => { if (yomichan.isExtensionUnloaded) { return; } diff --git a/test/data/html/test-document2-frame2.svg b/test/data/html/test-document2-frame2.svg new file mode 100644 index 00000000..380eab97 --- /dev/null +++ b/test/data/html/test-document2-frame2.svg @@ -0,0 +1,15 @@ + + + +ありがとう + \ No newline at end of file diff --git a/test/data/html/test-document2-script.js b/test/data/html/test-document2-script.js index ab516a4e..01bc211f 100644 --- a/test/data/html/test-document2-script.js +++ b/test/data/html/test-document2-script.js @@ -58,6 +58,10 @@ function setup(container, fullscreenElement=null) { if (template !== null && templateContentContainer !== null) { const mode = container.dataset.shadowMode; const shadow = templateContentContainer.attachShadow({mode}); + + const containerStyles = document.querySelector('#container-styles'); + shadow.appendChild(containerStyles.cloneNode(true)); + const content = document.importNode(template.content, true); setup(content); shadow.appendChild(content); diff --git a/test/data/html/test-document2.html b/test/data/html/test-document2.html index 6d174571..10fecbbb 100644 --- a/test/data/html/test-document2.html +++ b/test/data/html/test-document2.html @@ -8,6 +8,24 @@ +

Yomichan Manual Tests

@@ -15,7 +33,7 @@ Standard content. -
+
ありがとう
@@ -30,7 +48,7 @@