1 /** 2 * Copyright (C) 2005-2010 Alfresco Software Limited. 3 * 4 * This file is part of Alfresco 5 * 6 * Alfresco is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU Lesser General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * Alfresco is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public License 17 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 /** 21 * Global Header 22 * 23 * @namespace Alfresco 24 * @class Alfresco.component.Header 25 */ 26 (function() 27 { 28 /** 29 * YUI Library aliases 30 */ 31 var Dom = YAHOO.util.Dom, 32 Event = YAHOO.util.Event, 33 Selector = YAHOO.util.Selector; 34 35 /** 36 * Alfresco Slingshot aliases 37 */ 38 var $html = Alfresco.util.encodeHTML, 39 $siteURL = Alfresco.util.siteURL; 40 41 Alfresco.component.Header = function(htmlId) 42 { 43 return Alfresco.component.Header.superclass.constructor.call(this, "Alfresco.component.Header", htmlId, ["button", "menu", "container"]); 44 }; 45 46 YAHOO.extend(Alfresco.component.Header, Alfresco.component.Base, 47 { 48 /** 49 * Object container for initialization options 50 * 51 * @property options 52 * @type object 53 */ 54 options: 55 { 56 /** 57 * Current siteId. 58 * 59 * @property siteId 60 * @type string 61 * @default "" 62 */ 63 siteId: "", 64 65 /** 66 * Current site title. 67 * 68 * @property siteTitle 69 * @type string 70 * @default "" 71 */ 72 siteTitle: "", 73 74 /** 75 * Number of characters required for a search. 76 * 77 * @property minSearchTermLength 78 * @type int 79 * @default 1 80 */ 81 minSearchTermLength: 1, 82 83 /** 84 * URI replacement tokens 85 * 86 * @property tokens 87 * @type object 88 * @default {} 89 */ 90 tokens: {} 91 }, 92 93 /** 94 * Application Item YAHOO.widget instances 95 * 96 * @property appItems 97 * @type Array 98 */ 99 appItems: null, 100 101 /** 102 * User Item YAHOO.widget instances 103 * 104 * @property userItems 105 * @type Array 106 */ 107 userItems: null, 108 109 /** 110 * Default search text 111 * 112 * @property defaultSearchText 113 * @type string 114 */ 115 defaultSearchText: null, 116 117 /** 118 * Last status update time 119 * 120 * @property statusUpdateTime 121 * @type Date 122 */ 123 statusUpdateTime: null, 124 125 /** 126 * Fired by YUI when parent element is available for scripting. 127 * Initial History Manager event registration 128 * 129 * @method onReady 130 */ 131 onReady: function Header_onReady() 132 { 133 Dom.removeClass(this.id + "-appItems", "hidden"); 134 this.replaceUriTokens(); 135 this.configureSearch(); 136 this.configureMyStatus(); 137 }, 138 139 /** 140 * Called by header rendering code to register Application Item YAHOO.widget instances 141 * 142 * @method setAppItems 143 */ 144 setAppItems: function Header_setAppItems(items) 145 { 146 this.appItems = items; 147 }, 148 149 /** 150 * Called by header rendering code to register User Item YAHOO.widget instances 151 * 152 * @method setUserItems 153 */ 154 setUserItems: function Header_setUserItems(items) 155 { 156 this.userItems = items; 157 }, 158 159 160 /** 161 * About Share Handlers 162 */ 163 164 /** 165 * Show the About Share dialog 166 * 167 * @method showAboutShare 168 */ 169 showAboutShare: function Header_showAboutShare() 170 { 171 Alfresco.module.getAboutShareInstance().show(); 172 }, 173 174 175 /** 176 * Header Items Handlers 177 */ 178 179 /** 180 * Token replacement for header item URLs 181 * 182 * @method replaceUriTokens 183 */ 184 replaceUriTokens: function Header_replaceUriTokens() 185 { 186 var tokens = YAHOO.lang.merge(Alfresco.constants.URI_TEMPLATES, Alfresco.constants.HELP_PAGES, this.options.tokens), 187 links = Selector.query("a", this.id), 188 link, 189 attr; 190 191 for (var i = 0, ii = links.length; i < ii; i++) 192 { 193 link = links[i]; 194 attr = Dom.getAttribute(link, "templateUri"); 195 if (attr != null) 196 { 197 link.href = Alfresco.util.renderUriTemplate(attr, tokens); 198 } 199 } 200 }, 201 202 203 /** 204 * Search Handlers 205 */ 206 207 /** 208 * Configure search area 209 * 210 * @method configureSearch 211 */ 212 configureSearch: function Header_configureSearch() 213 { 214 this.widgets.searchBox = Dom.get(this.id + "-searchText"); 215 this.defaultSearchText = this.msg("header.search.default"); 216 217 Event.addListener(this.widgets.searchBox, "focus", this.onSearchFocus, null, this); 218 Event.addListener(this.widgets.searchBox, "blur", this.onSearchBlur, null, this); 219 220 this.setDefaultSearchText(); 221 222 // Register the "enter" event on the search text field 223 var me = this; 224 225 this.widgets.searchEnterListener = new YAHOO.util.KeyListener(this.widgets.searchBox, 226 { 227 keys: YAHOO.util.KeyListener.KEY.ENTER 228 }, 229 { 230 fn: me.submitSearch, 231 scope: this, 232 correctScope: true 233 }, "keydown").enable(); 234 235 this.widgets.searchMore = new YAHOO.widget.Button(this.id + "-search_more", 236 { 237 type: "menu", 238 menu: this.id + "-searchmenu_more" 239 }); 240 }, 241 242 /** 243 * Update image class when search box has focus. 244 * 245 * @method onSearchFocus 246 */ 247 onSearchFocus: function Header_onSearchFocus() 248 { 249 if (this.widgets.searchBox.value == this.defaultSearchText) 250 { 251 Dom.removeClass(this.widgets.searchBox, "faded"); 252 this.widgets.searchBox.value = ""; 253 } 254 else 255 { 256 this.widgets.searchBox.select(); 257 } 258 }, 259 260 /** 261 * Set default search text when box loses focus and is empty. 262 * 263 * @method onSearchBlur 264 */ 265 onSearchBlur: function Header_onSearchBlur() 266 { 267 var searchText = YAHOO.lang.trim(this.widgets.searchBox.value); 268 if (searchText.length === 0) 269 { 270 /** 271 * Since the blur event occurs before the KeyListener gets 272 * the enter we give the enter listener a chance of testing 273 * against "" instead of the help text. 274 */ 275 YAHOO.lang.later(100, this, this.setDefaultSearchText, []); 276 } 277 }, 278 279 /** 280 * Set default search text for search box. 281 * 282 * @method setDefaultSearchText 283 */ 284 setDefaultSearchText: function Header_setDefaultSearchText() 285 { 286 Dom.addClass(this.widgets.searchBox, "faded"); 287 this.widgets.searchBox.value = this.defaultSearchText; 288 }, 289 290 /** 291 * Get current search text from search box. 292 * 293 * @method getSearchText 294 */ 295 getSearchText: function Header_getSearchText() 296 { 297 return YAHOO.lang.trim(this.widgets.searchBox.value); 298 }, 299 300 /** 301 * Will trigger a search, via a page refresh to ensure the Back button works correctly 302 * 303 * @method submitSearch 304 */ 305 submitSearch: function Header_submitSearch() 306 { 307 var searchText = this.getSearchText(); 308 if (searchText.replace(/\*/g, "").length < this.options.minSearchTermLength) 309 { 310 Alfresco.util.PopupManager.displayMessage( 311 { 312 text: this.msg("message.minimum-length", this.options.minSearchTermLength) 313 }); 314 } 315 else 316 { 317 // Redirect to the search page 318 var url = "search?t=" + encodeURIComponent(searchText); 319 // Append repository search argument if within repo browser page or previous repository search 320 if (window.location.pathname.match("/repository$") == "/repository" || 321 (window.location.pathname.match("/search$") == "/search" && window.location.search.indexOf("r=true") != -1)) 322 { 323 url += "&r=true"; 324 } 325 window.location = $siteURL(url); 326 } 327 }, 328 329 /** 330 * This is the user status at the time the page was loaded. It is also updated each time the user makes an update. 331 * 332 * @property _currentStatus 333 * @type string 334 */ 335 _currentStatus: "", 336 337 /** 338 * My Status handlers 339 */ 340 341 /** 342 * Configure My Status UI 343 * 344 * @method configureMyStatus 345 */ 346 configureMyStatus: function Header_configureMyStatus() 347 { 348 this.widgets.statusBox = Dom.get(this.id + "-statusText"); 349 this.widgets.statusTime = Dom.get(this.id + "-statusTime"); 350 this._currentStatus = this.widgets.statusBox.value; // Store the loaded value. 351 352 var statusISOTime = this.widgets.statusTime.attributes.title.value; 353 if (statusISOTime !== "") 354 { 355 this.statusUpdateTime = Alfresco.util.fromISO8601(statusISOTime); 356 } 357 this.setStatusRelativeTime(); 358 359 // Find and siable the menuItem containing the My Status elements 360 Alfresco.util.bind(function Header_configureMyStatus_fnDisableUserMenu() 361 { 362 var allItems = this.userItems.concat(this.appItems), 363 item; 364 365 for (var i = 0, ii = allItems.length; i < ii; i++) 366 { 367 item = allItems[i]; 368 if (item instanceof YAHOO.widget.Button && YAHOO.lang.isFunction(item.getMenu) && item.getMenu() !== null) 369 { 370 var menuItems = item.getMenu().getItems(), 371 menuItem; 372 373 for (var j = 0, jj = menuItems.length; j < jj; j++) 374 { 375 menuItem = menuItems[j]; 376 if (Dom.hasClass(menuItem.element, "HEADER-MARKER")) 377 { 378 // Found the menu item, now disable it to remove default event handler behaviour 379 menuItem.cfg.setProperty("disabled", true); 380 return; 381 } 382 } 383 } 384 } 385 }, this)(); 386 387 // Stop the "click" event propagating to the menu handlers 388 Event.on(this.widgets.statusBox, "click", function(p_oEvent) 389 { 390 Event.stopEvent(p_oEvent); 391 }); 392 393 // When the user clicks in the status box, clear the previous status to make it easier to add new information... 394 var _this = this; 395 YAHOO.util.Event.addListener(this.id + "-statusText", "click", function(e) 396 { 397 Dom.get(_this.id + "-statusText").value = ""; 398 }); 399 400 // When the user clicks away from the status box, reset the previous status if they have not entered a value... 401 YAHOO.util.Event.addListener(this.id + "-statusText", "blur", function(e) 402 { 403 var textBox = Dom.get(_this.id + "-statusText"); 404 if (textBox.value.length == 0) 405 { 406 // If the user has not entered any data then reset the status... 407 textBox.value = _this._currentStatus; 408 } 409 }); 410 411 this.widgets.submitStatus = new YAHOO.widget.Button(this.id + "-submitStatus"); 412 this.widgets.submitStatus.on("click", this.submitStatus, this.widgets.submitStatus, this); 413 }, 414 415 /** 416 * Get current status text from textarea. 417 * 418 * @method getStatusText 419 */ 420 getStatusText: function Header_getStatusText() 421 { 422 return YAHOO.lang.trim(this.widgets.statusBox.value); 423 }, 424 425 /** 426 * Updates relative status time display. 427 * 428 * @method setStatusRelativeTime 429 */ 430 setStatusRelativeTime: function Header_setStatusRelativeTime() 431 { 432 var relativeTime = (this.statusUpdateTime === null) ? this.msg("status.never-updated") : Alfresco.util.relativeTime(this.statusUpdateTime); 433 this.widgets.statusTime.innerHTML = this.msg("status.updated", relativeTime); 434 }, 435 436 437 /** 438 * Submit status handler 439 * 440 * @method submitStatus 441 */ 442 submitStatus: function Header_submitStatus() 443 { 444 Alfresco.util.Ajax.jsonPost( 445 { 446 url: Alfresco.constants.URL_SERVICECONTEXT + "/components/profile/userstatus", 447 dataObj: 448 { 449 status: this.getStatusText() 450 }, 451 successCallback: 452 { 453 fn: this.onStatusUpdated, 454 scope: this 455 }, 456 failureMessage: this.msg("message.status.failure") 457 }); 458 }, 459 460 /** 461 * Status submitted handler 462 * 463 * @method onStatusUpdated 464 */ 465 onStatusUpdated: function Header_onStatusUpdated(response) 466 { 467 this.statusUpdateTime = Alfresco.util.fromISO8601(response.json.userStatusTime.iso8601); 468 this.setStatusRelativeTime(); 469 this._currentStatus = this.getStatusText(); 470 Alfresco.util.PopupManager.displayMessage( 471 { 472 text: this.msg("message.status.success") 473 }); 474 } 475 }); 476 })();