1 /*
  2  * CKEditor - The text editor for Internet - http://ckeditor.com
  3  * Copyright (C) 2003-2008 Frederico Caldeira Knabben
  4  *
  5  * == BEGIN LICENSE ==
  6  *
  7  * Licensed under the terms of any of the following licenses at your
  8  * choice:
  9  *
 10  *  - GNU General Public License Version 2 or later (the "GPL")
 11  *    http://www.gnu.org/licenses/gpl.html
 12  *
 13  *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
 14  *    http://www.gnu.org/licenses/lgpl.html
 15  *
 16  *  - Mozilla Public License Version 1.1 or later (the "MPL")
 17  *    http://www.mozilla.org/MPL/MPL-1.1.html
 18  *
 19  * == END LICENSE ==
 20  */
 21
 22 /**
 23  * @fileOverview Defines the {@link CKEDITOR.tools} object, which constains
 24  *		utility functions.
 25  */
 26
 27 /**
 28  * Utility functions.
 29  * @namespace
 30  * @example
 31  */
 32 CKEDITOR.tools =
 33 {
 34 	/**
 35 	 * Evaluates a script in a window (global) scope.
 36 	 * @param {String} script The script code to be evaluated.
 37 	 * @param {Object} [win] The target window. Defaults to the current window.
 38 	 * @example
 39 	 * var script = 'function sample() { alert( "Go!" ); }';
 40 	 *
 41 	 * // Evaluates a script in the current window.
 42 	 * CKEDITOR.tools.globalEval( script );
 43 	 *
 44 	 * // Evaluates a script in the parent window.
 45 	 * CKEDITOR.tools.globalEval( script, window.parent );
 46 	 *
 47 	 * // Alerts "Go!" twice.
 48 	 * window.sample();
 49 	 * window.parent.sample();
 50 	 */
 51 	globalEval : function( script, win )
 52 	{
 53 		if ( !win )
 54 			win = window;
 55
 56 		if ( win.execScript )
 57 			win.execScript( script );	// IE
 58 		else if ( CKEDITOR.env.webkit )
 59 		{
 60 			// win.eval in Safari executes in the current window environment,
 61 			// instead of win. The following should make it work.
 62 			var doc = win.document;
 63 			var scriptEl = doc.createElement('script');
 64 			scriptEl.appendChild( doc.createTextNode( script ) );
 65 			doc.documentElement.appendChild( scriptEl );
 66 		}
 67 		else
 68 			eval.call( win, script );
 69 	},
 70
 71 	/**
 72 	 * Copy the properties from one object to another. By default, properties
 73 	 * already present in the target object <strong>are not</strong> overwritten.
 74 	 * @param {Object} target The object to be extended.
 75 	 * @param {Object} source The object from which copy properties.
 76 	 * @param {Boolean} [overwrite] Indicates that properties already present
 77 	 *		in the target object must be overwritten.
 78 	 * @returns {Object} the extended object (target).
 79 	 * @example
 80 	 * // Create the sample object.
 81 	 * var myObject =
 82 	 * {
 83 	 *     prop1 : true
 84 	 * };
 85 	 *
 86 	 * // Extend the above object with two properties.
 87 	 * CKEDITOR.tools.extend( myObject,
 88 	 *     {
 89 	 *         prop2 : true,
 90 	 *         prop3 : true
 91 	 *     } );
 92 	 *
 93 	 * // Alert "prop1", "prop2" and "prop3".
 94 	 * for ( var p in myObject )
 95 	 *     alert( p );
 96 	 */
 97 	extend : function( target, source, overwrite )
 98 	{
 99 		for ( var propertyName in source )
100 		{
101 			if ( overwrite || target[ propertyName ] == undefined )
102 				target[ propertyName ] = source[ propertyName ];
103 		}
104 		return target;
105 	},
106
107 	/**
108 	 * Checks if an object is an Array.
109 	 * @param {Object} object The object to be checked.
110 	 * @type Boolean
111 	 * @returns <i>true</i> if the object is an Array, otherwise <i>false</i>.
112 	 * @example
113 	 * alert( CKEDITOR.tools.isArray( [] ) );      // "true"
114 	 * alert( CKEDITOR.tools.isArray( 'Test' ) );  // "false"
115 	 */
116 	isArray : function( object )
117 	{
118 		return ( !!object && object instanceof Array );
119 	},
120
121 	/**
122 	 * Transforms a CSS property name to its relative DOM style name.
123 	 * @param {String} cssName The CSS property name.
124 	 * @returns {String} The transformed name.
125 	 * @example
126 	 * alert( CKEDITOR.tools.cssStyleToDomStyle( 'background-color' ) );  // "backgroundColor"
127 	 * alert( CKEDITOR.tools.cssStyleToDomStyle( 'float' ) );             // "cssFloat"
128 	 */
129 	cssStyleToDomStyle : function( cssName )
130 	{
131 		if ( cssName == 'float' )
132 			return 'cssFloat';
133 		else
134 		{
135 			return cssName.replace( /-./g, function( match )
136 				{
137 					return match.substr( 1 ).toUpperCase();
138 				});
139 		}
140 	},
141
142 	/**
143 	 * Replace special HTML characters in a string with their relative HTML
144 	 * entity values.
145 	 * @param {String} text The string to be encoded.
146 	 * @returns {String} The encode string.
147 	 * @example
148 	 * alert( CKEDITOR.tools.htmlEncode( 'A > B & C < D' ) );  // "A &gt; B &amp; C &lt; D"
149 	 */
150 	htmlEncode : function( text )
151 	{
152 		var standard = function( text )
153 		{
154 			var span = new CKEDITOR.dom.element( 'span' );
155 			span.setText( text );
156 			return span.getHtml();
157 		};
158
159 		this.htmlEncode = ( standard( '>' ) == '>' ) ?
160 			function( text )
161 			{
162 				// WebKit does't encode the ">" character, which makes sense, but
163 				// it's different than other browsers.
164 				return standard( text ).replace( />/g, '>' );
165 			} :
166 			standard;
167
168 		return this.htmlEncode( text );
169 	},
170
171 	/**
172 	 * Gets a unique number for this CKEDITOR execution session. It returns
173 	 * progressive numbers starting at 1.
174 	 * @returns {Number} A unique number.
175 	 */
176 	getNextNumber : (function()
177 	{
178 		var last = 0;
179 		return function()
180 		{
181 			return ++last;
182 		};
183 	})()
184 };
185