@nativescript/core 9.1.0-alpha.8 → 9.1.0-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/animation-frame/animation-native.windows.d.ts +1 -0
- package/animation-frame/animation-native.windows.js +4 -0
- package/animation-frame/animation-native.windows.js.map +1 -0
- package/application/application-common.d.ts +2 -1
- package/application/application-common.js +4 -0
- package/application/application-common.js.map +1 -1
- package/application/application.android.d.ts +0 -16
- package/application/application.android.js +1 -6
- package/application/application.android.js.map +1 -1
- package/application/application.d.ts +9 -0
- package/application/application.ios.d.ts +1 -2
- package/application/application.ios.js +3 -50
- package/application/application.ios.js.map +1 -1
- package/application/application.windows.d.ts +27 -0
- package/application/application.windows.js +331 -0
- package/application/application.windows.js.map +1 -0
- package/application/helpers.windows.d.ts +8 -0
- package/application/helpers.windows.js +12 -0
- package/application/helpers.windows.js.map +1 -0
- package/application/index.windows.d.ts +2 -0
- package/application/index.windows.js +3 -0
- package/application/index.windows.js.map +1 -0
- package/application/window-helper.windows.d.ts +29 -0
- package/application/window-helper.windows.js +159 -0
- package/application/window-helper.windows.js.map +1 -0
- package/application-settings/index.windows.d.ts +11 -0
- package/application-settings/index.windows.js +93 -0
- package/application-settings/index.windows.js.map +1 -0
- package/color/index.d.ts +5 -0
- package/color/index.windows.d.ts +8 -0
- package/color/index.windows.js +19 -0
- package/color/index.windows.js.map +1 -0
- package/connectivity/index.windows.d.ts +11 -0
- package/connectivity/index.windows.js +50 -0
- package/connectivity/index.windows.js.map +1 -0
- package/debugger/webinspector-network.windows.d.ts +79 -0
- package/debugger/webinspector-network.windows.js +307 -0
- package/debugger/webinspector-network.windows.js.map +1 -0
- package/file-system/file-system-access.windows.d.ts +76 -0
- package/file-system/file-system-access.windows.js +476 -0
- package/file-system/file-system-access.windows.js.map +1 -0
- package/fps-meter/fps-native.windows.d.ts +8 -0
- package/fps-meter/fps-native.windows.js +40 -0
- package/fps-meter/fps-native.windows.js.map +1 -0
- package/global-types.d.ts +1 -0
- package/globals/index.js +1 -4
- package/globals/index.js.map +1 -1
- package/http/http-request/index.android.js.map +1 -1
- package/http/http-request/index.ios.js.map +1 -1
- package/http/http-request/index.windows.d.ts +2 -0
- package/http/http-request/index.windows.js +41 -0
- package/http/http-request/index.windows.js.map +1 -0
- package/http/http-request-internal/index.android.d.ts +1 -7
- package/http/http-request-internal/index.android.js.map +1 -1
- package/http/http-request-internal/index.ios.d.ts +1 -7
- package/http/http-request-internal/index.ios.js.map +1 -1
- package/http/http-request-internal/index.windows.d.ts +4 -0
- package/http/http-request-internal/index.windows.js +134 -0
- package/http/http-request-internal/index.windows.js.map +1 -0
- package/image-asset/index.windows.d.ts +9 -0
- package/image-asset/index.windows.js +34 -0
- package/image-asset/index.windows.js.map +1 -0
- package/image-source/index.android.d.ts +1 -0
- package/image-source/index.android.js.map +1 -1
- package/image-source/index.d.ts +5 -0
- package/image-source/index.ios.d.ts +1 -0
- package/image-source/index.ios.js.map +1 -1
- package/image-source/index.windows.d.ts +52 -0
- package/image-source/index.windows.js +498 -0
- package/image-source/index.windows.js.map +1 -0
- package/package.json +6 -2
- package/platform/common.d.ts +2 -0
- package/platform/common.js +2 -0
- package/platform/common.js.map +1 -1
- package/platform/device/index.windows.d.ts +18 -0
- package/platform/device/index.windows.js +94 -0
- package/platform/device/index.windows.js.map +1 -0
- package/platform/screen/index.windows.d.ts +13 -0
- package/platform/screen/index.windows.js +25 -0
- package/platform/screen/index.windows.js.map +1 -0
- package/platforms/windows/arm64/NativeScript.Widgets.dll +0 -0
- package/platforms/windows/arm64/NativeScript.Widgets.winmd +0 -0
- package/platforms/windows/x64/NativeScript.Widgets.dll +0 -0
- package/platforms/windows/x64/NativeScript.Widgets.winmd +0 -0
- package/plugin.props +12 -0
- package/plugin.targets +71 -0
- package/references.d.ts +4 -0
- package/text/index.windows.d.ts +9 -0
- package/text/index.windows.js +12 -0
- package/text/index.windows.js.map +1 -0
- package/timer/index.windows.d.ts +4 -0
- package/timer/index.windows.js +14 -0
- package/timer/index.windows.js.map +1 -0
- package/ui/action-bar/index.ios.js +1 -0
- package/ui/action-bar/index.ios.js.map +1 -1
- package/ui/action-bar/index.windows.d.ts +12 -0
- package/ui/action-bar/index.windows.js +36 -0
- package/ui/action-bar/index.windows.js.map +1 -0
- package/ui/activity-indicator/index.windows.d.ts +15 -0
- package/ui/activity-indicator/index.windows.js +65 -0
- package/ui/activity-indicator/index.windows.js.map +1 -0
- package/ui/animation/index.windows.d.ts +19 -0
- package/ui/animation/index.windows.js +603 -0
- package/ui/animation/index.windows.js.map +1 -0
- package/ui/builder/index.d.ts +1 -0
- package/ui/builder/index.js +2 -1
- package/ui/builder/index.js.map +1 -1
- package/ui/button/index.android.d.ts +9 -2
- package/ui/button/index.android.js +24 -7
- package/ui/button/index.android.js.map +1 -1
- package/ui/button/index.ios.d.ts +9 -2
- package/ui/button/index.ios.js +72 -17
- package/ui/button/index.ios.js.map +1 -1
- package/ui/button/index.windows.d.ts +13 -0
- package/ui/button/index.windows.js +73 -0
- package/ui/button/index.windows.js.map +1 -0
- package/ui/core/bindable/index.js +1 -2
- package/ui/core/bindable/index.js.map +1 -1
- package/ui/core/control-state-change/index.windows.d.ts +4 -0
- package/ui/core/control-state-change/index.windows.js +6 -0
- package/ui/core/control-state-change/index.windows.js.map +1 -0
- package/ui/core/view/index.android.d.ts +0 -1
- package/ui/core/view/index.android.js +8 -17
- package/ui/core/view/index.android.js.map +1 -1
- package/ui/core/view/index.ios.d.ts +0 -1
- package/ui/core/view/index.ios.js +4 -17
- package/ui/core/view/index.ios.js.map +1 -1
- package/ui/core/view/index.windows.d.ts +120 -0
- package/ui/core/view/index.windows.js +2178 -0
- package/ui/core/view/index.windows.js.map +1 -0
- package/ui/core/view/view-common.d.ts +2 -0
- package/ui/core/view/view-common.js +6 -1
- package/ui/core/view/view-common.js.map +1 -1
- package/ui/core/view/view-helper/index.d.ts +0 -1
- package/ui/core/view/view-helper/index.ios.d.ts +0 -24
- package/ui/core/view/view-helper/index.ios.js +5 -54
- package/ui/core/view/view-helper/index.ios.js.map +1 -1
- package/ui/core/view/view-helper/index.windows.d.ts +3 -0
- package/ui/core/view/view-helper/index.windows.js +4 -0
- package/ui/core/view/view-helper/index.windows.js.map +1 -0
- package/ui/core/view-base/index.d.ts +10 -24
- package/ui/core/view-base/index.js +32 -50
- package/ui/core/view-base/index.js.map +1 -1
- package/ui/date-picker/index.windows.d.ts +22 -0
- package/ui/date-picker/index.windows.js +97 -0
- package/ui/date-picker/index.windows.js.map +1 -0
- package/ui/dialogs/index.windows.d.ts +17 -0
- package/ui/dialogs/index.windows.js +471 -0
- package/ui/dialogs/index.windows.js.map +1 -0
- package/ui/editable-text-base/index.windows.d.ts +27 -0
- package/ui/editable-text-base/index.windows.js +165 -0
- package/ui/editable-text-base/index.windows.js.map +1 -0
- package/ui/embedding/index.windows.d.ts +1 -0
- package/ui/embedding/index.windows.js +4 -0
- package/ui/embedding/index.windows.js.map +1 -0
- package/ui/frame/fragment.transitions.android.d.ts +13 -13
- package/ui/frame/fragment.transitions.android.js.map +1 -1
- package/ui/frame/frame-common.d.ts +1 -2
- package/ui/frame/frame-common.js +0 -10
- package/ui/frame/frame-common.js.map +1 -1
- package/ui/frame/frame-helper-for-android.d.ts +4 -4
- package/ui/frame/frame-helper-for-android.js +8 -17
- package/ui/frame/frame-helper-for-android.js.map +1 -1
- package/ui/frame/index.android.d.ts +11 -6
- package/ui/frame/index.android.js +59 -18
- package/ui/frame/index.android.js.map +1 -1
- package/ui/frame/index.d.ts +21 -12
- package/ui/frame/index.ios.d.ts +2 -2
- package/ui/frame/index.ios.js.map +1 -1
- package/ui/frame/index.windows.d.ts +52 -0
- package/ui/frame/index.windows.js +778 -0
- package/ui/frame/index.windows.js.map +1 -0
- package/ui/gestures/index.windows.d.ts +35 -0
- package/ui/gestures/index.windows.js +483 -0
- package/ui/gestures/index.windows.js.map +1 -0
- package/ui/html-view/index.windows.d.ts +18 -0
- package/ui/html-view/index.windows.js +191 -0
- package/ui/html-view/index.windows.js.map +1 -0
- package/ui/image/index.windows.d.ts +17 -0
- package/ui/image/index.windows.js +132 -0
- package/ui/image/index.windows.js.map +1 -0
- package/ui/image/symbol-effects.windows.d.ts +5 -0
- package/ui/image/symbol-effects.windows.js +8 -0
- package/ui/image/symbol-effects.windows.js.map +1 -0
- package/ui/image-cache/index.windows.d.ts +11 -0
- package/ui/image-cache/index.windows.js +48 -0
- package/ui/image-cache/index.windows.js.map +1 -0
- package/ui/label/index.ios.d.ts +5 -2
- package/ui/label/index.ios.js +44 -12
- package/ui/label/index.ios.js.map +1 -1
- package/ui/label/index.windows.d.ts +15 -0
- package/ui/label/index.windows.js +66 -0
- package/ui/label/index.windows.js.map +1 -0
- package/ui/layouts/absolute-layout/index.ios.js +1 -5
- package/ui/layouts/absolute-layout/index.ios.js.map +1 -1
- package/ui/layouts/absolute-layout/index.windows.d.ts +8 -0
- package/ui/layouts/absolute-layout/index.windows.js +47 -0
- package/ui/layouts/absolute-layout/index.windows.js.map +1 -0
- package/ui/layouts/dock-layout/index.ios.js +1 -5
- package/ui/layouts/dock-layout/index.ios.js.map +1 -1
- package/ui/layouts/dock-layout/index.windows.d.ts +19 -0
- package/ui/layouts/dock-layout/index.windows.js +202 -0
- package/ui/layouts/dock-layout/index.windows.js.map +1 -0
- package/ui/layouts/flexbox-layout/flexbox-layout-common.d.ts +17 -2
- package/ui/layouts/flexbox-layout/flexbox-layout-common.js +73 -2
- package/ui/layouts/flexbox-layout/flexbox-layout-common.js.map +1 -1
- package/ui/layouts/flexbox-layout/index.ios.js +1 -5
- package/ui/layouts/flexbox-layout/index.ios.js.map +1 -1
- package/ui/layouts/flexbox-layout/index.windows.d.ts +27 -0
- package/ui/layouts/flexbox-layout/index.windows.js +188 -0
- package/ui/layouts/flexbox-layout/index.windows.js.map +1 -0
- package/ui/layouts/grid-layout/index.ios.js +1 -5
- package/ui/layouts/grid-layout/index.ios.js.map +1 -1
- package/ui/layouts/grid-layout/index.windows.d.ts +20 -0
- package/ui/layouts/grid-layout/index.windows.js +130 -0
- package/ui/layouts/grid-layout/index.windows.js.map +1 -0
- package/ui/layouts/layout-base.android.d.ts +10 -3
- package/ui/layouts/layout-base.android.js +24 -7
- package/ui/layouts/layout-base.android.js.map +1 -1
- package/ui/layouts/layout-base.ios.js.map +1 -1
- package/ui/layouts/layout-base.windows.d.ts +4 -0
- package/ui/layouts/layout-base.windows.js +5 -0
- package/ui/layouts/layout-base.windows.js.map +1 -0
- package/ui/layouts/liquid-glass/index.windows.d.ts +4 -0
- package/ui/layouts/liquid-glass/index.windows.js +5 -0
- package/ui/layouts/liquid-glass/index.windows.js.map +1 -0
- package/ui/layouts/liquid-glass-container/index.windows.d.ts +4 -0
- package/ui/layouts/liquid-glass-container/index.windows.js +5 -0
- package/ui/layouts/liquid-glass-container/index.windows.js.map +1 -0
- package/ui/layouts/root-layout/index.windows.d.ts +13 -0
- package/ui/layouts/root-layout/index.windows.js +160 -0
- package/ui/layouts/root-layout/index.windows.js.map +1 -0
- package/ui/layouts/stack-layout/index.ios.js +1 -5
- package/ui/layouts/stack-layout/index.ios.js.map +1 -1
- package/ui/layouts/stack-layout/index.windows.d.ts +13 -0
- package/ui/layouts/stack-layout/index.windows.js +63 -0
- package/ui/layouts/stack-layout/index.windows.js.map +1 -0
- package/ui/layouts/wrap-layout/index.ios.js +1 -5
- package/ui/layouts/wrap-layout/index.ios.js.map +1 -1
- package/ui/layouts/wrap-layout/index.windows.d.ts +20 -0
- package/ui/layouts/wrap-layout/index.windows.js +182 -0
- package/ui/layouts/wrap-layout/index.windows.js.map +1 -0
- package/ui/list-picker/index.windows.d.ts +19 -0
- package/ui/list-picker/index.windows.js +75 -0
- package/ui/list-picker/index.windows.js.map +1 -0
- package/ui/list-view/index.d.ts +1 -13
- package/ui/list-view/index.ios.d.ts +1 -3
- package/ui/list-view/index.ios.js +10 -48
- package/ui/list-view/index.ios.js.map +1 -1
- package/ui/list-view/index.windows.d.ts +60 -0
- package/ui/list-view/index.windows.js +842 -0
- package/ui/list-view/index.windows.js.map +1 -0
- package/ui/list-view/list-view-common.d.ts +0 -14
- package/ui/list-view/list-view-common.js +0 -4
- package/ui/list-view/list-view-common.js.map +1 -1
- package/ui/page/index.d.ts +1 -1
- package/ui/page/index.ios.d.ts +0 -1
- package/ui/page/index.ios.js +1 -15
- package/ui/page/index.ios.js.map +1 -1
- package/ui/page/index.windows.d.ts +12 -0
- package/ui/page/index.windows.js +42 -0
- package/ui/page/index.windows.js.map +1 -0
- package/ui/page/page-common.d.ts +2 -5
- package/ui/page/page-common.js.map +1 -1
- package/ui/progress/index.windows.d.ts +20 -0
- package/ui/progress/index.windows.js +65 -0
- package/ui/progress/index.windows.js.map +1 -0
- package/ui/repeater/index.d.ts +1 -2
- package/ui/repeater/index.js.map +1 -1
- package/ui/scroll-view/index.d.ts +0 -13
- package/ui/scroll-view/index.ios.js +7 -21
- package/ui/scroll-view/index.ios.js.map +1 -1
- package/ui/scroll-view/index.windows.d.ts +29 -0
- package/ui/scroll-view/index.windows.js +192 -0
- package/ui/scroll-view/index.windows.js.map +1 -0
- package/ui/scroll-view/scroll-view-common.d.ts +0 -6
- package/ui/scroll-view/scroll-view-common.js +0 -8
- package/ui/scroll-view/scroll-view-common.js.map +1 -1
- package/ui/search-bar/index.windows.d.ts +19 -0
- package/ui/search-bar/index.windows.js +91 -0
- package/ui/search-bar/index.windows.js.map +1 -0
- package/ui/segmented-bar/index.windows.d.ts +23 -0
- package/ui/segmented-bar/index.windows.js +117 -0
- package/ui/segmented-bar/index.windows.js.map +1 -0
- package/ui/segmented-bar/segmented-bar-common.d.ts +1 -5
- package/ui/segmented-bar/segmented-bar-common.js.map +1 -1
- package/ui/slider/index.windows.d.ts +25 -0
- package/ui/slider/index.windows.js +134 -0
- package/ui/slider/index.windows.js.map +1 -0
- package/ui/split-view/index.windows.d.ts +49 -0
- package/ui/split-view/index.windows.js +549 -0
- package/ui/split-view/index.windows.js.map +1 -0
- package/ui/styling/background.windows.d.ts +2 -0
- package/ui/styling/background.windows.js +2 -0
- package/ui/styling/background.windows.js.map +1 -0
- package/ui/styling/font.d.ts +4 -0
- package/ui/styling/font.windows.d.ts +25 -0
- package/ui/styling/font.windows.js +213 -0
- package/ui/styling/font.windows.js.map +1 -0
- package/ui/styling/style/index.d.ts +0 -1
- package/ui/styling/style/index.js.map +1 -1
- package/ui/styling/style-properties.d.ts +0 -1
- package/ui/styling/style-properties.js +32 -41
- package/ui/styling/style-properties.js.map +1 -1
- package/ui/styling/style-scope.js +9 -1
- package/ui/styling/style-scope.js.map +1 -1
- package/ui/switch/index.windows.d.ts +20 -0
- package/ui/switch/index.windows.js +97 -0
- package/ui/switch/index.windows.js.map +1 -0
- package/ui/tab-view/index.ios.d.ts +1 -10
- package/ui/tab-view/index.ios.js +4 -21
- package/ui/tab-view/index.ios.js.map +1 -1
- package/ui/tab-view/index.windows.d.ts +29 -0
- package/ui/tab-view/index.windows.js +268 -0
- package/ui/tab-view/index.windows.js.map +1 -0
- package/ui/tab-view/tab-view-common.d.ts +1 -5
- package/ui/tab-view/tab-view-common.js.map +1 -1
- package/ui/text-base/index.android.d.ts +9 -2
- package/ui/text-base/index.android.js +24 -7
- package/ui/text-base/index.android.js.map +1 -1
- package/ui/text-base/index.windows.d.ts +47 -0
- package/ui/text-base/index.windows.js +639 -0
- package/ui/text-base/index.windows.js.map +1 -0
- package/ui/text-field/index.ios.d.ts +9 -2
- package/ui/text-field/index.ios.js +23 -2
- package/ui/text-field/index.ios.js.map +1 -1
- package/ui/text-field/index.windows.d.ts +23 -0
- package/ui/text-field/index.windows.js +186 -0
- package/ui/text-field/index.windows.js.map +1 -0
- package/ui/text-view/index.ios.d.ts +9 -2
- package/ui/text-view/index.ios.js +72 -20
- package/ui/text-view/index.ios.js.map +1 -1
- package/ui/text-view/index.windows.d.ts +12 -0
- package/ui/text-view/index.windows.js +47 -0
- package/ui/text-view/index.windows.js.map +1 -0
- package/ui/time-picker/index.windows.d.ts +18 -0
- package/ui/time-picker/index.windows.js +77 -0
- package/ui/time-picker/index.windows.js.map +1 -0
- package/ui/transition/fade-transition.windows.d.ts +3 -0
- package/ui/transition/fade-transition.windows.js +4 -0
- package/ui/transition/fade-transition.windows.js.map +1 -0
- package/ui/transition/index.d.ts +1 -2
- package/ui/transition/index.windows.d.ts +20 -0
- package/ui/transition/index.windows.js +30 -0
- package/ui/transition/index.windows.js.map +1 -0
- package/ui/transition/modal-transition.ios.js +5 -33
- package/ui/transition/modal-transition.ios.js.map +1 -1
- package/ui/transition/modal-transition.windows.d.ts +3 -0
- package/ui/transition/modal-transition.windows.js +4 -0
- package/ui/transition/modal-transition.windows.js.map +1 -0
- package/ui/transition/page-transition.ios.d.ts +0 -5
- package/ui/transition/page-transition.ios.js +33 -296
- package/ui/transition/page-transition.ios.js.map +1 -1
- package/ui/transition/page-transition.windows.d.ts +3 -0
- package/ui/transition/page-transition.windows.js +4 -0
- package/ui/transition/page-transition.windows.js.map +1 -0
- package/ui/transition/shared-transition-helper.android.d.ts +0 -3
- package/ui/transition/shared-transition-helper.android.js +0 -9
- package/ui/transition/shared-transition-helper.android.js.map +1 -1
- package/ui/transition/shared-transition-helper.d.ts +0 -7
- package/ui/transition/shared-transition-helper.ios.d.ts +0 -36
- package/ui/transition/shared-transition-helper.ios.js +89 -765
- package/ui/transition/shared-transition-helper.ios.js.map +1 -1
- package/ui/transition/shared-transition-helper.windows.d.ts +30 -0
- package/ui/transition/shared-transition-helper.windows.js +155 -0
- package/ui/transition/shared-transition-helper.windows.js.map +1 -0
- package/ui/transition/shared-transition.d.ts +0 -66
- package/ui/transition/shared-transition.js +2 -57
- package/ui/transition/shared-transition.js.map +1 -1
- package/ui/transition/slide-transition.windows.d.ts +3 -0
- package/ui/transition/slide-transition.windows.js +4 -0
- package/ui/transition/slide-transition.windows.js.map +1 -0
- package/ui/utils.windows.d.ts +9 -0
- package/ui/utils.windows.js +21 -0
- package/ui/utils.windows.js.map +1 -0
- package/ui/web-view/index.windows.d.ts +23 -0
- package/ui/web-view/index.windows.js +115 -0
- package/ui/web-view/index.windows.js.map +1 -0
- package/utils/constants.windows.d.ts +2 -0
- package/utils/constants.windows.js +5 -0
- package/utils/constants.windows.js.map +1 -0
- package/utils/debug-source.js +3 -0
- package/utils/debug-source.js.map +1 -1
- package/utils/index.windows.d.ts +20 -0
- package/utils/index.windows.js +94 -0
- package/utils/index.windows.js.map +1 -0
- package/utils/layout-helper/index.windows.d.ts +25 -0
- package/utils/layout-helper/index.windows.js +74 -0
- package/utils/layout-helper/index.windows.js.map +1 -0
- package/utils/mainthread-helper.windows.d.ts +3 -0
- package/utils/mainthread-helper.windows.js +18 -0
- package/utils/mainthread-helper.windows.js.map +1 -0
- package/utils/native-helper.android.d.ts +2 -66
- package/utils/native-helper.android.js.map +1 -1
- package/utils/native-helper.ios.d.ts +2 -105
- package/utils/native-helper.ios.js +4 -15
- package/utils/native-helper.ios.js.map +1 -1
- package/utils/native-helper.windows.d.ts +8 -0
- package/utils/native-helper.windows.js +101 -0
- package/utils/native-helper.windows.js.map +1 -0
- package/utils/platform-check.d.ts +1 -1
- package/utils/platform-check.js.map +1 -1
- package/utils/native-helper.types.d.ts +0 -2
|
@@ -0,0 +1,842 @@
|
|
|
1
|
+
export * from './list-view-common';
|
|
2
|
+
import { ListViewBase, itemTemplatesProperty, rowHeightProperty, separatorColorProperty } from './list-view-common';
|
|
3
|
+
import { ChangeType } from '../../data/observable-array';
|
|
4
|
+
import { Color } from '../../color';
|
|
5
|
+
import { Builder } from '../builder';
|
|
6
|
+
const ITEMLOADING = ListViewBase.itemLoadingEvent;
|
|
7
|
+
const ITEMTAP = ListViewBase.itemTapEvent;
|
|
8
|
+
const LOADMOREITEMS = ListViewBase.loadMoreItemsEvent;
|
|
9
|
+
const HEADER_KEY = '__ns_header';
|
|
10
|
+
// Fire loadMoreItems when a container this many rows from the end is realized during scroll.
|
|
11
|
+
const LOAD_MORE_THRESHOLD = 8;
|
|
12
|
+
// Above this many touched rows in one mutation, granular updates stop being a win: WinRT has no range
|
|
13
|
+
// event (only per-item or whole-collection Reset), so we defer to a single Reset via refresh() instead.
|
|
14
|
+
const GRANULAR_MAX = 64;
|
|
15
|
+
const CHOOSING_TYPE = 'Windows.Foundation.TypedEventHandler`2<Microsoft.UI.Xaml.Controls.ListViewBase,Microsoft.UI.Xaml.Controls.ChoosingItemContainerEventArgs>';
|
|
16
|
+
const CC_TYPE = 'Windows.Foundation.TypedEventHandler`2<Microsoft.UI.Xaml.Controls.ListViewBase,Microsoft.UI.Xaml.Controls.ContainerContentChangingEventArgs>';
|
|
17
|
+
// Virtualized + recycling ListView (RecyclerView/UITableView model).
|
|
18
|
+
// ItemsSource is a native IVector<IInspectable> (NSWinRT.makeItemsSource) — JS arrays can't marshal to ItemsSource.
|
|
19
|
+
// ChoosingItemContainer supplies our own ListViewItem containers so WinUI virtualizes + recycles them, avoiding the
|
|
20
|
+
// DataTemplate ContentTemplateRoot typing problem. ContainerContentChanging binds each NS view as a ViewHolder —
|
|
21
|
+
// reusing on rebind, building only on first use or template change.
|
|
22
|
+
export class ListView extends ListViewBase {
|
|
23
|
+
constructor() {
|
|
24
|
+
super(...arguments);
|
|
25
|
+
this._clickDelegate = null;
|
|
26
|
+
// Held so their JS wrappers aren't GC'd — if collected, the events fire into dead callbacks and rows never bind.
|
|
27
|
+
this._choosingDelegate = null;
|
|
28
|
+
this._ccDelegate = null;
|
|
29
|
+
this._rows = [];
|
|
30
|
+
// Data-set length at which loadMoreItems last fired; reset to -1 on refresh so a longer list can fire again.
|
|
31
|
+
this._lastLoadMoreLen = -1;
|
|
32
|
+
this._cacheLengthSet = false;
|
|
33
|
+
// The observable index vector assigned to ItemsSource. Kept so growth can extend it in place
|
|
34
|
+
// (NSWinRT.extendItemsSource) — reading lv.ItemsSource back yields an untyped proxy without IVector methods.
|
|
35
|
+
this._itemsSource = null;
|
|
36
|
+
this._viewPool = new Map();
|
|
37
|
+
this._active = new Set();
|
|
38
|
+
// Bumped on every refresh() so containers holding a view from a previous data set
|
|
39
|
+
// (torn down by _teardown) are detected and never reused.
|
|
40
|
+
this._generation = 0;
|
|
41
|
+
// Row-separator colour (drawn as a 1px composition line at each container's bottom edge); null = none.
|
|
42
|
+
this._separatorColor = null;
|
|
43
|
+
}
|
|
44
|
+
createNativeView() {
|
|
45
|
+
const lv = new Microsoft.UI.Xaml.Controls.ListView();
|
|
46
|
+
lv.IsItemClickEnabled = true;
|
|
47
|
+
lv.SelectionMode = 0; // None
|
|
48
|
+
lv.HorizontalAlignment = 3; // Stretch
|
|
49
|
+
lv.HorizontalContentAlignment = 3;
|
|
50
|
+
lv.VerticalAlignment = 3;
|
|
51
|
+
// Kill the per-container entrance/reposition animations WinUI runs on realize — pointless work
|
|
52
|
+
// per row in a recycling virtualized list.
|
|
53
|
+
try {
|
|
54
|
+
lv.ItemContainerTransitions = new Microsoft.UI.Xaml.Media.Animation.TransitionCollection();
|
|
55
|
+
}
|
|
56
|
+
catch (_e) { }
|
|
57
|
+
// ShowsScrollingPlaceholders defaults true: WinUI defers ContainerContentChanging until a fling
|
|
58
|
+
// settles, leaving blank placeholder rows mid-scroll. Off = realize+bind synchronously as rows
|
|
59
|
+
// enter view, and recycled containers keep prior content until rebound.
|
|
60
|
+
try {
|
|
61
|
+
lv.ShowsScrollingPlaceholders = false;
|
|
62
|
+
}
|
|
63
|
+
catch (_e) { }
|
|
64
|
+
// Replace the stock ListViewItem template (selection / pointer-over / pressed / focus visual states
|
|
65
|
+
// + reveal brushes we never use, re-evaluated per realized container) with a bare ContentPresenter
|
|
66
|
+
// so each container is cheap to realize. Tap still works via ItemClick.
|
|
67
|
+
try {
|
|
68
|
+
const itemStyle = Microsoft.UI.Xaml.Markup.XamlReader.Load('<Style xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" TargetType="ListViewItem">' +
|
|
69
|
+
'<Setter Property="Margin" Value="0"/><Setter Property="Padding" Value="0"/>' +
|
|
70
|
+
'<Setter Property="MinHeight" Value="0"/><Setter Property="MinWidth" Value="0"/>' +
|
|
71
|
+
'<Setter Property="HorizontalContentAlignment" Value="Stretch"/>' +
|
|
72
|
+
'<Setter Property="Template"><Setter.Value>' +
|
|
73
|
+
'<ControlTemplate TargetType="ListViewItem">' +
|
|
74
|
+
'<ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" ' +
|
|
75
|
+
'HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" ' +
|
|
76
|
+
'VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" ' +
|
|
77
|
+
'Padding="{TemplateBinding Padding}"/>' +
|
|
78
|
+
'</ControlTemplate></Setter.Value></Setter></Style>');
|
|
79
|
+
if (itemStyle)
|
|
80
|
+
lv.ItemContainerStyle = itemStyle;
|
|
81
|
+
}
|
|
82
|
+
catch (_e) { }
|
|
83
|
+
return lv;
|
|
84
|
+
}
|
|
85
|
+
initNativeView() {
|
|
86
|
+
super.initNativeView();
|
|
87
|
+
const lv = this.nativeViewProtected;
|
|
88
|
+
if (!lv)
|
|
89
|
+
return;
|
|
90
|
+
const ref = new WeakRef(this);
|
|
91
|
+
// ChoosingItemContainer/ContainerContentChanging are generic TypedEventHandlers — the runtime can't
|
|
92
|
+
// derive their parameterized GUID from a plain assignment, so build them via asDelegate.
|
|
93
|
+
try {
|
|
94
|
+
this._choosingDelegate = NSWinRT.asDelegate(CHOOSING_TYPE, (_s, args) => {
|
|
95
|
+
ref.deref()?._onChoosingItemContainer(args);
|
|
96
|
+
});
|
|
97
|
+
lv.ChoosingItemContainer = this._choosingDelegate;
|
|
98
|
+
}
|
|
99
|
+
catch (_e) { }
|
|
100
|
+
try {
|
|
101
|
+
this._ccDelegate = NSWinRT.asDelegate(CC_TYPE, (_s, args) => {
|
|
102
|
+
ref.deref()?._onContainerContentChanging(args);
|
|
103
|
+
});
|
|
104
|
+
lv.ContainerContentChanging = this._ccDelegate;
|
|
105
|
+
}
|
|
106
|
+
catch (_e) { }
|
|
107
|
+
this._clickDelegate = NSWinRT.asDelegate('Microsoft.UI.Xaml.Controls.ItemClickEventHandler', (_s, e) => {
|
|
108
|
+
const owner = ref.deref();
|
|
109
|
+
if (!owner)
|
|
110
|
+
return;
|
|
111
|
+
try {
|
|
112
|
+
const lv2 = owner.nativeViewProtected;
|
|
113
|
+
const container = lv2.ContainerFromItem(e.ClickedItem);
|
|
114
|
+
const idx = container ? container.__ns_row_index ?? -1 : -1;
|
|
115
|
+
const row = owner._rows[idx];
|
|
116
|
+
if (!row || row.header || row.globalIndex < 0)
|
|
117
|
+
return;
|
|
118
|
+
owner.notify({ eventName: ITEMTAP, object: owner, index: row.globalIndex, view: owner._findActive(row.globalIndex), section: row.section });
|
|
119
|
+
}
|
|
120
|
+
catch (_e) { }
|
|
121
|
+
});
|
|
122
|
+
lv.ItemClick = this._clickDelegate;
|
|
123
|
+
}
|
|
124
|
+
disposeNativeView() {
|
|
125
|
+
const lv = this.nativeViewProtected;
|
|
126
|
+
lv.ChoosingItemContainer = null;
|
|
127
|
+
lv.ContainerContentChanging = null;
|
|
128
|
+
lv.ItemClick = null;
|
|
129
|
+
this._clickDelegate = null;
|
|
130
|
+
this._choosingDelegate = null;
|
|
131
|
+
this._ccDelegate = null;
|
|
132
|
+
this._teardown();
|
|
133
|
+
super.disposeNativeView?.();
|
|
134
|
+
}
|
|
135
|
+
_addViewToNativeVisualTree(_child, _atIndex) {
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
_keyForData(data, globalIndex) {
|
|
139
|
+
const selector = this._itemTemplateSelector;
|
|
140
|
+
if (typeof selector === 'function') {
|
|
141
|
+
try {
|
|
142
|
+
return selector(data, globalIndex, this.items);
|
|
143
|
+
}
|
|
144
|
+
catch (_e) { }
|
|
145
|
+
}
|
|
146
|
+
return 'default';
|
|
147
|
+
}
|
|
148
|
+
_templateByKey(key) {
|
|
149
|
+
for (const t of this._itemTemplatesInternal) {
|
|
150
|
+
if (t.key === key)
|
|
151
|
+
return t;
|
|
152
|
+
}
|
|
153
|
+
return this._itemTemplatesInternal[0];
|
|
154
|
+
}
|
|
155
|
+
// True when the bound items are identical to what's already realized (same count + same data refs).
|
|
156
|
+
// nativescript-vue re-assigns `items` on unrelated re-renders (e.g. a loadingMore toggle); a naive
|
|
157
|
+
// refresh() would then replace the ItemsSource, resetting scroll to 0 and re-realizing every cell.
|
|
158
|
+
_itemsUnchanged() {
|
|
159
|
+
if (!this._itemsSource || this.sectioned)
|
|
160
|
+
return false;
|
|
161
|
+
const items = this.items;
|
|
162
|
+
const newCount = items && typeof items.length === 'number' ? items.length : 0;
|
|
163
|
+
const oldCount = this._rows.length;
|
|
164
|
+
if (oldCount === 0 || newCount !== oldCount)
|
|
165
|
+
return false;
|
|
166
|
+
for (let i = 0; i < oldCount; i++) {
|
|
167
|
+
const data = this._getDataItem ? this._getDataItem(i) : items[i];
|
|
168
|
+
if (this._rows[i].data !== data)
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
// Append-only growth (infinite-scroll loadMore appends a page): extend the existing observable
|
|
174
|
+
// ItemsSource in place so WinUI adds the new rows at the bottom — preserving scroll and realized cells
|
|
175
|
+
// — instead of replacing the source (which reset scroll to top and re-realized every cell). Returns
|
|
176
|
+
// false (→ full rebuild) for any non-append change (replace / filter / reorder / shrink).
|
|
177
|
+
_tryAppendRows(lv) {
|
|
178
|
+
const extend = (typeof NSWinRT !== 'undefined') ? NSWinRT.extendItemsSource : null;
|
|
179
|
+
if (!extend || !this._itemsSource)
|
|
180
|
+
return false;
|
|
181
|
+
const items = this.items;
|
|
182
|
+
const newCount = items && typeof items.length === 'number' ? items.length : 0;
|
|
183
|
+
const oldCount = this._rows.length;
|
|
184
|
+
if (oldCount === 0 || newCount <= oldCount)
|
|
185
|
+
return false;
|
|
186
|
+
// Only an append if the existing prefix is unchanged (same data refs) — otherwise it's a
|
|
187
|
+
// replace/filter and must go through the full rebuild.
|
|
188
|
+
for (let i = 0; i < oldCount; i++) {
|
|
189
|
+
const data = this._getDataItem ? this._getDataItem(i) : items[i];
|
|
190
|
+
if (this._rows[i].data !== data)
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
// Extend the row map first so the new indices resolve when WinUI realizes them, then grow the
|
|
194
|
+
// native observable vector (fires VectorChanged → WinUI adds just the new rows, scroll intact).
|
|
195
|
+
for (let i = oldCount; i < newCount; i++) {
|
|
196
|
+
const data = this._getDataItem ? this._getDataItem(i) : items[i];
|
|
197
|
+
this._rows.push({ header: false, templateKey: this._keyForData(data, i), globalIndex: i, data });
|
|
198
|
+
}
|
|
199
|
+
try {
|
|
200
|
+
extend(this._itemsSource, newCount);
|
|
201
|
+
}
|
|
202
|
+
catch (_e) {
|
|
203
|
+
return false; // let the full rebuild recover (replaces the source)
|
|
204
|
+
}
|
|
205
|
+
this._lastLoadMoreLen = -1; // re-arm loadMore at the new end
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
// Replace the data set (filter / search / sort / reorder) WITHOUT tearing down realized cells: a full
|
|
209
|
+
// _teardown bumps the generation and rebuilds every visible cell (element creation is the expensive
|
|
210
|
+
// part on Windows). Instead keep the views, pool and generation, rebuild only the row map, and reset
|
|
211
|
+
// the index ItemsSource — WinUI re-realizes the containers and rebinds their existing cells.
|
|
212
|
+
// Returns false (→ full rebuild) for the sectioned case or if no items source can be made.
|
|
213
|
+
_tryReplaceRows(lv) {
|
|
214
|
+
const make = (typeof NSWinRT !== 'undefined') ? NSWinRT.makeItemsSource : null;
|
|
215
|
+
if (!make)
|
|
216
|
+
return false;
|
|
217
|
+
const src = this.items;
|
|
218
|
+
const count = src && typeof src.length === 'number' ? src.length : 0;
|
|
219
|
+
const rows = [];
|
|
220
|
+
for (let i = 0; i < count; i++) {
|
|
221
|
+
const data = this._getDataItem ? this._getDataItem(i) : src[i];
|
|
222
|
+
rows.push({ header: false, templateKey: this._keyForData(data, i), globalIndex: i, data });
|
|
223
|
+
}
|
|
224
|
+
let source = null;
|
|
225
|
+
try {
|
|
226
|
+
source = make(count);
|
|
227
|
+
}
|
|
228
|
+
catch (_e) {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
this._rows = rows;
|
|
232
|
+
this._itemsSource = source;
|
|
233
|
+
try {
|
|
234
|
+
lv.ItemsSource = source;
|
|
235
|
+
}
|
|
236
|
+
catch (_e) {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
this._lastLoadMoreLen = -1;
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
refresh() {
|
|
243
|
+
const lv = this.nativeViewProtected;
|
|
244
|
+
if (!lv)
|
|
245
|
+
return;
|
|
246
|
+
if (this._itemsUnchanged())
|
|
247
|
+
return; // no-op: items identical → keep scroll + realized cells
|
|
248
|
+
if (!this.sectioned && this._tryAppendRows(lv))
|
|
249
|
+
return; // append-only growth → extend in place
|
|
250
|
+
if (!this.sectioned && this._tryReplaceRows(lv))
|
|
251
|
+
return; // replace/filter → reuse cells, rebind
|
|
252
|
+
this._teardown();
|
|
253
|
+
const rows = [];
|
|
254
|
+
if (this.sectioned) {
|
|
255
|
+
let gi = 0;
|
|
256
|
+
const sections = this._getSectionCount();
|
|
257
|
+
for (let s = 0; s < sections; s++) {
|
|
258
|
+
const sectionData = this._getSectionData ? this._getSectionData(s) : null;
|
|
259
|
+
if (this.stickyHeaderTemplate) {
|
|
260
|
+
rows.push({ header: true, templateKey: HEADER_KEY, globalIndex: -1, section: s, data: sectionData ?? { title: '' } });
|
|
261
|
+
}
|
|
262
|
+
const itemsInSection = this._getItemsInSection(s);
|
|
263
|
+
const len = itemsInSection && typeof itemsInSection.length === 'number' ? itemsInSection.length : 0;
|
|
264
|
+
for (let j = 0; j < len; j++) {
|
|
265
|
+
const data = this._getDataItemInSection(s, j);
|
|
266
|
+
rows.push({ header: false, templateKey: this._keyForData(data, gi), globalIndex: gi, section: s, indexInSection: j, data });
|
|
267
|
+
gi++;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
const src = this.items;
|
|
273
|
+
const count = src && typeof src.length === 'number' ? src.length : 0;
|
|
274
|
+
for (let i = 0; i < count; i++) {
|
|
275
|
+
const data = this._getDataItem ? this._getDataItem(i) : src[i];
|
|
276
|
+
rows.push({ header: false, templateKey: this._keyForData(data, i), globalIndex: i, data });
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
this._rows = rows;
|
|
280
|
+
try {
|
|
281
|
+
this._itemsSource = typeof NSWinRT !== 'undefined' && NSWinRT.makeItemsSource ? NSWinRT.makeItemsSource(rows.length) : null;
|
|
282
|
+
lv.ItemsSource = this._itemsSource;
|
|
283
|
+
}
|
|
284
|
+
catch (_e) { }
|
|
285
|
+
// loadMoreItems fires from _onContainerContentChanging on scroll, not here — firing on every
|
|
286
|
+
// items-set would cascade (each appended page would immediately request the next).
|
|
287
|
+
this._lastLoadMoreLen = -1;
|
|
288
|
+
}
|
|
289
|
+
_onChoosingItemContainer(args) {
|
|
290
|
+
try {
|
|
291
|
+
if (!args.ItemContainer) {
|
|
292
|
+
args.ItemContainer = this._makeContainer();
|
|
293
|
+
}
|
|
294
|
+
args.IsContainerPrepared = true;
|
|
295
|
+
}
|
|
296
|
+
catch (_e) { }
|
|
297
|
+
}
|
|
298
|
+
_makeContainer() {
|
|
299
|
+
const lvi = new Microsoft.UI.Xaml.Controls.ListViewItem();
|
|
300
|
+
lvi.HorizontalContentAlignment = 3; // Stretch
|
|
301
|
+
lvi.VerticalContentAlignment = 0; // Top
|
|
302
|
+
lvi.Padding = Microsoft.UI.Xaml.ThicknessHelper.FromUniformLength(0);
|
|
303
|
+
// Reserve a deterministic min height so a recycled container never collapses to 0
|
|
304
|
+
// before its content re-measures (0-height rows render blank and skew scroll math).
|
|
305
|
+
lvi.MinHeight = this._effectiveRowHeight && this._effectiveRowHeight > 0 ? this._effectiveRowHeight : 52;
|
|
306
|
+
return lvi;
|
|
307
|
+
}
|
|
308
|
+
// Draw (or clear) the row separator as a 1px composition line pinned to the container's bottom edge.
|
|
309
|
+
// (ListViewItem.BorderBrush isn't honoured by the ListViewItemPresenter template, so a child visual
|
|
310
|
+
// is used instead.) The sprite is created once per container and reused on recycle.
|
|
311
|
+
_applySeparator(container) {
|
|
312
|
+
if (!container)
|
|
313
|
+
return;
|
|
314
|
+
try {
|
|
315
|
+
const EP = Microsoft.UI.Xaml.Hosting.ElementCompositionPreview;
|
|
316
|
+
if (!this._separatorColor) {
|
|
317
|
+
if (container.__ns_sepVisual) {
|
|
318
|
+
EP.SetElementChildVisual(container, null);
|
|
319
|
+
container.__ns_sepVisual = null;
|
|
320
|
+
}
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
let sprite = container.__ns_sepVisual;
|
|
324
|
+
if (!sprite) {
|
|
325
|
+
const N = Windows.Foundation.Numerics;
|
|
326
|
+
const c = EP.GetElementVisual(container).Compositor;
|
|
327
|
+
sprite = c.CreateSpriteVisual();
|
|
328
|
+
sprite.RelativeSizeAdjustment = new N.Vector2(1, 0); // full width
|
|
329
|
+
sprite.Size = new N.Vector2(0, 1); // 1px tall
|
|
330
|
+
sprite.RelativeOffsetAdjustment = new N.Vector3(0, 1, 0); // anchor to the bottom edge
|
|
331
|
+
sprite.Offset = new N.Vector3(0, -1, 0); // sit just inside it
|
|
332
|
+
sprite.Brush = c.CreateColorBrush();
|
|
333
|
+
container.__ns_sepVisual = sprite;
|
|
334
|
+
EP.SetElementChildVisual(container, sprite);
|
|
335
|
+
}
|
|
336
|
+
sprite.Brush.Color = this._separatorColor;
|
|
337
|
+
}
|
|
338
|
+
catch (_e) { }
|
|
339
|
+
}
|
|
340
|
+
// Size the virtualizing panel's realization buffer once it exists. CacheLength = how many viewports
|
|
341
|
+
// of containers WinUI keeps realized (and recycled) around the visible area; a larger buffer means
|
|
342
|
+
// more fling before the recycle pool runs dry and WinUI has to mint blank containers. Cheap now that
|
|
343
|
+
// a bind is O(1), so favor a deeper buffer.
|
|
344
|
+
_ensureCacheLength() {
|
|
345
|
+
if (this._cacheLengthSet)
|
|
346
|
+
return;
|
|
347
|
+
try {
|
|
348
|
+
const panel = this.nativeViewProtected?.ItemsPanelRoot;
|
|
349
|
+
if (panel && 'CacheLength' in panel) {
|
|
350
|
+
panel.CacheLength = 8.0;
|
|
351
|
+
this._cacheLengthSet = true;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
catch (_e) { }
|
|
355
|
+
}
|
|
356
|
+
_onContainerContentChanging(args) {
|
|
357
|
+
const container = args?.ItemContainer;
|
|
358
|
+
if (!container)
|
|
359
|
+
return;
|
|
360
|
+
this._ensureCacheLength();
|
|
361
|
+
// Container leaving the viewport: keep its current view + content (do NOT clear) so it shows prior
|
|
362
|
+
// content until rebound and never flashes blank on a fling. The realize pass below reuses it for a
|
|
363
|
+
// new row by swapping the data in place.
|
|
364
|
+
if (args.InRecycleQueue) {
|
|
365
|
+
try {
|
|
366
|
+
args.Handled = true;
|
|
367
|
+
}
|
|
368
|
+
catch (_e) { }
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
const idx = args.ItemIndex;
|
|
372
|
+
const row = this._rows[idx];
|
|
373
|
+
if (!row) {
|
|
374
|
+
try {
|
|
375
|
+
args.Handled = true;
|
|
376
|
+
}
|
|
377
|
+
catch (_e) { }
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
container.__ns_row_index = idx;
|
|
381
|
+
// Scroll-driven loadMoreItems: when a container within LOAD_MORE_THRESHOLD rows of the end is
|
|
382
|
+
// realized, request the next page — once per data-set length so it never cascades.
|
|
383
|
+
const total = this._rows.length;
|
|
384
|
+
if (total > 0 && idx >= total - LOAD_MORE_THRESHOLD && this._lastLoadMoreLen !== total) {
|
|
385
|
+
this._lastLoadMoreLen = total;
|
|
386
|
+
this.notify({ eventName: LOADMOREITEMS, object: this });
|
|
387
|
+
}
|
|
388
|
+
// Reuse the container's current view only if it's from this data set AND the same template;
|
|
389
|
+
// otherwise repool it and obtain the right one.
|
|
390
|
+
let view = container.__ns_view;
|
|
391
|
+
const stale = !!view && (view.__ns_gen !== this._generation || view.__ns_templateKey !== row.templateKey);
|
|
392
|
+
// Fast path — container already displays this exact row with a live view: do nothing. WinUI
|
|
393
|
+
// re-raises ContainerContentChanging for the SAME item on every layout / scroll-settle / re-measure
|
|
394
|
+
// pass, not just on genuine recycle; without this guard each re-fires itemLoading and re-binds the
|
|
395
|
+
// cell, starving layout during a fling (blank rows, dropped frames). Bind only when data changed.
|
|
396
|
+
if (view && !stale && container.__ns_boundData === row.data) {
|
|
397
|
+
const boundNative = view?.nativeViewProtected;
|
|
398
|
+
// WinUI can null a reused container's Content even when we keep the view — restore it cheaply.
|
|
399
|
+
try {
|
|
400
|
+
if (boundNative && container.Content !== boundNative)
|
|
401
|
+
container.Content = boundNative;
|
|
402
|
+
}
|
|
403
|
+
catch (_e) { }
|
|
404
|
+
try {
|
|
405
|
+
container.IsHitTestVisible = !row.header;
|
|
406
|
+
}
|
|
407
|
+
catch (_e) { }
|
|
408
|
+
try {
|
|
409
|
+
args.Handled = true;
|
|
410
|
+
}
|
|
411
|
+
catch (_e) { }
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
// View currently hosted by this container (null once stale) — lets us tell a plain rebind, where
|
|
415
|
+
// _bind hands back the SAME view, from a real attach.
|
|
416
|
+
const attachedView = stale ? null : view;
|
|
417
|
+
if (stale) {
|
|
418
|
+
this._detach(container);
|
|
419
|
+
view = null;
|
|
420
|
+
}
|
|
421
|
+
if (!view) {
|
|
422
|
+
view = this._obtain(row);
|
|
423
|
+
}
|
|
424
|
+
// Fire itemLoading and honor a view the handler may supply/replace via args.view (the cross-platform
|
|
425
|
+
// contract; e.g. nativescript-vue builds the cell in its handler). _bind returns the effective view,
|
|
426
|
+
// which may differ from the obtained one.
|
|
427
|
+
view = this._bind(view, row);
|
|
428
|
+
const native = view?.nativeViewProtected;
|
|
429
|
+
// Reusing the same cell for a new row is just a rebind (itemLoading already updated the data), so
|
|
430
|
+
// the one-time per-view setup runs only when the hosted view actually changes: first realize,
|
|
431
|
+
// template switch, or a handler that swapped the view.
|
|
432
|
+
if (view !== attachedView) {
|
|
433
|
+
this._attach(container, view);
|
|
434
|
+
try {
|
|
435
|
+
native.HorizontalAlignment = 3;
|
|
436
|
+
}
|
|
437
|
+
catch (_e) { }
|
|
438
|
+
try {
|
|
439
|
+
native.MinHeight = (this._effectiveRowHeight && this._effectiveRowHeight > 0) ? this._effectiveRowHeight : 44;
|
|
440
|
+
}
|
|
441
|
+
catch (_e) { }
|
|
442
|
+
try {
|
|
443
|
+
container.IsHitTestVisible = !row.header;
|
|
444
|
+
}
|
|
445
|
+
catch (_e) { }
|
|
446
|
+
this._applySeparator(container);
|
|
447
|
+
}
|
|
448
|
+
// Remember the row so the fast path above can skip redundant re-binds.
|
|
449
|
+
container.__ns_boundData = row.data;
|
|
450
|
+
// Safety net: a recycled container can come back with its Content nulled; restore it.
|
|
451
|
+
try {
|
|
452
|
+
if (native && container.Content !== native)
|
|
453
|
+
container.Content = native;
|
|
454
|
+
}
|
|
455
|
+
catch (_e) { }
|
|
456
|
+
try {
|
|
457
|
+
args.Handled = true;
|
|
458
|
+
}
|
|
459
|
+
catch (_e) { }
|
|
460
|
+
}
|
|
461
|
+
// Host a view's native element inside a container, first detaching it from any previous
|
|
462
|
+
// container so one native element never has two parents.
|
|
463
|
+
_attach(container, view) {
|
|
464
|
+
const native = view?.nativeViewProtected;
|
|
465
|
+
const prev = view.__ns_container;
|
|
466
|
+
if (prev && prev !== container) {
|
|
467
|
+
try {
|
|
468
|
+
if (prev.Content === native)
|
|
469
|
+
prev.Content = null;
|
|
470
|
+
}
|
|
471
|
+
catch (_e) { }
|
|
472
|
+
if (prev.__ns_view === view)
|
|
473
|
+
prev.__ns_view = null;
|
|
474
|
+
// prev no longer holds a view → drop its bound-row marker so it re-binds when next realized.
|
|
475
|
+
prev.__ns_boundData = null;
|
|
476
|
+
}
|
|
477
|
+
container.__ns_view = view;
|
|
478
|
+
view.__ns_container = container;
|
|
479
|
+
try {
|
|
480
|
+
if (container.Content !== native)
|
|
481
|
+
container.Content = native;
|
|
482
|
+
}
|
|
483
|
+
catch (_e) { }
|
|
484
|
+
}
|
|
485
|
+
// Detach the container's view, clear its Content, and return the view to the pool
|
|
486
|
+
// (unless it's stale from a previous data set, in which case just drop it).
|
|
487
|
+
_detach(container) {
|
|
488
|
+
const view = container.__ns_view;
|
|
489
|
+
container.__ns_view = null;
|
|
490
|
+
container.__ns_boundData = null;
|
|
491
|
+
if (!view)
|
|
492
|
+
return;
|
|
493
|
+
const native = view?.nativeViewProtected;
|
|
494
|
+
try {
|
|
495
|
+
if (container.Content === native)
|
|
496
|
+
container.Content = null;
|
|
497
|
+
}
|
|
498
|
+
catch (_e) { }
|
|
499
|
+
if (view.__ns_container === container)
|
|
500
|
+
view.__ns_container = null;
|
|
501
|
+
if (view.__ns_gen === this._generation) {
|
|
502
|
+
this._recycle(view);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
_obtain(row) {
|
|
506
|
+
const key = row.templateKey;
|
|
507
|
+
const free = this._viewPool.get(key);
|
|
508
|
+
if (free && free.length) {
|
|
509
|
+
return free.pop();
|
|
510
|
+
}
|
|
511
|
+
let view = null;
|
|
512
|
+
if (row.header) {
|
|
513
|
+
const tmpl = this.stickyHeaderTemplate;
|
|
514
|
+
try {
|
|
515
|
+
view = typeof tmpl === 'function' ? tmpl() : Builder.parse(tmpl, this);
|
|
516
|
+
}
|
|
517
|
+
catch (_e) { }
|
|
518
|
+
}
|
|
519
|
+
else {
|
|
520
|
+
const t = this._templateByKey(key);
|
|
521
|
+
try {
|
|
522
|
+
view = t?.createView() ?? null;
|
|
523
|
+
}
|
|
524
|
+
catch (_e) { }
|
|
525
|
+
// No view from the template (e.g. nativescript-vue supplies the cell from its itemLoading
|
|
526
|
+
// handler instead) — _bind defers to itemLoading and only then falls back to default content.
|
|
527
|
+
}
|
|
528
|
+
if (!view) {
|
|
529
|
+
return null;
|
|
530
|
+
}
|
|
531
|
+
this._track(view, key);
|
|
532
|
+
return view;
|
|
533
|
+
}
|
|
534
|
+
// Register a view with the ListView (logical child + active set), set it up, and tag it for
|
|
535
|
+
// recycling / generation checks. Idempotent: a view already tracked is left as-is.
|
|
536
|
+
_track(view, key) {
|
|
537
|
+
view.__ns_templateKey = key;
|
|
538
|
+
view.__ns_gen = this._generation;
|
|
539
|
+
if (!view.nativeViewProtected) {
|
|
540
|
+
try {
|
|
541
|
+
view._setupUI(this._context || {});
|
|
542
|
+
}
|
|
543
|
+
catch (_e) { }
|
|
544
|
+
}
|
|
545
|
+
if (!this._active.has(view)) {
|
|
546
|
+
this._addView(view);
|
|
547
|
+
this._active.add(view);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
_bind(view, row) {
|
|
551
|
+
let effective = view;
|
|
552
|
+
if (!row.header) {
|
|
553
|
+
// itemLoading lets a handler provide or replace the cell view via args.view.
|
|
554
|
+
const args = { eventName: ITEMLOADING, object: this, index: row.globalIndex, view: effective ?? undefined, bindingContext: row.data, section: row.section };
|
|
555
|
+
this.notify(args);
|
|
556
|
+
if (args.view) {
|
|
557
|
+
if (args.view !== effective) {
|
|
558
|
+
this._track(args.view, row.templateKey);
|
|
559
|
+
}
|
|
560
|
+
effective = args.view;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
// Fall back to default content only if neither the template nor the handler supplied a view.
|
|
564
|
+
if (!effective) {
|
|
565
|
+
effective = this._getDefaultItemContent(row.globalIndex);
|
|
566
|
+
this._track(effective, row.templateKey);
|
|
567
|
+
}
|
|
568
|
+
try {
|
|
569
|
+
effective.bindingContext = row.data;
|
|
570
|
+
}
|
|
571
|
+
catch (_e) { }
|
|
572
|
+
return effective;
|
|
573
|
+
}
|
|
574
|
+
_recycle(view) {
|
|
575
|
+
const key = view.__ns_templateKey || 'default';
|
|
576
|
+
let arr = this._viewPool.get(key);
|
|
577
|
+
if (!arr) {
|
|
578
|
+
arr = [];
|
|
579
|
+
this._viewPool.set(key, arr);
|
|
580
|
+
}
|
|
581
|
+
arr.push(view);
|
|
582
|
+
}
|
|
583
|
+
_findActive(globalIndex) {
|
|
584
|
+
const row = this._rows[globalIndex];
|
|
585
|
+
if (!row)
|
|
586
|
+
return null;
|
|
587
|
+
for (const v of this._active) {
|
|
588
|
+
if (v.bindingContext === row.data)
|
|
589
|
+
return v;
|
|
590
|
+
}
|
|
591
|
+
return null;
|
|
592
|
+
}
|
|
593
|
+
_teardown() {
|
|
594
|
+
// Invalidate any views still referenced by live containers — the generation guard in
|
|
595
|
+
// _onContainerContentChanging will discard them instead of reusing torn-down views.
|
|
596
|
+
this._generation++;
|
|
597
|
+
for (const v of this._active) {
|
|
598
|
+
try {
|
|
599
|
+
this._removeView(v);
|
|
600
|
+
}
|
|
601
|
+
catch (_e) { }
|
|
602
|
+
}
|
|
603
|
+
this._active.clear();
|
|
604
|
+
this._viewPool.clear();
|
|
605
|
+
this._rows = [];
|
|
606
|
+
this._itemsSource = null;
|
|
607
|
+
try {
|
|
608
|
+
this.nativeViewProtected.ItemsSource = null;
|
|
609
|
+
}
|
|
610
|
+
catch (_e) { }
|
|
611
|
+
}
|
|
612
|
+
eachChildView(callback) {
|
|
613
|
+
for (const v of this._active) {
|
|
614
|
+
if (!callback(v))
|
|
615
|
+
break;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
isItemAtIndexVisible(index) {
|
|
619
|
+
try {
|
|
620
|
+
return !!this.nativeViewProtected?.ContainerFromIndex(index);
|
|
621
|
+
}
|
|
622
|
+
catch (_e) {
|
|
623
|
+
return false;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
scrollToIndex(index) {
|
|
627
|
+
this._scrollToIndexCore(index, false);
|
|
628
|
+
}
|
|
629
|
+
scrollToIndexAnimated(index) {
|
|
630
|
+
this._scrollToIndexCore(index, true);
|
|
631
|
+
}
|
|
632
|
+
_scrollToIndexCore(index, animated) {
|
|
633
|
+
const lv = this.nativeViewProtected;
|
|
634
|
+
if (!lv)
|
|
635
|
+
return;
|
|
636
|
+
try {
|
|
637
|
+
const count = this._rows.length || 1;
|
|
638
|
+
const extent = NativeScript.Widgets.ScrollHelper.GetExtentHeight(lv);
|
|
639
|
+
if (extent > 0) {
|
|
640
|
+
const clamped = Math.max(0, Math.min(index, count - 1));
|
|
641
|
+
NativeScript.Widgets.ScrollHelper.ScrollToVerticalOffset(lv, (extent / count) * clamped, !animated);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
catch (_e) { }
|
|
645
|
+
}
|
|
646
|
+
onLoaded() {
|
|
647
|
+
super.onLoaded();
|
|
648
|
+
this.refresh();
|
|
649
|
+
}
|
|
650
|
+
// Granular ObservableArray updates — edit `_rows` and the native index ItemsSource in place (each op
|
|
651
|
+
// fires VectorChanged → WinUI realizes/drops only the touched containers), preserving scroll and every
|
|
652
|
+
// other realized cell. Anything we can't map to a reliable position (sectioned list, missing source,
|
|
653
|
+
// an insert whose prefix we can't verify, unknown action) falls back to refresh(). Safe because the
|
|
654
|
+
// native lookup is position-based (_rows[args.ItemIndex]), so the vector only needs the right length
|
|
655
|
+
// and VectorChanged events; element values go unread.
|
|
656
|
+
_onItemsChanged(data) {
|
|
657
|
+
const lv = this.nativeViewProtected;
|
|
658
|
+
const NS = typeof NSWinRT !== 'undefined' ? NSWinRT : null;
|
|
659
|
+
if (!lv || this.sectioned || !this._itemsSource || !NS || !data) {
|
|
660
|
+
this.refresh();
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
const items = this.items;
|
|
664
|
+
const newCount = items && typeof items.length === 'number' ? items.length : 0;
|
|
665
|
+
const oldCount = this._rows.length;
|
|
666
|
+
const removedCount = data.removed ? data.removed.length : 0;
|
|
667
|
+
const addedCount = data.addedCount || 0;
|
|
668
|
+
try {
|
|
669
|
+
switch (data.action) {
|
|
670
|
+
case ChangeType.Update: {
|
|
671
|
+
// setItem(i, value): one row's data replaced; count unchanged → fire ItemChanged.
|
|
672
|
+
const i = data.index;
|
|
673
|
+
if (i == null || i < 0 || i >= oldCount || newCount !== oldCount || !NS.updateItemsSource)
|
|
674
|
+
break;
|
|
675
|
+
this._rows[i] = this._makeRow(i);
|
|
676
|
+
NS.updateItemsSource(this._itemsSource, i, 1);
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
679
|
+
case ChangeType.Delete: {
|
|
680
|
+
// pop() reports index null → it removed the trailing `count` items. A front/middle
|
|
681
|
+
// removal (e.g. shift) reports null too but shifts positions, so the prefix check rejects it.
|
|
682
|
+
const count = removedCount || oldCount - newCount;
|
|
683
|
+
const start = data.index == null ? oldCount - count : data.index;
|
|
684
|
+
if (count <= 0 || start < 0 || start + count > oldCount || newCount !== oldCount - count)
|
|
685
|
+
break;
|
|
686
|
+
if (count > GRANULAR_MAX) {
|
|
687
|
+
this._resetRowsAndSource();
|
|
688
|
+
return;
|
|
689
|
+
} // bulk → one Reset, not N events
|
|
690
|
+
if (!NS.removeItemsSource || !this._prefixMatches(start))
|
|
691
|
+
break;
|
|
692
|
+
this._rows.splice(start, count);
|
|
693
|
+
this._renumberRowsFrom(start);
|
|
694
|
+
NS.removeItemsSource(this._itemsSource, start, count);
|
|
695
|
+
this._lastLoadMoreLen = -1;
|
|
696
|
+
return;
|
|
697
|
+
}
|
|
698
|
+
case ChangeType.Add: {
|
|
699
|
+
// push() reports index null → appended at the end. unshift() also reports null but
|
|
700
|
+
// inserts at the front; the prefix check rejects it (positions shifted) → refresh().
|
|
701
|
+
const count = addedCount || newCount - oldCount;
|
|
702
|
+
const start = data.index == null ? oldCount : data.index;
|
|
703
|
+
if (count <= 0 || start < 0 || start > oldCount || newCount !== oldCount + count)
|
|
704
|
+
break;
|
|
705
|
+
if (!NS.insertItemsSource || !this._prefixMatches(start))
|
|
706
|
+
break;
|
|
707
|
+
this._spliceRowsIn(start, count);
|
|
708
|
+
this._renumberRowsFrom(start);
|
|
709
|
+
NS.insertItemsSource(this._itemsSource, start, count);
|
|
710
|
+
this._lastLoadMoreLen = -1;
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
case ChangeType.Splice: {
|
|
714
|
+
const start = data.index;
|
|
715
|
+
if (start == null || start < 0 || start > oldCount || start + removedCount > oldCount)
|
|
716
|
+
break;
|
|
717
|
+
if (newCount !== oldCount - removedCount + addedCount)
|
|
718
|
+
break;
|
|
719
|
+
if (removedCount + addedCount > GRANULAR_MAX) {
|
|
720
|
+
this._resetRowsAndSource();
|
|
721
|
+
return;
|
|
722
|
+
} // bulk → one Reset
|
|
723
|
+
if (!NS.removeItemsSource || !NS.insertItemsSource || !this._prefixMatches(start))
|
|
724
|
+
break;
|
|
725
|
+
// Remove first, then insert at the same start — the intermediate state (both shrunk by
|
|
726
|
+
// removedCount) is self-consistent for any synchronous WinUI re-realize.
|
|
727
|
+
if (removedCount > 0) {
|
|
728
|
+
this._rows.splice(start, removedCount);
|
|
729
|
+
NS.removeItemsSource(this._itemsSource, start, removedCount);
|
|
730
|
+
}
|
|
731
|
+
if (addedCount > 0) {
|
|
732
|
+
this._spliceRowsIn(start, addedCount);
|
|
733
|
+
NS.insertItemsSource(this._itemsSource, start, addedCount);
|
|
734
|
+
}
|
|
735
|
+
this._renumberRowsFrom(start);
|
|
736
|
+
this._lastLoadMoreLen = -1;
|
|
737
|
+
return;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
catch (_e) {
|
|
742
|
+
// fall through to refresh
|
|
743
|
+
}
|
|
744
|
+
// Couldn't apply granularly (or it threw) → safe full rebuild.
|
|
745
|
+
this.refresh();
|
|
746
|
+
}
|
|
747
|
+
// Bulk change → rebuild the row map from the mutated collection and fire ONE VectorChanged(Reset) on
|
|
748
|
+
// the existing index vector (same ItemsSource instance), since WinRT has no range event. WinUI then
|
|
749
|
+
// re-realizes only the visible containers; off-screen rows rebind lazily from `_rows`. Falls back to
|
|
750
|
+
// refresh() if the reset shim is unavailable.
|
|
751
|
+
_resetRowsAndSource() {
|
|
752
|
+
const NS = typeof NSWinRT !== 'undefined' ? NSWinRT : null;
|
|
753
|
+
const lv = this.nativeViewProtected;
|
|
754
|
+
if (!lv || this.sectioned || !this._itemsSource || !NS || !NS.resetItemsSource) {
|
|
755
|
+
this.refresh();
|
|
756
|
+
return;
|
|
757
|
+
}
|
|
758
|
+
const items = this.items;
|
|
759
|
+
const count = items && typeof items.length === 'number' ? items.length : 0;
|
|
760
|
+
const rows = [];
|
|
761
|
+
for (let i = 0; i < count; i++) {
|
|
762
|
+
const data = this._getDataItem ? this._getDataItem(i) : items[i];
|
|
763
|
+
rows.push({ header: false, templateKey: this._keyForData(data, i), globalIndex: i, data });
|
|
764
|
+
}
|
|
765
|
+
this._rows = rows;
|
|
766
|
+
try {
|
|
767
|
+
NS.resetItemsSource(this._itemsSource, count);
|
|
768
|
+
}
|
|
769
|
+
catch (_e) {
|
|
770
|
+
this.refresh();
|
|
771
|
+
return;
|
|
772
|
+
}
|
|
773
|
+
this._lastLoadMoreLen = -1;
|
|
774
|
+
}
|
|
775
|
+
// Build the non-sectioned Row for position `i` (globalIndex === position) from the mutated items collection.
|
|
776
|
+
_makeRow(i) {
|
|
777
|
+
const items = this.items;
|
|
778
|
+
const data = this._getDataItem ? this._getDataItem(i) : items[i];
|
|
779
|
+
return { header: false, templateKey: this._keyForData(data, i), globalIndex: i, data };
|
|
780
|
+
}
|
|
781
|
+
// Insert `count` freshly-built rows at `start` (call BEFORE the native insert so a synchronous
|
|
782
|
+
// re-realize finds them).
|
|
783
|
+
_spliceRowsIn(start, count) {
|
|
784
|
+
const made = [];
|
|
785
|
+
for (let k = 0; k < count; k++) {
|
|
786
|
+
made.push(this._makeRow(start + k));
|
|
787
|
+
}
|
|
788
|
+
this._rows.splice(start, 0, ...made);
|
|
789
|
+
}
|
|
790
|
+
// Re-sync globalIndex (== array position when not sectioned) for rows shifted by an insert/remove.
|
|
791
|
+
_renumberRowsFrom(start) {
|
|
792
|
+
for (let i = start; i < this._rows.length; i++) {
|
|
793
|
+
this._rows[i].globalIndex = i;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
// True when realized rows [0, n) still hold the same data refs as the mutated collection — i.e. the
|
|
797
|
+
// mutation was at/after `n`, so earlier positions line up and a granular edit at `n` is safe.
|
|
798
|
+
_prefixMatches(n) {
|
|
799
|
+
if (n > this._rows.length)
|
|
800
|
+
return false;
|
|
801
|
+
const items = this.items;
|
|
802
|
+
for (let i = 0; i < n; i++) {
|
|
803
|
+
const data = this._getDataItem ? this._getDataItem(i) : items[i];
|
|
804
|
+
if (this._rows[i].data !== data)
|
|
805
|
+
return false;
|
|
806
|
+
}
|
|
807
|
+
return true;
|
|
808
|
+
}
|
|
809
|
+
[itemTemplatesProperty.getDefault]() {
|
|
810
|
+
return null;
|
|
811
|
+
}
|
|
812
|
+
[itemTemplatesProperty.setNative](value) {
|
|
813
|
+
this._itemTemplatesInternal = new Array(this._defaultTemplate);
|
|
814
|
+
if (value) {
|
|
815
|
+
this._itemTemplatesInternal = this._itemTemplatesInternal.concat(value);
|
|
816
|
+
}
|
|
817
|
+
if (this.nativeViewProtected)
|
|
818
|
+
this.refresh();
|
|
819
|
+
}
|
|
820
|
+
[rowHeightProperty.getDefault]() {
|
|
821
|
+
return 'auto';
|
|
822
|
+
}
|
|
823
|
+
[rowHeightProperty.setNative](_value) { }
|
|
824
|
+
[separatorColorProperty.getDefault]() {
|
|
825
|
+
return null;
|
|
826
|
+
}
|
|
827
|
+
// @ts-ignore — setNative is a symbol index whose value type is widened across properties.
|
|
828
|
+
[separatorColorProperty.setNative](value) {
|
|
829
|
+
this._separatorColor = value instanceof Color ? value.windows : null;
|
|
830
|
+
const lv = this.nativeViewProtected;
|
|
831
|
+
if (!lv)
|
|
832
|
+
return;
|
|
833
|
+
// Update already-realized containers; off-screen ones pick it up via _onContainerContentChanging.
|
|
834
|
+
for (let i = 0; i < this._rows.length; i++) {
|
|
835
|
+
try {
|
|
836
|
+
this._applySeparator(lv.ContainerFromIndex(i));
|
|
837
|
+
}
|
|
838
|
+
catch (_e) { }
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
//# sourceMappingURL=index.windows.js.map
|