-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathservice-worker.js
More file actions
138 lines (125 loc) · 3.79 KB
/
service-worker.js
File metadata and controls
138 lines (125 loc) · 3.79 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
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import { getFonts } from "./font";
/** @type {string[]} */
let stylesheets = [];
/** @type {Object.<number, string>} */
let injectedCSS = {};
/**
* @param {number} tabId
* @param {string} category
* @param {string} text
*/
async function insertOrReplaceCss(tabId, category, text) {
const previousCss = injectedCSS[tabId]?.[category];
if (previousCss == text) {
return;
}
// Insert new CSS...
await chrome.scripting.insertCSS({
target: { tabId },
css: text
});
if (previousCss) {
// ...and remove old CSS *afterwards* to prevent FOUT
await chrome.scripting.removeCSS({
target: { tabId },
css: previousCss
});
}
if (!(tabId in injectedCSS)) {
injectedCSS[tabId] = {};
}
injectedCSS[tabId][category] = text;
}
// Do the thing! (Generate stylesheet and inject into active tab)
export async function runTypeX() {
let tabs = await chrome.tabs.query({ active: true, currentWindow: true });
const activeTab = tabs[0];
if (activeTab) {
let fontDeclarations = await generateFontStyleSheets();
let fontFileDeclarations = await generateFontFileStyleSheets();
await injectStyleSheets(
activeTab.id,
fontDeclarations,
fontFileDeclarations
);
}
}
// Injecting the stylesheet is fast, adding a class to
// the body isn't. We don't want a delay, so the CSS will
// enable the fonts immediately, and we only add a class
// when we want to *remove* the custom fonts.
let customFontsOn = () => {
delete document.documentElement.dataset.disablefont;
};
let customFontsOff = () => {
document.documentElement.dataset.disablefont = "";
};
/**
* @param {number} tabId
*/
async function injectStyleSheets(
tabId,
fontDeclarations,
fontFileDeclarations
) {
let { extensionActive } = await chrome.storage.local.get("extensionActive");
let fontDeclarationsCss = fontDeclarations.join("\n");
let fontFileDeclarationsCss = fontFileDeclarations.join("\n");
if (extensionActive) {
// Inject CSS to activate font
await insertOrReplaceCss(tabId, "fonts", fontDeclarationsCss);
await insertOrReplaceCss(tabId, "fontfiles", fontFileDeclarationsCss);
}
chrome.scripting.executeScript({
target: { tabId },
func: extensionActive ? customFontsOn : customFontsOff
});
}
async function generateFontStyleSheets() {
let { blacklist } = await chrome.storage.local.get(["blacklist"]);
let fonts = await getFonts();
stylesheets = [];
for (const font of fonts) {
let fontName = font.name;
let stylesheet = "";
let selectors = font.cssSelectorString(blacklist);
const stack = `'${fontName}', ${font.fallback}`;
stylesheet += `
${selectors} {
font-family: ${stack} !important;
${font.cssVariationSettings()}
${font.css}
}`;
stylesheets.push(stylesheet);
}
return stylesheets;
}
async function generateFontFileStyleSheets() {
let fonts = await getFonts();
let { files } = await chrome.storage.local.get("files");
let stylesheets = [];
for (const font of fonts) {
let fontName = font.name;
if (font.file in files) {
stylesheets.push(`
@font-face {
font-family: '${fontName}';
src: url('${files[font.file].file}');
font-weight: 100 900;
font-stretch: 50% 200%;
}`);
}
}
return stylesheets;
}
// Listen for call from popup or page
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.pageLoad) {
// We moved to a new page; although we may have injected CSS into this *tab* previously,
// we haven't for this page, so clear it from our cache so we inject some more.
delete injectedCSS[sender.tab.id];
}
if (message.runTypeX) {
runTypeX();
}
});