@internetarchive/ia-item-navigator 1.1.1 → 2.0.0-alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. package/demo/app-root.ts +190 -28
  2. package/dist/demo/app-root.d.ts +7 -3
  3. package/dist/demo/app-root.js +158 -22
  4. package/dist/demo/app-root.js.map +1 -1
  5. package/dist/index.d.ts +4 -1
  6. package/dist/index.js +5 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/src/{item-navigator.js → iaux-item-navigator.js} +3 -10
  9. package/dist/src/iaux-item-navigator.js.map +1 -0
  10. package/dist/src/menus/iaux-sharing-options.d.ts +28 -0
  11. package/dist/src/menus/iaux-sharing-options.js +277 -0
  12. package/dist/src/menus/iaux-sharing-options.js.map +1 -0
  13. package/dist/src/menus/iaux-viewable-files.d.ts +32 -0
  14. package/dist/src/menus/iaux-viewable-files.js +367 -0
  15. package/dist/src/menus/iaux-viewable-files.js.map +1 -0
  16. package/dist/src/menus/share-providers/email.d.ts +11 -0
  17. package/dist/src/menus/share-providers/email.js +15 -0
  18. package/dist/src/menus/share-providers/email.js.map +1 -0
  19. package/dist/src/menus/share-providers/facebook.d.ts +11 -0
  20. package/dist/src/menus/share-providers/facebook.js +15 -0
  21. package/dist/src/menus/share-providers/facebook.js.map +1 -0
  22. package/dist/src/menus/share-providers/pinterest.d.ts +11 -0
  23. package/dist/src/menus/share-providers/pinterest.js +15 -0
  24. package/dist/src/menus/share-providers/pinterest.js.map +1 -0
  25. package/dist/src/menus/share-providers/provider.d.ts +20 -0
  26. package/dist/src/menus/share-providers/provider.js +37 -0
  27. package/dist/src/menus/share-providers/provider.js.map +1 -0
  28. package/dist/src/menus/share-providers/share-provider-interface.d.ts +13 -0
  29. package/dist/src/menus/share-providers/share-provider-interface.js +2 -0
  30. package/dist/src/menus/share-providers/share-provider-interface.js.map +1 -0
  31. package/dist/src/menus/share-providers/tumblr.d.ts +11 -0
  32. package/dist/src/menus/share-providers/tumblr.js +15 -0
  33. package/dist/src/menus/share-providers/tumblr.js.map +1 -0
  34. package/dist/src/menus/share-providers/twitter.d.ts +11 -0
  35. package/dist/src/menus/share-providers/twitter.js +15 -0
  36. package/dist/src/menus/share-providers/twitter.js.map +1 -0
  37. package/dist/test/iaux-item-navigator.test.d.ts +1 -0
  38. package/dist/test/{ia-item-navigator.test.js → iaux-item-navigator.test.js} +49 -27
  39. package/dist/test/iaux-item-navigator.test.js.map +1 -0
  40. package/dist/test/iaux-sharing-options.test.d.ts +1 -0
  41. package/dist/test/iaux-sharing-options.test.js +64 -0
  42. package/dist/test/iaux-sharing-options.test.js.map +1 -0
  43. package/index.ts +9 -1
  44. package/package.json +11 -4
  45. package/src/{item-navigator.ts → iaux-item-navigator.ts} +2 -10
  46. package/src/menus/foo.json +84 -0
  47. package/src/menus/iaux-sharing-options.ts +281 -0
  48. package/src/menus/iaux-viewable-files.ts +377 -0
  49. package/src/menus/share-providers/email.ts +23 -0
  50. package/src/menus/share-providers/facebook.ts +23 -0
  51. package/src/menus/share-providers/pinterest.ts +23 -0
  52. package/src/menus/share-providers/provider.ts +63 -0
  53. package/src/menus/share-providers/share-provider-interface.ts +17 -0
  54. package/src/menus/share-providers/tumblr.ts +23 -0
  55. package/src/menus/share-providers/twitter.ts +23 -0
  56. package/test/ia-sharing-options.test.js +78 -0
  57. package/test/{iaux-item-navigator.test.txt → iaux-item-navigator.test.ts} +46 -24
  58. package/dist/src/item-navigator.js.map +0 -1
  59. package/dist/test/ia-item-navigator.test.d.ts +0 -1
  60. package/dist/test/ia-item-navigator.test.js.map +0 -1
  61. package/test/ia-item-navigator.test.ts +0 -417
  62. /package/dist/src/{item-navigator.d.ts → iaux-item-navigator.d.ts} +0 -0
  63. /package/test/{iaux-sharing-options.test.txt → iaux-sharing-options.test.ts} +0 -0
@@ -1,417 +0,0 @@
1
- /* eslint-disable camelcase */
2
- import { html, fixture, expect } from '@open-wc/testing';
3
- import Sinon from 'sinon';
4
-
5
- import { SharedResizeObserver } from '@internetarchive/shared-resize-observer';
6
- import { ModalManager } from '@internetarchive/modal-manager';
7
- import { ItemNavigator } from '../src/item-navigator';
8
- import '../src/item-navigator';
9
-
10
- import { ItemStub, menuProvider, shortcut } from '../test/ia-stub';
11
- import {
12
- ManageFullscreenEvent,
13
- ToggleSideMenuOpenEvent,
14
- SetSideMenuContentsEvent,
15
- SetSideMenuShortcutsEvent,
16
- ToggleSidePanelOpenEvent,
17
- } from '../src/interfaces/event-interfaces';
18
-
19
- afterEach(() => {
20
- Sinon.restore();
21
- });
22
-
23
- describe('ItemNavigator', () => {
24
- describe('Theaters', () => {
25
- it('shows <ia-no-theater-available> if told', async () => {
26
- const el = await fixture<ItemNavigator>(
27
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
28
- );
29
- el.viewAvailable = false;
30
- await el.updateComplete;
31
- expect(el.viewAvailable).to.be.false;
32
- expect(el.shadowRoot?.querySelector('ia-no-theater-available')).to.exist;
33
- });
34
- it('opens main slot by default', async () => {
35
- const el = await fixture<ItemNavigator>(
36
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
37
- );
38
-
39
- expect(el.viewAvailable).to.be.true;
40
- expect(el.shadowRoot?.querySelector('ia-no-theater-available')).to.be
41
- .null;
42
- expect(el.shadowRoot?.querySelector('slot[name="main"]')).to.exist;
43
- });
44
- });
45
- describe('`el.loaded`', () => {
46
- it('toggles the spinning loader', async () => {
47
- const el = await fixture<ItemNavigator>(
48
- html`<ia-item-navigator></ia-item-navigator>`,
49
- );
50
- expect(el.loaded).to.be.null; // initial load
51
- expect(el.shadowRoot?.querySelector('ia-itemnav-loader')).to.exist;
52
- });
53
- it('hides reader section if `!loaded`', async () => {
54
- const el = await fixture<ItemNavigator>(
55
- html`<ia-item-navigator></ia-item-navigator>`,
56
- );
57
-
58
- expect(
59
- el.shadowRoot?.querySelector('#reader')?.getAttribute('class'),
60
- ).to.contain('hidden');
61
- });
62
- it('shows reader when `loaded` ', async () => {
63
- const el = await fixture<ItemNavigator>(
64
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
65
- );
66
-
67
- el.loaded = true;
68
- await el.updateComplete;
69
- const mainTheaterSection = el.shadowRoot?.querySelector('#reader');
70
- expect(mainTheaterSection?.classList.contains('hide')).to.be.false;
71
- expect(el.loaded).to.be.true;
72
- // `loaded` property is reflected as DOM attribute
73
- expect(el.hasAttribute('loaded')).to.equal(true);
74
- expect(el.shadowRoot?.querySelector('slot[name="main"]')).to.exist;
75
- });
76
- it('listens to `@loadingStateUpdated` to update `loaded` for <no-theater-available>', async () => {
77
- const el = await fixture<ItemNavigator>(
78
- html`<ia-item-navigator></ia-item-navigator>`,
79
- );
80
-
81
- await el.updateComplete;
82
- const spy = Sinon.spy();
83
- el.loadingStateUpdated = spy;
84
- el.loaded = null;
85
- el.viewAvailable = false;
86
- await el.updateComplete;
87
- // check base properties
88
- expect(el.loaded).to.equal(null);
89
- expect(el.item).to.be.undefined;
90
-
91
- // spy fires
92
- expect(spy.called).to.equal(true);
93
- expect(spy.callCount).to.equal(1);
94
- });
95
- });
96
-
97
- describe('`el.sharedObserver`', () => {
98
- it('uses one', async () => {
99
- const sharedObserver = new SharedResizeObserver();
100
- const el = await fixture<ItemNavigator>(
101
- html`<ia-item-navigator
102
- .sharedObserver=${sharedObserver}
103
- ></ia-item-navigator>`,
104
- );
105
-
106
- expect(el.sharedObserver).to.equal(sharedObserver);
107
- expect(typeof el.handleResize).to.equal('function');
108
- });
109
- it('freshly registers handlers', async () => {
110
- const sharedObserver = new SharedResizeObserver();
111
- const addObserverSpy = Sinon.spy(sharedObserver, 'addObserver');
112
-
113
- await fixture<ItemNavigator>(
114
- html`<ia-item-navigator
115
- .sharedObserver=${sharedObserver}
116
- ></ia-item-navigator>`,
117
- );
118
-
119
- expect(addObserverSpy.callCount).to.equal(2);
120
- });
121
- it('removes handler when component disconnects', async () => {
122
- const sharedObserver = new SharedResizeObserver();
123
- const removeObserverSpy = Sinon.spy(sharedObserver, 'removeObserver');
124
-
125
- const el = await fixture<ItemNavigator>(
126
- html`<ia-item-navigator
127
- .sharedObserver=${sharedObserver}
128
- ></ia-item-navigator>`,
129
- );
130
-
131
- el.disconnectedCallback();
132
- await el.updateComplete;
133
-
134
- expect(removeObserverSpy.callCount).to.equal(1);
135
- });
136
- it('sets menu to overlay if container width is <= 600px', async () => {
137
- const el = await fixture<ItemNavigator>(
138
- html`<ia-item-navigator></ia-item-navigator>`,
139
- );
140
-
141
- expect(el.openMenuState).to.equal('shift'); // as starting point
142
-
143
- const overlaySize = {
144
- contentRect: { width: 600 },
145
- } as ResizeObserverEntry;
146
- el.handleResize(overlaySize);
147
- await el.updateComplete;
148
-
149
- expect(el.openMenuState).to.equal('overlay'); // changes open menu display to an overlay
150
-
151
- const shiftSize = {
152
- contentRect: { width: 601 },
153
- } as ResizeObserverEntry;
154
- el.handleResize(shiftSize);
155
- await el.updateComplete;
156
-
157
- expect(el.openMenuState).to.equal('shift');
158
- });
159
- });
160
-
161
- describe('`el.modal`', () => {
162
- it('uses one', async () => {
163
- const modal = new ModalManager();
164
- const el = await fixture<ItemNavigator>(
165
- html`<ia-item-navigator .modal=${modal}></ia-item-navigator>`,
166
- );
167
- expect(el.modal).to.equal(modal);
168
- });
169
- });
170
-
171
- describe('full browser window immersion "fullscreen"', () => {
172
- it('creates reflected attribute `viewportinfullscreen`', async () => {
173
- /** to help with external styling adjustmnents */
174
- const el = await fixture<ItemNavigator>(
175
- html`<ia-item-navigator></ia-item-navigator>`,
176
- );
177
- expect(el.getAttribute('viewportinfullscreen')).to.be.null;
178
-
179
- el.viewportInFullscreen = true;
180
- await el.updateComplete;
181
-
182
- expect(el.getAttribute('viewportinfullscreen')).to.exist;
183
- });
184
- it('@ViewportInFullScreen', async () => {
185
- const el = await fixture<ItemNavigator>(
186
- html`<ia-item-navigator></ia-item-navigator>`,
187
- );
188
- expect(el.viewportInFullscreen).to.be.null;
189
-
190
- const yesFullscreenEvent = {
191
- detail: {
192
- isFullScreen: true,
193
- },
194
- } as ManageFullscreenEvent;
195
- el.manageViewportFullscreen(yesFullscreenEvent);
196
- await el.updateComplete;
197
- expect(el.viewportInFullscreen).to.be.true;
198
-
199
- const noFullscreenEvent = {
200
- detail: {
201
- isFullScreen: false,
202
- },
203
- } as ManageFullscreenEvent;
204
- el.manageViewportFullscreen(noFullscreenEvent);
205
- await el.updateComplete;
206
- expect(el.viewportInFullscreen).to.be.null;
207
- });
208
- });
209
-
210
- /* Side menu & shortcuts tests */
211
- describe('el.menuOpened', () => {
212
- it('toggles side menu open', async () => {
213
- const el = await fixture<ItemNavigator>(
214
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
215
- );
216
-
217
- el.menuContents = [menuProvider];
218
- await el.updateComplete;
219
-
220
- const nav = el.shadowRoot?.querySelector('nav');
221
-
222
- expect(nav?.querySelector('#menu')).to.exist;
223
- // side menu starts closed
224
- expect(el.menuOpened).to.be.false;
225
- expect(nav?.querySelector('#menu')?.getAttribute('class')).to.contain(
226
- 'hidden',
227
- );
228
-
229
- // let's open menu
230
- el.toggleMenu();
231
- await el.updateComplete;
232
-
233
- expect(el.menuOpened).to.be.true;
234
- expect(nav?.querySelector('#menu')?.getAttribute('class')).to.not.contain(
235
- 'hidden',
236
- );
237
- });
238
-
239
- it('opens menu shortcut with `@manageSideMenuEvents`', async () => {
240
- const el = await fixture<ItemNavigator>(
241
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
242
- );
243
- const detail = {
244
- menuId: 'fullscreen',
245
- action: 'open',
246
- };
247
-
248
- el.menuContents = [menuProvider];
249
- await el.updateComplete;
250
- const frame = el.shadowRoot?.querySelector('#frame');
251
- // default menu open behavior is to side menu open, not overlay
252
- expect(frame?.getAttribute('class')).to.contain('shift');
253
-
254
- expect(el.menuOpened).to.be.false;
255
- expect(el.openMenu).to.be.undefined;
256
- expect(frame?.getAttribute('class')).to.not.contain('open');
257
-
258
- const event = new CustomEvent('updateSideMenu', {
259
- detail,
260
- }) as ToggleSideMenuOpenEvent;
261
- el.manageSideMenuEvents(event);
262
- await el.updateComplete;
263
-
264
- expect(el.shouldRenderMenu).to.be.true;
265
- expect(el.menuOpened).to.be.true;
266
- expect(el.openMenu).to.equal(detail.menuId);
267
-
268
- expect(frame?.getAttribute('class')).to.contain('open');
269
-
270
- // no menu provided
271
- const openShortcutSpy = Sinon.spy(el, 'openShortcut');
272
- const toggleMenuSpy = Sinon.spy(el, 'toggleMenu');
273
-
274
- const noMenuProvidedEvent = new CustomEvent('updateSideMenu', {
275
- detail: {},
276
- }) as any;
277
- el.manageSideMenuEvents(noMenuProvidedEvent);
278
- await el.updateComplete;
279
-
280
- expect(openShortcutSpy.called).to.be.false;
281
- expect(toggleMenuSpy.called).to.be.false;
282
-
283
- // toggle menu
284
- const toggleMenuEvent = new CustomEvent('updateSideMenu', {
285
- detail: { action: 'toggle', menuId: 'fullscreen' },
286
- }) as any;
287
- el.manageSideMenuEvents(toggleMenuEvent);
288
- await el.updateComplete;
289
-
290
- expect(toggleMenuSpy.callCount).to.equal(1);
291
-
292
- // open menu
293
- const openMenuEvent = new CustomEvent('updateSideMenu', {
294
- detail: { action: 'open', menuId: 'fullscreen' },
295
- }) as any;
296
- el.manageSideMenuEvents(openMenuEvent);
297
- await el.updateComplete;
298
-
299
- expect(openShortcutSpy.callCount).to.equal(1);
300
- });
301
- });
302
-
303
- describe('el.menuContents', () => {
304
- it('draws side menu when populated', async () => {
305
- const el = await fixture<ItemNavigator>(
306
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
307
- );
308
-
309
- el.menuContents = [menuProvider];
310
- await el.updateComplete;
311
- expect(el.menuContents.length).to.exist;
312
- expect(el.shouldRenderMenu).to.be.true;
313
-
314
- const nav = el.shadowRoot?.querySelector('nav');
315
- expect(nav).to.exist;
316
-
317
- const menuSlider = nav?.querySelector('ia-menu-slider');
318
- expect(menuSlider).to.exist;
319
- expect(menuSlider?.getAttribute('manuallyhandleclose')).to.exist;
320
- expect(menuSlider?.getAttribute('open')).to.exist;
321
- });
322
- });
323
-
324
- describe('`el.menuShortcuts`', () => {
325
- it('displays shortcut & toggle side menu button', async () => {
326
- const el = await fixture<ItemNavigator>(
327
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
328
- );
329
-
330
- const anotherShortcut = {
331
- id: 'foo',
332
- icon: html`<i class="foo-shortcut"></i>`,
333
- };
334
- el.menuContents = [menuProvider];
335
- el.menuShortcuts = [shortcut, anotherShortcut];
336
- await el.updateComplete;
337
-
338
- const nav = el.shadowRoot?.querySelector('nav');
339
-
340
- const shortcutsContainer = nav?.querySelector('.shortcuts');
341
- expect(el.menuShortcuts.length).to.exist;
342
- expect(nav).to.exist;
343
- expect(shortcutsContainer).to.exist;
344
- expect(shortcutsContainer?.querySelector('i.fullscreen-test')).to.exist;
345
- expect(shortcutsContainer?.querySelector('button.shortcut.foo')).to.exist;
346
- expect(nav?.querySelector('.toggle-menu')).to.exist;
347
- });
348
- });
349
-
350
- describe('Menu events', () => {
351
- it('`el.setMenuShortcuts`', async () => {
352
- const el = await fixture<ItemNavigator>(
353
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
354
- );
355
- expect(el.menuShortcuts.length).to.equal(0);
356
-
357
- const menuShortcuts = [shortcut];
358
-
359
- el.setMenuShortcuts({
360
- detail: menuShortcuts,
361
- } as SetSideMenuShortcutsEvent);
362
- await el.updateComplete;
363
-
364
- expect(el.menuShortcuts.length).to.equal(1);
365
- });
366
- it('`el.setMenuContents`', async () => {
367
- const el = await fixture<ItemNavigator>(
368
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
369
- );
370
- expect(el.menuContents.length).to.equal(0);
371
-
372
- el.setMenuShortcuts({
373
- detail: [menuProvider],
374
- } as SetSideMenuContentsEvent);
375
- await el.updateComplete;
376
-
377
- expect(el.menuShortcuts.length).to.equal(1);
378
- });
379
- it('`el.setOpenMenu`', async () => {
380
- const el = await fixture<ItemNavigator>(
381
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
382
- );
383
-
384
- el.setOpenMenu({
385
- detail: { id: 'foo' },
386
- } as ToggleSidePanelOpenEvent);
387
- await el.updateComplete;
388
-
389
- expect(el.openMenu).to.equal('foo');
390
- expect(el.selectedMenuId).to.equal('foo');
391
-
392
- // toggles it off
393
- el.setOpenMenu({
394
- detail: { id: 'foo' },
395
- } as ToggleSidePanelOpenEvent);
396
- await el.updateComplete;
397
-
398
- expect(el.openMenu).to.be.undefined;
399
- expect(el.selectedMenuId).to.equal('');
400
- });
401
- it('`el.closeMenu`', async () => {
402
- const el = await fixture<ItemNavigator>(
403
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
404
- );
405
-
406
- el.menuOpened = true;
407
- await el.updateComplete;
408
-
409
- expect(el.menuOpened).to.be.true;
410
-
411
- el.closeMenu();
412
- await el.updateComplete;
413
-
414
- expect(el.menuOpened).to.be.false;
415
- });
416
- });
417
- });