1 /* 2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 (function() 7 { 8 CKEDITOR.htmlParser.filter = CKEDITOR.tools.createClass( 9 { 10 $ : function( rules ) 11 { 12 this._ = 13 { 14 elementNames : [], 15 attributeNames : [], 16 elements : { $length : 0 }, 17 attributes : { $length : 0 } 18 }; 19 20 if ( rules ) 21 this.addRules( rules, 10 ); 22 }, 23 24 proto : 25 { 26 addRules : function( rules, priority ) 27 { 28 if ( typeof priority != 'number' ) 29 priority = 10; 30 31 // Add the elementNames. 32 addItemsToList( this._.elementNames, rules.elementNames, priority ); 33 34 // Add the attributeNames. 35 addItemsToList( this._.attributeNames, rules.attributeNames, priority ); 36 37 // Add the elements. 38 addNamedItems( this._.elements, rules.elements, priority ); 39 40 // Add the attributes. 41 addNamedItems( this._.attributes, rules.attributes, priority ); 42 43 // Add the text. 44 this._.text = transformNamedItem( this._.text, rules.text, priority ) || this._.text; 45 46 // Add the comment. 47 this._.comment = transformNamedItem( this._.comment, rules.comment, priority ) || this._.comment; 48 }, 49 50 onElementName : function( name ) 51 { 52 return filterName( name, this._.elementNames ); 53 }, 54 55 onAttributeName : function( name ) 56 { 57 return filterName( name, this._.attributeNames ); 58 }, 59 60 onText : function( text ) 61 { 62 var textFilter = this._.text; 63 return textFilter ? textFilter.filter( text ) : text; 64 }, 65 66 onComment : function( commentText ) 67 { 68 var textFilter = this._.comment; 69 return textFilter ? textFilter.filter( commentText ) : commentText; 70 }, 71 72 onElement : function( element ) 73 { 74 // We must apply filters set to the specific element name as 75 // well as those set to the generic $ name. So, add both to an 76 // array and process them in a small loop. 77 var filters = [ this._.elements[ element.name ], this._.elements.$ ], 78 filter, ret; 79 80 for ( var i = 0 ; i < 2 ; i++ ) 81 { 82 filter = filters[ i ]; 83 if ( filter ) 84 { 85 ret = filter.filter( element, this ); 86 87 if ( ret === false ) 88 return null; 89 90 if ( ret && ret != element ) 91 return this.onElement( ret );; 92 } 93 } 94 95 return element; 96 }, 97 98 onAttribute : function( element, name, value ) 99 { 100 var filter = this._.attributes[ name ]; 101 102 if ( filter ) 103 { 104 var ret = filter.filter( value, element, this ); 105 106 if ( ret === false ) 107 return false; 108 109 if ( typeof ret != 'undefined' ) 110 return ret; 111 } 112 113 return value; 114 } 115 } 116 }); 117 118 function filterName( name, filters ) 119 { 120 for ( var i = 0 ; name && i < filters.length ; i++ ) 121 { 122 var filter = filters[ i ]; 123 name = name.replace( filter[ 0 ], filter[ 1 ] ); 124 } 125 return name; 126 } 127 128 function addItemsToList( list, items, priority ) 129 { 130 var i, j, 131 listLength = list.length, 132 itemsLength = items && items.length; 133 134 if ( itemsLength ) 135 { 136 // Find the index to insert the items at. 137 for ( i = 0 ; i < listLength && list[ i ].pri < priority ; i++ ) 138 {} 139 140 // Add all new items to the list at the specific index. 141 for ( j = itemsLength - 1 ; j >= 0 ; j-- ) 142 { 143 var item = items[ j ]; 144 item.pri = priority; 145 list.splice( i, 0, item ); 146 } 147 } 148 } 149 150 function addNamedItems( hashTable, items, priority ) 151 { 152 if ( items ) 153 { 154 for ( var name in items ) 155 { 156 var current = hashTable[ name ]; 157 158 hashTable[ name ] = 159 transformNamedItem( 160 current, 161 items[ name ], 162 priority ); 163 164 if ( !current ) 165 hashTable.$length++; 166 } 167 } 168 } 169 170 function transformNamedItem( current, item, priority ) 171 { 172 if ( item ) 173 { 174 item.pri = priority; 175 176 if ( current ) 177 { 178 // If the current item is not an Array, transform it. 179 if ( !current.splice ) 180 { 181 if ( current.pri > priority ) 182 current = [ item, current ]; 183 else 184 current = [ current, item ]; 185 186 current.filter = callItems; 187 } 188 else 189 addItemsToList( current, item, priority ); 190 191 return current; 192 } 193 else 194 { 195 item.filter = item; 196 return item; 197 } 198 } 199 } 200 201 function callItems( currentEntry ) 202 { 203 var isObject = ( typeof currentEntry == 'object' ); 204 205 for ( var i = 0 ; i < this.length ; i++ ) 206 { 207 var item = this[ i ], 208 ret = item.apply( window, arguments ); 209 210 if ( typeof ret != 'undefined' ) 211 { 212 if ( ret === false ) 213 return false; 214 215 if ( isObject && ret != currentEntry ) 216 return ret; 217 } 218 } 219 } 220 })(); 221 222 // "entities" plugin 223 /* 224 { 225 text : function( text ) 226 { 227 // TODO : Process entities. 228 return text.toUpperCase(); 229 } 230 }; 231 */ 232