Package cssutils :: Package stylesheets :: Module mediaquery
[hide private]
[frames] | no frames]

Source Code for Module cssutils.stylesheets.mediaquery

  1  """ 
  2  MediaQuery, see http://www.w3.org/TR/css3-mediaqueries/ 
  3   
  4  A cssutils own implementation, not defined in official DOM 
  5   
  6  TODO: 
  7      add possibility to 
  8   
  9  part of a media_query_list: <media_query> [, <media_query> ]* 
 10  see stylesheets.MediaList 
 11  """ 
 12  __all__ = ['MediaQuery'] 
 13  __docformat__ = 'restructuredtext' 
 14  __version__ = '$Id: mediaquery.py 1116 2008-03-05 13:52:23Z cthedot $' 
 15   
 16  import re 
 17  import xml.dom 
 18  import cssutils 
 19   
20 -class MediaQuery(cssutils.util.Base):
21 """ 22 A Media Query consists of a media type and one or more 23 expressions involving media features. 24 25 Properties 26 ========== 27 mediaText: of type DOMString 28 The parsable textual representation of this MediaQuery 29 mediaType: of type DOMString 30 one of MEDIA_TYPES like e.g. 'print' 31 seq: a list (cssutils) 32 All parts of this MediaQuery including CSSComments 33 wellformed: 34 if this query is wellformed 35 36 Format 37 ====== 38 :: 39 40 media_query: [[only | not]? <media_type> [ and <expression> ]*] 41 | <expression> [ and <expression> ]* 42 expression: ( <media_feature> [: <value>]? ) 43 media_type: all | aural | braille | handheld | print | 44 projection | screen | tty | tv | embossed 45 media_feature: width | min-width | max-width 46 | height | min-height | max-height 47 | device-width | min-device-width | max-device-width 48 | device-height | min-device-height | max-device-height 49 | device-aspect-ratio | min-device-aspect-ratio | max-device-aspect-ratio 50 | color | min-color | max-color 51 | color-index | min-color-index | max-color-index 52 | monochrome | min-monochrome | max-monochrome 53 | resolution | min-resolution | max-resolution 54 | scan | grid 55 56 """ 57 MEDIA_TYPES = [u'all', u'aural', u'braille', u'embossed', u'handheld', 58 u'print', u'projection', u'screen', u'tty', u'tv'] 59 60 # From the HTML spec (see MediaQuery): 61 # "[...] character that isn't a US ASCII letter [a-zA-Z] (Unicode 62 # decimal 65-90, 97-122), digit [0-9] (Unicode hex 30-39), or hyphen (45)." 63 # so the following is a valid mediaType 64 __mediaTypeMatch = re.compile(ur'^[-a-zA-Z0-9]+$', re.U).match 65
66 - def __init__(self, mediaText=None, readonly=False):
67 """ 68 mediaText 69 unicodestring of parsable media 70 """ 71 super(MediaQuery, self).__init__() 72 73 self.seq = [] 74 self._mediaType = u'' 75 if mediaText: 76 self.mediaText = mediaText # sets self._mediaType too 77 78 self._readonly = readonly
79
80 - def _getMediaText(self):
81 """ 82 returns serialized property mediaText 83 """ 84 return cssutils.ser.do_stylesheets_mediaquery(self)
85
86 - def _setMediaText(self, mediaText):
87 """ 88 mediaText 89 a single media query string, e.g. "print and (min-width: 25cm)" 90 91 DOMException 92 93 - SYNTAX_ERR: (self) 94 Raised if the specified string value has a syntax error and is 95 unparsable. 96 - INVALID_CHARACTER_ERR: (self) 97 Raised if the given mediaType is unknown. 98 - NO_MODIFICATION_ALLOWED_ERR: (self) 99 Raised if this media query is readonly. 100 """ 101 self._checkReadonly() 102 tokenizer = self._tokenize2(mediaText) 103 if not tokenizer: 104 self._log.error(u'MediaQuery: No MediaText given.') 105 else: 106 # for closures: must be a mutable 107 new = {'mediatype': None, 108 'wellformed': True } 109 110 def _ident_or_dim(expected, seq, token, tokenizer=None): 111 # only|not or mediatype or and 112 val = self._tokenvalue(token) 113 nval = self._normalize(val) 114 if expected.endswith('mediatype'): 115 if nval in (u'only', u'not'): 116 # only or not 117 seq.append(val) 118 return 'mediatype' 119 else: 120 # mediatype 121 new['mediatype'] = val 122 seq.append(val) 123 return 'and' 124 elif 'and' == nval and expected.startswith('and'): 125 seq.append(u'and') 126 return 'feature' 127 else: 128 self._log.error( 129 u'MediaQuery: Unexpected syntax.', token=token) 130 return expected
131 132 def _char(expected, seq, token, tokenizer=None): 133 # starting a feature which basically is a CSS Property 134 # but may simply be a property name too 135 val = self._tokenvalue(token) 136 if val == u'(' and expected == 'feature': 137 proptokens = self._tokensupto2( 138 tokenizer, funcendonly=True) 139 if proptokens and u')' == self._tokenvalue(proptokens[-1]): 140 proptokens.pop() 141 property = cssutils.css.Property(_mediaQuery=True) 142 property.cssText = proptokens 143 seq.append(property) 144 return 'and or EOF' 145 else: 146 self._log.error( 147 u'MediaQuery: Unexpected syntax, expected "and" but found "%s".' % 148 val, token) 149 return expected
150 151 # expected: only|not or mediatype, mediatype, feature, and 152 newseq = [] 153 wellformed, expected = self._parse(expected='only|not or mediatype', 154 seq=newseq, tokenizer=tokenizer, 155 productions={'IDENT': _ident_or_dim, # e.g. "print" 156 'DIMENSION': _ident_or_dim, # e.g. "3d" 157 'CHAR': _char}) 158 wellformed = wellformed and new['wellformed'] 159 160 # post conditions 161 if not new['mediatype']: 162 wellformed = False 163 self._log.error(u'MediaQuery: No mediatype found: %s' % 164 self._valuestr(mediaText)) 165 166 if wellformed: 167 # set 168 self.mediaType = new['mediatype'] 169 self.seq = newseq 170 171 mediaText = property(_getMediaText, _setMediaText, 172 doc="""(DOM) The parsable textual representation of the media list. 173 This is a comma-separated list of media.""") 174
175 - def _getMediaType(self):
176 """ 177 returns serialized property mediaText 178 """ 179 return self._mediaType
180
181 - def _setMediaType(self, mediaType):
182 """ 183 mediaType 184 one of MEDIA_TYPES 185 186 DOMException 187 188 - SYNTAX_ERR: (self) 189 Raised if the specified string value has a syntax error and is 190 unparsable. 191 - INVALID_CHARACTER_ERR: (self) 192 Raised if the given mediaType is unknown. 193 - NO_MODIFICATION_ALLOWED_ERR: (self) 194 Raised if this media query is readonly. 195 """ 196 self._checkReadonly() 197 nmediaType = self._normalize(mediaType) 198 199 if not MediaQuery.__mediaTypeMatch(nmediaType): 200 self._log.error( 201 u'MediaQuery: Syntax Error in media type "%s".' % mediaType, 202 error=xml.dom.SyntaxErr) 203 else: 204 if nmediaType not in MediaQuery.MEDIA_TYPES: 205 self._log.warn( 206 u'MediaQuery: Unknown media type "%s".' % mediaType, 207 error=xml.dom.InvalidCharacterErr) 208 209 # set 210 self._mediaType = mediaType 211 212 # update seq 213 for i, x in enumerate(self.seq): 214 if isinstance(x, basestring): 215 if self._normalize(x) in (u'only', u'not'): 216 continue 217 else: 218 self.seq[i] = mediaType 219 break 220 else: 221 self.seq.insert(0, mediaType)
222 223 mediaType = property(_getMediaType, _setMediaType, 224 doc="""(DOM) media type (one of MediaQuery.MEDIA_TYPES) of this MediaQuery.""") 225 226 wellformed = property(lambda self: bool(len(self.seq))) 227
228 - def __repr__(self):
229 return "cssutils.stylesheets.%s(mediaText=%r)" % ( 230 self.__class__.__name__, self.mediaText)
231
232 - def __str__(self):
233 return "<cssutils.stylesheets.%s object mediaText=%r at 0x%x>" % ( 234 self.__class__.__name__, self.mediaText, id(self))
235