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 (function()
  7 {
  8 	var defaultDataFilterRules =
  9 	{
 10 		elementNames :
 11 		[
 12 			// Elements that cause problems in wysiwyg mode.
 13 			[ /^(object|embed|param)$/, 'cke:$1' ]
 14 		],
 15
 16 		attributeNames :
 17 		[
 18 			// Event attributes (onXYZ) must not be directly set. They can become
 19 			// active in the editing area (IE|WebKit).
 20 			[ /^on/, '_cke_pa_on' ]
 21 		]
 22 	};
 23
 24 	var defaultHtmlFilterRules =
 25 		{
 26 			elementNames :
 27 			[
 28 				// Remove the "cke:" namespace prefix.
 29 				[ /^cke:/, '' ],
 30
 31 				// Ignore <?xml:namespace> tags.
 32 				[ /^\?xml:namespace$/, '' ]
 33 			],
 34
 35 			attributeNames :
 36 			[
 37 				// Attributes saved for changes and protected attributes.
 38 				[ /^_cke_(saved|pa)_/, '' ],
 39
 40 				// All "_cke" attributes are to be ignored.
 41 				[ /^_cke.*/, '' ]
 42 			],
 43
 44 			elements :
 45 			{
 46 				embed : function( element )
 47 				{
 48 					var parent = element.parent;
 49
 50 					// If the <embed> is child of a <object>, copy the width
 51 					// and height attributes from it.
 52 					if ( parent && parent.name == 'object' )
 53 					{
 54 						element.attributes.width = parent.attributes.width;
 55 						element.attributes.height = parent.attributes.height;
 56 					}
 57 				},
 58
 59 				img : function( element )
 60 				{
 61 					var attribs = element.attributes;
 62
 63 					if ( attribs._cke_saved_src )
 64 						delete attribs.src;
 65 				},
 66
 67 				a : function( element )
 68 				{
 69 					var attribs = element.attributes;
 70
 71 					if ( attribs._cke_saved_href )
 72 						delete attribs.href;
 73 				}
 74 			},
 75
 76 			attributes :
 77 			{
 78 				'class' : function( value, element )
 79 				{
 80 					// Remove all class names starting with "cke_".
 81 					return CKEDITOR.tools.ltrim( value.replace( /(?:^|\s+)cke_[^\s]*/g, '' ) ) || false;
 82 				}
 83 			}
 84 		};
 85
 86 	if ( CKEDITOR.env.ie )
 87 	{
 88 		// IE outputs style attribute in capital letters. We should convert
 89 		// them back to lower case.
 90 		defaultHtmlFilterRules.attributes.style = function( value, element )
 91 		{
 92 			return value.toLowerCase();
 93 		}
 94 	}
 95
 96 	var protectUrlTagRegex = /<(?:a|area|img).*?\s((?:href|src)\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|(?:[^ "'>]+)))/gi;
 97
 98 	function protectUrls( html )
 99 	{
100 		return html.replace( protectUrlTagRegex, '$& _cke_saved_$1' );
101 	};
102
103 	CKEDITOR.plugins.add( 'htmldataprocessor',
104 	{
105 		requires : [ 'htmlwriter' ],
106
107 		init : function( editor )
108 		{
109 			var dataProcessor = editor.dataProcessor = new CKEDITOR.htmlDataProcessor();
110
111 			dataProcessor.writer.forceSimpleAmpersand = editor.config.forceSimpleAmpersand;
112
113 			dataProcessor.dataFilter.addRules( defaultDataFilterRules );
114 			dataProcessor.htmlFilter.addRules( defaultHtmlFilterRules );
115 		}
116 	});
117
118 	CKEDITOR.htmlDataProcessor = function()
119 	{
120 		this.writer = new CKEDITOR.htmlWriter();
121 		this.dataFilter = new CKEDITOR.htmlParser.filter();
122 		this.htmlFilter = new CKEDITOR.htmlParser.filter();
123 	};
124
125 	CKEDITOR.htmlDataProcessor.prototype =
126 	{
127 		toHtml : function( data, fixForBody )
128 		{
129 			// The source data is already HTML, but we need to clean
130 			// it up and apply the filter.
131
132 			// Before anything, we must protect the URL attributes as the
133 			// browser may changing them when setting the innerHTML later in
134 			// the code.
135 			data = protectUrls( data );
136
137 			// Call the browser to help us fixing a possibly invalid HTML
138 			// structure.
139 			var div = document.createElement( 'div' );
140 			div.innerHTML = data;
141
142 			// Now use our parser to make further fixes to the structure, as
143 			// well as apply the filter.
144 			var fragment = CKEDITOR.htmlParser.fragment.fromHtml( div.innerHTML, fixForBody ),
145 				writer = new CKEDITOR.htmlParser.basicWriter();
146
147 			fragment.writeHtml( writer, this.dataFilter );
148
149 			return writer.getHtml( true );
150 		},
151
152 		toDataFormat : function( html, fixForBody )
153 		{
154 			var writer = this.writer,
155 				fragment = CKEDITOR.htmlParser.fragment.fromHtml( html, fixForBody );
156
157 			writer.reset();
158
159 			fragment.writeHtml( writer, this.htmlFilter );
160
161 			return writer.getHtml( true );
162 		}
163 	};
164 })();
165
166 CKEDITOR.config.forceSimpleAmpersand = false;
167