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