uicore-ts 1.1.357 → 1.1.362
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/compiledScripts/UIAutocompleteDropdownView.js +1 -0
- package/compiledScripts/UIAutocompleteDropdownView.js.map +2 -2
- package/compiledScripts/UIDialogView.js +3 -0
- package/compiledScripts/UIDialogView.js.map +2 -2
- package/compiledScripts/UIRootViewController.js +20 -14
- package/compiledScripts/UIRootViewController.js.map +2 -2
- package/compiledScripts/UITableView.d.ts +7 -0
- package/compiledScripts/UITableView.js +10 -1
- package/compiledScripts/UITableView.js.map +2 -2
- package/package.json +1 -1
- package/scripts/UIAutocompleteDropdownView.ts +5 -3
- package/scripts/UIDialogView.ts +6 -0
- package/scripts/UIRootViewController.ts +37 -12
- package/scripts/UITableView.ts +17 -1
|
@@ -43,6 +43,7 @@ class UIAutocompleteDropdownView extends import_UIView.UIView {
|
|
|
43
43
|
this.style.boxSizing = "content-box";
|
|
44
44
|
this.tableView = new import_UITableView.UITableView(elementID ? elementID + "TableView" : void 0);
|
|
45
45
|
this.addSubview(this.tableView);
|
|
46
|
+
this.tableView.disablesKeyboardNavigation = import_UIObject.YES;
|
|
46
47
|
this.tableView.allRowsHaveEqualHeight = import_UIObject.YES;
|
|
47
48
|
this.tableView.numberOfRows = () => this._filteredItems.length;
|
|
48
49
|
this.tableView.heightForRowWithIndex = () => this._rowHeight;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../scripts/UIAutocompleteDropdownView.ts"],
|
|
4
|
-
"sourcesContent": ["// noinspection JSConstantReassignment\n\nimport { UIAutocompleteItem, UIAutocompleteRowView } from \"./UIAutocompleteRowView\"\nimport { UIColor } from \"./UIColor\"\nimport { IS, IS_NOT, NO, YES } from \"./UIObject\"\nimport { UIRectangle } from \"./UIRectangle\"\nimport { UITableView } from \"./UITableView\"\nimport { UIView } from \"./UIView\"\n\n\nexport class UIAutocompleteDropdownView<T> extends UIView {\n \n tableView: UITableView\n _fullHeightView: UIView\n \n _filteredItems: UIAutocompleteItem<T>[] = []\n _filterWords: string[] = []\n _highlightedRowIndex: number = -1\n _rowHeight: number = 36\n _maxVisibleRows: number = 8\n _isPointerInsideDropdown: boolean = NO\n _suppressHoverHighlight: boolean = NO\n \n didSelectItem?: (item: UIAutocompleteItem<T>) => void\n anchorView?: UIView\n \n constructor(elementID?: string) {\n \n super(elementID)\n \n this.hidden = YES\n this.userInteractionEnabled = YES\n \n this.backgroundColor = UIColor.whiteColor\n this.setBorder(0, 1)\n this.style.boxSizing = \"content-box\"\n \n this.tableView = new UITableView(elementID ? elementID + \"TableView\" : undefined)\n this.addSubview(this.tableView)\n \n this.tableView.allRowsHaveEqualHeight = YES\n this.tableView.numberOfRows = () => this._filteredItems.length\n this.tableView.heightForRowWithIndex = () => this._rowHeight\n this.tableView.newReusableViewForIdentifier = (identifier, rowIndex) => this.newRowView(identifier, rowIndex)\n this.tableView.viewForRowWithIndex = (index) => this.viewForRowWithIndex(index)\n \n // A transparent full-height view so the native scrollbar reflects the total\n // content height rather than just the virtualised visible rows.\n this._fullHeightView = new UIView(elementID ? elementID + \"FullHeightView\" : undefined)\n this._fullHeightView.userInteractionEnabled = NO\n this.tableView.addSubview(this._fullHeightView)\n \n // Use a native mousemove listener on the tableView element so we catch movement\n // regardless of which child row the pointer is over (framework events don't bubble\n // up through the scroll container from its row children).\n this.tableView.viewHTMLElement.addEventListener(\"mousemove\", () => {\n this._suppressHoverHighlight = NO\n })\n \n }\n \n \n /** Override in subclass to provide custom row views. */\n newRowView(identifier: string, rowIndex: number): UIAutocompleteRowView<T> {\n return new UIAutocompleteRowView<T>(this.elementID + identifier + rowIndex)\n }\n \n \n viewForRowWithIndex(index: number): UIView {\n \n const row = this.tableView.reusableViewForIdentifier(\n \"AutocompleteRow\",\n index\n ) as UIAutocompleteRowView<T>\n \n const item = this._filteredItems[index]\n if (IS(item)) {\n row.item = item\n }\n \n row.filterWords = this._filterWords\n \n // Reflect current keyboard highlight state via the native selected flag.\n row.selected = (index === this._highlightedRowIndex)\n \n // PointerHover fires as the pointer moves over the row.\n // We suppress scroll-into-view since the user is already looking at the row.\n // We also suppress highlight changes after a keyboard-triggered scroll, until\n // the pointer actually moves (PointerMove clears the suppression flag).\n const rowWasHovered = () => {\n if (this._suppressHoverHighlight) {\n return\n }\n this._setHighlightedRowIndex(index, NO)\n }\n if ((row as any)._autocompleteHoverHandler) {\n row.removeTargetForControlEvent(\n UIView.controlEvent.PointerHover,\n (row as any)._autocompleteHoverHandler\n )\n }\n row.controlEventTargetAccumulator.PointerHover = rowWasHovered;\n (row as any)._autocompleteHoverHandler = rowWasHovered\n \n // Clicking a row selects it.\n const rowWasTapped = () => {\n if (IS(item) && this.didSelectItem) {\n this.didSelectItem(item)\n }\n }\n if ((row as any)._autocompleteTapHandler) {\n row.removeTargetForControlEvent(\n UIView.controlEvent.PointerUpInside,\n (row as any)._autocompleteTapHandler\n )\n }\n row.controlEventTargetAccumulator.PointerUpInside = rowWasTapped;\n (row as any)._autocompleteTapHandler = rowWasTapped\n \n return row\n \n }\n \n \n get highlightedRowIndex(): number {\n return this._highlightedRowIndex\n }\n \n set highlightedRowIndex(index: number) {\n this._setHighlightedRowIndex(index, YES)\n }\n \n \n /** Internal setter. scrollIntoView=YES for keyboard navigation, NO for pointer hover. */\n _setHighlightedRowIndex(index: number, scrollIntoView: boolean) {\n \n const previousIndex = this._highlightedRowIndex\n this._highlightedRowIndex = index\n \n // Clear selected state on previous row.\n const previousRow = this.tableView.visibleRowWithIndex(previousIndex) as\n UIAutocompleteRowView<T> | undefined\n if (IS(previousRow)) {\n previousRow.selected = NO\n }\n \n // Set selected state on newly highlighted row.\n const currentRow = this.tableView.visibleRowWithIndex(index) as\n UIAutocompleteRowView<T> | undefined\n if (IS(currentRow)) {\n currentRow.selected = YES\n \n if (scrollIntoView) {\n // Scroll the view if needed\n let contentOffset = this.tableView.contentOffset\n if (currentRow.frame.y < contentOffset.y) {\n contentOffset.y = currentRow.frame.y\n }\n if (currentRow.frame.max.y > (contentOffset.y + this.tableView.bounds.height)) {\n contentOffset = contentOffset.pointByAddingY(-(contentOffset.y + this.tableView.bounds.height -\n currentRow.frame.max.y))\n }\n const animationDuration = this.tableView.animationDuration\n this.tableView.animationDuration = 0\n this.tableView.contentOffset = contentOffset\n this.tableView.animationDuration = animationDuration\n \n // Suppress hover-driven highlight changes until the user physically\n // moves the mouse \u2014 the native mousemove listener on the tableView\n // element clears this flag when actual movement is detected.\n this._suppressHoverHighlight = YES\n }\n }\n \n }\n \n \n get highlightedItem(): UIAutocompleteItem<T> | undefined {\n if (this._highlightedRowIndex >= 0 && this._highlightedRowIndex < this._filteredItems.length) {\n return this._filteredItems[this._highlightedRowIndex]\n }\n return undefined\n }\n \n \n set filteredItems(items: UIAutocompleteItem<T>[]) {\n this._filteredItems = items\n this._highlightedRowIndex = -1\n this.tableView.reloadData()\n this.hidden = (items.length === 0)\n this._updateFullHeightView()\n this.setNeedsLayout()\n }\n \n get filteredItems(): UIAutocompleteItem<T>[] {\n return this._filteredItems\n }\n \n \n set filterWords(words: string[]) {\n this._filterWords = words\n this.tableView.reloadData()\n }\n \n get filterWords(): string[] {\n return this._filterWords\n }\n \n \n /** Anchors this dropdown below the given field view inside the rootView. */\n showAnchoredToView(anchorView: UIView) {\n \n this.anchorView = anchorView\n \n this.calculateAndSetViewFrame = () => {\n \n const rootView = anchorView.rootView\n \n const padding = anchorView.core.paddingLength\n \n if (!this.superview || this.superview !== rootView) {\n this.removeFromSuperview()\n rootView.addSubview(this)\n }\n \n const fieldFrameInRoot = (this.anchorView?.superview?.rectangleInView(\n this.anchorView?.frame,\n rootView\n ) as UIRectangle)\n .rectangleByAddingX(padding)\n .rectangleByAddingY(padding)\n \n if (IS_NOT(fieldFrameInRoot)) {\n return\n }\n \n const dropdownHeight = Math.min(\n this._filteredItems.length * this._rowHeight,\n this._maxVisibleRows * this._rowHeight\n )\n \n \n this.frame = fieldFrameInRoot.rectangleForNextRow(0, dropdownHeight)\n \n }\n \n this.setNeedsLayoutUpToRootView()\n this.calculateAndSetViewFrame()\n \n this.style.zIndex = \"10000\"\n this.hidden = (this._filteredItems.length === 0)\n \n }\n \n \n dismiss() {\n this.hidden = YES\n this._highlightedRowIndex = -1\n this._isPointerInsideDropdown = NO\n }\n \n \n _updateFullHeightView() {\n const totalHeight = this._filteredItems.length * this._rowHeight\n this._fullHeightView.frame = this._fullHeightView.frame\n .rectangleWithY(0)\n .rectangleWithHeight(totalHeight)\n .rectangleWithWidth(1)\n this._fullHeightView.hasWeakFrame = YES\n }\n \n \n override layoutSubviews() {\n \n super.layoutSubviews()\n \n const bounds = this.contentBounds\n this.tableView.frame = bounds\n this._updateFullHeightView()\n \n }\n \n \n}\n\n\n\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,mCAA0D;AAC1D,qBAAwB;AACxB,sBAAoC;AAEpC,yBAA4B;AAC5B,oBAAuB;AAGhB,MAAM,mCAAsC,qBAAO;AAAA,EAgBtD,YAAY,WAAoB;AAE5B,UAAM,SAAS;AAbnB,0BAA0C,CAAC;AAC3C,wBAAyB,CAAC;AAC1B,gCAA+B;AAC/B,sBAAqB;AACrB,2BAA0B;AAC1B,oCAAoC;AACpC,mCAAmC;AAS/B,SAAK,SAAS;AACd,SAAK,yBAAyB;AAE9B,SAAK,kBAAkB,uBAAQ;AAC/B,SAAK,UAAU,GAAG,CAAC;AACnB,SAAK,MAAM,YAAY;AAEvB,SAAK,YAAY,IAAI,+BAAY,YAAY,YAAY,cAAc,MAAS;AAChF,SAAK,WAAW,KAAK,SAAS;
|
|
4
|
+
"sourcesContent": ["// noinspection JSConstantReassignment\n\nimport { UIAutocompleteItem, UIAutocompleteRowView } from \"./UIAutocompleteRowView\"\nimport { UIColor } from \"./UIColor\"\nimport { IS, IS_NOT, NO, YES } from \"./UIObject\"\nimport { UIRectangle } from \"./UIRectangle\"\nimport { UITableView } from \"./UITableView\"\nimport { UIView } from \"./UIView\"\n\n\nexport class UIAutocompleteDropdownView<T> extends UIView {\n \n tableView: UITableView\n _fullHeightView: UIView\n \n _filteredItems: UIAutocompleteItem<T>[] = []\n _filterWords: string[] = []\n _highlightedRowIndex: number = -1\n _rowHeight: number = 36\n _maxVisibleRows: number = 8\n _isPointerInsideDropdown: boolean = NO\n _suppressHoverHighlight: boolean = NO\n \n didSelectItem?: (item: UIAutocompleteItem<T>) => void\n anchorView?: UIView\n \n constructor(elementID?: string) {\n \n super(elementID)\n \n this.hidden = YES\n this.userInteractionEnabled = YES\n \n this.backgroundColor = UIColor.whiteColor\n this.setBorder(0, 1)\n this.style.boxSizing = \"content-box\"\n \n this.tableView = new UITableView(elementID ? elementID + \"TableView\" : undefined)\n this.addSubview(this.tableView)\n \n // Keyboard navigation and focus are owned by the text field, not the table.\n // Disabling it prevents the pointerdown handler from calling el.focus() and\n // stealing focus away from the text field when the user clicks a row.\n this.tableView.disablesKeyboardNavigation = YES\n \n this.tableView.allRowsHaveEqualHeight = YES\n this.tableView.numberOfRows = () => this._filteredItems.length\n this.tableView.heightForRowWithIndex = () => this._rowHeight\n this.tableView.newReusableViewForIdentifier = (identifier, rowIndex) => this.newRowView(identifier, rowIndex)\n this.tableView.viewForRowWithIndex = (index) => this.viewForRowWithIndex(index)\n \n // A transparent full-height view so the native scrollbar reflects the total\n // content height rather than just the virtualised visible rows.\n this._fullHeightView = new UIView(elementID ? elementID + \"FullHeightView\" : undefined)\n this._fullHeightView.userInteractionEnabled = NO\n this.tableView.addSubview(this._fullHeightView)\n \n // Use a native mousemove listener on the tableView element so we catch movement\n // regardless of which child row the pointer is over (framework events don't bubble\n // up through the scroll container from its row children).\n this.tableView.viewHTMLElement.addEventListener(\"mousemove\", () => {\n this._suppressHoverHighlight = NO\n })\n \n }\n \n \n /** Override in subclass to provide custom row views. */\n newRowView(identifier: string, rowIndex: number): UIAutocompleteRowView<T> {\n return new UIAutocompleteRowView<T>(this.elementID + identifier + rowIndex)\n }\n \n \n viewForRowWithIndex(index: number): UIView {\n \n const row = this.tableView.reusableViewForIdentifier(\n \"AutocompleteRow\",\n index\n ) as UIAutocompleteRowView<T>\n \n const item = this._filteredItems[index]\n if (IS(item)) {\n row.item = item\n }\n \n row.filterWords = this._filterWords\n \n // Reflect current keyboard highlight state via the native selected flag.\n row.selected = (index === this._highlightedRowIndex)\n \n // PointerHover fires as the pointer moves over the row.\n // We suppress scroll-into-view since the user is already looking at the row.\n // We also suppress highlight changes after a keyboard-triggered scroll, until\n // the pointer actually moves (PointerMove clears the suppression flag).\n const rowWasHovered = () => {\n if (this._suppressHoverHighlight) {\n return\n }\n this._setHighlightedRowIndex(index, NO)\n }\n if ((row as any)._autocompleteHoverHandler) {\n row.removeTargetForControlEvent(\n UIView.controlEvent.PointerHover,\n (row as any)._autocompleteHoverHandler\n )\n }\n row.controlEventTargetAccumulator.PointerHover = rowWasHovered;\n (row as any)._autocompleteHoverHandler = rowWasHovered\n \n // Clicking a row selects it.\n const rowWasTapped = () => {\n if (IS(item) && this.didSelectItem) {\n this.didSelectItem(item)\n }\n }\n if ((row as any)._autocompleteTapHandler) {\n row.removeTargetForControlEvent(\n UIView.controlEvent.PointerUpInside,\n (row as any)._autocompleteTapHandler\n )\n }\n row.controlEventTargetAccumulator.PointerUpInside = rowWasTapped;\n (row as any)._autocompleteTapHandler = rowWasTapped\n \n return row\n \n }\n \n \n get highlightedRowIndex(): number {\n return this._highlightedRowIndex\n }\n \n set highlightedRowIndex(index: number) {\n this._setHighlightedRowIndex(index, YES)\n }\n \n \n /** Internal setter. scrollIntoView=YES for keyboard navigation, NO for pointer hover. */\n _setHighlightedRowIndex(index: number, scrollIntoView: boolean) {\n \n const previousIndex = this._highlightedRowIndex\n this._highlightedRowIndex = index\n \n // Clear selected state on previous row.\n const previousRow = this.tableView.visibleRowWithIndex(previousIndex) as\n UIAutocompleteRowView<T> | undefined\n if (IS(previousRow)) {\n previousRow.selected = NO\n }\n \n // Set selected state on newly highlighted row.\n const currentRow = this.tableView.visibleRowWithIndex(index) as\n UIAutocompleteRowView<T> | undefined\n if (IS(currentRow)) {\n currentRow.selected = YES\n \n if (scrollIntoView) {\n // Scroll the view if needed\n let contentOffset = this.tableView.contentOffset\n if (currentRow.frame.y < contentOffset.y) {\n contentOffset.y = currentRow.frame.y\n }\n if (currentRow.frame.max.y > (contentOffset.y + this.tableView.bounds.height)) {\n contentOffset = contentOffset.pointByAddingY(-(contentOffset.y + this.tableView.bounds.height -\n currentRow.frame.max.y))\n }\n const animationDuration = this.tableView.animationDuration\n this.tableView.animationDuration = 0\n this.tableView.contentOffset = contentOffset\n this.tableView.animationDuration = animationDuration\n \n // Suppress hover-driven highlight changes until the user physically\n // moves the mouse \u2014 the native mousemove listener on the tableView\n // element clears this flag when actual movement is detected.\n this._suppressHoverHighlight = YES\n }\n }\n \n }\n \n \n get highlightedItem(): UIAutocompleteItem<T> | undefined {\n if (this._highlightedRowIndex >= 0 && this._highlightedRowIndex < this._filteredItems.length) {\n return this._filteredItems[this._highlightedRowIndex]\n }\n return undefined\n }\n \n \n set filteredItems(items: UIAutocompleteItem<T>[]) {\n this._filteredItems = items\n this._highlightedRowIndex = -1\n this.tableView.reloadData()\n this.hidden = (items.length === 0)\n this._updateFullHeightView()\n this.setNeedsLayout()\n }\n \n get filteredItems(): UIAutocompleteItem<T>[] {\n return this._filteredItems\n }\n \n \n set filterWords(words: string[]) {\n this._filterWords = words\n this.tableView.reloadData()\n }\n \n get filterWords(): string[] {\n return this._filterWords\n }\n \n \n /** Anchors this dropdown below the given field view inside the rootView. */\n showAnchoredToView(anchorView: UIView) {\n \n this.anchorView = anchorView\n \n this.calculateAndSetViewFrame = () => {\n \n const rootView = anchorView.rootView\n \n const padding = anchorView.core.paddingLength\n \n if (!this.superview || this.superview !== rootView) {\n this.removeFromSuperview()\n rootView.addSubview(this)\n }\n \n const fieldFrameInRoot = (this.anchorView?.superview?.rectangleInView(\n this.anchorView?.frame,\n rootView\n ) as UIRectangle)\n .rectangleByAddingX(padding)\n .rectangleByAddingY(padding)\n \n if (IS_NOT(fieldFrameInRoot)) {\n return\n }\n \n const dropdownHeight = Math.min(\n this._filteredItems.length * this._rowHeight,\n this._maxVisibleRows * this._rowHeight\n )\n \n \n this.frame = fieldFrameInRoot.rectangleForNextRow(0, dropdownHeight)\n \n }\n \n this.setNeedsLayoutUpToRootView()\n this.calculateAndSetViewFrame()\n \n this.style.zIndex = \"10000\"\n this.hidden = (this._filteredItems.length === 0)\n \n }\n \n \n dismiss() {\n this.hidden = YES\n this._highlightedRowIndex = -1\n this._isPointerInsideDropdown = NO\n }\n \n \n _updateFullHeightView() {\n const totalHeight = this._filteredItems.length * this._rowHeight\n this._fullHeightView.frame = this._fullHeightView.frame\n .rectangleWithY(0)\n .rectangleWithHeight(totalHeight)\n .rectangleWithWidth(1)\n this._fullHeightView.hasWeakFrame = YES\n }\n \n \n override layoutSubviews() {\n \n super.layoutSubviews()\n \n const bounds = this.contentBounds\n this.tableView.frame = bounds\n this._updateFullHeightView()\n \n }\n \n \n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -159,6 +159,9 @@ const _UIDialogView = class extends import_UIView.UIView {
|
|
|
159
159
|
if (event.name == import_UICore.UICore.broadcastEventName.WindowDidResize) {
|
|
160
160
|
this.setNeedsLayout();
|
|
161
161
|
}
|
|
162
|
+
if (event.name == import_UIView.UIView.broadcastEventName.PageDidScroll) {
|
|
163
|
+
this.setNeedsLayout();
|
|
164
|
+
}
|
|
162
165
|
}
|
|
163
166
|
layoutSubviews() {
|
|
164
167
|
var _a, _b, _c, _d;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../scripts/UIDialogView.ts"],
|
|
4
|
-
"sourcesContent": ["import { IS_FIREFOX } from \"./ClientCheckers\"\nimport { UIColor } from \"./UIColor\"\nimport { UICore } from \"./UICore\"\nimport { UINativeScrollView } from \"./UINativeScrollView\"\nimport { FIRST, IF, IS, nil, NO, YES } from \"./UIObject\"\nimport { UIScrollView } from \"./UIScrollView\"\nimport { UIView, UIViewBroadcastEvent } from \"./UIView\"\n\n\nexport class UIDialogView<ViewType extends UIView = UIView> extends UIView {\n \n _isAUIDialogView = YES\n _view: ViewType = new UIView() as any\n _appearedAnimated?: boolean\n animationDuration: number = 0.25\n _zIndex: number = 100\n isVisible: boolean = NO\n dismissesOnTapOutside = YES\n \n static _activeDialogCount = 0\n _fillsViewport = NO\n \n constructor(elementID?: string, viewHTMLElement?: HTMLElement) {\n \n super(elementID, viewHTMLElement)\n \n this.addSubview(this.view)\n \n this.addTargetForControlEvent(\n UIView.controlEvent.PointerTap,\n (sender: UIView, event: Event) => {\n \n this.didDetectTapOutside(sender, event)\n \n }\n )\n \n this.backgroundColor = UIColor.colorWithRGBA(0, 10, 25).colorWithAlpha(0.75) //CBColor.primaryContentColor.colorWithAlpha(0.75)\n \n this.zIndex = this._zIndex\n \n }\n \n \n didDetectTapOutside(sender: UIView, event: Event) {\n \n if (event.target == this.viewHTMLElement && this.dismissesOnTapOutside) {\n this.dismiss(this._appearedAnimated)\n }\n \n }\n \n \n set zIndex(zIndex: number) {\n \n this._zIndex = zIndex\n this.style.zIndex = \"\" + zIndex\n \n }\n \n get zIndex() {\n \n return this._zIndex\n \n }\n \n \n set view(view: ViewType) {\n \n this._view?.removeFromSuperview()\n \n this._view = view\n \n this.addSubview(view)\n \n }\n \n \n get view(): ViewType {\n \n return this._view\n \n }\n \n \n override willAppear(animated: boolean = NO) {\n \n if (animated) {\n \n this.style.opacity = \"0\"\n \n }\n \n this.style.height = \"\"\n \n this._frame = nil\n \n }\n \n \n animateAppearing() {\n \n this.style.opacity = \"1\"\n \n }\n \n animateDisappearing() {\n \n this.style.opacity = \"0\"\n \n }\n \n \n showInView(containerView: UIView, animated: boolean) {\n \n this._fillsViewport = containerView.rootView == containerView\n animated = (animated && !IS_FIREFOX)\n \n this._appearedAnimated = animated\n \n this.willAppear(animated)\n \n \n if (this._fillsViewport) {\n UIDialogView._activeDialogCount++\n if (UIDialogView._activeDialogCount >= 1) {\n document.body.style.overflow = \"hidden\"\n this.style.overflowY = \"auto\"\n }\n }\n \n containerView.addSubview(this)\n this.view.setNeedsLayoutUpToRootView()\n \n if (animated) {\n \n UIView.layoutViewsIfNeeded()\n this.layoutSubviews()\n \n UIView.animateViewOrViewsWithDurationDelayAndFunction(\n this,\n this.animationDuration,\n 0,\n undefined,\n () => this.animateAppearing(),\n nil\n )\n \n \n }\n else {\n \n this.setNeedsLayout()\n \n }\n \n this.isVisible = YES\n \n }\n \n \n showInRootView(animated: boolean) {\n \n this.showInView(UICore.main.rootViewController.view, animated)\n \n }\n \n \n dismiss(animated?: boolean) {\n \n if (!this.isVisible) {\n return\n }\n \n animated = (animated && !IS_FIREFOX)\n \n if (animated == undefined) {\n \n animated = this._appearedAnimated\n \n }\n \n const unlockScroll = () => {\n if (this._fillsViewport) {\n UIDialogView._activeDialogCount = Math.max(0, UIDialogView._activeDialogCount - 1)\n if (UIDialogView._activeDialogCount === 0) {\n document.body.style.overflow = \"\"\n }\n this.style.overflowY = \"\"\n }\n }\n \n if (animated) {\n \n UIView.animateViewOrViewsWithDurationDelayAndFunction(\n this,\n this.animationDuration,\n 0,\n undefined,\n (() => {\n \n this.animateDisappearing()\n \n }).bind(this),\n () => {\n \n if (this.isVisible == NO) {\n \n this.removeFromSuperview()\n unlockScroll()\n \n }\n \n }\n )\n \n }\n else {\n \n this.removeFromSuperview()\n unlockScroll()\n \n }\n \n this.isVisible = NO\n \n }\n \n \n override didReceiveBroadcastEvent(event: UIViewBroadcastEvent) {\n \n super.didReceiveBroadcastEvent(event)\n \n if (event.name == UICore.broadcastEventName.WindowDidResize) {\n \n this.setNeedsLayout()\n \n }\n \n }\n \n \n override layoutSubviews() {\n \n \n if (!IS(this.view)) {\n \n return\n \n }\n \n if (this._fillsViewport) {\n const containerRect = this.superview?.viewHTMLElement?.getBoundingClientRect()\n const topOffset = containerRect ? -containerRect.top / UIView.pageScale : 0\n this.setPosition(0, 0, 0, topOffset, window.innerHeight / UIView.pageScale, \"100%\")\n }\n else {\n this.setPosition(0, 0, 0, 0, 0, \"100%\")\n this.setPosition(\n 0,\n 0,\n 0,\n 0,\n FIRST(\n IF(this.superview?.isKindOfClass(UINativeScrollView))(() => this.superview?.scrollSize.height ?? 0)\n .ELSE_IF(this.superview?.isKindOfClass(UIScrollView))(\n () => this.superview?.scrollSize.height ?? 0)\n .ELSE(() => this.superview?.frame.height ?? 0),\n UIView.pageHeight\n ) / UIView.pageScale,\n \"100%\"\n )\n }\n \n this.view.style.zIndex = \"\" + this.zIndex\n \n this.view.setNeedsLayout()\n \n super.layoutSubviews()\n \n }\n \n \n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { IS_FIREFOX } from \"./ClientCheckers\"\nimport { UIColor } from \"./UIColor\"\nimport { UICore } from \"./UICore\"\nimport { UINativeScrollView } from \"./UINativeScrollView\"\nimport { FIRST, IF, IS, nil, NO, YES } from \"./UIObject\"\nimport { UIScrollView } from \"./UIScrollView\"\nimport { UIView, UIViewBroadcastEvent } from \"./UIView\"\n\n\nexport class UIDialogView<ViewType extends UIView = UIView> extends UIView {\n \n _isAUIDialogView = YES\n _view: ViewType = new UIView() as any\n _appearedAnimated?: boolean\n animationDuration: number = 0.25\n _zIndex: number = 100\n isVisible: boolean = NO\n dismissesOnTapOutside = YES\n \n static _activeDialogCount = 0\n _fillsViewport = NO\n \n constructor(elementID?: string, viewHTMLElement?: HTMLElement) {\n \n super(elementID, viewHTMLElement)\n \n this.addSubview(this.view)\n \n this.addTargetForControlEvent(\n UIView.controlEvent.PointerTap,\n (sender: UIView, event: Event) => {\n \n this.didDetectTapOutside(sender, event)\n \n }\n )\n \n this.backgroundColor = UIColor.colorWithRGBA(0, 10, 25).colorWithAlpha(0.75) //CBColor.primaryContentColor.colorWithAlpha(0.75)\n \n this.zIndex = this._zIndex\n \n }\n \n \n didDetectTapOutside(sender: UIView, event: Event) {\n \n if (event.target == this.viewHTMLElement && this.dismissesOnTapOutside) {\n this.dismiss(this._appearedAnimated)\n }\n \n }\n \n \n set zIndex(zIndex: number) {\n \n this._zIndex = zIndex\n this.style.zIndex = \"\" + zIndex\n \n }\n \n get zIndex() {\n \n return this._zIndex\n \n }\n \n \n set view(view: ViewType) {\n \n this._view?.removeFromSuperview()\n \n this._view = view\n \n this.addSubview(view)\n \n }\n \n \n get view(): ViewType {\n \n return this._view\n \n }\n \n \n override willAppear(animated: boolean = NO) {\n \n if (animated) {\n \n this.style.opacity = \"0\"\n \n }\n \n this.style.height = \"\"\n \n this._frame = nil\n \n }\n \n \n animateAppearing() {\n \n this.style.opacity = \"1\"\n \n }\n \n animateDisappearing() {\n \n this.style.opacity = \"0\"\n \n }\n \n \n showInView(containerView: UIView, animated: boolean) {\n \n this._fillsViewport = containerView.rootView == containerView\n animated = (animated && !IS_FIREFOX)\n \n this._appearedAnimated = animated\n \n this.willAppear(animated)\n \n \n if (this._fillsViewport) {\n UIDialogView._activeDialogCount++\n if (UIDialogView._activeDialogCount >= 1) {\n document.body.style.overflow = \"hidden\"\n this.style.overflowY = \"auto\"\n }\n }\n \n containerView.addSubview(this)\n this.view.setNeedsLayoutUpToRootView()\n \n if (animated) {\n \n UIView.layoutViewsIfNeeded()\n this.layoutSubviews()\n \n UIView.animateViewOrViewsWithDurationDelayAndFunction(\n this,\n this.animationDuration,\n 0,\n undefined,\n () => this.animateAppearing(),\n nil\n )\n \n \n }\n else {\n \n this.setNeedsLayout()\n \n }\n \n this.isVisible = YES\n \n }\n \n \n showInRootView(animated: boolean) {\n \n this.showInView(UICore.main.rootViewController.view, animated)\n \n }\n \n \n dismiss(animated?: boolean) {\n \n if (!this.isVisible) {\n return\n }\n \n animated = (animated && !IS_FIREFOX)\n \n if (animated == undefined) {\n \n animated = this._appearedAnimated\n \n }\n \n const unlockScroll = () => {\n if (this._fillsViewport) {\n UIDialogView._activeDialogCount = Math.max(0, UIDialogView._activeDialogCount - 1)\n if (UIDialogView._activeDialogCount === 0) {\n document.body.style.overflow = \"\"\n }\n this.style.overflowY = \"\"\n }\n }\n \n if (animated) {\n \n UIView.animateViewOrViewsWithDurationDelayAndFunction(\n this,\n this.animationDuration,\n 0,\n undefined,\n (() => {\n \n this.animateDisappearing()\n \n }).bind(this),\n () => {\n \n if (this.isVisible == NO) {\n \n this.removeFromSuperview()\n unlockScroll()\n \n }\n \n }\n )\n \n }\n else {\n \n this.removeFromSuperview()\n unlockScroll()\n \n }\n \n this.isVisible = NO\n \n }\n \n \n override didReceiveBroadcastEvent(event: UIViewBroadcastEvent) {\n \n super.didReceiveBroadcastEvent(event)\n \n if (event.name == UICore.broadcastEventName.WindowDidResize) {\n \n this.setNeedsLayout()\n \n }\n \n if (event.name == UIView.broadcastEventName.PageDidScroll) {\n \n this.setNeedsLayout()\n \n }\n \n }\n \n \n override layoutSubviews() {\n \n \n if (!IS(this.view)) {\n \n return\n \n }\n \n if (this._fillsViewport) {\n const containerRect = this.superview?.viewHTMLElement?.getBoundingClientRect()\n const topOffset = containerRect ? -containerRect.top / UIView.pageScale : 0\n this.setPosition(0, 0, 0, topOffset, window.innerHeight / UIView.pageScale, \"100%\")\n }\n else {\n this.setPosition(0, 0, 0, 0, 0, \"100%\")\n this.setPosition(\n 0,\n 0,\n 0,\n 0,\n FIRST(\n IF(this.superview?.isKindOfClass(UINativeScrollView))(() => this.superview?.scrollSize.height ?? 0)\n .ELSE_IF(this.superview?.isKindOfClass(UIScrollView))(\n () => this.superview?.scrollSize.height ?? 0)\n .ELSE(() => this.superview?.frame.height ?? 0),\n UIView.pageHeight\n ) / UIView.pageScale,\n \"100%\"\n )\n }\n \n this.view.style.zIndex = \"\" + this.zIndex\n \n this.view.setNeedsLayout()\n \n super.layoutSubviews()\n \n }\n \n \n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["_a", "_b"]
|
|
7
7
|
}
|
|
@@ -238,7 +238,7 @@ class UIRootViewController extends import_UIViewController.UIViewController {
|
|
|
238
238
|
topBarHeight = 65,
|
|
239
239
|
bottomBarMinHeight = 100
|
|
240
240
|
} = {}) {
|
|
241
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
241
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
242
242
|
const bounds = this.view.bounds;
|
|
243
243
|
if (this.topBarView) {
|
|
244
244
|
this.topBarView.frame = new import_UIRectangle.UIRectangle(0, 0, topBarHeight, bounds.width);
|
|
@@ -286,19 +286,25 @@ class UIRootViewController extends import_UIViewController.UIViewController {
|
|
|
286
286
|
this.detailsViewController.view.intrinsicContentWidth() || contentView.bounds.width,
|
|
287
287
|
contentView.bounds.width
|
|
288
288
|
);
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
0.5
|
|
294
|
-
).rectangleWithHeight(
|
|
295
|
-
Math.max(
|
|
296
|
-
this.detailsViewController.view.intrinsicContentHeight(
|
|
297
|
-
this.detailsViewController.view.bounds.width
|
|
298
|
-
),
|
|
299
|
-
contentView.bounds.height
|
|
300
|
-
)
|
|
289
|
+
const containerRect = this.view.viewHTMLElement.getBoundingClientRect();
|
|
290
|
+
const visibleTopBarHeight = Math.max(
|
|
291
|
+
0,
|
|
292
|
+
((_k = (_j = this.topBarView) == null ? void 0 : _j.frame.height) != null ? _k : 0) + containerRect.top / import_UIView.UIView.pageScale
|
|
301
293
|
);
|
|
294
|
+
const minimumTop = visibleTopBarHeight + paddingLength;
|
|
295
|
+
const viewportHeight = window.innerHeight / import_UIView.UIView.pageScale;
|
|
296
|
+
const viewportBelowTopBarCenterY = minimumTop + (viewportHeight - minimumTop) * 0.5;
|
|
297
|
+
const detailsHeight = Math.max(
|
|
298
|
+
this.detailsViewController.view.intrinsicContentHeight(
|
|
299
|
+
this.detailsViewController.view.bounds.width
|
|
300
|
+
),
|
|
301
|
+
contentView.bounds.height
|
|
302
|
+
);
|
|
303
|
+
let detailsFrame = this.backgroundView.frame.rectangleWithWidth(detailsWidth, 0.5).rectangleWithHeight(detailsHeight).rectangleWithY(viewportBelowTopBarCenterY, 0.5);
|
|
304
|
+
if (detailsFrame.y < minimumTop) {
|
|
305
|
+
detailsFrame = detailsFrame.rectangleWithY(minimumTop);
|
|
306
|
+
}
|
|
307
|
+
this.detailsViewController.view.frame = detailsFrame;
|
|
302
308
|
} else {
|
|
303
309
|
contentView.style.transform = "translateX(" + 0 + "px)";
|
|
304
310
|
}
|
|
@@ -309,7 +315,7 @@ class UIRootViewController extends import_UIViewController.UIViewController {
|
|
|
309
315
|
Math.max(bottomBarMinHeight, this.bottomBarView.intrinsicContentHeight(this.backgroundView.frame.width))
|
|
310
316
|
);
|
|
311
317
|
}
|
|
312
|
-
(0, import_UIObject.wrapInNil)(this._detailsDialogView).setMaxSizes((
|
|
318
|
+
(0, import_UIObject.wrapInNil)(this._detailsDialogView).setMaxSizes((_m = (_l = this.bottomBarView) == null ? void 0 : _l.frame.max.y) != null ? _m : 0);
|
|
313
319
|
}
|
|
314
320
|
}
|
|
315
321
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../scripts/UIRootViewController.ts"],
|
|
4
|
-
"sourcesContent": ["import { UIColor } from \"./UIColor\"\nimport { UICore } from \"./UICore\"\nimport { UIDialogView } from \"./UIDialogView\"\nimport { EXTEND, FIRST, FIRST_OR_NIL, IS, IS_NOT, LAZY_VALUE, nil, NO, UIObject, wrapInNil, YES } from \"./UIObject\"\nimport { UIRectangle } from \"./UIRectangle\"\nimport { UIRoute } from \"./UIRoute\"\nimport { UIView } from \"./UIView\"\nimport { UIViewController } from \"./UIViewController\"\n\n\nexport interface UIRootViewControllerLazyViewControllerObject<T extends typeof UIViewController> {\n instance: InstanceType<T>;\n class: T;\n shouldShow: () => (Promise<boolean> | boolean);\n isInitialized: boolean;\n deleteOnUnload: boolean;\n deleteOnLogout: boolean;\n /** Only applicable when the VC is registered in detailsViewControllers.\n * When YES, pressing Escape will dismiss the details dialog. */\n dismissesOnEscape: boolean;\n deleteInstance: () => void\n}\n\n\nexport interface UIRootViewControllerLazyViewControllersObject {\n [x: string]: UIRootViewControllerLazyViewControllerObject<typeof UIViewController>\n}\n\n\nexport interface UIRootViewControllerLazyContentViewControllersObject extends UIRootViewControllerLazyViewControllersObject {\n mainViewController: UIRootViewControllerLazyViewControllerObject<typeof UIViewController>\n}\n\n\nexport class UIRootViewController extends UIViewController {\n \n topBarView?: UIView\n backgroundView: UIView = new UIView(this.view.elementID + \"BackgroundView\").configuredWithObject({\n style: {\n background: \"linear-gradient(\" + UIColor.whiteColor.stringValue + \", \" + UIColor.blueColor.stringValue + \")\",\n backgroundSize: \"cover\",\n backgroundRepeat: \"no-repeat\"\n }\n })\n bottomBarView?: UIView\n \n _contentViewController?: UIViewController\n contentViewControllers: UIRootViewControllerLazyContentViewControllersObject = {\n mainViewController: this.lazyViewControllerObjectWithClass(UIViewController)\n }\n \n _detailsDialogView: UIDialogView = new UIDialogView(this.view.elementID + \"DetailsDialogView\")\n .configuredWithObject({\n dismiss: EXTEND(() => {\n let route = UIRoute.currentRoute\n this.detailsViewControllers.allValues.forEach(\n value => route = route.routeByRemovingComponentNamed(value.class.routeComponentName)\n )\n route.apply()\n }\n )\n })\n _detailsViewController?: UIViewController\n detailsViewControllers: UIRootViewControllerLazyViewControllersObject = {}\n \n \n constructor(view: UIView) {\n \n super(view)\n \n this.view.addSubview(this.backgroundView)\n \n }\n \n \n lazyViewControllerObjectWithClass<T extends typeof UIViewController>(\n classObject: T,\n options: {\n shouldShow?: () => (Promise<boolean> | boolean),\n deleteOnUnload?: boolean,\n deleteOnLogout?: boolean,\n /** Only applicable when the VC is registered in detailsViewControllers.\n * When YES, pressing Escape will dismiss the details dialog. */\n dismissesOnEscape?: boolean\n } = {}\n ): UIRootViewControllerLazyViewControllerObject<T> {\n const shouldShow = options.shouldShow ?? (() => YES)\n const deleteOnUnload = options.deleteOnUnload ?? NO\n const deleteOnLogout = options.deleteOnLogout ?? YES\n const dismissesOnEscape = options.dismissesOnEscape ?? NO\n \n const result: UIRootViewControllerLazyViewControllerObject<T> = {\n class: classObject,\n instance: nil,\n shouldShow: shouldShow,\n isInitialized: NO,\n deleteOnUnload: deleteOnUnload,\n deleteOnLogout: deleteOnLogout,\n dismissesOnEscape: dismissesOnEscape,\n deleteInstance: () => {\n if (result.isInitialized) {\n result.isInitialized = NO\n // Remove the view's DOM element before resetting the lazy value.\n // UIView reuses existing elements by ID, so if the element remains\n // in the DOM the next construction would attach a new controller\n // to the same stale element, causing duplicate subviews.\n const existingView = result.instance?.view\n if (existingView) {\n existingView.removeFromSuperview()\n existingView.viewHTMLElement.remove()\n }\n initializeLazyInstance()\n }\n }\n }\n \n const initializeLazyInstance = () => {\n UIObject.configureWithObject(result, {\n // @ts-ignore\n instance: LAZY_VALUE(\n () => {\n result.isInitialized = YES\n return new classObject(\n new UIView(classObject.name.replace(\"ViewController\", \"View\"))\n )\n }\n )\n })\n }\n \n initializeLazyInstance()\n \n return result\n }\n \n \n override async handleRoute(route: UIRoute) {\n \n await super.handleRoute(route)\n \n UICore.languageService.updateCurrentLanguageKey()\n \n // Show content view\n await this.setContentViewControllerForRoute(route)\n \n await this.setDetailsViewControllerForRoute(route)\n \n }\n \n \n async setContentViewControllerForRoute(route: UIRoute) {\n const contentViewControllerObject = FIRST(\n await this.contentViewControllers.allValues.findAsyncSequential(\n async value => IS(route.componentWithViewController(value.class)) && await value.shouldShow()\n ),\n this.contentViewControllers.mainViewController\n )\n \n // Delete old view controller if it has deleteOnUnload flag set\n if (IS(this._contentViewController) && this._contentViewController !== contentViewControllerObject.instance) {\n const oldViewControllerObject = this.contentViewControllers.allValues.find(\n value => value.isInitialized && value.instance === this._contentViewController\n )\n if (oldViewControllerObject?.deleteOnUnload) {\n oldViewControllerObject.deleteInstance()\n }\n }\n \n this.contentViewController = contentViewControllerObject.instance\n }\n \n async setDetailsViewControllerForRoute(route: UIRoute) {\n const detailsViewControllerObject = FIRST_OR_NIL(\n await this.detailsViewControllers.allValues.findAsyncSequential(\n async value => IS(route.componentWithViewController(value.class)) && await value.shouldShow()\n )\n )\n if (IS(route) && IS(this.detailsViewController) && IS_NOT(detailsViewControllerObject)) {\n // Delete old details view controller if it has deleteOnUnload flag set\n const oldViewControllerObject = this.detailsViewControllers.allValues.find(\n value => value.isInitialized && value.instance === this._detailsViewController\n )\n if (oldViewControllerObject?.deleteOnUnload) {\n oldViewControllerObject.deleteInstance()\n }\n \n this.detailsViewController = undefined\n this._detailsDialogView.dismiss()\n this.view.setNeedsLayout()\n return\n }\n \n // Delete old details view controller if it has deleteOnUnload flag set and is being replaced\n if (IS(this._detailsViewController) && this._detailsViewController !== detailsViewControllerObject?.instance) {\n const oldViewControllerObject = this.detailsViewControllers.allValues.find(\n value => value.isInitialized && value.instance === this._detailsViewController\n )\n if (oldViewControllerObject?.deleteOnUnload) {\n oldViewControllerObject.deleteInstance()\n }\n }\n \n this.detailsViewController = detailsViewControllerObject?.instance\n }\n \n get contentViewController(): UIViewController | undefined {\n return this._contentViewController\n }\n \n set contentViewController(controller: UIViewController) {\n \n if (this.contentViewController == controller) {\n return\n }\n \n if (this.contentViewController) {\n this.removeChildViewController(this.contentViewController)\n }\n \n this._contentViewController = controller\n this.addChildViewControllerInContainer(controller, this.backgroundView)\n this._triggerLayoutViewSubviews()\n \n if (this.contentViewController) {\n this.contentViewController.view.style.boxShadow = \"0 3px 6px 0 rgba(0, 0, 0, 0.1)\"\n }\n \n this.view.setNeedsLayout()\n \n }\n \n \n get detailsViewController(): UIViewController | undefined {\n return this._detailsViewController\n }\n \n set detailsViewController(controller: UIViewController | undefined) {\n \n if (this.detailsViewController == controller) {\n return\n }\n \n if (IS(this.detailsViewController)) {\n this.removeChildViewController(this.detailsViewController)\n }\n \n this._detailsViewController = controller\n \n if (!IS(controller)) {\n return\n }\n \n this.addChildViewControllerInDialogView(controller, this._detailsDialogView)\n this._triggerLayoutViewSubviews()\n \n FIRST_OR_NIL(this.detailsViewController).view.style.borderRadius = \"5px\"\n \n this._detailsDialogView.showInView(this.view, YES)\n \n }\n \n updatePageScale(\n {\n minScaleWidth = 700,\n maxScaleWidth = 1500,\n minScale = 0.7,\n maxScale = 1\n } = {}\n ) {\n const actualPageWidth = window.innerWidth ?? (UIView.pageWidth * UIView.pageScale).integerValue\n let scale = minScale + (maxScale - minScale) *\n ((actualPageWidth - minScaleWidth) / (maxScaleWidth - minScaleWidth))\n scale = Math.min(scale, maxScale)\n scale = Math.max(scale, minScale)\n UIView.pageScale = scale\n }\n \n \n performDefaultLayout(\n {\n paddingLength = 20,\n contentViewMaxWidth = 1000,\n topBarHeight = 65,\n bottomBarMinHeight = 100\n } = {}\n ) {\n \n // View bounds\n const bounds = this.view.bounds\n \n if (this.topBarView) {\n this.topBarView.frame = new UIRectangle(0, 0, topBarHeight, bounds.width)\n }\n \n this.backgroundView.style.top = \"\" + (this.topBarView?.frame.height.integerValue ?? 0) + \"px\"\n this.backgroundView.style.width = \"100%\"\n this.backgroundView.style.height = \"fit-content\"\n this.backgroundView.style.minHeight = \"\" +\n (bounds.height - (this.topBarView?.frame.height ?? 0) - (this.bottomBarView?.frame.height ?? 0)).integerValue + \"px\"\n \n const contentView: UIView = this.contentViewController?.view ?? nil\n \n //var contentViewStyleString = contentView.viewHTMLElement.style.cssText\n \n contentView.style.position = \"relative\"\n contentView.style.bottom = \"0\"\n contentView.style.top = \"0\"\n contentView.style.width = \"100%\"\n contentView.setPaddings(nil, nil, paddingLength, nil)\n \n \n if (contentViewMaxWidth < this.backgroundView.bounds.width) {\n \n contentView.style.marginBottom = \"\" +\n Math.min(\n (this.backgroundView.bounds.width - contentViewMaxWidth) * 0.5,\n paddingLength\n ).integerValue + \"px\"\n contentView.style.marginTop = \"\" +\n Math.min(\n (this.backgroundView.bounds.width - contentViewMaxWidth) * 0.5,\n paddingLength\n ).integerValue + \"px\"\n contentView.style.maxWidth = contentViewMaxWidth + \"px\"\n \n contentView.style.left = \"\" +\n ((this.backgroundView.bounds.width - contentView.bounds.width) * 0.5).integerValue +\n \"px\"\n \n }\n else {\n \n contentView.style.margin = \"\"\n contentView.style.left = \"\"\n contentView.style.maxWidth = \"\"\n \n }\n \n // if (contentViewStyleString != contentView.style.cssText) {\n //\n // contentView.setNeedsLayout()\n //\n // }\n \n \n \n // Triggering immediate layout to ensure that the intrinsicContentHeight calculations work well\n this.contentViewController?._triggerLayoutViewSubviews()\n \n let contentViewControllerViewHeight = contentView.intrinsicContentHeight(\n contentView.bounds.width\n )\n \n const detailsViewControllerViewHeight = FIRST_OR_NIL(this.detailsViewController).view.intrinsicContentHeight(\n contentView.bounds.width)\n if (detailsViewControllerViewHeight > contentViewControllerViewHeight) {\n contentViewControllerViewHeight = detailsViewControllerViewHeight\n }\n \n \n contentView.style.height = \"\" + contentViewControllerViewHeight.integerValue + \"px\"\n //contentView.setNeedsLayout()\n \n if (IS(this.detailsViewController)) {\n \n contentView.style.transform = \"translateX(\" + 0 + \"px)\"\n \n const detailsWidth = Math.min(\n this.detailsViewController.view.intrinsicContentWidth() || contentView.bounds.width,\n contentView.bounds.width\n )\n this.detailsViewController.view.frame = this.backgroundView.frame.rectangleWithInset(\n paddingLength\n ).rectangleWithWidth(\n detailsWidth,\n 0.5\n ).rectangleWithHeight(\n Math.max(\n this.detailsViewController.view.intrinsicContentHeight(\n this.detailsViewController.view.bounds.width\n ),\n contentView.bounds.height\n )\n )\n \n }\n else {\n \n contentView.style.transform = \"translateX(\" + 0 + \"px)\"\n \n }\n \n if (this.bottomBarView) {\n this.bottomBarView.frame = this.backgroundView.frame.rectangleWithY(\n this.backgroundView.frame.max.y\n ).rectangleWithHeight(\n Math.max(bottomBarMinHeight, this.bottomBarView.intrinsicContentHeight(this.backgroundView.frame.width))\n )\n }\n \n \n wrapInNil(this._detailsDialogView).setMaxSizes(this.bottomBarView?.frame.max.y ?? 0)\n \n }\n \n \n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { UIColor } from \"./UIColor\"\nimport { UICore } from \"./UICore\"\nimport { UIDialogView } from \"./UIDialogView\"\nimport { EXTEND, FIRST, FIRST_OR_NIL, IS, IS_NOT, LAZY_VALUE, nil, NO, UIObject, wrapInNil, YES } from \"./UIObject\"\nimport { UIRectangle } from \"./UIRectangle\"\nimport { UIRoute } from \"./UIRoute\"\nimport { UIView } from \"./UIView\"\nimport { UIViewController } from \"./UIViewController\"\n\n\nexport interface UIRootViewControllerLazyViewControllerObject<T extends typeof UIViewController> {\n instance: InstanceType<T>;\n class: T;\n shouldShow: () => (Promise<boolean> | boolean);\n isInitialized: boolean;\n deleteOnUnload: boolean;\n deleteOnLogout: boolean;\n /** Only applicable when the VC is registered in detailsViewControllers.\n * When YES, pressing Escape will dismiss the details dialog. */\n dismissesOnEscape: boolean;\n deleteInstance: () => void\n}\n\n\nexport interface UIRootViewControllerLazyViewControllersObject {\n [x: string]: UIRootViewControllerLazyViewControllerObject<typeof UIViewController>\n}\n\n\nexport interface UIRootViewControllerLazyContentViewControllersObject extends UIRootViewControllerLazyViewControllersObject {\n mainViewController: UIRootViewControllerLazyViewControllerObject<typeof UIViewController>\n}\n\n\nexport class UIRootViewController extends UIViewController {\n \n topBarView?: UIView\n backgroundView: UIView = new UIView(this.view.elementID + \"BackgroundView\").configuredWithObject({\n style: {\n background: \"linear-gradient(\" + UIColor.whiteColor.stringValue + \", \" + UIColor.blueColor.stringValue + \")\",\n backgroundSize: \"cover\",\n backgroundRepeat: \"no-repeat\"\n }\n })\n bottomBarView?: UIView\n \n _contentViewController?: UIViewController\n contentViewControllers: UIRootViewControllerLazyContentViewControllersObject = {\n mainViewController: this.lazyViewControllerObjectWithClass(UIViewController)\n }\n \n _detailsDialogView: UIDialogView = new UIDialogView(this.view.elementID + \"DetailsDialogView\")\n .configuredWithObject({\n dismiss: EXTEND(() => {\n let route = UIRoute.currentRoute\n this.detailsViewControllers.allValues.forEach(\n value => route = route.routeByRemovingComponentNamed(value.class.routeComponentName)\n )\n route.apply()\n }\n )\n })\n _detailsViewController?: UIViewController\n detailsViewControllers: UIRootViewControllerLazyViewControllersObject = {}\n \n \n constructor(view: UIView) {\n \n super(view)\n \n this.view.addSubview(this.backgroundView)\n \n }\n \n \n lazyViewControllerObjectWithClass<T extends typeof UIViewController>(\n classObject: T,\n options: {\n shouldShow?: () => (Promise<boolean> | boolean),\n deleteOnUnload?: boolean,\n deleteOnLogout?: boolean,\n /** Only applicable when the VC is registered in detailsViewControllers.\n * When YES, pressing Escape will dismiss the details dialog. */\n dismissesOnEscape?: boolean\n } = {}\n ): UIRootViewControllerLazyViewControllerObject<T> {\n const shouldShow = options.shouldShow ?? (() => YES)\n const deleteOnUnload = options.deleteOnUnload ?? NO\n const deleteOnLogout = options.deleteOnLogout ?? YES\n const dismissesOnEscape = options.dismissesOnEscape ?? NO\n \n const result: UIRootViewControllerLazyViewControllerObject<T> = {\n class: classObject,\n instance: nil,\n shouldShow: shouldShow,\n isInitialized: NO,\n deleteOnUnload: deleteOnUnload,\n deleteOnLogout: deleteOnLogout,\n dismissesOnEscape: dismissesOnEscape,\n deleteInstance: () => {\n if (result.isInitialized) {\n result.isInitialized = NO\n // Remove the view's DOM element before resetting the lazy value.\n // UIView reuses existing elements by ID, so if the element remains\n // in the DOM the next construction would attach a new controller\n // to the same stale element, causing duplicate subviews.\n const existingView = result.instance?.view\n if (existingView) {\n existingView.removeFromSuperview()\n existingView.viewHTMLElement.remove()\n }\n initializeLazyInstance()\n }\n }\n }\n \n const initializeLazyInstance = () => {\n UIObject.configureWithObject(result, {\n // @ts-ignore\n instance: LAZY_VALUE(\n () => {\n result.isInitialized = YES\n return new classObject(\n new UIView(classObject.name.replace(\"ViewController\", \"View\"))\n )\n }\n )\n })\n }\n \n initializeLazyInstance()\n \n return result\n }\n \n \n override async handleRoute(route: UIRoute) {\n \n await super.handleRoute(route)\n \n UICore.languageService.updateCurrentLanguageKey()\n \n // Show content view\n await this.setContentViewControllerForRoute(route)\n \n await this.setDetailsViewControllerForRoute(route)\n \n }\n \n \n async setContentViewControllerForRoute(route: UIRoute) {\n const contentViewControllerObject = FIRST(\n await this.contentViewControllers.allValues.findAsyncSequential(\n async value => IS(route.componentWithViewController(value.class)) && await value.shouldShow()\n ),\n this.contentViewControllers.mainViewController\n )\n \n // Delete old view controller if it has deleteOnUnload flag set\n if (IS(this._contentViewController) && this._contentViewController !== contentViewControllerObject.instance) {\n const oldViewControllerObject = this.contentViewControllers.allValues.find(\n value => value.isInitialized && value.instance === this._contentViewController\n )\n if (oldViewControllerObject?.deleteOnUnload) {\n oldViewControllerObject.deleteInstance()\n }\n }\n \n this.contentViewController = contentViewControllerObject.instance\n }\n \n async setDetailsViewControllerForRoute(route: UIRoute) {\n const detailsViewControllerObject = FIRST_OR_NIL(\n await this.detailsViewControllers.allValues.findAsyncSequential(\n async value => IS(route.componentWithViewController(value.class)) && await value.shouldShow()\n )\n )\n if (IS(route) && IS(this.detailsViewController) && IS_NOT(detailsViewControllerObject)) {\n // Delete old details view controller if it has deleteOnUnload flag set\n const oldViewControllerObject = this.detailsViewControllers.allValues.find(\n value => value.isInitialized && value.instance === this._detailsViewController\n )\n if (oldViewControllerObject?.deleteOnUnload) {\n oldViewControllerObject.deleteInstance()\n }\n \n this.detailsViewController = undefined\n this._detailsDialogView.dismiss()\n this.view.setNeedsLayout()\n return\n }\n \n // Delete old details view controller if it has deleteOnUnload flag set and is being replaced\n if (IS(this._detailsViewController) && this._detailsViewController !== detailsViewControllerObject?.instance) {\n const oldViewControllerObject = this.detailsViewControllers.allValues.find(\n value => value.isInitialized && value.instance === this._detailsViewController\n )\n if (oldViewControllerObject?.deleteOnUnload) {\n oldViewControllerObject.deleteInstance()\n }\n }\n \n this.detailsViewController = detailsViewControllerObject?.instance\n }\n \n get contentViewController(): UIViewController | undefined {\n return this._contentViewController\n }\n \n set contentViewController(controller: UIViewController) {\n \n if (this.contentViewController == controller) {\n return\n }\n \n if (this.contentViewController) {\n this.removeChildViewController(this.contentViewController)\n }\n \n this._contentViewController = controller\n this.addChildViewControllerInContainer(controller, this.backgroundView)\n this._triggerLayoutViewSubviews()\n \n if (this.contentViewController) {\n this.contentViewController.view.style.boxShadow = \"0 3px 6px 0 rgba(0, 0, 0, 0.1)\"\n }\n \n this.view.setNeedsLayout()\n \n }\n \n \n get detailsViewController(): UIViewController | undefined {\n return this._detailsViewController\n }\n \n set detailsViewController(controller: UIViewController | undefined) {\n \n if (this.detailsViewController == controller) {\n return\n }\n \n if (IS(this.detailsViewController)) {\n this.removeChildViewController(this.detailsViewController)\n }\n \n this._detailsViewController = controller\n \n if (!IS(controller)) {\n return\n }\n \n this.addChildViewControllerInDialogView(controller, this._detailsDialogView)\n this._triggerLayoutViewSubviews()\n \n FIRST_OR_NIL(this.detailsViewController).view.style.borderRadius = \"5px\"\n \n this._detailsDialogView.showInView(this.view, YES)\n \n }\n \n updatePageScale(\n {\n minScaleWidth = 700,\n maxScaleWidth = 1500,\n minScale = 0.7,\n maxScale = 1\n } = {}\n ) {\n const actualPageWidth = window.innerWidth ?? (UIView.pageWidth * UIView.pageScale).integerValue\n let scale = minScale + (maxScale - minScale) *\n ((actualPageWidth - minScaleWidth) / (maxScaleWidth - minScaleWidth))\n scale = Math.min(scale, maxScale)\n scale = Math.max(scale, minScale)\n UIView.pageScale = scale\n }\n \n \n performDefaultLayout(\n {\n paddingLength = 20,\n contentViewMaxWidth = 1000,\n topBarHeight = 65,\n bottomBarMinHeight = 100\n } = {}\n ) {\n \n // View bounds\n const bounds = this.view.bounds\n \n if (this.topBarView) {\n this.topBarView.frame = new UIRectangle(0, 0, topBarHeight, bounds.width)\n }\n \n this.backgroundView.style.top = \"\" + (this.topBarView?.frame.height.integerValue ?? 0) + \"px\"\n this.backgroundView.style.width = \"100%\"\n this.backgroundView.style.height = \"fit-content\"\n this.backgroundView.style.minHeight = \"\" +\n (bounds.height - (this.topBarView?.frame.height ?? 0) - (this.bottomBarView?.frame.height ?? 0)).integerValue + \"px\"\n \n const contentView: UIView = this.contentViewController?.view ?? nil\n \n //var contentViewStyleString = contentView.viewHTMLElement.style.cssText\n \n contentView.style.position = \"relative\"\n contentView.style.bottom = \"0\"\n contentView.style.top = \"0\"\n contentView.style.width = \"100%\"\n contentView.setPaddings(nil, nil, paddingLength, nil)\n \n \n if (contentViewMaxWidth < this.backgroundView.bounds.width) {\n \n contentView.style.marginBottom = \"\" +\n Math.min(\n (this.backgroundView.bounds.width - contentViewMaxWidth) * 0.5,\n paddingLength\n ).integerValue + \"px\"\n contentView.style.marginTop = \"\" +\n Math.min(\n (this.backgroundView.bounds.width - contentViewMaxWidth) * 0.5,\n paddingLength\n ).integerValue + \"px\"\n contentView.style.maxWidth = contentViewMaxWidth + \"px\"\n \n contentView.style.left = \"\" +\n ((this.backgroundView.bounds.width - contentView.bounds.width) * 0.5).integerValue +\n \"px\"\n \n }\n else {\n \n contentView.style.margin = \"\"\n contentView.style.left = \"\"\n contentView.style.maxWidth = \"\"\n \n }\n \n // if (contentViewStyleString != contentView.style.cssText) {\n //\n // contentView.setNeedsLayout()\n //\n // }\n \n \n \n // Triggering immediate layout to ensure that the intrinsicContentHeight calculations work well\n this.contentViewController?._triggerLayoutViewSubviews()\n \n let contentViewControllerViewHeight = contentView.intrinsicContentHeight(\n contentView.bounds.width\n )\n \n const detailsViewControllerViewHeight = FIRST_OR_NIL(this.detailsViewController).view.intrinsicContentHeight(\n contentView.bounds.width)\n if (detailsViewControllerViewHeight > contentViewControllerViewHeight) {\n contentViewControllerViewHeight = detailsViewControllerViewHeight\n }\n \n \n contentView.style.height = \"\" + contentViewControllerViewHeight.integerValue + \"px\"\n //contentView.setNeedsLayout()\n \n if (IS(this.detailsViewController)) {\n \n contentView.style.transform = \"translateX(\" + 0 + \"px)\"\n \n const detailsWidth = Math.min(\n this.detailsViewController.view.intrinsicContentWidth() || contentView.bounds.width,\n contentView.bounds.width\n )\n \n // _detailsDialogView fills the currently visible viewport and uses\n // viewport-relative local coordinates (its own y = 0 is \"top of the\n // visible viewport\", tracking scroll \u2014 see UIDialogView.layoutSubviews).\n // The dialog content is a subview of that backdrop, so its frame must\n // be computed in that same viewport-relative space, not in the page's\n // document coordinates that backgroundView.frame uses. Otherwise the\n // dialog's vertical position drifts further down the page the more\n // the user has scrolled before opening it.\n const containerRect = this.view.viewHTMLElement.getBoundingClientRect()\n const visibleTopBarHeight = Math.max(\n 0,\n (this.topBarView?.frame.height ?? 0) + containerRect.top / UIView.pageScale\n )\n const minimumTop = visibleTopBarHeight + paddingLength\n const viewportHeight = window.innerHeight / UIView.pageScale\n const viewportBelowTopBarCenterY = minimumTop + (viewportHeight - minimumTop) * 0.5\n \n const detailsHeight = Math.max(\n this.detailsViewController.view.intrinsicContentHeight(\n this.detailsViewController.view.bounds.width\n ),\n contentView.bounds.height\n )\n \n let detailsFrame = this.backgroundView.frame\n .rectangleWithWidth(detailsWidth, 0.5)\n .rectangleWithHeight(detailsHeight)\n .rectangleWithY(viewportBelowTopBarCenterY, 0.5)\n \n // If centering would place the dialog's top edge above the visible\n // top bar (or above the viewport entirely, on very short dialogs),\n // shift it down so it never overlaps or floats above that boundary.\n if (detailsFrame.y < minimumTop) {\n detailsFrame = detailsFrame.rectangleWithY(minimumTop)\n }\n \n this.detailsViewController.view.frame = detailsFrame\n \n }\n else {\n \n contentView.style.transform = \"translateX(\" + 0 + \"px)\"\n \n }\n \n if (this.bottomBarView) {\n this.bottomBarView.frame = this.backgroundView.frame.rectangleWithY(\n this.backgroundView.frame.max.y\n ).rectangleWithHeight(\n Math.max(bottomBarMinHeight, this.bottomBarView.intrinsicContentHeight(this.backgroundView.frame.width))\n )\n }\n \n \n wrapInNil(this._detailsDialogView).setMaxSizes(this.bottomBarView?.frame.max.y ?? 0)\n \n }\n \n \n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["_a"]
|
|
7
7
|
}
|
|
@@ -57,6 +57,13 @@ export declare class UITableView extends UINativeScrollView {
|
|
|
57
57
|
* encompasses both.
|
|
58
58
|
*/
|
|
59
59
|
_keyboardListenerElement: HTMLElement;
|
|
60
|
+
/**
|
|
61
|
+
* When YES, suppresses the grid ARIA role, tabIndex, and all keyboard/pointer
|
|
62
|
+
* focus listeners. Set this on table views that are controlled by an external
|
|
63
|
+
* focus owner (e.g. an autocomplete text field) so clicks inside the table
|
|
64
|
+
* never steal focus away from that owner.
|
|
65
|
+
*/
|
|
66
|
+
disablesKeyboardNavigation: boolean;
|
|
60
67
|
_setupGridAccessibility(): void;
|
|
61
68
|
/** Called by CBDataView after descriptors change. */
|
|
62
69
|
setColumnCount(count: number): void;
|
|
@@ -46,6 +46,7 @@ class UITableView extends import_UINativeScrollView.UINativeScrollView {
|
|
|
46
46
|
this._columnCount = 0;
|
|
47
47
|
this._keyboardListenersAttached = false;
|
|
48
48
|
this._keyboardListenerElement = this.viewHTMLElement;
|
|
49
|
+
this.disablesKeyboardNavigation = import_UIObject.NO;
|
|
49
50
|
this._windowScrollHandler = () => {
|
|
50
51
|
if (!this.isMemberOfViewTree) {
|
|
51
52
|
return;
|
|
@@ -87,6 +88,9 @@ class UITableView extends import_UINativeScrollView.UINativeScrollView {
|
|
|
87
88
|
return result;
|
|
88
89
|
}
|
|
89
90
|
_setupGridAccessibility() {
|
|
91
|
+
if (this.disablesKeyboardNavigation) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
90
94
|
const el = this._keyboardListenerElement;
|
|
91
95
|
el.setAttribute("role", "grid");
|
|
92
96
|
el.setAttribute("aria-rowcount", "0");
|
|
@@ -667,6 +671,9 @@ class UITableView extends import_UINativeScrollView.UINativeScrollView {
|
|
|
667
671
|
const el = this._keyboardListenerElement;
|
|
668
672
|
el.addEventListener("keydown", this._keydownHandler);
|
|
669
673
|
el.addEventListener("pointerdown", (event) => {
|
|
674
|
+
if (this.disablesKeyboardNavigation) {
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
670
677
|
const target = event.target;
|
|
671
678
|
if ((target == null ? void 0 : target.tagName) === "INPUT" || (target == null ? void 0 : target.tagName) === "TEXTAREA") {
|
|
672
679
|
return;
|
|
@@ -701,7 +708,9 @@ class UITableView extends import_UINativeScrollView.UINativeScrollView {
|
|
|
701
708
|
view.tabIndex = -1;
|
|
702
709
|
}
|
|
703
710
|
});
|
|
704
|
-
this.
|
|
711
|
+
if (!this.disablesKeyboardNavigation) {
|
|
712
|
+
this._keyboardListenerElement.tabIndex = 0;
|
|
713
|
+
}
|
|
705
714
|
}
|
|
706
715
|
setFrame(rectangle, zIndex, performUncheckedLayout) {
|
|
707
716
|
const frame = this.frame;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../scripts/UITableView.ts"],
|
|
4
|
-
"sourcesContent": ["import { UIButton } from \"./UIButton\"\nimport { UINativeScrollView } from \"./UINativeScrollView\"\nimport { EXTEND, FIRST_OR_NIL, IF, IS, IS_DEFINED, MAKE_ID, nil, NO, YES } from \"./UIObject\"\nimport { UIPoint } from \"./UIPoint\"\nimport { UIRectangle } from \"./UIRectangle\"\nimport { UIView, UIViewBroadcastEvent } from \"./UIView\"\n\n\ninterface UITableViewRowView extends UIView {\n \n _UITableViewRowIndex?: number;\n \n}\n\n\nexport interface UITableViewReusableViewsContainerObject {\n \n [key: string]: UIView[];\n \n}\n\n\nexport interface UITableViewReusableViewPositionObject {\n \n bottomY: number;\n topY: number;\n \n isValid: boolean;\n \n}\n\n\nexport class UITableView extends UINativeScrollView {\n \n \n allRowsHaveEqualHeight: boolean = NO\n _visibleRows: UITableViewRowView[] = []\n \n /** Shared intrinsic size cache identifier used for all row views when\n * allRowsHaveEqualHeight is YES. Stable for the lifetime of the table;\n * the shared cache bucket is invalidated on reloadData and\n * clearIntrinsicSizeCache so the height is re-measured after data changes. */\n _equalRowHeightCacheIdentifier: string\n \n _rowPositions: UITableViewReusableViewPositionObject[] = []\n \n _highestValidRowPositionIndex: number = 0\n \n _unusedReusableViews: UITableViewReusableViewsContainerObject = {}\n \n _fullHeightView: UIView\n _rowIDIndex: number = 0\n reloadsOnLanguageChange = YES\n sidePadding = 0\n \n cellWeights?: number[]\n \n _persistedData: any[] = []\n _needsDrawingOfVisibleRowsBeforeLayout = NO\n _isDrawVisibleRowsScheduled = NO\n _shouldAnimateNextLayout?: boolean\n \n override usesVirtualLayoutingForIntrinsicSizing = NO\n \n override animationDuration = 0.25\n \n // Viewport scrolling properties\n _intersectionObserver?: IntersectionObserver\n \n // -------------------------------------------------------------------------\n // Keyboard navigation state\n // -------------------------------------------------------------------------\n \n /** Row index with -1 meaning the header row. undefined means no focus. */\n _keyboardFocusedRowIndex: number | undefined = undefined\n /** Cell index within the focused row. */\n _keyboardFocusedCellIndex: number = 0\n /** Total number of data columns (excludes left/right side cells). Set by CBDataView. */\n _columnCount: number = 0\n /** Called by UITableView when the focused row/cell changes. CBDataView overrides this. */\n keyboardFocusDidChange?: (rowIndex: number | undefined, cellIndex: number) => void\n /** Fired when Enter is pressed on a focused cell. Passes rowIndex and cellIndex. */\n keyboardDidActivateCell?: (rowIndex: number, cellIndex: number) => void\n \n _keydownHandler?: (event: KeyboardEvent) => void\n _keyboardListenersAttached = false\n \n \n get _reusableViews(): UITableViewReusableViewsContainerObject {\n \n const result: UITableViewReusableViewsContainerObject = {}\n \n const addView = (view: UIView) => {\n const identifier = view._UITableViewReusabilityIdentifier\n if (!identifier) {\n return\n }\n if (!result[identifier]) {\n result[identifier] = []\n }\n result[identifier].push(view)\n }\n \n this._visibleRows.forEach(addView)\n \n this._unusedReusableViews.forEach((views: UIView[]) => views.forEach(addView))\n \n return result\n \n }\n \n \n constructor(elementID?: string) {\n \n super(elementID)\n \n this._equalRowHeightCacheIdentifier = (elementID ?? MAKE_ID()) + \"_rowHeight\"\n \n this._fullHeightView = new UIView()\n this._fullHeightView.hidden = YES\n this._fullHeightView.userInteractionEnabled = NO\n this.addSubview(this._fullHeightView)\n \n this.scrollsX = NO\n \n this._setupViewportScrollAndResizeHandlersIfNeeded()\n this._setupGridAccessibility()\n this._setupKeyboardNavigation()\n \n }\n \n \n // -------------------------------------------------------------------------\n // ARIA / Accessibility setup\n // -------------------------------------------------------------------------\n \n /**\n * The element that receives tabIndex, ARIA grid role, and all keyboard/pointer\n * listeners. Defaults to the table's own element. CBDataView overrides this\n * to a container that wraps both the header and the table, so the focus ring\n * encompasses both.\n */\n _keyboardListenerElement: HTMLElement = this.viewHTMLElement\n \n _setupGridAccessibility() {\n const el = this._keyboardListenerElement\n el.setAttribute(\"role\", \"grid\")\n el.setAttribute(\"aria-rowcount\", \"0\")\n el.setAttribute(\"aria-colcount\", \"0\")\n el.tabIndex = 0\n }\n \n /** Called by CBDataView after descriptors change. */\n setColumnCount(count: number) {\n this._columnCount = count\n this._keyboardListenerElement.setAttribute(\"aria-colcount\", String(count))\n }\n \n /** Called by CBDataView after data loads. */\n setRowCount(count: number) {\n this._keyboardListenerElement.setAttribute(\"aria-rowcount\", String(count))\n }\n \n \n // -------------------------------------------------------------------------\n // Keyboard navigation\n // -------------------------------------------------------------------------\n \n _setupKeyboardNavigation() {\n \n this._keydownHandler = (event: KeyboardEvent) => {\n \n if (!this.isMemberOfViewTree) {\n return\n }\n \n const target = event.target as HTMLElement\n if (target.tagName === \"INPUT\" || target.tagName === \"TEXTAREA\") {\n return\n }\n \n const rowCount = this.numberOfRows()\n const hasHeader = this._keyboardFocusedRowIndex !== undefined\n \n if (event.key === \"ArrowDown\") {\n event.preventDefault()\n if (this._keyboardFocusedRowIndex === undefined) {\n this._setKeyboardFocus(0, this._keyboardFocusedCellIndex)\n }\n else if (event.metaKey || event.ctrlKey) {\n this._setKeyboardFocus(rowCount - 1, this._keyboardFocusedCellIndex)\n }\n else if (event.altKey) {\n const pageSize = Math.max(1, Math.floor(this.bounds.height / (this._heightForAnyRow() || 50)))\n const next = Math.min(\n (this._keyboardFocusedRowIndex < 0 ? 0 : this._keyboardFocusedRowIndex) + pageSize,\n rowCount - 1\n )\n this._setKeyboardFocus(next, this._keyboardFocusedCellIndex)\n }\n else if (this._keyboardFocusedRowIndex === -1) {\n this._setKeyboardFocus(0, this._keyboardFocusedCellIndex)\n }\n else if (this._keyboardFocusedRowIndex < rowCount - 1) {\n this._setKeyboardFocus(this._keyboardFocusedRowIndex + 1, this._keyboardFocusedCellIndex)\n }\n }\n else if (event.key === \"ArrowUp\") {\n event.preventDefault()\n if (this._keyboardFocusedRowIndex === undefined) {\n this._setKeyboardFocus(rowCount - 1, this._keyboardFocusedCellIndex)\n }\n else if (event.metaKey || event.ctrlKey) {\n this._setKeyboardFocus(-1, this._keyboardFocusedCellIndex)\n }\n else if (event.altKey) {\n const pageSize = Math.max(1, Math.floor(this.bounds.height / (this._heightForAnyRow() || 50)))\n const prev = Math.max(\n (this._keyboardFocusedRowIndex < 0 ? 0 : this._keyboardFocusedRowIndex) - pageSize, -1)\n this._setKeyboardFocus(prev, this._keyboardFocusedCellIndex)\n }\n else if (this._keyboardFocusedRowIndex === 0) {\n this._setKeyboardFocus(-1, this._keyboardFocusedCellIndex)\n }\n else if (this._keyboardFocusedRowIndex > 0) {\n this._setKeyboardFocus(this._keyboardFocusedRowIndex - 1, this._keyboardFocusedCellIndex)\n }\n }\n else if (event.key === \"ArrowRight\") {\n event.preventDefault()\n if (this._keyboardFocusedRowIndex !== undefined && this._columnCount > 0) {\n const nextCell = event.metaKey || event.ctrlKey\n ? this._columnCount - 1\n : Math.min(this._keyboardFocusedCellIndex + 1, this._columnCount - 1)\n this._setKeyboardFocus(this._keyboardFocusedRowIndex, nextCell)\n }\n }\n else if (event.key === \"ArrowLeft\") {\n event.preventDefault()\n if (this._keyboardFocusedRowIndex !== undefined && this._columnCount > 0) {\n const prevCell = event.metaKey || event.ctrlKey\n ? 0\n : Math.max(this._keyboardFocusedCellIndex - 1, 0)\n this._setKeyboardFocus(this._keyboardFocusedRowIndex, prevCell)\n }\n }\n else if (event.key === \"Home\") {\n event.preventDefault()\n if (this._keyboardFocusedRowIndex !== undefined) {\n this._setKeyboardFocus(this._keyboardFocusedRowIndex, 0)\n }\n }\n else if (event.key === \"End\") {\n event.preventDefault()\n if (this._keyboardFocusedRowIndex !== undefined && this._columnCount > 0) {\n this._setKeyboardFocus(this._keyboardFocusedRowIndex, this._columnCount - 1)\n }\n }\n else if (event.key === \"PageDown\") {\n event.preventDefault()\n if (this._keyboardFocusedRowIndex !== undefined) {\n const pageSize = Math.max(1, Math.floor(this.bounds.height / (this._heightForAnyRow() || 50)))\n const next = Math.min(\n (this._keyboardFocusedRowIndex < 0 ? 0 : this._keyboardFocusedRowIndex) + pageSize,\n rowCount - 1\n )\n this._setKeyboardFocus(next, this._keyboardFocusedCellIndex)\n }\n }\n else if (event.key === \"PageUp\") {\n event.preventDefault()\n if (this._keyboardFocusedRowIndex !== undefined) {\n const pageSize = Math.max(1, Math.floor(this.bounds.height / (this._heightForAnyRow() || 50)))\n const prev = Math.max(\n (this._keyboardFocusedRowIndex < 0 ? 0 : this._keyboardFocusedRowIndex) - pageSize, -1)\n this._setKeyboardFocus(prev, this._keyboardFocusedCellIndex)\n }\n }\n else if (event.key === \"Enter\" || event.key === \" \") {\n if (this._keyboardFocusedRowIndex !== undefined && this._keyboardFocusedRowIndex >= 0) {\n event.preventDefault()\n this.keyboardDidActivateCell?.(this._keyboardFocusedRowIndex, this._keyboardFocusedCellIndex)\n }\n }\n else if (event.key === \"Escape\") {\n // Release focus from the table \u2014 move to next focusable element\n this._clearKeyboardFocus()\n this._keyboardListenerElement.blur()\n }\n \n }\n \n // Listeners are attached in wasAddedToViewTree to guarantee they land\n // on the final stable viewHTMLElement after the framework has fully\n // initialised the view.\n \n }\n \n /**\n * Move keyboard focus to a specific row and cell.\n * rowIndex = -1 means the header row.\n */\n _setKeyboardFocus(rowIndex: number, cellIndex: number) {\n \n const previousRowIndex = this._keyboardFocusedRowIndex\n const previousCellIndex = this._keyboardFocusedCellIndex\n \n // When moving to a different data row, land on the first button cell by default\n if (rowIndex >= 0 && rowIndex !== previousRowIndex) {\n const row = this.visibleRowWithIndex(rowIndex) as any\n if (row && typeof row.firstButtonCellIndex === \"function\") {\n cellIndex = row.firstButtonCellIndex()\n }\n }\n \n this._keyboardFocusedRowIndex = rowIndex\n this._keyboardFocusedCellIndex = cellIndex\n \n // Clear highlight from old position\n if (previousRowIndex !== undefined && previousRowIndex !== rowIndex) {\n this._clearKeyboardFocusOnRow(previousRowIndex)\n }\n else if (previousRowIndex === rowIndex && previousCellIndex !== cellIndex) {\n this._clearKeyboardFocusOnRow(rowIndex)\n }\n \n // Scroll the focused row into view if it is a data row\n if (rowIndex >= 0) {\n this._scrollRowIntoView(rowIndex)\n }\n \n // Apply highlight to new position\n this._applyKeyboardFocusToVisibleRows()\n \n // Notify observers (CBDataView uses this to sync header highlight)\n this.keyboardFocusDidChange?.(rowIndex, cellIndex)\n \n }\n \n _clearKeyboardFocus() {\n const previous = this._keyboardFocusedRowIndex\n this._keyboardFocusedRowIndex = undefined\n if (previous !== undefined) {\n this._clearKeyboardFocusOnRow(previous)\n }\n this.keyboardFocusDidChange?.(undefined, this._keyboardFocusedCellIndex)\n }\n \n _clearKeyboardFocusOnRow(rowIndex: number) {\n if (rowIndex === -1) {\n // Header \u2014 notify via callback; CBDataView handles the header view\n this.keyboardFocusDidChange?.(-1, -1)\n return\n }\n const row = this.visibleRowWithIndex(rowIndex) as any\n if (row && typeof row.setKeyboardFocusedCellIndex === \"function\") {\n row.setKeyboardFocusedCellIndex(undefined)\n }\n }\n \n _applyKeyboardFocusToVisibleRows(clearAll = false) {\n this._visibleRows.forEach((row: any) => {\n if (typeof row.setKeyboardFocusedCellIndex !== \"function\") {\n return\n }\n if (clearAll || row._UITableViewRowIndex !== this._keyboardFocusedRowIndex) {\n row.setKeyboardFocusedCellIndex(undefined)\n }\n else {\n row.setKeyboardFocusedCellIndex(this._keyboardFocusedCellIndex)\n }\n })\n }\n \n _scrollRowIntoView(rowIndex: number) {\n const position = this._rowPositionWithIndex(rowIndex)\n if (!position) {\n return\n }\n const offsetY = this.contentOffset.y\n const visibleHeight = this.bounds.height\n if (position.topY < offsetY) {\n const duration = this.animationDuration\n this.animationDuration = 0\n this.contentOffset = this.contentOffset.pointWithY(position.topY)\n this.animationDuration = duration\n }\n else if (position.bottomY > offsetY + visibleHeight) {\n const duration = this.animationDuration\n this.animationDuration = 0\n this.contentOffset = this.contentOffset.pointWithY(position.bottomY - visibleHeight)\n this.animationDuration = duration\n }\n }\n \n /** Expose so CBDataView can call it after loading data. */\n focusRowAtIndex(rowIndex: number, cellIndex: number = 0) {\n this._setKeyboardFocus(rowIndex, cellIndex)\n this._keyboardListenerElement.focus({ preventScroll: true })\n }\n \n \n _windowScrollHandler = () => {\n if (!this.isMemberOfViewTree) {\n return\n }\n this._scheduleDrawVisibleRows()\n }\n \n _resizeHandler = () => {\n if (!this.isMemberOfViewTree) {\n return\n }\n // Invalidate all row positions on resize as widths may have changed\n this._rowPositions.everyElement.isValid = NO\n this._highestValidRowPositionIndex = -1\n this._scheduleDrawVisibleRows()\n }\n \n _setupViewportScrollAndResizeHandlersIfNeeded() {\n if (this._intersectionObserver) {\n return\n }\n \n window.addEventListener(\"scroll\", this._windowScrollHandler, { passive: true })\n window.addEventListener(\"resize\", this._resizeHandler, { passive: true })\n \n // Use IntersectionObserver to detect when table enters/exits viewport\n this._intersectionObserver = new IntersectionObserver(\n (entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && this.isMemberOfViewTree) {\n this._scheduleDrawVisibleRows()\n }\n })\n },\n {\n root: null,\n rootMargin: \"100% 0px\", // Load rows 100% viewport height before/after\n threshold: 0\n }\n )\n this._intersectionObserver.observe(this.viewHTMLElement)\n }\n \n \n _cleanupViewportScrollListeners() {\n window.removeEventListener(\"scroll\", this._windowScrollHandler)\n window.removeEventListener(\"resize\", this._resizeHandler)\n if (this._intersectionObserver) {\n this._intersectionObserver.disconnect()\n this._intersectionObserver = undefined\n }\n }\n \n override wasRemovedFromViewTree() {\n super.wasRemovedFromViewTree()\n this._cleanupViewportScrollListeners()\n if (this._keydownHandler) {\n this.viewHTMLElement.removeEventListener(\"keydown\", this._keydownHandler)\n }\n // Reset so listeners are re-attached if added back to the tree\n this._keyboardListenersAttached = false\n }\n \n \n loadData() {\n \n this._persistedData = []\n \n this._calculatePositionsUntilIndex(this.numberOfRows() - 1)\n this._needsDrawingOfVisibleRowsBeforeLayout = YES\n \n this.setNeedsLayout()\n \n }\n \n reloadData() {\n \n this._removeVisibleRows()\n this._removeAllReusableRows()\n \n this._rowPositions = []\n this._highestValidRowPositionIndex = -1\n \n if (this.allRowsHaveEqualHeight) {\n UIView.invalidateSharedIntrinsicSizeCache(this._equalRowHeightCacheIdentifier)\n }\n \n this.loadData()\n \n }\n \n \n highlightChanges(previousData: any[], newData: any[]) {\n \n previousData = previousData.map(dataPoint => JSON.stringify(dataPoint))\n newData = newData.map(dataPoint => JSON.stringify(dataPoint))\n \n const newIndexes: number[] = []\n \n newData.forEach((value, index) => {\n \n if (!previousData.contains(value)) {\n \n newIndexes.push(index)\n \n }\n \n })\n \n newIndexes.forEach(index => {\n \n if (this.isRowWithIndexVisible(index)) {\n this.highlightRowAsNew(\n this.visibleRowWithIndex(index) ?? this.viewForRowWithIndex(index)\n )\n }\n \n })\n \n }\n \n \n highlightRowAsNew(row: UIView) {\n \n \n }\n \n \n invalidateSizeOfRowWithIndex(index: number, animateChange = NO) {\n if (this._rowPositions?.[index]) {\n FIRST_OR_NIL(this._rowPositions[index]).isValid = NO\n this._rowPositions.slice(index).everyElement.isValid = NO\n }\n this._highestValidRowPositionIndex = Math.min(this._highestValidRowPositionIndex, index - 1)\n this._needsDrawingOfVisibleRowsBeforeLayout = YES\n this._shouldAnimateNextLayout = animateChange\n }\n \n \n _rowPositionWithIndex(index: number, positions = this._rowPositions) {\n if (this.allRowsHaveEqualHeight && index > 0) {\n const firstPositionObject = positions[0]\n const rowHeight = firstPositionObject.bottomY - firstPositionObject.topY\n const result = {\n bottomY: rowHeight * (index + 1),\n topY: rowHeight * index,\n isValid: firstPositionObject.isValid\n }\n return result\n }\n return positions[index]\n }\n \n _calculateAllPositions() {\n this._calculatePositionsUntilIndex(this.numberOfRows() - 1)\n }\n \n _calculatePositionsUntilIndex(maxIndex: number) {\n \n if (this.allRowsHaveEqualHeight) {\n const positionObject: UITableViewReusableViewPositionObject = {\n bottomY: this._heightForAnyRow(),\n topY: 0,\n isValid: YES\n }\n this._rowPositions = [positionObject]\n return\n }\n \n let validPositionObject = this._rowPositions[this._highestValidRowPositionIndex]\n if (!IS(validPositionObject)) {\n validPositionObject = {\n bottomY: 0,\n topY: 0,\n isValid: YES\n }\n }\n \n let previousBottomY = validPositionObject.bottomY\n if (!this._rowPositions.length) {\n this._highestValidRowPositionIndex = -1\n }\n \n for (let i = this._highestValidRowPositionIndex + 1; i <= maxIndex; i++) {\n \n let height: number\n \n const rowPositionObject = this._rowPositions[i]\n \n if (IS((rowPositionObject || nil).isValid)) {\n height = rowPositionObject.bottomY - rowPositionObject.topY\n }\n // Do not calculate heights if all rows have equal heights, and we already have a height\n else if (this.allRowsHaveEqualHeight && i > 0) {\n height = this._rowPositions[0].bottomY - this._rowPositions[0].topY\n }\n else {\n height = this.heightForRowWithIndex(i)\n }\n \n const positionObject: UITableViewReusableViewPositionObject = {\n bottomY: previousBottomY + height,\n topY: previousBottomY,\n isValid: YES\n }\n \n if (i < this._rowPositions.length) {\n this._rowPositions[i] = positionObject\n }\n else {\n this._rowPositions.push(positionObject)\n }\n this._highestValidRowPositionIndex = i\n previousBottomY = previousBottomY + height\n \n }\n \n }\n \n \n _heightForAnyRow(calculateVisibleRows = YES) {\n return this.heightForRowWithIndex(\n this._visibleRows.firstElement?._UITableViewRowIndex ??\n (calculateVisibleRows ? this.indexesForVisibleRows().firstElement : 0) ??\n 0\n )\n }\n \n indexesForVisibleRows(paddingRatio = 0.5): number[] {\n \n // 1. Calculate the visible frame relative to the Table's bounds (0,0 is top-left of the table view)\n // This accounts for the Window viewport clipping the table if it is partially off-screen.\n const tableRect = this.viewHTMLElement.getBoundingClientRect()\n const viewportHeight = window.innerHeight\n const pageScale = UIView.pageScale\n \n // The top of the visible window relative to the view's top edge.\n // If tableRect.top is negative, the table is scrolled up and clipped by the window top.\n const visibleFrameTop = Math.max(0, -tableRect.top / pageScale)\n \n // The bottom of the visible window relative to the view's top edge.\n // We clip it to the table's actual bounds height so we don't look past the table content.\n const visibleFrameBottom = Math.min(\n this.bounds.height,\n (viewportHeight - tableRect.top) / pageScale\n )\n \n // If the table is completely off-screen, return empty\n if (visibleFrameBottom <= visibleFrameTop) {\n return []\n }\n \n // 2. Convert to Content Coordinates (Scroll Offset)\n // contentOffset.y is the internal scroll position.\n // If using viewport scrolling (full height), contentOffset.y is typically 0.\n // If using internal scrolling, this shifts the visible frame to the correct content rows.\n let firstVisibleY = this.contentOffset.y + visibleFrameTop\n let lastVisibleY = this.contentOffset.y + visibleFrameBottom\n \n // 3. Apply Padding\n // We calculate padding based on the viewport height to ensure smooth scrolling\n const paddingPx = (viewportHeight / pageScale) * paddingRatio\n firstVisibleY = Math.max(0, firstVisibleY - paddingPx)\n lastVisibleY = lastVisibleY + paddingPx\n \n const numberOfRows = this.numberOfRows()\n \n // 4. Find Indexes\n if (this.allRowsHaveEqualHeight) {\n \n const rowHeight = this._heightForAnyRow(NO)\n \n let firstIndex = Math.floor(firstVisibleY / rowHeight)\n let lastIndex = Math.floor(lastVisibleY / rowHeight)\n \n // Clamp BOTH indexes to [0, numberOfRows-1].\n // Without the upper clamp on firstIndex, when the viewport extends below the\n // last row firstIndex can exceed numberOfRows-1 while lastIndex is already\n // clamped there. firstIndex > lastIndex \u2192 empty result \u2192 _removeVisibleRows \u2192\n // browser collapses scrollHeight \u2192 scrollTop resets to 0 \u2192 rows pile at top.\n firstIndex = Math.max(0, Math.min(firstIndex, numberOfRows - 1))\n lastIndex = Math.max(0, Math.min(lastIndex, numberOfRows - 1))\n \n const result = []\n for (let i = firstIndex; i <= lastIndex; i++) {\n result.push(i)\n }\n return result\n }\n \n // Variable Heights\n this._calculateAllPositions()\n const result = []\n \n // Clamp firstVisibleY to the actual content height so that when the viewport\n // extends below the last row the intersection check still matches the final rows\n // rather than producing an empty result.\n const totalContentHeight = IF(this._rowPositions.lastElement)(() =>\n this._rowPositions.lastElement.bottomY\n ).ELSE(() =>\n 0\n )\n firstVisibleY = Math.min(firstVisibleY, totalContentHeight)\n \n for (let i = 0; i < numberOfRows; i++) {\n \n const position = this._rowPositionWithIndex(i)\n if (!position) {\n break\n }\n \n const rowTop = position.topY\n const rowBottom = position.bottomY\n \n // Check intersection\n if (rowBottom >= firstVisibleY && rowTop <= lastVisibleY) {\n result.push(i)\n }\n \n if (rowTop > lastVisibleY) {\n break\n }\n \n }\n \n return result\n \n }\n \n \n // This is called when no rows are supposed to be visible as a performance shortcut\n _removeVisibleRows() {\n \n this._visibleRows.forEach((row: UIView) => {\n \n this._persistedData[row._UITableViewRowIndex as number] = this.persistenceDataItemForRowWithIndex(\n row._UITableViewRowIndex as number,\n row\n )\n row.removeFromSuperview()\n this._markReusableViewAsUnused(row)\n \n })\n this._visibleRows = []\n \n }\n \n \n _removeAllReusableRows() {\n this._unusedReusableViews.forEach((rows: UIView[]) =>\n rows.forEach((row: UIView) => {\n \n this._persistedData[row._UITableViewRowIndex as number] = this.persistenceDataItemForRowWithIndex(\n row._UITableViewRowIndex as number,\n row\n )\n row.removeFromSuperview()\n \n })\n )\n this._unusedReusableViews = {}\n }\n \n \n _markReusableViewAsUnused(row: UIView) {\n const identifier = row._UITableViewReusabilityIdentifier\n if (!this._unusedReusableViews[identifier]) {\n this._unusedReusableViews[identifier] = []\n }\n if (!this._unusedReusableViews[identifier].contains(row)) {\n this._unusedReusableViews[identifier].push(row)\n }\n }\n \n _scheduleDrawVisibleRows() {\n if (!this._isDrawVisibleRowsScheduled) {\n this._isDrawVisibleRowsScheduled = YES\n \n UIView.runFunctionBeforeNextFrame(() => {\n this._calculateAllPositions()\n this._drawVisibleRows()\n this.setNeedsLayout()\n this._isDrawVisibleRowsScheduled = NO\n })\n }\n }\n \n _drawVisibleRows() {\n \n if (!this.isMemberOfViewTree) {\n return\n }\n \n // Uses the unified method above\n const visibleIndexes = this.indexesForVisibleRows()\n \n // If no rows are visible, remove all current rows\n if (visibleIndexes.length === 0) {\n this._removeVisibleRows()\n return\n }\n \n const minIndex = visibleIndexes[0]\n const maxIndex = visibleIndexes[visibleIndexes.length - 1]\n \n const removedViews: UITableViewRowView[] = []\n const visibleRows: UITableViewRowView[] = []\n \n // 1. Identify rows that have moved off-screen\n this._visibleRows.forEach((row) => {\n if (IS_DEFINED(row._UITableViewRowIndex) &&\n (row._UITableViewRowIndex < minIndex || row._UITableViewRowIndex > maxIndex)) {\n \n // Persist state before removal\n this._persistedData[row._UITableViewRowIndex] = this.persistenceDataItemForRowWithIndex(\n row._UITableViewRowIndex,\n row\n )\n this._markReusableViewAsUnused(row)\n removedViews.push(row)\n }\n else {\n visibleRows.push(row)\n }\n })\n \n this._visibleRows = visibleRows\n \n // 2. Add new rows that have moved onto the screen\n visibleIndexes.forEach((rowIndex: number) => {\n // If the view is already in this._visibleRows, do nothing to it\n if (this.isRowWithIndexVisible(rowIndex)) {\n return\n }\n \n // Get view from reuse pool (marked as unused before) or make a new one\n const view: UITableViewRowView = this.viewForRowWithIndex(rowIndex)\n this._visibleRows.push(view)\n this.addSubview(view)\n \n // Ensure the row and all its children stay out of the natural tab order\n view.tabIndex = -1\n view.forEachViewInSubtree(subview => {\n subview.tabIndex = -1\n })\n })\n \n // 3. Clean up DOM\n removedViews.forEach(row => {\n // Check that the row has not been added back\n if (this._visibleRows.indexOf(row) == -1) {\n row.removeFromSuperview()\n }\n })\n \n // 4. Re-apply keyboard focus highlight after rows are re-rendered\n this._applyKeyboardFocusToVisibleRows()\n \n }\n \n \n visibleRowWithIndex(rowIndex: number | undefined): UIView | undefined {\n for (let i = 0; i < this._visibleRows.length; i++) {\n const row = this._visibleRows[i]\n if (row._UITableViewRowIndex == rowIndex) {\n return row\n }\n }\n }\n \n \n isRowWithIndexVisible(rowIndex: number) {\n return IS(this.visibleRowWithIndex(rowIndex))\n }\n \n \n reusableViewForIdentifier(identifier: string, rowIndex: number): UITableViewRowView {\n \n const visibleRowView = this.visibleRowWithIndex(rowIndex)\n if (visibleRowView?._UITableViewReusabilityIdentifier === identifier) {\n return visibleRowView\n }\n \n if (!this._unusedReusableViews[identifier]) {\n this._unusedReusableViews[identifier] = []\n }\n \n let view: UITableViewRowView\n \n if (this._unusedReusableViews[identifier]?.length) {\n \n view = this._unusedReusableViews[identifier].pop() as UITableViewRowView\n view._UITableViewRowIndex = rowIndex\n Object.assign(view, this._persistedData[rowIndex] || this.defaultRowPersistenceDataItem())\n \n }\n else {\n \n view = this.newReusableViewForIdentifier(identifier, this._rowIDIndex) as UITableViewRowView\n this._rowIDIndex = this._rowIDIndex + 1\n \n view.configureWithObject({\n _UITableViewReusabilityIdentifier: identifier,\n _UITableViewRowIndex: rowIndex,\n \n // Extend clearIntrinsicSizeCache so that when the row (or any of its\n // subviews) invalidates its own size cache, the table is notified to\n // re-measure that specific row index. EXTEND preserves the original\n // implementation and appends this behaviour after it.\n clearIntrinsicSizeCache: EXTEND(() => {\n const currentRowIndex = view._UITableViewRowIndex\n if (IS_DEFINED(currentRowIndex) && view.isMemberOfViewTree) {\n this.invalidateSizeOfRowWithIndex(currentRowIndex)\n this.setNeedsLayout()\n }\n })\n })\n \n Object.assign(view, this._persistedData[rowIndex] || this.defaultRowPersistenceDataItem())\n \n }\n \n // When all rows are uniform, opt the view into the shared height cache so\n // only the first measurement is ever computed for the whole table.\n if (this.allRowsHaveEqualHeight) {\n view.sharedIntrinsicSizeCacheIdentifier = this._equalRowHeightCacheIdentifier\n }\n else {\n view.sharedIntrinsicSizeCacheIdentifier = undefined\n }\n \n return view\n \n }\n \n \n // Functions that should be overridden to draw the correct content START\n newReusableViewForIdentifier(identifier: string, rowIDIndex: number): UIView {\n \n const view = new UIButton(this.elementID + \"Row\" + rowIDIndex)\n \n view.stopsPointerEventPropagation = NO\n view.pausesPointerEvents = NO\n \n return view\n \n }\n \n heightForRowWithIndex(index: number): number {\n return 50\n }\n \n numberOfRows() {\n return 10000\n }\n \n defaultRowPersistenceDataItem(): any {\n \n \n }\n \n persistenceDataItemForRowWithIndex(rowIndex: number, row: UIView): any {\n \n \n }\n \n viewForRowWithIndex(rowIndex: number): UITableViewRowView {\n const row = this.reusableViewForIdentifier(\"Row\", rowIndex)\n row._UITableViewRowIndex = rowIndex\n FIRST_OR_NIL((row as unknown as UIButton).titleLabel).text = \"Row \" + rowIndex\n return row\n }\n \n // Functions that should be overridden to draw the correct content END\n \n \n // Functions that trigger redrawing of the content\n override didScrollToPosition(offsetPosition: UIPoint) {\n \n super.didScrollToPosition(offsetPosition)\n \n this.forEachViewInSubtree((view: UIView) => {\n view._isPointerValid = NO\n })\n \n this._scheduleDrawVisibleRows()\n \n }\n \n override willMoveToSuperview(superview: UIView) {\n super.willMoveToSuperview(superview)\n \n if (IS(superview)) {\n // Set up viewport listeners when added to a superview\n this._setupViewportScrollAndResizeHandlersIfNeeded()\n }\n else {\n // Clean up when removed from superview\n this._cleanupViewportScrollListeners()\n }\n }\n \n override wasAddedToViewTree() {\n super.wasAddedToViewTree()\n this.loadData()\n \n // Ensure listeners are set up\n this._setupViewportScrollAndResizeHandlersIfNeeded()\n \n // Attach keyboard and pointer listeners now that the element is stable\n // in the DOM. Guarded so repeated wasAddedToViewTree calls (e.g. after\n // navigation returns) don't stack duplicate listeners.\n if (!this._keyboardListenersAttached) {\n this._keyboardListenersAttached = true\n const el = this._keyboardListenerElement\n \n el.addEventListener(\"keydown\", this._keydownHandler!)\n \n el.addEventListener(\"pointerdown\", (event: PointerEvent) => {\n const target = event.target as HTMLElement | null\n if (target?.tagName === \"INPUT\" || target?.tagName === \"TEXTAREA\") {\n return\n }\n let walkedTarget = target\n while (walkedTarget && walkedTarget !== el) {\n const viewObject = (walkedTarget as any).UIViewObject as UITableViewRowView | undefined\n if (viewObject?._UITableViewRowIndex !== undefined) {\n this._setKeyboardFocus(viewObject._UITableViewRowIndex, this._keyboardFocusedCellIndex)\n el.focus({ preventScroll: true })\n return\n }\n walkedTarget = walkedTarget.parentElement\n }\n el.focus({ preventScroll: true })\n })\n \n el.addEventListener(\"focus\", () => {\n if (this._keyboardFocusedRowIndex === undefined && this.numberOfRows() > 0) {\n this._setKeyboardFocus(0, this._keyboardFocusedCellIndex)\n }\n else if (this._keyboardFocusedRowIndex !== undefined) {\n this._applyKeyboardFocusToVisibleRows()\n }\n })\n \n el.addEventListener(\"blur\", (event: FocusEvent) => {\n if (!el.contains(event.relatedTarget as Node)) {\n this._applyKeyboardFocusToVisibleRows(true)\n }\n })\n }\n \n // Remove all subviews from the browser's natural tab order.\n // The container (_keyboardListenerElement) is the single tab stop.\n // Internal navigation is handled exclusively via arrow keys.\n this.forEachViewInSubtree(view => {\n if (view !== this) {\n view.tabIndex = -1\n }\n })\n // Re-assert tabIndex=0 on the listener element \u2014 wasAddedToViewTree fires\n // on every tree insertion including navigation returns.\n this._keyboardListenerElement.tabIndex = 0\n \n }\n \n override setFrame(rectangle: UIRectangle, zIndex?: number, performUncheckedLayout?: boolean) {\n \n const frame = this.frame\n super.setFrame(rectangle, zIndex, performUncheckedLayout)\n if (frame.isEqualTo(rectangle) && !performUncheckedLayout) {\n return\n }\n \n this._needsDrawingOfVisibleRowsBeforeLayout = YES\n \n }\n \n \n override didReceiveBroadcastEvent(event: UIViewBroadcastEvent) {\n \n super.didReceiveBroadcastEvent(event)\n \n if (event.name == UIView.broadcastEventName.LanguageChanged && this.reloadsOnLanguageChange) {\n \n this.reloadData()\n \n }\n \n \n }\n \n \n override clearIntrinsicSizeCache() {\n super.clearIntrinsicSizeCache()\n if (this.allRowsHaveEqualHeight) {\n UIView.invalidateSharedIntrinsicSizeCache(this._equalRowHeightCacheIdentifier)\n }\n this.invalidateSizeOfRowWithIndex(0)\n }\n \n private _layoutAllRows(positions = this._rowPositions) {\n \n const bounds = this.bounds\n \n const sortedRows = this._visibleRows.sort(\n (rowA, rowB) => rowA._UITableViewRowIndex! - rowB._UITableViewRowIndex!\n )\n \n sortedRows.forEach((row, i) => {\n \n const frame = bounds.copy()\n \n const positionObject = this._rowPositionWithIndex(row._UITableViewRowIndex!, positions)\n frame.min.y = positionObject.topY\n frame.max.y = positionObject.bottomY\n row.frame = frame\n \n row.style.width = \"\" + (bounds.width - this.sidePadding * 2).integerValue + \"px\"\n row.style.left = \"\" + this.sidePadding.integerValue + \"px\"\n \n // Set aria-rowindex (1-based per ARIA spec)\n row.viewHTMLElement.setAttribute(\"aria-rowindex\", String((row._UITableViewRowIndex ?? 0) + 1))\n \n // Insert before the correct next sibling so DOM order always matches\n // row index order. The nextSibling check makes this a no-op when the\n // element is already in the right position, avoiding unnecessary DOM\n // mutations and the focus loss that appendChild causes.\n const nextSiblingElement = sortedRows[i + 1]?.viewHTMLElement\n ?? this._fullHeightView.viewHTMLElement\n if (row.viewHTMLElement.nextSibling !== nextSiblingElement) {\n this.viewHTMLElement.insertBefore(row.viewHTMLElement, nextSiblingElement)\n }\n \n })\n \n // Use _rowPositionWithIndex rather than positions.lastElement.\n // When allRowsHaveEqualHeight = YES, _rowPositions contains only a single\n // entry (row 0). positions.lastElement.bottomY would therefore equal just\n // ONE row's height (e.g. 50px) instead of the full content height.\n // _rowPositionWithIndex correctly uses the computed formula for equal-height\n // tables (numberOfRows \u00D7 rowHeight) and falls back to positions[N-1] otherwise.\n // This ensures _fullHeightView maintains the correct scroll height even when\n // all visible rows have been removed from the DOM (e.g. after crossing the\n // bottom edge), preventing the browser from clamping scrollTop to 0.\n const numberOfRows = this.numberOfRows()\n const fullContentHeight = numberOfRows\n ? this._rowPositionWithIndex(numberOfRows - 1, positions).bottomY\n : 0\n this._fullHeightView.frame = bounds.rectangleWithHeight(fullContentHeight)\n .rectangleWithWidth(bounds.width * 0.5)\n \n }\n \n private _animateLayoutAllRows() {\n \n UIView.animateViewOrViewsWithDurationDelayAndFunction(\n this._visibleRows,\n this.animationDuration,\n 0,\n undefined,\n () => {\n \n this._layoutAllRows()\n \n },\n () => {\n \n \n }\n )\n \n }\n \n // UITableView has usesVirtualLayoutingForIntrinsicSizing = NO and is always\n // given a fixed viewport frame by its parent \u2014 so frame.height never changes\n // between layout passes. The base didLayoutSubviews compares frame.height and\n // therefore never propagates upward, even when row positions have changed and\n // intrinsicContentHeight now returns a different value.\n // We override here to track the intrinsic content height instead, so that\n // parents (e.g. CBDataView) get their cache invalidated and re-layout whenever\n // the total row stack height changes.\n override didLayoutSubviews() {\n this.viewController?.viewDidLayoutSubviews()\n \n if (!this.isVirtualLayouting && IS(this.superview) && this.isMemberOfViewTree) {\n const currentContentHeight = this.intrinsicContentHeight()\n if (currentContentHeight !== this._lastReportedHeight) {\n this._lastReportedHeight = currentContentHeight\n this.clearIntrinsicSizeCache()\n this.superview.setNeedsLayout()\n }\n }\n }\n \n \n override layoutSubviews() {\n \n if (this.isVirtualLayouting) {\n console.error(\"layout subviews called during virtual layouting on UITableView, \" +\n \"indicating a possible error in the layout system.\")\n return\n }\n \n const previousPositions: UITableViewReusableViewPositionObject[] = JSON.parse(\n JSON.stringify(this._rowPositions))\n \n const previousVisibleRowsLength = this._visibleRows.length\n \n if (this._needsDrawingOfVisibleRowsBeforeLayout) {\n \n this._drawVisibleRows()\n \n this._needsDrawingOfVisibleRowsBeforeLayout = NO\n \n }\n \n \n super.layoutSubviews()\n \n \n if (!this.numberOfRows() || !this.isMemberOfViewTree) {\n \n return\n \n }\n \n \n if (this._shouldAnimateNextLayout) {\n \n \n // Need to do layout with the previous positions\n \n this._layoutAllRows(previousPositions)\n \n \n if (previousVisibleRowsLength < this._visibleRows.length) {\n \n \n UIView.runFunctionBeforeNextFrame(() => {\n \n this._animateLayoutAllRows()\n \n })\n \n }\n else {\n \n this._animateLayoutAllRows()\n \n }\n \n \n this._shouldAnimateNextLayout = NO\n \n }\n else {\n \n this._calculateAllPositions()\n \n this._layoutAllRows()\n \n \n }\n \n \n }\n \n \n override intrinsicContentHeight(constrainingWidth = 0) {\n \n let result = 0\n this._calculateAllPositions()\n \n const numberOfRows = this.numberOfRows()\n if (numberOfRows) {\n result = this._rowPositionWithIndex(numberOfRows - 1).bottomY\n }\n \n return result\n \n }\n \n \n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { UIButton } from \"./UIButton\"\nimport { UINativeScrollView } from \"./UINativeScrollView\"\nimport { EXTEND, FIRST_OR_NIL, IF, IS, IS_DEFINED, MAKE_ID, nil, NO, YES } from \"./UIObject\"\nimport { UIPoint } from \"./UIPoint\"\nimport { UIRectangle } from \"./UIRectangle\"\nimport { UIView, UIViewBroadcastEvent } from \"./UIView\"\n\n\ninterface UITableViewRowView extends UIView {\n \n _UITableViewRowIndex?: number;\n \n}\n\n\nexport interface UITableViewReusableViewsContainerObject {\n \n [key: string]: UIView[];\n \n}\n\n\nexport interface UITableViewReusableViewPositionObject {\n \n bottomY: number;\n topY: number;\n \n isValid: boolean;\n \n}\n\n\nexport class UITableView extends UINativeScrollView {\n \n \n allRowsHaveEqualHeight: boolean = NO\n _visibleRows: UITableViewRowView[] = []\n \n /** Shared intrinsic size cache identifier used for all row views when\n * allRowsHaveEqualHeight is YES. Stable for the lifetime of the table;\n * the shared cache bucket is invalidated on reloadData and\n * clearIntrinsicSizeCache so the height is re-measured after data changes. */\n _equalRowHeightCacheIdentifier: string\n \n _rowPositions: UITableViewReusableViewPositionObject[] = []\n \n _highestValidRowPositionIndex: number = 0\n \n _unusedReusableViews: UITableViewReusableViewsContainerObject = {}\n \n _fullHeightView: UIView\n _rowIDIndex: number = 0\n reloadsOnLanguageChange = YES\n sidePadding = 0\n \n cellWeights?: number[]\n \n _persistedData: any[] = []\n _needsDrawingOfVisibleRowsBeforeLayout = NO\n _isDrawVisibleRowsScheduled = NO\n _shouldAnimateNextLayout?: boolean\n \n override usesVirtualLayoutingForIntrinsicSizing = NO\n \n override animationDuration = 0.25\n \n // Viewport scrolling properties\n _intersectionObserver?: IntersectionObserver\n \n // -------------------------------------------------------------------------\n // Keyboard navigation state\n // -------------------------------------------------------------------------\n \n /** Row index with -1 meaning the header row. undefined means no focus. */\n _keyboardFocusedRowIndex: number | undefined = undefined\n /** Cell index within the focused row. */\n _keyboardFocusedCellIndex: number = 0\n /** Total number of data columns (excludes left/right side cells). Set by CBDataView. */\n _columnCount: number = 0\n /** Called by UITableView when the focused row/cell changes. CBDataView overrides this. */\n keyboardFocusDidChange?: (rowIndex: number | undefined, cellIndex: number) => void\n /** Fired when Enter is pressed on a focused cell. Passes rowIndex and cellIndex. */\n keyboardDidActivateCell?: (rowIndex: number, cellIndex: number) => void\n \n _keydownHandler?: (event: KeyboardEvent) => void\n _keyboardListenersAttached = false\n \n \n get _reusableViews(): UITableViewReusableViewsContainerObject {\n \n const result: UITableViewReusableViewsContainerObject = {}\n \n const addView = (view: UIView) => {\n const identifier = view._UITableViewReusabilityIdentifier\n if (!identifier) {\n return\n }\n if (!result[identifier]) {\n result[identifier] = []\n }\n result[identifier].push(view)\n }\n \n this._visibleRows.forEach(addView)\n \n this._unusedReusableViews.forEach((views: UIView[]) => views.forEach(addView))\n \n return result\n \n }\n \n \n constructor(elementID?: string) {\n \n super(elementID)\n \n this._equalRowHeightCacheIdentifier = (elementID ?? MAKE_ID()) + \"_rowHeight\"\n \n this._fullHeightView = new UIView()\n this._fullHeightView.hidden = YES\n this._fullHeightView.userInteractionEnabled = NO\n this.addSubview(this._fullHeightView)\n \n this.scrollsX = NO\n \n this._setupViewportScrollAndResizeHandlersIfNeeded()\n this._setupGridAccessibility()\n this._setupKeyboardNavigation()\n \n }\n \n \n // -------------------------------------------------------------------------\n // ARIA / Accessibility setup\n // -------------------------------------------------------------------------\n \n /**\n * The element that receives tabIndex, ARIA grid role, and all keyboard/pointer\n * listeners. Defaults to the table's own element. CBDataView overrides this\n * to a container that wraps both the header and the table, so the focus ring\n * encompasses both.\n */\n _keyboardListenerElement: HTMLElement = this.viewHTMLElement\n \n /**\n * When YES, suppresses the grid ARIA role, tabIndex, and all keyboard/pointer\n * focus listeners. Set this on table views that are controlled by an external\n * focus owner (e.g. an autocomplete text field) so clicks inside the table\n * never steal focus away from that owner.\n */\n disablesKeyboardNavigation: boolean = NO\n \n _setupGridAccessibility() {\n if (this.disablesKeyboardNavigation) {\n return\n }\n const el = this._keyboardListenerElement\n el.setAttribute(\"role\", \"grid\")\n el.setAttribute(\"aria-rowcount\", \"0\")\n el.setAttribute(\"aria-colcount\", \"0\")\n el.tabIndex = 0\n }\n \n /** Called by CBDataView after descriptors change. */\n setColumnCount(count: number) {\n this._columnCount = count\n this._keyboardListenerElement.setAttribute(\"aria-colcount\", String(count))\n }\n \n /** Called by CBDataView after data loads. */\n setRowCount(count: number) {\n this._keyboardListenerElement.setAttribute(\"aria-rowcount\", String(count))\n }\n \n \n // -------------------------------------------------------------------------\n // Keyboard navigation\n // -------------------------------------------------------------------------\n \n _setupKeyboardNavigation() {\n \n this._keydownHandler = (event: KeyboardEvent) => {\n \n if (!this.isMemberOfViewTree) {\n return\n }\n \n const target = event.target as HTMLElement\n if (target.tagName === \"INPUT\" || target.tagName === \"TEXTAREA\") {\n return\n }\n \n const rowCount = this.numberOfRows()\n const hasHeader = this._keyboardFocusedRowIndex !== undefined\n \n if (event.key === \"ArrowDown\") {\n event.preventDefault()\n if (this._keyboardFocusedRowIndex === undefined) {\n this._setKeyboardFocus(0, this._keyboardFocusedCellIndex)\n }\n else if (event.metaKey || event.ctrlKey) {\n this._setKeyboardFocus(rowCount - 1, this._keyboardFocusedCellIndex)\n }\n else if (event.altKey) {\n const pageSize = Math.max(1, Math.floor(this.bounds.height / (this._heightForAnyRow() || 50)))\n const next = Math.min(\n (this._keyboardFocusedRowIndex < 0 ? 0 : this._keyboardFocusedRowIndex) + pageSize,\n rowCount - 1\n )\n this._setKeyboardFocus(next, this._keyboardFocusedCellIndex)\n }\n else if (this._keyboardFocusedRowIndex === -1) {\n this._setKeyboardFocus(0, this._keyboardFocusedCellIndex)\n }\n else if (this._keyboardFocusedRowIndex < rowCount - 1) {\n this._setKeyboardFocus(this._keyboardFocusedRowIndex + 1, this._keyboardFocusedCellIndex)\n }\n }\n else if (event.key === \"ArrowUp\") {\n event.preventDefault()\n if (this._keyboardFocusedRowIndex === undefined) {\n this._setKeyboardFocus(rowCount - 1, this._keyboardFocusedCellIndex)\n }\n else if (event.metaKey || event.ctrlKey) {\n this._setKeyboardFocus(-1, this._keyboardFocusedCellIndex)\n }\n else if (event.altKey) {\n const pageSize = Math.max(1, Math.floor(this.bounds.height / (this._heightForAnyRow() || 50)))\n const prev = Math.max(\n (this._keyboardFocusedRowIndex < 0 ? 0 : this._keyboardFocusedRowIndex) - pageSize, -1)\n this._setKeyboardFocus(prev, this._keyboardFocusedCellIndex)\n }\n else if (this._keyboardFocusedRowIndex === 0) {\n this._setKeyboardFocus(-1, this._keyboardFocusedCellIndex)\n }\n else if (this._keyboardFocusedRowIndex > 0) {\n this._setKeyboardFocus(this._keyboardFocusedRowIndex - 1, this._keyboardFocusedCellIndex)\n }\n }\n else if (event.key === \"ArrowRight\") {\n event.preventDefault()\n if (this._keyboardFocusedRowIndex !== undefined && this._columnCount > 0) {\n const nextCell = event.metaKey || event.ctrlKey\n ? this._columnCount - 1\n : Math.min(this._keyboardFocusedCellIndex + 1, this._columnCount - 1)\n this._setKeyboardFocus(this._keyboardFocusedRowIndex, nextCell)\n }\n }\n else if (event.key === \"ArrowLeft\") {\n event.preventDefault()\n if (this._keyboardFocusedRowIndex !== undefined && this._columnCount > 0) {\n const prevCell = event.metaKey || event.ctrlKey\n ? 0\n : Math.max(this._keyboardFocusedCellIndex - 1, 0)\n this._setKeyboardFocus(this._keyboardFocusedRowIndex, prevCell)\n }\n }\n else if (event.key === \"Home\") {\n event.preventDefault()\n if (this._keyboardFocusedRowIndex !== undefined) {\n this._setKeyboardFocus(this._keyboardFocusedRowIndex, 0)\n }\n }\n else if (event.key === \"End\") {\n event.preventDefault()\n if (this._keyboardFocusedRowIndex !== undefined && this._columnCount > 0) {\n this._setKeyboardFocus(this._keyboardFocusedRowIndex, this._columnCount - 1)\n }\n }\n else if (event.key === \"PageDown\") {\n event.preventDefault()\n if (this._keyboardFocusedRowIndex !== undefined) {\n const pageSize = Math.max(1, Math.floor(this.bounds.height / (this._heightForAnyRow() || 50)))\n const next = Math.min(\n (this._keyboardFocusedRowIndex < 0 ? 0 : this._keyboardFocusedRowIndex) + pageSize,\n rowCount - 1\n )\n this._setKeyboardFocus(next, this._keyboardFocusedCellIndex)\n }\n }\n else if (event.key === \"PageUp\") {\n event.preventDefault()\n if (this._keyboardFocusedRowIndex !== undefined) {\n const pageSize = Math.max(1, Math.floor(this.bounds.height / (this._heightForAnyRow() || 50)))\n const prev = Math.max(\n (this._keyboardFocusedRowIndex < 0 ? 0 : this._keyboardFocusedRowIndex) - pageSize, -1)\n this._setKeyboardFocus(prev, this._keyboardFocusedCellIndex)\n }\n }\n else if (event.key === \"Enter\" || event.key === \" \") {\n if (this._keyboardFocusedRowIndex !== undefined && this._keyboardFocusedRowIndex >= 0) {\n event.preventDefault()\n this.keyboardDidActivateCell?.(this._keyboardFocusedRowIndex, this._keyboardFocusedCellIndex)\n }\n }\n else if (event.key === \"Escape\") {\n // Release focus from the table \u2014 move to next focusable element\n this._clearKeyboardFocus()\n this._keyboardListenerElement.blur()\n }\n \n }\n \n // Listeners are attached in wasAddedToViewTree to guarantee they land\n // on the final stable viewHTMLElement after the framework has fully\n // initialised the view.\n \n }\n \n /**\n * Move keyboard focus to a specific row and cell.\n * rowIndex = -1 means the header row.\n */\n _setKeyboardFocus(rowIndex: number, cellIndex: number) {\n \n const previousRowIndex = this._keyboardFocusedRowIndex\n const previousCellIndex = this._keyboardFocusedCellIndex\n \n // When moving to a different data row, land on the first button cell by default\n if (rowIndex >= 0 && rowIndex !== previousRowIndex) {\n const row = this.visibleRowWithIndex(rowIndex) as any\n if (row && typeof row.firstButtonCellIndex === \"function\") {\n cellIndex = row.firstButtonCellIndex()\n }\n }\n \n this._keyboardFocusedRowIndex = rowIndex\n this._keyboardFocusedCellIndex = cellIndex\n \n // Clear highlight from old position\n if (previousRowIndex !== undefined && previousRowIndex !== rowIndex) {\n this._clearKeyboardFocusOnRow(previousRowIndex)\n }\n else if (previousRowIndex === rowIndex && previousCellIndex !== cellIndex) {\n this._clearKeyboardFocusOnRow(rowIndex)\n }\n \n // Scroll the focused row into view if it is a data row\n if (rowIndex >= 0) {\n this._scrollRowIntoView(rowIndex)\n }\n \n // Apply highlight to new position\n this._applyKeyboardFocusToVisibleRows()\n \n // Notify observers (CBDataView uses this to sync header highlight)\n this.keyboardFocusDidChange?.(rowIndex, cellIndex)\n \n }\n \n _clearKeyboardFocus() {\n const previous = this._keyboardFocusedRowIndex\n this._keyboardFocusedRowIndex = undefined\n if (previous !== undefined) {\n this._clearKeyboardFocusOnRow(previous)\n }\n this.keyboardFocusDidChange?.(undefined, this._keyboardFocusedCellIndex)\n }\n \n _clearKeyboardFocusOnRow(rowIndex: number) {\n if (rowIndex === -1) {\n // Header \u2014 notify via callback; CBDataView handles the header view\n this.keyboardFocusDidChange?.(-1, -1)\n return\n }\n const row = this.visibleRowWithIndex(rowIndex) as any\n if (row && typeof row.setKeyboardFocusedCellIndex === \"function\") {\n row.setKeyboardFocusedCellIndex(undefined)\n }\n }\n \n _applyKeyboardFocusToVisibleRows(clearAll = false) {\n this._visibleRows.forEach((row: any) => {\n if (typeof row.setKeyboardFocusedCellIndex !== \"function\") {\n return\n }\n if (clearAll || row._UITableViewRowIndex !== this._keyboardFocusedRowIndex) {\n row.setKeyboardFocusedCellIndex(undefined)\n }\n else {\n row.setKeyboardFocusedCellIndex(this._keyboardFocusedCellIndex)\n }\n })\n }\n \n _scrollRowIntoView(rowIndex: number) {\n const position = this._rowPositionWithIndex(rowIndex)\n if (!position) {\n return\n }\n const offsetY = this.contentOffset.y\n const visibleHeight = this.bounds.height\n if (position.topY < offsetY) {\n const duration = this.animationDuration\n this.animationDuration = 0\n this.contentOffset = this.contentOffset.pointWithY(position.topY)\n this.animationDuration = duration\n }\n else if (position.bottomY > offsetY + visibleHeight) {\n const duration = this.animationDuration\n this.animationDuration = 0\n this.contentOffset = this.contentOffset.pointWithY(position.bottomY - visibleHeight)\n this.animationDuration = duration\n }\n }\n \n /** Expose so CBDataView can call it after loading data. */\n focusRowAtIndex(rowIndex: number, cellIndex: number = 0) {\n this._setKeyboardFocus(rowIndex, cellIndex)\n this._keyboardListenerElement.focus({ preventScroll: true })\n }\n \n \n _windowScrollHandler = () => {\n if (!this.isMemberOfViewTree) {\n return\n }\n this._scheduleDrawVisibleRows()\n }\n \n _resizeHandler = () => {\n if (!this.isMemberOfViewTree) {\n return\n }\n // Invalidate all row positions on resize as widths may have changed\n this._rowPositions.everyElement.isValid = NO\n this._highestValidRowPositionIndex = -1\n this._scheduleDrawVisibleRows()\n }\n \n _setupViewportScrollAndResizeHandlersIfNeeded() {\n if (this._intersectionObserver) {\n return\n }\n \n window.addEventListener(\"scroll\", this._windowScrollHandler, { passive: true })\n window.addEventListener(\"resize\", this._resizeHandler, { passive: true })\n \n // Use IntersectionObserver to detect when table enters/exits viewport\n this._intersectionObserver = new IntersectionObserver(\n (entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && this.isMemberOfViewTree) {\n this._scheduleDrawVisibleRows()\n }\n })\n },\n {\n root: null,\n rootMargin: \"100% 0px\", // Load rows 100% viewport height before/after\n threshold: 0\n }\n )\n this._intersectionObserver.observe(this.viewHTMLElement)\n }\n \n \n _cleanupViewportScrollListeners() {\n window.removeEventListener(\"scroll\", this._windowScrollHandler)\n window.removeEventListener(\"resize\", this._resizeHandler)\n if (this._intersectionObserver) {\n this._intersectionObserver.disconnect()\n this._intersectionObserver = undefined\n }\n }\n \n override wasRemovedFromViewTree() {\n super.wasRemovedFromViewTree()\n this._cleanupViewportScrollListeners()\n if (this._keydownHandler) {\n this.viewHTMLElement.removeEventListener(\"keydown\", this._keydownHandler)\n }\n // Reset so listeners are re-attached if added back to the tree\n this._keyboardListenersAttached = false\n }\n \n \n loadData() {\n \n this._persistedData = []\n \n this._calculatePositionsUntilIndex(this.numberOfRows() - 1)\n this._needsDrawingOfVisibleRowsBeforeLayout = YES\n \n this.setNeedsLayout()\n \n }\n \n reloadData() {\n \n this._removeVisibleRows()\n this._removeAllReusableRows()\n \n this._rowPositions = []\n this._highestValidRowPositionIndex = -1\n \n if (this.allRowsHaveEqualHeight) {\n UIView.invalidateSharedIntrinsicSizeCache(this._equalRowHeightCacheIdentifier)\n }\n \n this.loadData()\n \n }\n \n \n highlightChanges(previousData: any[], newData: any[]) {\n \n previousData = previousData.map(dataPoint => JSON.stringify(dataPoint))\n newData = newData.map(dataPoint => JSON.stringify(dataPoint))\n \n const newIndexes: number[] = []\n \n newData.forEach((value, index) => {\n \n if (!previousData.contains(value)) {\n \n newIndexes.push(index)\n \n }\n \n })\n \n newIndexes.forEach(index => {\n \n if (this.isRowWithIndexVisible(index)) {\n this.highlightRowAsNew(\n this.visibleRowWithIndex(index) ?? this.viewForRowWithIndex(index)\n )\n }\n \n })\n \n }\n \n \n highlightRowAsNew(row: UIView) {\n \n \n }\n \n \n invalidateSizeOfRowWithIndex(index: number, animateChange = NO) {\n if (this._rowPositions?.[index]) {\n FIRST_OR_NIL(this._rowPositions[index]).isValid = NO\n this._rowPositions.slice(index).everyElement.isValid = NO\n }\n this._highestValidRowPositionIndex = Math.min(this._highestValidRowPositionIndex, index - 1)\n this._needsDrawingOfVisibleRowsBeforeLayout = YES\n this._shouldAnimateNextLayout = animateChange\n }\n \n \n _rowPositionWithIndex(index: number, positions = this._rowPositions) {\n if (this.allRowsHaveEqualHeight && index > 0) {\n const firstPositionObject = positions[0]\n const rowHeight = firstPositionObject.bottomY - firstPositionObject.topY\n const result = {\n bottomY: rowHeight * (index + 1),\n topY: rowHeight * index,\n isValid: firstPositionObject.isValid\n }\n return result\n }\n return positions[index]\n }\n \n _calculateAllPositions() {\n this._calculatePositionsUntilIndex(this.numberOfRows() - 1)\n }\n \n _calculatePositionsUntilIndex(maxIndex: number) {\n \n if (this.allRowsHaveEqualHeight) {\n const positionObject: UITableViewReusableViewPositionObject = {\n bottomY: this._heightForAnyRow(),\n topY: 0,\n isValid: YES\n }\n this._rowPositions = [positionObject]\n return\n }\n \n let validPositionObject = this._rowPositions[this._highestValidRowPositionIndex]\n if (!IS(validPositionObject)) {\n validPositionObject = {\n bottomY: 0,\n topY: 0,\n isValid: YES\n }\n }\n \n let previousBottomY = validPositionObject.bottomY\n if (!this._rowPositions.length) {\n this._highestValidRowPositionIndex = -1\n }\n \n for (let i = this._highestValidRowPositionIndex + 1; i <= maxIndex; i++) {\n \n let height: number\n \n const rowPositionObject = this._rowPositions[i]\n \n if (IS((rowPositionObject || nil).isValid)) {\n height = rowPositionObject.bottomY - rowPositionObject.topY\n }\n // Do not calculate heights if all rows have equal heights, and we already have a height\n else if (this.allRowsHaveEqualHeight && i > 0) {\n height = this._rowPositions[0].bottomY - this._rowPositions[0].topY\n }\n else {\n height = this.heightForRowWithIndex(i)\n }\n \n const positionObject: UITableViewReusableViewPositionObject = {\n bottomY: previousBottomY + height,\n topY: previousBottomY,\n isValid: YES\n }\n \n if (i < this._rowPositions.length) {\n this._rowPositions[i] = positionObject\n }\n else {\n this._rowPositions.push(positionObject)\n }\n this._highestValidRowPositionIndex = i\n previousBottomY = previousBottomY + height\n \n }\n \n }\n \n \n _heightForAnyRow(calculateVisibleRows = YES) {\n return this.heightForRowWithIndex(\n this._visibleRows.firstElement?._UITableViewRowIndex ??\n (calculateVisibleRows ? this.indexesForVisibleRows().firstElement : 0) ??\n 0\n )\n }\n \n indexesForVisibleRows(paddingRatio = 0.5): number[] {\n \n // 1. Calculate the visible frame relative to the Table's bounds (0,0 is top-left of the table view)\n // This accounts for the Window viewport clipping the table if it is partially off-screen.\n const tableRect = this.viewHTMLElement.getBoundingClientRect()\n const viewportHeight = window.innerHeight\n const pageScale = UIView.pageScale\n \n // The top of the visible window relative to the view's top edge.\n // If tableRect.top is negative, the table is scrolled up and clipped by the window top.\n const visibleFrameTop = Math.max(0, -tableRect.top / pageScale)\n \n // The bottom of the visible window relative to the view's top edge.\n // We clip it to the table's actual bounds height so we don't look past the table content.\n const visibleFrameBottom = Math.min(\n this.bounds.height,\n (viewportHeight - tableRect.top) / pageScale\n )\n \n // If the table is completely off-screen, return empty\n if (visibleFrameBottom <= visibleFrameTop) {\n return []\n }\n \n // 2. Convert to Content Coordinates (Scroll Offset)\n // contentOffset.y is the internal scroll position.\n // If using viewport scrolling (full height), contentOffset.y is typically 0.\n // If using internal scrolling, this shifts the visible frame to the correct content rows.\n let firstVisibleY = this.contentOffset.y + visibleFrameTop\n let lastVisibleY = this.contentOffset.y + visibleFrameBottom\n \n // 3. Apply Padding\n // We calculate padding based on the viewport height to ensure smooth scrolling\n const paddingPx = (viewportHeight / pageScale) * paddingRatio\n firstVisibleY = Math.max(0, firstVisibleY - paddingPx)\n lastVisibleY = lastVisibleY + paddingPx\n \n const numberOfRows = this.numberOfRows()\n \n // 4. Find Indexes\n if (this.allRowsHaveEqualHeight) {\n \n const rowHeight = this._heightForAnyRow(NO)\n \n let firstIndex = Math.floor(firstVisibleY / rowHeight)\n let lastIndex = Math.floor(lastVisibleY / rowHeight)\n \n // Clamp BOTH indexes to [0, numberOfRows-1].\n // Without the upper clamp on firstIndex, when the viewport extends below the\n // last row firstIndex can exceed numberOfRows-1 while lastIndex is already\n // clamped there. firstIndex > lastIndex \u2192 empty result \u2192 _removeVisibleRows \u2192\n // browser collapses scrollHeight \u2192 scrollTop resets to 0 \u2192 rows pile at top.\n firstIndex = Math.max(0, Math.min(firstIndex, numberOfRows - 1))\n lastIndex = Math.max(0, Math.min(lastIndex, numberOfRows - 1))\n \n const result = []\n for (let i = firstIndex; i <= lastIndex; i++) {\n result.push(i)\n }\n return result\n }\n \n // Variable Heights\n this._calculateAllPositions()\n const result = []\n \n // Clamp firstVisibleY to the actual content height so that when the viewport\n // extends below the last row the intersection check still matches the final rows\n // rather than producing an empty result.\n const totalContentHeight = IF(this._rowPositions.lastElement)(() =>\n this._rowPositions.lastElement.bottomY\n ).ELSE(() =>\n 0\n )\n firstVisibleY = Math.min(firstVisibleY, totalContentHeight)\n \n for (let i = 0; i < numberOfRows; i++) {\n \n const position = this._rowPositionWithIndex(i)\n if (!position) {\n break\n }\n \n const rowTop = position.topY\n const rowBottom = position.bottomY\n \n // Check intersection\n if (rowBottom >= firstVisibleY && rowTop <= lastVisibleY) {\n result.push(i)\n }\n \n if (rowTop > lastVisibleY) {\n break\n }\n \n }\n \n return result\n \n }\n \n \n // This is called when no rows are supposed to be visible as a performance shortcut\n _removeVisibleRows() {\n \n this._visibleRows.forEach((row: UIView) => {\n \n this._persistedData[row._UITableViewRowIndex as number] = this.persistenceDataItemForRowWithIndex(\n row._UITableViewRowIndex as number,\n row\n )\n row.removeFromSuperview()\n this._markReusableViewAsUnused(row)\n \n })\n this._visibleRows = []\n \n }\n \n \n _removeAllReusableRows() {\n this._unusedReusableViews.forEach((rows: UIView[]) =>\n rows.forEach((row: UIView) => {\n \n this._persistedData[row._UITableViewRowIndex as number] = this.persistenceDataItemForRowWithIndex(\n row._UITableViewRowIndex as number,\n row\n )\n row.removeFromSuperview()\n \n })\n )\n this._unusedReusableViews = {}\n }\n \n \n _markReusableViewAsUnused(row: UIView) {\n const identifier = row._UITableViewReusabilityIdentifier\n if (!this._unusedReusableViews[identifier]) {\n this._unusedReusableViews[identifier] = []\n }\n if (!this._unusedReusableViews[identifier].contains(row)) {\n this._unusedReusableViews[identifier].push(row)\n }\n }\n \n _scheduleDrawVisibleRows() {\n if (!this._isDrawVisibleRowsScheduled) {\n this._isDrawVisibleRowsScheduled = YES\n \n UIView.runFunctionBeforeNextFrame(() => {\n this._calculateAllPositions()\n this._drawVisibleRows()\n this.setNeedsLayout()\n this._isDrawVisibleRowsScheduled = NO\n })\n }\n }\n \n _drawVisibleRows() {\n \n if (!this.isMemberOfViewTree) {\n return\n }\n \n // Uses the unified method above\n const visibleIndexes = this.indexesForVisibleRows()\n \n // If no rows are visible, remove all current rows\n if (visibleIndexes.length === 0) {\n this._removeVisibleRows()\n return\n }\n \n const minIndex = visibleIndexes[0]\n const maxIndex = visibleIndexes[visibleIndexes.length - 1]\n \n const removedViews: UITableViewRowView[] = []\n const visibleRows: UITableViewRowView[] = []\n \n // 1. Identify rows that have moved off-screen\n this._visibleRows.forEach((row) => {\n if (IS_DEFINED(row._UITableViewRowIndex) &&\n (row._UITableViewRowIndex < minIndex || row._UITableViewRowIndex > maxIndex)) {\n \n // Persist state before removal\n this._persistedData[row._UITableViewRowIndex] = this.persistenceDataItemForRowWithIndex(\n row._UITableViewRowIndex,\n row\n )\n this._markReusableViewAsUnused(row)\n removedViews.push(row)\n }\n else {\n visibleRows.push(row)\n }\n })\n \n this._visibleRows = visibleRows\n \n // 2. Add new rows that have moved onto the screen\n visibleIndexes.forEach((rowIndex: number) => {\n // If the view is already in this._visibleRows, do nothing to it\n if (this.isRowWithIndexVisible(rowIndex)) {\n return\n }\n \n // Get view from reuse pool (marked as unused before) or make a new one\n const view: UITableViewRowView = this.viewForRowWithIndex(rowIndex)\n this._visibleRows.push(view)\n this.addSubview(view)\n \n // Ensure the row and all its children stay out of the natural tab order\n view.tabIndex = -1\n view.forEachViewInSubtree(subview => {\n subview.tabIndex = -1\n })\n })\n \n // 3. Clean up DOM\n removedViews.forEach(row => {\n // Check that the row has not been added back\n if (this._visibleRows.indexOf(row) == -1) {\n row.removeFromSuperview()\n }\n })\n \n // 4. Re-apply keyboard focus highlight after rows are re-rendered\n this._applyKeyboardFocusToVisibleRows()\n \n }\n \n \n visibleRowWithIndex(rowIndex: number | undefined): UIView | undefined {\n for (let i = 0; i < this._visibleRows.length; i++) {\n const row = this._visibleRows[i]\n if (row._UITableViewRowIndex == rowIndex) {\n return row\n }\n }\n }\n \n \n isRowWithIndexVisible(rowIndex: number) {\n return IS(this.visibleRowWithIndex(rowIndex))\n }\n \n \n reusableViewForIdentifier(identifier: string, rowIndex: number): UITableViewRowView {\n \n const visibleRowView = this.visibleRowWithIndex(rowIndex)\n if (visibleRowView?._UITableViewReusabilityIdentifier === identifier) {\n return visibleRowView\n }\n \n if (!this._unusedReusableViews[identifier]) {\n this._unusedReusableViews[identifier] = []\n }\n \n let view: UITableViewRowView\n \n if (this._unusedReusableViews[identifier]?.length) {\n \n view = this._unusedReusableViews[identifier].pop() as UITableViewRowView\n view._UITableViewRowIndex = rowIndex\n Object.assign(view, this._persistedData[rowIndex] || this.defaultRowPersistenceDataItem())\n \n }\n else {\n \n view = this.newReusableViewForIdentifier(identifier, this._rowIDIndex) as UITableViewRowView\n this._rowIDIndex = this._rowIDIndex + 1\n \n view.configureWithObject({\n _UITableViewReusabilityIdentifier: identifier,\n _UITableViewRowIndex: rowIndex,\n \n // Extend clearIntrinsicSizeCache so that when the row (or any of its\n // subviews) invalidates its own size cache, the table is notified to\n // re-measure that specific row index. EXTEND preserves the original\n // implementation and appends this behaviour after it.\n clearIntrinsicSizeCache: EXTEND(() => {\n const currentRowIndex = view._UITableViewRowIndex\n if (IS_DEFINED(currentRowIndex) && view.isMemberOfViewTree) {\n this.invalidateSizeOfRowWithIndex(currentRowIndex)\n this.setNeedsLayout()\n }\n })\n })\n \n Object.assign(view, this._persistedData[rowIndex] || this.defaultRowPersistenceDataItem())\n \n }\n \n // When all rows are uniform, opt the view into the shared height cache so\n // only the first measurement is ever computed for the whole table.\n if (this.allRowsHaveEqualHeight) {\n view.sharedIntrinsicSizeCacheIdentifier = this._equalRowHeightCacheIdentifier\n }\n else {\n view.sharedIntrinsicSizeCacheIdentifier = undefined\n }\n \n return view\n \n }\n \n \n // Functions that should be overridden to draw the correct content START\n newReusableViewForIdentifier(identifier: string, rowIDIndex: number): UIView {\n \n const view = new UIButton(this.elementID + \"Row\" + rowIDIndex)\n \n view.stopsPointerEventPropagation = NO\n view.pausesPointerEvents = NO\n \n return view\n \n }\n \n heightForRowWithIndex(index: number): number {\n return 50\n }\n \n numberOfRows() {\n return 10000\n }\n \n defaultRowPersistenceDataItem(): any {\n \n \n }\n \n persistenceDataItemForRowWithIndex(rowIndex: number, row: UIView): any {\n \n \n }\n \n viewForRowWithIndex(rowIndex: number): UITableViewRowView {\n const row = this.reusableViewForIdentifier(\"Row\", rowIndex)\n row._UITableViewRowIndex = rowIndex\n FIRST_OR_NIL((row as unknown as UIButton).titleLabel).text = \"Row \" + rowIndex\n return row\n }\n \n // Functions that should be overridden to draw the correct content END\n \n \n // Functions that trigger redrawing of the content\n override didScrollToPosition(offsetPosition: UIPoint) {\n \n super.didScrollToPosition(offsetPosition)\n \n this.forEachViewInSubtree((view: UIView) => {\n view._isPointerValid = NO\n })\n \n this._scheduleDrawVisibleRows()\n \n }\n \n override willMoveToSuperview(superview: UIView) {\n super.willMoveToSuperview(superview)\n \n if (IS(superview)) {\n // Set up viewport listeners when added to a superview\n this._setupViewportScrollAndResizeHandlersIfNeeded()\n }\n else {\n // Clean up when removed from superview\n this._cleanupViewportScrollListeners()\n }\n }\n \n override wasAddedToViewTree() {\n super.wasAddedToViewTree()\n this.loadData()\n \n // Ensure listeners are set up\n this._setupViewportScrollAndResizeHandlersIfNeeded()\n \n // Attach keyboard and pointer listeners now that the element is stable\n // in the DOM. Guarded so repeated wasAddedToViewTree calls (e.g. after\n // navigation returns) don't stack duplicate listeners.\n if (!this._keyboardListenersAttached) {\n this._keyboardListenersAttached = true\n const el = this._keyboardListenerElement\n \n el.addEventListener(\"keydown\", this._keydownHandler!)\n \n el.addEventListener(\"pointerdown\", (event: PointerEvent) => {\n if (this.disablesKeyboardNavigation) {\n return\n }\n const target = event.target as HTMLElement | null\n if (target?.tagName === \"INPUT\" || target?.tagName === \"TEXTAREA\") {\n return\n }\n let walkedTarget = target\n while (walkedTarget && walkedTarget !== el) {\n const viewObject = (walkedTarget as any).UIViewObject as UITableViewRowView | undefined\n if (viewObject?._UITableViewRowIndex !== undefined) {\n this._setKeyboardFocus(viewObject._UITableViewRowIndex, this._keyboardFocusedCellIndex)\n el.focus({ preventScroll: true })\n return\n }\n walkedTarget = walkedTarget.parentElement\n }\n el.focus({ preventScroll: true })\n })\n \n el.addEventListener(\"focus\", () => {\n if (this._keyboardFocusedRowIndex === undefined && this.numberOfRows() > 0) {\n this._setKeyboardFocus(0, this._keyboardFocusedCellIndex)\n }\n else if (this._keyboardFocusedRowIndex !== undefined) {\n this._applyKeyboardFocusToVisibleRows()\n }\n })\n \n el.addEventListener(\"blur\", (event: FocusEvent) => {\n if (!el.contains(event.relatedTarget as Node)) {\n this._applyKeyboardFocusToVisibleRows(true)\n }\n })\n }\n \n // Remove all subviews from the browser's natural tab order.\n // The container (_keyboardListenerElement) is the single tab stop.\n // Internal navigation is handled exclusively via arrow keys.\n this.forEachViewInSubtree(view => {\n if (view !== this) {\n view.tabIndex = -1\n }\n })\n // Re-assert tabIndex=0 on the listener element \u2014 wasAddedToViewTree fires\n // on every tree insertion including navigation returns.\n if (!this.disablesKeyboardNavigation) {\n this._keyboardListenerElement.tabIndex = 0\n }\n \n }\n \n override setFrame(rectangle: UIRectangle, zIndex?: number, performUncheckedLayout?: boolean) {\n \n const frame = this.frame\n super.setFrame(rectangle, zIndex, performUncheckedLayout)\n if (frame.isEqualTo(rectangle) && !performUncheckedLayout) {\n return\n }\n \n this._needsDrawingOfVisibleRowsBeforeLayout = YES\n \n }\n \n \n override didReceiveBroadcastEvent(event: UIViewBroadcastEvent) {\n \n super.didReceiveBroadcastEvent(event)\n \n if (event.name == UIView.broadcastEventName.LanguageChanged && this.reloadsOnLanguageChange) {\n \n this.reloadData()\n \n }\n \n \n }\n \n \n override clearIntrinsicSizeCache() {\n super.clearIntrinsicSizeCache()\n if (this.allRowsHaveEqualHeight) {\n UIView.invalidateSharedIntrinsicSizeCache(this._equalRowHeightCacheIdentifier)\n }\n this.invalidateSizeOfRowWithIndex(0)\n }\n \n private _layoutAllRows(positions = this._rowPositions) {\n \n const bounds = this.bounds\n \n const sortedRows = this._visibleRows.sort(\n (rowA, rowB) => rowA._UITableViewRowIndex! - rowB._UITableViewRowIndex!\n )\n \n sortedRows.forEach((row, i) => {\n \n const frame = bounds.copy()\n \n const positionObject = this._rowPositionWithIndex(row._UITableViewRowIndex!, positions)\n frame.min.y = positionObject.topY\n frame.max.y = positionObject.bottomY\n row.frame = frame\n \n row.style.width = \"\" + (bounds.width - this.sidePadding * 2).integerValue + \"px\"\n row.style.left = \"\" + this.sidePadding.integerValue + \"px\"\n \n // Set aria-rowindex (1-based per ARIA spec)\n row.viewHTMLElement.setAttribute(\"aria-rowindex\", String((row._UITableViewRowIndex ?? 0) + 1))\n \n // Insert before the correct next sibling so DOM order always matches\n // row index order. The nextSibling check makes this a no-op when the\n // element is already in the right position, avoiding unnecessary DOM\n // mutations and the focus loss that appendChild causes.\n const nextSiblingElement = sortedRows[i + 1]?.viewHTMLElement\n ?? this._fullHeightView.viewHTMLElement\n if (row.viewHTMLElement.nextSibling !== nextSiblingElement) {\n this.viewHTMLElement.insertBefore(row.viewHTMLElement, nextSiblingElement)\n }\n \n })\n \n // Use _rowPositionWithIndex rather than positions.lastElement.\n // When allRowsHaveEqualHeight = YES, _rowPositions contains only a single\n // entry (row 0). positions.lastElement.bottomY would therefore equal just\n // ONE row's height (e.g. 50px) instead of the full content height.\n // _rowPositionWithIndex correctly uses the computed formula for equal-height\n // tables (numberOfRows \u00D7 rowHeight) and falls back to positions[N-1] otherwise.\n // This ensures _fullHeightView maintains the correct scroll height even when\n // all visible rows have been removed from the DOM (e.g. after crossing the\n // bottom edge), preventing the browser from clamping scrollTop to 0.\n const numberOfRows = this.numberOfRows()\n const fullContentHeight = numberOfRows\n ? this._rowPositionWithIndex(numberOfRows - 1, positions).bottomY\n : 0\n this._fullHeightView.frame = bounds.rectangleWithHeight(fullContentHeight)\n .rectangleWithWidth(bounds.width * 0.5)\n \n }\n \n private _animateLayoutAllRows() {\n \n UIView.animateViewOrViewsWithDurationDelayAndFunction(\n this._visibleRows,\n this.animationDuration,\n 0,\n undefined,\n () => {\n \n this._layoutAllRows()\n \n },\n () => {\n \n \n }\n )\n \n }\n \n // UITableView has usesVirtualLayoutingForIntrinsicSizing = NO and is always\n // given a fixed viewport frame by its parent \u2014 so frame.height never changes\n // between layout passes. The base didLayoutSubviews compares frame.height and\n // therefore never propagates upward, even when row positions have changed and\n // intrinsicContentHeight now returns a different value.\n // We override here to track the intrinsic content height instead, so that\n // parents (e.g. CBDataView) get their cache invalidated and re-layout whenever\n // the total row stack height changes.\n override didLayoutSubviews() {\n this.viewController?.viewDidLayoutSubviews()\n \n if (!this.isVirtualLayouting && IS(this.superview) && this.isMemberOfViewTree) {\n const currentContentHeight = this.intrinsicContentHeight()\n if (currentContentHeight !== this._lastReportedHeight) {\n this._lastReportedHeight = currentContentHeight\n this.clearIntrinsicSizeCache()\n this.superview.setNeedsLayout()\n }\n }\n }\n \n \n override layoutSubviews() {\n \n if (this.isVirtualLayouting) {\n console.error(\"layout subviews called during virtual layouting on UITableView, \" +\n \"indicating a possible error in the layout system.\")\n return\n }\n \n const previousPositions: UITableViewReusableViewPositionObject[] = JSON.parse(\n JSON.stringify(this._rowPositions))\n \n const previousVisibleRowsLength = this._visibleRows.length\n \n if (this._needsDrawingOfVisibleRowsBeforeLayout) {\n \n this._drawVisibleRows()\n \n this._needsDrawingOfVisibleRowsBeforeLayout = NO\n \n }\n \n \n super.layoutSubviews()\n \n \n if (!this.numberOfRows() || !this.isMemberOfViewTree) {\n \n return\n \n }\n \n \n if (this._shouldAnimateNextLayout) {\n \n \n // Need to do layout with the previous positions\n \n this._layoutAllRows(previousPositions)\n \n \n if (previousVisibleRowsLength < this._visibleRows.length) {\n \n \n UIView.runFunctionBeforeNextFrame(() => {\n \n this._animateLayoutAllRows()\n \n })\n \n }\n else {\n \n this._animateLayoutAllRows()\n \n }\n \n \n this._shouldAnimateNextLayout = NO\n \n }\n else {\n \n this._calculateAllPositions()\n \n this._layoutAllRows()\n \n \n }\n \n \n }\n \n \n override intrinsicContentHeight(constrainingWidth = 0) {\n \n let result = 0\n this._calculateAllPositions()\n \n const numberOfRows = this.numberOfRows()\n if (numberOfRows) {\n result = this._rowPositionWithIndex(numberOfRows - 1).bottomY\n }\n \n return result\n \n }\n \n \n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["result"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uicore-ts",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.362",
|
|
4
4
|
"description": "UICore is a library to build native-like user interfaces using pure Typescript. No HTML is needed at all. Components are described as TS classes and all user interactions are handled explicitly. This library is strongly inspired by the UIKit framework that is used in IOS. In addition, UICore has tools to handle URL based routing, array sorting and filtering and adds a number of other utilities for convenience.",
|
|
5
5
|
"main": "compiledScripts/index.js",
|
|
6
6
|
"types": "compiledScripts/index.d.ts",
|
|
@@ -38,6 +38,11 @@ export class UIAutocompleteDropdownView<T> extends UIView {
|
|
|
38
38
|
this.tableView = new UITableView(elementID ? elementID + "TableView" : undefined)
|
|
39
39
|
this.addSubview(this.tableView)
|
|
40
40
|
|
|
41
|
+
// Keyboard navigation and focus are owned by the text field, not the table.
|
|
42
|
+
// Disabling it prevents the pointerdown handler from calling el.focus() and
|
|
43
|
+
// stealing focus away from the text field when the user clicks a row.
|
|
44
|
+
this.tableView.disablesKeyboardNavigation = YES
|
|
45
|
+
|
|
41
46
|
this.tableView.allRowsHaveEqualHeight = YES
|
|
42
47
|
this.tableView.numberOfRows = () => this._filteredItems.length
|
|
43
48
|
this.tableView.heightForRowWithIndex = () => this._rowHeight
|
|
@@ -282,6 +287,3 @@ export class UIAutocompleteDropdownView<T> extends UIView {
|
|
|
282
287
|
|
|
283
288
|
|
|
284
289
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
package/scripts/UIDialogView.ts
CHANGED
|
@@ -369,20 +369,45 @@ export class UIRootViewController extends UIViewController {
|
|
|
369
369
|
this.detailsViewController.view.intrinsicContentWidth() || contentView.bounds.width,
|
|
370
370
|
contentView.bounds.width
|
|
371
371
|
)
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
372
|
+
|
|
373
|
+
// _detailsDialogView fills the currently visible viewport and uses
|
|
374
|
+
// viewport-relative local coordinates (its own y = 0 is "top of the
|
|
375
|
+
// visible viewport", tracking scroll — see UIDialogView.layoutSubviews).
|
|
376
|
+
// The dialog content is a subview of that backdrop, so its frame must
|
|
377
|
+
// be computed in that same viewport-relative space, not in the page's
|
|
378
|
+
// document coordinates that backgroundView.frame uses. Otherwise the
|
|
379
|
+
// dialog's vertical position drifts further down the page the more
|
|
380
|
+
// the user has scrolled before opening it.
|
|
381
|
+
const containerRect = this.view.viewHTMLElement.getBoundingClientRect()
|
|
382
|
+
const visibleTopBarHeight = Math.max(
|
|
383
|
+
0,
|
|
384
|
+
(this.topBarView?.frame.height ?? 0) + containerRect.top / UIView.pageScale
|
|
385
|
+
)
|
|
386
|
+
const minimumTop = visibleTopBarHeight + paddingLength
|
|
387
|
+
const viewportHeight = window.innerHeight / UIView.pageScale
|
|
388
|
+
const viewportBelowTopBarCenterY = minimumTop + (viewportHeight - minimumTop) * 0.5
|
|
389
|
+
|
|
390
|
+
const detailsHeight = Math.max(
|
|
391
|
+
this.detailsViewController.view.intrinsicContentHeight(
|
|
392
|
+
this.detailsViewController.view.bounds.width
|
|
393
|
+
),
|
|
394
|
+
contentView.bounds.height
|
|
384
395
|
)
|
|
385
396
|
|
|
397
|
+
let detailsFrame = this.backgroundView.frame
|
|
398
|
+
.rectangleWithWidth(detailsWidth, 0.5)
|
|
399
|
+
.rectangleWithHeight(detailsHeight)
|
|
400
|
+
.rectangleWithY(viewportBelowTopBarCenterY, 0.5)
|
|
401
|
+
|
|
402
|
+
// If centering would place the dialog's top edge above the visible
|
|
403
|
+
// top bar (or above the viewport entirely, on very short dialogs),
|
|
404
|
+
// shift it down so it never overlaps or floats above that boundary.
|
|
405
|
+
if (detailsFrame.y < minimumTop) {
|
|
406
|
+
detailsFrame = detailsFrame.rectangleWithY(minimumTop)
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
this.detailsViewController.view.frame = detailsFrame
|
|
410
|
+
|
|
386
411
|
}
|
|
387
412
|
else {
|
|
388
413
|
|
package/scripts/UITableView.ts
CHANGED
|
@@ -142,7 +142,18 @@ export class UITableView extends UINativeScrollView {
|
|
|
142
142
|
*/
|
|
143
143
|
_keyboardListenerElement: HTMLElement = this.viewHTMLElement
|
|
144
144
|
|
|
145
|
+
/**
|
|
146
|
+
* When YES, suppresses the grid ARIA role, tabIndex, and all keyboard/pointer
|
|
147
|
+
* focus listeners. Set this on table views that are controlled by an external
|
|
148
|
+
* focus owner (e.g. an autocomplete text field) so clicks inside the table
|
|
149
|
+
* never steal focus away from that owner.
|
|
150
|
+
*/
|
|
151
|
+
disablesKeyboardNavigation: boolean = NO
|
|
152
|
+
|
|
145
153
|
_setupGridAccessibility() {
|
|
154
|
+
if (this.disablesKeyboardNavigation) {
|
|
155
|
+
return
|
|
156
|
+
}
|
|
146
157
|
const el = this._keyboardListenerElement
|
|
147
158
|
el.setAttribute("role", "grid")
|
|
148
159
|
el.setAttribute("aria-rowcount", "0")
|
|
@@ -1019,6 +1030,9 @@ export class UITableView extends UINativeScrollView {
|
|
|
1019
1030
|
el.addEventListener("keydown", this._keydownHandler!)
|
|
1020
1031
|
|
|
1021
1032
|
el.addEventListener("pointerdown", (event: PointerEvent) => {
|
|
1033
|
+
if (this.disablesKeyboardNavigation) {
|
|
1034
|
+
return
|
|
1035
|
+
}
|
|
1022
1036
|
const target = event.target as HTMLElement | null
|
|
1023
1037
|
if (target?.tagName === "INPUT" || target?.tagName === "TEXTAREA") {
|
|
1024
1038
|
return
|
|
@@ -1062,7 +1076,9 @@ export class UITableView extends UINativeScrollView {
|
|
|
1062
1076
|
})
|
|
1063
1077
|
// Re-assert tabIndex=0 on the listener element — wasAddedToViewTree fires
|
|
1064
1078
|
// on every tree insertion including navigation returns.
|
|
1065
|
-
this.
|
|
1079
|
+
if (!this.disablesKeyboardNavigation) {
|
|
1080
|
+
this._keyboardListenerElement.tabIndex = 0
|
|
1081
|
+
}
|
|
1066
1082
|
|
|
1067
1083
|
}
|
|
1068
1084
|
|