diff --git a/background.js b/background.js new file mode 100644 index 0000000..4821159 --- /dev/null +++ b/background.js @@ -0,0 +1,215 @@ +function ChaZD(queryWord, sendResponse) { + var url = urls.dict + queryWord; + console.log("Query url: " + url); + var queryResult = {}; + var self = this; + var xhr = new XMLHttpRequest(); + + xhr.open("GET", url, true); + xhr.onreadystatechange = function() { + if (xhr.readyState != 4) return; + var resultObj = self.parseResult.call(self, xhr.responseText); + sendResponse(resultObj); + } + xhr.send(); +} + +ChaZD.prototype.checkErrorCode = function (errorCode) { + var response = { + "message": "", + "error": 0 + }; + switch (errorCode) { + case 0: + response["message"] = "query success"; + break; + case 20: + response["message"] = "要翻译的文本过长"; + response["error"] = 1; + break; + case 30: + response["message"] = "无法进行有效的翻译"; + response["error"] = 1; + break; + case 40: + response["message"] = "不支持的语言类型"; + response["error"] = 1; + break; + case 50: + response["message"] = "无效的key"; + response["error"] = 1; + break; + case 60: + response["message"] = "无辞典结果"; + response["error"] = 1; + break; + default: + } + return response; +} + +ChaZD.prototype.parseResult = function (responseText) { + var result = JSON.parse(responseText); + var resultObj = {}; + var validResult = this.checkErrorCode(result["errorCode"]); + if (!validResult["error"]) { + var titleBlock = this.initTitle(result); + resultObj.titleBlock = titleBlock; + if (result["basic"] !== undefined) { + var basicBlock = this.parseBasicResult(result); + resultObj.basicBlock = basicBlock + } + + if (result["web"] !== undefined) { + var webBlock = this.parseWebResult(result); + resultObj.webBlock = webBlock; + } + } + resultObj.validMessage = validResult["message"]; + return resultObj; +} + +ChaZD.prototype.initTitle = function (result) { + var translation = result["translation"]; + console.log(translation + " " + result["translation"] ); + var queryWord = result["query"]; + + var voiceContainer = this.initVoice(queryWord); + var titleWord = fmt(frames.titleWord, queryWord, voiceContainer); + var titleTranslation = fmt(frames.titleTranslation, translation.toString()); + + return fmt(frames.titleContainer, titleWord, titleTranslation); +} + +ChaZD.prototype.parseBasicResult = function (result) { + var basic = result["basic"]; + var queryWord = result["query"]; + + var phoneticBlock = this.parseBasicPhonetic(basic, queryWord); + var explainsBlock = this.parseBasicExplains(basic, queryWord); + + var basicContainer = fmt(frames.basicContainer, phoneticBlock, explainsBlock); + return basicContainer; +} + +ChaZD.prototype.parseBasicPhonetic = function (basic, queryWord) { + var ukPhonetic = basic["uk-phonetic"]; + var usPhonetic = basic["us-phonetic"]; + + if (ukPhonetic !== undefined && usPhonetic !== undefined) { + var ukVoice = this.initVoice(queryWord, 1); + var ukPhoneticContainer = fmt(frames.ukPhoneticContainer, "[" + ukPhonetic + "]" + ukVoice); + + var usVoice = this.initVoice(queryWord, 2); + var usPhoneticContainer = fmt(frames.usPhoneticContainer, "[" + usPhonetic + "]" + usVoice); + + return fmt(frames.phoneticContainer, ukPhoneticContainer, usPhoneticContainer); + } + + return fmt(frames.phoneticContainer, "", ""); +} + +ChaZD.prototype.initVoice = function (queryWord, type) { + var src = urls.voice + queryWord; + if(type !== undefined) + src = src + "&type=" + type; + var title = ""; + if(type === 1){ + title = "英音"; + } else if (type === 2){ + title = "美音"; + } else { + title = "真人发音"; + } + + return fmt(frames.voiceContainer, src, title); +} + +ChaZD.prototype.parseBasicExplains = function (basic, queryWord) { + var explains = basic["explains"]; + var i; + var explainsContent = ""; + for (i = 0; i < explains.length; i++) { + var currentExplain = explains[i]; + + var haveProperty = currentExplain.indexOf(" "); + var property = (haveProperty !== -1) ? currentExplain.slice(0, haveProperty) : ""; + var propertyTitle = this.parseProperty(property); + var propertyContainer = fmt(frames.propertyContainer, propertyTitle, property); + var explainText = (haveProperty !== -1) ? currentExplain.slice(haveProperty) : currentExplain; + + var explain = fmt(frames.explain, propertyContainer, explainText); + explainsContent += explain; + } + + return fmt(frames.explainsContainer, fmt(frames.explainsList, explainsContent)); +} + +ChaZD.prototype.parseProperty = function (property) { + var propertyText = ""; + switch (property) { + case "adj." : + propertyText = "形容词"; + break; + case "adv." : + propertyText = "副词"; + break; + case "n." : + propertyText = "名词"; + break; + case "vi." : + propertyText = "不及物动词"; + break; + case "vt." : + propertyText = "及物动词"; + break; + case "prep." : + propertyText = "介词"; + break; + case "conj." : + propertyText = "连词"; + break; + case "int." : + propertyText = "感叹词"; + break; + case "abbr." : + propertyText = "代词"; + break; + case "pron." : + propertyText = ""; + break; + default : + } + + return propertyText; +} + + + +ChaZD.prototype.parseWebResult = function (result) { + var web = result["web"]; + var webExplainsContent = ""; + var i; + for (i = 0; i < web.length ; i++) { + var webEplain = fmt(frames.webEplain, web[i].key + web[i].value); + webExplainsContent += webEplain; + } + + return fmt(frames.webExplainsContainer, fmt(frames.webEplainsList, webExplainsContent)); +} + +/* +ChaZD.prototype.parsePhrase = function (queryWord, key) { + var words = []; + words = queryWord.split(/\s+/); +} +*/ + +chrome.runtime.onMessage.addListener( + function(message, sender, sendResponse){ + console.log("message from sender:" + JSON.stringify(message)); + console.log("sender is " + JSON.stringify(sender)); + new ChaZD(message.queryWord, sendResponse); + + return true; +}); diff --git a/icons/icon128.png b/icons/icon128.png new file mode 100644 index 0000000..25d11a6 Binary files /dev/null and b/icons/icon128.png differ diff --git a/icons/icon16.png b/icons/icon16.png new file mode 100644 index 0000000..dbff9d5 Binary files /dev/null and b/icons/icon16.png differ diff --git a/icons/icon19.png b/icons/icon19.png new file mode 100644 index 0000000..74721d2 Binary files /dev/null and b/icons/icon19.png differ diff --git a/icons/icon38.png b/icons/icon38.png new file mode 100644 index 0000000..172c20d Binary files /dev/null and b/icons/icon38.png differ diff --git a/icons/icon48.png b/icons/icon48.png new file mode 100644 index 0000000..b68d63e Binary files /dev/null and b/icons/icon48.png differ diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..b9d8c15 --- /dev/null +++ b/manifest.json @@ -0,0 +1,51 @@ +{ + "manifest_version": 2, + + "name": "ChaZD", + "version": "0.6.0", + "description": "ChaZD 查字典,简洁易用的英汉字典扩展程序,支持划词哦:)", + + "permissions": [ + "http://dict.youdao.com/*", + "http://fanyi.youdao.com/*", + "contextMenus", + "tabs", + "storage" + ], + + "background": { + "persistent": true, + "scripts": [ "utility.js", "background.js" ] + }, + + "content_scripts": [ { + "all_frames": true, + "css": ["style/inPage.css", "style/fonts/YDdict-Icon.css"], + "js": ["utility.js", "selection.js"], + "matches": [""] + + } ], + + "browser_action": { + "default_popup": "popup.html", + "default_icon": { + "38": "icons/icon38.png", + "19": "icons/icon19.png" + } + }, + + "icons": { + "16": "icons/icon16.png", + "48": "icons/icon48.png", + "128": "icons/icon128.png" + }, + + "commands": { + "_execute_browser_action": { + "suggested_key": { + "default": "Ctrl+Shift+F", + "mac": "MacCtrl+Shift+F" + } + } + } +} \ No newline at end of file diff --git a/popup.html b/popup.html new file mode 100644 index 0000000..b3b2405 --- /dev/null +++ b/popup.html @@ -0,0 +1,52 @@ + + + + + Youdao Dictionary + + + +
+ + +
+ +
+ +
+

+ Tips: 你可以通过“Ctrl+Shift+F”快速启动词典, + 也可以在这里自定义快捷键哦:) +

+
不再显示Tips
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + +
+
+ + + + + + \ No newline at end of file diff --git a/popup.js b/popup.js new file mode 100644 index 0000000..fed233d --- /dev/null +++ b/popup.js @@ -0,0 +1,121 @@ +var button = $("search"); +var tipsContainer = $("tips"); +var input = $("query_word"); +var queryResultContainer = $("query_result"); + +function queryInPopup() { + if (!tipsContainer.classList.contains("unshow")) + tipsContainer.classList.add("unshow"); + input.select(); + if (queryResultContainer.classList.contains("unshow")) + queryResultContainer.classList.remove("unshow"); + queryResultContainer.innerHTML = "ψ(._. )>词典君正在翻译。。。"; + chrome.extension.sendMessage({queryWord: input.value}, function(response) { + //alert("response from xhr: " + JSON.stringify(response)); + var resultObj = response; + var resultBlock = ""; + if (resultObj.validMessage == "query success") { + resultBlock += resultObj.titleBlock; + if (resultObj.basicBlock !== undefined) { + resultBlock += resultObj.basicBlock; + } + if (resultObj.webBlock !== undefined) { + resultBlock += resultObj.webBlock; + } + queryResultContainer.innerHTML = resultBlock; + var voiceCollection = document.querySelectorAll(".voice_container"); + for (var i = 0; i < voiceCollection.length; i++) { + var src = voiceCollection[i].getAttribute("data-src"); + var audioBlock = document.createElement("audio"); + audioBlock.setAttribute("src", src); + voiceCollection[i].appendChild(audioBlock); + audioBlock.addEventListener("ended", function(event) { + this.load(); + }) + voiceCollection[i].addEventListener("click", function(event) { + this.firstChild.play(); + }) + } + } else { + queryResultContainer.innerHTML = resultObj.validMessage + "
词典君崩溃了(┬_┬)"; + } + }); +} + +button.addEventListener("click", function(event) { + queryInPopup(); +}); + +input.focus(); +input.addEventListener("keyup", function(event) { + if (event.keyCode === 13) { + queryInPopup(); + } +}); + +function createLink(link, url) { + link.addEventListener("click", function(event) { + chrome.tabs.create({'url': url}); + }); +} + +var issue = $("issue"); +var email = $("email"); +var source = $("source"); +var keySet = $("key_set"); + +createLink(email, "mailto:ververcpp@gmail.com"); +createLink(source, "https://github.com/ververcpp/ChaZD"); +createLink(issue, "https://github.com/ververcpp/ChaZD/issues/new"); +createLink(keySet, "chrome://extensions/configureCommands") + +var setting_button = $("setting_button"); +setting_button.addEventListener("click", function(event) { + //alert(JSON.stringify( $("settings").style)); + this.classList.toggle("setting_button_clicked"); + $("settings").classList.toggle("unshow"); +}) + +var mouseSelect = $("mouseSelect"); +var showPositionSide = $("showPositionSide"); +var showPositionNear = $("showPositionNear"); +var showDuration = $("showDuration"); +var currentDuration = $("currentDuration"); +var turnOffTips = $("turn_off_tips"); +var tips = $("tips"); + +chrome.storage.sync.get(null, function(items) { + mouseSelect.checked = items["mouseSelect"]; + if (items.showTips) { + tips.classList.remove("unshow"); + } + if (items.showPosition === "side") { + showPositionSide.checked = true; + } else if (items.showPosition === "near") { + showPositionNear.checked = true; + } + currentDuration.innerHTML = showDuration.value = items["duration"]; +}); + +turnOffTips.addEventListener("click", function(event) { + tips.classList.add("unshow"); + updateSetting("showTips", false); +}) + +mouseSelect.addEventListener("click", function(event) { + var isChecked = event.target.checked; + updateSetting("mouseSelect", isChecked); +}); + +showPositionSide.addEventListener("click", function(event) { + updateSetting("showPosition", "side"); +}); + +showPositionNear.addEventListener("click", function(event) { + updateSetting("showPosition", "near"); +}); + +showDuration.addEventListener("click", function(event) { + currentDuration.innerHTML = event.target.value; + updateSetting("duration", event.target.value); +}) \ No newline at end of file diff --git a/selection.js b/selection.js new file mode 100644 index 0000000..3ef8092 --- /dev/null +++ b/selection.js @@ -0,0 +1,128 @@ +var resultSideList = document.createElement("div"); +resultSideList.setAttribute("class", "ChaZD_result_side_list"); +document.body.appendChild(resultSideList); + +function queryInPage(event) { + var selection = window.getSelection(); + var selectText = trim(selection.toString()); + var selectRange = selection.getRangeAt(0).getBoundingClientRect(); + if(selectText == "" || !(/[a-zA-Z\s]/.test(selectText))) return; + console.log("Selected Text at %s : %s", location.href, selectText); + var currentSettings = {}; + chrome.storage.sync.get(null, function(items) { + console.log("[Settings after select]"); + for( var key in items) { + currentSettings[key] = items[key]; + console.log(" %s : %s", key, currentSettings[key]); + } + if(!currentSettings["mouseSelect"]) return; + var duration = currentSettings["duration"] + if(currentSettings["showPosition"] == "side") { + //console.log("in 1"); + showResultSide(selectText, duration); + } + if(currentSettings["showPosition"] == "near") { + //console.log("in 2"); + showResultNear(selectText, selectRange, duration, event); + } + }); +} + +function showResultSide(text, duration) { + if(isExist(text)) return; + var resultSideContainer = document.createElement("div"); + resultSideContainer.setAttribute("class", "ChaZD_result_container"); + resultSideContainer.setAttribute("data-text", text); + resultSideContainer.innerHTML = "ψ(._. )>划词君正在翻译。。。"; + chrome.runtime.sendMessage({queryWord: text}, function(response) { + var resultObj = response; + resultSideContainer.innerHTML = ""; + if(resultObj.validMessage === "query success") { + resultSideContainer.innerHTML += resultObj.titleBlock; + if(resultObj.basicBlock) + resultSideContainer.innerHTML += resultObj.basicBlock; + else { + var unableMessage = "╮(╯▽╰)╭划词君无能为力啊
复制给词典君试试吧↗" + resultSideContainer.innerHTML += unableMessage; + } + } + }); + setTimeout(function(){ + resultSideList.appendChild(resultSideContainer); + }, 100); + + setTimeout(function(){ + //resultSideContainer.classList.add("result_side_container_timeup"); + resultSideList.removeChild(resultSideContainer); + }, 1000*duration); +} + +function showResultNear(text, range, duration, event) { + if(isExist(text)) return; + var showNearPosition = {}; + //文本框中选取的内容返回的left top 为0,此时采集鼠标的位置 + if (range.left === 0 && range.top === 0) { + range = { left: event.clientX, top: event.clientY, height: 15}; + } + + var left = range.left + document.body.scrollLeft; + var top = range.top + document.body.scrollTop; + var clientHeight = 0; + // + clientHeight = (document.documentElement.clientHeight > document.body.clientHeight) ? document.body.clientHeight : document.documentElement.clientHeight; + console.log("clientHeight : " + clientHeight); + if (range.top >= 150) { + var bottom = clientHeight - top; + showNearPosition = { left: left, bottom: bottom }; + } else { + showNearPosition = { left: left, top: top + range.height + 5 }; + } + + var resultNearContainer = document.createElement("div"); + resultNearContainer.setAttribute("class", "ChaZD_result_container"); + resultNearContainer.setAttribute("data-text", text); + resultNearContainer.style.position = "absolute"; + resultNearContainer.style.left = showNearPosition.left + "px"; + if (showNearPosition.bottom) { + resultNearContainer.style.bottom = showNearPosition.bottom + "px"; + } + if (showNearPosition.top) { + resultNearContainer.style.top = showNearPosition.top + "px"; + } + resultNearContainer.innerHTML = "ψ(._. )>划词君正在翻译。。。"; + chrome.runtime.sendMessage({queryWord: text}, function(response) { + var resultObj = response; + resultNearContainer.innerHTML = ""; + if(resultObj.validMessage === "query success") { + resultNearContainer.innerHTML += resultObj.titleBlock; + if(resultObj.basicBlock) + resultNearContainer.innerHTML += resultObj.basicBlock; + else { + var unableMessage = "╮(╯▽╰)╭划词君无能为力啊
复制给词典君试试吧↗" + resultNearContainer.innerHTML += unableMessage; + } + } + }); + setTimeout(function() { + document.body.appendChild(resultNearContainer); + }, 100); + setTimeout(function() { + document.body.removeChild(resultNearContainer); + }, 1000 * duration); +} + +function isExist(text) { + var resultContainerCollection = document.getElementsByClassName("ChaZD_result_container"); + var length = resultContainerCollection.length; + if (length !== 0) { + for (var i = 0; i < length; i++) { + if (resultContainerCollection[i].getAttribute("data-text") === text) + return true; + } + } + return false; +} + + +document.body.addEventListener("mouseup", queryInPage); + diff --git a/style/fonts/YDdict-Icon-font.eot b/style/fonts/YDdict-Icon-font.eot new file mode 100644 index 0000000..a94640d Binary files /dev/null and b/style/fonts/YDdict-Icon-font.eot differ diff --git a/style/fonts/YDdict-Icon-font.svg b/style/fonts/YDdict-Icon-font.svg new file mode 100644 index 0000000..abccde4 --- /dev/null +++ b/style/fonts/YDdict-Icon-font.svg @@ -0,0 +1,22 @@ + + + +Copyright (C) 2014 by original authors @ fontello.com + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/style/fonts/YDdict-Icon-font.ttf b/style/fonts/YDdict-Icon-font.ttf new file mode 100644 index 0000000..f1e9315 Binary files /dev/null and b/style/fonts/YDdict-Icon-font.ttf differ diff --git a/style/fonts/YDdict-Icon-font.woff b/style/fonts/YDdict-Icon-font.woff new file mode 100644 index 0000000..349ec45 Binary files /dev/null and b/style/fonts/YDdict-Icon-font.woff differ diff --git a/style/fonts/YDdict-Icon.css b/style/fonts/YDdict-Icon.css new file mode 100644 index 0000000..c512336 --- /dev/null +++ b/style/fonts/YDdict-Icon.css @@ -0,0 +1,8 @@ +@font-face { + font-family: "YDdict-Icon"; + src: url("YDdict-Icon-font.eot"); + src: url("YDdict-Icon-font.svg") format("svg"), + url("YDdict-Icon-font.woff") format("woff"); + font-weight: normal; + font-style: normal; +} \ No newline at end of file diff --git a/style/inPage.css b/style/inPage.css new file mode 100644 index 0000000..a8462b4 --- /dev/null +++ b/style/inPage.css @@ -0,0 +1,89 @@ +.ChaZD_result_side_list { + position: fixed; + right: 5px; + top: 5px; + margin: 0; + padding: 0; + width: 250px; + z-index: 99999999; + text-align: left; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; +} + +.ChaZD_result_container { + width: 250px; + background-color: #ffdb70; + padding: 5px; + margin: 2px; + opacity: 0.9; + border: 1px solid rgba(209, 209, 209, 1); + border-radius: 2px; + z-index: 99999999; +} + +.ChaZD_result_container .title_container { + color: rgba(41, 94, 255, 1); + display: flex; + max-width: 100%; + font-size: 18px; + margin-bottom: 10px; +} + +.ChaZD_result_container .title_container .title_word { + position: relative; + max-width: 100%; + text-align: left; +} + +.ChaZD_result_container .title_container .title_translation { + display: none; +} + +/*Result Block -- basic container*/ +.ChaZD_result_container .basic_container { + +} + +/*Result Block -- basic container -- phonetic container*/ +.ChaZD_result_container .phonetic_container { + display: none; +} + +/* +.ChaZD_result_container .voice_container::after { + content: '\E803'; + font-family: "YDdict-Icon"; + + -webkit-transition: color 0.2s linear; + transition : color 0.2s linear; +} + +.ChaZD_result_container .voice_container:hover { + color: rgba(119, 110, 101, 1); +} +*/ + +/*Result Block -- basic container -- explains container*/ +.ChaZD_result_container .explains_container { + font-size: 14px; + margin-top: 10px; +} + +.ChaZD_result_container .explains_list { + list-style: none; + margin: 0; + padding: 0; +} + +.ChaZD_result_container .explains_list li { + margin-bottom: 5px; +} + +.ChaZD_result_container .property_container { + margin-right: 5px; +} + +.ChaZD_result_container .voice_container { + display: none; +} \ No newline at end of file diff --git a/style/style.css b/style/style.css new file mode 100644 index 0000000..f47513b --- /dev/null +++ b/style/style.css @@ -0,0 +1,368 @@ +@import url(fonts/YDdict-Icon.css); + +body { + margin: 0.5em; + padding: 0; + width: 300px; + background-color: #faf8ef; + color: #776e65; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; +} + +ul { + list-style: none; + margin: 0; + padding: 0; +} + +.input_container{ + position: relative; + margin: 0; + border: 1px solid #dbd8e4; + box-shadow: -0.2px -0.2px 0.2px 0.2px ; + border-radius: 3px; +} + +.input_container:after { + content: ""; + display: block; + clear: both; +} + +.input_area { + display: block; + padding: 2px; + border: none; + font-size: 1.3em; + width: 270px; + margin: 0 0 0 17px; +} + +.input_area:focus { + outline: none; +} + +.query_button { + display: block; + height: 100%; + float: left; + border: 0; + border-radius: 1px; + margin: 0; + padding: 4px; + background-color: transparent; + line-height: 19px; + color: rgba(0, 0, 0, 0.2); + +} + +.query_button:focus { + outline-color: transparent; +} + +.query_button:hover { + color: rgba(0, 0, 0, 1); +} + +.query_button:active { + color: rgba(235, 0, 0, 1); +} + +.query_button::after { + content: '\E800'; + -webkit-transition: color 0.2s linear; + transition: color 0.2s linear; + font-size: 0.8em; + font-family: "YDdict-Icon"; +} + + + +/*Result Block*/ +.result_container { + margin-top: 10px; + padding: 4px; +} + +.unshow { + display: none; +} + +/*Result Block -- title contaniner*/ +.title_container { + margin-left: 10px; + display: flex; + min-width: 50%; + max-width: 100%; + font-size: 22px; +} + +.title_container .title_phonetic { + display: none; +} + +.title_container .title_word { + position: relative; + max-width: 50%; + text-align: left; +} + +.title_container .title_word .voice_container { + display: inline-block; + margin-left: 10px; + +} + +.title_container .title_word .voice_container::after { + content: '\E804'; + font-family: "YDdict-Icon"; + font-size: 70%; +} + +.title_container .title_translation { + flex:1; + margin-left: 10px; + text-align: justify; + max-width: 50%; +} + + +/*Result Block -- basic container*/ +.basic_container { + margin-top: 10px; +} + +/*Result Block -- basic container -- phonetic container*/ +.phonetic_container { + margin-left: 10px; + font-size: 1em; +} + +.uk_phonetic_container::before { + content: "英 "; + color: #776e65; +} + +.us_phonetic_container::before { + content: "美 "; + color: #776e65; +} + +.uk_phonetic_container, .us_phonetic_container { + display: inline-block; + margin-right: 10px; + color: red; +} + +.voice_container { + cursor: pointer; + display: inline-block; + margin-left: 10px; + color: rgba(119, 110, 101, 0.2); +} + +.voice_container::after { + content: '\E803'; + font-family: "YDdict-Icon"; + + -webkit-transition: color 0.2s linear; + transition : color 0.2s linear; +} + +.voice_container:hover { + color: rgba(119, 110, 101, 1); +} + + +/*Result Block -- basic container -- explains container*/ +.explains_container { + font-size: 14px; + margin-top: 10px; +} + +.explains_list { + border: 1px solid #F0EFF0; + border-radius: 1px; + padding: 10px; +} + +.explains_list li { + margin-bottom: 5px; +} + +.property_container { + margin-right: 5px; +} + +/*Result Block -- web explains container*/ +.web_explains_container { + font-size: 14px; + margin-top: 20px; + position: relative; +} + +.web_title { + position: absolute; + top: -5px; + left: 10px; + background-color: #faf8ef; + font-weight: bold; +} + +.web_title::before { + content: '\E802'; + font-family: "YDdict-Icon"; + margin-right: 5px; + color: #ccbb1e; +} + +.web_explains_list { + border: 1px solid #F0EFF0; + border-radius: 1px; + padding: 10px; + padding-top: 20px; +} + +.web_explains_list li { + margin-bottom: 5px; +} + +.tips_container { + position: relative; + padding: 5px; + font-size: 0.4em; + color: rgba(0, 0, 0, 0.4); +} + +.tips_container p { + margin: 0; + margin-top: 10px; + padding: 0; +} + +.tips_container .link { + color: rgba(0, 161, 194, 1); + cursor: pointer; + -webkit-transition: color 0.2s linear; + transition : color 0.2s linear; +} + +#turn_off_tips { + position: absolute; + right: 5px; + bottom: 5px; + cursor: pointer; + text-decoration: underline; +} + +footer { + font-size: 0.3em; + text-align: center; + position: relative; +} + +footer img { + position: relative; + top:4px; + width: 50px; +} + +.contact_info { + font-size: 0.3em; + font-family: "YDdict-Icon"; + position: absolute; + bottom:0; + right: 0; +} + +.link{ + cursor: pointer; + text-decoration: none; + color: rgba(0, 0, 0, 0.2); + opacity: 0.5; +} + +.link:hover{ + color: rgba(0, 0, 0, 1); +} + +#email::after { + content: '\E806'; + + -webkit-transition: color 0.2s linear; + transition : color 0.2s linear; +} + +#issue::after { + content: '\E805'; + + -webkit-transition: color 0.2s linear; + transition : color 0.2s linear; +} + +#source::after { + content: '\E807'; + + -webkit-transition: color 0.2s linear; + transition : color 0.2s linear; +} + +.setting_button { + position: absolute; + bottom:0; + left: 0; + cursor: pointer; + font-size: 0.3em; + font-family: "YDdict-Icon"; +} + +.setting_button_clicked { + color: #000000; +} + +.setting_button::after { + content: "\E80A"; + -webkit-transition: color 0.2s linear; + transition : color 0.2s linear; +} + +.setting_block { + margin: 5px 0; + padding: 10px; + position: relative; + text-align: justify; + border: 1px solid #F0EFF0; + border-radius: 1px; + background-color: #f2ecd4; +} + +.setting_block div { + margin-top: 5px; +} + +.setting_block label { + margin-left: 5px; +} + +.setting_block input { + margin: 0; +} + +input[type="range"] { + width: 100px; + position: relative; + top:3px; +} + +#save { + position: absolute; + top: 0; + right: 0; +} + +#cancel { + position: absolute; + top: 25px; + right: 0; +} diff --git a/utility.js b/utility.js new file mode 100644 index 0000000..5da35c7 --- /dev/null +++ b/utility.js @@ -0,0 +1,104 @@ +var api = { + key: 1116151381, + keyfrom : "youdaocidian" +}; + +var urls = { + dict : "http://fanyi.youdao.com/openapi.do?keyfrom=" + api.keyfrom +"&key="+ api.key +"&type=data&doctype=json&version=1.1&q=", + voice : "http://dict.youdao.com/dictvoice?audio=" +}; + +var settings = { + mouseSelect : true, //是否启用划词翻译 + showPosition : "side", //划词翻译结果显示的位置 + duration : 5, //翻译结果显示的时间 + showTips : true //是否显示Tips +} + +var frames = { + //title frame + titleContainer : "
#{1}#{2}
", + titleWord : "
#{1}#{2}
", + voiceContainer : "
", + titleTranslation : "
#{1}
", + + //basic frame + basicContainer : "
#{1}#{2}
", + + //basic phonetic frame + phoneticContainer : "
#{1}#{2}
", + ukPhoneticContainer : "
#{1}
", + usPhoneticContainer : "
#{1}
", + + //basic explain frame + explainsContainer : "
#{1}
", + explainsList : "", + explain : "
  • #{1}#{2}
  • ", + propertyContainer : "#{2}", + + //web explain frame + webExplainsContainer : "
    网络释义及短语
    #{1}
    ", + webEplainsList : "", + webEplain : "
  • #{1}
  • " +} + +chrome.storage.sync.get(null,function(items) { + //console.log(JSON.stringify(items)); + if (items["mouseSelect"] === undefined ) { + console.log("storage 是空的"); + chrome.storage.sync.set(settings); + } else { + console.log("[Current Settings]") + for(var key in items){ + settings[key] = items[key]; + console.log(" %s : %s", key, settings[key]); + } + } +}); + +chrome.storage.onChanged.addListener(function(changes) { + for (var key in changes) { + console.log("Settings Update, [%s] %s => %s", key, changes[key].oldValue, changes[key].newValue); + } +}); + +function $(id) { + return document.getElementById(id) +} + +//判断一个初始化后的对象是否为空 +function isEmpty(obj) { + for (var name in obj) { + return false; + } + return true; +} + +function updateSetting(key, newValue) { + //this.key = key; + console.log("Set %s value to '%s'", key, newValue); + settings[key] = newValue; + chrome.storage.sync.set(settings); +} + +/* + * 文本模板函数fmt, @greatghoul + * 参考TransIt。 + */ +function fmt() { + var args = arguments; + return args[0].replace(/#{(.*?)}/g, function(match, prop) { + return function(obj, props) { + var prop = /\d+/.test(props[0]) ? parseInt(props[0]) : props[0]; + if (props.length > 1) { + return arguments.callee(obj[prop], props.slice(1)); + } else { + return obj[prop]; + } + }(typeof args[1] === 'object' ? args[1] : args, prop.split(/\.|\[|\]\[|\]\./)); + }); +} + +function trim(str) { + return str.replace(/(^\s*)|(\s*$)/g, ""); +} \ No newline at end of file