@react-x11/components 0.10.0 → 0.11.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.
- package/dist/code/index.d.ts.map +1 -1
- package/dist/code/index.js +25 -24
- package/dist/code/index.js.map +1 -1
- package/dist/code-language/index.d.ts +1 -1
- package/dist/code-language/index.d.ts.map +1 -1
- package/dist/code-language/index.js +1 -1
- package/dist/code-language/index.js.map +1 -1
- package/dist/code-language/runs.d.ts +31 -0
- package/dist/code-language/runs.d.ts.map +1 -1
- package/dist/code-language/runs.js +105 -0
- package/dist/code-language/runs.js.map +1 -1
- package/dist/codeblock/index.d.ts +13 -0
- package/dist/codeblock/index.d.ts.map +1 -1
- package/dist/codeblock/index.js +37 -1
- package/dist/codeblock/index.js.map +1 -1
- package/dist/html/css/cascade.d.ts +32 -10
- package/dist/html/css/cascade.d.ts.map +1 -1
- package/dist/html/css/cascade.js +72 -27
- package/dist/html/css/cascade.js.map +1 -1
- package/dist/html/css/style.d.ts +7 -4
- package/dist/html/css/style.d.ts.map +1 -1
- package/dist/html/css/style.js +37 -6
- package/dist/html/css/style.js.map +1 -1
- package/dist/html/css/ua.js +8 -5
- package/dist/html/css/ua.js.map +1 -1
- package/dist/html/layout/block.d.ts.map +1 -1
- package/dist/html/layout/block.js +127 -9
- package/dist/html/layout/block.js.map +1 -1
- package/dist/html/layout/boxes.d.ts +27 -0
- package/dist/html/layout/boxes.d.ts.map +1 -1
- package/dist/html/layout/boxes.js +30 -2
- package/dist/html/layout/boxes.js.map +1 -1
- package/dist/html/layout/inline.d.ts +3 -0
- package/dist/html/layout/inline.d.ts.map +1 -1
- package/dist/html/layout/inline.js +236 -14
- package/dist/html/layout/inline.js.map +1 -1
- package/dist/html/node.d.ts.map +1 -1
- package/dist/html/node.js +118 -57
- package/dist/html/node.js.map +1 -1
- package/dist/html/paint.d.ts.map +1 -1
- package/dist/html/paint.js +203 -37
- package/dist/html/paint.js.map +1 -1
- package/dist/html/svg.d.ts.map +1 -1
- package/dist/html/svg.js +27 -20
- package/dist/html/svg.js.map +1 -1
- package/dist/internal/codelines.d.ts +42 -0
- package/dist/internal/codelines.d.ts.map +1 -0
- package/dist/internal/codelines.js +170 -0
- package/dist/internal/codelines.js.map +1 -0
- package/dist/markdown/index.d.ts.map +1 -1
- package/dist/markdown/index.js +98 -26
- package/dist/markdown/index.js.map +1 -1
- package/dist/rich-text-editor/index.d.ts.map +1 -1
- package/dist/rich-text-editor/index.js +3 -8
- package/dist/rich-text-editor/index.js.map +1 -1
- package/dist/rich-text-editor/markdown.d.ts.map +1 -1
- package/dist/rich-text-editor/markdown.js +30 -1
- package/dist/rich-text-editor/markdown.js.map +1 -1
- package/dist/rich-text-editor/replace.d.ts +13 -0
- package/dist/rich-text-editor/replace.d.ts.map +1 -0
- package/dist/rich-text-editor/replace.js +64 -0
- package/dist/rich-text-editor/replace.js.map +1 -0
- package/dist/terminal-output/index.d.ts.map +1 -1
- package/dist/terminal-output/index.js +100 -25
- package/dist/terminal-output/index.js.map +1 -1
- package/dist/terminal-output/runs.d.ts +4 -1
- package/dist/terminal-output/runs.d.ts.map +1 -1
- package/dist/terminal-output/runs.js +5 -1
- package/dist/terminal-output/runs.js.map +1 -1
- package/package.json +1 -1
- package/src/code/index.ts +34 -32
- package/src/code-language/index.ts +1 -1
- package/src/code-language/runs.ts +111 -1
- package/src/codeblock/index.ts +48 -1
- package/src/html/css/cascade.ts +117 -39
- package/src/html/css/style.ts +43 -15
- package/src/html/css/ua.ts +8 -5
- package/src/html/layout/block.ts +134 -8
- package/src/html/layout/boxes.ts +43 -2
- package/src/html/layout/inline.ts +257 -13
- package/src/html/node.ts +145 -79
- package/src/html/paint.ts +236 -45
- package/src/html/svg.ts +30 -19
- package/src/internal/codelines.ts +200 -0
- package/src/markdown/index.ts +145 -26
- package/src/rich-text-editor/index.ts +3 -11
- package/src/rich-text-editor/markdown.ts +36 -1
- package/src/rich-text-editor/replace.ts +85 -0
- package/src/terminal-output/index.ts +127 -34
- package/src/terminal-output/runs.ts +16 -2
package/dist/html/paint.js
CHANGED
|
@@ -24,7 +24,7 @@ import { alphaOf, inkColor, isTransparent, resolve } from './css/values.js';
|
|
|
24
24
|
import { blend, borderShades } from './css/color.js';
|
|
25
25
|
import { CONTAIN_LAYOUT, CONTAIN_PAINT, CONTAIN_SIZE, copyStyle, scrolls, } from './css/style.js';
|
|
26
26
|
import { contained } from './layout/block.js';
|
|
27
|
-
import { BOX_RAISES, LINE_BOX_RAISES, Box, CLAMPED, CLIPPED_CELLS, COLLAPSED_CELLS, FADED_BLOCKS, PAINT_ORDER, INLINE_OFFSETS, SHADOWED_TEXT, SHIFTED_LINES, TEXT_RAISES, TEXT_SHIFTS, } from './layout/boxes.js';
|
|
27
|
+
import { BOX_RAISES, LINE_BOX_RAISES, Box, CLAMPED, CLIPPED_CELLS, COLLAPSED_CELLS, FADED_BLOCKS, PAINT_ORDER, INLINE_OFFSETS, MOVED_OFF_LINES, SHADOWED_TEXT, SHIFTED_LINES, TEXT_RAISES, TEXT_SHIFTS, } from './layout/boxes.js';
|
|
28
28
|
import { CLIPPED_TEXT, clipBoxOf, depthOf, inklessLayout, layoutOffsetOf, layoutOffsets, } from './layout/inline.js';
|
|
29
29
|
import { tableGrid } from './layout/grid.js';
|
|
30
30
|
import { SvgDrawing, inlineDrawing } from './svg.js';
|
|
@@ -280,7 +280,7 @@ export function paintDocument(ctx, tree, options) {
|
|
|
280
280
|
if (!canFill(ctx))
|
|
281
281
|
return;
|
|
282
282
|
ctx.save();
|
|
283
|
-
const canvas = canvasBackground(tree
|
|
283
|
+
const canvas = canvasBackground(tree);
|
|
284
284
|
if (canvas)
|
|
285
285
|
paintCanvas(ctx, canvas, tree.root, options);
|
|
286
286
|
paintBox(ctx, tree.root, {
|
|
@@ -296,22 +296,41 @@ export function paintDocument(ctx, tree, options) {
|
|
|
296
296
|
* `<body>`'s, which then paints no background of its own. A document with
|
|
297
297
|
* no `<html>` tag has the root box standing in for its root element, and a
|
|
298
298
|
* `<body>` in it is still the body: mail often starts at `<body style>`.
|
|
299
|
-
*
|
|
300
|
-
*
|
|
299
|
+
* With neither tag, the root box stands in for the body, and the `<html>`
|
|
300
|
+
* around it is implied: an `html { … }` or a `:root { … }` background, which
|
|
301
|
+
* a test's reference sets on a document with no tags at all, has no box
|
|
302
|
+
* but the canvas to be painted on. `anchor` is the box the image is
|
|
303
|
+
* positioned against: the root element's, whichever box it came from.
|
|
301
304
|
*/
|
|
302
|
-
function canvasBackground(
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
!!
|
|
306
|
-
!!
|
|
305
|
+
function canvasBackground(tree) {
|
|
306
|
+
const root = tree.root;
|
|
307
|
+
const has = (s) => !isTransparent(s.backgroundColor) ||
|
|
308
|
+
!!s.backgroundImage ||
|
|
309
|
+
!!s.backgroundGradient ||
|
|
310
|
+
!!s.backgroundImages;
|
|
311
|
+
const implied = tree.impliedHtml;
|
|
312
|
+
if (implied) {
|
|
313
|
+
// an `<html>` that is not displayed has no background to give
|
|
314
|
+
if (implied.display === 'none')
|
|
315
|
+
return null;
|
|
316
|
+
if (has(implied))
|
|
317
|
+
return { style: implied, source: null, anchor: root };
|
|
318
|
+
// containment on either keeps the body's to the body (CSS Containment 2)
|
|
319
|
+
if (implied.contain || root.style.contain)
|
|
320
|
+
return null;
|
|
321
|
+
return has(root.style)
|
|
322
|
+
? { style: root.style, source: root, anchor: root }
|
|
323
|
+
: null;
|
|
324
|
+
}
|
|
307
325
|
const top = childNamed(root, 'html') ?? root;
|
|
308
|
-
if (has(top))
|
|
309
|
-
return { source: top, anchor: top };
|
|
326
|
+
if (has(top.style))
|
|
327
|
+
return { style: top.style, source: top, anchor: top };
|
|
310
328
|
const body = childNamed(top, 'body');
|
|
311
|
-
// containment on either keeps the body's to the body (CSS Containment 2)
|
|
312
329
|
if (!body || top.style.contain || body.style.contain)
|
|
313
330
|
return null;
|
|
314
|
-
return has(body)
|
|
331
|
+
return has(body.style)
|
|
332
|
+
? { style: body.style, source: body, anchor: top }
|
|
333
|
+
: null;
|
|
315
334
|
}
|
|
316
335
|
/** A box's child element of that name, or one inside the anonymous boxes
|
|
317
336
|
* it is wrapped in: a `<body>` in an `<html>` set `display: table` is in
|
|
@@ -328,7 +347,7 @@ function childNamed(box, name) {
|
|
|
328
347
|
}
|
|
329
348
|
return null;
|
|
330
349
|
}
|
|
331
|
-
function paintCanvas(ctx, { source, anchor }, root, options) {
|
|
350
|
+
function paintCanvas(ctx, { style: source, anchor }, root, options) {
|
|
332
351
|
const whole = options.canvas ?? {
|
|
333
352
|
x: root.x + options.originX,
|
|
334
353
|
y: root.y + options.originY,
|
|
@@ -338,8 +357,8 @@ function paintCanvas(ctx, { source, anchor }, root, options) {
|
|
|
338
357
|
const area = clampRect(options, Math.round(whole.x), Math.round(whole.y), Math.ceil(whole.width), Math.ceil(whole.height));
|
|
339
358
|
if (!area)
|
|
340
359
|
return;
|
|
341
|
-
const layers = layersOf(source
|
|
342
|
-
const visible = source.
|
|
360
|
+
const layers = layersOf(source) ?? [source];
|
|
361
|
+
const visible = source.visibility === 'visible';
|
|
343
362
|
for (let i = layers.length - 1; i >= 0; i -= 1) {
|
|
344
363
|
const style = layers[i];
|
|
345
364
|
if (!isTransparent(style.backgroundColor) && visible) {
|
|
@@ -403,22 +422,32 @@ function layersOf(style) {
|
|
|
403
422
|
*/
|
|
404
423
|
function paintLayers(ctx, box, options, image) {
|
|
405
424
|
// a background painted through the text is painted with it
|
|
406
|
-
// (`paintClippedText`), and not as a box
|
|
407
|
-
|
|
425
|
+
// (`paintClippedText`), and not as a box — but for what `border-area
|
|
426
|
+
// text` paints in the border as well
|
|
427
|
+
const style = box.style;
|
|
428
|
+
if (style.backgroundClipText && style.backgroundClip !== 'border-area') {
|
|
408
429
|
return;
|
|
409
|
-
|
|
430
|
+
}
|
|
431
|
+
const layers = layersOf(style);
|
|
410
432
|
if (!layers) {
|
|
411
|
-
|
|
412
|
-
if (image && box.style.backgroundImage)
|
|
413
|
-
image(box.style);
|
|
433
|
+
paintLayer(ctx, box, options, style, image);
|
|
414
434
|
return;
|
|
415
435
|
}
|
|
416
436
|
for (let i = layers.length - 1; i >= 0; i -= 1) {
|
|
417
|
-
|
|
418
|
-
if (image && layers[i].backgroundImage)
|
|
419
|
-
image(layers[i]);
|
|
437
|
+
paintLayer(ctx, box, options, layers[i], image);
|
|
420
438
|
}
|
|
421
439
|
}
|
|
440
|
+
function paintLayer(ctx, box, options, layer, image) {
|
|
441
|
+
// painted over the border box, inside what the border paints
|
|
442
|
+
const area = layer.backgroundClip === 'border-area';
|
|
443
|
+
if (area && !pushBorderArea(ctx, box, options))
|
|
444
|
+
return;
|
|
445
|
+
paintBackground(ctx, box, options, layer);
|
|
446
|
+
if (image && layer.backgroundImage)
|
|
447
|
+
image(layer);
|
|
448
|
+
if (area)
|
|
449
|
+
ctx.restore();
|
|
450
|
+
}
|
|
422
451
|
/** A box's padding box in window coordinates. */
|
|
423
452
|
function paddingBox(box, options) {
|
|
424
453
|
return {
|
|
@@ -627,14 +656,7 @@ function paintOwnBackground(ctx, box, options) {
|
|
|
627
656
|
if (style.boxShadow)
|
|
628
657
|
paintShadows(ctx, box, options, false);
|
|
629
658
|
if (box !== options.canvasSource) {
|
|
630
|
-
paintLayers(ctx, box, options, (
|
|
631
|
-
const painted = clipArea(box, options, layer, true);
|
|
632
|
-
const area = painted &&
|
|
633
|
-
clampRect(options, painted.x, painted.y, painted.w, painted.h);
|
|
634
|
-
if (area) {
|
|
635
|
-
paintBackgroundImage(ctx, layer, area, originBox(box, options, layer), options, painted.corners);
|
|
636
|
-
}
|
|
637
|
-
});
|
|
659
|
+
paintLayers(ctx, box, options, frameImages(ctx, box, options));
|
|
638
660
|
}
|
|
639
661
|
if (style.boxShadow)
|
|
640
662
|
paintShadows(ctx, box, options, true);
|
|
@@ -644,6 +666,21 @@ function paintOwnBackground(ctx, box, options) {
|
|
|
644
666
|
if (box.kind === 'table')
|
|
645
667
|
paintPartBackgrounds(ctx, box, options);
|
|
646
668
|
}
|
|
669
|
+
/**
|
|
670
|
+
* How `paintLayers` draws a frame's image layers: each in the area its
|
|
671
|
+
* `background-clip` names, from the box its `background-origin` names
|
|
672
|
+
* (CSS Backgrounds 3, 3.7 and 3.8) — a block's, or an inline box's
|
|
673
|
+
* fragment's, whose background is its images as much as its colour.
|
|
674
|
+
*/
|
|
675
|
+
function frameImages(ctx, frame, options) {
|
|
676
|
+
return (layer) => {
|
|
677
|
+
const painted = clipArea(frame, options, layer, true);
|
|
678
|
+
const area = painted && clampRect(options, painted.x, painted.y, painted.w, painted.h);
|
|
679
|
+
if (area) {
|
|
680
|
+
paintBackgroundImage(ctx, layer, area, originBox(frame, options, layer), options, painted.corners);
|
|
681
|
+
}
|
|
682
|
+
};
|
|
683
|
+
}
|
|
647
684
|
/** How far past its shape a shadow's blur shows: three standard deviations,
|
|
648
685
|
* the blur being two (CSS Backgrounds 3, 7.1.1). */
|
|
649
686
|
function shadowReach(blur) {
|
|
@@ -1215,9 +1252,10 @@ function spreadCorners(c, width, height, top, right, bottom, left) {
|
|
|
1215
1252
|
return rounded ? { x, y } : null;
|
|
1216
1253
|
}
|
|
1217
1254
|
/** How far in from a box's border box the box a `<visual-box>` names is:
|
|
1218
|
-
* top, right, bottom and left
|
|
1255
|
+
* top, right, bottom and left — none for `border-area`, whose layer is
|
|
1256
|
+
* painted over the border box inside what the border paints. */
|
|
1219
1257
|
function edgeInsets(box, which) {
|
|
1220
|
-
if (which === 'border-box')
|
|
1258
|
+
if (which === 'border-box' || which === 'border-area')
|
|
1221
1259
|
return NO_INSETS;
|
|
1222
1260
|
const t = box.borderTop;
|
|
1223
1261
|
const r = box.borderRight;
|
|
@@ -2821,6 +2859,88 @@ function roundedRing(ctx, box, x, y, w, h, options) {
|
|
|
2821
2859
|
}, insetCorners(corners, top, right, bottom, left));
|
|
2822
2860
|
return true;
|
|
2823
2861
|
}
|
|
2862
|
+
/**
|
|
2863
|
+
* Clip to what a box's border paints, for a layer of `background-clip:
|
|
2864
|
+
* border-area` (CSS Backgrounds 4, 2.1): each side's width and style, and
|
|
2865
|
+
* not its colour — a transparent border still has an area, which is what
|
|
2866
|
+
* the value is for. The shapes are the border painter's own, so that the
|
|
2867
|
+
* background shows exactly where that border would: the ring `roundedRing`
|
|
2868
|
+
* fills where a rounded border is solid, the ring the trapezoids of a 3D
|
|
2869
|
+
* style make, and otherwise the rectangles `fillEdge` fills a side at a
|
|
2870
|
+
* time — the dots, the dashes, the two lines of a double border. All of
|
|
2871
|
+
* them run clockwise and a ring's inside the other way, so the clip is the
|
|
2872
|
+
* union by the non-zero rule, the one every context's `clip` takes. False
|
|
2873
|
+
* where the border paints nothing or the context cannot clip, and nothing
|
|
2874
|
+
* is pushed.
|
|
2875
|
+
*/
|
|
2876
|
+
function pushBorderArea(ctx, box, options) {
|
|
2877
|
+
const t = box.borderTop;
|
|
2878
|
+
const r = box.borderRight;
|
|
2879
|
+
const b = box.borderBottom;
|
|
2880
|
+
const l = box.borderLeft;
|
|
2881
|
+
if (!(t || r || b || l) || !ctx.beginPath || !ctx.rect || !ctx.clip) {
|
|
2882
|
+
return false;
|
|
2883
|
+
}
|
|
2884
|
+
const s = box.style;
|
|
2885
|
+
const left = box.x + options.originX;
|
|
2886
|
+
const top = frameY(box) + options.originY;
|
|
2887
|
+
const x = Math.round(left);
|
|
2888
|
+
const y = Math.round(top);
|
|
2889
|
+
const w = Math.round(left + box.width) - x;
|
|
2890
|
+
const h = Math.round(top + frameHeight(box)) - y;
|
|
2891
|
+
if (w <= 0 || h <= 0)
|
|
2892
|
+
return false;
|
|
2893
|
+
const area = clampRect(options, x, y, w, h);
|
|
2894
|
+
if (!area)
|
|
2895
|
+
return false;
|
|
2896
|
+
const corners = cornersOf(s, w, h);
|
|
2897
|
+
ctx.save();
|
|
2898
|
+
ctx.beginPath();
|
|
2899
|
+
if (corners && canCurve(ctx) && solidBorder(box)) {
|
|
2900
|
+
roundedRect(ctx, area.x, area.y, area.w, area.h, corners, true);
|
|
2901
|
+
const iw = area.w - l - r;
|
|
2902
|
+
const ih = area.h - t - b;
|
|
2903
|
+
if (iw > 0 && ih > 0) {
|
|
2904
|
+
const inner = insetCorners(corners, t, r, b, l);
|
|
2905
|
+
roundedRect(ctx, area.x + l, area.y + t, iw, ih, inner, true, true);
|
|
2906
|
+
}
|
|
2907
|
+
}
|
|
2908
|
+
else if (sculpted(s)) {
|
|
2909
|
+
// a band a side, which the trapezoids cover between them
|
|
2910
|
+
ctx.rect(area.x, area.y, area.w, t);
|
|
2911
|
+
ctx.rect(area.x, area.y + area.h - b, area.w, b);
|
|
2912
|
+
ctx.rect(area.x, area.y + t, l, area.h - t - b);
|
|
2913
|
+
ctx.rect(area.x + area.w - r, area.y + t, r, area.h - t - b);
|
|
2914
|
+
}
|
|
2915
|
+
else {
|
|
2916
|
+
const path = { fillRect: ctx.rect.bind(ctx) };
|
|
2917
|
+
const edge = (ex, ey, ew, eh, style, horizontal) => {
|
|
2918
|
+
const rect = clampRect(options, ex, ey, ew, eh);
|
|
2919
|
+
if (rect)
|
|
2920
|
+
fillEdge(path, rect, horizontal ? ex : ey, style, horizontal);
|
|
2921
|
+
};
|
|
2922
|
+
const between = h - t - b;
|
|
2923
|
+
if (t > 0)
|
|
2924
|
+
edge(x, y, w, t, s.borderTopStyle, true);
|
|
2925
|
+
if (b > 0)
|
|
2926
|
+
edge(x, y + h - b, w, b, s.borderBottomStyle, true);
|
|
2927
|
+
if (l > 0)
|
|
2928
|
+
edge(x, y + t, l, between, s.borderLeftStyle, false);
|
|
2929
|
+
if (r > 0)
|
|
2930
|
+
edge(x + w - r, y + t, r, between, s.borderRightStyle, false);
|
|
2931
|
+
}
|
|
2932
|
+
ctx.clip();
|
|
2933
|
+
return true;
|
|
2934
|
+
}
|
|
2935
|
+
/** Whether every side a box has a border on is solid, which a rounded box
|
|
2936
|
+
* draws as one ring (`roundedRing`). */
|
|
2937
|
+
function solidBorder(box) {
|
|
2938
|
+
const s = box.style;
|
|
2939
|
+
return ((!box.borderTop || s.borderTopStyle === 'solid') &&
|
|
2940
|
+
(!box.borderRight || s.borderRightStyle === 'solid') &&
|
|
2941
|
+
(!box.borderBottom || s.borderBottomStyle === 'solid') &&
|
|
2942
|
+
(!box.borderLeft || s.borderLeftStyle === 'solid'));
|
|
2943
|
+
}
|
|
2824
2944
|
/** The border styles drawn in two shades, as though lit from the top left. */
|
|
2825
2945
|
const SCULPTED = new Set(['groove', 'ridge', 'inset', 'outset']);
|
|
2826
2946
|
function sculpted(s) {
|
|
@@ -3215,6 +3335,20 @@ function paintLines(ctx, box, options) {
|
|
|
3215
3335
|
if (line.y + line.height > top)
|
|
3216
3336
|
visible.push(line);
|
|
3217
3337
|
}
|
|
3338
|
+
// and a line the damage misses whose text or inline-block `position:
|
|
3339
|
+
// relative` moved into it: drawn by its line, it went undrawn with it
|
|
3340
|
+
const moved = MOVED_OFF_LINES.get(lines);
|
|
3341
|
+
if (moved && reachedOff(visible, moved, top, bottom)) {
|
|
3342
|
+
const drawn = new Set(visible);
|
|
3343
|
+
for (const line of moved) {
|
|
3344
|
+
if (movedInto(line, top, bottom))
|
|
3345
|
+
drawn.add(line);
|
|
3346
|
+
}
|
|
3347
|
+
visible.length = 0;
|
|
3348
|
+
for (const line of lines)
|
|
3349
|
+
if (drawn.has(line))
|
|
3350
|
+
visible.push(line);
|
|
3351
|
+
}
|
|
3218
3352
|
}
|
|
3219
3353
|
else {
|
|
3220
3354
|
visible.push(...lines);
|
|
@@ -3276,6 +3410,35 @@ function paintLines(ctx, box, options) {
|
|
|
3276
3410
|
}
|
|
3277
3411
|
}
|
|
3278
3412
|
}
|
|
3413
|
+
/** Whether any of the lines moved content was taken off, and the damage
|
|
3414
|
+
* does not already draw, has it within the damage's rows. */
|
|
3415
|
+
function reachedOff(visible, moved, top, bottom) {
|
|
3416
|
+
for (const line of moved) {
|
|
3417
|
+
if (!visible.includes(line) && movedInto(line, top, bottom))
|
|
3418
|
+
return true;
|
|
3419
|
+
}
|
|
3420
|
+
return false;
|
|
3421
|
+
}
|
|
3422
|
+
/** Whether what was moved off a line — its inline-blocks and images, where
|
|
3423
|
+
* their ink is, and its texts, where they are drawn — reaches the rows
|
|
3424
|
+
* between `top` and `bottom`. */
|
|
3425
|
+
function movedInto(line, top, bottom) {
|
|
3426
|
+
for (const placed of line.atomics) {
|
|
3427
|
+
const box = placed.box;
|
|
3428
|
+
if (box.boundsY < bottom && box.boundsY + box.boundsHeight > top) {
|
|
3429
|
+
return true;
|
|
3430
|
+
}
|
|
3431
|
+
}
|
|
3432
|
+
for (const text of line.texts) {
|
|
3433
|
+
const natural = text.layout.lines[text.layoutLine];
|
|
3434
|
+
if (!natural)
|
|
3435
|
+
continue;
|
|
3436
|
+
const y = text.drawY + natural.y;
|
|
3437
|
+
if (y < bottom && y + natural.height > top)
|
|
3438
|
+
return true;
|
|
3439
|
+
}
|
|
3440
|
+
return false;
|
|
3441
|
+
}
|
|
3279
3442
|
/**
|
|
3280
3443
|
* The part of each such fragment above its line, drawn again over the
|
|
3281
3444
|
* text there. CSS 2.1 Appendix E paints a block's inline content a line at
|
|
@@ -3297,7 +3460,7 @@ function paintBleeds(ctx, bleeds, options) {
|
|
|
3297
3460
|
ctx.beginPath();
|
|
3298
3461
|
ctx.rect(left, top, Math.ceil(fragment.width) + 2, bottom - top);
|
|
3299
3462
|
ctx.clip();
|
|
3300
|
-
paintLayers(ctx, fragment, options);
|
|
3463
|
+
paintLayers(ctx, fragment, options, frameImages(ctx, fragment, options));
|
|
3301
3464
|
paintBorders(ctx, fragment, options);
|
|
3302
3465
|
ctx.restore();
|
|
3303
3466
|
}
|
|
@@ -3755,7 +3918,10 @@ bleeds = null) {
|
|
|
3755
3918
|
};
|
|
3756
3919
|
if (fragment.width <= 0)
|
|
3757
3920
|
continue;
|
|
3758
|
-
|
|
3921
|
+
// its images from its own padding box, as its gradients are, each
|
|
3922
|
+
// fragment alike: `slice` would lay them out as though the fragments
|
|
3923
|
+
// were one box end to end, which a box on one line is
|
|
3924
|
+
paintLayers(ctx, fragment, options, frameImages(ctx, fragment, options));
|
|
3759
3925
|
paintBorders(ctx, fragment, options);
|
|
3760
3926
|
if (box.style.outlineStyle !== 'none')
|
|
3761
3927
|
paintOutline(ctx, fragment, options);
|