uicore-ts 1.1.55 → 1.1.57

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.
@@ -0,0 +1,65 @@
1
+ export declare class UITextMeasurement {
2
+ private static canvas;
3
+ private static context;
4
+ private static fontCache;
5
+ private static lineHeightCache;
6
+ private static measurementElement;
7
+ /**
8
+ * Get or create the canvas context for text measurement
9
+ */
10
+ private static getContext;
11
+ /**
12
+ * Detect if content is plain text or complex HTML
13
+ */
14
+ private static isPlainText;
15
+ /**
16
+ * Check if content has only simple inline formatting
17
+ */
18
+ private static hasSimpleFormatting;
19
+ /**
20
+ * Get or create measurement element for complex HTML
21
+ */
22
+ private static getMeasurementElement;
23
+ /**
24
+ * Fast measurement using DOM (but optimized to minimize reflows)
25
+ */
26
+ private static measureWithDOM;
27
+ /**
28
+ * Extract font properties from computed style and create font string
29
+ */
30
+ private static getFontString;
31
+ /**
32
+ * Get line height in pixels
33
+ */
34
+ private static getLineHeight;
35
+ /**
36
+ * Measure text width using Canvas API
37
+ */
38
+ static measureTextWidth(text: string, font: string): number;
39
+ /**
40
+ * Split text into lines based on width constraint
41
+ */
42
+ private static wrapText;
43
+ private static wrapNormal;
44
+ private static wrapPreservingWhitespace;
45
+ /**
46
+ * Calculate intrinsic content size for text - SMART METHOD
47
+ * Automatically chooses the most efficient measurement technique
48
+ */
49
+ static calculateTextSize(element: HTMLElement, content: string, constrainingWidth?: number, constrainingHeight?: number): {
50
+ width: number;
51
+ height: number;
52
+ };
53
+ /**
54
+ * Calculate size for plain text using canvas (no HTML)
55
+ */
56
+ private static calculatePlainTextSize;
57
+ /**
58
+ * Clear all caches (call when fonts change or for cleanup)
59
+ */
60
+ static clearCaches(): void;
61
+ /**
62
+ * Clean up measurement element (call on app cleanup)
63
+ */
64
+ static cleanup(): void;
65
+ }
@@ -0,0 +1,268 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var UITextMeasurement_exports = {};
20
+ __export(UITextMeasurement_exports, {
21
+ UITextMeasurement: () => UITextMeasurement
22
+ });
23
+ module.exports = __toCommonJS(UITextMeasurement_exports);
24
+ class UITextMeasurement {
25
+ static getContext() {
26
+ if (!this.context) {
27
+ this.canvas = document.createElement("canvas");
28
+ this.context = this.canvas.getContext("2d");
29
+ }
30
+ return this.context;
31
+ }
32
+ static isPlainText(content) {
33
+ const hasComplexHTML = /<(?!\/?(b|i|em|strong|span|br)\b)[^>]+>/i.test(content);
34
+ return !hasComplexHTML;
35
+ }
36
+ static hasSimpleFormatting(content) {
37
+ const simpleTagPattern = /^[^<]*(?:<\/?(?:b|i|em|strong|span)(?:\s+style="[^"]*")?>[^<]*)*$/i;
38
+ return simpleTagPattern.test(content);
39
+ }
40
+ static getMeasurementElement() {
41
+ if (!this.measurementElement) {
42
+ this.measurementElement = document.createElement("div");
43
+ this.measurementElement.style.cssText = `
44
+ position: absolute;
45
+ visibility: hidden;
46
+ pointer-events: none;
47
+ top: -9999px;
48
+ left: -9999px;
49
+ width: auto;
50
+ height: auto;
51
+ `;
52
+ }
53
+ return this.measurementElement;
54
+ }
55
+ static measureWithDOM(element, content, constrainingWidth, constrainingHeight) {
56
+ const measureEl = this.getMeasurementElement();
57
+ const style = window.getComputedStyle(element);
58
+ measureEl.style.font = this.getFontString(element);
59
+ measureEl.style.lineHeight = style.lineHeight;
60
+ measureEl.style.whiteSpace = style.whiteSpace;
61
+ measureEl.style.wordBreak = style.wordBreak;
62
+ measureEl.style.wordWrap = style.wordWrap;
63
+ measureEl.style.padding = style.padding;
64
+ measureEl.style.border = style.border;
65
+ measureEl.style.boxSizing = style.boxSizing;
66
+ if (constrainingWidth) {
67
+ measureEl.style.width = constrainingWidth + "px";
68
+ measureEl.style.maxWidth = constrainingWidth + "px";
69
+ } else {
70
+ measureEl.style.width = "auto";
71
+ measureEl.style.maxWidth = "none";
72
+ }
73
+ if (constrainingHeight) {
74
+ measureEl.style.height = constrainingHeight + "px";
75
+ measureEl.style.maxHeight = constrainingHeight + "px";
76
+ } else {
77
+ measureEl.style.height = "auto";
78
+ measureEl.style.maxHeight = "none";
79
+ }
80
+ measureEl.innerHTML = content;
81
+ if (!measureEl.parentElement) {
82
+ document.body.appendChild(measureEl);
83
+ }
84
+ const rect = measureEl.getBoundingClientRect();
85
+ const result = {
86
+ width: rect.width || measureEl.scrollWidth,
87
+ height: rect.height || measureEl.scrollHeight
88
+ };
89
+ return result;
90
+ }
91
+ static getFontString(element) {
92
+ const cacheKey = element.className + element.id;
93
+ if (this.fontCache.has(cacheKey)) {
94
+ return this.fontCache.get(cacheKey);
95
+ }
96
+ const style = window.getComputedStyle(element);
97
+ const font = [
98
+ style.fontStyle,
99
+ style.fontVariant,
100
+ style.fontWeight,
101
+ style.fontSize,
102
+ style.fontFamily
103
+ ].join(" ");
104
+ this.fontCache.set(cacheKey, font);
105
+ return font;
106
+ }
107
+ static getLineHeight(element, fontSize) {
108
+ const style = window.getComputedStyle(element);
109
+ const lineHeight = style.lineHeight;
110
+ if (lineHeight === "normal") {
111
+ return fontSize * 1.2;
112
+ }
113
+ if (lineHeight.endsWith("px")) {
114
+ return parseFloat(lineHeight);
115
+ }
116
+ const numericLineHeight = parseFloat(lineHeight);
117
+ if (!isNaN(numericLineHeight)) {
118
+ return fontSize * numericLineHeight;
119
+ }
120
+ return fontSize * 1.2;
121
+ }
122
+ static measureTextWidth(text, font) {
123
+ const ctx = this.getContext();
124
+ ctx.font = font;
125
+ return ctx.measureText(text).width;
126
+ }
127
+ static wrapText(text, maxWidth, font, whiteSpace) {
128
+ if (whiteSpace === "nowrap" || whiteSpace === "pre") {
129
+ return [text];
130
+ }
131
+ const ctx = this.getContext();
132
+ ctx.font = font;
133
+ const lines = [];
134
+ const paragraphs = text.split("\n");
135
+ for (const paragraph of paragraphs) {
136
+ if (whiteSpace === "pre-wrap") {
137
+ lines.push(...this.wrapPreservingWhitespace(paragraph, maxWidth, ctx));
138
+ } else {
139
+ lines.push(...this.wrapNormal(paragraph, maxWidth, ctx));
140
+ }
141
+ }
142
+ return lines;
143
+ }
144
+ static wrapNormal(text, maxWidth, ctx) {
145
+ const words = text.split(/\s+/).filter((w) => w.length > 0);
146
+ const lines = [];
147
+ let currentLine = "";
148
+ for (const word of words) {
149
+ const testLine = currentLine ? `${currentLine} ${word}` : word;
150
+ const metrics = ctx.measureText(testLine);
151
+ if (metrics.width > maxWidth && currentLine) {
152
+ lines.push(currentLine);
153
+ currentLine = word;
154
+ } else {
155
+ currentLine = testLine;
156
+ }
157
+ }
158
+ if (currentLine) {
159
+ lines.push(currentLine);
160
+ }
161
+ return lines.length > 0 ? lines : [""];
162
+ }
163
+ static wrapPreservingWhitespace(text, maxWidth, ctx) {
164
+ const lines = [];
165
+ let currentLine = "";
166
+ for (let i = 0; i < text.length; i++) {
167
+ const char = text[i];
168
+ const testLine = currentLine + char;
169
+ const metrics = ctx.measureText(testLine);
170
+ if (metrics.width > maxWidth && currentLine) {
171
+ lines.push(currentLine);
172
+ currentLine = char;
173
+ } else {
174
+ currentLine = testLine;
175
+ }
176
+ }
177
+ if (currentLine) {
178
+ lines.push(currentLine);
179
+ }
180
+ return lines.length > 0 ? lines : [""];
181
+ }
182
+ static calculateTextSize(element, content, constrainingWidth, constrainingHeight) {
183
+ if (!content || content.length === 0) {
184
+ const style = window.getComputedStyle(element);
185
+ const paddingTop = parseFloat(style.paddingTop) || 0;
186
+ const paddingBottom = parseFloat(style.paddingBottom) || 0;
187
+ const paddingLeft = parseFloat(style.paddingLeft) || 0;
188
+ const paddingRight = parseFloat(style.paddingRight) || 0;
189
+ return {
190
+ width: paddingLeft + paddingRight,
191
+ height: paddingTop + paddingBottom
192
+ };
193
+ }
194
+ const isPlain = this.isPlainText(content);
195
+ const hasSimple = this.hasSimpleFormatting(content);
196
+ if (isPlain) {
197
+ return this.calculatePlainTextSize(
198
+ element,
199
+ content,
200
+ constrainingWidth,
201
+ constrainingHeight
202
+ );
203
+ }
204
+ if (hasSimple) {
205
+ const plainText = content.replace(/<[^>]+>/g, "");
206
+ return this.calculatePlainTextSize(
207
+ element,
208
+ plainText,
209
+ constrainingWidth,
210
+ constrainingHeight
211
+ );
212
+ }
213
+ return this.measureWithDOM(
214
+ element,
215
+ content,
216
+ constrainingWidth,
217
+ constrainingHeight
218
+ );
219
+ }
220
+ static calculatePlainTextSize(element, text, constrainingWidth, constrainingHeight) {
221
+ const font = this.getFontString(element);
222
+ const style = window.getComputedStyle(element);
223
+ const whiteSpace = style.whiteSpace;
224
+ const fontSize = parseFloat(style.fontSize);
225
+ const lineHeight = this.getLineHeight(element, fontSize);
226
+ const paddingLeft = parseFloat(style.paddingLeft) || 0;
227
+ const paddingRight = parseFloat(style.paddingRight) || 0;
228
+ const paddingTop = parseFloat(style.paddingTop) || 0;
229
+ const paddingBottom = parseFloat(style.paddingBottom) || 0;
230
+ const availableWidth = constrainingWidth ? constrainingWidth - paddingLeft - paddingRight : Infinity;
231
+ let width;
232
+ let height;
233
+ if (whiteSpace === "nowrap" || whiteSpace === "pre" || !constrainingWidth) {
234
+ width = this.measureTextWidth(text, font) + paddingLeft + paddingRight;
235
+ height = lineHeight + paddingTop + paddingBottom;
236
+ } else {
237
+ const lines = this.wrapText(text, availableWidth, font, whiteSpace);
238
+ width = Math.max(
239
+ ...lines.map((line) => this.measureTextWidth(line, font))
240
+ ) + paddingLeft + paddingRight;
241
+ height = lines.length * lineHeight + paddingTop + paddingBottom;
242
+ }
243
+ return { width, height };
244
+ }
245
+ static clearCaches() {
246
+ this.fontCache.clear();
247
+ this.lineHeightCache.clear();
248
+ }
249
+ static cleanup() {
250
+ if (this.measurementElement && this.measurementElement.parentElement) {
251
+ document.body.removeChild(this.measurementElement);
252
+ }
253
+ this.measurementElement = null;
254
+ this.canvas = null;
255
+ this.context = null;
256
+ this.clearCaches();
257
+ }
258
+ }
259
+ UITextMeasurement.canvas = null;
260
+ UITextMeasurement.context = null;
261
+ UITextMeasurement.fontCache = /* @__PURE__ */ new Map();
262
+ UITextMeasurement.lineHeightCache = /* @__PURE__ */ new Map();
263
+ UITextMeasurement.measurementElement = null;
264
+ // Annotate the CommonJS export names for ESM import in node:
265
+ 0 && (module.exports = {
266
+ UITextMeasurement
267
+ });
268
+ //# sourceMappingURL=UITextMeasurement.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../scripts/UITextMeasurement.ts"],
4
+ "sourcesContent": ["// UITextMeasurement.ts - Efficient text measurement without DOM reflows\n\nexport class UITextMeasurement {\n \n private static canvas: HTMLCanvasElement | null = null;\n private static context: CanvasRenderingContext2D | null = null;\n \n // Cache for computed font strings to avoid repeated style parsing\n private static fontCache = new Map<string, string>();\n \n // Cache for line height calculations\n private static lineHeightCache = new Map<string, number>();\n \n // Temporary element for complex HTML measurements (reused to avoid allocations)\n private static measurementElement: HTMLDivElement | null = null;\n \n /**\n * Get or create the canvas context for text measurement\n */\n private static getContext(): CanvasRenderingContext2D {\n if (!this.context) {\n this.canvas = document.createElement('canvas');\n this.context = this.canvas.getContext('2d')!;\n }\n return this.context;\n }\n \n /**\n * Detect if content is plain text or complex HTML\n */\n private static isPlainText(content: string): boolean {\n // Check for HTML tags (excluding simple formatting like <b>, <i>, <span>)\n const hasComplexHTML = /<(?!\\/?(b|i|em|strong|span|br)\\b)[^>]+>/i.test(content);\n return !hasComplexHTML;\n }\n \n /**\n * Check if content has only simple inline formatting\n */\n private static hasSimpleFormatting(content: string): boolean {\n // Only <b>, <i>, <strong>, <em>, <span> with inline styles\n const simpleTagPattern = /^[^<]*(?:<\\/?(?:b|i|em|strong|span)(?:\\s+style=\"[^\"]*\")?>[^<]*)*$/i;\n return simpleTagPattern.test(content);\n }\n \n /**\n * Get or create measurement element for complex HTML\n */\n private static getMeasurementElement(): HTMLDivElement {\n if (!this.measurementElement) {\n this.measurementElement = document.createElement('div');\n this.measurementElement.style.cssText = `\n position: absolute;\n visibility: hidden;\n pointer-events: none;\n top: -9999px;\n left: -9999px;\n width: auto;\n height: auto;\n `;\n }\n return this.measurementElement;\n }\n \n /**\n * Fast measurement using DOM (but optimized to minimize reflows)\n */\n private static measureWithDOM(\n element: HTMLElement,\n content: string,\n constrainingWidth?: number,\n constrainingHeight?: number\n ): { width: number; height: number } {\n const measureEl = this.getMeasurementElement();\n const style = window.getComputedStyle(element);\n \n // Copy relevant styles\n measureEl.style.font = this.getFontString(element);\n measureEl.style.lineHeight = style.lineHeight;\n measureEl.style.whiteSpace = style.whiteSpace;\n measureEl.style.wordBreak = style.wordBreak;\n measureEl.style.wordWrap = style.wordWrap;\n measureEl.style.padding = style.padding;\n measureEl.style.border = style.border;\n measureEl.style.boxSizing = style.boxSizing;\n \n // Set constraints\n if (constrainingWidth) {\n measureEl.style.width = constrainingWidth + 'px';\n measureEl.style.maxWidth = constrainingWidth + 'px';\n } else {\n measureEl.style.width = 'auto';\n measureEl.style.maxWidth = 'none';\n }\n \n if (constrainingHeight) {\n measureEl.style.height = constrainingHeight + 'px';\n measureEl.style.maxHeight = constrainingHeight + 'px';\n } else {\n measureEl.style.height = 'auto';\n measureEl.style.maxHeight = 'none';\n }\n \n // Set content\n measureEl.innerHTML = content;\n \n // Add to DOM only if not already there\n if (!measureEl.parentElement) {\n document.body.appendChild(measureEl);\n }\n \n // Single reflow for both measurements\n const rect = measureEl.getBoundingClientRect();\n const result = {\n width: rect.width || measureEl.scrollWidth,\n height: rect.height || measureEl.scrollHeight\n };\n \n return result;\n }\n \n /**\n * Extract font properties from computed style and create font string\n */\n private static getFontString(element: HTMLElement): string {\n const cacheKey = element.className + element.id;\n \n if (this.fontCache.has(cacheKey)) {\n return this.fontCache.get(cacheKey)!;\n }\n \n const style = window.getComputedStyle(element);\n const font = [\n style.fontStyle,\n style.fontVariant,\n style.fontWeight,\n style.fontSize,\n style.fontFamily\n ].join(' ');\n \n this.fontCache.set(cacheKey, font);\n return font;\n }\n \n /**\n * Get line height in pixels\n */\n private static getLineHeight(element: HTMLElement, fontSize: number): number {\n const style = window.getComputedStyle(element);\n const lineHeight = style.lineHeight;\n \n if (lineHeight === 'normal') {\n // Browsers typically use 1.2 as default line height\n return fontSize * 1.2;\n }\n \n if (lineHeight.endsWith('px')) {\n return parseFloat(lineHeight);\n }\n \n // If it's a unitless number, multiply by font size\n const numericLineHeight = parseFloat(lineHeight);\n if (!isNaN(numericLineHeight)) {\n return fontSize * numericLineHeight;\n }\n \n return fontSize * 1.2; // fallback\n }\n \n /**\n * Measure text width using Canvas API\n */\n static measureTextWidth(text: string, font: string): number {\n const ctx = this.getContext();\n ctx.font = font;\n return ctx.measureText(text).width;\n }\n \n /**\n * Split text into lines based on width constraint\n */\n private static wrapText(\n text: string,\n maxWidth: number,\n font: string,\n whiteSpace: string\n ): string[] {\n // No wrapping needed\n if (whiteSpace === 'nowrap' || whiteSpace === 'pre') {\n return [text];\n }\n \n const ctx = this.getContext();\n ctx.font = font;\n \n const lines: string[] = [];\n const paragraphs = text.split('\\n');\n \n for (const paragraph of paragraphs) {\n if (whiteSpace === 'pre-wrap') {\n // Preserve whitespace but wrap at maxWidth\n lines.push(...this.wrapPreservingWhitespace(paragraph, maxWidth, ctx));\n } else {\n // Normal wrapping (collapse whitespace)\n lines.push(...this.wrapNormal(paragraph, maxWidth, ctx));\n }\n }\n \n return lines;\n }\n \n private static wrapNormal(\n text: string,\n maxWidth: number,\n ctx: CanvasRenderingContext2D\n ): string[] {\n const words = text.split(/\\s+/).filter(w => w.length > 0);\n const lines: string[] = [];\n let currentLine = '';\n \n for (const word of words) {\n const testLine = currentLine ? `${currentLine} ${word}` : word;\n const metrics = ctx.measureText(testLine);\n \n if (metrics.width > maxWidth && currentLine) {\n lines.push(currentLine);\n currentLine = word;\n } else {\n currentLine = testLine;\n }\n }\n \n if (currentLine) {\n lines.push(currentLine);\n }\n \n return lines.length > 0 ? lines : [''];\n }\n \n private static wrapPreservingWhitespace(\n text: string,\n maxWidth: number,\n ctx: CanvasRenderingContext2D\n ): string[] {\n const lines: string[] = [];\n let currentLine = '';\n \n for (let i = 0; i < text.length; i++) {\n const char = text[i];\n const testLine = currentLine + char;\n const metrics = ctx.measureText(testLine);\n \n if (metrics.width > maxWidth && currentLine) {\n lines.push(currentLine);\n currentLine = char;\n } else {\n currentLine = testLine;\n }\n }\n \n if (currentLine) {\n lines.push(currentLine);\n }\n \n return lines.length > 0 ? lines : [''];\n }\n \n /**\n * Calculate intrinsic content size for text - SMART METHOD\n * Automatically chooses the most efficient measurement technique\n */\n static calculateTextSize(\n element: HTMLElement,\n content: string,\n constrainingWidth?: number,\n constrainingHeight?: number\n ): { width: number; height: number } {\n // Empty content\n if (!content || content.length === 0) {\n const style = window.getComputedStyle(element);\n const paddingTop = parseFloat(style.paddingTop) || 0;\n const paddingBottom = parseFloat(style.paddingBottom) || 0;\n const paddingLeft = parseFloat(style.paddingLeft) || 0;\n const paddingRight = parseFloat(style.paddingRight) || 0;\n \n return {\n width: paddingLeft + paddingRight,\n height: paddingTop + paddingBottom\n };\n }\n \n // Check complexity of content\n const isPlain = this.isPlainText(content);\n const hasSimple = this.hasSimpleFormatting(content);\n \n // Strategy 1: Pure canvas for plain text (fastest)\n if (isPlain) {\n return this.calculatePlainTextSize(\n element,\n content,\n constrainingWidth,\n constrainingHeight\n );\n }\n \n // Strategy 2: Optimized DOM for simple formatting (fast)\n if (hasSimple) {\n // For simple formatting, we can still use canvas but need to strip tags\n const plainText = content.replace(/<[^>]+>/g, '');\n return this.calculatePlainTextSize(\n element,\n plainText,\n constrainingWidth,\n constrainingHeight\n );\n }\n \n // Strategy 3: DOM measurement for complex HTML (slower but accurate)\n return this.measureWithDOM(\n element,\n content,\n constrainingWidth,\n constrainingHeight\n );\n }\n \n /**\n * Calculate size for plain text using canvas (no HTML)\n */\n private static calculatePlainTextSize(\n element: HTMLElement,\n text: string,\n constrainingWidth?: number,\n constrainingHeight?: number\n ): { width: number; height: number } {\n const font = this.getFontString(element);\n const style = window.getComputedStyle(element);\n const whiteSpace = style.whiteSpace;\n \n // Get font size in pixels\n const fontSize = parseFloat(style.fontSize);\n const lineHeight = this.getLineHeight(element, fontSize);\n \n // Get padding\n const paddingLeft = parseFloat(style.paddingLeft) || 0;\n const paddingRight = parseFloat(style.paddingRight) || 0;\n const paddingTop = parseFloat(style.paddingTop) || 0;\n const paddingBottom = parseFloat(style.paddingBottom) || 0;\n \n // Adjust constraining width for padding\n const availableWidth = constrainingWidth\n ? constrainingWidth - paddingLeft - paddingRight\n : Infinity;\n \n // Calculate dimensions\n let width: number;\n let height: number;\n \n if (whiteSpace === 'nowrap' || whiteSpace === 'pre' || !constrainingWidth) {\n // Single line or no width constraint\n width = this.measureTextWidth(text, font) + paddingLeft + paddingRight;\n height = lineHeight + paddingTop + paddingBottom;\n } else {\n // Multi-line text\n const lines = this.wrapText(text, availableWidth, font, whiteSpace);\n \n // Find the widest line\n width = Math.max(\n ...lines.map(line => this.measureTextWidth(line, font))\n ) + paddingLeft + paddingRight;\n \n height = (lines.length * lineHeight) + paddingTop + paddingBottom;\n }\n \n return { width, height };\n }\n \n /**\n * Clear all caches (call when fonts change or for cleanup)\n */\n static clearCaches(): void {\n this.fontCache.clear();\n this.lineHeightCache.clear();\n }\n \n /**\n * Clean up measurement element (call on app cleanup)\n */\n static cleanup(): void {\n if (this.measurementElement && this.measurementElement.parentElement) {\n document.body.removeChild(this.measurementElement);\n }\n this.measurementElement = null;\n this.canvas = null;\n this.context = null;\n this.clearCaches();\n }\n}\n\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -40,6 +40,7 @@ export declare class UITextView extends UIView {
40
40
  static _ptToPx: number;
41
41
  static _pxToPt: number;
42
42
  _text?: string;
43
+ private _useFastMeasurement;
43
44
  constructor(elementID?: string, textViewType?: string | ValueOf<typeof UITextView.type>, viewHTMLElement?: null);
44
45
  static _determinePXAndPTRatios(): void;
45
46
  static type: {
@@ -86,5 +87,9 @@ export declare class UITextView extends UIView {
86
87
  layoutSubviews(): void;
87
88
  intrinsicContentHeight(constrainingWidth?: number): any;
88
89
  intrinsicContentWidth(constrainingHeight?: number): any;
90
+ intrinsicContentSizeWithConstraints(constrainingHeight?: number, constrainingWidth?: number): UIRectangle;
91
+ private _shouldUseFastMeasurement;
92
+ setUseFastMeasurement(useFast: boolean): void;
93
+ invalidateMeasurementStrategy(): void;
89
94
  intrinsicContentSize(): UIRectangle;
90
95
  }
@@ -24,6 +24,7 @@ module.exports = __toCommonJS(UITextView_exports);
24
24
  var import_UIColor = require("./UIColor");
25
25
  var import_UIObject = require("./UIObject");
26
26
  var import_UIRectangle = require("./UIRectangle");
27
+ var import_UITextMeasurement = require("./UITextMeasurement");
27
28
  var import_UIView = require("./UIView");
28
29
  const _UITextView = class extends import_UIView.UIView {
29
30
  constructor(elementID, textViewType = _UITextView.type.paragraph, viewHTMLElement = null) {
@@ -119,6 +120,8 @@ const _UITextView = class extends import_UIView.UIView {
119
120
  this._intrinsicHeightCache = new import_UIObject.UIObject();
120
121
  this._intrinsicWidthCache = new import_UIObject.UIObject();
121
122
  }
123
+ this._useFastMeasurement = void 0;
124
+ this._intrinsicSizesCache = {};
122
125
  this.setNeedsLayout();
123
126
  }
124
127
  set innerHTML(innerHTML) {
@@ -214,6 +217,48 @@ const _UITextView = class extends import_UIView.UIView {
214
217
  }
215
218
  return result;
216
219
  }
220
+ intrinsicContentSizeWithConstraints(constrainingHeight = 0, constrainingWidth = 0) {
221
+ var _a;
222
+ const cacheKey = "h_" + constrainingHeight + "__w_" + constrainingWidth;
223
+ const cachedResult = this._intrinsicSizesCache[cacheKey];
224
+ if (cachedResult) {
225
+ return cachedResult;
226
+ }
227
+ const shouldUseFastPath = (_a = this._useFastMeasurement) != null ? _a : this._shouldUseFastMeasurement();
228
+ let result;
229
+ if (shouldUseFastPath) {
230
+ const size = import_UITextMeasurement.UITextMeasurement.calculateTextSize(
231
+ this.viewHTMLElement,
232
+ this.text || this.innerHTML,
233
+ constrainingWidth || void 0,
234
+ constrainingHeight || void 0
235
+ );
236
+ result = new import_UIRectangle.UIRectangle(0, 0, size.height, size.width);
237
+ } else {
238
+ result = super.intrinsicContentSizeWithConstraints(constrainingHeight, constrainingWidth);
239
+ }
240
+ this._intrinsicSizesCache[cacheKey] = result.copy();
241
+ return result;
242
+ }
243
+ _shouldUseFastMeasurement() {
244
+ const content = this.text || this.innerHTML;
245
+ if ((0, import_UIObject.IS)(this._innerHTMLKey) || (0, import_UIObject.IS)(this._localizedTextObject)) {
246
+ return false;
247
+ }
248
+ if (this.notificationAmount > 0) {
249
+ return false;
250
+ }
251
+ const hasComplexHTML = /<(?!\/?(b|i|em|strong|span|br)\b)[^>]+>/i.test(content);
252
+ return !hasComplexHTML;
253
+ }
254
+ setUseFastMeasurement(useFast) {
255
+ this._useFastMeasurement = useFast;
256
+ this._intrinsicSizesCache = {};
257
+ }
258
+ invalidateMeasurementStrategy() {
259
+ this._useFastMeasurement = void 0;
260
+ this._intrinsicSizesCache = {};
261
+ }
217
262
  intrinsicContentSize() {
218
263
  const result = this.intrinsicContentSizeWithConstraints(import_UIObject.nil, import_UIObject.nil);
219
264
  return result;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../scripts/UITextView.ts"],
4
- "sourcesContent": ["import { UIColor } from \"./UIColor\"\nimport { UILocalizedTextObject } from \"./UIInterfaces\"\nimport { FIRST, IS_LIKE_NULL, nil, NO, UIObject, YES } from \"./UIObject\"\nimport { UIRectangle } from \"./UIRectangle\"\nimport type { ValueOf } from \"./UIObject\"\nimport { UIView, UIViewBroadcastEvent } from \"./UIView\"\n\n\nexport class UITextView extends UIView {\n \n \n _textColor: UIColor = UITextView.defaultTextColor\n _textAlignment?: ValueOf<typeof UITextView.textAlignment>\n \n _isSingleLine = YES\n \n textPrefix = \"\"\n textSuffix = \"\"\n \n _notificationAmount = 0\n \n _minFontSize?: number\n _maxFontSize?: number\n \n _automaticFontSizeSelection = NO\n \n changesOften = NO\n \n static defaultTextColor = UIColor.blackColor\n static notificationTextColor = UIColor.redColor\n \n static _intrinsicHeightCache: { [x: string]: { [x: string]: number; }; } & UIObject = new UIObject() as any\n static _intrinsicWidthCache: { [x: string]: { [x: string]: number; }; } & UIObject = new UIObject() as any\n \n _intrinsicHeightCache: { [x: string]: { [x: string]: number; }; } & UIObject = new UIObject() as any\n _intrinsicWidthCache: { [x: string]: { [x: string]: number; }; } & UIObject = new UIObject() as any\n \n \n static _ptToPx: number\n static _pxToPt: number\n _text?: string\n \n \n constructor(\n elementID?: string,\n textViewType: string | ValueOf<typeof UITextView.type> = UITextView.type.paragraph,\n viewHTMLElement = null\n ) {\n \n super(elementID, viewHTMLElement, textViewType)\n \n this.text = \"\"\n \n this.style.overflow = \"hidden\"\n this.style.textOverflow = \"ellipsis\"\n this.isSingleLine = YES\n \n this.textColor = this.textColor\n \n this.userInteractionEnabled = YES\n \n \n if (textViewType == UITextView.type.textArea) {\n \n this.pausesPointerEvents = YES\n \n this.addTargetForControlEvent(\n UIView.controlEvent.PointerUpInside,\n (sender, event) => sender.focus()\n )\n \n \n }\n \n \n }\n \n \n static _determinePXAndPTRatios() {\n \n if (UITextView._ptToPx) {\n return\n }\n \n const o = document.createElement(\"div\")\n o.style.width = \"1000pt\"\n document.body.appendChild(o)\n UITextView._ptToPx = o.clientWidth / 1000\n document.body.removeChild(o)\n UITextView._pxToPt = 1 / UITextView._ptToPx\n \n }\n \n \n static type = {\n \n \"paragraph\": \"p\",\n \"header1\": \"h1\",\n \"header2\": \"h2\",\n \"header3\": \"h3\",\n \"header4\": \"h4\",\n \"header5\": \"h5\",\n \"header6\": \"h6\",\n \"textArea\": \"textarea\",\n \"textField\": \"input\",\n \"span\": \"span\",\n \"label\": \"label\"\n \n } as const\n \n \n static textAlignment = {\n \n \"left\": \"left\",\n \"center\": \"center\",\n \"right\": \"right\",\n \"justify\": \"justify\"\n \n } as const\n \n get textAlignment() {\n // @ts-ignore\n return this.style.textAlign\n }\n \n set textAlignment(textAlignment: ValueOf<typeof UITextView.textAlignment>) {\n this._textAlignment = textAlignment\n this.style.textAlign = textAlignment\n }\n \n \n get textColor() {\n return this._textColor\n }\n \n set textColor(color: UIColor) {\n \n this._textColor = color || UITextView.defaultTextColor\n this.style.color = this._textColor.stringValue\n \n }\n \n \n get isSingleLine() {\n \n return this._isSingleLine\n \n }\n \n set isSingleLine(isSingleLine: boolean) {\n \n this._isSingleLine = isSingleLine\n \n this._intrinsicHeightCache = new UIObject() as any\n this._intrinsicWidthCache = new UIObject() as any\n \n if (isSingleLine) {\n \n this.style.whiteSpace = \"pre\"\n \n return\n \n }\n \n this.style.whiteSpace = \"pre-wrap\"\n \n }\n \n \n get notificationAmount() {\n \n return this._notificationAmount\n \n }\n \n set notificationAmount(notificationAmount: number) {\n \n if (this._notificationAmount == notificationAmount) {\n \n return\n \n }\n \n this._notificationAmount = notificationAmount\n \n this.text = this.text\n \n this.setNeedsLayoutUpToRootView()\n \n this.notificationAmountDidChange(notificationAmount)\n \n }\n \n notificationAmountDidChange(notificationAmount: number) {\n \n \n }\n \n \n get text() {\n \n return (this._text || this.viewHTMLElement.innerHTML)\n \n }\n \n set text(text) {\n \n this._text = text\n \n var notificationText = \"\"\n \n if (this.notificationAmount) {\n \n notificationText = \"<span style=\\\"color: \" + UITextView.notificationTextColor.stringValue + \";\\\">\" +\n (\" (\" + this.notificationAmount + \")\").bold() + \"</span>\"\n \n }\n \n if (this.viewHTMLElement.innerHTML != this.textPrefix + text + this.textSuffix + notificationText) {\n \n this.viewHTMLElement.innerHTML = this.textPrefix + FIRST(text, \"\") + this.textSuffix + notificationText\n \n }\n \n if (this.changesOften) {\n \n this._intrinsicHeightCache = new UIObject() as any\n this._intrinsicWidthCache = new UIObject() as any\n \n }\n \n this.setNeedsLayout()\n \n }\n \n override set innerHTML(innerHTML: string) {\n \n this.text = innerHTML\n \n }\n \n override get innerHTML() {\n \n return this.viewHTMLElement.innerHTML\n \n }\n \n \n setText(key: string, defaultString: string, parameters?: { [x: string]: string | UILocalizedTextObject }) {\n \n this.setInnerHTML(key, defaultString, parameters)\n \n }\n \n \n get fontSize() {\n \n const style = window.getComputedStyle(this.viewHTMLElement, null).fontSize\n \n const result = (parseFloat(style) * UITextView._pxToPt)\n \n return result\n \n }\n \n set fontSize(fontSize: number) {\n \n \n this.style.fontSize = \"\" + fontSize + \"pt\"\n \n this._intrinsicHeightCache = new UIObject() as any\n this._intrinsicWidthCache = new UIObject() as any // MEETOD LUUA!!!!\n \n \n }\n \n \n useAutomaticFontSize(minFontSize: number = nil, maxFontSize: number = nil) {\n \n \n this._automaticFontSizeSelection = YES\n \n \n this._minFontSize = minFontSize\n \n this._maxFontSize = maxFontSize\n \n this.setNeedsLayout()\n \n \n }\n \n \n static automaticallyCalculatedFontSize(\n bounds: UIRectangle,\n currentSize: UIRectangle,\n currentFontSize: number,\n minFontSize?: number,\n maxFontSize?: number\n ) {\n \n minFontSize = FIRST(minFontSize, 1)\n \n maxFontSize = FIRST(maxFontSize, 100000000000)\n \n \n const heightMultiplier = bounds.height / (currentSize.height + 1)\n \n const widthMultiplier = bounds.width / (currentSize.width + 1)\n \n \n var multiplier = heightMultiplier\n \n if (heightMultiplier > widthMultiplier) {\n \n multiplier = widthMultiplier\n \n \n }\n \n \n const maxFittingFontSize = currentFontSize * multiplier\n \n \n if (maxFittingFontSize > maxFontSize) {\n \n return maxFontSize\n \n }\n \n if (minFontSize > maxFittingFontSize) {\n \n return minFontSize\n \n }\n \n \n return maxFittingFontSize\n \n \n }\n \n \n override didReceiveBroadcastEvent(event: UIViewBroadcastEvent) {\n \n super.didReceiveBroadcastEvent(event)\n \n }\n \n \n override willMoveToSuperview(superview: UIView) {\n \n super.willMoveToSuperview(superview)\n \n }\n \n \n override layoutSubviews() {\n \n super.layoutSubviews()\n \n \n if (this._automaticFontSizeSelection) {\n \n this.fontSize = UITextView.automaticallyCalculatedFontSize(\n new UIRectangle(0, 0, 1 *\n this.viewHTMLElement.offsetHeight, 1 *\n this.viewHTMLElement.offsetWidth),\n this.intrinsicContentSize(),\n this.fontSize,\n this._minFontSize,\n this._maxFontSize\n )\n \n \n }\n \n \n }\n \n \n override intrinsicContentHeight(constrainingWidth = 0) {\n \n const keyPath = (this.viewHTMLElement.innerHTML + \"_csf_\" + this.computedStyle.font).replace(new RegExp(\n \"\\\\.\",\n \"g\"\n ), \"_\") + \".\" +\n (\"\" + constrainingWidth).replace(new RegExp(\"\\\\.\", \"g\"), \"_\")\n \n let cacheObject = UITextView._intrinsicHeightCache\n \n if (this.changesOften) {\n \n // @ts-ignore\n cacheObject = this._intrinsicHeightCache\n \n \n }\n \n \n var result = cacheObject.valueForKeyPath(keyPath)\n \n \n if (IS_LIKE_NULL(result)) {\n \n result = super.intrinsicContentHeight(constrainingWidth)\n \n cacheObject.setValueForKeyPath(keyPath, result)\n \n \n }\n \n \n return result\n \n }\n \n override intrinsicContentWidth(constrainingHeight = 0) {\n \n const keyPath = (this.viewHTMLElement.innerHTML + \"_csf_\" + this.computedStyle.font).replace(new RegExp(\n \"\\\\.\",\n \"g\"\n ), \"_\") + \".\" +\n (\"\" + constrainingHeight).replace(new RegExp(\"\\\\.\", \"g\"), \"_\")\n \n let cacheObject = UITextView._intrinsicWidthCache\n \n if (this.changesOften) {\n \n // @ts-ignore\n cacheObject = this._intrinsicWidthCache\n \n \n }\n \n \n var result = cacheObject.valueForKeyPath(keyPath)\n \n \n if (IS_LIKE_NULL(result)) {\n \n result = super.intrinsicContentWidth(constrainingHeight)\n \n cacheObject.setValueForKeyPath(keyPath, result)\n \n \n }\n \n \n return result\n \n }\n \n \n override intrinsicContentSize() {\n \n // This works but is slow\n const result = this.intrinsicContentSizeWithConstraints(nil, nil)\n \n return result\n \n }\n \n \n}\n\n\nUITextView._determinePXAndPTRatios()\n\n\n// /**\n// * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.\n// * \n// * @param {String} text The text to be rendered.\n// * @param {String} font The css font descriptor that text is to be rendered with (e.g. \"bold 14px verdana\").\n// * \n// * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393\n// */\n// function getTextMetrics(text, font) {\n// // re-use canvas object for better performance\n// var canvas = getTextMetrics.canvas || (getTextMetrics.canvas = document.createElement(\"canvas\"));\n// var context = canvas.getContext(\"2d\");\n// context.font = font;\n// var metrics = context.measureText(text);\n// return metrics;\n// }\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { UIColor } from \"./UIColor\"\nimport { UILocalizedTextObject } from \"./UIInterfaces\"\nimport { FIRST, IS, IS_LIKE_NULL, nil, NO, UIObject, YES } from \"./UIObject\"\nimport { UIRectangle } from \"./UIRectangle\"\nimport type { ValueOf } from \"./UIObject\"\nimport { UITextMeasurement } from \"./UITextMeasurement\"\nimport { UIView, UIViewBroadcastEvent } from \"./UIView\"\n\n\nexport class UITextView extends UIView {\n \n \n _textColor: UIColor = UITextView.defaultTextColor\n _textAlignment?: ValueOf<typeof UITextView.textAlignment>\n \n _isSingleLine = YES\n \n textPrefix = \"\"\n textSuffix = \"\"\n \n _notificationAmount = 0\n \n _minFontSize?: number\n _maxFontSize?: number\n \n _automaticFontSizeSelection = NO\n \n changesOften = NO\n \n static defaultTextColor = UIColor.blackColor\n static notificationTextColor = UIColor.redColor\n \n static _intrinsicHeightCache: { [x: string]: { [x: string]: number; }; } & UIObject = new UIObject() as any\n static _intrinsicWidthCache: { [x: string]: { [x: string]: number; }; } & UIObject = new UIObject() as any\n \n _intrinsicHeightCache: { [x: string]: { [x: string]: number; }; } & UIObject = new UIObject() as any\n _intrinsicWidthCache: { [x: string]: { [x: string]: number; }; } & UIObject = new UIObject() as any\n \n \n static _ptToPx: number\n static _pxToPt: number\n _text?: string\n \n private _useFastMeasurement: boolean | undefined;\n \n \n constructor(\n elementID?: string,\n textViewType: string | ValueOf<typeof UITextView.type> = UITextView.type.paragraph,\n viewHTMLElement = null\n ) {\n \n super(elementID, viewHTMLElement, textViewType)\n \n this.text = \"\"\n \n this.style.overflow = \"hidden\"\n this.style.textOverflow = \"ellipsis\"\n this.isSingleLine = YES\n \n this.textColor = this.textColor\n \n this.userInteractionEnabled = YES\n \n \n if (textViewType == UITextView.type.textArea) {\n \n this.pausesPointerEvents = YES\n \n this.addTargetForControlEvent(\n UIView.controlEvent.PointerUpInside,\n (sender, event) => sender.focus()\n )\n \n \n }\n \n \n }\n \n \n static _determinePXAndPTRatios() {\n \n if (UITextView._ptToPx) {\n return\n }\n \n const o = document.createElement(\"div\")\n o.style.width = \"1000pt\"\n document.body.appendChild(o)\n UITextView._ptToPx = o.clientWidth / 1000\n document.body.removeChild(o)\n UITextView._pxToPt = 1 / UITextView._ptToPx\n \n }\n \n \n static type = {\n \n \"paragraph\": \"p\",\n \"header1\": \"h1\",\n \"header2\": \"h2\",\n \"header3\": \"h3\",\n \"header4\": \"h4\",\n \"header5\": \"h5\",\n \"header6\": \"h6\",\n \"textArea\": \"textarea\",\n \"textField\": \"input\",\n \"span\": \"span\",\n \"label\": \"label\"\n \n } as const\n \n \n static textAlignment = {\n \n \"left\": \"left\",\n \"center\": \"center\",\n \"right\": \"right\",\n \"justify\": \"justify\"\n \n } as const\n \n get textAlignment() {\n // @ts-ignore\n return this.style.textAlign\n }\n \n set textAlignment(textAlignment: ValueOf<typeof UITextView.textAlignment>) {\n this._textAlignment = textAlignment\n this.style.textAlign = textAlignment\n }\n \n \n get textColor() {\n return this._textColor\n }\n \n set textColor(color: UIColor) {\n \n this._textColor = color || UITextView.defaultTextColor\n this.style.color = this._textColor.stringValue\n \n }\n \n \n get isSingleLine() {\n \n return this._isSingleLine\n \n }\n \n set isSingleLine(isSingleLine: boolean) {\n \n this._isSingleLine = isSingleLine\n \n this._intrinsicHeightCache = new UIObject() as any\n this._intrinsicWidthCache = new UIObject() as any\n \n if (isSingleLine) {\n \n this.style.whiteSpace = \"pre\"\n \n return\n \n }\n \n this.style.whiteSpace = \"pre-wrap\"\n \n }\n \n \n get notificationAmount() {\n \n return this._notificationAmount\n \n }\n \n set notificationAmount(notificationAmount: number) {\n \n if (this._notificationAmount == notificationAmount) {\n \n return\n \n }\n \n this._notificationAmount = notificationAmount\n \n this.text = this.text\n \n this.setNeedsLayoutUpToRootView()\n \n this.notificationAmountDidChange(notificationAmount)\n \n }\n \n notificationAmountDidChange(notificationAmount: number) {\n \n \n }\n \n \n get text() {\n \n return (this._text || this.viewHTMLElement.innerHTML)\n \n }\n \n set text(text) {\n this._text = text\n var notificationText = \"\"\n if (this.notificationAmount) {\n notificationText = \"<span style=\\\"color: \" + UITextView.notificationTextColor.stringValue + \";\\\">\" +\n (\" (\" + this.notificationAmount + \")\").bold() + \"</span>\"\n }\n \n if (this.viewHTMLElement.innerHTML != this.textPrefix + text + this.textSuffix + notificationText) {\n this.viewHTMLElement.innerHTML = this.textPrefix + FIRST(text, \"\") + this.textSuffix + notificationText\n }\n \n if (this.changesOften) {\n this._intrinsicHeightCache = new UIObject() as any\n this._intrinsicWidthCache = new UIObject() as any\n }\n // Invalidate measurement strategy when text changes significantly\n this._useFastMeasurement = undefined;\n this._intrinsicSizesCache = {};\n \n this.setNeedsLayout()\n \n }\n \n override set innerHTML(innerHTML: string) {\n \n this.text = innerHTML\n \n }\n \n override get innerHTML() {\n \n return this.viewHTMLElement.innerHTML\n \n }\n \n \n setText(key: string, defaultString: string, parameters?: { [x: string]: string | UILocalizedTextObject }) {\n \n this.setInnerHTML(key, defaultString, parameters)\n \n }\n \n \n get fontSize() {\n \n const style = window.getComputedStyle(this.viewHTMLElement, null).fontSize\n \n const result = (parseFloat(style) * UITextView._pxToPt)\n \n return result\n \n }\n \n set fontSize(fontSize: number) {\n \n \n this.style.fontSize = \"\" + fontSize + \"pt\"\n \n this._intrinsicHeightCache = new UIObject() as any\n this._intrinsicWidthCache = new UIObject() as any // MEETOD LUUA!!!!\n \n \n }\n \n \n useAutomaticFontSize(minFontSize: number = nil, maxFontSize: number = nil) {\n \n \n this._automaticFontSizeSelection = YES\n \n \n this._minFontSize = minFontSize\n \n this._maxFontSize = maxFontSize\n \n this.setNeedsLayout()\n \n \n }\n \n \n static automaticallyCalculatedFontSize(\n bounds: UIRectangle,\n currentSize: UIRectangle,\n currentFontSize: number,\n minFontSize?: number,\n maxFontSize?: number\n ) {\n \n minFontSize = FIRST(minFontSize, 1)\n \n maxFontSize = FIRST(maxFontSize, 100000000000)\n \n \n const heightMultiplier = bounds.height / (currentSize.height + 1)\n \n const widthMultiplier = bounds.width / (currentSize.width + 1)\n \n \n var multiplier = heightMultiplier\n \n if (heightMultiplier > widthMultiplier) {\n \n multiplier = widthMultiplier\n \n \n }\n \n \n const maxFittingFontSize = currentFontSize * multiplier\n \n \n if (maxFittingFontSize > maxFontSize) {\n \n return maxFontSize\n \n }\n \n if (minFontSize > maxFittingFontSize) {\n \n return minFontSize\n \n }\n \n \n return maxFittingFontSize\n \n \n }\n \n \n override didReceiveBroadcastEvent(event: UIViewBroadcastEvent) {\n \n super.didReceiveBroadcastEvent(event)\n \n }\n \n \n override willMoveToSuperview(superview: UIView) {\n \n super.willMoveToSuperview(superview)\n \n }\n \n \n override layoutSubviews() {\n \n super.layoutSubviews()\n \n \n if (this._automaticFontSizeSelection) {\n \n this.fontSize = UITextView.automaticallyCalculatedFontSize(\n new UIRectangle(0, 0, 1 *\n this.viewHTMLElement.offsetHeight, 1 *\n this.viewHTMLElement.offsetWidth),\n this.intrinsicContentSize(),\n this.fontSize,\n this._minFontSize,\n this._maxFontSize\n )\n \n \n }\n \n \n }\n \n \n override intrinsicContentHeight(constrainingWidth = 0) {\n \n const keyPath = (this.viewHTMLElement.innerHTML + \"_csf_\" + this.computedStyle.font).replace(new RegExp(\n \"\\\\.\",\n \"g\"\n ), \"_\") + \".\" +\n (\"\" + constrainingWidth).replace(new RegExp(\"\\\\.\", \"g\"), \"_\")\n \n let cacheObject = UITextView._intrinsicHeightCache\n \n if (this.changesOften) {\n \n // @ts-ignore\n cacheObject = this._intrinsicHeightCache\n \n \n }\n \n \n var result = cacheObject.valueForKeyPath(keyPath)\n \n \n if (IS_LIKE_NULL(result)) {\n \n result = super.intrinsicContentHeight(constrainingWidth)\n \n cacheObject.setValueForKeyPath(keyPath, result)\n \n \n }\n \n \n return result\n \n }\n \n override intrinsicContentWidth(constrainingHeight = 0) {\n \n const keyPath = (this.viewHTMLElement.innerHTML + \"_csf_\" + this.computedStyle.font).replace(new RegExp(\n \"\\\\.\",\n \"g\"\n ), \"_\") + \".\" +\n (\"\" + constrainingHeight).replace(new RegExp(\"\\\\.\", \"g\"), \"_\")\n \n let cacheObject = UITextView._intrinsicWidthCache\n \n if (this.changesOften) {\n \n // @ts-ignore\n cacheObject = this._intrinsicWidthCache\n \n \n }\n \n \n var result = cacheObject.valueForKeyPath(keyPath)\n \n \n if (IS_LIKE_NULL(result)) {\n \n result = super.intrinsicContentWidth(constrainingHeight)\n \n cacheObject.setValueForKeyPath(keyPath, result)\n \n \n }\n \n \n return result\n \n }\n \n \n override intrinsicContentSizeWithConstraints(\n constrainingHeight: number = 0,\n constrainingWidth: number = 0\n ): UIRectangle {\n const cacheKey = \"h_\" + constrainingHeight + \"__w_\" + constrainingWidth;\n const cachedResult = this._intrinsicSizesCache[cacheKey];\n if (cachedResult) {\n return cachedResult;\n }\n \n // Determine measurement strategy\n const shouldUseFastPath = this._useFastMeasurement ?? this._shouldUseFastMeasurement();\n \n let result: UIRectangle;\n \n if (shouldUseFastPath) {\n // Fast path: canvas-based measurement\n const size = UITextMeasurement.calculateTextSize(\n this.viewHTMLElement,\n this.text || this.innerHTML,\n constrainingWidth || undefined,\n constrainingHeight || undefined\n );\n result = new UIRectangle(0, 0, size.height, size.width);\n } else {\n // Fallback: original DOM-based measurement for complex content\n result = super.intrinsicContentSizeWithConstraints(constrainingHeight, constrainingWidth);\n }\n \n this._intrinsicSizesCache[cacheKey] = result.copy();\n return result;\n }\n \n // Helper to determine if we can use fast measurement\n private _shouldUseFastMeasurement(): boolean {\n const content = this.text || this.innerHTML;\n \n // If using dynamic innerHTML with parameters, use DOM measurement\n if (IS(this._innerHTMLKey) || IS(this._localizedTextObject)) {\n return false;\n }\n \n // Check for notification badges\n if (this.notificationAmount > 0) {\n return false; // Has span with colored text\n }\n \n // Check content complexity\n const hasComplexHTML = /<(?!\\/?(b|i|em|strong|span|br)\\b)[^>]+>/i.test(content);\n \n return !hasComplexHTML;\n }\n \n // Optional: Allow manual override for specific instances\n setUseFastMeasurement(useFast: boolean): void {\n this._useFastMeasurement = useFast;\n this._intrinsicSizesCache = {};\n }\n \n // Optional: Force re-evaluation of measurement strategy\n invalidateMeasurementStrategy(): void {\n this._useFastMeasurement = undefined;\n this._intrinsicSizesCache = {};\n }\n \n \n \n override intrinsicContentSize() {\n \n // This works but is slow\n const result = this.intrinsicContentSizeWithConstraints(nil, nil)\n \n return result\n \n }\n \n \n}\n\n\nUITextView._determinePXAndPTRatios()\n\n\n// /**\n// * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.\n// * \n// * @param {String} text The text to be rendered.\n// * @param {String} font The css font descriptor that text is to be rendered with (e.g. \"bold 14px verdana\").\n// * \n// * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393\n// */\n// function getTextMetrics(text, font) {\n// // re-use canvas object for better performance\n// var canvas = getTextMetrics.canvas || (getTextMetrics.canvas = document.createElement(\"canvas\"));\n// var context = canvas.getContext(\"2d\");\n// context.font = font;\n// var metrics = context.measureText(text);\n// return metrics;\n// }\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -136,7 +136,7 @@ export declare class UIView extends UIObject {
136
136
  static _onWindowMouseMove: (event: MouseEvent) => void;
137
137
  static _onWindowMouseup: (event: MouseEvent) => void;
138
138
  private _resizeObserverEntry?;
139
- private _intrinsicSizesCache;
139
+ protected _intrinsicSizesCache: Record<string, UIRectangle>;
140
140
  constructor(elementID?: string, viewHTMLElement?: HTMLElement & LooseObject | null, elementType?: string | null, initViewData?: any);
141
141
  static get nextIndex(): number;
142
142
  static get pageHeight(): number;