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

# Source Code for Module cssutils.css.cssnamespacerule

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