This sample page demonstrates the idea of Advanced Content Filter (ACF), a sophisticated tool that takes control over what kind of data is accepted by the editor and what kind of output is produced.
ACF controls every single source of data that comes to the editor. It process both HTML that is inserted manually (i.e. pasted by the user) and programmatically like:
editor.setData( '<p>Hello world!</p>' );
ACF discards invalid, useless HTML tags and attributes so the editor remains "clean" during runtime. ACF behaviour can be configured and adjusted for a particular case to prevent the output HTML (i.e. in CMS systems) from being polluted. This kind of filtering is a first, client-side line of defense against "tag soups", the tool that precisely restricts which tags, attributes and styles are allowed (desired). When properly configured, ACF is an easy and fast way to produce a high-quality, intentionally filtered HTML.
			Advanced Content Filter is enabled by default, working in "automatic mode", yet
			it provides a set of easy rules that allow adjusting filtering rules
			and disabling the entire feature when necessary. The config property
			responsible for this feature is config.allowedContent.
		
			By "automatic mode" is meant that loaded plugins decide which kind
			of content is enabled and which is not. For example, if the link
			plugin is loaded it implies that <a> tag is
			automatically allowed. Each plugin is given a set
			of predefined ACF rules
			that control the editor until 
			config.allowedContent
			is defined manually.
		
			Let's assume our intention is to restrict the editor to accept (produce) paragraphs
			only: no attributes, no styles, no other tags.
			With ACF
			this is very simple. Basically set 
			config.allowedContent to 'p':
		
var editor = CKEDITOR.replace( textarea_id, {
	allowedContent: 'p'
} );
		Now try to play with allowed content:
// Trying to insert disallowed tag and attribute. editor.setData( '<p style="color: red">Hello <em>world</em>!</p>' ); alert( editor.getData() ); // Filtered data is returned. "<p>Hello world!</p>"
			What happened? Since config.allowedContent: 'p' is set the editor assumes
			that only plain <p> are accepted. Nothing more. This is why
			style attribute and <em> tag are gone. The same
			filtering would happen if we pasted disallowed HTML into this editor.
		
This is just a small sample of what ACF can do. To know more, please refer to the sample section below and the official Advanced Content Filter guide.
			You may, of course, want CKEditor to avoid filtering of any kind.
			To get rid of ACF,
			basically set 
			config.allowedContent to true like this:
		
CKEDITOR.replace( textarea_id, {
	allowedContent: true
} );
		
			ACF is far more than
			I/O control: the entire
			UI of the editor is adjusted to what
			filters restrict. For example: if <a> tag is
			disallowed
			by ACF,
			then accordingly link command, toolbar button and link dialog
			are also disabled. Editor is smart: it knows which features must be
			removed from the interface to match filtering rules.
		
			CKEditor can be far more specific. If <a> tag is
			allowed by filtering rules to be used but it is restricted
			to have only one attribute (href)
			config.allowedContent = 'a[!href]', then
			"Target" tab of the link dialog is automatically disabled as target
			attribute isn't included in ACF rules
			for <a>. This behaviour applies to dialog fields, context
			menus and toolbar buttons.
		
There are several editor instances below that present different ACF setups. All of them, except the inline instance, share the same HTML content to visualize how different filtering rules affect the same input data.
				This editor is using default configuration ("automatic mode"). It means that
				
				config.allowedContent is defined by loaded plugins.
				Each plugin extends filtering rules to make it's own associated content
				available for the user.
			
This editor is using a custom configuration for ACF:
CKEDITOR.replace( 'editor2', {
	allowedContent:
		'h1 h2 h3 p blockquote strong em;' +
		'a[!href];' +
		'img(left,right)[!src,alt,width,height];' +
		'table tr th td caption;' +
		'span{!font-family};' +'
		'span{!color};' +
		'span(!marker);' +
		'del ins'
} );
			The following rules may require additional explanation:
h1 h2 h3 p blockquote strong em - These tags
					are accepted by the editor. Any tag attributes will be discarded.
				a[!href] - href attribute is obligatory
					for <a> tag. Tags without this attribute
					are disarded. No other attribute will be accepted.
				img(left,right)[!src,alt,width,height] - src
					attribute is obligatory for <img> tag.
					alt, width, height
					and class attributes are accepted but
					class must be either class="left"
					or class="right"
				table tr th td caption - These tags
					are accepted by the editor. Any tag attributes will be discarded.
				span{!font-family}, span{!color},
					span(!marker) - <span> tags
					will be accepted if either font-family or
					color style is set or class="marker"
					is present.
				del ins - These tags
					are accepted by the editor. Any tag attributes will be discarded.
				
				Please note that UI of the
				editor is different. It's a response to what happened to the filters.
				Since text-align isn't allowed, the align toolbar is gone.
				The same thing happened to subscript/superscript, strike, underline
				(<u>, <sub>, <sup>
				are disallowed by 
				config.allowedContent) and many other buttons.
			
This editor is using a custom configuration for ACF. Note that filters can be configured as an object literal as an alternative to a string-based definition.
CKEDITOR.replace( 'editor3', {
	allowedContent: {
		'b i ul ol big small': true,
		'h1 h2 h3 p blockquote li': {
			styles: 'text-align'
		},
		a: { attributes: '!href,target' },
		img: {
			attributes: '!src,alt',
			styles: 'width,height',
			classes: 'left,right'
		}
	}
} );
		This editor is using a custom set of plugins and buttons.
CKEDITOR.replace( 'editor4', {
	removePlugins: 'bidi,font,forms,horizontalrule,iframe,justify,table,tabletools,smiley',
	removeButtons: 'Anchor,Underline,Strike,Subscript,Superscript,Image',
	format_tags: 'p;h1;h2;h3;pre;address'
} );
			
				As you can see, removing plugins and buttons implies filtering.
				Several tags are not allowed in the editor because there's no
				plugin/button that is responsible for creating and editing this
				kind of content (for example: the image is missing because
				of removeButtons: 'Image'). The conclusion is that
				ACF works "backwards"
				as well: modifying UI
				elements is changing allowed content rules.
			
				This editor is built on editable <h1> element.
				ACF takes care of
				what can be included in <h1>. Note that there
				are no block styles in Styles combo. Also why lists, indentation,
				blockquote, div, form and other buttons are missing.
			
				ACF makes sure that
				no disallowed tags will come to <h1> so the final
				markup is valid. If the user tried to paste some invalid HTML
				into this editor (let's say a list), it would be automatically
				converted into plain text.
			
				This editor is using a custom configuration for ACF.
				It's using the 
				Disallowed Content property of the filter to eliminate all title attributes.
			
CKEDITOR.replace( 'editor6', {
	allowedContent: {
		'b i ul ol big small': true,
		'h1 h2 h3 p blockquote li': {
			styles: 'text-align'
		},
		a: {attributes: '!href,target'},
		img: {
			attributes: '!src,alt',
			styles: 'width,height',
			classes: 'left,right'
		}
	},
	disallowedContent: '*{title*}'
} );
		
				This editor is using a custom configuration for ACF.
				It's using the 
				Disallowed Content property of the filter to eliminate all a and img tags,
				while allowing all other tags.
			
CKEDITOR.replace( 'editor7', {
	allowedContent: {
		// Allow all content.
		$1: {
			elements: CKEDITOR.dtd,
			attributes: true,
			styles: true,
			classes: true
		}
	},
	disallowedContent: 'img a'
} );