1 /*
  2 Copyright (c) 2003-2012, 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.dom.document} class, which
  8  *		represents a DOM document.
  9  */
 10 
 11 /**
 12  * Represents a DOM document.
 13  * @constructor
 14  * @augments CKEDITOR.dom.domObject
 15  * @param {Object} domDocument A native DOM document.
 16  * @example
 17  * var document = new CKEDITOR.dom.document( document );
 18  */
 19 CKEDITOR.dom.document = function( domDocument )
 20 {
 21 	CKEDITOR.dom.domObject.call( this, domDocument );
 22 };
 23 
 24 // PACKAGER_RENAME( CKEDITOR.dom.document )
 25 
 26 CKEDITOR.dom.document.prototype = new CKEDITOR.dom.domObject();
 27 
 28 CKEDITOR.tools.extend( CKEDITOR.dom.document.prototype,
 29 	/** @lends CKEDITOR.dom.document.prototype */
 30 	{
 31 		/**
 32 		 * Appends a CSS file to the document.
 33 		 * @param {String} cssFileUrl The CSS file URL.
 34 		 * @example
 35 		 * <b>CKEDITOR.document.appendStyleSheet( '/mystyles.css' )</b>;
 36 		 */
 37 		appendStyleSheet : function( cssFileUrl )
 38 		{
 39 			if ( this.$.createStyleSheet )
 40 				this.$.createStyleSheet( cssFileUrl );
 41 			else
 42 			{
 43 				var link = new CKEDITOR.dom.element( 'link' );
 44 				link.setAttributes(
 45 					{
 46 						rel		:'stylesheet',
 47 						type	: 'text/css',
 48 						href	: cssFileUrl
 49 					});
 50 
 51 				this.getHead().append( link );
 52 			}
 53 		},
 54 
 55 		appendStyleText : function( cssStyleText )
 56 		{
 57 			if ( this.$.createStyleSheet )
 58 			{
 59 				var styleSheet = this.$.createStyleSheet( "" );
 60 				styleSheet.cssText = cssStyleText ;
 61 			}
 62 			else
 63 			{
 64 				var style = new CKEDITOR.dom.element( 'style', this );
 65 				style.append( new CKEDITOR.dom.text( cssStyleText, this ) );
 66 				this.getHead().append( style );
 67 			}
 68 		},
 69 
 70 		createElement : function( name, attribsAndStyles )
 71 		{
 72 			var element = new CKEDITOR.dom.element( name, this );
 73 
 74 			if ( attribsAndStyles )
 75 			{
 76 				if ( attribsAndStyles.attributes )
 77 					element.setAttributes( attribsAndStyles.attributes );
 78 
 79 				if ( attribsAndStyles.styles )
 80 					element.setStyles( attribsAndStyles.styles );
 81 			}
 82 
 83 			return element;
 84 		},
 85 
 86 		createText : function( text )
 87 		{
 88 			return new CKEDITOR.dom.text( text, this );
 89 		},
 90 
 91 		focus : function()
 92 		{
 93 			this.getWindow().focus();
 94 		},
 95 
 96 		/**
 97 		 * Gets and element based on its id.
 98 		 * @param {String} elementId The element id.
 99 		 * @returns {CKEDITOR.dom.element} The element instance, or null if not found.
100 		 * @example
101 		 * var element = <b>CKEDITOR.document.getById( 'myElement' )</b>;
102 		 * alert( element.getId() );  // "myElement"
103 		 */
104 		getById : function( elementId )
105 		{
106 			var $ = this.$.getElementById( elementId );
107 			return $ ? new CKEDITOR.dom.element( $ ) : null;
108 		},
109 
110 		getByAddress : function( address, normalized )
111 		{
112 			var $ = this.$.documentElement;
113 
114 			for ( var i = 0 ; $ && i < address.length ; i++ )
115 			{
116 				var target = address[ i ];
117 
118 				if ( !normalized )
119 				{
120 					$ = $.childNodes[ target ];
121 					continue;
122 				}
123 
124 				var currentIndex = -1;
125 
126 				for (var j = 0 ; j < $.childNodes.length ; j++ )
127 				{
128 					var candidate = $.childNodes[ j ];
129 
130 					if ( normalized === true &&
131 							candidate.nodeType == 3 &&
132 							candidate.previousSibling &&
133 							candidate.previousSibling.nodeType == 3 )
134 					{
135 						continue;
136 					}
137 
138 					currentIndex++;
139 
140 					if ( currentIndex == target )
141 					{
142 						$ = candidate;
143 						break;
144 					}
145 				}
146 			}
147 
148 			return $ ? new CKEDITOR.dom.node( $ ) : null;
149 		},
150 
151 		getElementsByTag : function( tagName, namespace )
152 		{
153 			if ( !( CKEDITOR.env.ie && ! ( document.documentMode > 8 ) ) && namespace )
154 				tagName = namespace + ':' + tagName;
155 			return new CKEDITOR.dom.nodeList( this.$.getElementsByTagName( tagName ) );
156 		},
157 
158 		/**
159 		 * Gets the <head> element for this document.
160 		 * @returns {CKEDITOR.dom.element} The <head> element.
161 		 * @example
162 		 * var element = <b>CKEDITOR.document.getHead()</b>;
163 		 * alert( element.getName() );  // "head"
164 		 */
165 		getHead : function()
166 		{
167 			var head = this.$.getElementsByTagName( 'head' )[0];
168 			if ( !head )
169 				head = this.getDocumentElement().append( new CKEDITOR.dom.element( 'head' ), true );
170 			else
171 			head = new CKEDITOR.dom.element( head );
172 
173 			return (
174 			this.getHead = function()
175 				{
176 					return head;
177 				})();
178 		},
179 
180 		/**
181 		 * Gets the <body> element for this document.
182 		 * @returns {CKEDITOR.dom.element} The <body> element.
183 		 * @example
184 		 * var element = <b>CKEDITOR.document.getBody()</b>;
185 		 * alert( element.getName() );  // "body"
186 		 */
187 		getBody : function()
188 		{
189 			var body = new CKEDITOR.dom.element( this.$.body );
190 
191 			return (
192 			this.getBody = function()
193 				{
194 					return body;
195 				})();
196 		},
197 
198 		/**
199 		 * Gets the DOM document element for this document.
200 		 * @returns {CKEDITOR.dom.element} The DOM document element.
201 		 */
202 		getDocumentElement : function()
203 		{
204 			var documentElement = new CKEDITOR.dom.element( this.$.documentElement );
205 
206 			return (
207 			this.getDocumentElement = function()
208 				{
209 					return documentElement;
210 				})();
211 		},
212 
213 		/**
214 		 * Gets the window object that holds this document.
215 		 * @returns {CKEDITOR.dom.window} The window object.
216 		 */
217 		getWindow : function()
218 		{
219 			var win = new CKEDITOR.dom.window( this.$.parentWindow || this.$.defaultView );
220 
221 			return (
222 			this.getWindow = function()
223 				{
224 					return win;
225 				})();
226 		},
227 
228 		/**
229 		 * Defines the document contents through document.write. Note that the
230 		 * previous document contents will be lost (cleaned).
231 		 * @since 3.5
232 		 * @param {String} html The HTML defining the document contents.
233 		 * @example
234 		 * document.write(
235 		 *     '<html>' +
236 		 *         '<head><title>Sample Doc</title></head>' +
237 		 *         '<body>Document contents created by code</body>' +
238 		 *      '</html>' );
239 		 */
240 		write : function( html )
241 		{
242 			// Don't leave any history log in IE. (#5657)
243 			this.$.open( 'text/html', 'replace' );
244 
245 			// Support for custom document.domain in IE.
246 			CKEDITOR.env.isCustomDomain() &&  ( this.$.domain = document.domain );
247 
248 			this.$.write( html );
249 			this.$.close();
250 		}
251 	});
252