feat(mindspace): 公开页分享组件、workspace 路径与 Plaza 发布增强

- 新增 public share widget 与 workspace relative path 解析
- 增强 publications/chat-plaza 发布链路与缩略图 demo
- 补充 schema、cover 检查脚本与回归测试

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-07-05 23:14:41 +08:00
parent 69be1e5293
commit e2ad3bf62b
39 changed files with 2184 additions and 256 deletions
+30 -19
View File
@@ -10,7 +10,7 @@ export function isPlazaEmbedRequest(query = {}) {
export function publishedPageCspForEmbed(isFullHtml) {
if (isFullHtml) {
return "default-src 'none'; style-src 'unsafe-inline' https:; img-src data: https:; font-src https: data:; base-uri 'none'; form-action 'self'; frame-ancestors *; script-src 'unsafe-inline'";
return "default-src 'none'; style-src 'unsafe-inline' https:; img-src 'self' data: https: http:; font-src https: data:; base-uri 'none'; form-action 'self'; frame-ancestors *; script-src 'unsafe-inline'";
}
return "default-src 'none'; style-src 'unsafe-inline'; img-src data:; font-src 'none'; base-uri 'none'; form-action 'self'; frame-ancestors *; script-src 'unsafe-inline'";
}
@@ -22,13 +22,22 @@ export function allowPlazaEmbedFrame(res) {
const EMBED_BOOTSTRAP = `<script id="plaza-embed-bootstrap">(function(){
if(window.parent===window)return;
var d=document;
function isDecorative(el){
if(!el||el.nodeType!==1)return true;
var cls=String(el.className||'');
if(/\b(bg-particles|glow-orb|particle|backdrop|ambient|bg-glow)\b/i.test(cls))return true;
var st=window.getComputedStyle(el);
if(st.position==='fixed')return true;
if(st.position==='absolute'&&(Number(st.zIndex||0)<=0||st.pointerEvents==='none'))return true;
return false;
}
function blocks(){
var out=[],hero=d.querySelector('.hero');
if(hero)out.push(hero);
d.querySelectorAll('.section,.quote-section').forEach(function(el){out.push(el);});
d.querySelectorAll('.section,.quote-section,.container,main,article').forEach(function(el){out.push(el);});
var foot=d.querySelector('.footer');
if(foot)out.push(foot);
return out.length?out:[d.body||d.documentElement];
return out;
}
function fullHeight(){
var body=d.body,root=d.documentElement;
@@ -41,27 +50,21 @@ const EMBED_BOOTSTRAP = `<script id="plaza-embed-bootstrap">(function(){
}
var els=blocks();
for(var i=0;i<els.length;i++){
if(!els[i])continue;
if(!els[i]||isDecorative(els[i]))continue;
measured=Math.max(measured,bottomOf(els[i]),els[i].offsetTop+els[i].offsetHeight);
}
if(body){
for(var j=0;j<body.children.length;j++){
measured=Math.max(measured,bottomOf(body.children[j]));
var child=body.children[j];
if(isDecorative(child))continue;
measured=Math.max(measured,bottomOf(child),child.offsetTop+child.offsetHeight);
}
}
if(body&&body.lastElementChild){
if(body&&body.lastElementChild&&!isDecorative(body.lastElementChild)){
var last=body.lastElementChild;
measured=Math.max(measured,bottomOf(last),last.offsetTop+last.offsetHeight);
}
measured=Math.max(
measured,
root?root.scrollHeight:0,
root?root.offsetHeight:0,
body?body.scrollHeight:0,
body?body.offsetHeight:0,
420
);
return Math.ceil(measured);
return Math.max(Math.ceil(measured),420);
}
function restoreBlock(block){
if(!block)return;
@@ -97,6 +100,7 @@ const EMBED_BOOTSTRAP = `<script id="plaza-embed-bootstrap">(function(){
}
function showAll(){
var b=blocks();
if(!b.length&&d.body)b=[d.body];
for(var i=0;i<b.length;i++){
b[i].style.display='';
b[i].style.visibility='';
@@ -138,10 +142,17 @@ const EMBED_BOOTSTRAP = `<script id="plaza-embed-bootstrap">(function(){
});
if(typeof ResizeObserver!=='undefined'){
var ro=new ResizeObserver(function(){reportHeight();});
ro.observe(d.documentElement);
if(d.body)ro.observe(d.body);
}
if(typeof MutationObserver!=='undefined'){
function observeBlocks(){
blocks().forEach(function(el){if(el)ro.observe(el);});
}
observeBlocks();
if(typeof MutationObserver!=='undefined'){
new MutationObserver(function(){
observeBlocks();
scheduleReport();
}).observe(d.documentElement,{childList:true,subtree:true,attributes:true});
}
} else if(typeof MutationObserver!=='undefined'){
new MutationObserver(function(){scheduleReport();}).observe(d.documentElement,{childList:true,subtree:true,attributes:true});
}
d.querySelectorAll('img,video,iframe').forEach(function(el){