1 /* 2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 /** 7 * @fileOverview Defines the {@link CKEDITOR.tools} object, which contains 8 * utility functions. 9 */ 10 11 /** 12 * Utility functions. 13 * @namespace 14 * @example 15 */ 16 CKEDITOR.tools = 17 { 18 /** 19 * Copy the properties from one object to another. By default, properties 20 * already present in the target object <strong>are not</strong> overwritten. 21 * @param {Object} target The object to be extended. 22 * @param {Object} source[,souce(n)] The objects from which copy 23 * properties. Any number of objects can be passed to this function. 24 * @param {Boolean} [overwrite] Indicates that properties already present 25 * in the target object must be overwritten. This must be the last 26 * parameter in the function call. 27 * @returns {Object} the extended object (target). 28 * @example 29 * // Create the sample object. 30 * var myObject = 31 * { 32 * prop1 : true 33 * }; 34 * 35 * // Extend the above object with two properties. 36 * CKEDITOR.tools.extend( myObject, 37 * { 38 * prop2 : true, 39 * prop3 : true 40 * } ); 41 * 42 * // Alert "prop1", "prop2" and "prop3". 43 * for ( var p in myObject ) 44 * alert( p ); 45 */ 46 extend : function( target ) 47 { 48 var argsLength = arguments.length, 49 overwrite = arguments[ argsLength - 1 ]; 50 51 if ( typeof overwrite == 'boolean' ) 52 argsLength--; 53 else 54 overwrite = false; 55 56 for ( var i = 1 ; i < argsLength ; i++ ) 57 { 58 var source = arguments[ i ]; 59 60 for ( var propertyName in source ) 61 { 62 if ( overwrite || target[ propertyName ] == undefined ) 63 target[ propertyName ] = source[ propertyName ]; 64 } 65 } 66 67 return target; 68 }, 69 70 /** 71 * Creates an object which is an instance of a class which prototype is a 72 * predefined object. All properties defined in the source object are 73 * automatically inherited by the resulting object, including future 74 * changes to it. 75 * @param {Object} source The source object to be used as the prototype for 76 * the final object. 77 * @returns {Object} The resulting copy. 78 */ 79 prototypedCopy : function( source ) 80 { 81 var copy = function() 82 {}; 83 copy.prototype = source; 84 return new copy(); 85 }, 86 87 /** 88 * Checks if an object is an Array. 89 * @param {Object} object The object to be checked. 90 * @type Boolean 91 * @returns <i>true</i> if the object is an Array, otherwise <i>false</i>. 92 * @example 93 * alert( CKEDITOR.tools.isArray( [] ) ); // "true" 94 * alert( CKEDITOR.tools.isArray( 'Test' ) ); // "false" 95 */ 96 isArray : function( object ) 97 { 98 return ( !!object && object instanceof Array ); 99 }, 100 101 /** 102 * Transforms a CSS property name to its relative DOM style name. 103 * @param {String} cssName The CSS property name. 104 * @returns {String} The transformed name. 105 * @example 106 * alert( CKEDITOR.tools.cssStyleToDomStyle( 'background-color' ) ); // "backgroundColor" 107 * alert( CKEDITOR.tools.cssStyleToDomStyle( 'float' ) ); // "cssFloat" 108 */ 109 cssStyleToDomStyle : function( cssName ) 110 { 111 if ( cssName == 'float' ) 112 return 'cssFloat'; 113 else 114 { 115 return cssName.replace( /-./g, function( match ) 116 { 117 return match.substr( 1 ).toUpperCase(); 118 }); 119 } 120 }, 121 122 /** 123 * Replace special HTML characters in a string with their relative HTML 124 * entity values. 125 * @param {String} text The string to be encoded. 126 * @returns {String} The encode string. 127 * @example 128 * alert( CKEDITOR.tools.htmlEncode( 'A > B & C < D' ) ); // "A > B & C < D" 129 */ 130 htmlEncode : function( text ) 131 { 132 var standard = function( text ) 133 { 134 var span = new CKEDITOR.dom.element( 'span' ); 135 span.setText( text ); 136 return span.getHtml(); 137 }; 138 139 this.htmlEncode = ( standard( '>' ) == '>' ) ? 140 function( text ) 141 { 142 // WebKit does't encode the ">" character, which makes sense, but 143 // it's different than other browsers. 144 return standard( text ).replace( />/g, '>' ); 145 } : 146 standard; 147 148 return this.htmlEncode( text ); 149 }, 150 151 /** 152 * Gets a unique number for this CKEDITOR execution session. It returns 153 * progressive numbers starting at 1. 154 * @function 155 * @returns {Number} A unique number. 156 * @example 157 * alert( CKEDITOR.tools.<b>getNextNumber()</b> ); // "1" (e.g.) 158 * alert( CKEDITOR.tools.<b>getNextNumber()</b> ); // "2" 159 */ 160 getNextNumber : (function() 161 { 162 var last = 0; 163 return function() 164 { 165 return ++last; 166 }; 167 })(), 168 169 /** 170 * Creates a function override. 171 * @param {Function} originalFunction The function to be overridden. 172 * @param {Function} functionBuilder A function that returns the new 173 * function. The original function reference will be passed to this 174 * function. 175 * @returns {Function} The new function. 176 * @example 177 * var example = 178 * { 179 * myFunction : function( name ) 180 * { 181 * alert( 'Name: ' + name ); 182 * } 183 * }; 184 * 185 * example.myFunction = CKEDITOR.tools.override( example.myFunction, function( myFunctionOriginal ) 186 * { 187 * return function( name ) 188 * { 189 * alert( 'Override Name: ' + name ); 190 * myFunctionOriginal.call( this, name ); 191 * }; 192 * }); 193 */ 194 override : function( originalFunction, functionBuilder ) 195 { 196 return functionBuilder( originalFunction ); 197 }, 198 199 /** 200 * Executes a function after specified delay. 201 * @param {Function} func The function to be executed. 202 * @param {Number} [milliseconds] The amount of time (millisecods) to wait 203 * to fire the function execution. Defaults to zero. 204 * @param {Object} [scope] The object to hold the function execution scope 205 * (the "this" object). By default the "window" object. 206 * @param {Object|Array} [args] A single object, or an array of objects, to 207 * pass as arguments to the function. 208 * @param {Object} [ownerWindow] The window that will be used to set the 209 * timeout. By default the current "window". 210 * @returns {Object} A value that can be used to cancel the function execution. 211 * @example 212 * CKEDITOR.tools.<b>setTimeout( 213 * function() 214 * { 215 * alert( 'Executed after 2 seconds' ); 216 * }, 217 * 2000 )</b>; 218 */ 219 setTimeout : function( func, milliseconds, scope, args, ownerWindow ) 220 { 221 if ( !ownerWindow ) 222 ownerWindow = window; 223 224 if ( !scope ) 225 scope = ownerWindow; 226 227 return ownerWindow.setTimeout( 228 function() 229 { 230 if ( args ) 231 func.apply( scope, [].concat( args ) ) ; 232 else 233 func.apply( scope ) ; 234 }, 235 milliseconds || 0 ); 236 }, 237 238 /** 239 * Remove spaces from the start and the end of a string. The following 240 * characters are removed: space, tab, line break, line feed. 241 * @function 242 * @param {String} str The text from which remove the spaces. 243 * @returns {String} The modified string without the boundary spaces. 244 * @example 245 * alert( CKEDITOR.tools.trim( ' example ' ); // "example" 246 */ 247 trim : (function() 248 { 249 // We are not using \s because we don't want "non-breaking spaces" to be caught. 250 var trimRegex = /(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g; 251 return function( str ) 252 { 253 return str.replace( trimRegex, '' ) ; 254 }; 255 })(), 256 257 /** 258 * Remove spaces from the start (left) of a string. The following 259 * characters are removed: space, tab, line break, line feed. 260 * @function 261 * @param {String} str The text from which remove the spaces. 262 * @returns {String} The modified string excluding the removed spaces. 263 * @example 264 * alert( CKEDITOR.tools.ltrim( ' example ' ); // "example " 265 */ 266 ltrim : (function() 267 { 268 // We are not using \s because we don't want "non-breaking spaces" to be caught. 269 var trimRegex = /^[ \t\n\r]+/g; 270 return function( str ) 271 { 272 return str.replace( trimRegex, '' ) ; 273 }; 274 })(), 275 276 /** 277 * Remove spaces from the end (right) of a string. The following 278 * characters are removed: space, tab, line break, line feed. 279 * @function 280 * @param {String} str The text from which remove the spaces. 281 * @returns {String} The modified string excluding the removed spaces. 282 * @example 283 * alert( CKEDITOR.tools.ltrim( ' example ' ); // " example" 284 */ 285 rtrim : (function() 286 { 287 // We are not using \s because we don't want "non-breaking spaces" to be caught. 288 var trimRegex = /[ \t\n\r]+$/g; 289 return function( str ) 290 { 291 return str.replace( trimRegex, '' ) ; 292 }; 293 })(), 294 295 /** 296 * Returns the index of an element in an array. 297 * @param {Array} array The array to be searched. 298 * @param {Object} entry The element to be found. 299 * @returns {Number} The (zero based) index of the first entry that matches 300 * the entry, or -1 if not found. 301 * @example 302 * var letters = [ 'a', 'b', 'c' ]; 303 * alert( CKEDITOR.tools.indexOf( letters, 'b' ) ); "1" 304 */ 305 indexOf : function( array, entry ) 306 { 307 for ( var i = 0, len = array.length ; i < len ; i++ ) 308 { 309 if ( array[ i ] == entry ) 310 return i; 311 } 312 return -1; 313 } 314 }; 315 316 // PACKAGER_RENAME( CKEDITOR.tools ) 317