@@ -196,23 +196,31 @@ function getAbsoluteSrcsetString(doc: Document, attributeValue: string) {
196196 return output . join ( ', ' ) ;
197197}
198198
199+ const cachedDocument = new WeakMap < Document , HTMLAnchorElement > ( ) ;
200+
199201export function absoluteToDoc ( doc : Document , attributeValue : string ) : string {
200202 if ( ! attributeValue || attributeValue . trim ( ) === '' ) {
201203 return attributeValue ;
202204 }
203- const a : HTMLAnchorElement = doc . createElement ( 'a' ) ;
204- a . href = attributeValue ;
205- return a . href ;
205+
206+ return getHref ( doc , attributeValue ) ;
206207}
207208
208209function isSVGElement ( el : Element ) : boolean {
209210 return Boolean ( el . tagName === 'svg' || ( el as SVGElement ) . ownerSVGElement ) ;
210211}
211212
212- function getHref ( ) {
213- // return a href without hash
214- const a = document . createElement ( 'a' ) ;
215- a . href = '' ;
213+ function getHref ( doc : Document , customHref ?: string ) {
214+ let a = cachedDocument . get ( doc ) ;
215+ if ( ! a ) {
216+ a = doc . createElement ( 'a' ) ;
217+ cachedDocument . set ( doc , a ) ;
218+ }
219+ if ( ! customHref ) {
220+ customHref = '' ;
221+ }
222+ // note: using `new URL` is slower. See #1434 or https://jsbench.me/uqlud17rxo/1
223+ a . setAttribute ( 'href' , customHref ) ;
216224 return a . href ;
217225}
218226
@@ -244,7 +252,7 @@ export function transformAttribute(
244252 } else if ( name === 'srcset' ) {
245253 return getAbsoluteSrcsetString ( doc , value ) ;
246254 } else if ( name === 'style' ) {
247- return absoluteToStylesheet ( value , getHref ( ) ) ;
255+ return absoluteToStylesheet ( value , getHref ( doc ) ) ;
248256 } else if ( tagName === 'object' && name === 'data' ) {
249257 return absoluteToDoc ( doc , value ) ;
250258 }
@@ -506,6 +514,7 @@ function serializeNode(
506514 } ) ;
507515 case n . TEXT_NODE :
508516 return serializeTextNode ( n as Text , {
517+ doc,
509518 needsMask,
510519 maskTextFn,
511520 rootId,
@@ -536,6 +545,7 @@ function getRootId(doc: Document, mirror: Mirror): number | undefined {
536545function serializeTextNode (
537546 n : Text ,
538547 options : {
548+ doc : Document ;
539549 needsMask : boolean | undefined ;
540550 maskTextFn : MaskTextFn | undefined ;
541551 rootId : number | undefined ;
@@ -567,7 +577,7 @@ function serializeTextNode(
567577 n ,
568578 ) ;
569579 }
570- textContent = absoluteToStylesheet ( textContent , getHref ( ) ) ;
580+ textContent = absoluteToStylesheet ( textContent , getHref ( options . doc ) ) ;
571581 }
572582 if ( isScript ) {
573583 textContent = 'SCRIPT_PLACEHOLDER' ;
@@ -661,7 +671,7 @@ function serializeElementNode(
661671 ( n as HTMLStyleElement ) . sheet as CSSStyleSheet ,
662672 ) ;
663673 if ( cssText ) {
664- attributes . _cssText = absoluteToStylesheet ( cssText , getHref ( ) ) ;
674+ attributes . _cssText = absoluteToStylesheet ( cssText , getHref ( doc ) ) ;
665675 }
666676 }
667677 // form fields
0 commit comments