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 1152 2008-03-18 22:36:39Z 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 = 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 # update seq 286 for i, item in enumerate(self.seq): 287 val, typ = item.value, item.type 288 if 'name' == typ: 289 self._seq[i] = (name, typ, item.line, item.col) 290 break 291 else: 292 # append 293 seq = self._tempSeq() 294 for item in self.seq: 295 # copy current seq 296 seq.append(item.value, item.type, item.line, item.col) 297 seq.append(self.href, 'href') 298 self._setSeq(seq) 299 self._name = name 300 # set title of referred sheet 301 if self.styleSheet: 302 self.styleSheet.title = name
303 304 name = property(lambda self: self._name, _setName, 305 doc=u"An optional name for the imported sheet") 306
307 - def __setStyleSheet(self):
308 """Read new CSSStyleSheet cssText from href using parentStyleSheet.base 309 310 indirectly called if setting ``href`` 311 """ 312 # should simply fail so all errors are catched! 313 if self.parentStyleSheet and self.href: 314 href = urlparse.urljoin(self.parentStyleSheet.href, self.href) 315 316 try: 317 # all possible exceptions are ignored and styleSheet is None 318 sheet = cssutils.css.CSSStyleSheet(href=href, 319 media=self.media, 320 ownerRule=self, 321 title=self.name) 322 cssText = cssutils.util._readURL(href) 323 if not cssText: 324 raise IOError() 325 sheet.cssText = cssText 326 except Exception, e: 327 self._log.warn(u'CSSImportRule: Error processing imported style sheet: href=%r: %r' 328 % (self.href, e), neverraise=True) 329 else: 330 self._styleSheet = sheet
331 332 styleSheet = property(lambda self: self._styleSheet, 333 doc="(readonly) The style sheet referred to by this rule.") 334 335 wellformed = property(lambda self: bool(self.href and self.media.wellformed)) 336
337 - def __repr__(self):
338 return "cssutils.css.%s(href=%r, mediaText=%r, name=%r)" % ( 339 self.__class__.__name__, 340 self.href, self.media.mediaText, self.name)
341
342 - def __str__(self):
343 return "<cssutils.css.%s object href=%r at 0x%x>" % ( 344 self.__class__.__name__, self.href, id(self))
345