/**
* LWT Javascript functions
*
* @author andreask7 <andreasks7@users.noreply.github.com>
* @license Unlicense <http://unlicense.org/>
* @since 1.6.16-fork
*
* "Learning with Texts" (LWT) is free and unencumbered software
* released into the PUBLIC DOMAIN.
*
* Anyone is free to copy, modify, publish, use, compile, sell, or
* distribute this software, either in source code form or as a
* compiled binary, for any purpose, commercial or non-commercial,
* and by any means.
*
* In jurisdictions that recognize copyright laws, the author or
* authors of this software dedicate any and all copyright
* interest in the software to the public domain. We make this
* dedication for the benefit of the public at large and to the
* detriment of our heirs and successors. We intend this
* dedication to be an overt act of relinquishment in perpetuity
* of all present and future rights to this software under
* copyright law.
*
* 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 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.
*
* For more information, please refer to [http://unlicense.org/].
*/
/**************************************************************
Global variables for OVERLIB
***************************************************************/
/**
* OVERLIB text font
*/
var ol_textfont = '"Lucida Grande",Arial,sans-serif,STHeiti,"Arial Unicode MS",MingLiu';
var ol_textsize = 3;
var ol_sticky = 1;
var ol_captionfont = '"Lucida Grande",Arial,sans-serif,STHeiti,"Arial Unicode MS",MingLiu';
var ol_captionsize = 3;
var ol_width = 260;
var ol_close = 'Close';
var ol_offsety = 30;
var ol_offsetx = 3;
var ol_fgcolor = '#FFFFE8';
var ol_closecolor = '#FFFFFF';
/**************************************************************
* Helper functions for overlib
***************************************************************/
/**
* Handle click event on ignored words
*
* @param {string} wblink1 First dictionary URL
* @param {string} wblink2 Second dictionary URL
* @param {string} wblink3 Google Translate dictionary URL
* @param {string} hints Hint for the word
* @param {int} txid Text ID
* @param {*} torder
* @param {string} txt Text
* @param {int} wid Word ID
* @param {*} multi_words
* @param {boolean} rtl Right-to-left text indicator
* @param {*} ann
* @returns {boolean}
*/
function run_overlib_status_98(
wblink1, wblink2, wblink3, hints, txid, torder, txt, wid, multi_words, rtl, ann
) {
const lang = getLangFromDict(WBLINK3);
return overlib(
make_overlib_audio(txt, lang) +
'<b>' + escape_html_chars_2(hints, ann) + '</b><br/>' +
make_overlib_link_new_word(txid, torder, wid) + ' | ' +
make_overlib_link_delete_word(txid, wid) +
make_overlib_link_new_multiword(txid, torder, multi_words, rtl) + ' <br /> ' +
make_overlib_link_wb(wblink1, wblink2, wblink3, txt, txid, torder),
CAPTION,
'Word'
);
}
/**
* Handle click event on well-known words
*
* @param {string} wblink1 First dictionary URL
* @param {string} wblink2 Second dictionary URL
* @param {string} wblink3 Google Translate dictionary URL
* @param {string} hints Hint for the word
* @param {int} txid Text ID
* @param {*} torder
* @param {string} txt Text
* @param {int} wid Word ID
* @param {*} multi_words
* @param {boolean} rtl Right-to-left text indicator
* @param {*} ann
* @returns {boolean}
*/
function run_overlib_status_99 (
wblink1, wblink2, wblink3, hints, txid, torder, txt, wid, multi_words, rtl, ann
) {
const lang = getLangFromDict(WBLINK3);
return overlib(
make_overlib_audio(txt, lang) +
'<b>' + escape_html_chars_2(hints, ann) + '</b><br/> ' +
make_overlib_link_new_word(txid, torder, wid) + ' | ' +
make_overlib_link_delete_word(txid, wid) +
make_overlib_link_new_multiword(txid, torder, multi_words, rtl) + ' <br /> ' +
make_overlib_link_wb(wblink1, wblink2, wblink3, txt, txid, torder),
CAPTION,
'Word'
);
}
/**
* Handle click event on learning words (levels 1 to 5)
*
* @param {string} wblink1 First dictionary URL
* @param {string} wblink2 Second dictionary URL
* @param {string} wblink3 Google Translate dictionary URL
* @param {string} hints Hint for the word
* @param {int} txid Text ID
* @param {*} torder
* @param {string} txt Text
* @param {int} wid Word ID
* @param {int} stat
* @param {*} multi_words
* @param {boolean} rtl Right-to-left text indicator
* @param {*} ann Unused
* @returns {boolean}
*/
function run_overlib_status_1_to_5 (
wblink1, wblink2, wblink3, hints, txid,
torder, txt, wid, stat, multi_words, rtl, ann
) {
const lang = getLangFromDict(WBLINK3);
return overlib(
'<div>' + make_overlib_audio(txt, lang) + '<span>(Read)</span></div>' +
make_overlib_link_change_status_all(txid, torder, wid, stat) + ' <br /> ' +
make_overlib_link_edit_word(txid, torder, wid) + ' | ' +
make_overlib_link_delete_word(txid, wid) +
make_overlib_link_new_multiword(txid, torder, multi_words, rtl) + ' <br /> ' +
make_overlib_link_wb(wblink1, wblink2, wblink3, txt, txid, torder),
CAPTION,
make_overlib_link_edit_word_title(
'Word ',
txid, torder, wid
)
);
}
/**
* Handle click event on unknown words.
*
* @param {string} wblink1 First dictionary URL
* @param {string} wblink2 Second dictionary URL
* @param {string} wblink3 Google Translate dictionary URL
* @param {string} hints Hint for the word
* @param {int} txid Text ID
* @param {*} torder
* @param {string} txt Text
* @param {array<string>} multi_words
* @param {int} rtl 1 if right-to-left language
* @returns {boolean}
*/
function run_overlib_status_unknown (
wblink1, wblink2, wblink3, hints, txid, torder, txt, multi_words, rtl
) {
const lang = getLangFromDict(WBLINK3);
return overlib(
make_overlib_audio(txt, lang) + '<b>' + escape_html_chars(hints) + '</b><br /> ' +
make_overlib_link_wellknown_word(txid, torder) + ' <br /> ' +
make_overlib_link_ignore_word(txid, torder) +
make_overlib_link_new_multiword(txid, torder, multi_words, rtl) + ' <br /> ' +
make_overlib_link_wb(wblink1, wblink2, wblink3, txt, txid, torder),
CAPTION,
'New Word'
);
}
/**
* Handle click event on a multi-word.
*
* @param {string} wblink1 First dictionary URL
* @param {string} wblink2 Second dictionary URL
* @param {string} wblink3 Google Translate dictionary URL
* @param {string} hints Hint for the word
* @param {int} txid Text ID
* @param {*} torder
* @param {string} txt Text
* @param {int} wid Word ID
* @param {int} rtl 1 if right-to-left language
* @returns {boolean}
*/
function run_overlib_multiword (
wblink1, wblink2, wblink3, hints, txid, torder, txt, wid, stat, wcnt, ann
) {
const lang = getLangFromDict(WBLINK3);
return overlib(
make_overlib_audio(txt, lang) + '<b>' + escape_html_chars_2(hints, ann) + '</b><br /> ' +
make_overlib_link_change_status_all(txid, torder, wid, stat) + ' <br /> ' +
make_overlib_link_edit_multiword(txid, torder, wid) + ' | ' +
make_overlib_link_delete_multiword(txid, wid) + ' <br /> ' +
make_overlib_link_wb(wblink1, wblink2, wblink3, txt, txid, torder),
CAPTION,
make_overlib_link_edit_multiword_title(
wcnt.trim() + '-Word-Expression', txid, torder, wid
)
);
}
/**
* Make an overlib dialog so that the user can say if he knows the word or not.
*
* @param {string} wblink1 Dictionary 1 URI
* @param {string} wblink2 Dictionary 2 URI
* @param {string} wblink3 Google Translate URI
* @param {int} wid Word ID
* @param {string} txt Word text
* @param {string} trans Word translation
* @param {string} roman Word romanization
* @param {string} stat Word learning status
* @param {string} sent Lookup sentence in Google Translate
* @param {int} todo If 1, the user should say if he knows the word.
* @param {*} oldstat Old status, unused
* @returns {*} An overlib object
*/
function run_overlib_test(
wblink1, wblink2, wblink3, wid, txt, trans, roman, stat, sent, todo, oldstat
) {
const s = parseInt(stat, 10);
let c = s + 1;
if (c > 5) c = 5;
let w = s - 1;
if (w < 1) w = 1;
let cc = stat + ' ▶ ' + c;
if (c == s) cc = c;
let ww = stat + ' ▶ ' + w;
if (w == s) ww = w;
let overlib_string = '';
if (todo == 1) {
overlib_string += '<center><hr noshade size=1 /><b>';
if (stat >= 1 && stat <= 5) {
overlib_string +=
make_overlib_link_change_status_test(
wid,
1,
'<img src="icn/thumb-up.png" title="Got it!" alt="Got it!" /> Got it! [' +
cc + ']'
) +
'<hr noshade size=1 />' +
make_overlib_link_change_status_test(
wid,
-1,
'<img src="icn/thumb.png" title="Oops!" alt="Oops!" /> Oops! [' + ww + ']'
) +
'<hr noshade size=1 />';
}
overlib_string +=
make_overlib_link_change_status_alltest(wid, stat) +
'</b></center><hr noshade size=1 />';
}
overlib_string += '<b>' + escape_html_chars(make_tooltip(txt, trans, roman, stat)) +
'</b><br />' +
' <a href="edit_tword.php?wid=' + wid +
'" target="ro" onclick="showRightFrames();">Edit term</a><br />' +
createTheDictLink(wblink1, txt, 'Dict1', 'Lookup Term: ') +
createTheDictLink(wblink2, txt, 'Dict2', '') +
createTheDictLink(wblink3, txt, 'Trans', '') +
createTheDictLink(wblink3, sent, 'Trans', '<br />Lookup Sentence:');
return overlib(overlib_string, CAPTION, 'Got it?');
}
/**
* Return all multiwords
*
* @param {int} txid Text ID
* @param {any} torder
* @param {array<string>} multi_words A list of 8 string elements
* @param {boolean} rtl Right-to-left indicator
*
* @return {string} All multiwords
*
* @since 2.8.0-fork LTR texts were wrongly displayed
*/
function make_overlib_link_new_multiword (txid, torder, multi_words, rtl) {
// Quit if all multiwords are '' or undefined
if (multi_words.every((x) => !x)) return '';
const output = Array();
if (rtl) {
for (let i = 7; i < 0; i--) {
if (multi_words[i]) {
output.push(make_overlib_link_create_edit_multiword_rtl(
i + 2, txid, torder, multi_words[i]
));
}
}
} else {
for (let i = 0; i < 7; i++) {
if (multi_words[i]) {
output.push(make_overlib_link_create_edit_multiword(
i + 2, txid, torder, multi_words[i]
));
}
}
}
return ' <br />Expr: ' + output.join(' ') + ' ';
}
/**
* Make link to translations through dictionaries or all sentences lookup.
*
* @param {string} wblink1 Dictionary 1 URI
* @param {string} wblink2 Dictionary 2 URI
* @param {string} wblink3 Google Translate URI
* @param {string} txt Word string
* @param {int} txid Text ID
* @param {int} torder
* @returns {string}
*/
function make_overlib_link_wb(wblink1, wblink2, wblink3, txt, txid, torder) {
let s =
createTheDictLink(wblink1, txt, 'Dict1', 'Lookup Term: ') +
createTheDictLink(wblink2, txt, 'Dict2', '') +
createTheDictLink(wblink3, txt, 'Trans', '');
if (torder > 0 && txid > 0) {
s += '<br />Lookup Sentence: ' +
createSentLookupLink(torder, txid, wblink3, 'Trans');
}
return s;
}
/**
* Create a list of links for dictionary translation.
*
* @param {string} wblink1 Dictionary 1 URI
* @param {string} wblink2 Dictionary 2 URI
* @param {string} wblink3 Google Translate URI
* @param {string} txt Word string
* @param {int} txid Text ID
* @param {int} torder
* @returns {string} HTML-formatted list of dictionaries link, and sentece link
*/
function make_overlib_link_wbnl (wblink1, wblink2, wblink3, txt, txid, torder) {
let s =
createTheDictLink(wblink1, txt, 'Dict1', 'Term: ') +
createTheDictLink(wblink2, txt, 'Dict2', '') +
createTheDictLink(wblink3, txt, 'Trans', '');
if (torder > 0 && txid > 0) {
s += ' | Sentence: ' + createSentLookupLink(torder, txid, wblink3, 'Trans');
}
return s;
}
/**
* Create link to dictionaries.
*
* @param {string} wblink1 Dictionary 1 URI
* @param {string} wblink2 Dictionary 2 URI
* @param {string} wblink3 Google Translate URI
* @param {string} txt Word string
* @param {string} sent Complete sentence
* @returns {string} HTML-formatted list of links
*/
function make_overlib_link_wbnl2 (wblink1, wblink2, wblink3, txt, sent) {
let s =
createTheDictLink(wblink1, txt, 'Dict1', 'Term: ') +
createTheDictLink(wblink2, txt, 'Dict2', '') +
createTheDictLink(wblink3, txt, 'Trans', '');
if (sent != '') {
s += createTheDictLink(wblink3, sent, 'Trans', ' | Sentence:');
}
return s;
}
/**
* Change the status of a word multiple time.
*
* @param {int} txid Text ID
* @param {*} torder
* @param {int} wid Word ID
* @param {int} oldstat Old word status
* @returns {string} Multiple links for a new word status.
*/
function make_overlib_link_change_status_all (txid, torder, wid, oldstat) {
let result = 'St: ';
for (let newstat = 1; newstat <= 5; newstat++) {
result += make_overlib_link_change_status(txid, torder, wid, oldstat, newstat);
}
result += make_overlib_link_change_status(txid, torder, wid, oldstat, 99);
result += make_overlib_link_change_status(txid, torder, wid, oldstat, 98);
return result;
}
/**
* Return a list of links to change word status
*
* @param {int} wid Word ID
* @param {int} oldstat Current status of the word
* @returns {string} An HTML-formatted list of links.
*/
function make_overlib_link_change_status_alltest (wid, oldstat) {
let result = '';
for (let newstat = 1; newstat <= 5; newstat++) {
result += make_overlib_link_change_status_test2(wid, oldstat, newstat);
}
result += make_overlib_link_change_status_test2(wid, oldstat, 99);
result += make_overlib_link_change_status_test2(wid, oldstat, 98);
return result;
}
/**
* Return a link to change the status of a word.
*
* @param {int} txid Text ID
* @param {*} torder
* @param {int} wid Word ID
* @param {int} oldstat Old word status
* @param {int} newstat New word status
* @returns {string} HTML formatted link to change word status
*/
function make_overlib_link_change_status (txid, torder, wid, oldstat, newstat) {
if (oldstat == newstat) {
return '<span title="' +
getStatusName(oldstat) + '">◆</span>';
}
return ' <a href="set_word_status.php?tid=' + txid +
'&ord=' + torder +
'&wid=' + wid +
'&status=' + newstat + '" target="ro" onclick="showRightFrames();">' +
'<span title="' + getStatusName(newstat) + '">[' +
getStatusAbbr(newstat) + ']</span></a> ';
}
/**
* Prepare an HTML-formated string containing the new statuses choices
*
* @param {int} wid ID of the word
* @param {int} oldstat Old status
* @param {int} newstat New status
* @returns {string} HTML-formatted link
*/
function make_overlib_link_change_status_test2 (wid, oldstat, newstat) {
let output = ' <a href="set_test_status.php?wid=' + wid +
'&status=' + newstat + '&ajax=1" target="ro" onclick="showRightFrames();">' +
'<span title="' + getStatusName(newstat) + '">[';
output += (oldstat == newstat) ? '◆' : getStatusAbbr(newstat);
output += ']</span></a> ';
return output;
}
/**
* Make a link for a word status change
*
* @param {int} wid ID of the word
* @param {int} plusminus Amplitude of the change (normally 1 or -1)
* @param {string} text Text to be embed
*
* @returns {string} A tag containing formatted text
*/
function make_overlib_link_change_status_test (wid, plusminus, text) {
return ' <a href="set_test_status.php?wid=' + wid +
'&stchange=' + plusminus +
'&ajax=1" target="ro" onclick="showRightFrames();' +
(plusminus > 0 ? 'successSound()' : 'failureSound()') + ';">' +
text + '</a> ';
}
/**
* Make a link to learn a new word.
*
*
* @param {int} txid Text ID
* @param {*} torder
* @param {int} wid Word ID
*
* @returns {string}
*/
function make_overlib_link_new_word (txid, torder, wid) {
return ' <a href="edit_word.php?tid=' + txid +
'&ord=' + torder +
'&wid=' + wid + '" target="ro" onclick="showRightFrames();">Learn term</a> ';
}
/**
* Create a link to edit a multiword.
*
* @param {int} txid Text ID
* @param {*} torder
* @param {int} wid Word ID
* @returns {string}
*/
function make_overlib_link_edit_multiword (txid, torder, wid) {
return ' <a href="edit_mword.php?tid=' + txid +
'&ord=' + torder +
'&wid=' + wid + '" target="ro" onclick="showRightFrames();">Edit term</a> ';
}
/**
* Create an overlib title for a multiword edition.
*
* @param {*} text
* @param {int} txid
* @param {*} torder
* @param {int} wid
* @returns {string}
*/
function make_overlib_link_edit_multiword_title (text, txid, torder, wid) {
return '<a style="color:yellow" href="edit_mword.php?tid=' + txid +
'&ord=' + torder +
'&wid=' + wid + '" target="ro" onclick="showRightFrames();">' +
text + '</a>';
}
/**
* Create or edit a multiword with overlib.
*
* @param {int} len Number of words in the multi-word
* @param {int} txid Text ID
* @param {*} torder
* @param {string} txt Multi-word text
* @returns {string}
*/
function make_overlib_link_create_edit_multiword (len, txid, torder, txt) {
return ' <a href="edit_mword.php?tid=' + txid +
'&ord=' + torder +
'&txt=' + txt +
'" target="ro" onclick="showRightFrames();">' +
len + '..' + escape_html_chars(txt.substring(2).trim()) + '</a> ';
}
/**
* Create or edit a right-to-left multiword with overlib.
*
* @param {int} len Number of words in the multi-word
* @param {int} txid Text ID
* @param {*} torder
* @param {string} txt Multi-word text
* @returns {string}
*/
function make_overlib_link_create_edit_multiword_rtl (len, txid, torder, txt) {
return ' <a dir="rtl" href="edit_mword.php?tid=' + txid +
'&ord=' + torder +
'&txt=' + txt +
'" target="ro" onclick="showRightFrames();">' +
len + '..' + escape_html_chars(txt.substring(2).trim()) + '</a> ';
}
/**
* Make a link to edit a word, displaying "Edit term"
*
* @param {int} txid
* @param {*} torder
* @param {int} wid
* @returns {string}
*/
function make_overlib_link_edit_word (txid, torder, wid) {
const url = 'edit_word.php?tid=' + txid +
'&ord=' + torder +
'&wid=' + wid;
return ' <a href="' + url +
' " target="ro" onclick="showRightFrames()">Edit term</a> ';
}
/**
* Make a link to edit a word for an overlib title, displaying the word's text.
*
* @param {string} text Word text
* @param {int} txid Text ID
* @param {*} torder
* @param {int} wid Word ID
* @returns {string} HTML-formatted link
*/
function make_overlib_link_edit_word_title (text, txid, torder, wid) {
return '<a style="color:yellow" href="edit_word.php?tid=' +
txid + '&ord=' + torder +
'&wid=' + wid + '" target="ro" onclick="showRightFrames();">' +
text + '</a>';
}
/**
* Make a link to delete a word with overlib.
*
* @param {int} txid Text ID
* @param {int} wid Word ID
* @returns {string} HTML-formatted link.
*/
function make_overlib_link_delete_word (txid, wid) {
return ' <a onclick="showRightFrames(); return confirmDelete();" ' +
'href="delete_word.php?wid=' + wid + '&tid=' + txid +
'" target="ro">Delete term</a> ';
}
/**
* Make a link to delete a multiword.
*
* @param {int} txid Text ID
* @param {int} wid Word ID
* @returns {string} HTML-formatted string
*/
function make_overlib_link_delete_multiword (txid, wid) {
return ' <a onclick="showRightFrames(); return confirmDelete();" ' +
'href="delete_mword.php?wid=' + wid + '&tid=' + txid +
'" target="ro">Delete term</a> ';
}
/**
* Return a link to a word well-known.
*
* @param {int} txid
* @param {*} torder
* @returns {string} HTML link to mark the word well knwown
*/
function make_overlib_link_wellknown_word (txid, torder) {
return ' <a href="insert_word_wellknown.php?tid=' +
txid + '&ord=' + torder +
'" target="ro" onclick="showRightFrames();">I know this term well</a> ';
}
/**
* Return a link to ignore a word.
*
* @param {int} txid
* @param {*} torder
* @returns {string} HTML string to ignore the word
*/
function make_overlib_link_ignore_word (txid, torder) {
return ' <a href="insert_word_ignore.php?tid=' + txid +
'&ord=' + torder +
'" target="ro" onclick="showRightFrames();">Ignore this term</a> ';
}
/**
* Create a clickable button to read a word aloud.
*
* @param {string} txt Word to say
* @param {string} lang Language name (two letters or four letters separated with a
* caret)
* @return {string} HTML-formatted clickable icon
*/
function make_overlib_audio(txt, lang) {
let img = document.createElement("img");
img.title = "Click to read!";
img.src = "icn/speaker-volume.png";
img.style.cursor = "pointer";
img.setAttribute(
"onclick",
"readTextAloud('" + escape_html_chars(txt) + "', '" + (lang || "") + "')"
);
return img.outerHTML;
}
/**************************************************************
* Other JS utility functions
**************************************************************/
/**
* Return the name of a given status.
*
* @param {int} status Status number (int<1, 5>|98|99)
* @returns {string}
*/
function getStatusName (status) {
return STATUSES[status] ? STATUSES[status].name : 'Unknown';
}
/**
* Return the abbreviation of a status
*
* @param {int} status Status number (int<1, 5>|98|99)
* @returns {string} Abbreviation
*/
function getStatusAbbr (status) {
return STATUSES[status] ? STATUSES[status].abbr : '?';
}
/**
* Translate a sentence.
*
* @param {string} url Translation URL with "{term}" marking the interesting term
* @param {object} sentctl Textarea contaning sentence
* @returns {void}
*/
function translateSentence (url, sentctl) {
if (sentctl !== undefined && url != '') {
const text = sentctl.value;
if (typeof text === 'string') {
showRightFrames(undefined, createTheDictUrl(url, text.replace(/[{}]/g, '')));
}
}
}
/**
* Translate a sentence.
*
* @param {string} url Translation URL with "{term}" marking the interesting term
* @param {object} sentctl Textarea contaning sentence
* @returns {void}
*/
function translateSentence2 (url, sentctl) {
if (typeof sentctl !== 'undefined' && url != '') {
const text = sentctl.value;
if (typeof text === 'string') {
const finalurl = createTheDictUrl(url, text.replace(/[{}]/g, ''));
owin(finalurl);
}
}
}
/**
* Open a new window with the translation of the word.
*
* @param {string} url Dictionary URL
* @param {object} wordctl Textarea containing word to translate.
* @returns {void}
*/
function translateWord(url, wordctl) {
if (wordctl !== undefined && url != '') {
const text = wordctl.value;
if (typeof text === 'string') {
showRightFrames(undefined, createTheDictUrl(url, text));
}
}
}
/**
* Open a new window with the translation of the word.
*
* @param {string} url Dictionary URL
* @param {object} wordctl Textarea containing word to translate.
* @returns {void}
*/
function translateWord2(url, wordctl) {
if (wordctl !== undefined && url != '') {
const text = wordctl.value;
if (typeof text === 'string') {
owin(createTheDictUrl(url, text));
}
}
}
/**
* Open a new window with the translation of the word.
*
* @param {string} url Dictionary URL
* @param {string} word Word to translate.
* @returns {void}
*/
function translateWord3(url, word) {
owin(createTheDictUrl(url, word));
}
/**
* Get the language name from the Google Translate URL.
*
* @param {string} wblink3 Google Translate Dictionary URL
* @returns {string} Language name
*
* @since 2.7.0 Also works with a LibreTranslate URL
*/
function getLangFromDict(wblink3) {
let dictUrl, urlParams;
if (wblink3.trim() == '') {
return '';
}
// Replace pop-up marker '*'
if (wblink3.startsWith('*')) {
wblink3 = wblink3.substring(1);
}
if (wblink3.startsWith("trans.php") || wblink3.startsWith("ggl.php")) {
wblink3 = 'http://' + wblink3;
}
dictUrl = new URL(wblink3);
urlParams = dictUrl.searchParams;
if (urlParams.get("lwt_translator") == "libretranslate") {
return urlParams.get("source") || "";
}
// Fallback to Google Translate
return urlParams.get("sl") || "";
}
/**
* Return a tooltip, a short string describing the word (word, translation,
* romanization and learning status)
*
* @param {string} word The word
* @param {string} trans Translation of the word
* @param {string} roman Romanized version
* @param {int} status Learning status of the word
* @returns {string} Tooltip for this word
*/
function make_tooltip (word, trans, roman, status) {
const nl = '\x0d';
let title = word;
if (roman != '') {
if (title != '') title += nl;
title += '▶ ' + roman;
}
if (trans != '' && trans != '*') {
if (title != '') title += nl;
title += '▶ ' + trans;
}
if (title != '') title += nl;
title += '▶ ' + getStatusName(status) + ' [' +
getStatusAbbr(status) + ']';
return title;
}
/**
* Escape the HTML characters, with an eventual annotation
*
* @param {string} title String to be escaped
* @param {string} ann An annotation to show in red
* @returns {string} Escaped string
*/
function escape_html_chars_2 (title, ann) {
if (ann != '') {
const ann2 = escape_html_chars(ann);
return escape_html_chars(title).replace(ann2,
'<span style="color:red">' + ann2 + '</span>');
}
return escape_html_chars(title);
}
/**
* Open a window.
*
* @param {string} url URL of the window
*/
function owin (url) {
window.open(
url,
'dictwin',
'width=800, height=400, scrollbars=yes, menubar=no, resizable=yes, status=no'
);
}
/**
* Open a window in edit mode.
*
* @param {string} url Window URL
*/
function oewin (url) {
window.open(
url,
'editwin',
'width=800, height=600, scrollbars=yes, menubar=no, resizable=yes, status=no'
);
}
/**
* Create a dictionary URL.
*
* JS alter ego of the createTheDictLink PHP function.
*
* Case 1: url without any ### or "lwt_term": append term
* Case 2: url with one ### or "lwt_term": substitute term
*
* @param {string} u Dictionary URL
* @param {string} w Term to be inserted in the URL
* @returns {string} A link to external dictionary to get a translation of the word
*
* @since 2.6.0-fork Internals rewrote, do no longer use PHP code.
* The option putting encoding between ###enc### does no
* longer work. It is deprecated and will be removed.
* @since 2.7.0-fork Using "###" is deprecated, "lwt_term" recommended instead
*/
function createTheDictUrl (u, w) {
const url = u.trim();
const trm = w.trim();
const term_elem = url.match(/lwt_term|###/);
const pos = (term_elem === null) ? -1 : url.indexOf(term_elem[0]);
// No ###/lwt_term found
if (pos == -1) {
return url + encodeURIComponent(trm);
}
// ###/lwt_term found
const pos2 = url.indexOf('###', pos + 1);
if (pos2 === -1) {
// 1 ###/lwt_term found
return url.replace(term_elem, trm == '' ? '+' : encodeURIComponent(trm));
}
// 2 ### found
// Get encoding
const enc = url.substring(
pos + term_elem[0].length, pos2 - pos - term_elem[0].length
).trim();
console.warn(
"Trying to use encoding '" + enc + "'. This feature is abandonned since " +
"2.6.0-fork. Using default UTF-8."
);
let output = url.substring(0, pos) + encodeURIComponent(trm);
if (pos2+3 < url.length) {
output += url.substring(pos2 + 3);
}
return output;
}
/**
* Create an HTML link for a dictionary.
*
* @param {string} u Dictionary URL
* @param {string} w Word or sentence to be translated
* @param {string} t Text to display
* @param {string} b Some other text to display before the link
* @returns {string} HTML-formatted link
*/
function createTheDictLink (u, w, t, b) {
let url = u.trim();
let popup = false;
const trm = w.trim();
const txt = t.trim();
const txtbefore = b.trim();
let r = '';
if (url == '' || txt == '') {
return r;
}
if (url.startsWith('*')) {
url = url.substring(1);
popup = true;
}
try {
let final_url = new URL(url);
popup |= final_url.searchParams.has('lwt_popup');
} catch (err) {
if (!(err instanceof TypeError)) {
throw err;
}
}
if (popup) {
r = ' ' + txtbefore +
' <span class="click" onclick="owin(\''
+ createTheDictUrl(url, escape_apostrophes(trm))
+ '\');">' + txt + '</span> ';
} else {
r = ' ' + txtbefore +
' <a href="' + createTheDictUrl(url, trm) +
'" target="ru" onclick="showRightFrames();">' + txt + '</a> ';
}
return r;
}
/**
* Create a sentence lookup link.
*
* @param {int} torder Text order
* @param {int} txid Text ID
* @param {string} url Translator URL
* @param {string} txt Word text
* @returns {string} HTML-formatted link.
*/
function createSentLookupLink (torder, txid, url, txt) {
url = url.trim();
txt = txt.trim();
let r = '';
let popup = false;
let external = false;
const target_url = 'trans.php?x=1&i=' + torder + '&t=' + txid;
if (url == '' || txt == '') {
return r;
}
if (url.startsWith('*')) {
url = url.substring(1);
popup = true;
}
try {
let final_url = new URL(url);
popup |= final_url.searchParams.has('lwt_popup');
external = true;
} catch (err) {
if (!(err instanceof TypeError)) {
throw err;
}
}
if (popup) {
return ' <span class="click" onclick="owin(\'' + target_url + '\');">' +
txt + '</span> ';
}
if (external) {
return ' <a href="' + target_url + '" target="ru" onclick="showRightFrames();">'
+ txt + '</a> ';
}
return r;
}
/**
* Replace html characters with encodings
*
* See https://stackoverflow.com/questions/1787322/what-is-the-htmlspecialchars-equivalent-in-javascript
*
* @param {string} s String to be escaped
* @returns {string} Escaped string
*/
function escape_html_chars(s) {
let map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
"\x0d": '<br />' // This one inserts HTML, delete? (2.9.0)
};
return s.replace(/[&<>"'\x0d]/g, function(m) { return map[m]; });
}
/**
* Escape only single apostrophe ("'") from string
*
* @param {string} s String to be escaped
* @returns {string} Escaped string
*/
function escape_apostrophes (s) {
return s.replace(/'/g, '\\\'');
}
function selectToggle (toggle, form) {
const myForm = document.forms[form];
for (let i = 0; i < myForm.length; i++) {
if (toggle) {
myForm.elements[i].checked = 'checked';
} else {
myForm.elements[i].checked = '';
}
}
markClick();
}
function multiActionGo (f, sel) {
if (f !== undefined && sel !== undefined) {
const v = sel.value;
const t = sel.options[sel.selectedIndex].text;
if (typeof v === 'string') {
if (v == 'addtag' || v == 'deltag') {
let notok = 1;
var answer = '';
while (notok) {
answer = prompt(
'*** ' + t + ' ***' +
'\n\n*** ' + $('input.markcheck:checked').length +
' Record(s) will be affected ***' +
'\n\nPlease enter one tag (20 char. max., no spaces, no commas -- ' +
'or leave empty to cancel:',
answer
);
if (typeof answer === 'object') answer = '';
if (answer.indexOf(' ') > 0 || answer.indexOf(',') > 0) {
alert('Please no spaces or commas!');
} else if (answer.length > 20) {
alert('Please no tags longer than 20 char.!');
} else {
notok = 0;
}
}
if (answer != '') {
f.data.value = answer;
f.submit();
}
} else if (
v == 'del' || v == 'smi1' || v == 'spl1' || v == 's1' || v == 's5' ||
v == 's98' || v == 's99' || v == 'today' || v == 'delsent' ||
v == 'lower' || v == 'cap'
) {
var answer = confirm(
'*** ' + t + ' ***\n\n*** ' + $('input.markcheck:checked').length +
' Record(s) will be affected ***\n\nAre you sure?'
);
if (answer) {
f.submit();
}
} else {
f.submit();
}
}
sel.value = '';
}
}
function allActionGo (f, sel, n) {
if (typeof f !== 'undefined' && typeof sel !== 'undefined') {
const v = sel.value;
const t = sel.options[sel.selectedIndex].text;
if (typeof v === 'string') {
if (v == 'addtagall' || v == 'deltagall') {
let notok = 1;
var answer = '';
while (notok) {
answer = prompt(
'THIS IS AN ACTION ON ALL RECORDS\n' +
'ON ALL PAGES OF THE CURRENT QUERY!\n\n' +
'*** ' + t + ' ***\n\n*** ' + n + ' Record(s) will be affected ***\n\n' +
'Please enter one tag (20 char. max., no spaces, no commas -- ' +
'or leave empty to cancel:',
answer
);
if (typeof answer === 'object') answer = '';
if (answer.indexOf(' ') > 0 || answer.indexOf(',') > 0) {
alert('Please no spaces or commas!');
} else if (answer.length > 20) {
alert('Please no tags longer than 20 char.!');
} else {
notok = 0;
}
}
if (answer != '') {
f.data.value = answer;
f.submit();
}
} else if (
v == 'delall' || v == 'smi1all' || v == 'spl1all' || v == 's1all' ||
v == 's5all' || v == 's98all' || v == 's99all' || v == 'todayall' ||
v == 'delsentall' || v == 'capall' || v == 'lowerall'
) {
var answer = confirm(
'THIS IS AN ACTION ON ALL RECORDS\nON ALL PAGES OF THE CURRENT QUERY!\n\n'+
'*** ' + t + ' ***\n\n*** ' + n + ' Record(s) will be affected ***\n\n' +
'ARE YOU SURE?'
);
if (answer) {
f.submit();
}
} else {
f.submit();
}
}
sel.value = '';
}
}
/**
* Check if cookies are enabled by setting a cookie.
*
* @returns {boolean} true if cookies are enabled, false otherwise
*/
function areCookiesEnabled () {
setCookie('test', 'none', '', '/', '', '');
if (getCookie('test')) {
cookie_set = true;
deleteCookie('test', '/', '');
} else {
cookie_set = false;
}
return cookie_set;
}
/**
* Set the current language.
*
* @param {string} ctl Current language name
* @param {string} url
* @returns {void}
*/
function setLang (ctl, url) {
location.href = 'inc/save_setting_redirect.php?k=currentlanguage&v=' +
ctl.options[ctl.selectedIndex].value +
'&u=' + url;
}
/**
* Reset current language to default.
*
* @param {string} url
* @returns {void}
*/
function resetAll (url) {
location.href = 'inc/save_setting_redirect.php?k=currentlanguage&v=&u=' + url;
}
/**
* Get a specific cookie by its name.
*
* @param {string} check_name Cookie name
* @returns {string|null} Value of the cookie if found, null otherwise
*
* @since 2.6.0-fork Use decodeURIComponent instead of deprecated unescape
*/
function getCookie (check_name) {
const a_all_cookies = document.cookie.split(';');
let a_temp_cookie = '';
let cookie_name = '';
let cookie_value = '';
let b_cookie_found = false; // set boolean t/f default f
let i = '';
for (i = 0; i < a_all_cookies.length; i++) {
a_temp_cookie = a_all_cookies[i].split('=');
cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');
if (cookie_name == check_name) {
b_cookie_found = true;
if (a_temp_cookie.length > 1) {
cookie_value = decodeURIComponent(
a_temp_cookie[1].replace(/^\s+|\s+$/g, '')
);
}
return cookie_value;
}
a_temp_cookie = null;
cookie_name = '';
}
if (!b_cookie_found) {
return null;
}
}
/**
* Set a new cookie.
*
* @param {string} name Name of the cookie
* @param {string} value Cookie value
* @param {number} expires Number of DAYS before the cookie expires.
* @param {string} path Cookie path
* @param {string} domain Cookie domain
* @param {boolean} secure If it should only be sent through secure connection
* @returns {void}
*
* @since 2.6.0-fork Use encodeURIComponent instead of deprecated escape
*/
function setCookie (name, value, expires, path, domain, secure) {
const today = new Date();
today.setTime(today.getTime());
if (expires) {
expires = expires * 1000 * 60 * 60 * 24;
}
const expires_date = new Date(today.getTime() + (expires));
document.cookie = name + '=' + encodeURIComponent(value) +
(expires ? ';expires=' + expires_date.toGMTString() : '') +
(path ? ';path=' + path : '') +
(domain ? ';domain=' + domain : '') +
(secure ? ';secure' : '');
}
/**
* Delete a cookie.
*
* @param {string} name Cookie name
* @param {string} path Cookie path
* @param {string} domain Cookie domain
* @returns {void}
*/
function deleteCookie (name, path, domain) {
if (getCookie(name)) {
document.cookie = name + '=' +
(path ? ';path=' + path : '') +
(domain ? ';domain=' + domain : '') +
';expires=Thu, 01-Jan-1970 00:00:01 GMT';
}
}
/**
* Prepare a window to make all words from a text well-known
*
* @param {string} t Text ID
*/
function iknowall(t) {
const answer = confirm('Are you sure?');
if (answer) {
showRightFrames('all_words_wellknown.php?text=' + t);
}
}
/**
* Check is the table prefix is a valid alphanumeric character.
* Create an alert if not.
*
* @param {string} p Table prefix
* @returns {boolean} true is the prefix is valid
*/
function check_table_prefix (p) {
const re = /^[_a-zA-Z0-9]*$/;
const r = p.length <= 20 && p.length > 0 && p.match(re);
if (!r) {
alert(
'Table Set Name (= Table Prefix) must'
+ '\ncontain 1 to 20 characters (only 0-9, a-z, A-Z and _).'
+ '\nPlease correct your input.'
);
}
return r;
}