Package cssutils :: Package css :: Module cssmediarule
[hide private]
[frames] | no frames]

Source Code for Module cssutils.css.cssmediarule

  1  """CSSMediaRule implements DOM Level 2 CSS CSSMediaRule. 
  2  """ 
  3  __all__ = ['CSSMediaRule'] 
  4  __docformat__ = 'restructuredtext' 
  5  __author__ = '$LastChangedBy: cthedot $' 
  6  __date__ = '$LastChangedDate: 2007-08-20 22:07:12 +0200 (Mo, 20 Aug 2007) $' 
  7  __version__ = '$LastChangedRevision: 257 $' 
  8   
  9  import xml.dom 
 10  import cssrule 
 11  import cssutils 
 12   
13 -class CSSMediaRule(cssrule.CSSRule):
14 """ 15 represents an @media rule in a CSS style sheet. A @media rule can be 16 used to delimit style rules for specific media types. 17 18 Properties 19 ========== 20 cssRules: A css::CSSRuleList of all CSS rules contained within the 21 media block. 22 cssText: of type DOMString 23 The parsable textual representation of this rule 24 media: of type stylesheets::MediaList, (DOM readonly) 25 A list of media types for this rule of type MediaList. 26 27 cssutils only 28 ------------- 29 atkeyword: 30 the literal keyword used 31 32 Inherits properties from CSSRule 33 34 Format 35 ====== 36 media 37 : MEDIA_SYM S* medium [ COMMA S* medium ]* LBRACE S* ruleset* '}' S*; 38 """ 39 # CONSTANT 40 type = cssrule.CSSRule.MEDIA_RULE 41
42 - def __init__(self, mediaText='all', readonly=False):
43 """ 44 constructor 45 """ 46 super(CSSMediaRule, self).__init__() 47 48 self.atkeyword = u'@media' 49 self._media = cssutils.stylesheets.MediaList( 50 mediaText, readonly=readonly) 51 if not self.media.valid: 52 self._media = cssutils.stylesheets.MediaList() 53 self._rules = cssutils.css.cssrulelist.CSSRuleList() 54 55 self._readonly = readonly
56
57 - def _getMedia(self):
58 "returns MediaList" 59 return self._media
60 61 media = property(_getMedia, 62 doc=u"(DOM readonly) A list of media types for this rule of type\ 63 MediaList") 64
65 - def _getCssRules(self):
66 return self._rules
67 68 cssRules = property(_getCssRules, 69 doc="(DOM readonly) A css::CSSRuleList of all CSS rules contained\ 70 within the media block.") 71
72 - def deleteRule(self, index):
73 """ 74 index 75 within the media block's rule collection of the rule to remove. 76 77 Used to delete a rule from the media block. 78 79 DOMExceptions 80 81 - INDEX_SIZE_ERR: (self) 82 Raised if the specified index does not correspond to a rule in 83 the media rule list. 84 - NO_MODIFICATION_ALLOWED_ERR: (self) 85 Raised if this media rule is readonly. 86 """ 87 self._checkReadonly() 88 89 try: 90 self._rules[index].parentRule = None # detach 91 del self._rules[index] # remove from @media 92 except IndexError: 93 raise xml.dom.IndexSizeErr( 94 u'CSSMediaRule: %s is not a valid index in the rulelist of length %i' % ( 95 index, self.cssRules.length))
96
97 - def insertRule(self, rule, index=None):
98 """ 99 rule 100 The parsable text representing the rule. For rule sets this 101 contains both the selector and the style declaration. For 102 at-rules, this specifies both the at-identifier and the rule 103 content. 104 105 cssutils also allows rule to be a valid **CSSRule** object 106 107 index 108 within the media block's rule collection of the rule before 109 which to insert the specified rule. If the specified index is 110 equal to the length of the media blocks's rule collection, the 111 rule will be added to the end of the media block. 112 If index is not given or None rule will be appended to rule 113 list. 114 115 Used to insert a new rule into the media block. 116 117 DOMException on setting 118 119 - HIERARCHY_REQUEST_ERR: 120 (no use case yet as no @charset or @import allowed)) 121 Raised if the rule cannot be inserted at the specified index, 122 e.g., if an @import rule is inserted after a standard rule set 123 or other at-rule. 124 - INDEX_SIZE_ERR: (self) 125 Raised if the specified index is not a valid insertion point. 126 - NO_MODIFICATION_ALLOWED_ERR: (self) 127 Raised if this media rule is readonly. 128 - SYNTAX_ERR: (CSSStyleRule) 129 Raised if the specified rule has a syntax error and is 130 unparsable. 131 132 returns the index within the media block's rule collection of the 133 newly inserted rule. 134 135 """ 136 self._checkReadonly() 137 138 # check position 139 if index is None: 140 index = len(self.cssRules) 141 elif index < 0 or index > self.cssRules.length: 142 raise xml.dom.IndexSizeErr( 143 u'CSSMediaRule: Invalid index %s for CSSRuleList with a length of %s.' % ( 144 index, self.cssRules.length)) 145 146 # parse 147 if isinstance(rule, basestring): 148 tempsheet = CSSStyleSheet() 149 tempsheet.cssText = rule 150 if len(tempsheet.cssRules) != 1 or (tempsheet.cssRules and 151 not isinstance(tempsheet.cssRules[0], cssutils.css.CSSRule)): 152 self._log.error(u'CSSMediaRule: Invalid Rule: %s' % rule) 153 return 154 rule = tempsheet.cssRules[0] 155 elif not isinstance(rule, cssutils.css.CSSRule): 156 self._log.error(u'CSSMediaRule: Not a CSSRule: %s' % rule) 157 return 158 159 # CHECK HIERARCHY 160 # @charset @import @media -> TODO: @page @namespace 161 if isinstance(rule, cssutils.css.CSSCharsetRule) or \ 162 isinstance(rule, cssutils.css.CSSImportRule) or \ 163 isinstance(rule, CSSMediaRule): 164 self._log.error(u'CSSMediaRule: This type of rule is not allowed here: %s' % 165 rule.cssText, 166 error=xml.dom.HierarchyRequestErr) 167 return 168 169 self.cssRules.insert(index, rule) 170 rule.parentRule = self 171 return index
172
173 - def _getCssText(self):
174 """ 175 returns serialized property cssText 176 """ 177 return cssutils.ser.do_CSSMediaRule(self)
178
179 - def _setCssText(self, cssText):
180 """ 181 DOMException on setting 182 183 - NO_MODIFICATION_ALLOWED_ERR: (self) 184 Raised if the rule is readonly. 185 - INVALID_MODIFICATION_ERR: (self) 186 Raised if the specified CSS string value represents a different 187 type of rule than the current one. 188 - HIERARCHY_REQUEST_ERR: (self) 189 Raised if the rule cannot be inserted at this point in the 190 style sheet. 191 - SYNTAX_ERR: (self) 192 Raised if the specified CSS string value has a syntax error and 193 is unparsable. 194 """ 195 super(CSSMediaRule, self)._setCssText(cssText) 196 tokens = self._tokenize(cssText) 197 valid = True 198 199 # check if right token 200 if not tokens or tokens and tokens[0].type != self._ttypes.MEDIA_SYM: 201 self._log.error(u'CSSMediaRule: No CSSMediaRule found: %s' % 202 self._valuestr(cssText), 203 error=xml.dom.InvalidModificationErr) 204 return 205 else: 206 newatkeyword = tokens[0].value 207 208 newmedia = cssutils.stylesheets.MediaList() 209 mediatokens, endi = self._tokensupto(tokens[1:], 210 blockstartonly=True) 211 212 # checks if media ends with rules start and if at least 213 # one media found, medialist default to all which is wrong here! 214 if mediatokens and mediatokens[-1].value == u'{' and \ 215 self._ttypes.IDENT in [_t.type for _t in mediatokens]: 216 newmedia.mediaText = mediatokens[:-1] 217 else: 218 self._log.error(xml.dom.SyntaxErr( 219 u'CSSMediaRule: Syntax error in MediaList: %s' % 220 self._valuestr(cssText))) 221 return 222 223 newrules = cssutils.css.CSSRuleList() 224 i, imax = endi + 2, len(tokens) 225 while i < imax: 226 t = tokens[i] 227 228 if t.type == self._ttypes.EOF: 229 break 230 231 elif self._ttypes.S == t.type: # ignore 232 pass 233 234 elif self._ttypes.COMMENT == t.type: # just add 235 newrules.append(cssutils.css.CSSComment(t)) 236 237 elif u'}' == t.value: # end 238 if i+1 < len(tokens): 239 self._log.error( 240 u'CSSMediaRule: Unexpected tokens found: "%s".' 241 % self._valuestr(tokens[i:]), t) 242 break 243 244 elif self._ttypes.ATKEYWORD == t.type: 245 # @UNKNOWN 246 self._log.info(u'CSSMediaRule: Found unknown @rule.', t, 247 error=None) 248 atruletokens, endi = self._tokensupto(tokens[i:]) 249 i += endi 250 atrule = cssutils.css.CSSUnknownRule() 251 atrule.cssText = atruletokens 252 newrules.append(atrule) 253 254 elif t.type in (self._ttypes.CHARSET_SYM, self._ttypes.IMPORT_SYM, 255 self._ttypes.MEDIA_SYM, self._ttypes.PAGE_SYM): 256 atruletokens, endi = self._tokensupto(tokens[i:]) 257 i += endi + 1 258 self._log.error( 259 u'CSSMediaRule: This rule is not allowed in CSSMediaRule - ignored: %s.' 260 % self._valuestr(atruletokens), t, 261 xml.dom.HierarchyRequestErr) 262 continue 263 264 else: 265 # StyleRule 266 ruletokens, endi = self._tokensupto( 267 tokens[i:], blockendonly=True) 268 i += endi 269 rule = cssutils.css.CSSStyleRule() 270 rule.cssText = ruletokens 271 newrules.append(rule) 272 273 i += 1 274 275 if valid: 276 self.atkeyword = newatkeyword 277 self._media = newmedia 278 self._rules = newrules 279 for r in self._rules: 280 r.parentRule = self
281 282 cssText = property(_getCssText, _setCssText, 283 doc="(DOM attribute) The parsable textual representation.") 284
285 - def __repr__(self):
286 return "cssutils.css.%s(mediaText=%r)" % ( 287 self.__class__.__name__, self.media.mediaText)
288
289 - def __str__(self):
290 return "<cssutils.css.%s object mediaText=%r at 0x%x>" % ( 291 self.__class__.__name__, self.media.mediaText, id(self))
292 293 294 if __name__ == '__main__': 295 m = CSSMediaRule() 296 m.cssText = u'@media all {@;}' 297 print m.cssText 298