diff --git a/dist/background.js b/dist/background.js index ec815fa..4f28f03 100644 --- a/dist/background.js +++ b/dist/background.js @@ -1 +1 @@ -(()=>{"use strict";var e={994:function(e,t,o){var i=this&&this.__awaiter||function(e,t,o,i){return new(o||(o=Promise))((function(n,s){function r(e){try{c(i.next(e))}catch(e){s(e)}}function l(e){try{c(i.throw(e))}catch(e){s(e)}}function c(e){var t;e.done?n(e.value):(t=e.value,t instanceof o?t:new o((function(e){e(t)}))).then(r,l)}c((i=i.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:!0});const n=o(379);chrome.action.onClicked.addListener((e=>{e.id&&e.url&&chrome.scripting.executeScript({target:{tabId:e.id},files:["content_script.js"]})}));const s=new n.LocalDatabase;console.log("Background script started."),chrome.runtime.onMessage.addListener(((e,t,o)=>{if(console.log("Message received in background:",e),"save_entry"===e.type)return s.save(e.entry).then((()=>i(void 0,void 0,void 0,(function*(){console.log("Entry saved successfully:",e.entry);const t=yield s.getAll();console.log("All entries after save:",t),o({status:"ok"})})))),!0}))},379:function(e,t){var o=this&&this.__awaiter||function(e,t,o,i){return new(o||(o=Promise))((function(n,s){function r(e){try{c(i.next(e))}catch(e){s(e)}}function l(e){try{c(i.throw(e))}catch(e){s(e)}}function c(e){var t;e.done?n(e.value):(t=e.value,t instanceof o?t:new o((function(e){e(t)}))).then(r,l)}c((i=i.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:!0}),t.LocalDatabase=void 0,t.LocalDatabase=class{constructor(){this.STORAGE_KEY="word_entries",this.EXCLUDED_DOMAIN_KEY="excluded_domains",this.INCLUDED_DOMAIN_KEY="included_domains"}getAll(){return o(this,void 0,void 0,(function*(){console.log("Getting all entries from storage...");const e=yield chrome.storage.local.get(this.STORAGE_KEY);return console.log("All entries:",e),e[this.STORAGE_KEY]||[]}))}save(e){return o(this,void 0,void 0,(function*(){const t=yield this.getAll(),o=t.findIndex((t=>t.key===e.key));o>-1?t[o]=e:t.push(e),yield chrome.storage.local.set({[this.STORAGE_KEY]:t})}))}delete(e){return o(this,void 0,void 0,(function*(){const t=(yield this.getAll()).filter((t=>t.key!==e));yield chrome.storage.local.set({[this.STORAGE_KEY]:t})}))}getAllExcludedDomains(){return o(this,void 0,void 0,(function*(){return(yield chrome.storage.local.get(this.EXCLUDED_DOMAIN_KEY))[this.EXCLUDED_DOMAIN_KEY]||[]}))}addExcludedDomain(e){return o(this,void 0,void 0,(function*(){const t=yield this.getAllExcludedDomains();t.some((t=>t.domain===e))||(t.push({domain:e}),yield chrome.storage.local.set({[this.EXCLUDED_DOMAIN_KEY]:t}))}))}removeExcludedDomain(e){return o(this,void 0,void 0,(function*(){const t=(yield this.getAllExcludedDomains()).filter((t=>t.domain!==e));yield chrome.storage.local.set({[this.EXCLUDED_DOMAIN_KEY]:t})}))}getAllIncludedDomains(){return o(this,void 0,void 0,(function*(){return(yield chrome.storage.local.get(this.INCLUDED_DOMAIN_KEY))[this.INCLUDED_DOMAIN_KEY]||[]}))}addIncludedDomain(e){return o(this,void 0,void 0,(function*(){const t=yield this.getAllIncludedDomains();t.some((t=>t.domain===e))||(t.push({domain:e}),yield chrome.storage.local.set({[this.INCLUDED_DOMAIN_KEY]:t}))}))}removeIncludedDomain(e){return o(this,void 0,void 0,(function*(){const t=(yield this.getAllIncludedDomains()).filter((t=>t.domain!==e));yield chrome.storage.local.set({[this.INCLUDED_DOMAIN_KEY]:t})}))}}}},t={};!function o(i){var n=t[i];if(void 0!==n)return n.exports;var s=t[i]={exports:{}};return e[i].call(s.exports,s,s.exports,o),s.exports}(994)})(); \ No newline at end of file +(()=>{"use strict";var e={994:function(e,t,o){var n=this&&this.__awaiter||function(e,t,o,n){return new(o||(o=Promise))((function(i,s){function r(e){try{l(n.next(e))}catch(e){s(e)}}function c(e){try{l(n.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof o?t:new o((function(e){e(t)}))).then(r,c)}l((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:!0});const i=o(379);chrome.action.onClicked.addListener((e=>{e.id&&e.url&&chrome.tabs.sendMessage(e.id,{type:"CHECK_SCRIPT"},(t=>{!chrome.runtime.lastError&&t&&t.injected?console.log("Content script already injected."):chrome.scripting.executeScript({target:{tabId:e.id},files:["content_script.js"]}).then((()=>{console.log("Content script injected successfully.")})).catch((e=>{console.error("Failed to inject content script:",e)}))}))}));const s=new i.LocalDatabase;console.log("Background script started."),chrome.runtime.onMessage.addListener(((e,t,o)=>{if(console.log("Message received in background:",e),"save_entry"===e.type)return s.save(e.entry).then((()=>n(void 0,void 0,void 0,(function*(){console.log("Entry saved successfully:",e.entry);const t=yield s.getAll();console.log("All entries after save:",t),o({status:"ok"})})))),!0}))},379:function(e,t){var o=this&&this.__awaiter||function(e,t,o,n){return new(o||(o=Promise))((function(i,s){function r(e){try{l(n.next(e))}catch(e){s(e)}}function c(e){try{l(n.throw(e))}catch(e){s(e)}}function l(e){var t;e.done?i(e.value):(t=e.value,t instanceof o?t:new o((function(e){e(t)}))).then(r,c)}l((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:!0}),t.LocalDatabase=void 0,t.LocalDatabase=class{constructor(){this.STORAGE_KEY="word_entries",this.EXCLUDED_DOMAIN_KEY="excluded_domains",this.INCLUDED_DOMAIN_KEY="included_domains"}getAll(){return o(this,void 0,void 0,(function*(){console.log("Getting all entries from storage...");const e=yield chrome.storage.local.get(this.STORAGE_KEY);return console.log("All entries:",e),e[this.STORAGE_KEY]||[]}))}save(e){return o(this,void 0,void 0,(function*(){const t=yield this.getAll(),o=t.findIndex((t=>t.key===e.key));o>-1?t[o]=e:t.push(e),yield chrome.storage.local.set({[this.STORAGE_KEY]:t})}))}delete(e){return o(this,void 0,void 0,(function*(){const t=(yield this.getAll()).filter((t=>t.key!==e));yield chrome.storage.local.set({[this.STORAGE_KEY]:t})}))}getAllExcludedDomains(){return o(this,void 0,void 0,(function*(){return(yield chrome.storage.local.get(this.EXCLUDED_DOMAIN_KEY))[this.EXCLUDED_DOMAIN_KEY]||[]}))}addExcludedDomain(e){return o(this,void 0,void 0,(function*(){const t=yield this.getAllExcludedDomains();t.some((t=>t.domain===e))||(t.push({domain:e}),yield chrome.storage.local.set({[this.EXCLUDED_DOMAIN_KEY]:t}))}))}removeExcludedDomain(e){return o(this,void 0,void 0,(function*(){const t=(yield this.getAllExcludedDomains()).filter((t=>t.domain!==e));yield chrome.storage.local.set({[this.EXCLUDED_DOMAIN_KEY]:t})}))}getAllIncludedDomains(){return o(this,void 0,void 0,(function*(){return(yield chrome.storage.local.get(this.INCLUDED_DOMAIN_KEY))[this.INCLUDED_DOMAIN_KEY]||[]}))}addIncludedDomain(e){return o(this,void 0,void 0,(function*(){const t=yield this.getAllIncludedDomains();t.some((t=>t.domain===e))||(t.push({domain:e}),yield chrome.storage.local.set({[this.INCLUDED_DOMAIN_KEY]:t}))}))}removeIncludedDomain(e){return o(this,void 0,void 0,(function*(){const t=(yield this.getAllIncludedDomains()).filter((t=>t.domain!==e));yield chrome.storage.local.set({[this.INCLUDED_DOMAIN_KEY]:t})}))}}}},t={};!function o(n){var i=t[n];if(void 0!==i)return i.exports;var s=t[n]={exports:{}};return e[n].call(s.exports,s,s.exports,o),s.exports}(994)})(); \ No newline at end of file diff --git a/dist/content_script.js b/dist/content_script.js index 42d4102..28a39f5 100644 --- a/dist/content_script.js +++ b/dist/content_script.js @@ -1 +1 @@ -(()=>{"use strict";var e={619:function(e,t,n){var o=this&&this.__awaiter||function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function c(e){try{s(o.next(e))}catch(e){r(e)}}function l(e){try{s(o.throw(e))}catch(e){r(e)}}function s(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(c,l)}s((o=o.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:!0});const i=n(922);function r(e){return o(this,void 0,void 0,(function*(){return new Promise(((t,n)=>{chrome.runtime.sendMessage({type:"save_entry",entry:e},(o=>{chrome.runtime.lastError?(console.error("Runtime error:",chrome.runtime.lastError),n(chrome.runtime.lastError)):o&&"ok"===o.status?(console.log("Saved entry:",e),t()):(console.error("Failed to save:",o),n(new Error("Failed to save entry")))}))}))}))}o(void 0,void 0,void 0,(function*(){var e;const t=window.location.hostname;console.log(`Current domain: ${t}`);const n=yield chrome.storage.local.get(["domainFilterMode","excluded_domains","included_domains"]),c=null!==(e=n.domainFilterMode)&&void 0!==e?e:"exclude",l=n.excluded_domains||[],s=n.included_domains||[];(0,i.checkDomainFilterMode)(c,l,s,t)?(document.addEventListener("scroll",(()=>{const e=document.querySelector('button[data-extension="cliplex"]');e&&document.body.removeChild(e);const t=document.querySelector('button[data-extension="cliplex-sentence"]');t&&document.body.removeChild(t)})),document.addEventListener("click",(e=>{const t=document.querySelector('button[data-extension="cliplex"]'),n=document.querySelector('button[data-extension="cliplex-sentence"]');if(t&&!t.contains(e.target)){const n=t.getBoundingClientRect(),o=50;(e.clientXn.right+o||e.clientYn.bottom+o)&&document.body.removeChild(t)}if(n&&!n.contains(e.target)){const t=n.getBoundingClientRect(),o=50;(e.clientXt.right+o||e.clientYt.bottom+o)&&document.body.removeChild(n)}})),document.addEventListener("mouseup",(()=>{const e=window.getSelection();if(!e)return;const t=e.toString().trim();if(!t)return;const n=e.getRangeAt(0).getBoundingClientRect(),i=document.createElement("button");i.style.position="absolute",i.style.top=`${n.bottom+window.scrollY}px`,i.style.left=`${n.left+window.scrollX}px`,i.style.zIndex="9999",i.style.background="transparent",i.style.border="none",i.style.cursor="pointer";const c=document.createElement("img");c.src=chrome.runtime.getURL("ui/icon.png"),c.alt="保存",c.style.width="24px",c.style.height="24px",i.appendChild(c),i.dataset.extension="cliplex",document.body.appendChild(i);const l=document.createElement("button");l.style.position="absolute",l.style.top=`${n.bottom+window.scrollY}px`,l.style.left=`${n.left+window.scrollX+40}px`,l.style.zIndex="9999",l.style.background="transparent",l.style.border="none",l.style.cursor="pointer";const s=document.createElement("img");s.src=chrome.runtime.getURL("ui/sentence.png"),s.style.width="24px",s.style.height="24px",l.appendChild(s),l.dataset.extension="cliplex-sentence",document.body.appendChild(l),i.addEventListener("click",(()=>o(void 0,void 0,void 0,(function*(){const e={key:t,examples:[],note:"",addedDate:(new Date).toISOString(),priority:3};try{yield r(e),console.log("保存しました in cliplex")}catch(e){console.error("保存に失敗しました in cliplex",e),alert("保存に失敗しました in cliplex")}})))),l.addEventListener("click",(()=>o(void 0,void 0,void 0,(function*(){try{const e=yield function(){return o(this,void 0,void 0,(function*(){return new Promise((e=>{chrome.storage.local.get(["word_entries"],(t=>{const n=t.word_entries||[];e(n)}))}))}))}();let n=0;for(const o of e)t.toLowerCase().includes(o.key.toLowerCase())&&(o.examples.push(t),yield r(o),n++);if(0===n){const e={key:t.split(/\s+/)[0]||t,examples:[t],note:"",addedDate:(new Date).toISOString(),priority:3};yield r(e),console.log("新規ワードを追加:",e)}}catch(e){console.error("画像+sentence処理中にエラー:",e),alert("画像+sentence処理中にエラーが発生しました。")}}))))}))):console.log("Content script blocked for this domain.")}))},922:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.checkDomainFilterMode=function(e,t,n,o){return"exclude"===e?!t.some((e=>e.domain===o)):n.some((e=>e.domain===o))}}},t={};!function n(o){var i=t[o];if(void 0!==i)return i.exports;var r=t[o]={exports:{}};return e[o].call(r.exports,r,r.exports,n),r.exports}(619)})(); \ No newline at end of file +(()=>{"use strict";var e={619:function(e,t,n){var o=this&&this.__awaiter||function(e,t,n,o){return new(n||(n=Promise))((function(i,r){function c(e){try{s(o.next(e))}catch(e){r(e)}}function l(e){try{s(o.throw(e))}catch(e){r(e)}}function s(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(c,l)}s((o=o.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:!0});const i=n(922);function r(e){return o(this,void 0,void 0,(function*(){return new Promise(((t,n)=>{chrome.runtime.sendMessage({type:"save_entry",entry:e},(o=>{chrome.runtime.lastError?(console.error("Runtime error:",chrome.runtime.lastError),n(chrome.runtime.lastError)):o&&"ok"===o.status?(console.log("Saved entry:",e),t()):(console.error("Failed to save:",o),n(new Error("Failed to save entry")))}))}))}))}chrome.runtime.onMessage.addListener(((e,t,n)=>{"CHECK_SCRIPT"===e.type&&n({injected:!0})})),o(void 0,void 0,void 0,(function*(){var e;const t=window.location.hostname;console.log(`Current domain: ${t}`);const n=yield chrome.storage.local.get(["domainFilterMode","excluded_domains","included_domains"]),c=null!==(e=n.domainFilterMode)&&void 0!==e?e:"exclude",l=n.excluded_domains||[],s=n.included_domains||[];(0,i.checkDomainFilterMode)(c,l,s,t)?(document.addEventListener("scroll",(()=>{const e=document.querySelector('button[data-extension="cliplex"]');e&&document.body.removeChild(e);const t=document.querySelector('button[data-extension="cliplex-sentence"]');t&&document.body.removeChild(t)})),document.addEventListener("click",(e=>{const t=document.querySelector('button[data-extension="cliplex"]'),n=document.querySelector('button[data-extension="cliplex-sentence"]');if(t&&!t.contains(e.target)){const n=t.getBoundingClientRect(),o=50;(e.clientXn.right+o||e.clientYn.bottom+o)&&document.body.removeChild(t)}if(n&&!n.contains(e.target)){const t=n.getBoundingClientRect(),o=50;(e.clientXt.right+o||e.clientYt.bottom+o)&&document.body.removeChild(n)}})),document.addEventListener("mouseup",(()=>{const e=window.getSelection();if(!e)return;const t=e.toString().trim();if(!t)return;const n=e.getRangeAt(0).getBoundingClientRect(),i=document.createElement("button");i.style.position="absolute",i.style.top=`${n.bottom+window.scrollY}px`,i.style.left=`${n.left+window.scrollX}px`,i.style.zIndex="9999",i.style.background="transparent",i.style.border="none",i.style.cursor="pointer";const c=document.createElement("img");c.src=chrome.runtime.getURL("ui/icon.png"),c.alt="保存",c.style.width="24px",c.style.height="24px",i.appendChild(c),i.dataset.extension="cliplex",document.body.appendChild(i);const l=document.createElement("button");l.style.position="absolute",l.style.top=`${n.bottom+window.scrollY}px`,l.style.left=`${n.left+window.scrollX+40}px`,l.style.zIndex="9999",l.style.background="transparent",l.style.border="none",l.style.cursor="pointer";const s=document.createElement("img");s.src=chrome.runtime.getURL("ui/sentence.png"),s.style.width="24px",s.style.height="24px",l.appendChild(s),l.dataset.extension="cliplex-sentence",document.body.appendChild(l),i.addEventListener("click",(()=>o(void 0,void 0,void 0,(function*(){const e={key:t,examples:[],note:"",addedDate:(new Date).toISOString(),priority:3};try{yield r(e),console.log("保存しました in cliplex")}catch(e){console.error("保存に失敗しました in cliplex",e),alert("保存に失敗しました in cliplex")}})))),l.addEventListener("click",(()=>o(void 0,void 0,void 0,(function*(){try{const e=yield function(){return o(this,void 0,void 0,(function*(){return new Promise((e=>{chrome.storage.local.get(["word_entries"],(t=>{const n=t.word_entries||[];e(n)}))}))}))}();let n=0;for(const o of e)t.toLowerCase().includes(o.key.toLowerCase())&&(o.examples.push(t),yield r(o),n++);if(0===n){const e={key:t.split(/\s+/)[0]||t,examples:[t],note:"",addedDate:(new Date).toISOString(),priority:3};yield r(e),console.log("新規ワードを追加:",e)}}catch(e){console.error("画像+sentence処理中にエラー:",e),alert("画像+sentence処理中にエラーが発生しました。")}}))))}))):console.log("Content script blocked for this domain.")}))},922:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.checkDomainFilterMode=function(e,t,n,o){return"exclude"===e?!t.some((e=>e.domain===o)):n.some((e=>e.domain===o))}}},t={};!function n(o){var i=t[o];if(void 0!==i)return i.exports;var r=t[o]={exports:{}};return e[o].call(r.exports,r,r.exports,n),r.exports}(619)})(); \ No newline at end of file diff --git a/dist/extention.zip b/dist/extention.zip deleted file mode 100644 index 582842c..0000000 Binary files a/dist/extention.zip and /dev/null differ diff --git a/dist/manifest.json b/dist/manifest.json index b723cec..b2e722d 100644 --- a/dist/manifest.json +++ b/dist/manifest.json @@ -5,13 +5,6 @@ "description": "Improve your English vocabulary with ClipLex", "permissions": ["storage", "activeTab", "scripting"], "options_page": "options/options.html", - "content_scripts": [ - { - "matches": [""], - "js": ["content_script.js"], - "run_at": "document_idle" - } - ], "background": { "service_worker": "background.js" }, diff --git a/privacy_policy.md b/privacy_policy.md index ebe8c1a..0e65bb0 100644 --- a/privacy_policy.md +++ b/privacy_policy.md @@ -34,6 +34,8 @@ - **理由**: ClipLexのスクリプトをウェブページに挿入し、選択されたテキストを取得するために必要です。 3. **`storage`** - **理由**:選択したテキストやフィルタ設定をローカルに保存するために必要です。 +4. **ホスト権限(``)** + - **理由**:activeTabで許可されたタブのすべてのコンテンツにスムーズにClipLexスクリプトを挿入するために必要です。 これらの権限は、本拡張機能の動作に必要な最小限の範囲に限定されています。 diff --git a/src/background.ts b/src/background.ts index 73a0d90..916fa1f 100644 --- a/src/background.ts +++ b/src/background.ts @@ -2,9 +2,22 @@ import { LocalDatabase } from "./database"; chrome.action.onClicked.addListener((tab) => { if (tab.id && tab.url) { - chrome.scripting.executeScript({ - target: { tabId: tab.id }, - files: ["content_script.js"], // 動的に注入するスクリプト + chrome.tabs.sendMessage(tab.id, { type: "CHECK_SCRIPT" }, (response) => { + if (chrome.runtime.lastError || !response || !response.injected) { + // スクリプトが未注入の場合、注入する + chrome.scripting.executeScript({ + target: { tabId: tab.id! }, + files: ["content_script.js"], + }) + .then(() => { + console.log("Content script injected successfully."); + }) + .catch(err => { + console.error("Failed to inject content script:", err); + }); + } else { + console.log("Content script already injected."); + } }); } }); diff --git a/src/content_script.ts b/src/content_script.ts index 311e763..5c4390b 100644 --- a/src/content_script.ts +++ b/src/content_script.ts @@ -1,5 +1,11 @@ import { checkDomainFilterMode } from "./content_script_helper"; +chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { + if (message.type === "CHECK_SCRIPT") { + sendResponse({ injected: true }); + } +}); + // 既存: background.ts と通信して save するための Promiseラッパー関数 async function saveEntryToBackground(entry: WordEntry): Promise { return new Promise((resolve, reject) => { diff --git a/src/manifest.json b/src/manifest.json index b723cec..b2e722d 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -5,13 +5,6 @@ "description": "Improve your English vocabulary with ClipLex", "permissions": ["storage", "activeTab", "scripting"], "options_page": "options/options.html", - "content_scripts": [ - { - "matches": [""], - "js": ["content_script.js"], - "run_at": "document_idle" - } - ], "background": { "service_worker": "background.js" },