mirror of
https://github.com/kovidgoyal/calibre.git
synced 2026-06-06 05:55:27 -04:00
Update bundled version of cssutils. Fixes #3162 (Calibre does not support complete font-face standard)
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
"""CSSFontFaceRule implements DOM Level 2 CSS CSSFontFaceRule.
|
||||
|
||||
From cssutils 0.9.6 additions from CSS Fonts Module Level 3 are
|
||||
added http://www.w3.org/TR/css3-fonts/.
|
||||
"""
|
||||
__all__ = ['CSSFontFaceRule']
|
||||
__docformat__ = 'restructuredtext'
|
||||
__version__ = '$Id: cssfontfacerule.py 1638 2009-01-13 20:39:33Z cthedot $'
|
||||
__version__ = '$Id: cssfontfacerule.py 1818 2009-07-30 21:39:00Z cthedot $'
|
||||
|
||||
from cssstyledeclaration import CSSStyleDeclaration
|
||||
import cssrule
|
||||
@@ -21,6 +24,11 @@ class CSSFontFaceRule(cssrule.CSSRule):
|
||||
: FONT_FACE_SYM S*
|
||||
'{' S* declaration [ ';' S* declaration ]* '}' S*
|
||||
;
|
||||
|
||||
cssutils uses a :class:`~cssutils.css.CSSStyleDeclaration` to
|
||||
represent the font descriptions. For validation a specific profile
|
||||
is used though were some properties have other valid values than
|
||||
when used in e.g. a :class:`~cssutils.css.CSSStyleRule`.
|
||||
"""
|
||||
def __init__(self, style=None, parentRule=None,
|
||||
parentStyleSheet=None, readonly=False):
|
||||
@@ -28,25 +36,26 @@ class CSSFontFaceRule(cssrule.CSSRule):
|
||||
If readonly allows setting of properties in constructor only.
|
||||
|
||||
:param style:
|
||||
CSSStyleDeclaration for this CSSStyleRule
|
||||
CSSStyleDeclaration used to hold any font descriptions
|
||||
for this CSSFontFaceRule
|
||||
"""
|
||||
super(CSSFontFaceRule, self).__init__(parentRule=parentRule,
|
||||
parentStyleSheet=parentStyleSheet)
|
||||
self._atkeyword = u'@font-face'
|
||||
self._style = CSSStyleDeclaration(parentRule=self)
|
||||
if style:
|
||||
self.style = style
|
||||
else:
|
||||
self._style = CSSStyleDeclaration(parentRule=self)
|
||||
|
||||
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))
|
||||
return "<cssutils.css.%s object style=%r valid=%r at 0x%x>" % (
|
||||
self.__class__.__name__, self.style.cssText, self.valid,
|
||||
id(self))
|
||||
|
||||
def _getCssText(self):
|
||||
"""Return serialized property cssText."""
|
||||
@@ -112,15 +121,22 @@ class CSSFontFaceRule(cssrule.CSSRule):
|
||||
self._log.error(u'CSSFontFaceRule: Trailing content found.',
|
||||
token=nonetoken)
|
||||
|
||||
newstyle = CSSStyleDeclaration()
|
||||
teststyle = CSSStyleDeclaration(parentRule=self)
|
||||
if 'EOF' == typ:
|
||||
# add again as style needs it
|
||||
styletokens.append(braceorEOFtoken)
|
||||
newstyle.cssText = styletokens
|
||||
# may raise:
|
||||
teststyle.cssText = styletokens
|
||||
|
||||
if wellformed:
|
||||
self.style = newstyle
|
||||
self._setSeq(newseq) # contains (probably comments) upto { only
|
||||
# contains probably comments only upto {
|
||||
self._setSeq(newseq)
|
||||
|
||||
# known as correct from before
|
||||
cssutils.log.enabled = False
|
||||
self.style.cssText = styletokens
|
||||
cssutils.log.enabled = True
|
||||
|
||||
|
||||
cssText = property(_getCssText, _setCssText,
|
||||
doc="(DOM) The parsable textual representation of this rule.")
|
||||
@@ -132,9 +148,10 @@ class CSSFontFaceRule(cssrule.CSSRule):
|
||||
"""
|
||||
self._checkReadonly()
|
||||
if isinstance(style, basestring):
|
||||
self._style = CSSStyleDeclaration(parentRule=self, cssText=style)
|
||||
self._style.cssText = style
|
||||
else:
|
||||
self._style._seq = style.seq
|
||||
self._style = style
|
||||
self._style.parentRule = self
|
||||
|
||||
style = property(lambda self: self._style, _setStyle,
|
||||
doc="(DOM) The declaration-block of this rule set, "
|
||||
@@ -144,5 +161,20 @@ class CSSFontFaceRule(cssrule.CSSRule):
|
||||
doc="The type of this rule, as defined by a CSSRule "
|
||||
"type constant.")
|
||||
|
||||
def _getValid(self):
|
||||
needed = ['font-family', 'src']
|
||||
for p in self.style.getProperties(all=True):
|
||||
if not p.valid:
|
||||
return False
|
||||
try:
|
||||
needed.remove(p.name)
|
||||
except ValueError:
|
||||
pass
|
||||
return not bool(needed)
|
||||
|
||||
valid = property(_getValid, doc='CSSFontFace is valid if properties '
|
||||
'`font-family` and `src` are set and all properties are '
|
||||
'valid.')
|
||||
|
||||
# constant but needed:
|
||||
wellformed = property(lambda self: True)
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
"""CSSImportRule implements DOM Level 2 CSS CSSImportRule plus the
|
||||
``name`` property from http://www.w3.org/TR/css3-cascade/#cascading.
|
||||
|
||||
"""
|
||||
``name`` property from http://www.w3.org/TR/css3-cascade/#cascading."""
|
||||
__all__ = ['CSSImportRule']
|
||||
__docformat__ = 'restructuredtext'
|
||||
__version__ = '$Id: cssimportrule.py 1638 2009-01-13 20:39:33Z cthedot $'
|
||||
__version__ = '$Id: cssimportrule.py 1824 2009-08-01 21:00:34Z cthedot $'
|
||||
|
||||
import cssrule
|
||||
import cssutils
|
||||
@@ -320,7 +318,8 @@ class CSSImportRule(cssrule.CSSRule):
|
||||
parentHref = self.parentStyleSheet.href
|
||||
if parentHref is None:
|
||||
# use cwd instead
|
||||
parentHref = u'file:' + urllib.pathname2url(os.getcwd()) + '/'
|
||||
#parentHref = u'file:' + urllib.pathname2url(os.getcwd()) + '/'
|
||||
parentHref = cssutils.helper.path2url(os.getcwd()) + '/'
|
||||
href = urlparse.urljoin(parentHref, self.href)
|
||||
|
||||
# all possible exceptions are ignored (styleSheet is None then)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""CSSMediaRule implements DOM Level 2 CSS CSSMediaRule."""
|
||||
__all__ = ['CSSMediaRule']
|
||||
__docformat__ = 'restructuredtext'
|
||||
__version__ = '$Id: cssmediarule.py 1743 2009-05-09 20:33:15Z cthedot $'
|
||||
__version__ = '$Id: cssmediarule.py 1820 2009-08-01 20:53:08Z cthedot $'
|
||||
|
||||
import cssrule
|
||||
import cssutils
|
||||
@@ -34,15 +34,11 @@ class CSSMediaRule(cssrule.CSSRule):
|
||||
readonly=readonly)
|
||||
self.name = name
|
||||
self.cssRules = cssutils.css.cssrulelist.CSSRuleList()
|
||||
self.cssRules.append = self.insertRule
|
||||
self.cssRules.extend = self.insertRule
|
||||
self.cssRules.__delitem__ == self.deleteRule
|
||||
|
||||
self._readonly = readonly
|
||||
|
||||
def __iter__(self):
|
||||
"""Generator iterating over these rule's cssRules."""
|
||||
for rule in self.cssRules:
|
||||
for rule in self._cssRules:
|
||||
yield rule
|
||||
|
||||
def __repr__(self):
|
||||
@@ -53,6 +49,20 @@ class CSSMediaRule(cssrule.CSSRule):
|
||||
return "<cssutils.css.%s object mediaText=%r at 0x%x>" % (
|
||||
self.__class__.__name__, self.media.mediaText, id(self))
|
||||
|
||||
def _setCssRules(self, cssRules):
|
||||
"Set new cssRules and update contained rules refs."
|
||||
cssRules.append = self.insertRule
|
||||
cssRules.extend = self.insertRule
|
||||
cssRules.__delitem__ == self.deleteRule
|
||||
for rule in cssRules:
|
||||
rule._parentStyleSheet = self.parentStyleSheet
|
||||
rule._parentRule = self
|
||||
self._cssRules = cssRules
|
||||
|
||||
cssRules = property(lambda self: self._cssRules, _setCssRules,
|
||||
"All Rules in this style sheet, a "
|
||||
":class:`~cssutils.css.CSSRuleList`.")
|
||||
|
||||
def _getCssText(self):
|
||||
"""Return serialized property cssText."""
|
||||
return cssutils.ser.do_CSSMediaRule(self)
|
||||
@@ -204,9 +214,9 @@ class CSSMediaRule(cssrule.CSSRule):
|
||||
self._media.mediaText = newmedia.mediaText
|
||||
self.name = name
|
||||
self._setSeq(nameseq)
|
||||
del self.cssRules[:]
|
||||
del self._cssRules[:]
|
||||
for r in newcssrules:
|
||||
self.cssRules.append(r)
|
||||
self._cssRules.append(r)
|
||||
|
||||
cssText = property(_getCssText, _setCssText,
|
||||
doc="(DOM) The parsable textual representation of this rule.")
|
||||
@@ -245,12 +255,12 @@ class CSSMediaRule(cssrule.CSSRule):
|
||||
self._checkReadonly()
|
||||
|
||||
try:
|
||||
self.cssRules[index]._parentRule = None # detach
|
||||
del self.cssRules[index] # remove from @media
|
||||
self._cssRules[index]._parentRule = None # detach
|
||||
del self._cssRules[index] # remove from @media
|
||||
except IndexError:
|
||||
raise xml.dom.IndexSizeErr(
|
||||
u'CSSMediaRule: %s is not a valid index in the rulelist of length %i' % (
|
||||
index, self.cssRules.length))
|
||||
index, self._cssRules.length))
|
||||
|
||||
def add(self, rule):
|
||||
"""Add `rule` to end of this mediarule.
|
||||
@@ -300,11 +310,11 @@ class CSSMediaRule(cssrule.CSSRule):
|
||||
|
||||
# check position
|
||||
if index is None:
|
||||
index = len(self.cssRules)
|
||||
elif index < 0 or index > self.cssRules.length:
|
||||
index = len(self._cssRules)
|
||||
elif index < 0 or index > self._cssRules.length:
|
||||
raise xml.dom.IndexSizeErr(
|
||||
u'CSSMediaRule: Invalid index %s for CSSRuleList with a length of %s.' % (
|
||||
index, self.cssRules.length))
|
||||
index, self._cssRules.length))
|
||||
|
||||
# parse
|
||||
if isinstance(rule, basestring):
|
||||
@@ -315,6 +325,13 @@ class CSSMediaRule(cssrule.CSSRule):
|
||||
self._log.error(u'CSSMediaRule: Invalid Rule: %s' % rule)
|
||||
return
|
||||
rule = tempsheet.cssRules[0]
|
||||
|
||||
elif isinstance(rule, cssutils.css.CSSRuleList):
|
||||
# insert all rules
|
||||
for i, r in enumerate(rule):
|
||||
self.insertRule(r, index + i)
|
||||
return index
|
||||
|
||||
elif not isinstance(rule, cssutils.css.CSSRule):
|
||||
self._log.error(u'CSSMediaRule: Not a CSSRule: %s' % rule)
|
||||
return
|
||||
@@ -332,7 +349,7 @@ class CSSMediaRule(cssrule.CSSRule):
|
||||
error=xml.dom.HierarchyRequestErr)
|
||||
return
|
||||
|
||||
self.cssRules.insert(index, rule)
|
||||
self._cssRules.insert(index, rule)
|
||||
rule._parentRule = self
|
||||
rule._parentStyleSheet = self.parentStyleSheet
|
||||
return index
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
"""CSSPageRule implements DOM Level 2 CSS CSSPageRule.
|
||||
"""
|
||||
"""CSSPageRule implements DOM Level 2 CSS CSSPageRule."""
|
||||
__all__ = ['CSSPageRule']
|
||||
__docformat__ = 'restructuredtext'
|
||||
__version__ = '$Id: csspagerule.py 1658 2009-02-07 18:24:40Z cthedot $'
|
||||
__version__ = '$Id: csspagerule.py 1824 2009-08-01 21:00:34Z cthedot $'
|
||||
|
||||
from cssstyledeclaration import CSSStyleDeclaration
|
||||
from selectorlist import SelectorList
|
||||
@@ -45,11 +44,12 @@ class CSSPageRule(cssrule.CSSRule):
|
||||
tempseq.append(self.selectorText, 'selectorText')
|
||||
else:
|
||||
self._selectorText = self._tempSeq()
|
||||
|
||||
self._style = CSSStyleDeclaration(parentRule=self)
|
||||
if style:
|
||||
self.style = style
|
||||
tempseq.append(self.style, 'style')
|
||||
else:
|
||||
self._style = CSSStyleDeclaration(parentRule=self)
|
||||
|
||||
self._setSeq(tempseq)
|
||||
|
||||
self._readonly = readonly
|
||||
@@ -192,7 +192,7 @@ class CSSPageRule(cssrule.CSSRule):
|
||||
|
||||
wellformed, newselectorseq = self.__parseSelectorText(selectortokens)
|
||||
|
||||
newstyle = CSSStyleDeclaration()
|
||||
teststyle = CSSStyleDeclaration(parentRule=self)
|
||||
val, typ = self._tokenvalue(braceorEOFtoken), self._type(braceorEOFtoken)
|
||||
if val != u'}' and typ != 'EOF':
|
||||
wellformed = False
|
||||
@@ -203,13 +203,15 @@ class CSSPageRule(cssrule.CSSRule):
|
||||
if 'EOF' == typ:
|
||||
# add again as style needs it
|
||||
styletokens.append(braceorEOFtoken)
|
||||
newstyle.cssText = styletokens
|
||||
teststyle.cssText = styletokens
|
||||
|
||||
if wellformed:
|
||||
self._selectorText = newselectorseq # already parsed
|
||||
self.style = newstyle
|
||||
self._setSeq(newselectorseq) # contains upto style only
|
||||
|
||||
# known as correct from before
|
||||
cssutils.log.enabled = False
|
||||
self._selectorText = newselectorseq # TODO: TEST and REFS
|
||||
self.style.cssText = styletokens
|
||||
cssutils.log.enabled = True
|
||||
|
||||
cssText = property(_getCssText, _setCssText,
|
||||
doc="(DOM) The parsable textual representation of this rule.")
|
||||
|
||||
@@ -239,7 +241,7 @@ class CSSPageRule(cssrule.CSSRule):
|
||||
|
||||
# may raise SYNTAX_ERR
|
||||
wellformed, newseq = self.__parseSelectorText(selectorText)
|
||||
if wellformed and newseq:
|
||||
if wellformed:
|
||||
self._selectorText = newseq
|
||||
|
||||
selectorText = property(_getSelectorText, _setSelectorText,
|
||||
@@ -251,19 +253,16 @@ class CSSPageRule(cssrule.CSSRule):
|
||||
a CSSStyleDeclaration or string
|
||||
"""
|
||||
self._checkReadonly()
|
||||
|
||||
if isinstance(style, basestring):
|
||||
self._style.cssText = style
|
||||
else:
|
||||
# cssText would be serialized with optional preferences
|
||||
# so use seq!
|
||||
self._style._seq = style.seq
|
||||
self._style = style
|
||||
self._style.parentRule = self
|
||||
|
||||
style = property(lambda self: self._style, _setStyle,
|
||||
doc="(DOM) The declaration-block of this rule set, "
|
||||
"a :class:`~cssutils.css.CSSStyleDeclaration`.")
|
||||
|
||||
|
||||
type = property(lambda self: self.PAGE_RULE,
|
||||
doc="The type of this rule, as defined by a CSSRule "
|
||||
"type constant.")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""CSSRule implements DOM Level 2 CSS CSSRule."""
|
||||
__all__ = ['CSSRule']
|
||||
__docformat__ = 'restructuredtext'
|
||||
__version__ = '$Id: cssrule.py 1638 2009-01-13 20:39:33Z cthedot $'
|
||||
__version__ = '$Id: cssrule.py 1808 2009-07-29 13:09:36Z cthedot $'
|
||||
|
||||
import cssutils
|
||||
import xml.dom
|
||||
@@ -35,6 +35,7 @@ class CSSRule(cssutils.util.Base2):
|
||||
def __init__(self, parentRule=None, parentStyleSheet=None, readonly=False):
|
||||
"""Set common attributes for all rules."""
|
||||
super(CSSRule, self).__init__()
|
||||
self._parent = parentRule
|
||||
self._parentRule = parentRule
|
||||
self._parentStyleSheet = parentStyleSheet
|
||||
self._setSeq(self._tempSeq())
|
||||
@@ -78,6 +79,10 @@ class CSSRule(cssutils.util.Base2):
|
||||
"rule. This reflects the current state of the rule "
|
||||
"and not its initial value.")
|
||||
|
||||
parent = property(lambda self: self._parent,
|
||||
doc="The Parent Node of this CSSRule (currently if a "
|
||||
"CSSStyleDeclaration only!) or None.")
|
||||
|
||||
parentRule = property(lambda self: self._parentRule,
|
||||
doc="If this rule is contained inside "
|
||||
"another rule (e.g. a style rule inside "
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
"""CSSRuleList implements DOM Level 2 CSS CSSRuleList.
|
||||
Partly also http://dev.w3.org/csswg/cssom/#the-cssrulelist
|
||||
"""
|
||||
Partly also http://dev.w3.org/csswg/cssom/#the-cssrulelist."""
|
||||
__all__ = ['CSSRuleList']
|
||||
__docformat__ = 'restructuredtext'
|
||||
__version__ = '$Id: cssrulelist.py 1641 2009-01-13 21:05:37Z cthedot $'
|
||||
__version__ = '$Id: cssrulelist.py 1824 2009-08-01 21:00:34Z cthedot $'
|
||||
|
||||
class CSSRuleList(list):
|
||||
"""The CSSRuleList object represents an (ordered) list of statements.
|
||||
|
||||
@@ -51,7 +51,7 @@ TODO:
|
||||
"""
|
||||
__all__ = ['CSSStyleDeclaration', 'Property']
|
||||
__docformat__ = 'restructuredtext'
|
||||
__version__ = '$Id: cssstyledeclaration.py 1710 2009-04-18 15:46:20Z cthedot $'
|
||||
__version__ = '$Id: cssstyledeclaration.py 1819 2009-08-01 20:52:43Z cthedot $'
|
||||
|
||||
from cssproperties import CSS2Properties
|
||||
from property import Property
|
||||
@@ -127,6 +127,11 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
|
||||
for name in self.__nnames():
|
||||
yield self.getProperty(name)
|
||||
return properties()
|
||||
|
||||
def keys(self):
|
||||
"""Analoguous to standard dict returns property names which are set in
|
||||
this declaration."""
|
||||
return list(self.__nnames())
|
||||
|
||||
def __getitem__(self, CSSName):
|
||||
"""Retrieve the value of property ``CSSName`` from this declaration.
|
||||
@@ -247,6 +252,13 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
|
||||
"""
|
||||
self.removeProperty(CSSName)
|
||||
|
||||
def children(self):
|
||||
"""Generator yielding any known child in this declaration including
|
||||
*all* properties, comments or CSSUnknownrules.
|
||||
"""
|
||||
for item in self._seq:
|
||||
yield item.value
|
||||
|
||||
def _getCssText(self):
|
||||
"""Return serialized property cssText."""
|
||||
return cssutils.ser.do_css_CSSStyleDeclaration(self)
|
||||
@@ -275,10 +287,10 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
|
||||
semicolon=True)
|
||||
if self._tokenvalue(tokens[-1]) == u';':
|
||||
tokens.pop()
|
||||
property = Property()
|
||||
property = Property(parent=self)
|
||||
property.cssText = tokens
|
||||
if property.wellformed:
|
||||
seq.append(property, 'Property')
|
||||
seq.append(property, 'Property')
|
||||
else:
|
||||
self._log.error(u'CSSStyleDeclaration: Syntax Error in Property: %s'
|
||||
% self._valuestr(tokens))
|
||||
@@ -301,12 +313,13 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
|
||||
productions={'IDENT': ident},#, 'CHAR': char},
|
||||
default=unexpected)
|
||||
# wellformed set by parse
|
||||
# post conditions
|
||||
|
||||
for item in newseq:
|
||||
item.value._parent = self
|
||||
|
||||
# do not check wellformed as invalid things are removed anyway
|
||||
#if wellformed:
|
||||
self._setSeq(newseq)
|
||||
|
||||
|
||||
cssText = property(_getCssText, _setCssText,
|
||||
doc="(DOM) A parsable textual representation of the declaration\
|
||||
block excluding the surrounding curly braces.")
|
||||
@@ -322,13 +335,12 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
|
||||
"""
|
||||
return cssutils.ser.do_css_CSSStyleDeclaration(self, separator)
|
||||
|
||||
def _getParentRule(self):
|
||||
return self._parentRule
|
||||
|
||||
def _setParentRule(self, parentRule):
|
||||
self._parentRule = parentRule
|
||||
|
||||
parentRule = property(_getParentRule, _setParentRule,
|
||||
for x in self.children():
|
||||
x.parent = self
|
||||
|
||||
parentRule = property(lambda self: self._parentRule, _setParentRule,
|
||||
doc="(DOM) The CSS rule that contains this declaration block or "
|
||||
"None if this CSSStyleDeclaration is not attached to a CSSRule.")
|
||||
|
||||
@@ -581,6 +593,7 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
|
||||
property.priority = newp.priority
|
||||
break
|
||||
else:
|
||||
newp.parent = self
|
||||
self.seq._readonly = False
|
||||
self.seq.append(newp, 'Property')
|
||||
self.seq._readonly = True
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""CSSStyleRule implements DOM Level 2 CSS CSSStyleRule."""
|
||||
__all__ = ['CSSStyleRule']
|
||||
__docformat__ = 'restructuredtext'
|
||||
__version__ = '$Id: cssstylerule.py 1638 2009-01-13 20:39:33Z cthedot $'
|
||||
__version__ = '$Id: cssstylerule.py 1815 2009-07-29 16:51:58Z cthedot $'
|
||||
|
||||
from cssstyledeclaration import CSSStyleDeclaration
|
||||
from selectorlist import SelectorList
|
||||
@@ -107,6 +107,8 @@ class CSSStyleRule(cssrule.CSSRule):
|
||||
else:
|
||||
wellformed = True
|
||||
|
||||
testselectorlist, teststyle = None, None
|
||||
|
||||
bracetoken = selectortokens.pop()
|
||||
if self._tokenvalue(bracetoken) != u'{':
|
||||
wellformed = False
|
||||
@@ -117,11 +119,11 @@ class CSSStyleRule(cssrule.CSSRule):
|
||||
wellformed = False
|
||||
self._log.error(u'CSSStyleRule: No selector found: %r.' %
|
||||
self._valuestr(cssText), bracetoken)
|
||||
newselectorlist = SelectorList(selectorText=(selectortokens,
|
||||
|
||||
testselectorlist = SelectorList(selectorText=(selectortokens,
|
||||
namespaces),
|
||||
parentRule=self)
|
||||
|
||||
newstyle = CSSStyleDeclaration()
|
||||
if not styletokens:
|
||||
wellformed = False
|
||||
self._log.error(
|
||||
@@ -139,11 +141,14 @@ class CSSStyleRule(cssrule.CSSRule):
|
||||
if 'EOF' == typ:
|
||||
# add again as style needs it
|
||||
styletokens.append(braceorEOFtoken)
|
||||
newstyle.cssText = styletokens
|
||||
teststyle = CSSStyleDeclaration(styletokens, parentRule=self)
|
||||
|
||||
if wellformed:
|
||||
self._selectorList = newselectorlist
|
||||
self.style = newstyle
|
||||
if wellformed and testselectorlist and teststyle:
|
||||
# known as correct from before
|
||||
cssutils.log.enabled = False
|
||||
self.style.cssText = styletokens
|
||||
self.selectorList.selectorText=(selectortokens, namespaces)
|
||||
cssutils.log.enabled = True
|
||||
|
||||
cssText = property(_getCssText, _setCssText,
|
||||
doc="(DOM) The parsable textual representation of this rule.")
|
||||
@@ -164,11 +169,12 @@ class CSSStyleRule(cssrule.CSSRule):
|
||||
|
||||
def _setSelectorList(self, selectorList):
|
||||
"""
|
||||
:param selectorList: selectorList, only content is used, not the actual
|
||||
object
|
||||
:param selectorList: A SelectorList which replaces the current
|
||||
selectorList object
|
||||
"""
|
||||
self._checkReadonly()
|
||||
self.selectorText = selectorList.selectorText
|
||||
selectorList._parentRule = self
|
||||
self._selectorList = selectorList
|
||||
|
||||
selectorList = property(lambda self: self._selectorList, _setSelectorList,
|
||||
doc="The SelectorList of this rule.")
|
||||
@@ -200,16 +206,15 @@ class CSSStyleRule(cssrule.CSSRule):
|
||||
|
||||
def _setStyle(self, style):
|
||||
"""
|
||||
:param style: CSSStyleDeclaration or string, only the cssText of a
|
||||
declaration is used, not the actual object
|
||||
:param style: A string or CSSStyleDeclaration which replaces the
|
||||
current style object.
|
||||
"""
|
||||
self._checkReadonly()
|
||||
if isinstance(style, basestring):
|
||||
self._style.cssText = style
|
||||
else:
|
||||
# cssText would be serialized with optional preferences
|
||||
# so use _seq!
|
||||
self._style._seq = style._seq
|
||||
style._parentRule = self
|
||||
self._style = style
|
||||
|
||||
style = property(lambda self: self._style, _setStyle,
|
||||
doc="(DOM) The declaration-block of this rule set.")
|
||||
|
||||
@@ -9,7 +9,7 @@ TODO:
|
||||
"""
|
||||
__all__ = ['CSSStyleSheet']
|
||||
__docformat__ = 'restructuredtext'
|
||||
__version__ = '$Id: cssstylesheet.py 1641 2009-01-13 21:05:37Z cthedot $'
|
||||
__version__ = '$Id: cssstylesheet.py 1820 2009-08-01 20:53:08Z cthedot $'
|
||||
|
||||
from cssutils.helper import Deprecated
|
||||
from cssutils.util import _Namespaces, _SimpleNamespaces, _readUrl
|
||||
@@ -42,8 +42,6 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
||||
|
||||
self._ownerRule = ownerRule
|
||||
self.cssRules = cssutils.css.CSSRuleList()
|
||||
self.cssRules.append = self.insertRule
|
||||
self.cssRules.extend = self.insertRule
|
||||
self._namespaces = _Namespaces(parentStyleSheet=self, log=self._log)
|
||||
self._readonly = readonly
|
||||
|
||||
@@ -53,7 +51,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
||||
|
||||
def __iter__(self):
|
||||
"Generator which iterates over cssRules."
|
||||
for rule in self.cssRules:
|
||||
for rule in self._cssRules:
|
||||
yield rule
|
||||
|
||||
def __repr__(self):
|
||||
@@ -78,7 +76,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
||||
|
||||
def _cleanNamespaces(self):
|
||||
"Remove all namespace rules with same namespaceURI but last one set."
|
||||
rules = self.cssRules
|
||||
rules = self._cssRules
|
||||
namespaceitems = self.namespaces.items()
|
||||
i = 0
|
||||
while i < len(rules):
|
||||
@@ -101,6 +99,19 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
||||
useduris.update(r2.selectorList._getUsedUris())
|
||||
return useduris
|
||||
|
||||
def _setCssRules(self, cssRules):
|
||||
"Set new cssRules and update contained rules refs."
|
||||
cssRules.append = self.insertRule
|
||||
cssRules.extend = self.insertRule
|
||||
cssRules.__delitem__ == self.deleteRule
|
||||
for rule in cssRules:
|
||||
rule._parentStyleSheet = self
|
||||
self._cssRules = cssRules
|
||||
|
||||
cssRules = property(lambda self: self._cssRules, _setCssRules,
|
||||
"All Rules in this style sheet, a "
|
||||
":class:`~cssutils.css.CSSRuleList`.")
|
||||
|
||||
def _getCssText(self):
|
||||
"Textual representation of the stylesheet (a byte string)."
|
||||
return cssutils.ser.do_CSSStyleSheet(self)
|
||||
@@ -260,7 +271,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
||||
default=ruleset)
|
||||
|
||||
if wellformed:
|
||||
del self.cssRules[:]
|
||||
del self._cssRules[:]
|
||||
for rule in newseq:
|
||||
self.insertRule(rule, _clean=False)
|
||||
self._cleanNamespaces()
|
||||
@@ -277,7 +288,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
||||
except AttributeError:
|
||||
try:
|
||||
# explicit @charset
|
||||
selfAsParentEncoding = self.cssRules[0].encoding
|
||||
selfAsParentEncoding = self._cssRules[0].encoding
|
||||
except (IndexError, AttributeError):
|
||||
# default not UTF-8 but None!
|
||||
selfAsParentEncoding = None
|
||||
@@ -312,6 +323,14 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
||||
"""Set @import URL loader, if None the default is used."""
|
||||
self._fetcher = fetcher
|
||||
|
||||
def _getEncoding(self):
|
||||
"""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'
|
||||
|
||||
def _setEncoding(self, encoding):
|
||||
"""Set `encoding` of charset rule if present in sheet or insert a new
|
||||
:class:`~cssutils.css.CSSCharsetRule` with given `encoding`.
|
||||
@@ -319,7 +338,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
||||
default encoding of utf-8.
|
||||
"""
|
||||
try:
|
||||
rule = self.cssRules[0]
|
||||
rule = self._cssRules[0]
|
||||
except IndexError:
|
||||
rule = None
|
||||
if rule and rule.CHARSET_RULE == rule.type:
|
||||
@@ -330,14 +349,6 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
||||
elif encoding:
|
||||
self.insertRule(cssutils.css.CSSCharsetRule(encoding=encoding), 0)
|
||||
|
||||
def _getEncoding(self):
|
||||
"""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) Reflect encoding of an @charset rule or 'utf-8' "
|
||||
"(default) if set to ``None``")
|
||||
@@ -371,11 +382,11 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
||||
self._checkReadonly()
|
||||
|
||||
try:
|
||||
rule = self.cssRules[index]
|
||||
rule = self._cssRules[index]
|
||||
except IndexError:
|
||||
raise xml.dom.IndexSizeErr(
|
||||
u'CSSStyleSheet: %s is not a valid index in the rulelist of length %i' % (
|
||||
index, self.cssRules.length))
|
||||
index, self._cssRules.length))
|
||||
else:
|
||||
if rule.type == rule.NAMESPACE_RULE:
|
||||
# check all namespacerules if used
|
||||
@@ -388,7 +399,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
||||
return
|
||||
|
||||
rule._parentStyleSheet = None # detach
|
||||
del self.cssRules[index] # delete from StyleSheet
|
||||
del self._cssRules[index] # delete from StyleSheet
|
||||
|
||||
def insertRule(self, rule, index=None, inOrder=False, _clean=True):
|
||||
"""
|
||||
@@ -427,11 +438,11 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
||||
|
||||
# check position
|
||||
if index is None:
|
||||
index = len(self.cssRules)
|
||||
elif index < 0 or index > self.cssRules.length:
|
||||
index = len(self._cssRules)
|
||||
elif index < 0 or index > self._cssRules.length:
|
||||
raise xml.dom.IndexSizeErr(
|
||||
u'CSSStyleSheet: Invalid index %s for CSSRuleList with a length of %s.' % (
|
||||
index, self.cssRules.length))
|
||||
index, self._cssRules.length))
|
||||
return
|
||||
|
||||
if isinstance(rule, basestring):
|
||||
@@ -447,11 +458,11 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
||||
# prepend encoding if in this sheet to be able to use it in
|
||||
# @import rules encoding resolution
|
||||
# do not add if new rule startswith "@charset" (which is exact!)
|
||||
if not rule.startswith(u'@charset') and (self.cssRules and
|
||||
self.cssRules[0].type == self.cssRules[0].CHARSET_RULE):
|
||||
if not rule.startswith(u'@charset') and (self._cssRules and
|
||||
self._cssRules[0].type == self._cssRules[0].CHARSET_RULE):
|
||||
# rule 0 is @charset!
|
||||
newrulescount, newruleindex = 2, 1
|
||||
rule = self.cssRules[0].cssText + rule
|
||||
rule = self._cssRules[0].cssText + rule
|
||||
else:
|
||||
newrulescount, newruleindex = 1, 0
|
||||
|
||||
@@ -484,29 +495,29 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
||||
if inOrder:
|
||||
index = 0
|
||||
# always first and only
|
||||
if (self.cssRules and self.cssRules[0].type == rule.CHARSET_RULE):
|
||||
self.cssRules[0].encoding = rule.encoding
|
||||
if (self._cssRules and self._cssRules[0].type == rule.CHARSET_RULE):
|
||||
self._cssRules[0].encoding = rule.encoding
|
||||
else:
|
||||
self.cssRules.insert(0, rule)
|
||||
elif index != 0 or (self.cssRules and
|
||||
self.cssRules[0].type == rule.CHARSET_RULE):
|
||||
self._cssRules.insert(0, rule)
|
||||
elif index != 0 or (self._cssRules and
|
||||
self._cssRules[0].type == rule.CHARSET_RULE):
|
||||
self._log.error(
|
||||
u'CSSStylesheet: @charset only allowed once at the beginning of a stylesheet.',
|
||||
error=xml.dom.HierarchyRequestErr)
|
||||
return
|
||||
else:
|
||||
self.cssRules.insert(index, rule)
|
||||
self._cssRules.insert(index, rule)
|
||||
|
||||
# @unknown or comment
|
||||
elif rule.type in (rule.UNKNOWN_RULE, rule.COMMENT) and not inOrder:
|
||||
if index == 0 and self.cssRules and\
|
||||
self.cssRules[0].type == rule.CHARSET_RULE:
|
||||
if index == 0 and self._cssRules and\
|
||||
self._cssRules[0].type == rule.CHARSET_RULE:
|
||||
self._log.error(
|
||||
u'CSSStylesheet: @charset must be the first rule.',
|
||||
error=xml.dom.HierarchyRequestErr)
|
||||
return
|
||||
else:
|
||||
self.cssRules.insert(index, rule)
|
||||
self._cssRules.insert(index, rule)
|
||||
|
||||
# @import
|
||||
elif rule.type == rule.IMPORT_RULE:
|
||||
@@ -514,27 +525,27 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
||||
# automatic order
|
||||
if rule.type in (r.type for r in self):
|
||||
# find last of this type
|
||||
for i, r in enumerate(reversed(self.cssRules)):
|
||||
for i, r in enumerate(reversed(self._cssRules)):
|
||||
if r.type == rule.type:
|
||||
index = len(self.cssRules) - i
|
||||
index = len(self._cssRules) - i
|
||||
break
|
||||
else:
|
||||
# find first point to insert
|
||||
if self.cssRules and self.cssRules[0].type in (rule.CHARSET_RULE,
|
||||
if self._cssRules and self._cssRules[0].type in (rule.CHARSET_RULE,
|
||||
rule.COMMENT):
|
||||
index = 1
|
||||
else:
|
||||
index = 0
|
||||
else:
|
||||
# after @charset
|
||||
if index == 0 and self.cssRules and\
|
||||
self.cssRules[0].type == rule.CHARSET_RULE:
|
||||
if index == 0 and self._cssRules and\
|
||||
self._cssRules[0].type == rule.CHARSET_RULE:
|
||||
self._log.error(
|
||||
u'CSSStylesheet: Found @charset at index 0.',
|
||||
error=xml.dom.HierarchyRequestErr)
|
||||
return
|
||||
# before @namespace, @page, @font-face, @media and stylerule
|
||||
for r in self.cssRules[:index]:
|
||||
for r in self._cssRules[:index]:
|
||||
if r.type in (r.NAMESPACE_RULE, r.MEDIA_RULE, r.PAGE_RULE,
|
||||
r.STYLE_RULE, r.FONT_FACE_RULE):
|
||||
self._log.error(
|
||||
@@ -542,27 +553,27 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
||||
index,
|
||||
error=xml.dom.HierarchyRequestErr)
|
||||
return
|
||||
self.cssRules.insert(index, rule)
|
||||
self._cssRules.insert(index, rule)
|
||||
|
||||
# @namespace
|
||||
elif rule.type == rule.NAMESPACE_RULE:
|
||||
if inOrder:
|
||||
if rule.type in (r.type for r in self):
|
||||
# find last of this type
|
||||
for i, r in enumerate(reversed(self.cssRules)):
|
||||
for i, r in enumerate(reversed(self._cssRules)):
|
||||
if r.type == rule.type:
|
||||
index = len(self.cssRules) - i
|
||||
index = len(self._cssRules) - i
|
||||
break
|
||||
else:
|
||||
# find first point to insert
|
||||
for i, r in enumerate(self.cssRules):
|
||||
for i, r in enumerate(self._cssRules):
|
||||
if r.type in (r.MEDIA_RULE, r.PAGE_RULE, r.STYLE_RULE,
|
||||
r.FONT_FACE_RULE, r.UNKNOWN_RULE, r.COMMENT):
|
||||
index = i # before these
|
||||
break
|
||||
else:
|
||||
# after @charset and @import
|
||||
for r in self.cssRules[index:]:
|
||||
for r in self._cssRules[index:]:
|
||||
if r.type in (r.CHARSET_RULE, r.IMPORT_RULE):
|
||||
self._log.error(
|
||||
u'CSSStylesheet: Cannot insert @namespace here, found @charset or @import after index %s.' %
|
||||
@@ -570,7 +581,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
||||
error=xml.dom.HierarchyRequestErr)
|
||||
return
|
||||
# before @media and stylerule
|
||||
for r in self.cssRules[:index]:
|
||||
for r in self._cssRules[:index]:
|
||||
if r.type in (r.MEDIA_RULE, r.PAGE_RULE, r.STYLE_RULE,
|
||||
r.FONT_FACE_RULE):
|
||||
self._log.error(
|
||||
@@ -582,7 +593,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
||||
if not (rule.prefix in self.namespaces and
|
||||
self.namespaces[rule.prefix] == rule.namespaceURI):
|
||||
# no doublettes
|
||||
self.cssRules.insert(index, rule)
|
||||
self._cssRules.insert(index, rule)
|
||||
if _clean:
|
||||
self._cleanNamespaces()
|
||||
|
||||
@@ -590,17 +601,17 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
||||
else:
|
||||
if inOrder:
|
||||
# simply add to end as no specific order
|
||||
self.cssRules.append(rule)
|
||||
index = len(self.cssRules) - 1
|
||||
self._cssRules.append(rule)
|
||||
index = len(self._cssRules) - 1
|
||||
else:
|
||||
for r in self.cssRules[index:]:
|
||||
for r in self._cssRules[index:]:
|
||||
if r.type in (r.CHARSET_RULE, r.IMPORT_RULE, r.NAMESPACE_RULE):
|
||||
self._log.error(
|
||||
u'CSSStylesheet: Cannot insert rule here, found @charset, @import or @namespace before index %s.' %
|
||||
index,
|
||||
error=xml.dom.HierarchyRequestErr)
|
||||
return
|
||||
self.cssRules.insert(index, rule)
|
||||
self._cssRules.insert(index, rule)
|
||||
|
||||
# post settings, TODO: for other rules which contain @rules
|
||||
rule._parentStyleSheet = self
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"""
|
||||
__all__ = ['CSSValue', 'CSSPrimitiveValue', 'CSSValueList', 'RGBColor']
|
||||
__docformat__ = 'restructuredtext'
|
||||
__version__ = '$Id: cssvalue.py 1684 2009-03-01 18:26:21Z cthedot $'
|
||||
__version__ = '$Id: cssvalue.py 1834 2009-08-02 12:20:21Z cthedot $'
|
||||
|
||||
from cssutils.prodparser import *
|
||||
import cssutils
|
||||
@@ -81,6 +81,7 @@ class CSSValue(cssutils.util._NewBase):
|
||||
[ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* |
|
||||
TIME S* | FREQ S* ]
|
||||
| STRING S* | IDENT S* | URI S* | hexcolor | function
|
||||
| UNICODE-RANGE S*
|
||||
;
|
||||
function
|
||||
: FUNCTION S* expr ')' S*
|
||||
@@ -108,7 +109,7 @@ class CSSValue(cssutils.util._NewBase):
|
||||
|
||||
# used as operator is , / or S
|
||||
nextSor = u',/'
|
||||
|
||||
|
||||
term = Choice(Sequence(PreDef.unary(),
|
||||
Choice(PreDef.number(nextSor=nextSor),
|
||||
PreDef.percentage(nextSor=nextSor),
|
||||
@@ -117,22 +118,25 @@ class CSSValue(cssutils.util._NewBase):
|
||||
PreDef.ident(nextSor=nextSor),
|
||||
PreDef.uri(nextSor=nextSor),
|
||||
PreDef.hexcolor(nextSor=nextSor),
|
||||
PreDef.unicode_range(nextSor=nextSor),
|
||||
# special case IE only expression
|
||||
Prod(name='expression',
|
||||
match=lambda t, v: t == self._prods.FUNCTION and
|
||||
match=lambda t, v: t == self._prods.FUNCTION and (
|
||||
cssutils.helper.normalize(v) in (u'expression(',
|
||||
u'alpha('),
|
||||
u'alpha(') or
|
||||
v.startswith(u'progid:DXImageTransform.Microsoft.') ),
|
||||
nextSor=nextSor,
|
||||
toSeq=lambda t, tokens: (ExpressionValue.name,
|
||||
ExpressionValue(cssutils.helper.pushtoken(t,
|
||||
tokens)))),
|
||||
tokens)))
|
||||
),
|
||||
PreDef.function(nextSor=nextSor,
|
||||
toSeq=lambda t, tokens: ('FUNCTION',
|
||||
CSSFunction(cssutils.helper.pushtoken(t,
|
||||
tokens)))))
|
||||
operator = Choice(PreDef.S(optional=False, mayEnd=True),
|
||||
PreDef.CHAR('comma', ',', toSeq=lambda t, tokens: ('operator', t[1])),
|
||||
PreDef.CHAR('slash', '/', toSeq=lambda t, tokens: ('operator', t[1])),
|
||||
operator = Choice(PreDef.S(),
|
||||
PreDef.char('comma', ',', toSeq=lambda t, tokens: ('operator', t[1])),
|
||||
PreDef.char('slash', '/', toSeq=lambda t, tokens: ('operator', t[1])),
|
||||
optional=True)
|
||||
# CSSValue PRODUCTIONS
|
||||
valueprods = Sequence(term,
|
||||
@@ -154,19 +158,22 @@ class CSSValue(cssutils.util._NewBase):
|
||||
item = seq[i]
|
||||
if item.type == self._prods.S:
|
||||
pass
|
||||
elif item.value == u',' and item.type not in (self._prods.URI, self._prods.STRING):
|
||||
# counts as a single one
|
||||
|
||||
elif (item.value, item.type) == (u',', 'operator'):
|
||||
# , separared counts as a single STRING for now
|
||||
# URI or STRING value might be a single CHAR too!
|
||||
newseq.appendItem(item)
|
||||
if firstvalue:
|
||||
# may be IDENT or STRING but with , it is always STRING
|
||||
firstvalue = firstvalue[0], 'STRING'
|
||||
# each comma separated list counts as a single one only
|
||||
count -= 1
|
||||
if firstvalue:
|
||||
# list of IDENTs is handled as STRING!
|
||||
if firstvalue[1] == self._prods.IDENT:
|
||||
firstvalue = firstvalue[0], 'STRING'
|
||||
|
||||
elif item.value == u'/':
|
||||
# counts as a single one
|
||||
# / separated items count as one
|
||||
newseq.appendItem(item)
|
||||
|
||||
elif item.value == u'+' or item.value == u'-':
|
||||
elif item.value == u'-' or item.value == u'+':
|
||||
# combine +- and following number or other
|
||||
i += 1
|
||||
try:
|
||||
@@ -187,12 +194,12 @@ class CSSValue(cssutils.util._NewBase):
|
||||
if not firstvalue:
|
||||
firstvalue = (item.value, item.type)
|
||||
count += 1
|
||||
|
||||
|
||||
else:
|
||||
newseq.appendItem(item)
|
||||
|
||||
i += 1
|
||||
|
||||
|
||||
if not firstvalue:
|
||||
self._log.error(
|
||||
u'CSSValue: Unknown syntax or no value: %r.' %
|
||||
@@ -201,7 +208,7 @@ class CSSValue(cssutils.util._NewBase):
|
||||
# ok and set
|
||||
self._setSeq(newseq)
|
||||
self.wellformed = wellformed
|
||||
|
||||
|
||||
if hasattr(self, '_value'):
|
||||
# only in case of CSSPrimitiveValue, else remove!
|
||||
del self._value
|
||||
@@ -228,6 +235,8 @@ class CSSValue(cssutils.util._NewBase):
|
||||
return cssutils.helper.string(item.value)
|
||||
elif self._prods.URI == item.type:
|
||||
return cssutils.helper.uri(item.value)
|
||||
elif self._prods.FUNCTION == item.type:
|
||||
return item.value.cssText
|
||||
else:
|
||||
return item.value
|
||||
|
||||
@@ -253,7 +262,8 @@ class CSSValue(cssutils.util._NewBase):
|
||||
self._prods.NUMBER,
|
||||
self._prods.PERCENTAGE,
|
||||
self._prods.STRING,
|
||||
self._prods.URI):
|
||||
self._prods.URI,
|
||||
self._prods.UNICODE_RANGE):
|
||||
if nexttocommalist:
|
||||
# wait until complete
|
||||
commalist.append(itemValue(item))
|
||||
@@ -353,6 +363,7 @@ class CSSPrimitiveValue(CSSValue):
|
||||
CSS_RGBCOLOR = 25
|
||||
# NOT OFFICIAL:
|
||||
CSS_RGBACOLOR = 26
|
||||
CSS_UNICODE_RANGE = 27
|
||||
|
||||
_floattypes = (CSS_NUMBER, CSS_PERCENTAGE, CSS_EMS, CSS_EXS,
|
||||
CSS_PX, CSS_CM, CSS_MM, CSS_IN, CSS_PT, CSS_PC,
|
||||
@@ -426,9 +437,10 @@ class CSSPrimitiveValue(CSSValue):
|
||||
'CSS_MS', 'CSS_S',
|
||||
'CSS_HZ', 'CSS_KHZ',
|
||||
'CSS_DIMENSION',
|
||||
'CSS_STRING', 'CSS_URI', 'CSS_IDENT',
|
||||
'CSS_STRING', 'CSS_URI', 'CSS_IDENT',
|
||||
'CSS_ATTR', 'CSS_COUNTER', 'CSS_RECT',
|
||||
'CSS_RGBCOLOR', 'CSS_RGBACOLOR',
|
||||
'CSS_UNICODE_RANGE'
|
||||
]
|
||||
|
||||
_reNumDim = re.compile(ur'([+-]?\d*\.\d+|[+-]?\d+)(.*)$', re.I| re.U|re.X)
|
||||
@@ -464,6 +476,7 @@ class CSSPrimitiveValue(CSSValue):
|
||||
__types.NUMBER: 'CSS_NUMBER',
|
||||
__types.PERCENTAGE: 'CSS_PERCENTAGE',
|
||||
__types.STRING: 'CSS_STRING',
|
||||
__types.UNICODE_RANGE: 'CSS_UNICODE_RANGE',
|
||||
__types.URI: 'CSS_URI',
|
||||
__types.IDENT: 'CSS_IDENT',
|
||||
__types.HASH: 'CSS_RGBCOLOR',
|
||||
@@ -474,7 +487,6 @@ class CSSPrimitiveValue(CSSValue):
|
||||
def __set_primitiveType(self):
|
||||
"""primitiveType is readonly but is set lazy if accessed"""
|
||||
# TODO: check unary and font-family STRING a, b, "c"
|
||||
|
||||
val, type_ = self._value
|
||||
# try get by type_
|
||||
pt = self.__unitbytype.get(type_, 'CSS_UNKNOWN')
|
||||
@@ -827,7 +839,7 @@ class CSSFunction(CSSPrimitiveValue):
|
||||
types.PERCENTAGE,
|
||||
types.STRING),
|
||||
toSeq=lambda t, tokens: (t[0], CSSPrimitiveValue(t[1])))
|
||||
|
||||
|
||||
funcProds = Sequence(Prod(name='FUNC',
|
||||
match=lambda t, v: t == types.FUNCTION,
|
||||
toSeq=lambda t, tokens: (t[0], cssutils.helper.normalize(t[1]))),
|
||||
@@ -969,23 +981,31 @@ class RGBColor(CSSPrimitiveValue):
|
||||
|
||||
class ExpressionValue(CSSFunction):
|
||||
"""Special IE only CSSFunction which may contain *anything*.
|
||||
Used for expressions and ``alpha(opacity=100)`` currently"""
|
||||
Used for expressions and ``alpha(opacity=100)`` currently."""
|
||||
name = u'Expression (IE only)'
|
||||
|
||||
def _productiondefinition(self):
|
||||
"""Return defintion used for parsing."""
|
||||
types = self._prods # rename!
|
||||
|
||||
def toSeq(t, tokens):
|
||||
"Do not normalize function name!"
|
||||
return t[0], t[1]
|
||||
|
||||
funcProds = Sequence(Prod(name='expression',
|
||||
match=lambda t, v: t == types.FUNCTION,
|
||||
toSeq=lambda t, tokens: (t[0], cssutils.helper.normalize(t[1]))),
|
||||
toSeq=toSeq
|
||||
),
|
||||
Sequence(Choice(Prod(name='nested function',
|
||||
match=lambda t, v: t == self._prods.FUNCTION,
|
||||
toSeq=lambda t, tokens: (CSSFunction.name,
|
||||
CSSFunction(cssutils.helper.pushtoken(t,
|
||||
tokens)))),
|
||||
tokens)))
|
||||
),
|
||||
Prod(name='part',
|
||||
match=lambda t, v: v != u')',
|
||||
toSeq=lambda t, tokens: (t[0], t[1])), ),
|
||||
toSeq=lambda t, tokens: (t[0], t[1])),
|
||||
),
|
||||
minmax=lambda: (0, None)),
|
||||
PreDef.funcEnd(stop=True))
|
||||
return funcProds
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Property is a single CSS property in a CSSStyleDeclaration."""
|
||||
__all__ = ['Property']
|
||||
__docformat__ = 'restructuredtext'
|
||||
__version__ = '$Id: property.py 1685 2009-03-01 18:26:48Z cthedot $'
|
||||
__version__ = '$Id: property.py 1811 2009-07-29 13:11:15Z cthedot $'
|
||||
|
||||
from cssutils.helper import Deprecated
|
||||
from cssvalue import CSSValue
|
||||
@@ -44,7 +44,7 @@ class Property(cssutils.util.Base):
|
||||
|
||||
"""
|
||||
def __init__(self, name=None, value=None, priority=u'',
|
||||
_mediaQuery=False, _parent=None):
|
||||
_mediaQuery=False, parent=None, parentStyle=None):
|
||||
"""
|
||||
:param name:
|
||||
a property name string (will be normalized)
|
||||
@@ -55,16 +55,17 @@ class Property(cssutils.util.Base):
|
||||
u'!important' or u'important'
|
||||
:param _mediaQuery:
|
||||
if ``True`` value is optional (used by MediaQuery)
|
||||
:param _parent:
|
||||
:param parent:
|
||||
the parent object, normally a
|
||||
:class:`cssutils.css.CSSStyleDeclaration`
|
||||
:param parentStyle:
|
||||
DEPRECATED: Use ``parent`` instead
|
||||
"""
|
||||
super(Property, self).__init__()
|
||||
|
||||
self.seqs = [[], None, []]
|
||||
self.wellformed = False
|
||||
self._mediaQuery = _mediaQuery
|
||||
self._parent = _parent
|
||||
self.parent = parent
|
||||
|
||||
self.__nametoken = None
|
||||
self._name = u''
|
||||
@@ -363,13 +364,18 @@ class Property(cssutils.util.Base):
|
||||
literalpriority = property(lambda self: self._literalpriority,
|
||||
doc="Readonly literal (not normalized) priority of this property")
|
||||
|
||||
def validate(self, profiles=None):
|
||||
"""Validate value against `profiles`.
|
||||
def _setParent(self, parent):
|
||||
self._parent = parent
|
||||
|
||||
parent = property(lambda self: self._parent, _setParent,
|
||||
doc="The Parent Node (normally a CSSStyledeclaration) of this "
|
||||
"Property")
|
||||
|
||||
def validate(self):
|
||||
"""Validate value against `profiles` which are checked dynamically.
|
||||
properties in e.g. @font-face rules are checked against
|
||||
``cssutils.profile.CSS3_FONT_FACE`` only.
|
||||
|
||||
:param profiles:
|
||||
A list of profile names used for validating. If no `profiles`
|
||||
is given ``cssutils.profile.defaultProfiles`` is used
|
||||
|
||||
For each of the following cases a message is reported:
|
||||
|
||||
- INVALID (so the property is known but not valid)
|
||||
@@ -424,6 +430,16 @@ class Property(cssutils.util.Base):
|
||||
"""
|
||||
valid = False
|
||||
|
||||
profiles = None
|
||||
try:
|
||||
# if @font-face use that profile
|
||||
rule = self.parent.parentRule
|
||||
if rule.type == rule.FONT_FACE_RULE:
|
||||
profiles = [cssutils.profile.CSS3_FONT_FACE]
|
||||
#TODO: same for @page
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
if self.name and self.value:
|
||||
|
||||
if self.name in cssutils.profile.knownNames:
|
||||
@@ -467,3 +483,12 @@ class Property(cssutils.util.Base):
|
||||
|
||||
valid = property(validate, doc="Check if value of this property is valid "
|
||||
"in the properties context.")
|
||||
|
||||
|
||||
@Deprecated('Use ``parent`` attribute instead.')
|
||||
def _getParentStyle(self):
|
||||
return self._parent
|
||||
|
||||
parentStyle = property(_getParentStyle, _setParent,
|
||||
doc="DEPRECATED: Use ``parent`` instead")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user