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-08-20 22:07:12 +0200 (Mo, 20 Aug 2007) $'
     12  __version__ = '$LastChangedRevision: 257 $'
     13
     14  import xml.dom
     15
     16  import cssrule
     17  import cssutils
     18
     19
     20 -class CSSNamespaceRule(cssrule.CSSRule):
     21      """
     22      Represents an @namespace rule within a CSS style sheet.
     23
     24      The @namespace at-rule declares a namespace prefix and associates
     25      it with a given namespace (a string). This namespace prefix can then be
     26      used in namespace-qualified names such as those described in the
     27      Selectors Module [SELECT] or the Values and Units module [CSS3VAL].
     28
     29      Properties
     30      ==========
     31      cssText: of type DOMString
     32          The parsable textual representation of this rule
     33      uri: of type DOMString
     34          The namespace URI (a simple string!) which is bound to the given
     35          prefix. If no prefix is set (``CSSNamespaceRule.prefix==''``)
     36          the namespace defined by uri is set as the default 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, uri=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          uri
     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              uri is set as the default namespace
     71          prefix
     72              The prefix used in the stylesheet for the given
     73              ``CSSNamespaceRule.uri``.
     74          """
     75          super(CSSNamespaceRule, self).__init__()
     76
     77          self.atkeyword = u'@namespace'
     78          self.uri = uri
     79          self.prefix = prefix
     80          self.seq = [self.prefix, self.uri]
     81
     82          self._readonly = readonly
     83
     84
     85 -    def _getURI(self):
     86          """ returns uri as a string """
     87          return self._uri
     88
     89 -    def _setURI(self, uri):
     90          """
     91          DOMException on setting
     92
     93          - SYNTAX_ERR: (not checked here)
     94            Raised if the specified CSS string value has a syntax error and
     95            is unparsable.
     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._uri:
    104                  self.seq[i] = uri
    105                  break
    106          else:
    107              self.seq = [uri]
    108          # set new uri
    109          self._uri = uri
    110
    111      uri = property(_getURI, _setURI,
    112          doc="URI (string!) of the defined namespace.")
    113
    114
    115 -    def _getPrefix(self):
    116          """ returns prefix """
    117          return self._prefix
    118
    119 -    def _setPrefix(self, prefix=u''):
    120          """
    121          DOMException on setting
    122
    123          - SYNTAX_ERR: (not checked here)
    124            Raised if the specified CSS string value has a syntax error and
    125            is unparsable.
    126          - NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
    127            Raised if this rule is readonly.
    128          """
    129          self._checkReadonly()
    130
    131          # set new uri
    132          self._prefix = prefix
    133
    134          for i, x in enumerate(self.seq):
    135              if x == self._prefix:
    136                  self.seq[i] = prefix
    137                  break
    138          else:
    139              self.seq[0] = prefix # put prefix at the beginning!
    140
    141      prefix = property(_getPrefix, _setPrefix,
    142          doc="Prefix used for the defined namespace.")
    143
    144
    145 -    def _getCssText(self):
    146          """
    147          returns serialized property cssText
    148          """
    149          return cssutils.ser.do_CSSNamespaceRule(self)
    150
    151 -    def _setCssText(self, cssText):
    152          """
    153          DOMException on setting
    154
    155          - HIERARCHY_REQUEST_ERR: (CSSStylesheet)
    156            Raised if the rule cannot be inserted at this point in the
    157            style sheet.
    158          - INVALID_MODIFICATION_ERR: (self)
    159            Raised if the specified CSS string value represents a different
    160            type of rule than the current one.
    161          - NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
    162            Raised if the rule is readonly.
    163          - SYNTAX_ERR: (self)
    164            Raised if the specified CSS string value has a syntax error and
    165            is unparsable.
    166          """
    167          super(CSSNamespaceRule, self)._setCssText(cssText)
    168          tokens = self._tokenize(cssText)
    169          valid = True
    170
    171          # check if right type
    172          if not tokens or tokens and tokens[0].type != self._ttypes.NAMESPACE_SYM:
    173              self._log.error(u'CSSNamespaceRule: No CSSNamespaceRule found: %s' %
    174                        self._valuestr(cssText),
    175                        error=xml.dom.InvalidModificationErr)
    176              return
    177          else:
    178              newatkeyword = tokens[0].value
    179
    180          newseq = []
    181          newuri = None
    182          newprefix = u''
    183
    184          expected = 'uri or prefix' # uri semicolon
    185          for i in range(1, len(tokens)):
    186              t = tokens[i]
    187
    188              if self._ttypes.EOF == t.type:
    189                  expected = 'EOF'
    190
    191              elif self._ttypes.S == t.type: # ignore
    192                  pass
    193
    194              elif self._ttypes.COMMENT == t.type:
    195                  newseq.append(cssutils.css.CSSComment(t))
    196
    197              elif 'uri or prefix' == expected and\
    198                   self._ttypes.IDENT == t.type:
    199                  newprefix = t.value
    200                  newseq.append(newprefix)
    201                  expected = 'uri'
    202
    203              elif expected.startswith('uri') and \
    204                   t.type in (self._ttypes.URI, self._ttypes.STRING):
    205                  if t.type == self._ttypes.URI:
    206                      newuri = t.value[4:-1].strip() # url(href)
    207                      if newuri[0] ==  newuri[-1] == '"' or\
    208                         newuri[0] ==  newuri[-1] == "'":
    209                          newuri = newuri[1:-1]
    210                      self._log.warn(
    211                          u'CSSNamespaceRule: Found namespace definition with url(uri), this may be deprecated in the future, use string format "uri" instead.',
    212                          t, error = None, neverraise=True)
    213                  else:
    214                      newuri = t.value[1:-1] # "href" or 'href'
    215                  newseq.append(newuri)
    216                  expected = 'semicolon'
    217
    218              elif self._ttypes.SEMICOLON == t.type:
    219                  if 'semicolon' != expected: # normal end
    220                      valid = False
    221                      self._log.error(
    222                          u'CSSNamespaceRule: No namespace URI found.', t)
    223                  expected = None
    224                  continue
    225
    226              else:
    227                  valid = False
    228                  self._log.error(u'CSSNamespaceRule: Syntax Error.', t)
    229
    230          if expected and expected != 'EOF':
    231              valid = False
    232              self._log.error(u'CSSNamespaceRule: Syntax Error, no ";" found: %s' %
    233                        self._valuestr(cssText))
    234              return
    235
    236          if valid:
    237              self.atkeyword = newatkeyword
    238              self.uri = newuri
    239              self.prefix = newprefix
    240              self.seq = newseq
    241
    242      cssText = property(fget=_getCssText, fset=_setCssText,
    243          doc="(DOM attribute) The parsable textual representation.")
    244
    245 -    def __repr__(self):
    246          return "cssutils.css.%s(uri=%r, prefix=%r)" % (
    247                  self.__class__.__name__, self.uri, self.prefix)
    248
    249 -    def __str__(self):
    250          return "<cssutils.css.%s object uri=%r prefix=%r at 0x%x>" % (
    251                  self.__class__.__name__, self.uri, self.prefix, id(self))
    252
    253  if __name__ == '__main__':
    254      c = CSSNamespaceRule()
    255      c.uri = "x"
    256      print c.cssText
    257      c.prefix = "p"
    258      print c.cssText
    259      c.cssText = r'''@namespace "\"";'''
    260      print c.cssText
    261