summaryrefslogtreecommitdiff
path: root/Source/WebCore/css
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/css')
-rw-r--r--Source/WebCore/css/CSSComputedStyleDeclaration.cpp47
-rw-r--r--Source/WebCore/css/CSSComputedStyleDeclaration.h2
-rw-r--r--Source/WebCore/css/CSSCursorImageValue.cpp17
-rw-r--r--Source/WebCore/css/CSSCursorImageValue.h18
-rw-r--r--Source/WebCore/css/CSSFontFaceSource.cpp3
-rw-r--r--Source/WebCore/css/CSSGrammar.y.in70
-rw-r--r--Source/WebCore/css/CSSImageGeneratorValue.cpp9
-rw-r--r--Source/WebCore/css/CSSImageSetValue.cpp27
-rw-r--r--Source/WebCore/css/CSSImportRule.cpp7
-rw-r--r--Source/WebCore/css/CSSParser.cpp536
-rw-r--r--Source/WebCore/css/CSSParser.h28
-rw-r--r--Source/WebCore/css/CSSParserValues.h3
-rw-r--r--Source/WebCore/css/CSSPrimitiveValue.cpp12
-rw-r--r--Source/WebCore/css/CSSPrimitiveValue.h6
-rw-r--r--Source/WebCore/css/CSSPrimitiveValueMappings.h63
-rw-r--r--Source/WebCore/css/CSSProperty.cpp29
-rw-r--r--Source/WebCore/css/CSSProperty.h53
-rw-r--r--Source/WebCore/css/CSSPropertyNames.in6
-rw-r--r--Source/WebCore/css/CSSPropertySourceData.h4
-rw-r--r--Source/WebCore/css/CSSRule.cpp30
-rw-r--r--Source/WebCore/css/CSSRule.h7
-rw-r--r--Source/WebCore/css/CSSSelector.cpp38
-rw-r--r--Source/WebCore/css/CSSSelector.h10
-rw-r--r--Source/WebCore/css/CSSSelectorList.cpp8
-rw-r--r--Source/WebCore/css/CSSSelectorList.h2
-rw-r--r--Source/WebCore/css/CSSStyleDeclaration.h4
-rw-r--r--Source/WebCore/css/CSSValueKeywords.in22
-rw-r--r--Source/WebCore/css/CSSValueList.h1
-rw-r--r--Source/WebCore/css/CachedSVGDocumentReference.h50
-rw-r--r--Source/WebCore/css/MediaFeatureNames.h3
-rw-r--r--Source/WebCore/css/MediaQueryEvaluator.cpp163
-rw-r--r--Source/WebCore/css/MediaQueryExp.cpp18
-rw-r--r--Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp54
-rw-r--r--Source/WebCore/css/PropertySetCSSStyleDeclaration.h2
-rw-r--r--Source/WebCore/css/RuleFeature.cpp11
-rw-r--r--Source/WebCore/css/RuleFeature.h7
-rw-r--r--Source/WebCore/css/RuleSet.cpp40
-rw-r--r--Source/WebCore/css/RuleSet.h15
-rw-r--r--Source/WebCore/css/SVGCSSParser.cpp1
-rw-r--r--Source/WebCore/css/SVGCSSStyleSelector.cpp5
-rw-r--r--Source/WebCore/css/SelectorChecker.cpp32
-rw-r--r--Source/WebCore/css/SelectorChecker.h2
-rw-r--r--Source/WebCore/css/StyleBuilder.cpp2
-rw-r--r--Source/WebCore/css/StylePropertySet.cpp288
-rw-r--r--Source/WebCore/css/StylePropertySet.h92
-rw-r--r--Source/WebCore/css/StyleResolver.cpp264
-rw-r--r--Source/WebCore/css/StyleResolver.h55
-rw-r--r--Source/WebCore/css/StyleRule.cpp64
-rw-r--r--Source/WebCore/css/StyleRule.h46
-rw-r--r--Source/WebCore/css/StyleScopeResolver.cpp82
-rw-r--r--Source/WebCore/css/StyleScopeResolver.h13
-rw-r--r--Source/WebCore/css/StyleSheetContents.cpp7
-rw-r--r--Source/WebCore/css/WebKitCSSViewportRule.cpp97
-rw-r--r--Source/WebCore/css/WebKitCSSViewportRule.h73
-rw-r--r--Source/WebCore/css/html.css139
-rw-r--r--Source/WebCore/css/mathml.css10
-rw-r--r--Source/WebCore/css/mediaControls.css9
-rw-r--r--Source/WebCore/css/themeBlackBerry.css45
58 files changed, 2032 insertions, 719 deletions
diff --git a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp
index 586c133ea..1e6d2079a 100644
--- a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp
+++ b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp
@@ -34,7 +34,6 @@
#include "CSSParser.h"
#include "CSSPrimitiveValue.h"
#include "CSSPrimitiveValueMappings.h"
-#include "CSSProperty.h"
#include "CSSPropertyNames.h"
#include "CSSReflectValue.h"
#include "CSSSelector.h"
@@ -905,6 +904,10 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(const RenderObj
break;
}
#if ENABLE(CSS_SHADERS)
+ case FilterOperation::VALIDATED_CUSTOM:
+ // ValidatedCustomFilterOperation is not supposed to end up in the RenderStyle.
+ ASSERT_NOT_REACHED();
+ break;
case FilterOperation::CUSTOM: {
CustomFilterOperation* customOperation = static_cast<CustomFilterOperation*>(filterOperation);
filterValue = WebKitCSSFilterValue::create(WebKitCSSFilterValue::CustomFilterOperation);
@@ -921,27 +924,29 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(const RenderObj
shadersList->append(cssValuePool().createIdentifierValue(CSSValueNone));
const CustomFilterProgramMixSettings mixSettings = program->mixSettings();
- if (program->programType() == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE) {
- RefPtr<WebKitCSSMixFunctionValue> mixFunction = WebKitCSSMixFunctionValue::create();
- mixFunction->append(program->fragmentShader()->cssValue());
- mixFunction->append(cssValuePool().createValue(mixSettings.blendMode));
- mixFunction->append(cssValuePool().createValue(mixSettings.compositeOperator));
- shadersList->append(mixFunction.release());
- } else if (program->fragmentShader())
- shadersList->append(program->fragmentShader()->cssValue());
+ if (program->fragmentShader()) {
+ if (program->programType() == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE) {
+ RefPtr<WebKitCSSMixFunctionValue> mixFunction = WebKitCSSMixFunctionValue::create();
+ mixFunction->append(program->fragmentShader()->cssValue());
+ mixFunction->append(cssValuePool().createValue(mixSettings.blendMode));
+ mixFunction->append(cssValuePool().createValue(mixSettings.compositeOperator));
+ shadersList->append(mixFunction.release());
+ } else
+ shadersList->append(program->fragmentShader()->cssValue());
+ }
else
shadersList->append(cssValuePool().createIdentifierValue(CSSValueNone));
filterValue->append(shadersList.release());
RefPtr<CSSValueList> meshParameters = CSSValueList::createSpaceSeparated();
- meshParameters->append(cssValuePool().createValue(customOperation->meshRows(), CSSPrimitiveValue::CSS_NUMBER));
meshParameters->append(cssValuePool().createValue(customOperation->meshColumns(), CSSPrimitiveValue::CSS_NUMBER));
+ meshParameters->append(cssValuePool().createValue(customOperation->meshRows(), CSSPrimitiveValue::CSS_NUMBER));
meshParameters->append(cssValuePool().createValue(customOperation->meshBoxType()));
// FIXME: The specification doesn't have any "attached" identifier. Should we add one?
// https://bugs.webkit.org/show_bug.cgi?id=72700
- if (customOperation->meshType() == CustomFilterOperation::DETACHED)
+ if (customOperation->meshType() == MeshTypeDetached)
meshParameters->append(cssValuePool().createIdentifierValue(CSSValueDetached));
filterValue->append(meshParameters.release());
@@ -2133,7 +2138,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
case CSSPropertyWordWrap:
return cssValuePool().createValue(style->overflowWrap());
case CSSPropertyWebkitLineBreak:
- return cssValuePool().createValue(style->khtmlLineBreak());
+ return cssValuePool().createValue(style->lineBreak());
case CSSPropertyWebkitNbspMode:
return cssValuePool().createValue(style->nbspMode());
case CSSPropertyResize:
@@ -2644,6 +2649,14 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
#endif
break;
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ case CSSPropertyMaxZoom:
+ case CSSPropertyMinZoom:
+ case CSSPropertyOrientation:
+ case CSSPropertyUserZoom:
+ break;
+#endif
+
#if ENABLE(SVG)
case CSSPropertyClipPath:
case CSSPropertyClipRule:
@@ -2724,20 +2737,20 @@ String CSSComputedStyleDeclaration::item(unsigned i) const
return getPropertyNameString(computedProperties[i]);
}
-bool CSSComputedStyleDeclaration::cssPropertyMatches(const CSSProperty* property) const
+bool CSSComputedStyleDeclaration::cssPropertyMatches(const StylePropertySet::PropertyReference& property) const
{
- if (property->id() == CSSPropertyFontSize && property->value()->isPrimitiveValue() && m_node) {
+ if (property.id() == CSSPropertyFontSize && property.value()->isPrimitiveValue() && m_node) {
m_node->document()->updateLayoutIgnorePendingStylesheets();
RenderStyle* style = m_node->computedStyle(m_pseudoElementSpecifier);
if (style && style->fontDescription().keywordSize()) {
int sizeValue = cssIdentifierForFontSizeKeyword(style->fontDescription().keywordSize());
- CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(property->value());
+ const CSSPrimitiveValue* primitiveValue = static_cast<const CSSPrimitiveValue*>(property.value());
if (primitiveValue->isIdent() && primitiveValue->getIdent() == sizeValue)
return true;
}
}
- RefPtr<CSSValue> value = getPropertyCSSValue(property->id());
- return value && value->cssText() == property->value()->cssText();
+ RefPtr<CSSValue> value = getPropertyCSSValue(property.id());
+ return value && value->cssText() == property.value()->cssText();
}
PassRefPtr<StylePropertySet> CSSComputedStyleDeclaration::copy() const
diff --git a/Source/WebCore/css/CSSComputedStyleDeclaration.h b/Source/WebCore/css/CSSComputedStyleDeclaration.h
index cfc837b9f..6b239e956 100644
--- a/Source/WebCore/css/CSSComputedStyleDeclaration.h
+++ b/Source/WebCore/css/CSSComputedStyleDeclaration.h
@@ -95,7 +95,7 @@ private:
virtual String getPropertyValueInternal(CSSPropertyID);
virtual void setPropertyInternal(CSSPropertyID, const String& value, bool important, ExceptionCode&);
- virtual bool cssPropertyMatches(const CSSProperty*) const;
+ virtual bool cssPropertyMatches(const StylePropertySet::PropertyReference&) const OVERRIDE;
PassRefPtr<CSSValue> valueForShadow(const ShadowData*, CSSPropertyID, const RenderStyle*) const;
PassRefPtr<CSSPrimitiveValue> currentColorOrValidColor(RenderStyle*, const Color&) const;
diff --git a/Source/WebCore/css/CSSCursorImageValue.cpp b/Source/WebCore/css/CSSCursorImageValue.cpp
index 06d93ea60..0faa813b1 100644
--- a/Source/WebCore/css/CSSCursorImageValue.cpp
+++ b/Source/WebCore/css/CSSCursorImageValue.cpp
@@ -56,8 +56,9 @@ static inline SVGCursorElement* resourceReferencedByCursorElement(const String&
}
#endif
-CSSCursorImageValue::CSSCursorImageValue(const String& url, const IntPoint& hotSpot)
+CSSCursorImageValue::CSSCursorImageValue(const String& url, bool hasHotSpot, const IntPoint& hotSpot)
: CSSImageValue(CursorImageClass, url)
+ , m_hasHotSpot(hasHotSpot)
, m_hotSpot(hotSpot)
{
}
@@ -80,6 +81,19 @@ CSSCursorImageValue::~CSSCursorImageValue()
#endif
}
+String CSSCursorImageValue::customCssText() const
+{
+ StringBuilder result;
+ result.append(CSSImageValue::customCssText());
+ if (m_hasHotSpot) {
+ result.append(' ');
+ result.appendNumber(m_hotSpot.x());
+ result.append(' ');
+ result.appendNumber(m_hotSpot.y());
+ }
+ return result.toString();
+}
+
bool CSSCursorImageValue::updateIfSVGCursorIsUsed(Element* element)
{
#if !ENABLE(SVG)
@@ -94,6 +108,7 @@ bool CSSCursorImageValue::updateIfSVGCursorIsUsed(Element* element)
if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url(), element->document())) {
// FIXME: This will override hot spot specified in CSS, which is probably incorrect.
SVGLengthContext lengthContext(0);
+ m_hasHotSpot = true;
float x = roundf(cursorElement->x().value(lengthContext));
m_hotSpot.setX(static_cast<int>(x));
diff --git a/Source/WebCore/css/CSSCursorImageValue.h b/Source/WebCore/css/CSSCursorImageValue.h
index dc8d1ff4c..80d3f15e0 100644
--- a/Source/WebCore/css/CSSCursorImageValue.h
+++ b/Source/WebCore/css/CSSCursorImageValue.h
@@ -32,14 +32,23 @@ class SVGElement;
class CSSCursorImageValue : public CSSImageValue {
public:
- static PassRefPtr<CSSCursorImageValue> create(const String& url, const IntPoint& hotSpot)
+ static PassRefPtr<CSSCursorImageValue> create(const String& url, bool hasHotSpot, const IntPoint& hotSpot)
{
- return adoptRef(new CSSCursorImageValue(url, hotSpot));
+ return adoptRef(new CSSCursorImageValue(url, hasHotSpot, hotSpot));
}
~CSSCursorImageValue();
- IntPoint hotSpot() const { return m_hotSpot; }
+ bool hasHotSpot() const { return m_hasHotSpot; }
+
+ IntPoint hotSpot() const
+ {
+ if (m_hasHotSpot)
+ return m_hotSpot;
+ return IntPoint(-1, -1);
+ }
+
+ String customCssText() const;
bool updateIfSVGCursorIsUsed(Element*);
StyleCachedImage* cachedImage(CachedResourceLoader*);
@@ -51,8 +60,9 @@ public:
void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
private:
- CSSCursorImageValue(const String& url, const IntPoint& hotSpot);
+ CSSCursorImageValue(const String& url, bool hasHotSpot, const IntPoint& hotSpot);
+ bool m_hasHotSpot;
IntPoint m_hotSpot;
#if ENABLE(SVG)
diff --git a/Source/WebCore/css/CSSFontFaceSource.cpp b/Source/WebCore/css/CSSFontFaceSource.cpp
index 5e5289f6d..2fd63f6fa 100644
--- a/Source/WebCore/css/CSSFontFaceSource.cpp
+++ b/Source/WebCore/css/CSSFontFaceSource.cpp
@@ -106,7 +106,8 @@ PassRefPtr<SimpleFontData> CSSFontFaceSource::getFontData(const FontDescription&
#endif
) {
// We're local. Just return a SimpleFontData from the normal cache.
- return fontCache()->getCachedFontData(fontDescription, m_string);
+ // We don't want to check alternate font family names here, so pass true as the checkingAlternateName parameter.
+ return fontCache()->getCachedFontData(fontDescription, m_string, true);
}
// See if we have a mapping in our FontData cache.
diff --git a/Source/WebCore/css/CSSGrammar.y.in b/Source/WebCore/css/CSSGrammar.y.in
index 4b894fb95..9eedcc394 100644
--- a/Source/WebCore/css/CSSGrammar.y.in
+++ b/Source/WebCore/css/CSSGrammar.y.in
@@ -3,6 +3,7 @@
* Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
* Copyright (C) 2008 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -95,6 +96,9 @@ static inline int cssyyerror(void*, const char*)
%token SUPPORTS_SYM
#endif
%token FONT_FACE_SYM
+#if ENABLE_SHADOW_DOM
+%token HOST_SYM
+#endif
%token CHARSET_SYM
%token NAMESPACE_SYM
%token VARFUNCTION
@@ -106,6 +110,7 @@ static inline int cssyyerror(void*, const char*)
%token WEBKIT_MEDIAQUERY_SYM
%token WEBKIT_SELECTOR_SYM
%token WEBKIT_REGION_RULE_SYM
+%token WEBKIT_VIEWPORT_RULE_SYM
%token <marginBox> TOPLEFTCORNER_SYM
%token <marginBox> TOPLEFT_SYM
%token <marginBox> TOPCENTER_SYM
@@ -187,6 +192,9 @@ static inline int cssyyerror(void*, const char*)
%type <rule> page
%type <rule> margin_box
%type <rule> font_face
+#if ENABLE_SHADOW_DOM
+%type <rule> host
+#endif
%type <rule> keyframes
%type <rule> invalid_rule
%type <rule> save_block
@@ -200,6 +208,9 @@ static inline int cssyyerror(void*, const char*)
#if ENABLE_CSS3_CONDITIONAL_RULES
%type <rule> supports
#endif
+#if ENABLE_CSS_DEVICE_ADAPTATION
+%type <rule> viewport
+#endif
%type <string> maybe_ns_prefix
@@ -402,6 +413,12 @@ valid_rule:
#if ENABLE_CSS3_CONDITIONAL_RULES
| supports
#endif
+#if ENABLE_SHADOW_DOM
+ | host
+#endif
+#if ENABLE_CSS_DEVICE_ADAPTATION
+ | viewport
+#endif
;
rule:
@@ -430,6 +447,9 @@ block_valid_rule:
| page
| font_face
| keyframes
+#if ENABLE_CSS_DEVICE_ADAPTATION
+ | viewport
+#endif
;
block_rule:
@@ -901,6 +921,52 @@ font_face:
}
;
+#if ENABLE_SHADOW_DOM
+before_host_rule:
+ /* empty */ {
+ parser->markRuleHeaderStart(CSSRuleSourceData::HOST_RULE);
+ }
+ ;
+
+host:
+ before_host_rule HOST_SYM at_rule_header_end_maybe_space
+ '{' at_rule_body_start maybe_space block_rule_list save_block {
+ $$ = parser->createHostRule($7);
+ }
+ | before_host_rule HOST_SYM at_rule_header_end_maybe_space ';' {
+ $$ = 0;
+ parser->popRuleData();
+ }
+ ;
+#endif
+
+#if ENABLE_CSS_DEVICE_ADAPTATION
+before_viewport_rule:
+ /* empty */ {
+ parser->markViewportRuleBodyStart();
+ parser->markRuleHeaderStart(CSSRuleSourceData::VIEWPORT_RULE);
+ }
+ ;
+
+viewport:
+ before_viewport_rule WEBKIT_VIEWPORT_RULE_SYM at_rule_header_end_maybe_space
+ '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
+ $$ = parser->createViewportRule();
+ parser->markViewportRuleBodyEnd();
+ }
+ | before_viewport_rule WEBKIT_VIEWPORT_RULE_SYM error invalid_block {
+ $$ = 0;
+ parser->popRuleData();
+ parser->markViewportRuleBodyEnd();
+ }
+ | before_viewport_rule WEBKIT_VIEWPORT_RULE_SYM error ';' {
+ $$ = 0;
+ parser->popRuleData();
+ parser->markViewportRuleBodyEnd();
+ }
+;
+#endif
+
region_selector:
selector_list {
if ($1) {
@@ -1241,7 +1307,9 @@ pseudo:
$3.lower();
$$->setValue($3);
// FIXME: This call is needed to force selector to compute the pseudoType early enough.
- $$->pseudoType();
+ CSSSelector::PseudoType type = $$->pseudoType();
+ if (type == CSSSelector::PseudoUnknown)
+ $$ = 0;
}
// use by :-webkit-any.
// FIXME: should we support generic selectors here or just simple_selectors?
diff --git a/Source/WebCore/css/CSSImageGeneratorValue.cpp b/Source/WebCore/css/CSSImageGeneratorValue.cpp
index 8cf47f06d..6c460a768 100644
--- a/Source/WebCore/css/CSSImageGeneratorValue.cpp
+++ b/Source/WebCore/css/CSSImageGeneratorValue.cpp
@@ -36,6 +36,15 @@
#include <wtf/MemoryInstrumentationHashMap.h>
#include <wtf/text/WTFString.h>
+
+namespace WTF {
+
+template<> struct SequenceMemoryInstrumentationTraits<const WebCore::RenderObject*> {
+ template <typename I> static void reportMemoryUsage(I, I, MemoryClassInfo&) { }
+};
+
+}
+
namespace WebCore {
CSSImageGeneratorValue::CSSImageGeneratorValue(ClassType classType)
diff --git a/Source/WebCore/css/CSSImageSetValue.cpp b/Source/WebCore/css/CSSImageSetValue.cpp
index 6dc76f580..f7d401f5c 100644
--- a/Source/WebCore/css/CSSImageSetValue.cpp
+++ b/Source/WebCore/css/CSSImageSetValue.cpp
@@ -140,7 +140,32 @@ StyleImage* CSSImageSetValue::cachedOrPendingImageSet(Document* document)
String CSSImageSetValue::customCssText() const
{
- return "-webkit-image-set(" + CSSValueList::customCssText() + ")";
+ StringBuilder result;
+ result.append("-webkit-image-set(");
+
+ size_t length = this->length();
+ size_t i = 0;
+ while (i < length) {
+ if (i > 0)
+ result.append(", ");
+
+ const CSSValue* imageValue = item(i);
+ result.append(imageValue->cssText());
+ result.append(' ');
+
+ ++i;
+ ASSERT(i < length);
+ const CSSValue* scaleFactorValue = item(i);
+ result.append(scaleFactorValue->cssText());
+ // FIXME: Eventually the scale factor should contain it's own unit http://wkb.ug/100120.
+ // For now 'x' is hard-coded in the parser, so we hard-code it here too.
+ result.append('x');
+
+ ++i;
+ }
+
+ result.append(")");
+ return result.toString();
}
bool CSSImageSetValue::hasFailedOrCanceledSubresources() const
diff --git a/Source/WebCore/css/CSSImportRule.cpp b/Source/WebCore/css/CSSImportRule.cpp
index 3bbe650a5..8697f668f 100644
--- a/Source/WebCore/css/CSSImportRule.cpp
+++ b/Source/WebCore/css/CSSImportRule.cpp
@@ -69,8 +69,11 @@ String CSSImportRule::cssText() const
result.append("\")");
if (m_importRule->mediaQueries()) {
- result.append(' ');
- result.append(m_importRule->mediaQueries()->mediaText());
+ String mediaText = m_importRule->mediaQueries()->mediaText();
+ if (!mediaText.isEmpty()) {
+ result.append(' ');
+ result.append(mediaText);
+ }
}
result.append(';');
diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp
index d16537e6c..8ff97b8e9 100644
--- a/Source/WebCore/css/CSSParser.cpp
+++ b/Source/WebCore/css/CSSParser.cpp
@@ -6,6 +6,7 @@
* Copyright (C) 2008 Eric Seidel <eric@webkit.org>
* Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
* Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -43,7 +44,6 @@
#include "CSSMediaRule.h"
#include "CSSPageRule.h"
#include "CSSPrimitiveValue.h"
-#include "CSSProperty.h"
#include "CSSPropertySourceData.h"
#include "CSSReflectValue.h"
#include "CSSSelector.h"
@@ -53,7 +53,6 @@
#include "CSSValueKeywords.h"
#include "CSSValueList.h"
#include "CSSValuePool.h"
-#include "StylePropertyShorthand.h"
#if ENABLE(CSS_VARIABLES)
#include "CSSVariableValue.h"
#endif
@@ -271,6 +270,9 @@ CSSParser::CSSParser(const CSSParserContext& context)
, m_lastSelectorLineNumber(0)
, m_allowImportRules(true)
, m_allowNamespaceDeclarations(true)
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ , m_inViewport(false)
+#endif
, m_selectorVector(adoptPtr(new CSSSelectorVector))
{
#if YYDEBUG > 0
@@ -337,11 +339,12 @@ AtomicString CSSParserString::lowerSubstring(unsigned position, unsigned length)
return AtomicString(result);
}
-void CSSParser::setupParser(const char* prefix, const String& string, const char* suffix)
+void CSSParser::setupParser(const char* prefix, unsigned prefixLength, const String& string, const char* suffix, unsigned suffixLength)
{
- m_parsedTextPrefixLength = strlen(prefix);
+ m_parsedTextPrefixLength = prefixLength;
unsigned stringLength = string.length();
- unsigned length = stringLength + m_parsedTextPrefixLength + strlen(suffix) + 1;
+ unsigned length = stringLength + m_parsedTextPrefixLength + suffixLength + 1;
+ m_length = length;
if (!stringLength || string.is8Bit()) {
m_dataStart8 = adoptArrayPtr(new LChar[length]);
@@ -352,7 +355,7 @@ void CSSParser::setupParser(const char* prefix, const String& string, const char
memcpy(m_dataStart8.get() + m_parsedTextPrefixLength, string.characters8(), stringLength * sizeof(LChar));
unsigned start = m_parsedTextPrefixLength + stringLength;
- unsigned end = start + strlen(suffix);
+ unsigned end = start + suffixLength;
for (unsigned i = start; i < end; i++)
m_dataStart8[i] = suffix[i - start];
@@ -362,7 +365,6 @@ void CSSParser::setupParser(const char* prefix, const String& string, const char
m_currentCharacter8 = m_dataStart8.get();
m_currentCharacter16 = 0;
setTokenStart<LChar>(m_currentCharacter8);
- m_length = length;
m_lexFunc = &CSSParser::realLex<LChar>;
return;
}
@@ -374,7 +376,7 @@ void CSSParser::setupParser(const char* prefix, const String& string, const char
memcpy(m_dataStart16.get() + m_parsedTextPrefixLength, string.characters(), stringLength * sizeof(UChar));
unsigned start = m_parsedTextPrefixLength + stringLength;
- unsigned end = start + strlen(suffix);
+ unsigned end = start + suffixLength;
for (unsigned i = start; i < end; i++)
m_dataStart16[i] = suffix[i - start];
@@ -384,7 +386,6 @@ void CSSParser::setupParser(const char* prefix, const String& string, const char
m_currentCharacter8 = 0;
m_currentCharacter16 = m_dataStart16.get();
setTokenStart<UChar>(m_currentCharacter16);
- m_length = length;
m_lexFunc = &CSSParser::realLex<UChar>;
}
@@ -829,8 +830,8 @@ static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int
if (valueID == CSSValueNone || valueID == CSSValueEdges)
return true;
break;
- case CSSPropertyWebkitLineBreak: // normal | after-white-space
- if (valueID == CSSValueNormal || valueID == CSSValueAfterWhiteSpace)
+ case CSSPropertyWebkitLineBreak: // auto | loose | normal | strict | after-white-space
+ if (valueID == CSSValueAuto || valueID == CSSValueLoose || valueID == CSSValueNormal || valueID == CSSValueStrict || valueID == CSSValueAfterWhiteSpace)
return true;
break;
case CSSPropertyWebkitLineSnap:
@@ -1572,7 +1573,7 @@ bool CSSParser::validUnit(CSSParserValue* value, Units unitflags, CSSParserMode
case CSSPrimitiveValue::CSS_TURN:
b = (unitflags & FAngle);
break;
-#if ENABLE(CSS_IMAGE_RESOLUTION)
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
case CSSPrimitiveValue::CSS_DPPX:
case CSSPrimitiveValue::CSS_DPI:
case CSSPrimitiveValue::CSS_DPCM:
@@ -1601,8 +1602,8 @@ inline PassRefPtr<CSSPrimitiveValue> CSSParser::createPrimitiveNumericValue(CSSP
ASSERT(isCalculation(value));
return CSSPrimitiveValue::create(m_parsedCalculation.release());
}
-
-#if ENABLE(CSS_IMAGE_RESOLUTION)
+
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
ASSERT((value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
|| (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_REMS)
|| (value->unit >= CSSPrimitiveValue::CSS_VW && value->unit <= CSSPrimitiveValue::CSS_VMIN)
@@ -1664,7 +1665,7 @@ inline PassRefPtr<CSSPrimitiveValue> CSSParser::parseValidPrimitive(int identifi
return createPrimitiveNumericValue(value);
if (value->unit >= CSSPrimitiveValue::CSS_VW && value->unit <= CSSPrimitiveValue::CSS_VMIN)
return createPrimitiveNumericValue(value);
-#if ENABLE(CSS_IMAGE_RESOLUTION)
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
if (value->unit >= CSSPrimitiveValue::CSS_DPPX && value->unit <= CSSPrimitiveValue::CSS_DPCM)
return createPrimitiveNumericValue(value);
#endif
@@ -1729,6 +1730,11 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important)
return true;
}
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ if (inViewport())
+ return parseViewportProperty(propId, important);
+#endif
+
bool validPrimitive = false;
RefPtr<CSSValue> parsedValue;
@@ -1876,15 +1882,18 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important)
coords.append(int(value->fValue));
value = m_valueList->next();
}
+ bool hasHotSpot = false;
IntPoint hotSpot(-1, -1);
int nrcoords = coords.size();
if (nrcoords > 0 && nrcoords != 2)
return false;
- if (nrcoords == 2)
+ if (nrcoords == 2) {
+ hasHotSpot = true;
hotSpot = IntPoint(coords[0], coords[1]);
+ }
if (!uri.isNull())
- list->append(CSSCursorImageValue::create(completeURL(uri), hotSpot));
+ list->append(CSSCursorImageValue::create(completeURL(uri), hasHotSpot, hotSpot));
if ((inStrictMode() && !value) || (value && !(value->unit == CSSParserValue::Operator && value->iValue == ',')))
return false;
@@ -2853,6 +2862,17 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important)
// These properties should be handled before in isValidKeywordPropertyAndValue().
ASSERT_NOT_REACHED();
return false;
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ // Properties bellow are validated inside parseViewportProperty, because we
+ // check for parser state inViewportScope. We need to invalidate if someone
+ // adds them outside a @viewport rule.
+ case CSSPropertyMaxZoom:
+ case CSSPropertyMinZoom:
+ case CSSPropertyOrientation:
+ case CSSPropertyUserZoom:
+ validPrimitive = false;
+ break;
+#endif
#if ENABLE(SVG)
default:
return parseSVGValue(propId, important);
@@ -7210,76 +7230,241 @@ public:
, m_allowSingleArgument(false)
, m_unit(CSSParser::FUnknown)
{
- if (equalIgnoringCase(name, "scale(") || equalIgnoringCase(name, "scalex(") || equalIgnoringCase(name, "scaley(") || equalIgnoringCase(name, "scalez(")) {
- m_unit = CSSParser::FNumber;
- if (equalIgnoringCase(name, "scale("))
- m_type = WebKitCSSTransformValue::ScaleTransformOperation;
- else if (equalIgnoringCase(name, "scalex("))
- m_type = WebKitCSSTransformValue::ScaleXTransformOperation;
- else if (equalIgnoringCase(name, "scaley("))
- m_type = WebKitCSSTransformValue::ScaleYTransformOperation;
- else
- m_type = WebKitCSSTransformValue::ScaleZTransformOperation;
- } else if (equalIgnoringCase(name, "scale3d(")) {
- m_type = WebKitCSSTransformValue::Scale3DTransformOperation;
- m_argCount = 5;
- m_unit = CSSParser::FNumber;
- } else if (equalIgnoringCase(name, "rotate(")) {
- m_type = WebKitCSSTransformValue::RotateTransformOperation;
- m_unit = CSSParser::FAngle;
- } else if (equalIgnoringCase(name, "rotatex(") ||
- equalIgnoringCase(name, "rotatey(") ||
- equalIgnoringCase(name, "rotatez(")) {
- m_unit = CSSParser::FAngle;
- if (equalIgnoringCase(name, "rotatex("))
- m_type = WebKitCSSTransformValue::RotateXTransformOperation;
- else if (equalIgnoringCase(name, "rotatey("))
- m_type = WebKitCSSTransformValue::RotateYTransformOperation;
- else
- m_type = WebKitCSSTransformValue::RotateZTransformOperation;
- } else if (equalIgnoringCase(name, "rotate3d(")) {
- m_type = WebKitCSSTransformValue::Rotate3DTransformOperation;
- m_argCount = 7;
- m_unit = CSSParser::FNumber;
- } else if (equalIgnoringCase(name, "skew(") || equalIgnoringCase(name, "skewx(") || equalIgnoringCase(name, "skewy(")) {
- m_unit = CSSParser::FAngle;
- if (equalIgnoringCase(name, "skew("))
+ const UChar* characters;
+ unsigned nameLength = name.length();
+
+ const unsigned longestNameLength = 12;
+ UChar characterBuffer[longestNameLength];
+ if (name.is8Bit()) {
+ unsigned length = std::min(longestNameLength, nameLength);
+ const LChar* characters8 = name.characters8();
+ for (unsigned i = 0; i < length; ++i)
+ characterBuffer[i] = characters8[i];
+ characters = characterBuffer;
+ } else
+ characters = name.characters16();
+
+ switch (nameLength) {
+ case 5:
+ // Valid name: skew(.
+ if (((characters[0] == 's') || (characters[0] == 'S'))
+ & ((characters[1] == 'k') || (characters[1] == 'K'))
+ & ((characters[2] == 'e') || (characters[2] == 'E'))
+ & ((characters[3] == 'w') || (characters[3] == 'W'))
+ & (characters[4] == '(')) {
+ m_unit = CSSParser::FAngle;
m_type = WebKitCSSTransformValue::SkewTransformOperation;
- else if (equalIgnoringCase(name, "skewx("))
- m_type = WebKitCSSTransformValue::SkewXTransformOperation;
- else
- m_type = WebKitCSSTransformValue::SkewYTransformOperation;
- } else if (equalIgnoringCase(name, "translate(") || equalIgnoringCase(name, "translatex(") || equalIgnoringCase(name, "translatey(") || equalIgnoringCase(name, "translatez(")) {
- m_unit = CSSParser::FLength | CSSParser::FPercent;
- if (equalIgnoringCase(name, "translate("))
+ m_allowSingleArgument = true;
+ m_argCount = 3;
+ }
+ break;
+ case 6:
+ // Valid names: skewx(, skewy(, scale(.
+ if ((characters[1] == 'c') || (characters[1] == 'C')) {
+ if (((characters[0] == 's') || (characters[0] == 'S'))
+ & ((characters[2] == 'a') || (characters[2] == 'A'))
+ & ((characters[3] == 'l') || (characters[3] == 'L'))
+ & ((characters[4] == 'e') || (characters[4] == 'E'))
+ & (characters[5] == '(')) {
+ m_unit = CSSParser::FNumber;
+ m_type = WebKitCSSTransformValue::ScaleTransformOperation;
+ m_allowSingleArgument = true;
+ m_argCount = 3;
+ }
+ } else if (((characters[0] == 's') || (characters[0] == 'S'))
+ & ((characters[1] == 'k') || (characters[1] == 'K'))
+ & ((characters[2] == 'e') || (characters[2] == 'E'))
+ & ((characters[3] == 'w') || (characters[3] == 'W'))
+ & (characters[5] == '(')) {
+ if ((characters[4] == 'x') || (characters[4] == 'X')) {
+ m_unit = CSSParser::FAngle;
+ m_type = WebKitCSSTransformValue::SkewXTransformOperation;
+ } else if ((characters[4] == 'y') || (characters[4] == 'Y')) {
+ m_unit = CSSParser::FAngle;
+ m_type = WebKitCSSTransformValue::SkewYTransformOperation;
+ }
+ }
+ break;
+ case 7:
+ // Valid names: matrix(, rotate(, scalex(, scaley(, scalez(.
+ if ((characters[0] == 'm') || (characters[0] == 'M')) {
+ if (((characters[1] == 'a') || (characters[1] == 'A'))
+ & ((characters[2] == 't') || (characters[2] == 'T'))
+ & ((characters[3] == 'r') || (characters[3] == 'R'))
+ & ((characters[4] == 'i') || (characters[4] == 'I'))
+ & ((characters[5] == 'x') || (characters[5] == 'X'))
+ & (characters[6] == '(')) {
+ m_unit = CSSParser::FNumber;
+ m_type = WebKitCSSTransformValue::MatrixTransformOperation;
+ m_argCount = 11;
+ }
+ } else if ((characters[0] == 'r') || (characters[0] == 'R')) {
+ if (((characters[1] == 'o') || (characters[1] == 'O'))
+ & ((characters[2] == 't') || (characters[2] == 'T'))
+ & ((characters[3] == 'a') || (characters[3] == 'A'))
+ & ((characters[4] == 't') || (characters[4] == 'T'))
+ & ((characters[5] == 'e') || (characters[5] == 'E'))
+ & (characters[6] == '(')) {
+ m_unit = CSSParser::FAngle;
+ m_type = WebKitCSSTransformValue::RotateTransformOperation;
+ }
+ } else if (((characters[0] == 's') || (characters[0] == 'S'))
+ & ((characters[1] == 'c') || (characters[1] == 'C'))
+ & ((characters[2] == 'a') || (characters[2] == 'A'))
+ & ((characters[3] == 'l') || (characters[3] == 'L'))
+ & ((characters[4] == 'e') || (characters[4] == 'E'))
+ & (characters[6] == '(')) {
+ if ((characters[5] == 'x') || (characters[5] == 'X')) {
+ m_unit = CSSParser::FNumber;
+ m_type = WebKitCSSTransformValue::ScaleXTransformOperation;
+ } else if ((characters[5] == 'y') || (characters[5] == 'Y')) {
+ m_unit = CSSParser::FNumber;
+ m_type = WebKitCSSTransformValue::ScaleYTransformOperation;
+ } else if ((characters[5] == 'z') || (characters[5] == 'Z')) {
+ m_unit = CSSParser::FNumber;
+ m_type = WebKitCSSTransformValue::ScaleZTransformOperation;
+ }
+ }
+ break;
+ case 8:
+ // Valid names: rotatex(, rotatey(, rotatez(, scale3d(.
+ if ((characters[0] == 's') || (characters[0] == 'S')) {
+ if (((characters[1] == 'c') || (characters[1] == 'C'))
+ & ((characters[2] == 'a') || (characters[2] == 'A'))
+ & ((characters[3] == 'l') || (characters[3] == 'L'))
+ & ((characters[4] == 'e') || (characters[4] == 'E'))
+ & (characters[5] == '3')
+ & ((characters[6] == 'd') || (characters[6] == 'D'))
+ & (characters[7] == '(')) {
+ m_unit = CSSParser::FNumber;
+ m_type = WebKitCSSTransformValue::Scale3DTransformOperation;
+ m_argCount = 5;
+ }
+ } else if (((characters[0] == 'r') || (characters[0] == 'R'))
+ & ((characters[1] == 'o') || (characters[1] == 'O'))
+ & ((characters[2] == 't') || (characters[2] == 'T'))
+ & ((characters[3] == 'a') || (characters[3] == 'A'))
+ & ((characters[4] == 't') || (characters[4] == 'T'))
+ & ((characters[5] == 'e') || (characters[5] == 'E'))
+ & (characters[7] == '(')) {
+ if ((characters[6] == 'x') || (characters[6] == 'X')) {
+ m_unit = CSSParser::FAngle;
+ m_type = WebKitCSSTransformValue::RotateXTransformOperation;
+ } else if ((characters[6] == 'y') || (characters[6] == 'Y')) {
+ m_unit = CSSParser::FAngle;
+ m_type = WebKitCSSTransformValue::RotateYTransformOperation;
+ } else if ((characters[6] == 'z') || (characters[6] == 'Z')) {
+ m_unit = CSSParser::FAngle;
+ m_type = WebKitCSSTransformValue::RotateZTransformOperation;
+ }
+ }
+ break;
+ case 9:
+ // Valid names: matrix3d(, rotate3d(.
+ if ((characters[0] == 'm') || (characters[0] == 'M')) {
+ if (((characters[1] == 'a') || (characters[1] == 'A'))
+ & ((characters[2] == 't') || (characters[2] == 'T'))
+ & ((characters[3] == 'r') || (characters[3] == 'R'))
+ & ((characters[4] == 'i') || (characters[4] == 'I'))
+ & ((characters[5] == 'x') || (characters[5] == 'X'))
+ & (characters[6] == '3')
+ & ((characters[7] == 'd') || (characters[7] == 'D'))
+ & (characters[8] == '(')) {
+ m_unit = CSSParser::FNumber;
+ m_type = WebKitCSSTransformValue::Matrix3DTransformOperation;
+ m_argCount = 31;
+ }
+ } else if (((characters[0] == 'r') || (characters[0] == 'R'))
+ & ((characters[1] == 'o') || (characters[1] == 'O'))
+ & ((characters[2] == 't') || (characters[2] == 'T'))
+ & ((characters[3] == 'a') || (characters[3] == 'A'))
+ & ((characters[4] == 't') || (characters[4] == 'T'))
+ & ((characters[5] == 'e') || (characters[5] == 'E'))
+ & (characters[6] == '3')
+ & ((characters[7] == 'd') || (characters[7] == 'D'))
+ & (characters[8] == '(')) {
+ m_unit = CSSParser::FNumber;
+ m_type = WebKitCSSTransformValue::Rotate3DTransformOperation;
+ m_argCount = 7;
+ }
+ break;
+ case 10:
+ // Valid name: translate(.
+ if (((characters[0] == 't') || (characters[0] == 'T'))
+ & ((characters[1] == 'r') || (characters[1] == 'R'))
+ & ((characters[2] == 'a') || (characters[2] == 'A'))
+ & ((characters[3] == 'n') || (characters[3] == 'N'))
+ & ((characters[4] == 's') || (characters[4] == 'S'))
+ & ((characters[5] == 'l') || (characters[5] == 'L'))
+ & ((characters[6] == 'a') || (characters[6] == 'A'))
+ & ((characters[7] == 't') || (characters[7] == 'T'))
+ & ((characters[8] == 'e') || (characters[8] == 'E'))
+ & (characters[9] == '(')) {
+ m_unit = CSSParser::FLength | CSSParser::FPercent;
m_type = WebKitCSSTransformValue::TranslateTransformOperation;
- else if (equalIgnoringCase(name, "translatex("))
- m_type = WebKitCSSTransformValue::TranslateXTransformOperation;
- else if (equalIgnoringCase(name, "translatey("))
- m_type = WebKitCSSTransformValue::TranslateYTransformOperation;
- else
- m_type = WebKitCSSTransformValue::TranslateZTransformOperation;
- } else if (equalIgnoringCase(name, "translate3d(")) {
- m_type = WebKitCSSTransformValue::Translate3DTransformOperation;
- m_argCount = 5;
- m_unit = CSSParser::FLength | CSSParser::FPercent;
- } else if (equalIgnoringCase(name, "matrix(")) {
- m_type = WebKitCSSTransformValue::MatrixTransformOperation;
- m_argCount = 11;
- m_unit = CSSParser::FNumber;
- } else if (equalIgnoringCase(name, "matrix3d(")) {
- m_type = WebKitCSSTransformValue::Matrix3DTransformOperation;
- m_argCount = 31;
- m_unit = CSSParser::FNumber;
- } else if (equalIgnoringCase(name, "perspective(")) {
- m_type = WebKitCSSTransformValue::PerspectiveTransformOperation;
- m_unit = CSSParser::FNumber;
- }
-
- if (equalIgnoringCase(name, "scale(") || equalIgnoringCase(name, "skew(") || equalIgnoringCase(name, "translate(")) {
- m_allowSingleArgument = true;
- m_argCount = 3;
- }
+ m_allowSingleArgument = true;
+ m_argCount = 3;
+ }
+ break;
+ case 11:
+ // Valid names: translatex(, translatey(, translatez(.
+ if (((characters[0] == 't') || (characters[0] == 'T'))
+ & ((characters[1] == 'r') || (characters[1] == 'R'))
+ & ((characters[2] == 'a') || (characters[2] == 'A'))
+ & ((characters[3] == 'n') || (characters[3] == 'N'))
+ & ((characters[4] == 's') || (characters[4] == 'S'))
+ & ((characters[5] == 'l') || (characters[5] == 'L'))
+ & ((characters[6] == 'a') || (characters[6] == 'A'))
+ & ((characters[7] == 't') || (characters[7] == 'T'))
+ & ((characters[8] == 'e') || (characters[8] == 'E'))
+ & (characters[10] == '(')) {
+ if ((characters[9] == 'x') || (characters[9] == 'X')) {
+ m_unit = CSSParser::FLength | CSSParser::FPercent;
+ m_type = WebKitCSSTransformValue::TranslateXTransformOperation;
+ } else if ((characters[9] == 'y') || (characters[9] == 'Y')) {
+ m_unit = CSSParser::FLength | CSSParser::FPercent;
+ m_type = WebKitCSSTransformValue::TranslateYTransformOperation;
+ } else if ((characters[9] == 'z') || (characters[9] == 'Z')) {
+ m_unit = CSSParser::FLength | CSSParser::FPercent;
+ m_type = WebKitCSSTransformValue::TranslateZTransformOperation;
+ }
+ }
+ break;
+ case 12:
+ // Valid names: perspective(, translate3d(.
+ if ((characters[0] == 'p') || (characters[0] == 'P')) {
+ if (((characters[1] == 'e') || (characters[1] == 'E'))
+ & ((characters[2] == 'r') || (characters[2] == 'R'))
+ & ((characters[3] == 's') || (characters[3] == 'S'))
+ & ((characters[4] == 'p') || (characters[4] == 'P'))
+ & ((characters[5] == 'e') || (characters[5] == 'E'))
+ & ((characters[6] == 'c') || (characters[6] == 'C'))
+ & ((characters[7] == 't') || (characters[7] == 'T'))
+ & ((characters[8] == 'i') || (characters[8] == 'I'))
+ & ((characters[9] == 'v') || (characters[9] == 'V'))
+ & ((characters[10] == 'e') || (characters[10] == 'E'))
+ & (characters[11] == '(')) {
+ m_unit = CSSParser::FNumber;
+ m_type = WebKitCSSTransformValue::PerspectiveTransformOperation;
+ }
+ } else if (((characters[0] == 't') || (characters[0] == 'T'))
+ & ((characters[1] == 'r') || (characters[1] == 'R'))
+ & ((characters[2] == 'a') || (characters[2] == 'A'))
+ & ((characters[3] == 'n') || (characters[3] == 'N'))
+ & ((characters[4] == 's') || (characters[4] == 'S'))
+ & ((characters[5] == 'l') || (characters[5] == 'L'))
+ & ((characters[6] == 'a') || (characters[6] == 'A'))
+ & ((characters[7] == 't') || (characters[7] == 'T'))
+ & ((characters[8] == 'e') || (characters[8] == 'E'))
+ & (characters[9] == '3')
+ & ((characters[10] == 'd') || (characters[10] == 'D'))
+ & (characters[11] == '(')) {
+ m_unit = CSSParser::FLength | CSSParser::FPercent;
+ m_type = WebKitCSSTransformValue::Translate3DTransformOperation;
+ m_argCount = 5;
+ }
+ break;
+ } // end switch ()
}
WebKitCSSTransformValue::TransformOperationType type() const { return m_type; }
@@ -8009,6 +8194,8 @@ bool CSSParser::parsePerspectiveOrigin(CSSPropertyID propId, CSSPropertyID& prop
switch (propId) {
case CSSPropertyWebkitPerspectiveOrigin:
+ if (m_valueList->size() > 2)
+ return false;
parseFillPosition(m_valueList.get(), value, value2);
break;
case CSSPropertyWebkitPerspectiveOriginX: {
@@ -9010,7 +9197,7 @@ inline void CSSParser::detectNumberToken(CharacterType* type, int length)
case 'd':
if (length == 3 && isASCIIAlphaCaselessEqual(type[1], 'e') && isASCIIAlphaCaselessEqual(type[2], 'g'))
m_token = DEGS;
-#if ENABLE(CSS_IMAGE_RESOLUTION)
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
else if (length > 2 && isASCIIAlphaCaselessEqual(type[1], 'p')) {
if (length == 4) {
// There is a discussion about the name of this unit on www-style.
@@ -9185,6 +9372,13 @@ inline void CSSParser::detectAtToken(int length, bool hasEscape)
m_token = FONT_FACE_SYM;
return;
+#if ENABLE(SHADOW_DOM)
+ case 'h':
+ if (length == 5 && isEqualToCSSIdentifier(name + 2, "ost"))
+ m_token = HOST_SYM;
+ return;
+#endif
+
case 'i':
if (length == 7 && isEqualToCSSIdentifier(name + 2, "mport")) {
m_parsingMode = MediaQueryMode;
@@ -9308,8 +9502,15 @@ inline void CSSParser::detectAtToken(int length, bool hasEscape)
return;
case 17:
- if (!hasEscape && isEqualToCSSIdentifier(name + 2, "webkit-selector"))
+ if (hasEscape)
+ return;
+
+ if (isASCIIAlphaCaselessEqual(name[16], 'r') && isEqualToCSSIdentifier(name + 2, "webkit-selecto"))
m_token = WEBKIT_SELECTOR_SYM;
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ else if (isASCIIAlphaCaselessEqual(name[16], 't') && isEqualToCSSIdentifier(name + 2, "webkit-viewpor"))
+ m_token = WEBKIT_VIEWPORT_RULE_SYM;
+#endif
return;
case 18:
@@ -10017,6 +10218,24 @@ StyleRuleBase* CSSParser::createFontFaceRule()
return result;
}
+#if ENABLE(SHADOW_DOM)
+StyleRuleBase* CSSParser::createHostRule(RuleList* rules)
+{
+ m_allowImportRules = m_allowNamespaceDeclarations = false;
+ RefPtr<StyleRuleHost> rule;
+ if (rules)
+ rule = StyleRuleHost::create(*rules);
+ else {
+ RuleList emptyRules;
+ rule = StyleRuleHost::create(emptyRules);
+ }
+ StyleRuleHost* result = rule.get();
+ m_parsedRules.append(rule.release());
+ processAndAddNewRuleToSourceTreeIfNeeded();
+ return result;
+}
+#endif
+
void CSSParser::addNamespace(const AtomicString& prefix, const AtomicString& uri)
{
if (!m_styleSheet || !m_allowNamespaceDeclarations)
@@ -10038,7 +10257,7 @@ void CSSParser::updateSpecifiersWithElementName(const AtomicString& namespacePre
{
AtomicString determinedNamespace = namespacePrefix != nullAtom && m_styleSheet ? m_styleSheet->determineNamespace(namespacePrefix) : m_defaultNamespace;
QualifiedName tag = QualifiedName(namespacePrefix, elementName, determinedNamespace);
- if (!specifiers->isUnknownPseudoElement()) {
+ if (!specifiers->isCustomPseudoElement()) {
specifiers->setTag(tag);
return;
}
@@ -10047,7 +10266,7 @@ void CSSParser::updateSpecifiersWithElementName(const AtomicString& namespacePre
CSSParserSelector* history = specifiers;
while (history->tagHistory()) {
history = history->tagHistory();
- if (history->isUnknownPseudoElement() || history->hasShadowDescendant())
+ if (history->isCustomPseudoElement() || history->hasShadowDescendant())
lastShadowDescendant = history;
}
@@ -10066,12 +10285,12 @@ void CSSParser::updateSpecifiersWithElementName(const AtomicString& namespacePre
CSSParserSelector* CSSParser::updateSpecifiers(CSSParserSelector* specifiers, CSSParserSelector* newSpecifier)
{
- if (newSpecifier->isUnknownPseudoElement()) {
+ if (newSpecifier->isCustomPseudoElement()) {
// Unknown pseudo element always goes at the top of selector chain.
newSpecifier->appendTagHistory(CSSSelector::ShadowDescendant, sinkFloatingSelector(specifiers));
return newSpecifier;
}
- if (specifiers->isUnknownPseudoElement()) {
+ if (specifiers->isCustomPseudoElement()) {
// Specifiers for unknown pseudo element go right behind it in the chain.
specifiers->insertTagHistory(CSSSelector::SubSelector, sinkFloatingSelector(newSpecifier), CSSSelector::ShadowDescendant);
return specifiers;
@@ -10364,6 +10583,102 @@ void CSSParser::markPropertyEnd(bool isImportantFound, bool isPropertyParsed)
resetPropertyRange();
}
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+StyleRuleBase* CSSParser::createViewportRule()
+{
+ m_allowImportRules = m_allowNamespaceDeclarations = false;
+
+ RefPtr<StyleRuleViewport> rule = StyleRuleViewport::create();
+
+ rule->setProperties(createStylePropertySet());
+ clearProperties();
+
+ StyleRuleViewport* result = rule.get();
+ m_parsedRules.append(rule.release());
+ processAndAddNewRuleToSourceTreeIfNeeded();
+
+ return result;
+}
+
+bool CSSParser::parseViewportProperty(CSSPropertyID propId, bool important)
+{
+ CSSParserValue* value = m_valueList->current();
+ if (!value)
+ return false;
+
+ int id = value->id;
+ bool validPrimitive = false;
+
+ switch (propId) {
+ case CSSPropertyMinWidth: // auto | device-width | device-height | <length> | <percentage>
+ case CSSPropertyMaxWidth:
+ case CSSPropertyMinHeight:
+ case CSSPropertyMaxHeight:
+ if (id == CSSValueAuto || id == CSSValueDeviceWidth || id == CSSValueDeviceHeight)
+ validPrimitive = true;
+ else
+ validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg));
+ break;
+ case CSSPropertyWidth: // shorthand
+ return parseViewportShorthand(propId, CSSPropertyMinWidth, CSSPropertyMaxWidth, important);
+ case CSSPropertyHeight:
+ return parseViewportShorthand(propId, CSSPropertyMinHeight, CSSPropertyMaxHeight, important);
+ case CSSPropertyMinZoom: // auto | <number> | <percentage>
+ case CSSPropertyMaxZoom:
+ case CSSPropertyZoom:
+ if (id == CSSValueAuto)
+ validPrimitive = true;
+ else
+ validPrimitive = (!id && validUnit(value, FNumber | FPercent | FNonNeg));
+ break;
+ case CSSPropertyUserZoom: // zoom | fixed
+ if (id == CSSValueZoom || id == CSSValueFixed)
+ validPrimitive = true;
+ break;
+ case CSSPropertyOrientation: // auto | portrait | landscape
+ if (id == CSSValueAuto || id == CSSValuePortrait || id == CSSValueLandscape)
+ validPrimitive = true;
+ default:
+ break;
+ }
+
+ RefPtr<CSSValue> parsedValue;
+ if (validPrimitive) {
+ parsedValue = parseValidPrimitive(id, value);
+ m_valueList->next();
+ }
+
+ if (parsedValue) {
+ if (!m_valueList->current() || inShorthand()) {
+ addProperty(propId, parsedValue.release(), important);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool CSSParser::parseViewportShorthand(CSSPropertyID propId, CSSPropertyID first, CSSPropertyID second, bool important)
+{
+ unsigned numValues = m_valueList->size();
+
+ if (numValues > 2)
+ return false;
+
+ ShorthandScope scope(this, propId);
+
+ if (!parseViewportProperty(first, important))
+ return false;
+
+ // If just one value is supplied, the second value
+ // is implicitly initialized with the first value.
+ if (numValues == 1)
+ m_valueList->previous();
+
+ return parseViewportProperty(second, important);
+}
+#endif
+
template <typename CharacterType>
static CSSPropertyID cssPropertyID(const CharacterType* propertyName, unsigned length)
{
@@ -10556,20 +10871,16 @@ static bool isCSSTokenizerURL(const String& string)
return isCSSTokenizerURL(string.characters(), length);
}
-// We use single quotes for now because markup.cpp uses double quotes.
-String quoteCSSString(const String& string)
-{
- // This function expands each character to at most 3 characters ('\u0010' -> '\' '1' '0') as well as adds
- // 2 quote characters (before and after). Make sure the resulting size (3 * length + 2) will not overflow unsigned.
- if (string.length() >= (std::numeric_limits<unsigned>::max() / 3) - 2)
- return "";
+template <typename CharacterType>
+static inline String quoteCSSStringInternal(const CharacterType* characters, unsigned length)
+{
// For efficiency, we first pre-calculate the length of the quoted string, then we build the actual one.
// Please see below for the actual logic.
unsigned quotedStringSize = 2; // Two quotes surrounding the entire string.
bool afterEscape = false;
- for (unsigned i = 0; i < string.length(); ++i) {
- UChar ch = string[i];
+ for (unsigned i = 0; i < length; ++i) {
+ CharacterType ch = characters[i];
if (ch == '\\' || ch == '\'') {
quotedStringSize += 2;
afterEscape = false;
@@ -10582,12 +10893,12 @@ String quoteCSSString(const String& string)
}
}
- StringBuffer<UChar> buffer(quotedStringSize);
+ StringBuffer<CharacterType> buffer(quotedStringSize);
unsigned index = 0;
buffer[index++] = '\'';
afterEscape = false;
- for (unsigned i = 0; i < string.length(); ++i) {
- UChar ch = string[i];
+ for (unsigned i = 0; i < length; ++i) {
+ CharacterType ch = characters[i];
if (ch == '\\' || ch == '\'') {
buffer[index++] = '\\';
buffer[index++] = ch;
@@ -10610,6 +10921,25 @@ String quoteCSSString(const String& string)
return String::adopt(buffer);
}
+// We use single quotes for now because markup.cpp uses double quotes.
+String quoteCSSString(const String& string)
+{
+ // This function expands each character to at most 3 characters ('\u0010' -> '\' '1' '0') as well as adds
+ // 2 quote characters (before and after). Make sure the resulting size (3 * length + 2) will not overflow unsigned.
+
+ unsigned length = string.length();
+
+ if (!length)
+ return String("\'\'");
+
+ if (length > std::numeric_limits<unsigned>::max() / 3 - 2)
+ return emptyString();
+
+ if (string.is8Bit())
+ return quoteCSSStringInternal(string.characters8(), length);
+ return quoteCSSStringInternal(string.characters16(), length);
+}
+
String quoteCSSStringIfNeeded(const String& string)
{
return isCSSTokenizerIdentifier(string) ? string : quoteCSSString(string);
diff --git a/Source/WebCore/css/CSSParser.h b/Source/WebCore/css/CSSParser.h
index 75668cf30..2c31794ca 100644
--- a/Source/WebCore/css/CSSParser.h
+++ b/Source/WebCore/css/CSSParser.h
@@ -47,7 +47,6 @@ namespace WebCore {
class CSSBorderImageSliceValue;
class CSSPrimitiveValue;
-class CSSProperty;
class CSSSelectorList;
class CSSValue;
class CSSValueList;
@@ -282,6 +281,9 @@ public:
StyleRuleBase* createPageRule(PassOwnPtr<CSSParserSelector> pageSelector);
StyleRuleBase* createRegionRule(CSSSelectorVector* regionSelector, RuleList* rules);
StyleRuleBase* createMarginAtRule(CSSSelector::MarginBoxType);
+#if ENABLE(SHADOW_DOM)
+ StyleRuleBase* createHostRule(RuleList* rules);
+#endif
void startDeclarationsForMarginBox();
void endDeclarationsForMarginBox();
@@ -364,6 +366,12 @@ public:
int token() { return m_token; }
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ void markViewportRuleBodyStart() { m_inViewport = true; }
+ void markViewportRuleBodyEnd() { m_inViewport = false; }
+ StyleRuleBase* createViewportRule();
+#endif
+
PassRefPtr<CSSPrimitiveValue> createPrimitiveNumericValue(CSSParserValue*);
PassRefPtr<CSSPrimitiveValue> createPrimitiveStringValue(CSSParserValue*);
#if ENABLE(CSS_VARIABLES)
@@ -452,8 +460,12 @@ private:
void recheckAtKeyword(const UChar* str, int len);
- void setupParser(const char* prefix, const String&, const char* suffix);
-
+ template<unsigned prefixLength, unsigned suffixLength>
+ inline void setupParser(const char (&prefix)[prefixLength], const String& string, const char (&suffix)[suffixLength])
+ {
+ setupParser(prefix, prefixLength - 1, string, suffix, suffixLength - 1);
+ }
+ void setupParser(const char* prefix, unsigned prefixLength, const String&, const char* suffix, unsigned suffixLength);
bool inShorthand() const { return m_inParseShorthand; }
bool validWidth(CSSParserValue*);
@@ -511,6 +523,14 @@ private:
bool m_allowImportRules;
bool m_allowNamespaceDeclarations;
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ bool parseViewportProperty(CSSPropertyID propId, bool important);
+ bool parseViewportShorthand(CSSPropertyID propId, CSSPropertyID first, CSSPropertyID second, bool important);
+
+ bool inViewport() const { return m_inViewport; }
+ bool m_inViewport;
+#endif
+
int (CSSParser::*m_lexFunc)(void*);
Vector<RefPtr<StyleRuleBase> > m_parsedRules;
@@ -545,7 +565,7 @@ private:
FFrequency = 0x0040,
FPositiveInteger = 0x0080,
FRelative = 0x0100,
-#if ENABLE(CSS_IMAGE_RESOLUTION)
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
FResolution = 0x0200,
#endif
FNonNeg = 0x0400
diff --git a/Source/WebCore/css/CSSParserValues.h b/Source/WebCore/css/CSSParserValues.h
index d3fc40353..60986a830 100644
--- a/Source/WebCore/css/CSSParserValues.h
+++ b/Source/WebCore/css/CSSParserValues.h
@@ -191,7 +191,8 @@ public:
void adoptSelectorVector(CSSSelectorVector&);
CSSSelector::PseudoType pseudoType() const { return m_selector->pseudoType(); }
- bool isUnknownPseudoElement() const { return m_selector->isUnknownPseudoElement(); }
+ bool isCustomPseudoElement() const { return m_selector->isCustomPseudoElement(); }
+
bool isSimple() const { return !m_tagHistory && m_selector->isSimple(); }
bool hasShadowDescendant() const;
diff --git a/Source/WebCore/css/CSSPrimitiveValue.cpp b/Source/WebCore/css/CSSPrimitiveValue.cpp
index 55ede8b37..c6726cdf2 100644
--- a/Source/WebCore/css/CSSPrimitiveValue.cpp
+++ b/Source/WebCore/css/CSSPrimitiveValue.cpp
@@ -62,7 +62,7 @@ static inline bool isValidCSSUnitTypeForDoubleConversion(CSSPrimitiveValue::Unit
case CSSPrimitiveValue::CSS_CM:
case CSSPrimitiveValue::CSS_DEG:
case CSSPrimitiveValue::CSS_DIMENSION:
-#if ENABLE(CSS_IMAGE_RESOLUTION)
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
case CSSPrimitiveValue::CSS_DPPX:
case CSSPrimitiveValue::CSS_DPI:
case CSSPrimitiveValue::CSS_DPCM:
@@ -94,7 +94,7 @@ static inline bool isValidCSSUnitTypeForDoubleConversion(CSSPrimitiveValue::Unit
#if ENABLE(DASHBOARD_SUPPORT)
case CSSPrimitiveValue::CSS_DASHBOARD_REGION:
#endif
-#if !ENABLE(CSS_IMAGE_RESOLUTION)
+#if !ENABLE(CSS_IMAGE_RESOLUTION) && !ENABLE(RESOLUTION_MEDIA_QUERY)
case CSSPrimitiveValue::CSS_DPPX:
case CSSPrimitiveValue::CSS_DPI:
case CSSPrimitiveValue::CSS_DPCM:
@@ -154,7 +154,7 @@ static CSSPrimitiveValue::UnitCategory unitCategory(CSSPrimitiveValue::UnitTypes
case CSSPrimitiveValue::CSS_VH:
case CSSPrimitiveValue::CSS_VMIN:
return CSSPrimitiveValue::UViewportPercentageLength;
-#if ENABLE(CSS_IMAGE_RESOLUTION)
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
case CSSPrimitiveValue::CSS_DPPX:
case CSSPrimitiveValue::CSS_DPI:
case CSSPrimitiveValue::CSS_DPCM:
@@ -676,7 +676,7 @@ CSSPrimitiveValue::UnitTypes CSSPrimitiveValue::canonicalUnitTypeForCategory(Uni
return CSS_HZ;
case UViewportPercentageLength:
return CSS_UNKNOWN; // Cannot convert between numbers and relative lengths.
-#if ENABLE(CSS_IMAGE_RESOLUTION)
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
case UResolution:
return CSS_DPPX;
#endif
@@ -896,7 +896,7 @@ String CSSPrimitiveValue::customCssText() const
case CSS_CM:
text = formatNumber(m_value.num, "cm");
break;
-#if ENABLE(CSS_IMAGE_RESOLUTION)
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
case CSS_DPPX:
text = formatNumber(m_value.num, "dppx");
break;
@@ -1228,7 +1228,7 @@ PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::cloneForCSSOM() const
case CSS_VW:
case CSS_VH:
case CSS_VMIN:
-#if ENABLE(CSS_IMAGE_RESOLUTION)
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
case CSS_DPPX:
case CSS_DPI:
case CSS_DPCM:
diff --git a/Source/WebCore/css/CSSPrimitiveValue.h b/Source/WebCore/css/CSSPrimitiveValue.h
index aa2dbeac3..fcc5b83b8 100644
--- a/Source/WebCore/css/CSSPrimitiveValue.h
+++ b/Source/WebCore/css/CSSPrimitiveValue.h
@@ -143,7 +143,7 @@ public:
UTime,
UFrequency,
UViewportPercentageLength,
-#if ENABLE(CSS_IMAGE_RESOLUTION)
+#if ENABLE(CSS_IMAGE_RESOLUTION) || ENABLE(RESOLUTION_MEDIA_QUERY)
UResolution,
#endif
UOther
@@ -181,6 +181,10 @@ public:
bool isCalculated() const { return m_primitiveUnitType == CSS_CALC; }
bool isCalculatedPercentageWithNumber() const { return primitiveType() == CSS_CALC_PERCENTAGE_WITH_NUMBER; }
bool isCalculatedPercentageWithLength() const { return primitiveType() == CSS_CALC_PERCENTAGE_WITH_LENGTH; }
+ bool isDotsPerInch() const { return primitiveType() == CSS_DPI; }
+ bool isDotsPerPixel() const { return primitiveType() == CSS_DPPX; }
+ bool isDotsPerCentimeter() const { return primitiveType() == CSS_DPCM; }
+
#if ENABLE(CSS_VARIABLES)
bool isVariableName() const { return primitiveType() == CSS_VARIABLE_NAME; }
#endif
diff --git a/Source/WebCore/css/CSSPrimitiveValueMappings.h b/Source/WebCore/css/CSSPrimitiveValueMappings.h
index 984c0826e..9b198aacd 100644
--- a/Source/WebCore/css/CSSPrimitiveValueMappings.h
+++ b/Source/WebCore/css/CSSPrimitiveValueMappings.h
@@ -1440,31 +1440,46 @@ template<> inline CSSPrimitiveValue::operator EFloat() const
return NoFloat;
}
-template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EKHTMLLineBreak e)
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(LineBreak e)
: CSSValue(PrimitiveClass)
{
m_primitiveUnitType = CSS_IDENT;
switch (e) {
- case LBNORMAL:
- m_value.ident = CSSValueNormal;
- break;
- case AFTER_WHITE_SPACE:
- m_value.ident = CSSValueAfterWhiteSpace;
- break;
+ case LineBreakAuto:
+ m_value.ident = CSSValueAuto;
+ break;
+ case LineBreakLoose:
+ m_value.ident = CSSValueLoose;
+ break;
+ case LineBreakNormal:
+ m_value.ident = CSSValueNormal;
+ break;
+ case LineBreakStrict:
+ m_value.ident = CSSValueStrict;
+ break;
+ case LineBreakAfterWhiteSpace:
+ m_value.ident = CSSValueAfterWhiteSpace;
+ break;
}
}
-template<> inline CSSPrimitiveValue::operator EKHTMLLineBreak() const
+template<> inline CSSPrimitiveValue::operator LineBreak() const
{
switch (m_value.ident) {
- case CSSValueAfterWhiteSpace:
- return AFTER_WHITE_SPACE;
- case CSSValueNormal:
- return LBNORMAL;
+ case CSSValueAuto:
+ return LineBreakAuto;
+ case CSSValueLoose:
+ return LineBreakLoose;
+ case CSSValueNormal:
+ return LineBreakNormal;
+ case CSSValueStrict:
+ return LineBreakStrict;
+ case CSSValueAfterWhiteSpace:
+ return LineBreakAfterWhiteSpace;
}
ASSERT_NOT_REACHED();
- return LBNORMAL;
+ return LineBreakAuto;
}
template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EListStylePosition e)
@@ -3400,41 +3415,41 @@ template<> inline CSSPrimitiveValue::operator ESpeak() const
}
#if ENABLE(CSS_SHADERS)
-template<> inline CSSPrimitiveValue::CSSPrimitiveValue(CustomFilterOperation::MeshBoxType meshBoxType)
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(CustomFilterMeshBoxType meshBoxType)
: CSSValue(PrimitiveClass)
{
m_primitiveUnitType = CSS_IDENT;
switch (meshBoxType) {
- case CustomFilterOperation::FILTER_BOX:
+ case MeshBoxTypeFilter:
m_value.ident = CSSValueFilterBox;
break;
- case CustomFilterOperation::BORDER_BOX:
+ case MeshBoxTypeBorder:
m_value.ident = CSSValueBorderBox;
break;
- case CustomFilterOperation::PADDING_BOX:
+ case MeshBoxTypePadding:
m_value.ident = CSSValuePaddingBox;
break;
- case CustomFilterOperation::CONTENT_BOX:
+ case MeshBoxTypeContent:
m_value.ident = CSSValueContentBox;
break;
}
}
-template<> inline CSSPrimitiveValue::operator CustomFilterOperation::MeshBoxType() const
+template<> inline CSSPrimitiveValue::operator CustomFilterMeshBoxType() const
{
switch (m_value.ident) {
case CSSValueFilterBox:
- return CustomFilterOperation::FILTER_BOX;
+ return MeshBoxTypeFilter;
case CSSValueBorderBox:
- return CustomFilterOperation::BORDER_BOX;
+ return MeshBoxTypeBorder;
case CSSValuePaddingBox:
- return CustomFilterOperation::PADDING_BOX;
+ return MeshBoxTypePadding;
case CSSValueContentBox:
- return CustomFilterOperation::CONTENT_BOX;
+ return MeshBoxTypeContent;
}
ASSERT_NOT_REACHED();
- return CustomFilterOperation::FILTER_BOX;
+ return MeshBoxTypeFilter;
}
#endif // ENABLE(CSS_SHADERS)
diff --git a/Source/WebCore/css/CSSProperty.cpp b/Source/WebCore/css/CSSProperty.cpp
index b412fdbfa..79be67b46 100644
--- a/Source/WebCore/css/CSSProperty.cpp
+++ b/Source/WebCore/css/CSSProperty.cpp
@@ -41,29 +41,6 @@ struct SameSizeAsCSSProperty {
COMPILE_ASSERT(sizeof(CSSProperty) == sizeof(SameSizeAsCSSProperty), CSSProperty_should_stay_small);
-String CSSProperty::cssName() const
-{
-#if ENABLE(CSS_VARIABLES)
- if (id() == CSSPropertyVariable) {
- ASSERT(value()->isVariableValue());
- return "-webkit-var-" + static_cast<CSSVariableValue*>(value())->name();
- }
-#endif
- return getPropertyNameString(id());
-}
-
-String CSSProperty::cssText() const
-{
- StringBuilder result;
- result.append(cssName());
- result.appendLiteral(": ");
- result.append(m_value->cssText());
- if (isImportant())
- result.appendLiteral(" !important");
- result.append(';');
- return result.toString();
-}
-
void CSSProperty::wrapValueInCommaSeparatedList()
{
RefPtr<CSSValue> value = m_value.release();
@@ -704,6 +681,12 @@ bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID)
#if ENABLE(DRAGGABLE_REGION)
case CSSPropertyWebkitAppRegion:
#endif
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ case CSSPropertyMaxZoom:
+ case CSSPropertyMinZoom:
+ case CSSPropertyOrientation:
+ case CSSPropertyUserZoom:
+#endif
return false;
case CSSPropertyInvalid:
ASSERT_NOT_REACHED();
diff --git a/Source/WebCore/css/CSSProperty.h b/Source/WebCore/css/CSSProperty.h
index fe76e846a..27650ef74 100644
--- a/Source/WebCore/css/CSSProperty.h
+++ b/Source/WebCore/css/CSSProperty.h
@@ -31,30 +31,47 @@
namespace WebCore {
-class CSSProperty {
-public:
- CSSProperty(CSSPropertyID propID, PassRefPtr<CSSValue> value, bool important = false, CSSPropertyID shorthandID = CSSPropertyInvalid, bool implicit = false)
- : m_id(propID)
+union StylePropertyMetadata {
+ StylePropertyMetadata(CSSPropertyID propertyID, CSSPropertyID shorthandID, bool important, bool implicit, bool inherited)
+ : m_propertyID(propertyID)
, m_shorthandID(shorthandID)
, m_important(important)
, m_implicit(implicit)
- , m_inherited(isInheritedProperty(propID))
+ , m_inherited(inherited)
+ {
+ }
+
+ unsigned m_bits;
+ struct {
+ unsigned m_propertyID : 14;
+ unsigned m_shorthandID : 14; // If this property was set as part of a shorthand, gives the shorthand.
+ unsigned m_important : 1;
+ unsigned m_implicit : 1; // Whether or not the property was set implicitly as the result of a shorthand.
+ unsigned m_inherited : 1;
+ };
+};
+
+class CSSProperty {
+public:
+ CSSProperty(CSSPropertyID propertyID, PassRefPtr<CSSValue> value, bool important = false, CSSPropertyID shorthandID = CSSPropertyInvalid, bool implicit = false)
+ : m_metadata(propertyID, shorthandID, important, implicit, isInheritedProperty(propertyID))
, m_value(value)
{
}
- CSSPropertyID id() const { return static_cast<CSSPropertyID>(m_id); }
- CSSPropertyID shorthandID() const { return static_cast<CSSPropertyID>(m_shorthandID); }
+ // FIXME: Remove this.
+ CSSProperty(StylePropertyMetadata metadata, CSSValue* value)
+ : m_metadata(metadata)
+ , m_value(value)
+ {
+ }
- bool isImportant() const { return m_important; }
- bool isImplicit() const { return m_implicit; }
- bool isInherited() const { return m_inherited; }
+ CSSPropertyID id() const { return static_cast<CSSPropertyID>(m_metadata.m_propertyID); }
+ CSSPropertyID shorthandID() const { return static_cast<CSSPropertyID>(m_metadata.m_shorthandID); }
+ bool isImportant() const { return m_metadata.m_important; }
CSSValue* value() const { return m_value.get(); }
- String cssName() const;
- String cssText() const;
-
void wrapValueInCommaSeparatedList();
static CSSPropertyID resolveDirectionAwareProperty(CSSPropertyID, TextDirection, WritingMode);
@@ -62,14 +79,10 @@ public:
void reportMemoryUsage(MemoryObjectInfo*) const;
-private:
- // Make sure the following fits in 4 bytes. Really.
- unsigned m_id : 14;
- unsigned m_shorthandID : 14; // If this property was set as part of a shorthand, gives the shorthand.
- unsigned m_important : 1;
- unsigned m_implicit : 1; // Whether or not the property was set implicitly as the result of a shorthand.
- unsigned m_inherited : 1;
+ StylePropertyMetadata metadata() const { return m_metadata; }
+private:
+ StylePropertyMetadata m_metadata;
RefPtr<CSSValue> m_value;
};
diff --git a/Source/WebCore/css/CSSPropertyNames.in b/Source/WebCore/css/CSSPropertyNames.in
index 8776e04be..7f699e383 100644
--- a/Source/WebCore/css/CSSPropertyNames.in
+++ b/Source/WebCore/css/CSSPropertyNames.in
@@ -402,6 +402,12 @@ z-index
-webkit-wrap-through
-webkit-wrap
#endif
+#if defined(ENABLE_CSS_DEVICE_ADAPTATION) && ENABLE_CSS_DEVICE_ADAPTATION
+max-zoom
+min-zoom
+orientation
+user-zoom
+#endif
#if defined(ENABLE_TOUCH_EVENTS) && ENABLE_TOUCH_EVENTS
-webkit-tap-highlight-color
#endif
diff --git a/Source/WebCore/css/CSSPropertySourceData.h b/Source/WebCore/css/CSSPropertySourceData.h
index 469bdb630..8982acf73 100644
--- a/Source/WebCore/css/CSSPropertySourceData.h
+++ b/Source/WebCore/css/CSSPropertySourceData.h
@@ -94,7 +94,9 @@ struct CSSRuleSourceData : public RefCounted<CSSRuleSourceData> {
FONT_FACE_RULE,
PAGE_RULE,
KEYFRAMES_RULE,
- REGION_RULE
+ REGION_RULE,
+ HOST_RULE,
+ VIEWPORT_RULE
};
static PassRefPtr<CSSRuleSourceData> create(Type type)
diff --git a/Source/WebCore/css/CSSRule.cpp b/Source/WebCore/css/CSSRule.cpp
index cd533d9a8..6c522bd03 100644
--- a/Source/WebCore/css/CSSRule.cpp
+++ b/Source/WebCore/css/CSSRule.cpp
@@ -30,12 +30,13 @@
#include "CSSStyleRule.h"
#include "CSSStyleSheet.h"
#include "CSSUnknownRule.h"
-#include "WebKitCSSKeyframeRule.h"
-#include "WebKitCSSKeyframesRule.h"
-#include "WebKitCSSRegionRule.h"
#include "NotImplemented.h"
#include "StyleRule.h"
#include "StyleSheetContents.h"
+#include "WebKitCSSKeyframeRule.h"
+#include "WebKitCSSKeyframesRule.h"
+#include "WebKitCSSRegionRule.h"
+#include "WebKitCSSViewportRule.h"
namespace WebCore {
@@ -50,6 +51,10 @@ COMPILE_ASSERT(sizeof(CSSRule) == sizeof(SameSizeAsCSSRule), CSSRule_should_stay
COMPILE_ASSERT(StyleRuleBase::Region == static_cast<StyleRuleBase::Type>(CSSRule::WEBKIT_REGION_RULE), enums_should_match);
#endif
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+COMPILE_ASSERT(StyleRuleBase::Viewport == static_cast<StyleRuleBase::Type>(CSSRule::WEBKIT_VIEWPORT_RULE), enums_should_match);
+#endif
+
void CSSRule::setCssText(const String& /*cssText*/, ExceptionCode& /*ec*/)
{
notImplemented();
@@ -76,6 +81,10 @@ String CSSRule::cssText() const
return static_cast<const WebKitCSSKeyframesRule*>(this)->cssText();
case WEBKIT_KEYFRAME_RULE:
return static_cast<const WebKitCSSKeyframeRule*>(this)->cssText();
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ case WEBKIT_VIEWPORT_RULE:
+ return static_cast<const WebKitCSSViewportRule*>(this)->cssText();
+#endif
#if ENABLE(CSS_REGIONS)
case WEBKIT_REGION_RULE:
return static_cast<const WebKitCSSRegionRule*>(this)->cssText();
@@ -115,6 +124,11 @@ void CSSRule::destroy()
case WEBKIT_KEYFRAME_RULE:
delete static_cast<WebKitCSSKeyframeRule*>(this);
return;
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ case WEBKIT_VIEWPORT_RULE:
+ delete static_cast<WebKitCSSViewportRule*>(this);
+ return;
+#endif
#if ENABLE(CSS_REGIONS)
case WEBKIT_REGION_RULE:
delete static_cast<WebKitCSSRegionRule*>(this);
@@ -155,6 +169,11 @@ void CSSRule::reattach(StyleRuleBase* rule)
// No need to reattach, the underlying data is shareable on mutation.
ASSERT_NOT_REACHED();
return;
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ case WEBKIT_VIEWPORT_RULE:
+ static_cast<WebKitCSSViewportRule*>(this)->reattach(static_cast<StyleRuleViewport*>(rule));
+ return;
+#endif
#if ENABLE(CSS_REGIONS)
case WEBKIT_REGION_RULE:
static_cast<WebKitCSSRegionRule*>(this)->reattach(static_cast<StyleRuleRegion*>(rule));
@@ -194,6 +213,11 @@ void CSSRule::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
case WEBKIT_KEYFRAME_RULE:
static_cast<const WebKitCSSKeyframeRule*>(this)->reportDescendantMemoryUsage(memoryObjectInfo);
return;
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ case WEBKIT_VIEWPORT_RULE:
+ static_cast<const WebKitCSSViewportRule*>(this)->reportDescendantMemoryUsage(memoryObjectInfo);
+ return;
+#endif
#if ENABLE(CSS_REGIONS)
case WEBKIT_REGION_RULE:
static_cast<const WebKitCSSRegionRule*>(this)->reportDescendantMemoryUsage(memoryObjectInfo);
diff --git a/Source/WebCore/css/CSSRule.h b/Source/WebCore/css/CSSRule.h
index b31fe7b8d..ab3004887 100644
--- a/Source/WebCore/css/CSSRule.h
+++ b/Source/WebCore/css/CSSRule.h
@@ -57,6 +57,9 @@ public:
// <https://bugs.webkit.org/show_bug.cgi?id=71293>.
WEBKIT_KEYFRAMES_RULE,
WEBKIT_KEYFRAME_RULE,
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ WEBKIT_VIEWPORT_RULE = 15,
+#endif
#if ENABLE(CSS_REGIONS)
WEBKIT_REGION_RULE = 16
#endif
@@ -73,6 +76,10 @@ public:
bool isStyleRule() const { return type() == STYLE_RULE; }
bool isImportRule() const { return type() == IMPORT_RULE; }
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ bool isViewportRule() const { return type() == WEBKIT_VIEWPORT_RULE; }
+#endif
+
#if ENABLE(CSS_REGIONS)
bool isRegionRule() const { return type() == WEBKIT_REGION_RULE; }
#endif
diff --git a/Source/WebCore/css/CSSSelector.cpp b/Source/WebCore/css/CSSSelector.cpp
index d2ba75677..c9dd1937a 100644
--- a/Source/WebCore/css/CSSSelector.cpp
+++ b/Source/WebCore/css/CSSSelector.cpp
@@ -218,6 +218,8 @@ PseudoId CSSSelector::pseudoId(PseudoType type)
case PseudoRightPage:
case PseudoInRange:
case PseudoOutOfRange:
+ case PseudoUserAgentCustomElement:
+ case PseudoWebKitCustomElement:
return NOPSEUDO;
case PseudoNotParsed:
ASSERT_NOT_REACHED();
@@ -387,12 +389,22 @@ CSSSelector::PseudoType CSSSelector::parsePseudoType(const AtomicString& name)
return PseudoUnknown;
HashMap<AtomicStringImpl*, CSSSelector::PseudoType>* nameToPseudoType = nameToPseudoTypeMap();
HashMap<AtomicStringImpl*, CSSSelector::PseudoType>::iterator slot = nameToPseudoType->find(name.impl());
- return slot == nameToPseudoType->end() ? PseudoUnknown : slot->value;
+
+ if (slot != nameToPseudoType->end())
+ return slot->value;
+
+ if (name.startsWith("-webkit-"))
+ return PseudoWebKitCustomElement;
+ if (name.startsWith("x-"))
+ return PseudoUserAgentCustomElement;
+
+ return PseudoUnknown;
}
-bool CSSSelector::isUnknownPseudoType(const AtomicString& name)
+bool CSSSelector::isCustomPseudoType(const AtomicString& name)
{
- return parsePseudoType(name) == PseudoUnknown;
+ CSSSelector::PseudoType type = parsePseudoType(name);
+ return type == PseudoUserAgentCustomElement || type == PseudoWebKitCustomElement;
}
void CSSSelector::extractPseudoType() const
@@ -420,6 +432,8 @@ void CSSSelector::extractPseudoType() const
case PseudoScrollbarTrack:
case PseudoScrollbarTrackPiece:
case PseudoSelection:
+ case PseudoUserAgentCustomElement:
+ case PseudoWebKitCustomElement:
element = true;
break;
case PseudoUnknown:
@@ -627,17 +641,19 @@ String CSSSelector::selectorText() const
if (CSSSelector* tagHistory = cs->tagHistory()) {
String tagHistoryText = tagHistory->selectorText();
- if (cs->relation() == CSSSelector::DirectAdjacent)
+ switch (cs->relation()) {
+ case CSSSelector::Descendant:
+ return tagHistoryText + " " + str.toString();
+ case CSSSelector::Child:
+ return tagHistoryText + " > " + str.toString();
+ case CSSSelector::DirectAdjacent:
return tagHistoryText + " + " + str.toString();
- else if (cs->relation() == CSSSelector::IndirectAdjacent)
+ case CSSSelector::IndirectAdjacent:
return tagHistoryText + " ~ " + str.toString();
- else if (cs->relation() == CSSSelector::Child)
- return tagHistoryText + " > " + str.toString();
- else if (cs->relation() == CSSSelector::ShadowDescendant)
+ case CSSSelector::SubSelector:
+ ASSERT_NOT_REACHED();
+ case CSSSelector::ShadowDescendant:
return tagHistoryText + str.toString();
- else {
- // Descendant
- return tagHistoryText + " " + str.toString();
}
}
diff --git a/Source/WebCore/css/CSSSelector.h b/Source/WebCore/css/CSSSelector.h
index 5ca24f4e0..aee5074d7 100644
--- a/Source/WebCore/css/CSSSelector.h
+++ b/Source/WebCore/css/CSSSelector.h
@@ -154,6 +154,8 @@ namespace WebCore {
#endif
PseudoInRange,
PseudoOutOfRange,
+ PseudoUserAgentCustomElement,
+ PseudoWebKitCustomElement,
};
enum MarginBoxType {
@@ -183,7 +185,7 @@ namespace WebCore {
}
static PseudoType parsePseudoType(const AtomicString&);
- static bool isUnknownPseudoType(const AtomicString&);
+ static bool isCustomPseudoType(const AtomicString&);
static PseudoId pseudoId(PseudoType);
// Selectors are kept in an array by CSSSelectorList. The next component of the selector is
@@ -211,6 +213,7 @@ namespace WebCore {
bool matchesPseudoElement() const;
bool isUnknownPseudoElement() const;
+ bool isCustomPseudoElement() const;
bool isSiblingSelector() const;
bool isAttributeSelector() const;
@@ -291,6 +294,11 @@ inline bool CSSSelector::isUnknownPseudoElement() const
return m_match == PseudoElement && m_pseudoType == PseudoUnknown;
}
+inline bool CSSSelector::isCustomPseudoElement() const
+{
+ return m_match == PseudoElement && (m_pseudoType == PseudoUserAgentCustomElement || m_pseudoType == PseudoWebKitCustomElement);
+}
+
inline bool CSSSelector::isSiblingSelector() const
{
PseudoType type = pseudoType();
diff --git a/Source/WebCore/css/CSSSelectorList.cpp b/Source/WebCore/css/CSSSelectorList.cpp
index 56d2859d2..6a8db4f3a 100644
--- a/Source/WebCore/css/CSSSelectorList.cpp
+++ b/Source/WebCore/css/CSSSelectorList.cpp
@@ -197,17 +197,17 @@ bool CSSSelectorList::selectorsNeedNamespaceResolution()
return forEachSelector(functor, this);
}
-class SelectorHasUnknownPseudoElementFunctor {
+class SelectorHasInvalidSelectorFunctor {
public:
bool operator()(CSSSelector* selector)
{
- return selector->isUnknownPseudoElement();
+ return selector->isUnknownPseudoElement() || selector->isCustomPseudoElement();
}
};
-bool CSSSelectorList::hasUnknownPseudoElements() const
+bool CSSSelectorList::hasInvalidSelector() const
{
- SelectorHasUnknownPseudoElementFunctor functor;
+ SelectorHasInvalidSelectorFunctor functor;
return forEachSelector(functor, this);
}
diff --git a/Source/WebCore/css/CSSSelectorList.h b/Source/WebCore/css/CSSSelectorList.h
index d2ce1134c..83ecf9b3f 100644
--- a/Source/WebCore/css/CSSSelectorList.h
+++ b/Source/WebCore/css/CSSSelectorList.h
@@ -59,7 +59,7 @@ public:
}
bool selectorsNeedNamespaceResolution();
- bool hasUnknownPseudoElements() const;
+ bool hasInvalidSelector() const;
String selectorsText() const;
diff --git a/Source/WebCore/css/CSSStyleDeclaration.h b/Source/WebCore/css/CSSStyleDeclaration.h
index 3247d1eae..0cd794c3f 100644
--- a/Source/WebCore/css/CSSStyleDeclaration.h
+++ b/Source/WebCore/css/CSSStyleDeclaration.h
@@ -23,6 +23,7 @@
#include "CSSPropertyNames.h"
#include "CSSRule.h"
+#include "StylePropertySet.h"
#include <wtf/Forward.h>
namespace WebCore {
@@ -30,7 +31,6 @@ namespace WebCore {
class CSSProperty;
class CSSStyleSheet;
class CSSValue;
-class StylePropertySet;
class StyledElement;
typedef int ExceptionCode;
@@ -66,7 +66,7 @@ public:
virtual PassRefPtr<StylePropertySet> copy() const = 0;
virtual PassRefPtr<StylePropertySet> makeMutable() = 0;
- virtual bool cssPropertyMatches(const CSSProperty*) const = 0;
+ virtual bool cssPropertyMatches(const StylePropertySet::PropertyReference&) const = 0;
virtual CSSStyleSheet* parentStyleSheet() const { return 0; }
virtual void reportMemoryUsage(MemoryObjectInfo*) const = 0;
diff --git a/Source/WebCore/css/CSSValueKeywords.in b/Source/WebCore/css/CSSValueKeywords.in
index c60aa586d..4b9cc6ea6 100644
--- a/Source/WebCore/css/CSSValueKeywords.in
+++ b/Source/WebCore/css/CSSValueKeywords.in
@@ -621,6 +621,10 @@ space
//
// CSS_PROP__KHTML_LINE_BREAK
//
+// auto
+loose
+// normal
+strict
after-white-space
// -webkit-appearance
@@ -771,6 +775,24 @@ step-end
document
reset
+#if defined(ENABLE_CSS_DEVICE_ADAPTATION) && ENABLE_CSS_DEVICE_ADAPTATION
+//
+// CSS_PROP_USER_ZOOM
+//
+// fixed
+zoom
+
+//
+// CSS_PROP_MIN_WIDTH
+// CSS_PROP_MAX_WIDTH
+// CSS_PROP_MIN_HEIGHT
+// CSS_PROP_MAX_HEIGHT
+//
+// auto
+device-width
+device-height
+#endif
+
//
// CSS_PROP_POINTER_EVENTS
//
diff --git a/Source/WebCore/css/CSSValueList.h b/Source/WebCore/css/CSSValueList.h
index 06415fb18..3d897bcfe 100644
--- a/Source/WebCore/css/CSSValueList.h
+++ b/Source/WebCore/css/CSSValueList.h
@@ -50,6 +50,7 @@ public:
size_t length() const { return m_values.size(); }
CSSValue* item(size_t index) { return index < m_values.size() ? m_values[index].get() : 0; }
+ const CSSValue* item(size_t index) const { return index < m_values.size() ? m_values[index].get() : 0; }
CSSValue* itemWithoutBoundsCheck(size_t index) { return m_values[index].get(); }
void append(PassRefPtr<CSSValue> value) { m_values.append(value); }
diff --git a/Source/WebCore/css/CachedSVGDocumentReference.h b/Source/WebCore/css/CachedSVGDocumentReference.h
new file mode 100644
index 000000000..2a253abd4
--- /dev/null
+++ b/Source/WebCore/css/CachedSVGDocumentReference.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CachedSVGDocumentReference_h
+#define CachedSVGDocumentReference_h
+
+#if ENABLE(SVG) && ENABLE(CSS_FILTERS)
+#include "CachedResourceHandle.h"
+#include "FilterOperation.h"
+
+namespace WebCore {
+
+class CachedSVGDocument;
+
+class CachedSVGDocumentReference : public ReferenceFilterOperation::Data, public CachedSVGDocumentClient {
+public:
+ CachedSVGDocumentReference(CachedSVGDocument* document) : m_document(document) { m_document->addClient(this); }
+ virtual ~CachedSVGDocumentReference() { m_document->removeClient(this); }
+ CachedSVGDocument* document() { return m_document.get(); }
+private:
+ CachedResourceHandle<CachedSVGDocument> m_document;
+};
+
+};
+
+#endif
+
+#endif
diff --git a/Source/WebCore/css/MediaFeatureNames.h b/Source/WebCore/css/MediaFeatureNames.h
index b08439e4a..26668ae46 100644
--- a/Source/WebCore/css/MediaFeatureNames.h
+++ b/Source/WebCore/css/MediaFeatureNames.h
@@ -47,6 +47,7 @@ namespace WebCore {
macro(max_height, "max-height") \
macro(max_monochrome, "max-monochrome") \
macro(max_width, "max-width") \
+ macro(max_resolution, "max-resolution") \
macro(min_color, "min-color") \
macro(min_aspect_ratio, "min-aspect-ratio") \
macro(min_device_aspect_ratio, "min-device-aspect-ratio") \
@@ -56,7 +57,9 @@ namespace WebCore {
macro(min_height, "min-height") \
macro(min_monochrome, "min-monochrome") \
macro(min_width, "min-width") \
+ macro(min_resolution, "min-resolution") \
macro(pointer, "pointer") \
+ macro(resolution, "resolution") \
macro(transform_2d, "-webkit-transform-2d") \
macro(transform_3d, "-webkit-transform-3d") \
macro(transition, "-webkit-transition") \
diff --git a/Source/WebCore/css/MediaQueryEvaluator.cpp b/Source/WebCore/css/MediaQueryEvaluator.cpp
index daa490b8b..2cf69990d 100644
--- a/Source/WebCore/css/MediaQueryEvaluator.cpp
+++ b/Source/WebCore/css/MediaQueryEvaluator.cpp
@@ -29,11 +29,12 @@
#include "MediaQueryEvaluator.h"
#include "CSSAspectRatioValue.h"
-#include "Chrome.h"
-#include "ChromeClient.h"
#include "CSSPrimitiveValue.h"
#include "CSSValueKeywords.h"
#include "CSSValueList.h"
+#include "Chrome.h"
+#include "ChromeClient.h"
+#include "DOMWindow.h"
#include "FloatRect.h"
#include "Frame.h"
#include "FrameView.h"
@@ -45,8 +46,9 @@
#include "NodeRenderStyle.h"
#include "Page.h"
#include "PlatformScreen.h"
-#include "RenderView.h"
#include "RenderStyle.h"
+#include "RenderView.h"
+#include "Screen.h"
#include "Settings.h"
#include "StyleResolver.h"
#include <wtf/HashMap.h>
@@ -66,15 +68,13 @@ typedef HashMap<AtomicStringImpl*, EvalFunc> FunctionMap;
static FunctionMap* gFunctionMap;
/*
- * FIXME: following media features are not implemented: color_index, scan, resolution
+ * FIXME: following media features are not implemented: color_index, scan
*
* color_index, min-color-index, max_color_index: It's unknown how to retrieve
* the information if the display mode is indexed
* scan: The "scan" media feature describes the scanning process of
* tv output devices. It's unknown how to retrieve this information from
* the platform
- * resolution, min-resolution, max-resolution: css parser doesn't seem to
- * support CSS_DIMENSION
*/
MediaQueryEvaluator::MediaQueryEvaluator(bool mediaFeatureResult)
@@ -197,6 +197,23 @@ static bool compareAspectRatioValue(CSSValue* value, int width, int height, Medi
return false;
}
+#if ENABLE(RESOLUTION_MEDIA_QUERY)
+static bool compareResolution(float min, float max, float value, MediaFeaturePrefix op)
+{
+ switch (op) {
+ case NoPrefix:
+ // A 'resolution' (without a "min-" or "max-" prefix) query
+ // never matches a device with non-square pixels.
+ return value == min && value == max;
+ case MinPrefix:
+ return min >= value;
+ case MaxPrefix:
+ return max <= value;
+ }
+ return false;
+}
+#endif
+
static bool numberValue(CSSValue* value, float& result)
{
if (value->isPrimitiveValue()
@@ -272,10 +289,128 @@ static bool device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle*, F
static bool device_pixel_ratioMediaFeatureEval(CSSValue *value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
{
- if (value)
- return value->isPrimitiveValue() && compareValue(frame->page()->deviceScaleFactor(), static_cast<CSSPrimitiveValue*>(value)->getFloatValue(), op);
+ // FIXME: Possible handle other media types than 'screen' and 'print'.
+ float deviceScaleFactor = 0;
+
+ // This checks the actual media type applied to the document, and we know
+ // this method only got called if this media type matches the one defined
+ // in the query. Thus, if if the document's media type is "print", the
+ // media type of the query will either be "print" or "all".
+ String mediaType = frame->view()->mediaType();
+ if (equalIgnoringCase(mediaType, "screen"))
+ deviceScaleFactor = frame->page()->deviceScaleFactor();
+ else if (equalIgnoringCase(mediaType, "print")) {
+ // The resolution of images while printing should not depend on the dpi
+ // of the screen. Until we support proper ways of querying this info
+ // we use 300px which is considered minimum for current printers.
+ deviceScaleFactor = 3.125; // 300dpi / 96dpi;
+ }
- return frame->page()->deviceScaleFactor() != 0;
+ if (!value)
+ return !!deviceScaleFactor;
+
+ return value->isPrimitiveValue() && compareValue(deviceScaleFactor, static_cast<CSSPrimitiveValue*>(value)->getFloatValue(), op);
+}
+
+static bool resolutionMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
+{
+#if ENABLE(RESOLUTION_MEDIA_QUERY)
+ // The DPI below is dots per CSS inch and thus not device inch. The
+ // functions should respect this.
+ //
+ // For square pixels, it is simply the device scale factor (dppx) times 96,
+ // per definition.
+ //
+ // The device scale factor is a predefined value which is calculated per
+ // device given the preferred distance in arms length (considered one arms
+ // length for desktop computers and usually 0.6 arms length for phones).
+ //
+ // The value can be calculated as follows (rounded to quarters):
+ // round((deviceDotsPerInch * distanceInArmsLength / 96) * 4) / 4.
+ // Example (mid-range resolution phone):
+ // round((244 * 0.6 / 96) * 4) / 4 = 1.5
+ // Example (high-range resolution laptop):
+ // round((220 * 1.0 / 96) * 4) / 4 = 2.0
+
+ float horiDPI;
+ float vertDPI;
+
+ // This checks the actual media type applied to the document, and we know
+ // this method only got called if this media type matches the one defined
+ // in the query. Thus, if if the document's media type is "print", the
+ // media type of the query will either be "print" or "all".
+ String mediaType = frame->view()->mediaType();
+ if (equalIgnoringCase(mediaType, "screen")) {
+ Screen* screen = frame->document()->domWindow()->screen();
+ horiDPI = screen->horizontalDPI();
+ vertDPI = screen->verticalDPI();
+ } else if (equalIgnoringCase(mediaType, "print")) {
+ // The resolution of images while printing should not depend on the dpi
+ // of the screen. Until we support proper ways of querying this info
+ // we use 300px which is considered minimum for current printers.
+ horiDPI = vertDPI = 300;
+ } else {
+ // FIXME: Possible handle other media types than 'screen' and 'print'.
+ // For now, do not match.
+ return false;
+ }
+
+ float leastDenseDPI = std::min(horiDPI, vertDPI);
+ float mostDenseDPI = std::max(horiDPI, vertDPI);
+
+ // According to spec, (resolution) will evaluate to true if (resolution:x)
+ // will evaluate to true for a value x other than zero or zero followed by
+ // a valid unit identifier (i.e., other than 0, 0dpi, 0dpcm, or 0dppx.),
+ // which is always the case. But the spec special cases 'resolution' to
+ // never matches a device with non-square pixels.
+ if (!value) {
+ ASSERT(op == NoPrefix);
+ return leastDenseDPI == mostDenseDPI;
+ }
+
+ if (!value->isPrimitiveValue())
+ return false;
+
+ // http://dev.w3.org/csswg/css3-values/#resolution defines resolution as a
+ // dimension, which contains a number (decimal point allowed), not just an
+ // integer. Also, http://dev.w3.org/csswg/css3-values/#numeric-types says
+ // "CSS theoretically supports infinite precision and infinite ranges for
+ // all value types;
+ CSSPrimitiveValue* rawValue = static_cast<CSSPrimitiveValue*>(value);
+
+ if (rawValue->isDotsPerPixel()) {
+ // http://dev.w3.org/csswg/css3-values/#absolute-lengths recommends
+ // "that the pixel unit refer to the whole number of device pixels that
+ // best approximates the reference pixel". We compare with 3 decimal
+ // points, which aligns with current device-pixel-ratio's in use.
+ float leastDenseDensity = floorf(leastDenseDPI * 1000 / 96) / 1000;
+ float mostDenseDensity = floorf(leastDenseDPI * 1000 / 96) / 1000;
+ float testedDensity = rawValue->getFloatValue(CSSPrimitiveValue::CSS_DPPX);
+ return compareResolution(leastDenseDensity, mostDenseDensity, testedDensity, op);
+ }
+
+ if (rawValue->isDotsPerInch()) {
+ unsigned testedDensity = rawValue->getFloatValue(CSSPrimitiveValue::CSS_DPI);
+ return compareResolution(leastDenseDPI, mostDenseDPI, testedDensity, op);
+ }
+
+ // http://dev.w3.org/csswg/css3-values/#absolute-lengths recommends "that
+ // the pixel unit refer to the whole number of device pixels that best
+ // approximates the reference pixel".
+ float leastDenseDPCM = roundf(leastDenseDPI / 2.54); // (2.54 cm/in)
+ float mostDenseDPCM = roundf(mostDenseDPI / 2.54);
+
+ if (rawValue->isDotsPerCentimeter()) {
+ float testedDensity = rawValue->getFloatValue(CSSPrimitiveValue::CSS_DPCM);
+ return compareResolution(leastDenseDPCM, mostDenseDPCM, testedDensity, op);
+ }
+#else
+ UNUSED_PARAM(value);
+ UNUSED_PARAM(frame);
+ UNUSED_PARAM(op);
+#endif
+
+ return false;
}
static bool gridMediaFeatureEval(CSSValue* value, RenderStyle*, Frame*, MediaFeaturePrefix op)
@@ -456,6 +591,16 @@ static bool max_device_widthMediaFeatureEval(CSSValue* value, RenderStyle* style
return device_widthMediaFeatureEval(value, style, frame, MaxPrefix);
}
+static bool min_resolutionMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+{
+ return resolutionMediaFeatureEval(value, style, frame, MinPrefix);
+}
+
+static bool max_resolutionMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+{
+ return resolutionMediaFeatureEval(value, style, frame, MaxPrefix);
+}
+
static bool animationMediaFeatureEval(CSSValue* value, RenderStyle*, Frame*, MediaFeaturePrefix op)
{
if (value) {
diff --git a/Source/WebCore/css/MediaQueryExp.cpp b/Source/WebCore/css/MediaQueryExp.cpp
index 1a06b7965..23be429ca 100644
--- a/Source/WebCore/css/MediaQueryExp.cpp
+++ b/Source/WebCore/css/MediaQueryExp.cpp
@@ -67,6 +67,16 @@ static inline bool featureWithValidPositiveLenghtOrNumber(const AtomicString& me
|| mediaFeature == MediaFeatureNames::min_device_widthMediaFeature;
}
+static inline bool featureWithValidDensity(const AtomicString& mediaFeature, const CSSParserValue* value)
+{
+ if ((value->unit != CSSPrimitiveValue::CSS_DPPX && value->unit != CSSPrimitiveValue::CSS_DPI && value->unit != CSSPrimitiveValue::CSS_DPCM) || value->fValue <= 0)
+ return false;
+
+ return mediaFeature == MediaFeatureNames::resolutionMediaFeature
+ || mediaFeature == MediaFeatureNames::max_resolutionMediaFeature
+ || mediaFeature == MediaFeatureNames::min_resolutionMediaFeature;
+}
+
static inline bool featureWithPositiveInteger(const AtomicString& mediaFeature, const CSSParserValue* value)
{
if (!value->isInt || value->fValue < 0)
@@ -114,6 +124,7 @@ static inline bool featureWithAspectRatio(const AtomicString& mediaFeature)
static inline bool featureWithoutValue(const AtomicString& mediaFeature)
{
+ // Media features that are prefixed by min/max cannot be used without a value.
return mediaFeature == MediaFeatureNames::monochromeMediaFeature
|| mediaFeature == MediaFeatureNames::colorMediaFeature
|| mediaFeature == MediaFeatureNames::gridMediaFeature
@@ -131,7 +142,8 @@ static inline bool featureWithoutValue(const AtomicString& mediaFeature)
|| mediaFeature == MediaFeatureNames::animationMediaFeature
|| mediaFeature == MediaFeatureNames::view_modeMediaFeature
|| mediaFeature == MediaFeatureNames::pointerMediaFeature
- || mediaFeature == MediaFeatureNames::device_pixel_ratioMediaFeature;
+ || mediaFeature == MediaFeatureNames::device_pixel_ratioMediaFeature
+ || mediaFeature == MediaFeatureNames::resolutionMediaFeature;
}
inline MediaQueryExp::MediaQueryExp(const AtomicString& mediaFeature, CSSParserValueList* valueList)
@@ -148,6 +160,10 @@ inline MediaQueryExp::MediaQueryExp(const AtomicString& mediaFeature, CSSParserV
if (featureWithCSSValueID(mediaFeature, value))
m_value = CSSPrimitiveValue::createIdentifier(value->id);
+ // Media features that must have non-negative <density>, ie. dppx, dpi or dpcm.
+ else if (featureWithValidDensity(mediaFeature, value))
+ m_value = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
+
// Media features that must have non-negative <lenght> or number value.
else if (featureWithValidPositiveLenghtOrNumber(mediaFeature, value))
m_value = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
diff --git a/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp b/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp
index 93d4e4538..824d90fb2 100644
--- a/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp
+++ b/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp
@@ -30,7 +30,6 @@
#include "MutationRecord.h"
#include "StylePropertySet.h"
#include "StyledElement.h"
-#include "UndoManager.h"
#include "WebCoreMemoryInstrumentation.h"
#include <wtf/MemoryInstrumentationHashMap.h>
@@ -55,39 +54,25 @@ public:
ASSERT(!s_currentDecl);
s_currentDecl = decl;
-#if ENABLE(MUTATION_OBSERVERS) || ENABLE(UNDO_MANAGER)
+#if ENABLE(MUTATION_OBSERVERS)
if (!s_currentDecl->parentElement())
return;
bool shouldReadOldValue = false;
-#if ENABLE(MUTATION_OBSERVERS)
m_mutationRecipients = MutationObserverInterestGroup::createForAttributesMutation(s_currentDecl->parentElement(), HTMLNames::styleAttr);
if (m_mutationRecipients && m_mutationRecipients->isOldValueRequested())
shouldReadOldValue = true;
-#endif
-#if ENABLE(UNDO_MANAGER)
- m_isRecordingAutomaticTransaction = UndoManager::isRecordingAutomaticTransaction(s_currentDecl->parentElement());
- if (m_isRecordingAutomaticTransaction)
- shouldReadOldValue = true;
-#endif
AtomicString oldValue;
if (shouldReadOldValue)
oldValue = s_currentDecl->parentElement()->getAttribute(HTMLNames::styleAttr);
-#if ENABLE(MUTATION_OBSERVERS)
if (m_mutationRecipients) {
AtomicString requestedOldValue = m_mutationRecipients->isOldValueRequested() ? oldValue : nullAtom;
m_mutation = MutationRecord::createAttributes(s_currentDecl->parentElement(), HTMLNames::styleAttr, requestedOldValue);
}
#endif
-#if ENABLE(UNDO_MANAGER)
- if (m_isRecordingAutomaticTransaction)
- m_oldValue = oldValue;
-#endif
-
-#endif
}
~StyleAttributeMutationScope()
@@ -99,14 +84,7 @@ public:
#if ENABLE(MUTATION_OBSERVERS)
if (m_mutation && s_shouldDeliver)
m_mutationRecipients->enqueueMutationRecord(m_mutation);
-#endif
-#if ENABLE(UNDO_MANAGER)
- if (m_isRecordingAutomaticTransaction && s_shouldDeliver) {
- UndoManager::addTransactionStep(AttrChangingDOMTransactionStep::create(
- s_currentDecl->parentElement(), HTMLNames::styleAttr, m_oldValue, s_currentDecl->parentElement()->getAttribute(HTMLNames::styleAttr)));
- }
-#endif
-#if ENABLE(MUTATION_OBSERVERS) || ENABLE(UNDO_MANAGER)
+
s_shouldDeliver = false;
#endif
if (!s_shouldNotifyInspector) {
@@ -121,7 +99,7 @@ public:
InspectorInstrumentation::didInvalidateStyleAttr(localCopyStyleDecl->parentElement()->document(), localCopyStyleDecl->parentElement());
}
-#if ENABLE(MUTATION_OBSERVERS) || ENABLE(UNDO_MANAGER)
+#if ENABLE(MUTATION_OBSERVERS)
void enqueueMutationRecord()
{
s_shouldDeliver = true;
@@ -137,7 +115,7 @@ private:
static unsigned s_scopeCount;
static PropertySetCSSStyleDeclaration* s_currentDecl;
static bool s_shouldNotifyInspector;
-#if ENABLE(MUTATION_OBSERVERS) || ENABLE(UNDO_MANAGER)
+#if ENABLE(MUTATION_OBSERVERS)
static bool s_shouldDeliver;
#endif
@@ -145,16 +123,12 @@ private:
OwnPtr<MutationObserverInterestGroup> m_mutationRecipients;
RefPtr<MutationRecord> m_mutation;
#endif
-#if ENABLE(UNDO_MANAGER)
- bool m_isRecordingAutomaticTransaction;
- AtomicString m_oldValue;
-#endif
};
unsigned StyleAttributeMutationScope::s_scopeCount = 0;
PropertySetCSSStyleDeclaration* StyleAttributeMutationScope::s_currentDecl = 0;
bool StyleAttributeMutationScope::s_shouldNotifyInspector = false;
-#if ENABLE(MUTATION_OBSERVERS) || ENABLE(UNDO_MANAGER)
+#if ENABLE(MUTATION_OBSERVERS)
bool StyleAttributeMutationScope::s_shouldDeliver = false;
#endif
@@ -196,7 +170,7 @@ String PropertySetCSSStyleDeclaration::cssText() const
void PropertySetCSSStyleDeclaration::setCssText(const String& text, ExceptionCode& ec)
{
-#if ENABLE(MUTATION_OBSERVERS) || ENABLE(UNDO_MANAGER)
+#if ENABLE(MUTATION_OBSERVERS)
StyleAttributeMutationScope mutationScope(this);
#endif
willMutate();
@@ -207,7 +181,7 @@ void PropertySetCSSStyleDeclaration::setCssText(const String& text, ExceptionCod
didMutate(PropertyChanged);
-#if ENABLE(MUTATION_OBSERVERS) || ENABLE(UNDO_MANAGER)
+#if ENABLE(MUTATION_OBSERVERS)
mutationScope.enqueueMutationRecord();
#endif
}
@@ -257,7 +231,7 @@ bool PropertySetCSSStyleDeclaration::isPropertyImplicit(const String& propertyNa
void PropertySetCSSStyleDeclaration::setProperty(const String& propertyName, const String& value, const String& priority, ExceptionCode& ec)
{
-#if ENABLE(MUTATION_OBSERVERS) || ENABLE(UNDO_MANAGER)
+#if ENABLE(MUTATION_OBSERVERS)
StyleAttributeMutationScope mutationScope(this);
#endif
CSSPropertyID propertyID = cssPropertyID(propertyName);
@@ -276,7 +250,7 @@ void PropertySetCSSStyleDeclaration::setProperty(const String& propertyName, con
if (changed) {
// CSS DOM requires raising SYNTAX_ERR of parsing failed, but this is too dangerous for compatibility,
// see <http://bugs.webkit.org/show_bug.cgi?id=7296>.
-#if ENABLE(MUTATION_OBSERVERS) || ENABLE(UNDO_MANAGER)
+#if ENABLE(MUTATION_OBSERVERS)
mutationScope.enqueueMutationRecord();
#endif
}
@@ -284,7 +258,7 @@ void PropertySetCSSStyleDeclaration::setProperty(const String& propertyName, con
String PropertySetCSSStyleDeclaration::removeProperty(const String& propertyName, ExceptionCode& ec)
{
-#if ENABLE(MUTATION_OBSERVERS) || ENABLE(UNDO_MANAGER)
+#if ENABLE(MUTATION_OBSERVERS)
StyleAttributeMutationScope mutationScope(this);
#endif
CSSPropertyID propertyID = cssPropertyID(propertyName);
@@ -300,7 +274,7 @@ String PropertySetCSSStyleDeclaration::removeProperty(const String& propertyName
didMutate(changed ? PropertyChanged : NoChanges);
if (changed) {
-#if ENABLE(MUTATION_OBSERVERS) || ENABLE(UNDO_MANAGER)
+#if ENABLE(MUTATION_OBSERVERS)
mutationScope.enqueueMutationRecord();
#endif
}
@@ -319,7 +293,7 @@ String PropertySetCSSStyleDeclaration::getPropertyValueInternal(CSSPropertyID pr
void PropertySetCSSStyleDeclaration::setPropertyInternal(CSSPropertyID propertyID, const String& value, bool important, ExceptionCode& ec)
{
-#if ENABLE(MUTATION_OBSERVERS) || ENABLE(UNDO_MANAGER)
+#if ENABLE(MUTATION_OBSERVERS)
StyleAttributeMutationScope mutationScope(this);
#endif
willMutate();
@@ -330,7 +304,7 @@ void PropertySetCSSStyleDeclaration::setPropertyInternal(CSSPropertyID propertyI
didMutate(changed ? PropertyChanged : NoChanges);
if (changed) {
-#if ENABLE(MUTATION_OBSERVERS) || ENABLE(UNDO_MANAGER)
+#if ENABLE(MUTATION_OBSERVERS)
mutationScope.enqueueMutationRecord();
#endif
}
@@ -369,7 +343,7 @@ PassRefPtr<StylePropertySet> PropertySetCSSStyleDeclaration::makeMutable()
return m_propertySet;
}
-bool PropertySetCSSStyleDeclaration::cssPropertyMatches(const CSSProperty* property) const
+bool PropertySetCSSStyleDeclaration::cssPropertyMatches(const StylePropertySet::PropertyReference& property) const
{
return m_propertySet->propertyMatches(property);
}
diff --git a/Source/WebCore/css/PropertySetCSSStyleDeclaration.h b/Source/WebCore/css/PropertySetCSSStyleDeclaration.h
index 0bbd64b7c..cb10437df 100644
--- a/Source/WebCore/css/PropertySetCSSStyleDeclaration.h
+++ b/Source/WebCore/css/PropertySetCSSStyleDeclaration.h
@@ -67,7 +67,7 @@ private:
virtual String getPropertyValueInternal(CSSPropertyID) OVERRIDE;
virtual void setPropertyInternal(CSSPropertyID, const String& value, bool important, ExceptionCode&) OVERRIDE;
- virtual bool cssPropertyMatches(const CSSProperty*) const OVERRIDE;
+ virtual bool cssPropertyMatches(const StylePropertySet::PropertyReference&) const OVERRIDE;
virtual PassRefPtr<StylePropertySet> copy() const OVERRIDE;
virtual PassRefPtr<StylePropertySet> makeMutable() OVERRIDE;
diff --git a/Source/WebCore/css/RuleFeature.cpp b/Source/WebCore/css/RuleFeature.cpp
index 663b94613..b1f929687 100644
--- a/Source/WebCore/css/RuleFeature.cpp
+++ b/Source/WebCore/css/RuleFeature.cpp
@@ -38,11 +38,14 @@ namespace WebCore {
void RuleFeatureSet::add(const RuleFeatureSet& other)
{
- HashSet<AtomicStringImpl*>::iterator end = other.idsInRules.end();
- for (HashSet<AtomicStringImpl*>::iterator it = other.idsInRules.begin(); it != end; ++it)
+ HashSet<AtomicStringImpl*>::const_iterator end = other.idsInRules.end();
+ for (HashSet<AtomicStringImpl*>::const_iterator it = other.idsInRules.begin(); it != end; ++it)
idsInRules.add(*it);
+ end = other.classesInRules.end();
+ for (HashSet<AtomicStringImpl*>::const_iterator it = other.classesInRules.begin(); it != end; ++it)
+ classesInRules.add(*it);
end = other.attrsInRules.end();
- for (HashSet<AtomicStringImpl*>::iterator it = other.attrsInRules.begin(); it != end; ++it)
+ for (HashSet<AtomicStringImpl*>::const_iterator it = other.attrsInRules.begin(); it != end; ++it)
attrsInRules.add(*it);
siblingRules.append(other.siblingRules);
uncommonAttributeRules.append(other.uncommonAttributeRules);
@@ -53,6 +56,7 @@ void RuleFeatureSet::add(const RuleFeatureSet& other)
void RuleFeatureSet::clear()
{
idsInRules.clear();
+ classesInRules.clear();
attrsInRules.clear();
siblingRules.clear();
uncommonAttributeRules.clear();
@@ -64,6 +68,7 @@ void RuleFeatureSet::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
info.addMember(idsInRules);
+ info.addMember(classesInRules);
info.addMember(attrsInRules);
info.addMember(siblingRules);
info.addMember(uncommonAttributeRules);
diff --git a/Source/WebCore/css/RuleFeature.h b/Source/WebCore/css/RuleFeature.h
index 5f16288c0..ce6d04e66 100644
--- a/Source/WebCore/css/RuleFeature.h
+++ b/Source/WebCore/css/RuleFeature.h
@@ -31,8 +31,7 @@ namespace WebCore {
class StyleRule;
-class RuleFeature {
-public:
+struct RuleFeature {
RuleFeature(StyleRule* rule, unsigned selectorIndex, bool hasDocumentSecurityOrigin)
: rule(rule)
, selectorIndex(selectorIndex)
@@ -44,8 +43,7 @@ public:
bool hasDocumentSecurityOrigin;
};
-class RuleFeatureSet {
-public:
+struct RuleFeatureSet {
RuleFeatureSet()
: usesFirstLineRules(false)
, usesBeforeAfterRules(false)
@@ -55,6 +53,7 @@ public:
void clear();
void reportMemoryUsage(MemoryObjectInfo*) const;
HashSet<AtomicStringImpl*> idsInRules;
+ HashSet<AtomicStringImpl*> classesInRules;
HashSet<AtomicStringImpl*> attrsInRules;
Vector<RuleFeature> siblingRules;
Vector<RuleFeature> uncommonAttributeRules;
diff --git a/Source/WebCore/css/RuleSet.cpp b/Source/WebCore/css/RuleSet.cpp
index e2be5771e..e92d1768b 100644
--- a/Source/WebCore/css/RuleSet.cpp
+++ b/Source/WebCore/css/RuleSet.cpp
@@ -107,18 +107,18 @@ static inline bool containsUncommonAttributeSelector(const CSSSelector* selector
return false;
}
-RuleData::RuleData(StyleRule* rule, unsigned selectorIndex, unsigned position, bool hasDocumentSecurityOrigin, bool canUseFastCheckSelector, bool inRegionRule)
+RuleData::RuleData(StyleRule* rule, unsigned selectorIndex, unsigned position, AddRuleFlags addRuleFlags)
: m_rule(rule)
, m_selectorIndex(selectorIndex)
, m_position(position)
, m_specificity(selector()->specificity())
- , m_hasFastCheckableSelector(canUseFastCheckSelector && SelectorChecker::isFastCheckableSelector(selector()))
+ , m_hasFastCheckableSelector((addRuleFlags & RuleCanUseFastCheckSelector) && SelectorChecker::isFastCheckableSelector(selector()))
, m_hasMultipartSelector(!!selector()->tagHistory())
, m_hasRightmostSelectorMatchingHTMLBasedOnRuleHash(isSelectorMatchingHTMLBasedOnRuleHash(selector()))
, m_containsUncommonAttributeSelector(WebCore::containsUncommonAttributeSelector(selector()))
, m_linkMatchType(SelectorChecker::determineLinkMatchType(selector()))
- , m_hasDocumentSecurityOrigin(hasDocumentSecurityOrigin)
- , m_isInRegionRule(inRegionRule)
+ , m_hasDocumentSecurityOrigin(addRuleFlags & RuleHasDocumentSecurityOrigin)
+ , m_isInRegionRule(addRuleFlags & RuleIsInRegionRule)
{
ASSERT(m_position == position);
ASSERT(m_selectorIndex == selectorIndex);
@@ -161,7 +161,9 @@ static inline void collectFeaturesFromSelector(RuleFeatureSet& features, const C
{
if (selector->m_match == CSSSelector::Id)
features.idsInRules.add(selector->value().impl());
- if (selector->isAttributeSelector())
+ else if (selector->m_match == CSSSelector::Class)
+ features.classesInRules.add(selector->value().impl());
+ else if (selector->isAttributeSelector())
features.attrsInRules.add(selector->attribute().localName().impl());
switch (selector->pseudoType()) {
case CSSSelector::PseudoFirstLine:
@@ -207,9 +209,14 @@ void RuleSet::addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map, const RuleDa
rules->append(ruleData);
}
-void RuleSet::addRule(StyleRule* rule, unsigned selectorIndex, bool hasDocumentSecurityOrigin, bool canUseFastCheckSelector, bool inRegionRule)
+void RuleSet::addRule(StyleRule* rule, unsigned selectorIndex, AddRuleFlags addRuleFlags)
{
- RuleData ruleData(rule, selectorIndex, m_ruleCount++, hasDocumentSecurityOrigin, canUseFastCheckSelector, inRegionRule);
+ RuleData ruleData(rule, selectorIndex, m_ruleCount++, addRuleFlags);
+ static const unsigned athostRuleSpecificity = 0x100000;
+
+ if (addRuleFlags & RuleIsHostRule)
+ ruleData.increaseSpecificity(athostRuleSpecificity);
+
collectFeaturesFromRuleData(m_features, ruleData);
CSSSelector* selector = ruleData.selector();
@@ -222,7 +229,7 @@ void RuleSet::addRule(StyleRule* rule, unsigned selectorIndex, bool hasDocumentS
addToRuleSet(selector->value().impl(), m_classRules, ruleData);
return;
}
- if (selector->isUnknownPseudoElement()) {
+ if (selector->isCustomPseudoElement()) {
addToRuleSet(selector->value().impl(), m_shadowPseudoElementRules, ruleData);
return;
}
@@ -264,10 +271,12 @@ void RuleSet::addRegionRule(StyleRuleRegion* regionRule, bool hasDocumentSecurit
// Collect the region rules into a rule set
const Vector<RefPtr<StyleRuleBase> >& childRules = regionRule->childRules();
+ AddRuleFlags addRuleFlags = hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState;
+ addRuleFlags = static_cast<AddRuleFlags>(addRuleFlags | RuleCanUseFastCheckSelector | RuleIsInRegionRule);
for (unsigned i = 0; i < childRules.size(); ++i) {
StyleRuleBase* regionStylingRule = childRules[i].get();
if (regionStylingRule->isStyleRule())
- regionRuleSet->addStyleRule(static_cast<StyleRule*>(regionStylingRule), hasDocumentSecurityOrigin, true, true);
+ regionRuleSet->addStyleRule(static_cast<StyleRule*>(regionStylingRule), addRuleFlags);
}
// Update the "global" rule count so that proper order is maintained
m_ruleCount = regionRuleSet->m_ruleCount;
@@ -286,6 +295,7 @@ void RuleSet::addRulesFromSheet(StyleSheetContents* sheet, const MediaQueryEvalu
addRulesFromSheet(importRule->styleSheet(), medium, resolver, scope);
}
bool hasDocumentSecurityOrigin = resolver && resolver->document()->securityOrigin()->canRequest(sheet->baseURL());
+ AddRuleFlags addRuleFlags = static_cast<AddRuleFlags>((hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : 0) | (!scope ? RuleCanUseFastCheckSelector : 0));
const Vector<RefPtr<StyleRuleBase> >& rules = sheet->childRules();
for (unsigned i = 0; i < rules.size(); ++i) {
@@ -293,7 +303,7 @@ void RuleSet::addRulesFromSheet(StyleSheetContents* sheet, const MediaQueryEvalu
ASSERT(!rule->isImportRule());
if (rule->isStyleRule())
- addStyleRule(static_cast<StyleRule*>(rule), hasDocumentSecurityOrigin, !scope);
+ addStyleRule(static_cast<StyleRule*>(rule), addRuleFlags);
else if (rule->isPageRule())
addPageRule(static_cast<StyleRulePage*>(rule));
else if (rule->isMediaRule()) {
@@ -305,7 +315,7 @@ void RuleSet::addRulesFromSheet(StyleSheetContents* sheet, const MediaQueryEvalu
for (unsigned j = 0; j < childRules.size(); ++j) {
StyleRuleBase* childRule = childRules[j].get();
if (childRule->isStyleRule())
- addStyleRule(static_cast<StyleRule*>(childRule), hasDocumentSecurityOrigin, !scope);
+ addStyleRule(static_cast<StyleRule*>(childRule), addRuleFlags);
else if (childRule->isPageRule())
addPageRule(static_cast<StyleRulePage*>(childRule));
else if (childRule->isFontFaceRule() && resolver) {
@@ -347,15 +357,19 @@ void RuleSet::addRulesFromSheet(StyleSheetContents* sheet, const MediaQueryEvalu
addRegionRule(static_cast<StyleRuleRegion*>(rule), hasDocumentSecurityOrigin);
}
#endif
+#if ENABLE(SHADOW_DOM)
+ else if (rule->isHostRule())
+ resolver->addHostRule(static_cast<StyleRuleHost*>(rule), hasDocumentSecurityOrigin, scope);
+#endif
}
if (m_autoShrinkToFitEnabled)
shrinkToFit();
}
-void RuleSet::addStyleRule(StyleRule* rule, bool hasDocumentSecurityOrigin, bool canUseFastCheckSelector, bool isInRegionRule)
+void RuleSet::addStyleRule(StyleRule* rule, AddRuleFlags addRuleFlags)
{
for (size_t selectorIndex = 0; selectorIndex != notFound; selectorIndex = rule->selectorList().indexOfNextSelectorAfter(selectorIndex))
- addRule(rule, selectorIndex, hasDocumentSecurityOrigin, canUseFastCheckSelector, isInRegionRule);
+ addRule(rule, selectorIndex, addRuleFlags);
}
static inline void shrinkMapVectorsToFit(RuleSet::AtomRuleMap& map)
diff --git a/Source/WebCore/css/RuleSet.h b/Source/WebCore/css/RuleSet.h
index 6577238ba..a2fbecbc0 100644
--- a/Source/WebCore/css/RuleSet.h
+++ b/Source/WebCore/css/RuleSet.h
@@ -31,6 +31,14 @@
namespace WebCore {
+enum AddRuleFlags {
+ RuleHasNoSpecialState = 0,
+ RuleHasDocumentSecurityOrigin = 1,
+ RuleCanUseFastCheckSelector = 1 << 1,
+ RuleIsInRegionRule = 1 << 2,
+ RuleIsHostRule = 1 << 3,
+};
+
class CSSSelector;
class ContainerNode;
class MediaQueryEvaluator;
@@ -40,7 +48,7 @@ class StyleSheetContents;
class RuleData {
public:
- RuleData(StyleRule*, unsigned selectorIndex, unsigned position, bool hasDocumentSecurityOrigin, bool canUseFastCheckSelector, bool inRegionRule);
+ RuleData(StyleRule*, unsigned selectorIndex, unsigned position, AddRuleFlags);
unsigned position() const { return m_position; }
StyleRule* rule() const { return m_rule; }
@@ -55,6 +63,7 @@ public:
unsigned linkMatchType() const { return m_linkMatchType; }
bool hasDocumentSecurityOrigin() const { return m_hasDocumentSecurityOrigin; }
bool isInRegionRule() const { return m_isInRegionRule; }
+ void increaseSpecificity(unsigned value) { m_specificity += value; }
// Try to balance between memory usage (there can be lots of RuleData objects) and good filtering performance.
static const unsigned maximumIdentifierCount = 4;
@@ -98,8 +107,8 @@ public:
void addRulesFromSheet(StyleSheetContents*, const MediaQueryEvaluator&, StyleResolver* = 0, const ContainerNode* = 0);
- void addStyleRule(StyleRule*, bool hasDocumentSecurityOrigin, bool canUseFastCheckSelector, bool isInRegionRule = false);
- void addRule(StyleRule*, unsigned selectorIndex, bool hasDocumentSecurityOrigin, bool canUseFastCheckSelector, bool isInRegionRule = false);
+ void addStyleRule(StyleRule*, AddRuleFlags);
+ void addRule(StyleRule*, unsigned selectorIndex, AddRuleFlags);
void addPageRule(StyleRulePage*);
void addToRuleSet(AtomicStringImpl* key, AtomRuleMap&, const RuleData&);
void addRegionRule(StyleRuleRegion*, bool hasDocumentSecurityOrigin);
diff --git a/Source/WebCore/css/SVGCSSParser.cpp b/Source/WebCore/css/SVGCSSParser.cpp
index 26d44e462..7200f218d 100644
--- a/Source/WebCore/css/SVGCSSParser.cpp
+++ b/Source/WebCore/css/SVGCSSParser.cpp
@@ -26,7 +26,6 @@
#include "CSSInheritedValue.h"
#include "CSSInitialValue.h"
#include "CSSParser.h"
-#include "CSSProperty.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "CSSValueList.h"
diff --git a/Source/WebCore/css/SVGCSSStyleSelector.cpp b/Source/WebCore/css/SVGCSSStyleSelector.cpp
index eaedc1065..6145bb1f1 100644
--- a/Source/WebCore/css/SVGCSSStyleSelector.cpp
+++ b/Source/WebCore/css/SVGCSSStyleSelector.cpp
@@ -185,6 +185,11 @@ void StyleResolver::applySVGProperty(CSSPropertyID id, CSSValue* value)
svgstyle->setColorInterpolationFilters(*primitiveValue);
break;
}
+ case CSSPropertyColorProfile:
+ {
+ // Not implemented.
+ break;
+ }
case CSSPropertyColorRendering:
{
HANDLE_INHERIT_AND_INITIAL(colorRendering, ColorRendering)
diff --git a/Source/WebCore/css/SelectorChecker.cpp b/Source/WebCore/css/SelectorChecker.cpp
index eb5b9f387..38d41f784 100644
--- a/Source/WebCore/css/SelectorChecker.cpp
+++ b/Source/WebCore/css/SelectorChecker.cpp
@@ -51,6 +51,7 @@
#include "RenderStyle.h"
#include "ScrollableArea.h"
#include "ScrollbarTheme.h"
+#include "ShadowRoot.h"
#include "SiblingTraversalStrategies.h"
#include "StyledElement.h"
#include "Text.h"
@@ -268,8 +269,7 @@ bool SelectorChecker::checkSelector(CSSSelector* sel, Element* element, bool isF
}
PseudoId ignoreDynamicPseudo = NOPSEUDO;
- bool hasUnknownPseudoElements = false;
- return checkSelector(SelectorCheckingContext(sel, element, SelectorChecker::VisitedMatchDisabled), ignoreDynamicPseudo, hasUnknownPseudoElements) == SelectorMatches;
+ return checkSelector(SelectorCheckingContext(sel, element, SelectorChecker::VisitedMatchDisabled), ignoreDynamicPseudo) == SelectorMatches;
}
namespace {
@@ -440,16 +440,21 @@ bool SelectorChecker::isFastCheckableSelector(const CSSSelector* selector)
// * SelectorFailsLocally - the selector fails for the element e
// * SelectorFailsAllSiblings - the selector fails for e and any sibling of e
// * SelectorFailsCompletely - the selector fails for e and any sibling or ancestor of e
-SelectorChecker::SelectorMatch SelectorChecker::checkSelector(const SelectorCheckingContext& context, PseudoId& dynamicPseudo, bool& hasUnknownPseudoElements) const
+SelectorChecker::SelectorMatch SelectorChecker::checkSelector(const SelectorCheckingContext& context, PseudoId& dynamicPseudo) const
{
// first selector has to match
if (!checkOneSelector(context, DOMSiblingTraversalStrategy()))
return SelectorFailsLocally;
if (context.selector->m_match == CSSSelector::PseudoElement) {
- if (context.selector->isUnknownPseudoElement()) {
- hasUnknownPseudoElements = true;
- if (context.element->shadowPseudoId() != context.selector->value())
+ if (context.selector->isCustomPseudoElement()) {
+ if (ShadowRoot* root = context.element->shadowRoot()) {
+ if (context.element->shadowPseudoId() != context.selector->value())
+ return SelectorFailsLocally;
+
+ if (context.selector->pseudoType() == CSSSelector::PseudoWebKitCustomElement && root->type() != ShadowRoot::UserAgentShadowRoot)
+ return SelectorFailsLocally;
+ } else
return SelectorFailsLocally;
} else {
if ((!context.elementStyle && m_mode == ResolvingStyle) || m_mode == QueryingRules)
@@ -500,7 +505,7 @@ SelectorChecker::SelectorMatch SelectorChecker::checkSelector(const SelectorChec
nextContext.elementStyle = 0;
nextContext.elementParentStyle = 0;
for (; nextContext.element; nextContext.element = nextContext.element->parentElement()) {
- SelectorMatch match = checkSelector(nextContext, ignoreDynamicPseudo, hasUnknownPseudoElements);
+ SelectorMatch match = checkSelector(nextContext, ignoreDynamicPseudo);
if (match == SelectorMatches || match == SelectorFailsCompletely)
return match;
if (nextContext.element == nextContext.scope)
@@ -515,7 +520,7 @@ SelectorChecker::SelectorMatch SelectorChecker::checkSelector(const SelectorChec
nextContext.isSubSelector = false;
nextContext.elementStyle = 0;
nextContext.elementParentStyle = 0;
- return checkSelector(nextContext, ignoreDynamicPseudo, hasUnknownPseudoElements);
+ return checkSelector(nextContext, ignoreDynamicPseudo);
case CSSSelector::DirectAdjacent:
if (m_mode == ResolvingStyle && context.element->parentElement()) {
@@ -529,7 +534,7 @@ SelectorChecker::SelectorMatch SelectorChecker::checkSelector(const SelectorChec
nextContext.isSubSelector = false;
nextContext.elementStyle = 0;
nextContext.elementParentStyle = 0;
- return checkSelector(nextContext, ignoreDynamicPseudo, hasUnknownPseudoElements);
+ return checkSelector(nextContext, ignoreDynamicPseudo);
case CSSSelector::IndirectAdjacent:
if (m_mode == ResolvingStyle && context.element->parentElement()) {
@@ -542,7 +547,7 @@ SelectorChecker::SelectorMatch SelectorChecker::checkSelector(const SelectorChec
nextContext.elementStyle = 0;
nextContext.elementParentStyle = 0;
for (; nextContext.element; nextContext.element = nextContext.element->previousElementSibling()) {
- SelectorMatch match = checkSelector(nextContext, ignoreDynamicPseudo, hasUnknownPseudoElements);
+ SelectorMatch match = checkSelector(nextContext, ignoreDynamicPseudo);
if (match == SelectorMatches || match == SelectorFailsAllSiblings || match == SelectorFailsCompletely)
return match;
};
@@ -559,7 +564,7 @@ SelectorChecker::SelectorMatch SelectorChecker::checkSelector(const SelectorChec
&& !(nextContext.hasScrollbarPseudo && nextContext.selector->m_match == CSSSelector::PseudoClass))
return SelectorFailsCompletely;
nextContext.isSubSelector = true;
- return checkSelector(nextContext, dynamicPseudo, hasUnknownPseudoElements);
+ return checkSelector(nextContext, dynamicPseudo);
case CSSSelector::ShadowDescendant:
{
@@ -573,7 +578,7 @@ SelectorChecker::SelectorMatch SelectorChecker::checkSelector(const SelectorChec
nextContext.isSubSelector = false;
nextContext.elementStyle = 0;
nextContext.elementParentStyle = 0;
- return checkSelector(nextContext, ignoreDynamicPseudo, hasUnknownPseudoElements);
+ return checkSelector(nextContext, ignoreDynamicPseudo);
}
}
@@ -979,10 +984,9 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, c
{
SelectorCheckingContext subContext(context);
subContext.isSubSelector = true;
- bool hasUnknownPseudoElements = false;
PseudoId ignoreDynamicPseudo = NOPSEUDO;
for (subContext.selector = selector->selectorList()->first(); subContext.selector; subContext.selector = CSSSelectorList::next(subContext.selector)) {
- if (checkSelector(subContext, ignoreDynamicPseudo, hasUnknownPseudoElements) == SelectorMatches)
+ if (checkSelector(subContext, ignoreDynamicPseudo) == SelectorMatches)
return true;
}
}
diff --git a/Source/WebCore/css/SelectorChecker.h b/Source/WebCore/css/SelectorChecker.h
index 9eadada59..9bdb669b2 100644
--- a/Source/WebCore/css/SelectorChecker.h
+++ b/Source/WebCore/css/SelectorChecker.h
@@ -82,7 +82,7 @@ public:
};
bool checkSelector(CSSSelector*, Element*, bool isFastCheckableSelector = false) const;
- SelectorMatch checkSelector(const SelectorCheckingContext&, PseudoId&, bool& hasUnknownPseudoElements) const;
+ SelectorMatch checkSelector(const SelectorCheckingContext&, PseudoId&) const;
template<typename SiblingTraversalStrategy>
bool checkOneSelector(const SelectorCheckingContext&, const SiblingTraversalStrategy&) const;
diff --git a/Source/WebCore/css/StyleBuilder.cpp b/Source/WebCore/css/StyleBuilder.cpp
index 5795defc4..0501dc9d1 100644
--- a/Source/WebCore/css/StyleBuilder.cpp
+++ b/Source/WebCore/css/StyleBuilder.cpp
@@ -2002,7 +2002,7 @@ StyleBuilder::StyleBuilder()
setPropertyHandler(CSSPropertyWebkitHyphenateLimitLines, ApplyPropertyNumber<short, &RenderStyle::hyphenationLimitLines, &RenderStyle::setHyphenationLimitLines, &RenderStyle::initialHyphenationLimitLines, CSSValueNoLimit>::createHandler());
setPropertyHandler(CSSPropertyWebkitHyphens, ApplyPropertyDefault<Hyphens, &RenderStyle::hyphens, Hyphens, &RenderStyle::setHyphens, Hyphens, &RenderStyle::initialHyphens>::createHandler());
setPropertyHandler(CSSPropertyWebkitLineAlign, ApplyPropertyDefault<LineAlign, &RenderStyle::lineAlign, LineAlign, &RenderStyle::setLineAlign, LineAlign, &RenderStyle::initialLineAlign>::createHandler());
- setPropertyHandler(CSSPropertyWebkitLineBreak, ApplyPropertyDefault<EKHTMLLineBreak, &RenderStyle::khtmlLineBreak, EKHTMLLineBreak, &RenderStyle::setKHTMLLineBreak, EKHTMLLineBreak, &RenderStyle::initialKHTMLLineBreak>::createHandler());
+ setPropertyHandler(CSSPropertyWebkitLineBreak, ApplyPropertyDefault<LineBreak, &RenderStyle::lineBreak, LineBreak, &RenderStyle::setLineBreak, LineBreak, &RenderStyle::initialLineBreak>::createHandler());
setPropertyHandler(CSSPropertyWebkitLineClamp, ApplyPropertyDefault<const LineClampValue&, &RenderStyle::lineClamp, LineClampValue, &RenderStyle::setLineClamp, LineClampValue, &RenderStyle::initialLineClamp>::createHandler());
setPropertyHandler(CSSPropertyWebkitLineGrid, ApplyPropertyString<MapNoneToNull, &RenderStyle::lineGrid, &RenderStyle::setLineGrid, &RenderStyle::initialLineGrid>::createHandler());
setPropertyHandler(CSSPropertyWebkitLineSnap, ApplyPropertyDefault<LineSnap, &RenderStyle::lineSnap, LineSnap, &RenderStyle::setLineSnap, LineSnap, &RenderStyle::initialLineSnap>::createHandler());
diff --git a/Source/WebCore/css/StylePropertySet.cpp b/Source/WebCore/css/StylePropertySet.cpp
index 5e522af92..110b802c9 100644
--- a/Source/WebCore/css/StylePropertySet.cpp
+++ b/Source/WebCore/css/StylePropertySet.cpp
@@ -34,6 +34,10 @@
#include <wtf/MemoryInstrumentationVector.h>
#include <wtf/text/StringBuilder.h>
+#if ENABLE(CSS_VARIABLES)
+#include "CSSVariableValue.h"
+#endif
+
#ifndef NDEBUG
#include <stdio.h>
#include <wtf/ASCIICType.h>
@@ -51,14 +55,14 @@ static PropertySetCSSOMWrapperMap& propertySetCSSOMWrapperMap()
return propertySetCSSOMWrapperMapInstance;
}
-static size_t immutableStylePropertySetSize(unsigned count)
+static size_t sizeForImmutableStylePropertySetWithPropertyCount(unsigned count)
{
- return sizeof(ImmutableStylePropertySet) + sizeof(CSSProperty) * count;
+ return sizeof(ImmutableStylePropertySet) - sizeof(void*) + sizeof(CSSValue*) * count + sizeof(StylePropertyMetadata) * count;
}
PassRefPtr<StylePropertySet> StylePropertySet::createImmutable(const CSSProperty* properties, unsigned count, CSSParserMode cssParserMode)
{
- void* slot = WTF::fastMalloc(immutableStylePropertySetSize(count));
+ void* slot = WTF::fastMalloc(sizeForImmutableStylePropertySetWithPropertyCount(count));
return adoptRef(new (slot) ImmutableStylePropertySet(properties, count, cssParserMode));
}
@@ -80,8 +84,20 @@ MutableStylePropertySet::MutableStylePropertySet(const CSSProperty* properties,
ImmutableStylePropertySet::ImmutableStylePropertySet(const CSSProperty* properties, unsigned length, CSSParserMode cssParserMode)
: StylePropertySet(cssParserMode, length)
{
- for (unsigned i = 0; i < length; ++i)
- new (&reinterpret_cast<CSSProperty*>(&m_propertyArray)[i]) CSSProperty(properties[i]);
+ StylePropertyMetadata* metadataArray = const_cast<StylePropertyMetadata*>(immutableMetadataArray());
+ CSSValue** valueArray = const_cast<CSSValue**>(immutableValueArray());
+ for (unsigned i = 0; i < length; ++i) {
+ metadataArray[i] = properties[i].metadata();
+ valueArray[i] = properties[i].value();
+ valueArray[i]->ref();
+ }
+}
+
+ImmutableStylePropertySet::~ImmutableStylePropertySet()
+{
+ CSSValue** valueArray = const_cast<CSSValue**>(immutableValueArray());
+ for (unsigned i = 0; i < m_arraySize; ++i)
+ valueArray[i]->deref();
}
MutableStylePropertySet::MutableStylePropertySet(const StylePropertySet& other)
@@ -92,16 +108,10 @@ MutableStylePropertySet::MutableStylePropertySet(const StylePropertySet& other)
else {
m_propertyVector.reserveInitialCapacity(other.propertyCount());
for (unsigned i = 0; i < other.propertyCount(); ++i)
- m_propertyVector.uncheckedAppend(other.immutablePropertyArray()[i]);
+ m_propertyVector.uncheckedAppend(other.propertyAt(i).toCSSProperty());
}
}
-ImmutableStylePropertySet::~ImmutableStylePropertySet()
-{
- for (unsigned i = 0; i < m_arraySize; ++i)
- immutablePropertyArray()[i].~CSSProperty();
-}
-
StylePropertySet::~StylePropertySet()
{
ASSERT(!m_ownsCSSOMWrapper || propertySetCSSOMWrapperMap().contains(this));
@@ -206,16 +216,17 @@ String StylePropertySet::borderSpacingValue(const StylePropertyShorthand& shorth
return horizontalValueCSSText + ' ' + verticalValueCSSText;
}
-bool StylePropertySet::appendFontLonghandValueIfExplicit(CSSPropertyID propertyId, StringBuilder& result) const
+bool StylePropertySet::appendFontLonghandValueIfExplicit(CSSPropertyID propertyID, StringBuilder& result) const
{
- const CSSProperty* property = findPropertyWithId(propertyId);
- if (!property)
+ int foundPropertyIndex = findPropertyIndex(propertyID);
+ if (foundPropertyIndex == -1)
return false; // All longhands must have at least implicit values if "font" is specified.
- if (property->isImplicit())
+
+ if (propertyAt(foundPropertyIndex).isImplicit())
return true;
char prefix = '\0';
- switch (propertyId) {
+ switch (propertyID) {
case CSSPropertyFontStyle:
break; // No prefix.
case CSSPropertyFontFamily:
@@ -232,15 +243,19 @@ bool StylePropertySet::appendFontLonghandValueIfExplicit(CSSPropertyID propertyI
if (prefix && !result.isEmpty())
result.append(prefix);
- result.append(property->value()->cssText());
+ result.append(propertyAt(foundPropertyIndex).value()->cssText());
return true;
}
String StylePropertySet::fontValue() const
{
- const CSSProperty* fontSizeProperty = findPropertyWithId(CSSPropertyFontSize);
- if (!fontSizeProperty || fontSizeProperty->isImplicit())
+ int foundPropertyIndex = findPropertyIndex(CSSPropertyFontSize);
+ if (foundPropertyIndex == -1)
+ return emptyString();
+
+ PropertyReference fontSizeProperty = propertyAt(foundPropertyIndex);
+ if (fontSizeProperty.isImplicit())
return emptyString();
StringBuilder result;
@@ -250,7 +265,7 @@ String StylePropertySet::fontValue() const
success &= appendFontLonghandValueIfExplicit(CSSPropertyFontWeight, result);
if (!result.isEmpty())
result.append(' ');
- result.append(fontSizeProperty->value()->cssText());
+ result.append(fontSizeProperty.value()->cssText());
success &= appendFontLonghandValueIfExplicit(CSSPropertyLineHeight, result);
success &= appendFontLonghandValueIfExplicit(CSSPropertyFontFamily, result);
if (!success) {
@@ -265,36 +280,44 @@ String StylePropertySet::fontValue() const
String StylePropertySet::get4Values(const StylePropertyShorthand& shorthand) const
{
// Assume the properties are in the usual order top, right, bottom, left.
- const CSSProperty* top = findPropertyWithId(shorthand.properties()[0]);
- const CSSProperty* right = findPropertyWithId(shorthand.properties()[1]);
- const CSSProperty* bottom = findPropertyWithId(shorthand.properties()[2]);
- const CSSProperty* left = findPropertyWithId(shorthand.properties()[3]);
+ int topValueIndex = findPropertyIndex(shorthand.properties()[0]);
+ int rightValueIndex = findPropertyIndex(shorthand.properties()[1]);
+ int bottomValueIndex = findPropertyIndex(shorthand.properties()[2]);
+ int leftValueIndex = findPropertyIndex(shorthand.properties()[3]);
+
+ if (topValueIndex == -1 || rightValueIndex == -1 || bottomValueIndex == -1 || leftValueIndex == -1)
+ return String();
+
+ PropertyReference top = propertyAt(topValueIndex);
+ PropertyReference right = propertyAt(rightValueIndex);
+ PropertyReference bottom = propertyAt(bottomValueIndex);
+ PropertyReference left = propertyAt(leftValueIndex);
// All 4 properties must be specified.
- if (!top || !top->value() || !right || !right->value() || !bottom || !bottom->value() || !left || !left->value())
+ if (!top.value() || !right.value() || !bottom.value() || !left.value())
return String();
- if (top->value()->isInitialValue() || right->value()->isInitialValue() || bottom->value()->isInitialValue() || left->value()->isInitialValue())
+ if (top.value()->isInitialValue() || right.value()->isInitialValue() || bottom.value()->isInitialValue() || left.value()->isInitialValue())
return String();
- if (top->isImportant() != right->isImportant() || right->isImportant() != bottom->isImportant() || bottom->isImportant() != left->isImportant())
+ if (top.isImportant() != right.isImportant() || right.isImportant() != bottom.isImportant() || bottom.isImportant() != left.isImportant())
return String();
- bool showLeft = right->value()->cssText() != left->value()->cssText();
- bool showBottom = (top->value()->cssText() != bottom->value()->cssText()) || showLeft;
- bool showRight = (top->value()->cssText() != right->value()->cssText()) || showBottom;
+ bool showLeft = right.value()->cssText() != left.value()->cssText();
+ bool showBottom = (top.value()->cssText() != bottom.value()->cssText()) || showLeft;
+ bool showRight = (top.value()->cssText() != right.value()->cssText()) || showBottom;
StringBuilder result;
- result.append(top->value()->cssText());
+ result.append(top.value()->cssText());
if (showRight) {
result.append(' ');
- result.append(right->value()->cssText());
+ result.append(right.value()->cssText());
}
if (showBottom) {
result.append(' ');
- result.append(bottom->value()->cssText());
+ result.append(bottom.value()->cssText());
}
if (showLeft) {
result.append(' ');
- result.append(left->value()->cssText());
+ result.append(left.value()->cssText());
}
return result.toString();
}
@@ -480,8 +503,10 @@ String StylePropertySet::borderPropertyValue(CommonValueMode valueMode) const
PassRefPtr<CSSValue> StylePropertySet::getPropertyCSSValue(CSSPropertyID propertyID) const
{
- const CSSProperty* property = findPropertyWithId(propertyID);
- return property ? property->value() : 0;
+ int foundPropertyIndex = findPropertyIndex(propertyID);
+ if (foundPropertyIndex == -1)
+ return 0;
+ return propertyAt(foundPropertyIndex).value();
}
bool StylePropertySet::removeShorthandProperty(CSSPropertyID propertyID)
@@ -503,28 +528,28 @@ bool StylePropertySet::removeProperty(CSSPropertyID propertyID, String* returnTe
return true;
}
- CSSProperty* foundProperty = findPropertyWithId(propertyID);
- if (!foundProperty) {
+ int foundPropertyIndex = findPropertyIndex(propertyID);
+ if (foundPropertyIndex == -1) {
if (returnText)
*returnText = "";
return false;
}
if (returnText)
- *returnText = foundProperty->value()->cssText();
+ *returnText = propertyAt(foundPropertyIndex).value()->cssText();
// A more efficient removal strategy would involve marking entries as empty
// and sweeping them when the vector grows too big.
- mutablePropertyVector().remove(foundProperty - mutablePropertyVector().data());
+ mutablePropertyVector().remove(foundPropertyIndex);
return true;
}
bool StylePropertySet::propertyIsImportant(CSSPropertyID propertyID) const
{
- const CSSProperty* property = findPropertyWithId(propertyID);
- if (property)
- return property->isImportant();
+ int foundPropertyIndex = findPropertyIndex(propertyID);
+ if (foundPropertyIndex != -1)
+ return propertyAt(foundPropertyIndex).isImportant();
StylePropertyShorthand shorthand = shorthandForProperty(propertyID);
if (!shorthand.length())
@@ -539,14 +564,18 @@ bool StylePropertySet::propertyIsImportant(CSSPropertyID propertyID) const
CSSPropertyID StylePropertySet::getPropertyShorthand(CSSPropertyID propertyID) const
{
- const CSSProperty* property = findPropertyWithId(propertyID);
- return property ? property->shorthandID() : CSSPropertyInvalid;
+ int foundPropertyIndex = findPropertyIndex(propertyID);
+ if (foundPropertyIndex == -1)
+ return CSSPropertyInvalid;
+ return propertyAt(foundPropertyIndex).shorthandID();
}
bool StylePropertySet::isPropertyImplicit(CSSPropertyID propertyID) const
{
- const CSSProperty* property = findPropertyWithId(propertyID);
- return property ? property->isImplicit() : false;
+ int foundPropertyIndex = findPropertyIndex(propertyID);
+ if (foundPropertyIndex == -1)
+ return false;
+ return propertyAt(foundPropertyIndex).isImplicit();
}
bool StylePropertySet::setProperty(CSSPropertyID propertyID, const String& value, bool important, StyleSheetContents* contextStyleSheet)
@@ -577,20 +606,20 @@ void StylePropertySet::setProperty(CSSPropertyID propertyID, PassRefPtr<CSSValue
RefPtr<CSSValue> value = prpValue;
for (unsigned i = 0; i < shorthand.length(); ++i)
- append(CSSProperty(shorthand.properties()[i], value, important));
+ mutablePropertyVector().append(CSSProperty(shorthand.properties()[i], value, important));
}
void StylePropertySet::setProperty(const CSSProperty& property, CSSProperty* slot)
{
ASSERT(isMutable());
if (!removeShorthandProperty(property.id())) {
- CSSProperty* toReplace = slot ? slot : findPropertyWithId(property.id());
+ CSSProperty* toReplace = slot ? slot : findMutableCSSPropertyWithID(property.id());
if (toReplace) {
*toReplace = property;
return;
}
}
- append(property);
+ mutablePropertyVector().append(property);
}
bool StylePropertySet::setProperty(CSSPropertyID propertyID, int identifier, bool important)
@@ -635,10 +664,10 @@ String StylePropertySet::asText() const
{
StringBuilder result;
- const CSSProperty* positionXProp = 0;
- const CSSProperty* positionYProp = 0;
- const CSSProperty* repeatXProp = 0;
- const CSSProperty* repeatYProp = 0;
+ int positionXPropertyIndex = -1;
+ int positionYPropertyIndex = -1;
+ int repeatXPropertyIndex = -1;
+ int repeatYPropertyIndex = -1;
BitArray<numCSSProperties> shorthandPropertyUsed;
BitArray<numCSSProperties> shorthandPropertyAppeared;
@@ -646,8 +675,8 @@ String StylePropertySet::asText() const
unsigned size = propertyCount();
unsigned numDecls = 0;
for (unsigned n = 0; n < size; ++n) {
- const CSSProperty& prop = propertyAt(n);
- CSSPropertyID propertyID = prop.id();
+ PropertyReference property = propertyAt(n);
+ CSSPropertyID propertyID = property.id();
CSSPropertyID shorthandPropertyID = CSSPropertyInvalid;
CSSPropertyID borderFallbackShorthandProperty = CSSPropertyInvalid;
String value;
@@ -657,20 +686,20 @@ String StylePropertySet::asText() const
case CSSPropertyVariable:
if (numDecls++)
result.append(' ');
- result.append(prop.cssText());
+ result.append(property.cssText());
continue;
#endif
case CSSPropertyBackgroundPositionX:
- positionXProp = &prop;
+ positionXPropertyIndex = n;
continue;
case CSSPropertyBackgroundPositionY:
- positionYProp = &prop;
+ positionYPropertyIndex = n;
continue;
case CSSPropertyBackgroundRepeatX:
- repeatXProp = &prop;
+ repeatXPropertyIndex = n;
continue;
case CSSPropertyBackgroundRepeatY:
- repeatYProp = &prop;
+ repeatYPropertyIndex = n;
continue;
case CSSPropertyBorderTopWidth:
case CSSPropertyBorderRightWidth:
@@ -806,7 +835,7 @@ String StylePropertySet::asText() const
propertyID = shorthandPropertyID;
shorthandPropertyUsed.set(shortPropertyIndex);
} else
- value = prop.value()->cssText();
+ value = property.value()->cssText();
if (value == "initial" && !CSSProperty::isInheritedProperty(propertyID))
continue;
@@ -816,7 +845,7 @@ String StylePropertySet::asText() const
result.append(getPropertyName(propertyID));
result.appendLiteral(": ");
result.append(value);
- if (prop.isImportant())
+ if (property.isImportant())
result.appendLiteral(" !important");
result.append(';');
}
@@ -825,58 +854,64 @@ String StylePropertySet::asText() const
// It is required because background-position-x/y are non-standard properties and WebKit generated output
// would not work in Firefox (<rdar://problem/5143183>)
// It would be a better solution if background-position was CSS_PAIR.
- if (positionXProp && positionYProp && positionXProp->isImportant() == positionYProp->isImportant()) {
+ if (positionXPropertyIndex != -1 && positionYPropertyIndex != -1 && propertyAt(positionXPropertyIndex).isImportant() == propertyAt(positionYPropertyIndex).isImportant()) {
+ PropertyReference positionXProperty = propertyAt(positionXPropertyIndex);
+ PropertyReference positionYProperty = propertyAt(positionYPropertyIndex);
+
if (numDecls++)
result.append(' ');
result.appendLiteral("background-position: ");
- if (positionXProp->value()->isValueList() || positionYProp->value()->isValueList())
+ if (positionXProperty.value()->isValueList() || positionYProperty.value()->isValueList())
result.append(getLayeredShorthandValue(backgroundPositionShorthand()));
else {
- result.append(positionXProp->value()->cssText());
+ result.append(positionXProperty.value()->cssText());
result.append(' ');
- result.append(positionYProp->value()->cssText());
+ result.append(positionYProperty.value()->cssText());
}
- if (positionXProp->isImportant())
+ if (positionXProperty.isImportant())
result.appendLiteral(" !important");
result.append(';');
} else {
- if (positionXProp) {
+ if (positionXPropertyIndex != -1) {
if (numDecls++)
result.append(' ');
- result.append(positionXProp->cssText());
+ result.append(propertyAt(positionXPropertyIndex).cssText());
}
- if (positionYProp) {
+ if (positionYPropertyIndex != -1) {
if (numDecls++)
result.append(' ');
- result.append(positionYProp->cssText());
+ result.append(propertyAt(positionYPropertyIndex).cssText());
}
}
// FIXME: We need to do the same for background-repeat.
- if (repeatXProp && repeatYProp && repeatXProp->isImportant() == repeatYProp->isImportant()) {
+ if (repeatXPropertyIndex != -1 && repeatYPropertyIndex != -1 && propertyAt(repeatXPropertyIndex).isImportant() == propertyAt(repeatYPropertyIndex).isImportant()) {
+ PropertyReference repeatXProperty = propertyAt(repeatXPropertyIndex);
+ PropertyReference repeatYProperty = propertyAt(repeatYPropertyIndex);
+
if (numDecls++)
result.append(' ');
result.appendLiteral("background-repeat: ");
- if (repeatXProp->value()->isValueList() || repeatYProp->value()->isValueList())
+ if (repeatXProperty.value()->isValueList() || repeatYProperty.value()->isValueList())
result.append(getLayeredShorthandValue(backgroundRepeatShorthand()));
else {
- result.append(repeatXProp->value()->cssText());
+ result.append(repeatXProperty.value()->cssText());
result.append(' ');
- result.append(repeatYProp->value()->cssText());
+ result.append(repeatYProperty.value()->cssText());
}
- if (repeatXProp->isImportant())
+ if (repeatXProperty.isImportant())
result.appendLiteral(" !important");
result.append(';');
} else {
- if (repeatXProp) {
+ if (repeatXPropertyIndex != -1) {
if (numDecls++)
result.append(' ');
- result.append(repeatXProp->cssText());
+ result.append(propertyAt(repeatXPropertyIndex).cssText());
}
- if (repeatYProp) {
+ if (repeatYPropertyIndex != -1) {
if (numDecls++)
result.append(' ');
- result.append(repeatYProp->cssText());
+ result.append(propertyAt(repeatYPropertyIndex).cssText());
}
}
@@ -889,12 +924,12 @@ void StylePropertySet::mergeAndOverrideOnConflict(const StylePropertySet* other)
ASSERT(isMutable());
unsigned size = other->propertyCount();
for (unsigned n = 0; n < size; ++n) {
- const CSSProperty& toMerge = other->propertyAt(n);
- CSSProperty* old = findPropertyWithId(toMerge.id());
+ PropertyReference toMerge = other->propertyAt(n);
+ CSSProperty* old = findMutableCSSPropertyWithID(toMerge.id());
if (old)
- setProperty(toMerge, old);
+ setProperty(toMerge.toCSSProperty(), old);
else
- append(toMerge);
+ mutablePropertyVector().append(toMerge.toCSSProperty());
}
}
@@ -943,6 +978,12 @@ static const CSSPropertyID blockProperties[] = {
CSSPropertyWidows
};
+void StylePropertySet::clear()
+{
+ ASSERT(isMutable());
+ mutablePropertyVector().clear();
+}
+
const unsigned numBlockProperties = WTF_ARRAY_LENGTH(blockProperties);
PassRefPtr<StylePropertySet> StylePropertySet::copyBlockProperties() const
@@ -985,29 +1026,30 @@ bool StylePropertySet::removePropertiesInSet(const CSSPropertyID* set, unsigned
return changed;
}
-const CSSProperty* StylePropertySet::findPropertyWithId(CSSPropertyID propertyID) const
+int StylePropertySet::findPropertyIndex(CSSPropertyID propertyID) const
{
for (int n = propertyCount() - 1 ; n >= 0; --n) {
if (propertyID == propertyAt(n).id())
- return &propertyAt(n);
+ return n;
}
- return 0;
+ return -1;
}
-CSSProperty* StylePropertySet::findPropertyWithId(CSSPropertyID propertyID)
+CSSProperty* StylePropertySet::findMutableCSSPropertyWithID(CSSPropertyID propertyID)
{
ASSERT(isMutable());
- for (int n = propertyCount() - 1 ; n >= 0; --n) {
- if (propertyID == propertyAt(n).id())
- return &propertyAt(n);
- }
- return 0;
+ int foundPropertyIndex = findPropertyIndex(propertyID);
+ if (foundPropertyIndex == -1)
+ return 0;
+ return &mutablePropertyVector().at(foundPropertyIndex);
}
-bool StylePropertySet::propertyMatches(const CSSProperty* property) const
+bool StylePropertySet::propertyMatches(const PropertyReference& property) const
{
- RefPtr<CSSValue> value = getPropertyCSSValue(property->id());
- return value && value->cssText() == property->value()->cssText();
+ int foundPropertyIndex = findPropertyIndex(property.id());
+ if (foundPropertyIndex == -1)
+ return false;
+ return propertyAt(foundPropertyIndex).value()->cssText() == property.value()->cssText();
}
void StylePropertySet::removeEquivalentProperties(const StylePropertySet* style)
@@ -1016,8 +1058,8 @@ void StylePropertySet::removeEquivalentProperties(const StylePropertySet* style)
Vector<CSSPropertyID> propertiesToRemove;
unsigned size = mutablePropertyVector().size();
for (unsigned i = 0; i < size; ++i) {
- const CSSProperty& property = mutablePropertyVector().at(i);
- if (style->propertyMatches(&property))
+ PropertyReference property = propertyAt(i);
+ if (style->propertyMatches(property))
propertiesToRemove.append(property.id());
}
// FIXME: This should use mass removal.
@@ -1031,8 +1073,8 @@ void StylePropertySet::removeEquivalentProperties(const CSSStyleDeclaration* sty
Vector<CSSPropertyID> propertiesToRemove;
unsigned size = mutablePropertyVector().size();
for (unsigned i = 0; i < size; ++i) {
- const CSSProperty& property = mutablePropertyVector().at(i);
- if (style->cssPropertyMatches(&property))
+ PropertyReference property = propertyAt(i);
+ if (style->cssPropertyMatches(property))
propertiesToRemove.append(property.id());
}
// FIXME: This should use mass removal.
@@ -1097,19 +1139,19 @@ void StylePropertySet::clearParentElement(StyledElement* element)
unsigned StylePropertySet::averageSizeInBytes()
{
// Please update this if the storage scheme changes so that this longer reflects the actual size.
- return sizeof(StylePropertySet) + sizeof(CSSProperty) * 2;
+ return sizeForImmutableStylePropertySetWithPropertyCount(2);
}
void StylePropertySet::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
- size_t actualSize = m_isMutable ? sizeof(StylePropertySet) : immutableStylePropertySetSize(m_arraySize);
+ size_t actualSize = m_isMutable ? sizeof(StylePropertySet) : sizeForImmutableStylePropertySetWithPropertyCount(m_arraySize);
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS, actualSize);
if (m_isMutable)
info.addMember(mutablePropertyVector());
-
- unsigned count = propertyCount();
- for (unsigned i = 0; i < count; ++i)
- info.addMember(propertyAt(i));
+ else {
+ for (unsigned i = 0; i < propertyCount(); ++i)
+ info.addMember(propertyAt(i).value());
+ }
}
// See the function above if you need to update this.
@@ -1125,12 +1167,6 @@ void StylePropertySet::showStyle()
}
#endif
-inline void StylePropertySet::append(const CSSProperty& property)
-{
- ASSERT(isMutable());
- mutablePropertyVector().append(property);
-}
-
PassRefPtr<StylePropertySet> StylePropertySet::create(CSSParserMode cssParserMode)
{
return adoptRef(new MutableStylePropertySet(cssParserMode));
@@ -1141,4 +1177,28 @@ PassRefPtr<StylePropertySet> StylePropertySet::create(const CSSProperty* propert
return adoptRef(new MutableStylePropertySet(properties, count));
}
+String StylePropertySet::PropertyReference::cssName() const
+{
+#if ENABLE(CSS_VARIABLES)
+ if (id() == CSSPropertyVariable) {
+ ASSERT(propertyValue()->isVariableValue());
+ return "-webkit-var-" + static_cast<const CSSVariableValue*>(propertyValue())->name();
+ }
+#endif
+ return getPropertyNameString(id());
+}
+
+String StylePropertySet::PropertyReference::cssText() const
+{
+ StringBuilder result;
+ result.append(cssName());
+ result.appendLiteral(": ");
+ result.append(propertyValue()->cssText());
+ if (isImportant())
+ result.appendLiteral(" !important");
+ result.append(';');
+ return result.toString();
+}
+
+
} // namespace WebCore
diff --git a/Source/WebCore/css/StylePropertySet.h b/Source/WebCore/css/StylePropertySet.h
index 44b6b19fc..f70f1ff7b 100644
--- a/Source/WebCore/css/StylePropertySet.h
+++ b/Source/WebCore/css/StylePropertySet.h
@@ -42,6 +42,7 @@ class StylePropertyShorthand;
class StyleSheetContents;
class StylePropertySet : public RefCounted<StylePropertySet> {
+ friend class PropertyReference;
public:
~StylePropertySet();
@@ -53,10 +54,53 @@ public:
static PassRefPtr<StylePropertySet> create(const CSSProperty* properties, unsigned count);
static PassRefPtr<StylePropertySet> createImmutable(const CSSProperty* properties, unsigned count, CSSParserMode);
+ class PropertyReference {
+ public:
+ PropertyReference(const StylePropertySet& propertySet, unsigned index)
+ : m_propertySet(propertySet)
+ , m_index(index)
+ {
+ }
+
+ CSSPropertyID id() const { return static_cast<CSSPropertyID>(propertyMetadata().m_propertyID); }
+ CSSPropertyID shorthandID() const { return static_cast<CSSPropertyID>(propertyMetadata().m_shorthandID); }
+
+ bool isImportant() const { return propertyMetadata().m_important; }
+ bool isInherited() const { return propertyMetadata().m_inherited; }
+ bool isImplicit() const { return propertyMetadata().m_implicit; }
+
+ String cssName() const;
+ String cssText() const;
+
+ const CSSValue* value() const { return propertyValue(); }
+ // FIXME: We should try to remove this mutable overload.
+ CSSValue* value() { return const_cast<CSSValue*>(propertyValue()); }
+
+ // FIXME: Remove this.
+ CSSProperty toCSSProperty() const { return CSSProperty(propertyMetadata(), const_cast<CSSValue*>(propertyValue())); }
+
+ private:
+ StylePropertyMetadata propertyMetadata() const
+ {
+ if (m_propertySet.isMutable())
+ return m_propertySet.mutablePropertyVector().at(m_index).metadata();
+ return m_propertySet.immutableMetadataArray()[m_index];
+ }
+
+ const CSSValue* propertyValue() const
+ {
+ if (m_propertySet.isMutable())
+ return m_propertySet.mutablePropertyVector().at(m_index).value();
+ return m_propertySet.immutableValueArray()[m_index];
+ }
+
+ const StylePropertySet& m_propertySet;
+ unsigned m_index;
+ };
+
unsigned propertyCount() const;
bool isEmpty() const;
- const CSSProperty& propertyAt(unsigned index) const;
- CSSProperty& propertyAt(unsigned index);
+ PropertyReference propertyAt(unsigned index) const { return PropertyReference(*this, index); }
PassRefPtr<CSSValue> getPropertyCSSValue(CSSPropertyID) const;
String getPropertyValue(CSSPropertyID) const;
@@ -79,6 +123,7 @@ public:
void addParsedProperties(const Vector<CSSProperty>&);
void addParsedProperty(const CSSProperty&);
+ void clear();
PassRefPtr<StylePropertySet> copyBlockProperties() const;
void removeBlockProperties();
bool removePropertiesInSet(const CSSPropertyID* set, unsigned length);
@@ -115,7 +160,8 @@ public:
void showStyle();
#endif
- const CSSProperty* immutablePropertyArray() const;
+ const CSSValue** immutableValueArray() const;
+ const StylePropertyMetadata* immutableMetadataArray() const;
protected:
StylePropertySet(CSSParserMode cssParserMode)
@@ -154,12 +200,10 @@ private:
bool appendFontLonghandValueIfExplicit(CSSPropertyID, StringBuilder& result) const;
bool removeShorthandProperty(CSSPropertyID);
- bool propertyMatches(const CSSProperty*) const;
-
- const CSSProperty* findPropertyWithId(CSSPropertyID) const;
- CSSProperty* findPropertyWithId(CSSPropertyID);
+ bool propertyMatches(const PropertyReference&) const;
- void append(const CSSProperty&);
+ int findPropertyIndex(CSSPropertyID) const;
+ CSSProperty* findMutableCSSPropertyWithID(CSSPropertyID);
friend class PropertySetCSSStyleDeclaration;
};
@@ -169,9 +213,21 @@ public:
ImmutableStylePropertySet(const CSSProperty*, unsigned count, CSSParserMode);
~ImmutableStylePropertySet();
- void* m_propertyArray;
+ void* m_storage;
};
+inline const CSSValue** StylePropertySet::immutableValueArray() const
+{
+ ASSERT(!m_isMutable);
+ return reinterpret_cast<const CSSValue**>(const_cast<const void**>((&static_cast<const ImmutableStylePropertySet*>(this)->m_storage)));
+}
+
+inline const StylePropertyMetadata* StylePropertySet::immutableMetadataArray() const
+{
+ ASSERT(!m_isMutable);
+ return reinterpret_cast<const StylePropertyMetadata*>(&reinterpret_cast<const char*>((&static_cast<const ImmutableStylePropertySet*>(this)->m_storage))[m_arraySize * sizeof(CSSValue*)]);
+}
+
class MutableStylePropertySet : public StylePropertySet {
public:
MutableStylePropertySet(CSSParserMode cssParserMode)
@@ -195,24 +251,6 @@ inline const Vector<CSSProperty, 4>& StylePropertySet::mutablePropertyVector() c
return static_cast<const MutableStylePropertySet*>(this)->m_propertyVector;
}
-inline const CSSProperty* StylePropertySet::immutablePropertyArray() const
-{
- ASSERT(!m_isMutable);
- return reinterpret_cast<const CSSProperty*>(&static_cast<const ImmutableStylePropertySet*>(this)->m_propertyArray);
-}
-
-inline CSSProperty& StylePropertySet::propertyAt(unsigned index)
-{
- return mutablePropertyVector().at(index);
-}
-
-inline const CSSProperty& StylePropertySet::propertyAt(unsigned index) const
-{
- if (m_isMutable)
- return mutablePropertyVector().at(index);
- return immutablePropertyArray()[index];
-}
-
inline unsigned StylePropertySet::propertyCount() const
{
if (m_isMutable)
diff --git a/Source/WebCore/css/StyleResolver.cpp b/Source/WebCore/css/StyleResolver.cpp
index ad8ddcb3c..7ccdfffd7 100644
--- a/Source/WebCore/css/StyleResolver.cpp
+++ b/Source/WebCore/css/StyleResolver.cpp
@@ -117,7 +117,6 @@
#include "StylePendingImage.h"
#include "StyleRule.h"
#include "StyleRuleImport.h"
-#include "StyleScopeResolver.h"
#include "StyleSheetContents.h"
#include "StyleSheetList.h"
#include "Text.h"
@@ -148,6 +147,7 @@
#if ENABLE(SVG)
#include "CachedSVGDocument.h"
+#include "CachedSVGDocumentReference.h"
#include "SVGDocument.h"
#include "SVGElement.h"
#include "SVGNames.h"
@@ -157,6 +157,7 @@
#if ENABLE(CSS_SHADERS)
#include "CustomFilterArrayParameter.h"
+#include "CustomFilterConstants.h"
#include "CustomFilterNumberParameter.h"
#include "CustomFilterOperation.h"
#include "CustomFilterParameter.h"
@@ -176,6 +177,14 @@
using namespace std;
+namespace WTF {
+
+template<> struct SequenceMemoryInstrumentationTraits<const WebCore::RuleData*> {
+ template <typename I> static void reportMemoryUsage(I, I, MemoryClassInfo&) { }
+};
+
+}
+
namespace WebCore {
using namespace HTMLNames;
@@ -273,7 +282,6 @@ StyleResolver::StyleResolver(Document* document, bool matchAuthorAndUserStyles)
, m_matchAuthorAndUserStyles(matchAuthorAndUserStyles)
, m_sameOriginOnly(false)
, m_distributedToInsertionPoint(false)
- , m_hasUnknownPseudoElements(false)
, m_fontSelector(CSSFontSelector::create(document))
, m_applyPropertyToRegularStyle(true)
, m_applyPropertyToVisitedLinkStyle(false)
@@ -331,25 +339,9 @@ StyleResolver::StyleResolver(Document* document, bool matchAuthorAndUserStyles)
}
#endif
- addStylesheetsFromSeamlessParents();
appendAuthorStyleSheets(0, styleSheetCollection->activeAuthorStyleSheets());
}
-void StyleResolver::addStylesheetsFromSeamlessParents()
-{
- // Build a list of stylesheet lists from our ancestors, and walk that
- // list in reverse order so that the root-most sheets are appended first.
- Document* childDocument = document();
- Vector<const Vector<RefPtr<CSSStyleSheet> >* > ancestorSheets;
- while (HTMLIFrameElement* parentIFrame = childDocument->seamlessParentIFrame()) {
- Document* parentDocument = parentIFrame->document();
- ancestorSheets.append(&parentDocument->styleSheetCollection()->activeAuthorStyleSheets());
- childDocument = parentDocument;
- }
- for (int i = ancestorSheets.size() - 1; i >= 0; i--)
- appendAuthorStyleSheets(0, *ancestorSheets[i]);
-}
-
void StyleResolver::addAuthorRulesAndCollectUserRulesFromSheets(const Vector<RefPtr<CSSStyleSheet> >* userSheets, RuleSet& userStyle)
{
if (!userSheets)
@@ -372,7 +364,7 @@ static PassOwnPtr<RuleSet> makeRuleSet(const Vector<RuleFeature>& rules)
return nullptr;
OwnPtr<RuleSet> ruleSet = RuleSet::create();
for (size_t i = 0; i < size; ++i)
- ruleSet->addRule(rules[i].rule, rules[i].selectorIndex, rules[i].hasDocumentSecurityOrigin, false);
+ ruleSet->addRule(rules[i].rule, rules[i].selectorIndex, rules[i].hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState);
ruleSet->shrinkToFit();
return ruleSet.release();
}
@@ -411,12 +403,12 @@ void StyleResolver::appendAuthorStyleSheets(unsigned firstNew, const Vector<RefP
if (cssSheet->mediaQueries() && !m_medium->eval(cssSheet->mediaQueries(), this))
continue;
StyleSheetContents* sheet = cssSheet->contents();
+#if ENABLE(STYLE_SCOPED) || ENABLE(SHADOW_DOM)
if (const ContainerNode* scope = StyleScopeResolver::scopeFor(cssSheet)) {
- if (!m_scopeResolver)
- m_scopeResolver = adoptPtr(new StyleScopeResolver());
- m_scopeResolver->ensureRuleSetFor(scope)->addRulesFromSheet(sheet, *m_medium, this, scope);
+ ensureScopeResolver()->ensureRuleSetFor(scope)->addRulesFromSheet(sheet, *m_medium, this, scope);
continue;
}
+#endif
m_authorStyle->addRulesFromSheet(sheet, *m_medium, this);
if (!m_styleRuleToCSSOMWrapperMap.isEmpty())
@@ -637,11 +629,56 @@ inline void StyleResolver::addElementStyleProperties(MatchResult& result, const
result.isCacheable = false;
}
+class MatchingUARulesScope {
+public:
+ MatchingUARulesScope();
+ ~MatchingUARulesScope();
+
+ static bool isMatchingUARules();
+
+private:
+ static bool m_matchingUARules;
+};
+
+MatchingUARulesScope::MatchingUARulesScope()
+{
+ ASSERT(!m_matchingUARules);
+ m_matchingUARules = true;
+}
+
+MatchingUARulesScope::~MatchingUARulesScope()
+{
+ m_matchingUARules = false;
+}
+
+inline bool MatchingUARulesScope::isMatchingUARules()
+{
+ return m_matchingUARules;
+}
+
+bool MatchingUARulesScope::m_matchingUARules = false;
+
void StyleResolver::collectMatchingRules(RuleSet* rules, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions& options)
{
ASSERT(rules);
ASSERT(m_element);
+ const AtomicString& pseudoId = m_element->shadowPseudoId();
+ if (!pseudoId.isEmpty()) {
+ ASSERT(m_styledElement);
+ collectMatchingRulesForList(rules->shadowPseudoElementRules(pseudoId.impl()), firstRuleIndex, lastRuleIndex, options);
+ }
+
+ // Check whether other types of rules are applicable in the current tree scope. Criteria for this:
+ // a) it's a UA rule
+ // b) the tree scope allows author rules
+ // c) the rules comes from a scoped style sheet within the same tree scope
+ TreeScope* treeScope = m_element->treeScope();
+ if (!MatchingUARulesScope::isMatchingUARules()
+ && !treeScope->applyAuthorStyles()
+ && (!options.scope || options.scope->treeScope() != treeScope))
+ return;
+
// We need to collect the rules for id, class, tag, and everything else into a buffer and
// then sort the buffer.
if (m_element->hasID())
@@ -650,11 +687,7 @@ void StyleResolver::collectMatchingRules(RuleSet* rules, int& firstRuleIndex, in
for (size_t i = 0; i < m_styledElement->classNames().size(); ++i)
collectMatchingRulesForList(rules->classRules(m_styledElement->classNames()[i].impl()), firstRuleIndex, lastRuleIndex, options);
}
- const AtomicString& pseudoId = m_element->shadowPseudoId();
- if (!pseudoId.isEmpty()) {
- ASSERT(m_styledElement);
- collectMatchingRulesForList(rules->shadowPseudoElementRules(pseudoId.impl()), firstRuleIndex, lastRuleIndex, options);
- }
+
if (m_element->isLink())
collectMatchingRulesForList(rules->linkPseudoClassRules(), firstRuleIndex, lastRuleIndex, options);
if (m_checker.matchesFocusPseudoClass(m_element))
@@ -710,7 +743,12 @@ void StyleResolver::sortAndTransferMatchedRules(MatchResult& result)
void StyleResolver::matchScopedAuthorRules(MatchResult& result, bool includeEmptyRules)
{
#if ENABLE(STYLE_SCOPED) || ENABLE(SHADOW_DOM)
- if (!m_scopeResolver || !m_scopeResolver->hasScopedStyles())
+ if (!m_scopeResolver)
+ return;
+
+ matchHostRules(result, includeEmptyRules);
+
+ if (!m_scopeResolver->hasScopedStyles())
return;
// Match scoped author rules by traversing the scoped element stack (rebuild it if it got inconsistent).
@@ -742,6 +780,35 @@ void StyleResolver::matchScopedAuthorRules(MatchResult& result, bool includeEmpt
#endif
}
+inline bool StyleResolver::styleSharingCandidateMatchesHostRules()
+{
+#if ENABLE(SHADOW_DOM)
+ return m_scopeResolver && m_scopeResolver->styleSharingCandidateMatchesHostRules(m_element);
+#else
+ return false;
+#endif
+}
+
+void StyleResolver::matchHostRules(MatchResult& result, bool includeEmptyRules)
+{
+#if ENABLE(SHADOW_DOM)
+ ASSERT(m_scopeResolver);
+
+ Vector<RuleSet*> matchedRules;
+ m_scopeResolver->matchHostRules(m_element, matchedRules);
+ if (matchedRules.isEmpty())
+ return;
+
+ MatchOptions options(includeEmptyRules);
+ options.scope = m_element;
+ for (unsigned i = matchedRules.size(); i > 0; --i)
+ collectMatchingRules(matchedRules.at(i-1), result.ranges.firstAuthorRule, result.ranges.lastAuthorRule, options);
+#else
+ UNUSED_PARAM(result);
+ UNUSED_PARAM(includeEmptyRules);
+#endif
+}
+
void StyleResolver::matchAuthorRules(MatchResult& result, bool includeEmptyRules)
{
m_matchedRules.clear();
@@ -784,42 +851,11 @@ void StyleResolver::matchUARules(MatchResult& result, RuleSet* rules)
sortAndTransferMatchedRules(result);
}
-class MatchingUARulesScope {
-public:
- MatchingUARulesScope();
- ~MatchingUARulesScope();
-
- static bool isMatchingUARules();
-
-private:
- static bool m_matchingUARules;
-};
-
-MatchingUARulesScope::MatchingUARulesScope()
-{
- ASSERT(!m_matchingUARules);
- m_matchingUARules = true;
-}
-
-MatchingUARulesScope::~MatchingUARulesScope()
-{
- m_matchingUARules = false;
-}
-
-inline bool MatchingUARulesScope::isMatchingUARules()
-{
- return m_matchingUARules;
-}
-
-bool MatchingUARulesScope::m_matchingUARules = false;
-
void StyleResolver::collectMatchingRulesForList(const Vector<RuleData>* rules, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions& options)
{
if (!rules)
return;
- TreeScope* treeScope = m_element->treeScope();
-
// In some cases we may end up looking up style for random elements in the middle of a recursive tree resolve.
// Ancestor identifier filter won't be up-to-date in that case and we can't use the fast path.
bool canUseFastReject = m_checker.parentStackIsConsistent(m_parentNode);
@@ -833,19 +869,6 @@ void StyleResolver::collectMatchingRulesForList(const Vector<RuleData>* rules, i
StyleRule* rule = ruleData.rule();
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willMatchRule(document(), rule);
if (checkSelector(ruleData, options.scope)) {
- // Check whether the rule is applicable in the current tree scope. Criteria for this:
- // a) it's a UA rule
- // b) the tree scope allows author rules
- // c) the rules comes from a scoped style sheet within the same tree scope
- // d) the rule contains shadow-ID pseudo elements
- if (!MatchingUARulesScope::isMatchingUARules()
- && !treeScope->applyAuthorStyles()
- && (!options.scope || options.scope->treeScope() != treeScope)
- && !m_hasUnknownPseudoElements) {
-
- InspectorInstrumentation::didMatchRule(cookie, false);
- continue;
- }
// If the rule has no properties to apply, then ignore it in the non-debug mode.
const StylePropertySet* properties = rule->properties();
if (!properties || (properties->isEmpty() && !options.includeEmptyRules)) {
@@ -959,21 +982,10 @@ inline bool shouldResetStyleInheritance(NodeRenderingContext& context)
if (context.resetStyleInheritance())
return true;
- InsertionPoint* insertionPoint = context.insertionPoint();
- if (!insertionPoint)
- return false;
-
- ASSERT(parentElementForDistribution(context.node()));
- ElementShadow* shadow = parentElementForDistribution(context.node())->shadow();
- ASSERT(shadow);
+ if (InsertionPoint* insertionPoint = context.insertionPoint())
+ return insertionPoint->resetStyleInheritance();
- for ( ; insertionPoint; ) {
- InsertionPoint* youngerInsertionPoint = shadow->insertionPointFor(insertionPoint);
- if (!youngerInsertionPoint)
- break;
- insertionPoint = youngerInsertionPoint;
- }
- return insertionPoint->resetStyleInheritance();
+ return false;
}
inline void StyleResolver::initForStyleResolve(Element* e, RenderStyle* parentStyle, PseudoId pseudoID)
@@ -1124,10 +1136,10 @@ static inline bool attributeStylesEqual(const StylePropertySet* a, const StylePr
return false;
unsigned propertyCount = a->propertyCount();
for (unsigned i = 0; i < propertyCount; ++i) {
- const CSSProperty& aProperty = a->propertyAt(i);
+ StylePropertySet::PropertyReference aProperty = a->propertyAt(i);
unsigned j;
for (j = 0; j < propertyCount; ++j) {
- const CSSProperty& bProperty = b->propertyAt(j);
+ StylePropertySet::PropertyReference bProperty = b->propertyAt(j);
if (aProperty.id() != bProperty.id())
continue;
// We could get a few more hits by comparing cssText() here, but that gets expensive quickly.
@@ -1187,8 +1199,6 @@ bool StyleResolver::canShareStyleWithElement(StyledElement* element) const
return false;
if (element == element->document()->cssTarget())
return false;
- if (m_element == m_element->document()->cssTarget())
- return false;
if (element->fastGetAttribute(XMLNames::langAttr) != m_element->fastGetAttribute(XMLNames::langAttr))
return false;
if (element->fastGetAttribute(langAttr) != m_element->fastGetAttribute(langAttr))
@@ -1204,9 +1214,7 @@ bool StyleResolver::canShareStyleWithElement(StyledElement* element) const
#if ENABLE(PROGRESS_ELEMENT)
if (element->hasTagName(progressTag)) {
- if (!m_element->hasTagName(progressTag))
- return false;
-
+ ASSERT(m_element->hasTagName(progressTag));
HTMLProgressElement* thisProgressElement = static_cast<HTMLProgressElement*>(element);
HTMLProgressElement* otherProgressElement = static_cast<HTMLProgressElement*>(m_element);
if (thisProgressElement->isDeterminate() != otherProgressElement->isDeterminate())
@@ -1243,7 +1251,7 @@ bool StyleResolver::canShareStyleWithElement(StyledElement* element) const
return false;
#endif
- if (elementHasDirectionAuto(element) || elementHasDirectionAuto(m_element))
+ if (elementHasDirectionAuto(element))
return false;
if (element->hasClass()) {
@@ -1309,6 +1317,10 @@ RenderStyle* StyleResolver::locateSharedStyle()
return 0;
if (m_styledElement->hasScopedHTMLStyleChild())
return 0;
+ if (m_element == m_element->document()->cssTarget())
+ return 0;
+ if (elementHasDirectionAuto(m_element))
+ return 0;
// Check previous siblings and their cousins.
unsigned count = 0;
@@ -1332,6 +1344,9 @@ RenderStyle* StyleResolver::locateSharedStyle()
// Can't share if attribute rules apply.
if (styleSharingCandidateMatchesRuleSet(m_uncommonAttributeRuleSet.get()))
return 0;
+ // Can't share if @host @-rules apply.
+ if (styleSharingCandidateMatchesHostRules())
+ return 0;
// Tracking child index requires unique style for each node. This may get set by the sibling rule match above.
if (parentStylePreventsSharing(m_parentStyle))
return 0;
@@ -1539,9 +1554,10 @@ PassRefPtr<RenderStyle> StyleResolver::styleForElement(Element* element, RenderS
// contenteditable attribute (implemented by -webkit-user-modify) should
// be propagated from shadow host to distributed node.
if (m_distributedToInsertionPoint) {
- ASSERT(element->parentElement());
- if (RenderStyle* styleOfShadowHost = element->parentElement()->renderStyle())
- m_style->setUserModify(styleOfShadowHost->userModify());
+ if (Element* parent = element->parentElement()) {
+ if (RenderStyle* styleOfShadowHost = parent->renderStyle())
+ m_style->setUserModify(styleOfShadowHost->userModify());
+ }
}
if (element->isLink()) {
@@ -2159,7 +2175,6 @@ PassRefPtr<CSSRuleList> StyleResolver::pseudoStyleRulesForElement(Element* e, Ps
inline bool StyleResolver::checkSelector(const RuleData& ruleData, const ContainerNode* scope)
{
m_dynamicPseudo = NOPSEUDO;
- m_hasUnknownPseudoElements = false;
if (ruleData.hasFastCheckableSelector()) {
// We know this selector does not include any pseudo elements.
@@ -2183,7 +2198,7 @@ inline bool StyleResolver::checkSelector(const RuleData& ruleData, const Contain
context.elementParentStyle = m_parentNode ? m_parentNode->renderStyle() : 0;
context.scope = scope;
context.pseudoStyle = m_pseudoStyle;
- SelectorChecker::SelectorMatch match = m_checker.checkSelector(context, m_dynamicPseudo, m_hasUnknownPseudoElements);
+ SelectorChecker::SelectorMatch match = m_checker.checkSelector(context, m_dynamicPseudo);
if (match != SelectorChecker::SelectorMatches)
return false;
if (m_pseudoStyle != NOPSEUDO && m_pseudoStyle != m_dynamicPseudo)
@@ -2196,7 +2211,6 @@ bool StyleResolver::checkRegionSelector(CSSSelector* regionSelector, Element* re
if (!regionSelector || !regionElement)
return false;
- m_hasUnknownPseudoElements = false;
m_pseudoStyle = NOPSEUDO;
for (CSSSelector* s = regionSelector; s; s = CSSSelectorList::next(s))
@@ -2227,7 +2241,7 @@ void StyleResolver::applyProperties(const StylePropertySet* properties, StyleRul
unsigned propertyCount = properties->propertyCount();
for (unsigned i = 0; i < propertyCount; ++i) {
- const CSSProperty& current = properties->propertyAt(i);
+ StylePropertySet::PropertyReference current = properties->propertyAt(i);
if (isImportant != current.isImportant())
continue;
if (inheritedOnly && !current.isInherited()) {
@@ -2780,7 +2794,7 @@ void StyleResolver::resolveVariables(CSSPropertyID id, CSSValue* value, Vector<s
return; // expression failed to parse.
for (unsigned i = 0; i < resultSet->propertyCount(); i++) {
- const CSSProperty& property = resultSet->propertyAt(i);
+ StylePropertySet::PropertyReference property = resultSet->propertyAt(i);
if (property.id() != CSSPropertyVariable && hasVariableReference(property.value()))
resolveVariables(property.id(), property.value(), knownExpressions);
else
@@ -4235,11 +4249,6 @@ Color StyleResolver::colorFromPrimitiveValue(CSSPrimitiveValue* value, bool forV
}
}
-bool StyleResolver::hasSelectorForAttribute(const AtomicString &attrname) const
-{
- return m_features.attrsInRules.contains(attrname.impl());
-}
-
void StyleResolver::addViewportDependentMediaQueryResult(const MediaQueryExp* expr, bool result)
{
m_viewportDependentMediaQueryResults.append(adoptPtr(new MediaQueryResult(*expr, result)));
@@ -4586,7 +4595,7 @@ void StyleResolver::loadPendingSVGDocuments()
continue;
// Stash the CachedSVGDocument on the reference filter.
- referenceFilter->setData(cachedDocument);
+ referenceFilter->setData(adoptPtr(new CachedSVGDocumentReference(cachedDocument)));
}
}
m_pendingSVGDocuments.clear();
@@ -4765,16 +4774,18 @@ PassRefPtr<CustomFilterOperation> StyleResolver::createCustomFilterOperation(Web
ASSERT(shadersValue->isValueList());
CSSValueList* shadersList = static_cast<CSSValueList*>(shadersValue);
- ASSERT(shadersList->length());
- RefPtr<StyleShader> vertexShader = styleShader(shadersList->itemWithoutBoundsCheck(0));
+ unsigned shadersListLength = shadersList->length();
+ ASSERT(shadersListLength);
+ RefPtr<StyleShader> vertexShader = styleShader(shadersList->itemWithoutBoundsCheck(0));
RefPtr<StyleShader> fragmentShader;
- CustomFilterProgramType programType = PROGRAM_TYPE_NO_ELEMENT_TEXTURE;
+ CustomFilterProgramType programType = PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE;
CustomFilterProgramMixSettings mixSettings;
- if (shadersList->length() > 1) {
+
+ if (shadersListLength > 1) {
CSSValue* fragmentShaderOrMixFunction = shadersList->itemWithoutBoundsCheck(1);
+
if (fragmentShaderOrMixFunction->isWebKitCSSMixFunctionValue()) {
- programType = PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE;
WebKitCSSMixFunctionValue* mixFunction = static_cast<WebKitCSSMixFunctionValue*>(fragmentShaderOrMixFunction);
CSSValueListIterator iterator(mixFunction);
@@ -4793,14 +4804,16 @@ PassRefPtr<CustomFilterOperation> StyleResolver::createCustomFilterOperation(Web
ASSERT_NOT_REACHED();
iterator.advance();
}
- } else
+ } else {
+ programType = PROGRAM_TYPE_NO_ELEMENT_TEXTURE;
fragmentShader = styleShader(fragmentShaderOrMixFunction);
+ }
}
unsigned meshRows = 1;
unsigned meshColumns = 1;
- CustomFilterOperation::MeshBoxType meshBoxType = CustomFilterOperation::FILTER_BOX;
- CustomFilterOperation::MeshType meshType = CustomFilterOperation::ATTACHED;
+ CustomFilterMeshBoxType meshBoxType = MeshBoxTypeFilter;
+ CustomFilterMeshType meshType = MeshTypeAttached;
CSSValue* parametersValue = 0;
@@ -4816,14 +4829,14 @@ PassRefPtr<CustomFilterOperation> StyleResolver::createCustomFilterOperation(Web
if (primitiveValue->isNumber()) {
// If only one integer value is specified, it will set both
// the rows and the columns.
- meshRows = meshColumns = primitiveValue->getIntValue();
+ meshColumns = meshRows = primitiveValue->getIntValue();
iterator.advance();
- // Try to match another number for the columns.
+ // Try to match another number for the rows.
if (iterator.hasMore() && iterator.isPrimitiveValue()) {
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(iterator.value());
if (primitiveValue->isNumber()) {
- meshColumns = primitiveValue->getIntValue();
+ meshRows = primitiveValue->getIntValue();
iterator.advance();
}
}
@@ -4844,7 +4857,7 @@ PassRefPtr<CustomFilterOperation> StyleResolver::createCustomFilterOperation(Web
if (iterator.hasMore() && iterator.isPrimitiveValue()) {
CSSPrimitiveValue* primitiveValue = static_cast<CSSPrimitiveValue*>(iterator.value());
if (primitiveValue->getIdent() == CSSValueDetached) {
- meshType = CustomFilterOperation::DETACHED;
+ meshType = MeshTypeDetached;
iterator.advance();
}
}
@@ -4864,7 +4877,7 @@ PassRefPtr<CustomFilterOperation> StyleResolver::createCustomFilterOperation(Web
if (parametersValue && !parseCustomFilterParameterList(parametersValue, parameterList))
return 0;
- RefPtr<StyleCustomFilterProgram> program = StyleCustomFilterProgram::create(vertexShader.release(), fragmentShader.release(), programType, mixSettings);
+ RefPtr<StyleCustomFilterProgram> program = StyleCustomFilterProgram::create(vertexShader.release(), fragmentShader.release(), programType, mixSettings, meshType);
return CustomFilterOperation::create(program.release(), parameterList, meshRows, meshColumns, meshBoxType, meshType);
}
#endif
@@ -4896,6 +4909,11 @@ bool StyleResolver::createFilterOperations(CSSValue* inValue, RenderStyle* style
FilterOperation::OperationType operationType = filterOperationForType(filterValue->operationType());
#if ENABLE(CSS_SHADERS)
+ if (operationType == FilterOperation::VALIDATED_CUSTOM) {
+ // ValidatedCustomFilterOperation is not supposed to end up in the RenderStyle.
+ ASSERT_NOT_REACHED();
+ continue;
+ }
if (operationType == FilterOperation::CUSTOM) {
RefPtr<CustomFilterOperation> operation = createCustomFilterOperation(filterValue);
if (!operation)
@@ -4921,8 +4939,8 @@ bool StyleResolver::createFilterOperations(CSSValue* inValue, RenderStyle* style
if (SVGURIReference::isExternalURIReference(svgDocumentValue->url(), m_element->document())) {
if (!svgDocumentValue->loadRequested())
m_pendingSVGDocuments.set(operation.get(), svgDocumentValue);
- else
- operation->setData(svgDocumentValue->cachedSVGDocument());
+ else if (svgDocumentValue->cachedSVGDocument())
+ operation->setData(adoptPtr(new CachedSVGDocumentReference(svgDocumentValue->cachedSVGDocument())));
}
operations.operations().append(operation);
#endif
diff --git a/Source/WebCore/css/StyleResolver.h b/Source/WebCore/css/StyleResolver.h
index 5b514ce55..f76993442 100644
--- a/Source/WebCore/css/StyleResolver.h
+++ b/Source/WebCore/css/StyleResolver.h
@@ -29,8 +29,10 @@
#include "MediaQueryExp.h"
#include "RenderStyle.h"
#include "RuleFeature.h"
+#include "RuntimeEnabledFeatures.h"
#include "SelectorChecker.h"
#include "StyleInheritedData.h"
+#include "StyleScopeResolver.h"
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/RefPtr.h>
@@ -59,6 +61,7 @@ class CSSValue;
class ContainerNode;
class CustomFilterOperation;
class CustomFilterParameter;
+class CustomFilterParameterList;
class Document;
class Element;
class Frame;
@@ -80,6 +83,7 @@ class StyleKeyframe;
class StylePendingImage;
class StylePropertySet;
class StyleRule;
+class StyleRuleHost;
class StyleRuleKeyframes;
class StyleRulePage;
class StyleRuleRegion;
@@ -92,10 +96,6 @@ class WebKitCSSFilterValue;
class WebKitCSSShaderValue;
class WebKitCSSSVGDocumentValue;
-#if ENABLE(CSS_SHADERS)
-typedef Vector<RefPtr<CustomFilterParameter> > CustomFilterParameterList;
-#endif
-
class MediaQueryResult {
WTF_MAKE_NONCOPYABLE(MediaQueryResult); WTF_MAKE_FAST_ALLOCATED;
public:
@@ -137,6 +137,9 @@ public:
void popParentElement(Element*);
void pushParentShadowRoot(const ShadowRoot*);
void popParentShadowRoot(const ShadowRoot*);
+#if ENABLE(SHADOW_DOM)
+ void addHostRule(StyleRuleHost* rule, bool hasDocumentSecurityOrigin, const ContainerNode* scope) { ensureScopeResolver()->addHostRule(rule, hasDocumentSecurityOrigin, scope); }
+#endif
PassRefPtr<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle = 0, StyleSharingBehavior = AllowStyleSharing,
RuleMatchingBehavior = MatchAllRules, RenderRegion* regionForStyling = 0);
@@ -166,11 +169,30 @@ public:
void appendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >&);
private:
+#if ENABLE(STYLE_SCOPED) || ENABLE(SHADOW_DOM)
+ StyleScopeResolver* ensureScopeResolver()
+ {
+#if ENABLE(STYLE_SCOPED)
+#if ENABLE(SHADOW_DOM)
+ ASSERT(RuntimeEnabledFeatures::shadowDOMEnabled() || RuntimeEnabledFeatures::styleScopedEnabled());
+#else
+ ASSERT(RuntimeEnabledFeatures::styleScopedEnabled());
+#endif
+#else
+ ASSERT(RuntimeEnabledFeatures::shadowDOMEnabled());
+#endif
+ if (!m_scopeResolver)
+ m_scopeResolver = adoptPtr(new StyleScopeResolver());
+ return m_scopeResolver.get();
+ }
+#endif
+
void initForStyleResolve(Element*, RenderStyle* parentStyle = 0, PseudoId = NOPSEUDO);
void initElement(Element*);
void collectFeatures();
RenderStyle* locateSharedStyle();
bool styleSharingCandidateMatchesRuleSet(RuleSet*);
+ bool styleSharingCandidateMatchesHostRules();
Node* locateCousinList(Element* parent, unsigned& visitedNodeCount) const;
StyledElement* findSiblingForStyleSharing(Node*, unsigned& count) const;
bool canShareStyleWithElement(StyledElement*) const;
@@ -218,6 +240,8 @@ public:
static bool colorFromPrimitiveValueIsDerivedFromElement(CSSPrimitiveValue*);
Color colorFromPrimitiveValue(CSSPrimitiveValue*, bool forVisitedLink = false) const;
+ bool hasSelectorForId(const AtomicString&) const;
+ bool hasSelectorForClass(const AtomicString&) const;
bool hasSelectorForAttribute(const AtomicString&) const;
CSSFontSelector* fontSelector() const { return m_fontSelector.get(); }
@@ -323,6 +347,7 @@ private:
void matchAuthorRules(MatchResult&, bool includeEmptyRules);
void matchUserRules(MatchResult&, bool includeEmptyRules);
void matchScopedAuthorRules(MatchResult&, bool includeEmptyRules);
+ void matchHostRules(MatchResult&, bool includeEmptyRules);
void collectMatchingRules(RuleSet*, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions&);
void collectMatchingRulesForRegion(RuleSet*, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions&);
void collectMatchingRulesForList(const Vector<RuleData>*, int& firstRuleIndex, int& lastRuleIndex, const MatchOptions&);
@@ -330,7 +355,7 @@ private:
void sortMatchedRules();
void sortAndTransferMatchedRules(MatchResult&);
- bool checkSelector(const RuleData&, const ContainerNode* scope = 0);
+ bool checkSelector(const RuleData&, const ContainerNode* scope);
bool checkRegionSelector(CSSSelector* regionSelector, Element* regionElement);
void applyMatchedProperties(const MatchResult&, const Element*);
enum StyleApplicationPass {
@@ -396,7 +421,6 @@ public:
private:
static RenderStyle* s_styleNotYetAvailable;
- void addStylesheetsFromSeamlessParents();
void addAuthorRulesAndCollectUserRulesFromSheets(const Vector<RefPtr<CSSStyleSheet> >*, RuleSet& userStyle);
void cacheBorderAndBackground();
@@ -465,7 +489,6 @@ private:
bool m_matchAuthorAndUserStyles;
bool m_sameOriginOnly;
bool m_distributedToInsertionPoint;
- bool m_hasUnknownPseudoElements;
RefPtr<CSSFontSelector> m_fontSelector;
Vector<OwnPtr<MediaQueryResult> > m_viewportDependentMediaQueryResults;
@@ -495,6 +518,24 @@ private:
friend bool operator!=(const MatchRanges&, const MatchRanges&);
};
+inline bool StyleResolver::hasSelectorForAttribute(const AtomicString &attributeName) const
+{
+ ASSERT(!attributeName.isEmpty());
+ return m_features.attrsInRules.contains(attributeName.impl());
+}
+
+inline bool StyleResolver::hasSelectorForClass(const AtomicString& classValue) const
+{
+ ASSERT(!classValue.isEmpty());
+ return m_features.classesInRules.contains(classValue.impl());
+}
+
+inline bool StyleResolver::hasSelectorForId(const AtomicString& idValue) const
+{
+ ASSERT(!idValue.isEmpty());
+ return m_features.idsInRules.contains(idValue.impl());
+}
+
} // namespace WebCore
#endif // StyleResolver_h
diff --git a/Source/WebCore/css/StyleRule.cpp b/Source/WebCore/css/StyleRule.cpp
index 73b0af26c..713c97146 100644
--- a/Source/WebCore/css/StyleRule.cpp
+++ b/Source/WebCore/css/StyleRule.cpp
@@ -33,6 +33,7 @@
#include "WebKitCSSKeyframeRule.h"
#include "WebKitCSSKeyframesRule.h"
#include "WebKitCSSRegionRule.h"
+#include "WebKitCSSViewportRule.h"
#include <wtf/MemoryInstrumentationVector.h>
namespace WebCore {
@@ -79,6 +80,14 @@ void StyleRuleBase::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
case Keyframes:
static_cast<const StyleRuleKeyframes*>(this)->reportDescendantMemoryUsage(memoryObjectInfo);
return;
+ case Host:
+ static_cast<const StyleRuleBlock*>(this)->reportDescendantMemoryUsage(memoryObjectInfo);
+ return;
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ case Viewport:
+ static_cast<const StyleRuleViewport*>(this)->reportDescendantMemoryUsage(memoryObjectInfo);
+ return;
+#endif
case Unknown:
case Charset:
case Keyframe:
@@ -117,6 +126,14 @@ void StyleRuleBase::destroy()
case Keyframes:
delete static_cast<StyleRuleKeyframes*>(this);
return;
+ case Host:
+ delete static_cast<StyleRuleHost*>(this);
+ return;
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ case Viewport:
+ delete static_cast<StyleRuleViewport*>(this);
+ return;
+#endif
case Unknown:
case Charset:
case Keyframe:
@@ -150,6 +167,12 @@ PassRefPtr<StyleRuleBase> StyleRuleBase::copy() const
return 0;
case Keyframes:
return static_cast<const StyleRuleKeyframes*>(this)->copy();
+ case Host:
+ return static_cast<const StyleRuleHost*>(this)->copy();
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ case Viewport:
+ return static_cast<const StyleRuleViewport*>(this)->copy();
+#endif
case Unknown:
case Charset:
case Keyframe:
@@ -191,6 +214,12 @@ PassRefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet
case Keyframes:
rule = WebKitCSSKeyframesRule::create(static_cast<StyleRuleKeyframes*>(self), parentSheet);
break;
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ case Viewport:
+ rule = WebKitCSSViewportRule::create(static_cast<StyleRuleViewport*>(self), parentSheet);
+ break;
+#endif
+ case Host:
case Unknown:
case Charset:
case Keyframe:
@@ -381,4 +410,39 @@ void StyleRuleRegion::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObject
info.addMember(m_selectorList);
}
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+StyleRuleViewport::StyleRuleViewport()
+ : StyleRuleBase(Viewport, 0)
+{
+}
+
+StyleRuleViewport::StyleRuleViewport(const StyleRuleViewport& o)
+ : StyleRuleBase(o)
+ , m_properties(o.m_properties->copy())
+{
+}
+
+StyleRuleViewport::~StyleRuleViewport()
+{
+}
+
+StylePropertySet* StyleRuleViewport::mutableProperties()
+{
+ if (!m_properties->isMutable())
+ m_properties = m_properties->copy();
+ return m_properties.get();
+}
+
+void StyleRuleViewport::setProperties(PassRefPtr<StylePropertySet> properties)
+{
+ m_properties = properties;
+}
+
+void StyleRuleViewport::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+{
+ MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
+ info.addMember(m_properties);
+}
+#endif // ENABLE(CSS_DEVICE_ADAPTATION)
+
} // namespace WebCore
diff --git a/Source/WebCore/css/StyleRule.h b/Source/WebCore/css/StyleRule.h
index e15f32e40..4d4340a6d 100644
--- a/Source/WebCore/css/StyleRule.h
+++ b/Source/WebCore/css/StyleRule.h
@@ -46,6 +46,10 @@ public:
Page,
Keyframes,
Keyframe, // Not used. These are internally non-rule StyleKeyframe objects.
+ Host,
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ Viewport = 15,
+#endif
Region = 16
};
Type type() const { return static_cast<Type>(m_type); }
@@ -57,7 +61,11 @@ public:
bool isPageRule() const { return type() == Page; }
bool isStyleRule() const { return type() == Style; }
bool isRegionRule() const { return type() == Region; }
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ bool isViewportRule() const { return type() == Viewport; }
+#endif
bool isImportRule() const { return type() == Import; }
+ bool isHostRule() const { return type() == Host; }
PassRefPtr<StyleRuleBase> copy() const;
@@ -223,6 +231,44 @@ private:
CSSSelectorList m_selectorList;
};
+class StyleRuleHost : public StyleRuleBlock {
+public:
+ static PassRefPtr<StyleRuleHost> create(Vector<RefPtr<StyleRuleBase> >& adoptRules)
+ {
+ return adoptRef(new StyleRuleHost(adoptRules));
+ }
+
+ PassRefPtr<StyleRuleHost> copy() const { return adoptRef(new StyleRuleHost(*this)); }
+
+private:
+ StyleRuleHost(Vector<RefPtr<StyleRuleBase> >& adoptRules) : StyleRuleBlock(Host, adoptRules) { }
+ StyleRuleHost(const StyleRuleHost& o) : StyleRuleBlock(o) { }
+};
+
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+class StyleRuleViewport : public StyleRuleBase {
+public:
+ static PassRefPtr<StyleRuleViewport> create() { return adoptRef(new StyleRuleViewport); }
+
+ ~StyleRuleViewport();
+
+ const StylePropertySet* properties() const { return m_properties.get(); }
+ StylePropertySet* mutableProperties();
+
+ void setProperties(PassRefPtr<StylePropertySet>);
+
+ PassRefPtr<StyleRuleViewport> copy() const { return adoptRef(new StyleRuleViewport(*this)); }
+
+ void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
+
+private:
+ StyleRuleViewport();
+ StyleRuleViewport(const StyleRuleViewport&);
+
+ RefPtr<StylePropertySet> m_properties;
+};
+#endif // ENABLE(CSS_DEVICE_ADAPTATION)
+
} // namespace WebCore
#endif // StyleRule_h
diff --git a/Source/WebCore/css/StyleScopeResolver.cpp b/Source/WebCore/css/StyleScopeResolver.cpp
index 87402baa5..5ff2b3e0b 100644
--- a/Source/WebCore/css/StyleScopeResolver.cpp
+++ b/Source/WebCore/css/StyleScopeResolver.cpp
@@ -29,8 +29,10 @@
#if ENABLE(STYLE_SCOPED) || ENABLE(SHADOW_DOM)
+#include "CSSStyleRule.h"
#include "CSSStyleSheet.h"
#include "ContextFeatures.h"
+#include "ElementShadow.h"
#include "HTMLNames.h"
#include "HTMLStyleElement.h"
#include "RuleFeature.h"
@@ -154,11 +156,91 @@ void StyleScopeResolver::collectFeaturesTo(RuleFeatureSet& features)
features.add(it->value->features());
}
+inline RuleSet* StyleScopeResolver::ensureAtHostRuleSetFor(const ShadowRoot* shadowRoot)
+{
+ ScopedRuleSetMap::AddResult addResult = m_atHostRules.add(shadowRoot, nullptr);
+ if (addResult.isNewEntry)
+ addResult.iterator->value = RuleSet::create();
+ return addResult.iterator->value.get();
+}
+
+inline RuleSet* StyleScopeResolver::atHostRuleSetFor(const ShadowRoot* shadowRoot) const
+{
+ ScopedRuleSetMap::const_iterator it = m_atHostRules.find(shadowRoot);
+ return it != m_atHostRules.end() ? it->value.get() : 0;
+}
+
+void StyleScopeResolver::addHostRule(StyleRuleHost* hostRule, bool hasDocumentSecurityOrigin, const ContainerNode* scope)
+{
+ if (!scope || !scope->isInShadowTree())
+ return;
+
+ ShadowRoot* shadowRoot = scope->shadowRoot();
+ if (!shadowRoot || !shadowRoot->host())
+ return;
+
+ RuleSet* rule = ensureAtHostRuleSetFor(shadowRoot);
+
+ const Vector<RefPtr<StyleRuleBase> >& childRules = hostRule->childRules();
+ AddRuleFlags addRuleFlags = hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState;
+ addRuleFlags = static_cast<AddRuleFlags>(addRuleFlags | RuleCanUseFastCheckSelector | RuleIsHostRule);
+ for (unsigned i = 0; i < childRules.size(); ++i) {
+ StyleRuleBase* hostStylingRule = childRules[i].get();
+ if (hostStylingRule->isStyleRule())
+ rule->addStyleRule(static_cast<StyleRule*>(hostStylingRule), addRuleFlags);
+ }
+}
+
+bool StyleScopeResolver::styleSharingCandidateMatchesHostRules(const Element* element)
+{
+ if (m_atHostRules.isEmpty())
+ return false;
+
+ ElementShadow* shadow = element->shadow();
+ if (!shadow)
+ return false;
+
+ // FIXME(99827): https://bugs.webkit.org/show_bug.cgi?id=99827
+ // add a new flag to ElementShadow and cache whether any@host @-rules are
+ // applied to the element or not. So we can avoid always traversing
+ // shadow roots.
+ for (ShadowRoot* shadowRoot = shadow->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot()) {
+ if (atHostRuleSetFor(shadowRoot))
+ return true;
+
+ if (!shadowRoot->hasShadowInsertionPoint())
+ break;
+ }
+ return false;
+}
+
+void StyleScopeResolver::matchHostRules(const Element* element, Vector<RuleSet*>& matchedRules)
+{
+ if (m_atHostRules.isEmpty())
+ return;
+
+ ElementShadow* shadow = element->shadow();
+ if (!shadow)
+ return;
+
+ // FIXME(99827): https://bugs.webkit.org/show_bug.cgi?id=99827
+ // add a new flag to ElementShadow and cache whether any @host @-rules are
+ // applied to the element or not. So we can quickly exit this method
+ // by using the flag.
+ for (ShadowRoot* shadowRoot = shadow->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot()) {
+ if (RuleSet* ruleSet = atHostRuleSetFor(shadowRoot))
+ matchedRules.append(ruleSet);
+ if (!shadowRoot->hasShadowInsertionPoint())
+ break;
+ }
+}
+
void StyleScopeResolver::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
{
MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
info.addMember(m_authorStyles);
info.addMember(m_stack);
+ info.addMember(m_atHostRules);
}
}
diff --git a/Source/WebCore/css/StyleScopeResolver.h b/Source/WebCore/css/StyleScopeResolver.h
index 5a32dfe79..3be3ff4f7 100644
--- a/Source/WebCore/css/StyleScopeResolver.h
+++ b/Source/WebCore/css/StyleScopeResolver.h
@@ -37,8 +37,11 @@ namespace WebCore {
class ContainerNode;
class CSSStyleSheet;
+class Element;
class RuleSet;
-class RuleFeatureSet;
+class ShadowRoot;
+class StyleRuleHost;
+struct RuleFeatureSet;
#if ENABLE(STYLE_SCOPED) || ENABLE(SHADOW_DOM)
@@ -72,12 +75,18 @@ public:
bool matchesStyleBounds(const StackFrame& frame) const { return frame.m_authorStyleBoundsIndex == m_stackParentBoundsIndex; }
void collectFeaturesTo(RuleFeatureSet&);
+ void addHostRule(StyleRuleHost*, bool hasDocumentSecurityOrigin, const ContainerNode* scope);
+ bool styleSharingCandidateMatchesHostRules(const Element*);
+ void matchHostRules(const Element*, Vector<RuleSet*>& matchedRules);
+
void reportMemoryUsage(MemoryObjectInfo*) const;
private:
RuleSet* ruleSetFor(const ContainerNode* scope) const;
void setupStack(const ContainerNode*);
bool stackIsConsistent(const ContainerNode* parent) const { return parent && parent == m_stackParent; }
+ RuleSet* ensureAtHostRuleSetFor(const ShadowRoot*);
+ RuleSet* atHostRuleSetFor(const ShadowRoot*) const;
ScopedRuleSetMap m_authorStyles;
@@ -88,6 +97,8 @@ private:
// This is used to decide whether m_scopingElementStack is consistent, separately from SelectorChecker::m_parentStack.
const ContainerNode* m_stackParent;
int m_stackParentBoundsIndex;
+
+ ScopedRuleSetMap m_atHostRules;
};
inline bool StyleScopeResolver::ensureStackConsistency(ContainerNode* parent)
diff --git a/Source/WebCore/css/StyleSheetContents.cpp b/Source/WebCore/css/StyleSheetContents.cpp
index e7ce81eaa..2f07fce83 100644
--- a/Source/WebCore/css/StyleSheetContents.cpp
+++ b/Source/WebCore/css/StyleSheetContents.cpp
@@ -435,6 +435,10 @@ static bool childRulesHaveFailedOrCanceledSubresources(const Vector<RefPtr<Style
if (childRulesHaveFailedOrCanceledSubresources(static_cast<const StyleRuleRegion*>(rule)->childRules()))
return true;
break;
+ case StyleRuleBase::Host:
+ if (childRulesHaveFailedOrCanceledSubresources(static_cast<const StyleRuleHost*>(rule)->childRules()))
+ return true;
+ break;
case StyleRuleBase::Import:
ASSERT_NOT_REACHED();
case StyleRuleBase::Page:
@@ -442,6 +446,9 @@ static bool childRulesHaveFailedOrCanceledSubresources(const Vector<RefPtr<Style
case StyleRuleBase::Unknown:
case StyleRuleBase::Charset:
case StyleRuleBase::Keyframe:
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ case StyleRuleBase::Viewport:
+#endif
break;
}
}
diff --git a/Source/WebCore/css/WebKitCSSViewportRule.cpp b/Source/WebCore/css/WebKitCSSViewportRule.cpp
new file mode 100644
index 000000000..c815b56b5
--- /dev/null
+++ b/Source/WebCore/css/WebKitCSSViewportRule.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebKitCSSViewportRule.h"
+
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+
+#include "PropertySetCSSStyleDeclaration.h"
+#include "StylePropertySet.h"
+#include "StyleRule.h"
+#include "WebCoreMemoryInstrumentation.h"
+#include <wtf/text/StringBuilder.h>
+
+namespace WebCore {
+
+WebKitCSSViewportRule::WebKitCSSViewportRule(StyleRuleViewport* viewportRule, CSSStyleSheet* sheet)
+ : CSSRule(sheet, CSSRule::WEBKIT_VIEWPORT_RULE)
+ , m_viewportRule(viewportRule)
+{
+}
+
+WebKitCSSViewportRule::~WebKitCSSViewportRule()
+{
+ if (m_propertiesCSSOMWrapper)
+ m_propertiesCSSOMWrapper->clearParentRule();
+}
+
+CSSStyleDeclaration* WebKitCSSViewportRule::style() const
+{
+ if (!m_propertiesCSSOMWrapper)
+ m_propertiesCSSOMWrapper = StyleRuleCSSStyleDeclaration::create(m_viewportRule->mutableProperties(), const_cast<WebKitCSSViewportRule*>(this));
+
+ return m_propertiesCSSOMWrapper.get();
+}
+
+String WebKitCSSViewportRule::cssText() const
+{
+ StringBuilder result;
+ result.appendLiteral("@-webkit-viewport { ");
+
+ String decls = m_viewportRule->properties()->asText();
+ result.append(decls);
+ if (!decls.isEmpty())
+ result.append(' ');
+
+ result.append('}');
+
+ return result.toString();
+}
+
+void WebKitCSSViewportRule::reattach(StyleRuleViewport* rule)
+{
+ ASSERT(rule);
+ m_viewportRule = rule;
+
+ if (m_propertiesCSSOMWrapper)
+ m_propertiesCSSOMWrapper->reattach(m_viewportRule->mutableProperties());
+}
+
+void WebKitCSSViewportRule::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
+{
+ MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);
+ CSSRule::reportBaseClassMemoryUsage(memoryObjectInfo);
+ info.addMember(m_viewportRule);
+ info.addMember(m_propertiesCSSOMWrapper);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(CSS_DEVICE_ADAPTATION)
diff --git a/Source/WebCore/css/WebKitCSSViewportRule.h b/Source/WebCore/css/WebKitCSSViewportRule.h
new file mode 100644
index 000000000..e8a27d18c
--- /dev/null
+++ b/Source/WebCore/css/WebKitCSSViewportRule.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef WebKitCSSViewportRule_h
+#define WebKitCSSViewportRule_h
+
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+
+#include "CSSRule.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class CSSStyleDeclaration;
+class StyleRuleViewport;
+class StyleRuleCSSStyleDeclaration;
+
+class WebKitCSSViewportRule: public CSSRule {
+public:
+ static PassRefPtr<WebKitCSSViewportRule> create(StyleRuleViewport* viewportRule, CSSStyleSheet* sheet)
+ {
+ return adoptRef(new WebKitCSSViewportRule(viewportRule, sheet));
+ }
+ ~WebKitCSSViewportRule();
+
+ CSSStyleDeclaration* style() const;
+
+ String cssText() const;
+
+ void reattach(StyleRuleViewport*);
+
+ void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
+
+private:
+ WebKitCSSViewportRule(StyleRuleViewport*, CSSStyleSheet*);
+
+ RefPtr<StyleRuleViewport> m_viewportRule;
+
+ mutable RefPtr<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper;
+};
+
+} // namespace WebCore
+
+#endif // WebKitCSSViewportRule_h
+
+#endif // ENABLE(CSS_DEVICE_ADAPTATION)
diff --git a/Source/WebCore/css/html.css b/Source/WebCore/css/html.css
index f07fed67b..6b3f258f7 100644
--- a/Source/WebCore/css/html.css
+++ b/Source/WebCore/css/html.css
@@ -482,7 +482,8 @@ input[type="date"] {
-webkit-align-items: stretch;
display: -webkit-inline-flex;
font-family: monospace;
- padding: 0 0 0 1px;
+ padding: 0;
+ -webkit-padding-start: 1px;
}
#endif
#if defined(ENABLE_INPUT_TYPE_DATETIME) && ENABLE_INPUT_TYPE_DATETIME
@@ -490,7 +491,8 @@ input[type="datetime"] {
-webkit-align-items: stretch;
display: -webkit-inline-flex;
font-family: monospace;
- padding: 0 0 0 1px;
+ padding: 0;
+ -webkit-padding-start: 1px;
}
#endif
#if defined(ENABLE_INPUT_TYPE_DATETIMELOCAL) && ENABLE_INPUT_TYPE_DATETIMELOCAL
@@ -498,7 +500,8 @@ input[type="datetime-local"] {
-webkit-align-items: stretch;
display: -webkit-inline-flex;
font-family: monospace;
- padding: 0 0 0 1px;
+ padding: 0;
+ -webkit-padding-start: 1px;
}
#endif
#if defined(ENABLE_INPUT_TYPE_MONTH) && ENABLE_INPUT_TYPE_MONTH
@@ -506,7 +509,8 @@ input[type="month"] {
-webkit-align-items: stretch;
display: -webkit-inline-flex;
font-family: monospace;
- padding: 0 0 0 1px;
+ padding: 0;
+ -webkit-padding-start: 1px;
}
#endif
#if defined(ENABLE_INPUT_TYPE_TIME) && ENABLE_INPUT_TYPE_TIME
@@ -514,7 +518,8 @@ input[type="time"] {
-webkit-align-items: stretch;
display: -webkit-inline-flex;
font-family: monospace;
- padding: 0 0 0 1px;
+ padding: 0;
+ -webkit-padding-start: 1px;
}
#endif
#if defined(ENABLE_INPUT_TYPE_WEEK) && ENABLE_INPUT_TYPE_WEEK
@@ -522,64 +527,47 @@ input[type="week"] {
-webkit-align-items: stretch;
display: -webkit-inline-flex;
font-family: monospace;
- padding: 0 0 0 1px;
+ padding: 0;
+ -webkit-padding-start: 1px;
}
#endif
input::-webkit-datetime-edit {
- -webkit-align-items: center;
-webkit-flex: 1;
-webkit-user-modify: read-only !important;
- display: -webkit-flex;
- white-space: pre;
-}
-
-input::-webkit-datetime-edit-ampm-field {
- -webkit-user-modify: read-only !important;
- border: none;
- padding: 0.15em;
- display: inline-block;
- text-align: center;
-}
-
-input::-webkit-datetime-edit-day-field {
- -webkit-user-modify: read-only !important;
display: inline-block;
- border: none;
- text-align: center;
- padding: 0.15em;
-}
-
-input::-webkit-datetime-edit-hour-field {
- -webkit-user-modify: read-only !important;
- display: inline-block;
- border: none;
- text-align: center;
- padding: 0.15em;
+ white-space: pre;
}
-input::-webkit-datetime-edit-millisecond-field {
+input::-webkit-datetime-edit-ampm-field,
+input::-webkit-datetime-edit-day-field,
+input::-webkit-datetime-edit-hour-field,
+input::-webkit-datetime-edit-millisecond-field,
+input::-webkit-datetime-edit-minute-field,
+input::-webkit-datetime-edit-month-field,
+input::-webkit-datetime-edit-second-field,
+input::-webkit-datetime-edit-week-field,
+input::-webkit-datetime-edit-year-field {
-webkit-user-modify: read-only !important;
- display: inline-block;
border: none;
- text-align: center;
- padding: 0.15em;
-}
-
-input::-webkit-datetime-edit-minute-field {
- -webkit-user-modify: read-only !important;
display: inline-block;
- border: none;
+ margin: 1px;
text-align: center;
- padding: 0.15em;
}
-input::-webkit-datetime-edit-month-field {
- -webkit-user-modify: read-only !important;
- display: inline-block;
- border: none;
- text-align: center;
- padding: 0.15em;
+/* Remove focus ring from fields and use highlight color */
+input::-webkit-datetime-edit-ampm-field:focus,
+input::-webkit-datetime-edit-day-field:focus,
+input::-webkit-datetime-edit-hour-field:focus,
+input::-webkit-datetime-edit-millisecond-field:focus,
+input::-webkit-datetime-edit-minute-field:focus,
+input::-webkit-datetime-edit-month-field:focus,
+input::-webkit-datetime-edit-second-field:focus,
+input::-webkit-datetime-edit-week-field:focus,
+input::-webkit-datetime-edit-year-field:focus {
+ background-color: highlight;
+ color: highlighttext;
+ outline: none;
}
/* This selector is used when step >= 3600 second but format contains minute field. */
@@ -587,28 +575,9 @@ input::-webkit-datetime-edit-minute-field[readonly] {
color: GrayText;
}
-input::-webkit-datetime-edit-second-field {
- -webkit-user-modify: read-only !important;
- display: inline-block;
- border: none;
- text-align: center;
- padding: 0.15em;
-}
-
-input::-webkit-datetime-edit-week-field {
- -webkit-user-modify: read-only !important;
- display: inline-block;
- border: none;
- text-align: center;
- padding: 0.15em;
-}
-
-input::-webkit-datetime-edit-year-field {
- -webkit-user-modify: read-only !important;
- display: inline-block;
- border: none;
- text-align: center;
- padding: 0.15em;
+/* This selector is used when step >= 60 second but format contains second field. */
+input::-webkit-datetime-edit-second-field[readonly] {
+ color: GrayText;
}
input::-webkit-datetime-edit-text {
@@ -616,36 +585,10 @@ input::-webkit-datetime-edit-text {
display: inline-block;
}
-input::-webkit-datetime-edit-gap {
- -webkit-flex: 1;
- -webkit-user-modify: read-only !important;
- display: inline-block;
-}
-
input::-webkit-date-and-time-container {
-webkit-align-items: center;
-webkit-flex: 1;
- display: -webkit-flex;
-}
-
-/* Remove focus ring from fields and use highlight color */
-input::-webkit-datetime-edit-ampm-field:focus,
-input::-webkit-datetime-edit-day-field:focus,
-input::-webkit-datetime-edit-hour-field:focus,
-input::-webkit-datetime-edit-millisecond-field:focus,
-input::-webkit-datetime-edit-minute-field:focus,
-input::-webkit-datetime-edit-month-field:focus,
-input::-webkit-datetime-edit-second-field:focus,
-input::-webkit-datetime-edit-week-field:focus,
-input::-webkit-datetime-edit-year-field:focus {
- background-color: highlight;
- color: highlighttext;
- outline: none;
-}
-
-/* This selector is used when step >= 60 second but format contains second field. */
-input::-webkit-datetime-edit-second-field[readonly] {
- color: GrayText;
+ display: -webkit-inline-flex;
}
input[type="date"]::-webkit-inner-spin-button,
@@ -655,8 +598,8 @@ input[type="month"]::-webkit-inner-spin-button,
input[type="time"]::-webkit-inner-spin-button,
input[type="week"]::-webkit-inner-spin-button {
display: inline-block;
- margin-left: 0.2em;
position: static;
+ -webkit-margin-start: 2px;
}
#endif
diff --git a/Source/WebCore/css/mathml.css b/Source/WebCore/css/mathml.css
index 205f07688..7c3118ef0 100644
--- a/Source/WebCore/css/mathml.css
+++ b/Source/WebCore/css/mathml.css
@@ -8,8 +8,16 @@ mtext {
line-height: 1.0;
}
+/* Keep font-family and other defaults here consistent with http://mxr.mozilla.org/mozilla-central/source/layout/mathml/mathml.css and feedback from www-math. */
+math, mfenced > * {
+ font-family: MathJax_Main, STIXGeneral, "DejaVu Serif", Cambria, "Cambria Math", Times, serif;
+}
+mo, mfenced {
+ font-family: MathJax_Main, STIXGeneral, STIXSizeOneSym, "DejaVu Sans", "DejaVu Serif", Cambria, "Cambria Math",
+ "Lucida Sans Unicode", "Arial Unicode MS", "Lucida Grande", OpenSymbol, "Standard Symbols L", sans-serif;
+}
+
math {
- font-family: STIXGeneral, Symbol, "Times New Roman", sans-serif;
display: -webkit-inline-flex !important;
padding-left: 1px;
padding-right: 1px;
diff --git a/Source/WebCore/css/mediaControls.css b/Source/WebCore/css/mediaControls.css
index 81b0e16b9..6df03402d 100644
--- a/Source/WebCore/css/mediaControls.css
+++ b/Source/WebCore/css/mediaControls.css
@@ -216,7 +216,7 @@ video::-webkit-media-text-track-container {
font-size: 22px;
font-family: sans-serif;
text-align: center;
- color: rgba(255, 255, 255, 0);
+ color: rgba(255, 255, 255, 1);
letter-spacing: normal;
word-spacing: normal;
@@ -234,8 +234,6 @@ video::-webkit-media-text-track-past-nodes {
background-color: rgba(0, 0, 0, 0.8);
padding: 2px 2px;
-
- white-space: pre-wrap;
}
video::-webkit-media-text-track-future-nodes {
@@ -246,11 +244,10 @@ video::-webkit-media-text-track-future-nodes {
margin-left: -2px;
padding: 2px 2px 2px 0px;
-
- white-space: pre-wrap;
}
video::-webkit-media-text-track-display {
position: absolute;
- color: rgba(255, 255, 255, 1);
+ overflow: hidden;
+ white-space: pre-wrap;
}
diff --git a/Source/WebCore/css/themeBlackBerry.css b/Source/WebCore/css/themeBlackBerry.css
index 120ce4981..c4d8f73bb 100644
--- a/Source/WebCore/css/themeBlackBerry.css
+++ b/Source/WebCore/css/themeBlackBerry.css
@@ -20,10 +20,6 @@ textarea {
font-family: monospace;
}
-input, textarea {
- border-radius: 3px;
-}
-
input[type="datetime"],
input[type="date"],
input[type="week"],
@@ -35,22 +31,35 @@ input[type="color"] {
border: solid 2px blue;
}
-select:focus {
- border: 1px solid black;
- outline: none;
+select {
+ border-radius: 0;
+}
+
+select[size="0"],
+select[size="1"] {
+ border-radius: 0;
+}
+
+::-webkit-validation-bubble-message {
+ padding-left: 10px;
+ padding-right: 10px;
+ background: #fafafa;
+ border-color: #ffffff;
+ border-width: 1px;
+ box-shadow: 2px 2px 4px rgba(100,100,100,0.3), 0 0 4px rgba(100,100,100,0.6);
+ -webkit-border-radius: 4px;
+ top: -1px;
}
-select[size],
-select[multiple],
-select[size][multiple] {
- padding: 5px;
- border-radius: 5px;
- border: 1px solid rgb(139,139,139);
+::-webkit-validation-bubble-arrow {
+ left: 40px;
+ top: 3px;
+ background: #fafafa;
+ border-color: #ffffff;
+ border-width: 1px;
+ box-shadow: 0 0 4px rgba(100,100,100,0.6);
}
-select[size]:focus,
-select[multiple]:focus,
-select[size][multiple]:focus {
- border: 1px solid black;
- outline: none;
+::-webkit-validation-bubble-heading {
+ font-weight: normal;
}