@addon-core/inject-css 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +224 -72
- package/dist/index.cjs +556 -77
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +90 -9
- package/dist/index.js +543 -79
- package/dist/index.js.map +1 -1
- package/package.json +29 -10
package/dist/index.cjs
CHANGED
|
@@ -20,7 +20,19 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
-
|
|
23
|
+
InjectCssBaseError: () => InjectCssBaseError,
|
|
24
|
+
InjectCssDeliveryError: () => InjectCssDeliveryError,
|
|
25
|
+
InjectCssFrameDeliveryError: () => InjectCssFrameDeliveryError,
|
|
26
|
+
InjectCssTimeoutError: () => InjectCssTimeoutError,
|
|
27
|
+
InvalidInjectCssCodeError: () => InvalidInjectCssCodeError,
|
|
28
|
+
InvalidInjectCssFilesError: () => InvalidInjectCssFilesError,
|
|
29
|
+
InvalidInjectCssOptionsError: () => InvalidInjectCssOptionsError,
|
|
30
|
+
InvalidInjectCssTargetError: () => InvalidInjectCssTargetError,
|
|
31
|
+
UnsupportedInjectCssOperationError: () => UnsupportedInjectCssOperationError,
|
|
32
|
+
UnsupportedInjectCssOptionError: () => UnsupportedInjectCssOptionError,
|
|
33
|
+
UnsupportedInjectCssTargetError: () => UnsupportedInjectCssTargetError,
|
|
34
|
+
default: () => index_default,
|
|
35
|
+
injectCss: () => injectCss
|
|
24
36
|
});
|
|
25
37
|
module.exports = __toCommonJS(index_exports);
|
|
26
38
|
var import_browser3 = require("@addon-core/browser");
|
|
@@ -28,120 +40,587 @@ var import_browser3 = require("@addon-core/browser");
|
|
|
28
40
|
// src/InjectCssV2.ts
|
|
29
41
|
var import_browser = require("@addon-core/browser");
|
|
30
42
|
|
|
43
|
+
// src/errors.ts
|
|
44
|
+
var InjectCssBaseError = class extends Error {
|
|
45
|
+
code;
|
|
46
|
+
cause;
|
|
47
|
+
constructor(name, code, message, cause) {
|
|
48
|
+
super(message);
|
|
49
|
+
this.name = name;
|
|
50
|
+
this.code = code;
|
|
51
|
+
if (cause !== void 0) {
|
|
52
|
+
this.cause = cause;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
var InvalidInjectCssTargetError = class extends InjectCssBaseError {
|
|
57
|
+
constructor(message) {
|
|
58
|
+
super("InvalidInjectCssTargetError", "ERR_INJECT_CSS_INVALID_TARGET", `Invalid InjectCss target: ${message}`);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
var UnsupportedInjectCssTargetError = class extends InjectCssBaseError {
|
|
62
|
+
constructor(message, cause) {
|
|
63
|
+
super(
|
|
64
|
+
"UnsupportedInjectCssTargetError",
|
|
65
|
+
"ERR_INJECT_CSS_UNSUPPORTED_TARGET",
|
|
66
|
+
`Unsupported InjectCss target: ${message}`,
|
|
67
|
+
cause
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
var InvalidInjectCssOptionsError = class extends InjectCssBaseError {
|
|
72
|
+
constructor(message) {
|
|
73
|
+
super(
|
|
74
|
+
"InvalidInjectCssOptionsError",
|
|
75
|
+
"ERR_INJECT_CSS_INVALID_OPTIONS",
|
|
76
|
+
`Invalid InjectCss options: ${message}`
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
var UnsupportedInjectCssOptionError = class extends InjectCssBaseError {
|
|
81
|
+
constructor(message, cause) {
|
|
82
|
+
super(
|
|
83
|
+
"UnsupportedInjectCssOptionError",
|
|
84
|
+
"ERR_INJECT_CSS_UNSUPPORTED_OPTION",
|
|
85
|
+
`Unsupported InjectCss option: ${message}`,
|
|
86
|
+
cause
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
var UnsupportedInjectCssOperationError = class extends InjectCssBaseError {
|
|
91
|
+
operation;
|
|
92
|
+
constructor(operation, message, cause) {
|
|
93
|
+
super(
|
|
94
|
+
"UnsupportedInjectCssOperationError",
|
|
95
|
+
"ERR_INJECT_CSS_UNSUPPORTED_OPERATION",
|
|
96
|
+
`Unsupported InjectCss operation "${operation}": ${message}`,
|
|
97
|
+
cause
|
|
98
|
+
);
|
|
99
|
+
this.operation = operation;
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
var InvalidInjectCssCodeError = class extends InjectCssBaseError {
|
|
103
|
+
constructor(message) {
|
|
104
|
+
super("InvalidInjectCssCodeError", "ERR_INJECT_CSS_INVALID_CODE", `Invalid InjectCss code: ${message}`);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
var InvalidInjectCssFilesError = class extends InjectCssBaseError {
|
|
108
|
+
constructor(message) {
|
|
109
|
+
super("InvalidInjectCssFilesError", "ERR_INJECT_CSS_INVALID_FILES", `Invalid InjectCss files: ${message}`);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
var InjectCssTimeoutError = class extends InjectCssBaseError {
|
|
113
|
+
target;
|
|
114
|
+
timeoutMs;
|
|
115
|
+
operation;
|
|
116
|
+
constructor(target, timeoutMs, operation = "insert") {
|
|
117
|
+
const action = operation === "insert" ? "injection" : "removal";
|
|
118
|
+
super("InjectCssTimeoutError", "ERR_INJECT_CSS_TIMEOUT", `CSS ${action} timed out after ${timeoutMs} ms.`);
|
|
119
|
+
this.target = target;
|
|
120
|
+
this.timeoutMs = timeoutMs;
|
|
121
|
+
this.operation = operation;
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
var InjectCssFrameDeliveryError = class extends InjectCssBaseError {
|
|
125
|
+
tabId;
|
|
126
|
+
frameId;
|
|
127
|
+
operation;
|
|
128
|
+
constructor(tabId, frameId, cause, operation = "insert") {
|
|
129
|
+
const message = cause instanceof Error ? cause.message : String(cause);
|
|
130
|
+
const action = operation === "insert" ? "injection" : "removal";
|
|
131
|
+
super(
|
|
132
|
+
"InjectCssFrameDeliveryError",
|
|
133
|
+
"ERR_INJECT_CSS_FRAME_DELIVERY",
|
|
134
|
+
`CSS ${action} failed in frame ${frameId} of tab ${tabId}: ${message}`,
|
|
135
|
+
cause
|
|
136
|
+
);
|
|
137
|
+
this.tabId = tabId;
|
|
138
|
+
this.frameId = frameId;
|
|
139
|
+
this.operation = operation;
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
var InjectCssDeliveryError = class extends InjectCssBaseError {
|
|
143
|
+
target;
|
|
144
|
+
operation;
|
|
145
|
+
constructor(target, cause, operation = "insert") {
|
|
146
|
+
const causeMessage = cause instanceof Error ? cause.message : String(cause);
|
|
147
|
+
const action = operation === "insert" ? "injection" : "removal";
|
|
148
|
+
const message = cause instanceof InjectCssFrameDeliveryError ? causeMessage : `CSS ${action} failed: ${causeMessage}`;
|
|
149
|
+
super("InjectCssDeliveryError", "ERR_INJECT_CSS_DELIVERY", message, cause);
|
|
150
|
+
this.target = target;
|
|
151
|
+
this.operation = operation;
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
// src/validation.ts
|
|
156
|
+
var TARGET_KEYS = /* @__PURE__ */ new Set(["tabId", "allFrames", "frameIds", "documentIds"]);
|
|
157
|
+
var EXECUTION_OPTION_KEYS = /* @__PURE__ */ new Set(["matchAboutBlank", "runAt", "origin", "timeoutMs"]);
|
|
158
|
+
var INJECT_CSS_OPTION_KEYS = /* @__PURE__ */ new Set(["target", ...EXECUTION_OPTION_KEYS]);
|
|
159
|
+
var RUN_AT_VALUES = /* @__PURE__ */ new Set(["document_start", "document_end", "document_idle"]);
|
|
160
|
+
var ORIGIN_VALUES = /* @__PURE__ */ new Set(["AUTHOR", "USER"]);
|
|
161
|
+
var isObject = (value) => {
|
|
162
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
163
|
+
};
|
|
164
|
+
var assertKnownKeys = (value, keys, subject) => {
|
|
165
|
+
const unknownKeys = Object.keys(value).filter((key) => !keys.has(key));
|
|
166
|
+
if (unknownKeys.length > 0) {
|
|
167
|
+
throw new InvalidInjectCssOptionsError(
|
|
168
|
+
`${subject} contains unknown ${unknownKeys.length === 1 ? "field" : "fields"}: ${unknownKeys.map((key) => `"${key}"`).join(", ")}.`
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
var cloneTarget = (target) => {
|
|
173
|
+
if ("frameIds" in target && target.frameIds !== void 0) {
|
|
174
|
+
return { tabId: target.tabId, frameIds: [...target.frameIds] };
|
|
175
|
+
}
|
|
176
|
+
if ("documentIds" in target && target.documentIds !== void 0) {
|
|
177
|
+
return { tabId: target.tabId, documentIds: [...target.documentIds] };
|
|
178
|
+
}
|
|
179
|
+
if ("allFrames" in target && target.allFrames === true) {
|
|
180
|
+
return { tabId: target.tabId, allFrames: true };
|
|
181
|
+
}
|
|
182
|
+
return { tabId: target.tabId };
|
|
183
|
+
};
|
|
184
|
+
var validateInjectCssTarget = (value) => {
|
|
185
|
+
if (!isObject(value)) {
|
|
186
|
+
throw new InvalidInjectCssTargetError("target must be an object.");
|
|
187
|
+
}
|
|
188
|
+
const unknownKeys = Object.keys(value).filter((key) => !TARGET_KEYS.has(key));
|
|
189
|
+
if (unknownKeys.length > 0) {
|
|
190
|
+
throw new InvalidInjectCssTargetError(
|
|
191
|
+
`target contains unknown ${unknownKeys.length === 1 ? "field" : "fields"}: ${unknownKeys.map((key) => `"${key}"`).join(", ")}.`
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
if (!Number.isInteger(value.tabId) || value.tabId < 0) {
|
|
195
|
+
throw new InvalidInjectCssTargetError('"tabId" must be a non-negative integer.');
|
|
196
|
+
}
|
|
197
|
+
const selectors = ["allFrames", "frameIds", "documentIds"].filter((key) => value[key] !== void 0);
|
|
198
|
+
if (selectors.length > 1) {
|
|
199
|
+
throw new InvalidInjectCssTargetError('"allFrames", "frameIds", and "documentIds" are mutually exclusive.');
|
|
200
|
+
}
|
|
201
|
+
if (value.allFrames !== void 0 && value.allFrames !== true) {
|
|
202
|
+
throw new InvalidInjectCssTargetError('"allFrames" must be exactly true when provided.');
|
|
203
|
+
}
|
|
204
|
+
if (value.frameIds !== void 0) {
|
|
205
|
+
if (!Array.isArray(value.frameIds) || value.frameIds.length === 0) {
|
|
206
|
+
throw new InvalidInjectCssTargetError('"frameIds" must contain at least one frame ID.');
|
|
207
|
+
}
|
|
208
|
+
if (value.frameIds.some((frameId) => !Number.isInteger(frameId) || frameId < 0)) {
|
|
209
|
+
throw new InvalidInjectCssTargetError("frame ID must be a non-negative integer.");
|
|
210
|
+
}
|
|
211
|
+
if (new Set(value.frameIds).size !== value.frameIds.length) {
|
|
212
|
+
throw new InvalidInjectCssTargetError('"frameIds" must not contain duplicate frame IDs.');
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (value.documentIds !== void 0) {
|
|
216
|
+
if (!Array.isArray(value.documentIds) || value.documentIds.length === 0) {
|
|
217
|
+
throw new InvalidInjectCssTargetError('"documentIds" must contain at least one document ID.');
|
|
218
|
+
}
|
|
219
|
+
if (value.documentIds.some((documentId) => typeof documentId !== "string" || documentId.trim().length === 0)) {
|
|
220
|
+
throw new InvalidInjectCssTargetError("document ID must be a non-empty string.");
|
|
221
|
+
}
|
|
222
|
+
if (new Set(value.documentIds).size !== value.documentIds.length) {
|
|
223
|
+
throw new InvalidInjectCssTargetError('"documentIds" must not contain duplicate document IDs.');
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return cloneTarget(value);
|
|
227
|
+
};
|
|
228
|
+
var validateInjectCssExecutionOptions = (value) => {
|
|
229
|
+
if (!isObject(value)) {
|
|
230
|
+
throw new InvalidInjectCssOptionsError("execution options must be an object.");
|
|
231
|
+
}
|
|
232
|
+
assertKnownKeys(value, EXECUTION_OPTION_KEYS, "execution options");
|
|
233
|
+
if (value.matchAboutBlank !== void 0 && typeof value.matchAboutBlank !== "boolean") {
|
|
234
|
+
throw new InvalidInjectCssOptionsError('"matchAboutBlank" must be a boolean.');
|
|
235
|
+
}
|
|
236
|
+
if (value.runAt !== void 0 && (typeof value.runAt !== "string" || !RUN_AT_VALUES.has(value.runAt))) {
|
|
237
|
+
throw new InvalidInjectCssOptionsError('"runAt" must be "document_start", "document_end", or "document_idle".');
|
|
238
|
+
}
|
|
239
|
+
if (value.origin !== void 0 && (typeof value.origin !== "string" || !ORIGIN_VALUES.has(value.origin))) {
|
|
240
|
+
throw new InvalidInjectCssOptionsError('"origin" must be "AUTHOR" or "USER".');
|
|
241
|
+
}
|
|
242
|
+
if (value.timeoutMs !== void 0 && (typeof value.timeoutMs !== "number" || !Number.isInteger(value.timeoutMs) || value.timeoutMs <= 0)) {
|
|
243
|
+
throw new InvalidInjectCssOptionsError('"timeoutMs" must be a positive integer.');
|
|
244
|
+
}
|
|
245
|
+
return { ...value };
|
|
246
|
+
};
|
|
247
|
+
var validateInjectCssOptions = (value) => {
|
|
248
|
+
if (!isObject(value)) {
|
|
249
|
+
throw new InvalidInjectCssOptionsError("options must be an object.");
|
|
250
|
+
}
|
|
251
|
+
assertKnownKeys(value, INJECT_CSS_OPTION_KEYS, "options");
|
|
252
|
+
const { target, ...execution } = value;
|
|
253
|
+
return {
|
|
254
|
+
target: validateInjectCssTarget(target),
|
|
255
|
+
execution: validateInjectCssExecutionOptions(execution)
|
|
256
|
+
};
|
|
257
|
+
};
|
|
258
|
+
var validateInjectCssCode = (value) => {
|
|
259
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
260
|
+
throw new InvalidInjectCssCodeError("code must be a non-empty string.");
|
|
261
|
+
}
|
|
262
|
+
return value;
|
|
263
|
+
};
|
|
264
|
+
var validateInjectCssFiles = (files) => {
|
|
265
|
+
const fileList = typeof files === "string" ? [files] : files;
|
|
266
|
+
if (!Array.isArray(fileList) || fileList.length === 0) {
|
|
267
|
+
throw new InvalidInjectCssFilesError("at least one file is required.");
|
|
268
|
+
}
|
|
269
|
+
if (fileList.some((file) => typeof file !== "string" || file.trim().length === 0)) {
|
|
270
|
+
throw new InvalidInjectCssFilesError("each file must be a non-empty string.");
|
|
271
|
+
}
|
|
272
|
+
return [...fileList];
|
|
273
|
+
};
|
|
274
|
+
|
|
31
275
|
// src/AbstractInjectCss.ts
|
|
276
|
+
var DEFAULT_TIMEOUT_MS = 4e3;
|
|
32
277
|
var AbstractInjectCss_default = class {
|
|
33
|
-
|
|
34
|
-
|
|
278
|
+
_target;
|
|
279
|
+
_execution;
|
|
280
|
+
constructor(options) {
|
|
281
|
+
const normalized = validateInjectCssOptions(options);
|
|
282
|
+
this._target = normalized.target;
|
|
283
|
+
this._execution = normalized.execution;
|
|
284
|
+
}
|
|
285
|
+
target(target) {
|
|
286
|
+
const normalizedTarget = validateInjectCssTarget(target);
|
|
287
|
+
this.assertAdapterSupport(normalizedTarget, this._execution);
|
|
288
|
+
this._target = normalizedTarget;
|
|
289
|
+
return this;
|
|
35
290
|
}
|
|
36
291
|
options(options) {
|
|
37
|
-
|
|
292
|
+
const normalizedOptions = validateInjectCssExecutionOptions(options);
|
|
293
|
+
const nextExecution = { ...this._execution, ...normalizedOptions };
|
|
294
|
+
this.assertAdapterSupport(this._target, nextExecution);
|
|
295
|
+
this._execution = nextExecution;
|
|
38
296
|
return this;
|
|
39
297
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
298
|
+
validateCode(css) {
|
|
299
|
+
return validateInjectCssCode(css);
|
|
300
|
+
}
|
|
301
|
+
normalizeFiles(files) {
|
|
302
|
+
return validateInjectCssFiles(files);
|
|
303
|
+
}
|
|
304
|
+
snapshotTarget() {
|
|
305
|
+
return validateInjectCssTarget(this._target);
|
|
43
306
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return typeof frameId === "boolean" ? frameId : void 0;
|
|
307
|
+
snapshotExecution() {
|
|
308
|
+
return { ...this._execution };
|
|
47
309
|
}
|
|
48
|
-
get
|
|
49
|
-
|
|
50
|
-
|
|
310
|
+
get timeoutMs() {
|
|
311
|
+
return this._execution.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
312
|
+
}
|
|
313
|
+
async withTimeout(task, target, timeoutMs, operation = "insert") {
|
|
314
|
+
return new Promise((resolve, reject) => {
|
|
315
|
+
let settled = false;
|
|
316
|
+
const finish = (callback) => {
|
|
317
|
+
if (settled) return;
|
|
318
|
+
settled = true;
|
|
319
|
+
clearTimeout(timeoutId);
|
|
320
|
+
callback();
|
|
321
|
+
};
|
|
322
|
+
const timeoutId = setTimeout(() => {
|
|
323
|
+
finish(() => reject(new InjectCssTimeoutError(target, timeoutMs, operation)));
|
|
324
|
+
}, timeoutMs);
|
|
325
|
+
task.then(
|
|
326
|
+
(value) => finish(() => resolve(value)),
|
|
327
|
+
(error) => finish(() => reject(error))
|
|
328
|
+
);
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
deliveryError(target, error, operation = "insert") {
|
|
332
|
+
if (error instanceof InjectCssDeliveryError || error instanceof InjectCssTimeoutError) {
|
|
333
|
+
return error;
|
|
334
|
+
}
|
|
335
|
+
return new InjectCssDeliveryError(target, error, operation);
|
|
51
336
|
}
|
|
52
337
|
};
|
|
53
338
|
|
|
339
|
+
// src/native-errors.ts
|
|
340
|
+
var UNSUPPORTED_API_PATTERN = /(not supported|unsupported|not (?:available|implemented)|is not a function)\b/i;
|
|
341
|
+
var UNSUPPORTED_FIELD_PATTERN = /(not supported|unsupported|unexpected|unknown|unrecognized|invalid|not (?:a )?valid)\b/i;
|
|
342
|
+
var UNSUPPORTED_TARGET_FIELD_PATTERN = /(not supported|unsupported|unexpected|unknown|unrecognized)\b/i;
|
|
343
|
+
var getNativeErrorMessage = (error) => {
|
|
344
|
+
return error instanceof Error ? error.message : String(error);
|
|
345
|
+
};
|
|
346
|
+
var isUnsupportedRemovalCapabilityError = (error) => {
|
|
347
|
+
const message = getNativeErrorMessage(error);
|
|
348
|
+
return /remove\s*css/i.test(message) && UNSUPPORTED_API_PATTERN.test(message);
|
|
349
|
+
};
|
|
350
|
+
var isUnsupportedOriginCapabilityError = (error) => {
|
|
351
|
+
const message = getNativeErrorMessage(error);
|
|
352
|
+
return /\b(?:(?:css|style)[\s_-]*)?origin\b/i.test(message) && UNSUPPORTED_FIELD_PATTERN.test(message);
|
|
353
|
+
};
|
|
354
|
+
var isUnsupportedDocumentTargetCapabilityError = (error) => {
|
|
355
|
+
const message = getNativeErrorMessage(error);
|
|
356
|
+
return /documentIds?/i.test(message) && UNSUPPORTED_TARGET_FIELD_PATTERN.test(message);
|
|
357
|
+
};
|
|
358
|
+
|
|
54
359
|
// src/InjectCssV2.ts
|
|
55
360
|
var InjectCssV2_default = class extends AbstractInjectCss_default {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
await
|
|
68
|
-
}
|
|
69
|
-
|
|
361
|
+
constructor(options) {
|
|
362
|
+
super(options);
|
|
363
|
+
this.assertAdapterSupport(this._target, this._execution);
|
|
364
|
+
}
|
|
365
|
+
async insert(css) {
|
|
366
|
+
const code = this.validateCode(css);
|
|
367
|
+
const target = this.snapshotTarget();
|
|
368
|
+
const execution = this.snapshotExecution();
|
|
369
|
+
const timeoutMs = this.timeoutMs;
|
|
370
|
+
const details = this.createDetails("insert", execution, { code });
|
|
371
|
+
try {
|
|
372
|
+
await this.withTimeout(this.execute("insert", target, details), target, timeoutMs);
|
|
373
|
+
} catch (error) {
|
|
374
|
+
this.throwDeliveryError("insert", target, execution, error);
|
|
70
375
|
}
|
|
71
376
|
}
|
|
72
377
|
async file(files) {
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
378
|
+
const fileList = this.normalizeFiles(files);
|
|
379
|
+
await this.deliverFiles("insert", fileList);
|
|
380
|
+
}
|
|
381
|
+
async remove(css) {
|
|
382
|
+
const code = this.validateCode(css);
|
|
383
|
+
await this.removeSource({ code });
|
|
384
|
+
}
|
|
385
|
+
async removeFile(files) {
|
|
386
|
+
const fileList = this.normalizeFiles(files);
|
|
387
|
+
await this.deliverFiles("remove", fileList);
|
|
388
|
+
}
|
|
389
|
+
assertAdapterSupport(target, _execution) {
|
|
390
|
+
if ("documentIds" in target && target.documentIds !== void 0) {
|
|
391
|
+
throw new UnsupportedInjectCssTargetError('"documentIds" are not supported by the MV2 adapter.');
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
createDetails(operation, execution, source) {
|
|
395
|
+
return {
|
|
396
|
+
...source,
|
|
397
|
+
...operation === "insert" && execution.runAt !== void 0 ? { runAt: execution.runAt } : {},
|
|
398
|
+
...execution.origin !== void 0 ? { cssOrigin: execution.origin.toLowerCase() } : {},
|
|
399
|
+
...execution.matchAboutBlank !== void 0 ? { matchAboutBlank: execution.matchAboutBlank } : {}
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
async execute(operation, target, details) {
|
|
403
|
+
const deliver = operation === "insert" ? import_browser.insertCssTab : import_browser.removeCssTab;
|
|
404
|
+
if ("allFrames" in target && target.allFrames === true) {
|
|
405
|
+
await deliver(target.tabId, { ...details, allFrames: true });
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
if ("frameIds" in target && target.frameIds !== void 0) {
|
|
409
|
+
await Promise.all(
|
|
410
|
+
target.frameIds.map(
|
|
411
|
+
(frameId) => this.executeFrame(operation, target.tabId, frameId, { ...details, frameId })
|
|
412
|
+
)
|
|
413
|
+
);
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
await deliver(target.tabId, details);
|
|
417
|
+
}
|
|
418
|
+
async executeFrame(operation, tabId, frameId, details) {
|
|
419
|
+
try {
|
|
420
|
+
const deliver = operation === "insert" ? import_browser.insertCssTab : import_browser.removeCssTab;
|
|
421
|
+
await deliver(tabId, details);
|
|
422
|
+
} catch (error) {
|
|
423
|
+
throw new InjectCssFrameDeliveryError(tabId, frameId, error, operation);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
async removeSource(source) {
|
|
427
|
+
const target = this.snapshotTarget();
|
|
428
|
+
const execution = this.snapshotExecution();
|
|
429
|
+
const timeoutMs = this.timeoutMs;
|
|
430
|
+
this.assertRemovalSupport();
|
|
431
|
+
try {
|
|
432
|
+
await this.withTimeout(
|
|
433
|
+
this.execute("remove", target, this.createDetails("remove", execution, source)),
|
|
434
|
+
target,
|
|
435
|
+
timeoutMs,
|
|
436
|
+
"remove"
|
|
437
|
+
);
|
|
438
|
+
} catch (error) {
|
|
439
|
+
this.throwDeliveryError("remove", target, execution, error);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
async deliverFiles(operation, fileList) {
|
|
443
|
+
const target = this.snapshotTarget();
|
|
444
|
+
const execution = this.snapshotExecution();
|
|
445
|
+
const timeoutMs = this.timeoutMs;
|
|
446
|
+
let stopped = false;
|
|
447
|
+
if (operation === "remove") {
|
|
448
|
+
this.assertRemovalSupport();
|
|
449
|
+
}
|
|
450
|
+
const task = (async () => {
|
|
451
|
+
for (const file of fileList) {
|
|
452
|
+
if (stopped) return;
|
|
453
|
+
await this.execute(operation, target, this.createDetails(operation, execution, { file }));
|
|
89
454
|
}
|
|
455
|
+
})();
|
|
456
|
+
try {
|
|
457
|
+
await this.withTimeout(task, target, timeoutMs, operation);
|
|
458
|
+
} catch (error) {
|
|
459
|
+
stopped = true;
|
|
460
|
+
this.throwDeliveryError(operation, target, execution, error);
|
|
90
461
|
}
|
|
91
|
-
await Promise.all(injectTasks);
|
|
92
462
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
463
|
+
assertRemovalSupport() {
|
|
464
|
+
if (typeof (0, import_browser.browser)().tabs?.removeCSS !== "function") {
|
|
465
|
+
throw new UnsupportedInjectCssOperationError(
|
|
466
|
+
"remove",
|
|
467
|
+
'the current MV2 browser does not expose "tabs.removeCSS".'
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
throwDeliveryError(operation, target, execution, error) {
|
|
472
|
+
if (operation === "remove" && isUnsupportedRemovalCapabilityError(error)) {
|
|
473
|
+
throw new UnsupportedInjectCssOperationError(
|
|
474
|
+
"remove",
|
|
475
|
+
'the current MV2 browser does not support "tabs.removeCSS".',
|
|
476
|
+
error
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
if (execution.origin !== void 0 && isUnsupportedOriginCapabilityError(error)) {
|
|
480
|
+
throw new UnsupportedInjectCssOptionError('"origin" is not supported by the current browser.', error);
|
|
481
|
+
}
|
|
482
|
+
throw this.deliveryError(target, error, operation);
|
|
96
483
|
}
|
|
97
484
|
};
|
|
98
485
|
|
|
99
486
|
// src/InjectCssV3.ts
|
|
100
487
|
var import_browser2 = require("@addon-core/browser");
|
|
101
488
|
var InjectCssV3_default = class extends AbstractInjectCss_default {
|
|
489
|
+
constructor(options) {
|
|
490
|
+
super(options);
|
|
491
|
+
this.assertAdapterSupport(this._target, this._execution);
|
|
492
|
+
}
|
|
102
493
|
async insert(css) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
494
|
+
const code = this.validateCode(css);
|
|
495
|
+
const target = this.snapshotTarget();
|
|
496
|
+
const execution = this.snapshotExecution();
|
|
497
|
+
const timeoutMs = this.timeoutMs;
|
|
498
|
+
await this.execute(
|
|
499
|
+
"insert",
|
|
500
|
+
target,
|
|
501
|
+
execution,
|
|
502
|
+
{
|
|
503
|
+
target: this.toNativeTarget(target),
|
|
504
|
+
css: code,
|
|
505
|
+
...execution.origin !== void 0 ? { origin: execution.origin } : {}
|
|
506
|
+
},
|
|
507
|
+
timeoutMs
|
|
508
|
+
);
|
|
108
509
|
}
|
|
109
|
-
async file(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
510
|
+
async file(files) {
|
|
511
|
+
const fileList = this.normalizeFiles(files);
|
|
512
|
+
const target = this.snapshotTarget();
|
|
513
|
+
const execution = this.snapshotExecution();
|
|
514
|
+
const timeoutMs = this.timeoutMs;
|
|
515
|
+
await this.execute(
|
|
516
|
+
"insert",
|
|
517
|
+
target,
|
|
518
|
+
execution,
|
|
519
|
+
{
|
|
520
|
+
target: this.toNativeTarget(target),
|
|
521
|
+
files: fileList,
|
|
522
|
+
...execution.origin !== void 0 ? { origin: execution.origin } : {}
|
|
523
|
+
},
|
|
524
|
+
timeoutMs
|
|
525
|
+
);
|
|
526
|
+
}
|
|
527
|
+
async remove(css) {
|
|
528
|
+
const code = this.validateCode(css);
|
|
529
|
+
await this.removeInjection({ css: code });
|
|
115
530
|
}
|
|
116
|
-
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
531
|
+
async removeFile(files) {
|
|
532
|
+
const fileList = this.normalizeFiles(files);
|
|
533
|
+
await this.removeInjection({ files: fileList });
|
|
534
|
+
}
|
|
535
|
+
assertAdapterSupport(_target, execution) {
|
|
536
|
+
if (execution.matchAboutBlank !== void 0) {
|
|
537
|
+
throw new UnsupportedInjectCssOptionError('"matchAboutBlank" is not supported by the MV3 adapter.');
|
|
120
538
|
}
|
|
121
|
-
if (
|
|
122
|
-
|
|
539
|
+
if (execution.runAt !== void 0) {
|
|
540
|
+
throw new UnsupportedInjectCssOptionError('"runAt" is not supported by the MV3 adapter.');
|
|
123
541
|
}
|
|
124
|
-
|
|
542
|
+
}
|
|
543
|
+
async execute(operation, target, execution, injection, timeoutMs) {
|
|
125
544
|
try {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
545
|
+
const task = operation === "insert" ? (0, import_browser2.insertCss)(injection) : (0, import_browser2.removeCss)(injection);
|
|
546
|
+
await this.withTimeout(task, target, timeoutMs, operation);
|
|
547
|
+
} catch (error) {
|
|
548
|
+
if ("documentIds" in target && target.documentIds !== void 0 && isUnsupportedDocumentTargetCapabilityError(error)) {
|
|
549
|
+
throw new UnsupportedInjectCssTargetError(
|
|
550
|
+
'"documentIds" are not supported by the current browser.',
|
|
551
|
+
error
|
|
552
|
+
);
|
|
553
|
+
}
|
|
554
|
+
if (operation === "remove" && isUnsupportedRemovalCapabilityError(error)) {
|
|
555
|
+
throw new UnsupportedInjectCssOperationError(
|
|
556
|
+
"remove",
|
|
557
|
+
'the current MV3 browser does not support "scripting.removeCSS".',
|
|
558
|
+
error
|
|
559
|
+
);
|
|
560
|
+
}
|
|
561
|
+
if (execution.origin !== void 0 && isUnsupportedOriginCapabilityError(error)) {
|
|
562
|
+
throw new UnsupportedInjectCssOptionError('"origin" is not supported by the current browser.', error);
|
|
133
563
|
}
|
|
564
|
+
throw this.deliveryError(target, error, operation);
|
|
134
565
|
}
|
|
135
|
-
return target;
|
|
136
566
|
}
|
|
137
|
-
|
|
138
|
-
const
|
|
139
|
-
|
|
567
|
+
async removeInjection(source) {
|
|
568
|
+
const target = this.snapshotTarget();
|
|
569
|
+
const execution = this.snapshotExecution();
|
|
570
|
+
const timeoutMs = this.timeoutMs;
|
|
571
|
+
this.assertRemovalSupport();
|
|
572
|
+
await this.execute(
|
|
573
|
+
"remove",
|
|
574
|
+
target,
|
|
575
|
+
execution,
|
|
576
|
+
{
|
|
577
|
+
target: this.toNativeTarget(target),
|
|
578
|
+
...source,
|
|
579
|
+
...execution.origin !== void 0 ? { origin: execution.origin } : {}
|
|
580
|
+
},
|
|
581
|
+
timeoutMs
|
|
582
|
+
);
|
|
583
|
+
}
|
|
584
|
+
assertRemovalSupport() {
|
|
585
|
+
if (typeof (0, import_browser2.browser)().scripting?.removeCSS !== "function") {
|
|
586
|
+
throw new UnsupportedInjectCssOperationError(
|
|
587
|
+
"remove",
|
|
588
|
+
'the current MV3 browser does not expose "scripting.removeCSS".'
|
|
589
|
+
);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
toNativeTarget(target) {
|
|
593
|
+
if ("frameIds" in target && target.frameIds !== void 0) {
|
|
594
|
+
return { tabId: target.tabId, frameIds: [...target.frameIds] };
|
|
595
|
+
}
|
|
596
|
+
if ("documentIds" in target && target.documentIds !== void 0) {
|
|
597
|
+
return { tabId: target.tabId, documentIds: [...target.documentIds] };
|
|
598
|
+
}
|
|
599
|
+
if ("allFrames" in target && target.allFrames === true) {
|
|
600
|
+
return { tabId: target.tabId, allFrames: true };
|
|
601
|
+
}
|
|
602
|
+
return { tabId: target.tabId };
|
|
140
603
|
}
|
|
141
604
|
};
|
|
142
605
|
|
|
143
606
|
// src/index.ts
|
|
144
|
-
var
|
|
607
|
+
var injectCss = (options) => {
|
|
145
608
|
return (0, import_browser3.isManifestVersion3)() ? new InjectCssV3_default(options) : new InjectCssV2_default(options);
|
|
146
609
|
};
|
|
610
|
+
var index_default = injectCss;
|
|
611
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
612
|
+
0 && (module.exports = {
|
|
613
|
+
InjectCssBaseError,
|
|
614
|
+
InjectCssDeliveryError,
|
|
615
|
+
InjectCssFrameDeliveryError,
|
|
616
|
+
InjectCssTimeoutError,
|
|
617
|
+
InvalidInjectCssCodeError,
|
|
618
|
+
InvalidInjectCssFilesError,
|
|
619
|
+
InvalidInjectCssOptionsError,
|
|
620
|
+
InvalidInjectCssTargetError,
|
|
621
|
+
UnsupportedInjectCssOperationError,
|
|
622
|
+
UnsupportedInjectCssOptionError,
|
|
623
|
+
UnsupportedInjectCssTargetError,
|
|
624
|
+
injectCss
|
|
625
|
+
});
|
|
147
626
|
//# sourceMappingURL=index.cjs.map
|