Commits

Anonymous committed c1f1a8a

refactoring Html conv

  • Participants
  • Parent commits 45351c6
  • Branches unstable

Comments (0)

Files changed (2)

insanities/forms/convs.py

 
 class Html(Char):
     
-    tags = ('a', 'p', 'br', 'li', 'ul', 'ol', 'hr', 'u', 'i', 'b', 'blockquote', 'sub', 'sup')
-    attrs = ('href', 'src', 'alt', 'title', 'class', 'rel')
+    allowed_elements = ('a', 'p', 'br', 'li', 'ul', 'ol', 'hr', 'u', 'i', 'b',
+                        'blockquote', 'sub', 'sup')
+    allowed_attributes = ('href', 'src', 'alt', 'title', 'class', 'rel')
     drop_empty_tags = ('p', 'a', 'u', 'i', 'b', 'sub', 'sup')
-    classes = {}
+    allowed_classes = {}
     
     def __init__(self, **kwargs):
+        from ..utils.html import Sanitizer, PROPERTIES
         
-        if 'add_tags' in kwargs:
-            tags = list(kwargs.get('tags', self.tags))
-            kwargs['tags'] = tags + list(kwargs['add_tags'])
-        
-        if 'add_attrs' in kwargs:
-            attrs = list(kwargs.get('attrs', self.attrs))
-            kwargs['attrs'] = attrs + list(kwargs['add_attrs'])
-        
-        if 'add_classes' in kwargs:
-            classes = kwargs.get('classes', self.classes.copy())
-            for tag, _classes in kwargs['add_classes'].items():
-                classes.setdefault(tag, [])
-                classes[tag] = tuple(set(list(classes[tag]) + list(_classes)))
-            kwargs['classes'] = classes
-        
-        if 'classes' in kwargs:
-            kwargs['classes'] = kwargs['classes'].copy()
-        
-        # instantiate Sanitizer here?
+        #sa_kwargs = kwargs.copy()
+        for opt in PROPERTIES:
+            if hasattr(self, opt):
+                kwargs.setdefault(opt, getattr(self, opt))
+            if hasattr(self, 'add_' + opt):
+                kwargs.setdefault('add_' + opt, getattr(self, 'add_' + opt))
+
         super(Html, self).__init__(**kwargs)
+
+        self.sanitizer = Sanitizer(**kwargs)
     
     def clean_value(self, value):
-        from ..utils.html import sanitize, ParseError
+        from ..utils.html import ParseError
         value = super(Html, self).clean_value(value)
         try:
-            clean = sanitize(value, safe_tags=self.tags, safe_attrs=self.attrs,
-                             allowed_classes=self.classes,
-                             drop_empty_tags=self.drop_empty_tags)
+            clean = self.sanitizer.sanitize(value)
             return Markup(clean)
         except ParseError:
             raise ValidationError, u'not valid html'
+    
+    @property
+    def tags(self):
+        return self.sanitizer.allowed_elements
+    @property
+    def attrs(self):
+        return self.sanitizer.allowed_attributes
 
 
 class List(Converter):

insanities/utils/html.py

 
 SAFE_CLASSES = {}
 
+def _add_options_helper(obj, kwargs, key):
+    # addition to kwargs as in convs.Html API
+    if key.startswith('add_') and key[4:] in obj.options:
+        key_to_add = key[4:]
+        default = getattr(obj, key_to_add)
+        if type(default) in (list, tuple):
+            value = kwargs.get(key_to_add, default)
+            value = list(value) + list(kwargs.pop(key))
+            setattr(obj, key_to_add, value)
+            kwargs[key_to_add] = value
+            return True
+
 class TokenSanitazer(sanitizer.HTMLSanitizer):
     escape_invalid_tags = False
-    #drop_empty_tags=('p',)
-    safe_classes = {}
     
-    # only html elements and attributes
+    # only html (not SVG or MathML) elements and attributes
     allowed_elements = sanitizer.HTMLSanitizer.acceptable_elements
     allowed_attributes = sanitizer.HTMLSanitizer.acceptable_attributes
     allowed_classes = SAFE_CLASSES
     def __init__(self, *args, **kwargs):
         for old, new in self.property_aliases:
             if old in kwargs:
+                # XXX write warning
                 kwargs[new] = kwargs.pop(old)
+            if 'add_' + old in kwargs:
+                # XXX write warning
+                kwargs['add_' + new] = kwargs.pop('add_' + old)
+                
         for key in kwargs.keys():
+            add = _add_options_helper(self, kwargs, key)
             if key in self.options:
                 setattr(self, key, kwargs.pop(key))
-            elif key not in ('encoding', 'parseMeta', 'useChardet', 
-                             'lowercaseElementName', 'lowercaseAttrName'):
+            elif not add and key not in ('encoding', 'parseMeta', 'useChardet', 
+                                         'lowercaseElementName',
+                                         'lowercaseAttrName'):
                 kwargs.pop(key)
         super(TokenSanitazer, self).__init__(*args, **kwargs)
     
         #a.unlink()
     return dom_tree
 
-def remove_TinyMCE_trash(clean, **kwargs):
-    return re.compile('<!--.*?-->', re.DOTALL).sub(' ', clean)
 
 def strip_empty_tags(clean, drop_empty_tags=[], **kwargs):
     # XXX Sometimes doesn't work (with nested empty tags)
     allowed_elements = sanitizer.HTMLSanitizer.acceptable_elements
     allowed_attributes = sanitizer.HTMLSanitizer.acceptable_attributes    
     dom_callbacks = [remove_a_tags_without_href]
-    string_callbacks = [remove_TinyMCE_trash, strip_empty_tags]
+    string_callbacks = [strip_empty_tags]
     method = 'xhtml'
     strip_whitespace = True
+    tokensanitazer = TokenSanitazer
 
     options = ('dom_callbacks', 'string_callbacks', 'method', 'strip_whitespace')
 
     def __init__(self, **kwargs):
         for key in kwargs.keys():
+            add = _add_options_helper(self, kwargs, key)
             if key in self.options:
                 setattr(self, key, kwargs.pop(key))
         self.kwargs = kwargs
         '''Proxy function to pass arguments into Sanitizer constructor'''
         def func(*args, **kwargs):
             kwargs.update(self.kwargs)
-            san = TokenSanitazer(*args, **kwargs)
-            return san
+            return self.tokensanitazer(*args, **kwargs)
         return func
 
     def get_dom(self, buf):
 
         return unicode(clean)
 
+
+PROPERTIES = list(TokenSanitazer.options) + \
+             [x[0] for x in TokenSanitazer.property_aliases] + \
+             list(Sanitizer.options)
+
+
+
 def sanitize(buf, **kwargs):
     return Sanitizer(**kwargs).sanitize(buf)