diff --git a/.gitignore b/.gitignore index 442afcc..62c1b09 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,14 @@ .old-reference/ dist/ node_modules/ + +# Local debug captures +after-export-requests.txt +before-export-requests.txt +network-after-page2.txt + +# Unrelated local planning artifacts +docs/superpowers/plans/2026-04-25-professional-capability-exam-guide.md +docs/superpowers/specs/2026-04-25-professional-capability-exam-guide-design.md +externaldocs/2026-04-25-专业能力测试冲刺讲义.html +externaldocs/2026-04-25-专业能力测试冲刺讲义.pdf diff --git a/README.md b/README.md index 268eec1..0b86272 100644 --- a/README.md +++ b/README.md @@ -83,3 +83,37 @@ When the market page is opened without a valid auth state, the content script re 6. Apply a threshold filter and confirm the list hides unmatched rows 7. Apply a sort and confirm row order changes 8. Export CSV and confirm the file includes plugin status and after-search-rate fields + +提交的数据格式 +```json +{ + "logtoUserId": "p7pdhhtde8kj", + "creatorName": "王少卿", + "resource": "https://talent-search.intelligrow.cn", + "batchName": "自动验证批次", + "batchId": "p7pdhhtde8kj-<提交当时的 ISO 时间戳>", + "createdAt": "<提交当时的 ISO 时间戳>", + "authors": [ + { "authorId": "7041184989643276324", "authorName": "旖旖小虎🐯" }, + { "authorId": "7021245050621263906", "authorName": "瑶一瑶小肉包" }, + { "authorId": "6629722292110753806", "authorName": "陈翔六点半" }, + { "authorId": "7065613279053217829", "authorName": "小花花的每一天" }, + { "authorId": "7254389871895117885", "authorName": "疯铲姐妹" }, + { "authorId": "7294473194298146854", "authorName": "奇奇de海洋" }, + { "authorId": "6834119701379940360", "authorName": "任志达" }, + { "authorId": "6870159718216630285", "authorName": "大师兄的表哥" }, + { "authorId": "6833914516833566727", "authorName": "旺仔是三七分" }, + { "authorId": "7401565089431552037", "authorName": "笑典动物园" }, + { "authorId": "7120107426002501639", "authorName": "嘻哈不拆" }, + { "authorId": "7015813716650393630", "authorName": "周星伦" }, + { "authorId": "6870170568893661197", "authorName": "周周的周" }, + { "authorId": "6839989503663276045", "authorName": "潇潇学姐" }, + { "authorId": "7023032374749298718", "authorName": "大自然奇观" }, + { "authorId": "6870164079617523719", "authorName": "王小怪" }, + { "authorId": "6969058840033624100", "authorName": "周三拾" }, + { "authorId": "6825383642127138829", "authorName": "罗臣臣" }, + { "authorId": "6684403430837977100", "authorName": "段炼丶Exercise" }, + { "authorId": "7319160797236559882", "authorName": "郑皓文" } + ] + } +``` \ No newline at end of file diff --git a/src/content/market/plugin-toolbar.ts b/src/content/market/plugin-toolbar.ts index 82e8f60..0e1e577 100644 --- a/src/content/market/plugin-toolbar.ts +++ b/src/content/market/plugin-toolbar.ts @@ -17,6 +17,8 @@ export interface PluginToolbarDom { root: HTMLElement; } +const PLUGIN_ACTION_BUTTON_STYLE_ID = "sces-plugin-action-button-style"; + export function isPluginToolbarMounted( root: HTMLElement, document: Document @@ -29,6 +31,8 @@ export function ensurePluginToolbar( document: Document, handlers: PluginToolbarHandlers ): PluginToolbarDom { + ensurePluginActionButtonTheme(document); + const existingRoot = document.querySelector( "[data-plugin-toolbar='root']" ) as HTMLElement | null; @@ -430,7 +434,7 @@ function applyNativeControlStyles( } [controls.exportButton, controls.batchSubmitButton].forEach((button) => { - applyPrimaryButtonStyles(button, Boolean(primaryButton)); + applyPrimaryButtonStyles(button); button.style.whiteSpace = "nowrap"; }); @@ -449,21 +453,18 @@ function applyNativeControlStyles( } function applyPrimaryButtonStyles( - button: HTMLButtonElement, - isUsingNativePrimaryButtonClass: boolean + button: HTMLButtonElement ): void { - if (!isUsingNativePrimaryButtonClass) { - button.style.backgroundColor = "#fe346e"; - button.style.border = "1px solid #fe346e"; - button.style.borderRadius = "8px"; - button.style.color = "#ffffff"; - button.style.height = "32px"; - button.style.padding = "0 15px"; - } else { - button.style.color = "#ffffff"; - } - + button.style.backgroundColor = "#7f1d2d"; + button.style.border = "1px solid #7f1d2d"; + button.style.borderRadius = "8px"; + button.style.color = "#ffffff"; + button.style.height = "32px"; + button.style.padding = "0 15px"; button.style.boxSizing = "border-box"; + button.style.fontWeight = "600"; + button.style.transition = + "background-color 0.16s ease, border-color 0.16s ease, box-shadow 0.16s ease, transform 0.16s ease"; } function applyStatusStyles(statusText: HTMLElement): void { @@ -474,6 +475,47 @@ function applyStatusStyles(statusText: HTMLElement): void { statusText.style.whiteSpace = "nowrap"; } +function ensurePluginActionButtonTheme(document: Document): void { + if (document.getElementById(PLUGIN_ACTION_BUTTON_STYLE_ID)) { + return; + } + + const style = document.createElement("style"); + style.id = PLUGIN_ACTION_BUTTON_STYLE_ID; + style.textContent = ` + [data-plugin-export="button"]:hover:not(:disabled), + [data-plugin-batch-submit="button"]:hover:not(:disabled) { + background-color: #6d1627 !important; + border-color: #6d1627 !important; + } + + [data-plugin-export="button"]:active:not(:disabled), + [data-plugin-batch-submit="button"]:active:not(:disabled) { + background-color: #58111f !important; + border-color: #58111f !important; + transform: translateY(1px); + } + + [data-plugin-export="button"]:focus-visible, + [data-plugin-batch-submit="button"]:focus-visible { + outline: none !important; + box-shadow: 0 0 0 3px rgba(127, 29, 45, 0.2) !important; + } + + [data-plugin-export="button"]:disabled, + [data-plugin-batch-submit="button"]:disabled { + background-color: #c89ca4 !important; + border-color: #c89ca4 !important; + color: rgba(255, 255, 255, 0.95) !important; + cursor: not-allowed !important; + opacity: 1 !important; + transform: none !important; + box-shadow: none !important; + } + `; + document.head.appendChild(style); +} + function normalizeText(value: string | null | undefined): string { return value?.replace(/\s+/g, " ").trim() ?? ""; } diff --git a/tests/market-content-entry.test.ts b/tests/market-content-entry.test.ts index 8aef431..126bc81 100644 --- a/tests/market-content-entry.test.ts +++ b/tests/market-content-entry.test.ts @@ -293,8 +293,8 @@ describe("market-content-entry", () => { const batchSubmitButton = document.querySelector( '[data-plugin-batch-submit="button"]' ) as HTMLButtonElement | null; - expect(exportButton?.style.backgroundColor).toBe("rgb(254, 52, 110)"); - expect(batchSubmitButton?.style.backgroundColor).toBe("rgb(254, 52, 110)"); + expect(exportButton?.style.backgroundColor).toBe("rgb(127, 29, 45)"); + expect(batchSubmitButton?.style.backgroundColor).toBe("rgb(127, 29, 45)"); expect(exportButton?.style.color).toBe("rgb(255, 255, 255)"); expect(batchSubmitButton?.style.color).toBe("rgb(255, 255, 255)"); });