src/pyams_skin/resources/js/ext/tinymce/dev/classes/ui/MenuButton.js
changeset 566 a1707c607eec
parent 565 318533413200
child 567 bca1726b1d85
equal deleted inserted replaced
565:318533413200 566:a1707c607eec
     1 /**
       
     2  * MenuButton.js
       
     3  *
       
     4  * Copyright, Moxiecode Systems AB
       
     5  * Released under LGPL License.
       
     6  *
       
     7  * License: http://www.tinymce.com/license
       
     8  * Contributing: http://www.tinymce.com/contributing
       
     9  */
       
    10 
       
    11 /**
       
    12  * Creates a new menu button.
       
    13  *
       
    14  * @-x-less MenuButton.less
       
    15  * @class tinymce.ui.MenuButton
       
    16  * @extends tinymce.ui.Button
       
    17  */
       
    18 define("tinymce/ui/MenuButton", [
       
    19 	"tinymce/ui/Button",
       
    20 	"tinymce/ui/Factory",
       
    21 	"tinymce/ui/MenuBar"
       
    22 ], function(Button, Factory, MenuBar) {
       
    23 	"use strict";
       
    24 
       
    25 	// TODO: Maybe add as some global function
       
    26 	function isChildOf(node, parent) {
       
    27 		while (node) {
       
    28 			if (parent === node) {
       
    29 				return true;
       
    30 			}
       
    31 
       
    32 			node = node.parentNode;
       
    33 		}
       
    34 
       
    35 		return false;
       
    36 	}
       
    37 
       
    38 	var MenuButton = Button.extend({
       
    39 		/**
       
    40 		 * Constructs a instance with the specified settings.
       
    41 		 *
       
    42 		 * @constructor
       
    43 		 * @param {Object} settings Name/value object with settings.
       
    44 		 */
       
    45 		init: function(settings) {
       
    46 			var self = this;
       
    47 
       
    48 			self._renderOpen = true;
       
    49 			self._super(settings);
       
    50 
       
    51 			self.addClass('menubtn');
       
    52 
       
    53 			if (settings.fixedWidth) {
       
    54 				self.addClass('fixed-width');
       
    55 			}
       
    56 
       
    57 			self.aria('haspopup', true);
       
    58 			self.hasPopup = true;
       
    59 		},
       
    60 
       
    61 		/**
       
    62 		 * Shows the menu for the button.
       
    63 		 *
       
    64 		 * @method showMenu
       
    65 		 */
       
    66 		showMenu: function() {
       
    67 			var self = this, settings = self.settings, menu;
       
    68 
       
    69 			if (self.menu && self.menu.visible()) {
       
    70 				return self.hideMenu();
       
    71 			}
       
    72 
       
    73 			if (!self.menu) {
       
    74 				menu = settings.menu || [];
       
    75 
       
    76 				// Is menu array then auto constuct menu control
       
    77 				if (menu.length) {
       
    78 					menu = {
       
    79 						type: 'menu',
       
    80 						items: menu
       
    81 					};
       
    82 				} else {
       
    83 					menu.type = menu.type || 'menu';
       
    84 				}
       
    85 
       
    86 				self.menu = Factory.create(menu).parent(self).renderTo();
       
    87 				self.fire('createmenu');
       
    88 				self.menu.reflow();
       
    89 				self.menu.on('cancel', function(e) {
       
    90 					if (e.control.parent() === self.menu) {
       
    91 						e.stopPropagation();
       
    92 						self.focus();
       
    93 						self.hideMenu();
       
    94 					}
       
    95 				});
       
    96 
       
    97 				// Move focus to button when a menu item is selected/clicked
       
    98 				self.menu.on('select', function() {
       
    99 					self.focus();
       
   100 				});
       
   101 
       
   102 				self.menu.on('show hide', function(e) {
       
   103 					if (e.control == self.menu) {
       
   104 						self.activeMenu(e.type == 'show');
       
   105 					}
       
   106 
       
   107 					self.aria('expanded', e.type == 'show');
       
   108 				}).fire('show');
       
   109 			}
       
   110 
       
   111 			self.menu.show();
       
   112 			self.menu.layoutRect({w: self.layoutRect().w});
       
   113 			self.menu.moveRel(self.getEl(), self.isRtl() ? ['br-tr', 'tr-br'] : ['bl-tl', 'tl-bl']);
       
   114 		},
       
   115 
       
   116 		/**
       
   117 		 * Hides the menu for the button.
       
   118 		 *
       
   119 		 * @method hideMenu
       
   120 		 */
       
   121 		hideMenu: function() {
       
   122 			var self = this;
       
   123 
       
   124 			if (self.menu) {
       
   125 				self.menu.items().each(function(item) {
       
   126 					if (item.hideMenu) {
       
   127 						item.hideMenu();
       
   128 					}
       
   129 				});
       
   130 
       
   131 				self.menu.hide();
       
   132 			}
       
   133 		},
       
   134 
       
   135 		/**
       
   136 		 * Sets the active menu state.
       
   137 		 *
       
   138 		 * @private
       
   139 		 */
       
   140 		activeMenu: function(state) {
       
   141 			this.toggleClass('active', state);
       
   142 		},
       
   143 
       
   144 		/**
       
   145 		 * Renders the control as a HTML string.
       
   146 		 *
       
   147 		 * @method renderHtml
       
   148 		 * @return {String} HTML representing the control.
       
   149 		 */
       
   150 		renderHtml: function() {
       
   151 			var self = this, id = self._id, prefix = self.classPrefix;
       
   152 			var icon = self.settings.icon, image;
       
   153 
       
   154 			image = self.settings.image;
       
   155 			if (image) {
       
   156 				icon = 'none';
       
   157 
       
   158 				// Support for [high dpi, low dpi] image sources
       
   159 				if (typeof image != "string") {
       
   160 					image = window.getSelection ? image[0] : image[1];
       
   161 				}
       
   162 
       
   163 				image = ' style="background-image: url(\'' + image + '\')"';
       
   164 			} else {
       
   165 				image = '';
       
   166 			}
       
   167 
       
   168 			icon = self.settings.icon ? prefix + 'ico ' + prefix + 'i-' + icon : '';
       
   169 
       
   170 			self.aria('role', self.parent() instanceof MenuBar ? 'menuitem' : 'button');
       
   171 
       
   172 			return (
       
   173 				'<div id="' + id + '" class="' + self.classes() + '" tabindex="-1" aria-labelledby="' + id + '">' +
       
   174 					'<button id="' + id + '-open" role="presentation" type="button" tabindex="-1">' +
       
   175 						(icon ? '<i class="' + icon + '"' + image + '></i>' : '') +
       
   176 						'<span>' + (self._text ? (icon ? '\u00a0' : '') + self.encode(self._text) : '') + '</span>' +
       
   177 						' <i class="' + prefix + 'caret"></i>' +
       
   178 					'</button>' +
       
   179 				'</div>'
       
   180 			);
       
   181 		},
       
   182 
       
   183 		/**
       
   184 		 * Gets invoked after the control has been rendered.
       
   185 		 *
       
   186 		 * @method postRender
       
   187 		 */
       
   188 		postRender: function() {
       
   189 			var self = this;
       
   190 
       
   191 			self.on('click', function(e) {
       
   192 				if (e.control === self && isChildOf(e.target, self.getEl())) {
       
   193 					self.showMenu();
       
   194 
       
   195 					if (e.aria) {
       
   196 						self.menu.items()[0].focus();
       
   197 					}
       
   198 				}
       
   199 			});
       
   200 
       
   201 			self.on('mouseenter', function(e) {
       
   202 				var overCtrl = e.control, parent = self.parent(), hasVisibleSiblingMenu;
       
   203 
       
   204 				if (overCtrl && parent && overCtrl instanceof MenuButton && overCtrl.parent() == parent) {
       
   205 					parent.items().filter('MenuButton').each(function(ctrl) {
       
   206 						if (ctrl.hideMenu && ctrl != overCtrl) {
       
   207 							if (ctrl.menu && ctrl.menu.visible()) {
       
   208 								hasVisibleSiblingMenu = true;
       
   209 							}
       
   210 
       
   211 							ctrl.hideMenu();
       
   212 						}
       
   213 					});
       
   214 
       
   215 					if (hasVisibleSiblingMenu) {
       
   216 						overCtrl.focus(); // Fix for: #5887
       
   217 						overCtrl.showMenu();
       
   218 					}
       
   219 				}
       
   220 			});
       
   221 
       
   222 			return self._super();
       
   223 		},
       
   224 
       
   225 		/**
       
   226 		 * Sets/gets the current button text.
       
   227 		 *
       
   228 		 * @method text
       
   229 		 * @param {String} [text] New button text.
       
   230 		 * @return {String|tinymce.ui.MenuButton} Current text or current MenuButton instance.
       
   231 		 */
       
   232 		text: function(text) {
       
   233 			var self = this, i, children;
       
   234 
       
   235 			if (self._rendered) {
       
   236 				children = self.getEl('open').getElementsByTagName('span');
       
   237 				for (i = 0; i < children.length; i++) {
       
   238 					children[i].innerHTML = (self.settings.icon && text ? '\u00a0' : '') + self.encode(text);
       
   239 				}
       
   240 			}
       
   241 
       
   242 			return this._super(text);
       
   243 		},
       
   244 
       
   245 		/**
       
   246 		 * Removes the control and it's menus.
       
   247 		 *
       
   248 		 * @method remove
       
   249 		 */
       
   250 		remove: function() {
       
   251 			this._super();
       
   252 
       
   253 			if (this.menu) {
       
   254 				this.menu.remove();
       
   255 			}
       
   256 		}
       
   257 	});
       
   258 
       
   259 	return MenuButton;
       
   260 });