@vectojs/markdown 0.18.1 → 0.18.2

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.
@@ -94,14 +94,40 @@ export declare class Markdown extends UIComponent {
94
94
  saveFile: (filename: string, content: string, mimeType: string) => void;
95
95
  private activeBlockMetrics;
96
96
  /**
97
- * Called after a streamed append has re-laid-out the document.
98
- *
99
- * Not required for a `VirtualList` to track a streaming row's height: the list
100
- * re-reads `height` on every mounted row each frame, so it sees this entity grow
101
- * without being told. Prefer that over wiring this up — it fires from the append
102
- * path only, **not** from `setContent()`, so it is not a complete size signal.
97
+ * Called after this entity's own `width`/`height` changed because the document
98
+ * was re-laid-out. **This is the hook to wire up when a host has to move or
99
+ * resize anything positioned below the document.**
100
+ *
101
+ * Fires from three paths, all of which republish `width`/`height` from
102
+ * `content`:
103
+ *
104
+ * - a streamed append (`updateTokens`),
105
+ * - a width change ({@link setMaxWidth}),
106
+ * - a paragraph image whose decoded bitmap corrected the guessed aspect ratio
107
+ * (`reflowAfterImageResize`) — the guess is a flat 16:10, so this one fires
108
+ * on essentially every document containing an image, and a host that misses
109
+ * it leaves every block below the image overlapping it.
110
+ *
111
+ * It does **not** fire from `setContent()`, which replaces the whole document
112
+ * and is a call the host already made, so this is a re-layout signal rather
113
+ * than a complete size signal.
114
+ *
115
+ * A `VirtualList` needs none of this to track a streaming row: it re-reads
116
+ * `height` on every mounted row each frame, so it sees this entity grow without
117
+ * being told. Prefer that where it applies. Reach for this callback when the
118
+ * host owns absolute positions of its own — a page that stacks navigation, a
119
+ * footer and a scroll height under the document has to recompute them here.
120
+ *
121
+ * There is no `onHeightChanged`. That name has been assigned by real callers
122
+ * through an `as unknown as` cast, which compiles, silences the type error and
123
+ * then never fires; if a layout callback appears dead, check the name first.
103
124
  */
104
125
  onLayoutUpdated?: () => void;
126
+ /**
127
+ * Latch for the miswired-hook warning, so a streaming document warns once
128
+ * rather than on every chunk.
129
+ */
130
+ private hasWarnedLayoutHookName;
105
131
  /**
106
132
  * The document's BODY text — everything after any front matter block.
107
133
  *
@@ -596,6 +622,23 @@ export declare class Markdown extends UIComponent {
596
622
  * level sees a freshly-sized child before it positions anything.
597
623
  */
598
624
  private reflowAfterImageResize;
625
+ /**
626
+ * Publish a completed re-layout to the host.
627
+ *
628
+ * Every path that republishes `width`/`height` from `content` ends here rather
629
+ * than calling {@link onLayoutUpdated} directly, so the misuse check below is
630
+ * reached however the re-layout was triggered.
631
+ *
632
+ * The check exists because the failure it catches is silent and was found in
633
+ * production, not in review. A host wired its reflow to `onHeightChanged` — a
634
+ * name this class has never had — through an `as unknown as` cast. The cast
635
+ * satisfied the compiler, the callback never fired, and every post containing
636
+ * an image stayed laid out against the guessed 16:10 aspect ratio with a stale
637
+ * document scroll height. Nothing in the type system, the tests or the console
638
+ * said anything. A property that is *only ever assigned* has no read site to
639
+ * fail, so the one place that can notice is the moment we would have called it.
640
+ */
641
+ private notifyLayoutUpdated;
599
642
  /**
600
643
  * Re-derive one `MarkdownContainer`'s cached box from its children.
601
644
  *
package/dist/index.js CHANGED
@@ -2787,6 +2787,12 @@ import_marked.marked.use({
2787
2787
  }
2788
2788
  ]
2789
2789
  });
2790
+ var MISWIRED_LAYOUT_HOOK_NAMES = [
2791
+ "onHeightChanged",
2792
+ "onHeightChange",
2793
+ "onLayoutUpdate",
2794
+ "onResize"
2795
+ ];
2790
2796
  var markdownWorker = null;
2791
2797
  var workerIdCounter = 0;
2792
2798
  var workerInstanceCounter = 0;
@@ -2854,14 +2860,40 @@ var Markdown = class _Markdown extends import_ui4.UIComponent {
2854
2860
  saveFile;
2855
2861
  activeBlockMetrics = null;
2856
2862
  /**
2857
- * Called after a streamed append has re-laid-out the document.
2863
+ * Called after this entity's own `width`/`height` changed because the document
2864
+ * was re-laid-out. **This is the hook to wire up when a host has to move or
2865
+ * resize anything positioned below the document.**
2866
+ *
2867
+ * Fires from three paths, all of which republish `width`/`height` from
2868
+ * `content`:
2869
+ *
2870
+ * - a streamed append (`updateTokens`),
2871
+ * - a width change ({@link setMaxWidth}),
2872
+ * - a paragraph image whose decoded bitmap corrected the guessed aspect ratio
2873
+ * (`reflowAfterImageResize`) — the guess is a flat 16:10, so this one fires
2874
+ * on essentially every document containing an image, and a host that misses
2875
+ * it leaves every block below the image overlapping it.
2858
2876
  *
2859
- * Not required for a `VirtualList` to track a streaming row's height: the list
2860
- * re-reads `height` on every mounted row each frame, so it sees this entity grow
2861
- * without being told. Prefer that over wiring this up — it fires from the append
2862
- * path only, **not** from `setContent()`, so it is not a complete size signal.
2877
+ * It does **not** fire from `setContent()`, which replaces the whole document
2878
+ * and is a call the host already made, so this is a re-layout signal rather
2879
+ * than a complete size signal.
2880
+ *
2881
+ * A `VirtualList` needs none of this to track a streaming row: it re-reads
2882
+ * `height` on every mounted row each frame, so it sees this entity grow without
2883
+ * being told. Prefer that where it applies. Reach for this callback when the
2884
+ * host owns absolute positions of its own — a page that stacks navigation, a
2885
+ * footer and a scroll height under the document has to recompute them here.
2886
+ *
2887
+ * There is no `onHeightChanged`. That name has been assigned by real callers
2888
+ * through an `as unknown as` cast, which compiles, silences the type error and
2889
+ * then never fires; if a layout callback appears dead, check the name first.
2863
2890
  */
2864
2891
  onLayoutUpdated;
2892
+ /**
2893
+ * Latch for the miswired-hook warning, so a streaming document warns once
2894
+ * rather than on every chunk.
2895
+ */
2896
+ hasWarnedLayoutHookName = false;
2865
2897
  /**
2866
2898
  * The document's BODY text — everything after any front matter block.
2867
2899
  *
@@ -3312,7 +3344,7 @@ var Markdown = class _Markdown extends import_ui4.UIComponent {
3312
3344
  this.content.layout();
3313
3345
  this.width = this.content.width;
3314
3346
  this.height = this.content.height;
3315
- this.onLayoutUpdated?.();
3347
+ this.notifyLayoutUpdated();
3316
3348
  this.scene?.markDirty();
3317
3349
  return this;
3318
3350
  }
@@ -4182,7 +4214,40 @@ var Markdown = class _Markdown extends import_ui4.UIComponent {
4182
4214
  }
4183
4215
  this.width = this.content.width;
4184
4216
  this.height = this.content.height;
4185
- this.onLayoutUpdated?.();
4217
+ this.notifyLayoutUpdated();
4218
+ }
4219
+ /**
4220
+ * Publish a completed re-layout to the host.
4221
+ *
4222
+ * Every path that republishes `width`/`height` from `content` ends here rather
4223
+ * than calling {@link onLayoutUpdated} directly, so the misuse check below is
4224
+ * reached however the re-layout was triggered.
4225
+ *
4226
+ * The check exists because the failure it catches is silent and was found in
4227
+ * production, not in review. A host wired its reflow to `onHeightChanged` — a
4228
+ * name this class has never had — through an `as unknown as` cast. The cast
4229
+ * satisfied the compiler, the callback never fired, and every post containing
4230
+ * an image stayed laid out against the guessed 16:10 aspect ratio with a stale
4231
+ * document scroll height. Nothing in the type system, the tests or the console
4232
+ * said anything. A property that is *only ever assigned* has no read site to
4233
+ * fail, so the one place that can notice is the moment we would have called it.
4234
+ */
4235
+ notifyLayoutUpdated() {
4236
+ if (this.onLayoutUpdated) {
4237
+ this.onLayoutUpdated();
4238
+ return;
4239
+ }
4240
+ if (!this.hasWarnedLayoutHookName) {
4241
+ const wrongName = MISWIRED_LAYOUT_HOOK_NAMES.find(
4242
+ (name) => typeof this[name] === "function"
4243
+ );
4244
+ if (wrongName) {
4245
+ this.hasWarnedLayoutHookName = true;
4246
+ console.warn(
4247
+ `[VectoJS] Markdown.${wrongName} is not a VectoJS callback and will never fire. The document just re-laid-out and nothing was notified. Assign \`onLayoutUpdated\` instead \u2014 anything positioned below the document needs it, and a paragraph image corrects its guessed aspect ratio on decode, so a missed signal leaves following blocks overlapping the image.`
4248
+ );
4249
+ }
4250
+ }
4186
4251
  }
4187
4252
  /**
4188
4253
  * Re-derive one `MarkdownContainer`'s cached box from its children.
@@ -4993,9 +5058,7 @@ var Markdown = class _Markdown extends import_ui4.UIComponent {
4993
5058
  this.width = this.content.width;
4994
5059
  this.height = this.content.height;
4995
5060
  this.scene?.markDirty();
4996
- if (this.onLayoutUpdated) {
4997
- this.onLayoutUpdated();
4998
- }
5061
+ this.notifyLayoutUpdated();
4999
5062
  }
5000
5063
  /**
5001
5064
  * Render one nested block with a temporary width/margin context while
package/dist/index.mjs CHANGED
@@ -2735,6 +2735,12 @@ marked.use({
2735
2735
  }
2736
2736
  ]
2737
2737
  });
2738
+ var MISWIRED_LAYOUT_HOOK_NAMES = [
2739
+ "onHeightChanged",
2740
+ "onHeightChange",
2741
+ "onLayoutUpdate",
2742
+ "onResize"
2743
+ ];
2738
2744
  var markdownWorker = null;
2739
2745
  var workerIdCounter = 0;
2740
2746
  var workerInstanceCounter = 0;
@@ -2802,14 +2808,40 @@ var Markdown = class _Markdown extends UIComponent3 {
2802
2808
  saveFile;
2803
2809
  activeBlockMetrics = null;
2804
2810
  /**
2805
- * Called after a streamed append has re-laid-out the document.
2811
+ * Called after this entity's own `width`/`height` changed because the document
2812
+ * was re-laid-out. **This is the hook to wire up when a host has to move or
2813
+ * resize anything positioned below the document.**
2814
+ *
2815
+ * Fires from three paths, all of which republish `width`/`height` from
2816
+ * `content`:
2817
+ *
2818
+ * - a streamed append (`updateTokens`),
2819
+ * - a width change ({@link setMaxWidth}),
2820
+ * - a paragraph image whose decoded bitmap corrected the guessed aspect ratio
2821
+ * (`reflowAfterImageResize`) — the guess is a flat 16:10, so this one fires
2822
+ * on essentially every document containing an image, and a host that misses
2823
+ * it leaves every block below the image overlapping it.
2806
2824
  *
2807
- * Not required for a `VirtualList` to track a streaming row's height: the list
2808
- * re-reads `height` on every mounted row each frame, so it sees this entity grow
2809
- * without being told. Prefer that over wiring this up — it fires from the append
2810
- * path only, **not** from `setContent()`, so it is not a complete size signal.
2825
+ * It does **not** fire from `setContent()`, which replaces the whole document
2826
+ * and is a call the host already made, so this is a re-layout signal rather
2827
+ * than a complete size signal.
2828
+ *
2829
+ * A `VirtualList` needs none of this to track a streaming row: it re-reads
2830
+ * `height` on every mounted row each frame, so it sees this entity grow without
2831
+ * being told. Prefer that where it applies. Reach for this callback when the
2832
+ * host owns absolute positions of its own — a page that stacks navigation, a
2833
+ * footer and a scroll height under the document has to recompute them here.
2834
+ *
2835
+ * There is no `onHeightChanged`. That name has been assigned by real callers
2836
+ * through an `as unknown as` cast, which compiles, silences the type error and
2837
+ * then never fires; if a layout callback appears dead, check the name first.
2811
2838
  */
2812
2839
  onLayoutUpdated;
2840
+ /**
2841
+ * Latch for the miswired-hook warning, so a streaming document warns once
2842
+ * rather than on every chunk.
2843
+ */
2844
+ hasWarnedLayoutHookName = false;
2813
2845
  /**
2814
2846
  * The document's BODY text — everything after any front matter block.
2815
2847
  *
@@ -3260,7 +3292,7 @@ var Markdown = class _Markdown extends UIComponent3 {
3260
3292
  this.content.layout();
3261
3293
  this.width = this.content.width;
3262
3294
  this.height = this.content.height;
3263
- this.onLayoutUpdated?.();
3295
+ this.notifyLayoutUpdated();
3264
3296
  this.scene?.markDirty();
3265
3297
  return this;
3266
3298
  }
@@ -4130,7 +4162,40 @@ var Markdown = class _Markdown extends UIComponent3 {
4130
4162
  }
4131
4163
  this.width = this.content.width;
4132
4164
  this.height = this.content.height;
4133
- this.onLayoutUpdated?.();
4165
+ this.notifyLayoutUpdated();
4166
+ }
4167
+ /**
4168
+ * Publish a completed re-layout to the host.
4169
+ *
4170
+ * Every path that republishes `width`/`height` from `content` ends here rather
4171
+ * than calling {@link onLayoutUpdated} directly, so the misuse check below is
4172
+ * reached however the re-layout was triggered.
4173
+ *
4174
+ * The check exists because the failure it catches is silent and was found in
4175
+ * production, not in review. A host wired its reflow to `onHeightChanged` — a
4176
+ * name this class has never had — through an `as unknown as` cast. The cast
4177
+ * satisfied the compiler, the callback never fired, and every post containing
4178
+ * an image stayed laid out against the guessed 16:10 aspect ratio with a stale
4179
+ * document scroll height. Nothing in the type system, the tests or the console
4180
+ * said anything. A property that is *only ever assigned* has no read site to
4181
+ * fail, so the one place that can notice is the moment we would have called it.
4182
+ */
4183
+ notifyLayoutUpdated() {
4184
+ if (this.onLayoutUpdated) {
4185
+ this.onLayoutUpdated();
4186
+ return;
4187
+ }
4188
+ if (!this.hasWarnedLayoutHookName) {
4189
+ const wrongName = MISWIRED_LAYOUT_HOOK_NAMES.find(
4190
+ (name) => typeof this[name] === "function"
4191
+ );
4192
+ if (wrongName) {
4193
+ this.hasWarnedLayoutHookName = true;
4194
+ console.warn(
4195
+ `[VectoJS] Markdown.${wrongName} is not a VectoJS callback and will never fire. The document just re-laid-out and nothing was notified. Assign \`onLayoutUpdated\` instead \u2014 anything positioned below the document needs it, and a paragraph image corrects its guessed aspect ratio on decode, so a missed signal leaves following blocks overlapping the image.`
4196
+ );
4197
+ }
4198
+ }
4134
4199
  }
4135
4200
  /**
4136
4201
  * Re-derive one `MarkdownContainer`'s cached box from its children.
@@ -4941,9 +5006,7 @@ var Markdown = class _Markdown extends UIComponent3 {
4941
5006
  this.width = this.content.width;
4942
5007
  this.height = this.content.height;
4943
5008
  this.scene?.markDirty();
4944
- if (this.onLayoutUpdated) {
4945
- this.onLayoutUpdated();
4946
- }
5009
+ this.notifyLayoutUpdated();
4947
5010
  }
4948
5011
  /**
4949
5012
  * Render one nested block with a temporary width/margin context while
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vectojs/markdown",
3
- "version": "0.18.1",
3
+ "version": "0.18.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },