// core/wrapper-inline.js // iframe 内部注入脚本,同步执行,避免外部加载的时序问题 /** * 基础脚本:高度测量 + STscript * 两个渲染器共用 */ export function getIframeBaseScript() { return ` (function(){ // vh 修复:CSS注入(立即生效) + 延迟样式表遍历(不阻塞渲染) (function(){ var s=document.createElement('style'); s.textContent='html,body{height:auto!important;min-height:0!important;max-height:none!important}'; (document.head||document.documentElement).appendChild(s); // 延迟遍历样式表,不阻塞初次渲染 (window.requestIdleCallback||function(cb){setTimeout(cb,50)})(function(){ try{ for(var i=0,sheets=document.styleSheets;i-1)st.height='auto'; if((st.minHeight||'').indexOf('vh')>-1)st.minHeight='0'; if((st.maxHeight||'').indexOf('vh')>-1)st.maxHeight='none'; } }catch(e){} } }catch(e){} }); })(); function measureVisibleHeight(){ try{ var doc=document,target=doc.body; if(!target)return 0; var minTop=Infinity,maxBottom=0; var addRect=function(el){ try{ var r=el.getBoundingClientRect(); if(r&&r.height>0){ if(minTop>r.top)minTop=r.top; if(maxBottom0?Math.ceil(maxBottom-Math.min(minTop,0)):(target.scrollHeight||0); }catch(e){ return(document.body&&document.body.scrollHeight)||0; } } var parentOrigin;try{parentOrigin=new URL(document.referrer).origin}catch(_){parentOrigin='*'} function post(m){try{parent.postMessage(m,parentOrigin)}catch(e){}} var rafPending=false,lastH=0,HYSTERESIS=2; function send(force){ if(rafPending&&!force)return; rafPending=true; requestAnimationFrame(function(){ rafPending=false; var h=measureVisibleHeight(); if(force||Math.abs(h-lastH)>=HYSTERESIS){ lastH=h; post({height:h,force:!!force}); } }); } try{send(true)}catch(e){} document.addEventListener('DOMContentLoaded',function(){send(true)},{once:true}); window.addEventListener('load',function(){send(true)},{once:true}); try{ if(document.fonts){ document.fonts.ready.then(function(){send(true)}).catch(function(){}); if(document.fonts.addEventListener){ document.fonts.addEventListener('loadingdone',function(){send(true)}); document.fonts.addEventListener('loadingerror',function(){send(true)}); } } }catch(e){} ['transitionend','animationend'].forEach(function(evt){ document.addEventListener(evt,function(){send(false)},{passive:true,capture:true}); }); try{ var root=document.body||document.documentElement; var ro=new ResizeObserver(function(){send(false)}); ro.observe(root); }catch(e){ try{ var rootMO=document.body||document.documentElement; new MutationObserver(function(){send(false)}) .observe(rootMO,{childList:true,subtree:true,attributes:true,characterData:true}); }catch(e){} window.addEventListener('resize',function(){send(false)},{passive:true}); } window.addEventListener('message',function(e){ if(parentOrigin!=='*'&&e&&e.origin!==parentOrigin)return; var d=e&&e.data||{}; if(d&&d.type==='probe')setTimeout(function(){send(true)},10); }); window.STscript=function(command){ return new Promise(function(resolve,reject){ try{ if(!command){reject(new Error('empty'));return} if(command[0]!=='/')command='/'+command; var id=Date.now().toString(36)+Math.random().toString(36).slice(2); function onMessage(e){ if(parentOrigin!=='*'&&e&&e.origin!==parentOrigin)return; var d=e&&e.data||{}; if(d.source!=='xiaobaix-host')return; if((d.type==='commandResult'||d.type==='commandError')&&d.id===id){ try{window.removeEventListener('message',onMessage)}catch(e){} if(d.type==='commandResult')resolve(d.result); else reject(new Error(d.error||'error')); } } try{window.addEventListener('message',onMessage)}catch(e){} post({type:'runCommand',id:id,command:command}); setTimeout(function(){ try{window.removeEventListener('message',onMessage)}catch(e){} reject(new Error('Command timeout')); },180000); }catch(e){reject(e)} }); }; try{if(typeof window['stscript']!=='function')window['stscript']=window.STscript}catch(e){} })();`; } /** * CallGenerate + Avatar * 提供 callGenerate() 函数供角色卡调用 */ export function getWrapperScript() { return ` (function(){ function sanitizeOptions(options){ try{ return JSON.parse(JSON.stringify(options,function(k,v){return(typeof v==='function')?undefined:v})) }catch(_){ try{ var seen=new WeakSet(); var clone=function(val){ if(val===null||val===undefined)return val; var t=typeof val; if(t==='function')return undefined; if(t!=='object')return val; if(seen.has(val))return undefined; seen.add(val); if(Array.isArray(val)){ var arr=[];for(var i=0;i