uicore-ts 1.0.521 → 1.0.527

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 (60) hide show
  1. package/compiledScripts/UIButton.d.ts +2 -2
  2. package/compiledScripts/UIButton.js +1 -0
  3. package/compiledScripts/UIButton.js.map +2 -2
  4. package/compiledScripts/UICore.js +3 -1
  5. package/compiledScripts/UICore.js.map +2 -2
  6. package/compiledScripts/UICoreExtensions.d.ts +4 -1
  7. package/compiledScripts/UICoreExtensions.js +29 -3
  8. package/compiledScripts/UICoreExtensions.js.map +2 -2
  9. package/compiledScripts/UIDialogView.d.ts +2 -2
  10. package/compiledScripts/UIDialogView.js +1 -0
  11. package/compiledScripts/UIDialogView.js.map +2 -2
  12. package/compiledScripts/UIImageView.js +4 -1
  13. package/compiledScripts/UIImageView.js.map +2 -2
  14. package/compiledScripts/UIKeyValueSorter.d.ts +42 -0
  15. package/compiledScripts/UIKeyValueSorter.js +155 -0
  16. package/compiledScripts/UIKeyValueSorter.js.map +7 -0
  17. package/compiledScripts/UIKeyValueSorterWebWorker.worker.d.ts +10 -0
  18. package/compiledScripts/UIKeyValueSorterWebWorker.worker.js +78 -0
  19. package/compiledScripts/UIKeyValueSorterWebWorker.worker.js.map +7 -0
  20. package/compiledScripts/UILinkButton.d.ts +1 -1
  21. package/compiledScripts/UINativeScrollView.d.ts +1 -0
  22. package/compiledScripts/UINativeScrollView.js +7 -3
  23. package/compiledScripts/UINativeScrollView.js.map +2 -2
  24. package/compiledScripts/UIObject.d.ts +14 -4
  25. package/compiledScripts/UIObject.js +4 -0
  26. package/compiledScripts/UIObject.js.map +2 -2
  27. package/compiledScripts/UIRootViewController.js +8 -9
  28. package/compiledScripts/UIRootViewController.js.map +2 -2
  29. package/compiledScripts/UITableView.d.ts +1 -0
  30. package/compiledScripts/UITableView.js +3 -1
  31. package/compiledScripts/UITableView.js.map +2 -2
  32. package/compiledScripts/UITextField.d.ts +1 -1
  33. package/compiledScripts/UITextField.js.map +2 -2
  34. package/compiledScripts/UITextView.js +4 -2
  35. package/compiledScripts/UITextView.js.map +2 -2
  36. package/compiledScripts/UIView.d.ts +12 -3
  37. package/compiledScripts/UIView.js +101 -40
  38. package/compiledScripts/UIView.js.map +2 -2
  39. package/compiledScripts/UIViewController.js +4 -2
  40. package/compiledScripts/UIViewController.js.map +2 -2
  41. package/compiledScripts/index.d.ts +1 -1
  42. package/compiledScripts/index.js +1 -1
  43. package/compiledScripts/index.js.map +2 -2
  44. package/package.json +1 -1
  45. package/scripts/UIButton.ts +2 -2
  46. package/scripts/UICore.ts +37 -36
  47. package/scripts/UICoreExtensions.ts +41 -4
  48. package/scripts/UIDialogView.ts +2 -2
  49. package/scripts/UIImageView.ts +1 -1
  50. package/scripts/{UIKeyValueStringSorter.ts → UIKeyValueSorter.ts} +10 -9
  51. package/scripts/{UIKeyValueStringSorterWebWorker.worker.ts → UIKeyValueSorterWebWorker.worker.ts} +15 -4
  52. package/scripts/UINativeScrollView.ts +10 -4
  53. package/scripts/UIObject.ts +24 -6
  54. package/scripts/UIRootViewController.ts +16 -5
  55. package/scripts/UITableView.ts +4 -5
  56. package/scripts/UITextField.ts +1 -1
  57. package/scripts/UITextView.ts +20 -12
  58. package/scripts/UIView.ts +165 -65
  59. package/scripts/UIViewController.ts +7 -3
  60. package/scripts/index.ts +1 -1
@@ -195,7 +195,7 @@ export class UIRootViewController extends UIViewController {
195
195
  maxScale = 1
196
196
  } = {}
197
197
  ) {
198
- const actualPageWidth = (UIView.pageWidth * UIView.pageScale).integerValue
198
+ const actualPageWidth = window.innerWidth ?? (UIView.pageWidth * UIView.pageScale).integerValue
199
199
  let scale = minScale + (maxScale - minScale) *
200
200
  ((actualPageWidth - minScaleWidth) / (maxScaleWidth - minScaleWidth))
201
201
  scale = Math.min(scale, maxScale)
@@ -220,19 +220,22 @@ export class UIRootViewController extends UIViewController {
220
220
  this.topBarView.frame = new UIRectangle(0, 0, topBarHeight, bounds.width)
221
221
  }
222
222
 
223
- this.backgroundView.style.top = "" + this.topBarView?.frame.height.integerValue ?? 0 + "px"
223
+ this.backgroundView.style.top = "" + (this.topBarView?.frame.height.integerValue ?? 0) + "px"
224
224
  this.backgroundView.style.width = "100%"
225
225
  this.backgroundView.style.height = "fit-content"
226
226
  this.backgroundView.style.minHeight = "" +
227
227
  (bounds.height - (this.topBarView?.frame.height ?? 0) - (this.bottomBarView?.frame.height ?? 0)).integerValue + "px"
228
228
 
229
- const contentView = this.contentViewController?.view ?? nil
229
+ const contentView: UIView = this.contentViewController?.view ?? nil
230
+
231
+ //var contentViewStyleString = contentView.viewHTMLElement.style.cssText
232
+
230
233
  contentView.style.position = "relative"
231
234
  contentView.style.bottom = "0"
232
235
  contentView.style.top = "0"
233
236
  contentView.style.width = "100%"
234
237
  contentView.setPaddings(nil, nil, paddingLength, nil)
235
- contentView.setNeedsLayout()
238
+
236
239
 
237
240
  if (contentViewMaxWidth < this.backgroundView.bounds.width) {
238
241
 
@@ -261,6 +264,14 @@ export class UIRootViewController extends UIViewController {
261
264
 
262
265
  }
263
266
 
267
+ // if (contentViewStyleString != contentView.style.cssText) {
268
+ //
269
+ // contentView.setNeedsLayout()
270
+ //
271
+ // }
272
+
273
+
274
+
264
275
  // Triggering immediate layout to ensure that the intrinsicContentHeight calculations work well
265
276
  this.contentViewController?._triggerLayoutViewSubviews()
266
277
 
@@ -276,7 +287,7 @@ export class UIRootViewController extends UIViewController {
276
287
 
277
288
 
278
289
  contentView.style.height = "" + contentViewControllerViewHeight.integerValue + "px"
279
- contentView.setNeedsLayout()
290
+ //contentView.setNeedsLayout()
280
291
 
281
292
  if (IS(this.detailsViewController)) {
282
293
 
@@ -42,16 +42,14 @@ export class UITableView extends UINativeScrollView {
42
42
  _highestValidRowPositionIndex: number = 0
43
43
 
44
44
  _reusableViews: UITableViewReusableViewsContainerObject = {}
45
-
46
45
  _removedReusableViews: UITableViewReusableViewsContainerObject = {}
47
46
 
48
47
  _fullHeightView: UIView
49
-
50
48
  _rowIDIndex: number = 0
51
-
52
49
  reloadsOnLanguageChange = YES
53
-
54
50
  sidePadding = 0
51
+
52
+ cellWeights?: number[]
55
53
 
56
54
  _persistedData: any[] = []
57
55
  _needsDrawingOfVisibleRowsBeforeLayout = NO
@@ -280,7 +278,7 @@ export class UITableView extends UINativeScrollView {
280
278
  row
281
279
  )
282
280
  row.removeFromSuperview()
283
- this._removedReusableViews[row._UITableViewReusabilityIdentifier].push(row)
281
+ this._removedReusableViews[row?._UITableViewReusabilityIdentifier]?.push(row)
284
282
 
285
283
 
286
284
  })
@@ -460,6 +458,7 @@ export class UITableView extends UINativeScrollView {
460
458
 
461
459
  viewForRowWithIndex(rowIndex: number): UITableViewRowView {
462
460
  const row = this.reusableViewForIdentifier("Row", rowIndex);
461
+ row._UITableViewRowIndex = rowIndex
463
462
  FIRST_OR_NIL((row as unknown as UIButton).titleLabel).text = "Row " + rowIndex
464
463
  return row
465
464
  }
@@ -47,7 +47,7 @@ export class UITextField extends UITextView {
47
47
  })
48
48
 
49
49
 
50
- override get controlEventTargetAccumulator(): UIViewAddControlEventTargetObject<UITextField> {
50
+ override get controlEventTargetAccumulator(): UIViewAddControlEventTargetObject<typeof UITextField> {
51
51
  return (super.controlEventTargetAccumulator as any)
52
52
  }
53
53
 
@@ -41,7 +41,11 @@ export class UITextView extends UIView {
41
41
  _text?: string
42
42
 
43
43
 
44
- constructor(elementID?: string, textViewType: string | ValueOf<typeof UITextView.type> = UITextView.type.paragraph, viewHTMLElement = null) {
44
+ constructor(
45
+ elementID?: string,
46
+ textViewType: string | ValueOf<typeof UITextView.type> = UITextView.type.paragraph,
47
+ viewHTMLElement = null
48
+ ) {
45
49
 
46
50
  super(elementID, viewHTMLElement, textViewType)
47
51
 
@@ -57,15 +61,15 @@ export class UITextView extends UIView {
57
61
 
58
62
 
59
63
  if (textViewType == UITextView.type.textArea) {
60
-
64
+
61
65
  this.pausesPointerEvents = YES
62
-
66
+
63
67
  this.addTargetForControlEvent(
64
68
  UIView.controlEvent.PointerUpInside,
65
69
  (sender, event) => sender.focus()
66
70
  )
67
-
68
-
71
+
72
+
69
73
  }
70
74
 
71
75
 
@@ -73,18 +77,18 @@ export class UITextView extends UIView {
73
77
 
74
78
 
75
79
  static _determinePXAndPTRatios() {
76
-
80
+
77
81
  if (UITextView._ptToPx) {
78
82
  return
79
83
  }
80
-
84
+
81
85
  const o = document.createElement("div")
82
86
  o.style.width = "1000pt"
83
87
  document.body.appendChild(o)
84
88
  UITextView._ptToPx = o.clientWidth / 1000
85
89
  document.body.removeChild(o)
86
90
  UITextView._pxToPt = 1 / UITextView._ptToPx
87
-
91
+
88
92
  }
89
93
 
90
94
 
@@ -218,17 +222,21 @@ export class UITextView extends UIView {
218
222
 
219
223
  }
220
224
 
221
- this._intrinsicHeightCache = new UIObject() as any
222
- this._intrinsicWidthCache = new UIObject() as any
225
+ if (this.changesOften) {
226
+
227
+ this._intrinsicHeightCache = new UIObject() as any
228
+ this._intrinsicWidthCache = new UIObject() as any
229
+
230
+ }
223
231
 
224
232
  this.setNeedsLayout()
225
233
 
226
234
  }
227
235
 
228
236
  override set innerHTML(innerHTML: string) {
229
-
237
+
230
238
  this.text = innerHTML
231
-
239
+
232
240
  }
233
241
 
234
242
  override get innerHTML() {
package/scripts/UIView.ts CHANGED
@@ -5,20 +5,7 @@ import { UICore } from "./UICore"
5
5
  import "./UICoreExtensions"
6
6
  import type { UIDialogView } from "./UIDialogView"
7
7
  import { UILocalizedTextObject } from "./UIInterfaces"
8
- import {
9
- FIRST,
10
- FIRST_OR_NIL,
11
- IF,
12
- IS,
13
- IS_DEFINED,
14
- IS_NIL,
15
- IS_NOT,
16
- nil,
17
- NO,
18
- RETURNER,
19
- UIObject,
20
- YES
21
- } from "./UIObject"
8
+ import { FIRST, FIRST_OR_NIL, IF, IS, IS_DEFINED, IS_NIL, IS_NOT, nil, NO, RETURNER, UIObject, YES } from "./UIObject"
22
9
  import { UIPoint } from "./UIPoint"
23
10
  import { UIRectangle } from "./UIRectangle"
24
11
  import { UIViewController } from "./UIViewController"
@@ -87,6 +74,17 @@ if (!window.AutoLayout) {
87
74
  }
88
75
 
89
76
 
77
+ declare global {
78
+
79
+ interface HTMLElement {
80
+
81
+ UIView?: UIView;
82
+
83
+ }
84
+
85
+ }
86
+
87
+
90
88
  export interface LooseObject {
91
89
  [key: string]: any
92
90
  }
@@ -119,7 +117,7 @@ export type UIViewAddControlEventTargetObject<T extends { controlEvent: Record<s
119
117
  sender: UIView,
120
118
  event: Event
121
119
  ) => void) & Partial<UIViewAddControlEventTargetObject<T>>
122
-
120
+
123
121
  }>
124
122
 
125
123
 
@@ -136,6 +134,7 @@ interface Constraint {
136
134
 
137
135
 
138
136
  export function UIComponentView(target: Function, context: ClassDecoratorContext) {
137
+ console.log("Recording annotation UIComponentView on " + target.name)
139
138
  UIObject.recordAnnotation(UIComponentView, target)
140
139
  }
141
140
 
@@ -201,7 +200,14 @@ export class UIView extends UIObject {
201
200
  static _pageScale = 1
202
201
  _scale: number = 1
203
202
  isInternalScaling: boolean = YES
204
- private _resizeObserver!: ResizeObserver
203
+ static resizeObserver = new ResizeObserver((entries, observer) => {
204
+ for (let i = 0; i < entries.length; i++) {
205
+ const entry = entries[i]
206
+ // @ts-ignore
207
+ const view: UIView = entry.target.UIView
208
+ view?.didResize?.(entry)
209
+ }
210
+ })
205
211
 
206
212
  private _isMovable = NO
207
213
  makeNotMovable?: () => void
@@ -216,6 +222,8 @@ export class UIView extends UIObject {
216
222
  static _onWindowTouchMove: (event: TouchEvent) => void = nil
217
223
  static _onWindowMouseMove: (event: MouseEvent) => void = nil
218
224
  static _onWindowMouseup: (event: MouseEvent) => void = nil
225
+ private _resizeObserverEntry?: ResizeObserverEntry
226
+ private _intrinsicSizesCache: Record<string, UIRectangle> = {}
219
227
 
220
228
 
221
229
  constructor(
@@ -321,9 +329,6 @@ export class UIView extends UIObject {
321
329
  this.viewHTMLElement.UIView = this
322
330
  this.addStyleClass(this.styleClassName)
323
331
 
324
- this._resizeObserver = new ResizeObserver(() => this.setNeedsLayout())
325
- this._resizeObserver.observe(this.viewHTMLElement)
326
-
327
332
  }
328
333
 
329
334
 
@@ -947,10 +952,10 @@ export class UIView extends UIObject {
947
952
  let result: UIRectangle & { zIndex?: number } = this._frame?.copy() as any
948
953
  if (!result) {
949
954
  result = new UIRectangle(
950
- this.viewHTMLElement.offsetLeft,
951
- this.viewHTMLElement.offsetTop,
952
- this.viewHTMLElement.offsetHeight,
953
- this.viewHTMLElement.offsetWidth
955
+ this._resizeObserverEntry?.contentRect.left ?? this.viewHTMLElement.offsetLeft,
956
+ this._resizeObserverEntry?.contentRect.top ?? this.viewHTMLElement.offsetTop,
957
+ this._resizeObserverEntry?.contentRect.height ?? this.viewHTMLElement.offsetHeight,
958
+ this._resizeObserverEntry?.contentRect.width ?? this.viewHTMLElement.offsetWidth
954
959
  ) as any
955
960
  result.zIndex = 0
956
961
  }
@@ -974,7 +979,7 @@ export class UIView extends UIObject {
974
979
  }
975
980
  this._frame = rectangle
976
981
 
977
- if (frame && frame.isEqualTo(rectangle) && frame.zIndex == rectangle.zIndex && !performUncheckedLayout) {
982
+ if (frame && frame != nil && frame.isEqualTo(rectangle) && frame.zIndex == rectangle.zIndex && !performUncheckedLayout) {
978
983
  return
979
984
  }
980
985
 
@@ -994,7 +999,7 @@ export class UIView extends UIObject {
994
999
 
995
1000
  if (frame.height != rectangle.height || frame.width != rectangle.width || performUncheckedLayout) {
996
1001
  this.setNeedsLayout()
997
- this.boundsDidChange()
1002
+ this.boundsDidChange(this.bounds)
998
1003
  }
999
1004
 
1000
1005
  }
@@ -1002,7 +1007,12 @@ export class UIView extends UIObject {
1002
1007
  get bounds() {
1003
1008
  let result: UIRectangle
1004
1009
  if (IS_NOT(this._frame)) {
1005
- result = new UIRectangle(0, 0, this.viewHTMLElement.offsetHeight, this.viewHTMLElement.offsetWidth)
1010
+ result = new UIRectangle(
1011
+ 0,
1012
+ 0,
1013
+ this._resizeObserverEntry?.contentRect.height ?? this.viewHTMLElement.offsetHeight,
1014
+ this._resizeObserverEntry?.contentRect.width ?? this.viewHTMLElement.offsetWidth
1015
+ )
1006
1016
  }
1007
1017
  else {
1008
1018
  result = this.frame.copy()
@@ -1013,7 +1023,7 @@ export class UIView extends UIObject {
1013
1023
  }
1014
1024
 
1015
1025
 
1016
- set bounds(rectangle) {
1026
+ set bounds(rectangle: UIRectangle) {
1017
1027
  const frame = this.frame
1018
1028
  const newFrame = new UIRectangle(frame.topLeft.x, frame.topLeft.y, rectangle.height, rectangle.width)
1019
1029
  // @ts-ignore
@@ -1021,9 +1031,18 @@ export class UIView extends UIObject {
1021
1031
  this.frame = newFrame
1022
1032
  }
1023
1033
 
1024
- boundsDidChange() {
1034
+ boundsDidChange(bounds: UIRectangle) {
1035
+
1025
1036
 
1037
+ }
1026
1038
 
1039
+ didResize(entry: ResizeObserverEntry) {
1040
+
1041
+ this._resizeObserverEntry = entry
1042
+ this.setNeedsLayout()
1043
+
1044
+ this.boundsDidChange(new UIRectangle(0, 0, entry.contentRect.height, entry.contentRect.width))
1045
+
1027
1046
  }
1028
1047
 
1029
1048
  get frameTransform(): string {
@@ -1059,7 +1078,7 @@ export class UIView extends UIObject {
1059
1078
  const bounds = this.bounds
1060
1079
  if (bounds.height != previousBounds.height || bounds.width != previousBounds.width) {
1061
1080
  this.setNeedsLayout()
1062
- this.boundsDidChange()
1081
+ this.boundsDidChange(bounds)
1063
1082
  }
1064
1083
 
1065
1084
  }
@@ -1074,7 +1093,7 @@ export class UIView extends UIObject {
1074
1093
  const bounds = this.bounds
1075
1094
  if (bounds.height != previousBounds.height || bounds.width != previousBounds.width) {
1076
1095
  this.setNeedsLayout()
1077
- this.boundsDidChange()
1096
+ this.boundsDidChange(bounds)
1078
1097
  }
1079
1098
 
1080
1099
  }
@@ -1089,7 +1108,7 @@ export class UIView extends UIObject {
1089
1108
  const bounds = this.bounds
1090
1109
  if (bounds.height != previousBounds.height || bounds.width != previousBounds.width) {
1091
1110
  this.setNeedsLayout()
1092
- this.boundsDidChange()
1111
+ this.boundsDidChange(bounds)
1093
1112
  }
1094
1113
 
1095
1114
  }
@@ -1104,7 +1123,7 @@ export class UIView extends UIObject {
1104
1123
  const bounds = this.bounds
1105
1124
  if (bounds.height != previousBounds.height || bounds.width != previousBounds.width) {
1106
1125
  this.setNeedsLayout()
1107
- this.boundsDidChange()
1126
+ this.boundsDidChange(bounds)
1108
1127
  }
1109
1128
 
1110
1129
  }
@@ -1118,7 +1137,7 @@ export class UIView extends UIObject {
1118
1137
  const bounds = this.bounds
1119
1138
  if (bounds.height != previousBounds.height || bounds.width != previousBounds.width) {
1120
1139
  this.setNeedsLayout()
1121
- this.boundsDidChange()
1140
+ this.boundsDidChange(bounds)
1122
1141
  }
1123
1142
 
1124
1143
  }
@@ -1135,7 +1154,7 @@ export class UIView extends UIObject {
1135
1154
  const bounds = this.bounds
1136
1155
  if (bounds.height != previousBounds.height || bounds.width != previousBounds.width) {
1137
1156
  this.setNeedsLayout()
1138
- this.boundsDidChange()
1157
+ this.boundsDidChange(bounds)
1139
1158
  }
1140
1159
 
1141
1160
  }
@@ -1150,7 +1169,7 @@ export class UIView extends UIObject {
1150
1169
  const bounds = this.bounds
1151
1170
  if (bounds.height != previousBounds.height || bounds.width != previousBounds.width) {
1152
1171
  this.setNeedsLayout()
1153
- this.boundsDidChange()
1172
+ this.boundsDidChange(bounds)
1154
1173
  }
1155
1174
 
1156
1175
  }
@@ -1168,7 +1187,7 @@ export class UIView extends UIObject {
1168
1187
  const bounds = this.bounds
1169
1188
  if (bounds.height != previousBounds.height || bounds.width != previousBounds.width) {
1170
1189
  this.setNeedsLayout()
1171
- this.boundsDidChange()
1190
+ this.boundsDidChange(bounds)
1172
1191
  }
1173
1192
 
1174
1193
  }
@@ -1416,42 +1435,62 @@ export class UIView extends UIObject {
1416
1435
  width = width.integerValue + "px"
1417
1436
  }
1418
1437
 
1419
- let str = element.style.cssText
1438
+ //let str = element.style.cssText
1420
1439
 
1421
- frameTransform = UIView._transformAttribute + ": translate3d(" + (left).integerValue + "px, " +
1440
+ frameTransform =
1441
+ "translate3d(" + (left).integerValue + "px, " +
1422
1442
  (top).integerValue + "px, 0px)" + frameTransform
1423
1443
 
1444
+ const style = element.style
1445
+
1424
1446
  if (element.UIView) {
1425
1447
 
1426
- str = str + frameTransform +
1427
- (element.style.transform.match(
1428
- new RegExp("scale\\(.*\\)", "g")
1429
- )?.firstElement ?? "") + ";"
1448
+ frameTransform = frameTransform + (style.transform.match(
1449
+ new RegExp("scale\\(.*\\)", "g")
1450
+ )?.firstElement ?? "")
1451
+
1452
+ //str = str + UIView._transformAttribute + ": " + frameTransform + ";"
1430
1453
 
1431
1454
  }
1432
1455
 
1433
1456
  if (IS_NIL(height)) {
1434
- str = str + " height: unset;"
1435
- }
1436
- else {
1437
- str = str + " height:" + height + ";"
1457
+
1458
+ //str = str + " height: unset;"
1459
+ height = "unset"
1460
+
1438
1461
  }
1462
+ // else {
1463
+ // str = str + " height:" + height + ";"
1464
+ // }
1439
1465
 
1440
1466
  if (IS_NIL(width)) {
1441
- str = str + " width: unset;"
1442
- }
1443
- else {
1444
- str = str + " width:" + width + ";"
1467
+
1468
+ //str = str + " width: unset;"
1469
+ width = "unset"
1470
+
1445
1471
  }
1472
+ // else {
1473
+ // str = str + " width:" + width + ";"
1474
+ // }
1475
+
1476
+ let zIndexString = "" + zIndex
1446
1477
 
1447
1478
  if (IS_NIL(zIndex)) {
1448
- str = str + " z-index: unset;"
1449
- }
1450
- else {
1451
- str = str + " z-index:" + zIndex + ";"
1479
+
1480
+ //str = str + " z-index: unset;"
1481
+ zIndexString = "unset"
1482
+
1452
1483
  }
1484
+ // else {
1485
+ // str = str + " z-index:" + zIndex + ";"
1486
+ // }
1487
+
1488
+ style.transform = frameTransform
1489
+ style.height = height
1490
+ style.width = width
1491
+ style.zIndex = zIndexString
1453
1492
 
1454
- element.style.cssText = element.style.cssText + str
1493
+ //element.style.cssText = element.style.cssText + str
1455
1494
 
1456
1495
  }
1457
1496
 
@@ -1587,6 +1626,8 @@ export class UIView extends UIObject {
1587
1626
  // Register view for layout before next frame
1588
1627
  UIView._viewsToLayout.push(this)
1589
1628
 
1629
+ this._intrinsicSizesCache = {}
1630
+
1590
1631
  if (UIView._viewsToLayout.length == 1) {
1591
1632
  UIView.scheduleLayoutViewsIfNeeded()
1592
1633
  }
@@ -1651,7 +1692,7 @@ export class UIView extends UIObject {
1651
1692
  applyClassesAndStyles() {
1652
1693
  for (let i = 0; i < this.styleClasses.length; i++) {
1653
1694
  const styleClass = this.styleClasses[i]
1654
- if (styleClass) {
1695
+ if (styleClass && !this.viewHTMLElement.classList.contains(styleClass)) {
1655
1696
  this.viewHTMLElement.classList.add(styleClass)
1656
1697
  }
1657
1698
  }
@@ -1859,8 +1900,8 @@ export class UIView extends UIObject {
1859
1900
  views.forEach(view => this.addSubview(view))
1860
1901
  }
1861
1902
 
1862
- addedAsSubviewToView(view: UIView, aboveView?: UIView) {
1863
- view.addSubview(this, aboveView)
1903
+ addedAsSubviewToView(view: UIView | undefined, aboveView?: UIView) {
1904
+ view?.addSubview(this, aboveView)
1864
1905
  return this
1865
1906
  }
1866
1907
 
@@ -1935,12 +1976,16 @@ export class UIView extends UIObject {
1935
1976
  }
1936
1977
 
1937
1978
  wasAddedToViewTree() {
1938
-
1979
+
1980
+ UIView.resizeObserver.observe(this.viewHTMLElement)
1981
+
1939
1982
  }
1940
1983
 
1941
1984
 
1942
1985
  wasRemovedFromViewTree() {
1943
-
1986
+
1987
+ UIView.resizeObserver.unobserve(this.viewHTMLElement)
1988
+
1944
1989
  }
1945
1990
 
1946
1991
 
@@ -1966,6 +2011,19 @@ export class UIView extends UIObject {
1966
2011
  return result
1967
2012
  }
1968
2013
 
2014
+ get elementWithAllSuperviewElements(): HTMLElement[] {
2015
+ const result = []
2016
+ let view: (HTMLElement & { UIView?: UIView }) | undefined | null = this.viewHTMLElement
2017
+ for (let i = 0; IS(view); i = i) {
2018
+ if (!view) {
2019
+ return result
2020
+ }
2021
+ result.push(view)
2022
+ view = view.parentElement
2023
+ }
2024
+ return result
2025
+ }
2026
+
1969
2027
 
1970
2028
  setNeedsLayoutOnAllSuperviews() {
1971
2029
  this.withAllSuperviews.reverse().everyElement.setNeedsLayout()
@@ -3252,19 +3310,52 @@ export class UIView extends UIObject {
3252
3310
  }
3253
3311
 
3254
3312
  rectangleInView(rectangle: UIRectangle, view: UIView) {
3313
+
3255
3314
  if (!view.isMemberOfViewTree || !this.isMemberOfViewTree) {
3256
3315
  return nil
3257
3316
  }
3258
3317
 
3259
- const viewClientRectangle = view.viewHTMLElement.getBoundingClientRect()
3260
- const viewLocation = new UIPoint(viewClientRectangle.left, viewClientRectangle.top)
3318
+ // Get all the superview elements
3319
+ const allViewSuperviewElements = view.elementWithAllSuperviewElements
3320
+
3321
+ // Find the first common element and the views in between
3322
+ const superviewElementsUntilCommonElement = this.elementWithAllSuperviewElements.slice(
3323
+ 0,
3324
+ this.elementWithAllSuperviewElements.findIndex(
3325
+ viewElement => allViewSuperviewElements.contains(viewElement)
3326
+ ) + 1
3327
+ )
3328
+ const commonElement = superviewElementsUntilCommonElement.lastElement
3329
+ const viewSuperviewElementsUntilCommonElement = allViewSuperviewElements.slice(
3330
+ 0,
3331
+ allViewSuperviewElements.findIndex(viewElement => viewElement == commonElement) + 1
3332
+ )
3333
+
3334
+ // Step until the common element and record the offsets
3335
+ let selfOffsetPoint = new UIPoint(0, 0)
3336
+ //let selfScale = 1
3337
+ for (let i = 0; i < superviewElementsUntilCommonElement.length - 1; i++) {
3338
+ const element = superviewElementsUntilCommonElement[i]
3339
+ selfOffsetPoint = selfOffsetPoint.add(
3340
+ element.UIView?.frame.min ?? new UIPoint(element.offsetLeft, element.offsetTop)
3341
+ )
3342
+ //selfScale = selfScale * (element.UIView?.scale ?? (element.getBoundingClientRect().width / element.offsetWidth))
3343
+ }
3261
3344
 
3262
- const selfClientRectangle = this.viewHTMLElement.getBoundingClientRect()
3263
- const selfLocation = new UIPoint(selfClientRectangle.left, selfClientRectangle.top)
3345
+ let viewOffsetPoint = new UIPoint(0, 0)
3346
+ //let viewScale = 1
3347
+ for (let i = 0; i < viewSuperviewElementsUntilCommonElement.length - 1; i++) {
3348
+ const element = viewSuperviewElementsUntilCommonElement[i]
3349
+ viewOffsetPoint = viewOffsetPoint.add(
3350
+ element.UIView?.frame.min ?? new UIPoint(element.offsetLeft, element.offsetTop)
3351
+ )
3352
+ //viewScale = viewScale * (element.UIView?.scale ?? (element.getBoundingClientRect().width / element.offsetWidth))
3353
+ }
3264
3354
 
3265
- const offsetPoint = selfLocation.subtract(viewLocation)
3355
+ const offsetPoint = selfOffsetPoint.subtract(viewOffsetPoint)
3266
3356
 
3267
3357
  return rectangle.copy().offsetByPoint(offsetPoint)
3358
+
3268
3359
  }
3269
3360
 
3270
3361
 
@@ -3275,6 +3366,12 @@ export class UIView extends UIObject {
3275
3366
 
3276
3367
  intrinsicContentSizeWithConstraints(constrainingHeight: number = 0, constrainingWidth: number = 0) {
3277
3368
 
3369
+ const cacheKey = "h_" + constrainingHeight + "__w_" + constrainingWidth
3370
+ const cachedResult = this._intrinsicSizesCache[cacheKey]
3371
+ if (cachedResult) {
3372
+ return cachedResult
3373
+ }
3374
+
3278
3375
  // This works but is slow
3279
3376
 
3280
3377
  const result = new UIRectangle(0, 0, 0, 0)
@@ -3343,6 +3440,8 @@ export class UIView extends UIObject {
3343
3440
  result.width = resultWidth
3344
3441
 
3345
3442
 
3443
+ this._intrinsicSizesCache[cacheKey] = result.copy()
3444
+
3346
3445
  return result
3347
3446
 
3348
3447
  }
@@ -3367,6 +3466,7 @@ export class UIView extends UIObject {
3367
3466
 
3368
3467
  }
3369
3468
 
3469
+
3370
3470
  }
3371
3471
 
3372
3472
 
@@ -79,9 +79,13 @@ export class UIViewController extends UIObject {
79
79
 
80
80
  _triggerLayoutViewSubviews() {
81
81
 
82
- this.view.layoutSubviews()
83
-
84
- this.viewDidLayoutSubviews()
82
+ if (this.view.needsLayout) {
83
+
84
+ this.view.layoutSubviews()
85
+
86
+ this.viewDidLayoutSubviews()
87
+
88
+ }
85
89
 
86
90
  }
87
91
 
package/scripts/index.ts CHANGED
@@ -17,7 +17,7 @@ export * from "./UILink"
17
17
  export * from "./UILinkButton"
18
18
  export * from "./UILayoutGrid"
19
19
  export * from "./UIKeyValueStringFilter"
20
- export * from "./UIKeyValueStringSorter"
20
+ export * from "./UIKeyValueSorter"
21
21
  export * from "./UIImageView"
22
22
  export * from "./UIDialogView"
23
23
  export * from "./UIDateTimeInput"