1 /* 2 * ***** BEGIN LICENSE BLOCK ***** 3 * Zimbra Collaboration Suite Web Client 4 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc. 5 * 6 * The contents of this file are subject to the Common Public Attribution License Version 1.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at: https://www.zimbra.com/license 9 * The License is based on the Mozilla Public License Version 1.1 but Sections 14 and 15 10 * have been added to cover use of software over a computer network and provide for limited attribution 11 * for the Original Developer. In addition, Exhibit A has been modified to be consistent with Exhibit B. 12 * 13 * Software distributed under the License is distributed on an "AS IS" basis, 14 * WITHOUT WARRANTY OF ANY KIND, either express or implied. 15 * See the License for the specific language governing rights and limitations under the License. 16 * The Original Code is Zimbra Open Source Web Client. 17 * The Initial Developer of the Original Code is Zimbra, Inc. All rights to the Original Code were 18 * transferred by Zimbra, Inc. to Synacor, Inc. on September 14, 2015. 19 * 20 * All portions of the code are Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013, 2014, 2015, 2016 Synacor, Inc. All Rights Reserved. 21 * ***** END LICENSE BLOCK ***** 22 */ 23 24 /** 25 * @overview 26 * This file defines a label. 27 * 28 */ 29 30 /** 31 * Creates a label. 32 * @constructor 33 * @class 34 * This class represents a label, which consists of an image and/or text. It is used 35 * both as a concrete class and as the base class for {@link DwtButton}. The label 36 * components are managed within a table. The label can be enabled or disabled, which are reflected in 37 * its display. A disabled label looks greyed out. 38 * 39 * <h4>CSS</h4> 40 * <ul> 41 * <li><code>.className table</code> - the label table</li> 42 * <li><code>.className .Icon</code> - class name for the icon image cell</li> 43 * <li><code>.className .Text</code> - enabled text cell</li> 44 * <li><code>.className .DisabledText</code> - disabled text cell</li> 45 * </ul> 46 * 47 * <h4>Keyboard Actions</h4> 48 * None 49 * 50 * <h4>Events</h4> 51 * None 52 * 53 * @author Ross Dargahi 54 * 55 * @param {hash} params the hash of parameters 56 * @param {DwtComposite} params.parent the parent widget 57 * @param {constant} params.style the label style: May be one of: {@link DwtLabel.IMAGE_LEFT} 58 * or {@link DwtLabel.IMAGE_RIGHT} arithmetically or'd (|) with one of: 59 * {@link DwtLabel.ALIGN_LEFT}, {@link DwtLabel.ALIGN_CENTER}, or {@link DwtLabel.ALIGN_LEFT} 60 * The first determines were in the label the icon will appear (if one is set), the second 61 * determine how the content of the label will be aligned. The default value for 62 * this parameter is: {@link DwtLabel.IMAGE_LEFT} | {@link DwtLabel.ALIGN_CENTER} 63 * @param {string} params.className the CSS class 64 * @param {constant} params.posStyle the positioning style (see {@link DwtControl}) 65 * @param {string} params.id the to use for the control HTML element 66 * @param {number} params.index the index at which to add this control among parent's children 67 * 68 * @extends DwtComposite 69 */ 70 DwtLabel = function(params) { 71 if (arguments.length == 0) { return; } 72 params = Dwt.getParams(arguments, DwtLabel.PARAMS); 73 74 params.className = params.className || "DwtLabel"; 75 DwtComposite.call(this, params); 76 77 /** 78 * The label style. See the constructor for more info. 79 */ 80 this._style = params.style || (DwtLabel.IMAGE_LEFT | DwtLabel.ALIGN_CENTER); 81 82 /** 83 * The label text background color. 84 */ 85 this._textBackground = null; 86 87 /** 88 * The label text foreground color. 89 */ 90 this._textForeground = null; 91 92 this._createHtml(params.template); 93 //MOW: this.setCursor("default"); 94 } 95 96 DwtLabel.PARAMS = ["parent", "style", "className", "posStyle", "id", "index"]; 97 98 DwtLabel.prototype = new DwtComposite; 99 DwtLabel.prototype.constructor = DwtLabel; 100 101 DwtLabel.prototype.isFocusable = true; 102 103 /** 104 * Returns a string representation of the object. 105 * 106 * @return {string} a string representation of the object 107 */ 108 DwtLabel.prototype.toString = 109 function() { 110 return "DwtLabel"; 111 } 112 113 // 114 // Constants 115 // 116 117 // display styles 118 /** 119 * Defines the "left" align image (i.e. align to the left of text, if both present). 120 */ 121 DwtLabel.IMAGE_LEFT = 1; 122 123 /** 124 * Defines the "right" align image (i.e. align to the right of text, if both present). 125 */ 126 DwtLabel.IMAGE_RIGHT = 2; 127 128 /** 129 * Defines both "right" and "left" align images (i.e. align to the left and to the right of text, if all present). 130 */ 131 DwtLabel.IMAGE_BOTH = 4; 132 133 /** 134 * Defines the "left" align label. 135 */ 136 DwtLabel.ALIGN_LEFT = 8; 137 138 /** 139 * Defines the "right" align label. 140 */ 141 DwtLabel.ALIGN_RIGHT = 16; 142 143 /** 144 * Defines the "center" align label. 145 */ 146 DwtLabel.ALIGN_CENTER = 32; 147 148 /** 149 * Defines the last style label (used for subclasses). 150 * @private 151 */ 152 DwtLabel._LAST_STYLE = 32; 153 154 /** 155 * Defines the "left" side icon 156 */ 157 DwtLabel.LEFT = "left"; 158 159 /** 160 * Defines the "right" side icon 161 */ 162 DwtLabel.RIGHT = "right"; 163 164 // 165 // Data 166 // 167 168 DwtLabel.prototype.TEMPLATE = "dwt.Widgets#ZLabel"; 169 170 // 171 // Public methods 172 // 173 174 /** 175 * Disposes of the label. 176 * 177 */ 178 DwtLabel.prototype.dispose = 179 function() { 180 delete this._dropDownEl; 181 delete this._iconEl; 182 delete this._textEl; 183 DwtControl.prototype.dispose.call(this); 184 }; 185 186 /** 187 * Sets the enabled/disabled state of the label. A disabled label may have a different 188 * image, and greyed out text. This method overrides {@link DwtControl#setEnabled}. 189 * 190 * @param {boolean} enabled if <code>true</code>, set the label as enabled 191 */ 192 DwtLabel.prototype.setEnabled = 193 function(enabled) { 194 if (enabled != this._enabled) { 195 DwtControl.prototype.setEnabled.call(this, enabled); 196 var direction = this._style & DwtLabel.IMAGE_RIGHT ? DwtLabel.RIGHT : DwtLabel.LEFT; 197 this.__imageInfo = this.__imageInfo || {}; 198 this.__setImage(this.__imageInfo[direction]); 199 } 200 } 201 202 /** 203 * Gets the current image info. 204 * 205 * @param {string} direction position of the image 206 * 207 * @return {string} the image info 208 */ 209 DwtLabel.prototype.getImage = 210 function(direction) { 211 direction = direction || (this._style & DwtLabel.IMAGE_RIGHT ? DwtLabel.RIGHT : DwtLabel.LEFT); 212 return this.__imageInfo[direction]; 213 } 214 215 /** 216 * Sets the main (enabled) image. If the label is currently enabled, the image is updated. 217 * 218 * @param {string} imageInfo the image 219 * @param {string} direction position of the image 220 * @param {string} altText alternate text for non-visual users 221 */ 222 DwtLabel.prototype.setImage = 223 function(imageInfo, direction, altText) { 224 direction = direction || (this._style & DwtLabel.IMAGE_RIGHT ? DwtLabel.RIGHT : DwtLabel.LEFT); 225 this.__imageInfo = this.__imageInfo || {}; 226 this.__imageInfo[direction] = imageInfo; 227 this.__setImage(imageInfo, direction, altText); 228 } 229 230 /** 231 * 232 * Set _iconEl, used for buttons that contains only images 233 * 234 * @param htmlElement/DOM node 235 * @param {string} direction position of the image 236 * 237 */ 238 DwtLabel.prototype.setIconEl = function(iconElement, direction) { 239 this._iconEl = this._iconEl || {}; 240 direction = direction || (this._style & DwtLabel.IMAGE_RIGHT ? DwtLabel.RIGHT : DwtLabel.LEFT); 241 this._iconEl[direction] = iconElement; 242 } 243 244 /** 245 * Sets the disabled image. If the label is currently disabled, its image is updated. 246 * 247 * @param {string} imageInfo the image 248 * @deprecated no longer support different images for disabled 249 * @see #setImage 250 */ 251 DwtLabel.prototype.setDisabledImage = 252 function(imageInfo) { 253 // DEPRECATED -- we no longer support different images for disabled. 254 // See __setImage() for details. 255 } 256 257 /** 258 * Gets the label text. 259 * 260 * @return {string} the text or <code>null</code> if not set 261 */ 262 DwtLabel.prototype.getText = 263 function() { 264 return (this.__text != null) ? this.__text : null; 265 } 266 267 /** 268 * Sets the label text, and manages the placement and display. 269 * 270 * @param {string} text the new label text 271 */ 272 DwtLabel.prototype.setText = function(text) { 273 274 if (!this._textEl) { 275 return; 276 } 277 278 if (text == null || text == "") { 279 this.__text = null; 280 this._textEl.innerHTML = ""; 281 } 282 else { 283 this.__text = text; 284 this._textEl.innerHTML = text; 285 } 286 287 this._textSet(text); 288 }; 289 290 /** 291 * Sets the text background. 292 * 293 * @param {string} color the background color 294 */ 295 DwtLabel.prototype.setTextBackground = 296 function(color) { 297 this._textBackground = color; 298 if (this._textEl) { 299 this._textEl.style.backgroundColor = color; 300 } 301 } 302 303 /** 304 * Sets the text foreground. 305 * 306 * @param {string} color the foreground color 307 */ 308 DwtLabel.prototype.setTextForeground = 309 function(color) { 310 this._textForeground = color; 311 if (this._textEl) { 312 this._textEl.style.color = color; 313 } 314 } 315 316 /** 317 * Sets the align style. 318 * 319 * @param {constant} alignStyle the align style (see {@link DwtControl}) 320 */ 321 DwtLabel.prototype.setAlign = 322 function(alignStyle) { 323 this._style = alignStyle; 324 325 // reset dom since alignment style may have changed 326 var direction = this._style & DwtLabel.IMAGE_RIGHT ? DwtLabel.RIGHT : DwtLabel.LEFT; 327 this.__imageInfo = this.__imageInfo || {}; 328 this.__setImage(this.__imageInfo[direction]); 329 } 330 331 /** 332 * Checks if the given style is set as the current label style. 333 * 334 * @param {constant} style the style 335 * @return {boolean} <code>true</code> if the style is set 336 */ 337 DwtLabel.prototype.isStyle = function(style) { 338 return this._style & style; 339 }; 340 341 DwtLabel.prototype.getTabGroupMember = 342 function() { 343 // DwtLabel descends from DwtComposite, as some buttons contain nested 344 // members; it's a widget, however, and should be directly focusable 345 return DwtControl.prototype.getTabGroupMember.apply(this, arguments); 346 } 347 348 // 349 // Protected methods 350 // 351 352 /** 353 * @private 354 */ 355 DwtLabel.prototype._createHtml = function(templateId) { 356 var data = { id: this._htmlElId }; 357 this._createHtmlFromTemplate(templateId || this.TEMPLATE, data); 358 }; 359 360 /** 361 * @private 362 */ 363 DwtLabel.prototype._createHtmlFromTemplate = function(templateId, data) { 364 DwtControl.prototype._createHtmlFromTemplate.call(this, templateId, data); 365 this._textEl = document.getElementById(data.id+"_title"); 366 }; 367 368 /** 369 * @private 370 * 371 * @param {string} direction position of the image 372 */ 373 DwtLabel.prototype._getIconEl = function(direction) { 374 var _dir = this._style & DwtLabel.IMAGE_RIGHT ? DwtLabel.RIGHT : DwtLabel.LEFT; 375 direction = typeof direction === 'boolean' ? _dir : (direction || _dir); // fix for Bug 90130 376 // MOW: getting the proper icon element on demand rather than all the time for speed 377 this._iconEl = this._iconEl || {}; 378 return this._iconEl[direction] || 379 (this._iconEl[direction] = document.getElementById(this._htmlElId+"_"+direction+"_icon")); 380 }; 381 382 // 383 // Private methods 384 // 385 386 /** 387 * Set the label's image, and manage its placement. 388 * 389 * @private 390 * 391 * @param {string} imageInfo the image 392 * @param {string} direction position of the image 393 * @param {string} altText alternate text for non-visual users 394 */ 395 DwtLabel.prototype.__setImage = 396 function(imageInfo, direction, altText) { 397 this.__altText = altText || this.__altText; 398 399 var iconEl = this._getIconEl(direction); 400 if (iconEl) { 401 if (imageInfo) { 402 AjxImg.setImage(iconEl, imageInfo, null, !this._enabled, null, this.__altText); 403 404 // set a ZHasRightIcon or ZHasLeftIcon on the outer element, depending on which we set 405 var elementClass = (this._style & DwtLabel.IMAGE_RIGHT ? "ZHasRightIcon" : "ZHasLeftIcon"); 406 Dwt.addClass(this.getHtmlElement(), elementClass); 407 } else { 408 iconEl.innerHTML = ""; 409 } 410 } 411 }; 412 413 // Accessibility 414 DwtLabel.prototype._textSet = function(text) { 415 416 // assign the ARIA label directly; we want it to override the tooltip, if any 417 if (!this.hasAttribute('aria-labelledby')) { 418 if (text) { 419 this.setAttribute('aria-label', text); 420 } else { 421 this.removeAttribute('aria-label'); 422 } 423 } 424 }; 425