blob: 52d67b95ed0818abe7ff2f9523a3f2599075318b (
plain) (
blame)
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
|
import select from 'select-dom';
import observeEl from './simplified-element-observer';
type CommitStatus = false | typeof SUCCESS | typeof FAILURE | typeof PENDING | typeof COMMIT_CHANGED;
type StatusListener = (status: CommitStatus) => void;
// `.TimelineItem--condensed` excludes unrelated references. See `deemphasize-unrelated-commit-references` feature
const commitSelector = '.js-commit.TimelineItem--condensed';
function getLastCommitReference(): string | null {
return select.last(`${commitSelector} code`)!.textContent;
}
export const SUCCESS = Symbol('Success');
export const FAILURE = Symbol('Failure');
export const PENDING = Symbol('Pending');
export const COMMIT_CHANGED = Symbol('Commit changed');
export function get(): CommitStatus {
// Excludes commit references. Sometimes commits don't have a status icon at all, yet
const lastCommit = select.last(commitSelector);
if (lastCommit) {
if (lastCommit.querySelector('.octicon-check')) {
return SUCCESS;
}
if (lastCommit.querySelector('.octicon-x')) {
return FAILURE;
}
if (lastCommit.querySelector('.octicon-primitive-dot')) {
return PENDING;
}
}
return false;
}
export async function wait(): Promise<CommitStatus> {
return new Promise(resolve => {
addEventListener(function handler(newStatus: CommitStatus) {
removeEventListener(handler);
resolve(newStatus);
});
});
}
const observers = new WeakMap<StatusListener, MutationObserver>();
export function addEventListener(listener: StatusListener): void {
if (observers.has(listener)) {
return;
}
let previousCommit = getLastCommitReference();
let previousStatus = get();
const filteredListener = (): void => {
// Cancel submission if a new commit was pushed
const newCommit = getLastCommitReference();
if (newCommit !== previousCommit) {
previousCommit = newCommit;
listener(COMMIT_CHANGED);
return;
}
// Ignore update if the status hasn't changed
const newStatus = get();
if (newStatus !== previousStatus) {
previousStatus = newStatus;
listener(newStatus);
}
};
const observer = observeEl('.js-discussion', filteredListener, {
childList: true,
subtree: true
})!;
observers.set(listener, observer);
}
export function removeEventListener(listener: StatusListener): void {
observers.get(listener)!.disconnect();
}
|