assign-gingerly 0.0.36 → 0.0.38
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/object-extension.js +2 -2
- package/object-extension.ts +3 -3
- package/package.json +1 -1
- package/parseWithAttrs.js +19 -4
- package/parseWithAttrs.ts +24 -6
- package/types/assign-gingerly/types.d.ts +7 -0
package/object-extension.js
CHANGED
|
@@ -138,7 +138,7 @@ class ElementEnhancementContainer {
|
|
|
138
138
|
}
|
|
139
139
|
// Check if there's an enhKey
|
|
140
140
|
if (registryItem.enhKey) {
|
|
141
|
-
const ctx = { config: registryItem, mountCtx };
|
|
141
|
+
const ctx = { config: registryItem, mountCtx, emc: mountCtx?.emc };
|
|
142
142
|
const self = this;
|
|
143
143
|
// Get existing initVals from enhKey
|
|
144
144
|
const existingInitVals = self[registryItem.enhKey] &&
|
|
@@ -155,7 +155,7 @@ class ElementEnhancementContainer {
|
|
|
155
155
|
}
|
|
156
156
|
else {
|
|
157
157
|
// No enhKey, still pass attrInitVals
|
|
158
|
-
const ctx = { config: registryItem, mountCtx };
|
|
158
|
+
const ctx = { config: registryItem, mountCtx, emc: mountCtx?.emc };
|
|
159
159
|
instance = new SpawnClass(element, ctx, attrInitVals);
|
|
160
160
|
}
|
|
161
161
|
// Store in global instance map
|
package/object-extension.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import assignGingerly, { EnhancementRegistry, ItemscopeRegistry, IAssignGingerlyOptions, getInstanceMap, INSTANCE_MAP_GUID } from './assignGingerly.js';
|
|
2
|
-
import { EnhancementConfig } from './types/assign-gingerly/types.js';
|
|
2
|
+
import { EnhancementConfig, SpawnContext } from './types/assign-gingerly/types.js';
|
|
3
3
|
import { parseWithAttrs } from './parseWithAttrs.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -225,7 +225,7 @@ class ElementEnhancementContainer {
|
|
|
225
225
|
|
|
226
226
|
// Check if there's an enhKey
|
|
227
227
|
if (registryItem.enhKey) {
|
|
228
|
-
const ctx = { config: registryItem, mountCtx };
|
|
228
|
+
const ctx: SpawnContext = { config: registryItem, mountCtx, emc: (mountCtx as any)?.emc };
|
|
229
229
|
const self = this as any;
|
|
230
230
|
|
|
231
231
|
// Get existing initVals from enhKey
|
|
@@ -245,7 +245,7 @@ class ElementEnhancementContainer {
|
|
|
245
245
|
self[registryItem.enhKey] = instance;
|
|
246
246
|
} else {
|
|
247
247
|
// No enhKey, still pass attrInitVals
|
|
248
|
-
const ctx = { config: registryItem, mountCtx };
|
|
248
|
+
const ctx: SpawnContext = { config: registryItem, mountCtx, emc: (mountCtx as any)?.emc };
|
|
249
249
|
instance = new SpawnClass(element, ctx, attrInitVals);
|
|
250
250
|
}
|
|
251
251
|
|
package/package.json
CHANGED
package/parseWithAttrs.js
CHANGED
|
@@ -143,10 +143,15 @@ function hasDashOrNonASCII(str) {
|
|
|
143
143
|
* Gets attribute value with smart enh- prefix handling
|
|
144
144
|
* @param element - The element to read from
|
|
145
145
|
* @param attrName - The attribute name (without enh- prefix)
|
|
146
|
-
* @param allowUnprefixed - Pattern (string or RegExp) that element tag name must match to allow unprefixed attributes
|
|
146
|
+
* @param allowUnprefixed - Pattern (string or RegExp) that element tag name must match to allow unprefixed attributes,
|
|
147
|
+
* or `true` for custom element mode (read attributes directly, no enh- prefix)
|
|
147
148
|
* @returns The attribute value or null
|
|
148
149
|
*/
|
|
149
150
|
function getAttributeValue(element, attrName, allowUnprefixed) {
|
|
151
|
+
// Custom element mode - read attribute directly, no enh- prefix
|
|
152
|
+
if (allowUnprefixed === true) {
|
|
153
|
+
return element.getAttribute(attrName);
|
|
154
|
+
}
|
|
150
155
|
const { localName } = element;
|
|
151
156
|
const isCustomElement = localName.includes('-');
|
|
152
157
|
const isSVGElement = typeof SVGElement !== 'undefined' && element instanceof SVGElement;
|
|
@@ -222,15 +227,18 @@ function getDefaultParser(instanceOf) {
|
|
|
222
227
|
* Parses attributes from an element based on AttrPatterns configuration
|
|
223
228
|
* @param element - The DOM element to read attributes from
|
|
224
229
|
* @param attrPatterns - The attribute patterns configuration
|
|
225
|
-
* @param allowUnprefixed - Pattern (string or RegExp) that element tag name must match to allow unprefixed attributes
|
|
230
|
+
* @param allowUnprefixed - Pattern (string or RegExp) that element tag name must match to allow unprefixed attributes,
|
|
231
|
+
* or `true` for custom element mode: reads attributes directly (no enh- prefix),
|
|
232
|
+
* skips base attribute dash validation, and skips properties already set on the element
|
|
226
233
|
* @param spawnContext - Optional spawn context containing enhancement config and synthesizer element
|
|
227
234
|
* @returns Object with parsed attribute values ready for initVals
|
|
228
235
|
*/
|
|
229
236
|
export function parseWithAttrs(element, attrPatterns, allowUnprefixed, spawnContext) {
|
|
230
237
|
// Extract synthesizerElement from spawnContext for backward compatibility
|
|
231
238
|
const synthesizerElement = spawnContext?.synthesizerElement;
|
|
232
|
-
|
|
233
|
-
if (
|
|
239
|
+
const isCustomElementMode = allowUnprefixed === true;
|
|
240
|
+
// Validate base attribute if present (skip in custom element mode)
|
|
241
|
+
if ('base' in attrPatterns && !isCustomElementMode) {
|
|
234
242
|
const baseValue = attrPatterns.base;
|
|
235
243
|
if (!hasDashOrNonASCII(baseValue)) {
|
|
236
244
|
throw new Error(`Invalid base attribute "${baseValue}": must contain a dash (-) or non-ASCII character. ` +
|
|
@@ -284,6 +292,13 @@ export function parseWithAttrs(element, attrPatterns, allowUnprefixed, spawnCont
|
|
|
284
292
|
}
|
|
285
293
|
// Second pass: read attributes and parse values
|
|
286
294
|
for (const [key, { attrName, config }] of resolvedAttrs) {
|
|
295
|
+
// In custom element mode, skip properties already set on the element
|
|
296
|
+
if (isCustomElementMode) {
|
|
297
|
+
const mapsTo = config.mapsTo ?? (key === 'base' ? '.' : key);
|
|
298
|
+
if (mapsTo !== '.' && element[mapsTo] !== undefined) {
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
287
302
|
const attrValue = getAttributeValue(element, attrName, allowUnprefixed);
|
|
288
303
|
// Create parser context
|
|
289
304
|
const parserContext = {
|
package/parseWithAttrs.ts
CHANGED
|
@@ -178,14 +178,20 @@ function hasDashOrNonASCII(str: string): boolean {
|
|
|
178
178
|
* Gets attribute value with smart enh- prefix handling
|
|
179
179
|
* @param element - The element to read from
|
|
180
180
|
* @param attrName - The attribute name (without enh- prefix)
|
|
181
|
-
* @param allowUnprefixed - Pattern (string or RegExp) that element tag name must match to allow unprefixed attributes
|
|
181
|
+
* @param allowUnprefixed - Pattern (string or RegExp) that element tag name must match to allow unprefixed attributes,
|
|
182
|
+
* or `true` for custom element mode (read attributes directly, no enh- prefix)
|
|
182
183
|
* @returns The attribute value or null
|
|
183
184
|
*/
|
|
184
185
|
function getAttributeValue(
|
|
185
186
|
element: Element,
|
|
186
187
|
attrName: string,
|
|
187
|
-
allowUnprefixed?: string | RegExp
|
|
188
|
+
allowUnprefixed?: string | RegExp | true
|
|
188
189
|
): string | null {
|
|
190
|
+
// Custom element mode - read attribute directly, no enh- prefix
|
|
191
|
+
if (allowUnprefixed === true) {
|
|
192
|
+
return element.getAttribute(attrName);
|
|
193
|
+
}
|
|
194
|
+
|
|
189
195
|
const { localName } = element;
|
|
190
196
|
const isCustomElement = localName.includes('-');
|
|
191
197
|
const isSVGElement = typeof SVGElement !== 'undefined' && element instanceof SVGElement;
|
|
@@ -261,21 +267,25 @@ function getDefaultParser(instanceOf?: string | Function): ParserFunction {
|
|
|
261
267
|
* Parses attributes from an element based on AttrPatterns configuration
|
|
262
268
|
* @param element - The DOM element to read attributes from
|
|
263
269
|
* @param attrPatterns - The attribute patterns configuration
|
|
264
|
-
* @param allowUnprefixed - Pattern (string or RegExp) that element tag name must match to allow unprefixed attributes
|
|
270
|
+
* @param allowUnprefixed - Pattern (string or RegExp) that element tag name must match to allow unprefixed attributes,
|
|
271
|
+
* or `true` for custom element mode: reads attributes directly (no enh- prefix),
|
|
272
|
+
* skips base attribute dash validation, and skips properties already set on the element
|
|
265
273
|
* @param spawnContext - Optional spawn context containing enhancement config and synthesizer element
|
|
266
274
|
* @returns Object with parsed attribute values ready for initVals
|
|
267
275
|
*/
|
|
268
276
|
export function parseWithAttrs<T = any>(
|
|
269
277
|
element: Element,
|
|
270
278
|
attrPatterns: AttrPatterns<T>,
|
|
271
|
-
allowUnprefixed?: string | RegExp,
|
|
279
|
+
allowUnprefixed?: string | RegExp | true,
|
|
272
280
|
spawnContext?: SpawnContext<T>
|
|
273
281
|
): Partial<T> {
|
|
274
282
|
// Extract synthesizerElement from spawnContext for backward compatibility
|
|
275
283
|
const synthesizerElement = spawnContext?.synthesizerElement;
|
|
276
284
|
|
|
277
|
-
|
|
278
|
-
|
|
285
|
+
const isCustomElementMode = allowUnprefixed === true;
|
|
286
|
+
|
|
287
|
+
// Validate base attribute if present (skip in custom element mode)
|
|
288
|
+
if ('base' in attrPatterns && !isCustomElementMode) {
|
|
279
289
|
const baseValue = attrPatterns.base as string;
|
|
280
290
|
if (!hasDashOrNonASCII(baseValue)) {
|
|
281
291
|
throw new Error(
|
|
@@ -341,6 +351,14 @@ export function parseWithAttrs<T = any>(
|
|
|
341
351
|
|
|
342
352
|
// Second pass: read attributes and parse values
|
|
343
353
|
for (const [key, { attrName, config }] of resolvedAttrs) {
|
|
354
|
+
// In custom element mode, skip properties already set on the element
|
|
355
|
+
if (isCustomElementMode) {
|
|
356
|
+
const mapsTo = config.mapsTo ?? (key === 'base' ? '.' : key);
|
|
357
|
+
if (mapsTo !== '.' && (element as any)[mapsTo as string] !== undefined) {
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
344
362
|
const attrValue = getAttributeValue(element, attrName, allowUnprefixed);
|
|
345
363
|
|
|
346
364
|
// Create parser context
|
|
@@ -212,6 +212,13 @@ export interface SpawnContext<T = any, TMountContext = any> {
|
|
|
212
212
|
* Used for scoped parser registry access during attribute parsing.
|
|
213
213
|
*/
|
|
214
214
|
synthesizerElement?: Element;
|
|
215
|
+
/**
|
|
216
|
+
* The full EMC configuration object that triggered this spawn.
|
|
217
|
+
* Passed through so enhancement classes can access their full configuration
|
|
218
|
+
* (including customData) without needing to separately import the JSON file.
|
|
219
|
+
* This avoids duplicate JSON imports when using emoji shorthand aliases.
|
|
220
|
+
*/
|
|
221
|
+
emc?: any;
|
|
215
222
|
}
|
|
216
223
|
|
|
217
224
|
/**
|