@jqhtml/core 2.3.54 → 2.3.61

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.
@@ -17,7 +17,8 @@ export interface ComponentInstruction {
17
17
  export interface SlotInstruction {
18
18
  slot: [string, Record<string, any>, (context: any) => [any[], Jqhtml_Component]];
19
19
  }
20
- export type Instruction = TagInstruction | RawTagInstruction | ComponentInstruction | SlotInstruction | string;
20
+ export type ContentInstruction = ['_content', Instruction[], Jqhtml_Component?];
21
+ export type Instruction = TagInstruction | RawTagInstruction | ComponentInstruction | SlotInstruction | ContentInstruction | string;
21
22
  export declare function uid(): string;
22
23
  /**
23
24
  * Process an array of instructions and append to target
@@ -1 +1 @@
1
- {"version":3,"file":"instruction-processor.d.ts","sourceRoot":"","sources":["../src/instruction-processor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAKlD,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC;CAClL;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC;CAClF;AAED,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,iBAAiB,GAAG,oBAAoB,GAAG,eAAe,GAAG,MAAM,CAAC;AAqB/G,wBAAgB,GAAG,IAAI,MAAM,CA2C5B;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,WAAW,EAAE,EAC3B,MAAM,EAAE,GAAG,EACX,OAAO,EAAE,gBAAgB,EACzB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GACtC,IAAI,CAwCN;AAogBD;;GAEG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAW1F"}
1
+ {"version":3,"file":"instruction-processor.d.ts","sourceRoot":"","sources":["../src/instruction-processor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAKlD,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC;CAClL;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC;CAClF;AAQD,MAAM,MAAM,kBAAkB,GAAG,CAAC,UAAU,EAAE,WAAW,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAEhF,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,iBAAiB,GAAG,oBAAoB,GAAG,eAAe,GAAG,kBAAkB,GAAG,MAAM,CAAC;AAqBpI,wBAAgB,GAAG,IAAI,MAAM,CA2C5B;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,WAAW,EAAE,EAC3B,MAAM,EAAE,GAAG,EACX,OAAO,EAAE,gBAAgB,EACzB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GACtC,IAAI,CA0CN;AAyhBD;;GAEG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAW1F"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * JQHTML Core v2.3.54
2
+ * JQHTML Core v2.3.61
3
3
  * (c) 2025 JQHTML Team
4
4
  * Released under the MIT License
5
5
  */
@@ -639,7 +639,9 @@ function process_instructions(instructions, target, context, slots) {
639
639
  if (el) {
640
640
  const element = $(el);
641
641
  el.removeAttribute('data-tid');
642
- apply_attributes(element, tagData.attrs, context);
642
+ // Bind to the component whose template wrote this element, which for
643
+ // spliced content is not the component being rendered.
644
+ apply_attributes(element, tagData.attrs, tagData.context);
643
645
  }
644
646
  }
645
647
  // Third pass: initialize and boot components in parallel
@@ -665,6 +667,16 @@ function process_instruction_to_html(instruction, html, tagElements, components,
665
667
  // Raw HTML/text - no escaping, as requested
666
668
  html.push(instruction);
667
669
  }
670
+ else if (Array.isArray(instruction)) {
671
+ if (instruction[0] !== '_content' || !Array.isArray(instruction[1])) {
672
+ return;
673
+ }
674
+ // Content written in another template renders in that template's component.
675
+ const definer = instruction[2] || context;
676
+ for (const item of instruction[1]) {
677
+ process_instruction_to_html(item, html, tagElements, components, definer, slots);
678
+ }
679
+ }
668
680
  else if ('tag' in instruction) {
669
681
  // HTML tag
670
682
  process_tag_to_html(instruction, html, tagElements, components, context);
@@ -861,11 +873,22 @@ function process_rawtag_to_html(instruction, html) {
861
873
  }
862
874
  }
863
875
  html.push('>');
864
- // Add raw content - escape HTML entities but preserve whitespace
865
- const escaped_content = rawContent
866
- .replace(/&/g, '&amp;')
867
- .replace(/</g, '&lt;')
868
- .replace(/>/g, '&gt;');
876
+ // Add raw content, preserving whitespace.
877
+ //
878
+ // <textarea> holds text and nothing else, so everything is escaped.
879
+ //
880
+ // <pre> holds phrasing content - <pre><code> is the standard code-block idiom - so
881
+ // markup the author wrote is passed through. A '<' that does not begin a tag is
882
+ // still escaped, which is what the HTML tokenizer itself does with a stray '<' and
883
+ // keeps code samples such as "if (a < b)" rendering as written. Interpolated
884
+ // values are escaped by the compiler before they reach this point.
885
+ const is_raw_html_content = tagName.toLowerCase() === 'pre';
886
+ const escaped_content = is_raw_html_content
887
+ ? rawContent.replace(/<(?![a-zA-Z/!?])/g, '&lt;')
888
+ : rawContent
889
+ .replace(/&/g, '&amp;')
890
+ .replace(/</g, '&lt;')
891
+ .replace(/>/g, '&gt;');
869
892
  html.push(escaped_content);
870
893
  // Close tag
871
894
  html.push(`</${tagName}>`);
@@ -1537,6 +1560,11 @@ class Load_Coordinator {
1537
1560
  }
1538
1561
  if (!uncacheable_property) {
1539
1562
  uncacheable_property = key;
1563
+ // This package compiles with strictNullChecks off, and without it
1564
+ // TypeScript will not narrow a discriminated union by its boolean
1565
+ // discriminant - so `serialized` is still the full Serialize_Result
1566
+ // here even though `ok` has been ruled out above. The cast states
1567
+ // what the control flow already guarantees.
1540
1568
  uncacheable_reason = serialized.reason;
1541
1569
  }
1542
1570
  return { key: null, uncacheable_property, uncacheable_reason };
@@ -1824,7 +1852,7 @@ Load_Coordinator._registry = new Map();
1824
1852
  const class_registry = Object.create(null);
1825
1853
  // Markers for serialized class instances (unique to avoid collisions with user data)
1826
1854
  // Replaced at build time by rollup (see rollup.config.js).
1827
- const CORE_VERSION = '2.3.54';
1855
+ const CORE_VERSION = '2.3.61';
1828
1856
  const CLASS_MARKER = '__jqhtml_class__';
1829
1857
  const PROPS_MARKER = '__jqhtml_props__';
1830
1858
  /**
@@ -3833,10 +3861,10 @@ class Jqhtml_Component {
3833
3861
  // Create a content function that invokes child slots
3834
3862
  // When parent calls content('slotName'), it invokes the child's slot function
3835
3863
  const childSlots = instructions._slots;
3836
- const contentFunction = (slotName, data) => {
3864
+ const contentFunction = (slotName, ...slotArgs) => {
3837
3865
  if (childSlots[slotName] && typeof childSlots[slotName] === 'function') {
3838
- // Invoke the slot function with data parameter
3839
- const [slotInstructions, slotContext] = childSlots[slotName](data);
3866
+ // Invoke the slot function with everything content() was given
3867
+ const [slotInstructions, slotContext] = childSlots[slotName](...slotArgs);
3840
3868
  // Return in render function format: [instructions, context]
3841
3869
  // The template expression handler expects this format
3842
3870
  return [slotInstructions, slotContext];
@@ -3861,12 +3889,11 @@ class Jqhtml_Component {
3861
3889
  instructions = [];
3862
3890
  }
3863
3891
  }
3864
- // Flatten any nested content instructions before processing
3865
- // Instructions may contain ['_content', [...]] markers from content() calls
3866
- const flattenedInstructions = this._flatten_instructions(instructions);
3867
- // Process instructions to generate DOM
3892
+ // Process instructions to generate DOM. ['_content', ...] markers from
3893
+ // content() are handled by the processor, which renders them in the
3894
+ // component that wrote them.
3868
3895
  // This kicks off child component boots but doesn't wait for them
3869
- process_instructions(flattenedInstructions, this.$, this);
3896
+ process_instructions(instructions, this.$, this);
3870
3897
  }
3871
3898
  // Don't update ready state here - let phases complete in order
3872
3899
  this._update_debug_attrs();
@@ -4958,11 +4985,21 @@ class Jqhtml_Component {
4958
4985
  }
4959
4986
  /**
4960
4987
  * Find closest ancestor component matching selector
4988
+ *
4989
+ * A bare component name - a plain identifier starting with a capital letter,
4990
+ * such as 'Parent_Dashboard' - is treated as the component-name class
4991
+ * selector '.Parent_Dashboard'. Components carry a CSS class for every name
4992
+ * in their prototype chain, so a base class name matches its subclasses too.
4993
+ * Every other selector ('.Foo', '#id', '[attr]', 'div > .Component') is
4994
+ * passed to jQuery unchanged.
4961
4995
  */
4962
4996
  closest(selector) {
4997
+ const search = Jqhtml_Component.COMPONENT_NAME_PATTERN.test(selector)
4998
+ ? `.${selector}`
4999
+ : selector;
4963
5000
  let current = this.$.parent();
4964
5001
  while (current.length > 0) {
4965
- if (current.is(selector)) {
5002
+ if (current.is(search)) {
4966
5003
  const comp = current.data('_component');
4967
5004
  if (comp instanceof Jqhtml_Component) {
4968
5005
  return comp;
@@ -5016,26 +5053,6 @@ class Jqhtml_Component {
5016
5053
  _generate_cid() {
5017
5054
  return uid();
5018
5055
  }
5019
- /**
5020
- * Flatten instruction array - converts ['_content', [...]] markers to flat array
5021
- * Recursively flattens nested content from content() calls
5022
- */
5023
- _flatten_instructions(instructions) {
5024
- const result = [];
5025
- for (const instruction of instructions) {
5026
- // Check if this is a _content marker: ['_content', [...]]
5027
- if (Array.isArray(instruction) && instruction[0] === '_content' && Array.isArray(instruction[1])) {
5028
- // Recursively flatten the content instructions
5029
- const contentInstructions = this._flatten_instructions(instruction[1]);
5030
- result.push(...contentInstructions);
5031
- }
5032
- else {
5033
- // Regular instruction - keep as is
5034
- result.push(instruction);
5035
- }
5036
- }
5037
- return result;
5038
- }
5039
5056
  _apply_css_classes() {
5040
5057
  const hierarchy = this.constructor.get_class_hierarchy();
5041
5058
  // If component name differs from class name, add component name to hierarchy
@@ -5259,6 +5276,8 @@ class Jqhtml_Component {
5259
5276
  }
5260
5277
  // Static properties
5261
5278
  Jqhtml_Component.__jqhtml_component = true; // Marker for unified register() detection
5279
+ // A bare component name, as accepted by closest() in place of a class selector
5280
+ Jqhtml_Component.COMPONENT_NAME_PATTERN = /^[A-Z][A-Za-z0-9_]*$/;
5262
5281
 
5263
5282
  /**
5264
5283
  * JQHTML v2 Template Renderer
@@ -6155,7 +6174,7 @@ function init(jQuery, config) {
6155
6174
  }
6156
6175
  }
6157
6176
  // Version - will be replaced during build with actual version from package.json
6158
- const version = '2.3.54';
6177
+ const version = '2.3.61';
6159
6178
  // Default export with all functionality
6160
6179
  const jqhtml = {
6161
6180
  // Core