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-10-27 21:33:12 +0200 (Sa, 27 Okt 2007) $' 
  9  __version__ = '$LastChangedRevision: 580 $' 
 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 if not new['name']: 209 wellformed = False 210 self._log.error(u'Property: No name found: %s' % 211 self._valuestr(name)) 212 213 if wellformed: 214 self.wellformed = True 215 self._name = new['name'] 216 self.normalname = self._normalize(self._name) 217 self.seqs[0] = newseq 218 219 # validate 220 if self.normalname not in cssproperties.cssvalues: 221 self.valid = False 222 self._log.info(u'Property: No CSS2 Property: "%s".' % 223 new['name'], neverraise=True) 224 else: 225 self.valid = True 226 if self.cssValue: 227 self.cssValue._propertyName = self.normalname 228 self.valid = self.cssValue.valid 229 230 231 else: 232 self.wellformed = False
233 234 name = property(_getName, _setName, 235 doc="(cssutils) Name of this property") 236
237 - def _getCSSValue(self):
238 return self.seqs[1]
239
240 - def _setCSSValue(self, cssText):
241 """ 242 see css.CSSValue 243 244 DOMException on setting? 245 246 - SYNTAX_ERR: (self) 247 Raised if the specified CSS string value has a syntax error 248 (according to the attached property) or is unparsable. 249 - TODO: INVALID_MODIFICATION_ERR: 250 Raised if the specified CSS string value represents a different 251 type of values than the values allowed by the CSS property. 252 """ 253 if self._mediaQuery and not cssText: 254 self.seqs[1] = CSSValue() 255 else: 256 if not self.seqs[1]: 257 self.seqs[1] = CSSValue() 258 259 cssvalue = self.seqs[1] 260 cssvalue._propertyName = self.name 261 cssvalue.cssText = cssText 262 if cssvalue._value and cssvalue.wellformed: 263 self.seqs[1] = cssvalue 264 self.valid = self.valid and cssvalue.valid 265 self.wellformed = self.wellformed and cssvalue.wellformed
266 267 cssValue = property(_getCSSValue, _setCSSValue, 268 doc="(cssutils) CSSValue object of this property") 269
270 - def _getValue(self):
271 if self.cssValue: return self.cssValue._value 272 else: return u''
273
274 - def _setValue(self, value):
275 self.cssValue.cssText = value 276 self.valid = self.valid and self.cssValue.valid 277 self.wellformed = self.wellformed and self.cssValue.wellformed
278 279 value = property(_getValue, _setValue, 280 doc="The textual value of this Properties cssValue.") 281
282 - def _getPriority(self):
283 return cssutils.ser.do_Property_priority(self.seqs[2])
284
285 - def _setPriority(self, priority):
286 """ 287 priority 288 a string 289 290 Format 291 ====== 292 :: 293 294 prio 295 : IMPORTANT_SYM S* 296 ; 297 298 "!"{w}"important" {return IMPORTANT_SYM;} 299 300 DOMException on setting 301 302 - SYNTAX_ERR: (self) 303 Raised if the specified priority has a syntax error and is 304 unparsable. 305 In this case a priority not equal to None, "" or "!{w}important". 306 """ 307 if self._mediaQuery: 308 self._priority = u'' 309 if priority: 310 self._log.error(u'Property: No priority in a MediaQuery - ignored.') 311 return 312 313 # for closures: must be a mutable 314 new = {'priority': u'', 315 'wellformed': True} 316 317 def _char(expected, seq, token, tokenizer=None): 318 # "!" 319 val = self._tokenvalue(token) 320 if u'!' == expected == val: 321 seq.append(val) 322 return 'important' 323 else: 324 new['wellformed'] = False 325 self._log.error(u'Property: Unexpected char.', token) 326 return expected
327 328 def _ident(expected, seq, token, tokenizer=None): 329 # "important" 330 val = self._tokenvalue(token) 331 normalval = self._tokenvalue(token, normalize=True) 332 if 'important' == expected == normalval: 333 new['priority'] = val 334 seq.append(val) 335 return 'EOF' 336 else: 337 new['wellformed'] = False 338 self._log.error(u'Property: Unexpected ident.', token) 339 return expected 340 341 newseq = [] 342 wellformed, expected = self._parse(expected='!', 343 seq=newseq, 344 tokenizer=self._tokenize2(priority), 345 productions={'CHAR': _char, 346 'IDENT': _ident}) 347 wellformed = wellformed and new['wellformed'] 348 349 # post conditions 350 if priority and not new['priority']: 351 wellformed = False 352 self._log.info(u'Property: Invalid priority: %r.' % 353 self._valuestr(priority)) 354 355 if wellformed: 356 self.wellformed = self.wellformed and wellformed 357 self._priority = new['priority'] 358 self._normalpriority = self._normalize(self._priority) 359 self.seqs[2] = newseq 360 361 # validate 362 if self._normalpriority not in (u'', u'important'): 363 self.valid = False 364 self._log.info(u'Property: No CSS2 priority value: %r.' % 365 self._normalpriority, neverraise=True) 366 367 priority = property(_getPriority, _setPriority, 368 doc="(cssutils) Priority of this property") 369
370 - def __repr__(self):
371 return "cssutils.css.%s(name=%r, value=%r, priority=%r)" % ( 372 self.__class__.__name__, 373 self.name, self.cssValue.cssText, self.priority)
374
375 - def __str__(self):
376 return "<%s.%s object name=%r value=%r priority=%r at 0x%x>" % ( 377 self.__class__.__module__, self.__class__.__name__, 378 self.name, self.cssValue.cssText, self.priority, id(self))
379