@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.
- package/dist/domBackground.d.ts +3 -0
- package/dist/domBackground.d.ts.map +1 -0
- package/dist/domBackground.js +9 -0
- package/dist/domBackground.js.map +1 -0
- package/dist/domBitmap.d.ts +4 -0
- package/dist/domBitmap.d.ts.map +1 -0
- package/dist/domBitmap.js +81 -0
- package/dist/domBitmap.js.map +1 -0
- package/dist/domCSSFilterBinding.d.ts +19 -0
- package/dist/domCSSFilterBinding.d.ts.map +1 -0
- package/dist/domCSSFilterBinding.js +36 -0
- package/dist/domCSSFilterBinding.js.map +1 -0
- package/dist/domCache.d.ts +14 -0
- package/dist/domCache.d.ts.map +1 -0
- package/dist/domCache.js +64 -0
- package/dist/domCache.js.map +1 -0
- package/dist/domClip.d.ts +3 -0
- package/dist/domClip.d.ts.map +1 -0
- package/dist/domClip.js +38 -0
- package/dist/domClip.js.map +1 -0
- package/dist/domClipContours.d.ts +6 -0
- package/dist/domClipContours.d.ts.map +1 -0
- package/dist/domClipContours.js +48 -0
- package/dist/domClipContours.js.map +1 -0
- package/dist/domClipRectangle.d.ts +6 -0
- package/dist/domClipRectangle.d.ts.map +1 -0
- package/dist/domClipRectangle.js +148 -0
- package/dist/domClipRectangle.js.map +1 -0
- package/dist/domFontSource.d.ts +5 -0
- package/dist/domFontSource.d.ts.map +1 -0
- package/dist/domFontSource.js +18 -0
- package/dist/domFontSource.js.map +1 -0
- package/dist/domHtmlView.d.ts +4 -0
- package/dist/domHtmlView.d.ts.map +1 -0
- package/dist/domHtmlView.js +28 -0
- package/dist/domHtmlView.js.map +1 -0
- package/dist/domImageSource.d.ts +4 -0
- package/dist/domImageSource.d.ts.map +1 -0
- package/dist/domImageSource.js +36 -0
- package/dist/domImageSource.js.map +1 -0
- package/dist/domMaterials.d.ts +15 -0
- package/dist/domMaterials.d.ts.map +1 -0
- package/dist/domMaterials.js +68 -0
- package/dist/domMaterials.js.map +1 -0
- package/dist/domNativeText.d.ts +5 -0
- package/dist/domNativeText.d.ts.map +1 -0
- package/dist/domNativeText.js +88 -0
- package/dist/domNativeText.js.map +1 -0
- package/dist/domNode2D.d.ts +5 -0
- package/dist/domNode2D.d.ts.map +1 -0
- package/dist/domNode2D.js +60 -0
- package/dist/domNode2D.js.map +1 -0
- package/dist/domReconcile.d.ts +9 -0
- package/dist/domReconcile.d.ts.map +1 -0
- package/dist/domReconcile.js +69 -0
- package/dist/domReconcile.js.map +1 -0
- package/dist/domRenderState.d.ts +5 -0
- package/dist/domRenderState.d.ts.map +1 -0
- package/dist/domRenderState.js +43 -0
- package/dist/domRenderState.js.map +1 -0
- package/dist/domRenderView.d.ts +4 -0
- package/dist/domRenderView.d.ts.map +1 -0
- package/dist/domRenderView.js +24 -0
- package/dist/domRenderView.js.map +1 -0
- package/dist/domRichText.d.ts +6 -0
- package/dist/domRichText.d.ts.map +1 -0
- package/dist/domRichText.js +184 -0
- package/dist/domRichText.js.map +1 -0
- package/dist/domScale9Mapper.d.ts +3 -0
- package/dist/domScale9Mapper.d.ts.map +1 -0
- package/dist/domScale9Mapper.js +37 -0
- package/dist/domScale9Mapper.js.map +1 -0
- package/dist/domScale9Shape.d.ts +10 -0
- package/dist/domScale9Shape.d.ts.map +1 -0
- package/dist/domScale9Shape.js +59 -0
- package/dist/domScale9Shape.js.map +1 -0
- package/dist/domShape.d.ts +4 -0
- package/dist/domShape.d.ts.map +1 -0
- package/dist/domShape.js +45 -0
- package/dist/domShape.js.map +1 -0
- package/dist/domStyle.d.ts +9 -0
- package/dist/domStyle.d.ts.map +1 -0
- package/dist/domStyle.js +25 -0
- package/dist/domStyle.js.map +1 -0
- package/dist/domTextHelpers.d.ts +6 -0
- package/dist/domTextHelpers.d.ts.map +1 -0
- package/dist/domTextHelpers.js +8 -0
- package/dist/domTextHelpers.js.map +1 -0
- package/dist/domTextInput.d.ts +4 -0
- package/dist/domTextInput.d.ts.map +1 -0
- package/dist/domTextInput.js +60 -0
- package/dist/domTextInput.js.map +1 -0
- package/dist/domTextLabel.d.ts +4 -0
- package/dist/domTextLabel.d.ts.map +1 -0
- package/dist/domTextLabel.js +75 -0
- package/dist/domTextLabel.js.map +1 -0
- package/dist/domTransform.d.ts +4 -0
- package/dist/domTransform.d.ts.map +1 -0
- package/dist/domTransform.js +16 -0
- package/dist/domTransform.js.map +1 -0
- package/dist/domVideo.d.ts +4 -0
- package/dist/domVideo.d.ts.map +1 -0
- package/dist/domVideo.js +27 -0
- package/dist/domVideo.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/package.json +55 -0
- package/src/domBackground.test.ts +35 -0
- package/src/domBitmap.test.ts +117 -0
- package/src/domCSSFilterBinding.test.ts +62 -0
- package/src/domCache.test.ts +93 -0
- package/src/domClip.test.ts +12 -0
- package/src/domClipContours.test.ts +62 -0
- package/src/domClipRectangle.test.ts +81 -0
- package/src/domFontSource.test.ts +30 -0
- package/src/domHtmlView.test.ts +117 -0
- package/src/domImageSource.test.ts +47 -0
- package/src/domMaterials.test.ts +100 -0
- package/src/domNativeText.test.ts +102 -0
- package/src/domNode2D.test.ts +236 -0
- package/src/domReconcile.test.ts +158 -0
- package/src/domRenderState.test.ts +87 -0
- package/src/domRenderView.test.ts +69 -0
- package/src/domRichText.test.ts +169 -0
- package/src/domScale9Mapper.test.ts +20 -0
- package/src/domScale9Shape.test.ts +76 -0
- package/src/domShape.test.ts +85 -0
- package/src/domStyle.test.ts +130 -0
- package/src/domTextHelpers.test.ts +27 -0
- package/src/domTextInput.test.ts +61 -0
- package/src/domTextLabel.test.ts +92 -0
- package/src/domTransform.test.ts +68 -0
- 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"}
|
package/dist/domShape.js
ADDED
|
@@ -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":"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"}
|
|
@@ -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"}
|
package/dist/domStyle.js
ADDED
|
@@ -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, '&').replace(/</g, '<').replace(/>/g, '>').replace(/ /g, ' ');
|
|
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"}
|