/* Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved. For licensing, see LICENSE.html or http://ckeditor.com/license */ CKEDITOR.plugins.add( 'htmlwriter' ); /** * Class used to write HTML data. * @constructor * @example * 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>" */ CKEDITOR.htmlWriter = CKEDITOR.tools.createClass( { base : CKEDITOR.htmlParser.basicWriter, $ : function() { // Call the base contructor. this.base(); /** * The characters to be used for each identation step. * @type String * @default "\t" (tab) * @example * // Use two spaces for indentation. * editorInstance.dataProcessor.writer.indentationChars = ' '; */ this.indentationChars = '\t'; /** * The characters to be used to close "self-closing" elements, like "br" or * "img". * @type String * @default " />" * @example * // Use HTML4 notation for self-closing elements. * editorInstance.dataProcessor.writer.selfClosingEnd = '>'; */ this.selfClosingEnd = ' />'; /** * The characters to be used for line breaks. * @type String * @default "\n" (LF) * @example * // Use CRLF for line breaks. * editorInstance.dataProcessor.writer.lineBreakChars = '\r\n'; */ this.lineBreakChars = '\n'; this.forceSimpleAmpersand = 0; 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 : 1, breakBeforeOpen : 1, breakAfterOpen : 1, breakBeforeClose : !dtd[ e ][ '#' ], breakAfterClose : 1 }); } this.setRules( 'br', { breakAfterOpen : 1 }); this.setRules( 'title', { indent : 0, breakAfterOpen : 0 }); this.setRules( 'style', { indent : 0, breakBeforeClose : 1 }); // Disable indentation on
.
this.setRules( 'pre',
{
indent : 0
});
},
proto :
{
/**
* Writes the tag opening part for a opener tag.
* @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.
* @example
* // Writes "<p".
* writer.openTag( 'p', { class : 'MyClass', id : 'MyId' } );
*/
openTag : function( tagName, attributes )
{
var rules = this._.rules[ tagName ];
if ( this._.indent )
this.indentation();
// Do not break if indenting.
else if ( rules && rules.breakBeforeOpen )
{
this.lineBreak();
this.indentation();
}
this._.output.push( '<', tagName );
},
/**
* Writes the tag closing part for a opener tag.
* @param {String} tagName The element name for this tag.
* @param {Boolean} isSelfClose Indicates that this is a self-closing tag,
* like "br" or "img".
* @example
* // Writes ">".
* writer.openTagClose( 'p', false );
* @example
* // Writes " />".
* writer.openTagClose( 'br', true );
*/
openTagClose : function( tagName, isSelfClose )
{
var rules = this._.rules[ tagName ];
if ( isSelfClose )
this._.output.push( this.selfClosingEnd );
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}.
* @param {String} attName The attribute name.
* @param {String} attValue The attribute value.
* @example
* // Writes ' class="MyClass"'.
* writer.attribute( 'class', 'MyClass' );
*/
attribute : function( attName, attValue )
{
if ( typeof attValue == 'string' )
{
this.forceSimpleAmpersand && ( attValue = attValue.replace( /&/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.
* @param {String} tagName The element name for this tag.
* @example
* // Writes "</p>".
* writer.closeTag( 'p' );
*/
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();
},
/**
* Writes text.
* @param {String} text The text value
* @example
* // Writes "Hello Word".
* writer.text( 'Hello Word' );
*/
text : function( text )
{
if ( this._.indent )
{
this.indentation();
!this._.inPre && ( text = CKEDITOR.tools.ltrim( text ) );
}
this._.output.push( text );
},
/**
* Writes a comment.
* @param {String} comment The comment text.
* @example
* // Writes "<!-- My comment -->".
* writer.comment( ' My comment ' );
*/
comment : function( comment )
{
if ( this._.indent )
this.indentation();
this._.output.push( '' );
},
/**
* Writes a line break. It uses the {@link #lineBreakChars} property for it.
* @example
* // 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 chars. It uses the
* {@link #indentationChars} property, repeating it for the current
* indentation steps.
* @example
* // Writes "\t" (e.g.).
* writer.indentation();
*/
indentation : function()
{
if( !this._.inPre )
this._.output.push( this._.indentation );
this._.indent = 0;
},
/**
* Sets formatting rules for a give element. The possible rules are:
*