JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
vanilla ckeditor-3.0
[ckeditor.git] / _source / core / htmlparser / filter.js
diff --git a/_source/core/htmlparser/filter.js b/_source/core/htmlparser/filter.js
new file mode 100644 (file)
index 0000000..3d46487
--- /dev/null
@@ -0,0 +1,233 @@
+/*\r
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.html or http://ckeditor.com/license\r
+*/\r
+\r
+(function()\r
+{\r
+       CKEDITOR.htmlParser.filter = CKEDITOR.tools.createClass(\r
+       {\r
+               $ : function( rules )\r
+               {\r
+                       this._ =\r
+                       {\r
+                               elementNames : [],\r
+                               attributeNames : [],\r
+                               elements : { $length : 0 },\r
+                               attributes : { $length : 0 }\r
+                       };\r
+\r
+                       if ( rules )\r
+                               this.addRules( rules, 10 );\r
+               },\r
+\r
+               proto :\r
+               {\r
+                       addRules : function( rules, priority )\r
+                       {\r
+                               if ( typeof priority != 'number' )\r
+                                       priority = 10;\r
+\r
+                               // Add the elementNames.\r
+                               addItemsToList( this._.elementNames, rules.elementNames, priority );\r
+\r
+                               // Add the attributeNames.\r
+                               addItemsToList( this._.attributeNames, rules.attributeNames, priority );\r
+\r
+                               // Add the elements.\r
+                               addNamedItems( this._.elements, rules.elements, priority );\r
+\r
+                               // Add the attributes.\r
+                               addNamedItems( this._.attributes, rules.attributes, priority );\r
+\r
+                               // Add the text.\r
+                               this._.text = transformNamedItem( this._.text, rules.text, priority ) || this._.text;\r
+\r
+                               // Add the comment.\r
+                               this._.comment = transformNamedItem( this._.comment, rules.comment, priority ) || this._.comment;\r
+                       },\r
+\r
+                       onElementName : function( name )\r
+                       {\r
+                               return filterName( name, this._.elementNames );\r
+                       },\r
+\r
+                       onAttributeName : function( name )\r
+                       {\r
+                               return filterName( name, this._.attributeNames );\r
+                       },\r
+\r
+                       onText : function( text )\r
+                       {\r
+                               var textFilter = this._.text;\r
+                               return textFilter ? textFilter.filter( text ) : text;\r
+                       },\r
+\r
+                       onComment : function( commentText )\r
+                       {\r
+                               var textFilter = this._.comment;\r
+                               return textFilter ? textFilter.filter( commentText ) : commentText;\r
+                       },\r
+\r
+                       onElement : function( element )\r
+                       {\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
+                                       filter, ret;\r
+\r
+                               for ( var i = 0 ; i < 2 ; i++ )\r
+                               {\r
+                                       filter = filters[ i ];\r
+                                       if ( filter )\r
+                                       {\r
+                                               ret = filter.filter( element, this );\r
+\r
+                                               if ( ret === false )\r
+                                                       return null;\r
+\r
+                                               if ( ret && ret != element )\r
+                                                       return this.onElement( ret );\r
+                                       }\r
+                               }\r
+\r
+                               return element;\r
+                       },\r
+\r
+                       onAttribute : function( element, name, value )\r
+                       {\r
+                               var filter = this._.attributes[ name ];\r
+\r
+                               if ( filter )\r
+                               {\r
+                                       var ret = filter.filter( value, element, this );\r
+\r
+                                       if ( ret === false )\r
+                                               return false;\r
+\r
+                                       if ( typeof ret != 'undefined' )\r
+                                               return ret;\r
+                               }\r
+\r
+                               return value;\r
+                       }\r
+               }\r
+       });\r
+\r
+       function filterName( name, filters )\r
+       {\r
+               for ( var i = 0 ; name && i < filters.length ; i++ )\r
+               {\r
+                       var filter = filters[ i ];\r
+                       name = name.replace( filter[ 0 ], filter[ 1 ] );\r
+               }\r
+               return name;\r
+       }\r
+\r
+       function addItemsToList( list, items, priority )\r
+       {\r
+               var i, j,\r
+                       listLength = list.length,\r
+                       itemsLength = items && items.length;\r
+\r
+               if ( itemsLength )\r
+               {\r
+                       // Find the index to insert the items at.\r
+                       for ( i = 0 ; i < listLength && list[ i ].pri < priority ; i++ )\r
+                       { /*jsl:pass*/ }\r
+\r
+                       // Add all new items to the list at the specific index.\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
+                       }\r
+               }\r
+       }\r
+\r
+       function addNamedItems( hashTable, items, priority )\r
+       {\r
+               if ( items )\r
+               {\r
+                       for ( var name in items )\r
+                       {\r
+                               var current = hashTable[ name ];\r
+\r
+                               hashTable[ name ] =\r
+                                       transformNamedItem(\r
+                                               current,\r
+                                               items[ name ],\r
+                                               priority );\r
+\r
+                               if ( !current )\r
+                                       hashTable.$length++;\r
+                       }\r
+               }\r
+       }\r
+\r
+       function transformNamedItem( current, item, priority )\r
+       {\r
+               if ( item )\r
+               {\r
+                       item.pri = priority;\r
+\r
+                       if ( current )\r
+                       {\r
+                               // If the current item is not an Array, transform it.\r
+                               if ( !current.splice )\r
+                               {\r
+                                       if ( current.pri > priority )\r
+                                               current = [ item, current ];\r
+                                       else\r
+                                               current = [ current, item ];\r
+\r
+                                       current.filter = callItems;\r
+                               }\r
+                               else\r
+                                       addItemsToList( current, item, priority );\r
+\r
+                               return current;\r
+                       }\r
+                       else\r
+                       {\r
+                               item.filter = item;\r
+                               return item;\r
+                       }\r
+               }\r
+       }\r
+\r
+       function callItems( currentEntry )\r
+       {\r
+               var isObject = ( typeof currentEntry == 'object' );\r
+\r
+               for ( var i = 0 ; i < this.length ; i++ )\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
+\r
+                               if ( isObject && ret != currentEntry )\r
+                                       return ret;\r
+                       }\r
+               }\r
+\r
+               return null;\r
+       }\r
+})();\r
+\r
+// "entities" plugin\r
+/*\r
+{\r
+       text : function( text )\r
+       {\r
+               // TODO : Process entities.\r
+               return text.toUpperCase();\r
+       }\r
+};\r
+*/\r