[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/editor/atto/yui/build/moodle-editor_atto-menu/ -> moodle-editor_atto-menu.js (source)

   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"]});


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1