geico-design-kit 7.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of geico-design-kit might be problematic. Click here for more details.

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