This commit is contained in:
Alex Yatskov 2017-03-02 22:35:02 -08:00
parent a01ca1f17c
commit faf13d696c
6 changed files with 77 additions and 56 deletions

View File

@ -126,11 +126,11 @@ class Yomichan {
return note;
}
api_getOptions({callback}) {
api_optionsGet({callback}) {
promiseCallback(optionsLoad(), callback);
}
api_findKanji({text, callback}) {
api_kanjiFind({text, callback}) {
promiseCallback(
this.translator.findKanji(text, dictEnabled(this.options)).then(definitions => {
return definitions.slice(0, this.options.general.maxResults);
@ -139,7 +139,7 @@ class Yomichan {
);
}
api_findTerms({text, callback}) {
api_termsFind({text, callback}) {
promiseCallback(
this.translator.findTerms(text, dictEnabled(this.options), this.options.general.softKatakana).then(({definitions, length}) => {
return {length, definitions: definitions.slice(0, this.options.general.maxResults)};
@ -148,7 +148,7 @@ class Yomichan {
);
}
api_findTermsGrouped({text, callback}) {
api_termsFindGrouped({text, callback}) {
promiseCallback(
this.translator.findTermsGrouped(text, dictEnabled(this.options), this.options.general.softKatakana).then(({definitions, length}) => {
return {length, definitions: definitions.slice(0, this.options.general.maxResults)};
@ -157,16 +157,16 @@ class Yomichan {
);
}
api_renderText({template, data, callback}) {
api_textRender({template, data, callback}) {
callback({result: Handlebars.templates[template](data)});
}
api_addDefinition({definition, mode, callback}) {
api_definitionAdd({definition, mode, callback}) {
const note = this.formatNote(definition, mode);
promiseCallback(this.anki.addNote(note), callback);
}
api_canAddDefinitions({definitions, modes, callback}) {
api_definitionsAddable({definitions, modes, callback}) {
const notes = [];
for (const definition of definitions) {
for (const mode of modes) {

View File

@ -28,7 +28,7 @@ class Driver {
this.pendingLookup = false;
this.options = null;
getOptions().then(options => {
bgOptionsGet().then(options => {
this.options = options;
window.addEventListener('mouseover', this.onMouseOver.bind(this));
window.addEventListener('mousedown', this.onMouseDown.bind(this));
@ -115,7 +115,7 @@ class Driver {
return;
}
const textSource = textSourceFromPoint(point, this.options.scanning.imposter);
const textSource = docRangeFromPoint(point, this.options.scanning.imposter);
if (textSource === null || !textSource.containsPoint(point)) {
return;
}
@ -139,14 +139,14 @@ class Driver {
searchTerms(textSource) {
textSource.setEndOffset(this.options.scanning.length);
const findFunc = this.options.general.groupResults ? findTermsGrouped : findTerms;
const findFunc = this.options.general.groupResults ? bgTermsFindGrouped : bgTermsFind;
return findFunc(textSource.text()).then(({definitions, length}) => {
if (definitions.length === 0) {
return false;
} else {
textSource.setEndOffset(length);
const sentence = extractSentence(textSource, this.options.anki.sentenceExt);
const sentence = docSentenceExtract(textSource, this.options.anki.sentenceExt);
const url = window.location.href;
this.popup.showNextTo(textSource.getRect());
@ -165,11 +165,11 @@ class Driver {
searchKanji(textSource) {
textSource.setEndOffset(1);
return findKanji(textSource.text()).then(definitions => {
return bgKanjiFind(textSource.text()).then(definitions => {
if (definitions.length === 0) {
return false;
} else {
const sentence = extractSentence(textSource, this.options.anki.sentenceExt);
const sentence = docSentenceExtract(textSource, this.options.anki.sentenceExt);
const url = window.location.href;
this.popup.showNextTo(textSource.getRect());
@ -186,7 +186,7 @@ class Driver {
}
searchClear() {
destroyImposters();
docImposterDestroy();
this.popup.hide();
if (this.options.scanning.selectText && this.lastTextSource !== null) {
@ -203,7 +203,7 @@ class Driver {
this.popup.showOrphaned();
}
} else {
showError(error);
errorShow(error);
}
}

View File

@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
class Frame {
constructor() {
this.definitions = [];
@ -48,14 +49,14 @@ class Frame {
this.showSpinner(false);
window.scrollTo(0, 0);
renderText(params, 'terms.html').then(content => {
bgTextRender(params, 'terms.html').then(content => {
$('#content').html(content);
$('.action-add-note').click(this.onAddNote.bind(this));
$('.kanji-link').click(e => {
e.preventDefault();
const character = $(e.target).text();
findKanji(character).then(definitions => this.api_showKanjiDefs({definitions, options, context}));
bgKanjiFind(character).then(definitions => this.api_showKanjiDefs({definitions, options, context}));
});
$('.action-play-audio').click(e => {
@ -86,7 +87,7 @@ class Frame {
this.showSpinner(false);
window.scrollTo(0, 0);
renderText(params, 'kanji.html').then(content => {
bgTextRender(params, 'kanji.html').then(content => {
$('#content').html(content);
$('.action-add-note').click(this.onAddNote.bind(this));
@ -115,19 +116,19 @@ class Frame {
const definition = this.definitions[index];
if (mode !== 'kanji') {
const url = buildAudioUrl(definition);
const filename = buildAudioFilename(definition);
const url = audioUrlBuild(definition);
const filename = audioFilenameBuild(definition);
if (url && filename) {
definition.audio = {url, filename};
}
}
addDefinition(definition, mode).then(success => {
bgDefinitionAdd(definition, mode).then(success => {
if (success) {
const button = this.findAddNoteButton(index, mode);
button.addClass('disabled');
} else {
showError('note could not be added');
errorShow('note could not be added');
}
}).catch(error => {
this.handleError(error);
@ -137,7 +138,7 @@ class Frame {
}
updateAddNoteButtons(modes, sequence) {
canAddDefinitions(this.definitions, modes).then(states => {
bgDefinitionsAddable(this.definitions, modes).then(states => {
if (states === null) {
return;
}
@ -180,7 +181,7 @@ class Frame {
}
}
const url = buildAudioUrl(definition);
const url = audioUrlBuild(definition);
if (!url) {
return;
}
@ -206,7 +207,7 @@ class Frame {
if (window.orphaned) {
this.api_showOrphaned();
} else {
showError(error);
errorShow(error);
}
}
}

View File

@ -20,6 +20,7 @@
* 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);

View File

@ -17,7 +17,11 @@
*/
function invokeBgApi(action, params) {
/*
* Background
*/
function bgInvoke(action, params) {
return new Promise((resolve, reject) => {
try {
chrome.runtime.sendMessage({action, params}, ({result, error}) => {
@ -34,39 +38,40 @@ function invokeBgApi(action, params) {
});
}
function showError(error) {
window.alert(`Error: ${error}`);
function bgOptionsGet() {
return bgInvoke('optionsGet', {});
}
function getOptions() {
return invokeBgApi('getOptions', {});
function bgTermsFind(text) {
return bgInvoke('termsFind', {text});
}
function findTerms(text) {
return invokeBgApi('findTerms', {text});
function bgTermsFindGrouped(text) {
return bgInvoke('termsFindGrouped', {text});
}
function findTermsGrouped(text) {
return invokeBgApi('findTermsGrouped', {text});
function bgKanjiFind(text) {
return bgInvoke('kanjiFind', {text});
}
function findKanji(text) {
return invokeBgApi('findKanji', {text});
function bgTextRender(data, template) {
return bgInvoke('textRender', {data, template});
}
function renderText(data, template) {
return invokeBgApi('renderText', {data, template});
function bgDefinitionsAddable(definitions, modes) {
return bgInvoke('definitionsAddable', {definitions, modes}).catch(() => null);
}
function canAddDefinitions(definitions, modes) {
return invokeBgApi('canAddDefinitions', {definitions, modes}).catch(() => null);
function bgDefinitionAdd(definition, mode) {
return bgInvoke('definitionAdd', {definition, mode});
}
function addDefinition(definition, mode) {
return invokeBgApi('addDefinition', {definition, mode});
}
function getElementOffset(element) {
/*
* Document
*/
function docOffsetCalc(element) {
const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft;
@ -80,14 +85,14 @@ function getElementOffset(element) {
return {top, left};
}
function createImposter(element) {
function docImposterCreate(element) {
const styleProps = window.getComputedStyle(element);
const stylePairs = [];
for (const key of styleProps) {
stylePairs.push(`${key}: ${styleProps[key]};`);
}
const offset = getElementOffset(element);
const offset = docOffsetCalc(element);
const imposter = document.createElement('div');
imposter.className = 'yomichan-imposter';
imposter.innerText = element.value;
@ -105,39 +110,39 @@ function createImposter(element) {
imposter.scrollLeft = element.scrollLeft;
}
function destroyImposters() {
function docImposterDestroy() {
for (const element of document.getElementsByClassName('yomichan-imposter')) {
element.parentNode.removeChild(element);
}
}
function hideImposters() {
function docImposterHide() {
for (const element of document.getElementsByClassName('yomichan-imposter')) {
element.style.visibility = 'hidden';
}
}
function textSourceFromPoint(point, imposter) {
function docRangeFromPoint(point, imposter) {
const element = document.elementFromPoint(point.x, point.y);
if (element !== null) {
if (element.nodeName === 'IMG' || element.nodeName === 'BUTTON') {
return new TextSourceElement(element);
} else if (imposter && (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA')) {
createImposter(element);
docImposterCreate(element);
}
}
const range = document.caretRangeFromPoint(point.x, point.y);
if (range !== null) {
hideImposters();
docImposterHide();
return new TextSourceRange(range);
}
destroyImposters();
docImposterDestroy();
return null;
}
function extractSentence(source, extent) {
function docSentenceExtract(source, extent) {
const quotesFwd = {'「': '」', '『': '』', "'": "'", '"': '"'};
const quotesBwd = {'」': '「', '』': '『', "'": "'", '"': '"'};
const terminators = '…。..?!';
@ -192,7 +197,12 @@ function extractSentence(source, extent) {
return content.substring(startPos, endPos).trim();
}
function buildAudioUrl(definition) {
/*
* Audio
*/
function audioUrlBuild(definition) {
let kana = definition.reading;
let kanji = definition.expression;
@ -216,7 +226,7 @@ function buildAudioUrl(definition) {
return `https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?${params.join('&')}`;
}
function buildAudioFilename(definition) {
function audioFilenameBuild(definition) {
if (!definition.reading && !definition.expression) {
return null;
}
@ -231,3 +241,12 @@ function buildAudioFilename(definition) {
return filename += '.mp3';
}
/*
* Error
*/
function errorShow(error) {
window.alert(`Error: ${error}`);
}

View File

@ -16,10 +16,10 @@
"matches": ["http://*/*", "https://*/*", "file://*/*"],
"js": [
"fg/js/gecko.js",
"fg/js/util.js",
"fg/js/source-range.js",
"fg/js/source-element.js",
"fg/js/popup.js",
"fg/js/util.js",
"fg/js/driver.js"
],
"css": ["fg/css/client.css"]