@internetarchive/ia-topnav 1.3.5-alpha8 → 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 +0 -6
- package/src/login-button.js +2 -2
- package/src/media-button.js +0 -20
- package/src/media-menu.js +2 -96
- package/src/media-slider.js +7 -21
- package/src/nav-search.js +8 -2
- package/src/primary-nav.js +18 -24
- package/src/search-menu.js +0 -30
- package/src/styles/dropdown-menu.js +0 -2
- package/src/styles/media-menu.js +2 -2
- package/src/styles/primary-nav.js +7 -16
- package/src/styles/search-menu.js +0 -5
- package/src/user-menu.js +0 -14
- package/src/lib/keyboard-navigation.js +0 -124
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,7 +77,6 @@ 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) {
|
|
@@ -276,7 +274,6 @@ export default class IATopNav extends LitElement {
|
|
|
276
274
|
.selectedMenuOption=${this.selectedMenuOption}
|
|
277
275
|
.username=${this.username}
|
|
278
276
|
.userProfileImagePath=${this.userProfileImagePath}
|
|
279
|
-
.currentTab=${this.currentTab}
|
|
280
277
|
?hideSearch=${this.hideSearch}
|
|
281
278
|
@mediaTypeSelected=${this.mediaTypeSelected}
|
|
282
279
|
@toggleSearchMenu=${this.toggleSearchMenu}
|
|
@@ -292,8 +289,6 @@ export default class IATopNav extends LitElement {
|
|
|
292
289
|
.selectedMenuOption=${this.selectedMenuOption}
|
|
293
290
|
.mediaSliderOpen=${this.mediaSliderOpen}
|
|
294
291
|
.menus=${this.menus}
|
|
295
|
-
tabindex="${this.mediaSliderOpen ? '1' : ''}"
|
|
296
|
-
@moveFocusToOthers=${(e) => this.currentTab = e.detail}
|
|
297
292
|
></media-slider>
|
|
298
293
|
</div>
|
|
299
294
|
${this.username ? this.userMenu : this.signedOutDropdown}
|
|
@@ -310,7 +305,6 @@ export default class IATopNav extends LitElement {
|
|
|
310
305
|
<desktop-subnav
|
|
311
306
|
.baseHost=${this.baseHost}
|
|
312
307
|
.menuItems=${this.desktopSubnavMenuItems}
|
|
313
|
-
@focus=${this.closeMenus}
|
|
314
308
|
></desktop-subnav>
|
|
315
309
|
<div id="close-layer" class="${this.closeLayerClass}" @click=${this.closeMenus}></div>
|
|
316
310
|
`;
|
package/src/login-button.js
CHANGED
|
@@ -67,9 +67,9 @@ class LoginButton extends TrackedElement {
|
|
|
67
67
|
${icons.user}
|
|
68
68
|
</a>
|
|
69
69
|
<span>
|
|
70
|
-
<a href="${this.signupPath}"
|
|
70
|
+
<a href="${this.signupPath}">Sign up</a>
|
|
71
71
|
|
|
|
72
|
-
<a href="${this.loginPath}"
|
|
72
|
+
<a href="${this.loginPath}">Log in</a>
|
|
73
73
|
</span>
|
|
74
74
|
</div>
|
|
75
75
|
`;
|
package/src/media-button.js
CHANGED
|
@@ -18,7 +18,6 @@ class MediaButton extends TrackedElement {
|
|
|
18
18
|
mediatype: { type: String },
|
|
19
19
|
openMenu: { type: String },
|
|
20
20
|
selected: { type: Boolean },
|
|
21
|
-
selectedMenuOption: { type: String },
|
|
22
21
|
followable: { type: Boolean },
|
|
23
22
|
};
|
|
24
23
|
}
|
|
@@ -36,16 +35,9 @@ class MediaButton extends TrackedElement {
|
|
|
36
35
|
this.mediatype = '';
|
|
37
36
|
this.openMenu = '';
|
|
38
37
|
this.selected = false;
|
|
39
|
-
this.selectedMenuOption = '';
|
|
40
38
|
this.followable = false;
|
|
41
39
|
}
|
|
42
40
|
|
|
43
|
-
updated() {
|
|
44
|
-
console.log(this.selectedMenuOption)
|
|
45
|
-
// if (this.selectedMenuOption)
|
|
46
|
-
// this.shadowDom.querySelector(`a.${this.mediatype}`).focus();
|
|
47
|
-
}
|
|
48
|
-
|
|
49
41
|
onClick(e) {
|
|
50
42
|
this.trackClick(e);
|
|
51
43
|
e.preventDefault();
|
|
@@ -103,26 +95,14 @@ class MediaButton extends TrackedElement {
|
|
|
103
95
|
`;
|
|
104
96
|
}
|
|
105
97
|
|
|
106
|
-
emitHandleSubMenuKeyDown(e) {
|
|
107
|
-
this.dispatchEvent(new CustomEvent('subMenuKeyDown1', {
|
|
108
|
-
bubbles: true,
|
|
109
|
-
composed: true,
|
|
110
|
-
detail: {
|
|
111
|
-
e
|
|
112
|
-
}
|
|
113
|
-
}));
|
|
114
|
-
}
|
|
115
|
-
|
|
116
98
|
render() {
|
|
117
99
|
return html`
|
|
118
100
|
<a
|
|
119
101
|
href="${this.href}"
|
|
120
102
|
class="menu-item ${this.mediatype} ${this.buttonClass}"
|
|
121
103
|
@click=${this.followable ? this.trackClick : this.onClick}
|
|
122
|
-
@keydown="${this.emitHandleSubMenuKeyDown}"
|
|
123
104
|
data-event-click-tracking="${this.analyticsEvent}"
|
|
124
105
|
title="${this.tooltipPrefix} ${this.mediatype} menu"
|
|
125
|
-
tabindex="${this.openMenu === 'media' ? '' : '0'}"
|
|
126
106
|
>
|
|
127
107
|
${this.menuItem}
|
|
128
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,11 +67,6 @@ class MediaMenu extends LitElement {
|
|
|
67
67
|
config: { type: Object },
|
|
68
68
|
openMenu: { type: String },
|
|
69
69
|
selectedMenuOption: { type: String },
|
|
70
|
-
|
|
71
|
-
isSubMenuOpen: { type: Boolean },
|
|
72
|
-
focusedIndex: { type: Number },
|
|
73
|
-
|
|
74
|
-
currentTab: { type: Object },
|
|
75
70
|
};
|
|
76
71
|
}
|
|
77
72
|
|
|
@@ -80,95 +75,8 @@ class MediaMenu extends LitElement {
|
|
|
80
75
|
this.config = {};
|
|
81
76
|
this.openMenu = '';
|
|
82
77
|
this.selectedMenuOption = '';
|
|
83
|
-
|
|
84
|
-
this.isSubMenuOpen = false;
|
|
85
|
-
this.focusedIndex = -1;
|
|
86
|
-
this.menuRef = [];
|
|
87
|
-
this.subMenuRef = [];
|
|
88
|
-
|
|
89
|
-
this.currentTab = {};
|
|
90
|
-
this.focusOn = 0;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
firstUpdated() {
|
|
94
|
-
this.menuRef = Array.from(this.shadowRoot.querySelectorAll('media-button'));
|
|
95
|
-
// this.subMenuRef = Array.from(this.shadowRoot.querySelectorAll('.submenu-item'));
|
|
96
|
-
// this.shadowRoot.querySelector('media-button').focus();
|
|
97
|
-
// this.addEventListener('keydown', this.handleKeyDown.bind(this));
|
|
98
|
-
|
|
99
|
-
// this.shadowRoot.querySelector('.menu-group media-button').shadowRoot.querySelector(`${this.selectedMenuOption}`);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
updated(props) {
|
|
103
|
-
// console.log(props)
|
|
104
|
-
if (props.has('currentTab')) {
|
|
105
|
-
// console.log(this.currentTab.mediatype, this.currentTab.moveTo)
|
|
106
|
-
|
|
107
|
-
// const dd = this.shadowRoot.querySelector('primary-nav').shadowRoot.querySelector('media-menu');
|
|
108
|
-
const mediaButtons = Array.from(this.shadowRoot.querySelectorAll('media-button'));
|
|
109
|
-
// console.log(mediaButtons)
|
|
110
|
-
|
|
111
|
-
// let = newIndex1 = 0;
|
|
112
|
-
mediaButtons.map((button, index) => {
|
|
113
|
-
// console.log(button.shadowRoot.querySelector('a.menu-item'));
|
|
114
|
-
|
|
115
|
-
const linkItem = button.shadowRoot.querySelector('a.menu-item');
|
|
116
|
-
if (linkItem) {
|
|
117
|
-
// console.log(linkItem)
|
|
118
|
-
if (linkItem.classList.contains(`${this.selectedMenuOption}`)) {
|
|
119
|
-
linkItem.classList.remove('selected');
|
|
120
|
-
linkItem.blur();
|
|
121
|
-
|
|
122
|
-
// newIndex1 = this.currentTab.moveTo === 'next' ? index++ : index--;
|
|
123
|
-
// if (this.currentTab.moveTo)
|
|
124
|
-
// mediaButtons[index].shadowRoot.querySelector('a.menu-item').blur();
|
|
125
|
-
// if (this.currentTab.moveTo === 'next') {
|
|
126
|
-
// mediaButtons[index + 1].shadowRoot.querySelector('a.menu-item').focus();
|
|
127
|
-
// } else if (this.currentTab.moveTo === 'prev') {
|
|
128
|
-
mediaButtons[this.currentTab.moveTo === 'next' ? index + 1 : index - 1].shadowRoot.querySelector('a.menu-item').focus();
|
|
129
|
-
// }
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
// console.log('updatedddddddddddd', this.selectedMenuOption, this.shadowRoot.querySelector('.menu-group'));
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
// this.shadowRoot.querySelector('.menu-group').focus();
|
|
138
|
-
// console.log(props);
|
|
139
|
-
// this.shadowRoot.querySelectorAll('media-button').shadowRoot.querySelector(`${this.selectedMenuOption}`);
|
|
140
|
-
|
|
141
|
-
// this.requestUpdate();
|
|
142
|
-
// this.updateRequest();
|
|
143
|
-
// this.menuRef = Array.from(this.shadowRoot.querySelectorAll('media-button'));
|
|
144
|
-
}
|
|
145
78
|
}
|
|
146
79
|
|
|
147
|
-
handleKeyDown(e) {
|
|
148
|
-
// console.log('dddddddddddd')
|
|
149
|
-
if (e.key === 'Tab') {
|
|
150
|
-
console.log(this.menuRef)
|
|
151
|
-
this.focusedIndex = (this.focusedIndex + 1) % this.menuRef.length;
|
|
152
|
-
this.submenuFocusedIndex = -1; // reset submenu focus index
|
|
153
|
-
this.menuRef[this.focusedIndex].focus();
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// handleSubMenuKeydown(e) {
|
|
158
|
-
// console.log(e);
|
|
159
|
-
// if (e.key === 'ArrowDown') {
|
|
160
|
-
// this.focusedIndex = (this.focusedIndex + 1) % this.subMenuRef.length;
|
|
161
|
-
// this.subMenuRef[this.focusedIndex].focus();
|
|
162
|
-
// } else if (e.key === 'ArrowUp') {
|
|
163
|
-
// this.focusedIndex = (this.focusedIndex - 1 + this.subMenuRef.length) % this.subMenuRef.length;
|
|
164
|
-
// this.subMenuRef[this.focusedIndex].focus();
|
|
165
|
-
// } else if (e.key === 'Escape') {
|
|
166
|
-
// this.isSubMenuOpen = false;
|
|
167
|
-
// this.requestUpdate();
|
|
168
|
-
// setTimeout(() => this.menuRef[0]?.focus(), 0);
|
|
169
|
-
// }
|
|
170
|
-
// }
|
|
171
|
-
|
|
172
80
|
get mediaMenuOptionsTemplate() {
|
|
173
81
|
const buttons = menuSelection.map(({
|
|
174
82
|
icon,
|
|
@@ -178,7 +86,6 @@ class MediaMenu extends LitElement {
|
|
|
178
86
|
followable,
|
|
179
87
|
}) => {
|
|
180
88
|
const selected = this.selectedMenuOption === menu;
|
|
181
|
-
// this.focusOn =
|
|
182
89
|
return html`
|
|
183
90
|
<media-button
|
|
184
91
|
.config=${this.config}
|
|
@@ -189,9 +96,7 @@ class MediaMenu extends LitElement {
|
|
|
189
96
|
.mediatype=${menu}
|
|
190
97
|
.openMenu=${this.openMenu}
|
|
191
98
|
.selected=${selected}
|
|
192
|
-
.selectedMenuOption=${this.selectedMenuOption}
|
|
193
99
|
data-mediatype="${menu}"
|
|
194
|
-
.focusOn=${this.focusOn}
|
|
195
100
|
></media-button>
|
|
196
101
|
`;
|
|
197
102
|
});
|
|
@@ -212,6 +117,7 @@ class MediaMenu extends LitElement {
|
|
|
212
117
|
<div class="overflow-clip">
|
|
213
118
|
<nav
|
|
214
119
|
class="media-menu-inner"
|
|
120
|
+
aria-hidden="${!this.menuOpened}"
|
|
215
121
|
aria-expanded="${this.menuOpened}"
|
|
216
122
|
>
|
|
217
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) {
|
|
@@ -154,11 +152,7 @@ class PrimaryNav extends TrackedElement {
|
|
|
154
152
|
}
|
|
155
153
|
|
|
156
154
|
get uploadButtonTemplate() {
|
|
157
|
-
return html
|
|
158
|
-
<a href="${formatUrl('/create', this.baseHost)}"
|
|
159
|
-
class="upload"
|
|
160
|
-
@focus=${this.toggleMediaMenu}
|
|
161
|
-
>
|
|
155
|
+
return html`<a href="${formatUrl('/create', this.baseHost)}" class="upload">
|
|
162
156
|
${icons.upload}
|
|
163
157
|
<span>Upload</span>
|
|
164
158
|
</a>`;
|
|
@@ -187,15 +181,6 @@ class PrimaryNav extends TrackedElement {
|
|
|
187
181
|
const mediaMenuTabIndex = this.openMenu === 'media' ? '' : '-1';
|
|
188
182
|
return html`
|
|
189
183
|
<nav class=${this.hideSearch ? 'hide-search' : nothing}>
|
|
190
|
-
<button
|
|
191
|
-
class="hamburger"
|
|
192
|
-
@click="${this.toggleMediaMenu}"
|
|
193
|
-
data-event-click-tracking="${this.config.eventCategory}|NavHamburger"
|
|
194
|
-
title="Open main menu"
|
|
195
|
-
>
|
|
196
|
-
<icon-hamburger ?active=${this.openMenu === 'media'}></icon-hamburger>
|
|
197
|
-
</button>
|
|
198
|
-
|
|
199
184
|
<div class=${`branding ${this.secondLogoClass}`}>
|
|
200
185
|
<a
|
|
201
186
|
href=${formatUrl('/', this.baseHost)}
|
|
@@ -203,25 +188,34 @@ class PrimaryNav extends TrackedElement {
|
|
|
203
188
|
data-event-click-tracking="${this.config.eventCategory}|NavHome"
|
|
204
189
|
title="Go home"
|
|
205
190
|
class="link-home"
|
|
206
|
-
tabindex="-1"
|
|
207
191
|
>${icons.iaLogo}${logoWordmarkStacked}</a
|
|
208
192
|
>
|
|
209
193
|
${this.secondLogoSlot}
|
|
210
194
|
</div>
|
|
195
|
+
|
|
196
|
+
<div class="right-side-section">
|
|
197
|
+
${this.mobileDonateHeart}
|
|
198
|
+
${this.searchMenu}
|
|
199
|
+
${this.uploadButtonTemplate}
|
|
200
|
+
${this.userStateTemplate}
|
|
201
|
+
</div>
|
|
211
202
|
<media-menu
|
|
212
203
|
.baseHost=${this.baseHost}
|
|
213
204
|
.config=${this.config}
|
|
214
205
|
?mediaMenuAnimate="${this.mediaMenuAnimate}"
|
|
206
|
+
tabindex="${mediaMenuTabIndex}"
|
|
215
207
|
.selectedMenuOption=${this.selectedMenuOption}
|
|
216
208
|
.openMenu=${this.openMenu}
|
|
217
|
-
.currentTab=${this.currentTab}
|
|
218
209
|
></media-menu>
|
|
219
|
-
<
|
|
220
|
-
|
|
221
|
-
${this.
|
|
222
|
-
|
|
223
|
-
${this.
|
|
224
|
-
|
|
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>
|
|
225
219
|
</nav>
|
|
226
220
|
`;
|
|
227
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
|
@@ -24,7 +24,7 @@ export default css`
|
|
|
24
24
|
/* Mobile view styles */
|
|
25
25
|
@media (max-width: 889px) {
|
|
26
26
|
.media-menu-container {
|
|
27
|
-
|
|
27
|
+
position: relative;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
.media-menu-inner {
|
|
@@ -39,7 +39,7 @@ export default css`
|
|
|
39
39
|
.overflow-clip {
|
|
40
40
|
position: absolute;
|
|
41
41
|
z-index: -1; /** needs to be under the navigation, otherwise it intercepts clicks */
|
|
42
|
-
top:
|
|
42
|
+
top: 0;
|
|
43
43
|
left: 0;
|
|
44
44
|
height: 0;
|
|
45
45
|
width: 100%;
|
|
@@ -10,8 +10,7 @@ export default css`
|
|
|
10
10
|
nav {
|
|
11
11
|
position: relative;
|
|
12
12
|
display: -ms-grid;
|
|
13
|
-
|
|
14
|
-
display: flex;
|
|
13
|
+
display: grid;
|
|
15
14
|
height: 4rem;
|
|
16
15
|
grid-template-areas: 'hamburger empty heart search user';
|
|
17
16
|
-ms-grid-columns: 4rem minmax(1rem, 100%) 4rem 4rem 4rem;
|
|
@@ -30,7 +29,6 @@ export default css`
|
|
|
30
29
|
|
|
31
30
|
.right-side-section {
|
|
32
31
|
display: flex;
|
|
33
|
-
margin-left: auto;
|
|
34
32
|
user-select: none;
|
|
35
33
|
}
|
|
36
34
|
button {
|
|
@@ -88,9 +86,6 @@ export default css`
|
|
|
88
86
|
fill: var(--activeColor);
|
|
89
87
|
}
|
|
90
88
|
|
|
91
|
-
.mobile-donate-link {
|
|
92
|
-
display: inline-block;
|
|
93
|
-
}
|
|
94
89
|
.mobile-donate-link svg {
|
|
95
90
|
height: 4rem;
|
|
96
91
|
width: 4rem;
|
|
@@ -156,8 +151,7 @@ export default css`
|
|
|
156
151
|
height: 100%;
|
|
157
152
|
}
|
|
158
153
|
|
|
159
|
-
.user-menu:hover
|
|
160
|
-
.user-menu:focus {
|
|
154
|
+
.user-menu:hover {
|
|
161
155
|
color: var(--linkHoverColor);
|
|
162
156
|
}
|
|
163
157
|
|
|
@@ -193,13 +187,6 @@ export default css`
|
|
|
193
187
|
slot[name='opt-sec-logo'] {
|
|
194
188
|
display: none;
|
|
195
189
|
}
|
|
196
|
-
|
|
197
|
-
.right-side-section {
|
|
198
|
-
display: initial;
|
|
199
|
-
}
|
|
200
|
-
.right-side-section .user-info {
|
|
201
|
-
float: right;
|
|
202
|
-
}
|
|
203
190
|
}
|
|
204
191
|
|
|
205
192
|
@media (min-width: 890px) {
|
|
@@ -208,8 +195,12 @@ export default css`
|
|
|
208
195
|
--userIconHeight: 3.2rem;
|
|
209
196
|
}
|
|
210
197
|
|
|
198
|
+
.right-side-section {
|
|
199
|
+
display: contents;
|
|
200
|
+
}
|
|
201
|
+
|
|
211
202
|
nav {
|
|
212
|
-
display:
|
|
203
|
+
display: block;
|
|
213
204
|
z-index: 4;
|
|
214
205
|
height: 5rem;
|
|
215
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')) {
|
|
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,124 +0,0 @@
|
|
|
1
|
-
export default class KeyboardNavigation {
|
|
2
|
-
/**
|
|
3
|
-
* Constructor for the KeyboardNavigation class.
|
|
4
|
-
* @param {HTMLElement} elementsContainer - The container element that holds the focusable elements.
|
|
5
|
-
* @param {string} menuOption - The type of menu option ('web' or 'usermenu').
|
|
6
|
-
*/
|
|
7
|
-
constructor(elementsContainer, menuOption) {
|
|
8
|
-
this.elementsContainer = elementsContainer;
|
|
9
|
-
this.menuOption = menuOption;
|
|
10
|
-
this.focusableElements = this.getFocusableElements();
|
|
11
|
-
this.focusedIndex = this.getInitialFocusedIndex();
|
|
12
|
-
|
|
13
|
-
this.focusableElements[this.focusedIndex]?.focus();
|
|
14
|
-
this.handleKeyDown = this.handleKeyDown.bind(this);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Returns the initial focused index based on the menu option.
|
|
19
|
-
* @returns {number} The initial focused index (0 for 'web', 1 for 'usermenu').
|
|
20
|
-
*/
|
|
21
|
-
getInitialFocusedIndex() {
|
|
22
|
-
return this.menuOption === 'usermenu' ? 1 : 0;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Gets an array of focusable elements within the container.
|
|
27
|
-
* @returns {HTMLElement[]} An array of focusable elements.
|
|
28
|
-
*/
|
|
29
|
-
getFocusableElements() {
|
|
30
|
-
const focusableTagSelectors = 'a[href], button, input, textarea, select, details, [tabindex]:not([tabindex="-1"])';
|
|
31
|
-
const isDisabledOrHidden = el => !el.hasAttribute('disabled') && !el.getAttribute('aria-hidden');
|
|
32
|
-
|
|
33
|
-
let elements;
|
|
34
|
-
if (this.menuOption === 'web') {
|
|
35
|
-
const waybackSlider = this.elementsContainer.querySelector('wayback-slider').shadowRoot;
|
|
36
|
-
const waybackSearch = waybackSlider.querySelector('wayback-search');
|
|
37
|
-
const waybackSearchElements = Array.from(waybackSearch.shadowRoot.querySelectorAll(focusableTagSelectors));
|
|
38
|
-
|
|
39
|
-
const normalElements = Array.from(waybackSlider.querySelectorAll(focusableTagSelectors));
|
|
40
|
-
|
|
41
|
-
const savePageForm = waybackSlider.querySelector('save-page-form');
|
|
42
|
-
const savePageFormElements = Array.from(savePageForm.shadowRoot.querySelectorAll(focusableTagSelectors));
|
|
43
|
-
|
|
44
|
-
elements = [...waybackSearchElements, ...normalElements, ...savePageFormElements];
|
|
45
|
-
} else {
|
|
46
|
-
elements = this.elementsContainer.querySelectorAll(focusableTagSelectors);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return Array.from(elements).filter(isDisabledOrHidden);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Handles keyboard events and focuses the appropriate element.
|
|
54
|
-
* @param {KeyboardEvent} event - The keyboard event object.
|
|
55
|
-
*/
|
|
56
|
-
handleKeyDown(event) {
|
|
57
|
-
const { key } = event;
|
|
58
|
-
const isArrowKey = ['ArrowDown', 'ArrowRight', 'ArrowUp', 'ArrowLeft'].includes(key);
|
|
59
|
-
const isTabKey = key === 'Tab';
|
|
60
|
-
|
|
61
|
-
if (isArrowKey) {
|
|
62
|
-
this.handleArrowKey(key);
|
|
63
|
-
} else if (isTabKey) {
|
|
64
|
-
this.handleTabKey(event);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Handles arrow key events and focuses the next or previous element.
|
|
70
|
-
* @param {string} key - The key that was pressed ('ArrowDown', 'ArrowRight', 'ArrowUp', or 'ArrowLeft').
|
|
71
|
-
*/
|
|
72
|
-
handleArrowKey(key) {
|
|
73
|
-
const isDownOrRight = ['ArrowDown', 'ArrowRight'].includes(key);
|
|
74
|
-
isDownOrRight ? this.focusNext() : this.focusPrevious();
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Focuses the previous focusable element in the container.
|
|
79
|
-
*/
|
|
80
|
-
focusPrevious() {
|
|
81
|
-
if (this.focusableElements.length === 0) return;
|
|
82
|
-
this.focusedIndex = (this.focusedIndex - 1 + this.focusableElements.length) % this.focusableElements.length;
|
|
83
|
-
this.focusableElements[this.focusedIndex]?.focus();
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Focuses the next focusable element in the container.
|
|
88
|
-
*/
|
|
89
|
-
focusNext() {
|
|
90
|
-
if (this.focusableElements.length === 0) return;
|
|
91
|
-
this.focusedIndex = (this.focusedIndex + 1) % this.focusableElements.length;
|
|
92
|
-
this.focusableElements[this.focusedIndex]?.focus();
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Handles the Tab key event and focuses the next or previous menu item.
|
|
97
|
-
* @param {KeyboardEvent} event - The keyboard event object.
|
|
98
|
-
*/
|
|
99
|
-
handleTabKey(event) {
|
|
100
|
-
if (this.menuOption !== 'usermenu') {
|
|
101
|
-
const isShiftPressed = event.shiftKey;
|
|
102
|
-
this.focusNextMenuItem(isShiftPressed);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
event.preventDefault();
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Focuses the next or previous menu item based on the provided flag.
|
|
110
|
-
* @param {boolean} isPrevious - A flag indicating whether to focus the previous menu item.
|
|
111
|
-
*/
|
|
112
|
-
focusNextMenuItem(isPrevious = false) {
|
|
113
|
-
this.elementsContainer.dispatchEvent(
|
|
114
|
-
new CustomEvent('moveFocusToOthers', {
|
|
115
|
-
bubbles: true,
|
|
116
|
-
composed: true,
|
|
117
|
-
detail: {
|
|
118
|
-
mediatype: this.menuOption,
|
|
119
|
-
moveTo: isPrevious ? 'prev' : 'next',
|
|
120
|
-
},
|
|
121
|
-
})
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
}
|