X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=_source%2Fplugins%2Fhtmldataprocessor%2Fplugin.js;h=f9b5deab14620bc52a86c17fff26657b7dd56c9e;hb=9afde8772159bd3436f1f5b7862960307710ae5a;hp=47bdb7c5bf1122b0130643bc4375a88bbd10b56c;hpb=941b0a9ba4e673e292510d80a5a86806994b8ea6;p=ckeditor.git diff --git a/_source/plugins/htmldataprocessor/plugin.js b/_source/plugins/htmldataprocessor/plugin.js index 47bdb7c..f9b5dea 100644 --- a/_source/plugins/htmldataprocessor/plugin.js +++ b/_source/plugins/htmldataprocessor/plugin.js @@ -16,7 +16,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license { var lastIndex = block.children.length, last = block.children[ lastIndex - 1 ]; - while( last && last.type == CKEDITOR.NODE_TEXT && !CKEDITOR.tools.trim( last.value ) ) + while ( last && last.type == CKEDITOR.NODE_TEXT && !CKEDITOR.tools.trim( last.value ) ) last = block.children[ --lastIndex ]; return last; } @@ -38,31 +38,44 @@ For licensing, see LICENSE.html or http://ckeditor.com/license } } - function blockNeedsExtension( block ) + function blockNeedsExtension( block, fromSource, extendEmptyBlock ) { - var lastChild = lastNoneSpaceChild( block ); - return !lastChild || lastChild.type == CKEDITOR.NODE_ELEMENT && lastChild.name == 'br'; - } + if( !fromSource && ( !extendEmptyBlock || + typeof extendEmptyBlock == 'function' && ( extendEmptyBlock( block ) === false ) ) ) + return false; + + // 1. For IE version >=8, empty blocks are displayed correctly themself in wysiwiyg; + // 2. For the rest, at least table cell and list item need no filler space. + // (#6248) + if ( fromSource && CKEDITOR.env.ie && + ( document.documentMode > 7 + || block.name in CKEDITOR.dtd.tr + || block.name in CKEDITOR.dtd.$listItem ) ) + return false; - function extendBlockForDisplay( block ) - { - trimFillers( block, true ); + var lastChild = lastNoneSpaceChild( block ); - if ( blockNeedsExtension( block ) ) - { - if ( CKEDITOR.env.ie ) - block.add( new CKEDITOR.htmlParser.text( '\xa0' ) ); - else - block.add( new CKEDITOR.htmlParser.element( 'br', {} ) ); - } + return !lastChild || lastChild && + ( lastChild.type == CKEDITOR.NODE_ELEMENT && lastChild.name == 'br' + // Some of the controls in form needs extension too, + // to move cursor at the end of the form. (#4791) + || block.name == 'form' && lastChild.name == 'input' ); } - function extendBlockForOutput( block ) + function getBlockExtension( isOutput, emptyBlockFiller ) { - trimFillers( block ); + return function( node ) + { + trimFillers( node, !isOutput ); - if ( blockNeedsExtension( block ) ) - block.add( new CKEDITOR.htmlParser.text( '\xa0' ) ); + if ( blockNeedsExtension( node, !isOutput, emptyBlockFiller ) ) + { + if ( isOutput || CKEDITOR.env.ie ) + node.add( new CKEDITOR.htmlParser.text( '\xa0' ) ); + else + node.add( new CKEDITOR.htmlParser.element( 'br', {} ) ); + } + }; } var dtd = CKEDITOR.dtd; @@ -79,18 +92,19 @@ For licensing, see LICENSE.html or http://ckeditor.com/license delete blockLikeTags.pre; var defaultDataFilterRules = { + elements : {}, attributeNames : [ // Event attributes (onXYZ) must not be directly set. They can become // active in the editing area (IE|WebKit). - [ ( /^on/ ), '_cke_pa_on' ] + [ ( /^on/ ), 'data-cke-pa-on' ] ] }; var defaultDataBlockFilterRules = { elements : {} }; for ( i in blockLikeTags ) - defaultDataBlockFilterRules.elements[ i ] = extendBlockForDisplay; + defaultDataBlockFilterRules.elements[ i ] = getBlockExtension(); var defaultHtmlFilterRules = { @@ -106,10 +120,10 @@ For licensing, see LICENSE.html or http://ckeditor.com/license attributeNames : [ // Attributes saved for changes and protected attributes. - [ ( /^_cke_(saved|pa)_/ ), '' ], + [ ( /^data-cke-(saved|pa)-/ ), '' ], - // All "_cke" attributes are to be ignored. - [ ( /^_cke.*/ ), '' ], + // All "data-cke" attributes are to be ignored. + [ ( /^data-cke.*/ ), '' ], [ 'hidefocus', '' ] ], @@ -123,7 +137,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license if ( attribs ) { // Elements marked as temporary are to be ignored. - if ( attribs.cke_temp ) + if ( attribs[ 'data-cke-temp' ] ) return false; // Remove duplicated attributes - #3789. @@ -131,7 +145,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license savedAttributeName; for ( var i = 0 ; i < attributeNames.length ; i++ ) { - savedAttributeName = '_cke_saved_' + attributeNames[ i ]; + savedAttributeName = 'data-cke-saved-' + attributeNames[ i ]; savedAttributeName in attribs && ( delete attribs[ attributeNames[ i ] ] ); } } @@ -166,12 +180,25 @@ For licensing, see LICENSE.html or http://ckeditor.com/license { if ( !( element.children.length || element.attributes.name || - element.attributes._cke_saved_name ) ) + element.attributes[ 'data-cke-saved-name' ] ) ) { return false; } }, + // Remove dummy span in webkit. + span: function( element ) + { + if ( element.attributes[ 'class' ] == 'Apple-style-span' ) + delete element.name; + }, + + html : function( element ) + { + delete element.attributes.contenteditable; + delete element.attributes[ 'class' ]; + }, + body : function( element ) { delete element.attributes.spellcheck; @@ -185,6 +212,12 @@ For licensing, see LICENSE.html or http://ckeditor.com/license if ( !element.attributes.type ) element.attributes.type = 'text/css'; + }, + + title : function( element ) + { + var titleText = element.children[ 0 ]; + titleText && ( titleText.value = element.attributes[ 'data-cke-title' ] || '' ); } }, @@ -215,11 +248,6 @@ For licensing, see LICENSE.html or http://ckeditor.com/license } }; - var defaultHtmlBlockFilterRules = { elements : {} }; - - for ( i in blockLikeTags ) - defaultHtmlBlockFilterRules.elements[ i ] = extendBlockForOutput; - if ( CKEDITOR.env.ie ) { // IE outputs style attribute in capital letters. We should convert @@ -230,7 +258,23 @@ For licensing, see LICENSE.html or http://ckeditor.com/license }; } - var protectAttributeRegex = /<(?:a|area|img|input)[\s\S]*?\s((?:href|src|name)\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|(?:[^ "'>]+)))/gi; + function protectReadOnly( element ) + { + element.attributes.contenteditable = "false"; + } + function unprotectReadyOnly( element ) + { + delete element.attributes.contenteditable; + } + // Disable form elements editing mode provided by some browers. (#5746) + for ( i in { input : 1, textarea : 1 } ) + { + defaultDataFilterRules.elements[ i ] = protectReadOnly; + defaultHtmlFilterRules.elements[ i ] = unprotectReadyOnly; + } + + var protectAttributeRegex = /<((?:a|area|img|input)\b[\s\S]*?\s)((href|src|name)\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|(?:[^ "'>]+)))([^>]*)>/gi, + findSavedSrcRegex = /\sdata-cke-saved-src\s*=/; var protectElementsRegex = /(?:])[^>]*>[\s\S]*<\/style>)|(?:<(:?link|meta|base)[^>]*>)/gi, encodedElementsRegex = /([^<]*)<\/cke:encoded>/gi; @@ -242,7 +286,14 @@ For licensing, see LICENSE.html or http://ckeditor.com/license function protectAttributes( html ) { - return html.replace( protectAttributeRegex, '$& _cke_saved_$1' ); + return html.replace( protectAttributeRegex, function( tag, beginning, fullAttr, attrName, end ) + { + // We should not rewrite the _cke_saved_src attribute (#5218) + if ( attrName == 'src' && findSavedSrcRegex.test( tag ) ) + return tag; + else + return '<' + beginning + fullAttr + ' data-cke-saved-' + fullAttr + end + '>'; + }); } function protectElements( html ) @@ -276,6 +327,11 @@ For licensing, see LICENSE.html or http://ckeditor.com/license return html.replace( protectSelfClosingRegex, '' ); } + function protectPreFormatted( html ) + { + return html.replace( /(]*>)(\r\n|\n)/g, '$1$2$2' ); + } + function protectRealComments( html ) { return html.replace( //g, function( match ) @@ -357,7 +413,17 @@ For licensing, see LICENSE.html or http://ckeditor.com/license dataProcessor.dataFilter.addRules( defaultDataFilterRules ); dataProcessor.dataFilter.addRules( defaultDataBlockFilterRules ); dataProcessor.htmlFilter.addRules( defaultHtmlFilterRules ); + + var defaultHtmlBlockFilterRules = { elements : {} }; + for ( i in blockLikeTags ) + defaultHtmlBlockFilterRules.elements[ i ] = getBlockExtension( true, editor.config.fillEmptyBlocks ); + dataProcessor.htmlFilter.addRules( defaultHtmlBlockFilterRules ); + }, + + onLoad : function() + { + ! ( 'fillEmptyBlocks' in CKEDITOR.config ) && ( CKEDITOR.config.fillEmptyBlocks = 1 ); } }); @@ -396,6 +462,10 @@ For licensing, see LICENSE.html or http://ckeditor.com/license // protecting them into open-close. (#3591) data = protectSelfClosingElements( data ); + // Compensate one leading line break after
 open as browsers
+			// eat it up. (#5789)
+			data = protectPreFormatted( data );
+
 			// Call the browser to help us fixing a possibly invalid HTML
 			// structure.
 			var div = new CKEDITOR.dom.element( 'div' );
@@ -442,12 +512,32 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
 
 /**
  * Whether to force using "&" instead of "&amp;" in elements attributes
- * values. It's not recommended to change this setting for compliance with the
- * W3C XHTML 1.0 standards
- * (C.12, XHTML 1.0).
+ * values, it's not recommended to change this setting for compliance with the
+ * W3C XHTML 1.0 standards (C.12, XHTML 1.0).
+ * @name CKEDITOR.config.forceSimpleAmpersand
+ * @name CKEDITOR.config.forceSimpleAmpersand
  * @type Boolean
  * @default false
  * @example
  * config.forceSimpleAmpersand = false;
  */
-CKEDITOR.config.forceSimpleAmpersand = false;
+
+/**
+ * Whether a filler text (non-breaking space entity -  ) will be inserted into empty block elements in HTML output,
+ * this is used to render block elements properly with line-height; When a function is instead specified,
+ * it'll be passed a {@link CKEDITOR.htmlParser.element} to decide whether adding the filler text
+ * by expecting a boolean return value.
+ * @name CKEDITOR.config.fillEmptyBlocks
+ * @since 3.5
+ * @type Boolean
+ * @default true
+ * @example
+ * config.fillEmptyBlocks = false;	// Prevent filler nodes in all empty blocks.
+ *
+ * // Prevent filler node only in float cleaners.
+ * config.fillEmptyBlocks = function( element )
+ * {
+ * 	if ( element.attributes[ 'class' ].indexOf ( 'clear-both' ) != -1 )
+ * 		return false;
+ * }
+ */