assign-gingerly 0.0.56 → 0.0.58

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.
@@ -39,15 +39,27 @@ function getMarkerName(templateEl) {
39
39
  */
40
40
  export class LazyLoadHandler {
41
41
  config;
42
+ static #markerCounter = 0;
42
43
  constructor(config) {
43
44
  this.config = config;
44
45
  }
45
46
  async assign(lhsTarget, resolvedParams) {
46
- const { if: condition, instantiate, method = 'appendChild', forget = false, transitional = false, hideClass = DEFAULT_HIDE_CLASS, markerName, toggleInert = false, toggleDisabled = false } = resolvedParams;
47
+ const { if: condition, instantiate, method = 'appendChild', forget = false, transitional = false, hideClass = DEFAULT_HIDE_CLASS, hideCss, markerName, toggleInert = false, toggleDisabled = false } = resolvedParams;
47
48
  if (!(lhsTarget instanceof Element)) {
48
49
  throw new Error('builtIns.lazyLoad: lhsTarget must be a DOM Element');
49
50
  }
50
- const name = markerName ?? getMarkerName(instantiate) ?? (lhsTarget.id || 'anonymous');
51
+ let name = markerName ?? getMarkerName(instantiate) ?? (lhsTarget.id || 'anonymous');
52
+ if (name === 'anonymous' && method === 'after') {
53
+ const stored = lhsTarget.dataset?.agMarker;
54
+ if (stored) {
55
+ name = stored;
56
+ } else {
57
+ name = `_ag_${LazyLoadHandler.#markerCounter++}`;
58
+ if (lhsTarget.dataset) {
59
+ lhsTarget.dataset.agMarker = name;
60
+ }
61
+ }
62
+ }
51
63
  let [startMarker, endMarker] = method === 'after'
52
64
  ? findMarkersSibling(lhsTarget, name)
53
65
  : findMarkers(lhsTarget, name);
@@ -61,7 +73,7 @@ export class LazyLoadHandler {
61
73
  }
62
74
  else {
63
75
  if (transitional) {
64
- ensureHideStyle(lhsTarget.getRootNode());
76
+ ensureHideStyle(lhsTarget.getRootNode(), hideClass, hideCss);
65
77
  withTransition(startMarker, 'show', true, () => {
66
78
  this.cloneAndInsertSync(instantiate, startMarker, endMarker, lhsTarget, resolvedParams);
67
79
  });
@@ -77,7 +89,7 @@ export class LazyLoadHandler {
77
89
  [startMarker, endMarker] = createMarkers(lhsTarget, name, method);
78
90
  }
79
91
  if (transitional) {
80
- ensureHideStyle(lhsTarget.getRootNode());
92
+ ensureHideStyle(lhsTarget.getRootNode(), hideClass, hideCss);
81
93
  withTransition(startMarker, 'show', true, () => {
82
94
  this.cloneAndInsertSync(instantiate, startMarker, endMarker, lhsTarget, resolvedParams);
83
95
  });
@@ -99,7 +111,7 @@ export class LazyLoadHandler {
99
111
  }
100
112
  else {
101
113
  withTransition(startMarker, 'hide', transitional, () => {
102
- this.hideNodes(nodes, lhsTarget, transitional, hideClass, toggleInert, toggleDisabled);
114
+ this.hideNodes(nodes, lhsTarget, transitional, hideClass, hideCss, toggleInert, toggleDisabled);
103
115
  });
104
116
  }
105
117
  }
@@ -122,11 +134,11 @@ export class LazyLoadHandler {
122
134
  }
123
135
  }
124
136
  }
125
- hideNodes(nodes, lhsTarget, transitional, hideClass, toggleInert, toggleDisabled) {
137
+ hideNodes(nodes, lhsTarget, transitional, hideClass, hideCss, toggleInert, toggleDisabled) {
126
138
  for (const node of nodes) {
127
139
  if (node instanceof Element) {
128
140
  if (transitional) {
129
- ensureHideStyle(lhsTarget.getRootNode(), hideClass);
141
+ ensureHideStyle(lhsTarget.getRootNode(), hideClass, hideCss);
130
142
  node.classList.add(hideClass);
131
143
  } else {
132
144
  node.setAttribute('hidden', '');
@@ -46,6 +46,7 @@ function getMarkerName(templateEl: any): string {
46
46
  */
47
47
  export class LazyLoadHandler implements AssignFromHandler {
48
48
  config: any;
49
+ static #markerCounter = 0;
49
50
 
50
51
  constructor(config: any) {
51
52
  this.config = config;
@@ -59,6 +60,7 @@ export class LazyLoadHandler implements AssignFromHandler {
59
60
  forget = false,
60
61
  transitional = false,
61
62
  hideClass = DEFAULT_HIDE_CLASS,
63
+ hideCss,
62
64
  markerName,
63
65
  toggleInert = false,
64
66
  toggleDisabled = false,
@@ -68,7 +70,20 @@ export class LazyLoadHandler implements AssignFromHandler {
68
70
  throw new Error('builtIns.lazyLoad: lhsTarget must be a DOM Element');
69
71
  }
70
72
 
71
- const name = markerName ?? getMarkerName(instantiate) ?? (lhsTarget.id || 'anonymous');
73
+ // Determine marker name auto-generate for 'after' mode if would be 'anonymous'
74
+ let name = markerName ?? getMarkerName(instantiate) ?? (lhsTarget.id || 'anonymous');
75
+ if (name === 'anonymous' && method === 'after') {
76
+ // Check for previously stored name on the anchor
77
+ const stored = (lhsTarget as HTMLElement).dataset?.agMarker;
78
+ if (stored) {
79
+ name = stored;
80
+ } else {
81
+ name = `_ag_${LazyLoadHandler.#markerCounter++}`;
82
+ if ((lhsTarget as HTMLElement).dataset) {
83
+ (lhsTarget as HTMLElement).dataset.agMarker = name;
84
+ }
85
+ }
86
+ }
72
87
 
73
88
  // Find or create markers based on method
74
89
  let [startMarker, endMarker] = method === 'after'
@@ -87,7 +102,7 @@ export class LazyLoadHandler implements AssignFromHandler {
87
102
  } else {
88
103
  // Content was removed (forget mode) — re-clone
89
104
  if (transitional) {
90
- ensureHideStyle(lhsTarget.getRootNode());
105
+ ensureHideStyle(lhsTarget.getRootNode(), hideClass, hideCss);
91
106
  withTransition(startMarker, 'show', true, () => {
92
107
  this.cloneAndInsertSync(instantiate, startMarker!, endMarker!, lhsTarget, resolvedParams);
93
108
  });
@@ -103,7 +118,7 @@ export class LazyLoadHandler implements AssignFromHandler {
103
118
  [startMarker, endMarker] = createMarkers(lhsTarget, name, method);
104
119
  }
105
120
  if (transitional) {
106
- ensureHideStyle(lhsTarget.getRootNode());
121
+ ensureHideStyle(lhsTarget.getRootNode(), hideClass, hideCss);
107
122
  withTransition(startMarker, 'show', true, () => {
108
123
  this.cloneAndInsertSync(instantiate, startMarker!, endMarker!, lhsTarget, resolvedParams);
109
124
  });
@@ -125,7 +140,7 @@ export class LazyLoadHandler implements AssignFromHandler {
125
140
  });
126
141
  } else {
127
142
  withTransition(startMarker, 'hide', transitional, () => {
128
- this.hideNodes(nodes, lhsTarget, transitional, hideClass, toggleInert, toggleDisabled);
143
+ this.hideNodes(nodes, lhsTarget, transitional, hideClass, hideCss, toggleInert, toggleDisabled);
129
144
  });
130
145
  }
131
146
  }
@@ -167,13 +182,14 @@ export class LazyLoadHandler implements AssignFromHandler {
167
182
  lhsTarget: Element,
168
183
  transitional: boolean,
169
184
  hideClass: string,
185
+ hideCss: string | undefined,
170
186
  toggleInert: boolean,
171
187
  toggleDisabled: boolean
172
188
  ): void {
173
189
  for (const node of nodes) {
174
190
  if (node instanceof Element) {
175
191
  if (transitional) {
176
- ensureHideStyle(lhsTarget.getRootNode(), hideClass);
192
+ ensureHideStyle(lhsTarget.getRootNode(), hideClass, hideCss);
177
193
  node.classList.add(hideClass);
178
194
  } else {
179
195
  node.setAttribute('hidden', '');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "assign-gingerly",
3
- "version": "0.0.56",
3
+ "version": "0.0.58",
4
4
  "description": "This package provides a utility function for carefully merging one object into another.",
5
5
  "homepage": "https://github.com/bahrus/assign-gingerly#readme",
6
6
  "bugs": {
@@ -77,9 +77,9 @@ export function withTransition(markerNode, direction, transitional, domMutation)
77
77
  }
78
78
 
79
79
  /**
80
- * Track which rootNodes already have the hide style injected.
80
+ * Track which (rootNode, className) combos already have styles injected.
81
81
  */
82
- const styleInjected = new WeakSet();
82
+ const styleInjected = new WeakMap();
83
83
 
84
84
  /**
85
85
  * Default CSS class name for hidden elements during transitions.
@@ -87,7 +87,7 @@ const styleInjected = new WeakSet();
87
87
  export const DEFAULT_HIDE_CLASS = 'ag-hide';
88
88
 
89
89
  /**
90
- * Ensure the hide class style is injected into the rootNode (once per rootNode).
90
+ * Ensure the hide class style is injected into the rootNode (once per rootNode + className combo).
91
91
  *
92
92
  * @param {any} rootNode - The Document, ShadowRoot, or element root to inject into
93
93
  * @param {string} [hideClass='ag-hide'] - CSS class name
@@ -100,8 +100,14 @@ export function ensureHideStyle(rootNode, hideClass = DEFAULT_HIDE_CLASS, hideCs
100
100
  target = document.head;
101
101
  }
102
102
 
103
- if (styleInjected.has(target)) return;
104
- styleInjected.add(target);
103
+ let injectedClasses = styleInjected.get(target);
104
+ if (!injectedClasses) {
105
+ injectedClasses = new Set();
106
+ styleInjected.set(target, injectedClasses);
107
+ }
108
+
109
+ if (injectedClasses.has(hideClass)) return;
110
+ injectedClasses.add(hideClass);
105
111
 
106
112
  const style = document.createElement('style');
107
113
  style.textContent = `.${hideClass} { ${hideCss} }`;
@@ -91,9 +91,9 @@ export function withTransition(
91
91
  }
92
92
 
93
93
  /**
94
- * Track which rootNodes already have the hide style injected.
94
+ * Track which (rootNode, className) combos already have styles injected.
95
95
  */
96
- const styleInjected = new WeakSet<object>();
96
+ const styleInjected = new WeakMap<object, Set<string>>();
97
97
 
98
98
  /**
99
99
  * Default CSS class name for hidden elements during transitions.
@@ -106,7 +106,7 @@ export const DEFAULT_HIDE_CLASS = 'ag-hide';
106
106
  const DEFAULT_HIDE_CSS = `display: none`;
107
107
 
108
108
  /**
109
- * Ensure the hide class style is injected into the rootNode (once per rootNode).
109
+ * Ensure the hide class style is injected into the rootNode (once per rootNode + className combo).
110
110
  *
111
111
  * @param rootNode - The Document, ShadowRoot, or element root to inject into
112
112
  * @param hideClass - CSS class name (default: 'ag-hide')
@@ -123,8 +123,14 @@ export function ensureHideStyle(
123
123
  target = document.head;
124
124
  }
125
125
 
126
- if (styleInjected.has(target)) return;
127
- styleInjected.add(target);
126
+ let injectedClasses = styleInjected.get(target);
127
+ if (!injectedClasses) {
128
+ injectedClasses = new Set();
129
+ styleInjected.set(target, injectedClasses);
130
+ }
131
+
132
+ if (injectedClasses.has(hideClass)) return;
133
+ injectedClasses.add(hideClass);
128
134
 
129
135
  const style = document.createElement('style');
130
136
  style.textContent = `.${hideClass} { ${hideCss} }`;
@@ -546,6 +546,8 @@ export interface LazyLoadConfig extends HandlerConfig {
546
546
  transitional?: boolean | string;
547
547
  /** CSS class for hiding (default: 'ag-hide', only used when transitional: true) */
548
548
  hideClass?: string;
549
+ /** Custom CSS for the hide class (default: 'display: none') */
550
+ hideCss?: string;
549
551
  /** Optional async callback invoked after cloning, resolved from the VM */
550
552
  onInstantiated?: string;
551
553
  /** Override auto-derived marker name */
@@ -573,6 +575,8 @@ export interface LazyLoadResolvedParams {
573
575
  transitional?: boolean;
574
576
  /** CSS class for hiding (default: 'ag-hide', only used when transitional: true) */
575
577
  hideClass?: string;
578
+ /** Custom CSS for the hide class (default: 'display: none') */
579
+ hideCss?: string;
576
580
  /** Callback after clone+insert */
577
581
  onInstantiated?: (ctx: LazyLoadInstantiatedContext) => void | Promise<void>;
578
582
  /** Override auto-derived marker name */
@@ -597,7 +601,7 @@ export interface LazyLoadSwitchConfig extends HandlerConfig {
597
601
  rhs: string;
598
602
  /** Template element to clone (resolved via protocol or path) */
599
603
  instantiate: string;
600
- /** Insert method: 'appendChild' (default) or 'prepend' */
604
+ /** Insert method: 'appendChild' (default), 'prepend', or 'after' */
601
605
  method?: string;
602
606
  /** If true, removes nodes when hiding instead of adding hidden attribute */
603
607
  forget?: boolean | string;
@@ -605,6 +609,8 @@ export interface LazyLoadSwitchConfig extends HandlerConfig {
605
609
  transitional?: boolean | string;
606
610
  /** CSS class for hiding (default: 'ag-hide', only used when transitional: true) */
607
611
  hideClass?: string;
612
+ /** Custom CSS for the hide class (default: 'display: none') */
613
+ hideCss?: string;
608
614
  /** Optional async callback invoked after cloning, resolved from the VM */
609
615
  onInstantiated?: string;
610
616
  };