public/ckeditor/_source/core/htmlparser.js
function( html )
		{
			var parts,
				tagName,
				nextIndex = 0,
				cdata;	// The collected data inside a CDATA section.

			while ( ( parts = this._.htmlPartsRegex.exec( html ) ) )
			{
				var tagIndex = parts.index;
				if ( tagIndex > nextIndex )
				{
					var text = html.substring( nextIndex, tagIndex );

					if ( cdata )
						cdata.push( text );
					else
						this.onText( text );
				}

				nextIndex = this._.htmlPartsRegex.lastIndex;

				/*
				 "parts" is an array with the following items:
					0 : The entire match for opening/closing tags and comments.
					1 : Group filled with the tag name for closing tags.
					2 : Group filled with the comment text.
					3 : Group filled with the tag name for opening tags.
					4 : Group filled with the attributes part of opening tags.
				 */

				// Closing tag
				if ( ( tagName = parts[ 1 ] ) )
				{
					tagName = tagName.toLowerCase();

					if ( cdata && CKEDITOR.dtd.$cdata[ tagName ] )
					{
						// Send the CDATA data.
						this.onCDATA( cdata.join('') );
						cdata = null;
					}

					if ( !cdata )
					{
						this.onTagClose( tagName );
						continue;
					}
				}

				// If CDATA is enabled, just save the raw match.
				if ( cdata )
				{
					cdata.push( parts[ 0 ] );
					continue;
				}

				// Opening tag
				if ( ( tagName = parts[ 3 ] ) )
				{
					tagName = tagName.toLowerCase();

					// There are some tag names that can break things, so let's
					// simply ignore them when parsing. (#5224)
					if ( /="/.test( tagName ) )
						continue;

					var attribs = {},
						attribMatch,
						attribsPart = parts[ 4 ],
						selfClosing = !!( attribsPart && attribsPart.charAt( attribsPart.length - 1 ) == '/' );

					if ( attribsPart )
					{
						while ( ( attribMatch = attribsRegex.exec( attribsPart ) ) )
						{
							var attName = attribMatch[1].toLowerCase(),
								attValue = attribMatch[2] || attribMatch[3] || attribMatch[4] || '';

							if ( !attValue && emptyAttribs[ attName ] )
								attribs[ attName ] = attName;
							else
								attribs[ attName ] = attValue;
						}
					}

					this.onTagOpen( tagName, attribs, selfClosing );

					// Open CDATA mode when finding the appropriate tags.
					if ( !cdata && CKEDITOR.dtd.$cdata[ tagName ] )
						cdata = [];

					continue;
				}

				// Comment
				if ( ( tagName = parts[ 2 ] ) )
					this.onComment( tagName );
			}

			if ( html.length > nextIndex )
				this.onText( html.substring( nextIndex, html.length ) );
		}
function( html )
		{
			var parts,
				tagName,
				nextIndex = 0,
				cdata;	// The collected data inside a CDATA section.

			while ( ( parts = this._.htmlPartsRegex.exec( html ) ) )
			{
				var tagIndex = parts.index;
				if ( tagIndex > nextIndex )
				{
					var text = html.substring( nextIndex, tagIndex );

					if ( cdata )
						cdata.push( text );
					else
						this.onText( text );
				}

				nextIndex = this._.htmlPartsRegex.lastIndex;

				/*
				 "parts" is an array with the following items:
					0 : The entire match for opening/closing tags and comments.
					1 : Group filled with the tag name for closing tags.
					2 : Group filled with the comment text.
					3 : Group filled with the tag name for opening tags.
					4 : Group filled with the attributes part of opening tags.
				 */

				// Closing tag
				if ( ( tagName = parts[ 1 ] ) )
				{
					tagName = tagName.toLowerCase();

					if ( cdata && CKEDITOR.dtd.$cdata[ tagName ] )
					{
						// Send the CDATA data.
						this.onCDATA( cdata.join('') );
						cdata = null;
					}

					if ( !cdata )
					{
						this.onTagClose( tagName );
						continue;
					}
				}

				// If CDATA is enabled, just save the raw match.
				if ( cdata )
				{
					cdata.push( parts[ 0 ] );
					continue;
				}

				// Opening tag
				if ( ( tagName = parts[ 3 ] ) )
				{
					tagName = tagName.toLowerCase();

					// There are some tag names that can break things, so let's
					// simply ignore them when parsing. (#5224)
					if ( /="/.test( tagName ) )
						continue;

					var attribs = {},
						attribMatch,
						attribsPart = parts[ 4 ],
						selfClosing = !!( attribsPart && attribsPart.charAt( attribsPart.length - 1 ) == '/' );

					if ( attribsPart )
					{
						while ( ( attribMatch = attribsRegex.exec( attribsPart ) ) )
						{
							var attName = attribMatch[1].toLowerCase(),
								attValue = attribMatch[2] || attribMatch[3] || attribMatch[4] || '';

							if ( !attValue && emptyAttribs[ attName ] )
								attribs[ attName ] = attName;
							else
								attribs[ attName ] = attValue;
						}
					}

					this.onTagOpen( tagName, attribs, selfClosing );

					// Open CDATA mode when finding the appropriate tags.
					if ( !cdata && CKEDITOR.dtd.$cdata[ tagName ] )
						cdata = [];

					continue;
				}

				// Comment
				if ( ( tagName = parts[ 2 ] ) )
					this.onComment( tagName );
			}

			if ( html.length > nextIndex )
				this.onText( html.substring( nextIndex, html.length ) );
		}
function ( html ) { var parts , tagName , nextIndex = 0 , cdata ; // The collected data inside a CDATA section.
 while ( ( parts = this . _ . htmlPartsRegex . exec ( html ) ) ) { var tagIndex = parts . index ; if ( tagIndex > nextIndex ) { var text = html . substring ( nextIndex , tagIndex ) ; if ( cdata ) cdata . push ( text ) ; else this . onText ( text ) ; } nextIndex = this . _ . htmlPartsRegex . lastIndex ; /*
				 "parts" is an array with the following items:
					0 : The entire match for opening/closing tags and comments.
					1 : Group filled with the tag name for closing tags.
					2 : Group filled with the comment text.
					3 : Group filled with the tag name for opening tags.
					4 : Group filled with the attributes part of opening tags.
				 */ // Closing tag
 if ( ( tagName = parts [ 1 ] ) ) { tagName = tagName . toLowerCase ( ) ; if ( cdata && CKEDITOR . dtd . $cdata [ tagName ] ) { // Send the CDATA data.
 this . onCDATA ( cdata . join ( '' ) ) ; cdata = null ; } if ( ! cdata ) { this . onTagClose ( tagName ) ; continue ; } } // If CDATA is enabled, just save the raw match.
 if ( cdata ) { cdata . push ( parts [ 0 ] ) ; continue ; } // Opening tag
 if ( ( tagName = parts [ 3 ] ) ) { tagName = tagName . toLowerCase ( ) ; // There are some tag names that can break things, so let's
 // simply ignore them when parsing. (#5224)
 if ( / =" / . test ( tagName ) ) continue ; var attribs = { } , attribMatch , attribsPart = parts [ 4 ] , selfClosing = ! ! ( attribsPart && attribsPart . charAt ( attribsPart . length - 1 ) == '/' ) ; if ( attribsPart ) { while ( ( attribMatch = attribsRegex . exec ( attribsPart ) ) ) { var attName = attribMatch [ 1 ] . toLowerCase ( ) , attValue = attribMatch [ 2 ] || attribMatch [ 3 ] || attribMatch [ 4 ] || '' ; if ( ! attValue && emptyAttribs [ attName ] ) attribs [ attName ] = attName ; else attribs [ attName ] = attValue ; } } this . onTagOpen ( tagName , attribs , selfClosing ) ; // Open CDATA mode when finding the appropriate tags.
 if ( ! cdata && CKEDITOR . dtd . $cdata [ tagName ] ) cdata = [ ] ; continue ; } // Comment
 if ( ( tagName = parts [ 2 ] ) ) this . onComment ( tagName ) ; } if ( html . length > nextIndex ) this . onText ( html . substring ( nextIndex , html . length ) ) ; }
Parses text, looking for HTML tokens, like tag openers or closers,
or comments. This function fires the onTagOpen, onTagClose, onText
and onComment function during its execution.
@param {String} html The HTML to be parsed.
@example
var parser = new CKEDITOR.htmlParser();
// The onTagOpen, onTagClose, onText and onComment should be overriden
// at this point.
parser.parse( "&lt;!-- Example --&gt;&lt;b&gt;Hello&lt;/b&gt;" );
Parses text looking for HTML tokens like tag openers or closers or comments . This function fires the onTagOpen onTagClose onText and onComment function during its execution .