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