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 . 18 */ 19 20 /** 21
* YUI Library aliases 22 * Deliberately named differently to the
ones various components and modules use, to avoid unexpected
behaviour. 23 */ 24 var YUIDom = YAHOO.util.Dom, 25 YUIEvent =
YAHOO.util.Event, 26 YUISelector = YAHOO.util.Selector; 27 28 /**
29 * Alfresco root namespace. 30 * 31 * @namespace Alfresco 32 */
33 // Ensure Alfresco root object exists 34 if (typeof Alfresco ==
"undefined" || !Alfresco) 35 { 36 var Alfresco = {}; 37 } 38 39 /**
40 * Alfresco top-level constants namespace. 41 * 42 * @namespace
Alfresco 43 * @class Alfresco.constants 44 */ 45 Alfresco.constants
= Alfresco.constants || {}; 46 47 /** 48 * Alfresco top-level
template namespace. 49 * 50 * @namespace Alfresco 51 * @class
Alfresco.template 52 */ 53 Alfresco.template = Alfresco.template ||
{}; 54 55 /** 56 * Alfresco top-level component namespace. 57 * 58
* @namespace Alfresco 59 * @class Alfresco.component 60 */ 61
Alfresco.component = Alfresco.component || {}; 62 63 /** 64 *
Alfresco top-level dashlet namespace. 65 * 66 * @namespace Alfresco
67 * @class Alfresco.dashlet 68 */ 69 Alfresco.dashlet =
Alfresco.dashlet || {}; 70 71 /** 72 * Alfresco top-level module
namespace. 73 * 74 * @namespace Alfresco 75 * @class
Alfresco.module 76 */ 77 Alfresco.module = Alfresco.module || {};
78 79 /** 80 * Alfresco top-level util namespace. 81 * 82 *
@namespace Alfresco 83 * @class Alfresco.util 84 */ 85
Alfresco.util = Alfresco.util || {}; 86 87 /** 88 * Alfresco
top-level logger namespace. 89 * 90 * @namespace Alfresco 91 *
@class Alfresco.logger 92 */ 93 Alfresco.logger = Alfresco.logger
|| {}; 94 95 /** 96 * Alfresco top-level service namespace. 97 * 98
* @namespace Alfresco 99 * @class Alfresco.service100 */101
Alfresco.service = Alfresco.service || {};102 103 /**104 * Alfresco
top-level thirdparty namespace.105 * Used for importing third party
javascript functions106 * 107 * @namespace Alfresco108 * @class
Alfresco.thirdparty109 */110 Alfresco.thirdparty =
Alfresco.thirdparty || {};111 112 /**113 * Alfresco top-level
widget namespace.114 * 115 * @namespace Alfresco116 * @class
Alfresco.widget117 */118 Alfresco.widget = Alfresco.widget ||
{};119 120 /**121 * Alfresco top-level admin namespace.122 * 123 *
@namespace Alfresco124 * @class Alfresco.Admin125 */126
Alfresco.admin = Alfresco.admin || {};127 128 /**129 * Alfresco
top-level action namespace.130 * Used as a namespace for common
functionality reused by multiple components. 131 *132 * @namespace
Alfresco133 * @class Alfresco.action134 */135 Alfresco.action =
Alfresco.action || {};136 137 /**138 * Alfresco top-level doclib
namespace.139 *140 * @namespace Alfresco141 * @class
Alfresco.doclib142 */143 Alfresco.doclib = Alfresco.doclib ||144
{145 MODE_SITE: 0,146 MODE_REPOSITORY: 1147 };148 149 /**150 *
Alfresco top-level messages namespace.151 * 152 * @namespace
Alfresco153 * @class Alfresco.messages154 */155 Alfresco.messages =
Alfresco.messages ||156 {157 global: null,158 scope: {}159 };160
161 /**162 * Appends an array onto an object163 *164 * @method
Alfresco.util.appendArrayToObject165 * @param obj {object} Object
to be appended to166 * @param arr {array} Array to append/merge
onto object167 * @param p_value {object} Optional: default value
for property.168 * @return {object} The appended object169 *
@static170 */171 Alfresco.util.appendArrayToObject = function(obj,
arr, p_value)172 {173 var value = (p_value !== undefined ? p_value
: true);174 175 if (YAHOO.lang.isObjecT(obj) &&
YAHOO.lang.isArray(arr))176 {177 for (var i = 0, ii = arr.length; i
< ii; i++)178 {179 if (arr[i] !== undefined)180 {181 obj[arr[i]]
= value;182 }183 }184 }185 return obj;186 };187 188 /**189 *
Convert an array into an object190 *191 * @method
Alfresco.util.arrayToObject192 * @param arr {array} Array to
convert to object193 * @param p_value {object} Optional: default
value for property.194 * @return {object} Object conversion of
array195 * @static196 */197 Alfresco.util.arrayToObject =
function(arr, p_value)198 {199 var obj = {},200 value = (p_value
!== undefined ? p_value : true);201 202 if
(YAHOO.lang.isArray(arr))203 {204 for (var i = 0, ii = arr.length;
i < ii; i++)205 {206 if (arr[i] !== undefined)207 {208
obj[arr[i]] = value;209 }210 }211 }212 return obj;213 };214 215
/**216 * Copies the values in an object into a new instance.217
*218 * Note 1. This method ONLY copy values of type object, array,
date, boolean, string or number.219 * Note 2. Functions are not
copied.220 * Note 3. Objects with a constructor other than of type
Object are still in the result but aren't copied.221 * This means
that objects of HTMLElements or window will be in the result but
will not be copied and hence222 * shared between p_obj and the
returned copy og p_obj.223 *224 * @method Alfresco.util.deepCopy225
* @param p_obj {object|array|date|string|number|boolean} The object
to copy226 * @param p_oInstructions {object} (Optional) Contains
special non default copy instructions227 * @param
p_oInstructions.copyFunctions {boolean} (Optional) false by
default228 * @return {object|array|date|string|number|boolean} A
new instance of the same type as o with the same values229 *
@static230 */231 Alfresco.util.deepCopy = function(p_oObj,
p_oInstructions)232 {233 if (!p_oObj)234 {235 return p_oObj;236
}237 if (!p_oInstructions)238 {239 p_oInstructions = {};240 }241
242 if (YAHOO.lang.isArray(p_oObj))243 {244 var arr = [];245 for
(var i = 0, il = p_oObj.length, arrVal; i < il; i++)246 {247
arrVal = p_oObj[i];248 if (!YAHOO.lang.isFunction(arrVal) ||
p_oInstructions.copyFunctions == true)249 {250
arr.push(Alfresco.util.deepCopy(arrVal, p_oInstructions));251 }252
}253 return arr;254 }255 256 if (Alfresco.util.isDate(p_oObj))257
{258 return new Date(p_oObj.getTime());259 }260 261 if
(YAHOO.lang.isString(p_oObj) || YAHOO.lang.isNumber(p_oObj) ||
YAHOO.lang.isBoolean(p_oObj))262 {263 return p_oObj;264 }265 266 if
(YAHOO.lang.isObject(p_oObj))267 {268 if (p_oObj.toString() ==
"[object Object]")269 {270 var obj = {}, objVal;271 for (var name
in p_oObj)272 {273 if (p_oObj.hasOwnProperty(name))274 {275 objVal
= p_oObj[name];276 if (!YAHOO.lang.isFunction(objVal) ||
p_oInstructions.copyFunctions == true)277 {278 obj[name] =
Alfresco.util.deepCopy(objVal, p_oInstructions);279 }280 }281 }282
return obj;283 }284 else285 {286 // The object was287 return
p_oObj;288 }289 }290 291 return null;292 };293 294 /**295 * Tests
if o is of type date296 *297 * @method Alfresco.util.isDate298 *
@param o {object} The object to test299 * @return {boolean} True if
o is of type date300 * @static301 */302 Alfresco.util.isDate =
function(o)303 {304 return o.constructor &&
o.constructor.toString().indexOf("Date") != -1;305 };306 307 /**308
* Returns true if obj matches all attributes and their values in
pattern.309 * Attribute values in pattern may contain wildcards
("*").310 *311 * @method objectMatchesPattern312 * @param obj
{object} The object to match pattern against313 * @param pattern
{object} An object with attributes to match against obj314 *
@return {boolean} true if obj matches pattern, false otherwise315
*/316 Alfresco.util.objectMatchesPattern = function(obj,
pattern)317 {318 for (var attrName in pattern)319 {320 if
(pattern.hasOwnProperty(attrName) &&321
(!pattern.hasOwnProperty(attrName) || (obj[attrName] !=
pattern[attrName] && pattern[attrName] != "*")))322 {323
return false;324 }325 }326 return true;327 };328 329 /**330 *
Create empty JavaScript object literal from dotted notation
string331 * e.g.
Alfresco.util.dotNotationToObject("org.alfresco.site") returns
{"org":{"alfresco":{"site":{}}}}332 *333 * @method
Alfresco.util.dotNotationToObject334 * @param str {string} an
dotted notation string335 * @param value {object|string|number} an
optional object to set the "deepest" object to336 * @return
{object} An empty object literal, build from the dotted notation337
* @static338 */339 Alfresco.util.dotNotationToObject =
function(str, value)340 {341 var object = {}, obj = object;342 if
(typeof str === "string")343 {344 var properties = str.split("."),
property, i, ii;345 for (i = 0, ii = properties.length - 1; i <
ii; i++)346 {347 property = properties[i];348 obj[property] =
{};349 obj = obj[property];350 }351 obj[properties[i]] = value !==
undefined ? value : null;352 }353 return object;354 };355 356
/**357 * Returns an object literal's property value given a dotted
notation string representing the property path358 *359 * @method
Alfresco.util.findValueByDotNotation360 * @param obj {object} i.e.
{org:{alfresco:{site:"share"}}}361 * @param propertyPath {string}
i.e. "org.alfresco.site"362 * @param defaultValue {object} optional
The value to return if there is no value for the propertyPath363 *
@return {object} the value for the property specified by the
string, in the example "share" would be returned364 * @static365
*/366 Alfresco.util.findValueByDotNotation = function(obj,
propertyPath, defaultValue)367 {368 var value = defaultValue ?
defaultValue : null;369 if (propertyPath && obj)370 {371
var currObj = obj;372 var props = propertyPath.split(".");373 for
(var i = 0; i < props.length; i++)374 {375 currObj =
currObj[props[i]];376 if (typeof currObj == "undefined")377 {378
return value;379 }380 }381 return currObj;382 }383 return value;384
};385 386 /**387 * Check if an array contains an object388 *
@method Alfresco.util.arrayContains389 * @param arr {array} Array
to convert to object390 * @param el {object} The element to be
searched for in the array391 * @return {boolean} True if arr
contains el392 * @static393 */394 Alfresco.util.arrayContains =
function(arr, el)395 {396 return Alfresco.util.arrayIndex(arr, el)
!== -1;397 };398 399 /**400 * Removes element el from array arr401
*402 * @method Alfresco.util.arrayRemove403 * @param arr {array}
Array to remove el from404 * @param el {object} The element to be
removed405 * @return {boolean} The array now without the element406
* @static407 */408 Alfresco.util.arrayRemove = function(arr, el)409
{410 var i = Alfresco.util.arrayIndex(arr, el);411 while (i !==
-1)412 {413 arr.splice(i, 1);414 i = Alfresco.util.arrayIndex(arr,
el);415 }416 return arr;417 };418 419 /**420 * Finds the index of
an object in an array421 *422 * @method Alfresco.util.arrayIndex423
* @param arr {array} Array to search in424 * @param el {object} The
element to find the index for in the array425 * @return {integer}
-1 if not found, other wise the index426 * @static427 */428
Alfresco.util.arrayIndex = function(arr, el)429 {430 if (arr)431
{432 for (var i = 0, ii = arr.length; i < ii; i++)433 {434 if
(arr[i] == el)435 {436 return i;437 }438 }439 }440 return -1;441
};442 443 /**444 * Asserts param contains a proper value445 *
@method Alfresco.util.assertNotEmpty446 * @param param {object}
Parameter to assert valid447 * @param message {string} Error
message to throw on assertion failure448 * @static449 * @throws
{Error}450 */451 Alfresco.util.assertNotEmpty = function(param,
message)452 {453 if (typeof param == "undefined" || !param || param
=== "")454 {455 throw new Error(message);456 }457 };458 459 /**460
* Append multiple parts of a path, ensuring duplicate path
separators are removed.461 * Leaves "://" patterns intact so URIs
and nodeRefs are safe to pass through.462 *463 * @method
Alfresco.util.combinePaths464 * @param path1 {string} First path465
* @param path2 {string} Second path466 * @param ...467 * @param
pathN {string} Nth path468 * @return {string} A string containing
the combined paths469 * @static470 */471 Alfresco.util.combinePaths
= function()472 {473 var path = "", i, ii;474 for (i = 0, ii =
arguments.length; i < ii; i++)475 {476 if (arguments[i] !==
null)477 {478 path += arguments[i] + (arguments[i] !== "/" ? "/" :
"");479 }480 }481 return path.substring(0, path.length -
1).replace(/(^|[^:])\/{2,}/g, "$1/").replace(/(.)\/$/g, "$1");482
};483 484 /**485 * Constants for conversion between bytes,
kilobytes, megabytes and gigabytes486 */487 Alfresco.util.BYTES_KB
= 1024;488 Alfresco.util.BYTES_MB = 1048576;489
Alfresco.util.BYTES_GB = 1073741824;490 491 /**492 * Converts a
file size in bytes to human readable form493 *494 * @method
Alfresco.util.formatFileSize495 * @param fileSize {number} File
size in bytes496 * @return {string} The file size in a readable
form, i.e 1.2mb497 * @static498 * @throws {Error}499 */500
Alfresco.util.formatFileSize = function(fileSize)501 {502 if
(typeof fileSize == "string")503 {504 fileSize = parseInt(fileSize,
10);505 }506 507 if (fileSize < Alfresco.util.BYTES_KB)508 {509
return fileSize + " " + Alfresco.util.message("size.bytes");510
}511 else if (fileSize < Alfresco.util.BYTES_MB)512 {513
fileSize = Math.round(fileSize / Alfresco.util.BYTES_KB);514 return
fileSize + " " + Alfresco.util.message("size.kilobytes");515 }516
else if (fileSize < Alfresco.util.BYTES_GB)517 {518 fileSize =
Math.round(fileSize / Alfresco.util.BYTES_MB);519 return fileSize +
" " + Alfresco.util.message("size.megabytes");520 }521 522 fileSize
= Math.round(fileSize / Alfresco.util.BYTES_GB);523 return fileSize
+ " " + Alfresco.util.message("size.gigabytes");524 };525 526
/**527 * Given a filename, returns either a filetype icon or
generic icon file stem528 *529 * @method
Alfresco.util.getFileIcon530 * @param p_fileName {string} File to
find icon for531 * @param p_fileType {string} Optional: Filetype to
offer further hinting532 * @param p_iconSize {int} Icon size: 32533
* @return {string} The icon name, e.g. doc-file-32.png534 *
@static535 */536 Alfresco.util.getFileIcon = function(p_fileName,
p_fileType, p_iconSize)537 {538 // Mapping from extn to icon name
for cm:content539 var extns = 540 {541 "doc": "doc",542 "docx":
"doc",543 "ppt": "ppt",544 "pptx": "ppt",545 "xls": "xls",546
"xlsx": "xls",547 "pdf": "pdf",548 "bmp": "img",549 "gif":
"img",550 "jpg": "img",551 "jpeg": "img",552 "png": "img",553
"txt": "text"554 };555 556 var prefix = "generic",557 fileType =
typeof p_fileType === "string" ? p_fileType : "cm:content",558
iconSize = typeof p_iconSize === "number" ? p_iconSize : 32;559 560
// If type = cm:content, then use extn look-up561 var type =
Alfresco.util.getFileIcon.types[fileType];562 if (type ===
"file")563 {564 var extn =
p_fileName.substring(p_fileName.lastIndexOf(".") +
1).toLowerCase();565 if (extn in extns)566 {567 prefix =
extns[extn];568 }569 }570 else if (typeof type == "undefined")571
{572 type = "file";573 }574 return prefix + "-" + type + "-" +
iconSize + ".png";575 };576 Alfresco.util.getFileIcon.types =577
{578 "{http://www.alfresco.org/model/content/1.0}cmobject":
"file",579 "cm:cmobject": "file",580
"{http://www.alfresco.org/model/content/1.0}content": "file",581
"cm:content": "file",582
"{http://www.alfresco.org/model/content/1.0}thumbnail": "file",583
"cm:thumbnail": "file",584
"{http://www.alfresco.org/model/content/1.0}folder": "folder",585
"cm:folder": "folder",586
"{http://www.alfresco.org/model/content/1.0}category":
"category",587 "cm:category": "category",588
"{http://www.alfresco.org/model/content/1.0}person": "user",589
"cm:person": "user",590
"{http://www.alfresco.org/model/content/1.0}authorityContainer":
"group",591 "cm:authorityContainer": "group",592 "tag": "tag",593
"{http://www.alfresco.org/model/site/1.0}sites": "site",594
"st:sites": "site",595
"{http://www.alfresco.org/model/site/1.0}site": "site",596
"st:site": "site",597
"{http://www.alfresco.org/model/transfer/1.0}transferGroup":
"server-group",598 "trx:transferGroup": "server-group",599
"{http://www.alfresco.org/model/transfer/1.0}transferTarget":
"server",600 "trx:transferTarget": "server"601 };602 603 /**604 *
Returns the extension from file url or path605 * 606 * @method
Alfresco.util.getFileExtension607 * @param filePath {string} File
path from which to extract file extension608 * @return
{string|null} File extension or null609 * @static610 */611
Alfresco.util.getFileExtension = function(filePath)612 {613 var
match = (new String(filePath)).match(/^.*\.([^\.]*)$/);614 if
(YAHOO.lang.isArray(match) &&
YAHOO.lang.isString(match[1]))615 {616 return match[1];617 }618 619
return null;620 };621 622 /**623 * Formats a Freemarker datetime
into more UI-friendly format624 *625 * @method
Alfresco.util.formatDate626 * @param date {string} Optional: Date
as returned from data webscript. Today used if missing.627 * @param
mask {string} Optional: Mask to use to override default.628 *
@return {string} Date formatted for UI629 * @static630 */631
Alfresco.util.formatDate = function(date)632 {633 try634 {635
return Alfresco.thirdparty.dateFormat.apply(this, arguments);636
}637 catch(e)638 {639 return date;640 }641 };642 643 /**644 *
Convert an ISO8601 date string into a JavaScript native Date
object645 *646 * @method Alfresco.util.fromISO8601647 * @param date
{string} ISO8601 formatted date string648 * @return {Date|null}
JavaScript native Date object649 * @static650 */651
Alfresco.util.fromISO8601 = function(date)652 {653 try654 {655
return Alfresco.thirdparty.fromISO8601.apply(this, arguments);656
}657 catch(e)658 {659 return null;660 }661 };662 663 /**664 *
Convert a JavaScript native Date object into an ISO8601 date
string665 *666 * @method Alfresco.util.toISO8601667 * @param date
{Date} JavaScript native Date object668 * @return {string} ISO8601
formatted date string669 * @static670 */671 Alfresco.util.toISO8601
= function(date)672 {673 try674 {675 return
Alfresco.thirdparty.toISO8601.apply(this, arguments);676 }677
catch(e)678 {679 return "";680 }681 };682 683 /**684 * Convert an
JSON date exploded into an object literal into a JavaScript native
Date object.685 * NOTE: Passed-in date will have month as
zero-based.686 *687 * @method Alfresco.util.fromExplodedJSONDate688
* @param date {object} object literal of the following example
format (UTC):689 * 690 * date = 691 * {692 * year: 2009693 * month:
4 // NOTE: zero-based694 * date: 22695 * hours: 14696 * minutes:
27697 * seconds: 42698 * milliseconds: 390699 * }700 * 701 *
@return {Date|null} JavaScript native Date object702 * @static703
*/704 Alfresco.util.fromExplodedJSONDate = function(date)705 {706
try707 {708 var isoDate = YAHOO.lang.substitute("{year 4}-{month
2}-{date 2}T{hours 2}:{minutes 2}:{seconds 2}.{milliseconds 3}Z",
date, function(p_key, p_value, p_meta)709 {710 if (p_key ==
"month")711 {712 ++p_value;713 }714 p_value = String(p_value);715
var length = parseInt(p_meta, 10) || 2;716 while (p_value.length
< length)717 {718 p_value = "0" + p_value;719 }720 return
p_value;721 });722 return
Alfresco.thirdparty.fromISO8601.apply(this, [isoDate,
Array.prototype.slice.call(arguments).slice(1)]);723 }724
catch(e)725 {726 return null;727 }728 };729 730 /**731 * Convert an
object literal into a JavaScript native Date object into an JSON
date exploded.732 * NOTE: Passed-in date will have month as
zero-based.733 *734 * @method Alfresco.util.toExplodedJSONDate735 *
@param date {Date} JavaScript Date object736 * @return {object}737
* 738 * date = 739 * {740 * year: 2009741 * month: 4 // NOTE:
zero-based742 * date: 22743 * hours: 14744 * minutes: 27745 *
seconds: 42746 * milliseconds: 390747 * }748 * 749 * @static750
*/751 Alfresco.util.toExplodedJSONDate = function(date)752 {753
return (754 {755 zone: "UTC",756 year: date.getFullYear(),757
month: date.getMonth(),758 date: date.getDate(),759 hours:
date.getHours(),760 minutes: date.getMinutes(),761 seconds:
date.getSeconds(),762 milliseconds: date.getMilliseconds()763
});764 };765 766 /**767 * Generate a relative time between two Date
objects.768 * 769 * @method Alfresco.util.relativeTime770 * @param
from {Date} JavaScript Date object771 * @param to {Date} (Optional)
JavaScript Date object, defaults to now if not supplied772 *
@return {string} Relative time description773 * @static774 */775
Alfresco.util.relativeTime = function(from, to)776 {777 if
(YAHOO.lang.isUndefined(to))778 {779 to = new Date();780 }781 782
var $msg = Alfresco.util.message,783 seconds_ago = ((to - from) /
1000),784 minutes_ago = Math.floor(seconds_ago / 60);785 786 if
(minutes_ago and & entities with their character equivalents886
*887 * @method Alfresco.util.decodeHTML888 * @param html {string}
The string containing HTML entities889 * @return {string} Decoded
string890 * @static891 */892 Alfresco.util.decodeHTML =
function(html)893 {894 if (html === null)895 {896 return "";897
}898 return
html.split("").split("&").join("&").split(""").join('"');899
};900 901 /**902 * Encodes a potentially unsafe string with HTML
entities903 * Replaces , & characters with their entity
equivalents.904 * Based on the equivalent encodeHTML and
unencodeHTML functions in Prototype.905 *906 * @method
Alfresco.util.encodeHTML907 * @param text {string} The string to be
encoded908 * @param justified {boolean} If true, don't render lines
2..n with an indent909 * @return {string} Safe HTML string910 *
@static911 */912 Alfresco.util.encodeHTML = function(text,
justified)913 {914 if (text === null || typeof text ==
"undefined")915 {916 return "";917 }918 919 var indent = justified
=== true ? "" : "";920 921 if (YAHOO.env.ua.ie > 0)922 {923 text
= "" + text;924 return text.replace(/&/g, "&").replace(//g,
">").replace(/\n/g, "
" + indent).replace(/"/g, """);925 }926 var me =
arguments.callee;927 me.text.data = text;928 return
me.div.innerHTML.replace(/\n/g, "
" + indent).replace(/"/g, """);929 };930
Alfresco.util.encodeHTML.div = document.createElement("div");931
Alfresco.util.encodeHTML.text = document.createTextNode("");932
Alfresco.util.encodeHTML.div.appendChild(Alfresco.util.encodeHTML.text);933
934 /**935 * Encodes a folder path string for use in a REST URI.936
* First performs a encodeURI() pass so that the '/' character is
maintained937 * as the path must be intact as URI elements. Then
encodes further characters938 * on the path that would cause
problems in URLs, such as '&', '=' and '#'.939 *940 * @method
Alfresco.util.encodeURIPath941 * @param text {string} The string to
be encoded942 * @return {string} Encoded path URI string.943 *
@static944 */945 Alfresco.util.encodeURIPath = function(text)946
{947 return encodeURIComponent(text).replace(/%2F/g, "/");948 };949
950 /**951 * Scans a text string for links and injects HTML mark-up
to activate them.952 * NOTE: If used in conjunction with
encodeHTML, this function must be called last.953 *954 * @method
Alfresco.util.activateLinks955 * @param text {string} The string
potentially containing links956 * @return {string} String with
links marked-up to make them active957 * @static958 */959
Alfresco.util.activateLinks = function(text)960 {961 var re = new
RegExp(/((http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?\^=%&:\/~\+#]*[\w\-\@?\^=%&\/~\+#])?)/g);962
text = text.replace(re, "$1");963 return text;964 };965 966 /**967
* Convert a plaintext Tweet into HTML with detected links parsed
and "activated"968 *969 * @method Alfresco.util.tweetToHTML970 *
@param text {string} The plaintext Tweet971 * @return {string} HTML
string972 */973 Alfresco.util.tweetToHTML = function(text)974 {975
// URLs976 text = Alfresco.util.activateLinks(text);977 978 // User
links979 var re = new RegExp(/(^|[^\w])@([\w]{1,})/g);980 text =
text.replace(re, "$1@$2");981 982 // Hash tags983 re = new
RegExp(/#+([\w]{1,})/g);984 text = text.replace(re, "#$1");985 986
return text;987 };988 989 /**990 * Tests a select element's options
against "value" and991 * if there is a match that option is set to
the selected index.992 *993 * @method
Alfresco.util.setSelectedIndex994 * @param value
{HTMLSelectElement} The select element to change the selectedIndex
for995 * @param selectEl {string} The value to match agains the
select elements option values996 * @return {string} The label/name
of the seleceted option OR null if no option was found997 *
@static998 */999 Alfresco.util.setSelectedIndex =
function(selectEl, value)1000 {1001 for (var i = 0, l =
selectEl.options.length; i < l; i++)1002 {1003 if
(selectEl.options[i].value == value)1004 {1005
selectEl.selectedIndex = i;1006 return
selectEl.options[i].text;1007 }1008 }1009 return null;1010 };1011
1012 /**1013 * Removes selectClass from all of selectEl's parent's
child elements but adds it to selectEl.1014 *1015 * @method
Alfresco.util.setSelectedClass1016 * @param parentEl {HTMLElement}
The elements to deselct1017 * @param selectEl {HTMLElement} The
element to select1018 * @param selectClass {string} The css class
to remove from unselected and add to the selected element1019 *
@static1020 */1021 Alfresco.util.setSelectedClass =
function(parentEl, selectEl, selectClass)1022 {1023 var children =
parentEl.childNodes,1024 child = null;1025 1026 selectClass =
selectClass ? selectClass : "selected";1027 for (var i = 0, l =
children.length; i < l; i++)1028 {1029 child = children[i];1030
if (!selectEl || child.tagName == selectEl.tagName)1031 {1032
YUIDom.removeClass(child, selectClass);1033 if (child ===
selectEl)1034 {1035 YUIDom.addClass(child, selectClass);1036 }1037
}1038 }1039 };1040 1041 /**1042 * Returns a unique DOM ID for
dynamically-created content. Optionally applies the new ID to an
element.1043 *1044 * @method Alfresco.util.generateDomId1045 *
@param p_el {HTMLElement} Applies new ID to element1046 * @param
p_prefix {string} Optional prefix instead of "alf-id" default1047 *
@return {string} Dom Id guaranteed to be unique on the current
page1048 */1049 Alfresco.util.generateDomId = function(p_el,
p_prefix)1050 {1051 var domId, prefix = p_prefix || "alf-id";1052
do1053 {1054 domId = prefix +
Alfresco.util.generateDomId._nId++;1055 } while (YUIDom.get(domId)
!== null);1056 1057 Alfresco.util.setDomId(p_el, domId);1058 1059
return domId;1060 };1061 Alfresco.util.generateDomId._nId = 0;1062
1063 /**1064 * Sets the domId as the html dom id on el1065 *1066 *
@method Alfresco.util.setDomId1067 * @param p_el {HTMLElement}
Applies new ID to element1068 * @param p_domId {string} The dom id
to apply1069 */1070 Alfresco.util.setDomId = function(p_el,
p_domId)1071 {1072 if (p_el)1073 {1074 if (YAHOO.env.ua.ie > 0
&& YAHOO.env.ua.ie < 8)1075 {1076 // MSIE 6 & 7-safe
method1077 p_el.attributes["id"].value = p_domId;1078
p_el.setAttribute("id", p_domId);1079 }1080 else1081 {1082
p_el.setAttribute("id", p_domId);1083 }1084 }1085 };1086 1087
/**1088 * Converts "rel" attributes on tags to "target"
attributes.1089 * "target" isn't supported in XHTML, so we use
"rel" as a placeholder and replace at runtime.1090 *1091 * @method
relToTarget1092 * @param rootNode {HTMLElement|String} An id or
HTMLElement to start the query from1093 */1094
Alfresco.util.relToTarget = function(p_rootNode)1095 {1096 var
elements = YUISelector.query("a[rel]", p_rootNode);1097 for (var i
= 0, ii = elements.length; i < ii; i++)1098 {1099
elements[i].setAttribute("target",
elements[i].getAttribute("rel"));1100 }1101 };1102 1103 /**1104 *
Sets single or multiple DOM element innerHTML values.1105 * Ensures
target element exists in the DOM before attempting to set the
label.1106 *1107 * @method populateHTML1108 * @param p_label,
p_label, ... {Array} Array with exactly two members:1109 * 1110 *
[0] {String | HTMLElement} Accepts a string to use as an ID for
getting a DOM reference, or an actual DOM reference.
1111 * [1] {String} HTML content to populate element if it exists
in the DOM. HTML will NOT be escaped.1112 * 1113 */1114
Alfresco.util.populateHTML = function()1115 {1116 for (var i = 0,
ii = arguments.length, el = null; i < ii; i++)1117 {1118 el =
YUIDom.get(arguments[i][0]);1119 if (el)1120 {1121 el.innerHTML =
arguments[i][1];1122 }1123 }1124 };1125 1126 /**1127 * Wrapper to
create a YUI Button with common attributes.1128 * All supplied
object parameters are passed to the button constructor1129 * e.g.
Alfresco.util.createYUIButton(this, "OK", this.onOK, {type:
"submit"});1130 *1131 * @method Alfresco.util.createYUIButton1132 *
@param p_scope {object} Component containing button; must have "id"
parameter1133 * @param p_name {string} Dom element ID of markup
that button is created from {p_scope.id}-{name}1134 * @param
p_onclick {function} If supplied, registered with the button's
click event1135 * @param p_obj {object} Optional extra object
parameters to pass to button constructor1136 * @param p_oElement
{string|HTMLElement} Optional and accepts a string to use as an ID
for getting a DOM reference or an actual DOM reference1137 *
@return {YAHOO.widget.Button} New Button instance1138 * @static1139
*/1140 Alfresco.util.createYUIButton = function(p_scope, p_name,
p_onclick, p_obj, p_oElement)1141 {1142 // Default button
parameters1143 var obj =1144 {1145 type: "button",1146 disabled:
false1147 };1148 1149 // Any extra parameters?1150 if (typeof p_obj
== "object")1151 {1152 obj = YAHOO.lang.merge(obj, p_obj);1153
}1154 1155 // Fix-up the menu element ID1156 if ((obj.type ==
"menu") && (typeof obj.menu == "string"))1157 {1158
obj.menu = p_scope.id + "-" + obj.menu;1159 }1160 1161 // Create
the button1162 var oElement = p_oElement ? p_oElement : p_scope.id
+ "-" + p_name,1163 button = null;1164 1165 if
(YUIDom.get(oElement) !== null)1166 {1167 button = new
YAHOO.widget.Button(oElement, obj);1168 1169 if (typeof button ==
"object")1170 {1171 // Register the click listener if one was
supplied1172 if (typeof p_onclick == "function")1173 {1174 //
Special case for a menu1175 if (obj.type == "menu")1176 {1177
button.getMenu().subscribe("click", p_onclick, p_scope, true);1178
}1179 else1180 {1181 button.on("click", p_onclick, button,
p_scope);1182 }1183 }1184 1185 // Special case if htmlName was
passed-in as an option1186 if (typeof obj.htmlName !=
"undefined")1187 {1188
button.get("element").getElementsByTagName("button")[0].name =
obj.htmlName;1189 }1190 }1191 }1192 return button;1193 };1194 1195
/**1196 * Wrapper to disable a YUI Button, including link
buttons.1197 * Link buttons aren't disabled by YUI; see
http://developer.yahoo.com/yui/button/#apiref1198 *1199 * @method
Alfresco.util.disableYUIButton1200 * @param p_button
{YAHOO.widget.Button} Button instance1201 * @static1202 */1203
Alfresco.util.disableYUIButton = function(p_button)1204 {1205 if
(p_button.set && p_button.get)1206 {1207
p_button.set("disabled", true);1208 if (p_button.get("type") ==
"link")1209 {1210 /**1211 * Note the non-optimal use of a "private"
variable, which is why it's tested before use.1212 */1213
p_button.set("href", "");1214 if (p_button._button &&
p_button._button.setAttribute)1215 {1216
p_button._button.setAttribute("onclick", "return false;");1217
}1218 p_button.addStateCSSClasses("disabled");1219
p_button.removeStateCSSClasses("hover");1220
p_button.removeStateCSSClasses("active");1221
p_button.removeStateCSSClasses("focus");1222 }1223 }1224 };1225
1226 /**1227 * Wrapper to (re)enable a YUI Button, including link
buttons.1228 * Link buttons aren't disabled by YUI; see
http://developer.yahoo.com/yui/button/#apiref1229 *1230 * @method
Alfresco.util.enableYUIButton1231 * @param p_button
{YAHOO.widget.Button} Button instance1232 * @static1233 */1234
Alfresco.util.enableYUIButton = function(p_button)1235 {1236 if
(p_button.set && p_button.get)1237 {1238
p_button.set("disabled", false);1239 if (p_button.get("type") ==
"link")1240 {1241 /**1242 * Note the non-optimal use of a "private"
variable, which is why it's tested before use.1243 */1244 if
(p_button._button && p_button._button.removeAttribute)1245
{1246 p_button._button.removeAttribute("onclick");1247 }1248
p_button.removeStateCSSClasses("disabled");1249 }1250 }1251 };1252
1253 /**1254 * Creates a "disclosure twister" UI control from
existing mark-up.1255 *1256 * @method
Alfresco.util.createTwister1257 * @param p_controller
{Element|string} Element (or DOM ID) of controller node1258 * The
code will search for the next sibling which will be used as the
hideable panel, unless overridden below1259 * @param p_filterName
{string} Filter's name under which to save it's collapsed state via
preferences1260 * @param p_config {object} Optional additional
configuration to override the defaults1261 * 1262 * panel
{Element|string} Use this panel as the hideable element instead of
the controller's first sibling1263 * collapsed {boolean} Whether
the twister should be drawn collapsed upon creation1264 * 1265 *
@return {boolean} true = success1266 */1267
Alfresco.util.createTwister = function(p_controller, p_filterName,
p_config)1268 {1269 var defaultConfig =1270 {1271 panel: null,1272
collapsed: null,1273 CLASS_BASE: "alfresco-twister",1274
CLASS_OPEN: "alfresco-twister-open",1275 CLASS_CLOSED:
"alfresco-twister-closed"1276 };1277 1278 var elController,
elPanel,1279 config = YAHOO.lang.merge(defaultConfig, p_config ||
{});1280 1281 // Controller element1282 elController =
YUIDom.get(p_controller);1283 if (elController === null)1284 {1285
return false;1286 }1287 1288 // Panel element - next sibling or
specified in configuration1289 if (config.panel &&
YUIDom.get(config.panel))1290 {1291 elPanel =
YUIDom.get(config.panel);1292 }1293 else1294 {1295 // Find the
first sibling node1296 elPanel = elController.nextSibling;1297
while (elPanel.nodeType !== 1 && elPanel !== null)1298
{1299 elPanel = elPanel.nextSibling;1300 }1301 }1302 if (elPanel
=== null)1303 {1304 return false;1305 }1306 1307 // If "collapsed"
isn't specified in config, then use the value stored in
preferences1308 if (config.collapsed === null)1309 {1310 var
collapsedPrefs =
Alfresco.util.arrayToObject(Alfresco.util.createTwister.collapsed.split(","));1311
config.collapsed = !!collapsedPrefs[p_filterName];1312 }1313 1314
// Initial State1315 YUIDom.addClass(elController,
config.CLASS_BASE);1316 YUIDom.addClass(elController,
config.collapsed ? config.CLASS_CLOSED : config.CLASS_OPEN);1317
YUIDom.setStyle(elPanel, "display", config.collapsed ? "none" :
"block");1318 1319 YUIEvent.addListener(elController, "click",
function(p_event, p_obj)1320 {1321 // Update UI to new state1322
var collapse = YUIDom.hasClass(p_obj.controller,
config.CLASS_OPEN);1323 if (collapse)1324 {1325
YUIDom.replaceClass(p_obj.controller, config.CLASS_OPEN,
config.CLASS_CLOSED);1326 }1327 else1328 {1329
YUIDom.replaceClass(p_obj.controller, config.CLASS_CLOSED,
config.CLASS_OPEN);1330 }1331 YUIDom.setStyle(p_obj.panel,
"display", collapse ? "none" : "block");1332 1333 // Save to
preferences1334 var fnPref = collapse ? "add" : "remove",1335
preferences = new Alfresco.service.Preferences();1336 1337
preferences[fnPref].call(preferences,
Alfresco.service.Preferences.COLLAPSED_TWISTERS,
p_obj.filterName);1338 },1339 {1340 controller: elController,1341
panel: elPanel,1342 filterName: p_filterName1343 });1344 };1345
Alfresco.util.createTwister.collapsed = "";1346 1347 /**1348 *
Wrapper to create a YUI Panel with common attributes, as
follows:1349 * 1350 * modal: true,1351 * constraintoviewport:
true,1352 * draggable: true,1353 * fixedcenter: true,1354 * close:
true,1355 * visible: false1356 * 1357 * All supplied object
parameters are passed to the panel constructor1358 * e.g.
Alfresco.util.createYUIPanel("myId", { draggable: false });1359
*1360 * @method Alfresco.util.createYUIPanel1361 * @param p_el
{string|HTMLElement} The element ID representing the Panel or the
element representing the Panel1362 * @param p_params {object}
Optional extra/overridden object parameters to pass to Panel
constructor1363 * @param p_custom {object} Optional parameters to
customise Panel creation:1364 * 1365 * render {boolean} By default
the new Panel will be rendered to document.body. Set to false to
prevent this.1366 * type {object} Use to override
YAHOO.widget.Panel default type, e.g. YAHOO.widget.Dialog1367 *
1368 * @return {YAHOO.widget.Panel|flags.type} New Panel
instance1369 * @static1370 */1371 Alfresco.util.createYUIPanel =
function(p_el, p_params, p_custom)1372 {1373 // Default constructor
parameters1374 var panel,1375 params =1376 {1377 modal: true,1378
constraintoviewport: true,1379 draggable: true,1380 fixedcenter:
"contained",1381 close: true,1382 visible: false1383 },1384 custom
=1385 {1386 render: true,1387 type: YAHOO.widget.Panel1388 };1389
1390 // Any extra/overridden constructor parameters?1391 if (typeof
p_params == "object")1392 {1393 params = YAHOO.lang.merge(params,
p_params);1394 }1395 // Any customisation?1396 if (typeof p_custom
== "object")1397 {1398 custom = YAHOO.lang.merge(custom,
p_custom);1399 }1400 1401 // Create and return the panel1402 panel
= new (custom.type)(p_el, params);1403 1404 if (custom.render)1405
{1406 panel.render(document.body);1407 }1408 1409 // Let other
components react to when a panel is shown or hidden1410
panel.subscribe("show", function (p_event, p_args)1411 {1412
YAHOO.Bubbling.fire("showPanel",1413 {1414 panel: this1415 });1416
});1417 panel.subscribe("hide", function (p_event, p_args)1418
{1419 YAHOO.Bubbling.fire("hidePanel",1420 {1421 panel: this1422
});1423 });1424 1425 return panel;1426 };1427 1428 /**1429 * Find
an event target's class name, ignoring YUI classes.1430 *1431 *
@method Alfresco.util.findEventClass1432 * @param p_eventTarget
{object} Event target from Event class1433 * @param p_tagName
{string} Optional tag if 'span' needs to be overridden1434 *
@return {string|null} Class name or null1435 * @static1436 */1437
Alfresco.util.findEventClass = function(p_eventTarget,
p_tagName)1438 {1439 var src = p_eventTarget.element;1440 var
tagName = (p_tagName || "span").toLowerCase();1441 1442 // Walk
down until specified tag found and not a yui class1443 while ((src
!== null) && ((src.tagName.toLowerCase() != tagName) ||
(src.className.indexOf("yui") === 0)))1444 {1445 src =
src.firstChild;1446 }1447 1448 // Found the target element?1449 if
(src === null)1450 {1451 return null;1452 }1453 1454 return
src.className;1455 };1456 1457 /**1458 * Determines whether a
Bubbling event should be ignored or not1459 *1460 * @method
Alfresco.util.hasEventInterest1461 * @param p_instance {object}
Instance checking for event interest1462 * @param p_args {object}
Bubbling event args1463 * @return {boolean} false to ignore
event1464 */1465 Alfresco.util.hasEventInterest =
function(p_eventGroup, p_args)1466 {1467 var obj = p_args[1],1468
sourceGroup = "source",1469 targetGroup = "target",1470 hasInterest
= false;1471 1472 if (obj)1473 {1474 // Was this a defaultAction
event?1475 if (obj.action === "navigate")1476 {1477 obj.eventGroup
= obj.anchor.rel;1478 }1479 1480 if (obj.eventGroup &&
p_eventGroup)1481 {1482 sourceGroup = (typeof obj.eventGroup ==
"string") ? obj.eventGroup : obj.eventGroup.eventGroup;1483
targetGroup = (typeof p_eventGroup == "string") ? p_eventGroup :
p_eventGroup.eventGroup;1484 1485 hasInterest = (sourceGroup ==
targetGroup);1486 }1487 }1488 return hasInterest;1489 };1490 1491
/**1492 * Check if flash is installed.1493 * Returns true if a
flash player of the required version is installed1494 *1495 *
@method Alfresco.util.isFlashInstalled1496 * @param reqMajorVer
{int}1497 * @param reqMinorVer {int}1498 * @param reqRevision
{int}1499 * @return {boolean} Returns true if a flash player of the
required version is installed1500 * @static1501 */1502
Alfresco.util.hasRequiredFlashPlayer = function(reqMajorVer,
reqMinorVer, reqRevision)1503 {1504 if (typeof DetectFlashVer ==
"function")1505 {1506 return DetectFlashVer(reqMajorVer,
reqMinorVer, reqRevision);1507 }1508 return false;1509 };1510 1511
/**1512 * Add a component's messages to the central message
store.1513 *1514 * @method Alfresco.util.addMessages1515 * @param
p_obj {object} Object literal containing messages in the correct
locale1516 * @param p_messageScope {string} Message scope to add
these to, e.g. componentId1517 * @return {boolean} true if messages
added1518 * @throws {Error}1519 * @static1520 */1521
Alfresco.util.addMessages = function(p_obj, p_messageScope)1522
{1523 if (p_messageScope === undefined)1524 {1525 throw new
Error("messageScope must be defined");1526 }1527 else if
(p_messageScope == "global")1528 {1529 throw new
Error("messageScope cannot be 'global'");1530 }1531 else1532 {1533
Alfresco.messages.scope[p_messageScope] =
YAHOO.lang.merge(Alfresco.messages.scope[p_messageScope] || {},
p_obj);1534 return true;1535 }1536 // for completeness...1537
return false;1538 };1539 1540 /**1541 * Copy one namespace's
messages to another's.1542 *1543 * @method
Alfresco.util.copyMessages1544 * @param p_source {string} Source
namespace1545 * @param p_destination {string} Destination
namespace. Will be overwritten with source's messages1546 * @throws
{Error}1547 * @static1548 */1549 Alfresco.util.copyMessages =
function(p_source, p_destination)1550 {1551 if (p_source ===
undefined)1552 {1553 throw new Error("Source must be defined");1554
}1555 else if (Alfresco.messages.scope[p_source] === undefined)1556
{1557 throw new Error("Source namespace doesn't exist");1558 }1559
else if (p_destination === undefined)1560 {1561 throw new
Error("Destination must be defined");1562 }1563 else if
(p_destination == "global")1564 {1565 throw new Error("Destination
cannot be 'global'");1566 }1567 else1568 {1569
Alfresco.messages.scope[p_destination] = YAHOO.lang.merge({},
Alfresco.messages.scope[p_source]);1570 }1571 };1572 1573 /**1574 *
Resolve a messageId into a message.1575 * If a messageScope is
supplied, that container will be searched first, followed by the
"global" message scope.1576 * Note: Implementation follows
single-quote quirks of server implementations whereby I18N messages
containing1577 * one or more tokens must use two single-quotes in
order to display one.1578 * See:
http://download.oracle.com/javase/1.5.0/docs/api/java/text/MessageFormat.html1579
*1580 * @method Alfresco.util.message1581 * @param p_messageId
{string} Message id to resolve1582 * @param p_messageScope {string}
Message scope, e.g. componentId1583 * @param multiple-values
{string} Values to replace tokens with1584 * @return {string} The
localized message string or the messageId if not found1585 *
@throws {Error}1586 * @static1587 */1588 Alfresco.util.message =
function(p_messageId, p_messageScope)1589 {1590 var msg =
p_messageId;1591 1592 if (typeof p_messageId != "string")1593 {1594
throw new Error("Missing or invalid argument: messageId");1595
}1596 1597 var globalMsg =
Alfresco.messages.global[p_messageId];1598 if (typeof globalMsg ==
"string")1599 {1600 msg = globalMsg;1601 }1602 1603 if ((typeof
p_messageScope == "string") && (typeof
Alfresco.messages.scope[p_messageScope] == "object"))1604 {1605 var
scopeMsg =
Alfresco.messages.scope[p_messageScope][p_messageId];1606 if
(typeof scopeMsg == "string")1607 {1608 msg = scopeMsg;1609 }1610
}1611 1612 // Search/replace tokens1613 var tokens = [];1614 if
((arguments.length == 3) && (typeof arguments[2] ==
"object"))1615 {1616 tokens = arguments[2];1617 }1618 else1619
{1620 tokens = Array.prototype.slice.call(arguments).slice(2);1621
}1622 1623 // Emulate server-side I18NUtils implementation1624 if
(YAHOO.lang.isArray(tokens) && tokens.length > 0)1625
{1626 msg = msg.replace(/''/g, "'");1627 }1628 msg =
YAHOO.lang.substitute(msg, tokens);1629 1630 return msg;1631 };1632
1633 Alfresco.util.calI18nParams = function(oCal) 1634 /**1635 *
Helper method to set the required i18n properties on a YUI Calendar
Widget1636 * see:
http://developer.yahoo.com/yui/docs/YAHOO.widget.Calendar.html#config_MY_LABEL_MONTH_POSITION1637
* for what each property does1638 * 1639 * @method
Alfresco.util.calI18nParams1640 * @param oCal {object} a
YAHOO.widget.Calendar object1641 * @static1642 * 1643 */1644 {1645
var setP = oCal.cfg.setProperty,1646 msg =
Alfresco.util.message;1647 oCal.cfg.setProperty("MONTHS_SHORT",
msg("months.short").split(","));1648
oCal.cfg.setProperty("MONTHS_LONG",
msg("months.long").split(","));1649
oCal.cfg.setProperty("WEEKDAYS_1CHAR",
msg("days.initial").split(","));1650
oCal.cfg.setProperty("WEEKDAYS_SHORT",
msg("days.short").split(","));1651
oCal.cfg.setProperty("WEEKDAYS_MEDIUM",
msg("days.medium").split(","));1652
oCal.cfg.setProperty("WEEKDAYS_LONG",
msg("days.long").split(","));1653 var monthPos =
msg("calendar.widget_config.my_label_month_position");1654 if
(monthPos.length !== 0)1655 {1656
oCal.cfg.setProperty("MY_LABEL_MONTH_POSITION",
parseInt(monthPos));1657 }1658 var monthSuffix =
msg("calendar.widget_config.my_label_month_suffix");1659 if
(monthSuffix.length !== 0)1660 {1661
oCal.cfg.setProperty("MY_LABEL_MONTH_SUFFIX", monthSuffix);1662
}1663 var yearPos =
msg("calendar.widget_config.my_label_year_position");1664 if
(yearPos.length !== 0)1665 {1666
oCal.cfg.setProperty("MY_LABEL_YEAR_POSITION",
parseInt(yearPos));1667 }1668
oCal.cfg.setProperty("MY_LABEL_YEAR_SUFFIX",
msg("calendar.widget_config.my_label_year_suffix"));1669 1670
};1671 1672 /**1673 * Fixes the hidden caret problem in Firefox
2.x.1674 * Assumes or elements are wrapped in a 1675 *1676 *
@method Alfresco.util.caretFix1677 * @param p_formElement
{element|string} Form element to fix input boxes within1678 *
@static1679 */1680 Alfresco.util.caretFix =
function(p_formElement)1681 {1682 if (YAHOO.env.ua.gecko ===
1.8)1683 {1684 if (typeof p_formElement == "string")1685 {1686
p_formElement = YUIDom.get(p_formElement);1687 }1688 var nodes =
YUISelector.query(".yui-u", p_formElement);1689 for (var x = 0; x
< nodes.length; x++)1690 {1691 var elem = nodes[x];1692
YUIDom.addClass(elem, "caret-fix");1693 }1694 }1695 };1696 1697
/**1698 * Remove the fixes for the hidden caret problem in Firefox
2.x.1699 * Should be called before hiding a form for re-use.1700
*1701 * @method Alfresco.util.undoCaretFix1702 * @param
p_formElement {element|string} Form element to undo fixes
within1703 * @static1704 */1705 Alfresco.util.undoCaretFix =
function(p_formElement)1706 {1707 if (YAHOO.env.ua.gecko ===
1.8)1708 {1709 if (typeof p_formElement == "string")1710 {1711
p_formElement = YUIDom.get(p_formElement);1712 }1713 var nodes =
YUISelector.query(".caret-fix", p_formElement);1714 for (var x = 0;
x < nodes.length; x++)1715 {1716 var elem = nodes[x];1717
YUIDom.removeClass(elem, "caret-fix");1718 }1719 }1720 };1721 1722
/**1723 * Submits a form programatically, handling the 1724 *
various browser nuances.1725 * 1726 * @method
Alfresco.util.submitForm1727 * @param form The form to submit1728 *
@static1729 */1730 Alfresco.util.submitForm = function(form)1731
{1732 var UA = YAHOO.env.ua;1733 var submitTheForm = false;1734
1735 if (form !== null)1736 {1737 if (UA.ie) 1738 {1739 // IE1740
submitTheForm = form.fireEvent("onsubmit");1741 }1742 else 1743 {
1744 // Gecko, Opera, and Safari1745 var event =
document.createEvent("HTMLEvents");1746 event.initEvent("submit",
true, true);1747 submitTheForm = form.dispatchEvent(event);1748
}1749 1750 if ((UA.ie || UA.webkit) && submitTheForm) 1751
{1752 // for IE and webkit firing the event doesn't submit1753 //
the form so we have to do it manually (if the 1754 // submission
was not cancelled)1755 form.submit();1756 }1757 }1758 };1759 1760
/**1761 * Parses a string to a json object and returns it.1762 * If
str contains invalid json code that is displayed using
displayPrompt().1763 *1764 * @method Alfresco.util.parseJSON1765 *
@param jsonStr {string} The JSON string to be parsed1766 * @param
displayError {boolean} Set true to display a message informing
about bad JSON syntax1767 * @return {object} The object
representing the JSON string1768 * @static1769 */1770
Alfresco.util.parseJSON = function(jsonStr, displayError)1771 {1772
try1773 {1774 return YAHOO.lang.JSON.parse(jsonStr);1775 }1776
catch (error)1777 {1778 if (displayError)1779 {1780
Alfresco.util.PopupManager.displayPrompt(1781 {1782 title:
"Failure",1783 text: "Can't parse response as json: '" + jsonStr +
"'"1784 });1785 }1786 }1787 return null;1788 };1789 1790 /**1791 *
Returns a populated URI template, given a TemplateId and an object
literal1792 * containing the tokens to be substituted.1793 *
Understands when the application is hosted in a Portal
environment.1794 *1795 * @method Alfresco.util.uriTemplate1796 *
@param templateId {string} URI TemplateId from web-framework
configuration1797 * @param obj {object} The object literal
containing the token values to substitute1798 * @param absolute
{boolean} Whether the URL should include the protocol and host1799
* @return {string|null} The populated URI or null if templateId not
found1800 * @static1801 */1802 Alfresco.util.uriTemplate =
function(templateId, obj, absolute)1803 {1804 // Check we know
about the templateId1805 if (!(templateId in
Alfresco.constants.URI_TEMPLATES))1806 {1807 return null;1808 }1809
1810 return
Alfresco.util.renderUriTemplate(Alfresco.constants.URI_TEMPLATES[templateId],
obj, absolute);1811 };1812 1813 /**1814 * Returns a populated URI
template, given the URI template and an object literal1815 *
containing the tokens to be substituted.1816 * Understands when the
application is hosted in a Portal environment.1817 *1818 * @method
Alfresco.util.renderUriTemplate1819 * @param template {string} URI
Template to be populated1820 * @param obj {object} The object
literal containing the token values to substitute1821 * @param
absolute {boolean} Whether the URL should include the protocol and
host1822 * @return {string|null} The populated URI or null if
templateId not found1823 * @static1824 */1825
Alfresco.util.renderUriTemplate = function(template, obj,
absolute)1826 {1827 // If a site page was requested but no {siteid}
given, then use the current site or remove the missing
parameter1828 if (template.indexOf("{site}") !== -1)1829 {1830 if
(obj.hasOwnProperty("site"))1831 {1832 // A site parameter was
given - is it valid?1833 if (typeof obj.site !== "string" ||
obj.site.length === 0)1834 {1835 // Not valid - remove site part of
template1836 template = template.replace("/site/{site}", "");1837
}1838 }1839 else1840 {1841 if (Alfresco.constants.SITE.length >
0)1842 {1843 // We're currently in a Site, so generate an in-Site
link1844 obj.site = Alfresco.constants.SITE;1845 }1846 else1847
{1848 // No current Site context, so remove from the template1849
template = template.replace("/site/{site}", "");1850 }1851 }1852
}1853 1854 var uri = YAHOO.lang.substitute(template, obj),1855
regExp = /^(http|https):\/\//;1856 1857 if (!regExp.test(uri))1858
{1859 // Page context required1860 uri =
Alfresco.util.combinePaths(Alfresco.constants.URL_PAGECONTEXT,
uri);1861 }1862 1863 // Portlet scriptUrl mapping required?1864 if
(Alfresco.constants.PORTLET)1865 {1866 // Remove the context
prefix1867 if (uri.indexOf(Alfresco.constants.URL_CONTEXT) ===
0)1868 {1869 uri = Alfresco.util.combinePaths("/",
uri.substring(Alfresco.constants.URL_CONTEXT.length));1870 }1871
1872 uri = Alfresco.constants.PORTLET_URL.replace("$$scriptUrl$$",
encodeURIComponent(decodeURIComponent(uri)));1873 }1874 1875 //
Absolute URI needs current protocol and host1876 if (absolute
&& (uri.indexOf(location.protocol + "//") !== 0))1877 {1878
// Don't use combinePaths in case the PORTLET_URL encoding is
fragile1879 if (uri.substring(0, 1) !== "/")1880 {1881 uri = "/" +
uri;1882 }1883 uri = location.protocol + "//" + location.host +
uri;1884 }1885 1886 return uri;1887 };1888 1889 /**1890 * Returns a
URL to a site page.1891 * If no Site ID is supplied, generates a
link to the non-site page.1892 *1893 * @method
Alfresco.util.siteURL1894 * @param pageURI {string} Page ID and and
QueryString parameters the page might need, e.g.1895 * 1896 *
"folder-details?nodeRef=" + nodeRef1897 * 1898 * @param obj
{object} The object literal containing the token values to
substitute within the template1899 * @param absolute {boolean}
Whether the URL should include the protocol and host1900 * @return
{string} The populated URL1901 * @static1902 */1903
Alfresco.util.siteURL = function(pageURI, obj, absolute)1904 {1905
return Alfresco.util.uriTemplate("sitepage", YAHOO.lang.merge(obj
|| {},1906 {1907 pageid: pageURI1908 }), absolute);1909 };1910 1911
/**1912 * Navigates to a url1913 *1914 * @method
Alfresco.util.navigateTo1915 * @param uri {string} THe uri to
navigate to1916 * @param method {string} (Optional) Default is
"GET"1917 * @param parameters {string|object}1918 * @static1919
*/1920 Alfresco.util.navigateTo = function(uri, method,
parameters)1921 {1922 method = method ? method.toUpperCase() :
"GET";1923 if (method == "GET")1924 {1925 window.location.href =
uri;1926 }1927 else1928 {1929 var form =
document.createElement("form");1930 form.method = method;1931
form.action = uri;1932 if (method == "POST" || method == "PUT")1933
{1934 var input;1935 for (var name in parameters)1936 {1937 if
(parameters.hasOwnProperty(name))1938 {1939 value =
parameters[name];1940 if (value)1941 {1942 input =
document.createElement("input");1943 input.setAttribute("name",
name);1944 input.setAttribute("type", "hidden");1945 input.value =
value;1946 form.appendChild(input);1947 }1948 }1949 } 1950 }1951
document.body.appendChild(form);1952 form.submit();1953 }1954
};1955 1956 /**1957 * Generates a link to the user profile page
unless the "userprofilepage" uritemplate has1958 * been removed or
emptied in share-config-custom.xml1959 * If no fullName is
supplied, the userName is displayed instead.1960 *1961 * @method
Alfresco.util.userProfileLink1962 * @param userName {string} User
Name1963 * @param fullName {string} Full display name. "userName"
used if this param is empty or not supplied1964 * @param linkAttr
{string} Optional attributes to add to the tag, e.g. "class"1965 *
@param disableLink {boolean} Optional attribute instructing the
link to be disabled1966 * (ie returning a span element rather than
an a href element) 1967 * @return {string} The populated HTML
Link1968 * @static1969 */1970 Alfresco.util.userProfileLink =
function(userName, fullName, linkAttr, disableLink)1971 {1972 if
(!YAHOO.lang.isString(userName) || userName.length === 0)1973 {1974
return "";1975 }1976 1977 var html =
Alfresco.util.encodeHTML(YAHOO.lang.isString(fullName) &&
fullName.length > 0 ? fullName : userName),1978 template =
Alfresco.constants.URI_TEMPLATES["userprofilepage"],1979 uri =
"";1980 1981 // If the "userprofilepage" template doesn't exist or
is empty, or we're in portlet mode we'll just return the user's
fullName || userName1982 if (disableLink ||
YAHOO.lang.isUndefined(template) || template.length === 0 ||
Alfresco.constants.PORTLET)1983 {1984 return '' + html + '';1985
}1986 1987 // Generate the link1988 uri =
Alfresco.util.uriTemplate("userprofilepage",1989 {1990 userid:
userName1991 });1992 1993 return '' + html + '';1994 };1995 1996
/**1997 * Returns a URL to the content represented by the passed-in
nodeRef1998 *1999 * @method Alfresco.util.contentURL2000 * @param
nodeRef {string} Standard Alfresco nodeRef2001 * @param name
{string} Filename to download2002 * @param attach {boolean} If
true, browser should prompt the user to "Open or Save?", rather
than display inline2003 * @return {string} The URL to the
content2004 * @static2005 */2006 Alfresco.util.contentURL =
function(nodeRef, name, attach)2007 {2008 return
Alfresco.constants.PROXY_URI + "api/node/content/" +
nodeRef.replace(":/", "") + "/" + name + (attach ? "?a=true" :
"");2009 };2010 2011 /**2012 * Returns the value of the specified
query string parameter.2013 *2014 * @method
getQueryStringParameter2015 * @param {string} paramName Name of the
parameter we want to look up.2016 * @param {string} queryString
Optional URL to look at. If not specified,2017 * this method uses
the URL in the address bar.2018 * @return {string} The value of the
specified parameter, or null.2019 * @static2020 */2021
Alfresco.util.getQueryStringParameter = function(paramName,
url)2022 {2023 var params = this.getQueryStringParameters(url);2024
2025 if (paramName in params)2026 {2027 return
params[paramName];2028 }2029 2030 return null;2031 };2032 2033
/**2034 * Returns the query string parameters as an object
literal.2035 * Parameters appearing more than once are returned an
an array.2036 * This method has been extracted from the YUI Browser
History Manager.2037 * It can be used here without the overhead of
the History JavaScript include.2038 *2039 * @method
getQueryStringParameters2040 * @param queryString {string} Optional
URL to look at. If not specified,2041 * this method uses the URL in
the address bar.2042 * @return {object} Object literal containing
QueryString parameters as name/value pairs2043 * @static2044 */2045
Alfresco.util.getQueryStringParameters = function(url)2046 {2047
var i, len, idx, queryString, params, tokens, name, value,
objParams;2048 2049 url = url || window.location.href;2050 2051 idx
= url.indexOf("?");2052 queryString = idx >= 0 ? url.substr(idx
+ 1) : url;2053 2054 // Remove the hash if any2055 idx =
queryString.lastIndexOf("#");2056 queryString = idx >= 0 ?
queryString.substr(0, idx) : queryString;2057 2058 params =
queryString.split("&");2059 2060 objParams = {};2061 2062 for
(i = 0, len = params.length; i < len; i++)2063 {2064 tokens =
params[i].split("=");2065 if (tokens.length >= 2)2066 {2067 name
= tokens[0];2068 value = decodeURIComponent(tokens[1]);2069 switch
(typeof objParams[name])2070 {2071 case "undefined":2072
objParams[name] = value;2073 break;2074 2075 case "string":2076
objParams[name] = [objParams[name]].concat(value);2077 break;2078
2079 case "object":2080 objParams[name] =
objParams[name].concat(value);2081 break;2082 }2083 }2084 }2085
2086 return objParams;2087 };2088 2089 /**2090 * Turns an object
literal into a valid queryString.2091 * Format of the object is as
returned from the getQueryStringParameters() function.2092 *2093 *
@method toQueryString2094 * @param params {object} Object literal
containing QueryString parameters as name/value pairs2095 * @return
{string} QueryString-formatted string2096 * @static2097 */2098
Alfresco.util.toQueryString = function(p_params)2099 {2100 var qs =
"?", name, value, val;2101 for (name in p_params)2102 {2103 if
(p_params.hasOwnProperty(name))2104 {2105 value =
p_params[name];2106 if (typeof value == "object")2107 {2108 for
(val in value)2109 {2110 if (value.hasOwnProperty(val))2111 {2112
qs += encodeURIComponent(name) + "=" +
encodeURIComponent(value[val]) + "&";2113 }2114 }2115 }2116
else if (typeof value == "string")2117 {2118 qs +=
encodeURIComponent(name) + "=" + encodeURIComponent(value) +
"&";2119 }2120 }2121 }2122 2123 // Return the string after
removing the last character2124 return qs.substring(0, qs.length -
1);2125 };2126 2127 /**2128 * Retrieves a JavaScript session
variable.2129 * Variables are scoped to the current
"location.host"2130 *2131 * @method getVar2132 * @param name
{string} Variable name2133 * @param default {object} Default value
to return if not set2134 * @return {object|null} Variable value or
default if provided (null otherwise)2135 * @static2136 */2137
Alfresco.util.getVar = function(p_name, p_default)2138 {2139 var
returnValue = typeof p_default != "undefined" ? p_default :
null;2140 2141 try2142 {2143 if (window.name !== "" &&
YAHOO.lang.JSON.isValid(window.name))2144 {2145 var allVars =
YAHOO.lang.JSON.parse(window.name),2146 scopedVars =
allVars[location.host],2147 value = null;2148 2149 if (typeof
scopedVars == "object")2150 {2151 value = scopedVars[p_name];2152
if (typeof value !== "undefined" && value !== null)2153
{2154 returnValue = value;2155 }2156 }2157 }2158 }2159 catch
(e)2160 {2161 Alfresco.logger.error("Alfresco.util.getVar()",
p_name, p_default, e);2162 }2163 2164 return returnValue; 2165
};2166 2167 /**2168 * Sets a JavaScript session variable.2169 * The
variables are stored in window.name, so live for as long as the
browser window does.2170 * Variables are scoped to the current
"location.host"2171 *2172 * @method setVar2173 * @param name
{string} Variable name2174 * @param value {object} Value to set2175
* @return {boolean} True for successful set2176 * @static2177
*/2178 Alfresco.util.setVar = function(p_name, p_value)2179 {2180
var success = true;2181 2182 try2183 {2184 var allVars = {};2185
2186 if (window.name !== "" &&
YAHOO.lang.JSON.isValid(window.name))2187 {2188 allVars =
YAHOO.lang.JSON.parse(window.name);2189 }2190 2191 if (typeof
allVars[location.host] == "undefined")2192 {2193
allVars[location.host] = {};2194 }2195
allVars[location.host][p_name] = p_value;2196 2197 window.name =
YAHOO.lang.JSON.stringify(allVars);2198 }2199 catch (e)2200 {2201
Alfresco.logger.error("Alfresco.util.setVar()", p_name, p_value,
e);2202 success = false;2203 }2204 return success;2205 };2206 2207
2208 /**2209 * Takes a string and splits it up to valid tags by
using whitespace as separators.2210 * Multi-word tags are supported
by "quoting the phrase".2211 * e.g. the string2212 * hello*world
"this is alfresco"2213 * would result in tags: "hello*world" and
"this is alfresco".2214 *2215 * @method getTags2216 * @param str
{string} a string containing tags2217 * @return {array} of valid
tags2218 * @static2219 */2220 Alfresco.util.getTags =
function(str)2221 {2222 var match = null,2223 tags = [],2224 found
= {},2225 regexp = new RegExp(/([^"\^\s]+)\s*|"([\^"]+)"\s*/g),2226
tag;2227 2228 while (match = regexp.exec(str))2229 {2230 tag =
match[1] || match[2];2231 if (found[tag] === undefined)2232 {2233
found[tag] = true;2234 tags.push(tag);2235 }2236 }2237 return
tags;2238 };2239 2240 /**2241 * The YUI Bubbling Library augments
callback objects with its own built-in fields.2242 * This function
strips those out, so the remainder of the object is "clean"2243
*2244 * @method cleanBubblingObject2245 * @param callbackObj
{object} Object literal as passed to the event handler2246 *
@return {object} Object stripped of Bubbling Library fields2247 *
@static2248 */2249 Alfresco.util.cleanBubblingObject =
function(callbackObj)2250 {2251 // See Bubbling Library, fire()
function. These fields are correct for v2.1.2252 var augmented
=2253 {2254 action: true,2255 flagged: true,2256 decrepitate:
true,2257 stop: true2258 },2259 cleanObj = {};2260 2261 for (var
index in callbackObj)2262 {2263 if
(callbackObj.hasOwnProperty(index) && augmented[index] !==
true)2264 {2265 cleanObj[index] = callbackObj[index];2266 }2267
}2268 return cleanObj;2269 };2270 2271 /**2272 * Bind a function to
a specific context.2273 *2274 * @method bind2275 * @param fn
{function} Function to be bound.2276 * @param context {object}
Context to bind function to.2277 * @param arguments {object}
Optional arguments to prepend to arguments passed-in when function
is actually called2278 * @return {function} Function wrapper.2279 *
@static2280 */2281 Alfresco.util.bind = function(fn, context)2282
{2283 if (!YAHOO.lang.isObject(context))2284 {2285 return fn;2286
}2287 var args =
Array.prototype.slice.call(arguments).slice(2);2288 return
(function()2289 {2290 return fn.apply(context,
args.concat(Array.prototype.slice.call(arguments)));2291 });2292
};2293 2294 /**2295 * Autocomplete key filter2296 * Whether or not
key is functional or should be ignored. Note that the right2297 *
arrow key is NOT an ignored key since it triggers queries for
certain intl2298 * charsets.2299 * From
YAHOO.widget.AutoComplete.prototype._isIgnoreKey()2300 *2301 *
@method isAutocompleteIgnoreKey2302 * @param nKeycode {Number} Code
of key pressed.2303 * @return {Boolean} True if key should be
ignored, false otherwise.2304 */2305
Alfresco.util.isAutocompleteIgnoreKey = function(nKeyCode)2306
{2307 if (2308 (nKeyCode == 9) || (nKeyCode == 13) || // tab,
enter2309 (nKeyCode == 16) || (nKeyCode == 17) || // shift, ctl2310
(nKeyCode >= 18 && nKeyCode = 33 && nKeyCode =
36 && nKeyCode = 44 && nKeyCode 0)2411 {2412 /*
Have all the YUI components the caller requires been registered?
*/2413 var isRegistered = true;2414 for (var i = 0; i <
p_aComponents.length; i++)2415 {2416 if
(YAHOO.env.getVersion(p_aComponents[i]) === null)2417 {2418
isRegistered = false;2419 break;2420 }2421 }2422 if (isRegistered
&& (p_oCallback !== null))2423 {2424 YAHOO.lang.later(10,
p_oScope, p_oCallback);2425 }2426 else2427 {2428 /* Add to the list
of components to be loaded */2429
yuiLoader.require(p_aComponents);2430 2431 /* Store the callback
function and scope for later */2432 callbacks.push(2433 {2434
required: Alfresco.util.arrayToObject(p_aComponents),2435 fn:
p_oCallback,2436 scope: (typeof p_oScope != "undefined" ? p_oScope
: window)2437 });2438 }2439 }2440 else if (p_oCallback !==
null)2441 {2442 p_oCallback.call(typeof p_oScope != "undefined" ?
p_oScope : window);2443 }2444 },2445 2446 /**2447 * Called by
template once all component dependencies have been registered.
Should be just before the closing tag.2448 * @method
loadComponents2449 * @param p_pageLoad {Boolean} Whether the
function is being called from the page footer, or elsewhere. Only
the footer is allowed to use "true" here.2450 */2451
loadComponents: function YLH_loadComponents(p_pageLoad)2452 {2453
createYUILoader();2454 if (initialLoaderComplete || p_pageLoad ===
true)2455 {2456 if (yuiLoader !== null)2457 {2458
yuiLoader.insert(null, "js");2459 }2460 }2461 },2462 2463 /**2464 *
Callback from YUILoader once all required YUI componentshave been
loaded by the browser.2465 * @method onLoaderComplete2466 */2467
onLoaderComplete: function YLH_onLoaderComplete()2468 {2469 for
(var i = 0; i < callbacks.length; i++)2470 {2471 if
(callbacks[i].fn)2472 {2473
callbacks[i].fn.call(callbacks[i].scope);2474 }2475 }2476 callbacks
= [];2477 initialLoaderComplete = true;2478 }2479 });2480 }();2481
2482 2483 /**2484 * Keeps track of Alfresco components on a page.
Components should register() upon creation to be compliant.2485 *
@class Alfresco.util.ComponentManager2486 */2487
Alfresco.util.ComponentManager = function()2488 {2489 /**2490 *
Array of registered components.2491 * 2492 * @property
components2493 * @type Array2494 */2495 var components = [];2496
2497 return (2498 {2499 /**2500 * Main entrypoint for components
wishing to register themselves with the ComponentManager2501 *
@method register2502 * @param p_aComponent {object} Component
instance to be registered2503 */2504 register: function
CM_register(p_oComponent)2505 {2506
components.push(p_oComponent);2507 components[p_oComponent.id] =
p_oComponent;2508 },2509 2510 /**2511 * Unregister a component from
the ComponentManager2512 * @method unregister2513 * @param
p_aComponent {object} Component instance to be unregistered2514
*/2515 unregister: function CM_unregister(p_oComponent)2516 {2517
for (var i = 0; i < components.length; i++) // Do not
optimize2518 {2519 if (components[i] == p_oComponent)2520 {2521
components.splice(i, 1);2522 delete
components[p_oComponent.id];2523 break;2524 }2525 }2526 },2527 2528
/**2529 * Re-register a component with the ComponentManager2530 *
Component ID cannot be updated via this function, use separate
unregister(), register() calls instead.2531 * @method
reregister2532 * @param p_aComponent {object} Component instance to
be unregistered, then registered again2533 */2534 reregister:
function CM_reregister(p_oComponent)2535 {2536
this.unregister(p_oComponent);2537 this.register(p_oComponent);2538
},2539 2540 /**2541 * Allows components to find other registered
components by name, id or both2542 * e.g. find({name:
"Alfresco.DocumentLibrary"})2543 * @method find2544 * @param
p_oParams {object} List of paramters to search by2545 * @return
{Array} Array of components found in the search2546 */2547 find:
function CM_find(p_oParams)2548 {2549 var found = [];2550 var
bMatch, component;2551 2552 for (var i = 0, j = components.length;
i < j; i++)2553 {2554 component = components[i];2555 bMatch =
true;2556 for (var key in p_oParams)2557 {2558 if (p_oParams[key]
!= component[key])2559 {2560 bMatch = false;2561 }2562 }2563 if
(bMatch)2564 {2565 found.push(component);2566 }2567 }2568 return
found;2569 },2570 2571 /**2572 * Allows components to find first
registered components by name only2573 * e.g.
findFirst("Alfresco.DocumentLibrary")2574 * @method findFirst2575 *
@param p_sName {string} Name of registered component to search
on2576 * @return {object|null} Component found in the search2577
*/2578 findFirst: function CM_findFirst(p_sName)2579 {2580 var
found = Alfresco.util.ComponentManager.find(2581 {2582 name:
p_sName2583 });2584 2585 return (typeof found[0] == "object" ?
found[0] : null);2586 },2587 2588 /**2589 * Get component by Id2590
* e.g. get("global_x002e_header-sites-menu")2591 * @method get2592
* @param p_sId {string} Id of registered component to return2593 *
@return {object|null} Component with given Id2594 */2595 get:
function CM_get(p_sId)2596 {2597 return (components[p_sId] ||
null);2598 }2599 });2600 }();2601 2602 /**2603 * Provides a common
interface for displaying popups in various forms2604 *2605 * @class
Alfresco.util.PopupManager2606 */2607 Alfresco.util.PopupManager =
function()2608 {2609 /**2610 * Alfresco Slingshot aliases2611
*/2612 var $html = Alfresco.util.encodeHTML;2613 2614 return (2615
{2616 2617 /**2618 * The html zIndex startvalue that will be
incremented for each popup2619 * that is displayed to make sure the
popup is visible to the user.2620 *2621 * @property zIndex2622 *
@type int2623 */2624 zIndex: 15,2625 2626 /**2627 * The default
config for the displaying messages, can be overriden2628 * when
calling displayMessage()2629 *2630 * @property
defaultDisplayMessageConfig2631 * @type object2632 */2633
defaultDisplayMessageConfig:2634 {2635 title: null,2636 text:
null,2637 spanClass: "message",2638 displayTime: 2.5,2639 effect:
YAHOO.widget.ContainerEffect.FADE,2640 effectDuration: 0.5,2641
visible: false,2642 noEscape: false2643 },2644 2645 /**2646 *
Intended usage: To quickly assure the user that the expected
happened.2647 *2648 * Displays a message as a popup on the
screen.2649 * In default mode it fades, is visible for half a
second and then fades out.2650 *2651 * @method displayMessage2652 *
@param config {object}2653 * The config object is in the form
of:2654 * {2655 * text: {string}, // The message text to display,
mandatory2656 * spanClass: {string}, // The class of the span
wrapping the text2657 * effect: {YAHOO.widget.ContainerEffect}, //
the effect to use when shpwing and hiding the message,2658 * //
default is YAHOO.widget.ContainerEffect.FADE2659 * effectDuration:
{int}, // time in seconds that the effect should be played, default
is 0.52660 * displayTime: {int}, // time in seconds that the
message will be displayed, default 2.52661 * modal: {true} // if
the message should modal (the background overlayed with a gray
transparent layer), default is false2662 * }2663 * @param parent
{HTMLElement} (optional) Parent element in which to render prompt.
Defaults to document.body if not provided2664 */2665
displayMessage: function(config, parent)2666 {2667 var parent =
parent || document.body;2668 // Merge the users config with the
default config and check mandatory properties2669 var c =
YAHOO.lang.merge(this.defaultDisplayMessageConfig, config);2670 if
(c.text === undefined)2671 {2672 throw new Error("Property text in
userConfig must be set");2673 }2674 var dialogConfig =2675 {2676
modal: false,2677 visible: c.visible,2678 close: false,2679
draggable: false,2680 effect:2681 {2682 effect: c.effect,2683
duration: c.effectDuration2684 },2685 zIndex: this.zIndex++2686
};2687 // IE browsers don't deserve fading, as they can't handle it
properly2688 if (c.effect === null || YAHOO.env.ua.ie > 0)2689
{2690 delete dialogConfig.effect;2691 }2692 // Construct the YUI
Dialog that will display the message2693 var message = new
YAHOO.widget.Dialog("message", dialogConfig);2694 2695 // Set the
message that should be displayed2696 var bd = "" + (c.noEscape ?
c.text : $html(c.text)) + "";2697 message.setBody(bd);2698 2699
/**2700 * Add it to the dom, center it, schedule the fade out of
the message2701 * and show it.2702 */2703
message.render(parent);2704 message.center();2705 // Need to
schedule a fade-out?2706 if (c.displayTime > 0)2707 {2708
message.subscribe("show", this._delayPopupHide,2709 {2710 popup:
message,2711 displayTime: (c.displayTime * 1000)2712 }, true);2713
}2714 message.show();2715 2716 return message;2717 },2718 2719
/**2720 * Gets called after the message has been displayed as long
as it was2721 * configured.2722 * Hides the message from the
user.2723 *2724 * @method _delayPopupHide2725 */2726
_delayPopupHide: function()2727 { 2728
YAHOO.lang.later(this.displayTime, this, function()2729 {2730
this.popup.destroy();2731 });2732 },2733 2734 /**2735 * The default
config for displaying "prompt" messages, can be overriden2736 *
when calling displayPrompt()2737 *2738 * @property
defaultDisplayPromptConfig2739 * @type object2740 */2741
defaultDisplayPromptConfig:2742 {2743 title: null,2744 text:
null,2745 icon: null,2746 close: false,2747 constraintoviewport:
true,2748 draggable: true,2749 effect: null,2750 effectDuration:
0.5,2751 modal: true,2752 visible: false,2753 noEscape: false,2754
buttons: [2755 {2756 text: null, // Too early to localize at this
time, do it when called instead2757 handler: function()2758 {2759
this.destroy();2760 },2761 isDefault: true2762 }]2763 },2764 2765
/**2766 * Intended usage: To inform the user that something
unexpected happened2767 * OR that ask the user if if an action
should be performed.2768 *2769 * Displays a message as a popup on
the screen with a button to make sure2770 * the user responds to
the prompt.2771 *2772 * In default mode it shows with an OK button
that needs clicking to get closed.2773 *2774 * @method
displayPrompt2775 * @param config {object}2776 * The config object
is in the form of:2777 * {2778 * title: {string}, // the title of
the dialog, default is null2779 * text: {string}, // the text to
display for the user, mandatory2780 * icon: null, // the icon to
display next to the text, default is null2781 * effect:
{YAHOO.widget.ContainerEffect}, // the effect to use when showing
and hiding the prompt, default is null2782 * effectDuration: {int},
// the time in seconds that the effect should run, default is
0.52783 * modal: {boolean}, // if a grey transparent overlay should
be displayed in the background2784 * close: {boolean}, // if a
close icon should be displayed in the right upper corner, default
is false2785 * buttons: [] // an array of button configs as
described by YUI's SimpleDialog, default is a single OK button2786
* noEscape: {boolean} // indicates the the message has already been
escaped (e.g. to display HTML-based messages)2787 * }2788 * @param
parent {HTMLElement} (optional) Parent element in which to render
prompt. Defaults to document.body if not provided2789 */2790
displayPrompt: function(config, parent)2791 {2792 var parent =
parent || document.body;2793 if
(this.defaultDisplayPromptConfig.buttons[0].text === null)2794
{2795 /**2796 * This default value could not be set at instantion
time since the2797 * localized messages weren't present at that
time2798 */2799 this.defaultDisplayPromptConfig.buttons[0].text =
Alfresco.util.message("button.ok", this.name);2800 }2801 // Merge
users config and the default config and check manadatory
properties2802 var c =
YAHOO.lang.merge(this.defaultDisplayPromptConfig, config);2803 if
(c.text === undefined)2804 {2805 throw new Error("Property text in
userConfig must be set");2806 }2807 2808 // Create the SimpleDialog
that will display the text2809 var prompt = new
YAHOO.widget.SimpleDialog("prompt",2810 {2811 close: c.close,2812
constraintoviewport: c.constraintoviewport,2813 draggable:
c.draggable,2814 effect: c.effect,2815 modal: c.modal,2816 visible:
c.visible,2817 zIndex: this.zIndex++2818 });2819 2820 // Show the
title if it exists2821 if (c.title)2822 {2823
prompt.setHeader($html(c.title));2824 }2825 2826 // Show the prompt
text2827 prompt.setBody(c.noEscape ? c.text : $html(c.text));2828
2829 // Show the icon if it exists2830 if (c.icon)2831 {2832
prompt.cfg.setProperty("icon", c.icon);2833 }2834 2835 // Add the
buttons to the dialog2836 if (c.buttons)2837 {2838
prompt.cfg.queueProperty("buttons", c.buttons);2839 }2840 2841 //
Add the dialog to the dom, center it and show it.2842
prompt.render(parent);2843 prompt.center();2844 prompt.show();2845
},2846 2847 /**2848 * The default config for the getting user
input, can be overriden2849 * when calling getUserInput()2850 *2851
* @property defaultGetUserInputConfig2852 * @type object2853 */2854
defaultGetUserInputConfig:2855 {2856 title: null,2857 text:
null,2858 value: "",2859 icon: null,2860 close: true,2861
constraintoviewport: true,2862 draggable: true,2863 effect:
null,2864 effectDuration: 0.5,2865 modal: true,2866 visible:
false,2867 initialShow: true,2868 noEscape: true,2869 html:
null,2870 callback: null,2871 buttons: [2872 {2873 text: null, //
OK button. Too early to localize at this time, do it when called
instead2874 handler: null,2875 isDefault: true2876 },2877 {2878
text: null, // Cancel button. Too early to localize at this time,
do it when called instead2879 handler: function()2880 {2881
this.destroy();2882 }2883 }]2884 },2885 2886 /**2887 * Intended
usage: To ask the user for a simple text input, similar to
JavaScript's prompt() function.2888 *2889 * @method
getUserInput2890 * @param config {object}2891 * The config object
is in the form of:2892 * {2893 * title: {string}, // the title of
the dialog, default is null2894 * text: {string}, // optional label
next to input box2895 * value: {string}, // optional default value
to populate textbox with2896 * callback: {object} // Object literal
specifying function callback to receive user input. Only called if
default button config used.2897 * // fn: function, obj: optional
pass-thru object, scope: callback scope2898 * icon: null, // the
icon to display next to the text, default is null2899 * effect:
{YAHOO.widget.ContainerEffect}, // the effect to use when showing
and hiding the prompt, default is null2900 * effectDuration: {int},
// the time in seconds that the effect should run, default is
0.52901 * modal: {boolean}, // i
Top Related