Merge branch 'master' into firefox-amo

This commit is contained in:
Alex Yatskov 2017-04-08 18:04:37 -07:00
commit 1b49f91a9b
10 changed files with 72 additions and 49 deletions

View File

@ -9,14 +9,9 @@
<body> <body>
<div class="container"> <div class="container">
<div class="page-header"> <div class="page-header">
<h1>Welcome to Yomichan!</h1> <h1>Yomichan Usage Guide</h1>
</div> </div>
<p>Thank you for downloading this extension! I hope that Yomichan will help you on your language learning journey.</p>
<div>
<h2>Quick Guide</h2>
<p> <p>
Read the steps below to get up and running with Yomichan. For complete documentation, Read the steps below to get up and running with Yomichan. For complete documentation,
visit the <a href="https://foosoft.net/projects/yomichan/" target="_blank">official homepage</a>. visit the <a href="https://foosoft.net/projects/yomichan/" target="_blank">official homepage</a>.
@ -30,7 +25,8 @@
<li>Click on the <img src="/mixed/img/play-audio.png" alt> icon to hear the term pronounced by a native speaker.</li> <li>Click on the <img src="/mixed/img/play-audio.png" alt> icon to hear the term pronounced by a native speaker.</li>
<li>Click on individual Kanji in the term definition results to view additional information about those characters.</li> <li>Click on individual Kanji in the term definition results to view additional information about those characters.</li>
</ol> </ol>
</div>
<p>This startup notification can be turned off on the Yomichan options page.</p>
</div> </div>
</body> </body>
</html> </html>

View File

@ -25,6 +25,7 @@ function formRead() {
return optionsLoad().then(optionsOld => { return optionsLoad().then(optionsOld => {
const optionsNew = $.extend(true, {}, optionsOld); const optionsNew = $.extend(true, {}, optionsOld);
optionsNew.general.showGuide = $('#show-usage-guide').prop('checked');
optionsNew.general.audioSource = $('#audio-playback-source').val(); optionsNew.general.audioSource = $('#audio-playback-source').val();
optionsNew.general.audioVolume = $('#audio-playback-volume').val(); optionsNew.general.audioVolume = $('#audio-playback-volume').val();
optionsNew.general.groupResults = $('#group-terms-results').prop('checked'); optionsNew.general.groupResults = $('#group-terms-results').prop('checked');
@ -111,6 +112,7 @@ $(document).ready(() => {
handlebarsRegister(); handlebarsRegister();
optionsLoad().then(options => { optionsLoad().then(options => {
$('#show-usage-guide').prop('checked', options.general.showGuide);
$('#audio-playback-source').val(options.general.audioSource); $('#audio-playback-source').val(options.general.audioSource);
$('#audio-playback-volume').val(options.general.audioVolume); $('#audio-playback-volume').val(options.general.audioVolume);
$('#group-terms-results').prop('checked', options.general.groupResults); $('#group-terms-results').prop('checked', options.general.groupResults);
@ -368,9 +370,6 @@ function ankiFieldsPopulate(element, options) {
], ],
'kanji': [ 'kanji': [
'character', 'character',
'cloze-body',
'cloze-prefix',
'cloze-suffix',
'dictionary', 'dictionary',
'glossary', 'glossary',
'kunyomi', 'kunyomi',

View File

@ -89,7 +89,8 @@ function optionsSetDefaults(options) {
showAdvanced: false, showAdvanced: false,
popupWidth: 400, popupWidth: 400,
popupHeight: 250, popupHeight: 250,
popupOffset: 10 popupOffset: 10,
showGuide: true
}, },
scanning: { scanning: {
@ -144,6 +145,9 @@ function optionsVersion(options) {
} else { } else {
options.general.audioSource = 'disabled'; options.general.audioSource = 'disabled';
} }
},
() => {
options.general.showGuide = false;
} }
]; ];

View File

@ -28,8 +28,8 @@ window.yomichan = new class {
this.translator.prepare().then(optionsLoad).then(this.optionsSet.bind(this)).then(() => { this.translator.prepare().then(optionsLoad).then(this.optionsSet.bind(this)).then(() => {
chrome.commands.onCommand.addListener(this.onCommand.bind(this)); chrome.commands.onCommand.addListener(this.onCommand.bind(this));
chrome.runtime.onMessage.addListener(this.onMessage.bind(this)); chrome.runtime.onMessage.addListener(this.onMessage.bind(this));
if (chrome.runtime.onInstalled) { if (this.options.general.showGuide) {
chrome.runtime.onInstalled.addListener(this.onInstalled.bind(this)); chrome.tabs.create({url: chrome.extension.getURL('/bg/guide.html')});
} }
}); });
} }
@ -157,12 +157,6 @@ window.yomichan = new class {
return Promise.resolve(handlebarsRender(template, data)); return Promise.resolve(handlebarsRender(template, data));
} }
onInstalled(details) {
if (details.reason === 'install') {
chrome.tabs.create({url: chrome.extension.getURL('/bg/guide.html')});
}
}
onCommand(command) { onCommand(command) {
const handlers = { const handlers = {
search: () => { search: () => {

View File

@ -25,6 +25,10 @@
<div> <div>
<h3>General Options</h3> <h3>General Options</h3>
<div class="checkbox">
<label><input type="checkbox" id="show-usage-guide"> Show usage guide on startup</label>
</div>
<div class="checkbox"> <div class="checkbox">
<label><input type="checkbox" id="group-terms-results"> Group term results</label> <label><input type="checkbox" id="group-terms-results"> Group term results</label>
</div> </div>
@ -193,6 +197,13 @@
<input type="text" id="interface-server" class="form-control"> <input type="text" id="interface-server" class="form-control">
</div> </div>
<p class="help-block">
Specify the information you would like included in your flashcards in the field editor below.
Please be aware that Anki requires the first field in the model to be unique. It is highly recommended
that you set it to <code>{expression}</code> for term flashcards and <code>{character}</code> for
Kanji flashcards.
</p>
<div id="anki-format"> <div id="anki-format">
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
<li class="active"><a href="#terms" data-toggle="tab">Terms</a></li> <li class="active"><a href="#terms" data-toggle="tab">Terms</a></li>

View File

@ -172,13 +172,13 @@ window.driver = new class {
} else { } else {
textSource.setEndOffset(length); textSource.setEndOffset(length);
const cloze = docClozeExtract(textSource, this.options.anki.sentenceExt); const sentence = docSentenceExtract(textSource, this.options.anki.sentenceExt);
const url = window.location.href; const url = window.location.href;
this.popup.showTermDefs( this.popup.showTermDefs(
textSource.getRect(), textSource.getRect(),
definitions, definitions,
this.options, this.options,
{cloze, url} {sentence, url}
); );
this.lastTextSource = textSource; this.lastTextSource = textSource;
@ -198,13 +198,13 @@ window.driver = new class {
if (definitions.length === 0) { if (definitions.length === 0) {
return false; return false;
} else { } else {
const cloze = docClozeExtract(textSource, this.options.anki.sentenceExt); const sentence = docSentenceExtract(textSource, this.options.anki.sentenceExt);
const url = window.location.href; const url = window.location.href;
this.popup.showKanjiDefs( this.popup.showKanjiDefs(
textSource.getRect(), textSource.getRect(),
definitions, definitions,
this.options, this.options,
{cloze, url} {sentence, url}
); );
this.lastTextSource = textSource; this.lastTextSource = textSource;

View File

@ -152,7 +152,7 @@ function docRangeFromPoint(point, imposter) {
return null; return null;
} }
function docClozeExtract(source, extent) { function docSentenceExtract(source, extent) {
const quotesFwd = {'「': '」', '『': '』', "'": "'", '"': '"'}; const quotesFwd = {'「': '」', '『': '』', "'": "'", '"': '"'};
const quotesBwd = {'」': '「', '』': '『', "'": "'", '"': '"'}; const quotesBwd = {'」': '「', '』': '『', "'": "'", '"': '"'};
const terminators = '…。..?!'; const terminators = '…。..?!';
@ -182,7 +182,7 @@ function docClozeExtract(source, extent) {
quoteStack = []; quoteStack = [];
let endPos = content.length - 1; let endPos = content.length;
for (let i = position; i <= endPos; ++i) { for (let i = position; i <= endPos; ++i) {
const c = content[i]; const c = content[i];
@ -204,15 +204,11 @@ function docClozeExtract(source, extent) {
} }
} }
const sentence = content.substring(startPos, endPos); const text = content.substring(startPos, endPos);
const clozePrefix = sentence.substring(0, position - startPos); const padding = text.length - text.replace(/^\s+/, '').length;
const clozeBody = source.text();
const clozeSuffix = sentence.substring(position - startPos + clozeBody.length);
return { return {
sentence: sentence.trim(), text: text.trim(),
prefix: clozePrefix.trim(), offset: position - startPos - padding
body: clozeBody.trim(),
suffix: clozeSuffix.trim()
}; };
} }

View File

@ -1,7 +1,7 @@
{ {
"manifest_version": 2, "manifest_version": 2,
"name": "Yomichan", "name": "Yomichan",
"version": "1.1.11", "version": "1.1.12",
"description": "Japanese dictionary with Anki integration", "description": "Japanese dictionary with Anki integration",
"icons": {"16": "mixed/img/icon16.png", "48": "mixed/img/icon48.png", "128": "mixed/img/icon128.png"}, "icons": {"16": "mixed/img/icon16.png", "48": "mixed/img/icon48.png", "128": "mixed/img/icon128.png"},

View File

@ -74,7 +74,7 @@ class Display {
if (context) { if (context) {
for (const definition of definitions) { for (const definition of definitions) {
definition.cloze = context.cloze; definition.cloze = clozeBuild(context.sentence, definition.source);
definition.url = context.url; definition.url = context.url;
} }
} }
@ -108,7 +108,7 @@ class Display {
if (context) { if (context) {
for (const definition of definitions) { for (const definition of definitions) {
definition.cloze = context.cloze; definition.cloze = clozeBuild(context.sentence);
definition.url = context.url; definition.url = context.url;
} }
} }
@ -181,7 +181,7 @@ class Display {
}; };
if (this.context) { if (this.context) {
context.cloze = this.context.cloze; context.sentence = this.context.sentence;
context.url = this.context.url; context.url = this.context.url;
} }
@ -308,7 +308,7 @@ class Display {
if (this.context && this.context.source) { if (this.context && this.context.source) {
const context = { const context = {
url: this.context.source.url, url: this.context.source.url,
cloze: this.context.source.cloze, sentence: this.context.source.sentence,
index: this.context.source.index index: this.context.source.index
}; };

View File

@ -17,6 +17,25 @@
*/ */
/*
* Cloze
*/
function clozeBuild(sentence, source) {
const result = {
sentence: sentence.text.trim()
};
if (source) {
result.prefix = sentence.text.substring(0, sentence.offset).trim();
result.body = source.trim();
result.suffix = sentence.text.substring(sentence.offset + source.length).trim();
}
return result;
}
/* /*
* Audio * Audio
*/ */
@ -103,6 +122,10 @@ function audioBuildFilename(definition) {
} }
function audioInject(definition, fields, mode) { function audioInject(definition, fields, mode) {
if (mode === 'disabled') {
return Promise.resolve(true);
}
const filename = audioBuildFilename(definition); const filename = audioBuildFilename(definition);
if (!filename) { if (!filename) {
return Promise.resolve(true); return Promise.resolve(true);