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-01-27 17:57:38 +0100 (So, 27 Jan 2008) $' 
  9  __version__ = '$LastChangedRevision: 955 $' 
 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 valuetokens = self._tokensupto2(tokenizer, propertyvalueendonly=True) 144 prioritytokens = self._tokensupto2(tokenizer, propertypriorityendonly=True) 145 146 wellformed = True 147 if nametokens: 148 if self._mediaQuery and not valuetokens: 149 # MediaQuery may consist of name only 150 self.name = nametokens 151 self.cssValue = None 152 self.priority = None 153 return 154 155 # remove colon from nametokens 156 colontoken = nametokens.pop() 157 if self._tokenvalue(colontoken) != u':': 158 wellformed = False 159 self._log.error(u'Property: No ":" after name found: %r' % 160 self._valuestr(cssText), colontoken) 161 elif not nametokens: 162 wellformed = False 163 self._log.error(u'Property: No property name found: %r.' % 164 self._valuestr(cssText), colontoken) 165 166 if valuetokens: 167 if self._tokenvalue(valuetokens[-1]) == u'!': 168 # priority given, move "!" to prioritytokens 169 prioritytokens.insert(0, valuetokens.pop(-1)) 170 else: 171 wellformed = False 172 self._log.error(u'Property: No property value found: %r.' % 173 self._valuestr(cssText), colontoken) 174 175 if wellformed: 176 self.wellformed = True 177 self.name = nametokens 178 self.cssValue = valuetokens 179 self.priority = prioritytokens 180 181 else: 182 self._log.error(u'Property: No property name found: %r.' % 183 self._valuestr(cssText))
184 185 cssText = property(fget=_getCssText, fset=_setCssText, 186 doc="A parsable textual representation.") 187
188 - def _setName(self, name):
189 """ 190 DOMException on setting 191 192 - SYNTAX_ERR: (self) 193 Raised if the specified name has a syntax error and is 194 unparsable. 195 """ 196 # for closures: must be a mutable 197 new = {'literalname': None, 198 'wellformed': True} 199 200 def _ident(expected, seq, token, tokenizer=None): 201 # name 202 if 'name' == expected: 203 new['literalname'] = self._tokenvalue(token).lower() 204 seq.append(new['literalname']) 205 return 'EOF' 206 else: 207 new['wellformed'] = False 208 self._log.error(u'Property: Unexpected ident.', token) 209 return expected
210 211 newseq = [] 212 wellformed, expected = self._parse(expected='name', 213 seq=newseq, 214 tokenizer=self._tokenize2(name), 215 productions={'IDENT': _ident}) 216 wellformed = wellformed and new['wellformed'] 217 218 # post conditions 219 # define a token for error logging 220 if isinstance(name, list): 221 token = name[0] 222 else: 223 token = None 224 225 if not new['literalname']: 226 wellformed = False 227 self._log.error(u'Property: No name found: %r' % 228 self._valuestr(name), token=token) 229 230 if wellformed: 231 self.wellformed = True 232 self._literalname = new['literalname'] 233 self._name = self._normalize(self._literalname) 234 self.__normalname = self._name # DEPRECATED 235 self.seqs[0] = newseq 236 237 # validate 238 if self._name not in cssproperties.cssvalues: 239 self.valid = False 240 tokenizer=self._tokenize2(name) 241 self._log.info(u'Property: No CSS2 Property: %r.' % 242 new['literalname'], token=token, neverraise=True) 243 else: 244 self.valid = True 245 if self.cssValue: 246 self.cssValue._propertyName = self._name 247 self.valid = self.cssValue.valid 248 else: 249 self.wellformed = False
250 251 name = property(lambda self: self._name, _setName, 252 doc="Name of this property") 253 254 literalname = property(lambda self: self._literalname, 255 doc="Readonly literal (not normalized) name of this property") 256
257 - def _getCSSValue(self):
258 return self.seqs[1]
259
260 - def _setCSSValue(self, cssText):
261 """ 262 see css.CSSValue 263 264 DOMException on setting? 265 266 - SYNTAX_ERR: (self) 267 Raised if the specified CSS string value has a syntax error 268 (according to the attached property) or is unparsable. 269 - TODO: INVALID_MODIFICATION_ERR: 270 Raised if the specified CSS string value represents a different 271 type of values than the values allowed by the CSS property. 272 """ 273 if self._mediaQuery and not cssText: 274 self.seqs[1] = CSSValue() 275 else: 276 if not self.seqs[1]: 277 self.seqs[1] = CSSValue() 278 279 cssvalue = self.seqs[1] 280 cssvalue._propertyName = self.name 281 cssvalue.cssText = cssText 282 if cssvalue._value and cssvalue.wellformed: 283 self.seqs[1] = cssvalue 284 self.valid = self.valid and cssvalue.valid 285 self.wellformed = self.wellformed and cssvalue.wellformed
286 287 cssValue = property(_getCSSValue, _setCSSValue, 288 doc="(cssutils) CSSValue object of this property") 289
290 - def _getValue(self):
291 if self.cssValue: 292 return self.cssValue._value 293 else: 294 return u''
295
296 - def _setValue(self, value):
297 self.cssValue.cssText = value 298 self.valid = self.valid and self.cssValue.valid 299 self.wellformed = self.wellformed and self.cssValue.wellformed
300 301 value = property(_getValue, _setValue, 302 doc="The textual value of this Properties cssValue.") 303
304 - def _setPriority(self, priority):
305 """ 306 priority 307 a string, currently either u'', u'!important' or u'important' 308 309 Format 310 ====== 311 :: 312 313 prio 314 : IMPORTANT_SYM S* 315 ; 316 317 "!"{w}"important" {return IMPORTANT_SYM;} 318 319 DOMException on setting 320 321 - SYNTAX_ERR: (self) 322 Raised if the specified priority has a syntax error and is 323 unparsable. 324 In this case a priority not equal to None, "" or "!{w}important". 325 As CSSOM defines CSSStyleDeclaration.getPropertyPriority resulting in 326 u'important' this value is also allowed to set a Properties priority 327 """ 328 if self._mediaQuery: 329 self._priority = u'' 330 self._literalpriority = u'' 331 if priority: 332 self._log.error(u'Property: No priority in a MediaQuery - ignored.') 333 return 334 335 if isinstance(priority, basestring) and\ 336 u'important' == self._normalize(priority): 337 priority = u'!%s' % priority 338 339 # for closures: must be a mutable 340 new = {'literalpriority': u'', 341 'wellformed': True} 342 343 def _char(expected, seq, token, tokenizer=None): 344 # "!" 345 val = self._tokenvalue(token) 346 if u'!' == expected == val: 347 seq.append(val) 348 return 'important' 349 else: 350 new['wellformed'] = False 351 self._log.error(u'Property: Unexpected char.', token) 352 return expected
353 354 def _ident(expected, seq, token, tokenizer=None): 355 # "important" 356 val = self._tokenvalue(token) 357 normalval = self._tokenvalue(token, normalize=True) 358 if 'important' == expected == normalval: 359 new['literalpriority'] = val 360 seq.append(val) 361 return 'EOF' 362 else: 363 new['wellformed'] = False 364 self._log.error(u'Property: Unexpected ident.', token) 365 return expected 366 367 newseq = [] 368 wellformed, expected = self._parse(expected='!', 369 seq=newseq, 370 tokenizer=self._tokenize2(priority), 371 productions={'CHAR': _char, 372 'IDENT': _ident}) 373 wellformed = wellformed and new['wellformed'] 374 375 # post conditions 376 if priority and not new['literalpriority']: 377 wellformed = False 378 self._log.info(u'Property: Invalid priority: %r.' % 379 self._valuestr(priority)) 380 381 if wellformed: 382 self.wellformed = self.wellformed and wellformed 383 self._literalpriority = new['literalpriority'] 384 self._priority = self._normalize(self.literalpriority) 385 self.seqs[2] = newseq 386 387 # validate 388 if self._priority not in (u'', u'important'): 389 self.valid = False 390 self._log.info(u'Property: No CSS2 priority value: %r.' % 391 self._priority, neverraise=True) 392 393 priority = property(lambda self: self._priority, _setPriority, 394 doc="(cssutils) Priority of this property") 395 396 literalpriority = property(lambda self: self._literalpriority, 397 doc="Readonly literal (not normalized) priority of this property") 398
399 - def __repr__(self):
400 return "cssutils.css.%s(name=%r, value=%r, priority=%r)" % ( 401 self.__class__.__name__, 402 self.literalname, self.cssValue.cssText, self.priority)
403
404 - def __str__(self):
405 return "<%s.%s object name=%r value=%r priority=%r at 0x%x>" % ( 406 self.__class__.__module__, self.__class__.__name__, 407 self.name, self.cssValue.cssText, self.priority, id(self))
408 409 @Deprecated(u'Use property ``name`` instead (since cssutils 0.9.5).')
410 - def _getNormalname(self):
411 return self.__normalname
412 normalname = property(_getNormalname, 413 doc="DEPRECATED since 0.9.5, use name instead") 414