@webqit/oohtml 3.1.14 → 3.1.15
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/README.md +210 -215
- package/dist/main.js +18 -22
- package/dist/main.js.map +2 -2
- package/dist/main.lite.js +13 -17
- package/dist/main.lite.js.map +2 -2
- package/dist/namespaced-html.js +1 -1
- package/dist/namespaced-html.js.map +2 -2
- package/dist/scoped-css.js +1 -5
- package/dist/scoped-css.js.map +2 -2
- package/package.json +1 -1
- package/src/namespaced-html/index.js +91 -41
- package/src/scoped-css/index.js +32 -26
package/package.json
CHANGED
|
@@ -24,43 +24,83 @@ export default function init( $config = {} ) {
|
|
|
24
24
|
realtime.call( window, config );
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* @init
|
|
29
|
+
*
|
|
30
|
+
* @param Object config
|
|
31
|
+
*
|
|
32
|
+
* @return String
|
|
33
|
+
*/
|
|
34
|
+
function lidUtil( config ) {
|
|
35
|
+
const { lidrefPrefix, lidrefSeparator, } = config.tokens;
|
|
36
|
+
return {
|
|
37
|
+
escape( str, mode = 1 ) { return [ ...str ].map( x => !/\w/.test( x ) ? ( mode === 2 ? `\\\\${ x }` : `\\${ x }` ) : x ).join( '' ); },
|
|
38
|
+
lidrefPrefix( escapeMode = 0 ) { return escapeMode ? this.escape( lidrefPrefix, escapeMode ) : lidrefPrefix; },
|
|
39
|
+
lidrefSeparator( escapeMode = 0 ) { return escapeMode ? this.escape( lidrefSeparator, escapeMode ) : lidrefSeparator; },
|
|
40
|
+
isUuid( str, escapeMode = 0 ) { return str.startsWith( this.lidrefPrefix( escapeMode ) ) && str.includes( this.lidrefSeparator( escapeMode ) ); },
|
|
41
|
+
isLidref( str, escapeMode = 0 ) { return str.startsWith( this.lidrefPrefix( escapeMode ) ) && !str.includes( this.lidrefSeparator( escapeMode ) ); },
|
|
42
|
+
toUuid( hash, lid, escapeMode = 0 ) { return `${ this.lidrefPrefix( escapeMode ) }${ hash }${ this.lidrefSeparator( escapeMode ) }${ lid }`; },
|
|
43
|
+
uuidToLid( str, escapeMode = 0 ) { return this.isUuid( str ) ? str.split( this.lidrefSeparator( escapeMode ) )[ 1 ] : str; },
|
|
44
|
+
uuidToLidref( str, escapeMode = 0 ) { return this.isUuid( str ) ? `${ this.lidrefPrefix( escapeMode ) }${ str.split( this.lidrefSeparator( escapeMode ) )[ 1 ] }` : str; },
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
27
48
|
/**
|
|
28
49
|
* @rewriteSelector
|
|
29
50
|
*
|
|
30
51
|
* @param String selectorText
|
|
52
|
+
* @param String namespaceUUID
|
|
31
53
|
* @param String scopeSelector
|
|
32
|
-
* @param Bool
|
|
54
|
+
* @param Bool escapeMode
|
|
55
|
+
*
|
|
56
|
+
* @return String
|
|
33
57
|
*/
|
|
34
|
-
export function rewriteSelector( selectorText, scopeSelector = null,
|
|
58
|
+
export function rewriteSelector( selectorText, namespaceUUID, scopeSelector = null, escapeMode = 0 ) {
|
|
35
59
|
const window = this, { webqit: { oohtml: { configs: { NAMESPACED_HTML: config } } } } = window;
|
|
36
|
-
const
|
|
60
|
+
const $lidUtil = lidUtil( config );
|
|
37
61
|
// Match :scope and relative ID selector
|
|
38
|
-
const regex = new RegExp( `${ scopeSelector ? `:scope|` : '' }
|
|
62
|
+
const regex = new RegExp( `${ scopeSelector ? `:scope|` : '' }#(${ $lidUtil.lidrefPrefix( escapeMode + 1 ) })?([\\w]+${ $lidUtil.lidrefSeparator( escapeMode + 1 ) })?((?:[\\w-]|\\\\.)+)`, 'g' );
|
|
39
63
|
// Parse potentially combined selectors individually and categorise into categories per whether they have :scope or not
|
|
40
64
|
const [ cat1, cat2 ] = _splitOuter( selectorText, ',' ).reduce( ( [ cat1, cat2 ], selector ) => {
|
|
41
65
|
// The deal: match and replace
|
|
42
66
|
let quotesMatch, hadScopeSelector;
|
|
43
|
-
selector = selector.replace( regex, ( match,
|
|
67
|
+
selector = selector.replace( regex, ( match, lidrefPrefixMatch, lidrefSeparatorMatch, id, index ) => {
|
|
44
68
|
if ( !quotesMatch ) { // Lazy: stuff
|
|
45
69
|
// Match strings between quotes (single or double) and use that qualify matches above
|
|
46
70
|
// The string: String.raw`She said, "Hello, John. I\"m your friend." or "you're he're" 'f\'"j\'"f'jfjf`;
|
|
47
71
|
// Should yield: `"Hello, John. I\\"m your friend."`, `"you're he're"`, `'f\\'"j\\'"f'`
|
|
48
72
|
quotesMatch = [ ...selector.matchAll( /(["'])(?:(?=(\\?))\2.)*?\1/g ) ];
|
|
49
73
|
}
|
|
74
|
+
if ( quotesMatch[ 0 ] )
|
|
50
75
|
// Qualify match
|
|
51
|
-
if ( quotesMatch.some( q => index > q.index && index + match.length < q.index +
|
|
76
|
+
if ( quotesMatch.some( q => index > q.index && index + match.length < q.index + q[ 0 ].length ) ) return match;
|
|
52
77
|
// Replace :scope
|
|
53
78
|
if ( match === ':scope' ) {
|
|
54
79
|
hadScopeSelector = true;
|
|
55
80
|
return scopeSelector;
|
|
56
81
|
}
|
|
57
|
-
|
|
58
|
-
const
|
|
82
|
+
const isLidref = lidrefPrefixMatch && !lidrefSeparatorMatch;
|
|
83
|
+
const isUuid = lidrefPrefixMatch && lidrefSeparatorMatch;
|
|
84
|
+
if ( isUuid ) {
|
|
85
|
+
return `#${ $lidUtil.escape( match.replace( '#', '' ), 1 ) }`;
|
|
86
|
+
}
|
|
87
|
+
// Rewrite relative ID selector
|
|
88
|
+
let lowerBoundFactor = false;
|
|
89
|
+
if ( isLidref ) {
|
|
90
|
+
if ( config.attr.lid === 'id' && namespaceUUID ) {
|
|
91
|
+
return `#${ $lidUtil.toUuid( namespaceUUID, id, 1 ) }`;
|
|
92
|
+
}
|
|
93
|
+
// Fallback to attr-based
|
|
94
|
+
lowerBoundFactor = true;
|
|
95
|
+
}
|
|
96
|
+
// Rewrite absolute ID selector
|
|
97
|
+
let rewrite;
|
|
59
98
|
if ( config.attr.lid === 'id' ) {
|
|
60
|
-
|
|
99
|
+
rewrite = `[id^="${ $lidUtil.lidrefPrefix( escapeMode ) }"][id$="${ $lidUtil.lidrefSeparator( escapeMode ) }${ id }"]`;
|
|
61
100
|
} else {
|
|
62
|
-
|
|
101
|
+
rewrite = `:is(#${ id },[${ window.CSS.escape( config.attr.lid ) }="${ id }"])`;
|
|
63
102
|
}
|
|
103
|
+
return scopeSelector && lowerBoundFactor ? `:is(${ rewrite }):not(${ scopeSelector } [${ config.attr.namespace }] *)` : rewrite;
|
|
64
104
|
} );
|
|
65
105
|
// Category 2 has :scope and category 1 does not
|
|
66
106
|
return hadScopeSelector ? [ cat1, cat2.concat( selector ) ] : [ cat1.concat( selector ), cat2 ];
|
|
@@ -82,7 +122,7 @@ export function rewriteSelector( selectorText, scopeSelector = null, isCssSelect
|
|
|
82
122
|
*
|
|
83
123
|
* @return Object
|
|
84
124
|
*/
|
|
85
|
-
function getNamespaceObject( node ) {
|
|
125
|
+
export function getNamespaceObject( node ) {
|
|
86
126
|
if ( !_( node ).has( 'namespace' ) ) {
|
|
87
127
|
const namespaceObj = Object.create( null );
|
|
88
128
|
_( node ).set( 'namespace', namespaceObj );
|
|
@@ -90,6 +130,17 @@ function getNamespaceObject( node ) {
|
|
|
90
130
|
return _( node ).get( 'namespace' );
|
|
91
131
|
}
|
|
92
132
|
|
|
133
|
+
/**
|
|
134
|
+
* @param Element node
|
|
135
|
+
*
|
|
136
|
+
* @return String
|
|
137
|
+
*/
|
|
138
|
+
export function getNamespaceUUID( node ) {
|
|
139
|
+
const window = this, { webqit: { oohtml: { configs: { NAMESPACED_HTML: config } } } } = window;
|
|
140
|
+
const namespaceObj = getNamespaceObject( node instanceof window.Document ? node : ( node.closest( `[${ config.attr.namespace }]` ) || node.ownerDocument ) );
|
|
141
|
+
return _fromHash( namespaceObj ) || _toHash( namespaceObj );
|
|
142
|
+
}
|
|
143
|
+
|
|
93
144
|
/**
|
|
94
145
|
* Exposes Namespaced HTML with native APIs.
|
|
95
146
|
*
|
|
@@ -120,7 +171,6 @@ function exposeAPIs( config ) {
|
|
|
120
171
|
*/
|
|
121
172
|
function realtime( config ) {
|
|
122
173
|
const window = this, { webqit: { Observer, realdom, oohtml: { configs }, DOMNamingContext } } = window;
|
|
123
|
-
const { lidrefPrefix, lidrefSeparator } = config.tokens;
|
|
124
174
|
|
|
125
175
|
// ------------
|
|
126
176
|
// NAMESPACE
|
|
@@ -149,31 +199,25 @@ function realtime( config ) {
|
|
|
149
199
|
const idRefAttrs = [ 'for', 'list', 'form', 'aria-activedescendant', 'aria-details', 'aria-errormessage', ];
|
|
150
200
|
const attrList = [ config.attr.lid, ...idRefsAttrs, ...idRefAttrs ];
|
|
151
201
|
const relMap = { id: 'id'/* just in case it's in attrList */, for: 'htmlFor', 'aria-owns': 'ariaOwns', 'aria-controls': 'ariaControls', 'aria-labelledby': 'ariaLabelledBy', 'aria-describedby': 'ariaDescribedBy', 'aria-flowto': 'ariaFlowto', 'aria-activedescendant': 'ariaActiveDescendant', 'aria-details': 'ariaDetails', 'aria-errormessage': 'ariaErrorMessage' };
|
|
152
|
-
const
|
|
153
|
-
const isLidref = str => str.startsWith( lidrefPrefix ) && !str.includes( lidrefSeparator );
|
|
154
|
-
const toUuid = ( hash, lid ) => `${ lidrefPrefix }${ hash }${ lidrefSeparator }${ lid }`;
|
|
155
|
-
const uuidToLid = str => isUuid( str ) ? str.split( lidrefSeparator )[ 1 ] : str;
|
|
156
|
-
const uuidToLidref = str => isUuid( str ) ? `${ lidrefPrefix }${ str.split( lidrefSeparator )[ 1 ] }` : str;
|
|
202
|
+
const $lidUtil = lidUtil( config );
|
|
157
203
|
|
|
158
204
|
// Intercept getAttribute()
|
|
159
|
-
const
|
|
160
|
-
Object.defineProperty( window.Element.prototype, 'getAttribute', { ...
|
|
161
|
-
const value =
|
|
162
|
-
return !_( this, 'lock' ).get( attrName ) && attrList.includes( attrName ) ? ( attrName === 'id' ? uuidToLid : uuidToLidref )( value ) : value;
|
|
205
|
+
const getAttributeDescr = Object.getOwnPropertyDescriptor( window.Element.prototype, 'getAttribute' );
|
|
206
|
+
Object.defineProperty( window.Element.prototype, 'getAttribute', { ...getAttributeDescr, value( attrName ) {
|
|
207
|
+
const value = getAttributeDescr.value.call( this, attrName );
|
|
208
|
+
return !_( this, 'lock' ).get( attrName ) && attrList.includes( attrName ) ? ( attrName === 'id' ? $lidUtil.uuidToLid : $lidUtil.uuidToLidref ).call( $lidUtil, value ) : value;
|
|
163
209
|
} } );
|
|
164
210
|
// Intercept getElementById()
|
|
165
|
-
const
|
|
166
|
-
Object.defineProperty( window.Document.prototype, 'getElementById', { ...
|
|
167
|
-
|
|
168
|
-
const node = this.querySelector( rewriteSelector.call( window, `#${ id }` ) );
|
|
169
|
-
return node;// !node?.closest( config.namespaceSelector ) ? node : null; // Cool, but not consistent with querySelector(All)() results
|
|
211
|
+
const getElementByIdDescr = Object.getOwnPropertyDescriptor( window.Document.prototype, 'getElementById' );
|
|
212
|
+
Object.defineProperty( window.Document.prototype, 'getElementById', { ...getElementByIdDescr, value( id ) {
|
|
213
|
+
return this.querySelector( `#${ id }`/* Will be rewritten at querySelector() */ );
|
|
170
214
|
} } );
|
|
171
215
|
// Intercept querySelector() and querySelectorAll()
|
|
172
216
|
for ( const queryApi of [ 'querySelector', 'querySelectorAll' ] ) {
|
|
173
217
|
for ( nodeApi of [ window.Document, window.Element ] ) {
|
|
174
|
-
const
|
|
175
|
-
Object.defineProperty( nodeApi.prototype, queryApi, { ...
|
|
176
|
-
return
|
|
218
|
+
const querySelectorDescr = Object.getOwnPropertyDescriptor( nodeApi.prototype, queryApi );
|
|
219
|
+
Object.defineProperty( nodeApi.prototype, queryApi, { ...querySelectorDescr, value( selector ) {
|
|
220
|
+
return querySelectorDescr.value.call( this, rewriteSelector.call( window, selector, getNamespaceUUID.call( window, this ) ) );
|
|
177
221
|
} } );
|
|
178
222
|
}
|
|
179
223
|
}
|
|
@@ -182,15 +226,21 @@ function realtime( config ) {
|
|
|
182
226
|
if ( !( attrName in relMap ) ) continue;
|
|
183
227
|
const domApis = attrName === 'for' ? [ window.HTMLLabelElement, window.HTMLOutputElement ] : [ window.Element ];
|
|
184
228
|
for ( const domApi of domApis ) {
|
|
185
|
-
const
|
|
186
|
-
if ( !
|
|
187
|
-
Object.defineProperty( domApi.prototype, relMap[ attrName ], { ...
|
|
188
|
-
return ( attrName === 'id' ? uuidToLid : uuidToLidref )(
|
|
229
|
+
const propertyDescr = Object.getOwnPropertyDescriptor( domApi.prototype, relMap[ attrName ] );
|
|
230
|
+
if ( !propertyDescr ) continue;
|
|
231
|
+
Object.defineProperty( domApi.prototype, relMap[ attrName ], { ...propertyDescr, get() {
|
|
232
|
+
return ( attrName === 'id' ? $lidUtil.uuidToLid : $lidUtil.uuidToLidref ).call( $lidUtil, propertyDescr.get.call( this, attrName ) || '' );
|
|
189
233
|
} } );
|
|
190
234
|
}
|
|
191
235
|
}
|
|
192
|
-
//
|
|
236
|
+
// Hide implementation details on the Attr node too.
|
|
237
|
+
const propertyDescr = Object.getOwnPropertyDescriptor( window.Attr.prototype, 'value' );
|
|
238
|
+
Object.defineProperty( window.Attr.prototype, 'value', { ...propertyDescr, get() {
|
|
239
|
+
const value = propertyDescr.get.call( this );
|
|
240
|
+
return attrList.includes( this.name ) ? ( this.name === 'id' ? $lidUtil.uuidToLid : $lidUtil.uuidToLidref ).call( $lidUtil, value ) : value;
|
|
241
|
+
} } );
|
|
193
242
|
if ( config.attr.lid !== 'id' ) {
|
|
243
|
+
// Reflect the custom [config.attr.lid] attribute
|
|
194
244
|
Object.defineProperty( window.Element.prototype, config.attr.lid, { configurable: true, enumerable: true, get() {
|
|
195
245
|
return this.getAttribute( config.attr.lid );
|
|
196
246
|
}, set( value ) {
|
|
@@ -210,10 +260,10 @@ function realtime( config ) {
|
|
|
210
260
|
// Get down to work
|
|
211
261
|
const namespaceObj = _( entry ).get( 'ownerNamespace' );
|
|
212
262
|
if ( attrName === config.attr.lid ) {
|
|
213
|
-
const lid = uuidToLid( oldValue );
|
|
263
|
+
const lid = $lidUtil.uuidToLid( oldValue );
|
|
214
264
|
if ( Observer.get( namespaceObj, lid ) === entry ) { Observer.deleteProperty( namespaceObj, lid ); }
|
|
215
265
|
} else {
|
|
216
|
-
const newAttrValue = oldValue.split( ' ' ).map( lid => ( lid = lid.trim() ) && uuidToLidref( lid ) ).join( ' ' );
|
|
266
|
+
const newAttrValue = oldValue.split( ' ' ).map( lid => ( lid = lid.trim() ) && $lidUtil.uuidToLidref( lid ) ).join( ' ' );
|
|
217
267
|
entry.setAttribute( attrName, newAttrValue );
|
|
218
268
|
}
|
|
219
269
|
// Release locking
|
|
@@ -229,14 +279,14 @@ function realtime( config ) {
|
|
|
229
279
|
const namespaceObj = _( entry ).get( 'ownerNamespace' );
|
|
230
280
|
const namespaceUUID = _( entry ).get( 'namespaceUUID' );
|
|
231
281
|
if ( attrName === config.attr.lid ) {
|
|
232
|
-
const lid = uuidToLid( value );
|
|
282
|
+
const lid = $lidUtil.uuidToLid( value );
|
|
233
283
|
if ( Observer.get( namespaceObj, lid ) !== entry ) {
|
|
234
284
|
// Setup new namespace relationships
|
|
235
|
-
entry.setAttribute( 'id', toUuid( namespaceUUID, lid ) );
|
|
285
|
+
entry.setAttribute( 'id', $lidUtil.toUuid( namespaceUUID, lid ) );
|
|
236
286
|
Observer.set( namespaceObj, lid, entry );
|
|
237
287
|
}
|
|
238
288
|
} else {
|
|
239
|
-
const newAttrValue = value.split( ' ' ).map( lid => ( lid = lid.trim() ) &&
|
|
289
|
+
const newAttrValue = value.split( ' ' ).map( lid => ( lid = lid.trim() ) && !$lidUtil.isLidref( lid ) ? lid : $lidUtil.toUuid( namespaceUUID, lid.replace( $lidUtil.lidrefPrefix(), '' ) ) ).join( ' ' );
|
|
240
290
|
entry.setAttribute( attrName, newAttrValue );
|
|
241
291
|
}
|
|
242
292
|
// Release locking
|
|
@@ -297,8 +347,8 @@ function realtime( config ) {
|
|
|
297
347
|
// ------------
|
|
298
348
|
let prevTarget;
|
|
299
349
|
const activateTarget = () => {
|
|
300
|
-
if ( !window.location.hash?.startsWith( `#${ lidrefPrefix }` ) ) return;
|
|
301
|
-
const path = window.location.hash?.substring( `#${ lidrefPrefix }`.length ).split( '/' ).map( s => s.trim() ).filter( s => s ) || [];
|
|
350
|
+
if ( !window.location.hash?.startsWith( `#${ $lidUtil.lidrefPrefix() }` ) ) return;
|
|
351
|
+
const path = window.location.hash?.substring( `#${ $lidUtil.lidrefPrefix() }`.length ).split( '/' ).map( s => s.trim() ).filter( s => s ) || [];
|
|
302
352
|
const currTarget = path.reduce( ( prev, segment ) => prev && prev[ config.api.namespace ][ segment ], window.document );
|
|
303
353
|
if ( prevTarget && config.target.attr ) { prevTarget.toggleAttribute( config.target.attr, false ); }
|
|
304
354
|
if ( currTarget && currTarget !== window.document ) {
|
package/src/scoped-css/index.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* @imports
|
|
4
4
|
*/
|
|
5
|
-
import { rewriteSelector } from '../namespaced-html/index.js';
|
|
6
|
-
import { _init, _toHash
|
|
5
|
+
import { rewriteSelector, getNamespaceUUID } from '../namespaced-html/index.js';
|
|
6
|
+
import { _init, _toHash } from '../util.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @init
|
|
@@ -63,79 +63,85 @@ function realtime( config ) {
|
|
|
63
63
|
if ( handled.has( style ) ) return;
|
|
64
64
|
handled.add( style );
|
|
65
65
|
if ( !style.scoped ) return;
|
|
66
|
+
style.parentNode[ config.api.styleSheets ].push( style );
|
|
66
67
|
// Do compilation
|
|
67
68
|
const sourceHash = _toHash( style.textContent );
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
compiledSheet = createAdoptableStylesheet.call( window, style, scopeSelector );
|
|
72
|
-
//compiledSheet = style.sheet; upgradeSheet( style.sheet, /*!window.CSSScopeRule &&*/ scopeSelector );
|
|
73
|
-
oohtml.Style.compileCache.set( sourceHash, compiledSheet );
|
|
74
|
-
}
|
|
75
|
-
// Run now!!!
|
|
76
|
-
style.parentNode[ config.api.styleSheets ].push( style );
|
|
77
|
-
Object.defineProperty( style, 'sheet', { value: compiledSheet, configurable: true } );
|
|
69
|
+
const supportsHAS = CSS.supports( 'selector(:has(a,b))' );
|
|
70
|
+
const scopeSelector = supportsHAS ? `:has(> style[rand-${ sourceHash }])` : `[rand-${ sourceHash }]`;
|
|
71
|
+
const supportsScope = window.CSSScopeRule && false/* Disabled for buggy behaviour: rewriting selectorText within an @scope block invalidates the scoping */;
|
|
78
72
|
( supportsHAS ? style : style.parentNode ).toggleAttribute( `rand-${ sourceHash }`, true );
|
|
79
|
-
|
|
73
|
+
if ( false ) {
|
|
74
|
+
let compiledSheet;
|
|
75
|
+
if ( !( compiledSheet = oohtml.Style.compileCache.get( sourceHash ) ) ) {
|
|
76
|
+
compiledSheet = createAdoptableStylesheet.call( window, style, null, supportsScope, scopeSelector );
|
|
77
|
+
oohtml.Style.compileCache.set( sourceHash, compiledSheet );
|
|
78
|
+
}
|
|
79
|
+
// Run now!!!
|
|
80
|
+
Object.defineProperty( style, 'sheet', { value: compiledSheet, configurable: true } );
|
|
81
|
+
style.textContent = '\n/*[ Shared style sheet ]*/\n';
|
|
82
|
+
} else {
|
|
83
|
+
const namespaceUUID = getNamespaceUUID.call( window, style );
|
|
84
|
+
upgradeSheet.call( this, style.sheet, namespaceUUID, !supportsScope && scopeSelector );
|
|
85
|
+
}
|
|
80
86
|
} );
|
|
81
87
|
}, { live: true, timing: 'intercept', generation: 'entrants' } );
|
|
82
88
|
// ---
|
|
83
89
|
}
|
|
84
90
|
|
|
85
|
-
function createAdoptableStylesheet( style, scopeSelector ) {
|
|
86
|
-
const window = this, textContent = style.textContent
|
|
91
|
+
function createAdoptableStylesheet( style, namespaceUUID, supportsScope, scopeSelector ) {
|
|
92
|
+
const window = this, textContent = style.textContent;
|
|
87
93
|
let styleSheet, cssText = supportsScope ? `@scope (${ scopeSelector }) {\n${ textContent.trim() }\n}` : textContent.trim();
|
|
88
94
|
try {
|
|
89
95
|
styleSheet = new window.CSSStyleSheet;
|
|
90
96
|
styleSheet.replaceSync( cssText );
|
|
91
|
-
upgradeSheet( styleSheet, !supportsScope && scopeSelector );
|
|
97
|
+
upgradeSheet.call( this, styleSheet, namespaceUUID, !supportsScope && scopeSelector );
|
|
92
98
|
document.adoptedStyleSheets.push( styleSheet );
|
|
93
99
|
} catch( e ) {
|
|
94
100
|
const style = window.document.createElement( 'style' );
|
|
95
101
|
window.document.body.appendChild( style );
|
|
96
102
|
style.textContent = cssText;
|
|
97
103
|
styleSheet = style.sheet;
|
|
98
|
-
upgradeSheet( styleSheet, !supportsScope && scopeSelector );
|
|
104
|
+
upgradeSheet.call( this, styleSheet, namespaceUUID, !supportsScope && scopeSelector );
|
|
99
105
|
}
|
|
100
106
|
return styleSheet;
|
|
101
107
|
}
|
|
102
108
|
|
|
103
|
-
function upgradeSheet( styleSheet, scopeSelector = null ) {
|
|
109
|
+
function upgradeSheet( styleSheet, namespaceUUID, scopeSelector = null ) {
|
|
104
110
|
const l = styleSheet?.cssRules.length || -1;
|
|
105
111
|
for ( let i = 0; i < l; ++i ) {
|
|
106
112
|
const cssRule = styleSheet.cssRules[ i ];
|
|
107
113
|
if ( cssRule instanceof CSSImportRule ) {
|
|
108
114
|
// Handle imported stylesheets
|
|
109
|
-
//upgradeSheet( cssRule.styleSheet, scopeSelector );
|
|
115
|
+
//upgradeSheet( cssRule.styleSheet, namespaceUUID, scopeSelector );
|
|
110
116
|
continue;
|
|
111
117
|
}
|
|
112
|
-
upgradeRule( cssRule, scopeSelector );
|
|
118
|
+
upgradeRule.call( this, cssRule, namespaceUUID, scopeSelector );
|
|
113
119
|
}
|
|
114
120
|
}
|
|
115
121
|
|
|
116
|
-
function upgradeRule( cssRule, scopeSelector = null ) {
|
|
122
|
+
function upgradeRule( cssRule, namespaceUUID, scopeSelector = null ) {
|
|
117
123
|
if ( cssRule instanceof CSSStyleRule ) {
|
|
118
124
|
// Resolve relative IDs and scoping (for non-@scope browsers)
|
|
119
|
-
upgradeSelector( cssRule, scopeSelector );
|
|
125
|
+
upgradeSelector.call( this, cssRule, namespaceUUID, scopeSelector );
|
|
120
126
|
return;
|
|
121
127
|
}
|
|
122
128
|
if ( [ window.CSSScopeRule, window.CSSMediaRule, window.CSSContainerRule, window.CSSSupportsRule, window.CSSLayerBlockRule ].some( type => type && cssRule instanceof type ) ) {
|
|
123
129
|
// Parse @rule blocks
|
|
124
130
|
const l = cssRule.cssRules.length;
|
|
125
131
|
for ( let i = 0; i < l; ++i ) {
|
|
126
|
-
upgradeRule( cssRule.cssRules[ i ], scopeSelector );
|
|
132
|
+
upgradeRule.call( this, cssRule.cssRules[ i ], namespaceUUID, scopeSelector );
|
|
127
133
|
}
|
|
128
134
|
}
|
|
129
135
|
}
|
|
130
136
|
|
|
131
|
-
function upgradeSelector( cssRule, scopeSelector = null ) {
|
|
132
|
-
const newSelectorText = rewriteSelector( cssRule.selectorText, scopeSelector,
|
|
137
|
+
function upgradeSelector( cssRule, namespaceUUID, scopeSelector = null ) {
|
|
138
|
+
const newSelectorText = rewriteSelector.call( this, cssRule.selectorText, namespaceUUID, scopeSelector, 1 );
|
|
133
139
|
cssRule.selectorText = newSelectorText;
|
|
134
140
|
// Parse nested blocks. (CSS nesting)
|
|
135
141
|
if ( cssRule.cssRules ) {
|
|
136
142
|
const l = cssRule.cssRules.length;
|
|
137
143
|
for ( let i = 0; i < l; ++i ) {
|
|
138
|
-
upgradeSelector( cssRule.cssRules[ i ], /* Nesting has nothing to do with scopeSelector */ );
|
|
144
|
+
upgradeSelector.call( this, cssRule.cssRules[ i ], namespaceUUID, /* Nesting has nothing to do with scopeSelector */ );
|
|
139
145
|
}
|
|
140
146
|
}
|
|
141
147
|
}
|