diff --git a/packages/core/package.json b/packages/core/package.json index 122092a4..76c188da 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -43,6 +43,7 @@ "homepage": "https://github.com/enncy/online-course-script#readme", "devDependencies": { "@types/string-similarity": "^4.0.0", + "@types/tampermonkey": "^4.0.5", "@vitejs/plugin-vue": "^1.6.1", "@vitejs/plugin-vue-jsx": "^1.3.9", "@vue/compiler-sfc": "^3.2.31", diff --git a/packages/core/src/App.vue b/packages/core/src/App.vue index 8455b209..b9265587 100644 --- a/packages/core/src/App.vue +++ b/packages/core/src/App.vue @@ -43,7 +43,7 @@ import { computed } from "@vue/reactivity"; import { h, ref, watch } from "vue"; import { addFunctionEventListener, getCurrentPanels, togglePanel } from "./core/utils"; import { store } from "./script"; -import { definedScripts } from "./main.ts"; +import { definedScripts } from "./main"; const panels = ref(getCurrentPanels(definedScripts)); diff --git a/packages/core/src/components/index.tsx b/packages/core/src/components/index.tsx index 676c4f61..5d86441c 100644 --- a/packages/core/src/components/index.tsx +++ b/packages/core/src/components/index.tsx @@ -154,7 +154,7 @@ export function createWorkerSetting( {Reflect.ownKeys(aw.data || {}).map((key) => (
  • {key.toString()} = - {hideToken(aw.data[key.toString()])} + {hideToken(aw.data?.[key.toString()] || "")}
  • ))} diff --git a/packages/core/src/core/index.ts b/packages/core/src/core/index.ts index 59686058..e2a73efd 100644 --- a/packages/core/src/core/index.ts +++ b/packages/core/src/core/index.ts @@ -1,10 +1,9 @@ import { defineScript } from "./define.script"; import { OCSWorker } from "./worker"; import { logger } from "../logger"; -import { getItem, setItem } from "./store"; import { QuestionTypeEnum } from "./worker/interface"; import { defaultAnswerWrapperHandler } from "./worker/answer.wrapper.handler"; /** 统一导出 */ -export { getItem, setItem, logger, defineScript, OCSWorker, QuestionTypeEnum, defaultAnswerWrapperHandler }; +export { logger, defineScript, OCSWorker, QuestionTypeEnum, defaultAnswerWrapperHandler }; export * as utils from "./utils"; diff --git a/packages/core/src/core/store.ts b/packages/core/src/core/store.ts index c696316d..51e41708 100644 --- a/packages/core/src/core/store.ts +++ b/packages/core/src/core/store.ts @@ -1,35 +1,17 @@ -import get from "lodash/get"; -import set from "lodash/set"; import { ScriptSettings } from "../scripts"; +import { WorkResult } from "./worker/interface"; -let listeners: any[] = []; - -/** - * object path - * @param path @see https://www.lodashjs.com/docs/lodash.set - * @param value - */ -export function setItem(path: string | string[], value: any) { - const loc: OCSLocalStorage = JSON.parse(localStorage.getItem("OCS") || "{}"); - set(loc, path, value); - localStorage.setItem("OCS", JSON.stringify(loc)); - - listeners - .filter((l) => l.path === path) - .forEach((listener) => { - listener(value); - }); -} - -/** - * object path - * @param path @see https://www.lodashjs.com/docs/lodash.get - * @param defaults 默认值 - * @returns - */ -export function getItem(path: string | string[], defaultValue?: any) { - const loc: OCSLocalStorage = JSON.parse(localStorage.getItem("OCS") || "{}"); - return get(loc, path) || defaultValue; +export interface OCSStore { + /** 版本号 */ + VERSION: string; + setting: ScriptSettings; + localStorage: OCSLocalStorage; + /** 当前视频 */ + currentMedia: HTMLMediaElement | null; + /** 超星 videojs 元素 */ + videojs: HTMLElement | null; + /** 搜索结果存储 */ + workResults: WorkResult[]; } /** @@ -40,7 +22,7 @@ export interface OCSLocalStorage { /** 网课平台类型 */ platform?: string; /** 本地设置 */ - setting?: ScriptSettings; + setting: ScriptSettings; /** 面板是否隐藏 */ hide: boolean; /** 面板位置 */ diff --git a/packages/core/src/core/worker/answer.wrapper.handler.ts b/packages/core/src/core/worker/answer.wrapper.handler.ts index 3c670c89..9d155c0a 100644 --- a/packages/core/src/core/worker/answer.wrapper.handler.ts +++ b/packages/core/src/core/worker/answer.wrapper.handler.ts @@ -1,5 +1,4 @@ import get from "lodash/get"; -import { getItem } from "../store"; /** 题库查询结果 */ export interface SearchResult { @@ -172,9 +171,7 @@ export async function defaultAnswerWrapperHandler( matches.forEach((placeHolder) => { const value: any = /** 获取元素属性 */ - get({ type, title }, placeHolder.replace(/\${(.*)}/, "$1")) || - /** 获取本地存储 */ - getItem(placeHolder.replace(/\${(.*)}/, "$1")); + get({ type, title }, placeHolder.replace(/\${(.*)}/, "$1")); str = str.replace(placeHolder, value); }); return str; diff --git a/packages/core/src/custome.d.ts b/packages/core/src/custome.d.ts index 833ca81e..353c8c38 100644 --- a/packages/core/src/custome.d.ts +++ b/packages/core/src/custome.d.ts @@ -6,6 +6,4 @@ declare global { interface Window { OCS: typeof import("../index"); } - const unsafeWindow: Window | null; - const OCS = ocs; } diff --git a/packages/core/src/script/index.ts b/packages/core/src/script/index.ts index c4a31000..27057373 100644 --- a/packages/core/src/script/index.ts +++ b/packages/core/src/script/index.ts @@ -1,28 +1,29 @@ import defaultsDeep from "lodash/defaultsDeep"; import { reactive, watch } from "vue"; -import { DefineScript } from "../core/define.script"; -import { OCSLocalStorage } from "../core/store"; +import { OCSLocalStorage, OCSStore } from "../core/store"; import { onReady } from "../core/utils"; -import { WorkResult } from "../core/worker/interface"; import { logger } from "../logger"; import { defaultOCSSetting } from "../scripts"; -export interface OCSStore { - /** 版本号 */ - VERSION: string; - setting: typeof defaultOCSSetting; - localStorage: OCSLocalStorage; - /** 当前视频 */ - currentMedia: HTMLMediaElement | null; - /** 超星 videojs 元素 */ - videojs: HTMLElement | null; - /** 搜索结果存储 */ - workResults: WorkResult[]; +/** + * OCS 响应式存储对象, 在除油猴环境下的其他环境为 `{}` + */ +export let store: OCSStore = {} as OCSStore; + +// 环境检测 +if (typeof global === "undefined") { + onReady(() => { + if (typeof unsafeWindow !== "undefined") { + store = unsafeWindow.top?.OCS.store || createStore(); + } else { + logger("warn", "为了确保功能正常使用, 请在油猴环境下运行 https://www.tampermonkey.net/"); + } + }); } -/** 本地存储数据 */ -const _localStorage: OCSLocalStorage = reactive( - defaultsDeep(typeof global === "undefined" ? JSON.parse(localStorage.getItem("OCS") || "{}") : {}, { +function createStore() { + /** 默认存储数据 */ + const defaultStore = defaultsDeep(typeof global === "undefined" ? GM_getValue("store", {}) : {}, { logs: [], workResults: [], /** 是否缩小隐藏面板 */ @@ -32,41 +33,29 @@ const _localStorage: OCSLocalStorage = reactive( x: 0, y: 0, }, - } as OCSLocalStorage) -); - -/** 全局设置 */ -const setting: typeof defaultOCSSetting = defaultsDeep(_localStorage.setting, defaultOCSSetting); + } as Partial); -// @ts-ignore -_localStorage.setting = setting; - -const _store = reactive({ - localStorage: _localStorage, - // @ts-ignore - VERSION: process.env._VERSION_, - setting: setting, - currentMedia: null, - videojs: null, - workResults: [], -}); + /** 本地存储数据 */ + const _localStorage: OCSLocalStorage = reactive({ + setting: defaultsDeep(defaultStore.setting, defaultOCSSetting), + ...defaultStore, + }); -// @ts-ignore -export let store: OCSStore = _store; + // 响应式对象 + const _store = reactive({ + localStorage: _localStorage, + // @ts-ignore + VERSION: process.env._VERSION_, + setting: _localStorage.setting, + currentMedia: null, + videojs: null, + workResults: [], + }); -if (typeof global === "undefined") { /** 监听,并保存到本地 */ watch(_localStorage, () => { - localStorage.OCS = JSON.stringify(_localStorage); + GM_setValue("store", JSON.parse(JSON.stringify(_localStorage))); }); - onReady(() => { - // @ts-ignore - if (typeof unsafeWindow !== "undefined") { - // @ts-ignore - store = unsafeWindow?.top?.OCS.store || _store; - } else { - logger("warn", "为了确保功能正常使用, 请在油猴环境下运行 https://www.tampermonkey.net/"); - } - }); + return _store; } diff --git a/packages/core/src/scripts.ts b/packages/core/src/scripts.ts index 07faed96..b38c20db 100644 --- a/packages/core/src/scripts.ts +++ b/packages/core/src/scripts.ts @@ -18,7 +18,9 @@ export interface Setting { export type SupportPlatform = "zhs" | "cx"; -export type ScriptSettings = Record; +export type ScriptSettings = Record & { + answererWrappers: AnswererWrapper[]; +}; export const defaultOCSSetting = { zhs: defaultSetting(), diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 8bc65439..c1bc69ba 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -13,5 +13,5 @@ "resolveJsonModule": true }, - "include": ["./src/core/index.ts"] + "include": ["./src/core/index.ts", "./src/**/*.ts"] }