From 231b471f45505a8b8fc4a8b25aa685f6f877953c Mon Sep 17 00:00:00 2001 From: Alex Yatskov Date: Thu, 16 Mar 2017 22:13:54 -0700 Subject: [PATCH] wip --- ext/fg/js/driver.js | 21 +++++---- ext/fg/js/popup.js | 110 +++++++++++++++++++++++--------------------- 2 files changed, 70 insertions(+), 61 deletions(-) diff --git a/ext/fg/js/driver.js b/ext/fg/js/driver.js index fddfbc29..fbe89ab8 100644 --- a/ext/fg/js/driver.js +++ b/ext/fg/js/driver.js @@ -153,9 +153,12 @@ window.driver = new class { const sentence = docSentenceExtract(textSource, this.options.anki.sentenceExt); const url = window.location.href; - - this.popup.showNextTo(textSource.getRect(), this.options); - this.popup.showTermDefs(definitions, this.options, {sentence, url}); + this.popup.showTermDefs( + textSource.getRect(), + definitions, + this.options, + {sentence, url} + ); this.lastTextSource = textSource; if (this.options.scanning.selectText) { @@ -176,9 +179,12 @@ window.driver = new class { } else { const sentence = docSentenceExtract(textSource, this.options.anki.sentenceExt); const url = window.location.href; - - this.popup.showNextTo(textSource.getRect(), this.options); - this.popup.showKanjiDefs(definitions, this.options, {sentence, url}); + this.popup.showKanjiDefs( + textSource.getRect(), + definitions, + this.options, + {sentence, url} + ); this.lastTextSource = textSource; if (this.options.scanning.selectText) { @@ -204,8 +210,7 @@ window.driver = new class { handleError(error, textSource) { if (window.orphaned) { if (textSource && this.options.scanning.requireShift) { - this.popup.showNextTo(textSource.getRect(), this.options); - this.popup.showOrphaned(); + this.popup.showOrphaned(textSource.getRect(), this.options); } } else { window.alert(`Error: ${error}`); diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 210a3688..cd7e846a 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -26,67 +26,65 @@ class Popup { this.container.setAttribute('src', chrome.extension.getURL('/fg/frame.html')); this.container.style.width = '0px'; this.container.style.height = '0px'; - this.injected = false; + this.injected = null; } inject() { if (!this.injected) { - document.body.appendChild(this.container); - this.injected = true; + this.injected = new Promise((resolve, reject) => { + this.container.addEventListener('load', resolve); + document.body.appendChild(this.container); + }); } + + return this.injected; } - showAt(rect) { - this.inject(); + show(elementRect, options) { + return this.inject().then(() => { + const containerStyle = window.getComputedStyle(this.container); + const containerHeight = parseInt(containerStyle.height); + const containerWidth = parseInt(containerStyle.width); - this.container.style.left = `${rect.x}px`; - this.container.style.top = `${rect.y}px`; - this.container.style.height = `${rect.height}px`; - this.container.style.width = `${rect.width}px`; - this.container.style.visibility = 'visible'; - } + const limitX = document.body.clientWidth; + const limitY = window.innerHeight; - showNextTo(elementRect, options) { - this.inject(); - - const containerStyle = window.getComputedStyle(this.container); - const containerHeight = parseInt(containerStyle.height); - const containerWidth = parseInt(containerStyle.width); - - const limitX = document.body.clientWidth; - const limitY = window.innerHeight; - - let x = elementRect.left; - let width = Math.max(containerWidth, options.general.popupWidth); - const overflowX = Math.max(x + width - limitX, 0); - if (overflowX > 0) { - if (x >= overflowX) { - x -= overflowX; - } else { - width = limitX; - x = 0; + let x = elementRect.left; + let width = Math.max(containerWidth, options.general.popupWidth); + const overflowX = Math.max(x + width - limitX, 0); + if (overflowX > 0) { + if (x >= overflowX) { + x -= overflowX; + } else { + width = limitX; + x = 0; + } } - } - let y = 0; - let height = Math.max(containerHeight, options.general.popupHeight); - const yBelow = elementRect.bottom + options.general.popupOffset; - const yAbove = elementRect.top - options.general.popupOffset; - const overflowBelow = Math.max(yBelow + height - limitY, 0); - const overflowAbove = Math.max(height - yAbove, 0); - if (overflowBelow > 0 || overflowAbove > 0) { - if (overflowBelow < overflowAbove) { - height = Math.max(height - overflowBelow, 0); + let y = 0; + let height = Math.max(containerHeight, options.general.popupHeight); + const yBelow = elementRect.bottom + options.general.popupOffset; + const yAbove = elementRect.top - options.general.popupOffset; + const overflowBelow = Math.max(yBelow + height - limitY, 0); + const overflowAbove = Math.max(height - yAbove, 0); + if (overflowBelow > 0 || overflowAbove > 0) { + if (overflowBelow < overflowAbove) { + height = Math.max(height - overflowBelow, 0); + y = yBelow; + } else { + height = Math.max(height - overflowAbove, 0); + y = Math.max(yAbove - height, 0); + } + } else { y = yBelow; - } else { - height = Math.max(height - overflowAbove, 0); - y = Math.max(yAbove - height, 0); } - } else { - y = yBelow; - } - this.showAt({x, y, width, height}); + this.container.style.left = `${x}px`; + this.container.style.top = `${y}px`; + this.container.style.width = `${width}px`; + this.container.style.height = `${height}px`; + this.container.style.visibility = 'visible'; + }); } hide() { @@ -97,16 +95,22 @@ class Popup { return this.injected && this.container.style.visibility !== 'hidden'; } - showTermDefs(definitions, options, context) { - this.invokeApi('showTermDefs', {definitions, options, context}); + showTermDefs(elementRect, definitions, options, context) { + this.show(elementRect, options).then(() => { + this.invokeApi('showTermDefs', {definitions, options, context}); + }); } - showKanjiDefs(definitions, options, context) { - this.invokeApi('showKanjiDefs', {definitions, options, context}); + showKanjiDefs(elementRect, definitions, options, context) { + this.show(elementRect, options).then(() => { + this.invokeApi('showKanjiDefs', {definitions, options, context}); + }); } - showOrphaned() { - this.invokeApi('showOrphaned'); + showOrphaned(elementRect, options) { + this.show(elementRect, options).then(() => { + this.invokeApi('showOrphaned'); + }); } invokeApi(action, params={}) {