@@ -6,6 +6,7 @@ import { rewriteUrl, unrewriteUrl } from "@rewriters/url";
66import { SCRAMJETCLIENT } from "@/symbols" ;
77import { ScramjetClient } from "@client/index" ;
88import { isHtmlMimeType } from "@/shared/mime" ;
9+ import { ForeignContext } from "@/shared/rewriters/html" ;
910
1011const encoder = new TextEncoder ( ) ;
1112function bytesToBase64 ( bytes : Uint8Array ) {
@@ -15,6 +16,35 @@ function bytesToBase64(bytes: Uint8Array) {
1516
1617 return btoa ( binString ) ;
1718}
19+
20+ export function foreignContextForElement (
21+ client : ScramjetClient ,
22+ element : Element
23+ ) : ForeignContext {
24+ if ( client . box . instanceof ( element , "SVGElement" ) ) return "svg" ;
25+ if ( client . box . instanceof ( element , "MathMLElement" ) ) return "math" ;
26+ return undefined ;
27+ }
28+
29+ // NOTE: NOT INCLUSIVE OF THE CURRENT ELEMENT
30+ export function insideForeignContext (
31+ client : ScramjetClient ,
32+ element : Element | null
33+ ) : ForeignContext {
34+ let current : Element | null = element . parentElement ;
35+
36+ while ( current ) {
37+ const context = foreignContextForElement ( client , current ) ;
38+ if ( context ) return context ;
39+ // EXPLICITLY an html context, don't go up further
40+ if ( client . box . instanceof ( current , "SVGForeignObjectElement" ) )
41+ return undefined ;
42+ current = current . parentElement ;
43+ }
44+
45+ return undefined ;
46+ }
47+
1848export default function ( client : ScramjetClient , self : typeof window ) {
1949 const attrObject = {
2050 nonce : [ self . HTMLElement ] ,
@@ -327,6 +357,7 @@ export default function (client: ScramjetClient, self: typeof window) {
327357 inline : true ,
328358 source : client . url . href ,
329359 apisource : "set Element.prototype.innerHTML" ,
360+ foreignContext : foreignContextForElement ( client , ctx . this ) ,
330361 } ) ;
331362 } catch {
332363 newval = value ;
@@ -430,6 +461,7 @@ export default function (client: ScramjetClient, self: typeof window) {
430461 inline : true ,
431462 source : client . url . href ,
432463 apisource : "set Element.prototype.setHTMLUnsafe" ,
464+ foreignContext : foreignContextForElement ( client , ctx . this ) ,
433465 } ) ;
434466 } catch { }
435467 } ,
@@ -450,6 +482,7 @@ export default function (client: ScramjetClient, self: typeof window) {
450482 inline : true ,
451483 source : client . url . href ,
452484 apisource : "set Element.prototype.insertAdjacentHTML" ,
485+ foreignContext : foreignContextForElement ( client , ctx . this ) ,
453486 } ) ;
454487 } catch { }
455488 } ,
@@ -611,6 +644,7 @@ export default function (client: ScramjetClient, self: typeof window) {
611644
612645 client . Proxy ( "DOMParser.prototype.parseFromString" , {
613646 apply ( ctx ) {
647+ // TODO: what do we do if it's xml/svg?
614648 if ( typeof ctx . args [ 1 ] === "string" && isHtmlMimeType ( ctx . args [ 1 ] ) ) {
615649 try {
616650 ctx . args [ 0 ] = rewriteHtml ( ctx . args [ 0 ] , client . context , client . meta , {
0 commit comments