Merge pull request #20 from dr-forget/fix/script

feat: 优化script脚本执行机制
This commit is contained in:
仓鼠 2024-12-18 10:23:28 +08:00 committed by GitHub
commit 115fd59ec8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -21,11 +21,14 @@ export const InjectContext = (content: string) => {
})
}
const executeInlineScript = (scriptElement: HTMLScriptElement): void => {
const executeInlineScript = (scriptContent: string): Promise<void> => {
return new Promise((resolve) => {
const script = document.createElement("script")
script.textContent = scriptElement.textContent
script.textContent = scriptContent
script.setAttribute(INJECTION_MARK, "true") // 添加标识
document.body.appendChild(script)
resolve()
})
}
const loadStyle = (styleElement: HTMLStyleElement): Promise<void> => {
@ -56,8 +59,8 @@ export const InjectContext = (content: string) => {
// 加载外部脚本
return loadExternalScript(scriptElement)
} else {
// 推迟执行内联脚本,后续手动执行
return Promise.resolve()
// 执行内联脚本
return executeInlineScript(scriptElement.textContent || "")
}
},
STYLE: (element) => loadStyle(element as HTMLStyleElement),
@ -77,28 +80,20 @@ export const InjectContext = (content: string) => {
// 开始注入前清理已有资源
cleanInjectedResources()
const externalScriptQueue: Promise<void>[] = []
Array.from(tempDiv.childNodes).forEach((node) => {
const executeSequentially = async () => {
for (const node of Array.from(tempDiv.childNodes)) {
if (node.nodeType === Node.ELEMENT_NODE) {
const element = node as HTMLElement
if (element.tagName === "SCRIPT" && !(element as HTMLScriptElement).src) {
// 直接执行内联脚本
executeInlineScript(element as HTMLScriptElement)
} else {
const handler = handlers[element.tagName] || handlers.DEFAULT
externalScriptQueue.push(handler(element))
}
await handler(element) // 按顺序等待当前脚本或资源完成处理
} else if (node.nodeType === Node.TEXT_NODE) {
document.body.appendChild(document.createTextNode(node.textContent || ""))
}
})
}
console.log("All resources have been injected and executed in sequence.")
}
return Promise.all(externalScriptQueue)
.then(() => {
console.log("All resources have been injected successfully.")
})
.catch((error) => {
return executeSequentially().catch((error) => {
console.error("Error during resource injection:", error)
})
}