text: ﻿/**
   * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
   * For licensing, see LICENSE.md or http://ckeditor.com/license
   */
  
  CKEDITOR.plugins.add( 'htmlwriter', {
  	init: function( editor ) {
  		var writer = new CKEDITOR.htmlWriter();
  
  		writer.forceSimpleAmpersand = editor.config.forceSimpleAmpersand;
  		writer.indentationChars = editor.config.dataIndentationChars || '\t';
  
  		// Overwrite default basicWriter initialized in hmtlDataProcessor constructor.
  		editor.dataProcessor.writer = writer;
  	}
  } );
  
  /**
   * The class used to write HTML data.
   *
   *		var writer = new CKEDITOR.htmlWriter();
   *		writer.openTag( 'p' );
   *		writer.attribute( 'class', 'MyClass' );
   *		writer.openTagClose( 'p' );
   *		writer.text( 'Hello' );
   *		writer.closeTag( 'p' );
   *		alert( writer.getHtml() ); // '<p class="MyClass">Hello</p>'
   *
   * @class
   * @extends CKEDITOR.htmlParser.basicWriter
   */
  CKEDITOR.htmlWriter = CKEDITOR.tools.createClass( {
  	base: CKEDITOR.htmlParser.basicWriter,
  
  	/**
  	 * Creates an `htmlWriter` class instance.
  	 *
  	 * @constructor
  	 */
  	$: function() {
  		// Call the base contructor.
  		this.base();
  
  		/**
  		 * The characters to be used for each indentation step.
  		 *
  		 *		// Use tab for indentation.
  		 *		editorInstance.dataProcessor.writer.indentationChars = '\t';
  		 */
  		this.indentationChars = '\t';
  
  		/**
  		 * The characters to be used to close "self-closing" elements, like `<br>` or `<img>`.
  		 *
  		 *		// Use HTML4 notation for self-closing elements.
  		 *		editorInstance.dataProcessor.writer.selfClosingEnd = '>';
  		 */
  		this.selfClosingEnd = ' />';
  
  		/**
  		 * The characters to be used for line breaks.
  		 *
  		 *		// Use CRLF for line breaks.
  		 *		editorInstance.dataProcessor.writer.lineBreakChars = '\r\n';
  		 */
  		this.lineBreakChars = '\n';
  
  		this.sortAttributes = 1;
  
  		this._.indent = 0;
  		this._.indentation = '';
  		// Indicate preformatted block context status. (#5789)
  		this._.inPre = 0;
  		this._.rules = {};
  
  		var dtd = CKEDITOR.dtd;
  
  		for ( var e in CKEDITOR.tools.extend( {}, dtd.$nonBodyContent, dtd.$block, dtd.$listItem, dtd.$tableContent ) ) {
  			this.setRules( e, {
  				indent: !dtd[ e ][ '#' ],
  				breakBeforeOpen: 1,
  				breakBeforeClose: !dtd[ e ][ '#' ],
  				breakAfterClose: 1,
  				needsSpace: ( e in dtd.$block ) && !( e in { li: 1, dt: 1, dd: 1 } )
  			} );
  		}
  
  		this.setRules( 'br', { breakAfterOpen: 1 } );
  
  		this.setRules( 'title', {
  			indent: 0,
  			breakAfterOpen: 0
  		} );
  
  		this.setRules( 'style', {
  			indent: 0,
  			breakBeforeClose: 1
  		} );
  
  		this.setRules( 'pre', {
  			breakAfterOpen: 1, // Keep line break after the opening tag
  			indent: 0 // Disable indentation on <pre>.
  		} );
  	},
  
  	proto: {
  		/**
  		 * Writes the tag opening part for an opener tag.
  		 *
  		 *		// Writes '<p'.
  		 *		writer.openTag( 'p', { class : 'MyClass', id : 'MyId' } );
  		 *
  		 * @param {String} tagName The element name for this tag.
  		 * @param {Object} attributes The attributes defined for this tag. The
  		 * attributes could be used to inspect the tag.
  		 */
  		openTag: function( tagName ) {
  			var rules = this._.rules[ tagName ];
  
  			if ( this._.afterCloser && rules && rules.needsSpace && this._.needsSpace )
  				this._.output.push( '\n' );
  
  			if ( this._.indent )
  				this.indentation();
  			// Do not break if indenting.
  			else if ( rules && rules.breakBeforeOpen ) {
  				this.lineBreak();
  				this.indentation();
  			}
  
  			this._.output.push( '<', tagName );
  
  			this._.afterCloser = 0;
  		},
  
  		/**
  		 * Writes the tag closing part for an opener tag.
  		 *
  		 *		// Writes '>'.
  		 *		writer.openTagClose( 'p', false );
  		 *
  		 *		// Writes ' />'.
  		 *		writer.openTagClose( 'br', true );
  		 *
  		 * @param {String} tagName The element name for this tag.
  		 * @param {Boolean} isSelfClose Indicates that this is a self-closing tag,
  		 * like `<br>` or `<img>`.
  		 */
  		openTagClose: function( tagName, isSelfClose ) {
  			var rules = this._.rules[ tagName ];
  
  			if ( isSelfClose ) {
  				this._.output.push( this.selfClosingEnd );
  
  				if ( rules && rules.breakAfterClose )
  					this._.needsSpace = rules.needsSpace;
  			} else {
  				this._.output.push( '>' );
  
  				if ( rules && rules.indent )
  					this._.indentation += this.indentationChars;
  			}
  
  			if ( rules && rules.breakAfterOpen )
  				this.lineBreak();
  			tagName == 'pre' && ( this._.inPre = 1 );
  		},
  
  		/**
  		 * Writes an attribute. This function should be called after opening the
  		 * tag with {@link #openTagClose}.
  		 *
  		 *		// Writes ' class="MyClass"'.
  		 *		writer.attribute( 'class', 'MyClass' );
  		 *
  		 * @param {String} attName The attribute name.
  		 * @param {String} attValue The attribute value.
  		 */
  		attribute: function( attName, attValue ) {
  
  			if ( typeof attValue == 'string' ) {
  				this.forceSimpleAmpersand && ( attValue = attValue.replace( /&amp;/g, '&' ) );
  				// Browsers don't always escape special character in attribute values. (#4683, #4719).
  				attValue = CKEDITOR.tools.htmlEncodeAttr( attValue );
  			}
  
  			this._.output.push( ' ', attName, '="', attValue, '"' );
  		},
  
  		/**
  		 * Writes a closer tag.
  		 *
  		 *		// Writes '</p>'.
  		 *		writer.closeTag( 'p' );
  		 *
  		 * @param {String} tagName The element name for this tag.
  		 */
  		closeTag: function( tagName ) {
  			var rules = this._.rules[ tagName ];
  
  			if ( rules && rules.indent )
  				this._.indentation = this._.indentation.substr( this.indentationChars.length );
  
  			if ( this._.indent )
  				this.indentation();
  			// Do not break if indenting.
  			else if ( rules && rules.breakBeforeClose ) {
  				this.lineBreak();
  				this.indentation();
  			}
  
  			this._.output.push( '</', tagName, '>' );
  			tagName == 'pre' && ( this._.inPre = 0 );
  
  			if ( rules && rules.breakAfterClose ) {
  				this.lineBreak();
  				this._.needsSpace = rules.needsSpace;
  			}
  
  			this._.afterCloser = 1;
  		},
  
  		/**
  		 * Writes text.
  		 *
  		 *		// Writes 'Hello Word'.
  		 *		writer.text( 'Hello Word' );
  		 *
  		 * @param {String} text The text value
  		 */
  		text: function( text ) {
  			if ( this._.indent ) {
  				this.indentation();
  				!this._.inPre && ( text = CKEDITOR.tools.ltrim( text ) );
  			}
  
  			this._.output.push( text );
  		},
  
  		/**
  		 * Writes a comment.
  		 *
  		 *		// Writes "<!-- My comment -->".
  		 *		writer.comment( ' My comment ' );
  		 *
  		 * @param {String} comment The comment text.
  		 */
  		comment: function( comment ) {
  			if ( this._.indent )
  				this.indentation();
  
  			this._.output.push( '<!--', comment, '-->' );
  		},
  
  		/**
  		 * Writes a line break. It uses the {@link #lineBreakChars} property for it.
  		 *
  		 *		// Writes '\n' (e.g.).
  		 *		writer.lineBreak();
  		 */
  		lineBreak: function() {
  			if ( !this._.inPre && this._.output.length > 0 )
  				this._.output.push( this.lineBreakChars );
  			this._.indent = 1;
  		},
  
  		/**
  		 * Writes the current indentation character. It uses the {@link #indentationChars}
  		 * property, repeating it for the current indentation steps.
  		 *
  		 *		// Writes '\t' (e.g.).
  		 *		writer.indentation();
  		 */
  		indentation: function() {
  			if ( !this._.inPre && this._.indentation )
  				this._.output.push( this._.indentation );
  			this._.indent = 0;
  		},
  
  		/**
  		 * Empties the current output buffer. It also brings back the default
  		 * values of the writer flags.
  		 *
  		 *		writer.reset();
  		 */
  		reset: function() {
  			this._.output = [];
  			this._.indent = 0;
  			this._.indentation = '';
  			this._.afterCloser = 0;
  			this._.inPre = 0;
  			this._.needsSpace = 0;
  		},
  
  		/**
  		 * Sets formatting rules for a given element. Possible rules are:
  		 *
  		 * * `indent` &ndash; indent the element content.
  		 * * `breakBeforeOpen` &ndash; break line before the opener tag for this element.
  		 * * `breakAfterOpen` &ndash; break line after the opener tag for this element.
  		 * * `breakBeforeClose` &ndash; break line before the closer tag for this element.
  		 * * `breakAfterClose` &ndash; break line after the closer tag for this element.
  		 *
  		 * All rules default to `false`. Each function call overrides rules that are
  		 * already present, leaving the undefined ones untouched.
  		 *
  		 * By default, all elements available in the {@link CKEDITOR.dtd#$block},
  		 * {@link CKEDITOR.dtd#$listItem}, and {@link CKEDITOR.dtd#$tableContent}
  		 * lists have all the above rules set to `true`. Additionaly, the `<br>`
  		 * element has the `breakAfterOpen` rule set to `true`.
  		 *
  		 *		// Break line before and after "img" tags.
  		 *		writer.setRules( 'img', {
  		 *			breakBeforeOpen: true
  		 *			breakAfterOpen: true
  		 *		} );
  		 *
  		 *		// Reset the rules for the "h1" tag.
  		 *		writer.setRules( 'h1', {} );
  		 *
  		 * @param {String} tagName The name of the element for which the rules are set.
  		 * @param {Object} rules An object containing the element rules.
  		 */
  		setRules: function( tagName, rules ) {
  			var currentRules = this._.rules[ tagName ];
  
  			if ( currentRules )
  				CKEDITOR.tools.extend( currentRules, rules, true );
  			else
  				this._.rules[ tagName ] = rules;
  		}
  	}
  } );
  
  /**
   * Whether to force using `'&'` instead of `'&amp;'` in element attributes
   * values. It is not recommended to change this setting for compliance with the
   * W3C XHTML 1.0 standards ([C.12, XHTML 1.0](http://www.w3.org/TR/xhtml1/#C_12)).
   *
   *		// Use `'&'` instead of `'&amp;'`
   *		CKEDITOR.config.forceSimpleAmpersand = true;
   *
   * @cfg {Boolean} [forceSimpleAmpersand=false]
   * @member CKEDITOR.config
   */
  
  /**
   * The characters to be used for indenting HTML output produced by the editor.
   * Using characters different from `' '` (space) and `'\t'` (tab) is not recommended
   * as it will mess the code.
   *
   *		// No indentation.
   *		CKEDITOR.config.dataIndentationChars = '';
   *
   *		// Use two spaces for indentation.
   *		CKEDITOR.config.dataIndentationChars = '  ';
   *
   * @cfg {String} [dataIndentationChars='\t']
   * @member CKEDITOR.config
   */
  