顶栏改为知乎式两行结构:第一行左侧站点 LOGO、右侧当前用户头像, 第二行只保留正文工具条并居中,同时移除「Jio / 写文章」字样。 - bootstrap payload 新增 site/viewer 身份字段(复用 jio_get_site_logo_url 与 jio_get_avatar_url,前端不拼 URL、不做权限判断) - 拆分 draft 类型、TinyMCE 块运行时、顶栏组件,index.tsx 1065 → 735 行 - 清理死代码:未调用的 keepCaretInsideCode、永远无法打开的代码语言弹窗 (setCodeLanguage 只会收到 null,codeTargetRef 从未赋值)及其样式, 以及顶栏移除后失效的 bar-left/brand/mode/save-draft/ghost/primary 规则 - 契约测试、本地预览与截图脚本同步到新 DOM Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
78 lines
2.8 KiB
JavaScript
78 lines
2.8 KiB
JavaScript
/**
|
|
* 截图:打开预览页并保存桌面 / 移动端截图,同时把配色、字体与布局尺寸打印出来。
|
|
*/
|
|
const fs = require('fs');
|
|
const puppeteer = require('puppeteer-core');
|
|
|
|
const CANDIDATES = [
|
|
process.env.JIO_BROWSER,
|
|
'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
|
|
'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
|
|
'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe',
|
|
'C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe',
|
|
].filter(Boolean);
|
|
const BROWSER = CANDIDATES.find((p) => fs.existsSync(p));
|
|
|
|
const URL = process.argv[2] || 'https://localhost/jio-preview.html';
|
|
const PREFIX = process.argv[3] || 'C:/Users/Xing/Desktop/WP-Date/data/wordpress/shot';
|
|
|
|
(async () => {
|
|
if (!BROWSER) {
|
|
console.error('no browser');
|
|
process.exit(1);
|
|
}
|
|
const browser = await puppeteer.launch({
|
|
executablePath: BROWSER,
|
|
headless: 'new',
|
|
ignoreHTTPSErrors: true,
|
|
args: ['--disable-gpu', '--no-sandbox'],
|
|
});
|
|
|
|
for (const [name, viewport] of [
|
|
['desktop', { width: 1440, height: 1000 }],
|
|
['mobile', { width: 390, height: 844, isMobile: true, hasTouch: true }],
|
|
]) {
|
|
const page = await browser.newPage();
|
|
await page.setViewport(viewport);
|
|
await page.goto(URL, { waitUntil: 'networkidle2', timeout: 60000 });
|
|
await new Promise((r) => setTimeout(r, 2000));
|
|
await page.screenshot({ path: `${PREFIX}-${name}.png` });
|
|
|
|
const metrics = await page.evaluate(() => {
|
|
const pick = (sel) => {
|
|
const el = document.querySelector(sel);
|
|
if (!el) return null;
|
|
const cs = getComputedStyle(el);
|
|
const r = el.getBoundingClientRect();
|
|
return {
|
|
text: (el.textContent || '').trim().slice(0, 40),
|
|
font: `${cs.fontSize}/${cs.lineHeight} ${cs.fontFamily.split(',')[0]}`,
|
|
weight: cs.fontWeight,
|
|
color: cs.color,
|
|
bg: cs.backgroundColor,
|
|
pad: cs.padding,
|
|
box: `${Math.round(r.width)}x${Math.round(r.height)}`,
|
|
};
|
|
};
|
|
return {
|
|
masthead: pick('.jio-creator__masthead'),
|
|
brandLogo: pick('.jio-creator__brand-logo'),
|
|
avatar: pick('.jio-creator__me-avatar'),
|
|
bar: pick('.jio-creator__bar'),
|
|
title: pick('.jio-creator__title textarea'),
|
|
settings: pick('.jio-creator__settings'),
|
|
canvas: pick('.jio-creator__canvas'),
|
|
toolbar: pick('.jio-creator__toolbar-tools'),
|
|
editor: pick('.jio-creator__editor .mce-edit-area'),
|
|
publishBtn: pick('.jio-creator__status-primary'),
|
|
pageBg: getComputedStyle(document.body).backgroundColor,
|
|
};
|
|
});
|
|
console.log(`=== ${name} ===`);
|
|
console.log(JSON.stringify(metrics, null, 2));
|
|
await page.close();
|
|
}
|
|
|
|
await browser.close();
|
|
})();
|