X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=_source%2Fplugins%2Fhtmldataprocessor%2Fplugin.js;h=ecf87ed45212310349d1f2696abad5e95bdd39b4;hb=2f22c0c38f17e75be5541089076885442aaa2377;hp=a460bba57ef742079d4cbb243195a1f562f79af8;hpb=48b1db88210b4160dce439c6e3e32e14af8c106b;p=ckeditor.git diff --git a/_source/plugins/htmldataprocessor/plugin.js b/_source/plugins/htmldataprocessor/plugin.js index a460bba..ecf87ed 100644 --- a/_source/plugins/htmldataprocessor/plugin.js +++ b/_source/plugins/htmldataprocessor/plugin.js @@ -1,5 +1,5 @@ /* -Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved. +Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. For licensing, see LICENSE.html or http://ckeditor.com/license */ @@ -44,14 +44,14 @@ For licensing, see LICENSE.html or http://ckeditor.com/license 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; + // 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; var lastChild = lastNoneSpaceChild( block ); @@ -80,6 +80,9 @@ For licensing, see LICENSE.html or http://ckeditor.com/license var dtd = CKEDITOR.dtd; + // Define orders of table elements. + var tableOrder = [ 'caption', 'colgroup', 'col', 'thead', 'tfoot', 'tbody' ]; + // Find out the list of block-like tags that can contain
. var blockLikeTags = CKEDITOR.tools.extend( {}, dtd.$block, dtd.$listItem, dtd.$tableContent ); for ( var i in blockLikeTags ) @@ -92,14 +95,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license delete blockLikeTags.pre; var defaultDataFilterRules = { - elements : { - a : function( element ) - { - var attrs = element.attributes; - if ( attrs && attrs[ 'data-cke-saved-name' ] ) - attrs[ 'class' ] = ( attrs[ 'class' ] ? attrs[ 'class' ] + ' ' : '' ) + 'cke_anchor'; - } - }, + elements : {}, attributeNames : [ // Event attributes (onXYZ) must not be directly set. They can become @@ -160,6 +156,17 @@ For licensing, see LICENSE.html or http://ckeditor.com/license return element; }, + // The contents of table should be in correct order (#4809). + table : function( element ) + { + var children = element.children; + children.sort( function ( node1, node2 ) + { + return node1.type == CKEDITOR.NODE_ELEMENT && node2.type == node1.type ? + CKEDITOR.tools.indexOf( tableOrder, node1.name ) > CKEDITOR.tools.indexOf( tableOrder, node2.name ) ? 1 : -1 : 0; + } ); + }, + embed : function( element ) { var parent = element.parent; @@ -238,23 +245,6 @@ For licensing, see LICENSE.html or http://ckeditor.com/license // Remove all class names starting with "cke_". return CKEDITOR.tools.ltrim( value.replace( /(?:^|\s+)cke_[^\s]*/g, '' ) ) || false; } - }, - - comment : function( contents ) - { - // If this is a comment for protected source. - if ( contents.substr( 0, protectedSourceMarker.length ) == protectedSourceMarker ) - { - // Remove the extra marker for real comments from it. - if ( contents.substr( protectedSourceMarker.length, 3 ) == '{C}' ) - contents = contents.substr( protectedSourceMarker.length + 3 ); - else - contents = contents.substr( protectedSourceMarker.length ); - - return new CKEDITOR.htmlParser.cdata( decodeURIComponent( contents ) ); - } - - return contents; } }; @@ -299,7 +289,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license } var protectElementRegex = /<(a|area|img|input)\b([^>]*)>/gi, - protectAttributeRegex = /\b(href|src|name)\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|(?:[^ "'>]+))/gi; + protectAttributeRegex = /\b(on\w+|href|src|name)\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|(?:[^ "'>]+))/gi; var protectElementsRegex = /(?:])[^>]*>[\s\S]*<\/style>)|(?:<(:?link|meta|base)[^>]*>)/gi, encodedElementsRegex = /([^<]*)<\/cke:encoded>/gi; @@ -315,9 +305,10 @@ For licensing, see LICENSE.html or http://ckeditor.com/license { return '<' + tag + attributes.replace( protectAttributeRegex, function( fullAttr, attrName ) { + // Avoid corrupting the inline event attributes (#7243). // We should not rewrite the existed protected attributes, e.g. clipboard content from editor. (#5218) - if ( attributes.indexOf( 'data-cke-saved-' + attrName ) == -1 ) - return ' data-cke-saved-' + fullAttr + ' ' + fullAttr; + if ( !( /^on/ ).test( attrName ) && attributes.indexOf( 'data-cke-saved-' + attrName ) == -1 ) + return ' data-cke-saved-' + fullAttr + ' data-cke-' + CKEDITOR.rnd + '-' + fullAttr; return fullAttr; }) + '>'; @@ -379,9 +370,24 @@ For licensing, see LICENSE.html or http://ckeditor.com/license }); } - function protectSource( data, protectRegexes ) + function unprotectSource( html, editor ) + { + var store = editor._.dataStore; + + return html.replace( //g, function( match, data ) + { + return decodeURIComponent( data ); + }).replace( /\{cke_protected_(\d+)\}/g, function( match, id ) + { + return store && store[ id ] || ''; + }); + } + + function protectSource( data, editor ) { var protectedHtml = [], + protectRegexes = editor.config.protectedSource, + store = editor._.dataStore || ( editor._.dataStore = { id : 1 } ), tempRegex = /<\!--\{cke_temp(comment)?\}(\d*?)-->/g; var regexes = @@ -414,7 +420,10 @@ For licensing, see LICENSE.html or http://ckeditor.com/license return protectedHtml[ id ]; } ); - return ''; + + // Avoid protecting over protected, e.g. /\{.*?\}/ + return ( /cke_temp(comment)?/ ).test( match ) ? match + : ''; }); } data = data.replace( tempRegex, function( $, isComment, id ) @@ -425,7 +434,17 @@ For licensing, see LICENSE.html or http://ckeditor.com/license '-->'; } ); - return data; + + // Different protection pattern is used for those that + // live in attributes to avoid from being HTML encoded. + return data.replace( /(['"]).*?\1/g, function ( match ) + { + return match.replace( //g, function( match, data ) + { + store[ store.id ] = decodeURIComponent( data ); + return '{cke_protected_'+ ( store.id++ ) + '}'; + }); + }); } CKEDITOR.plugins.add( 'htmldataprocessor', @@ -471,7 +490,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license // The source data is already HTML, but we need to clean // it up and apply the filter. - data = protectSource( data, this.editor.config.protectedSource ); + data = protectSource( data, this.editor ); // Before anything, we must protect the URL attributes as the // browser may changing them when setting the innerHTML later in @@ -497,10 +516,14 @@ For licensing, see LICENSE.html or http://ckeditor.com/license // Call the browser to help us fixing a possibly invalid HTML // structure. var div = new CKEDITOR.dom.element( 'div' ); + // Add fake character to workaround IE comments bug. (#3801) div.setHtml( 'a' + data ); data = div.getHtml().substr( 1 ); + // Restore shortly protected attribute names. + data = data.replace( new RegExp( ' data-cke-' + CKEDITOR.rnd + '-', 'ig' ), ' ' ); + // Unprotect "some" of the protected elements at this point. data = unprotectElementNames( data ); @@ -533,7 +556,13 @@ For licensing, see LICENSE.html or http://ckeditor.com/license fragment.writeHtml( writer, this.htmlFilter ); - return writer.getHtml( true ); + var data = writer.getHtml( true ); + + // Restore those non-HTML protected source. (#4475,#4880) + data = unprotectRealComments( data ); + data = unprotectSource( data, this.editor ); + + return data; } }; })();