From cb0f30b7bffb2664ecc55ae4b5466aaa2b734509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ismael=20Mart=C3=ADn=20Alabarce?= Date: Fri, 30 Oct 2020 17:02:44 +0100 Subject: [PATCH 1/6] Initial implementation of DuckDuckGo Instant answer --- src/background/plugins.js | 31 +++++++++++++++++++++++++++---- src/manifest.json | 5 +++-- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/background/plugins.js b/src/background/plugins.js index 24857de..80115a7 100644 --- a/src/background/plugins.js +++ b/src/background/plugins.js @@ -81,10 +81,33 @@ export default { displayName: 'DuckDuckGo search', match: /\s*(.*?)/, keys: [ 'd', 'duckduckgo' ], - item: { - favicon: 'https://duckduckgo.com/favicon.ico', - title: 'Search DuckDuckGo for $1', - url: 'https://duckduckgo.com?q=$1', + async item(query) { + const results = [ + { + favicon: 'https://duckduckgo.com/favicon.ico', + title: 'Search DuckDuckGo for $1', + url: 'https://duckduckgo.com?q=$1', + } + ] + if (query.length > 3) { + const search = await fetch(`https://api.duckduckgo.com/?q=${query}&format=json`).then(response => response.json()) + if (search.Results[0]) results.push({ + favicon: search.Results[0].Icon.URL, + title: search.Results[0].Text, + url: search.Results[0].FirstURL + }) + if (search.Abstract) results.push({ + favicon: search.Image, + title: search.AbstractText, + url: search.AbstractURL + }) + results.push(...search.RelatedTopics.map(topic => ({ + favicon: topic.Icon.URL, + title: topic.Text, + url: topic.FirstURL + }))) + } + return results }, handler(item, sendResponse) { chrome.tabs.create({ active: true, url: item.url }, () => sendResponse()); diff --git a/src/manifest.json b/src/manifest.json index e968b81..ab6481b 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -26,7 +26,8 @@ "history", "bookmarks", "chrome://favicon/", - "storage" + "storage", + "https://api.duckduckgo.com/*" ], - "content_security_policy": "script-src 'self'; object-src 'self'; img-src http: https: chrome://favicon;" + "content_security_policy": "script-src 'self'; object-src 'self'; img-src http: https: data: chrome://favicon;" } \ No newline at end of file From bb86e1b5fe2b8731594b472680a9cbfb573191a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ismael=20Mart=C3=ADn=20Alabarce?= Date: Mon, 9 Nov 2020 09:13:15 +0100 Subject: [PATCH 2/6] Minor fixes and results in new category --- src/background/plugins.js | 41 ++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/background/plugins.js b/src/background/plugins.js index 80115a7..eaef897 100644 --- a/src/background/plugins.js +++ b/src/background/plugins.js @@ -82,32 +82,37 @@ export default { match: /\s*(.*?)/, keys: [ 'd', 'duckduckgo' ], async item(query) { - const results = [ - { - favicon: 'https://duckduckgo.com/favicon.ico', - title: 'Search DuckDuckGo for $1', - url: 'https://duckduckgo.com?q=$1', - } - ] + const results = [] if (query.length > 3) { - const search = await fetch(`https://api.duckduckgo.com/?q=${query}&format=json`).then(response => response.json()) - if (search.Results[0]) results.push({ - favicon: search.Results[0].Icon.URL, - title: search.Results[0].Text, - url: search.Results[0].FirstURL - }) + const category = 'Instant answer' + const search = await fetch(`https://api.duckduckgo.com/?q=${encodeURI(query)}&format=json`).then(response => response.json()) if (search.Abstract) results.push({ - favicon: search.Image, - title: search.AbstractText, - url: search.AbstractURL + favicon: search.Image, + title: search.AbstractText, + url: search.AbstractURL, + category }) + results.push(...search.Results.map(result => ({ + favicon: result.Icon.URL, + title: result.Text, + url: result.FirstURL, + category + }))) results.push(...search.RelatedTopics.map(topic => ({ favicon: topic.Icon.URL, title: topic.Text, - url: topic.FirstURL + url: topic.FirstURL, + category }))) } - return results + return [ + { + favicon: 'https://duckduckgo.com/favicon.ico', + title: 'Results from DuckDuckGo for $1', + url: 'https://duckduckgo.com?q=$1', + }, + ...results + ] }, handler(item, sendResponse) { chrome.tabs.create({ active: true, url: item.url }, () => sendResponse()); From 00325ea70101a497d43e6b8a3d7e9807023c3524 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ismael=20Mart=C3=ADn=20Alabarce?= Date: Wed, 11 Nov 2020 16:42:31 +0100 Subject: [PATCH 3/6] Dummy catch duckduckgo API errors --- src/background/plugins.js | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/background/plugins.js b/src/background/plugins.js index eaef897..b32f54a 100644 --- a/src/background/plugins.js +++ b/src/background/plugins.js @@ -85,25 +85,27 @@ export default { const results = [] if (query.length > 3) { const category = 'Instant answer' - const search = await fetch(`https://api.duckduckgo.com/?q=${encodeURI(query)}&format=json`).then(response => response.json()) - if (search.Abstract) results.push({ - favicon: search.Image, - title: search.AbstractText, - url: search.AbstractURL, - category - }) - results.push(...search.Results.map(result => ({ - favicon: result.Icon.URL, - title: result.Text, - url: result.FirstURL, - category - }))) - results.push(...search.RelatedTopics.map(topic => ({ - favicon: topic.Icon.URL, - title: topic.Text, - url: topic.FirstURL, + try { + const search = await fetch(`https://api.duckduckgo.com/?q=${encodeURI(query)}&format=json`).then(response => response.json()) + if (search.Abstract) results.push({ + favicon: search.Image, + title: search.AbstractText, + url: search.AbstractURL, category - }))) + }) + results.push(...search.Results.map(result => ({ + favicon: result.Icon.URL, + title: result.Text, + url: result.FirstURL, + category + }))) + results.push(...search.RelatedTopics.map(topic => ({ + favicon: topic.Icon.URL, + title: topic.Text, + url: topic.FirstURL, + category + }))) + } catch {} } return [ { From cd46150212a149a2d6f514ff62cb231229b17759 Mon Sep 17 00:00:00 2001 From: blenderskool Date: Fri, 13 Nov 2020 14:09:33 +0530 Subject: [PATCH 4/6] Improve formatting and cases prone to errors --- src/background/plugins.js | 50 +++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/src/background/plugins.js b/src/background/plugins.js index b32f54a..ef15c63 100644 --- a/src/background/plugins.js +++ b/src/background/plugins.js @@ -82,29 +82,39 @@ export default { match: /\s*(.*?)/, keys: [ 'd', 'duckduckgo' ], async item(query) { - const results = [] + const results = []; + if (query.length > 3) { - const category = 'Instant answer' + const category = 'Instant answer'; try { - const search = await fetch(`https://api.duckduckgo.com/?q=${encodeURI(query)}&format=json`).then(response => response.json()) - if (search.Abstract) results.push({ - favicon: search.Image, - title: search.AbstractText, - url: search.AbstractURL, - category - }) + const search = await fetch(`https://api.duckduckgo.com/?q=${encodeURI(query)}&format=json`).then(response => response.json()); + + if (search.Abstract) { + results.push({ + favicon: search.Image, + title: search.AbstractText, + url: search.AbstractURL, + category, + }); + } + results.push(...search.Results.map(result => ({ - favicon: result.Icon.URL, + favicon: result.Icon?.URL, title: result.Text, url: result.FirstURL, - category - }))) - results.push(...search.RelatedTopics.map(topic => ({ - favicon: topic.Icon.URL, - title: topic.Text, - url: topic.FirstURL, - category - }))) + category, + }))); + + results.push( + ...search.RelatedTopics + .filter(topic => !!topic.FirstURL) + .map(topic => ({ + favicon: topic.Icon?.URL, + title: topic.Text, + url: topic.FirstURL, + category, + })) + ); } catch {} } return [ @@ -113,8 +123,8 @@ export default { title: 'Results from DuckDuckGo for $1', url: 'https://duckduckgo.com?q=$1', }, - ...results - ] + ...results, + ]; }, handler(item, sendResponse) { chrome.tabs.create({ active: true, url: item.url }, () => sendResponse()); From 4b0f97030029269e098bc5ee879a1fe78d50bc2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ismael=20Mart=C3=ADn=20Alabarce?= Date: Sun, 15 Nov 2020 10:24:22 +0100 Subject: [PATCH 5/6] Fix missing icons --- src/background/plugins.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/background/plugins.js b/src/background/plugins.js index ef15c63..fafd8c6 100644 --- a/src/background/plugins.js +++ b/src/background/plugins.js @@ -86,12 +86,16 @@ export default { if (query.length > 3) { const category = 'Instant answer'; + const parseIconUrl = (url) => { + if (!url || url === '') return 'https://duckduckgo.com/favicon.ico' + return url.indexOf('http') === 0 ? url : 'https://duckduckgo.com' + url + } try { const search = await fetch(`https://api.duckduckgo.com/?q=${encodeURI(query)}&format=json`).then(response => response.json()); if (search.Abstract) { results.push({ - favicon: search.Image, + favicon: parseIconUrl(search.Image), title: search.AbstractText, url: search.AbstractURL, category, @@ -99,7 +103,7 @@ export default { } results.push(...search.Results.map(result => ({ - favicon: result.Icon?.URL, + favicon: parseIconUrl(result.Icon?.URL), title: result.Text, url: result.FirstURL, category, @@ -109,7 +113,7 @@ export default { ...search.RelatedTopics .filter(topic => !!topic.FirstURL) .map(topic => ({ - favicon: topic.Icon?.URL, + favicon: parseIconUrl(topic.Icon?.URL), title: topic.Text, url: topic.FirstURL, category, From a931cadbe2fc0c2fcfa0d11909d886240f622a78 Mon Sep 17 00:00:00 2001 From: blenderskool Date: Sun, 15 Nov 2020 22:33:57 +0530 Subject: [PATCH 6/6] Update formatting and default favicon --- src/background/plugins.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/background/plugins.js b/src/background/plugins.js index fafd8c6..e6f417b 100644 --- a/src/background/plugins.js +++ b/src/background/plugins.js @@ -87,9 +87,10 @@ export default { if (query.length > 3) { const category = 'Instant answer'; const parseIconUrl = (url) => { - if (!url || url === '') return 'https://duckduckgo.com/favicon.ico' - return url.indexOf('http') === 0 ? url : 'https://duckduckgo.com' + url - } + if (!url || url === '') return; + return url.indexOf('http') === 0 ? url : 'https://duckduckgo.com' + url; + }; + try { const search = await fetch(`https://api.duckduckgo.com/?q=${encodeURI(query)}&format=json`).then(response => response.json());