@internetarchive/ia-topnav 1.3.5-alpha9 → 1.3.5
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/package.json +1 -1
- package/src/data/menus.js +6 -30
- package/src/dropdown-menu.js +0 -1
- package/src/ia-topnav.js +1 -8
- package/src/media-button.js +0 -1
- package/src/media-menu.js +2 -22
- package/src/media-slider.js +7 -21
- package/src/nav-search.js +8 -2
- package/src/primary-nav.js +18 -39
- package/src/search-menu.js +0 -30
- package/src/styles/dropdown-menu.js +0 -2
- package/src/styles/media-menu.js +5 -1
- package/src/styles/primary-nav.js +8 -15
- package/src/styles/search-menu.js +0 -5
- package/src/user-menu.js +0 -14
- package/src/lib/keyboard-navigation.js +0 -130
package/package.json
CHANGED
package/src/data/menus.js
CHANGED
|
@@ -48,10 +48,6 @@ export function buildTopNavMenus(userid = '___USERID___', localLinks = true, way
|
|
|
48
48
|
title: 'All Audio',
|
|
49
49
|
url: `${prefix}/details/audio`,
|
|
50
50
|
},
|
|
51
|
-
{
|
|
52
|
-
title: 'This Just In',
|
|
53
|
-
url: `${prefix}/search.php?query=mediatype:audio&sort=-publicdate`,
|
|
54
|
-
},
|
|
55
51
|
{
|
|
56
52
|
title: 'Grateful Dead',
|
|
57
53
|
url: `${prefix}/details/GratefulDead`,
|
|
@@ -119,10 +115,6 @@ export function buildTopNavMenus(userid = '___USERID___', localLinks = true, way
|
|
|
119
115
|
title: 'All Images',
|
|
120
116
|
url: `${prefix}/details/image`,
|
|
121
117
|
},
|
|
122
|
-
{
|
|
123
|
-
title: 'This Just In',
|
|
124
|
-
url: `${prefix}/search.php?query=mediatype:image&sort=-publicdate`,
|
|
125
|
-
},
|
|
126
118
|
{
|
|
127
119
|
title: 'Flickr Commons',
|
|
128
120
|
url: `${prefix}/details/flickrcommons`,
|
|
@@ -212,10 +204,6 @@ export function buildTopNavMenus(userid = '___USERID___', localLinks = true, way
|
|
|
212
204
|
title: 'All Software',
|
|
213
205
|
url: `${prefix}/details/software`,
|
|
214
206
|
},
|
|
215
|
-
{
|
|
216
|
-
title: 'This Just In',
|
|
217
|
-
url: `${prefix}/search.php?query=mediatype:software&sort=-publicdate`,
|
|
218
|
-
},
|
|
219
207
|
{
|
|
220
208
|
title: 'Old School Emulation',
|
|
221
209
|
url: `${prefix}/details/tosec`,
|
|
@@ -293,32 +281,24 @@ export function buildTopNavMenus(userid = '___USERID___', localLinks = true, way
|
|
|
293
281
|
],
|
|
294
282
|
},
|
|
295
283
|
texts: {
|
|
296
|
-
heading: '
|
|
284
|
+
heading: 'Texts',
|
|
297
285
|
iconLinks: [
|
|
298
|
-
{
|
|
299
|
-
title: 'Books to Borrow',
|
|
300
|
-
icon: `${prefix}/images/book-lend.png`,
|
|
301
|
-
url: `${prefix}/details/inlibrary`,
|
|
302
|
-
},
|
|
303
286
|
{
|
|
304
287
|
title: 'Open Library',
|
|
305
288
|
icon: `${prefix}/images/widgetOL.png`,
|
|
306
289
|
url: 'https://openlibrary.org/',
|
|
307
290
|
},
|
|
308
|
-
],
|
|
309
|
-
featuredLinks: [
|
|
310
291
|
{
|
|
311
|
-
title: '
|
|
312
|
-
|
|
292
|
+
title: 'American Libraries',
|
|
293
|
+
icon: `${prefix}/services/img/americana`,
|
|
294
|
+
url: `${prefix}/details/americana`,
|
|
313
295
|
},
|
|
296
|
+
],
|
|
297
|
+
featuredLinks: [
|
|
314
298
|
{
|
|
315
299
|
title: 'All Texts',
|
|
316
300
|
url: `${prefix}/details/texts`,
|
|
317
301
|
},
|
|
318
|
-
{
|
|
319
|
-
title: 'This Just In',
|
|
320
|
-
url: `${prefix}/search.php?query=mediatype:texts&sort=-publicdate`,
|
|
321
|
-
},
|
|
322
302
|
{
|
|
323
303
|
title: 'Smithsonian Libraries',
|
|
324
304
|
url: `${prefix}/details/smithsonian`,
|
|
@@ -443,10 +423,6 @@ export function buildTopNavMenus(userid = '___USERID___', localLinks = true, way
|
|
|
443
423
|
title: 'All Video',
|
|
444
424
|
url: `${prefix}/details/movies`,
|
|
445
425
|
},
|
|
446
|
-
{
|
|
447
|
-
title: 'This Just In',
|
|
448
|
-
url: `${prefix}/search.php?query=mediatype:movies&sort=-publicdate`,
|
|
449
|
-
},
|
|
450
426
|
{
|
|
451
427
|
title: 'Prelinger Archives',
|
|
452
428
|
url: `${prefix}/details/prelinger`,
|
package/src/dropdown-menu.js
CHANGED
|
@@ -57,7 +57,6 @@ class DropdownMenu extends TrackedElement {
|
|
|
57
57
|
return html`<a
|
|
58
58
|
href="${formatUrl(link.url, this.baseHost)}"
|
|
59
59
|
class="${link.class}"
|
|
60
|
-
tabindex="${this.open ? '' : '-1'}"
|
|
61
60
|
@click=${this.trackClick}
|
|
62
61
|
data-event-click-tracking="${this.config.eventCategory}|Nav${link.analyticsEvent}"
|
|
63
62
|
aria-label=${calloutText ? `New feature: ${link.title}` : nothing}>
|
package/src/ia-topnav.js
CHANGED
|
@@ -62,7 +62,6 @@ export default class IATopNav extends LitElement {
|
|
|
62
62
|
username: { type: String },
|
|
63
63
|
userProfileImagePath: { type: String },
|
|
64
64
|
secondIdentitySlotMode: { type: String },
|
|
65
|
-
currentTab: { type: Object },
|
|
66
65
|
};
|
|
67
66
|
}
|
|
68
67
|
|
|
@@ -78,12 +77,11 @@ export default class IATopNav extends LitElement {
|
|
|
78
77
|
this.searchIn = '';
|
|
79
78
|
this.selectedMenuOption = '';
|
|
80
79
|
this.secondIdentitySlotMode = '';
|
|
81
|
-
this.currentTab = {};
|
|
82
80
|
}
|
|
83
81
|
|
|
84
82
|
updated(props) {
|
|
85
83
|
if (props.has('username') || props.has('localLinks') || props.has('baseHost') ||
|
|
86
|
-
|
|
84
|
+
props.has('waybackPagesArchived') || props.has('itemIdentifier')) {
|
|
87
85
|
this.menuSetup();
|
|
88
86
|
}
|
|
89
87
|
}
|
|
@@ -201,7 +199,6 @@ export default class IATopNav extends LitElement {
|
|
|
201
199
|
tabindex="${this.userMenuTabIndex}"
|
|
202
200
|
@menuToggled=${this.menuToggled}
|
|
203
201
|
@trackClick=${this.trackClick}
|
|
204
|
-
@moveFocusToOthers=${(e) => this.currentTab = e.detail}
|
|
205
202
|
></user-menu>
|
|
206
203
|
`;
|
|
207
204
|
}
|
|
@@ -277,7 +274,6 @@ export default class IATopNav extends LitElement {
|
|
|
277
274
|
.selectedMenuOption=${this.selectedMenuOption}
|
|
278
275
|
.username=${this.username}
|
|
279
276
|
.userProfileImagePath=${this.userProfileImagePath}
|
|
280
|
-
.currentTab=${this.currentTab}
|
|
281
277
|
?hideSearch=${this.hideSearch}
|
|
282
278
|
@mediaTypeSelected=${this.mediaTypeSelected}
|
|
283
279
|
@toggleSearchMenu=${this.toggleSearchMenu}
|
|
@@ -293,8 +289,6 @@ export default class IATopNav extends LitElement {
|
|
|
293
289
|
.selectedMenuOption=${this.selectedMenuOption}
|
|
294
290
|
.mediaSliderOpen=${this.mediaSliderOpen}
|
|
295
291
|
.menus=${this.menus}
|
|
296
|
-
tabindex="${this.mediaSliderOpen ? '1' : ''}"
|
|
297
|
-
@moveFocusToOthers=${(e) => this.currentTab = e.detail}
|
|
298
292
|
></media-slider>
|
|
299
293
|
</div>
|
|
300
294
|
${this.username ? this.userMenu : this.signedOutDropdown}
|
|
@@ -311,7 +305,6 @@ export default class IATopNav extends LitElement {
|
|
|
311
305
|
<desktop-subnav
|
|
312
306
|
.baseHost=${this.baseHost}
|
|
313
307
|
.menuItems=${this.desktopSubnavMenuItems}
|
|
314
|
-
@focus=${this.closeMenus}
|
|
315
308
|
></desktop-subnav>
|
|
316
309
|
<div id="close-layer" class="${this.closeLayerClass}" @click=${this.closeMenus}></div>
|
|
317
310
|
`;
|
package/src/media-button.js
CHANGED
|
@@ -103,7 +103,6 @@ class MediaButton extends TrackedElement {
|
|
|
103
103
|
@click=${this.followable ? this.trackClick : this.onClick}
|
|
104
104
|
data-event-click-tracking="${this.analyticsEvent}"
|
|
105
105
|
title="${this.tooltipPrefix} ${this.mediatype} menu"
|
|
106
|
-
tabindex="${this.openMenu === 'media' ? '' : '0'}"
|
|
107
106
|
>
|
|
108
107
|
${this.menuItem}
|
|
109
108
|
</a>
|
package/src/media-menu.js
CHANGED
|
@@ -15,7 +15,7 @@ const menuSelection = [
|
|
|
15
15
|
icon: 'texts',
|
|
16
16
|
menu: 'texts',
|
|
17
17
|
href: '/details/texts',
|
|
18
|
-
label: '
|
|
18
|
+
label: 'Texts',
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
icon: 'video',
|
|
@@ -67,7 +67,6 @@ class MediaMenu extends LitElement {
|
|
|
67
67
|
config: { type: Object },
|
|
68
68
|
openMenu: { type: String },
|
|
69
69
|
selectedMenuOption: { type: String },
|
|
70
|
-
currentTab: { type: Object },
|
|
71
70
|
};
|
|
72
71
|
}
|
|
73
72
|
|
|
@@ -76,25 +75,6 @@ class MediaMenu extends LitElement {
|
|
|
76
75
|
this.config = {};
|
|
77
76
|
this.openMenu = '';
|
|
78
77
|
this.selectedMenuOption = '';
|
|
79
|
-
this.currentTab = {};
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
updated(props) {
|
|
83
|
-
if (props.has('currentTab')) {
|
|
84
|
-
const mediaButtons = Array.from(this.shadowRoot.querySelectorAll('media-button'));
|
|
85
|
-
|
|
86
|
-
mediaButtons.map((button, index) => {
|
|
87
|
-
const linkItem = button.shadowRoot.querySelector('a.menu-item');
|
|
88
|
-
if (linkItem) {
|
|
89
|
-
if (linkItem.classList.contains(`${this.selectedMenuOption}`)) {
|
|
90
|
-
linkItem.classList.remove('selected');
|
|
91
|
-
linkItem.blur();
|
|
92
|
-
|
|
93
|
-
mediaButtons[this.currentTab.moveTo === 'next' ? index + 1 : index - 1].shadowRoot.querySelector('a.menu-item').focus();
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
78
|
}
|
|
99
79
|
|
|
100
80
|
get mediaMenuOptionsTemplate() {
|
|
@@ -116,7 +96,6 @@ class MediaMenu extends LitElement {
|
|
|
116
96
|
.mediatype=${menu}
|
|
117
97
|
.openMenu=${this.openMenu}
|
|
118
98
|
.selected=${selected}
|
|
119
|
-
.selectedMenuOption=${this.selectedMenuOption}
|
|
120
99
|
data-mediatype="${menu}"
|
|
121
100
|
></media-button>
|
|
122
101
|
`;
|
|
@@ -138,6 +117,7 @@ class MediaMenu extends LitElement {
|
|
|
138
117
|
<div class="overflow-clip">
|
|
139
118
|
<nav
|
|
140
119
|
class="media-menu-inner"
|
|
120
|
+
aria-hidden="${!this.menuOpened}"
|
|
141
121
|
aria-expanded="${this.menuOpened}"
|
|
142
122
|
>
|
|
143
123
|
<div class="menu-group">
|
package/src/media-slider.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { LitElement, html } from 'https://offshoot.prod.archive.org/lit.js';
|
|
2
2
|
import './media-subnav.js';
|
|
3
3
|
import mediaSliderCSS from './styles/media-slider.js';
|
|
4
|
-
import KeyboardNavigation from './lib/keyboard-navigation.js';
|
|
5
4
|
|
|
6
5
|
class MediaSlider extends LitElement {
|
|
7
6
|
static get styles() {
|
|
@@ -27,19 +26,6 @@ class MediaSlider extends LitElement {
|
|
|
27
26
|
this.selectedMenuOption = 'texts';
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
updated(props) {
|
|
31
|
-
if (props.has('selectedMenuOption') && this.selectedMenuOption) {
|
|
32
|
-
const container = this.shadowRoot?.querySelector('.has-focused')?.shadowRoot;
|
|
33
|
-
|
|
34
|
-
if (container) {
|
|
35
|
-
const keyboardNavigation = new KeyboardNavigation(container, this.selectedMenuOption);
|
|
36
|
-
this.addEventListener('keydown', keyboardNavigation.handleKeyDown);
|
|
37
|
-
this.removeEventListener('keydown', this.previousKeydownListener);
|
|
38
|
-
this.previousKeydownListener = keyboardNavigation.handleKeyDown;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
29
|
shouldUpdate() {
|
|
44
30
|
const scrollPane = this.shadowRoot ? this.shadowRoot.querySelector('.information-menu') : null;
|
|
45
31
|
|
|
@@ -61,49 +47,49 @@ class MediaSlider extends LitElement {
|
|
|
61
47
|
<media-subnav
|
|
62
48
|
.baseHost=${this.baseHost}
|
|
63
49
|
.config=${this.config}
|
|
64
|
-
class="${this.selectedMenuOption === 'audio' ? '
|
|
50
|
+
class="${this.selectedMenuOption === 'audio' ? '' : 'hidden'}"
|
|
65
51
|
menu="audio"
|
|
66
52
|
.menuItems=${this.menus.audio}
|
|
67
53
|
></media-subnav>
|
|
68
54
|
<media-subnav
|
|
69
55
|
.baseHost=${this.baseHost}
|
|
70
56
|
.config=${this.config}
|
|
71
|
-
class="${this.selectedMenuOption === 'images' ? '
|
|
57
|
+
class="${this.selectedMenuOption === 'images' ? '' : 'hidden'}"
|
|
72
58
|
menu="images"
|
|
73
59
|
.menuItems=${this.menus.images}
|
|
74
60
|
></media-subnav>
|
|
75
61
|
<media-subnav
|
|
76
62
|
.baseHost=${this.baseHost}
|
|
77
63
|
.config=${this.config}
|
|
78
|
-
class="${this.selectedMenuOption === 'software' ? '
|
|
64
|
+
class="${this.selectedMenuOption === 'software' ? '' : 'hidden'}"
|
|
79
65
|
menu="software"
|
|
80
66
|
.menuItems=${this.menus.software}
|
|
81
67
|
></media-subnav>
|
|
82
68
|
<media-subnav
|
|
83
69
|
.baseHost=${this.baseHost}
|
|
84
70
|
.config=${this.config}
|
|
85
|
-
class="${this.selectedMenuOption === 'texts' ? '
|
|
71
|
+
class="${this.selectedMenuOption === 'texts' ? '' : 'hidden'}"
|
|
86
72
|
menu="texts"
|
|
87
73
|
.menuItems=${this.menus.texts}
|
|
88
74
|
></media-subnav>
|
|
89
75
|
<media-subnav
|
|
90
76
|
.baseHost=${this.baseHost}
|
|
91
77
|
.config=${this.config}
|
|
92
|
-
class="${this.selectedMenuOption === 'video' ? '
|
|
78
|
+
class="${this.selectedMenuOption === 'video' ? '' : 'hidden'}"
|
|
93
79
|
menu="video"
|
|
94
80
|
.menuItems=${this.menus.video}
|
|
95
81
|
></media-subnav>
|
|
96
82
|
<media-subnav
|
|
97
83
|
.baseHost=${this.baseHost}
|
|
98
84
|
.config=${this.config}
|
|
99
|
-
class="${this.selectedMenuOption === 'web' ? '
|
|
85
|
+
class="${this.selectedMenuOption === 'web' ? '' : 'hidden'}"
|
|
100
86
|
menu="web"
|
|
101
87
|
.menuItems=${this.menus.web}
|
|
102
88
|
></media-subnav>
|
|
103
89
|
<media-subnav
|
|
104
90
|
.baseHost=${this.baseHost}
|
|
105
91
|
.config=${this.config}
|
|
106
|
-
class="${this.selectedMenuOption === 'more' ? '
|
|
92
|
+
class="${this.selectedMenuOption === 'more' ? '' : 'hidden'}"
|
|
107
93
|
menu="more"
|
|
108
94
|
.menuItems=${this.menus.more}
|
|
109
95
|
></media-subnav>
|
package/src/nav-search.js
CHANGED
|
@@ -34,6 +34,13 @@ class NavSearch extends TrackedElement {
|
|
|
34
34
|
this.initSearchBetaOptIn();
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
updated() {
|
|
38
|
+
if (this.open) {
|
|
39
|
+
this.shadowRoot.querySelector('[name=query]').focus();
|
|
40
|
+
}
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
|
|
37
44
|
initSearchBetaOptIn() {
|
|
38
45
|
this.inSearchBeta = !!window.localStorage?.getItem('SearchBeta-opt-in') ||
|
|
39
46
|
!!window.localStorage?.getItem('SearchBeta-launched');
|
|
@@ -98,14 +105,13 @@ class NavSearch extends TrackedElement {
|
|
|
98
105
|
class="search-field"
|
|
99
106
|
placeholder="Search"
|
|
100
107
|
autocomplete="off"
|
|
101
|
-
value=${this.searchQuery || ''}
|
|
102
108
|
@focus=${this.toggleSearchMenu}
|
|
109
|
+
value=${this.searchQuery || ''}
|
|
103
110
|
/>
|
|
104
111
|
${this.searchInsideInput}
|
|
105
112
|
<button
|
|
106
113
|
type="submit"
|
|
107
114
|
class="search"
|
|
108
|
-
tabindex="-1"
|
|
109
115
|
data-event-click-tracking="${this.config.eventCategory}|NavSearchClose"
|
|
110
116
|
>
|
|
111
117
|
${icons.search}
|
package/src/primary-nav.js
CHANGED
|
@@ -31,7 +31,6 @@ class PrimaryNav extends TrackedElement {
|
|
|
31
31
|
userMenuOpen: { type: Boolean },
|
|
32
32
|
username: { type: String },
|
|
33
33
|
userProfileImagePath: { type: String },
|
|
34
|
-
currentTab: { type: Object },
|
|
35
34
|
};
|
|
36
35
|
}
|
|
37
36
|
|
|
@@ -45,7 +44,6 @@ class PrimaryNav extends TrackedElement {
|
|
|
45
44
|
this.userMenuOpen = false;
|
|
46
45
|
this.mediaBaseHost = 'https://archive.org';
|
|
47
46
|
this.secondIdentitySlotMode = '';
|
|
48
|
-
this.currentTab = {};
|
|
49
47
|
}
|
|
50
48
|
|
|
51
49
|
toggleMediaMenu(e) {
|
|
@@ -81,21 +79,6 @@ class PrimaryNav extends TrackedElement {
|
|
|
81
79
|
);
|
|
82
80
|
}
|
|
83
81
|
|
|
84
|
-
updated(props) {
|
|
85
|
-
const { currentTab } = this;
|
|
86
|
-
const isUserMenuTab = currentTab && currentTab.mediatype === 'usermenu';
|
|
87
|
-
if (props.has('currentTab') && isUserMenuTab) {
|
|
88
|
-
console.log(currentTab)
|
|
89
|
-
const focusElement = currentTab.moveTo === 'next'
|
|
90
|
-
? this.shadowRoot.querySelector('a.upload')
|
|
91
|
-
: this.shadowRoot.querySelector('.media-menu-container');
|
|
92
|
-
|
|
93
|
-
if (focusElement) {
|
|
94
|
-
focusElement.focus();
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
82
|
get userIcon() {
|
|
100
83
|
const userMenuClass = this.openMenu === 'user' ? 'active' : '';
|
|
101
84
|
const userMenuToolTip = this.openMenu === 'user' ? 'Close user menu' : 'Expand user menu';
|
|
@@ -169,11 +152,7 @@ class PrimaryNav extends TrackedElement {
|
|
|
169
152
|
}
|
|
170
153
|
|
|
171
154
|
get uploadButtonTemplate() {
|
|
172
|
-
return html
|
|
173
|
-
<a href="${formatUrl('/create', this.baseHost)}"
|
|
174
|
-
class="upload"
|
|
175
|
-
@focus=${this.toggleMediaMenu}
|
|
176
|
-
>
|
|
155
|
+
return html`<a href="${formatUrl('/create', this.baseHost)}" class="upload">
|
|
177
156
|
${icons.upload}
|
|
178
157
|
<span>Upload</span>
|
|
179
158
|
</a>`;
|
|
@@ -202,15 +181,6 @@ class PrimaryNav extends TrackedElement {
|
|
|
202
181
|
const mediaMenuTabIndex = this.openMenu === 'media' ? '' : '-1';
|
|
203
182
|
return html`
|
|
204
183
|
<nav class=${this.hideSearch ? 'hide-search' : nothing}>
|
|
205
|
-
<button
|
|
206
|
-
class="hamburger"
|
|
207
|
-
@click="${this.toggleMediaMenu}"
|
|
208
|
-
data-event-click-tracking="${this.config.eventCategory}|NavHamburger"
|
|
209
|
-
title="Open main menu"
|
|
210
|
-
>
|
|
211
|
-
<icon-hamburger ?active=${this.openMenu === 'media'}></icon-hamburger>
|
|
212
|
-
</button>
|
|
213
|
-
|
|
214
184
|
<div class=${`branding ${this.secondLogoClass}`}>
|
|
215
185
|
<a
|
|
216
186
|
href=${formatUrl('/', this.baseHost)}
|
|
@@ -218,25 +188,34 @@ class PrimaryNav extends TrackedElement {
|
|
|
218
188
|
data-event-click-tracking="${this.config.eventCategory}|NavHome"
|
|
219
189
|
title="Go home"
|
|
220
190
|
class="link-home"
|
|
221
|
-
tabindex="-1"
|
|
222
191
|
>${icons.iaLogo}${logoWordmarkStacked}</a
|
|
223
192
|
>
|
|
224
193
|
${this.secondLogoSlot}
|
|
225
194
|
</div>
|
|
195
|
+
|
|
196
|
+
<div class="right-side-section">
|
|
197
|
+
${this.mobileDonateHeart}
|
|
198
|
+
${this.searchMenu}
|
|
199
|
+
${this.uploadButtonTemplate}
|
|
200
|
+
${this.userStateTemplate}
|
|
201
|
+
</div>
|
|
226
202
|
<media-menu
|
|
227
203
|
.baseHost=${this.baseHost}
|
|
228
204
|
.config=${this.config}
|
|
229
205
|
?mediaMenuAnimate="${this.mediaMenuAnimate}"
|
|
206
|
+
tabindex="${mediaMenuTabIndex}"
|
|
230
207
|
.selectedMenuOption=${this.selectedMenuOption}
|
|
231
208
|
.openMenu=${this.openMenu}
|
|
232
|
-
.currentTab=${this.currentTab}
|
|
233
209
|
></media-menu>
|
|
234
|
-
<
|
|
235
|
-
|
|
236
|
-
${this.
|
|
237
|
-
|
|
238
|
-
${this.
|
|
239
|
-
|
|
210
|
+
<button
|
|
211
|
+
class="hamburger"
|
|
212
|
+
@click="${this.toggleMediaMenu}"
|
|
213
|
+
tabindex="1"
|
|
214
|
+
data-event-click-tracking="${this.config.eventCategory}|NavHamburger"
|
|
215
|
+
title="Open main menu"
|
|
216
|
+
>
|
|
217
|
+
<icon-hamburger ?active=${this.openMenu === 'media'}></icon-hamburger>
|
|
218
|
+
</button>
|
|
240
219
|
</nav>
|
|
241
220
|
`;
|
|
242
221
|
}
|
package/src/search-menu.js
CHANGED
|
@@ -29,36 +29,6 @@ class SearchMenu extends TrackedElement {
|
|
|
29
29
|
this.selectedSearchType = '';
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
firstUpdated() {
|
|
33
|
-
this.shadowRoot.addEventListener('keydown', e => this.handleKeyDownEvent(e));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
disconnectedCallback() {
|
|
37
|
-
// Clean up event listener when the element is removed
|
|
38
|
-
this.shadowRoot.removeEventListener('keydown', e => this.handleKeyDownEvent(e));
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
handleKeyDownEvent(e) {
|
|
42
|
-
const searchTypes = this.shadowRoot.querySelectorAll('.search-menu-inner label input[type=radio]');
|
|
43
|
-
|
|
44
|
-
const length = searchTypes.length - 1;
|
|
45
|
-
if (!length) return;
|
|
46
|
-
|
|
47
|
-
const searchTypeHandler = (index) => {
|
|
48
|
-
e.preventDefault();
|
|
49
|
-
const searchType = searchTypes[index];
|
|
50
|
-
searchType.checked = true;
|
|
51
|
-
searchType.dispatchEvent(new Event('change'));
|
|
52
|
-
searchType.focus();
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
if (e.key === 'Home') {
|
|
56
|
-
searchTypeHandler(0);
|
|
57
|
-
} else if (e.key === 'End') {
|
|
58
|
-
searchTypeHandler(length);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
32
|
selectSearchType(e) {
|
|
63
33
|
this.selectedSearchType = e.target.value;
|
|
64
34
|
}
|
|
@@ -92,7 +92,6 @@ export default css`
|
|
|
92
92
|
|
|
93
93
|
@media (min-width: 890px) {
|
|
94
94
|
nav {
|
|
95
|
-
display: flex;
|
|
96
95
|
overflow: visible;
|
|
97
96
|
top: 0;
|
|
98
97
|
left: auto;
|
|
@@ -147,7 +146,6 @@ export default css`
|
|
|
147
146
|
a:focus {
|
|
148
147
|
color: var(--linkHoverColor);
|
|
149
148
|
background: var(--linkColor);
|
|
150
|
-
outline: none;
|
|
151
149
|
}
|
|
152
150
|
|
|
153
151
|
.initial,
|
package/src/styles/media-menu.js
CHANGED
|
@@ -23,6 +23,10 @@ export default css`
|
|
|
23
23
|
|
|
24
24
|
/* Mobile view styles */
|
|
25
25
|
@media (max-width: 889px) {
|
|
26
|
+
.media-menu-container {
|
|
27
|
+
position: relative;
|
|
28
|
+
}
|
|
29
|
+
|
|
26
30
|
.media-menu-inner {
|
|
27
31
|
position: absolute;
|
|
28
32
|
width: 100%;
|
|
@@ -35,7 +39,7 @@ export default css`
|
|
|
35
39
|
.overflow-clip {
|
|
36
40
|
position: absolute;
|
|
37
41
|
z-index: -1; /** needs to be under the navigation, otherwise it intercepts clicks */
|
|
38
|
-
top:
|
|
42
|
+
top: 0;
|
|
39
43
|
left: 0;
|
|
40
44
|
height: 0;
|
|
41
45
|
width: 100%;
|
|
@@ -9,7 +9,8 @@ export default css`
|
|
|
9
9
|
|
|
10
10
|
nav {
|
|
11
11
|
position: relative;
|
|
12
|
-
display:
|
|
12
|
+
display: -ms-grid;
|
|
13
|
+
display: grid;
|
|
13
14
|
height: 4rem;
|
|
14
15
|
grid-template-areas: 'hamburger empty heart search user';
|
|
15
16
|
-ms-grid-columns: 4rem minmax(1rem, 100%) 4rem 4rem 4rem;
|
|
@@ -28,7 +29,6 @@ export default css`
|
|
|
28
29
|
|
|
29
30
|
.right-side-section {
|
|
30
31
|
display: flex;
|
|
31
|
-
margin-left: auto;
|
|
32
32
|
user-select: none;
|
|
33
33
|
}
|
|
34
34
|
button {
|
|
@@ -86,9 +86,6 @@ export default css`
|
|
|
86
86
|
fill: var(--activeColor);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
.mobile-donate-link {
|
|
90
|
-
display: inline-block;
|
|
91
|
-
}
|
|
92
89
|
.mobile-donate-link svg {
|
|
93
90
|
height: 4rem;
|
|
94
91
|
width: 4rem;
|
|
@@ -154,8 +151,7 @@ export default css`
|
|
|
154
151
|
height: 100%;
|
|
155
152
|
}
|
|
156
153
|
|
|
157
|
-
.user-menu:hover
|
|
158
|
-
.user-menu:focus {
|
|
154
|
+
.user-menu:hover {
|
|
159
155
|
color: var(--linkHoverColor);
|
|
160
156
|
}
|
|
161
157
|
|
|
@@ -191,13 +187,6 @@ export default css`
|
|
|
191
187
|
slot[name='opt-sec-logo'] {
|
|
192
188
|
display: none;
|
|
193
189
|
}
|
|
194
|
-
|
|
195
|
-
.right-side-section {
|
|
196
|
-
display: initial;
|
|
197
|
-
}
|
|
198
|
-
.right-side-section .user-info {
|
|
199
|
-
float: right;
|
|
200
|
-
}
|
|
201
190
|
}
|
|
202
191
|
|
|
203
192
|
@media (min-width: 890px) {
|
|
@@ -206,8 +195,12 @@ export default css`
|
|
|
206
195
|
--userIconHeight: 3.2rem;
|
|
207
196
|
}
|
|
208
197
|
|
|
198
|
+
.right-side-section {
|
|
199
|
+
display: contents;
|
|
200
|
+
}
|
|
201
|
+
|
|
209
202
|
nav {
|
|
210
|
-
display:
|
|
203
|
+
display: block;
|
|
211
204
|
z-index: 4;
|
|
212
205
|
height: 5rem;
|
|
213
206
|
padding-right: 1.5rem;
|
|
@@ -43,9 +43,6 @@ export default css`
|
|
|
43
43
|
.advanced-search {
|
|
44
44
|
text-decoration: none;
|
|
45
45
|
color: var(--linkColor);
|
|
46
|
-
line-height: normal;
|
|
47
|
-
padding: 0.5rem;
|
|
48
|
-
margin-top: 5px;
|
|
49
46
|
}
|
|
50
47
|
|
|
51
48
|
@media (min-width: 890px) {
|
|
@@ -89,8 +86,6 @@ export default css`
|
|
|
89
86
|
|
|
90
87
|
label {
|
|
91
88
|
padding: 0;
|
|
92
|
-
font-weight: normal;
|
|
93
|
-
margin: 0;
|
|
94
89
|
}
|
|
95
90
|
|
|
96
91
|
label + label {
|
package/src/user-menu.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { html } from 'https://offshoot.prod.archive.org/lit.js';
|
|
2
2
|
import DropdownMenu from './dropdown-menu.js';
|
|
3
3
|
import userMenuCSS from './styles/user-menu.js';
|
|
4
|
-
import KeyboardNavigation from './lib/keyboard-navigation.js';
|
|
5
4
|
|
|
6
5
|
class UserMenu extends DropdownMenu {
|
|
7
6
|
static get styles() {
|
|
@@ -22,19 +21,6 @@ class UserMenu extends DropdownMenu {
|
|
|
22
21
|
this.username = '';
|
|
23
22
|
}
|
|
24
23
|
|
|
25
|
-
updated(props) {
|
|
26
|
-
if (props.has('open') && this.open) {
|
|
27
|
-
const container = this.shadowRoot?.querySelector('.nav-container');
|
|
28
|
-
|
|
29
|
-
if (container) {
|
|
30
|
-
const keyboardNavigation = new KeyboardNavigation(container, 'usermenu');
|
|
31
|
-
this.addEventListener('keydown', keyboardNavigation.handleKeyDown);
|
|
32
|
-
this.removeEventListener('keydown', this.previousKeydownListener);
|
|
33
|
-
this.previousKeydownListener = keyboardNavigation.handleKeyDown;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
24
|
render() {
|
|
39
25
|
return html`
|
|
40
26
|
<div class="nav-container">
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export default class KeyboardNavigation {
|
|
5
|
-
/**
|
|
6
|
-
* Constructor for the KeyboardNavigation class.
|
|
7
|
-
* @param {HTMLElement} elementsContainer - The container element that holds the focusable elements.
|
|
8
|
-
* @param {string} menuOption - The type of menu option ('web' or 'usermenu').
|
|
9
|
-
*/
|
|
10
|
-
constructor(elementsContainer, menuOption) {
|
|
11
|
-
this.elementsContainer = elementsContainer;
|
|
12
|
-
this.menuOption = menuOption;
|
|
13
|
-
this.focusableElements = this.getFocusableElements();
|
|
14
|
-
this.focusedIndex = this.getInitialFocusedIndex();
|
|
15
|
-
|
|
16
|
-
this.focusableElements[this.focusedIndex]?.focus();
|
|
17
|
-
this.handleKeyDown = this.handleKeyDown.bind(this);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Returns the initial focused index based on the menu option.
|
|
22
|
-
* @returns {number} The initial focused index (0 for 'web', 1 for 'usermenu').
|
|
23
|
-
*/
|
|
24
|
-
getInitialFocusedIndex() {
|
|
25
|
-
return this.menuOption === 'usermenu' ? 1 : 0;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Gets an array of focusable elements within the container.
|
|
30
|
-
* @returns {HTMLElement[]} An array of focusable elements.
|
|
31
|
-
*/
|
|
32
|
-
getFocusableElements() {
|
|
33
|
-
const focusableTagSelectors = 'a[href], button, input, textarea, select, details, [tabindex]:not([tabindex="-1"])';
|
|
34
|
-
const isDisabledOrHidden = el => !el.hasAttribute('disabled') && !el.getAttribute('aria-hidden');
|
|
35
|
-
|
|
36
|
-
let elements;
|
|
37
|
-
if (this.menuOption === 'web') {
|
|
38
|
-
const waybackSlider = this.elementsContainer.querySelector('wayback-slider').shadowRoot;
|
|
39
|
-
const waybackSearch = waybackSlider.querySelector('wayback-search');
|
|
40
|
-
const waybackSearchElements = Array.from(waybackSearch.shadowRoot.querySelectorAll(focusableTagSelectors));
|
|
41
|
-
|
|
42
|
-
const normalElements = Array.from(waybackSlider.querySelectorAll(focusableTagSelectors));
|
|
43
|
-
|
|
44
|
-
const savePageForm = waybackSlider.querySelector('save-page-form');
|
|
45
|
-
const savePageFormElements = Array.from(savePageForm.shadowRoot.querySelectorAll(focusableTagSelectors));
|
|
46
|
-
|
|
47
|
-
elements = [...waybackSearchElements, ...normalElements, ...savePageFormElements];
|
|
48
|
-
} else {
|
|
49
|
-
elements = this.elementsContainer.querySelectorAll(focusableTagSelectors);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return Array.from(elements).filter(isDisabledOrHidden);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Handles keyboard events and focuses the appropriate element.
|
|
57
|
-
* @param {KeyboardEvent} event - The keyboard event object.
|
|
58
|
-
*/
|
|
59
|
-
handleKeyDown(event) {
|
|
60
|
-
const { key } = event;
|
|
61
|
-
const isArrowKey = ['ArrowDown', 'ArrowRight', 'ArrowUp', 'ArrowLeft'].includes(key);
|
|
62
|
-
const isTabKey = key === 'Tab';
|
|
63
|
-
|
|
64
|
-
if (isArrowKey) {
|
|
65
|
-
this.handleArrowKey(key);
|
|
66
|
-
event.preventDefault();
|
|
67
|
-
} else if (isTabKey) {
|
|
68
|
-
this.handleTabKey(event);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Handles arrow key events and focuses the next or previous element.
|
|
74
|
-
* @param {string} key - The key that was pressed ('ArrowDown', 'ArrowRight', 'ArrowUp', or 'ArrowLeft').
|
|
75
|
-
*/
|
|
76
|
-
handleArrowKey(key) {
|
|
77
|
-
const isDownOrRight = ['ArrowDown', 'ArrowRight'].includes(key);
|
|
78
|
-
isDownOrRight ? this.focusNext() : this.focusPrevious();
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Focuses the previous focusable element in the container.
|
|
83
|
-
*/
|
|
84
|
-
focusPrevious() {
|
|
85
|
-
if (this.focusableElements.length === 0) return;
|
|
86
|
-
this.focusedIndex = (this.focusedIndex - 1 + this.focusableElements.length) % this.focusableElements.length;
|
|
87
|
-
this.focusableElements[this.focusedIndex]?.focus();
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Focuses the next focusable element in the container.
|
|
92
|
-
*/
|
|
93
|
-
focusNext() {
|
|
94
|
-
if (this.focusableElements.length === 0) return;
|
|
95
|
-
this.focusedIndex = (this.focusedIndex + 1) % this.focusableElements.length;
|
|
96
|
-
this.focusableElements[this.focusedIndex]?.focus();
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Handles the Tab key event and focuses the next or previous menu item.
|
|
101
|
-
* @param {KeyboardEvent} event - The keyboard event object.
|
|
102
|
-
*/
|
|
103
|
-
handleTabKey(event) {
|
|
104
|
-
console.log(this.menuOption)
|
|
105
|
-
if (this.menuOption) {
|
|
106
|
-
const isShiftPressed = event.shiftKey;
|
|
107
|
-
this.focusNextMenuItem(isShiftPressed);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
this.focusableElements[this.focusedIndex]?.blur();
|
|
111
|
-
event.preventDefault();
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Focuses the next or previous menu item based on the provided flag.
|
|
116
|
-
* @param {boolean} isPrevious - A flag indicating whether to focus the previous menu item.
|
|
117
|
-
*/
|
|
118
|
-
focusNextMenuItem(isPrevious = false) {
|
|
119
|
-
this.elementsContainer.dispatchEvent(
|
|
120
|
-
new CustomEvent('moveFocusToOthers', {
|
|
121
|
-
bubbles: true,
|
|
122
|
-
composed: true,
|
|
123
|
-
detail: {
|
|
124
|
-
mediatype: this.menuOption,
|
|
125
|
-
moveTo: isPrevious ? 'prev' : 'next',
|
|
126
|
-
},
|
|
127
|
-
})
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
}
|