Ticket #8041: media-safestrings.diff
File media-safestrings.diff, 4.9 KB (added by , 16 years ago) |
---|
-
forms/widgets.py
35 35 media_attrs = media.__dict__ 36 36 else: 37 37 media_attrs = kwargs 38 38 39 39 self._css = {} 40 40 self._js = [] 41 41 42 42 for name in MEDIA_TYPES: 43 43 getattr(self, 'add_' + name)(media_attrs.get(name, None)) 44 44 45 45 # Any leftover attributes must be invalid. 46 46 # if media_attrs != {}: 47 47 # raise TypeError, "'class Media' has invalid attribute(s): %s" % ','.join(media_attrs.keys()) 48 48 49 49 def __unicode__(self): 50 50 return self.render() 51 51 52 52 def render(self): 53 53 return u'\n'.join(chain(*[getattr(self, 'render_' + name)() for name in MEDIA_TYPES])) 54 54 55 55 def render_js(self): 56 return [ u'<script type="text/javascript" src="%s"></script>' % self.absolute_path(path) for path in self._js]57 56 return [mark_safe(u'<script type="text/javascript" src="%s"></script>' % conditional_escape(self.absolute_path(path))) for path in self._js] 57 58 58 def render_css(self): 59 59 # To keep rendering order consistent, we can't just iterate over items(). 60 60 # We need to sort the keys, and iterate over the sorted list. 61 61 media = self._css.keys() 62 62 media.sort() 63 63 return chain(*[ 64 [ u'<link href="%s" type="text/css" media="%s" rel="stylesheet" />' % (self.absolute_path(path), medium)65 for path in self._css[medium]] 64 [mark_safe(u'<link href="%s" type="text/css" media="%s" rel="stylesheet" />' % (conditional_escape(self.absolute_path(path)), medium)) 65 for path in self._css[medium]] 66 66 for medium in media]) 67 67 68 68 def absolute_path(self, path): 69 69 if path.startswith(u'http://') or path.startswith(u'https://') or path.startswith(u'/'): 70 70 return path … … 77 77 raise KeyError('Unknown media type "%s"' % name) 78 78 79 79 def add_js(self, data): 80 if data: 80 if data: 81 81 self._js.extend([path for path in data if path not in self._js]) 82 82 83 83 def add_css(self, data): 84 84 if data: 85 85 for medium, paths in data.items(): … … 99 99 base = super(cls, self).media 100 100 else: 101 101 base = Media() 102 103 # Get the media definition for this class 102 103 # Get the media definition for this class 104 104 definition = getattr(cls, 'Media', None) 105 105 if definition: 106 106 extend = getattr(definition, 'extend', True) … … 117 117 else: 118 118 return base 119 119 return property(_media) 120 120 121 121 class MediaDefiningClass(type): 122 122 "Metaclass for classes that can have media definitions" 123 def __new__(cls, name, bases, attrs): 123 def __new__(cls, name, bases, attrs): 124 124 new_class = super(MediaDefiningClass, cls).__new__(cls, name, bases, 125 125 attrs) 126 126 if 'media' not in attrs: 127 127 new_class.media = media_property(new_class) 128 128 return new_class 129 129 130 130 class Widget(object): 131 131 __metaclass__ = MediaDefiningClass 132 132 is_hidden = False # Determines whether this corresponds to an <input type="hidden">. … … 264 264 def value_from_datadict(self, data, files, name): 265 265 "File widgets take data from FILES, not POST" 266 266 return files.get(name, None) 267 267 268 268 def _has_changed(self, initial, data): 269 269 if data is None: 270 270 return False … … 410 410 if isinstance(data, MultiValueDict): 411 411 return data.getlist(name) 412 412 return data.get(name, None) 413 413 414 414 def _has_changed(self, initial, data): 415 415 if initial is None: 416 416 initial = [] … … 527 527 label_for = u' for="%s"' % final_attrs['id'] 528 528 else: 529 529 label_for = '' 530 530 531 531 cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values) 532 532 option_value = force_unicode(option_value) 533 533 rendered_cb = cb.render(name, option_value) … … 601 601 602 602 def value_from_datadict(self, data, files, name): 603 603 return [widget.value_from_datadict(data, files, name + '_%s' % i) for i, widget in enumerate(self.widgets)] 604 604 605 605 def _has_changed(self, initial, data): 606 606 if initial is None: 607 607 initial = [u'' for x in range(0, len(data))] … … 637 637 media = media + w.media 638 638 return media 639 639 media = property(_get_media) 640 640 641 641 class SplitDateTimeWidget(MultiWidget): 642 642 """ 643 643 A Widget that splits datetime input into two <input type="text"> boxes. … … 650 650 if value: 651 651 return [value.date(), value.time().replace(microsecond=0)] 652 652 return [None, None] 653