/*\r
-Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.\r
+Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\r
For licensing, see LICENSE.html or http://ckeditor.com/license\r
*/\r
\r
\r
// Add the comment.\r
this._.comment = transformNamedItem( this._.comment, rules.comment, priority ) || this._.comment;\r
+\r
+ // Add root fragment.\r
+ this._.root = transformNamedItem( this._.root, rules.root, priority ) || this._.root;\r
},\r
\r
onElementName : function( name )\r
return textFilter ? textFilter.filter( text ) : text;\r
},\r
\r
- onComment : function( commentText )\r
+ onComment : function( commentText, comment )\r
{\r
var textFilter = this._.comment;\r
- return textFilter ? textFilter.filter( commentText ) : commentText;\r
+ return textFilter ? textFilter.filter( commentText, comment ) : commentText;\r
+ },\r
+\r
+ onFragment : function( element )\r
+ {\r
+ var rootFilter = this._.root;\r
+ return rootFilter ? rootFilter.filter( element ) : element;\r
},\r
\r
onElement : function( element )\r
// We must apply filters set to the specific element name as\r
// well as those set to the generic $ name. So, add both to an\r
// array and process them in a small loop.\r
- var filters = [ this._.elements[ element.name ], this._.elements.$ ],\r
+ var filters = [ this._.elements[ '^' ], this._.elements[ element.name ], this._.elements.$ ],\r
filter, ret;\r
\r
- for ( var i = 0 ; i < 2 ; i++ )\r
+ for ( var i = 0 ; i < 3 ; i++ )\r
{\r
filter = filters[ i ];\r
if ( filter )\r
return null;\r
\r
if ( ret && ret != element )\r
- return this.onElement( ret );\r
+ return this.onNode( ret );\r
+\r
+ // The non-root element has been dismissed by one of the filters.\r
+ if ( element.parent && !element.name )\r
+ break;\r
}\r
}\r
\r
return element;\r
},\r
\r
+ onNode : function( node )\r
+ {\r
+ var type = node.type;\r
+\r
+ return type == CKEDITOR.NODE_ELEMENT ? this.onElement( node ) :\r
+ type == CKEDITOR.NODE_TEXT ? new CKEDITOR.htmlParser.text( this.onText( node.value ) ) :\r
+ type == CKEDITOR.NODE_COMMENT ? new CKEDITOR.htmlParser.comment( this.onComment( node.value ) ):\r
+ null;\r
+ },\r
+\r
onAttribute : function( element, name, value )\r
{\r
var filter = this._.attributes[ name ];\r
\r
function addItemsToList( list, items, priority )\r
{\r
- if( typeof items == 'function' )\r
+ if ( typeof items == 'function' )\r
items = [ items ];\r
\r
var i, j,\r
for ( j = itemsLength - 1 ; j >= 0 ; j-- )\r
{\r
var item = items[ j ];\r
- item.pri = priority;\r
- list.splice( i, 0, item );\r
+ if ( item )\r
+ {\r
+ item.pri = priority;\r
+ list.splice( i, 0, item );\r
+ }\r
}\r
}\r
}\r
}\r
}\r
\r
+ // Invoke filters sequentially on the array, break the iteration\r
+ // when it doesn't make sense to continue anymore.\r
function callItems( currentEntry )\r
{\r
- var isObject = ( typeof currentEntry == 'object' );\r
+ var isNode = currentEntry.type\r
+ || currentEntry instanceof CKEDITOR.htmlParser.fragment;\r
\r
for ( var i = 0 ; i < this.length ; i++ )\r
{\r
+ // Backup the node info before filtering.\r
+ if ( isNode )\r
+ {\r
+ var orgType = currentEntry.type,\r
+ orgName = currentEntry.name;\r
+ }\r
+\r
var item = this[ i ],\r
ret = item.apply( window, arguments );\r
\r
- if ( typeof ret != 'undefined' )\r
- {\r
- if ( ret === false )\r
- return false;\r
+ if ( ret === false )\r
+ return ret;\r
\r
- if ( isObject && ret != currentEntry )\r
+ // We're filtering node (element/fragment).\r
+ if ( isNode )\r
+ {\r
+ // No further filtering if it's not anymore\r
+ // fitable for the subsequent filters.\r
+ if ( ret && ( ret.name != orgName\r
+ || ret.type != orgType ) )\r
+ {\r
return ret;\r
+ }\r
}\r
+ // Filtering value (nodeName/textValue/attrValue).\r
+ else\r
+ {\r
+ // No further filtering if it's not\r
+ // any more values.\r
+ if ( typeof ret != 'string' )\r
+ return ret;\r
+ }\r
+\r
+ ret != undefined && ( currentEntry = ret );\r
}\r
\r
- return null;\r
+ return currentEntry;\r
}\r
})();\r
\r