uicore-ts 1.1.57 → 1.1.59

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.
@@ -3,7 +3,7 @@ import { UILocalizedTextObject } from "./UIInterfaces"
3
3
  import { FIRST, IS, IS_LIKE_NULL, nil, NO, UIObject, YES } from "./UIObject"
4
4
  import { UIRectangle } from "./UIRectangle"
5
5
  import type { ValueOf } from "./UIObject"
6
- import { UITextMeasurement } from "./UITextMeasurement"
6
+ import { TextMeasurementStyle, UITextMeasurement } from "./UITextMeasurement"
7
7
  import { UIView, UIViewBroadcastEvent } from "./UIView"
8
8
 
9
9
 
@@ -42,6 +42,7 @@ export class UITextView extends UIView {
42
42
  _text?: string
43
43
 
44
44
  private _useFastMeasurement: boolean | undefined;
45
+ private _cachedMeasurementStyles: TextMeasurementStyle | undefined;
45
46
 
46
47
 
47
48
  constructor(
@@ -167,6 +168,8 @@ export class UITextView extends UIView {
167
168
 
168
169
  this.style.whiteSpace = "pre-wrap"
169
170
 
171
+ this.invalidateMeasurementStrategy()
172
+
170
173
  }
171
174
 
172
175
 
@@ -225,6 +228,8 @@ export class UITextView extends UIView {
225
228
  // Invalidate measurement strategy when text changes significantly
226
229
  this._useFastMeasurement = undefined;
227
230
  this._intrinsicSizesCache = {};
231
+ this.invalidateMeasurementStrategy()
232
+ this._invalidateMeasurementStyles()
228
233
 
229
234
  this.setNeedsLayout()
230
235
 
@@ -233,6 +238,7 @@ export class UITextView extends UIView {
233
238
  override set innerHTML(innerHTML: string) {
234
239
 
235
240
  this.text = innerHTML
241
+ this.invalidateMeasurementStrategy()
236
242
 
237
243
  }
238
244
 
@@ -246,13 +252,14 @@ export class UITextView extends UIView {
246
252
  setText(key: string, defaultString: string, parameters?: { [x: string]: string | UILocalizedTextObject }) {
247
253
 
248
254
  this.setInnerHTML(key, defaultString, parameters)
255
+ this.invalidateMeasurementStrategy()
249
256
 
250
257
  }
251
258
 
252
259
 
253
260
  get fontSize() {
254
261
 
255
- const style = window.getComputedStyle(this.viewHTMLElement, null).fontSize
262
+ const style = this.style.fontSize || window.getComputedStyle(this.viewHTMLElement, null).fontSize
256
263
 
257
264
  const result = (parseFloat(style) * UITextView._pxToPt)
258
265
 
@@ -262,29 +269,30 @@ export class UITextView extends UIView {
262
269
 
263
270
  set fontSize(fontSize: number) {
264
271
 
272
+ if (fontSize != this.fontSize) {
273
+
274
+ this.style.fontSize = "" + fontSize + "pt"
275
+
276
+ this._intrinsicHeightCache = new UIObject() as any
277
+ this._intrinsicWidthCache = new UIObject() as any // MEETOD LUUA!!!!
278
+
279
+ this._invalidateMeasurementStyles() // Invalidate when font changes
265
280
 
266
- this.style.fontSize = "" + fontSize + "pt"
267
-
268
- this._intrinsicHeightCache = new UIObject() as any
269
- this._intrinsicWidthCache = new UIObject() as any // MEETOD LUUA!!!!
270
-
281
+ }
271
282
 
272
283
  }
273
284
 
274
285
 
286
+
275
287
  useAutomaticFontSize(minFontSize: number = nil, maxFontSize: number = nil) {
276
288
 
277
-
278
289
  this._automaticFontSizeSelection = YES
279
290
 
280
-
281
291
  this._minFontSize = minFontSize
282
-
283
292
  this._maxFontSize = maxFontSize
284
293
 
285
294
  this.setNeedsLayout()
286
295
 
287
-
288
296
  }
289
297
 
290
298
 
@@ -297,44 +305,28 @@ export class UITextView extends UIView {
297
305
  ) {
298
306
 
299
307
  minFontSize = FIRST(minFontSize, 1)
300
-
301
308
  maxFontSize = FIRST(maxFontSize, 100000000000)
302
309
 
303
-
304
310
  const heightMultiplier = bounds.height / (currentSize.height + 1)
305
-
306
311
  const widthMultiplier = bounds.width / (currentSize.width + 1)
307
312
 
308
-
309
313
  var multiplier = heightMultiplier
310
-
311
314
  if (heightMultiplier > widthMultiplier) {
312
-
313
315
  multiplier = widthMultiplier
314
-
315
-
316
316
  }
317
317
 
318
-
319
318
  const maxFittingFontSize = currentFontSize * multiplier
320
319
 
321
-
322
320
  if (maxFittingFontSize > maxFontSize) {
323
-
324
321
  return maxFontSize
325
-
326
322
  }
327
323
 
328
324
  if (minFontSize > maxFittingFontSize) {
329
-
330
325
  return minFontSize
331
-
332
326
  }
333
327
 
334
-
335
328
  return maxFittingFontSize
336
329
 
337
-
338
330
  }
339
331
 
340
332
 
@@ -449,6 +441,58 @@ export class UITextView extends UIView {
449
441
  }
450
442
 
451
443
 
444
+ // Call this when styles change (fontSize, padding, etc.)
445
+ private _invalidateMeasurementStyles(): void {
446
+ this._cachedMeasurementStyles = undefined;
447
+ UITextMeasurement.invalidateElement(this.viewHTMLElement);
448
+ this._intrinsicSizesCache = {};
449
+ }
450
+
451
+ // Extract styles ONCE and cache them (avoids getComputedStyle)
452
+ private _getMeasurementStyles(): TextMeasurementStyle {
453
+ if (this._cachedMeasurementStyles) {
454
+ return this._cachedMeasurementStyles;
455
+ }
456
+
457
+ // Only call getComputedStyle once and cache the result
458
+ const computed = window.getComputedStyle(this.viewHTMLElement);
459
+ const fontSize = parseFloat(computed.fontSize);
460
+
461
+ this._cachedMeasurementStyles = {
462
+ font: [
463
+ computed.fontStyle,
464
+ computed.fontVariant,
465
+ computed.fontWeight,
466
+ computed.fontSize,
467
+ computed.fontFamily
468
+ ].join(' '),
469
+ fontSize: fontSize,
470
+ lineHeight: this._parseLineHeight(computed.lineHeight, fontSize),
471
+ whiteSpace: computed.whiteSpace,
472
+ paddingLeft: parseFloat(computed.paddingLeft) || 0,
473
+ paddingRight: parseFloat(computed.paddingRight) || 0,
474
+ paddingTop: parseFloat(computed.paddingTop) || 0,
475
+ paddingBottom: parseFloat(computed.paddingBottom) || 0
476
+ };
477
+
478
+ return this._cachedMeasurementStyles;
479
+ }
480
+
481
+ private _parseLineHeight(lineHeight: string, fontSize: number): number {
482
+ if (lineHeight === 'normal') {
483
+ return fontSize * 1.2;
484
+ }
485
+ if (lineHeight.endsWith('px')) {
486
+ return parseFloat(lineHeight);
487
+ }
488
+ const numericLineHeight = parseFloat(lineHeight);
489
+ if (!isNaN(numericLineHeight)) {
490
+ return fontSize * numericLineHeight;
491
+ }
492
+ return fontSize * 1.2;
493
+ }
494
+
495
+ // Override the intrinsic size method
452
496
  override intrinsicContentSizeWithConstraints(
453
497
  constrainingHeight: number = 0,
454
498
  constrainingWidth: number = 0
@@ -465,12 +509,14 @@ export class UITextView extends UIView {
465
509
  let result: UIRectangle;
466
510
 
467
511
  if (shouldUseFastPath) {
468
- // Fast path: canvas-based measurement
512
+ // Fast path: canvas-based measurement with pre-extracted styles
513
+ const styles = this._getMeasurementStyles();
469
514
  const size = UITextMeasurement.calculateTextSize(
470
515
  this.viewHTMLElement,
471
516
  this.text || this.innerHTML,
472
517
  constrainingWidth || undefined,
473
- constrainingHeight || undefined
518
+ constrainingHeight || undefined,
519
+ styles // Pass pre-computed styles to avoid getComputedStyle!
474
520
  );
475
521
  result = new UIRectangle(0, 0, size.height, size.width);
476
522
  } else {
@@ -487,7 +533,7 @@ export class UITextView extends UIView {
487
533
  const content = this.text || this.innerHTML;
488
534
 
489
535
  // If using dynamic innerHTML with parameters, use DOM measurement
490
- if (IS(this._innerHTMLKey) || IS(this._localizedTextObject)) {
536
+ if (this._innerHTMLKey || this._localizedTextObject) {
491
537
  return false;
492
538
  }
493
539
 
@@ -511,11 +557,13 @@ export class UITextView extends UIView {
511
557
  // Optional: Force re-evaluation of measurement strategy
512
558
  invalidateMeasurementStrategy(): void {
513
559
  this._useFastMeasurement = undefined;
514
- this._intrinsicSizesCache = {};
560
+ this._invalidateMeasurementStyles();
515
561
  }
516
562
 
517
563
 
518
564
 
565
+
566
+
519
567
  override intrinsicContentSize() {
520
568
 
521
569
  // This works but is slow
package/scripts/UIView.ts CHANGED
@@ -1944,9 +1944,14 @@ export class UIView extends UIObject {
1944
1944
  }
1945
1945
 
1946
1946
 
1947
+ cancelNeedsLayout() {
1948
+ this._shouldLayout = NO
1949
+ }
1950
+
1947
1951
  removeFromSuperview() {
1948
1952
  if (IS(this.superview)) {
1949
1953
  this.forEachViewInSubtree(view => view.blur())
1954
+ this.cancelNeedsLayout()
1950
1955
  const index = this.superview.subviews.indexOf(this)
1951
1956
  if (index > -1) {
1952
1957
  this.superview.subviews.splice(index, 1)