forked from WorldBrain/Memex
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtab-events.js
92 lines (82 loc) · 2.99 KB
/
tab-events.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
import eventToPromise from './event-to-promise'
const tabChangedEvents = tabId => [
{
event: browser.webNavigation.onCommitted,
filter: details => details.tabId === tabId && details.frameId === 0,
reason: { message: 'Tab URL changed before event occurred.' },
},
// TODO Handle history state updates more carefully. Ignoring these events for now.
// {
// event: browser.webNavigation.onHistoryStateUpdated,
// filter: details => (details.tabId === tabId && details.frameId === 0),
// reason: {message: 'Tab URL changed before event occurred.'},
// },
{
event: browser.tabs.onRemoved,
filter: closedTabId => closedTabId === tabId,
reason: { message: 'Tab was closed before event occurred.' },
},
]
// Resolve if or when the page DOM is loaded (document.readyState==='interactive')
// Rejects if it is closed before that.
// XXX Needs host permission on the tab
export function whenPageDOMLoaded({ tabId }) {
return new Promise((resolve, reject) => {
// Using executeScript at document_end here as a workaround, as there is
// no tab.status==='interactive'; it is either 'loading' or 'complete'.
browser.tabs
.executeScript(tabId, {
code: 'undefined',
runAt: 'document_end',
})
.then(() => resolve())
.catch(reject)
// Reject when the page unloads.
eventToPromise({
reject: tabChangedEvents(tabId),
}).catch(reject)
})
}
// Resolve if or when the page is completely loaded.
// Rejects if it is closed before that.
export async function whenPageLoadComplete({ tabId }) {
const tab = await browser.tabs.get(tabId)
if (tab.status === 'complete') {
return
} // Resolve directly
return eventToPromise({
resolve: {
event: browser.tabs.onUpdated,
filter: (changedTabId, { status }) =>
changedTabId === tabId && status === 'complete',
},
reject: tabChangedEvents(tabId),
})
}
// Resolve if or when the tab is active.
// Rejects if it is closed before that.
export async function whenTabActive({ tabId }) {
const activeTabs = await browser.tabs.query({ active: true })
const isActive = activeTabs.map(t => t.id).indexOf(tabId) > -1
if (isActive) {
return
} // Resolve directly
return eventToPromise({
resolve: {
event: browser.tabs.onActivated,
filter: ({ tabId: activatedTabId }) => activatedTabId === tabId,
},
reject: tabChangedEvents(tabId),
})
}
// Resolve if or when the tab title updates.
// Rejects if it is closed before that.
export const whenTabTitleUpdates = ({ tabId }) =>
eventToPromise({
resolve: {
event: browser.tabs.onUpdated,
filter: (updatedTabId, changeInfo) =>
updatedTabId === tabId && changeInfo.title != null,
},
reject: tabChangedEvents(tabId),
})