diff --git a/.eslintrc.json b/.eslintrc.json index 7294a8b0e5..85636e335a 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -104,5 +104,6 @@ "lit/attribute-value-entities": 0 }, "plugins": ["disable", "import", "lit", "prettier", "@typescript-eslint"], - "processor": "disable/disable" + "processor": "disable/disable", + "ignorePatterns": ["src/resources/lit-virtualizer/*"] } diff --git a/.gitignore b/.gitignore index 317cc85ab2..3040ca0d9d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,17 @@ +.DS_Store +.reify-cache + +# build build build-translations/* +hass_frontend/* +dist + +# yarn +.yarn +yarn-error.log node_modules/* npm-debug.log -.DS_Store -hass_frontend/* -.reify-cache # Python stuff *.py[cod] @@ -14,11 +21,8 @@ hass_frontend/* # venv stuff pyvenv.cfg pip-selfcheck.json -venv +venv/* .venv -lib -bin -dist # vscode .vscode/* @@ -31,9 +35,8 @@ src/cast/dev_const.ts # Secrets .lokalise_token -yarn-error.log -#asdf +# asdf .tool-versions # Home Assistant config diff --git a/build-scripts/webpack.js b/build-scripts/webpack.js index d3e50ebd78..fe025abac2 100644 --- a/build-scripts/webpack.js +++ b/build-scripts/webpack.js @@ -116,8 +116,9 @@ const createWebpackConfig = ({ // We need to change the import of the polyfill for EventTarget, so we replace the polyfill file with our customized one new webpack.NormalModuleReplacementPlugin( new RegExp( - require.resolve( - "@lit-labs/virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/EventTarget.js" + path.resolve( + paths.polymer_dir, + "src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/EventTarget.js" ) ), path.resolve(paths.polymer_dir, "src/resources/EventTarget-ponyfill.js") diff --git a/setup.py b/setup.py index e5030abd42..32ad5f3e1a 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name="home-assistant-frontend", - version="20210531.1", + version="20210601.0", description="The Home Assistant frontend", url="https://github.com/home-assistant/home-assistant-polymer", author="The Home Assistant Authors", diff --git a/src/components/data-table/ha-data-table.ts b/src/components/data-table/ha-data-table.ts index b3b8080e07..0811669c51 100644 --- a/src/components/data-table/ha-data-table.ts +++ b/src/components/data-table/ha-data-table.ts @@ -1,4 +1,4 @@ -import { Layout1d, scroll } from "@lit-labs/virtualizer"; +import { Layout1d, scroll } from "../../resources/lit-virtualizer"; import deepClone from "deep-clone-simple"; import { css, @@ -340,11 +340,10 @@ export class HaDataTable extends LitElement { ${scroll({ items: this._items, layout: Layout1d, - // @ts-expect-error renderItem: (row: DataTableRowData, index) => { // not sure how this happens... if (!row) { - return ""; + return html``; } if (row.append) { return html` diff --git a/src/dialogs/more-info/controls/more-info-weather.ts b/src/dialogs/more-info/controls/more-info-weather.ts index 3b69a35a7a..4fe0407ea4 100644 --- a/src/dialogs/more-info/controls/more-info-weather.ts +++ b/src/dialogs/more-info/controls/more-info-weather.ts @@ -108,7 +108,7 @@ class MoreInfoWeather extends LitElement { this.stateObj.attributes.pressure, this.hass.locale )} - ${getWeatherUnit(this.hass, "air_pressure")} + ${getWeatherUnit(this.hass, "pressure")} ` diff --git a/src/dialogs/quick-bar/ha-quick-bar.ts b/src/dialogs/quick-bar/ha-quick-bar.ts index e00565e59a..5b39620c92 100644 --- a/src/dialogs/quick-bar/ha-quick-bar.ts +++ b/src/dialogs/quick-bar/ha-quick-bar.ts @@ -1,4 +1,4 @@ -import { Layout1d, scroll } from "@lit-labs/virtualizer"; +import { Layout1d, scroll } from "../../resources/lit-virtualizer"; import "@material/mwc-list/mwc-list"; import type { List } from "@material/mwc-list/mwc-list"; import { SingleSelectedEvent } from "@material/mwc-list/mwc-list-foundation"; @@ -188,7 +188,6 @@ export class QuickBar extends LitElement { ${scroll({ items, layout: Layout1d, - // @ts-expect-error renderItem: (item: QuickBarItem, index) => this._renderItem(item, index), })} @@ -224,7 +223,7 @@ export class QuickBar extends LitElement { private _renderItem(item: QuickBarItem, index?: number) { if (!item) { - return undefined; + return html``; } return isCommandItem(item) ? this._renderCommandItem(item, index) diff --git a/src/panels/logbook/ha-logbook.ts b/src/panels/logbook/ha-logbook.ts index 87c1402869..3c62b1c3af 100644 --- a/src/panels/logbook/ha-logbook.ts +++ b/src/panels/logbook/ha-logbook.ts @@ -1,4 +1,4 @@ -import { Layout1d, scroll } from "@lit-labs/virtualizer"; +import { Layout1d, scroll } from "../../resources/lit-virtualizer"; import { css, CSSResultGroup, @@ -100,7 +100,6 @@ class HaLogbook extends LitElement { ? scroll({ items: this.entries, layout: Layout1d, - // @ts-expect-error renderItem: (item: LogbookEntry, index) => this._renderLogbookItem(item, index), }) diff --git a/src/resources/lit-virtualizer/lib/lit-virtualizer.d.ts b/src/resources/lit-virtualizer/lib/lit-virtualizer.d.ts new file mode 100644 index 0000000000..1971dce046 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/lit-virtualizer.d.ts @@ -0,0 +1,39 @@ +import { LitElement, TemplateResult } from "lit"; +import { + LayoutSpecifier, + Layout, + LayoutConstructor, +} from "./uni-virtualizer/lib/layouts/Layout.js"; +/** + * A LitElement wrapper of the scroll directive. + * + * Import this module to declare the lit-virtualizer custom element. + * Pass an items array, renderItem method, and scroll target as properties + * to the element. + */ +export declare class LitVirtualizer extends LitElement { + renderItem?: (item: any, index?: number) => TemplateResult; + items: Array; + scrollTarget: Element | Window; + keyFunction: ((item: unknown) => unknown) | undefined; + private _layout; + private _scrollToIndex; + createRenderRoot(): this; + /** + * The method used for rendering each item. + */ + set layout(layout: Layout | LayoutConstructor | LayoutSpecifier | null); + get layout(): Layout | LayoutConstructor | LayoutSpecifier | null; + /** + * Scroll to the specified index, placing that item at the given position + * in the scroll view. + */ + scrollToIndex(index: number, position?: string): Promise; + render(): TemplateResult; +} +declare global { + interface HTMLElementTagNameMap { + "lit-virtualizer": LitVirtualizer; + } +} +//# sourceMappingURL=lit-virtualizer.d.ts.map diff --git a/src/resources/lit-virtualizer/lib/lit-virtualizer.d.ts.map b/src/resources/lit-virtualizer/lib/lit-virtualizer.d.ts.map new file mode 100644 index 0000000000..763404320e --- /dev/null +++ b/src/resources/lit-virtualizer/lib/lit-virtualizer.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"lit-virtualizer.d.ts","sourceRoot":"","sources":["../src/lib/lit-virtualizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,UAAU,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAKvD,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAErG;;;;;;GAMG;AACH,qBACa,cAAe,SAAQ,UAAU;IAE1C,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,cAAc,CAAC,CAAC;IAG7D,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAM;IAG3B,YAAY,EAAE,OAAO,GAAG,MAAM,CAAQ;IAGtC,WAAW,EAAE,CAAC,CAAC,IAAI,EAAC,OAAO,KAAK,OAAO,CAAC,GAAG,SAAS,CAAa;IAEjE,OAAO,CAAC,OAAO,CAA6D;IAE5E,OAAO,CAAC,cAAc,CAAkD;IAExE,gBAAgB;IAahB;;OAEG;IAWH,IACI,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,GAAG,eAAe,GAAG,IAAI,EAIrE;IAED,IAAI,MAAM,IAAI,MAAM,GAAG,iBAAiB,GAAG,eAAe,GAAG,IAAI,CAEhE;IAGD;;;OAGG;IACG,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAgB;IAO7D,MAAM,IAAI,cAAc;CAO3B;AAED,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,qBAAqB;QAC3B,iBAAiB,EAAE,cAAc,CAAC;KACrC;CACJ"} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/lit-virtualizer.js b/src/resources/lit-virtualizer/lib/lit-virtualizer.js new file mode 100644 index 0000000000..1d5cfab019 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/lit-virtualizer.js @@ -0,0 +1,118 @@ +var __decorate = + (this && this.__decorate) || + function (decorators, target, key, desc) { + var c = arguments.length, + r = + c < 3 + ? target + : desc === null + ? (desc = Object.getOwnPropertyDescriptor(target, key)) + : desc, + d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") + r = Reflect.decorate(decorators, target, key, desc); + else + for (var i = decorators.length - 1; i >= 0; i--) + if ((d = decorators[i])) + r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; + }; +import { html, LitElement } from "lit"; +import { customElement } from "lit/decorators/custom-element.js"; +import { property } from "lit/decorators/property.js"; +import { scroll } from "./scroll.js"; +import { scrollerRef } from "./uni-virtualizer/lib/VirtualScroller.js"; +/** + * A LitElement wrapper of the scroll directive. + * + * Import this module to declare the lit-virtualizer custom element. + * Pass an items array, renderItem method, and scroll target as properties + * to the element. + */ +let LitVirtualizer = class LitVirtualizer extends LitElement { + constructor() { + super(...arguments); + this.items = []; + this.scrollTarget = this; + this.keyFunction = undefined; + this._layout = null; + this._scrollToIndex = null; + } + createRenderRoot() { + return this; + } + // get items() { + // return this._items; + // } + // set items(items) { + // this._items = items; + // this._scroller.totalItems = items.length; + // } + /** + * The method used for rendering each item. + */ + // get renderItem() { + // return this._renderItem; + // } + // set renderItem(renderItem) { + // if (renderItem !== this.renderItem) { + // this._renderItem = renderItem; + // this.requestUpdate(); + // } + // } + set layout(layout) { + // TODO (graynorton): Shouldn't have to set this here + this._layout = layout; + this.requestUpdate(); + } + get layout() { + return this[scrollerRef].layout; + } + /** + * Scroll to the specified index, placing that item at the given position + * in the scroll view. + */ + async scrollToIndex(index, position = "start") { + this._scrollToIndex = { index, position }; + this.requestUpdate(); + await this.updateComplete; + this._scrollToIndex = null; + } + render() { + const { items, renderItem, keyFunction, scrollTarget } = this; + const layout = this._layout; + return html` + ${scroll({ + items, + renderItem, + layout, + keyFunction, + scrollTarget, + scrollToIndex: this._scrollToIndex, + })} + `; + } +}; +__decorate([property()], LitVirtualizer.prototype, "renderItem", void 0); +__decorate( + [property({ attribute: false })], + LitVirtualizer.prototype, + "items", + void 0 +); +__decorate( + [property({ attribute: false })], + LitVirtualizer.prototype, + "scrollTarget", + void 0 +); +__decorate([property()], LitVirtualizer.prototype, "keyFunction", void 0); +__decorate( + [property({ attribute: false })], + LitVirtualizer.prototype, + "layout", + null +); +LitVirtualizer = __decorate([customElement("lit-virtualizer")], LitVirtualizer); +export { LitVirtualizer }; +//# sourceMappingURL=lit-virtualizer.js.map diff --git a/src/resources/lit-virtualizer/lib/lit-virtualizer.js.map b/src/resources/lit-virtualizer/lib/lit-virtualizer.js.map new file mode 100644 index 0000000000..54c885bd14 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/lit-virtualizer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"lit-virtualizer.js","sourceRoot":"","sources":["../src/lib/lit-virtualizer.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAkB,MAAM,KAAK,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,WAAW,EAAoB,MAAM,0CAA0C,CAAC;AAGzF;;;;;;GAMG;AAEH,IAAa,cAAc,GAA3B,MAAa,cAAe,SAAQ,UAAU;IAA9C;;QAKI,UAAK,GAAmB,EAAE,CAAC;QAG3B,iBAAY,GAAqB,IAAI,CAAC;QAGtC,gBAAW,GAA4C,SAAS,CAAC;QAEzD,YAAO,GAAwD,IAAI,CAAC;QAEpE,mBAAc,GAA6C,IAAI,CAAC;IA0D5E,CAAC;IAxDG,gBAAgB;QACZ,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,gBAAgB;IAChB,0BAA0B;IAC1B,IAAI;IAEJ,qBAAqB;IACrB,2BAA2B;IAC3B,gDAAgD;IAChD,IAAI;IAEJ;;OAEG;IACH,qBAAqB;IACrB,+BAA+B;IAC/B,IAAI;IACJ,+BAA+B;IAC/B,4CAA4C;IAC5C,yCAAyC;IACzC,gCAAgC;IAChC,QAAQ;IACR,IAAI;IAGJ,IAAI,MAAM,CAAC,MAA2D;QAClE,qDAAqD;QACrD,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,aAAa,EAAE,CAAC;IACzB,CAAC;IAED,IAAI,MAAM;QACN,OAAQ,IAAyB,CAAC,WAAW,CAAE,CAAC,MAAM,CAAC;IAC3D,CAAC;IAGD;;;OAGG;IACH,KAAK,CAAC,aAAa,CAAC,KAAa,EAAE,WAAmB,OAAO;QACzD,IAAI,CAAC,cAAc,GAAG,EAAC,KAAK,EAAE,QAAQ,EAAC,CAAC;QACxC,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,MAAM,IAAI,CAAC,cAAc,CAAC;QAC1B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;IAC/B,CAAC;IAED,MAAM;QACF,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;QAC9D,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;QAC5B,OAAO,IAAI,CAAA;cACL,MAAM,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC;SACzG,CAAC;IACN,CAAC;CACJ,CAAA;AAvEG;IADC,QAAQ,EAAE;kDACkD;AAG7D;IADC,QAAQ,CAAC,EAAC,SAAS,EAAE,KAAK,EAAC,CAAC;6CACF;AAG3B;IADC,QAAQ,CAAC,EAAC,SAAS,EAAE,KAAK,EAAC,CAAC;oDACS;AAGtC;IADC,QAAQ,EAAE;mDACsD;AAiCjE;IADC,QAAQ,CAAC,EAAC,SAAS,EAAC,KAAK,EAAC,CAAC;4CAK3B;AAhDQ,cAAc;IAD1B,aAAa,CAAC,iBAAiB,CAAC;GACpB,cAAc,CAyE1B;SAzEY,cAAc","sourcesContent":["import { html, LitElement, TemplateResult } from 'lit';\nimport { customElement } from 'lit/decorators/custom-element.js';\nimport { property } from 'lit/decorators/property.js';\nimport { scroll } from './scroll.js';\nimport { scrollerRef, ContainerElement } from './uni-virtualizer/lib/VirtualScroller.js';\nimport { LayoutSpecifier, Layout, LayoutConstructor } from './uni-virtualizer/lib/layouts/Layout.js';\n\n/**\n * A LitElement wrapper of the scroll directive.\n *\n * Import this module to declare the lit-virtualizer custom element.\n * Pass an items array, renderItem method, and scroll target as properties\n * to the element.\n */\n@customElement('lit-virtualizer')\nexport class LitVirtualizer extends LitElement {\n @property()\n renderItem?: ((item: any, index?: number) => TemplateResult);\n\n @property({attribute: false})\n items: Array = [];\n\n @property({attribute: false})\n scrollTarget: Element | Window = this;\n\n @property()\n keyFunction: ((item:unknown) => unknown) | undefined = undefined;\n\n private _layout: Layout | LayoutConstructor | LayoutSpecifier | null = null;\n\n private _scrollToIndex: {index: number, position: string} | null = null;\n \n createRenderRoot() {\n return this;\n }\n\n // get items() {\n // return this._items;\n // }\n\n // set items(items) {\n // this._items = items;\n // this._scroller.totalItems = items.length;\n // }\n\n /**\n * The method used for rendering each item.\n */\n // get renderItem() {\n // return this._renderItem;\n // }\n // set renderItem(renderItem) {\n // if (renderItem !== this.renderItem) {\n // this._renderItem = renderItem;\n // this.requestUpdate();\n // }\n // }\n\n @property({attribute:false})\n set layout(layout: Layout | LayoutConstructor | LayoutSpecifier | null) {\n // TODO (graynorton): Shouldn't have to set this here\n this._layout = layout;\n this.requestUpdate();\n }\n\n get layout(): Layout | LayoutConstructor | LayoutSpecifier | null {\n return (this as ContainerElement)[scrollerRef]!.layout;\n }\n \n \n /**\n * Scroll to the specified index, placing that item at the given position\n * in the scroll view.\n */\n async scrollToIndex(index: number, position: string = 'start') {\n this._scrollToIndex = {index, position};\n this.requestUpdate();\n await this.updateComplete;\n this._scrollToIndex = null;\n }\n\n render(): TemplateResult {\n const { items, renderItem, keyFunction, scrollTarget } = this;\n const layout = this._layout;\n return html`\n ${scroll({ items, renderItem, layout, keyFunction, scrollTarget, scrollToIndex: this._scrollToIndex })}\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lit-virtualizer': LitVirtualizer;\n }\n}"]} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/scroll.d.ts b/src/resources/lit-virtualizer/lib/scroll.d.ts new file mode 100644 index 0000000000..fa31951222 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/scroll.d.ts @@ -0,0 +1,61 @@ +import { TemplateResult, ChildPart } from "lit"; +import { PartInfo } from "lit/directive.js"; +import { AsyncDirective } from "lit/async-directive.js"; +import { + Layout, + LayoutConstructor, + LayoutSpecifier, +} from "./uni-virtualizer/lib/layouts/Layout.js"; +import { + VirtualScroller, + ScrollToIndexValue, +} from "./uni-virtualizer/lib/VirtualScroller.js"; +/** + * Configuration options for the scroll directive. + */ +interface ScrollConfig { + /** + * A function that returns a lit-html TemplateResult. It will be used + * to generate the DOM for each item in the virtual list. + */ + renderItem?: (item: any, index?: number) => TemplateResult; + keyFunction?: (item: any) => unknown; + layout?: Layout | LayoutConstructor | LayoutSpecifier | null; + /** + * An element that receives scroll events for the virtual scroller. + */ + scrollTarget?: Element | Window; + /** + * The list of items to display via the renderItem function. + */ + items?: Array; + /** + * Limit for the number of items to display. Defaults to the length of the + * items array. + */ + totalItems?: number; + /** + * Index and position of the item to scroll to. + */ + scrollToIndex?: ScrollToIndexValue; +} +export declare const defaultKeyFunction: (item: any) => any; +export declare const defaultRenderItem: (item: any) => TemplateResult<1>; +declare class ScrollDirective extends AsyncDirective { + container: HTMLElement | null; + scroller: VirtualScroller | null; + first: number; + last: number; + renderItem: (item: any, index?: number) => TemplateResult; + keyFunction: (item: any) => unknown; + items: Array; + constructor(part: PartInfo); + render(config?: ScrollConfig): unknown; + update(part: ChildPart, [config]: [ScrollConfig]): unknown; + private _initialize; +} +export declare const scroll: ( + config?: ScrollConfig | undefined +) => import("lit-html/directive").DirectiveResult; +export {}; +//# sourceMappingURL=scroll.d.ts.map diff --git a/src/resources/lit-virtualizer/lib/scroll.d.ts.map b/src/resources/lit-virtualizer/lib/scroll.d.ts.map new file mode 100644 index 0000000000..5278da9ef9 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/scroll.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"scroll.d.ts","sourceRoot":"","sources":["../src/lib/scroll.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAW,SAAS,EAAQ,MAAM,KAAK,CAAC;AAC/D,OAAO,EAAa,QAAQ,EAAY,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AACrG,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAE/F;;GAEG;AACH,UAAU,YAAY;IAClB;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,cAAc,CAAC;IAE3D,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC;IAGrC,MAAM,CAAC,EAAE,MAAM,GAAG,iBAAiB,GAAG,eAAe,GAAG,IAAI,CAAC;IAE7D;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAEhC;;OAEG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAEnB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,aAAa,CAAC,EAAE,kBAAkB,CAAC;CACpC;AAEH,eAAO,MAAM,kBAAkB,SAAU,GAAG,QAAS,CAAC;AACtD,eAAO,MAAM,iBAAiB,SAAU,GAAG,sBAA2C,CAAC;AAEvF,cAAM,eAAgB,SAAQ,cAAc;IACxC,SAAS,EAAE,WAAW,GAAG,IAAI,CAAO;IACpC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAO;IACvC,KAAK,SAAI;IACT,IAAI,SAAK;IACT,UAAU,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,cAAc,CAAqB;IAC9E,WAAW,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,CAAsB;IACzD,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAK;gBAEd,IAAI,EAAE,QAAQ;IAO1B,MAAM,CAAC,MAAM,CAAC,EAAE,YAAY;IAc5B,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC;IAehD,OAAO,CAAC,WAAW;CAiBtB;AAED,eAAO,MAAM,MAAM,6GAA6B,CAAC"} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/scroll.js b/src/resources/lit-virtualizer/lib/scroll.js new file mode 100644 index 0000000000..7096cae0f3 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/scroll.js @@ -0,0 +1,79 @@ +import { nothing, html } from "lit"; +import { directive, PartType } from "lit/directive.js"; +import { AsyncDirective } from "lit/async-directive.js"; +import { repeat } from "lit/directives/repeat.js"; +import { VirtualScroller } from "./uni-virtualizer/lib/VirtualScroller.js"; +export const defaultKeyFunction = (item) => item; +export const defaultRenderItem = (item) => + html`${JSON.stringify(item, null, 2)}`; +class ScrollDirective extends AsyncDirective { + constructor(part) { + super(part); + this.container = null; + this.scroller = null; + this.first = 0; + this.last = -1; + this.renderItem = defaultRenderItem; + this.keyFunction = defaultKeyFunction; + this.items = []; + if (part.type !== PartType.CHILD) { + throw new Error( + "The scroll directive can only be used in child expressions" + ); + } + } + render(config) { + if (config) { + this.renderItem = config.renderItem || this.renderItem; + this.keyFunction = config.keyFunction || this.keyFunction; + } + const itemsToRender = []; + if (this.first >= 0 && this.last >= this.first) { + for (let i = this.first; i < this.last + 1; i++) { + itemsToRender.push(this.items[i]); + } + } + return repeat( + itemsToRender, + this.keyFunction || defaultKeyFunction, + this.renderItem + ); + } + update(part, [config]) { + var _a; + if (this.scroller || this._initialize(part, config)) { + const { scroller } = this; + this.items = scroller.items = config.items || []; + scroller.totalItems = + config.totalItems || + ((_a = config.items) === null || _a === void 0 ? void 0 : _a.length) || + 0; + scroller.layout = config.layout || null; + scroller.scrollTarget = config.scrollTarget || this.container; + if (config.scrollToIndex) { + scroller.scrollToIndex = config.scrollToIndex; + } + return this.render(config); + } + return nothing; + } + _initialize(part, config) { + const container = (this.container = part.parentNode); + if (container && container.nodeType === 1) { + this.scroller = new VirtualScroller({ container }); + container.addEventListener("rangeChanged", (e) => { + this.first = e.detail.first; + this.last = e.detail.last; + this.setValue(this.render()); + }); + return true; + } + // TODO (GN): This seems to be needed in the case where the `scroll` + // directive is used within the `LitVirtualizer` element. Figure out why + // and see if there's a cleaner solution. + Promise.resolve().then(() => this.update(part, [config])); + return false; + } +} +export const scroll = directive(ScrollDirective); +//# sourceMappingURL=scroll.js.map diff --git a/src/resources/lit-virtualizer/lib/scroll.js.map b/src/resources/lit-virtualizer/lib/scroll.js.map new file mode 100644 index 0000000000..4cf7e26beb --- /dev/null +++ b/src/resources/lit-virtualizer/lib/scroll.js.map @@ -0,0 +1 @@ +{"version":3,"file":"scroll.js","sourceRoot":"","sources":["../src/lib/scroll.ts"],"names":[],"mappings":"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","sourcesContent":["import { TemplateResult, nothing, ChildPart, html } from 'lit';\nimport { directive, PartInfo, PartType } from 'lit/directive.js';\nimport { AsyncDirective } from 'lit/async-directive.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { Layout, LayoutConstructor, LayoutSpecifier } from './uni-virtualizer/lib/layouts/Layout.js';\nimport { VirtualScroller, ScrollToIndexValue } from './uni-virtualizer/lib/VirtualScroller.js';\n\n/**\n * Configuration options for the scroll directive.\n */\ninterface ScrollConfig {\n /**\n * A function that returns a lit-html TemplateResult. It will be used\n * to generate the DOM for each item in the virtual list.\n */\n renderItem?: (item: any, index?: number) => TemplateResult;\n\n keyFunction?: (item: any) => unknown;\n \n // TODO (graynorton): Document...\n layout?: Layout | LayoutConstructor | LayoutSpecifier | null;\n \n /**\n * An element that receives scroll events for the virtual scroller.\n */\n scrollTarget?: Element | Window;\n \n /**\n * The list of items to display via the renderItem function.\n */\n items?: Array;\n \n /**\n * Limit for the number of items to display. Defaults to the length of the\n * items array.\n */\n totalItems?: number;\n \n /**\n * Index and position of the item to scroll to.\n */\n scrollToIndex?: ScrollToIndexValue;\n }\n \nexport const defaultKeyFunction = (item: any) => item;\nexport const defaultRenderItem = (item: any) => html`${JSON.stringify(item, null, 2)}`;\n\nclass ScrollDirective extends AsyncDirective {\n container: HTMLElement | null = null\n scroller: VirtualScroller | null = null\n first = 0\n last = -1\n renderItem: (item: any, index?: number) => TemplateResult = defaultRenderItem;\n keyFunction: (item: any) => unknown = defaultKeyFunction;\n items: Array = []\n\n constructor(part: PartInfo) {\n super(part);\n if (part.type !== PartType.CHILD) {\n throw new Error('The scroll directive can only be used in child expressions');\n }\n }\n \n render(config?: ScrollConfig) {\n if (config) {\n this.renderItem = config.renderItem || this.renderItem;\n this.keyFunction = config.keyFunction || this.keyFunction;\n }\n const itemsToRender = [];\n if (this.first >= 0 && this.last >= this.first) {\n for (let i = this.first; i < this.last + 1; i++) {\n itemsToRender.push(this.items[i]);\n } \n }\n return repeat(itemsToRender, this.keyFunction || defaultKeyFunction, this.renderItem);\n }\n\n update(part: ChildPart, [config]: [ScrollConfig]) {\n if (this.scroller || this._initialize(part, config)) {\n const { scroller } = this;\n this.items = scroller!.items = config.items || [];\n scroller!.totalItems = config.totalItems || config.items?.length || 0;\n scroller!.layout = config.layout || null;\n scroller!.scrollTarget = config.scrollTarget || this.container;\n if (config.scrollToIndex) {\n scroller!.scrollToIndex = config.scrollToIndex;\n }\n return this.render(config); \n }\n return nothing;\n }\n\n private _initialize(part: ChildPart, config: ScrollConfig) {\n const container = this.container = part.parentNode as HTMLElement;\n if (container && container.nodeType === 1) {\n this.scroller = new VirtualScroller({ container });\n container.addEventListener('rangeChanged', (e: Event) => {\n this.first = (e as CustomEvent).detail.first;\n this.last = (e as CustomEvent).detail.last;\n this.setValue(this.render());\n });\n return true;\n }\n // TODO (GN): This seems to be needed in the case where the `scroll`\n // directive is used within the `LitVirtualizer` element. Figure out why\n // and see if there's a cleaner solution.\n Promise.resolve().then(() => this.update(part, [config]));\n return false;\n }\n}\n\nexport const scroll = directive(ScrollDirective);"]} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/VirtualScroller.d.ts b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/VirtualScroller.d.ts new file mode 100644 index 0000000000..8b25e924e3 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/VirtualScroller.d.ts @@ -0,0 +1,230 @@ +import { + ItemBox, + Layout, + LayoutConstructor, + LayoutSpecifier, +} from "./layouts/Layout.js"; +export declare const scrollerRef: unique symbol; +export declare type RangeChangeEvent = { + first: number; + last: number; + firstVisible: number; + lastVisible: number; +}; +interface ElementWithOptionalScrollerRef extends Element { + [scrollerRef]?: VirtualScroller; +} +interface ShadowRootWithOptionalScrollerRef extends ShadowRoot { + [scrollerRef]?: VirtualScroller; +} +declare type Container = + | ElementWithOptionalScrollerRef + | ShadowRootWithOptionalScrollerRef; +export declare type ContainerElement = ElementWithOptionalScrollerRef; +declare type ChildMeasurements = { + [key: number]: ItemBox; +}; +export declare type ScrollToIndexValue = { + index: number; + position?: string; +} | null; +export interface VirtualScrollerConfig { + layout?: Layout | LayoutConstructor | LayoutSpecifier; + /** + * An element that receives scroll events for the virtual scroller. + */ + scrollTarget?: Element | Window; + /** + * The parent of all child nodes to be rendered. + */ + container: Element | ShadowRoot; +} +/** + * Provides virtual scrolling boilerplate. + * + * Extensions of this class must set container, layout, and scrollTarget. + * + * Extensions of this class must also override VirtualRepeater's DOM + * manipulation methods. + */ +export declare class VirtualScroller { + private _benchmarkStart; + /** + * Whether the layout should receive an updated viewport size on the next + * render. + */ + private _layout; + /** + * The element that generates scroll events and defines the container + * viewport. Set by scrollTarget. + */ + private _scrollTarget; + /** + * A sentinel element that sizes the container when it is a scrolling + * element. This ensures the scroll bar accurately reflects the total + * size of the list. + */ + private _sizer; + /** + * Layout provides these values, we set them on _render(). + * TODO @straversi: Can we find an XOR type, usable for the key here? + */ + private _scrollSize; + /** + * Difference between scroll target's current and required scroll offsets. + * Provided by layout. + */ + private _scrollErr; + /** + * A list of the positions (top, left) of the children in the current range. + */ + private _childrenPos; + private _childMeasurements; + private _toBeMeasured; + private _rangeChanged; + private _itemsChanged; + private _visibilityChanged; + /** + * Containing element. Set by container. + */ + protected _container: Container | null; + /** + * The parent of all child nodes to be rendered. Set by container. + */ + private _containerElement; + /** + * Keep track of original inline style of the container, so it can be + * restored when container is changed. + */ + private _containerInlineStyle; + /** + * Size of the container. + */ + private _containerSize; + /** + * Resize observer attached to container. + */ + private _containerRO; + /** + * Resize observer attached to children. + */ + private _childrenRO; + private _mutationObserver; + private _mutationPromise; + private _mutationPromiseResolver; + private _mutationsObserved; + private _loadListener; + /** + * Index and position of item to scroll to. + */ + private _scrollToIndex; + /** + * Items to render. Set by items. + */ + private _items; + /** + * Total number of items to render. Set by totalItems. + */ + private _totalItems; + /** + * Index of the first child in the range, not necessarily the first visible child. + * TODO @straversi: Consider renaming these. + */ + protected _first: number; + /** + * Index of the last child in the range. + */ + protected _last: number; + /** + * Index of the first item intersecting the container element. + */ + private _firstVisible; + /** + * Index of the last item intersecting the container element. + */ + private _lastVisible; + protected _scheduled: WeakSet; + /** + * Invoked at the end of each render cycle: children in the range are + * measured, and their dimensions passed to this callback. Use it to layout + * children as needed. + */ + protected _measureCallback: ((sizes: ChildMeasurements) => void) | null; + protected _measureChildOverride: + | ((element: Element, item: unknown) => ItemBox) + | null; + constructor(config?: VirtualScrollerConfig); + set items(items: Array | undefined); + /** + * The total number of items, regardless of the range, that can be rendered + * as child nodes. + */ + get totalItems(): number; + set totalItems(num: number); + /** + * The parent of all child nodes to be rendered. + */ + get container(): Container | null; + set container(container: Container | null); + get layout(): Layout | LayoutConstructor | LayoutSpecifier | null; + set layout(layout: Layout | LayoutConstructor | LayoutSpecifier | null); + startBenchmarking(): void; + stopBenchmarking(): { + timeElapsed: number; + virtualizationTime: number; + } | null; + private _measureChildren; + /** + * Returns the width, height, and margins of the given child. + */ + _measureChild(element: Element): ItemBox; + /** + * The element that generates scroll events and defines the container + * viewport. The value `null` (default) corresponds to `window` as scroll + * target. + */ + get scrollTarget(): Element | Window | null; + set scrollTarget(target: Element | Window | null); + /** + * Index and position of item to scroll to. The scroller will fix to that point + * until the user scrolls. + */ + set scrollToIndex(newValue: ScrollToIndexValue); + protected _schedule(method: Function): Promise; + _updateDOM(): Promise; + _updateLayout(): void; + private _handleScrollEvent; + handleEvent(event: CustomEvent): void; + private _initResizeObservers; + private _createContainerSizer; + get _children(): Array; + private _updateView; + /** + * Styles the _sizer element or the container so that its size reflects the + * total size of all items. + */ + private _sizeContainer; + /** + * Sets the top and left transform style of the children from the values in + * pos. + */ + private _positionChildren; + private _adjustRange; + private _correctScrollError; + /** + * Emits a rangechange event with the current first, last, firstVisible, and + * lastVisible. + */ + private _notifyRange; + private _notifyVisibility; + /** + * Render and update the view at the next opportunity with the given + * container size. + */ + private _containerSizeChanged; + private _observeMutations; + private _childLoaded; + private _childrenSizeChanged; +} +export {}; +//# sourceMappingURL=VirtualScroller.d.ts.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/VirtualScroller.d.ts.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/VirtualScroller.d.ts.map new file mode 100644 index 0000000000..917e1bf686 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/VirtualScroller.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"VirtualScroller.d.ts","sourceRoot":"","sources":["../../../src/lib/uni-virtualizer/lib/VirtualScroller.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/VirtualScroller.js b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/VirtualScroller.js new file mode 100644 index 0000000000..d7ae72e0fc --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/VirtualScroller.js @@ -0,0 +1,725 @@ +import getResizeObserver from "./polyfillLoaders/ResizeObserver.js"; +export const scrollerRef = Symbol("scrollerRef"); +/** + * Provides virtual scrolling boilerplate. + * + * Extensions of this class must set container, layout, and scrollTarget. + * + * Extensions of this class must also override VirtualRepeater's DOM + * manipulation methods. + */ +export class VirtualScroller { + constructor(config) { + this._benchmarkStart = null; + /** + * Whether the layout should receive an updated viewport size on the next + * render. + */ + // private _needsUpdateView: boolean = false; + this._layout = null; + /** + * The element that generates scroll events and defines the container + * viewport. Set by scrollTarget. + */ + this._scrollTarget = null; + /** + * A sentinel element that sizes the container when it is a scrolling + * element. This ensures the scroll bar accurately reflects the total + * size of the list. + */ + this._sizer = null; + /** + * Layout provides these values, we set them on _render(). + * TODO @straversi: Can we find an XOR type, usable for the key here? + */ + this._scrollSize = null; + /** + * Difference between scroll target's current and required scroll offsets. + * Provided by layout. + */ + this._scrollErr = null; + /** + * A list of the positions (top, left) of the children in the current range. + */ + this._childrenPos = null; + // TODO: (graynorton): type + this._childMeasurements = null; + this._toBeMeasured = new Map(); + this._rangeChanged = true; + this._itemsChanged = true; + this._visibilityChanged = true; + /** + * Containing element. Set by container. + */ + this._container = null; + /** + * The parent of all child nodes to be rendered. Set by container. + */ + this._containerElement = null; + /** + * Keep track of original inline style of the container, so it can be + * restored when container is changed. + */ + this._containerInlineStyle = null; + /** + * Size of the container. + */ + this._containerSize = null; + /** + * Resize observer attached to container. + */ + this._containerRO = null; + /** + * Resize observer attached to children. + */ + this._childrenRO = null; + this._mutationObserver = null; + this._mutationPromise = null; + this._mutationPromiseResolver = null; + this._mutationsObserved = false; + // TODO (graynorton): Rethink, per longer comment below + this._loadListener = this._childLoaded.bind(this); + /** + * Index and position of item to scroll to. + */ + this._scrollToIndex = null; + /** + * Items to render. Set by items. + */ + this._items = []; + /** + * Total number of items to render. Set by totalItems. + */ + this._totalItems = null; + /** + * Index of the first child in the range, not necessarily the first visible child. + * TODO @straversi: Consider renaming these. + */ + this._first = 0; + /** + * Index of the last child in the range. + */ + this._last = 0; + /** + * Index of the first item intersecting the container element. + */ + this._firstVisible = 0; + /** + * Index of the last item intersecting the container element. + */ + this._lastVisible = 0; + this._scheduled = new WeakSet(); + /** + * Invoked at the end of each render cycle: children in the range are + * measured, and their dimensions passed to this callback. Use it to layout + * children as needed. + */ + this._measureCallback = null; + this._measureChildOverride = null; + this._first = -1; + this._last = -1; + if (config) { + Object.assign(this, config); + } + } + set items(items) { + if (Array.isArray(items) && items !== this._items) { + this._itemsChanged = true; + this._items = items; + this._schedule(this._updateLayout); + } + } + /** + * The total number of items, regardless of the range, that can be rendered + * as child nodes. + */ + get totalItems() { + return this._totalItems === null ? this._items.length : this._totalItems; + } + set totalItems(num) { + if (typeof num !== "number" && num !== null) { + throw new Error("New value must be a number."); + } + // TODO(valdrin) should we check if it is a finite number? + // Technically, Infinity would break Layout, not VirtualRepeater. + if (num !== this._totalItems) { + this._totalItems = num; + this._schedule(this._updateLayout); + } + } + /** + * The parent of all child nodes to be rendered. + */ + get container() { + return this._container; + } + set container(container) { + if (container === this._container) { + return; + } + if (this._container) { + // Remove children from old container. + // TODO (graynorton): Decide whether we'd rather fire an event to clear + // the range and let the renderer take care of removing the DOM children + this._children.forEach((child) => child.parentNode.removeChild(child)); + } + this._container = container; + this._schedule(this._updateLayout); + this._initResizeObservers().then(() => { + const oldEl = this._containerElement; + // Consider document fragments as shadowRoots. + const newEl = + container && container.nodeType === Node.DOCUMENT_FRAGMENT_NODE + ? container.host + : container; + if (oldEl === newEl) { + return; + } + this._containerRO.disconnect(); + this._containerSize = null; + if (oldEl) { + if (this._containerInlineStyle) { + oldEl.setAttribute("style", this._containerInlineStyle); + } else { + oldEl.removeAttribute("style"); + } + this._containerInlineStyle = null; + if (oldEl === this._scrollTarget) { + oldEl.removeEventListener("scroll", this, { passive: true }); + this._sizer && this._sizer.remove(); + } + oldEl.removeEventListener("load", this._loadListener, true); + this._mutationObserver.disconnect(); + } else { + // First time container was setup, add listeners only now. + addEventListener("scroll", this, { passive: true }); + } + this._containerElement = newEl; + if (newEl) { + this._containerInlineStyle = newEl.getAttribute("style") || null; + // https://github.com/PolymerLabs/uni-virtualizer/issues/104 + // Would rather set these CSS properties on the host using Shadow Root + // style scoping (and fall back to a global stylesheet where native + // Shadow DOM is not available), but this Mobile Safari bug is preventing + // that from working: https://bugs.webkit.org/show_bug.cgi?id=226195 + const style = newEl.style; + style.display = style.display || "block"; + style.position = style.position || "relative"; + style.overflow = style.overflow || "auto"; + style.contain = style.contain || "strict"; + if (newEl === this._scrollTarget) { + this._sizer = this._sizer || this._createContainerSizer(); + this._container.insertBefore(this._sizer, this._container.firstChild); + } + this._schedule(this._updateLayout); + this._containerRO.observe(newEl); + this._mutationObserver.observe(newEl, { childList: true }); + this._mutationPromise = new Promise( + (resolve) => (this._mutationPromiseResolver = resolve) + ); + if (this._layout && this._layout.listenForChildLoadEvents) { + newEl.addEventListener("load", this._loadListener, true); + } + } + }); + } + // This will always actually return a layout instance, + // but TypeScript wants the getter and setter types to be the same + get layout() { + return this._layout; + } + set layout(layout) { + if (this._layout === layout) { + return; + } + let _layout = null; + let _config = {}; + if (typeof layout === "object") { + if (layout.type !== undefined) { + _layout = layout.type; + // delete (layout as LayoutSpecifier).type; + } + _config = layout; + } else { + _layout = layout; + } + if (typeof _layout === "function") { + if (this._layout instanceof _layout) { + if (_config) { + this._layout.config = _config; + } + return; + } else { + _layout = new _layout(_config); + } + } + if (this._layout) { + this._measureCallback = null; + this._measureChildOverride = null; + this._layout.removeEventListener("scrollsizechange", this); + this._layout.removeEventListener("scrollerrorchange", this); + this._layout.removeEventListener("itempositionchange", this); + this._layout.removeEventListener("rangechange", this); + delete this.container[scrollerRef]; + this.container.removeEventListener("load", this._loadListener, true); + // Reset container size so layout can get correct viewport size. + if (this._containerElement) { + this._sizeContainer(undefined); + } + } + this._layout = _layout; + if (this._layout) { + if ( + this._layout.measureChildren && + typeof this._layout.updateItemSizes === "function" + ) { + if (typeof this._layout.measureChildren === "function") { + this._measureChildOverride = this._layout.measureChildren; + } + this._measureCallback = this._layout.updateItemSizes.bind(this._layout); + } + this._layout.addEventListener("scrollsizechange", this); + this._layout.addEventListener("scrollerrorchange", this); + this._layout.addEventListener("itempositionchange", this); + this._layout.addEventListener("rangechange", this); + this._container[scrollerRef] = this; + if (this._layout.listenForChildLoadEvents) { + this._container.addEventListener("load", this._loadListener, true); + } + this._schedule(this._updateLayout); + } + } + // TODO (graynorton): Rework benchmarking so that it has no API and + // instead is always on except in production builds + startBenchmarking() { + if (this._benchmarkStart === null) { + this._benchmarkStart = window.performance.now(); + } + } + stopBenchmarking() { + if (this._benchmarkStart !== null) { + const now = window.performance.now(); + const timeElapsed = now - this._benchmarkStart; + const entries = performance.getEntriesByName( + "uv-virtualizing", + "measure" + ); + const virtualizationTime = entries + .filter((e) => e.startTime >= this._benchmarkStart && e.startTime < now) + .reduce((t, m) => t + m.duration, 0); + this._benchmarkStart = null; + return { timeElapsed, virtualizationTime }; + } + return null; + } + _measureChildren() { + const mm = {}; + const children = this._children; + const fn = this._measureChildOverride || this._measureChild; + for (let i = 0; i < children.length; i++) { + const child = children[i]; + const idx = this._first + i; + if (this._itemsChanged || this._toBeMeasured.has(child)) { + mm[idx] = fn.call( + this, + child, + this._items[idx] /*as unknown as object*/ + ); + } + } + this._childMeasurements = mm; + this._schedule(this._updateLayout); + this._toBeMeasured.clear(); + } + /** + * Returns the width, height, and margins of the given child. + */ + _measureChild(element) { + // offsetWidth doesn't take transforms in consideration, so we use + // getBoundingClientRect which does. + const { width, height } = element.getBoundingClientRect(); + return Object.assign({ width, height }, getMargins(element)); + } + /** + * The element that generates scroll events and defines the container + * viewport. The value `null` (default) corresponds to `window` as scroll + * target. + */ + get scrollTarget() { + return this._scrollTarget; + } + set scrollTarget(target) { + // Consider window as null. + if (target === window) { + target = null; + } + if (this._scrollTarget === target) { + return; + } + this._sizeContainer(undefined); + if (this._scrollTarget) { + this._scrollTarget.removeEventListener("scroll", this, { passive: true }); + if (this._sizer && this._scrollTarget === this._containerElement) { + this._sizer.remove(); + } + } + this._scrollTarget = target; + if (target) { + target.addEventListener("scroll", this, { passive: true }); + if (target === this._containerElement) { + this._sizer = this._sizer || this._createContainerSizer(); + this._container.insertBefore(this._sizer, this._container.firstChild); + } + } + } + /** + * Index and position of item to scroll to. The scroller will fix to that point + * until the user scrolls. + */ + set scrollToIndex(newValue) { + this._scrollToIndex = newValue; + this._schedule(this._updateLayout); + } + async _schedule(method) { + if (!this._scheduled.has(method)) { + this._scheduled.add(method); + await Promise.resolve(); + this._scheduled.delete(method); + method.call(this); + } + } + async _updateDOM() { + const { _rangeChanged, _itemsChanged } = this; + if (this._visibilityChanged) { + this._notifyVisibility(); + this._visibilityChanged = false; + } + if (_rangeChanged || _itemsChanged) { + this._notifyRange(); + this._rangeChanged = false; + this._itemsChanged = false; + await this._mutationPromise; + } + if (this._layout.measureChildren) { + this._children.forEach((child) => this._childrenRO.observe(child)); + } + this._positionChildren(this._childrenPos); + this._sizeContainer(this._scrollSize); + if (this._scrollErr) { + this._correctScrollError(this._scrollErr); + this._scrollErr = null; + } + if (this._benchmarkStart && "mark" in window.performance) { + window.performance.mark("uv-end"); + } + } + _updateLayout() { + this._layout.totalItems = this._totalItems; + if (this._scrollToIndex !== null) { + this._layout.scrollToIndex( + this._scrollToIndex.index, + this._scrollToIndex.position + ); + this._scrollToIndex = null; + } + this._updateView(); + if (this._childMeasurements !== null) { + // If the layout has been changed, we may have measurements but no callback + if (this._measureCallback) { + this._measureCallback(this._childMeasurements); + } + this._childMeasurements = null; + } + this._layout.reflowIfNeeded(this._itemsChanged); + if (this._benchmarkStart && "mark" in window.performance) { + window.performance.mark("uv-end"); + } + } + _handleScrollEvent() { + if (this._benchmarkStart && "mark" in window.performance) { + try { + window.performance.measure("uv-virtualizing", "uv-start", "uv-end"); + } catch (e) { + console.warn("Error measuring performance data: ", e); + } + window.performance.mark("uv-start"); + } + this._schedule(this._updateLayout); + } + handleEvent(event) { + switch (event.type) { + case "scroll": + if (!this._scrollTarget || event.target === this._scrollTarget) { + this._handleScrollEvent(); + } + break; + case "scrollsizechange": + this._scrollSize = event.detail; + this._schedule(this._updateDOM); + break; + case "scrollerrorchange": + this._scrollErr = event.detail; + this._schedule(this._updateDOM); + break; + case "itempositionchange": + this._childrenPos = event.detail; + this._schedule(this._updateDOM); + break; + case "rangechange": + this._adjustRange(event.detail); + this._schedule(this._updateDOM); + break; + default: + console.warn("event not handled", event); + } + } + async _initResizeObservers() { + if (this._containerRO === null) { + const ResizeObserver = await getResizeObserver(); + this._containerRO = new ResizeObserver((entries) => + this._containerSizeChanged(entries[0].contentRect) + ); + this._childrenRO = new ResizeObserver( + this._childrenSizeChanged.bind(this) + ); + this._mutationObserver = new MutationObserver( + this._observeMutations.bind(this) + ); + } + } + _createContainerSizer() { + const sizer = document.createElement("div"); + // When the scrollHeight is large, the height of this element might be + // ignored. Setting content and font-size ensures the element has a size. + Object.assign(sizer.style, { + position: "absolute", + margin: "-2px 0 0 0", + padding: 0, + visibility: "hidden", + fontSize: "2px", + }); + sizer.innerHTML = " "; + sizer.id = "uni-virtualizer-spacer"; + return sizer; + } + get _children() { + const arr = []; + let next = this.container.firstElementChild; + while (next) { + // Skip our spacer. TODO (graynorton): Feels a bit hacky. Anything better? + if (next.id !== "uni-virtualizer-spacer") { + arr.push(next); + } + next = next.nextElementSibling; + } + return arr; + } + _updateView() { + if (!this.container || !this._containerElement || !this._layout) { + return; + } + let width, height, top, left; + if ( + this._scrollTarget === this._containerElement && + this._containerSize !== null + ) { + width = this._containerSize.width; + height = this._containerSize.height; + left = this._containerElement.scrollLeft; + top = this._containerElement.scrollTop; + } else { + const containerBounds = this._containerElement.getBoundingClientRect(); + const scrollBounds = this._scrollTarget + ? this._scrollTarget.getBoundingClientRect() + : { + top: containerBounds.top + window.pageYOffset, + left: containerBounds.left + window.pageXOffset, + width: innerWidth, + height: innerHeight, + }; + const scrollerWidth = scrollBounds.width; + const scrollerHeight = scrollBounds.height; + const xMin = Math.max( + 0, + Math.min(scrollerWidth, containerBounds.left - scrollBounds.left) + ); + const yMin = Math.max( + 0, + Math.min(scrollerHeight, containerBounds.top - scrollBounds.top) + ); + // TODO (graynorton): Direction is intended to be a layout-level concept, not a scroller-level concept, + // so this feels like a factoring problem + const xMax = + this._layout.direction === "vertical" + ? Math.max( + 0, + Math.min(scrollerWidth, containerBounds.right - scrollBounds.left) + ) + : scrollerWidth; + const yMax = + this._layout.direction === "vertical" + ? scrollerHeight + : Math.max( + 0, + Math.min( + scrollerHeight, + containerBounds.bottom - scrollBounds.top + ) + ); + width = xMax - xMin; + height = yMax - yMin; + left = Math.max(0, -(containerBounds.left - scrollBounds.left)); + top = Math.max(0, -(containerBounds.top - scrollBounds.top)); + } + this._layout.viewportSize = { width, height }; + this._layout.viewportScroll = { top, left }; + } + /** + * Styles the _sizer element or the container so that its size reflects the + * total size of all items. + */ + _sizeContainer(size) { + if (this._scrollTarget === this._containerElement) { + const left = size && size.width ? size.width - 1 : 0; + const top = size && size.height ? size.height - 1 : 0; + if (this._sizer) { + this._sizer.style.transform = `translate(${left}px, ${top}px)`; + } + } else { + if (this._containerElement) { + const style = this._containerElement.style; + style.minWidth = size && size.width ? size.width + "px" : null; + style.minHeight = size && size.height ? size.height + "px" : null; + } + } + } + /** + * Sets the top and left transform style of the children from the values in + * pos. + */ + _positionChildren(pos) { + if (pos) { + const children = this._children; + Object.keys(pos).forEach((key) => { + const idx = key - this._first; + const child = children[idx]; + if (child) { + const { top, left, width, height } = pos[key]; + child.style.position = "absolute"; + child.style.boxSizing = "border-box"; + child.style.transform = `translate(${left}px, ${top}px)`; + if (width !== undefined) { + child.style.width = width + "px"; + } + if (height !== undefined) { + child.style.height = height + "px"; + } + } + }); + } + } + async _adjustRange(range) { + const { _first, _last, _firstVisible, _lastVisible } = this; + this._first = range.first; + this._last = range.last; + this._firstVisible = range.firstVisible; + this._lastVisible = range.lastVisible; + this._rangeChanged = + this._rangeChanged || this._first !== _first || this._last !== _last; + this._visibilityChanged = + this._visibilityChanged || + this._firstVisible !== _firstVisible || + this._lastVisible !== _lastVisible; + } + _correctScrollError(err) { + if (this._scrollTarget) { + this._scrollTarget.scrollTop -= err.top; + this._scrollTarget.scrollLeft -= err.left; + } else { + window.scroll( + window.pageXOffset - err.left, + window.pageYOffset - err.top + ); + } + } + /** + * Emits a rangechange event with the current first, last, firstVisible, and + * lastVisible. + */ + _notifyRange() { + // TODO (graynorton): Including visibility here for backward compat, but + // may decide to remove at some point. The rationale for separating is that + // range change events are mainly intended for "internal" consumption by the + // renderer, whereas visibility change events are mainly intended for "external" + // consumption by application code. + this._container.dispatchEvent( + new CustomEvent("rangeChanged", { + detail: { + first: this._first, + last: this._last, + firstVisible: this._firstVisible, + lastVisible: this._lastVisible, + }, + }) + ); + } + _notifyVisibility() { + this._container.dispatchEvent( + new CustomEvent("visibilityChanged", { + detail: { + first: this._first, + last: this._last, + firstVisible: this._firstVisible, + lastVisible: this._lastVisible, + }, + }) + ); + } + /** + * Render and update the view at the next opportunity with the given + * container size. + */ + _containerSizeChanged(size) { + const { width, height } = size; + this._containerSize = { width, height }; + this._schedule(this._updateLayout); + } + async _observeMutations() { + if (!this._mutationsObserved) { + this._mutationsObserved = true; + this._mutationPromiseResolver(); + this._mutationPromise = new Promise( + (resolve) => (this._mutationPromiseResolver = resolve) + ); + this._mutationsObserved = false; + } + } + // TODO (graynorton): Rethink how this works. Probably child loading is too specific + // to have dedicated support for; might want some more generic lifecycle hooks for + // layouts to use. Possibly handle measurement this way, too, or maybe that remains + // a first-class feature? + _childLoaded() { + // this.requestRemeasure(); + } + _childrenSizeChanged(changes) { + for (const change of changes) { + this._toBeMeasured.set(change.target, change.contentRect); + } + this._measureChildren(); + this._schedule(this._updateLayout); + } +} +function getMargins(el) { + const style = window.getComputedStyle(el); + return { + marginTop: getMarginValue(style.marginTop), + marginRight: getMarginValue(style.marginRight), + marginBottom: getMarginValue(style.marginBottom), + marginLeft: getMarginValue(style.marginLeft), + }; +} +function getMarginValue(value) { + const float = value ? parseFloat(value) : NaN; + return Number.isNaN(float) ? 0 : float; +} +//# sourceMappingURL=VirtualScroller.js.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/VirtualScroller.js.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/VirtualScroller.js.map new file mode 100644 index 0000000000..693e4099af --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/VirtualScroller.js.map @@ -0,0 +1 @@ +{"version":3,"file":"VirtualScroller.js","sourceRoot":"","sources":["../../../src/lib/uni-virtualizer/lib/VirtualScroller.ts"],"names":[],"mappings":"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","sourcesContent":["import getResizeObserver from './polyfillLoaders/ResizeObserver.js';\nimport { ItemBox, Margins, Layout, LayoutConstructor, LayoutSpecifier } from './layouts/Layout.js';\n\nexport const scrollerRef = Symbol('scrollerRef');\n\ninterface Range {\n first: number;\n last: number;\n num: number;\n remeasure: boolean;\n stable: boolean;\n firstVisible: number;\n lastVisible: number;\n}\n\nexport type RangeChangeEvent = {\n first: number;\n last: number;\n firstVisible: number;\n lastVisible: number;\n};\n\ninterface ElementWithOptionalScrollerRef extends Element {\n [scrollerRef]?: VirtualScroller\n}\n\ninterface ShadowRootWithOptionalScrollerRef extends ShadowRoot {\n [scrollerRef]?: VirtualScroller\n}\n\ntype Container = ElementWithOptionalScrollerRef | ShadowRootWithOptionalScrollerRef;\nexport type ContainerElement = ElementWithOptionalScrollerRef;\n\ntype VerticalScrollSize = {height: number};\ntype HorizontalScrollSize = {width: number};\ntype ScrollSize = VerticalScrollSize | HorizontalScrollSize;\n\ntype ChildMeasurements = {[key: number]: ItemBox};\n\nexport type ScrollToIndexValue = {index: number, position?: string} | null;\n\nexport interface VirtualScrollerConfig {\n layout?: Layout | LayoutConstructor | LayoutSpecifier;\n\n /**\n * An element that receives scroll events for the virtual scroller.\n */\n scrollTarget?: Element | Window;\n\n /**\n * The parent of all child nodes to be rendered.\n */\n container: Element | ShadowRoot;\n}\n\n/**\n * Provides virtual scrolling boilerplate.\n *\n * Extensions of this class must set container, layout, and scrollTarget.\n *\n * Extensions of this class must also override VirtualRepeater's DOM\n * manipulation methods.\n */\nexport class VirtualScroller {\n private _benchmarkStart: number | null = null;\n /**\n * Whether the layout should receive an updated viewport size on the next\n * render.\n */\n // private _needsUpdateView: boolean = false;\n\n private _layout: Layout | null = null;\n\n /**\n * The element that generates scroll events and defines the container\n * viewport. Set by scrollTarget.\n */\n private _scrollTarget: Element | null = null;\n\n /**\n * A sentinel element that sizes the container when it is a scrolling\n * element. This ensures the scroll bar accurately reflects the total\n * size of the list.\n */\n private _sizer: HTMLElement | null = null;\n\n /**\n * Layout provides these values, we set them on _render().\n * TODO @straversi: Can we find an XOR type, usable for the key here?\n */\n private _scrollSize: ScrollSize | null = null;\n\n /**\n * Difference between scroll target's current and required scroll offsets.\n * Provided by layout.\n */\n private _scrollErr: {left: number, top: number} | null = null;\n\n /**\n * A list of the positions (top, left) of the children in the current range.\n */\n private _childrenPos: Array<{top: number, left: number}> | null = null;\n\n // TODO: (graynorton): type\n private _childMeasurements: ChildMeasurements | null = null;\n\n private _toBeMeasured: Map = new Map();\n\n private _rangeChanged = true;\n\n private _itemsChanged = true;\n\n private _visibilityChanged = true;\n\n /**\n * Containing element. Set by container.\n */\n protected _container: Container | null = null;\n\n /**\n * The parent of all child nodes to be rendered. Set by container.\n */\n private _containerElement: ContainerElement | null = null;\n\n /**\n * Keep track of original inline style of the container, so it can be\n * restored when container is changed.\n */\n private _containerInlineStyle: string | null = null;\n\n /**\n * Size of the container.\n */\n private _containerSize: {width: number, height: number} | null = null;\n\n /**\n * Resize observer attached to container.\n */\n private _containerRO: ResizeObserver | null = null;\n\n /**\n * Resize observer attached to children.\n */\n private _childrenRO: ResizeObserver | null = null;\n\n private _mutationObserver: MutationObserver | null = null;\n private _mutationPromise: Promise | null = null;\n private _mutationPromiseResolver: Function | null = null;\n private _mutationsObserved = false;\n\n // TODO (graynorton): Rethink, per longer comment below\n\n private _loadListener = this._childLoaded.bind(this);\n\n /**\n * Index and position of item to scroll to.\n */\n private _scrollToIndex: ScrollToIndexValue = null;\n\n /**\n * Items to render. Set by items.\n */\n private _items: Array = [];\n\n /**\n * Total number of items to render. Set by totalItems.\n */\n private _totalItems: number | null = null;\n\n /**\n * Index of the first child in the range, not necessarily the first visible child.\n * TODO @straversi: Consider renaming these.\n */\n protected _first = 0;\n\n /**\n * Index of the last child in the range.\n */\n protected _last = 0;\n\n /**\n * Index of the first item intersecting the container element.\n */\n private _firstVisible = 0;\n\n /**\n * Index of the last item intersecting the container element.\n */\n private _lastVisible = 0;\n\n protected _scheduled = new WeakSet();\n\n /**\n * Invoked at the end of each render cycle: children in the range are\n * measured, and their dimensions passed to this callback. Use it to layout\n * children as needed.\n */\n protected _measureCallback: ((sizes: ChildMeasurements) => void) | null = null;\n\n protected _measureChildOverride: ((element: Element, item: unknown) => ItemBox) | null = null;\n\n constructor(config?: VirtualScrollerConfig) {\n this._first = -1;\n this._last = -1;\n\n if (config) {\n Object.assign(this, config);\n }\n }\n\n set items(items: Array | undefined) {\n if (Array.isArray(items) && items !== this._items) {\n this._itemsChanged = true;\n this._items = items;\n this._schedule(this._updateLayout);\n }\n }\n\n /**\n * The total number of items, regardless of the range, that can be rendered\n * as child nodes.\n */\n get totalItems(): number {\n return (this._totalItems === null ? this._items.length : this._totalItems);\n }\n\n set totalItems(num: number) {\n if (typeof num !== 'number' && num !== null) {\n throw new Error('New value must be a number.');\n }\n\n // TODO(valdrin) should we check if it is a finite number?\n // Technically, Infinity would break Layout, not VirtualRepeater.\n if (num !== this._totalItems) {\n this._totalItems = num;\n this._schedule(this._updateLayout);\n }\n }\n\n /**\n * The parent of all child nodes to be rendered.\n */\n get container(): Container | null {\n return this._container;\n }\n\n set container(container: Container | null) {\n if (container === this._container) {\n return;\n }\n\n if (this._container) {\n // Remove children from old container.\n // TODO (graynorton): Decide whether we'd rather fire an event to clear\n // the range and let the renderer take care of removing the DOM children\n this._children.forEach(child => child.parentNode!.removeChild(child));\n }\n\n this._container = container;\n\n this._schedule(this._updateLayout);\n\n this._initResizeObservers().then(() => {\n const oldEl = this._containerElement as HTMLElement;\n // Consider document fragments as shadowRoots.\n const newEl =\n (container && container.nodeType === Node.DOCUMENT_FRAGMENT_NODE) ?\n (container as ShadowRoot).host as HTMLElement :\n container as HTMLElement;\n if (oldEl === newEl) {\n return;\n }\n \n this._containerRO!.disconnect();\n this._containerSize = null;\n \n if (oldEl) {\n if (this._containerInlineStyle) {\n oldEl.setAttribute('style', this._containerInlineStyle!);\n } else {\n oldEl.removeAttribute('style');\n }\n this._containerInlineStyle = null;\n if (oldEl === this._scrollTarget) {\n oldEl.removeEventListener('scroll', this, {passive: true} as EventListenerOptions);\n this._sizer && this._sizer.remove();\n }\n oldEl.removeEventListener('load', this._loadListener, true);\n\n this._mutationObserver!.disconnect();\n } else {\n // First time container was setup, add listeners only now.\n addEventListener('scroll', this, {passive: true});\n }\n \n this._containerElement = newEl;\n \n if (newEl) {\n this._containerInlineStyle = newEl.getAttribute('style') || null;\n // https://github.com/PolymerLabs/uni-virtualizer/issues/104\n // Would rather set these CSS properties on the host using Shadow Root\n // style scoping (and fall back to a global stylesheet where native\n // Shadow DOM is not available), but this Mobile Safari bug is preventing\n // that from working: https://bugs.webkit.org/show_bug.cgi?id=226195\n const style = newEl.style as CSSStyleDeclaration & { contain: string };\n style.display = style.display || 'block';\n style.position = style.position || 'relative';\n style.overflow = style.overflow || 'auto';\n style.contain = style.contain || 'strict';\n if (newEl === this._scrollTarget) {\n this._sizer = this._sizer || this._createContainerSizer();\n this._container!.insertBefore(this._sizer, this._container!.firstChild);\n }\n this._schedule(this._updateLayout);\n this._containerRO!.observe(newEl);\n this._mutationObserver!.observe(newEl, { childList: true });\n this._mutationPromise = new Promise(resolve => this._mutationPromiseResolver = resolve);\n \n if (this._layout && this._layout.listenForChildLoadEvents) {\n newEl.addEventListener('load', this._loadListener, true);\n }\n }\n }); \n }\n\n // This will always actually return a layout instance,\n // but TypeScript wants the getter and setter types to be the same\n get layout(): Layout | LayoutConstructor | LayoutSpecifier | null {\n return this._layout;\n }\n\n set layout(layout: Layout | LayoutConstructor | LayoutSpecifier | null) {\n if (this._layout === layout) {\n return;\n }\n\n let _layout: LayoutConstructor | Layout | null = null;\n let _config: object = {};\n\n if (typeof layout === 'object') {\n if ((layout as LayoutSpecifier).type !== undefined) {\n _layout = (layout as LayoutSpecifier).type;\n // delete (layout as LayoutSpecifier).type;\n }\n _config = layout as object;\n }\n else {\n _layout = layout;\n }\n\n if (typeof _layout === 'function') {\n if (this._layout instanceof _layout) {\n if (_config) {\n this._layout!.config = _config;\n }\n return;\n }\n else {\n _layout = new _layout(_config);\n }\n }\n\n if (this._layout) {\n this._measureCallback = null;\n this._measureChildOverride = null;\n this._layout.removeEventListener('scrollsizechange', this);\n this._layout.removeEventListener('scrollerrorchange', this);\n this._layout.removeEventListener('itempositionchange', this);\n this._layout.removeEventListener('rangechange', this);\n delete this.container![scrollerRef];\n this.container!.removeEventListener('load', this._loadListener, true);\n // Reset container size so layout can get correct viewport size.\n if (this._containerElement) {\n this._sizeContainer(undefined);\n }\n }\n\n this._layout = _layout as Layout | null;\n\n if (this._layout) {\n if (this._layout.measureChildren && typeof this._layout.updateItemSizes === 'function') {\n if (typeof this._layout.measureChildren === 'function') {\n this._measureChildOverride = this._layout.measureChildren;\n }\n this._measureCallback = this._layout.updateItemSizes.bind(this._layout);\n }\n this._layout.addEventListener('scrollsizechange', this);\n this._layout.addEventListener('scrollerrorchange', this);\n this._layout.addEventListener('itempositionchange', this);\n this._layout.addEventListener('rangechange', this);\n this._container![scrollerRef] = this;\n if (this._layout.listenForChildLoadEvents) {\n this._container!.addEventListener('load', this._loadListener, true);\n }\n this._schedule(this._updateLayout);\n }\n }\n\n // TODO (graynorton): Rework benchmarking so that it has no API and\n // instead is always on except in production builds\n startBenchmarking() {\n if (this._benchmarkStart === null) {\n this._benchmarkStart = window.performance.now();\n }\n }\n\n stopBenchmarking() {\n if (this._benchmarkStart !== null) {\n const now = window.performance.now();\n const timeElapsed = now - this._benchmarkStart;\n const entries = performance.getEntriesByName('uv-virtualizing', 'measure');\n const virtualizationTime = entries\n .filter(e => e.startTime >= this._benchmarkStart! && e.startTime < now)\n .reduce((t, m) => t + m.duration, 0);\n this._benchmarkStart = null;\n return { timeElapsed, virtualizationTime };\n }\n return null;\n }\n\n private _measureChildren(): void {\n const mm: ChildMeasurements = {};\n const children = this._children;\n const fn = this._measureChildOverride || this._measureChild;\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n const idx = this._first + i;\n if (this._itemsChanged || this._toBeMeasured.has(child)) {\n mm[idx] = fn.call(this, child, this._items[idx] /*as unknown as object*/);\n }\n }\n this._childMeasurements = mm;\n this._schedule(this._updateLayout);\n this._toBeMeasured.clear();\n }\n\n /**\n * Returns the width, height, and margins of the given child.\n */\n _measureChild(element: Element): ItemBox {\n // offsetWidth doesn't take transforms in consideration, so we use\n // getBoundingClientRect which does.\n const {width, height} = element.getBoundingClientRect();\n return Object.assign({width, height}, getMargins(element));\n }\n\n\n /**\n * The element that generates scroll events and defines the container\n * viewport. The value `null` (default) corresponds to `window` as scroll\n * target.\n */\n get scrollTarget(): Element | Window | null {\n return this._scrollTarget;\n }\n set scrollTarget(target: Element | Window | null) {\n // Consider window as null.\n if (target === window) {\n target = null;\n }\n if (this._scrollTarget === target) {\n return;\n }\n this._sizeContainer(undefined);\n if (this._scrollTarget) {\n this._scrollTarget.removeEventListener('scroll', this, {passive: true} as EventListenerOptions);\n if (this._sizer && this._scrollTarget === this._containerElement) {\n this._sizer.remove();\n }\n }\n\n this._scrollTarget = target as (Element | null);\n\n if (target) {\n target.addEventListener('scroll', this, {passive: true});\n if (target === this._containerElement) {\n this._sizer = this._sizer || this._createContainerSizer();\n this._container!.insertBefore(this._sizer, this._container!.firstChild);\n }\n }\n }\n\n /**\n * Index and position of item to scroll to. The scroller will fix to that point\n * until the user scrolls.\n */\n set scrollToIndex(newValue: ScrollToIndexValue) {\n this._scrollToIndex = newValue;\n this._schedule(this._updateLayout);\n }\n\n protected async _schedule(method: Function): Promise {\n if (!this._scheduled.has(method)) {\n this._scheduled.add(method);\n await Promise.resolve();\n this._scheduled.delete(method);\n method.call(this);\n }\n }\n\n async _updateDOM() {\n const {_rangeChanged, _itemsChanged} = this;\n if (this._visibilityChanged) {\n this._notifyVisibility();\n this._visibilityChanged = false;\n }\n if (_rangeChanged || _itemsChanged) {\n this._notifyRange();\n this._rangeChanged = false;\n this._itemsChanged = false;\n await this._mutationPromise;\n }\n if (this._layout!.measureChildren) {\n this._children.forEach((child) => this._childrenRO!.observe(child));\n }\n this._positionChildren(this._childrenPos!);\n this._sizeContainer(this._scrollSize);\n if (this._scrollErr) {\n this._correctScrollError(this._scrollErr);\n this._scrollErr = null;\n }\n if (this._benchmarkStart && 'mark' in window.performance) {\n window.performance.mark('uv-end');\n }\n }\n\n _updateLayout() {\n this._layout!.totalItems = this._totalItems!;\n if (this._scrollToIndex !== null) {\n this._layout!.scrollToIndex(this._scrollToIndex.index, this._scrollToIndex!.position!);\n this._scrollToIndex = null;\n }\n this._updateView();\n if (this._childMeasurements !== null) {\n // If the layout has been changed, we may have measurements but no callback\n if (this._measureCallback) {\n this._measureCallback(this._childMeasurements);\n }\n this._childMeasurements = null;\n }\n this._layout!.reflowIfNeeded(this._itemsChanged);\n if (this._benchmarkStart && 'mark' in window.performance) {\n window.performance.mark('uv-end');\n }\n }\n\n private _handleScrollEvent() {\n if (this._benchmarkStart && 'mark' in window.performance) {\n try {\n window.performance.measure(\n 'uv-virtualizing',\n 'uv-start',\n 'uv-end'\n );\n } catch(e) {\n console.warn('Error measuring performance data: ', e);\n }\n window.performance.mark('uv-start');\n }\n this._schedule(this._updateLayout);\n }\n\n handleEvent(event: CustomEvent) {\n switch (event.type) {\n case 'scroll':\n if (!this._scrollTarget || event.target === this._scrollTarget) {\n this._handleScrollEvent();\n }\n break;\n case 'scrollsizechange':\n this._scrollSize = event.detail;\n this._schedule(this._updateDOM);\n break;\n case 'scrollerrorchange':\n this._scrollErr = event.detail;\n this._schedule(this._updateDOM);\n break;\n case 'itempositionchange':\n this._childrenPos = event.detail;\n this._schedule(this._updateDOM);\n break;\n case 'rangechange':\n this._adjustRange(event.detail);\n this._schedule(this._updateDOM);\n break;\n default:\n console.warn('event not handled', event);\n }\n }\n\n private async _initResizeObservers() {\n if (this._containerRO === null) {\n const ResizeObserver = await getResizeObserver();\n this._containerRO = new ResizeObserver(\n (entries: ResizeObserverEntry[]) => this._containerSizeChanged(entries[0].contentRect));\n this._childrenRO =\n new ResizeObserver(this._childrenSizeChanged.bind(this));\n this._mutationObserver = new MutationObserver(this._observeMutations.bind(this));\n }\n }\n\n private _createContainerSizer(): HTMLDivElement {\n const sizer = document.createElement('div');\n // When the scrollHeight is large, the height of this element might be\n // ignored. Setting content and font-size ensures the element has a size.\n Object.assign(sizer.style, {\n position: 'absolute',\n margin: '-2px 0 0 0',\n padding: 0,\n visibility: 'hidden',\n fontSize: '2px',\n });\n sizer.innerHTML = ' ';\n sizer.id = 'uni-virtualizer-spacer';\n return sizer;\n }\n\n get _children(): Array {\n const arr = [];\n let next = this.container!.firstElementChild as HTMLElement;\n while (next) {\n // Skip our spacer. TODO (graynorton): Feels a bit hacky. Anything better?\n if (next.id !== 'uni-virtualizer-spacer') {\n arr.push(next);\n }\n next = next.nextElementSibling as HTMLElement;\n }\n return arr;\n }\n\n private _updateView() {\n if (!this.container || !this._containerElement || !this._layout) {\n return;\n }\n let width, height, top, left;\n if (this._scrollTarget === this._containerElement && this._containerSize !== null) {\n width = this._containerSize.width;\n height = this._containerSize.height;\n left = this._containerElement.scrollLeft;\n top = this._containerElement.scrollTop;\n } else {\n const containerBounds = this._containerElement.getBoundingClientRect();\n const scrollBounds = this._scrollTarget ?\n this._scrollTarget.getBoundingClientRect() :\n {\n top: containerBounds.top + window.pageYOffset,\n left: containerBounds.left + window.pageXOffset,\n width: innerWidth,\n height: innerHeight\n };\n const scrollerWidth = scrollBounds.width;\n const scrollerHeight = scrollBounds.height;\n const xMin = Math.max(\n 0, Math.min(scrollerWidth, containerBounds.left - scrollBounds.left));\n const yMin = Math.max(\n 0, Math.min(scrollerHeight, containerBounds.top - scrollBounds.top));\n // TODO (graynorton): Direction is intended to be a layout-level concept, not a scroller-level concept,\n // so this feels like a factoring problem\n const xMax = this._layout.direction === 'vertical' ?\n Math.max(\n 0,\n Math.min(\n scrollerWidth, containerBounds.right - scrollBounds.left)) :\n scrollerWidth;\n const yMax = this._layout.direction === 'vertical' ?\n scrollerHeight :\n Math.max(\n 0,\n Math.min(\n scrollerHeight, containerBounds.bottom - scrollBounds.top));\n width = xMax - xMin;\n height = yMax - yMin;\n left = Math.max(0, -(containerBounds.left - scrollBounds.left));\n top = Math.max(0, -(containerBounds.top - scrollBounds.top));\n }\n this._layout.viewportSize = {width, height};\n this._layout.viewportScroll = {top, left};\n }\n\n /**\n * Styles the _sizer element or the container so that its size reflects the\n * total size of all items.\n */\n private _sizeContainer(size?: ScrollSize | null) {\n if (this._scrollTarget === this._containerElement) {\n const left = size && (size as HorizontalScrollSize).width ? (size as HorizontalScrollSize).width - 1 : 0;\n const top = size && (size as VerticalScrollSize).height ? (size as VerticalScrollSize).height - 1 : 0;\n if (this._sizer) {\n this._sizer.style.transform = `translate(${left}px, ${top}px)`;\n }\n } else {\n if (this._containerElement) {\n const style = (this._containerElement as HTMLElement).style;\n (style.minWidth as string | null) = size && (size as HorizontalScrollSize).width ? (size as HorizontalScrollSize).width + 'px' : null;\n (style.minHeight as string | null) = size && (size as VerticalScrollSize).height ? (size as VerticalScrollSize).height + 'px' : null; \n }\n }\n }\n\n /**\n * Sets the top and left transform style of the children from the values in\n * pos.\n */\n private _positionChildren(pos: Array<{top: number, left: number, width?: number, height?: number}>) {\n if (pos) {\n const children = this._children;\n Object.keys(pos).forEach((key) => {\n const idx = (key as unknown as number) - this._first;\n const child = children[idx];\n if (child) {\n const {top, left, width, height} = pos[key as unknown as number];\n child.style.position = 'absolute';\n child.style.boxSizing = 'border-box';\n child.style.transform = `translate(${left}px, ${top}px)`;\n if (width !== undefined) {\n child.style.width = width + 'px';\n }\n if (height !== undefined) {\n child.style.height = height + 'px';\n }\n }\n }); \n }\n }\n\n private async _adjustRange(range: Range) {\n const {_first, _last, _firstVisible, _lastVisible} = this;\n this._first = range.first;\n this._last = range.last;\n this._firstVisible = range.firstVisible;\n this._lastVisible = range.lastVisible;\n this._rangeChanged = (\n this._rangeChanged ||\n this._first !== _first ||\n this._last !== _last\n );\n this._visibilityChanged = (\n this._visibilityChanged ||\n this._firstVisible !== _firstVisible ||\n this._lastVisible !== _lastVisible\n );\n }\n\n private _correctScrollError(err: {top: number, left: number}) {\n if (this._scrollTarget) {\n this._scrollTarget.scrollTop -= err.top;\n this._scrollTarget.scrollLeft -= err.left;\n } else {\n window.scroll(window.pageXOffset - err.left, window.pageYOffset - err.top);\n }\n }\n\n /**\n * Emits a rangechange event with the current first, last, firstVisible, and\n * lastVisible.\n */\n private _notifyRange() {\n // TODO (graynorton): Including visibility here for backward compat, but \n // may decide to remove at some point. The rationale for separating is that\n // range change events are mainly intended for \"internal\" consumption by the\n // renderer, whereas visibility change events are mainly intended for \"external\"\n // consumption by application code.\n this._container!.dispatchEvent(\n new CustomEvent('rangeChanged', {detail:{\n first: this._first,\n last: this._last,\n firstVisible: this._firstVisible,\n lastVisible: this._lastVisible,\n }})\n );\n }\n\n private _notifyVisibility() {\n this._container!.dispatchEvent(\n new CustomEvent('visibilityChanged', {detail:{\n first: this._first,\n last: this._last,\n firstVisible: this._firstVisible,\n lastVisible: this._lastVisible,\n }})\n );\n }\n\n /**\n * Render and update the view at the next opportunity with the given\n * container size.\n */\n private _containerSizeChanged(size: {width: number, height: number}) {\n const {width, height} = size;\n this._containerSize = {width, height};\n this._schedule(this._updateLayout);\n }\n\n private async _observeMutations() {\n if (!this._mutationsObserved) {\n this._mutationsObserved = true;\n this._mutationPromiseResolver!();\n this._mutationPromise = new Promise(resolve => this._mutationPromiseResolver = resolve);\n this._mutationsObserved = false;\n }\n }\n\n // TODO (graynorton): Rethink how this works. Probably child loading is too specific\n // to have dedicated support for; might want some more generic lifecycle hooks for\n // layouts to use. Possibly handle measurement this way, too, or maybe that remains\n // a first-class feature?\n\n private _childLoaded() {\n // this.requestRemeasure();\n }\n\n private _childrenSizeChanged(changes: ResizeObserverEntry[]) {\n for (const change of changes) {\n this._toBeMeasured.set(change.target as HTMLElement, change.contentRect);\n }\n this._measureChildren();\n this._schedule(this._updateLayout);\n }\n}\n\nfunction getMargins(el: Element): Margins {\n const style = window.getComputedStyle(el);\n return {\n marginTop: getMarginValue(style.marginTop),\n marginRight: getMarginValue(style.marginRight),\n marginBottom: getMarginValue(style.marginBottom),\n marginLeft: getMarginValue(style.marginLeft),\n };\n}\n\nfunction getMarginValue(value: string): number {\n const float = value ? parseFloat(value) : NaN;\n return Number.isNaN(float) ? 0 : float;\n}"]} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout.d.ts b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout.d.ts new file mode 100644 index 0000000000..d6e549b396 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout.d.ts @@ -0,0 +1,90 @@ +export declare type dimension = "height" | "width"; +export declare type Size = { + [key in dimension]: number; +}; +export declare type Margins = { + marginTop: number; + marginRight: number; + marginBottom: number; + marginLeft: number; +}; +export declare type ItemBox = Size | (Size & Margins); +export declare type position = "left" | "top"; +export declare type Positions = { + left: number; + top: number; + width?: number; + height?: number; +}; +export declare type LayoutConstructor = new (config?: object) => Layout; +export interface LayoutSpecifier { + type: LayoutConstructor; +} +export declare type LayoutSpecifierFactory = ( + config?: object +) => LayoutSpecifier; +export declare type ScrollDirection = "vertical" | "horizontal"; +/** + * Interface for layouts consumed by VirtualScroller or VirtualRepeater. + */ +export interface Layout { + config?: object; + totalItems: number; + direction: ScrollDirection; + viewportSize: Size; + viewportScroll: Positions; + readonly measureChildren?: boolean | ((e: Element, i: unknown) => ItemBox); + readonly listenForChildLoadEvents?: boolean; + updateItemSizes?: (sizes: { [key: number]: ItemBox }) => void; + addEventListener: Function; + removeEventListener: Function; + scrollToIndex: (index: number, position: string) => void; + /** + * Called by a VirtualRepeater or VirtualScroller when an update that + * potentially affects layout has occurred. For example, a viewport size + * change. + * + * The layout is in turn responsible for dispatching events, as necessary, + * to the VirtualRepeater or VirtualScroller. Each of the following events + * represents an update that should be determined during a reflow. Dispatch + * each event at maximum once during a single reflow. + * + * Events that should be dispatched: + * - scrollsizechange + * Dispatch when the total length of all items in the scrolling direction, + * including spacing, changes. + * detail: { + * 'height' | 'width': number + * } + * - rangechange + * Dispatch when the range of children that should be displayed changes + * (based on layout calculations and the size of the container) or when + * the first or last item to intersect the container changes. + * detail: { + * first: number, + * last: number, + * num: number, + * stable: boolean, + * remeasure: boolean, + * firstVisible: number, + * lastVisible: number, + * } + * - itempositionchange + * Dispatch when the child positions change, for example due to a range + * change. + * detail { + * [number]: { + * left: number, + * top: number + * } + * } + * - scrollerrorchange + * Dispatch when the set viewportScroll offset is not what it should be. + * detail { + * height: number, + * width: number, + * } + */ + reflowIfNeeded: (force: boolean) => void; +} +//# sourceMappingURL=Layout.d.ts.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout.d.ts.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout.d.ts.map new file mode 100644 index 0000000000..13497a406b --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Layout.d.ts","sourceRoot":"","sources":["../../../../src/lib/uni-virtualizer/lib/layouts/Layout.ts"],"names":[],"mappings":"AAAA,oBAAY,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAC3C,oBAAY,IAAI,GAAG;KAChB,GAAG,IAAI,SAAS,GAAG,MAAM;CAC3B,CAAC;AAEF,oBAAY,OAAO,GAAG;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAA;CACnB,CAAC;AAEF,oBAAY,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC;AAE9C,oBAAY,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;AACtC,oBAAY,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAC;AAGF,oBAAY,iBAAiB,GAAG,KAAI,MAAM,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;AAE/D,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,iBAAiB,CAAA;CACxB;AAED,oBAAY,sBAAsB,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,eAAe,CAAC;AAG1E,oBAAY,eAAe,GAAG,UAAU,GAAG,YAAY,CAAC;AAExD;;GAEG;AACF,MAAM,WAAW,MAAM;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,UAAU,EAAE,MAAM,CAAC;IAEnB,SAAS,EAAE,eAAe,CAAC;IAE3B,YAAY,EAAE,IAAI,CAAC;IAEnB,cAAc,EAAE,SAAS,CAAC;IAE1B,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC;IAE3E,QAAQ,CAAC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAE5C,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE;QACxB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KACvB,KAAK,IAAI,CAAC;IAEX,gBAAgB,EAAE,QAAQ,CAAC;IAE3B,mBAAmB,EAAE,QAAQ,CAAC;IAE9B,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6CG;IACH,cAAc,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAC1C"} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout.js b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout.js new file mode 100644 index 0000000000..d99f71dc72 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout.js @@ -0,0 +1,2 @@ +export {}; +//# sourceMappingURL=Layout.js.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout.js.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout.js.map new file mode 100644 index 0000000000..a95ae35dbf --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Layout.js","sourceRoot":"","sources":["../../../../src/lib/uni-virtualizer/lib/layouts/Layout.ts"],"names":[],"mappings":"","sourcesContent":["export type dimension = 'height' | 'width';\nexport type Size = {\n [key in dimension]: number\n};\n\nexport type Margins = {\n marginTop: number,\n marginRight: number,\n marginBottom: number,\n marginLeft: number\n};\n\nexport type ItemBox = Size | (Size & Margins);\n\nexport type position = 'left' | 'top';\nexport type Positions = {\n left: number,\n top: number,\n width?: number,\n height?: number\n};\n\n\nexport type LayoutConstructor = new(config?: object) => Layout;\n\nexport interface LayoutSpecifier {\n type: LayoutConstructor\n}\n\nexport type LayoutSpecifierFactory = (config?: object) => LayoutSpecifier;\n\n\nexport type ScrollDirection = 'vertical' | 'horizontal';\n\n/**\n * Interface for layouts consumed by VirtualScroller or VirtualRepeater.\n */\n export interface Layout {\n config?: object;\n \n totalItems: number;\n\n direction: ScrollDirection;\n\n viewportSize: Size;\n\n viewportScroll: Positions;\n\n readonly measureChildren?: boolean | ((e: Element, i: unknown) => ItemBox);\n\n readonly listenForChildLoadEvents?: boolean;\n\n updateItemSizes?: (sizes: {\n [key: number]: ItemBox\n }) => void;\n\n addEventListener: Function;\n\n removeEventListener: Function;\n\n scrollToIndex: (index: number, position: string) => void;\n\n /**\n * Called by a VirtualRepeater or VirtualScroller when an update that\n * potentially affects layout has occurred. For example, a viewport size\n * change.\n *\n * The layout is in turn responsible for dispatching events, as necessary,\n * to the VirtualRepeater or VirtualScroller. Each of the following events\n * represents an update that should be determined during a reflow. Dispatch\n * each event at maximum once during a single reflow.\n *\n * Events that should be dispatched:\n * - scrollsizechange\n * Dispatch when the total length of all items in the scrolling direction,\n * including spacing, changes.\n * detail: {\n * 'height' | 'width': number\n * }\n * - rangechange\n * Dispatch when the range of children that should be displayed changes\n * (based on layout calculations and the size of the container) or when\n * the first or last item to intersect the container changes.\n * detail: {\n * first: number,\n * last: number,\n * num: number,\n * stable: boolean,\n * remeasure: boolean,\n * firstVisible: number,\n * lastVisible: number,\n * }\n * - itempositionchange\n * Dispatch when the child positions change, for example due to a range\n * change.\n * detail {\n * [number]: {\n * left: number,\n * top: number\n * }\n * }\n * - scrollerrorchange\n * Dispatch when the set viewportScroll offset is not what it should be.\n * detail {\n * height: number,\n * width: number,\n * }\n */\n reflowIfNeeded: (force: boolean) => void;\n}"]} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1d.d.ts b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1d.d.ts new file mode 100644 index 0000000000..a9550273cf --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1d.d.ts @@ -0,0 +1,108 @@ +import { Layout1dBase, Layout1dBaseConfig } from "./Layout1dBase.js"; +import { ItemBox, Positions, Size } from "./Layout.js"; +declare type ItemBounds = { + pos: number; + size: number; +}; +declare type Layout1dConstructor = { + prototype: Layout1d; + new (config?: Layout1dBaseConfig): Layout1d; +}; +declare type Layout1dSpecifier = Layout1dBaseConfig & { + type: Layout1dConstructor; +}; +declare type Layout1dSpecifierFactory = ( + config?: Layout1dBaseConfig +) => Layout1dSpecifier; +export declare const layout1d: Layout1dSpecifierFactory; +export declare class Layout1d extends Layout1dBase { + /** + * Indices of children mapped to their (position and length) in the scrolling + * direction. Used to keep track of children that are in range. + */ + _physicalItems: Map; + /** + * Used in tandem with _physicalItems to track children in range across + * reflows. + */ + _newPhysicalItems: Map; + /** + * Width and height of children by their index. + */ + _metrics: Map; + /** + * anchorIdx is the anchor around which we reflow. It is designed to allow + * jumping to any point of the scroll size. We choose it once and stick with + * it until stable. _first and _last are deduced around it. + */ + _anchorIdx: number | null; + /** + * Position in the scrolling direction of the anchor child. + */ + _anchorPos: number | null; + /** + * Whether all children in range were in range during the previous reflow. + */ + _stable: boolean; + /** + * Whether to remeasure children during the next reflow. + */ + _needsRemeasure: boolean; + /** + * Number of children to lay out. + */ + private _nMeasured; + /** + * Total length in the scrolling direction of the laid out children. + */ + private _tMeasured; + private _measureChildren; + _estimate: boolean; + get measureChildren(): boolean; + /** + * Determine the average size of all children represented in the sizes + * argument. + */ + updateItemSizes(sizes: { [key: number]: ItemBox }): void; + /** + * Set the average item size based on the total length and number of children + * in range. + */ + _updateItemSize(): void; + _getMetrics(idx: number): ItemBox; + _getPhysicalItem(idx: number): ItemBounds | undefined; + _getSize(idx: number): number | undefined; + /** + * Returns the position in the scrolling direction of the item at idx. + * Estimates it if the item at idx is not in the DOM. + */ + _getPosition(idx: number): number; + _calculateAnchor(lower: number, upper: number): number; + _getAnchor(lower: number, upper: number): number; + /** + * Updates _first and _last based on items that should be in the current + * viewed range. + */ + _getActiveItems(): void; + /** + * Sets the range to empty. + */ + _clearItems(): void; + _getItems(): void; + _calculateError(): number; + _updateScrollSize(): void; + _reflow(): void; + _resetReflowState(): void; + /** + * Returns the top and left positioning of the item at idx. + */ + _getItemPosition(idx: number): Positions; + /** + * Returns the height and width of the item at idx. + */ + _getItemSize(idx: number): Size; + _viewDim2Changed(): void; + _emitRange(): void; +} +export {}; +//# sourceMappingURL=Layout1d.d.ts.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1d.d.ts.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1d.d.ts.map new file mode 100644 index 0000000000..16037434e7 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1d.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Layout1d.d.ts","sourceRoot":"","sources":["../../../../src/lib/uni-virtualizer/lib/layouts/Layout1d.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,kBAAkB,EAAC,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAU,MAAM,aAAa,CAAC;AAE9D,aAAK,UAAU,GAAG;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAA;CACb,CAAC;AAEF,aAAK,mBAAmB,GAAG;IACzB,SAAS,EAAE,QAAQ,CAAC;IACpB,KAAI,MAAM,CAAC,EAAE,kBAAkB,GAAG,QAAQ,CAAA;CAC3C,CAAA;AAED,aAAK,iBAAiB,GAAG,kBAAkB,GAAG;IAC5C,IAAI,EAAE,mBAAmB,CAAA;CAC1B,CAAA;AAED,aAAK,wBAAwB,GAAG,CAAC,MAAM,CAAC,EAAE,kBAAkB,KAAK,iBAAiB,CAAC;AAEnF,eAAO,MAAM,QAAQ,EAAE,wBAEb,CAAC;AAGX,qBAAa,QAAS,SAAQ,YAAY,CAAC,kBAAkB,CAAC;IAC5D;;;OAGG;IACH,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAa;IAEpD;;;OAGG;IACH,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAa;IAEvD;;OAEG;IACH,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAa;IAExC;;;;OAIG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEjC;;OAEG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEjC;;OAEG;IACH,OAAO,UAAQ;IAEf;;OAEG;IACH,eAAe,UAAS;IAExB;;OAEG;IACH,OAAO,CAAC,UAAU,CAAK;IAEvB;;OAEG;IACH,OAAO,CAAC,UAAU,CAAK;IAEvB,OAAO,CAAC,gBAAgB,CAAQ;IAEhC,SAAS,UAAQ;IAUjB,IAAI,eAAe,YAElB;IAED;;;OAGG;IACH,eAAe,CAAC,KAAK,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAC;IAmC/C;;;OAGG;IACH,eAAe;IAMf,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IASjC,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAIrD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAKzC;;;OAGG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAKjC,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IActD,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAqDhD;;;OAGG;IACH,eAAe;IAQf;;OAEG;IACH,WAAW;IAeX,SAAS;IA+GT,eAAe,IAAI,MAAM;IAezB,iBAAiB;IAQjB,OAAO;IA0BP,iBAAiB;IAMjB;;OAEG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS;IAOxC;;OAEG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAO/B,gBAAgB;IAKhB,UAAU;CAMX"} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1d.js b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1d.js new file mode 100644 index 0000000000..7ded2f7588 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1d.js @@ -0,0 +1,406 @@ +import { Layout1dBase } from "./Layout1dBase.js"; +export const layout1d = (config) => + Object.assign( + { + type: Layout1d, + }, + config + ); +export class Layout1d extends Layout1dBase { + constructor() { + super(...arguments); + /** + * Indices of children mapped to their (position and length) in the scrolling + * direction. Used to keep track of children that are in range. + */ + this._physicalItems = new Map(); + /** + * Used in tandem with _physicalItems to track children in range across + * reflows. + */ + this._newPhysicalItems = new Map(); + /** + * Width and height of children by their index. + */ + this._metrics = new Map(); + /** + * anchorIdx is the anchor around which we reflow. It is designed to allow + * jumping to any point of the scroll size. We choose it once and stick with + * it until stable. _first and _last are deduced around it. + */ + this._anchorIdx = null; + /** + * Position in the scrolling direction of the anchor child. + */ + this._anchorPos = null; + /** + * Whether all children in range were in range during the previous reflow. + */ + this._stable = true; + /** + * Whether to remeasure children during the next reflow. + */ + this._needsRemeasure = false; + /** + * Number of children to lay out. + */ + this._nMeasured = 0; + /** + * Total length in the scrolling direction of the laid out children. + */ + this._tMeasured = 0; + this._measureChildren = true; + this._estimate = true; + } + // protected _defaultConfig: Layout1dBaseConfig = Object.assign({}, super._defaultConfig, { + // }) + // constructor(config: Layout1dConfig) { + // super(config); + // } + get measureChildren() { + return this._measureChildren; + } + /** + * Determine the average size of all children represented in the sizes + * argument. + */ + updateItemSizes(sizes) { + Object.keys(sizes).forEach((key) => { + const metrics = sizes[Number(key)], + mi = this._getMetrics(Number(key)), + prevSize = mi[this._sizeDim]; + // TODO(valdrin) Handle margin collapsing. + // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing + mi.width = + metrics.width + (metrics.marginLeft || 0) + (metrics.marginRight || 0); + mi.height = + metrics.height + (metrics.marginTop || 0) + (metrics.marginBottom || 0); + const size = mi[this._sizeDim]; + const item = this._getPhysicalItem(Number(key)); + if (item) { + let delta = 0; + if (size !== undefined) { + item.size = size; + if (prevSize === -1) { + delta = size; + this._nMeasured++; + } else { + delta = size - prevSize; + } + } + this._tMeasured = this._tMeasured + delta; + } + }); + if (this._nMeasured) { + this._updateItemSize(); + this._scheduleReflow(); + } + } + /** + * Set the average item size based on the total length and number of children + * in range. + */ + _updateItemSize() { + // Keep integer values. + this._itemSize[this._sizeDim] = Math.round( + this._tMeasured / this._nMeasured + ); + } + _getMetrics(idx) { + let metrics = this._metrics.get(idx); + if (metrics === undefined) { + metrics = { height: -1, width: -1 }; + this._metrics.set(idx, metrics); + } + return metrics; + } + _getPhysicalItem(idx) { + return this._newPhysicalItems.get(idx) || this._physicalItems.get(idx); + } + _getSize(idx) { + const item = this._getPhysicalItem(idx); + return item && item.size; + } + /** + * Returns the position in the scrolling direction of the item at idx. + * Estimates it if the item at idx is not in the DOM. + */ + _getPosition(idx) { + const item = this._getPhysicalItem(idx); + return item ? item.pos : idx * this._delta + this._spacing; + } + _calculateAnchor(lower, upper) { + if (lower === 0) { + return 0; + } + if (upper > this._scrollSize - this._viewDim1) { + return this._totalItems - 1; + } + return Math.max( + 0, + Math.min( + this._totalItems - 1, + Math.floor((lower + upper) / 2 / this._delta) + ) + ); + } + _getAnchor(lower, upper) { + if (this._physicalItems.size === 0) { + return this._calculateAnchor(lower, upper); + } + if (this._first < 0) { + console.error("_getAnchor: negative _first"); + return this._calculateAnchor(lower, upper); + } + if (this._last < 0) { + console.error("_getAnchor: negative _last"); + return this._calculateAnchor(lower, upper); + } + const firstItem = this._getPhysicalItem(this._first), + lastItem = this._getPhysicalItem(this._last), + firstMin = firstItem.pos, + firstMax = firstMin + firstItem.size, + lastMin = lastItem.pos, + lastMax = lastMin + lastItem.size; + if (lastMax < lower) { + // Window is entirely past physical items, calculate new anchor + return this._calculateAnchor(lower, upper); + } + if (firstMin > upper) { + // Window is entirely before physical items, calculate new anchor + return this._calculateAnchor(lower, upper); + } + if (firstMin >= lower || firstMax >= lower) { + // First physical item overlaps window, choose it + return this._first; + } + if (lastMax <= upper || lastMin <= upper) { + // Last physical overlaps window, choose it + return this._last; + } + // Window contains a physical item, but not the first or last + let maxIdx = this._last, + minIdx = this._first; + while (true) { + const candidateIdx = Math.round((maxIdx + minIdx) / 2), + candidate = this._physicalItems.get(candidateIdx), + cMin = candidate.pos, + cMax = cMin + candidate.size; + if ( + (cMin >= lower && cMin <= upper) || + (cMax >= lower && cMax <= upper) + ) { + return candidateIdx; + } else if (cMax < lower) { + minIdx = candidateIdx + 1; + } else if (cMin > upper) { + maxIdx = candidateIdx - 1; + } + } + } + /** + * Updates _first and _last based on items that should be in the current + * viewed range. + */ + _getActiveItems() { + if (this._viewDim1 === 0 || this._totalItems === 0) { + this._clearItems(); + } else { + this._getItems(); + } + } + /** + * Sets the range to empty. + */ + _clearItems() { + this._first = -1; + this._last = -1; + this._physicalMin = 0; + this._physicalMax = 0; + const items = this._newPhysicalItems; + this._newPhysicalItems = this._physicalItems; + this._newPhysicalItems.clear(); + this._physicalItems = items; + this._stable = true; + } + /* + * Updates _first and _last based on items that should be in the given range. + */ + _getItems() { + const items = this._newPhysicalItems; + let lower, upper; + // The anchorIdx is the anchor around which we reflow. It is designed to + // allow jumping to any point of the scroll size. We choose it once and + // stick with it until stable. first and last are deduced around it. + if (this._scrollToIndex >= 0) { + // If we have a scrollToIndex, we anchor on the given + // index and set the scroll position accordingly + this._anchorIdx = this._scrollToIndex; + this._anchorPos = this._getPosition(this._anchorIdx); + this._scrollIfNeeded(); + lower = Math.max(0, this._scrollPosition - this._overhang); + upper = Math.min( + this._scrollSize, + this._scrollPosition + this._viewDim1 + this._overhang + ); + } else { + // Otherwise, we find an appropriate index to anchor on + // given the current scroll position + upper = Math.min( + this._scrollSize, + this._scrollPosition + this._viewDim1 + this._overhang + ); + lower = Math.max(0, upper - this._viewDim1 - 2 * this._overhang); + if (this._anchorIdx === null || this._anchorPos === null) { + this._anchorIdx = this._getAnchor(lower, upper); + this._anchorPos = this._getPosition(this._anchorIdx); + } + } + let anchorSize = this._getSize(this._anchorIdx); + if (anchorSize === undefined) { + anchorSize = this._itemDim1; + } + // Anchor might be outside bounds, so prefer correcting the error and keep + // that anchorIdx. + let anchorErr = 0; + if (this._anchorPos + anchorSize + this._spacing < lower) { + anchorErr = lower - (this._anchorPos + anchorSize + this._spacing); + } + if (this._anchorPos > upper) { + anchorErr = upper - this._anchorPos; + } + if (anchorErr) { + this._scrollPosition -= anchorErr; + lower -= anchorErr; + upper -= anchorErr; + this._scrollError += anchorErr; + } + // TODO @straversi: If size is always itemDim1, then why keep track of it? + items.set(this._anchorIdx, { pos: this._anchorPos, size: anchorSize }); + this._first = this._last = this._anchorIdx; + this._physicalMin = this._physicalMax = this._anchorPos; + this._stable = true; + while (this._physicalMin > lower && this._first > 0) { + let size = this._getSize(--this._first); + if (size === undefined) { + this._stable = false; + size = this._itemDim1; + } + const pos = (this._physicalMin -= size + this._spacing); + items.set(this._first, { pos, size }); + if (this._stable === false && this._estimate === false) { + break; + } + } + while (this._physicalMax < upper && this._last < this._totalItems) { + let size = this._getSize(this._last); + if (size === undefined) { + this._stable = false; + size = this._itemDim1; + } + items.set(this._last++, { pos: this._physicalMax, size }); + if (this._stable === false && this._estimate === false) { + break; + } else { + this._physicalMax += size + this._spacing; + } + } + this._last--; + // This handles the cases where we were relying on estimated sizes. + const extentErr = this._calculateError(); + if (extentErr) { + this._physicalMin -= extentErr; + this._physicalMax -= extentErr; + this._anchorPos -= extentErr; + this._scrollPosition -= extentErr; + items.forEach((item) => (item.pos -= extentErr)); + this._scrollError += extentErr; + } + if (this._stable) { + this._newPhysicalItems = this._physicalItems; + this._newPhysicalItems.clear(); + this._physicalItems = items; + } + } + _calculateError() { + if (this._first === 0) { + return this._physicalMin; + } else if (this._physicalMin <= 0) { + return this._physicalMin - this._first * this._delta; + } else if (this._last === this._totalItems - 1) { + return this._physicalMax - this._scrollSize; + } else if (this._physicalMax >= this._scrollSize) { + return ( + this._physicalMax - + this._scrollSize + + (this._totalItems - 1 - this._last) * this._delta + ); + } + return 0; + } + _updateScrollSize() { + // Reuse previously calculated physical max, as it might be higher than the + // estimated size. + super._updateScrollSize(); + this._scrollSize = Math.max(this._physicalMax, this._scrollSize); + } + // TODO: Can this be made to inherit from base, with proper hooks? + _reflow() { + const { _first, _last, _scrollSize } = this; + this._updateScrollSize(); + this._getActiveItems(); + if (this._scrollSize !== _scrollSize) { + this._emitScrollSize(); + } + this._updateVisibleIndices(); + this._emitRange(); + if (this._first === -1 && this._last === -1) { + this._resetReflowState(); + } else if ( + this._first !== _first || + this._last !== _last || + this._needsRemeasure + ) { + this._emitChildPositions(); + this._emitScrollError(); + } else { + this._emitChildPositions(); + this._emitScrollError(); + this._resetReflowState(); + } + } + _resetReflowState() { + this._anchorIdx = null; + this._anchorPos = null; + this._stable = true; + } + /** + * Returns the top and left positioning of the item at idx. + */ + _getItemPosition(idx) { + return { + [this._positionDim]: this._getPosition(idx), + [this._secondaryPositionDim]: 0, + }; + } + /** + * Returns the height and width of the item at idx. + */ + _getItemSize(idx) { + return { + [this._sizeDim]: this._getSize(idx) || this._itemDim1, + [this._secondarySizeDim]: this._itemDim2, + }; + } + _viewDim2Changed() { + this._needsRemeasure = true; + this._scheduleReflow(); + } + _emitRange() { + const remeasure = this._needsRemeasure; + const stable = this._stable; + this._needsRemeasure = false; + super._emitRange({ remeasure, stable }); + } +} +//# sourceMappingURL=Layout1d.js.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1d.js.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1d.js.map new file mode 100644 index 0000000000..53e2375c71 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1d.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Layout1d.js","sourceRoot":"","sources":["../../../../src/lib/uni-virtualizer/lib/layouts/Layout1d.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAqB,MAAM,mBAAmB,CAAC;AAmBnE,MAAM,CAAC,MAAM,QAAQ,GAA6B,CAAC,MAA2B,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC;IAC/F,IAAI,EAAE,QAAQ;CACf,EAAE,MAAM,CAAC,CAAC;AAGX,MAAM,OAAO,QAAS,SAAQ,YAAgC;IAA9D;;QACE;;;WAGG;QACH,mBAAc,GAA4B,IAAI,GAAG,EAAE,CAAC;QAEpD;;;WAGG;QACH,sBAAiB,GAA4B,IAAI,GAAG,EAAE,CAAC;QAEvD;;WAEG;QACH,aAAQ,GAAsB,IAAI,GAAG,EAAE,CAAC;QAExC;;;;WAIG;QACH,eAAU,GAAkB,IAAI,CAAC;QAEjC;;WAEG;QACH,eAAU,GAAkB,IAAI,CAAC;QAEjC;;WAEG;QACH,YAAO,GAAG,IAAI,CAAC;QAEf;;WAEG;QACH,oBAAe,GAAG,KAAK,CAAC;QAExB;;WAEG;QACK,eAAU,GAAG,CAAC,CAAC;QAEvB;;WAEG;QACK,eAAU,GAAG,CAAC,CAAC;QAEf,qBAAgB,GAAG,IAAI,CAAC;QAEhC,cAAS,GAAG,IAAI,CAAC;IAgYnB,CAAC;IA9XC,2FAA2F;IAE3F,KAAK;IAEL,wCAAwC;IACxC,mBAAmB;IACnB,IAAI;IAEJ,IAAI,eAAe;QACjB,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC/B,CAAC;IAED;;;OAGG;IACH,eAAe,CAAC,KAA+B;QAC7C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACjC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAChE,QAAQ,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAEnC,0CAA0C;YAC1C,6FAA6F;YAC7F,EAAE,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,GAAG,CAAE,OAAmB,CAAC,UAAU,IAAI,CAAC,CAAC;gBAC7D,CAAE,OAAmB,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;YAC5C,EAAE,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,CAAE,OAAmB,CAAC,SAAS,IAAI,CAAC,CAAC;gBAC9D,CAAE,OAAmB,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC;YAE7C,MAAM,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAChD,IAAI,IAAI,EAAE;gBACR,IAAI,KAAK,GAAG,CAAC,CAAC;gBAEd,IAAI,IAAI,KAAK,SAAS,EAAE;oBACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;oBACjB,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE;wBACnB,KAAK,GAAG,IAAI,CAAC;wBACb,IAAI,CAAC,UAAU,EAAE,CAAC;qBACnB;yBAAM;wBACL,KAAK,GAAG,IAAI,GAAG,QAAQ,CAAC;qBACzB;iBACF;gBACD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;aAC3C;QACH,CAAC,CAAC,CAAC;QACH,IAAI,IAAI,CAAC,UAAU,EAAE;YACnB,IAAI,CAAC,eAAe,EAAE,CAAC;YACvB,IAAI,CAAC,eAAe,EAAE,CAAC;SACxB;IACH,CAAC;IAED;;;OAGG;IACH,eAAe;QACb,uBAAuB;QACvB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;IACpD,CAAC;IAED,WAAW,CAAC,GAAW;QACrB,IAAI,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,OAAO,KAAK,SAAS,EAAE;YACzB,OAAO,GAAG,EAAC,MAAM,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAC,CAAC;YAClC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;SACjC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,gBAAgB,CAAC,GAAW;QAC1B,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzE,CAAC;IAED,QAAQ,CAAC,GAAW;QAClB,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACxC,OAAO,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACH,YAAY,CAAC,GAAW;QACtB,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACxC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;IACjE,CAAC;IAED,gBAAgB,CAAC,KAAa,EAAE,KAAa;QAC3C,IAAI,KAAK,KAAK,CAAC,EAAE;YACf,OAAO,CAAC,CAAC;SACV;QACD,IAAI,KAAK,GAAG,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE;YAC7C,OAAO,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;SAC7B;QACD,OAAO,IAAI,CAAC,GAAG,CACX,CAAC,EACD,IAAI,CAAC,GAAG,CACJ,IAAI,CAAC,WAAW,GAAG,CAAC,EACpB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,UAAU,CAAC,KAAa,EAAE,KAAa;QACrC,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,KAAK,CAAC,EAAE;YAClC,OAAO,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;SAC5C;QACD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;YACnB,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAC7C,OAAO,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;SAC5C;QACD,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE;YAClB,OAAO,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAC5C,OAAO,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;SAC5C;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,EAC9C,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,EAC5C,QAAQ,GAAG,SAAU,CAAC,GAAG,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAU,CAAC,IAAI,EAChE,OAAO,GAAG,QAAS,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,GAAG,QAAS,CAAC,IAAI,CAAC;QAElE,IAAI,OAAO,GAAG,KAAK,EAAE;YACnB,+DAA+D;YAC/D,OAAO,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;SAC5C;QACD,IAAI,QAAQ,GAAG,KAAK,EAAE;YACpB,iEAAiE;YACjE,OAAO,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;SAC5C;QACD,IAAI,QAAQ,IAAI,KAAK,IAAI,QAAQ,IAAI,KAAK,EAAE;YAC1C,iDAAiD;YACjD,OAAO,IAAI,CAAC,MAAM,CAAC;SACpB;QACD,IAAI,OAAO,IAAI,KAAK,IAAI,OAAO,IAAI,KAAK,EAAE;YACxC,2CAA2C;YAC3C,OAAO,IAAI,CAAC,KAAK,CAAC;SACnB;QACD,6DAA6D;QAC7D,IAAI,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAE9C,OAAO,IAAI,EAAE;YACX,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,EAChD,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,EACjD,IAAI,GAAG,SAAU,CAAC,GAAG,EAAE,IAAI,GAAG,IAAI,GAAG,SAAU,CAAC,IAAI,CAAC;YAE3D,IAAI,CAAC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC;gBAChC,CAAC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC,EAAE;gBACpC,OAAO,YAAY,CAAC;aACrB;iBAAM,IAAI,IAAI,GAAG,KAAK,EAAE;gBACvB,MAAM,GAAG,YAAY,GAAG,CAAC,CAAC;aAC3B;iBAAM,IAAI,IAAI,GAAG,KAAK,EAAE;gBACvB,MAAM,GAAG,YAAY,GAAG,CAAC,CAAC;aAC3B;SACF;IACH,CAAC;IAED;;;OAGG;IACH,eAAe;QACb,IAAI,IAAI,CAAC,SAAS,KAAK,CAAC,IAAI,IAAI,CAAC,WAAW,KAAK,CAAC,EAAE;YAClD,IAAI,CAAC,WAAW,EAAE,CAAC;SACpB;aAAM;YACL,IAAI,CAAC,SAAS,EAAE,CAAC;SAClB;IACH,CAAC;IAED;;OAEG;IACH,WAAW;QACT,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAChB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACtB,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC;QACrC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,cAAc,CAAC;QAC7C,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,SAAS;QACP,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC;QACrC,IAAI,KAAK,EAAE,KAAK,CAAC;QAEjB,wEAAwE;QACxE,uEAAuE;QACvE,oEAAoE;QAEpE,IAAI,IAAI,CAAC,cAAc,IAAI,CAAC,EAAE;YAC5B,qDAAqD;YACrD,gDAAgD;YAChD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC;YACtC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACrD,IAAI,CAAC,eAAe,EAAE,CAAC;YACvB,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;YAC3D,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;SAC5F;aACI;YACH,uDAAuD;YACvD,oCAAoC;YACpC,KAAK,GAAG,IAAI,CAAC,GAAG,CACd,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CACvD,CAAC;YACF,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;YAEnE,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;gBACxD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;gBAChD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;aACtD;SACF;QAED,IAAI,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAChD,IAAI,UAAU,KAAK,SAAS,EAAE;YAC5B,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC;SAC7B;QAED,0EAA0E;QAC1E,kBAAkB;QAClB,IAAI,SAAS,GAAG,CAAC,CAAC;QAElB,IAAI,IAAI,CAAC,UAAU,GAAG,UAAU,GAAG,IAAI,CAAC,QAAQ,GAAG,KAAK,EAAE;YACxD,SAAS,GAAG,KAAK,GAAG,CAAC,IAAI,CAAC,UAAU,GAAG,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;SACpE;QAED,IAAI,IAAI,CAAC,UAAU,GAAG,KAAK,EAAE;YAC3B,SAAS,GAAG,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC;SACrC;QAED,IAAI,SAAS,EAAE;YACb,IAAI,CAAC,eAAe,IAAI,SAAS,CAAC;YAClC,KAAK,IAAI,SAAS,CAAC;YACnB,KAAK,IAAI,SAAS,CAAC;YACnB,IAAI,CAAC,YAAY,IAAI,SAAS,CAAC;SAChC;QAED,0EAA0E;QAC1E,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,EAAC,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,UAAU,EAAC,CAAC,CAAC;QAErE,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,CAAC,YAAY,GAAG,CAAC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;QAE1D,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QAEpB,OAAO,IAAI,CAAC,YAAY,GAAG,KAAK,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;YACnD,IAAI,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YACxC,IAAI,IAAI,KAAK,SAAS,EAAE;gBACtB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;gBACrB,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;aACvB;YACD,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;YACxD,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,EAAC,GAAG,EAAE,IAAI,EAAC,CAAC,CAAC;YACpC,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK,IAAI,IAAI,CAAC,SAAS,KAAK,KAAK,EAAE;gBACtD,MAAM;aACP;SACF;QAED,OAAO,IAAI,CAAC,YAAY,GAAG,KAAK,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE;YACjE,IAAI,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrC,IAAI,IAAI,KAAK,SAAS,EAAE;gBACtB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;gBACrB,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;aACvB;YACD,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,EAAC,GAAG,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,EAAC,CAAC,CAAC;YACxD,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK,IAAI,IAAI,CAAC,SAAS,KAAK,KAAK,EAAE;gBACtD,MAAM;aACP;iBAAM;gBACL,IAAI,CAAC,YAAY,IAAI,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;aAC3C;SACF;QAED,IAAI,CAAC,KAAK,EAAE,CAAC;QAEb,mEAAmE;QACnE,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QACzC,IAAI,SAAS,EAAE;YACb,IAAI,CAAC,YAAY,IAAI,SAAS,CAAC;YAC/B,IAAI,CAAC,YAAY,IAAI,SAAS,CAAC;YAC/B,IAAI,CAAC,UAAU,IAAI,SAAS,CAAC;YAC7B,IAAI,CAAC,eAAe,IAAI,SAAS,CAAC;YAClC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,IAAI,SAAS,CAAC,CAAC;YAC/C,IAAI,CAAC,YAAY,IAAI,SAAS,CAAC;SAChC;QAED,IAAI,IAAI,CAAC,OAAO,EAAE;YAChB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,cAAc,CAAC;YAC7C,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;YAC/B,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;SAC7B;IACH,CAAC;IAED,eAAe;QACb,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;YACrB,OAAO,IAAI,CAAC,YAAY,CAAC;SAC1B;aAAM,IAAI,IAAI,CAAC,YAAY,IAAI,CAAC,EAAE;YACjC,OAAO,IAAI,CAAC,YAAY,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;SACxD;aAAM,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,WAAW,GAAG,CAAC,EAAE;YAC9C,OAAO,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC;SAC7C;aAAM,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,WAAW,EAAE;YAChD,OAAO,CACH,CAAC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC;gBACtC,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;SAC1D;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,iBAAiB;QACf,2EAA2E;QAC3E,kBAAkB;QAClB,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACnE,CAAC;IAED,kEAAkE;IAClE,OAAO;QACL,MAAM,EAAC,MAAM,EAAE,KAAK,EAAE,WAAW,EAAC,GAAG,IAAI,CAAC;QAE1C,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,IAAI,CAAC,eAAe,EAAE,CAAC;QAEvB,IAAI,IAAI,CAAC,WAAW,KAAK,WAAW,EAAE;YACpC,IAAI,CAAC,eAAe,EAAE,CAAC;SACxB;QAED,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC7B,IAAI,CAAC,UAAU,EAAE,CAAC;QAClB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC,EAAE;YAC3C,IAAI,CAAC,iBAAiB,EAAE,CAAC;SAC1B;aAAM,IACH,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK;YAC9C,IAAI,CAAC,eAAe,EAAE;YACxB,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,IAAI,CAAC,gBAAgB,EAAE,CAAC;SACzB;aAAM;YACL,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,IAAI,CAAC,iBAAiB,EAAE,CAAC;SAC1B;IACH,CAAC;IAED,iBAAiB;QACf,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,GAAW;QAC1B,OAAO;YACL,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC;YAC3C,CAAC,IAAI,CAAC,qBAAqB,CAAC,EAAE,CAAC;SACnB,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,GAAW;QACtB,OAAO;YACL,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,SAAS;YACrD,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,IAAI,CAAC,SAAS;SACjC,CAAC;IACZ,CAAC;IAED,gBAAgB;QACd,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC5B,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAED,UAAU;QACR,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QAC7B,KAAK,CAAC,UAAU,CAAC,EAAC,SAAS,EAAE,MAAM,EAAC,CAAC,CAAC;IACxC,CAAC;CACF","sourcesContent":["import {Layout1dBase, Layout1dBaseConfig} from './Layout1dBase.js';\nimport {ItemBox, Positions, Size, Margins} from './Layout.js';\n\ntype ItemBounds = {\n pos: number,\n size: number\n};\n\ntype Layout1dConstructor = {\n prototype: Layout1d,\n new(config?: Layout1dBaseConfig): Layout1d\n}\n\ntype Layout1dSpecifier = Layout1dBaseConfig & {\n type: Layout1dConstructor\n}\n\ntype Layout1dSpecifierFactory = (config?: Layout1dBaseConfig) => Layout1dSpecifier;\n\nexport const layout1d: Layout1dSpecifierFactory = (config?: Layout1dBaseConfig) => Object.assign({\n type: Layout1d\n}, config);\n\n\nexport class Layout1d extends Layout1dBase {\n /**\n * Indices of children mapped to their (position and length) in the scrolling\n * direction. Used to keep track of children that are in range.\n */\n _physicalItems: Map = new Map();\n\n /**\n * Used in tandem with _physicalItems to track children in range across\n * reflows.\n */\n _newPhysicalItems: Map = new Map();\n\n /**\n * Width and height of children by their index.\n */\n _metrics: Map = new Map();\n\n /**\n * anchorIdx is the anchor around which we reflow. It is designed to allow\n * jumping to any point of the scroll size. We choose it once and stick with\n * it until stable. _first and _last are deduced around it.\n */\n _anchorIdx: number | null = null;\n\n /**\n * Position in the scrolling direction of the anchor child.\n */\n _anchorPos: number | null = null;\n\n /**\n * Whether all children in range were in range during the previous reflow.\n */\n _stable = true;\n\n /**\n * Whether to remeasure children during the next reflow.\n */\n _needsRemeasure = false;\n\n /**\n * Number of children to lay out.\n */\n private _nMeasured = 0;\n\n /**\n * Total length in the scrolling direction of the laid out children.\n */\n private _tMeasured = 0;\n\n private _measureChildren = true;\n\n _estimate = true;\n\n // protected _defaultConfig: Layout1dBaseConfig = Object.assign({}, super._defaultConfig, {\n\n // })\n\n // constructor(config: Layout1dConfig) {\n // super(config);\n // }\n\n get measureChildren() {\n return this._measureChildren;\n }\n\n /**\n * Determine the average size of all children represented in the sizes\n * argument.\n */\n updateItemSizes(sizes: {[key: number]: ItemBox}) {\n Object.keys(sizes).forEach((key) => {\n const metrics = sizes[Number(key)], mi = this._getMetrics(Number(key)),\n prevSize = mi[this._sizeDim];\n\n // TODO(valdrin) Handle margin collapsing.\n // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing\n mi.width = metrics.width + ((metrics as Margins).marginLeft || 0) +\n ((metrics as Margins).marginRight || 0);\n mi.height = metrics.height + ((metrics as Margins).marginTop || 0) +\n ((metrics as Margins).marginBottom || 0);\n\n const size = mi[this._sizeDim];\n const item = this._getPhysicalItem(Number(key));\n if (item) {\n let delta = 0;\n\n if (size !== undefined) {\n item.size = size;\n if (prevSize === -1) {\n delta = size;\n this._nMeasured++;\n } else {\n delta = size - prevSize;\n }\n }\n this._tMeasured = this._tMeasured + delta;\n }\n });\n if (this._nMeasured) {\n this._updateItemSize();\n this._scheduleReflow();\n }\n }\n\n /**\n * Set the average item size based on the total length and number of children\n * in range.\n */\n _updateItemSize() {\n // Keep integer values.\n this._itemSize[this._sizeDim] =\n Math.round(this._tMeasured / this._nMeasured);\n }\n\n _getMetrics(idx: number): ItemBox {\n let metrics = this._metrics.get(idx);\n if (metrics === undefined) {\n metrics = {height: -1, width: -1};\n this._metrics.set(idx, metrics);\n }\n return metrics;\n }\n\n _getPhysicalItem(idx: number): ItemBounds | undefined {\n return this._newPhysicalItems.get(idx) || this._physicalItems.get(idx);\n }\n\n _getSize(idx: number): number | undefined {\n const item = this._getPhysicalItem(idx);\n return item && item.size;\n }\n\n /**\n * Returns the position in the scrolling direction of the item at idx.\n * Estimates it if the item at idx is not in the DOM.\n */\n _getPosition(idx: number): number {\n const item = this._getPhysicalItem(idx);\n return item ? item.pos : (idx * (this._delta)) + this._spacing;\n }\n\n _calculateAnchor(lower: number, upper: number): number {\n if (lower === 0) {\n return 0;\n }\n if (upper > this._scrollSize - this._viewDim1) {\n return this._totalItems - 1;\n }\n return Math.max(\n 0,\n Math.min(\n this._totalItems - 1,\n Math.floor(((lower + upper) / 2) / this._delta)));\n }\n\n _getAnchor(lower: number, upper: number): number {\n if (this._physicalItems.size === 0) {\n return this._calculateAnchor(lower, upper);\n }\n if (this._first < 0) {\n console.error('_getAnchor: negative _first');\n return this._calculateAnchor(lower, upper);\n }\n if (this._last < 0) {\n console.error('_getAnchor: negative _last');\n return this._calculateAnchor(lower, upper);\n }\n\n const firstItem = this._getPhysicalItem(this._first),\n lastItem = this._getPhysicalItem(this._last),\n firstMin = firstItem!.pos, firstMax = firstMin + firstItem!.size,\n lastMin = lastItem!.pos, lastMax = lastMin + lastItem!.size;\n\n if (lastMax < lower) {\n // Window is entirely past physical items, calculate new anchor\n return this._calculateAnchor(lower, upper);\n }\n if (firstMin > upper) {\n // Window is entirely before physical items, calculate new anchor\n return this._calculateAnchor(lower, upper);\n }\n if (firstMin >= lower || firstMax >= lower) {\n // First physical item overlaps window, choose it\n return this._first;\n }\n if (lastMax <= upper || lastMin <= upper) {\n // Last physical overlaps window, choose it\n return this._last;\n }\n // Window contains a physical item, but not the first or last\n let maxIdx = this._last, minIdx = this._first;\n\n while (true) {\n const candidateIdx = Math.round((maxIdx + minIdx) / 2),\n candidate = this._physicalItems.get(candidateIdx),\n cMin = candidate!.pos, cMax = cMin + candidate!.size;\n\n if ((cMin >= lower && cMin <= upper) ||\n (cMax >= lower && cMax <= upper)) {\n return candidateIdx;\n } else if (cMax < lower) {\n minIdx = candidateIdx + 1;\n } else if (cMin > upper) {\n maxIdx = candidateIdx - 1;\n }\n }\n }\n\n /**\n * Updates _first and _last based on items that should be in the current\n * viewed range.\n */\n _getActiveItems() {\n if (this._viewDim1 === 0 || this._totalItems === 0) {\n this._clearItems();\n } else {\n this._getItems();\n }\n }\n\n /**\n * Sets the range to empty.\n */\n _clearItems() {\n this._first = -1;\n this._last = -1;\n this._physicalMin = 0;\n this._physicalMax = 0;\n const items = this._newPhysicalItems;\n this._newPhysicalItems = this._physicalItems;\n this._newPhysicalItems.clear();\n this._physicalItems = items;\n this._stable = true;\n }\n\n /*\n * Updates _first and _last based on items that should be in the given range.\n */\n _getItems() {\n const items = this._newPhysicalItems;\n let lower, upper;\n\n // The anchorIdx is the anchor around which we reflow. It is designed to\n // allow jumping to any point of the scroll size. We choose it once and\n // stick with it until stable. first and last are deduced around it.\n\n if (this._scrollToIndex >= 0) {\n // If we have a scrollToIndex, we anchor on the given\n // index and set the scroll position accordingly\n this._anchorIdx = this._scrollToIndex;\n this._anchorPos = this._getPosition(this._anchorIdx);\n this._scrollIfNeeded();\n lower = Math.max(0, this._scrollPosition - this._overhang);\n upper = Math.min(this._scrollSize, this._scrollPosition + this._viewDim1 + this._overhang);\n }\n else {\n // Otherwise, we find an appropriate index to anchor on\n // given the current scroll position\n upper = Math.min(\n this._scrollSize,\n this._scrollPosition + this._viewDim1 + this._overhang\n );\n lower = Math.max(0, upper - this._viewDim1 - (2 * this._overhang));\n\n if (this._anchorIdx === null || this._anchorPos === null) {\n this._anchorIdx = this._getAnchor(lower, upper);\n this._anchorPos = this._getPosition(this._anchorIdx); \n }\n }\n\n let anchorSize = this._getSize(this._anchorIdx);\n if (anchorSize === undefined) {\n anchorSize = this._itemDim1;\n }\n\n // Anchor might be outside bounds, so prefer correcting the error and keep\n // that anchorIdx.\n let anchorErr = 0;\n\n if (this._anchorPos + anchorSize + this._spacing < lower) {\n anchorErr = lower - (this._anchorPos + anchorSize + this._spacing);\n }\n\n if (this._anchorPos > upper) {\n anchorErr = upper - this._anchorPos;\n }\n\n if (anchorErr) {\n this._scrollPosition -= anchorErr;\n lower -= anchorErr;\n upper -= anchorErr;\n this._scrollError += anchorErr;\n }\n\n // TODO @straversi: If size is always itemDim1, then why keep track of it?\n items.set(this._anchorIdx, {pos: this._anchorPos, size: anchorSize});\n\n this._first = (this._last = this._anchorIdx);\n this._physicalMin = (this._physicalMax = this._anchorPos);\n\n this._stable = true;\n\n while (this._physicalMin > lower && this._first > 0) {\n let size = this._getSize(--this._first);\n if (size === undefined) {\n this._stable = false;\n size = this._itemDim1;\n }\n const pos = (this._physicalMin -= size + this._spacing);\n items.set(this._first, {pos, size});\n if (this._stable === false && this._estimate === false) {\n break;\n }\n }\n\n while (this._physicalMax < upper && this._last < this._totalItems) {\n let size = this._getSize(this._last);\n if (size === undefined) {\n this._stable = false;\n size = this._itemDim1;\n }\n items.set(this._last++, {pos: this._physicalMax, size});\n if (this._stable === false && this._estimate === false) {\n break;\n } else {\n this._physicalMax += size + this._spacing;\n }\n }\n\n this._last--;\n\n // This handles the cases where we were relying on estimated sizes.\n const extentErr = this._calculateError();\n if (extentErr) {\n this._physicalMin -= extentErr;\n this._physicalMax -= extentErr;\n this._anchorPos -= extentErr;\n this._scrollPosition -= extentErr;\n items.forEach((item) => item.pos -= extentErr);\n this._scrollError += extentErr;\n }\n\n if (this._stable) {\n this._newPhysicalItems = this._physicalItems;\n this._newPhysicalItems.clear();\n this._physicalItems = items;\n }\n }\n\n _calculateError(): number {\n if (this._first === 0) {\n return this._physicalMin;\n } else if (this._physicalMin <= 0) {\n return this._physicalMin - (this._first * this._delta);\n } else if (this._last === this._totalItems - 1) {\n return this._physicalMax - this._scrollSize;\n } else if (this._physicalMax >= this._scrollSize) {\n return (\n (this._physicalMax - this._scrollSize) +\n ((this._totalItems - 1 - this._last) * this._delta));\n }\n return 0;\n }\n\n _updateScrollSize() {\n // Reuse previously calculated physical max, as it might be higher than the\n // estimated size.\n super._updateScrollSize();\n this._scrollSize = Math.max(this._physicalMax, this._scrollSize);\n }\n\n // TODO: Can this be made to inherit from base, with proper hooks?\n _reflow() {\n const {_first, _last, _scrollSize} = this;\n\n this._updateScrollSize();\n this._getActiveItems();\n\n if (this._scrollSize !== _scrollSize) {\n this._emitScrollSize();\n }\n\n this._updateVisibleIndices();\n this._emitRange();\n if (this._first === -1 && this._last === -1) {\n this._resetReflowState();\n } else if (\n this._first !== _first || this._last !== _last ||\n this._needsRemeasure) {\n this._emitChildPositions();\n this._emitScrollError();\n } else {\n this._emitChildPositions();\n this._emitScrollError();\n this._resetReflowState();\n }\n }\n\n _resetReflowState() {\n this._anchorIdx = null;\n this._anchorPos = null;\n this._stable = true;\n }\n\n /**\n * Returns the top and left positioning of the item at idx.\n */\n _getItemPosition(idx: number): Positions {\n return {\n [this._positionDim]: this._getPosition(idx),\n [this._secondaryPositionDim]: 0,\n } as Positions;\n }\n\n /**\n * Returns the height and width of the item at idx.\n */\n _getItemSize(idx: number): Size {\n return {\n [this._sizeDim]: this._getSize(idx) || this._itemDim1,\n [this._secondarySizeDim]: this._itemDim2,\n } as Size;\n }\n\n _viewDim2Changed() {\n this._needsRemeasure = true;\n this._scheduleReflow();\n }\n\n _emitRange() {\n const remeasure = this._needsRemeasure;\n const stable = this._stable;\n this._needsRemeasure = false;\n super._emitRange({remeasure, stable});\n }\n}\n"]} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dBase.d.ts b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dBase.d.ts new file mode 100644 index 0000000000..5e5624f343 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dBase.d.ts @@ -0,0 +1,236 @@ +import { + Layout, + Positions, + ScrollDirection, + Size, + dimension, + position, +} from "./Layout.js"; +declare type UpdateVisibleIndicesOptions = { + emit?: boolean; +}; +export interface Layout1dBaseConfig { + direction?: ScrollDirection; + totalItems?: number; +} +export declare abstract class Layout1dBase + implements Layout { + /** + * The last set viewport scroll position. + */ + private _latestCoords; + /** + * Scrolling direction. + */ + private _direction; + /** + * Dimensions of the viewport. + */ + private _viewportSize; + /** + * Flag for debouncing asynchnronous reflow requests. + */ + private _pendingReflow; + private _pendingLayoutUpdate; + /** + * Index of the item that has been scrolled to via the public API. When the + * container is otherwise scrolled, this value is set back to -1. + */ + protected _scrollToIndex: number; + /** + * When a child is scrolled to, the offset from the top of the child and the + * top of the viewport. Value is a proportion of the item size. + */ + private _scrollToAnchor; + /** + * The index of the first item intersecting the viewport. + */ + private _firstVisible; + /** + * The index of the last item intersecting the viewport. + */ + private _lastVisible; + private _eventTargetPromise; + /** + * Pixel offset in the scroll direction of the first child. + */ + protected _physicalMin: number; + /** + * Pixel offset in the scroll direction of the last child. + */ + protected _physicalMax: number; + /** + * Index of the first child. + */ + protected _first: number; + /** + * Index of the last child. + */ + protected _last: number; + /** + * The _estimated_ size of a child. + */ + protected _itemSize: Size; + /** + * Space in pixels between children. + */ + protected _spacing: number; + /** + * Length in the scrolling direction. + */ + protected _sizeDim: dimension; + /** + * Length in the non-scrolling direction. + */ + protected _secondarySizeDim: dimension; + /** + * Position in the scrolling direction. + */ + protected _positionDim: position; + /** + * Position in the non-scrolling direction. + */ + protected _secondaryPositionDim: position; + /** + * Current scroll offset in pixels. + */ + protected _scrollPosition: number; + /** + * Difference between current scroll offset and scroll offset calculated due + * to a reflow. + */ + protected _scrollError: number; + /** + * Total number of items that could possibly be displayed. Used to help + * calculate the scroll size. + */ + protected _totalItems: number; + /** + * The total (estimated) length of all items in the scrolling direction. + */ + protected _scrollSize: number; + /** + * Number of pixels beyond the visible size of the container to still include + * in the active range of items. + */ + protected _overhang: number; + private _eventTarget; + protected _spacingChanged: boolean; + protected _defaultConfig: C; + constructor(config?: C); + set config(config: C); + get config(): C; + /** + * Maximum index of children + 1, to help estimate total height of the scroll + * space. + */ + get totalItems(): number; + set totalItems(num: number); + /** + * Primary scrolling direction. + */ + get direction(): ScrollDirection; + set direction(dir: ScrollDirection); + /** + * Estimate of the dimensions of a single child. + */ + get itemSize(): Size; + set itemSize(dims: Size); + /** + * Amount of space in between items. + */ + get spacing(): number; + set spacing(px: number); + /** + * Height and width of the viewport. + */ + get viewportSize(): Size; + set viewportSize(dims: Size); + /** + * Scroll offset of the viewport. + */ + get viewportScroll(): Positions; + set viewportScroll(coords: Positions); + /** + * Perform a reflow if one has been scheduled. + */ + reflowIfNeeded(force: boolean): void; + /** + * Scroll to the child at the given index, and the given position within that + * child. + */ + scrollToIndex(index: number, position?: string): void; + dispatchEvent(evt: Event): Promise; + addEventListener( + type: string, + listener: EventListener | EventListenerObject | null, + options?: boolean | AddEventListenerOptions | undefined + ): Promise; + removeEventListener( + type: string, + callback: EventListener | EventListenerObject | null, + options?: boolean | EventListenerOptions | undefined + ): Promise; + /** + * Get the top and left positioning of the item at idx. + */ + abstract _getItemPosition(idx: number): Positions; + /** + * Update _first and _last based on items that should be in the current + * range. + */ + abstract _getActiveItems(): void; + protected _itemDim2Changed(): void; + protected _viewDim2Changed(): void; + protected _updateLayout(): void; + protected _getItemSize(_idx: number): Size; + /** + * The size of an item in the scrolling direction + space between items. + */ + protected get _delta(): number; + /** + * The height or width of an item, whichever corresponds to the scrolling direction. + */ + protected get _itemDim1(): number; + /** + * The height or width of an item, whichever does NOT correspond to the scrolling direction. + */ + protected get _itemDim2(): number; + /** + * The height or width of the viewport, whichever corresponds to the scrolling direction. + */ + protected get _viewDim1(): number; + /** + * The height or width of the viewport, whichever does NOT correspond to the scrolling direction. + */ + protected get _viewDim2(): number; + protected _scheduleReflow(): void; + protected _scheduleLayoutUpdate(): void; + protected _reflow(): void; + /** + * Estimates the total length of all items in the scrolling direction, including spacing. + */ + protected _updateScrollSize(): void; + protected _scrollIfNeeded(): void; + protected _emitRange(inProps?: unknown): void; + protected _emitScrollSize(): void; + protected _emitScrollError(): void; + /** + * Get or estimate the top and left positions of items in the current range. + * Emit an itempositionchange event with these positions. + */ + protected _emitChildPositions(): void; + /** + * Number of items to display. + */ + private get _num(); + private _checkThresholds; + /** + * Find the indices of the first and last items to intersect the viewport. + * Emit a visibleindiceschange event when either index changes. + */ + protected _updateVisibleIndices(options?: UpdateVisibleIndicesOptions): void; + private _scrollPositionChanged; +} +export {}; +//# sourceMappingURL=Layout1dBase.d.ts.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dBase.d.ts.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dBase.d.ts.map new file mode 100644 index 0000000000..96c99bef00 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dBase.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Layout1dBase.d.ts","sourceRoot":"","sources":["../../../../src/lib/uni-virtualizer/lib/layouts/Layout1dBase.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dBase.js b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dBase.js new file mode 100644 index 0000000000..11349b1018 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dBase.js @@ -0,0 +1,477 @@ +import EventTarget from "../polyfillLoaders/EventTarget.js"; +export class Layout1dBase { + constructor(config) { + /** + * The last set viewport scroll position. + */ + this._latestCoords = { left: 0, top: 0 }; + /** + * Scrolling direction. + */ + this._direction = "vertical"; + /** + * Dimensions of the viewport. + */ + this._viewportSize = { width: 0, height: 0 }; + /** + * Flag for debouncing asynchnronous reflow requests. + */ + this._pendingReflow = false; + this._pendingLayoutUpdate = false; + /** + * Index of the item that has been scrolled to via the public API. When the + * container is otherwise scrolled, this value is set back to -1. + */ + this._scrollToIndex = -1; + /** + * When a child is scrolled to, the offset from the top of the child and the + * top of the viewport. Value is a proportion of the item size. + */ + this._scrollToAnchor = 0; + /** + * The index of the first item intersecting the viewport. + */ + this._firstVisible = 0; + /** + * The index of the last item intersecting the viewport. + */ + this._lastVisible = 0; + this._eventTargetPromise = EventTarget().then((Ctor) => { + this._eventTarget = new Ctor(); + }); + /** + * Pixel offset in the scroll direction of the first child. + */ + this._physicalMin = 0; + /** + * Pixel offset in the scroll direction of the last child. + */ + this._physicalMax = 0; + /** + * Index of the first child. + */ + this._first = -1; + /** + * Index of the last child. + */ + this._last = -1; + /** + * The _estimated_ size of a child. + */ + this._itemSize = { width: 100, height: 100 }; + /** + * Space in pixels between children. + */ + this._spacing = 0; + /** + * Length in the scrolling direction. + */ + this._sizeDim = "height"; + /** + * Length in the non-scrolling direction. + */ + this._secondarySizeDim = "width"; + /** + * Position in the scrolling direction. + */ + this._positionDim = "top"; + /** + * Position in the non-scrolling direction. + */ + this._secondaryPositionDim = "left"; + /** + * Current scroll offset in pixels. + */ + this._scrollPosition = 0; + /** + * Difference between current scroll offset and scroll offset calculated due + * to a reflow. + */ + this._scrollError = 0; + /** + * Total number of items that could possibly be displayed. Used to help + * calculate the scroll size. + */ + this._totalItems = 0; + /** + * The total (estimated) length of all items in the scrolling direction. + */ + this._scrollSize = 1; + /** + * Number of pixels beyond the visible size of the container to still include + * in the active range of items. + */ + // TODO (graynorton): Probably want to make this something we calculate based + // on viewport size, item size, other factors, possibly still with a dial of some kind + this._overhang = 1000; + this._eventTarget = null; + this._spacingChanged = false; + this._defaultConfig = { + direction: "vertical", + }; + this.config = config || this._defaultConfig; + } + set config(config) { + Object.assign(this, Object.assign({}, this._defaultConfig, config)); + } + get config() { + return { + direction: this.direction, + }; + } + /** + * Maximum index of children + 1, to help estimate total height of the scroll + * space. + */ + get totalItems() { + return this._totalItems; + } + set totalItems(num) { + const _num = Number(num); + if (_num !== this._totalItems) { + this._totalItems = _num; + this._scheduleReflow(); + } + } + /** + * Primary scrolling direction. + */ + get direction() { + return this._direction; + } + set direction(dir) { + // Force it to be either horizontal or vertical. + dir = dir === "horizontal" ? dir : "vertical"; + if (dir !== this._direction) { + this._direction = dir; + this._sizeDim = dir === "horizontal" ? "width" : "height"; + this._secondarySizeDim = dir === "horizontal" ? "height" : "width"; + this._positionDim = dir === "horizontal" ? "left" : "top"; + this._secondaryPositionDim = dir === "horizontal" ? "top" : "left"; + this._scheduleLayoutUpdate(); + } + } + /** + * Estimate of the dimensions of a single child. + */ + get itemSize() { + return this._itemSize; + } + set itemSize(dims) { + const { _itemDim1, _itemDim2 } = this; + Object.assign(this._itemSize, dims); + if (_itemDim1 !== this._itemDim1 || _itemDim2 !== this._itemDim2) { + if (_itemDim2 !== this._itemDim2) { + this._itemDim2Changed(); + } else { + this._scheduleLayoutUpdate(); + } + } + } + /** + * Amount of space in between items. + */ + get spacing() { + return this._spacing; + } + set spacing(px) { + const _px = Number(px); + if (_px !== this._spacing) { + this._spacing = _px; + this._scheduleLayoutUpdate(); + } + } + /** + * Height and width of the viewport. + */ + get viewportSize() { + return this._viewportSize; + } + set viewportSize(dims) { + const { _viewDim1, _viewDim2 } = this; + Object.assign(this._viewportSize, dims); + if (_viewDim2 !== this._viewDim2) { + this._viewDim2Changed(); + } else if (_viewDim1 !== this._viewDim1) { + this._checkThresholds(); + } + } + /** + * Scroll offset of the viewport. + */ + get viewportScroll() { + return this._latestCoords; + } + set viewportScroll(coords) { + Object.assign(this._latestCoords, coords); + const oldPos = this._scrollPosition; + this._scrollPosition = this._latestCoords[this._positionDim]; + if (oldPos !== this._scrollPosition) { + this._scrollPositionChanged(oldPos, this._scrollPosition); + this._updateVisibleIndices({ emit: true }); + } + this._checkThresholds(); + } + /** + * Perform a reflow if one has been scheduled. + */ + reflowIfNeeded(force) { + if (force || this._pendingReflow) { + this._pendingReflow = false; + this._reflow(); + } + } + /** + * Scroll to the child at the given index, and the given position within that + * child. + */ + scrollToIndex(index, position = "start") { + if (!Number.isFinite(index)) return; + index = Math.min(this.totalItems, Math.max(0, index)); + this._scrollToIndex = index; + if (position === "nearest") { + position = index > this._first + this._num / 2 ? "end" : "start"; + } + switch (position) { + case "start": + this._scrollToAnchor = 0; + break; + case "center": + this._scrollToAnchor = 0.5; + break; + case "end": + this._scrollToAnchor = 1; + break; + default: + throw new TypeError( + "position must be one of: start, center, end, nearest" + ); + } + this._scheduleReflow(); + } + async dispatchEvent(evt) { + await this._eventTargetPromise; + this._eventTarget.dispatchEvent(evt); + } + async addEventListener(type, listener, options) { + await this._eventTargetPromise; + this._eventTarget.addEventListener(type, listener, options); + } + async removeEventListener(type, callback, options) { + await this._eventTargetPromise; + this._eventTarget.removeEventListener(type, callback, options); + } + _itemDim2Changed() { + // Override + } + _viewDim2Changed() { + // Override + } + _updateLayout() { + // Override + } + _getItemSize(_idx) { + return { + [this._sizeDim]: this._itemDim1, + [this._secondarySizeDim]: this._itemDim2, + }; + } + /** + * The size of an item in the scrolling direction + space between items. + */ + get _delta() { + return this._itemDim1 + this._spacing; + } + /** + * The height or width of an item, whichever corresponds to the scrolling direction. + */ + get _itemDim1() { + return this._itemSize[this._sizeDim]; + } + /** + * The height or width of an item, whichever does NOT correspond to the scrolling direction. + */ + get _itemDim2() { + return this._itemSize[this._secondarySizeDim]; + } + /** + * The height or width of the viewport, whichever corresponds to the scrolling direction. + */ + get _viewDim1() { + return this._viewportSize[this._sizeDim]; + } + /** + * The height or width of the viewport, whichever does NOT correspond to the scrolling direction. + */ + get _viewDim2() { + return this._viewportSize[this._secondarySizeDim]; + } + _scheduleReflow() { + this._pendingReflow = true; + } + _scheduleLayoutUpdate() { + this._pendingLayoutUpdate = true; + this._scheduleReflow(); + } + _reflow() { + const { _first, _last, _scrollSize } = this; + if (this._pendingLayoutUpdate) { + this._updateLayout(); + this._pendingLayoutUpdate = false; + } + this._updateScrollSize(); + this._getActiveItems(); + this._scrollIfNeeded(); + this._updateVisibleIndices(); + if (this._scrollSize !== _scrollSize) { + this._emitScrollSize(); + } + if (this._first === -1 && this._last === -1) { + // TODO: have default empty object for emitRange instead + this._emitRange(); + } else if ( + this._first !== _first || + this._last !== _last || + this._spacingChanged + ) { + // TODO: have default empty object for emitRange instead + this._emitRange(); + this._emitChildPositions(); + } + this._emitScrollError(); + } + /** + * Estimates the total length of all items in the scrolling direction, including spacing. + */ + _updateScrollSize() { + // Ensure we have at least 1px - this allows getting at least 1 item to be + // rendered. + this._scrollSize = Math.max(1, this._totalItems * this._delta); + } + _scrollIfNeeded() { + if (this._scrollToIndex === -1) { + return; + } + const index = this._scrollToIndex; + const anchor = this._scrollToAnchor; + const pos = this._getItemPosition(index)[this._positionDim]; + const size = this._getItemSize(index)[this._sizeDim]; + const curAnchorPos = this._scrollPosition + this._viewDim1 * anchor; + const newAnchorPos = pos + size * anchor; + // Ensure scroll position is an integer within scroll bounds. + const scrollPosition = Math.floor( + Math.min( + this._scrollSize - this._viewDim1, + Math.max(0, this._scrollPosition - curAnchorPos + newAnchorPos) + ) + ); + this._scrollError += this._scrollPosition - scrollPosition; + this._scrollPosition = scrollPosition; + } + _emitRange(inProps = undefined) { + const detail = Object.assign( + { + first: this._first, + last: this._last, + num: this._num, + stable: true, + firstVisible: this._firstVisible, + lastVisible: this._lastVisible, + }, + inProps + ); + this.dispatchEvent(new CustomEvent("rangechange", { detail })); + } + _emitScrollSize() { + const detail = { + [this._sizeDim]: this._scrollSize, + }; + this.dispatchEvent(new CustomEvent("scrollsizechange", { detail })); + } + _emitScrollError() { + if (this._scrollError) { + const detail = { + [this._positionDim]: this._scrollError, + [this._secondaryPositionDim]: 0, + }; + this.dispatchEvent(new CustomEvent("scrollerrorchange", { detail })); + this._scrollError = 0; + } + } + /** + * Get or estimate the top and left positions of items in the current range. + * Emit an itempositionchange event with these positions. + */ + _emitChildPositions() { + const detail = {}; + for (let idx = this._first; idx <= this._last; idx++) { + detail[idx] = this._getItemPosition(idx); + } + this.dispatchEvent(new CustomEvent("itempositionchange", { detail })); + } + /** + * Number of items to display. + */ + get _num() { + if (this._first === -1 || this._last === -1) { + return 0; + } + return this._last - this._first + 1; + } + _checkThresholds() { + if (this._viewDim1 === 0 && this._num > 0) { + this._scheduleReflow(); + } else { + const min = Math.max(0, this._scrollPosition - this._overhang); + const max = Math.min( + this._scrollSize, + this._scrollPosition + this._viewDim1 + this._overhang + ); + if (this._physicalMin > min || this._physicalMax < max) { + this._scheduleReflow(); + } + } + } + /** + * Find the indices of the first and last items to intersect the viewport. + * Emit a visibleindiceschange event when either index changes. + */ + _updateVisibleIndices(options) { + if (this._first === -1 || this._last === -1) return; + let firstVisible = this._first; + while ( + Math.round( + this._getItemPosition(firstVisible)[this._positionDim] + + this._getItemSize(firstVisible)[this._sizeDim] + ) <= Math.round(this._scrollPosition) + ) { + firstVisible++; + } + let lastVisible = this._last; + while ( + Math.round(this._getItemPosition(lastVisible)[this._positionDim]) >= + Math.round(this._scrollPosition + this._viewDim1) + ) { + lastVisible--; + } + if ( + firstVisible !== this._firstVisible || + lastVisible !== this._lastVisible + ) { + this._firstVisible = firstVisible; + this._lastVisible = lastVisible; + if (options && options.emit) { + this._emitRange(); + } + } + } + _scrollPositionChanged(oldPos, newPos) { + // When both values are bigger than the max scroll position, keep the + // current _scrollToIndex, otherwise invalidate it. + const maxPos = this._scrollSize - this._viewDim1; + if (oldPos < maxPos || newPos < maxPos) { + this._scrollToIndex = -1; + } + } +} +//# sourceMappingURL=Layout1dBase.js.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dBase.js.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dBase.js.map new file mode 100644 index 0000000000..be6a74593f --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dBase.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Layout1dBase.js","sourceRoot":"","sources":["../../../../src/lib/uni-virtualizer/lib/layouts/Layout1dBase.ts"],"names":[],"mappings":"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","sourcesContent":["import EventTarget from '../polyfillLoaders/EventTarget.js';\nimport {Layout, Positions, ScrollDirection, Size, dimension, position} from './Layout.js';\n\ntype UpdateVisibleIndicesOptions = {\n emit?: boolean\n}\n\nexport interface Layout1dBaseConfig {\n direction?: ScrollDirection,\n totalItems?: number\n}\n\nexport abstract class Layout1dBase implements Layout {\n /**\n * The last set viewport scroll position.\n */\n private _latestCoords: Positions = {left: 0, top: 0};\n\n /**\n * Scrolling direction.\n */\n private _direction: ScrollDirection = 'vertical';\n\n /**\n * Dimensions of the viewport.\n */\n private _viewportSize: Size = {width: 0, height: 0};\n\n /**\n * Flag for debouncing asynchnronous reflow requests.\n */\n private _pendingReflow = false;\n\n private _pendingLayoutUpdate = false;\n\n /**\n * Index of the item that has been scrolled to via the public API. When the\n * container is otherwise scrolled, this value is set back to -1.\n */\n protected _scrollToIndex = -1;\n\n /**\n * When a child is scrolled to, the offset from the top of the child and the\n * top of the viewport. Value is a proportion of the item size.\n */\n private _scrollToAnchor = 0;\n\n /**\n * The index of the first item intersecting the viewport.\n */\n private _firstVisible = 0;\n\n /**\n * The index of the last item intersecting the viewport.\n */\n private _lastVisible = 0;\n\n private _eventTargetPromise: Promise = (EventTarget().then((Ctor) => {\n this._eventTarget = new Ctor();\n }));\n\n /**\n * Pixel offset in the scroll direction of the first child.\n */\n protected _physicalMin = 0;\n\n /**\n * Pixel offset in the scroll direction of the last child.\n */\n protected _physicalMax = 0;\n\n /**\n * Index of the first child.\n */\n protected _first = -1;\n\n /**\n * Index of the last child.\n */\n protected _last = -1;\n\n /**\n * The _estimated_ size of a child.\n */\n protected _itemSize: Size = {width: 100, height: 100};\n\n /**\n * Space in pixels between children.\n */\n protected _spacing = 0;\n\n /**\n * Length in the scrolling direction.\n */\n protected _sizeDim: dimension = 'height';\n\n /**\n * Length in the non-scrolling direction.\n */\n protected _secondarySizeDim: dimension = 'width';\n\n /**\n * Position in the scrolling direction.\n */\n protected _positionDim: position = 'top';\n\n /**\n * Position in the non-scrolling direction.\n */\n protected _secondaryPositionDim: position = 'left';\n\n /**\n * Current scroll offset in pixels.\n */\n protected _scrollPosition = 0;\n\n /**\n * Difference between current scroll offset and scroll offset calculated due\n * to a reflow.\n */\n protected _scrollError = 0;\n\n /**\n * Total number of items that could possibly be displayed. Used to help\n * calculate the scroll size.\n */\n protected _totalItems = 0;\n\n /**\n * The total (estimated) length of all items in the scrolling direction.\n */\n protected _scrollSize = 1;\n\n /**\n * Number of pixels beyond the visible size of the container to still include\n * in the active range of items.\n */\n // TODO (graynorton): Probably want to make this something we calculate based\n // on viewport size, item size, other factors, possibly still with a dial of some kind\n protected _overhang = 1000;\n\n private _eventTarget: EventTarget | null = null;\n protected _spacingChanged = false;\n\n protected _defaultConfig: C = {\n direction: 'vertical'\n } as C\n\n constructor(config?: C) {\n this.config = config || this._defaultConfig;\n }\n\n set config(config: C) {\n Object.assign(this, Object.assign({}, this._defaultConfig, config));\n }\n\n get config(): C {\n return {\n direction: this.direction\n } as C;\n }\n\n /**\n * Maximum index of children + 1, to help estimate total height of the scroll\n * space.\n */\n get totalItems(): number {\n return this._totalItems;\n }\n set totalItems(num) {\n const _num = Number(num);\n if (_num !== this._totalItems) {\n this._totalItems = _num;\n this._scheduleReflow();\n }\n }\n\n /**\n * Primary scrolling direction.\n */\n get direction(): ScrollDirection {\n return this._direction;\n }\n set direction(dir) {\n // Force it to be either horizontal or vertical.\n dir = (dir === 'horizontal') ? dir : 'vertical';\n if (dir !== this._direction) {\n this._direction = dir;\n this._sizeDim = (dir === 'horizontal') ? 'width' : 'height';\n this._secondarySizeDim = (dir === 'horizontal') ? 'height' : 'width';\n this._positionDim = (dir === 'horizontal') ? 'left' : 'top';\n this._secondaryPositionDim = (dir === 'horizontal') ? 'top' : 'left';\n this._scheduleLayoutUpdate();\n }\n }\n\n /**\n * Estimate of the dimensions of a single child.\n */\n get itemSize(): Size {\n return this._itemSize;\n }\n set itemSize(dims) {\n const {_itemDim1, _itemDim2} = this;\n Object.assign(this._itemSize, dims);\n if (_itemDim1 !== this._itemDim1 || _itemDim2 !== this._itemDim2) {\n if (_itemDim2 !== this._itemDim2) {\n this._itemDim2Changed();\n } else {\n this._scheduleLayoutUpdate();\n }\n }\n }\n\n /**\n * Amount of space in between items.\n */\n get spacing(): number {\n return this._spacing;\n }\n set spacing(px) {\n const _px = Number(px);\n if (_px !== this._spacing) {\n this._spacing = _px;\n this._scheduleLayoutUpdate();\n }\n }\n\n /**\n * Height and width of the viewport.\n */\n get viewportSize(): Size {\n return this._viewportSize;\n }\n set viewportSize(dims) {\n const {_viewDim1, _viewDim2} = this;\n Object.assign(this._viewportSize, dims);\n if (_viewDim2 !== this._viewDim2) {\n this._viewDim2Changed();\n } else if (_viewDim1 !== this._viewDim1) {\n this._checkThresholds();\n }\n }\n\n /**\n * Scroll offset of the viewport.\n */\n get viewportScroll(): Positions {\n return this._latestCoords;\n }\n set viewportScroll(coords) {\n Object.assign(this._latestCoords, coords);\n const oldPos = this._scrollPosition;\n this._scrollPosition = this._latestCoords[this._positionDim];\n if (oldPos !== this._scrollPosition) {\n this._scrollPositionChanged(oldPos, this._scrollPosition);\n this._updateVisibleIndices({emit: true});\n }\n this._checkThresholds();\n }\n\n /**\n * Perform a reflow if one has been scheduled.\n */\n reflowIfNeeded(force: boolean) {\n if (force || this._pendingReflow) {\n this._pendingReflow = false;\n this._reflow();\n }\n }\n\n /**\n * Scroll to the child at the given index, and the given position within that\n * child.\n */\n scrollToIndex(index: number, position = 'start') {\n if (!Number.isFinite(index))\n return;\n index = Math.min(this.totalItems, Math.max(0, index));\n this._scrollToIndex = index;\n if (position === 'nearest') {\n position = index > this._first + this._num / 2 ? 'end' : 'start';\n }\n switch (position) {\n case 'start':\n this._scrollToAnchor = 0;\n break;\n case 'center':\n this._scrollToAnchor = 0.5;\n break;\n case 'end':\n this._scrollToAnchor = 1;\n break;\n default:\n throw new TypeError(\n 'position must be one of: start, center, end, nearest');\n }\n this._scheduleReflow();\n }\n\n async dispatchEvent(evt: Event) {\n await this._eventTargetPromise;\n this._eventTarget!.dispatchEvent(evt);\n }\n\n async addEventListener(type: string, listener: EventListener | EventListenerObject | null, options?: boolean | AddEventListenerOptions | undefined) {\n await this._eventTargetPromise;\n this._eventTarget!.addEventListener(type, listener, options);\n }\n\n async removeEventListener(type: string, callback: EventListener | EventListenerObject | null, options?: boolean | EventListenerOptions | undefined) {\n await this._eventTargetPromise;\n this._eventTarget!.removeEventListener(type, callback, options);\n }\n\n /**\n * Get the top and left positioning of the item at idx.\n */\n abstract _getItemPosition(idx: number): Positions;\n\n /**\n * Update _first and _last based on items that should be in the current\n * range.\n */\n abstract _getActiveItems(): void;\n\n protected _itemDim2Changed() {\n // Override\n }\n\n protected _viewDim2Changed() {\n // Override\n }\n\n protected _updateLayout() {\n // Override\n }\n\n protected _getItemSize(_idx: number): Size {\n return {\n [this._sizeDim]: this._itemDim1,\n [this._secondarySizeDim]: this._itemDim2,\n } as unknown as Size;\n }\n\n /**\n * The size of an item in the scrolling direction + space between items.\n */\n protected get _delta(): number {\n return this._itemDim1 + this._spacing;\n }\n\n /**\n * The height or width of an item, whichever corresponds to the scrolling direction.\n */\n protected get _itemDim1(): number {\n return this._itemSize[this._sizeDim];\n }\n\n /**\n * The height or width of an item, whichever does NOT correspond to the scrolling direction.\n */\n protected get _itemDim2(): number {\n return this._itemSize[this._secondarySizeDim];\n }\n\n /**\n * The height or width of the viewport, whichever corresponds to the scrolling direction.\n */\n protected get _viewDim1(): number {\n return this._viewportSize[this._sizeDim];\n }\n\n /**\n * The height or width of the viewport, whichever does NOT correspond to the scrolling direction.\n */\n protected get _viewDim2(): number {\n return this._viewportSize[this._secondarySizeDim];\n }\n\n protected _scheduleReflow() {\n this._pendingReflow = true;\n }\n\n protected _scheduleLayoutUpdate() {\n this._pendingLayoutUpdate = true;\n this._scheduleReflow();\n }\n\n protected _reflow() {\n const {_first, _last, _scrollSize} = this;\n\n if (this._pendingLayoutUpdate) {\n this._updateLayout();\n this._pendingLayoutUpdate = false;\n }\n this._updateScrollSize();\n this._getActiveItems();\n this._scrollIfNeeded();\n this._updateVisibleIndices();\n\n if (this._scrollSize !== _scrollSize) {\n this._emitScrollSize();\n }\n\n if (this._first === -1 && this._last === -1) {\n // TODO: have default empty object for emitRange instead\n this._emitRange();\n } else if (\n this._first !== _first || this._last !== _last ||\n this._spacingChanged) {\n // TODO: have default empty object for emitRange instead\n this._emitRange();\n this._emitChildPositions();\n }\n this._emitScrollError();\n }\n\n /**\n * Estimates the total length of all items in the scrolling direction, including spacing.\n */\n protected _updateScrollSize() {\n // Ensure we have at least 1px - this allows getting at least 1 item to be\n // rendered.\n this._scrollSize = Math.max(1, this._totalItems * this._delta);\n }\n\n protected _scrollIfNeeded() {\n if (this._scrollToIndex === -1) {\n return;\n }\n const index = this._scrollToIndex;\n const anchor = this._scrollToAnchor;\n const pos = this._getItemPosition(index)[this._positionDim];\n const size = this._getItemSize(index)[this._sizeDim];\n\n const curAnchorPos = this._scrollPosition + this._viewDim1 * anchor;\n const newAnchorPos = pos + size * anchor;\n // Ensure scroll position is an integer within scroll bounds.\n const scrollPosition = Math.floor(Math.min(\n this._scrollSize - this._viewDim1,\n Math.max(0, this._scrollPosition - curAnchorPos + newAnchorPos)));\n this._scrollError += this._scrollPosition - scrollPosition;\n this._scrollPosition = scrollPosition;\n }\n\n protected _emitRange(inProps: unknown = undefined) {\n const detail = Object.assign(\n {\n first: this._first,\n last: this._last,\n num: this._num,\n stable: true,\n firstVisible: this._firstVisible,\n lastVisible: this._lastVisible,\n },\n inProps);\n this.dispatchEvent(new CustomEvent('rangechange', {detail}));\n }\n\n protected _emitScrollSize() {\n const detail = {\n [this._sizeDim]: this._scrollSize,\n };\n this.dispatchEvent(new CustomEvent('scrollsizechange', {detail}));\n }\n\n protected _emitScrollError() {\n if (this._scrollError) {\n const detail = {\n [this._positionDim]: this._scrollError,\n [this._secondaryPositionDim]: 0,\n };\n this.dispatchEvent(new CustomEvent('scrollerrorchange', {detail}));\n this._scrollError = 0;\n }\n }\n\n /**\n * Get or estimate the top and left positions of items in the current range.\n * Emit an itempositionchange event with these positions.\n */\n protected _emitChildPositions() {\n const detail: {[key: number]: Positions} = {};\n for (let idx = this._first; idx <= this._last; idx++) {\n detail[idx] = this._getItemPosition(idx);\n }\n this.dispatchEvent(new CustomEvent('itempositionchange', {detail}));\n }\n\n /**\n * Number of items to display.\n */\n private get _num(): number {\n if (this._first === -1 || this._last === -1) {\n return 0;\n }\n return this._last - this._first + 1;\n }\n\n private _checkThresholds() {\n if (this._viewDim1 === 0 && this._num > 0) {\n this._scheduleReflow();\n } else {\n const min = Math.max(0, this._scrollPosition - this._overhang);\n const max = Math.min(\n this._scrollSize,\n this._scrollPosition + this._viewDim1 + this._overhang);\n if (this._physicalMin > min || this._physicalMax < max) {\n this._scheduleReflow();\n }\n }\n }\n\n /**\n * Find the indices of the first and last items to intersect the viewport.\n * Emit a visibleindiceschange event when either index changes.\n */\n protected _updateVisibleIndices(options?: UpdateVisibleIndicesOptions) {\n if (this._first === -1 || this._last === -1) return;\n\n let firstVisible = this._first;\n while (\n Math.round(\n this._getItemPosition(firstVisible)[this._positionDim] +\n this._getItemSize(firstVisible)[this._sizeDim]\n )\n <=\n Math.round (this._scrollPosition)\n ) {\n firstVisible++;\n }\n\n let lastVisible = this._last;\n while (\n Math.round(this._getItemPosition(lastVisible)[this._positionDim])\n >=\n Math.round(this._scrollPosition + this._viewDim1)\n ) {\n lastVisible--;\n }\n\n if (firstVisible !== this._firstVisible || lastVisible !== this._lastVisible) {\n this._firstVisible = firstVisible;\n this._lastVisible = lastVisible;\n if (options && options.emit) {\n this._emitRange();\n }\n }\n }\n\n private _scrollPositionChanged(oldPos: number, newPos: number) {\n // When both values are bigger than the max scroll position, keep the\n // current _scrollToIndex, otherwise invalidate it.\n const maxPos = this._scrollSize - this._viewDim1;\n if (oldPos < maxPos || newPos < maxPos) {\n this._scrollToIndex = -1;\n }\n }\n}\n"]} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dFlex.d.ts b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dFlex.d.ts new file mode 100644 index 0000000000..809557d00f --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dFlex.d.ts @@ -0,0 +1,65 @@ +import { Layout1dBase, Layout1dBaseConfig } from "./Layout1dBase"; +import { ItemBox, Positions, Size } from "./Layout"; +interface Layout1dFlexConfig extends Layout1dBaseConfig { + spacing?: number; + idealSize?: number; +} +declare type Layout1dFlexSpecifier = Layout1dFlexConfig & { + type: new (config?: Layout1dFlexConfig) => Layout1dFlex; +}; +declare type Layout1dFlexSpecifierFactory = ( + config?: Layout1dFlexConfig +) => Layout1dFlexSpecifier; +export declare const layout1dFlex: Layout1dFlexSpecifierFactory; +interface Rolumn { + _startIdx: number; + _endIdx: number; + _startPos: number; + _size: number; +} +interface Chunk { + _itemPositions: Array; + _rolumns: Array; + _size: number; + _dirty: boolean; +} +/** + * TODO @straversi: document and test this Layout. + */ +export declare class Layout1dFlex extends Layout1dBase { + private _itemSizes; + private _chunkSize; + private _chunks; + private _aspectRatios; + private _numberOfAspectRatiosMeasured; + protected _idealSize: number | null; + protected _config: Layout1dFlexConfig; + protected _defaultConfig: Layout1dFlexConfig; + listenForChildLoadEvents: boolean; + /** + * TODO graynorton@ Don't hard-code Flickr - probably need a config option + */ + measureChildren: (e: Element, i: unknown) => ItemBox; + set idealSize(px: number | null); + get idealSize(): number | null; + updateItemSizes(sizes: { [key: number]: ItemBox }): void; + _newChunk(): { + _rolumns: never[]; + _itemPositions: never[]; + _size: number; + _dirty: boolean; + }; + _getChunk(idx: number | string): Chunk; + _recordAspectRatio(dims: ItemBox): void; + _getRandomAspectRatio(): Size; + _viewDim2Changed(): void; + _getActiveItems(): void; + _getItemPosition(idx: number): Positions; + _getItemSize(idx: number): Size; + _getNaturalItemDims(idx: number): Size; + _layOutChunk(startIdx: number): Chunk; + _updateLayout(): void; + _updateScrollSize(): void; +} +export {}; +//# sourceMappingURL=Layout1dFlex.d.ts.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dFlex.d.ts.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dFlex.d.ts.map new file mode 100644 index 0000000000..de4bacef32 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dFlex.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Layout1dFlex.d.ts","sourceRoot":"","sources":["../../../../src/lib/uni-virtualizer/lib/layouts/Layout1dFlex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,kBAAkB,EAAC,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAC,MAAM,UAAU,CAAC;AAElD,UAAU,kBAAmB,SAAQ,kBAAkB;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,aAAK,qBAAqB,GAAG,kBAAkB,GAAG;IAChD,IAAI,EAAE,KAAI,MAAM,CAAC,EAAE,kBAAkB,KAAK,YAAY,CAAA;CACvD,CAAA;AAED,aAAK,4BAA4B,GAAG,CAAC,MAAM,CAAC,EAAE,kBAAkB,KAAK,qBAAqB,CAAC;AAE3F,eAAO,MAAM,YAAY,EAAE,4BAEjB,CAAC;AAEX,UAAU,MAAM;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAA;CACd;AAED,UAAU,KAAK;IACb,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IACjC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAA;CAChB;AAeD;;GAEG;AACH,qBAAa,YAAa,SAAQ,YAAY,CAAC,kBAAkB,CAAC;IAChE,OAAO,CAAC,UAAU,CAAmB;IAIrC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,6BAA6B,CAAa;IAClD,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC3C,SAAS,CAAC,OAAO,EAAE,kBAAkB,CAAM;IAC3C,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAGzC;IAEH,wBAAwB,UAAQ;IAElC;;OAEG;IACD,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAUvD;IAED,IAAI,SAAS,CAAC,EAAE,eAAA,EAMf;IAED,IAAI,SAAS,kBAEZ;IAED,eAAe,CAAC,KAAK,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAC;IAqB/C,SAAS;;;;;;IAST,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAI9B,kBAAkB,CAAC,IAAI,EAAE,OAAO;IAahC,qBAAqB,IAAI,IAAI;IAa7B,gBAAgB;IAIhB,eAAe;IA2Bf,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS;IAKxC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAM/B,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAStC,YAAY,CAAC,QAAQ,EAAE,MAAM;IA+D7B,aAAa,IAAI,IAAI;IAYrB,iBAAiB;CAOlB"} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dFlex.js b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dFlex.js new file mode 100644 index 0000000000..fe0f5c5fc9 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dFlex.js @@ -0,0 +1,264 @@ +import { Layout1dBase } from "./Layout1dBase"; +export const layout1dFlex = (config) => + Object.assign( + { + type: Layout1dFlex, + }, + config + ); +/** + * TODO @straversi: document and test this Layout. + */ +export class Layout1dFlex extends Layout1dBase { + constructor() { + super(...arguments); + this._itemSizes = []; + // private _itemPositions: Array = []; + // private _rolumnStartIdx: Array = []; + // private _rolumnStartPos: Array = []; + this._chunkSize = null; + this._chunks = []; + this._aspectRatios = {}; + this._numberOfAspectRatiosMeasured = 0; + this._idealSize = null; + this._config = {}; + this._defaultConfig = Object.assign({}, super._defaultConfig, { + spacing: 0, + idealSize: 200, + }); + this.listenForChildLoadEvents = true; + /** + * TODO graynorton@ Don't hard-code Flickr - probably need a config option + */ + this.measureChildren = function (e, i) { + const { naturalWidth, naturalHeight } = e; + if (naturalWidth !== undefined && naturalHeight != undefined) { + return { width: naturalWidth, height: naturalHeight }; + } + const { o_width, o_height } = i; + if (o_width !== undefined && o_height !== undefined) { + return { width: o_width, height: o_height }; + } + return { width: -1, height: -1 }; + }; + } + set idealSize(px) { + const _px = Number(px); + if (_px !== this._idealSize) { + this._idealSize = _px; + this._scheduleLayoutUpdate(); + } + } + get idealSize() { + return this._idealSize; + } + updateItemSizes(sizes) { + let dirty; + Object.keys(sizes).forEach((key) => { + const n = Number(key); + const chunk = this._getChunk(n); + const dims = sizes[n]; + const prevDims = this._itemSizes[n]; + if (dims.width && dims.height) { + if ( + !prevDims || + prevDims.width !== dims.width || + prevDims.height !== dims.height + ) { + chunk._dirty = true; + dirty = true; + this._itemSizes[n] = sizes[n]; + this._recordAspectRatio(sizes[n]); + } + } + }); + if (dirty) { + this._scheduleLayoutUpdate(); + } + } + _newChunk() { + return { + ["_rolumns"]: [], + _itemPositions: [], + _size: 0, + _dirty: false, + }; + } + _getChunk(idx) { + return ( + this._chunks[Math.floor(Number(idx) / this._chunkSize)] || + this._newChunk() + ); + } + _recordAspectRatio(dims) { + if (dims.width && dims.height) { + const bucket = Math.round((dims.width / dims.height) * 10) / 10; + if (this._aspectRatios[bucket]) { + this._aspectRatios[bucket]++; + } else { + this._aspectRatios[bucket] = 1; + } + this._numberOfAspectRatiosMeasured++; + } + } + _getRandomAspectRatio() { + if (this._numberOfAspectRatiosMeasured === 0) { + return { width: 1, height: 1 }; + } + const n = Math.random() * this._numberOfAspectRatiosMeasured; + const buckets = Object.keys(this._aspectRatios); + let i = -1, + m = 0; + while (m < n && i < buckets.length) { + m += this._aspectRatios[buckets[++i]]; + } + return { width: Number(buckets[i]), height: 1 }; + } + _viewDim2Changed() { + this._scheduleLayoutUpdate(); + } + _getActiveItems() { + const chunk = this._getChunk(0); + if (chunk._rolumns.length === 0) return; + const scrollPos = Math.max( + 0, + Math.min(this._scrollPosition, this._scrollSize - this._viewDim1) + ); + const min = Math.max(0, scrollPos - this._overhang); + const max = Math.min( + this._scrollSize, + scrollPos + this._viewDim1 + this._overhang + ); + const mid = (min + max) / 2; + const estMidRolumn = Math.round( + (mid / this._scrollSize) * chunk._rolumns.length + ); + let idx = estMidRolumn; + while (chunk._rolumns[idx]._startPos < min) { + idx++; + } + while (chunk._rolumns[idx]._startPos > min) { + idx--; + } + this._first = chunk._rolumns[idx]._startIdx; + this._physicalMin = chunk._rolumns[idx]._startPos; + let rolumnMax; + while ( + (rolumnMax = + chunk._rolumns[idx]._startPos + + chunk._rolumns[idx]._size + + this._spacing * 2) < max + ) { + idx++; + } + this._last = chunk._rolumns[idx]._endIdx; + this._physicalMax = rolumnMax; + } + _getItemPosition(idx) { + const chunk = this._getChunk(0); + return chunk._itemPositions[idx]; + } + _getItemSize(idx) { + const chunk = this._getChunk(0); + const { width, height } = chunk._itemPositions[idx]; + return { width, height }; + } + _getNaturalItemDims(idx) { + let itemDims = this._itemSizes[idx]; + if ( + itemDims === undefined || + itemDims.width === -1 || + itemDims.height === -1 + ) { + itemDims = this._getRandomAspectRatio(); + } + return itemDims; + } + _layOutChunk(startIdx) { + const chunk = this._newChunk(); + let startPos = this._spacing; + let idx = 0; + let rolumnSize2 = 0; + let lastRatio = Infinity; + const finishRolumn = (lastIdx) => { + const rolumn = { + _startIdx: startIdx, + _endIdx: lastIdx, + _startPos: startPos - this._spacing, + _size: 0, + }; + chunk._rolumns.push(rolumn); + let itemStartPos = this._spacing; + for (let i = startIdx; i <= lastIdx; i++) { + const pos = chunk._itemPositions[i]; + pos.width = pos.width * lastRatio; + pos.height = pos.height * lastRatio; + pos.left = this._positionDim === "left" ? startPos : itemStartPos; + pos.top = this._positionDim === "top" ? startPos : itemStartPos; + itemStartPos += pos[this._secondarySizeDim] + this._spacing; + } + rolumn._size = chunk._itemPositions[lastIdx][this._sizeDim]; + }; + while (idx < this._chunkSize) { + const itemDims = this._getNaturalItemDims(idx); + const availableSpace = + this._viewDim2 - this._spacing * (idx - startIdx + 2); + const itemSize = itemDims[this._sizeDim]; + const itemSize2 = itemDims[this._secondarySizeDim]; + const idealScaleFactor = this._idealSize / itemSize; + const adjItemSize = idealScaleFactor * itemSize; + const adjItemSize2 = idealScaleFactor * itemSize2; + chunk._itemPositions[idx] = { + left: 0, + top: 0, + width: this._sizeDim === "width" ? adjItemSize : adjItemSize2, + height: this._sizeDim === "height" ? adjItemSize : adjItemSize2, + }; + const ratio = availableSpace / (rolumnSize2 + adjItemSize2); + if (Math.abs(1 - ratio) > Math.abs(1 - lastRatio)) { + // rolumn is better without adding this item + finishRolumn(idx - 1); + startIdx = idx; + startPos += this._idealSize * lastRatio + this._spacing; + lastRatio = (this._viewDim2 - 2 * this._spacing) / adjItemSize2; + rolumnSize2 = adjItemSize2; + } else { + // add this item and continue + rolumnSize2 += adjItemSize2; + lastRatio = ratio; + } + if (idx === this._chunkSize - 1) { + finishRolumn(idx); + } + idx++; + } + const lastRolumn = chunk._rolumns[chunk._rolumns.length - 1]; + chunk._size = lastRolumn._startPos + lastRolumn._size; + return chunk; + } + _updateLayout() { + if (/*this._rolumnStartIdx === undefined ||*/ this._viewDim2 === 0) return; + this._chunkSize = Math.ceil( + (2 * (this._viewDim1 * this._viewDim2)) / + (this._idealSize * this._idealSize) + ); + console.log("chunkSize", this._chunkSize); + // TODO: An odd place to do this, need to think through the logistics of getting size info to the layout + // in all cases + // this._itemSizes.length = 100;//this._totalItems; + this._chunks[0] = this._layOutChunk(0); + // TODO (graynorton): This is a hack to force reflow + this._spacingChanged = true; + } + _updateScrollSize() { + const chunk = this._chunks[0]; + this._scrollSize = + !chunk || chunk._rolumns.length === 0 + ? 1 + : chunk._size + 2 * this._spacing; + // chunk._rolumns[chunk._rolumns.length - 1]._startPos + + // chunk._itemPositions[chunk._rolumns.length - 1][this._sizeDim] + + // (this._spacing * 2); + } +} +//# sourceMappingURL=Layout1dFlex.js.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dFlex.js.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dFlex.js.map new file mode 100644 index 0000000000..1d93aa6da4 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dFlex.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Layout1dFlex.js","sourceRoot":"","sources":["../../../../src/lib/uni-virtualizer/lib/layouts/Layout1dFlex.ts"],"names":[],"mappings":"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","sourcesContent":["import {Layout1dBase, Layout1dBaseConfig} from './Layout1dBase';\nimport {ItemBox, Positions, Size} from './Layout';\n\ninterface Layout1dFlexConfig extends Layout1dBaseConfig {\n spacing?: number,\n idealSize?: number\n}\n\ntype Layout1dFlexSpecifier = Layout1dFlexConfig & {\n type: new(config?: Layout1dFlexConfig) => Layout1dFlex\n}\n\ntype Layout1dFlexSpecifierFactory = (config?: Layout1dFlexConfig) => Layout1dFlexSpecifier;\n\nexport const layout1dFlex: Layout1dFlexSpecifierFactory = (config?: Layout1dFlexConfig) => Object.assign({\n type: Layout1dFlex\n}, config);\n\ninterface Rolumn {\n _startIdx: number,\n _endIdx: number,\n _startPos: number,\n _size: number\n}\n\ninterface Chunk {\n _itemPositions: Array,\n _rolumns: Array,\n _size: number,\n _dirty: boolean\n}\n\ninterface AspectRatios {\n // conceptually, key is a number, but strictly speaking it's a string\n [key: string]: number\n}\n\n/**\n * TODO graynorton@ Don't hard-code Flickr - probably need a config option\n */\n interface FlickrImageData {\n o_width: number,\n o_height: number\n}\n\n/**\n * TODO @straversi: document and test this Layout.\n */\nexport class Layout1dFlex extends Layout1dBase {\n private _itemSizes: Array = [];\n // private _itemPositions: Array = [];\n // private _rolumnStartIdx: Array = [];\n // private _rolumnStartPos: Array = [];\n private _chunkSize: number | null = null;\n private _chunks: Array = [];\n private _aspectRatios: AspectRatios = {};\n private _numberOfAspectRatiosMeasured: number = 0;\n protected _idealSize: number | null = null;\n protected _config: Layout1dFlexConfig = {};\n protected _defaultConfig: Layout1dFlexConfig = Object.assign({}, super._defaultConfig, {\n spacing: 0,\n idealSize: 200\n });\n\n listenForChildLoadEvents = true;\n\n/**\n * TODO graynorton@ Don't hard-code Flickr - probably need a config option\n */\n measureChildren: ((e: Element, i: unknown) => (ItemBox)) = function (e, i) {\n const { naturalWidth, naturalHeight } = e as HTMLImageElement;\n if (naturalWidth !== undefined && naturalHeight != undefined) {\n return { width: naturalWidth, height: naturalHeight };\n }\n const { o_width, o_height } = i as FlickrImageData;\n if (o_width !== undefined && o_height !== undefined) {\n return { width: o_width, height: o_height };\n }\n return { width: -1, height: -1 };\n }\n\n set idealSize(px) {\n const _px = Number(px);\n if (_px !== this._idealSize) {\n this._idealSize = _px;\n this._scheduleLayoutUpdate();\n }\n }\n\n get idealSize() {\n return this._idealSize;\n }\n\n updateItemSizes(sizes: {[key: number]: ItemBox}) {\n let dirty;\n Object.keys(sizes).forEach((key) => {\n const n = Number(key);\n const chunk = this._getChunk(n);\n const dims = sizes[n];\n const prevDims = this._itemSizes[n];\n if (dims.width && dims.height) {\n if (!prevDims || prevDims.width !== dims.width || prevDims.height !== dims.height) {\n chunk._dirty = true;\n dirty = true;\n this._itemSizes[n] = sizes[n];\n this._recordAspectRatio(sizes[n]);\n }\n }\n });\n if (dirty) {\n this._scheduleLayoutUpdate();\n }\n }\n\n _newChunk() {\n return {\n ['_rolumns']: [],\n _itemPositions: [],\n _size: 0,\n _dirty: false \n }\n }\n\n _getChunk(idx: number | string) {\n return this._chunks[Math.floor(Number(idx) / this._chunkSize!)] || this._newChunk();\n }\n\n _recordAspectRatio(dims: ItemBox) {\n if (dims.width && dims.height) {\n const bucket = Math.round(dims.width / dims.height * 10) / 10;\n if (this._aspectRatios[bucket]) {\n this._aspectRatios[bucket]++;\n }\n else {\n this._aspectRatios[bucket] = 1;\n }\n this._numberOfAspectRatiosMeasured++; \n }\n }\n\n _getRandomAspectRatio(): Size {\n if (this._numberOfAspectRatiosMeasured === 0) {\n return {width: 1, height: 1};\n }\n const n = Math.random() * this._numberOfAspectRatiosMeasured;\n const buckets = Object.keys(this._aspectRatios);\n let i = -1, m = 0;\n while (m < n && i < buckets.length) {\n m += this._aspectRatios[buckets[++i]];\n }\n return {width: Number(buckets[i]), height: 1};\n}\n\n _viewDim2Changed() {\n this._scheduleLayoutUpdate();\n }\n\n _getActiveItems() {\n const chunk = this._getChunk(0);\n if (chunk._rolumns.length === 0) return;\n const scrollPos = Math.max(0, Math.min(this._scrollPosition, this._scrollSize - this._viewDim1));\n const min = Math.max(0, scrollPos - this._overhang);\n const max = Math.min(\n this._scrollSize,\n scrollPos + this._viewDim1 + this._overhang);\n const mid = (min + max) / 2;\n const estMidRolumn = Math.round((mid / this._scrollSize) * chunk._rolumns.length);\n let idx = estMidRolumn;\n while (chunk._rolumns[idx]._startPos < min) {\n idx++;\n }\n while (chunk._rolumns[idx]._startPos > min) {\n idx--;\n }\n this._first = chunk._rolumns[idx]._startIdx;\n this._physicalMin = chunk._rolumns[idx]._startPos;\n let rolumnMax;\n while ((rolumnMax = chunk._rolumns[idx]._startPos + chunk._rolumns[idx]._size + (this._spacing * 2)) < max) {\n idx++;\n }\n this._last = chunk._rolumns[idx]._endIdx;\n this._physicalMax = rolumnMax;\n }\n\n _getItemPosition(idx: number): Positions {\n const chunk = this._getChunk(0);\n return chunk._itemPositions[idx];\n }\n\n _getItemSize(idx: number): Size {\n const chunk = this._getChunk(0);\n const {width, height} = chunk._itemPositions[idx];\n return {width, height} as Size;\n }\n\n _getNaturalItemDims(idx: number): Size {\n let itemDims = this._itemSizes[idx];\n if (itemDims === undefined || itemDims.width === -1 || itemDims.height === -1) {\n itemDims = this._getRandomAspectRatio();\n }\n return itemDims;\n }\n\n\n _layOutChunk(startIdx: number) {\n const chunk: Chunk = this._newChunk();\n let startPos = this._spacing;\n let idx = 0;\n let rolumnSize2 = 0;\n let lastRatio = Infinity;\n const finishRolumn = (lastIdx: number) => {\n const rolumn = {\n _startIdx: startIdx,\n _endIdx: lastIdx,\n _startPos: startPos - this._spacing,\n _size: 0\n }\n chunk._rolumns.push(rolumn);\n let itemStartPos = this._spacing;\n for (let i = startIdx; i <= lastIdx; i++) {\n const pos = chunk._itemPositions[i];\n pos.width = pos.width! * lastRatio;\n pos.height = pos.height! * lastRatio;\n pos.left = this._positionDim === 'left' ? startPos : itemStartPos;\n pos.top = this._positionDim === 'top' ? startPos : itemStartPos;\n itemStartPos += pos[this._secondarySizeDim]! + this._spacing;\n }\n rolumn._size = chunk._itemPositions[lastIdx][this._sizeDim]!;\n }\n while (idx < this._chunkSize!) {\n const itemDims = this._getNaturalItemDims(idx);\n const availableSpace = this._viewDim2 - (this._spacing * (idx - startIdx + 2));\n const itemSize = itemDims[this._sizeDim];\n const itemSize2 = itemDims[this._secondarySizeDim];\n const idealScaleFactor = this._idealSize! / itemSize;\n const adjItemSize = idealScaleFactor * itemSize;\n const adjItemSize2 = idealScaleFactor * itemSize2;\n chunk._itemPositions[idx] = {\n left: 0,\n top: 0,\n width: (this._sizeDim === 'width' ? adjItemSize : adjItemSize2),\n height: (this._sizeDim === 'height' ? adjItemSize : adjItemSize2)\n };\n const ratio = availableSpace / (rolumnSize2 + adjItemSize2);\n if (Math.abs(1 - ratio) > Math.abs(1 - lastRatio)) {\n // rolumn is better without adding this item\n finishRolumn(idx - 1);\n startIdx = idx;\n startPos += (this._idealSize! * lastRatio) + this._spacing;\n lastRatio = (this._viewDim2 - (2 * this._spacing)) / adjItemSize2;\n rolumnSize2 = adjItemSize2;\n }\n else {\n // add this item and continue\n rolumnSize2 += adjItemSize2;\n lastRatio = ratio;\n }\n if (idx === this._chunkSize! - 1) {\n finishRolumn(idx);\n }\n idx++;\n }\n const lastRolumn = chunk._rolumns[chunk._rolumns.length - 1];\n chunk._size = lastRolumn._startPos + lastRolumn._size;\n return chunk; \n }\n\n _updateLayout(): void {\n if (/*this._rolumnStartIdx === undefined ||*/ this._viewDim2 === 0) return;\n this._chunkSize = Math.ceil(2 * (this._viewDim1 * this._viewDim2) / (this._idealSize! * this._idealSize!));\n console.log('chunkSize', this._chunkSize);\n // TODO: An odd place to do this, need to think through the logistics of getting size info to the layout\n // in all cases\n // this._itemSizes.length = 100;//this._totalItems;\n this._chunks[0] = this._layOutChunk(0);\n // TODO (graynorton): This is a hack to force reflow\n this._spacingChanged = true;\n}\n\n _updateScrollSize() {\n const chunk = this._chunks[0];\n this._scrollSize = !chunk || chunk._rolumns.length === 0 ? 1 : chunk._size + (2 * this._spacing);\n // chunk._rolumns[chunk._rolumns.length - 1]._startPos +\n // chunk._itemPositions[chunk._rolumns.length - 1][this._sizeDim] +\n // (this._spacing * 2);\n }\n}"]} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dGrid.d.ts b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dGrid.d.ts new file mode 100644 index 0000000000..9c63a02c1e --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dGrid.d.ts @@ -0,0 +1,20 @@ +import { Layout1dBase } from "./Layout1dBase.js"; +/** + * TODO @straversi: document and test this Layout. + */ +export declare abstract class Layout1dGrid< + Config +> extends Layout1dBase { + protected _rolumns: number; + _viewDim2Changed(): void; + _itemDim2Changed(): void; + _getActiveItems(): void; + _getItemPosition( + idx: number + ): { + top: number; + left: number; + }; + _updateScrollSize(): void; +} +//# sourceMappingURL=Layout1dGrid.d.ts.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dGrid.d.ts.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dGrid.d.ts.map new file mode 100644 index 0000000000..ed14c15459 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dGrid.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Layout1dGrid.d.ts","sourceRoot":"","sources":["../../../../src/lib/uni-virtualizer/lib/layouts/Layout1dGrid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAE/C;;GAEG;AACH,8BAAsB,YAAY,CAAC,MAAM,CAAE,SAAQ,YAAY,CAAC,MAAM,CAAC;IACrE,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAK;IAO/B,gBAAgB;IAIhB,gBAAgB;IAIhB,eAAe;IAef,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC;IAQ1D,iBAAiB;CAIlB"} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dGrid.js b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dGrid.js new file mode 100644 index 0000000000..c1c3919273 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dGrid.js @@ -0,0 +1,52 @@ +import { Layout1dBase } from "./Layout1dBase.js"; +/** + * TODO @straversi: document and test this Layout. + */ +export class Layout1dGrid extends Layout1dBase { + constructor() { + super(...arguments); + this._rolumns = 1; + } + // constructor(config) { + // super(config); + // this._rolumns = 1; + // } + _viewDim2Changed() { + this._scheduleLayoutUpdate(); + } + _itemDim2Changed() { + this._scheduleLayoutUpdate(); + } + _getActiveItems() { + const min = Math.max(0, this._scrollPosition - this._overhang); + const max = Math.min( + this._scrollSize, + this._scrollPosition + this._viewDim1 + this._overhang + ); + const firstCow = Math.floor(min / this._delta); + const lastCow = Math.ceil(max / this._delta) - 1; + this._first = firstCow * this._rolumns; + this._last = Math.min( + (lastCow + 1) * this._rolumns - 1, + this._totalItems - 1 + ); + this._physicalMin = this._delta * firstCow; + this._physicalMax = this._delta * (lastCow + 1); + } + _getItemPosition(idx) { + return { + [this._positionDim]: + this._spacing + Math.floor(idx / this._rolumns) * this._delta, + [this._secondaryPositionDim]: + this._spacing + + (idx % this._rolumns) * (this._spacing + this._itemDim2), + }; + } + _updateScrollSize() { + this._scrollSize = Math.max( + 1, + Math.ceil(this._totalItems / this._rolumns) * this._delta + this._spacing + ); + } +} +//# sourceMappingURL=Layout1dGrid.js.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dGrid.js.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dGrid.js.map new file mode 100644 index 0000000000..d5b5318d4d --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dGrid.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Layout1dGrid.js","sourceRoot":"","sources":["../../../../src/lib/uni-virtualizer/lib/layouts/Layout1dGrid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAE/C;;GAEG;AACH,MAAM,OAAgB,YAAqB,SAAQ,YAAoB;IAAvE;;QACY,aAAQ,GAAW,CAAC,CAAC;IA0CjC,CAAC;IAxCC,wBAAwB;IACxB,mBAAmB;IACnB,uBAAuB;IACvB,IAAI;IAEJ,gBAAgB;QACd,IAAI,CAAC,qBAAqB,EAAE,CAAC;IAC/B,CAAC;IAED,gBAAgB;QACd,IAAI,CAAC,qBAAqB,EAAE,CAAC;IAC/B,CAAC;IAED,eAAe;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAChB,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAEjD,IAAI,CAAC,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QACvC,IAAI,CAAC,KAAK;YACN,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;QACxE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC;QAC3C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,gBAAgB,CAAC,GAAW;QAC1B,OAAO;YACL,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,MAAM;YAC9E,CAAC,IAAI,CAAC,qBAAqB,CAAC,EAAE,IAAI,CAAC,QAAQ;gBAC3C,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;SACrB,CAAC;IAC9C,CAAC;IAED,iBAAiB;QACf,IAAI,CAAC,WAAW;YACZ,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC7F,CAAC;CACF","sourcesContent":["import {Layout1dBase} from './Layout1dBase.js';\n\n/**\n * TODO @straversi: document and test this Layout.\n */\nexport abstract class Layout1dGrid extends Layout1dBase {\n protected _rolumns: number = 1;\n\n // constructor(config) {\n // super(config);\n // this._rolumns = 1;\n // }\n\n _viewDim2Changed() {\n this._scheduleLayoutUpdate();\n }\n\n _itemDim2Changed() {\n this._scheduleLayoutUpdate();\n }\n\n _getActiveItems() {\n const min = Math.max(0, this._scrollPosition - this._overhang);\n const max = Math.min(\n this._scrollSize,\n this._scrollPosition + this._viewDim1 + this._overhang);\n const firstCow = Math.floor(min / this._delta);\n const lastCow = Math.ceil(max / this._delta) - 1;\n\n this._first = firstCow * this._rolumns;\n this._last =\n Math.min(((lastCow + 1) * this._rolumns) - 1, this._totalItems - 1);\n this._physicalMin = this._delta * firstCow;\n this._physicalMax = this._delta * (lastCow + 1);\n }\n\n _getItemPosition(idx: number): {top: number, left: number} {\n return {\n [this._positionDim]: this._spacing + Math.floor(idx / this._rolumns) * this._delta,\n [this._secondaryPositionDim]: this._spacing +\n ((idx % this._rolumns) * (this._spacing + this._itemDim2))\n } as unknown as {top: number, left: number};\n }\n\n _updateScrollSize() {\n this._scrollSize =\n Math.max(1, Math.ceil(this._totalItems / this._rolumns) * this._delta + this._spacing);\n }\n}\n"]} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dNaturalSizeGrid.d.ts b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dNaturalSizeGrid.d.ts new file mode 100644 index 0000000000..42c93a28d3 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dNaturalSizeGrid.d.ts @@ -0,0 +1,8 @@ +import { Layout1dGrid } from "./Layout1dGrid.js"; +import { Layout1dBaseConfig } from "./Layout1dBase.js"; +import { ItemBox } from "./Layout"; +export declare class Layout1dNaturalSizeGrid extends Layout1dGrid { + updateItemSizes(sizes: { [key: number]: ItemBox }): void; + _updateLayout(): void; +} +//# sourceMappingURL=Layout1dNaturalSizeGrid.d.ts.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dNaturalSizeGrid.d.ts.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dNaturalSizeGrid.d.ts.map new file mode 100644 index 0000000000..5b45aac00d --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dNaturalSizeGrid.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Layout1dNaturalSizeGrid.d.ts","sourceRoot":"","sources":["../../../../src/lib/uni-virtualizer/lib/layouts/Layout1dNaturalSizeGrid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAC,kBAAkB,EAAC,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAC,OAAO,EAAC,MAAM,UAAU,CAAC;AAEjC,qBAAa,uBAAwB,SAAQ,YAAY,CAAC,kBAAkB,CAAC;IACzE,eAAe,CAAC,KAAK,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAC;IAQ7C,aAAa;CAYlB"} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dNaturalSizeGrid.js b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dNaturalSizeGrid.js new file mode 100644 index 0000000000..65ed5ad0f9 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dNaturalSizeGrid.js @@ -0,0 +1,23 @@ +import { Layout1dGrid } from "./Layout1dGrid.js"; +export class Layout1dNaturalSizeGrid extends Layout1dGrid { + updateItemSizes(sizes) { + // Assume all items have the same size. + const size = Object.values(sizes)[0]; + if (size) { + this.itemSize = size; + } + } + _updateLayout() { + const { _spacing } = this; + this._rolumns = Math.max(1, Math.floor(this._viewDim2 / this._itemDim2)); + if (this._rolumns > 1) { + this._spacing = + (this._viewDim2 % (this._rolumns * this._itemDim2)) / + (this._rolumns + 1); + } else { + this._spacing = 0; + } + this._spacingChanged = !(_spacing === this._spacing); + } +} +//# sourceMappingURL=Layout1dNaturalSizeGrid.js.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dNaturalSizeGrid.js.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dNaturalSizeGrid.js.map new file mode 100644 index 0000000000..cf506e8d0d --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dNaturalSizeGrid.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Layout1dNaturalSizeGrid.js","sourceRoot":"","sources":["../../../../src/lib/uni-virtualizer/lib/layouts/Layout1dNaturalSizeGrid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAI/C,MAAM,OAAO,uBAAwB,SAAQ,YAAgC;IACzE,eAAe,CAAC,KAA+B;QAC3C,uCAAuC;QACvC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACrC,IAAI,IAAI,EAAE;YACR,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;SACtB;IACH,CAAC;IAED,aAAa;QACX,MAAM,EAAC,QAAQ,EAAC,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QACzE,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,EAAE;YACrB,IAAI,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC/D,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;SACzB;aACI;YACH,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;SACnB;QACD,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,CAAC,CAAC;IACvD,CAAC;CACN","sourcesContent":["import {Layout1dGrid} from './Layout1dGrid.js';\nimport {Layout1dBaseConfig} from './Layout1dBase.js';\nimport {ItemBox} from './Layout';\n\nexport class Layout1dNaturalSizeGrid extends Layout1dGrid {\n updateItemSizes(sizes: {[key: number]: ItemBox}) {\n // Assume all items have the same size.\n const size = Object.values(sizes)[0];\n if (size) {\n this.itemSize = size;\n }\n }\n \n _updateLayout() {\n const {_spacing} = this;\n this._rolumns = Math.max(1, Math.floor(this._viewDim2 / this._itemDim2));\n if (this._rolumns > 1) {\n this._spacing = (this._viewDim2 % (this._rolumns * this._itemDim2)) /\n (this._rolumns + 1);\n }\n else {\n this._spacing = 0;\n }\n this._spacingChanged = !(_spacing === this._spacing);\n } \n}"]} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dSquareGrid.d.ts b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dSquareGrid.d.ts new file mode 100644 index 0000000000..5f7e92b5c9 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dSquareGrid.d.ts @@ -0,0 +1,22 @@ +import { Layout1dBaseConfig } from "./Layout1dBase.js"; +import { Layout1dGrid } from "./Layout1dGrid.js"; +import { Positions } from "./Layout.js"; +interface Layout1dSquareGridConfig extends Layout1dBaseConfig { + spacing?: number; + idealSize?: number; +} +declare type Layout1dSquareGridSpecifier = Layout1dSquareGridConfig & { + type: new (config?: Layout1dSquareGridConfig) => Layout1dSquareGrid; +}; +declare type Layout1dSquareGridSpecifierFactory = ( + config?: Layout1dSquareGridConfig +) => Layout1dSquareGridSpecifier; +export declare const layout1dSquareGrid: Layout1dSquareGridSpecifierFactory; +export declare class Layout1dSquareGrid extends Layout1dGrid { + protected _idealSize: number; + set idealSize(px: number); + _getItemPosition(idx: number): Positions; + _updateLayout(): void; +} +export {}; +//# sourceMappingURL=Layout1dSquareGrid.d.ts.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dSquareGrid.d.ts.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dSquareGrid.d.ts.map new file mode 100644 index 0000000000..9fcaf8aa40 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dSquareGrid.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"Layout1dSquareGrid.d.ts","sourceRoot":"","sources":["../../../../src/lib/uni-virtualizer/lib/layouts/Layout1dSquareGrid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAC,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AAEtC,UAAU,wBAAyB,SAAQ,kBAAkB;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,aAAK,2BAA2B,GAAG,wBAAwB,GAAG;IAC5D,IAAI,EAAE,KAAI,MAAM,CAAC,EAAE,wBAAwB,KAAK,kBAAkB,CAAA;CACnE,CAAA;AAED,aAAK,kCAAkC,GAAG,CAAC,MAAM,CAAC,EAAE,wBAAwB,KAAK,2BAA2B,CAAC;AAE7G,eAAO,MAAM,kBAAkB,EAAE,kCAEvB,CAAC;AAEX,qBAAa,kBAAmB,SAAQ,YAAY,CAAC,wBAAwB,CAAC;IAC5E,SAAS,CAAC,UAAU,EAAE,MAAM,CAAO;IASnC,IAAI,SAAS,CAAC,EAAE,EAAE,MAAM,EAKvB;IAED,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS;IAIxC,aAAa;CASd"} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dSquareGrid.js b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dSquareGrid.js new file mode 100644 index 0000000000..4af9049334 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dSquareGrid.js @@ -0,0 +1,41 @@ +import { Layout1dGrid } from "./Layout1dGrid.js"; +export const layout1dSquareGrid = (config) => + Object.assign( + { + type: Layout1dSquareGrid, + }, + config + ); +export class Layout1dSquareGrid extends Layout1dGrid { + constructor() { + super(...arguments); + this._idealSize = 200; + } + // constructor(config) { + // super(config); + // if (config.idealSize === undefined) { + // this._idealSize = 200; + // } + // } + set idealSize(px) { + if (px !== this._idealSize) { + this._idealSize = px; + this._scheduleLayoutUpdate(); + } + } + _getItemPosition(idx) { + return Object.assign(super._getItemPosition(idx), this._itemSize); + } + _updateLayout() { + const frolumns = this._viewDim2 / this._idealSize; + this._rolumns = + frolumns % 1 < 0.5 ? Math.floor(frolumns) : Math.ceil(frolumns); + const adjSize = + (this._viewDim2 - (this._rolumns + 1) * this._spacing) / this._rolumns; + if (adjSize !== this._itemSize.width) { + this._itemSize = { width: adjSize, height: adjSize }; + this._spacingChanged = true; + } + } +} +//# sourceMappingURL=Layout1dSquareGrid.js.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dSquareGrid.js.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dSquareGrid.js.map new file mode 100644 index 0000000000..701d122818 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/layouts/Layout1dSquareGrid.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Layout1dSquareGrid.js","sourceRoot":"","sources":["../../../../src/lib/uni-virtualizer/lib/layouts/Layout1dSquareGrid.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAc/C,MAAM,CAAC,MAAM,kBAAkB,GAAuC,CAAC,MAAiC,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC;IACzH,IAAI,EAAE,kBAAkB;CACzB,EAAE,MAAM,CAAC,CAAC;AAEX,MAAM,OAAO,kBAAmB,SAAQ,YAAsC;IAA9E;;QACY,eAAU,GAAW,GAAG,CAAC;IA6BrC,CAAC;IA3BC,wBAAwB;IACxB,mBAAmB;IACnB,0CAA0C;IAC1C,+BAA+B;IAC/B,MAAM;IACN,IAAI;IAEJ,IAAI,SAAS,CAAC,EAAU;QACtB,IAAI,EAAE,KAAK,IAAI,CAAC,UAAU,EAAE;YAC1B,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;YACrB,IAAI,CAAC,qBAAqB,EAAE,CAAC;SAC9B;IACH,CAAC;IAED,gBAAgB,CAAC,GAAW;QAC1B,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACpE,CAAC;IAED,aAAa;QACX,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC;QAClD,IAAI,CAAC,QAAQ,GAAG,QAAQ,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChF,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;QACzF,IAAI,OAAO,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE;YACpC,IAAI,CAAC,SAAS,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;YACrD,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;SAC7B;IACH,CAAC;CACF","sourcesContent":["import {Layout1dBaseConfig} from './Layout1dBase.js';\nimport {Layout1dGrid} from './Layout1dGrid.js';\nimport {Positions} from './Layout.js';\n\ninterface Layout1dSquareGridConfig extends Layout1dBaseConfig {\n spacing?: number,\n idealSize?: number\n}\n\ntype Layout1dSquareGridSpecifier = Layout1dSquareGridConfig & {\n type: new(config?: Layout1dSquareGridConfig) => Layout1dSquareGrid\n}\n\ntype Layout1dSquareGridSpecifierFactory = (config?: Layout1dSquareGridConfig) => Layout1dSquareGridSpecifier;\n\nexport const layout1dSquareGrid: Layout1dSquareGridSpecifierFactory = (config?: Layout1dSquareGridConfig) => Object.assign({\n type: Layout1dSquareGrid\n}, config);\n\nexport class Layout1dSquareGrid extends Layout1dGrid {\n protected _idealSize: number = 200;\n\n // constructor(config) {\n // super(config);\n // if (config.idealSize === undefined) {\n // this._idealSize = 200;\n // }\n // }\n\n set idealSize(px: number) {\n if (px !== this._idealSize) {\n this._idealSize = px;\n this._scheduleLayoutUpdate();\n }\n }\n\n _getItemPosition(idx: number): Positions {\n return Object.assign(super._getItemPosition(idx), this._itemSize);\n }\n\n _updateLayout() {\n const frolumns = this._viewDim2 / this._idealSize;\n this._rolumns = frolumns % 1 < 0.5 ? Math.floor(frolumns) : Math.ceil(frolumns);\n const adjSize = (this._viewDim2 - ((this._rolumns + 1) * this._spacing)) / this._rolumns;\n if (adjSize !== this._itemSize.width) {\n this._itemSize = { width: adjSize, height: adjSize };\n this._spacingChanged = true;\n }\n } \n}"]} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/EventTarget.d.ts b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/EventTarget.d.ts new file mode 100644 index 0000000000..0839acf088 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/EventTarget.d.ts @@ -0,0 +1,6 @@ +interface EventTargetConstructor { + new (): EventTarget; +} +export default function EventTarget(): Promise; +export {}; +//# sourceMappingURL=EventTarget.d.ts.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/EventTarget.d.ts.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/EventTarget.d.ts.map new file mode 100644 index 0000000000..7e5f49dc04 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/EventTarget.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"EventTarget.d.ts","sourceRoot":"","sources":["../../../../src/lib/uni-virtualizer/lib/polyfillLoaders/EventTarget.ts"],"names":[],"mappings":"AAEA,UAAU,sBAAsB;IAC5B,QAAO,WAAW,CAAA;CACrB;AAKD,wBAA8B,WAAW,oCAExC"} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/EventTarget.js b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/EventTarget.js new file mode 100644 index 0000000000..4fd9c6546d --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/EventTarget.js @@ -0,0 +1,15 @@ +let _ET; +let ET; +export default async function EventTarget() { + return ET || init(); +} +async function init() { + _ET = window.EventTarget; + try { + new _ET(); + } catch (_a) { + _ET = (await import("event-target-shim")).EventTarget; + } + return (ET = _ET); +} +//# sourceMappingURL=EventTarget.js.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/EventTarget.js.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/EventTarget.js.map new file mode 100644 index 0000000000..4ce7a8b18f --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/EventTarget.js.map @@ -0,0 +1 @@ +{"version":3,"file":"EventTarget.js","sourceRoot":"","sources":["../../../../src/lib/uni-virtualizer/lib/polyfillLoaders/EventTarget.ts"],"names":[],"mappings":"AAMA,IAAI,GAA+C,CAAC;AACpD,IAAI,EAA0B,CAAC;AAE/B,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,WAAW;IACrC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC;AACxB,CAAC;AAED,KAAK,UAAU,IAAI;IACf,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC;IACzB,IAAI;QACA,IAAI,GAAG,EAAE,CAAC;KACb;IACD,WAAM;QACF,GAAG,GAAG,CAAC,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC,CAAC,WAAW,CAAC;KACzD;IACD,OAAO,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC;AACtB,CAAC","sourcesContent":["type EventTargetModule = typeof import('event-target-shim');\n\ninterface EventTargetConstructor {\n new(): EventTarget\n}\n\nlet _ET: EventTargetModule | EventTargetConstructor;\nlet ET: EventTargetConstructor;\n\nexport default async function EventTarget() {\n return ET || init();\n}\n\nasync function init() {\n _ET = window.EventTarget;\n try {\n new _ET();\n }\n catch {\n _ET = (await import('event-target-shim')).EventTarget;\n }\n return (ET = _ET);\n}"]} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/ResizeObserver.d.ts b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/ResizeObserver.d.ts new file mode 100644 index 0000000000..aee6384ff5 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/ResizeObserver.d.ts @@ -0,0 +1,3 @@ +import { ResizeObserverConstructor } from "../polyfills/resize-observer-polyfill/ResizeObserver.js"; +export default function ResizeObserver(): Promise; +//# sourceMappingURL=ResizeObserver.d.ts.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/ResizeObserver.d.ts.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/ResizeObserver.d.ts.map new file mode 100644 index 0000000000..4168af9c1a --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/ResizeObserver.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"ResizeObserver.d.ts","sourceRoot":"","sources":["../../../../src/lib/uni-virtualizer/lib/polyfillLoaders/ResizeObserver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,yDAAyD,CAAC;AAMpG,wBAA8B,cAAc,uCAE3C"} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/ResizeObserver.js b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/ResizeObserver.js new file mode 100644 index 0000000000..184e1749b7 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/ResizeObserver.js @@ -0,0 +1,20 @@ +let _RO; +let RO; +export default async function ResizeObserver() { + return RO || init(); +} +async function init() { + if (_RO) { + return (await _RO).default; + } else { + _RO = window.ResizeObserver; + try { + new _RO(function () {}); + } catch (e) { + _RO = import("../polyfills/resize-observer-polyfill/ResizeObserver.js"); + _RO = (await _RO).default; + } + return (RO = _RO); + } +} +//# sourceMappingURL=ResizeObserver.js.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/ResizeObserver.js.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/ResizeObserver.js.map new file mode 100644 index 0000000000..b7fd1477db --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfillLoaders/ResizeObserver.js.map @@ -0,0 +1 @@ +{"version":3,"file":"ResizeObserver.js","sourceRoot":"","sources":["../../../../src/lib/uni-virtualizer/lib/polyfillLoaders/ResizeObserver.ts"],"names":[],"mappings":"AAGA,IAAI,GAAqD,CAAC;AAC1D,IAAI,EAA6B,CAAC;AAElC,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,cAAc;IACxC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC;AACxB,CAAC;AAED,KAAK,UAAU,IAAI;IACf,IAAI,GAAG,EAAE;QACL,OAAO,CAAC,MAAM,GAA4B,CAAA,CAAC,OAAO,CAAC;KACtD;SACI;QACD,GAAG,GAAG,MAAM,CAAC,cAAc,CAAC;QAC5B,IAAI;YACA,IAAI,GAAG,CAAC,cAAY,CAAC,CAAC,CAAC;SAC1B;QACD,OAAO,CAAC,EAAE;YACN,GAAG,GAAG,MAAM,CAAC,yDAAyD,CAAoC,CAAC;YAC3G,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC;SAC7B;QACD,OAAO,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC;KACrB;AACL,CAAC","sourcesContent":["import { ResizeObserverConstructor } from '../polyfills/resize-observer-polyfill/ResizeObserver.js';\ntype ResizeObserverModule = typeof import('../polyfills/resize-observer-polyfill/ResizeObserver.js');\n\nlet _RO: ResizeObserverModule | ResizeObserverConstructor;\nlet RO: ResizeObserverConstructor;\n\nexport default async function ResizeObserver() {\n return RO || init();\n}\n\nasync function init() {\n if (_RO) {\n return (await _RO as ResizeObserverModule).default;\n }\n else {\n _RO = window.ResizeObserver;\n try {\n new _RO(function() {});\n }\n catch (e) {\n _RO = import('../polyfills/resize-observer-polyfill/ResizeObserver.js') as unknown as ResizeObserverModule;\n _RO = (await _RO).default;\n }\n return (RO = _RO); \n }\n}"]} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfills/resize-observer-polyfill/ResizeObserver.js b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfills/resize-observer-polyfill/ResizeObserver.js new file mode 100644 index 0000000000..21886a3e29 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/lib/polyfills/resize-observer-polyfill/ResizeObserver.js @@ -0,0 +1,960 @@ +/** + * Detects whether window and document objects are available in current environment. + */ +var isBrowser = + typeof window !== "undefined" && + typeof document !== "undefined" && + window.document === document; + +// Returns global object of a current environment. +var global$1 = (function () { + if (typeof global !== "undefined" && global.Math === Math) { + return global; + } + if (typeof self !== "undefined" && self.Math === Math) { + return self; + } + if (typeof window !== "undefined" && window.Math === Math) { + return window; + } + // eslint-disable-next-line no-new-func + return Function("return this")(); +})(); + +/** + * A shim for the requestAnimationFrame which falls back to the setTimeout if + * first one is not supported. + * + * @returns {number} Requests' identifier. + */ +var requestAnimationFrame$1 = (function () { + if (typeof requestAnimationFrame === "function") { + // It's required to use a bounded function because IE sometimes throws + // an "Invalid calling object" error if rAF is invoked without the global + // object on the left hand side. + return requestAnimationFrame.bind(global$1); + } + var result = function (callback) { + return setTimeout(function () { + callback(+Date.now()); + }, 1000 / 60); + }; + return result; +})(); + +// Defines minimum timeout before adding a trailing call. +var trailingTimeout = 2; +/** + * Creates a wrapper function which ensures that provided callback will be + * invoked only once during the specified delay period. + * + * @param callback - Function to be invoked after the delay period. + * @param delay - Delay after which to invoke callback. + */ +function throttle(callback, delay) { + var leadingCall = false, + trailingCall = false, + lastCallTime = 0; + /** + * Invokes the original callback function and schedules new invocation if + * the "proxy" was called during current request. + */ + function resolvePending() { + if (leadingCall) { + leadingCall = false; + callback(); + } + if (trailingCall) { + proxy(); + } + } + /** + * Callback invoked after the specified delay. It will further postpone + * invocation of the original function delegating it to the + * requestAnimationFrame. + * + * @returns {void} + */ + function timeoutCallback() { + requestAnimationFrame$1(resolvePending); + } + /** + * Schedules invocation of the original function. + */ + function proxy() { + var timeStamp = Date.now(); + if (leadingCall) { + // Reject immediately following calls. + if (timeStamp - lastCallTime < trailingTimeout) { + return; + } + // Schedule new call to be in invoked when the pending one is resolved. + // This is important for "transitions" which never actually start + // immediately so there is a chance that we might miss one if change + // happens amids the pending invocation. + trailingCall = true; + } else { + leadingCall = true; + trailingCall = false; + setTimeout(timeoutCallback, delay); + } + lastCallTime = timeStamp; + } + return proxy; +} + +// Minimum delay before invoking the update of observers. +var REFRESH_DELAY = 20; +// A list of substrings of CSS properties used to find transition events that +// might affect dimensions of observed elements. +var transitionKeys = [ + "top", + "right", + "bottom", + "left", + "width", + "height", + "size", + "weight", +]; +// Check if MutationObserver is available. +var mutationObserverSupported = typeof MutationObserver !== "undefined"; +// Get the native implementation of HTMLElement.attachShadow +var origAttachShadow = + isBrowser && + HTMLElement.prototype.attachShadow && + HTMLElement.prototype.attachShadow.toString().indexOf("[native code]") !== -1 + ? HTMLElement.prototype.attachShadow + : null; +/** + * Singleton controller class which handles updates of ResizeObserver instances. + */ +var ResizeObserverController = /** @class */ (function () { + /** + * Creates a new instance of ResizeObserverController. + */ + function ResizeObserverController() { + /** + * Indicates whether DOM listeners have been added. + */ + this.connected_ = false; + /** + * Tells that controller has subscribed for Mutation Events. + */ + this.mutationEventsAdded_ = false; + /** + * Keeps reference to the instance of MutationObserver. + */ + this.mutationsObserver_ = null; + /** + * A list of connected observers. + */ + this.observers_ = []; + this.onTransitionEnd_ = this.onTransitionEnd_.bind(this); + this.refresh = throttle(this.refresh.bind(this), REFRESH_DELAY); + } + /** + * Adds observer to observers list. + * + * @param observer Observer to be added. + */ + ResizeObserverController.prototype.addObserver = function (observer) { + if (!~this.observers_.indexOf(observer)) { + this.observers_.push(observer); + } + // Add listeners if they haven't been added yet. + if (!this.connected_) { + this.connect_(); + } + }; + /** + * Removes observer from observers list. + * + * @param observer Observer to be removed. + */ + ResizeObserverController.prototype.removeObserver = function (observer) { + var observers = this.observers_; + var index = observers.indexOf(observer); + // Remove observer if it's present in registry. + if (~index) { + observers.splice(index, 1); + } + // Remove listeners if controller has no connected observers. + if (!observers.length && this.connected_) { + this.disconnect_(); + } + }; + /** + * Invokes the update of observers. It will continue running updates insofar + * it detects changes. + */ + ResizeObserverController.prototype.refresh = function () { + var changesDetected = this.updateObservers_(); + // Continue running updates if changes have been detected as there might + // be future ones caused by CSS transitions. + if (changesDetected) { + this.refresh(); + } + }; + /** + * Updates every observer from observers list and notifies them of queued + * entries. + * + * @returns Returns "true" if any observer has detected changes in + * dimensions of it's elements. + */ + ResizeObserverController.prototype.updateObservers_ = function () { + // Collect observers that have active observations. + var activeObservers = this.observers_.filter(function (observer) { + return observer.gatherActive(), observer.hasActive(); + }); + // Deliver notifications in a separate cycle in order to avoid any + // collisions between observers, e.g. when multiple instances of + // ResizeObserver are tracking the same element and the callback of one + // of them changes content dimensions of the observed target. Sometimes + // this may result in notifications being blocked for the rest of observers. + activeObservers.forEach(function (observer) { + return observer.broadcastActive(); + }); + return activeObservers.length > 0; + }; + /** + * Initializes DOM listeners. + */ + ResizeObserverController.prototype.connect_ = function () { + // Do nothing if running in a non-browser environment or if listeners + // have been already added. + if (!isBrowser || this.connected_) { + return; + } + // Subscription to the "Transitionend" event is used as a workaround for + // delayed transitions. This way it's possible to capture at least the + // final state of an element. + document.addEventListener("transitionend", this.onTransitionEnd_); + window.addEventListener("resize", this.refresh); + if (mutationObserverSupported) { + this.mutationsObserver_ = new MutationObserver(this.refresh); + var options_1 = { + attributes: true, + childList: true, + characterData: true, + subtree: true, + }; + this.mutationsObserver_.observe(document, options_1); + if (origAttachShadow) { + var controller_1 = this; + (function observeExistingShadowRoots(node) { + var shadowRoot = node.shadowRoot; + if (shadowRoot) { + controller_1.mutationsObserver_.observe(shadowRoot, options_1); + observeExistingShadowRoots(shadowRoot); + } + var child = node.firstElementChild; + while (child) { + observeExistingShadowRoots(child); + child = child.nextElementSibling; + } + })(document); + HTMLElement.prototype.attachShadow = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + var shadowRoot = origAttachShadow.apply(this, args); + controller_1.mutationsObserver_.observe(shadowRoot, options_1); + return shadowRoot; + }; + } + } else { + document.addEventListener("DOMSubtreeModified", this.refresh); + this.mutationEventsAdded_ = true; + } + this.connected_ = true; + }; + /** + * Removes DOM listeners. + */ + ResizeObserverController.prototype.disconnect_ = function () { + // Do nothing if running in a non-browser environment or if listeners + // have been already removed. + if (!isBrowser || !this.connected_) { + return; + } + document.removeEventListener("transitionend", this.onTransitionEnd_); + window.removeEventListener("resize", this.refresh); + if (this.mutationsObserver_) { + this.mutationsObserver_.disconnect(); + if (origAttachShadow) { + HTMLElement.prototype.attachShadow = origAttachShadow; + } + } + if (this.mutationEventsAdded_) { + document.removeEventListener("DOMSubtreeModified", this.refresh); + } + this.mutationsObserver_ = null; + this.mutationEventsAdded_ = false; + this.connected_ = false; + }; + /** + * "Transitionend" event handler. + */ + ResizeObserverController.prototype.onTransitionEnd_ = function (_a) { + var _b = _a.propertyName, + propertyName = _b === void 0 ? "" : _b; + // Detect whether transition may affect dimensions of an element. + var isReflowProperty = transitionKeys.some(function (key) { + return !!~propertyName.indexOf(key); + }); + if (isReflowProperty) { + this.refresh(); + } + }; + /** + * Returns instance of the ResizeObserverController. + */ + ResizeObserverController.getInstance = function () { + if (!ResizeObserverController.instance_) { + ResizeObserverController.instance_ = new ResizeObserverController(); + } + return ResizeObserverController.instance_; + }; + /** + * Holds reference to the controller's instance. + */ + ResizeObserverController.instance_ = null; + return ResizeObserverController; +})(); + +/*! ***************************************************************************** + Copyright (c) Microsoft Corporation. All rights reserved. + Licensed under the Apache License, Version 2.0 (the "License"); you may not use + this file except in compliance with the License. You may obtain a copy of the + License at http://www.apache.org/licenses/LICENSE-2.0 + + THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED + WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, + MERCHANTABLITY OR NON-INFRINGEMENT. + + See the Apache Version 2.0 License for specific language governing permissions + and limitations under the License. + ***************************************************************************** */ + +function __values(o) { + var m = typeof Symbol === "function" && o[Symbol.iterator], + i = 0; + if (m) return m.call(o); + return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + }, + }; +} + +/** + * Defines non-writable/enumerable properties of the provided target object. + * + * @param target Object for which to define properties. + * @param props Properties to be defined. + * @returns Target object. + */ +var defineConfigurable = function (target, props) { + var e_1, _a; + try { + for ( + var _b = __values(Object.keys(props)), _c = _b.next(); + !_c.done; + _c = _b.next() + ) { + var key = _c.value; + Object.defineProperty(target, key, { + value: props[key], + enumerable: false, + writable: false, + configurable: true, + }); + } + } catch (e_1_1) { + e_1 = { error: e_1_1 }; + } finally { + try { + if (_c && !_c.done && (_a = _b.return)) _a.call(_b); + } finally { + if (e_1) throw e_1.error; + } + } + return target; +}; + +/** + * Returns the global object associated with provided element. + * + * @param {EventT} target + * @returns {Object} + */ +var getWindowOf = function (target) { + var _a; + // Assume that the element is an instance of Node, which means that it + // has the "ownerDocument" property from which we can retrieve a + // corresponding global object. + // Return the local global object if it's not possible extract one from + // provided element. + return ( + ((_a = + target === null || target === void 0 ? void 0 : target.ownerDocument) === + null || _a === void 0 + ? void 0 + : _a.defaultView) || global$1 + ); +}; + +// Placeholder of an empty content rectangle. +var emptyRect = createRectInit(0, 0, 0, 0); +/** + * Converts provided string to a number. + */ +function toFloat(value) { + if (typeof value === "number") { + return value; + } + return parseFloat(value) || 0; +} +/** + * Extracts borders size from provided styles. + */ +function getBordersSize(styles) { + var positions = []; + for (var _i = 1; _i < arguments.length; _i++) { + positions[_i - 1] = arguments[_i]; + } + return positions.reduce(function (size, position) { + var value = styles["border-" + position + "-width"]; + return size + toFloat(value); + }, 0); +} +/** + * Extracts paddings sizes from provided styles. + */ +function getPaddings(styles) { + var st = styles; + return { + top: toFloat(st["padding-top"]), + right: toFloat(st["padding-right"]), + bottom: toFloat(st["padding-bottom"]), + left: toFloat(st["padding-left"]), + }; +} +/** + * Calculates content rectangle of provided SVG element. + * + * @param target Element content rectangle of which needs to be calculated. + */ +function getSVGContentRect(target) { + var bbox = target.getBBox(); + return createRectInit(0, 0, bbox.width, bbox.height); +} +/** + * Calculates content rectangle of provided HTMLElement. + * + * @param target Element for which to calculate the content rectangle. + */ +function getHTMLElementContentRect(target) { + // Client width & height properties can't be + // used exclusively as they provide rounded values. + var clientWidth = target.clientWidth, + clientHeight = target.clientHeight; + // By this condition we can catch all non-replaced inline, hidden and + // detached elements. Though elements with width & height properties less + // than 0.5 will be discarded as well. + // + // Without it we would need to implement separate methods for each of + // those cases and it's not possible to perform a precise and performance + // effective test for hidden elements. E.g. even jQuery's ':visible' filter + // gives wrong results for elements with width & height less than 0.5. + if (!clientWidth && !clientHeight) { + return emptyRect; + } + var styles = getWindowOf(target).getComputedStyle(target); + var paddings = getPaddings(styles); + var horizPad = paddings.left + paddings.right; + var vertPad = paddings.top + paddings.bottom; + // Computed styles of width & height are being used because they are the + // only dimensions available to JS that contain non-rounded values. It could + // be possible to utilize the getBoundingClientRect if only it's data wasn't + // affected by CSS transformations let alone paddings, borders and scroll + // bars. + var width = toFloat(styles.width), + height = toFloat(styles.height); + // Width & height include paddings and borders when the 'border-box' box + // model is applied (except for IE). + if (styles.boxSizing === "border-box") { + // Following conditions are required to handle Internet Explorer which + // doesn't include paddings and borders to computed CSS dimensions. + // + // We can say that if CSS dimensions + paddings are equal to the "client" + // properties then it's either IE, and thus we don't need to subtract + // anything, or an element merely doesn't have paddings/borders styles. + if (Math.round(width + horizPad) !== clientWidth) { + width -= getBordersSize(styles, "left", "right") + horizPad; + } + if (Math.round(height + vertPad) !== clientHeight) { + height -= getBordersSize(styles, "top", "bottom") + vertPad; + } + } + // Following steps can't be applied to the document's root element as its + // client[Width/Height] properties represent viewport area of the window. + // Besides, it's as well not necessary as the itself neither has + // rendered scroll bars nor it can be clipped. + if (!isDocumentElement(target)) { + // In some browsers (only in Firefox, actually) CSS width & height + // include scroll bars size which can be removed at this step as scroll + // bars are the only difference between rounded dimensions + paddings + // and "client" properties, though that is not always true in Chrome. + var vertScrollbar = Math.round(width + horizPad) - clientWidth; + var horizScrollbar = Math.round(height + vertPad) - clientHeight; + // Chrome has a rather weird rounding of "client" properties. + // E.g. for an element with content width of 314.2px it sometimes gives + // the client width of 315px and for the width of 314.7px it may give + // 314px. And it doesn't happen all the time. So just ignore this delta + // as a non-relevant. + if (Math.abs(vertScrollbar) !== 1) { + width -= vertScrollbar; + } + if (Math.abs(horizScrollbar) !== 1) { + height -= horizScrollbar; + } + } + return createRectInit(paddings.left, paddings.top, width, height); +} +/** + * Checks whether provided element is an instance of the SVGGraphicsElement. + * + * @param target Element to be checked. + */ +var isSVGGraphicsElement = (function () { + // Some browsers, namely IE and Edge, don't have the SVGGraphicsElement + // interface. + if (typeof SVGGraphicsElement !== "undefined") { + return function (target) { + return target instanceof getWindowOf(target).SVGGraphicsElement; + }; + } + // If it's so, then check that element is at least an instance of the + // SVGElement and that it has the "getBBox" method. + // eslint-disable-next-line no-extra-parens + return function (target) { + return ( + target instanceof getWindowOf(target).SVGElement && + typeof target.getBBox === "function" + ); + }; +})(); +/** + * Checks whether provided element is a document element (). + * + * @param target Element to be checked. + */ +function isDocumentElement(target) { + return target === getWindowOf(target).document.documentElement; +} +/** + * Calculates an appropriate content rectangle for provided html or svg element. + * + * @param target Element content rectangle of which needs to be calculated. + */ +function getContentRect(target) { + if (!isBrowser) { + return emptyRect; + } + if (isSVGGraphicsElement(target)) { + return getSVGContentRect(target); + } + return getHTMLElementContentRect(target); +} +/** + * Creates rectangle with an interface of the DOMRectReadOnly. + * Spec: https://drafts.fxtf.org/geometry/#domrectreadonly + * + * @param rectInit Object with rectangle's x/y coordinates and + * dimensions. + */ +function createReadOnlyRect(_a) { + var x = _a.x, + y = _a.y, + width = _a.width, + height = _a.height; + // If DOMRectReadOnly is available use it as a prototype for the rectangle. + var Constr = + typeof DOMRectReadOnly !== "undefined" ? DOMRectReadOnly : Object; + var rect = Object.create(Constr.prototype); + // Rectangle's properties are not writable and non-enumerable. + defineConfigurable(rect, { + x: x, + y: y, + width: width, + height: height, + top: y, + right: x + width, + bottom: height + y, + left: x, + }); + return rect; +} +/** + * Creates DOMRectInit object based on the provided dimensions and the x/y + * coordinates. Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit + * + * @param x X coordinate. + * @param y Y coordinate. + * @param width Rectangle's width. + * @param height Rectangle's height. + */ +function createRectInit(x, y, width, height) { + return { x: x, y: y, width: width, height: height }; +} + +/** + * Class that is responsible for computations of the content rectangle of + * provided DOM element and for keeping track of it's changes. + */ +var ResizeObservation = /** @class */ (function () { + /** + * Creates an instance of ResizeObservation. + * + * @param target Element to be observed. + */ + function ResizeObservation(target) { + /** + * Broadcasted width of content rectangle. + */ + this.broadcastWidth = 0; + /** + * Broadcasted height of content rectangle. + */ + this.broadcastHeight = 0; + /** + * Reference to the last observed content rectangle. + */ + this.contentRect_ = createRectInit(0, 0, 0, 0); + this.target = target; + } + /** + * Updates content rectangle and tells whether it's width or height properties + * have changed since the last broadcast. + */ + ResizeObservation.prototype.isActive = function () { + var rect = getContentRect(this.target); + this.contentRect_ = rect; + return ( + rect.width !== this.broadcastWidth || rect.height !== this.broadcastHeight + ); + }; + /** + * Updates 'broadcastWidth' and 'broadcastHeight' properties with a data + * from the corresponding properties of the last observed content rectangle. + * + * @returns Last observed content rectangle. + */ + ResizeObservation.prototype.broadcastRect = function () { + var rect = this.contentRect_; + this.broadcastWidth = rect.width; + this.broadcastHeight = rect.height; + return rect; + }; + return ResizeObservation; +})(); + +var ResizeObserverEntry = /** @class */ (function () { + /** + * Creates an instance of ResizeObserverEntry. + * + * @param target Element that is being observed. + * @param rectInit Data of the element's content rectangle. + */ + function ResizeObserverEntry(target, rectInit) { + var contentRect = createReadOnlyRect(rectInit); + // According to the specification following properties are not writable + // and are also not enumerable in the native implementation. + // + // Property accessors are not being used as they'd require to define a + // private WeakMap storage which may cause memory leaks in browsers that + // don't support this type of collections. + defineConfigurable(this, { target: target, contentRect: contentRect }); + } + return ResizeObserverEntry; +})(); + +/** + * A collection of shims that provide minimal functionality of the ES6 + * collections. + * + * These implementations are not meant to be used outside of the ResizeObserver + * modules as they cover only a limited range of use cases. + */ +/* eslint-disable require-jsdoc, valid-jsdoc */ +var MapShim = (function () { + if (typeof Map !== "undefined") { + return Map; + } + /** + * Returns index in provided array that matches the specified key. + */ + function getIndex(arr, key) { + var result = -1; + arr.some(function (entry, index) { + if (entry[0] === key) { + result = index; + return true; + } + return false; + }); + return result; + } + return /** @class */ (function () { + function class_1() { + this.__entries__ = []; + } + Object.defineProperty(class_1.prototype, "size", { + get: function () { + return this.__entries__.length; + }, + enumerable: true, + configurable: true, + }); + class_1.prototype.get = function (key) { + var _a; + var index = getIndex(this.__entries__, key); + return (_a = this.__entries__[index]) === null || _a === void 0 + ? void 0 + : _a[1]; + }; + class_1.prototype.set = function (key, value) { + var index = getIndex(this.__entries__, key); + if (~index) { + this.__entries__[index][1] = value; + } else { + this.__entries__.push([key, value]); + } + }; + class_1.prototype.delete = function (key) { + var entries = this.__entries__; + var index = getIndex(entries, key); + if (~index) { + entries.splice(index, 1); + } + }; + class_1.prototype.has = function (key) { + return !!~getIndex(this.__entries__, key); + }; + class_1.prototype.clear = function () { + this.__entries__.splice(0); + }; + class_1.prototype.forEach = function (callback, ctx) { + var e_1, _a; + if (ctx === void 0) { + ctx = null; + } + try { + for ( + var _b = __values(this.__entries__), _c = _b.next(); + !_c.done; + _c = _b.next() + ) { + var entry = _c.value; + callback.call(ctx, entry[1], entry[0]); + } + } catch (e_1_1) { + e_1 = { error: e_1_1 }; + } finally { + try { + if (_c && !_c.done && (_a = _b.return)) _a.call(_b); + } finally { + if (e_1) throw e_1.error; + } + } + }; + return class_1; + })(); +})(); + +var ResizeObserverSPI = /** @class */ (function () { + /** + * Creates a new instance of ResizeObserver. + * + * @param callback Callback function that is invoked when one of the observed + * elements changes it's content dimensions. + * @param controller Controller instance which is responsible for the updates + * of observer. + * @param callbackCtx Reference to the public ResizeObserver instance which + * will be passed to callback function. + */ + function ResizeObserverSPI(callback, controller, callbackCtx) { + /** + * Collection of resize observations that have detected changes in dimensions + * of elements. + */ + this.activeObservations_ = []; + /** + * Registry of the ResizeObservation instances. + */ + this.observations_ = new MapShim(); + if (typeof callback !== "function") { + throw new TypeError( + "The callback provided as parameter 1 is not a function." + ); + } + this.callback_ = callback; + this.controller_ = controller; + this.callbackCtx_ = callbackCtx; + } + /** + * Starts observing provided element. + * + * @param target Element to be observed. + */ + ResizeObserverSPI.prototype.observe = function (target) { + if (target === undefined) { + throw new TypeError("1 argument required, but only 0 present."); + } + // Do nothing if current environment doesn't have the Element interface. + if (typeof Element === "undefined" || !(Element instanceof Object)) { + return; + } + if (!(target instanceof getWindowOf(target).Element)) { + throw new TypeError('parameter 1 is not of type "Element".'); + } + var observations = this.observations_; + // Do nothing if element is already being observed. + if (observations.has(target)) { + return; + } + observations.set(target, new ResizeObservation(target)); + this.controller_.addObserver(this); + // Force the update of observations. + this.controller_.refresh(); + }; + /** + * Stops observing provided element. + * + * @param target Element to stop observing. + */ + ResizeObserverSPI.prototype.unobserve = function (target) { + if (target === undefined) { + throw new TypeError("1 argument required, but only 0 present."); + } + // Do nothing if current environment doesn't have the Element interface. + if (typeof Element === "undefined" || !(Element instanceof Object)) { + return; + } + if (!(target instanceof getWindowOf(target).Element)) { + throw new TypeError('parameter 1 is not of type "Element".'); + } + var observations = this.observations_; + // Do nothing if element is not being observed. + if (!observations.has(target)) { + return; + } + observations.delete(target); + if (!observations.size) { + this.controller_.removeObserver(this); + } + }; + /** + * Stops observing all elements. + */ + ResizeObserverSPI.prototype.disconnect = function () { + this.clearActive(); + this.observations_.clear(); + this.controller_.removeObserver(this); + }; + /** + * Collects observation instances the associated element of which has changed + * it's content rectangle. + */ + ResizeObserverSPI.prototype.gatherActive = function () { + var _this = this; + this.clearActive(); + this.observations_.forEach(function (observation) { + if (observation.isActive()) { + _this.activeObservations_.push(observation); + } + }); + }; + /** + * Invokes initial callback function with a list of ResizeObserverEntry + * instances collected from active resize observations. + */ + ResizeObserverSPI.prototype.broadcastActive = function () { + // Do nothing if observer doesn't have active observations. + if (!this.hasActive()) { + return; + } + var ctx = this.callbackCtx_; + // Create ResizeObserverEntry instance for every active observation. + var entries = this.activeObservations_.map(function (observation) { + return new ResizeObserverEntry( + observation.target, + observation.broadcastRect() + ); + }); + this.callback_.call(ctx, entries, ctx); + this.clearActive(); + }; + /** + * Clears the collection of active observations. + */ + ResizeObserverSPI.prototype.clearActive = function () { + this.activeObservations_.splice(0); + }; + /** + * Tells whether observer has active observations. + */ + ResizeObserverSPI.prototype.hasActive = function () { + return this.activeObservations_.length > 0; + }; + return ResizeObserverSPI; +})(); + +/** + * ResizeObserver API. Encapsulates the ResizeObserver SPI implementation + * exposing only those methods and properties that are defined in the spec. + */ +var ResizeObserver = /** @class */ (function () { + /** + * Creates a new instance of ResizeObserver. + * + * @param callback Callback that is invoked when dimensions of the observed + * elements change. + */ + function ResizeObserver(callback) { + if (!(this instanceof ResizeObserver)) { + throw new TypeError("Cannot call a class as a function."); + } + if (!arguments.length) { + throw new TypeError("1 argument required, but only 0 present."); + } + var controller = ResizeObserverController.getInstance(); + this.observer_ = new ResizeObserverSPI(callback, controller, this); + } + ResizeObserver.prototype.observe = function (target) { + this.observer_.observe(target); + }; + ResizeObserver.prototype.unobserve = function (target) { + this.observer_.unobserve(target); + }; + ResizeObserver.prototype.disconnect = function () { + this.observer_.disconnect(); + }; + return ResizeObserver; +})(); + +var index = (function () { + // Export existing implementation if available. + if (typeof global$1.ResizeObserver !== "undefined") { + return global$1.ResizeObserver; + } + return ResizeObserver; +})(); + +export default index; diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/uni-virtualizer.d.ts b/src/resources/lit-virtualizer/lib/uni-virtualizer/uni-virtualizer.d.ts new file mode 100644 index 0000000000..3523f18ccc --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/uni-virtualizer.d.ts @@ -0,0 +1,8 @@ +export { + VirtualScroller, + RangeChangeEvent, + scrollerRef, +} from "./lib/VirtualScroller.js"; +export { Layout1d, layout1d } from "./lib/layouts/Layout1d.js"; +export { Layout1dGrid } from "./lib/layouts/Layout1dGrid.js"; +//# sourceMappingURL=uni-virtualizer.d.ts.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/uni-virtualizer.d.ts.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/uni-virtualizer.d.ts.map new file mode 100644 index 0000000000..38e1246ce6 --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/uni-virtualizer.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"uni-virtualizer.d.ts","sourceRoot":"","sources":["../../src/lib/uni-virtualizer/uni-virtualizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE1F,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC"} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/uni-virtualizer.js b/src/resources/lit-virtualizer/lib/uni-virtualizer/uni-virtualizer.js new file mode 100644 index 0000000000..af65e6ff7b --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/uni-virtualizer.js @@ -0,0 +1,4 @@ +export { VirtualScroller, scrollerRef } from "./lib/VirtualScroller.js"; +export { Layout1d, layout1d } from "./lib/layouts/Layout1d.js"; +export { Layout1dGrid } from "./lib/layouts/Layout1dGrid.js"; +//# sourceMappingURL=uni-virtualizer.js.map diff --git a/src/resources/lit-virtualizer/lib/uni-virtualizer/uni-virtualizer.js.map b/src/resources/lit-virtualizer/lib/uni-virtualizer/uni-virtualizer.js.map new file mode 100644 index 0000000000..326d70cd4e --- /dev/null +++ b/src/resources/lit-virtualizer/lib/uni-virtualizer/uni-virtualizer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"uni-virtualizer.js","sourceRoot":"","sources":["../../src/lib/uni-virtualizer/uni-virtualizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAoB,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE1F,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC","sourcesContent":["export { VirtualScroller, RangeChangeEvent, scrollerRef } from './lib/VirtualScroller.js';\n\nexport { Layout1d, layout1d } from './lib/layouts/Layout1d.js';\nexport { Layout1dGrid } from './lib/layouts/Layout1dGrid.js';\n"]} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lit-virtualizer.d.ts b/src/resources/lit-virtualizer/lit-virtualizer.d.ts new file mode 100644 index 0000000000..0c0f754aa4 --- /dev/null +++ b/src/resources/lit-virtualizer/lit-virtualizer.d.ts @@ -0,0 +1,10 @@ +export { scroll } from "./lib/scroll.js"; +export { + Layout1d, + layout1d, + Layout1dGrid, + RangeChangeEvent, + scrollerRef, +} from "./lib/uni-virtualizer/uni-virtualizer.js"; +export { LitVirtualizer } from "./lib/lit-virtualizer.js"; +//# sourceMappingURL=lit-virtualizer.d.ts.map diff --git a/src/resources/lit-virtualizer/lit-virtualizer.d.ts.map b/src/resources/lit-virtualizer/lit-virtualizer.d.ts.map new file mode 100644 index 0000000000..08ad361b84 --- /dev/null +++ b/src/resources/lit-virtualizer/lit-virtualizer.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"lit-virtualizer.d.ts","sourceRoot":"","sources":["src/lit-virtualizer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAC;AAC3H,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC"} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/lit-virtualizer.js b/src/resources/lit-virtualizer/lit-virtualizer.js new file mode 100644 index 0000000000..d160157fe0 --- /dev/null +++ b/src/resources/lit-virtualizer/lit-virtualizer.js @@ -0,0 +1,10 @@ +// export { repeat } from './lib/repeat.js'; +export { scroll } from "./lib/scroll.js"; +export { + Layout1d, + layout1d, + Layout1dGrid, + scrollerRef, +} from "./lib/uni-virtualizer/uni-virtualizer.js"; +export { LitVirtualizer } from "./lib/lit-virtualizer.js"; +//# sourceMappingURL=lit-virtualizer.js.map diff --git a/src/resources/lit-virtualizer/lit-virtualizer.js.map b/src/resources/lit-virtualizer/lit-virtualizer.js.map new file mode 100644 index 0000000000..c0c3a0f6bb --- /dev/null +++ b/src/resources/lit-virtualizer/lit-virtualizer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"lit-virtualizer.js","sourceRoot":"","sources":["src/lit-virtualizer.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAoB,WAAW,EAAE,MAAM,0CAA0C,CAAC;AAC3H,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC","sourcesContent":["// export { repeat } from './lib/repeat.js';\nexport { scroll } from './lib/scroll.js';\nexport { Layout1d, layout1d, Layout1dGrid, RangeChangeEvent, scrollerRef } from './lib/uni-virtualizer/uni-virtualizer.js';\nexport { LitVirtualizer } from './lib/lit-virtualizer.js';\n"]} \ No newline at end of file diff --git a/src/resources/lit-virtualizer/package.json b/src/resources/lit-virtualizer/package.json new file mode 100644 index 0000000000..443dfc4ff0 --- /dev/null +++ b/src/resources/lit-virtualizer/package.json @@ -0,0 +1,55 @@ +{ + "name": "@lit-labs/virtualizer", + "version": "0.7.0", + "description": "Virtual scrolling for Lit", + "license": "BSD-3-Clause", + "main": "lit-virtualizer.js", + "files": [ + "/lit-virtualizer.js", + "/lit-virtualizer.d.ts", + "/lit-virtualizer.d.ts.map", + "/lib/" + ], + "module": "lit-virtualizer.js", + "scripts": { + "bench": "tach --root=../.. --browser=chrome-headless test/benchmarks/${BENCH:-basic}.html --measure=fcp", + "bench:debug": "tach --root=../.. test/benchmarks/${BENCH:-basic}.html --measure=fcp", + "bench:scroll": "tach --force-clean-npm-install --config=test/benchmarks/scrollingBenchmarks.json", + "build": "tsc & copyfiles -u 2 src/lib/uni-virtualizer/lib/polyfills/resize-observer-polyfill/ResizeObserver.js lib", + "checksize": "rollup -c; rm lit-virtualizer.bundled.js lit-virtualizer-with-polyfills.bundled.js", + "clean": "rm -r node_modules/", + "lint": "tslint --project ./", + "prepare": "npm run build", + "test": "karma start karma.conf.js", + "test:debug": "karma start karma.conf.js --single-run=false --debug", + "test:screenshot": "cd test/screenshot && rollup -c && mocha screenshot.js", + "generate-screenshots": "cd test/screenshot && rollup -c && mocha screenshot.js --generate-screenshots" + }, + "author": "Google LLC", + "devDependencies": { + "chai": "^4.2.0", + "copyfiles": "^2.4.1", + "http-server": "^0.11.1", + "karma": "^4.1.0", + "karma-chai": "^0.1.0", + "karma-chrome-launcher": "^2.2.0", + "karma-mocha": "^1.3.0", + "karma-mocha-reporter": "^2.2.5", + "karma-rollup-preprocessor": "^7.0.0", + "mocha": "^6.1.4", + "pixelmatch": "^4.0.2", + "pngjs": "^3.4.0", + "puppeteer": "^1.17.0", + "rollup": "^1.11.2", + "rollup-plugin-filesize": "^6.1.1", + "rollup-plugin-node-resolve": "^4.2.3", + "rollup-plugin-terser": "^5.0.0", + "tachometer": "^0.4.7", + "typescript": "^4.1.3" + }, + "dependencies": { + "event-target-shim": "^5.0.1", + "lit": "^2.0.0-rc.1", + "tslib": "^1.10.0" + } +} diff --git a/translations/frontend/ko.json b/translations/frontend/ko.json index 16898e6ed1..061c61763b 100644 --- a/translations/frontend/ko.json +++ b/translations/frontend/ko.json @@ -931,6 +931,9 @@ "config_entry_system_options": { "enable_new_entities_description": "비활성화한 경우 새로 발견된 {integration} 구성요소는 Home Assistant에 자동으로 추가되지 않습니다.", "enable_new_entities_label": "새로 추가된 구성요소를 활성화합니다.", + "enable_polling_description": "Home Assistant가 업데이트를 위해 {integration} 구성요소를 자동으로 폴링해야하는 경우.", + "enable_polling_label": "업데이트를 위해 폴링을 활성화합니다.", + "restart_home_assistant": "변경 사항을 적용하려면 Home Assistant를 다시 시작해야합니다.", "title": "{integration} 시스템 옵션", "update": "업데이트" }, @@ -2217,6 +2220,7 @@ }, "disabled_cause": "{cause}에 의해 비활성화되었습니다" }, + "disabled_polling": "데이터 업데이트를 위한 자동 폴링 비활성화", "documentation": "관련 문서", "enable_restart_confirm": "이 통합 구성요소를 활성화하려면 Home Assistant를 다시 시작해주세요", "entities": "{count} {count, plural,\none{개의 구성요소}\nother{개의 구성요소}\n}",