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 (function()
  7 {
  8 	var cssStyle = CKEDITOR.htmlParser.cssStyle,
  9 			cssLength = CKEDITOR.tools.cssLength;
 10 
 11 	var cssLengthRegex = /^((?:\d*(?:\.\d+))|(?:\d+))(.*)?$/i;
 12 
 13 	/*
 14 	 * Replacing the former CSS length value with the later one, with
 15 	 * adjustment to the length  unit.
 16 	 */
 17 	function replaceCssLength( length1, length2 )
 18 	{
 19 		var parts1 = cssLengthRegex.exec( length1 ),
 20 				parts2 = cssLengthRegex.exec( length2 );
 21 
 22 		// Omit pixel length unit when necessary,
 23 		// e.g. replaceCssLength( 10, '20px' ) -> 20
 24 		if ( parts1 )
 25 		{
 26 			if ( !parts1[ 2 ] && parts2[ 2 ] == 'px' )
 27 				return parts2[ 1 ];
 28 			if ( parts1[ 2 ] == 'px' && !parts2[ 2 ] )
 29 				return parts2[ 1 ] + 'px';
 30 		}
 31 
 32 		return length2;
 33 	}
 34 
 35 	var htmlFilterRules =
 36 	{
 37 		elements :
 38 		{
 39 			$ : function( element )
 40 			{
 41 				var attributes = element.attributes,
 42 					realHtml = attributes && attributes[ 'data-cke-realelement' ],
 43 					realFragment = realHtml && new CKEDITOR.htmlParser.fragment.fromHtml( decodeURIComponent( realHtml ) ),
 44 					realElement = realFragment && realFragment.children[ 0 ];
 45 
 46 				// Width/height in the fake object are subjected to clone into the real element.
 47 				if ( realElement && element.attributes[ 'data-cke-resizable' ] )
 48 				{
 49 					var styles = new cssStyle( element ).rules,
 50 						realAttrs = realElement.attributes,
 51 						width = styles.width,
 52 						height = styles.height;
 53 
 54 					width && ( realAttrs.width = replaceCssLength( realAttrs.width, width ) );
 55 					height && ( realAttrs.height = replaceCssLength( realAttrs.height, height ) );
 56 				}
 57 
 58 				return realElement;
 59 			}
 60 		}
 61 	};
 62 
 63 	CKEDITOR.plugins.add( 'fakeobjects',
 64 	{
 65 		requires : [ 'htmlwriter' ],
 66 
 67 		afterInit : function( editor )
 68 		{
 69 			var dataProcessor = editor.dataProcessor,
 70 				htmlFilter = dataProcessor && dataProcessor.htmlFilter;
 71 
 72 			if ( htmlFilter )
 73 				htmlFilter.addRules( htmlFilterRules );
 74 		}
 75 	});
 76 
 77 	CKEDITOR.editor.prototype.createFakeElement = function( realElement, className, realElementType, isResizable )
 78 	{
 79 		var lang = this.lang.fakeobjects,
 80 			label = lang[ realElementType ] || lang.unknown;
 81 
 82 		var attributes =
 83 		{
 84 			'class' : className,
 85 			src : CKEDITOR.getUrl( 'images/spacer.gif' ),
 86 			'data-cke-realelement' : encodeURIComponent( realElement.getOuterHtml() ),
 87 			'data-cke-real-node-type' : realElement.type,
 88 			alt : label,
 89 			title : label,
 90 			align : realElement.getAttribute( 'align' ) || ''
 91 		};
 92 
 93 		if ( realElementType )
 94 			attributes[ 'data-cke-real-element-type' ] = realElementType;
 95 
 96 		if ( isResizable )
 97 		{
 98 			attributes[ 'data-cke-resizable' ] = isResizable;
 99 
100 			var fakeStyle = new cssStyle();
101 
102 			var width = realElement.getAttribute( 'width' ),
103 				height = realElement.getAttribute( 'height' );
104 
105 			width && ( fakeStyle.rules.width = cssLength( width ) );
106 			height && ( fakeStyle.rules.height = cssLength( height ) );
107 			fakeStyle.populate( attributes );
108 		}
109 
110 		return this.document.createElement( 'img', { attributes : attributes } );
111 	};
112 
113 	CKEDITOR.editor.prototype.createFakeParserElement = function( realElement, className, realElementType, isResizable )
114 	{
115 		var lang = this.lang.fakeobjects,
116 			label = lang[ realElementType ] || lang.unknown,
117 			html;
118 
119 		var writer = new CKEDITOR.htmlParser.basicWriter();
120 		realElement.writeHtml( writer );
121 		html = writer.getHtml();
122 
123 		var attributes =
124 		{
125 			'class' : className,
126 			src : CKEDITOR.getUrl( 'images/spacer.gif' ),
127 			'data-cke-realelement' : encodeURIComponent( html ),
128 			'data-cke-real-node-type' : realElement.type,
129 			alt : label,
130 			title : label,
131 			align : realElement.attributes.align || ''
132 		};
133 
134 		if ( realElementType )
135 			attributes[ 'data-cke-real-element-type' ] = realElementType;
136 
137 		if ( isResizable )
138 		{
139 			attributes[ 'data-cke-resizable' ] = isResizable;
140 			var realAttrs = realElement.attributes,
141 				fakeStyle = new cssStyle();
142 
143 			var width = realAttrs.width,
144 				height = realAttrs.height;
145 
146 			width != undefined && ( fakeStyle.rules.width =  cssLength( width ) );
147 			height != undefined && ( fakeStyle.rules.height = cssLength ( height ) );
148 			fakeStyle.populate( attributes );
149 		}
150 
151 		return new CKEDITOR.htmlParser.element( 'img', attributes );
152 	};
153 
154 	CKEDITOR.editor.prototype.restoreRealElement = function( fakeElement )
155 	{
156 		if ( fakeElement.data( 'cke-real-node-type' ) != CKEDITOR.NODE_ELEMENT )
157 			return null;
158 
159 		var element = CKEDITOR.dom.element.createFromHtml(
160 			decodeURIComponent( fakeElement.data( 'cke-realelement' ) ),
161 			this.document );
162 
163 		if ( fakeElement.data( 'cke-resizable') )
164 		{
165 			var width = fakeElement.getStyle( 'width' ),
166 				height = fakeElement.getStyle( 'height' );
167 
168 			width && element.setAttribute( 'width', replaceCssLength( element.getAttribute( 'width' ), width ) );
169 			height && element.setAttribute( 'height', replaceCssLength( element.getAttribute( 'height' ), height ) );
170 		}
171 
172 		return element;
173 	};
174 
175 })();
176