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

# Source Code for Module cssutils.css.cssnamespacerule

      1  """CSSNamespaceRule currently implements
      2  http://www.w3.org/TR/2006/WD-css3-namespace-20060828/
      3
      4  The following changes have been done:
      5      1. the url() syntax is not implemented as it may (?) be deprecated
      6      anyway
      7  """
      8  __all__ = ['CSSNamespaceRule']
      9  __docformat__ = 'restructuredtext'
     10  __author__ = '$LastChangedBy: cthedot $'
     11  __date__ = '$LastChangedDate: 2007-10-20 20:06:26 +0200 (Sa, 20 Okt 2007) $'
     12  __version__ = '$LastChangedRevision: 543 $'
     13
     14  import xml.dom
     15  import cssrule
     16  import cssutils
     17  from cssutils.util import Deprecated
     18
     19 -class CSSNamespaceRule(cssrule.CSSRule):
     20      """
     21      Represents an @namespace rule within a CSS style sheet.
     22
     23      The @namespace at-rule declares a namespace prefix and associates
     24      it with a given namespace (a string). This namespace prefix can then be
     25      used in namespace-qualified names such as those described in the
     26      Selectors Module [SELECT] or the Values and Units module [CSS3VAL].
     27
     28      Properties
     29      ==========
     30      cssText: of type DOMString
     31          The parsable textual representation of this rule
     32      uri: of type DOMString
     33          The namespace URI (a simple string!) which is bound to the given
     34          prefix. If no prefix is set (``CSSNamespaceRule.prefix==''``)
     35          the namespace defined by uri is set as the default namespace.
     36      prefix: of type DOMString
     37          The prefix used in the stylesheet for the given
     38          ``CSSNamespaceRule.nsuri``. If prefix is empty uri sets the default
     39          namespace for the stylesheet.
     40
     41      cssutils only
     42      -------------
     43      atkeyword:
     44          the literal keyword used
     45
     46      Inherits properties from CSSRule
     47
     48      Format
     49      ======
     50      namespace
     51        : NAMESPACE_SYM S* [namespace_prefix S*]? [STRING|URI] S* ';' S*
     52        ;
     53      namespace_prefix
     54        : IDENT
     55        ;
     56      """
     57      type = cssrule.CSSRule.NAMESPACE_RULE
     58
     59 -    def __init__(self, namespaceURI=None, prefix=u'', readonly=False):
     60          """
     61          if readonly allows setting of properties in constructor only
     62
     63          Do not use as positional but as keyword attributes only!
     64
     65          namespaceURI
     66              The namespace URI (a simple string!) which is bound to the
     67              given prefix. If no prefix is set
     68              (``CSSNamespaceRule.prefix==''``) the namespace defined by
     69              namespaceURI is set as the default namespace
     70          prefix
     71              The prefix used in the stylesheet for the given
     72              ``CSSNamespaceRule.uri``.
     73
     74          format namespace::
     75
     76              : NAMESPACE_SYM S* [namespace_prefix S*]? [STRING|URI] S* ';' S*
     77              ;
     78          """
     79          super(CSSNamespaceRule, self).__init__()
     80
     81          self.atkeyword = u'@namespace'
     82          self.namespaceURI = namespaceURI
     83          self.prefix = prefix
     84          self.seq = [self.prefix, self.namespaceURI]
     85
     86          self._readonly = readonly
     87
     88 -    def _getNamespaceURI(self):
     89          """ returns uri as a string """
     90          return self._namespaceURI
     91
     92 -    def _setNamespaceURI(self, namespaceURI):
     93          """
     94          DOMException on setting
     95
     96          - NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
     97            Raised if this rule is readonly.
     98          """
     99          self._checkReadonly()
    100
    101          # update seq
    102          for i, x in enumerate(self.seq):
    103              if x == self._namespaceURI:
    104                  self.seq[i] = namespaceURI
    105                  break
    106          else:
    107              self.seq = [namespaceURI]
    108          # set new uri
    109          self._namespaceURI = namespaceURI
    110
    111      namespaceURI = property(_getNamespaceURI, _setNamespaceURI,
    112          doc="URI (string!) of the defined namespace.")
    113
    114      @Deprecated(u'Use property namespaceURI instead.')
    115 -    def _getURI(self):
    116          return self.namespaceURI
    117
    118      @Deprecated(u'Use property namespaceURI instead.')
    119 -    def _setURI(self, uri):
    120          self._setNamespaceURI(uri)
    121
    122      uri = property(_getURI, _setURI,
    123          doc="DEPRECATED: Use property namespaceURI instead.")
    124
    125
    126 -    def _getPrefix(self):
    127          """ returns prefix """
    128          return self._prefix
    129
    130 -    def _setPrefix(self, prefix=u''):
    131          """
    132          DOMException on setting
    133
    134          - SYNTAX_ERR: (not checked here)
    135            Raised if the specified CSS string value has a syntax error and
    136            is unparsable.
    137          - NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
    138            Raised if this rule is readonly.
    139          """
    140          self._checkReadonly()
    141
    142          # set new uri
    143          self._prefix = prefix
    144
    145          for i, x in enumerate(self.seq):
    146              if x == self._prefix:
    147                  self.seq[i] = prefix
    148                  break
    149          else:
    150              self.seq[0] = prefix # put prefix at the beginning!
    151
    152      prefix = property(_getPrefix, _setPrefix,
    153          doc="Prefix used for the defined namespace.")
    154
    155
    156 -    def _getCssText(self):
    157          """
    158          returns serialized property cssText
    159          """
    160          return cssutils.ser.do_CSSNamespaceRule(self)
    161
    162 -    def _setCssText(self, cssText):
    163          """
    164          DOMException on setting
    165
    166          - HIERARCHY_REQUEST_ERR: (CSSStylesheet)
    167            Raised if the rule cannot be inserted at this point in the
    168            style sheet.
    169          - INVALID_MODIFICATION_ERR: (self)
    170            Raised if the specified CSS string value represents a different
    171            type of rule than the current one.
    172          - NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
    173            Raised if the rule is readonly.
    174          - SYNTAX_ERR: (self)
    175            Raised if the specified CSS string value has a syntax error and
    176            is unparsable.
    177          """
    178          super(CSSNamespaceRule, self)._setCssText(cssText)
    179          tokenizer = self._tokenize2(cssText)
    180          attoken = self._nexttoken(tokenizer, None)
    181          if not attoken or self._type(attoken) != self._prods.NAMESPACE_SYM:
    182              self._log.error(u'CSSNamespaceRule: No CSSNamespaceRule found: %s' %
    183                  self._valuestr(cssText),
    184                  error=xml.dom.InvalidModificationErr)
    185          else:
    186              # for closures: must be a mutable
    187              new = {
    188                     'keyword': self._tokenvalue(attoken),
    189                     'prefix': None,
    190                     'uri': None,
    191                     'valid': True
    192                     }
    193
    194              def _ident(expected, seq, token, tokenizer=None):
    195                  # the namespace prefix, optional
    196                  if 'prefix or uri' == expected:
    197                      new['prefix'] = self._tokenvalue(token)
    198                      seq.append(new['prefix'])
    199                      return 'uri'
    200                  else:
    201                      new['valid'] = False
    202                      self._log.error(
    203                          u'CSSNamespaceRule: Unexpected ident.', token)
    204                      return expected
    205
    206              def _string(expected, seq, token, tokenizer=None):
    207                  # the namespace URI as a STRING
    208                  if expected.endswith('uri'):
    209                      new['uri'] = self._tokenvalue(token)[1:-1] # "uri" or 'uri'
    210                      seq.append(new['uri'])
    211                      return ';'
    212
    213                  else:
    214                      new['valid'] = False
    215                      self._log.error(
    216                          u'CSSNamespaceRule: Unexpected string.', token)
    217                      return expected
    218
    219              def _uri(expected, seq, token, tokenizer=None):
    220                  # the namespace URI as URI which is DEPRECATED
    221                  if expected.endswith('uri'):
    222                      uri = self._tokenvalue(token)[4:-1].strip() # url(uri)
    223                      if uri[0] == uri[-1] == '"' or\
    224                         uri[0] == uri[-1] == "'":
    225                          uri = uri[1:-1]
    226                      self._log.warn(
    227                          u'CSSNamespaceRule: Found namespace definition with url(uri), this may be deprecated in the future, use string format "uri" instead.',
    228                          token, error = None, neverraise=True)
    229                      new['uri'] = uri
    230                      seq.append(new['uri'])
    231                      return ';'
    232                  else:
    233                      new['valid'] = False
    234                      self._log.error(
    235                          u'CSSNamespaceRule: Unexpected URI.', token)
    236                      return expected
    237
    238              def _char(expected, seq, token, tokenizer=None):
    239                  # final ;
    240                  val = self._tokenvalue(token)
    241                  if ';' == expected and u';' == val:
    242                      return 'EOF'
    243                  else:
    244                      new['valid'] = False
    245                      self._log.error(
    246                          u'CSSNamespaceRule: Unexpected char.', token)
    247                      return expected
    248
    249              # "NAMESPACE_SYM S* [namespace_prefix S*]? [STRING|URI] S* ';' S*"
    250              newseq = []
    251              valid, expected = self._parse(expected='prefix or uri',
    252                  seq=newseq, tokenizer=tokenizer,
    253                  productions={'IDENT': _ident,
    254                               'STRING': _string,
    255                               'URI': _uri,
    256                               'CHAR': _char})
    257
    258              # valid set by parse
    259              valid = valid and new['valid']
    260
    261              # post conditions
    262              if not new['uri']:
    263                  valid = False
    264                  self._log.error(u'CSSNamespaceRule: No namespace URI found: %s' %
    265                      self._valuestr(cssText))
    266
    267              if expected != 'EOF':
    268                  valid = False
    269                  self._log.error(u'CSSNamespaceRule: No ";" found: %s' %
    270                      self._valuestr(cssText))
    271
    272              # set all
    273              self.valid = valid
    274              if valid:
    275                  self.atkeyword = new['keyword']
    276                  self.prefix = new['prefix']
    277                  self.namespaceURI = new['uri']
    278                  self.seq = newseq
    279
    280      cssText = property(fget=_getCssText, fset=_setCssText,
    281          doc="(DOM attribute) The parsable textual representation.")
    282
    283 -    def __repr__(self):
    284          return "cssutils.css.%s(namespaceURI=%r, prefix=%r)" % (
    285                  self.__class__.__name__, self.namespaceURI, self.prefix)
    286
    287 -    def __str__(self):
    288          return "<cssutils.css.%s object namespaceURI=%r prefix=%r at 0x%x>" % (
    289                  self.__class__.__name__, self.namespaceURI, self.prefix, id(self))
    290