1 """CSSValue related classes
2
3 - CSSValue implements DOM Level 2 CSS CSSValue
4 - CSSPrimitiveValue implements DOM Level 2 CSS CSSPrimitiveValue
5 - CSSValueList implements DOM Level 2 CSS CSSValueList
6
7 """
8 __all__ = ['CSSValue', 'CSSPrimitiveValue', 'CSSValueList']
9 __docformat__ = 'restructuredtext'
10 __author__ = '$LastChangedBy: cthedot $'
11 __date__ = '$LastChangedDate: 2007-09-01 18:44:48 +0200 (Sa, 01 Sep 2007) $'
12 __version__ = '$LastChangedRevision: 306 $'
13
14 import re
15 import types
16 import xml.dom
17 import cssutils
18 import cssproperties
19 from cssutils.token import Token
20
22 """
23 The CSSValue interface represents a simple or a complex value.
24 A CSSValue object only occurs in a context of a CSS property
25
26 Properties
27 ==========
28 cssText
29 A string representation of the current value.
30 cssValueType
31 A (readonly) code defining the type of the value.
32
33 seq: a list (cssutils)
34 All parts of this style declaration including CSSComments
35 valid: boolean
36 if the value is valid at all, False for e.g. color: #1
37
38 _value
39 value without any comments, used by Property to validate
40 """
41
42 CSS_INHERIT = 0
43 """
44 The value is inherited and the cssText contains "inherit".
45 """
46 CSS_PRIMITIVE_VALUE = 1
47 """
48 The value is a primitive value and an instance of the
49 CSSPrimitiveValue interface can be obtained by using binding-specific
50 casting methods on this instance of the CSSValue interface.
51 """
52 CSS_VALUE_LIST = 2
53 """
54 The value is a CSSValue list and an instance of the CSSValueList
55 interface can be obtained by using binding-specific casting
56 methods on this instance of the CSSValue interface.
57 """
58 CSS_CUSTOM = 3
59 """
60 The value is a custom value.
61 """
62 _typestrings = ['CSS_INHERIT' , 'CSS_PRIMITIVE_VALUE', 'CSS_VALUE_LIST',
63 'CSS_CUSTOM']
64
65 - def __init__(self, cssText=None, readonly=False, _propertyName=None):
66 """
67 inits a new CSS Value
68
69 cssText
70 the parsable cssText of the value
71 readonly
72 defaults to False
73 _propertyName
74 used to validate this value in the context of a property
75 the name must be normalized: lowercase with no escapes
76 """
77 super(CSSValue, self).__init__()
78
79 self.seq = []
80 self.valid = False
81 self._value = u''
82 self._linetoken = None
83
84 self._propertyName = _propertyName
85
86 if cssText is not None:
87 self.cssText = cssText
88
89 self._readonly = readonly
90
92 v = []
93 for x in self.seq:
94 if isinstance(x, cssutils.css.CSSComment):
95 continue
96 elif type(x) in types.StringTypes:
97 v.append(x)
98 else:
99 v.append(x.cssText)
100 return u''.join(v).strip()
101
103 "overwritten by CSSValueList!"
104 self._valueValue = value
105
106 _value = property(_getValue, _setValue,
107 doc="Actual cssText value of this CSSValue.")
108
109 - def _getCssText(self):
111
112 - def _setCssText(self, cssText):
113 """
114 Format
115 ======
116 ::
117
118 expr = value
119 : term [ operator term ]*
120 ;
121 term
122 : unary_operator?
123 [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* |
124 ANGLE S* | TIME S* | FREQ S* | function ]
125 | STRING S* | IDENT S* | URI S* | hexcolor
126 ;
127 function
128 : FUNCTION S* expr ')' S*
129 ;
130 /*
131 * There is a constraint on the color that it must
132 * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F])
133 * after the "#"; e.g., "#000" is OK, but "#abcd" is not.
134 */
135 hexcolor
136 : HASH S*
137 ;
138
139 DOMException on setting
140
141 - SYNTAX_ERR: (self)
142 Raised if the specified CSS string value has a syntax error
143 (according to the attached property) or is unparsable.
144 - TODO: INVALID_MODIFICATION_ERR:
145 Raised if the specified CSS string value represents a different
146 type of values than the values allowed by the CSS property.
147 - NO_MODIFICATION_ALLOWED_ERR: (self)
148 Raised if this value is readonly.
149 """
150 def invalidToken(tokens, x):
151 """
152 raises SyntaxErr if an INVALID token in tokens
153
154 x
155 used for error message
156
157 returns True if INVALID found, else False
158 """
159 for t in tokens:
160 if t.type == self._ttypes.INVALID:
161 return u'Invalid token found in %s.' % x, t
162 return False
163
164 self._checkReadonly()
165 tokens = self._tokenize(cssText)
166 msg = invalidToken(tokens, 'value')
167
168 if msg:
169 self._log.error(
170 u'CSSValue: Unknown value syntax: "%s". (%s)' % (
171 self._valuestr(cssText), msg))
172 return
173
174 numvalues = numcommas = 0
175 newseq = []
176 i, imax = 0, len(tokens)
177 while i < imax:
178 t = tokens[i]
179 if self._ttypes.S == t.type:
180 if not newseq or newseq[-1] in (u', ', u' '):
181
182
183 pass
184 else:
185 newseq.append(u' ')
186 elif self._ttypes.COMMENT == t.type:
187 newseq.append(cssutils.css.CSSComment(t))
188 elif t.type == self._ttypes.COMMA:
189 if newseq and newseq[-1] == u' ':
190
191
192
193 newseq[-1] = u', '
194 else:
195 newseq.append(u', ')
196 numcommas += 1
197 elif t.type in (self._ttypes.IDENT,
198 self._ttypes.STRING,
199 self._ttypes.HASH,
200 self._ttypes.NUMBER,
201 self._ttypes.PERCENTAGE,
202 self._ttypes.DIMENSION,
203 self._ttypes.URI):
204 newseq.append(t.value)
205 numvalues += 1
206 elif self._ttypes.FUNCTION == t.type:
207 _functokens, endi = self._tokensupto(
208 tokens, funcendonly=True)
209 _func = []
210 for _t in _functokens:
211 _func.append(_t.value)
212 newseq.append(u''.join(_func))
213 i += endi
214 numvalues += 1
215
216
217
218
219
220 else:
221 self._log.error(u'CSSValue: Unknown value: "%s".' % t)
222
223 i += 1
224
225 if numvalues:
226 if tokens:
227 self._linetoken = tokens[0]
228 self.seq = newseq
229 self.valid = False
230
231 if self._propertyName and\
232 self._propertyName in cssproperties.cssvalues:
233 if cssproperties.cssvalues[self._propertyName](self._value):
234 self.valid = True
235 else:
236 self._log.warn(
237 u'CSSValue: Invalid value for CSS2 property %s: %s' %
238 (self._propertyName, self._value),
239 self._linetoken, neverraise=True)
240 else:
241 self._log.info(
242 u'CSSValue: Unable to validate as no property context set or unknown property: "%s"'
243 % self._value, neverraise=True)
244
245 if self._value == u'inherit':
246 self._cssValueType = CSSValue.CSS_INHERIT
247 self.__class__ = CSSValue
248 elif numvalues == 1:
249 self.__class__ = CSSPrimitiveValue
250 elif numvalues > 1 and numcommas == numvalues - 1:
251
252 self.__class__ = CSSPrimitiveValue
253 elif numvalues > 1:
254
255 self.__class__ = CSSValueList
256 self._init()
257 else:
258 self._cssValueType = CSSValue.CSS_CUSTOM
259 self.__class__ = CSSValue
260
261 else:
262 self._log.error(
263 u'CSSValue: Unknown syntax or no value: "%s".' % self._valuestr(
264 cssText).strip())
265
266 cssText = property(_getCssText, _setCssText,
267 doc="A string representation of the current value.")
268
270 if hasattr(self, '_cssValueType'):
271 return self._cssValueType
272
273 cssValueType = property(_getCssValueType,
274 doc="A (readonly) code defining the type of the value as defined above.")
275
282
283 cssValueTypeString = property(_getCssValueTypeString,
284 doc="cssutils: Name of cssValueType of this CSSValue (readonly).")
285
287 return "cssutils.css.%s(%r, _propertyName=%r)" % (
288 self.__class__.__name__, self.cssText, self._propertyName)
289
291 return "<cssutils.css.%s object cssValueType=%r cssText=%r propname=%r valid=%r at 0x%x>" % (
292 self.__class__.__name__, self.cssValueTypeString,
293 self.cssText, self._propertyName, self.valid, id(self))
294
295
297 """
298 represents a single CSS Value. May be used to determine the value of a
299 specific style property currently set in a block or to set a specific
300 style property explicitly within the block. Might be obtained from the
301 getPropertyCSSValue method of CSSStyleDeclaration.
302
303 Conversions are allowed between absolute values (from millimeters to
304 centimeters, from degrees to radians, and so on) but not between
305 relative values. (For example, a pixel value cannot be converted to a
306 centimeter value.) Percentage values can't be converted since they are
307 relative to the parent value (or another property value). There is one
308 exception for color percentage values: since a color percentage value
309 is relative to the range 0-255, a color percentage value can be
310 converted to a number; (see also the RGBColor interface).
311 """
312
313 cssValueType = CSSValue.CSS_PRIMITIVE_VALUE
314
315
316 CSS_UNKNOWN = 0
317 CSS_NUMBER = 1
318 CSS_PERCENTAGE = 2
319 CSS_EMS = 3
320 CSS_EXS = 4
321 CSS_PX = 5
322 CSS_CM = 6
323 CSS_MM = 7
324 CSS_IN = 8
325 CSS_PT = 9
326 CSS_PC = 10
327 CSS_DEG = 11
328 CSS_RAD = 12
329 CSS_GRAD = 13
330 CSS_MS = 14
331 CSS_S = 15
332 CSS_HZ = 16
333 CSS_KHZ = 17
334 CSS_DIMENSION = 18
335 CSS_STRING = 19
336 CSS_URI = 20
337 CSS_IDENT = 21
338 CSS_ATTR = 22
339 CSS_COUNTER = 23
340 CSS_RECT = 24
341 CSS_RGBCOLOR = 25
342
343 CSS_RGBACOLOR = 26
344
345 _floattypes = [CSS_NUMBER, CSS_PERCENTAGE, CSS_EMS, CSS_EXS,
346 CSS_PX, CSS_CM, CSS_MM, CSS_IN, CSS_PT, CSS_PC,
347 CSS_DEG, CSS_RAD, CSS_GRAD, CSS_MS, CSS_S,
348 CSS_HZ, CSS_KHZ, CSS_DIMENSION
349 ]
350 _stringtypes = [CSS_ATTR, CSS_IDENT, CSS_STRING, CSS_URI]
351 _countertypes = [CSS_COUNTER]
352 _recttypes = [CSS_RECT]
353 _rbgtypes = [CSS_RGBCOLOR, CSS_RGBACOLOR]
354
355
356
357 _unitinfos = [
358 ('CSS_UNKNOWN', None, None),
359 ('CSS_NUMBER', Token.NUMBER, None),
360 ('CSS_PERCENTAGE', Token.PERCENTAGE, None),
361 ('CSS_EMS', Token.DIMENSION, 'em'),
362 ('CSS_EXS', Token.DIMENSION, 'ex'),
363 ('CSS_PX', Token.DIMENSION, 'px'),
364 ('CSS_CM', Token.DIMENSION, 'cm'),
365 ('CSS_MM', Token.DIMENSION, 'mm'),
366 ('CSS_IN', Token.DIMENSION, 'in'),
367 ('CSS_PT', Token.DIMENSION, 'pt'),
368 ('CSS_PC', Token.DIMENSION, 'pc'),
369 ('CSS_DEG', Token.DIMENSION, 'deg'),
370 ('CSS_RAD', Token.DIMENSION, 'rad'),
371 ('CSS_GRAD', Token.DIMENSION, 'grad'),
372 ('CSS_MS', Token.DIMENSION, 'ms'),
373 ('CSS_S', Token.DIMENSION, 's'),
374 ('CSS_HZ', Token.DIMENSION, 'hz'),
375 ('CSS_KHZ', Token.DIMENSION, 'khz'),
376 ('CSS_DIMENSION', Token.DIMENSION, None),
377 ('CSS_STRING', Token.STRING, None),
378 ('CSS_URI', Token.URI, None),
379 ('CSS_IDENT', Token.IDENT, None),
380 ('CSS_ATTR', Token.FUNCTION, 'attr('),
381 ('CSS_COUNTER', Token.FUNCTION, 'counter('),
382 ('CSS_RECT', Token.FUNCTION, 'rect('),
383 ('CSS_RGBCOLOR', Token.FUNCTION, 'rgb('),
384 ('CSS_RGBACOLOR', Token.FUNCTION, 'rgba('),
385 ]
386
387 _reNumDim = re.compile(ur'^(.*?)([a-z]+|%)$', re.I| re.U|re.X)
388
389
390 _converter = {
391
392
393
394 (CSS_CM, CSS_MM): lambda x: x * 10,
395 (CSS_MM, CSS_CM): lambda x: x / 10,
396
397 (CSS_PT, CSS_PC): lambda x: x * 12,
398 (CSS_PC, CSS_PT): lambda x: x / 12,
399
400 (CSS_CM, CSS_IN): lambda x: x / 2.54,
401 (CSS_IN, CSS_CM): lambda x: x * 2.54,
402 (CSS_MM, CSS_IN): lambda x: x / 25.4,
403 (CSS_IN, CSS_MM): lambda x: x * 25.4,
404
405 (CSS_IN, CSS_PT): lambda x: x / 72,
406 (CSS_PT, CSS_IN): lambda x: x * 72,
407 (CSS_CM, CSS_PT): lambda x: x / 2.54 / 72,
408 (CSS_PT, CSS_CM): lambda x: x * 72 * 2.54,
409 (CSS_MM, CSS_PT): lambda x: x / 25.4 / 72,
410 (CSS_PT, CSS_MM): lambda x: x * 72 * 25.4,
411
412 (CSS_IN, CSS_PC): lambda x: x / 72 / 12,
413 (CSS_PC, CSS_IN): lambda x: x * 12 * 72,
414 (CSS_CM, CSS_PC): lambda x: x / 2.54 / 72 / 12,
415 (CSS_PC, CSS_CM): lambda x: x * 12 * 72 * 2.54,
416 (CSS_MM, CSS_PC): lambda x: x / 25.4 / 72 / 12,
417 (CSS_PC, CSS_MM): lambda x: x * 12 * 72 * 25.4,
418
419
420 (CSS_KHZ, CSS_HZ): lambda x: x * 1000,
421 (CSS_HZ, CSS_KHZ): lambda x: x / 1000,
422
423 (CSS_S, CSS_MS): lambda x: x * 1000,
424 (CSS_MS, CSS_S): lambda x: x / 1000
425
426
427 }
428
472
474 if not hasattr(self, '_primitivetype'):
475 self.__set_primitiveType()
476 return self._primitiveType
477
478 primitiveType = property(_getPrimitiveType,
479 doc="READONLY: The type of the value as defined by the constants specified above.")
480
483
484 primitiveTypeString = property(_getPrimitiveTypeString,
485 doc="Name of primitive type of this value.")
486
488 "get TypeString by given type which may be unknown, used by setters"
489 try:
490 return CSSPrimitiveValue._unitinfos[type][0]
491 except (IndexError, TypeError):
492 return u'%r (UNKNOWN TYPE)' % type
493
495 "splits self._value in numerical and dimension part"
496 try:
497 val, dim = self._reNumDim.findall(self._value)[0]
498 except IndexError:
499 val, dim = self._value, u''
500 try:
501 val = float(val)
502 except ValueError:
503 raise xml.dom.InvalidAccessErr(
504 u'CSSPrimitiveValue: No float value %s'
505 % (self._value))
506
507 return val, dim
508
510 """
511 (DOM method) This method is used to get a float value in a
512 specified unit. If this CSS value doesn't contain a float value
513 or can't be converted into the specified unit, a DOMException
514 is raised.
515
516 unitType
517 to get the float value. The unit code can only be a float unit type
518 (i.e. CSS_NUMBER, CSS_PERCENTAGE, CSS_EMS, CSS_EXS, CSS_PX, CSS_CM,
519 CSS_MM, CSS_IN, CSS_PT, CSS_PC, CSS_DEG, CSS_RAD, CSS_GRAD, CSS_MS,
520 CSS_S, CSS_HZ, CSS_KHZ, CSS_DIMENSION).
521
522 returns not necessarily a float but some cases just an int
523 e.g. if the value is ``1px`` it return ``1`` and **not** ``1.0``
524
525 conversions might return strange values like 1.000000000001
526 """
527 if unitType not in self._floattypes:
528 raise xml.dom.InvalidAccessErr(
529 u'unitType Parameter is not a float type')
530
531 val, dim = self.__getValDim()
532
533 if self.primitiveType != unitType:
534 try:
535 val = self._converter[self.primitiveType, unitType](val)
536 except KeyError:
537 raise xml.dom.InvalidAccessErr(
538 u'CSSPrimitiveValue: Cannot coerce primitiveType %s to %s'
539 % (self.primitiveTypeString,
540 self._getCSSPrimitiveTypeString(unitType)))
541
542 if val == int(val):
543 val = int(val)
544
545 return val
546
548 """
549 (DOM method) A method to set the float value with a specified unit.
550 If the property attached with this value can not accept the
551 specified unit or the float value, the value will be unchanged and
552 a DOMException will be raised.
553
554 unitType
555 a unit code as defined above. The unit code can only be a float
556 unit type
557 floatValue
558 the new float value which does not have to be a float value but
559 may simple be an int e.g. if setting::
560
561 setFloatValue(CSS_PX, 1)
562
563 raises DOMException
564 - INVALID_ACCESS_ERR: Raised if the attached property doesn't
565 support the float value or the unit type.
566 - NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly.
567 """
568 self._checkReadonly()
569 if unitType not in self._floattypes:
570 raise xml.dom.InvalidAccessErr(
571 u'CSSPrimitiveValue: unitType %s is not a float type' %
572 self._getCSSPrimitiveTypeString(unitType))
573 try:
574 val = float(floatValue)
575 except ValueError, e:
576 raise xml.dom.InvalidAccessErr(
577 u'CSSPrimitiveValue: floatValue "%s" is not a float' %
578 floatValue)
579
580 oldval, dim = self.__getValDim()
581
582 if self.primitiveType != unitType:
583
584 try:
585 val = self._converter[
586 unitType, self.primitiveType](val)
587 except KeyError:
588 raise xml.dom.InvalidAccessErr(
589 u'CSSPrimitiveValue: Cannot coerce primitiveType %s to %s'
590 % (self.primitiveTypeString,
591 self._getCSSPrimitiveTypeString(unitType)))
592
593 if val == int(val):
594 val = int(val)
595
596 self.cssText = '%s%s' % (val, dim)
597
626
628 """
629 (DOM method) A method to set the string value with the specified
630 unit. If the property attached to this value can't accept the
631 specified unit or the string value, the value will be unchanged and
632 a DOMException will be raised.
633
634 stringType
635 a string code as defined above. The string code can only be a
636 string unit type (i.e. CSS_STRING, CSS_URI, CSS_IDENT, and
637 CSS_ATTR).
638 stringValue
639 the new string value
640 Only the actual value is expected so for (CSS_URI, "a") the
641 new value will be ``url(a)``. For (CSS_STRING, "'a'")
642 the new value will be ``"\\'a\\'"`` as the surrounding ``'`` are
643 not part of the string value
644
645 raises
646 DOMException
647 - INVALID_ACCESS_ERR: Raised if the CSS value doesn't contain a
648 string value or if the string value can't be converted into
649 the specified unit.
650 - NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly.
651 """
652 self._checkReadonly()
653
654 if self.primitiveType not in self._stringtypes:
655 raise xml.dom.InvalidAccessErr(
656 u'CSSPrimitiveValue %s is not a string type'
657 % self.primitiveTypeString)
658
659 if stringType not in self._stringtypes:
660 raise xml.dom.InvalidAccessErr(
661 u'CSSPrimitiveValue: stringType %s is not a string type'
662 % self._getCSSPrimitiveTypeString(stringType))
663
664 if self._primitiveType != stringType:
665 raise xml.dom.InvalidAccessErr(
666 u'CSSPrimitiveValue: Cannot coerce primitiveType %s to %s'
667 % (self.primitiveTypeString,
668 self._getCSSPrimitiveTypeString(stringType)))
669
670 if CSSPrimitiveValue.CSS_STRING == self._primitiveType:
671 self.cssText = u'"%s"' % stringValue.replace(u'"', ur'\\"')
672 elif CSSPrimitiveValue.CSS_URI == self._primitiveType:
673
674
675
676
677
678
679
680 if u'(' in stringValue or\
681 u')' in stringValue or\
682 u',' in stringValue or\
683 u'"' in stringValue or\
684 u'\'' in stringValue or\
685 u'\n' in stringValue or\
686 u'\t' in stringValue or\
687 u'\r' in stringValue or\
688 u'\f' in stringValue or\
689 u' ' in stringValue:
690 stringValue = '"%s"' % stringValue.replace(u'"', ur'\"')
691 self.cssText = u'url(%s)' % stringValue
692 elif CSSPrimitiveValue.CSS_ATTR == self._primitiveType:
693 self.cssText = u'attr(%s)' % stringValue
694 else:
695 self.cssText = stringValue
696 self._primitiveType = stringType
697
699 """
700 (DOM method) This method is used to get the Counter value. If
701 this CSS value doesn't contain a counter value, a DOMException
702 is raised. Modification to the corresponding style property
703 can be achieved using the Counter interface.
704 """
705 if not self.CSS_COUNTER == self.primitiveType:
706 raise xml.dom.InvalidAccessErr(u'Value is not a counter type')
707
708 raise NotImplementedError()
709
711 """
712 (DOM method) This method is used to get the RGB color. If this
713 CSS value doesn't contain a RGB color value, a DOMException
714 is raised. Modification to the corresponding style property
715 can be achieved using the RGBColor interface.
716 """
717
718 if self.primitiveType not in self._rbgtypes:
719 raise xml.dom.InvalidAccessErr(u'Value is not a RGB value')
720
721 raise NotImplementedError()
722
724 """
725 (DOM method) This method is used to get the Rect value. If this CSS
726 value doesn't contain a rect value, a DOMException is raised.
727 Modification to the corresponding style property can be achieved
728 using the Rect interface.
729 """
730 if self.primitiveType not in self._recttypes:
731 raise xml.dom.InvalidAccessErr(u'value is not a Rect value')
732
733 raise NotImplementedError()
734
736 return "<cssutils.css.%s object primitiveType=%s cssText=%r _propertyName=%r valid=%r at 0x%x>" % (
737 self.__class__.__name__, self.primitiveTypeString,
738 self.cssText, self._propertyName, self.valid, id(self))
739
740
742 """
743 The CSSValueList interface provides the abstraction of an ordered
744 collection of CSS values.
745
746 Some properties allow an empty list into their syntax. In that case,
747 these properties take the none identifier. So, an empty list means
748 that the property has the value none.
749
750 The items in the CSSValueList are accessible via an integral index,
751 starting from 0.
752 """
753 cssValueType = CSSValue.CSS_VALUE_LIST
754 __ws = re.compile(ur'^\s*$')
755
756 - def __init__(self, cssText=None, readonly=False, _propertyName=None):
764
766 "called by CSSValue if newly identified as CSSValueList"
767 self._items = []
768 newseq = []
769 i, max = 0, len(self.seq)
770 while i < max:
771 v = self.seq[i]
772 if type(v) in types.StringTypes and not self.__ws.match(v):
773 if i+1 < max and self.seq[i+1] == u', ':
774
775
776 fullvalue = [v]
777 expected = 'comma'
778 for j in range(i+1, max):
779 testv = self.seq[j]
780 if u' ' == testv:
781 break
782 elif u', ' == testv and expected == 'comma':
783 fullvalue.append(testv)
784 expected = 'value'
785 elif u', ' != testv and expected == 'value':
786 fullvalue.append(testv)
787 expected = 'comma'
788 else:
789 self._log.error(
790 u'CSSValueList: Unknown syntax: "%s".'
791 % testv)
792 return
793 if expected == 'value':
794 self._log.error(
795 u'CSSValueList: Unknown syntax: "%s".'
796 % u''.join(self.seq))
797 return
798
799
800 i += len(fullvalue) - 1
801 o = CSSValue(cssText=u''.join(fullvalue),
802 _propertyName=self._propertyName)
803 else:
804
805 o = CSSValue(cssText=v, _propertyName=self._propertyName)
806
807 self._items.append(o)
808 newseq.append(o)
809
810 else:
811
812 newseq.append(v)
813
814 i += 1
815
816 self.seq = newseq
817
819 return len(self._items)
820
821 length = property(_getLength,
822 doc="(DOM attribute) The number of CSSValues in the list.")
823
824 - def item(self, index):
825 """
826 (DOM method) Used to retrieve a CSSValue by ordinal index. The
827 order in this collection represents the order of the values in the
828 CSS style property. If index is greater than or equal to the number
829 of values in the list, this returns None.
830 """
831 try:
832 return self._items[index]
833 except IndexError:
834 return None
835
839
841 "the iterator"
842 for i in range (0, self.length):
843 yield self.item(i)
844
846 return "<cssutils.css.%s object length=%s at 0x%x>" % (
847 self.__class__.__name__, self.length, id(self))
848