jtlt 0.4.0 → 0.6.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.
Files changed (34) hide show
  1. package/CHANGES.md +16 -0
  2. package/demo/index.css +4 -0
  3. package/demo/index.html +4 -4
  4. package/demo/index.js +6 -2
  5. package/demo/vendor/fontoxpath/dist/fontoxpath.esm.js +600 -0
  6. package/demo/vendor/prsc/dist/prsc.esm.js +2 -0
  7. package/demo/vendor/whynot/dist/whynot.esm.js +2 -0
  8. package/demo/vendor/xspattern/dist/xspattern.esm.js +2 -0
  9. package/dist/AbstractJoiningTransformer.d.ts +35 -0
  10. package/dist/AbstractJoiningTransformer.d.ts.map +1 -1
  11. package/dist/DOMJoiningTransformer.d.ts +85 -8
  12. package/dist/DOMJoiningTransformer.d.ts.map +1 -1
  13. package/dist/JSONJoiningTransformer.d.ts +28 -10
  14. package/dist/JSONJoiningTransformer.d.ts.map +1 -1
  15. package/dist/JSONPathTransformer.d.ts.map +1 -1
  16. package/dist/JSONPathTransformerContext.d.ts +168 -3
  17. package/dist/JSONPathTransformerContext.d.ts.map +1 -1
  18. package/dist/StringJoiningTransformer.d.ts +25 -8
  19. package/dist/StringJoiningTransformer.d.ts.map +1 -1
  20. package/dist/XPathTransformer.d.ts.map +1 -1
  21. package/dist/XPathTransformerContext.d.ts +107 -1
  22. package/dist/XPathTransformerContext.d.ts.map +1 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/docs/TO-DO.md +38 -36
  25. package/package.json +6 -2
  26. package/src/AbstractJoiningTransformer.js +53 -0
  27. package/src/DOMJoiningTransformer.js +199 -24
  28. package/src/JSONJoiningTransformer.js +89 -27
  29. package/src/JSONPathTransformer.js +2 -0
  30. package/src/JSONPathTransformerContext.js +572 -9
  31. package/src/StringJoiningTransformer.js +60 -22
  32. package/src/XPathTransformer.js +2 -0
  33. package/src/XPathTransformerContext.js +487 -11
  34. package/src/index.js +7 -1
@@ -36,7 +36,7 @@ function _makeDatasetAttribute (n0) {
36
36
  * plus special helpers: dataset (object) and $a (ordered attribute array).
37
37
  * @typedef {Record<string, unknown> & {
38
38
  * dataset?: Record<string, string>,
39
- * $a?: Array<[string, string]>
39
+ * $a?: [string, string][]
40
40
  * }} ElementAttributes
41
41
  */
42
42
 
@@ -142,6 +142,16 @@ class JSONJoiningTransformer extends AbstractJoiningTransformer {
142
142
  (/** @type {Record<string, any>} */ (this._obj))[prop] = val;
143
143
  }
144
144
 
145
+ /**
146
+ * Alias for propValue(). Set a key-value pair in the current map/object.
147
+ * @param {string} prop - Property name
148
+ * @param {any} val - Property value
149
+ * @returns {void}
150
+ */
151
+ mapEntry (prop, val) {
152
+ return this.propValue(prop, val);
153
+ }
154
+
145
155
  /* c8 ignore next 13 -- JSDoc block incorrectly counted as coverable by c8 */
146
156
  /**
147
157
  * @param {Record<string, unknown>|ObjectCallback} [objOrCb]
@@ -207,6 +217,22 @@ class JSONJoiningTransformer extends AbstractJoiningTransformer {
207
217
  return this;
208
218
  }
209
219
 
220
+ /**
221
+ * Alias for object(). Build an object/map.
222
+ * @param {Record<string, unknown>|ObjectCallback} [objOrCb]
223
+ * Seed object or callback.
224
+ * @param {ObjectCallback|any[]} [cbOrUsePropertySets] Callback or sets.
225
+ * @param {any[]|Record<string, unknown>} [usePropertySetsOrPropSets]
226
+ * Sets or prop sets.
227
+ * @param {Record<string, unknown>} [propSets] Key-value pairs to add.
228
+ * @returns {JSONJoiningTransformer}
229
+ */
230
+ map (objOrCb, cbOrUsePropertySets, usePropertySetsOrPropSets, propSets) {
231
+ return this.object(
232
+ objOrCb, cbOrUsePropertySets, usePropertySetsOrPropSets, propSets
233
+ );
234
+ }
235
+
210
236
  /**
211
237
  * Creates a new array and executes a callback in its context.
212
238
  * @param {any[]|ArrayCallback} [arrOrCb] Seed array or callback.
@@ -329,20 +355,6 @@ class JSONJoiningTransformer extends AbstractJoiningTransformer {
329
355
  return this;
330
356
  }
331
357
 
332
- /**
333
- * @param {import('./StringJoiningTransformer.js').OutputConfig} cfg
334
- * @returns {JSONJoiningTransformer}
335
- */
336
- output (cfg) {
337
- // We wait until first element is set in `element()` to add
338
- // XML declaration and DOCTYPE as latter depends on root element
339
- this._outputConfig = cfg;
340
-
341
- // Use for file extension if making downloadable?
342
- this.mediaType = cfg.mediaType;
343
- return this;
344
- }
345
-
346
358
  /**
347
359
  * Build a Jamilih-style element JSON array and append to current container.
348
360
  * Result form: ['tag', {attr: 'val'}, child1, child2, ...]
@@ -353,9 +365,10 @@ class JSONJoiningTransformer extends AbstractJoiningTransformer {
353
365
  * Attrs, children, or cb.
354
366
  * @param {any[]|SimpleCallback} [childNodes] Children or cb.
355
367
  * @param {SimpleCallback} [cb] Builder callback.
368
+ * @param {string[]} [useAttributeSets] - Attribute set names to apply
356
369
  * @returns {JSONJoiningTransformer}
357
370
  */
358
- element (elName, atts, childNodes, cb) {
371
+ element (elName, atts, childNodes, cb, useAttributeSets) {
359
372
  this._requireSameChildren('json', 'element');
360
373
  const isRoot = !this.root;
361
374
  if (isRoot) {
@@ -393,6 +406,17 @@ class JSONJoiningTransformer extends AbstractJoiningTransformer {
393
406
  /** @type {import('jamilih').JamilihChildren} */
394
407
  const jmlChildren = [];
395
408
 
409
+ // Apply attribute sets if specified
410
+ if (useAttributeSets && useAttributeSets.length) {
411
+ const mergedAtts = {};
412
+ useAttributeSets.forEach((setName) => {
413
+ if (this._attributeSet[setName]) {
414
+ Object.assign(mergedAtts, this._attributeSet[setName]);
415
+ }
416
+ });
417
+ attsObj = Object.assign(mergedAtts, attsObj);
418
+ }
419
+
396
420
  // Preprocess special attribute helpers present directly on attsObj
397
421
  if (attsObj.dataset && typeof attsObj.dataset === 'object' &&
398
422
  !Array.isArray(attsObj.dataset)
@@ -401,23 +425,35 @@ class JSONJoiningTransformer extends AbstractJoiningTransformer {
401
425
  for (const k in ds) {
402
426
  if (Object.hasOwn(ds, k)) {
403
427
  const dashed = k.replaceAll(camelCase, _makeDatasetAttribute);
404
- attsObj['data-' + dashed] = ds[k];
428
+ attsObj['data-' + dashed] = this._replaceCharacterMaps(ds[k]);
405
429
  }
406
430
  }
407
431
  delete attsObj.dataset;
408
432
  }
409
433
  if (Array.isArray(attsObj.$a)) {
410
- (/** @type {unknown[][]} */ (attsObj.$a)).forEach((pair) => {
434
+ attsObj.$a.forEach((pair) => {
411
435
  if (Array.isArray(pair) && pair.length > 1) {
412
- attsObj[String(pair[0])] = pair[1];
436
+ attsObj[String(pair[0])] = this._replaceCharacterMaps(pair[1]);
413
437
  }
414
438
  });
415
439
  delete attsObj.$a;
416
440
  }
417
441
 
442
+ // Apply character maps to all regular attribute values
443
+ for (const key in attsObj) {
444
+ if (Object.hasOwn(attsObj, key) && typeof attsObj[key] === 'string') {
445
+ attsObj[key] = this._replaceCharacterMaps(attsObj[key]);
446
+ }
447
+ }
448
+
418
449
  // If children provided as array, copy (may be primitives or nested JML)
419
450
  if (Array.isArray(childNodes) && childNodes.length) {
420
- jmlChildren.push(...childNodes);
451
+ jmlChildren.push(...childNodes.map((childNode) => {
452
+ if (typeof childNode === 'string') {
453
+ return this._replaceCharacterMaps(childNode);
454
+ }
455
+ return childNode;
456
+ }));
421
457
  }
422
458
 
423
459
  // Callback-driven building (attribute/text/nested element mutate stack)
@@ -435,9 +471,10 @@ class JSONJoiningTransformer extends AbstractJoiningTransformer {
435
471
  /** @type {any[]} */
436
472
  const jmlEl = [elementName];
437
473
  if (Object.keys(attsObj).length) {
438
- jmlEl.push(attsObj);
474
+ jmlEl.push(attsObj, jmlChildren);
475
+ } else {
476
+ jmlEl.push(jmlChildren);
439
477
  }
440
- jmlEl.push(...jmlChildren);
441
478
 
442
479
  if (isRoot) {
443
480
  // todo: indent, cdataSectionElements
@@ -490,6 +527,29 @@ class JSONJoiningTransformer extends AbstractJoiningTransformer {
490
527
  return this;
491
528
  }
492
529
 
530
+ /**
531
+ * @param {string} prefix
532
+ * @param {string} namespaceURI
533
+ * @returns {JSONJoiningTransformer}
534
+ */
535
+ namespace (prefix, namespaceURI) {
536
+ if (!this._elementStack.length) {
537
+ // No-op outside an element() callback (JSON joiner semantics)
538
+ return this;
539
+ }
540
+ const top = /** @type {ElementInfo} */ (this._elementStack.at(-1));
541
+ const {attsObj} = top;
542
+
543
+ if (!attsObj.xmlns) {
544
+ attsObj.xmlns = {};
545
+ }
546
+
547
+ /** @type {Record<string, string>} */
548
+ (attsObj.xmlns)[prefix] = this._replaceCharacterMaps(namespaceURI);
549
+
550
+ return this;
551
+ }
552
+
493
553
  /**
494
554
  * Adds/updates an attribute for the most recently open element built via
495
555
  * a callback-driven element(). When not in an element callback context,
@@ -513,20 +573,22 @@ class JSONJoiningTransformer extends AbstractJoiningTransformer {
513
573
  for (const k in datasetObj) {
514
574
  if (Object.hasOwn(datasetObj, k)) {
515
575
  const dashed = k.replaceAll(camelCase, _makeDatasetAttribute);
516
- attsObj['data-' + dashed] = datasetObj[k];
576
+ attsObj['data-' + dashed] = this._replaceCharacterMaps(
577
+ /** @type {string} */ (datasetObj[k])
578
+ );
517
579
  }
518
580
  }
519
581
  return this;
520
582
  }
521
583
  if (name === '$a' && Array.isArray(val)) {
522
- (/** @type {unknown[][]} */ (val)).forEach((pair) => {
584
+ val.forEach((pair) => {
523
585
  if (Array.isArray(pair) && pair.length > 1) {
524
- attsObj[String(pair[0])] = pair[1];
586
+ attsObj[String(pair[0])] = this._replaceCharacterMaps(pair[1]);
525
587
  }
526
588
  });
527
589
  return this;
528
590
  }
529
- attsObj[name] = val;
591
+ attsObj[name] = this._replaceCharacterMaps(/** @type {string} */ (val));
530
592
  return this;
531
593
  }
532
594
 
@@ -578,7 +640,7 @@ class JSONJoiningTransformer extends AbstractJoiningTransformer {
578
640
  if (this._elementStack.length) {
579
641
  const top = /** @type {ElementInfo} */ (this._elementStack.at(-1));
580
642
  const {jmlChildren} = top;
581
- jmlChildren.push(['!', txt]);
643
+ jmlChildren.push(this._replaceCharacterMaps(txt));
582
644
  return this;
583
645
  }
584
646
  // No-op outside element context in JSON joiner
@@ -70,6 +70,8 @@ class JSONPathTransformer {
70
70
  if (len > 1) {
71
71
  this._triggerEqualPriorityError();
72
72
  }
73
+ // Set up parameter context for valueOf() access in root template
74
+ jte._params = {0: jte._contextObj};
73
75
  const ret = /** @type {import('./index.js').JSONPathTemplateObject<T>} */ (
74
76
  templateObj
75
77
  ).template.call(jte, undefined, {mode});