diff options
Diffstat (limited to 'ext/fg/js')
-rw-r--r-- | ext/fg/js/display-frame.js | 71 | ||||
-rw-r--r-- | ext/fg/js/driver.js | 6 | ||||
-rw-r--r-- | ext/fg/js/frame.js | 215 | ||||
-rw-r--r-- | ext/fg/js/gecko.js | 36 | ||||
-rw-r--r-- | ext/fg/js/util.js | 59 |
5 files changed, 88 insertions, 299 deletions
diff --git a/ext/fg/js/display-frame.js b/ext/fg/js/display-frame.js new file mode 100644 index 00000000..8f4a790f --- /dev/null +++ b/ext/fg/js/display-frame.js @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2016 Alex Yatskov <alex@foosoft.net> + * Author: Alex Yatskov <alex@foosoft.net> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +window.displayFrame = new class extends Display { + constructor() { + super($('#spinner'), $('#content')); + $(window).on('message', this.onMessage.bind(this)); + } + + definitionAdd(definition, mode) { + return bgDefinitionAdd(definition, mode); + } + + definitionsAddable(definitions, mode) { + return bgDefinitionsAddable(definitions, mode); + } + + textRender(template, data) { + return bgTextRender(template, data); + } + + kanjiFind(character) { + return bgKanjiFind(character); + } + + handleError(error) { + if (window.orphaned) { + this.api_showOrphaned(); + } else { + errorShow(error); + } + } + + onMessage(e) { + const {action, params} = e.originalEvent.data, method = this['api_' + action]; + if (typeof(method) === 'function') { + method.call(this, params); + } + } + + api_showTermDefs({definitions, options, context}) { + window.scrollTo(0, 0); + super.showTermDefs(definitions, options, context); + } + + api_showKanjiDefs({definitions, options, context}) { + window.scrollTo(0, 0); + super.showKanjiDefs(defintions, options, context); + } + + api_showOrphaned() { + $('#content').hide(); + $('#orphan').show(); + } +}; diff --git a/ext/fg/js/driver.js b/ext/fg/js/driver.js index 87cce875..73ddd84f 100644 --- a/ext/fg/js/driver.js +++ b/ext/fg/js/driver.js @@ -73,11 +73,11 @@ class Driver { return; } - const searcher = () => this.searchAt(this.lastMousePos); + const searchFunc = () => this.searchAt(this.lastMousePos); if (this.popup.isVisible()) { - searcher(); + searchFunc(); } else { - this.popupTimerSet(searcher); + this.popupTimerSet(searchFunc); } } diff --git a/ext/fg/js/frame.js b/ext/fg/js/frame.js deleted file mode 100644 index c1253e41..00000000 --- a/ext/fg/js/frame.js +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (C) 2016 Alex Yatskov <alex@foosoft.net> - * Author: Alex Yatskov <alex@foosoft.net> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - - -class Frame { - constructor() { - this.definitions = []; - this.audioCache = {}; - this.sequence = 0; - - $(window).on('message', e => { - const {action, params} = e.originalEvent.data, method = this['api_' + action]; - if (typeof(method) === 'function') { - method.call(this, params); - } - }); - } - - api_showTermDefs({definitions, options, context}) { - const sequence = ++this.sequence; - const params = { - definitions, - grouped: options.general.groupResults, - addable: options.anki.enabled, - playback: options.general.audioPlayback - }; - - definitions.forEach(definition => { - definition.sentence = context.sentence; - definition.url = context.url; - }); - - this.definitions = definitions; - this.showSpinner(false); - window.scrollTo(0, 0); - - bgTextRender('terms.html', params).then(content => { - $('#content').html(content); - $('.action-add-note').click(this.onAddNote.bind(this)); - - $('.kanji-link').click(e => { - e.preventDefault(); - const character = $(e.target).text(); - bgKanjiFind(character).then(definitions => this.api_showKanjiDefs({definitions, options, context})); - }); - - $('.action-play-audio').click(e => { - e.preventDefault(); - const index = $(e.currentTarget).data('index'); - this.playAudio(this.definitions[index]); - }); - - this.updateAddNoteButtons(['term_kanji', 'term_kana'], sequence); - }).catch(error => { - this.handleError(error); - }); - } - - api_showKanjiDefs({definitions, options, context}) { - const sequence = ++this.sequence; - const params = { - definitions, - addable: options.anki.enabled - }; - - definitions.forEach(definition => { - definition.sentence = context.sentence; - definition.url = context.url; - }); - - this.definitions = definitions; - this.showSpinner(false); - window.scrollTo(0, 0); - - bgTextRender('kanji.html', params).then(content => { - $('#content').html(content); - $('.action-add-note').click(this.onAddNote.bind(this)); - - this.updateAddNoteButtons(['kanji'], sequence); - }).catch(error => { - this.handleError(error); - }); - } - - api_showOrphaned() { - $('#content').hide(); - $('#orphan').show(); - } - - findAddNoteButton(index, mode) { - return $(`.action-add-note[data-index="${index}"][data-mode="${mode}"]`); - } - - onAddNote(e) { - e.preventDefault(); - this.showSpinner(true); - - const link = $(e.currentTarget); - const index = link.data('index'); - const mode = link.data('mode'); - - const definition = this.definitions[index]; - if (mode !== 'kanji') { - const url = audioUrlBuild(definition); - const filename = audioFilenameBuild(definition); - if (url && filename) { - definition.audio = {url, filename}; - } - } - - bgDefinitionAdd(definition, mode).then(success => { - if (success) { - const button = this.findAddNoteButton(index, mode); - button.addClass('disabled'); - } else { - errorShow('note could not be added'); - } - }).catch(error => { - this.handleError(error); - }).then(() => { - this.showSpinner(false); - }); - } - - updateAddNoteButtons(modes, sequence) { - bgDefinitionsAddable(this.definitions, modes).then(states => { - if (states === null) { - return; - } - - if (sequence !== this.sequence) { - return; - } - - states.forEach((state, index) => { - for (const mode in state) { - const button = this.findAddNoteButton(index, mode); - if (state[mode]) { - button.removeClass('disabled'); - } else { - button.addClass('disabled'); - } - - button.removeClass('pending'); - } - }); - }).catch(error => { - this.handleError(error); - }); - } - - showSpinner(show) { - const spinner = $('#spinner'); - if (show) { - spinner.show(); - } else { - spinner.hide(); - } - } - - playAudio(definition) { - for (const key in this.audioCache) { - const audio = this.audioCache[key]; - if (audio !== null) { - audio.pause(); - } - } - - const url = audioUrlBuild(definition); - if (!url) { - return; - } - - let audio = this.audioCache[url]; - if (audio) { - audio.currentTime = 0; - audio.play(); - } else { - audio = new Audio(url); - audio.onloadeddata = () => { - if (audio.duration === 5.694694 || audio.duration === 5.720718) { - audio = new Audio('mp3/button.mp3'); - } - - this.audioCache[url] = audio; - audio.play(); - }; - } - } - - handleError(error) { - if (window.orphaned) { - this.api_showOrphaned(); - } else { - errorShow(error); - } - } -} - -window.frame = new Frame(); diff --git a/ext/fg/js/gecko.js b/ext/fg/js/gecko.js deleted file mode 100644 index 4057b95c..00000000 --- a/ext/fg/js/gecko.js +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2017 Alex Yatskov <alex@foosoft.net> - * Author: Alex Yatskov <alex@foosoft.net> - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -if (!document.caretRangeFromPoint) { - document.caretRangeFromPoint = (x, y) => { - const position = document.caretPositionFromPoint(x,y); - if (position === null) { - return null; - } - - const range = document.createRange(); - range.setStart(position.offsetNode, position.offset); - range.setEnd(position.offsetNode, position.offset); - return range; - }; -} diff --git a/ext/fg/js/util.js b/ext/fg/js/util.js index c38112f5..4fb8f288 100644 --- a/ext/fg/js/util.js +++ b/ext/fg/js/util.js @@ -119,6 +119,20 @@ function docImposterHide() { } function docRangeFromPoint(point, imposter) { + if (!document.elementFromPoint) { + document.elementFromPoint = (x, y) => { + const position = document.caretPositionFromPoint(x,y); + if (position === null) { + return null; + } + + const range = document.createRange(); + range.setStart(position.offsetNode, position.offset); + range.setEnd(position.offsetNode, position.offset); + return range; + }; + } + const element = document.elementFromPoint(point.x, point.y); if (element !== null) { if (element.nodeName === 'IMG' || element.nodeName === 'BUTTON') { @@ -195,51 +209,6 @@ function docSentenceExtract(source, extent) { /* - * Audio - */ - -function audioUrlBuild(definition) { - let kana = definition.reading; - let kanji = definition.expression; - - if (!kana && !kanji) { - return null; - } - - if (!kana && wanakana.isHiragana(kanji)) { - kana = kanji; - kanji = null; - } - - const params = []; - if (kanji) { - params.push(`kanji=${encodeURIComponent(kanji)}`); - } - if (kana) { - params.push(`kana=${encodeURIComponent(kana)}`); - } - - return `https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?${params.join('&')}`; -} - -function audioFilenameBuild(definition) { - if (!definition.reading && !definition.expression) { - return null; - } - - let filename = 'yomichan'; - if (definition.reading) { - filename += `_${definition.reading}`; - } - if (definition.expression) { - filename += `_${definition.expression}`; - } - - return filename += '.mp3'; -} - - -/* * Error */ |