1 | function _typeof(obj) {
|
2 | if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
|
3 | _typeof = function _typeof(obj) {
|
4 | return typeof obj;
|
5 | };
|
6 | } else {
|
7 | _typeof = function _typeof(obj) {
|
8 | return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
|
9 | };
|
10 | }
|
11 |
|
12 | return _typeof(obj);
|
13 | }
|
14 |
|
15 | function _toConsumableArray(arr) {
|
16 | return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
|
17 | }
|
18 |
|
19 | function _nonIterableSpread() {
|
20 | throw new TypeError("Invalid attempt to spread non-iterable instance");
|
21 | }
|
22 |
|
23 | function _iterableToArray(iter) {
|
24 | if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
|
25 | }
|
26 |
|
27 | function _arrayWithoutHoles(arr) {
|
28 | if (Array.isArray(arr)) {
|
29 | for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) {
|
30 | arr2[i] = arr[i];
|
31 | }
|
32 |
|
33 | return arr2;
|
34 | }
|
35 | }
|
36 |
|
37 | function _classCallCheck(instance, Constructor) {
|
38 | if (!(instance instanceof Constructor)) {
|
39 | throw new TypeError("Cannot call a class as a function");
|
40 | }
|
41 | }
|
42 |
|
43 | function _defineProperties(target, props) {
|
44 | for (var i = 0; i < props.length; i++) {
|
45 | var descriptor = props[i];
|
46 | descriptor.enumerable = descriptor.enumerable || false;
|
47 | descriptor.configurable = true;
|
48 | if ("value" in descriptor) descriptor.writable = true;
|
49 | Object.defineProperty(target, descriptor.key, descriptor);
|
50 | }
|
51 | }
|
52 |
|
53 | function _createClass(Constructor, protoProps, staticProps) {
|
54 | if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
55 | if (staticProps) _defineProperties(Constructor, staticProps);
|
56 | return Constructor;
|
57 | }
|
58 |
|
59 | function _possibleConstructorReturn(self, call) {
|
60 | if (call && (_typeof(call) === "object" || typeof call === "function")) {
|
61 | return call;
|
62 | }
|
63 |
|
64 | return _assertThisInitialized(self);
|
65 | }
|
66 |
|
67 | function _assertThisInitialized(self) {
|
68 | if (self === void 0) {
|
69 | throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
|
70 | }
|
71 |
|
72 | return self;
|
73 | }
|
74 |
|
75 | function _getPrototypeOf(o) {
|
76 | _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
|
77 | return o.__proto__ || Object.getPrototypeOf(o);
|
78 | };
|
79 | return _getPrototypeOf(o);
|
80 | }
|
81 |
|
82 | function _inherits(subClass, superClass) {
|
83 | if (typeof superClass !== "function" && superClass !== null) {
|
84 | throw new TypeError("Super expression must either be null or a function");
|
85 | }
|
86 |
|
87 | subClass.prototype = Object.create(superClass && superClass.prototype, {
|
88 | constructor: {
|
89 | value: subClass,
|
90 | writable: true,
|
91 | configurable: true
|
92 | }
|
93 | });
|
94 | if (superClass) _setPrototypeOf(subClass, superClass);
|
95 | }
|
96 |
|
97 | function _setPrototypeOf(o, p) {
|
98 | _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
|
99 | o.__proto__ = p;
|
100 | return o;
|
101 | };
|
102 |
|
103 | return _setPrototypeOf(o, p);
|
104 | }
|
105 |
|
106 | function _objectSpread(target) {
|
107 | for (var i = 1; i < arguments.length; i++) {
|
108 | var source = arguments[i] != null ? arguments[i] : {};
|
109 | var ownKeys = Object.keys(source);
|
110 |
|
111 | if (typeof Object.getOwnPropertySymbols === 'function') {
|
112 | ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
|
113 | return Object.getOwnPropertyDescriptor(source, sym).enumerable;
|
114 | }));
|
115 | }
|
116 |
|
117 | ownKeys.forEach(function (key) {
|
118 | _defineProperty(target, key, source[key]);
|
119 | });
|
120 | }
|
121 |
|
122 | return target;
|
123 | }
|
124 |
|
125 | function _defineProperty(obj, key, value) {
|
126 | if (key in obj) {
|
127 | Object.defineProperty(obj, key, {
|
128 | value: value,
|
129 | enumerable: true,
|
130 | configurable: true,
|
131 | writable: true
|
132 | });
|
133 | } else {
|
134 | obj[key] = value;
|
135 | }
|
136 |
|
137 | return obj;
|
138 | }
|
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 | import settings from '../../globals/js/settings';
|
148 | import eventMatches from '../../globals/js/misc/event-matches';
|
149 | import mixin from '../../globals/js/misc/mixin';
|
150 | import createComponent from '../../globals/js/mixins/create-component';
|
151 | import initComponentBySearch from '../../globals/js/mixins/init-component-by-search';
|
152 | import eventedShowHideState from '../../globals/js/mixins/evented-show-hide-state';
|
153 | import handles from '../../globals/js/mixins/handles';
|
154 | import FloatingMenu, { DIRECTION_TOP, DIRECTION_BOTTOM, DIRECTION_LEFT, DIRECTION_RIGHT } from '../floating-menu/floating-menu';
|
155 | import getLaunchingDetails from '../../globals/js/misc/get-launching-details';
|
156 | import on from '../../globals/js/misc/on';
|
157 | import { componentsX } from '../../globals/js/feature-flags';
|
158 |
|
159 |
|
160 |
|
161 |
|
162 |
|
163 | var triggerButtonPositionProps =
|
164 |
|
165 | function () {
|
166 | var _ref;
|
167 |
|
168 | return _ref = {}, _defineProperty(_ref, DIRECTION_TOP, 'bottom'), _defineProperty(_ref, DIRECTION_BOTTOM, 'top'), _defineProperty(_ref, DIRECTION_LEFT, 'left'), _defineProperty(_ref, DIRECTION_RIGHT, 'right'), _ref;
|
169 | }();
|
170 |
|
171 |
|
172 |
|
173 |
|
174 |
|
175 |
|
176 | var triggerButtonPositionFactors =
|
177 |
|
178 | function () {
|
179 | var _ref2;
|
180 |
|
181 | return _ref2 = {}, _defineProperty(_ref2, DIRECTION_TOP, -2), _defineProperty(_ref2, DIRECTION_BOTTOM, -1), _defineProperty(_ref2, DIRECTION_LEFT, -2), _defineProperty(_ref2, DIRECTION_RIGHT, -1), _ref2;
|
182 | }();
|
183 |
|
184 |
|
185 |
|
186 |
|
187 |
|
188 |
|
189 |
|
190 |
|
191 |
|
192 | export var getMenuOffset = function getMenuOffset(menuBody, direction, trigger) {
|
193 | var triggerButtonPositionProp = triggerButtonPositionProps[direction];
|
194 | var triggerButtonPositionFactor = triggerButtonPositionFactors[direction];
|
195 |
|
196 | if (!triggerButtonPositionProp || !triggerButtonPositionFactor) {
|
197 | console.warn('Wrong floating menu direction:', direction);
|
198 | }
|
199 |
|
200 | var menuWidth = menuBody.offsetWidth;
|
201 | var menuHeight = menuBody.offsetHeight;
|
202 | var arrowStyle = menuBody.ownerDocument.defaultView.getComputedStyle(menuBody, ':before');
|
203 | var values = [triggerButtonPositionProp, 'left', 'width', 'height', 'border-top-width'].reduce(function (o, name) {
|
204 | return _objectSpread({}, o, _defineProperty({}, name, Number((/^([\d-.]+)px$/.exec(arrowStyle.getPropertyValue(name)) || [])[1])));
|
205 | }, {});
|
206 |
|
207 | if (Object.keys(values).every(function (name) {
|
208 | return !isNaN(values[name]);
|
209 | })) {
|
210 | var left = values.left,
|
211 | width = values.width,
|
212 | height = values.height,
|
213 | borderTopWidth = values['border-top-width'];
|
214 | return {
|
215 | left: menuWidth / 2 - (left + Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)) / 2),
|
216 | top: Math.sqrt(Math.pow(borderTopWidth, 2) * 2) + triggerButtonPositionFactor * values[triggerButtonPositionProp]
|
217 | };
|
218 | }
|
219 |
|
220 | if (componentsX) {
|
221 |
|
222 | var menu = OverflowMenu.components.get(trigger);
|
223 |
|
224 | if (!menu) {
|
225 | throw new TypeError('Overflow menu instance cannot be found.');
|
226 | }
|
227 |
|
228 | var flip = menuBody.classList.contains(menu.options.classMenuFlip);
|
229 |
|
230 | if (triggerButtonPositionProp === 'top' || triggerButtonPositionProp === 'bottom') {
|
231 | var triggerWidth = trigger.offsetWidth;
|
232 | return {
|
233 | left: (!flip ? 1 : -1) * (menuWidth / 2 - triggerWidth / 2),
|
234 | top: 0
|
235 | };
|
236 | }
|
237 |
|
238 | if (triggerButtonPositionProp === 'left' || triggerButtonPositionProp === 'right') {
|
239 | var triggerHeight = trigger.offsetHeight;
|
240 | return {
|
241 | left: 0,
|
242 | top: (!flip ? 1 : -1) * (menuHeight / 2 - triggerHeight / 2)
|
243 | };
|
244 | }
|
245 | }
|
246 |
|
247 | return undefined;
|
248 | };
|
249 |
|
250 | var OverflowMenu =
|
251 |
|
252 | function (_mixin) {
|
253 | _inherits(OverflowMenu, _mixin);
|
254 | |
255 |
|
256 |
|
257 |
|
258 |
|
259 |
|
260 |
|
261 |
|
262 |
|
263 |
|
264 |
|
265 |
|
266 |
|
267 |
|
268 |
|
269 |
|
270 | function OverflowMenu(element, options) {
|
271 | var _this;
|
272 |
|
273 | _classCallCheck(this, OverflowMenu);
|
274 |
|
275 | _this = _possibleConstructorReturn(this, _getPrototypeOf(OverflowMenu).call(this, element, options));
|
276 |
|
277 | _this.getCurrentNavigation = function () {
|
278 | var focused = _this.element.ownerDocument.activeElement;
|
279 | return focused.nodeType === Node.ELEMENT_NODE && focused.matches(_this.options.selectorItem) ? focused : null;
|
280 | };
|
281 |
|
282 | _this.navigate = function (direction) {
|
283 | var items = _toConsumableArray(_this.element.ownerDocument.querySelectorAll(_this.options.selectorItem));
|
284 |
|
285 | var start = _this.getCurrentNavigation() || _this.element.querySelector(_this.options.selectorItemSelected);
|
286 |
|
287 | var getNextItem = function getNextItem(old) {
|
288 | var handleUnderflow = function handleUnderflow(index, length) {
|
289 | return index + (index >= 0 ? 0 : length);
|
290 | };
|
291 |
|
292 | var handleOverflow = function handleOverflow(index, length) {
|
293 | return index - (index < length ? 0 : length);
|
294 | };
|
295 |
|
296 |
|
297 | var index = Math.max(items.indexOf(old) + direction, -1);
|
298 | return items[handleUnderflow(handleOverflow(index, items.length), items.length)];
|
299 | };
|
300 |
|
301 | for (var current = getNextItem(start); current && current !== start; current = getNextItem(current)) {
|
302 | if (!current.matches(_this.options.selectorItemHidden) && !current.parentNode.matches(_this.options.selectorItemHidden) && !current.matches(_this.options.selectorItemSelected)) {
|
303 | current.focus();
|
304 | break;
|
305 | }
|
306 | }
|
307 | };
|
308 |
|
309 | _this.manage(on(_this.element.ownerDocument, 'click', function (event) {
|
310 | _this._handleDocumentClick(event);
|
311 |
|
312 | _this.wasOpenBeforeClick = undefined;
|
313 | }));
|
314 |
|
315 | _this.manage(on(_this.element.ownerDocument, 'keydown', function (event) {
|
316 | _this._handleKeyPress(event);
|
317 | }));
|
318 |
|
319 | _this.manage(on(_this.element, 'mousedown', function () {
|
320 | _this.wasOpenBeforeClick = element.classList.contains(_this.options.classShown);
|
321 | }));
|
322 |
|
323 | return _this;
|
324 | }
|
325 | |
326 |
|
327 |
|
328 |
|
329 |
|
330 |
|
331 |
|
332 |
|
333 | _createClass(OverflowMenu, [{
|
334 | key: "changeState",
|
335 | value: function changeState(state, detail, callback) {
|
336 | if (state === 'hidden') {
|
337 | this.element.setAttribute('aria-expanded', 'false');
|
338 | } else {
|
339 | this.element.setAttribute('aria-expanded', 'true');
|
340 | }
|
341 |
|
342 | if (!this.optionMenu) {
|
343 | var optionMenu = this.element.querySelector(this.options.selectorOptionMenu);
|
344 |
|
345 | if (!optionMenu) {
|
346 | throw new Error('Cannot find the target menu.');
|
347 | }
|
348 |
|
349 |
|
350 | this.optionMenu = FloatingMenu.create(optionMenu, {
|
351 | refNode: this.element,
|
352 | classShown: this.options.classMenuShown,
|
353 | classRefShown: this.options.classShown,
|
354 | offset: this.options.objMenuOffset
|
355 | });
|
356 | this.children.push(this.optionMenu);
|
357 | }
|
358 |
|
359 | if (this.optionMenu.element.classList.contains(this.options.classMenuFlip)) {
|
360 | this.optionMenu.options.offset = this.options.objMenuOffsetFlip;
|
361 | }
|
362 |
|
363 |
|
364 |
|
365 | this.optionMenu.changeState(state, Object.assign(detail, {
|
366 | delegatorNode: this.element
|
367 | }), callback);
|
368 | }
|
369 | |
370 |
|
371 |
|
372 |
|
373 |
|
374 |
|
375 | }, {
|
376 | key: "_handleDocumentClick",
|
377 | value: function _handleDocumentClick(event) {
|
378 | var element = this.element,
|
379 | optionMenu = this.optionMenu,
|
380 | wasOpenBeforeClick = this.wasOpenBeforeClick;
|
381 | var isOfSelf = element.contains(event.target);
|
382 | var isOfMenu = optionMenu && optionMenu.element.contains(event.target);
|
383 | var shouldBeOpen = isOfSelf && !wasOpenBeforeClick;
|
384 | var state = shouldBeOpen ? 'shown' : 'hidden';
|
385 |
|
386 | if (isOfSelf) {
|
387 | if (element.tagName === 'A') {
|
388 | event.preventDefault();
|
389 | }
|
390 |
|
391 | event.delegateTarget = element;
|
392 | }
|
393 |
|
394 | if (!isOfMenu || eventMatches(event, this.options.selectorItem)) {
|
395 | this.changeState(state, getLaunchingDetails(event), function () {
|
396 | if (state === 'hidden' && isOfMenu) {
|
397 | element.focus();
|
398 | }
|
399 | });
|
400 | }
|
401 | }
|
402 | |
403 |
|
404 |
|
405 |
|
406 |
|
407 | }, {
|
408 | key: "_handleKeyPress",
|
409 |
|
410 | |
411 |
|
412 |
|
413 |
|
414 |
|
415 | value: function _handleKeyPress(event) {
|
416 | var key = event.which;
|
417 | var element = this.element,
|
418 | optionMenu = this.optionMenu,
|
419 | options = this.options;
|
420 | var isOfMenu = optionMenu && optionMenu.element.contains(event.target);
|
421 | var isExpanded = this.element.classList.contains(this.options.classShown);
|
422 |
|
423 | switch (key) {
|
424 |
|
425 | case 27:
|
426 | this.changeState('hidden', getLaunchingDetails(event), function () {
|
427 | if (isOfMenu) {
|
428 | element.focus();
|
429 | }
|
430 | });
|
431 | break;
|
432 |
|
433 |
|
434 | case 13:
|
435 | case 32:
|
436 | {
|
437 | if (!isExpanded && this.element.ownerDocument.activeElement !== this.element) {
|
438 | return;
|
439 | }
|
440 |
|
441 | var isOfSelf = element.contains(event.target);
|
442 | var shouldBeOpen = isOfSelf && !element.classList.contains(options.classShown);
|
443 | var state = shouldBeOpen ? 'shown' : 'hidden';
|
444 |
|
445 | if (isOfSelf) {
|
446 | event.delegateTarget = element;
|
447 |
|
448 | event.preventDefault();
|
449 |
|
450 | this.changeState(state, getLaunchingDetails(event), function () {
|
451 | if (state === 'hidden' && isOfMenu) {
|
452 | element.focus();
|
453 | }
|
454 | });
|
455 | }
|
456 |
|
457 | break;
|
458 | }
|
459 |
|
460 | case 38:
|
461 |
|
462 | case 40:
|
463 |
|
464 | {
|
465 | if (!isExpanded) {
|
466 | return;
|
467 | }
|
468 |
|
469 | event.preventDefault();
|
470 |
|
471 | var direction = {
|
472 | 38: -1,
|
473 | 40: 1
|
474 | }[event.which];
|
475 | this.navigate(direction);
|
476 | }
|
477 | break;
|
478 |
|
479 | default:
|
480 | break;
|
481 | }
|
482 | }
|
483 | }], [{
|
484 | key: "options",
|
485 | get: function get() {
|
486 | var prefix = settings.prefix;
|
487 | return {
|
488 | selectorInit: '[data-overflow-menu]',
|
489 | selectorOptionMenu: ".".concat(prefix, "--overflow-menu-options"),
|
490 | selectorItem: "\n .".concat(prefix, "--overflow-menu-options--open >\n .").concat(prefix, "--overflow-menu-options__option:not(.").concat(prefix, "--overflow-menu-options__option--disabled) >\n .").concat(prefix, "--overflow-menu-options__btn\n "),
|
491 | classShown: "".concat(prefix, "--overflow-menu--open"),
|
492 | classMenuShown: "".concat(prefix, "--overflow-menu-options--open"),
|
493 | classMenuFlip: "".concat(prefix, "--overflow-menu--flip"),
|
494 | objMenuOffset: getMenuOffset,
|
495 | objMenuOffsetFlip: getMenuOffset
|
496 | };
|
497 | }
|
498 | }]);
|
499 |
|
500 | OverflowMenu.components = new WeakMap();
|
501 | return OverflowMenu;
|
502 | }(mixin(createComponent, initComponentBySearch, eventedShowHideState, handles));
|
503 |
|
504 | export default OverflowMenu; |
\ | No newline at end of file |