browser-extension-settings 0.0.3 → 0.0.5
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/common.ts +1 -0
- package/lib/extension-list.ts +97 -24
- package/lib/settings.ts +103 -22
- package/lib/style.scss +28 -0
- package/package.json +1 -1
package/lib/common.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
+
export const besVersion = 12
|
|
1
2
|
export const openButton = `<svg viewBox="0 0 60.2601318359375 84.8134765625" version="1.1" xmlns="http://www.w3.org/2000/svg" class=" glyph-box" style="height: 9.62969px; width: 6.84191px;"><g transform="matrix(1 0 0 1 -6.194965820312518 77.63671875)"><path d="M66.4551-35.2539C66.4551-36.4746 65.9668-37.5977 65.0391-38.4766L26.3672-76.3672C25.4883-77.1973 24.4141-77.6367 23.1445-77.6367C20.6543-77.6367 18.7012-75.7324 18.7012-73.1934C18.7012-71.9727 19.1895-70.8496 19.9707-70.0195L55.5176-35.2539L19.9707-0.488281C19.1895 0.341797 18.7012 1.41602 18.7012 2.68555C18.7012 5.22461 20.6543 7.12891 23.1445 7.12891C24.4141 7.12891 25.4883 6.68945 26.3672 5.81055L65.0391-32.0312C65.9668-32.959 66.4551-34.0332 66.4551-35.2539Z"></path></g></svg>`
|
|
2
3
|
export const openInNewTabButton = `<svg viewBox="0 0 72.127685546875 72.2177734375" version="1.1" xmlns="http://www.w3.org/2000/svg" class=" glyph-box" style="height: 8.19958px; width: 8.18935px;"><g transform="matrix(1 0 0 1 -12.451127929687573 71.3388671875)"><path d="M84.5703-17.334L84.5215-66.4551C84.5215-69.2383 82.7148-71.1914 79.7852-71.1914L30.6641-71.1914C27.9297-71.1914 26.0742-69.0918 26.0742-66.748C26.0742-64.4043 28.1738-62.4023 30.4688-62.4023L47.4609-62.4023L71.2891-63.1836L62.207-55.2246L13.8184-6.73828C12.9395-5.85938 12.4512-4.73633 12.4512-3.66211C12.4512-1.31836 14.5508 0.878906 16.9922 0.878906C18.1152 0.878906 19.1895 0.488281 20.0684-0.439453L68.5547-48.877L76.6113-58.0078L75.7324-35.2051L75.7324-17.1387C75.7324-14.8438 77.7344-12.6953 80.127-12.6953C82.4707-12.6953 84.5703-14.6973 84.5703-17.334Z"></path></g></svg>`
|
package/lib/extension-list.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
$,
|
|
3
|
+
$$,
|
|
4
|
+
addClass,
|
|
5
|
+
addElement,
|
|
6
|
+
createElement,
|
|
7
|
+
removeClass,
|
|
8
|
+
} from "browser-extension-utils"
|
|
2
9
|
import { openButton, openInNewTabButton } from "./common"
|
|
3
10
|
|
|
4
11
|
type InstalledExtension = {
|
|
@@ -27,6 +34,11 @@ const relatedExtensions: RelatedExtension[] = [
|
|
|
27
34
|
description: "在新标签页中打开第三方网站链接,图片链接转图片标签等",
|
|
28
35
|
url: "https://greasyfork.org/scripts/464541",
|
|
29
36
|
},
|
|
37
|
+
{
|
|
38
|
+
id: "v2ex.rep",
|
|
39
|
+
title: "V2EX.REP - 专注提升 V2EX 主题回复浏览体验",
|
|
40
|
+
url: "https://greasyfork.org/scripts/466589",
|
|
41
|
+
},
|
|
30
42
|
{
|
|
31
43
|
id: "v2ex.min",
|
|
32
44
|
title: "v2ex.min - V2EX 极简风格",
|
|
@@ -38,25 +50,72 @@ const getInstalledExtesionList = () => {
|
|
|
38
50
|
return $(".extension_list_container .installed_extension_list")
|
|
39
51
|
}
|
|
40
52
|
|
|
53
|
+
const getRelatedExtesionList = () => {
|
|
54
|
+
return $(".extension_list_container .related_extension_list")
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const isInstalledExtension = (id: string) => {
|
|
58
|
+
const list = getInstalledExtesionList()
|
|
59
|
+
if (!list) {
|
|
60
|
+
return false
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const installed = $(`[data-extension-id="${id}"]`, list)
|
|
64
|
+
return Boolean(installed)
|
|
65
|
+
}
|
|
66
|
+
|
|
41
67
|
export const addCurrentExtension = (extension: InstalledExtension) => {
|
|
42
68
|
const list = getInstalledExtesionList()
|
|
43
69
|
if (!list) {
|
|
44
70
|
return
|
|
45
71
|
}
|
|
46
72
|
|
|
47
|
-
|
|
48
|
-
const added = $(`[data-extension-id="${id}"]`, list)
|
|
49
|
-
if (added) {
|
|
73
|
+
if (isInstalledExtension(extension.id)) {
|
|
50
74
|
return
|
|
51
75
|
}
|
|
52
76
|
|
|
53
77
|
const element = createInstalledExtension(extension)
|
|
54
78
|
list.append(element)
|
|
79
|
+
|
|
80
|
+
const list2 = getRelatedExtesionList()
|
|
81
|
+
if (list2) {
|
|
82
|
+
updateRelatedExtensions(list2)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export const activeExtension = (id: string) => {
|
|
87
|
+
const list = getInstalledExtesionList()
|
|
88
|
+
if (!list) {
|
|
89
|
+
return false
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
for (const element of $$(".active", list)) {
|
|
93
|
+
removeClass(element, "active")
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const installed = $(`[data-extension-id="${id}"]`, list)
|
|
97
|
+
if (installed) {
|
|
98
|
+
addClass(installed, "active")
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export const activeExtensionList = () => {
|
|
103
|
+
const extensionListContainer = $(".extension_list_container")
|
|
104
|
+
if (extensionListContainer) {
|
|
105
|
+
addClass(extensionListContainer, "bes_active")
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export const deactiveExtensionList = () => {
|
|
110
|
+
const extensionListContainer = $(".extension_list_container")
|
|
111
|
+
if (extensionListContainer) {
|
|
112
|
+
removeClass(extensionListContainer, "bes_active")
|
|
113
|
+
}
|
|
55
114
|
}
|
|
56
115
|
|
|
57
116
|
const createInstalledExtension = (installedExtension: InstalledExtension) => {
|
|
58
117
|
const div = createElement("div", {
|
|
59
|
-
class: "
|
|
118
|
+
class: "installed_extension",
|
|
60
119
|
"data-extension-id": installedExtension.id,
|
|
61
120
|
})
|
|
62
121
|
const a = addElement(div, "a", {
|
|
@@ -71,6 +130,33 @@ const createInstalledExtension = (installedExtension: InstalledExtension) => {
|
|
|
71
130
|
return div
|
|
72
131
|
}
|
|
73
132
|
|
|
133
|
+
const updateRelatedExtensions = (container: HTMLElement) => {
|
|
134
|
+
container.innerHTML = ""
|
|
135
|
+
|
|
136
|
+
for (const relatedExtension of relatedExtensions) {
|
|
137
|
+
// console.log(relatedExtension)
|
|
138
|
+
|
|
139
|
+
if (isInstalledExtension(relatedExtension.id)) {
|
|
140
|
+
continue
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const div4 = addElement(container, "div", {
|
|
144
|
+
class: "related_extension",
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
const a = addElement(div4, "a", {
|
|
148
|
+
href: relatedExtension.url,
|
|
149
|
+
target: "_blank",
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
addElement(a, "span", {
|
|
153
|
+
textContent: relatedExtension.title,
|
|
154
|
+
})
|
|
155
|
+
const svg = addElement(a, "svg")
|
|
156
|
+
svg.outerHTML = openInNewTabButton
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
74
160
|
export function createExtensionList(installedExtensions: InstalledExtension[]) {
|
|
75
161
|
const div = createElement("div", {
|
|
76
162
|
class: "extension_list_container thin_scrollbar",
|
|
@@ -82,7 +168,11 @@ export function createExtensionList(installedExtensions: InstalledExtension[]) {
|
|
|
82
168
|
class: "installed_extension_list",
|
|
83
169
|
})
|
|
84
170
|
for (const installedExtension of installedExtensions) {
|
|
85
|
-
console.log(installedExtension)
|
|
171
|
+
// console.log(installedExtension)
|
|
172
|
+
|
|
173
|
+
if (isInstalledExtension(installedExtension.id)) {
|
|
174
|
+
continue
|
|
175
|
+
}
|
|
86
176
|
|
|
87
177
|
const element = createInstalledExtension(installedExtension)
|
|
88
178
|
div2.append(element)
|
|
@@ -92,24 +182,7 @@ export function createExtensionList(installedExtensions: InstalledExtension[]) {
|
|
|
92
182
|
const div3 = addElement(div, "div", {
|
|
93
183
|
class: "related_extension_list",
|
|
94
184
|
})
|
|
95
|
-
|
|
96
|
-
console.log(relatedExtension)
|
|
97
|
-
|
|
98
|
-
const div4 = addElement(div3, "div", {
|
|
99
|
-
class: "related_extension",
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
const a = addElement(div4, "a", {
|
|
103
|
-
href: relatedExtension.url,
|
|
104
|
-
target: "_blank",
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
addElement(a, "span", {
|
|
108
|
-
textContent: relatedExtension.title,
|
|
109
|
-
})
|
|
110
|
-
const svg = addElement(a, "svg")
|
|
111
|
-
svg.outerHTML = openInNewTabButton
|
|
112
|
-
}
|
|
185
|
+
updateRelatedExtensions(div3)
|
|
113
186
|
|
|
114
187
|
return div
|
|
115
188
|
}
|
package/lib/settings.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
$,
|
|
8
8
|
$$,
|
|
9
|
+
addClass,
|
|
9
10
|
addElement,
|
|
10
11
|
addEventListener,
|
|
11
12
|
addStyle,
|
|
@@ -15,7 +16,14 @@ import {
|
|
|
15
16
|
} from "browser-extension-utils"
|
|
16
17
|
import styleText from "data-text:./style.scss"
|
|
17
18
|
import { createSwitchOption } from "./switch"
|
|
18
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
createExtensionList,
|
|
21
|
+
addCurrentExtension,
|
|
22
|
+
activeExtension,
|
|
23
|
+
activeExtensionList,
|
|
24
|
+
deactiveExtensionList,
|
|
25
|
+
} from "./extension-list"
|
|
26
|
+
import { besVersion } from "./common"
|
|
19
27
|
|
|
20
28
|
const prefix = "browser_extension_settings_"
|
|
21
29
|
|
|
@@ -28,13 +36,19 @@ type SettingsOptions = {
|
|
|
28
36
|
relatedExtensions?: RelatedExtension[]
|
|
29
37
|
}
|
|
30
38
|
|
|
31
|
-
type SettingsTable = Record<string, SettingsSwitchItem>
|
|
39
|
+
type SettingsTable = Record<string, SettingsSwitchItem | SettingsInputItem>
|
|
32
40
|
|
|
33
41
|
type SettingsSwitchItem = {
|
|
34
42
|
title: string
|
|
35
43
|
defaultValue: boolean
|
|
36
44
|
}
|
|
37
45
|
|
|
46
|
+
type SettingsInputItem = {
|
|
47
|
+
title: string
|
|
48
|
+
defaultValue: string
|
|
49
|
+
type: string
|
|
50
|
+
}
|
|
51
|
+
|
|
38
52
|
type RelatedExtension = {
|
|
39
53
|
id: string
|
|
40
54
|
title: string
|
|
@@ -48,11 +62,14 @@ type InstalledExtension = {
|
|
|
48
62
|
version: string
|
|
49
63
|
}
|
|
50
64
|
|
|
51
|
-
const
|
|
52
|
-
|
|
65
|
+
const randomId = String(Math.round(Math.random() * 10_000))
|
|
66
|
+
const settingsContainerId = prefix + "container_" + randomId
|
|
67
|
+
const settingsElementId = prefix + "main_" + randomId
|
|
53
68
|
const getSettingsElement = () => $("#" + settingsElementId)
|
|
54
69
|
const getSettingsStyle: () => string = () =>
|
|
55
|
-
styleText
|
|
70
|
+
styleText
|
|
71
|
+
.replace(/browser_extension_settings_container/gm, settingsContainerId)
|
|
72
|
+
.replace(/browser_extension_settings_main/gm, settingsElementId)
|
|
56
73
|
const storageKey = "settings"
|
|
57
74
|
|
|
58
75
|
let settingsOptions: SettingsOptions
|
|
@@ -80,7 +97,17 @@ export function getSettingsValue(key: string): boolean | string | undefined {
|
|
|
80
97
|
: settingsTable[key]?.defaultValue
|
|
81
98
|
}
|
|
82
99
|
|
|
83
|
-
const
|
|
100
|
+
const closeModal = () => {
|
|
101
|
+
const settingsContainer = getSettingsContainer()
|
|
102
|
+
if (settingsContainer) {
|
|
103
|
+
settingsContainer.style.display = "none"
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
removeEventListener(document, "click", onDocumentClick)
|
|
107
|
+
removeEventListener(document, "keydown", onDocumentKeyDown)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const onDocumentClick = (event) => {
|
|
84
111
|
let target = event.target as HTMLElement
|
|
85
112
|
const settingsContainer = getSettingsContainer()
|
|
86
113
|
if (settingsContainer) {
|
|
@@ -91,11 +118,30 @@ const modalHandler = (event) => {
|
|
|
91
118
|
if (target === settingsContainer) {
|
|
92
119
|
return
|
|
93
120
|
}
|
|
121
|
+
}
|
|
94
122
|
|
|
95
|
-
|
|
123
|
+
closeModal()
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const onDocumentKeyDown = (event) => {
|
|
127
|
+
if (event.defaultPrevented) {
|
|
128
|
+
return // 如果事件已经在进行中,则不做任何事。
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
switch (event.key) {
|
|
132
|
+
case "Escape": {
|
|
133
|
+
// 按“ESC”键时要做的事。
|
|
134
|
+
closeModal()
|
|
135
|
+
break
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
default: {
|
|
139
|
+
return
|
|
140
|
+
} // 什么都没按就退出吧。
|
|
96
141
|
}
|
|
97
142
|
|
|
98
|
-
|
|
143
|
+
// 取消默认动作,从而避免处理两次。
|
|
144
|
+
event.preventDefault()
|
|
99
145
|
}
|
|
100
146
|
|
|
101
147
|
async function updateOptions() {
|
|
@@ -131,17 +177,27 @@ async function updateOptions() {
|
|
|
131
177
|
}
|
|
132
178
|
|
|
133
179
|
function getSettingsContainer() {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
180
|
+
const container = $(`.${prefix}container`)
|
|
181
|
+
if (container) {
|
|
182
|
+
const theVersion = Number.parseInt(container.dataset.besVersion || "0", 10)
|
|
183
|
+
if (theVersion < besVersion) {
|
|
184
|
+
container.id = settingsContainerId
|
|
185
|
+
container.dataset.besVersion = String(besVersion)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return container
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return addElement(doc.body, "div", {
|
|
192
|
+
id: settingsContainerId,
|
|
193
|
+
class: `${prefix}container`,
|
|
194
|
+
"data-bes-version": besVersion,
|
|
195
|
+
})
|
|
140
196
|
}
|
|
141
197
|
|
|
142
198
|
function getSettingsWrapper() {
|
|
143
199
|
return (
|
|
144
|
-
$(
|
|
200
|
+
$(`.${prefix}container .${prefix}wrapper`) ||
|
|
145
201
|
addElement(getSettingsContainer(), "div", {
|
|
146
202
|
class: `${prefix}wrapper`,
|
|
147
203
|
})
|
|
@@ -149,6 +205,11 @@ function getSettingsWrapper() {
|
|
|
149
205
|
}
|
|
150
206
|
|
|
151
207
|
function initExtensionList() {
|
|
208
|
+
if (!doc.body) {
|
|
209
|
+
setTimeout(initExtensionList, 100)
|
|
210
|
+
return
|
|
211
|
+
}
|
|
212
|
+
|
|
152
213
|
const wrapper = getSettingsWrapper()
|
|
153
214
|
if (!$(".extension_list_container", wrapper)) {
|
|
154
215
|
const list = createExtensionList([])
|
|
@@ -180,7 +241,7 @@ function createSettingsElement() {
|
|
|
180
241
|
textContent: "Settings",
|
|
181
242
|
class: "navigation_go_previous",
|
|
182
243
|
onclick() {
|
|
183
|
-
|
|
244
|
+
activeExtensionList()
|
|
184
245
|
},
|
|
185
246
|
})
|
|
186
247
|
|
|
@@ -267,17 +328,34 @@ function createSettingsElement() {
|
|
|
267
328
|
return settingsMain
|
|
268
329
|
}
|
|
269
330
|
|
|
270
|
-
function addSideMenu(
|
|
271
|
-
|
|
331
|
+
function addSideMenu() {
|
|
332
|
+
if (!doc.body) {
|
|
333
|
+
setTimeout(addSideMenu, 100)
|
|
334
|
+
return
|
|
335
|
+
}
|
|
336
|
+
|
|
272
337
|
const menu =
|
|
273
338
|
$("#browser_extension_side_menu") ||
|
|
274
339
|
addElement(doc.body, "div", {
|
|
275
340
|
id: "browser_extension_side_menu",
|
|
276
|
-
"data-version":
|
|
341
|
+
"data-bes-version": besVersion,
|
|
277
342
|
})
|
|
343
|
+
|
|
344
|
+
const button = $("button[data-bes-version]", menu)
|
|
345
|
+
|
|
346
|
+
if (button) {
|
|
347
|
+
const theVersion = Number.parseInt(button.dataset.besVersion || "0", 10)
|
|
348
|
+
if (theVersion >= besVersion) {
|
|
349
|
+
return
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
button.remove()
|
|
353
|
+
}
|
|
354
|
+
|
|
278
355
|
addElement(menu, "button", {
|
|
279
356
|
type: "button",
|
|
280
|
-
|
|
357
|
+
"data-bes-version": besVersion,
|
|
358
|
+
title: "设置",
|
|
281
359
|
onclick() {
|
|
282
360
|
setTimeout(showSettings, 1)
|
|
283
361
|
},
|
|
@@ -291,7 +369,10 @@ export async function showSettings() {
|
|
|
291
369
|
await updateOptions()
|
|
292
370
|
settingsContainer.style.display = "block"
|
|
293
371
|
|
|
294
|
-
addEventListener(document, "click",
|
|
372
|
+
addEventListener(document, "click", onDocumentClick)
|
|
373
|
+
addEventListener(document, "keydown", onDocumentKeyDown)
|
|
374
|
+
activeExtension(settingsOptions.id)
|
|
375
|
+
deactiveExtensionList()
|
|
295
376
|
}
|
|
296
377
|
|
|
297
378
|
export const initSettings = async (options: SettingsOptions) => {
|
|
@@ -308,5 +389,5 @@ export const initSettings = async (options: SettingsOptions) => {
|
|
|
308
389
|
settings = await getSettings()
|
|
309
390
|
addStyle(getSettingsStyle())
|
|
310
391
|
initExtensionList()
|
|
311
|
-
addSideMenu(
|
|
392
|
+
addSideMenu()
|
|
312
393
|
}
|
package/lib/style.scss
CHANGED
|
@@ -78,6 +78,10 @@
|
|
|
78
78
|
background-color: #e4e4e6;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
&.active a {
|
|
82
|
+
cursor: default;
|
|
83
|
+
}
|
|
84
|
+
|
|
81
85
|
&:first-of-type {
|
|
82
86
|
border-top: none;
|
|
83
87
|
border-top-right-radius: 10px;
|
|
@@ -183,6 +187,7 @@
|
|
|
183
187
|
}
|
|
184
188
|
|
|
185
189
|
.option_groups textarea {
|
|
190
|
+
font-size: 12px;
|
|
186
191
|
margin: 10px 0 10px 0;
|
|
187
192
|
height: 100px;
|
|
188
193
|
width: 100%;
|
|
@@ -332,6 +337,7 @@
|
|
|
332
337
|
top: 80px;
|
|
333
338
|
right: 0;
|
|
334
339
|
padding-top: 20px;
|
|
340
|
+
z-index: 10000;
|
|
335
341
|
}
|
|
336
342
|
|
|
337
343
|
#browser_extension_side_menu:hover {
|
|
@@ -354,3 +360,25 @@
|
|
|
354
360
|
#browser_extension_side_menu button:active {
|
|
355
361
|
opacity: 100%;
|
|
356
362
|
}
|
|
363
|
+
|
|
364
|
+
@media (max-width: 500px) {
|
|
365
|
+
#browser_extension_settings_container {
|
|
366
|
+
right: 10px;
|
|
367
|
+
|
|
368
|
+
.extension_list_container {
|
|
369
|
+
display: none;
|
|
370
|
+
}
|
|
371
|
+
.extension_list_container.bes_active {
|
|
372
|
+
display: block;
|
|
373
|
+
}
|
|
374
|
+
.extension_list_container.bes_active + div {
|
|
375
|
+
display: none;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
#browser_extension_settings_main {
|
|
380
|
+
a.navigation_go_previous {
|
|
381
|
+
display: block;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|