Merge branch 'master' into firefox-amo
This commit is contained in:
commit
1b49f91a9b
@ -9,28 +9,24 @@
|
|||||||
<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>
|
<p>
|
||||||
|
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>.
|
||||||
|
</p>
|
||||||
|
|
||||||
<div>
|
<ol>
|
||||||
<h2>Quick Guide</h2>
|
<li>Click on the <img src="/mixed/img/icon16.png" alt> icon in the browser toolbar to open the Yomichan actions dialog.</li>
|
||||||
|
<li>Click on the <em>monkey wrench</em> icon in the middle to open the options page.</li>
|
||||||
|
<li>Import the dictionaries you wish to use for term and Kanji searches.</li>
|
||||||
|
<li>Hold down <kbd>Shift</kbd> key or the middle mouse button as you move your mouse over text to display definitions.</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>
|
||||||
|
</ol>
|
||||||
|
|
||||||
<p>
|
<p>This startup notification can be turned off on the Yomichan options page.</p>
|
||||||
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>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<ol>
|
|
||||||
<li>Click on the <img src="/mixed/img/icon16.png" alt> icon in the browser toolbar to open the Yomichan actions dialog.</li>
|
|
||||||
<li>Click on the <em>monkey wrench</em> icon in the middle to open the options page.</li>
|
|
||||||
<li>Import the dictionaries you wish to use for term and Kanji searches.</li>
|
|
||||||
<li>Hold down <kbd>Shift</kbd> key or the middle mouse button as you move your mouse over text to display definitions.</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>
|
|
||||||
</ol>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -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',
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -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: () => {
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
|
@ -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()
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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"},
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user