mirror of
https://github.com/kovidgoyal/calibre.git
synced 2026-06-06 05:55:27 -04:00
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:
@@ -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 *
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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.")
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.")
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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))
|
||||
|
||||
+556
-936
File diff suppressed because it is too large
Load Diff
+128
-134
@@ -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.")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user