-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbackground.js
More file actions
84 lines (71 loc) · 2.53 KB
/
background.js
File metadata and controls
84 lines (71 loc) · 2.53 KB
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
const api = globalThis.browser ?? globalThis.chrome;
let sortingCount = 0;
const debounceTimers = new Map();
const DEBOUNCE_MS = 250;
const compare = (a, b) =>
a.title.localeCompare(b.title, undefined, { sensitivity: "base" });
async function sortFolder(folderId) {
const children = await api.bookmarks.getChildren(folderId);
if (children.length === 0) return [];
const subfolderIds = [], groups = [], separators = [];
let currentGroup = [];
for (const child of children) {
if (child.type === "separator") {
groups.push(currentGroup);
separators.push(child);
currentGroup = [];
} else {
if (!child.url) subfolderIds.push(child.id);
currentGroup.push(child);
}
}
groups.push(currentGroup);
const sortedGroups = groups.map((group) => [
...group.filter((item) => !item.url).sort(compare),
...group.filter((item) => item.url).sort(compare),
]);
const reassembled = sortedGroups.flatMap((group, i) =>
i < separators.length ? [...group, separators[i]] : group
);
sortingCount++;
try {
for (let i = 0; i < reassembled.length; i++)
await api.bookmarks.move(reassembled[i].id, { parentId: folderId, index: i });
} finally {
sortingCount--;
}
return subfolderIds;
}
async function sortFolderRecursive(folderId) {
const subfolderIds = await sortFolder(folderId);
for (const id of subfolderIds) await sortFolderRecursive(id);
}
async function sortAll() {
const tree = await api.bookmarks.getTree();
for (const container of tree[0].children) await sortFolderRecursive(container.id);
}
function debounceSortFolder(folderId) {
clearTimeout(debounceTimers.get(folderId));
debounceTimers.set(
folderId,
setTimeout(() => {
debounceTimers.delete(folderId);
if (sortingCount === 0) sortFolder(folderId).catch(console.error);
}, DEBOUNCE_MS)
);
}
function onBookmarkCreatedMovedRemoved(id, info) {
if (sortingCount > 0) return;
debounceSortFolder(info.parentId);
}
async function onBookmarkChanged(id) {
if (sortingCount > 0) return;
const [node] = await api.bookmarks.get(id).catch(() => []);
if (node) debounceSortFolder(node.parentId);
}
api.bookmarks.onCreated.addListener(onBookmarkCreatedMovedRemoved);
api.bookmarks.onMoved.addListener(onBookmarkCreatedMovedRemoved);
api.bookmarks.onRemoved.addListener(onBookmarkCreatedMovedRemoved);
api.bookmarks.onChanged.addListener(onBookmarkChanged);
api.runtime.onStartup.addListener(() => sortAll().catch(console.error));
api.runtime.onInstalled.addListener(() => sortAll().catch(console.error));