diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index f79bfa8c..629d6920 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -103,6 +103,9 @@ "fren_Cambridge": { "message": "Cambridge FR->EN Dictionary" }, "fren_Collins": { "message": "Collins FR->EN Dictionary" }, "rucn_Qianyi": { "message": "Qianyi RU->CN Dictionary" }, + "enes_Cambridge": { + "message": "English -> Spanish | Cambridge" + }, "labelAlignment": { "message": "initial" } } diff --git a/src/bg/js/options.js b/src/bg/js/options.js index d2c14c9f..ffdd9860 100644 --- a/src/bg/js/options.js +++ b/src/bg/js/options.js @@ -86,6 +86,7 @@ function populateSysScriptsList(dictLibrary) { let systemscripts = [ 'builtin_encn_Collins', 'general_Makenotes',//default & builtin script 'cncn_Zdic', //cn-cn dictionary + 'enes_Cambridge', 'encn_Collins', 'encn_Cambridge', 'encn_Cambridge_tc', 'encn_Oxford', 'encn_Youdao', 'encn_Baicizhan', //en-cn dictionaries 'enen_Collins', 'enen_LDOCE6MDX', 'enen_UrbanDict', //en-en dictionaries 'enfr_Cambridge', 'enfr_Collins', //en-fr dictionaries diff --git a/src/dict/enes_Cambridge.js b/src/dict/enes_Cambridge.js new file mode 100644 index 00000000..bd011acd --- /dev/null +++ b/src/dict/enes_Cambridge.js @@ -0,0 +1,142 @@ +/* global api */ +class enes_Cambridge { + constructor(options) { + this.options = options; + this.maxexample = 2; + this.word = ''; + } + + async displayName() { + let locale = await api.locale(); + if (locale.indexOf('EN') != -1) return 'English -> Spanish | Cambridge'; + return 'Inglés -> Español | Cambridge'; + } + + setOptions(options) { + this.options = options; + this.maxexample = options.maxexample; + } + + async findTerm(word) { + this.word = word; + let promises = [this.findCambridge(word)]; + let results = await Promise.all(promises); + return [].concat(...results).filter(x => x); + } + + 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-spanish/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 ? `${pos}` : ''; + audios[0] = entry.querySelector(".uk.dloc source"); + audios[0] = audios[0] ? 'https://dictionary.cambridge.org' + audios[0].getAttribute('src') : ''; + //audios[0] = audios[0].replace('https', 'http'); + audios[1] = entry.querySelector(".us.dloc source"); + audios[1] = audios[1] ? 'https://dictionary.cambridge.org' + audios[1].getAttribute('src') : ''; + //audios[1] = audios[1].replace('https', 'http'); + + 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 ? `
${phrasehead}
` : ''; + 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 = `${eng_tran.replace(RegExp(expression, 'gi'),`${expression}`)}`; + chn_tran = `${chn_tran}`; + let tran = `${chn_tran}`; + definition += phrasehead ? `${phrasehead}${tran}` : `${pos}${tran}`; + + // make exmaple segement + let examps = defblock.querySelectorAll('.def-body .examp') || []; + if (examps.length > 0 && this.maxexample > 0) { + definition += ''; + } + definition && definitions.push(definition); + } + } + } + let css = this.renderCSS(); + notes.push({ + css, + expression, + reading, + definitions, + audios + }); + } + return notes; + } + + renderCSS() { + let css = ` + `; + return css; + } +} \ No newline at end of file