1 """CSSValue implements DOM Level 2 CSS CSSValue.
2
3 TODO
4 parsing and exception raising
5 setting of correct CSSValueType
6
7 pprint of value/unit e.g. 3 px 5px -> 3px 5px
8 simplify colors if possible e.g. #ffaa55 -> #fa5
9 simplify values: 0px; -> 0;
10 """
11 __all__ = ['CSSValue']
12 __docformat__ = 'restructuredtext'
13 __author__ = '$LastChangedBy: doerwalter $'
14 __date__ = '$LastChangedDate: 2007-08-02 22:58:23 +0200 (Do, 02 Aug 2007) $'
15 __version__ = '0.9.2a5, $LastChangedRevision: 160 $'
16
17 import xml.dom
18
19 import cssutils
20
21
23 """
24 The CSSValue interface represents a simple or a complex value.
25 A CSSValue object only occurs in a context of a CSS property
26
27 Properties
28 ==========
29 cssText
30 A string representation of the current value.
31 cssValueType
32 A (readonly) code defining the type of the value.
33
34 seq: a list (cssutils)
35 All parts of this style declaration including CSSComments
36
37 _value
38 value without any comments, used by Property to validate
39 """
40
41 CSS_INHERIT = 0
42 """
43 The value is inherited and the cssText contains "inherit".
44 """
45 CSS_PRIMITIVE_VALUE = 1
46 """
47 The value is a primitive value and an instance of the
48 CSSPrimitiveValue interface can be obtained by using binding-specific
49 casting methods on this instance of the CSSValue interface.
50 """
51 CSS_VALUE_LIST = 2
52 """
53 The value is a CSSValue list and an instance of the CSSValueList
54 interface can be obtained by using binding-specific casting
55 methods on this instance of the CSSValue interface.
56 """
57 CSS_CUSTOM = 3
58 """
59 The value is a custom value.
60 """
61
62 - def __init__(self, cssText=u'inherit', readonly=False):
63 """
64 (cssutils)
65 inits a new CSS Value
66
67 cssText
68 the parsable cssText of the value
69 readonly
70 defaults to False
71 """
72 super(CSSValue, self).__init__()
73
74 self.seq = []
75 self._value = u''
76 self._linetoken = None
77 self.cssText = cssText
78 self._readonly = readonly
79
80
82 """
83 raises SyntaxErr if an INVALID token in tokens
84
85 x
86 used for error message
87
88 returns True if INVALID found, else False
89 """
90 for t in tokens:
91 if t.type == self._ttypes.INVALID:
92 self._log.error(u'CSSValue: Invalid token found in %s.' % x, t)
93 return True
94 return False
95
96
97 - def _getCssText(self):
99
100 - def _setCssText(self, cssText):
101 """
102 Format
103 ======
104 ::
105
106 expr = value
107 : term [ operator term ]*
108 ;
109 term
110 : unary_operator?
111 [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* |
112 ANGLE S* | TIME S* | FREQ S* | function ]
113 | STRING S* | IDENT S* | URI S* | hexcolor
114 ;
115 function
116 : FUNCTION S* expr ')' S*
117 ;
118 /*
119 * There is a constraint on the color that it must
120 * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F])
121 * after the "#"; e.g., "#000" is OK, but "#abcd" is not.
122 */
123 hexcolor
124 : HASH S*
125 ;
126
127 DOMException on setting
128
129 - SYNTAX_ERR: (self)
130 Raised if the specified CSS string value has a syntax error
131 (according to the attached property) or is unparsable.
132 - TODO: INVALID_MODIFICATION_ERR:
133 Raised if the specified CSS string value represents a different
134 type of values than the values allowed by the CSS property.
135 - NO_MODIFICATION_ALLOWED_ERR: (self)
136 Raised if this value is readonly.
137 """
138 self._checkReadonly()
139
140 tokens = self._tokenize(cssText)
141 if self.__invalidToken(tokens, 'value'):
142 self._log.error(
143 u'CSSValue: Unknown value syntax: "%s".' % self._valuestr(
144 cssText))
145 return
146
147 hasvalue = False
148 newseq = []
149 i, imax = 0, len(tokens)
150 while i < imax:
151 t = tokens[i]
152 if self._ttypes.S == t.type:
153 if not newseq or newseq[-1] == u' ':
154 pass
155 else:
156 newseq.append(u' ')
157 elif self._ttypes.COMMENT == t.type:
158 newseq.append(cssutils.css.CSSComment(t))
159 elif t.type in (
160 self._ttypes.SEMICOLON, self._ttypes.IMPORTANT_SYM) or\
161 u':' == t.value:
162 self._log.error(u'CSSValue: Syntax error.', t)
163 return
164 elif t.type == self._ttypes.FUNCTION:
165 _functokens, endi = self._tokensupto(
166 tokens, funcendonly=True)
167 _func = []
168 for _t in _functokens:
169 _func.append(_t.value)
170 newseq.append(u''.join(_func))
171 i += endi
172 hasvalue = True
173 else:
174 newseq.append(t.value)
175 hasvalue = True
176
177 i += 1
178
179 if hasvalue:
180 self.seq = newseq
181 self._value = u''.join([x for x in newseq if not isinstance(
182 x, cssutils.css.CSSComment)]).strip()
183
184 if tokens:
185 self._linetoken = tokens[0]
186
187 if self._value == u'inherit':
188 self._cssValueType = CSSValue.CSS_INHERIT
189 else:
190 self._cssValueType = CSSValue.CSS_CUSTOM
191
192 else:
193 self._log.error(
194 u'CSSValue: Unknown syntax or no value: "%s".' % self._valuestr(
195 cssText).strip())
196
197
198 cssText = property(_getCssText, _setCssText,
199 doc="A string representation of the current value.")
200
201
203 "readonly"
204 return self._cssValueType
205
206 cssValueType = property(_getCssValueType,
207 doc="A code defining the type of the value as defined above.")
208