-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathscript.js
111 lines (88 loc) · 2.89 KB
/
script.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
/* global idb, browser, IDBKeyRange, AbortController */
if (!window.browser) window.browser = window.chrome
const TAB_CHECK_DELAY = 100
const HISTORY_DB = 'history'
const HISTORY_VERSION = 1
const HISTORY_STORE = 'navigated'
const MAX_RESULTS = 8
const FORBIDDEN_PROTOCOLS = ['agregore:', 'chrome-extension:', 'devtools:']
main()
async function main () {
const db = await idb.openDB(HISTORY_DB, HISTORY_VERSION, {
upgrade
})
let aborter = null
browser.webNavigation.onCompleted.addListener(onCompleted)
window.db = db
window.search = search
async function * search (query = '', maxResults = MAX_RESULTS, _signal) {
let signal = _signal
if (!signal) {
if (aborter) aborter.abort()
aborter = new AbortController()
signal = aborter.signal
}
let sent = 0
const seen = new Set()
const regexText = query.split(' ').reduce((result, letter) => `${result}.*${letter}`, '')
const filter = new RegExp(regexText, 'iu')
const index = db.transaction(HISTORY_STORE, 'readonly').store.index('timestamp')
const start = Date.now()
const range = IDBKeyRange.upperBound(start)
const iterator = index.iterate(range, 'prev')
for await (const { value } of iterator) {
const { search: searchString, url } = value
if (searchString.match(filter)) {
if (seen.has(url)) continue
seen.add(url)
yield value
sent++
if (sent >= MAX_RESULTS) break
}
if (signal && signal.aborted) {
console.debug('Aborted search')
break
}
}
}
async function onCompleted ({ timeStamp, tabId }) {
await delay(TAB_CHECK_DELAY)
const tab = await getTab(tabId)
const { url, title } = tab
const { host, protocol, pathname } = new URL(url)
if (FORBIDDEN_PROTOCOLS.includes(protocol)) return console.debug('Skipping saving', url)
const historyItem = {
host,
protocol,
pathname,
url,
title,
timestamp: timeStamp,
search: `${url} ${title}`
}
console.log('Navigation event', historyItem)
await db.add(HISTORY_STORE, historyItem)
}
}
async function upgrade (db) {
const store = db.createObjectStore(HISTORY_STORE, {
// The 'id' property of the object will be the key.
keyPath: 'id',
// If it isn't explicitly set, create a value by auto incrementing.
autoIncrement: true
})
store.createIndex('search', 'search', { unique: false })
store.createIndex('timestamp', 'timestamp', { unique: false })
store.createIndex('url', 'url', { unique: false })
store.createIndex('title', 'title', { unique: false })
store.createIndex('host', 'host', { unique: false })
store.createIndex('protocol', 'protocol', { unique: false })
}
async function getTab (id) {
return new Promise((resolve) => {
browser.tabs.get(id, resolve)
})
}
async function delay (ms) {
return new Promise((resolve) => setTimeout(resolve, ms))
}