summaryrefslogtreecommitdiffstats
path: root/WebCore/css/CSSStyleSelector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/css/CSSStyleSelector.cpp')
-rw-r--r--WebCore/css/CSSStyleSelector.cpp383
1 files changed, 249 insertions, 134 deletions
diff --git a/WebCore/css/CSSStyleSelector.cpp b/WebCore/css/CSSStyleSelector.cpp
index aa724a3..a75dede 100644
--- a/WebCore/css/CSSStyleSelector.cpp
+++ b/WebCore/css/CSSStyleSelector.cpp
@@ -49,7 +49,6 @@
#include "CSSVariablesRule.h"
#include "CachedImage.h"
#include "Counter.h"
-#include "CounterContent.h"
#include "FocusController.h"
#include "FontFamilyValue.h"
#include "FontValue.h"
@@ -83,6 +82,7 @@
#include "ShadowValue.h"
#include "SkewTransformOperation.h"
#include "StyleCachedImage.h"
+#include "StylePendingImage.h"
#include "StyleGeneratedImage.h"
#include "StyleSheetList.h"
#include "Text.h"
@@ -199,12 +199,12 @@ if (value->isValueList()) { \
currChild = new FillLayer(LayerType##FillLayer); \
prevChild->setNext(currChild); \
} \
- mapFill##Prop(currChild, valueList->itemWithoutBoundsCheck(i)); \
+ mapFill##Prop(property, currChild, valueList->itemWithoutBoundsCheck(i)); \
prevChild = currChild; \
currChild = currChild->next(); \
} \
} else { \
- mapFill##Prop(currChild, value); \
+ mapFill##Prop(property, currChild, value); \
currChild = currChild->next(); \
} \
while (currChild) { \
@@ -370,15 +370,15 @@ public:
CSSRuleDataList* getIDRules(AtomicStringImpl* key) { return m_idRules.get(key); }
CSSRuleDataList* getClassRules(AtomicStringImpl* key) { return m_classRules.get(key); }
CSSRuleDataList* getTagRules(AtomicStringImpl* key) { return m_tagRules.get(key); }
- CSSRuleDataList* getUniversalRules() { return m_universalRules; }
- CSSRuleDataList* getPageRules() { return m_pageRules; }
+ CSSRuleDataList* getUniversalRules() { return m_universalRules.get(); }
+ CSSRuleDataList* getPageRules() { return m_pageRules.get(); }
public:
AtomRuleMap m_idRules;
AtomRuleMap m_classRules;
AtomRuleMap m_tagRules;
- CSSRuleDataList* m_universalRules;
- CSSRuleDataList* m_pageRules;
+ OwnPtr<CSSRuleDataList> m_universalRules;
+ OwnPtr<CSSRuleDataList> m_pageRules;
unsigned m_ruleCount;
unsigned m_pageRuleCount;
};
@@ -413,21 +413,19 @@ static const MediaQueryEvaluator& printEval()
return staticPrintEval;
}
-CSSStyleSelector::CSSStyleSelector(Document* doc, StyleSheetList* styleSheets, CSSStyleSheet* mappedElementSheet,
+CSSStyleSelector::CSSStyleSelector(Document* document, StyleSheetList* styleSheets, CSSStyleSheet* mappedElementSheet,
CSSStyleSheet* pageUserSheet, const Vector<RefPtr<CSSStyleSheet> >* pageGroupUserSheets,
bool strictParsing, bool matchAuthorAndUserStyles)
: m_backgroundData(BackgroundFillLayer)
- , m_checker(doc, strictParsing)
+ , m_checker(document, strictParsing)
, m_element(0)
, m_styledElement(0)
, m_elementLinkState(NotInsideLink)
- , m_fontSelector(CSSFontSelector::create(doc))
+ , m_fontSelector(CSSFontSelector::create(document))
{
- init();
-
m_matchAuthorAndUserStyles = matchAuthorAndUserStyles;
- Element* root = doc->documentElement();
+ Element* root = document->documentElement();
if (!defaultStyle) {
if (!root || elementCanUseSimpleDefaultStyle(root))
@@ -436,32 +434,28 @@ CSSStyleSelector::CSSStyleSelector(Document* doc, StyleSheetList* styleSheets, C
loadFullDefaultStyle();
}
- m_userStyle = 0;
-
// construct document root element default style. this is needed
// to evaluate media queries that contain relative constraints, like "screen and (max-width: 10em)"
// This is here instead of constructor, because when constructor is run,
// document doesn't have documentElement
// NOTE: this assumes that element that gets passed to styleForElement -call
// is always from the document that owns the style selector
- FrameView* view = doc->view();
+ FrameView* view = document->view();
if (view)
- m_medium = new MediaQueryEvaluator(view->mediaType());
+ m_medium = adoptPtr(new MediaQueryEvaluator(view->mediaType()));
else
- m_medium = new MediaQueryEvaluator("all");
+ m_medium = adoptPtr(new MediaQueryEvaluator("all"));
if (root)
m_rootDefaultStyle = styleForElement(root, 0, false, true); // don't ref, because the RenderStyle is allocated from global heap
- if (m_rootDefaultStyle && view) {
- delete m_medium;
- m_medium = new MediaQueryEvaluator(view->mediaType(), view->frame(), m_rootDefaultStyle.get());
- }
+ if (m_rootDefaultStyle && view)
+ m_medium = adoptPtr(new MediaQueryEvaluator(view->mediaType(), view->frame(), m_rootDefaultStyle.get()));
- m_authorStyle = new CSSRuleSet();
+ m_authorStyle = adoptPtr(new CSSRuleSet);
// FIXME: This sucks! The user sheet is reparsed every time!
- OwnPtr<CSSRuleSet> tempUserStyle(new CSSRuleSet);
+ OwnPtr<CSSRuleSet> tempUserStyle = adoptPtr(new CSSRuleSet);
if (pageUserSheet)
tempUserStyle->addRulesFromSheet(pageUserSheet, *m_medium, this);
if (pageGroupUserSheets) {
@@ -475,7 +469,7 @@ CSSStyleSelector::CSSStyleSelector(Document* doc, StyleSheetList* styleSheets, C
}
if (tempUserStyle->m_ruleCount > 0 || tempUserStyle->m_pageRuleCount > 0)
- m_userStyle = tempUserStyle.leakPtr();
+ m_userStyle = tempUserStyle.release();
// Add rules from elements like SVG's <font-face>
if (mappedElementSheet)
@@ -489,8 +483,8 @@ CSSStyleSelector::CSSStyleSelector(Document* doc, StyleSheetList* styleSheets, C
m_authorStyle->addRulesFromSheet(static_cast<CSSStyleSheet*>(sheet), *m_medium, this);
}
- if (doc->renderer() && doc->renderer()->style())
- doc->renderer()->style()->font().update(fontSelector());
+ if (document->renderer() && document->renderer()->style())
+ document->renderer()->style()->font().update(fontSelector());
}
// This is a simplified style setting function for keyframe styles
@@ -500,23 +494,10 @@ void CSSStyleSelector::addKeyframeStyle(PassRefPtr<WebKitCSSKeyframesRule> rule)
m_keyframesRuleMap.add(s.impl(), rule);
}
-void CSSStyleSelector::init()
-{
- initElement(0);
- m_matchedDecls.clear();
- m_ruleList = 0;
- m_rootDefaultStyle = 0;
- m_medium = 0;
-}
-
CSSStyleSelector::~CSSStyleSelector()
{
m_fontSelector->clearDocument();
- delete m_medium;
- delete m_authorStyle;
- delete m_userStyle;
deleteAllValues(m_viewportDependentMediaQueryResults);
- m_keyframesRuleMap.clear();
}
static CSSStyleSheet* parseUASheet(const String& str)
@@ -556,6 +537,14 @@ static void loadFullDefaultStyle()
String quirksRules = String(quirksUserAgentStyleSheet, sizeof(quirksUserAgentStyleSheet)) + RenderTheme::defaultTheme()->extraQuirksStyleSheet();
CSSStyleSheet* quirksSheet = parseUASheet(quirksRules);
defaultQuirksStyle->addRulesFromSheet(quirksSheet, screenEval());
+
+#if ENABLE(FULLSCREEN_API)
+ // Full-screen rules.
+ String fullscreenRules = String(fullscreenUserAgentStyleSheet, sizeof(fullscreenUserAgentStyleSheet)) + RenderTheme::defaultTheme()->extraDefaultStyleSheet();
+ CSSStyleSheet* fullscreenSheet = parseUASheet(fullscreenRules);
+ defaultStyle->addRulesFromSheet(fullscreenSheet, screenEval());
+ defaultQuirksStyle->addRulesFromSheet(fullscreenSheet, screenEval());
+#endif
}
static void loadSimpleDefaultStyle()
@@ -855,6 +844,8 @@ inline void CSSStyleSelector::initForStyleResolve(Element* e, RenderStyle* paren
m_matchedDecls.clear();
+ m_pendingImageProperties.clear();
+
m_ruleList = 0;
m_fontDirty = false;
@@ -1135,8 +1126,6 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForDocument(Document* document)
documentStyle->setFontDescription(fontDescription);
documentStyle->font().update(0);
- if (document->inCompatMode())
- documentStyle->setHtmlHacks(true); // enable html specific rendering tricks
return documentStyle.release();
}
@@ -1258,7 +1247,7 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* e, RenderStyl
if (!resolveForRootDefault) {
// 4. Now we check user sheet rules.
if (m_matchAuthorAndUserStyles)
- matchRules(m_userStyle, firstUserRule, lastUserRule);
+ matchRules(m_userStyle.get(), firstUserRule, lastUserRule);
// 5. Now check author rules, beginning first with presentational attributes
// mapped from HTML.
@@ -1297,7 +1286,7 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* e, RenderStyl
// 6. Check the rules in author sheets next.
if (m_matchAuthorAndUserStyles)
- matchRules(m_authorStyle, firstAuthorRule, lastAuthorRule);
+ matchRules(m_authorStyle.get(), firstAuthorRule, lastAuthorRule);
// 7. Now check our inline style attribute.
if (m_matchAuthorAndUserStyles && m_styledElement) {
@@ -1347,7 +1336,8 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* e, RenderStyl
applyDeclarations<false>(true, firstUserRule, lastUserRule);
}
applyDeclarations<false>(true, firstUARule, lastUARule);
-
+
+ ASSERT(!m_fontDirty);
// If our font got dirtied by one of the non-essential font props,
// go ahead and update it a second time.
if (m_fontDirty)
@@ -1356,6 +1346,9 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* e, RenderStyl
// Clean up our style object's display and text decorations (among other fixups).
adjustRenderStyle(style(), e);
+ // Start loading images referenced by this style.
+ loadPendingImages();
+
// If we have first-letter pseudo style, do not share this style
if (m_style->hasPseudoStyle(FIRST_LETTER))
m_style->setUnique();
@@ -1380,7 +1373,7 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForElement(Element* e, RenderStyl
return m_style.release();
}
-PassRefPtr<RenderStyle> CSSStyleSelector::styleForKeyframe(const RenderStyle* elementStyle, const WebKitCSSKeyframeRule* keyframeRule, KeyframeList& list)
+PassRefPtr<RenderStyle> CSSStyleSelector::styleForKeyframe(const RenderStyle* elementStyle, const WebKitCSSKeyframeRule* keyframeRule, KeyframeValue& keyframe)
{
if (keyframeRule->style())
addMatchedDeclaration(keyframeRule->style());
@@ -1414,7 +1407,10 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForKeyframe(const RenderStyle* el
if (m_fontDirty)
updateFont();
- // Add all the animating properties to the list
+ // Start loading images referenced by this style.
+ loadPendingImages();
+
+ // Add all the animating properties to the keyframe.
if (keyframeRule->style()) {
CSSMutableStyleDeclaration::const_iterator end = keyframeRule->style()->end();
for (CSSMutableStyleDeclaration::const_iterator it = keyframeRule->style()->begin(); it != end; ++it) {
@@ -1422,7 +1418,7 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForKeyframe(const RenderStyle* el
// Timing-function within keyframes is special, because it is not animated; it just
// describes the timing function between this keyframe and the next.
if (property != CSSPropertyWebkitAnimationTimingFunction)
- list.addProperty(property);
+ keyframe.addProperty(property);
}
}
@@ -1443,7 +1439,6 @@ void CSSStyleSelector::keyframeStylesForAnimation(Element* e, const RenderStyle*
return;
const WebKitCSSKeyframesRule* rule = m_keyframesRuleMap.find(list.animationName().impl()).get()->second.get();
- RefPtr<RenderStyle> keyframeStyle;
// Construct and populate the style for each keyframe
for (unsigned i = 0; i < rule->length(); ++i) {
@@ -1452,34 +1447,36 @@ void CSSStyleSelector::keyframeStylesForAnimation(Element* e, const RenderStyle*
initForStyleResolve(e);
const WebKitCSSKeyframeRule* keyframeRule = rule->item(i);
-
- keyframeStyle = styleForKeyframe(elementStyle, keyframeRule, list);
+
+ KeyframeValue keyframe(0, 0);
+ keyframe.setStyle(styleForKeyframe(elementStyle, keyframeRule, keyframe));
// Add this keyframe style to all the indicated key times
Vector<float> keys;
keyframeRule->getKeys(keys);
for (size_t keyIndex = 0; keyIndex < keys.size(); ++keyIndex) {
- float key = keys[keyIndex];
- list.insert(key, keyframeStyle.get());
+ keyframe.setKey(keys[keyIndex]);
+ list.insert(keyframe);
}
- keyframeStyle.release();
}
// If the 0% keyframe is missing, create it (but only if there is at least one other keyframe)
int initialListSize = list.size();
- if (initialListSize > 0 && list.beginKeyframes()->key() != 0) {
- RefPtr<WebKitCSSKeyframeRule> keyframe = WebKitCSSKeyframeRule::create();
- keyframe->setKeyText("0%");
- keyframeStyle = styleForKeyframe(elementStyle, keyframe.get(), list);
- list.insert(0, keyframeStyle.release());
+ if (initialListSize > 0 && list[0].key() != 0) {
+ RefPtr<WebKitCSSKeyframeRule> keyframeRule = WebKitCSSKeyframeRule::create();
+ keyframeRule->setKeyText("0%");
+ KeyframeValue keyframe(0, 0);
+ keyframe.setStyle(styleForKeyframe(elementStyle, keyframeRule.get(), keyframe));
+ list.insert(keyframe);
}
// If the 100% keyframe is missing, create it (but only if there is at least one other keyframe)
- if (initialListSize > 0 && (list.endKeyframes() - 1)->key() != 1) {
- RefPtr<WebKitCSSKeyframeRule> keyframe = WebKitCSSKeyframeRule::create();
- keyframe->setKeyText("100%");
- keyframeStyle = styleForKeyframe(elementStyle, keyframe.get(), list);
- list.insert(1, keyframeStyle.release());
+ if (initialListSize > 0 && (list[list.size() - 1].key() != 1)) {
+ RefPtr<WebKitCSSKeyframeRule> keyframeRule = WebKitCSSKeyframeRule::create();
+ keyframeRule->setKeyText("100%");
+ KeyframeValue keyframe(1, 0);
+ keyframe.setStyle(styleForKeyframe(elementStyle, keyframeRule.get(), keyframe));
+ list.insert(keyframe);
}
}
@@ -1518,8 +1515,8 @@ PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForElement(PseudoId pseudo,
matchUARules(firstUARule, lastUARule);
if (m_matchAuthorAndUserStyles) {
- matchRules(m_userStyle, firstUserRule, lastUserRule);
- matchRules(m_authorStyle, firstAuthorRule, lastAuthorRule);
+ matchRules(m_userStyle.get(), firstUserRule, lastUserRule);
+ matchRules(m_authorStyle.get(), firstAuthorRule, lastAuthorRule);
}
if (m_matchedDecls.isEmpty() && !visitedStyle)
@@ -1569,6 +1566,9 @@ PassRefPtr<RenderStyle> CSSStyleSelector::pseudoStyleForElement(PseudoId pseudo,
// Clean up our style object's display and text decorations (among other fixups).
adjustRenderStyle(style(), 0);
+ // Start loading images referenced by this style.
+ loadPendingImages();
+
// Hang our visited style off m_style.
if (visitedStyle)
m_style->addCachedPseudoStyle(visitedStyle.release());
@@ -1588,8 +1588,8 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForPage(int pageIndex)
const bool isFirst = isFirstPage(pageIndex);
const String page = pageName(pageIndex);
matchPageRules(defaultPrintStyle, isLeft, isFirst, page);
- matchPageRules(m_userStyle, isLeft, isFirst, page);
- matchPageRules(m_authorStyle, isLeft, isFirst, page);
+ matchPageRules(m_userStyle.get(), isLeft, isFirst, page);
+ matchPageRules(m_authorStyle.get(), isLeft, isFirst, page);
m_lineHeightValue = 0;
applyDeclarations<true>(false, 0, m_matchedDecls.size() - 1);
@@ -1603,6 +1603,9 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForPage(int pageIndex)
applyDeclarations<false>(false, 0, m_matchedDecls.size() - 1);
+ // Start loading images referenced by this style.
+ loadPendingImages();
+
// Now return the style.
return m_style.release();
}
@@ -1865,14 +1868,14 @@ PassRefPtr<CSSRuleList> CSSStyleSelector::pseudoStyleRulesForElement(Element* e,
// Now we check user sheet rules.
if (m_matchAuthorAndUserStyles) {
int firstUserRule = -1, lastUserRule = -1;
- matchRules(m_userStyle, firstUserRule, lastUserRule);
+ matchRules(m_userStyle.get(), firstUserRule, lastUserRule);
}
}
if (m_matchAuthorAndUserStyles) {
// Check the rules in author sheets.
int firstAuthorRule = -1, lastAuthorRule = -1;
- matchRules(m_authorStyle, firstAuthorRule, lastAuthorRule);
+ matchRules(m_authorStyle.get(), firstAuthorRule, lastAuthorRule);
}
m_checker.m_collectRulesOnly = false;
@@ -2598,22 +2601,7 @@ bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Eleme
return true;
break;
case CSSSelector::PseudoLang: {
- Node* n = e;
- AtomicString value;
- // The language property is inherited, so we iterate over the parents
- // to find the first language.
- while (n && value.isNull()) {
- if (n->isElementNode()) {
- // Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7
- value = static_cast<Element*>(n)->fastGetAttribute(XMLNames::langAttr);
- if (value.isNull())
- value = static_cast<Element*>(n)->fastGetAttribute(langAttr);
- } else if (n->isDocumentNode())
- // checking the MIME content-language
- value = static_cast<Document*>(n)->contentLanguage();
-
- n = n->parent();
- }
+ AtomicString value = e->computeInheritedLanguage();
const AtomicString& argument = sel->argument();
if (value.isEmpty() || !value.startsWith(argument, false))
break;
@@ -2621,6 +2609,26 @@ bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Eleme
break;
return true;
}
+#if ENABLE(FULLSCREEN_API)
+ case CSSSelector::PseudoFullScreen:
+ // While a Document is in the fullscreen state, and the document's current fullscreen
+ // element is an element in the document, the 'full-screen' pseudoclass applies to
+ // that element. Also, an <iframe>, <object> or <embed> element whose child browsing
+ // context's Document is in the fullscreen state has the 'full-screen' pseudoclass applied.
+ if (!e->document()->webkitFullScreen())
+ return false;
+ if (e != e->document()->webkitCurrentFullScreenElement())
+ return false;
+ return true;
+ case CSSSelector::PseudoFullScreenDocument:
+ // While a Document is in the fullscreen state, the 'full-screen-document' pseudoclass applies
+ // to the root element of that Document.
+ if (!e->document()->webkitFullScreen())
+ return false;
+ if (e != e->document()->documentElement())
+ return false;
+ return true;
+#endif
case CSSSelector::PseudoUnknown:
case CSSSelector::PseudoNotParsed:
default:
@@ -2745,11 +2753,9 @@ CSSValue* CSSStyleSelector::resolveVariableDependentValue(CSSVariableDependentVa
// -----------------------------------------------------------------
CSSRuleSet::CSSRuleSet()
+ : m_ruleCount(0)
+ , m_pageRuleCount(0)
{
- m_universalRules = 0;
- m_pageRules = 0;
- m_ruleCount = 0;
- m_pageRuleCount = 0;
}
CSSRuleSet::~CSSRuleSet()
@@ -2757,9 +2763,6 @@ CSSRuleSet::~CSSRuleSet()
deleteAllValues(m_idRules);
deleteAllValues(m_classRules);
deleteAllValues(m_tagRules);
-
- delete m_universalRules;
- delete m_pageRules;
}
@@ -2794,7 +2797,7 @@ void CSSRuleSet::addRule(CSSStyleRule* rule, CSSSelector* sel)
// Just put it in the universal rule set.
if (!m_universalRules)
- m_universalRules = new CSSRuleDataList(m_ruleCount++, rule, sel);
+ m_universalRules = adoptPtr(new CSSRuleDataList(m_ruleCount++, rule, sel));
else
m_universalRules->append(m_ruleCount++, rule, sel);
}
@@ -2802,7 +2805,7 @@ void CSSRuleSet::addRule(CSSStyleRule* rule, CSSSelector* sel)
void CSSRuleSet::addPageRule(CSSStyleRule* rule, CSSSelector* sel)
{
if (!m_pageRules)
- m_pageRules = new CSSRuleDataList(m_pageRuleCount++, rule, sel);
+ m_pageRules = adoptPtr(new CSSRuleDataList(m_pageRuleCount++, rule, sel));
else
m_pageRules->append(m_pageRuleCount++, rule, sel);
}
@@ -2922,7 +2925,7 @@ void CSSStyleSelector::applyDeclarations(bool isImportant, int startIndex, int e
if (applyFirst) {
COMPILE_ASSERT(firstCSSProperty == CSSPropertyColor, CSS_color_is_first_property);
- COMPILE_ASSERT(CSSPropertyZoom == CSSPropertyColor + 11, CSS_zoom_is_end_of_first_prop_range);
+ COMPILE_ASSERT(CSSPropertyZoom == CSSPropertyColor + 12, CSS_zoom_is_end_of_first_prop_range);
COMPILE_ASSERT(CSSPropertyLineHeight == CSSPropertyZoom + 1, CSS_line_height_is_after_zoom);
// give special priority to font-xxx, color properties, etc
@@ -3120,7 +3123,8 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
// What follows is a list that maps the CSS properties into their corresponding front-end
// RenderStyle values. Shorthands (e.g. border, background) occur in this list as well and
// are only hit when mapping "inherit" or "initial" into front-end values.
- switch (static_cast<CSSPropertyID>(id)) {
+ CSSPropertyID property = static_cast<CSSPropertyID>(id);
+ switch (property) {
// ident only properties
case CSSPropertyBackgroundAttachment:
HANDLE_BACKGROUND_VALUE(attachment, Attachment, value)
@@ -3510,11 +3514,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
CSSCursorImageValue* image = static_cast<CSSCursorImageValue*>(primitiveValue);
if (image->updateIfSVGCursorIsUsed(m_element)) // Elements with SVG cursors are not allowed to share style.
m_style->setUnique();
- // FIXME: Temporary clumsiness to pass off a CachedImage to an API that will eventually convert to using
- // StyleImage.
- RefPtr<StyleCachedImage> styleCachedImage(image->cachedImage(m_element->document()->docLoader()));
- if (styleCachedImage)
- m_style->addCursor(styleCachedImage->cachedImage(), image->hotSpot());
+ m_style->addCursor(cachedOrPendingFromValue(CSSPropertyCursor, image), image->hotSpot());
} else if (type == CSSPrimitiveValue::CSS_IDENT)
m_style->setCursor(*primitiveValue);
}
@@ -3611,7 +3611,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
case CSSPropertyListStyleImage:
{
HANDLE_INHERIT_AND_INITIAL(listStyleImage, ListStyleImage)
- m_style->setListStyleImage(styleImage(value));
+ m_style->setListStyleImage(styleImage(CSSPropertyListStyleImage, value));
return;
}
@@ -4066,10 +4066,10 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
fontDescription.setKeywordSize(primitiveValue->getIdent() - CSSValueXxSmall + 1);
break;
case CSSValueLarger:
- size = largerFontSize(oldSize, m_style->htmlHacks());
+ size = largerFontSize(oldSize, m_checker.m_document->inQuirksMode());
break;
case CSSValueSmaller:
- size = smallerFontSize(oldSize, m_style->htmlHacks());
+ size = smallerFontSize(oldSize, m_checker.m_document->inQuirksMode());
break;
default:
return;
@@ -4273,16 +4273,15 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
break;
}
case CSSPrimitiveValue::CSS_URI: {
- CSSImageValue* image = static_cast<CSSImageValue*>(val);
- m_style->setContent(image->cachedImage(m_element->document()->docLoader()), didSet);
+ m_style->setContent(cachedOrPendingFromValue(CSSPropertyContent, static_cast<CSSImageValue*>(val)), didSet);
didSet = true;
break;
}
case CSSPrimitiveValue::CSS_COUNTER: {
Counter* counterValue = val->getCounterValue();
- CounterContent* counter = new CounterContent(counterValue->identifier(),
- (EListStyleType)counterValue->listStyleNumber(), counterValue->separator());
- m_style->setContent(counter, didSet);
+ OwnPtr<CounterContent> counter = adoptPtr(new CounterContent(counterValue->identifier(),
+ (EListStyleType)counterValue->listStyleNumber(), counterValue->separator()));
+ m_style->setContent(counter.release(), didSet);
didSet = true;
}
}
@@ -4701,7 +4700,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
}
NinePieceImage image;
- mapNinePieceImage(value, image);
+ mapNinePieceImage(property, value, image);
if (id == CSSPropertyWebkitBorderImage)
m_style->setBorderImage(image);
@@ -4751,17 +4750,26 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
if (!pair)
return;
- int width = pair->first()->computeLengthInt(style(), m_rootElementStyle, zoomFactor);
- int height = pair->second()->computeLengthInt(style(), m_rootElementStyle, zoomFactor);
+ Length radiusWidth;
+ Length radiusHeight;
+ if (pair->first()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
+ radiusWidth = Length(pair->first()->getDoubleValue(), Percent);
+ else
+ radiusWidth = Length(max(intMinForLength, min(intMaxForLength, pair->first()->computeLengthInt(style(), m_rootElementStyle, zoomFactor))), Fixed);
+ if (pair->second()->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)
+ radiusHeight = Length(pair->second()->getDoubleValue(), Percent);
+ else
+ radiusHeight = Length(max(intMinForLength, min(intMaxForLength, pair->second()->computeLengthInt(style(), m_rootElementStyle, zoomFactor))), Fixed);
+ int width = radiusWidth.rawValue();
+ int height = radiusHeight.rawValue();
if (width < 0 || height < 0)
return;
-
if (width == 0)
- height = 0; // Null out the other value.
+ radiusHeight = radiusWidth; // Null out the other value.
else if (height == 0)
- width = 0; // Null out the other value.
+ radiusWidth = radiusHeight; // Null out the other value.
- IntSize size(width, height);
+ LengthSize size(radiusWidth, radiusHeight);
switch (id) {
case CSSPropertyBorderTopLeftRadius:
m_style->setBorderTopLeftRadius(size);
@@ -4851,7 +4859,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
reflection->setOffset(Length(reflectValue->offset()->computeLengthIntForLength(style(), m_rootElementStyle, zoomFactor), Fixed));
}
NinePieceImage mask;
- mapNinePieceImage(reflectValue->mask(), mask);
+ mapNinePieceImage(property, reflectValue->mask(), mask);
reflection->setMask(mask);
m_style->setBoxReflect(reflection.release());
@@ -5820,7 +5828,7 @@ Length CSSStyleSelector::inchLength(double inch)
return Length(CSSPrimitiveValue::create(inch, CSSPrimitiveValue::CSS_IN)->computeLengthIntForLength(style(), m_rootElementStyle), Fixed);
}
-void CSSStyleSelector::mapFillAttachment(FillLayer* layer, CSSValue* value)
+void CSSStyleSelector::mapFillAttachment(CSSPropertyID, FillLayer* layer, CSSValue* value)
{
if (value->cssValueType() == CSSValue::CSS_INITIAL) {
layer->setAttachment(FillLayer::initialFillAttachment(layer->type()));
@@ -5846,7 +5854,7 @@ void CSSStyleSelector::mapFillAttachment(FillLayer* layer, CSSValue* value)
}
}
-void CSSStyleSelector::mapFillClip(FillLayer* layer, CSSValue* value)
+void CSSStyleSelector::mapFillClip(CSSPropertyID, FillLayer* layer, CSSValue* value)
{
if (value->cssValueType() == CSSValue::CSS_INITIAL) {
layer->setClip(FillLayer::initialFillClip(layer->type()));
@@ -5860,7 +5868,7 @@ void CSSStyleSelector::mapFillClip(FillLayer* layer, CSSValue* value)
layer->setClip(*primitiveValue);
}
-void CSSStyleSelector::mapFillComposite(FillLayer* layer, CSSValue* value)
+void CSSStyleSelector::mapFillComposite(CSSPropertyID, FillLayer* layer, CSSValue* value)
{
if (value->cssValueType() == CSSValue::CSS_INITIAL) {
layer->setComposite(FillLayer::initialFillComposite(layer->type()));
@@ -5874,7 +5882,7 @@ void CSSStyleSelector::mapFillComposite(FillLayer* layer, CSSValue* value)
layer->setComposite(*primitiveValue);
}
-void CSSStyleSelector::mapFillOrigin(FillLayer* layer, CSSValue* value)
+void CSSStyleSelector::mapFillOrigin(CSSPropertyID, FillLayer* layer, CSSValue* value)
{
if (value->cssValueType() == CSSValue::CSS_INITIAL) {
layer->setOrigin(FillLayer::initialFillOrigin(layer->type()));
@@ -5888,26 +5896,36 @@ void CSSStyleSelector::mapFillOrigin(FillLayer* layer, CSSValue* value)
layer->setOrigin(*primitiveValue);
}
-StyleImage* CSSStyleSelector::styleImage(CSSValue* value)
+StyleImage* CSSStyleSelector::styleImage(CSSPropertyID property, CSSValue* value)
{
if (value->isImageValue())
- return static_cast<CSSImageValue*>(value)->cachedImage(m_element->document()->docLoader());
+ return cachedOrPendingFromValue(property, static_cast<CSSImageValue*>(value));
+
if (value->isImageGeneratorValue())
return static_cast<CSSImageGeneratorValue*>(value)->generatedImage();
+
return 0;
}
-void CSSStyleSelector::mapFillImage(FillLayer* layer, CSSValue* value)
+StyleImage* CSSStyleSelector::cachedOrPendingFromValue(CSSPropertyID property, CSSImageValue* value)
+{
+ StyleImage* image = value->cachedOrPendingImage();
+ if (image && image->isPendingImage())
+ m_pendingImageProperties.add(property);
+ return image;
+}
+
+void CSSStyleSelector::mapFillImage(CSSPropertyID property, FillLayer* layer, CSSValue* value)
{
if (value->cssValueType() == CSSValue::CSS_INITIAL) {
layer->setImage(FillLayer::initialFillImage(layer->type()));
return;
}
- layer->setImage(styleImage(value));
+ layer->setImage(styleImage(property, value));
}
-void CSSStyleSelector::mapFillRepeatX(FillLayer* layer, CSSValue* value)
+void CSSStyleSelector::mapFillRepeatX(CSSPropertyID, FillLayer* layer, CSSValue* value)
{
if (value->cssValueType() == CSSValue::CSS_INITIAL) {
layer->setRepeatX(FillLayer::initialFillRepeatX(layer->type()));
@@ -5921,7 +5939,7 @@ void CSSStyleSelector::mapFillRepeatX(FillLayer* layer, CSSValue* value)
layer->setRepeatX(*primitiveValue);
}
-void CSSStyleSelector::mapFillRepeatY(FillLayer* layer, CSSValue* value)
+void CSSStyleSelector::mapFillRepeatY(CSSPropertyID, FillLayer* layer, CSSValue* value)
{
if (value->cssValueType() == CSSValue::CSS_INITIAL) {
layer->setRepeatY(FillLayer::initialFillRepeatY(layer->type()));
@@ -5935,7 +5953,7 @@ void CSSStyleSelector::mapFillRepeatY(FillLayer* layer, CSSValue* value)
layer->setRepeatY(*primitiveValue);
}
-void CSSStyleSelector::mapFillSize(FillLayer* layer, CSSValue* value)
+void CSSStyleSelector::mapFillSize(CSSPropertyID, FillLayer* layer, CSSValue* value)
{
if (!value->isPrimitiveValue()) {
layer->setSizeType(SizeNone);
@@ -5997,7 +6015,7 @@ void CSSStyleSelector::mapFillSize(FillLayer* layer, CSSValue* value)
layer->setSizeLength(b);
}
-void CSSStyleSelector::mapFillXPosition(FillLayer* layer, CSSValue* value)
+void CSSStyleSelector::mapFillXPosition(CSSPropertyID, FillLayer* layer, CSSValue* value)
{
if (value->cssValueType() == CSSValue::CSS_INITIAL) {
layer->setXPosition(FillLayer::initialFillXPosition(layer->type()));
@@ -6021,7 +6039,7 @@ void CSSStyleSelector::mapFillXPosition(FillLayer* layer, CSSValue* value)
layer->setXPosition(l);
}
-void CSSStyleSelector::mapFillYPosition(FillLayer* layer, CSSValue* value)
+void CSSStyleSelector::mapFillYPosition(CSSPropertyID, FillLayer* layer, CSSValue* value)
{
if (value->cssValueType() == CSSValue::CSS_INITIAL) {
layer->setYPosition(FillLayer::initialFillYPosition(layer->type()));
@@ -6209,7 +6227,7 @@ void CSSStyleSelector::mapAnimationTimingFunction(Animation* animation, CSSValue
}
}
-void CSSStyleSelector::mapNinePieceImage(CSSValue* value, NinePieceImage& image)
+void CSSStyleSelector::mapNinePieceImage(CSSPropertyID property, CSSValue* value, NinePieceImage& image)
{
// If we're a primitive value, then we are "none" and don't need to alter the empty image at all.
if (!value || value->isPrimitiveValue())
@@ -6219,7 +6237,7 @@ void CSSStyleSelector::mapNinePieceImage(CSSValue* value, NinePieceImage& image)
CSSBorderImageValue* borderImage = static_cast<CSSBorderImageValue*>(value);
// Set the image (this kicks off the load).
- image.setImage(styleImage(borderImage->imageValue()));
+ image.setImage(styleImage(property, borderImage->imageValue()));
// Set up a length box to represent our image slices.
LengthBox l;
@@ -6430,7 +6448,7 @@ float CSSStyleSelector::fontSizeForKeyword(Document* document, int keyword, bool
if (!settings)
return 1.0f;
- bool quirksMode = document->inCompatMode();
+ bool quirksMode = document->inQuirksMode();
int mediumSize = fixed ? settings->defaultFixedFontSize() : settings->defaultFontSize();
if (mediumSize >= fontSizeTableMin && mediumSize <= fontSizeTableMax) {
// Look up the entry in the table.
@@ -6828,4 +6846,101 @@ bool CSSStyleSelector::createTransformOperations(CSSValue* inValue, RenderStyle*
return true;
}
+void CSSStyleSelector::loadPendingImages()
+{
+ if (m_pendingImageProperties.isEmpty())
+ return;
+
+ HashSet<int>::const_iterator end = m_pendingImageProperties.end();
+ for (HashSet<int>::const_iterator it = m_pendingImageProperties.begin(); it != end; ++it) {
+ CSSPropertyID currentProperty = static_cast<CSSPropertyID>(*it);
+
+ DocLoader* docLoader = m_element->document()->docLoader();
+
+ switch (currentProperty) {
+ case CSSPropertyBackgroundImage: {
+ for (FillLayer* backgroundLayer = m_style->accessBackgroundLayers(); backgroundLayer; backgroundLayer = backgroundLayer->next()) {
+ if (backgroundLayer->image() && backgroundLayer->image()->isPendingImage()) {
+ CSSImageValue* imageValue = static_cast<StylePendingImage*>(backgroundLayer->image())->cssImageValue();
+ backgroundLayer->setImage(imageValue->cachedImage(docLoader));
+ }
+ }
+ break;
+ }
+
+ case CSSPropertyContent: {
+ for (ContentData* contentData = const_cast<ContentData*>(m_style->contentData()); contentData; contentData = contentData->next()) {
+ if (contentData->isImage() && contentData->image()->isPendingImage()) {
+ CSSImageValue* imageValue = static_cast<StylePendingImage*>(contentData->image())->cssImageValue();
+ contentData->setImage(imageValue->cachedImage(docLoader));
+ }
+ }
+ break;
+ }
+
+ case CSSPropertyCursor: {
+ if (CursorList* cursorList = m_style->cursors()) {
+ for (size_t i = 0; i < cursorList->size(); ++i) {
+ CursorData& currentCursor = (*cursorList)[i];
+ if (currentCursor.image()->isPendingImage()) {
+ CSSImageValue* imageValue = static_cast<StylePendingImage*>(currentCursor.image())->cssImageValue();
+ currentCursor.setImage(imageValue->cachedImage(docLoader));
+ }
+ }
+ }
+ break;
+ }
+
+ case CSSPropertyListStyleImage: {
+ if (m_style->listStyleImage() && m_style->listStyleImage()->isPendingImage()) {
+ CSSImageValue* imageValue = static_cast<StylePendingImage*>(m_style->listStyleImage())->cssImageValue();
+ m_style->setListStyleImage(imageValue->cachedImage(docLoader));
+ }
+ break;
+ }
+
+ case CSSPropertyWebkitBorderImage: {
+ const NinePieceImage& borderImage = m_style->borderImage();
+ if (borderImage.image() && borderImage.image()->isPendingImage()) {
+ CSSImageValue* imageValue = static_cast<StylePendingImage*>(borderImage.image())->cssImageValue();
+ m_style->setBorderImage(NinePieceImage(imageValue->cachedImage(docLoader), borderImage.slices(), borderImage.horizontalRule(), borderImage.verticalRule()));
+ }
+ break;
+ }
+
+ case CSSPropertyWebkitBoxReflect: {
+ const NinePieceImage& maskImage = m_style->boxReflect()->mask();
+ if (maskImage.image() && maskImage.image()->isPendingImage()) {
+ CSSImageValue* imageValue = static_cast<StylePendingImage*>(maskImage.image())->cssImageValue();
+ m_style->boxReflect()->setMask(NinePieceImage(imageValue->cachedImage(docLoader), maskImage.slices(), maskImage.horizontalRule(), maskImage.verticalRule()));
+ }
+ break;
+ }
+
+ case CSSPropertyWebkitMaskBoxImage: {
+ const NinePieceImage& maskBoxImage = m_style->maskBoxImage();
+ if (maskBoxImage.image() && maskBoxImage.image()->isPendingImage()) {
+ CSSImageValue* imageValue = static_cast<StylePendingImage*>(maskBoxImage.image())->cssImageValue();
+ m_style->setMaskBoxImage(NinePieceImage(imageValue->cachedImage(docLoader), maskBoxImage.slices(), maskBoxImage.horizontalRule(), maskBoxImage.verticalRule()));
+ }
+ break;
+ }
+
+ case CSSPropertyWebkitMaskImage: {
+ for (FillLayer* maskLayer = m_style->accessMaskLayers(); maskLayer; maskLayer = maskLayer->next()) {
+ if (maskLayer->image() && maskLayer->image()->isPendingImage()) {
+ CSSImageValue* imageValue = static_cast<StylePendingImage*>(maskLayer->image())->cssImageValue();
+ maskLayer->setImage(imageValue->cachedImage(docLoader));
+ }
+ }
+ break;
+ }
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ }
+
+ m_pendingImageProperties.clear();
+}
+
} // namespace WebCore