1 /* 2 * ***** BEGIN LICENSE BLOCK ***** 3 * Zimbra Collaboration Suite Web Client 4 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2011, 2013, 2014, 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) 2004, 2005, 2006, 2007, 2009, 2010, 2011, 2013, 2014, 2016 Synacor, Inc. All Rights Reserved. 21 * ***** END LICENSE BLOCK ***** 22 */ 23 24 /** 25 * @overview 26 * 27 * This file contains the zimlet object handler base class. 28 * 29 */ 30 31 /** 32 * Creates the object handler. 33 * @class 34 * This class defines the default implementation for a zimlet object handler. 35 * <br /> 36 * <br /> 37 * To write a zimlet, see {@link ZmZimletBase}. 38 * 39 * @param {string} typeName the type name 40 * @param {string} className the class name 41 */ 42 ZmObjectHandler = function(typeName, className) { 43 if (arguments.length > 0) { 44 this.init(typeName, className); 45 } 46 } 47 48 ZmObjectHandler.prototype.constructor = ZmObjectHandler; 49 ZmObjectHandler.prototype.isZmObjectHandler = true; 50 51 /** 52 * This method is called by the Zimlet framework to initialize the object. 53 * 54 * @param {string} typeName the type name 55 * @param {string} className the class name; if <code>null</code>, "Object" will be used 56 */ 57 ZmObjectHandler.prototype.init = 58 function(typeName, className) { 59 this._typeName = typeName; 60 this._className = className ? className : "Object"; 61 this.name = this.toString(); 62 }; 63 64 /** 65 * Returns a string representation of the object. 66 * 67 * @return {string} a string representation of the object 68 */ 69 ZmObjectHandler.prototype.toString = 70 function() { 71 // If you can find a cleaner way to get the name of 72 // a sub-class without hard coding each instance 73 // in a toString() method feel free to change. 74 if(!this._toString) { 75 var ctor = "" + this.constructor; 76 ctor = ctor.substring(0,ctor.indexOf("(")); 77 this._toString = ctor.substring("function ".length); 78 } 79 return this._toString; 80 }; 81 82 ZmObjectHandler.prototype.getEnabled = function() { 83 return true; 84 }; 85 86 87 /** 88 * Gets the type name. 89 * 90 * @return {string} the type name 91 */ 92 ZmObjectHandler.prototype.getTypeName = 93 function() { 94 return this._typeName; 95 }; 96 97 /** 98 * Gets the class name for a given object. 99 * 100 * @param {Object} obj the object 101 * @param {Object} context the content 102 * @param {string} spanId ID of the SPAN 103 * 104 * @return {string} the class name 105 */ 106 ZmObjectHandler.prototype.getClassName = 107 function(obj, context, spanId) { 108 return this._className; 109 }; 110 111 /** 112 * Gets the hovered class name for the given object. 113 * 114 * @param {Object} obj the object 115 * @param {Object} context the content 116 * @param {string} spanId ID of hovered SPAN 117 * 118 * @return {string} the hovered class name 119 */ 120 ZmObjectHandler.prototype.getHoveredClassName = 121 function(obj, context, spanId) { 122 var cname = this.getClassName(obj, context, spanId); 123 if (this._cachedClassNameForHovered !== cname) { 124 this._cachedClassNameForHovered = cname; 125 this._classNameHovered = cname + "-" + DwtCssStyle.HOVER; 126 } 127 return this._classNameHovered; 128 }; 129 130 /** 131 * Gets the active class name for a given object. 132 * 133 * @param {Object} obj the object 134 * @param {Object} context the content 135 * @param {string} spanId ID of the SPAN 136 * 137 * @return {string} the active class name 138 */ 139 ZmObjectHandler.prototype.getActiveClassName = 140 function(obj, context, spanId) { 141 var cname = this.getClassName(obj, context, spanId); 142 if (this._cachedClassNameForActive !== cname) { 143 this._cachedClassNameForActive = cname; 144 this._classNameActive = cname + "-" + DwtCssStyle.ACTIVE; 145 } 146 return this._classNameActive; 147 }; 148 149 /** 150 * @private 151 */ 152 ZmObjectHandler.prototype.findObject = 153 function(content, startIndex, objectMgr) { 154 if (startIndex === 0) { 155 this._lastMatch = null; 156 this._noMatch = false; 157 } 158 if (this._noMatch) {return null;} 159 if (this._lastMatch && this._lastMatch.index >= startIndex) { 160 return this._lastMatch; 161 } 162 this._lastMatch = this.match(content, startIndex, objectMgr); 163 this._noMatch = (this._lastMatch === null); 164 return this._lastMatch; 165 }; 166 167 168 /** 169 * This method is used to match content for a zimlet. Zimlet implementations should 170 * override this method. Usage should return a non-null result in the format of 171 * <code>String.match</code> if text on the line matched the handler regular expression. 172 * 173 * <pre> 174 * var result = handler.match(line); 175 * result[0] // should be matched string 176 * result.index // should be location within line match occurred 177 * </pre> 178 * 179 * Handlers can also set result.context which will be passed back to 180 * them during the various method calls ({@link #getToolTipText}, etc). Handlers should set 181 * regex.lastIndex to startIndex and then use <code>regex.exec(content)</code>. Handlers should 182 * also use the "g" option when constructing their regex. 183 */ 184 ZmObjectHandler.prototype.match = 185 function(content, startIndex) { 186 return null; 187 }; 188 189 /** 190 * Generates content inside the <code><span></code> tag. 191 * 192 * @return {number} the content index 193 * @private 194 * */ 195 ZmObjectHandler.prototype._getHtmlContent = 196 function(html, idx, obj, context, spanId) { 197 html[idx++] = AjxStringUtil.htmlEncode(obj, true); 198 return idx; 199 }; 200 201 /** 202 * Generates the <code><span></code> tag. 203 * 204 * @return {number} the content index 205 * @private 206 */ 207 ZmObjectHandler.prototype.generateSpan = 208 function(html, idx, obj, spanId, context, options) { 209 html[idx++] = "<span class='"; 210 html[idx++] = this.getClassName(obj); 211 html[idx++] = "' role='link' id='"; 212 html[idx++] = spanId; 213 html[idx++] = "'>"; 214 idx = this._getHtmlContent(html, idx, obj, context, spanId, options); 215 html[idx++] = "</span>"; 216 return idx; 217 }; 218 219 /** 220 * Checks if the handler has tool tip text. 221 * 222 * @param {Object} obj the object 223 * @param {Object} context the context 224 * @return <code>true</code> if the handler has tool tip text; <code>false</code> otherwise 225 */ 226 ZmObjectHandler.prototype.hasToolTipText = 227 function(obj, context) { 228 return true; 229 }; 230 231 /** 232 * Gets the handler tool tip text. 233 * 234 * @param {Object} obj the object 235 * @param {Object} context the context 236 * @return {string} the handler has tool tip text 237 */ 238 ZmObjectHandler.prototype.getToolTipText = 239 function(obj, context) { 240 return AjxStringUtil.htmlEncode(obj); 241 }; 242 243 /** 244 * Populates the handler tool tip text. 245 * 246 * @param {Object} obj the object 247 * @param {Object} context the context 248 */ 249 ZmObjectHandler.prototype.populateToolTip = 250 function(obj, context) { 251 }; 252 253 /** 254 * Gets the action menu. 255 * 256 * @param {Object} obj the object 257 * @param {string} span the span element 258 * @param {Object} context the context 259 * @return {ZmActionMenu} the action menu 260 * 261 * @private 262 */ 263 ZmObjectHandler.prototype.getActionMenu = 264 function(obj, span, context) { 265 return null; 266 }; 267 268 /** 269 * This method is called by the Zimlet framework when the object is selected. 270 * 271 * @param {Object} obj the object 272 * @param {string} span the span element 273 * @param {Object} ev the event 274 * @param {Object} context the context 275 * @see #clicked 276 */ 277 ZmObjectHandler.prototype.selected = 278 function(obj, span, ev, context) { 279 return this.clicked(span, obj, context, ev); 280 }; 281 282 /** 283 * This method is called by the Zimlet framework when the object is clicked. 284 * 285 * @param {Object} obj the object 286 * @param {string} span the span element 287 * @param {Object} ev the event 288 * @param {Object} context the context 289 */ 290 ZmObjectHandler.prototype.clicked = 291 function(span, obj, context, ev) { 292 }; 293 294 /** 295 * This method is called when the object is hovered-over. 296 * 297 * @private 298 */ 299 ZmObjectHandler.prototype.hoverOver = function(object, context, x, y) { 300 301 var tooltip = this.getToolTipText(object, context) || '', 302 content, callback; 303 304 if (typeof(tooltip) === "string") { 305 content = tooltip; 306 } 307 else if (tooltip.isAjxCallback || AjxUtil.isFunction(tooltip)) { 308 callback = tooltip; 309 } 310 else if (typeof(tooltip) === "object") { 311 content = tooltip.content; 312 callback = tooltip.callback; 313 } 314 315 if (!content && callback && tooltip.loading) { 316 content = AjxMsg.loading; 317 } 318 319 if (content) { 320 this._showTooltip(object, context, x, y, content); 321 } 322 323 if (callback) { 324 var callback1 = new AjxCallback(this, this._showTooltip, [ object, context, x, y ]); 325 AjxTimedAction.scheduleAction(new AjxTimedAction(null, function() { 326 callback.run(callback1); 327 }), 0); 328 } 329 }; 330 331 ZmObjectHandler.prototype._showTooltip = function(object, context, x, y, content) { 332 var shell = DwtShell.getShell(window); 333 var tooltip = shell.getToolTip(); 334 tooltip.setContent(content); 335 tooltip.popup(x, y); 336 // TODO: call below is odd; not sure if it's used much, appears to be for two-step tooltips (eg a map) 337 this.populateToolTip(object, context); 338 }; 339 340 /** 341 * This method is called when the handler is hovered-out. 342 * 343 * @private 344 */ 345 ZmObjectHandler.prototype.hoverOut = function(object, context) { 346 var shell = DwtShell.getShell(window); 347 var tooltip = shell.getToolTip(); 348 tooltip.popdown(); 349 }; 350