页面嵌入搜索引擎,实时检索发音

pull/375/head
jingjingxyk 3 years ago
parent f21d3e466a
commit 2158795a8c

@ -9,6 +9,7 @@
> 5. 这就安装好了,去掉 Developer Mode 勾选。 > 5. 这就安装好了,去掉 Developer Mode 勾选。
> 6. 打开[`https://github.com/shimohq/chinese-programmer-wrong-pronunciation.git`](https://github.com/shimohq/chinese-programmer-wrong-pronunciation.git)点击单词,即可听正确的单词读音 > 6. 打开[`https://github.com/shimohq/chinese-programmer-wrong-pronunciation.git`](https://github.com/shimohq/chinese-programmer-wrong-pronunciation.git)点击单词,即可听正确的单词读音
## 扩展开发参考 ## 扩展开发参考
1. [content_scripts](https:////developer.chrome.com/docs/extensions/mv3/content_scripts/)
1. [content_scripts](https:////developer.chrome.com/docs/extensions/mv3/content_scripts/)
2. [Declare permissions](https:////developer.chrome.com/docs/extensions/mv3/declare_permissions/)

@ -1,33 +1,31 @@
tr:hover { tr:hover {
border: 8px solid #ddd !important; border: 8px solid #ddd !important;
border-radius: 8px !important; border-radius: 8px !important;
box-shadow: 5px 5px 15px #daf5fe !important; box-shadow: 5px 5px 15px #daf5fe !important;
color: #fff !important; color: #fff !important;
background-color: #3ec487 !important; background-color: #3ec487 !important;
/* /*
font-weight: 200; font-weight: 200;
font-size: 1.1rem; font-size: 1.1rem;
*/ */
} }
#chinese-programmer-wrong-pronunciation-custom-iframe-box{ #chinese-programmer-wrong-pronunciation-custom-iframe-box {
border: 8px solid #ddd !important; border: 8px solid #ddd !important;
border-radius: 8px !important; border-radius: 8px !important;
box-shadow: 5px 5px 15px #daf5fe !important; box-shadow: 5px 5px 15px #daf5fe !important;
z-index: 999; z-index: 999;
position: fixed !important; position: fixed !important;
} }
.chinese-programmer-wrong-pronunciation-custom-iframe-box{ .chinese-programmer-wrong-pronunciation-custom-iframe-box {
right: 0 !important; right: 0 !important;
top: 64px !important; top: 64px !important;
} }
#chinese-programmer-wrong-pronunciation-custom-iframe { #chinese-programmer-wrong-pronunciation-custom-iframe {
width:100%; width: 100%;
height: 100%; height: 100%;
min-width: 700px !important; min-width: 700px !important;
min-height: 600px !important; min-height: 600px !important;
} }

@ -0,0 +1,8 @@
#!/bin/env bash
set -exu
__DIR__=$(cd "$(dirname "$0")";pwd)
cd ${__DIR__}
npm run format-code

@ -1,39 +1,37 @@
import * as until from "./until.js"; import * as until from "./until.js";
import * as components from "./components.js" import * as components from "./components.js";
import * as searchEngine from "./search-engine.js" import * as searchEngine from "./search-engine.js";
let goToSearchPronounce = (word) => { let goToSearchPronounce = (word) => {
let search_engine_name = "gotToGoogleSearch";
// search_engine_name='gotToYouDaoSearch'
let tab = "current_tab";
let search_engine_name = "gotToGoogleSearch" let opener = components.getSearchEngineOpener();
// search_engine_name='gotToYouDaoSearch' if (opener && opener.expired_date) {
let tab = "current_tab" if (opener.expired_date > new Date().getTime()) {
if (opener.search_engine_name) {
let opener = components.getSearchEngineOpener(); search_engine_name = opener.search_engine_name;
if (opener && opener.expired_date) { }
if(opener.expired_date > (new Date()).getTime()) { if (opener.tab) {
if (opener.search_engine_name) { tab = opener.tab;
search_engine_name = opener.search_engine_name; }
}
if (opener.tab) {
tab = opener.tab;
}
}
} }
if (search_engine_name && searchEngine[search_engine_name]) { }
console.log(word) if (search_engine_name && searchEngine[search_engine_name]) {
let url = searchEngine[search_engine_name](word); console.log(word);
console.log(url) let url = searchEngine[search_engine_name](word);
if (tab === 'new_tab') { console.log(url);
window.open(url, '_blank') if (tab === "new_tab") {
} else { window.open(url, "_blank");
let iframe = components.getIframe();
iframe.setAttribute('src', url);
}
} else { } else {
console.log('search engine no found !') let iframe = components.getIframe();
iframe.setAttribute("src", url);
} }
} else {
console.log("search engine no found !");
}
};
} let box = { ...until, ...components, ...searchEngine, goToSearchPronounce };
export default box;
let box = {...until, ...components,...searchEngine, goToSearchPronounce};
export default box

@ -1,69 +1,88 @@
import {prettyBox } from "./pretty-box.js" import { prettyBox } from "./pretty-box.js";
let styleConfig = () => {
let styleConfig=()=>{ let css = document.createElement("link");
let css = document.createElement("link"); css.setAttribute("rel", "stylesheet");
css.setAttribute("rel", "stylesheet"); css.setAttribute("type", "text/css");
css.setAttribute("type", "text/css"); css.setAttribute("href", chrome.runtime.getURL("css/app.css"));
css.setAttribute("href", chrome.runtime.getURL("css/app.css")); document.head.appendChild(css);
document.head.appendChild(css); };
}
let customElement = () => {
let customElement=()=>{ let link = document.createElement("link");
let link = document.createElement("link"); link.setAttribute(
link.setAttribute("href",chrome.runtime.getURL("web-components/x-custom-box.html")); "href",
document.head.appendChild(link); chrome.runtime.getURL("web-components/x-custom-box.html")
} );
document.head.appendChild(link);
let getIframe=()=>{ };
let box = document.querySelector('#chinese-programmer-wrong-pronunciation-custom-iframe-box');
let iframe = null; let getIframe = () => {
if (!box) { let box = document.querySelector(
let custom_box = document.createElement('x-chinese-programmer-wrong-pronunciation-custom-box'); "#chinese-programmer-wrong-pronunciation-custom-iframe-box"
);
let aside=document.createElement('aside') let iframe = null;
aside.setAttribute('id','chinese-programmer-wrong-pronunciation-custom-iframe-box') if (!box) {
aside.setAttribute('class','chinese-programmer-wrong-pronunciation-custom-iframe-box') let custom_box = document.createElement(
aside.setAttribute('draggable',"true") "x-chinese-programmer-wrong-pronunciation-custom-box"
);
iframe=document.createElement('iframe')
iframe.setAttribute('id','chinese-programmer-wrong-pronunciation-custom-iframe') let aside = document.createElement("aside");
aside.appendChild(iframe) aside.setAttribute(
custom_box.appendChild(aside) "id",
document.body.appendChild(custom_box) "chinese-programmer-wrong-pronunciation-custom-iframe-box"
);
//设置 box 可 拖拽 aside.setAttribute(
prettyBox(aside) "class",
//显示重置按键 "chinese-programmer-wrong-pronunciation-custom-iframe-box"
//showResetCurrentSearchEngineTab() );
}else{ aside.setAttribute("draggable", "true");
iframe = box.querySelector('#chinese-programmer-wrong-pronunciation-custom-iframe')
} iframe = document.createElement("iframe");
return iframe iframe.setAttribute(
} "id",
"chinese-programmer-wrong-pronunciation-custom-iframe"
let opener_key = 'how-to-pronounce-from-search-engine-open-tab-opener' );
let getSearchEngineOpener=()=>{ aside.appendChild(iframe);
return JSON.parse(sessionStorage.getItem(opener_key)) custom_box.appendChild(aside);
} document.body.appendChild(custom_box);
let showResetCurrentSearchEngineTab=()=>{ //设置 box 可 拖拽
let div=document.createElement('div'); prettyBox(aside);
div.setAttribute('id','#chinese-programmer-wrong-pronunciation-custom-tools-bar') //显示重置按键
div.innerHTML=` //showResetCurrentSearchEngineTab()
} else {
iframe = box.querySelector(
"#chinese-programmer-wrong-pronunciation-custom-iframe"
);
}
return iframe;
};
let opener_key = "how-to-pronounce-from-search-engine-open-tab-opener";
let getSearchEngineOpener = () => {
return JSON.parse(sessionStorage.getItem(opener_key));
};
let showResetCurrentSearchEngineTab = () => {
let div = document.createElement("div");
div.setAttribute(
"id",
"#chinese-programmer-wrong-pronunciation-custom-tools-bar"
);
div.innerHTML = `
<span>关闭搜索页面</span>🥳🥳🥳🥳🥳🥳<span></span> <span>关闭搜索页面</span>🥳🥳🥳🥳🥳🥳<span></span>
` `;
document.querySelector('#chinese-programmer-wrong-pronunciation-custom-iframe-box').appendChild(div) document
.querySelector("#chinese-programmer-wrong-pronunciation-custom-iframe-box")
} .appendChild(div);
let setSearchEngineOpener=(search_engine_name,tab)=>{ };
let setSearchEngineOpener = (search_engine_name, tab) => {
let opener = getSearchEngineOpener() let opener = getSearchEngineOpener();
if (!opener || opener.expired_date < (new Date()).getTime()) { if (!opener || opener.expired_date < new Date().getTime()) {
search_engine_name = "gotToGoogleSearch";
search_engine_name = "gotToGoogleSearch" /*
/*
if (window.confirm('默认有道词典搜索,选择 “取消” 将设置为谷歌搜索,有效期一天')) { //当前页面展示搜索结果 if (window.confirm('默认有道词典搜索,选择 “取消” 将设置为谷歌搜索,有效期一天')) { //当前页面展示搜索结果
search_engine_name = "gotToYouDaoSearch" search_engine_name = "gotToYouDaoSearch"
} else { } else {
@ -72,13 +91,12 @@ let setSearchEngineOpener=(search_engine_name,tab)=>{
} }
*/ */
//页面展示方式,默认有效期一天
let expired_date = new Date().getTime() + 24 * 60 * 60 * 1000;
// expired_date = (new Date()).getTime() + 10000 # test expired
//页面展示方式,默认有效期一天 tab = "current_tab";
let expired_date = (new Date()).getTime() + 24 * 60 * 60 * 1000 /*
// expired_date = (new Date()).getTime() + 10000 # test expired
tab = "current_tab"
/*
if (window.confirm('允许当前页面展示搜索结果')) { //当前页面展示搜索结果 if (window.confirm('允许当前页面展示搜索结果')) { //当前页面展示搜索结果
tab = "current_tab" tab = "current_tab"
} else { } else {
@ -87,17 +105,25 @@ let setSearchEngineOpener=(search_engine_name,tab)=>{
} }
*/ */
sessionStorage.setItem(opener_key, JSON.stringify({ sessionStorage.setItem(
"tab": tab, opener_key,
"expired_date": expired_date, JSON.stringify({
'search_engine_name': search_engine_name tab: tab,
})); expired_date: expired_date,
} search_engine_name: search_engine_name,
} })
);
let cleanOpener=() => { }
sessionStorage.removeItem(opener_key) };
}
let cleanOpener = () => {
sessionStorage.removeItem(opener_key);
export {styleConfig,customElement,getIframe,getSearchEngineOpener,setSearchEngineOpener} };
export {
styleConfig,
customElement,
getIframe,
getSearchEngineOpener,
setSearchEngineOpener,
};

@ -1,66 +1,66 @@
import box from "./box.js" import box from "./box.js";
let init=()=>{ let init = () => {
let URLObj = new URL(location.href); let URLObj = new URL(location.href);
console.log(URLObj); console.log(URLObj);
if (document.querySelector("#readme table tbody")) { if (document.querySelector("#readme table tbody")) {
box.styleConfig(); box.styleConfig();
box.customElement(); box.customElement();
let audio_player = new Audio(); let audio_player = new Audio();
audio_player.setAttribute("autoplay", "true"); audio_player.setAttribute("autoplay", "true");
document document
.querySelector("#readme table tbody") .querySelector("#readme table tbody")
.addEventListener("click", (event) => { .addEventListener("click", (event) => {
//console.log(event.target)
// console.log(event.target.nodeType)
// console.log(event.target.nodeName);
let parentElement = event.target.parentElement;
if (parentElement && parentElement.nodeName === "TR") {
if (parentElement.firstElementChild === event.target) {
//使用搜索引擎查询发音
box.goToSearchPronounce(event.target.innerText);
}
}
event.preventDefault();
event.stopPropagation();
let audio_url = null;
if (event.target.nodeName === "TD") {
let aTag = event.target.querySelector("a");
if (aTag) {
audio_url = aTag.getAttribute("href");
}
}
if (event.target.nodeName === "IMG") {
let aTag = event.target.parentNode.parentNode;
audio_url = aTag.getAttribute("href");
}
if (audio_url) {
let desURL = new URL(audio_url);
//console.log(desURL.protocol);
if (desURL.protocol === "http:") {
//skip http
location.href = audio_url;
} else {
// console.log("audio_url:", audio_url);
audio_player.setAttribute("src", audio_url);
}
}
});
document
.querySelector("#readme table tbody")
.addEventListener("mouseover", (event) => {
let parentElement = event.target.parentElement;
if (parentElement && parentElement.nodeName === "TR") {
if (parentElement.firstElementChild === event.target) {
event.target.setAttribute("title", "点击我打开搜索引擎检索");
event.target.style.cursor = "pointer";
}
}
});
} else {
console.log("no found README.md table");
}
};
//console.log(event.target) export { init };
// console.log(event.target.nodeType)
// console.log(event.target.nodeName);
let parentElement = event.target.parentElement
if (parentElement && parentElement.nodeName === 'TR') {
if (parentElement.firstElementChild === event.target) {
//使用搜索引擎查询发音
box.goToSearchPronounce(event.target.innerText)
}
}
event.preventDefault();
event.stopPropagation();
let audio_url = null;
if (event.target.nodeName === "TD") {
let aTag = event.target.querySelector("a");
if (aTag) {
audio_url = aTag.getAttribute("href");
}
}
if (event.target.nodeName === "IMG") {
let aTag = event.target.parentNode.parentNode;
audio_url = aTag.getAttribute("href");
}
if (audio_url) {
let desURL = new URL(audio_url);
//console.log(desURL.protocol);
if (desURL.protocol === "http:") {
//skip http
location.href = audio_url;
} else {
// console.log("audio_url:", audio_url);
audio_player.setAttribute("src", audio_url);
}
}
});
document.querySelector("#readme table tbody").addEventListener('mouseover',(event)=>{
let parentElement = event.target.parentElement
if (parentElement && parentElement.nodeName === 'TR') {
if (parentElement.firstElementChild === event.target) {
event.target.setAttribute('title','点击我打开搜索引擎检索')
event.target.style.cursor='pointer'
}
}
})
}else{
console.log("no found README.md table")
}
}
export {init}

@ -1,79 +1,74 @@
import {addClass, removeClass} from "./until.js"; import { addClass, removeClass } from "./until.js";
let prettyBox = (box) => { let prettyBox = (box) => {
// 参考 https://blog.csdn.net/weixin_41910848/article/details/82218243
// 参考 https://blog.csdn.net/weixin_41910848/article/details/82218243 let dragging = false;
let diffX = null;
let dragging = false; let diffY = null;
let diffX = null; box.onmousedown = function (event) {
let diffY = null; dragging = true;
box.onmousedown = function (event) {
dragging = true; let left = box.offsetLeft;
let top = box.offsetTop;
let left = box.offsetLeft;
let top = box.offsetTop; removeClass(
box,
removeClass(box, 'chinese-programmer-wrong-pronunciation-custom-iframe-box') "chinese-programmer-wrong-pronunciation-custom-iframe-box"
);
box.style.left = left + "px";
box.style.top = top + "px"; box.style.left = left + "px";
box.style.top = top + "px";
diffX = event.clientX - left;
diffY = event.clientY - top; diffX = event.clientX - left;
diffY = event.clientY - top;
} };
document.onmousemove = function (event) { document.onmousemove = function (event) {
if (dragging) {
// console.log(event.clientX, event.clientY)
if (dragging) { //console.log(diffX, diffY)
// console.log(event.clientX, event.clientY) let moveX = event.clientX - diffX;
//console.log(diffX, diffY) let moveY = event.clientY - diffY;
let moveX = event.clientX - diffX; if (moveX < 0) {
let moveY = event.clientY - diffY; moveX = 0;
} else if (moveX > window.innerWidth - box.offsetWidth) {
if (moveX < 0) { moveX = window.innerWidth - box.offsetWidth;
moveX = 0 }
} else if (moveX > window.innerWidth - box.offsetWidth) { if (moveY < 0) {
moveX = window.innerWidth - box.offsetWidth moveY = 0;
} } else if (moveY > window.innerHeight - box.offsetHeight) {
if (moveY < 0) { moveY = window.innerHeight - box.offsetHeight;
moveY = 0 }
} else if (moveY > window.innerHeight - box.offsetHeight) {
moveY = window.innerHeight - box.offsetHeight box.style.left = moveX + "px";
} box.style.top = moveY + "px";
box.style.left = moveX + "px"; event.stopPropagation();
box.style.top = moveY + "px" event.preventDefault();
event.stopPropagation();
event.preventDefault();
}
}
document.onmouseup = function (event) {
dragging = false;
} }
};
box.onmouseup = (event) => { document.onmouseup = function (event) {
dragging = false; dragging = false;
} };
box.ondragstart = function (event) { box.onmouseup = (event) => {
console.log(box.offsetLeft, box.offsetTop) dragging = false;
console.log('开始拖拽'); };
}
box.ondrag = function () { box.ondragstart = function (event) {
console.log(box.offsetLeft, box.offsetTop) console.log(box.offsetLeft, box.offsetTop);
console.log('拖拽中'); console.log("开始拖拽");
} };
box.ondragend = function () { box.ondrag = function () {
console.log(box.offsetLeft, box.offsetTop) console.log(box.offsetLeft, box.offsetTop);
console.log('拖拽结束') console.log("拖拽中");
} };
box.ondragend = function () {
} console.log(box.offsetLeft, box.offsetTop);
console.log("拖拽结束");
};
export {prettyBox} };
export { prettyBox };

@ -1,23 +1,22 @@
let gotToGoogleSearch = (word) => {
word = word.replace(/\s/, "+");
return `https://www.google.com/search?q=how+to+pronounce+${word}`;
};
let gotToGoogleSearch=(word) => { let gotToYouDaoSearch = (word) => {
word = word.replace(/\s/, '+'); word = word.replace(/\s/, "+");
return `https://www.google.com/search?q=how+to+pronounce+${word}` return `https://www.youdao.com/result?word=${word}&lang=en`;
} };
let gotToYouDaoSearch=(word) => { let goToBaiDuHanYu = () => {
word = word.replace(/\s/, '+'); // 一点飞上天,黄河两头弯;八字大张口,言字中间走;左一扭,右一扭,你一长,我一长,中间加个马大王;心字底,月字旁,一个小勾挂麻糖,坐个车子逛咸阳。
return `https://www.youdao.com/result?word=${word}&lang=en` // 56个笔画的字 邉
} // U+30EDE (简化版本 U+30EDD
{
"汉".charCodeAt(0).toString(16);
String.fromCharCode("0x6c49");
}
//https://hanyu.baidu.com/s?wd=%E9%82%89
};
let goToBaiDuHanYu=() => { export { goToBaiDuHanYu, gotToYouDaoSearch, gotToGoogleSearch };
// 一点飞上天,黄河两头弯;八字大张口,言字中间走;左一扭,右一扭,你一长,我一长,中间加个马大王;心字底,月字旁,一个小勾挂麻糖,坐个车子逛咸阳。
// 56个笔画的字 邉
// U+30EDE (简化版本 U+30EDD
{
"汉".charCodeAt(0).toString(16)
String.fromCharCode('0x6c49')
}
//https://hanyu.baidu.com/s?wd=%E9%82%89
}
export {goToBaiDuHanYu,gotToYouDaoSearch,gotToGoogleSearch}

@ -1,24 +1,19 @@
function hasClass(el, className) { function hasClass(el, className) {
if (el.classList) if (el.classList) return el.classList.contains(className);
return el.classList.contains(className); return !!el.className.match(new RegExp("(\\s|^)" + className + "(\\s|$)"));
return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'));
} }
function addClass(el, className) { function addClass(el, className) {
if (el.classList) if (el.classList) el.classList.add(className);
el.classList.add(className) else if (!hasClass(el, className)) el.className += " " + className;
else if (!hasClass(el, className))
el.className += " " + className;
} }
function removeClass(el, className) { function removeClass(el, className) {
if (el.classList) if (el.classList) el.classList.remove(className);
el.classList.remove(className) else if (hasClass(el, className)) {
else if (hasClass(el, className)) { let reg = new RegExp("(\\s|^)" + className + "(\\s|$)");
let reg = new RegExp('(\\s|^)' + className + '(\\s|$)'); el.className = el.className.replace(reg, " ");
el.className = el.className.replace(reg, ' '); }
}
} }
export {addClass, removeClass} export { addClass, removeClass };

@ -1,4 +1,4 @@
(async () => { (async () => {
let app = await import(chrome.runtime.getURL('js/app/init.js')) let app = await import(chrome.runtime.getURL("js/app/init.js"));
app.init() app.init();
})(); })();

@ -17,7 +17,7 @@
"declarativeNetRequest", "declarativeNetRequest",
"declarativeNetRequestWithHostAccess" "declarativeNetRequestWithHostAccess"
], ],
"host_permissions": ["*://github.com/*","*://www.google.com/*"], "host_permissions": ["*://github.com/*", "*://www.google.com/*"],
"web_accessible_resources": [ "web_accessible_resources": [
{ {
"resources": ["*.js", "*.css", "*.html"], "resources": ["*.js", "*.css", "*.html"],

@ -38,7 +38,11 @@
}, },
"condition": { "condition": {
"urlFilter": "*", "urlFilter": "*",
"requestDomains": ["github.com", "githubusercontent.com","www.google.com"], "requestDomains": [
"github.com",
"githubusercontent.com",
"www.google.com"
],
"resourceTypes": [ "resourceTypes": [
"main_frame", "main_frame",
"sub_frame", "sub_frame",

@ -1,3 +1,3 @@
# HTML ImportsHTML Template、Shadow DOM----统称为 Web Components 规范 # HTML ImportsHTML Template、Shadow DOM----统称为 Web Components 规范
## Shadow DOM 实现代码隔离 ## Shadow DOM 实现代码隔离

@ -1,3 +1,3 @@
<x-chinese-programmer-wrong-pronunciation-custom-box> <x-chinese-programmer-wrong-pronunciation-custom-box>
<div>自定义web组件-做代码隔离</div> <div>自定义web组件-做代码隔离</div>
</x-chinese-programmer-wrong-pronunciation-custom-box> </x-chinese-programmer-wrong-pronunciation-custom-box>

Loading…
Cancel
Save