From fa9ca35053bf9463747f3ab722fefd0fbd8d1d95 Mon Sep 17 00:00:00 2001 From: ACTCD <101378590+ACTCD@users.noreply.github.com> Date: Wed, 15 Nov 2023 21:22:17 +0800 Subject: [PATCH 1/7] refactor(dev): improve eslint and jsconfig --- eslint.config.js | 18 +++++++++++++++++- scripts/build-app.js | 1 + scripts/build-ext-v4.js | 1 + scripts/build-ext-v5.js | 1 + scripts/jsconfig.json | 26 ++++++++++++++++++++++++++ scripts/preview-app.js | 1 + src/ext/background/main.js | 2 +- 7 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 scripts/jsconfig.json diff --git a/eslint.config.js b/eslint.config.js index e2bd75e7..5b5fa18f 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -49,7 +49,23 @@ export default [ // https://eslint.org/docs/latest/use/configure/migration-guide#configuring-language-options { - files: ["src/**/*.{js,svelte}"], + files: ["scripts/**/*.js"], + languageOptions: { + globals: { + ...globals.node, + }, + }, + }, + { + files: ["src/{app,dev}/**/*.{js,svelte}"], + languageOptions: { + globals: { + ...globals.browser, + }, + }, + }, + { + files: ["src/ext/**/*.{js,svelte}"], languageOptions: { globals: { ...globals.browser, diff --git a/scripts/build-app.js b/scripts/build-app.js index 2fedc7ce..f4713f70 100644 --- a/scripts/build-app.js +++ b/scripts/build-app.js @@ -14,6 +14,7 @@ import { svelte } from "@sveltejs/vite-plugin-svelte"; * Disable auto resolving {@link vite.config.js} * @see {@link https://vitejs.dev/config/ Config} * @see {@link https://vitejs.dev/guide/api-javascript.html#inlineconfig configFile} + * @type {import("vite").InlineConfig} */ const defineConfig = { base: "./", diff --git a/scripts/build-ext-v4.js b/scripts/build-ext-v4.js index 03b01c3a..4a091260 100644 --- a/scripts/build-ext-v4.js +++ b/scripts/build-ext-v4.js @@ -22,6 +22,7 @@ import { svelte } from "@sveltejs/vite-plugin-svelte"; * Disable auto resolving {@link vite.config.js} * @see {@link https://vitejs.dev/config/ Config} * @see {@link https://vitejs.dev/guide/api-javascript.html#inlineconfig configFile} + * @type {import("vite").InlineConfig} */ const defineConfig = { base: "./", diff --git a/scripts/build-ext-v5.js b/scripts/build-ext-v5.js index e810c972..605317b0 100644 --- a/scripts/build-ext-v5.js +++ b/scripts/build-ext-v5.js @@ -21,6 +21,7 @@ import { svelte } from "@sveltejs/vite-plugin-svelte"; * Disable auto resolving {@link vite.config.js} * @see {@link https://vitejs.dev/config/ Config} * @see {@link https://vitejs.dev/guide/api-javascript.html#inlineconfig configFile} + * @type {import("vite").InlineConfig} */ const defineConfig = { base: "./", diff --git a/scripts/jsconfig.json b/scripts/jsconfig.json new file mode 100644 index 00000000..f0633242 --- /dev/null +++ b/scripts/jsconfig.json @@ -0,0 +1,26 @@ +// https://code.visualstudio.com/docs/languages/jsconfig +// https://www.typescriptlang.org/docs/handbook/tsconfig-json.html +// https://www.typescriptlang.org/tsconfig + +// https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html +// https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html + +{ + "compilerOptions": { + "target": "ESNext", + "module": "NodeNext", + "moduleResolution": "nodenext", + + "verbatimModuleSyntax": true, + "isolatedModules": true, + "resolveJsonModule": true, + + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "skipLibCheck": true, + "sourceMap": true + }, + "include": ["**/*.d.ts", "**/*.js"] +} diff --git a/scripts/preview-app.js b/scripts/preview-app.js index 691f601c..d9060d8d 100644 --- a/scripts/preview-app.js +++ b/scripts/preview-app.js @@ -10,6 +10,7 @@ import { preview } from "vite"; * Disable auto resolving {@link vite.config.js} * @see {@link https://vitejs.dev/config/ Config} * @see {@link https://vitejs.dev/guide/api-javascript.html#inlineconfig configFile} + * @type {import("vite").InlineConfig} */ const defineConfig = { base: "./", diff --git a/src/ext/background/main.js b/src/ext/background/main.js index 5d481b2d..e0530cae 100644 --- a/src/ext/background/main.js +++ b/src/ext/background/main.js @@ -321,7 +321,7 @@ async function handleMessage(request, sender, sendResponse) { } case "API_ADD_STYLE": { const tabId = sender.tab.id; - /** @type {{code: string, cssOrigin: "user"|"author"}} */ + /** @type {import("webextension-polyfill").ExtensionTypes.InjectDetails} */ const details = { code: request.css, cssOrigin: "user" }; return browser.tabs.insertCSS(tabId, details); } From 99c5f00dd77adb8aa4a84de93afb49c58ab5a859 Mon Sep 17 00:00:00 2001 From: ACTCD <101378590+ACTCD@users.noreply.github.com> Date: Tue, 28 Nov 2023 03:36:30 +0800 Subject: [PATCH 2/7] refactor(dev): adjust directory structure --- .gitignore | 9 ++- .prettierignore | 2 +- entry-ext-extension-page.html | 2 +- .../ext/safari-15}/images/icon-128.png | Bin .../ext/safari-15}/images/icon-256.png | Bin .../ext/safari-15}/images/icon-48.png | Bin .../ext/safari-15}/images/icon-512.png | Bin .../ext/safari-15}/images/icon-96.png | Bin .../ext/safari-15}/images/toolbar-icon-16.png | Bin .../ext/safari-15}/images/toolbar-icon-32.png | Bin public/ext/safari-15/manifest.json | 63 ++++++++++++++++++ public/ext/safari-16.4/images/128.svg | 1 + public/ext/safari-16.4/images/action.svg | 1 + public/ext/safari-16.4/manifest.json | 48 +++++++++++++ public/ext/shared/_locales/en/messages.json | 10 +++ .../vendor}/jshint.min.js | 0 src/ext/content-scripts/entry-dot-user-js.js | 0 src/ext/content-scripts/entry-greasyfork.js | 0 .../{main.js => entry-userscripts.js} | 24 ++++--- src/ext/shared/utils.js | 4 +- vite.config.js | 38 ++++------- .../Resources/_locales/en/messages.json | 10 --- .../Ext-Safari/Resources/ext-v4-manifest.json | 46 ------------- .../Ext-Safari/Resources/ext-v5-manifest.json | 45 ------------- 24 files changed, 159 insertions(+), 144 deletions(-) rename {xcode/Ext-Safari/Resources => public/ext/safari-15}/images/icon-128.png (100%) rename {xcode/Ext-Safari/Resources => public/ext/safari-15}/images/icon-256.png (100%) rename {xcode/Ext-Safari/Resources => public/ext/safari-15}/images/icon-48.png (100%) rename {xcode/Ext-Safari/Resources => public/ext/safari-15}/images/icon-512.png (100%) rename {xcode/Ext-Safari/Resources => public/ext/safari-15}/images/icon-96.png (100%) rename {xcode/Ext-Safari/Resources => public/ext/safari-15}/images/toolbar-icon-16.png (100%) rename {xcode/Ext-Safari/Resources => public/ext/safari-15}/images/toolbar-icon-32.png (100%) create mode 100644 public/ext/safari-15/manifest.json create mode 100644 public/ext/safari-16.4/images/128.svg create mode 100644 public/ext/safari-16.4/images/action.svg create mode 100644 public/ext/safari-16.4/manifest.json create mode 100644 public/ext/shared/_locales/en/messages.json rename public/{extension-page => ext/vendor}/jshint.min.js (100%) create mode 100644 src/ext/content-scripts/entry-dot-user-js.js create mode 100644 src/ext/content-scripts/entry-greasyfork.js rename src/ext/content-scripts/{main.js => entry-userscripts.js} (92%) delete mode 100644 xcode/Ext-Safari/Resources/_locales/en/messages.json delete mode 100644 xcode/Ext-Safari/Resources/ext-v4-manifest.json delete mode 100644 xcode/Ext-Safari/Resources/ext-v5-manifest.json diff --git a/.gitignore b/.gitignore index 0a6c392f..ded7b2f9 100644 --- a/.gitignore +++ b/.gitignore @@ -13,7 +13,6 @@ dist dist-ssr build built -*.local # Logs logs @@ -47,5 +46,9 @@ xcuserdata/ *.xcuserstate *.dev.xcconfig XCBuildData -xcode/**/build/ -xcode/**/dist/ \ No newline at end of file +xcode/Ext-Safari/Resources/ + +# directories and files +local +*.local +/scripts/*.local.js \ No newline at end of file diff --git a/.prettierignore b/.prettierignore index be1335e6..5c1a0da1 100644 --- a/.prettierignore +++ b/.prettierignore @@ -6,7 +6,7 @@ # root /package -/public +/public/**/vendor /etc # dir diff --git a/entry-ext-extension-page.html b/entry-ext-extension-page.html index 16e4944d..b112106c 100644 --- a/entry-ext-extension-page.html +++ b/entry-ext-extension-page.html @@ -10,6 +10,6 @@
- + diff --git a/xcode/Ext-Safari/Resources/images/icon-128.png b/public/ext/safari-15/images/icon-128.png similarity index 100% rename from xcode/Ext-Safari/Resources/images/icon-128.png rename to public/ext/safari-15/images/icon-128.png diff --git a/xcode/Ext-Safari/Resources/images/icon-256.png b/public/ext/safari-15/images/icon-256.png similarity index 100% rename from xcode/Ext-Safari/Resources/images/icon-256.png rename to public/ext/safari-15/images/icon-256.png diff --git a/xcode/Ext-Safari/Resources/images/icon-48.png b/public/ext/safari-15/images/icon-48.png similarity index 100% rename from xcode/Ext-Safari/Resources/images/icon-48.png rename to public/ext/safari-15/images/icon-48.png diff --git a/xcode/Ext-Safari/Resources/images/icon-512.png b/public/ext/safari-15/images/icon-512.png similarity index 100% rename from xcode/Ext-Safari/Resources/images/icon-512.png rename to public/ext/safari-15/images/icon-512.png diff --git a/xcode/Ext-Safari/Resources/images/icon-96.png b/public/ext/safari-15/images/icon-96.png similarity index 100% rename from xcode/Ext-Safari/Resources/images/icon-96.png rename to public/ext/safari-15/images/icon-96.png diff --git a/xcode/Ext-Safari/Resources/images/toolbar-icon-16.png b/public/ext/safari-15/images/toolbar-icon-16.png similarity index 100% rename from xcode/Ext-Safari/Resources/images/toolbar-icon-16.png rename to public/ext/safari-15/images/toolbar-icon-16.png diff --git a/xcode/Ext-Safari/Resources/images/toolbar-icon-32.png b/public/ext/safari-15/images/toolbar-icon-32.png similarity index 100% rename from xcode/Ext-Safari/Resources/images/toolbar-icon-32.png rename to public/ext/safari-15/images/toolbar-icon-32.png diff --git a/public/ext/safari-15/manifest.json b/public/ext/safari-15/manifest.json new file mode 100644 index 00000000..99c503ee --- /dev/null +++ b/public/ext/safari-15/manifest.json @@ -0,0 +1,63 @@ +{ + "manifest_version": 2, + "default_locale": "en", + "name": "__MSG_extension_name__", + "description": "__MSG_extension_description__", + "version": "_VERSION_", + "icons": { + "48": "images/icon-48.png", + "96": "images/icon-96.png", + "128": "images/icon-128.png", + "256": "images/icon-256.png", + "512": "images/icon-512.png" + }, + "background": { + "scripts": ["dist/background.js"], + "persistent": false + }, + "browser_action": { + "default_popup": "dist/entry-ext-action-popup.html", + "default_icon": { + "16": "images/toolbar-icon-16.png", + "32": "images/toolbar-icon-32.png" + } + }, + "content_scripts": [ + { + "js": ["dist/content-scripts/userscripts.js"], + "matches": [""], + "run_at": "document_start", + "all_frames": true + }, + { + "js": ["dist/content-scripts/dot-user-js.js"], + "matches": [ + "*://*/*.user.js", + "*://*/*.user.js?*", + "*://*/*.user.css", + "*://*/*.user.css?*" + ], + "run_at": "document_start", + "all_frames": false + }, + { + "js": ["dist/content-scripts/greasyfork.js"], + "matches": ["*://*.greasyfork.org/*"], + "run_at": "document_start", + "all_frames": false + } + ], + "permissions": [ + "", + "clipboardWrite", + "contextMenus", + "declarativeNetRequest", + "declarativeNetRequestWithHostAccess", + "menus", + "nativeMessaging", + "storage", + "tabs", + "unlimitedStorage", + "webNavigation" + ] +} diff --git a/public/ext/safari-16.4/images/128.svg b/public/ext/safari-16.4/images/128.svg new file mode 100644 index 00000000..c6ec62ad --- /dev/null +++ b/public/ext/safari-16.4/images/128.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/ext/safari-16.4/images/action.svg b/public/ext/safari-16.4/images/action.svg new file mode 100644 index 00000000..ad16f09d --- /dev/null +++ b/public/ext/safari-16.4/images/action.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/ext/safari-16.4/manifest.json b/public/ext/safari-16.4/manifest.json new file mode 100644 index 00000000..7d2c00da --- /dev/null +++ b/public/ext/safari-16.4/manifest.json @@ -0,0 +1,48 @@ +{ + "manifest_version": 2, + "default_locale": "en", + "name": "__MSG_extension_name__", + "description": "__MSG_extension_description__", + "version": "_VERSION_", + "icons": { + "48": "images/128.svg", + "96": "images/128.svg", + "128": "images/128.svg", + "256": "images/128.svg", + "512": "images/128.svg" + }, + "background": { + "scripts": ["dist/background.js"], + "persistent": false + }, + "browser_action": { + "default_popup": "dist/entry-ext-action-popup.html", + "default_icon": "images/action.svg" + }, + "content_scripts": [ + { + "js": ["dist/content-scripts/userscripts.js"], + "matches": [""], + "run_at": "document_start", + "all_frames": true + } + ], + "permissions": [ + "", + "clipboardWrite", + "contextMenus", + "declarativeNetRequestWithHostAccess", + "menus", + "nativeMessaging", + "scripting", + "storage", + "tabs", + "unlimitedStorage", + "webNavigation" + ], + "browser_specific_settings": { + "safari": { + "strict_min_version": "16.4" + } + } +} diff --git a/public/ext/shared/_locales/en/messages.json b/public/ext/shared/_locales/en/messages.json new file mode 100644 index 00000000..e840a3a2 --- /dev/null +++ b/public/ext/shared/_locales/en/messages.json @@ -0,0 +1,10 @@ +{ + "extension_name": { + "message": "_NAME_", + "description": "The display name for the extension." + }, + "extension_description": { + "message": "Save and run javascript for the web pages you visit", + "description": "Description of what the extension does." + } +} diff --git a/public/extension-page/jshint.min.js b/public/ext/vendor/jshint.min.js similarity index 100% rename from public/extension-page/jshint.min.js rename to public/ext/vendor/jshint.min.js diff --git a/src/ext/content-scripts/entry-dot-user-js.js b/src/ext/content-scripts/entry-dot-user-js.js new file mode 100644 index 00000000..e69de29b diff --git a/src/ext/content-scripts/entry-greasyfork.js b/src/ext/content-scripts/entry-greasyfork.js new file mode 100644 index 00000000..e69de29b diff --git a/src/ext/content-scripts/main.js b/src/ext/content-scripts/entry-userscripts.js similarity index 92% rename from src/ext/content-scripts/main.js rename to src/ext/content-scripts/entry-userscripts.js index ce307fd8..ab620622 100644 --- a/src/ext/content-scripts/main.js +++ b/src/ext/content-scripts/entry-userscripts.js @@ -1,4 +1,4 @@ -import apis from "./api.js"; +import USAPI from "./api.js"; // code received from background page will be stored in this variable // code referenced again when strict CSPs block initial injection attempt @@ -52,24 +52,26 @@ function injectJS(userscript) { if (injectInto === "auto" && (userscript.fallback || cspFallbackAttempted)) { injectInto = "content"; console.warn(`Attempting fallback injection for ${name}`); - } else if (window.self === window.top) { - console.info(`Injecting ${name} %c(js)`, "color: #fff600"); + } + const world = injectInto === "content" ? "content" : "page"; + if (window.self === window.top) { + console.info(`Injecting: ${name} %c(js/${world})`, "color: #fff600"); } else { console.info( - `Injecting ${name} %c(js)%c - %cframe(${label})(${window.location})`, + `Injecting: ${name} %c(js/${world})%c - %cframe(${label})(${window.location})`, "color: #fff600", "color: inherit", "color: #006fff", ); } - if (injectInto !== "content") { + if (world === "page") { const div = document.createElement("div"); div.style.display = "none"; const shadowRoot = div.attachShadow({ mode: "closed" }); - document.body.append(div); const tag = document.createElement("script"); tag.textContent = code; shadowRoot.append(tag); + (document.body ?? document.head ?? document.documentElement).append(div); } else { try { // eslint-disable-next-line no-new-func @@ -186,8 +188,8 @@ async function injection() { for (let j = 0; j < grants.length; j++) { const grant = grants[j]; const method = grant.split(".")[1] || grant.split(".")[0]; - // ensure API method exists in apis object - if (!Object.keys(apis).includes(method)) continue; + // ensure API method exists in USAPI object + if (!Object.keys(USAPI).includes(method)) continue; // add granted methods switch (method) { case "info": @@ -197,15 +199,15 @@ async function injection() { case "setValue": case "deleteValue": case "listValues": - userscript.apis.GM[method] = apis[method].bind({ + userscript.apis.GM[method] = USAPI[method].bind({ US_filename: filename, }); break; case "GM_xmlhttpRequest": - userscript.apis[method] = apis[method]; + userscript.apis[method] = USAPI[method]; break; default: - userscript.apis.GM[method] = apis[method]; + userscript.apis.GM[method] = USAPI[method]; } } // triage userjs item for injection diff --git a/src/ext/shared/utils.js b/src/ext/shared/utils.js index c8c1355e..fae3e29e 100644 --- a/src/ext/shared/utils.js +++ b/src/ext/shared/utils.js @@ -186,8 +186,8 @@ export const validMetaKeys = new Set([ ]); export const extensionPaths = { - popup: "/dist/s/entry-ext-action-popup.html", - page: "/dist/s/entry-ext-extension-page.html", + popup: "/dist/entry-ext-action-popup.html", + page: "/dist/entry-ext-extension-page.html", }; export async function openExtensionPage() { diff --git a/vite.config.js b/vite.config.js index 81d75297..3d4378f9 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,34 +1,22 @@ import { defineConfig } from "vite"; import { svelte } from "@sveltejs/vite-plugin-svelte"; -// [inline-svg] -// TODO: remove this once vite resolved issue -// https://github.com/vitejs/vite/issues/1204 -// import fs from "fs"; -// import svgpkg from "svg-inline-loader"; -// export function svgInline() { // custom plugin -// return { -// name: "transform-file", -// transform(code, id) { -// if (id.endsWith(".svg")) { -// const svg = fs.readFileSync(id, "utf8"); -// const ret = svgpkg.getExtractedSVG(svg, {}); -// return `export default '${ret}'`; -// } -// } -// }; -// } -// [inline-svg] -// NOW: use `?raw` suffix import svg assets as inline -// https://vitejs.dev/guide/assets.html#importing-asset-as-string +/** + * About `inline-svg` + * use `?raw` suffix import svg assets as inline + * @see {@link https://vitejs.dev/guide/assets.html#importing-asset-as-string} + */ -// [autoprefixer] -// https://vitejs.dev/guide/features.html#postcss -// have config with `.postcssrc.json` file -// about `missing peer postcss` error, ignore it +/** + * About `autoprefixer` + * have config with `.postcssrc.json` file + * @see {@link https://vitejs.dev/guide/features.html#postcss} + * about `missing peer postcss` error, ignore it + */ -// https://vitejs.dev/config/ +/** @see {@link https://vitejs.dev/config/} */ export default defineConfig({ + publicDir: "public/ext/vendor/", plugins: [svelte()], base: "./", }); diff --git a/xcode/Ext-Safari/Resources/_locales/en/messages.json b/xcode/Ext-Safari/Resources/_locales/en/messages.json deleted file mode 100644 index 8db4438d..00000000 --- a/xcode/Ext-Safari/Resources/_locales/en/messages.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extension_name": { - "message": "_NAME_", - "description": "The display name for the extension." - }, - "extension_description": { - "message": "Save and run javascript for the web pages you visit", - "description": "Description of what the extension does." - } -} diff --git a/xcode/Ext-Safari/Resources/ext-v4-manifest.json b/xcode/Ext-Safari/Resources/ext-v4-manifest.json deleted file mode 100644 index dde68d2a..00000000 --- a/xcode/Ext-Safari/Resources/ext-v4-manifest.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "manifest_version": 2, - "default_locale": "en", - "name": "__MSG_extension_name__", - "description": "__MSG_extension_description__", - "version": "_VERSION_", - "icons": { - "48": "images/icon-48.png", - "96": "images/icon-96.png", - "128": "images/icon-128.png", - "256": "images/icon-256.png", - "512": "images/icon-512.png" - }, - "background": { - "scripts": ["dist/background.js"], - "persistent": false - }, - "browser_action": { - "default_popup": "dist/s/entry-ext-action-popup.html", - "default_icon": { - "16": "images/toolbar-icon-16.png", - "32": "images/toolbar-icon-32.png" - } - }, - "content_scripts": [ - { - "js": ["dist/content.js"], - "matches": [""], - "run_at": "document_start", - "all_frames": true - } - ], - "permissions": [ - "", - "clipboardWrite", - "contextMenus", - "declarativeNetRequest", - "declarativeNetRequestWithHostAccess", - "menus", - "nativeMessaging", - "storage", - "tabs", - "unlimitedStorage", - "webNavigation" - ] -} diff --git a/xcode/Ext-Safari/Resources/ext-v5-manifest.json b/xcode/Ext-Safari/Resources/ext-v5-manifest.json deleted file mode 100644 index ead6d695..00000000 --- a/xcode/Ext-Safari/Resources/ext-v5-manifest.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "manifest_version": 2, - "default_locale": "en", - "name": "__MSG_extension_name__", - "description": "__MSG_extension_description__", - "version": "_VERSION_", - "icons": { - "48": "images/icon-48.png", - "96": "images/icon-96.png", - "128": "images/icon-128.png", - "256": "images/icon-256.png", - "512": "images/icon-512.png" - }, - "background": { - "scripts": ["dist/background.js"], - "persistent": false - }, - "browser_action": { - "default_popup": "dist/s/entry-ext-action-popup.html", - "default_icon": { - "16": "images/toolbar-icon-16.png", - "32": "images/toolbar-icon-32.png" - } - }, - "content_scripts": [ - { - "js": ["dist/content.js"], - "matches": [""], - "run_at": "document_start", - "all_frames": true - } - ], - "permissions": [ - "", - "clipboardWrite", - "contextMenus", - "declarativeNetRequestWithHostAccess", - "menus", - "nativeMessaging", - "storage", - "tabs", - "unlimitedStorage", - "webNavigation" - ] -} From 6a3faded6327186518b05c07d5c4e16b80ed74fc Mon Sep 17 00:00:00 2001 From: ACTCD <101378590+ACTCD@users.noreply.github.com> Date: Tue, 28 Nov 2023 05:25:10 +0800 Subject: [PATCH 3/7] refactor(dev): create remote real-time dev build and server With this new way of development build and server, modify and save the extension code in the src to instantly see the reaction in the safari extension environment. The extension pages (popup, background etc.) are automatically refreshed, and the content scripts will instantly updated the next time the page is reload. --- entry-ext-background.html | 9 + package.json | 10 +- public/ext/safari-dev/manifest-ios.json | 52 +++++ public/ext/safari-dev/manifest-mac.json | 52 +++++ public/ext/shared-dev/images/128.svg | 1 + public/ext/shared-dev/images/action.svg | 1 + ...build-ext-v4.js => build-ext-safari-15.js} | 74 ++++-- ...ild-ext-v5.js => build-ext-safari-16.4.js} | 89 ++++--- scripts/dev-ext-safari.js | 220 ++++++++++++++++++ scripts/utils.js | 92 ++++++++ src/ext/action-popup/main.js | 14 +- src/ext/extension-page/main.js | 6 +- src/ext/shared/dev.js | 6 +- 13 files changed, 558 insertions(+), 68 deletions(-) create mode 100644 entry-ext-background.html create mode 100644 public/ext/safari-dev/manifest-ios.json create mode 100644 public/ext/safari-dev/manifest-mac.json create mode 100644 public/ext/shared-dev/images/128.svg create mode 100644 public/ext/shared-dev/images/action.svg rename scripts/{build-ext-v4.js => build-ext-safari-15.js} (55%) rename scripts/{build-ext-v5.js => build-ext-safari-16.4.js} (50%) create mode 100644 scripts/dev-ext-safari.js create mode 100644 scripts/utils.js diff --git a/entry-ext-background.html b/entry-ext-background.html new file mode 100644 index 00000000..e3ee5d4c --- /dev/null +++ b/entry-ext-background.html @@ -0,0 +1,9 @@ + + + + Userscripts background + + + + + diff --git a/package.json b/package.json index c2802776..e478e39d 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,15 @@ "type": "module", "scripts": { "dev": "vite", - "build": "npm run build:app && npm run build:ext", + "dev:ext-safari-mac": "SAFARI_PLATFORM=mac node scripts/dev-ext-safari.js", + "dev:ext-safari-ios": "SAFARI_PLATFORM=ios node scripts/dev-ext-safari.js", + "build:mac": "npm run build:app && npm run build:ext-safari-mac", + "build:ios": "npm run build:app && npm run build:ext-safari-ios", "build:app": "node scripts/build-app.js", - "build:ext": "node scripts/build-ext-v4.js", + "build:ext-safari-mac": "SAFARI_PLATFORM=mac node scripts/build-ext-safari-15.js", + "build:ext-safari-ios": "SAFARI_PLATFORM=ios node scripts/build-ext-safari-15.js", + "build:ext-safari-mac-16.4": "SAFARI_PLATFORM=mac node scripts/build-ext-safari-16.4.js", + "build:ext-safari-ios-16.4": "SAFARI_PLATFORM=ios node scripts/build-ext-safari-16.4.js", "lint:js": "eslint . && prettier --check . --plugin prettier-plugin-svelte", "lint:css": "stylelint '**/*.{css,html,svelte}'", "prettier": "prettier --write . --plugin prettier-plugin-svelte" diff --git a/public/ext/safari-dev/manifest-ios.json b/public/ext/safari-dev/manifest-ios.json new file mode 100644 index 00000000..2cb0308a --- /dev/null +++ b/public/ext/safari-dev/manifest-ios.json @@ -0,0 +1,52 @@ +{ + "manifest_version": 2, + "default_locale": "en", + "name": "__MSG_extension_name__", + "description": "__MSG_extension_description__", + "version": "_VERSION_", + "icons": { + "48": "images/128.svg", + "96": "images/128.svg", + "128": "images/128.svg", + "256": "images/128.svg", + "512": "images/128.svg" + }, + "background": { + "page": "dist/entry-ext-background.html", + "persistent": false + }, + "browser_action": { + "default_popup": "dist/entry-ext-action-popup.html", + "default_icon": "images/action.svg" + }, + "options_ui": { + "page": "dist/entry-ext-extension-page.html#settings" + }, + "content_scripts": [ + { + "js": ["dist/content-scripts/userscripts.js"], + "matches": [""], + "run_at": "document_start", + "all_frames": true + } + ], + "permissions": [ + "", + "clipboardWrite", + "contextMenus", + "declarativeNetRequestWithHostAccess", + "menus", + "nativeMessaging", + "scripting", + "storage", + "tabs", + "unlimitedStorage", + "webNavigation" + ], + "browser_specific_settings": { + "safari": { + "strict_min_version": "16.4" + } + }, + "content_security_policy": "script-src 'self' https://localhost:55173 https://userscripts.test:55173" +} diff --git a/public/ext/safari-dev/manifest-mac.json b/public/ext/safari-dev/manifest-mac.json new file mode 100644 index 00000000..046f8239 --- /dev/null +++ b/public/ext/safari-dev/manifest-mac.json @@ -0,0 +1,52 @@ +{ + "manifest_version": 2, + "default_locale": "en", + "name": "__MSG_extension_name__", + "description": "__MSG_extension_description__", + "version": "_VERSION_", + "icons": { + "48": "images/128.svg", + "96": "images/128.svg", + "128": "images/128.svg", + "256": "images/128.svg", + "512": "images/128.svg" + }, + "background": { + "page": "dist/entry-ext-background.html", + "persistent": true + }, + "browser_action": { + "default_popup": "dist/entry-ext-action-popup.html", + "default_icon": "images/action.svg" + }, + "options_ui": { + "page": "dist/entry-ext-extension-page.html#settings" + }, + "content_scripts": [ + { + "js": ["dist/content-scripts/userscripts.js"], + "matches": [""], + "run_at": "document_start", + "all_frames": true + } + ], + "permissions": [ + "", + "clipboardWrite", + "contextMenus", + "declarativeNetRequestWithHostAccess", + "menus", + "nativeMessaging", + "scripting", + "storage", + "tabs", + "unlimitedStorage", + "webNavigation" + ], + "browser_specific_settings": { + "safari": { + "strict_min_version": "16.4" + } + }, + "content_security_policy": "script-src 'self' https://localhost:55173 https://userscripts.test:55173" +} diff --git a/public/ext/shared-dev/images/128.svg b/public/ext/shared-dev/images/128.svg new file mode 100644 index 00000000..76189438 --- /dev/null +++ b/public/ext/shared-dev/images/128.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/ext/shared-dev/images/action.svg b/public/ext/shared-dev/images/action.svg new file mode 100644 index 00000000..3789dd89 --- /dev/null +++ b/public/ext/shared-dev/images/action.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/scripts/build-ext-v4.js b/scripts/build-ext-safari-15.js similarity index 55% rename from scripts/build-ext-v4.js rename to scripts/build-ext-safari-15.js index 4a091260..3242f700 100644 --- a/scripts/build-ext-v4.js +++ b/scripts/build-ext-safari-15.js @@ -16,17 +16,20 @@ import { build } from "vite"; import { svelte } from "@sveltejs/vite-plugin-svelte"; +import { cp, emptyBuildDir, rootDir, SAFARI_EXT_RESOURCES } from "./utils.js"; /** * Define default vite config options * Disable auto resolving {@link vite.config.js} * @see {@link https://vitejs.dev/config/ Config} - * @see {@link https://vitejs.dev/guide/api-javascript.html#inlineconfig configFile} + * @see {@link https://vitejs.dev/guide/api-javascript.html#inlineconfig InlineConfig} * @type {import("vite").InlineConfig} */ const defineConfig = { - base: "./", configFile: false, + envFile: false, + root: await rootDir(), + base: "./", define: { "import.meta.env.BROWSER": JSON.stringify("safari"), "import.meta.env.NATIVE_APP": JSON.stringify("app"), @@ -34,41 +37,62 @@ const defineConfig = { }; /** - * Build shared modules for safari - * These multiple entry files will share the same modules - * Using a subdirectory avoid emptying other built files + * Empty resources directory + * Copy public static assets */ -build({ - ...defineConfig, - plugins: [svelte()], - build: { - outDir: "xcode/Ext-Safari/Resources/dist/s/", - rollupOptions: { - input: ["entry-ext-action-popup.html", "entry-ext-extension-page.html"], - }, - }, -}); +await emptyBuildDir(SAFARI_EXT_RESOURCES); +cp("public/ext/shared", SAFARI_EXT_RESOURCES); +cp("public/ext/safari-15", SAFARI_EXT_RESOURCES); -/** - * Build independent scripts for safari - * Each entry in the array will generate a separate script - */ +/** Build content scripts */ [ - { background: "src/ext/background/main.js" }, - { content: "src/ext/content-scripts/main.js" }, + { userscripts: "src/ext/content-scripts/entry-userscripts.js" }, + { "dot-user-js": "src/ext/content-scripts/entry-dot-user-js.js" }, + { greasyfork: "src/ext/content-scripts/entry-greasyfork.js" }, ].forEach((input) => { build({ ...defineConfig, build: { - outDir: "xcode/Ext-Safari/Resources/dist/", + outDir: `${SAFARI_EXT_RESOURCES}/dist/content-scripts/`, emptyOutDir: false, copyPublicDir: false, rollupOptions: { input, - output: { - entryFileNames: "[name].js", - }, + output: { entryFileNames: "[name].js" }, }, }, }); }); + +/** Build background scripts */ +build({ + ...defineConfig, + build: { + outDir: `${SAFARI_EXT_RESOURCES}/dist/`, + emptyOutDir: false, + copyPublicDir: false, + rollupOptions: { + input: { background: "src/ext/background/main.js" }, + output: { entryFileNames: "[name].js" }, + }, + }, +}); + +/** Build shared modules */ +/** @type {import("rollup").InputOption} */ +let input = ["entry-ext-action-popup.html", "entry-ext-extension-page.html"]; +if (process.env.SAFARI_PLATFORM === "ios") { + input = ["entry-ext-action-popup.html"]; +} +build({ + ...defineConfig, + plugins: [svelte()], + publicDir: "public/ext/vendor/", + build: { + outDir: `${SAFARI_EXT_RESOURCES}/dist/`, + emptyOutDir: false, + rollupOptions: { + input, + }, + }, +}); diff --git a/scripts/build-ext-v5.js b/scripts/build-ext-safari-16.4.js similarity index 50% rename from scripts/build-ext-v5.js rename to scripts/build-ext-safari-16.4.js index 605317b0..12a67481 100644 --- a/scripts/build-ext-v5.js +++ b/scripts/build-ext-safari-16.4.js @@ -15,6 +15,7 @@ import { build } from "vite"; import { svelte } from "@sveltejs/vite-plugin-svelte"; +import { cp, emptyBuildDir, rootDir, SAFARI_EXT_RESOURCES } from "./utils.js"; /** * Define default vite config options @@ -24,8 +25,10 @@ import { svelte } from "@sveltejs/vite-plugin-svelte"; * @type {import("vite").InlineConfig} */ const defineConfig = { - base: "./", configFile: false, + envFile: false, + root: await rootDir(), + base: "./", define: { "import.meta.env.BROWSER": JSON.stringify("safari"), "import.meta.env.NATIVE_APP": JSON.stringify("app"), @@ -33,45 +36,71 @@ const defineConfig = { }; /** - * Build shared modules for safari - * These multiple entry files will share the same modules - * Using a subdirectory avoid emptying other built files + * Empty resources directory + * Copy public static assets */ -build({ - ...defineConfig, - plugins: [svelte()], - build: { - outDir: "xcode/Ext-Safari/Resources/dist/s/", - rollupOptions: { - input: { - background: "src/ext/background/main.js", - "action-popup": "entry-ext-action-popup.html", - "extension-page": "entry-ext-extension-page.html", - }, - output: { - entryFileNames: "[name].js", - }, - }, - }, -}); +await emptyBuildDir(SAFARI_EXT_RESOURCES); +cp("public/ext/shared", SAFARI_EXT_RESOURCES); +cp("public/ext/safari-16.4", SAFARI_EXT_RESOURCES); -/** - * Build independent scripts for safari - * Each entry in the array will generate a separate script - */ -[{ content: "src/ext/content-scripts/main.js" }].forEach((input) => { +/** Build content scripts */ +[ + { userscripts: "src/ext/content-scripts/entry-userscripts.js" }, + { "dot-user-js": "src/ext/content-scripts/entry-dot-user-js.js" }, + { greasyfork: "src/ext/content-scripts/entry-greasyfork.js" }, +].forEach((input) => { build({ ...defineConfig, build: { - outDir: "xcode/Ext-Safari/Resources/dist/", + outDir: `${SAFARI_EXT_RESOURCES}/dist/content-scripts/`, emptyOutDir: false, copyPublicDir: false, rollupOptions: { input, - output: { - entryFileNames: "[name].js", - }, + output: { entryFileNames: "[name].js" }, }, }, }); }); + +/** + * Build background scripts + * Modular background may not load correctly on Safari startup + * Currently build classic script separately to avoid this error + */ +build({ + ...defineConfig, + build: { + outDir: `${SAFARI_EXT_RESOURCES}/dist/`, + emptyOutDir: false, + copyPublicDir: false, + rollupOptions: { + input: { background: "src/ext/background/main.js" }, + output: { entryFileNames: "[name].js" }, + }, + }, +}); + +/** Build shared modules */ +/** @type {import("rollup").InputOption} */ +let input = { + // background: "src/ext/background/main.js", + "action-popup": "entry-ext-action-popup.html", + "extension-page": "entry-ext-extension-page.html", +}; +if (process.env.SAFARI_PLATFORM === "ios") { + delete input["extension-page"]; +} +build({ + ...defineConfig, + plugins: [svelte()], + publicDir: "public/ext/vendor/", + build: { + outDir: `${SAFARI_EXT_RESOURCES}/dist/`, + emptyOutDir: false, + rollupOptions: { + input, + output: { entryFileNames: "[name].js" }, + }, + }, +}); diff --git a/scripts/dev-ext-safari.js b/scripts/dev-ext-safari.js new file mode 100644 index 00000000..2b4e7c25 --- /dev/null +++ b/scripts/dev-ext-safari.js @@ -0,0 +1,220 @@ +/** + * @file Develop Safari extension resources using the Vite JavaScript API + * @see {@link https://vitejs.dev/guide/api-javascript.html JavaScript API} + * This development build and server requires a valid https certificate to support remote real-time development + * Typically using a self-signed certificate, it needs to be installed and trusted by the device or simulator + * @see {@link https://developer.apple.com/library/archive/qa/qa1948/} + * @see {@link https://developer.apple.com/library/archive/technotes/tn2326/} + */ + +import { build, createServer } from "vite"; +import { svelte } from "@sveltejs/vite-plugin-svelte"; +import { + cp, + emptyBuildDir, + sharedServerOptions, + rootDir, + SAFARI_EXT_RESOURCES, +} from "./utils.js"; +import https from "node:https"; + +/** + * Define default vite config options + * Disable auto resolving {@link vite.config.js} + * @see {@link https://vitejs.dev/config/ Config} + * @see {@link https://vitejs.dev/guide/api-javascript.html#inlineconfig configFile} + * @type {import("vite").InlineConfig} + */ +const defineConfig = { + configFile: false, + envFile: false, + root: await rootDir(), + base: "./", + define: { + "import.meta.env.BROWSER": JSON.stringify("safari"), + "import.meta.env.NATIVE_APP": JSON.stringify("app"), + }, +}; + +/** + * Build resources for remote real-time development + * @param {import("vite").ViteDevServer} server + * @param {string} origin + */ +async function buildResources(server, origin) { + /** + * empty resources directory + * copy public static assets + */ + await emptyBuildDir("dist"); + await emptyBuildDir(SAFARI_EXT_RESOURCES); + cp("public/ext/shared", SAFARI_EXT_RESOURCES); + cp("public/ext/shared-dev", SAFARI_EXT_RESOURCES); + if (process.env.SAFARI_PLATFORM === "ios") { + cp( + "public/ext/safari-dev/manifest-ios.json", + `${SAFARI_EXT_RESOURCES}/manifest.json`, + ); + } else { + cp( + "public/ext/safari-dev/manifest-mac.json", + `${SAFARI_EXT_RESOURCES}/manifest.json`, + ); + } + + /** build content scripts */ + [ + { userscripts: "src/ext/content-scripts/entry-userscripts.js" }, + { "dot-user-js": "src/ext/content-scripts/entry-dot-user-js.js" }, + { greasyfork: "src/ext/content-scripts/entry-greasyfork.js" }, + ].forEach((input) => { + /** build proxy content scripts replace actual code */ + build({ + ...defineConfig, + plugins: [ + { + name: "generate-content-proxy", + load(id) { + const name = id.replace(/.+entry-/, ""); + const url = `${origin}/dist/content-scripts/${name}`; + return `// proxy content + const xhr = new XMLHttpRequest(); + xhr.open("GET", "${url}", false); + xhr.send(); + const code = xhr.responseText; + try { + Function(code + "//# sourceURL=proxy-${name}")(); + } catch (error) { + console.error(error); + }`; + }, + }, + ], + build: { + outDir: `${SAFARI_EXT_RESOURCES}/dist/content-scripts/`, + emptyOutDir: false, + copyPublicDir: false, + rollupOptions: { + input, + output: { entryFileNames: "[name].js" }, + }, + }, + }); + /** build content scripts for dev server and watch changes */ + build({ + ...defineConfig, + build: { + outDir: `dist/content-scripts/`, + emptyOutDir: false, + copyPublicDir: false, + rollupOptions: { + input, + output: { entryFileNames: "[name].js" }, + }, + watch: {}, + minify: false, + }, + }); + }); + + /** generate entrance dist */ + build({ + ...defineConfig, + publicDir: "public/ext/vendor/", + plugins: [ + /** + * @see {@link https://github.com/vitejs/vite/issues/14263} + * Dev only requires entrances, so order `pre` without transform modules + */ + { + name: "generate-dev-entrance", + transformIndexHtml: { + order: "pre", + async handler(html, ctx) { + const str = await server.transformIndexHtml(ctx.path, html); + return str.replaceAll(`src="/`, `src="${origin}/`); + }, + }, + }, + ], + build: { + outDir: `${SAFARI_EXT_RESOURCES}/dist/`, + emptyOutDir: false, + rollupOptions: { + input: { + background: "entry-ext-background.html", + "action-popup": "entry-ext-action-popup.html", + "extension-page": "entry-ext-extension-page.html", + }, + }, + }, + }); +} + +/** + * Define shared constants + * Developing in native machine and simulator can just use `https://localhost:port/` as the origin + * But using a fixed domain name on non-native devices such as real iOS devices is a better choice + * The local domain name needs to be resolved to the LAN IP address on LAN DNS or the target device + * When the origin specified here is unreachable, localhost will be automatically used as the alternate + * The origin requires as an exemption to be added to the `manifest.json` due to default CSP limitations + * @see {@link https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_Security_Policy} + * @see {@link https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_security_policy} + */ +const serverOptions = await sharedServerOptions(); +const SERVER_PORT = 55173; +const SERVER_ORIGIN = `https://userscripts.test:${SERVER_PORT}`; + +/** + * Check if the server is reachable with self-signed certificate + * @param {string | URL} url + * @returns {Promise} + */ +async function serverCheck(url) { + const options = { + method: "HEAD", + ca: serverOptions.ca, + headers: { Accept: "*/*" }, + }; + return new Promise((resolve) => { + const req = https.request(url, options, (res) => { + if (res.headers.server === SERVER_ORIGIN) { + resolve(true); + } + resolve(false); + }); + req.on("error", (e) => { + console.error(`${req.host}: ${e.message}`); + resolve(false); + }); + req.end(); + }); +} + +/** main process */ +(async () => { + /** run development server */ + const server = await createServer({ + ...defineConfig, + plugins: [svelte()], + server: { + host: true, + port: SERVER_PORT, + strictPort: true, + https: { key: serverOptions.key, cert: serverOptions.cert }, + headers: { server: SERVER_ORIGIN }, + }, + }); + await server.listen(); + server.printUrls(); + + // Check available origins and build resources + for (let url of [SERVER_ORIGIN, ...server.resolvedUrls.local]) { + if (await serverCheck(url)) { + const origin = url.at(-1) === "/" ? url.slice(0, -1) : url; + console.info(`build with origin: ${origin}`); + buildResources(server, origin); + break; + } + } +})(); diff --git a/scripts/utils.js b/scripts/utils.js new file mode 100644 index 00000000..c80fb51b --- /dev/null +++ b/scripts/utils.js @@ -0,0 +1,92 @@ +import { chdir, cwd } from "node:process"; +import { fileURLToPath } from "node:url"; +import { + copyFile, + mkdir, + readdir, + readFile, + realpath, + rm, + stat, +} from "node:fs/promises"; + +/** Define shared constants */ +export const SAFARI_APP_RESOURCES = "xcode/App-Shared/Resources"; +export const SAFARI_EXT_RESOURCES = "xcode/Ext-Safari/Resources"; + +/** + * If not then cd to root dir and returns the path + * @returns {Promise} project root directory + */ +export async function rootDir() { + const root = fileURLToPath(new URL("..", import.meta.url)); + if (cwd() !== (await realpath(root))) { + chdir(root); + console.info("cd:", root); + } + return root; +} + +/** + * Empty the build directory safely + * @param {string} dir + * @returns {Promise} + */ +export async function emptyBuildDir(dir) { + const buildPaths = ["dist", SAFARI_APP_RESOURCES, SAFARI_EXT_RESOURCES]; + if (!buildPaths.includes(dir)) { + console.error("Non-build path, cannot be empty."); + return false; + } + const root = await rootDir(); + try { + for (const sub of await readdir(dir)) { + const path = `${root}/${dir}/${sub}`; + // console.log("rm:", path); // DEBUG + await rm(path, { force: true, recursive: true }); + } + return true; + } catch (error) { + console.error("emptyBuildDir:", error); + return false; + } +} + +/** + * Copy a file or folder recursively + * @param {string} src Source file or directory + * @param {string} dest Destination file or directory + */ +export async function cp(src, dest) { + // console.log("cp:", src, "->", dest); // DEBUG + await rootDir(); + const srcStat = await stat(src); + if (srcStat.isFile()) return copyFile(src, dest); + if (!srcStat.isDirectory()) return; + await mkdir(dest, { recursive: true }); + for (const sub of await readdir(src)) { + if ([".DS_Store"].includes(sub)) continue; + await cp(`${src}/${sub}`, `${dest}/${sub}`); + } +} + +/** + * Read file and return text + * @param {string} file file path + * @returns {Promise} file content + */ +export async function read(file) { + const path = fileURLToPath(new URL(file, import.meta.url)); + return readFile(path, "utf8"); +} + +/** + * @see {@link https://vitejs.dev/config/server-options.html#server-https} + * @see {@link https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener} + * @returns {Promise} https.ServerOptions + */ +export const sharedServerOptions = async () => ({ + ca: await read("./local/ca.pem"), + key: await read("./local/key.pem"), + cert: await read("./local/cert.pem"), +}); diff --git a/src/ext/action-popup/main.js b/src/ext/action-popup/main.js index ecf31c3f..2829a2c0 100644 --- a/src/ext/action-popup/main.js +++ b/src/ext/action-popup/main.js @@ -8,11 +8,12 @@ if (import.meta.env.MODE === "development") { const modules = import.meta.glob("../shared/dev.js", { eager: true }); const browser = modules["../shared/dev.js"]["browser"]; console.debug("DEV-ENV", import.meta.env, modules, browser); - // assign to window simulation WebExtension APIs - window.browser = browser; - // macos popup simulation - const style = document.createElement("style"); - style.textContent = ` + if (!window?.browser?.extension) { + // assign to window simulation WebExtension APIs + window.browser = browser; + // macos popup simulation + const style = document.createElement("style"); + style.textContent = ` body { top: 20px; left: 20px; @@ -32,7 +33,8 @@ body:before { border-radius: 9px; } `; - browser.platform === "macos" && document.head.append(style); + browser.platform === "macos" && document.head.append(style); + } } const app = new App({ diff --git a/src/ext/extension-page/main.js b/src/ext/extension-page/main.js index 9e90a4c7..ec2580e9 100644 --- a/src/ext/extension-page/main.js +++ b/src/ext/extension-page/main.js @@ -8,8 +8,10 @@ if (import.meta.env.MODE === "development") { const modules = import.meta.glob("../shared/dev.js", { eager: true }); const browser = modules["../shared/dev.js"]["browser"]; console.debug("DEV-ENV", import.meta.env, modules, browser); - // assign to window simulation WebExtension APIs - window.browser = browser; + if (!window?.browser?.extension) { + // assign to window simulation WebExtension APIs + window.browser = browser; + } } const app = new App({ diff --git a/src/ext/shared/dev.js b/src/ext/shared/dev.js index cfde2634..6d9a754c 100644 --- a/src/ext/shared/dev.js +++ b/src/ext/shared/dev.js @@ -470,9 +470,9 @@ const _browser = { new Promise((resolve) => { setTimeout(() => resolve(), _browser.delay); }), - onChanged: { - addListener: () => undefined, - }, + }, + onChanged: { + addListener: () => undefined, }, }, }; From 6e80a846706059a3d3b2fc3b88262d219f5b42f0 Mon Sep 17 00:00:00 2001 From: ACTCD <101378590+ACTCD@users.noreply.github.com> Date: Tue, 28 Nov 2023 05:44:44 +0800 Subject: [PATCH 4/7] refactor(dev): add xcode config and organize schemes Create a new configuration to correspond to the new remote real-time development build. --- xcode/App-Shared/ViewController.swift | 1 + xcode/Userscripts.xcodeproj/project.pbxproj | 71 ++++++++++++++--- ...tension.xcscheme => Mac-Vite-Dev.xcscheme} | 76 +++++------------- .../{Userscripts.xcscheme => Mac.xcscheme} | 22 ++---- .../xcschemes/iOS-Vite-Dev.xcscheme | 77 +++++++++++++++++++ .../xcshareddata/xcschemes/iOS.xcscheme | 77 +++++++++++++++++++ xcode/xcconfig/Mac-App.xcconfig | 2 + xcode/xcconfig/Mac-Safari-Extension.xcconfig | 7 +- xcode/xcconfig/Safari-Extension.xcconfig | 5 ++ xcode/xcconfig/Userscripts-Base.xcconfig | 1 + xcode/xcconfig/Userscripts-Release.xcconfig | 2 + xcode/xcconfig/Userscripts-Vite.xcconfig | 24 ++++++ xcode/xcconfig/iOS-App.xcconfig | 1 + xcode/xcconfig/iOS-Safari-Extension.xcconfig | 7 +- 14 files changed, 282 insertions(+), 91 deletions(-) rename xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/{Userscripts Extension.xcscheme => Mac-Vite-Dev.xcscheme} (53%) rename xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/{Userscripts.xcscheme => Mac.xcscheme} (83%) create mode 100644 xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/iOS-Vite-Dev.xcscheme create mode 100644 xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/iOS.xcscheme create mode 100644 xcode/xcconfig/Safari-Extension.xcconfig create mode 100644 xcode/xcconfig/Userscripts-Vite.xcconfig diff --git a/xcode/App-Shared/ViewController.swift b/xcode/App-Shared/ViewController.swift index df9befb9..a4dc6e4c 100644 --- a/xcode/App-Shared/ViewController.swift +++ b/xcode/App-Shared/ViewController.swift @@ -24,6 +24,7 @@ class ViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHan // https://developer.apple.com/documentation/webkit/wkwebview/4111163-inspectable/ self.webView.isInspectable = true } + logger?.debug("\(#function, privacy: .public) - DEBUG mode: isInspectable = true") #endif view = webView self.webView.scrollView.isScrollEnabled = false diff --git a/xcode/Userscripts.xcodeproj/project.pbxproj b/xcode/Userscripts.xcodeproj/project.pbxproj index aca26fad..5b6feb25 100644 --- a/xcode/Userscripts.xcodeproj/project.pbxproj +++ b/xcode/Userscripts.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -106,7 +106,7 @@ 033661A429510B7900CFE179 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/View.storyboard; sourceTree = ""; }; 039F59522AD9591C002E9977 /* dist */ = {isa = PBXFileReference; lastKnownFileType = folder; path = dist; sourceTree = ""; }; 039F59552ADA2FE2002E9977 /* USchemeHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = USchemeHandler.swift; sourceTree = ""; }; - 039F595A2ADFB312002E9977 /* ext-v5-manifest.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "ext-v5-manifest.json"; sourceTree = ""; }; + 039F59662B03AE5A002E9977 /* Userscripts-Vite.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Userscripts-Vite.xcconfig"; sourceTree = ""; }; 03C24F962ABD2CBB00F130F9 /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = ""; }; 03E20D05291E170000B4F692 /* dist */ = {isa = PBXFileReference; lastKnownFileType = folder; path = dist; sourceTree = ""; }; 4A143AA9279DE6FF0029BFD0 /* Mac-Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Mac-Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -134,7 +134,7 @@ 4A57BA07227235CE008A9763 /* SafariWebExtensionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariWebExtensionHandler.swift; sourceTree = ""; }; 4A57BA0E227235CE008A9763 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4A57BA1D227235E6008A9763 /* Mac.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Mac.entitlements; sourceTree = ""; }; - 4AD66D2026826D8100B004E8 /* ext-v4-manifest.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "ext-v4-manifest.json"; sourceTree = ""; }; + 4AD66D2026826D8100B004E8 /* manifest.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = manifest.json; sourceTree = ""; }; 4AED6491268CDB58001794BF /* Functions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Functions.swift; sourceTree = ""; }; 78391D4629A4CB3C00979E34 /* Userscripts-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Userscripts-Debug.xcconfig"; sourceTree = ""; }; 78391D4729A4CB3C00979E34 /* Userscripts-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Userscripts-Release.xcconfig"; sourceTree = ""; }; @@ -288,8 +288,7 @@ 4A36A617268266B30018536B /* _locales */, 4A36A616268266B30018536B /* images */, 03E20D05291E170000B4F692 /* dist */, - 4AD66D2026826D8100B004E8 /* ext-v4-manifest.json */, - 039F595A2ADFB312002E9977 /* ext-v5-manifest.json */, + 4AD66D2026826D8100B004E8 /* manifest.json */, ); path = Resources; sourceTree = ""; @@ -297,6 +296,7 @@ 7878ED2E299BBEBF00E36A24 /* xcconfig */ = { isa = PBXGroup; children = ( + 039F59662B03AE5A002E9977 /* Userscripts-Vite.xcconfig */, 78391D4629A4CB3C00979E34 /* Userscripts-Debug.xcconfig */, 78391D4729A4CB3C00979E34 /* Userscripts-Release.xcconfig */, 7878ED38299BBEBF00E36A24 /* Mac-App.xcconfig */, @@ -419,6 +419,7 @@ 4A57B9E4227235CD008A9763 /* Project object */ = { isa = PBXProject; attributes = { + BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 1320; LastUpgradeCheck = 1420; ORGANIZATIONNAME = "Justin Wasack"; @@ -705,6 +706,48 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 039F59602B03A48A002E9977 /* Vite */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 039F59662B03AE5A002E9977 /* Userscripts-Vite.xcconfig */; + buildSettings = { + }; + name = Vite; + }; + 039F59612B03A48A002E9977 /* Vite */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7878ED38299BBEBF00E36A24 /* Mac-App.xcconfig */; + buildSettings = { + }; + name = Vite; + }; + 039F59622B03A48A002E9977 /* Vite */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7878ED32299BBEBF00E36A24 /* Mac-Safari-Extension.xcconfig */; + buildSettings = { + }; + name = Vite; + }; + 039F59632B03A48A002E9977 /* Vite */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7878ED34299BBEBF00E36A24 /* iOS-App.xcconfig */; + buildSettings = { + }; + name = Vite; + }; + 039F59642B03A48A002E9977 /* Vite */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7878ED2F299BBEBF00E36A24 /* iOS-Safari-Extension.xcconfig */; + buildSettings = { + }; + name = Vite; + }; + 039F59652B03A48A002E9977 /* Vite */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7878ED31299BBEBF00E36A24 /* Mac-Tests.xcconfig */; + buildSettings = { + }; + name = Vite; + }; 4A143AAF279DE6FF0029BFD0 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7878ED31299BBEBF00E36A24 /* Mac-Tests.xcconfig */; @@ -795,56 +838,62 @@ 4A143AB1279DE6FF0029BFD0 /* Build configuration list for PBXNativeTarget "Mac-Tests" */ = { isa = XCConfigurationList; buildConfigurations = ( + 039F59652B03A48A002E9977 /* Vite */, 4A143AAF279DE6FF0029BFD0 /* Debug */, 4A143AB0279DE6FF0029BFD0 /* Release */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; + defaultConfigurationName = Debug; }; 4A4CF716270A38BF00111584 /* Build configuration list for PBXNativeTarget "iOS-Safari-Extension" */ = { isa = XCConfigurationList; buildConfigurations = ( + 039F59642B03A48A002E9977 /* Vite */, 4A4CF714270A38BF00111584 /* Debug */, 4A4CF715270A38BF00111584 /* Release */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; + defaultConfigurationName = Debug; }; 4A4CF717270A38BF00111584 /* Build configuration list for PBXNativeTarget "iOS-App" */ = { isa = XCConfigurationList; buildConfigurations = ( + 039F59632B03A48A002E9977 /* Vite */, 4A4CF711270A38BF00111584 /* Debug */, 4A4CF712270A38BF00111584 /* Release */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; + defaultConfigurationName = Debug; }; 4A57B9E7227235CD008A9763 /* Build configuration list for PBXProject "Userscripts" */ = { isa = XCConfigurationList; buildConfigurations = ( + 039F59602B03A48A002E9977 /* Vite */, 4A57BA14227235CE008A9763 /* Debug */, 4A57BA15227235CE008A9763 /* Release */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; + defaultConfigurationName = Debug; }; 4A57BA16227235CE008A9763 /* Build configuration list for PBXNativeTarget "Mac-Safari-Extension" */ = { isa = XCConfigurationList; buildConfigurations = ( + 039F59622B03A48A002E9977 /* Vite */, 4A57BA17227235CE008A9763 /* Debug */, 4A57BA18227235CE008A9763 /* Release */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; + defaultConfigurationName = Debug; }; 4A57BA1A227235CE008A9763 /* Build configuration list for PBXNativeTarget "Mac-App" */ = { isa = XCConfigurationList; buildConfigurations = ( + 039F59612B03A48A002E9977 /* Vite */, 4A57BA1B227235CE008A9763 /* Debug */, 4A57BA1C227235CE008A9763 /* Release */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; + defaultConfigurationName = Debug; }; /* End XCConfigurationList section */ }; diff --git a/xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/Userscripts Extension.xcscheme b/xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/Mac-Vite-Dev.xcscheme similarity index 53% rename from xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/Userscripts Extension.xcscheme rename to xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/Mac-Vite-Dev.xcscheme index bf2b16e1..0a3c056b 100644 --- a/xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/Userscripts Extension.xcscheme +++ b/xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/Mac-Vite-Dev.xcscheme @@ -1,26 +1,11 @@ + LastUpgradeVersion = "1500" + version = "1.7"> - - - - @@ -38,19 +23,11 @@ - - - - + shouldUseLaunchSchemeArgsEnv = "YES" + shouldAutocreateTestPlan = "YES"> @@ -65,63 +42,48 @@ - - - + allowLocationSimulation = "YES"> + - - - - - + + debugDocumentVersioning = "YES"> + buildConfiguration = "Vite"> diff --git a/xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/Userscripts.xcscheme b/xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/Mac.xcscheme similarity index 83% rename from xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/Userscripts.xcscheme rename to xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/Mac.xcscheme index e3d1c38e..d78f492e 100644 --- a/xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/Userscripts.xcscheme +++ b/xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/Mac.xcscheme @@ -1,7 +1,7 @@ + LastUpgradeVersion = "1500" + version = "1.7"> @@ -15,7 +15,7 @@ @@ -26,16 +26,8 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES"> - - - - + shouldUseLaunchSchemeArgsEnv = "YES" + shouldAutocreateTestPlan = "YES"> @@ -64,7 +56,7 @@ @@ -81,7 +73,7 @@ diff --git a/xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/iOS-Vite-Dev.xcscheme b/xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/iOS-Vite-Dev.xcscheme new file mode 100644 index 00000000..c87e739c --- /dev/null +++ b/xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/iOS-Vite-Dev.xcscheme @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/iOS.xcscheme b/xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/iOS.xcscheme new file mode 100644 index 00000000..9c0ceed5 --- /dev/null +++ b/xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/iOS.xcscheme @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xcode/xcconfig/Mac-App.xcconfig b/xcode/xcconfig/Mac-App.xcconfig index d477275f..7734d6a3 100644 --- a/xcode/xcconfig/Mac-App.xcconfig +++ b/xcode/xcconfig/Mac-App.xcconfig @@ -9,11 +9,13 @@ GENERATE_INFOPLIST_FILE = YES INFOPLIST_FILE = $(SRC_DIR)/Info.plist INFOPLIST_KEY_CFBundleDisplayName = $(PROJECT_NAME)-$(TARGET_NAME) INFOPLIST_KEY_CFBundleDisplayName[config=Debug] = $(PROJECT_NAME)-$(TARGET_NAME)-Debug +INFOPLIST_KEY_CFBundleDisplayName[config=Vite] = $(PROJECT_NAME)-$(TARGET_NAME)-Vite LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks MARKETING_VERSION = $(MAC_APP_VERSION) PRODUCT_BUNDLE_IDENTIFIER = $(APP_IDENTIFIER) PRODUCT_NAME = $(PROJECT_NAME) PRODUCT_NAME[config=Debug] = $(PROJECT_NAME)-Debug +PRODUCT_NAME[config=Vite] = $(PROJECT_NAME)-Vite // Override this file #include? "Mac-App.dev.xcconfig" diff --git a/xcode/xcconfig/Mac-Safari-Extension.xcconfig b/xcode/xcconfig/Mac-Safari-Extension.xcconfig index 6e392d8a..74251cf9 100644 --- a/xcode/xcconfig/Mac-Safari-Extension.xcconfig +++ b/xcode/xcconfig/Mac-Safari-Extension.xcconfig @@ -1,4 +1,6 @@ -SRC_DIR = Ext-Safari +// Shared config file +#include? "Safari-Extension.xcconfig" + CODE_SIGN_ENTITLEMENTS = $(SRC_DIR)/Mac.entitlements CURRENT_PROJECT_VERSION = $(MAC_APP_BUILD) ENABLE_HARDENED_RUNTIME = YES @@ -11,9 +13,6 @@ MARKETING_VERSION = $(MAC_APP_VERSION) PRODUCT_BUNDLE_IDENTIFIER = $(EXT_IDENTIFIER) PRODUCT_NAME = $(PROJECT_NAME)-$(TARGET_NAME) SKIP_INSTALL = YES -MANIFEST_FILE = $(SRC_DIR)/Resources/ext-v4-manifest.json -MANIFEST_NAME = $(PROJECT_NAME) -MANIFEST_NAME[config=Debug] = $(PROJECT_NAME)-Debug // Override this file #include? "Mac-Safari-Extension.dev.xcconfig" diff --git a/xcode/xcconfig/Safari-Extension.xcconfig b/xcode/xcconfig/Safari-Extension.xcconfig new file mode 100644 index 00000000..d2724321 --- /dev/null +++ b/xcode/xcconfig/Safari-Extension.xcconfig @@ -0,0 +1,5 @@ +SRC_DIR = Ext-Safari +MANIFEST_FILE = $(SRC_DIR)/Resources/manifest.json +MANIFEST_NAME = $(PROJECT_NAME) +MANIFEST_NAME[config=Debug] = $(PROJECT_NAME)-Debug +MANIFEST_NAME[config=Vite] = $(PROJECT_NAME)-Vite \ No newline at end of file diff --git a/xcode/xcconfig/Userscripts-Base.xcconfig b/xcode/xcconfig/Userscripts-Base.xcconfig index 4113b7fa..6ad773d0 100644 --- a/xcode/xcconfig/Userscripts-Base.xcconfig +++ b/xcode/xcconfig/Userscripts-Base.xcconfig @@ -55,6 +55,7 @@ MTL_FAST_MATH = YES ONLY_ACTIVE_ARCH[config=Debug] = YES SDKROOT = macosx SWIFT_ACTIVE_COMPILATION_CONDITIONS[config=Debug] = DEBUG +SWIFT_ACTIVE_COMPILATION_CONDITIONS[config=Vite] = DEBUG SWIFT_COMPILATION_MODE[config=Release] = wholemodule SWIFT_OPTIMIZATION_LEVEL[config=Debug] = -Onone SWIFT_OPTIMIZATION_LEVEL[config=Release] = -O diff --git a/xcode/xcconfig/Userscripts-Release.xcconfig b/xcode/xcconfig/Userscripts-Release.xcconfig index 5bfbafca..94cb3265 100644 --- a/xcode/xcconfig/Userscripts-Release.xcconfig +++ b/xcode/xcconfig/Userscripts-Release.xcconfig @@ -6,6 +6,8 @@ IOS_APP_VERSION = 1.5.0 MAC_APP_BUILD = 83 MAC_APP_VERSION = 4.5.0 +// Development +CODE_SIGN_IDENTITY = Apple Development // Developer Team ID DEVELOPMENT_TEAM = J74Q8V8V8N // Organization Identifier diff --git a/xcode/xcconfig/Userscripts-Vite.xcconfig b/xcode/xcconfig/Userscripts-Vite.xcconfig new file mode 100644 index 00000000..1635bab4 --- /dev/null +++ b/xcode/xcconfig/Userscripts-Vite.xcconfig @@ -0,0 +1,24 @@ +#include "Userscripts-Base.xcconfig" + +INFOPLIST_KEY_NSHumanReadableCopyright = Copyright © Userscripts +IOS_APP_BUILD = 2 +IOS_APP_VERSION = 2.0.0 +MAC_APP_BUILD = 5 +MAC_APP_VERSION = 5.0.0 + +// Sign to Run Locally +CODE_SIGN_IDENTITY = - +// Organization Identifier +ORG_IDENTIFIER = dev.vite +// Application Identifier +APP_IDENTIFIER = $(ORG_IDENTIFIER).userscripts +// Safari Extension Identifier +EXT_IDENTIFIER = $(APP_IDENTIFIER).ext.safari +// App Groups and Group Containers +IOS_SHARED_GID = group.$(ORG_IDENTIFIER).userscripts +MAC_SHARED_GID = 00000.$(ORG_IDENTIFIER).userscripts +// App URL Scheme +APP_URL_SCHEME = userscripts-vite + +// Override this file +#include? "Userscripts-Vite.dev.xcconfig" diff --git a/xcode/xcconfig/iOS-App.xcconfig b/xcode/xcconfig/iOS-App.xcconfig index 005ffcaf..b1e738bb 100644 --- a/xcode/xcconfig/iOS-App.xcconfig +++ b/xcode/xcconfig/iOS-App.xcconfig @@ -8,6 +8,7 @@ GENERATE_INFOPLIST_FILE = YES INFOPLIST_FILE = $(SRC_DIR)/Info.plist INFOPLIST_KEY_CFBundleDisplayName = $(PROJECT_NAME) INFOPLIST_KEY_CFBundleDisplayName[config=Debug] = $(PROJECT_NAME)-D +INFOPLIST_KEY_CFBundleDisplayName[config=Vite] = $(PROJECT_NAME)-V INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen INFOPLIST_KEY_UIMainStoryboardFile = Main diff --git a/xcode/xcconfig/iOS-Safari-Extension.xcconfig b/xcode/xcconfig/iOS-Safari-Extension.xcconfig index 7df9eae4..f45ffdb6 100644 --- a/xcode/xcconfig/iOS-Safari-Extension.xcconfig +++ b/xcode/xcconfig/iOS-Safari-Extension.xcconfig @@ -1,4 +1,6 @@ -SRC_DIR = Ext-Safari +// Shared config file +#include? "Safari-Extension.xcconfig" + CODE_SIGN_ENTITLEMENTS = $(SRC_DIR)/iOS.entitlements CURRENT_PROJECT_VERSION = $(IOS_APP_BUILD) GENERATE_INFOPLIST_FILE = YES @@ -15,9 +17,6 @@ SKIP_INSTALL = YES SWIFT_EMIT_LOC_STRINGS = YES TARGETED_DEVICE_FAMILY = 1,2 VALIDATE_PRODUCT[config=Release] = YES -MANIFEST_FILE = $(SRC_DIR)/Resources/ext-v4-manifest.json -MANIFEST_NAME = $(PROJECT_NAME) -MANIFEST_NAME[config=Debug] = $(PROJECT_NAME)-Debug // Override this file #include? "iOS-Safari-Extension.dev.xcconfig" From c963dc17824658b27cfe65bf16560e916e59c225 Mon Sep 17 00:00:00 2001 From: ACTCD <101378590+ACTCD@users.noreply.github.com> Date: Wed, 29 Nov 2023 09:40:07 +0800 Subject: [PATCH 5/7] refactor(docs): update docs and tasks --- .vscode/tasks.json | 69 ++++++++++++++++++++++++++++++++++++++++------ docs/dev.md | 11 ++++---- eslint.config.js | 26 ++++++++++------- 3 files changed, 83 insertions(+), 23 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 9d6aec0f..c967bcab 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -23,33 +23,86 @@ } }, { - "label": "npm: build", + "label": "npm: dev ext-safari-mac", + "detail": "Run dev server and build dev resource to xcode dist", + "type": "shell", + "command": "npm run dev:ext-safari-mac", + "group": "build", + "options": { + "cwd": "./" + } + }, + { + "label": "npm: dev ext-safari-ios", + "detail": "Run dev server and build dev resource to xcode dist", + "type": "shell", + "command": "npm run dev:ext-safari-ios", + "group": "build", + "options": { + "cwd": "./" + } + }, + { + "label": "npm: build mac", "detail": "Build to xcode dist path", "type": "shell", - "command": "npm run build", + "command": "npm run build:mac", "group": "build", "options": { "cwd": "./" } }, { - "label": "xcode: build", - "detail": "xcodebuild", + "label": "npm: build ios", + "detail": "Build to xcode dist path", "type": "shell", - "command": "xcodebuild -scheme Userscripts build", + "command": "npm run build:ios", + "group": "build", + "options": { + "cwd": "./" + } + }, + { + "label": "xcodebuild: mac-debug", + "detail": "xcodebuild mac debug", + "type": "shell", + "command": "xcodebuild -scheme Mac -configuration Debug", + "group": "build", + "options": { + "cwd": "./xcode/" + } + }, + { + "label": "xcodebuild: mac-vite", + "detail": "xcodebuild mac vite", + "type": "shell", + "command": "xcodebuild -scheme Mac-Vite-Dev -configuration Vite", "group": "build", "options": { "cwd": "./xcode/" } }, { - "label": "build all", - "detail": "npm build + xcodebuild", + "label": "dev: ext-safari-mac", + "detail": "npm: dev ext-safari-mac + xcodebuild: mac-vite", + "presentation": { + "reveal": "silent" + }, + "dependsOrder": "sequence", + "dependsOn": ["npm: dev ext-safari-mac", "xcodebuild: mac-vite"], + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "label": "build: mac debug", + "detail": "npm: build mac + xcodebuild: mac-debug", "presentation": { "reveal": "silent" }, "dependsOrder": "sequence", - "dependsOn": ["npm: build", "xcode: build"], + "dependsOn": ["npm: build mac", "xcodebuild: mac-debug"], "group": { "kind": "build", "isDefault": true diff --git a/docs/dev.md b/docs/dev.md index d1e7a7da..38ba3a6e 100644 --- a/docs/dev.md +++ b/docs/dev.md @@ -25,17 +25,18 @@ Reviewing the template will help you understand the composition of the project. # Dev -- `npm install`[^1] -- `npm run dev`[^1] +- `npm install` [^1] +- `npm run dev` [^1] # Build -- `npm run build`[^1] +- `npm run build:mac` [^1][^2] - `cd ./xcode` -- `xcodebuild`[^1][^2] or build with `Xcode` App +- `xcodebuild -scheme Mac` [^1][^2][^3] or build with `Xcode` App [^1]: These commands can also be executed directly through the vscode tasks. Please refer to: [/.vscode/tasks.json](../.vscode/tasks.json) -[^2]: Local setup may be required. Please refer to: [Building from the Command Line with Xcode FAQ](https://developer.apple.com/library/archive/technotes/tn2339/_index.html) +[^2]: Select the corresponding target and platform to build. Please refer to: [/package.json](../package.json) and [xcode-schemes](/xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/) +[^3]: Local setup may be required. Please refer to: [Building from the Command Line with Xcode FAQ](https://developer.apple.com/library/archive/technotes/tn2339/_index.html) # Xcode diff --git a/eslint.config.js b/eslint.config.js index 5b5fa18f..8bf9c246 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -14,13 +14,17 @@ import prettier from "eslint-config-prettier"; import globals from "globals"; export default [ - // https://eslint.org/docs/latest/use/configure/configuration-files-new#using-predefined-configurations - // https://github.com/eslint/eslint/tree/main/packages/js + /** + * @see {@link https://eslint.org/docs/latest/use/configure/configuration-files-new#using-predefined-configurations} + * @see {@link https://github.com/eslint/eslint/tree/main/packages/js} + */ js.configs.recommended, - // https://github.com/sveltejs/eslint-plugin-svelte - // currently no official svelte/recommended flat config - // flatten and call it through a custom config object + /** + * @see {@link https://github.com/sveltejs/eslint-plugin-svelte} + * currently no official svelte/recommended flat config + * flatten and call it through a custom config object + */ { files: ["**/*.svelte"], languageOptions: { @@ -36,18 +40,20 @@ export default [ }, }, - // https://github.com/prettier/eslint-config-prettier - // turns off the conflict rules, put it last + /** + * @see {@link https://github.com/prettier/eslint-config-prettier} + * turns off the conflict rules, put it last + */ prettier, - // custom config objects + /** custom config objects */ - // https://eslint.org/docs/latest/use/configure/configuration-files-new#globally-ignoring-files-with-ignores + /** @see {@link https://eslint.org/docs/latest/use/configure/configuration-files-new#globally-ignoring-files-with-ignores} */ { ignores: ["**/dist/", "**/build/", "etc/", "xcode/", "public/"], }, - // https://eslint.org/docs/latest/use/configure/migration-guide#configuring-language-options + /** @see {@link https://eslint.org/docs/latest/use/configure/migration-guide#configuring-language-options} */ { files: ["scripts/**/*.js"], languageOptions: { From 97da992d0c6fdff79f343efd5ca2e968a2f0ff8f Mon Sep 17 00:00:00 2001 From: ACTCD <101378590+ACTCD@users.noreply.github.com> Date: Wed, 29 Nov 2023 09:49:53 +0800 Subject: [PATCH 6/7] chore: add `sideEffects` key to help tree-shaking --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index e478e39d..36940a00 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "userscripts", "private": true, "type": "module", + "sideEffects": false, "scripts": { "dev": "vite", "dev:ext-safari-mac": "SAFARI_PLATFORM=mac node scripts/dev-ext-safari.js", From debe1a29b69ca3d7adc6afabd0ae83eb4df0ca93 Mon Sep 17 00:00:00 2001 From: ACTCD <101378590+ACTCD@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:17:05 +0800 Subject: [PATCH 7/7] chore: improve and correct document content --- docs/dev.md | 2 +- vite.config.js | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/dev.md b/docs/dev.md index 38ba3a6e..85633998 100644 --- a/docs/dev.md +++ b/docs/dev.md @@ -35,7 +35,7 @@ Reviewing the template will help you understand the composition of the project. - `xcodebuild -scheme Mac` [^1][^2][^3] or build with `Xcode` App [^1]: These commands can also be executed directly through the vscode tasks. Please refer to: [/.vscode/tasks.json](../.vscode/tasks.json) -[^2]: Select the corresponding target and platform to build. Please refer to: [/package.json](../package.json) and [xcode-schemes](/xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/) +[^2]: Select the corresponding target and platform to build. Please refer to: [/package.json](../package.json) and [xcode-schemes](../xcode/Userscripts.xcodeproj/xcshareddata/xcschemes/) [^3]: Local setup may be required. Please refer to: [Building from the Command Line with Xcode FAQ](https://developer.apple.com/library/archive/technotes/tn2339/_index.html) # Xcode diff --git a/vite.config.js b/vite.config.js index 3d4378f9..f7cf2b45 100644 --- a/vite.config.js +++ b/vite.config.js @@ -5,6 +5,9 @@ import { svelte } from "@sveltejs/vite-plugin-svelte"; * About `inline-svg` * use `?raw` suffix import svg assets as inline * @see {@link https://vitejs.dev/guide/assets.html#importing-asset-as-string} + * Ignore lint errors `{@html}`, since these are deterministic local svg resources, + * there is no risk of Cross-Site Scripting (XSS) attacks and can be safely disabled. + * @see {@link https://sveltejs.github.io/eslint-plugin-svelte/rules/no-at-html-tags/} */ /**