From 2e2d0929b8a1a1ad460e4389f80c1caf8dd60e17 Mon Sep 17 00:00:00 2001 From: Jos Storer Date: Tue, 6 Dec 2022 13:13:35 +0800 Subject: [PATCH 01/11] add support for more search engines --- README.md | 2 +- src/content-script/index.mjs | 70 +++++++++++++++++++++++++----------- src/content-script/utils.mjs | 35 ++++++++++++++++++ src/manifest.json | 35 ++++++++++++++---- src/manifest.v2.json | 40 ++++++++++++++++----- 5 files changed, 145 insertions(+), 37 deletions(-) create mode 100644 src/content-script/utils.mjs diff --git a/README.md b/README.md index b291957f..a8f26413 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ChatGPT for Google -A browser extension to display ChatGPT response alongside Google Search results, supports Chrome/Edge/Firefox +A browser extension to display ChatGPT response alongside Search Engine results, supports Chrome/Edge/Firefox ![Screenshot](screenshot.jpg?raw=true) diff --git a/src/content-script/index.mjs b/src/content-script/index.mjs index d3fe153c..3bc3a527 100644 --- a/src/content-script/index.mjs +++ b/src/content-script/index.mjs @@ -1,38 +1,66 @@ -import Browser from "webextension-polyfill"; +import Browser from 'webextension-polyfill' +import {getPossibleElementByClassArray, getPossibleElementByIdArray, getPossibleElementByNameArray} from './utils.mjs' + +const config = { + // input element name of search box + inputName: ['q', 'wd', 'text', 'query', 'p'], + // prepend child to + sidebarContainerId: [ + 'rhs', 'content_right', 'b_rrsr', 'search-result-aside', 'b_context', 'right', 'sub_pack' + ], + // if above ids not exist, prepend child to + sidebarContainerClass: [ + 'right-content-box _0_right_sidebar', 'results--sidebar js-results-sidebar', 'layout-web__sidebar layout-web__sidebar--web', + 'Contents__inner Contents__inner--sub' + ], + // if above all not exist, append child to + appendContainerId: [ + 'rcnt', '_0_app_content', 'content__left', 'container', 'content', 'main', 'contents__wrap', 'cols', 'links_wrapper', 'wrapper' + ], + // if above all not exist, append child to + appendContainerClass: [ + 'content__left', 'layout-web__body layout-web__body--desktop' + ] +} async function run(question) { - const container = document.createElement("div"); - container.className = "chat-gpt-container"; - container.innerHTML = '

Waiting for ChatGPT response...

'; + const container = document.createElement('div') + container.className = 'chat-gpt-container' + container.innerHTML = '

Waiting for ChatGPT response...

' - const siderbarContainer = document.getElementById("rhs"); + const siderbarContainer = + getPossibleElementByIdArray(config.sidebarContainerId) + || getPossibleElementByClassArray(config.sidebarContainerClass) if (siderbarContainer) { - siderbarContainer.prepend(container); + siderbarContainer.prepend(container) } else { - container.classList.add("sidebar-free"); - document.getElementById("rcnt").appendChild(container); + container.classList.add('sidebar-free') + const appendContainer = + getPossibleElementByIdArray(config.appendContainerId) + || getPossibleElementByClassArray(config.appendContainerClass) + if (appendContainer) + appendContainer.appendChild(container) } - - const port = Browser.runtime.connect(); + const port = Browser.runtime.connect() port.onMessage.addListener(function (msg) { if (msg.answer) { - container.innerHTML = '

ChatGPT:

'; - container.querySelector("pre").textContent = msg.answer; - } else if (msg.error === "UNAUTHORIZED") { + container.innerHTML = '

ChatGPT:

' + container.querySelector('pre').textContent = msg.answer + } else if (msg.error === 'UNAUTHORIZED') { container.innerHTML = - '

Please login at chat.openai.com first

'; + '

Please login at chat.openai.com first

' } else { - container.innerHTML = "

Failed to load response from ChatGPT

"; + container.innerHTML = '

Failed to load response from ChatGPT

' } - }); - port.postMessage({ question }); + }) + port.postMessage({question}) } -const searchInput = document.getElementsByName("q")[0]; +const searchInput = getPossibleElementByNameArray(config.inputName) if (searchInput && searchInput.value) { // only run on first page - const startParam = new URL(location.href).searchParams.get("start") || "0"; - if (startParam === "0") { - run(searchInput.value); + const startParam = new URL(location.href).searchParams.get('start') || '0' + if (startParam === '0') { + run(searchInput.value) } } diff --git a/src/content-script/utils.mjs b/src/content-script/utils.mjs new file mode 100644 index 00000000..3b56f6a3 --- /dev/null +++ b/src/content-script/utils.mjs @@ -0,0 +1,35 @@ +export function getPossibleElementByNameArray(elementNameArray) { + let element + elementNameArray.some( + (e) => { + element = document.getElementsByName(e)[0] + if (element) + return true + } + ) + return element +} + +export function getPossibleElementByIdArray(elementIdArray) { + let element + elementIdArray.some( + (e) => { + element = document.getElementById(e) + if (element) + return true + } + ) + return element +} + +export function getPossibleElementByClassArray(elementClassArray) { + let element + elementClassArray.some( + (e) => { + element = document.getElementsByClassName(e)[0] + if (element) + return true + } + ) + return element +} \ No newline at end of file diff --git a/src/manifest.json b/src/manifest.json index 15beee01..9b99261e 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -1,7 +1,7 @@ { "name": "ChatGPT for Google", - "description": "Display ChatGPT response alongside Google Search results", - "version": "1.1.0", + "description": "Display ChatGPT response alongside Search Engine results", + "version": "1.2.0", "manifest_version": 3, "icons": { "16": "logo.png", @@ -9,16 +9,37 @@ "48": "logo.png", "128": "logo.png" }, - "host_permissions": ["https://*.openai.com/"], + "host_permissions": [ + "https://*.openai.com/" + ], "background": { "service_worker": "background/index.js" }, "content_scripts": [ { - "matches": ["https://*/search*"], - "include_globs": ["*.google.*/*"], - "js": ["content-script/index.js"], - "css": ["styles.css"] + "matches": [ + "https://*/search*", + "https://duckduckgo.com/*q=*", + "https://*.startpage.com/sp/search*", + "https://*.baidu.com/s*wd=*" + ], + "include_globs": [ + "https://*.google.*/*", + "https://kagi.*/*", + "https://*.bing.*/*", + "https://*.yahoo.*/*", + "https://*.naver.*/*", + "https://yandex.*/*", + "https://duckduckgo.*", + "https://*.startpage.*/*", + "https://*.baidu.*" + ], + "js": [ + "content-script/index.js" + ], + "css": [ + "styles.css" + ] } ] } diff --git a/src/manifest.v2.json b/src/manifest.v2.json index 31c4d05c..5866550d 100644 --- a/src/manifest.v2.json +++ b/src/manifest.v2.json @@ -1,7 +1,7 @@ { "name": "ChatGPT for Google", - "description": "Display ChatGPT response alongside Google Search results", - "version": "1.1.0", + "description": "Display ChatGPT response alongside Search Engine results", + "version": "1.2.0", "manifest_version": 2, "icons": { "16": "logo.png", @@ -9,16 +9,40 @@ "48": "logo.png", "128": "logo.png" }, - "permissions": ["webRequest", "https://*.openai.com/"], + "permissions": [ + "webRequest", + "https://*.openai.com/" + ], "background": { - "scripts": ["background/index.js"] + "scripts": [ + "background/index.js" + ] }, "content_scripts": [ { - "matches": ["https://*/search*"], - "include_globs": ["*.google.*/*"], - "js": ["content-script/index.js"], - "css": ["styles.css"] + "matches": [ + "https://*/search*", + "https://duckduckgo.com/*q=*", + "https://*.startpage.com/sp/search*", + "https://*.baidu.com/s*wd=*" + ], + "include_globs": [ + "https://*.google.*/*", + "https://kagi.*/*", + "https://*.bing.*/*", + "https://*.yahoo.*/*", + "https://*.naver.*/*", + "https://yandex.*/*", + "https://duckduckgo.*", + "https://*.startpage.*/*", + "https://*.baidu.*" + ], + "js": [ + "content-script/index.js" + ], + "css": [ + "styles.css" + ] } ] } From bb9968afe9a9054649fa6043330b1ca9ea943e9d Mon Sep 17 00:00:00 2001 From: Jos Storer Date: Tue, 6 Dec 2022 22:29:11 +0800 Subject: [PATCH 02/11] support brave, searx, ecosia --- src/content-script/index.mjs | 5 +++-- src/manifest.json | 4 ++++ src/manifest.v2.json | 4 ++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/content-script/index.mjs b/src/content-script/index.mjs index 3bc3a527..82fdd0fb 100644 --- a/src/content-script/index.mjs +++ b/src/content-script/index.mjs @@ -6,12 +6,13 @@ const config = { inputName: ['q', 'wd', 'text', 'query', 'p'], // prepend child to sidebarContainerId: [ - 'rhs', 'content_right', 'b_rrsr', 'search-result-aside', 'b_context', 'right', 'sub_pack' + 'rhs', 'content_right', 'b_rrsr', 'search-result-aside', 'b_context', 'right', 'sub_pack', 'sidebar_results', + 'side-right' ], // if above ids not exist, prepend child to sidebarContainerClass: [ 'right-content-box _0_right_sidebar', 'results--sidebar js-results-sidebar', 'layout-web__sidebar layout-web__sidebar--web', - 'Contents__inner Contents__inner--sub' + 'Contents__inner Contents__inner--sub', 'sidebar web__sidebar' ], // if above all not exist, append child to appendContainerId: [ diff --git a/src/manifest.json b/src/manifest.json index 9b99261e..42e31408 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -29,6 +29,10 @@ "https://*.bing.*/*", "https://*.yahoo.*/*", "https://*.naver.*/*", + "https://*.brave.*/*", + "https://*.ecosia.org/*", + "https://searx.be/*", + "https://www.searx.be/*", "https://yandex.*/*", "https://duckduckgo.*", "https://*.startpage.*/*", diff --git a/src/manifest.v2.json b/src/manifest.v2.json index 5866550d..365c7f13 100644 --- a/src/manifest.v2.json +++ b/src/manifest.v2.json @@ -32,6 +32,10 @@ "https://*.bing.*/*", "https://*.yahoo.*/*", "https://*.naver.*/*", + "https://*.brave.*/*", + "https://*.ecosia.org/*", + "https://searx.be/*", + "https://www.searx.be/*", "https://yandex.*/*", "https://duckduckgo.*", "https://*.startpage.*/*", From c4e4708eac006d650273802bed3995d696cd55eb Mon Sep 17 00:00:00 2001 From: Jos Storer Date: Wed, 7 Dec 2022 15:39:30 +0800 Subject: [PATCH 03/11] update code style for more clear PR --- src/content-script/index.mjs | 61 ++++++++++++++++++------------------ src/content-script/utils.mjs | 30 +++++++++--------- 2 files changed, 46 insertions(+), 45 deletions(-) diff --git a/src/content-script/index.mjs b/src/content-script/index.mjs index 82fdd0fb..1d515380 100644 --- a/src/content-script/index.mjs +++ b/src/content-script/index.mjs @@ -1,67 +1,68 @@ -import Browser from 'webextension-polyfill' -import {getPossibleElementByClassArray, getPossibleElementByIdArray, getPossibleElementByNameArray} from './utils.mjs' +import Browser from "webextension-polyfill"; +import {getPossibleElementByClassArray, getPossibleElementByIdArray, getPossibleElementByNameArray} from "./utils.mjs" const config = { // input element name of search box - inputName: ['q', 'wd', 'text', 'query', 'p'], + inputName: ["q", "wd", "text", "query", "p"], // prepend child to sidebarContainerId: [ - 'rhs', 'content_right', 'b_rrsr', 'search-result-aside', 'b_context', 'right', 'sub_pack', 'sidebar_results', - 'side-right' + "rhs", "content_right", "b_rrsr", "search-result-aside", "b_context", "right", "sub_pack", "sidebar_results", + "side-right" ], // if above ids not exist, prepend child to sidebarContainerClass: [ - 'right-content-box _0_right_sidebar', 'results--sidebar js-results-sidebar', 'layout-web__sidebar layout-web__sidebar--web', - 'Contents__inner Contents__inner--sub', 'sidebar web__sidebar' + "right-content-box _0_right_sidebar", "results--sidebar js-results-sidebar", "layout-web__sidebar layout-web__sidebar--web", + "Contents__inner Contents__inner--sub", "sidebar web__sidebar" ], // if above all not exist, append child to appendContainerId: [ - 'rcnt', '_0_app_content', 'content__left', 'container', 'content', 'main', 'contents__wrap', 'cols', 'links_wrapper', 'wrapper' + "rcnt", "_0_app_content", "content__left", "container", "content", "main", "contents__wrap", "cols", "links_wrapper", "wrapper" ], // if above all not exist, append child to appendContainerClass: [ - 'content__left', 'layout-web__body layout-web__body--desktop' + "content__left", "layout-web__body layout-web__body--desktop" ] } async function run(question) { - const container = document.createElement('div') - container.className = 'chat-gpt-container' - container.innerHTML = '

Waiting for ChatGPT response...

' + const container = document.createElement("div"); + container.className = "chat-gpt-container"; + container.innerHTML = '

Waiting for ChatGPT response...

'; const siderbarContainer = getPossibleElementByIdArray(config.sidebarContainerId) - || getPossibleElementByClassArray(config.sidebarContainerClass) + || getPossibleElementByClassArray(config.sidebarContainerClass); if (siderbarContainer) { - siderbarContainer.prepend(container) + siderbarContainer.prepend(container); } else { - container.classList.add('sidebar-free') + container.classList.add("sidebar-free"); const appendContainer = getPossibleElementByIdArray(config.appendContainerId) - || getPossibleElementByClassArray(config.appendContainerClass) + || getPossibleElementByClassArray(config.appendContainerClass); if (appendContainer) - appendContainer.appendChild(container) + appendContainer.appendChild(container); } - const port = Browser.runtime.connect() + + const port = Browser.runtime.connect(); port.onMessage.addListener(function (msg) { if (msg.answer) { - container.innerHTML = '

ChatGPT:

' - container.querySelector('pre').textContent = msg.answer - } else if (msg.error === 'UNAUTHORIZED') { + container.innerHTML = '

ChatGPT:

'; + container.querySelector("pre").textContent = msg.answer; + } else if (msg.error === "UNAUTHORIZED") { container.innerHTML = - '

Please login at chat.openai.com first

' + '

Please login at chat.openai.com first

'; } else { - container.innerHTML = '

Failed to load response from ChatGPT

' + container.innerHTML = "

Failed to load response from ChatGPT

"; } - }) - port.postMessage({question}) + }); + port.postMessage({ question }); } -const searchInput = getPossibleElementByNameArray(config.inputName) +const searchInput = getPossibleElementByNameArray(config.inputName); if (searchInput && searchInput.value) { // only run on first page - const startParam = new URL(location.href).searchParams.get('start') || '0' - if (startParam === '0') { - run(searchInput.value) + const startParam = new URL(location.href).searchParams.get("start") || "0"; + if (startParam === "0") { + run(searchInput.value); } -} +} \ No newline at end of file diff --git a/src/content-script/utils.mjs b/src/content-script/utils.mjs index 3b56f6a3..663b8fbe 100644 --- a/src/content-script/utils.mjs +++ b/src/content-script/utils.mjs @@ -1,35 +1,35 @@ export function getPossibleElementByNameArray(elementNameArray) { - let element + let element; elementNameArray.some( (e) => { - element = document.getElementsByName(e)[0] + element = document.getElementsByName(e)[0]; if (element) - return true + return true; } - ) - return element + ); + return element; } export function getPossibleElementByIdArray(elementIdArray) { - let element + let element; elementIdArray.some( (e) => { - element = document.getElementById(e) + element = document.getElementById(e); if (element) - return true + return true; } - ) - return element + ); + return element; } export function getPossibleElementByClassArray(elementClassArray) { - let element + let element; elementClassArray.some( (e) => { - element = document.getElementsByClassName(e)[0] + element = document.getElementsByClassName(e)[0]; if (element) - return true + return true; } - ) - return element + ); + return element; } \ No newline at end of file From 9a957c5d55cca3df410878aefa7985e750ab44bb Mon Sep 17 00:00:00 2001 From: Jos Storer Date: Thu, 8 Dec 2022 11:33:24 +0800 Subject: [PATCH 04/11] resolve conflicts in PR --- src/manifest.json | 16 +++++----------- src/manifest.v2.json | 21 ++++++--------------- 2 files changed, 11 insertions(+), 26 deletions(-) diff --git a/src/manifest.json b/src/manifest.json index 42e31408..8858c869 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -1,7 +1,7 @@ { - "name": "ChatGPT for Google", + "name": "ChatGPT for Search Engine", "description": "Display ChatGPT response alongside Search Engine results", - "version": "1.2.0", + "version": "1.3.0", "manifest_version": 3, "icons": { "16": "logo.png", @@ -9,9 +9,7 @@ "48": "logo.png", "128": "logo.png" }, - "host_permissions": [ - "https://*.openai.com/" - ], + "host_permissions": ["https://*.openai.com/"], "background": { "service_worker": "background/index.js" }, @@ -38,12 +36,8 @@ "https://*.startpage.*/*", "https://*.baidu.*" ], - "js": [ - "content-script/index.js" - ], - "css": [ - "styles.css" - ] + "js": ["content-script/index.js"], + "css": ["github-markdown.css", "styles.css"] } ] } diff --git a/src/manifest.v2.json b/src/manifest.v2.json index 365c7f13..91ebe00d 100644 --- a/src/manifest.v2.json +++ b/src/manifest.v2.json @@ -1,7 +1,7 @@ { - "name": "ChatGPT for Google", + "name": "ChatGPT for Search Engine", "description": "Display ChatGPT response alongside Search Engine results", - "version": "1.2.0", + "version": "1.3.0", "manifest_version": 2, "icons": { "16": "logo.png", @@ -9,14 +9,9 @@ "48": "logo.png", "128": "logo.png" }, - "permissions": [ - "webRequest", - "https://*.openai.com/" - ], + "permissions": ["webRequest", "https://*.openai.com/"], "background": { - "scripts": [ - "background/index.js" - ] + "scripts": ["background/index.js"] }, "content_scripts": [ { @@ -41,12 +36,8 @@ "https://*.startpage.*/*", "https://*.baidu.*" ], - "js": [ - "content-script/index.js" - ], - "css": [ - "styles.css" - ] + "js": ["content-script/index.js"], + "css": ["github-markdown.css", "styles.css"] } ] } From df7b43aae9f4affb418af92ad412355570309802 Mon Sep 17 00:00:00 2001 From: Jos Storer Date: Thu, 8 Dec 2022 13:29:03 +0800 Subject: [PATCH 05/11] update config to make it more flexible and readable --- src/content-script/engine-match-config.mjs | 97 ++++++++++++++++++++++ src/content-script/index.mjs | 38 +++------ 2 files changed, 107 insertions(+), 28 deletions(-) create mode 100644 src/content-script/engine-match-config.mjs diff --git a/src/content-script/engine-match-config.mjs b/src/content-script/engine-match-config.mjs new file mode 100644 index 00000000..5b9cd46e --- /dev/null +++ b/src/content-script/engine-match-config.mjs @@ -0,0 +1,97 @@ +/** + * @typedef {object} SiteConfig + * @property {string[]} inputName - input element name of search box + * @property {string[]} sidebarContainerId - prepend child to + * @property {string[]} sidebarContainerClass - if above ids not exist, prepend child to + * @property {string[]} appendContainerId - if above all not exist, append child to + * @property {string[]} appendContainerClass - if above all not exist, append child to + */ +/** + * @type {Object.} + */ +export const config = { + google: { + inputName: ["q"], + sidebarContainerId: ["rhs"], + sidebarContainerClass: [], + appendContainerId: ["rcnt"], + appendContainerClass: [] + }, + bing: { + inputName: ["q"], + sidebarContainerId: ["b_context"], + sidebarContainerClass: [], + appendContainerId: [], + appendContainerClass: [] + }, + yahoo: { + inputName: ["p"], + sidebarContainerId: ["right"], + sidebarContainerClass: ["Contents__inner Contents__inner--sub"], + appendContainerId: ["cols", "contents__wrap"], // and yahoo jp + appendContainerClass: [] + }, + duckduckgo: { + inputName: ["q"], + sidebarContainerId: [], + sidebarContainerClass: ["results--sidebar js-results-sidebar"], + appendContainerId: ["links_wrapper"], + appendContainerClass: [] + }, + startpage: { + inputName: ["query"], + sidebarContainerId: [], + sidebarContainerClass: ["layout-web__sidebar layout-web__sidebar--web"], + appendContainerId: [], + appendContainerClass: ["layout-web__body layout-web__body--desktop"] + }, + baidu: { + inputName: ["wd"], + sidebarContainerId: ["content_right"], + sidebarContainerClass: [], + appendContainerId: ["container"], + appendContainerClass: [] + }, + kagi: { + inputName: ["q"], + sidebarContainerId: [], + sidebarContainerClass: ["right-content-box _0_right_sidebar"], + appendContainerId: ["_0_app_content"], + appendContainerClass: [] + }, + yandex: { + inputName: ["text"], + sidebarContainerId: ["search-result-aside"], + sidebarContainerClass: [], + appendContainerId: [], + appendContainerClass: [] + }, + naver: { + inputName: ["query"], + sidebarContainerId: ["sub_pack"], + sidebarContainerClass: [], + appendContainerId: ["content"], + appendContainerClass: [] + }, + brave: { + inputName: ["q"], + sidebarContainerId: ["side-right"], + sidebarContainerClass: [], + appendContainerId: [], + appendContainerClass: [] + }, + searx: { + inputName: ["q"], + sidebarContainerId: ["sidebar_results"], + sidebarContainerClass: [], + appendContainerId: [], + appendContainerClass: [] + }, + ecosia: { + inputName: ["q"], + sidebarContainerId: [], + sidebarContainerClass: ["sidebar web__sidebar"], + appendContainerId: ["main"], + appendContainerClass: [] + } +} \ No newline at end of file diff --git a/src/content-script/index.mjs b/src/content-script/index.mjs index 1d515380..6c947497 100644 --- a/src/content-script/index.mjs +++ b/src/content-script/index.mjs @@ -1,28 +1,6 @@ import Browser from "webextension-polyfill"; import {getPossibleElementByClassArray, getPossibleElementByIdArray, getPossibleElementByNameArray} from "./utils.mjs" - -const config = { - // input element name of search box - inputName: ["q", "wd", "text", "query", "p"], - // prepend child to - sidebarContainerId: [ - "rhs", "content_right", "b_rrsr", "search-result-aside", "b_context", "right", "sub_pack", "sidebar_results", - "side-right" - ], - // if above ids not exist, prepend child to - sidebarContainerClass: [ - "right-content-box _0_right_sidebar", "results--sidebar js-results-sidebar", "layout-web__sidebar layout-web__sidebar--web", - "Contents__inner Contents__inner--sub", "sidebar web__sidebar" - ], - // if above all not exist, append child to - appendContainerId: [ - "rcnt", "_0_app_content", "content__left", "container", "content", "main", "contents__wrap", "cols", "links_wrapper", "wrapper" - ], - // if above all not exist, append child to - appendContainerClass: [ - "content__left", "layout-web__body layout-web__body--desktop" - ] -} +import {config} from "./engine-match-config.mjs" async function run(question) { const container = document.createElement("div"); @@ -30,15 +8,15 @@ async function run(question) { container.innerHTML = '

Waiting for ChatGPT response...

'; const siderbarContainer = - getPossibleElementByIdArray(config.sidebarContainerId) - || getPossibleElementByClassArray(config.sidebarContainerClass); + getPossibleElementByIdArray(config[siteName].sidebarContainerId) + || getPossibleElementByClassArray(config[siteName].sidebarContainerClass); if (siderbarContainer) { siderbarContainer.prepend(container); } else { container.classList.add("sidebar-free"); const appendContainer = - getPossibleElementByIdArray(config.appendContainerId) - || getPossibleElementByClassArray(config.appendContainerClass); + getPossibleElementByIdArray(config[siteName].appendContainerId) + || getPossibleElementByClassArray(config[siteName].appendContainerClass); if (appendContainer) appendContainer.appendChild(container); } @@ -58,7 +36,11 @@ async function run(question) { port.postMessage({ question }); } -const searchInput = getPossibleElementByNameArray(config.inputName); +const siteName = document.location.hostname + .replace("www.", "").replace("search.", "") + .match(/(.+?)\./)[1] + +const searchInput = getPossibleElementByNameArray(config[siteName].inputName); if (searchInput && searchInput.value) { // only run on first page const startParam = new URL(location.href).searchParams.get("start") || "0"; From dbe6643b4c35ed9e07b8984cf1b62a44bd621941 Mon Sep 17 00:00:00 2001 From: Jos Storer Date: Thu, 8 Dec 2022 14:23:38 +0800 Subject: [PATCH 06/11] update siteName for cn.bing.com --- src/content-script/index.mjs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/content-script/index.mjs b/src/content-script/index.mjs index 6c947497..3525cdd1 100644 --- a/src/content-script/index.mjs +++ b/src/content-script/index.mjs @@ -36,9 +36,10 @@ async function run(question) { port.postMessage({ question }); } -const siteName = document.location.hostname - .replace("www.", "").replace("search.", "") - .match(/(.+?)\./)[1] +const siteNameReplaceList = [document.location.hostname, "www.", "search.", "cn."] +const siteName = siteNameReplaceList.reduce((pre, cur) => { + return pre.replace(cur, "") +}).match(/(.+?)\./)[1] const searchInput = getPossibleElementByNameArray(config[siteName].inputName); if (searchInput && searchInput.value) { From b3a92aed6a9db8bcee3e3182c62394773b3e0727 Mon Sep 17 00:00:00 2001 From: Jos Storer Date: Fri, 9 Dec 2022 00:46:33 +0800 Subject: [PATCH 07/11] simplify manifest --- src/manifest.json | 7 +------ src/manifest.v2.json | 7 +------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/manifest.json b/src/manifest.json index a54d037e..7b5599b7 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -15,12 +15,7 @@ }, "content_scripts": [ { - "matches": [ - "https://*/search*", - "https://duckduckgo.com/*q=*", - "https://*.startpage.com/sp/search*", - "https://*.baidu.com/s*wd=*" - ], + "matches": ["https://*/*"], "include_globs": [ "https://*.google.*/*", "https://kagi.*/*", diff --git a/src/manifest.v2.json b/src/manifest.v2.json index ddc3d54d..8eb64071 100644 --- a/src/manifest.v2.json +++ b/src/manifest.v2.json @@ -15,12 +15,7 @@ }, "content_scripts": [ { - "matches": [ - "https://*/search*", - "https://duckduckgo.com/*q=*", - "https://*.startpage.com/sp/search*", - "https://*.baidu.com/s*wd=*" - ], + "matches": ["https://*/*"], "include_globs": [ "https://*.google.*/*", "https://kagi.*/*", From e9bd8a2f285a5a723129b887614ebdde521de390 Mon Sep 17 00:00:00 2001 From: Jos Storer Date: Fri, 9 Dec 2022 00:47:27 +0800 Subject: [PATCH 08/11] change the implement in utils.mjs for get elements --- src/content-script/utils.mjs | 39 ++++++++++++++---------------------- 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/src/content-script/utils.mjs b/src/content-script/utils.mjs index 663b8fbe..809c3114 100644 --- a/src/content-script/utils.mjs +++ b/src/content-script/utils.mjs @@ -1,35 +1,26 @@ export function getPossibleElementByNameArray(elementNameArray) { - let element; - elementNameArray.some( - (e) => { - element = document.getElementsByName(e)[0]; - if (element) - return true; + for (const elementName of elementNameArray) { + const element = document.getElementsByName(elementName)[0]; + if (element) { + return element; } - ); - return element; + } } export function getPossibleElementByIdArray(elementIdArray) { - let element; - elementIdArray.some( - (e) => { - element = document.getElementById(e); - if (element) - return true; + for (const elementId of elementIdArray) { + const element = document.getElementById(elementId); + if (element) { + return element; } - ); - return element; + } } export function getPossibleElementByClassArray(elementClassArray) { - let element; - elementClassArray.some( - (e) => { - element = document.getElementsByClassName(e)[0]; - if (element) - return true; + for (const elementClass of elementClassArray) { + const element = document.getElementsByClassName(elementClass)[0]; + if (element) { + return element; } - ); - return element; + } } \ No newline at end of file From ee69cad843b1a0f4f6f21d7a89abbe6faa825f24 Mon Sep 17 00:00:00 2001 From: Jos Storer Date: Fri, 9 Dec 2022 00:48:14 +0800 Subject: [PATCH 09/11] change the way to get siteName, to make it more readable --- src/content-script/index.mjs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/content-script/index.mjs b/src/content-script/index.mjs index 757a4fbd..98081d98 100644 --- a/src/content-script/index.mjs +++ b/src/content-script/index.mjs @@ -40,10 +40,9 @@ async function run(question) { port.postMessage({ question }); } -const siteNameReplaceList = [document.location.hostname, "www.", "search.", "cn."] -const siteName = siteNameReplaceList.reduce((pre, cur) => { - return pre.replace(cur, "") -}).match(/(.+?)\./)[1] +const matchedSites = Object.keys(config); +const siteRegex = new RegExp(`(${matchedSites.join('|')})`); +const siteName = document.location.hostname.match(siteRegex)[0]; const searchInput = getPossibleElementByNameArray(config[siteName].inputName); if (searchInput && searchInput.value) { From f8e8893d43736ab362da580a9c18843b712f5309 Mon Sep 17 00:00:00 2001 From: Jos Storer Date: Fri, 9 Dec 2022 01:15:32 +0800 Subject: [PATCH 10/11] use document.querySelector to find elements --- src/content-script/engine-match-config.mjs | 106 ++++++++------------- src/content-script/index.mjs | 14 +-- src/content-script/utils.mjs | 24 +---- 3 files changed, 48 insertions(+), 96 deletions(-) diff --git a/src/content-script/engine-match-config.mjs b/src/content-script/engine-match-config.mjs index 5b9cd46e..712c7081 100644 --- a/src/content-script/engine-match-config.mjs +++ b/src/content-script/engine-match-config.mjs @@ -1,97 +1,71 @@ /** * @typedef {object} SiteConfig - * @property {string[]} inputName - input element name of search box - * @property {string[]} sidebarContainerId - prepend child to - * @property {string[]} sidebarContainerClass - if above ids not exist, prepend child to - * @property {string[]} appendContainerId - if above all not exist, append child to - * @property {string[]} appendContainerClass - if above all not exist, append child to + * @property {string[]} inputQuery - for search box + * @property {string[]} sidebarContainerQuery - prepend child to + * @property {string[]} appendContainerQuery - if sidebarContainer not exists, append child to */ /** * @type {Object.} */ export const config = { google: { - inputName: ["q"], - sidebarContainerId: ["rhs"], - sidebarContainerClass: [], - appendContainerId: ["rcnt"], - appendContainerClass: [] + inputQuery: ["input[name='q']"], + sidebarContainerQuery: ["#rhs"], + appendContainerQuery: ["#rcnt"] }, bing: { - inputName: ["q"], - sidebarContainerId: ["b_context"], - sidebarContainerClass: [], - appendContainerId: [], - appendContainerClass: [] + inputQuery: ["input[name='q']"], + sidebarContainerQuery: ["#b_context"], + appendContainerQuery: [] }, yahoo: { - inputName: ["p"], - sidebarContainerId: ["right"], - sidebarContainerClass: ["Contents__inner Contents__inner--sub"], - appendContainerId: ["cols", "contents__wrap"], // and yahoo jp - appendContainerClass: [] + inputQuery: ["input[name='p']"], + sidebarContainerQuery: ["#right", ".Contents__inner.Contents__inner--sub"], + appendContainerQuery: ["#cols", "#contents__wrap"] }, duckduckgo: { - inputName: ["q"], - sidebarContainerId: [], - sidebarContainerClass: ["results--sidebar js-results-sidebar"], - appendContainerId: ["links_wrapper"], - appendContainerClass: [] + inputQuery: ["input[name='q']"], + sidebarContainerQuery: [".results--sidebar.js-results-sidebar"], + appendContainerQuery: ["#links_wrapper"] }, startpage: { - inputName: ["query"], - sidebarContainerId: [], - sidebarContainerClass: ["layout-web__sidebar layout-web__sidebar--web"], - appendContainerId: [], - appendContainerClass: ["layout-web__body layout-web__body--desktop"] + inputQuery: ["input[name='query']"], + sidebarContainerQuery: [".layout-web__sidebar.layout-web__sidebar--web"], + appendContainerQuery: [".layout-web__body.layout-web__body--desktop"] }, baidu: { - inputName: ["wd"], - sidebarContainerId: ["content_right"], - sidebarContainerClass: [], - appendContainerId: ["container"], - appendContainerClass: [] + inputQuery: ["input[name='wd']"], + sidebarContainerQuery: ["#content_right"], + appendContainerQuery: ["#container"] }, kagi: { - inputName: ["q"], - sidebarContainerId: [], - sidebarContainerClass: ["right-content-box _0_right_sidebar"], - appendContainerId: ["_0_app_content"], - appendContainerClass: [] + inputQuery: ["input[name='q']"], + sidebarContainerQuery: [".right-content-box._0_right_sidebar"], + appendContainerQuery: ["#_0_app_content"], }, yandex: { - inputName: ["text"], - sidebarContainerId: ["search-result-aside"], - sidebarContainerClass: [], - appendContainerId: [], - appendContainerClass: [] + inputQuery: ["input[name='text']"], + sidebarContainerQuery: ["#search-result-aside"], + appendContainerQuery: [] }, naver: { - inputName: ["query"], - sidebarContainerId: ["sub_pack"], - sidebarContainerClass: [], - appendContainerId: ["content"], - appendContainerClass: [] + inputQuery: ["input[name='query']"], + sidebarContainerQuery: ["#sub_pack"], + appendContainerQuery: ["#content"] }, brave: { - inputName: ["q"], - sidebarContainerId: ["side-right"], - sidebarContainerClass: [], - appendContainerId: [], - appendContainerClass: [] + inputQuery: ["input[name='q']"], + sidebarContainerQuery: ["#side-right"], + appendContainerQuery: [] }, searx: { - inputName: ["q"], - sidebarContainerId: ["sidebar_results"], - sidebarContainerClass: [], - appendContainerId: [], - appendContainerClass: [] + inputQuery: ["input[name='q']"], + sidebarContainerQuery: ["#sidebar_results"], + appendContainerQuery: [] }, ecosia: { - inputName: ["q"], - sidebarContainerId: [], - sidebarContainerClass: ["sidebar web__sidebar"], - appendContainerId: ["main"], - appendContainerClass: [] + inputQuery: ["input[name='q']"], + sidebarContainerQuery: [".sidebar web__sidebar"], + appendContainerQuery: ["#main"] } -} \ No newline at end of file +} diff --git a/src/content-script/index.mjs b/src/content-script/index.mjs index 98081d98..e4e28f14 100644 --- a/src/content-script/index.mjs +++ b/src/content-script/index.mjs @@ -1,6 +1,6 @@ import MarkdownIt from "markdown-it"; import Browser from "webextension-polyfill"; -import {getPossibleElementByClassArray, getPossibleElementByIdArray, getPossibleElementByNameArray} from "./utils.mjs" +import {getPossibleElementByQuerySelector} from "./utils.mjs" import {config} from "./engine-match-config.mjs" async function run(question) { @@ -10,16 +10,12 @@ async function run(question) { container.className = "chat-gpt-container"; container.innerHTML = '

Waiting for ChatGPT response...

'; - const siderbarContainer = - getPossibleElementByIdArray(config[siteName].sidebarContainerId) - || getPossibleElementByClassArray(config[siteName].sidebarContainerClass); + const siderbarContainer = getPossibleElementByQuerySelector(config[siteName].sidebarContainerQuery); if (siderbarContainer) { siderbarContainer.prepend(container); } else { container.classList.add("sidebar-free"); - const appendContainer = - getPossibleElementByIdArray(config[siteName].appendContainerId) - || getPossibleElementByClassArray(config[siteName].appendContainerClass); + const appendContainer = getPossibleElementByQuerySelector(config[siteName].appendContainerQuery); if (appendContainer) appendContainer.appendChild(container); } @@ -44,11 +40,11 @@ const matchedSites = Object.keys(config); const siteRegex = new RegExp(`(${matchedSites.join('|')})`); const siteName = document.location.hostname.match(siteRegex)[0]; -const searchInput = getPossibleElementByNameArray(config[siteName].inputName); +const searchInput = getPossibleElementByQuerySelector(config[siteName].inputQuery); if (searchInput && searchInput.value) { // only run on first page const startParam = new URL(location.href).searchParams.get("start") || "0"; if (startParam === "0") { run(searchInput.value); } -} \ No newline at end of file +} diff --git a/src/content-script/utils.mjs b/src/content-script/utils.mjs index 809c3114..73061b36 100644 --- a/src/content-script/utils.mjs +++ b/src/content-script/utils.mjs @@ -1,26 +1,8 @@ -export function getPossibleElementByNameArray(elementNameArray) { - for (const elementName of elementNameArray) { - const element = document.getElementsByName(elementName)[0]; +export function getPossibleElementByQuerySelector(queryArray) { + for (const query of queryArray) { + const element = document.querySelector(query); if (element) { return element; } } } - -export function getPossibleElementByIdArray(elementIdArray) { - for (const elementId of elementIdArray) { - const element = document.getElementById(elementId); - if (element) { - return element; - } - } -} - -export function getPossibleElementByClassArray(elementClassArray) { - for (const elementClass of elementClassArray) { - const element = document.getElementsByClassName(elementClass)[0]; - if (element) { - return element; - } - } -} \ No newline at end of file From 21029269df8e79137af730cc1baf2a4536e23528 Mon Sep 17 00:00:00 2001 From: Jos Storer Date: Fri, 9 Dec 2022 01:24:51 +0800 Subject: [PATCH 11/11] update for bing and ecosia --- src/content-script/engine-match-config.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content-script/engine-match-config.mjs b/src/content-script/engine-match-config.mjs index 712c7081..d493bc5b 100644 --- a/src/content-script/engine-match-config.mjs +++ b/src/content-script/engine-match-config.mjs @@ -14,7 +14,7 @@ export const config = { appendContainerQuery: ["#rcnt"] }, bing: { - inputQuery: ["input[name='q']"], + inputQuery: ["textarea[name='q']"], sidebarContainerQuery: ["#b_context"], appendContainerQuery: [] }, @@ -65,7 +65,7 @@ export const config = { }, ecosia: { inputQuery: ["input[name='q']"], - sidebarContainerQuery: [".sidebar web__sidebar"], + sidebarContainerQuery: [".sidebar.web__sidebar"], appendContainerQuery: ["#main"] } }