3c57c167f2
导入 SiteForge Factory V5 基线源码: - FastAPI + SQLite + Docker Compose(Web + Worker)架构 - 四套商业主题 × 14 页面模板(1.1.0,含历史版本快照) - 四种建站模式骨架 + 迁移审计 + 发布门禁 - 52 项 pytest 测试 - 补全计划主文档 docs/superpowers/plans/ Co-Authored-By: Claude Code <noreply@anthropic.com>
26 lines
1.1 KiB
Python
26 lines
1.1 KiB
Python
"""Safe per-device block CSS using validated data-block identifiers."""
|
|
import re,json
|
|
|
|
def editor_css(blocks):
|
|
tablet=[];mobile=[]
|
|
for b in blocks:
|
|
uid=b.get('id','')
|
|
if not re.fullmatch('[a-zA-Z0-9_-]{4,50}',uid):continue
|
|
s=b.get('style') or {}
|
|
try:
|
|
tp=min(120,max(0,int(s.get('tablet_padding',50))))
|
|
mp=min(120,max(0,int(s.get('mobile_padding',28))))
|
|
except (TypeError,ValueError):tp,mp=50,28
|
|
tablet.append(f'.sf-section[data-block="{uid}"]{{--sf-pad:{tp}px}}')
|
|
mobile.append(f'.sf-section[data-block="{uid}"]{{--sf-pad:{mp}px}}')
|
|
if s.get('hide_tablet') is True:tablet.append(f'.sf-section[data-block="{uid}"]{{display:none}}')
|
|
if s.get('hide_mobile') is True:mobile.append(f'.sf-section[data-block="{uid}"]{{display:none}}')
|
|
return '@media(max-width:820px){'+''.join(tablet)+'}@media(max-width:540px){'+''.join(mobile)+'}'
|
|
|
|
def site_css(entries):
|
|
items=[]
|
|
for entry in entries:
|
|
meta=json.loads(entry.get('meta_json') or '{}')
|
|
items.extend(meta.get('blocks',[]) if isinstance(meta.get('blocks'),list) else [])
|
|
return editor_css(items)
|