diff --git a/.gitignore b/.gitignore index 4788c7a..681614b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ node_modules/ dist/ .DS_Store + +extension/dist diff --git a/calcit.cirru b/calcit.cirru index 090fe46..2dab6de 100644 --- a/calcit.cirru +++ b/calcit.cirru @@ -860,7 +860,7 @@ :data $ {} |T $ %{} :Leaf (:at 1722409346610) (:by |rJG4IHzWf) (:text |cursor) |b $ %{} :Leaf (:at 1722409346610) (:by |rJG4IHzWf) (:text |state) - |e $ %{} :Leaf (:at 1722536402711) (:by |rJG4IHzWf) (:text |prompt-test) + |e $ %{} :Leaf (:at 1723105757947) (:by |rJG4IHzWf) (:text |prompt-text) |h $ %{} :Leaf (:at 1722410766404) (:by |rJG4IHzWf) (:text |d!) |l $ %{} :Expr (:at 1722409347984) (:by |rJG4IHzWf) :data $ {} @@ -881,7 +881,7 @@ |D $ %{} :Leaf (:at 1722536657601) (:by |rJG4IHzWf) (:text |do) |L $ %{} :Expr (:at 1722536659137) (:by |rJG4IHzWf) :data $ {} - |T $ %{} :Leaf (:at 1722536663086) (:by |rJG4IHzWf) (:text |js/console.log) + |T $ %{} :Leaf (:at 1723105985253) (:by |rJG4IHzWf) (:text |js/console.warn) |b $ %{} :Leaf (:at 1722536669226) (:by |rJG4IHzWf) (:text "|\"Aborting prev") |T $ %{} :Expr (:at 1722536625917) (:by |rJG4IHzWf) :data $ {} @@ -910,6 +910,31 @@ |T $ %{} :Leaf (:at 1722409352561) (:by |rJG4IHzWf) (:text |let) |b $ %{} :Expr (:at 1722409352561) (:by |rJG4IHzWf) :data $ {} + |D $ %{} :Expr (:at 1723105003222) (:by |rJG4IHzWf) + :data $ {} + |T $ %{} :Leaf (:at 1723105005485) (:by |rJG4IHzWf) (:text |selected) + |b $ %{} :Expr (:at 1723105009538) (:by |rJG4IHzWf) + :data $ {} + |D $ %{} :Leaf (:at 1723105011568) (:by |rJG4IHzWf) (:text |w-js-log) + |T $ %{} :Expr (:at 1723105005806) (:by |rJG4IHzWf) + :data $ {} + |T $ %{} :Leaf (:at 1723105008294) (:by |rJG4IHzWf) (:text |js-await) + |b $ %{} :Expr (:at 1723105137971) (:by |rJG4IHzWf) + :data $ {} + |T $ %{} :Leaf (:at 1723105008656) (:by |rJG4IHzWf) (:text |get-selected) + |L $ %{} :Expr (:at 1723105744388) (:by |rJG4IHzWf) + :data $ {} + |T $ %{} :Leaf (:at 1723105749368) (:by |rJG4IHzWf) (:text |content) + |b $ %{} :Expr (:at 1723105750725) (:by |rJG4IHzWf) + :data $ {} + |T $ %{} :Leaf (:at 1723105752174) (:by |rJG4IHzWf) (:text |.replace) + |b $ %{} :Leaf (:at 1723105759695) (:by |rJG4IHzWf) (:text |prompt-text) + |h $ %{} :Leaf (:at 1723105766407) (:by |rJG4IHzWf) (:text "|\"{{selected}}") + |l $ %{} :Expr (:at 1723105777610) (:by |rJG4IHzWf) + :data $ {} + |D $ %{} :Leaf (:at 1723105791996) (:by |rJG4IHzWf) (:text |or) + |T $ %{} :Leaf (:at 1723105771630) (:by |rJG4IHzWf) (:text |selected) + |b $ %{} :Leaf (:at 1723105788710) (:by |rJG4IHzWf) (:text "|\"<未找到内容>") |T $ %{} :Expr (:at 1722409352561) (:by |rJG4IHzWf) :data $ {} |T $ %{} :Leaf (:at 1722409352561) (:by |rJG4IHzWf) (:text |result) @@ -952,7 +977,7 @@ |b $ %{} :Expr (:at 1722410582786) (:by |rJG4IHzWf) :data $ {} |T $ %{} :Leaf (:at 1722410582786) (:by |rJG4IHzWf) (:text |:text) - |b $ %{} :Leaf (:at 1722536405448) (:by |rJG4IHzWf) (:text |prompt-test) + |b $ %{} :Leaf (:at 1723105794657) (:by |rJG4IHzWf) (:text |content) |b $ %{} :Expr (:at 1722410320737) (:by |rJG4IHzWf) :data $ {} |T $ %{} :Leaf (:at 1722410323567) (:by |rJG4IHzWf) (:text |js-object) @@ -1309,6 +1334,13 @@ :data $ {} |T $ %{} :Leaf (:at 1722481924530) (:by |rJG4IHzWf) (:text |comp-copy) |b $ %{} :Leaf (:at 1722965064837) (:by |rJG4IHzWf) (:text |comp-close) + |ze $ %{} :Expr (:at 1723104975584) (:by |rJG4IHzWf) + :data $ {} + |T $ %{} :Leaf (:at 1723104991690) (:by |rJG4IHzWf) (:text "|\"../extension/get-selected") + |b $ %{} :Leaf (:at 1723104992655) (:by |rJG4IHzWf) (:text |:refer) + |h $ %{} :Expr (:at 1723104992888) (:by |rJG4IHzWf) + :data $ {} + |T $ %{} :Leaf (:at 1723105000472) (:by |rJG4IHzWf) (:text |get-selected) |app.config $ %{} :FileEntry :defs $ {} |dev? $ %{} :CodeEntry (:doc |) diff --git a/compact.cirru b/compact.cirru index 0e20c1c..38e8bcf 100644 --- a/compact.cirru +++ b/compact.cirru @@ -131,19 +131,22 @@ "\"&:focus-within" $ {} (:height "\"260px") |submit-message! $ %{} :CodeEntry (:doc |) :code $ quote - defn submit-message! (cursor state prompt-test d!) (hint-fn async) + defn submit-message! (cursor state prompt-text d!) (hint-fn async) if-let abort $ deref *abort-control - do (js/console.log "\"Aborting prev") (.!abort abort) + do (js/console.warn "\"Aborting prev") (.!abort abort) d! cursor $ -> state (assoc :answer nil) (assoc :loading? true) let + selected $ w-js-log + js-await $ get-selected + content $ .replace prompt-text "\"{{selected}}" (or selected "\"<未找到内容>") result $ js-await .!post axios str "\"https://sf.chenyong.life/v1beta/models/" (pick-model) "\":streamGenerateContent" js-object $ :contents js-array $ js-object :parts $ js-array - js-object $ :text prompt-test + js-object $ :text content js-object :params $ js-object :key $ get-gemini-key! @@ -189,6 +192,7 @@ "\"axios" :default axios respo-md.comp.md :refer $ comp-md-block style-code-block respo-ui.comp :refer $ comp-copy comp-close + "\"../extension/get-selected" :refer $ get-selected |app.config $ %{} :FileEntry :defs $ {} |dev? $ %{} :CodeEntry (:doc |) diff --git a/extension/content.js b/extension/content.js new file mode 100644 index 0000000..1622aeb --- /dev/null +++ b/extension/content.js @@ -0,0 +1,24 @@ +// Listen for messages +chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) { + // If the received message has the expected format... + console.log("[Side Message] msg", msg) + if (msg.get === 'selected') { + // Call the specified callback, passing + // the web-page's DOM content as argument + sendResponse(getSelectedText()); + } +}); + +let getSelectedText = () => { + if (window.getSelection) { + // 标准浏览器 + return window.getSelection().toString(); + } else if (document.selection) { + // IE 浏览器 + return document.selection.createRange().text; + } else { + return "<未获取到内容>"; + } +} + +console.log("[Side Message] prepared content script") \ No newline at end of file diff --git a/extension/get-selected.mjs b/extension/get-selected.mjs new file mode 100644 index 0000000..fe525c5 --- /dev/null +++ b/extension/get-selected.mjs @@ -0,0 +1,58 @@ + +export let get_selected = () => { + return new Promise((resolve, reject) => { + if (chrome?.runtime?.id == null) { + console.warn("not chrome extension runtime...") + resolve(null) + return + } + console.log("calling content script...") + chrome.tabs.query({active: true, currentWindow: true}) + .then(x => { + let activeTab = x[0] + if (activeTab) { + let id = activeTab.id + chrome.tabs.sendMessage(id, {get: 'selected'}, function(response) { + // 接收来自 content.js 的返回数据 + // console.info('Content script returned: ' + response); + resolve(response) + }); + + } else { + reject("found not active tab") + } + }).catch((error) => { + console.error("Error", error) + }) + }) +} + + +// setTimeout(()=>{ +// chrome.tabs.query({active: true, currentWindow: true}).then(x => { +// let activeTab = x[0] +// if (activeTab) { +// let id = activeTab.id +// chrome.tabs.sendMessage(id, {get: 'selected'}, function(response) { +// // 接收来自 content.js 的返回数据 +// console.info('Content script returned: ' + response); +// }); + +// } else { +// throw Error("no active tab found") +// } +// }) +// }, 2000) + + +// chrome.scripting.executeScript({ +// target: { tabId: 1201634844 }, +// function: () => { console.log(document.body.innerText) } +// }); + + +// chrome.tabs.sendMessage(1201634844, {get: 'selected'}, function(response) { +// // 接收来自 content.js 的返回数据 +// console.info('Content script returned: ' + response.message); +// }); + diff --git a/extension/manifest.json b/extension/manifest.json new file mode 100644 index 0000000..df3dbe9 --- /dev/null +++ b/extension/manifest.json @@ -0,0 +1,22 @@ + +{ + "manifest_version": 3, + "name": "Side message", + "version": "1.0", + "description": "Shows how to display the same side panel on every site using the Side Panel API.", + "background": { + "service_worker": "service-worker.js" + }, + "action": { + "default_title": "Click to open panel" + }, + "content_scripts": [{ + "matches": [""], + "match_origin_as_fallback": true, + "js": ["content.js"] + }], + "side_panel": { + "default_path": "dist/index.html" + }, + "permissions": ["sidePanel", "scripting", "activeTab", "tabs"] +} diff --git a/extension/service-worker.js b/extension/service-worker.js new file mode 100644 index 0000000..4229606 --- /dev/null +++ b/extension/service-worker.js @@ -0,0 +1,3 @@ +chrome.runtime.onInstalled.addListener(() => { + chrome.sidePanel.setPanelBehavior({ openPanelOnActionClick: true }); +}); \ No newline at end of file diff --git a/package.json b/package.json index 6e52b9c..f7b3e36 100644 --- a/package.json +++ b/package.json @@ -10,5 +10,8 @@ "bottom-tip": "^0.1.5", "vite": "^5.3.5" }, + "scripts": { + "build": "yarn vite build --base ./ && rm -rfv extension/dist && cp -vr dist extension/" + }, "version": "0.0.1" }