aboutsummaryrefslogtreecommitdiff
path: root/src/background
diff options
context:
space:
mode:
authorShin'ya Ueoka <ueokande@i-beam.org>2017-09-18 00:58:14 +0900
committerShin'ya Ueoka <ueokande@i-beam.org>2017-09-18 00:58:14 +0900
commit8a8222158cd2b2d2277b3cc956ad97517e64c65d (patch)
treef622f2748cc853a932615969ae956c96c3364359 /src/background
parentbf07e89126989cc555a10848ddf18589fffe2e49 (diff)
parent10bb350d849bf78d8811f11beb7f0bfb0e3ac03b (diff)
Merge branch 'history-completion'
Diffstat (limited to 'src/background')
-rw-r--r--src/background/histories.js84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/background/histories.js b/src/background/histories.js
new file mode 100644
index 0000000..6b6e4c6
--- /dev/null
+++ b/src/background/histories.js
@@ -0,0 +1,84 @@
+const filterHttp = (items) => {
+ const httpsHosts = items
+ .filter(item => item[1].protocol === 'https:')
+ .map(item => item[1].host);
+ const httpsHostSet = new Set(httpsHosts);
+ return items.filter(
+ item => !(item[1].protocol === 'http:' && httpsHostSet.has(item[1].host))
+ );
+};
+
+const filterEmptyTitle = (items) => {
+ return items.filter(item => item[0].title && item[0].title !== '');
+};
+
+const filterClosedPath = (items) => {
+ const allSimplePaths = items
+ .filter(item => item[1].hash === '' && item[1].search === '')
+ .map(item => item[1].origin + item[1].pathname);
+ const allSimplePathSet = new Set(allSimplePaths);
+ return items.filter(
+ item => !(item[1].hash === '' && item[1].search === '' &&
+ (/\/$/).test(item[1].pathname) &&
+ allSimplePathSet.has(
+ (item[1].origin + item[1].pathname).replace(/\/$/, '')
+ )
+ )
+ );
+};
+
+const reduceByPathname = (items, min) => {
+ let hash = {};
+ for (let item of items) {
+ let pathname = item[1].origin + item[1].pathname;
+ if (!hash[pathname]) {
+ hash[pathname] = item;
+ } else if (hash[pathname][1].href.length > item[1].href.length) {
+ hash[pathname] = item;
+ }
+ }
+ let filtered = Object.values(hash);
+ if (filtered.length < min) {
+ return items;
+ }
+ return filtered;
+};
+
+const reduceByOrigin = (items, min) => {
+ let hash = {};
+ for (let item of items) {
+ let origin = item[1].origin;
+ if (!hash[origin]) {
+ hash[origin] = item;
+ } else if (hash[origin][1].href.length > item[1].href.length) {
+ hash[origin] = item;
+ }
+ }
+ let filtered = Object.values(hash);
+ if (filtered.length < min) {
+ return items;
+ }
+ return filtered;
+};
+
+const getCompletions = (keyword) => {
+ return browser.history.search({
+ text: keyword,
+ startTime: 0,
+ }).then((historyItems) => {
+ return [historyItems.map(item => [item, new URL(item.url)])]
+ .map(filterEmptyTitle)
+ .map(filterHttp)
+ .map(filterClosedPath)
+ .map(items => reduceByPathname(items, 10))
+ .map(items => reduceByOrigin(items, 10))
+ .map(items => items
+ .sort((x, y) => x[0].visitCount < y[0].visitCount)
+ .slice(0, 10)
+ .map(item => item[0])
+ .sort((x, y) => x.url > y.url)
+ )[0];
+ });
+};
+
+export { getCompletions };