upgrade: adopt V8.32.0-dev.1 (theme preview iframe fix, editor simple mode)
Overlay 46 upstream items; full patch set re-applied (all patched files reset by overlay regardless of upstream change status — lesson recorded). Verified: theme suites 35/35; dual-baseline 418 passed vs pristine 389+29 ours, FAILED-set diff EMPTY (same 10 Windows env fails). Live: container 8.32.0-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:
@@ -1,15 +1,50 @@
|
||||
<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>SiteForge · 完整主题预览中心</title>
|
||||
<style>*{box-sizing:border-box}body{margin:0;background:#eef1f5;font:14px/1.6 system-ui,'Microsoft YaHei',sans-serif;color:#172c42}header{display:flex;align-items:center;justify-content:space-between;padding:14px 26px;background:#fff;border-bottom:1px solid #dce3eb;gap:24px;flex-wrap:wrap}header strong{font-size:17px}header strong span{background:#15253e;color:#fff;border-radius:6px;padding:6px 8px;margin-right:8px}header a{color:#255b99;text-decoration:none}.controls{display:flex;align-items:end;flex-wrap:wrap;gap:12px;padding:18px 26px;border-bottom:1px solid #dce3eb;background:white}.controls label{font-weight:700;color:#5c7083;font-size:11px;display:grid;gap:6px}.controls select{border:1px solid #ccd5df;background:#fff;color:#192d41;padding:10px 14px;border-radius:7px;min-width:132px;font-size:13px}.devices{display:flex;gap:4px;margin-left:auto;background:#f0f3f8;border-radius:8px;padding:4px}.devices button{border:0;background:none;padding:9px 14px;border-radius:6px;cursor:pointer;color:#52697e}.devices button.active{background:#1e446c;color:white}.stage{padding:22px 18px 80px;display:flex;justify-content:center;overflow:auto}.frame{width:100%;height:calc(100vh - 210px);min-height:520px;background:white;box-shadow:0 16px 50px #12304720;border-radius:10px;overflow:hidden;transition:width .25s}.frame iframe{border:0;width:100%;height:100%;background:white}.help{text-align:center;color:#6d8296;font-size:12px;margin:-55px auto 28px}.error{color:#c14f45;display:none}@media(max-width:700px){header,.controls{padding:12px}header strong{font-size:14px}.devices{margin-left:0}.frame{min-height:450px}}</style><link rel="stylesheet" href="/ui/professional-ui.css"><script defer src="/ui/professional-ui.js"></script></head>
|
||||
<style>*{box-sizing:border-box}body{margin:0;background:#eef1f5;font:14px/1.6 system-ui,'Microsoft YaHei',sans-serif;color:#172c42}header{display:flex;align-items:center;justify-content:space-between;padding:14px 26px;background:#fff;border-bottom:1px solid #dce3eb;gap:24px;flex-wrap:wrap}header strong{font-size:17px}header strong span{background:#15253e;color:#fff;border-radius:6px;padding:6px 8px;margin-right:8px}header a{color:#255b99;text-decoration:none}.controls{display:flex;align-items:end;flex-wrap:wrap;gap:12px;padding:18px 26px;border-bottom:1px solid #dce3eb;background:white}.controls label{font-weight:700;color:#5c7083;font-size:11px;display:grid;gap:6px}.controls select{border:1px solid #ccd5df;background:#fff;color:#192d41;padding:10px 14px;border-radius:7px;min-width:132px;font-size:13px}.devices{display:flex;gap:4px;margin-left:auto;background:#f0f3f8;border-radius:8px;padding:4px}.devices button{border:0;background:none;padding:9px 14px;border-radius:6px;cursor:pointer;color:#52697e}.devices button.active{background:#1e446c;color:white}.stage{padding:22px 18px 80px;display:flex;justify-content:center;overflow:auto}.frame{width:100%;height:calc(100vh - 210px);min-height:520px;background:white;box-shadow:0 16px 50px #12304720;border-radius:10px;overflow:hidden;transition:width .25s}.frame iframe{border:0;width:100%;height:100%;background:white}.help{text-align:center;color:#6d8296;font-size:12px;margin:-55px auto 28px}.sf-preview-status{font-size:12px;color:#566d83;max-width:350px}.sf-preview-status.error{color:#aa3434}.sf-preview-retry{padding:8px 12px;border:1px solid #cbd7e4;border-radius:7px;background:white;color:#28547f;cursor:pointer;text-decoration:none;font-size:12px}@media(max-width:700px){header,.controls{padding:12px}header strong{font-size:14px}.devices{margin-left:0}.frame{min-height:450px}}</style><link rel="stylesheet" href="/ui/professional-ui.css"><script defer src="/ui/professional-ui.js"></script></head>
|
||||
<body data-sf-page="theme"><header><strong><span>SF</span> SiteForge · 主题预览中心</strong><a href="/factory-studio">返回网站工厂 →</a></header>
|
||||
<section class="controls"><label>主题<select id="theme"><option value="automotive">Automotive · 汽车与出行</option><option value="industrial">Industrial · 工业制造</option><option value="corporate">Corporate · 企业品牌</option><option value="minimal">Minimal · 极简设计</option><option value="trade-pro">Trade Pro · International B2B</option></select></label>
|
||||
<label>页面类型<select id="page"><option value="home">首页</option><option value="about">关于我们</option><option value="listing">产品 / 分类列表</option><option value="category">分类详情</option><option value="product">产品详情</option><option value="brand">品牌详情</option><option value="article">新闻详情</option><option value="case">案例详情</option><option value="service">服务详情</option><option value="contact">联系我们</option><option value="faq">常见问题</option><option value="standard">标准页面</option><option value="notfound">404</option></select></label>
|
||||
<label>主题版本<select id="version"><option value="">最新</option></select></label><div class="devices"><button data-size="100%" class="active">PC</button><button data-size="820px">平板</button><button data-size="390px">手机</button></div><span class="error" id="error">预览失败,请确认已登录。</span></section>
|
||||
<label>主题版本<select id="version"><option value="">最新</option></select></label><div class="devices"><button data-size="100%" class="active">PC</button><button data-size="820px">平板</button><button data-size="390px">手机</button></div><span id="previewStatus" role="status" aria-live="polite" class="sf-preview-status">准备加载预览…</span><button type="button" id="retryPreview" class="sf-preview-retry" hidden>重新加载</button><a id="openPreview" target="_blank" rel="noopener" class="sf-preview-retry" href="#">单独打开预览</a></section>
|
||||
<div class="stage"><div class="frame" id="frame"><iframe id="preview" title="主题真实页面预览" loading="eager"></iframe></div></div>
|
||||
<div class="help">预览使用真实页面模板与演示数据。实际网站构建后将使用你的品牌信息和内容。</div>
|
||||
<script>
|
||||
const theme=document.querySelector('#theme'),page=document.querySelector('#page'),version=document.querySelector('#version'),frame=document.querySelector('#frame'),iframe=document.querySelector('#preview');
|
||||
function show(){iframe.src=`/api/factory/themes/${encodeURIComponent(theme.value)}/preview?page_type=${encodeURIComponent(page.value)}&version=${encodeURIComponent(version.value)}`;}
|
||||
async function loadVersions(){const response=await fetch(`/api/factory/themes/${encodeURIComponent(theme.value)}/versions`,{credentials:'same-origin'});if(!response.ok)throw Error('无法读取主题版本');const arr=await response.json();version.replaceChildren();arr.forEach(x=>{const op=new Option('v'+x.version,x.version);version.append(op);});show();}
|
||||
theme.addEventListener('change',()=>loadVersions().catch(()=>document.querySelector('#error').style.display='inline'));
|
||||
[page,version].forEach(x=>x.addEventListener('change',show));document.querySelectorAll('.devices button').forEach(x=>x.addEventListener('click',()=>{document.querySelectorAll('.devices button').forEach(y=>y.classList.remove('active'));x.classList.add('active');frame.style.width=x.dataset.size;}));loadVersions().catch(()=>document.querySelector('#error').style.display='inline');
|
||||
const status=document.querySelector('#previewStatus'),retry=document.querySelector('#retryPreview'),open=document.querySelector('#openPreview');
|
||||
let sequence=0,controller=null;
|
||||
function link(){return `/api/factory/themes/${encodeURIComponent(theme.value)}/preview?page_type=${encodeURIComponent(page.value)}&version=${encodeURIComponent(version.value)}`;}
|
||||
async function show(){
|
||||
const seq=++sequence;
|
||||
controller?.abort();controller=new AbortController();
|
||||
const url=link();open.href=url;retry.hidden=true;status.classList.remove('error');status.textContent='正在加载预览…';
|
||||
iframe.removeAttribute('src');
|
||||
try{
|
||||
// A successful iframe load event can also mean a browser error page, so first verify HTTP.
|
||||
const response=await fetch(url,{credentials:'same-origin',signal:controller.signal,cache:'no-store'});
|
||||
if(!response.ok||!(response.headers.get('content-type')||'').includes('text/html'))throw Error(response.status===401?'登录已过期,请重新登录':`页面返回 ${response.status},无法预览`);
|
||||
if(seq!==sequence)return;
|
||||
iframe.onload=()=>{if(seq===sequence)status.textContent='预览已打开 · 可以切换页面或设备';};
|
||||
iframe.src=url;
|
||||
}catch(error){
|
||||
if(seq!==sequence||error.name==='AbortError')return;
|
||||
status.textContent=`加载失败:${error.message}。请重试或单独打开预览。`;
|
||||
status.classList.add('error');retry.hidden=false;
|
||||
}
|
||||
}
|
||||
async function loadVersions(){
|
||||
const seq=++sequence;controller?.abort();
|
||||
version.replaceChildren(new Option('最新版本',''));version.disabled=true;
|
||||
try{
|
||||
const response=await fetch(`/api/factory/themes/${encodeURIComponent(theme.value)}/versions`,{credentials:'same-origin'});
|
||||
if(!response.ok)throw Error(`主题版本返回 ${response.status}`);
|
||||
const versions=await response.json();
|
||||
if(seq!==sequence)return;
|
||||
versions.forEach(item=>version.add(new Option(`v${item.version}`,item.version)));
|
||||
}catch(error){if(seq!==sequence)return;status.textContent=`版本列表暂时无法读取,将预览最新版本:${error.message}`;}
|
||||
finally{if(seq===sequence){version.disabled=false;show();}}
|
||||
}
|
||||
theme.addEventListener('change',loadVersions);[page,version].forEach(control=>control.addEventListener('change',show));
|
||||
retry.addEventListener('click',show);
|
||||
document.querySelectorAll('.devices button').forEach(button=>button.addEventListener('click',()=>{document.querySelectorAll('.devices button').forEach(other=>other.classList.remove('active'));button.classList.add('active');frame.style.width=button.dataset.size;}));
|
||||
const requestedTheme=new URLSearchParams(location.search).get('theme');
|
||||
if(['automotive','industrial','corporate','minimal'].includes(requestedTheme))theme.value=requestedTheme;
|
||||
loadVersions();
|
||||
</script></body></html>
|
||||
|
||||
Reference in New Issue
Block a user