@flighthq/scene2d-dom 0.2.1-next.840.857425c

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.
Files changed (135) hide show
  1. package/dist/domBackground.d.ts +3 -0
  2. package/dist/domBackground.d.ts.map +1 -0
  3. package/dist/domBackground.js +9 -0
  4. package/dist/domBackground.js.map +1 -0
  5. package/dist/domBitmap.d.ts +4 -0
  6. package/dist/domBitmap.d.ts.map +1 -0
  7. package/dist/domBitmap.js +81 -0
  8. package/dist/domBitmap.js.map +1 -0
  9. package/dist/domCSSFilterBinding.d.ts +19 -0
  10. package/dist/domCSSFilterBinding.d.ts.map +1 -0
  11. package/dist/domCSSFilterBinding.js +36 -0
  12. package/dist/domCSSFilterBinding.js.map +1 -0
  13. package/dist/domCache.d.ts +14 -0
  14. package/dist/domCache.d.ts.map +1 -0
  15. package/dist/domCache.js +64 -0
  16. package/dist/domCache.js.map +1 -0
  17. package/dist/domClip.d.ts +3 -0
  18. package/dist/domClip.d.ts.map +1 -0
  19. package/dist/domClip.js +38 -0
  20. package/dist/domClip.js.map +1 -0
  21. package/dist/domClipContours.d.ts +6 -0
  22. package/dist/domClipContours.d.ts.map +1 -0
  23. package/dist/domClipContours.js +48 -0
  24. package/dist/domClipContours.js.map +1 -0
  25. package/dist/domClipRectangle.d.ts +6 -0
  26. package/dist/domClipRectangle.d.ts.map +1 -0
  27. package/dist/domClipRectangle.js +148 -0
  28. package/dist/domClipRectangle.js.map +1 -0
  29. package/dist/domFontSource.d.ts +5 -0
  30. package/dist/domFontSource.d.ts.map +1 -0
  31. package/dist/domFontSource.js +18 -0
  32. package/dist/domFontSource.js.map +1 -0
  33. package/dist/domHtmlView.d.ts +4 -0
  34. package/dist/domHtmlView.d.ts.map +1 -0
  35. package/dist/domHtmlView.js +28 -0
  36. package/dist/domHtmlView.js.map +1 -0
  37. package/dist/domImageSource.d.ts +4 -0
  38. package/dist/domImageSource.d.ts.map +1 -0
  39. package/dist/domImageSource.js +36 -0
  40. package/dist/domImageSource.js.map +1 -0
  41. package/dist/domMaterials.d.ts +15 -0
  42. package/dist/domMaterials.d.ts.map +1 -0
  43. package/dist/domMaterials.js +68 -0
  44. package/dist/domMaterials.js.map +1 -0
  45. package/dist/domNativeText.d.ts +5 -0
  46. package/dist/domNativeText.d.ts.map +1 -0
  47. package/dist/domNativeText.js +88 -0
  48. package/dist/domNativeText.js.map +1 -0
  49. package/dist/domNode2D.d.ts +5 -0
  50. package/dist/domNode2D.d.ts.map +1 -0
  51. package/dist/domNode2D.js +60 -0
  52. package/dist/domNode2D.js.map +1 -0
  53. package/dist/domReconcile.d.ts +9 -0
  54. package/dist/domReconcile.d.ts.map +1 -0
  55. package/dist/domReconcile.js +69 -0
  56. package/dist/domReconcile.js.map +1 -0
  57. package/dist/domRenderState.d.ts +5 -0
  58. package/dist/domRenderState.d.ts.map +1 -0
  59. package/dist/domRenderState.js +43 -0
  60. package/dist/domRenderState.js.map +1 -0
  61. package/dist/domRenderView.d.ts +4 -0
  62. package/dist/domRenderView.d.ts.map +1 -0
  63. package/dist/domRenderView.js +24 -0
  64. package/dist/domRenderView.js.map +1 -0
  65. package/dist/domRichText.d.ts +6 -0
  66. package/dist/domRichText.d.ts.map +1 -0
  67. package/dist/domRichText.js +184 -0
  68. package/dist/domRichText.js.map +1 -0
  69. package/dist/domScale9Mapper.d.ts +3 -0
  70. package/dist/domScale9Mapper.d.ts.map +1 -0
  71. package/dist/domScale9Mapper.js +37 -0
  72. package/dist/domScale9Mapper.js.map +1 -0
  73. package/dist/domScale9Shape.d.ts +10 -0
  74. package/dist/domScale9Shape.d.ts.map +1 -0
  75. package/dist/domScale9Shape.js +59 -0
  76. package/dist/domScale9Shape.js.map +1 -0
  77. package/dist/domShape.d.ts +4 -0
  78. package/dist/domShape.d.ts.map +1 -0
  79. package/dist/domShape.js +45 -0
  80. package/dist/domShape.js.map +1 -0
  81. package/dist/domStyle.d.ts +9 -0
  82. package/dist/domStyle.d.ts.map +1 -0
  83. package/dist/domStyle.js +25 -0
  84. package/dist/domStyle.js.map +1 -0
  85. package/dist/domTextHelpers.d.ts +6 -0
  86. package/dist/domTextHelpers.d.ts.map +1 -0
  87. package/dist/domTextHelpers.js +8 -0
  88. package/dist/domTextHelpers.js.map +1 -0
  89. package/dist/domTextInput.d.ts +4 -0
  90. package/dist/domTextInput.d.ts.map +1 -0
  91. package/dist/domTextInput.js +60 -0
  92. package/dist/domTextInput.js.map +1 -0
  93. package/dist/domTextLabel.d.ts +4 -0
  94. package/dist/domTextLabel.d.ts.map +1 -0
  95. package/dist/domTextLabel.js +75 -0
  96. package/dist/domTextLabel.js.map +1 -0
  97. package/dist/domTransform.d.ts +4 -0
  98. package/dist/domTransform.d.ts.map +1 -0
  99. package/dist/domTransform.js +16 -0
  100. package/dist/domTransform.js.map +1 -0
  101. package/dist/domVideo.d.ts +4 -0
  102. package/dist/domVideo.d.ts.map +1 -0
  103. package/dist/domVideo.js +27 -0
  104. package/dist/domVideo.js.map +1 -0
  105. package/dist/index.d.ts +24 -0
  106. package/dist/index.d.ts.map +1 -0
  107. package/dist/index.js +24 -0
  108. package/dist/index.js.map +1 -0
  109. package/package.json +55 -0
  110. package/src/domBackground.test.ts +35 -0
  111. package/src/domBitmap.test.ts +117 -0
  112. package/src/domCSSFilterBinding.test.ts +62 -0
  113. package/src/domCache.test.ts +93 -0
  114. package/src/domClip.test.ts +12 -0
  115. package/src/domClipContours.test.ts +62 -0
  116. package/src/domClipRectangle.test.ts +81 -0
  117. package/src/domFontSource.test.ts +30 -0
  118. package/src/domHtmlView.test.ts +117 -0
  119. package/src/domImageSource.test.ts +47 -0
  120. package/src/domMaterials.test.ts +100 -0
  121. package/src/domNativeText.test.ts +102 -0
  122. package/src/domNode2D.test.ts +236 -0
  123. package/src/domReconcile.test.ts +158 -0
  124. package/src/domRenderState.test.ts +87 -0
  125. package/src/domRenderView.test.ts +69 -0
  126. package/src/domRichText.test.ts +169 -0
  127. package/src/domScale9Mapper.test.ts +20 -0
  128. package/src/domScale9Shape.test.ts +76 -0
  129. package/src/domShape.test.ts +85 -0
  130. package/src/domStyle.test.ts +130 -0
  131. package/src/domTextHelpers.test.ts +27 -0
  132. package/src/domTextInput.test.ts +61 -0
  133. package/src/domTextLabel.test.ts +92 -0
  134. package/src/domTransform.test.ts +68 -0
  135. package/src/domVideo.test.ts +30 -0
@@ -0,0 +1,184 @@
1
+ import { computeRgbHexString } from '@flighthq/color';
2
+ import { createEntity } from '@flighthq/entity';
3
+ import { computeTextFormatFontString } from '@flighthq/text';
4
+ import { getRichTextPasswordCharacter, getRichTextRuntime } from '@flighthq/text';
5
+ import { computeRichTextContent, computeTextBoundsHeight, computeTextBoundsWidth, computeTextLayout, getRichTextContent, getRichTextScrollYOffset, getRichTextSelectionRectangles, getTextLayoutResult, } from '@flighthq/textlayout';
6
+ import { getDomFontAscentCached, setDomFontAscentCached } from './domFontSource';
7
+ import { applyDomStyle, prepareDomElement, setDomRendererElement } from './domStyle';
8
+ import { escapeDomHtmlString } from './domTextHelpers';
9
+ function createDomRichTextData(_state, _source) {
10
+ return createEntity({ div: null });
11
+ }
12
+ let _measureCtx = null;
13
+ function getMeasureCtx() {
14
+ if (_measureCtx === null) {
15
+ _measureCtx = document.createElement('canvas').getContext('2d');
16
+ }
17
+ return _measureCtx;
18
+ }
19
+ export function drawDomRichText(state, renderProxy) {
20
+ drawDomRichTextField(state, renderProxy);
21
+ // The editable-input overlay (caret/selection) appends into the field div and must run even when the
22
+ // text is empty, so it is invoked after the field, keyed off the input slot. registerDomTextInputOverlay
23
+ // (enableDomTextInput) installs it; a static RichText leaves the slot null and pulls no text-input code.
24
+ if (_domTextInputOverlay !== null && getRichTextRuntime(renderProxy.source).input !== null) {
25
+ _domTextInputOverlay(state, renderProxy);
26
+ }
27
+ }
28
+ export function drawDomRichTextMask(state, renderProxy) {
29
+ drawDomRichText(state, renderProxy);
30
+ }
31
+ function drawDomRichTextField(state, renderProxy) {
32
+ const data = renderProxy.rendererData;
33
+ if (data === null)
34
+ return;
35
+ const source = renderProxy.source;
36
+ const { background, backgroundColor, border, borderColor, wordWrap, multiline, scrollH, scrollV } = source.data;
37
+ if (data.div === null) {
38
+ data.div = document.createElement('div');
39
+ prepareDomElement(data.div);
40
+ data.div.style.overflow = 'hidden';
41
+ }
42
+ const richTextRuntime = getRichTextRuntime(source);
43
+ const content = getRichTextContent(richTextRuntime);
44
+ computeRichTextContent(content, source.data, getRichTextPasswordCharacter(source));
45
+ const { text } = content;
46
+ const ctx = getMeasureCtx();
47
+ if (ctx === null)
48
+ return;
49
+ const measure = (t, fmt) => {
50
+ ctx.font = computeTextFormatFontString(fmt);
51
+ return ctx.measureText(t).width;
52
+ };
53
+ const result = getTextLayoutResult(richTextRuntime);
54
+ computeTextLayout(result, {
55
+ text,
56
+ formatRanges: content.formatRanges,
57
+ width: wordWrap ? source.data.width : 10000,
58
+ height: source.data.height,
59
+ measure,
60
+ multiline,
61
+ verticalAlign: source.data.autoSize === 'none' ? source.data.verticalAlign : 'top',
62
+ wordWrap,
63
+ });
64
+ const fieldW = computeTextBoundsWidth(source.data, result);
65
+ const fieldH = computeTextBoundsHeight(source.data, result);
66
+ const div = data.div;
67
+ div.style.width = `${fieldW}px`;
68
+ div.style.height = `${fieldH}px`;
69
+ div.style.backgroundColor = background ? computeRgbHexString(backgroundColor) : '';
70
+ div.style.border = border ? `1px solid ${computeRgbHexString(borderColor)}` : '';
71
+ if (text.length === 0) {
72
+ div.innerHTML = '';
73
+ applyDomStyle(state, div, renderProxy);
74
+ setDomRendererElement(state, div);
75
+ return;
76
+ }
77
+ const firstVisibleLine = scrollV - 1;
78
+ const scrollYOffset = firstVisibleLine > 0 ? getRichTextScrollYOffset(result.lineHeights, firstVisibleLine) : 0;
79
+ const scrollXOffset = scrollH;
80
+ let html = '';
81
+ if (source.data.selectable && richTextRuntime.selectionBeginIndex !== richTextRuntime.selectionEndIndex) {
82
+ getRichTextSelectionRectangles(_richTextSelectionRectangles, richTextRuntime.selectionBeginIndex, richTextRuntime.selectionEndIndex, result);
83
+ for (const rectangle of _richTextSelectionRectangles) {
84
+ html += `<div style="position:absolute;left:${rectangle.x - scrollXOffset}px;top:${rectangle.y - scrollYOffset}px;width:${rectangle.width}px;height:${rectangle.height}px;background:${DOM_SELECTION_COLOR};opacity:${DOM_SELECTION_ALPHA};pointer-events:none;"></div>`;
85
+ }
86
+ }
87
+ const bulletLines = new Set();
88
+ for (const group of result.groups) {
89
+ if (group.lineIndex < firstVisibleLine)
90
+ continue;
91
+ const fmt = group.format;
92
+ const slice = escapeDomHtmlString(text.substring(group.startIndex, group.endIndex));
93
+ const x = group.offsetX - scrollXOffset;
94
+ const fontStr = computeTextFormatFontString(fmt);
95
+ // Align the CSS alphabetic baseline with canvas: canvas draws at offsetY + group.ascent
96
+ // (alphabetic baseline). CSS places the baseline at top + fontBoundingBoxAscent, so we
97
+ // shift the div top so the two positions coincide.
98
+ const fontAscent = getDomFontAscent(ctx, fontStr);
99
+ const y = group.offsetY + group.ascent - fontAscent - scrollYOffset;
100
+ if (fmt.bullet && !bulletLines.has(group.lineIndex)) {
101
+ bulletLines.add(group.lineIndex);
102
+ const bulletSize = fmt.size ?? 12;
103
+ const bulletX = x - bulletSize * 0.7 - DOM_BULLET_GAP;
104
+ const bulletStyle = `position:absolute;left:${bulletX}px;top:${y}px;font:${fontStr};line-height:1;color:${computeRgbHexString(fmt.color ?? source.data.textColor)};white-space:nowrap;`;
105
+ html += `<div style="${bulletStyle}">•</div>`;
106
+ }
107
+ let style = `position:absolute;left:${x}px;top:${y}px;font:${fontStr};line-height:1;`;
108
+ style += `color:${computeRgbHexString(fmt.color ?? source.data.textColor)};white-space:nowrap;`;
109
+ if (fmt.underline || fmt.strikethrough) {
110
+ const decorations = [];
111
+ if (fmt.underline)
112
+ decorations.push('underline');
113
+ if (fmt.strikethrough)
114
+ decorations.push('line-through');
115
+ style += `text-decoration:${decorations.join(' ')};`;
116
+ }
117
+ switch (fmt.align) {
118
+ case 'center':
119
+ style += 'text-align:center;';
120
+ break;
121
+ case 'right':
122
+ style += 'text-align:right;';
123
+ break;
124
+ case 'justify':
125
+ style += 'text-align:justify;';
126
+ break;
127
+ }
128
+ if (fmt.leftMargin != null)
129
+ style += `padding-left:${fmt.leftMargin}px;`;
130
+ if (fmt.rightMargin != null)
131
+ style += `padding-right:${fmt.rightMargin}px;`;
132
+ if (fmt.indent != null)
133
+ style += `text-indent:${fmt.indent}px;`;
134
+ html += `<div style="${style}">${slice}</div>`;
135
+ }
136
+ div.innerHTML = html;
137
+ applyDomStyle(state, div, renderProxy);
138
+ setDomRendererElement(state, div);
139
+ }
140
+ const DOM_BULLET_GAP = 4;
141
+ function getDomFontAscent(ctx, font) {
142
+ const cached = getDomFontAscentCached(font);
143
+ if (cached !== undefined)
144
+ return cached;
145
+ // Measure the CSS alphabetic baseline directly: a zero-height inline-block with
146
+ // vertical-align:baseline sits with its top edge exactly on the line's baseline.
147
+ // getBoundingClientRect() gives the exact pixel distance CSS uses, with no
148
+ // inference from canvas metrics. Falls back to canvas measurement in non-browser env.
149
+ const ascent = typeof document !== 'undefined' && document.body ? probeCssFontAscent(font) : canvasFontAscentFallback(ctx, font);
150
+ setDomFontAscentCached(font, ascent);
151
+ return ascent;
152
+ }
153
+ function probeCssFontAscent(font) {
154
+ const container = document.createElement('div');
155
+ container.style.cssText = `font:${font};line-height:1;position:fixed;top:0;left:0;visibility:hidden;pointer-events:none;white-space:nowrap`;
156
+ const probe = document.createElement('span');
157
+ probe.style.cssText = 'display:inline-block;height:0;vertical-align:baseline';
158
+ container.appendChild(document.createTextNode('H'));
159
+ container.appendChild(probe);
160
+ document.body.appendChild(container);
161
+ const containerTop = container.getBoundingClientRect().top;
162
+ const probeTop = probe.getBoundingClientRect().top;
163
+ document.body.removeChild(container);
164
+ return probeTop - containerTop;
165
+ }
166
+ function canvasFontAscentFallback(ctx, font) {
167
+ ctx.font = font;
168
+ const metrics = ctx.measureText('H');
169
+ const sizeMatch = /(\d+(?:\.\d+)?)px/.exec(font);
170
+ const size = sizeMatch ? parseFloat(sizeMatch[1]) : 12;
171
+ return metrics.fontBoundingBoxAscent ?? size * 0.85;
172
+ }
173
+ const DOM_SELECTION_ALPHA = 0.35;
174
+ const DOM_SELECTION_COLOR = '#0078d7';
175
+ const _richTextSelectionRectangles = [];
176
+ let _domTextInputOverlay = null;
177
+ export function registerDomTextInputOverlay(overlay) {
178
+ _domTextInputOverlay = overlay;
179
+ }
180
+ export const defaultDomRichTextRenderer = {
181
+ createData: createDomRichTextData,
182
+ submit: drawDomRichText,
183
+ };
184
+ //# sourceMappingURL=domRichText.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domRichText.js","sourceRoot":"","sources":["../src/domRichText.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { RectangleLike, Scale9Mapper } from '@flighthq/types';
2
+ export declare function buildDomScale9Mapper(bounds: Readonly<RectangleLike>, scale9Grid: Readonly<RectangleLike>, scaleX: number, scaleY: number): Scale9Mapper | null;
3
+ //# sourceMappingURL=domScale9Mapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domScale9Mapper.d.ts","sourceRoot":"","sources":["../src/domScale9Mapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEnE,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,EAC/B,UAAU,EAAE,QAAQ,CAAC,aAAa,CAAC,EACnC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,YAAY,GAAG,IAAI,CAcrB"}
@@ -0,0 +1,37 @@
1
+ export function buildDomScale9Mapper(bounds, scale9Grid, scaleX, scaleY) {
2
+ if (scaleX <= 0 || scaleY <= 0 || bounds.width <= 0 || bounds.height <= 0)
3
+ return null;
4
+ const gx = scale9Grid.x;
5
+ const gy = scale9Grid.y;
6
+ const gw = scale9Grid.width;
7
+ const gh = scale9Grid.height;
8
+ const bw = bounds.width;
9
+ const bh = bounds.height;
10
+ return {
11
+ mapX: (x) => toScale9Position(x, gx, gw, bw, scaleX),
12
+ mapY: (y) => toScale9Position(y, gy, gh, bh, scaleY),
13
+ };
14
+ }
15
+ function toScale9Position(pos, scale9Start, scale9Center, unscaledSize, scale) {
16
+ const scale9End = unscaledSize - scale9Center - scale9Start;
17
+ const size = unscaledSize * scale;
18
+ const center = size - scale9Start - scale9End;
19
+ if (pos <= scale9Start) {
20
+ if (center < 0) {
21
+ return (pos * (scale9Start + scale9End + center)) / (scale9Start + scale9End);
22
+ }
23
+ return pos;
24
+ }
25
+ if (pos >= scale9Start + scale9Center) {
26
+ if (center < 0) {
27
+ return (((scale9Start + (pos - scale9Start - scale9Center)) * (scale9Start + scale9End + center)) /
28
+ (scale9Start + scale9End));
29
+ }
30
+ return scale9Start + center + (pos - scale9Start - scale9Center);
31
+ }
32
+ if (center < 0) {
33
+ return (scale9Start * (scale9Start + scale9End + center)) / (scale9Start + scale9End);
34
+ }
35
+ return scale9Start + (center * (pos - scale9Start)) / scale9Center;
36
+ }
37
+ //# sourceMappingURL=domScale9Mapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domScale9Mapper.js","sourceRoot":"","sources":["../src/domScale9Mapper.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,oBAAoB,CAClC,MAA+B,EAC/B,UAAmC,EACnC,MAAc,EACd,MAAc;IAEd,IAAI,MAAM,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAEvF,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC;IACxB,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC;IACxB,MAAM,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC;IAC5B,MAAM,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC;IAC7B,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC;IACxB,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC;IAEzB,OAAO;QACL,IAAI,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC;QAC5D,IAAI,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC;KAC7D,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CACvB,GAAW,EACX,WAAmB,EACnB,YAAoB,EACpB,YAAoB,EACpB,KAAa;IAEb,MAAM,SAAS,GAAG,YAAY,GAAG,YAAY,GAAG,WAAW,CAAC;IAC5D,MAAM,IAAI,GAAG,YAAY,GAAG,KAAK,CAAC;IAClC,MAAM,MAAM,GAAG,IAAI,GAAG,WAAW,GAAG,SAAS,CAAC;IAE9C,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;QACvB,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,GAAG,CAAC,WAAW,GAAG,SAAS,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;QAChF,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,IAAI,GAAG,IAAI,WAAW,GAAG,YAAY,EAAE,CAAC;QACtC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACf,OAAO,CACL,CAAC,CAAC,WAAW,GAAG,CAAC,GAAG,GAAG,WAAW,GAAG,YAAY,CAAC,CAAC,GAAG,CAAC,WAAW,GAAG,SAAS,GAAG,MAAM,CAAC,CAAC;gBACzF,CAAC,WAAW,GAAG,SAAS,CAAC,CAC1B,CAAC;QACJ,CAAC;QACD,OAAO,WAAW,GAAG,MAAM,GAAG,CAAC,GAAG,GAAG,WAAW,GAAG,YAAY,CAAC,CAAC;IACnE,CAAC;IAED,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACf,OAAO,CAAC,WAAW,GAAG,CAAC,WAAW,GAAG,SAAS,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;IACxF,CAAC;IACD,OAAO,WAAW,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,GAAG,WAAW,CAAC,CAAC,GAAG,YAAY,CAAC;AACrE,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { Scene2DRenderer, DomRenderState, Renderable, RendererData, RenderProxy2D, RenderState } from '@flighthq/types';
2
+ interface DomScale9ShapeData extends RendererData {
3
+ canvas: HTMLCanvasElement | null;
4
+ context: CanvasRenderingContext2D | null;
5
+ }
6
+ export declare function createDomScale9ShapeData(_state: RenderState, _source: Renderable): DomScale9ShapeData;
7
+ export declare function drawDomScale9Shape(state: DomRenderState, renderProxy: RenderProxy2D): void;
8
+ export declare const defaultDomScale9ShapeRenderer: Scene2DRenderer;
9
+ export {};
10
+ //# sourceMappingURL=domScale9Shape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domScale9Shape.d.ts","sourceRoot":"","sources":["../src/domScale9Shape.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EAEd,UAAU,EACV,YAAY,EACZ,aAAa,EACb,WAAW,EAEZ,MAAM,iBAAiB,CAAC;AAMzB,UAAU,kBAAmB,SAAQ,YAAY;IAC/C,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACjC,OAAO,EAAE,wBAAwB,GAAG,IAAI,CAAC;CAC1C;AAID,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,GAAG,kBAAkB,CAErG;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,GAAG,IAAI,CAuC1F;AAED,eAAO,MAAM,6BAA6B,EAAE,eAG3C,CAAC"}
@@ -0,0 +1,59 @@
1
+ import { createEntity } from '@flighthq/entity';
2
+ import { getNodeLocalBoundsRectangle } from '@flighthq/node';
3
+ import { mapCanvasScale9ShapeCommands, renderCanvasShapeCommands } from '@flighthq/scene2d-canvas';
4
+ import { buildDomScale9Mapper } from './domScale9Mapper';
5
+ import { drawDomShape } from './domShape';
6
+ import { prepareDomElement, setDomRendererElement } from './domStyle';
7
+ const _remappedCommands = [];
8
+ export function createDomScale9ShapeData(_state, _source) {
9
+ return createEntity({ canvas: null, context: null });
10
+ }
11
+ export function drawDomScale9Shape(state, renderProxy) {
12
+ const data = renderProxy.rendererData;
13
+ if (data === null)
14
+ return;
15
+ const source = renderProxy.source;
16
+ const { commands, scale9Grid } = source.data;
17
+ if (commands.length === 0)
18
+ return;
19
+ const bounds = getNodeLocalBoundsRectangle(source);
20
+ const mapper = buildDomScale9Mapper(bounds, scale9Grid, source.scaleX, source.scaleY);
21
+ if (mapper === null) {
22
+ drawDomShape(state, renderProxy);
23
+ return;
24
+ }
25
+ if (data.canvas === null) {
26
+ data.canvas = document.createElement('canvas');
27
+ data.context = data.canvas.getContext('2d');
28
+ prepareDomElement(data.canvas);
29
+ }
30
+ const w = Math.max(1, Math.ceil(bounds.width * source.scaleX));
31
+ const h = Math.max(1, Math.ceil(bounds.height * source.scaleY));
32
+ data.canvas.width = w;
33
+ data.canvas.height = h;
34
+ const ctx = data.context;
35
+ mapCanvasScale9ShapeCommands(_remappedCommands, commands, mapper);
36
+ if (bounds.x !== 0 || bounds.y !== 0) {
37
+ ctx.translate(-bounds.x, -bounds.y);
38
+ }
39
+ renderCanvasShapeCommands(ctx, _remappedCommands);
40
+ data.canvas.style.opacity = renderProxy.alpha < 1 ? String(renderProxy.alpha) : '';
41
+ data.canvas.style.imageRendering = state.allowSmoothing ? '' : 'pixelated';
42
+ state.applyBlendMode?.(data.canvas, renderProxy.blendMode);
43
+ setStrippedDomTransform(data.canvas, renderProxy.transform2D, source.scaleX, source.scaleY, state.roundPixels);
44
+ setDomRendererElement(state, data.canvas);
45
+ }
46
+ export const defaultDomScale9ShapeRenderer = {
47
+ createData: createDomScale9ShapeData,
48
+ submit: drawDomScale9Shape,
49
+ };
50
+ function setStrippedDomTransform(element, transform, scaleX, scaleY, roundPixels) {
51
+ const a = scaleX !== 0 ? transform.a / scaleX : transform.a;
52
+ const b = scaleX !== 0 ? transform.b / scaleX : transform.b;
53
+ const c = scaleY !== 0 ? transform.c / scaleY : transform.c;
54
+ const d = scaleY !== 0 ? transform.d / scaleY : transform.d;
55
+ const tx = roundPixels ? Math.fround(transform.tx) : transform.tx;
56
+ const ty = roundPixels ? Math.fround(transform.ty) : transform.ty;
57
+ element.style.transform = `matrix(${a},${b},${c},${d},${tx},${ty})`;
58
+ }
59
+ //# sourceMappingURL=domScale9Shape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domScale9Shape.js","sourceRoot":"","sources":["../src/domScale9Shape.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Scene2DRenderer, DomRenderState, RenderProxy2D } from '@flighthq/types';
2
+ export declare function drawDomShape(state: DomRenderState, renderProxy: RenderProxy2D): void;
3
+ export declare const defaultDomShapeRenderer: Scene2DRenderer;
4
+ //# sourceMappingURL=domShape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domShape.d.ts","sourceRoot":"","sources":["../src/domShape.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EAGd,aAAa,EAGd,MAAM,iBAAiB,CAAC;AAczB,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,GAAG,IAAI,CAqCpF;AAED,eAAO,MAAM,uBAAuB,EAAE,eAGrC,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { createEntity } from '@flighthq/entity';
2
+ import { getNodeLocalBoundsRectangle } from '@flighthq/node';
3
+ import { renderCanvasShapeCommands } from '@flighthq/scene2d-canvas';
4
+ import { prepareDomElement, setDomRendererElement } from './domStyle';
5
+ import { setDomTransformWithOffset } from './domTransform';
6
+ function createDomShapeData(_state, _source) {
7
+ return createEntity({ canvas: null, context: null });
8
+ }
9
+ export function drawDomShape(state, renderProxy) {
10
+ const data = renderProxy.rendererData;
11
+ if (data === null)
12
+ return;
13
+ const source = renderProxy.source;
14
+ const { commands } = source.data;
15
+ if (commands.length === 0)
16
+ return;
17
+ if (data.canvas === null) {
18
+ data.canvas = document.createElement('canvas');
19
+ data.context = data.canvas.getContext('2d');
20
+ prepareDomElement(data.canvas);
21
+ }
22
+ const bounds = getNodeLocalBoundsRectangle(source);
23
+ const w = Math.max(1, Math.ceil(bounds.width));
24
+ const h = Math.max(1, Math.ceil(bounds.height));
25
+ // Resizing clears the canvas and resets context state
26
+ data.canvas.width = w;
27
+ data.canvas.height = h;
28
+ const ctx = data.context;
29
+ if (bounds.x !== 0 || bounds.y !== 0) {
30
+ ctx.translate(-bounds.x, -bounds.y);
31
+ }
32
+ renderCanvasShapeCommands(ctx, commands);
33
+ data.canvas.style.opacity = renderProxy.alpha < 1 ? String(renderProxy.alpha) : '';
34
+ if (state.domCssFilterResolver !== null) {
35
+ data.canvas.style.filter = state.domCssFilterResolver(renderProxy) ?? '';
36
+ }
37
+ state.applyBlendMode?.(data.canvas, renderProxy.blendMode);
38
+ setDomTransformWithOffset(data.canvas, renderProxy.transform2D, bounds.x, bounds.y, state.roundPixels);
39
+ setDomRendererElement(state, data.canvas);
40
+ }
41
+ export const defaultDomShapeRenderer = {
42
+ createData: createDomShapeData,
43
+ submit: drawDomShape,
44
+ };
45
+ //# sourceMappingURL=domShape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domShape.js","sourceRoot":"","sources":["../src/domShape.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAWrE,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAO3D,SAAS,kBAAkB,CAAC,MAAmB,EAAE,OAAmB;IAClE,OAAO,YAAY,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAqB,EAAE,WAA0B;IAC5E,MAAM,IAAI,GAAG,WAAW,CAAC,YAAmC,CAAC;IAC7D,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO;IAE1B,MAAM,MAAM,GAAG,WAAW,CAAC,MAAe,CAAC;IAC3C,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC;IACjC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAElC,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC/C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC5C,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAED,MAAM,MAAM,GAAG,2BAA2B,CAAC,MAAM,CAAC,CAAC;IACnD,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAEhD,sDAAsD;IACtD,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;IACtB,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IAEvB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAQ,CAAC;IAC1B,IAAI,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,GAAG,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IAED,yBAAyB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAEzC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,WAAW,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACnF,IAAI,KAAK,CAAC,oBAAoB,KAAK,IAAI,EAAE,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,oBAAoB,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;IAC3E,CAAC;IACD,KAAK,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IAC3D,yBAAyB,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;IAEvG,qBAAqB,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,MAAM,uBAAuB,GAAoB;IACtD,UAAU,EAAE,kBAAkB;IAC9B,MAAM,EAAE,YAAY;CACrB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { DomRenderState, RenderProxy2D } from '@flighthq/types';
2
+ export declare function applyDomStyle(state: DomRenderState, element: HTMLElement, node: RenderProxy2D): void;
3
+ export declare function prepareDomElement(element: HTMLElement): void;
4
+ /**
5
+ * Registers the element produced by a renderer for this draw call.
6
+ * Placement into the container is always handled by the render loop, never by individual draw functions.
7
+ */
8
+ export declare function setDomRendererElement(state: DomRenderState, element: HTMLElement): void;
9
+ //# sourceMappingURL=domStyle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domStyle.d.ts","sourceRoot":"","sources":["../src/domStyle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAKrE,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,CAMpG;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAM5D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAEvF"}
@@ -0,0 +1,25 @@
1
+ import { getDomRenderStateRuntime } from './domRenderState';
2
+ import { setDomTransform } from './domTransform';
3
+ export function applyDomStyle(state, element, node) {
4
+ setDomTransform(element, node.transform2D, state.roundPixels);
5
+ element.style.opacity = node.alpha < 1 ? String(node.alpha) : '';
6
+ element.style.imageRendering = state.allowSmoothing ? '' : 'pixelated';
7
+ if (state.domCssFilterResolver !== null)
8
+ element.style.filter = state.domCssFilterResolver(node) ?? '';
9
+ state.applyBlendMode?.(element, node.blendMode);
10
+ }
11
+ export function prepareDomElement(element) {
12
+ element.style.position = 'absolute';
13
+ element.style.left = '0';
14
+ element.style.top = '0';
15
+ element.style.transformOrigin = '0 0';
16
+ element.style.pointerEvents = 'none';
17
+ }
18
+ /**
19
+ * Registers the element produced by a renderer for this draw call.
20
+ * Placement into the container is always handled by the render loop, never by individual draw functions.
21
+ */
22
+ export function setDomRendererElement(state, element) {
23
+ getDomRenderStateRuntime(state).domCurrentElement = element;
24
+ }
25
+ //# sourceMappingURL=domStyle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domStyle.js","sourceRoot":"","sources":["../src/domStyle.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,MAAM,UAAU,aAAa,CAAC,KAAqB,EAAE,OAAoB,EAAE,IAAmB;IAC5F,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;IAC9D,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACjE,OAAO,CAAC,KAAK,CAAC,cAAc,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;IACvE,IAAI,KAAK,CAAC,oBAAoB,KAAK,IAAI;QAAE,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACvG,KAAK,CAAC,cAAc,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAoB;IACpD,OAAO,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC;IACpC,OAAO,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC;IACzB,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC;IACxB,OAAO,CAAC,KAAK,CAAC,eAAe,GAAG,KAAK,CAAC;IACtC,OAAO,CAAC,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC;AACvC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAqB,EAAE,OAAoB;IAC/E,wBAAwB,CAAC,KAAK,CAAC,CAAC,iBAAiB,GAAG,OAAO,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Escapes HTML special characters in a text string for safe embedding as DOM inner HTML.
3
+ * Used internally by the DOM text renderers (RichText, TextLabel) to render text via innerHTML.
4
+ */
5
+ export declare function escapeDomHtmlString(str: string): string;
6
+ //# sourceMappingURL=domTextHelpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domTextHelpers.d.ts","sourceRoot":"","sources":["../src/domTextHelpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEvD"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Escapes HTML special characters in a text string for safe embedding as DOM inner HTML.
3
+ * Used internally by the DOM text renderers (RichText, TextLabel) to render text via innerHTML.
4
+ */
5
+ export function escapeDomHtmlString(str) {
6
+ return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/ /g, '&nbsp;');
7
+ }
8
+ //# sourceMappingURL=domTextHelpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domTextHelpers.js","sourceRoot":"","sources":["../src/domTextHelpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AACxG,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { DomRenderState, RenderProxy2D } from '@flighthq/types';
2
+ export declare function drawDomTextInputOverlay(_state: DomRenderState, renderProxy: RenderProxy2D): void;
3
+ export declare function enableDomTextInput(): void;
4
+ //# sourceMappingURL=domTextInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domTextInput.d.ts","sourceRoot":"","sources":["../src/domTextInput.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAgB,aAAa,EAAoC,MAAM,iBAAiB,CAAC;AAYrH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,GAAG,IAAI,CAiChG;AAID,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
@@ -0,0 +1,60 @@
1
+ import { computeRgbHexString } from '@flighthq/color';
2
+ import { getRichTextRuntime } from '@flighthq/text';
3
+ import { getTextInputCaretRectangle, getTextInputSelectionBeginIndex, getTextInputSelectionEndIndex, getTextInputSelectionRectangles, getTextInputState, } from '@flighthq/textinput';
4
+ import { getRichTextScrollYOffset } from '@flighthq/textlayout';
5
+ import { registerDomTextInputOverlay } from './domRichText';
6
+ let _keyframesInjected = false;
7
+ // Appends the editable-field overlay (selection highlight + blinking caret) into the field div of a
8
+ // RichText whose input slot is present. Invoked by the DOM RichText renderer after the field.
9
+ export function drawDomTextInputOverlay(_state, renderProxy) {
10
+ if (!_keyframesInjected) {
11
+ injectCaretBlinkKeyframes();
12
+ _keyframesInjected = true;
13
+ }
14
+ const source = renderProxy.source;
15
+ const input = getTextInputState(source);
16
+ if (input === null)
17
+ return;
18
+ const layout = getRichTextRuntime(source).textLayout;
19
+ const data = renderProxy.rendererData;
20
+ if ((!input.focused && !input.alwaysShowSelection) || layout === null || data?.div == null)
21
+ return;
22
+ const firstVisibleLine = source.data.scrollV - 1;
23
+ const scrollYOffset = firstVisibleLine > 0 ? getRichTextScrollYOffset(layout.lineHeights, firstVisibleLine) : 0;
24
+ const scrollXOffset = source.data.scrollH;
25
+ const selColor = computeRgbHexString(input.selectionColor);
26
+ const selAlpha = input.selectionAlpha;
27
+ let html = '';
28
+ getTextInputSelectionRectangles(selectionRectangles, source, layout);
29
+ for (const rect of selectionRectangles) {
30
+ html += `<div data-input-overlay style="position:absolute;left:${rect.x - scrollXOffset}px;top:${rect.y - scrollYOffset}px;width:${rect.width}px;height:${rect.height}px;background:${selColor};opacity:${selAlpha};pointer-events:none;"></div>`;
31
+ }
32
+ if (input.focused && getTextInputSelectionBeginIndex(source) === getTextInputSelectionEndIndex(source)) {
33
+ getTextInputCaretRectangle(caretRectangle, source, layout);
34
+ html += `<div data-input-overlay style="position:absolute;left:${caretRectangle.x - scrollXOffset}px;top:${caretRectangle.y - scrollYOffset}px;width:${input.caretWidth}px;height:${caretRectangle.height}px;background:${computeRgbHexString(input.caretColor)};animation:flight-caret-blink 1s step-end infinite;pointer-events:none;"></div>`;
35
+ }
36
+ for (const el of data.div.querySelectorAll('[data-input-overlay]'))
37
+ el.remove();
38
+ if (html.length > 0) {
39
+ data.div.insertAdjacentHTML('beforeend', html);
40
+ }
41
+ }
42
+ // Installs the caret/selection overlay onto the DOM RichText renderer. Importing this opts an app into
43
+ // text-input rendering; a static RichText leaves the slot null and pulls none of this module.
44
+ export function enableDomTextInput() {
45
+ registerDomTextInputOverlay(drawDomTextInputOverlay);
46
+ }
47
+ function injectCaretBlinkKeyframes() {
48
+ if (typeof document === 'undefined')
49
+ return;
50
+ const id = 'flight-caret-blink-style';
51
+ if (document.getElementById(id))
52
+ return;
53
+ const style = document.createElement('style');
54
+ style.id = id;
55
+ style.textContent = '@keyframes flight-caret-blink{0%,100%{opacity:1}50%{opacity:0}}';
56
+ document.head.appendChild(style);
57
+ }
58
+ const caretRectangle = { height: 0, lineIndex: 0, width: 0, x: 0, y: 0 };
59
+ const selectionRectangles = [];
60
+ //# sourceMappingURL=domTextInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domTextInput.js","sourceRoot":"","sources":["../src/domTextInput.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Scene2DRenderer, DomRenderState, RenderProxy2D } from '@flighthq/types';
2
+ export declare function drawDomTextLabel(state: DomRenderState, renderProxy: RenderProxy2D): void;
3
+ export declare const defaultDomTextLabelRenderer: Scene2DRenderer;
4
+ //# sourceMappingURL=domTextLabel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domTextLabel.d.ts","sourceRoot":"","sources":["../src/domTextLabel.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EAGd,aAAa,EAKd,MAAM,iBAAiB,CAAC;AAsBzB,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,GAAG,IAAI,CA0DxF;AAED,eAAO,MAAM,2BAA2B,EAAE,eAGzC,CAAC"}