@wordpress/interactivity-router 2.14.0 → 2.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/head.ts DELETED
@@ -1,126 +0,0 @@
1
- /**
2
- * The cache of prefetched stylesheets and scripts.
3
- */
4
- export const headElements = new Map<
5
- string,
6
- { tag: HTMLElement; text?: string }
7
- >();
8
-
9
- /**
10
- * Helper to update only the necessary tags in the head.
11
- *
12
- * @async
13
- * @param newHead The head elements of the new page.
14
- */
15
- export const updateHead = async ( newHead: HTMLHeadElement[] ) => {
16
- // Helper to get the tag id store in the cache.
17
- const getTagId = ( tag: Element ) => tag.id || tag.outerHTML;
18
-
19
- // Map incoming head tags by their content.
20
- const newHeadMap = new Map< string, Element >();
21
- for ( const child of newHead ) {
22
- newHeadMap.set( getTagId( child ), child );
23
- }
24
-
25
- const toRemove: Element[] = [];
26
-
27
- // Detect nodes that should be added or removed.
28
- for ( const child of document.head.children ) {
29
- const id = getTagId( child );
30
- // Always remove styles and links as they might change.
31
- if ( child.nodeName === 'LINK' || child.nodeName === 'STYLE' ) {
32
- toRemove.push( child );
33
- } else if ( newHeadMap.has( id ) ) {
34
- newHeadMap.delete( id );
35
- } else if ( child.nodeName !== 'SCRIPT' && child.nodeName !== 'META' ) {
36
- toRemove.push( child );
37
- }
38
- }
39
-
40
- await Promise.all(
41
- [ ...headElements.entries() ]
42
- .filter( ( [ , { tag } ] ) => tag.nodeName === 'SCRIPT' )
43
- .map( async ( [ url ] ) => {
44
- await import( /* webpackIgnore: true */ url );
45
- } )
46
- );
47
-
48
- // Prepare new assets.
49
- const toAppend = [ ...newHeadMap.values() ];
50
-
51
- // Apply the changes.
52
- toRemove.forEach( ( n ) => n.remove() );
53
- document.head.append( ...toAppend );
54
- };
55
-
56
- /**
57
- * Fetches and processes head assets (stylesheets and scripts) from a specified document.
58
- *
59
- * @async
60
- * @param doc The document from which to fetch head assets. It should support standard DOM querying methods.
61
- *
62
- * @return Returns an array of HTML elements representing the head assets.
63
- */
64
- export const fetchHeadAssets = async (
65
- doc: Document
66
- ): Promise< HTMLElement[] > => {
67
- const headTags = [];
68
-
69
- // We only want to fetch module scripts because regular scripts (without
70
- // `async` or `defer` attributes) can depend on the execution of other scripts.
71
- // Scripts found in the head are blocking and must be executed in order.
72
- const scripts = doc.querySelectorAll< HTMLScriptElement >(
73
- 'script[type="module"][src]'
74
- );
75
-
76
- scripts.forEach( ( script ) => {
77
- const src = script.getAttribute( 'src' );
78
- if ( ! headElements.has( src ) ) {
79
- // add the <link> elements to prefetch the module scripts
80
- const link = doc.createElement( 'link' );
81
- link.rel = 'modulepreload';
82
- link.href = src;
83
- document.head.append( link );
84
- headElements.set( src, { tag: script } );
85
- }
86
- } );
87
-
88
- const stylesheets = doc.querySelectorAll< HTMLLinkElement >(
89
- 'link[rel=stylesheet]'
90
- );
91
-
92
- await Promise.all(
93
- Array.from( stylesheets ).map( async ( tag ) => {
94
- const href = tag.getAttribute( 'href' );
95
- if ( ! href ) {
96
- return;
97
- }
98
-
99
- if ( ! headElements.has( href ) ) {
100
- try {
101
- const response = await fetch( href );
102
- const text = await response.text();
103
- headElements.set( href, {
104
- tag,
105
- text,
106
- } );
107
- } catch ( e ) {
108
- // eslint-disable-next-line no-console
109
- console.error( e );
110
- }
111
- }
112
-
113
- const headElement = headElements.get( href );
114
- const styleElement = doc.createElement( 'style' );
115
- styleElement.textContent = headElement.text;
116
-
117
- headTags.push( styleElement );
118
- } )
119
- );
120
-
121
- return [
122
- doc.querySelector( 'title' ),
123
- ...doc.querySelectorAll( 'style' ),
124
- ...headTags,
125
- ];
126
- };