原型(执行会话/目标-…-d85687/ui/mcn-workbench.html) - 功能入口卡改三段纵向(图标/标题/描述各一行),68 → 111.19px,对齐 mcn-work-shop 参考卡(同视口 1249×1277 实测 133px),补 --sh-L1 投影;主因是排布不是字号 - 左侧导航重建:由「纯图标 + 悬停提示」改为 64px 药丸浮栏,图标 24 在上、名字常驻在下 (名字一律 2 字,说明走 data-tip);真值取自 tiaoyue 源站实测 (栏 64/内衬 3/圆角 100/项 56×78/字 12px-500-行高 16) - 密度 A 方案:≤1000 卡最小宽 200→160、≤820 统计条最小宽 132→96 (两处 auto-fit 只在真装不下时才缩)⇒ 768/700/560 三处转绿,其余 10 个视口未动 - 移动档隐藏导航条横向滚动轨(16px 轨道曾吃掉 52px 条高的三成,还白吃 16px 主区) 取证通道 - _tools/cap.py 改为「只连不起」:只连 9223 常驻实例,视口走 Emulation.setDeviceMetricsOverride, 不再自起 headless Chrome(顺带解除 500px 视口下限,390×844 可测) - _tools/check_js.py 新增第 5 道门禁(node --check + 模板内注释反引号扫描) 文档 - 复盘-为什么第一版做得很差.md(新建):13 轮时间轴/四类反作用/三重归因/已修与仍欠 - 3d-审查报告.md:更正 §九 那条假 ✓(把「§5.5 五条逐条过完」记成机核,实际零覆盖, 正是「五道闸门全绿却难看」的开关),补 §十二 功能入口卡高差、§十三 tiaoyue 导航逐条对照 - 3b-实测记录.md/DESIGN.md/3c-GPT 参考版与会诊/布局排版参考 ×2 机制与记忆 - .workbuddy/collab/collabctl.py:off --ws 不再全机扫描(原先一次杀掉他区+看板共 5 个进程) - .workbuddy/memory/:本轮纪律与实测真值 - .gitignore:补排运行时噪音(ui/_scratch/__pycache__/浏览器取证临时目录/*.bak-*/一次性脚本) 闸门:语法全过/骨架八页 39 板块/变异对照 15-15/逐视口 14 绿(500×844 唯一红,缺口待拍板)/命名 2060-0-27
103 lines
4.3 KiB
Python
103 lines
4.3 KiB
Python
#!/usr/bin/env python
|
||
# -*- coding: utf-8 -*-
|
||
"""原型 JS 与模板字面量的**语法门禁**(③段 3b/3d 用,只读原型,⛔ 不写盘)。
|
||
|
||
为什么需要它(不是"为了严谨",是同一个坑踩了 **4 次**的真实事故):
|
||
原型是单文件自包含,页面结构写在一堆 JS **模板字面量**里(反引号包起来的字符串)。
|
||
只要在模板里的 **HTML 注释**(`<!-- ... -->`)中写出一个反引号,模板字面量就会被提前闭合,
|
||
而后面那段被当成 JS 代码解析 —— 症状是**页面静默坏掉**(白屏 / `xxx is not defined` /
|
||
`Unexpected identifier`),而 `node --check 整份 html` 是**报不出来**的(html 不是 js),
|
||
于是它一路混到浏览器里才炸。
|
||
|
||
已经踩到的 4 次(每次都是「HTML 注释里带反引号」):
|
||
1. P1 的 `.grid.cols2` 注释 → 页面白屏
|
||
2. P2 的 `.home-stats` / `.stat-item` 注释 → `stats is not defined`,自检没跑完
|
||
3. P2 的 `.grid-cards` / `font-size` 注释 → `Unexpected identifier 'style'`
|
||
4. P1 的 `.qa-block` / `.func-card .qa{...}` 注释 → `Unexpected token '{'`
|
||
|
||
本脚本查两件事:
|
||
① **语法**:把 `<script>` 段抠出来交给 `node --check`(⛔ 不是查整份 html)。
|
||
② **模板里的反引号**:多行扫描 script 区内的每个 `<!-- ... -->` 块,块内出现反引号即报红。
|
||
⚠️ 必须**多行**扫:反引号常在注释的**续行**上(单行 grep 抓不到)。
|
||
|
||
用法:
|
||
python _tools/check_js.py # 查同目录的 mcn-workbench.html
|
||
python _tools/check_js.py --proto X.html
|
||
退出码:0 = 全过;1 = 有 FAIL。
|
||
"""
|
||
|
||
import argparse
|
||
import io
|
||
import os
|
||
import re
|
||
import subprocess
|
||
import sys
|
||
import tempfile
|
||
|
||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||
DEFAULT_PROTO = os.path.abspath(os.path.join(HERE, '..', 'mcn-workbench.html'))
|
||
NODE = r"E:\ProgramData\.workbuddy\binaries\node\versions\22.22.2-6\node.exe"
|
||
|
||
|
||
def main():
|
||
ap = argparse.ArgumentParser()
|
||
ap.add_argument('--proto', default=DEFAULT_PROTO)
|
||
a = ap.parse_args()
|
||
|
||
src = io.open(a.proto, encoding='utf-8').read()
|
||
fails = []
|
||
|
||
i = src.index('<script>') + len('<script>')
|
||
j = src.rindex('</script>')
|
||
js = src[i:j]
|
||
|
||
# ① 语法:把 script 抠出来给 node --check
|
||
node = NODE if os.path.exists(NODE) else 'node'
|
||
with tempfile.NamedTemporaryFile('w', suffix='.js', delete=False, encoding='utf-8', newline='') as f:
|
||
f.write(js)
|
||
tmp = f.name
|
||
try:
|
||
r = subprocess.run([node, '--check', tmp], capture_output=True)
|
||
if r.returncode == 0:
|
||
print('PASS 语法:<script> 段 ' + str(js.count(chr(10))) + ' 行,node --check 通过')
|
||
else:
|
||
err = r.stderr.decode('utf-8', 'replace').strip().split('\n')
|
||
# 把临时文件里的行号换算回原文件行号
|
||
base = src[:i].count('\n') + 1
|
||
head = [l for l in err if l.strip()][:4]
|
||
fails.append('语法不过:' + ' / '.join(head))
|
||
print('FAIL 语法:node --check 报错(下面的行号是 script 段内的,原文件约 +%d 行)' % base)
|
||
for l in head:
|
||
print(' ' + l)
|
||
finally:
|
||
os.unlink(tmp)
|
||
|
||
# ② 模板里的反引号(多行扫描每个 HTML 注释块)
|
||
bad = []
|
||
for m in re.finditer(r'<!--[\s\S]*?-->', js):
|
||
blk = m.group(0)
|
||
if '`' in blk:
|
||
line = js[:m.start()].count('\n') + src[:i].count('\n') + 2
|
||
first = blk.split('\n')[0][:70]
|
||
n_tick = blk.count('`')
|
||
bad.append('原文件第 %d 行附近:模板里的 HTML 注释含 %d 个反引号 —— 「%s」' % (line, n_tick, first))
|
||
if bad:
|
||
fails.extend(bad)
|
||
print('FAIL 模板里的反引号:')
|
||
for b in bad:
|
||
print(' ' + b)
|
||
else:
|
||
print('PASS 模板里的反引号:script 区内所有 <!-- --> 块(多行扫描)都不含反引号')
|
||
|
||
print()
|
||
if fails:
|
||
print('结论:FAIL %d 项 —— 上面每一条都会让**页面在浏览器里才炸**(node --check 整份 html 看不到)。' % len(fails))
|
||
print('修法:注释里的反引号一律去掉(用 .cls 或 「cls」代替 `.cls`)。')
|
||
return 1
|
||
print('结论:全过。')
|
||
return 0
|
||
|
||
|
||
if __name__ == '__main__':
|
||
sys.exit(main())
|