diff --git a/chainWebpack.config.js b/chainWebpack.config.js index b74ebfa..00ddb55 100644 --- a/chainWebpack.config.js +++ b/chainWebpack.config.js @@ -62,6 +62,7 @@ const chainWebpack = (config) => { } config.entry('background').add(path.resolve(__dirname, './src/background/index.js')); config.entry('contentScripts').add(path.resolve(__dirname, './src/contentScripts/index.js')); + config.entry('offscreen/img2blob').add(path.resolve(__dirname, './src/offscreen/js/img2blob.js')); config.output.filename('[name].js'); config.plugin('copy').tap((_args) => { @@ -83,6 +84,7 @@ const chainWebpack = (config) => { }, { from: 'src/Dun-Cookies-Info.json', to: '[name][ext]' }, { from: 'node_modules/element-ui/lib/theme-chalk/fonts/', to: 'css/fonts/[name][ext]' }, + { from: 'src/offscreen/html', to: 'offscreen' }, ], }, ]; diff --git a/package-lock.json b/package-lock.json index 0e95f61..f997016 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,18 @@ { "name": "ceobe-canteen-browser-extension", - "version": "4.0.5", + "version": "5.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "ceobe-canteen-browser-extension", - "version": "4.0.5", + "version": "5.0.0", "dependencies": { "@enraged-dun-cookie-development-team/common": "^0.0.1-alpha.28", "@enraged-dun-cookie-development-team/cookie-fetcher-core": "^0.0.1-alpha.16", "animate.css": "^4.1.1", "core-js": "^3.25.1", - "crypto-js": "^4.1.1", + "crypto-js": "^4.2.0", "element-ui": "^2.15.9", "fastest-levenshtein": "^1.0.16", "html2canvas": "^1.4.1", @@ -42,7 +42,7 @@ "less": "^4.1.3", "less-loader": "^8.1.1", "lint-staged": "^13.0.3", - "postcss": "^8.4.16", + "postcss": "^8.4.31", "postcss-html": "^1.5.0", "postcss-less": "6.0.0", "prettier": "^2.7.1", @@ -8372,9 +8372,10 @@ } }, "node_modules/crypto-js": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", - "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", + "license": "MIT" }, "node_modules/css-functions-list": { "version": "3.1.0", @@ -12612,9 +12613,16 @@ "dev": true }, "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "version": "3.3.7", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -13238,13 +13246,28 @@ } }, "node_modules/postcss": { - "version": "8.4.27", - "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.27.tgz", - "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", + "version": "8.4.38", + "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", "dependencies": { - "nanoid": "^3.3.6", + "nanoid": "^3.3.7", "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" }, "engines": { "node": "^10 || ^12 || >=14" @@ -14530,9 +14553,10 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -22510,9 +22534,9 @@ } }, "crypto-js": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", - "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" }, "css-functions-list": { "version": "3.1.0", @@ -25635,9 +25659,9 @@ } }, "nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==" + "version": "3.3.7", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==" }, "natural-compare": { "version": "1.4.0", @@ -26116,13 +26140,13 @@ "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==" }, "postcss": { - "version": "8.4.27", - "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.27.tgz", - "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", + "version": "8.4.38", + "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "requires": { - "nanoid": "^3.3.6", + "nanoid": "^3.3.7", "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" } }, "postcss-html": { @@ -27061,9 +27085,9 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==" }, "source-map-support": { "version": "0.5.21", diff --git a/package.json b/package.json index 400832b..c51b152 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ceobe-canteen-browser-extension", - "version": "4.0.5", + "version": "5.0.0", "private": true, "scripts": { "serve": "vue-cli-service serve", @@ -15,7 +15,7 @@ "@enraged-dun-cookie-development-team/cookie-fetcher-core": "^0.0.1-alpha.16", "animate.css": "^4.1.1", "core-js": "^3.25.1", - "crypto-js": "^4.1.1", + "crypto-js": "^4.2.0", "element-ui": "^2.15.9", "fastest-levenshtein": "^1.0.16", "html2canvas": "^1.4.1", @@ -45,7 +45,7 @@ "less": "^4.1.3", "less-loader": "^8.1.1", "lint-staged": "^13.0.3", - "postcss": "^8.4.16", + "postcss": "^8.4.31", "postcss-html": "^1.5.0", "postcss-less": "6.0.0", "prettier": "^2.7.1", diff --git a/src/background/CookieHandler.js b/src/background/CookieHandler.js index de10104..66beb12 100644 --- a/src/background/CookieHandler.js +++ b/src/background/CookieHandler.js @@ -9,7 +9,6 @@ import { WeiboDataSource } from './fetcher/impl/local/WeiboDataSource'; import { NeteaseCloudMusicDataSource } from './fetcher/impl/local/NeteaseCloudMusicDataSource'; import { GameBulletinListDataSource } from './fetcher/impl/local/GameBulletinListDataSource'; import { MonsterSirenDataSource } from './fetcher/impl/local/MonsterSirenDataSource'; -import { ArknightsOfficialWebDataSource } from './fetcher/impl/local/ArknightsOfficialWebDataSource'; import { TerraHistoricusDataSource } from './fetcher/impl/local/TerraHistoricusDataSource'; import AvailableDataSourceMeta from '../common/sync/AvailableDataSourceMeta'; import { CookieItem } from '../common/CookieItem'; @@ -22,6 +21,16 @@ import { registerUrlToAddReferer } from './request_interceptor'; * @type {[string, string][]} */ const lastCookiesCache = []; +const lastCookiesCacheStorageKey = 'cache:lastCookies'; +PlatformHelper.Storage.getLocalStorage(lastCookiesCacheStorageKey).then((data) => { + if (typeof data === 'string' && data.length > 0) { + const cache = JSON.parse(data); + if (Array.isArray(cache) && cache.length > 0) { + lastCookiesCache.push(...cache); + } + } +}); + /** * 只缓存指定数量的饼用于检测重复 * @type {number} @@ -79,6 +88,7 @@ function tryNotice(source, newCookieList) { lastCookiesCache.shift(); } } + void PlatformHelper.Storage.saveLocalStorage(lastCookiesCacheStorageKey, JSON.stringify(lastCookiesCache)); } const LocalCardMap = {}; @@ -117,12 +127,10 @@ class CookieHandler { return GameBulletinListDataSource.processData(it.rawContent, sourceId); case 'arknights-website:monster-siren': return MonsterSirenDataSource.processData(it.rawContent, sourceId); - case 'arknights-website:official-website': - return ArknightsOfficialWebDataSource.processData(it.rawContent, sourceId); case 'arknights-website:terra-historicus': return TerraHistoricusDataSource.processData(it.rawContent, sourceId); default: - console.warn('未知数据源类型:' + it.dataSourceId.typeId); + console.warn('不支持的数据源类型:' + it.dataSourceId.typeId); } } }) diff --git a/src/background/countdown.js b/src/background/countdown.js new file mode 100644 index 0000000..162f670 --- /dev/null +++ b/src/background/countdown.js @@ -0,0 +1,97 @@ +import DebugUtil from '../common/util/DebugUtil'; +import CountDown from '../common/sync/CountDownInfo'; +import PlatformHelper from '../common/platform/PlatformHelper'; +import NotificationUtil from '../common/util/NotificationUtil'; +import TimeUtil from '../common/util/TimeUtil'; + +function countDownDebugLog(...data) { + DebugUtil.debugConsoleOutput(0, 'debug', '%c 倒计时 ', 'color: white; background: #DA70D6', ...data); +} + +const countDownThreshold = 5 * 60 * 1000; +let countDownFlag = false; +const countDown = { + sendNoticeList: [], + countDownList: [], + Start() { + CountDown.getCountDownLocalStorage().then((data) => { + data = JSON.parse(data); + if (data) { + this.countDownList = []; + data + .map((x) => x.data) + .forEach((item) => { + this.countDownList.push(item); + const endTime = new Date(item.stopTime).getTime(); + const delayTime = endTime - new Date().getTime(); + if (delayTime >= countDownThreshold) { + countDownDebugLog(`设置alarm[${item.name}]-指定时间:${new Date(endTime).toLocaleString()}`); + const uniqueName = 'countdown_' + item.name + '|' + Math.random().toFixed(3).substring(2, 5); + PlatformHelper.Alarms.create(uniqueName, { when: endTime }); + } else { + countDownDebugLog(`设置setTimeout[${item.name}]-延时:${delayTime}`); + this.sendNoticeList.push( + setTimeout((_) => { + NotificationUtil.SendNotice( + `倒计时完毕`, + `${item.name} 到点了!`, + null, + 'countdown_' + new Date().getTime() + ); + // 有过通知后从内存中删除计时器数据 + CountDown.removeCountDown(item); + }, delayTime) + ); + } + }); + } + }); + }, + Change() { + if (countDownFlag) { + return; + } + countDownFlag = true; + countDownDebugLog('清空setTimeout'); + this.sendNoticeList.forEach((id) => { + clearTimeout(id); + }); + this.sendNoticeList = []; + countDownDebugLog('清空alarms'); + // TODO 简单粗暴全清了显然不行 + // PlatformHelper.Alarms.clearAll().finally(() => { + // this.Start(); + // countDownFlag = false; + // }); + }, + GetAllCountDown() { + let list = []; + this.countDownList.forEach((item) => { + let value = TimeUtil.calcDiff(new Date(item.stopTime), new Date()); + if (value != '') { + list.push({ ...item, timeStr: value, stopTime: TimeUtil.format(item.stopTime, 'yyyy-MM-dd hh:mm:ss') }); + } + }); + return list; + }, +}; + +function countdownAlarmHandler(alarm) { + if (!alarm || !alarm.name) return; + if (alarm.name.startsWith('countdown_')) { + const countDownName = name.split('|')[0].substring('countdown_'.length); + NotificationUtil.SendNotice(`倒计时完毕`, `${countDownName} 到点了!`, null, 'countdown_' + new Date().getTime()); + void CountDown.removeCountDownByName(countDownName); + } +} + +// TODO 暂时没有启用倒计时 +export function CountDownInit() { + countDown.Start(); + PlatformHelper.osIsMac().then((isMac) => { + if (isMac) { + setInterval(() => countDown.Change(), 10 * 60 * 1000); + } + }); + PlatformHelper.Alarms.addListener(countdownAlarmHandler); +} diff --git a/src/background/fetcher.js b/src/background/fetcher.js new file mode 100644 index 0000000..01b9f1a --- /dev/null +++ b/src/background/fetcher.js @@ -0,0 +1,89 @@ +import { CookieFetchManager, registerFetcher } from './fetcher/CookieFetcherManager'; +import { CeobeCanteenCookieFetcher } from './fetcher/impl/CeobeCanteenCookieFetcher'; +import { FallbackLocalCookieFetcher } from './fetcher/impl/FallbackLocalCookieFetcher'; +import { CustomLocalCookieFetcher } from './fetcher/impl/CustomLocalCookieFetcher'; +import { FetchConfig, FetcherStrategy } from './fetcher/FetchConfig'; +import Settings from '../common/Settings'; + +const cookieFetcherManager = new CookieFetchManager(); + +registerFetcher('server', CeobeCanteenCookieFetcher); +/* IFTRUE_feature__local_fetch */ +registerFetcher('local-fallback', FallbackLocalCookieFetcher); +/* FITRUE_feature__local_fetch */ +/* IFTRUE_feature__custom_datasource */ +registerFetcher('local-custom', CustomLocalCookieFetcher); +/* FITRUE_feature__custom_datasource */ + +/** + * TODO 之后这个要改成能够自定义的 + * + * @return {FetchConfig} + */ +function buildMainCookieFetchConfig(enable = true) { + return new FetchConfig( + MAIN_FETCH_CONFIG_KEY, + enable, + Settings.enableDataSources, + Settings.dun.intervalTime, + Settings.dun.autoLowFrequency + ? Settings.dun.lowFrequencyTime.map((it) => { + let realHour; + if (it < 12) realHour = it + 12; + else realHour = it - 12; + return realHour; + }) + : undefined, + Settings.dun.autoLowFrequency ? Settings.dun.timeOfLowFrequency : 1, + [ + new FetcherStrategy('default', 'server'), + /* IFTRUE_feature__local_fetch */ + new FetcherStrategy('default', 'local-fallback'), + /* FITRUE_feature__local_fetch */ + ] + ); +} + +/* IFTRUE_feature__custom_datasource */ +/** + * @return {FetchConfig} + */ +function buildCustomCookieFetchConfig(enable = true) { + return new FetchConfig( + CUSTOM_FETCH_CONFIG_KEY, + enable, + Settings.extraFeature.enableCustomDataSources, + Settings.dun.intervalTime, + Settings.dun.autoLowFrequency + ? Settings.dun.lowFrequencyTime.map((it) => { + let realHour; + if (it < 12) realHour = it + 12; + else realHour = it - 12; + return realHour; + }) + : undefined, + Settings.dun.autoLowFrequency ? Settings.dun.timeOfLowFrequency : 1, + [new FetcherStrategy('default', 'local-custom')] + ); +} +/* FITRUE_feature__custom_datasource */ + +const MAIN_FETCH_CONFIG_KEY = 'main'; +const CUSTOM_FETCH_CONFIG_KEY = 'custom'; + +export function updateFetch() { + // 主配置在配置页面保证了不可能为空,自定义配置可能为空 + cookieFetcherManager.updateFetchConfig(MAIN_FETCH_CONFIG_KEY, buildMainCookieFetchConfig(true)); + /* IFTRUE_feature__custom_datasource */ + if (Settings.extraFeature.enableCustomDataSources?.length > 0) { + cookieFetcherManager.updateFetchConfig(CUSTOM_FETCH_CONFIG_KEY, buildCustomCookieFetchConfig(true)); + } else { + cookieFetcherManager.removeFetchConfig(CUSTOM_FETCH_CONFIG_KEY); + } + /* FITRUE_feature__custom_datasource */ +} + +export function stopFetch() { + cookieFetcherManager.removeFetchConfig(MAIN_FETCH_CONFIG_KEY); + cookieFetcherManager.removeFetchConfig(CUSTOM_FETCH_CONFIG_KEY); +} diff --git a/src/background/fetcher/impl/CeobeCanteenCookieFetcher.js b/src/background/fetcher/impl/CeobeCanteenCookieFetcher.js index 3389177..7f2bd5a 100644 --- a/src/background/fetcher/impl/CeobeCanteenCookieFetcher.js +++ b/src/background/fetcher/impl/CeobeCanteenCookieFetcher.js @@ -2,6 +2,7 @@ import { AbstractCookieFetcher } from '../AbstractCookieFetcher'; import ServerUtil from '../../../common/util/ServerUtil'; import { CookieHandler } from '../../CookieHandler'; import DebugUtil from '../../../common/util/DebugUtil'; +import PlatformHelper from '../../../common/platform/PlatformHelper'; export class CeobeCanteenCookieFetcher extends AbstractCookieFetcher { /** diff --git a/src/background/fetcher/impl/CustomLocalCookieFetcher.js b/src/background/fetcher/impl/CustomLocalCookieFetcher.js index 94123cc..22b9e03 100644 --- a/src/background/fetcher/impl/CustomLocalCookieFetcher.js +++ b/src/background/fetcher/impl/CustomLocalCookieFetcher.js @@ -12,33 +12,6 @@ registerDefaultDataSourceTypes(); const pad = (num) => (num > 9 ? `${num}` : `0${num}`); -/** - * - * @param fetchConfig {FetchConfig} - * @return {FetchControllerConfig} - */ -function _buildConfig(fetchConfig) { - const config = { - default_interval: fetchConfig.globalInterval * 1000, - groups: [], - }; - const customGroups = {}; - const commonGroupConfig = {}; - if (fetchConfig.lowFrequencyTimeRange && fetchConfig.lowFrequencyMultiple > 1) { - this.updateGroupIntervalByTimeRange(config.default_interval, fetchConfig, commonGroupConfig); - } - for (const { type, dataId } of fetchConfig.enableDataSourceList) { - if (!customGroups[type]) customGroups[type] = { type: type, datasource: [], ...commonGroupConfig }; - const source = {}; - if (this.dataIdKeyInConfig[type]) { - source[this.dataIdKeyInConfig[type]] = dataId; - } - customGroups[type].datasource.push(source); - } - config.groups.push(...Object.values(customGroups).filter((group) => group.datasource.length > 0)); - return config; -} - export class CustomLocalCookieFetcher extends AbstractCookieFetcher { dataIdKeyInConfig = { 'bilibili:dynamic-by-uid': 'uid', @@ -119,7 +92,7 @@ export class CustomLocalCookieFetcher extends AbstractCookieFetcher { async start(fetchConfig) { if (this.runningFlag) return; - const config = _buildConfig(fetchConfig); + const config = this._buildConfig(fetchConfig); this.startWithFetcherControllerConfig(config, fetchConfig); } @@ -131,7 +104,7 @@ export class CustomLocalCookieFetcher extends AbstractCookieFetcher { async _checkAvailable(fetchConfig) { if (fetchConfig) { - const config = _buildConfig(fetchConfig); + const config = this._buildConfig(fetchConfig); try { FetchController.validateConfig(config); } catch (e) { @@ -143,4 +116,31 @@ export class CustomLocalCookieFetcher extends AbstractCookieFetcher { await fetch('https://www.baidu.com/', { mode: 'no-cors' }); return true; } + + /** + * + * @param fetchConfig {FetchConfig} + * @return {FetchControllerConfig} + */ + _buildConfig(fetchConfig) { + const config = { + default_interval: fetchConfig.globalInterval * 1000, + groups: [], + }; + const customGroups = {}; + const commonGroupConfig = {}; + if (fetchConfig.lowFrequencyTimeRange && fetchConfig.lowFrequencyMultiple > 1) { + this.updateGroupIntervalByTimeRange(config.default_interval, fetchConfig, commonGroupConfig); + } + for (const { type, dataId } of fetchConfig.enableDataSourceList) { + if (!customGroups[type]) customGroups[type] = { type: type, datasource: [], ...commonGroupConfig }; + const source = {}; + if (this.dataIdKeyInConfig[type]) { + source[this.dataIdKeyInConfig[type]] = dataId; + } + customGroups[type].datasource.push(source); + } + config.groups.push(...Object.values(customGroups).filter((group) => group.datasource.length > 0)); + return config; + } } diff --git a/src/background/fetcher/impl/local/ArknightsOfficialWebDataSource.js b/src/background/fetcher/impl/local/ArknightsOfficialWebDataSource.js deleted file mode 100644 index 00cf89f..0000000 --- a/src/background/fetcher/impl/local/ArknightsOfficialWebDataSource.js +++ /dev/null @@ -1,27 +0,0 @@ -import Settings from '../../../../common/Settings'; -import TimeUtil from '../../../../common/util/TimeUtil'; -import { CookieItem } from '../../../../common/CookieItem'; -import PlatformHelper from '../../../../common/platform/PlatformHelper'; - -/** - * 明日方舟官网数据源。 - *
- */
-export class ArknightsOfficialWebDataSource {
- static async processData(rawDataText, sourceId) {
- let $ = PlatformHelper.HtmlParser;
- const $item = $(rawDataText);
- let date = $('.articleItemDate', $item).text();
- let title = $('.articleItemTitle', $item).text();
- let url = $('.articleItemLink', $item).attr('href');
- let time = new Date(`${date} ${Settings.getTimeBySortMode()}`);
- let judgment = url.match(/\d+/g);
- return CookieItem.builder(sourceId)
- .id(parseInt(judgment[0]))
- .timeForSort(time.getTime())
- .timeForDisplay(TimeUtil.format(time, 'yyyy-MM-dd'))
- .content(title)
- .jumpUrl(`https://ak.hypergryph.com${url}`)
- .build();
- }
-}
diff --git a/src/background/fetcher/impl/local/GameBulletinListDataSource.js b/src/background/fetcher/impl/local/GameBulletinListDataSource.js
index ae0a1d6..529b65e 100644
--- a/src/background/fetcher/impl/local/GameBulletinListDataSource.js
+++ b/src/background/fetcher/impl/local/GameBulletinListDataSource.js
@@ -1,8 +1,6 @@
-import { DataSourceMeta, DataSourceTypeInfo } from '../../../../common/datasource/DataSourceMeta';
import Settings from '../../../../common/Settings';
import TimeUtil from '../../../../common/util/TimeUtil';
import { CookieItem } from '../../../../common/CookieItem';
-import PlatformHelper from '../../../../common/platform/PlatformHelper';
/**
* 游戏公告数据源。
@@ -17,7 +15,7 @@ export class GameBulletinListDataSource {
.timeForSort(time.getTime())
.timeForDisplay(TimeUtil.format(time, 'yyyy-MM-dd'))
.content(data.title.replace('\\n', '\n'))
- .jumpUrl(`https://terra-historicus.hypergryph.com/comic/${data.comicCid}/episode/${data.episodeCid}`)
+ .jumpUrl(`https://ak-webview.hypergryph.com/api/game/bulletin/${data.cid}`)
.build();
}
}
diff --git a/src/background/heartbeat.js b/src/background/heartbeat.js
new file mode 100644
index 0000000..e453403
--- /dev/null
+++ b/src/background/heartbeat.js
@@ -0,0 +1,39 @@
+// 复制自:https://developer.chrome.com/docs/extensions/develop/migrate/to-service-workers?hl=zh-cn#keep-sw-alive
+// TODO 该文件暂未用到,Chrome官方不喜欢这样的,之后看看正常蹲饼能不能一直活,能的话就不要这个了,不能的话就还是用这个保活
+/**
+ * Tracks when a service worker was last alive and extends the service worker
+ * lifetime by writing the current time to extension storage every 20 seconds.
+ * You should still prepare for unexpected termination - for example, if the
+ * extension process crashes or your extension is manually stopped at
+ * chrome://serviceworker-internals.
+ */
+let heartbeatInterval;
+
+async function runHeartbeat() {
+ await PlatformHelper.Storage.saveLocalStorage('last-heartbeat', new Date().getTime());
+}
+
+/**
+ * Starts the heartbeat interval which keeps the service worker alive. Call
+ * this sparingly when you are doing work which requires persistence, and call
+ * stopHeartbeat once that work is complete.
+ */
+export async function startHeartbeat() {
+ // Run the heartbeat once at service worker startup.
+ runHeartbeat().then(() => {
+ // Then again every 20 seconds.
+ heartbeatInterval = setInterval(runHeartbeat, 20 * 1000);
+ });
+}
+
+export async function stopHeartbeat() {
+ clearInterval(heartbeatInterval);
+}
+
+/**
+ * Returns the last heartbeat stored in extension storage, or undefined if
+ * the heartbeat has never run before.
+ */
+export async function getLastHeartbeat() {
+ return await PlatformHelper.Storage.getLocalStorage('last-heartbeat');
+}
diff --git a/src/background/index.js b/src/background/index.js
index 63b06fa..a5eb366 100644
--- a/src/background/index.js
+++ b/src/background/index.js
@@ -1,9 +1,6 @@
-import Settings from '../common/Settings';
-import NotificationUtil from '../common/util/NotificationUtil';
-import SanInfo from '../common/sync/SanInfo';
+import DebugUtil from '../common/util/DebugUtil';
import {
ENABLE_FEATURES,
- MESSAGE_CHANGE_COUNTDOWN,
MESSAGE_GET_COUNTDOWN,
MESSAGE_SAN_GET,
MESSAGE_WEIBO_ADD_REFERER,
@@ -12,110 +9,157 @@ import {
PAGE_WELCOME,
PLATFORM_FIREFOX,
} from '../common/Constants';
+import Settings from '../common/Settings';
import PlatformHelper from '../common/platform/PlatformHelper';
import ServerUtil from '../common/util/ServerUtil';
-import CountDown from '../common/sync/CountDownInfo';
-import TimeUtil from '../common/util/TimeUtil';
-import PenguinStatistics from '../common/sync/PenguinStatisticsInfo';
+import { stopFetch, updateFetch } from './fetcher';
+import SanInfo from '../common/sync/SanInfo';
+import { registerUrlToAddReferer } from './request_interceptor';
import CardList from '../common/sync/CardList';
-import { CookieFetchManager, registerFetcher } from './fetcher/CookieFetcherManager';
-import { FetchConfig, FetcherStrategy } from './fetcher/FetchConfig';
-import { CeobeCanteenCookieFetcher } from './fetcher/impl/CeobeCanteenCookieFetcher';
-import { CustomLocalCookieFetcher } from './fetcher/impl/CustomLocalCookieFetcher';
-import DebugUtil from '../common/util/DebugUtil';
-import { interceptBeforeSendHeaders, registerUrlToAddReferer } from './request_interceptor';
-import { FallbackLocalCookieFetcher } from './fetcher/impl/FallbackLocalCookieFetcher';
+import NotificationUtil from '../common/util/NotificationUtil';
+import CountDown from '../common/sync/CountDownInfo';
import { UserUtil } from '../common/util/UserUtil';
+import PenguinStatistics from '../common/sync/PenguinStatisticsInfo';
+import { JsonValidator } from '@enraged-dun-cookie-development-team/common/json';
// 第一时间调用以生成uuid
void UserUtil.getClientId();
-
-// 开启弹出菜单窗口化时的窗口ID
-let popupWindowId = null;
-
-const cookieFetcherManager = new CookieFetchManager();
-
-registerFetcher('server', CeobeCanteenCookieFetcher);
-/* IFTRUE_feature__local_fetch */
-registerFetcher('local-fallback', FallbackLocalCookieFetcher);
-/* FITRUE_feature__local_fetch */
-/* IFTRUE_feature__custom_datasource */
-registerFetcher('local-custom', CustomLocalCookieFetcher);
-/* FITRUE_feature__custom_datasource */
-
-/**
- * TODO 之后这个要改成能够自定义的
- *
- * @return {FetchConfig}
- */
-function buildMainCookieFetchConfig(enable = true) {
- return new FetchConfig(
- MAIN_FETCH_CONFIG_KEY,
- enable,
- Settings.enableDataSources,
- Settings.dun.intervalTime,
- Settings.dun.autoLowFrequency
- ? Settings.dun.lowFrequencyTime.map((it) => {
- let realHour;
- if (it < 12) realHour = it + 12;
- else realHour = it - 12;
- return realHour;
- })
- : undefined,
- Settings.dun.autoLowFrequency ? Settings.dun.timeOfLowFrequency : 1,
- [
- new FetcherStrategy('default', 'server'),
- /* IFTRUE_feature__local_fetch */
- new FetcherStrategy('default', 'local-fallback'),
- /* FITRUE_feature__local_fetch */
- ]
- );
+// TODO 因为ajv用到了eval,所以只能全局禁止验证
+JsonValidator.validate = () => true;
+
+const alarmKeyCheckUpdate = 'core:check-extension-update';
+const alarmKeyCheckServerInfoCache = 'core:check-serverinfo-cache';
+const alarmKeyAliveCheck = 'core:alive-check';
+
+// 记录启动时间
+const startTime = new Date().getTime();
+
+function alarmHandler(alarm) {
+ if (!alarm || !alarm.name) return;
+ switch (alarm.name) {
+ case alarmKeyCheckUpdate: {
+ void checkExtensionUpdate();
+ break;
+ }
+ case alarmKeyCheckServerInfoCache: {
+ void ServerUtil.checkServerDataSourceInfoCache();
+ break;
+ }
+ case alarmKeyAliveCheck: {
+ // 3秒内视为这次闹钟触发的时候已经死了
+ if (Math.abs(new Date().getTime() - startTime) < 3000) {
+ DebugUtil.debugLog(0, '恢复蹲饼');
+ updateFetch();
+ }
+ break;
+ }
+ default: {
+ if (alarm.name.startsWith('countdown_')) {
+ const countDownName = name.split('|')[0].substring('countdown_'.length);
+ NotificationUtil.SendNotice(
+ `倒计时完毕`,
+ `${countDownName} 到点了!`,
+ null,
+ 'countdown_' + new Date().getTime()
+ );
+ void CountDown.removeCountDownByName(countDownName);
+ }
+ break;
+ }
+ }
}
-/* IFTRUE_feature__custom_datasource */
-/**
- * @return {FetchConfig}
- */
-function buildCustomCookieFetchConfig(enable = true) {
- return new FetchConfig(
- CUSTOM_FETCH_CONFIG_KEY,
- enable,
- Settings.extraFeature.enableCustomDataSources,
- Settings.dun.intervalTime,
- Settings.dun.autoLowFrequency
- ? Settings.dun.lowFrequencyTime.map((it) => {
- let realHour;
- if (it < 12) realHour = it + 12;
- else realHour = it - 12;
- return realHour;
- })
- : undefined,
- Settings.dun.autoLowFrequency ? Settings.dun.timeOfLowFrequency : 1,
- [new FetcherStrategy('default', 'local-custom')]
- );
+async function checkExtensionUpdate() {
+ const extensionInfo = await PlatformHelper.Extension.getExtensionInfo();
+ // 商店安装的不检查更新
+ if (extensionInfo.installType !== 'normal') {
+ void ServerUtil.getVersionInfo();
+ }
+ void ServerUtil.getAnnouncementInfo(true);
}
-/* FITRUE_feature__custom_datasource */
-const MAIN_FETCH_CONFIG_KEY = 'main';
-const CUSTOM_FETCH_CONFIG_KEY = 'custom';
+PlatformHelper.Alarms.addListener(alarmHandler);
+
+// 监听前台事件
+PlatformHelper.Message.registerListener('background', null, (message) => {
+ if (message.type) {
+ const data = message.data;
+ switch (message.type) {
+ case MESSAGE_SAN_GET:
+ return SanInfo;
+ // TODO 暂未启用Countdown
+ // case MESSAGE_CHANGE_COUNTDOWN:
+ // countDown.Change();
+ // return;
+ case MESSAGE_GET_COUNTDOWN:
+ return [];
+ // return countDown.GetAllCountDown();
+ case MESSAGE_WEIBO_ADD_REFERER:
+ if (data.urls && data.urls.length > 0) {
+ data.urls.forEach((src) => registerUrlToAddReferer(src, 'https://m.weibo.cn/'));
+ }
+ return;
+ default:
+ return;
+ }
+ }
+});
-function updateFetch() {
- // 主配置在配置页面保证了不可能为空,自定义配置可能为空
- cookieFetcherManager.updateFetchConfig(MAIN_FETCH_CONFIG_KEY, buildMainCookieFetchConfig(true));
- /* IFTRUE_feature__custom_datasource */
- if (Settings.extraFeature.enableCustomDataSources?.length > 0) {
- cookieFetcherManager.updateFetchConfig(CUSTOM_FETCH_CONFIG_KEY, buildCustomCookieFetchConfig(true));
+// 监听标签
+PlatformHelper.Notification.addClickListener((id) => {
+ let item = CardList.getFirstPageList().find((x) => x.id === id);
+ if (item) {
+ void PlatformHelper.Tabs.create(item.jumpUrl);
+ } else if (id === 'update') {
+ void PlatformHelper.Tabs.createWithExtensionFile(PAGE_UPDATE);
+ } else if (id.slice(0, 12) === 'announcement') {
+ alert('博士,你点下去的是条重要公告噢,打开列表就可以看到啦');
} else {
- cookieFetcherManager.removeFetchConfig(CUSTOM_FETCH_CONFIG_KEY);
+ alert('o(╥﹏╥)o 时间过于久远...最近列表内没有找到该网站');
}
- /* FITRUE_feature__custom_datasource */
-}
+});
+
+// 监听安装更新
+PlatformHelper.Lifecycle.addInstalledListener((details) => {
+ Settings.doAfterInit(() => {
+ if (details.reason === 'install' || !Settings.agreeLicense) {
+ void PlatformHelper.Tabs.createWithExtensionFile(PAGE_WELCOME);
+ }
+ if (details.reason === 'update' || details.reason === 'install') {
+ void PlatformHelper.Storage.saveLocalStorage('version-notice', false);
+ }
+ });
+});
+
+// 监听扩展图标被点击,用于打开窗口化的弹出页面
+PlatformHelper.BrowserAction.addIconClickListener(async () => {
+ const popupWindowIdStorageKey = 'runtime.popupWindowId';
+ if (Settings.display.windowMode) {
+ const popupWindowId = await PlatformHelper.Storage.getLocalStorage(popupWindowIdStorageKey);
+ if (popupWindowId) {
+ PlatformHelper.Windows.getAllWindow().then((allWindow) => {
+ if (allWindow.findIndex((x) => x.id == popupWindowId) > 0) {
+ PlatformHelper.Windows.remove(popupWindowId);
+ }
+ });
+ }
+ const width = 800;
+ let height = 950;
+ if (PlatformHelper.PlatformType === PLATFORM_FIREFOX) {
+ height = 850;
+ }
+ PlatformHelper.Windows.createPopupWindow(PlatformHelper.Extension.getURL(PAGE_POPUP_WINDOW), width, height).then(
+ (tab) => PlatformHelper.Storage.saveLocalStorage(popupWindowIdStorageKey, tab.id)
+ );
+ }
+});
function ExtensionInit() {
DebugUtil.debugLog(0, '插件启动...');
if (ENABLE_FEATURES.length > 0) {
DebugUtil.debugLog(0, '已启用特性:', ENABLE_FEATURES);
}
+
// 开始蹲饼!
Settings.doAfterInit((initSettings) => {
if (initSettings.open) {
@@ -124,14 +168,13 @@ function ExtensionInit() {
} else {
DebugUtil.debugLog(0, '蹲饼开关已关闭');
}
- setTimeout(async () => {
- const extensionInfo = await PlatformHelper.Extension.getExtensionInfo();
- // 商店安装的不检查更新
- if (extensionInfo.installType !== 'normal') {
- void ServerUtil.getVersionInfo();
- }
- void ServerUtil.getAnnouncementInfo(true);
- }, 600000);
+ });
+
+ Settings.doAfterInit((initSettings) => {
+ void PlatformHelper.Alarms.createIfNotExists(alarmKeyCheckUpdate, {
+ delayInMinutes: 60,
+ periodInMinutes: 60,
+ });
});
Settings.doAfterUpdate((settings, changed) => {
@@ -151,188 +194,27 @@ function ExtensionInit() {
DebugUtil.debugLog(0, '开始蹲饼');
updateFetch();
} else {
- cookieFetcherManager.removeFetchConfig(MAIN_FETCH_CONFIG_KEY);
- cookieFetcherManager.removeFetchConfig(CUSTOM_FETCH_CONFIG_KEY);
+ stopFetch();
+ // 都不蹲饼了还保什么活(
+ void PlatformHelper.Alarms.clear(alarmKeyAliveCheck);
}
});
// 启动时的缓存检查在AvailableDataSourceMeta
// 每隔6小时检查一遍缓存
- setInterval(() => {
- void ServerUtil.checkServerDataSourceInfoCache();
- }, 6 * 60 * 60 * 1000);
-
- // 监听前台事件
- PlatformHelper.Message.registerListener('background', null, (message) => {
- if (message.type) {
- const data = message.data;
- switch (message.type) {
- case MESSAGE_SAN_GET:
- return SanInfo;
- case MESSAGE_CHANGE_COUNTDOWN:
- countDown.Change();
- return;
- case MESSAGE_GET_COUNTDOWN:
- return countDown.GetAllCountDown();
- case MESSAGE_WEIBO_ADD_REFERER:
- if (data.urls && data.urls.length > 0) {
- data.urls.forEach((src) => registerUrlToAddReferer(src, 'https://m.weibo.cn/'));
- }
- return;
- default:
- return;
- }
- }
- });
-
- // 监听标签
- PlatformHelper.Notification.addClickListener((id) => {
- let item = CardList.getFirstPageList().find((x) => x.id === id);
- if (item) {
- PlatformHelper.Tabs.create(item.jumpUrl);
- } else if (id === 'update') {
- PlatformHelper.Tabs.createWithExtensionFile(PAGE_UPDATE);
- } else if (id.slice(0, 12) === 'announcement') {
- alert('博士,你点下去的是条重要公告噢,打开列表就可以看到啦');
- } else {
- alert('o(╥﹏╥)o 时间过于久远...最近列表内没有找到该网站');
- }
- });
-
- // 监听安装更新
- PlatformHelper.Lifecycle.addInstalledListener((details) => {
- Settings.doAfterInit(() => {
- if (details.reason === 'install' || !Settings.agreeLicense) {
- PlatformHelper.Tabs.createWithExtensionFile(PAGE_WELCOME);
- }
- if (details.reason === 'update' || details.reason === 'install') {
- PlatformHelper.Storage.saveLocalStorage('version-notice', false);
- }
- });
+ void PlatformHelper.Alarms.createIfNotExists(alarmKeyCheckServerInfoCache, {
+ delayInMinutes: 6 * 60,
+ periodInMinutes: 6 * 60,
});
- // 监听扩展图标被点击,用于打开窗口化的弹出页面
- PlatformHelper.BrowserAction.addIconClickListener(() => {
- if (Settings.display.windowMode) {
- if (popupWindowId != null) {
- PlatformHelper.Windows.getAllWindow().then((allWindow) => {
- if (allWindow.findIndex((x) => x.id == popupWindowId) > 0) {
- PlatformHelper.Windows.remove(popupWindowId);
- }
- });
- }
- const width = 800;
- let height = 950;
- if (PlatformHelper.PlatformType === PLATFORM_FIREFOX) {
- height = 850;
- }
- PlatformHelper.Windows.createPopupWindow(PlatformHelper.Extension.getURL(PAGE_POPUP_WINDOW), width, height).then(
- (tab) => (popupWindowId = tab.id)
- );
- }
- });
-
- PlatformHelper.Alarms.addListener((alarm) => {
- /**
- * @type {string|undefined}
- */
- const name = alarm.name;
- countDownDebugLog(`alarm监听器触发[${name}]:`, alarm);
- if (name && name.startsWith('countdown_')) {
- const countDownName = name.split('|')[0].substring('countdown_'.length);
- NotificationUtil.SendNotice(`倒计时完毕`, `${countDownName} 到点了!`, null, 'countdown_' + new Date().getTime());
- CountDown.removeCountDownByName(countDownName);
- }
- });
-
- PlatformHelper.Http.onBeforeSendHeaders(interceptBeforeSendHeaders, { urls: ['*://*.sinaimg.cn/*'] }, [
- 'blocking',
- 'requestHeaders',
- ]);
+ // 拿一次企鹅物流数据
+ PenguinStatistics.GetNewItems();
}
-function countDownDebugLog(...data) {
- DebugUtil.debugConsoleOutput(0, 'debug', '%c 倒计时 ', 'color: white; background: #DA70D6', ...data);
-}
-
-const countDownThreshold = 5 * 60 * 1000;
-let countDownFlag = false;
-const countDown = {
- sendNoticeList: [],
- countDownList: [],
- Start() {
- CountDown.getCountDownLocalStorage().then((data) => {
- data = JSON.parse(data);
- if (data) {
- this.countDownList = [];
- data
- .map((x) => x.data)
- .forEach((item) => {
- this.countDownList.push(item);
- const endTime = new Date(item.stopTime).getTime();
- const delayTime = endTime - new Date().getTime();
- if (delayTime >= countDownThreshold) {
- countDownDebugLog(`设置alarm[${item.name}]-指定时间:${new Date(endTime).toLocaleString()}`);
- const uniqueName = 'countdown_' + item.name + '|' + Math.random().toFixed(3).substring(2, 5);
- PlatformHelper.Alarms.create(uniqueName, { when: endTime });
- } else {
- countDownDebugLog(`设置setTimeout[${item.name}]-延时:${delayTime}`);
- this.sendNoticeList.push(
- setTimeout((_) => {
- NotificationUtil.SendNotice(
- `倒计时完毕`,
- `${item.name} 到点了!`,
- null,
- 'countdown_' + new Date().getTime()
- );
- // 有过通知后从内存中删除计时器数据
- CountDown.removeCountDown(item);
- }, delayTime)
- );
- }
- });
- }
- });
- },
- Change() {
- if (countDownFlag) {
- return;
- }
- countDownFlag = true;
- countDownDebugLog('清空setTimeout');
- this.sendNoticeList.forEach((id) => {
- clearTimeout(id);
- });
- this.sendNoticeList = [];
- countDownDebugLog('清空alarms');
- PlatformHelper.Alarms.clearAll().finally(() => {
- this.Start();
- countDownFlag = false;
- });
- },
- GetAllCountDown() {
- let list = [];
- this.countDownList.forEach((item) => {
- let value = TimeUtil.calcDiff(new Date(item.stopTime), new Date());
- if (value != '') {
- list.push({ ...item, timeStr: value, stopTime: TimeUtil.format(item.stopTime, 'yyyy-MM-dd hh:mm:ss') });
- }
- });
- return list;
- },
-};
-
-const penguinStatistics = {
- Init() {
- PenguinStatistics.GetNewItems();
- },
-};
-
ExtensionInit();
-countDown.Start();
-PlatformHelper.osIsMac().then((isMac) => {
- if (isMac) {
- setInterval(() => countDown.Change(), 10 * 60 * 1000);
- }
+
+// 每半分钟进行一次保活检查
+void PlatformHelper.Alarms.create(alarmKeyAliveCheck, {
+ delayInMinutes: 0.5,
+ periodInMinutes: 0.5,
});
-penguinStatistics.Init();
diff --git a/src/background/request_interceptor.js b/src/background/request_interceptor.js
index 6896154..7877947 100644
--- a/src/background/request_interceptor.js
+++ b/src/background/request_interceptor.js
@@ -1,26 +1,48 @@
-const refererMap = new Map();
+import PlatformHelper from '../common/platform/PlatformHelper';
/**
- *
- * @param url {string}
- * @param referer {string}
+ * Returns a hash code from a string
+ * @param {String} str The string to hash.
+ * @return {Number} A 32bit integer
+ * @see http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
*/
-export function registerUrlToAddReferer(url, referer) {
- refererMap.set(url, referer);
+function hashCode(str) {
+ let hash = 0;
+ for (let i = 0, len = str.length; i < len; i++) {
+ let chr = str.charCodeAt(i);
+ hash = (hash << 5) - hash + chr;
+ hash |= 0; // Convert to 32bit integer
+ }
+ return hash;
}
/**
*
- * @param details {{url: string, requestHeaders: HttpHeaders}}
+ * @param url {string}
+ * @param referer {string}
*/
-export function interceptBeforeSendHeaders(details) {
- if (!refererMap.has(details.url)) return {};
- for (let i = 0; i < details.requestHeaders.length; i++) {
- const header = details.requestHeaders[i];
- if (header.name.toLowerCase() === 'referer') {
- details.requestHeaders.splice(i, 1);
- }
- }
- details.requestHeaders.push({ name: 'Referer', value: refererMap.get(details.url) });
- return { requestHeaders: details.requestHeaders };
+export function registerUrlToAddReferer(url, referer) {
+ const id = Math.abs(hashCode(url));
+ void PlatformHelper.Http.updateSessionRules({
+ removeRuleIds: [id],
+ addRules: [
+ {
+ id: id,
+ action: {
+ type: 'modifyHeaders',
+ requestHeaders: [
+ {
+ header: 'Referer',
+ operation: 'set',
+ value: referer,
+ },
+ ],
+ },
+ condition: {
+ domainType: 'thirdParty',
+ urlFilter: url,
+ },
+ },
+ ],
+ });
}
diff --git a/src/common/platform/AbstractPlatform.js b/src/common/platform/AbstractPlatform.js
index cc41063..3fd56e3 100644
--- a/src/common/platform/AbstractPlatform.js
+++ b/src/common/platform/AbstractPlatform.js
@@ -80,6 +80,15 @@ export class AbstractPlatform {
throw new Error(unsupportedTip);
}
+ /**
+ * 从本地移除一项数据
+ * @param {string|string[]} keys
+ * @return {Promise
+ * @param options {{addRules: any[]}} 规则参数
+ * @return {Promise
+ * @param parameters {{url: string, reasons: string[], justification: string}} 创建参数
+ * @return {Promise
- * @param listener 监听器
- * @param filter URL匹配列表,指定要监听的请求URL
- * @param extraInfoSpec 额外参数
+ * @return {Promise
+ * NOTE: 注意!同时只能存在一个屏幕外文档,所以创建完只能临时用,必须马上关闭。如果要长期用需要专门做一套逻辑。
+ *