/* ********用户自定义配置区开始******** */
var oaldpeCfg = {
// 【配置项1:是否显示中文翻译】(点击"词性导航"白色块可显示/隐藏中文翻译)
// 选项(默认为false):false=不显示,true=显示
showTranslation: false,
// 【配置项2:是否显示词性导航栏】
// 选项(默认为true):false=不显示,true=显示
showNavbar: true,
// 【配置项15:是否选中词性导航all:是否选中词性导航all】
// 选项(默认为true):false=否,true=是
selectNavbarAll: true,
// 【配置项17:是否启用英文点译功能】(单句显示/隐藏中文)
// 选项(默认为true):false=否,true=是
touchToTranslate: true,
// 【配置项3:是否显示音节划分】(点击单词可切换音节划分)
// 选项(默认为true):false=不显示,true=显示
showSyllable: true,
// 【配置项4:是否简化词性】(如verb简化为v.)
// 选项(默认为true):false=不简化,true=简化
simplifyPos: true,
// 【配置项5:是否简化语法】(如[transitive]简化为[t])
// 选项(默认为true):false=不简化,true=简化
simplifyGrammar: true,
// 【配置项6:是否简化非例句中的something、somebody为sth、sb】
// 选项(默认为true):false=不简化,true=简化
simplifySthSb: true,
// 【配置项7:是否展开折叠块1】(绿虚线折叠区)
// 选项(默认为true):false=不展开,true=展开
unfoldBox1: true,
// 【配置项8:是否展开折叠块2】(浅红色折叠区)
// 选项(默认为false):false=不展开,true=展开
unfoldBox2: false,
// 【配置项9:是否展开折叠块3】(Idiom、Phrasal verbs)
// 选项(默认为false):false=不展开,true=展开
unfoldBox3: false,
// 【配置项10:是否展开义项】
// 选项(默认为true):false=否,true=是
unfoldSense: true,
// 【配置项11:点击Idioms、Phrasal verbs跳转后,自动展开内容】
// 选项(默认为true):false=不展开,true=展开
jumpsBox3Unfold: true,
// 【配置项12:点击小火箭返回后,自动折叠内容】
// 选项(默认为true):false=不折叠,true=折叠
leavesBox3Fold: true,
// 【配置项13:给粗体固定句式添加荧光笔下划线】
// 选项(默认为true):false=不添加,true=添加
phrasesAddUnderline: true,
// 【配置项14:是否使用普通样式的义项序号】
// 选项(默认为false):false=否,true=是
normalSenseNumber: false,
// 【配置项16:是否全局使用普通英文字体】
// 选项(默认为false):false=否,true=是
normalEnglishFont: false,
// 【配置项18:官方例句发音选项】(如果为0或1,则可删除oald.3.mdd文件)
// 选项(默认为2):0-不启用官方例句发音,1-启用官方在线例句发音,2-启用官方离线例句发音.ogg 3-启用官方离线例句发音.mp3(需要去网盘“文件替换”文件夹里下载oaldpe.3.mdd替换掉原来的文件)
// (电脑欧路、IOS等不支持选项2,可填选项3)
officialExPronOpt: 3,
// 【配置项19:无官方例句发音时,是否启用在线TTS发音】(需要高版本浏览器内核。发音图标为灰色。Mdict和电脑欧路暂不支持。)
// 选项(默认为true):false=否,true=是
enableOnlineTTS: true,
// 【配置项20:是否在手机欧路词典里使用更大的屏宽】
// 选项(默认为true):false=否,true=是
widerScreenEudic: true,
// 【配置项21:是否使用台湾繁体中文翻译】
// 选项(默认为false):false=否,true=是
showTraditional: false,
// 【配置项22:离线图片翻译选项】(当【配置项27:是否使用在线图片】设置为true时,图片翻译无效)
// 选项(默认为1):0-不使用翻译,1-简体中文翻译,2-港版繁体翻译
imgTranslationOpt: 1,
// 【配置项23:使用预设主题】(此设置可能会覆盖某些配置项)
// 选项(默认为0):0-默认主题(不做任何修改),1-官网主题,2-欢迎大家分享自己的主题,后续更新可以加上。
applyPresetTheme: 0,
// 【配置项24:TTS英音发音配置】
// 选项(默认为英音男1):英音男1,英音男2,英音女1,英音女2,英音女3
britishTTS: "英音男1",
// 【配置项25:TTS美音发音配置】
// 选项(默认为美音女1):美音男1,美音男2,美音男3,美音男4,美音男5,美音女1,美音女2,美音女3,美音女4
americanTTS: "美音女1",
// 【配置项26:是否使用在线单词发音】(如果为true,则可删除oaldpe.1.mdd)
// 选项(默认为false):true=是,false=否
onlineWordPron: false,
// 【配置项27:是否使用在线图片】(如果为true,则可删除oaldpe.2.mdd。注:在线图片无中文翻译)
// 选项(默认为false):true=是,false=否
onlineImage: false,
// 【配置项28:是否隐藏手机欧路自带的hr标签】
// 选项(默认为true):true=是,false=否
hideEudicAPPHr: true,
// 【配置项29:是否在导航栏每个选项首尾加宽留白】(方便双击或单击时不会点到文字而触发查词功能)
// 选项(默认为true):true=是,false=否
NavbarMargin: true,
// 【配置项30:自定义折叠块2开关】(浅红色折叠区)
// 选项(默认都为true):false=不显示,true=显示
box2ShowSwitch: {
"verbforms": true, // 动词形式
"wordorigin": true, // 词源
"colloc": true, // 词语搭配
"snippet": true, // 牛津搭配词典
"wordfinder": true, // 联想词
"extra_examples": true, // 更多例句
"cult": true, // 文化
"synonyms": true, // 同义词辨析
"which_word": true, // 词语辨析
"homophone": true, // 同音词
"more_about": true, // 词语辨析
"mlt": true, // 同类词语学习
"wordfamily": true, // 词族
"grammar": true, // 语法说明
"express": true, // 情景表达
"langbank": true, // 用语库
"vocab": true, // 词汇扩充
"british_american": true, // 英式 / 美式
"more_about": true, // 补充说明
},
// 【配置项31:自定义折叠块3开关】(Idioms、Phrasal verbs)
// 选项(默认都为true):false=不显示,true=显示
box3ShowSwitch: {
"idioms": true, // 习语
"phrasal_verb_links": true, // 短语动词
},
// 【配置项32:其他显示开关】
// 选项(默认都为true):false=不显示,true=显示
othersShowSwitch: {
"h2.shcut": true, // 整个box1标题(包含英文和翻译)
".box_title unboxx": true, // box2标题翻译(浅红色折叠区)
"h2.shcut shcut": true, // box1标题翻译(绿虚线折叠区)
".symbols": true, // 钥匙图标
".phonetics": true, // 单词发音
".sense .def": true, // 义项英文
".examples": true, // 例句
".grammar": true, // 语法,如[transitive]或[t]
".cf": true, // 固定搭配,如take sth with you
".topic-g": true, // Topics
".use": true, // 用法,如(not used in the progressive tenses 不用于进行时)
".xrefs[xt='see']": true, // see also
".xrefs[xt='cp']": true, // 对比
".xrefs[xt='nsyn'], .oaldpe .xrefs[xt='syn']": true, // 同义词
".xrefs[xt='opp']": true, // 反义词
".labels": true, // 标签,如(informal非正式用语)
".pos": true, // 词性,如verb或v.
".dis-g": true, // 主要用于,如(of machines, etc.机器等)(of verbs, nouns, etc.动词、名词等)
".variants": true, // 变体,如(also break time)
".un[un=help]": true, // 帮助
".inflections": true, // 词形变化,如(plural As, A's, a's)
"div#ox-enlarge": true, // 图片
},
// 【配置项33:自定义CSS样式】
// 选项(默认都为空):不为空=使用自定义,为空=不使用自定义
// 示例1:{"color": "red"}
// 示例2:{"color": "#BE002F", "font-size": "20px"}
// 示例3:{"font-weight": "bold", "font-style": "italic"}
// 示例4:{"background-color": "green", "font-style": "normal"}
customizeCSS: {
".examples li .x": {}, // 例句英文
".examples li .x chn": {}, // 例句中文
".def": {}, // 义项的英文释义
"deft > chn": {}, // 权威中文释义
"h1.headword": {}, // 词头
".oaldpe-nav": {}, // 导航栏
".oaldpe-nav span": {}, // 导航栏选项
".pos": {}, // 词性,如verb或v.
".cf": {}, // 固定搭配,如take sth with you
".grammar": {}, // 语法,如[transitive]或[t]
"div.li_sense_before": {}, // 义项数字
},
// 【配置项34:是否展开折叠块2的子标题栏下的内容】(浅红色折叠区)
// 选项(默认为true):false=不展开,true=展开
unfoldBox2Subtitle: true,
// 【配置项35:例句前的固定搭配使用代字号】(如把take sth with you替换为~ sth with you)
// 选项(默认为true):false=不使用,true=使用
usePlaceholder: true,
};
/* ********用户自定义配置区结束******** */
(function () {
var _userAgent = navigator.userAgent.toLowerCase();
if ((/windows\snt/.test(_userAgent)
&& /chrome|firefox/.test(_userAgent)) || jQuery('.gdarticle').css('-webkit-column-gap') == '1px') {
console.log('Windows Chrome/firefox detected.');
if (/windows\snt/.test(_userAgent) && /chrome|firefox/.test(_userAgent))
$("a.speaker").click(function () {
fSound = $(this).attr('href');
fSound = fSound.replace('sound://', '');
(new Audio(fSound)).play();
});
return jQuery;
} else {
return jQuery.noConflict(true)
}
})()
(function ($) {
// avoiding repeated loading
if ($(".oaldpe #is-oaldpe-loaded").length) {
return;
} else {
$('
').appendTo('.oaldpe');
}
// variable declaration area
const OALDPE_NAVBAR_CLASS = "oaldpe-nav";
const OALDPE_NAVBAR_SELECTOR = "." + OALDPE_NAVBAR_CLASS;
const OALDPE_PREFIX_FULL_IMAGE = "https://www.oxfordlearnersdictionaries.com/media/english/fullsize/";
const OALDPE_PREFIX_THUMB_IMAGE = "https://www.oxfordlearnersdictionaries.com/media/english/thumb/";
const OALDPE_PREFIX_WORD_UK = "https://www.oxfordlearnersdictionaries.com/media/english/uk_pron/";
const OALDPE_PREFIX_WORD_US = "https://www.oxfordlearnersdictionaries.com/media/english/us_pron/";
const OALDPE_PREFIX_EXAMPLE = "https://oxford-x-file.oss-cn-hangzhou.aliyuncs.com/audio/xgs/xgs_audio/";
const OALDPE_POS = {
"noun": "n.",
"adjective": "adj.",
"adverb": "adv.",
"abbreviation": "abbr.",
"adverb, adjective": "adv., adj.",
"verb": "v.",
"phrasal verb": "phrasal v.",
"exclamation": "interj.",
"idiom": "idiom",
"conjunction": "conj.",
"preposition": "prep.",
"modal verb": "modal v.",
"combining form": "combining form",
"prefix": "prefix",
"linking verb": "linking v.",
"suffix": "suffix",
"number": "num.",
"pronoun": "pron.",
"ordinal number": "ordinal num.",
"determiner": "det.",
"auxiliary verb": "aux. v.",
"indefinite article": "indefinite a.",
"definite article": "definite a.",
"infinitive marker": "infinitive marker",
"symbol": "symbol",
"adjective, adverb": "adj., adv.",
"adverb, preposition": "adv., prep.",
"noun, adjective": "n., adj.",
"short form": "short form",
"noun, exclamation": "n., interj.",
"exclamation, noun": "interj., n.",
"determiner, pronoun": "det., pron.",
"preposition, adverb": "prep., adv.",
"adjective, exclamation": "adj., interj.",
"preposition, conjunction, adverb": "prep., conj., adv.",
"adjective, adverb, exclamation": "adj., adv., interj.",
"adjective, noun": "adj., n.",
"adverb, exclamation": "adv., interj.",
"noun, determiner": "n., det.",
"determiner, pronoun, adverb": "det., pron., adv.",
"conjunction, preposition": "conj., prep.",
"adverb, pronoun, conjunction": "adv., pron., conj.",
"determiner, adjective": "det., adj.",
"determiner, ordinal number": "det., ordinal num.",
"noun, abbreviation": "n., abbr.",
"exclamation, adjective": "interj., adj.",
"conjunction, adverb": "conj., adv.",
"adjective, pronoun": "adj., pron.",
"number, determiner": "num., det.",
"noun, verb": "n., v.",
"pronoun, determiner": "pron., det.",
"preposition, conjunction": "prep., conj.",
"exclamation, adverb, pronoun": "interj., adv., pron.",
"adverb, conjunction": "adv., conj.",
"adverb, noun": "adv., n.",
}
const OALDPE_GRAMMAR = {
"[uncountable]": "[U]",
"[only before noun]": "[only bf N]",
"[singular]": "[sing]",
"[countable]": "[C]",
"[countable, uncountable]": "[C, U]",
"[after noun]": "[aft N]",
"[not before noun]": "[not bf N]",
"[usually before noun]": "[usu bf N]",
"[usually singular]": "[usu sing]",
"[uncountable, countable]": "[U, C]",
"[intransitive, transitive]": "[I, T]",
"[usually passive]": "[usu psv]",
"[plural]": "[pl]",
"[transitive]": "[T]",
"[uncountable, singular]": "[U, sing]",
"[intransitive]": "[I]",
"[often passive]": "[oft psv]",
"[not usually before noun]": "[not usu bf N]",
"[singular, uncountable]": "[sing, U]",
"[uncountable, plural]": "[U, pl]",
"[usually plural]": "[usu pl]",
"[countable, usually plural]": "[C, usu pl]",
"[uncountable, countable, usually singular]": "[U, C, usu sing]",
"[transitive, intransitive]": "[T, I]",
"[intransitive, transitive, often passive]": "[I, T, oft psv]",
"[transitive, often passive]": "[T, oft psv]",
"[countable, usually singular]": "[C, usu sing]",
"[countable + singular or plural verb]": "[C + sing or pl V]",
"[uncountable + singular or plural verb]": "[U + sing or pl V]",
"[transitive, usually passive]": "[T, usu psv]",
"[transitive, often passive, intransitive]": "[T, oft psv, I]",
"[no passive]": "[no psv]",
"[countable, usually singular, uncountable]": "[C, usu sing, U]",
"[countable, usually plural, uncountable]": "[C, usu pl, U]",
"[plural, singular or plural verb]": "[pl, sing or pl V]",
"[singular + singular or plural verb]": "[sing + sing or pl V]",
"[countable, singular, uncountable]": "[C, sing, U]",
"[intransitive, transitive, no passive]": "[I, T, no psv]",
"[transitive, no passive]": "[T, no psv]",
"[uncountable, countable, usually plural]": "[U, C, usu pl]",
"[plural, uncountable]": "[pl, U]",
"[countable + singular or plural verb, uncountable]": "[C + sing or pl V, U]",
"[transitive, intransitive, often passive]": "[T, I, oft psv]",
"[intransitive, transitive, usually passive]": "[I, T, usu psv]",
"[transitive, usually passive, intransitive]": "[T, usu psv, I]",
"[countable, plural]": "[C, pl]",
"[singular or plural verb]": "[sing or pl V]",
"[countable, uncountable + singular or plural verb]": "[C, U + sing or pl V]",
"[uncountable + singular or plural verb, countable]": "[U + sing or pl V, C]",
"[countable, singular]": "[C, sing]",
"[uncountable, countable, singular]": "[U, C, sing]",
"[countable, singular + singular or plural verb]": "[C, sing + sing or pl V]",
"[singular + singular or plural verb, uncountable]": "[sing + sing or pl V, U]",
"[transitive, no passive, intransitive]": "[T, no psv, I]",
"[usually singular, uncountable]": "[usu sing, U]",
"[transitive, intransitive, usually passive]": "[T, I, usu psv]",
}
var globalAudio = new Audio();
var conciseMeaning = !oaldpeCfg.unfoldSense;
// main
initialize();
fnSimplifyPos(oaldpeCfg.simplifyPos);
fnShowNavbar(oaldpeCfg.showNavbar);
fnShowTraditional(oaldpeCfg.showTraditional);
fnUnfoldBox1(oaldpeCfg.unfoldBox1);
fnUnfoldBox2(oaldpeCfg.unfoldBox2);
fnUnfoldBox3(oaldpeCfg.unfoldBox3);
fnUnfoldSense(oaldpeCfg.unfoldSense);
fnBox2ShowSwitch(oaldpeCfg.box2ShowSwitch);
fnSimplifySthSb(oaldpeCfg.simplifySthSb);
fnPhrasesAddUnderline(oaldpeCfg.phrasesAddUnderline);
fnNormalSenseNumber(oaldpeCfg.normalSenseNumber);
fnHideEudicAPPHr(oaldpeCfg.hideEudicAPPHr);
fnSelectNavbarAll(oaldpeCfg.selectNavbarAll);
fnOnlineImage(oaldpeCfg.onlineImage);
fnSimplifyGrammar(oaldpeCfg.simplifyGrammar);
fnNormalEnglishFont(oaldpeCfg.normalEnglishFont);
fnShowSyllable(oaldpeCfg.showSyllable);
fnShowTranslation(oaldpeCfg.showTranslation);
fnBox3ShowSwitch(oaldpeCfg.box3ShowSwitch);
fnEnableOnlineTTS(oaldpeCfg.enableOnlineTTS);
fnOthersShowSwitch(oaldpeCfg.othersShowSwitch);
addRocketAndReturn();
fnWiderScreenEudic(oaldpeCfg.widerScreenEudic);
scrollingAndJumping();
fnImgTranslationOpt(oaldpeCfg.imgTranslationOpt);
imageZoomEvent();
fnOfficialExPronOpt(oaldpeCfg.officialExPronOpt);
fnApplyPresetTheme(oaldpeCfg.applyPresetTheme);
addBox2Toggle();
fnCustomizeCSS(oaldpeCfg.customizeCSS);
fnOnlineWordPron(oaldpeCfg.onlineWordPron);
fnUsePlaceholder(oaldpeCfg.usePlaceholder);
termNumberClickEvent();
extendTranslationAreaForExamples();
fnUnfoldBox2Subtitle(oaldpeCfg.unfoldBox2Subtitle);
fnTouchToTranslate(oaldpeCfg.touchToTranslate);
// main end
// alert(navigator.userAgent.toLowerCase());
// function declaration area
function fnUsePlaceholder(itemValue) {
itemValue && $(".oaldpe .cf").each(function() {
_$headword = $(this).parents(".senses_multiple, .sense_single").prev().find(".headword");
_headword = _$headword.text().replace("·", "");
if (_headword !== "") {
$(this).text($(this).text().replace(_headword, "~"))
console.log("ok");
} else {
console.log("no");
}
});
}
function fnUnfoldBox2Subtitle(itemValue) {
if (!itemValue)
$(".collapse > .unbox > .body > .unbox+.bullet").hide();
$(".collapse > .unbox > .body > .unbox").click(function(e) {
if ($(this).next().hasClass("bullet") && ($(e.target).is($(this)))) {
e.stopPropagation();
$(this).next().slideToggle("fast");
}
})
}
function initialize() {
$(".oaldpe").show();
// 兼容DictTango
// 实现idioms和prasal verbs的滚动跳转
// $(".oaldpe .jumplinks a.Ref").each(function() {
// var _objHref = $(this).attr("href");
// _objHref = _objHref.replace("entry://", "");
// if ($(this).attr("href") !== _objHref)
// $(this).attr("href", _objHref);
// $(".oaldpe").before(`kkkk
`);
// });
}
function extendTranslationAreaForExamples() {
if (oaldpeCfg.officialExPronOpt === 0 || oaldpeCfg.enableOnlineTTS === false) {
$('.oaldpe example-audio, .oaldpe example-audio-ai').filter(function() {
return !$(this).is(":visible");
}).prev().addClass('inlineblock');
}
}
function fnTouchToTranslate(itemValue) {
if (!itemValue)
return;
// examples
$(".oaldpe ul.examples > li").click(function(e) {
e.stopPropagation();
$(this).find("chn").each(function() {
if (!$(this).parent().is("labelx")) {
$(this).slideToggle("fast");
} else {
$(this).fadeToggle("fast");
}
})
box3RefreshHeight();
});
// ask-after: .webtop > .variants or .use
$(".oaldpe .top-container .webtop .variants, .oaldpe .top-container .webtop .use").click(function(e) {
e.stopPropagation();
$(this).find("chn").fadeToggle("fast");
})
// title of box1
$('.oaldpe h2')
.each(function() {
$(this).contents().wrap('');
})
.find("div.h2content, chn")
.click(function(e) {
if ($(e.target).is('chn')) {
e.stopPropagation();
$(e.target).fadeToggle("fast");
} else if ($(e.target).is('.h2content')) {
_$chn = $(e.target).next().find("chn");
if (_$chn.parent().is(":visible")) {
_$chn.fadeToggle("fast");
e.stopPropagation();
}
}
});
// global click event for sense
$(".oaldpe li.sense .unbox").click(function(e) {
e.stopPropagation();
});
$(".oaldpe li.sense").click(function(e) {
e.stopPropagation();
$(this).find("span.def").siblings("deft, .sensetop, .labels, .dis-g, .use, .variants").find("chn").fadeToggle("fast");
box3RefreshHeight();
});
// light red background area
$(".oaldpe span.un").click(function(e) {
e.stopPropagation();
$(this).find("chn").fadeToggle("fast");
box3RefreshHeight();
});
// box2 event
var _$unboxs = $('.oaldpe .collapse > .unbox');
_$unboxs.each(function() {
// title of box2
$(this).find(".box_title div.text_title").click(function(e) {
_$chn = $(this).siblings("unboxx").find("chn")
if (_$chn.parent().is(":visible")) {
e.stopPropagation();
_$chn.fadeToggle("fast");
box3RefreshHeight();
}
})
$(this).find(".box_title chn").click(function(e) {
e.stopPropagation();
$(this).fadeToggle("fast");
});
// Collocations 词语搭配: gospel-2(Collocations), word title
$(this).find(".body > .unbox").click(function(e) {
if (!($(e.target).is($(this)))) {
e.stopPropagation();
$(this).find("chn").fadeToggle("fast");
box3RefreshHeight();
}
});
// Collocations 词语搭配: gospel-2, 所有义项
$(this).find(".body > .bullet > li.li").click(function(e) {
if ($(this).find(".item").length === 0) {
e.stopPropagation();
$(this).find("chn").fadeToggle("fast");
box3RefreshHeight();
}
});
// Synonyms 同义词辨析:take-2(所有义项)
$(this).find(".defpara").click(function(e) {
_$chn = $(this).children("undt").find("chn")
if (_$chn.length) {
e.stopPropagation();
_$chn.fadeToggle("fast");
box3RefreshHeight();
}
});
// Synonyms 同义词辨析:take-2(p标签翻译)
$(this).find(".body > span.p, .unbox .defpara .eb_undt").click(function(e) {
e.stopPropagation();
$(this).find("chn").fadeToggle("fast");
});
// Which Word? 词语辨析:take-4(the definition)
$(this).find(".body > ul.bullet > li > .item")
.click(function(e){
e.stopPropagation();
$(this).children("undt").find("chn").fadeToggle("fast");
box3RefreshHeight();
});
});
}
function termNumberClickEvent() {
$(".oaldpe .li_sense_before, .oaldpe .idm").click(function(e) {
e.stopPropagation();
if ($(this).hasClass("li_sense_before")) {
var _$objEle = $(this).next();
} else {
var _$objEle = $(this).parents(".idm-g");
}
_isVisible = _$objEle.find(".examples, .collapse, .un, .xrefs, .topic-g, div#ox-enlarge").is(":visible");
if (_isVisible) {
_$objEle.children(".examples, .collapse, .un, .xrefs, .topic-g").slideUp("fast");
_$objEle.find("div#ox-enlarge").slideUp("fast");
} else {
_$objEle.children(".examples, .collapse, .un, .xrefs, .topic-g").slideDown("fast");
_$objEle.find("div#ox-enlarge").slideDown("fast");
}
});
}
function addBox2Toggle() {
$(".oaldpe .box_title").click(function(e) {
e.stopPropagation();
$(this).next().slideToggle("fast").parent().toggleClass("is-active");
box3RefreshHeight();
});
}
function fnApplyPresetTheme(itemValue) {
if (itemValue === 1) {
fnNormalEnglishFont(true);
fnPhrasesAddUnderline(false);
fnNormalSenseNumber(true);
fnSimplifyPos(false);
fnSimplifyGrammar(false);
$(".oaldpe ul.examples > li > .exText > .x").css("color", "black");
$(".oaldpe h1.headword").css("color", "#1A3561");
$(".oaldpe .pos").css({"font-style": "italic", "color": "#333333", "border-color": "transparent", "background-color": "transparent", "font-weight": "normal"});
$(".oaldpe div.li_sense_before").css({"font-family": "unset", "font-style": "unset"});
}
}
function fnOfficialExPronOpt(itemValue) {
if (itemValue === 0) {
$('.oaldpe example-audio').addClass('audio_hide');
return;
}
// 启用官方例句在线发音
(itemValue === 1) && $(".oaldpe example-audio a")
.each(function(){
var _thisHref = $(this).attr("href");
if (isGoldenDict())
_thisHref = _thisHref.replace(getLastSlashContent(_thisHref), "sound:/");
var newHref = OALDPE_PREFIX_EXAMPLE + _thisHref.replace("sound://", "").replace(".ogg", ".wav");
$(this).attr("href", newHref);
})
.click(function(e){
var _thisHref = $(this).attr("href");
if (_thisHref.startsWith("http") && (_thisHref.endsWith(".mp3")
|| _thisHref.endsWith(".wav") || _thisHref.endsWith(".ogg"))) {
console.log("---------- play online");
e.preventDefault();
e.stopPropagation();
!globalAudio.paused && globalAudio.pause();
globalAudio.src = _thisHref;
globalAudio.play();
}
});
// 启用官方例句离线发音
(itemValue === 2 || itemValue === 3)
&& $(".oaldpe example-audio a").click(function(e){
var _thisHref = $(this).attr("href");
if ((_thisHref.startsWith("sound://") || (_thisHref.startsWith("gdau://"))) && (_thisHref.endsWith(".mp3")
|| _thisHref.endsWith(".wav") || _thisHref.endsWith(".ogg"))) {
e.stopPropagation();
if (itemValue === 3)
_thisHref = _thisHref.replace("%23", "_").replace(".ogg", ".mp3").replace(".wav", ".mp3");
if (oaldpeCfg.enableOnlineTTS && !isEudicPC() && !isGoldenDict()) {
!globalAudio.paused && globalAudio.pause();
globalAudio.src = _thisHref.replace("sound://", "");
globalAudio.play();
e.preventDefault();
} else {
// 不启用TTS时或特殊词典,使用系统默认发音
$(this).attr("href", _thisHref);
}
}
});
}
function imageZoomEvent() {
$(".oaldpe #ox-enlarge").click(function (e) {
e.stopPropagation();
var _$fullsize = $(this).find("img.fullsize"),
_$thumb = $(this).find("img.thumb");
if (_$fullsize.css("display") === "block") {
console.log("zoom out");
_$fullsize.css("display", "none") && _$thumb.css("display", "block");
$(this).css({"width": "100px", "height": "100px", "left": "0"});
$(this).find("span.ox-enlarge-label").css({"position": "absolute", "margin": "0"});
} else {
console.log("zoom in");
_$fullsize.css("display", "block") && _$thumb.css("display", "none");
$(this).css({"width": "100%", "height": "auto", "left": "5px"});
$(this).find("span.ox-enlarge-label").css({"position": "static", "margin": "0 5px 5px 0"});
}
});
}
function getLastSlashContent(str) {
const lastSlashIndex = str.lastIndexOf('/');
if (lastSlashIndex === -1) {
return str;
}
return str.substring(0, lastSlashIndex);
}
function fnImgTranslationOpt(itemValue) {
// 图片翻译:0-不使用翻译 1-简体中文翻译 2-台湾繁体翻译
$(".oaldpe img.fullsize, .oaldpe img.thumb").each(function(){
var _newSrc = $(this).attr("src");
if (itemValue === 1) {
_newSrc = _newSrc.replace("/oa10simp/", "/oa10simp/").replace("\\oa10simp\\", "\\oa10simp\\");
} else if (itemValue === 2) {
_newSrc = _newSrc.replace("/oa10simp/", "/oa10orth/").replace("\\oa10simp\\", "\\oa10orth\\");
} else {
_newSrc = _newSrc.replace("/oa10simp/", "/oa10src/").replace("\\oa10simp\\", "\\oa10src\\");
}
$(this).attr("src", _newSrc);
});
}
function scrollingAndJumping() {
// 实现idioms和prasal verbs的滚动跳转
$(".oaldpe .jumplinks a.Ref").click(function(e) {
e.preventDefault();
var objHref = $(this).attr("href");
var heightSpace = 48;
// $(".oaldpe").before(`${objHref}
`);
// var _temp = $(objHref).length;
// $(".oaldpe").before(`${$(objHref).offset().top - heightSpace}
`);
$('html, body').animate({
scrollTop: $(objHref).offset().top - heightSpace
}, {
duration: 300,
complete: function() {
if (oaldpeCfg.jumpsBox3Unfold && $(this).is("html"))
box3Unfold(objHref);
}
});
});
}
function fnWiderScreenEudic(itemValue) {
itemValue && isEudicAPP() && $(".oaldpe").parent().css({
"margin": "5px 8px 5px 5px",
"padding": "0"
});
}
function box3Toggle($obj) {
if ($obj.hasClass('expanded')) {
$obj.animate({height: '26px'}, 180, function() {
$obj.removeClass('expanded');
});
} else {
var actualHeight = $obj.prop('scrollHeight') - 19.2;
console.log("内容高度为:"+actualHeight);
$obj.animate({height: actualHeight + "px"}, 180, function() {
$obj.addClass('expanded');
});
}
}
function box3Fold($obj) {
$obj.parent().parent().css({height: '26px'}).removeClass('expanded');
}
function addRocketAndReturn() {
var _$jumplinksA = $(".oaldpe .jumplinks a.Ref");
$(".idioms > .idioms_heading, .phrasal_verb_links > .unbox").each(function(i) {
var _titleHtml = $(this).hasClass("idioms_heading")
? ""
: ""
var _$box3Title = $(_titleHtml).click(function() {
box3Toggle($(this).parent());
});
$(this).wrap(_$box3Title);
var _$objEle = _$jumplinksA.eq(i);
var _rocketHtml = $(this).hasClass("idioms_heading")
? ''
: ''
var _$returnRocket = $(_rocketHtml).click(function(e) {
e.stopPropagation();
// $(".oaldpe").before(`${_$objEle}
`);
if (oaldpeCfg.leavesBox3Fold)
box3Fold($(this));
$('html, body').animate({ scrollTop: _$objEle.offset().top - 48 }, 300);
});
$(this).after(_$returnRocket);
})
}
function box3Unfold(objEleId) {
var actualHeight = $(objEleId).prop('scrollHeight') - 19.2;
console.log("内容高度为:" + actualHeight);
$(objEleId).animate({height: actualHeight + "px"}, 180, function() {
$(objEleId).addClass('expanded');
});
}
function fnCustomizeCSS(itemValues) {
var _keysWithFalseValue = Object.keys(itemValues)
.filter(key => Object.keys(itemValues[key]).length !== 0);
for (var i = 0; i < _keysWithFalseValue.length; i++) {
_css = itemValues[_keysWithFalseValue[i]];
_selector = ".oaldpe " + _keysWithFalseValue[i];
$(_selector).css(_css);
}
}
function fnOthersShowSwitch(itemValues) {
var _keysWithFalseValue = Object.keys(itemValues)
.filter(key => !itemValues[key]);
if (_keysWithFalseValue.length) {
var _selectors = _keysWithFalseValue.map(item => `.oaldpe ${item}`).join(' ,');
$(_selectors).hide();
}
}
function fnBox3ShowSwitch(itemValue) {
if (!itemValue["idioms"])
$(".oaldpe div.idioms[hclass='idioms']").hide();
if (!itemValue["phrasal_verb_links"])
$(".oaldpe aside.phrasal_verb_links[hclass='phrasal_verb_links']").hide();
if (!itemValue["idioms"] && !itemValue["phrasal_verb_links"]) {
$(".oaldpe span.jumplinks").hide();
} else if (!itemValue["idioms"]) {
$(".oaldpe span.jumplinks a.Ref[title='Idioms definition']").hide();
} else if (!itemValue["phrasal_verb_links"]) {
$(".oaldpe span.jumplinks a.Ref[title='Phrasal Verbs definition']").hide();
}
}
function fnBox2ShowSwitch(itemValues) {
var _keysWithFalseValue = Object.keys(itemValues).filter(key => !itemValues[key]);
if (_keysWithFalseValue.length) {
var _selectors = _keysWithFalseValue.map(item => `.oaldpe .collapse .unbox[unbox=${item}]`).join(', ');
$(_selectors).closest('div.collapse').hide();
}
}
function fnEnableOnlineTTS(itemValue) {
!itemValue && $('.oaldpe example-audio-ai').addClass('audio_hide');
itemValue && $(".oaldpe example-audio-ai a.audio_uk, .oaldpe example-audio-ai a.audio_us")
.click(function(e){
e.stopPropagation();
e.preventDefault();
globalAudio.src = ""; // 在ios上TTS要先把src设置为空,第一次播放才会发音
selectedTTS = $(this).hasClass("audio_uk") ? oaldpeCfg.britishTTS : oaldpeCfg.americanTTS;
eleExText = $(this).parent().siblings("div.exText").clone();
eleExText.find(".cf, chn").remove();
speak_text = eleExText.text().replace(/\(.*?\)/g, "");
if (speak_text.includes("/")) {
slash_word = speak_text.match(/\w+(?:\/\w+)+/)[0];
splited_word = slash_word.split("/");
list_result = [];
for (each of splited_word) {
list_result.push(speak_text.replace(slash_word, each));
}
speak_text = list_result.join("\nor ");
}
speak(speak_text);
});
}
function fnUnfoldSense(itemValue) {
!itemValue && $(".oaldpe .li_sense_before").next().find(".examples, .collapse, .un, .xrefs, .topic-g").hide();
}
function fnUnfoldBox3(itemValue) {
if (itemValue) {
$(".oaldpe .idioms").addClass('expanded');
$(".oaldpe .idioms").css("height", "auto");
$(".oaldpe .phrasal_verb_links").addClass('expanded');
$(".oaldpe .phrasal_verb_links").css("height", "auto");
}
}
function fnUnfoldBox2(itemValue) {
if (itemValue) {
$(".oaldpe .box_title").parent().addClass("is-active");
$(".oaldpe .box_title").next().show();
} else {
$(".oaldpe .box_title").parent().removeClass("is-active");
$(".oaldpe .box_title").next().hide();
}
}
function fnUnfoldBox1(itemValue) {
!itemValue && $(".oaldpe h2").siblings().hide();
$(".oaldpe h2").click(function(e) {
e.stopPropagation();
$(this).siblings().slideToggle("fast");
});
}
function fnSimplifySthSb(itemValue) {
itemValue && $('.oaldpe .cf,.x,.def').each(function() {
_newHtml = $(this).html().replace(/something/g, 'sth').replace(/somebody/g,'sb');
$(this).html(_newHtml);
});
}
function fnPhrasesAddUnderline(itemValue) {
if (itemValue) {
$('.oaldpe .cf').addClass('underline');
} else {
$('.oaldpe .cf').removeClass('underline');
}
}
function fnNormalSenseNumber(itemValue) {
!itemValue && $('.oaldpe div.li_sense_before').addClass('colored');
}
function fnShowNavbar(itemValue) {
if (!itemValue)
return;
addNavigation();
var doubleClickTimer;
$(OALDPE_NAVBAR_SELECTOR).find("span")
.on("click", function() {
if ($(this).hasClass("active")) {
clearTimeout(doubleClickTimer);
_$thisObj = $(this);
doubleClickTimer = setTimeout(function() {
console.log("navbar: chinese_toggle");
chineseToggle();
}, 250);
} else {
console.log("navbar: index is changed");
$(this).siblings().removeClass('active');
$(this).addClass('active');
showHideEntry($(this).text() === "All" ? -1 : $(this).index());
}
})
.on("dblclick", function() {
if ($(this).hasClass("active")) {
clearTimeout(doubleClickTimer);
console.log("navbar: doubleClick");
const _selectors = {
allExpand: [
".oaldpe .sense .examples",
".oaldpe .sense .collapse",
".oaldpe .sense .un",
".oaldpe .sense .xrefs",
".oaldpe .sense .topic-g",
],
h2: ".oaldpe h2",
box2: ".oaldpe .box_title",
box3: [
".oaldpe .idioms",
".oaldpe .phrasal_verb_links"
],
box3Phrasal: "",
enlargeImage: ".oaldpe div#ox-enlarge",
};
if (conciseMeaning) {
// 全部展开
$(_selectors.allExpand.join(", ")).slideDown("fast");
// 折叠块2>折叠
$(_selectors.box2).parent().addClass("is-active");
$(_selectors.box2).next().slideDown("fast");
// 折叠块3>展开
$(_selectors.box3.join(", ")).addClass('expanded').css("height", "auto");
// 图片
$(_selectors.enlargeImage).slideDown("fast");
} else {
// 全部折叠
$(_selectors.allExpand.join(", ")).slideUp("fast");
$(_selectors.h2).siblings().slideDown("fast");
// 折叠块2>折叠
$(_selectors.box2).parent().removeClass("is-active");
$(_selectors.box2).next().slideUp("fast");
// 折叠块3>折叠
$(_selectors.box3.join(", ")).css("height", "26px").removeClass('expanded');
// 图片
$(_selectors.enlargeImage).slideUp("fast");
}
conciseMeaning = !conciseMeaning;
}
});
}
function addNavigation() {
// 已添加不添加
if ($(".oaldpe-nav").length)
return;
// if ($(".oaldpe-nav").length)
// return;
var _$eles = $(".oaldpe .oald");
// 没有entry不添加
if (_$eles.length < 1)
return;
var container = $("").addClass(OALDPE_NAVBAR_CLASS);
for (var i = 0; i < _$eles.length; i++) {
var _$sp = $("");
var _$pos = _$eles.eq(i).find(".pos").eq(0);
_$pos = _$pos.length && _$pos.text();
_$pos = !_$pos ? _$eles.eq(i).find(".headword").text() : _$pos;
_$sp.text(OALDPE_POS[_$pos] ? OALDPE_POS[_$pos] : _$pos);
if (!oaldpeCfg.selectNavbarAll && i === 0) {
_$sp.addClass("active");
}
container.append(_$sp);
}
// 添加All
var _$spAll = $("All");
oaldpeCfg.selectNavbarAll && _$spAll.addClass('active');
container.append(_$spAll);
showHideEntry(oaldpeCfg.selectNavbarAll ? -1 : 0);
// 不能加在.oaldpe里
// $(".oaldpe").prepend(container);
container.insertBefore($(".oaldpe").eq(0));
if (oaldpeCfg.NavbarMargin)
$(".oaldpe-nav span").css({"padding": ".2rem 1.2rem"})
}
function showHideEntry(index) {
var _$eles = $(".oaldpe .oald");
for (var i = 0; i < _$eles.length; i++) {
if (index === i || index < 0) {
_$eles.eq(i).show();
} else {
_$eles.eq(i).hide();
}
}
}
function fnSelectNavbarAll(itemValue) {
// 词性导航滚动到最右边
if (itemValue && oaldpeCfg.showNavbar) {
var _$navbar = $(".oaldpe-nav");
// 由于手机欧路滚动失效,所以加10000个像素
_$navbar.scrollLeft(_$navbar.scrollLeft() + _$navbar.width() + 10000);
}
}
function fnShowTranslation(itemValue) {
!itemValue && $(".oaldpe chn").hide();
}
function fnShowSyllable(itemValue) {
$(".oaldpe .headword")
.click(function(e) {
e.stopPropagation();
var selection = window.getSelection();
if (selection.toString().length > 0 && this.contains(selection.anchorNode)) {
// $(this).trigger('textSelected', [selection]);
console.log("有文本被选中");
} else {
toggleSyllable($(this));
}
})
.each(function() {
if (!itemValue)
toggleSyllable($(this));
});
}
function fnNormalEnglishFont(itemValue) {
if (itemValue) {
$(".oaldpe h1.headword, h2.h, h1.headword .st ,.pos ,.symbols a span.opal_symbol,.cf,div.li_sense_before,ul.examples > li > .x ,jumplink,.jumplink ,span.unx ,.oaldpe-nav ,.examples li span.labels, .examples li div.exText span.x").addClass('normal_eglFont');
$(".oaldpe").find('.oaldpe-nav').addClass('normal_eglFont');
}
}
function fnSimplifyGrammar(itemValue) {
itemValue && $(".oaldpe .grammar").each(function() {
$(this).text(OALDPE_GRAMMAR[$(this).text()]);
});
}
function fnSimplifyPos(itemValue) {
itemValue && $(".oaldpe .pos").each(function(){
$(this).text(OALDPE_POS[$(this).text()]);
});
}
function fnOnlineImage(itemValue) {
itemValue && $(".oaldpe div#ox-enlarge img").each(function(){
$(this).attr("src", getOnlineImageUrl($(this).attr("src")));
});
}
function fnOnlineWordPron(itemValue) {
itemValue && $('.oaldpe .audio_play_button')
.each(function(){
$(this).attr("href", getOnlineWordPronUrl($(this).attr("href")));
})
.click(function(e){
e.preventDefault();
globalAudio.paused || globalAudio.pause();
globalAudio.src = $(this).attr("href");
globalAudio.play();
});
}
function fnHideEudicAPPHr(itemValue) {
itemValue && isEudicAPP() && $(".oaldpe").parent().find("hr").not('.oaldpe hr').hide();
}
function fnShowTraditional(itemValue) {
if (itemValue) {
$(".oaldpe chn.simple").remove();
} else {
$(".oaldpe chn.traditional").remove();
}
}
function box3RefreshHeight() {
$(".oaldpe .idioms.expanded").css("height", "auto");
$(".oaldpe .phrasal_verb_links.expanded").css("height", "auto");
}
function chineseToggle() {
if (oaldpeCfg.showTranslation) {
$(".oaldpe chn").fadeOut("fast");
} else {
$(".oaldpe chn").fadeIn("fast");
}
oaldpeCfg.showTranslation = !oaldpeCfg.showTranslation;
box3RefreshHeight();
}
function isEudic() {
var ua = navigator.userAgent.toLowerCase();
return ua.indexOf("eudic") > -1;
}
function isEudicAPP() {
var ua = navigator.userAgent.toLowerCase();
return (ua.indexOf("eudic") > -1) && (ua.indexOf("android") > -1 || ua.indexOf("iphone") > -1);
}
function isEudicAPPIphone() {
var ua = navigator.userAgent.toLowerCase();
return ua.indexOf("eudic") > -1 && ua.indexOf("iphone") > -1;
}
function isEudicAPPAndroid() {
var ua = navigator.userAgent.toLowerCase();
return ua.indexOf("eudic") > -1 && ua.indexOf("android") > -1;
}
function isEudicPC() {
var ua = navigator.userAgent.toLowerCase();
return ua.indexOf("eudic") > -1 && ua.indexOf("windows") > -1;
}
function isGoldenDict() {
var ua = navigator.userAgent.toLowerCase();
return ua.indexOf("goldendict") > -1;
}
function getOnlineImageUrl(src) {
var _parts = src.split('/');
var _name = _parts[_parts.length - 1];
_parts = _name.split('_');
_name = _name.replace("fullsize_", "").replace("thumb_", "").replace(".jpg", ".png");
_imgSrc = _name.substring(0, 1) + '/' + replaceWithUnderscores(_name).substring(0, 3) + '/' + replaceWithUnderscores(_name).substring(0, 5) + '/' + _name;
return (_parts[0] === "fullsize" ? OALDPE_PREFIX_FULL_IMAGE : OALDPE_PREFIX_THUMB_IMAGE) + _imgSrc;
}
function replaceWithUnderscores(str) {
return str.replace(/\..+/, match => {
return '_'.repeat(match.length);
});
}
function getOnlineWordPronUrl(src) {
var parts = src.split('/');
var name = parts[parts.length - 1];
return (name.indexOf("_gb_") > -1 ? OALDPE_PREFIX_WORD_UK : OALDPE_PREFIX_WORD_US) + name.substring(0, 1) + '/' + name.substring(0, 3) + '/' + name.substring(0, 5) + '/' + name;
}
function toggleSyllable($obj) {
if ($obj.attr("syllable")) {
$obj.text($obj.text().indexOf("·") > -1 ? $obj.text().replace(/·/g, "") : $obj.attr("syllable"));
}
}
// the end
// region tts 功能
var ttsConfig = {
"美音女1": {
locale: "en-US",
voice: "en-US-MichelleNeural",
pitch: "+0Hz",
rate: "+0%",
volume: "+0%",
},
"美音女2": {
locale: "en-US",
voice: "en-US-AriaNeural",
pitch: "+0Hz",
rate: "+20%",
volume: "+0%",
},
"美音女3": {
locale: "en-US",
voice: "en-US-AnaNeural",
pitch: "+0Hz",
rate: "+20%",
volume: "+0%",
},
"美音女4": {
locale: "en-US",
voice: "en-US-JennyNeural",
pitch: "+0Hz",
rate: "+0%",
volume: "+0%",
},
"美音男1": {
locale: "en-US",
voice: "en-US-ChristopherNeural",
pitch: "+0Hz",
rate: "+0%",
volume: "+0%",
},
"美音男2": {
locale: "en-US",
voice: "en-US-EricNeural",
pitch: "+0Hz",
rate: "+0%",
volume: "+0%",
},
"美音男3": {
locale: "en-US",
voice: "en-US-GuyNeural",
pitch: "+0Hz",
rate: "+0%",
volume: "+0%",
},
"美音男4": {
locale: "en-US",
voice: "en-US-RogerNeural",
pitch: "+0Hz",
rate: "+0%",
volume: "+0%",
},
"美音男5": {
locale: "en-US",
voice: "en-US-SteffanNeural",
pitch: "+0Hz",
rate: "+0%",
volume: "+0%",
},
"英音女1": {
locale: "en-GB",
voice: "en-GB-SoniaNeural",
pitch: "+0Hz",
rate: "+0%",
volume: "+0%",
},
"英音女2": {
locale: "en-GB",
voice: "en-GB-MaisieNeural",
pitch: "+0Hz",
rate: "+0%",
volume: "+0%",
},
"英音女3": {
locale: "en-GB",
voice: "en-GB-LibbyNeural",
pitch: "+0Hz",
rate: "+0%",
volume: "+0%",
},
"英音男1": {
locale: "en-GB",
voice: "en-GB-RyanNeural",
pitch: "+0Hz",
rate: "+0%",
volume: "+0%",
},
"英音男2": {
locale: "en-GB",
voice: "en-GB-ThomasNeural",
pitch: "+0Hz",
rate: "+0%",
volume: "+0%",
},
}
var selectedTTS = "美音女1";
function create_edge_TTS(
timeout = 10,
auto_reconnect = true) {
const TRUSTED_CLIENT_TOKEN = "6A5AA1D4EAFF4E9FB37E23D68491D6F4";
const VOICES_URL = `https://speech.platform.bing.com/consumer/speech/synthesize/readaloud/voices/list?trustedclienttoken=${TRUSTED_CLIENT_TOKEN}`;
const SYNTH_URL = `wss://speech.platform.bing.com/consumer/speech/synthesize/readaloud/edge/v1?TrustedClientToken=${TRUSTED_CLIENT_TOKEN}`;
const BINARY_DELIM = "Path:audio\r\n";
const VOICE_LANG_REGEX = /\w{2}-\w{2}/;
let _outputFormat = "audio-24khz-48kbitrate-mono-mp3";
/* 修改发音人和语言 */
let _voiceLocale = 'en-US',
_voice = 'en-US-MichelleNeural',
// 调整音色
_pitch = '+0Hz',
// 调整速度
_rate = '+20%',
// 调整音量
_volume = '+0%';
const _queue = {
message: [],
url_resolve: {},
url_reject: {},
};
let ready = false;
function _SSMLTemplate(input) {
return `
${input}
`;
}
function uuidv4() {
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16));
}
let socket = null;
create_new_ws();
function setFormat(format) {
if (format)
_outputFormat = format;
/**/
socket.send(`Content-Type:application/json; charset=utf-8\r\nPath:speech.config\r\n\r\n
{
"context": {
"synthesis": {
"audio": {
"metadataoptions": {
"sentenceBoundaryEnabled": "false",
"wordBoundaryEnabled": "false"
},
"outputFormat": "${_outputFormat}"
}
}
}
}
`);
}
async function createURL(requestId) {
let index_message = 0;
for (let message of _queue.message) {
const isbinary = message instanceof Blob;
if (!isbinary)
continue;
const data = await message.text();
//console.log(data); //does the message order change?
//console.log(await event.data.arrayBuffer());
const Id = /X-RequestId:(.*?)\r\n/gm.exec(data)[1];
if (Id !== requestId)
continue;
if (data.charCodeAt(0) === 0x00 && data.charCodeAt(1) === 0x67 && data.charCodeAt(2) === 0x58) {
// Last (empty) audio fragment
console.log(`Last (empty) audio fragment`)
const blob = new Blob(_queue[requestId], {
'type': 'audio/mp3'
});
_queue[requestId] = null; //release memory
const url = URL.createObjectURL(blob);
console.log(url)
//URL.revokeObjectURL(url);
_queue.url_resolve[requestId](url);
//return url
} else {
const index = data.indexOf(BINARY_DELIM) + BINARY_DELIM.length;
const audioData = message.slice(index);
_queue[requestId].push(audioData);
_queue.message[index_message] = null; //release blob memory
}
++index_message;
}
}
function onopen(event) {
console.log('open');
//socket.send('Hello Server!');
//socket.close()
setFormat();
ready = true;
}
async function onmessage(event) {
const isbinary = event.data instanceof Blob;
// console.log(`Message from server, type: ${typeof (event.data)} Blob: ${isbinary}`);
_queue.message.push(event.data)
if (!isbinary) {
//console.log(event.data);
const requestId = /X-RequestId:(.*?)\r\n/gm.exec(event.data)[1];
if (event.data.includes("Path:turn.end")) {
// end of turn
createURL(requestId);
}
} else {
}
}
function onerror(event) {
ready = false;
console.log('WebSocket error: ', event);
}
function onclose(event) {
ready = false;
console.log('WebSocket close: ', event); //may be closed by remote
}
function addSocketListeners() {
socket.addEventListener('open', onopen);
// Listen for messages
socket.addEventListener('message', onmessage);
// Listen for possible errors
socket.addEventListener('error', onerror);
// Listen for possible errors
socket.addEventListener('close', onclose);
}
function create_new_ws() {
//try {
// Create WebSocket connection.
socket = new WebSocket(SYNTH_URL);
addSocketListeners();
}
let toStream = function (input) {
let requestSSML = _SSMLTemplate(input);
const requestId = uuidv4().replace(/-/g, '');
// const requestId = uuidv4().replaceAll('-', '');
const request = `X-RequestId:${requestId}\r\nContent-Type:application/ssml+xml\r\nPath:ssml\r\n\r\n
` + requestSSML.trim();
_queue[requestId] = [];
return new Promise((resolve, reject) => {
_queue.url_resolve[requestId] = resolve,
_queue.url_reject[requestId] = reject;
if (!ready) {
if (auto_reconnect) {
create_new_ws();
socket.addEventListener('open', _ => socket.send(request));
setTimeout(_ => {
if (!ready)
reject('reconnect timeout')
}, timeout * 1000);
} else
reject('socket error or timeout');
} else {
socket.send(request)
}
});
}
async function play(input, play_count = 1, play_span = 5000) {
const url = await toStream(input);
let play_resolve = function () {
};
// globalAudio.pause();
!globalAudio.paused && globalAudio.pause();
globalAudio.src = url;
// var audio = new Audio(url);
console.log('before play' + globalAudio.duration) //NaN
//let play_count = 3; //repeat times
globalAudio.onended = (e) => {
console.log(e);
if (--play_count > 0) {
console.log("play----");
setTimeout(_ => globalAudio.play(), play_span);
} else {
//URL.revokeObjectURL(url);
play_resolve(url);
console.log('play end');
}
}
await globalAudio.play();
console.log('after play' + globalAudio.duration);
return new Promise((resolve, reject) => {
play_resolve = resolve
});
}
return new Promise((resolve, reject) => {
setTimeout(_ => reject('socket open timeout'), timeout * 1000);
// Connection opened
socket.addEventListener('open', function (event) {
resolve({
_: play,
toStream,
setVoice: (voice, locale) => {
_voice = voice;
if (!locale) {
const voiceLangMatch = VOICE_LANG_REGEX.exec(_voice);
if (!voiceLangMatch)
throw new Error("Could not infer voiceLocale from voiceName!");
_voiceLocale = voiceLangMatch[0];
} else {
_voiceLocale = locale;
}
},
setFormat,
isReady: _ => ready
})
});
});
}
var tts;
async function init() {
tts = await create_edge_TTS();
}
typeof Promise !== "undefined" && init();
//-------------------------------
async function speak(chn) {
try {
await tts._(chn)
} catch (e) {
console.log('catch error:')
console.log(e)
}
}
});
/*
Words used for testing
"wordorigin": // 词源
"wordfinder": // 联想词horse
"cult": // 文化football
"synonyms": // 同义词辨析like, awful
"which_word": // 词语辨析like, about
"colloc": // 词语搭配show(n.1)
"homophone": // 同音词or
"more_about": // 词语辨析
"mlt": // 同类词语学习a, up, or, be,mere
"wordfamily": // 词族
"grammar": // 语法说明if, like, very
"express": // 情景表达like
"langbank": // 用语库for, up, like, about
"vocab": // 词汇扩充
"british_american": // 英式 / 美式
"snippet": // 牛津搭配词典
"extra_examples": // 更多例句
"verbforms": // 动词形式
"more_about": // 补充说明like
*/