@flighthq/displayobject-dom 0.1.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.
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 +77 -0
  8. package/dist/domBitmap.js.map +1 -0
  9. package/dist/domCSSFilterBinding.d.ts +28 -0
  10. package/dist/domCSSFilterBinding.d.ts.map +1 -0
  11. package/dist/domCSSFilterBinding.js +56 -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/domDisplayObject.d.ts +5 -0
  30. package/dist/domDisplayObject.d.ts.map +1 -0
  31. package/dist/domDisplayObject.js +60 -0
  32. package/dist/domDisplayObject.js.map +1 -0
  33. package/dist/domFontSource.d.ts +5 -0
  34. package/dist/domFontSource.d.ts.map +1 -0
  35. package/dist/domFontSource.js +18 -0
  36. package/dist/domFontSource.js.map +1 -0
  37. package/dist/domMaterials.d.ts +15 -0
  38. package/dist/domMaterials.d.ts.map +1 -0
  39. package/dist/domMaterials.js +62 -0
  40. package/dist/domMaterials.js.map +1 -0
  41. package/dist/domNativeText.d.ts +5 -0
  42. package/dist/domNativeText.d.ts.map +1 -0
  43. package/dist/domNativeText.js +65 -0
  44. package/dist/domNativeText.js.map +1 -0
  45. package/dist/domReconcile.d.ts +9 -0
  46. package/dist/domReconcile.d.ts.map +1 -0
  47. package/dist/domReconcile.js +69 -0
  48. package/dist/domReconcile.js.map +1 -0
  49. package/dist/domRenderState.d.ts +5 -0
  50. package/dist/domRenderState.d.ts.map +1 -0
  51. package/dist/domRenderState.js +43 -0
  52. package/dist/domRenderState.js.map +1 -0
  53. package/dist/domRenderView.d.ts +4 -0
  54. package/dist/domRenderView.d.ts.map +1 -0
  55. package/dist/domRenderView.js +24 -0
  56. package/dist/domRenderView.js.map +1 -0
  57. package/dist/domRichText.d.ts +7 -0
  58. package/dist/domRichText.d.ts.map +1 -0
  59. package/dist/domRichText.js +183 -0
  60. package/dist/domRichText.js.map +1 -0
  61. package/dist/domScale9Mapper.d.ts +3 -0
  62. package/dist/domScale9Mapper.d.ts.map +1 -0
  63. package/dist/domScale9Mapper.js +37 -0
  64. package/dist/domScale9Mapper.js.map +1 -0
  65. package/dist/domScale9Shape.d.ts +10 -0
  66. package/dist/domScale9Shape.d.ts.map +1 -0
  67. package/dist/domScale9Shape.js +59 -0
  68. package/dist/domScale9Shape.js.map +1 -0
  69. package/dist/domShape.d.ts +4 -0
  70. package/dist/domShape.d.ts.map +1 -0
  71. package/dist/domShape.js +45 -0
  72. package/dist/domShape.js.map +1 -0
  73. package/dist/domStyle.d.ts +9 -0
  74. package/dist/domStyle.d.ts.map +1 -0
  75. package/dist/domStyle.js +25 -0
  76. package/dist/domStyle.js.map +1 -0
  77. package/dist/domSvgFilter.d.ts +27 -0
  78. package/dist/domSvgFilter.d.ts.map +1 -0
  79. package/dist/domSvgFilter.js +88 -0
  80. package/dist/domSvgFilter.js.map +1 -0
  81. package/dist/domTextHelpers.d.ts +6 -0
  82. package/dist/domTextHelpers.d.ts.map +1 -0
  83. package/dist/domTextHelpers.js +8 -0
  84. package/dist/domTextHelpers.js.map +1 -0
  85. package/dist/domTextInput.d.ts +4 -0
  86. package/dist/domTextInput.d.ts.map +1 -0
  87. package/dist/domTextInput.js +60 -0
  88. package/dist/domTextInput.js.map +1 -0
  89. package/dist/domTextLabel.d.ts +4 -0
  90. package/dist/domTextLabel.d.ts.map +1 -0
  91. package/dist/domTextLabel.js +74 -0
  92. package/dist/domTextLabel.js.map +1 -0
  93. package/dist/domTransform.d.ts +4 -0
  94. package/dist/domTransform.d.ts.map +1 -0
  95. package/dist/domTransform.js +16 -0
  96. package/dist/domTransform.js.map +1 -0
  97. package/dist/domVideo.d.ts +4 -0
  98. package/dist/domVideo.d.ts.map +1 -0
  99. package/dist/domVideo.js +27 -0
  100. package/dist/domVideo.js.map +1 -0
  101. package/dist/htmlView.d.ts +4 -0
  102. package/dist/htmlView.d.ts.map +1 -0
  103. package/dist/htmlView.js +28 -0
  104. package/dist/htmlView.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 +49 -0
  110. package/src/domBackground.test.ts +35 -0
  111. package/src/domBitmap.test.ts +117 -0
  112. package/src/domCSSFilterBinding.test.ts +104 -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/domDisplayObject.test.ts +236 -0
  118. package/src/domFontSource.test.ts +30 -0
  119. package/src/domMaterials.test.ts +111 -0
  120. package/src/domNativeText.test.ts +71 -0
  121. package/src/domReconcile.test.ts +158 -0
  122. package/src/domRenderState.test.ts +87 -0
  123. package/src/domRenderView.test.ts +69 -0
  124. package/src/domRichText.test.ts +165 -0
  125. package/src/domScale9Mapper.test.ts +20 -0
  126. package/src/domScale9Shape.test.ts +76 -0
  127. package/src/domShape.test.ts +85 -0
  128. package/src/domStyle.test.ts +130 -0
  129. package/src/domSvgFilter.test.ts +116 -0
  130. package/src/domTextHelpers.test.ts +27 -0
  131. package/src/domTextInput.test.ts +61 -0
  132. package/src/domTextLabel.test.ts +92 -0
  133. package/src/domTransform.test.ts +68 -0
  134. package/src/domVideo.test.ts +30 -0
  135. package/src/htmlView.test.ts +117 -0
@@ -0,0 +1,183 @@
1
+ import { createEntity } from '@flighthq/entity';
2
+ import { computeRgbHexString } from '@flighthq/materials';
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
+ wordWrap,
62
+ });
63
+ const fieldW = computeTextBoundsWidth(source.data, result);
64
+ const fieldH = computeTextBoundsHeight(source.data, result);
65
+ const div = data.div;
66
+ div.style.width = `${fieldW}px`;
67
+ div.style.height = `${fieldH}px`;
68
+ div.style.backgroundColor = background ? computeRgbHexString(backgroundColor) : '';
69
+ div.style.border = border ? `1px solid ${computeRgbHexString(borderColor)}` : '';
70
+ if (text.length === 0) {
71
+ div.innerHTML = '';
72
+ applyDomStyle(state, div, renderProxy);
73
+ setDomRendererElement(state, div);
74
+ return;
75
+ }
76
+ const firstVisibleLine = scrollV - 1;
77
+ const scrollYOffset = firstVisibleLine > 0 ? getRichTextScrollYOffset(result.lineHeights, firstVisibleLine) : 0;
78
+ const scrollXOffset = scrollH;
79
+ let html = '';
80
+ if (source.data.selectable && richTextRuntime.selectionBeginIndex !== richTextRuntime.selectionEndIndex) {
81
+ getRichTextSelectionRectangles(_richTextSelectionRectangles, richTextRuntime.selectionBeginIndex, richTextRuntime.selectionEndIndex, result);
82
+ for (const rectangle of _richTextSelectionRectangles) {
83
+ 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>`;
84
+ }
85
+ }
86
+ const bulletLines = new Set();
87
+ for (const group of result.groups) {
88
+ if (group.lineIndex < firstVisibleLine)
89
+ continue;
90
+ const fmt = group.format;
91
+ const slice = escapeDomHtmlString(text.substring(group.startIndex, group.endIndex));
92
+ const x = group.offsetX - scrollXOffset;
93
+ const fontStr = computeTextFormatFontString(fmt);
94
+ // Align the CSS alphabetic baseline with canvas: canvas draws at offsetY + group.ascent
95
+ // (alphabetic baseline). CSS places the baseline at top + fontBoundingBoxAscent, so we
96
+ // shift the div top so the two positions coincide.
97
+ const fontAscent = getDomFontAscent(ctx, fontStr);
98
+ const y = group.offsetY + group.ascent - fontAscent - scrollYOffset;
99
+ if (fmt.bullet && !bulletLines.has(group.lineIndex)) {
100
+ bulletLines.add(group.lineIndex);
101
+ const bulletSize = fmt.size ?? 12;
102
+ const bulletX = x - bulletSize * 0.7 - DOM_BULLET_GAP;
103
+ 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;`;
104
+ html += `<div style="${bulletStyle}">•</div>`;
105
+ }
106
+ let style = `position:absolute;left:${x}px;top:${y}px;font:${fontStr};line-height:1;`;
107
+ style += `color:${computeRgbHexString(fmt.color ?? source.data.textColor)};white-space:nowrap;`;
108
+ if (fmt.underline || fmt.strikethrough) {
109
+ const decorations = [];
110
+ if (fmt.underline)
111
+ decorations.push('underline');
112
+ if (fmt.strikethrough)
113
+ decorations.push('line-through');
114
+ style += `text-decoration:${decorations.join(' ')};`;
115
+ }
116
+ switch (fmt.align) {
117
+ case 'center':
118
+ style += 'text-align:center;';
119
+ break;
120
+ case 'right':
121
+ style += 'text-align:right;';
122
+ break;
123
+ case 'justify':
124
+ style += 'text-align:justify;';
125
+ break;
126
+ }
127
+ if (fmt.leftMargin != null)
128
+ style += `padding-left:${fmt.leftMargin}px;`;
129
+ if (fmt.rightMargin != null)
130
+ style += `padding-right:${fmt.rightMargin}px;`;
131
+ if (fmt.indent != null)
132
+ style += `text-indent:${fmt.indent}px;`;
133
+ html += `<div style="${style}">${slice}</div>`;
134
+ }
135
+ div.innerHTML = html;
136
+ applyDomStyle(state, div, renderProxy);
137
+ setDomRendererElement(state, div);
138
+ }
139
+ const DOM_BULLET_GAP = 4;
140
+ function getDomFontAscent(ctx, font) {
141
+ const cached = getDomFontAscentCached(font);
142
+ if (cached !== undefined)
143
+ return cached;
144
+ // Measure the CSS alphabetic baseline directly: a zero-height inline-block with
145
+ // vertical-align:baseline sits with its top edge exactly on the line's baseline.
146
+ // getBoundingClientRect() gives the exact pixel distance CSS uses, with no
147
+ // inference from canvas metrics. Falls back to canvas measurement in non-browser env.
148
+ const ascent = typeof document !== 'undefined' && document.body ? probeCssFontAscent(font) : canvasFontAscentFallback(ctx, font);
149
+ setDomFontAscentCached(font, ascent);
150
+ return ascent;
151
+ }
152
+ function probeCssFontAscent(font) {
153
+ const container = document.createElement('div');
154
+ container.style.cssText = `font:${font};line-height:1;position:fixed;top:0;left:0;visibility:hidden;pointer-events:none;white-space:nowrap`;
155
+ const probe = document.createElement('span');
156
+ probe.style.cssText = 'display:inline-block;height:0;vertical-align:baseline';
157
+ container.appendChild(document.createTextNode('H'));
158
+ container.appendChild(probe);
159
+ document.body.appendChild(container);
160
+ const containerTop = container.getBoundingClientRect().top;
161
+ const probeTop = probe.getBoundingClientRect().top;
162
+ document.body.removeChild(container);
163
+ return probeTop - containerTop;
164
+ }
165
+ function canvasFontAscentFallback(ctx, font) {
166
+ ctx.font = font;
167
+ const metrics = ctx.measureText('H');
168
+ const sizeMatch = /(\d+(?:\.\d+)?)px/.exec(font);
169
+ const size = sizeMatch ? parseFloat(sizeMatch[1]) : 12;
170
+ return metrics.fontBoundingBoxAscent ?? size * 0.85;
171
+ }
172
+ const DOM_SELECTION_ALPHA = 0.35;
173
+ const DOM_SELECTION_COLOR = '#0078d7';
174
+ const _richTextSelectionRectangles = [];
175
+ let _domTextInputOverlay = null;
176
+ export function registerDomTextInputOverlay(overlay) {
177
+ _domTextInputOverlay = overlay;
178
+ }
179
+ export const defaultDomRichTextRenderer = {
180
+ createData: createDomRichTextData,
181
+ submit: drawDomRichText,
182
+ };
183
+ //# sourceMappingURL=domRichText.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domRichText.js","sourceRoot":"","sources":["../src/domRichText.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,4BAA4B,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAClF,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,8BAA8B,EAC9B,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAc9B,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACrF,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAMvD,SAAS,qBAAqB,CAAC,MAAmB,EAAE,OAAmB;IACrE,OAAO,YAAY,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;AACrC,CAAC;AAED,IAAI,WAAW,GAAoC,IAAI,CAAC;AAExD,SAAS,aAAa;IACpB,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACzB,WAAW,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAqB,EAAE,WAA0B;IAC/E,oBAAoB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IACzC,qGAAqG;IACrG,yGAAyG;IACzG,yGAAyG;IACzG,IAAI,oBAAoB,KAAK,IAAI,IAAI,kBAAkB,CAAC,WAAW,CAAC,MAAkB,CAAC,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QACvG,oBAAoB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC;AAID,MAAM,UAAU,mBAAmB,CAAC,KAAqB,EAAE,WAA0B;IACnF,eAAe,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAqB,EAAE,WAA0B;IAC7E,MAAM,IAAI,GAAG,WAAW,CAAC,YAAsC,CAAC;IAChE,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO;IAE1B,MAAM,MAAM,GAAG,WAAW,CAAC,MAAkB,CAAC;IAC9C,MAAM,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC;IAEhH,IAAI,IAAI,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;QACtB,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACzC,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACrC,CAAC;IAED,MAAM,eAAe,GAAG,kBAAkB,CAAC,MAAM,CAAoB,CAAC;IACtE,MAAM,OAAO,GAAG,kBAAkB,CAAC,eAAe,CAAC,CAAC;IACpD,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,4BAA4B,CAAC,MAAM,CAAC,CAAC,CAAC;IACnF,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IAEzB,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;IAC5B,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO;IAEzB,MAAM,OAAO,GAAG,CAAC,CAAS,EAAE,GAAe,EAAU,EAAE;QACrD,GAAG,CAAC,IAAI,GAAG,2BAA2B,CAAC,GAAG,CAAC,CAAC;QAC5C,OAAO,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAClC,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,mBAAmB,CAAC,eAAmC,CAAC,CAAC;IACxE,iBAAiB,CAAC,MAAM,EAAE;QACxB,IAAI;QACJ,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK;QAC3C,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;QAC1B,OAAO;QACP,SAAS;QACT,QAAQ;KACT,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,sBAAsB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,uBAAuB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;IACrB,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,MAAM,IAAI,CAAC;IAChC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC;IACjC,GAAG,CAAC,KAAK,CAAC,eAAe,GAAG,UAAU,CAAC,CAAC,CAAC,mBAAmB,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACnF,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,aAAa,mBAAmB,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAEjF,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,GAAG,CAAC,SAAS,GAAG,EAAE,CAAC;QACnB,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;QACvC,qBAAqB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IAED,MAAM,gBAAgB,GAAG,OAAO,GAAG,CAAC,CAAC;IACrC,MAAM,aAAa,GAAG,gBAAgB,GAAG,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC,MAAM,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChH,MAAM,aAAa,GAAG,OAAO,CAAC;IAE9B,IAAI,IAAI,GAAG,EAAE,CAAC;IAEd,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,IAAI,eAAe,CAAC,mBAAmB,KAAK,eAAe,CAAC,iBAAiB,EAAE,CAAC;QACxG,8BAA8B,CAC5B,4BAA4B,EAC5B,eAAe,CAAC,mBAAmB,EACnC,eAAe,CAAC,iBAAiB,EACjC,MAAM,CACP,CAAC;QACF,KAAK,MAAM,SAAS,IAAI,4BAA4B,EAAE,CAAC;YACrD,IAAI,IAAI,sCAAsC,SAAS,CAAC,CAAC,GAAG,aAAa,UAAU,SAAS,CAAC,CAAC,GAAG,aAAa,YAAY,SAAS,CAAC,KAAK,aAAa,SAAS,CAAC,MAAM,iBAAiB,mBAAmB,YAAY,mBAAmB,+BAA+B,CAAC;QAC3Q,CAAC;IACH,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClC,IAAI,KAAK,CAAC,SAAS,GAAG,gBAAgB;YAAE,SAAS;QAEjD,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC;QACzB,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;QACpF,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,GAAG,aAAa,CAAC;QACxC,MAAM,OAAO,GAAG,2BAA2B,CAAC,GAAG,CAAC,CAAC;QACjD,wFAAwF;QACxF,uFAAuF;QACvF,mDAAmD;QACnD,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,UAAU,GAAG,aAAa,CAAC;QAEpE,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;YACpD,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YACjC,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;YAClC,MAAM,OAAO,GAAG,CAAC,GAAG,UAAU,GAAG,GAAG,GAAG,cAAc,CAAC;YACtD,MAAM,WAAW,GAAG,0BAA0B,OAAO,UAAU,CAAC,WAAW,OAAO,wBAAwB,mBAAmB,CAAC,GAAG,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC;YACxL,IAAI,IAAI,eAAe,WAAW,iBAAiB,CAAC;QACtD,CAAC;QAED,IAAI,KAAK,GAAG,0BAA0B,CAAC,UAAU,CAAC,WAAW,OAAO,iBAAiB,CAAC;QACtF,KAAK,IAAI,SAAS,mBAAmB,CAAC,GAAG,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC;QAChG,IAAI,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,aAAa,EAAE,CAAC;YACvC,MAAM,WAAW,GAAG,EAAE,CAAC;YACvB,IAAI,GAAG,CAAC,SAAS;gBAAE,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACjD,IAAI,GAAG,CAAC,aAAa;gBAAE,WAAW,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YACxD,KAAK,IAAI,mBAAmB,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;QACvD,CAAC;QAED,QAAQ,GAAG,CAAC,KAAK,EAAE,CAAC;YAClB,KAAK,QAAQ;gBACX,KAAK,IAAI,oBAAoB,CAAC;gBAC9B,MAAM;YACR,KAAK,OAAO;gBACV,KAAK,IAAI,mBAAmB,CAAC;gBAC7B,MAAM;YACR,KAAK,SAAS;gBACZ,KAAK,IAAI,qBAAqB,CAAC;gBAC/B,MAAM;QACV,CAAC;QAED,IAAI,GAAG,CAAC,UAAU,IAAI,IAAI;YAAE,KAAK,IAAI,gBAAgB,GAAG,CAAC,UAAU,KAAK,CAAC;QACzE,IAAI,GAAG,CAAC,WAAW,IAAI,IAAI;YAAE,KAAK,IAAI,iBAAiB,GAAG,CAAC,WAAW,KAAK,CAAC;QAC5E,IAAI,GAAG,CAAC,MAAM,IAAI,IAAI;YAAE,KAAK,IAAI,eAAe,GAAG,CAAC,MAAM,KAAK,CAAC;QAEhE,IAAI,IAAI,eAAe,KAAK,KAAK,KAAK,QAAQ,CAAC;IACjD,CAAC;IAED,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC;IAErB,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;IACvC,qBAAqB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB,SAAS,gBAAgB,CAAC,GAA6B,EAAE,IAAY;IACnE,MAAM,MAAM,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACxC,gFAAgF;IAChF,iFAAiF;IACjF,2EAA2E;IAC3E,sFAAsF;IACtF,MAAM,MAAM,GACV,OAAO,QAAQ,KAAK,WAAW,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACpH,sBAAsB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACrC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAY;IACtC,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAChD,SAAS,CAAC,KAAK,CAAC,OAAO,GAAG,QAAQ,IAAI,qGAAqG,CAAC;IAC5I,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7C,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,uDAAuD,CAAC;IAC9E,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;IACpD,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC7B,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IACrC,MAAM,YAAY,GAAG,SAAS,CAAC,qBAAqB,EAAE,CAAC,GAAG,CAAC;IAC3D,MAAM,QAAQ,GAAG,KAAK,CAAC,qBAAqB,EAAE,CAAC,GAAG,CAAC;IACnD,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IACrC,OAAO,QAAQ,GAAG,YAAY,CAAC;AACjC,CAAC;AAED,SAAS,wBAAwB,CAAC,GAA6B,EAAE,IAAY;IAC3E,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;IAChB,MAAM,OAAO,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAqD,CAAC;IACzF,MAAM,SAAS,GAAG,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvD,OAAO,OAAO,CAAC,qBAAqB,IAAI,IAAI,GAAG,IAAI,CAAC;AACtD,CAAC;AACD,MAAM,mBAAmB,GAAG,IAAI,CAAC;AACjC,MAAM,mBAAmB,GAAG,SAAS,CAAC;AACtC,MAAM,4BAA4B,GAAiF,EAAE,CAAC;AACtH,IAAI,oBAAoB,GAA+B,IAAI,CAAC;AAE5D,MAAM,UAAU,2BAA2B,CAAC,OAA4B;IACtE,oBAAoB,GAAG,OAAO,CAAC;AACjC,CAAC;AAED,MAAM,CAAC,MAAM,0BAA0B,GAA0B;IAC/D,UAAU,EAAE,qBAAqB;IACjC,MAAM,EAAE,eAAe;CACxB,CAAC"}
@@ -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 { DisplayObjectRenderer, 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: DisplayObjectRenderer;
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,qBAAqB,EACrB,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,qBAG3C,CAAC"}
@@ -0,0 +1,59 @@
1
+ import { mapCanvasScale9ShapeCommands, renderCanvasShapeCommands } from '@flighthq/displayobject-canvas';
2
+ import { createEntity } from '@flighthq/entity';
3
+ import { getNodeLocalBoundsRectangle } from '@flighthq/node';
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 { DisplayObjectRenderer, DomRenderState, RenderProxy2D } from '@flighthq/types';
2
+ export declare function drawDomShape(state: DomRenderState, renderProxy: RenderProxy2D): void;
3
+ export declare const defaultDomShapeRenderer: DisplayObjectRenderer;
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,qBAAqB,EACrB,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,qBAGrC,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { renderCanvasShapeCommands } from '@flighthq/displayobject-canvas';
2
+ import { createEntity } from '@flighthq/entity';
3
+ import { getNodeLocalBoundsRectangle } from '@flighthq/node';
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"}
@@ -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,27 @@
1
+ import type { ColorMatrixFilter } from '@flighthq/types';
2
+ /**
3
+ * Builds a CSS `filter: url(#id)` string for a ColorMatrixFilter by injecting an inline SVG
4
+ * `<feColorMatrix>` element into a shared hidden SVG container. Callers pass the returned
5
+ * CSS string directly to `setDomCssFilter`.
6
+ *
7
+ * The Flash/OpenFL 4×5 color matrix uses offsets in the 0–255 range; SVG `feColorMatrix`
8
+ * expects values in the 0–1 range. This function divides offset columns (indices 4, 9, 14, 19)
9
+ * by 255 before writing the `values` attribute.
10
+ *
11
+ * The returned CSS string references a `<filter>` element owned by this module. Call
12
+ * `releaseDomSvgColorMatrixFilter` with the id portion when the filter is no longer needed to
13
+ * remove the SVG element from the DOM; not doing so leaks `<filter>` nodes.
14
+ *
15
+ * Returns null if called outside a document context (SSR / headless without DOM).
16
+ */
17
+ export declare function getDomSvgColorMatrixFilter(filter: Readonly<ColorMatrixFilter>): string | null;
18
+ /**
19
+ * Removes the SVG `<filter>` element registered under the given id from the shared container.
20
+ * The `id` is the fragment portion of the string returned by `getDomSvgColorMatrixFilter`
21
+ * (strip the leading `url(#` and trailing `)`).
22
+ *
23
+ * Call this when the filter is no longer needed to avoid leaking `<filter>` DOM nodes.
24
+ * No-op if the id is not found or outside a document context.
25
+ */
26
+ export declare function releaseDomSvgColorMatrixFilter(id: string): void;
27
+ //# sourceMappingURL=domSvgFilter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domSvgFilter.d.ts","sourceRoot":"","sources":["../src/domSvgFilter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,MAAM,GAAG,IAAI,CAa7F;AAED;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAK/D"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Builds a CSS `filter: url(#id)` string for a ColorMatrixFilter by injecting an inline SVG
3
+ * `<feColorMatrix>` element into a shared hidden SVG container. Callers pass the returned
4
+ * CSS string directly to `setDomCssFilter`.
5
+ *
6
+ * The Flash/OpenFL 4×5 color matrix uses offsets in the 0–255 range; SVG `feColorMatrix`
7
+ * expects values in the 0–1 range. This function divides offset columns (indices 4, 9, 14, 19)
8
+ * by 255 before writing the `values` attribute.
9
+ *
10
+ * The returned CSS string references a `<filter>` element owned by this module. Call
11
+ * `releaseDomSvgColorMatrixFilter` with the id portion when the filter is no longer needed to
12
+ * remove the SVG element from the DOM; not doing so leaks `<filter>` nodes.
13
+ *
14
+ * Returns null if called outside a document context (SSR / headless without DOM).
15
+ */
16
+ export function getDomSvgColorMatrixFilter(filter) {
17
+ const container = ensureSvgContainer();
18
+ if (container === null)
19
+ return null;
20
+ const id = `flighthq-cm-${_nextFilterId++}`;
21
+ const svgFilter = document.createElementNS('http://www.w3.org/2000/svg', 'filter');
22
+ svgFilter.id = id;
23
+ svgFilter.setAttribute('color-interpolation-filters', 'sRGB');
24
+ const feColorMatrix = document.createElementNS('http://www.w3.org/2000/svg', 'feColorMatrix');
25
+ feColorMatrix.setAttribute('type', 'matrix');
26
+ feColorMatrix.setAttribute('values', buildFeColorMatrixValues(filter.matrix));
27
+ svgFilter.appendChild(feColorMatrix);
28
+ container.appendChild(svgFilter);
29
+ return `url(#${id})`;
30
+ }
31
+ /**
32
+ * Removes the SVG `<filter>` element registered under the given id from the shared container.
33
+ * The `id` is the fragment portion of the string returned by `getDomSvgColorMatrixFilter`
34
+ * (strip the leading `url(#` and trailing `)`).
35
+ *
36
+ * Call this when the filter is no longer needed to avoid leaking `<filter>` DOM nodes.
37
+ * No-op if the id is not found or outside a document context.
38
+ */
39
+ export function releaseDomSvgColorMatrixFilter(id) {
40
+ const container = _svgContainer;
41
+ if (container === null)
42
+ return;
43
+ const el = container.querySelector(`#${CSS.escape(id)}`);
44
+ if (el !== null)
45
+ container.removeChild(el);
46
+ }
47
+ // Builds the SVG feColorMatrix `values` attribute string from a Flash/OpenFL 4×5 color matrix.
48
+ // SVG expects values in the 0–1 range; the offset column (every 5th value starting at index 4)
49
+ // is divided by 255 to convert from Flash's 0–255 convention.
50
+ function buildFeColorMatrixValues(matrix) {
51
+ const out = new Array(20);
52
+ for (let row = 0; row < 4; row++) {
53
+ const base = row * 5;
54
+ out[base + 0] = matrix[base + 0];
55
+ out[base + 1] = matrix[base + 1];
56
+ out[base + 2] = matrix[base + 2];
57
+ out[base + 3] = matrix[base + 3];
58
+ // Offset column: divide by 255 (Flash 0–255 → SVG 0–1).
59
+ out[base + 4] = matrix[base + 4] / 255;
60
+ }
61
+ return out.join(' ');
62
+ }
63
+ // Returns (or lazily creates) the shared hidden SVG container appended to document.body.
64
+ // Returns null when no document is available (SSR context).
65
+ function ensureSvgContainer() {
66
+ if (_svgContainer !== null)
67
+ return _svgContainer;
68
+ if (typeof document === 'undefined')
69
+ return null;
70
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
71
+ svg.setAttribute('aria-hidden', 'true');
72
+ svg.style.position = 'absolute';
73
+ svg.style.width = '0';
74
+ svg.style.height = '0';
75
+ svg.style.overflow = 'hidden';
76
+ svg.style.pointerEvents = 'none';
77
+ // The container lives outside the render root so clip-path / overflow:hidden cannot hide it.
78
+ document.body.appendChild(svg);
79
+ _svgContainer = svg;
80
+ return svg;
81
+ }
82
+ // SVG filter elements are appended to a shared hidden <svg> container at the document root so
83
+ // every element with `filter: url(#id)` can reference them regardless of placement in the DOM.
84
+ // Each filter gets a unique id derived from a monotonically incrementing counter so concurrent
85
+ // filters do not collide.
86
+ let _svgContainer = null;
87
+ let _nextFilterId = 0;
88
+ //# sourceMappingURL=domSvgFilter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domSvgFilter.js","sourceRoot":"","sources":["../src/domSvgFilter.ts"],"names":[],"mappings":"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"}
@@ -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"}