From 6183864f164a44bcb24e98ad2150ac9aafe371d3 Mon Sep 17 00:00:00 2001 From: Alex Yatskov Date: Sun, 11 Sep 2016 19:47:40 -0700 Subject: Cleanup --- ext/fg/js/client.js | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'ext/fg/js/client.js') diff --git a/ext/fg/js/client.js b/ext/fg/js/client.js index 628d5b30..ebfb1090 100644 --- a/ext/fg/js/client.js +++ b/ext/fg/js/client.js @@ -23,6 +23,7 @@ class Client { this.audio = {}; this.lastMousePos = null; this.lastTextSource = null; + this.pendingLookup = false; this.activateKey = 16; this.activateBtn = 2; this.enabled = false; @@ -36,8 +37,8 @@ class Client { window.addEventListener('mousedown', this.onMouseDown.bind(this)); window.addEventListener('mousemove', this.onMouseMove.bind(this)); window.addEventListener('keydown', this.onKeyDown.bind(this)); - window.addEventListener('scroll', (e) => this.hidePopup()); - window.addEventListener('resize', (e) => this.hidePopup()); + window.addEventListener('scroll', e => this.hidePopup()); + window.addEventListener('resize', e => this.hidePopup()); } onKeyDown(e) { @@ -89,11 +90,16 @@ class Client { return; } + if (this.pendingLookup) { + return; + } + textSource.setEndOffset(this.options.scanLength); let defs = []; let seq = -1; + this.pendingLookup = true; bgFindTerm(textSource.text()) .then(({definitions, length}) => { if (length === 0) { @@ -103,7 +109,7 @@ class Client { textSource.setEndOffset(length); const sentence = Client.extractSentence(textSource, this.options.sentenceExtent); - definitions.forEach((definition) => { + definitions.forEach(definition => { definition.url = window.location.href; definition.sentence = sentence; }); @@ -113,17 +119,21 @@ class Client { return bgRenderText({definitions, root: this.fgRoot, options: this.options, sequence: seq}, 'term-list.html'); }) - .then((content) => { + .then(content => { this.definitions = defs; this.showPopup(textSource, content); return bgCanAddDefinitions(defs, ['term_kanji', 'term_kana']); }) - .then((states) => { + .then(states => { + this.pendingLookup = false; if (states !== null) { states.forEach((state, index) => this.popup.sendMessage('setActionState', {index, state, sequence: seq})); } - }, () => this.hidePopup()); + }, () => { + this.pendingLookup = false; + this.hidePopup(); + }); } showPopup(textSource, content) { @@ -159,7 +169,7 @@ class Client { api_addNote({index, mode}) { const state = {[mode]: false}; - bgAddDefinition(this.definitions[index], mode).then((success) => { + bgAddDefinition(this.definitions[index], mode).then(success => { if (success) { this.popup.sendMessage('setActionState', {index, state, sequence: this.sequence}); } else { @@ -192,21 +202,21 @@ class Client { let seq = -1; bgFindKanji(kanji) - .then((definitions) => { - definitions.forEach((definition) => definition.url = window.location.href); + .then(definitions => { + definitions.forEach(definition => definition.url = window.location.href); defs = definitions; seq = ++this.sequence; return bgRenderText({definitions, root: this.fgRoot, options: this.options, sequence: seq}, 'kanji-list.html'); }) - .then((content) => { + .then(content => { this.definitions = defs; this.popup.setContent(content, defs); return bgCanAddDefinitions(defs, ['kanji']); }) - .then((states) => { + .then(states => { if (states !== null) { states.forEach((state, index) => this.popup.sendMessage('setActionState', {index, state, sequence: seq})); } @@ -217,7 +227,7 @@ class Client { const element = document.elementFromPoint(point.x, point.y); if (element !== null) { const names = ['IMG', 'INPUT', 'BUTTON', 'TEXTAREA']; - if (names.indexOf(element.nodeName) !== -1) { + if (names.includes(element.nodeName)) { return new TextSourceElement(element); } } @@ -246,7 +256,7 @@ class Client { for (let i = position; i >= startPos; --i) { const c = content[i]; - if (quoteStack.length === 0 && (terminators.indexOf(c) !== -1 || c in quotesFwd)) { + if (quoteStack.length === 0 && (terminators.includes(c) || c in quotesFwd)) { startPos = i + 1; break; } @@ -265,7 +275,7 @@ class Client { const c = content[i]; if (quoteStack.length === 0) { - if (terminators.indexOf(c) !== -1) { + if (terminators.includes(c)) { endPos = i + 1; break; } -- cgit v1.2.3 From 8f776cf759c0572904afbed5fc168883e8d3324f Mon Sep 17 00:00:00 2001 From: Alex Yatskov Date: Sun, 11 Sep 2016 20:18:34 -0700 Subject: Cleanup --- ext/fg/js/client.js | 92 +++++++++++++++++++++-------------------------------- 1 file changed, 37 insertions(+), 55 deletions(-) (limited to 'ext/fg/js/client.js') diff --git a/ext/fg/js/client.js b/ext/fg/js/client.js index ebfb1090..8f9fdc08 100644 --- a/ext/fg/js/client.js +++ b/ext/fg/js/client.js @@ -24,8 +24,6 @@ class Client { this.lastMousePos = null; this.lastTextSource = null; this.pendingLookup = false; - this.activateKey = 16; - this.activateBtn = 2; this.enabled = false; this.options = {}; this.definitions = null; @@ -42,21 +40,21 @@ class Client { } onKeyDown(e) { - if (this.enabled && this.lastMousePos !== null && (e.keyCode === this.activateKey || e.charCode === this.activateKey)) { + if (this.enabled && this.lastMousePos !== null && (e.keyCode === 16 || e.charCode === 16)) { this.searchAt(this.lastMousePos); } } onMouseMove(e) { this.lastMousePos = {x: e.clientX, y: e.clientY}; - if (this.enabled && (e.shiftKey || e.which === this.activateBtn)) { + if (this.enabled && (e.shiftKey || e.which === 2)) { this.searchAt(this.lastMousePos); } } onMouseDown(e) { this.lastMousePos = {x: e.clientX, y: e.clientY}; - if (this.enabled && (e.shiftKey || e.which === this.activateBtn)) { + if (this.enabled && (e.shiftKey || e.which === 2)) { this.searchAt(this.lastMousePos); } else { this.hidePopup(); @@ -80,6 +78,10 @@ class Client { } searchAt(point) { + if (this.pendingLookup) { + return; + } + const textSource = Client.textSourceFromPoint(point); if (textSource === null || !textSource.containsPoint(point)) { this.hidePopup(); @@ -90,22 +92,13 @@ class Client { return; } - if (this.pendingLookup) { - return; - } - textSource.setEndOffset(this.options.scanLength); - let defs = []; - let seq = -1; - this.pendingLookup = true; - bgFindTerm(textSource.text()) - .then(({definitions, length}) => { - if (length === 0) { - return Promise.reject(); - } - + bgFindTerm(textSource.text()).then(({definitions, length}) => { + if (length === 0) { + this.hidePopup(); + } else { textSource.setEndOffset(length); const sentence = Client.extractSentence(textSource, this.options.sentenceExtent); @@ -114,26 +107,18 @@ class Client { definition.sentence = sentence; }); - defs = definitions; - seq = ++this.sequence; - - return bgRenderText({definitions, root: this.fgRoot, options: this.options, sequence: seq}, 'term-list.html'); - }) - .then(content => { - this.definitions = defs; - this.showPopup(textSource, content); - - return bgCanAddDefinitions(defs, ['term_kanji', 'term_kana']); - }) - .then(states => { - this.pendingLookup = false; - if (states !== null) { - states.forEach((state, index) => this.popup.sendMessage('setActionState', {index, state, sequence: seq})); - } - }, () => { - this.pendingLookup = false; - this.hidePopup(); - }); + const sequence = ++this.sequence; + return bgRenderText({definitions, sequence, root: this.fgRoot, options: this.options}, 'term-list.html').then((content) => { + this.definitions = definitions; + this.showPopup(textSource, content); + return bgCanAddDefinitions(definitions, ['term_kanji', 'term_kana']); + }).then(states => { + if (states !== null) { + states.forEach((state, index) => this.popup.sendMessage('setActionState', {index, state, sequence })); + } + }); + } + }).then(() => this.pendingLookup = false); } showPopup(textSource, content) { @@ -201,26 +186,23 @@ class Client { let defs = []; let seq = -1; - bgFindKanji(kanji) - .then(definitions => { - definitions.forEach(definition => definition.url = window.location.href); + bgFindKanji(kanji).then(definitions => { + definitions.forEach(definition => definition.url = window.location.href); - defs = definitions; - seq = ++this.sequence; + defs = definitions; + seq = ++this.sequence; - return bgRenderText({definitions, root: this.fgRoot, options: this.options, sequence: seq}, 'kanji-list.html'); - }) - .then(content => { - this.definitions = defs; - this.popup.setContent(content, defs); + return bgRenderText({definitions, root: this.fgRoot, options: this.options, sequence: seq}, 'kanji-list.html'); + }).then(content => { + this.definitions = defs; + this.popup.setContent(content, defs); - return bgCanAddDefinitions(defs, ['kanji']); - }) - .then(states => { - if (states !== null) { - states.forEach((state, index) => this.popup.sendMessage('setActionState', {index, state, sequence: seq})); - } - }); + return bgCanAddDefinitions(defs, ['kanji']); + }).then(states => { + if (states !== null) { + states.forEach((state, index) => this.popup.sendMessage('setActionState', {index, state, sequence: seq})); + } + }); } static textSourceFromPoint(point) { -- cgit v1.2.3 From f653195aed4fe1ce12b771cb1e5de06d9e6f0253 Mon Sep 17 00:00:00 2001 From: Alex Yatskov Date: Sun, 11 Sep 2016 20:35:53 -0700 Subject: Cleanup --- ext/fg/js/client.js | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) (limited to 'ext/fg/js/client.js') diff --git a/ext/fg/js/client.js b/ext/fg/js/client.js index 8f9fdc08..266e4b5a 100644 --- a/ext/fg/js/client.js +++ b/ext/fg/js/client.js @@ -183,25 +183,19 @@ class Client { } api_displayKanji(kanji) { - let defs = []; - let seq = -1; - bgFindKanji(kanji).then(definitions => { definitions.forEach(definition => definition.url = window.location.href); - defs = definitions; - seq = ++this.sequence; - - return bgRenderText({definitions, root: this.fgRoot, options: this.options, sequence: seq}, 'kanji-list.html'); - }).then(content => { - this.definitions = defs; - this.popup.setContent(content, defs); - - return bgCanAddDefinitions(defs, ['kanji']); - }).then(states => { - if (states !== null) { - states.forEach((state, index) => this.popup.sendMessage('setActionState', {index, state, sequence: seq})); - } + const sequence = ++this.sequence; + return bgRenderText({definitions, sequence, root: this.fgRoot, options: this.options}, 'kanji-list.html').then(content => { + this.definitions = definitions; + this.popup.setContent(content, definitions); + return bgCanAddDefinitions(definitions, ['kanji']); + }).then(states => { + if (states !== null) { + states.forEach((state, index) => this.popup.sendMessage('setActionState', {index, state, sequence})); + } + }); }); } -- cgit v1.2.3 From fa446f540a3a93d51c457da661d61976bdd5cbdf Mon Sep 17 00:00:00 2001 From: Alex Yatskov Date: Sun, 11 Sep 2016 20:41:41 -0700 Subject: WIP --- ext/fg/js/client.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'ext/fg/js/client.js') diff --git a/ext/fg/js/client.js b/ext/fg/js/client.js index 266e4b5a..9a0ad25a 100644 --- a/ext/fg/js/client.js +++ b/ext/fg/js/client.js @@ -97,6 +97,7 @@ class Client { this.pendingLookup = true; bgFindTerm(textSource.text()).then(({definitions, length}) => { if (length === 0) { + this.pendingLookup = false; this.hidePopup(); } else { textSource.setEndOffset(length); @@ -108,8 +109,9 @@ class Client { }); const sequence = ++this.sequence; - return bgRenderText({definitions, sequence, root: this.fgRoot, options: this.options}, 'term-list.html').then((content) => { + return bgRenderText({definitions, sequence, root: this.fgRoot, options: this.options}, 'term-list.html').then(content => { this.definitions = definitions; + this.pendingLookup = false; this.showPopup(textSource, content); return bgCanAddDefinitions(definitions, ['term_kanji', 'term_kana']); }).then(states => { @@ -118,7 +120,7 @@ class Client { } }); } - }).then(() => this.pendingLookup = false); + }); } showPopup(textSource, content) { -- cgit v1.2.3 From f4314497e401e94ccd2ff88358b5720c73074612 Mon Sep 17 00:00:00 2001 From: Alex Yatskov Date: Sun, 11 Sep 2016 20:59:42 -0700 Subject: Cleanup --- ext/fg/js/api.js | 42 ------------------- ext/fg/js/client.js | 90 +++++------------------------------------ ext/fg/js/frame.js | 6 +-- ext/fg/js/popup.js | 4 +- ext/fg/js/util.js | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++ ext/manifest.json | 2 +- 6 files changed, 129 insertions(+), 129 deletions(-) delete mode 100644 ext/fg/js/api.js create mode 100644 ext/fg/js/util.js (limited to 'ext/fg/js/client.js') diff --git a/ext/fg/js/api.js b/ext/fg/js/api.js deleted file mode 100644 index 643d0360..00000000 --- a/ext/fg/js/api.js +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2016 Alex Yatskov - * Author: Alex Yatskov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -function bgSendMessage(action, params) { - return new Promise((resolve, reject) => chrome.runtime.sendMessage({action, params}, resolve)); -} - -function bgFindTerm(text) { - return bgSendMessage('findTerm', {text}); -} - -function bgFindKanji(text) { - return bgSendMessage('findKanji', {text}); -} - -function bgRenderText(data, template) { - return bgSendMessage('renderText', {data, template}); -} - -function bgCanAddDefinitions(definitions, modes) { - return bgSendMessage('canAddDefinitions', {definitions, modes}); -} - -function bgAddDefinition(definition, mode) { - return bgSendMessage('addDefinition', {definition, mode}); -} diff --git a/ext/fg/js/client.js b/ext/fg/js/client.js index 9a0ad25a..daeabf99 100644 --- a/ext/fg/js/client.js +++ b/ext/fg/js/client.js @@ -82,7 +82,7 @@ class Client { return; } - const textSource = Client.textSourceFromPoint(point); + const textSource = textSourceFromPoint(point); if (textSource === null || !textSource.containsPoint(point)) { this.hidePopup(); return; @@ -95,25 +95,25 @@ class Client { textSource.setEndOffset(this.options.scanLength); this.pendingLookup = true; - bgFindTerm(textSource.text()).then(({definitions, length}) => { + findTerm(textSource.text()).then(({definitions, length}) => { if (length === 0) { this.pendingLookup = false; this.hidePopup(); } else { textSource.setEndOffset(length); - const sentence = Client.extractSentence(textSource, this.options.sentenceExtent); + const sentence = extractSentence(textSource, this.options.sentenceExtent); definitions.forEach(definition => { definition.url = window.location.href; definition.sentence = sentence; }); const sequence = ++this.sequence; - return bgRenderText({definitions, sequence, root: this.fgRoot, options: this.options}, 'term-list.html').then(content => { + return renderText({definitions, sequence, root: this.fgRoot, options: this.options}, 'term-list.html').then(content => { this.definitions = definitions; this.pendingLookup = false; this.showPopup(textSource, content); - return bgCanAddDefinitions(definitions, ['term_kanji', 'term_kana']); + return canAddDefinitions(definitions, ['term_kanji', 'term_kana']); }).then(states => { if (states !== null) { states.forEach((state, index) => this.popup.sendMessage('setActionState', {index, state, sequence })); @@ -156,7 +156,7 @@ class Client { api_addNote({index, mode}) { const state = {[mode]: false}; - bgAddDefinition(this.definitions[index], mode).then(success => { + addDefinition(this.definitions[index], mode).then(success => { if (success) { this.popup.sendMessage('setActionState', {index, state, sequence: this.sequence}); } else { @@ -185,14 +185,14 @@ class Client { } api_displayKanji(kanji) { - bgFindKanji(kanji).then(definitions => { + findKanji(kanji).then(definitions => { definitions.forEach(definition => definition.url = window.location.href); const sequence = ++this.sequence; - return bgRenderText({definitions, sequence, root: this.fgRoot, options: this.options}, 'kanji-list.html').then(content => { + return renderText({definitions, sequence, root: this.fgRoot, options: this.options}, 'kanji-list.html').then(content => { this.definitions = definitions; this.popup.setContent(content, definitions); - return bgCanAddDefinitions(definitions, ['kanji']); + return canAddDefinitions(definitions, ['kanji']); }).then(states => { if (states !== null) { states.forEach((state, index) => this.popup.sendMessage('setActionState', {index, state, sequence})); @@ -200,78 +200,6 @@ class Client { }); }); } - - static textSourceFromPoint(point) { - const element = document.elementFromPoint(point.x, point.y); - if (element !== null) { - const names = ['IMG', 'INPUT', 'BUTTON', 'TEXTAREA']; - if (names.includes(element.nodeName)) { - return new TextSourceElement(element); - } - } - - const range = document.caretRangeFromPoint(point.x, point.y); - if (range !== null) { - return new TextSourceRange(range); - } - - return null; - } - - static extractSentence(source, extent) { - const quotesFwd = {'「': '」', '『': '』', "'": "'", '"': '"'}; - const quotesBwd = {'」': '「', '』': '『', "'": "'", '"': '"'}; - const terminators = '…。..??!!'; - - const sourceLocal = source.clone(); - const position = sourceLocal.setStartOffset(extent); - sourceLocal.setEndOffset(position + extent); - const content = sourceLocal.text(); - - let quoteStack = []; - - let startPos = 0; - for (let i = position; i >= startPos; --i) { - const c = content[i]; - - if (quoteStack.length === 0 && (terminators.includes(c) || c in quotesFwd)) { - startPos = i + 1; - break; - } - - if (quoteStack.length > 0 && c === quoteStack[0]) { - quoteStack.pop(); - } else if (c in quotesBwd) { - quoteStack = [quotesBwd[c]].concat(quoteStack); - } - } - - quoteStack = []; - - let endPos = content.length; - for (let i = position; i < endPos; ++i) { - const c = content[i]; - - if (quoteStack.length === 0) { - if (terminators.includes(c)) { - endPos = i + 1; - break; - } - else if (c in quotesBwd) { - endPos = i; - break; - } - } - - if (quoteStack.length > 0 && c === quoteStack[0]) { - quoteStack.pop(); - } else if (c in quotesFwd) { - quoteStack = [quotesFwd[c]].concat(quoteStack); - } - } - - return content.substring(startPos, endPos).trim(); - } } window.yomiClient = new Client(); diff --git a/ext/fg/js/frame.js b/ext/fg/js/frame.js index 8f3d3877..30cb7c73 100644 --- a/ext/fg/js/frame.js +++ b/ext/fg/js/frame.js @@ -19,7 +19,7 @@ function registerKanjiLinks() { for (const link of Array.from(document.getElementsByClassName('kanji-link'))) { - link.addEventListener('click', (e) => { + link.addEventListener('click', e => { e.preventDefault(); window.parent.postMessage({action: 'displayKanji', params: e.target.innerHTML}, '*'); }); @@ -28,7 +28,7 @@ function registerKanjiLinks() { function registerAddNoteLinks() { for (const link of Array.from(document.getElementsByClassName('action-add-note'))) { - link.addEventListener('click', (e) => { + link.addEventListener('click', e => { e.preventDefault(); const ds = e.currentTarget.dataset; window.parent.postMessage({action: 'addNote', params: {index: ds.index, mode: ds.mode}}, '*'); @@ -38,7 +38,7 @@ function registerAddNoteLinks() { function registerAudioLinks() { for (const link of Array.from(document.getElementsByClassName('action-play-audio'))) { - link.addEventListener('click', (e) => { + link.addEventListener('click', e => { e.preventDefault(); const ds = e.currentTarget.dataset; window.parent.postMessage({action: 'playAudio', params: ds.index}, '*'); diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index a0eb725c..930df18d 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -81,8 +81,8 @@ class Popup { this.popup = document.createElement('iframe'); this.popup.id = 'yomichan-popup'; - this.popup.addEventListener('mousedown', (e) => e.stopPropagation()); - this.popup.addEventListener('scroll', (e) => e.stopPropagation()); + this.popup.addEventListener('mousedown', e => e.stopPropagation()); + this.popup.addEventListener('scroll', e => e.stopPropagation()); document.body.appendChild(this.popup); } diff --git a/ext/fg/js/util.js b/ext/fg/js/util.js new file mode 100644 index 00000000..176765fc --- /dev/null +++ b/ext/fg/js/util.js @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2016 Alex Yatskov + * Author: Alex Yatskov + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +function sendMessage(action, params) { + return new Promise((resolve, reject) => chrome.runtime.sendMessage({action, params}, resolve)); +} + +function findTerm(text) { + return sendMessage('findTerm', {text}); +} + +function findKanji(text) { + return sendMessage('findKanji', {text}); +} + +function renderText(data, template) { + return sendMessage('renderText', {data, template}); +} + +function canAddDefinitions(definitions, modes) { + return sendMessage('canAddDefinitions', {definitions, modes}); +} + +function addDefinition(definition, mode) { + return sendMessage('addDefinition', {definition, mode}); +} + +function textSourceFromPoint(point) { + const element = document.elementFromPoint(point.x, point.y); + if (element !== null) { + const names = ['IMG', 'INPUT', 'BUTTON', 'TEXTAREA']; + if (names.includes(element.nodeName)) { + return new TextSourceElement(element); + } + } + + const range = document.caretRangeFromPoint(point.x, point.y); + if (range !== null) { + return new TextSourceRange(range); + } + + return null; +} + +function extractSentence(source, extent) { + const quotesFwd = {'「': '」', '『': '』', "'": "'", '"': '"'}; + const quotesBwd = {'」': '「', '』': '『', "'": "'", '"': '"'}; + const terminators = '…。..??!!'; + + const sourceLocal = source.clone(); + const position = sourceLocal.setStartOffset(extent); + sourceLocal.setEndOffset(position + extent); + const content = sourceLocal.text(); + + let quoteStack = []; + + let startPos = 0; + for (let i = position; i >= startPos; --i) { + const c = content[i]; + + if (quoteStack.length === 0 && (terminators.includes(c) || c in quotesFwd)) { + startPos = i + 1; + break; + } + + if (quoteStack.length > 0 && c === quoteStack[0]) { + quoteStack.pop(); + } else if (c in quotesBwd) { + quoteStack = [quotesBwd[c]].concat(quoteStack); + } + } + + quoteStack = []; + + let endPos = content.length; + for (let i = position; i < endPos; ++i) { + const c = content[i]; + + if (quoteStack.length === 0) { + if (terminators.includes(c)) { + endPos = i + 1; + break; + } + else if (c in quotesBwd) { + endPos = i; + break; + } + } + + if (quoteStack.length > 0 && c === quoteStack[0]) { + quoteStack.pop(); + } else if (c in quotesFwd) { + quoteStack = [quotesFwd[c]].concat(quoteStack); + } + } + + return content.substring(startPos, endPos).trim(); +} diff --git a/ext/manifest.json b/ext/manifest.json index 080f6f4f..c3864e10 100644 --- a/ext/manifest.json +++ b/ext/manifest.json @@ -15,7 +15,7 @@ "fg/js/source-range.js", "fg/js/source-element.js", "fg/js/popup.js", - "fg/js/api.js", + "fg/js/util.js", "fg/js/client.js" ], "css": ["fg/css/client.css"] -- cgit v1.2.3 From b969e8952c551fdc7c150dcc111eccdc90ac7408 Mon Sep 17 00:00:00 2001 From: Alex Yatskov Date: Thu, 15 Sep 2016 21:03:58 -0700 Subject: Cleanup --- ext/bg/js/translator.js | 6 +++--- ext/fg/js/client.js | 6 +++--- ext/fg/js/frame.js | 10 +++++++--- ext/fg/js/popup.js | 2 +- ext/fg/js/util.js | 12 ++++++------ 5 files changed, 20 insertions(+), 16 deletions(-) (limited to 'ext/fg/js/client.js') diff --git a/ext/bg/js/translator.js b/ext/bg/js/translator.js index 2331bde7..e534e0cb 100644 --- a/ext/bg/js/translator.js +++ b/ext/bg/js/translator.js @@ -54,10 +54,10 @@ class Translator { percent += banks[url].loaded / banks[url].total; } - percent /= 3; + percent /= 3.0; if (callback) { - callback({state: 'update', progress: Math.ceil(100 * percent)}); + callback({state: 'update', progress: Math.ceil(100.0 * percent)}); } }; @@ -69,7 +69,7 @@ class Translator { return this.dictionary.sealDb(); }).then(() => { if (callback) { - callback({state: 'end', progress: 100}); + callback({state: 'end', progress: 100.0}); } }); }).then(() => { diff --git a/ext/fg/js/client.js b/ext/fg/js/client.js index daeabf99..717b5873 100644 --- a/ext/fg/js/client.js +++ b/ext/fg/js/client.js @@ -116,7 +116,7 @@ class Client { return canAddDefinitions(definitions, ['term_kanji', 'term_kana']); }).then(states => { if (states !== null) { - states.forEach((state, index) => this.popup.sendMessage('setActionState', {index, state, sequence })); + states.forEach((state, index) => this.popup.invokeApi('setActionState', {index, state, sequence})); } }); } @@ -158,7 +158,7 @@ class Client { const state = {[mode]: false}; addDefinition(this.definitions[index], mode).then(success => { if (success) { - this.popup.sendMessage('setActionState', {index, state, sequence: this.sequence}); + this.popup.invokeApi('setActionState', {index, state, sequence: this.sequence}); } else { alert('Note could not be added'); } @@ -195,7 +195,7 @@ class Client { return canAddDefinitions(definitions, ['kanji']); }).then(states => { if (states !== null) { - states.forEach((state, index) => this.popup.sendMessage('setActionState', {index, state, sequence})); + states.forEach((state, index) => this.popup.invokeApi('setActionState', {index, state, sequence})); } }); }); diff --git a/ext/fg/js/frame.js b/ext/fg/js/frame.js index 590646d5..8a99a405 100644 --- a/ext/fg/js/frame.js +++ b/ext/fg/js/frame.js @@ -17,11 +17,15 @@ */ +function invokeApi(action, params, target) { + target.postMessage({action, params}, '*'); +} + function registerKanjiLinks() { for (const link of Array.from(document.getElementsByClassName('kanji-link'))) { link.addEventListener('click', e => { e.preventDefault(); - window.parent.postMessage({action: 'displayKanji', params: e.target.innerHTML}, '*'); + invokeApi('displayKanji', e.target.innerHTML, window.parent); }); } } @@ -31,7 +35,7 @@ function registerAddNoteLinks() { link.addEventListener('click', e => { e.preventDefault(); const ds = e.currentTarget.dataset; - window.parent.postMessage({action: 'addNote', params: {index: ds.index, mode: ds.mode}}, '*'); + invokeApi('addNote', {index: ds.index, mode: ds.mode}, window.parent); }); } } @@ -41,7 +45,7 @@ function registerAudioLinks() { link.addEventListener('click', e => { e.preventDefault(); const ds = e.currentTarget.dataset; - window.parent.postMessage({action: 'playAudio', params: ds.index}, '*'); + invokeApi('playAudio', ds.index, window.parent); }); } } diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 930df18d..88b8e4e3 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -68,7 +68,7 @@ class Popup { doc.close(); } - sendMessage(action, params, callback) { + invokeApi(action, params) { if (this.popup !== null) { this.popup.contentWindow.postMessage({action, params}, '*'); } diff --git a/ext/fg/js/util.js b/ext/fg/js/util.js index 176765fc..c24ad885 100644 --- a/ext/fg/js/util.js +++ b/ext/fg/js/util.js @@ -17,28 +17,28 @@ */ -function sendMessage(action, params) { +function invokeApiBg(action, params) { return new Promise((resolve, reject) => chrome.runtime.sendMessage({action, params}, resolve)); } function findTerm(text) { - return sendMessage('findTerm', {text}); + return invokeApiBg('findTerm', {text}); } function findKanji(text) { - return sendMessage('findKanji', {text}); + return invokeApiBg('findKanji', {text}); } function renderText(data, template) { - return sendMessage('renderText', {data, template}); + return invokeApiBg('renderText', {data, template}); } function canAddDefinitions(definitions, modes) { - return sendMessage('canAddDefinitions', {definitions, modes}); + return invokeApiBg('canAddDefinitions', {definitions, modes}); } function addDefinition(definition, mode) { - return sendMessage('addDefinition', {definition, mode}); + return invokeApiBg('addDefinition', {definition, mode}); } function textSourceFromPoint(point) { -- cgit v1.2.3 From dc273c0c73dd39e8cad45e591b02231cb2cbed8c Mon Sep 17 00:00:00 2001 From: Alex Yatskov Date: Thu, 15 Sep 2016 22:44:33 -0700 Subject: Cleanup --- ext/fg/js/client.js | 205 ---------------------------------------------------- ext/fg/js/driver.js | 205 ++++++++++++++++++++++++++++++++++++++++++++++++++++ ext/manifest.json | 2 +- 3 files changed, 206 insertions(+), 206 deletions(-) delete mode 100644 ext/fg/js/client.js create mode 100644 ext/fg/js/driver.js (limited to 'ext/fg/js/client.js') diff --git a/ext/fg/js/client.js b/ext/fg/js/client.js deleted file mode 100644 index 717b5873..00000000 --- a/ext/fg/js/client.js +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (C) 2016 Alex Yatskov - * Author: Alex Yatskov - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -class Client { - constructor() { - this.popup = new Popup(); - this.audio = {}; - this.lastMousePos = null; - this.lastTextSource = null; - this.pendingLookup = false; - this.enabled = false; - this.options = {}; - this.definitions = null; - this.sequence = 0; - this.fgRoot = chrome.extension.getURL('fg'); - - chrome.runtime.onMessage.addListener(this.onBgMessage.bind(this)); - window.addEventListener('message', this.onFrameMessage.bind(this)); - window.addEventListener('mousedown', this.onMouseDown.bind(this)); - window.addEventListener('mousemove', this.onMouseMove.bind(this)); - window.addEventListener('keydown', this.onKeyDown.bind(this)); - window.addEventListener('scroll', e => this.hidePopup()); - window.addEventListener('resize', e => this.hidePopup()); - } - - onKeyDown(e) { - if (this.enabled && this.lastMousePos !== null && (e.keyCode === 16 || e.charCode === 16)) { - this.searchAt(this.lastMousePos); - } - } - - onMouseMove(e) { - this.lastMousePos = {x: e.clientX, y: e.clientY}; - if (this.enabled && (e.shiftKey || e.which === 2)) { - this.searchAt(this.lastMousePos); - } - } - - onMouseDown(e) { - this.lastMousePos = {x: e.clientX, y: e.clientY}; - if (this.enabled && (e.shiftKey || e.which === 2)) { - this.searchAt(this.lastMousePos); - } else { - this.hidePopup(); - } - } - - onBgMessage({action, params}, sender, callback) { - const method = this['api_' + action]; - if (typeof(method) === 'function') { - method.call(this, params); - } - - callback(); - } - - onFrameMessage(e) { - const {action, params} = e.data, method = this['api_' + action]; - if (typeof(method) === 'function') { - method.call(this, params); - } - } - - searchAt(point) { - if (this.pendingLookup) { - return; - } - - const textSource = textSourceFromPoint(point); - if (textSource === null || !textSource.containsPoint(point)) { - this.hidePopup(); - return; - } - - if (this.lastTextSource !== null && this.lastTextSource.equals(textSource)) { - return; - } - - textSource.setEndOffset(this.options.scanLength); - - this.pendingLookup = true; - findTerm(textSource.text()).then(({definitions, length}) => { - if (length === 0) { - this.pendingLookup = false; - this.hidePopup(); - } else { - textSource.setEndOffset(length); - - const sentence = extractSentence(textSource, this.options.sentenceExtent); - definitions.forEach(definition => { - definition.url = window.location.href; - definition.sentence = sentence; - }); - - const sequence = ++this.sequence; - return renderText({definitions, sequence, root: this.fgRoot, options: this.options}, 'term-list.html').then(content => { - this.definitions = definitions; - this.pendingLookup = false; - this.showPopup(textSource, content); - return canAddDefinitions(definitions, ['term_kanji', 'term_kana']); - }).then(states => { - if (states !== null) { - states.forEach((state, index) => this.popup.invokeApi('setActionState', {index, state, sequence})); - } - }); - } - }); - } - - showPopup(textSource, content) { - this.popup.showNextTo(textSource.getRect(), content); - - if (this.options.selectMatchedText) { - textSource.select(); - } - - this.lastTextSource = textSource; - } - - hidePopup() { - this.popup.hide(); - - if (this.options.selectMatchedText && this.lastTextSource !== null) { - this.lastTextSource.deselect(); - } - - this.lastTextSource = null; - this.definitions = null; - } - - api_setOptions(opts) { - this.options = opts; - } - - api_setEnabled(enabled) { - if (!(this.enabled = enabled)) { - this.hidePopup(); - } - } - - api_addNote({index, mode}) { - const state = {[mode]: false}; - addDefinition(this.definitions[index], mode).then(success => { - if (success) { - this.popup.invokeApi('setActionState', {index, state, sequence: this.sequence}); - } else { - alert('Note could not be added'); - } - }); - } - - api_playAudio(index) { - const definition = this.definitions[index]; - - let url = `https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?kanji=${encodeURIComponent(definition.expression)}`; - if (definition.reading) { - url += `&kana=${encodeURIComponent(definition.reading)}`; - } - - for (const key in this.audio) { - this.audio[key].pause(); - } - - const audio = this.audio[url] || new Audio(url); - audio.currentTime = 0; - audio.play(); - - this.audio[url] = audio; - } - - api_displayKanji(kanji) { - findKanji(kanji).then(definitions => { - definitions.forEach(definition => definition.url = window.location.href); - - const sequence = ++this.sequence; - return renderText({definitions, sequence, root: this.fgRoot, options: this.options}, 'kanji-list.html').then(content => { - this.definitions = definitions; - this.popup.setContent(content, definitions); - return canAddDefinitions(definitions, ['kanji']); - }).then(states => { - if (states !== null) { - states.forEach((state, index) => this.popup.invokeApi('setActionState', {index, state, sequence})); - } - }); - }); - } -} - -window.yomiClient = new Client(); diff --git a/ext/fg/js/driver.js b/ext/fg/js/driver.js new file mode 100644 index 00000000..de097980 --- /dev/null +++ b/ext/fg/js/driver.js @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2016 Alex Yatskov + * Author: Alex Yatskov + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +class Driver { + constructor() { + this.popup = new Popup(); + this.audio = {}; + this.lastMousePos = null; + this.lastTextSource = null; + this.pendingLookup = false; + this.enabled = false; + this.options = {}; + this.definitions = null; + this.sequence = 0; + this.fgRoot = chrome.extension.getURL('fg'); + + chrome.runtime.onMessage.addListener(this.onBgMessage.bind(this)); + window.addEventListener('message', this.onFrameMessage.bind(this)); + window.addEventListener('mousedown', this.onMouseDown.bind(this)); + window.addEventListener('mousemove', this.onMouseMove.bind(this)); + window.addEventListener('keydown', this.onKeyDown.bind(this)); + window.addEventListener('scroll', e => this.hidePopup()); + window.addEventListener('resize', e => this.hidePopup()); + } + + onKeyDown(e) { + if (this.enabled && this.lastMousePos !== null && (e.keyCode === 16 || e.charCode === 16)) { + this.searchAt(this.lastMousePos); + } + } + + onMouseMove(e) { + this.lastMousePos = {x: e.clientX, y: e.clientY}; + if (this.enabled && (e.shiftKey || e.which === 2)) { + this.searchAt(this.lastMousePos); + } + } + + onMouseDown(e) { + this.lastMousePos = {x: e.clientX, y: e.clientY}; + if (this.enabled && (e.shiftKey || e.which === 2)) { + this.searchAt(this.lastMousePos); + } else { + this.hidePopup(); + } + } + + onBgMessage({action, params}, sender, callback) { + const method = this['api_' + action]; + if (typeof(method) === 'function') { + method.call(this, params); + } + + callback(); + } + + onFrameMessage(e) { + const {action, params} = e.data, method = this['api_' + action]; + if (typeof(method) === 'function') { + method.call(this, params); + } + } + + searchAt(point) { + if (this.pendingLookup) { + return; + } + + const textSource = textSourceFromPoint(point); + if (textSource === null || !textSource.containsPoint(point)) { + this.hidePopup(); + return; + } + + if (this.lastTextSource !== null && this.lastTextSource.equals(textSource)) { + return; + } + + textSource.setEndOffset(this.options.scanLength); + + this.pendingLookup = true; + findTerm(textSource.text()).then(({definitions, length}) => { + if (length === 0) { + this.pendingLookup = false; + this.hidePopup(); + } else { + textSource.setEndOffset(length); + + const sentence = extractSentence(textSource, this.options.sentenceExtent); + definitions.forEach(definition => { + definition.url = window.location.href; + definition.sentence = sentence; + }); + + const sequence = ++this.sequence; + return renderText({definitions, sequence, root: this.fgRoot, options: this.options}, 'term-list.html').then(content => { + this.definitions = definitions; + this.pendingLookup = false; + this.showPopup(textSource, content); + return canAddDefinitions(definitions, ['term_kanji', 'term_kana']); + }).then(states => { + if (states !== null) { + states.forEach((state, index) => this.popup.invokeApi('setActionState', {index, state, sequence})); + } + }); + } + }); + } + + showPopup(textSource, content) { + this.popup.showNextTo(textSource.getRect(), content); + + if (this.options.selectMatchedText) { + textSource.select(); + } + + this.lastTextSource = textSource; + } + + hidePopup() { + this.popup.hide(); + + if (this.options.selectMatchedText && this.lastTextSource !== null) { + this.lastTextSource.deselect(); + } + + this.lastTextSource = null; + this.definitions = null; + } + + api_setOptions(opts) { + this.options = opts; + } + + api_setEnabled(enabled) { + if (!(this.enabled = enabled)) { + this.hidePopup(); + } + } + + api_addNote({index, mode}) { + const state = {[mode]: false}; + addDefinition(this.definitions[index], mode).then(success => { + if (success) { + this.popup.invokeApi('setActionState', {index, state, sequence: this.sequence}); + } else { + alert('Note could not be added'); + } + }); + } + + api_playAudio(index) { + const definition = this.definitions[index]; + + let url = `https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?kanji=${encodeURIComponent(definition.expression)}`; + if (definition.reading) { + url += `&kana=${encodeURIComponent(definition.reading)}`; + } + + for (const key in this.audio) { + this.audio[key].pause(); + } + + const audio = this.audio[url] || new Audio(url); + audio.currentTime = 0; + audio.play(); + + this.audio[url] = audio; + } + + api_displayKanji(kanji) { + findKanji(kanji).then(definitions => { + definitions.forEach(definition => definition.url = window.location.href); + + const sequence = ++this.sequence; + return renderText({definitions, sequence, root: this.fgRoot, options: this.options}, 'kanji-list.html').then(content => { + this.definitions = definitions; + this.popup.setContent(content, definitions); + return canAddDefinitions(definitions, ['kanji']); + }).then(states => { + if (states !== null) { + states.forEach((state, index) => this.popup.invokeApi('setActionState', {index, state, sequence})); + } + }); + }); + } +} + +window.driver = new Driver(); diff --git a/ext/manifest.json b/ext/manifest.json index c3864e10..fcf7cef7 100644 --- a/ext/manifest.json +++ b/ext/manifest.json @@ -16,7 +16,7 @@ "fg/js/source-element.js", "fg/js/popup.js", "fg/js/util.js", - "fg/js/client.js" + "fg/js/driver.js" ], "css": ["fg/css/client.css"] }], -- cgit v1.2.3