[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 /** 2 * @provides phuix-dropdown-menu 3 * @requires javelin-install 4 * javelin-util 5 * javelin-dom 6 * javelin-vector 7 * javelin-stratcom 8 * @javelin 9 */ 10 11 12 /** 13 * Basic interaction for a dropdown menu. 14 * 15 * The menu is unaware of the content inside it, so it can not close itself 16 * when an item is selected. Callers must make a call to @{method:close} after 17 * an item is chosen in order to close the menu. 18 */ 19 JX.install('PHUIXDropdownMenu', { 20 21 construct : function(node) { 22 this._node = node; 23 24 JX.DOM.listen( 25 this._node, 26 'click', 27 null, 28 JX.bind(this, this._onclick)); 29 30 JX.Stratcom.listen( 31 'mousedown', 32 null, 33 JX.bind(this, this._onanyclick)); 34 35 JX.Stratcom.listen( 36 'resize', 37 null, 38 JX.bind(this, this._adjustposition)); 39 40 JX.Stratcom.listen('phuix.dropdown.open', null, JX.bind(this, this.close)); 41 42 JX.Stratcom.listen('keydown', null, JX.bind(this, this._onkey)); 43 }, 44 45 events: ['open'], 46 47 properties: { 48 width: null, 49 align: 'right', 50 offsetX: 0, 51 offsetY: 0 52 }, 53 54 members: { 55 _node: null, 56 _menu: null, 57 _open: false, 58 _content: null, 59 60 setContent: function(content) { 61 JX.DOM.setContent(this._getMenuNode(), content); 62 return this; 63 }, 64 65 open: function() { 66 if (this._open) { 67 return; 68 } 69 70 this.invoke('open'); 71 JX.Stratcom.invoke('phuix.dropdown.open'); 72 73 this._open = true; 74 this._show(); 75 76 return this; 77 }, 78 79 close: function() { 80 if (!this._open) { 81 return; 82 } 83 this._open = false; 84 this._hide(); 85 86 return this; 87 }, 88 89 _getMenuNode: function() { 90 if (!this._menu) { 91 var attrs = { 92 className: 'phuix-dropdown-menu', 93 role: 'button' 94 }; 95 96 var menu = JX.$N('div', attrs); 97 98 this._menu = menu; 99 } 100 101 return this._menu; 102 }, 103 104 _onclick : function(e) { 105 if (this._open) { 106 this.close(); 107 } else { 108 this.open(); 109 } 110 e.prevent(); 111 }, 112 113 _onanyclick : function(e) { 114 if (!this._open) { 115 return; 116 } 117 118 if (JX.Stratcom.pass(e)) { 119 return; 120 } 121 122 var t = e.getTarget(); 123 while (t) { 124 if (t == this._menu || t == this._node) { 125 return; 126 } 127 t = t.parentNode; 128 } 129 130 this.close(); 131 }, 132 133 _show : function() { 134 document.body.appendChild(this._menu); 135 136 if (this.getWidth()) { 137 new JX.Vector(this.getWidth(), null).setDim(this._menu); 138 } 139 140 this._adjustposition(); 141 142 JX.DOM.alterClass(this._node, 'phuix-dropdown-open', true); 143 144 this._node.setAttribute('aria-expanded', 'true'); 145 146 // Try to highlight the first link in the menu for assistive technologies. 147 var links = JX.DOM.scry(this._menu, 'a'); 148 if (links[0]) { 149 JX.DOM.focus(links[0]); 150 } 151 }, 152 153 _hide : function() { 154 JX.DOM.remove(this._menu); 155 156 JX.DOM.alterClass(this._node, 'phuix-dropdown-open', false); 157 158 this._node.setAttribute('aria-expanded', 'false'); 159 }, 160 161 _adjustposition : function() { 162 if (!this._open) { 163 return; 164 } 165 166 var m = JX.Vector.getDim(this._menu); 167 168 var v = JX.$V(this._node); 169 var d = JX.Vector.getDim(this._node); 170 171 switch (this.getAlign()) { 172 case 'right': 173 v = v.add(d) 174 .add(JX.$V(-m.x, 0)); 175 break; 176 default: 177 v = v.add(0, d.y); 178 break; 179 } 180 181 v = v.add(this.getOffsetX(), this.getOffsetY()); 182 183 v.setPos(this._menu); 184 }, 185 186 _onkey: function(e) { 187 // When the user presses escape with a menu open, close the menu and 188 // refocus the button which activates the menu. In particular, this makes 189 // popups more usable with assistive technologies. 190 191 if (!this._open) { 192 return; 193 } 194 195 if (e.getSpecialKey() != 'esc') { 196 return; 197 } 198 199 this.close(); 200 JX.DOM.focus(this._node); 201 202 e.prevent(); 203 } 204 205 } 206 });
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |