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

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 (65) 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/menu-slider/ia-menu-slider.js +1 -1
  11. package/dist/src/menu-slider/ia-menu-slider.js.map +1 -1
  12. package/dist/src/menus/iaux-sharing-options.d.ts +28 -0
  13. package/dist/src/menus/iaux-sharing-options.js +277 -0
  14. package/dist/src/menus/iaux-sharing-options.js.map +1 -0
  15. package/dist/src/menus/iaux-viewable-files.d.ts +32 -0
  16. package/dist/src/menus/iaux-viewable-files.js +367 -0
  17. package/dist/src/menus/iaux-viewable-files.js.map +1 -0
  18. package/dist/src/menus/share-providers/email.d.ts +11 -0
  19. package/dist/src/menus/share-providers/email.js +15 -0
  20. package/dist/src/menus/share-providers/email.js.map +1 -0
  21. package/dist/src/menus/share-providers/facebook.d.ts +11 -0
  22. package/dist/src/menus/share-providers/facebook.js +15 -0
  23. package/dist/src/menus/share-providers/facebook.js.map +1 -0
  24. package/dist/src/menus/share-providers/pinterest.d.ts +11 -0
  25. package/dist/src/menus/share-providers/pinterest.js +15 -0
  26. package/dist/src/menus/share-providers/pinterest.js.map +1 -0
  27. package/dist/src/menus/share-providers/provider.d.ts +20 -0
  28. package/dist/src/menus/share-providers/provider.js +37 -0
  29. package/dist/src/menus/share-providers/provider.js.map +1 -0
  30. package/dist/src/menus/share-providers/share-provider-interface.d.ts +13 -0
  31. package/dist/src/menus/share-providers/share-provider-interface.js +2 -0
  32. package/dist/src/menus/share-providers/share-provider-interface.js.map +1 -0
  33. package/dist/src/menus/share-providers/tumblr.d.ts +11 -0
  34. package/dist/src/menus/share-providers/tumblr.js +15 -0
  35. package/dist/src/menus/share-providers/tumblr.js.map +1 -0
  36. package/dist/src/menus/share-providers/twitter.d.ts +11 -0
  37. package/dist/src/menus/share-providers/twitter.js +15 -0
  38. package/dist/src/menus/share-providers/twitter.js.map +1 -0
  39. package/dist/test/iaux-item-navigator.test.d.ts +1 -0
  40. package/dist/test/{ia-item-navigator.test.js → iaux-item-navigator.test.js} +49 -27
  41. package/dist/test/iaux-item-navigator.test.js.map +1 -0
  42. package/dist/test/iaux-sharing-options.test.d.ts +1 -0
  43. package/dist/test/iaux-sharing-options.test.js +64 -0
  44. package/dist/test/iaux-sharing-options.test.js.map +1 -0
  45. package/index.ts +9 -1
  46. package/package.json +11 -4
  47. package/src/{item-navigator.ts → iaux-item-navigator.ts} +2 -10
  48. package/src/menu-slider/ia-menu-slider.ts +1 -1
  49. package/src/menus/foo.json +84 -0
  50. package/src/menus/iaux-sharing-options.ts +281 -0
  51. package/src/menus/iaux-viewable-files.ts +377 -0
  52. package/src/menus/share-providers/email.ts +23 -0
  53. package/src/menus/share-providers/facebook.ts +23 -0
  54. package/src/menus/share-providers/pinterest.ts +23 -0
  55. package/src/menus/share-providers/provider.ts +63 -0
  56. package/src/menus/share-providers/share-provider-interface.ts +17 -0
  57. package/src/menus/share-providers/tumblr.ts +23 -0
  58. package/src/menus/share-providers/twitter.ts +23 -0
  59. package/test/ia-sharing-options.test.js +78 -0
  60. package/test/{ia-item-navigator.test.ts → iaux-item-navigator.test.ts} +49 -27
  61. package/test/iaux-sharing-options.test.ts +84 -0
  62. package/dist/src/item-navigator.js.map +0 -1
  63. package/dist/test/ia-item-navigator.test.d.ts +0 -1
  64. package/dist/test/ia-item-navigator.test.js.map +0 -1
  65. /package/dist/src/{item-navigator.d.ts → iaux-item-navigator.d.ts} +0 -0
@@ -0,0 +1,23 @@
1
+ import '@internetarchive/icon-pinterest/icon-pinterest';
2
+ import { TemplateResult, html } from 'lit';
3
+ import Provider from './provider';
4
+ import { ProviderParams } from './share-provider-interface';
5
+
6
+ export default class extends Provider {
7
+ name: string;
8
+
9
+ icon: TemplateResult;
10
+
11
+ class: string;
12
+
13
+ constructor(params: ProviderParams) {
14
+ super(params);
15
+ this.name = 'Pinterest';
16
+ this.icon = html`<ia-icon-pinterest></ia-icon-pinterest>`;
17
+ this.class = 'pinterest';
18
+ }
19
+
20
+ override get url(): string {
21
+ return `http://www.pinterest.com/pin/create/button/?url=https://${this.baseHost}/details/${this.itemPath}&description=${this.encodedDescription}+%3A+${this.encodedCreator}${this.encodedPromoCopy}`;
22
+ }
23
+ }
@@ -0,0 +1,63 @@
1
+ import { TemplateResult } from 'lit';
2
+ import { ProviderParams } from './share-provider-interface';
3
+
4
+ export default class Provider {
5
+ promoCopy: string;
6
+
7
+ description: string;
8
+
9
+ creator: string;
10
+
11
+ fileSubPrefix: string;
12
+
13
+ identifier: string;
14
+
15
+ baseHost: string;
16
+
17
+ name: string | undefined;
18
+
19
+ icon: TemplateResult | string | undefined;
20
+
21
+ class: string | undefined;
22
+
23
+ constructor(params: ProviderParams) {
24
+ this.promoCopy =
25
+ ' : Free Download, Borrow, and Streaming : Internet Archive';
26
+
27
+ this.description = params?.description || '';
28
+ this.creator = params?.creator || '';
29
+ this.fileSubPrefix = params?.fileSubPrefix || '';
30
+ this.identifier = params?.identifier || '';
31
+ this.baseHost = params?.baseHost || '';
32
+ }
33
+
34
+ get encodedDescription(): string {
35
+ return this.encodeString(this.description);
36
+ }
37
+
38
+ get encodedCreator(): string {
39
+ return this.encodeString(this.creator);
40
+ }
41
+
42
+ get encodedPromoCopy(): string {
43
+ return this.encodeString(this.promoCopy);
44
+ }
45
+
46
+ get itemPath(): string {
47
+ const encodedFileSubPrefix = this.fileSubPrefix
48
+ ? encodeURIComponent(this.fileSubPrefix)
49
+ : '';
50
+ return encodedFileSubPrefix
51
+ ? `${this.identifier}/${encodedFileSubPrefix}`
52
+ : this.identifier;
53
+ }
54
+
55
+ get url(): string {
56
+ return `https://${this.baseHost}/details/${this.itemPath}`;
57
+ }
58
+
59
+ encodeString(str: string): string {
60
+ if (!str) return '';
61
+ return encodeURIComponent(str.replace(/\s/g, '+')).replace(/%2B/g, '+');
62
+ }
63
+ }
@@ -0,0 +1,17 @@
1
+ import { TemplateResult } from 'lit';
2
+
3
+ export type ProviderParams = {
4
+ class: string;
5
+ icon: TemplateResult | string;
6
+ name: string;
7
+
8
+ promoCopy: string;
9
+ description: string;
10
+ creator: string;
11
+
12
+ // ia item
13
+ fileSubPrefix: string;
14
+ identifier: string;
15
+ baseHost: string;
16
+ itemPath: string;
17
+ };
@@ -0,0 +1,23 @@
1
+ import '@internetarchive/icon-tumblr/icon-tumblr';
2
+ import { TemplateResult, html } from 'lit';
3
+ import Provider from './provider';
4
+ import { ProviderParams } from './share-provider-interface';
5
+
6
+ export default class extends Provider {
7
+ name: string;
8
+
9
+ icon: TemplateResult;
10
+
11
+ class: string;
12
+
13
+ constructor(params: ProviderParams) {
14
+ super(params);
15
+ this.name = 'Tumblr';
16
+ this.icon = html`<ia-icon-tumblr></ia-icon-tumblr>`;
17
+ this.class = 'tumblr';
18
+ }
19
+
20
+ override get url(): string {
21
+ return `https://www.tumblr.com/share/video?embed=%3Ciframe+width%3D%22640%22+height%3D%22480%22+frameborder%3D%220%22+allowfullscreen+src%3D%22https%3A%2F%2F${this.baseHost}%2Fembed%2F%22+webkitallowfullscreen%3D%22true%22+mozallowfullscreen%3D%22true%22%26gt%3B%26lt%3B%2Fiframe%3E&name=${this.encodedDescription}+%3A+${this.encodedCreator}${this.encodedPromoCopy}`;
22
+ }
23
+ }
@@ -0,0 +1,23 @@
1
+ import '@internetarchive/icon-twitter/icon-twitter';
2
+ import { TemplateResult, html } from 'lit';
3
+ import Provider from './provider';
4
+ import { ProviderParams } from './share-provider-interface';
5
+
6
+ export default class TwitterProvider extends Provider {
7
+ name: string;
8
+
9
+ icon: TemplateResult;
10
+
11
+ class: string;
12
+
13
+ constructor(params: ProviderParams) {
14
+ super(params);
15
+ this.name = 'Twitter';
16
+ this.icon = html`<ia-icon-twitter></ia-icon-twitter>`;
17
+ this.class = 'twitter';
18
+ }
19
+
20
+ override get url(): string {
21
+ return `https://twitter.com/intent/tweet?url=https://${this.baseHost}/details/${this.itemPath}&via=internetarchive&text=${this.encodedDescription}+%3A+${this.encodedCreator}${this.encodedPromoCopy}`;
22
+ }
23
+ }
@@ -0,0 +1,78 @@
1
+ import { html, fixture, expect } from '@open-wc/testing';
2
+ import sinon from 'sinon';
3
+ import '../src/ia-sharing-options.js';
4
+
5
+ const identifier = 'goody';
6
+ const itemType = 'book';
7
+ const creator = 'Welsh, Charles';
8
+ const description = 'The history of Little Goody Two-Shoes : otherwise called Mrs. Margery Two-Shoes ... [1766 edition]';
9
+
10
+ const container = (optionalFileSubprefix = '') => (
11
+ html`<ia-sharing-options
12
+ identifier="${identifier}"
13
+ type="${itemType}"
14
+ creator="${creator}"
15
+ description="${description}"
16
+ baseHost="archive.org"
17
+ fileSubPrefix="${optionalFileSubprefix}"
18
+ ></ia-sharing-options>`
19
+ );
20
+
21
+ describe('<ia-sharing-options>', () => {
22
+ afterEach(() => {
23
+ sinon.restore();
24
+ });
25
+
26
+ it('sets default properties', async () => {
27
+ const el = await fixture(container());
28
+
29
+ expect(el.identifier).to.equal(identifier);
30
+ expect(el.type).to.equal(itemType);
31
+ expect(el.creator).to.equal(creator);
32
+ expect(el.description).to.equal(description);
33
+ });
34
+
35
+ it('renders buttons for each sharing method', async () => {
36
+ const el = await fixture(container());
37
+
38
+ await el.updateComplete;
39
+
40
+ el.sharingOptions.forEach((option) => {
41
+ const button = el.shadowRoot.querySelector(`a.${option.class}`);
42
+ expect(button).to.exist;
43
+ expect(button.getAttribute('href')).to.equal(option.url);
44
+ });
45
+ });
46
+
47
+ it('toggles visibility of embed options', async () => {
48
+ const el = await fixture(container());
49
+
50
+ el.toggleEmbedOptions(new Event('click'));
51
+ await el.updateComplete;
52
+
53
+ expect(el.embedOptionsVisible).to.equal(true);
54
+ });
55
+
56
+ it('does not show internal header by default', async () => {
57
+ const el = await fixture(container());
58
+ expect(el.shadowRoot.querySelector('header')).to.be.null;
59
+ });
60
+
61
+ it('does shows internal header when requested', async () => {
62
+ const el = await fixture(container());
63
+ el.renderHeader = true;
64
+ await el.updateComplete;
65
+ expect(el.shadowRoot.querySelector('header')).to.not.be.null;
66
+ });
67
+
68
+ it('sets file subprefix to end of share URLs if present', async () => {
69
+ const optionalFileSubprefix = 'foo- bar - 123-';
70
+ const el = await fixture(container(optionalFileSubprefix));
71
+
72
+ el.sharingOptions.forEach((option) => {
73
+ if (option.name !== 'Tumblr') {
74
+ expect(option.url).to.contain(encodeURIComponent(optionalFileSubprefix));
75
+ }
76
+ });
77
+ });
78
+ });
@@ -4,10 +4,10 @@ import Sinon from 'sinon';
4
4
 
5
5
  import { SharedResizeObserver } from '@internetarchive/shared-resize-observer';
6
6
  import { ModalManager } from '@internetarchive/modal-manager';
7
- import { ItemNavigator } from '../src/item-navigator';
8
- import '../src/item-navigator';
7
+ import { ItemNavigator } from '../src/iaux-item-navigator';
8
+ import '../src/iaux-item-navigator';
9
9
 
10
- import { ItemStub, menuProvider, shortcut } from '../test/ia-stub';
10
+ import { ItemStub, menuProvider, shortcut } from './ia-stub';
11
11
  import {
12
12
  ManageFullscreenEvent,
13
13
  ToggleSideMenuOpenEvent,
@@ -24,7 +24,9 @@ describe('ItemNavigator', () => {
24
24
  describe('Theaters', () => {
25
25
  it('shows <ia-no-theater-available> if told', async () => {
26
26
  const el = await fixture<ItemNavigator>(
27
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
27
+ html`<iaux-item-navigator
28
+ .item=${new ItemStub()}
29
+ ></iaux-item-navigator>`,
28
30
  );
29
31
  el.viewAvailable = false;
30
32
  await el.updateComplete;
@@ -33,7 +35,9 @@ describe('ItemNavigator', () => {
33
35
  });
34
36
  it('opens main slot by default', async () => {
35
37
  const el = await fixture<ItemNavigator>(
36
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
38
+ html`<iaux-item-navigator
39
+ .item=${new ItemStub()}
40
+ ></iaux-item-navigator>`,
37
41
  );
38
42
 
39
43
  expect(el.viewAvailable).to.be.true;
@@ -45,14 +49,14 @@ describe('ItemNavigator', () => {
45
49
  describe('`el.loaded`', () => {
46
50
  it('toggles the spinning loader', async () => {
47
51
  const el = await fixture<ItemNavigator>(
48
- html`<ia-item-navigator></ia-item-navigator>`,
52
+ html`<iaux-item-navigator></iaux-item-navigator>`,
49
53
  );
50
54
  expect(el.loaded).to.be.null; // initial load
51
55
  expect(el.shadowRoot?.querySelector('ia-itemnav-loader')).to.exist;
52
56
  });
53
57
  it('hides reader section if `!loaded`', async () => {
54
58
  const el = await fixture<ItemNavigator>(
55
- html`<ia-item-navigator></ia-item-navigator>`,
59
+ html`<iaux-item-navigator></iaux-item-navigator>`,
56
60
  );
57
61
 
58
62
  expect(
@@ -61,7 +65,9 @@ describe('ItemNavigator', () => {
61
65
  });
62
66
  it('shows reader when `loaded` ', async () => {
63
67
  const el = await fixture<ItemNavigator>(
64
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
68
+ html`<iaux-item-navigator
69
+ .item=${new ItemStub()}
70
+ ></iaux-item-navigator>`,
65
71
  );
66
72
 
67
73
  el.loaded = true;
@@ -75,7 +81,7 @@ describe('ItemNavigator', () => {
75
81
  });
76
82
  it('listens to `@loadingStateUpdated` to update `loaded` for <no-theater-available>', async () => {
77
83
  const el = await fixture<ItemNavigator>(
78
- html`<ia-item-navigator></ia-item-navigator>`,
84
+ html`<iaux-item-navigator></iaux-item-navigator>`,
79
85
  );
80
86
 
81
87
  await el.updateComplete;
@@ -98,9 +104,9 @@ describe('ItemNavigator', () => {
98
104
  it('uses one', async () => {
99
105
  const sharedObserver = new SharedResizeObserver();
100
106
  const el = await fixture<ItemNavigator>(
101
- html`<ia-item-navigator
107
+ html`<iaux-item-navigator
102
108
  .sharedObserver=${sharedObserver}
103
- ></ia-item-navigator>`,
109
+ ></iaux-item-navigator>`,
104
110
  );
105
111
 
106
112
  expect(el.sharedObserver).to.equal(sharedObserver);
@@ -111,9 +117,9 @@ describe('ItemNavigator', () => {
111
117
  const addObserverSpy = Sinon.spy(sharedObserver, 'addObserver');
112
118
 
113
119
  await fixture<ItemNavigator>(
114
- html`<ia-item-navigator
120
+ html`<iaux-item-navigator
115
121
  .sharedObserver=${sharedObserver}
116
- ></ia-item-navigator>`,
122
+ ></iaux-item-navigator>`,
117
123
  );
118
124
 
119
125
  expect(addObserverSpy.callCount).to.equal(2);
@@ -123,9 +129,9 @@ describe('ItemNavigator', () => {
123
129
  const removeObserverSpy = Sinon.spy(sharedObserver, 'removeObserver');
124
130
 
125
131
  const el = await fixture<ItemNavigator>(
126
- html`<ia-item-navigator
132
+ html`<iaux-item-navigator
127
133
  .sharedObserver=${sharedObserver}
128
- ></ia-item-navigator>`,
134
+ ></iaux-item-navigator>`,
129
135
  );
130
136
 
131
137
  el.disconnectedCallback();
@@ -135,7 +141,7 @@ describe('ItemNavigator', () => {
135
141
  });
136
142
  it('sets menu to overlay if container width is <= 600px', async () => {
137
143
  const el = await fixture<ItemNavigator>(
138
- html`<ia-item-navigator></ia-item-navigator>`,
144
+ html`<iaux-item-navigator></iaux-item-navigator>`,
139
145
  );
140
146
 
141
147
  expect(el.openMenuState).to.equal('shift'); // as starting point
@@ -162,7 +168,7 @@ describe('ItemNavigator', () => {
162
168
  it('uses one', async () => {
163
169
  const modal = new ModalManager();
164
170
  const el = await fixture<ItemNavigator>(
165
- html`<ia-item-navigator .modal=${modal}></ia-item-navigator>`,
171
+ html`<iaux-item-navigator .modal=${modal}></iaux-item-navigator>`,
166
172
  );
167
173
  expect(el.modal).to.equal(modal);
168
174
  });
@@ -172,7 +178,7 @@ describe('ItemNavigator', () => {
172
178
  it('creates reflected attribute `viewportinfullscreen`', async () => {
173
179
  /** to help with external styling adjustmnents */
174
180
  const el = await fixture<ItemNavigator>(
175
- html`<ia-item-navigator></ia-item-navigator>`,
181
+ html`<iaux-item-navigator></iaux-item-navigator>`,
176
182
  );
177
183
  expect(el.getAttribute('viewportinfullscreen')).to.be.null;
178
184
 
@@ -183,7 +189,7 @@ describe('ItemNavigator', () => {
183
189
  });
184
190
  it('@ViewportInFullScreen', async () => {
185
191
  const el = await fixture<ItemNavigator>(
186
- html`<ia-item-navigator></ia-item-navigator>`,
192
+ html`<iaux-item-navigator></iaux-item-navigator>`,
187
193
  );
188
194
  expect(el.viewportInFullscreen).to.be.null;
189
195
 
@@ -211,7 +217,9 @@ describe('ItemNavigator', () => {
211
217
  describe('el.menuOpened', () => {
212
218
  it('toggles side menu open', async () => {
213
219
  const el = await fixture<ItemNavigator>(
214
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
220
+ html`<iaux-item-navigator
221
+ .item=${new ItemStub()}
222
+ ></iaux-item-navigator>`,
215
223
  );
216
224
 
217
225
  el.menuContents = [menuProvider];
@@ -238,7 +246,9 @@ describe('ItemNavigator', () => {
238
246
 
239
247
  it('opens menu shortcut with `@manageSideMenuEvents`', async () => {
240
248
  const el = await fixture<ItemNavigator>(
241
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
249
+ html`<iaux-item-navigator
250
+ .item=${new ItemStub()}
251
+ ></iaux-item-navigator>`,
242
252
  );
243
253
  const detail = {
244
254
  menuId: 'fullscreen',
@@ -303,7 +313,9 @@ describe('ItemNavigator', () => {
303
313
  describe('el.menuContents', () => {
304
314
  it('draws side menu when populated', async () => {
305
315
  const el = await fixture<ItemNavigator>(
306
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
316
+ html`<iaux-item-navigator
317
+ .item=${new ItemStub()}
318
+ ></iaux-item-navigator>`,
307
319
  );
308
320
 
309
321
  el.menuContents = [menuProvider];
@@ -324,7 +336,9 @@ describe('ItemNavigator', () => {
324
336
  describe('`el.menuShortcuts`', () => {
325
337
  it('displays shortcut & toggle side menu button', async () => {
326
338
  const el = await fixture<ItemNavigator>(
327
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
339
+ html`<iaux-item-navigator
340
+ .item=${new ItemStub()}
341
+ ></iaux-item-navigator>`,
328
342
  );
329
343
 
330
344
  const anotherShortcut = {
@@ -350,7 +364,9 @@ describe('ItemNavigator', () => {
350
364
  describe('Menu events', () => {
351
365
  it('`el.setMenuShortcuts`', async () => {
352
366
  const el = await fixture<ItemNavigator>(
353
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
367
+ html`<iaux-item-navigator
368
+ .item=${new ItemStub()}
369
+ ></iaux-item-navigator>`,
354
370
  );
355
371
  expect(el.menuShortcuts.length).to.equal(0);
356
372
 
@@ -365,7 +381,9 @@ describe('ItemNavigator', () => {
365
381
  });
366
382
  it('`el.setMenuContents`', async () => {
367
383
  const el = await fixture<ItemNavigator>(
368
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
384
+ html`<iaux-item-navigator
385
+ .item=${new ItemStub()}
386
+ ></iaux-item-navigator>`,
369
387
  );
370
388
  expect(el.menuContents.length).to.equal(0);
371
389
 
@@ -378,7 +396,9 @@ describe('ItemNavigator', () => {
378
396
  });
379
397
  it('`el.setOpenMenu`', async () => {
380
398
  const el = await fixture<ItemNavigator>(
381
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
399
+ html`<iaux-item-navigator
400
+ .item=${new ItemStub()}
401
+ ></iaux-item-navigator>`,
382
402
  );
383
403
 
384
404
  el.setOpenMenu({
@@ -400,7 +420,9 @@ describe('ItemNavigator', () => {
400
420
  });
401
421
  it('`el.closeMenu`', async () => {
402
422
  const el = await fixture<ItemNavigator>(
403
- html`<ia-item-navigator .item=${new ItemStub()}></ia-item-navigator>`,
423
+ html`<iaux-item-navigator
424
+ .item=${new ItemStub()}
425
+ ></iaux-item-navigator>`,
404
426
  );
405
427
 
406
428
  el.menuOpened = true;
@@ -0,0 +1,84 @@
1
+ import { html, fixture, expect } from '@open-wc/testing';
2
+ import sinon from 'sinon';
3
+ import '../src/menus/iaux-sharing-options';
4
+ import type { IauxSharingOptions } from '../src/menus/iaux-sharing-options';
5
+
6
+ const identifier = 'goody';
7
+ const itemType = 'book';
8
+ const creator = 'Welsh, Charles';
9
+ const description =
10
+ 'The history of Little Goody Two-Shoes : otherwise called Mrs. Margery Two-Shoes ... [1766 edition]';
11
+
12
+ const container = (optionalFileSubprefix = '') =>
13
+ html`<iaux-sharing-options
14
+ identifier="${identifier}"
15
+ type="${itemType}"
16
+ creator="${creator}"
17
+ description="${description}"
18
+ baseHost="archive.org"
19
+ fileSubPrefix="${optionalFileSubprefix}"
20
+ ></iaux-sharing-options>`;
21
+
22
+ describe('<iaux-sharing-options>', () => {
23
+ afterEach(() => {
24
+ sinon.restore();
25
+ });
26
+
27
+ it('sets default properties', async () => {
28
+ const el = (await fixture(container())) as IauxSharingOptions;
29
+
30
+ expect(el.identifier).to.equal(identifier);
31
+ expect(el.type).to.equal(itemType);
32
+ expect(el.creator).to.equal(creator);
33
+ expect(el.description).to.equal(description);
34
+ });
35
+
36
+ it('renders buttons for each sharing method', async () => {
37
+ const el = (await fixture(container())) as IauxSharingOptions;
38
+
39
+ await el.updateComplete;
40
+
41
+ el.sharingOptions.forEach(option => {
42
+ const button =
43
+ el.shadowRoot && el.shadowRoot.querySelector(`a.${option.class}`);
44
+ expect(button).to.exist;
45
+ expect(button?.getAttribute('href')).to.equal(option.url);
46
+ });
47
+ });
48
+
49
+ it('toggles visibility of embed options', async () => {
50
+ const el = (await fixture(container())) as IauxSharingOptions;
51
+
52
+ el.toggleEmbedOptions(new Event('click'));
53
+ await el.updateComplete;
54
+
55
+ expect(el.embedOptionsVisible).to.equal(true);
56
+ });
57
+
58
+ it('does not show internal header by default', async () => {
59
+ const el = (await fixture(container())) as IauxSharingOptions;
60
+ expect(el.shadowRoot?.querySelector('header')).to.be.null;
61
+ });
62
+
63
+ it('does shows internal header when requested', async () => {
64
+ const el = (await fixture(container())) as IauxSharingOptions;
65
+ el.renderHeader = true;
66
+ await el.updateComplete;
67
+ expect(el.shadowRoot?.querySelector('header')).to.not.be.null;
68
+ });
69
+
70
+ it('sets file subprefix to end of share URLs if present', async () => {
71
+ const optionalFileSubprefix = 'foo- bar - 123-';
72
+ const el = (await fixture(
73
+ container(optionalFileSubprefix),
74
+ )) as IauxSharingOptions;
75
+
76
+ el.sharingOptions.forEach(option => {
77
+ if (option.name !== 'Tumblr') {
78
+ expect(option.url).to.contain(
79
+ encodeURIComponent(optionalFileSubprefix),
80
+ );
81
+ }
82
+ });
83
+ });
84
+ });
@@ -1 +0,0 @@
1
- {"version":3,"file":"item-navigator.js","sourceRoot":"","sources":["../../src/item-navigator.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n css,\n html,\n LitElement,\n PropertyValues,\n CSSResult,\n TemplateResult,\n nothing,\n} from 'lit';\nimport { customElement, property, state, query } from 'lit/decorators.js';\nimport { MetadataResponse } from '@internetarchive/search-service';\nimport {\n SharedResizeObserver,\n SharedResizeObserverResizeHandlerInterface,\n} from '@internetarchive/shared-resize-observer';\nimport { ModalManager } from '@internetarchive/modal-manager';\nimport '@internetarchive/icon-ellipses/icon-ellipses';\n\nimport './menu-slider/ia-menu-slider';\nimport './loader';\n\nimport {\n ToggleSideMenuOpenEvent,\n ToggleSidePanelOpenEvent,\n SetSideMenuContentsEvent,\n SetSideMenuShortcutsEvent,\n loadingStateUpdatedEvent,\n ManageFullscreenEvent,\n} from './interfaces/event-interfaces';\n\nimport {\n MenuProviderInterface,\n MenuShortcutInterface,\n MenuId,\n} from './interfaces/menu-interfaces';\nimport './no-theater-available';\n\n@customElement('ia-item-navigator')\nexport class ItemNavigator\n extends LitElement\n implements SharedResizeObserverResizeHandlerInterface\n{\n @property({\n type: Object,\n converter: (value: string | MetadataResponse | null): MetadataResponse => {\n if (value && typeof value === 'string') {\n return new MetadataResponse(JSON.parse(atob(value)));\n }\n return value as MetadataResponse;\n },\n })\n item?: MetadataResponse;\n\n @property({ type: Boolean }) viewAvailable: Boolean = true;\n\n @property({ type: String }) baseHost = 'archive.org';\n\n @property({\n converter: (arg: string | boolean | null) => {\n if (typeof arg === 'boolean') {\n return arg;\n }\n return arg === 'true';\n },\n })\n signedIn = false;\n\n @property({ type: Array }) menuContents: MenuProviderInterface[] = [];\n\n @property({ type: Array }) menuShortcuts: MenuShortcutInterface[] = [];\n\n @property({ type: Boolean, reflect: true, attribute: true })\n viewportInFullscreen: boolean | null = null;\n\n @property({ type: Boolean }) menuOpened = false;\n\n @property({ type: String }) openMenu?: MenuId;\n\n @property({ attribute: false }) modal?: ModalManager;\n\n @property({ attribute: false }) sharedObserver?: SharedResizeObserver;\n\n @property({ type: Boolean, reflect: true, attribute: true }) loaded:\n | true\n | null = null;\n\n @state() openMenuState: 'overlay' | 'shift' = 'shift';\n\n @query('#frame') private frame!: HTMLDivElement;\n\n @query('slot[name=\"header\"]') private headerSlot!: HTMLSlotElement;\n\n @query('slot[name=\"main\"]') private mainSlot!: HTMLSlotElement;\n\n disconnectedCallback() {\n this.removeResizeObserver();\n }\n\n updated(changed: PropertyValues) {\n if (changed.has('sharedObserver')) {\n const oldObserver = changed.get('sharedObserver') as SharedResizeObserver;\n oldObserver?.removeObserver(this.resizeObserverConfig);\n this.setResizeObserver();\n }\n }\n\n /** Shared observer */\n handleResize(entry: ResizeObserverEntry): void {\n const { width } = entry.contentRect;\n if (width <= 600) {\n this.openMenuState = 'overlay';\n return;\n }\n this.openMenuState = 'shift';\n }\n\n private setResizeObserver(): void {\n this.sharedObserver?.addObserver(this.resizeObserverConfig);\n this.sharedObserver?.addObserver({\n target: this.headerSlot,\n handler: {\n handleResize: ({ contentRect }) => {\n if (contentRect.height) {\n this.requestUpdate();\n }\n },\n },\n });\n }\n\n private removeResizeObserver(): void {\n this.sharedObserver?.removeObserver(this.resizeObserverConfig);\n }\n\n get resizeObserverConfig(): {\n handler: SharedResizeObserverResizeHandlerInterface;\n target: Element;\n } {\n return {\n handler: this,\n target: this.frame,\n };\n }\n /** End shared observer */\n\n get loaderTitle() {\n return this.viewportInFullscreen ? 'Internet Archive' : '';\n }\n\n get loadingArea() {\n return html`\n <div class=\"loading-area\">\n <div class=\"loading-view\">\n <ia-itemnav-loader\n .loaderMessage=${this.loaderTitle}\n ></ia-itemnav-loader>\n </div>\n </div>\n `;\n }\n\n slotChange(e: Event, type: 'header' | 'main'): void {\n const slottedContent = (\n e.target as HTMLSlotElement\n ).assignedNodes()?.[0] as HTMLElement;\n\n this.dispatchEvent(\n new CustomEvent('slotChange', {\n detail: { slot: slottedContent, type },\n }),\n );\n this.requestUpdate();\n }\n\n render(): TemplateResult {\n const displayReaderClass = this.loaded ? '' : 'hidden';\n const headerHeight =\n (this.headerSlot?.assignedNodes()[0] as HTMLElement)?.offsetHeight || 0;\n return html`\n <div id=\"frame\" class=${this.menuClass}>\n <slot\n name=\"header\"\n style=${`height: ${headerHeight}px`}\n @slotchange=${(e: Event) => this.slotChange(e, 'header')}\n ></slot>\n <div class=\"menu-and-reader\">\n ${this.shouldRenderMenu ? this.renderSideMenu : nothing}\n <div id=\"reader\" class=${displayReaderClass}>\n ${this.renderViewport}\n </div>\n ${!this.loaded ? this.loadingArea : nothing}\n </div>\n </div>\n `;\n }\n\n get noTheaterView() {\n return html`<ia-no-theater-available\n .identifier=${this.item?.metadata?.identifier}\n @loadingStateUpdated=${this.loadingStateUpdated}\n ></ia-no-theater-available>`;\n }\n\n get renderViewport(): TemplateResult | typeof nothing {\n if (!this.viewAvailable) {\n return this.noTheaterView;\n }\n\n const slotVisibility = !this.loaded ? 'opacity: 0;' : 'opacity: 1;';\n return html`\n <div slot=\"main\" style=${slotVisibility}>\n <slot\n name=\"main\"\n @slotchange=${(e: Event) => this.slotChange(e, 'main')}\n ></slot>\n </div>\n `;\n }\n\n loadingStateUpdated(e: loadingStateUpdatedEvent): void {\n const { loaded } = e.detail;\n this.loaded = loaded || null;\n }\n\n /** Fullscreen Management */\n manageViewportFullscreen(e: ManageFullscreenEvent): void {\n const fullscreenStatus = !!e.detail.isFullScreen;\n this.viewportInFullscreen = !fullscreenStatus ? null : fullscreenStatus;\n\n const event = new CustomEvent('fullscreenToggled', {\n detail: e.detail,\n }) as ManageFullscreenEvent;\n\n this.dispatchEvent(event);\n }\n /** End Fullscreen Management */\n\n /** Side menu */\n get shouldRenderMenu(): boolean {\n return !!this.menuContents?.length;\n }\n\n toggleMenu(): void {\n this.menuOpened = !this.menuOpened;\n }\n\n closeMenu(): void {\n this.menuOpened = false;\n }\n\n setOpenMenu(e: ToggleSidePanelOpenEvent): void {\n const { id } = e.detail;\n this.openMenu = id !== this.openMenu ? id : undefined;\n }\n\n setMenuContents(e: SetSideMenuContentsEvent): void {\n const updatedContents = [...e.detail];\n this.menuContents = updatedContents;\n }\n\n setMenuShortcuts(e: SetSideMenuShortcutsEvent) {\n this.menuShortcuts = [...e.detail];\n }\n\n /** Toggles Side Menu & Sets viewable subpanel */\n manageSideMenuEvents(e: ToggleSideMenuOpenEvent): void {\n const { menuId, action } = e.detail;\n if (!menuId) {\n return;\n }\n\n if (action === 'open') {\n this.openShortcut(menuId);\n } else if (action === 'toggle') {\n this.openMenu = menuId;\n this.toggleMenu();\n }\n }\n\n get menuToggleButton() {\n return html`\n <button\n class=\"toggle-menu\"\n @click=${this.toggleMenu}\n title=\"Toggle theater side panels\"\n >\n <div>\n <ia-icon-ellipses\n style=\"width: var(--iconWidth); height: var(--iconHeight);\"\n ></ia-icon-ellipses>\n </div>\n </button>\n `;\n }\n\n get selectedMenuId(): MenuId | '' {\n return this.openMenu || '';\n }\n\n get renderSideMenu(): TemplateResult {\n const drawerState = this.menuOpened ? '' : 'hidden';\n return html`\n <nav>\n <div class=\"minimized\">${this.shortcuts} ${this.menuToggleButton}</div>\n <div id=\"menu\" class=${drawerState}>\n <ia-menu-slider\n .menus=${this.menuContents}\n .selectedMenu=${this.selectedMenuId}\n @menuTypeSelected=${this.setOpenMenu}\n @menuSliderClosed=${this.closeMenu}\n manuallyHandleClose\n open\n ></ia-menu-slider>\n </div>\n </nav>\n `;\n }\n /** End Side menu */\n\n /** Menu Shortcuts */\n openShortcut(selectedMenuId: MenuId = ''): void {\n this.openMenu = selectedMenuId;\n this.menuOpened = true;\n }\n\n get shortcuts(): TemplateResult {\n const shortcuts = this.menuShortcuts.map(({ icon, id }) => {\n if (id === 'fullscreen') {\n return html`${icon}`;\n }\n\n return html`\n <button class=\"shortcut ${id}\" @click=\"${() => this.openShortcut(id)}\">\n ${icon}\n </button>\n `;\n });\n return html`<div class=\"shortcuts\">${shortcuts}</div>`;\n }\n /** End Menu Shortcuts */\n\n /** Misc Render */\n get menuClass(): string {\n const hasMenuOrShortcuts =\n this.menuContents?.length || this.menuShortcuts?.length;\n const drawerState = this.menuOpened && hasMenuOrShortcuts ? 'open' : '';\n const fullscreenState = this.viewportInFullscreen ? 'fullscreen' : '';\n return `${drawerState} ${fullscreenState} ${this.openMenuState}`;\n }\n\n static get styles(): CSSResult {\n const subnavWidth = css`var(--menuWidth, 320px)`;\n const transitionTiming = css`var(--animationTiming, 200ms)`;\n const transitionEffect = css`transform ${transitionTiming} ease-out`;\n const menuMargin = css`var(--theaterMenuMargin, 42px)`;\n const theaterBg = css`var(--theaterBgColor, #000)`;\n\n return css`\n :host,\n #frame,\n .menu-and-reader {\n position: relative;\n overflow: hidden;\n display: block;\n }\n\n :host,\n #frame,\n .loading-area,\n .loading-view {\n min-height: inherit;\n height: inherit;\n }\n\n slot {\n display: block;\n width: 100%;\n }\n\n slot * {\n display: block;\n height: inherit;\n }\n\n #frame {\n background-color: ${theaterBg};\n color-scheme: dark;\n display: flex;\n flex-direction: column;\n }\n\n #frame.fullscreen {\n position: fixed;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n z-index: 9;\n }\n\n .loading-view {\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .loading-area {\n width: 100%;\n }\n\n ia-itemnav-loader {\n display: block;\n width: 100%;\n }\n\n .hidden {\n display: none !important;\n }\n\n button {\n cursor: pointer;\n padding: 0;\n border: 0;\n }\n\n button:focus,\n button:active {\n outline: none;\n }\n\n .menu-and-reader {\n position: relative;\n display: flex;\n flex: 1;\n }\n\n nav button {\n background: none;\n }\n\n nav .minimized {\n background: rgba(0, 0, 0, 0.7);\n padding-top: 6px;\n position: absolute;\n width: ${menuMargin};\n z-index: 2;\n left: 0;\n border-bottom-right-radius: 5%;\n }\n\n nav .minimized button {\n width: var(--iconWidth);\n height: var(--iconHeight);\n margin-bottom: 0.2rem;\n margin: auto;\n display: inline-flex;\n vertical-align: middle;\n -webkit-box-align: center;\n align-items: center;\n -webkit-box-pack: center;\n justify-content: center;\n width: ${menuMargin};\n height: ${menuMargin};\n }\n\n nav .minimized button.toggle-menu > * {\n border: 2px solid var(--iconStrokeColor);\n border-radius: var(--iconWidth);\n width: var(--iconWidth);\n height: var(--iconHeight);\n margin: auto;\n }\n\n ia-icon-ellipses {\n width: var(--iconWidth);\n height: var(--iconHeight);\n }\n\n #menu {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n z-index: 3;\n overflow: hidden;\n transform: translateX(-${subnavWidth});\n width: ${subnavWidth};\n transform: translateX(calc(${subnavWidth} * -1));\n transition: ${transitionEffect};\n }\n\n #reader {\n position: relative;\n z-index: 1;\n transform: translateX(0);\n width: 100%;\n display: flex;\n }\n\n #reader > * {\n width: 100%;\n display: flex;\n flex: 1;\n }\n\n .open.overlay #reader {\n transition: none;\n }\n\n .open #menu {\n width: ${subnavWidth};\n transform: translateX(0);\n transition: ${transitionEffect};\n }\n\n .open.shift #reader {\n width: calc(100% - ${subnavWidth});\n margin-left: ${subnavWidth};\n transition: ${transitionEffect};\n }\n `;\n }\n}\n"]}
@@ -1 +0,0 @@
1
- import '../src/item-navigator';