From 10214b54bbc8196683c86c6337ce79e121c3780f Mon Sep 17 00:00:00 2001 From: Georgebuk <george.boulton@hotmail.co.uk> Date: Wed, 26 Jul 2023 13:06:57 +0900 Subject: [PATCH 1/2] Added English to Japanese Cambridge dictionary --- src/dict/enjp_Cambridge.js | 140 +++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 src/dict/enjp_Cambridge.js diff --git a/src/dict/enjp_Cambridge.js b/src/dict/enjp_Cambridge.js new file mode 100644 index 0000000..cc335b0 --- /dev/null +++ b/src/dict/enjp_Cambridge.js @@ -0,0 +1,140 @@ +/* global api */ +class enjp_Cambridge { + constructor(options) { + this.options = options; + this.maxexample = 2; + this.word = ''; + } + + async displayName() { + let locale = await api.locale(); + if (locale.indexOf('CN') != -1) return '剑桥英日词典'; + if (locale.indexOf('TW') != -1) return '剑桥英日词典'; + return 'Cambridge EN->JP Dictionary'; + } + + setOptions(options) { + this.options = options; + this.maxexample = options.maxexample; + } + + async findTerm(word) { + this.word = word; + return this.findCambridge(word); + } + + async findCambridge(word) { + let notes = []; + if (!word) return notes; // return empty notes + + function T(node) { + if (!node) + return ''; + else + return node.innerText.trim(); + } + + let base = 'https://dictionary.cambridge.org/search/english-japanese/direct/?q='; + let url = base + encodeURIComponent(word); + let doc = ''; + try { + let data = await api.fetch(url); + let parser = new DOMParser(); + doc = parser.parseFromString(data, 'text/html'); + } catch (err) { + return []; + } + + let entries = doc.querySelectorAll('.pr .entry-body__el') || []; + for (const entry of entries) { + let definitions = []; + let audios = []; + + let expression = T(entry.querySelector('.headword')); + let reading = ''; + let readings = entry.querySelectorAll('.pron .ipa'); + if (readings) { + let reading_uk = T(readings[0]); + let reading_us = T(readings[1]); + reading = (reading_uk || reading_us) ? `UK[${reading_uk}] US[${reading_us}] ` : ''; + } + let pos = T(entry.querySelector('.posgram')); + pos = pos ? `<span class='pos'>${pos}</span>` : ''; + audios[0] = entry.querySelector(".uk.dloc source"); + audios[0] = audios[0] ? 'https://dictionary.cambridge.org' + audios[0].getAttribute('src') : ''; + + audios[1] = entry.querySelector(".us.dloc source"); + audios[1] = audios[1] ? 'https://dictionary.cambridge.org' + audios[1].getAttribute('src') : ''; + + let sensbodys = entry.querySelectorAll('.sense-body') || []; + for (const sensbody of sensbodys) { + let sensblocks = sensbody.childNodes || []; + for (const sensblock of sensblocks) { + let phrasehead = ''; + let defblocks = []; + if (sensblock.classList && sensblock.classList.contains('phrase-block')) { + phrasehead = T(sensblock.querySelector('.phrase-title')); + phrasehead = phrasehead ? `<div class="phrasehead">${phrasehead}</div>` : ''; + defblocks = sensblock.querySelectorAll('.def-block') || []; + } + if (sensblock.classList && sensblock.classList.contains('def-block')) { + defblocks = [sensblock]; + } + if (defblocks.length <= 0) continue; + + // make definition segement + for (const defblock of defblocks) { + let eng_tran = T(defblock.querySelector('.ddef_h .def')); + let chn_tran = T(defblock.querySelector('.def-body .trans')); + if (!eng_tran) continue; + let definition = ''; + eng_tran = `<span class='eng_tran'>${eng_tran.replace(RegExp(expression, 'gi'),`<b>${expression}</b>`)}</span>`; + chn_tran = `<span class='chn_tran'>${chn_tran}</span>`; + let tran = `<span class='tran'>${eng_tran}${chn_tran}</span>`; + definition += phrasehead ? `${phrasehead}${tran}` : `${pos}${tran}`; + + // make exmaple segement + let examps = defblock.querySelectorAll('.def-body .examp') || []; + if (examps.length > 0 && this.maxexample > 0) { + definition += '<ul class="sents">'; + for (const [index, examp] of examps.entries()) { + if (index > this.maxexample - 1) break; // to control only 2 example sentence. + let eng_examp = T(examp.querySelector('.eg')); + let chn_examp = T(examp.querySelector('.trans')); + definition += `<li class='sent'><span class='eng_sent'>${eng_examp.replace(RegExp(expression, 'gi'),`<b>${expression}</b>`)}</span><span class='chn_sent'>${chn_examp}</span></li>`; + } + definition += '</ul>'; + } + definition && definitions.push(definition); + } + } + } + let css = this.renderCSS(); + notes.push({ + css, + expression, + reading, + definitions, + audios + }); + } + return notes; + } + + renderCSS() { + let css = ` + <style> + div.phrasehead{margin: 2px 0;font-weight: bold;} + span.star {color: #FFBB00;} + span.pos {text-transform:lowercase; font-size:0.9em; margin-right:5px; padding:2px 4px; color:white; background-color:#0d47a1; border-radius:3px;} + span.tran {margin:0; padding:0;} + span.eng_tran {margin-right:3px; padding:0;} + span.chn_tran {color:#0d47a1;} + ul.sents {font-size:0.8em; list-style:square inside; margin:3px 0;padding:5px;background:rgba(13,71,161,0.1); border-radius:5px;} + li.sent {margin:0; padding:0;} + span.eng_sent {margin-right:5px;} + span.chn_sent {color:#0d47a1;} + </style>`; + return css; + } +} \ No newline at end of file From a3e8a612735d57f4f8f0ad78e3709c20afe0183f Mon Sep 17 00:00:00 2001 From: Georgebuk <george.boulton@hotmail.co.uk> Date: Tue, 1 Aug 2023 10:03:14 +0900 Subject: [PATCH 2/2] Added dictionary to System Scripts list --- src/_locales/en/messages.json | 3 ++- src/_locales/zh_CN/messages.json | 1 + src/_locales/zh_TW/messages.json | 1 + src/bg/js/options.js | 2 +- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index c10f763..355a626 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -93,6 +93,7 @@ "enen_UrbanDict": { "message": "Urban EN->EN Dictionary" }, "enfr_Cambridge": { "message": "Cambridge EN->FR Dictionary" }, "enfr_Collins": { "message": "Collins EN->FR Dictionary" }, + "enjp_Cambridge": { "message": "Cambridge EN->JP Dictionary" }, "esen_Spanishdict": { "message": "Spanishdict.com ES->CN Dictionary" }, "decn_Eudict": { "message": "Eudict DE->CN Dictionary" }, "escn_Eudict": { "message": "Eudict ES->CN Dictionary" }, @@ -101,6 +102,6 @@ "fren_Cambridge": { "message": "Cambridge FR->EN Dictionary" }, "fren_Collins": { "message": "Collins FR->EN Dictionary" }, "rucn_Qianyi": { "message": "Qianyi RU->CN Dictionary" }, - + "labelAlignment": { "message": "initial" } } diff --git a/src/_locales/zh_CN/messages.json b/src/_locales/zh_CN/messages.json index e6eee91..cf82f33 100644 --- a/src/_locales/zh_CN/messages.json +++ b/src/_locales/zh_CN/messages.json @@ -91,6 +91,7 @@ "enen_UrbanDict": { "message": "Urban英英俚语词典" }, "enfr_Cambridge": { "message": "剑桥英法词典" }, "enfr_Collins": { "message": "柯林斯英法词典" }, + "enjp_Cambridge": { "message": "剑桥英日词典" }, "esen_Spanishdict": { "message": "Spanishdict.com西英词典" }, "decn_Eudict": { "message": "欧路德语助手" }, "escn_Eudict": { "message": "欧路西语助手" }, diff --git a/src/_locales/zh_TW/messages.json b/src/_locales/zh_TW/messages.json index 7ef4454..01bcf17 100644 --- a/src/_locales/zh_TW/messages.json +++ b/src/_locales/zh_TW/messages.json @@ -91,6 +91,7 @@ "enen_UrbanDict": { "message": "Urban英英俚語詞典" }, "enfr_Cambridge": { "message": "劍橋英法詞典" }, "enfr_Collins": { "message": "柯林斯英法詞典" }, + "enjp_Cambridge": { "message": "剑桥英日词典" }, "esen_Spanishdict": { "message": "Spanishdict.com西英詞典" }, "decn_Eudict": { "message": "歐路德語助手" }, "escn_Eudict": { "message": "歐路西語助手" }, diff --git a/src/bg/js/options.js b/src/bg/js/options.js index a2b21c3..fac90c7 100644 --- a/src/bg/js/options.js +++ b/src/bg/js/options.js @@ -72,7 +72,7 @@ function populateSysScriptsList(dictLibrary) { 'enen_Collins', 'enen_LDOCE6MDX', 'enen_UrbanDict', //en-en dictionaries 'enfr_Cambridge', 'enfr_Collins', //en-fr dictionaries 'fren_Cambridge', 'fren_Collins', //fr-cn dictionaries - 'esen_Spanishdict', 'decn_Eudict', 'escn_Eudict', 'frcn_Eudict', 'frcn_Youdao', 'rucn_Qianyi' //msci dictionaries + 'esen_Spanishdict', 'decn_Eudict', 'escn_Eudict', 'frcn_Eudict', 'frcn_Youdao', 'rucn_Qianyi', 'enjp_Cambridge' //msci dictionaries ]; $('#scriptslistbody').empty(); systemscripts.forEach(script => {