@vectojs/markdown 0.18.0 → 0.18.1
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/dist/Markdown.d.ts +30 -0
- package/dist/index.js +69 -0
- package/dist/index.mjs +69 -0
- package/package.json +1 -1
package/dist/Markdown.d.ts
CHANGED
|
@@ -574,6 +574,36 @@ export declare class Markdown extends UIComponent {
|
|
|
574
574
|
*/
|
|
575
575
|
private affordanceButtonOptions;
|
|
576
576
|
private paragraphImage;
|
|
577
|
+
/**
|
|
578
|
+
* Re-position every block after an image whose decode corrected its box.
|
|
579
|
+
*
|
|
580
|
+
* The 16:10 guess above is rarely the real aspect ratio, so without this every
|
|
581
|
+
* sibling below the image keeps the position computed from the guess, and an
|
|
582
|
+
* image taller than the guess renders *under* the paragraph that follows it.
|
|
583
|
+
*
|
|
584
|
+
* A bare `this.content.layout()` is not enough, and that is the part worth
|
|
585
|
+
* knowing: `Stack.layout()` is **not recursive**. It positions its children
|
|
586
|
+
* from the size each child reports at the moment it runs and never asks a
|
|
587
|
+
* child to recompute its own box first. Every image sits behind at least one
|
|
588
|
+
* intermediate container that caches a height — an image-bearing paragraph is
|
|
589
|
+
* a `Stack`, a list item's or blockquote's image is wrapped in a
|
|
590
|
+
* `MarkdownContainer` — so laying out `content` alone re-reads the very boxes
|
|
591
|
+
* the decode just invalidated. Measured on `94d6da3`: a 600x900 portrait in
|
|
592
|
+
* `\n\nAfter.` corrects `Image.height` 480 to 900 while its parent
|
|
593
|
+
* `Stack` stays 480 and the following paragraph stays at `y=496`.
|
|
594
|
+
*
|
|
595
|
+
* So resync bottom-up, from the image's own parent up to `content`, and each
|
|
596
|
+
* level sees a freshly-sized child before it positions anything.
|
|
597
|
+
*/
|
|
598
|
+
private reflowAfterImageResize;
|
|
599
|
+
/**
|
|
600
|
+
* Re-derive one `MarkdownContainer`'s cached box from its children.
|
|
601
|
+
*
|
|
602
|
+
* Mirrors how {@link reflowToken}'s `blockquote` / `container` arms and every
|
|
603
|
+
* construction site derive it, so an image resize and a width change converge
|
|
604
|
+
* on the same geometry rather than each having its own arithmetic.
|
|
605
|
+
*/
|
|
606
|
+
private resyncWrapperBox;
|
|
577
607
|
/** One table cell entity, shared by the render arm and the streamed-table path. */
|
|
578
608
|
private tableCellRichText;
|
|
579
609
|
/**
|
package/dist/index.js
CHANGED
|
@@ -4130,16 +4130,83 @@ var Markdown = class _Markdown extends import_ui4.UIComponent {
|
|
|
4130
4130
|
radius: this.theme.imageRadius,
|
|
4131
4131
|
onLoad: () => {
|
|
4132
4132
|
const bmp = img.bitmap;
|
|
4133
|
+
const previousWidth = img.width;
|
|
4134
|
+
const previousHeight = img.height;
|
|
4133
4135
|
if (bmp && bmp.naturalWidth && bmp.naturalHeight) {
|
|
4134
4136
|
const aspect = bmp.naturalHeight / bmp.naturalWidth;
|
|
4135
4137
|
img.width = Math.min(bmp.naturalWidth, availableWidth);
|
|
4136
4138
|
img.height = Math.round(img.width * aspect);
|
|
4137
4139
|
}
|
|
4140
|
+
if (img.width !== previousWidth || img.height !== previousHeight) {
|
|
4141
|
+
this.reflowAfterImageResize(img);
|
|
4142
|
+
}
|
|
4138
4143
|
this.scene?.markDirty();
|
|
4139
4144
|
}
|
|
4140
4145
|
});
|
|
4141
4146
|
return img;
|
|
4142
4147
|
}
|
|
4148
|
+
/**
|
|
4149
|
+
* Re-position every block after an image whose decode corrected its box.
|
|
4150
|
+
*
|
|
4151
|
+
* The 16:10 guess above is rarely the real aspect ratio, so without this every
|
|
4152
|
+
* sibling below the image keeps the position computed from the guess, and an
|
|
4153
|
+
* image taller than the guess renders *under* the paragraph that follows it.
|
|
4154
|
+
*
|
|
4155
|
+
* A bare `this.content.layout()` is not enough, and that is the part worth
|
|
4156
|
+
* knowing: `Stack.layout()` is **not recursive**. It positions its children
|
|
4157
|
+
* from the size each child reports at the moment it runs and never asks a
|
|
4158
|
+
* child to recompute its own box first. Every image sits behind at least one
|
|
4159
|
+
* intermediate container that caches a height — an image-bearing paragraph is
|
|
4160
|
+
* a `Stack`, a list item's or blockquote's image is wrapped in a
|
|
4161
|
+
* `MarkdownContainer` — so laying out `content` alone re-reads the very boxes
|
|
4162
|
+
* the decode just invalidated. Measured on `94d6da3`: a 600x900 portrait in
|
|
4163
|
+
* `\n\nAfter.` corrects `Image.height` 480 to 900 while its parent
|
|
4164
|
+
* `Stack` stays 480 and the following paragraph stays at `y=496`.
|
|
4165
|
+
*
|
|
4166
|
+
* So resync bottom-up, from the image's own parent up to `content`, and each
|
|
4167
|
+
* level sees a freshly-sized child before it positions anything.
|
|
4168
|
+
*/
|
|
4169
|
+
reflowAfterImageResize(img) {
|
|
4170
|
+
let reachesContent = false;
|
|
4171
|
+
for (let node = img.parent; node; node = node.parent) {
|
|
4172
|
+
if (node === this.content) {
|
|
4173
|
+
reachesContent = true;
|
|
4174
|
+
break;
|
|
4175
|
+
}
|
|
4176
|
+
}
|
|
4177
|
+
if (!reachesContent) return;
|
|
4178
|
+
for (let node = img.parent; node; node = node.parent) {
|
|
4179
|
+
if (node instanceof import_ui4.Stack) node.layout();
|
|
4180
|
+
else if (node instanceof MarkdownContainer) this.resyncWrapperBox(node);
|
|
4181
|
+
if (node === this.content) break;
|
|
4182
|
+
}
|
|
4183
|
+
this.width = this.content.width;
|
|
4184
|
+
this.height = this.content.height;
|
|
4185
|
+
this.onLayoutUpdated?.();
|
|
4186
|
+
}
|
|
4187
|
+
/**
|
|
4188
|
+
* Re-derive one `MarkdownContainer`'s cached box from its children.
|
|
4189
|
+
*
|
|
4190
|
+
* Mirrors how {@link reflowToken}'s `blockquote` / `container` arms and every
|
|
4191
|
+
* construction site derive it, so an image resize and a width change converge
|
|
4192
|
+
* on the same geometry rather than each having its own arithmetic.
|
|
4193
|
+
*/
|
|
4194
|
+
resyncWrapperBox(wrapper) {
|
|
4195
|
+
const innerStack = wrapper.children.find((c) => c instanceof import_ui4.Stack);
|
|
4196
|
+
const border = wrapper.children.find((c) => c instanceof QuoteBorder);
|
|
4197
|
+
const background = wrapper.children.find((c) => c instanceof ContainerBackground);
|
|
4198
|
+
if (border || background) {
|
|
4199
|
+
const contentHeight = innerStack?.height || 20;
|
|
4200
|
+
if (border instanceof QuoteBorder) border.height = contentHeight;
|
|
4201
|
+
if (background instanceof ContainerBackground) background.height = contentHeight;
|
|
4202
|
+
wrapper.height = Math.max(background?.height ?? 0, border?.height ?? 0, contentHeight);
|
|
4203
|
+
return;
|
|
4204
|
+
}
|
|
4205
|
+
const child = wrapper.children[0];
|
|
4206
|
+
if (!child) return;
|
|
4207
|
+
wrapper.width = child.x + child.width;
|
|
4208
|
+
wrapper.height = child.height;
|
|
4209
|
+
}
|
|
4143
4210
|
/** One table cell entity, shared by the render arm and the streamed-table path. */
|
|
4144
4211
|
tableCellRichText(cell, header, t) {
|
|
4145
4212
|
return new import_ui4.RichText(this.tableCellSpans(cell, t), {
|
|
@@ -4251,6 +4318,8 @@ var Markdown = class _Markdown extends import_ui4.UIComponent {
|
|
|
4251
4318
|
const wrapper = new MarkdownContainer();
|
|
4252
4319
|
el.x = indent;
|
|
4253
4320
|
wrapper.add(el);
|
|
4321
|
+
wrapper.width = el.width + indent;
|
|
4322
|
+
wrapper.height = el.height;
|
|
4254
4323
|
stack.add(wrapper);
|
|
4255
4324
|
}
|
|
4256
4325
|
for (let i = leadChildren.length; i < children.length; i++) {
|
package/dist/index.mjs
CHANGED
|
@@ -4078,16 +4078,83 @@ var Markdown = class _Markdown extends UIComponent3 {
|
|
|
4078
4078
|
radius: this.theme.imageRadius,
|
|
4079
4079
|
onLoad: () => {
|
|
4080
4080
|
const bmp = img.bitmap;
|
|
4081
|
+
const previousWidth = img.width;
|
|
4082
|
+
const previousHeight = img.height;
|
|
4081
4083
|
if (bmp && bmp.naturalWidth && bmp.naturalHeight) {
|
|
4082
4084
|
const aspect = bmp.naturalHeight / bmp.naturalWidth;
|
|
4083
4085
|
img.width = Math.min(bmp.naturalWidth, availableWidth);
|
|
4084
4086
|
img.height = Math.round(img.width * aspect);
|
|
4085
4087
|
}
|
|
4088
|
+
if (img.width !== previousWidth || img.height !== previousHeight) {
|
|
4089
|
+
this.reflowAfterImageResize(img);
|
|
4090
|
+
}
|
|
4086
4091
|
this.scene?.markDirty();
|
|
4087
4092
|
}
|
|
4088
4093
|
});
|
|
4089
4094
|
return img;
|
|
4090
4095
|
}
|
|
4096
|
+
/**
|
|
4097
|
+
* Re-position every block after an image whose decode corrected its box.
|
|
4098
|
+
*
|
|
4099
|
+
* The 16:10 guess above is rarely the real aspect ratio, so without this every
|
|
4100
|
+
* sibling below the image keeps the position computed from the guess, and an
|
|
4101
|
+
* image taller than the guess renders *under* the paragraph that follows it.
|
|
4102
|
+
*
|
|
4103
|
+
* A bare `this.content.layout()` is not enough, and that is the part worth
|
|
4104
|
+
* knowing: `Stack.layout()` is **not recursive**. It positions its children
|
|
4105
|
+
* from the size each child reports at the moment it runs and never asks a
|
|
4106
|
+
* child to recompute its own box first. Every image sits behind at least one
|
|
4107
|
+
* intermediate container that caches a height — an image-bearing paragraph is
|
|
4108
|
+
* a `Stack`, a list item's or blockquote's image is wrapped in a
|
|
4109
|
+
* `MarkdownContainer` — so laying out `content` alone re-reads the very boxes
|
|
4110
|
+
* the decode just invalidated. Measured on `94d6da3`: a 600x900 portrait in
|
|
4111
|
+
* `\n\nAfter.` corrects `Image.height` 480 to 900 while its parent
|
|
4112
|
+
* `Stack` stays 480 and the following paragraph stays at `y=496`.
|
|
4113
|
+
*
|
|
4114
|
+
* So resync bottom-up, from the image's own parent up to `content`, and each
|
|
4115
|
+
* level sees a freshly-sized child before it positions anything.
|
|
4116
|
+
*/
|
|
4117
|
+
reflowAfterImageResize(img) {
|
|
4118
|
+
let reachesContent = false;
|
|
4119
|
+
for (let node = img.parent; node; node = node.parent) {
|
|
4120
|
+
if (node === this.content) {
|
|
4121
|
+
reachesContent = true;
|
|
4122
|
+
break;
|
|
4123
|
+
}
|
|
4124
|
+
}
|
|
4125
|
+
if (!reachesContent) return;
|
|
4126
|
+
for (let node = img.parent; node; node = node.parent) {
|
|
4127
|
+
if (node instanceof Stack) node.layout();
|
|
4128
|
+
else if (node instanceof MarkdownContainer) this.resyncWrapperBox(node);
|
|
4129
|
+
if (node === this.content) break;
|
|
4130
|
+
}
|
|
4131
|
+
this.width = this.content.width;
|
|
4132
|
+
this.height = this.content.height;
|
|
4133
|
+
this.onLayoutUpdated?.();
|
|
4134
|
+
}
|
|
4135
|
+
/**
|
|
4136
|
+
* Re-derive one `MarkdownContainer`'s cached box from its children.
|
|
4137
|
+
*
|
|
4138
|
+
* Mirrors how {@link reflowToken}'s `blockquote` / `container` arms and every
|
|
4139
|
+
* construction site derive it, so an image resize and a width change converge
|
|
4140
|
+
* on the same geometry rather than each having its own arithmetic.
|
|
4141
|
+
*/
|
|
4142
|
+
resyncWrapperBox(wrapper) {
|
|
4143
|
+
const innerStack = wrapper.children.find((c) => c instanceof Stack);
|
|
4144
|
+
const border = wrapper.children.find((c) => c instanceof QuoteBorder);
|
|
4145
|
+
const background = wrapper.children.find((c) => c instanceof ContainerBackground);
|
|
4146
|
+
if (border || background) {
|
|
4147
|
+
const contentHeight = innerStack?.height || 20;
|
|
4148
|
+
if (border instanceof QuoteBorder) border.height = contentHeight;
|
|
4149
|
+
if (background instanceof ContainerBackground) background.height = contentHeight;
|
|
4150
|
+
wrapper.height = Math.max(background?.height ?? 0, border?.height ?? 0, contentHeight);
|
|
4151
|
+
return;
|
|
4152
|
+
}
|
|
4153
|
+
const child = wrapper.children[0];
|
|
4154
|
+
if (!child) return;
|
|
4155
|
+
wrapper.width = child.x + child.width;
|
|
4156
|
+
wrapper.height = child.height;
|
|
4157
|
+
}
|
|
4091
4158
|
/** One table cell entity, shared by the render arm and the streamed-table path. */
|
|
4092
4159
|
tableCellRichText(cell, header, t) {
|
|
4093
4160
|
return new RichText2(this.tableCellSpans(cell, t), {
|
|
@@ -4199,6 +4266,8 @@ var Markdown = class _Markdown extends UIComponent3 {
|
|
|
4199
4266
|
const wrapper = new MarkdownContainer();
|
|
4200
4267
|
el.x = indent;
|
|
4201
4268
|
wrapper.add(el);
|
|
4269
|
+
wrapper.width = el.width + indent;
|
|
4270
|
+
wrapper.height = el.height;
|
|
4202
4271
|
stack.add(wrapper);
|
|
4203
4272
|
}
|
|
4204
4273
|
for (let i = leadChildren.length; i < children.length; i++) {
|