aboutsummaryrefslogtreecommitdiff
path: root/ext/mixed
diff options
context:
space:
mode:
Diffstat (limited to 'ext/mixed')
-rw-r--r--ext/mixed/css/display.css21
-rw-r--r--ext/mixed/js/display-generator.js80
-rw-r--r--ext/mixed/js/display.js249
-rw-r--r--ext/mixed/js/scroll.js2
4 files changed, 146 insertions, 206 deletions
diff --git a/ext/mixed/css/display.css b/ext/mixed/css/display.css
index 6a5383bc..c4758235 100644
--- a/ext/mixed/css/display.css
+++ b/ext/mixed/css/display.css
@@ -30,8 +30,8 @@
* General
*/
-html:root[data-yomichan-page=float]:not([data-yomichan-theme]),
-html:root[data-yomichan-page=float]:not([data-yomichan-theme]) body {
+:root[data-yomichan-page=float]:not([data-yomichan-theme]),
+:root[data-yomichan-page=float]:not([data-yomichan-theme]) body {
background-color: transparent;
}
@@ -65,10 +65,6 @@ ol, ul {
height: 2.28571428em; /* 14px => 32px */
}
-.invisible {
- visibility: hidden;
-}
-
/*
* Navigation
*/
@@ -82,17 +78,18 @@ ol, ul {
padding: 0.25em 0.5em;
border-bottom-width: 0.07142857em; /* 14px => 1px */
border-bottom-style: solid;
+ z-index: 10;
}
-html:root[data-yomichan-page=search] .navigation-header {
+:root[data-yomichan-page=search] .navigation-header {
position: sticky;
}
-html:root[data-yomichan-page=float] .navigation-header {
+:root[data-yomichan-page=float] .navigation-header {
position: fixed;
}
-html:root[data-yomichan-page=float] .navigation-header:not([hidden])~.navigation-header-spacer {
+:root[data-yomichan-page=float] .navigation-header:not([hidden])~.navigation-header-spacer {
height: 2.1em;
}
@@ -136,7 +133,7 @@ html:root[data-yomichan-page=float] .navigation-header:not([hidden])~.navigation
margin-right: 0.2em;
}
-html:root[data-yomichan-page=search][data-search-mode=popup] .search-input {
+:root[data-yomichan-page=search][data-search-mode=popup] .search-input {
display: none;
}
@@ -150,7 +147,7 @@ html:root[data-yomichan-page=search][data-search-mode=popup] .search-input {
padding-bottom: 0.72em;
}
-html:root[data-yomichan-page=float] .entry {
+:root[data-yomichan-page=float] .entry {
padding-left: 0.72em;
padding-right: 0.72em;
}
@@ -231,7 +228,7 @@ button.action-button {
margin-right: 0.375em;
}
-html:root:not([data-enable-search-tags=true]) .tag[data-category=search] {
+:root:not([data-enable-search-tags=true]) .tag[data-category=search] {
display: none;
}
diff --git a/ext/mixed/js/display-generator.js b/ext/mixed/js/display-generator.js
index 46f3d17e..d7e77cc0 100644
--- a/ext/mixed/js/display-generator.js
+++ b/ext/mixed/js/display-generator.js
@@ -16,36 +16,20 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/*global apiGetDisplayTemplatesHtml*/
+/*global apiGetDisplayTemplatesHtml, TemplateHandler*/
class DisplayGenerator {
constructor() {
- this._termEntryTemplate = null;
- this._termExpressionTemplate = null;
- this._termDefinitionItemTemplate = null;
- this._termDefinitionOnlyTemplate = null;
- this._termGlossaryItemTemplate = null;
- this._termReasonTemplate = null;
-
- this._kanjiEntryTemplate = null;
- this._kanjiInfoTableTemplate = null;
- this._kanjiInfoTableItemTemplate = null;
- this._kanjiInfoTableEmptyTemplate = null;
- this._kanjiGlossaryItemTemplate = null;
- this._kanjiReadingTemplate = null;
-
- this._tagTemplate = null;
- this._tagFrequencyTemplate = null;
+ this._templateHandler = null;
}
async prepare() {
const html = await apiGetDisplayTemplatesHtml();
- const doc = new DOMParser().parseFromString(html, 'text/html');
- this._setTemplates(doc);
+ this._templateHandler = new TemplateHandler(html);
}
createTermEntry(details) {
- const node = DisplayGenerator._instantiateTemplate(this._termEntryTemplate);
+ const node = this._templateHandler.instantiate('term-entry');
const expressionsContainer = node.querySelector('.term-expression-list');
const reasonsContainer = node.querySelector('.term-reasons');
@@ -78,7 +62,7 @@ class DisplayGenerator {
}
createTermExpression([details, termTags]) {
- const node = DisplayGenerator._instantiateTemplate(this._termExpressionTemplate);
+ const node = this._templateHandler.instantiate('term-expression');
const expressionContainer = node.querySelector('.term-expression-text');
const tagContainer = node.querySelector('.tags');
@@ -112,7 +96,7 @@ class DisplayGenerator {
}
createTermReason(reason) {
- const fragment = DisplayGenerator._instantiateTemplateFragment(this._termReasonTemplate);
+ const fragment = this._templateHandler.instantiateFragment('term-reason');
const node = fragment.querySelector('.term-reason');
node.textContent = reason;
node.dataset.reason = reason;
@@ -120,7 +104,7 @@ class DisplayGenerator {
}
createTermDefinitionItem(details) {
- const node = DisplayGenerator._instantiateTemplate(this._termDefinitionItemTemplate);
+ const node = this._templateHandler.instantiate('term-definition-item');
const tagListContainer = node.querySelector('.term-definition-tag-list');
const onlyListContainer = node.querySelector('.term-definition-only-list');
@@ -136,7 +120,7 @@ class DisplayGenerator {
}
createTermGlossaryItem(glossary) {
- const node = DisplayGenerator._instantiateTemplate(this._termGlossaryItemTemplate);
+ const node = this._templateHandler.instantiate('term-glossary-item');
const container = node.querySelector('.term-glossary');
if (container !== null) {
DisplayGenerator._appendMultilineText(container, glossary);
@@ -145,7 +129,7 @@ class DisplayGenerator {
}
createTermOnly(only) {
- const node = DisplayGenerator._instantiateTemplate(this._termDefinitionOnlyTemplate);
+ const node = this._templateHandler.instantiate('term-definition-only');
node.dataset.only = only;
node.textContent = only;
return node;
@@ -160,7 +144,7 @@ class DisplayGenerator {
}
createKanjiEntry(details) {
- const node = DisplayGenerator._instantiateTemplate(this._kanjiEntryTemplate);
+ const node = this._templateHandler.instantiate('kanji-entry');
const glyphContainer = node.querySelector('.kanji-glyph');
const frequenciesContainer = node.querySelector('.frequencies');
@@ -205,7 +189,7 @@ class DisplayGenerator {
}
createKanjiGlossaryItem(glossary) {
- const node = DisplayGenerator._instantiateTemplate(this._kanjiGlossaryItemTemplate);
+ const node = this._templateHandler.instantiate('kanji-glossary-item');
const container = node.querySelector('.kanji-glossary');
if (container !== null) {
DisplayGenerator._appendMultilineText(container, glossary);
@@ -214,13 +198,13 @@ class DisplayGenerator {
}
createKanjiReading(reading) {
- const node = DisplayGenerator._instantiateTemplate(this._kanjiReadingTemplate);
+ const node = this._templateHandler.instantiate('kanji-reading');
node.textContent = reading;
return node;
}
createKanjiInfoTable(details) {
- const node = DisplayGenerator._instantiateTemplate(this._kanjiInfoTableTemplate);
+ const node = this._templateHandler.instantiate('kanji-info-table');
const container = node.querySelector('.kanji-info-table-body');
@@ -236,7 +220,7 @@ class DisplayGenerator {
}
createKanjiInfoTableItem(details) {
- const node = DisplayGenerator._instantiateTemplate(this._kanjiInfoTableItemTemplate);
+ const node = this._templateHandler.instantiate('kanji-info-table-item');
const nameNode = node.querySelector('.kanji-info-table-item-header');
const valueNode = node.querySelector('.kanji-info-table-item-value');
if (nameNode !== null) {
@@ -249,11 +233,11 @@ class DisplayGenerator {
}
createKanjiInfoTableItemEmpty() {
- return DisplayGenerator._instantiateTemplate(this._kanjiInfoTableEmptyTemplate);
+ return this._templateHandler.instantiate('kanji-info-table-empty');
}
createTag(details) {
- const node = DisplayGenerator._instantiateTemplate(this._tagTemplate);
+ const node = this._templateHandler.instantiate('tag');
const inner = node.querySelector('.tag-inner');
@@ -265,7 +249,7 @@ class DisplayGenerator {
}
createSearchTag(details) {
- const node = DisplayGenerator._instantiateTemplate(this._tagSearchTemplate);
+ const node = this._templateHandler.instantiate('tag-search');
node.textContent = details.query;
@@ -275,7 +259,7 @@ class DisplayGenerator {
}
createFrequencyTag(details) {
- const node = DisplayGenerator._instantiateTemplate(this._tagFrequencyTemplate);
+ const node = this._templateHandler.instantiate('tag-frequency');
let n = node.querySelector('.term-frequency-dictionary-name');
if (n !== null) {
@@ -293,26 +277,6 @@ class DisplayGenerator {
return node;
}
- _setTemplates(doc) {
- this._termEntryTemplate = doc.querySelector('#term-entry-template');
- this._termExpressionTemplate = doc.querySelector('#term-expression-template');
- this._termDefinitionItemTemplate = doc.querySelector('#term-definition-item-template');
- this._termDefinitionOnlyTemplate = doc.querySelector('#term-definition-only-template');
- this._termGlossaryItemTemplate = doc.querySelector('#term-glossary-item-template');
- this._termReasonTemplate = doc.querySelector('#term-reason-template');
-
- this._kanjiEntryTemplate = doc.querySelector('#kanji-entry-template');
- this._kanjiInfoTableTemplate = doc.querySelector('#kanji-info-table-template');
- this._kanjiInfoTableItemTemplate = doc.querySelector('#kanji-info-table-item-template');
- this._kanjiInfoTableEmptyTemplate = doc.querySelector('#kanji-info-table-empty-template');
- this._kanjiGlossaryItemTemplate = doc.querySelector('#kanji-glossary-item-template');
- this._kanjiReadingTemplate = doc.querySelector('#kanji-reading-template');
-
- this._tagTemplate = doc.querySelector('#tag-template');
- this._tagSearchTemplate = doc.querySelector('#tag-search-template');
- this._tagFrequencyTemplate = doc.querySelector('#tag-frequency-template');
- }
-
_appendKanjiLinks(container, text) {
let part = '';
for (const c of text) {
@@ -382,12 +346,4 @@ class DisplayGenerator {
container.appendChild(document.createTextNode(parts[i]));
}
}
-
- static _instantiateTemplate(template) {
- return document.importNode(template.content.firstChild, true);
- }
-
- static _instantiateTemplateFragment(template) {
- return document.importNode(template.content, true);
- }
}
diff --git a/ext/mixed/js/display.js b/ext/mixed/js/display.js
index 8113260c..631f9e34 100644
--- a/ext/mixed/js/display.js
+++ b/ext/mixed/js/display.js
@@ -45,6 +45,110 @@ class Display {
this.displayGenerator = new DisplayGenerator();
this.windowScroll = new WindowScroll();
+ this._onKeyDownHandlers = new Map([
+ ['Escape', () => {
+ this.onSearchClear();
+ return true;
+ }],
+ ['PageUp', (e) => {
+ if (e.altKey) {
+ this.entryScrollIntoView(this.index - 3, null, true);
+ return true;
+ }
+ return false;
+ }],
+ ['PageDown', (e) => {
+ if (e.altKey) {
+ this.entryScrollIntoView(this.index + 3, null, true);
+ return true;
+ }
+ return false;
+ }],
+ ['End', (e) => {
+ if (e.altKey) {
+ this.entryScrollIntoView(this.definitions.length - 1, null, true);
+ return true;
+ }
+ return false;
+ }],
+ ['Home', (e) => {
+ if (e.altKey) {
+ this.entryScrollIntoView(0, null, true);
+ return true;
+ }
+ return false;
+ }],
+ ['ArrowUp', (e) => {
+ if (e.altKey) {
+ this.entryScrollIntoView(this.index - 1, null, true);
+ return true;
+ }
+ return false;
+ }],
+ ['ArrowDown', (e) => {
+ if (e.altKey) {
+ this.entryScrollIntoView(this.index + 1, null, true);
+ return true;
+ }
+ return false;
+ }],
+ ['B', (e) => {
+ if (e.altKey) {
+ this.sourceTermView();
+ return true;
+ }
+ return false;
+ }],
+ ['F', (e) => {
+ if (e.altKey) {
+ this.nextTermView();
+ return true;
+ }
+ return false;
+ }],
+ ['E', (e) => {
+ if (e.altKey) {
+ this.noteTryAdd('term-kanji');
+ return true;
+ }
+ return false;
+ }],
+ ['K', (e) => {
+ if (e.altKey) {
+ this.noteTryAdd('kanji');
+ return true;
+ }
+ return false;
+ }],
+ ['R', (e) => {
+ if (e.altKey) {
+ this.noteTryAdd('term-kana');
+ return true;
+ }
+ return false;
+ }],
+ ['P', (e) => {
+ if (e.altKey) {
+ const index = this.index;
+ if (index < 0 || index >= this.definitions.length) { return; }
+
+ const entry = this.getEntry(index);
+ if (entry !== null && entry.dataset.type === 'term') {
+ this.audioPlay(this.definitions[index], this.firstExpressionIndex, index);
+ }
+ return true;
+ }
+ return false;
+ }],
+ ['V', (e) => {
+ if (e.altKey) {
+ this.noteTryView();
+ return true;
+ }
+ return false;
+ }]
+ ]);
+
this.setInteractive(true);
}
@@ -215,9 +319,9 @@ class Display {
onKeyDown(e) {
const key = Display.getKeyFromEvent(e);
- const handler = Display._onKeyDownHandlers.get(key);
+ const handler = this._onKeyDownHandlers.get(key);
if (typeof handler === 'function') {
- if (handler(this, e)) {
+ if (handler(e)) {
e.preventDefault();
return true;
}
@@ -303,7 +407,7 @@ class Display {
if (interactive) {
const actionPrevious = document.querySelector('.action-previous');
const actionNext = document.querySelector('.action-next');
- const navigationHeader = document.querySelector('.navigation-header');
+ // const navigationHeader = document.querySelector('.navigation-header');
this.persistentEventListeners.addEventListener(document, 'keydown', this.onKeyDown.bind(this), false);
this.persistentEventListeners.addEventListener(document, 'wheel', this.onWheel.bind(this), {passive: false});
@@ -313,9 +417,10 @@ class Display {
if (actionNext !== null) {
this.persistentEventListeners.addEventListener(actionNext, 'click', this.onNextTermView.bind(this));
}
- if (navigationHeader !== null) {
- this.persistentEventListeners.addEventListener(navigationHeader, 'wheel', this.onHistoryWheel.bind(this), {passive: false});
- }
+ // temporarily disabled
+ // if (navigationHeader !== null) {
+ // this.persistentEventListeners.addEventListener(navigationHeader, 'wheel', this.onHistoryWheel.bind(this), {passive: false});
+ // }
} else {
this.persistentEventListeners.removeAllEventListeners();
}
@@ -519,15 +624,13 @@ class Display {
updateAdderButtons(states) {
for (let i = 0; i < states.length; ++i) {
- const state = states[i];
let noteId = null;
- for (const mode in state) {
+ for (const [mode, info] of Object.entries(states[i])) {
const button = this.adderButtonFind(i, mode);
if (button === null) {
continue;
}
- const info = state[mode];
if (!info.canAdd && noteId === null && info.noteId) {
noteId = info.noteId;
}
@@ -634,7 +737,7 @@ class Display {
this.setSpinnerVisible(true);
const context = {};
- if (this.noteUsesScreenshot()) {
+ if (this.noteUsesScreenshot(mode)) {
const screenshot = await this.getScreenshot();
if (screenshot) {
context.screenshot = screenshot;
@@ -704,10 +807,11 @@ class Display {
}
}
- noteUsesScreenshot() {
- const fields = this.options.anki.terms.fields;
- for (const name in fields) {
- if (fields[name].includes('{screenshot}')) {
+ noteUsesScreenshot(mode) {
+ const optionsAnki = this.options.anki;
+ const fields = (mode === 'kanji' ? optionsAnki.kanji : optionsAnki.terms).fields;
+ for (const fieldValue of Object.values(fields)) {
+ if (fieldValue.includes('{screenshot}')) {
return true;
}
}
@@ -814,120 +918,3 @@ class Display {
return (typeof key === 'string' ? (key.length === 1 ? key.toUpperCase() : key) : '');
}
}
-
-Display._onKeyDownHandlers = new Map([
- ['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;
- }],
-
- ['F', (self, e) => {
- if (e.altKey) {
- self.nextTermView();
- 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 index = self.index;
- if (index < 0 || index >= self.definitions.length) { return; }
-
- const entry = self.getEntry(index);
- if (entry !== null && entry.dataset.type === 'term') {
- self.audioPlay(self.definitions[index], self.firstExpressionIndex, index);
- }
- return true;
- }
- return false;
- }],
-
- ['V', (self, e) => {
- if (e.altKey) {
- self.noteTryView();
- return true;
- }
- return false;
- }]
-]);
diff --git a/ext/mixed/js/scroll.js b/ext/mixed/js/scroll.js
index 5829d294..72da8b65 100644
--- a/ext/mixed/js/scroll.js
+++ b/ext/mixed/js/scroll.js
@@ -26,7 +26,7 @@ class WindowScroll {
this.animationEndTime = 0;
this.animationEndX = 0;
this.animationEndY = 0;
- this.requestAnimationFrameCallback = (t) => this.onAnimationFrame(t);
+ this.requestAnimationFrameCallback = this.onAnimationFrame.bind(this);
}
toY(y) {