From 62b95a656f5e55395893982822b0388a425f5a29 Mon Sep 17 00:00:00 2001
From: odehjoseph
Search your installed dictionaries by entering a Japanese expression into the field below.
+Search your installed dictionaries by entering a Japanese expression into the field below.
-
- ++
-
Copyright (C) 2016-2017 Alex Yatskov diff --git a/ext/bg/search.html b/ext/bg/search.html index 121b477c..668b2436 100644 --- a/ext/bg/search.html +++ b/ext/bg/search.html @@ -9,7 +9,7 @@ -+Yomichan Search
diff --git a/ext/bg/settings.html b/ext/bg/settings.html index 02780f38..4db0a9b0 100644 --- a/ext/bg/settings.html +++ b/ext/bg/settings.html @@ -9,7 +9,7 @@ -+Profiles
-- cgit v1.2.3 From 9b929ffcd4bf34b784b94137f636a8a483b1f18e Mon Sep 17 00:00:00 2001 From: toasted-nutbreadDate: Sat, 28 Sep 2019 13:30:41 -0400 Subject: Add wrapping for usage conditions on small screens --- ext/bg/css/settings.css | 30 ++++++++++++++++++++++++++++++ ext/bg/settings.html | 3 ++- 2 files changed, 32 insertions(+), 1 deletion(-) (limited to 'ext') diff --git a/ext/bg/css/settings.css b/ext/bg/css/settings.css index 150209e3..12bbe8a8 100644 --- a/ext/bg/css/settings.css +++ b/ext/bg/css/settings.css @@ -48,6 +48,20 @@ border-color: #f00000; } +.condition { + display: flex; + -flex-wrap: wrap; +} +.condition-input { + flex: 1 1 auto; +} +.condition-line-break { + flex: 1 0 100%; + display: none; +} +.condition>.input-group-btn { + width: auto; +} .condition>.condition-prefix:after { content: "IF"; } @@ -55,6 +69,9 @@ content: "AND"; } +.input-group .condition-prefix { + flex: 0 0 auto; +} .input-group .condition-prefix, .input-group .condition-group-separator-label { width: 60px; @@ -122,3 +139,16 @@ margin-top: 15px; } } + +@media screen and (max-width: 600px) { + .condition { + flex-wrap: wrap; + } + .condition-input { + order: 2; + } + .condition-line-break { + display: block; + order: 1; + } +} diff --git a/ext/bg/settings.html b/ext/bg/settings.html index 4db0a9b0..1406826b 100644 --- a/ext/bg/settings.html +++ b/ext/bg/settings.html @@ -105,7 +105,8 @@ - + + -- cgit v1.2.3 From b42fa9581fc6c6ca27a0cf3759f6f029b18f1ab2 Mon Sep 17 00:00:00 2001 From: toasted-nutbread-- cgit v1.2.3 From 8b7558a757447b931ee0dd1b5d724673e98bc13d Mon Sep 17 00:00:00 2001 From: toasted-nutbreadDate: Sat, 28 Sep 2019 13:32:51 -0400 Subject: Fix some incorrect labels --- ext/bg/settings.html | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'ext') diff --git a/ext/bg/settings.html b/ext/bg/settings.html index 1406826b..5a368e91 100644 --- a/ext/bg/settings.html +++ b/ext/bg/settings.html @@ -188,14 +188,14 @@ - +- +@@ -402,7 +403,7 @@- +Date: Sun, 29 Sep 2019 15:26:46 -0400 Subject: Use toIterable for cross-window origin objects --- ext/bg/js/conditions-ui.js | 4 ++-- ext/bg/js/settings.js | 4 ++-- ext/mixed/js/extension.js | 15 +++++++++++++-- 3 files changed, 17 insertions(+), 6 deletions(-) (limited to 'ext') diff --git a/ext/bg/js/conditions-ui.js b/ext/bg/js/conditions-ui.js index a6f54a1c..43c6dc08 100644 --- a/ext/bg/js/conditions-ui.js +++ b/ext/bg/js/conditions-ui.js @@ -36,7 +36,7 @@ ConditionsUI.Container = class Container { this.container.empty(); - for (const conditionGroup of conditionGroups) { + for (const conditionGroup of toIterable(conditionGroups)) { this.children.push(new ConditionsUI.ConditionGroup(this, conditionGroup)); } @@ -122,7 +122,7 @@ ConditionsUI.ConditionGroup = class ConditionGroup { this.separator = ConditionsUI.instantiateTemplate('#condition-group-separator-template').appendTo(parent.container); this.addButton = this.options.find('.condition-add'); - for (const condition of conditionGroup.conditions) { + for (const condition of toIterable(conditionGroup.conditions)) { this.children.push(new ConditionsUI.Condition(this, condition)); } diff --git a/ext/bg/js/settings.js b/ext/bg/js/settings.js index a0fe7c70..a100550c 100644 --- a/ext/bg/js/settings.js +++ b/ext/bg/js/settings.js @@ -422,7 +422,7 @@ async function onDictionaryPurge(e) { dictionarySpinnerShow(true); await utilDatabasePurge(); - for (const options of await getOptionsArray()) { + for (const options of toIterable(await getOptionsArray())) { options.dictionaries = utilBackgroundIsolate({}); options.general.mainDictionary = ''; } @@ -466,7 +466,7 @@ async function onDictionaryImport(e) { const exceptions = []; const summary = await utilDatabaseImport(e.target.files[0], updateProgress, exceptions); - for (const options of await getOptionsArray()) { + for (const options of toIterable(await getOptionsArray())) { options.dictionaries[summary.title] = utilBackgroundIsolate({ enabled: true, priority: 0, diff --git a/ext/mixed/js/extension.js b/ext/mixed/js/extension.js index d7085e5b..5c803132 100644 --- a/ext/mixed/js/extension.js +++ b/ext/mixed/js/extension.js @@ -17,13 +17,24 @@ */ +// toIterable is required on Edge for cross-window origin objects. function toIterable(value) { if (typeof Symbol !== 'undefined' && typeof value[Symbol.iterator] !== 'undefined') { return value; } - const array = JSON.parse(JSON.stringify(value)); - return Array.isArray(array) ? array : []; + if (value !== null && typeof value === 'object') { + const length = value.length; + if (typeof length === 'number' && Number.isFinite(length)) { + const array = []; + for (let i = 0; i < length; ++i) { + array.push(value[i]); + } + return array; + } + } + + throw 'Could not convert to iterable'; } function extensionHasChrome() { -- cgit v1.2.3 From 25a4dafd73890a8181bd072d0b514ec9668ecfea Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Sun, 29 Sep 2019 13:00:32 -0400 Subject: Fix tab focus being changed due to settings changes --- ext/fg/js/frontend.js | 14 +++++++------- ext/fg/js/popup-proxy-host.js | 6 +++--- ext/fg/js/popup-proxy.js | 4 ++-- ext/fg/js/popup.js | 21 +++++++++++++-------- 4 files changed, 25 insertions(+), 20 deletions(-) (limited to 'ext') diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index 167e82c0..d5bb00c0 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -128,7 +128,7 @@ class Frontend { } this.popupTimerClear(); - this.searchClear(); + this.searchClear(true); } onMouseOut(e) { @@ -138,7 +138,7 @@ class Frontend { onFrameMessage(e) { const handlers = { popupClose: () => { - this.searchClear(); + this.searchClear(true); }, selectionCopy: () => { @@ -153,7 +153,7 @@ class Frontend { } onResize() { - this.searchClear(); + this.searchClear(true); } onClick(e) { @@ -265,7 +265,7 @@ class Frontend { async updateOptions() { this.options = await apiOptionsGet(this.getOptionsContext()); if (!this.options.enable) { - this.searchClear(); + this.searchClear(false); } } @@ -320,7 +320,7 @@ class Frontend { textSource.cleanup(); } if (hideResults && this.options.scanning.autoHideResults) { - this.searchClear(); + this.searchClear(true); } this.pendingLookup = false; @@ -392,8 +392,8 @@ class Frontend { return true; } - searchClear() { - this.popup.hide(); + searchClear(changeFocus) { + this.popup.hide(changeFocus); this.popup.clearAutoPlayTimer(); if (this.options.scanning.selectText && this.textSourceLast) { diff --git a/ext/fg/js/popup-proxy-host.js b/ext/fg/js/popup-proxy-host.js index 396f7556..cb9741be 100644 --- a/ext/fg/js/popup-proxy-host.js +++ b/ext/fg/js/popup-proxy-host.js @@ -40,7 +40,7 @@ class PopupProxyHost { createNestedPopup: ({parentId}) => this.createNestedPopup(parentId), show: ({id, elementRect, options}) => this.show(id, elementRect, options), showOrphaned: ({id, elementRect, options}) => this.show(id, elementRect, options), - hide: ({id}) => this.hide(id), + hide: ({id, changeFocus}) => this.hide(id, changeFocus), setVisible: ({id, visible}) => this.setVisible(id, visible), containsPoint: ({id, x, y}) => this.containsPoint(id, x, y), termsShow: ({id, elementRect, writingMode, definitions, options, context}) => this.termsShow(id, elementRect, writingMode, definitions, options, context), @@ -98,9 +98,9 @@ class PopupProxyHost { return await popup.showOrphaned(elementRect, options); } - async hide(id) { + async hide(id, changeFocus) { const popup = this.getPopup(id); - return popup.hide(); + return popup.hide(changeFocus); } async setVisible(id, visible) { diff --git a/ext/fg/js/popup-proxy.js b/ext/fg/js/popup-proxy.js index 235e1730..072cebc9 100644 --- a/ext/fg/js/popup-proxy.js +++ b/ext/fg/js/popup-proxy.js @@ -58,11 +58,11 @@ class PopupProxy { return await this.invokeHostApi('showOrphaned', {id, elementRect, options}); } - async hide() { + async hide(changeFocus) { if (this.id === null) { return; } - return await this.invokeHostApi('hide', {id: this.id}); + return await this.invokeHostApi('hide', {id: this.id, changeFocus}); } async setVisible(visible) { diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 08965084..64da9aef 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -105,7 +105,7 @@ class Popup { container.style.height = `${height}px`; container.style.visibility = 'visible'; - this.hideChildren(); + this.hideChildren(true); } static getPositionForHorizontalText(elementRect, width, height, maxWidth, maxHeight, optionsGeneral) { @@ -206,16 +206,21 @@ class Popup { this.invokeApi('orphaned'); } - hide() { - this.hideChildren(); + hide(changeFocus) { + if (this.isContainerHidden()) { + changeFocus = false; + } + this.hideChildren(changeFocus); this.hideContainer(); - this.focusParent(); + if (changeFocus) { + this.focusParent(); + } } - hideChildren() { - // recursively hides all children - if (this.child && !this.child.isContainerHidden()) { - this.child.hide(); + hideChildren(changeFocus) { + // Recursively hides all children. + if (this.child !== null && !this.child.isContainerHidden()) { + this.child.hide(changeFocus); } } -- cgit v1.2.3 From 44119eea2c8ad4c8eed38070ef1a3ce27fa9359e Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Mon, 30 Sep 2019 22:09:16 -0400 Subject: Fix deinflections not being handled correctly --- ext/bg/js/translator.js | 58 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 18 deletions(-) (limited to 'ext') diff --git a/ext/bg/js/translator.js b/ext/bg/js/translator.js index 4eb4b03a..65d746ea 100644 --- a/ext/bg/js/translator.js +++ b/ext/bg/js/translator.js @@ -218,22 +218,55 @@ class Translator { return []; } - const definitions = await this.database.findTermsBulk(deinflections.map(e => e.term), titles); + const uniqueDeinflectionTerms = []; + const uniqueDeinflectionArrays = []; + const uniqueDeinflectionsMap = {}; + for (const deinflection of deinflections) { + const term = deinflection.term; + let deinflectionArray; + if (uniqueDeinflectionsMap.hasOwnProperty(term)) { + deinflectionArray = uniqueDeinflectionsMap[term]; + } else { + deinflectionArray = []; + uniqueDeinflectionTerms.push(term); + uniqueDeinflectionArrays.push(deinflectionArray); + uniqueDeinflectionsMap[term] = deinflectionArray; + } + deinflectionArray.push(deinflection); + } + + const definitions = await this.database.findTermsBulk(uniqueDeinflectionTerms, titles); - for (const d of definitions) { - deinflections[d.index].definitions.push(d); + for (const definition of definitions) { + for (const deinflection of uniqueDeinflectionArrays[definition.index]) { + if (Translator.definitionContainsAnyRule(definition, deinflection.rules)) { + deinflection.definitions.push(definition); + } + } } return deinflections.filter(e => e.definitions.length > 0); } + static definitionContainsAnyRule(definition, rules) { + if (rules.length === 0) { + return true; + } + const definitionRules = definition.rules; + for (const rule of rules) { + if (definitionRules.includes(rule)) { + return true; + } + } + return false; + } + getDeinflections(text) { const deinflections = []; - const deinflectionsKeys = {}; for (let i = text.length; i > 0; --i) { const textSlice = text.slice(0, i); - Translator.addUniqueDeinflections(this.deinflector.deinflect(textSlice), deinflections, deinflectionsKeys); + deinflections.push(...this.deinflector.deinflect(textSlice)); } return deinflections; @@ -241,30 +274,19 @@ class Translator { getDeinflections2(text, text2) { const deinflections = []; - const deinflectionsKeys = {}; for (let i = text.length; i > 0; --i) { const textSlice = text.slice(0, i); const text2Slice = text2.slice(0, i); - Translator.addUniqueDeinflections(this.deinflector.deinflect(textSlice), deinflections, deinflectionsKeys); + deinflections.push(...this.deinflector.deinflect(textSlice)); if (textSlice !== text2Slice) { - Translator.addUniqueDeinflections(this.deinflector.deinflect(text2Slice), deinflections, deinflectionsKeys); + deinflections.push(...this.deinflector.deinflect(text2Slice)); } } return deinflections; } - static addUniqueDeinflections(newValues, deinflections, deinflectionsKeys) { - for (const value of newValues) { - const key = value.term; - if (!deinflectionsKeys.hasOwnProperty(key)) { - deinflections.push(value); - deinflectionsKeys[key] = true; - } - } - } - async findKanji(text, dictionaries) { let definitions = []; const processed = {}; -- cgit v1.2.3 From 861474d2fcebd9db82b25700c71351b7d6611794 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Tue, 1 Oct 2019 19:05:30 -0400 Subject: Fix inconsistent return type --- ext/fg/js/frontend.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ext') diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index d5bb00c0..3292cac4 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -333,7 +333,7 @@ class Frontend { const searchText = textSource.text(); if (searchText.length === 0) { - return; + return false; } const {definitions, length} = await apiTermsFind(searchText, this.getOptionsContext()); @@ -366,7 +366,7 @@ class Frontend { const searchText = textSource.text(); if (searchText.length === 0) { - return; + return false; } const definitions = await apiKanjiFind(searchText, this.getOptionsContext()); -- cgit v1.2.3 From a628610cbd9ea235987cef399021b0685c50f0e4 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Thu, 19 Sep 2019 22:03:26 -0400 Subject: Use KeyboardEvent.key for onKeyDown handlers --- ext/fg/js/float.js | 31 ++++--- ext/mixed/js/display.js | 241 ++++++++++++++++++++++++++---------------------- 2 files changed, 149 insertions(+), 123 deletions(-) (limited to 'ext') diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js index 2e952efb..8a05aa70 100644 --- a/ext/fg/js/float.js +++ b/ext/fg/js/float.js @@ -102,21 +102,16 @@ class DisplayFloat extends Display { } onKeyDown(e) { - const handlers = { - 67: /* c */ () => { - if (e.ctrlKey && !window.getSelection().toString()) { - this.onSelectionCopy(); - return true; - } + const key = Display.getKeyFromEvent(e); + const handlers = DisplayFloat.onKeyDownHandlers; + if (handlers.hasOwnProperty(key)) { + const handler = handlers[key]; + if (handler(this, e)) { + e.preventDefault(); + return; } - }; - - const handler = handlers[e.keyCode]; - if (handler && handler()) { - e.preventDefault(); - } else { - super.onKeyDown(e); } + super.onKeyDown(e); } autoPlayAudio() { @@ -146,4 +141,14 @@ class DisplayFloat extends Display { } } +DisplayFloat.onKeyDownHandlers = { + 'C': (self, e) => { + if (e.ctrlKey && !window.getSelection().toString()) { + self.onSelectionCopy(); + return true; + } + return false; + } +}; + window.yomichan_display = new DisplayFloat(); diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index 46016192..eb40a5df 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -150,117 +150,13 @@ class Display { } onKeyDown(e) { - const noteTryAdd = mode => { - const button = this.adderButtonFind(this.index, mode); - if (button !== null && !button.classList.contains('disabled')) { - this.noteAdd(this.definitions[this.index], mode); + const key = Display.getKeyFromEvent(e); + const handlers = Display.onKeyDownHandlers; + if (handlers.hasOwnProperty(key)) { + const handler = handlers[key]; + if (handler(this, e)) { + e.preventDefault(); } - }; - - const noteTryView = mode => { - const button = this.viewerButtonFind(this.index); - if (button !== null && !button.classList.contains('disabled')) { - apiNoteView(button.dataset.noteId); - } - }; - - const handlers = { - 27: /* escape */ () => { - this.onSearchClear(); - return true; - }, - - 33: /* page up */ () => { - if (e.altKey) { - this.entryScrollIntoView(this.index - 3, null, true); - return true; - } - }, - - 34: /* page down */ () => { - if (e.altKey) { - this.entryScrollIntoView(this.index + 3, null, true); - return true; - } - }, - - 35: /* end */ () => { - if (e.altKey) { - this.entryScrollIntoView(this.definitions.length - 1, null, true); - return true; - } - }, - - 36: /* home */ () => { - if (e.altKey) { - this.entryScrollIntoView(0, null, true); - return true; - } - }, - - 38: /* up */ () => { - if (e.altKey) { - this.entryScrollIntoView(this.index - 1, null, true); - return true; - } - }, - - 40: /* down */ () => { - if (e.altKey) { - this.entryScrollIntoView(this.index + 1, null, true); - return true; - } - }, - - 66: /* b */ () => { - if (e.altKey) { - this.sourceTermView(); - return true; - } - }, - - 69: /* e */ () => { - if (e.altKey) { - noteTryAdd('term-kanji'); - return true; - } - }, - - 75: /* k */ () => { - if (e.altKey) { - noteTryAdd('kanji'); - return true; - } - }, - - 82: /* r */ () => { - if (e.altKey) { - noteTryAdd('term-kana'); - return true; - } - }, - - 80: /* p */ () => { - if (e.altKey) { - const entry = this.getEntry(this.index); - if (entry !== null && entry.dataset.type === 'term') { - this.audioPlay(this.definitions[this.index], this.firstExpressionIndex); - } - - return true; - } - }, - - 86: /* v */ () => { - if (e.altKey) { - noteTryView(); - } - } - }; - - const handler = handlers[e.keyCode]; - if (handler && handler()) { - e.preventDefault(); } } @@ -459,6 +355,20 @@ class Display { } } + noteTryAdd(mode) { + const button = this.adderButtonFind(this.index, mode); + if (button !== null && !button.classList.contains('disabled')) { + this.noteAdd(this.definitions[this.index], mode); + } + } + + noteTryView() { + const button = this.viewerButtonFind(this.index); + if (button !== null && !button.classList.contains('disabled')) { + apiNoteView(button.dataset.noteId); + } + } + async noteAdd(definition, mode) { try { this.setSpinnerVisible(true); @@ -634,4 +544,115 @@ class Display { const documentRect = document.documentElement.getBoundingClientRect(); return elementRect.top - documentRect.top; } + + static getKeyFromEvent(event) { + const key = event.key; + return key.length === 1 ? key.toUpperCase() : key; + } } + +Display.onKeyDownHandlers = { + 'Escape': (self) => { + self.onSearchClear(); + return true; + }, + + 'PageUp': (self, e) => { + if (e.altKey) { + self.entryScrollIntoView(self.index - 3, null, true); + return true; + } + return false; + }, + + 'PageDown': (self, e) => { + if (e.altKey) { + self.entryScrollIntoView(self.index + 3, null, true); + return true; + } + return false; + }, + + 'End': (self, e) => { + if (e.altKey) { + self.entryScrollIntoView(self.definitions.length - 1, null, true); + return true; + } + return false; + }, + + 'Home': (self, e) => { + if (e.altKey) { + self.entryScrollIntoView(0, null, true); + return true; + } + return false; + }, + + 'ArrowUp': (self, e) => { + if (e.altKey) { + self.entryScrollIntoView(self.index - 1, null, true); + return true; + } + return false; + }, + + 'ArrowDown': (self, e) => { + if (e.altKey) { + self.entryScrollIntoView(self.index + 1, null, true); + return true; + } + return false; + }, + + 'B': (self, e) => { + if (e.altKey) { + self.sourceTermView(); + return true; + } + return false; + }, + + 'E': (self, e) => { + if (e.altKey) { + self.noteTryAdd('term-kanji'); + return true; + } + return false; + }, + + 'K': (self, e) => { + if (e.altKey) { + self.noteTryAdd('kanji'); + return true; + } + return false; + }, + + 'R': (self, e) => { + if (e.altKey) { + self.noteTryAdd('term-kana'); + return true; + } + return false; + }, + + 'P': (self, e) => { + if (e.altKey) { + const entry = self.getEntry(self.index); + if (entry !== null && entry.dataset.type === 'term') { + self.audioPlay(self.definitions[self.index], self.firstExpressionIndex); + } + return true; + } + return false; + }, + + 'V': (self, e) => { + if (e.altKey) { + self.noteTryView(); + return true; + } + return false; + } +}; -- cgit v1.2.3 From 7d15213916355a806ba687803ca94209e29f142c Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Wed, 2 Oct 2019 20:31:42 -0400 Subject: Use static object for frontend message handlers --- ext/fg/js/frontend.js | 64 +++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 30 deletions(-) (limited to 'ext') diff --git a/ext/fg/js/frontend.js b/ext/fg/js/frontend.js index d5bb00c0..deec1ffd 100644 --- a/ext/fg/js/frontend.js +++ b/ext/fg/js/frontend.js @@ -55,7 +55,7 @@ class Frontend { try { this.options = await apiOptionsGet(this.getOptionsContext()); - window.addEventListener('message', this.onFrameMessage.bind(this)); + window.addEventListener('message', this.onWindowMessage.bind(this)); window.addEventListener('mousedown', this.onMouseDown.bind(this)); window.addEventListener('mousemove', this.onMouseMove.bind(this)); window.addEventListener('mouseover', this.onMouseOver.bind(this)); @@ -71,7 +71,7 @@ class Frontend { window.addEventListener('contextmenu', this.onContextMenu.bind(this)); } - chrome.runtime.onMessage.addListener(this.onBgMessage.bind(this)); + chrome.runtime.onMessage.addListener(this.onRuntimeMessage.bind(this)); } catch (e) { this.onError(e); } @@ -135,20 +135,12 @@ class Frontend { this.popupTimerClear(); } - onFrameMessage(e) { - const handlers = { - popupClose: () => { - this.searchClear(true); - }, - - selectionCopy: () => { - document.execCommand('copy'); - } - }; - - const handler = handlers[e.data]; - if (handler) { - handler(); + onWindowMessage(e) { + const action = e.data; + const handlers = Frontend.windowMessageHandlers; + if (handlers.hasOwnProperty(action)) { + const handler = handlers[action]; + handler(this); } } @@ -240,20 +232,11 @@ class Frontend { this.contextMenuChecking = false; } - onBgMessage({action, params}, sender, callback) { - const handlers = { - optionsUpdate: () => { - this.updateOptions(); - }, - - popupSetVisible: ({visible}) => { - this.popup.setVisible(visible); - } - }; - - const handler = handlers[action]; - if (handler) { - handler(params); + onRuntimeMessage({action, params}, sender, callback) { + const handlers = Frontend.runtimeMessageHandlers; + if (handlers.hasOwnProperty(action)) { + const handler = handlers[action]; + handler(this, params); callback(); } } @@ -529,4 +512,25 @@ class Frontend { } } +Frontend.windowMessageHandlers = { + popupClose: (self) => { + self.searchClear(true); + }, + + selectionCopy: () => { + document.execCommand('copy'); + } +}; + +Frontend.runtimeMessageHandlers = { + optionsUpdate: (self) => { + self.updateOptions(); + }, + + popupSetVisible: (self, {visible}) => { + self.popup.setVisible(visible); + } +}; + + window.yomichan_frontend = Frontend.create(); -- cgit v1.2.3 From bf382652a7be949d0bbfe176bb2876af2d0f7fa2 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Wed, 2 Oct 2019 20:46:35 -0400 Subject: Use static object for float message handlers --- ext/fg/js/float.js | 69 +++++++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 34 deletions(-) (limited to 'ext') diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js index 8a05aa70..8f561fec 100644 --- a/ext/fg/js/float.js +++ b/ext/fg/js/float.js @@ -63,41 +63,11 @@ class DisplayFloat extends Display { } onMessage(e) { - const handlers = { - termsShow: ({definitions, options, context}) => { - this.termsShow(definitions, options, context); - }, - - kanjiShow: ({definitions, options, context}) => { - this.kanjiShow(definitions, options, context); - }, - - clearAutoPlayTimer: () => { - this.clearAutoPlayTimer(); - }, - - orphaned: () => { - this.onOrphaned(); - }, - - setOptions: (options) => { - const css = options.general.customPopupCss; - if (css) { - this.setStyle(css); - } - }, - - popupNestedInitialize: ({id, depth, parentFrameId, url}) => { - this.optionsContext.depth = depth; - this.optionsContext.url = url; - popupNestedInitialize(id, depth, parentFrameId, url); - } - }; - const {action, params} = e.data; - const handler = handlers[action]; - if (handler) { - handler(params); + const handlers = DisplayFloat.messageHandlers; + if (handlers.hasOwnProperty(action)) { + const handler = handlers[action]; + handler(this, params); } } @@ -151,4 +121,35 @@ DisplayFloat.onKeyDownHandlers = { } }; +DisplayFloat.messageHandlers = { + termsShow: (self, {definitions, options, context}) => { + self.termsShow(definitions, options, context); + }, + + kanjiShow: (self, {definitions, options, context}) => { + self.kanjiShow(definitions, options, context); + }, + + clearAutoPlayTimer: (self) => { + self.clearAutoPlayTimer(); + }, + + orphaned: (self) => { + self.onOrphaned(); + }, + + setOptions: (self, options) => { + const css = options.general.customPopupCss; + if (css) { + self.setStyle(css); + } + }, + + popupNestedInitialize: (self, {id, depth, parentFrameId, url}) => { + self.optionsContext.depth = depth; + self.optionsContext.url = url; + popupNestedInitialize(id, depth, parentFrameId, url); + } +}; + window.yomichan_display = new DisplayFloat(); -- cgit v1.2.3 From 10458c63e71303f27888c3dfca7b3f59d5a0702b Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Wed, 2 Oct 2019 20:46:48 -0400 Subject: Use static object for backend message handlers --- ext/bg/js/backend.js | 84 ++++++++++++++-------------------------------------- 1 file changed, 22 insertions(+), 62 deletions(-) (limited to 'ext') diff --git a/ext/bg/js/backend.js b/ext/bg/js/backend.js index 4068b760..3c5ad885 100644 --- a/ext/bg/js/backend.js +++ b/ext/bg/js/backend.js @@ -69,68 +69,13 @@ class Backend { } onMessage({action, params}, sender, callback) { - const forward = (promise, callback) => { - return promise.then(result => { - callback({result}); - }).catch(error => { - callback({error: error.toString ? error.toString() : error}); - }); - }; - - const handlers = { - optionsGet: ({optionsContext, callback}) => { - forward(apiOptionsGet(optionsContext), callback); - }, - - kanjiFind: ({text, optionsContext, callback}) => { - forward(apiKanjiFind(text, optionsContext), callback); - }, - - termsFind: ({text, optionsContext, callback}) => { - forward(apiTermsFind(text, optionsContext), callback); - }, - - definitionAdd: ({definition, mode, context, optionsContext, callback}) => { - forward(apiDefinitionAdd(definition, mode, context, optionsContext), callback); - }, - - definitionsAddable: ({definitions, modes, optionsContext, callback}) => { - forward(apiDefinitionsAddable(definitions, modes, optionsContext), callback); - }, - - noteView: ({noteId}) => { - forward(apiNoteView(noteId), callback); - }, - - templateRender: ({template, data, dynamic, callback}) => { - forward(apiTemplateRender(template, data, dynamic), callback); - }, - - commandExec: ({command, callback}) => { - forward(apiCommandExec(command), callback); - }, - - audioGetUrl: ({definition, source, callback}) => { - forward(apiAudioGetUrl(definition, source), callback); - }, - - screenshotGet: ({options}) => { - forward(apiScreenshotGet(options, sender), callback); - }, - - forward: ({action, params}) => { - forward(apiForward(action, params, sender), callback); - }, - - frameInformationGet: () => { - forward(apiFrameInformationGet(sender), callback); - } - }; - - const handler = handlers[action]; - if (handler) { - params.callback = callback; - handler(params); + const handlers = Backend.messageHandlers; + if (handlers.hasOwnProperty(action)) { + const handler = handlers[action]; + const promise = handler(params, sender); + promise + .then(result => callback({result})) + .catch(error => callback({error: typeof error.toString === 'function' ? error.toString() : error})); } return true; @@ -227,5 +172,20 @@ class Backend { } } +Backend.messageHandlers = { + optionsGet: ({optionsContext}) => apiOptionsGet(optionsContext), + kanjiFind: ({text, optionsContext}) => apiKanjiFind(text, optionsContext), + termsFind: ({text, optionsContext}) => apiTermsFind(text, optionsContext), + definitionAdd: ({definition, mode, context, optionsContext}) => apiDefinitionAdd(definition, mode, context, optionsContext), + definitionsAddable: ({definitions, modes, optionsContext}) => apiDefinitionsAddable(definitions, modes, optionsContext), + noteView: ({noteId}) => apiNoteView(noteId), + templateRender: ({template, data, dynamic}) => apiTemplateRender(template, data, dynamic), + commandExec: ({command}) => apiCommandExec(command), + audioGetUrl: ({definition, source}) => apiAudioGetUrl(definition, source), + screenshotGet: ({options}, sender) => apiScreenshotGet(options, sender), + forward: ({action, params}, sender) => apiForward(action, params, sender), + frameInformationGet: (params, sender) => apiFrameInformationGet(sender), +}; + window.yomichan_backend = new Backend(); window.yomichan_backend.prepare(); -- cgit v1.2.3 From 0d6177398d0a738430a555ce307ba0a61c15bf9a Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Wed, 2 Oct 2019 20:47:03 -0400 Subject: Use static object for api command handlers --- ext/bg/js/api.js | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'ext') diff --git a/ext/bg/js/api.js b/ext/bg/js/api.js index 474fe604..222e7ffe 100644 --- a/ext/bg/js/api.js +++ b/ext/bg/js/api.js @@ -126,35 +126,35 @@ async function apiTemplateRender(template, data, dynamic) { } async function apiCommandExec(command) { - const handlers = { - search: () => { - chrome.tabs.create({url: chrome.extension.getURL('/bg/search.html')}); - }, - - help: () => { - chrome.tabs.create({url: 'https://foosoft.net/projects/yomichan/'}); - }, - - options: () => { - chrome.runtime.openOptionsPage(); - }, - - toggle: async () => { - const optionsContext = { - depth: 0, - url: window.location.href - }; - const options = await apiOptionsGet(optionsContext); - options.general.enable = !options.general.enable; - await apiOptionsSave('popup'); - } - }; - - const handler = handlers[command]; - if (handler) { + const handlers = apiCommandExec.handlers; + if (handlers.hasOwnProperty(command)) { + const handler = handlers[command]; handler(); } } +apiCommandExec.handlers = { + search: () => { + chrome.tabs.create({url: chrome.extension.getURL('/bg/search.html')}); + }, + + help: () => { + chrome.tabs.create({url: 'https://foosoft.net/projects/yomichan/'}); + }, + + options: () => { + chrome.runtime.openOptionsPage(); + }, + + toggle: async () => { + const optionsContext = { + depth: 0, + url: window.location.href + }; + const options = await apiOptionsGet(optionsContext); + options.general.enable = !options.general.enable; + await apiOptionsSave('popup'); + } +}; async function apiAudioGetUrl(definition, source) { return audioBuildUrl(definition, source); -- cgit v1.2.3 From 7380ada1f12c382d423133c2e9142f36a6634067 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Wed, 2 Oct 2019 20:57:48 -0400 Subject: Simplify onWheel handler --- ext/mixed/js/display.js | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'ext') diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js index eb40a5df..dc64dbea 100644 --- a/ext/mixed/js/display.js +++ b/ext/mixed/js/display.js @@ -161,20 +161,12 @@ class Display { } onWheel(e) { - const handler = () => { - if (e.altKey) { - if (e.deltaY < 0) { // scroll up - this.entryScrollIntoView(this.index - 1, null, true); - return true; - } else if (e.deltaY > 0) { // scroll down - this.entryScrollIntoView(this.index + 1, null, true); - return true; - } + if (e.altKey) { + const delta = e.deltaY; + if (delta !== 0) { + this.entryScrollIntoView(this.index + (delta > 0 ? 1 : -1), null, true); + e.preventDefault(); } - }; - - if (handler()) { - e.preventDefault(); } } -- cgit v1.2.3 From fa7ee468c0b8b877bb6d94a031464525b1a87c6b Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Wed, 2 Oct 2019 21:11:06 -0400 Subject: Simplify float initialization --- ext/fg/js/float.js | 45 +++++++++++++++++---------------------------- ext/fg/js/popup.js | 20 +++++++++++--------- 2 files changed, 28 insertions(+), 37 deletions(-) (limited to 'ext') diff --git a/ext/fg/js/float.js b/ext/fg/js/float.js index 8f561fec..88842eef 100644 --- a/ext/fg/js/float.js +++ b/ext/fg/js/float.js @@ -96,6 +96,18 @@ class DisplayFloat extends Display { } } + initialize(options, popupInfo, url) { + const css = options.general.customPopupCss; + if (css) { + this.setStyle(css); + } + + const {id, depth, parentFrameId} = popupInfo; + this.optionsContext.depth = depth; + this.optionsContext.url = url; + popupNestedInitialize(id, depth, parentFrameId, url); + } + setStyle(css) { const parent = document.head; @@ -122,34 +134,11 @@ DisplayFloat.onKeyDownHandlers = { }; DisplayFloat.messageHandlers = { - termsShow: (self, {definitions, options, context}) => { - self.termsShow(definitions, options, context); - }, - - kanjiShow: (self, {definitions, options, context}) => { - self.kanjiShow(definitions, options, context); - }, - - clearAutoPlayTimer: (self) => { - self.clearAutoPlayTimer(); - }, - - orphaned: (self) => { - self.onOrphaned(); - }, - - setOptions: (self, options) => { - const css = options.general.customPopupCss; - if (css) { - self.setStyle(css); - } - }, - - popupNestedInitialize: (self, {id, depth, parentFrameId, url}) => { - self.optionsContext.depth = depth; - self.optionsContext.url = url; - popupNestedInitialize(id, depth, parentFrameId, url); - } + termsShow: (self, {definitions, options, context}) => self.termsShow(definitions, options, context), + kanjiShow: (self, {definitions, options, context}) => self.kanjiShow(definitions, options, context), + clearAutoPlayTimer: (self) => self.clearAutoPlayTimer(), + orphaned: (self) => self.onOrphaned(), + initialize: (self, {options, popupInfo, url}) => self.initialize(options, popupInfo, url) }; window.yomichan_display = new DisplayFloat(); diff --git a/ext/fg/js/popup.js b/ext/fg/js/popup.js index 64da9aef..9dff6f28 100644 --- a/ext/fg/js/popup.js +++ b/ext/fg/js/popup.js @@ -56,17 +56,19 @@ class Popup { return new Promise((resolve) => { const parentFrameId = (typeof this.frameId === 'number' ? this.frameId : null); this.container.addEventListener('load', () => { - this.invokeApi('popupNestedInitialize', { - id: this.id, - depth: this.depth, - parentFrameId, + this.invokeApi('initialize', { + options: { + general: { + customPopupCss: options.general.customPopupCss + } + }, + popupInfo: { + id: this.id, + depth: this.depth, + parentFrameId + }, url: this.url }); - this.invokeApi('setOptions', { - general: { - customPopupCss: options.general.customPopupCss - } - }); resolve(); }); this.observeFullscreen(); -- cgit v1.2.3 From 457caf2221dad6fb67e0e3b8500984ef5a65e826 Mon Sep 17 00:00:00 2001 From: toasted-nutbread Date: Fri, 4 Oct 2019 22:11:45 -0400 Subject: Add support for progressive/perfect inflections --- ext/bg/lang/deinflect.json | 205 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 161 insertions(+), 44 deletions(-) (limited to 'ext') diff --git a/ext/bg/lang/deinflect.json b/ext/bg/lang/deinflect.json index 7a68ea71..c7977c88 100644 --- a/ext/bg/lang/deinflect.json +++ b/ext/bg/lang/deinflect.json @@ -1185,7 +1185,9 @@ { "kanaIn": "て", "kanaOut": "る", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v1", "vk" @@ -1194,7 +1196,9 @@ { "kanaIn": "いて", "kanaOut": "く", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1202,7 +1206,9 @@ { "kanaIn": "いで", "kanaOut": "ぐ", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1210,7 +1216,9 @@ { "kanaIn": "きて", "kanaOut": "くる", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "vk" ] @@ -1218,7 +1226,9 @@ { "kanaIn": "くて", "kanaOut": "い", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "adj-i" ] @@ -1226,7 +1236,9 @@ { "kanaIn": "して", "kanaOut": "す", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1234,7 +1246,9 @@ { "kanaIn": "して", "kanaOut": "する", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "vs" ] @@ -1242,7 +1256,9 @@ { "kanaIn": "って", "kanaOut": "う", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1250,7 +1266,9 @@ { "kanaIn": "って", "kanaOut": "つ", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1258,7 +1276,9 @@ { "kanaIn": "って", "kanaOut": "る", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1266,7 +1286,9 @@ { "kanaIn": "んで", "kanaOut": "ぬ", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1274,7 +1296,9 @@ { "kanaIn": "んで", "kanaOut": "ぶ", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1282,7 +1306,9 @@ { "kanaIn": "んで", "kanaOut": "む", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1290,7 +1316,9 @@ { "kanaIn": "のたもうて", "kanaOut": "のたまう", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1298,7 +1326,9 @@ { "kanaIn": "いって", "kanaOut": "いく", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1306,7 +1336,9 @@ { "kanaIn": "おうて", "kanaOut": "おう", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1314,7 +1346,9 @@ { "kanaIn": "こうて", "kanaOut": "こう", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1322,7 +1356,9 @@ { "kanaIn": "そうて", "kanaOut": "そう", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1330,7 +1366,9 @@ { "kanaIn": "とうて", "kanaOut": "とう", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1338,7 +1376,9 @@ { "kanaIn": "行って", "kanaOut": "行く", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1346,7 +1386,9 @@ { "kanaIn": "逝って", "kanaOut": "逝く", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1354,7 +1396,9 @@ { "kanaIn": "往って", "kanaOut": "往く", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1362,7 +1406,9 @@ { "kanaIn": "請うて", "kanaOut": "請う", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1370,7 +1416,9 @@ { "kanaIn": "乞うて", "kanaOut": "乞う", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1378,7 +1426,9 @@ { "kanaIn": "恋うて", "kanaOut": "恋う", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1386,7 +1436,9 @@ { "kanaIn": "問うて", "kanaOut": "問う", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1394,7 +1446,9 @@ { "kanaIn": "負うて", "kanaOut": "負う", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1402,7 +1456,9 @@ { "kanaIn": "沿うて", "kanaOut": "沿う", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1410,7 +1466,9 @@ { "kanaIn": "添うて", "kanaOut": "添う", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1418,7 +1476,9 @@ { "kanaIn": "副うて", "kanaOut": "副う", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] @@ -1426,10 +1486,22 @@ { "kanaIn": "厭うて", "kanaOut": "厭う", - "rulesIn": [], + "rulesIn": [ + "iru" + ], "rulesOut": [ "v5" ] + }, + { + "kanaIn": "で", + "kanaOut": "", + "rulesIn": [ + "iru" + ], + "rulesOut": [ + "neg-de" + ] } ], "-zu": [ @@ -2161,7 +2233,8 @@ "kanaIn": "ない", "kanaOut": "る", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "v1", @@ -2172,7 +2245,8 @@ "kanaIn": "かない", "kanaOut": "く", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "v5" @@ -2182,7 +2256,8 @@ "kanaIn": "がない", "kanaOut": "ぐ", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "v5" @@ -2192,7 +2267,8 @@ "kanaIn": "くない", "kanaOut": "い", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "adj-i" @@ -2202,7 +2278,8 @@ "kanaIn": "こない", "kanaOut": "くる", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "vk" @@ -2212,7 +2289,8 @@ "kanaIn": "さない", "kanaOut": "す", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "v5" @@ -2222,7 +2300,8 @@ "kanaIn": "しない", "kanaOut": "する", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "vs" @@ -2232,7 +2311,8 @@ "kanaIn": "たない", "kanaOut": "つ", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "v5" @@ -2242,7 +2322,8 @@ "kanaIn": "なない", "kanaOut": "ぬ", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "v5" @@ -2252,7 +2333,8 @@ "kanaIn": "ばない", "kanaOut": "ぶ", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "v5" @@ -2262,7 +2344,8 @@ "kanaIn": "まない", "kanaOut": "む", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "v5" @@ -2272,7 +2355,8 @@ "kanaIn": "らない", "kanaOut": "る", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "v5" @@ -2282,7 +2366,8 @@ "kanaIn": "わない", "kanaOut": "う", "rulesIn": [ - "adj-i" + "adj-i", + "neg-de" ], "rulesOut": [ "v5" @@ -3593,5 +3678,37 @@ "vk" ] } + ], + "progressive or perfect": [ + { + "kanaIn": "いる", + "kanaOut": "", + "rulesIn": [ + "v1" + ], + "rulesOut": [ + "iru" + ] + }, + { + "kanaIn": "る", + "kanaOut": "", + "rulesIn": [ + "v1" + ], + "rulesOut": [ + "iru" + ] + }, + { + "kanaIn": "おる", + "kanaOut": "", + "rulesIn": [ + "v1" + ], + "rulesOut": [ + "iru" + ] + } ] } -- cgit v1.2.3