[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 YUI.add('moodle-editor_atto-menu', function (Y, NAME) { 2 3 // This file is part of Moodle - http://moodle.org/ 4 // 5 // Moodle is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // Moodle is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 17 18 /** 19 * A Menu for the Atto editor. 20 * 21 * @module moodle-editor_atto-menu 22 * @submodule menu-base 23 * @package editor_atto 24 * @copyright 2013 Damyon Wiese 25 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 26 */ 27 28 var LOGNAME = 'moodle-editor_atto-menu'; 29 var MENUDIALOGUE = '' + 30 '<div class="open {{config.buttonClass}} atto_menu" ' + 31 'style="min-width:{{config.innerOverlayWidth}};">' + 32 '<ul class="dropdown-menu">' + 33 '{{#each config.items}}' + 34 '<li role="presentation" class="atto_menuentry">' + 35 '<a href="#" role="menuitem" data-index="{{@index}}" {{#each data}}data-{{@key}}="{{this}}"{{/each}}>' + 36 '{{{text}}}' + 37 '</a>' + 38 '</li>' + 39 '{{/each}}' + 40 '</ul>' + 41 '</div>'; 42 43 /** 44 * A Menu for the Atto editor used in Moodle. 45 * 46 * This is a drop down list of buttons triggered (and aligned to) a 47 * location. 48 * 49 * @namespace M.editor_atto 50 * @class Menu 51 * @main 52 * @constructor 53 * @extends M.core.dialogue 54 */ 55 var Menu = function() { 56 Menu.superclass.constructor.apply(this, arguments); 57 }; 58 59 Y.extend(Menu, M.core.dialogue, { 60 61 /** 62 * A list of the menu handlers which have been attached here. 63 * 64 * @property _menuHandlers 65 * @type Array 66 * @private 67 */ 68 _menuHandlers: null, 69 70 initializer: function(config) { 71 var headertext, 72 bb; 73 74 this._menuHandlers = []; 75 76 // Create the actual button. 77 var template = Y.Handlebars.compile(MENUDIALOGUE), 78 menu = Y.Node.create(template({ 79 config: config 80 })); 81 this.set('bodyContent', menu); 82 83 bb = this.get('boundingBox'); 84 bb.addClass('editor_atto_controlmenu'); 85 bb.addClass('editor_atto_menu'); 86 bb.one('.moodle-dialogue-wrap') 87 .removeClass('moodle-dialogue-wrap') 88 .addClass('moodle-dialogue-content'); 89 90 headertext = Y.Node.create('<h3/>') 91 .addClass('accesshide') 92 .setHTML(this.get('headerText')); 93 this.get('bodyContent').prepend(headertext); 94 95 // Hide the header and footer node entirely. 96 this.headerNode.hide(); 97 this.footerNode.hide(); 98 99 this._setupHandlers(); 100 }, 101 102 /** 103 * Setup the Event handlers. 104 * 105 * @method _setupHandlers 106 * @private 107 */ 108 _setupHandlers: function() { 109 var contentBox = this.get('contentBox'); 110 // Handle menu item selection. 111 this._menuHandlers.push( 112 // Select the menu item on space, and enter. 113 contentBox.delegate('key', this._chooseMenuItem, '32, enter', '.atto_menuentry', this), 114 115 // Move up and down the menu on up/down. 116 contentBox.delegate('key', this._handleKeyboardEvent, 'down:38,40', '.dropdown-menu', this), 117 118 // Hide the menu when clicking outside of it. 119 contentBox.on('focusoutside', this.hide, this), 120 121 // Hide the menu on left/right, and escape keys. 122 contentBox.delegate('key', this.hide, 'down:37,39,esc', '.dropdown-menu', this) 123 ); 124 }, 125 126 /** 127 * Simulate other types of menu selection. 128 * 129 * @method _chooseMenuItem 130 * @param {EventFacade} e 131 */ 132 _chooseMenuItem: function(e) { 133 e.target.simulate('click'); 134 e.preventDefault(); 135 }, 136 137 /** 138 * Hide a menu, removing all of the event handlers which trigger the hide. 139 * 140 * @method hide 141 * @param {EventFacade} e 142 */ 143 hide: function(e) { 144 if (this.get('preventHideMenu') === true) { 145 return; 146 } 147 148 // We must prevent the default action (left/right/escape) because 149 // there are other listeners on the toolbar which will focus on the 150 // editor. 151 if (e) { 152 e.preventDefault(); 153 } 154 155 return Menu.superclass.hide.call(this, arguments); 156 }, 157 158 /** 159 * Implement arrow-key navigation for the items in a toolbar menu. 160 * 161 * @method _handleKeyboardEvent 162 * @param {EventFacade} e The keyboard event. 163 * @static 164 */ 165 _handleKeyboardEvent: function(e) { 166 // Prevent the default browser behaviour. 167 e.preventDefault(); 168 169 // Get a list of all buttons in the menu. 170 var buttons = e.currentTarget.all('a[role="menuitem"]'); 171 172 // On cursor moves we loops through the buttons. 173 var found = false, 174 index = 0, 175 direction = 1, 176 checkCount = 0, 177 current = e.target.ancestor('a[role="menuitem"]', true), 178 next; 179 180 // Determine which button is currently selected. 181 while (!found && index < buttons.size()) { 182 if (buttons.item(index) === current) { 183 found = true; 184 } else { 185 index++; 186 } 187 } 188 189 if (!found) { 190 return; 191 } 192 193 if (e.keyCode === 38) { 194 // Moving up so reverse the direction. 195 direction = -1; 196 } 197 198 // Try to find the next 199 do { 200 index += direction; 201 if (index < 0) { 202 index = buttons.size() - 1; 203 } else if (index >= buttons.size()) { 204 // Handle wrapping. 205 index = 0; 206 } 207 next = buttons.item(index); 208 209 // Add a counter to ensure we don't get stuck in a loop if there's only one visible menu item. 210 checkCount++; 211 // Loop while: 212 // * we are not in a loop and have not already checked every button; and 213 // * we are on a different button; and 214 // * the next menu item is not hidden. 215 } while (checkCount < buttons.size() && next !== current && next.hasAttribute('hidden')); 216 217 if (next) { 218 next.focus(); 219 } 220 221 e.preventDefault(); 222 e.stopImmediatePropagation(); 223 } 224 }, { 225 NAME: "menu", 226 ATTRS: { 227 /** 228 * The header for the drop down (only accessible to screen readers). 229 * 230 * @attribute headerText 231 * @type String 232 * @default '' 233 */ 234 headerText: { 235 value: '' 236 } 237 238 } 239 }); 240 241 Y.Base.modifyAttrs(Menu, { 242 /** 243 * The width for this menu. 244 * 245 * @attribute width 246 * @default 'auto' 247 */ 248 width: { 249 value: 'auto' 250 }, 251 252 /** 253 * When to hide this menu. 254 * 255 * By default, this attribute consists of: 256 * <ul> 257 * <li>an object which will cause the menu to hide when the user clicks outside of the menu</li> 258 * </ul> 259 * 260 * @attribute hideOn 261 */ 262 hideOn: { 263 value: [ 264 { 265 eventName: 'clickoutside' 266 } 267 ] 268 }, 269 270 /** 271 * The default list of extra classes for this menu. 272 * 273 * @attribute extraClasses 274 * @type Array 275 * @default editor_atto_menu 276 */ 277 extraClasses: { 278 value: [ 279 'editor_atto_menu' 280 ] 281 }, 282 283 /** 284 * Override the responsive nature of the core dialogues. 285 * 286 * @attribute responsive 287 * @type boolean 288 * @default false 289 */ 290 responsive: { 291 value: false 292 }, 293 294 /** 295 * The default visibility of the menu. 296 * 297 * @attribute visible 298 * @type boolean 299 * @default false 300 */ 301 visible: { 302 value: false 303 }, 304 305 /** 306 * Whether to centre the menu. 307 * 308 * @attribute center 309 * @type boolean 310 * @default false 311 */ 312 center: { 313 value: false 314 }, 315 316 /** 317 * Hide the close button. 318 * @attribute closeButton 319 * @type boolean 320 * @default false 321 */ 322 closeButton: { 323 value: false 324 } 325 }); 326 327 Y.namespace('M.editor_atto').Menu = Menu; 328 329 330 }, '@VERSION@', {"requires": ["moodle-core-notification-dialogue", "node", "event", "event-custom"]});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |