1 /** 2 * @fileOverview Exposes a set of API wrappers that will hide the dirty work of 3 * constructing Finesse API requests and consuming Finesse events. 4 * 5 * @name finesse.containerservices.ContainerServices 6 * @requires OpenAjax, jQuery 1.5, finesse.utilities.Utilities 7 */ 8 var finesse = finesse || {}; 9 finesse.containerservices = finesse.containerservices || {}; 10 /** 11 * @class 12 * Provide container level services for gadget developers, exposing container events by 13 * calling a set of exposed functions. Gadgets can utilize the container dialogs and 14 * event handling (add/remove) 15 */ 16 finesse.containerservices.ContainerServices = (function () { 17 18 var 19 20 /** 21 * Shortcut reference to the finesse.utilities.Utilities singleton 22 * This will be set by init() 23 * @private 24 */ 25 _util, 26 27 /** 28 * Shortcut reference to the gadget pubsub Hub instance. 29 * This will be set by init() 30 * @private 31 */ 32 _hub, 33 34 /** 35 * @private 36 * Whether the Client Services have been initiated yet. 37 */ 38 _inited = false, 39 40 /** 41 * Stores the list of subscription IDs for all subscriptions so that it 42 * could be retrieve for unsubscriptions. 43 * @private 44 */ 45 _subscriptionID = {}, 46 47 /** 48 * @private 49 * Reference to the gadget's parent container 50 */ 51 _parent, 52 53 /** 54 * @private 55 * Reference to the gadget's parent container 56 */ 57 _tabVisibleNotifier, 58 59 /** 60 * @private 61 * Reference to the gadget's prefs object 62 */ 63 _prefs, 64 65 /** 66 * @private 67 * Reference to the tabId that is associated with the gadget 68 */ 69 _myTab, 70 71 /** 72 * @private 73 * Reference to the visibility of current gadget 74 */ 75 _visible, 76 77 /** 78 * Shortcut reference to the Topics class. 79 * This will be set by init() 80 * @private 81 */ 82 _topics, 83 84 /** 85 * Ensure that ClientServices have been inited. 86 * @private 87 */ 88 _isInited = function () { 89 if (!_inited) { 90 throw new Error("ContainerServices needs to be inited."); 91 } 92 }, 93 /** 94 * Retrieves a reference to a particular notifierType. 95 * @param {String} notifierType 96 * Specifies the notifier to retrieve (tabVisible: when the parent tab becomes visible) 97 * @return {Notifier} The notifier object. 98 */ 99 _getNotifierReference = function (notifierType) { 100 var notifierReference = null; 101 if (notifierType === 'tabVisible') { 102 notifierReference = _tabVisibleNotifier; 103 } else { 104 throw new Error("_getNotifierReference(): Trying to get unknown notifier(notifierType=" + notifierType + ")"); 105 } 106 return notifierReference; 107 }, 108 /** 109 * @private 110 * Utility function to make a subscription to a particular topic. Only one 111 * callback function is registered to a particular topic at any time. 112 * @param {String} topic 113 * The full topic name. The topic name should follow the OpenAjax 114 * convention using dot notation (ex: finesse.api.User.1000). 115 * @param {Function} callback 116 * The function that should be invoked with the data when an event 117 * is delivered to the specific topic. 118 * @returns {Boolean} 119 * True if the subscription was made successfully and the callback was 120 * been registered. False if the subscription already exist, the 121 * callback was not overwritten. 122 */ 123 _subscribe = function (topic, callback) { 124 _isInited(); 125 126 //Ensure that the same subscription isn't made twice. 127 if (!_subscriptionID[topic]) { 128 //Store the subscription ID using the topic name as the key. 129 _subscriptionID[topic] = _hub.subscribe(topic, 130 //Invoke the callback just with the data object. 131 function (topic, data) { 132 callback(data); 133 }); 134 return true; 135 } 136 return false; 137 }, 138 139 /** 140 * @private 141 * Unsubscribe from a particular topic. 142 * @param {String} topic 143 * The full topic name. 144 */ 145 _unsubscribe = function (topic) { 146 _isInited(); 147 148 //Unsubscribe from the topic using the subscription ID recorded when 149 //the subscription was made, then delete the ID from data structure. 150 _hub.unsubscribe(_subscriptionID[topic]); 151 delete _subscriptionID[topic]; 152 }, 153 154 _tabTracker = function(tabId) { 155 if (tabId === _myTab) { 156 if(!_visible) { 157 _visible = true; 158 _tabVisibleNotifier.notifyListeners(this); 159 } 160 } else { 161 _visible = false; 162 } 163 }; 164 165 return { 166 /** 167 * Shows the jQuery UI Dialog with the specified parameters and the 168 * following defaults: 169 * - The only button "Ok" closes the dialog 170 * - Modal 171 * - Not draggable 172 * - Fixed size 173 * @param {Object} options 174 * An object containing additional options for the dialog. 175 * @param {String/Boolean} options.title 176 * Title to use. undefined defaults to "Cisco Finesse". 177 * false to hide 178 * @param {Function} options.close 179 * A function to invoke when the dialog is closed. 180 * @param {String} options.message 181 * The message to display in the dialog. 182 * Defaults to "A generic error has occurred." 183 * @param {Boolean} options.isBlocking 184 * Flag indicating whether this dialog will block other 185 * dialogs from being shown. 186 * @returns {jQuery} 187 * jQuery wrapped object of the dialog DOM element 188 */ 189 showDialog: function(options) { 190 if ((_parent.showDialog !== undefined) && (_parent.showDialog !== this.showDialog)) { 191 return _parent.showDialog(options); 192 } 193 }, 194 195 /** 196 * Hides the jQuery UI Dialog 197 * @returns {jQuery} 198 * jQuery wrapped object of the dialog DOM element 199 */ 200 hideDialog: function() { 201 if ((_parent.hideDialog !== undefined) && (_parent.hideDialog !== this.hideDialog)) { 202 return _parent.hideDialog(); 203 } 204 }, 205 206 /** 207 * Adds an handler to this object. 208 * @param {String} notifierType 209 * The type of notifier to add to ('tabVisible') 210 * @param {Function} callback 211 * The function callback to invoke. 212 */ 213 addHandler: function (notifierType, callback) { 214 _isInited(); 215 var notifier = null; 216 try { 217 _util.validateHandler(callback); 218 219 notifier = _getNotifierReference(notifierType); 220 221 notifier.addListener(callback); 222 223 } catch (err) { 224 throw new Error("addHandler(): " + err); 225 } 226 }, 227 228 /** 229 * Removes a handler from this object. 230 * @param {String} notifierType 231 * The type of notifier to remove ('tabVisible') 232 * @param {Function} callback 233 * The function to remove. 234 */ 235 removeHandler: function(notifierType, callback) { 236 var notifier = null; 237 try { 238 _util.validateHandler(callback); 239 240 notifier = _getNotifierReference(notifierType); 241 242 notifier.removeListener(callback); 243 } catch (err) { 244 throw new Error("removeHandler(): " + err); 245 } 246 }, 247 /** 248 * Returns the visibility of current gadget 249 * @return {Boolean} 250 * The visibility of current gadget 251 */ 252 tabVisible: function(){ 253 return _visible; 254 }, 255 256 /** 257 * Make a request to the check the current tab 258 */ 259 makeActiveTabReq : function () { 260 if(_hub){ 261 var data = { 262 type: "ActiveTabReq", 263 data: {}, 264 invokeID: (new Date()).getTime() 265 }; 266 _hub.publish(_topics.REQUESTS, data); 267 } else { 268 throw new Error("Hub is not defined."); 269 } 270 271 }, 272 273 /** 274 * Initiates the Container Services. 275 * @return {Object} 276 * The ContainerServices instance 277 */ 278 init: function () { 279 if (!_inited) { 280 // Set shortcuts 281 _util = finesse.utilities.Utilities; 282 _parent = parent.finesse.container.Container; 283 _prefs = new gadgets.Prefs(); 284 _myTab = _prefs.getString("tabId"); 285 _tabVisibleNotifier = new finesse.restservices.Notifier(); 286 _inited = true; 287 //init the hub only when it's available 288 if(gadgets.Hub) { 289 _hub = gadgets.Hub; 290 _subscribe("finesse.containerservices.activeTab", _tabTracker); 291 } 292 if(finesse.containerservices.Topics) { 293 _topics = finesse.containerservices.Topics; 294 } 295 if(finesse.containerservices.MasterPublisher){ 296 publisher = new finesse.containerservices.MasterPublisher(); 297 } 298 } 299 300 //Return the CS object for object chaining. 301 return this; 302 }, 303 304 305 306 //BEGIN TEST CODE// 307 /** 308 * Test code added to expose private functions that are used by unit test 309 * framework. This section of code is removed during the build process 310 * before packaging production code. The [begin|end]TestSection are used 311 * by the build to identify the section to strip. 312 * @ignore 313 */ 314 beginTestSection : 0, 315 316 /** 317 * @ignore 318 */ 319 getTestObject: function () { 320 //Load mock dependencies. 321 var _mock = new MockControl(); 322 _util = _mock.createMock(finesse.utilities.Utilities); 323 _hub = _mock.createMock(gadgets.Hub); 324 _inited = true; 325 _tabVisibleNotifier = new finesse.restservices.Notifier(); 326 return { 327 //Expose mock dependencies 328 mock: _mock, 329 hub: _hub, 330 util: _util, 331 tabVisibleNotifier: _tabVisibleNotifier, 332 addHandler: this.addHandler, 333 removeHandler: this.removeHandler 334 335 }; 336 }, 337 338 /** 339 * @ignore 340 */ 341 endTestSection: 0 342 //END TEST CODE// 343 }; 344 }()); 345