@internetarchive/ia-topnav 1.4.1-alpha-webdev8259.10 → 1.4.1
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/.prettierignore +1 -1
- package/LICENSE +661 -661
- package/README.md +147 -147
- package/demo/index.html +28 -28
- package/dist/src/data/menus.js +1 -1
- package/dist/src/data/menus.js.map +1 -1
- package/dist/src/ia-topnav.d.ts +9 -6
- package/dist/src/ia-topnav.js +66 -27
- package/dist/src/ia-topnav.js.map +1 -1
- package/dist/src/login-button.js +1 -1
- package/dist/src/login-button.js.map +1 -1
- package/dist/src/primary-nav.d.ts +4 -5
- package/dist/src/primary-nav.js +35 -14
- package/dist/src/primary-nav.js.map +1 -1
- package/dist/src/styles/ia-topnav.js +5 -0
- package/dist/src/styles/ia-topnav.js.map +1 -1
- package/dist/src/styles/primary-nav.js +0 -55
- package/dist/src/styles/primary-nav.js.map +1 -1
- package/dist/test/ia-topnav.test.js +60 -18
- package/dist/test/ia-topnav.test.js.map +1 -1
- package/dist/test/primary-nav.test.js +2 -31
- package/dist/test/primary-nav.test.js.map +1 -1
- package/eslint.config.mjs +53 -53
- package/package.json +72 -72
- package/prettier.config.js +9 -9
- package/src/data/menus.ts +1 -1
- package/src/ia-topnav.ts +79 -30
- package/src/login-button.ts +1 -1
- package/src/primary-nav.ts +33 -14
- package/src/styles/ia-topnav.ts +5 -0
- package/src/styles/primary-nav.ts +0 -55
- package/ssl/server.key +28 -28
- package/test/ia-topnav.test.ts +81 -20
- package/test/primary-nav.test.ts +2 -43
- package/tsconfig.json +31 -31
- package/web-dev-server.config.mjs +32 -32
- package/web-test-runner.config.mjs +41 -41
package/src/ia-topnav.ts
CHANGED
|
@@ -11,9 +11,11 @@ import {
|
|
|
11
11
|
IATopNavSecondIdentitySlotMode,
|
|
12
12
|
} from './models';
|
|
13
13
|
import './primary-nav';
|
|
14
|
+
import './search-menu';
|
|
14
15
|
import './signed-out-dropdown';
|
|
15
16
|
import iaTopNavCSS from './styles/ia-topnav';
|
|
16
17
|
import './user-menu';
|
|
18
|
+
import KeyboardNavigation from './lib/keyboard-navigation';
|
|
17
19
|
|
|
18
20
|
@customElement('ia-topnav')
|
|
19
21
|
export class IATopNav extends LitElement {
|
|
@@ -41,6 +43,10 @@ export class IATopNav extends LitElement {
|
|
|
41
43
|
|
|
42
44
|
@property({ type: String }) screenName: string = '';
|
|
43
45
|
|
|
46
|
+
@property({ type: String }) searchIn = '';
|
|
47
|
+
|
|
48
|
+
@property({ type: String }) searchQuery = '';
|
|
49
|
+
|
|
44
50
|
@property({ type: String }) selectedMenuOption = '';
|
|
45
51
|
|
|
46
52
|
@property({ type: String }) username: string = '';
|
|
@@ -57,10 +63,10 @@ export class IATopNav extends LitElement {
|
|
|
57
63
|
};
|
|
58
64
|
|
|
59
65
|
@state() private menus: IATopNavMenuConfig = buildTopNavMenus();
|
|
66
|
+
private previousKeydownListener: // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
67
|
+
((this: HTMLElement, ev: KeyboardEvent) => any) | undefined;
|
|
60
68
|
|
|
61
|
-
private
|
|
62
|
-
|
|
63
|
-
private boundHandleClick = this.handleDocumentClick.bind(this);
|
|
69
|
+
private keyboardNavigation?: KeyboardNavigation;
|
|
64
70
|
|
|
65
71
|
private get normalizedBaseHost() {
|
|
66
72
|
return !this.localLinks ? this.baseHost : '';
|
|
@@ -80,32 +86,37 @@ export class IATopNav extends LitElement {
|
|
|
80
86
|
) {
|
|
81
87
|
this.menuSetup();
|
|
82
88
|
}
|
|
83
|
-
}
|
|
84
89
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
90
|
+
if (this.openMenu === 'search') {
|
|
91
|
+
const targetElement =
|
|
92
|
+
this.renderRoot.querySelector('search-menu')?.shadowRoot;
|
|
93
|
+
if (targetElement) {
|
|
94
|
+
this.keyboardNavigation = new KeyboardNavigation(
|
|
95
|
+
targetElement as unknown as HTMLElement,
|
|
96
|
+
this.openMenu,
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
if (this.previousKeydownListener) {
|
|
100
|
+
this.removeEventListener('keydown', this.previousKeydownListener);
|
|
101
|
+
}
|
|
102
|
+
this.addEventListener('keydown', this.keyboardNavigation.handleKeyDown);
|
|
103
|
+
this.previousKeydownListener = this.keyboardNavigation.handleKeyDown;
|
|
104
|
+
}
|
|
100
105
|
}
|
|
101
106
|
}
|
|
102
107
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
108
|
+
firstUpdated() {
|
|
109
|
+
// close open menu on `esc` click
|
|
110
|
+
document.addEventListener(
|
|
111
|
+
'keydown',
|
|
112
|
+
(e) => {
|
|
113
|
+
if (e.key === 'Escape') {
|
|
114
|
+
this.openMenu = '';
|
|
115
|
+
this.mediaSliderOpen = false;
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
false,
|
|
119
|
+
);
|
|
109
120
|
}
|
|
110
121
|
|
|
111
122
|
menuSetup() {
|
|
@@ -128,6 +139,23 @@ export class IATopNav extends LitElement {
|
|
|
128
139
|
this.closeMediaSlider();
|
|
129
140
|
}
|
|
130
141
|
|
|
142
|
+
navSearchBlurEvent(e: CustomEvent) {
|
|
143
|
+
if (this.previousKeydownListener) {
|
|
144
|
+
this.removeEventListener('keydown', this.previousKeydownListener);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const isUploadButton = e.detail?.isUploadButton;
|
|
148
|
+
if (!isUploadButton) {
|
|
149
|
+
const searchMenu = this.renderRoot.querySelector(
|
|
150
|
+
'search-menu',
|
|
151
|
+
) as HTMLElement;
|
|
152
|
+
const elements = this.keyboardNavigation?.getFocusableElements();
|
|
153
|
+
if (searchMenu && elements?.length) {
|
|
154
|
+
elements[0].focus();
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
131
159
|
openMediaSlider() {
|
|
132
160
|
this.mediaSliderOpen = true;
|
|
133
161
|
}
|
|
@@ -142,6 +170,10 @@ export class IATopNav extends LitElement {
|
|
|
142
170
|
this.closeMediaSlider();
|
|
143
171
|
}
|
|
144
172
|
|
|
173
|
+
searchInChanged(e: CustomEvent) {
|
|
174
|
+
this.searchIn = e.detail.searchIn;
|
|
175
|
+
}
|
|
176
|
+
|
|
145
177
|
trackClick(e: CustomEvent) {
|
|
146
178
|
this.dispatchEvent(
|
|
147
179
|
new CustomEvent('analyticsClick', {
|
|
@@ -171,6 +203,10 @@ export class IATopNav extends LitElement {
|
|
|
171
203
|
this.openMediaSlider();
|
|
172
204
|
}
|
|
173
205
|
|
|
206
|
+
get searchMenuOpened() {
|
|
207
|
+
return this.openMenu === 'search';
|
|
208
|
+
}
|
|
209
|
+
|
|
174
210
|
get signedOutOpened() {
|
|
175
211
|
return this.openMenu === 'login';
|
|
176
212
|
}
|
|
@@ -179,6 +215,10 @@ export class IATopNav extends LitElement {
|
|
|
179
215
|
return this.openMenu === 'user';
|
|
180
216
|
}
|
|
181
217
|
|
|
218
|
+
get searchMenuTabIndex() {
|
|
219
|
+
return this.searchMenuOpened ? '' : '-1';
|
|
220
|
+
}
|
|
221
|
+
|
|
182
222
|
get userMenuTabIndex() {
|
|
183
223
|
return this.userMenuOpened ? '' : '-1';
|
|
184
224
|
}
|
|
@@ -251,10 +291,6 @@ export class IATopNav extends LitElement {
|
|
|
251
291
|
return this.secondIdentitySlotMode === 'allow';
|
|
252
292
|
}
|
|
253
293
|
|
|
254
|
-
get searchSlot() {
|
|
255
|
-
return html`<slot name="search" slot="search"></slot>`;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
294
|
get secondLogoSlot() {
|
|
259
295
|
return this.allowSecondaryIcon
|
|
260
296
|
? html`
|
|
@@ -277,6 +313,8 @@ export class IATopNav extends LitElement {
|
|
|
277
313
|
.config=${this.config}
|
|
278
314
|
.openMenu=${this.openMenu}
|
|
279
315
|
.screenName=${this.screenName}
|
|
316
|
+
.searchIn=${this.searchIn}
|
|
317
|
+
.searchQuery=${this.searchQuery}
|
|
280
318
|
.secondIdentitySlotMode=${this.secondIdentitySlotMode}
|
|
281
319
|
.selectedMenuOption=${this.selectedMenuOption}
|
|
282
320
|
.username=${this.username}
|
|
@@ -287,8 +325,9 @@ export class IATopNav extends LitElement {
|
|
|
287
325
|
@trackClick=${this.trackClick}
|
|
288
326
|
@trackSubmit=${this.trackSubmit}
|
|
289
327
|
@menuToggled=${this.menuToggled}
|
|
328
|
+
@navSearchBlur=${this.navSearchBlurEvent}
|
|
290
329
|
>
|
|
291
|
-
${this.secondLogoSlot}
|
|
330
|
+
${this.secondLogoSlot}
|
|
292
331
|
</primary-nav>
|
|
293
332
|
<media-slider
|
|
294
333
|
.baseHost=${this.normalizedBaseHost}
|
|
@@ -302,6 +341,16 @@ export class IATopNav extends LitElement {
|
|
|
302
341
|
></media-slider>
|
|
303
342
|
</div>
|
|
304
343
|
${this.username ? this.userMenu : this.signedOutDropdown}
|
|
344
|
+
<search-menu
|
|
345
|
+
.baseHost=${this.normalizedBaseHost}
|
|
346
|
+
.config=${this.config}
|
|
347
|
+
.openMenu=${this.openMenu}
|
|
348
|
+
tabindex="${this.searchMenuTabIndex}"
|
|
349
|
+
?hideSearch=${this.hideSearch}
|
|
350
|
+
@searchInChanged=${this.searchInChanged}
|
|
351
|
+
@trackClick=${this.trackClick}
|
|
352
|
+
@trackSubmit=${this.trackSubmit}
|
|
353
|
+
></search-menu>
|
|
305
354
|
<desktop-subnav
|
|
306
355
|
.baseHost=${this.normalizedBaseHost}
|
|
307
356
|
.menuItems=${this.menus.more.links}
|
package/src/login-button.ts
CHANGED
package/src/primary-nav.ts
CHANGED
|
@@ -3,9 +3,11 @@ import TrackedElement from './tracked-element';
|
|
|
3
3
|
import icons from './assets/img/icons';
|
|
4
4
|
import './assets/img/hamburger';
|
|
5
5
|
import './login-button';
|
|
6
|
+
import './nav-search';
|
|
6
7
|
import './media-menu';
|
|
7
8
|
import logoWordmarkStacked from './assets/img/wordmark-stacked';
|
|
8
9
|
import primaryNavCSS from './styles/primary-nav';
|
|
10
|
+
import locationHandler from './lib/location-handler';
|
|
9
11
|
import formatUrl from './lib/format-url';
|
|
10
12
|
import { customElement, property } from 'lit/decorators.js';
|
|
11
13
|
import { IATopNavConfig, IATopNavSecondIdentitySlotMode } from './models';
|
|
@@ -19,6 +21,8 @@ export class PrimaryNav extends TrackedElement {
|
|
|
19
21
|
@property({ type: Object }) config: IATopNavConfig = defaultTopNavConfig;
|
|
20
22
|
@property({ type: String }) openMenu = '';
|
|
21
23
|
@property({ type: String }) screenName = '';
|
|
24
|
+
@property({ type: String }) searchIn = '';
|
|
25
|
+
@property({ type: String }) searchQuery = '';
|
|
22
26
|
@property({ type: String })
|
|
23
27
|
secondIdentitySlotMode: IATopNavSecondIdentitySlotMode = '';
|
|
24
28
|
@property({ type: String }) selectedMenuOption = '';
|
|
@@ -162,19 +166,6 @@ export class PrimaryNav extends TrackedElement {
|
|
|
162
166
|
return this.secondIdentitySlotMode === 'allow';
|
|
163
167
|
}
|
|
164
168
|
|
|
165
|
-
/**
|
|
166
|
-
* The search slot container, rendered between media-menu and
|
|
167
|
-
* right-side-section so it sits left of the Upload button on desktop.
|
|
168
|
-
*/
|
|
169
|
-
get searchSlotContainer() {
|
|
170
|
-
if (this.hideSearch) return nothing;
|
|
171
|
-
return html`
|
|
172
|
-
<div class="search-container ${this.searchMenuOpen ? 'open' : ''}">
|
|
173
|
-
<slot name="search"></slot>
|
|
174
|
-
</div>
|
|
175
|
-
`;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
169
|
get searchMenu() {
|
|
179
170
|
if (this.hideSearch) return nothing;
|
|
180
171
|
|
|
@@ -186,9 +177,38 @@ export class PrimaryNav extends TrackedElement {
|
|
|
186
177
|
>
|
|
187
178
|
${icons.search}
|
|
188
179
|
</button>
|
|
180
|
+
<nav-search
|
|
181
|
+
.baseHost=${this.baseHost}
|
|
182
|
+
.config=${this.config}
|
|
183
|
+
.locationHandler=${locationHandler}
|
|
184
|
+
.open=${this.searchMenuOpen}
|
|
185
|
+
.openMenu=${this.openMenu}
|
|
186
|
+
.searchIn=${this.searchIn}
|
|
187
|
+
.searchQuery=${this.searchQuery}
|
|
188
|
+
@blur=${this.emitNavSearchBlurEvent}
|
|
189
|
+
></nav-search>
|
|
189
190
|
`;
|
|
190
191
|
}
|
|
191
192
|
|
|
193
|
+
private emitNavSearchBlurEvent(e: FocusEvent) {
|
|
194
|
+
const relatedTarget = e.relatedTarget as HTMLElement;
|
|
195
|
+
const isUploadButton = relatedTarget?.classList.contains('upload');
|
|
196
|
+
|
|
197
|
+
if (isUploadButton) {
|
|
198
|
+
(this.shadowRoot?.querySelector('a.upload') as HTMLElement).focus();
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
this.dispatchEvent(
|
|
202
|
+
new CustomEvent('navSearchBlur', {
|
|
203
|
+
detail: {
|
|
204
|
+
isUploadButton: !!isUploadButton,
|
|
205
|
+
},
|
|
206
|
+
bubbles: true,
|
|
207
|
+
composed: true,
|
|
208
|
+
}),
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
|
|
192
212
|
get mobileDonateHeart() {
|
|
193
213
|
return html`
|
|
194
214
|
<a
|
|
@@ -266,7 +286,6 @@ export class PrimaryNav extends TrackedElement {
|
|
|
266
286
|
.openMenu=${this.openMenu}
|
|
267
287
|
.currentTab=${this.currentTab}
|
|
268
288
|
></media-menu>
|
|
269
|
-
${this.searchSlotContainer}
|
|
270
289
|
<div class="right-side-section">
|
|
271
290
|
${this.mobileDonateHeart} ${this.userStateTemplate}
|
|
272
291
|
${this.uploadButtonTemplate} ${this.searchMenu}
|
package/src/styles/ia-topnav.ts
CHANGED
|
@@ -24,6 +24,11 @@ export default css`
|
|
|
24
24
|
--activeButtonBg: var(--grey20);
|
|
25
25
|
--iconFill: var(--grey60);
|
|
26
26
|
|
|
27
|
+
--searchActiveBg: var(--grey20);
|
|
28
|
+
--searchActiveInputBg: var(--white);
|
|
29
|
+
--searchMenuBg: var(--grey20);
|
|
30
|
+
--desktopSearchIconFill: var(--grey20);
|
|
31
|
+
|
|
27
32
|
--mediaMenuBg: var(--grey13);
|
|
28
33
|
--mediaLabelDesktopColor: var(--grey60);
|
|
29
34
|
--activeDesktopMenuIcon: var(--grey28);
|
|
@@ -128,42 +128,6 @@ export default css`
|
|
|
128
128
|
z-index: 3;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
.search-container {
|
|
132
|
-
display: none;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
.search-container.open {
|
|
136
|
-
display: flex;
|
|
137
|
-
position: absolute;
|
|
138
|
-
top: 0;
|
|
139
|
-
right: 4rem;
|
|
140
|
-
bottom: 0;
|
|
141
|
-
left: 4rem;
|
|
142
|
-
z-index: 3;
|
|
143
|
-
padding: 0.5rem;
|
|
144
|
-
border-radius: 1rem 1rem 0 0;
|
|
145
|
-
background: var(--primaryNavBg);
|
|
146
|
-
align-items: center;
|
|
147
|
-
animation: fade-in 0.2s forwards;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
.search-container ::slotted(*) {
|
|
151
|
-
display: block;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
.search-container slot {
|
|
155
|
-
width: 100%;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
@keyframes fade-in {
|
|
159
|
-
0% {
|
|
160
|
-
opacity: 0;
|
|
161
|
-
}
|
|
162
|
-
100% {
|
|
163
|
-
opacity: 1;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
131
|
.upload {
|
|
168
132
|
display: none;
|
|
169
133
|
}
|
|
@@ -328,25 +292,6 @@ export default css`
|
|
|
328
292
|
float: right;
|
|
329
293
|
margin-left: 1rem;
|
|
330
294
|
}
|
|
331
|
-
|
|
332
|
-
.search-container,
|
|
333
|
-
.search-container.open {
|
|
334
|
-
display: flex;
|
|
335
|
-
position: static;
|
|
336
|
-
top: auto;
|
|
337
|
-
right: auto;
|
|
338
|
-
bottom: auto;
|
|
339
|
-
left: auto;
|
|
340
|
-
align-items: center;
|
|
341
|
-
padding: 0 0 0 1rem;
|
|
342
|
-
background: transparent;
|
|
343
|
-
border-radius: 0;
|
|
344
|
-
z-index: auto;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
.search-container slot {
|
|
348
|
-
width: auto;
|
|
349
|
-
}
|
|
350
295
|
}
|
|
351
296
|
|
|
352
297
|
@media (min-width: 990px) {
|
package/ssl/server.key
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
-----BEGIN PRIVATE KEY-----
|
|
2
|
-
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDZqbS9hNS38Atc
|
|
3
|
-
A7Uszq7EA7RavuHc8AcpbURa6Y7NORs0SmfDD0oLptQ7DX5pSuHyOeDHzQ3UXRCU
|
|
4
|
-
DAhAD1XlaYQ6PPdiJPRAe4ACELzgDzepxVz3pdKPcfXd5/mHV3ghUZya2XW5DSF1
|
|
5
|
-
CRYUX2j10a+JORJIG4bhvTg4HxTJZZDuaNfBMC6ZSn7d9YLQoAf1MLLJm43Ycj1W
|
|
6
|
-
lOnyG4DHxNEqEk260BlbBywJH+SJA6GA0GR2bnzYZaDnZ0wqea0Zamx8ijpdJxBU
|
|
7
|
-
xYOqLfzs2KREVkkGOmsFEu82W6G3D4bKsY1UNaWXb/jcl3UkXIJJij6CdbbMQkUJ
|
|
8
|
-
c8dow3sVAgMBAAECggEANgLpITAhcuVDhFk9L3m4H1bF/dCpDmCXfl2pXR/guicm
|
|
9
|
-
C4M9HUeheaOzvVWbXThiOe/HyfylpmFTmFEmCPNlPrDAyYzQXE/MNmYO/TQ3Eihk
|
|
10
|
-
iSG68I764XKHbsG+Byoa2rW8NSaqEjniZ/7Rtkt4qasXMmdxlGgUP9bq6O45g8HV
|
|
11
|
-
kHxneFlA2KbrvmWnBi7NTea9+tp61NWiq5n97UgHacQR6KkYIpbxd7uNSnCSdmXt
|
|
12
|
-
pcwzO4ZPabJ2/DKRjePhU5OggPh+9AhJ3jsBo99GwYPgSZDh8E3vh2OWOtLBMUH3
|
|
13
|
-
rmAYwlRT2aZ5hy5yi+4QD98WoUQtsr+9n757F8V6MQKBgQDzZycdgaKwWd5d34NN
|
|
14
|
-
0TkFtPQPwxxJTCCs3I3q02uWcS3svQzBK0cWb4nISO04TnJ3MnXo83dgGhCMF+uZ
|
|
15
|
-
FCXxAA53z8F92iZo+ELlXFDFwNeNYih/afDA42tWZ6TlVsDnZ4zQgRjHS7jEF/JV
|
|
16
|
-
0ZgwGpw5725JQt64dic8wTOcDQKBgQDk7YYACQcWTnmjDhZQ3PZSX4fcTtzPZKZj
|
|
17
|
-
fa1GrXEaUH1hSyc9VmY6qJpUmXexpvtr194nXE+O5wbThOHcBjVlo2Qv+vswmUX3
|
|
18
|
-
WEcVzTVN4/fODCLCqFcMNIr+BzwZfwpT+p0u8g9FxDy1gGmvkxwIu8DCpnUT12Xj
|
|
19
|
-
hm2wO+UxKQKBgFxCSDBF9+2SUtgQJYv0dwGzwiLLWMhro6MCAoT02D3w7nBihBgg
|
|
20
|
-
GFTnuDkDc285ROfrZ4gB6MizeHwxgOrIGU2NMO62/+d9LbvyBiE76Z3bZ5i+kQ0i
|
|
21
|
-
kc/7I69fn8ASLxJHTLenh0XbbNBfJ0riJCZvn7HSEGKShysyFdNQhAhtAoGAFYVi
|
|
22
|
-
0IQIv4cXFkYPwQBUw7+pVQOw7GpI3heFf5x0goXIk6nuAW0q5R7Oi192CiRphGTh
|
|
23
|
-
xI+ABy4ezSmz1exbfreShpQwowv1sOACpsEI3s6skBlB90y+Ci6yVlk1xCvWO7jW
|
|
24
|
-
qAAngWaGUoXE6bWJsCR+ZY4ieYAJWw9bJnMrA6kCgYAzV4Xeoh5ofENZM21wKW3W
|
|
25
|
-
iCzRibPObv6Vb/j9A9yT57yzI3BdfvsX5zmuSvOJm1DimgGY9nCJUzUEYG0a1Dhh
|
|
26
|
-
/rqObPoVIFGesmvwflVYFktmVHk7ycEDVreSTz23cvmraPz1fnpdKeuEs4sRQJV7
|
|
27
|
-
iJhLoxX5SJlJc0RXMhgHGQ==
|
|
28
|
-
-----END PRIVATE KEY-----
|
|
1
|
+
-----BEGIN PRIVATE KEY-----
|
|
2
|
+
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDZqbS9hNS38Atc
|
|
3
|
+
A7Uszq7EA7RavuHc8AcpbURa6Y7NORs0SmfDD0oLptQ7DX5pSuHyOeDHzQ3UXRCU
|
|
4
|
+
DAhAD1XlaYQ6PPdiJPRAe4ACELzgDzepxVz3pdKPcfXd5/mHV3ghUZya2XW5DSF1
|
|
5
|
+
CRYUX2j10a+JORJIG4bhvTg4HxTJZZDuaNfBMC6ZSn7d9YLQoAf1MLLJm43Ycj1W
|
|
6
|
+
lOnyG4DHxNEqEk260BlbBywJH+SJA6GA0GR2bnzYZaDnZ0wqea0Zamx8ijpdJxBU
|
|
7
|
+
xYOqLfzs2KREVkkGOmsFEu82W6G3D4bKsY1UNaWXb/jcl3UkXIJJij6CdbbMQkUJ
|
|
8
|
+
c8dow3sVAgMBAAECggEANgLpITAhcuVDhFk9L3m4H1bF/dCpDmCXfl2pXR/guicm
|
|
9
|
+
C4M9HUeheaOzvVWbXThiOe/HyfylpmFTmFEmCPNlPrDAyYzQXE/MNmYO/TQ3Eihk
|
|
10
|
+
iSG68I764XKHbsG+Byoa2rW8NSaqEjniZ/7Rtkt4qasXMmdxlGgUP9bq6O45g8HV
|
|
11
|
+
kHxneFlA2KbrvmWnBi7NTea9+tp61NWiq5n97UgHacQR6KkYIpbxd7uNSnCSdmXt
|
|
12
|
+
pcwzO4ZPabJ2/DKRjePhU5OggPh+9AhJ3jsBo99GwYPgSZDh8E3vh2OWOtLBMUH3
|
|
13
|
+
rmAYwlRT2aZ5hy5yi+4QD98WoUQtsr+9n757F8V6MQKBgQDzZycdgaKwWd5d34NN
|
|
14
|
+
0TkFtPQPwxxJTCCs3I3q02uWcS3svQzBK0cWb4nISO04TnJ3MnXo83dgGhCMF+uZ
|
|
15
|
+
FCXxAA53z8F92iZo+ELlXFDFwNeNYih/afDA42tWZ6TlVsDnZ4zQgRjHS7jEF/JV
|
|
16
|
+
0ZgwGpw5725JQt64dic8wTOcDQKBgQDk7YYACQcWTnmjDhZQ3PZSX4fcTtzPZKZj
|
|
17
|
+
fa1GrXEaUH1hSyc9VmY6qJpUmXexpvtr194nXE+O5wbThOHcBjVlo2Qv+vswmUX3
|
|
18
|
+
WEcVzTVN4/fODCLCqFcMNIr+BzwZfwpT+p0u8g9FxDy1gGmvkxwIu8DCpnUT12Xj
|
|
19
|
+
hm2wO+UxKQKBgFxCSDBF9+2SUtgQJYv0dwGzwiLLWMhro6MCAoT02D3w7nBihBgg
|
|
20
|
+
GFTnuDkDc285ROfrZ4gB6MizeHwxgOrIGU2NMO62/+d9LbvyBiE76Z3bZ5i+kQ0i
|
|
21
|
+
kc/7I69fn8ASLxJHTLenh0XbbNBfJ0riJCZvn7HSEGKShysyFdNQhAhtAoGAFYVi
|
|
22
|
+
0IQIv4cXFkYPwQBUw7+pVQOw7GpI3heFf5x0goXIk6nuAW0q5R7Oi192CiRphGTh
|
|
23
|
+
xI+ABy4ezSmz1exbfreShpQwowv1sOACpsEI3s6skBlB90y+Ci6yVlk1xCvWO7jW
|
|
24
|
+
qAAngWaGUoXE6bWJsCR+ZY4ieYAJWw9bJnMrA6kCgYAzV4Xeoh5ofENZM21wKW3W
|
|
25
|
+
iCzRibPObv6Vb/j9A9yT57yzI3BdfvsX5zmuSvOJm1DimgGY9nCJUzUEYG0a1Dhh
|
|
26
|
+
/rqObPoVIFGesmvwflVYFktmVHk7ycEDVreSTz23cvmraPz1fnpdKeuEs4sRQJV7
|
|
27
|
+
iJhLoxX5SJlJc0RXMhgHGQ==
|
|
28
|
+
-----END PRIVATE KEY-----
|
package/test/ia-topnav.test.ts
CHANGED
|
@@ -9,9 +9,35 @@ import {
|
|
|
9
9
|
|
|
10
10
|
import '../src/ia-topnav';
|
|
11
11
|
import { IATopNav } from '../src/ia-topnav';
|
|
12
|
+
import { SearchMenu } from '../src/search-menu';
|
|
12
13
|
import { SignedOutDropdown } from '../src/signed-out-dropdown';
|
|
13
14
|
import UserMenu from '../src/user-menu';
|
|
14
15
|
|
|
16
|
+
// const container = (
|
|
17
|
+
// {
|
|
18
|
+
// username = '',
|
|
19
|
+
// screenName = '',
|
|
20
|
+
// config = {},
|
|
21
|
+
// localLinks = true,
|
|
22
|
+
// secondIdentitySlotMode = '',
|
|
23
|
+
// }: {
|
|
24
|
+
// username?: string;
|
|
25
|
+
// screenName?: string;
|
|
26
|
+
// config?: IATopNavConfig;
|
|
27
|
+
// localLinks: boolean;
|
|
28
|
+
// secondIdentitySlotMode?: IATopNavSecondIdentitySlotMode;
|
|
29
|
+
// } = {
|
|
30
|
+
// localLinks: true,
|
|
31
|
+
// },
|
|
32
|
+
// ) =>
|
|
33
|
+
// html`<ia-topnav
|
|
34
|
+
// .screenName=${screenName}
|
|
35
|
+
// username=${username}
|
|
36
|
+
// ?localLinks=${localLinks}
|
|
37
|
+
// .config=${config}
|
|
38
|
+
// .secondIdentitySlotMode=${secondIdentitySlotMode}
|
|
39
|
+
// ></ia-topnav>`;
|
|
40
|
+
|
|
15
41
|
const verifyClosed = (instance: IATopNav) => {
|
|
16
42
|
expect(instance.mediaSliderOpen).to.be.false;
|
|
17
43
|
expect(instance.selectedMenuOption).to.equal('');
|
|
@@ -27,6 +53,25 @@ afterEach(() => {
|
|
|
27
53
|
});
|
|
28
54
|
|
|
29
55
|
describe('<ia-topnav>', () => {
|
|
56
|
+
it('assigns a value to "search in" from outside event', async () => {
|
|
57
|
+
const el = await fixture<IATopNav>(html` <ia-topnav></ia-topnav>`);
|
|
58
|
+
const query = 'atari';
|
|
59
|
+
const searchMenu = el.shadowRoot?.querySelector(
|
|
60
|
+
'search-menu',
|
|
61
|
+
) as SearchMenu;
|
|
62
|
+
|
|
63
|
+
const inputEvent = new InputEvent('input');
|
|
64
|
+
Object.defineProperty(inputEvent, 'target', {
|
|
65
|
+
value: { value: query },
|
|
66
|
+
writable: false,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
searchMenu?.searchInChanged(inputEvent);
|
|
70
|
+
await el.updateComplete;
|
|
71
|
+
|
|
72
|
+
expect(el.searchIn).to.equal(query);
|
|
73
|
+
});
|
|
74
|
+
|
|
30
75
|
it('dispatches an analyticsClick event when trackClick event fired', async () => {
|
|
31
76
|
const el = await fixture<IATopNav>(html` <ia-topnav></ia-topnav>`);
|
|
32
77
|
const clickEvent = new MouseEvent('click');
|
|
@@ -42,6 +87,22 @@ describe('<ia-topnav>', () => {
|
|
|
42
87
|
expect(response).to.exist;
|
|
43
88
|
});
|
|
44
89
|
|
|
90
|
+
it('dispatches an analyticsSubmit event when trackSubmit event fired', async () => {
|
|
91
|
+
const el = await fixture<IATopNav>(html` <ia-topnav></ia-topnav>`);
|
|
92
|
+
const submitEvent = new Event('submit');
|
|
93
|
+
const form = el.shadowRoot
|
|
94
|
+
?.querySelector('primary-nav')
|
|
95
|
+
?.shadowRoot?.querySelector('nav-search')
|
|
96
|
+
?.shadowRoot?.querySelector('form');
|
|
97
|
+
|
|
98
|
+
form?.addEventListener('submit', (e) => e.preventDefault());
|
|
99
|
+
(form?.querySelector('[name=query]') as HTMLInputElement).value = 'atari';
|
|
100
|
+
setTimeout(() => form?.dispatchEvent(submitEvent));
|
|
101
|
+
const response = await oneEvent(el, 'trackSubmit');
|
|
102
|
+
|
|
103
|
+
expect(response).to.exist;
|
|
104
|
+
});
|
|
105
|
+
|
|
45
106
|
it('closes all menus when close-layer clicked', async () => {
|
|
46
107
|
const el = await fixture<IATopNav>(html` <ia-topnav></ia-topnav>`);
|
|
47
108
|
|
|
@@ -129,6 +190,17 @@ describe('<ia-topnav>', () => {
|
|
|
129
190
|
expect(el.selectedMenuOption).to.equal('');
|
|
130
191
|
});
|
|
131
192
|
|
|
193
|
+
it('toggles search menu tabindex when dropdown open', async () => {
|
|
194
|
+
const el = await fixture<IATopNav>(html` <ia-topnav></ia-topnav>`);
|
|
195
|
+
|
|
196
|
+
el.openMenu = 'search';
|
|
197
|
+
await el.updateComplete;
|
|
198
|
+
|
|
199
|
+
expect(
|
|
200
|
+
el.shadowRoot?.querySelector('search-menu')?.getAttribute('tabindex'),
|
|
201
|
+
).to.equal('');
|
|
202
|
+
});
|
|
203
|
+
|
|
132
204
|
it('toggles user menu tabindex when dropdown open', async () => {
|
|
133
205
|
const el = await fixture<IATopNav>(
|
|
134
206
|
html` <ia-topnav username="shaneriley" ?localLinks=${false}></ia-topnav>`,
|
|
@@ -174,6 +246,11 @@ describe('<ia-topnav>', () => {
|
|
|
174
246
|
screenName="shaneriley"
|
|
175
247
|
?localLinks=${false}
|
|
176
248
|
></ia-topnav>`,
|
|
249
|
+
// container({
|
|
250
|
+
// username: 'shaneriley',
|
|
251
|
+
// screenName: 'shaneriley',
|
|
252
|
+
// localLinks: false,
|
|
253
|
+
// }),
|
|
177
254
|
);
|
|
178
255
|
|
|
179
256
|
(
|
|
@@ -205,6 +282,7 @@ describe('<ia-topnav>', () => {
|
|
|
205
282
|
'primary-nav',
|
|
206
283
|
'media-slider',
|
|
207
284
|
'desktop-subnav',
|
|
285
|
+
'search-menu',
|
|
208
286
|
];
|
|
209
287
|
componentSelectors.forEach((selector) => {
|
|
210
288
|
const component = el.shadowRoot?.querySelector(selector) as unknown as {
|
|
@@ -235,24 +313,6 @@ describe('<ia-topnav>', () => {
|
|
|
235
313
|
});
|
|
236
314
|
});
|
|
237
315
|
|
|
238
|
-
describe('search slot', () => {
|
|
239
|
-
it('forwards search slot to primary-nav', async () => {
|
|
240
|
-
const el = await fixture<IATopNav>(html`<ia-topnav></ia-topnav>`);
|
|
241
|
-
await el.updateComplete;
|
|
242
|
-
|
|
243
|
-
const primaryNav = el.shadowRoot?.querySelector('primary-nav');
|
|
244
|
-
const slot = primaryNav?.querySelector('slot[name="search"]');
|
|
245
|
-
expect(slot).to.exist;
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
it('does not render search-menu', async () => {
|
|
249
|
-
const el = await fixture<IATopNav>(html`<ia-topnav></ia-topnav>`);
|
|
250
|
-
await el.updateComplete;
|
|
251
|
-
|
|
252
|
-
expect(el.shadowRoot?.querySelector('search-menu')).to.not.exist;
|
|
253
|
-
});
|
|
254
|
-
});
|
|
255
|
-
|
|
256
316
|
describe('slot pass throughs', () => {
|
|
257
317
|
describe('slot for <primary-nav>', () => {
|
|
258
318
|
it('opens a slot with `secondIdentitySlotMode`', async () => {
|
|
@@ -267,14 +327,15 @@ describe('<ia-topnav>', () => {
|
|
|
267
327
|
|
|
268
328
|
const slot = el.shadowRoot
|
|
269
329
|
?.querySelector('primary-nav')
|
|
270
|
-
?.querySelector('slot
|
|
330
|
+
?.querySelector('slot');
|
|
271
331
|
expect(slot).to.exist;
|
|
332
|
+
expect(slot?.getAttribute('name')).to.equal('opt-sec-logo');
|
|
272
333
|
|
|
273
334
|
el.secondIdentitySlotMode = '';
|
|
274
335
|
await elementUpdated(el);
|
|
275
336
|
const noSlot = el.shadowRoot
|
|
276
337
|
?.querySelector('primary-nav')
|
|
277
|
-
?.querySelector('slot
|
|
338
|
+
?.querySelector('slot');
|
|
278
339
|
expect(noSlot).to.not.exist;
|
|
279
340
|
});
|
|
280
341
|
});
|
package/test/primary-nav.test.ts
CHANGED
|
@@ -50,7 +50,7 @@ describe('<primary-nav>', () => {
|
|
|
50
50
|
expect(el.shadowRoot?.querySelector('login-button')).to.not.be.undefined;
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
-
it('does not render search
|
|
53
|
+
it('does not render search menu toggle and search form if hideSearch true', async () => {
|
|
54
54
|
const el = await fixture<PrimaryNav>(
|
|
55
55
|
component({
|
|
56
56
|
baseHost: 'archive.org',
|
|
@@ -61,48 +61,7 @@ describe('<primary-nav>', () => {
|
|
|
61
61
|
);
|
|
62
62
|
|
|
63
63
|
expect(el.shadowRoot?.querySelector('.search-trigger')).to.equal(null);
|
|
64
|
-
expect(el.shadowRoot?.querySelector('
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('renders search slot container', async () => {
|
|
68
|
-
const el = await fixture<PrimaryNav>(
|
|
69
|
-
component({
|
|
70
|
-
baseHost: 'archive.org',
|
|
71
|
-
username: 'testuser',
|
|
72
|
-
screenName: 'testuser',
|
|
73
|
-
}),
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
expect(el.shadowRoot?.querySelector('.search-container')).to.exist;
|
|
77
|
-
|
|
78
|
-
const slot = el.shadowRoot?.querySelector<HTMLSlotElement>(
|
|
79
|
-
'slot[name="search"]',
|
|
80
|
-
);
|
|
81
|
-
expect(slot).to.exist;
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it('renders search trigger button for mobile toggle', async () => {
|
|
85
|
-
const el = await fixture<PrimaryNav>(
|
|
86
|
-
component({
|
|
87
|
-
baseHost: 'archive.org',
|
|
88
|
-
username: 'testuser',
|
|
89
|
-
screenName: 'testuser',
|
|
90
|
-
}),
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
expect(el.shadowRoot?.querySelector('.search-trigger')).to.exist;
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
it('does not render nav-search', async () => {
|
|
97
|
-
const el = await fixture<PrimaryNav>(
|
|
98
|
-
component({
|
|
99
|
-
baseHost: 'archive.org',
|
|
100
|
-
username: 'testuser',
|
|
101
|
-
screenName: 'testuser',
|
|
102
|
-
}),
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
expect(el.shadowRoot?.querySelector('nav-search')).to.not.exist;
|
|
64
|
+
expect(el.shadowRoot?.querySelector('nav-search')).to.equal(null);
|
|
106
65
|
});
|
|
107
66
|
|
|
108
67
|
it('opens a slot with `secondIdentitySlotMode`', async () => {
|