2 Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
3 For licensing, see LICENSE.html or http://ckeditor.com/license
8 CKEDITOR
.htmlParser
.filter
= CKEDITOR
.tools
.createClass(
16 elements
: { $length
: 0 },
17 attributes
: { $length
: 0 }
21 this.addRules( rules
, 10 );
26 addRules : function( rules
, priority
)
28 if ( typeof priority
!= 'number' )
31 // Add the elementNames.
32 addItemsToList( this._
.elementNames
, rules
.elementNames
, priority
);
34 // Add the attributeNames.
35 addItemsToList( this._
.attributeNames
, rules
.attributeNames
, priority
);
38 addNamedItems( this._
.elements
, rules
.elements
, priority
);
40 // Add the attributes.
41 addNamedItems( this._
.attributes
, rules
.attributes
, priority
);
44 this._
.text
= transformNamedItem( this._
.text
, rules
.text
, priority
) || this._
.text
;
47 this._
.comment
= transformNamedItem( this._
.comment
, rules
.comment
, priority
) || this._
.comment
;
50 this._
.root
= transformNamedItem( this._
.root
, rules
.root
, priority
) || this._
.root
;
53 onElementName : function( name
)
55 return filterName( name
, this._
.elementNames
);
58 onAttributeName : function( name
)
60 return filterName( name
, this._
.attributeNames
);
63 onText : function( text
)
65 var textFilter
= this._
.text
;
66 return textFilter
? textFilter
.filter( text
) : text
;
69 onComment : function( commentText
, comment
)
71 var textFilter
= this._
.comment
;
72 return textFilter
? textFilter
.filter( commentText
, comment
) : commentText
;
75 onFragment : function( element
)
77 var rootFilter
= this._
.root
;
78 return rootFilter
? rootFilter
.filter( element
) : element
;
81 onElement : function( element
)
83 // We must apply filters set to the specific element name as
84 // well as those set to the generic $ name. So, add both to an
85 // array and process them in a small loop.
86 var filters
= [ this._
.elements
[ '^' ], this._
.elements
[ element
.name
], this._
.elements
.$ ],
89 for ( var i
= 0 ; i
< 3 ; i
++ )
91 filter
= filters
[ i
];
94 ret
= filter
.filter( element
, this );
99 if ( ret
&& ret
!= element
)
100 return this.onNode( ret
);
102 // The non-root element has been dismissed by one of the filters.
103 if ( element
.parent
&& !element
.name
)
111 onNode : function( node
)
113 var type
= node
.type
;
115 return type
== CKEDITOR
.NODE_ELEMENT
? this.onElement( node
) :
116 type
== CKEDITOR
.NODE_TEXT
? new CKEDITOR
.htmlParser
.text( this.onText( node
.value
) ) :
117 type
== CKEDITOR
.NODE_COMMENT
? new CKEDITOR
.htmlParser
.comment( this.onComment( node
.value
) ):
121 onAttribute : function( element
, name
, value
)
123 var filter
= this._
.attributes
[ name
];
127 var ret
= filter
.filter( value
, element
, this );
132 if ( typeof ret
!= 'undefined' )
141 function filterName( name
, filters
)
143 for ( var i
= 0 ; name
&& i
< filters
.length
; i
++ )
145 var filter
= filters
[ i
];
146 name
= name
.replace( filter
[ 0 ], filter
[ 1 ] );
151 function addItemsToList( list
, items
, priority
)
153 if ( typeof items
== 'function' )
157 listLength
= list
.length
,
158 itemsLength
= items
&& items
.length
;
162 // Find the index to insert the items at.
163 for ( i
= 0 ; i
< listLength
&& list
[ i
].pri
< priority
; i
++ )
166 // Add all new items to the list at the specific index.
167 for ( j
= itemsLength
- 1 ; j
>= 0 ; j
-- )
169 var item
= items
[ j
];
173 list
.splice( i
, 0, item
);
179 function addNamedItems( hashTable
, items
, priority
)
183 for ( var name
in items
)
185 var current
= hashTable
[ name
];
199 function transformNamedItem( current
, item
, priority
)
207 // If the current item is not an Array, transform it.
208 if ( !current
.splice
)
210 if ( current
.pri
> priority
)
211 current
= [ item
, current
];
213 current
= [ current
, item
];
215 current
.filter
= callItems
;
218 addItemsToList( current
, item
, priority
);
230 // Invoke filters sequentially on the array, break the iteration
231 // when it doesn't make sense to continue anymore.
232 function callItems( currentEntry
)
234 var isNode
= currentEntry
.type
235 || currentEntry
instanceof CKEDITOR
.htmlParser
.fragment
;
237 for ( var i
= 0 ; i
< this.length
; i
++ )
239 // Backup the node info before filtering.
242 var orgType
= currentEntry
.type
,
243 orgName
= currentEntry
.name
;
246 var item
= this[ i
],
247 ret
= item
.apply( window
, arguments
);
252 // We're filtering node (element/fragment).
255 // No further filtering if it's not anymore
256 // fitable for the subsequent filters.
257 if ( ret
&& ( ret
.name
!= orgName
258 || ret
.type
!= orgType
) )
263 // Filtering value (nodeName/textValue/attrValue).
266 // No further filtering if it's not
268 if ( typeof ret
!= 'string' )
272 ret
!= undefined && ( currentEntry
= ret
);
282 text : function( text )
284 // TODO : Process entities.
285 return text.toUpperCase();