Package cssutils :: Package css :: Module cssstylerule |
[hide private]
[frames] | no frames]

# Source Code for Module cssutils.css.cssstylerule

      1  """CSSStyleRule implements DOM Level 2 CSS CSSStyleRule.
      2  """
      3  __all__ = ['CSSStyleRule']
      4  __docformat__ = 'restructuredtext'
      5  __version__ = '$Id: cssstylerule.py 1284 2008-06-05 16:29:17Z cthedot $'
      6
      7  import xml.dom
      8  import cssrule
      9  import cssutils
     10  from selectorlist import SelectorList
     11  from cssstyledeclaration import CSSStyleDeclaration
     12
     13 -class CSSStyleRule(cssrule.CSSRule):
     14      """
     15      The CSSStyleRule object represents a ruleset specified (if any) in a CSS
     16      style sheet. It provides access to a declaration block as well as to the
     17      associated group of selectors.
     18
     19      Properties
     20      ==========
     21      selectorList: of type SelectorList (cssutils only)
     22          A list of all Selector elements for the rule set.
     23      selectorText: of type DOMString
     24          The textual representation of the selector for the rule set. The
     25          implementation may have stripped out insignificant whitespace while
     26          parsing the selector.
     27      style: of type CSSStyleDeclaration, (DOM)
     28          The declaration-block of this rule set.
     29      type
     30          the type of this rule, constant cssutils.CSSRule.STYLE_RULE
     31
     32      inherited properties:
     33          - cssText
     34          - parentRule
     35          - parentStyleSheet
     36
     37      Format
     38      ======
     39      ruleset::
     40
     41          : selector [ COMMA S* selector ]*
     42          LBRACE S* declaration [ ';' S* declaration ]* '}' S*
     43          ;
     44      """
     45      type = property(lambda self: cssrule.CSSRule.STYLE_RULE)
     46
     47 -    def __init__(self, selectorText=None, style=None, parentRule=None,
     48                   parentStyleSheet=None, readonly=False):
     49          """
     50          :Parameters:
     51              selectorText
     52                  string parsed into selectorList
     53              style
     54                  string parsed into CSSStyleDeclaration for this CSSStyleRule
     55              readonly
     56                  if True allows setting of properties in constructor only
     57          """
     58          super(CSSStyleRule, self).__init__(parentRule=parentRule,
     59                                             parentStyleSheet=parentStyleSheet)
     60
     61          self._selectorList = SelectorList(parentRule=self)
     62          self._style = CSSStyleDeclaration(parentRule=self)
     63          if selectorText:
     64              self.selectorText = selectorText
     65          if style:
     66              self.style = style
     67
     68          self._readonly = readonly
     69
     70
     71 -    def _getCssText(self):
     72          """
     73          returns serialized property cssText
     74          """
     75          return cssutils.ser.do_CSSStyleRule(self)
     76
     77 -    def _setCssText(self, cssText):
     78          """
     79          :param cssText:
     80              a parseable string or a tuple of (cssText, dict-of-namespaces)
     81          :Exceptions:
     82              - `NAMESPACE_ERR`: (Selector)
     83                Raised if the specified selector uses an unknown namespace
     84                prefix.
     85              - `SYNTAX_ERR`: (self, StyleDeclaration, etc)
     86                Raised if the specified CSS string value has a syntax error and
     87                is unparsable.
     88              - `INVALID_MODIFICATION_ERR`: (self)
     89                Raised if the specified CSS string value represents a different
     90                type of rule than the current one.
     91              - `HIERARCHY_REQUEST_ERR`: (CSSStylesheet)
     92                Raised if the rule cannot be inserted at this point in the
     93                style sheet.
     94              - `NO_MODIFICATION_ALLOWED_ERR`: (CSSRule)
     95                Raised if the rule is readonly.
     96          """
     97          super(CSSStyleRule, self)._setCssText(cssText)
     98
     99          # might be (cssText, namespaces)
    100          cssText, namespaces = self._splitNamespacesOff(cssText)
    101          try:
    102              # use parent style sheet ones if available
    103              namespaces = self.parentStyleSheet.namespaces
    104          except AttributeError:
    105              pass
    106
    107          tokenizer = self._tokenize2(cssText)
    108          selectortokens = self._tokensupto2(tokenizer, blockstartonly=True)
    109          styletokens = self._tokensupto2(tokenizer, blockendonly=True)
    110          trail = self._nexttoken(tokenizer)
    111          if trail:
    112              self._log.error(u'CSSStyleRule: Trailing content: %s' %
    113                              self._valuestr(cssText), token=trail)
    114          elif not selectortokens:
    115              self._log.error(u'CSSStyleRule: No selector found: %r' %
    116                              self._valuestr(cssText))
    117          elif self._tokenvalue(selectortokens[0]).startswith(u'@'):
    118              self._log.error(u'CSSStyleRule: No style rule: %r' %
    119                              self._valuestr(cssText),
    120                              error=xml.dom.InvalidModificationErr)
    121          else:
    122              wellformed = True
    123
    124              bracetoken = selectortokens.pop()
    125              if self._tokenvalue(bracetoken) != u'{':
    126                  wellformed = False
    127                  self._log.error(
    128                      u'CSSStyleRule: No start { of style declaration found: %r' %
    129                      self._valuestr(cssText), bracetoken)
    130              elif not selectortokens:
    131                  wellformed = False
    132                  self._log.error(u'CSSStyleRule: No selector found: %r.' %
    133                              self._valuestr(cssText), bracetoken)
    134              newselectorlist = SelectorList(selectorText=(selectortokens,
    135                                                           namespaces),
    136                                             parentRule=self)
    137
    138              newstyle = CSSStyleDeclaration()
    139              if not styletokens:
    140                  wellformed = False
    141                  self._log.error(
    142                      u'CSSStyleRule: No style declaration or "}" found: %r' %
    143                      self._valuestr(cssText))
    144              else:
    145                  braceorEOFtoken = styletokens.pop()
    146                  val, typ = self._tokenvalue(braceorEOFtoken), self._type(braceorEOFtoken)
    147                  if val != u'}' and typ != 'EOF':
    148                      wellformed = False
    149                      self._log.error(
    150                          u'CSSStyleRule: No "}" after style declaration found: %r' %
    151                          self._valuestr(cssText))
    152                  else:
    153                      if 'EOF' == typ:
    154                          # add again as style needs it
    155                          styletokens.append(braceorEOFtoken)
    156                      newstyle.cssText = styletokens
    157
    158              if wellformed:
    159                  self._selectorList = newselectorlist
    160                  self.style = newstyle
    161
    162      cssText = property(_getCssText, _setCssText,
    163          doc="(DOM) The parsable textual representation of the rule.")
    164
    165
    166 -    def __getNamespaces(self):
    167          "uses children namespaces if not attached to a sheet, else the sheet's ones"
    168          try:
    169              return self.parentStyleSheet.namespaces
    170          except AttributeError:
    171              return self.selectorList._namespaces
    172
    173      _namespaces = property(__getNamespaces, doc=u"""if this Rule is
    174          attached to a CSSStyleSheet the namespaces of that sheet are mirrored
    175          here. While the Rule is not attached the namespaces of selectorList
    176          are used.""")
    177
    178 -    def _setSelectorList(self, selectorList):
    179          """
    180          :param selectorList: selectorList, only content is used, not the actual
    181              object
    182          """
    183          self._checkReadonly()
    184          self.selectorText = selectorList.selectorText
    185
    186      selectorList = property(lambda self: self._selectorList, _setSelectorList,
    187          doc="The SelectorList of this rule.")
    188
    189 -    def _setSelectorText(self, selectorText):
    190          """
    191          wrapper for cssutils SelectorList object
    192
    193          :param selectorText: of type string, might also be a comma separated list
    194              of selectors
    195          :Exceptions:
    196              - `NAMESPACE_ERR`: (Selector)
    197                Raised if the specified selector uses an unknown namespace
    198                prefix.
    199              - `SYNTAX_ERR`: (SelectorList, Selector)
    200                Raised if the specified CSS string value has a syntax error
    201                and is unparsable.
    202              - `NO_MODIFICATION_ALLOWED_ERR`: (self)
    203                Raised if this rule is readonly.
    204          """
    205          self._checkReadonly()
    206          self._selectorList.selectorText = selectorText
    207
    208      selectorText = property(lambda self: self._selectorList.selectorText,
    209                              _setSelectorText,
    210          doc="""(DOM) The textual representation of the selector for the
    211              rule set.""")
    212
    213 -    def _setStyle(self, style):
    214          """
    215          :param style: CSSStyleDeclaration or string, only the cssText of a
    216              declaration is used, not the actual object
    217          """
    218          self._checkReadonly()
    219          if isinstance(style, basestring):
    220              self._style.cssText = style
    221          else:
    222              # cssText would be serialized with optional preferences
    223              # so use _seq!
    224              self._style._seq = style._seq
    225
    226      style = property(lambda self: self._style, _setStyle,
    227          doc="(DOM) The declaration-block of this rule set.")
    228
    229      wellformed = property(lambda self: self.selectorList.wellformed)
    230
    231 -    def __repr__(self):
    232          if self._namespaces:
    233              st = (self.selectorText, self._namespaces)
    234          else:
    235              st = self.selectorText
    236          return "cssutils.css.%s(selectorText=%r, style=%r)" % (
    237                  self.__class__.__name__, st, self.style.cssText)
    238
    239 -    def __str__(self):
    240          return "<cssutils.css.%s object selector=%r style=%r _namespaces=%r at 0x%x>" % (
    241                  self.__class__.__name__, self.selectorText, self.style.cssText,
    242                  self._namespaces, id(self))
    243