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.
-
- +
--
cgit v1.2.3
From b61fc810127ae3cf54e6f4ca84ea95301f9ba2a5 Mon Sep 17 00:00:00 2001
From: toasted-nutbread +
-
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-nutbread
Date: 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(-)
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
Date: 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(-)
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 @@
-
+
--
cgit v1.2.3
From 8b7558a757447b931ee0dd1b5d724673e98bc13d Mon Sep 17 00:00:00 2001
From: toasted-nutbread
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(-)
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(-)
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(-)
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(-)
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(-)
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(-)
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(-)
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(-)
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(-)
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(-)
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(-)
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(-)
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