wg5 0.0.1-security → 8.462.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 wg5 might be problematic. Click here for more details.

@@ -0,0 +1,193 @@
1
+ import { Menubar } from './scripts/a11y-navigation/Menubar';
2
+ import throttle from 'lodash.throttle';
3
+ import { TrialForm } from '../../molecules/trial-form/trial-form';
4
+
5
+ class Header {
6
+ constructor() {
7
+ this.nodes = {
8
+ navMenuTrigger: document.querySelectorAll('.js-nav-menu-trigger'),
9
+ header: document.querySelector('.header'),
10
+ headerShadow: document.querySelector('.header__shadow'),
11
+ widgetIntro: document.querySelector('.widget-intro'),
12
+ body: document.body,
13
+ subMenuTriggerMobile: document.querySelectorAll('.js-sub-menu-trigger-mobile'),
14
+ formGroup: document.querySelector('.header-form-group'),
15
+ formTrigger: document.querySelector('.header-trial-form-trigger'),
16
+ contactSales: document.querySelector('.header__nav-group-item--contact-sales'),
17
+ };
18
+
19
+ this.headerHeight = this.nodes.header.clientHeight;
20
+ this.opacityScrollRate = 500;
21
+ this.stickPoint = 0;
22
+ this.activeMenuItem = null;
23
+ this.activeSubMenu = null;
24
+ this.isWithTheme = true;
25
+ this.isNavOpen = false;
26
+ this.isTrialOpen = false;
27
+ this.theme = this.nodes.widgetIntro ? this.nodes.widgetIntro.getAttribute('data-theme') : 'default';
28
+ this.nodes.header.classList.add('header--theme-' + this.theme);
29
+ this.headerStickyTheme = this.nodes.header.getAttribute('data-sticky-theme')
30
+ ? this.nodes.header.getAttribute('data-sticky-theme')
31
+ : 'default';
32
+
33
+ this.initNavMenu();
34
+ this.initTrialForm();
35
+
36
+ window.addEventListener(
37
+ 'scroll',
38
+ throttle(() => {
39
+ this.onScroll();
40
+ }, 50)
41
+ );
42
+ }
43
+
44
+ initTrialForm() {
45
+ const formsCollection = this.nodes.header.querySelectorAll('.trial-form');
46
+
47
+ [].forEach.call(formsCollection, (formNode) => {
48
+ const trialForm = new TrialForm(formNode);
49
+
50
+ trialForm.init();
51
+
52
+ if (!formNode.classList.contains('header-trial-form-mobile')) {
53
+ document.addEventListener('click', (event) => {
54
+ const isFormTriggerEnable =
55
+ event.target === this.nodes.formTrigger || event.target.parentNode === this.nodes.formTrigger;
56
+
57
+ const isFormTriggerDisable =
58
+ event.target !== trialForm.fields.email.control &&
59
+ trialForm.fields.button.node !== event.target.parentNode &&
60
+ !trialForm.fields.email.dirty &&
61
+ this.isTrialOpen;
62
+
63
+ if (isFormTriggerEnable) {
64
+ this.nodes.formGroup.classList.add('header-form-group--opened');
65
+ trialForm.fields.email.control.focus();
66
+ this.isTrialOpen = true;
67
+ this.nodes.contactSales.hidden = true;
68
+ }
69
+
70
+ if (isFormTriggerDisable) {
71
+ this.nodes.formGroup.classList.remove('header-form-group--opened');
72
+ trialForm.resetFormStatuses();
73
+ this.isTrialOpen = false;
74
+ this.nodes.contactSales.hidden = false;
75
+ }
76
+ });
77
+ }
78
+ });
79
+ }
80
+
81
+ initNavMenu() {
82
+ const navMenuTrigger = [].slice.call(this.nodes.navMenuTrigger);
83
+ const subMenuTriggerMobile = [].slice.call(this.nodes.subMenuTriggerMobile);
84
+
85
+ navMenuTrigger.forEach((item) => {
86
+ item.addEventListener('click', () => {
87
+ this.nodes.body.classList.toggle('page--nav-opened');
88
+ this.isNavOpen = !this.isNavOpen;
89
+ });
90
+ });
91
+
92
+ subMenuTriggerMobile.forEach((item) => {
93
+ item.addEventListener('click', (event) => {
94
+ event.preventDefault();
95
+ const targetElement = event.target;
96
+ const subMenu = targetElement.nextElementSibling;
97
+
98
+ if (subMenu.style.maxHeight) {
99
+ targetElement.classList.remove('header-menu-mobile__link--opened');
100
+ subMenu.style.maxHeight = null;
101
+ this.activeMenuItem = null;
102
+ this.activeSubMenu = null;
103
+ } else {
104
+ subMenu.style.maxHeight = subMenu.scrollHeight + 'px';
105
+ targetElement.classList.add('header-menu-mobile__link--opened');
106
+
107
+ if (this.activeSubMenu && this.activeMenuItem) {
108
+ this.activeSubMenu.style.maxHeight = null;
109
+ this.activeMenuItem.classList.remove('header-menu-mobile__link--opened');
110
+ }
111
+
112
+ this.activeMenuItem = targetElement;
113
+ this.activeSubMenu = subMenu;
114
+ }
115
+ });
116
+ });
117
+ }
118
+
119
+ onScroll() {
120
+ const clientScrollOffset = window.pageYOffset;
121
+ const isReadyToStuck = clientScrollOffset > this.stickPoint && !this.stuck;
122
+ const isReadyToUnstuck = clientScrollOffset <= this.stickPoint && this.stuck;
123
+
124
+ this.initShadow(clientScrollOffset);
125
+
126
+ if (this.nodes.widgetIntro && this.theme !== this.headerStickyTheme) {
127
+ this.changeStickyTheme();
128
+ }
129
+
130
+ if (isReadyToStuck) {
131
+ this.stuck = true;
132
+ this.nodes.header.classList.add('header--sticky');
133
+ if (this.nodes.contactSales) {
134
+ this.nodes.contactSales.hidden = true;
135
+ }
136
+ }
137
+ if (isReadyToUnstuck) {
138
+ this.stuck = false;
139
+ this.nodes.header.classList.remove('header--sticky');
140
+ if (this.nodes.contactSales) {
141
+ this.nodes.contactSales.hidden = false;
142
+ }
143
+ }
144
+ }
145
+
146
+ initShadow(pageScrollOffset) {
147
+ let opacityValue = '1';
148
+
149
+ if (pageScrollOffset < this.opacityScrollRate) {
150
+ opacityValue = pageScrollOffset / this.opacityScrollRate;
151
+ }
152
+
153
+ this.nodes.headerShadow.style.opacity = opacityValue;
154
+ }
155
+
156
+ changeStickyTheme() {
157
+ const introScrollOffset = this.nodes.widgetIntro.getBoundingClientRect();
158
+ const isHeaderOverIntro =
159
+ introScrollOffset.top <= this.headerHeight && introScrollOffset.bottom > this.headerHeight;
160
+ const isHeaderUnderIntro = introScrollOffset.bottom <= this.headerHeight;
161
+
162
+ if (isHeaderOverIntro && !this.isWithTheme) {
163
+ this.isWithTheme = true;
164
+ this.nodes.header.classList.add('header--theme-' + this.theme);
165
+ this.nodes.header.classList.remove('header--theme-' + this.headerStickyTheme);
166
+ }
167
+
168
+ if (isHeaderUnderIntro && this.isWithTheme) {
169
+ this.isWithTheme = false;
170
+ this.nodes.header.classList.remove('header--theme-' + this.theme);
171
+ this.nodes.header.classList.add('header--theme-' + this.headerStickyTheme);
172
+ }
173
+ }
174
+ }
175
+
176
+ const isLightHeader = document.querySelector('.header--light');
177
+
178
+ if (!isLightHeader) {
179
+ const menubar = new Menubar(document.querySelector('.header-menu__list'));
180
+
181
+ menubar.init();
182
+
183
+ const languageSelector = new Menubar(document.querySelector('.header-language-selector'));
184
+
185
+ languageSelector.init();
186
+ }
187
+
188
+ const header = new Header();
189
+
190
+
191
+
192
+ // WEBPACK FOOTER //
193
+ // ./node_modules/wg5/src/modules/organisms/header/header.js
@@ -0,0 +1,176 @@
1
+ import { PopupMenu } from './PopupMenu';
2
+ import { isPrintableCharacter, keyCode } from './helpers';
3
+
4
+ export class MenuItem {
5
+ constructor(domNode, menuObj) {
6
+ this.domNode = domNode;
7
+ this.menu = menuObj;
8
+ this.popupMenu = null;
9
+ this.isMenubarItem = false;
10
+ this.navMenuDelay = 300;
11
+ this.keyCode = keyCode;
12
+ }
13
+
14
+ init() {
15
+ this.domNode.tabIndex = -1;
16
+
17
+ this.domNode.addEventListener('keydown', this.handleKeydown.bind(this));
18
+ this.domNode.addEventListener('click', this.handleClick.bind(this));
19
+ this.domNode.addEventListener('focus', this.handleFocus.bind(this));
20
+ this.domNode.addEventListener('blur', this.handleBlur.bind(this));
21
+ this.domNode.addEventListener('mouseover', this.handleMouseover.bind(this));
22
+ this.domNode.addEventListener('mouseout', this.handleMouseout.bind(this));
23
+
24
+ // Initialize flyout menu
25
+
26
+ let nextElement = this.domNode.nextElementSibling;
27
+
28
+ if (nextElement && nextElement.tagName === 'UL') {
29
+ this.popupMenu = new PopupMenu(nextElement, this);
30
+ this.popupMenu.init();
31
+ }
32
+ }
33
+
34
+ isExpanded() {
35
+ return this.domNode.getAttribute('aria-expanded') === 'true';
36
+ }
37
+
38
+ handleKeydown(event) {
39
+ let currentTarget = event.currentTarget,
40
+ char = event.key,
41
+ isMenuOpen = false,
42
+ clickEvent;
43
+
44
+ switch (event.keyCode) {
45
+ case this.keyCode.SPACE:
46
+ case this.keyCode.RETURN:
47
+ if (this.popupMenu) {
48
+ this.popupMenu.open();
49
+ this.popupMenu.setFocusToFirstItem();
50
+ } else {
51
+ // Create simulated mouse event to mimic the behavior of ATs
52
+ // and let the event handler handleClick do the housekeeping.
53
+ try {
54
+ clickEvent = new MouseEvent('click', {
55
+ view: window,
56
+ bubbles: true,
57
+ cancelable: true,
58
+ });
59
+ } catch (err) {
60
+ if (document.createEvent) {
61
+ // DOM Level 3 for IE 9+
62
+ clickEvent = document.createEvent('MouseEvents');
63
+ clickEvent.initEvent('click', true, true);
64
+ }
65
+ }
66
+ currentTarget.dispatchEvent(clickEvent);
67
+ }
68
+
69
+ isMenuOpen = true;
70
+ break;
71
+
72
+ case this.keyCode.UP:
73
+ this.menu.setFocusToPreviousItem(this);
74
+ isMenuOpen = true;
75
+ break;
76
+
77
+ case this.keyCode.DOWN:
78
+ this.menu.setFocusToNextItem(this);
79
+ isMenuOpen = true;
80
+ break;
81
+
82
+ case this.keyCode.LEFT:
83
+ this.menu.setFocusToController('previous', true);
84
+ this.menu.close(true);
85
+ isMenuOpen = true;
86
+ break;
87
+
88
+ case this.keyCode.RIGHT:
89
+ if (this.popupMenu) {
90
+ this.popupMenu.open();
91
+ this.popupMenu.setFocusToFirstItem();
92
+ } else {
93
+ this.menu.setFocusToController('next', true);
94
+ this.menu.close(true);
95
+ }
96
+ isMenuOpen = true;
97
+ break;
98
+
99
+ case this.keyCode.HOME:
100
+ case this.keyCode.PAGEUP:
101
+ this.menu.setFocusToFirstItem();
102
+ isMenuOpen = true;
103
+ break;
104
+
105
+ case this.keyCode.END:
106
+ case this.keyCode.PAGEDOWN:
107
+ this.menu.setFocusToLastItem();
108
+ isMenuOpen = true;
109
+ break;
110
+
111
+ case this.keyCode.ESC:
112
+ this.menu.setFocusToController();
113
+ this.menu.close(true);
114
+ isMenuOpen = true;
115
+ break;
116
+
117
+ case this.keyCode.TAB:
118
+ this.menu.setFocusToController();
119
+ break;
120
+
121
+ default:
122
+ if (isPrintableCharacter(char)) {
123
+ this.menu.setFocusByFirstCharacter(this, char);
124
+ isMenuOpen = true;
125
+ }
126
+ break;
127
+ }
128
+
129
+ if (isMenuOpen) {
130
+ event.stopPropagation();
131
+ event.preventDefault();
132
+ }
133
+ }
134
+
135
+ setExpanded(value) {
136
+ this.domNode.setAttribute('aria-expanded', value ? 'true' : 'false');
137
+ }
138
+
139
+ handleClick() {
140
+ this.menu.setFocusToController();
141
+ this.menu.close(true);
142
+ }
143
+
144
+ handleFocus() {
145
+ this.menu.hasFocus = true;
146
+ }
147
+
148
+ handleBlur() {
149
+ this.menu.hasFocus = false;
150
+ setTimeout(this.menu.close.bind(this.menu, false), this.navMenuDelay);
151
+ }
152
+
153
+ handleMouseover() {
154
+ this.menu.hasHover = true;
155
+ this.menu.open();
156
+ if (this.popupMenu) {
157
+ this.popupMenu.hasHover = true;
158
+ this.popupMenu.open();
159
+ }
160
+ }
161
+
162
+ handleMouseout() {
163
+ if (this.popupMenu) {
164
+ this.popupMenu.hasHover = false;
165
+ this.popupMenu.close(true);
166
+ }
167
+
168
+ this.menu.hasHover = false;
169
+ setTimeout(this.menu.close.bind(this.menu, false), this.navMenuDelay);
170
+ }
171
+ }
172
+
173
+
174
+
175
+ // WEBPACK FOOTER //
176
+ // ./node_modules/wg5/src/modules/organisms/header/scripts/a11y-navigation/MenuItem.js
@@ -0,0 +1,178 @@
1
+ import { MenubarItem } from './MenubarItem';
2
+
3
+ export class Menubar {
4
+ constructor(domNode) {
5
+ const msgPrefix = 'Menubar constructor argument menubarNode ';
6
+ let element;
7
+
8
+ // Check whether menubarNode is a DOM element
9
+
10
+ if (!(domNode instanceof Element)) {
11
+ throw new TypeError(msgPrefix + 'is not a DOM Element.');
12
+ }
13
+
14
+ // Check whether menubarNode has descendant elements
15
+
16
+ if (domNode.childElementCount === 0) {
17
+ throw new Error(msgPrefix + 'has no element children.');
18
+ }
19
+
20
+ // Check whether menubarNode has A elements
21
+
22
+ element = domNode.firstElementChild;
23
+ while (element) {
24
+ let menubarItem = element.firstElementChild;
25
+
26
+ if (element && menubarItem && menubarItem.tagName !== 'A') {
27
+ throw new Error(msgPrefix + 'has child elements are not A elements.');
28
+ }
29
+ element = element.nextElementSibling;
30
+ }
31
+
32
+ this.isMenubar = true;
33
+
34
+ this.domNode = domNode;
35
+
36
+ this.menubarItems = []; // See Menubar init method
37
+ this.firstChars = []; // See Menubar init method
38
+
39
+ this.firstItem = null; // See Menubar init method
40
+ this.lastItem = null; // See Menubar init method
41
+
42
+ this.hasFocus = false; // See MenubarItem handleFocus, handleBlur
43
+ this.hasHover = false; // See Menubar handleMouseover, handleMouseout
44
+ }
45
+
46
+ init() {
47
+ let menubarItem, textContent, numItems, element;
48
+
49
+ // Traverse the element children of menubarNode: configure each with
50
+ // menuitem role behavior and store reference in menuitems array.
51
+
52
+ element = this.domNode.firstElementChild;
53
+
54
+ while (element) {
55
+ let menuElement = element.firstElementChild;
56
+
57
+ if (element && menuElement && menuElement.tagName === 'A') {
58
+ menubarItem = new MenubarItem(menuElement, this);
59
+ menubarItem.init();
60
+ this.menubarItems.push(menubarItem);
61
+ textContent = menuElement.textContent.trim();
62
+ this.firstChars.push(textContent.substring(0, 1).toLowerCase());
63
+ }
64
+
65
+ element = element.nextElementSibling;
66
+ }
67
+
68
+ // Use populated menuitems array to initialize firstItem and lastItem.
69
+
70
+ numItems = this.menubarItems.length;
71
+ if (numItems > 0) {
72
+ this.firstItem = this.menubarItems[0];
73
+ this.lastItem = this.menubarItems[numItems - 1];
74
+ }
75
+ this.firstItem.domNode.tabIndex = 0;
76
+ }
77
+
78
+ setFocusToItem(newItem) {
79
+ let flag = false;
80
+
81
+ for (let i = 0; i < this.menubarItems.length; i++) {
82
+ let mbi = this.menubarItems[i];
83
+
84
+ if (mbi.domNode.tabIndex === 0) {
85
+ flag = mbi.domNode.getAttribute('aria-expanded') === 'true';
86
+ }
87
+
88
+ mbi.domNode.tabIndex = -1;
89
+ if (mbi.popupMenu) {
90
+ mbi.popupMenu.close();
91
+ }
92
+ }
93
+
94
+ newItem.domNode.focus();
95
+ newItem.domNode.tabIndex = 0;
96
+
97
+ if (flag && newItem.popupMenu) {
98
+ newItem.popupMenu.open();
99
+ }
100
+ }
101
+
102
+ setFocusToFirstItem() {
103
+ this.setFocusToItem(this.firstItem);
104
+ }
105
+
106
+ setFocusToLastItem() {
107
+ this.setFocusToItem(this.lastItem);
108
+ }
109
+
110
+ setFocusToPreviousItem(currentItem) {
111
+ let index, newItem;
112
+
113
+ if (currentItem === this.firstItem) {
114
+ newItem = this.lastItem;
115
+ } else {
116
+ index = this.menubarItems.indexOf(currentItem);
117
+ newItem = this.menubarItems[index - 1];
118
+ }
119
+
120
+ this.setFocusToItem(newItem);
121
+ }
122
+
123
+ setFocusToNextItem(currentItem) {
124
+ let index, newItem;
125
+
126
+ if (currentItem === this.lastItem) {
127
+ newItem = this.firstItem;
128
+ } else {
129
+ index = this.menubarItems.indexOf(currentItem);
130
+ newItem = this.menubarItems[index + 1];
131
+ }
132
+
133
+ this.setFocusToItem(newItem);
134
+ }
135
+
136
+ setFocusByFirstCharacter(currentItem, char) {
137
+ let start,
138
+ index,
139
+ lowerCasedChar = char.toLowerCase();
140
+
141
+ // Get start index for search based on position of currentItem
142
+
143
+ start = this.menubarItems.indexOf(currentItem) + 1;
144
+ if (start === this.menubarItems.length) {
145
+ start = 0;
146
+ }
147
+
148
+ // Check remaining slots in the menu
149
+
150
+ index = this.getIndexFirstChars(start, lowerCasedChar);
151
+
152
+ // If not found in remaining slots, check from beginning
153
+
154
+ if (index === -1) {
155
+ index = this.getIndexFirstChars(0, lowerCasedChar);
156
+ }
157
+
158
+ // If match was found...
159
+
160
+ if (index > -1) {
161
+ this.setFocusToItem(this.menubarItems[index]);
162
+ }
163
+ }
164
+
165
+ getIndexFirstChars(startIndex, char) {
166
+ for (let i = startIndex; i < this.firstChars.length; i++) {
167
+ if (char === this.firstChars[i]) {
168
+ return i;
169
+ }
170
+ }
171
+ return -1;
172
+ }
173
+ }
174
+
175
+
176
+
177
+ // WEBPACK FOOTER //
178
+ // ./node_modules/wg5/src/modules/organisms/header/scripts/a11y-navigation/Menubar.js
@@ -0,0 +1,136 @@
1
+ import { PopupMenu } from './PopupMenu';
2
+ import { isPrintableCharacter, keyCode } from './helpers';
3
+
4
+ export class MenubarItem {
5
+ constructor(domNode, menuObj) {
6
+ this.menu = menuObj;
7
+ this.domNode = domNode;
8
+ this.popupMenu = false;
9
+ this.hasFocus = false;
10
+ this.hasHover = false;
11
+ this.isMenubarItem = true;
12
+ this.keyCode = keyCode;
13
+ }
14
+
15
+ init() {
16
+ this.domNode.addEventListener('keydown', this.handleKeydown.bind(this));
17
+ this.domNode.addEventListener('focus', this.handleFocus.bind(this));
18
+ this.domNode.addEventListener('blur', this.handleBlur.bind(this));
19
+
20
+ // Since css hover rule is set for element li, it is necessary to add event handler for element li
21
+ this.domNode.parentNode.addEventListener('mouseover', this.handleMouseover.bind(this));
22
+ this.domNode.parentNode.addEventListener('mouseout', this.handleMouseout.bind(this));
23
+
24
+ // Initialize pop up menus
25
+ let nextElement = this.domNode.nextElementSibling;
26
+ let hasSubMenu = nextElement && nextElement.classList.contains('js-header-sub-menu');
27
+
28
+ if (hasSubMenu) {
29
+ this.popupMenu = new PopupMenu(nextElement, this);
30
+ this.popupMenu.init();
31
+ }
32
+ }
33
+
34
+ handleKeydown() {
35
+ let char = event.key,
36
+ isMenuOpen = false;
37
+
38
+ switch (event.keyCode) {
39
+ case this.keyCode.SPACE:
40
+ case this.keyCode.RETURN:
41
+ case this.keyCode.DOWN:
42
+ if (this.popupMenu) {
43
+ this.popupMenu.open();
44
+ this.popupMenu.setFocusToFirstItem();
45
+ isMenuOpen = true;
46
+ }
47
+ break;
48
+
49
+ case this.keyCode.LEFT:
50
+ this.menu.setFocusToPreviousItem(this);
51
+ isMenuOpen = true;
52
+ break;
53
+
54
+ case this.keyCode.RIGHT:
55
+ this.menu.setFocusToNextItem(this);
56
+ isMenuOpen = true;
57
+ break;
58
+
59
+ case this.keyCode.UP:
60
+ if (this.popupMenu) {
61
+ this.popupMenu.open();
62
+ this.popupMenu.setFocusToLastItem();
63
+ isMenuOpen = true;
64
+ }
65
+ break;
66
+
67
+ case this.keyCode.HOME:
68
+ case this.keyCode.PAGEUP:
69
+ this.menu.setFocusToFirstItem();
70
+ isMenuOpen = true;
71
+ break;
72
+
73
+ case this.keyCode.END:
74
+ case this.keyCode.PAGEDOWN:
75
+ this.menu.setFocusToLastItem();
76
+ isMenuOpen = true;
77
+ break;
78
+
79
+ case this.keyCode.TAB:
80
+ if (this.popupMenu) {
81
+ this.popupMenu.close(true);
82
+ }
83
+
84
+ break;
85
+
86
+ case this.keyCode.ESC:
87
+ this.popupMenu.close(true);
88
+ break;
89
+
90
+ default:
91
+ if (isPrintableCharacter(char)) {
92
+ this.menu.setFocusByFirstCharacter(this, char);
93
+ isMenuOpen = true;
94
+ }
95
+ break;
96
+ }
97
+
98
+ if (isMenuOpen) {
99
+ event.stopPropagation();
100
+ event.preventDefault();
101
+ }
102
+ }
103
+
104
+ setExpanded(value) {
105
+ this.domNode.setAttribute('aria-expanded', value ? 'true' : 'false');
106
+ }
107
+
108
+ handleFocus() {
109
+ this.menu.hasFocus = true;
110
+ }
111
+
112
+ handleBlur() {
113
+ this.menu.hasFocus = false;
114
+ }
115
+
116
+ handleMouseover() {
117
+ this.hasHover = true;
118
+
119
+ if (this.popupMenu) {
120
+ this.popupMenu.open();
121
+ }
122
+ }
123
+
124
+ handleMouseout() {
125
+ this.hasHover = false;
126
+
127
+ if (this.popupMenu) {
128
+ setTimeout(this.popupMenu.close.bind(this.popupMenu, false), 0);
129
+ }
130
+ }
131
+ }
132
+
133
+
134
+
135
+ // WEBPACK FOOTER //
136
+ // ./node_modules/wg5/src/modules/organisms/header/scripts/a11y-navigation/MenubarItem.js