-
Notifications
You must be signed in to change notification settings - Fork 2
/
combine-tw5-and-search-engine-results.user.js
132 lines (122 loc) · 4.22 KB
/
combine-tw5-and-search-engine-results.user.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// ==UserScript==
// @name TiddlyWiki5: Combine TW5 and search engine results
// @description Combine TiddlyWiki and your preferred search engine to find your own answers more easily
// @version 0.3.1
// @author bimlas
// @supportURL https://github.com/bimlas/userscript-combine-tw5-and-search-engine-results
// @downloadURL https://github.com/bimlas/userscript-combine-tw5-and-search-engine-results/raw/master/combine-tw5-and-search-engine-results.user.js
// @icon https://tiddlywiki.com/favicon.ico
// @namespace Violentmonkey Scripts
// @match *://www.google.com/search*
// @match *://www.startpage.com/*
// @match *://duckduckgo.com/*
// @match *://www.ecosia.org/search*
// @grant GM_xmlhttpRequest
// ==/UserScript==
// READ THE DOCUMENTATION BEFORE TRYING TO USE THE SCRIPT!
// https://github.com/bimlas/userscript-combine-tw5-and-search-engine-results
const wikis = ["http://localhost:8080"];
const buildWikiFilter = function (query) {
return `[!is[system]search[${query}]]`;
};
// NOTE: If you want to show results in the sidebar, change this option to
// 'sidebar', but remember that the sidebar is not always visible (for example,
// if the window is too narrow).
const placementOfResults = "main";
const searchEngineConfigs = {
"www.google.com": {
searchInputSelector: "input[name=q]",
searchResultsSelector: {
main: "#center_col",
sidebar: "#rhs",
},
},
// StartPage changes its URL and website structure, so the script does not work in all cases
"www.startpage.com": {
searchInputSelector: "#q",
searchResultsSelector: {
main: "div.mainline-results",
sidebar: "div.sidebar-results",
},
},
"duckduckgo.com": {
searchInputSelector: "input[name=q]",
searchResultsSelector: {
main: "#links.results",
sidebar: "div.sidebar-modules",
},
},
"www.ecosia.org": {
searchInputSelector: "input[name=q]",
searchResultsSelector: {
main: "div.mainline",
sidebar: "div.sidebar",
},
},
};
const searchEngine = searchEngineConfigs[document.domain];
function fetchJSON(origin, url) {
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: "GET",
headers: {
Origin: origin,
},
url: url,
onload: function (response) {
resolve(JSON.parse(response.responseText));
},
});
});
}
function getTiddlerLink(wiki, title) {
const urlEncodedTitle = encodeURIComponent(title);
const singleViewUrl = `${wiki}/${urlEncodedTitle}`;
const normalViewUrl = `${wiki}/#${urlEncodedTitle}`;
return `<a href="${singleViewUrl}">${title}</a> (<a href="${normalViewUrl}">#</a>)`;
}
function getWikiTitle(wiki) {
return new Promise((resolve, reject) => {
const urlEncodedQuery = encodeURIComponent("$:/SiteTitle");
const url = `${wiki}/recipes/default/tiddlers/${urlEncodedQuery}`;
fetchJSON(wiki, url).then((results) => {
resolve(results.text);
});
});
}
function addToPage(text) {
const searchEngineResults = document.querySelector(
searchEngine.searchResultsSelector[placementOfResults]
);
const node = document.createElement("div");
node.style.display = "inline-flex";
node.style.margin = "1em";
node.style.backgroundColor = "rgba(0, 0, 0, 0.05)";
node.innerHTML = text;
searchEngineResults.insertBefore(node, searchEngineResults.childNodes[0]);
}
function makeHtmlListFromTiddlers(wiki, listOfTiddlers) {
const htmlList = listOfTiddlers.reduce((text, tiddler) => {
return text + `<li>${getTiddlerLink(wiki, tiddler.title)}</li>`;
}, "");
return `<ul>${htmlList}</ul>`;
}
const query = document.querySelector(searchEngine.searchInputSelector).value;
const urlEncodedQuery = encodeURIComponent(buildWikiFilter(query));
let searchResults = "";
wikis.forEach((wiki) => {
const url = `${wiki}/recipes/default/tiddlers.json?filter=${urlEncodedQuery}`;
Promise.all([fetchJSON(wiki, url), getWikiTitle(wiki)]).then(
([results, wikiTitle]) => {
if (!results.length) return;
const wikiLink = `<small><a href="${wiki}">${wiki}</a></small>`;
const header = `<h3>${wikiTitle}</h3>${wikiLink}<p>`;
addToPage(
`<div style="margin: 1em;">${header}<p>${makeHtmlListFromTiddlers(
wiki,
results
)}</p><div>`
);
}
);
});