browser-extension-utils 0.0.15 → 0.1.1

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/lib/index.d.ts CHANGED
@@ -1,34 +1,28 @@
1
+ export const doc: Document
2
+
1
3
  export function uniq(array: any[]): any[]
2
4
 
3
5
  export function toCamelCase(text: string): string
4
6
 
5
- export function $(selectors: string): HTMLElement
6
-
7
7
  export function $(
8
- element: HTMLElement | Document | string,
9
- selectors: string
10
- ): HTMLElement
11
-
12
- export function querySelector(selectors: string): HTMLElement
8
+ selectors: string,
9
+ element?: HTMLElement | Document
10
+ ): Element | undefined
13
11
 
14
12
  export function querySelector(
15
- element: HTMLElement | Document | string,
16
- selectors: string
17
- ): HTMLElement
18
-
19
- export function $$(selectors: string): HTMLElement[]
13
+ selectors: string,
14
+ element?: HTMLElement | Document
15
+ ): Element | undefined
20
16
 
21
17
  export function $$(
22
- element: HTMLElement | Document | string,
23
- selectors: string
24
- ): HTMLElement[]
25
-
26
- export function querySelectorAll(selectors: string): HTMLElement[]
18
+ selectors: string,
19
+ element?: HTMLElement | Document
20
+ ): Element[]
27
21
 
28
22
  export function querySelectorAll(
29
- element: HTMLElement | Document | string,
30
- selectors: string
31
- ): HTMLElement[]
23
+ selectors: string,
24
+ element?: HTMLElement | Document
25
+ ): Element[]
32
26
 
33
27
  export function createElement(
34
28
  tagName: string,
@@ -85,6 +79,12 @@ export function setAttributes(
85
79
  attributes: Record<string, unknown>
86
80
  ): void
87
81
 
82
+ export function addAttribute(
83
+ element: HTMLElement,
84
+ name: string,
85
+ value: string
86
+ ): void
87
+
88
88
  export type SetStyle = (
89
89
  element: HTMLElement,
90
90
  style: string | Record<string, unknown>,
@@ -105,9 +105,13 @@ export function createSetStyle(styleText: string): SetStyle
105
105
 
106
106
  export function isUrl(text: string): boolean
107
107
 
108
+ export function throttle(func: Function, interval: number): Function
109
+
108
110
  export type MenuCallback = (event?: MouseEvent | KeyboardEvent) => void
109
111
  export function registerMenuCommand(
110
112
  name: string,
111
113
  callback: MenuCallback,
112
114
  accessKey?: string
113
115
  ): void
116
+
117
+ export function extendHistoryApi(): void
package/lib/index.js CHANGED
@@ -1,4 +1,4 @@
1
- const doc = document
1
+ export const doc = document
2
2
 
3
3
  export const uniq = (array) => [...new Set(array)]
4
4
 
@@ -9,14 +9,11 @@ export const toCamelCase = function (text) {
9
9
  })
10
10
  }
11
11
 
12
- export const $ = (element, selectors) =>
13
- element && typeof element === "object"
14
- ? element.querySelector(selectors)
15
- : doc.querySelector(element)
16
- export const $$ = (element, selectors) =>
17
- element && typeof element === "object"
18
- ? [...element.querySelectorAll(selectors)]
19
- : [...doc.querySelectorAll(element)]
12
+ export const $ = (selectors, element) =>
13
+ (element || doc).querySelector(selectors)
14
+ export const $$ = (selectors, element) => [
15
+ ...(element || doc).querySelectorAll(selectors),
16
+ ]
20
17
  export const querySelector = $
21
18
  export const querySelectorAll = $$
22
19
 
@@ -115,6 +112,15 @@ export const setAttributes = (element, attributes) => {
115
112
  return element
116
113
  }
117
114
 
115
+ export const addAttribute = (element, name, value) => {
116
+ const orgValue = getAttribute(element, name)
117
+ if (!orgValue) {
118
+ setAttribute(element, name, value)
119
+ } else if (!orgValue.includes(value)) {
120
+ setAttribute(element, name, orgValue + " " + value)
121
+ }
122
+ }
123
+
118
124
  export const setStyle = (element, values, overwrite) => {
119
125
  if (!element) {
120
126
  return
@@ -186,9 +192,65 @@ export const createSetStyle = (styleText) => {
186
192
 
187
193
  export const isUrl = (text) => /^https?:\/\//.test(text)
188
194
 
195
+ /**
196
+ *
197
+ * @param { function } func
198
+ * @param { number } interval
199
+ * @returns
200
+ */
201
+ export const throttle = (func, interval) => {
202
+ let timeoutId = null
203
+ let next = false
204
+ const handler = (...args) => {
205
+ if (timeoutId) {
206
+ next = true
207
+ } else {
208
+ func.apply(this, args)
209
+ timeoutId = setTimeout(() => {
210
+ timeoutId = null
211
+ if (next) {
212
+ next = false
213
+ handler()
214
+ }
215
+ }, interval)
216
+ }
217
+ }
218
+
219
+ return handler
220
+ }
221
+
189
222
  if (typeof Object.hasOwn !== "function") {
190
223
  Object.hasOwn = (instance, prop) =>
191
224
  Object.prototype.hasOwnProperty.call(instance, prop)
192
225
  }
193
226
 
194
227
  export const registerMenuCommand = () => undefined
228
+
229
+ export const extendHistoryApi = () => {
230
+ // https://dirask.com/posts/JavaScript-on-location-changed-event-on-url-changed-event-DKeyZj
231
+ const pushState = history.pushState
232
+ const replaceState = history.replaceState
233
+
234
+ history.pushState = function () {
235
+ // eslint-disable-next-line prefer-rest-params
236
+ pushState.apply(history, arguments)
237
+ window.dispatchEvent(new Event("pushstate"))
238
+ window.dispatchEvent(new Event("locationchange"))
239
+ }
240
+
241
+ history.replaceState = function () {
242
+ // eslint-disable-next-line prefer-rest-params
243
+ replaceState.apply(history, arguments)
244
+ window.dispatchEvent(new Event("replacestate"))
245
+ window.dispatchEvent(new Event("locationchange"))
246
+ }
247
+
248
+ window.addEventListener("popstate", function () {
249
+ window.dispatchEvent(new Event("locationchange"))
250
+ })
251
+
252
+ // Usage example:
253
+ // window.addEventListener("locationchange", function () {
254
+ // console.log("onlocationchange event occurred!")
255
+ // })
256
+ }
package/lib/userscript.js CHANGED
@@ -1,4 +1,9 @@
1
- import { setAttributes } from "./index.js"
1
+ import {
2
+ doc,
3
+ setAttributes,
4
+ addElement as _addElement,
5
+ addStyle as _addStyle,
6
+ } from "./index.js"
2
7
 
3
8
  export * from "./index.js"
4
9
 
@@ -15,23 +20,50 @@ process.env.PLASMO_TAG === "dev" &&
15
20
  }
16
21
  })()
17
22
 
18
- /* eslint-disable new-cap */
19
- export const addElement = (parentNode, tagName, attributes) => {
20
- if (typeof parentNode === "string" || typeof tagName === "string") {
21
- const element = GM_addElement(parentNode, tagName, attributes)
22
- setAttributes(element, attributes)
23
- return element
24
- }
23
+ /* eslint-disable new-cap, camelcase */
24
+ export const addElement =
25
+ typeof GM_addElement === "function"
26
+ ? (parentNode, tagName, attributes) => {
27
+ if (!parentNode) {
28
+ return
29
+ }
25
30
 
26
- // tagName: HTMLElement
27
- setAttributes(tagName, attributes)
28
- parentNode.append(tagName)
29
- return tagName
30
- }
31
+ if (typeof parentNode === "string") {
32
+ attributes = tagName
33
+ tagName = parentNode
34
+ parentNode = doc.head
35
+ }
31
36
 
32
- export const addStyle = (styleText) => GM_addStyle(styleText)
37
+ if (typeof tagName === "string") {
38
+ const element = GM_addElement(tagName)
39
+ setAttributes(element, attributes)
40
+ parentNode.append(element)
41
+ return element
42
+ }
43
+
44
+ // tagName: HTMLElement
45
+ setAttributes(tagName, attributes)
46
+ parentNode.append(tagName)
47
+ return tagName
48
+ }
49
+ : _addElement
50
+
51
+ export const addStyle =
52
+ typeof GM_addStyle === "function"
53
+ ? (styleText) => GM_addStyle(styleText)
54
+ : _addStyle
33
55
 
34
56
  // Only register menu on top frame
35
- export const registerMenuCommand = (name, callback, accessKey) =>
36
- window === top && GM_registerMenuCommand(name, callback, accessKey)
37
- /* eslint-enable new-cap */
57
+ export const registerMenuCommand = (name, callback, accessKey) => {
58
+ if (window !== top) {
59
+ return
60
+ }
61
+
62
+ if (typeof GM.registerMenuCommand !== "function") {
63
+ console.warn("Do not support GM.registerMenuCommand!")
64
+ return
65
+ }
66
+
67
+ GM.registerMenuCommand(name, callback, accessKey)
68
+ }
69
+ /* eslint-enable new-cap, camelcase */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browser-extension-utils",
3
- "version": "0.0.15",
3
+ "version": "0.1.1",
4
4
  "description": "Utilities for developing browser extensions and userscripts",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -29,8 +29,8 @@
29
29
  },
30
30
  "homepage": "https://github.com/PipecraftNet/browser-extension-utils#readme",
31
31
  "devDependencies": {
32
- "prettier": "^2.8.7",
33
- "xo": "^0.53.1"
32
+ "prettier": "^2.8.8",
33
+ "xo": "^0.54.2"
34
34
  },
35
35
  "files": [
36
36
  "lib/",
@@ -44,9 +44,11 @@
44
44
  "space": 2,
45
45
  "prettier": true,
46
46
  "globals": [
47
+ "GM",
47
48
  "GM_addElement",
48
49
  "GM_addStyle",
49
50
  "GM_registerMenuCommand",
51
+ "history",
50
52
  "window",
51
53
  "top",
52
54
  "document"