@operato/layout 10.29.39 → 10.29.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/src/actions/entity360-name.js +1 -1
- package/dist/src/actions/entity360-name.js.map +1 -1
- package/dist/src/actions/entity360-registry.d.ts +4 -2
- package/dist/src/actions/entity360-registry.js +6 -4
- package/dist/src/actions/entity360-registry.js.map +1 -1
- package/dist/src/actions/entity360.d.ts +5 -2
- package/dist/src/actions/entity360.js +6 -3
- package/dist/src/actions/entity360.js.map +1 -1
- package/dist/src/actions/layout.d.ts +2 -0
- package/dist/src/actions/layout.js +15 -2
- package/dist/src/actions/layout.js.map +1 -1
- package/dist/src/components/ox-url-tabs.js +2 -2
- package/dist/src/components/ox-url-tabs.js.map +1 -1
- package/dist/test/overlay-close-after-write.test.d.ts +1 -0
- package/dist/test/overlay-close-after-write.test.js +29 -0
- package/dist/test/overlay-close-after-write.test.js.map +1 -0
- package/dist/test/popup-navigation.test.d.ts +1 -0
- package/dist/test/popup-navigation.test.js +60 -0
- package/dist/test/popup-navigation.test.js.map +1 -0
- package/dist/test/popup-result.test.js +4 -2
- package/dist/test/popup-result.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/test/overlay-close-after-write.test.ts +31 -0
- package/test/popup-navigation.test.ts +67 -0
- package/test/popup-result.test.ts +5 -2
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +0 -1136
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -210
- package/coverage/lcov.info +0 -62848
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"popup-navigation.test.js","sourceRoot":"","sources":["../../test/popup-navigation.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, fixture, waitUntil } from '@open-wc/testing'\nimport { sendMouse } from '@web/test-runner-commands'\nimport { html } from 'lit'\nimport { addressController, writeAddress } from '@operato/utils/address.js'\nimport { store } from '@operato/shell'\nimport { closeOverlay, openPopup, UPDATE_VIEWPART } from '../src/index.js'\n\n/**\n * Before 2026-10-17 a button in a popup that navigated went where it said and the popup closed; a hidden\n * overlay held nothing back. These pin that behaviour.\n */\n\nconst overlays = () => document.querySelector('ox-header-bar')!.shadowRoot!.querySelectorAll('ox-floating-overlay')\nconst click = async (element: Element) => {\n const bounds = element.getBoundingClientRect()\n await sendMouse({\n type: 'click',\n position: [Math.round(bounds.x + bounds.width / 2), Math.round(bounds.y + bounds.height / 2)]\n })\n}\nconst shown = async (element: Element) => {\n await waitUntil(() => element.isConnected && element.getBoundingClientRect().width > 0, 'popup not shown')\n await addressController().whenSettled()\n}\n\ndescribe('requests from inside a popup', () => {\n beforeEach(async () => {\n await fixture(html`<ox-header-bar></ox-header-bar>`)\n })\n\n afterEach(async () => {\n for (const overlay of Array.from(overlays()).reverse()) closeOverlay((overlay as any).name)\n await addressController().whenSettled()\n await waitUntil(() => overlays().length === 0, 'a popup stayed open after the test')\n })\n\n it('a button in a popup that navigates closes the popup and replaces its entry', async () => {\n expect(await writeAddress('?under=popup')).to.equal(true)\n const under = location.href\n const button = document.createElement('button')\n button.textContent = 'open elsewhere'\n let request: Promise<boolean> | undefined\n button.addEventListener('click', () => (request = writeAddress('?destination=1', { source: button, intent: 'navigation' })))\n openPopup(html`${button}`, { backdrop: true })\n await shown(button)\n\n await click(button)\n expect(await request).to.equal(true)\n expect(location.search).to.equal('?destination=1')\n await waitUntil(() => overlays().length === 0, 'popup left open')\n\n history.back()\n await waitUntil(() => location.href === under, \"back did not arrive\")\n expect(location.href).to.equal(under)\n })\n\n it('a popup hidden through the store is closed: it no longer holds requests back', async () => {\n const content = document.createElement('div')\n content.textContent = 'printing'\n const handle = openPopup(html`${content}`, { backdrop: true })\n await shown(content)\n\n store.dispatch({ type: UPDATE_VIEWPART, name: handle.name, override: { show: false } })\n await addressController().whenSettled()\n expect(await writeAddress('?after=hidden')).to.equal(true)\n })\n})\n"]}
|
|
@@ -2,6 +2,7 @@ import { expect, fixture } from '@open-wc/testing';
|
|
|
2
2
|
import { html } from 'lit';
|
|
3
3
|
import { store } from '@operato/shell';
|
|
4
4
|
import { closePopup } from '@operato/popup';
|
|
5
|
+
import { writeAddress } from '@operato/utils/address.js';
|
|
5
6
|
import '../src/index.js';
|
|
6
7
|
import { openPopup } from '../src/index.js';
|
|
7
8
|
/**
|
|
@@ -44,7 +45,8 @@ let markerSequence = 0;
|
|
|
44
45
|
async function open(options = {}) {
|
|
45
46
|
/* Closing must go back exactly one step - to this marker, not past it. */
|
|
46
47
|
const marker = `before-popup-${markerSequence++}`;
|
|
47
|
-
|
|
48
|
+
/* Through the address layer, as every writer does: an entry written around it has no place it can trust. */
|
|
49
|
+
await writeAddress(location.href, { state: { marker } });
|
|
48
50
|
const handle = openPopup(html `<div class="content">content</div>`, options);
|
|
49
51
|
let onclosedCalls = 0;
|
|
50
52
|
handle.onclosed = () => onclosedCalls++;
|
|
@@ -65,7 +67,7 @@ describe('openPopup result - layout implementation', () => {
|
|
|
65
67
|
* `history.length`-independent checks below: the next popup would not appear.
|
|
66
68
|
*/
|
|
67
69
|
for (let i = 0; i < 5; i++)
|
|
68
|
-
|
|
70
|
+
await writeAddress(location.href, { state: {} });
|
|
69
71
|
await fixture(html `<ox-header-bar></ox-header-bar>`);
|
|
70
72
|
});
|
|
71
73
|
it('handle.close(value) settles with that value', async () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"popup-result.test.js","sourceRoot":"","sources":["../../test/popup-result.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect, fixture } from '@open-wc/testing'\nimport { html } from 'lit'\n\nimport { store } from '@operato/shell'\nimport { closePopup } from '@operato/popup'\nimport type { OxFloatingOverlay } from '@operato/popup/ox-floating-overlay.js'\n\nimport '../src/index.js'\nimport { openPopup } from '../src/index.js'\n\n/**\n * The popup result settles exactly once, with the right value, whichever way the popup closes -\n * for the layout implementation, the one applications run.\n *\n * Here every close goes through history: the overlay pushes a state when it opens, and closing is\n * history.back(), which hides the temporary viewpart, which removes the overlay, which announces\n * `overlay-closed`. The same table runs for the default implementation in @operato/popup/test.\n */\n\nconst TIMEOUT = 'TIMEOUT'\n\nfunction within<T>(promise: Promise<T>, ms = 3000): Promise<T | typeof TIMEOUT> {\n return Promise.race([promise, new Promise<typeof TIMEOUT>(resolve => setTimeout(() => resolve(TIMEOUT), ms))])\n}\n\nconst settleTurn = (ms = 100) => new Promise(resolve => setTimeout(resolve, ms))\n\n/*\n * Stand in for the application shell's router: it calls the registered navigation callbacks on\n * popstate. The layout's overlay stack lives in one of those callbacks.\n */\nwindow.addEventListener('popstate', e => {\n const callbacks = ((store.getState() as any).route?.callbacks || []) as Array<(l: Location, e: Event) => void>\n callbacks.forEach(callback => callback(window.location, e))\n})\n\nasync function waitForOverlay(name: string): Promise<OxFloatingOverlay> {\n for (let i = 0; i < 50; i++) {\n const bar = document.querySelector('ox-header-bar') as (HTMLElement & { renderRoot: ParentNode }) | null\n const overlays = Array.from(bar?.renderRoot.querySelectorAll('ox-floating-overlay') ?? []) as OxFloatingOverlay[]\n const overlay = overlays.find(o => o.name === name)\n if (overlay) {\n await overlay.updateComplete\n return overlay\n }\n await settleTurn(20)\n }\n throw new Error(`overlay ${name} did not appear`)\n}\n\nlet markerSequence = 0\n\nasync function open(options = {}) {\n /* Closing must go back exactly one step - to this marker, not past it. */\n const marker = `before-popup-${markerSequence++}`\n history.pushState({ marker }, '', location.href)\n\n const handle = openPopup<string>(html`<div class=\"content\">content</div>`, options)\n let onclosedCalls = 0\n handle.onclosed = () => onclosedCalls++\n\n const overlay = await waitForOverlay(handle.name)\n\n return {\n handle,\n overlay,\n content: overlay.querySelector('.content') as HTMLElement,\n onclosedCalls: () => onclosedCalls,\n backToMarker: () => history.state?.marker === marker && !history.state?.overlay\n }\n}\n\ndescribe('openPopup result - layout implementation', () => {\n beforeEach(async () => {\n /*\n * A floor of history entries, so a close that goes back one step too far lands on this page\n * instead of leaving the test runner. Such an extra step still fails the test through\n * `history.length`-independent checks below: the next popup would not appear.\n */\n for (let i = 0; i < 5; i++) history.pushState({}, '', location.href)\n await fixture(html`<ox-header-bar></ox-header-bar>`)\n })\n\n it('handle.close(value) settles with that value', async () => {\n const { handle, onclosedCalls, backToMarker } = await open()\n\n handle.close('saved')\n\n expect(await within(handle.result)).to.equal('saved')\n await settleTurn()\n expect(handle.closed).to.equal(true)\n expect(onclosedCalls()).to.equal(1)\n expect(backToMarker(), 'history went back exactly one step').to.equal(true)\n })\n\n it('closePopup(element, value) from the content settles with that value', async () => {\n const { handle, content, onclosedCalls, backToMarker } = await open()\n\n closePopup(content, 'picked')\n\n expect(await within(handle.result)).to.equal('picked')\n await settleTurn()\n expect(handle.closed).to.equal(true)\n expect(onclosedCalls()).to.equal(1)\n expect(backToMarker(), 'history went back exactly one step').to.equal(true)\n })\n\n it('history back settles undefined', async () => {\n const { handle, onclosedCalls, backToMarker } = await open()\n\n history.back()\n\n expect(await within(handle.result)).to.equal(undefined)\n await settleTurn()\n expect(handle.closed).to.equal(true)\n expect(onclosedCalls()).to.equal(1)\n expect(backToMarker(), 'history went back exactly one step').to.equal(true)\n })\n\n it('ESC settles undefined', async () => {\n const { handle, onclosedCalls, backToMarker } = await open({ escapable: true })\n\n document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }))\n\n expect(await within(handle.result)).to.equal(undefined)\n await settleTurn()\n expect(onclosedCalls()).to.equal(1)\n expect(backToMarker(), 'history went back exactly one step').to.equal(true)\n })\n\n it('backdrop click settles undefined', async () => {\n const { handle, overlay, onclosedCalls, backToMarker } = await open({ escapable: true })\n\n const backdrop = overlay.renderRoot.querySelector('#backdrop') as HTMLElement\n expect(backdrop, 'backdrop element').to.exist\n backdrop.click()\n\n expect(await within(handle.result)).to.equal(undefined)\n await settleTurn()\n expect(onclosedCalls()).to.equal(1)\n expect(backToMarker(), 'history went back exactly one step').to.equal(true)\n })\n\n it('the X button settles undefined', async () => {\n const { handle, overlay, onclosedCalls, backToMarker } = await open({ title: 'x' })\n\n const closer = overlay.renderRoot.querySelector('[closable][close]') as HTMLElement\n expect(closer, 'close button').to.exist\n closer.click()\n\n expect(await within(handle.result)).to.equal(undefined)\n await settleTurn()\n expect(onclosedCalls()).to.equal(1)\n expect(backToMarker(), 'history went back exactly one step').to.equal(true)\n })\n\n it('the first close request wins: closePopup then handle.close', async () => {\n const { handle, content, onclosedCalls, backToMarker } = await open()\n\n closePopup(content, 'first')\n handle.close('second')\n\n expect(await within(handle.result)).to.equal('first')\n await settleTurn()\n expect(onclosedCalls()).to.equal(1)\n expect(backToMarker(), 'history went back exactly one step').to.equal(true)\n })\n\n it('a close request that closed nothing leaves no value behind', async () => {\n /*\n * A lower popup cannot close while another sits on top of it. Its close('ignored') does nothing -\n * and must not come back later as the result when the person dismisses that popup.\n */\n const lower = await open()\n const upper = await open()\n\n lower.handle.close('ignored')\n await settleTurn()\n expect(lower.handle.closed, 'the lower popup stays open').to.equal(false)\n\n upper.handle.close()\n expect(await within(upper.handle.result)).to.equal(undefined)\n await settleTurn()\n\n const closer = lower.overlay.renderRoot.querySelector('[closable][close]') as HTMLElement\n closer.click()\n\n expect(await within(lower.handle.result)).to.equal(undefined)\n })\n\n it('the first close request wins: handle.close then closePopup', async () => {\n const { handle, content, onclosedCalls, backToMarker } = await open()\n\n handle.close('first')\n closePopup(content, 'second')\n\n expect(await within(handle.result)).to.equal('first')\n await settleTurn()\n expect(onclosedCalls()).to.equal(1)\n expect(backToMarker(), 'history went back exactly one step').to.equal(true)\n })\n})\n"]}
|
|
1
|
+
{"version":3,"file":"popup-result.test.js","sourceRoot":"","sources":["../../test/popup-result.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAE1B,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAG3C,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAExD,OAAO,iBAAiB,CAAA;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C;;;;;;;GAOG;AAEH,MAAM,OAAO,GAAG,SAAS,CAAA;AAEzB,SAAS,MAAM,CAAI,OAAmB,EAAE,EAAE,GAAG,IAAI;IAC/C,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,IAAI,OAAO,CAAiB,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;AAChH,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,EAAE,GAAG,GAAG,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAA;AAEhF;;;GAGG;AACH,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE;;IACtC,MAAM,SAAS,GAAG,CAAC,CAAA,MAAC,KAAK,CAAC,QAAQ,EAAU,CAAC,KAAK,0CAAE,SAAS,KAAI,EAAE,CAA2C,CAAA;IAC9G,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAA;AAC7D,CAAC,CAAC,CAAA;AAEF,KAAK,UAAU,cAAc,CAAC,IAAY;;IACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,eAAe,CAAsD,CAAA;QACxG,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,MAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,UAAU,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,mCAAI,EAAE,CAAwB,CAAA;QACjH,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;QACnD,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,OAAO,CAAC,cAAc,CAAA;YAC5B,OAAO,OAAO,CAAA;QAChB,CAAC;QACD,MAAM,UAAU,CAAC,EAAE,CAAC,CAAA;IACtB,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,iBAAiB,CAAC,CAAA;AACnD,CAAC;AAED,IAAI,cAAc,GAAG,CAAC,CAAA;AAEtB,KAAK,UAAU,IAAI,CAAC,OAAO,GAAG,EAAE;IAC9B,0EAA0E;IAC1E,MAAM,MAAM,GAAG,gBAAgB,cAAc,EAAE,EAAE,CAAA;IACjD,4GAA4G;IAC5G,MAAM,YAAY,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,CAAA;IAExD,MAAM,MAAM,GAAG,SAAS,CAAS,IAAI,CAAA,oCAAoC,EAAE,OAAO,CAAC,CAAA;IACnF,IAAI,aAAa,GAAG,CAAC,CAAA;IACrB,MAAM,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC,aAAa,EAAE,CAAA;IAEvC,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAEjD,OAAO;QACL,MAAM;QACN,OAAO;QACP,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,UAAU,CAAgB;QACzD,aAAa,EAAE,GAAG,EAAE,CAAC,aAAa;QAClC,YAAY,EAAE,GAAG,EAAE,eAAC,OAAA,CAAA,MAAA,OAAO,CAAC,KAAK,0CAAE,MAAM,MAAK,MAAM,IAAI,CAAC,CAAA,MAAA,OAAO,CAAC,KAAK,0CAAE,OAAO,CAAA,CAAA,EAAA;KAChF,CAAA;AACH,CAAC;AAED,QAAQ,CAAC,0CAA0C,EAAE,GAAG,EAAE;IACxD,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB;;;;WAIG;QACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAAE,MAAM,YAAY,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAA;QAC5E,MAAM,OAAO,CAAC,IAAI,CAAA,iCAAiC,CAAC,CAAA;IACtD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,MAAM,IAAI,EAAE,CAAA;QAE5D,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAErB,MAAM,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACrD,MAAM,UAAU,EAAE,CAAA;QAClB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACpC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACnC,MAAM,CAAC,YAAY,EAAE,EAAE,oCAAoC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC7E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,qEAAqE,EAAE,KAAK,IAAI,EAAE;QACnF,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,MAAM,IAAI,EAAE,CAAA;QAErE,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;QAE7B,MAAM,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QACtD,MAAM,UAAU,EAAE,CAAA;QAClB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACpC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACnC,MAAM,CAAC,YAAY,EAAE,EAAE,oCAAoC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC7E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,MAAM,IAAI,EAAE,CAAA;QAE5D,OAAO,CAAC,IAAI,EAAE,CAAA;QAEd,MAAM,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QACvD,MAAM,UAAU,EAAE,CAAA;QAClB,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACpC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACnC,MAAM,CAAC,YAAY,EAAE,EAAE,oCAAoC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC7E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;QACrC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,MAAM,IAAI,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAE/E,QAAQ,CAAC,aAAa,CAAC,IAAI,aAAa,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QAEtF,MAAM,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QACvD,MAAM,UAAU,EAAE,CAAA;QAClB,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACnC,MAAM,CAAC,YAAY,EAAE,EAAE,oCAAoC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC7E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,MAAM,IAAI,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAExF,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,WAAW,CAAgB,CAAA;QAC7E,MAAM,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAA;QAC7C,QAAQ,CAAC,KAAK,EAAE,CAAA;QAEhB,MAAM,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QACvD,MAAM,UAAU,EAAE,CAAA;QAClB,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACnC,MAAM,CAAC,YAAY,EAAE,EAAE,oCAAoC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC7E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,MAAM,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;QAEnF,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,mBAAmB,CAAgB,CAAA;QACnF,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,KAAK,CAAA;QACvC,MAAM,CAAC,KAAK,EAAE,CAAA;QAEd,MAAM,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QACvD,MAAM,UAAU,EAAE,CAAA;QAClB,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACnC,MAAM,CAAC,YAAY,EAAE,EAAE,oCAAoC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC7E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;QAC1E,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,MAAM,IAAI,EAAE,CAAA;QAErE,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAC5B,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QAEtB,MAAM,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACrD,MAAM,UAAU,EAAE,CAAA;QAClB,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACnC,MAAM,CAAC,YAAY,EAAE,EAAE,oCAAoC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC7E,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;QAC1E;;;WAGG;QACH,MAAM,KAAK,GAAG,MAAM,IAAI,EAAE,CAAA;QAC1B,MAAM,KAAK,GAAG,MAAM,IAAI,EAAE,CAAA;QAE1B,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QAC7B,MAAM,UAAU,EAAE,CAAA;QAClB,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,4BAA4B,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAEzE,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAA;QACpB,MAAM,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QAC7D,MAAM,UAAU,EAAE,CAAA;QAElB,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,mBAAmB,CAAgB,CAAA;QACzF,MAAM,CAAC,KAAK,EAAE,CAAA;QAEd,MAAM,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IAC/D,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;QAC1E,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,MAAM,IAAI,EAAE,CAAA;QAErE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACrB,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;QAE7B,MAAM,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACrD,MAAM,UAAU,EAAE,CAAA;QAClB,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACnC,MAAM,CAAC,YAAY,EAAE,EAAE,oCAAoC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC7E,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA","sourcesContent":["import { expect, fixture } from '@open-wc/testing'\nimport { html } from 'lit'\n\nimport { store } from '@operato/shell'\nimport { closePopup } from '@operato/popup'\nimport type { OxFloatingOverlay } from '@operato/popup/ox-floating-overlay.js'\n\nimport { writeAddress } from '@operato/utils/address.js'\n\nimport '../src/index.js'\nimport { openPopup } from '../src/index.js'\n\n/**\n * The popup result settles exactly once, with the right value, whichever way the popup closes -\n * for the layout implementation, the one applications run.\n *\n * Here every close goes through history: the overlay pushes a state when it opens, and closing is\n * history.back(), which hides the temporary viewpart, which removes the overlay, which announces\n * `overlay-closed`. The same table runs for the default implementation in @operato/popup/test.\n */\n\nconst TIMEOUT = 'TIMEOUT'\n\nfunction within<T>(promise: Promise<T>, ms = 3000): Promise<T | typeof TIMEOUT> {\n return Promise.race([promise, new Promise<typeof TIMEOUT>(resolve => setTimeout(() => resolve(TIMEOUT), ms))])\n}\n\nconst settleTurn = (ms = 100) => new Promise(resolve => setTimeout(resolve, ms))\n\n/*\n * Stand in for the application shell's router: it calls the registered navigation callbacks on\n * popstate. The layout's overlay stack lives in one of those callbacks.\n */\nwindow.addEventListener('popstate', e => {\n const callbacks = ((store.getState() as any).route?.callbacks || []) as Array<(l: Location, e: Event) => void>\n callbacks.forEach(callback => callback(window.location, e))\n})\n\nasync function waitForOverlay(name: string): Promise<OxFloatingOverlay> {\n for (let i = 0; i < 50; i++) {\n const bar = document.querySelector('ox-header-bar') as (HTMLElement & { renderRoot: ParentNode }) | null\n const overlays = Array.from(bar?.renderRoot.querySelectorAll('ox-floating-overlay') ?? []) as OxFloatingOverlay[]\n const overlay = overlays.find(o => o.name === name)\n if (overlay) {\n await overlay.updateComplete\n return overlay\n }\n await settleTurn(20)\n }\n throw new Error(`overlay ${name} did not appear`)\n}\n\nlet markerSequence = 0\n\nasync function open(options = {}) {\n /* Closing must go back exactly one step - to this marker, not past it. */\n const marker = `before-popup-${markerSequence++}`\n /* Through the address layer, as every writer does: an entry written around it has no place it can trust. */\n await writeAddress(location.href, { state: { marker } })\n\n const handle = openPopup<string>(html`<div class=\"content\">content</div>`, options)\n let onclosedCalls = 0\n handle.onclosed = () => onclosedCalls++\n\n const overlay = await waitForOverlay(handle.name)\n\n return {\n handle,\n overlay,\n content: overlay.querySelector('.content') as HTMLElement,\n onclosedCalls: () => onclosedCalls,\n backToMarker: () => history.state?.marker === marker && !history.state?.overlay\n }\n}\n\ndescribe('openPopup result - layout implementation', () => {\n beforeEach(async () => {\n /*\n * A floor of history entries, so a close that goes back one step too far lands on this page\n * instead of leaving the test runner. Such an extra step still fails the test through\n * `history.length`-independent checks below: the next popup would not appear.\n */\n for (let i = 0; i < 5; i++) await writeAddress(location.href, { state: {} })\n await fixture(html`<ox-header-bar></ox-header-bar>`)\n })\n\n it('handle.close(value) settles with that value', async () => {\n const { handle, onclosedCalls, backToMarker } = await open()\n\n handle.close('saved')\n\n expect(await within(handle.result)).to.equal('saved')\n await settleTurn()\n expect(handle.closed).to.equal(true)\n expect(onclosedCalls()).to.equal(1)\n expect(backToMarker(), 'history went back exactly one step').to.equal(true)\n })\n\n it('closePopup(element, value) from the content settles with that value', async () => {\n const { handle, content, onclosedCalls, backToMarker } = await open()\n\n closePopup(content, 'picked')\n\n expect(await within(handle.result)).to.equal('picked')\n await settleTurn()\n expect(handle.closed).to.equal(true)\n expect(onclosedCalls()).to.equal(1)\n expect(backToMarker(), 'history went back exactly one step').to.equal(true)\n })\n\n it('history back settles undefined', async () => {\n const { handle, onclosedCalls, backToMarker } = await open()\n\n history.back()\n\n expect(await within(handle.result)).to.equal(undefined)\n await settleTurn()\n expect(handle.closed).to.equal(true)\n expect(onclosedCalls()).to.equal(1)\n expect(backToMarker(), 'history went back exactly one step').to.equal(true)\n })\n\n it('ESC settles undefined', async () => {\n const { handle, onclosedCalls, backToMarker } = await open({ escapable: true })\n\n document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true }))\n\n expect(await within(handle.result)).to.equal(undefined)\n await settleTurn()\n expect(onclosedCalls()).to.equal(1)\n expect(backToMarker(), 'history went back exactly one step').to.equal(true)\n })\n\n it('backdrop click settles undefined', async () => {\n const { handle, overlay, onclosedCalls, backToMarker } = await open({ escapable: true })\n\n const backdrop = overlay.renderRoot.querySelector('#backdrop') as HTMLElement\n expect(backdrop, 'backdrop element').to.exist\n backdrop.click()\n\n expect(await within(handle.result)).to.equal(undefined)\n await settleTurn()\n expect(onclosedCalls()).to.equal(1)\n expect(backToMarker(), 'history went back exactly one step').to.equal(true)\n })\n\n it('the X button settles undefined', async () => {\n const { handle, overlay, onclosedCalls, backToMarker } = await open({ title: 'x' })\n\n const closer = overlay.renderRoot.querySelector('[closable][close]') as HTMLElement\n expect(closer, 'close button').to.exist\n closer.click()\n\n expect(await within(handle.result)).to.equal(undefined)\n await settleTurn()\n expect(onclosedCalls()).to.equal(1)\n expect(backToMarker(), 'history went back exactly one step').to.equal(true)\n })\n\n it('the first close request wins: closePopup then handle.close', async () => {\n const { handle, content, onclosedCalls, backToMarker } = await open()\n\n closePopup(content, 'first')\n handle.close('second')\n\n expect(await within(handle.result)).to.equal('first')\n await settleTurn()\n expect(onclosedCalls()).to.equal(1)\n expect(backToMarker(), 'history went back exactly one step').to.equal(true)\n })\n\n it('a close request that closed nothing leaves no value behind', async () => {\n /*\n * A lower popup cannot close while another sits on top of it. Its close('ignored') does nothing -\n * and must not come back later as the result when the person dismisses that popup.\n */\n const lower = await open()\n const upper = await open()\n\n lower.handle.close('ignored')\n await settleTurn()\n expect(lower.handle.closed, 'the lower popup stays open').to.equal(false)\n\n upper.handle.close()\n expect(await within(upper.handle.result)).to.equal(undefined)\n await settleTurn()\n\n const closer = lower.overlay.renderRoot.querySelector('[closable][close]') as HTMLElement\n closer.click()\n\n expect(await within(lower.handle.result)).to.equal(undefined)\n })\n\n it('the first close request wins: handle.close then closePopup', async () => {\n const { handle, content, onclosedCalls, backToMarker } = await open()\n\n handle.close('first')\n closePopup(content, 'second')\n\n expect(await within(handle.result)).to.equal('first')\n await settleTurn()\n expect(onclosedCalls()).to.equal(1)\n expect(backToMarker(), 'history went back exactly one step').to.equal(true)\n })\n})\n"]}
|