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

Source Code for Module cssutils.css.property

  1  """Property is a single CSS property in a CSSStyleDeclaration 
  2   
  3  Internal use only, may be removed in the future! 
  4  """ 
  5  __all__ = ['Property'] 
  6  __docformat__ = 'restructuredtext' 
  7  __author__ = '$LastChangedBy: cthedot $' 
  8  __date__ = '$LastChangedDate: 2008-02-19 22:56:27 +0100 (Di, 19 Feb 2008) $' 
  9  __version__ = '$LastChangedRevision: 1068 $' 
 10   
 11  import xml.dom 
 12  import cssutils 
 13  import cssproperties 
 14  from cssvalue import CSSValue 
 15  from cssutils.util import Deprecated 
16 17 -class Property(cssutils.util.Base):
18 """ 19 (cssutils) a CSS property in a StyleDeclaration of a CSSStyleRule 20 21 Properties 22 ========== 23 cssText 24 a parsable textual representation of this property 25 name 26 normalized name of the property, e.g. "color" when name is "c\olor" 27 (since 0.9.5) 28 literalname (since 0.9.5) 29 original name of the property in the source CSS which is not normalized 30 e.g. "C\\OLor" 31 cssValue 32 the relevant CSSValue instance for this property 33 value 34 the string value of the property, same as cssValue.cssText 35 priority 36 of the property (currently only u"important" or None) 37 literalpriority 38 original priority of the property in the source CSS which is not 39 normalized e.g. "IM\portant" 40 seqs 41 combination of a list for seq of name, a CSSValue object, and 42 a list for seq of priority (empty or [!important] currently) 43 valid 44 if this Property is valid 45 wellformed 46 if this Property is syntactically ok 47 48 DEPRECATED normalname (since 0.9.5) 49 normalized name of the property, e.g. "color" when name is "c\olor" 50 51 Format 52 ====== 53 :: 54 55 property = name 56 : IDENT S* 57 ; 58 59 expr = value 60 : term [ operator term ]* 61 ; 62 term 63 : unary_operator? 64 [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* | 65 TIME S* | FREQ S* | function ] 66 | STRING S* | IDENT S* | URI S* | hexcolor 67 ; 68 function 69 : FUNCTION S* expr ')' S* 70 ; 71 /* 72 * There is a constraint on the color that it must 73 * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F]) 74 * after the "#"; e.g., "#000" is OK, but "#abcd" is not. 75 */ 76 hexcolor 77 : HASH S* 78 ; 79 80 prio 81 : IMPORTANT_SYM S* 82 ; 83 84 """
85 - def __init__(self, name=None, value=None, priority=u'', _mediaQuery=False):
86 """ 87 inits property 88 89 name 90 a property name string (will be normalized) 91 value 92 a property value string 93 priority 94 an optional priority string which currently must be u'', 95 u'!important' or u'important' 96 _mediaQuery boolean 97 if True value is optional as used by MediaQuery objects 98 """ 99 super(Property, self).__init__() 100 101 self.seqs = [[], None, []] 102 self.valid = False 103 self.wellformed = False 104 self._mediaQuery = _mediaQuery 105 106 if name: 107 self.name = name 108 else: 109 self._name = u'' 110 self._literalname = u'' 111 self.__normalname = u'' # DEPRECATED 112 113 if value: 114 self.cssValue = value 115 else: 116 self.seqs[1] = CSSValue() 117 118 if priority: 119 self.priority = priority 120 else: 121 self._priority = u'' 122 self._literalpriority = u''
123
124 - def _getCssText(self):
125 """ 126 returns serialized property cssText 127 """ 128 return cssutils.ser.do_Property(self)
129
130 - def _setCssText(self, cssText):
131 """ 132 DOMException on setting 133 134 - NO_MODIFICATION_ALLOWED_ERR: (CSSRule) 135 Raised if the rule is readonly. 136 - SYNTAX_ERR: (self) 137 Raised if the specified CSS string value has a syntax error and 138 is unparsable. 139 """ 140 # check and prepare tokenlists for setting 141 tokenizer = self._tokenize2(cssText) 142 nametokens = self._tokensupto2(tokenizer, propertynameendonly=True) 143 if nametokens: 144 wellformed = True 145 146 valuetokens = self._tokensupto2(tokenizer, 147 propertyvalueendonly=True) 148 prioritytokens = self._tokensupto2(tokenizer, 149 propertypriorityendonly=True) 150 151 if self._mediaQuery and not valuetokens: 152 # MediaQuery may consist of name only 153 self.name = nametokens 154 self.cssValue = None 155 self.priority = None 156 return 157 158 # remove colon from nametokens 159 colontoken = nametokens.pop() 160 if self._tokenvalue(colontoken) != u':': 161 wellformed = False 162 self._log.error(u'Property: No ":" after name found: %r' % 163 self._valuestr(cssText), colontoken) 164 elif not nametokens: 165 wellformed = False 166 self._log.error(u'Property: No property name found: %r.' % 167 self._valuestr(cssText), colontoken) 168 169 if valuetokens: 170 if self._tokenvalue(valuetokens[-1]) == u'!': 171 # priority given, move "!" to prioritytokens 172 prioritytokens.insert(0, valuetokens.pop(-1)) 173 else: 174 wellformed = False 175 self._log.error(u'Property: No property value found: %r.' % 176 self._valuestr(cssText), colontoken) 177 178 if wellformed: 179 self.wellformed = True 180 self.name = nametokens 181 self.cssValue = valuetokens 182 self.priority = prioritytokens 183 184 else: 185 self._log.error(u'Property: No property name found: %r.' % 186 self._valuestr(cssText))
187 188 cssText = property(fget=_getCssText, fset=_setCssText, 189 doc="A parsable textual representation.") 190
191 - def _setName(self, name):
192 """ 193 DOMException on setting 194 195 - SYNTAX_ERR: (self) 196 Raised if the specified name has a syntax error and is 197 unparsable. 198 """ 199 # for closures: must be a mutable 200 new = {'literalname': None, 201 'wellformed': True} 202 203 def _ident(expected, seq, token, tokenizer=None): 204 # name 205 if 'name' == expected: 206 new['literalname'] = self._tokenvalue(token).lower() 207 seq.append(new['literalname']) 208 return 'EOF' 209 else: 210 new['wellformed'] = False 211 self._log.error(u'Property: Unexpected ident.', token) 212 return expected
213 214 newseq = [] 215 wellformed, expected = self._parse(expected='name', 216 seq=newseq, 217 tokenizer=self._tokenize2(name), 218 productions={'IDENT': _ident}) 219 wellformed = wellformed and new['wellformed'] 220 221 # post conditions 222 # define a token for error logging 223 if isinstance(name, list): 224 token = name[0] 225 else: 226 token = None 227 228 if not new['literalname']: 229 wellformed = False 230 self._log.error(u'Property: No name found: %r' % 231 self._valuestr(name), token=token) 232 233 if wellformed: 234 self.wellformed = True 235 self._literalname = new['literalname'] 236 self._name = self._normalize(self._literalname) 237 self.__normalname = self._name # DEPRECATED 238 self.seqs[0] = newseq 239 240 # validate 241 if self._name not in cssproperties.cssvalues: 242 self.valid = False 243 tokenizer=self._tokenize2(name) 244 self._log.info(u'Property: No CSS2 Property: %r.' % 245 new['literalname'], token=token, neverraise=True) 246 else: 247 self.valid = True 248 if self.cssValue: 249 self.cssValue._propertyName = self._name 250 self.valid = self.cssValue.valid 251 else: 252 self.wellformed = False
253 254 name = property(lambda self: self._name, _setName, 255 doc="Name of this property") 256 257 literalname = property(lambda self: self._literalname, 258 doc="Readonly literal (not normalized) name of this property") 259
260 - def _getCSSValue(self):
261 return self.seqs[1]
262
263 - def _setCSSValue(self, cssText):
264 """ 265 see css.CSSValue 266 267 DOMException on setting? 268 269 - SYNTAX_ERR: (self) 270 Raised if the specified CSS string value has a syntax error 271 (according to the attached property) or is unparsable. 272 - TODO: INVALID_MODIFICATION_ERR: 273 Raised if the specified CSS string value represents a different 274 type of values than the values allowed by the CSS property. 275 """ 276 if self._mediaQuery and not cssText: 277 self.seqs[1] = CSSValue() 278 else: 279 if not self.seqs[1]: 280 self.seqs[1] = CSSValue() 281 282 cssvalue = self.seqs[1] 283 cssvalue._propertyName = self.name 284 cssvalue.cssText = cssText 285 if cssvalue._value and cssvalue.wellformed: 286 self.seqs[1] = cssvalue 287 self.valid = self.valid and cssvalue.valid 288 self.wellformed = self.wellformed and cssvalue.wellformed
289 290 cssValue = property(_getCSSValue, _setCSSValue, 291 doc="(cssutils) CSSValue object of this property") 292
293 - def _getValue(self):
294 if self.cssValue: 295 return self.cssValue._value 296 else: 297 return u''
298
299 - def _setValue(self, value):
300 self.cssValue.cssText = value 301 self.valid = self.valid and self.cssValue.valid 302 self.wellformed = self.wellformed and self.cssValue.wellformed
303 304 value = property(_getValue, _setValue, 305 doc="The textual value of this Properties cssValue.") 306
307 - def _setPriority(self, priority):
308 """ 309 priority 310 a string, currently either u'', u'!important' or u'important' 311 312 Format 313 ====== 314 :: 315 316 prio 317 : IMPORTANT_SYM S* 318 ; 319 320 "!"{w}"important" {return IMPORTANT_SYM;} 321 322 DOMException on setting 323 324 - SYNTAX_ERR: (self) 325 Raised if the specified priority has a syntax error and is 326 unparsable. 327 In this case a priority not equal to None, "" or "!{w}important". 328 As CSSOM defines CSSStyleDeclaration.getPropertyPriority resulting in 329 u'important' this value is also allowed to set a Properties priority 330 """ 331 if self._mediaQuery: 332 self._priority = u'' 333 self._literalpriority = u'' 334 if priority: 335 self._log.error(u'Property: No priority in a MediaQuery - ignored.') 336 return 337 338 if isinstance(priority, basestring) and\ 339 u'important' == self._normalize(priority): 340 priority = u'!%s' % priority 341 342 # for closures: must be a mutable 343 new = {'literalpriority': u'', 344 'wellformed': True} 345 346 def _char(expected, seq, token, tokenizer=None): 347 # "!" 348 val = self._tokenvalue(token) 349 if u'!' == expected == val: 350 seq.append(val) 351 return 'important' 352 else: 353 new['wellformed'] = False 354 self._log.error(u'Property: Unexpected char.', token) 355 return expected
356 357 def _ident(expected, seq, token, tokenizer=None): 358 # "important" 359 val = self._tokenvalue(token) 360 normalval = self._tokenvalue(token, normalize=True) 361 if 'important' == expected == normalval: 362 new['literalpriority'] = val 363 seq.append(val) 364 return 'EOF' 365 else: 366 new['wellformed'] = False 367 self._log.error(u'Property: Unexpected ident.', token) 368 return expected 369 370 newseq = [] 371 wellformed, expected = self._parse(expected='!', 372 seq=newseq, 373 tokenizer=self._tokenize2(priority), 374 productions={'CHAR': _char, 375 'IDENT': _ident}) 376 wellformed = wellformed and new['wellformed'] 377 378 # post conditions 379 if priority and not new['literalpriority']: 380 wellformed = False 381 self._log.info(u'Property: Invalid priority: %r.' % 382 self._valuestr(priority)) 383 384 if wellformed: 385 self.wellformed = self.wellformed and wellformed 386 self._literalpriority = new['literalpriority'] 387 self._priority = self._normalize(self.literalpriority) 388 self.seqs[2] = newseq 389 390 # validate 391 if self._priority not in (u'', u'important'): 392 self.valid = False 393 self._log.info(u'Property: No CSS2 priority value: %r.' % 394 self._priority, neverraise=True) 395 396 priority = property(lambda self: self._priority, _setPriority, 397 doc="(cssutils) Priority of this property") 398 399 literalpriority = property(lambda self: self._literalpriority, 400 doc="Readonly literal (not normalized) priority of this property") 401
402 - def __repr__(self):
403 return "cssutils.css.%s(name=%r, value=%r, priority=%r)" % ( 404 self.__class__.__name__, 405 self.literalname, self.cssValue.cssText, self.priority)
406
407 - def __str__(self):
408 return "<%s.%s object name=%r value=%r priority=%r at 0x%x>" % ( 409 self.__class__.__module__, self.__class__.__name__, 410 self.name, self.cssValue.cssText, self.priority, id(self))
411 412 @Deprecated(u'Use property ``name`` instead (since cssutils 0.9.5).')
413 - def _getNormalname(self):
414 return self.__normalname
415 normalname = property(_getNormalname, 416 doc="DEPRECATED since 0.9.5, use name instead") 417