geico-design-kit 7.0.0
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.
Potentially problematic release.
This version of geico-design-kit might be problematic. Click here for more details.
- package/.babelrc +5 -0
- package/LICENSE +0 -0
- package/dist/analytics.js +119 -0
- package/dist/appState.js +56 -0
- package/dist/baseComponent.js +110 -0
- package/dist/components/Accordion.js +312 -0
- package/dist/components/AddressAutoComplete.js +220 -0
- package/dist/components/Alert.js +145 -0
- package/dist/components/BackgroundPattern.js +99 -0
- package/dist/components/BackgroundPatternPortfolio.js +242 -0
- package/dist/components/ButtonSwitch.js +236 -0
- package/dist/components/CardSelections.js +230 -0
- package/dist/components/CommonQuestionsSquares.js +169 -0
- package/dist/components/Confirmation.js +156 -0
- package/dist/components/ConsolidatedSummary.js +489 -0
- package/dist/components/CoverageGraph.js +201 -0
- package/dist/components/CreditCard.js +591 -0
- package/dist/components/CurrencyInput.js +302 -0
- package/dist/components/DatePicker.js +468 -0
- package/dist/components/DockedMessage.js +146 -0
- package/dist/components/DotNavigation.js +200 -0
- package/dist/components/EditComponent.js +128 -0
- package/dist/components/EditableTable.js +113 -0
- package/dist/components/InPageNavigation.js +360 -0
- package/dist/components/Loader.js +232 -0
- package/dist/components/MakePayment.js +361 -0
- package/dist/components/Modal.js +254 -0
- package/dist/components/MoreInfoButton.js +227 -0
- package/dist/components/MultipleSelectBox.js +217 -0
- package/dist/components/NavigationalBox.js +161 -0
- package/dist/components/Navigator.js +294 -0
- package/dist/components/PasswordMeter.js +201 -0
- package/dist/components/PayPlans.js +534 -0
- package/dist/components/SegmentedControl.js +327 -0
- package/dist/components/SortableTable.js +166 -0
- package/dist/components/Tabs.js +1 -0
- package/dist/components/TextAreaCountdown.js +219 -0
- package/dist/components/Timeline.js +498 -0
- package/dist/components/TimelineFilter.js +492 -0
- package/dist/components/ToTopArrow.js +153 -0
- package/dist/components/Tooltip.js +329 -0
- package/dist/components/Upsell.js +168 -0
- package/dist/components/VIN.js +271 -0
- package/dist/components/ValidateForm.js +938 -0
- package/dist/components/ViewMoreLess.js +191 -0
- package/dist/components/ZipCode.js +191 -0
- package/dist/components/portfolio.js +99 -0
- package/dist/geico-design-kit.js +141 -0
- package/dist/global/components.js +98 -0
- package/dist/global/footer.js +26 -0
- package/dist/global/nav.js +1257 -0
- package/dist/services/CharacterTypeService.js +106 -0
- package/dist/services/UserAgentService.js +73 -0
- package/dist/utils.js +79 -0
- package/package.json +32 -0
- package/src/analytics.js +82 -0
- package/src/appState.js +56 -0
- package/src/baseComponent.js +156 -0
- package/src/components/Accordion.js +336 -0
- package/src/components/AddressAutoComplete.js +236 -0
- package/src/components/Alert.js +135 -0
- package/src/components/BackgroundPattern.js +96 -0
- package/src/components/BackgroundPatternPortfolio.js +284 -0
- package/src/components/ButtonSwitch.js +241 -0
- package/src/components/CardSelections.js +240 -0
- package/src/components/CommonQuestionsSquares.js +179 -0
- package/src/components/Confirmation.js +160 -0
- package/src/components/ConsolidatedSummary.js +505 -0
- package/src/components/CoverageGraph.js +203 -0
- package/src/components/CreditCard.js +595 -0
- package/src/components/CurrencyInput.js +321 -0
- package/src/components/DatePicker.js +487 -0
- package/src/components/DockedMessage.js +142 -0
- package/src/components/DotNavigation.js +206 -0
- package/src/components/EditComponent.js +130 -0
- package/src/components/EditableTable.js +106 -0
- package/src/components/InPageNavigation.js +391 -0
- package/src/components/Loader.js +272 -0
- package/src/components/MakePayment.js +397 -0
- package/src/components/Modal.js +279 -0
- package/src/components/MoreInfoButton.js +243 -0
- package/src/components/MultipleSelectBox.js +211 -0
- package/src/components/NavigationalBox.js +163 -0
- package/src/components/Navigator.js +338 -0
- package/src/components/PasswordMeter.js +209 -0
- package/src/components/PayPlans.js +604 -0
- package/src/components/SegmentedControl.js +365 -0
- package/src/components/SortableTable.js +176 -0
- package/src/components/Tabs.js +0 -0
- package/src/components/TextAreaCountdown.js +231 -0
- package/src/components/Timeline.js +532 -0
- package/src/components/TimelineFilter.js +533 -0
- package/src/components/ToTopArrow.js +153 -0
- package/src/components/Tooltip.js +344 -0
- package/src/components/Upsell.js +196 -0
- package/src/components/VIN.js +289 -0
- package/src/components/ValidateForm.js +1030 -0
- package/src/components/ViewMoreLess.js +193 -0
- package/src/components/ZipCode.js +193 -0
- package/src/components/portfolio.js +106 -0
- package/src/geico-design-kit.js +144 -0
- package/src/global/components.js +92 -0
- package/src/global/footer.js +25 -0
- package/src/global/nav.js +1457 -0
- package/src/services/CharacterTypeService.js +107 -0
- package/src/services/UserAgentService.js +59 -0
- package/src/utils.js +82 -0
|
@@ -0,0 +1,1457 @@
|
|
|
1
|
+
import * as utils from '../utils';
|
|
2
|
+
import appState from '../appState';
|
|
3
|
+
|
|
4
|
+
//Global nav vars
|
|
5
|
+
let body,
|
|
6
|
+
header,
|
|
7
|
+
headerAnchors,
|
|
8
|
+
nav,
|
|
9
|
+
navBackground,
|
|
10
|
+
actionableIcons,
|
|
11
|
+
submenuWrapper,
|
|
12
|
+
panelTriggers,
|
|
13
|
+
headerLinks,
|
|
14
|
+
currentlyOpenPanel,
|
|
15
|
+
currentlyOpenSubPanel,
|
|
16
|
+
panels,
|
|
17
|
+
panelUL,
|
|
18
|
+
panelIsOpen = false,
|
|
19
|
+
hover_timer,
|
|
20
|
+
panel_timer,
|
|
21
|
+
open_timer,
|
|
22
|
+
svgAnim_timer,
|
|
23
|
+
currentNavState,
|
|
24
|
+
mainListItems,
|
|
25
|
+
mainListItemsAnchor,
|
|
26
|
+
mainListItemsAnchorMobile,
|
|
27
|
+
mainListItemsAnchorRightMobile,
|
|
28
|
+
mobilenavaccordionHeadlines,
|
|
29
|
+
secondaryListItemsAnchorMobile,
|
|
30
|
+
svgToAnim,
|
|
31
|
+
subpanelName,
|
|
32
|
+
hamburgerIcons,
|
|
33
|
+
dashOffsetEnd = 180,//svg animation settings
|
|
34
|
+
dashArrayComplete = 183,//svg animation settings
|
|
35
|
+
tickSpeed = 3.5,//svg animation settings
|
|
36
|
+
tickSpeedMobile = 5,//svg animation settings
|
|
37
|
+
tick = 0;//svg animation settings
|
|
38
|
+
var isHovering = false;
|
|
39
|
+
var isTouch = false;
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
function init(config) {
|
|
43
|
+
|
|
44
|
+
if(!config || config.generateMobileNavHtml) {
|
|
45
|
+
generateMobileMenuElements(config);
|
|
46
|
+
/*
|
|
47
|
+
* At this point the mobile nav has been generated so we
|
|
48
|
+
* can initialize the view-more-less components for the first menu tier.
|
|
49
|
+
* */
|
|
50
|
+
var mobileNav = new GDK.Accordion({
|
|
51
|
+
"content" : "#mobile-nav",
|
|
52
|
+
"forceOpenSingleAccordionElement" : true
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
console.log('Initialized Navigation');
|
|
58
|
+
|
|
59
|
+
findDomElements();
|
|
60
|
+
|
|
61
|
+
if (appState.mode === "mobile") {
|
|
62
|
+
body.style.overflowX = "hidden";
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
//add the navigation background
|
|
66
|
+
nav.insertAdjacentHTML('afterBegin', '<div id="nav-background"></div>');
|
|
67
|
+
navBackground = document.getElementById('nav-background');
|
|
68
|
+
|
|
69
|
+
addSVGs();
|
|
70
|
+
addHamburgerMarkup();
|
|
71
|
+
|
|
72
|
+
if (appState.mode === "desktop") {
|
|
73
|
+
currentNavState = "desktop";
|
|
74
|
+
|
|
75
|
+
if (appState.isTouchDevice) {
|
|
76
|
+
initDesktopTouchEvents();
|
|
77
|
+
} else {
|
|
78
|
+
initDesktopEvents();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
} else {
|
|
82
|
+
currentNavState = "mobile";
|
|
83
|
+
|
|
84
|
+
if (appState.isTouchDevice) {
|
|
85
|
+
initMobileTouchEvents();
|
|
86
|
+
} else {
|
|
87
|
+
initMobileEvents();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if(document.querySelector('.skip-to-content')&&(!document.body.classList.contains('with-unsupported-browser')||!document.querySelector('.unsupported-browser'))){
|
|
93
|
+
document.querySelector('.skip-to-content').addEventListener('blur', function(){document.querySelector('#primary-header').style.top = '0';});
|
|
94
|
+
document.querySelector('.skip-to-content').addEventListener('focus', function(){document.querySelector('#primary-header').style.top = '2rem';});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
Array.prototype.forEach.call(headerAnchors, function (el, i) {
|
|
98
|
+
el.setAttribute('aria-expanded', 'false');
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
window.addEventListener('resize', handleResize);
|
|
102
|
+
handleResize();
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
//for IE
|
|
106
|
+
Array.prototype.forEach.call(mainListItemsAnchor, function (el, i) {
|
|
107
|
+
el.addEventListener('pointerdown', function(e){
|
|
108
|
+
if(e.pointerType=='touch' && el.parentNode.querySelector('.geico-nav-menu-secondary-wrapper')){
|
|
109
|
+
e.preventDefault();
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
//for IE, Chrome, FF - affects all browsers
|
|
115
|
+
document.querySelector('#primary-header').addEventListener('mouseover', function(){
|
|
116
|
+
if(isHovering === false){
|
|
117
|
+
isHovering = true;
|
|
118
|
+
isTouch = false;
|
|
119
|
+
|
|
120
|
+
appState.isTouchDevice = false;
|
|
121
|
+
|
|
122
|
+
removeNavEvents();
|
|
123
|
+
if (appState.mode === "desktop") {
|
|
124
|
+
currentNavState = "desktop";
|
|
125
|
+
|
|
126
|
+
if (appState.isTouchDevice) {
|
|
127
|
+
initDesktopTouchEvents();
|
|
128
|
+
} else {
|
|
129
|
+
initDesktopEvents();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
} else {
|
|
133
|
+
currentNavState = "mobile";
|
|
134
|
+
|
|
135
|
+
if (appState.isTouchDevice) {
|
|
136
|
+
initMobileTouchEvents();
|
|
137
|
+
} else {
|
|
138
|
+
initMobileEvents();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function closeAccordionsMobileNav() {
|
|
149
|
+
let openAccordians = document.querySelector('#mobile-nav').querySelectorAll(".accordion > li.open");
|
|
150
|
+
Array.prototype.forEach.call(openAccordians, (el, i)=>{
|
|
151
|
+
el.classList.remove("open");
|
|
152
|
+
let contentContainer = el.querySelector(".accordion-content-container");
|
|
153
|
+
contentContainer.style.display="none";
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* findDomElements()
|
|
160
|
+
* Finds all Dom elements needed to run the navigation functionality
|
|
161
|
+
*/
|
|
162
|
+
function findDomElements() {
|
|
163
|
+
body = document.getElementsByTagName('body')[0];
|
|
164
|
+
header = document.getElementById('primary-header');
|
|
165
|
+
nav = document.getElementById('primary-navigation');
|
|
166
|
+
|
|
167
|
+
//find all header anchors
|
|
168
|
+
headerAnchors = header.querySelectorAll('a');
|
|
169
|
+
|
|
170
|
+
//finds any dom elements that have a data attribute of side-panel.
|
|
171
|
+
//Any header element that opens a panel should have this data attribute, so we know which panel to open
|
|
172
|
+
panelTriggers = header.querySelectorAll('[data-side-panel-trigger]');
|
|
173
|
+
headerLinks = header.querySelectorAll('a');
|
|
174
|
+
panels = nav.querySelectorAll('.panel-wrapper');
|
|
175
|
+
|
|
176
|
+
//find all the submenus
|
|
177
|
+
submenuWrapper = nav.querySelectorAll('.geico-nav-menu-secondary-wrapper');
|
|
178
|
+
|
|
179
|
+
//find all hamburger icons
|
|
180
|
+
hamburgerIcons = header.querySelectorAll('.hamburger-menu');
|
|
181
|
+
|
|
182
|
+
//find all the actionable-icons
|
|
183
|
+
actionableIcons = nav.querySelectorAll('a .geico-icon--actionable');
|
|
184
|
+
|
|
185
|
+
Array.prototype.forEach.call(actionableIcons, function (el, i) {
|
|
186
|
+
el.style.width = "60px";
|
|
187
|
+
el.style.height = "60px";
|
|
188
|
+
el.style.lineHeight = "60px";
|
|
189
|
+
el.style.fontSize = "30px";
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
//find all first level li's for mobile
|
|
194
|
+
mainListItems = nav.querySelectorAll('.panel-wrapper > ul > li');
|
|
195
|
+
mainListItemsAnchor = nav.querySelectorAll('.panel-wrapper > ul > li > a');
|
|
196
|
+
mainListItemsAnchorMobile = nav.querySelectorAll('.panel-wrapper > #mobile-nav > li > .accordion-content-container > div > ul > li > a');
|
|
197
|
+
mainListItemsAnchorRightMobile = nav.querySelectorAll('.panel-wrapper.right > ul > li > a');
|
|
198
|
+
mobilenavaccordionHeadlines = nav.querySelectorAll('.panel-wrapper > #mobile-nav > li > .accordion-headline');
|
|
199
|
+
secondaryListItemsAnchorMobile = nav.querySelectorAll('.panel-wrapper > #mobile-nav .geico-nav-menu-secondary-wrapper > ul > li > a');
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
panelUL = nav.querySelectorAll('.panel-wrapper > ul');
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Svetoslav Kostadinov
|
|
209
|
+
* 07.Jan.2106
|
|
210
|
+
*
|
|
211
|
+
* Generate mobile navigation markup.
|
|
212
|
+
*/
|
|
213
|
+
function generateMobileMenuElements(config) {
|
|
214
|
+
|
|
215
|
+
let navContainer = document.querySelectorAll('#primary-navigation')[0];
|
|
216
|
+
/* Delete any existing Mobile Nav */
|
|
217
|
+
if(navContainer.querySelector('[data-side-panel="mobile-menu"]') !== null) {
|
|
218
|
+
navContainer.removeChild(navContainer.querySelector('[data-side-panel="mobile-menu"]'));
|
|
219
|
+
}
|
|
220
|
+
let mobileNavDiv = navContainer.cloneNode(true);
|
|
221
|
+
|
|
222
|
+
// Create the mobile menu element
|
|
223
|
+
let navMobilePanelWrapper = document.createElement('div');
|
|
224
|
+
navMobilePanelWrapper.className = 'panel-wrapper';
|
|
225
|
+
navMobilePanelWrapper.setAttribute('data-side-panel', 'mobile-menu');
|
|
226
|
+
|
|
227
|
+
// Generate the mobile nav shell
|
|
228
|
+
let mobileNavigation = document.createElement('ul');
|
|
229
|
+
mobileNavigation.setAttribute('id', 'mobile-nav');
|
|
230
|
+
mobileNavigation.setAttribute('class', 'accordion');
|
|
231
|
+
|
|
232
|
+
// generate the search form section
|
|
233
|
+
if(config && config.mobileSearchForm) {
|
|
234
|
+
let searchForm = document.createElement('form');
|
|
235
|
+
searchForm.setAttribute('method', config.mobileSearchForm.method);
|
|
236
|
+
searchForm.setAttribute('action', config.mobileSearchForm.action);
|
|
237
|
+
searchForm.setAttribute('class', 'search-box');
|
|
238
|
+
|
|
239
|
+
let searchInputField = document.createElement('input');
|
|
240
|
+
searchInputField.setAttribute('type', 'text');
|
|
241
|
+
searchInputField.setAttribute('class', 'search-input');
|
|
242
|
+
searchInputField.setAttribute('placeholder', config.mobileSearchForm.placeholder);
|
|
243
|
+
searchInputField.setAttribute('name', config.mobileSearchForm.name);
|
|
244
|
+
searchInputField.setAttribute('aria-label', config.mobileSearchForm.ariaLabel);
|
|
245
|
+
|
|
246
|
+
let searchSubmitButton = document.createElement('button');
|
|
247
|
+
searchSubmitButton.setAttribute('type', 'submit');
|
|
248
|
+
searchSubmitButton.setAttribute('class', 'icon-search small');
|
|
249
|
+
|
|
250
|
+
// assemble the search form
|
|
251
|
+
searchForm.appendChild(searchInputField);
|
|
252
|
+
searchForm.appendChild(searchSubmitButton);
|
|
253
|
+
|
|
254
|
+
let searchResultField = document.createElement('ul');
|
|
255
|
+
searchResultField.setAttribute('class', 'dropdown-list');
|
|
256
|
+
searchResultField.setAttribute('style', 'display: none');
|
|
257
|
+
|
|
258
|
+
// Add the search form to the Mobile Nav before the Tier One Elements Loop
|
|
259
|
+
navMobilePanelWrapper.appendChild(searchForm);
|
|
260
|
+
navMobilePanelWrapper.appendChild(searchResultField);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
let mobileHeader = document.querySelector('#primary-header').cloneNode(true);
|
|
264
|
+
let primaryHeaderLeftAnchors = mobileHeader.querySelectorAll('#header-left-links .desktop-links a');
|
|
265
|
+
let nonMenuAnchorUL = document.createElement('UL');
|
|
266
|
+
Array.prototype.forEach.call(primaryHeaderLeftAnchors, function(el, i){
|
|
267
|
+
if(!el.getAttribute('data-side-panel-trigger')){
|
|
268
|
+
let justAnchorLI = document.createElement('LI');
|
|
269
|
+
let anchorTextNode = document.createTextNode(el.innerHTML);
|
|
270
|
+
el.innerHTML = "";
|
|
271
|
+
let justAnchorSpan = document.createElement('SPAN');
|
|
272
|
+
justAnchorSpan.classList.add('geico-nav-menu-item');
|
|
273
|
+
justAnchorSpan.appendChild(anchorTextNode);
|
|
274
|
+
el.appendChild(justAnchorSpan);
|
|
275
|
+
justAnchorLI.appendChild(el);
|
|
276
|
+
nonMenuAnchorUL.appendChild(justAnchorLI);
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
// generate nav tier 1 elements
|
|
283
|
+
// pull nav elements from the desktop main menu.
|
|
284
|
+
let navElementsArray = mobileNavDiv.querySelectorAll('.panel-wrapper');
|
|
285
|
+
// Loop through and generate the mobile menu structure.
|
|
286
|
+
Array.prototype.forEach.call(navElementsArray, function(element, i){
|
|
287
|
+
if(element.className.indexOf("no-mobile") === -1) {
|
|
288
|
+
let tierOneElement = document.createElement('li');
|
|
289
|
+
|
|
290
|
+
// Element Headline and Label
|
|
291
|
+
let tierOneHeadline = document.createElement('div');
|
|
292
|
+
tierOneHeadline.setAttribute('class', 'accordion-headline');
|
|
293
|
+
tierOneHeadline.setAttribute('tabindex', '0');
|
|
294
|
+
let tierOneHeadlineH3 = document.createElement('h3');
|
|
295
|
+
tierOneHeadlineH3.innerHTML = element.getAttribute('data-side-panel').capitalizeFirstLetter();
|
|
296
|
+
tierOneHeadline.appendChild(tierOneHeadlineH3);
|
|
297
|
+
|
|
298
|
+
//element content container
|
|
299
|
+
let tierOneContentContainer = document.createElement('div');
|
|
300
|
+
tierOneContentContainer.setAttribute('class', 'accordion-content-container');
|
|
301
|
+
|
|
302
|
+
let tierOneContent = document.createElement('div');
|
|
303
|
+
tierOneContent.setAttribute('class', 'accordion-content');
|
|
304
|
+
tierOneContent.setAttribute('data-side-panel', 'mobile-menu');
|
|
305
|
+
|
|
306
|
+
let tierOneContentUl = document.createElement('ul');
|
|
307
|
+
// fill the ul with tier 2 and 3 elements.
|
|
308
|
+
Array.prototype.forEach.call(element.querySelectorAll('ul>li[data-name]'), function(el, i){
|
|
309
|
+
|
|
310
|
+
let classNames = el.className;
|
|
311
|
+
let classArray = classNames.split(' ');
|
|
312
|
+
|
|
313
|
+
el.className = classArray.join(' ');
|
|
314
|
+
tierOneContentUl.appendChild(el);
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
// assemble the navigation
|
|
318
|
+
tierOneContent.appendChild(tierOneContentUl);
|
|
319
|
+
tierOneContentContainer.appendChild(tierOneContent);
|
|
320
|
+
tierOneElement.appendChild(tierOneHeadline);
|
|
321
|
+
tierOneElement.appendChild(tierOneContentContainer);
|
|
322
|
+
mobileNavigation.appendChild(tierOneElement);
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
navMobilePanelWrapper.appendChild(mobileNavigation);
|
|
327
|
+
navMobilePanelWrapper.appendChild(nonMenuAnchorUL);
|
|
328
|
+
|
|
329
|
+
navContainer.appendChild(navMobilePanelWrapper);
|
|
330
|
+
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Svetoslav Kostadinov
|
|
335
|
+
* 07.Jan.2016
|
|
336
|
+
*
|
|
337
|
+
* @returns {string}
|
|
338
|
+
*/
|
|
339
|
+
String.prototype.capitalizeFirstLetter = function() {
|
|
340
|
+
return this.charAt(0).toUpperCase() + this.slice(1);
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* initDesktopEvents()
|
|
346
|
+
* Initialize all desktop events
|
|
347
|
+
*/
|
|
348
|
+
function initDesktopEvents() {
|
|
349
|
+
console.log("initDesktopEvents");
|
|
350
|
+
|
|
351
|
+
document.addEventListener('keyup', function(e){
|
|
352
|
+
if(document.getElementById('wrapper').contains(e.target)){
|
|
353
|
+
if(e.which == '9' || e.keyCode == '9'){
|
|
354
|
+
if (panelIsOpen) {
|
|
355
|
+
closePanel(currentlyOpenPanel);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
Array.prototype.forEach.call(panelTriggers, function (el, i) {
|
|
362
|
+
el.addEventListener('click', menuEnter);
|
|
363
|
+
el.addEventListener('keydown', menuEnter);
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
Array.prototype.forEach.call(headerLinks, function (el, i) {
|
|
367
|
+
el.addEventListener('mouseenter', displayHoverStyle);
|
|
368
|
+
el.addEventListener('mouseleave', removeHoverStyle);
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
//keyboard navigation events on header anchors
|
|
372
|
+
Array.prototype.forEach.call(headerAnchors, function (el, i) {
|
|
373
|
+
addKeyboardFocus(el);
|
|
374
|
+
el.addEventListener('focus', focusPanel);
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
Array.prototype.forEach.call(mainListItems, function (el, i) {
|
|
378
|
+
el.addEventListener('click', closeAllPanels);
|
|
379
|
+
el.addEventListener('mouseenter', openSubMenu);
|
|
380
|
+
el.addEventListener('focus', openSubMenu, true);
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
//for each submenu wrapper listen for its mouse over
|
|
384
|
+
//so we know when to close the menu when you roll off the submenu
|
|
385
|
+
Array.prototype.forEach.call(submenuWrapper, function (el, i) {
|
|
386
|
+
el.addEventListener('mouseover', submenuWrapperHover);
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
//for each panel listen for its mouse leave so we know when to close the menu
|
|
390
|
+
Array.prototype.forEach.call(panels, function (el, i) {
|
|
391
|
+
el.addEventListener('mouseenter', function(){let dataside = el.getAttribute('data-side-panel');
|
|
392
|
+
Array.prototype.forEach.call(headerAnchors, (el, i) => {
|
|
393
|
+
if (el.getAttribute('data-side-panel-trigger') != dataside) {
|
|
394
|
+
el.classList.add("not-open");
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
});
|
|
398
|
+
let firstFocusableInPanel = nav.querySelectorAll('.first-focusable');
|
|
399
|
+
Array.prototype.forEach.call(firstFocusableInPanel, function(el, i){
|
|
400
|
+
el.addEventListener('keydown', keyPressSearchBackward);
|
|
401
|
+
});
|
|
402
|
+
if(document.querySelector('.search input')){
|
|
403
|
+
document.querySelector('.search input').addEventListener('keydown', keyPressSearchBackward);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
if(!el.classList.contains('search')){
|
|
407
|
+
if (el.querySelector('ul') && el.firstElementChild.nodeName == 'UL' && el.querySelector('ul').firstElementChild && el.querySelector('ul').lastElementChild) {
|
|
408
|
+
el.querySelector('ul').firstElementChild.querySelector('a').addEventListener('keydown', keyPressFirstBackwards);
|
|
409
|
+
if (el.querySelector('ul').lastElementChild.querySelector('.geico-nav-menu-secondary-wrapper')) {
|
|
410
|
+
el.querySelector('ul').lastElementChild.querySelector('.geico-nav-menu-secondary-wrapper').querySelector('ul').lastElementChild.querySelector('a').addEventListener('keydown', keyPressNextTab);
|
|
411
|
+
} else {
|
|
412
|
+
el.querySelector('ul').lastElementChild.querySelector('a').addEventListener('keydown', keyPressNextTab);
|
|
413
|
+
}
|
|
414
|
+
} else {
|
|
415
|
+
if (el.lastElementChild.querySelector('ul') && el.lastElementChild.querySelector('ul').lastElementChild) {
|
|
416
|
+
el.lastElementChild.querySelector('ul').lastElementChild.querySelector('a').addEventListener('keydown', keyPressNextTab);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
navBackground.addEventListener('click', closeAllPanels);
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
function removeHoverStyle(){
|
|
427
|
+
Array.prototype.forEach.call(headerAnchors, (el, i) => {
|
|
428
|
+
if (el != this) {
|
|
429
|
+
el.classList.remove("not-open");
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
function displayHoverStyle(){
|
|
435
|
+
Array.prototype.forEach.call(headerAnchors, (el, i) => {
|
|
436
|
+
if (el != this) {
|
|
437
|
+
el.classList.add("not-open");
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
function keyPressSearchBackward(e){
|
|
444
|
+
if(e.shiftKey && e.keyCode == 9){
|
|
445
|
+
e.preventDefault();
|
|
446
|
+
|
|
447
|
+
let parentPanel = e.target.parentNode.parentNode;
|
|
448
|
+
//to be refined for an easier way to implement this logic
|
|
449
|
+
if(!parentPanel.getAttribute('data-side-panel')){
|
|
450
|
+
parentPanel = parentPanel.parentNode;
|
|
451
|
+
if(!parentPanel.getAttribute('data-side-panel')){
|
|
452
|
+
parentPanel = parentPanel.parentNode;
|
|
453
|
+
if(!parentPanel.getAttribute('data-side-panel')){
|
|
454
|
+
parentPanel = parentPanel.parentNode;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
header.querySelector('[data-side-panel-trigger="' + parentPanel.getAttribute('data-side-panel') + '"]').focus();
|
|
459
|
+
if (appState.mode === "desktop") {
|
|
460
|
+
Array.prototype.forEach.call(headerAnchors, function (el, i) {
|
|
461
|
+
el.removeAttribute('tabindex');
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
function keyPressNextTab(e){
|
|
468
|
+
if(e.shiftKey){
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
else if(e.which == 9 || e.keyCode == 9){
|
|
472
|
+
console.log('tab only');
|
|
473
|
+
console.log(e.target);
|
|
474
|
+
let parentPanel = findUpParent(e.target, 'data-side-panel');
|
|
475
|
+
//let parentPanel = e.target.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;
|
|
476
|
+
//console.log(header.querySelector('[data-side-panel-trigger="' + parentPanel.getAttribute('data-side-panel') + '"]').parentNode);
|
|
477
|
+
header.querySelector('[data-side-panel-trigger="' + parentPanel.getAttribute('data-side-panel') + '"]').parentNode.querySelector('a').focus();
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
function keyPressFirstBackwards(e){
|
|
482
|
+
//header.querySelector('[data-side-panel-trigger="versions"]').focus();
|
|
483
|
+
if(e.shiftKey && e.keyCode == 9){
|
|
484
|
+
e.preventDefault();
|
|
485
|
+
let parentPanel = e.target.parentNode.parentNode.parentNode;
|
|
486
|
+
if(appState.mode == 'desktop'){
|
|
487
|
+
header.querySelector('[data-side-panel-trigger="' + parentPanel.getAttribute('data-side-panel') + '"]').focus();
|
|
488
|
+
}
|
|
489
|
+
else if(appState.mode == 'mobile'){
|
|
490
|
+
header.querySelector('.mobile-links [data-side-panel-trigger="' + parentPanel.getAttribute('data-side-panel') + '"]').focus();
|
|
491
|
+
}
|
|
492
|
+
console.log(parentPanel);
|
|
493
|
+
console.log(header.querySelector('[data-side-panel-trigger="' + parentPanel.getAttribute('data-side-panel') + '"]'));
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
function findUpParent(el, attribute) {
|
|
498
|
+
while (el.parentNode) {
|
|
499
|
+
el = el.parentNode;
|
|
500
|
+
if (el.getAttribute(attribute))
|
|
501
|
+
return el;
|
|
502
|
+
}
|
|
503
|
+
return null;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* initDesktopTouchEvents()
|
|
508
|
+
* Initialize all desktop touch events
|
|
509
|
+
*/
|
|
510
|
+
function initDesktopTouchEvents() {
|
|
511
|
+
console.log("initDesktopTouchEvents");
|
|
512
|
+
|
|
513
|
+
//All panel triggers should have a click event that open or closes a panel
|
|
514
|
+
Array.prototype.forEach.call(panelTriggers, function (el, i) {
|
|
515
|
+
el.addEventListener('touchend', menuEnter);
|
|
516
|
+
el.addEventListener('click', function(e){
|
|
517
|
+
if(el.getAttribute('data-side-panel-trigger')!==''){
|
|
518
|
+
e.preventDefault();
|
|
519
|
+
}
|
|
520
|
+
});
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
Array.prototype.forEach.call(mainListItemsAnchor, function (el, i) {
|
|
525
|
+
el.addEventListener('click', openSubMenu);
|
|
526
|
+
});
|
|
527
|
+
|
|
528
|
+
//for each submenu wrapper listen for its mouse over
|
|
529
|
+
//so we know when to close the menu when you roll off the submenu
|
|
530
|
+
Array.prototype.forEach.call(submenuWrapper, function (el, i) {
|
|
531
|
+
el.addEventListener('touchend', submenuWrapperHover);
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
navBackground.addEventListener('touchend', closeAllPanels);
|
|
535
|
+
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* initMobileEvents()
|
|
541
|
+
* Initialize all mobile events
|
|
542
|
+
*/
|
|
543
|
+
function initMobileEvents() {
|
|
544
|
+
let isClick = false;
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
document.addEventListener('keyup', function(e){
|
|
548
|
+
if(document.getElementById('wrapper').contains(e.target)){
|
|
549
|
+
if(e.which == '9' || e.keyCode == '9'){
|
|
550
|
+
if (panelIsOpen) {
|
|
551
|
+
closePanel(currentlyOpenPanel);
|
|
552
|
+
header.querySelector('.mobile-links [data-side-panel-trigger="' + currentlyOpenPanel.getAttribute('data-side-panel') + '"]').focus();
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
//All panel triggers should have a click event that open or closes a panel
|
|
559
|
+
Array.prototype.forEach.call(panelTriggers, function (el, i) {
|
|
560
|
+
el.addEventListener('click', menuEnter);
|
|
561
|
+
el.addEventListener('keypress', menuEnter);
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
Array.prototype.forEach.call(headerAnchors, function (el, i) {
|
|
565
|
+
addKeyboardFocus(el);
|
|
566
|
+
});
|
|
567
|
+
|
|
568
|
+
//close mobile panel when focusing on geico logo
|
|
569
|
+
document.querySelector('#header-middle-links a').addEventListener('focus', function () {
|
|
570
|
+
Array.prototype.forEach.call(panels, function (panel, i) {
|
|
571
|
+
if (panel.classList.contains('open')) {
|
|
572
|
+
closePanel(panel);
|
|
573
|
+
}
|
|
574
|
+
});
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
Array.prototype.forEach.call(mainListItemsAnchorMobile, function (el, i) {
|
|
578
|
+
addKeyboardFocus(el);
|
|
579
|
+
|
|
580
|
+
el.addEventListener('mousedown', function(){
|
|
581
|
+
isClick = true;
|
|
582
|
+
});
|
|
583
|
+
|
|
584
|
+
el.addEventListener('click', openMobileSubMenu);
|
|
585
|
+
|
|
586
|
+
el.addEventListener('focus', function (e) {
|
|
587
|
+
let submenu = el.parentNode.getElementsByClassName('geico-nav-menu-secondary-wrapper');
|
|
588
|
+
|
|
589
|
+
if (!isClick && submenu.length > 0) {
|
|
590
|
+
openMobileSubMenu.bind(this)(e);
|
|
591
|
+
} else {
|
|
592
|
+
if (currentlyOpenSubPanel) {
|
|
593
|
+
//closeMobileSubMenu(currentlyOpenSubPanel); do not need, duplicate
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
//reset flag
|
|
598
|
+
isClick = false;
|
|
599
|
+
|
|
600
|
+
let parentAccordion = findClosestParent(el, 'accordion-content-container');
|
|
601
|
+
let accordionHeadline = parentAccordion.parentNode.querySelector('.accordion-headline');
|
|
602
|
+
|
|
603
|
+
if(!parentAccordion.parentNode.classList.contains('open')){
|
|
604
|
+
accordionHeadline.click();
|
|
605
|
+
}
|
|
606
|
+
});
|
|
607
|
+
|
|
608
|
+
Array.prototype.forEach.call(secondaryListItemsAnchorMobile, function (el, i) {
|
|
609
|
+
addKeyboardFocus(el);
|
|
610
|
+
|
|
611
|
+
el.addEventListener('focus', function (e) {
|
|
612
|
+
//var parentLI = el.closest('.accordion-content > ul > li');
|
|
613
|
+
var parentLI = findUpParent(el, 'data-name');
|
|
614
|
+
var submenu = parentLI.querySelector('.geico-nav-menu-secondary-wrapper');
|
|
615
|
+
|
|
616
|
+
if(!parentLI.classList.contains('open')){
|
|
617
|
+
openMobileSubMenu.bind(submenu)(e);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
var parentAccordion = findClosestParent(el, 'accordion-content-container');
|
|
621
|
+
var accordionHeadline = parentAccordion.parentNode.querySelector('.accordion-headline');
|
|
622
|
+
|
|
623
|
+
if(!parentAccordion.parentNode.classList.contains('open')){
|
|
624
|
+
accordionHeadline.click();
|
|
625
|
+
}
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
el.addEventListener('click', closeAllPanels);
|
|
629
|
+
|
|
630
|
+
});
|
|
631
|
+
});
|
|
632
|
+
|
|
633
|
+
navBackground.addEventListener('click', closeAllPanels);
|
|
634
|
+
|
|
635
|
+
Array.prototype.forEach.call(mobilenavaccordionHeadlines, function (el, i) {
|
|
636
|
+
addKeyboardFocus(el);
|
|
637
|
+
el.addEventListener('click', closeSubMenufromHeadline);
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
Array.prototype.forEach.call(headerAnchors, function(el, i){
|
|
641
|
+
el.setAttribute('tabindex', '-1');
|
|
642
|
+
if(el.parentNode.parentNode.classList.contains('mobile-links')||el.parentNode.parentNode.classList.contains('right-mobile-links')||el.classList.contains('icon-geico')){
|
|
643
|
+
el.removeAttribute('tabindex');
|
|
644
|
+
}
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
Array.prototype.forEach.call(mainListItemsAnchorRightMobile, function(el, i){
|
|
648
|
+
el.addEventListener('focus', function(){
|
|
649
|
+
addKeyboardFocus(el);
|
|
650
|
+
});
|
|
651
|
+
});
|
|
652
|
+
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* initMobileTouchEvents()
|
|
657
|
+
* Initialize mobile touch events
|
|
658
|
+
*/
|
|
659
|
+
function initMobileTouchEvents() {
|
|
660
|
+
|
|
661
|
+
//All panel triggers should have a click event that open or closes a panel
|
|
662
|
+
Array.prototype.forEach.call(panelTriggers, function (el, i) {
|
|
663
|
+
el.addEventListener('touchend', menuEnter);
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
Array.prototype.forEach.call(mainListItemsAnchorMobile, function (el, i) {
|
|
667
|
+
el.addEventListener('click', openMobileSubMenu);
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
navBackground.addEventListener('touchend', closeAllPanels);
|
|
671
|
+
|
|
672
|
+
Array.prototype.forEach.call(mobilenavaccordionHeadlines, function (el, i) {
|
|
673
|
+
el.addEventListener('touchend', closeSubMenufromHeadline);
|
|
674
|
+
});
|
|
675
|
+
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
function closeSubMenufromHeadline(){
|
|
679
|
+
if (currentlyOpenSubPanel) {
|
|
680
|
+
closeMobileSubMenu(currentlyOpenSubPanel);
|
|
681
|
+
//console.log(subWrapper.getBoundingClientRect().top);
|
|
682
|
+
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
|
|
687
|
+
/**
|
|
688
|
+
* removeNavEvents()
|
|
689
|
+
* Remove all navigation events
|
|
690
|
+
*/
|
|
691
|
+
|
|
692
|
+
function removeNavEvents() {
|
|
693
|
+
|
|
694
|
+
Array.prototype.forEach.call(panelTriggers, function (el, i) {
|
|
695
|
+
el.removeEventListener('touchstart', menuEnter);
|
|
696
|
+
el.removeEventListener('click', menuEnter);
|
|
697
|
+
el.removeEventListener('mouseenter', menuEnter);
|
|
698
|
+
el.removeEventListener('mouseleave', menuLeave);
|
|
699
|
+
el.removeEventListener('keypress', menuEnter);
|
|
700
|
+
el.removeEventListener('touchend', menuEnter);
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
Array.prototype.forEach.call(headerAnchors, function (el, i) {
|
|
704
|
+
el.removeEventListener('keypress', menuEnter);
|
|
705
|
+
el.removeEventListener('focus', focusPanel);
|
|
706
|
+
});
|
|
707
|
+
|
|
708
|
+
Array.prototype.forEach.call(mainListItems, function (el, i) {
|
|
709
|
+
el.removeEventListener('click', closeAllPanels);
|
|
710
|
+
el.removeEventListener('mouseenter', openSubMenu);
|
|
711
|
+
el.removeEventListener('focus', openSubMenu, true);
|
|
712
|
+
});
|
|
713
|
+
|
|
714
|
+
Array.prototype.forEach.call(mainListItemsAnchor, function (el, i) {
|
|
715
|
+
el.removeEventListener('click', openMobileSubMenu);
|
|
716
|
+
el.removeEventListener('touchstart', openSubMenu);
|
|
717
|
+
el.removeEventListener('mouseenter', openSubMenu);
|
|
718
|
+
});
|
|
719
|
+
|
|
720
|
+
Array.prototype.forEach.call(submenuWrapper, function (el, i) {
|
|
721
|
+
el.removeEventListener('touchstart', submenuWrapperHover);
|
|
722
|
+
el.removeEventListener('mouseover', submenuWrapperHover);
|
|
723
|
+
});
|
|
724
|
+
|
|
725
|
+
Array.prototype.forEach.call(panels, function (el, i) {
|
|
726
|
+
el.removeEventListener('mouseleave', panelLeave);
|
|
727
|
+
});
|
|
728
|
+
|
|
729
|
+
navBackground.removeEventListener('touchstart', closeAllPanels);
|
|
730
|
+
navBackground.removeEventListener('click', closeAllPanels);
|
|
731
|
+
|
|
732
|
+
removeTabIndexes();
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
function focusPanel(){
|
|
736
|
+
Array.prototype.forEach.call(panels, function (panel, i) {
|
|
737
|
+
if(panel.classList.contains('open')){
|
|
738
|
+
closePanel(panel);
|
|
739
|
+
}
|
|
740
|
+
});
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
/**
|
|
744
|
+
* removeTabIndexes()
|
|
745
|
+
* remove all tabindexes from nav elements
|
|
746
|
+
*/
|
|
747
|
+
function removeTabIndexes() {
|
|
748
|
+
let headerLinks = header.querySelectorAll('a');
|
|
749
|
+
|
|
750
|
+
Array.prototype.forEach.call(headerLinks, function (headerLink) {
|
|
751
|
+
headerLink.removeAttribute('tabindex');
|
|
752
|
+
});
|
|
753
|
+
|
|
754
|
+
let panelElements = nav.querySelectorAll('*');
|
|
755
|
+
|
|
756
|
+
Array.prototype.forEach.call(panelElements, function (panelElement) {
|
|
757
|
+
if(panelElement.classList&&!panelElement.classList.contains('accordion-headline'))
|
|
758
|
+
panelElement.removeAttribute('tabindex');
|
|
759
|
+
});
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
/**
|
|
763
|
+
* addKeyboardFocus()
|
|
764
|
+
* add/remove focus class to keyboard focused and blurred elements
|
|
765
|
+
*/
|
|
766
|
+
function addKeyboardFocus(element){
|
|
767
|
+
let isClick = false;
|
|
768
|
+
|
|
769
|
+
element.addEventListener('mousedown', function () {
|
|
770
|
+
isClick = true;
|
|
771
|
+
});
|
|
772
|
+
|
|
773
|
+
element.addEventListener('focus', function (e) {
|
|
774
|
+
if(!isClick){
|
|
775
|
+
element.classList.add('keyboard-focus');
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
//reset flag
|
|
779
|
+
isClick = false;
|
|
780
|
+
});
|
|
781
|
+
|
|
782
|
+
element.addEventListener('blur', function () {
|
|
783
|
+
element.classList.remove('keyboard-focus');
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
/**
|
|
788
|
+
* findClosestParent()
|
|
789
|
+
* finds closest parent element by class
|
|
790
|
+
*/
|
|
791
|
+
function findClosestParent(element, parentClass) {
|
|
792
|
+
while ((element = element.parentElement) && !element.classList.contains(parentClass));
|
|
793
|
+
return element;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
/**
|
|
797
|
+
* menuEnter()
|
|
798
|
+
* Gets called whenever your mouse enters a trigger link
|
|
799
|
+
*/
|
|
800
|
+
|
|
801
|
+
function menuEnter(e) {
|
|
802
|
+
//for keyboard navigation: if anything other than "enter" key is pressed do not continue
|
|
803
|
+
if((e.type == 'keydown' || e.type == 'keypress') && ((e.keyCode || e.which) != 13)){
|
|
804
|
+
return;
|
|
805
|
+
}else if(e.type == 'keydown' || e.type == 'keypress' || e.type == 'click'){
|
|
806
|
+
if(appState.mode === "desktop") {
|
|
807
|
+
Array.prototype.forEach.call(headerAnchors, function (el, i) {
|
|
808
|
+
el.setAttribute('tabindex', '-1');
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
Array.prototype.forEach.call(submenuWrapper, function (el, i) {
|
|
812
|
+
el.removeEventListener('mouseover', submenuWrapperHover);
|
|
813
|
+
});
|
|
814
|
+
}else if(e.type == 'mouseenter'){
|
|
815
|
+
removeNavEvents();
|
|
816
|
+
if (appState.isTouchDevice) {
|
|
817
|
+
initDesktopTouchEvents();
|
|
818
|
+
} else {
|
|
819
|
+
initDesktopEvents();
|
|
820
|
+
}
|
|
821
|
+
if(appState.mode == "desktop"){
|
|
822
|
+
if (panelIsOpen&&e.target.classList.contains('open')) {
|
|
823
|
+
e.preventDefault();
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
}else if(e.type == 'click'){
|
|
828
|
+
if(appState.mode == "desktop"){
|
|
829
|
+
if (panelIsOpen) {
|
|
830
|
+
e.preventDefault();
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
e.preventDefault();
|
|
837
|
+
let panelToFind;
|
|
838
|
+
|
|
839
|
+
//get the name of the panel to find which is stored in the data attribute of the trigger
|
|
840
|
+
if (e.target.nodeName === "A") {
|
|
841
|
+
panelToFind = e.target.getAttribute('data-side-panel-trigger');
|
|
842
|
+
} else {
|
|
843
|
+
panelToFind = utils.getParentByTagName(e.target, "A").getAttribute('data-side-panel-trigger');
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
if (appState.mode === "mobile" && utils.hasClass(this, 'open')) {
|
|
847
|
+
|
|
848
|
+
//if our mode is mobile and the panel is already open just close it
|
|
849
|
+
Array.prototype.forEach.call(panels, function (el, i) {
|
|
850
|
+
|
|
851
|
+
if (el.getAttribute('data-side-panel') === panelToFind) {
|
|
852
|
+
closePanel(el);
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
});
|
|
857
|
+
|
|
858
|
+
|
|
859
|
+
} else {
|
|
860
|
+
if(this.classList.contains('open')){
|
|
861
|
+
closePanel(currentlyOpenPanel);
|
|
862
|
+
return;
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
//if there is a current panel open then close it before opening the new one
|
|
866
|
+
if (panelIsOpen) {
|
|
867
|
+
closePanel(currentlyOpenPanel);
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
//add and open class the the a tag
|
|
871
|
+
this.classList.add('open');
|
|
872
|
+
this.setAttribute('aria-expanded', 'true');
|
|
873
|
+
|
|
874
|
+
//for each panel find the one that was triggered
|
|
875
|
+
Array.prototype.forEach.call(panels, function (el, i) {
|
|
876
|
+
|
|
877
|
+
if (el.getAttribute('data-side-panel') === panelToFind) {
|
|
878
|
+
|
|
879
|
+
openPanel(el);
|
|
880
|
+
if(appState.mode == 'desktop' && !appState.isTouchDevice)
|
|
881
|
+
el.style.display = "block";
|
|
882
|
+
let allAinPanel = el.querySelectorAll('a');
|
|
883
|
+
Array.prototype.forEach.call(allAinPanel, function(el, i){
|
|
884
|
+
el.removeAttribute('tabindex');
|
|
885
|
+
});
|
|
886
|
+
let allULinPanel = el.querySelectorAll('ul');
|
|
887
|
+
if(el.querySelector('.geico-nav-menu-secondary-wrapper')){
|
|
888
|
+
let allSecondaryUL = el.querySelectorAll('.geico-nav-menu-secondary-wrapper > ul');
|
|
889
|
+
Array.prototype.forEach.call(allSecondaryUL, function(el, i){
|
|
890
|
+
el.removeAttribute('tabindex');
|
|
891
|
+
});
|
|
892
|
+
Array.prototype.forEach.call(allULinPanel, function(el, i){
|
|
893
|
+
el.setAttribute('tabindex', '-1');
|
|
894
|
+
let allSVGinUL = el.querySelectorAll('svg');
|
|
895
|
+
Array.prototype.forEach.call(allSVGinUL, function(el, i){
|
|
896
|
+
el.setAttribute('focusable', 'false');
|
|
897
|
+
});
|
|
898
|
+
});
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
|
|
902
|
+
}else{
|
|
903
|
+
if(appState.mode == 'desktop' && !appState.isTouchDevice)
|
|
904
|
+
el.style.display = "none";
|
|
905
|
+
let allAinPanel = el.querySelectorAll('a');
|
|
906
|
+
Array.prototype.forEach.call(allAinPanel, function(el, i){
|
|
907
|
+
el.setAttribute('tabindex', '-1');
|
|
908
|
+
});
|
|
909
|
+
let allULinPanel = el.querySelectorAll('ul');
|
|
910
|
+
|
|
911
|
+
if(el.querySelector('.geico-nav-menu-secondary-wrapper')){
|
|
912
|
+
let allSecondaryUL = el.querySelectorAll('.geico-nav-menu-secondary-wrapper > ul');
|
|
913
|
+
Array.prototype.forEach.call(allSecondaryUL, function(el, i){
|
|
914
|
+
el.setAttribute('tabindex', '-1');
|
|
915
|
+
});
|
|
916
|
+
}
|
|
917
|
+
Array.prototype.forEach.call(allULinPanel, function(el, i){
|
|
918
|
+
el.setAttribute('tabindex', '-1');
|
|
919
|
+
});
|
|
920
|
+
}
|
|
921
|
+
});
|
|
922
|
+
|
|
923
|
+
//add a class to every panel trigger you did not roll over
|
|
924
|
+
Array.prototype.forEach.call(panelTriggers, (el, i) => {
|
|
925
|
+
|
|
926
|
+
if (el != this) {
|
|
927
|
+
el.classList.add("not-open");
|
|
928
|
+
el.setAttribute('aria-expanded', 'false');
|
|
929
|
+
}
|
|
930
|
+
});
|
|
931
|
+
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
/**
|
|
937
|
+
* menuEnter()
|
|
938
|
+
* Gets called whenever your mouse leaves a trigger link
|
|
939
|
+
*/
|
|
940
|
+
function menuLeave(e) {
|
|
941
|
+
//When your mouse leaves the trigger detect if its over the open panel
|
|
942
|
+
//If its not over the open panel then close the panel
|
|
943
|
+
if (currentlyOpenPanel) {
|
|
944
|
+
if (!currentlyOpenPanel.contains(e.relatedTarget)) {
|
|
945
|
+
closePanel(currentlyOpenPanel);
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
function scrollTo(element, to, duration) {
|
|
952
|
+
if (duration <= 0) return;
|
|
953
|
+
var difference = to - element.scrollTop;
|
|
954
|
+
var perTick = difference / duration * 10;
|
|
955
|
+
|
|
956
|
+
setTimeout(function() {
|
|
957
|
+
element.scrollTop = element.scrollTop + perTick;
|
|
958
|
+
if (element.scrollTop === to) return;
|
|
959
|
+
scrollTo(element, to, duration - 10);
|
|
960
|
+
}, 10);
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
/**
|
|
964
|
+
* panelLeave()
|
|
965
|
+
* Gets fired when your mouse leaves a panel
|
|
966
|
+
*/
|
|
967
|
+
function panelLeave() {
|
|
968
|
+
//only close the panel if there is not a sub panel open
|
|
969
|
+
if (currentlyOpenSubPanel || currentlyOpenPanel) {
|
|
970
|
+
if(!currentlyOpenPanel.contains(document.activeElement)){
|
|
971
|
+
closePanel(currentlyOpenPanel);
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
|
|
977
|
+
/**
|
|
978
|
+
* openPanel()
|
|
979
|
+
* Opens a panel by adding the necessary open a classes
|
|
980
|
+
*/
|
|
981
|
+
function openPanel(el) {
|
|
982
|
+
|
|
983
|
+
//if there is a panel close timer than cancel it because we just opened up another panel
|
|
984
|
+
if (panel_timer) {
|
|
985
|
+
clearTimeout(panel_timer);
|
|
986
|
+
nav.style.display = "block";
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
nav.style.display = "block";
|
|
990
|
+
|
|
991
|
+
|
|
992
|
+
if (appState.mode === "mobile") {
|
|
993
|
+
document.querySelector('body').style.overflowY = "hidden";
|
|
994
|
+
document.querySelector('body').style.position = "fixed";
|
|
995
|
+
|
|
996
|
+
header.querySelector('#header-middle-links a').setAttribute('tabindex', '-1');
|
|
997
|
+
|
|
998
|
+
if(el.getAttribute('data-side-panel')=='mobile-menu'){
|
|
999
|
+
let allHeaderRight = header.querySelectorAll('#header-right-links .mobile-links a');
|
|
1000
|
+
Array.prototype.forEach.call(allHeaderRight, function(el, i){
|
|
1001
|
+
el.setAttribute('tabindex', '-1');
|
|
1002
|
+
});
|
|
1003
|
+
}else if(el.classList.contains('right')){
|
|
1004
|
+
header.querySelector('#header-middle-links a').removeAttribute('tabindex');
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
clearTimeout(open_timer);
|
|
1010
|
+
|
|
1011
|
+
open_timer = setTimeout(()=> {
|
|
1012
|
+
|
|
1013
|
+
nav.classList.add('open');
|
|
1014
|
+
if(el.getAttribute('data-side-panel')=='mobile-menu'){
|
|
1015
|
+
header.classList.add('open');
|
|
1016
|
+
}
|
|
1017
|
+
el.classList.add('open');
|
|
1018
|
+
if(appState.mode === 'mobile'&&!appState.isTouchDevice){
|
|
1019
|
+
Array.prototype.forEach.call(panels, function(el, i){
|
|
1020
|
+
if(!el.classList.contains('open')){
|
|
1021
|
+
el.style.display = "none";
|
|
1022
|
+
}
|
|
1023
|
+
});
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
//store the open panel
|
|
1027
|
+
currentlyOpenPanel = el;
|
|
1028
|
+
panelIsOpen = true;
|
|
1029
|
+
|
|
1030
|
+
}, 50);
|
|
1031
|
+
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
/**
|
|
1035
|
+
* closePanel()
|
|
1036
|
+
* Closes a panel by removing the necessary open a classes
|
|
1037
|
+
*/
|
|
1038
|
+
function closePanel(el, e) {
|
|
1039
|
+
|
|
1040
|
+
if (appState.mode === "mobile") {
|
|
1041
|
+
document.querySelector('body').style.overflowY = "visible";
|
|
1042
|
+
document.querySelector('body').style.position = "relative";
|
|
1043
|
+
|
|
1044
|
+
closeAccordionsMobileNav();
|
|
1045
|
+
|
|
1046
|
+
header.querySelector('#header-middle-links a').removeAttribute('tabindex');
|
|
1047
|
+
|
|
1048
|
+
}
|
|
1049
|
+
if(appState.mode === 'mobile'){
|
|
1050
|
+
Array.prototype.forEach.call(panels, function(el, i){
|
|
1051
|
+
|
|
1052
|
+
el.removeAttribute('style');
|
|
1053
|
+
|
|
1054
|
+
});
|
|
1055
|
+
}
|
|
1056
|
+
nav.classList.remove('open');
|
|
1057
|
+
header.classList.remove('open');
|
|
1058
|
+
el.classList.remove('open');
|
|
1059
|
+
panelIsOpen = false;
|
|
1060
|
+
subpanelName = null;
|
|
1061
|
+
|
|
1062
|
+
Array.prototype.forEach.call(panelTriggers, function (el, i) {
|
|
1063
|
+
el.classList.remove('open');
|
|
1064
|
+
el.classList.remove('not-open');
|
|
1065
|
+
el.setAttribute('aria-expanded', 'false');
|
|
1066
|
+
});
|
|
1067
|
+
|
|
1068
|
+
|
|
1069
|
+
//if a sub menu is open then close that
|
|
1070
|
+
if (currentlyOpenSubPanel) {
|
|
1071
|
+
currentlyOpenSubPanel.classList.remove("open");
|
|
1072
|
+
currentlyOpenSubPanel = null;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
|
|
1076
|
+
panel_timer = setTimeout(()=> {
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
Array.prototype.forEach.call(mainListItems, function (el, i) {
|
|
1080
|
+
el.classList.remove("open");
|
|
1081
|
+
});
|
|
1082
|
+
|
|
1083
|
+
if (appState.mode === "mobile") {
|
|
1084
|
+
Array.prototype.forEach.call(submenuWrapper, function (el, i) {
|
|
1085
|
+
el.style.maxHeight = "0px";
|
|
1086
|
+
});
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
nav.style.display = "none";
|
|
1090
|
+
panel_timer = null;
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
}, 500);
|
|
1094
|
+
|
|
1095
|
+
|
|
1096
|
+
removeTabIndexes();
|
|
1097
|
+
//no animation for kit purpose because too jagged
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
/**
|
|
1101
|
+
* submenuWrapperHover()
|
|
1102
|
+
* Detects if you have rolled over the submenuWrapper
|
|
1103
|
+
* so we know when to close the menu when you roll off the submenu
|
|
1104
|
+
*/
|
|
1105
|
+
function submenuWrapperHover(e) {
|
|
1106
|
+
if (currentlyOpenPanel) {
|
|
1107
|
+
//NodeList of items that the mouse is currently over in document order.
|
|
1108
|
+
//The last element in the NodeList is the most specific, each preceding
|
|
1109
|
+
//one should be a parent, grandparent, and so on.
|
|
1110
|
+
let nodes = document.querySelectorAll(":hover");
|
|
1111
|
+
|
|
1112
|
+
//if the target node is a div an the last hovered node is the wrapper
|
|
1113
|
+
//we know we are off the submenu so close menues
|
|
1114
|
+
if (e.target.nodeName == "DIV" && e.target == nodes[nodes.length - 1]) {
|
|
1115
|
+
closePanel(currentlyOpenPanel);
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
/**
|
|
1121
|
+
* openSubMenu()
|
|
1122
|
+
* Opens the submenu when you click on its parent li
|
|
1123
|
+
* This is used when on a touch device
|
|
1124
|
+
*/
|
|
1125
|
+
function openSubMenu(e) {
|
|
1126
|
+
Array.prototype.forEach.call(headerAnchors, function (el, i) {
|
|
1127
|
+
el.removeAttribute('tabindex');
|
|
1128
|
+
});
|
|
1129
|
+
//dont open a subpanel if the parent is not open
|
|
1130
|
+
if (!panelIsOpen) {
|
|
1131
|
+
return;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
clearTimeout(hover_timer);
|
|
1135
|
+
let p;
|
|
1136
|
+
let hoverDelay;
|
|
1137
|
+
if (appState.isTouchDevice) {
|
|
1138
|
+
p = this.parentNode;
|
|
1139
|
+
hoverDelay = 0;
|
|
1140
|
+
} else {
|
|
1141
|
+
p = this;
|
|
1142
|
+
hoverDelay = 150;
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
let subWrapper = p.querySelector(".geico-nav-menu-secondary-wrapper");
|
|
1146
|
+
|
|
1147
|
+
|
|
1148
|
+
if (subWrapper) {
|
|
1149
|
+
e.preventDefault();
|
|
1150
|
+
}
|
|
1151
|
+
hover_timer = setTimeout(()=> {
|
|
1152
|
+
|
|
1153
|
+
if (!utils.hasClass(p, 'open')) {
|
|
1154
|
+
//animate the svg
|
|
1155
|
+
if(p.querySelector("svg")) {
|
|
1156
|
+
svgToAnim = p.querySelector("svg");
|
|
1157
|
+
svgAnim();
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
//if a sub menu is open then close that
|
|
1162
|
+
if (currentlyOpenSubPanel) {
|
|
1163
|
+
currentlyOpenSubPanel.classList.remove("open");
|
|
1164
|
+
currentlyOpenSubPanel = null;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
currentlyOpenSubPanel = p;
|
|
1168
|
+
|
|
1169
|
+
if (!appState.isTouchDevice) {
|
|
1170
|
+
p.classList.toggle('open'); //this FF
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
if (subWrapper) {
|
|
1174
|
+
|
|
1175
|
+
if (appState.isTouchDevice) {
|
|
1176
|
+
p.classList.toggle('open');
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
|
|
1181
|
+
}, hoverDelay);
|
|
1182
|
+
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
|
|
1186
|
+
/**
|
|
1187
|
+
* closeMobileSubMenu()
|
|
1188
|
+
* Opens the submenu when you click on its parent li
|
|
1189
|
+
*/
|
|
1190
|
+
function closeMobileSubMenu(el) {
|
|
1191
|
+
el.classList.remove('open');
|
|
1192
|
+
let subWrapper = el.querySelector(".geico-nav-menu-secondary-wrapper");
|
|
1193
|
+
subWrapper.style.maxHeight = "0px";
|
|
1194
|
+
currentlyOpenSubPanel = null;
|
|
1195
|
+
subpanelName = null;
|
|
1196
|
+
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
|
|
1200
|
+
/**
|
|
1201
|
+
* openMobileSubMenu()
|
|
1202
|
+
* Opens the submenu when you click on its parent li
|
|
1203
|
+
*/
|
|
1204
|
+
function openMobileSubMenu(e) {
|
|
1205
|
+
|
|
1206
|
+
//console.log("openMobileSubMenu");
|
|
1207
|
+
|
|
1208
|
+
//this is the list item that was clicked
|
|
1209
|
+
let p = this.parentNode;
|
|
1210
|
+
let subWrapper = p.querySelector(".geico-nav-menu-secondary-wrapper");
|
|
1211
|
+
let clickedSubpanelName = p.getAttribute('data-name');
|
|
1212
|
+
let shouldOpenSubPanel = false;
|
|
1213
|
+
let subMenuOpened = false;
|
|
1214
|
+
//console.log(subWrapper.parentNode.querySelector('a').querySelector('span').getBoundingClientRect().top);
|
|
1215
|
+
|
|
1216
|
+
|
|
1217
|
+
if (subWrapper) {
|
|
1218
|
+
//if there is a submenu then prevent default
|
|
1219
|
+
e.preventDefault();
|
|
1220
|
+
|
|
1221
|
+
if (subpanelName !== clickedSubpanelName) {
|
|
1222
|
+
shouldOpenSubPanel = true;
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
///close any open submenus
|
|
1226
|
+
if (currentlyOpenSubPanel) {
|
|
1227
|
+
subMenuOpened = true;
|
|
1228
|
+
closeMobileSubMenu(currentlyOpenSubPanel);
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
//if the submenu you are trying to open up is not already open then open the submenu
|
|
1232
|
+
if (shouldOpenSubPanel) {
|
|
1233
|
+
|
|
1234
|
+
//store the open panel and its name
|
|
1235
|
+
currentlyOpenSubPanel = p;
|
|
1236
|
+
subpanelName = this.parentNode.getAttribute('data-name');
|
|
1237
|
+
|
|
1238
|
+
|
|
1239
|
+
if (!utils.hasClass(p, 'open')) {
|
|
1240
|
+
//animate the svg
|
|
1241
|
+
svgToAnim = p.querySelector("svg");
|
|
1242
|
+
svgAnim();
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
p.classList.toggle('open');
|
|
1246
|
+
let accordionContainer = searchParentByClassName(this, "accordion-content-container");
|
|
1247
|
+
|
|
1248
|
+
let subWrapperUl = subWrapper.querySelector("ul");
|
|
1249
|
+
if (window.getComputedStyle(subWrapper).maxHeight == "0px") {
|
|
1250
|
+
|
|
1251
|
+
subWrapper.style.maxHeight = outerHeight(subWrapperUl) + "px";
|
|
1252
|
+
accordionContainer.style.maxHeight = accordionContainer.offsetHeight + outerHeight(subWrapperUl) + "px";
|
|
1253
|
+
|
|
1254
|
+
//if there are no other submenus opened, scroll the current submenu being opened to the top of the page
|
|
1255
|
+
if (subMenuOpened === false) {
|
|
1256
|
+
let aboveNavOffset = 0;
|
|
1257
|
+
let aboveNavElements = document.getElementsByClassName('above-nav');
|
|
1258
|
+
|
|
1259
|
+
Array.prototype.forEach.call(aboveNavElements, function (el, i) {
|
|
1260
|
+
aboveNavOffset += el.offsetHeight;
|
|
1261
|
+
});
|
|
1262
|
+
|
|
1263
|
+
let mobileMenu = document.querySelector('[data-side-panel="mobile-menu"]');
|
|
1264
|
+
let offset = p.getBoundingClientRect().top + mobileMenu.scrollTop - aboveNavOffset;
|
|
1265
|
+
|
|
1266
|
+
setTimeout(()=>{
|
|
1267
|
+
scrollTo(mobileMenu, offset, 200);
|
|
1268
|
+
}, 296);
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
} else {
|
|
1272
|
+
accordionContainer.style.maxHeight = accordionContainer.offsetHeight - outerHeight(subWrapperUl) + "px";
|
|
1273
|
+
subWrapper.style.maxHeight = "0px";
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
} else {
|
|
1277
|
+
closePanel(currentlyOpenPanel);
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
|
|
1282
|
+
/**
|
|
1283
|
+
* Svetoslav Kostadinov
|
|
1284
|
+
* 06.Jan.2016
|
|
1285
|
+
* Recursive Search of a Parent element by a search Criteria
|
|
1286
|
+
*
|
|
1287
|
+
* @param sPoint // starting point
|
|
1288
|
+
* @param criteria // search criteria
|
|
1289
|
+
* @returns {*}
|
|
1290
|
+
*/
|
|
1291
|
+
function searchParentByClassName(sPoint, criteria){
|
|
1292
|
+
if(typeof sPoint === "undefined") {
|
|
1293
|
+
return null;
|
|
1294
|
+
}
|
|
1295
|
+
else if(sPoint.className.indexOf(criteria) === -1) {
|
|
1296
|
+
let element = searchParentByClassName(sPoint.parentNode, criteria);
|
|
1297
|
+
if (element !== null)
|
|
1298
|
+
return element;
|
|
1299
|
+
}
|
|
1300
|
+
else {
|
|
1301
|
+
return sPoint;
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
/**
|
|
1306
|
+
* addSVGs()
|
|
1307
|
+
* Adds the border SVGs to all first level nav items
|
|
1308
|
+
*/
|
|
1309
|
+
function addSVGs() {
|
|
1310
|
+
|
|
1311
|
+
//All panel triggers should have a click event that open or closes a panel
|
|
1312
|
+
Array.prototype.forEach.call(actionableIcons, function (el, i) {
|
|
1313
|
+
el.insertAdjacentHTML('beforebegin', `<svg width="60" height="60" version="1.1" xmlns="http://www.w3.org/2000/svg" style="width: 60px; height: 60px;"><circle cx="30" cy='30' r="29" /></svg>`);
|
|
1314
|
+
});
|
|
1315
|
+
|
|
1316
|
+
Array.prototype.forEach.call(actionableIcons, function (el, i) {
|
|
1317
|
+
el.style.width = "60px";
|
|
1318
|
+
el.style.height = "60px";
|
|
1319
|
+
el.style.lineHeight = "60px";
|
|
1320
|
+
el.style.fontSize = "30px";
|
|
1321
|
+
});
|
|
1322
|
+
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
|
|
1326
|
+
/**
|
|
1327
|
+
* addSVGs()
|
|
1328
|
+
* Adds additional markup to every hamburger item
|
|
1329
|
+
*/
|
|
1330
|
+
function addHamburgerMarkup() {
|
|
1331
|
+
|
|
1332
|
+
//All panel triggers should have a click event that open or closes a panel
|
|
1333
|
+
Array.prototype.forEach.call(hamburgerIcons, function (el, i) {
|
|
1334
|
+
el.insertAdjacentHTML('beforeend', `<div class="hamburger"><span></span><span></span><span></span><span></span></div>`);
|
|
1335
|
+
});
|
|
1336
|
+
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
|
|
1340
|
+
/**
|
|
1341
|
+
* handleResize()
|
|
1342
|
+
* listen for window resize so we can detect the mode
|
|
1343
|
+
*/
|
|
1344
|
+
function handleResize() {
|
|
1345
|
+
if (appState.mode === "desktop" && currentNavState === "mobile") {
|
|
1346
|
+
//clear some styling
|
|
1347
|
+
Array.prototype.forEach.call(submenuWrapper, function (el, i) {
|
|
1348
|
+
el.removeAttribute('style');
|
|
1349
|
+
});
|
|
1350
|
+
Array.prototype.forEach.call(panels, function(el, i){
|
|
1351
|
+
if(!el.classList.contains('open')){
|
|
1352
|
+
el.removeAttribute('style');
|
|
1353
|
+
}
|
|
1354
|
+
});
|
|
1355
|
+
removeNavEvents();
|
|
1356
|
+
currentNavState = "desktop";
|
|
1357
|
+
if (currentlyOpenPanel) {
|
|
1358
|
+
closePanel(currentlyOpenPanel);
|
|
1359
|
+
}
|
|
1360
|
+
if (appState.isTouchDevice) {
|
|
1361
|
+
initDesktopTouchEvents();
|
|
1362
|
+
} else {
|
|
1363
|
+
initDesktopEvents();
|
|
1364
|
+
}
|
|
1365
|
+
//document.querySelector('body').style.overflowY = "visible";
|
|
1366
|
+
//document.querySelector('body').style.position = "relative";
|
|
1367
|
+
//body.style.overflowX = "visible";
|
|
1368
|
+
body.removeAttribute('style');
|
|
1369
|
+
|
|
1370
|
+
} else if (appState.mode === "mobile" && currentNavState === "desktop") {
|
|
1371
|
+
removeNavEvents();
|
|
1372
|
+
currentNavState = "mobile";
|
|
1373
|
+
if (currentlyOpenPanel) {
|
|
1374
|
+
closePanel(currentlyOpenPanel);
|
|
1375
|
+
}
|
|
1376
|
+
if (appState.isTouchDevice) {
|
|
1377
|
+
initMobileTouchEvents();
|
|
1378
|
+
} else {
|
|
1379
|
+
initMobileEvents();
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
|
|
1385
|
+
/**
|
|
1386
|
+
* closeAllPanels()
|
|
1387
|
+
* this force closes all menus, good for single page apps thats need to close the menu
|
|
1388
|
+
*/
|
|
1389
|
+
function closeAllPanels() {
|
|
1390
|
+
|
|
1391
|
+
if (currentlyOpenPanel) {
|
|
1392
|
+
closePanel(currentlyOpenPanel);
|
|
1393
|
+
removeHoverStyle();
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
|
|
1398
|
+
/**
|
|
1399
|
+
* outerHeight()
|
|
1400
|
+
* used to get the height of an element that is the same across all browsers
|
|
1401
|
+
*
|
|
1402
|
+
* @param {Object} node DOM node
|
|
1403
|
+
* @return {number}
|
|
1404
|
+
*/
|
|
1405
|
+
function outerHeight(el) {
|
|
1406
|
+
let height = el.offsetHeight;
|
|
1407
|
+
let style = getComputedStyle(el);
|
|
1408
|
+
|
|
1409
|
+
height += parseInt(style.marginTop) + parseInt(style.marginBottom);
|
|
1410
|
+
return height;
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
|
|
1414
|
+
/**
|
|
1415
|
+
* svgAnim()
|
|
1416
|
+
* animates the svg around the icon
|
|
1417
|
+
*/
|
|
1418
|
+
function svgAnim() {
|
|
1419
|
+
|
|
1420
|
+
if (appState.mode === "desktop") {
|
|
1421
|
+
tick += tickSpeed;
|
|
1422
|
+
} else {
|
|
1423
|
+
tick += tickSpeedMobile;
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1426
|
+
|
|
1427
|
+
let t = tick / 100;
|
|
1428
|
+
let offsetStrokeDasharray = easeInQuad(t, 0, dashArrayComplete, 1);
|
|
1429
|
+
svgToAnim.style.strokeDasharray = `${offsetStrokeDasharray} , ${dashArrayComplete}`;
|
|
1430
|
+
|
|
1431
|
+
if (tick < 100) {
|
|
1432
|
+
requestAnimationFrame(svgAnim.bind(this));
|
|
1433
|
+
} else {
|
|
1434
|
+
tick = 0;
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
|
|
1440
|
+
/**
|
|
1441
|
+
* easeInQuad()
|
|
1442
|
+
* Quadratic easing
|
|
1443
|
+
*/
|
|
1444
|
+
function easeInQuad(t, b, c, d) {
|
|
1445
|
+
var ts = (t /= d) * t;
|
|
1446
|
+
return b + c * (ts);
|
|
1447
|
+
}
|
|
1448
|
+
/**
|
|
1449
|
+
* easeInCubic()
|
|
1450
|
+
* Cubic easing
|
|
1451
|
+
*/
|
|
1452
|
+
function easeInCubic(t, b, c, d) {
|
|
1453
|
+
var ts = (t /= d) * t * t;
|
|
1454
|
+
return b + c * (ts);
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
export { init, closeAllPanels };
|