Frontend iframe renderer framework: 3D models, OpenAPI (#37233)

Introduces a frontend external-render framework that runs renderer
plugins inside an `iframe` (loaded via `srcdoc` to keep the CSP
`sandbox` directive working without origin-related console noise), and
migrates the 3D viewer and OpenAPI/Swagger renderers onto it. PDF and
asciicast paths are refactored to share the same `data-render-name`
mechanism.

Adds e2e coverage for 3D, PDF, asciicast and OpenAPI render paths, plus
a regression for the `RefTypeNameSubURL` double-escape on non-ASCII
branch names.

Signed-off-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
silverwind
2026-04-18 00:30:17 +02:00
committed by GitHub
parent 0161f3019b
commit d5831b9385
32 changed files with 540 additions and 293 deletions
+13 -3
View File
@@ -108,7 +108,12 @@ func TestExternalMarkupRenderer(t *testing.T) {
// default sandbox in sub page response
assert.Equal(t, "frame-src 'self'; sandbox allow-scripts allow-popups", respSub.Header().Get("Content-Security-Policy"))
// FIXME: actually here is a bug (legacy design problem), the "PostProcess" will escape "<script>" tag, but it indeed is the sanitizer's job
assert.Equal(t, `<script nonce crossorigin src="`+public.AssetURI("js/external-render-helper.js")+`"></script><link rel="stylesheet" href="`+public.AssetURI("css/theme-gitea-auto.css")+`"><div><any attr="val">&lt;script&gt;&lt;/script&gt;</any></div>`, respSub.Body.String())
assert.Equal(t,
`<script nonce crossorigin src="`+public.AssetURI("js/external-render-helper.js")+`" id="gitea-external-render-helper" data-render-query-string=""></script>`+
`<link rel="stylesheet" href="`+public.AssetURI("css/theme-gitea-auto.css")+`">`+
`<div><any attr="val">&lt;script&gt;&lt;/script&gt;</any></div>`,
respSub.Body.String(),
)
})
})
@@ -129,9 +134,14 @@ func TestExternalMarkupRenderer(t *testing.T) {
})
t.Run("HTMLContentWithExternalRenderIframeHelper", func(t *testing.T) {
req := NewRequest(t, "GET", "/user2/repo1/render/branch/master/html.no-sanitizer")
req := NewRequest(t, "GET", "/user2/repo1/render/branch/master/html.no-sanitizer?a=1%2f2")
respSub := MakeRequest(t, req, http.StatusOK)
assert.Equal(t, `<script nonce crossorigin src="`+public.AssetURI("js/external-render-helper.js")+`"></script><link rel="stylesheet" href="`+public.AssetURI("css/theme-gitea-auto.css")+`"><script>foo("raw")</script>`, respSub.Body.String())
assert.Equal(t,
`<script nonce crossorigin src="`+public.AssetURI("js/external-render-helper.js")+`" id="gitea-external-render-helper" data-render-query-string="a=1%2f2"></script>`+
`<link rel="stylesheet" href="`+public.AssetURI("css/theme-gitea-auto.css")+`">`+
`<script>foo("raw")</script>`,
respSub.Body.String(),
)
assert.Equal(t, "frame-src 'self'", respSub.Header().Get("Content-Security-Policy"))
})
})