This commit is contained in:
RT15548
2026-01-01 16:10:36 +08:00
committed by GitHub
parent 90a80f99df
commit 452e0b687e

View File

@@ -5,7 +5,7 @@ import { xbLog, CacheRegistry } from "../core/debug-core.js";
import { replaceXbGetVarInString } from "./variables/var-commands.js"; import { replaceXbGetVarInString } from "./variables/var-commands.js";
import { executeSlashCommand } from "../core/slash-command.js"; import { executeSlashCommand } from "../core/slash-command.js";
import { default_user_avatar, default_avatar } from "../../../../../script.js"; import { default_user_avatar, default_avatar } from "../../../../../script.js";
import { getIframeBaseScript, getWrapperScript } from "../core/wrapper-inline.js";
const MODULE_ID = 'iframeRenderer'; const MODULE_ID = 'iframeRenderer';
const events = createModuleEvents(MODULE_ID); const events = createModuleEvents(MODULE_ID);
@@ -150,144 +150,25 @@ function buildResourceHints(html) {
return hints + preload; return hints + preload;
} }
function iframeClientScript() {
return `
(function(){
function measureVisibleHeight(){
try{
var doc = document;
var 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(maxBottom < r.bottom) maxBottom = r.bottom;
}
}catch(e){}
};
addRect(target);
var children = target.children || [];
for(var i=0;i<children.length;i++){
var child = children[i];
if(!child) continue;
try{
var s = window.getComputedStyle(child);
if(s.display === 'none' || s.visibility === 'hidden') continue;
if(!child.offsetParent && s.position !== 'fixed') continue;
}catch(e){}
addRect(child);
}
return maxBottom > 0 ? Math.ceil(maxBottom - Math.min(minTop, 0)) : (target.scrollHeight || 0);
}catch(e){
return (document.body && document.body.scrollHeight) || 0;
}
}
function post(m){ try{ parent.postMessage(m,'*') }catch(e){} }
var rafPending=false, lastH=0;
var 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){
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){
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, 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){}
})();`;
}
function buildWrappedHtml(html) { function buildWrappedHtml(html) {
const settings = getSettings(); const settings = getSettings();
const api = `<script>${iframeClientScript()}</script>`;
const wrapperToggle = settings.wrapperIframe ?? true; const wrapperToggle = settings.wrapperIframe ?? true;
const origin = typeof location !== 'undefined' && location.origin ? location.origin : ''; const origin = typeof location !== 'undefined' && location.origin ? location.origin : '';
const optWrapperUrl = `${origin}/scripts/extensions/third-party/${EXT_ID}/bridges/wrapper-iframe.js`;
const optWrapper = wrapperToggle ? `<script src="${optWrapperUrl}"></script>` : "";
const baseTag = settings.useBlob ? `<base href="${origin}/">` : ""; const baseTag = settings.useBlob ? `<base href="${origin}/">` : "";
const headHints = buildResourceHints(html); const headHints = buildResourceHints(html);
const vhFix = `<style>html,body{height:auto!important;min-height:0!important;max-height:none!important}.profile-container,[style*="100vh"]{height:auto!important;min-height:600px!important}[style*="height:100%"]{height:auto!important;min-height:100%!important}</style>`; const vhFix = `<style>html,body{height:auto!important;min-height:0!important;max-height:none!important}.profile-container,[style*="100vh"]{height:auto!important;min-height:600px!important}[style*="height:100%"]{height:auto!important;min-height:100%!important}</style>`;
// 内联脚本按顺序wrapper(callGenerate) -> base(高度+STscript)
const scripts = wrapperToggle
? `<script>${getWrapperScript()}${getIframeBaseScript()}</script>`
: `<script>${getIframeBaseScript()}</script>`;
if (html.includes('<html') && html.includes('</html')) { if (html.includes('<html') && html.includes('</html')) {
if (html.includes('<head>')) if (html.includes('<head>'))
return html.replace('<head>', `<head>${baseTag}${api}${optWrapper}${headHints}${vhFix}`); return html.replace('<head>', `<head>${scripts}${baseTag}${headHints}${vhFix}`);
if (html.includes('</head>')) if (html.includes('</head>'))
return html.replace('</head>', `${baseTag}${api}${optWrapper}${headHints}${vhFix}</head>`); return html.replace('</head>', `${scripts}${baseTag}${headHints}${vhFix}</head>`);
return html.replace('<body', `<head>${baseTag}${api}${optWrapper}${headHints}${vhFix}</head><body`); return html.replace('<body', `<head>${scripts}${baseTag}${headHints}${vhFix}</head><body`);
} }
return `<!DOCTYPE html> return `<!DOCTYPE html>
@@ -295,14 +176,11 @@ function buildWrappedHtml(html) {
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
${scripts}
${baseTag} ${baseTag}
${api}
${optWrapper}
${headHints} ${headHints}
${vhFix} ${vhFix}
<style> <style>html,body{margin:0;padding:0;background:transparent}</style>
html, body { margin: 0; padding: 0; background: transparent; }
</style>
</head> </head>
<body>${html}</body></html>`; <body>${html}</body></html>`;
} }