upgrade: adopt V8.31.1 (theme 1.3/1.4 redesigns, editor deep-canvas, guided launch, component library)

Overlay 190 upstream items (V8.22→8.31) preserving trade-pro theme,
registry tests, and design docs. Re-applied full patch set on identical
anchors (discovery/env_for/blocks.css/type-mapping/locale-override/
theme_color/frontend entries/test_theme_pro_v3 mods) plus compose pins.

Verified: theme suites 35/35; dual-baseline full run 415 passed vs
pristine 386+29 ours, FAILED-set diff EMPTY (same 10 Windows env fails).
Live: container 8.31.1-dev.1 healthy, hesupipe 192 entries intact,
trade-pro build 203 pages 0 errors.

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-10-26 09:43:17 +08:00
parent a63548c645
commit 8884e100f9
647 changed files with 20853 additions and 271 deletions
+4 -28
View File
@@ -544,34 +544,10 @@ def editor_preview(site_id:str,entry_id:str,payload:BlueprintPayload):
html=_re.sub(r'<link\s+rel="stylesheet"[^>]*>', '', html)
html=_re.sub(r'<script\s+defer\s+src="assets/[^"]+"[^>]*></script>', '', html)
html=html.replace('</head>','<style>'+styles+'</style></head>')
bridge = r'''<script>(function(){
const fields={'title':'h1,h2','description':'.sf-hero-copy p,.sf-image-text p'};
const sections=Array.from(document.querySelectorAll('[data-block]'));
sections.forEach(block=>{
block.setAttribute('data-studio-selectable','true');
block.addEventListener('click',event=>{
if(event.target.closest('a'))event.preventDefault();
sections.forEach(item=>item.classList.remove('sf-editor-selected'));
block.classList.add('sf-editor-selected');
parent.postMessage({source:'siteforge-select-block',blockId:block.dataset.block},'*');
});
for(const [field,selector] of Object.entries(fields)){
const target=block.querySelector(selector);if(!target)continue;
target.title='双击直接修改文字';target.addEventListener('dblclick',()=>{
target.contentEditable='plaintext-only';target.focus();
target.style.outline='2px dashed #367bdd';
});
target.addEventListener('blur',()=>{
if(!target.isContentEditable)return;
target.removeAttribute('contenteditable');target.style.outline='';
parent.postMessage({source:'siteforge-inline-editor',blockId:block.dataset.block,field:field,value:target.textContent},'*');
});
}
});
const style=document.createElement('style');
style.textContent='[data-studio-selectable]:hover{outline:2px dashed #e98b45!important;outline-offset:-2px;cursor:pointer}[data-studio-selectable].sf-editor-selected{outline:2px solid #ea8138!important;outline-offset:-2px}';
document.head.appendChild(style);
})()</script>'''
# External trusted bridge is injected only into the sandboxed editor preview;
# production/static builds never include authoring controls.
bridge_source=(ROOT/'app'/'static'/'studio-canvas-bridge.js').read_text(encoding='utf-8')
bridge='<script>'+bridge_source+'</script>'
# The static site's /media/ assets are hosted by the admin at
# /local-media/{site}/. Rewrite only the editor response, never builds.
html=html.replace('src="/media/',f'src="/local-media/{site_id}/')