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.

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
+ }