Statistics
| Revision:

gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.app / org.gvsig.scripting.app.mainplugin / src / main / resources-plugin / scripting / lib / cssutils / css / cssstylerule.py @ 475

History | View | Annotate | Download (9 KB)

1
"""CSSStyleRule implements DOM Level 2 CSS CSSStyleRule."""
2
__all__ = ['CSSStyleRule']
3
__docformat__ = 'restructuredtext'
4
__version__ = '$Id$'
5

    
6
from cssstyledeclaration import CSSStyleDeclaration
7
from selectorlist import SelectorList
8
import cssrule
9
import cssutils
10
import xml.dom
11

    
12
class CSSStyleRule(cssrule.CSSRule):
13
    """The CSSStyleRule object represents a ruleset specified (if any) in a CSS
14
    style sheet. It provides access to a declaration block as well as to the
15
    associated group of selectors.
16

17
    Format::
18

19
        : selector [ COMMA S* selector ]*
20
        LBRACE S* declaration [ ';' S* declaration ]* '}' S*
21
        ;
22
    """
23
    def __init__(self, selectorText=None, style=None, parentRule=None,
24
                 parentStyleSheet=None, readonly=False):
25
        """
26
        :Parameters:
27
            selectorText
28
                string parsed into selectorList
29
            style
30
                string parsed into CSSStyleDeclaration for this CSSStyleRule
31
            readonly
32
                if True allows setting of properties in constructor only
33
        """
34
        super(CSSStyleRule, self).__init__(parentRule=parentRule,
35
                                           parentStyleSheet=parentStyleSheet)
36

    
37
        self.selectorList = SelectorList()
38
        if selectorText:
39
            self.selectorText = selectorText
40

    
41
        if style:
42
            self.style = style
43
        else:
44
            self.style = CSSStyleDeclaration()
45

    
46
        self._readonly = readonly
47

    
48
    def __repr__(self):
49
        if self._namespaces:
50
            st = (self.selectorText, self._namespaces)
51
        else:
52
            st = self.selectorText
53
        return u"cssutils.css.%s(selectorText=%r, style=%r)" % (
54
                self.__class__.__name__, st, self.style.cssText)
55

    
56
    def __str__(self):
57
        return u"<cssutils.css.%s object selectorText=%r style=%r _namespaces=%r "\
58
               u"at 0x%x>" % (self.__class__.__name__,
59
                              self.selectorText,
60
                              self.style.cssText,
61
                              self._namespaces,
62
                              id(self))
63

    
64
    def _getCssText(self):
65
        """Return serialized property cssText."""
66
        return cssutils.ser.do_CSSStyleRule(self)
67

    
68
    def _setCssText(self, cssText):
69
        """
70
        :param cssText:
71
            a parseable string or a tuple of (cssText, dict-of-namespaces)
72
        :exceptions:
73
            - :exc:`~xml.dom.NamespaceErr`:
74
              Raised if the specified selector uses an unknown namespace
75
              prefix.
76
            - :exc:`~xml.dom.SyntaxErr`:
77
              Raised if the specified CSS string value has a syntax error and
78
              is unparsable.
79
            - :exc:`~xml.dom.InvalidModificationErr`:
80
              Raised if the specified CSS string value represents a different
81
              type of rule than the current one.
82
            - :exc:`~xml.dom.HierarchyRequestErr`:
83
              Raised if the rule cannot be inserted at this point in the
84
              style sheet.
85
            - :exc:`~xml.dom.NoModificationAllowedErr`:
86
              Raised if the rule is readonly.
87
        """
88
        super(CSSStyleRule, self)._setCssText(cssText)
89

    
90
        # might be (cssText, namespaces)
91
        cssText, namespaces = self._splitNamespacesOff(cssText)
92
        try:
93
            # use parent style sheet ones if available
94
            namespaces = self.parentStyleSheet.namespaces
95
        except AttributeError:
96
            pass
97

    
98
        tokenizer = self._tokenize2(cssText)
99
        selectortokens = self._tokensupto2(tokenizer, blockstartonly=True)
100
        styletokens = self._tokensupto2(tokenizer, blockendonly=True)
101
        trail = self._nexttoken(tokenizer)
102
        if trail:
103
            self._log.error(u'CSSStyleRule: Trailing content: %s' %
104
                            self._valuestr(cssText), token=trail)
105
        elif not selectortokens:
106
            self._log.error(u'CSSStyleRule: No selector found: %r' %
107
                            self._valuestr(cssText))
108
        elif self._tokenvalue(selectortokens[0]).startswith(u'@'):
109
            self._log.error(u'CSSStyleRule: No style rule: %r' %
110
                            self._valuestr(cssText),
111
                            error=xml.dom.InvalidModificationErr)
112
        else:
113
            newSelectorList = SelectorList(parentRule=self)
114
            newStyle = CSSStyleDeclaration(parentRule=self)
115
            ok = True
116

    
117
            bracetoken = selectortokens.pop()
118
            if self._tokenvalue(bracetoken) != u'{':
119
                ok = False
120
                self._log.error(
121
                    u'CSSStyleRule: No start { of style declaration found: %r' %
122
                    self._valuestr(cssText), bracetoken)
123
            elif not selectortokens:
124
                ok = False
125
                self._log.error(u'CSSStyleRule: No selector found: %r.' %
126
                            self._valuestr(cssText), bracetoken)
127
            # SET
128
            newSelectorList.selectorText = (selectortokens,
129
                                              namespaces)
130

    
131
            if not styletokens:
132
                ok = False
133
                self._log.error(
134
                    u'CSSStyleRule: No style declaration or "}" found: %r' %
135
                    self._valuestr(cssText))
136
            else:
137
                braceorEOFtoken = styletokens.pop()
138
                val, typ = self._tokenvalue(braceorEOFtoken),\
139
                           self._type(braceorEOFtoken)
140
                if val != u'}' and typ != 'EOF':
141
                    ok = False
142
                    self._log.error(u'CSSStyleRule: No "}" after style '
143
                                    u'declaration found: %r'
144
                                    % self._valuestr(cssText))
145
                else:
146
                    if 'EOF' == typ:
147
                        # add again as style needs it
148
                        styletokens.append(braceorEOFtoken)
149
                    # SET, may raise:
150
                    newStyle.cssText = styletokens
151

    
152
            if ok:
153
                self.selectorList = newSelectorList
154
                self.style = newStyle
155

    
156
    cssText = property(_getCssText, _setCssText,
157
                       doc=u"(DOM) The parsable textual representation of this "
158
                       u"rule.")
159

    
160
    def __getNamespaces(self):
161
        """Uses children namespaces if not attached to a sheet, else the sheet's
162
        ones."""
163
        try:
164
            return self.parentStyleSheet.namespaces
165
        except AttributeError:
166
            return self.selectorList._namespaces
167

    
168
    _namespaces = property(__getNamespaces,
169
                           doc=u"If this Rule is attached to a CSSStyleSheet "
170
                               u"the namespaces of that sheet are mirrored "
171
                               u"here. While the Rule is not attached the "
172
                               u"namespaces of selectorList are used.""")
173

    
174
    def _setSelectorList(self, selectorList):
175
        """
176
        :param selectorList: A SelectorList which replaces the current
177
            selectorList object
178
        """
179
        self._checkReadonly()
180
        selectorList._parentRule = self
181
        self._selectorList = selectorList
182

    
183
    _selectorList = None
184
    selectorList = property(lambda self: self._selectorList, _setSelectorList,
185
                            doc=u"The SelectorList of this rule.")
186

    
187
    def _setSelectorText(self, selectorText):
188
        """
189
        wrapper for cssutils SelectorList object
190

191
        :param selectorText:
192
            of type string, might also be a comma separated list
193
            of selectors
194
        :exceptions:
195
            - :exc:`~xml.dom.NamespaceErr`:
196
              Raised if the specified selector uses an unknown namespace
197
              prefix.
198
            - :exc:`~xml.dom.SyntaxErr`:
199
              Raised if the specified CSS string value has a syntax error
200
              and is unparsable.
201
            - :exc:`~xml.dom.NoModificationAllowedErr`:
202
              Raised if this rule is readonly.
203
        """
204
        self._checkReadonly()
205

    
206
        sl = SelectorList(selectorText=selectorText, parentRule=self)
207
        if sl.wellformed:
208
            self._selectorList = sl
209

    
210
    selectorText = property(lambda self: self._selectorList.selectorText,
211
                            _setSelectorText,
212
                            doc=u"(DOM) The textual representation of the "
213
                                u"selector for the rule set.")
214

    
215
    def _setStyle(self, style):
216
        """
217
        :param style: A string or CSSStyleDeclaration which replaces the
218
            current style object.
219
        """
220
        self._checkReadonly()
221
        if isinstance(style, basestring):
222
            self._style = CSSStyleDeclaration(cssText=style, parentRule=self)
223
        else:
224
            style._parentRule = self
225
            self._style = style
226

    
227
    style = property(lambda self: self._style, _setStyle,
228
                     doc=u"(DOM) The declaration-block of this rule set.")
229

    
230
    type = property(lambda self: self.STYLE_RULE,
231
                    doc=u"The type of this rule, as defined by a CSSRule "
232
                        "type constant.")
233

    
234
    wellformed = property(lambda self: self.selectorList.wellformed)