PageSourceSearch

https://wp.ufpel.edu.br/acessoainformacao/wp-content/themes/UFPel2…/PopupMenuItemLinks.js?ver=1686149137

js ufpel.edu.br collected 2026-09-24 08:32:55 UTC 5,890 bytes, 236 lines download raw bytes

1/*
2*   This content is licensed according to the W3C Software License at
3*   https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
4*
5*   File:   MenuItem.js
6*
7*   Desc:   Popup Menu Menuitem widget that implements ARIA Authoring Practices
8*
9*   Author: Jon Gunderson, Ku Ja Eun and Nicholas Hoyt
10*/
11
12/*
13*   @constructor MenuItem
14*
15*   @desc
16*       Wrapper object for a simple menu item in a popup menu
17*
18*   @param domNode
19*       The DOM element node that serves as the menu item container.
20*       The menuObj PopupMenu is responsible for checking that it has
21*       requisite metadata, e.g. role="menuitem".
22*
23*   @param menuObj
24*       The object that is a wrapper for the PopupMenu DOM element that
25*       contains the menu item DOM element. See PopupMenu.js
26*/
27var MenuItem = function (domNode, menuObj) {
28
29  if (typeof popupObj !== 'object') {
30    popupObj = false;
31  }
32
33  this.domNode = domNode;
34  this.menu = menuObj;
35  this.popupMenu = false;
36  this.isMenubarItem = false;
37
38  this.keyCode = Object.freeze({
39    'TAB': 9,
40    'RETURN': 13,
41    'ESC': 27,
42    'SPACE': 32,
43    'PAGEUP': 33,
44    'PAGEDOWN': 34,
45    'END': 35,
46    'HOME': 36,
47    'LEFT': 37,
48    'UP': 38,
49    'RIGHT': 39,
50    'DOWN': 40
51  });
52};
53
54MenuItem.prototype.init = function () {
55  this.domNode.tabIndex = -1;
56
57  if (!this.domNode.getAttribute('role')) {
58    this.domNode.setAttribute('role', 'menuitem');
59  }
60
61  if (this.domNode.parentNode.tagName === 'LI') {
62    this.domNode.parentNode.setAttribute('role', 'none');
63  }
64
65  this.domNode.addEventListener('keydown', this.handleKeydown.bind(this));
66//  this.domNode.addEventListener('click', this.handleClick.bind(this));
67  this.domNode.addEventListener('focus', this.handleFocus.bind(this));
68  this.domNode.addEventListener('blur', this.handleBlur.bind(this));
69  this.domNode.addEventListener('mouseover', this.handleMouseover.bind(this));
70  this.domNode.addEventListener('mouseout', this.handleMouseout.bind(this));
71
72  // Initialize flyout menu
73
74  var nextElement = this.domNode.nextElementSibling;
75
76  if (nextElement && nextElement.tagName === 'UL') {
77    console.log('popup sub-menu');
78    this.popupMenu = new PopupMenu(nextElement, this.menu, this);
79    this.popupMenu.init();
80  }
81
82};
83
84MenuItem.prototype.isExpanded = function () {
85  return this.domNode.getAttribute('aria-expanded') === 'true';
86};
87
88/* EVENT HANDLERS */
89
90MenuItem.prototype.handleKeydown = function (event) {
91  var tgt  = event.currentTarget,
92      char = event.key,
93      flag = false,
94      clickEvent;
95
96  function isPrintableCharacter (str) {
97    return str.length === 1 && str.match(/\S/);
98  }
99
100  switch (event.keyCode) {
101    case this.keyCode.RETURN:
102      if (this.domNode.getAttribute('href') != '#') {
103        return
104      }
105    case this.keyCode.SPACE:
106      if (this.popupMenu) {
107        this.popupMenu.open();
108        this.popupMenu.setFocusToFirstItem();
109      }
110      else {
111
112        // Create simulated mouse event to mimic the behavior of ATs
113        // and let the event handler handleClick do the housekeeping.
114        try {
115          clickEvent = new MouseEvent('click', {
116            'view': window,
117            'bubbles': true,
118            'cancelable': true
119          });
120        }
121        catch (err) {
122          if (document.createEvent) {
123            // DOM Level 3 for IE 9+
124            clickEvent = document.createEvent('MouseEvents');
125            clickEvent.initEvent('click', true, true);
126          }
127        }
128        tgt.dispatchEvent(clickEvent);
129      }
130
131      flag = true;
132      break;
133
134    case this.keyCode.ESC:
135      this.menu.setFocusToController();
136      this.menu.close(true);
137      flag = true;
138      break;
139
140    case this.keyCode.UP:
141      this.menu.setFocusToPreviousItem(this);
142      flag = true;
143      break;
144
145    case this.keyCode.DOWN:
146      this.menu.setFocusToNextItem(this);
147      flag = true;
148      break;
149
150    case this.keyCode.LEFT:
151      this.menu.setFocusToController('previous', true);
152      this.menu.close(true);
153      flag = true;
154      break;
155
156    case this.keyCode.RIGHT:
157      if (this.popupMenu) {
158        this.popupMenu.open();
159        this.popupMenu.setFocusToFirstItem();
160      }
161      else {
162        this.menu.setFocusToController('next', true);
163        this.menu.close(true);
164      }
165      flag = true;
166      break;
167
168    case this.keyCode.HOME:
169    case this.keyCode.PAGEUP:
170      this.menu.setFocusToFirstItem();
171      flag = true;
172      break;
173
174    case this.keyCode.END:
175    case this.keyCode.PAGEDOWN:
176      this.menu.setFocusToLastItem();
177      flag = true;
178      break;
179
180    case this.keyCode.TAB:
181      this.menu.setFocusToController();
182      this.menu.close(true);
183      break;
184
185    default:
186      if (isPrintableCharacter(char)) {
187        this.menu.setFocusByFirstCharacter(this, char);
188        flag = true;
189      }
190      break;
191  }
192
193  if (flag) {
194    event.stopPropagation();
195    event.preventDefault();
196  }
197};
198
199MenuItem.prototype.handleClick = function (event) {
200  this.menu.setFocusToController();
201  this.menu.close(true);
202};
203
204MenuItem.prototype.handleFocus = function (event) {
205  this.menu.hasFocus = true;
206  if (!this.menu.controller.isMenubarItem) {
207    this.menu.controller.hasFocus = true;
208  }
209};
210
211MenuItem.prototype.handleBlur = function (event) {
212  this.menu.hasFocus = false;
213  if (!this.menu.controller.isMenubarItem) {
214    this.menu.controller.hasFocus = false;
215  }
216  setTimeout(this.menu.close.bind(this.menu, false), 300);
217};
218
219MenuItem.prototype.handleMouseover = function (event) {
220  this.menu.hasHover = true;
221  this.menu.open();
222  if (this.popupMenu) {
223    this.popupMenu.hasHover = true;
224    this.popupMenu.open();
225  }
226};
227
228MenuItem.prototype.handleMouseout = function (event) {
229  if (this.popupMenu) {
230    this.popupMenu.hasHover = false;
231    this.popupMenu.close(true);
232  }
233
234  this.menu.hasHover = false;
235  setTimeout(this.menu.close.bind(this.menu, false), 300);
236};

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.