@internetarchive/ia-item-navigator 0.0.0-a9 → 0.0.2-a2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +29 -19
  2. package/demo/app-root.ts +37 -31
  3. package/demo/index.html +1 -0
  4. package/dist/demo/app-root.d.ts +11 -15
  5. package/dist/demo/app-root.js +26 -26
  6. package/dist/demo/app-root.js.map +1 -1
  7. package/dist/src/interfaces/custom-theater-interface.d.ts +20 -0
  8. package/dist/src/interfaces/custom-theater-interface.js +2 -0
  9. package/dist/src/interfaces/custom-theater-interface.js.map +1 -0
  10. package/dist/src/interfaces/event-interfaces.d.ts +11 -11
  11. package/dist/src/interfaces/event-interfaces.js.map +1 -1
  12. package/dist/src/interfaces/menu-interfaces.d.ts +6 -7
  13. package/dist/src/interfaces/menu-interfaces.js.map +1 -1
  14. package/dist/src/interfaces/nav-controller-interface.d.ts +11 -6
  15. package/dist/src/interfaces/nav-controller-interface.js.map +1 -1
  16. package/dist/src/item-inspector/item-inspector.d.ts +0 -47
  17. package/dist/src/item-inspector/item-inspector.js +253 -271
  18. package/dist/src/item-inspector/item-inspector.js.map +1 -1
  19. package/dist/src/item-navigator.d.ts +41 -28
  20. package/dist/src/item-navigator.js +96 -113
  21. package/dist/src/item-navigator.js.map +1 -1
  22. package/dist/src/no-theater-available.d.ts +9 -0
  23. package/dist/src/no-theater-available.js +79 -0
  24. package/dist/src/no-theater-available.js.map +1 -0
  25. package/dist/test/book-nav-stub.d.ts +22 -0
  26. package/dist/test/book-nav-stub.js +49 -0
  27. package/dist/test/book-nav-stub.js.map +1 -0
  28. package/dist/test/ia-item-navigator.test.d.ts +1 -0
  29. package/dist/test/ia-item-navigator.test.js +279 -131
  30. package/dist/test/ia-item-navigator.test.js.map +1 -1
  31. package/dist/test/ia-stub.d.ts +22 -0
  32. package/dist/test/ia-stub.js +34 -3
  33. package/dist/test/ia-stub.js.map +1 -1
  34. package/dist/test/no-theater-available.test.d.ts +1 -0
  35. package/dist/test/no-theater-available.test.js +27 -0
  36. package/dist/test/no-theater-available.test.js.map +1 -0
  37. package/package.json +4 -3
  38. package/src/interfaces/custom-theater-interface.ts +28 -0
  39. package/src/interfaces/event-interfaces.ts +15 -11
  40. package/src/interfaces/menu-interfaces.ts +9 -10
  41. package/src/item-navigator.ts +133 -144
  42. package/src/no-theater-available.ts +85 -0
  43. package/test/book-nav-stub.ts +47 -0
  44. package/test/ia-item-navigator.test.ts +365 -156
  45. package/test/ia-stub.ts +78 -2
  46. package/test/no-theater-available.test.ts +32 -0
  47. package/demo/demo-book-manifest.json +0 -1163
  48. package/src/interfaces/nav-controller-interface.ts +0 -18
  49. package/src/item-inspector/files-by-type/files-by-type-provider.ts +0 -43
  50. package/src/item-inspector/files-by-type/ia-files-by-type.ts +0 -100
  51. package/src/item-inspector/item-inspector.ts +0 -296
  52. package/src/item-inspector/share-provider.ts +0 -51
  53. package/src/item-inspector/visual-mod-provider.ts +0 -65
  54. package/src/item-navigator-js.js +0 -372
@@ -0,0 +1,79 @@
1
+ import { __decorate } from "tslib";
2
+ import { LitElement, customElement, property, html, css, } from 'lit-element';
3
+ let IANoTheaterAvailable = class IANoTheaterAvailable extends LitElement {
4
+ constructor() {
5
+ super(...arguments);
6
+ this.identifier = '';
7
+ }
8
+ emitLoaded() {
9
+ this.dispatchEvent(new CustomEvent('loadingStateUpdated', {
10
+ detail: { loaded: true },
11
+ }));
12
+ }
13
+ updated(changed) {
14
+ if (changed.has('identifier')) {
15
+ this.emitLoaded();
16
+ }
17
+ }
18
+ get downloadUrl() {
19
+ return `/download/${this.identifier}`;
20
+ }
21
+ render() {
22
+ return html `
23
+ <section>
24
+ <h2>THERE IS NO PREVIEW AVAILABLE FOR THIS ITEM</h2>
25
+ <p>
26
+ This item does not appear to have any files that can be experienced on
27
+ Archive.org. <br />
28
+ Please download files in this item to interact with them on your
29
+ computer.
30
+ </p>
31
+ <a href=${this.downloadUrl}>Show all files</a>
32
+ </section>
33
+ `;
34
+ }
35
+ static get styles() {
36
+ return css `
37
+ :host {
38
+ color: var(--primaryTextColor, #fff);
39
+ text-align: center;
40
+ }
41
+ section {
42
+ margin: 10% auto 0;
43
+ padding: 0 5%;
44
+ }
45
+ p {
46
+ font-size: 1.4rem;
47
+ }
48
+ a {
49
+ color: var(--primaryTextColor, #fff);
50
+ background-color: rgb(25, 72, 128);
51
+ min-height: 35px;
52
+ outline: none;
53
+ cursor: pointer;
54
+ line-height: normal;
55
+ border-radius: 0.4rem;
56
+ text-align: center;
57
+ vertical-align: middle;
58
+ font-size: 1.4rem;
59
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
60
+ display: inline-block;
61
+ padding: 0.85rem 1.2rem;
62
+ border: 1px solid rgb(197, 209, 223);
63
+ white-space: nowrap;
64
+ appearance: auto;
65
+ box-sizing: border-box;
66
+ user-select: none;
67
+ text-decoration: none;
68
+ }
69
+ `;
70
+ }
71
+ };
72
+ __decorate([
73
+ property({ type: String })
74
+ ], IANoTheaterAvailable.prototype, "identifier", void 0);
75
+ IANoTheaterAvailable = __decorate([
76
+ customElement('ia-no-theater-available')
77
+ ], IANoTheaterAvailable);
78
+ export { IANoTheaterAvailable };
79
+ //# sourceMappingURL=no-theater-available.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-theater-available.js","sourceRoot":"","sources":["../../src/no-theater-available.ts"],"names":[],"mappings":";AAAA,OAAO,EACL,UAAU,EACV,aAAa,EACb,QAAQ,EACR,IAAI,EAIJ,GAAG,GACJ,MAAM,aAAa,CAAC;AAGrB,IAAa,oBAAoB,GAAjC,MAAa,oBAAqB,SAAQ,UAAU;IAApD;;QAC8B,eAAU,GAAY,EAAE,CAAC;IAuEvD,CAAC;IArEC,UAAU;QACR,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAsB,qBAAqB,EAAE;YAC1D,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;SACzB,CAAC,CACH,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,OAAuB;QAC7B,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE;YAC7B,IAAI,CAAC,UAAU,EAAE,CAAC;SACnB;IACH,CAAC;IAED,IAAI,WAAW;QACb,OAAO,aAAa,IAAI,CAAC,UAAU,EAAE,CAAC;IACxC,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAA;;;;;;;;;kBASG,IAAI,CAAC,WAAW;;KAE7B,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,MAAM;QACf,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAiCT,CAAC;IACJ,CAAC;CACF,CAAA;AAvE6B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;wDAA0B;AAD1C,oBAAoB;IADhC,aAAa,CAAC,yBAAyB,CAAC;GAC5B,oBAAoB,CAwEhC;SAxEY,oBAAoB","sourcesContent":["import {\n LitElement,\n customElement,\n property,\n html,\n TemplateResult,\n PropertyValues,\n CSSResult,\n css,\n} from 'lit-element';\n\n@customElement('ia-no-theater-available')\nexport class IANoTheaterAvailable extends LitElement {\n @property({ type: String }) identifier?: string = '';\n\n emitLoaded(): void {\n this.dispatchEvent(\n new CustomEvent<{ loaded: boolean }>('loadingStateUpdated', {\n detail: { loaded: true },\n })\n );\n }\n\n updated(changed: PropertyValues): void {\n if (changed.has('identifier')) {\n this.emitLoaded();\n }\n }\n\n get downloadUrl(): string {\n return `/download/${this.identifier}`;\n }\n\n render(): TemplateResult {\n return html`\n <section>\n <h2>THERE IS NO PREVIEW AVAILABLE FOR THIS ITEM</h2>\n <p>\n This item does not appear to have any files that can be experienced on\n Archive.org. <br />\n Please download files in this item to interact with them on your\n computer.\n </p>\n <a href=${this.downloadUrl}>Show all files</a>\n </section>\n `;\n }\n\n static get styles(): CSSResult {\n return css`\n :host {\n color: var(--primaryTextColor, #fff);\n text-align: center;\n }\n section {\n margin: 10% auto 0;\n padding: 0 5%;\n }\n p {\n font-size: 1.4rem;\n }\n a {\n color: var(--primaryTextColor, #fff);\n background-color: rgb(25, 72, 128);\n min-height: 35px;\n outline: none;\n cursor: pointer;\n line-height: normal;\n border-radius: 0.4rem;\n text-align: center;\n vertical-align: middle;\n font-size: 1.4rem;\n font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;\n display: inline-block;\n padding: 0.85rem 1.2rem;\n border: 1px solid rgb(197, 209, 223);\n white-space: nowrap;\n appearance: auto;\n box-sizing: border-box;\n user-select: none;\n text-decoration: none;\n }\n `;\n }\n}\n"]}
@@ -0,0 +1,22 @@
1
+ import { ModalManager } from '@internetarchive/modal-manager';
2
+ import { SharedResizeObserver } from '@internetarchive/shared-resize-observer';
3
+ import { LitElement } from 'lit-element';
4
+ import { MetadataResponse } from '@internetarchive/search-service';
5
+ import { MenuProviderInterface, MenuShortcutInterface } from '../src/interfaces/menu-interfaces';
6
+ import { CustomTheaterInterface } from '../src/interfaces/custom-theater-interface';
7
+ export declare class BookNavigator extends LitElement implements CustomTheaterInterface {
8
+ modal?: ModalManager;
9
+ itemMD?: MetadataResponse;
10
+ baseHost?: string;
11
+ signedIn?: boolean | null;
12
+ sideMenuOpen: boolean;
13
+ sharedObserver?: SharedResizeObserver;
14
+ menuProviders?: MenuProviderInterface[];
15
+ menuShortcuts?: MenuShortcutInterface[];
16
+ emitLoadingStatusUpdate(): void;
17
+ addMenuShortcut(menuId: string): string;
18
+ removeMenuShortcut(menuId: string): string;
19
+ sortMenuShortcuts(): void;
20
+ emitMenuShortcutsUpdated(): void;
21
+ render(): import("lit-element").TemplateResult;
22
+ }
@@ -0,0 +1,49 @@
1
+ import { __decorate } from "tslib";
2
+ import { html, customElement, LitElement, property } from 'lit-element';
3
+ let BookNavigator = class BookNavigator extends LitElement {
4
+ constructor() {
5
+ super(...arguments);
6
+ this.signedIn = null;
7
+ }
8
+ emitLoadingStatusUpdate() { }
9
+ addMenuShortcut(menuId) {
10
+ return menuId;
11
+ }
12
+ removeMenuShortcut(menuId) {
13
+ return menuId;
14
+ }
15
+ sortMenuShortcuts() { }
16
+ emitMenuShortcutsUpdated() { }
17
+ render() {
18
+ return html ` <p>foo</p> `;
19
+ }
20
+ };
21
+ __decorate([
22
+ property({ attribute: false })
23
+ ], BookNavigator.prototype, "modal", void 0);
24
+ __decorate([
25
+ property({ type: Object })
26
+ ], BookNavigator.prototype, "itemMD", void 0);
27
+ __decorate([
28
+ property({ type: String })
29
+ ], BookNavigator.prototype, "baseHost", void 0);
30
+ __decorate([
31
+ property({ type: Boolean, reflect: true })
32
+ ], BookNavigator.prototype, "signedIn", void 0);
33
+ __decorate([
34
+ property({ type: Boolean })
35
+ ], BookNavigator.prototype, "sideMenuOpen", void 0);
36
+ __decorate([
37
+ property({ attribute: false })
38
+ ], BookNavigator.prototype, "sharedObserver", void 0);
39
+ __decorate([
40
+ property({ type: Array })
41
+ ], BookNavigator.prototype, "menuProviders", void 0);
42
+ __decorate([
43
+ property({ type: Array })
44
+ ], BookNavigator.prototype, "menuShortcuts", void 0);
45
+ BookNavigator = __decorate([
46
+ customElement('book-navigator')
47
+ ], BookNavigator);
48
+ export { BookNavigator };
49
+ //# sourceMappingURL=book-nav-stub.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"book-nav-stub.js","sourceRoot":"","sources":["../../test/book-nav-stub.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAQxE,IAAa,aAAa,GAA1B,MAAa,aACX,SAAQ,UAAU;IADpB;;QAS8C,aAAQ,GAAoB,IAAI,CAAC;IA2B/E,CAAC;IAjBC,uBAAuB,KAAI,CAAC;IAE5B,eAAe,CAAC,MAAc;QAC5B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,kBAAkB,CAAC,MAAc;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,iBAAiB,KAAI,CAAC;IAEtB,wBAAwB,KAAI,CAAC;IAE7B,MAAM;QACJ,OAAO,IAAI,CAAA,cAAc,CAAC;IAC5B,CAAC;CACF,CAAA;AAjCiC;IAA/B,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;4CAAsB;AAEzB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;6CAA2B;AAE1B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;+CAAmB;AAEF;IAA3C,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;+CAAkC;AAEhD;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;mDAAwB;AAEpB;IAA/B,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;qDAAuC;AAE3C;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;oDAAyC;AAExC;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;oDAAyC;AAjBxD,aAAa;IADzB,aAAa,CAAC,gBAAgB,CAAC;GACnB,aAAa,CAoCzB;SApCY,aAAa","sourcesContent":["import { ModalManager } from '@internetarchive/modal-manager';\nimport { SharedResizeObserver } from '@internetarchive/shared-resize-observer';\nimport { html, customElement, LitElement, property } from 'lit-element';\nimport { MetadataResponse } from '@internetarchive/search-service';\nimport {\n MenuProviderInterface,\n MenuShortcutInterface,\n} from '../src/interfaces/menu-interfaces';\nimport { CustomTheaterInterface } from '../src/interfaces/custom-theater-interface';\n@customElement('book-navigator')\nexport class BookNavigator\n extends LitElement\n implements CustomTheaterInterface {\n @property({ attribute: false }) modal?: ModalManager;\n\n @property({ type: Object }) itemMD?: MetadataResponse;\n\n @property({ type: String }) baseHost?: string;\n\n @property({ type: Boolean, reflect: true }) signedIn?: boolean | null = null;\n\n @property({ type: Boolean }) sideMenuOpen!: boolean;\n\n @property({ attribute: false }) sharedObserver?: SharedResizeObserver;\n\n @property({ type: Array }) menuProviders?: MenuProviderInterface[];\n\n @property({ type: Array }) menuShortcuts?: MenuShortcutInterface[];\n\n emitLoadingStatusUpdate() {}\n\n addMenuShortcut(menuId: string) {\n return menuId;\n }\n\n removeMenuShortcut(menuId: string) {\n return menuId;\n }\n\n sortMenuShortcuts() {}\n\n emitMenuShortcutsUpdated() {}\n\n render() {\n return html` <p>foo</p> `;\n }\n}\n"]}
@@ -1 +1,2 @@
1
1
  import '../src/item-navigator';
2
+ import '../test/book-nav-stub';
@@ -1,169 +1,317 @@
1
1
  /* eslint-disable camelcase */
2
- /* eslint-disable import/no-duplicates */
3
2
  import { html, fixture, expect } from '@open-wc/testing';
4
3
  import Sinon from 'sinon';
5
- // import { MetadataResponse, Metadata, File, Review, SpeechMusicASREntry } from '@internetarchive/search-service';
6
- import { SharedResizeObserver,
7
- // SharedResizeObserverInterface
8
- } from '@internetarchive/shared-resize-observer';
4
+ import { SharedResizeObserver } from '@internetarchive/shared-resize-observer';
5
+ import { ModalManager } from '@internetarchive/modal-manager';
6
+ import { ItemType } from '../src/item-navigator';
9
7
  import '../src/item-navigator';
10
- // import { IaItemInspector } from '../src/item-inspector/item-inspector';
11
- // class ItemStub implements MetadataResponse {
12
- // constructor() {
13
- // this.rawResponse = '';
14
- // this.created = 1;
15
- // this.d1 = 'hello';
16
- // this.d2 = 'boop';
17
- // this.dir = 'whee';
18
- // this.files = [];
19
- // this.files_count = 0;
20
- // this.item_last_updated = 2020;
21
- // this.item_size = 111;
22
- // this.metadata = { identifier: 'foo' } as Metadata;
23
- // this.server = 'foo-server';
24
- // this.uniq = 2;
25
- // this.workable_servers = ['abc'];
26
- // }
27
- // rawResponse: any;
28
- // created: number;
29
- // d1: string;
30
- // d2: string;
31
- // dir: string;
32
- // files: File[];
33
- // files_count: number;
34
- // item_last_updated: number;
35
- // item_size: number;
36
- // metadata: Metadata;
37
- // server: string;
38
- // uniq: number;
39
- // workable_servers: string[];
40
- // speech_vs_music_asr?: SpeechMusicASREntry[] | undefined;
41
- // reviews?: Review[] | undefined;
42
- // };
8
+ import '../test/book-nav-stub';
9
+ import { ItemStub, menuProvider, shortcut } from '../test/ia-stub';
43
10
  afterEach(() => {
44
11
  Sinon.restore();
45
12
  });
46
13
  describe('ItemNavigator', () => {
47
- describe('Loading Behavior', () => {
48
- it('shows the spinning loader', async () => {
14
+ describe('Theaters', () => {
15
+ it('shows <ia-no-theater-available> by default', async () => {
49
16
  var _a;
50
- const el = await fixture(html `<ia-item-navigator></ia-item-navigator>`);
51
- expect((_a = el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('ia-itemnav-loader')).to.be.exist;
17
+ const el = await fixture(html `<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`);
18
+ expect((_a = el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('ia-no-theater-available')).to.exist;
52
19
  });
53
- it('hides reader section if not `loaded`', async () => {
20
+ it('shows <book-navigator> if `this.itemType = "bookreader"`', async () => {
54
21
  var _a;
55
- const el = await fixture(html `<ia-item-navigator></ia-item-navigator>`);
56
- const mainTheaterSection = (_a = el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('#reader');
57
- expect(mainTheaterSection).to.be.exist;
58
- expect(mainTheaterSection === null || mainTheaterSection === void 0 ? void 0 : mainTheaterSection.classList.contains('hide')).to.be.true;
59
- expect(el.loaded).to.be.false;
60
- expect(el.hasAttribute('loaded')).to.equal(false);
22
+ const el = await fixture(html `<ia-item-navigator
23
+ .itemType=${ItemType.BOOK}
24
+ .item=${new ItemStub()}
25
+ .modal=${new ModalManager()}
26
+ .sharedObserver=${new SharedResizeObserver()}
27
+ ></ia-item-navigator>`);
28
+ await el.updateComplete;
29
+ el.toggleMenu();
30
+ await el.updateComplete;
31
+ const bookNavigator = (_a = el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('book-navigator');
32
+ await bookNavigator.updateComplete;
33
+ console.log('132234234324324324');
34
+ // TODO: add BookNavigator type & import via @internetarchive/bookreader
35
+ // For now, let's check that the BookNavigator element and its properties exist w/ stub
36
+ expect(bookNavigator).to.exist;
37
+ expect(bookNavigator === null || bookNavigator === void 0 ? void 0 : bookNavigator.modal).to.exist;
38
+ expect(bookNavigator === null || bookNavigator === void 0 ? void 0 : bookNavigator.baseHost).to.exist;
39
+ expect(bookNavigator === null || bookNavigator === void 0 ? void 0 : bookNavigator.signedIn).to.be.null;
40
+ expect(bookNavigator === null || bookNavigator === void 0 ? void 0 : bookNavigator.sharedObserver).to.exist;
41
+ expect(bookNavigator === null || bookNavigator === void 0 ? void 0 : bookNavigator.sideMenuOpen).to.exist;
61
42
  });
62
- it('shows reader once `loaded`', async () => {
43
+ });
44
+ describe('`el.loaded`', () => {
45
+ it('toggles the spinning loader', async () => {
63
46
  var _a;
64
47
  const el = await fixture(html `<ia-item-navigator></ia-item-navigator>`);
65
- el.loaded = true;
66
- await el.updateComplete;
48
+ expect(el.loaded).to.be.null; // initial load
49
+ expect((_a = el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('ia-itemnav-loader')).to.exist;
50
+ });
51
+ it('hides reader section if `!loaded`', async () => {
52
+ var _a, _b;
53
+ const el = await fixture(html `<ia-item-navigator></ia-item-navigator>`);
54
+ expect((_b = (_a = el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('#reader')) === null || _b === void 0 ? void 0 : _b.getAttribute('class')).to.contain('hide');
55
+ });
56
+ it('shows reader when `loaded` ', async () => {
57
+ var _a, _b;
58
+ const el = await fixture(html `<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`);
67
59
  const mainTheaterSection = (_a = el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('#reader');
68
60
  expect(mainTheaterSection === null || mainTheaterSection === void 0 ? void 0 : mainTheaterSection.classList.contains('hide')).to.be.false;
69
61
  expect(el.loaded).to.be.true;
70
62
  // `loaded` property is reflected as DOM attribute
71
63
  expect(el.hasAttribute('loaded')).to.equal(true);
64
+ expect((_b = el.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('ia-no-theater-available')).to.exist;
72
65
  });
73
- // it('listens to event `loadingStateUpdated` to signal load', async () => {
74
- // const item = new ItemStub() as MetadataResponse;
75
- // const el = await fixture<ItemNavigator>(
76
- // html`<ia-item-navigator .item=${item}></ia-item-navigator>`
77
- // );
78
- // // const loadSpy = Sinon.spy();
79
- // // el.loadingStateUpdated = loadSpy;
80
- // await el.updateComplete;
81
- // expect(el?.item).to.not.be.undefined;
82
- // const mainTheaterSection = el.shadowRoot?.querySelector('#reader');
83
- // const contentController = mainTheaterSection?.querySelector('ia-item-inspector');
84
- // expect(contentController).to.equal(32324);
85
- // // const loadingEvent = new CustomEvent('loadingStateUpdated', { detail: { loaded: true }}) as IntLoadingStateUpdatedEvent;
86
- // // contentController?.emitLoadingStatusUpdate(true);
87
- // // await contentController?.updateComplete;
88
- // // await el.updateComplete;
89
- // });
90
- });
91
- describe('It uses a shared ResizeObserver', () => {
92
- it('can create one', async () => {
66
+ it('listens to `@loadingStateUpdated` to update `loaded`', async () => {
93
67
  const el = await fixture(html `<ia-item-navigator></ia-item-navigator>`);
94
68
  await el.updateComplete;
95
- expect(el.sharedObserver).to.not.be.null;
96
- expect(el.sharedObserver).to.be.instanceOf(SharedResizeObserver);
69
+ const spy = Sinon.spy();
70
+ el.loadingStateUpdated = spy;
71
+ el.loaded = null;
72
+ await el.updateComplete;
73
+ // check base properties
74
+ expect(el.loaded).to.equal(null);
75
+ expect(el.item).to.be.undefined;
76
+ // hydrate item
77
+ el.item = new ItemStub();
78
+ await el.updateComplete;
79
+ // spy fires
80
+ expect(spy.called).to.equal(true);
81
+ expect(spy.callCount).to.equal(1);
97
82
  });
98
- it('can recieve one', async () => {
83
+ });
84
+ describe('`el.sharedObserver`', () => {
85
+ it('uses one', async () => {
99
86
  const sharedObserver = new SharedResizeObserver();
100
87
  const el = await fixture(html `<ia-item-navigator
101
88
  .sharedObserver=${sharedObserver}
102
89
  ></ia-item-navigator>`);
103
- await el.updateComplete;
104
- expect(el.sharedObserver).to.be.instanceOf(SharedResizeObserver);
90
+ expect(el.sharedObserver).to.equal(sharedObserver);
91
+ expect(typeof el.handleResize).to.equal('function');
105
92
  });
106
- });
107
- describe('It uses a shared modal component', () => {
108
- it('can create one', async () => {
109
- const el = await fixture(html `<ia-item-navigator></ia-item-navigator>`);
110
- await el.updateComplete;
111
- expect(el.sharedObserver).to.not.be.null;
112
- expect(el.sharedObserver).to.be.instanceOf(SharedResizeObserver);
93
+ it('freshly registers handler', async () => {
94
+ const sharedObserver = new SharedResizeObserver();
95
+ const addObserverSpy = Sinon.spy(sharedObserver, 'addObserver');
96
+ await fixture(html `<ia-item-navigator
97
+ .sharedObserver=${sharedObserver}
98
+ ></ia-item-navigator>`);
99
+ expect(addObserverSpy.callCount).to.equal(1);
113
100
  });
114
- it('can recieve one', async () => {
101
+ it('removes handler when component disconnects', async () => {
115
102
  const sharedObserver = new SharedResizeObserver();
116
- const observerSpy = Sinon.stub(sharedObserver, 'addObserver');
103
+ const removeObserverSpy = Sinon.spy(sharedObserver, 'removeObserver');
117
104
  const el = await fixture(html `<ia-item-navigator
118
105
  .sharedObserver=${sharedObserver}
119
106
  ></ia-item-navigator>`);
107
+ el.disconnectedCallback();
108
+ await el.updateComplete;
109
+ expect(removeObserverSpy.callCount).to.equal(1);
110
+ });
111
+ it('sets menu to overlay if container width is <= 600px', async () => {
112
+ const el = await fixture(html `<ia-item-navigator></ia-item-navigator>`);
113
+ expect(el.openMenuState).to.equal('shift'); // as starting point
114
+ const overlaySize = {
115
+ contentRect: { width: 600 },
116
+ };
117
+ el.handleResize(overlaySize);
118
+ await el.updateComplete;
119
+ expect(el.openMenuState).to.equal('overlay'); // changes open menu display to an overlay
120
+ const shiftSize = {
121
+ contentRect: { width: 601 },
122
+ };
123
+ el.handleResize(shiftSize);
124
+ await el.updateComplete;
125
+ expect(el.openMenuState).to.equal('shift');
126
+ });
127
+ });
128
+ describe('`el.modal`', () => {
129
+ it('uses one', async () => {
130
+ const modal = new ModalManager();
131
+ const el = await fixture(html `<ia-item-navigator .modal=${modal}></ia-item-navigator>`);
132
+ expect(el.modal).to.equal(modal);
133
+ });
134
+ });
135
+ describe('full browser window immersion "fullscreen"', () => {
136
+ it('creates reflected attribute `viewportinfullscreen`', async () => {
137
+ /** to help with external styling adjustmnents */
138
+ const el = await fixture(html `<ia-item-navigator></ia-item-navigator>`);
139
+ expect(el.getAttribute('viewportinfullscreen')).to.be.null;
140
+ el.viewportInFullscreen = true;
141
+ await el.updateComplete;
142
+ expect(el.getAttribute('viewportinfullscreen')).to.exist;
143
+ });
144
+ it('@ViewportInFullScreen', async () => {
145
+ const el = await fixture(html `<ia-item-navigator></ia-item-navigator>`);
146
+ expect(el.viewportInFullscreen).to.be.null;
147
+ const yesFullscreenEvent = {
148
+ detail: {
149
+ isFullScreen: true,
150
+ },
151
+ };
152
+ el.manageViewportFullscreen(yesFullscreenEvent);
153
+ await el.updateComplete;
154
+ expect(el.viewportInFullscreen).to.be.true;
155
+ const noFullscreenEvent = {
156
+ detail: {
157
+ isFullScreen: false,
158
+ },
159
+ };
160
+ el.manageViewportFullscreen(noFullscreenEvent);
161
+ await el.updateComplete;
162
+ expect(el.viewportInFullscreen).to.be.null;
163
+ });
164
+ });
165
+ /* Side menu & shortcuts tests */
166
+ describe('el.menuOpened', () => {
167
+ it('toggles side menu open', async () => {
168
+ var _a, _b, _c;
169
+ const el = await fixture(html `<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`);
170
+ el.menuContents = [menuProvider];
171
+ await el.updateComplete;
172
+ const nav = (_a = el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('nav');
173
+ expect(nav === null || nav === void 0 ? void 0 : nav.querySelector('#menu')).to.exist;
174
+ // side menu starts closed
175
+ expect(el.menuOpened).to.be.false;
176
+ expect((_b = nav === null || nav === void 0 ? void 0 : nav.querySelector('#menu')) === null || _b === void 0 ? void 0 : _b.getAttribute('class')).to.contain('hidden');
177
+ // let's open menu
178
+ el.toggleMenu();
179
+ await el.updateComplete;
180
+ expect(el.menuOpened).to.be.true;
181
+ expect((_c = nav === null || nav === void 0 ? void 0 : nav.querySelector('#menu')) === null || _c === void 0 ? void 0 : _c.getAttribute('class')).to.not.contain('hidden');
182
+ });
183
+ it('opens menu shortcut with `@manageSideMenuEvents`', async () => {
184
+ var _a;
185
+ const el = await fixture(html `<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`);
186
+ const detail = {
187
+ menuId: 'fullscreen',
188
+ action: 'open',
189
+ };
190
+ el.menuContents = [menuProvider];
191
+ await el.updateComplete;
192
+ const frame = (_a = el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('#frame');
193
+ // default menu open behavior is to side menu open, not overlay
194
+ expect(frame === null || frame === void 0 ? void 0 : frame.getAttribute('class')).to.contain('shift');
195
+ expect(el.menuOpened).to.be.false;
196
+ expect(el.openMenu).to.be.undefined;
197
+ expect(frame === null || frame === void 0 ? void 0 : frame.getAttribute('class')).to.not.contain('open');
198
+ const event = new CustomEvent('updateSideMenu', {
199
+ detail,
200
+ });
201
+ el.manageSideMenuEvents(event);
202
+ await el.updateComplete;
203
+ expect(el.shouldRenderMenu).to.be.true;
204
+ expect(el.menuOpened).to.be.true;
205
+ expect(el.openMenu).to.equal(detail.menuId);
206
+ expect(frame === null || frame === void 0 ? void 0 : frame.getAttribute('class')).to.contain('open');
207
+ // no menu provided
208
+ const openShortcutSpy = Sinon.spy(el, 'openShortcut');
209
+ const toggleMenuSpy = Sinon.spy(el, 'toggleMenu');
210
+ const noMenuProvidedEvent = new CustomEvent('updateSideMenu', {
211
+ detail: {},
212
+ });
213
+ el.manageSideMenuEvents(noMenuProvidedEvent);
214
+ await el.updateComplete;
215
+ expect(openShortcutSpy.called).to.be.false;
216
+ expect(toggleMenuSpy.called).to.be.false;
217
+ // toggle menu
218
+ const toggleMenuEvent = new CustomEvent('updateSideMenu', {
219
+ detail: { action: 'toggle', menuId: 'fullscreen' },
220
+ });
221
+ el.manageSideMenuEvents(toggleMenuEvent);
222
+ await el.updateComplete;
223
+ expect(toggleMenuSpy.callCount).to.equal(1);
224
+ // open menu
225
+ const openMenuEvent = new CustomEvent('updateSideMenu', {
226
+ detail: { action: 'open', menuId: 'fullscreen' },
227
+ });
228
+ el.manageSideMenuEvents(openMenuEvent);
229
+ await el.updateComplete;
230
+ expect(openShortcutSpy.callCount).to.equal(1);
231
+ });
232
+ });
233
+ describe('el.menuContents', () => {
234
+ it('draws side menu when populated', async () => {
235
+ var _a;
236
+ const el = await fixture(html `<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`);
237
+ el.menuContents = [menuProvider];
238
+ await el.updateComplete;
239
+ expect(el.menuContents.length).to.exist;
240
+ expect(el.shouldRenderMenu).to.be.true;
241
+ const nav = (_a = el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('nav');
242
+ expect(nav).to.exist;
243
+ const menuSlider = nav === null || nav === void 0 ? void 0 : nav.querySelector('ia-menu-slider');
244
+ expect(menuSlider).to.exist;
245
+ expect(menuSlider === null || menuSlider === void 0 ? void 0 : menuSlider.getAttribute('manuallyhandleclose')).to.exist;
246
+ expect(menuSlider === null || menuSlider === void 0 ? void 0 : menuSlider.getAttribute('open')).to.exist;
247
+ });
248
+ });
249
+ describe('`el.menuShortcuts`', () => {
250
+ it('displays shortcut & toggle side menu button', async () => {
251
+ var _a;
252
+ const el = await fixture(html `<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`);
253
+ const anotherShortcut = {
254
+ id: 'foo',
255
+ icon: html `<i class="foo-shortcut"></i>`,
256
+ };
257
+ el.menuContents = [menuProvider];
258
+ el.menuShortcuts = [shortcut, anotherShortcut];
259
+ await el.updateComplete;
260
+ const nav = (_a = el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('nav');
261
+ const shortcutsContainer = nav === null || nav === void 0 ? void 0 : nav.querySelector('.shortcuts');
262
+ expect(el.menuShortcuts.length).to.exist;
263
+ expect(nav).to.exist;
264
+ expect(shortcutsContainer).to.exist;
265
+ expect(shortcutsContainer === null || shortcutsContainer === void 0 ? void 0 : shortcutsContainer.querySelector('i.fullscreen-test')).to.exist;
266
+ expect(shortcutsContainer === null || shortcutsContainer === void 0 ? void 0 : shortcutsContainer.querySelector('button.shortcut.foo')).to.exist;
267
+ expect(nav === null || nav === void 0 ? void 0 : nav.querySelector('.toggle-menu')).to.exist;
268
+ });
269
+ });
270
+ describe('Menu events', () => {
271
+ it('`el.setMenuShortcuts`', async () => {
272
+ const el = await fixture(html `<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`);
273
+ expect(el.menuShortcuts.length).to.equal(0);
274
+ const menuShortcuts = [shortcut];
275
+ el.setMenuShortcuts({
276
+ detail: menuShortcuts,
277
+ });
278
+ await el.updateComplete;
279
+ expect(el.menuShortcuts.length).to.equal(1);
280
+ });
281
+ it('`el.setMenuContents`', async () => {
282
+ const el = await fixture(html `<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`);
283
+ expect(el.menuContents.length).to.equal(0);
284
+ el.setMenuShortcuts({
285
+ detail: [menuProvider],
286
+ });
287
+ await el.updateComplete;
288
+ expect(el.menuShortcuts.length).to.equal(1);
289
+ });
290
+ it('`el.setOpenMenu`', async () => {
291
+ const el = await fixture(html `<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`);
292
+ el.setOpenMenu({
293
+ detail: { id: 'foo' },
294
+ });
295
+ await el.updateComplete;
296
+ expect(el.openMenu).to.equal('foo');
297
+ expect(el.selectedMenuId).to.equal('foo');
298
+ // toggles it off
299
+ el.setOpenMenu({
300
+ detail: { id: 'foo' },
301
+ });
302
+ await el.updateComplete;
303
+ expect(el.openMenu).to.be.undefined;
304
+ expect(el.selectedMenuId).to.equal('');
305
+ });
306
+ it('`el.closeMenu`', async () => {
307
+ const el = await fixture(html `<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`);
308
+ el.menuOpened = true;
309
+ await el.updateComplete;
310
+ expect(el.menuOpened).to.be.true;
311
+ el.closeMenu();
120
312
  await el.updateComplete;
121
- expect(el.sharedObserver).to.be.instanceOf(SharedResizeObserver);
122
- expect(observerSpy.called).to.equal(true);
313
+ expect(el.menuOpened).to.be.false;
123
314
  });
124
315
  });
125
- // describe('full browser window immersion "fullscreen"', () => {
126
- // it('creates reflected attribute `viewportinfullscreen`', () =>{
127
- // /** to help with external styling adjustmnents */
128
- // });
129
- // });
130
- // describe('Loads side menu contents', () =>{
131
- // });
132
- // describe('Menu Shortcuts', () => {
133
- // });
134
- // it('passes the a11y audit', async () => {
135
- // const el = await fixture<YourWebComponent>(
136
- // html`<your-webcomponent></your-webcomponent>`
137
- // );
138
- // await expect(el).shadowDom.to.be.accessible();
139
- // });
140
316
  });
141
- // describe('YourWebComponent', () => {
142
- // it('has a default title "Hey there" and counter 5', async () => {
143
- // const el = await fixture<YourWebComponent>(
144
- // html`<your-webcomponent></your-webcomponent>`
145
- // );
146
- // expect(el.title).to.equal('Hey there');
147
- // expect(el.counter).to.equal(5);
148
- // });
149
- // it('increases the counter on button click', async () => {
150
- // const el = await fixture<YourWebComponent>(
151
- // html`<your-webcomponent></your-webcomponent>`
152
- // );
153
- // el.shadowRoot!.querySelector('button')!.click();
154
- // expect(el.counter).to.equal(6);
155
- // });
156
- // it('can override the title via attribute', async () => {
157
- // const el = await fixture<YourWebComponent>(
158
- // html`<your-webcomponent title="attribute title"></your-webcomponent>`
159
- // );
160
- // expect(el.title).to.equal('attribute title');
161
- // });
162
- // it('passes the a11y audit', async () => {
163
- // const el = await fixture<YourWebComponent>(
164
- // html`<your-webcomponent></your-webcomponent>`
165
- // );
166
- // await expect(el).shadowDom.to.be.accessible();
167
- // });
168
- // });
169
317
  //# sourceMappingURL=ia-item-navigator.test.js.map