From c7fd0306c3c2ad43dc7d239efda6621043974873 Mon Sep 17 00:00:00 2001 From: maekawa Date: Wed, 17 Mar 2021 00:10:26 +0900 Subject: [PATCH] update: make window resizable --- package-lock.json | 2 +- package.json | 2 +- readme.md | 2 +- src/assets/resize.svg | 126 ++++++++++++++++++++++++++ src/background.js | 10 +-- src/content-scripts/App.vue | 173 +++++++++++++++++++++++++++++------- src/options/App.vue | 22 +++-- 7 files changed, 290 insertions(+), 47 deletions(-) create mode 100644 src/assets/resize.svg diff --git a/package-lock.json b/package-lock.json index 3214657..d5561a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "lazy-translator", - "version": "1.4.0", + "version": "1.5.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index c1ca7e3..9e77aa9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lazy-translator", - "version": "1.4.0", + "version": "1.5.0", "description": "extension that translates and lookup imported dictionary", "author": "tempe", "license": "MIT", diff --git a/readme.md b/readme.md index 5e4196f..71d8ac0 100644 --- a/readme.md +++ b/readme.md @@ -46,7 +46,7 @@ $ npm install ``` ## 開発中 -ブラウザから `dist` ディレクトリを行うことで、ホットリロードしながら開発が行なえます。 +ブラウザから `dist` ディレクトリを読み込むことで、ホットリロードしながら開発することが出来ます。 ```shell $ npm run serve ``` diff --git a/src/assets/resize.svg b/src/assets/resize.svg new file mode 100644 index 0000000..f154c32 --- /dev/null +++ b/src/assets/resize.svg @@ -0,0 +1,126 @@ + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/background.js b/src/background.js index 2357c9e..e8b8333 100644 --- a/src/background.js +++ b/src/background.js @@ -1,5 +1,5 @@ browser.runtime.onInstalled.addListener(() => { - chrome.storage.local.set({ isExtensionOn: 1 }); + chrome.storage.local.set({ LazyTranslator_isExtensionOn: 1 }); }); function sendMsg2AllTab(message) { @@ -12,8 +12,8 @@ function sendMsg2AllTab(message) { function getCurrentMode() { return new Promise((resolve) => { - chrome.storage.local.get('isExtensionOn', (res) => { - resolve(res.isExtensionOn); + chrome.storage.local.get('LazyTranslator_isExtensionOn', (res) => { + resolve(res.LazyTranslator_isExtensionOn); }); }); } @@ -22,11 +22,11 @@ async function toggleMode() { const currentMode = await getCurrentMode(); if (currentMode === 1) { chrome.browserAction.setIcon({ path: './icons/icon_48_gray.png' }); - chrome.storage.local.set({ isExtensionOn: 0 }); + chrome.storage.local.set({ LazyTranslator_isExtensionOn: 0 }); sendMsg2AllTab({ func: 'toggleMode', data: { isEnabled: false } }); // disable content script } else { chrome.browserAction.setIcon({ path: './icons/icon_48.png' }); - chrome.storage.local.set({ isExtensionOn: 1 }); + chrome.storage.local.set({ LazyTranslator_isExtensionOn: 1 }); sendMsg2AllTab({ func: 'toggleMode', data: { isEnabled: true } }); // enable content script } } diff --git a/src/content-scripts/App.vue b/src/content-scripts/App.vue index ec57220..47e91ea 100644 --- a/src/content-scripts/App.vue +++ b/src/content-scripts/App.vue @@ -1,16 +1,19 @@ @@ -22,37 +25,86 @@ export default { data() { return { isEnabled: true, + isInitialized: false, + isResizing: false, show: false, mode: null, resFromDict: [], translated: '', apiError: false, + contentWidth: 400, + contentHeight: 30, + contentPadding: 20, + contentBorder: 6, + resizerRadius: 5, }; }, + computed: { + resizerPositionLeft() { + return this.contentWidth + this.contentPadding + this.contentBorder - this.resizerRadius; + }, + resizerPositionBottom() { + return this.contentHeight + this.contentPadding - this.resizerRadius; + }, + }, + watch: { + show(newValue) { + this.updateContainerShowStatus(newValue); + }, + }, created() { - // check if extension is turned ON - chrome.storage.local.get('isExtensionOn', (res) => { - this.isEnabled = res.isExtensionOn === 1; - }); + this.fetchAndApplyExtensionDataFromStorage(); this.setListeners(); }, mounted() { browser.runtime.onMessage.addListener((req) => { if (req.func === 'toggleMode') { - this.show = false; // hide + this.show = false; this.isEnabled = req.data.isEnabled; } }); + this.updatePositionStyle(); + this.updateContainerShowStatus(); + + const resizeObserver = new ResizeObserver((entries) => { + for (const entry of entries) { + if (entry.target.nodeName !== 'BODY') { return; } + if (!this.contentWidth || !this.contentHeight) { return; } + // even if window size is resized smaller than lazytranslator element, keep resizer visible + // after window getting bigger than lazytranslator element, reset resizer position + if ((this.contentWidth + this.contentPadding + this.contentBorder) > document.body.clientWidth) { + this.$refs.resizer.style.left = `${document.body.clientWidth - 20}px`; + } else { + this.$refs.resizer.style.left = `${this.resizerPositionLeft}px`; + } + if ((this.contentHeight + this.contentPadding) > window.innerHeight) { + this.$refs.resizer.style.bottom = `${window.innerHeight - 20}px`; + } else { + this.$refs.resizer.style.bottom = `${this.resizerPositionBottom}px`; + } + } + }); + resizeObserver.observe(document.body); + + // consider initialize time to calculate contents height and hide it + setTimeout(() => { + this.isInitialized = true; + }, 100); }, methods: { setListeners() { window.addEventListener('mouseup', () => { + if (this.isResizing) { return; } const selectedString = this.getSelected(); this.check(selectedString); }); window.addEventListener('message', (e) => { - if (e.data.extension === 'lazyTranslator') { - this.check(e.data.selectedString); + if (!e.data || (e.data.extension !== 'lazyTranslator')) { return; } + if (e.data.selectedString) { this.check(e.data.selectedString); } + if (e.data.contentWidth || e.data.contentHeight) { + this.contentWidth = e.data.contentWidth || this.contentWidth; + this.contentHeight = e.data.contentHeight || this.contentHeight; + this.updatePositionStyle(); } }); }, @@ -95,8 +147,6 @@ export default { async setResultFromTranslateApi(text) { try { const url = `https://translate.googleapis.com/translate_a/single?dt=t&dt=bd&dt=qc&dt=rm&dt=ex&client=gtx&hl=ja&sl=auto&tl=ja&q=${encodeURI(text)}&dj=1`; - // const body = text; - // const headers = { 'Content-Type': 'text/plain' }; const response = await fetch(url); const json = await response.json(); this.translated = ''; @@ -166,36 +216,82 @@ export default { * reset scroll position of translator div */ resetScroll() { - this.$refs.mainElement.scrollTop = 0; + this.$refs.content.scrollTop = 0; + }, + resizeStart() { + document.onmousemove = this.resize; + document.onmouseup = this.resizeEnd; + this.isResizing = true; + }, + resize(e) { + this.contentWidth = e.clientX - this.contentPadding - this.contentBorder - this.resizerRadius; + this.contentHeight = window.innerHeight - e.clientY - this.contentPadding - this.resizerRadius; + this.updatePositionStyle(); }, + resizeEnd() { + document.onmousemove = null; + document.onmouseup = null; + // avoid mouseup event firing by resizing content + setTimeout(() => { + this.isResizing = false; + }, 100); + }, + fetchAndApplyExtensionDataFromStorage() { + chrome.storage.local.get(['LazyTranslator_isExtensionOn', 'LazyTranslator_ContentWidth', 'LazyTranslator_ContentHeight'], (res) => { + this.isEnabled = res.LazyTranslator_isExtensionOn === 1; + if (!res.LazyTranslator_ContentWidth || !res.LazyTranslator_ContentHeight) { return; } + this.contentWidth = res.LazyTranslator_ContentWidth; + this.contentHeight = res.LazyTranslator_ContentHeight; + this.updatePositionStyle(); + this.updateContainerShowStatus(); + }); + }, + updatePositionStyle() { + this.$refs.content.style.width = `${this.contentWidth}px`; + this.$refs.content.style.height = `${this.contentHeight}px`; + this.$refs.resizer.style.left = `${this.resizerPositionLeft}px`; + this.$refs.resizer.style.bottom = `${this.resizerPositionBottom}px`; + if (!this.contentWidth || !this.contentHeight) { return; } + chrome.storage.local.set({ + LazyTranslator_ContentWidth: this.contentWidth, + LazyTranslator_ContentHeight: this.contentHeight, + }); + }, + updateContainerShowStatus(value = false) { + if (value) { + this.$refs.container.style.bottom = '0px'; + } else { + this.$refs.container.style.bottom = `${-this.contentHeight - 30}px`; + } + }, }, }; diff --git a/src/options/App.vue b/src/options/App.vue index 5a274ee..c208515 100644 --- a/src/options/App.vue +++ b/src/options/App.vue @@ -62,18 +62,30 @@ export default { async clearDict() { // remember current settings let isExtensionOn = true; + let contentWidth = 400; + let contentHeight = 30; await new Promise((resolve) => { - chrome.storage.local.get('isExtensionOn', (value) => { - if (value.isExtensionOn) { - isExtensionOn = value.isExtensionOn; - resolve(); + chrome.storage.local.get(['LazyTranslator_isExtensionOn', 'LazyTranslator_ContentWidth', 'LazyTranslator_ContentHeight'], (value) => { + if (value.LazyTranslator_isExtensionOn) { + isExtensionOn = value.LazyTranslator_isExtensionOn; } + if (value.LazyTranslator_ContentWidth) { + contentWidth = value.LazyTranslator_ContentWidth; + } + if (value.LazyTranslator_ContentHeight) { + contentHeight = value.LazyTranslator_ContentHeight; + } + resolve(); }); }); // clear local storage chrome.storage.local.clear(); // restore settings - chrome.storage.local.set({ isExtensionOn }); + chrome.storage.local.set({ + LazyTranslator_isExtensionOn: isExtensionOn, + LazyTranslator_ContentWidth: contentWidth, + LazyTranslator_ContentHeight: contentHeight, + }); this.updateProgress('辞書データを削除しました'); // close modal this.modal = false;