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

Source Code for Module cssutils.css.cssimportrule

  1  """CSSImportRule implements DOM Level 2 CSS CSSImportRule. 
  2   
  3  plus:  
  4   
  5  ``name`` property 
  6      http://www.w3.org/TR/css3-cascade/#cascading 
  7   
  8  """ 
  9  __all__ = ['CSSImportRule'] 
 10  __docformat__ = 'restructuredtext' 
 11  __version__ = '$Id: cssimportrule.py 1199 2008-03-23 00:18:28Z cthedot $' 
 12   
 13  import os 
 14  import urlparse 
 15  import xml.dom 
 16  import cssrule 
 17  import cssutils 
 18   
19 -class CSSImportRule(cssrule.CSSRule):
20 """ 21 Represents an @import rule within a CSS style sheet. The @import rule 22 is used to import style rules from other style sheets. 23 24 Properties 25 ========== 26 atkeyword: (cssutils only) 27 the literal keyword used 28 cssText: of type DOMString 29 The parsable textual representation of this rule 30 href: of type DOMString, (DOM readonly, cssutils also writable) 31 The location of the style sheet to be imported. The attribute will 32 not contain the url(...) specifier around the URI. 33 hreftype: 'uri' (serializer default) or 'string' (cssutils only) 34 The original type of href, not really relevant as it may be 35 reconfigured in the serializer but it is kept anyway 36 media: of type stylesheets::MediaList (DOM readonly) 37 A list of media types for this rule of type MediaList. 38 name: 39 An optional name used for cascading 40 styleSheet: of type CSSStyleSheet (DOM readonly) 41 The style sheet referred to by this rule. The value of this 42 attribute is None if the style sheet has not yet been loaded or if 43 it will not be loaded (e.g. if the stylesheet is for a media type 44 not supported by the user agent). 45 46 Inherits properties from CSSRule 47 48 Format 49 ====== 50 import 51 : IMPORT_SYM S* 52 [STRING|URI] S* [ medium [ COMMA S* medium]* ]? S* STRING? S* ';' S* 53 ; 54 """ 55 type = property(lambda self: cssrule.CSSRule.IMPORT_RULE) 56
57 - def __init__(self, href=None, mediaText=u'all', name=None, 58 parentRule=None, parentStyleSheet=None, readonly=False):
59 """ 60 if readonly allows setting of properties in constructor only 61 62 Do not use as positional but as keyword attributes only! 63 64 href 65 location of the style sheet to be imported. 66 mediaText 67 A list of media types for which this style sheet may be used 68 as a string 69 """ 70 super(CSSImportRule, self).__init__(parentRule=parentRule, 71 parentStyleSheet=parentStyleSheet) 72 self._atkeyword = u'@import' 73 self.hreftype = None 74 self._styleSheet = None 75 76 self._href = None 77 self.href = href 78 79 self._media = cssutils.stylesheets.MediaList( 80 mediaText, readonly=readonly) 81 self._name = name 82 if not self.media.wellformed: 83 self._media = cssutils.stylesheets.MediaList() 84 85 seq = self._tempSeq() 86 seq.append(self.href, 'href') 87 seq.append(self.media, 'media') 88 seq.append(self.name, 'name') 89 self._setSeq(seq) 90 91 self._readonly = readonly
92
93 - def _getCssText(self):
94 """ 95 returns serialized property cssText 96 """ 97 return cssutils.ser.do_CSSImportRule(self)
98
99 - def _setCssText(self, cssText):
100 """ 101 DOMException on setting 102 103 - HIERARCHY_REQUEST_ERR: (CSSStylesheet) 104 Raised if the rule cannot be inserted at this point in the 105 style sheet. 106 - INVALID_MODIFICATION_ERR: (self) 107 Raised if the specified CSS string value represents a different 108 type of rule than the current one. 109 - NO_MODIFICATION_ALLOWED_ERR: (CSSRule) 110 Raised if the rule is readonly. 111 - SYNTAX_ERR: (self) 112 Raised if the specified CSS string value has a syntax error and 113 is unparsable. 114 """ 115 super(CSSImportRule, self)._setCssText(cssText) 116 tokenizer = self._tokenize2(cssText) 117 attoken = self._nexttoken(tokenizer, None) 118 if self._type(attoken) != self._prods.IMPORT_SYM: 119 self._log.error(u'CSSImportRule: No CSSImportRule found: %s' % 120 self._valuestr(cssText), 121 error=xml.dom.InvalidModificationErr) 122 else: 123 # for closures: must be a mutable 124 new = {'keyword': self._tokenvalue(attoken), 125 'href': None, 126 'hreftype': None, 127 'media': cssutils.stylesheets.MediaList(), 128 'name': None, 129 'wellformed': True 130 } 131 132 def __doname(seq, token): 133 # called by _string or _ident 134 new['name'] = self._stringtokenvalue(token) 135 seq.append(new['name'], 'name') 136 return ';'
137 138 def _string(expected, seq, token, tokenizer=None): 139 if 'href' == expected: 140 # href 141 new['href'] = self._stringtokenvalue(token) 142 new['hreftype'] = 'string' 143 seq.append(new['href'], 'href') 144 return 'media name ;' 145 elif 'name' in expected: 146 # name 147 return __doname(seq, token) 148 else: 149 new['wellformed'] = False 150 self._log.error( 151 u'CSSImportRule: Unexpected string.', token) 152 return expected
153 154 def _uri(expected, seq, token, tokenizer=None): 155 # href 156 if 'href' == expected: 157 uri = self._uritokenvalue(token) 158 new['hreftype'] = 'uri' 159 new['href'] = uri 160 seq.append(new['href'], 'href') 161 return 'media name ;' 162 else: 163 new['wellformed'] = False 164 self._log.error( 165 u'CSSImportRule: Unexpected URI.', token) 166 return expected 167 168 def _ident(expected, seq, token, tokenizer=None): 169 # medialist ending with ; which is checked upon too 170 if expected.startswith('media'): 171 mediatokens = self._tokensupto2( 172 tokenizer, importmediaqueryendonly=True) 173 mediatokens.insert(0, token) # push found token 174 175 last = mediatokens.pop() # retrieve ; 176 lastval, lasttyp = self._tokenvalue(last), self._type(last) 177 if lastval != u';' and lasttyp not in ('EOF', self._prods.STRING): 178 new['wellformed'] = False 179 self._log.error(u'CSSImportRule: No ";" found: %s' % 180 self._valuestr(cssText), token=token) 181 182 media = cssutils.stylesheets.MediaList() 183 media.mediaText = mediatokens 184 if media.wellformed: 185 new['media'] = media 186 seq.append(media, 'media') 187 else: 188 new['wellformed'] = False 189 self._log.error(u'CSSImportRule: Invalid MediaList: %s' % 190 self._valuestr(cssText), token=token) 191 192 if lasttyp == self._prods.STRING: 193 # name 194 return __doname(seq, last) 195 else: 196 return 'EOF' # ';' is token "last" 197 else: 198 new['wellformed'] = False 199 self._log.error( 200 u'CSSImportRule: Unexpected ident.', token) 201 return expected 202 203 def _char(expected, seq, token, tokenizer=None): 204 # final ; 205 val = self._tokenvalue(token) 206 if expected.endswith(';') and u';' == val: 207 return 'EOF' 208 else: 209 new['wellformed'] = False 210 self._log.error( 211 u'CSSImportRule: Unexpected char.', token) 212 return expected 213 214 # import : IMPORT_SYM S* [STRING|URI] 215 # S* [ medium [ ',' S* medium]* ]? ';' S* 216 # STRING? # see http://www.w3.org/TR/css3-cascade/#cascading 217 # ; 218 newseq = self._tempSeq() 219 wellformed, expected = self._parse(expected='href', 220 seq=newseq, tokenizer=tokenizer, 221 productions={'STRING': _string, 222 'URI': _uri, 223 'IDENT': _ident, 224 'CHAR': _char}, 225 new=new) 226 227 # wellformed set by parse 228 wellformed = wellformed and new['wellformed'] 229 230 # post conditions 231 if not new['href']: 232 wellformed = False 233 self._log.error(u'CSSImportRule: No href found: %s' % 234 self._valuestr(cssText)) 235 236 if expected != 'EOF': 237 wellformed = False 238 self._log.error(u'CSSImportRule: No ";" found: %s' % 239 self._valuestr(cssText)) 240 241 # set all 242 if wellformed: 243 self.atkeyword = new['keyword'] 244 self.hreftype = new['hreftype'] 245 self._media = new['media'] 246 self.name = new['name'] 247 self._setSeq(newseq) 248 249 self.href = new['href'] 250 251 if self.styleSheet: 252 # title is set by href 253 #self.styleSheet._href = self.href 254 self.styleSheet._parentStyleSheet = self.parentStyleSheet 255 256 cssText = property(fget=_getCssText, fset=_setCssText, 257 doc="(DOM attribute) The parsable textual representation.") 258
259 - def _setHref(self, href):
260 # update seq 261 for i, item in enumerate(self.seq): 262 val, typ = item.value, item.type 263 if 'href' == typ: 264 self._seq[i] = (href, typ, item.line, item.col) 265 break 266 else: 267 seq = self._tempSeq() 268 seq.append(self.href, 'href') 269 self._setSeq(seq) 270 # set new href 271 self._href = href 272 273 if not self.styleSheet: 274 # set only if not set before 275 self.__setStyleSheet()
276 277 href = property(lambda self: self._href, _setHref, 278 doc="Location of the style sheet to be imported.") 279 280 media = property(lambda self: self._media, 281 doc=u"(DOM readonly) A list of media types for this rule" 282 " of type MediaList") 283
284 - def _setName(self, name):
285 """raises xml.dom.SyntaxErr if name is not a string""" 286 if isinstance(name, basestring) or name is None: 287 # "" or '' 288 if not name: 289 name = None 290 # update seq 291 for i, item in enumerate(self.seq): 292 val, typ = item.value, item.type 293 if 'name' == typ: 294 self._seq[i] = (name, typ, item.line, item.col) 295 break 296 else: 297 # append 298 seq = self._tempSeq() 299 for item in self.seq: 300 # copy current seq 301 seq.append(item.value, item.type, item.line, item.col) 302 seq.append(name, 'name') 303 self._setSeq(seq) 304 self._name = name 305 # set title of referred sheet 306 if self.styleSheet: 307 self.styleSheet.title = name 308 else: 309 self._log.error(u'CSSImportRule: Not a valid name: %s' % name)
310 311 name = property(lambda self: self._name, _setName, 312 doc=u"An optional name for the imported sheet") 313
314 - def __setStyleSheet(self):
315 """Read new CSSStyleSheet cssText from href using parentStyleSheet.base 316 317 indirectly called if setting ``href`` 318 """ 319 # should simply fail so all errors are catched! 320 if self.parentStyleSheet and self.href: 321 href = urlparse.urljoin(self.parentStyleSheet.href, self.href) 322 323 try: 324 # all possible exceptions are ignored and styleSheet is None 325 sheet = cssutils.css.CSSStyleSheet(href=href, 326 media=self.media, 327 ownerRule=self, 328 title=self.name) 329 cssText = cssutils.util._readURL(href) 330 if not cssText: 331 raise IOError() 332 sheet.cssText = cssText 333 except Exception, e: 334 self._log.warn(u'CSSImportRule: Error processing imported style sheet: href=%r: %r' 335 % (self.href, e), neverraise=True) 336 else: 337 self._styleSheet = sheet
338 339 styleSheet = property(lambda self: self._styleSheet, 340 doc="(readonly) The style sheet referred to by this rule.") 341 342 wellformed = property(lambda self: bool(self.href and self.media.wellformed)) 343
344 - def __repr__(self):
345 if self.media: 346 mediaText = self.media.mediaText 347 else: 348 mediaText = None 349 return "cssutils.css.%s(href=%r, mediaText=%r, name=%r)" % ( 350 self.__class__.__name__, 351 self.href, self.media.mediaText, self.name)
352
353 - def __str__(self):
354 if self.media: 355 mediaText = self.media.mediaText 356 else: 357 mediaText = None 358 return "<cssutils.css.%s object href=%r mediaText=%r name=%r at 0x%x>" % ( 359 self.__class__.__name__, self.href, mediaText, self.name, id(self))
360