Skip to content

Commit 0825b9e

Browse files
committed
增加支持自定义网站配置
1 parent e62d5df commit 0825b9e

File tree

8 files changed

+157
-15
lines changed

8 files changed

+157
-15
lines changed

README.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,36 @@ markdownDownload(websiteConfigs.juejin, {
5050
[博客园](https://www.cnblogs.com/)
5151
[微信文章](https://mp.weixin.qq.com/)
5252
[开源中国](https://www.oschina.net/)
53-
[CSDN](https://blog.csdn.net/)
53+
[CSDN](https://blog.csdn.net/)
54+
55+
## 自定义网站配置
56+
如果某网站没有被支持, 可以自定义网站配置.
57+
在控制台选中插件环境, 或者在插件的选项页/背景页, 将示例代码修改为对应网站配置, 并执行
58+
自定义的网站配置的优先级, 要比默认的网站配置更高
59+
``` js
60+
// 注意: 网站域名 和 文章内容选择器为必填项
61+
setWebsite(
62+
'juejin',
63+
{
64+
// * 网站域名, 默认配置支持正则, 这里暂不支持
65+
hosts: ['juejin.cn'],
66+
link: true,
67+
br: false,
68+
code: false,
69+
selectors: {
70+
// 标题选择器
71+
title: '.article-title',
72+
// * 文章内容选择器
73+
body: '.markdown-body',
74+
// 文章作者用户名选择器
75+
userName: '.username .name',
76+
// 文章作者链接选择器
77+
userLink: '.username',
78+
// 无效内容的选择器
79+
invalid: 'style',
80+
// 文章标签选择器
81+
tag: '.article-end .tag-list .tag-item'
82+
}
83+
}
84+
)
85+
```

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "markdown-downloader",
3-
"version": "2.0.1",
3+
"version": "2.0.2",
44
"description": "markdown文章下载",
55
"main": "dist/index.js",
66
"scripts": {

src/background.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { ajax, blob2array } from './request'
22
import { configs } from './websites'
3+
import { getLocal, setWebsite } from './utils'
4+
5+
globalThis.setWebsite = setWebsite
36

47
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
58
const { type } = message
@@ -40,9 +43,16 @@ const sendMessage = (message, onsuccess) => {
4043
})
4144
}
4245

43-
chrome.action.onClicked.addListener((tab) => {
46+
chrome.action.onClicked.addListener(async (tab) => {
4447
const { host } = new URL(tab.url)
45-
const matched = configs.some(({ website, hosts }) => {
48+
const localWebsites = await getLocal('websites')
49+
const localConfigs = localWebsites instanceof Object ? Object.keys(localWebsites).reduce((acc, curr) => {
50+
return localWebsites[curr] instanceof Object ? acc.concat({
51+
website: curr,
52+
hosts: localWebsites[curr].hosts
53+
}) : acc
54+
}, []) : []
55+
const matched = localConfigs.concat(configs).some(({ website, hosts }) => {
4656
if (
4757
website && Array.isArray(hosts) && hosts.some(item => item instanceof RegExp ? item.test(host) : item === host)
4858
) {

src/index.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
import { websites } from './websites'
1+
import { websites, hooks } from './websites'
22
import {
33
isExtension,
4-
sendMessage
4+
sendMessage,
5+
getLocal,
6+
setWebsite
57
} from './utils'
68
import downloadZip from './download'
79
import { downloadMarkdown } from './markdown'
810
import { getLocalOptions } from './options'
911

10-
const extract = async (options, customOptions, hook) => {
12+
const extract = async (options, customOptions = {}, hook = {}) => {
1113
const localOptions = await getLocalOptions()
1214
const data = await downloadMarkdown(options, Object.assign(customOptions, {
1315
localOptions
@@ -25,15 +27,29 @@ const extract = async (options, customOptions, hook) => {
2527

2628
if (isExtension) {
2729
chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
30+
const localWebsites = await getLocal('websites')
2831
if (message instanceof Object) {
2932
if (message.type === 'download') {
3033
if (typeof websites[message.website] === 'function') {
3134
await websites[message.website](extract)
35+
} else {
36+
const localWebsite = localWebsites[message.website]
37+
if (localWebsite instanceof Object) {
38+
await extract(
39+
localWebsite,
40+
localWebsite.customOptions instanceof Object ? localWebsite.customOptions : {},
41+
Object.assign({},
42+
hooks[message.website] instanceof Object ? hooks[message.website] : {},
43+
localWebsite.hooks instanceof Object ? localWebsite.hooks : {}
44+
)
45+
)
46+
}
3247
}
3348
}
3449
}
3550
sendResponse('')
3651
})
52+
window.setWebsite = setWebsite
3753
}
3854

3955
export default downloadMarkdown

src/option.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
<meta name="description" content="插件配置" />
88
<title>插件配置</title>
99
<script defer="defer" src="main.d77d57b4.js"></script>
10+
<script defer="defer" src="option.js"></script>
1011
<link href="main.092cdea9.css" rel="stylesheet">
1112
<link href="main.css" rel="stylesheet">
13+
1214
</head>
1315

1416
<body>

src/option.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
const getLocal = (key) =>
2+
new Promise((resolve) => {
3+
chrome.storage.local.get(key, (data) => {
4+
resolve(data[key])
5+
})
6+
})
7+
const setWebsite = async (website, options) => {
8+
const localWebsites = await getLocal('websites')
9+
const websites = Object.assign(
10+
{},
11+
localWebsites instanceof Object ? localWebsites : {}
12+
)
13+
const valid = website
14+
&&
15+
options instanceof Object
16+
&&
17+
Array.isArray(options.hosts)
18+
&&
19+
options.hosts.length
20+
&&
21+
(options.selectors || {}).body
22+
if (valid) {
23+
options.origin = website
24+
Object.assign(
25+
websites,
26+
{
27+
[website]: options
28+
}
29+
)
30+
chrome.storage.local.set({
31+
websites
32+
})
33+
} else if (options === null) {
34+
delete websites[website]
35+
chrome.storage.local.set({
36+
websites
37+
})
38+
}
39+
return websites
40+
}
41+
window.setWebsite = setWebsite

src/options.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { getLocal } from './utils'
2+
13
const defaultOptions = {
24
partLimit: 1e3,
35
requestLimit: 5,
@@ -6,12 +8,9 @@ const defaultOptions = {
68

79
export const options = Object.assign({}, defaultOptions)
810

9-
export const getLocalOptions = () => {
10-
return new Promise((resolve) => {
11-
chrome.storage.local.get('localOptions', ({ localOptions }) => {
12-
resolve(localOptions instanceof Object ? localOptions : {})
13-
})
14-
})
11+
export const getLocalOptions = async () => {
12+
const localOptions = await getLocal('localOptions')
13+
return localOptions instanceof Object ? localOptions : {}
1514
}
1615
export const mergeOptions = (newOptions) => {
1716
return Object.assign(options, defaultOptions, newOptions instanceof Object ? newOptions : {})

src/utils.js

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,47 @@ export const exec = async (...rest) => {
115115
}
116116
return exec.returnValue
117117
}
118-
118+
export const getLocal = (key) => {
119+
return new Promise((resolve) => {
120+
chrome.storage.local.get(key, (data) => {
121+
resolve(data[key])
122+
})
123+
})
124+
}
125+
export const setWebsite = async (website, options) => {
126+
const localWebsites = await getLocal('websites')
127+
const websites = Object.assign(
128+
{},
129+
localWebsites instanceof Object ? localWebsites : {}
130+
)
131+
const valid = website
132+
&&
133+
options instanceof Object
134+
&&
135+
Array.isArray(options.hosts)
136+
&&
137+
options.hosts.length
138+
&&
139+
(options.selectors || {}).body
140+
if (valid) {
141+
options.origin = website
142+
Object.assign(
143+
websites,
144+
{
145+
[website]: options
146+
}
147+
)
148+
chrome.storage.local.set({
149+
websites
150+
})
151+
} else if (options === null) {
152+
delete websites[website]
153+
chrome.storage.local.set({
154+
websites
155+
})
156+
}
157+
return websites
158+
}
119159
export default {
120160
isBrowser,
121161
isExtension,
@@ -132,5 +172,7 @@ export default {
132172
formatDate,
133173
insertAfter,
134174
getUrl,
135-
exec
175+
exec,
176+
getLocal,
177+
setWebsite
136178
}

0 commit comments

Comments
 (0)