Update cssutils to 0.9.6a1. Fixes #1869 (TypeError: 'NoneType' object is not iterable / [ERROR] CSSColor: No match in choice: ('HASH', u'#FFBCCB67B', 20, 19))

This commit is contained in:
Kovid Goyal
2009-02-18 09:23:50 -08:00
parent ee950ce4c7
commit 1d5aaaf830
38 changed files with 3003 additions and 3446 deletions
+3 -3
View File
@@ -1,5 +1,4 @@
"""
Document Object Model Level 2 CSS
"""Implements Document Object Model Level 2 CSS
http://www.w3.org/TR/2000/PR-DOM-Level-2-Style-20000927/css.html
currently implemented
@@ -43,7 +42,7 @@ __all__ = [
'CSSValue', 'CSSPrimitiveValue', 'CSSValueList'
]
__docformat__ = 'restructuredtext'
__version__ = '$Id: __init__.py 1116 2008-03-05 13:52:23Z cthedot $'
__version__ = '$Id: __init__.py 1610 2009-01-03 21:07:57Z cthedot $'
from cssstylesheet import *
from cssrulelist import *
@@ -60,4 +59,5 @@ from cssunknownrule import *
from selector import *
from selectorlist import *
from cssstyledeclaration import *
from property import *
from cssvalue import *
+49 -56
View File
@@ -1,16 +1,12 @@
"""CSSCharsetRule implements DOM Level 2 CSS CSSCharsetRule.
TODO:
- check encoding syntax and not codecs.lookup?
"""
"""CSSCharsetRule implements DOM Level 2 CSS CSSCharsetRule."""
__all__ = ['CSSCharsetRule']
__docformat__ = 'restructuredtext'
__version__ = '$Id: csscharsetrule.py 1170 2008-03-20 17:42:07Z cthedot $'
__version__ = '$Id: csscharsetrule.py 1605 2009-01-03 18:27:32Z cthedot $'
import codecs
import xml.dom
import cssrule
import cssutils
import xml.dom
class CSSCharsetRule(cssrule.CSSRule):
"""
@@ -28,35 +24,26 @@ class CSSCharsetRule(cssrule.CSSRule):
character encoding information e.g. in an HTTP header, has priority
(see CSS document representation) but this is not reflected in the
CSSCharsetRule.
This rule is not really needed anymore as setting
:attr:`CSSStyleSheet.encoding` is much easier.
Properties
==========
cssText: of type DOMString
The parsable textual representation of this rule
encoding: of type DOMString
The encoding information used in this @charset rule.
Format::
Inherits properties from CSSRule
charsetrule:
CHARSET_SYM S* STRING S* ';'
Format
======
charsetrule:
CHARSET_SYM S* STRING S* ';'
BUT: Only valid format is:
BUT: Only valid format is (single space, double quotes!)::
@charset "ENCODING";
"""
type = property(lambda self: cssrule.CSSRule.CHARSET_RULE)
def __init__(self, encoding=None, parentRule=None,
parentStyleSheet=None, readonly=False):
"""
encoding:
:param encoding:
a valid character encoding
readonly:
:param readonly:
defaults to False, not used yet
if readonly allows setting of properties in constructor only
"""
super(CSSCharsetRule, self).__init__(parentRule=parentRule,
parentStyleSheet=parentStyleSheet)
@@ -67,25 +54,34 @@ class CSSCharsetRule(cssrule.CSSRule):
self._readonly = readonly
def __repr__(self):
return "cssutils.css.%s(encoding=%r)" % (
self.__class__.__name__, self.encoding)
def __str__(self):
return "<cssutils.css.%s object encoding=%r at 0x%x>" % (
self.__class__.__name__, self.encoding, id(self))
def _getCssText(self):
"""returns serialized property cssText"""
"""The parsable textual representation."""
return cssutils.ser.do_CSSCharsetRule(self)
def _setCssText(self, cssText):
"""
DOMException on setting
- SYNTAX_ERR: (self)
Raised if the specified CSS string value has a syntax error and
is unparsable.
- INVALID_MODIFICATION_ERR: (self)
Raised if the specified CSS string value represents a different
type of rule than the current one.
- HIERARCHY_REQUEST_ERR: (CSSStylesheet)
Raised if the rule cannot be inserted at this point in the
style sheet.
- NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
Raised if the rule is readonly.
:param cssText:
A parsable DOMString.
:exceptions:
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified CSS string value has a syntax error and
is unparsable.
- :exc:`~xml.dom.InvalidModificationErr`:
Raised if the specified CSS string value represents a different
type of rule than the current one.
- :exc:`~xml.dom.HierarchyRequestErr`:
Raised if the rule cannot be inserted at this point in the
style sheet.
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if the rule is readonly.
"""
super(CSSCharsetRule, self)._setCssText(cssText)
@@ -120,14 +116,15 @@ class CSSCharsetRule(cssrule.CSSRule):
def _setEncoding(self, encoding):
"""
DOMException on setting
- NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
Raised if this encoding rule is readonly.
- SYNTAX_ERR: (self)
Raised if the specified encoding value has a syntax error and
is unparsable.
Currently only valid Python encodings are allowed.
:param encoding:
a valid encoding to be used. Currently only valid Python encodings
are allowed.
:exceptions:
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if this encoding rule is readonly.
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified encoding value has a syntax error and
is unparsable.
"""
self._checkReadonly()
tokenizer = self._tokenize2(encoding)
@@ -154,12 +151,8 @@ class CSSCharsetRule(cssrule.CSSRule):
encoding = property(lambda self: self._encoding, _setEncoding,
doc="(DOM)The encoding information used in this @charset rule.")
type = property(lambda self: self.CHARSET_RULE,
doc="The type of this rule, as defined by a CSSRule "
"type constant.")
wellformed = property(lambda self: bool(self.encoding))
def __repr__(self):
return "cssutils.css.%s(encoding=%r)" % (
self.__class__.__name__, self.encoding)
def __str__(self):
return "<cssutils.css.%s object encoding=%r at 0x%x>" % (
self.__class__.__name__, self.encoding, id(self))
+32 -40
View File
@@ -1,36 +1,24 @@
"""CSSComment is not defined in DOM Level 2 at all but a cssutils defined
class only.
Implements CSSRule which is also extended for a CSSComment rule type
Implements CSSRule which is also extended for a CSSComment rule type.
"""
__all__ = ['CSSComment']
__docformat__ = 'restructuredtext'
__version__ = '$Id: csscomment.py 1170 2008-03-20 17:42:07Z cthedot $'
__version__ = '$Id: csscomment.py 1638 2009-01-13 20:39:33Z cthedot $'
import xml.dom
import cssrule
import cssutils
import xml.dom
class CSSComment(cssrule.CSSRule):
"""
(cssutils) a CSS comment
Represents a CSS comment (cssutils only).
Properties
==========
cssText: of type DOMString
The comment text including comment delimiters
Inherits properties from CSSRule
Format
======
::
Format::
/*...*/
"""
type = property(lambda self: cssrule.CSSRule.COMMENT) # value = -1
# constant but needed:
wellformed = True
def __init__(self, cssText=None, parentRule=None,
parentStyleSheet=None, readonly=False):
super(CSSComment, self).__init__(parentRule=parentRule,
@@ -42,28 +30,33 @@ class CSSComment(cssrule.CSSRule):
self._readonly = readonly
def __repr__(self):
return "cssutils.css.%s(cssText=%r)" % (
self.__class__.__name__, self.cssText)
def __str__(self):
return "<cssutils.css.%s object cssText=%r at 0x%x>" % (
self.__class__.__name__, self.cssText, id(self))
def _getCssText(self):
"""returns serialized property cssText"""
"""Return serialized property cssText."""
return cssutils.ser.do_CSSComment(self)
def _setCssText(self, cssText):
"""
cssText
:param cssText:
textual text to set or tokenlist which is not tokenized
anymore. May also be a single token for this rule
parser
if called from cssparser directly this is Parser instance
DOMException on setting
- SYNTAX_ERR: (self)
Raised if the specified CSS string value has a syntax error and
is unparsable.
- INVALID_MODIFICATION_ERR: (self)
Raised if the specified CSS string value represents a different
type of rule than the current one.
- NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
Raised if the rule is readonly.
:exceptions:
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified CSS string value has a syntax error and
is unparsable.
- :exc:`~xml.dom.InvalidModificationErr`:
Raised if the specified CSS string value represents a different
type of rule than the current one.
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if the rule is readonly.
"""
super(CSSComment, self)._setCssText(cssText)
tokenizer = self._tokenize2(cssText)
@@ -81,12 +74,11 @@ class CSSComment(cssrule.CSSRule):
self._cssText = self._tokenvalue(commenttoken)
cssText = property(_getCssText, _setCssText,
doc=u"(cssutils) Textual representation of this comment")
doc=u"The parsable textual representation of this rule.")
def __repr__(self):
return "cssutils.css.%s(cssText=%r)" % (
self.__class__.__name__, self.cssText)
def __str__(self):
return "<cssutils.css.%s object cssText=%r at 0x%x>" % (
self.__class__.__name__, self.cssText, id(self))
type = property(lambda self: self.COMMENT,
doc="The type of this rule, as defined by a CSSRule "
"type constant.")
# constant but needed:
wellformed = property(lambda self: True)
+38 -53
View File
@@ -2,12 +2,12 @@
"""
__all__ = ['CSSFontFaceRule']
__docformat__ = 'restructuredtext'
__version__ = '$Id: cssfontfacerule.py 1284 2008-06-05 16:29:17Z cthedot $'
__version__ = '$Id: cssfontfacerule.py 1638 2009-01-13 20:39:33Z cthedot $'
import xml.dom
from cssstyledeclaration import CSSStyleDeclaration
import cssrule
import cssutils
from cssstyledeclaration import CSSStyleDeclaration
import xml.dom
class CSSFontFaceRule(cssrule.CSSRule):
"""
@@ -15,36 +15,19 @@ class CSSFontFaceRule(cssrule.CSSRule):
style sheet. The @font-face rule is used to hold a set of font
descriptions.
Properties
==========
atkeyword (cssutils only)
the literal keyword used
cssText: of type DOMString
The parsable textual representation of this rule
style: of type CSSStyleDeclaration
The declaration-block of this rule.
Inherits properties from CSSRule
Format
======
::
Format::
font_face
: FONT_FACE_SYM S*
'{' S* declaration [ ';' S* declaration ]* '}' S*
;
"""
type = property(lambda self: cssrule.CSSRule.FONT_FACE_RULE)
# constant but needed:
wellformed = True
def __init__(self, style=None, parentRule=None,
parentStyleSheet=None, readonly=False):
"""
if readonly allows setting of properties in constructor only
If readonly allows setting of properties in constructor only.
style
:param style:
CSSStyleDeclaration for this CSSStyleRule
"""
super(CSSFontFaceRule, self).__init__(parentRule=parentRule,
@@ -57,27 +40,32 @@ class CSSFontFaceRule(cssrule.CSSRule):
self._readonly = readonly
def __repr__(self):
return "cssutils.css.%s(style=%r)" % (
self.__class__.__name__, self.style.cssText)
def __str__(self):
return "<cssutils.css.%s object style=%r at 0x%x>" % (
self.__class__.__name__, self.style.cssText, id(self))
def _getCssText(self):
"""
returns serialized property cssText
"""
"""Return serialized property cssText."""
return cssutils.ser.do_CSSFontFaceRule(self)
def _setCssText(self, cssText):
"""
DOMException on setting
- SYNTAX_ERR: (self, StyleDeclaration)
Raised if the specified CSS string value has a syntax error and
is unparsable.
- INVALID_MODIFICATION_ERR: (self)
Raised if the specified CSS string value represents a different
type of rule than the current one.
- HIERARCHY_REQUEST_ERR: (CSSStylesheet)
Raised if the rule cannot be inserted at this point in the
style sheet.
- NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
Raised if the rule is readonly.
:exceptions:
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified CSS string value has a syntax error and
is unparsable.
- :exc:`~xml.dom.InvalidModificationErr`:
Raised if the specified CSS string value represents a different
type of rule than the current one.
- :exc:`~xml.dom.HierarchyRequestErr`:
Raised if the rule cannot be inserted at this point in the
style sheet.
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if the rule is readonly.
"""
super(CSSFontFaceRule, self)._setCssText(cssText)
@@ -135,15 +123,12 @@ class CSSFontFaceRule(cssrule.CSSRule):
self._setSeq(newseq) # contains (probably comments) upto { only
cssText = property(_getCssText, _setCssText,
doc="(DOM) The parsable textual representation of the rule.")
def _getStyle(self):
return self._style
doc="(DOM) The parsable textual representation of this rule.")
def _setStyle(self, style):
"""
style
StyleDeclaration or string
:param style:
a CSSStyleDeclaration or string
"""
self._checkReadonly()
if isinstance(style, basestring):
@@ -151,13 +136,13 @@ class CSSFontFaceRule(cssrule.CSSRule):
else:
self._style._seq = style.seq
style = property(_getStyle, _setStyle,
doc="(DOM) The declaration-block of this rule set.")
style = property(lambda self: self._style, _setStyle,
doc="(DOM) The declaration-block of this rule set, "
"a :class:`~cssutils.css.CSSStyleDeclaration`.")
def __repr__(self):
return "cssutils.css.%s(style=%r)" % (
self.__class__.__name__, self.style.cssText)
type = property(lambda self: self.FONT_FACE_RULE,
doc="The type of this rule, as defined by a CSSRule "
"type constant.")
def __str__(self):
return "<cssutils.css.%s object style=%r at 0x%x>" % (
self.__class__.__name__, self.style.cssText, id(self))
# constant but needed:
wellformed = property(lambda self: True)
+50 -79
View File
@@ -1,60 +1,30 @@
"""CSSImportRule implements DOM Level 2 CSS CSSImportRule.
plus:
``name`` property
http://www.w3.org/TR/css3-cascade/#cascading
"""CSSImportRule implements DOM Level 2 CSS CSSImportRule plus the
``name`` property from http://www.w3.org/TR/css3-cascade/#cascading.
"""
__all__ = ['CSSImportRule']
__docformat__ = 'restructuredtext'
__version__ = '$Id: cssimportrule.py 1401 2008-07-29 21:07:54Z cthedot $'
__version__ = '$Id: cssimportrule.py 1638 2009-01-13 20:39:33Z cthedot $'
import cssrule
import cssutils
import os
import urllib
import urlparse
import xml.dom
import cssrule
import cssutils
class CSSImportRule(cssrule.CSSRule):
"""
Represents an @import rule within a CSS style sheet. The @import rule
is used to import style rules from other style sheets.
Properties
==========
atkeyword: (cssutils only)
the literal keyword used
cssText: of type DOMString
The parsable textual representation of this rule
href: of type DOMString, (DOM readonly, cssutils also writable)
The location of the style sheet to be imported. The attribute will
not contain the url(...) specifier around the URI.
hreftype: 'uri' (serializer default) or 'string' (cssutils only)
The original type of href, not really relevant as it may be
reconfigured in the serializer but it is kept anyway
media: of type stylesheets::MediaList (DOM readonly)
A list of media types for this rule of type MediaList.
name:
An optional name used for cascading
styleSheet: of type CSSStyleSheet (DOM readonly)
The style sheet referred to by this rule. The value of this
attribute is None if the style sheet has not yet been loaded or if
it will not be loaded (e.g. if the stylesheet is for a media type
not supported by the user agent).
Format::
Inherits properties from CSSRule
Format
======
import
: IMPORT_SYM S*
[STRING|URI] S* [ medium [ COMMA S* medium]* ]? S* STRING? S* ';' S*
;
import
: IMPORT_SYM S*
[STRING|URI] S* [ medium [ COMMA S* medium]* ]? S* STRING? S* ';' S*
;
"""
type = property(lambda self: cssrule.CSSRule.IMPORT_RULE)
def __init__(self, href=None, mediaText=u'all', name=None,
parentRule=None, parentStyleSheet=None, readonly=False):
"""
@@ -90,30 +60,44 @@ class CSSImportRule(cssrule.CSSRule):
self._setSeq(seq)
self._readonly = readonly
def __repr__(self):
if self._usemedia:
mediaText = self.media.mediaText
else:
mediaText = None
return "cssutils.css.%s(href=%r, mediaText=%r, name=%r)" % (
self.__class__.__name__,
self.href, self.media.mediaText, self.name)
def __str__(self):
if self._usemedia:
mediaText = self.media.mediaText
else:
mediaText = None
return "<cssutils.css.%s object href=%r mediaText=%r name=%r at 0x%x>" % (
self.__class__.__name__, self.href, mediaText, self.name, id(self))
_usemedia = property(lambda self: self.media.mediaText not in (u'', u'all'),
doc="if self._media is used (or simply empty)")
def _getCssText(self):
"""
returns serialized property cssText
"""
"""Return serialized property cssText."""
return cssutils.ser.do_CSSImportRule(self)
def _setCssText(self, cssText):
"""
DOMException on setting
- HIERARCHY_REQUEST_ERR: (CSSStylesheet)
Raised if the rule cannot be inserted at this point in the
style sheet.
- INVALID_MODIFICATION_ERR: (self)
Raised if the specified CSS string value represents a different
type of rule than the current one.
- NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
Raised if the rule is readonly.
- SYNTAX_ERR: (self)
Raised if the specified CSS string value has a syntax error and
is unparsable.
:exceptions:
- :exc:`~xml.dom.HierarchyRequestErr`:
Raised if the rule cannot be inserted at this point in the
style sheet.
- :exc:`~xml.dom.InvalidModificationErr`:
Raised if the specified CSS string value represents a different
type of rule than the current one.
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if the rule is readonly.
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified CSS string value has a syntax error and
is unparsable.
"""
super(CSSImportRule, self)._setCssText(cssText)
tokenizer = self._tokenize2(cssText)
@@ -268,7 +252,7 @@ class CSSImportRule(cssrule.CSSRule):
self.styleSheet._parentStyleSheet = self.parentStyleSheet
cssText = property(fget=_getCssText, fset=_setCssText,
doc="(DOM attribute) The parsable textual representation.")
doc="(DOM) The parsable textual representation of this rule.")
def _setHref(self, href):
# update seq
@@ -291,11 +275,11 @@ class CSSImportRule(cssrule.CSSRule):
doc="Location of the style sheet to be imported.")
media = property(lambda self: self._media,
doc=u"(DOM readonly) A list of media types for this rule"
" of type MediaList")
doc="(DOM readonly) A list of media types for this rule "
"of type :class:`~cssutils.stylesheets.MediaList`.")
def _setName(self, name):
"""raises xml.dom.SyntaxErr if name is not a string"""
"""Raises xml.dom.SyntaxErr if name is not a string."""
if isinstance(name, basestring) or name is None:
# "" or ''
if not name:
@@ -322,7 +306,7 @@ class CSSImportRule(cssrule.CSSRule):
self._log.error(u'CSSImportRule: Not a valid name: %s' % name)
name = property(lambda self: self._name, _setName,
doc=u"An optional name for the imported sheet")
doc=u"An optional name for the imported sheet.")
def __setStyleSheet(self):
"""Read new CSSStyleSheet cssText from href using parentStyleSheet.href
@@ -372,28 +356,15 @@ class CSSImportRule(cssrule.CSSRule):
styleSheet = property(lambda self: self._styleSheet,
doc="(readonly) The style sheet referred to by this rule.")
type = property(lambda self: self.IMPORT_RULE,
doc="The type of this rule, as defined by a CSSRule "
"type constant.")
def _getWellformed(self):
"depending if media is used at all"
"Depending if media is used at all."
if self._usemedia:
return bool(self.href and self.media.wellformed)
else:
return bool(self.href)
wellformed = property(_getWellformed)
def __repr__(self):
if self._usemedia:
mediaText = self.media.mediaText
else:
mediaText = None
return "cssutils.css.%s(href=%r, mediaText=%r, name=%r)" % (
self.__class__.__name__,
self.href, self.media.mediaText, self.name)
def __str__(self):
if self._usemedia:
mediaText = self.media.mediaText
else:
mediaText = None
return "<cssutils.css.%s object href=%r mediaText=%r name=%r at 0x%x>" % (
self.__class__.__name__, self.href, mediaText, self.name, id(self))
+69 -81
View File
@@ -1,12 +1,11 @@
"""CSSMediaRule implements DOM Level 2 CSS CSSMediaRule.
"""
"""CSSMediaRule implements DOM Level 2 CSS CSSMediaRule."""
__all__ = ['CSSMediaRule']
__docformat__ = 'restructuredtext'
__version__ = '$Id: cssmediarule.py 1370 2008-07-14 20:15:03Z cthedot $'
__version__ = '$Id: cssmediarule.py 1641 2009-01-13 21:05:37Z cthedot $'
import xml.dom
import cssrule
import cssutils
import xml.dom
class CSSMediaRule(cssrule.CSSRule):
"""
@@ -14,31 +13,17 @@ class CSSMediaRule(cssrule.CSSRule):
MEDIA_RULE constant. On these objects the type attribute must return the
value of that constant.
Properties
==========
atkeyword: (cssutils only)
the literal keyword used
cssRules: A css::CSSRuleList of all CSS rules contained within the
media block.
cssText: of type DOMString
The parsable textual representation of this rule
media: of type stylesheets::MediaList, (DOM readonly)
A list of media types for this rule of type MediaList.
name:
An optional name used for cascading
Format::
Format
======
media
: MEDIA_SYM S* medium [ COMMA S* medium ]*
STRING? # the name
LBRACE S* ruleset* '}' S*;
``cssRules``
All Rules in this media rule, a :class:`~cssutils.css.CSSRuleList`.
"""
# CONSTANT
type = property(lambda self: cssrule.CSSRule.MEDIA_RULE)
def __init__(self, mediaText='all', name=None,
parentRule=None, parentStyleSheet=None, readonly=False):
"""constructor"""
@@ -56,12 +41,20 @@ class CSSMediaRule(cssrule.CSSRule):
self._readonly = readonly
def __iter__(self):
"""generator which iterates over cssRules."""
"""Generator iterating over these rule's cssRules."""
for rule in self.cssRules:
yield rule
def __repr__(self):
return "cssutils.css.%s(mediaText=%r)" % (
self.__class__.__name__, self.media.mediaText)
def __str__(self):
return "<cssutils.css.%s object mediaText=%r at 0x%x>" % (
self.__class__.__name__, self.media.mediaText, id(self))
def _getCssText(self):
"""return serialized property cssText"""
"""Return serialized property cssText."""
return cssutils.ser.do_CSSMediaRule(self)
def _setCssText(self, cssText):
@@ -69,19 +62,19 @@ class CSSMediaRule(cssrule.CSSRule):
:param cssText:
a parseable string or a tuple of (cssText, dict-of-namespaces)
:Exceptions:
- `NAMESPACE_ERR`: (Selector)
- :exc:`~xml.dom.NamespaceErr`:
Raised if a specified selector uses an unknown namespace
prefix.
- `SYNTAX_ERR`: (self, StyleDeclaration, etc)
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified CSS string value has a syntax error and
is unparsable.
- `INVALID_MODIFICATION_ERR`: (self)
- :exc:`~xml.dom.InvalidModificationErr`:
Raised if the specified CSS string value represents a different
type of rule than the current one.
- `HIERARCHY_REQUEST_ERR`: (CSSStylesheet)
- :exc:`~xml.dom.HierarchyRequestErr`:
Raised if the rule cannot be inserted at this point in the
style sheet.
- `NO_MODIFICATION_ALLOWED_ERR`: (CSSRule)
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if the rule is readonly.
"""
super(CSSMediaRule, self)._setCssText(cssText)
@@ -209,7 +202,7 @@ class CSSMediaRule(cssrule.CSSRule):
self.cssRules.append(r)
cssText = property(_getCssText, _setCssText,
doc="(DOM attribute) The parsable textual representation.")
doc="(DOM) The parsable textual representation of this rule.")
def _setName(self, name):
if isinstance(name, basestring) or name is None:
@@ -221,30 +214,26 @@ class CSSMediaRule(cssrule.CSSRule):
else:
self._log.error(u'CSSImportRule: Not a valid name: %s' % name)
name = property(lambda self: self._name, _setName,
doc=u"An optional name for the media rules")
doc=u"An optional name for this media rule.")
media = property(lambda self: self._media,
doc=u"(DOM readonly) A list of media types for this rule of type\
MediaList")
wellformed = property(lambda self: self.media.wellformed)
doc=u"(DOM readonly) A list of media types for this rule of type "
u":class:`~cssutils.stylesheets.MediaList`.")
def deleteRule(self, index):
"""
index
within the media block's rule collection of the rule to remove.
Delete the rule at `index` from the media block.
:param index:
of the rule to remove within the media block's rule collection
Used to delete a rule from the media block.
DOMExceptions
- INDEX_SIZE_ERR: (self)
Raised if the specified index does not correspond to a rule in
the media rule list.
- NO_MODIFICATION_ALLOWED_ERR: (self)
Raised if this media rule is readonly.
:Exceptions:
- :exc:`~xml.dom.IndexSizeErr`:
Raised if the specified index does not correspond to a rule in
the media rule list.
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if this media rule is readonly.
"""
self._checkReadonly()
@@ -257,46 +246,47 @@ class CSSMediaRule(cssrule.CSSRule):
index, self.cssRules.length))
def add(self, rule):
"""Add rule to end of this mediarule. Same as ``.insertRule(rule)``."""
"""Add `rule` to end of this mediarule.
Same as :meth:`~cssutils.css.CSSMediaRule.insertRule`."""
self.insertRule(rule, index=None)
def insertRule(self, rule, index=None):
"""
rule
The parsable text representing the rule. For rule sets this
contains both the selector and the style declaration. For
at-rules, this specifies both the at-identifier and the rule
Insert `rule` into the media block.
:param rule:
the parsable text representing the `rule` to be inserted. For rule
sets this contains both the selector and the style declaration.
For at-rules, this specifies both the at-identifier and the rule
content.
cssutils also allows rule to be a valid **CSSRule** object
cssutils also allows rule to be a valid :class:`~cssutils.css.CSSRule`
object.
index
within the media block's rule collection of the rule before
which to insert the specified rule. If the specified index is
:param index:
before the specified `rule` will be inserted.
If the specified `index` is
equal to the length of the media blocks's rule collection, the
rule will be added to the end of the media block.
If index is not given or None rule will be appended to rule
list.
Used to insert a new rule into the media block.
:returns:
the index within the media block's rule collection of the
newly inserted rule.
DOMException on setting
- HIERARCHY_REQUEST_ERR:
(no use case yet as no @charset or @import allowed))
Raised if the rule cannot be inserted at the specified index,
e.g., if an @import rule is inserted after a standard rule set
or other at-rule.
- INDEX_SIZE_ERR: (self)
Raised if the specified index is not a valid insertion point.
- NO_MODIFICATION_ALLOWED_ERR: (self)
Raised if this media rule is readonly.
- SYNTAX_ERR: (CSSStyleRule)
Raised if the specified rule has a syntax error and is
unparsable.
returns the index within the media block's rule collection of the
newly inserted rule.
:exceptions:
- :exc:`~xml.dom.HierarchyRequestErr`:
Raised if the `rule` cannot be inserted at the specified `index`,
e.g., if an @import rule is inserted after a standard rule set
or other at-rule.
- :exc:`~xml.dom.IndexSizeErr`:
Raised if the specified `index` is not a valid insertion point.
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if this media rule is readonly.
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified `rule` has a syntax error and is
unparsable.
"""
self._checkReadonly()
@@ -340,10 +330,8 @@ class CSSMediaRule(cssrule.CSSRule):
rule._parentStyleSheet = self.parentStyleSheet
return index
def __repr__(self):
return "cssutils.css.%s(mediaText=%r)" % (
self.__class__.__name__, self.media.mediaText)
def __str__(self):
return "<cssutils.css.%s object mediaText=%r at 0x%x>" % (
self.__class__.__name__, self.media.mediaText, id(self))
type = property(lambda self: self.MEDIA_RULE,
doc="The type of this rule, as defined by a CSSRule "
"type constant.")
wellformed = property(lambda self: self.media.wellformed)
+40 -64
View File
@@ -1,16 +1,12 @@
"""CSSNamespaceRule currently implements
http://dev.w3.org/csswg/css3-namespace/
(until 0.9.5a2: http://www.w3.org/TR/2006/WD-css3-namespace-20060828/)
"""
"""CSSNamespaceRule currently implements http://dev.w3.org/csswg/css3-namespace/"""
__all__ = ['CSSNamespaceRule']
__docformat__ = 'restructuredtext'
__version__ = '$Id: cssnamespacerule.py 1305 2008-06-22 18:42:51Z cthedot $'
__version__ = '$Id: cssnamespacerule.py 1638 2009-01-13 20:39:33Z cthedot $'
import xml.dom
from cssutils.helper import Deprecated
import cssrule
import cssutils
from cssutils.helper import Deprecated
import xml.dom
class CSSNamespaceRule(cssrule.CSSRule):
"""
@@ -20,36 +16,19 @@ class CSSNamespaceRule(cssrule.CSSRule):
it with a given namespace (a string). This namespace prefix can then be
used in namespace-qualified names such as those described in the
Selectors Module [SELECT] or the Values and Units module [CSS3VAL].
Dealing with these rules directly is not needed anymore, easier is
the use of :attr:`cssutils.css.CSSStyleSheet.namespaces`.
Properties
==========
atkeyword (cssutils only)
the literal keyword used
cssText: of type DOMString
The parsable textual representation of this rule
namespaceURI: of type DOMString
The namespace URI (a simple string!) which is bound to the given
prefix. If no prefix is set (``CSSNamespaceRule.prefix==''``)
the namespace defined by ``namespaceURI`` is set as the default
namespace.
prefix: of type DOMString
The prefix used in the stylesheet for the given
``CSSNamespaceRule.nsuri``. If prefix is empty namespaceURI sets a
default namespace for the stylesheet.
Format::
Inherits properties from CSSRule
Format
======
namespace
: NAMESPACE_SYM S* [namespace_prefix S*]? [STRING|URI] S* ';' S*
;
namespace_prefix
: IDENT
;
namespace
: NAMESPACE_SYM S* [namespace_prefix S*]? [STRING|URI] S* ';' S*
;
namespace_prefix
: IDENT
;
"""
type = property(lambda self: cssrule.CSSRule.NAMESPACE_RULE)
def __init__(self, namespaceURI=None, prefix=None, cssText=None,
parentRule=None, parentStyleSheet=None, readonly=False):
"""
@@ -102,27 +81,31 @@ class CSSNamespaceRule(cssrule.CSSRule):
self._readonly = readonly
def __repr__(self):
return "cssutils.css.%s(namespaceURI=%r, prefix=%r)" % (
self.__class__.__name__, self.namespaceURI, self.prefix)
def __str__(self):
return "<cssutils.css.%s object namespaceURI=%r prefix=%r at 0x%x>" % (
self.__class__.__name__, self.namespaceURI, self.prefix, id(self))
def _getCssText(self):
"""
returns serialized property cssText
"""
"""Return serialized property cssText"""
return cssutils.ser.do_CSSNamespaceRule(self)
def _setCssText(self, cssText):
"""
DOMException on setting
:param cssText: initial value for this rules cssText which is parsed
:Exceptions:
- `HIERARCHY_REQUEST_ERR`: (CSSStylesheet)
:exceptions:
- :exc:`~xml.dom.HierarchyRequestErr`:
Raised if the rule cannot be inserted at this point in the
style sheet.
- `INVALID_MODIFICATION_ERR`: (self)
- :exc:`~xml.dom.InvalidModificationErr`:
Raised if the specified CSS string value represents a different
type of rule than the current one.
- `NO_MODIFICATION_ALLOWED_ERR`: (CSSRule)
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if the rule is readonly.
- `SYNTAX_ERR`: (self)
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified CSS string value has a syntax error and
is unparsable.
"""
@@ -222,15 +205,13 @@ class CSSNamespaceRule(cssrule.CSSRule):
self._setSeq(newseq)
cssText = property(fget=_getCssText, fset=_setCssText,
doc="(DOM attribute) The parsable textual representation.")
doc="(DOM) The parsable textual representation of this rule.")
def _setNamespaceURI(self, namespaceURI):
"""
DOMException on setting
:param namespaceURI: the initial value for this rules namespaceURI
:Exceptions:
- `NO_MODIFICATION_ALLOWED_ERR`:
:exceptions:
- :exc:`~xml.dom.NoModificationAllowedErr`:
(CSSRule) Raised if this rule is readonly or a namespaceURI is
already set in this rule.
"""
@@ -246,18 +227,16 @@ class CSSNamespaceRule(cssrule.CSSRule):
error=xml.dom.NoModificationAllowedErr)
namespaceURI = property(lambda self: self._namespaceURI, _setNamespaceURI,
doc="URI (string!) of the defined namespace.")
doc="URI (handled as simple string) of the defined namespace.")
def _setPrefix(self, prefix=None):
"""
DOMException on setting
:param prefix: the new prefix
:Exceptions:
- `SYNTAX_ERR`: (TODO)
:exceptions:
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified CSS string value has a syntax error and
is unparsable.
- `NO_MODIFICATION_ALLOWED_ERR`: CSSRule)
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if this rule is readonly.
"""
self._checkReadonly()
@@ -295,12 +274,9 @@ class CSSNamespaceRule(cssrule.CSSRule):
# _setParentStyleSheet,
# doc=u"Containing CSSStyleSheet.")
type = property(lambda self: self.NAMESPACE_RULE,
doc="The type of this rule, as defined by a CSSRule "
"type constant.")
wellformed = property(lambda self: self.namespaceURI is not None)
def __repr__(self):
return "cssutils.css.%s(namespaceURI=%r, prefix=%r)" % (
self.__class__.__name__, self.namespaceURI, self.prefix)
def __str__(self):
return "<cssutils.css.%s object namespaceURI=%r prefix=%r at 0x%x>" % (
self.__class__.__name__, self.namespaceURI, self.prefix, id(self))
+86 -100
View File
@@ -2,13 +2,13 @@
"""
__all__ = ['CSSPageRule']
__docformat__ = 'restructuredtext'
__version__ = '$Id: csspagerule.py 1284 2008-06-05 16:29:17Z cthedot $'
__version__ = '$Id: csspagerule.py 1658 2009-02-07 18:24:40Z cthedot $'
import xml.dom
from cssstyledeclaration import CSSStyleDeclaration
from selectorlist import SelectorList
import cssrule
import cssutils
from selectorlist import SelectorList
from cssstyledeclaration import CSSStyleDeclaration
import xml.dom
class CSSPageRule(cssrule.CSSRule):
"""
@@ -16,22 +16,7 @@ class CSSPageRule(cssrule.CSSRule):
sheet. The @page rule is used to specify the dimensions, orientation,
margins, etc. of a page box for paged media.
Properties
==========
atkeyword (cssutils only)
the literal keyword used
cssText: of type DOMString
The parsable textual representation of this rule
selectorText: of type DOMString
The parsable textual representation of the page selector for the rule.
style: of type CSSStyleDeclaration
The declaration-block of this rule.
Inherits properties from CSSRule
Format
======
::
Format::
page
: PAGE_SYM S* pseudo_page? S*
@@ -40,20 +25,15 @@ class CSSPageRule(cssrule.CSSRule):
pseudo_page
: ':' IDENT # :first, :left, :right in CSS 2.1
;
"""
type = property(lambda self: cssrule.CSSRule.PAGE_RULE)
# constant but needed:
wellformed = True
def __init__(self, selectorText=None, style=None, parentRule=None,
parentStyleSheet=None, readonly=False):
"""
if readonly allows setting of properties in constructor only
If readonly allows setting of properties in constructor only.
selectorText
:param selectorText:
type string
style
:param style:
CSSStyleDeclaration for this CSSStyleRule
"""
super(CSSPageRule, self).__init__(parentRule=parentRule,
@@ -64,7 +44,7 @@ class CSSPageRule(cssrule.CSSRule):
self.selectorText = selectorText
tempseq.append(self.selectorText, 'selectorText')
else:
self._selectorText = u''
self._selectorText = self._tempSeq()
if style:
self.style = style
tempseq.append(self.style, 'style')
@@ -74,20 +54,29 @@ class CSSPageRule(cssrule.CSSRule):
self._readonly = readonly
def __repr__(self):
return "cssutils.css.%s(selectorText=%r, style=%r)" % (
self.__class__.__name__, self.selectorText, self.style.cssText)
def __str__(self):
return "<cssutils.css.%s object selectorText=%r style=%r at 0x%x>" % (
self.__class__.__name__, self.selectorText, self.style.cssText,
id(self))
def __parseSelectorText(self, selectorText):
"""
parses selectorText which may also be a list of tokens
and returns (selectorText, seq)
Parse `selectorText` which may also be a list of tokens
and returns (selectorText, seq).
see _setSelectorText for details
"""
# for closures: must be a mutable
new = {'selector': None, 'wellformed': True}
new = {'wellformed': True, 'last-S': False}
def _char(expected, seq, token, tokenizer=None):
# pseudo_page, :left, :right or :first
val = self._tokenvalue(token)
if ':' == expected and u':' == val:
if not new['last-S'] and expected in ['page', ': or EOF'] and u':' == val:
try:
identtoken = tokenizer.next()
except StopIteration:
@@ -100,8 +89,7 @@ class CSSPageRule(cssrule.CSSRule):
u'CSSPageRule selectorText: Expected IDENT but found: %r' %
ival, token)
else:
new['selector'] = val + ival
seq.append(new['selector'], 'selector')
seq.append(val + ival, 'pseudo')
return 'EOF'
return expected
else:
@@ -112,22 +100,37 @@ class CSSPageRule(cssrule.CSSRule):
def S(expected, seq, token, tokenizer=None):
"Does not raise if EOF is found."
if expected == ': or EOF':
# pseudo must directly follow IDENT if given
new['last-S'] = True
return expected
def IDENT(expected, seq, token, tokenizer=None):
""
val = self._tokenvalue(token)
if 'page' == expected:
seq.append(val, 'IDENT')
return ': or EOF'
else:
new['wellformed'] = False
self._log.error(
u'CSSPageRule selectorText: Unexpected IDENT: %r' % val, token)
return expected
def COMMENT(expected, seq, token, tokenizer=None):
"Does not raise if EOF is found."
seq.append(cssutils.css.CSSComment([token]), 'COMMENT')
return expected
newseq = self._tempSeq()
wellformed, expected = self._parse(expected=':',
wellformed, expected = self._parse(expected='page',
seq=newseq, tokenizer=self._tokenize2(selectorText),
productions={'CHAR': _char,
'IDENT': IDENT,
'COMMENT': COMMENT,
'S': S},
new=new)
wellformed = wellformed and new['wellformed']
newselector = new['selector']
# post conditions
if expected == 'ident':
@@ -135,33 +138,30 @@ class CSSPageRule(cssrule.CSSRule):
u'CSSPageRule selectorText: No valid selector: %r' %
self._valuestr(selectorText))
if not newselector in (None, u':first', u':left', u':right'):
self._log.warn(u'CSSPageRule: Unknown CSS 2.1 @page selector: %r' %
newselector, neverraise=True)
# if not newselector in (None, u':first', u':left', u':right'):
# self._log.warn(u'CSSPageRule: Unknown CSS 2.1 @page selector: %r' %
# newselector, neverraise=True)
return newselector, newseq
return wellformed, newseq
def _getCssText(self):
"""
returns serialized property cssText
"""
"""Return serialized property cssText."""
return cssutils.ser.do_CSSPageRule(self)
def _setCssText(self, cssText):
"""
DOMException on setting
- SYNTAX_ERR: (self, StyleDeclaration)
Raised if the specified CSS string value has a syntax error and
is unparsable.
- INVALID_MODIFICATION_ERR: (self)
Raised if the specified CSS string value represents a different
type of rule than the current one.
- HIERARCHY_REQUEST_ERR: (CSSStylesheet)
Raised if the rule cannot be inserted at this point in the
style sheet.
- NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
Raised if the rule is readonly.
:exceptions:
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified CSS string value has a syntax error and
is unparsable.
- :exc:`~xml.dom.InvalidModificationErr`:
Raised if the specified CSS string value represents a different
type of rule than the current one.
- :exc:`~xml.dom.HierarchyRequestErr`:
Raised if the rule cannot be inserted at this point in the
style sheet.
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if the rule is readonly.
"""
super(CSSPageRule, self)._setCssText(cssText)
@@ -190,7 +190,7 @@ class CSSPageRule(cssrule.CSSRule):
u'CSSPageRule: Trailing content found.', token=nonetoken)
newselector, newselectorseq = self.__parseSelectorText(selectortokens)
wellformed, newselectorseq = self.__parseSelectorText(selectortokens)
newstyle = CSSStyleDeclaration()
val, typ = self._tokenvalue(braceorEOFtoken), self._type(braceorEOFtoken)
@@ -206,63 +206,49 @@ class CSSPageRule(cssrule.CSSRule):
newstyle.cssText = styletokens
if wellformed:
self._selectorText = newselector # already parsed
self._selectorText = newselectorseq # already parsed
self.style = newstyle
self._setSeq(newselectorseq) # contains upto style only
cssText = property(_getCssText, _setCssText,
doc="(DOM) The parsable textual representation of the rule.")
doc="(DOM) The parsable textual representation of this rule.")
def _getSelectorText(self):
"""
wrapper for cssutils Selector object
"""
return self._selectorText
"""Wrapper for cssutils Selector object."""
return cssutils.ser.do_CSSPageRuleSelector(self._selectorText)#self._selectorText
def _setSelectorText(self, selectorText):
"""
wrapper for cssutils Selector object
"""Wrapper for cssutils Selector object.
selector: DOM String
in CSS 2.1 one of
:param selectorText:
DOM String, in CSS 2.1 one of
- :first
- :left
- :right
- empty
If WS or Comments are included they are ignored here! Only
way to add a comment is via setting ``cssText``
DOMException on setting
- SYNTAX_ERR:
Raised if the specified CSS string value has a syntax error
and is unparsable.
- NO_MODIFICATION_ALLOWED_ERR: (self)
Raised if this rule is readonly.
:exceptions:
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified CSS string value has a syntax error
and is unparsable.
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if this rule is readonly.
"""
self._checkReadonly()
# may raise SYNTAX_ERR
newselectortext, newseq = self.__parseSelectorText(selectorText)
if newselectortext:
for i, x in enumerate(self.seq):
if x == self._selectorText:
self.seq[i] = newselectortext
self._selectorText = newselectortext
wellformed, newseq = self.__parseSelectorText(selectorText)
if wellformed and newseq:
self._selectorText = newseq
selectorText = property(_getSelectorText, _setSelectorText,
doc="""(DOM) The parsable textual representation of the page selector for the rule.""")
def _getStyle(self):
return self._style
def _setStyle(self, style):
"""
style
StyleDeclaration or string
:param style:
a CSSStyleDeclaration or string
"""
self._checkReadonly()
@@ -273,14 +259,14 @@ class CSSPageRule(cssrule.CSSRule):
# so use seq!
self._style._seq = style.seq
style = property(_getStyle, _setStyle,
doc="(DOM) The declaration-block of this rule set.")
style = property(lambda self: self._style, _setStyle,
doc="(DOM) The declaration-block of this rule set, "
"a :class:`~cssutils.css.CSSStyleDeclaration`.")
def __repr__(self):
return "cssutils.css.%s(selectorText=%r, style=%r)" % (
self.__class__.__name__, self.selectorText, self.style.cssText)
def __str__(self):
return "<cssutils.css.%s object selectorText=%r style=%r at 0x%x>" % (
self.__class__.__name__, self.selectorText, self.style.cssText,
id(self))
type = property(lambda self: self.PAGE_RULE,
doc="The type of this rule, as defined by a CSSRule "
"type constant.")
# constant but needed:
wellformed = property(lambda self: True)
+28 -255
View File
@@ -45,264 +45,16 @@ TODO: CSS2Properties DOMImplementation
string for this extended interface listed in this section is "CSS2"
and the version is "2.0".
cssvalues
=========
contributed by Kevin D. Smith, thanks!
"cssvalues" is used as a property validator.
it is an importable object that contains a dictionary of compiled regular
expressions. The keys of this dictionary are all of the valid CSS property
names. The values are compiled regular expressions that can be used to
validate the values for that property. (Actually, the values are references
to the 'match' method of a compiled regular expression, so that they are
simply called like functions.)
"""
__all__ = ['CSS2Properties', 'cssvalues']
__all__ = ['CSS2Properties']
__docformat__ = 'restructuredtext'
__version__ = '$Id: cssproperties.py 1469 2008-09-15 19:06:00Z cthedot $'
__version__ = '$Id: cssproperties.py 1638 2009-01-13 20:39:33Z cthedot $'
import cssutils.profiles
import re
"""
Define some regular expression fragments that will be used as
macros within the CSS property value regular expressions.
"""
MACROS = {
'ident': r'[-]?{nmstart}{nmchar}*',
'name': r'{nmchar}+',
'nmstart': r'[_a-z]|{nonascii}|{escape}',
'nonascii': r'[^\0-\177]',
'unicode': r'\\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?',
'escape': r'{unicode}|\\[ -~\200-\777]',
# 'escape': r'{unicode}|\\[ -~\200-\4177777]',
'int': r'[-]?\d+',
'nmchar': r'[\w-]|{nonascii}|{escape}',
'num': r'[-]?\d+|[-]?\d*\.\d+',
'number': r'{num}',
'string': r'{string1}|{string2}',
'string1': r'"(\\\"|[^\"])*"',
'string2': r"'(\\\'|[^\'])*'",
'nl': r'\n|\r\n|\r|\f',
'w': r'\s*',
'integer': r'{int}',
'length': r'0|{num}(em|ex|px|in|cm|mm|pt|pc)',
'angle': r'0|{num}(deg|grad|rad)',
'time': r'0|{num}m?s',
'frequency': r'0|{num}k?Hz',
'color': r'(maroon|red|orange|yellow|olive|purple|fuchsia|white|lime|green|navy|blue|aqua|teal|black|silver|gray|ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText)|#[0-9a-f]{3}|#[0-9a-f]{6}|rgb\({w}{int}{w},{w}{int}{w},{w}{int}{w}\)|rgb\({w}{num}%{w},{w}{num}%{w},{w}{num}%{w}\)',
'uri': r'url\({w}({string}|(\\\)|[^\)])+){w}\)',
'percentage': r'{num}%',
'border-style': 'none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset',
'border-color': '{color}',
'border-width': '{length}|thin|medium|thick',
'background-color': r'{color}|transparent|inherit',
'background-image': r'{uri}|none|inherit',
'background-position': r'({percentage}|{length})(\s*({percentage}|{length}))?|((top|center|bottom)\s*(left|center|right))|((left|center|right)\s*(top|center|bottom))|inherit',
'background-repeat': r'repeat|repeat-x|repeat-y|no-repeat|inherit',
'background-attachment': r'scroll|fixed|inherit',
'shape': r'rect\(({w}({length}|auto}){w},){3}{w}({length}|auto){w}\)',
'counter': r'counter\({w}{identifier}{w}(?:,{w}{list-style-type}{w})?\)',
'identifier': r'{ident}',
'family-name': r'{string}|{identifier}',
'generic-family': r'serif|sans-serif|cursive|fantasy|monospace',
'absolute-size': r'(x?x-)?(small|large)|medium',
'relative-size': r'smaller|larger',
'font-family': r'(({family-name}|{generic-family}){w},{w})*({family-name}|{generic-family})|inherit',
'font-size': r'{absolute-size}|{relative-size}|{length}|{percentage}|inherit',
'font-style': r'normal|italic|oblique|inherit',
'font-variant': r'normal|small-caps|inherit',
'font-weight': r'normal|bold|bolder|lighter|[1-9]00|inherit',
'line-height': r'normal|{number}|{length}|{percentage}|inherit',
'list-style-image': r'{uri}|none|inherit',
'list-style-position': r'inside|outside|inherit',
'list-style-type': r'disc|circle|square|decimal|decimal-leading-zero|lower-roman|upper-roman|lower-greek|lower-(latin|alpha)|upper-(latin|alpha)|armenian|georgian|none|inherit',
'margin-width': r'{length}|{percentage}|auto',
'outline-color': r'{color}|invert|inherit',
'outline-style': r'{border-style}|inherit',
'outline-width': r'{border-width}|inherit',
'padding-width': r'{length}|{percentage}',
'specific-voice': r'{identifier}',
'generic-voice': r'male|female|child',
'content': r'{string}|{uri}|{counter}|attr\({w}{identifier}{w}\)|open-quote|close-quote|no-open-quote|no-close-quote',
'border-attrs': r'{border-width}|{border-style}|{border-color}',
'background-attrs': r'{background-color}|{background-image}|{background-repeat}|{background-attachment}|{background-position}',
'list-attrs': r'{list-style-type}|{list-style-position}|{list-style-image}',
'font-attrs': r'{font-style}|{font-variant}|{font-weight}',
'outline-attrs': r'{outline-color}|{outline-style}|{outline-width}',
'text-attrs': r'underline|overline|line-through|blink',
}
"""
Define the regular expressions for validation all CSS values
"""
cssvalues = {
'azimuth': r'{angle}|(behind\s+)?(left-side|far-left|left|center-left|center|center-right|right|far-right|right-side)(\s+behind)?|behind|leftwards|rightwards|inherit',
'background-attachment': r'{background-attachment}',
'background-color': r'{background-color}',
'background-image': r'{background-image}',
'background-position': r'{background-position}',
'background-repeat': r'{background-repeat}',
# Each piece should only be allowed one time
'background': r'{background-attrs}(\s+{background-attrs})*|inherit',
'border-collapse': r'collapse|separate|inherit',
'border-color': r'({border-color}|transparent)(\s+({border-color}|transparent)){0,3}|inherit',
'border-spacing': r'{length}(\s+{length})?|inherit',
'border-style': r'{border-style}(\s+{border-style}){0,3}|inherit',
'border-top': r'{border-attrs}(\s+{border-attrs})*|inherit',
'border-right': r'{border-attrs}(\s+{border-attrs})*|inherit',
'border-bottom': r'{border-attrs}(\s+{border-attrs})*|inherit',
'border-left': r'{border-attrs}(\s+{border-attrs})*|inherit',
'border-top-color': r'{border-color}|transparent|inherit',
'border-right-color': r'{border-color}|transparent|inherit',
'border-bottom-color': r'{border-color}|transparent|inherit',
'border-left-color': r'{border-color}|transparent|inherit',
'border-top-style': r'{border-style}|inherit',
'border-right-style': r'{border-style}|inherit',
'border-bottom-style': r'{border-style}|inherit',
'border-left-style': r'{border-style}|inherit',
'border-top-width': r'{border-width}|inherit',
'border-right-width': r'{border-width}|inherit',
'border-bottom-width': r'{border-width}|inherit',
'border-left-width': r'{border-width}|inherit',
'border-width': r'{border-width}(\s+{border-width}){0,3}|inherit',
'border': r'{border-attrs}(\s+{border-attrs})*|inherit',
'bottom': r'{length}|{percentage}|auto|inherit',
'caption-side': r'top|bottom|inherit',
'clear': r'none|left|right|both|inherit',
'clip': r'{shape}|auto|inherit',
'color': r'{color}|inherit',
'content': r'normal|{content}(\s+{content})*|inherit',
'counter-increment': r'({identifier}(\s+{integer})?)(\s+({identifier}(\s+{integer})))*|none|inherit',
'counter-reset': r'({identifier}(\s+{integer})?)(\s+({identifier}(\s+{integer})))*|none|inherit',
'cue-after': r'{uri}|none|inherit',
'cue-before': r'{uri}|none|inherit',
'cue': r'({uri}|none|inherit){1,2}|inherit',
'cursor': r'((({uri}{w},{w})*)?(auto|crosshair|default|pointer|move|(e|ne|nw|n|se|sw|s|w)-resize|text|wait|help|progress))|inherit',
'direction': r'ltr|rtl|inherit',
'display': r'inline|block|list-item|run-in|inline-block|table|inline-table|table-row-group|table-header-group|table-footer-group|table-row|table-column-group|table-column|table-cell|table-caption|none|inherit',
'elevation': r'{angle}|below|level|above|higher|lower|inherit',
'empty-cells': r'show|hide|inherit',
'float': r'left|right|none|inherit',
'font-family': r'{font-family}',
'font-size': r'{font-size}',
'font-style': r'{font-style}',
'font-variant': r'{font-variant}',
'font-weight': r'{font-weight}',
'font': r'({font-attrs}\s+)*{font-size}({w}/{w}{line-height})?\s+{font-family}|caption|icon|menu|message-box|small-caption|status-bar|inherit',
'height': r'{length}|{percentage}|auto|inherit',
'left': r'{length}|{percentage}|auto|inherit',
'letter-spacing': r'normal|{length}|inherit',
'line-height': r'{line-height}',
'list-style-image': r'{list-style-image}',
'list-style-position': r'{list-style-position}',
'list-style-type': r'{list-style-type}',
'list-style': r'{list-attrs}(\s+{list-attrs})*|inherit',
'margin-right': r'{margin-width}|inherit',
'margin-left': r'{margin-width}|inherit',
'margin-top': r'{margin-width}|inherit',
'margin-bottom': r'{margin-width}|inherit',
'margin': r'{margin-width}(\s+{margin-width}){0,3}|inherit',
'max-height': r'{length}|{percentage}|none|inherit',
'max-width': r'{length}|{percentage}|none|inherit',
'min-height': r'{length}|{percentage}|none|inherit',
'min-width': r'{length}|{percentage}|none|inherit',
'orphans': r'{integer}|inherit',
'outline-color': r'{outline-color}',
'outline-style': r'{outline-style}',
'outline-width': r'{outline-width}',
'outline': r'{outline-attrs}(\s+{outline-attrs})*|inherit',
'overflow': r'visible|hidden|scroll|auto|inherit',
'padding-top': r'{padding-width}|inherit',
'padding-right': r'{padding-width}|inherit',
'padding-bottom': r'{padding-width}|inherit',
'padding-left': r'{padding-width}|inherit',
'padding': r'{padding-width}(\s+{padding-width}){0,3}|inherit',
'page-break-after': r'auto|always|avoid|left|right|inherit',
'page-break-before': r'auto|always|avoid|left|right|inherit',
'page-break-inside': r'avoid|auto|inherit',
'pause-after': r'{time}|{percentage}|inherit',
'pause-before': r'{time}|{percentage}|inherit',
'pause': r'({time}|{percentage}){1,2}|inherit',
'pitch-range': r'{number}|inherit',
'pitch': r'{frequency}|x-low|low|medium|high|x-high|inherit',
'play-during': r'{uri}(\s+(mix|repeat))*|auto|none|inherit',
'position': r'static|relative|absolute|fixed|inherit',
'quotes': r'({string}\s+{string})(\s+{string}\s+{string})*|none|inherit',
'richness': r'{number}|inherit',
'right': r'{length}|{percentage}|auto|inherit',
'speak-header': r'once|always|inherit',
'speak-numeral': r'digits|continuous|inherit',
'speak-punctuation': r'code|none|inherit',
'speak': r'normal|none|spell-out|inherit',
'speech-rate': r'{number}|x-slow|slow|medium|fast|x-fast|faster|slower|inherit',
'stress': r'{number}|inherit',
'table-layout': r'auto|fixed|inherit',
'text-align': r'left|right|center|justify|inherit',
'text-decoration': r'none|{text-attrs}(\s+{text-attrs})*|inherit',
'text-indent': r'{length}|{percentage}|inherit',
'text-transform': r'capitalize|uppercase|lowercase|none|inherit',
'top': r'{length}|{percentage}|auto|inherit',
'unicode-bidi': r'normal|embed|bidi-override|inherit',
'vertical-align': r'baseline|sub|super|top|text-top|middle|bottom|text-bottom|{percentage}|{length}|inherit',
'visibility': r'visible|hidden|collapse|inherit',
'voice-family': r'({specific-voice}|{generic-voice}{w},{w})*({specific-voice}|{generic-voice})|inherit',
'volume': r'{number}|{percentage}|silent|x-soft|soft|medium|loud|x-loud|inherit',
'white-space': r'normal|pre|nowrap|pre-wrap|pre-line|inherit',
'widows': r'{integer}|inherit',
'width': r'{length}|{percentage}|auto|inherit',
'word-spacing': r'normal|{length}|inherit',
'z-index': r'auto|{integer}|inherit',
}
def _expand_macros(tokdict):
""" Expand macros in token dictionary """
def macro_value(m):
return '(?:%s)' % MACROS[m.groupdict()['macro']]
for key, value in tokdict.items():
while re.search(r'{[a-z][a-z0-9-]*}', value):
value = re.sub(r'{(?P<macro>[a-z][a-z0-9-]*)}',
macro_value, value)
tokdict[key] = value
return tokdict
def _compile_regexes(tokdict):
""" Compile all regular expressions into callable objects """
for key, value in tokdict.items():
tokdict[key] = re.compile('^(?:%s)$' % value, re.I).match
return tokdict
_compile_regexes(_expand_macros(cssvalues))
# functions to convert between CSS and DOM name
_reCSStoDOMname = re.compile('-[a-z]', re.I)
def _toDOMname(CSSname):
"""
returns DOMname for given CSSname e.g. for CSSname 'font-style' returns
'fontStyle'
"""
def _doCSStoDOMname2(m): return m.group(0)[1].capitalize()
return _reCSStoDOMname.sub(_doCSStoDOMname2, CSSname)
_reDOMtoCSSname = re.compile('([A-Z])[a-z]+')
def _toCSSname(DOMname):
"""
returns CSSname for given DOMname e.g. for DOMname 'fontStyle' returns
'font-style'
"""
def _doDOMtoCSSname2(m): return '-' + m.group(0).lower()
return _reDOMtoCSSname.sub(_doDOMtoCSSname2, DOMname)
class CSS2Properties(object):
"""
The CSS2Properties interface represents a convenience mechanism
"""The CSS2Properties interface represents a convenience mechanism
for retrieving and setting properties within a CSSStyleDeclaration.
The attributes of this interface correspond to all the properties
specified in CSS2. Getting an attribute of this interface is
@@ -325,17 +77,38 @@ class CSS2Properties(object):
def _getP(self, CSSname): pass
def _setP(self, CSSname, value): pass
def _delP(self, CSSname): pass
_reCSStoDOMname = re.compile('-[a-z]', re.I)
def _toDOMname(CSSname):
"""Returns DOMname for given CSSname e.g. for CSSname 'font-style' returns
'fontStyle'.
"""
def _doCSStoDOMname2(m): return m.group(0)[1].capitalize()
return _reCSStoDOMname.sub(_doCSStoDOMname2, CSSname)
_reDOMtoCSSname = re.compile('([A-Z])[a-z]+')
def _toCSSname(DOMname):
"""Return CSSname for given DOMname e.g. for DOMname 'fontStyle' returns
'font-style'.
"""
def _doDOMtoCSSname2(m): return '-' + m.group(0).lower()
return _reDOMtoCSSname.sub(_doDOMtoCSSname2, DOMname)
# add list of DOMname properties to CSS2Properties
# used for CSSStyleDeclaration to check if allowed properties
# but somehow doubled, any better way?
CSS2Properties._properties = [_toDOMname(p) for p in cssvalues.keys()]
CSS2Properties._properties = []
for group in cssutils.profiles.properties:
for name in cssutils.profiles.properties[group]:
CSS2Properties._properties.append(_toDOMname(name))
# add CSS2Properties to CSSStyleDeclaration:
def __named_property_def(DOMname):
"""
closure to keep name known in each properties accessor function
DOMname is converted to CSSname here, so actual calls use CSSname
Closure to keep name known in each properties accessor function
DOMname is converted to CSSname here, so actual calls use CSSname.
"""
CSSname = _toCSSname(DOMname)
def _get(self): return self._getP(CSSname)
+44 -79
View File
@@ -1,46 +1,17 @@
"""CSSRule implements DOM Level 2 CSS CSSRule."""
__all__ = ['CSSRule']
__docformat__ = 'restructuredtext'
__version__ = '$Id: cssrule.py 1177 2008-03-20 17:47:23Z cthedot $'
__version__ = '$Id: cssrule.py 1638 2009-01-13 20:39:33Z cthedot $'
import xml.dom
import cssutils
import xml.dom
class CSSRule(cssutils.util.Base2):
"""
Abstract base interface for any type of CSS statement. This includes
"""Abstract base interface for any type of CSS statement. This includes
both rule sets and at-rules. An implementation is expected to preserve
all rules specified in a CSS style sheet, even if the rule is not
recognized by the parser. Unrecognized rules are represented using the
CSSUnknownRule interface.
Properties
==========
cssText: of type DOMString
The parsable textual representation of the rule. This reflects the
current state of the rule and not its initial value.
parentRule: of type CSSRule, readonly
If this rule is contained inside another rule (e.g. a style rule
inside an @media block), this is the containing rule. If this rule
is not nested inside any other rules, this returns None.
parentStyleSheet: of type CSSStyleSheet, readonly
The style sheet that contains this rule.
type: of type unsigned short, readonly
The type of the rule, as defined above. The expectation is that
binding-specific casting methods can be used to cast down from an
instance of the CSSRule interface to the specific derived interface
implied by the type.
cssutils only
-------------
seq (READONLY):
contains sequence of parts of the rule including comments but
excluding @KEYWORD and braces
typeString: string
A string name of the type of this rule, e.g. 'STYLE_RULE'. Mainly
useful for debugging
wellformed:
if a rule is valid
:class:`CSSUnknownRule` interface.
"""
"""
@@ -61,21 +32,8 @@ class CSSRule(cssutils.util.Base2):
'MEDIA_RULE', 'FONT_FACE_RULE', 'PAGE_RULE', 'NAMESPACE_RULE',
'COMMENT']
type = UNKNOWN_RULE
"""
The type of this rule, as defined by a CSSRule type constant.
Overwritten in derived classes.
The expectation is that binding-specific casting methods can be used to
cast down from an instance of the CSSRule interface to the specific
derived interface implied by the type.
(Casting not for this Python implementation I guess...)
"""
def __init__(self, parentRule=None, parentStyleSheet=None, readonly=False):
"""
set common attributes for all rules
"""
"""Set common attributes for all rules."""
super(CSSRule, self).__init__()
self._parentRule = parentRule
self._parentStyleSheet = parentStyleSheet
@@ -83,33 +41,8 @@ class CSSRule(cssutils.util.Base2):
# must be set after initialization of #inheriting rule is done
self._readonly = False
def _setCssText(self, cssText):
"""
DOMException on setting
- SYNTAX_ERR:
Raised if the specified CSS string value has a syntax error and
is unparsable.
- INVALID_MODIFICATION_ERR:
Raised if the specified CSS string value represents a different
type of rule than the current one.
- HIERARCHY_REQUEST_ERR:
Raised if the rule cannot be inserted at this point in the
style sheet.
- NO_MODIFICATION_ALLOWED_ERR: (self)
Raised if the rule is readonly.
"""
self._checkReadonly()
cssText = property(lambda self: u'', _setCssText,
doc="""(DOM) The parsable textual representation of the rule. This
reflects the current state of the rule and not its initial value.
The initial value is saved, but this may be removed in a future
version!
MUST BE OVERWRITTEN IN SUBCLASS TO WORK!""")
def _setAtkeyword(self, akw):
"""checks if new keyword is normalized same as old"""
"""Check if new keyword fits the rule it is used for."""
if not self.atkeyword or (self._normalize(akw) ==
self._normalize(self.atkeyword)):
self._atkeyword = akw
@@ -119,16 +52,48 @@ class CSSRule(cssutils.util.Base2):
error=xml.dom.InvalidModificationErr)
atkeyword = property(lambda self: self._atkeyword, _setAtkeyword,
doc=u"@keyword for @rules")
doc=u"Literal keyword of an @rule (e.g. ``@IMport``).")
def _setCssText(self, cssText):
"""
:param cssText:
A parsable DOMString.
:exceptions:
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified CSS string value has a syntax error and
is unparsable.
- :exc:`~xml.dom.InvalidModificationErr`:
Raised if the specified CSS string value represents a different
type of rule than the current one.
- :exc:`~xml.dom.HierarchyRequestErr`:
Raised if the rule cannot be inserted at this point in the
style sheet.
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if the rule is readonly.
"""
self._checkReadonly()
cssText = property(lambda self: u'', _setCssText,
doc="(DOM) The parsable textual representation of the "
"rule. This reflects the current state of the rule "
"and not its initial value.")
parentRule = property(lambda self: self._parentRule,
doc=u"READONLY")
doc="If this rule is contained inside "
"another rule (e.g. a style rule inside "
"an @media block), this is the containing "
"rule. If this rule is not nested inside "
"any other rules, this returns None.")
parentStyleSheet = property(lambda self: self._parentStyleSheet,
doc=u"READONLY")
doc="The style sheet that contains this rule.")
wellformed = property(lambda self: False,
doc=u"READONLY")
type = property(lambda self: self.UNKNOWN_RULE,
doc="The type of this rule, as defined by a CSSRule "
"type constant.")
typeString = property(lambda self: CSSRule._typestrings[self.type],
doc="Name of this rules type.")
doc="Descriptive name of this rule's type.")
wellformed = property(lambda self: False,
doc=u"If the rule is wellformed.")
+7 -19
View File
@@ -1,16 +1,12 @@
"""
CSSRuleList implements DOM Level 2 CSS CSSRuleList.
Partly also
* http://dev.w3.org/csswg/cssom/#the-cssrulelist
"""CSSRuleList implements DOM Level 2 CSS CSSRuleList.
Partly also http://dev.w3.org/csswg/cssom/#the-cssrulelist
"""
__all__ = ['CSSRuleList']
__docformat__ = 'restructuredtext'
__version__ = '$Id: cssrulelist.py 1116 2008-03-05 13:52:23Z cthedot $'
__version__ = '$Id: cssrulelist.py 1641 2009-01-13 21:05:37Z cthedot $'
class CSSRuleList(list):
"""
The CSSRuleList object represents an (ordered) list of statements.
"""The CSSRuleList object represents an (ordered) list of statements.
The items in the CSSRuleList are accessible via an integral index,
starting from 0.
@@ -21,28 +17,20 @@ class CSSRuleList(list):
class if so desired.
E.g. CSSStyleSheet adds ``append`` which is not available in a simple
instance of this class!
Properties
==========
length: of type unsigned long, readonly
The number of CSSRules in the list. The range of valid child rule
indices is 0 to length-1 inclusive.
"""
def __init__(self, *ignored):
"nothing is set as this must also be defined later"
"Nothing is set as this must also be defined later."
pass
def __notimplemented(self, *ignored):
"no direct setting possible"
"Implemented in class using a CSSRuleList only."
raise NotImplementedError(
'Must be implemented by class using an instance of this class.')
append = extend = __setitem__ = __setslice__ = __notimplemented
def item(self, index):
"""
(DOM)
Used to retrieve a CSS rule by ordinal index. The order in this
"""(DOM) Retrieve a CSS rule by ordinal `index`. The order in this
collection represents the order of the rules in the CSS style
sheet. If index is greater than or equal to the number of rules in
the list, this returns None.
+169 -200
View File
@@ -51,16 +51,15 @@ TODO:
"""
__all__ = ['CSSStyleDeclaration', 'Property']
__docformat__ = 'restructuredtext'
__version__ = '$Id: cssstyledeclaration.py 1284 2008-06-05 16:29:17Z cthedot $'
__version__ = '$Id: cssstyledeclaration.py 1658 2009-02-07 18:24:40Z cthedot $'
import xml.dom
import cssutils
from cssproperties import CSS2Properties
from property import Property
import cssutils
import xml.dom
class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
"""
The CSSStyleDeclaration class represents a single CSS declaration
"""The CSSStyleDeclaration class represents a single CSS declaration
block. This class may be used to determine the style properties
currently set in a block or to set style properties explicitly
within the block.
@@ -76,24 +75,6 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
Additionally the CSS2Properties interface is implemented.
Properties
==========
cssText
The parsable textual representation of the declaration block
(excluding the surrounding curly braces). Setting this attribute
will result in the parsing of the new value and resetting of the
properties in the declaration block. It also allows the insertion
of additional properties and their values into the block.
length: of type unsigned long, readonly
The number of properties that have been explicitly set in this
declaration block. The range of valid indices is 0 to length-1
inclusive.
parentRule: of type CSSRule, readonly
The CSS rule that contains this declaration block or None if this
CSSStyleDeclaration is not attached to a CSSRule.
seq: a list (cssutils)
All parts of this style declaration including CSSComments
$css2propertyname
All properties defined in the CSS2Properties class are available
as direct properties of CSSStyleDeclaration with their respective
@@ -106,33 +87,32 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
>>> print style.color
green
>>> del style.color
>>> print style.color # print empty string
>>> print style.color
<BLANKLINE>
Format
======
[Property: Value Priority?;]* [Property: Value Priority?]?
Format::
[Property: Value Priority?;]* [Property: Value Priority?]?
"""
def __init__(self, cssText=u'', parentRule=None, readonly=False):
"""
cssText
:param cssText:
Shortcut, sets CSSStyleDeclaration.cssText
parentRule
:param parentRule:
The CSS rule that contains this declaration block or
None if this CSSStyleDeclaration is not attached to a CSSRule.
readonly
:param readonly:
defaults to False
"""
super(CSSStyleDeclaration, self).__init__()
self._parentRule = parentRule
#self._seq = self._tempSeq()
self.cssText = cssText
self._readonly = readonly
def __contains__(self, nameOrProperty):
"""
checks if a property (or a property with given name is in style
"""Check if a property (or a property with given name) is in style.
name
:param name:
a string or Property, uses normalized name and not literalname
"""
if isinstance(nameOrProperty, Property):
@@ -142,47 +122,12 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
return name in self.__nnames()
def __iter__(self):
"""
iterator of set Property objects with different normalized names.
"""
"""Iterator of set Property objects with different normalized names."""
def properties():
for name in self.__nnames():
yield self.getProperty(name)
return properties()
def __setattr__(self, n, v):
"""
Prevent setting of unknown properties on CSSStyleDeclaration
which would not work anyway. For these
``CSSStyleDeclaration.setProperty`` MUST be called explicitly!
TODO:
implementation of known is not really nice, any alternative?
"""
known = ['_tokenizer', '_log', '_ttypes',
'_seq', 'seq', 'parentRule', '_parentRule', 'cssText',
'valid', 'wellformed',
'_readonly']
known.extend(CSS2Properties._properties)
if n in known:
super(CSSStyleDeclaration, self).__setattr__(n, v)
else:
raise AttributeError(
'Unknown CSS Property, ``CSSStyleDeclaration.setProperty("%s", ...)`` MUST be used.'
% n)
def __nnames(self):
"""
returns iterator for all different names in order as set
if names are set twice the last one is used (double reverse!)
"""
names = []
for item in reversed(self.seq):
val = item.value
if isinstance(val, Property) and not val.name in names:
names.append(val.name)
return reversed(names)
def __getitem__(self, CSSName):
"""Retrieve the value of property ``CSSName`` from this declaration.
@@ -211,11 +156,49 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
"""
return self.removeProperty(CSSName)
def __setattr__(self, n, v):
"""Prevent setting of unknown properties on CSSStyleDeclaration
which would not work anyway. For these
``CSSStyleDeclaration.setProperty`` MUST be called explicitly!
TODO:
implementation of known is not really nice, any alternative?
"""
known = ['_tokenizer', '_log', '_ttypes',
'_seq', 'seq', 'parentRule', '_parentRule', 'cssText',
'valid', 'wellformed',
'_readonly', '_profiles']
known.extend(CSS2Properties._properties)
if n in known:
super(CSSStyleDeclaration, self).__setattr__(n, v)
else:
raise AttributeError(
'Unknown CSS Property, ``CSSStyleDeclaration.setProperty("%s", ...)`` MUST be used.'
% n)
def __repr__(self):
return "cssutils.css.%s(cssText=%r)" % (
self.__class__.__name__, self.getCssText(separator=u' '))
def __str__(self):
return "<cssutils.css.%s object length=%r (all: %r) at 0x%x>" % (
self.__class__.__name__, self.length,
len(self.getProperties(all=True)), id(self))
def __nnames(self):
"""Return iterator for all different names in order as set
if names are set twice the last one is used (double reverse!)
"""
names = []
for item in reversed(self.seq):
val = item.value
if isinstance(val, Property) and not val.name in names:
names.append(val.name)
return reversed(names)
# overwritten accessor functions for CSS2Properties' properties
def _getP(self, CSSName):
"""
(DOM CSS2Properties)
Overwritten here and effectively the same as
"""(DOM CSS2Properties) Overwritten here and effectively the same as
``self.getPropertyValue(CSSname)``.
Parameter is in CSSname format ('font-style'), see CSS2Properties.
@@ -229,9 +212,7 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
return self.getPropertyValue(CSSName)
def _setP(self, CSSName, value):
"""
(DOM CSS2Properties)
Overwritten here and effectively the same as
"""(DOM CSS2Properties) Overwritten here and effectively the same as
``self.setProperty(CSSname, value)``.
Only known CSS2Properties may be set this way, otherwise an
@@ -247,44 +228,40 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
>>> style.fontStyle = 'italic'
>>> # or
>>> style.setProperty('font-style', 'italic', '!important')
"""
self.setProperty(CSSName, value)
# TODO: Shorthand ones
def _delP(self, CSSName):
"""
(cssutils only)
Overwritten here and effectively the same as
"""(cssutils only) Overwritten here and effectively the same as
``self.removeProperty(CSSname)``.
Example::
>>> style = CSSStyleDeclaration(cssText='font-style:italic;')
>>> del style.fontStyle
>>> print style.fontStyle # prints u''
>>> print style.fontStyle
<BLANKLINE>
"""
self.removeProperty(CSSName)
def _getCssText(self):
"""
returns serialized property cssText
"""
"""Return serialized property cssText."""
return cssutils.ser.do_css_CSSStyleDeclaration(self)
def _setCssText(self, cssText):
"""
Setting this attribute will result in the parsing of the new value
"""Setting this attribute will result in the parsing of the new value
and resetting of all the properties in the declaration block
including the removal or addition of properties.
DOMException on setting
- NO_MODIFICATION_ALLOWED_ERR: (self)
Raised if this declaration is readonly or a property is readonly.
- SYNTAX_ERR: (self)
Raised if the specified CSS string value has a syntax error and
is unparsable.
:exceptions:
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if this declaration is readonly or a property is readonly.
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified CSS string value has a syntax error and
is unparsable.
"""
self._checkReadonly()
tokenizer = self._tokenize2(cssText)
@@ -336,11 +313,12 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
def getCssText(self, separator=None):
"""
returns serialized property cssText, each property separated by
given ``separator`` which may e.g. be u'' to be able to use
cssText directly in an HTML style attribute. ";" is always part of
each property (except the last one) and can **not** be set with
separator!
:returns:
serialized property cssText, each property separated by
given `separator` which may e.g. be ``u''`` to be able to use
cssText directly in an HTML style attribute. ``;`` is part of
each property (except the last one) and **cannot** be set with
separator!
"""
return cssutils.ser.do_css_CSSStyleDeclaration(self, separator)
@@ -351,25 +329,27 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
self._parentRule = parentRule
parentRule = property(_getParentRule, _setParentRule,
doc="(DOM) The CSS rule that contains this declaration block or\
None if this CSSStyleDeclaration is not attached to a CSSRule.")
doc="(DOM) The CSS rule that contains this declaration block or "
"None if this CSSStyleDeclaration is not attached to a CSSRule.")
def getProperties(self, name=None, all=False):
"""
Returns a list of Property objects set in this declaration.
:param name:
optional `name` of properties which are requested.
Only properties with this **always normalized** `name` are returned.
If `name` is ``None`` all properties are returned (at least one for
each set name depending on parameter `all`).
:param all:
if ``False`` (DEFAULT) only the effective properties are returned.
If name is given a list with only one property is returned.
name
optional name of properties which are requested (a filter).
Only properties with this **always normalized** name are returned.
all=False
if False (DEFAULT) only the effective properties (the ones set
last) are returned. If name is given a list with only one property
is returned.
if True all properties including properties set multiple times with
different values or priorities for different UAs are returned.
if ``True`` all properties including properties set multiple times
with different values or priorities for different UAs are returned.
The order of the properties is fully kept as in the original
stylesheet.
:returns:
a list of :class:`~cssutils.css.Property` objects set in
this declaration.
"""
if name and not all:
# single prop but list
@@ -394,16 +374,16 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
def getProperty(self, name, normalize=True):
"""
Returns the effective Property object.
name
:param name:
of the CSS property, always lowercase (even if not normalized)
normalize
if True (DEFAULT) name will be normalized (lowercase, no simple
:param normalize:
if ``True`` (DEFAULT) name will be normalized (lowercase, no simple
escapes) so "color", "COLOR" or "C\olor" will all be equivalent
If False may return **NOT** the effective value but the effective
for the unnormalized name.
If ``False`` may return **NOT** the effective value but the
effective for the unnormalized name.
:returns:
the effective :class:`~cssutils.css.Property` object.
"""
nname = self._normalize(name)
found = None
@@ -419,17 +399,17 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
def getPropertyCSSValue(self, name, normalize=True):
"""
Returns CSSValue, the value of the effective property if it has been
explicitly set for this declaration block.
name
:param name:
of the CSS property, always lowercase (even if not normalized)
normalize
if True (DEFAULT) name will be normalized (lowercase, no simple
:param normalize:
if ``True`` (DEFAULT) name will be normalized (lowercase, no simple
escapes) so "color", "COLOR" or "C\olor" will all be equivalent
If False may return **NOT** the effective value but the effective
If ``False`` may return **NOT** the effective value but the effective
for the unnormalized name.
:returns:
:class:`~cssutils.css.CSSValue`, the value of the effective
property if it has been explicitly set for this declaration block.
(DOM)
Used to retrieve the object representation of the value of a CSS
@@ -461,18 +441,18 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
def getPropertyValue(self, name, normalize=True):
"""
Returns the value of the effective property if it has been explicitly
set for this declaration block. Returns the empty string if the
property has not been set.
name
:param name:
of the CSS property, always lowercase (even if not normalized)
normalize
if True (DEFAULT) name will be normalized (lowercase, no simple
:param normalize:
if ``True`` (DEFAULT) name will be normalized (lowercase, no simple
escapes) so "color", "COLOR" or "C\olor" will all be equivalent
If False may return **NOT** the effective value but the effective
for the unnormalized name.
If ``False`` may return **NOT** the effective value but the
effective for the unnormalized name.
:returns:
the value of the effective property if it has been explicitly set
for this declaration block. Returns the empty string if the
property has not been set.
"""
p = self.getProperty(name, normalize)
if p:
@@ -482,18 +462,18 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
def getPropertyPriority(self, name, normalize=True):
"""
Returns the priority of the effective CSS property (e.g. the
"important" qualifier) if the property has been explicitly set in
this declaration block. The empty string if none exists.
name
:param name:
of the CSS property, always lowercase (even if not normalized)
normalize
if True (DEFAULT) name will be normalized (lowercase, no simple
:param normalize:
if ``True`` (DEFAULT) name will be normalized (lowercase, no simple
escapes) so "color", "COLOR" or "C\olor" will all be equivalent
If False may return **NOT** the effective value but the effective
for the unnormalized name.
If ``False`` may return **NOT** the effective value but the
effective for the unnormalized name.
:returns:
the priority of the effective CSS property (e.g. the
"important" qualifier) if the property has been explicitly set in
this declaration block. The empty string if none exists.
"""
p = self.getProperty(name, normalize)
if p:
@@ -507,28 +487,28 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
Used to remove a CSS property if it has been explicitly set within
this declaration block.
Returns the value of the property if it has been explicitly set for
this declaration block. Returns the empty string if the property
has not been set or the property name does not correspond to a
known CSS property
name
:param name:
of the CSS property
normalize
if True (DEFAULT) name will be normalized (lowercase, no simple
:param normalize:
if ``True`` (DEFAULT) name will be normalized (lowercase, no simple
escapes) so "color", "COLOR" or "C\olor" will all be equivalent.
The effective Property value is returned and *all* Properties
with ``Property.name == name`` are removed.
If False may return **NOT** the effective value but the effective
for the unnormalized ``name`` only. Also only the Properties with
the literal name ``name`` are removed.
If ``False`` may return **NOT** the effective value but the
effective for the unnormalized `name` only. Also only the
Properties with the literal name `name` are removed.
:returns:
the value of the property if it has been explicitly set for
this declaration block. Returns the empty string if the property
has not been set or the property name does not correspond to a
known CSS property
raises DOMException
- NO_MODIFICATION_ALLOWED_ERR: (self)
Raised if this declaration is readonly or the property is
readonly.
:exceptions:
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if this declaration is readonly or the property is
readonly.
"""
self._checkReadonly()
r = self.getPropertyValue(name, normalize=normalize)
@@ -548,41 +528,40 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
return r
def setProperty(self, name, value=None, priority=u'', normalize=True):
"""
(DOM)
Used to set a property value and priority within this declaration
"""(DOM) Set a property value and priority within this declaration
block.
name
:param name:
of the CSS property to set (in W3C DOM the parameter is called
"propertyName"), always lowercase (even if not normalized)
If a property with this name is present it will be reset
If a property with this `name` is present it will be reset.
cssutils also allowed name to be a Property object, all other
cssutils also allowed `name` to be a
:class:`~cssutils.css.Property` object, all other
parameter are ignored in this case
value
the new value of the property, omit if name is already a Property
priority
the optional priority of the property (e.g. "important")
normalize
if True (DEFAULT) name will be normalized (lowercase, no simple
:param value:
the new value of the property, ignored if `name` is a Property.
:param priority:
the optional priority of the property (e.g. "important"),
ignored if `name` is a Property.
:param normalize:
if True (DEFAULT) `name` will be normalized (lowercase, no simple
escapes) so "color", "COLOR" or "C\olor" will all be equivalent
DOMException on setting
- SYNTAX_ERR: (self)
Raised if the specified value has a syntax error and is
unparsable.
- NO_MODIFICATION_ALLOWED_ERR: (self)
Raised if this declaration is readonly or the property is
readonly.
:exceptions:
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified value has a syntax error and is
unparsable.
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if this declaration is readonly or the property is
readonly.
"""
self._checkReadonly()
if isinstance(name, Property):
newp = name
newp = name
name = newp.literalname
else:
newp = Property(name, value, priority)
@@ -607,27 +586,26 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
self.seq._readonly = True
def item(self, index):
"""
(DOM)
Used to retrieve the properties that have been explicitly set in
"""(DOM) Retrieve the properties that have been explicitly set in
this declaration block. The order of the properties retrieved using
this method does not have to be the order in which they were set.
This method can be used to iterate over all properties in this
declaration block.
index
:param index:
of the property to retrieve, negative values behave like
negative indexes on Python lists, so -1 is the last element
returns the name of the property at this ordinal position. The
empty string if no property exists at this position.
:returns:
the name of the property at this ordinal position. The
empty string if no property exists at this position.
ATTENTION:
Only properties with a different name are counted. If two
**ATTENTION:**
Only properties with different names are counted. If two
properties with the same name are present in this declaration
only the effective one is included.
``item()`` and ``length`` work on the same set here.
:meth:`item` and :attr:`length` work on the same set here.
"""
names = list(self.__nnames())
try:
@@ -636,16 +614,7 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
return u''
length = property(lambda self: len(self.__nnames()),
doc="(DOM) The number of distinct properties that have been explicitly\
in this declaration block. The range of valid indices is 0 to\
length-1 inclusive. These are properties with a different ``name``\
only. ``item()`` and ``length`` work on the same set here.")
def __repr__(self):
return "cssutils.css.%s(cssText=%r)" % (
self.__class__.__name__, self.getCssText(separator=u' '))
def __str__(self):
return "<cssutils.css.%s object length=%r (all: %r) at 0x%x>" % (
self.__class__.__name__, self.length,
len(self.getProperties(all=True)), id(self))
doc="(DOM) The number of distinct properties that have been explicitly "
"in this declaration block. The range of valid indices is 0 to "
"length-1 inclusive. These are properties with a different ``name`` "
"only. :meth:`item` and :attr:`length` work on the same set here.")
+46 -67
View File
@@ -1,49 +1,25 @@
"""CSSStyleRule implements DOM Level 2 CSS CSSStyleRule.
"""
"""CSSStyleRule implements DOM Level 2 CSS CSSStyleRule."""
__all__ = ['CSSStyleRule']
__docformat__ = 'restructuredtext'
__version__ = '$Id: cssstylerule.py 1284 2008-06-05 16:29:17Z cthedot $'
__version__ = '$Id: cssstylerule.py 1638 2009-01-13 20:39:33Z cthedot $'
import xml.dom
from cssstyledeclaration import CSSStyleDeclaration
from selectorlist import SelectorList
import cssrule
import cssutils
from selectorlist import SelectorList
from cssstyledeclaration import CSSStyleDeclaration
import xml.dom
class CSSStyleRule(cssrule.CSSRule):
"""
The CSSStyleRule object represents a ruleset specified (if any) in a CSS
"""The CSSStyleRule object represents a ruleset specified (if any) in a CSS
style sheet. It provides access to a declaration block as well as to the
associated group of selectors.
Properties
==========
selectorList: of type SelectorList (cssutils only)
A list of all Selector elements for the rule set.
selectorText: of type DOMString
The textual representation of the selector for the rule set. The
implementation may have stripped out insignificant whitespace while
parsing the selector.
style: of type CSSStyleDeclaration, (DOM)
The declaration-block of this rule set.
type
the type of this rule, constant cssutils.CSSRule.STYLE_RULE
inherited properties:
- cssText
- parentRule
- parentStyleSheet
Format
======
ruleset::
Format::
: selector [ COMMA S* selector ]*
LBRACE S* declaration [ ';' S* declaration ]* '}' S*
;
"""
type = property(lambda self: cssrule.CSSRule.STYLE_RULE)
def __init__(self, selectorText=None, style=None, parentRule=None,
parentStyleSheet=None, readonly=False):
"""
@@ -67,31 +43,41 @@ class CSSStyleRule(cssrule.CSSRule):
self._readonly = readonly
def __repr__(self):
if self._namespaces:
st = (self.selectorText, self._namespaces)
else:
st = self.selectorText
return "cssutils.css.%s(selectorText=%r, style=%r)" % (
self.__class__.__name__, st, self.style.cssText)
def __str__(self):
return "<cssutils.css.%s object selector=%r style=%r _namespaces=%r at 0x%x>" % (
self.__class__.__name__, self.selectorText, self.style.cssText,
self._namespaces, id(self))
def _getCssText(self):
"""
returns serialized property cssText
"""
"""Return serialized property cssText."""
return cssutils.ser.do_CSSStyleRule(self)
def _setCssText(self, cssText):
"""
:param cssText:
a parseable string or a tuple of (cssText, dict-of-namespaces)
:Exceptions:
- `NAMESPACE_ERR`: (Selector)
:exceptions:
- :exc:`~xml.dom.NamespaceErr`:
Raised if the specified selector uses an unknown namespace
prefix.
- `SYNTAX_ERR`: (self, StyleDeclaration, etc)
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified CSS string value has a syntax error and
is unparsable.
- `INVALID_MODIFICATION_ERR`: (self)
- :exc:`~xml.dom.InvalidModificationErr`:
Raised if the specified CSS string value represents a different
type of rule than the current one.
- `HIERARCHY_REQUEST_ERR`: (CSSStylesheet)
- :exc:`~xml.dom.HierarchyRequestErr`:
Raised if the rule cannot be inserted at this point in the
style sheet.
- `NO_MODIFICATION_ALLOWED_ERR`: (CSSRule)
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if the rule is readonly.
"""
super(CSSStyleRule, self)._setCssText(cssText)
@@ -160,20 +146,21 @@ class CSSStyleRule(cssrule.CSSRule):
self.style = newstyle
cssText = property(_getCssText, _setCssText,
doc="(DOM) The parsable textual representation of the rule.")
doc="(DOM) The parsable textual representation of this rule.")
def __getNamespaces(self):
"uses children namespaces if not attached to a sheet, else the sheet's ones"
"Uses children namespaces if not attached to a sheet, else the sheet's ones."
try:
return self.parentStyleSheet.namespaces
except AttributeError:
return self.selectorList._namespaces
_namespaces = property(__getNamespaces, doc=u"""if this Rule is
attached to a CSSStyleSheet the namespaces of that sheet are mirrored
here. While the Rule is not attached the namespaces of selectorList
are used.""")
_namespaces = property(__getNamespaces,
doc="If this Rule is attached to a CSSStyleSheet "
"the namespaces of that sheet are mirrored "
"here. While the Rule is not attached the "
"namespaces of selectorList are used.""")
def _setSelectorList(self, selectorList):
"""
@@ -190,16 +177,17 @@ class CSSStyleRule(cssrule.CSSRule):
"""
wrapper for cssutils SelectorList object
:param selectorText: of type string, might also be a comma separated list
:param selectorText:
of type string, might also be a comma separated list
of selectors
:Exceptions:
- `NAMESPACE_ERR`: (Selector)
:exceptions:
- :exc:`~xml.dom.NamespaceErr`:
Raised if the specified selector uses an unknown namespace
prefix.
- `SYNTAX_ERR`: (SelectorList, Selector)
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified CSS string value has a syntax error
and is unparsable.
- `NO_MODIFICATION_ALLOWED_ERR`: (self)
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if this rule is readonly.
"""
self._checkReadonly()
@@ -207,8 +195,8 @@ class CSSStyleRule(cssrule.CSSRule):
selectorText = property(lambda self: self._selectorList.selectorText,
_setSelectorText,
doc="""(DOM) The textual representation of the selector for the
rule set.""")
doc="(DOM) The textual representation of the "
"selector for the rule set.")
def _setStyle(self, style):
"""
@@ -224,19 +212,10 @@ class CSSStyleRule(cssrule.CSSRule):
self._style._seq = style._seq
style = property(lambda self: self._style, _setStyle,
doc="(DOM) The declaration-block of this rule set.")
doc="(DOM) The declaration-block of this rule set.")
type = property(lambda self: self.STYLE_RULE,
doc="The type of this rule, as defined by a CSSRule "
"type constant.")
wellformed = property(lambda self: self.selectorList.wellformed)
def __repr__(self):
if self._namespaces:
st = (self.selectorText, self._namespaces)
else:
st = self.selectorText
return "cssutils.css.%s(selectorText=%r, style=%r)" % (
self.__class__.__name__, st, self.style.cssText)
def __str__(self):
return "<cssutils.css.%s object selector=%r style=%r _namespaces=%r at 0x%x>" % (
self.__class__.__name__, self.selectorText, self.style.cssText,
self._namespaces, id(self))
+95 -138
View File
@@ -1,5 +1,4 @@
"""
CSSStyleSheet implements DOM Level 2 CSS CSSStyleSheet.
"""CSSStyleSheet implements DOM Level 2 CSS CSSStyleSheet.
Partly also:
- http://dev.w3.org/csswg/cssom/#the-cssstylesheet
@@ -10,53 +9,32 @@ TODO:
"""
__all__ = ['CSSStyleSheet']
__docformat__ = 'restructuredtext'
__version__ = '$Id: cssstylesheet.py 1429 2008-08-11 19:01:52Z cthedot $'
__version__ = '$Id: cssstylesheet.py 1641 2009-01-13 21:05:37Z cthedot $'
import xml.dom
import cssutils.stylesheets
from cssutils.util import _Namespaces, _SimpleNamespaces, _readUrl
from cssutils.helper import Deprecated
from cssutils.util import _Namespaces, _SimpleNamespaces, _readUrl
import cssutils.stylesheets
import xml.dom
class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
"""
The CSSStyleSheet interface represents a CSS style sheet.
"""CSSStyleSheet represents a CSS style sheet.
Properties
==========
CSSOM
-----
cssRules
of type CSSRuleList, (DOM readonly)
encoding
reflects the encoding of an @charset rule or 'utf-8' (default)
if set to ``None``
ownerRule
of type CSSRule, readonly. If this sheet is imported this is a ref
to the @import rule that imports it.
Format::
stylesheet
: [ CHARSET_SYM S* STRING S* ';' ]?
[S|CDO|CDC]* [ import [S|CDO|CDC]* ]*
[ namespace [S|CDO|CDC]* ]* # according to @namespace WD
[ [ ruleset | media | page ] [S|CDO|CDC]* ]*
Inherits properties from stylesheet.StyleSheet
cssutils
--------
cssText: string
a textual representation of the stylesheet
namespaces
reflects set @namespace rules of this rule.
A dict of {prefix: namespaceURI} mapping.
Format
======
stylesheet
: [ CHARSET_SYM S* STRING S* ';' ]?
[S|CDO|CDC]* [ import [S|CDO|CDC]* ]*
[ namespace [S|CDO|CDC]* ]* # according to @namespace WD
[ [ ruleset | media | page ] [S|CDO|CDC]* ]*
``cssRules``
All Rules in this style sheet, a :class:`~cssutils.css.CSSRuleList`.
"""
def __init__(self, href=None, media=None, title=u'', disabled=None,
ownerNode=None, parentStyleSheet=None, readonly=False,
ownerRule=None):
"""
init parameters are the same as for stylesheets.StyleSheet
For parameters see :class:`~cssutils.stylesheets.StyleSheet`
"""
super(CSSStyleSheet, self).__init__(
'text/css', href, media, title, disabled,
@@ -74,12 +52,32 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
self._fetcher = None
def __iter__(self):
"generator which iterates over cssRules."
"Generator which iterates over cssRules."
for rule in self.cssRules:
yield rule
def __repr__(self):
if self.media:
mediaText = self.media.mediaText
else:
mediaText = None
return "cssutils.css.%s(href=%r, media=%r, title=%r)" % (
self.__class__.__name__,
self.href, mediaText, self.title)
def __str__(self):
if self.media:
mediaText = self.media.mediaText
else:
mediaText = None
return "<cssutils.css.%s object encoding=%r href=%r "\
"media=%r title=%r namespaces=%r at 0x%x>" % (
self.__class__.__name__, self.encoding, self.href,
mediaText, self.title, self.namespaces.namespaces,
id(self))
def _cleanNamespaces(self):
"removes all namespace rules with same namespaceURI but last one set"
"Remove all namespace rules with same namespaceURI but last one set."
rules = self.cssRules
namespaceitems = self.namespaces.items()
i = 0
@@ -92,7 +90,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
i += 1
def _getUsedURIs(self):
"returns set of URIs used in the sheet"
"Return set of URIs used in the sheet."
useduris = set()
for r1 in self:
if r1.STYLE_RULE == r1.type:
@@ -104,21 +102,20 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
return useduris
def _getCssText(self):
"Textual representation of the stylesheet (a byte string)."
return cssutils.ser.do_CSSStyleSheet(self)
def _setCssText(self, cssText):
"""
(cssutils)
Parses ``cssText`` and overwrites the whole stylesheet.
"""Parse `cssText` and overwrites the whole stylesheet.
:param cssText:
a parseable string or a tuple of (cssText, dict-of-namespaces)
:Exceptions:
- `NAMESPACE_ERR`:
:exceptions:
- :exc:`~xml.dom.NamespaceErr`:
If a namespace prefix is found which is not declared.
- `NO_MODIFICATION_ALLOWED_ERR`: (self)
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if the rule is readonly.
- `SYNTAX_ERR`:
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified CSS string value has a syntax error and
is unparsable.
"""
@@ -269,10 +266,10 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
self._cleanNamespaces()
cssText = property(_getCssText, _setCssText,
"(cssutils) a textual representation of the stylesheet")
"Textual representation of the stylesheet (a byte string)")
def _resolveImport(self, url):
"""Read (encoding, enctype, decodedContent) from ``url`` for @import
"""Read (encoding, enctype, decodedContent) from `url` for @import
sheets."""
try:
# only available during parse of a complete sheet
@@ -289,12 +286,12 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
overrideEncoding=self.__encodingOverride,
parentEncoding=selfAsParentEncoding)
def _setCssTextWithEncodingOverride(self, cssText, encodingOverride=None,
def _setCssTextWithEncodingOverride(self, cssText, encodingOverride=None,
encoding=None):
"""Set cssText but use ``encodingOverride`` to overwrite detected
"""Set `cssText` but use `encodingOverride` to overwrite detected
encoding. This is used by parse and @import during setting of cssText.
If ``encoding`` is given use this but do not save it as encodingOverride"""
If `encoding` is given use this but do not save it as `encodingOverride`."""
if encodingOverride:
# encoding during resolving of @import
self.__encodingOverride = encodingOverride
@@ -312,14 +309,14 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
self.encoding = encoding
def _setFetcher(self, fetcher=None):
"""sets @import URL loader, if None the default is used"""
"""Set @import URL loader, if None the default is used."""
self._fetcher = fetcher
def _setEncoding(self, encoding):
"""
sets encoding of charset rule if present or inserts new charsetrule
with given encoding. If encoding if None removes charsetrule if
present.
"""Set `encoding` of charset rule if present in sheet or insert a new
:class:`~cssutils.css.CSSCharsetRule` with given `encoding`.
If `encoding` is None removes charsetrule if present resulting in
default encoding of utf-8.
"""
try:
rule = self.cssRules[0]
@@ -334,41 +331,41 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
self.insertRule(cssutils.css.CSSCharsetRule(encoding=encoding), 0)
def _getEncoding(self):
"return encoding if @charset rule if given or default of 'utf-8'"
"""Encoding set in :class:`~cssutils.css.CSSCharsetRule` or if ``None``
resulting in default ``utf-8`` encoding being used."""
try:
return self.cssRules[0].encoding
except (IndexError, AttributeError):
return 'utf-8'
encoding = property(_getEncoding, _setEncoding,
"(cssutils) reflects the encoding of an @charset rule or 'UTF-8' (default) if set to ``None``")
"(cssutils) Reflect encoding of an @charset rule or 'utf-8' "
"(default) if set to ``None``")
namespaces = property(lambda self: self._namespaces,
doc="Namespaces used in this CSSStyleSheet.")
doc="All Namespaces used in this CSSStyleSheet.")
def add(self, rule):
"""
Adds rule to stylesheet at appropriate position.
Same as ``sheet.insertRule(rule, inOrder=True)``.
"""Add `rule` to style sheet at appropriate position.
Same as ``insertRule(rule, inOrder=True)``.
"""
return self.insertRule(rule, index=None, inOrder=True)
def deleteRule(self, index):
"""
Used to delete a rule from the style sheet.
"""Delete rule at `index` from the style sheet.
:param index:
of the rule to remove in the StyleSheet's rule list. For an
index < 0 **no** INDEX_SIZE_ERR is raised but rules for
normal Python lists are used. E.g. ``deleteRule(-1)`` removes
the last rule in cssRules.
:Exceptions:
- `INDEX_SIZE_ERR`: (self)
`index` < 0 **no** :exc:`~xml.dom.IndexSizeErr` is raised but
rules for normal Python lists are used. E.g. ``deleteRule(-1)``
removes the last rule in cssRules.
:exceptions:
- :exc:`~xml.dom.IndexSizeErr`:
Raised if the specified index does not correspond to a rule in
the style sheet's rule list.
- `NAMESPACE_ERR`: (self)
- :exc:`~xml.dom.NamespaceErr`:
Raised if removing this rule would result in an invalid StyleSheet
- `NO_MODIFICATION_ALLOWED_ERR`: (self)
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if this style sheet is readonly.
"""
self._checkReadonly()
@@ -398,32 +395,31 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
Used to insert a new rule into the style sheet. The new rule now
becomes part of the cascade.
:Parameters:
rule
a parsable DOMString, in cssutils also a CSSRule or a
CSSRuleList
index
of the rule before the new rule will be inserted.
If the specified index is equal to the length of the
StyleSheet's rule collection, the rule will be added to the end
of the style sheet.
If index is not given or None rule will be appended to rule
list.
inOrder
if True the rule will be put to a proper location while
ignoring index but without raising HIERARCHY_REQUEST_ERR.
The resulting index is returned nevertheless
:returns: the index within the stylesheet's rule collection
:param rule:
a parsable DOMString, in cssutils also a
:class:`~cssutils.css.CSSRule` or :class:`~cssutils.css.CSSRuleList`
:param index:
of the rule before the new rule will be inserted.
If the specified `index` is equal to the length of the
StyleSheet's rule collection, the rule will be added to the end
of the style sheet.
If `index` is not given or ``None`` rule will be appended to rule
list.
:param inOrder:
if ``True`` the rule will be put to a proper location while
ignoring `index` and without raising :exc:`~xml.dom.HierarchyRequestErr`.
The resulting index is returned nevertheless.
:returns: The index within the style sheet's rule collection
:Exceptions:
- `HIERARCHY_REQUEST_ERR`: (self)
Raised if the rule cannot be inserted at the specified index
- :exc:`~xml.dom.HierarchyRequestErr`:
Raised if the rule cannot be inserted at the specified `index`
e.g. if an @import rule is inserted after a standard rule set
or other at-rule.
- `INDEX_SIZE_ERR`: (self)
Raised if the specified index is not a valid insertion point.
- `NO_MODIFICATION_ALLOWED_ERR`: (self)
- :exc:`~xml.dom.IndexSizeErr`:
Raised if the specified `index` is not a valid insertion point.
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if this style sheet is readonly.
- `SYNTAX_ERR`: (rule)
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified rule has a syntax error and is
unparsable.
"""
@@ -618,57 +614,18 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
return index
ownerRule = property(lambda self: self._ownerRule,
doc="(DOM attribute) NOT IMPLEMENTED YET")
@Deprecated('Use cssutils.replaceUrls(sheet, replacer) instead.')
def replaceUrls(self, replacer):
"""
**EXPERIMENTAL**
Utility method to replace all ``url(urlstring)`` values in
``CSSImportRules`` and ``CSSStyleDeclaration`` objects (properties).
``replacer`` must be a function which is called with a single
argument ``urlstring`` which is the current value of url()
excluding ``url(`` and ``)``. It still may have surrounding
single or double quotes though.
"""
cssutils.replaceUrls(self, replacer)
doc="A ref to an @import rule if it is imported, else ``None``.")
def setSerializer(self, cssserializer):
"""
Sets the global Serializer used for output of all stylesheet
output.
"""
"""Set the cssutils global Serializer used for all output."""
if isinstance(cssserializer, cssutils.CSSSerializer):
cssutils.ser = cssserializer
else:
raise ValueError(u'Serializer must be an instance of cssutils.CSSSerializer.')
def setSerializerPref(self, pref, value):
"""
Sets Preference of CSSSerializer used for output of this
stylesheet. See cssutils.serialize.Preferences for possible
"""Set a Preference of CSSSerializer used for output.
See :class:`cssutils.serialize.Preferences` for possible
preferences to be set.
"""
cssutils.ser.prefs.__setattr__(pref, value)
def __repr__(self):
if self.media:
mediaText = self.media.mediaText
else:
mediaText = None
return "cssutils.css.%s(href=%r, media=%r, title=%r)" % (
self.__class__.__name__,
self.href, mediaText, self.title)
def __str__(self):
if self.media:
mediaText = self.media.mediaText
else:
mediaText = None
return "<cssutils.css.%s object encoding=%r href=%r "\
"media=%r title=%r namespaces=%r at 0x%x>" % (
self.__class__.__name__, self.encoding, self.href,
mediaText, self.title, self.namespaces.namespaces,
id(self))
+33 -48
View File
@@ -1,44 +1,25 @@
"""CSSUnknownRule implements DOM Level 2 CSS CSSUnknownRule.
"""
"""CSSUnknownRule implements DOM Level 2 CSS CSSUnknownRule."""
__all__ = ['CSSUnknownRule']
__docformat__ = 'restructuredtext'
__version__ = '$Id: cssunknownrule.py 1170 2008-03-20 17:42:07Z cthedot $'
__version__ = '$Id: cssunknownrule.py 1638 2009-01-13 20:39:33Z cthedot $'
import xml.dom
import cssrule
import cssutils
import xml.dom
class CSSUnknownRule(cssrule.CSSRule):
"""
represents an at-rule not supported by this user agent.
Represents an at-rule not supported by this user agent, so in
effect all other at-rules not defined in cssutils.
Properties
==========
inherited from CSSRule
- cssText
- type
Format::
cssutils only
-------------
atkeyword
the literal keyword used
seq
All parts of this rule excluding @KEYWORD but including CSSComments
wellformed
if this Rule is wellformed, for Unknown rules if an atkeyword is set
at all
Format
======
unknownrule:
@xxx until ';' or block {...}
"""
type = property(lambda self: cssrule.CSSRule.UNKNOWN_RULE)
def __init__(self, cssText=u'', parentRule=None,
parentStyleSheet=None, readonly=False):
"""
cssText
:param cssText:
of type string
"""
super(CSSUnknownRule, self).__init__(parentRule=parentRule,
@@ -49,25 +30,32 @@ class CSSUnknownRule(cssrule.CSSRule):
self._readonly = readonly
def __repr__(self):
return "cssutils.css.%s(cssText=%r)" % (
self.__class__.__name__, self.cssText)
def __str__(self):
return "<cssutils.css.%s object cssText=%r at 0x%x>" % (
self.__class__.__name__, self.cssText, id(self))
def _getCssText(self):
""" returns serialized property cssText """
"""Return serialized property cssText."""
return cssutils.ser.do_CSSUnknownRule(self)
def _setCssText(self, cssText):
"""
DOMException on setting
- SYNTAX_ERR:
Raised if the specified CSS string value has a syntax error and
is unparsable.
- INVALID_MODIFICATION_ERR:
Raised if the specified CSS string value represents a different
type of rule than the current one.
- HIERARCHY_REQUEST_ERR: (never raised)
Raised if the rule cannot be inserted at this point in the
style sheet.
- NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
Raised if the rule is readonly.
:exceptions:
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified CSS string value has a syntax error and
is unparsable.
- :exc:`~xml.dom.InvalidModificationErr`:
Raised if the specified CSS string value represents a different
type of rule than the current one.
- :exc:`~xml.dom.HierarchyRequestErr`:
Raised if the rule cannot be inserted at this point in the
style sheet.
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if the rule is readonly.
"""
super(CSSUnknownRule, self)._setCssText(cssText)
tokenizer = self._tokenize2(cssText)
@@ -197,12 +185,9 @@ class CSSUnknownRule(cssrule.CSSRule):
cssText = property(fget=_getCssText, fset=_setCssText,
doc="(DOM) The parsable textual representation.")
wellformed = property(lambda self: bool(self.atkeyword))
type = property(lambda self: self.UNKNOWN_RULE,
doc="The type of this rule, as defined by a CSSRule "
"type constant.")
def __repr__(self):
return "cssutils.css.%s(cssText=%r)" % (
self.__class__.__name__, self.cssText)
def __str__(self):
return "<cssutils.css.%s object cssText=%r at 0x%x>" % (
self.__class__.__name__, self.cssText, id(self))
wellformed = property(lambda self: bool(self.atkeyword))
File diff suppressed because it is too large Load Diff
+128 -134
View File
@@ -1,55 +1,18 @@
"""Property is a single CSS property in a CSSStyleDeclaration
Internal use only, may be removed in the future!
"""
"""Property is a single CSS property in a CSSStyleDeclaration."""
__all__ = ['Property']
__docformat__ = 'restructuredtext'
__version__ = '$Id: property.py 1444 2008-08-31 18:45:35Z cthedot $'
__version__ = '$Id: property.py 1664 2009-02-07 22:47:09Z cthedot $'
import xml.dom
import cssutils
#import cssproperties
from cssutils.helper import Deprecated
from cssutils.profiles import profiles
from cssvalue import CSSValue
from cssutils.helper import Deprecated
import cssutils
import xml.dom
class Property(cssutils.util.Base):
"""
(cssutils) a CSS property in a StyleDeclaration of a CSSStyleRule
"""A CSS property in a StyleDeclaration of a CSSStyleRule (cssutils).
Properties
==========
cssText
a parsable textual representation of this property
name
normalized name of the property, e.g. "color" when name is "c\olor"
(since 0.9.5)
literalname (since 0.9.5)
original name of the property in the source CSS which is not normalized
e.g. "C\\OLor"
cssValue
the relevant CSSValue instance for this property
value
the string value of the property, same as cssValue.cssText
priority
of the property (currently only u"important" or None)
literalpriority
original priority of the property in the source CSS which is not
normalized e.g. "IM\portant"
seqs
combination of a list for seq of name, a CSSValue object, and
a list for seq of priority (empty or [!important] currently)
valid
if this Property is valid
wellformed
if this Property is syntactically ok
DEPRECATED normalname (since 0.9.5)
normalized name of the property, e.g. "color" when name is "c\olor"
Format
======
::
Format::
property = name
: IDENT S*
@@ -81,60 +44,67 @@ class Property(cssutils.util.Base):
;
"""
def __init__(self, name=None, value=None, priority=u'', _mediaQuery=False):
def __init__(self, name=None, value=None, priority=u'',
_mediaQuery=False, _parent=None):
"""
inits property
name
:param name:
a property name string (will be normalized)
value
:param value:
a property value string
priority
:param priority:
an optional priority string which currently must be u'',
u'!important' or u'important'
_mediaQuery boolean
if True value is optional as used by MediaQuery objects
:param _mediaQuery:
if ``True`` value is optional (used by MediaQuery)
:param _parent:
the parent object, normally a
:class:`cssutils.css.CSSStyleDeclaration`
"""
super(Property, self).__init__()
self.seqs = [[], None, []]
self.valid = False
self.wellformed = False
self._mediaQuery = _mediaQuery
self._parent = _parent
self._name = u''
self._literalname = u''
if name:
self.name = name
else:
self._name = u''
self._literalname = u''
self.__normalname = u'' # DEPRECATED
if value:
self.cssValue = value
else:
self.seqs[1] = CSSValue()
self._priority = u''
self._literalpriority = u''
if priority:
self.priority = priority
else:
self._priority = u''
self._literalpriority = u''
def __repr__(self):
return "cssutils.css.%s(name=%r, value=%r, priority=%r)" % (
self.__class__.__name__,
self.literalname, self.cssValue.cssText, self.priority)
def __str__(self):
return "<%s.%s object name=%r value=%r priority=%r valid=%r at 0x%x>" % (
self.__class__.__module__, self.__class__.__name__,
self.name, self.cssValue.cssText, self.priority,
self.valid, id(self))
def _getCssText(self):
"""
returns serialized property cssText
"""
"""Return serialized property cssText."""
return cssutils.ser.do_Property(self)
def _setCssText(self, cssText):
"""
DOMException on setting
- NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
Raised if the rule is readonly.
- SYNTAX_ERR: (self)
Raised if the specified CSS string value has a syntax error and
is unparsable.
:exceptions:
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified CSS string value has a syntax error and
is unparsable.
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if the rule is readonly.
"""
# check and prepare tokenlists for setting
tokenizer = self._tokenize2(cssText)
@@ -174,11 +144,14 @@ class Property(cssutils.util.Base):
self._log.error(u'Property: No property value found: %r.' %
self._valuestr(cssText), colontoken)
if wellformed:
if wellformed:
self.wellformed = True
self.name = nametokens
self.cssValue = valuetokens
self.priority = prioritytokens
# also invalid values are set!
self.validate()
else:
self._log.error(u'Property: No property name found: %r.' %
@@ -189,11 +162,10 @@ class Property(cssutils.util.Base):
def _setName(self, name):
"""
DOMException on setting
- SYNTAX_ERR: (self)
Raised if the specified name has a syntax error and is
unparsable.
:exceptions:
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified name has a syntax error and is
unparsable.
"""
# for closures: must be a mutable
new = {'literalname': None,
@@ -233,43 +205,42 @@ class Property(cssutils.util.Base):
self.wellformed = True
self._literalname = new['literalname']
self._name = self._normalize(self._literalname)
self.__normalname = self._name # DEPRECATED
self.seqs[0] = newseq
# validate
if self._name not in profiles.propertiesByProfile():
self.valid = False
tokenizer=self._tokenize2(name)
self._log.warn(u'Property: Unknown Property: %r.' %
new['literalname'], token=token, neverraise=True)
# # validate
if self._name not in profiles.knownnames:
# self.valid = False
self._log.warn(u'Property: Unknown Property.',
token=token, neverraise=True)
else:
self.valid = True
if self.cssValue:
self.cssValue._propertyName = self._name
self.valid = self.cssValue.valid
pass
# self.valid = True
# if self.cssValue:
# self.cssValue._propertyName = self._name
# #self.valid = self.cssValue.valid
else:
self.wellformed = False
name = property(lambda self: self._name, _setName,
doc="Name of this property")
doc="Name of this property.")
literalname = property(lambda self: self._literalname,
doc="Readonly literal (not normalized) name of this property")
doc="Readonly literal (not normalized) name "
"of this property")
def _getCSSValue(self):
return self.seqs[1]
def _setCSSValue(self, cssText):
"""
see css.CSSValue
See css.CSSValue
DOMException on setting?
- SYNTAX_ERR: (self)
:exceptions:
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified CSS string value has a syntax error
(according to the attached property) or is unparsable.
- TODO: INVALID_MODIFICATION_ERR:
Raised if the specified CSS string value represents a different
- :exc:`~xml.dom.InvalidModificationErr`:
TODO: Raised if the specified CSS string value represents a different
type of values than the values allowed by the CSS property.
"""
if self._mediaQuery and not cssText:
@@ -279,25 +250,24 @@ class Property(cssutils.util.Base):
self.seqs[1] = CSSValue()
cssvalue = self.seqs[1]
cssvalue._propertyName = self.name
cssvalue.cssText = cssText
if cssvalue._value and cssvalue.wellformed:
if cssvalue.wellformed: #cssvalue._value and
self.seqs[1] = cssvalue
self.valid = self.valid and cssvalue.valid
self.wellformed = self.wellformed and cssvalue.wellformed
cssValue = property(_getCSSValue, _setCSSValue,
doc="(cssutils) CSSValue object of this property")
def _getValue(self):
if self.cssValue:
return self.cssValue._value
return self.cssValue.cssText # _value # [0]
else:
return u''
def _setValue(self, value):
self.cssValue.cssText = value
self.valid = self.valid and self.cssValue.valid
# self.valid = self.valid and self.cssValue.valid
self.wellformed = self.wellformed and self.cssValue.wellformed
value = property(_getValue, _setValue,
@@ -308,9 +278,7 @@ class Property(cssutils.util.Base):
priority
a string, currently either u'', u'!important' or u'important'
Format
======
::
Format::
prio
: IMPORTANT_SYM S*
@@ -318,14 +286,13 @@ class Property(cssutils.util.Base):
"!"{w}"important" {return IMPORTANT_SYM;}
DOMException on setting
- SYNTAX_ERR: (self)
Raised if the specified priority has a syntax error and is
unparsable.
In this case a priority not equal to None, "" or "!{w}important".
As CSSOM defines CSSStyleDeclaration.getPropertyPriority resulting in
u'important' this value is also allowed to set a Properties priority
:exceptions:
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified priority has a syntax error and is
unparsable.
In this case a priority not equal to None, "" or "!{w}important".
As CSSOM defines CSSStyleDeclaration.getPropertyPriority resulting in
u'important' this value is also allowed to set a Properties priority
"""
if self._mediaQuery:
self._priority = u''
@@ -356,8 +323,7 @@ class Property(cssutils.util.Base):
def _ident(expected, seq, token, tokenizer=None):
# "important"
val = self._tokenvalue(token)
normalval = self._tokenvalue(token, normalize=True)
if 'important' == expected == normalval:
if 'important' == expected:
new['literalpriority'] = val
seq.append(val)
return 'EOF'
@@ -378,38 +344,66 @@ class Property(cssutils.util.Base):
if priority and not new['literalpriority']:
wellformed = False
self._log.info(u'Property: Invalid priority: %r.' %
self._valuestr(priority))
self._valuestr(priority))
if wellformed:
self.wellformed = self.wellformed and wellformed
self._literalpriority = new['literalpriority']
self._priority = self._normalize(self.literalpriority)
self.seqs[2] = newseq
# validate
# validate priority
if self._priority not in (u'', u'important'):
self.valid = False
self._log.info(u'Property: No CSS2 priority value: %r.' %
self._priority, neverraise=True)
self._log.error(u'Property: No CSS priority value: %r.' %
self._priority)
priority = property(lambda self: self._priority, _setPriority,
doc="(cssutils) Priority of this property")
doc="Priority of this property.")
literalpriority = property(lambda self: self._literalpriority,
doc="Readonly literal (not normalized) priority of this property")
def __repr__(self):
return "cssutils.css.%s(name=%r, value=%r, priority=%r)" % (
self.__class__.__name__,
self.literalname, self.cssValue.cssText, self.priority)
def validate(self, profile=None):
"""Validate value against `profile`.
:param profile:
A profile name used for validating. If no `profile` is given
``Property.profiles
"""
valid = False
if self.name and self.value:
if profile is None:
usedprofile = cssutils.profiles.defaultprofile
else:
usedprofile = profile
if self.name in profiles.knownnames:
valid, validprofiles = profiles.validateWithProfile(self.name,
self.value,
usedprofile)
def __str__(self):
return "<%s.%s object name=%r value=%r priority=%r at 0x%x>" % (
self.__class__.__module__, self.__class__.__name__,
self.name, self.cssValue.cssText, self.priority, id(self))
if not valid:
self._log.error(u'Property: Invalid value for "%s" property: %s: %s'
% (u'/'.join(validprofiles),
self.name,
self.value),
neverraise=True)
elif valid and (usedprofile and usedprofile not in validprofiles):
self._log.warn(u'Property: Not valid for profile "%s": %s: %s'
% (usedprofile, self.name, self.value),
neverraise=True)
if valid:
self._log.info(u'Property: Found valid "%s" property: %s: %s'
% (u'/'.join(validprofiles),
self.name,
self.value),
neverraise=True)
if self._priority not in (u'', u'important'):
valid = False
@Deprecated(u'Use property ``name`` instead (since cssutils 0.9.5).')
def _getNormalname(self):
return self.__normalname
normalname = property(_getNormalname,
doc="DEPRECATED since 0.9.5, use name instead")
return valid
valid = property(validate, doc="Check if value of this property is valid "
"in the properties context.")
+58 -78
View File
@@ -1,7 +1,5 @@
"""Selector is a single Selector of a CSSStyleRule SelectorList.
Partly implements
http://www.w3.org/TR/css3-selectors/
Partly implements http://www.w3.org/TR/css3-selectors/.
TODO
- .contains(selector)
@@ -9,45 +7,18 @@ TODO
"""
__all__ = ['Selector']
__docformat__ = 'restructuredtext'
__version__ = '$Id: selector.py 1429 2008-08-11 19:01:52Z cthedot $'
__version__ = '$Id: selector.py 1638 2009-01-13 20:39:33Z cthedot $'
import xml.dom
import cssutils
from cssutils.util import _SimpleNamespaces
import cssutils
import xml.dom
class Selector(cssutils.util.Base2):
"""
(cssutils) a single selector in a SelectorList of a CSSStyleRule
(cssutils) a single selector in a :class:`~cssutils.css.SelectorList`
of a :class:`~cssutils.css.CSSStyleRule`.
Properties
==========
element
Effective element target of this selector
parentList: of type SelectorList, readonly
The SelectorList that contains this selector or None if this
Selector is not attached to a SelectorList.
selectorText
textual representation of this Selector
seq
sequence of Selector parts including comments
specificity (READONLY)
tuple of (a, b, c, d) where:
a
presence of style in document, always 0 if not used on a document
b
number of ID selectors
c
number of .class selectors
d
number of Element (type) selectors
wellformed
if this selector is wellformed regarding the Selector spec
Format
======
::
Format::
# implemented in SelectorList
selectors_group
@@ -150,14 +121,46 @@ class Selector(cssutils.util.Base2):
self._readonly = readonly
def __repr__(self):
if self.__getNamespaces():
st = (self.selectorText, self._getUsedNamespaces())
else:
st = self.selectorText
return u"cssutils.css.%s(selectorText=%r)" % (
self.__class__.__name__, st)
def __str__(self):
return u"<cssutils.css.%s object selectorText=%r specificity=%r _namespaces=%r at 0x%x>" % (
self.__class__.__name__, self.selectorText, self.specificity,
self._getUsedNamespaces(), id(self))
def _getUsedUris(self):
"Return list of actually used URIs in this Selector."
uris = set()
for item in self.seq:
type_, val = item.type, item.value
if type_.endswith(u'-selector') or type_ == u'universal' and \
type(val) == tuple and val[0] not in (None, u'*'):
uris.add(val[0])
return uris
def _getUsedNamespaces(self):
"Return actually used namespaces only."
useduris = self._getUsedUris()
namespaces = _SimpleNamespaces(log=self._log)
for p, uri in self._namespaces.items():
if uri in useduris:
namespaces[p] = uri
return namespaces
def __getNamespaces(self):
"uses own namespaces if not attached to a sheet, else the sheet's ones"
"Use own namespaces if not attached to a sheet, else the sheet's ones."
try:
return self._parent.parentRule.parentStyleSheet.namespaces
except AttributeError:
return self.__namespaces
_namespaces = property(__getNamespaces, doc="""if this Selector is attached
_namespaces = property(__getNamespaces, doc="""If this Selector is attached
to a CSSStyleSheet the namespaces of that sheet are mirrored here.
While the Selector (or parent SelectorList or parentRule(s) of that are
not attached a own dict of {prefix: namespaceURI} is used.""")
@@ -171,9 +174,7 @@ class Selector(cssutils.util.Base2):
None if this Selector is not attached to a SelectorList.")
def _getSelectorText(self):
"""
returns serialized format
"""
"""Return serialized format."""
return cssutils.ser.do_css_Selector(self)
def _setSelectorText(self, selectorText):
@@ -183,14 +184,14 @@ class Selector(cssutils.util.Base2):
Given namespaces are ignored if this object is attached to a
CSSStyleSheet!
:Exceptions:
- `NAMESPACE_ERR`: (self)
:exceptions:
- :exc:`~xml.dom.NamespaceErr`:
Raised if the specified selector uses an unknown namespace
prefix.
- `SYNTAX_ERR`: (self)
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified CSS string value has a syntax error
and is unparsable.
- `NO_MODIFICATION_ALLOWED_ERR`: (self)
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if this rule is readonly.
"""
self._checkReadonly()
@@ -763,38 +764,17 @@ class Selector(cssutils.util.Base2):
specificity = property(lambda self: self._specificity,
doc="Specificity of this selector (READONLY).")
doc="""Specificity of this selector (READONLY).
Tuple of (a, b, c, d) where:
a
presence of style in document, always 0 if not used on a document
b
number of ID selectors
c
number of .class selectors
d
number of Element (type) selectors
""")
wellformed = property(lambda self: bool(len(self.seq)))
def __repr__(self):
if self.__getNamespaces():
st = (self.selectorText, self._getUsedNamespaces())
else:
st = self.selectorText
return u"cssutils.css.%s(selectorText=%r)" % (
self.__class__.__name__, st)
def __str__(self):
return u"<cssutils.css.%s object selectorText=%r specificity=%r _namespaces=%r at 0x%x>" % (
self.__class__.__name__, self.selectorText, self.specificity,
self._getUsedNamespaces(), id(self))
def _getUsedUris(self):
"returns list of actually used URIs in this Selector"
uris = set()
for item in self.seq:
type_, val = item.type, item.value
if type_.endswith(u'-selector') or type_ == u'universal' and \
type(val) == tuple and val[0] not in (None, u'*'):
uris.add(val[0])
return uris
def _getUsedNamespaces(self):
"returns actually used namespaces only"
useduris = self._getUsedUris()
namespaces = _SimpleNamespaces(log=self._log)
for p, uri in self._namespaces.items():
if uri in useduris:
namespaces[p] = uri
return namespaces
+95 -114
View File
@@ -17,37 +17,18 @@ TODO
"""
__all__ = ['SelectorList']
__docformat__ = 'restructuredtext'
__version__ = '$Id: selectorlist.py 1174 2008-03-20 17:43:07Z cthedot $'
__version__ = '$Id: selectorlist.py 1638 2009-01-13 20:39:33Z cthedot $'
import xml.dom
import cssutils
from selector import Selector
import cssutils
import xml.dom
class SelectorList(cssutils.util.Base, cssutils.util.ListSeq):
"""
(cssutils) a list of Selectors of a CSSStyleRule
Properties
==========
length: of type unsigned long, readonly
The number of Selector elements in the list.
parentRule: of type CSSRule, readonly
The CSS rule that contains this selector list or None if this
list is not attached to a CSSRule.
selectorText: of type DOMString
The textual representation of the selector for the rule set. The
implementation may have stripped out insignificant whitespace while
parsing the selector.
seq: (internal use!)
A list of Selector objects
wellformed
if this selectorlist is wellformed regarding the Selector spec
"""
"""A list of :class:`~cssutils.css.Selector` objects
of a :class:`~cssutils.css.CSSStyleRule`."""
def __init__(self, selectorText=None, parentRule=None,
readonly=False):
"""
initializes SelectorList with optional selectorText
:Parameters:
selectorText
parsable list of Selectors
@@ -63,8 +44,30 @@ class SelectorList(cssutils.util.Base, cssutils.util.ListSeq):
self._readonly = readonly
def __repr__(self):
if self._namespaces:
st = (self.selectorText, self._namespaces)
else:
st = self.selectorText
return "cssutils.css.%s(selectorText=%r)" % (
self.__class__.__name__, st)
def __str__(self):
return "<cssutils.css.%s object selectorText=%r _namespaces=%r at 0x%x>" % (
self.__class__.__name__, self.selectorText, self._namespaces,
id(self))
def __setitem__(self, index, newSelector):
"""Overwrite ListSeq.__setitem__
Any duplicate Selectors are **not** removed.
"""
newSelector = self.__prepareset(newSelector)
if newSelector:
self.seq[index] = newSelector
def __prepareset(self, newSelector, namespaces=None):
"used by appendSelector and __setitem__"
"Used by appendSelector and __setitem__"
if not namespaces:
namespaces = {}
self._checkReadonly()
@@ -75,26 +78,8 @@ class SelectorList(cssutils.util.Base, cssutils.util.ListSeq):
newSelector._parent = self # maybe set twice but must be!
return newSelector
def __setitem__(self, index, newSelector):
"""
overwrites ListSeq.__setitem__
Any duplicate Selectors are **not** removed.
"""
newSelector = self.__prepareset(newSelector)
if newSelector:
self.seq[index] = newSelector
def append(self, newSelector):
"same as appendSelector(newSelector)"
self.appendSelector(newSelector)
length = property(lambda self: len(self),
doc="The number of Selector elements in the list.")
def __getNamespaces(self):
"uses children namespaces if not attached to a sheet, else the sheet's ones"
"Use children namespaces if not attached to a sheet, else the sheet's ones."
try:
return self.parentRule.parentStyleSheet.namespaces
except AttributeError:
@@ -103,17 +88,67 @@ class SelectorList(cssutils.util.Base, cssutils.util.ListSeq):
namespaces.update(selector._namespaces)
return namespaces
_namespaces = property(__getNamespaces, doc="""if this SelectorList is
def _getUsedUris(self):
"Used by CSSStyleSheet to check if @namespace rules are needed"
uris = set()
for s in self:
uris.update(s._getUsedUris())
return uris
_namespaces = property(__getNamespaces, doc="""If this SelectorList is
attached to a CSSStyleSheet the namespaces of that sheet are mirrored
here. While the SelectorList (or parentRule(s) are
not attached the namespaces of all children Selectors are used.""")
parentRule = property(lambda self: self._parentRule,
doc="(DOM) The CSS rule that contains this SelectorList or\
None if this SelectorList is not attached to a CSSRule.")
def append(self, newSelector):
"Same as :meth:`appendSelector`."
self.appendSelector(newSelector)
def appendSelector(self, newSelector):
"""
Append `newSelector` to this list (a string will be converted to a
:class:`~cssutils.css.Selector`).
:param newSelector:
comma-separated list of selectors (as a single string) or a tuple of
`(newSelector, dict-of-namespaces)`
:returns: New :class:`~cssutils.css.Selector` or ``None`` if
`newSelector` is not wellformed.
:exceptions:
- :exc:`~xml.dom.NamespaceErr`:
Raised if the specified selector uses an unknown namespace
prefix.
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified CSS string value has a syntax error
and is unparsable.
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if this rule is readonly.
"""
self._checkReadonly()
# might be (selectorText, namespaces)
newSelector, namespaces = self._splitNamespacesOff(newSelector)
try:
# use parent's only if available
namespaces = self.parentRule.parentStyleSheet.namespaces
except AttributeError:
# use already present namespaces plus new given ones
_namespaces = self._namespaces
_namespaces.update(namespaces)
namespaces = _namespaces
newSelector = self.__prepareset(newSelector, namespaces)
if newSelector:
seq = self.seq[:]
del self.seq[:]
for s in seq:
if s.selectorText != newSelector.selectorText:
self.seq.append(s)
self.seq.append(newSelector)
return newSelector
def _getSelectorText(self):
"returns serialized format"
"Return serialized format."
return cssutils.ser.do_css_SelectorList(self)
def _setSelectorText(self, selectorText):
@@ -121,14 +156,14 @@ class SelectorList(cssutils.util.Base, cssutils.util.ListSeq):
:param selectorText:
comma-separated list of selectors or a tuple of
(selectorText, dict-of-namespaces)
:Exceptions:
- `NAMESPACE_ERR`: (Selector)
:exceptions:
- :exc:`~xml.dom.NamespaceErr`:
Raised if the specified selector uses an unknown namespace
prefix.
- `SYNTAX_ERR`: (self)
- :exc:`~xml.dom.SyntaxErr`:
Raised if the specified CSS string value has a syntax error
and is unparsable.
- `NO_MODIFICATION_ALLOWED_ERR`: (self)
- :exc:`~xml.dom.NoModificationAllowedErr`:
Raised if this rule is readonly.
"""
self._checkReadonly()
@@ -184,66 +219,12 @@ class SelectorList(cssutils.util.Base, cssutils.util.ListSeq):
doc="""(cssutils) The textual representation of the selector for
a rule set.""")
length = property(lambda self: len(self),
doc="The number of :class:`~cssutils.css.Selector` objects in the list.")
parentRule = property(lambda self: self._parentRule,
doc="(DOM) The CSS rule that contains this SelectorList or "
"``None`` if this SelectorList is not attached to a CSSRule.")
wellformed = property(lambda self: bool(len(self.seq)))
def appendSelector(self, newSelector):
"""
Append newSelector (a string will be converted to a new
Selector).
:param newSelector:
comma-separated list of selectors or a tuple of
(selectorText, dict-of-namespaces)
:returns: New Selector or None if newSelector is not wellformed.
:Exceptions:
- `NAMESPACE_ERR`: (self)
Raised if the specified selector uses an unknown namespace
prefix.
- `SYNTAX_ERR`: (self)
Raised if the specified CSS string value has a syntax error
and is unparsable.
- `NO_MODIFICATION_ALLOWED_ERR`: (self)
Raised if this rule is readonly.
"""
self._checkReadonly()
# might be (selectorText, namespaces)
newSelector, namespaces = self._splitNamespacesOff(newSelector)
try:
# use parent's only if available
namespaces = self.parentRule.parentStyleSheet.namespaces
except AttributeError:
# use already present namespaces plus new given ones
_namespaces = self._namespaces
_namespaces.update(namespaces)
namespaces = _namespaces
newSelector = self.__prepareset(newSelector, namespaces)
if newSelector:
seq = self.seq[:]
del self.seq[:]
for s in seq:
if s.selectorText != newSelector.selectorText:
self.seq.append(s)
self.seq.append(newSelector)
return newSelector
def __repr__(self):
if self._namespaces:
st = (self.selectorText, self._namespaces)
else:
st = self.selectorText
return "cssutils.css.%s(selectorText=%r)" % (
self.__class__.__name__, st)
def __str__(self):
return "<cssutils.css.%s object selectorText=%r _namespaces=%r at 0x%x>" % (
self.__class__.__name__, self.selectorText, self._namespaces,
id(self))
def _getUsedUris(self):
"used by CSSStyleSheet to check if @namespace rules are needed"
uris = set()
for s in self:
uris.update(s._getUsedUris())
return uris