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
|
import React from 'dom-chef';
import * as pageDetect from 'github-url-detection';
import delegate, {DelegateEvent} from 'delegate-it';
import {CachedFunction} from 'webext-storage-cache';
import api from '../github-helpers/api.js';
import features from '../feature-manager.js';
import {buildRepoURL, cacheByRepo} from '../github-helpers/index.js';
import observe from '../helpers/selector-observer.js';
import GetReleases from './releases-dropdown.gql';
const getReleases = new CachedFunction('releases', {
async updater(): Promise<string[]> {
const {repository} = await api.v4(GetReleases);
return repository.releases.nodes.map(({tagName}: {tagName: string}) => tagName);
},
maxAge: {hours: 1},
staleWhileRevalidate: {days: 4},
cacheKey: cacheByRepo,
});
// `datalist` selections don't have an `inputType`
async function selectionHandler(event: DelegateEvent<Event, HTMLInputElement>): Promise<void> {
const field = event.delegateTarget;
const selectedTag = field.value;
const releases = await getReleases.get(); // Expected to be in cache
if (!('inputType' in event) && releases.includes(selectedTag)) {
location.href = buildRepoURL('releases/tag', encodeURIComponent(selectedTag));
field.value = ''; // Can't call `preventDefault`, the `input` event is not cancelable
}
}
async function addList(searchField: HTMLInputElement): Promise<void> {
const releases = await getReleases.get();
if (releases.length === 0) {
return;
}
searchField.setAttribute('list', 'rgh-releases-dropdown');
searchField.after(
<datalist id="rgh-releases-dropdown">
{releases.map(tag => <option value={tag}/>)}
</datalist>,
);
}
const searchFieldSelector = 'input#release-filter';
async function init(signal: AbortSignal): Promise<void> {
observe(searchFieldSelector, addList, {signal});
delegate(searchFieldSelector, 'input', selectionHandler, {signal});
}
void features.add(import.meta.url, {
include: [
pageDetect.isReleases,
],
init,
});
/*
## Test URLs
https://github.com/refined-github/refined-github/tags
https://github.com/refined-github/sandbox/releases
*/
|