gesso-core 0.6.0 → 0.6.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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # gesso-core
2
2
 
3
+ ## 0.6.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 45f3ffe: Copying a selection over truncated text now copies the text the truncation hides, as a browser does with `text-overflow`. A `<text>` with `maxLines` or `textOverflow="ellipsis"` used to copy only the glyphs it drew, so a title shown as "Brand Story & Brand…" copied as "Brand Story & Brand".
8
+
9
+ A selection that stays inside the drawn glyphs still copies just those. One that reaches the end of a truncated line, onto the far half of the ellipsis or past the last glyph, copies through the end of the string, and so do select all, a selection that runs through a truncated node on its way to the next, and a triple click on the line. A double click on a word the ellipsis cuts takes the whole word. The ellipsis is highlighted whenever the selection includes text it hides.
10
+
11
+ `ParagraphGeometry` gains `source`, the whole text, and `sourceEnd`, the offset a selection may run to; `offsetAtPointIn` can answer `sourceEnd` and `selectionRectsIn` includes the ellipsis box for a range that reaches past `end`.
12
+
3
13
  ## 0.6.0
4
14
 
5
15
  ### Minor Changes
@@ -8987,11 +8987,14 @@ function paragraphGeometryFrom(lines, text, box, state, measurer) {
8987
8987
  function geometryFor(lines, text, request, state, measurer) {
8988
8988
  const end = lines.length === 0 ? 0 : lines[lines.length - 1].end;
8989
8989
  const spanned = spannedRunsFor(request, measurer);
8990
+ const truncated = end < text.length && /\S/.test(text.slice(end));
8990
8991
  return {
8991
8992
  lines,
8992
8993
  text: end === text.length ? text : text.slice(0, end),
8993
8994
  start: lines.length === 0 ? 0 : lines[0].start,
8994
8995
  end,
8996
+ source: text,
8997
+ sourceEnd: truncated ? text.length : end,
8995
8998
  measure: (run, from) => run.length === 0 ? 0 : spanned === void 0 || from === void 0 ? measurer.measureRunWidth(run, request) : spanned.width(text, from, from + run.length),
8996
8999
  rtl: state.rtl,
8997
9000
  hidden: state.spans === void 0 ? NO_RANGES : hiddenRangesOf(state.spans)
@@ -9001,21 +9004,73 @@ function geometryFor(lines, text, request, state, measurer) {
9001
9004
  function hasDrawnText(geometry) {
9002
9005
  return geometry.lines.length > 0 && geometry.end > geometry.start;
9003
9006
  }
9004
- /** The offset nearest a point, clamped to the drawn text. */
9007
+ /**
9008
+ * The offset nearest a point: within the drawn text, or `sourceEnd`
9009
+ * when the point is past the last drawn glyph of a truncated paragraph.
9010
+ */
9005
9011
  function offsetAtPointIn(geometry, x, y) {
9006
- if (geometry.lines.length === 0) return 0;
9007
- return offsetAtPoint(geometry.lines, geometry.text, x, y, geometry.measure, geometry.rtl);
9012
+ const lines = geometry.lines;
9013
+ if (lines.length === 0) return 0;
9014
+ const offset = offsetAtPoint(lines, geometry.text, x, y, geometry.measure, geometry.rtl);
9015
+ if (offset !== geometry.end || geometry.sourceEnd === geometry.end || lineIndexAtY(lines, y) !== lines.length - 1) return offset;
9016
+ const line = lines[lines.length - 1];
9017
+ const drawn = drawnWidth(geometry);
9018
+ return (geometry.rtl ? line.x + line.width - x : x - line.x) > drawn + (line.width - drawn) / 2 ? geometry.sourceEnd : offset;
9008
9019
  }
9009
- /** The boxes covering `[start, end)`, one per line the range touches. */
9020
+ /**
9021
+ * The boxes covering `[start, end)`, one per line the range touches.
9022
+ * A range reaching into the hidden tail lights the ellipsis, which is
9023
+ * where that text is on screen.
9024
+ */
9010
9025
  function selectionRectsIn(geometry, start, end) {
9026
+ if (geometry.lines.length === 0) return [];
9011
9027
  const from = clamp(start, geometry.start, geometry.end);
9012
9028
  const to = clamp(end, geometry.start, geometry.end);
9013
- if (geometry.lines.length === 0 || to <= from) return [];
9014
- return selectionRects(geometry.lines, geometry.text, from, to, geometry.measure, geometry.rtl);
9029
+ const rects = to <= from ? [] : selectionRects(geometry.lines, geometry.text, from, to, geometry.measure, geometry.rtl);
9030
+ const ellipsis = end > geometry.end && start < geometry.sourceEnd && geometry.sourceEnd > geometry.end ? ellipsisBox(geometry) : void 0;
9031
+ if (ellipsis === void 0) return rects;
9032
+ const last = rects.length === 0 ? void 0 : rects[rects.length - 1];
9033
+ if (last !== void 0 && last.y === ellipsis.y) {
9034
+ const left = Math.min(last.x, ellipsis.x);
9035
+ const right = Math.max(last.x + last.width, ellipsis.x + ellipsis.width);
9036
+ rects[rects.length - 1] = {
9037
+ x: left,
9038
+ y: last.y,
9039
+ width: right - left,
9040
+ height: last.height
9041
+ };
9042
+ } else rects.push(ellipsis);
9043
+ return rects;
9015
9044
  }
9016
- /** The word around an offset, for a double click. */
9045
+ /**
9046
+ * The word around an offset, for a double click. Read from the source,
9047
+ * so a word the ellipsis cuts is taken whole, as a browser takes it.
9048
+ */
9017
9049
  function wordRangeIn(geometry, offset) {
9018
- return visibleWordRange(geometry.text, geometry.hidden, clamp(offset, geometry.start, geometry.end));
9050
+ const word = visibleWordRange(geometry.source, geometry.hidden, clamp(offset, geometry.start, geometry.sourceEnd));
9051
+ return {
9052
+ start: word.start,
9053
+ end: Math.min(word.end, geometry.sourceEnd)
9054
+ };
9055
+ }
9056
+ /** The advance of the last line's drawn glyphs, its ellipsis excluded. */
9057
+ function drawnWidth(geometry) {
9058
+ const line = geometry.lines[geometry.lines.length - 1];
9059
+ const drawn = geometry.text.slice(line.start, geometry.end);
9060
+ return drawn.length === line.text.length ? line.width : geometry.measure(drawn, line.start);
9061
+ }
9062
+ /** The ellipsis on the last line, or undefined for a clamp that draws none. */
9063
+ function ellipsisBox(geometry) {
9064
+ const line = geometry.lines[geometry.lines.length - 1];
9065
+ const drawn = drawnWidth(geometry);
9066
+ const width = line.width - drawn;
9067
+ if (width <= 0) return;
9068
+ return {
9069
+ x: geometry.rtl ? line.x : line.x + drawn,
9070
+ y: line.y,
9071
+ width,
9072
+ height: line.height
9073
+ };
9019
9074
  }
9020
9075
  function clamp(value, low, high) {
9021
9076
  return value < low ? low : value > high ? high : value;
@@ -21157,4 +21212,4 @@ function createCanvasSurface(host) {
21157
21212
  //#endregion
21158
21213
  export { pointerDeviceOf as $, UiKeyboardEvent as $a, boxShadow as $i, lineIndexAtY as $n, radialGradient as $r, DEFAULT_FONT_SIZE as $t, withOverrideSource as A, rgb8 as Aa, darkTheme as Ai, linkRunAtPointIn as An, UiProperties as Ar, edgeField as At, FlexDirection as B, writeDeclaredProperty as Ba, withThemeExtension as Bi, isReadOnly as Bn, validateSubgrid as Br, fillTextRects as Bt, SCROLLBAR_LINGER_MS as C, UiBasicColors as Ca, insetsEqual as Ci, isNodeTabStop as Cn, findPropertyDefinition as Cr, offsetAtPointIn as Ct, formatExplanation as D, colorsEqual as Da, bandOf as Di, hasTextLinks as Dn, propertyEffects as Dr, wordRangeIn as Dt, formatConstraints as E, colorValuesEqual as Ea, UiContainerSizeSource as Ei, clearLinkHover as En, inheritedPropertyNames as Er, selectionRectsIn as Et, clampSize as F, UiNode as Fa, defineThemeExtension as Fi, caretVisibleAt as Fn, normalizeStates as Fr, EditableLayout as Ft, CrossAxisAlignment as G, visualState as Ga, densityFactors as Gi, videoFrameSize as Gn, parseTransform as Gr, textMeasureRequest as Gt, placeGridItems as H, UiVisualState as Ha, highContrastColors as Hi, syncEditorValue as Hn, paintValuesEqual as Hr, runCanvasStyleInto as Ht, constraintsEqual as I, DirtyNodeSet as Ia, hasThemeExtension as Ii, editorFor as In, statesEqual as Ir, applyCanvasTextStyle as It, parseCrossAxisAlignment as J, UiBeforeInputEvent as Ja, spacingEqual as Ji, spannedRunsFor as Jn, transformsEqual as Jr, bumpFontStack as Jt, MainAxisAlignment as K, visualStatesEqual as Ka, defaultSpacing as Ki, CharacterCountTextMeasurer as Kn, transform as Kr, textRunBackgrounds as Kt, tightenConstraints as L, clearOverrideProperty as La, noThemeExtensions as Li, editorOf as Ln, validateRole as Lr, buildFontString as Lt, contentOffset as M, createEnvironmentKey as Ma, themesEqual as Mi, CARET_BLINK_MS as Mn, UI_SEMANTIC_STATES as Mr, commandForKey as Mt, LayoutRecord as N, findEnvironmentKey as Na, withContrast as Ni, CARET_WIDTH as Nn, isUiRole as Nr, detectEditingPlatform as Nt, formatNumber as O, normalizeColor as Oa, containerBands as Oi, linkHoverOf as On, propertyIsInherited as Or, adjacentField as Ot, Constraints as P, UiEnvironment as Pa, withDensity as Pi, EDITOR_PROP as Pn, isUiSemanticState as Pr, isPrintable as Pt, capturePointer as Q, UiInputEvent as Qa, BOX_SHADOW_BLUR_REACH as Qi, caretRectFor as Qn, linearGradient as Qr, DEFAULT_FONT_FAMILY as Qt, MAX_MEASURES_PER_CHILD as R, overrideSources as Ra, themeExtension as Ri, isEditableNode as Rn, validateStates as Rr, createCanvasTextStyle as Rt, SCROLLBAR_FADE_MS as S, lightColors as Sa, UiInsetRegistry as Si, isNodeSelectable as Sn, closestPropertyName as Sr, hasDrawnText as St, describeOverrides as T, colorToRgba as Ta, observeViewportInsets as Ti, resolveCursor as Tn, inheritedPropertyFlags as Tr, paragraphGeometryFrom as Tt, sizeGridTracks as U, defaultVisualState as Ua, raiseContrast as Ui, resolveColorValue as Un, pathValuesEqual as Ur, runFontString as Ut, parseFlexDirection as V, writeOverrideProperty as Va, contrastRatio as Vi, nextCaretToggle as Vn, inputsEqual as Vr, layoutTextLines as Vt, AlignContent as W, hasVisualState as Wa, relativeLuminance as Wi, isVideoSurface as Wn, UiTransforms as Wr, spanOf as Wt, CanvasPlatformSurface as X, UiFocusEvent as Xa, defaultShadows as Xi, layoutParagraph as Xn, gradientPaint as Xr, fontStackFor as Xt, parseMainAxisAlignment as Y, UiEventType as Ya, spacingSteps as Yi, ELLIPSIS as Yn, MAX_GRADIENT_STOPS as Yr, clearFontStacks as Yt, UiPlatformAdapter as Z, UiGestureEvent as Za, shadowsEqual as Zi, proportionalFontMetrics as Zn, gradientsEqual as Zr, registerFontStack as Zt, LABEL_PADDING_X as _, textContentOf as _a, normalizeBorderRadius as _i, selectionRangeOf as _n, resolveBoolean as _r, scrollRange as _t, PaintPictureCache as a, isShapeName as aa, isMinMaxTrack as ai, isPaintVisible as an, UiWheelDeltaMode as ao, selectionRects as ar, UiPinchRecognizer as at, snapScroll as b, colorsEqualPalette as ba, propertyValuesEqual as bi, isNodeHitTestable as bn, resolvePropertyByName as br, scrollbarZoneAt as bt, EMPTY_RECORDING as c, isTypographyRole as ca, percent as ci, resolvePaintState as cn, wheelDeltaYOf as co, lineEndAt as cr, UiKeyboardController as ct, tracePathData as d, editableSpansOf as da, UiBorderRadiuses as di, matchRangesOf as dn, UiBinding as do, nextWordEnd as dr, UiHitTester as dt, boxShadowArraysEqual as ea, validateGradient as ei, DEFAULT_FONT_WEIGHT as en, UiPasteEvent as eo, lineIndexForOffset as er, prepareInputSurface as et, ScaledImageCache as f, flattenTextSpans as fa, borderRadius as fi, setMatchRanges as fn, previousGraphemeStart as fr, SCROLLBAR_HOVER_ZONE as ft, paintsAfterChildren as g, spannedTextOf as ga, borderRadiusValuesEqual as gi, selectableTextOf as gn, DEFAULT_LINE_HEIGHT_FACTOR as gr, scrollLeaderOf as gt, hasDecorationPhase as h, spanAtOffset as ha, borderRadiusIsZero as hi, selectableTextNodes as hn, UiGraph as hr, SCROLLBAR_THICKNESS as ht, traceRoundedRect as i, defaultShapes as ia, isFrLength as ii, createPaintState as in, UiTextChangeEvent as io, offsetForVerticalMove as ir, UiGestureRecognizer as it, accumulatedOffsetTo as j, rgba as ja, lightTheme as ji, setLinkHover as jn, UI_ROLES as jr, editingGroupOf as jt, labelNode as k, parseColor as ka, unknownContainerSize as ki, linkOf as kn, propertyValuesEqualByName as kr, comparePositions as kt, PaintRecorder as l, typographyEqual as la, repeat as li, TEXT_MATCHES_PROP as ln, UiNodeType as lo, lineStartAt as lr, UiPointerController as lt, decorationRect as m, resolvedSpansOf as ma, borderRadiusEqual as mi, clearSelectionRange as mn, wordRangeAt as mr, SCROLLBAR_MIN_THUMB as mt, createCanvasSurface as n, boxShadowReach as na, fr as ni, colorToCss as nn, UiPointerEvent as no, offsetAtPoint as nr, UiEditingController as nt, paintPictures as o, shapesEqual as oa, isPercentLength as oi, normalizeTextAlign as on, UiWheelEvent as oo, EditableTextModel as or, UiWheelController as ot, decorationColor as p, hiddenRangesOf as pa, borderRadiusCorners as pi, TEXT_SELECTION_PROP as pn, previousWordStart as pr, SCROLLBAR_INSET as pt, parseAlignContent as q, MOUSE_POINTER as qa, scaleSpacing as qi, ParagraphTextMeasurer as qn, transformIsIdentity as qr, textRunDecorations as qt, Canvas2DRenderer as r, boxShadowsEqual as ra, isAutoLength as ri, computeObjectFitRect as rn, UiSelectionChangeEvent as ro, offsetAtX as rr, UiTouchScroller as rt, PaintTarget as s, defaultTypography as sa, minmax as si, normalizeVerticalAlign as sn, noKeyModifiers as so, graphemeBoundaries as sr, isScrollContainer as st, CanvasSurface as t, boxShadowRadius as ta, auto as ti, DEFAULT_TEXT_COLOR as tn, UiPinchEvent as to, lineLimit as tr, touchActionFor as tt, replayPaint as u, defaultTextStyle as ua, resolveLength as ui, clearMatchRanges as un, DirtyFlags as uo, nextGraphemeEnd as ur, UiFocusManager as ut, drawOverlayShapes as v, textSpansEqual as va, uniformBorderRadius as vi, setSelectionRange as vn, resolveNumber as vr, scrollbarThumb as vt, describeLength as w, colorToHex as wa, noInsets as wi, isPressable as wn, getPropertyNames as wr, paragraphGeometry as wt, LayoutEngine as x, darkColors as xa, UiEnvironmentKeys as xi, isNodeInert as xn, resolveString as xr, UiInputDispatcher as xt, labelOrigin as y, textStylesEqual as ya, defineProperty as yi, isNodeFocusable as yn, resolveProperty as yr, scrollbarThumbs as yt, isLayoutProtocol as z, resetOverrideWarnings as za, themeExtensionsEqual as zi, isMultiline as zn, UI_SUBGRID_AXES as zr, drawText as zt };
21159
21214
 
21160
- //# sourceMappingURL=CanvasSurface-CKvX3pXn.js.map
21215
+ //# sourceMappingURL=CanvasSurface-Bxu_gNmc.js.map