PageSourceSearch

https://wiedza.pkn.pl/html/js/liferay/menu.js?t=1544454314000

js pkn.pl collected 2026-10-02 04:32:34 UTC 12,335 bytes, 549 lines download raw bytes

1AUI.add(
2	'liferay-menu',
3	function(A) {
4		var Lang = A.Lang;
5
6		var trim = Lang.trim;
7
8		var ATTR_CLASS_NAME = 'className';
9
10		var AUTO = 'auto';
11
12		var ARIA_ATTR_ROLE = 'role';
13
14		var CSS_STATE_ACTIVE = 'aui-state-active';
15
16		var CSS_EXTENDED = 'lfr-extended';
17
18		var DEFAULT_ALIGN_POINTS = ['tl', 'bl'];
19
20		var EVENT_CLICK = 'click';
21
22		var STR_B = 'b';
23
24		var STR_L = 'l';
25
26		var STR_R = 'r';
27
28		var STR_T = 't';
29
30		var MAP_ALIGN_HORIZONTAL_OVERLAY = {
31			right: STR_L,
32			left: STR_R
33		};
34
35		var MAP_ALIGN_HORIZONTAL_TRIGGER = {
36			right: STR_R,
37			left: STR_L
38		};
39
40		var MAP_ALIGN_VERTICAL_OVERLAY = {
41			down: STR_T,
42			up: STR_B
43		};
44
45		var MAP_ALIGN_VERTICAL_TRIGGER = {
46			down: STR_B,
47			up: STR_T
48		};
49
50		var MAP_LIVE_SEARCH = {};
51
52		var REGEX_DIRECTION = /\bdirection-(down|left|right|up)\b/;
53
54		var REGEX_MAX_DISPLAY_ITEMS = /max-display-items-(\d+)/;
55
56		var SELECTOR_ANCHOR = 'a';
57
58		var SELECTOR_TEXT = 'a, span';
59
60		var SELECTOR_LIST_ITEM = 'li';
61
62		var SELECTOR_SEARCH_CONTAINER = '.lfr-menu-list-search-container';
63
64		var SELECTOR_SEARCH_INPUT = '.lfr-menu-list-search';
65
66		var STR_BLANK = '';
67
68		var TPL_MENU = '<div class="lfr-component lfr-menu-list" />';
69
70		var TPL_SEARCH_BOX = '<div class="lfr-menu-list-search-container">' +
71				'<input autocomplete="off" aria-autocomplete="list" aria-expanded="true" aria-labelledby="{searchLabeledBy}" aria-owns="{searchOwns}" class="lfr-menu-list-search" id="{searchId}" role="combobox">' +
72			'</div>';
73
74		var Menu = function() {
75			var instance = this;
76
77			instance._handles = [];
78
79			if (!Menu._INSTANCE) {
80				Menu._INSTANCE = instance;
81			}
82		};
83
84		Menu.prototype = {
85			_closeActiveMenu: function() {
86				var instance = this;
87
88				var menu = instance._activeMenu;
89
90				if (menu) {
91					var handles = instance._handles;
92
93					A.Array.invoke(handles, 'detach');
94
95					handles.length = 0;
96
97					instance._overlay.hide();
98
99					var trigger = instance._activeTrigger;
100
101					instance._activeMenu = null;
102					instance._activeTrigger = null;
103
104					if (trigger.hasClass(CSS_EXTENDED)) {
105						trigger.removeClass(CSS_STATE_ACTIVE);
106					}
107				}
108			},
109
110			_getAlignPoints: A.cached(
111				function(cssClass) {
112					var instance = this;
113
114					var alignPoints = DEFAULT_ALIGN_POINTS;
115
116					if (cssClass.indexOf(AUTO) == -1) {
117						var directionMatch = cssClass.match(REGEX_DIRECTION);
118
119						var direction = (directionMatch && directionMatch[1]) || AUTO;
120
121						var overlayHorizontal = MAP_ALIGN_HORIZONTAL_OVERLAY[direction] || STR_L;
122						var overlayVertical = MAP_ALIGN_VERTICAL_OVERLAY[direction] || STR_T;
123
124						var triggerHorizontal = MAP_ALIGN_HORIZONTAL_TRIGGER[direction] || STR_L;
125						var triggerVertical = MAP_ALIGN_VERTICAL_TRIGGER[direction] || STR_T;
126
127						alignPoints = [overlayVertical + overlayHorizontal, triggerVertical + triggerHorizontal];
128					}
129
130					return alignPoints;
131				}
132			),
133
134			_getMenu: function(trigger) {
135				var instance = this;
136
137				var overlay = instance._overlay;
138
139				if (!overlay) {
140					overlay = new A.OverlayBase(
141						{
142							align: {
143								node: trigger,
144								points: DEFAULT_ALIGN_POINTS
145							},
146							constrain: true,
147							cssClass: 'lfr-menu-list',
148							hideClass: false,
149							preventOverlap: true,
150							zIndex: Liferay.zIndex.MENU
151						}
152					).render();
153
154					var boundingBox = overlay.get('boundingBox');
155
156					boundingBox.addClass('lfr-component');
157
158					instance._overlay = overlay;
159				}
160				else {
161					overlay.set('align.node', trigger);
162				}
163
164				var listContainer = trigger.getData('menuListContainer');
165				var menu = trigger.getData('menu');
166				var menuHeight = trigger.getData('menuHeight');
167
168				var liveSearch = menu && MAP_LIVE_SEARCH[menu.guid()];
169
170				if (liveSearch) {
171					liveSearch.search(STR_BLANK);
172				}
173
174				var listItems;
175
176				if (!menu || !listContainer) {
177					listContainer = trigger.one('ul');
178
179					listItems = listContainer.all(SELECTOR_LIST_ITEM);
180
181					menu = A.Node.create(TPL_MENU);
182
183					listContainer.placeBefore(menu);
184
185					listItems.last().addClass('last');
186
187					menu.append(listContainer);
188
189					trigger.setData('menuListContainer', listContainer);
190					trigger.setData('menu', menu);
191
192					instance._setARIARoles(trigger, menu, listContainer);
193
194					Liferay.Util.createFlyouts(
195						{
196							container: listContainer.getDOM()
197						}
198					);
199				}
200
201				overlay.setStdModContent(A.WidgetStdMod.BODY, menu);
202
203				if (!menuHeight) {
204					menuHeight = instance._getMenuHeight(trigger, menu, listItems || listContainer.all(SELECTOR_LIST_ITEM));
205
206					trigger.setData('menuHeight', menuHeight);
207
208					listContainer.addClass('lfr-menu-list-overflow');
209
210					if (menuHeight != AUTO) {
211						listContainer.setStyle('maxHeight', menuHeight);
212					}
213				}
214
215				instance._getFocusManager();
216
217				return menu;
218			},
219
220			_getMenuHeight: function(trigger, menu, listItems) {
221				var instance = this;
222
223				var cssClass = trigger.attr(ATTR_CLASS_NAME);
224
225				var height = AUTO;
226
227				if (cssClass.indexOf('lfr-menu-expanded') == -1) {
228					var params = REGEX_MAX_DISPLAY_ITEMS.exec(cssClass);
229
230					var maxDisplayItems = params && parseInt(params[1], 10);
231
232					if (maxDisplayItems && listItems.size() > maxDisplayItems) {
233						instance._getLiveSearch(trigger, trigger.getData('menu'));
234
235						height = 0;
236
237						var heights = listItems.slice(0, maxDisplayItems).get('offsetHeight');
238
239						for (var i = heights.length - 1; i >= 0; i--) {
240							height += heights[i];
241						}
242					}
243				}
244
245				return height;
246			},
247
248			_positionActiveMenu: function() {
249				var instance = this;
250
251				var menu = instance._activeMenu;
252				var trigger = instance._activeTrigger;
253
254				if (menu) {
255					var cssClass = trigger.attr(ATTR_CLASS_NAME);
256
257					var overlay = instance._overlay;
258
259					var align = overlay.get('align');
260
261					align.points = instance._getAlignPoints(cssClass);
262
263					overlay.show();
264
265					overlay.set('align', align);
266
267					if (Liferay.Browser.isIe() && Liferay.Browser.getMajorVersion() <= 7) {
268						var searchContainer = menu.one(SELECTOR_SEARCH_CONTAINER);
269
270						if (searchContainer) {
271							searchContainer.width(menu.innerWidth());
272
273							menu.one(SELECTOR_SEARCH_INPUT).width('100%');
274						}
275					}
276
277					if (cssClass.indexOf(CSS_EXTENDED) > -1) {
278						trigger.addClass(CSS_STATE_ACTIVE);
279					}
280
281					var focusManager = overlay.bodyNode.focusManager;
282
283					if (focusManager) {
284						focusManager.focus(0);
285					}
286				}
287			},
288
289			_setARIARoles: function(trigger, menu, listContainer) {
290				var links = menu.all(SELECTOR_ANCHOR);
291
292				var searchContainer = menu.one(SELECTOR_SEARCH_CONTAINER);
293
294				var listNode = menu.one('ul');
295
296				var ariaListNodeAttr = 'menu';
297				var ariaLinksAttr = 'menuitem';
298
299				if (searchContainer) {
300					ariaListNodeAttr = 'listbox';
301					ariaListNodeAttr = 'option';
302				}
303
304				listNode.setAttribute(ARIA_ATTR_ROLE, ariaListNodeAttr);
305				links.set(ARIA_ATTR_ROLE, ariaLinksAttr);
306
307				var anchor = trigger.one(SELECTOR_ANCHOR);
308
309				if (anchor) {
310					anchor.attr(
311						{
312							'aria-haspopup': true,
313							role: 'button'
314						}
315					);
316
317					listNode.setAttribute('aria-labelledby', anchor.guid());
318				}
319			}
320		};
321
322		Menu.handleFocus = function(id) {
323			var node = A.one(id);
324
325			if (node) {
326				node.delegate('mouseenter', A.rbind(Menu._targetLink, node, 'focus'), SELECTOR_LIST_ITEM);
327				node.delegate('mouseleave', A.rbind(Menu._targetLink, node, 'blur'), SELECTOR_LIST_ITEM);
328			}
329		};
330
331		var buffer = [];
332
333		Menu.register = function(id) {
334			var menuNode = document.getElementById(id);
335
336			if (!Menu._INSTANCE) {
337				new Menu();
338			}
339
340			buffer.push(menuNode);
341
342			Menu._registerTask();
343		};
344
345		Menu._registerTask = A.debounce(
346			function() {
347				var instance = Menu._INSTANCE;
348
349				if (buffer.length) {
350					var nodes = A.all(buffer);
351
352					nodes.on(EVENT_CLICK, A.bind('_registerMenu', Menu));
353				}
354			},
355			100
356		);
357
358		Menu._targetLink = function(event, action) {
359			var anchor = event.currentTarget.one(SELECTOR_ANCHOR);
360
361			if (anchor) {
362				anchor[action]();
363			}
364		};
365
366		Liferay.provide(
367			Menu,
368			'_getFocusManager',
369			function() {
370				var instance = Menu._INSTANCE;
371
372				var focusManager = instance._focusManager;
373
374				if (!focusManager) {
375					var bodyNode = instance._overlay.bodyNode;
376
377					bodyNode.plug(
378						A.Plugin.NodeFocusManager,
379						{
380							circular: true,
381							descendants: 'li:not(.aui-helper-hidden) a,input',
382							focusClass: 'aui-focus',
383							keys: {
384								next: 'down:40',
385								previous: 'down:38'
386							}
387						}
388					);
389
390					bodyNode.on(
391						'key',
392						function(event) {
393							var activeTrigger = instance._activeTrigger;
394
395							if (activeTrigger) {
396								var anchor = activeTrigger.one(SELECTOR_ANCHOR);
397
398								instance._closeActiveMenu();
399
400								anchor.focus();
401							}
402						},
403						'down:27,9'
404					);
405
406					focusManager = bodyNode.focusManager;
407
408					bodyNode.delegate(
409						'mouseenter',
410						function (event) {
411							if (focusManager.get('focused')) {
412								focusManager.focus(event.currentTarget.one(SELECTOR_ANCHOR));
413							}
414						},
415						SELECTOR_LIST_ITEM
416					);
417
418					focusManager.after(
419						'activeDescendantChange',
420						function(event) {
421							var descendants = focusManager.get('descendants');
422
423							var selectedItem = descendants.item(event.newVal);
424
425							bodyNode.one('ul').setAttribute('aria-activedescendant', selectedItem.guid());
426						}
427					);
428
429					instance._focusManager = focusManager;
430				}
431
432				focusManager.refresh();
433			},
434			['node-focusmanager'],
435			true
436		);
437
438		Liferay.provide(
439			Menu,
440			'_getLiveSearch',
441			function(trigger, menu) {
442				var instance = Menu._INSTANCE;
443
444				var id = menu.guid();
445
446				var liveSearch = MAP_LIVE_SEARCH[id];
447
448				if (!liveSearch) {
449					var searchId = A.guid();
450
451					var listNode = menu.one('ul');
452
453					var searchLabelNode = trigger.one(SELECTOR_ANCHOR) || trigger;
454
455					var searchBoxContent = Lang.sub(
456						TPL_SEARCH_BOX,
457						{
458							searchId: searchId,
459							searchLabeledBy: searchLabelNode.guid(),
460							searchOwns: listNode.guid()
461						}
462					);
463
464					var inputSearch = A.Node.create(searchBoxContent);
465
466					inputSearch.swallowEvent('click');
467
468					menu.prepend(inputSearch);
469
470					var options = {
471						data: function(node) {
472							return trim(node.one(SELECTOR_TEXT).text());
473						},
474						input: '#' + searchId,
475						nodes: '#' + listNode.guid() + ' > li'
476					};
477
478					liveSearch = new A.LiveSearch(options);
479
480					var bodyNode = instance._overlay.bodyNode;
481
482					liveSearch.after(
483						'search',
484						function(event) {
485							var focusManager = bodyNode.focusManager;
486
487							if (focusManager) {
488								focusManager.refresh();
489							}
490						}
491					);
492
493					MAP_LIVE_SEARCH[id] = liveSearch;
494				}
495			},
496			['aui-live-search'],
497			true
498		);
499
500		Liferay.provide(
501			Menu,
502			'_registerMenu',
503			function(event) {
504				var instance = Menu._INSTANCE;
505
506				var handles = instance._handles;
507
508				var trigger = event.currentTarget;
509
510				var activeTrigger = instance._activeTrigger;
511
512				if (activeTrigger && (activeTrigger != trigger)) {
513					activeTrigger.removeClass(CSS_STATE_ACTIVE);
514				}
515
516				if (!trigger.hasClass('disabled')) {
517					var menu = instance._getMenu(trigger);
518
519					instance._activeMenu = menu;
520					instance._activeTrigger = trigger;
521
522					if (!handles.length) {
523						handles.push(
524							A.getWin().on('resize', A.debounce(instance._positionActiveMenu, 200, instance)),
525							A.getDoc().on(EVENT_CLICK, instance._closeActiveMenu, instance)
526						);
527
528						var DDM = A.DD && A.DD.DDM;
529
530						if (DDM) {
531							handles.push(DDM.on('ddm:start', instance._closeActiveMenu, instance));
532						}
533					}
534
535					instance._positionActiveMenu();
536
537					event.halt();
538				}
539			},
540			['aui-overlay']
541		);
542
543		Liferay.Menu = Menu;
544	},
545	'',
546	{
547		requires: ['aui-debounce', 'aui-node']
548	}
549);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.