diff --git a/dist-release/content/index.js b/dist-release/content/index.js index db7cf3a..6d655e1 100644 --- a/dist-release/content/index.js +++ b/dist-release/content/index.js @@ -1354,20 +1354,34 @@ const templateCells = getDirectContentCells(templateColumn); for (let index = 0; index < rowCount; index += 1) { const existingCell = getDirectContentCells(column)[index] ?? null; + const templateCell = templateCells[index] ?? templateCells[templateCells.length - 1] ?? null; if (existingCell) { existingCell.dataset.marketRowCell = field; applyPluginContentCellStyles(existingCell); + syncContentCellHeight(existingCell, templateCell); continue; } - const templateCell = templateCells[index] ?? templateCells[templateCells.length - 1] ?? null; const nextCell = field === SELECTION_COLUMN_KEY ? templateCell ? createSelectionContentCell(templateCell) : createBareContentCell(column.ownerDocument) : templateCell ? cloneElementShallow(templateCell) : createBareContentCell(column.ownerDocument); nextCell.dataset.marketRowCell = field; applyColumnWidth(nextCell, field); applyPluginContentCellStyles(nextCell); + syncContentCellHeight(nextCell, templateCell); nextCell.textContent = ""; column.appendChild(nextCell); } } + function syncContentCellHeight(cell, templateCell) { + if (!templateCell) { + return; + } + const measuredHeight = Math.round(templateCell.getBoundingClientRect().height); + const nextHeight = measuredHeight > 0 ? `${measuredHeight}px` : templateCell.style.height; + if (nextHeight) { + cell.style.height = nextHeight; + } else { + cell.style.removeProperty("height"); + } + } function applyPluginHeaderCellStyles(cell) { cell.style.display = "flex"; cell.style.alignItems = "center"; diff --git a/docs/【给同事】从Git下载使用说明.md b/docs/【给同事】从Git下载使用说明.md index 91d8b4c..ee3279c 100644 --- a/docs/【给同事】从Git下载使用说明.md +++ b/docs/【给同事】从Git下载使用说明.md @@ -69,6 +69,16 @@ git clone https://git.internal.intelligrow.cn/wangshaoqing/star-chart-search-enh --- +## 🆕 最近修复 + +当前版本已修复: + +- 在星图搜索关键词后,左侧插件勾选框和右侧达人行可能逐行错位的问题 + +如果你之前已经装过旧版本,请务必按下面的“后续更新”步骤执行一次更新和重新加载。 + +--- + ## 🔄 后续更新 当我发布新版本时,你只需要: @@ -81,6 +91,21 @@ npm run build:release 然后到 `chrome://extensions` 页面点击插件卡片的 **"重新加载"** 🔄 +推荐完整更新顺序: + +1. 先关闭星图页面标签页 +2. 执行 `git pull` +3. 执行 `npm run build:release` +4. 到 `chrome://extensions` 点击插件卡片的 **"重新加载"** +5. 重新打开星图页面 + +如果你主要使用的是“达人市场”页面,更新后可以这样快速确认修复是否生效: + +1. 打开 `https://xingtu.cn/ad/creator/market` +2. 在搜索框输入关键词,例如 `孕晚期` +3. 向下滚动到达人列表区域 +4. 确认左侧勾选框和右侧达人行保持对齐 + ⚠️ **如果重新加载后还是旧版本**: - 先点击插件卡片的 **"移除"** 删除旧版本 - 然后重新点击 **"加载已解压的扩展程序"** diff --git a/src/content/market/dom-sync.ts b/src/content/market/dom-sync.ts index 9f4494a..cd7c855 100644 --- a/src/content/market/dom-sync.ts +++ b/src/content/market/dom-sync.ts @@ -99,39 +99,10 @@ export interface MarketTableDom { rows: MarketRowDom[]; } -export interface MarketAlignmentDiagnostic { - authorId: string; - authorName: string; - checkboxTop: number; - rowTop: number; - topDelta: number; -} - export function syncMarketTable(root: ParentNode): MarketTableDom | null { return syncSyntheticMarketTable(root) ?? syncDivGridMarketTable(root); } -export function readMarketAlignmentDiagnostics( - table: MarketTableDom -): MarketAlignmentDiagnostic[] { - return table.rows.map((rowDom) => { - const selectionCell = rowDom.selectionCheckbox.parentElement; - const selectionRect = selectionCell?.getBoundingClientRect(); - const rowRect = rowDom.row.getBoundingClientRect(); - - const checkboxTop = selectionRect?.top ?? Number.NaN; - const rowTop = rowRect.top ?? Number.NaN; - - return { - authorId: rowDom.authorId, - authorName: rowDom.authorName, - checkboxTop, - rowTop, - topDelta: checkboxTop - rowTop - }; - }); -} - export function readMarketPageSignature(root: ParentNode): string { const document = getOwnerDocument(root); const explicitPageIndex = diff --git a/src/content/market/index.ts b/src/content/market/index.ts index 252cdad..cbb0340 100644 --- a/src/content/market/index.ts +++ b/src/content/market/index.ts @@ -4,7 +4,6 @@ import { createBatchPayload, type BatchPayload } from "./batch-payload"; import { applyRowOrder, applyRowVisibility, - readMarketAlignmentDiagnostics, readMarketPageSignature, renderMarketRowState, syncPluginSortHeaders, @@ -397,7 +396,6 @@ export function createMarketController(options: CreateMarketControllerOptions) { applyRowOrder(table, records.map((record) => record.authorId)); bindSelectionControls(table); syncMarketSelectionState(table, selectedAuthorIds); - logMarketAlignmentDiagnosticsIfEnabled(options.window, table, "applyCurrentView"); lastKnownPageSignature = readMarketPageSignature(options.document); }); } @@ -664,23 +662,12 @@ export function createMarketController(options: CreateMarketControllerOptions) { } const step = Math.max(scrollContainer.clientHeight, 240); - logMarketScrollTraceIfEnabled(options.window, { - event: "start", - maxScrollTop, - originalScrollTop, - step - }); for ( let nextScrollTop = Math.min(originalScrollTop + step, maxScrollTop); nextScrollTop > originalScrollTop && nextScrollTop <= maxScrollTop; nextScrollTop = Math.min(nextScrollTop + step, maxScrollTop) ) { setScrollTop(scrollContainer, nextScrollTop); - logMarketScrollTraceIfEnabled(options.window, { - event: "step", - nextScrollTop, - scrollTop: scrollContainer.scrollTop - }); hydrationSnapshot = await collectCurrentPageSnapshotsUntilSettled(); if ( hydrationSnapshot.missingDefaultFieldCount === 0 && @@ -696,10 +683,6 @@ export function createMarketController(options: CreateMarketControllerOptions) { if (scrollContainer.scrollTop !== originalScrollTop) { setScrollTop(scrollContainer, originalScrollTop); - logMarketScrollTraceIfEnabled(options.window, { - event: "restore", - restoredScrollTop: scrollContainer.scrollTop - }); } } @@ -1026,45 +1009,6 @@ function setScrollTop(element: HTMLElement, top: number): void { element.dispatchEvent(new Event("scroll")); } -function logMarketAlignmentDiagnosticsIfEnabled( - window: Window, - table: ReturnType, - label: string -): void { - if (!isMarketDebugLoggingEnabled(window) || !table) { - return; - } - - const diagnostics = readMarketAlignmentDiagnostics(table); - console.info(`[SCES debug] ${label} alignment`, diagnostics); -} - -function logMarketScrollTraceIfEnabled( - window: Window, - payload: Record -): void { - if (!isMarketDebugLoggingEnabled(window)) { - return; - } - - console.info("[SCES debug] submit/export scroll", payload); -} - -function isMarketDebugLoggingEnabled(window: Window): boolean { - try { - const searchParams = new URL(window.location.href).searchParams; - if (searchParams.get("scesDebug") === "1") { - return true; - } - } catch {} - - try { - return window.localStorage.getItem("scesDebugMarket") === "1"; - } catch { - return false; - } -} - function readCurrentPageRows(document: Document): MarketRowSnapshot[] { const table = syncMarketTable(document); if (!table) { diff --git a/tests/market-dom-sync.test.ts b/tests/market-dom-sync.test.ts index e700980..5e804ec 100644 --- a/tests/market-dom-sync.test.ts +++ b/tests/market-dom-sync.test.ts @@ -7,7 +7,6 @@ import { applyRowVisibility, findNextPageControl, isPageControlDisabled, - readMarketAlignmentDiagnostics, readMarketPageSignature, renderMarketRowState, syncMarketTable @@ -354,46 +353,6 @@ describe("market-dom-sync", () => { expect(readSelectionCellHeights()).toEqual(["152px", "152px"]); }); - test("reads alignment diagnostics for selection cells against native rows", () => { - document.body.innerHTML = buildRealMarketGridFixture(); - - const table = syncMarketTable(document); - if (!table) { - throw new Error("Expected market table"); - } - - const firstSelectionCell = table.rows[0].selectionCheckbox.parentElement as HTMLElement; - const secondSelectionCell = table.rows[1].selectionCheckbox.parentElement as HTMLElement; - - vi.spyOn(firstSelectionCell, "getBoundingClientRect").mockReturnValue( - createRect({ height: 24, top: 100 }) - ); - vi.spyOn(table.rows[0].row, "getBoundingClientRect").mockReturnValue( - createRect({ height: 120, top: 120 }) - ); - vi.spyOn(secondSelectionCell, "getBoundingClientRect").mockReturnValue( - createRect({ height: 24, top: 260 }) - ); - vi.spyOn(table.rows[1].row, "getBoundingClientRect").mockReturnValue( - createRect({ height: 120, top: 250 }) - ); - - expect(readMarketAlignmentDiagnostics(table)).toEqual([ - expect.objectContaining({ - authorId: "111", - checkboxTop: 100, - rowTop: 120, - topDelta: -20 - }), - expect.objectContaining({ - authorId: "222", - checkboxTop: 260, - rowTop: 250, - topDelta: 10 - }) - ]); - }); - test("uses native-like alignment styles for plugin cells", () => { document.body.innerHTML = buildRealMarketGridFixtureWithScopedAttributes();