diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2012-10-15 16:08:57 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-10-15 16:08:57 +0200 |
commit | 5466563f4b5b6b86523e3f89bb7f77e5b5270c78 (patch) | |
tree | 8caccf7cd03a15207cde3ba282c88bf132482a91 /Source/WebCore/css | |
parent | 33b26980cb24288b5a9f2590ccf32a949281bb79 (diff) | |
download | qtwebkit-5466563f4b5b6b86523e3f89bb7f77e5b5270c78.tar.gz |
Imported WebKit commit 0dc6cd75e1d4836eaffbb520be96fac4847cc9d2 (http://svn.webkit.org/repository/webkit/trunk@131300)
WebKit update which introduces the QtWebKitWidgets module that contains the WK1
widgets based API. (In fact it renames QtWebKit to QtWebKitWidgets while we're
working on completing the entire split as part of
https://bugs.webkit.org/show_bug.cgi?id=99314
Diffstat (limited to 'Source/WebCore/css')
90 files changed, 2552 insertions, 1887 deletions
diff --git a/Source/WebCore/css/CSSAllInOne.cpp b/Source/WebCore/css/CSSAllInOne.cpp index 193b7afc4..84f9fe7f4 100644 --- a/Source/WebCore/css/CSSAllInOne.cpp +++ b/Source/WebCore/css/CSSAllInOne.cpp @@ -66,7 +66,10 @@ #include "CSSValue.cpp" #include "CSSValueList.cpp" #include "CSSValuePool.cpp" +#include "RuleFeature.cpp" +#include "RuleSet.cpp" #include "StyleBuilder.cpp" #include "StylePropertySet.cpp" #include "StylePropertyShorthand.cpp" #include "StyleResolver.cpp" +#include "StyleScopeResolver.cpp" diff --git a/Source/WebCore/css/CSSBasicShapes.cpp b/Source/WebCore/css/CSSBasicShapes.cpp index 37335ffca..3fda6b1d1 100644 --- a/Source/WebCore/css/CSSBasicShapes.cpp +++ b/Source/WebCore/css/CSSBasicShapes.cpp @@ -39,20 +39,24 @@ namespace WebCore { static String buildRectangleString(const String& x, const String& y, const String& width, const String& height, const String& radiusX, const String& radiusY) { + char opening[] = "rectangle("; + char separator[] = ", "; StringBuilder result; - result.appendLiteral("rectangle("); + // Compute the required capacity in advance to reduce allocations. + result.reserveCapacity((sizeof(opening) - 1) + (5 * (sizeof(separator) -1 )) + 1 + x.length() + y.length() + width.length() + height.length() + radiusX.length() + radiusY.length()); + result.appendLiteral(opening); result.append(x); - result.appendLiteral(", "); + result.appendLiteral(separator); result.append(y); - result.appendLiteral(", "); + result.appendLiteral(separator); result.append(width); - result.appendLiteral(", "); + result.appendLiteral(separator); result.append(height); if (!radiusX.isNull()) { - result.appendLiteral(", "); + result.appendLiteral(separator); result.append(radiusX); if (!radiusY.isNull()) { - result.appendLiteral(", "); + result.appendLiteral(separator); result.append(radiusY); } } @@ -63,22 +67,22 @@ static String buildRectangleString(const String& x, const String& y, const Strin String CSSBasicShapeRectangle::cssText() const { return buildRectangleString(m_x->cssText(), - m_y->cssText(), - m_width->cssText(), - m_height->cssText(), - m_radiusX.get() ? m_radiusX->cssText() : String(), - m_radiusY.get() ? m_radiusY->cssText() : String()); + m_y->cssText(), + m_width->cssText(), + m_height->cssText(), + m_radiusX.get() ? m_radiusX->cssText() : String(), + m_radiusY.get() ? m_radiusY->cssText() : String()); } #if ENABLE(CSS_VARIABLES) String CSSBasicShapeRectangle::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const { return buildRectangleString(m_x->serializeResolvingVariables(variables), - m_y->serializeResolvingVariables(variables), - m_width->serializeResolvingVariables(variables), - m_height->serializeResolvingVariables(variables), - m_radiusX.get() ? m_radiusX->serializeResolvingVariables(variables) : String(), - m_radiusY.get() ? m_radiusY->serializeResolvingVariables(variables) : String()); + m_y->serializeResolvingVariables(variables), + m_width->serializeResolvingVariables(variables), + m_height->serializeResolvingVariables(variables), + m_radiusX.get() ? m_radiusX->serializeResolvingVariables(variables) : String(), + m_radiusY.get() ? m_radiusY->serializeResolvingVariables(variables) : String()); } bool CSSBasicShapeRectangle::hasVariableReference() const @@ -106,8 +110,8 @@ String CSSBasicShapeCircle::cssText() const String CSSBasicShapeCircle::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const { return buildCircleString(m_centerX->serializeResolvingVariables(variables), - m_centerY->serializeResolvingVariables(variables), - m_radius->serializeResolvingVariables(variables)); + m_centerY->serializeResolvingVariables(variables), + m_radius->serializeResolvingVariables(variables)); } bool CSSBasicShapeCircle::hasVariableReference() const @@ -132,9 +136,9 @@ String CSSBasicShapeEllipse::cssText() const String CSSBasicShapeEllipse::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const { return buildEllipseString(m_centerX->serializeResolvingVariables(variables), - m_centerY->serializeResolvingVariables(variables), - m_radiusX->serializeResolvingVariables(variables), - m_radiusY->serializeResolvingVariables(variables)); + m_centerY->serializeResolvingVariables(variables), + m_radiusX->serializeResolvingVariables(variables), + m_radiusY->serializeResolvingVariables(variables)); } bool CSSBasicShapeEllipse::hasVariableReference() const @@ -148,18 +152,32 @@ bool CSSBasicShapeEllipse::hasVariableReference() const static String buildPolygonString(const WindRule& windRule, const Vector<String>& points) { + ASSERT(!(points.size() % 2)); + StringBuilder result; + char evenOddOpening[] = "polygon(evenodd, "; + char nonZeroOpening[] = "polygon(nonzero, "; + char commaSeparator[] = ", "; + COMPILE_ASSERT(sizeof(evenOddOpening) == sizeof(nonZeroOpening), polygon_string_openings_have_same_length); + + // Compute the required capacity in advance to reduce allocations. + size_t length = sizeof(evenOddOpening) - 1; + for (size_t i = 0; i < points.size(); i += 2) { + if (i) + length += (sizeof(commaSeparator) - 1); + // add length of two strings, plus one for the space separator. + length += points[i].length() + 1 + points[i + 1].length(); + } + result.reserveCapacity(length); if (windRule == RULE_EVENODD) - result.appendLiteral("polygon(evenodd, "); + result.appendLiteral(evenOddOpening); else - result.appendLiteral("polygon(nonzero, "); - - ASSERT(!(points.size() % 2)); + result.appendLiteral(nonZeroOpening); for (size_t i = 0; i < points.size(); i += 2) { if (i) - result.appendLiteral(", "); + result.appendLiteral(commaSeparator); result.append(points[i]); result.append(' '); result.append(points[i + 1]); diff --git a/Source/WebCore/css/CSSCanvasValue.cpp b/Source/WebCore/css/CSSCanvasValue.cpp index 787a1742c..3aea17c44 100644 --- a/Source/WebCore/css/CSSCanvasValue.cpp +++ b/Source/WebCore/css/CSSCanvasValue.cpp @@ -53,14 +53,14 @@ void CSSCanvasValue::canvasChanged(HTMLCanvasElement*, const FloatRect& changedR IntRect imageChangeRect = enclosingIntRect(changedRect); RenderObjectSizeCountMap::const_iterator end = clients().end(); for (RenderObjectSizeCountMap::const_iterator curr = clients().begin(); curr != end; ++curr) - const_cast<RenderObject*>(curr->first)->imageChanged(static_cast<WrappedImagePtr>(this), &imageChangeRect); + const_cast<RenderObject*>(curr->key)->imageChanged(static_cast<WrappedImagePtr>(this), &imageChangeRect); } void CSSCanvasValue::canvasResized(HTMLCanvasElement*) { RenderObjectSizeCountMap::const_iterator end = clients().end(); for (RenderObjectSizeCountMap::const_iterator curr = clients().begin(); curr != end; ++curr) - const_cast<RenderObject*>(curr->first)->imageChanged(static_cast<WrappedImagePtr>(this)); + const_cast<RenderObject*>(curr->key)->imageChanged(static_cast<WrappedImagePtr>(this)); } void CSSCanvasValue::canvasDestroyed(HTMLCanvasElement* element) diff --git a/Source/WebCore/css/CSSCharsetRule.idl b/Source/WebCore/css/CSSCharsetRule.idl index 3cdaf4a78..d2386de94 100644 --- a/Source/WebCore/css/CSSCharsetRule.idl +++ b/Source/WebCore/css/CSSCharsetRule.idl @@ -18,16 +18,13 @@ * Boston, MA 02110-1301, USA. */ -module css { - - // Introduced in DOM Level 2: - interface CSSCharsetRule : CSSRule { +// Introduced in DOM Level 2: +interface CSSCharsetRule : CSSRule { #if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C - readonly attribute [TreatReturnedNullStringAs=Null] DOMString encoding; + [TreatReturnedNullStringAs=Null] readonly attribute DOMString encoding; #else - attribute [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] DOMString encoding - setter raises(DOMException); + [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] attribute DOMString encoding + setter raises(DOMException); #endif - }; +}; -} diff --git a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp index d10d738a3..aab8acb98 100644 --- a/Source/WebCore/css/CSSComputedStyleDeclaration.cpp +++ b/Source/WebCore/css/CSSComputedStyleDeclaration.cpp @@ -49,6 +49,7 @@ #include "FontFeatureSettings.h" #include "FontFeatureValue.h" #include "FontValue.h" +#include "HTMLFrameOwnerElement.h" #include "Pair.h" #include "Rect.h" #include "RenderBox.h" @@ -58,6 +59,7 @@ #include "StyleInheritedData.h" #include "StylePropertySet.h" #include "StylePropertyShorthand.h" +#include "StyleResolver.h" #include "WebCoreMemoryInstrumentation.h" #include "WebKitCSSTransformValue.h" #include "WebKitFontFamilyNames.h" @@ -78,7 +80,7 @@ #include "WebKitCSSFilterValue.h" #endif -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) #include "DashboardRegion.h" #endif @@ -350,7 +352,7 @@ static const CSSPropertyID computedProperties[] = { CSSPropertyWebkitRegionBreakInside, #endif #if ENABLE(WIDGET_REGION) - CSSPropertyWebkitWidgetRegion, + CSSPropertyWebkitAppRegion, #endif #if ENABLE(CSS_EXCLUSIONS) CSSPropertyWebkitWrapFlow, @@ -1300,8 +1302,8 @@ static PassRefPtr<CSSValue> counterToCSSValue(const RenderStyle* style, CSSPrope RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); for (CounterDirectiveMap::const_iterator it = map->begin(); it != map->end(); ++it) { - list->append(cssValuePool().createValue(it->first, CSSPrimitiveValue::CSS_STRING)); - short number = propertyID == CSSPropertyCounterIncrement ? it->second.incrementValue() : it->second.resetValue(); + list->append(cssValuePool().createValue(it->key, CSSPrimitiveValue::CSS_STRING)); + short number = propertyID == CSSPropertyCounterIncrement ? it->value.incrementValue() : it->value.resetValue(); list->append(cssValuePool().createValue((double)number, CSSPrimitiveValue::CSS_NUMBER)); } return list.release(); @@ -1384,15 +1386,57 @@ static PassRefPtr<CSSPrimitiveValue> fontWeightFromStyle(RenderStyle* style) return cssValuePool().createIdentifierValue(CSSValueNormal); } +static bool isLayoutDependentProperty(CSSPropertyID propertyID) +{ + switch (propertyID) { + case CSSPropertyWidth: + case CSSPropertyHeight: + case CSSPropertyMargin: + case CSSPropertyMarginTop: + case CSSPropertyMarginBottom: + case CSSPropertyMarginLeft: + case CSSPropertyMarginRight: + case CSSPropertyPadding: + case CSSPropertyPaddingTop: + case CSSPropertyPaddingBottom: + case CSSPropertyPaddingLeft: + case CSSPropertyPaddingRight: + case CSSPropertyWebkitPerspectiveOrigin: + case CSSPropertyWebkitTransformOrigin: + case CSSPropertyWebkitTransform: +#if ENABLE(CSS_FILTERS) + case CSSPropertyWebkitFilter: +#endif + return true; + default: + return false; + } +} + PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const { Node* node = m_node.get(); if (!node) return 0; - // Make sure our layout is up to date before we allow a query on these attributes. - if (updateLayout) - node->document()->updateLayoutIgnorePendingStylesheets(); + if (updateLayout) { + Document* document = m_node->document(); + // FIXME: Some of these cases could be narrowed down or optimized better. + bool forceFullLayout = isLayoutDependentProperty(propertyID) + || node->isInShadowTree() + || (document->styleResolverIfExists() && document->styleResolverIfExists()->hasViewportDependentMediaQueries() && document->ownerElement()) + || document->seamlessParentIFrame(); + + if (forceFullLayout) + document->updateLayoutIgnorePendingStylesheets(); + else { + bool needsStyleRecalc = document->hasPendingForcedStyleRecalc(); + for (Node* n = m_node.get(); n && !needsStyleRecalc; n = n->parentNode()) + needsStyleRecalc = n->needsStyleRecalc(); + if (needsStyleRecalc) + document->updateStyleIfNeeded(); + } + } RenderObject* renderer = node->renderer(); @@ -2125,13 +2169,8 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert if (style->boxSizing() == CONTENT_BOX) return cssValuePool().createIdentifierValue(CSSValueContentBox); return cssValuePool().createIdentifierValue(CSSValueBorderBox); -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) #if ENABLE(DASHBOARD_SUPPORT) case CSSPropertyWebkitDashboardRegion: -#endif -#if ENABLE(WIDGET_REGION) - case CSSPropertyWebkitWidgetRegion: -#endif { const Vector<StyleDashboardRegion>& regions = style->dashboardRegions(); unsigned count = regions.size(); @@ -2162,6 +2201,10 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert return cssValuePool().createValue(firstRegion.release()); } #endif +#if ENABLE(WIDGET_REGION) + case CSSPropertyWebkitAppRegion: + return cssValuePool().createIdentifierValue(style->getDraggableRegionMode() == DraggableRegionDrag ? CSSValueDrag : CSSValueNoDrag); +#endif case CSSPropertyWebkitAnimationDelay: return getDelayValue(style->animations()); case CSSPropertyWebkitAnimationDirection: { @@ -2300,7 +2343,10 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert case CSSPropertyWebkitPerspectiveOrigin: { RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated(); if (renderer) { - LayoutRect box = sizingBox(renderer); + LayoutRect box; + if (renderer->isBox()) + box = toRenderBox(renderer)->borderBoxRect(); + RenderView* renderView = m_node->document()->renderView(); list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginX(), box.width(), renderView), style.get())); list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginY(), box.height(), renderView), style.get())); @@ -2421,6 +2467,12 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert if (ClipPathOperation* operation = style->clipPath()) { if (operation->getOperationType() == ClipPathOperation::SHAPE) return valueForBasicShape(static_cast<ShapeClipPathOperation*>(operation)->basicShape()); +#if ENABLE(SVG) + else if (operation->getOperationType() == ClipPathOperation::REFERENCE) { + ReferenceClipPathOperation* referenceOperation = static_cast<ReferenceClipPathOperation*>(operation); + return CSSPrimitiveValue::create(referenceOperation->url(), CSSPrimitiveValue::CSS_URI); + } +#endif } return cssValuePool().createIdentifierValue(CSSValueNone); #if ENABLE(CSS_REGIONS) @@ -2443,13 +2495,13 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert case CSSPropertyWebkitWrapPadding: return cssValuePool().createValue(style->wrapPadding()); case CSSPropertyWebkitShapeInside: - if (!style->wrapShapeInside()) + if (!style->shapeInside()) return cssValuePool().createIdentifierValue(CSSValueAuto); - return valueForBasicShape(style->wrapShapeInside()); + return valueForBasicShape(style->shapeInside()); case CSSPropertyWebkitShapeOutside: - if (!style->wrapShapeOutside()) + if (!style->shapeOutside()) return cssValuePool().createIdentifierValue(CSSValueAuto); - return valueForBasicShape(style->wrapShapeOutside()); + return valueForBasicShape(style->shapeOutside()); case CSSPropertyWebkitWrapThrough: return cssValuePool().createValue(style->wrapThrough()); #endif diff --git a/Source/WebCore/css/CSSCrossfadeValue.cpp b/Source/WebCore/css/CSSCrossfadeValue.cpp index a224a3611..126734ffc 100644 --- a/Source/WebCore/css/CSSCrossfadeValue.cpp +++ b/Source/WebCore/css/CSSCrossfadeValue.cpp @@ -179,7 +179,7 @@ void CSSCrossfadeValue::crossfadeChanged(const IntRect&) { RenderObjectSizeCountMap::const_iterator end = clients().end(); for (RenderObjectSizeCountMap::const_iterator curr = clients().begin(); curr != end; ++curr) { - RenderObject* client = const_cast<RenderObject*>(curr->first); + RenderObject* client = const_cast<RenderObject*>(curr->key); client->imageChanged(static_cast<WrappedImagePtr>(this)); } } diff --git a/Source/WebCore/css/CSSCursorImageValue.cpp b/Source/WebCore/css/CSSCursorImageValue.cpp index 68ffa9c11..06d93ea60 100644 --- a/Source/WebCore/css/CSSCursorImageValue.cpp +++ b/Source/WebCore/css/CSSCursorImageValue.cpp @@ -26,6 +26,7 @@ #include "TreeScope.h" #include "WebCoreMemoryInstrumentation.h" #include <wtf/MathExtras.h> +#include <wtf/MemoryInstrumentationHashSet.h> #include <wtf/UnusedParam.h> #include <wtf/text/WTFString.h> @@ -138,7 +139,7 @@ void CSSCursorImageValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryOb MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS); CSSImageValue::reportDescendantMemoryUsage(memoryObjectInfo); #if ENABLE(SVG) - info.addInstrumentedHashSet(m_referencedElements); + info.addMember(m_referencedElements); #endif } diff --git a/Source/WebCore/css/CSSFontFace.cpp b/Source/WebCore/css/CSSFontFace.cpp index 67a7f7038..277fbd928 100644 --- a/Source/WebCore/css/CSSFontFace.cpp +++ b/Source/WebCore/css/CSSFontFace.cpp @@ -91,7 +91,7 @@ void CSSFontFace::fontLoaded(CSSFontFaceSource* source) fontSelector->fontLoaded(); } -SimpleFontData* CSSFontFace::getFontData(const FontDescription& fontDescription, bool syntheticBold, bool syntheticItalic) +PassRefPtr<SimpleFontData> CSSFontFace::getFontData(const FontDescription& fontDescription, bool syntheticBold, bool syntheticItalic) { m_activeSource = 0; if (!isValid()) @@ -102,9 +102,9 @@ SimpleFontData* CSSFontFace::getFontData(const FontDescription& fontDescription, size_t size = m_sources.size(); for (size_t i = 0; i < size; ++i) { - if (SimpleFontData* result = m_sources[i]->getFontData(fontDescription, syntheticBold, syntheticItalic, fontSelector)) { + if (RefPtr<SimpleFontData> result = m_sources[i]->getFontData(fontDescription, syntheticBold, syntheticItalic, fontSelector)) { m_activeSource = m_sources[i].get(); - return result; + return result.release(); } } diff --git a/Source/WebCore/css/CSSFontFace.h b/Source/WebCore/css/CSSFontFace.h index 7fbbf0a5f..e3f648107 100644 --- a/Source/WebCore/css/CSSFontFace.h +++ b/Source/WebCore/css/CSSFontFace.h @@ -64,7 +64,7 @@ public: void fontLoaded(CSSFontFaceSource*); - SimpleFontData* getFontData(const FontDescription&, bool syntheticBold, bool syntheticItalic); + PassRefPtr<SimpleFontData> getFontData(const FontDescription&, bool syntheticBold, bool syntheticItalic); struct UnicodeRange { UnicodeRange(UChar32 from, UChar32 to) diff --git a/Source/WebCore/css/CSSFontFaceRule.idl b/Source/WebCore/css/CSSFontFaceRule.idl index bd38a6137..f13497c43 100644 --- a/Source/WebCore/css/CSSFontFaceRule.idl +++ b/Source/WebCore/css/CSSFontFaceRule.idl @@ -18,11 +18,8 @@ * Boston, MA 02110-1301, USA. */ -module css { +// Introduced in DOM Level 2: +interface CSSFontFaceRule : CSSRule { + readonly attribute CSSStyleDeclaration style; +}; - // Introduced in DOM Level 2: - interface CSSFontFaceRule : CSSRule { - readonly attribute CSSStyleDeclaration style; - }; - -} diff --git a/Source/WebCore/css/CSSFontFaceSource.cpp b/Source/WebCore/css/CSSFontFaceSource.cpp index dd904d37f..5e5289f6d 100644 --- a/Source/WebCore/css/CSSFontFaceSource.cpp +++ b/Source/WebCore/css/CSSFontFaceSource.cpp @@ -33,7 +33,6 @@ #include "Document.h" #include "FontCache.h" #include "FontDescription.h" -#include "GlyphPageTreeNode.h" #include "SimpleFontData.h" #if ENABLE(SVG_FONTS) @@ -95,7 +94,7 @@ void CSSFontFaceSource::fontLoaded(CachedFont*) m_face->fontLoaded(this); } -SimpleFontData* CSSFontFaceSource::getFontData(const FontDescription& fontDescription, bool syntheticBold, bool syntheticItalic, CSSFontSelector* fontSelector) +PassRefPtr<SimpleFontData> CSSFontFaceSource::getFontData(const FontDescription& fontDescription, bool syntheticBold, bool syntheticItalic, CSSFontSelector* fontSelector) { // If the font hasn't loaded or an error occurred, then we've got nothing. if (!isValid()) @@ -114,11 +113,9 @@ SimpleFontData* CSSFontFaceSource::getFontData(const FontDescription& fontDescri unsigned hashKey = (fontDescription.computedPixelSize() + 1) << 6 | fontDescription.widthVariant() << 4 | (fontDescription.textOrientation() == TextOrientationUpright ? 8 : 0) | (fontDescription.orientation() == Vertical ? 4 : 0) | (syntheticBold ? 2 : 0) | (syntheticItalic ? 1 : 0); - SimpleFontData*& cachedData = m_fontDataTable.add(hashKey, 0).iterator->second; - if (cachedData) - return cachedData; - - OwnPtr<SimpleFontData> fontData; + RefPtr<SimpleFontData>& fontData = m_fontDataTable.add(hashKey, 0).iterator->value; + if (fontData) + return fontData; // No release, because fontData is a reference to a RefPtr that is held in the m_fontDataTable. // If we are still loading, then we let the system pick a font. if (isLoaded()) { @@ -157,7 +154,7 @@ SimpleFontData* CSSFontFaceSource::getFontData(const FontDescription& fontDescri m_svgFontFaceElement = fontFaceElement; } - fontData = adoptPtr(new SimpleFontData(SVGFontData::create(fontFaceElement), fontDescription.computedPixelSize(), syntheticBold, syntheticItalic)); + fontData = SimpleFontData::create(SVGFontData::create(fontFaceElement), fontDescription.computedPixelSize(), syntheticBold, syntheticItalic); } } else #endif @@ -166,14 +163,14 @@ SimpleFontData* CSSFontFaceSource::getFontData(const FontDescription& fontDescri if (!m_font->ensureCustomFontData()) return 0; - fontData = adoptPtr(new SimpleFontData(m_font->platformDataFromCustomData(fontDescription.computedPixelSize(), syntheticBold, syntheticItalic, fontDescription.orientation(), - fontDescription.textOrientation(), fontDescription.widthVariant(), fontDescription.renderingMode()), true, false)); + fontData = SimpleFontData::create(m_font->platformDataFromCustomData(fontDescription.computedPixelSize(), syntheticBold, syntheticItalic, + fontDescription.orientation(), fontDescription.textOrientation(), fontDescription.widthVariant(), fontDescription.renderingMode()), true, false); } } else { #if ENABLE(SVG_FONTS) // In-Document SVG Fonts if (m_svgFontFaceElement) - fontData = adoptPtr(new SimpleFontData(SVGFontData::create(m_svgFontFaceElement.get()), fontDescription.computedPixelSize(), syntheticBold, syntheticItalic)); + fontData = SimpleFontData::create(SVGFontData::create(m_svgFontFaceElement.get()), fontDescription.computedPixelSize(), syntheticBold, syntheticItalic); #endif } } else { @@ -184,15 +181,10 @@ SimpleFontData* CSSFontFaceSource::getFontData(const FontDescription& fontDescri // This temporary font is not retained and should not be returned. FontCachePurgePreventer fontCachePurgePreventer; SimpleFontData* temporaryFont = fontCache()->getNonRetainedLastResortFallbackFont(fontDescription); - fontData = adoptPtr(new SimpleFontData(temporaryFont->platformData(), true, true)); - } - - if (Document* document = fontSelector->document()) { - cachedData = fontData.get(); - document->registerCustomFont(fontData.release()); + fontData = SimpleFontData::create(temporaryFont->platformData(), true, true); } - return cachedData; + return fontData; // No release, because fontData is a reference to a RefPtr that is held in the m_fontDataTable. } #if ENABLE(SVG_FONTS) diff --git a/Source/WebCore/css/CSSFontFaceSource.h b/Source/WebCore/css/CSSFontFaceSource.h index e36fe4542..0488d10d3 100644 --- a/Source/WebCore/css/CSSFontFaceSource.h +++ b/Source/WebCore/css/CSSFontFaceSource.h @@ -59,7 +59,7 @@ public: virtual void fontLoaded(CachedFont*); - SimpleFontData* getFontData(const FontDescription&, bool syntheticBold, bool syntheticItalic, CSSFontSelector*); + PassRefPtr<SimpleFontData> getFontData(const FontDescription&, bool syntheticBold, bool syntheticItalic, CSSFontSelector*); void pruneTable(); @@ -76,7 +76,7 @@ private: AtomicString m_string; // URI for remote, built-in font name for local. CachedResourceHandle<CachedFont> m_font; // For remote fonts, a pointer to our cached resource. CSSFontFace* m_face; // Our owning font face. - HashMap<unsigned, SimpleFontData*> m_fontDataTable; // The hash key is composed of size synthetic styles. + HashMap<unsigned, RefPtr<SimpleFontData> > m_fontDataTable; // The hash key is composed of size synthetic styles. #if ENABLE(SVG_FONTS) RefPtr<SVGFontFaceElement> m_svgFontFaceElement; diff --git a/Source/WebCore/css/CSSFontSelector.cpp b/Source/WebCore/css/CSSFontSelector.cpp index cc5ffa06c..64ee0a8d7 100644 --- a/Source/WebCore/css/CSSFontSelector.cpp +++ b/Source/WebCore/css/CSSFontSelector.cpp @@ -285,7 +285,7 @@ void CSSFontSelector::addFontFaceRule(const StyleRuleFontFace* fontFaceRule) if (familyName.isEmpty()) continue; - OwnPtr<Vector<RefPtr<CSSFontFace> > >& familyFontFaces = m_fontFaces.add(familyName, nullptr).iterator->second; + OwnPtr<Vector<RefPtr<CSSFontFace> > >& familyFontFaces = m_fontFaces.add(familyName, nullptr).iterator->value; if (!familyFontFaces) { familyFontFaces = adoptPtr(new Vector<RefPtr<CSSFontFace> >); @@ -350,7 +350,7 @@ void CSSFontSelector::fontCacheInvalidated() dispatchInvalidationCallbacks(); } -static FontData* fontDataForGenericFamily(Document* document, const FontDescription& fontDescription, const AtomicString& familyName) +static PassRefPtr<FontData> fontDataForGenericFamily(Document* document, const FontDescription& fontDescription, const AtomicString& familyName) { if (!document || !document->frame()) return 0; @@ -465,7 +465,7 @@ static inline bool compareFontFaces(CSSFontFace* first, CSSFontFace* second) return false; } -FontData* CSSFontSelector::getFontData(const FontDescription& fontDescription, const AtomicString& familyName) +PassRefPtr<FontData> CSSFontSelector::getFontData(const FontDescription& fontDescription, const AtomicString& familyName) { if (m_fontFaces.isEmpty()) { if (familyName.startsWith("-webkit-")) @@ -487,13 +487,13 @@ FontData* CSSFontSelector::getFontData(const FontDescription& fontDescription, c return fontDataForGenericFamily(m_document, fontDescription, familyName); } - OwnPtr<HashMap<unsigned, RefPtr<CSSSegmentedFontFace> > >& segmentedFontFaceCache = m_fonts.add(family, nullptr).iterator->second; + OwnPtr<HashMap<unsigned, RefPtr<CSSSegmentedFontFace> > >& segmentedFontFaceCache = m_fonts.add(family, nullptr).iterator->value; if (!segmentedFontFaceCache) segmentedFontFaceCache = adoptPtr(new HashMap<unsigned, RefPtr<CSSSegmentedFontFace> >); FontTraitsMask traitsMask = fontDescription.traitsMask(); - RefPtr<CSSSegmentedFontFace>& face = segmentedFontFaceCache->add(traitsMask, 0).iterator->second; + RefPtr<CSSSegmentedFontFace>& face = segmentedFontFaceCache->add(traitsMask, 0).iterator->value; if (!face) { face = CSSSegmentedFontFace::create(this); diff --git a/Source/WebCore/css/CSSFontSelector.h b/Source/WebCore/css/CSSFontSelector.h index 3e7bda3fd..d02100c32 100644 --- a/Source/WebCore/css/CSSFontSelector.h +++ b/Source/WebCore/css/CSSFontSelector.h @@ -55,7 +55,7 @@ public: virtual unsigned version() const OVERRIDE { return m_version; } - virtual FontData* getFontData(const FontDescription& fontDescription, const AtomicString& familyName); + virtual PassRefPtr<FontData> getFontData(const FontDescription&, const AtomicString&); void clearDocument(); diff --git a/Source/WebCore/css/CSSGradientValue.h b/Source/WebCore/css/CSSGradientValue.h index 882cc628f..1e5e7e24e 100644 --- a/Source/WebCore/css/CSSGradientValue.h +++ b/Source/WebCore/css/CSSGradientValue.h @@ -59,7 +59,7 @@ public: void addStop(const CSSGradientColorStop& stop) { m_stops.append(stop); } - Vector<CSSGradientColorStop>& stops() { return m_stops; } + unsigned stopCount() const { return m_stops.size(); } void sortStopsIfNeeded(); @@ -116,7 +116,7 @@ protected: RefPtr<CSSPrimitiveValue> m_secondY; // Stops - Vector<CSSGradientColorStop> m_stops; + Vector<CSSGradientColorStop, 2> m_stops; bool m_stopsSorted; bool m_deprecatedType; // -webkit-gradient() bool m_repeating; diff --git a/Source/WebCore/css/CSSGrammar.y b/Source/WebCore/css/CSSGrammar.y index 5167537f7..4e3533e3c 100644 --- a/Source/WebCore/css/CSSGrammar.y +++ b/Source/WebCore/css/CSSGrammar.y @@ -88,6 +88,11 @@ using namespace HTMLNames; %{ +#if YYDEBUG > 0 +#define YYPRINT(File,Type,Value) print_token_value(File,Type,Value) +static void print_token_value(FILE * yyoutput, int yytype, YYSTYPE const &yyvalue); +#endif + static inline int cssyyerror(void*, const char*) { return 1; @@ -95,7 +100,7 @@ static inline int cssyyerror(void*, const char*) %} -%expect 63 +%expect 65 %nonassoc LOWEST_PREC @@ -529,9 +534,15 @@ maybe_media_value: ; media_query_exp: - '(' maybe_space media_feature maybe_space maybe_media_value ')' maybe_space { - $3.lower(); - $$ = parser->createFloatingMediaQueryExp($3, $5); + maybe_media_restrictor maybe_space '(' maybe_space media_feature maybe_space maybe_media_value ')' maybe_space { + // If restrictor is specified, media query expression is invalid. + // Create empty media query expression and continue parsing media query. + if ($1 != MediaQuery::None) + $$ = parser->createFloatingMediaQueryExp("", 0); + else { + $5.lower(); + $$ = parser->createFloatingMediaQueryExp($5, $7); + } } ; @@ -685,7 +696,7 @@ key_list: ; key: - PERCENTAGE { $$.id = 0; $$.isInt = false; $$.fValue = $1; $$.unit = CSSPrimitiveValue::CSS_NUMBER; } + maybe_unary_operator PERCENTAGE { $$.id = 0; $$.isInt = false; $$.fValue = $1 * $2; $$.unit = CSSPrimitiveValue::CSS_NUMBER; } | IDENT { $$.id = 0; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_NUMBER; CSSParserString& str = $1; @@ -1729,3 +1740,31 @@ invalid_block_list: ; %% + +#if YYDEBUG > 0 +static void print_token_value(FILE * yyoutput, int yytype, YYSTYPE const &yyvalue) +{ + switch (yytype) { + case IDENT: + case STRING: + case NTH: + case HEX: + case IDSEL: + case DIMEN: + case INVALIDDIMEN: + case URI: + case FUNCTION: + case ANYFUNCTION: + case NOTFUNCTION: + case CALCFUNCTION: + case MINFUNCTION: + case MAXFUNCTION: + case VAR_DEFINITION: + case UNICODERANGE: + YYFPRINTF(yyoutput, "%s", String(yyvalue.string).utf8().data()); + break; + default: + break; + } +} +#endif diff --git a/Source/WebCore/css/CSSImageGeneratorValue.cpp b/Source/WebCore/css/CSSImageGeneratorValue.cpp index 63cb422a9..8cf47f06d 100644 --- a/Source/WebCore/css/CSSImageGeneratorValue.cpp +++ b/Source/WebCore/css/CSSImageGeneratorValue.cpp @@ -32,6 +32,8 @@ #include "Image.h" #include "RenderObject.h" #include "WebCoreMemoryInstrumentation.h" +#include <wtf/MemoryInstrumentationHashCountedSet.h> +#include <wtf/MemoryInstrumentationHashMap.h> #include <wtf/text/WTFString.h> namespace WebCore { @@ -57,7 +59,7 @@ void CSSImageGeneratorValue::addClient(RenderObject* renderer, const IntSize& si if (it == m_clients.end()) m_clients.add(renderer, SizeAndCount(size, 1)); else { - SizeAndCount& sizeCount = it->second; + SizeAndCount& sizeCount = it->value; ++sizeCount.count; } } @@ -69,7 +71,7 @@ void CSSImageGeneratorValue::removeClient(RenderObject* renderer) ASSERT(it != m_clients.end()); IntSize removedImageSize; - SizeAndCount& sizeCount = it->second; + SizeAndCount& sizeCount = it->value; IntSize size = sizeCount.size; if (!size.isEmpty()) { m_sizes.remove(size); @@ -87,7 +89,7 @@ Image* CSSImageGeneratorValue::getImage(RenderObject* renderer, const IntSize& s { RenderObjectSizeCountMap::iterator it = m_clients.find(renderer); if (it != m_clients.end()) { - SizeAndCount& sizeCount = it->second; + SizeAndCount& sizeCount = it->value; IntSize oldSize = sizeCount.size; if (oldSize != size) { RefPtr<CSSImageGeneratorValue> protect(this); @@ -112,9 +114,9 @@ void CSSImageGeneratorValue::putImage(const IntSize& size, PassRefPtr<Image> ima void CSSImageGeneratorValue::reportBaseClassMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS); - info.addHashCountedSet(m_sizes); - info.addHashMap(m_clients); - info.addHashMap(m_images); // FIXME: instrument Image + info.addMember(m_sizes); + info.addMember(m_clients); + info.addMember(m_images); // FIXME: instrument Image } PassRefPtr<Image> CSSImageGeneratorValue::image(RenderObject* renderer, const IntSize& size) diff --git a/Source/WebCore/css/CSSImportRule.idl b/Source/WebCore/css/CSSImportRule.idl index ddd0a8bff..d1d76abca 100644 --- a/Source/WebCore/css/CSSImportRule.idl +++ b/Source/WebCore/css/CSSImportRule.idl @@ -18,13 +18,10 @@ * Boston, MA 02110-1301, USA. */ -module css { +// Introduced in DOM Level 2: +interface CSSImportRule : CSSRule { + [TreatReturnedNullStringAs=Null] readonly attribute DOMString href; + readonly attribute MediaList media; + readonly attribute CSSStyleSheet styleSheet; +}; - // Introduced in DOM Level 2: - interface CSSImportRule : CSSRule { - readonly attribute [TreatReturnedNullStringAs=Null] DOMString href; - readonly attribute MediaList media; - readonly attribute CSSStyleSheet styleSheet; - }; - -} diff --git a/Source/WebCore/css/CSSMediaRule.idl b/Source/WebCore/css/CSSMediaRule.idl index f52a6cec8..10e8b76c4 100644 --- a/Source/WebCore/css/CSSMediaRule.idl +++ b/Source/WebCore/css/CSSMediaRule.idl @@ -18,18 +18,15 @@ * Boston, MA 02110-1301, USA. */ -module css { +// Introduced in DOM Level 2: +interface CSSMediaRule : CSSRule { + readonly attribute MediaList media; + readonly attribute CSSRuleList cssRules; + + [ObjCLegacyUnnamedParameters] unsigned long insertRule(in [Optional=DefaultIsUndefined] DOMString rule, + in [Optional=DefaultIsUndefined] unsigned long index) + raises(DOMException); + void deleteRule(in [Optional=DefaultIsUndefined] unsigned long index) + raises(DOMException); +}; - // Introduced in DOM Level 2: - interface CSSMediaRule : CSSRule { - readonly attribute MediaList media; - readonly attribute CSSRuleList cssRules; - - [ObjCLegacyUnnamedParameters] unsigned long insertRule(in [Optional=DefaultIsUndefined] DOMString rule, - in [Optional=DefaultIsUndefined] unsigned long index) - raises(DOMException); - void deleteRule(in [Optional=DefaultIsUndefined] unsigned long index) - raises(DOMException); - }; - -} diff --git a/Source/WebCore/css/CSSNamespace.h b/Source/WebCore/css/CSSNamespace.h deleted file mode 100644 index 992b97fa0..000000000 --- a/Source/WebCore/css/CSSNamespace.h +++ /dev/null @@ -1 +0,0 @@ -// FIXME: Remove this file. diff --git a/Source/WebCore/css/CSSPageRule.idl b/Source/WebCore/css/CSSPageRule.idl index b3ea22850..e9e49d096 100644 --- a/Source/WebCore/css/CSSPageRule.idl +++ b/Source/WebCore/css/CSSPageRule.idl @@ -18,15 +18,12 @@ * Boston, MA 02110-1301, USA. */ -module css { +// Introduced in DOM Level 2: +interface CSSPageRule : CSSRule { - // Introduced in DOM Level 2: - interface CSSPageRule : CSSRule { + [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] attribute DOMString selectorText; - attribute [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] DOMString selectorText; + readonly attribute CSSStyleDeclaration style; - readonly attribute CSSStyleDeclaration style; +}; - }; - -} diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp index 9a922f191..42282a196 100644 --- a/Source/WebCore/css/CSSParser.cpp +++ b/Source/WebCore/css/CSSParser.cpp @@ -110,7 +110,7 @@ #include "WebKitCSSShaderValue.h" #endif -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) #include "DashboardRegion.h" #endif @@ -380,6 +380,7 @@ void CSSParser::parseSheet(StyleSheetContents* sheet, const String& string, int m_lineNumber = startLineNumber; setupParser("", string, ""); cssyyparse(this); + sheet->shrinkToFit(); m_currentRuleDataStack.clear(); m_ruleSourceDataResult = 0; m_rule = 0; @@ -1521,6 +1522,8 @@ bool CSSParser::validUnit(CSSParserValue* value, Units unitflags, CSSParserMode } if (!b && (unitflags & FInteger) && value->isInt) b = true; + if (!b && (unitflags & FPositiveInteger) && value->isInt && value->fValue > 0) + b = true; break; case CSSPrimitiveValue::CSS_PERCENTAGE: b = (unitflags & FPercent); @@ -1599,63 +1602,6 @@ inline PassRefPtr<CSSPrimitiveValue> CSSParser::createPrimitiveStringValue(CSSPa return cssValuePool().createValue(value->string, CSSPrimitiveValue::CSS_STRING); } -static int unitFromString(CSSParserValue* value) -{ - if (value->unit != CSSPrimitiveValue::CSS_IDENT || value->id) - return 0; - - if (equal(value->string, "em")) - return CSSPrimitiveValue::CSS_EMS; - if (equal(value->string, "rem")) - return CSSPrimitiveValue::CSS_REMS; - if (equal(value->string, "ex")) - return CSSPrimitiveValue::CSS_EXS; - if (equal(value->string, "px")) - return CSSPrimitiveValue::CSS_PX; - if (equal(value->string, "cm")) - return CSSPrimitiveValue::CSS_CM; - if (equal(value->string, "mm")) - return CSSPrimitiveValue::CSS_MM; - if (equal(value->string, "in")) - return CSSPrimitiveValue::CSS_IN; - if (equal(value->string, "pt")) - return CSSPrimitiveValue::CSS_PT; - if (equal(value->string, "pc")) - return CSSPrimitiveValue::CSS_PC; - if (equal(value->string, "deg")) - return CSSPrimitiveValue::CSS_DEG; - if (equal(value->string, "rad")) - return CSSPrimitiveValue::CSS_RAD; - if (equal(value->string, "grad")) - return CSSPrimitiveValue::CSS_GRAD; - if (equal(value->string, "turn")) - return CSSPrimitiveValue::CSS_TURN; - if (equal(value->string, "ms")) - return CSSPrimitiveValue::CSS_MS; - if (equal(value->string, "s")) - return CSSPrimitiveValue::CSS_S; - if (equal(value->string, "Hz")) - return CSSPrimitiveValue::CSS_HZ; - if (equal(value->string, "kHz")) - return CSSPrimitiveValue::CSS_KHZ; - if (equal(value->string, "vw")) - return CSSPrimitiveValue::CSS_VW; - if (equal(value->string, "vh")) - return CSSPrimitiveValue::CSS_VH; - if (equal(value->string, "vmin")) - return CSSPrimitiveValue::CSS_VMIN; -#if ENABLE(CSS_IMAGE_RESOLUTION) - if (equal(value->string, "dppx")) - return CSSPrimitiveValue::CSS_DPPX; - if (equal(value->string, "dpi")) - return CSSPrimitiveValue::CSS_DPI; - if (equal(value->string, "dpcm")) - return CSSPrimitiveValue::CSS_DPCM; -#endif - - return 0; -} - static inline bool isComma(CSSParserValue* value) { return value && value->unit == CSSParserValue::Operator && value->iValue == ','; @@ -1678,37 +1624,6 @@ bool CSSParser::validHeight(CSSParserValue* value) return !id && validUnit(value, FLength | FPercent | FNonNeg); } -void CSSParser::checkForOrphanedUnits() -{ - if (inStrictMode() || inShorthand()) - return; - - // The purpose of this code is to implement the WinIE quirk that allows unit types to be separated from their numeric values - // by whitespace, so e.g., width: 20 px instead of width:20px. This is invalid CSS, so we don't do this in strict mode. - CSSParserValue* numericVal = 0; - unsigned size = m_valueList->size(); - for (unsigned i = 0; i < size; i++) { - CSSParserValue* value = m_valueList->valueAt(i); - - if (numericVal) { - // Change the unit type of the numeric val to match. - int unit = unitFromString(value); - if (unit) { - numericVal->unit = unit; - numericVal = 0; - - // Now delete the bogus unit value. - m_valueList->deleteValueAt(i); - i--; // We're safe even though |i| is unsigned, since we only hit this code if we had a previous numeric value (so |i| is always > 0 here). - size--; - continue; - } - } - - numericVal = (value->unit == CSSPrimitiveValue::CSS_NUMBER) ? value : 0; - } -} - inline PassRefPtr<CSSPrimitiveValue> CSSParser::parseValidPrimitive(int identifier, CSSParserValue* value) { if (identifier) @@ -1753,10 +1668,6 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) int id = value->id; - // In quirks mode, we will look for units that have been incorrectly separated from the number they belong to - // by a space. We go ahead and associate the unit with the number even though it is invalid CSS. - checkForOrphanedUnits(); - int num = inShorthand() ? 1 : m_valueList->size(); if (id == CSSValueInherit) { @@ -2527,7 +2438,7 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) if (id == CSSValueAuto) validPrimitive = true; else - validPrimitive = !id && validUnit(value, FInteger | FNonNeg, CSSQuirksMode); + validPrimitive = !id && validUnit(value, FPositiveInteger, CSSQuirksMode); break; case CSSPropertyWebkitColumnGap: // normal | <length> if (id == CSSValueNormal) @@ -2606,19 +2517,21 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) validPrimitive = true; break; -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) #if ENABLE(DASHBOARD_SUPPORT) case CSSPropertyWebkitDashboardRegion: // <dashboard-region> | <dashboard-region> -#endif -#if ENABLE(WIDGET_REGION) - case CSSPropertyWebkitWidgetRegion: -#endif if (value->unit == CSSParserValue::Function || id == CSSValueNone) return parseDashboardRegions(propId, important); break; #endif // End Apple-specific properties +#if ENABLE(WIDGET_REGION) + case CSSPropertyWebkitAppRegion: + if (id >= CSSValueDrag && id <= CSSValueNoDrag) + validPrimitive = true; + break; +#endif + #if ENABLE(TOUCH_EVENTS) case CSSPropertyWebkitTapHighlightColor: if ((id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu @@ -2764,6 +2677,13 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important) validPrimitive = true; else if (value->unit == CSSParserValue::Function) return parseBasicShape(propId, important); +#if ENABLE(SVG) + else if (value->unit == CSSPrimitiveValue::CSS_URI) { + parsedValue = CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_URI); + addProperty(propId, parsedValue.release(), important); + return true; + } +#endif break; #if ENABLE(CSS_EXCLUSIONS) case CSSPropertyWebkitShapeInside: @@ -4292,7 +4212,7 @@ bool CSSParser::parseGridTrackList(CSSPropertyID propId, bool important) } -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) #define DASHBOARD_REGION_NUM_PARAMETERS 6 #define DASHBOARD_REGION_SHORT_NUM_PARAMETERS 2 @@ -4345,32 +4265,7 @@ bool CSSParser::parseDashboardRegions(CSSPropertyID propId, bool important) // dashboard-region(label, type) or dashboard-region(label type) // dashboard-region(label, type) or dashboard-region(label type) CSSParserValueList* args = value->function->args.get(); - if (!args) { - valid = false; - break; - } - bool validFunctionName = false; -#if ENABLE(DASHBOARD_SUPPORT) - static const char dashboardRegionFunctionName[] = "dashboard-region("; - if (equalIgnoringCase(value->function->name, dashboardRegionFunctionName)) { - validFunctionName = true; -#if ENABLE(DASHBOARD_SUPPORT) && ENABLE(WIDGET_REGION) - // Keep track of function name when both features are enabled. - region->m_cssFunctionName = dashboardRegionFunctionName; -#endif - } -#endif -#if ENABLE(WIDGET_REGION) - static const char widgetRegionFunctionName[] = "region("; - if (equalIgnoringCase(value->function->name, widgetRegionFunctionName)) { - validFunctionName = true; -#if ENABLE(DASHBOARD_SUPPORT) && ENABLE(WIDGET_REGION) - // Keep track of function name when both features are enabled. - region->m_cssFunctionName = widgetRegionFunctionName; -#endif - } -#endif - if (!validFunctionName) { + if (!equalIgnoringCase(value->function->name, "dashboard-region(") || !args) { valid = false; break; } @@ -4456,7 +4351,7 @@ bool CSSParser::parseDashboardRegions(CSSPropertyID propId, bool important) return valid; } -#endif /* ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) */ +#endif /* ENABLE(DASHBOARD_SUPPORT) */ PassRefPtr<CSSValue> CSSParser::parseCounterContent(CSSParserValueList* args, bool counters) { @@ -6910,8 +6805,7 @@ bool CSSParser::parseLinearGradient(CSSParserValueList* valueList, RefPtr<CSSVal if (!parseGradientColorStops(args, result.get(), expectComma)) return false; - Vector<CSSGradientColorStop>& stops = result->stops(); - if (stops.isEmpty()) + if (!result->stopCount()) return false; gradient = result.release(); @@ -7072,7 +6966,7 @@ bool CSSParser::parseGradientColorStops(CSSParserValueList* valueList, CSSGradie } // Must have 2 or more stops to be valid. - return gradient->stops().size() > 1; + return gradient->stopCount() >= 2; } bool CSSParser::isGeneratedImageValue(CSSParserValue* val) const @@ -9925,8 +9819,10 @@ MediaQuerySet* CSSParser::createMediaQuerySet() StyleRuleBase* CSSParser::createImportRule(const CSSParserString& url, MediaQuerySet* media) { - if (!media || !m_allowImportRules) + if (!media || !m_allowImportRules) { + popRuleData(); return 0; + } RefPtr<StyleRuleImport> rule = StyleRuleImport::create(url, media); StyleRuleImport* result = rule.get(); m_parsedRules.append(rule.release()); @@ -9986,6 +9882,7 @@ PassRefPtr<CSSRuleSourceData> CSSParser::popRuleData() return 0; ASSERT(!m_currentRuleDataStack->isEmpty()); + m_currentRuleData.clear(); RefPtr<CSSRuleSourceData> data = m_currentRuleDataStack->last(); m_currentRuleDataStack->removeLast(); return data.release(); @@ -10037,6 +9934,7 @@ StyleRuleBase* CSSParser::createFontFaceRule() // have 'initial' value and cannot 'inherit' from parent. // See http://dev.w3.org/csswg/css3-fonts/#font-family-desc clearProperties(); + popRuleData(); return 0; } } @@ -10126,7 +10024,8 @@ StyleRuleBase* CSSParser::createPageRule(PassOwnPtr<CSSParserSelector> pageSelec pageRule = rule.get(); m_parsedRules.append(rule.release()); processAndAddNewRuleToSourceTreeIfNeeded(); - } + } else + popRuleData(); clearProperties(); return pageRule; } @@ -10139,8 +10038,10 @@ void CSSParser::setReusableRegionSelectorVector(CSSSelectorVector* selectors) StyleRuleBase* CSSParser::createRegionRule(Vector<OwnPtr<CSSParserSelector> >* regionSelector, RuleList* rules) { - if (!cssRegionsEnabled() || !regionSelector || !rules) + if (!cssRegionsEnabled() || !regionSelector || !rules) { + popRuleData(); return 0; + } m_allowImportRules = m_allowNamespaceDeclarations = false; @@ -10290,8 +10191,14 @@ void CSSParser::markRuleHeaderStart(CSSRuleSourceData::Type ruleType) { if (!isExtractingSourceData()) return; + + // Pop off data for a previous invalid rule. + if (m_currentRuleData) + m_currentRuleDataStack->removeLast(); + RefPtr<CSSRuleSourceData> data = CSSRuleSourceData::create(ruleType); data->ruleHeaderRange.start = tokenStartOffset(); + m_currentRuleData = data; m_currentRuleDataStack->append(data.release()); } @@ -10325,6 +10232,7 @@ void CSSParser::markRuleBodyStart() { if (!isExtractingSourceData()) return; + m_currentRuleData.clear(); unsigned offset = tokenStartOffset(); if (tokenStartChar() == '{') ++offset; // Skip the rule body opening brace. diff --git a/Source/WebCore/css/CSSParser.h b/Source/WebCore/css/CSSParser.h index e33090f83..b1103b1cf 100644 --- a/Source/WebCore/css/CSSParser.h +++ b/Source/WebCore/css/CSSParser.h @@ -344,6 +344,7 @@ public: size_t m_parsedTextPrefixLength; SourceRange m_propertyRange; OwnPtr<RuleSourceDataList> m_currentRuleDataStack; + RefPtr<CSSRuleSourceData> m_currentRuleData; RuleSourceDataList* m_ruleSourceDataResult; void fixUnparsedPropertyRanges(CSSRuleSourceData*); @@ -451,8 +452,6 @@ private: bool validWidth(CSSParserValue*); bool validHeight(CSSParserValue*); - void checkForOrphanedUnits(); - void deleteFontFaceOnlyValues(); bool isGeneratedImageValue(CSSParserValue*) const; @@ -526,19 +525,20 @@ private: // defines units allowed for a certain property, used in parseUnit enum Units { - FUnknown = 0x0000, - FInteger = 0x0001, - FNumber = 0x0002, // Real Numbers - FPercent = 0x0004, - FLength = 0x0008, - FAngle = 0x0010, - FTime = 0x0020, + FUnknown = 0x0000, + FInteger = 0x0001, + FNumber = 0x0002, // Real Numbers + FPercent = 0x0004, + FLength = 0x0008, + FAngle = 0x0010, + FTime = 0x0020, FFrequency = 0x0040, - FRelative = 0x0100, + FPositiveInteger = 0x0080, + FRelative = 0x0100, #if ENABLE(CSS_IMAGE_RESOLUTION) - FResolution= 0x0200, + FResolution = 0x0200, #endif - FNonNeg = 0x0400 + FNonNeg = 0x0400 }; friend inline Units operator|(Units a, Units b) diff --git a/Source/WebCore/css/CSSParserValues.cpp b/Source/WebCore/css/CSSParserValues.cpp index 8b7625578..6110807e3 100644 --- a/Source/WebCore/css/CSSParserValues.cpp +++ b/Source/WebCore/css/CSSParserValues.cpp @@ -124,7 +124,7 @@ PassRefPtr<CSSValue> CSSParserValue::createCSSValue() case CSSPrimitiveValue::CSS_DPI: case CSSPrimitiveValue::CSS_DPCM: case CSSPrimitiveValue::CSS_PAIR: -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) case CSSPrimitiveValue::CSS_DASHBOARD_REGION: #endif case CSSPrimitiveValue::CSS_UNICODE_RANGE: diff --git a/Source/WebCore/css/CSSPrimitiveValue.cpp b/Source/WebCore/css/CSSPrimitiveValue.cpp index 5ca7ceb92..55ede8b37 100644 --- a/Source/WebCore/css/CSSPrimitiveValue.cpp +++ b/Source/WebCore/css/CSSPrimitiveValue.cpp @@ -45,7 +45,7 @@ #include <wtf/text/StringBuffer.h> #include <wtf/text/StringBuilder.h> -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) #include "DashboardRegion.h" #endif @@ -91,7 +91,7 @@ static inline bool isValidCSSUnitTypeForDoubleConversion(CSSPrimitiveValue::Unit case CSSPrimitiveValue::CSS_ATTR: case CSSPrimitiveValue::CSS_COUNTER: case CSSPrimitiveValue::CSS_COUNTER_NAME: -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) case CSSPrimitiveValue::CSS_DASHBOARD_REGION: #endif #if !ENABLE(CSS_IMAGE_RESOLUTION) @@ -330,7 +330,7 @@ void CSSPrimitiveValue::init(PassRefPtr<Quad> quad) m_value.quad = quad.leakRef(); } -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) void CSSPrimitiveValue::init(PassRefPtr<DashboardRegion> r) { m_primitiveUnitType = CSS_DASHBOARD_REGION; @@ -391,7 +391,7 @@ void CSSPrimitiveValue::cleanup() case CSS_PAIR: m_value.pair->deref(); break; -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) case CSS_DASHBOARD_REGION: if (m_value.region) m_value.region->deref(); @@ -522,7 +522,10 @@ double CSSPrimitiveValue::computeLengthDouble(RenderStyle* style, RenderStyle* r // FIXME: We have a bug right now where the zoom will be applied twice to EX units. // We really need to compute EX using fontMetrics for the original specifiedSize and not use // our actual constructed rendering font. - factor = style->fontMetrics().xHeight(); + if (style->fontMetrics().hasXHeight()) + factor = style->fontMetrics().xHeight(); + else + factor = (computingFontSize ? style->fontDescription().specifiedSize() : style->fontDescription().computedSize()) / 2.0; break; case CSS_REMS: if (rootStyle) @@ -1031,19 +1034,13 @@ String CSSPrimitiveValue::customCssText() const case CSS_PAIR: text = getPairValue()->cssText(); break; -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) case CSS_DASHBOARD_REGION: { StringBuilder result; for (DashboardRegion* region = getDashboardRegionValue(); region; region = region->m_next.get()) { if (!result.isEmpty()) result.append(' '); -#if ENABLE(DASHBOARD_SUPPORT) && ENABLE(WIDGET_REGION) - result.append(region->m_cssFunctionName); -#elif ENABLE(DASHBOARD_SUPPORT) result.appendLiteral("dashboard-region("); -#else - result.appendLiteral("region("); -#endif result.append(region->m_label); if (region->m_isCircle) result.appendLiteral(" circle"); @@ -1194,7 +1191,7 @@ PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::cloneForCSSOM() const // Pair is not exposed to the CSSOM, no need for a deep clone. result = CSSPrimitiveValue::create(m_value.pair); break; -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) case CSS_DASHBOARD_REGION: // DashboardRegion is not exposed to the CSSOM, no need for a deep clone. result = CSSPrimitiveValue::create(m_value.region); @@ -1286,7 +1283,7 @@ void CSSPrimitiveValue::reportDescendantMemoryUsage(MemoryObjectInfo* memoryObje case CSS_PAIR: info.addMember(m_value.pair); break; -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) case CSS_DASHBOARD_REGION: info.addMember(m_value.region); break; diff --git a/Source/WebCore/css/CSSPrimitiveValue.h b/Source/WebCore/css/CSSPrimitiveValue.h index 0fb6445b0..aa2dbeac3 100644 --- a/Source/WebCore/css/CSSPrimitiveValue.h +++ b/Source/WebCore/css/CSSPrimitiveValue.h @@ -99,7 +99,7 @@ public: CSS_DPI = 30, CSS_DPCM = 31, CSS_PAIR = 100, // We envision this being exposed as a means of getting computed style values for pairs (border-spacing/radius, background-position, etc.) -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) CSS_DASHBOARD_REGION = 101, // FIXME: Dashboard region should not be a primitive value. #endif CSS_UNICODE_RANGE = 102, @@ -284,7 +284,7 @@ public: Pair* getPairValue(ExceptionCode&) const; Pair* getPairValue() const { return m_primitiveUnitType != CSS_PAIR ? 0 : m_value.pair; } -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) DashboardRegion* getDashboardRegionValue() const { return m_primitiveUnitType != CSS_DASHBOARD_REGION ? 0 : m_value.region; } #endif diff --git a/Source/WebCore/css/CSSPrimitiveValue.idl b/Source/WebCore/css/CSSPrimitiveValue.idl index 6c637c9ab..f64cb4742 100644 --- a/Source/WebCore/css/CSSPrimitiveValue.idl +++ b/Source/WebCore/css/CSSPrimitiveValue.idl @@ -17,59 +17,56 @@ * Boston, MA 02110-1301, USA. */ -module css { +interface CSSPrimitiveValue : CSSValue { - interface CSSPrimitiveValue : CSSValue { + // UnitTypes + const unsigned short CSS_UNKNOWN = 0; + const unsigned short CSS_NUMBER = 1; + const unsigned short CSS_PERCENTAGE = 2; + const unsigned short CSS_EMS = 3; + const unsigned short CSS_EXS = 4; + const unsigned short CSS_PX = 5; + const unsigned short CSS_CM = 6; + const unsigned short CSS_MM = 7; + const unsigned short CSS_IN = 8; + const unsigned short CSS_PT = 9; + const unsigned short CSS_PC = 10; + const unsigned short CSS_DEG = 11; + const unsigned short CSS_RAD = 12; + const unsigned short CSS_GRAD = 13; + const unsigned short CSS_MS = 14; + const unsigned short CSS_S = 15; + const unsigned short CSS_HZ = 16; + const unsigned short CSS_KHZ = 17; + const unsigned short CSS_DIMENSION = 18; + const unsigned short CSS_STRING = 19; + const unsigned short CSS_URI = 20; + const unsigned short CSS_IDENT = 21; + const unsigned short CSS_ATTR = 22; + const unsigned short CSS_COUNTER = 23; + const unsigned short CSS_RECT = 24; + const unsigned short CSS_RGBCOLOR = 25; + const unsigned short CSS_VW = 26; + const unsigned short CSS_VH = 27; + const unsigned short CSS_VMIN = 28; + + readonly attribute unsigned short primitiveType; - // UnitTypes - const unsigned short CSS_UNKNOWN = 0; - const unsigned short CSS_NUMBER = 1; - const unsigned short CSS_PERCENTAGE = 2; - const unsigned short CSS_EMS = 3; - const unsigned short CSS_EXS = 4; - const unsigned short CSS_PX = 5; - const unsigned short CSS_CM = 6; - const unsigned short CSS_MM = 7; - const unsigned short CSS_IN = 8; - const unsigned short CSS_PT = 9; - const unsigned short CSS_PC = 10; - const unsigned short CSS_DEG = 11; - const unsigned short CSS_RAD = 12; - const unsigned short CSS_GRAD = 13; - const unsigned short CSS_MS = 14; - const unsigned short CSS_S = 15; - const unsigned short CSS_HZ = 16; - const unsigned short CSS_KHZ = 17; - const unsigned short CSS_DIMENSION = 18; - const unsigned short CSS_STRING = 19; - const unsigned short CSS_URI = 20; - const unsigned short CSS_IDENT = 21; - const unsigned short CSS_ATTR = 22; - const unsigned short CSS_COUNTER = 23; - const unsigned short CSS_RECT = 24; - const unsigned short CSS_RGBCOLOR = 25; - const unsigned short CSS_VW = 26; - const unsigned short CSS_VH = 27; - const unsigned short CSS_VMIN = 28; - - readonly attribute unsigned short primitiveType; + [ObjCLegacyUnnamedParameters] void setFloatValue(in [Optional=DefaultIsUndefined] unsigned short unitType, + in [Optional=DefaultIsUndefined] float floatValue) + raises(DOMException); + float getFloatValue(in [Optional=DefaultIsUndefined] unsigned short unitType) + raises(DOMException); + [ObjCLegacyUnnamedParameters] void setStringValue(in [Optional=DefaultIsUndefined] unsigned short stringType, + in [Optional=DefaultIsUndefined] DOMString stringValue) + raises(DOMException); + DOMString getStringValue() + raises(DOMException); + Counter getCounterValue() + raises(DOMException); + Rect getRectValue() + raises(DOMException); + RGBColor getRGBColorValue() + raises(DOMException); +}; - [ObjCLegacyUnnamedParameters] void setFloatValue(in [Optional=DefaultIsUndefined] unsigned short unitType, - in [Optional=DefaultIsUndefined] float floatValue) - raises(DOMException); - float getFloatValue(in [Optional=DefaultIsUndefined] unsigned short unitType) - raises(DOMException); - [ObjCLegacyUnnamedParameters] void setStringValue(in [Optional=DefaultIsUndefined] unsigned short stringType, - in [Optional=DefaultIsUndefined] DOMString stringValue) - raises(DOMException); - DOMString getStringValue() - raises(DOMException); - Counter getCounterValue() - raises(DOMException); - Rect getRectValue() - raises(DOMException); - RGBColor getRGBColorValue() - raises(DOMException); - }; - -} diff --git a/Source/WebCore/css/CSSProperty.cpp b/Source/WebCore/css/CSSProperty.cpp index b5a9d3f4f..bf2ead12c 100644 --- a/Source/WebCore/css/CSSProperty.cpp +++ b/Source/WebCore/css/CSSProperty.cpp @@ -702,7 +702,7 @@ bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID) case CSSPropertyWebkitDashboardRegion: #endif #if ENABLE(WIDGET_REGION) - case CSSPropertyWebkitWidgetRegion: + case CSSPropertyWebkitAppRegion: #endif return false; case CSSPropertyInvalid: diff --git a/Source/WebCore/css/CSSPropertyNames.in b/Source/WebCore/css/CSSPropertyNames.in index bdd848811..69dafb882 100644 --- a/Source/WebCore/css/CSSPropertyNames.in +++ b/Source/WebCore/css/CSSPropertyNames.in @@ -265,12 +265,12 @@ z-index #if defined(ENABLE_CSS_BOX_DECORATION_BREAK) && ENABLE_CSS_BOX_DECORATION_BREAK -webkit-box-decoration-break #endif -#if defined(ENABLE_CSS_FILTERS) && ENABLE_CSS_FILTERS --webkit-filter -#endif #if defined(ENABLE_CSS_COMPOSITING) && ENABLE_CSS_COMPOSITING -webkit-blend-mode #endif +#if defined(ENABLE_CSS_FILTERS) && ENABLE_CSS_FILTERS +-webkit-filter +#endif -webkit-align-content -webkit-align-items -webkit-align-self @@ -409,7 +409,7 @@ z-index -webkit-dashboard-region #endif #if defined(ENABLE_WIDGET_REGION) && ENABLE_WIDGET_REGION --webkit-widget-region +-webkit-app-region #endif #if defined(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) && ENABLE_ACCELERATED_OVERFLOW_SCROLLING -webkit-overflow-scrolling diff --git a/Source/WebCore/css/CSSRule.idl b/Source/WebCore/css/CSSRule.idl index 79215cb4a..585adab19 100644 --- a/Source/WebCore/css/CSSRule.idl +++ b/Source/WebCore/css/CSSRule.idl @@ -18,39 +18,36 @@ * Boston, MA 02110-1301, USA. */ -module css { - - // Introduced in DOM Level 2: - interface [ - JSCustomMarkFunction, - JSGenerateIsReachable, - CustomToJSObject, - ObjCPolymorphic, - V8DependentLifetime - ] CSSRule { - - // RuleType - const unsigned short UNKNOWN_RULE = 0; - const unsigned short STYLE_RULE = 1; - const unsigned short CHARSET_RULE = 2; - const unsigned short IMPORT_RULE = 3; - const unsigned short MEDIA_RULE = 4; - const unsigned short FONT_FACE_RULE = 5; - const unsigned short PAGE_RULE = 6; - const unsigned short WEBKIT_KEYFRAMES_RULE = 7; - const unsigned short WEBKIT_KEYFRAME_RULE = 8; +// Introduced in DOM Level 2: +[ + JSCustomMarkFunction, + JSGenerateIsReachable, + CustomToJSObject, + ObjCPolymorphic, + V8DependentLifetime +] interface CSSRule { + + // RuleType + const unsigned short UNKNOWN_RULE = 0; + const unsigned short STYLE_RULE = 1; + const unsigned short CHARSET_RULE = 2; + const unsigned short IMPORT_RULE = 3; + const unsigned short MEDIA_RULE = 4; + const unsigned short FONT_FACE_RULE = 5; + const unsigned short PAGE_RULE = 6; + const unsigned short WEBKIT_KEYFRAMES_RULE = 7; + const unsigned short WEBKIT_KEYFRAME_RULE = 8; #if defined(ENABLE_CSS_REGIONS) && ENABLE_CSS_REGIONS - const unsigned short WEBKIT_REGION_RULE = 16; + const unsigned short WEBKIT_REGION_RULE = 16; #endif - readonly attribute unsigned short type; + readonly attribute unsigned short type; - attribute [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] DOMString cssText - setter raises (DOMException); + [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] attribute DOMString cssText + setter raises (DOMException); - readonly attribute CSSStyleSheet parentStyleSheet; - readonly attribute CSSRule parentRule; + readonly attribute CSSStyleSheet parentStyleSheet; + readonly attribute CSSRule parentRule; - }; +}; -} diff --git a/Source/WebCore/css/CSSRuleList.idl b/Source/WebCore/css/CSSRuleList.idl index 7ac533b8a..02448c001 100644 --- a/Source/WebCore/css/CSSRuleList.idl +++ b/Source/WebCore/css/CSSRuleList.idl @@ -23,16 +23,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -module css { +// Introduced in DOM Level 2: +[ + JSCustomIsReachable, + IndexedGetter, + V8DependentLifetime +] interface CSSRuleList { + readonly attribute unsigned long length; + CSSRule item(in [Optional=DefaultIsUndefined] unsigned long index); +}; - // Introduced in DOM Level 2: - interface [ - JSCustomIsReachable, - IndexedGetter, - V8DependentLifetime - ] CSSRuleList { - readonly attribute unsigned long length; - CSSRule item(in [Optional=DefaultIsUndefined] unsigned long index); - }; - -} diff --git a/Source/WebCore/css/CSSSegmentedFontFace.cpp b/Source/WebCore/css/CSSSegmentedFontFace.cpp index 983425469..9e9083f20 100644 --- a/Source/WebCore/css/CSSSegmentedFontFace.cpp +++ b/Source/WebCore/css/CSSSegmentedFontFace.cpp @@ -81,8 +81,9 @@ void CSSSegmentedFontFace::appendFontFace(PassRefPtr<CSSFontFace> fontFace) m_fontFaces.append(fontFace); } -static void appendFontDataWithInvalidUnicodeRangeIfLoading(SegmentedFontData* newFontData, const SimpleFontData* faceFontData, const Vector<CSSFontFace::UnicodeRange>& ranges) +static void appendFontDataWithInvalidUnicodeRangeIfLoading(SegmentedFontData* newFontData, PassRefPtr<SimpleFontData> prpFaceFontData, const Vector<CSSFontFace::UnicodeRange>& ranges) { + RefPtr<SimpleFontData> faceFontData = prpFaceFontData; if (faceFontData->isLoading()) { newFontData->appendRange(FontDataRange(0, 0, faceFontData)); return; @@ -98,19 +99,23 @@ static void appendFontDataWithInvalidUnicodeRangeIfLoading(SegmentedFontData* ne newFontData->appendRange(FontDataRange(ranges[j].from(), ranges[j].to(), faceFontData)); } -FontData* CSSSegmentedFontFace::getFontData(const FontDescription& fontDescription) +PassRefPtr<FontData> CSSSegmentedFontFace::getFontData(const FontDescription& fontDescription) { if (!isValid()) return 0; FontTraitsMask desiredTraitsMask = fontDescription.traitsMask(); - unsigned hashKey = ((fontDescription.computedPixelSize() + 1) << (FontTraitsMaskWidth + 1)) | ((fontDescription.orientation() == Vertical ? 1 : 0) << FontTraitsMaskWidth) | desiredTraitsMask; + unsigned hashKey = ((fontDescription.computedPixelSize() + 1) << (FontTraitsMaskWidth + FontWidthVariantWidth + 1)) + | ((fontDescription.orientation() == Vertical ? 1 : 0) << (FontTraitsMaskWidth + FontWidthVariantWidth)) + | fontDescription.widthVariant() << FontTraitsMaskWidth + | desiredTraitsMask; - SegmentedFontData*& fontData = m_fontDataTable.add(hashKey, 0).iterator->second; - if (fontData) - return fontData; + RefPtr<SegmentedFontData>& fontData = m_fontDataTable.add(hashKey, 0).iterator->value; + if (fontData && fontData->numRanges()) + return fontData; // No release, we have a reference to an object in the cache which should retain the ref count it has. - OwnPtr<SegmentedFontData> newFontData = adoptPtr(new SegmentedFontData); + if (!fontData) + fontData = SegmentedFontData::create(); unsigned size = m_fontFaces.size(); for (unsigned i = 0; i < size; i++) { @@ -119,19 +124,15 @@ FontData* CSSSegmentedFontFace::getFontData(const FontDescription& fontDescripti FontTraitsMask traitsMask = m_fontFaces[i]->traitsMask(); bool syntheticBold = !(traitsMask & (FontWeight600Mask | FontWeight700Mask | FontWeight800Mask | FontWeight900Mask)) && (desiredTraitsMask & (FontWeight600Mask | FontWeight700Mask | FontWeight800Mask | FontWeight900Mask)); bool syntheticItalic = !(traitsMask & FontStyleItalicMask) && (desiredTraitsMask & FontStyleItalicMask); - if (const SimpleFontData* faceFontData = m_fontFaces[i]->getFontData(fontDescription, syntheticBold, syntheticItalic)) { + if (RefPtr<SimpleFontData> faceFontData = m_fontFaces[i]->getFontData(fontDescription, syntheticBold, syntheticItalic)) { ASSERT(!faceFontData->isSegmented()); - appendFontDataWithInvalidUnicodeRangeIfLoading(newFontData.get(), faceFontData, m_fontFaces[i]->ranges()); - } - } - if (newFontData->numRanges()) { - if (Document* document = m_fontSelector->document()) { - fontData = newFontData.get(); - document->registerCustomFont(newFontData.release()); + appendFontDataWithInvalidUnicodeRangeIfLoading(fontData.get(), faceFontData.release(), m_fontFaces[i]->ranges()); } } + if (fontData->numRanges()) + return fontData; // No release, we have a reference to an object in the cache which should retain the ref count it has. - return fontData; + return 0; } } diff --git a/Source/WebCore/css/CSSSegmentedFontFace.h b/Source/WebCore/css/CSSSegmentedFontFace.h index 3efc47a63..f183f4995 100644 --- a/Source/WebCore/css/CSSSegmentedFontFace.h +++ b/Source/WebCore/css/CSSSegmentedFontFace.h @@ -51,7 +51,7 @@ public: void appendFontFace(PassRefPtr<CSSFontFace>); - FontData* getFontData(const FontDescription&); + PassRefPtr<FontData> getFontData(const FontDescription&); private: CSSSegmentedFontFace(CSSFontSelector*); @@ -60,7 +60,7 @@ private: bool isValid() const; CSSFontSelector* m_fontSelector; - HashMap<unsigned, SegmentedFontData*> m_fontDataTable; + HashMap<unsigned, RefPtr<SegmentedFontData> > m_fontDataTable; Vector<RefPtr<CSSFontFace>, 1> m_fontFaces; }; diff --git a/Source/WebCore/css/CSSSelector.cpp b/Source/WebCore/css/CSSSelector.cpp index 62233e6d4..d2ba75677 100644 --- a/Source/WebCore/css/CSSSelector.cpp +++ b/Source/WebCore/css/CSSSelector.cpp @@ -52,11 +52,24 @@ unsigned CSSSelector::specificity() const { // make sure the result doesn't overflow static const unsigned maxValueMask = 0xffffff; + static const unsigned idMask = 0xff0000; + static const unsigned classMask = 0xff00; + static const unsigned elementMask = 0xff; unsigned total = 0; + unsigned temp = 0; for (const CSSSelector* selector = this; selector; selector = selector->tagHistory()) { if (selector->m_isForPage) return (total + selector->specificityForPage()) & maxValueMask; - total = (total + selector->specificityForOneSelector()) & maxValueMask; + temp = total + selector->specificityForOneSelector(); + // Clamp each component to its max in the case of overflow. + if ((temp & idMask) < (total & idMask)) + total |= idMask; + else if ((temp & classMask) < (total & classMask)) + total |= classMask; + else if ((temp & elementMask) < (total & elementMask)) + total |= elementMask; + else + total = temp; } return total; } @@ -374,7 +387,7 @@ 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->second; + return slot == nameToPseudoType->end() ? PseudoUnknown : slot->value; } bool CSSSelector::isUnknownPseudoType(const AtomicString& name) diff --git a/Source/WebCore/css/CSSStyleDeclaration.idl b/Source/WebCore/css/CSSStyleDeclaration.idl index 9846c5458..196bfac65 100644 --- a/Source/WebCore/css/CSSStyleDeclaration.idl +++ b/Source/WebCore/css/CSSStyleDeclaration.idl @@ -18,41 +18,38 @@ * Boston, MA 02110-1301, USA. */ -module css { - - // Introduced in DOM Level 2: - interface [ - JSCustomMarkFunction, - JSGenerateIsReachable, - JSCustomGetOwnPropertySlotAndDescriptor, - CustomNamedSetter, +// Introduced in DOM Level 2: +[ + JSCustomMarkFunction, + JSGenerateIsReachable, + JSCustomGetOwnPropertySlotAndDescriptor, + CustomNamedSetter, #if defined(V8_BINDING) && V8_BINDING - NamedGetter, + NamedGetter, #endif - IndexedGetter, - CustomEnumerateProperty, - V8DependentLifetime - ] CSSStyleDeclaration { - attribute [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] DOMString cssText - setter raises(DOMException); + IndexedGetter, + CustomEnumerateProperty, + V8DependentLifetime +] interface CSSStyleDeclaration { + [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] attribute DOMString cssText + setter raises(DOMException); - [TreatReturnedNullStringAs=Null] DOMString getPropertyValue(in [Optional=DefaultIsUndefined] DOMString propertyName); - [JSCustom] CSSValue getPropertyCSSValue(in [Optional=DefaultIsUndefined] DOMString propertyName); - [TreatReturnedNullStringAs=Null] DOMString removeProperty(in [Optional=DefaultIsUndefined] DOMString propertyName) - raises(DOMException); - [TreatReturnedNullStringAs=Null] DOMString getPropertyPriority(in [Optional=DefaultIsUndefined] DOMString propertyName); - [ObjCLegacyUnnamedParameters] void setProperty(in [Optional=DefaultIsUndefined] DOMString propertyName, - in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString value, - in [Optional=DefaultIsUndefined] DOMString priority) - raises(DOMException); + [TreatReturnedNullStringAs=Null] DOMString getPropertyValue(in [Optional=DefaultIsUndefined] DOMString propertyName); + [JSCustom] CSSValue getPropertyCSSValue(in [Optional=DefaultIsUndefined] DOMString propertyName); + [TreatReturnedNullStringAs=Null] DOMString removeProperty(in [Optional=DefaultIsUndefined] DOMString propertyName) + raises(DOMException); + [TreatReturnedNullStringAs=Null] DOMString getPropertyPriority(in [Optional=DefaultIsUndefined] DOMString propertyName); + [ObjCLegacyUnnamedParameters] void setProperty(in [Optional=DefaultIsUndefined] DOMString propertyName, + in [TreatNullAs=NullString,Optional=DefaultIsUndefined] DOMString value, + in [Optional=DefaultIsUndefined] DOMString priority) + raises(DOMException); - readonly attribute unsigned long length; - DOMString item(in [Optional=DefaultIsUndefined] unsigned long index); - readonly attribute CSSRule parentRule; + readonly attribute unsigned long length; + DOMString item(in [Optional=DefaultIsUndefined] unsigned long index); + readonly attribute CSSRule parentRule; - // Extensions - [TreatReturnedNullStringAs=Null] DOMString getPropertyShorthand(in [Optional=DefaultIsUndefined] DOMString propertyName); - boolean isPropertyImplicit(in [Optional=DefaultIsUndefined] DOMString propertyName); - }; + // Extensions + [TreatReturnedNullStringAs=Null] DOMString getPropertyShorthand(in [Optional=DefaultIsUndefined] DOMString propertyName); + boolean isPropertyImplicit(in [Optional=DefaultIsUndefined] DOMString propertyName); +}; -} diff --git a/Source/WebCore/css/CSSStyleRule.idl b/Source/WebCore/css/CSSStyleRule.idl index c57632942..23cd73af4 100644 --- a/Source/WebCore/css/CSSStyleRule.idl +++ b/Source/WebCore/css/CSSStyleRule.idl @@ -18,15 +18,12 @@ * Boston, MA 02110-1301, USA. */ -module css { +// Introduced in DOM Level 2: +interface CSSStyleRule : CSSRule { - // Introduced in DOM Level 2: - interface CSSStyleRule : CSSRule { + [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] attribute DOMString selectorText; - attribute [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] DOMString selectorText; + readonly attribute CSSStyleDeclaration style; - readonly attribute CSSStyleDeclaration style; +}; - }; - -} diff --git a/Source/WebCore/css/CSSStyleSheet.cpp b/Source/WebCore/css/CSSStyleSheet.cpp index dcfc22006..13fd9a446 100644 --- a/Source/WebCore/css/CSSStyleSheet.cpp +++ b/Source/WebCore/css/CSSStyleSheet.cpp @@ -203,6 +203,8 @@ void CSSStyleSheet::setDisabled(bool disabled) void CSSStyleSheet::setMediaQueries(PassRefPtr<MediaQuerySet> mediaQueries) { m_mediaQueries = mediaQueries; + if (m_mediaCSSOMWrapper && m_mediaQueries) + m_mediaCSSOMWrapper->reattach(m_mediaQueries.get()); } unsigned CSSStyleSheet::length() const diff --git a/Source/WebCore/css/CSSStyleSheet.idl b/Source/WebCore/css/CSSStyleSheet.idl index 782db586c..69843e495 100644 --- a/Source/WebCore/css/CSSStyleSheet.idl +++ b/Source/WebCore/css/CSSStyleSheet.idl @@ -18,30 +18,27 @@ * Boston, MA 02110-1301, USA. */ -module css { +// Introduced in DOM Level 2: +[ + V8GenerateIsReachable=ImplOwnerNodeRoot +] interface CSSStyleSheet : StyleSheet { + readonly attribute CSSRule ownerRule; + readonly attribute CSSRuleList cssRules; - // Introduced in DOM Level 2: - interface [ - V8GenerateIsReachable=ImplOwnerNodeRoot - ] CSSStyleSheet : StyleSheet { - readonly attribute CSSRule ownerRule; - readonly attribute CSSRuleList cssRules; + [ObjCLegacyUnnamedParameters] unsigned long insertRule(in [Optional=DefaultIsUndefined] DOMString rule, + in [Optional=DefaultIsUndefined] unsigned long index) + raises(DOMException); + void deleteRule(in [Optional=DefaultIsUndefined] unsigned long index) + raises(DOMException); - [ObjCLegacyUnnamedParameters] unsigned long insertRule(in [Optional=DefaultIsUndefined] DOMString rule, - in [Optional=DefaultIsUndefined] unsigned long index) - raises(DOMException); - void deleteRule(in [Optional=DefaultIsUndefined] unsigned long index) - raises(DOMException); + // IE Extensions + readonly attribute CSSRuleList rules; - // IE Extensions - readonly attribute CSSRuleList rules; + long addRule(in [Optional=DefaultIsUndefined] DOMString selector, + in [Optional=DefaultIsUndefined] DOMString style, + in [Optional] unsigned long index) + raises(DOMException); + void removeRule(in [Optional=DefaultIsUndefined] unsigned long index) + raises(DOMException); +}; - long addRule(in [Optional=DefaultIsUndefined] DOMString selector, - in [Optional=DefaultIsUndefined] DOMString style, - in [Optional] unsigned long index) - raises(DOMException); - void removeRule(in [Optional=DefaultIsUndefined] unsigned long index) - raises(DOMException); - }; - -} diff --git a/Source/WebCore/css/CSSUnknownRule.idl b/Source/WebCore/css/CSSUnknownRule.idl index b62ceb873..0b0ca0c83 100644 --- a/Source/WebCore/css/CSSUnknownRule.idl +++ b/Source/WebCore/css/CSSUnknownRule.idl @@ -18,12 +18,9 @@ * Boston, MA 02110-1301, USA. */ -module css { +// Introduced in DOM Level 2: +[ + OmitConstructor +] interface CSSUnknownRule : CSSRule { +}; - // Introduced in DOM Level 2: - interface [ - OmitConstructor - ] CSSUnknownRule : CSSRule { - }; - -} diff --git a/Source/WebCore/css/CSSValue.idl b/Source/WebCore/css/CSSValue.idl index 2b0ceb31f..dec3714a1 100644 --- a/Source/WebCore/css/CSSValue.idl +++ b/Source/WebCore/css/CSSValue.idl @@ -18,27 +18,24 @@ * Boston, MA 02110-1301, USA. */ -module css { +[ + CustomToJSObject, + JSCustomIsReachable, + JSCustomFinalize, + ObjCPolymorphic, + V8DependentLifetime +] interface CSSValue { - interface [ - CustomToJSObject, - JSCustomIsReachable, - JSCustomFinalize, - ObjCPolymorphic, - V8DependentLifetime - ] CSSValue { + // UnitTypes + const unsigned short CSS_INHERIT = 0; + const unsigned short CSS_PRIMITIVE_VALUE = 1; + const unsigned short CSS_VALUE_LIST = 2; + const unsigned short CSS_CUSTOM = 3; - // UnitTypes - const unsigned short CSS_INHERIT = 0; - const unsigned short CSS_PRIMITIVE_VALUE = 1; - const unsigned short CSS_VALUE_LIST = 2; - const unsigned short CSS_CUSTOM = 3; + [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] attribute DOMString cssText + setter raises(DOMException); - attribute [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] DOMString cssText - setter raises(DOMException); + readonly attribute unsigned short cssValueType; - readonly attribute unsigned short cssValueType; +}; - }; - -} diff --git a/Source/WebCore/css/CSSValueKeywords.in b/Source/WebCore/css/CSSValueKeywords.in index 4b996796f..56c37a2a1 100644 --- a/Source/WebCore/css/CSSValueKeywords.in +++ b/Source/WebCore/css/CSSValueKeywords.in @@ -963,3 +963,8 @@ snap -webkit-paged-x -webkit-paged-y +// -webkit-app-region +#if defined(ENABLE_WIDGET_REGION) && ENABLE_WIDGET_REGION +drag +no-drag +#endif diff --git a/Source/WebCore/css/CSSValueList.h b/Source/WebCore/css/CSSValueList.h index e6a9ebdc3..06415fb18 100644 --- a/Source/WebCore/css/CSSValueList.h +++ b/Source/WebCore/css/CSSValueList.h @@ -79,7 +79,7 @@ private: explicit CSSValueList(ValueListSeparator); explicit CSSValueList(CSSParserValueList*); - Vector<RefPtr<CSSValue> > m_values; + Vector<RefPtr<CSSValue>, 4> m_values; }; // Objects of this class are intended to be stack-allocated and scoped to a single function. diff --git a/Source/WebCore/css/CSSValueList.idl b/Source/WebCore/css/CSSValueList.idl index 23e27ec16..e96392b35 100644 --- a/Source/WebCore/css/CSSValueList.idl +++ b/Source/WebCore/css/CSSValueList.idl @@ -23,14 +23,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -module css { +// Introduced in DOM Level 2: +[ + IndexedGetter +] interface CSSValueList : CSSValue { + readonly attribute unsigned long length; + CSSValue item(in [Optional=DefaultIsUndefined] unsigned long index); +}; - // Introduced in DOM Level 2: - interface [ - IndexedGetter - ] CSSValueList : CSSValue { - readonly attribute unsigned long length; - CSSValue item(in [Optional=DefaultIsUndefined] unsigned long index); - }; - -} diff --git a/Source/WebCore/css/CSSValuePool.cpp b/Source/WebCore/css/CSSValuePool.cpp index ce757b933..c1689919d 100644 --- a/Source/WebCore/css/CSSValuePool.cpp +++ b/Source/WebCore/css/CSSValuePool.cpp @@ -78,8 +78,8 @@ PassRefPtr<CSSPrimitiveValue> CSSValuePool::createColorValue(unsigned rgbValue) RefPtr<CSSPrimitiveValue> dummyValue; ColorValueCache::AddResult entry = m_colorValueCache.add(rgbValue, dummyValue); if (entry.isNewEntry) - entry.iterator->second = CSSPrimitiveValue::createColor(rgbValue); - return entry.iterator->second; + entry.iterator->value = CSSPrimitiveValue::createColor(rgbValue); + return entry.iterator->value; } PassRefPtr<CSSPrimitiveValue> CSSValuePool::createValue(double value, CSSPrimitiveValue::UnitTypes type) @@ -113,7 +113,7 @@ PassRefPtr<CSSPrimitiveValue> CSSValuePool::createValue(double value, CSSPrimiti PassRefPtr<CSSPrimitiveValue> CSSValuePool::createFontFamilyValue(const String& familyName) { - RefPtr<CSSPrimitiveValue>& value = m_fontFamilyValueCache.add(familyName, 0).iterator->second; + RefPtr<CSSPrimitiveValue>& value = m_fontFamilyValueCache.add(familyName, 0).iterator->value; if (!value) value = CSSPrimitiveValue::create(familyName, CSSPrimitiveValue::CSS_STRING); return value; @@ -126,7 +126,7 @@ PassRefPtr<CSSValueList> CSSValuePool::createFontFaceValue(const AtomicString& s if (m_fontFaceValueCache.size() > maximumFontFaceCacheSize) m_fontFaceValueCache.clear(); - RefPtr<CSSValueList>& value = m_fontFaceValueCache.add(string, 0).iterator->second; + RefPtr<CSSValueList>& value = m_fontFaceValueCache.add(string, 0).iterator->value; if (!value) value = CSSParser::parseFontFaceValue(string); return value; diff --git a/Source/WebCore/css/Counter.idl b/Source/WebCore/css/Counter.idl index 6236c454e..c96c708a1 100644 --- a/Source/WebCore/css/Counter.idl +++ b/Source/WebCore/css/Counter.idl @@ -17,13 +17,10 @@ * Boston, MA 02110-1301, USA. */ -module css { +// Introduced in DOM Level 2: +interface Counter { + readonly attribute DOMString identifier; + readonly attribute DOMString listStyle; + readonly attribute DOMString separator; +}; - // Introduced in DOM Level 2: - interface Counter { - readonly attribute DOMString identifier; - readonly attribute DOMString listStyle; - readonly attribute DOMString separator; - }; - -} diff --git a/Source/WebCore/css/DashboardRegion.h b/Source/WebCore/css/DashboardRegion.h index a698e4919..91e5d7ae1 100644 --- a/Source/WebCore/css/DashboardRegion.h +++ b/Source/WebCore/css/DashboardRegion.h @@ -23,7 +23,7 @@ #include "Rect.h" -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) namespace WebCore { @@ -37,11 +37,6 @@ public: bool m_isCircle : 1; bool m_isRectangle : 1; -#if ENABLE(DASHBOARD_SUPPORT) && ENABLE(WIDGET_REGION) - // Used to tell different CSS function name when both features are enabled. - String m_cssFunctionName; -#endif - private: DashboardRegion() : m_isCircle(false), m_isRectangle(false) { } }; diff --git a/Source/WebCore/css/MediaList.idl b/Source/WebCore/css/MediaList.idl index 35445a3dd..308eaf480 100644 --- a/Source/WebCore/css/MediaList.idl +++ b/Source/WebCore/css/MediaList.idl @@ -23,24 +23,21 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -module stylesheets { +// Introduced in DOM Level 2: +[ + JSGenerateIsReachable, + IndexedGetter +] interface MediaList { - // Introduced in DOM Level 2: - interface [ - JSGenerateIsReachable, - IndexedGetter - ] MediaList { + [TreatNullAs=NullString, TreatReturnedNullStringAs=Null] attribute DOMString mediaText + setter raises(DOMException); + readonly attribute unsigned long length; - attribute [TreatNullAs=NullString, TreatReturnedNullStringAs=Null] DOMString mediaText - setter raises(DOMException); - readonly attribute unsigned long length; + [TreatReturnedNullStringAs=Null] DOMString item(in [Optional=DefaultIsUndefined] unsigned long index); + void deleteMedium(in [Optional=DefaultIsUndefined] DOMString oldMedium) + raises(DOMException); + void appendMedium(in [Optional=DefaultIsUndefined] DOMString newMedium) + raises(DOMException); - [TreatReturnedNullStringAs=Null] DOMString item(in [Optional=DefaultIsUndefined] unsigned long index); - void deleteMedium(in [Optional=DefaultIsUndefined] DOMString oldMedium) - raises(DOMException); - void appendMedium(in [Optional=DefaultIsUndefined] DOMString newMedium) - raises(DOMException); +}; - }; - -} diff --git a/Source/WebCore/css/MediaQuery.cpp b/Source/WebCore/css/MediaQuery.cpp index fc4551ffb..103a3c0aa 100644 --- a/Source/WebCore/css/MediaQuery.cpp +++ b/Source/WebCore/css/MediaQuery.cpp @@ -41,32 +41,36 @@ namespace WebCore { String MediaQuery::serialize() const { StringBuilder result; - - switch (m_restrictor) { - case MediaQuery::Only: - result.append("only "); - break; - case MediaQuery::Not: - result.append("not "); - break; - case MediaQuery::None: - break; - } - - if (m_expressions->isEmpty()) { - result.append(m_mediaType); - return result.toString(); - } - - if (m_mediaType != "all" || m_restrictor != None) { - result.append(m_mediaType); - result.append(" and "); - } - - result.append(m_expressions->at(0)->serialize()); - for (size_t i = 1; i < m_expressions->size(); ++i) { - result.append(" and "); - result.append(m_expressions->at(i)->serialize()); + if (!m_ignored) { + switch (m_restrictor) { + case MediaQuery::Only: + result.append("only "); + break; + case MediaQuery::Not: + result.append("not "); + break; + case MediaQuery::None: + break; + } + + if (m_expressions->isEmpty()) { + result.append(m_mediaType); + return result.toString(); + } + + if (m_mediaType != "all" || m_restrictor != None) { + result.append(m_mediaType); + result.append(" and "); + } + + result.append(m_expressions->at(0)->serialize()); + for (size_t i = 1; i < m_expressions->size(); ++i) { + result.append(" and "); + result.append(m_expressions->at(i)->serialize()); + } + } else { + // If query is invalid, serialized text should turn into "not all". + result.append("not all"); } return result.toString(); } diff --git a/Source/WebCore/css/MediaQueryEvaluator.cpp b/Source/WebCore/css/MediaQueryEvaluator.cpp index 82e754532..daa490b8b 100644 --- a/Source/WebCore/css/MediaQueryEvaluator.cpp +++ b/Source/WebCore/css/MediaQueryEvaluator.cpp @@ -28,9 +28,11 @@ #include "config.h" #include "MediaQueryEvaluator.h" +#include "CSSAspectRatioValue.h" #include "Chrome.h" #include "ChromeClient.h" #include "CSSPrimitiveValue.h" +#include "CSSValueKeywords.h" #include "CSSValueList.h" #include "FloatRect.h" #include "Frame.h" @@ -171,29 +173,6 @@ bool MediaQueryEvaluator::eval(const MediaQuerySet* querySet, StyleResolver* sty return result; } -static bool parseAspectRatio(CSSValue* value, int& h, int& v) -{ - if (value->isValueList()) { - CSSValueList* valueList = static_cast<CSSValueList*>(value); - if (valueList->length() == 3) { - CSSValue* i0 = valueList->itemWithoutBoundsCheck(0); - CSSValue* i1 = valueList->itemWithoutBoundsCheck(1); - CSSValue* i2 = valueList->itemWithoutBoundsCheck(2); - if (i0->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(i0)->isNumber() - && i1->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(i1)->isString() - && i2->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(i2)->isNumber()) { - String str = static_cast<CSSPrimitiveValue*>(i1)->getStringValue(); - if (!str.isNull() && str.length() == 1 && str[0] == '/') { - h = static_cast<CSSPrimitiveValue*>(i0)->getIntValue(CSSPrimitiveValue::CSS_NUMBER); - v = static_cast<CSSPrimitiveValue*>(i2)->getIntValue(CSSPrimitiveValue::CSS_NUMBER); - return true; - } - } - } - } - return false; -} - template<typename T> bool compareValue(T a, T b, MediaFeaturePrefix op) { @@ -208,6 +187,16 @@ bool compareValue(T a, T b, MediaFeaturePrefix op) return false; } +static bool compareAspectRatioValue(CSSValue* value, int width, int height, MediaFeaturePrefix op) +{ + if (value->isAspectRatioValue()) { + CSSAspectRatioValue* aspectRatio = static_cast<CSSAspectRatioValue*>(value); + return compareValue(width * static_cast<int>(aspectRatio->denominatorValue()), height * static_cast<int>(aspectRatio->numeratorValue()), op); + } + + return false; +} + static bool numberValue(CSSValue* value, float& result) { if (value->isPrimitiveValue() @@ -243,29 +232,25 @@ static bool monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Fram static bool orientationMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix) { - // A missing parameter should fail - if (!value) - return false; - FrameView* view = frame->view(); int width = view->layoutWidth(); int height = view->layoutHeight(); - if (width > height) // Square viewport is portrait - return "landscape" == static_cast<CSSPrimitiveValue*>(value)->getStringValue(); - return "portrait" == static_cast<CSSPrimitiveValue*>(value)->getStringValue(); + if (value && value->isPrimitiveValue()) { + const int id = static_cast<CSSPrimitiveValue*>(value)->getIdent(); + if (width > height) // Square viewport is portrait. + return CSSValueLandscape == id; + return CSSValuePortrait == id; + } + + // Expression (orientation) evaluates to true if width and height >= 0. + return height >= 0 && width >= 0; } static bool aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op) { if (value) { FrameView* view = frame->view(); - int width = view->layoutWidth(); - int height = view->layoutHeight(); - int h = 0; - int v = 0; - if (parseAspectRatio(value, h, v)) - return v != 0 && compareValue(width * v, height * h, op); - return false; + return compareAspectRatioValue(value, view->layoutWidth(), view->layoutHeight(), op); } // ({,min-,max-}aspect-ratio) @@ -277,11 +262,7 @@ static bool device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle*, F { if (value) { FloatRect sg = screenRect(frame->page()->mainFrame()->view()); - int h = 0; - int v = 0; - if (parseAspectRatio(value, h, v)) - return v != 0 && compareValue(static_cast<int>(sg.width()) * v, static_cast<int>(sg.height()) * h, op); - return false; + return compareAspectRatioValue(value, static_cast<int>(sg.width()), static_cast<int>(sg.height()), op); } // ({,min-,max-}device-aspect-ratio) @@ -534,7 +515,32 @@ static bool view_modeMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* fram UNUSED_PARAM(op); if (!value) return true; - return Page::stringToViewMode(static_cast<CSSPrimitiveValue*>(value)->getStringValue()) == frame->page()->viewMode(); + + const int viewModeCSSKeywordID = static_cast<CSSPrimitiveValue*>(value)->getIdent(); + const Page::ViewMode viewMode = frame->page()->viewMode(); + bool result = false; + switch (viewMode) { + case Page::ViewModeWindowed: + result = viewModeCSSKeywordID == CSSValueWindowed; + break; + case Page::ViewModeFloating: + result = viewModeCSSKeywordID == CSSValueFloating; + break; + case Page::ViewModeFullscreen: + result = viewModeCSSKeywordID == CSSValueFullscreen; + break; + case Page::ViewModeMaximized: + result = viewModeCSSKeywordID == CSSValueMaximized; + break; + case Page::ViewModeMinimized: + result = viewModeCSSKeywordID == CSSValueMinimized; + break; + default: + result = false; + break; + } + + return result; } enum PointerDeviceType { TouchPointer, MousePointer, NoPointer, UnknownPointer }; @@ -591,10 +597,10 @@ static bool pointerMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, if (!value->isPrimitiveValue()) return false; - String str = static_cast<CSSPrimitiveValue*>(value)->getStringValue(); - return (pointer == NoPointer && str == "none") - || (pointer == TouchPointer && str == "coarse") - || (pointer == MousePointer && str == "fine"); + const int id = static_cast<CSSPrimitiveValue*>(value)->getIdent(); + return (pointer == NoPointer && id == CSSValueNone) + || (pointer == TouchPointer && id == CSSValueCoarse) + || (pointer == MousePointer && id == CSSValueFine); } static void createFunctionMap() diff --git a/Source/WebCore/css/MediaQueryExp.cpp b/Source/WebCore/css/MediaQueryExp.cpp index 5302d7b9a..1a06b7965 100644 --- a/Source/WebCore/css/MediaQueryExp.cpp +++ b/Source/WebCore/css/MediaQueryExp.cpp @@ -29,6 +29,7 @@ #include "config.h" #include "MediaQueryExp.h" +#include "CSSAspectRatioValue.h" #include "CSSParser.h" #include "CSSPrimitiveValue.h" #include "CSSValueList.h" @@ -37,51 +38,166 @@ namespace WebCore { +static inline bool featureWithCSSValueID(const AtomicString& mediaFeature, const CSSParserValue* value) +{ + if (!value->id) + return false; + + return mediaFeature == MediaFeatureNames::orientationMediaFeature + || mediaFeature == MediaFeatureNames::view_modeMediaFeature + || mediaFeature == MediaFeatureNames::pointerMediaFeature; +} + +static inline bool featureWithValidPositiveLenghtOrNumber(const AtomicString& mediaFeature, const CSSParserValue* value) +{ + if (!(((value->unit >= CSSPrimitiveValue::CSS_EMS && value->unit <= CSSPrimitiveValue::CSS_PC) || value->unit == CSSPrimitiveValue::CSS_REMS) || value->unit == CSSPrimitiveValue::CSS_NUMBER) || value->fValue < 0) + return false; + + return mediaFeature == MediaFeatureNames::heightMediaFeature + || mediaFeature == MediaFeatureNames::max_heightMediaFeature + || mediaFeature == MediaFeatureNames::min_heightMediaFeature + || mediaFeature == MediaFeatureNames::widthMediaFeature + || mediaFeature == MediaFeatureNames::max_widthMediaFeature + || mediaFeature == MediaFeatureNames::min_widthMediaFeature + || mediaFeature == MediaFeatureNames::device_heightMediaFeature + || mediaFeature == MediaFeatureNames::max_device_heightMediaFeature + || mediaFeature == MediaFeatureNames::min_device_heightMediaFeature + || mediaFeature == MediaFeatureNames::device_widthMediaFeature + || mediaFeature == MediaFeatureNames::max_device_widthMediaFeature + || mediaFeature == MediaFeatureNames::min_device_widthMediaFeature; +} + +static inline bool featureWithPositiveInteger(const AtomicString& mediaFeature, const CSSParserValue* value) +{ + if (!value->isInt || value->fValue < 0) + return false; + + return mediaFeature == MediaFeatureNames::colorMediaFeature + || mediaFeature == MediaFeatureNames::max_colorMediaFeature + || mediaFeature == MediaFeatureNames::min_colorMediaFeature + || mediaFeature == MediaFeatureNames::min_monochromeMediaFeature + || mediaFeature == MediaFeatureNames::max_monochromeMediaFeature; +} + +static inline bool featureWithPositiveNumber(const AtomicString& mediaFeature, const CSSParserValue* value) +{ + if (value->unit != CSSPrimitiveValue::CSS_NUMBER || value->fValue < 0) + return false; + + return mediaFeature == MediaFeatureNames::transform_2dMediaFeature + || mediaFeature == MediaFeatureNames::transform_3dMediaFeature + || mediaFeature == MediaFeatureNames::transitionMediaFeature + || mediaFeature == MediaFeatureNames::animationMediaFeature + || mediaFeature == MediaFeatureNames::device_pixel_ratioMediaFeature + || mediaFeature == MediaFeatureNames::max_device_pixel_ratioMediaFeature + || mediaFeature == MediaFeatureNames::min_device_pixel_ratioMediaFeature; +} + +static inline bool featureWithZeroOrOne(const AtomicString& mediaFeature, const CSSParserValue* value) +{ + if (!value->isInt || !(value->fValue == 1 || !value->fValue)) + return false; + + return mediaFeature == MediaFeatureNames::gridMediaFeature + || mediaFeature == MediaFeatureNames::hoverMediaFeature; +} + +static inline bool featureWithAspectRatio(const AtomicString& mediaFeature) +{ + return mediaFeature == MediaFeatureNames::aspect_ratioMediaFeature + || mediaFeature == MediaFeatureNames::device_aspect_ratioMediaFeature + || mediaFeature == MediaFeatureNames::min_aspect_ratioMediaFeature + || mediaFeature == MediaFeatureNames::max_aspect_ratioMediaFeature + || mediaFeature == MediaFeatureNames::min_device_aspect_ratioMediaFeature + || mediaFeature == MediaFeatureNames::max_device_aspect_ratioMediaFeature; +} + +static inline bool featureWithoutValue(const AtomicString& mediaFeature) +{ + return mediaFeature == MediaFeatureNames::monochromeMediaFeature + || mediaFeature == MediaFeatureNames::colorMediaFeature + || mediaFeature == MediaFeatureNames::gridMediaFeature + || mediaFeature == MediaFeatureNames::heightMediaFeature + || mediaFeature == MediaFeatureNames::widthMediaFeature + || mediaFeature == MediaFeatureNames::device_heightMediaFeature + || mediaFeature == MediaFeatureNames::device_widthMediaFeature + || mediaFeature == MediaFeatureNames::orientationMediaFeature + || mediaFeature == MediaFeatureNames::aspect_ratioMediaFeature + || mediaFeature == MediaFeatureNames::device_aspect_ratioMediaFeature + || mediaFeature == MediaFeatureNames::hoverMediaFeature + || mediaFeature == MediaFeatureNames::transform_2dMediaFeature + || mediaFeature == MediaFeatureNames::transform_3dMediaFeature + || mediaFeature == MediaFeatureNames::transitionMediaFeature + || mediaFeature == MediaFeatureNames::animationMediaFeature + || mediaFeature == MediaFeatureNames::view_modeMediaFeature + || mediaFeature == MediaFeatureNames::pointerMediaFeature + || mediaFeature == MediaFeatureNames::device_pixel_ratioMediaFeature; +} + inline MediaQueryExp::MediaQueryExp(const AtomicString& mediaFeature, CSSParserValueList* valueList) : m_mediaFeature(mediaFeature) , m_value(0) - , m_isValid(true) + , m_isValid(false) { + // Initialize media query expression that must have 1 or more values. if (valueList) { if (valueList->size() == 1) { CSSParserValue* value = valueList->current(); - if (value->id != 0) + // Media features that use CSSValueIDs. + if (featureWithCSSValueID(mediaFeature, value)) m_value = CSSPrimitiveValue::createIdentifier(value->id); - else if (value->unit == CSSPrimitiveValue::CSS_STRING) - m_value = CSSPrimitiveValue::create(value->string, (CSSPrimitiveValue::UnitTypes) value->unit); - else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && - value->unit <= CSSPrimitiveValue::CSS_KHZ) + + // 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); - valueList->next(); - } else if (valueList->size() > 1) { - // create list of values - // currently accepts only <integer>/<integer> + // Media features that must have non-negative integer value. + else if (featureWithPositiveInteger(mediaFeature, value)) + m_value = CSSPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_NUMBER); - RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); - CSSParserValue* value = valueList->current(); - bool isValid = true; + // Media features that must have non-negative number value. + else if (featureWithPositiveNumber(mediaFeature, value)) + m_value = CSSPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_NUMBER); - while (value && isValid) { - if (value->unit == CSSParserValue::Operator && value->iValue == '/') - list->append(CSSPrimitiveValue::create("/", CSSPrimitiveValue::CSS_STRING)); - else if (value->unit == CSSPrimitiveValue::CSS_NUMBER) - list->append(CSSPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_NUMBER)); - else - isValid = false; + // Media features that must have (0|1) value. + else if (featureWithZeroOrOne(mediaFeature, value)) + m_value = CSSPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_NUMBER); - value = valueList->next(); + m_isValid = m_value; + } else if (valueList->size() == 3 && featureWithAspectRatio(mediaFeature)) { + // Create list of values. + // Currently accepts only <integer>/<integer>. + // Applicable to device-aspect-ratio and aspec-ratio. + bool isValid = true; + float numeratorValue = 0; + float denominatorValue = 0; + + // The aspect-ratio must be <integer> (whitespace)? / (whitespace)? <integer>. + for (unsigned i = 0; i < 3; ++i, valueList->next()) { + const CSSParserValue* value = valueList->current(); + if (i != 1 && value->unit == CSSPrimitiveValue::CSS_NUMBER && value->fValue > 0 && value->isInt) { + if (!i) + numeratorValue = value->fValue; + else + denominatorValue = value->fValue; + } else if (i == 1 && value->unit == CSSParserValue::Operator && value->iValue == '/') + continue; + else { + isValid = false; + break; + } } if (isValid) - m_value = list.release(); + m_value = CSSAspectRatioValue::create(numeratorValue, denominatorValue); + + m_isValid = m_value; } - m_isValid = m_value; - } + } else if (featureWithoutValue(mediaFeature)) + m_isValid = true; } - PassOwnPtr<MediaQueryExp> MediaQueryExp::create(const AtomicString& mediaFeature, CSSParserValueList* values) { return adoptPtr(new MediaQueryExp(mediaFeature, values)); diff --git a/Source/WebCore/css/MediaQueryList.idl b/Source/WebCore/css/MediaQueryList.idl index b4f7b9581..e22cbd884 100644 --- a/Source/WebCore/css/MediaQueryList.idl +++ b/Source/WebCore/css/MediaQueryList.idl @@ -17,11 +17,9 @@ * Boston, MA 02110-1301, USA. */ -module view { - interface MediaQueryList { - readonly attribute DOMString media; - readonly attribute boolean matches; - void addListener(in [Optional=DefaultIsUndefined] MediaQueryListListener listener); - void removeListener(in [Optional=DefaultIsUndefined] MediaQueryListListener listener); - }; -} +interface MediaQueryList { + readonly attribute DOMString media; + readonly attribute boolean matches; + void addListener(in [Optional=DefaultIsUndefined] MediaQueryListListener listener); + void removeListener(in [Optional=DefaultIsUndefined] MediaQueryListListener listener); +}; diff --git a/Source/WebCore/css/MediaQueryListListener.idl b/Source/WebCore/css/MediaQueryListListener.idl index d8f383aae..cfcea0b75 100644 --- a/Source/WebCore/css/MediaQueryListListener.idl +++ b/Source/WebCore/css/MediaQueryListListener.idl @@ -17,13 +17,11 @@ * Boston, MA 02110-1301, USA. */ -module view { - interface [ - JSNoStaticTables, - ObjCProtocol, - CPPPureInterface, - OmitConstructor - ] MediaQueryListListener { - void queryChanged(in [Optional=DefaultIsUndefined] MediaQueryList list); - }; -} +[ + JSNoStaticTables, + ObjCProtocol, + CPPPureInterface, + OmitConstructor +] interface MediaQueryListListener { + void queryChanged(in [Optional=DefaultIsUndefined] MediaQueryList list); +}; diff --git a/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp b/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp index f6e3db39b..93d4e4538 100644 --- a/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp +++ b/Source/WebCore/css/PropertySetCSSStyleDeclaration.cpp @@ -32,6 +32,7 @@ #include "StyledElement.h" #include "UndoManager.h" #include "WebCoreMemoryInstrumentation.h" +#include <wtf/MemoryInstrumentationHashMap.h> using namespace std; @@ -173,8 +174,7 @@ void PropertySetCSSStyleDeclaration::reportMemoryUsage(MemoryObjectInfo* memoryO { MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS); info.addMember(m_propertySet); - if (m_cssomCSSValueClones) - info.addInstrumentedMapEntries(*m_cssomCSSValueClones); + info.addMember(m_cssomCSSValueClones); } unsigned PropertySetCSSStyleDeclaration::length() const @@ -346,7 +346,7 @@ CSSValue* PropertySetCSSStyleDeclaration::cloneAndCacheForCSSOM(CSSValue* intern if (!m_cssomCSSValueClones) m_cssomCSSValueClones = adoptPtr(new HashMap<CSSValue*, RefPtr<CSSValue> >); - RefPtr<CSSValue>& clonedValue = m_cssomCSSValueClones->add(internalValue, RefPtr<CSSValue>()).iterator->second; + RefPtr<CSSValue>& clonedValue = m_cssomCSSValueClones->add(internalValue, RefPtr<CSSValue>()).iterator->value; if (!clonedValue) clonedValue = internalValue->cloneForCSSOM(); return clonedValue.get(); diff --git a/Source/WebCore/css/RGBColor.idl b/Source/WebCore/css/RGBColor.idl index 1dc87bcfd..fa2ffc4db 100644 --- a/Source/WebCore/css/RGBColor.idl +++ b/Source/WebCore/css/RGBColor.idl @@ -18,21 +18,18 @@ * Boston, MA 02110-1301, USA. */ -module css { +// Introduced in DOM Level 2: +interface RGBColor { + readonly attribute CSSPrimitiveValue red; + readonly attribute CSSPrimitiveValue green; + readonly attribute CSSPrimitiveValue blue; - // Introduced in DOM Level 2: - interface RGBColor { - readonly attribute CSSPrimitiveValue red; - readonly attribute CSSPrimitiveValue green; - readonly attribute CSSPrimitiveValue blue; - - // WebKit extensions + // WebKit extensions #if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT - readonly attribute CSSPrimitiveValue alpha; + readonly attribute CSSPrimitiveValue alpha; #endif #if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C - readonly attribute Color color; + readonly attribute Color color; #endif - }; +}; -} diff --git a/Source/WebCore/css/Rect.h b/Source/WebCore/css/Rect.h index 7666f199c..feef87520 100644 --- a/Source/WebCore/css/Rect.h +++ b/Source/WebCore/css/Rect.h @@ -83,9 +83,9 @@ public: String serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const { return generateCSSString(top()->customSerializeResolvingVariables(variables), - right()->customSerializeResolvingVariables(variables), - bottom()->customSerializeResolvingVariables(variables), - left()->customSerializeResolvingVariables(variables)); + right()->customSerializeResolvingVariables(variables), + bottom()->customSerializeResolvingVariables(variables), + left()->customSerializeResolvingVariables(variables)); } #endif @@ -113,9 +113,9 @@ public: String serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const { return generateCSSString(top()->customSerializeResolvingVariables(variables), - right()->customSerializeResolvingVariables(variables), - bottom()->customSerializeResolvingVariables(variables), - left()->customSerializeResolvingVariables(variables)); + right()->customSerializeResolvingVariables(variables), + bottom()->customSerializeResolvingVariables(variables), + left()->customSerializeResolvingVariables(variables)); } #endif @@ -125,6 +125,8 @@ private: static String generateCSSString(const String& top, const String& right, const String& bottom, const String& left) { StringBuilder result; + // reserve space for the four strings, plus three space separator characters. + result.reserveCapacity(top.length() + right.length() + bottom.length() + left.length() + 3); result.append(top); if (right != top || bottom != top || left != top) { result.append(' '); diff --git a/Source/WebCore/css/Rect.idl b/Source/WebCore/css/Rect.idl index 60eb70e31..ffc490cbd 100644 --- a/Source/WebCore/css/Rect.idl +++ b/Source/WebCore/css/Rect.idl @@ -17,13 +17,10 @@ * Boston, MA 02110-1301, USA. */ -module css { +interface Rect { + readonly attribute CSSPrimitiveValue top; + readonly attribute CSSPrimitiveValue right; + readonly attribute CSSPrimitiveValue bottom; + readonly attribute CSSPrimitiveValue left; +}; - interface Rect { - readonly attribute CSSPrimitiveValue top; - readonly attribute CSSPrimitiveValue right; - readonly attribute CSSPrimitiveValue bottom; - readonly attribute CSSPrimitiveValue left; - }; - -} diff --git a/Source/WebCore/css/RuleFeature.cpp b/Source/WebCore/css/RuleFeature.cpp new file mode 100644 index 000000000..663b94613 --- /dev/null +++ b/Source/WebCore/css/RuleFeature.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 1999 Lars Knoll (knoll@kde.org) + * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) + * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) + * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. + * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> + * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> + * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) + * Copyright (c) 2011, Code Aurora Forum. All rights reserved. + * Copyright (C) Research In Motion Limited 2011. All rights reserved. + * Copyright (C) 2012 Google Inc. 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 + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "RuleFeature.h" + +#include "WebCoreMemoryInstrumentation.h" +#include <wtf/MemoryInstrumentationHashMap.h> +#include <wtf/MemoryInstrumentationHashSet.h> +#include <wtf/MemoryInstrumentationVector.h> + +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) + idsInRules.add(*it); + end = other.attrsInRules.end(); + for (HashSet<AtomicStringImpl*>::iterator it = other.attrsInRules.begin(); it != end; ++it) + attrsInRules.add(*it); + siblingRules.append(other.siblingRules); + uncommonAttributeRules.append(other.uncommonAttributeRules); + usesFirstLineRules = usesFirstLineRules || other.usesFirstLineRules; + usesBeforeAfterRules = usesBeforeAfterRules || other.usesBeforeAfterRules; +} + +void RuleFeatureSet::clear() +{ + idsInRules.clear(); + attrsInRules.clear(); + siblingRules.clear(); + uncommonAttributeRules.clear(); + usesFirstLineRules = false; + usesBeforeAfterRules = false; +} + +void RuleFeatureSet::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const +{ + MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS); + info.addMember(idsInRules); + info.addMember(attrsInRules); + info.addMember(siblingRules); + info.addMember(uncommonAttributeRules); +} + +} // namespace WebCore diff --git a/Source/WebCore/css/RuleFeature.h b/Source/WebCore/css/RuleFeature.h new file mode 100644 index 000000000..5f16288c0 --- /dev/null +++ b/Source/WebCore/css/RuleFeature.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 1999 Lars Knoll (knoll@kde.org) + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. 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 + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef RuleFeature_h +#define RuleFeature_h + +#include <wtf/Forward.h> +#include <wtf/HashMap.h> +#include <wtf/HashSet.h> +#include <wtf/text/AtomicString.h> + +namespace WebCore { + +class StyleRule; + +class RuleFeature { +public: + RuleFeature(StyleRule* rule, unsigned selectorIndex, bool hasDocumentSecurityOrigin) + : rule(rule) + , selectorIndex(selectorIndex) + , hasDocumentSecurityOrigin(hasDocumentSecurityOrigin) + { + } + StyleRule* rule; + unsigned selectorIndex; + bool hasDocumentSecurityOrigin; +}; + +class RuleFeatureSet { +public: + RuleFeatureSet() + : usesFirstLineRules(false) + , usesBeforeAfterRules(false) + { } + + void add(const RuleFeatureSet&); + void clear(); + void reportMemoryUsage(MemoryObjectInfo*) const; + HashSet<AtomicStringImpl*> idsInRules; + HashSet<AtomicStringImpl*> attrsInRules; + Vector<RuleFeature> siblingRules; + Vector<RuleFeature> uncommonAttributeRules; + bool usesFirstLineRules; + bool usesBeforeAfterRules; +}; + +} // namespace WebCore + +#endif // RuleFeature_h diff --git a/Source/WebCore/css/RuleSet.cpp b/Source/WebCore/css/RuleSet.cpp new file mode 100644 index 000000000..e2be5771e --- /dev/null +++ b/Source/WebCore/css/RuleSet.cpp @@ -0,0 +1,380 @@ +/* + * Copyright (C) 1999 Lars Knoll (knoll@kde.org) + * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) + * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) + * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. + * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> + * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> + * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) + * Copyright (c) 2011, Code Aurora Forum. All rights reserved. + * Copyright (C) Research In Motion Limited 2011. All rights reserved. + * Copyright (C) 2012 Google Inc. 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 + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "RuleSet.h" + +#include "CSSFontSelector.h" +#include "CSSSelector.h" +#include "CSSSelectorList.h" +#include "HTMLNames.h" +#include "MediaQueryEvaluator.h" +#include "SecurityOrigin.h" +#include "SelectorChecker.h" +#include "StyleResolver.h" +#include "StyleRule.h" +#include "StyleRuleImport.h" +#include "StyleSheetContents.h" +#include "WebCoreMemoryInstrumentation.h" +#include "WebKitCSSKeyframesRule.h" +#include <wtf/MemoryInstrumentationHashMap.h> +#include <wtf/MemoryInstrumentationHashSet.h> +#include <wtf/MemoryInstrumentationVector.h> + +namespace WebCore { + +using namespace HTMLNames; + +// ----------------------------------------------------------------- + +static inline bool isSelectorMatchingHTMLBasedOnRuleHash(const CSSSelector* selector) +{ + const AtomicString& selectorNamespace = selector->tag().namespaceURI(); + if (selectorNamespace != starAtom && selectorNamespace != xhtmlNamespaceURI) + return false; + if (selector->m_match == CSSSelector::None) + return true; + if (selector->tag() != starAtom) + return false; + if (SelectorChecker::isCommonPseudoClassSelector(selector)) + return true; + return selector->m_match == CSSSelector::Id || selector->m_match == CSSSelector::Class; +} + +static inline bool selectorListContainsUncommonAttributeSelector(const CSSSelector* selector) +{ + CSSSelectorList* selectorList = selector->selectorList(); + if (!selectorList) + return false; + for (CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) { + if (subSelector->isAttributeSelector()) + return true; + } + return false; +} + +static inline bool isCommonAttributeSelectorAttribute(const QualifiedName& attribute) +{ + // These are explicitly tested for equality in canShareStyleWithElement. + return attribute == typeAttr || attribute == readonlyAttr; +} + +static inline bool containsUncommonAttributeSelector(const CSSSelector* selector) +{ + for (; selector; selector = selector->tagHistory()) { + // Allow certain common attributes (used in the default style) in the selectors that match the current element. + if (selector->isAttributeSelector() && !isCommonAttributeSelectorAttribute(selector->attribute())) + return true; + if (selectorListContainsUncommonAttributeSelector(selector)) + return true; + if (selector->relation() != CSSSelector::SubSelector) { + selector = selector->tagHistory(); + break; + } + } + + for (; selector; selector = selector->tagHistory()) { + if (selector->isAttributeSelector()) + return true; + if (selectorListContainsUncommonAttributeSelector(selector)) + return true; + } + return false; +} + +RuleData::RuleData(StyleRule* rule, unsigned selectorIndex, unsigned position, bool hasDocumentSecurityOrigin, bool canUseFastCheckSelector, bool inRegionRule) + : m_rule(rule) + , m_selectorIndex(selectorIndex) + , m_position(position) + , m_specificity(selector()->specificity()) + , m_hasFastCheckableSelector(canUseFastCheckSelector && 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) +{ + ASSERT(m_position == position); + ASSERT(m_selectorIndex == selectorIndex); + SelectorChecker::collectIdentifierHashes(selector(), m_descendantSelectorIdentifierHashes, maximumIdentifierCount); +} + +void RuleData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const +{ + MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS); +} + +static void reportAtomRuleMap(MemoryClassInfo* info, const RuleSet::AtomRuleMap& atomicRuleMap) +{ + info->addMember(atomicRuleMap); + for (RuleSet::AtomRuleMap::const_iterator it = atomicRuleMap.begin(); it != atomicRuleMap.end(); ++it) + info->addMember(*it->value); +} + +void RuleSet::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const +{ + MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS); + reportAtomRuleMap(&info, m_idRules); + reportAtomRuleMap(&info, m_classRules); + reportAtomRuleMap(&info, m_tagRules); + reportAtomRuleMap(&info, m_shadowPseudoElementRules); + info.addMember(m_linkPseudoClassRules); + info.addMember(m_focusPseudoClassRules); + info.addMember(m_universalRules); + info.addMember(m_pageRules); + info.addMember(m_regionSelectorsAndRuleSets); +} + +void RuleSet::RuleSetSelectorPair::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const +{ + MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS); + info.addMember(ruleSet); +} + +static inline void collectFeaturesFromSelector(RuleFeatureSet& features, const CSSSelector* selector) +{ + if (selector->m_match == CSSSelector::Id) + features.idsInRules.add(selector->value().impl()); + if (selector->isAttributeSelector()) + features.attrsInRules.add(selector->attribute().localName().impl()); + switch (selector->pseudoType()) { + case CSSSelector::PseudoFirstLine: + features.usesFirstLineRules = true; + break; + case CSSSelector::PseudoBefore: + case CSSSelector::PseudoAfter: + features.usesBeforeAfterRules = true; + break; + default: + break; + } +} + +static void collectFeaturesFromRuleData(RuleFeatureSet& features, const RuleData& ruleData) +{ + bool foundSiblingSelector = false; + for (CSSSelector* selector = ruleData.selector(); selector; selector = selector->tagHistory()) { + collectFeaturesFromSelector(features, selector); + + if (CSSSelectorList* selectorList = selector->selectorList()) { + for (CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) { + if (!foundSiblingSelector && selector->isSiblingSelector()) + foundSiblingSelector = true; + collectFeaturesFromSelector(features, subSelector); + } + } else if (!foundSiblingSelector && selector->isSiblingSelector()) + foundSiblingSelector = true; + } + if (foundSiblingSelector) + features.siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex(), ruleData.hasDocumentSecurityOrigin())); + if (ruleData.containsUncommonAttributeSelector()) + features.uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex(), ruleData.hasDocumentSecurityOrigin())); +} + +void RuleSet::addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map, const RuleData& ruleData) +{ + if (!key) + return; + OwnPtr<Vector<RuleData> >& rules = map.add(key, nullptr).iterator->value; + if (!rules) + rules = adoptPtr(new Vector<RuleData>); + rules->append(ruleData); +} + +void RuleSet::addRule(StyleRule* rule, unsigned selectorIndex, bool hasDocumentSecurityOrigin, bool canUseFastCheckSelector, bool inRegionRule) +{ + RuleData ruleData(rule, selectorIndex, m_ruleCount++, hasDocumentSecurityOrigin, canUseFastCheckSelector, inRegionRule); + collectFeaturesFromRuleData(m_features, ruleData); + + CSSSelector* selector = ruleData.selector(); + + if (selector->m_match == CSSSelector::Id) { + addToRuleSet(selector->value().impl(), m_idRules, ruleData); + return; + } + if (selector->m_match == CSSSelector::Class) { + addToRuleSet(selector->value().impl(), m_classRules, ruleData); + return; + } + if (selector->isUnknownPseudoElement()) { + addToRuleSet(selector->value().impl(), m_shadowPseudoElementRules, ruleData); + return; + } + if (SelectorChecker::isCommonPseudoClassSelector(selector)) { + switch (selector->pseudoType()) { + case CSSSelector::PseudoLink: + case CSSSelector::PseudoVisited: + case CSSSelector::PseudoAnyLink: + m_linkPseudoClassRules.append(ruleData); + return; + case CSSSelector::PseudoFocus: + m_focusPseudoClassRules.append(ruleData); + return; + default: + ASSERT_NOT_REACHED(); + } + return; + } + const AtomicString& localName = selector->tag().localName(); + if (localName != starAtom) { + addToRuleSet(localName.impl(), m_tagRules, ruleData); + return; + } + m_universalRules.append(ruleData); +} + +void RuleSet::addPageRule(StyleRulePage* rule) +{ + m_pageRules.append(rule); +} + +void RuleSet::addRegionRule(StyleRuleRegion* regionRule, bool hasDocumentSecurityOrigin) +{ + OwnPtr<RuleSet> regionRuleSet = RuleSet::create(); + // The region rule set should take into account the position inside the parent rule set. + // Otherwise, the rules inside region block might be incorrectly positioned before other similar rules from + // the stylesheet that contains the region block. + regionRuleSet->m_ruleCount = m_ruleCount; + + // Collect the region rules into a rule set + const Vector<RefPtr<StyleRuleBase> >& childRules = regionRule->childRules(); + 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); + } + // Update the "global" rule count so that proper order is maintained + m_ruleCount = regionRuleSet->m_ruleCount; + + m_regionSelectorsAndRuleSets.append(RuleSetSelectorPair(regionRule->selectorList().first(), regionRuleSet.release())); +} + +void RuleSet::addRulesFromSheet(StyleSheetContents* sheet, const MediaQueryEvaluator& medium, StyleResolver* resolver, const ContainerNode* scope) +{ + ASSERT(sheet); + + const Vector<RefPtr<StyleRuleImport> >& importRules = sheet->importRules(); + for (unsigned i = 0; i < importRules.size(); ++i) { + StyleRuleImport* importRule = importRules[i].get(); + if (importRule->styleSheet() && (!importRule->mediaQueries() || medium.eval(importRule->mediaQueries(), resolver))) + addRulesFromSheet(importRule->styleSheet(), medium, resolver, scope); + } + bool hasDocumentSecurityOrigin = resolver && resolver->document()->securityOrigin()->canRequest(sheet->baseURL()); + + const Vector<RefPtr<StyleRuleBase> >& rules = sheet->childRules(); + for (unsigned i = 0; i < rules.size(); ++i) { + StyleRuleBase* rule = rules[i].get(); + + ASSERT(!rule->isImportRule()); + if (rule->isStyleRule()) + addStyleRule(static_cast<StyleRule*>(rule), hasDocumentSecurityOrigin, !scope); + else if (rule->isPageRule()) + addPageRule(static_cast<StyleRulePage*>(rule)); + else if (rule->isMediaRule()) { + StyleRuleMedia* mediaRule = static_cast<StyleRuleMedia*>(rule); + + if ((!mediaRule->mediaQueries() || medium.eval(mediaRule->mediaQueries(), resolver))) { + // Traverse child elements of the @media rule. + const Vector<RefPtr<StyleRuleBase> >& childRules = mediaRule->childRules(); + for (unsigned j = 0; j < childRules.size(); ++j) { + StyleRuleBase* childRule = childRules[j].get(); + if (childRule->isStyleRule()) + addStyleRule(static_cast<StyleRule*>(childRule), hasDocumentSecurityOrigin, !scope); + else if (childRule->isPageRule()) + addPageRule(static_cast<StyleRulePage*>(childRule)); + else if (childRule->isFontFaceRule() && resolver) { + // Add this font face to our set. + // FIXME(BUG 72461): We don't add @font-face rules of scoped style sheets for the moment. + if (scope) + continue; + const StyleRuleFontFace* fontFaceRule = static_cast<StyleRuleFontFace*>(childRule); + resolver->fontSelector()->addFontFaceRule(fontFaceRule); + resolver->invalidateMatchedPropertiesCache(); + } else if (childRule->isKeyframesRule() && resolver) { + // Add this keyframe rule to our set. + // FIXME(BUG 72462): We don't add @keyframe rules of scoped style sheets for the moment. + if (scope) + continue; + resolver->addKeyframeStyle(static_cast<StyleRuleKeyframes*>(childRule)); + } + } // for rules + } // if rules + } else if (rule->isFontFaceRule() && resolver) { + // Add this font face to our set. + // FIXME(BUG 72461): We don't add @font-face rules of scoped style sheets for the moment. + if (scope) + continue; + const StyleRuleFontFace* fontFaceRule = static_cast<StyleRuleFontFace*>(rule); + resolver->fontSelector()->addFontFaceRule(fontFaceRule); + resolver->invalidateMatchedPropertiesCache(); + } else if (rule->isKeyframesRule() && resolver) { + // FIXME (BUG 72462): We don't add @keyframe rules of scoped style sheets for the moment. + if (scope) + continue; + resolver->addKeyframeStyle(static_cast<StyleRuleKeyframes*>(rule)); + } +#if ENABLE(CSS_REGIONS) + else if (rule->isRegionRule() && resolver) { + // FIXME (BUG 72472): We don't add @-webkit-region rules of scoped style sheets for the moment. + if (scope) + continue; + addRegionRule(static_cast<StyleRuleRegion*>(rule), hasDocumentSecurityOrigin); + } +#endif + } + if (m_autoShrinkToFitEnabled) + shrinkToFit(); +} + +void RuleSet::addStyleRule(StyleRule* rule, bool hasDocumentSecurityOrigin, bool canUseFastCheckSelector, bool isInRegionRule) +{ + for (size_t selectorIndex = 0; selectorIndex != notFound; selectorIndex = rule->selectorList().indexOfNextSelectorAfter(selectorIndex)) + addRule(rule, selectorIndex, hasDocumentSecurityOrigin, canUseFastCheckSelector, isInRegionRule); +} + +static inline void shrinkMapVectorsToFit(RuleSet::AtomRuleMap& map) +{ + RuleSet::AtomRuleMap::iterator end = map.end(); + for (RuleSet::AtomRuleMap::iterator it = map.begin(); it != end; ++it) + it->value->shrinkToFit(); +} + +void RuleSet::shrinkToFit() +{ + shrinkMapVectorsToFit(m_idRules); + shrinkMapVectorsToFit(m_classRules); + shrinkMapVectorsToFit(m_tagRules); + shrinkMapVectorsToFit(m_shadowPseudoElementRules); + m_linkPseudoClassRules.shrinkToFit(); + m_focusPseudoClassRules.shrinkToFit(); + m_universalRules.shrinkToFit(); + m_pageRules.shrinkToFit(); +} + +} // namespace WebCore diff --git a/Source/WebCore/css/RuleSet.h b/Source/WebCore/css/RuleSet.h new file mode 100644 index 000000000..6577238ba --- /dev/null +++ b/Source/WebCore/css/RuleSet.h @@ -0,0 +1,157 @@ +/* + * Copyright (C) 1999 Lars Knoll (knoll@kde.org) + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. 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 + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef RuleSet_h +#define RuleSet_h + +#include "RuleFeature.h" +#include "StyleRule.h" +#include <wtf/Forward.h> +#include <wtf/HashMap.h> +#include <wtf/HashSet.h> +#include <wtf/text/AtomicString.h> + +namespace WebCore { + +class CSSSelector; +class ContainerNode; +class MediaQueryEvaluator; +class StyleResolver; +class StyleRuleRegion; +class StyleSheetContents; + +class RuleData { +public: + RuleData(StyleRule*, unsigned selectorIndex, unsigned position, bool hasDocumentSecurityOrigin, bool canUseFastCheckSelector, bool inRegionRule); + + unsigned position() const { return m_position; } + StyleRule* rule() const { return m_rule; } + CSSSelector* selector() const { return m_rule->selectorList().selectorAt(m_selectorIndex); } + unsigned selectorIndex() const { return m_selectorIndex; } + + bool hasFastCheckableSelector() const { return m_hasFastCheckableSelector; } + bool hasMultipartSelector() const { return m_hasMultipartSelector; } + bool hasRightmostSelectorMatchingHTMLBasedOnRuleHash() const { return m_hasRightmostSelectorMatchingHTMLBasedOnRuleHash; } + bool containsUncommonAttributeSelector() const { return m_containsUncommonAttributeSelector; } + unsigned specificity() const { return m_specificity; } + unsigned linkMatchType() const { return m_linkMatchType; } + bool hasDocumentSecurityOrigin() const { return m_hasDocumentSecurityOrigin; } + bool isInRegionRule() const { return m_isInRegionRule; } + + // Try to balance between memory usage (there can be lots of RuleData objects) and good filtering performance. + static const unsigned maximumIdentifierCount = 4; + const unsigned* descendantSelectorIdentifierHashes() const { return m_descendantSelectorIdentifierHashes; } + + void reportMemoryUsage(MemoryObjectInfo*) const; + +private: + StyleRule* m_rule; + unsigned m_selectorIndex : 12; + // This number was picked fairly arbitrarily. We can probably lower it if we need to. + // Some simple testing showed <100,000 RuleData's on large sites. + unsigned m_position : 20; + unsigned m_specificity : 24; + unsigned m_hasFastCheckableSelector : 1; + unsigned m_hasMultipartSelector : 1; + unsigned m_hasRightmostSelectorMatchingHTMLBasedOnRuleHash : 1; + unsigned m_containsUncommonAttributeSelector : 1; + unsigned m_linkMatchType : 2; // SelectorChecker::LinkMatchMask + unsigned m_hasDocumentSecurityOrigin : 1; + unsigned m_isInRegionRule : 1; + // Use plain array instead of a Vector to minimize memory overhead. + unsigned m_descendantSelectorIdentifierHashes[maximumIdentifierCount]; +}; + +struct SameSizeAsRuleData { + void* a; + unsigned b; + unsigned c; + unsigned d[4]; +}; + +COMPILE_ASSERT(sizeof(RuleData) == sizeof(SameSizeAsRuleData), RuleData_should_stay_small); + +class RuleSet { + WTF_MAKE_NONCOPYABLE(RuleSet); WTF_MAKE_FAST_ALLOCATED; +public: + static PassOwnPtr<RuleSet> create() { return adoptPtr(new RuleSet); } + + typedef HashMap<AtomicStringImpl*, OwnPtr<Vector<RuleData> > > AtomRuleMap; + + 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 addPageRule(StyleRulePage*); + void addToRuleSet(AtomicStringImpl* key, AtomRuleMap&, const RuleData&); + void addRegionRule(StyleRuleRegion*, bool hasDocumentSecurityOrigin); + void shrinkToFit(); + void disableAutoShrinkToFit() { m_autoShrinkToFitEnabled = false; } + + const RuleFeatureSet& features() const { return m_features; } + + const Vector<RuleData>* idRules(AtomicStringImpl* key) const { return m_idRules.get(key); } + const Vector<RuleData>* classRules(AtomicStringImpl* key) const { return m_classRules.get(key); } + const Vector<RuleData>* tagRules(AtomicStringImpl* key) const { return m_tagRules.get(key); } + const Vector<RuleData>* shadowPseudoElementRules(AtomicStringImpl* key) const { return m_shadowPseudoElementRules.get(key); } + const Vector<RuleData>* linkPseudoClassRules() const { return &m_linkPseudoClassRules; } + const Vector<RuleData>* focusPseudoClassRules() const { return &m_focusPseudoClassRules; } + const Vector<RuleData>* universalRules() const { return &m_universalRules; } + const Vector<StyleRulePage*>& pageRules() const { return m_pageRules; } + + void reportMemoryUsage(MemoryObjectInfo*) const; + +public: + RuleSet(); + + AtomRuleMap m_idRules; + AtomRuleMap m_classRules; + AtomRuleMap m_tagRules; + AtomRuleMap m_shadowPseudoElementRules; + Vector<RuleData> m_linkPseudoClassRules; + Vector<RuleData> m_focusPseudoClassRules; + Vector<RuleData> m_universalRules; + Vector<StyleRulePage*> m_pageRules; + unsigned m_ruleCount; + bool m_autoShrinkToFitEnabled; + RuleFeatureSet m_features; + + struct RuleSetSelectorPair { + RuleSetSelectorPair(CSSSelector* selector, PassOwnPtr<RuleSet> ruleSet) : selector(selector), ruleSet(ruleSet) { } + RuleSetSelectorPair(const RuleSetSelectorPair& rs) : selector(rs.selector), ruleSet(const_cast<RuleSetSelectorPair*>(&rs)->ruleSet.release()) { } + void reportMemoryUsage(MemoryObjectInfo*) const; + + CSSSelector* selector; + OwnPtr<RuleSet> ruleSet; + }; + + Vector<RuleSetSelectorPair> m_regionSelectorsAndRuleSets; +}; + +inline RuleSet::RuleSet() + : m_ruleCount(0) + , m_autoShrinkToFitEnabled(true) +{ +} + +} // namespace WebCore + +#endif // RuleSet_h diff --git a/Source/WebCore/css/SelectorChecker.cpp b/Source/WebCore/css/SelectorChecker.cpp index aae47e2cf..7a107c5c1 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 "SiblingTraversalStrategies.h" #include "StyledElement.h" #include "Text.h" #include "XLinkNames.h" @@ -266,9 +267,9 @@ bool SelectorChecker::checkSelector(CSSSelector* sel, Element* element, bool isF return fastCheckSelector(sel, element); } - PseudoId dynamicPseudo = NOPSEUDO; + PseudoId ignoreDynamicPseudo = NOPSEUDO; bool hasUnknownPseudoElements = false; - return checkSelector(SelectorCheckingContext(sel, element, SelectorChecker::VisitedMatchDisabled), dynamicPseudo, hasUnknownPseudoElements) == SelectorMatches; + return checkSelector(SelectorCheckingContext(sel, element, SelectorChecker::VisitedMatchDisabled), ignoreDynamicPseudo, hasUnknownPseudoElements) == SelectorMatches; } namespace { @@ -442,9 +443,28 @@ bool SelectorChecker::isFastCheckableSelector(const CSSSelector* selector) SelectorChecker::SelectorMatch SelectorChecker::checkSelector(const SelectorCheckingContext& context, PseudoId& dynamicPseudo, bool& hasUnknownPseudoElements) const { // first selector has to match - if (!checkOneSelector(context, dynamicPseudo, hasUnknownPseudoElements)) + 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()) + return SelectorFailsLocally; + } else { + if ((!context.elementStyle && m_mode == ResolvingStyle) || m_mode == QueryingRules) + return SelectorFailsLocally; + + PseudoId pseudoId = CSSSelector::pseudoId(context.selector->pseudoType()); + if (pseudoId == FIRST_LETTER) { + if (Document* document = context.element->document()) + document->styleSheetCollection()->setUsesFirstLetterRules(true); + } + if (pseudoId != NOPSEUDO && m_mode != SharingRules) + dynamicPseudo = pseudoId; + } + } + // The rest of the selectors has to match CSSSelector::Relation relation = context.selector->relation(); @@ -456,6 +476,7 @@ SelectorChecker::SelectorMatch SelectorChecker::checkSelector(const SelectorChec SelectorCheckingContext nextContext(context); nextContext.selector = historySelector; + PseudoId ignoreDynamicPseudo = NOPSEUDO; if (relation != CSSSelector::SubSelector) { // Abort if the next selector would exceed the scope. if (context.element == context.scope) @@ -468,6 +489,8 @@ SelectorChecker::SelectorMatch SelectorChecker::checkSelector(const SelectorChec // Disable :visited matching when we see the first link or try to match anything else than an ancestors. if (!context.isSubSelector && (context.element->isLink() || (relation != CSSSelector::Descendant && relation != CSSSelector::Child))) nextContext.visitedMatchType = VisitedMatchDisabled; + + nextContext.pseudoStyle = NOPSEUDO; } switch (relation) { @@ -477,7 +500,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, dynamicPseudo, hasUnknownPseudoElements); + SelectorMatch match = checkSelector(nextContext, ignoreDynamicPseudo, hasUnknownPseudoElements); if (match == SelectorMatches || match == SelectorFailsCompletely) return match; if (nextContext.element == nextContext.scope) @@ -492,7 +515,7 @@ SelectorChecker::SelectorMatch SelectorChecker::checkSelector(const SelectorChec nextContext.isSubSelector = false; nextContext.elementStyle = 0; nextContext.elementParentStyle = 0; - return checkSelector(nextContext, dynamicPseudo, hasUnknownPseudoElements); + return checkSelector(nextContext, ignoreDynamicPseudo, hasUnknownPseudoElements); case CSSSelector::DirectAdjacent: if (m_mode == ResolvingStyle && context.element->parentElement()) { @@ -506,7 +529,7 @@ SelectorChecker::SelectorMatch SelectorChecker::checkSelector(const SelectorChec nextContext.isSubSelector = false; nextContext.elementStyle = 0; nextContext.elementParentStyle = 0; - return checkSelector(nextContext, dynamicPseudo, hasUnknownPseudoElements); + return checkSelector(nextContext, ignoreDynamicPseudo, hasUnknownPseudoElements); case CSSSelector::IndirectAdjacent: if (m_mode == ResolvingStyle && context.element->parentElement()) { @@ -519,7 +542,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, dynamicPseudo, hasUnknownPseudoElements); + SelectorMatch match = checkSelector(nextContext, ignoreDynamicPseudo, hasUnknownPseudoElements); if (match == SelectorMatches || match == SelectorFailsAllSiblings || match == SelectorFailsCompletely) return match; }; @@ -529,8 +552,11 @@ SelectorChecker::SelectorMatch SelectorChecker::checkSelector(const SelectorChec // a selector is invalid if something follows a pseudo-element // We make an exception for scrollbar pseudo elements and allow a set of pseudo classes (but nothing else) // to follow the pseudo elements. - if ((context.elementStyle || m_mode == CollectingRules || m_mode == QueryingRules) && dynamicPseudo != NOPSEUDO && dynamicPseudo != SELECTION - && !((RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER) && nextContext.selector->m_match == CSSSelector::PseudoClass)) + nextContext.hasScrollbarPseudo = RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER; + nextContext.hasSelectionPseudo = dynamicPseudo == SELECTION; + if ((context.elementStyle || m_mode == CollectingRules || m_mode == QueryingRules) && dynamicPseudo != NOPSEUDO + && !nextContext.hasSelectionPseudo + && !(nextContext.hasScrollbarPseudo && nextContext.selector->m_match == CSSSelector::PseudoClass)) return SelectorFailsCompletely; nextContext.isSubSelector = true; return checkSelector(nextContext, dynamicPseudo, hasUnknownPseudoElements); @@ -547,7 +573,7 @@ SelectorChecker::SelectorMatch SelectorChecker::checkSelector(const SelectorChec nextContext.isSubSelector = false; nextContext.elementStyle = 0; nextContext.elementParentStyle = 0; - return checkSelector(nextContext, dynamicPseudo, hasUnknownPseudoElements); + return checkSelector(nextContext, ignoreDynamicPseudo, hasUnknownPseudoElements); } } @@ -701,7 +727,8 @@ static bool anyAttributeMatches(Element* element, CSSSelector::Match match, cons return false; } -bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, PseudoId& dynamicPseudo, bool& hasUnknownPseudoElements) const +template<typename SiblingTraversalStrategy> +bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, const SiblingTraversalStrategy& siblingTraversalStrategy) const { Element* const & element = context.element; CSSSelector* const & selector = context.selector; @@ -748,14 +775,14 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P // We select between :visited and :link when applying. We don't know which one applied (or not) yet. if (subContext.selector->pseudoType() == CSSSelector::PseudoVisited || (subContext.selector->pseudoType() == CSSSelector::PseudoLink && subContext.visitedMatchType == VisitedMatchEnabled)) return true; - if (!checkOneSelector(subContext, dynamicPseudo, hasUnknownPseudoElements)) + if (!checkOneSelector(subContext, DOMSiblingTraversalStrategy())) return true; } - } else if (dynamicPseudo != NOPSEUDO && (RenderScrollbar::scrollbarForStyleResolve() || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER)) { + } else if (context.hasScrollbarPseudo) { // CSS scrollbars match a specific subset of pseudo classes, and they have specialized rules for each // (since there are no elements involved). - return checkScrollbarPseudoClass(selector, dynamicPseudo); - } else if (dynamicPseudo == SELECTION) { + return checkScrollbarPseudoClass(selector); + } else if (context.hasSelectionPseudo) { if (selector->pseudoType() == CSSSelector::PseudoWindowInactive) return !m_document->page()->focusController()->isActive(); } @@ -792,9 +819,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P case CSSSelector::PseudoFirstChild: // first-child matches the first child that is an element if (element->parentElement()) { - bool result = false; - if (!element->previousElementSibling()) - result = true; + bool result = siblingTraversalStrategy.isFirstChild(element); if (m_mode == ResolvingStyle) { RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element->renderStyle(); RenderStyle* parentStyle = context.elementStyle ? context.elementParentStyle : element->parentNode()->renderStyle(); @@ -809,14 +834,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P case CSSSelector::PseudoFirstOfType: // first-of-type matches the first element of its type if (element->parentElement()) { - bool result = true; - const QualifiedName& type = element->tagQName(); - for (const Element* sibling = element->previousElementSibling(); sibling; sibling = sibling->previousElementSibling()) { - if (sibling->hasTagName(type)) { - result = false; - break; - } - } + bool result = siblingTraversalStrategy.isFirstOfType(element, element->tagQName()); if (m_mode == ResolvingStyle) { RenderStyle* parentStyle = context.elementStyle ? context.elementParentStyle : element->parentNode()->renderStyle(); if (parentStyle) @@ -828,7 +846,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P case CSSSelector::PseudoLastChild: // last-child matches the last child that is an element if (Element* parentElement = element->parentElement()) { - bool result = parentElement->isFinishedParsingChildren() && !element->nextElementSibling(); + bool result = parentElement->isFinishedParsingChildren() && siblingTraversalStrategy.isLastChild(element); if (m_mode == ResolvingStyle) { RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element->renderStyle(); RenderStyle* parentStyle = context.elementStyle ? context.elementParentStyle : parentElement->renderStyle(); @@ -850,19 +868,13 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P } if (!parentElement->isFinishedParsingChildren()) return false; - const QualifiedName& type = element->tagQName(); - for (const Element* sibling = element->nextElementSibling(); sibling; sibling = sibling->nextElementSibling()) { - if (sibling->hasTagName(type)) - return false; - } - return true; + return siblingTraversalStrategy.isLastOfType(element, element->tagQName()); } break; case CSSSelector::PseudoOnlyChild: if (Element* parentElement = element->parentElement()) { - bool firstChild = !element->previousElementSibling(); - bool onlyChild = firstChild && parentElement->isFinishedParsingChildren() && !element->nextElementSibling(); - + bool firstChild = siblingTraversalStrategy.isFirstChild(element); + bool onlyChild = firstChild && parentElement->isFinishedParsingChildren() && siblingTraversalStrategy.isLastChild(element); if (m_mode == ResolvingStyle) { RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element->renderStyle(); RenderStyle* parentStyle = context.elementStyle ? context.elementParentStyle : parentElement->renderStyle(); @@ -890,33 +902,14 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P } if (!parentElement->isFinishedParsingChildren()) return false; - const QualifiedName& type = element->tagQName(); - for (const Element* sibling = element->previousElementSibling(); sibling; sibling = sibling->previousElementSibling()) { - if (sibling->hasTagName(type)) - return false; - } - for (const Element* sibling = element->nextElementSibling(); sibling; sibling = sibling->nextElementSibling()) { - if (sibling->hasTagName(type)) - return false; - } - return true; + return siblingTraversalStrategy.isFirstOfType(element, element->tagQName()) && siblingTraversalStrategy.isLastOfType(element, element->tagQName()); } break; case CSSSelector::PseudoNthChild: if (!selector->parseNth()) break; if (Element* parentElement = element->parentElement()) { - int count = 1; - for (const Element* sibling = element->previousElementSibling(); sibling; sibling = sibling->previousElementSibling()) { - RenderStyle* s = sibling->renderStyle(); - unsigned index = s ? s->childIndex() : 0; - if (index) { - count += index; - break; - } - count++; - } - + int count = 1 + siblingTraversalStrategy.countElementsBefore(element); if (m_mode == ResolvingStyle) { RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element->renderStyle(); RenderStyle* parentStyle = context.elementStyle ? context.elementParentStyle : parentElement->renderStyle(); @@ -934,12 +927,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P if (!selector->parseNth()) break; if (Element* parentElement = element->parentElement()) { - int count = 1; - const QualifiedName& type = element->tagQName(); - for (const Element* sibling = element->previousElementSibling(); sibling; sibling = sibling->previousElementSibling()) { - if (sibling->hasTagName(type)) - ++count; - } + int count = 1 + siblingTraversalStrategy.countElementsOfTypeBefore(element, element->tagQName()); if (m_mode == ResolvingStyle) { RenderStyle* parentStyle = context.elementStyle ? context.elementParentStyle : parentElement->renderStyle(); if (parentStyle) @@ -961,9 +949,7 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P } if (!parentElement->isFinishedParsingChildren()) return false; - int count = 1; - for (const Element* sibling = element->nextElementSibling(); sibling; sibling = sibling->nextElementSibling()) - ++count; + int count = 1 + siblingTraversalStrategy.countElementsAfter(element); if (selector->matchNth(count)) return true; } @@ -979,12 +965,8 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P } if (!parentElement->isFinishedParsingChildren()) return false; - int count = 1; - const QualifiedName& type = element->tagQName(); - for (const Element* sibling = element->nextElementSibling(); sibling; sibling = sibling->nextElementSibling()) { - if (sibling->hasTagName(type)) - ++count; - } + + int count = 1 + siblingTraversalStrategy.countElementsOfTypeAfter(element, element->tagQName()); if (selector->matchNth(count)) return true; } @@ -997,8 +979,10 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P { 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, dynamicPseudo, hasUnknownPseudoElements) == SelectorMatches) + if (checkSelector(subContext, ignoreDynamicPseudo, hasUnknownPseudoElements) == SelectorMatches) return true; } } @@ -1172,28 +1156,11 @@ bool SelectorChecker::checkOneSelector(const SelectorCheckingContext& context, P } return false; } - if (selector->m_match == CSSSelector::PseudoElement) { - if (selector->isUnknownPseudoElement()) { - hasUnknownPseudoElements = true; - return element->shadowPseudoId() == selector->value(); - } - - if ((!context.elementStyle && m_mode == ResolvingStyle) || m_mode == QueryingRules) - return false; - - PseudoId pseudoId = CSSSelector::pseudoId(selector->pseudoType()); - if (pseudoId == FIRST_LETTER) { - if (Document* document = element->document()) - document->styleSheetCollection()->setUsesFirstLetterRules(true); - } - if (pseudoId != NOPSEUDO) - dynamicPseudo = pseudoId; - } // ### add the rest of the checks... return true; } -bool SelectorChecker::checkScrollbarPseudoClass(CSSSelector* sel, PseudoId&) const +bool SelectorChecker::checkScrollbarPseudoClass(CSSSelector* sel) const { RenderScrollbar* scrollbar = RenderScrollbar::scrollbarForStyleResolve(); ScrollbarPart part = RenderScrollbar::partForStyleResolve(); @@ -1392,4 +1359,7 @@ bool SelectorChecker::determineSelectorScopes(const CSSSelectorList& selectorLis return true; } +template +bool SelectorChecker::checkOneSelector(const SelectorChecker::SelectorCheckingContext&, const ShadowDOMSiblingTraversalStrategy&) const; + } diff --git a/Source/WebCore/css/SelectorChecker.h b/Source/WebCore/css/SelectorChecker.h index f15ce0d08..dccf563e0 100644 --- a/Source/WebCore/css/SelectorChecker.h +++ b/Source/WebCore/css/SelectorChecker.h @@ -52,7 +52,7 @@ public: enum SelectorMatch { SelectorMatches, SelectorFailsLocally, SelectorFailsAllSiblings, SelectorFailsCompletely }; enum VisitedMatchType { VisitedMatchDisabled, VisitedMatchEnabled }; - enum Mode { ResolvingStyle = 0, CollectingRules, QueryingRules }; + enum Mode { ResolvingStyle = 0, CollectingRules, QueryingRules, SharingRules }; struct SelectorCheckingContext { // Initial selector constructor @@ -61,24 +61,31 @@ public: , element(element) , scope(0) , visitedMatchType(visitedMatchType) + , pseudoStyle(NOPSEUDO) , elementStyle(0) , elementParentStyle(0) , isSubSelector(false) - , pseudoStyle(NOPSEUDO) + , hasScrollbarPseudo(false) + , hasSelectionPseudo(false) { } CSSSelector* selector; Element* element; const ContainerNode* scope; VisitedMatchType visitedMatchType; + PseudoId pseudoStyle; RenderStyle* elementStyle; RenderStyle* elementParentStyle; bool isSubSelector; - PseudoId pseudoStyle; + bool hasScrollbarPseudo; + bool hasSelectionPseudo; }; bool checkSelector(CSSSelector*, Element*, bool isFastCheckableSelector = false) const; SelectorMatch checkSelector(const SelectorCheckingContext&, PseudoId&, bool& hasUnknownPseudoElements) const; + template<typename SiblingTraversalStrategy> + bool checkOneSelector(const SelectorCheckingContext&, const SiblingTraversalStrategy&) const; + static bool isFastCheckableSelector(const CSSSelector*); bool fastCheckSelector(const CSSSelector*, const Element*) const; @@ -117,8 +124,7 @@ public: static bool elementMatchesSelectorScopes(const StyledElement*, const HashSet<AtomicStringImpl*>& idScopes, const HashSet<AtomicStringImpl*>& classScopes); private: - bool checkOneSelector(const SelectorCheckingContext&, PseudoId&, bool& hasUnknownPseudoElements) const; - bool checkScrollbarPseudoClass(CSSSelector*, PseudoId& dynamicPseudo) const; + bool checkScrollbarPseudoClass(CSSSelector*) const; static bool isFrameFocused(const Element*); bool fastCheckRightmostSelector(const CSSSelector*, const Element*, VisitedMatchType) const; diff --git a/Source/WebCore/css/SiblingTraversalStrategies.h b/Source/WebCore/css/SiblingTraversalStrategies.h new file mode 100644 index 000000000..e583e6c13 --- /dev/null +++ b/Source/WebCore/css/SiblingTraversalStrategies.h @@ -0,0 +1,274 @@ +/* + * Copyright (C) 1999 Lars Knoll (knoll@kde.org) + * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com) + * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com) + * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. + * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org> + * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org> + * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) + * Copyright (c) 2011, Code Aurora Forum. All rights reserved. + * Copyright (C) Research In Motion Limited 2011. All rights reserved. + * Copyright (C) 2012, Google, Inc. 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 + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef SiblingTraversalStrategies_h +#define SiblingTraversalStrategies_h + +#include "Element.h" +#include "RenderStyle.h" + +#include <wtf/UnusedParam.h> + +namespace WebCore { + +struct DOMSiblingTraversalStrategy { + bool isFirstChild(Element*) const; + bool isLastChild(Element*) const; + bool isFirstOfType(Element*, const QualifiedName&) const; + bool isLastOfType(Element*, const QualifiedName&) const; + + int countElementsBefore(Element*) const; + int countElementsAfter(Element*) const; + int countElementsOfTypeBefore(Element*, const QualifiedName&) const; + int countElementsOfTypeAfter(Element*, const QualifiedName&) const; +}; + +inline bool DOMSiblingTraversalStrategy::isFirstChild(Element* element) const +{ + return !element->previousElementSibling(); +} + +inline bool DOMSiblingTraversalStrategy::isLastChild(Element* element) const +{ + return !element->nextElementSibling(); +} + +inline bool DOMSiblingTraversalStrategy::isFirstOfType(Element* element, const QualifiedName& type) const +{ + for (const Element* sibling = element->previousElementSibling(); sibling; sibling = sibling->previousElementSibling()) { + if (sibling->hasTagName(type)) + return false; + } + return true; +} + +inline bool DOMSiblingTraversalStrategy::isLastOfType(Element* element, const QualifiedName& type) const +{ + for (const Element* sibling = element->nextElementSibling(); sibling; sibling = sibling->nextElementSibling()) { + if (sibling->hasTagName(type)) + return false; + } + return true; +} + +inline int DOMSiblingTraversalStrategy::countElementsBefore(Element* element) const +{ + int count = 0; + for (const Element* sibling = element->previousElementSibling(); sibling; sibling = sibling->previousElementSibling()) { + RenderStyle* s = sibling->renderStyle(); + unsigned index = s ? s->childIndex() : 0; + if (index) { + count += index; + break; + } + count++; + } + + return count; +} + +inline int DOMSiblingTraversalStrategy::countElementsOfTypeBefore(Element* element, const QualifiedName& type) const +{ + int count = 0; + for (const Element* sibling = element->previousElementSibling(); sibling; sibling = sibling->previousElementSibling()) { + if (sibling->hasTagName(type)) + ++count; + } + + return count; +} + +inline int DOMSiblingTraversalStrategy::countElementsAfter(Element* element) const +{ + int count = 0; + for (const Element* sibling = element->nextElementSibling(); sibling; sibling = sibling->nextElementSibling()) + ++count; + + return count; +} + +inline int DOMSiblingTraversalStrategy::countElementsOfTypeAfter(Element* element, const QualifiedName& type) const +{ + int count = 0; + for (const Element* sibling = element->nextElementSibling(); sibling; sibling = sibling->nextElementSibling()) { + if (sibling->hasTagName(type)) + ++count; + } + + return count; +} + +struct ShadowDOMSiblingTraversalStrategy { + ShadowDOMSiblingTraversalStrategy(const Vector<RefPtr<Node> >& siblings, int nth) + : m_siblings(siblings) + , m_nth(nth) + { + } + + bool isFirstChild(Element*) const; + bool isLastChild(Element*) const; + bool isFirstOfType(Element*, const QualifiedName&) const; + bool isLastOfType(Element*, const QualifiedName&) const; + + int countElementsBefore(Element*) const; + int countElementsAfter(Element*) const; + int countElementsOfTypeBefore(Element*, const QualifiedName&) const; + int countElementsOfTypeAfter(Element*, const QualifiedName&) const; + +private: + Vector<RefPtr<Node> > m_siblings; + int m_nth; +}; + +inline bool ShadowDOMSiblingTraversalStrategy::isFirstChild(Element* element) const +{ + UNUSED_PARAM(element); + + const Vector<RefPtr<Node> >& siblings = m_siblings; + ASSERT(element == toElement(siblings[m_nth].get())); + + for (int i = m_nth - 1; i >= 0; --i) { + if (siblings[i] && siblings[i]->isElementNode()) + return false; + } + + return true; +} + +inline bool ShadowDOMSiblingTraversalStrategy::isLastChild(Element* element) const +{ + UNUSED_PARAM(element); + + const Vector<RefPtr<Node> >& siblings = m_siblings; + ASSERT(element == toElement(siblings[m_nth].get())); + + for (size_t i = m_nth + 1; i < siblings.size(); ++i) { + if (siblings[i] && siblings[i]->isElementNode()) + return false; + } + + return true; +} + +inline bool ShadowDOMSiblingTraversalStrategy::isFirstOfType(Element* element, const QualifiedName& type) const +{ + UNUSED_PARAM(element); + + const Vector<RefPtr<Node> >& siblings = m_siblings; + ASSERT(element == toElement(siblings[m_nth].get())); + + for (int i = m_nth - 1; i >= 0; --i) { + if (siblings[i] && siblings[i]->isElementNode() && siblings[i]->hasTagName(type)) + return false; + } + + return true; +} + +inline bool ShadowDOMSiblingTraversalStrategy::isLastOfType(Element* element, const QualifiedName& type) const +{ + UNUSED_PARAM(element); + + const Vector<RefPtr<Node> >& siblings = m_siblings; + ASSERT(element == toElement(siblings[m_nth].get())); + + for (size_t i = m_nth + 1; i < siblings.size(); ++i) { + if (siblings[i] && siblings[i]->isElementNode() && siblings[i]->hasTagName(type)) + return false; + } + + return true; +} + +inline int ShadowDOMSiblingTraversalStrategy::countElementsBefore(Element* element) const +{ + UNUSED_PARAM(element); + + const Vector<RefPtr<Node> >& siblings = m_siblings; + ASSERT(element == toElement(siblings[m_nth].get())); + + int count = 0; + for (int i = m_nth - 1; i >= 0; --i) { + if (siblings[i] && siblings[i]->isElementNode()) + ++count; + } + + return count; +} + +inline int ShadowDOMSiblingTraversalStrategy::countElementsAfter(Element* element) const +{ + UNUSED_PARAM(element); + + const Vector<RefPtr<Node> >& siblings = m_siblings; + ASSERT(element == toElement(siblings[m_nth].get())); + + int count = 0; + for (size_t i = m_nth + 1; i < siblings.size(); ++i) { + if (siblings[i] && siblings[i]->isElementNode()) + return ++count; + } + + return count; +} + +inline int ShadowDOMSiblingTraversalStrategy::countElementsOfTypeBefore(Element* element, const QualifiedName& type) const +{ + UNUSED_PARAM(element); + + const Vector<RefPtr<Node> >& siblings = m_siblings; + ASSERT(element == toElement(siblings[m_nth].get())); + + int count = 0; + for (int i = m_nth - 1; i >= 0; --i) { + if (siblings[i] && siblings[i]->isElementNode() && siblings[i]->hasTagName(type)) + ++count; + } + + return count; +} + +inline int ShadowDOMSiblingTraversalStrategy::countElementsOfTypeAfter(Element* element, const QualifiedName& type) const +{ + UNUSED_PARAM(element); + + const Vector<RefPtr<Node> >& siblings = m_siblings; + ASSERT(element == toElement(siblings[m_nth].get())); + + int count = 0; + for (size_t i = m_nth + 1; i < siblings.size(); ++i) { + if (siblings[i] && siblings[i]->isElementNode() && siblings[i]->hasTagName(type)) + return ++count; + } + + return count; +} + +} + +#endif diff --git a/Source/WebCore/css/StyleBuilder.cpp b/Source/WebCore/css/StyleBuilder.cpp index 09c27b717..3129059c0 100644 --- a/Source/WebCore/css/StyleBuilder.cpp +++ b/Source/WebCore/css/StyleBuilder.cpp @@ -891,7 +891,7 @@ public: } }; -enum BorderImageType { Image = 0, Mask }; +enum BorderImageType { BorderImage = 0, BorderMask }; template <BorderImageType borderImageType, CSSPropertyID property, const NinePieceImage& (RenderStyle::*getterFunction)() const, @@ -901,7 +901,7 @@ public: static void applyValue(CSSPropertyID, StyleResolver* styleResolver, CSSValue* value) { NinePieceImage image; - if (borderImageType == Mask) + if (borderImageType == BorderMask) image.setMaskDefaults(); styleResolver->styleMap()->mapNinePieceImage(property, value, image); (styleResolver->style()->*setterFunction)(image); @@ -918,8 +918,8 @@ enum BorderImageModifierType { Outset, Repeat, Slice, Width }; template <BorderImageType type, BorderImageModifierType modifier> class ApplyPropertyBorderImageModifier { private: - static inline const NinePieceImage& getValue(RenderStyle* style) { return type == Image ? style->borderImage() : style->maskBoxImage(); } - static inline void setValue(RenderStyle* style, const NinePieceImage& value) { return type == Image ? style->setBorderImage(value) : style->setMaskBoxImage(value); } + static inline const NinePieceImage& getValue(RenderStyle* style) { return type == BorderImage ? style->borderImage() : style->maskBoxImage(); } + static inline void setValue(RenderStyle* style, const NinePieceImage& value) { return type == BorderImage ? style->setBorderImage(value) : style->setMaskBoxImage(value); } public: static void applyInheritValue(CSSPropertyID, StyleResolver* styleResolver) { @@ -954,12 +954,12 @@ public: break; case Slice: // Masks have a different initial value for slices. Preserve the value of 0 for backwards compatibility. - image.setImageSlices(type == Image ? LengthBox(Length(100, Percent), Length(100, Percent), Length(100, Percent), Length(100, Percent)) : LengthBox()); + image.setImageSlices(type == BorderImage ? LengthBox(Length(100, Percent), Length(100, Percent), Length(100, Percent), Length(100, Percent)) : LengthBox()); image.setFill(false); break; case Width: // Masks have a different initial value for widths. They use an 'auto' value rather than trying to fit to the border. - image.setBorderSlices(type == Image ? LengthBox(Length(1, Relative), Length(1, Relative), Length(1, Relative), Length(1, Relative)) : LengthBox()); + image.setBorderSlices(type == BorderImage ? LengthBox(Length(1, Relative), Length(1, Relative), Length(1, Relative), Length(1, Relative)) : LengthBox()); break; } setValue(styleResolver->style(), image); @@ -1012,11 +1012,11 @@ public: typedef CounterDirectiveMap::iterator Iterator; Iterator end = parentMap.end(); for (Iterator it = parentMap.begin(); it != end; ++it) { - CounterDirectives& directives = map.add(it->first, CounterDirectives()).iterator->second; + CounterDirectives& directives = map.add(it->key, CounterDirectives()).iterator->value; if (counterBehavior == Reset) { - directives.inheritReset(it->second); + directives.inheritReset(it->value); } else { - directives.inheritIncrement(it->second); + directives.inheritIncrement(it->value); } } } @@ -1033,9 +1033,9 @@ public: Iterator end = map.end(); for (Iterator it = map.begin(); it != end; ++it) if (counterBehavior == Reset) - it->second.clearReset(); + it->value.clearReset(); else - it->second.clearIncrement(); + it->value.clearIncrement(); int length = list ? list->length() : 0; for (int i = 0; i < length; ++i) { @@ -1049,7 +1049,7 @@ public: AtomicString identifier = static_cast<CSSPrimitiveValue*>(pair->first())->getStringValue(); int value = static_cast<CSSPrimitiveValue*>(pair->second())->getIntValue(); - CounterDirectives& directives = map.add(identifier, CounterDirectives()).iterator->second; + CounterDirectives& directives = map.add(identifier, CounterDirectives()).iterator->value; if (counterBehavior == Reset) { directives.setResetValue(value); } else { @@ -1698,6 +1698,14 @@ public: else if (primitiveValue->isShape()) { setValue(styleResolver->style(), ShapeClipPathOperation::create(basicShapeForValue(styleResolver, primitiveValue->getShapeValue()))); } +#if ENABLE(SVG) + else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_URI) { + String cssURLValue = primitiveValue->getStringValue(); + KURL url = styleResolver->document()->completeURL(cssURLValue); + // FIXME: It doesn't work with forward or external SVG references (see https://bugs.webkit.org/show_bug.cgi?id=90405) + setValue(styleResolver->style(), ReferenceClipPathOperation::create(cssURLValue, url.fragmentIdentifier())); + } +#endif } } static PropertyHandler createHandler() @@ -1709,7 +1717,7 @@ public: #if ENABLE(CSS_EXCLUSIONS) template <BasicShape* (RenderStyle::*getterFunction)() const, void (RenderStyle::*setterFunction)(PassRefPtr<BasicShape>), BasicShape* (*initialFunction)()> -class ApplyPropertyWrapShape { +class ApplyPropertyExclusionShape { public: static void setValue(RenderStyle* style, PassRefPtr<BasicShape> value) { (style->*setterFunction)(value); } static void applyValue(CSSPropertyID, StyleResolver* styleResolver, CSSValue* value) @@ -1719,8 +1727,8 @@ public: if (primitiveValue->getIdent() == CSSValueAuto) setValue(styleResolver->style(), 0); else if (primitiveValue->isShape()) { - RefPtr<BasicShape> wrapShape = basicShapeForValue(styleResolver, primitiveValue->getShapeValue()); - setValue(styleResolver->style(), wrapShape.release()); + RefPtr<BasicShape> shape = basicShapeForValue(styleResolver, primitiveValue->getShapeValue()); + setValue(styleResolver->style(), shape.release()); } } } @@ -1815,11 +1823,11 @@ StyleBuilder::StyleBuilder() setPropertyHandler(CSSPropertyBorderCollapse, ApplyPropertyDefault<EBorderCollapse, &RenderStyle::borderCollapse, EBorderCollapse, &RenderStyle::setBorderCollapse, EBorderCollapse, &RenderStyle::initialBorderCollapse>::createHandler()); setPropertyHandler(CSSPropertyBorderColor, ApplyPropertyExpanding<SuppressValue, CSSPropertyBorderTopColor, CSSPropertyBorderRightColor, CSSPropertyBorderBottomColor, CSSPropertyBorderLeftColor>::createHandler()); setPropertyHandler(CSSPropertyBorderImage, ApplyPropertyExpanding<SuppressValue, CSSPropertyBorderImageSource, CSSPropertyBorderImageSlice, CSSPropertyBorderImageWidth, CSSPropertyBorderImageOutset, CSSPropertyBorderImageRepeat>::createHandler()); - setPropertyHandler(CSSPropertyBorderImageOutset, ApplyPropertyBorderImageModifier<Image, Outset>::createHandler()); - setPropertyHandler(CSSPropertyBorderImageRepeat, ApplyPropertyBorderImageModifier<Image, Repeat>::createHandler()); - setPropertyHandler(CSSPropertyBorderImageSlice, ApplyPropertyBorderImageModifier<Image, Slice>::createHandler()); + setPropertyHandler(CSSPropertyBorderImageOutset, ApplyPropertyBorderImageModifier<BorderImage, Outset>::createHandler()); + setPropertyHandler(CSSPropertyBorderImageRepeat, ApplyPropertyBorderImageModifier<BorderImage, Repeat>::createHandler()); + setPropertyHandler(CSSPropertyBorderImageSlice, ApplyPropertyBorderImageModifier<BorderImage, Slice>::createHandler()); setPropertyHandler(CSSPropertyBorderImageSource, ApplyPropertyBorderImageSource<CSSPropertyBorderImageSource, &RenderStyle::borderImageSource, &RenderStyle::setBorderImageSource, &RenderStyle::initialBorderImageSource>::createHandler()); - setPropertyHandler(CSSPropertyBorderImageWidth, ApplyPropertyBorderImageModifier<Image, Width>::createHandler()); + setPropertyHandler(CSSPropertyBorderImageWidth, ApplyPropertyBorderImageModifier<BorderImage, Width>::createHandler()); setPropertyHandler(CSSPropertyBorderLeft, ApplyPropertyExpanding<SuppressValue, CSSPropertyBorderLeftColor, CSSPropertyBorderLeftStyle, CSSPropertyBorderLeftWidth>::createHandler()); setPropertyHandler(CSSPropertyBorderLeftColor, ApplyPropertyColor<NoInheritFromParent, &RenderStyle::borderLeftColor, &RenderStyle::setBorderLeftColor, &RenderStyle::setVisitedLinkBorderLeftColor, &RenderStyle::color>::createHandler()); setPropertyHandler(CSSPropertyBorderLeftStyle, ApplyPropertyDefault<EBorderStyle, &RenderStyle::borderLeftStyle, EBorderStyle, &RenderStyle::setBorderLeftStyle, EBorderStyle, &RenderStyle::initialBorderStyle>::createHandler()); @@ -1938,7 +1946,7 @@ StyleBuilder::StyleBuilder() #endif setPropertyHandler(CSSPropertyWebkitBorderFit, ApplyPropertyDefault<EBorderFit, &RenderStyle::borderFit, EBorderFit, &RenderStyle::setBorderFit, EBorderFit, &RenderStyle::initialBorderFit>::createHandler()); setPropertyHandler(CSSPropertyWebkitBorderHorizontalSpacing, ApplyPropertyComputeLength<short, &RenderStyle::horizontalBorderSpacing, &RenderStyle::setHorizontalBorderSpacing, &RenderStyle::initialHorizontalBorderSpacing>::createHandler()); - setPropertyHandler(CSSPropertyWebkitBorderImage, ApplyPropertyBorderImage<Image, CSSPropertyWebkitBorderImage, &RenderStyle::borderImage, &RenderStyle::setBorderImage>::createHandler()); + setPropertyHandler(CSSPropertyWebkitBorderImage, ApplyPropertyBorderImage<BorderImage, CSSPropertyWebkitBorderImage, &RenderStyle::borderImage, &RenderStyle::setBorderImage>::createHandler()); setPropertyHandler(CSSPropertyWebkitBorderRadius, CSSPropertyBorderRadius); setPropertyHandler(CSSPropertyWebkitBorderVerticalSpacing, ApplyPropertyComputeLength<short, &RenderStyle::verticalBorderSpacing, &RenderStyle::setVerticalBorderSpacing, &RenderStyle::initialVerticalBorderSpacing>::createHandler()); setPropertyHandler(CSSPropertyWebkitBoxAlign, ApplyPropertyDefault<EBoxAlignment, &RenderStyle::boxAlign, EBoxAlignment, &RenderStyle::setBoxAlign, EBoxAlignment, &RenderStyle::initialBoxAlign>::createHandler()); @@ -2003,12 +2011,12 @@ StyleBuilder::StyleBuilder() setPropertyHandler(CSSPropertyWebkitMarqueeDirection, ApplyPropertyDefault<EMarqueeDirection, &RenderStyle::marqueeDirection, EMarqueeDirection, &RenderStyle::setMarqueeDirection, EMarqueeDirection, &RenderStyle::initialMarqueeDirection>::createHandler()); setPropertyHandler(CSSPropertyWebkitMarqueeStyle, ApplyPropertyDefault<EMarqueeBehavior, &RenderStyle::marqueeBehavior, EMarqueeBehavior, &RenderStyle::setMarqueeBehavior, EMarqueeBehavior, &RenderStyle::initialMarqueeBehavior>::createHandler()); setPropertyHandler(CSSPropertyWebkitMaskAttachment, ApplyPropertyFillLayer<EFillAttachment, CSSPropertyWebkitMaskAttachment, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isAttachmentSet, &FillLayer::attachment, &FillLayer::setAttachment, &FillLayer::clearAttachment, &FillLayer::initialFillAttachment, &CSSToStyleMap::mapFillAttachment>::createHandler()); - setPropertyHandler(CSSPropertyWebkitMaskBoxImage, ApplyPropertyBorderImage<Mask, CSSPropertyWebkitMaskBoxImage, &RenderStyle::maskBoxImage, &RenderStyle::setMaskBoxImage>::createHandler()); - setPropertyHandler(CSSPropertyWebkitMaskBoxImageOutset, ApplyPropertyBorderImageModifier<Mask, Outset>::createHandler()); - setPropertyHandler(CSSPropertyWebkitMaskBoxImageRepeat, ApplyPropertyBorderImageModifier<Mask, Repeat>::createHandler()); - setPropertyHandler(CSSPropertyWebkitMaskBoxImageSlice, ApplyPropertyBorderImageModifier<Mask, Slice>::createHandler()); + setPropertyHandler(CSSPropertyWebkitMaskBoxImage, ApplyPropertyBorderImage<BorderMask, CSSPropertyWebkitMaskBoxImage, &RenderStyle::maskBoxImage, &RenderStyle::setMaskBoxImage>::createHandler()); + setPropertyHandler(CSSPropertyWebkitMaskBoxImageOutset, ApplyPropertyBorderImageModifier<BorderMask, Outset>::createHandler()); + setPropertyHandler(CSSPropertyWebkitMaskBoxImageRepeat, ApplyPropertyBorderImageModifier<BorderMask, Repeat>::createHandler()); + setPropertyHandler(CSSPropertyWebkitMaskBoxImageSlice, ApplyPropertyBorderImageModifier<BorderMask, Slice>::createHandler()); setPropertyHandler(CSSPropertyWebkitMaskBoxImageSource, ApplyPropertyBorderImageSource<CSSPropertyWebkitMaskBoxImageSource, &RenderStyle::maskBoxImageSource, &RenderStyle::setMaskBoxImageSource, &RenderStyle::initialMaskBoxImageSource>::createHandler()); - setPropertyHandler(CSSPropertyWebkitMaskBoxImageWidth, ApplyPropertyBorderImageModifier<Mask, Width>::createHandler()); + setPropertyHandler(CSSPropertyWebkitMaskBoxImageWidth, ApplyPropertyBorderImageModifier<BorderMask, Width>::createHandler()); setPropertyHandler(CSSPropertyWebkitMaskClip, ApplyPropertyFillLayer<EFillBox, CSSPropertyWebkitMaskClip, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isClipSet, &FillLayer::clip, &FillLayer::setClip, &FillLayer::clearClip, &FillLayer::initialFillClip, &CSSToStyleMap::mapFillClip>::createHandler()); setPropertyHandler(CSSPropertyWebkitMaskComposite, ApplyPropertyFillLayer<CompositeOperator, CSSPropertyWebkitMaskComposite, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isCompositeSet, &FillLayer::composite, &FillLayer::setComposite, &FillLayer::clearComposite, &FillLayer::initialFillComposite, &CSSToStyleMap::mapFillComposite>::createHandler()); setPropertyHandler(CSSPropertyWebkitMaskImage, ApplyPropertyFillLayer<StyleImage*, CSSPropertyWebkitMaskImage, MaskFillLayer, &RenderStyle::accessMaskLayers, &RenderStyle::maskLayers, &FillLayer::isImageSet, &FillLayer::image, &FillLayer::setImage, &FillLayer::clearImage, &FillLayer::initialFillImage, &CSSToStyleMap::mapFillImage>::createHandler()); @@ -2060,8 +2068,8 @@ StyleBuilder::StyleBuilder() setPropertyHandler(CSSPropertyWebkitWrapMargin, ApplyPropertyLength<&RenderStyle::wrapMargin, &RenderStyle::setWrapMargin, &RenderStyle::initialWrapMargin>::createHandler()); setPropertyHandler(CSSPropertyWebkitWrapPadding, ApplyPropertyLength<&RenderStyle::wrapPadding, &RenderStyle::setWrapPadding, &RenderStyle::initialWrapPadding>::createHandler()); setPropertyHandler(CSSPropertyWebkitWrapThrough, ApplyPropertyDefault<WrapThrough, &RenderStyle::wrapThrough, WrapThrough, &RenderStyle::setWrapThrough, WrapThrough, &RenderStyle::initialWrapThrough>::createHandler()); - setPropertyHandler(CSSPropertyWebkitShapeInside, ApplyPropertyWrapShape<&RenderStyle::wrapShapeInside, &RenderStyle::setWrapShapeInside, &RenderStyle::initialWrapShapeInside>::createHandler()); - setPropertyHandler(CSSPropertyWebkitShapeOutside, ApplyPropertyWrapShape<&RenderStyle::wrapShapeOutside, &RenderStyle::setWrapShapeOutside, &RenderStyle::initialWrapShapeOutside>::createHandler()); + setPropertyHandler(CSSPropertyWebkitShapeInside, ApplyPropertyExclusionShape<&RenderStyle::shapeInside, &RenderStyle::setShapeInside, &RenderStyle::initialShapeInside>::createHandler()); + setPropertyHandler(CSSPropertyWebkitShapeOutside, ApplyPropertyExclusionShape<&RenderStyle::shapeOutside, &RenderStyle::setShapeOutside, &RenderStyle::initialShapeOutside>::createHandler()); #endif setPropertyHandler(CSSPropertyWhiteSpace, ApplyPropertyDefault<EWhiteSpace, &RenderStyle::whiteSpace, EWhiteSpace, &RenderStyle::setWhiteSpace, EWhiteSpace, &RenderStyle::initialWhiteSpace>::createHandler()); setPropertyHandler(CSSPropertyWidows, ApplyPropertyDefault<short, &RenderStyle::widows, short, &RenderStyle::setWidows, short, &RenderStyle::initialWidows>::createHandler()); diff --git a/Source/WebCore/css/StyleMedia.idl b/Source/WebCore/css/StyleMedia.idl index 5dd58da1f..6568a2e28 100644 --- a/Source/WebCore/css/StyleMedia.idl +++ b/Source/WebCore/css/StyleMedia.idl @@ -24,11 +24,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -module view { - interface [ - JSGenerateIsReachable=ImplFrame - ] StyleMedia { - readonly attribute DOMString type; - boolean matchMedium(in [Optional=DefaultIsUndefined] DOMString mediaquery); - }; -} +[ + JSGenerateIsReachable=ImplFrame +] interface StyleMedia { + readonly attribute DOMString type; + boolean matchMedium(in [Optional=DefaultIsUndefined] DOMString mediaquery); +}; diff --git a/Source/WebCore/css/StyleResolver.cpp b/Source/WebCore/css/StyleResolver.cpp index 97cf985aa..00ed250e3 100644 --- a/Source/WebCore/css/StyleResolver.cpp +++ b/Source/WebCore/css/StyleResolver.cpp @@ -61,6 +61,7 @@ #include "CounterContent.h" #include "CursorList.h" #include "DocumentStyleSheetCollection.h" +#include "ElementShadow.h" #include "FontFeatureValue.h" #include "FontValue.h" #include "Frame.h" @@ -98,6 +99,7 @@ #include "RenderTheme.h" #include "RenderView.h" #include "RotateTransformOperation.h" +#include "RuleSet.h" #include "SVGDocumentExtensions.h" #include "SVGFontFaceElement.h" #include "ScaleTransformOperation.h" @@ -106,6 +108,7 @@ #include "ShadowData.h" #include "ShadowRoot.h" #include "ShadowValue.h" +#include "SiblingTraversalStrategies.h" #include "SkewTransformOperation.h" #include "StyleBuilder.h" #include "StyleCachedImage.h" @@ -113,6 +116,7 @@ #include "StylePendingImage.h" #include "StyleRule.h" #include "StyleRuleImport.h" +#include "StyleScopeResolver.h" #include "StyleSheetContents.h" #include "StyleSheetList.h" #include "Text.h" @@ -126,6 +130,8 @@ #include "WebKitCSSTransformValue.h" #include "WebKitFontFamilyNames.h" #include "XMLNames.h" +#include <wtf/MemoryInstrumentationHashMap.h> +#include <wtf/MemoryInstrumentationHashSet.h> #include <wtf/MemoryInstrumentationVector.h> #include <wtf/StdLibExtras.h> #include <wtf/Vector.h> @@ -135,7 +141,7 @@ #include "WebKitCSSFilterValue.h" #endif -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) +#if ENABLE(DASHBOARD_SUPPORT) #include "DashboardRegion.h" #endif @@ -167,11 +173,6 @@ #include "StyleCachedImageSet.h" #endif -#if PLATFORM(BLACKBERRY) -#define FIXED_POSITION_CREATES_STACKING_CONTEXT 1 -#endif - - using namespace std; namespace WebCore { @@ -203,113 +204,6 @@ HANDLE_INHERIT_AND_INITIAL(prop, Prop) \ if (primitiveValue) \ m_style->set##Prop(*primitiveValue); -class RuleData { -public: - RuleData(StyleRule*, unsigned selectorIndex, unsigned position, bool hasDocumentSecurityOrigin, bool canUseFastCheckSelector, bool inRegionRule); - - unsigned position() const { return m_position; } - StyleRule* rule() const { return m_rule; } - CSSSelector* selector() const { return m_rule->selectorList().selectorAt(m_selectorIndex); } - unsigned selectorIndex() const { return m_selectorIndex; } - - bool hasFastCheckableSelector() const { return m_hasFastCheckableSelector; } - bool hasMultipartSelector() const { return m_hasMultipartSelector; } - bool hasRightmostSelectorMatchingHTMLBasedOnRuleHash() const { return m_hasRightmostSelectorMatchingHTMLBasedOnRuleHash; } - bool containsUncommonAttributeSelector() const { return m_containsUncommonAttributeSelector; } - unsigned specificity() const { return m_specificity; } - unsigned linkMatchType() const { return m_linkMatchType; } - bool hasDocumentSecurityOrigin() const { return m_hasDocumentSecurityOrigin; } - bool isInRegionRule() const { return m_isInRegionRule; } - - // Try to balance between memory usage (there can be lots of RuleData objects) and good filtering performance. - static const unsigned maximumIdentifierCount = 4; - const unsigned* descendantSelectorIdentifierHashes() const { return m_descendantSelectorIdentifierHashes; } - - void reportMemoryUsage(MemoryObjectInfo*) const; - -private: - StyleRule* m_rule; - unsigned m_selectorIndex : 12; - // This number was picked fairly arbitrarily. We can probably lower it if we need to. - // Some simple testing showed <100,000 RuleData's on large sites. - unsigned m_position : 20; - unsigned m_specificity : 24; - unsigned m_hasFastCheckableSelector : 1; - unsigned m_hasMultipartSelector : 1; - unsigned m_hasRightmostSelectorMatchingHTMLBasedOnRuleHash : 1; - unsigned m_containsUncommonAttributeSelector : 1; - unsigned m_linkMatchType : 2; // SelectorChecker::LinkMatchMask - unsigned m_hasDocumentSecurityOrigin : 1; - unsigned m_isInRegionRule : 1; - // Use plain array instead of a Vector to minimize memory overhead. - unsigned m_descendantSelectorIdentifierHashes[maximumIdentifierCount]; -}; - -struct SameSizeAsRuleData { - void* a; - unsigned b; - unsigned c; - unsigned d[4]; -}; - -COMPILE_ASSERT(sizeof(RuleData) == sizeof(SameSizeAsRuleData), RuleData_should_stay_small); - -class RuleSet { - WTF_MAKE_NONCOPYABLE(RuleSet); WTF_MAKE_FAST_ALLOCATED; -public: - static PassOwnPtr<RuleSet> create() { return adoptPtr(new RuleSet); } - - typedef HashMap<AtomicStringImpl*, OwnPtr<Vector<RuleData> > > AtomRuleMap; - - 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 addPageRule(StyleRulePage*); - void addToRuleSet(AtomicStringImpl* key, AtomRuleMap&, const RuleData&); - void addRegionRule(StyleRuleRegion*, bool hasDocumentSecurityOrigin); - void shrinkToFit(); - void disableAutoShrinkToFit() { m_autoShrinkToFitEnabled = false; } - - const StyleResolver::Features& features() const { return m_features; } - - const Vector<RuleData>* idRules(AtomicStringImpl* key) const { return m_idRules.get(key); } - const Vector<RuleData>* classRules(AtomicStringImpl* key) const { return m_classRules.get(key); } - const Vector<RuleData>* tagRules(AtomicStringImpl* key) const { return m_tagRules.get(key); } - const Vector<RuleData>* shadowPseudoElementRules(AtomicStringImpl* key) const { return m_shadowPseudoElementRules.get(key); } - const Vector<RuleData>* linkPseudoClassRules() const { return &m_linkPseudoClassRules; } - const Vector<RuleData>* focusPseudoClassRules() const { return &m_focusPseudoClassRules; } - const Vector<RuleData>* universalRules() const { return &m_universalRules; } - const Vector<StyleRulePage*>& pageRules() const { return m_pageRules; } - - void reportMemoryUsage(MemoryObjectInfo*) const; - -public: - RuleSet(); - - AtomRuleMap m_idRules; - AtomRuleMap m_classRules; - AtomRuleMap m_tagRules; - AtomRuleMap m_shadowPseudoElementRules; - Vector<RuleData> m_linkPseudoClassRules; - Vector<RuleData> m_focusPseudoClassRules; - Vector<RuleData> m_universalRules; - Vector<StyleRulePage*> m_pageRules; - unsigned m_ruleCount; - bool m_autoShrinkToFitEnabled; - StyleResolver::Features m_features; - - struct RuleSetSelectorPair { - RuleSetSelectorPair(CSSSelector* selector, PassOwnPtr<RuleSet> ruleSet) : selector(selector), ruleSet(ruleSet) { } - RuleSetSelectorPair(const RuleSetSelectorPair& rs) : selector(rs.selector), ruleSet(const_cast<RuleSetSelectorPair*>(&rs)->ruleSet.release()) { } - void reportMemoryUsage(MemoryObjectInfo*) const; - - CSSSelector* selector; - OwnPtr<RuleSet> ruleSet; - }; - - Vector<RuleSetSelectorPair> m_regionSelectorsAndRuleSets; -}; static RuleSet* defaultStyle; static RuleSet* defaultQuirksStyle; @@ -391,10 +285,6 @@ StyleResolver::StyleResolver(Document* document, bool matchAuthorAndUserStyles) #if ENABLE(CSS_SHADERS) , m_hasPendingShaders(false) #endif -#if ENABLE(STYLE_SCOPED) - , m_scopeStackParent(0) - , m_scopeStackParentBoundsIndex(0) -#endif , m_styleMap(this) { Element* root = document->documentElement(); @@ -424,11 +314,7 @@ StyleResolver::StyleResolver(Document* document, bool matchAuthorAndUserStyles) if (m_rootDefaultStyle && view) m_medium = adoptPtr(new MediaQueryEvaluator(view->mediaType(), view->frame(), m_rootDefaultStyle.get())); - m_authorStyle = RuleSet::create(); - // Adding rules from multiple sheets, shrink at the end. - // Adding global rules from multiple sheets, shrink at the end. - // Note that there usually is only 1 sheet for scoped rules, so auto-shrink-to-fit is fine. - m_authorStyle->disableAutoShrinkToFit(); + resetAuthorStyle(); DocumentStyleSheetCollection* styleSheetCollection = document->styleSheetCollection(); // FIXME: This sucks! The user sheet is reparsed every time! @@ -483,7 +369,7 @@ void StyleResolver::addAuthorRulesAndCollectUserRulesFromSheets(const Vector<Ref } } -static PassOwnPtr<RuleSet> makeRuleSet(const Vector<StyleResolver::RuleFeature>& rules) +static PassOwnPtr<RuleSet> makeRuleSet(const Vector<RuleFeature>& rules) { size_t size = rules.size(); if (!size) @@ -503,10 +389,8 @@ void StyleResolver::collectFeatures() // sharing candidates. m_features.add(defaultStyle->features()); m_features.add(m_authorStyle->features()); -#if ENABLE(STYLE_SCOPED) - for (ScopedRuleSetMap::iterator it = m_scopedAuthorStyles.begin(); it != m_scopedAuthorStyles.end(); ++it) - m_features.add(it->second->features()); -#endif + if (m_scopeResolver) + m_scopeResolver->collectFeaturesTo(m_features); if (m_userStyle) m_features.add(m_userStyle->features()); @@ -514,37 +398,11 @@ void StyleResolver::collectFeatures() m_uncommonAttributeRuleSet = makeRuleSet(m_features.uncommonAttributeRules); } -#if ENABLE(STYLE_SCOPED) -const ContainerNode* StyleResolver::determineScope(const CSSStyleSheet* sheet) +void StyleResolver::resetAuthorStyle() { - ASSERT(sheet); - - if (!ContextFeatures::styleScopedEnabled(document())) - return 0; - - Node* ownerNode = sheet->ownerNode(); - if (!ownerNode || !ownerNode->isHTMLElement() || !ownerNode->hasTagName(HTMLNames::styleTag)) - return 0; - - HTMLStyleElement* styleElement = static_cast<HTMLStyleElement*>(ownerNode); - if (!styleElement->scoped()) - return styleElement->isInShadowTree()? styleElement->shadowRoot() : 0; - - ContainerNode* parent = styleElement->parentNode(); - if (!parent) - return 0; - - return (parent->isElementNode() || parent->isShadowRoot()) ? parent : 0; -} - -inline RuleSet* StyleResolver::ruleSetForScope(const ContainerNode* scope) const -{ - if (!scope->hasScopedHTMLStyleChild()) - return 0; - ScopedRuleSetMap::const_iterator it = m_scopedAuthorStyles.find(scope); - return it != m_scopedAuthorStyles.end() ? it->second.get() : 0; + m_authorStyle = RuleSet::create(); + m_authorStyle->disableAutoShrinkToFit(); } -#endif void StyleResolver::appendAuthorStylesheets(unsigned firstNew, const Vector<RefPtr<StyleSheet> >& stylesheets) { @@ -560,16 +418,13 @@ 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) - const ContainerNode* scope = determineScope(cssSheet); - if (scope) { - ScopedRuleSetMap::AddResult addResult = m_scopedAuthorStyles.add(scope, nullptr); - if (addResult.isNewEntry) - addResult.iterator->second = RuleSet::create(); - addResult.iterator->second->addRulesFromSheet(sheet, *m_medium, this, scope); + 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); continue; } -#endif + m_authorStyle->addRulesFromSheet(sheet, *m_medium, this); if (!m_styleRuleToCSSOMWrapperMap.isEmpty()) collectCSSOMWrappers(m_styleRuleToCSSOMWrapperMap, cssSheet); @@ -581,62 +436,6 @@ void StyleResolver::appendAuthorStylesheets(unsigned firstNew, const Vector<RefP document()->renderer()->style()->font().update(fontSelector()); } -#if ENABLE(STYLE_SCOPED) -void StyleResolver::setupScopeStack(const ContainerNode* parent) -{ - // The scoping element stack shouldn't be used if <style scoped> isn't used anywhere. - ASSERT(!m_scopedAuthorStyles.isEmpty()); - - m_scopeStack.shrink(0); - int authorStyleBoundsIndex = 0; - for (const ContainerNode* scope = parent; scope; scope = scope->parentOrHostNode()) { - RuleSet* ruleSet = ruleSetForScope(scope); - if (ruleSet) - m_scopeStack.append(ScopeStackFrame(scope, authorStyleBoundsIndex, ruleSet)); - if (scope->isShadowRoot() && !toShadowRoot(scope)->applyAuthorStyles()) - --authorStyleBoundsIndex; - } - m_scopeStack.reverse(); - m_scopeStackParent = parent; - m_scopeStackParentBoundsIndex = 0; -} - -void StyleResolver::pushScope(const ContainerNode* scope, const ContainerNode* scopeParent) -{ - // Shortcut: Don't bother with the scoping element stack if <style scoped> isn't used anywhere. - if (m_scopedAuthorStyles.isEmpty()) { - ASSERT(!m_scopeStackParent); - ASSERT(m_scopeStack.isEmpty()); - return; - } - // In some wacky cases during style resolve we may get invoked for random elements. - // Recreate the whole scoping element stack in such cases. - if (!scopeStackIsConsistent(scopeParent)) { - setupScopeStack(scope); - return; - } - if (scope->isShadowRoot() && !toShadowRoot(scope)->applyAuthorStyles()) - ++m_scopeStackParentBoundsIndex; - // Otherwise just push the parent onto the stack. - RuleSet* ruleSet = ruleSetForScope(scope); - if (ruleSet) - m_scopeStack.append(ScopeStackFrame(scope, m_scopeStackParentBoundsIndex, ruleSet)); - m_scopeStackParent = scope; -} - -void StyleResolver::popScope(const ContainerNode* scope) -{ - // Only bother to update the scoping element stack if it is consistent. - if (scopeStackIsConsistent(scope)) { - if (!m_scopeStack.isEmpty() && m_scopeStack.last().m_scope == scope) - m_scopeStack.removeLast(); - if (scope->isShadowRoot() && !toShadowRoot(scope)->applyAuthorStyles()) - --m_scopeStackParentBoundsIndex; - m_scopeStackParent = scope->parentOrHostNode(); - } -} -#endif - void StyleResolver::pushParentElement(Element* parent) { const ContainerNode* parentsParent = parent->parentOrHostElement(); @@ -651,7 +450,8 @@ void StyleResolver::pushParentElement(Element* parent) m_checker.pushParent(parent); // Note: We mustn't skip ShadowRoot nodes for the scope stack. - pushScope(parent, parent->parentOrHostNode()); + if (m_scopeResolver) + m_scopeResolver->push(parent, parent->parentOrHostNode()); } void StyleResolver::popParentElement(Element* parent) @@ -660,19 +460,22 @@ void StyleResolver::popParentElement(Element* parent) // Pause maintaining the stack in this case. if (m_checker.parentStackIsConsistent(parent)) m_checker.popParent(); - popScope(parent); + if (m_scopeResolver) + m_scopeResolver->pop(parent); } void StyleResolver::pushParentShadowRoot(const ShadowRoot* shadowRoot) { ASSERT(shadowRoot->host()); - pushScope(shadowRoot, shadowRoot->host()); + if (m_scopeResolver) + m_scopeResolver->push(shadowRoot, shadowRoot->host()); } void StyleResolver::popParentShadowRoot(const ShadowRoot* shadowRoot) { ASSERT(shadowRoot->host()); - popScope(shadowRoot); + if (m_scopeResolver) + m_scopeResolver->pop(shadowRoot); } // This is a simplified style setting function for keyframe styles @@ -696,10 +499,10 @@ void StyleResolver::sweepMatchedPropertiesCache() MatchedPropertiesCache::iterator it = m_matchedPropertiesCache.begin(); MatchedPropertiesCache::iterator end = m_matchedPropertiesCache.end(); for (; it != end; ++it) { - Vector<MatchedProperties>& matchedProperties = it->second.matchedProperties; + Vector<MatchedProperties>& matchedProperties = it->value.matchedProperties; for (size_t i = 0; i < matchedProperties.size(); ++i) { if (matchedProperties[i].properties->hasOneRef()) { - toRemove.append(it->first); + toRemove.append(it->key); break; } } @@ -708,49 +511,6 @@ void StyleResolver::sweepMatchedPropertiesCache() m_matchedPropertiesCache.remove(toRemove[i]); } -StyleResolver::Features::Features() - : usesFirstLineRules(false) - , usesBeforeAfterRules(false) -{ -} - -StyleResolver::Features::~Features() -{ -} - -void StyleResolver::Features::add(const StyleResolver::Features& other) -{ - HashSet<AtomicStringImpl*>::iterator end = other.idsInRules.end(); - for (HashSet<AtomicStringImpl*>::iterator it = other.idsInRules.begin(); it != end; ++it) - idsInRules.add(*it); - end = other.attrsInRules.end(); - for (HashSet<AtomicStringImpl*>::iterator it = other.attrsInRules.begin(); it != end; ++it) - attrsInRules.add(*it); - siblingRules.append(other.siblingRules); - uncommonAttributeRules.append(other.uncommonAttributeRules); - usesFirstLineRules = usesFirstLineRules || other.usesFirstLineRules; - usesBeforeAfterRules = usesBeforeAfterRules || other.usesBeforeAfterRules; -} - -void StyleResolver::Features::clear() -{ - idsInRules.clear(); - attrsInRules.clear(); - siblingRules.clear(); - uncommonAttributeRules.clear(); - usesFirstLineRules = false; - usesBeforeAfterRules = false; -} - -void StyleResolver::Features::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const -{ - MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS); - info.addHashSet(idsInRules); - info.addHashSet(attrsInRules); - info.addMember(siblingRules); - info.addMember(uncommonAttributeRules); -} - static StyleSheetContents* parseUASheet(const String& str) { StyleSheetContents* sheet = StyleSheetContents::create().leakRef(); // leak the sheet on purpose @@ -954,45 +714,33 @@ void StyleResolver::sortAndTransferMatchedRules(MatchResult& result) void StyleResolver::matchScopedAuthorRules(MatchResult& result, bool includeEmptyRules) { -#if ENABLE(STYLE_SCOPED) - if (m_scopedAuthorStyles.isEmpty()) +#if ENABLE(STYLE_SCOPED) || ENABLE(SHADOW_DOM) + if (!m_scopeResolver || !m_scopeResolver->hasScopedStyles()) return; - MatchOptions options(includeEmptyRules); - // Match scoped author rules by traversing the scoped element stack (rebuild it if it got inconsistent). - if (!scopeStackIsConsistent(m_element)) - setupScopeStack(m_element); - - unsigned int firstShadowScopeIndex = 0; - if (m_element->treeScope()->applyAuthorStyles()) { - unsigned i; - for (i = 0; i < m_scopeStack.size() && !m_scopeStack[i].m_scope->isInShadowTree(); ++i) { - const ScopeStackFrame& frame = m_scopeStack[i]; - options.scope = frame.m_scope; - collectMatchingRules(frame.m_ruleSet, result.ranges.firstAuthorRule, result.ranges.lastAuthorRule, options); - collectMatchingRulesForRegion(frame.m_ruleSet, result.ranges.firstAuthorRule, result.ranges.lastAuthorRule, options); - } - firstShadowScopeIndex = i; - } - - if (!m_element->isInShadowTree() || m_scopeStack.isEmpty()) + if (!m_scopeResolver->ensureStackConsistency(m_element)) return; - unsigned scopedIndex = m_scopeStack.size(); - int authorStyleBoundsIndex = m_scopeStackParentBoundsIndex; - for ( ; scopedIndex > firstShadowScopeIndex; --scopedIndex) { - if (authorStyleBoundsIndex != m_scopeStack[scopedIndex - 1].m_authorStyleBoundsIndex) - break; - } - - // Ruleset for ancestor nodes should be applied first. - for (unsigned i = scopedIndex; i < m_scopeStack.size(); ++i) { - const ScopeStackFrame& frame = m_scopeStack[i]; - options.scope = frame.m_scope; + bool applyAuthorStyles = m_element->treeScope()->applyAuthorStyles(); + bool documentScope = true; + unsigned scopeSize = m_scopeResolver->stackSize(); + for (unsigned i = 0; i < scopeSize; ++i) { + const StyleScopeResolver::StackFrame& frame = m_scopeResolver->stackFrameAt(i); + documentScope = documentScope && !frame.m_scope->isInShadowTree(); + if (documentScope) { + if (!applyAuthorStyles) + continue; + } else { + if (!m_scopeResolver->matchesStyleBounds(frame)) + continue; + } + + MatchOptions options(includeEmptyRules, frame.m_scope); collectMatchingRules(frame.m_ruleSet, result.ranges.firstAuthorRule, result.ranges.lastAuthorRule, options); collectMatchingRulesForRegion(frame.m_ruleSet, result.ranges.firstAuthorRule, result.ranges.lastAuthorRule, options); } + #else UNUSED_PARAM(result); UNUSED_PARAM(includeEmptyRules); @@ -1089,11 +837,7 @@ void StyleResolver::collectMatchingRulesForList(const Vector<RuleData>* rules, i StyleRule* rule = ruleData.rule(); InspectorInstrumentationCookie cookie = InspectorInstrumentation::willMatchRule(document(), rule); -#if ENABLE(STYLE_SCOPED) if (checkSelector(ruleData, options.scope)) { -#else - if (checkSelector(ruleData)) { -#endif // 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 @@ -1101,9 +845,7 @@ void StyleResolver::collectMatchingRulesForList(const Vector<RuleData>* rules, i // d) the rule contains shadow-ID pseudo elements if (!MatchingUARulesScope::isMatchingUARules() && !treeScope->applyAuthorStyles() -#if ENABLE(STYLE_SCOPED) && (!options.scope || options.scope->treeScope() != treeScope) -#endif && !m_hasUnknownPseudoElements) { InspectorInstrumentation::didMatchRule(cookie, false); @@ -1217,6 +959,27 @@ inline void StyleResolver::initElement(Element* e) } } +inline bool shouldResetStyleInheritance(NodeRenderingContext& context) +{ + if (context.resetStyleInheritance()) + return true; + + InsertionPoint* insertionPoint = context.insertionPoint(); + if (!insertionPoint) + return false; + ASSERT(context.node()->parentElement()); + ElementShadow* shadow = context.node()->parentElement()->shadow(); + ASSERT(shadow); + + for ( ; insertionPoint; ) { + InsertionPoint* youngerInsertionPoint = shadow->insertionPointFor(insertionPoint); + if (!youngerInsertionPoint) + break; + insertionPoint = youngerInsertionPoint; + } + return insertionPoint->resetStyleInheritance(); +} + inline void StyleResolver::initForStyleResolve(Element* e, RenderStyle* parentStyle, PseudoId pseudoID) { m_pseudoStyle = pseudoID; @@ -1224,7 +987,7 @@ inline void StyleResolver::initForStyleResolve(Element* e, RenderStyle* parentSt if (e) { NodeRenderingContext context(e); m_parentNode = context.parentNodeForRenderingAndStyle(); - m_parentStyle = context.resetStyleInheritance()? 0 : + m_parentStyle = shouldResetStyleInheritance(context) ? 0 : parentStyle ? parentStyle : m_parentNode ? m_parentNode->renderStyle() : 0; m_distributedToInsertionPoint = context.insertionPoint(); @@ -1256,10 +1019,8 @@ Node* StyleResolver::locateCousinList(Element* parent, unsigned& visitedNodeCoun return 0; if (!parent || !parent->isStyledElement()) return 0; -#if ENABLE(STYLE_SCOPED) if (parent->hasScopedHTMLStyleChild()) return 0; -#endif StyledElement* p = static_cast<StyledElement*>(parent); if (p->inlineStyle()) return 0; @@ -1297,15 +1058,16 @@ Node* StyleResolver::locateCousinList(Element* parent, unsigned& visitedNodeCoun return 0; } -bool StyleResolver::matchesRuleSet(RuleSet* ruleSet) +bool StyleResolver::styleSharingCandidateMatchesRuleSet(RuleSet* ruleSet) { if (!ruleSet) return false; m_matchedRules.clear(); int firstRuleIndex = -1, lastRuleIndex = -1; + m_checker.setMode(SelectorChecker::SharingRules); collectMatchingRules(ruleSet, firstRuleIndex, lastRuleIndex, false); - + m_checker.setMode(SelectorChecker::ResolvingStyle); if (m_matchedRules.isEmpty()) return false; m_matchedRules.clear(); @@ -1439,14 +1201,10 @@ bool StyleResolver::canShareStyleWithElement(StyledElement* element) const return false; if (element->fastGetAttribute(cellpaddingAttr) != m_element->fastGetAttribute(cellpaddingAttr)) return false; - if (element->hasID() && m_features.idsInRules.contains(element->idForStyleResolution().impl())) return false; - -#if ENABLE(STYLE_SCOPED) if (element->hasScopedHTMLStyleChild()) return false; -#endif #if ENABLE(PROGRESS_ELEMENT) if (element->hasTagName(progressTag)) { @@ -1480,7 +1238,7 @@ bool StyleResolver::canShareStyleWithElement(StyledElement* element) const #if USE(ACCELERATED_COMPOSITING) // Turn off style sharing for elements that can gain layers for reasons outside of the style system. // See comments in RenderObject::setStyle(). - if (element->hasTagName(iframeTag) || element->hasTagName(frameTag) || element->hasTagName(embedTag) || element->hasTagName(objectTag) || element->hasTagName(appletTag) + if (element->hasTagName(iframeTag) || element->hasTagName(frameTag) || element->hasTagName(embedTag) || element->hasTagName(objectTag) || element->hasTagName(appletTag) || element->hasTagName(canvasTag) #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) // With proxying, the media elements are backed by a RenderEmbeddedObject. || element->hasTagName(videoTag) || element->hasTagName(audioTag) @@ -1553,10 +1311,8 @@ RenderStyle* StyleResolver::locateSharedStyle() return 0; if (parentStylePreventsSharing(m_parentStyle)) return 0; -#if ENABLE(STYLE_SCOPED) if (m_styledElement->hasScopedHTMLStyleChild()) return 0; -#endif // Check previous siblings and their cousins. unsigned count = 0; @@ -1575,10 +1331,10 @@ RenderStyle* StyleResolver::locateSharedStyle() return 0; // Can't share if sibling rules apply. This is checked at the end as it should rarely fail. - if (matchesRuleSet(m_siblingRuleSet.get())) + if (styleSharingCandidateMatchesRuleSet(m_siblingRuleSet.get())) return 0; // Can't share if attribute rules apply. - if (matchesRuleSet(m_uncommonAttributeRuleSet.get())) + if (styleSharingCandidateMatchesRuleSet(m_uncommonAttributeRuleSet.get())) 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)) @@ -1878,7 +1634,7 @@ void StyleResolver::keyframeStylesForAnimation(Element* e, const RenderStyle* el if (it == m_keyframesRuleMap.end()) return; - const StyleRuleKeyframes* keyframesRule = it->second.get(); + const StyleRuleKeyframes* keyframesRule = it->value.get(); // Construct and populate the style for each keyframe const Vector<RefPtr<StyleKeyframe> >& keyframes = keyframesRule->keyframes(); @@ -2198,11 +1954,7 @@ void StyleResolver::adjustRenderStyle(RenderStyle* style, RenderStyle* parentSty || style->hasFilter() || style->hasBlendMode() || style->position() == StickyPosition -#ifdef FIXED_POSITION_CREATES_STACKING_CONTEXT - || style->position() == FixedPosition -#else || (style->position() == FixedPosition && e && e->document()->page() && e->document()->page()->settings()->fixedPositionCreatesStackingContext()) -#endif #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING) // Touch overflow scrolling creates a stacking context. || ((style->overflowX() != OHIDDEN || style->overflowY() != OHIDDEN) && style->useTouchOverflowScrolling()) @@ -2478,339 +2230,6 @@ bool StyleResolver::determineStylesheetSelectorScopes(StyleSheetContents* styles return true; } -// ----------------------------------------------------------------- - -static inline bool isSelectorMatchingHTMLBasedOnRuleHash(const CSSSelector* selector) -{ - const AtomicString& selectorNamespace = selector->tag().namespaceURI(); - if (selectorNamespace != starAtom && selectorNamespace != xhtmlNamespaceURI) - return false; - if (selector->m_match == CSSSelector::None) - return true; - if (selector->tag() != starAtom) - return false; - if (SelectorChecker::isCommonPseudoClassSelector(selector)) - return true; - return selector->m_match == CSSSelector::Id || selector->m_match == CSSSelector::Class; -} - -static inline bool selectorListContainsUncommonAttributeSelector(const CSSSelector* selector) -{ - CSSSelectorList* selectorList = selector->selectorList(); - if (!selectorList) - return false; - for (CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) { - if (subSelector->isAttributeSelector()) - return true; - } - return false; -} - -static inline bool isCommonAttributeSelectorAttribute(const QualifiedName& attribute) -{ - // These are explicitly tested for equality in canShareStyleWithElement. - return attribute == typeAttr || attribute == readonlyAttr; -} - -static inline bool containsUncommonAttributeSelector(const CSSSelector* selector) -{ - for (; selector; selector = selector->tagHistory()) { - // Allow certain common attributes (used in the default style) in the selectors that match the current element. - if (selector->isAttributeSelector() && !isCommonAttributeSelectorAttribute(selector->attribute())) - return true; - if (selectorListContainsUncommonAttributeSelector(selector)) - return true; - if (selector->relation() != CSSSelector::SubSelector) { - selector = selector->tagHistory(); - break; - } - } - - for (; selector; selector = selector->tagHistory()) { - if (selector->isAttributeSelector()) - return true; - if (selectorListContainsUncommonAttributeSelector(selector)) - return true; - } - return false; -} - -RuleData::RuleData(StyleRule* rule, unsigned selectorIndex, unsigned position, bool hasDocumentSecurityOrigin, bool canUseFastCheckSelector, bool inRegionRule) - : m_rule(rule) - , m_selectorIndex(selectorIndex) - , m_position(position) - , m_specificity(selector()->specificity()) - , m_hasFastCheckableSelector(canUseFastCheckSelector && 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) -{ - ASSERT(m_position == position); - ASSERT(m_selectorIndex == selectorIndex); - SelectorChecker::collectIdentifierHashes(selector(), m_descendantSelectorIdentifierHashes, maximumIdentifierCount); -} - -void RuleData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const -{ - MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS); -} - -RuleSet::RuleSet() - : m_ruleCount(0) - , m_autoShrinkToFitEnabled(true) -{ -} - -static void reportAtomRuleMap(MemoryClassInfo* info, const RuleSet::AtomRuleMap& atomicRuleMap) -{ - info->addHashMap(atomicRuleMap); - for (RuleSet::AtomRuleMap::const_iterator it = atomicRuleMap.begin(); it != atomicRuleMap.end(); ++it) - info->addMember(*it->second); -} - -void RuleSet::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const -{ - MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS); - reportAtomRuleMap(&info, m_idRules); - reportAtomRuleMap(&info, m_classRules); - reportAtomRuleMap(&info, m_tagRules); - reportAtomRuleMap(&info, m_shadowPseudoElementRules); - info.addMember(m_linkPseudoClassRules); - info.addMember(m_focusPseudoClassRules); - info.addMember(m_universalRules); - info.addMember(m_pageRules); - info.addMember(m_regionSelectorsAndRuleSets); -} - -void RuleSet::RuleSetSelectorPair::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const -{ - MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS); - info.addMember(ruleSet); -} - -static inline void collectFeaturesFromSelector(StyleResolver::Features& features, const CSSSelector* selector) -{ - if (selector->m_match == CSSSelector::Id) - features.idsInRules.add(selector->value().impl()); - if (selector->isAttributeSelector()) - features.attrsInRules.add(selector->attribute().localName().impl()); - switch (selector->pseudoType()) { - case CSSSelector::PseudoFirstLine: - features.usesFirstLineRules = true; - break; - case CSSSelector::PseudoBefore: - case CSSSelector::PseudoAfter: - features.usesBeforeAfterRules = true; - break; - default: - break; - } -} - -static void collectFeaturesFromRuleData(StyleResolver::Features& features, const RuleData& ruleData) -{ - bool foundSiblingSelector = false; - for (CSSSelector* selector = ruleData.selector(); selector; selector = selector->tagHistory()) { - collectFeaturesFromSelector(features, selector); - - if (CSSSelectorList* selectorList = selector->selectorList()) { - for (CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) { - if (!foundSiblingSelector && selector->isSiblingSelector()) - foundSiblingSelector = true; - collectFeaturesFromSelector(features, subSelector); - } - } else if (!foundSiblingSelector && selector->isSiblingSelector()) - foundSiblingSelector = true; - } - if (foundSiblingSelector) - features.siblingRules.append(StyleResolver::RuleFeature(ruleData.rule(), ruleData.selectorIndex(), ruleData.hasDocumentSecurityOrigin())); - if (ruleData.containsUncommonAttributeSelector()) - features.uncommonAttributeRules.append(StyleResolver::RuleFeature(ruleData.rule(), ruleData.selectorIndex(), ruleData.hasDocumentSecurityOrigin())); -} - -void RuleSet::addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map, const RuleData& ruleData) -{ - if (!key) - return; - OwnPtr<Vector<RuleData> >& rules = map.add(key, nullptr).iterator->second; - if (!rules) - rules = adoptPtr(new Vector<RuleData>); - rules->append(ruleData); -} - -void RuleSet::addRule(StyleRule* rule, unsigned selectorIndex, bool hasDocumentSecurityOrigin, bool canUseFastCheckSelector, bool inRegionRule) -{ - RuleData ruleData(rule, selectorIndex, m_ruleCount++, hasDocumentSecurityOrigin, canUseFastCheckSelector, inRegionRule); - collectFeaturesFromRuleData(m_features, ruleData); - - CSSSelector* selector = ruleData.selector(); - - if (selector->m_match == CSSSelector::Id) { - addToRuleSet(selector->value().impl(), m_idRules, ruleData); - return; - } - if (selector->m_match == CSSSelector::Class) { - addToRuleSet(selector->value().impl(), m_classRules, ruleData); - return; - } - if (selector->isUnknownPseudoElement()) { - addToRuleSet(selector->value().impl(), m_shadowPseudoElementRules, ruleData); - return; - } - if (SelectorChecker::isCommonPseudoClassSelector(selector)) { - switch (selector->pseudoType()) { - case CSSSelector::PseudoLink: - case CSSSelector::PseudoVisited: - case CSSSelector::PseudoAnyLink: - m_linkPseudoClassRules.append(ruleData); - return; - case CSSSelector::PseudoFocus: - m_focusPseudoClassRules.append(ruleData); - return; - default: - ASSERT_NOT_REACHED(); - } - return; - } - const AtomicString& localName = selector->tag().localName(); - if (localName != starAtom) { - addToRuleSet(localName.impl(), m_tagRules, ruleData); - return; - } - m_universalRules.append(ruleData); -} - -void RuleSet::addPageRule(StyleRulePage* rule) -{ - m_pageRules.append(rule); -} - -void RuleSet::addRegionRule(StyleRuleRegion* regionRule, bool hasDocumentSecurityOrigin) -{ - OwnPtr<RuleSet> regionRuleSet = RuleSet::create(); - // The region rule set should take into account the position inside the parent rule set. - // Otherwise, the rules inside region block might be incorrectly positioned before other similar rules from - // the stylesheet that contains the region block. - regionRuleSet->m_ruleCount = m_ruleCount; - - // Collect the region rules into a rule set - const Vector<RefPtr<StyleRuleBase> >& childRules = regionRule->childRules(); - 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); - } - // Update the "global" rule count so that proper order is maintained - m_ruleCount = regionRuleSet->m_ruleCount; - - m_regionSelectorsAndRuleSets.append(RuleSetSelectorPair(regionRule->selectorList().first(), regionRuleSet.release())); -} - -void RuleSet::addRulesFromSheet(StyleSheetContents* sheet, const MediaQueryEvaluator& medium, StyleResolver* resolver, const ContainerNode* scope) -{ - ASSERT(sheet); - - const Vector<RefPtr<StyleRuleImport> >& importRules = sheet->importRules(); - for (unsigned i = 0; i < importRules.size(); ++i) { - StyleRuleImport* importRule = importRules[i].get(); - if (importRule->styleSheet() && (!importRule->mediaQueries() || medium.eval(importRule->mediaQueries(), resolver))) - addRulesFromSheet(importRule->styleSheet(), medium, resolver, scope); - } - bool hasDocumentSecurityOrigin = resolver && resolver->document()->securityOrigin()->canRequest(sheet->baseURL()); - - const Vector<RefPtr<StyleRuleBase> >& rules = sheet->childRules(); - for (unsigned i = 0; i < rules.size(); ++i) { - StyleRuleBase* rule = rules[i].get(); - - ASSERT(!rule->isImportRule()); - if (rule->isStyleRule()) - addStyleRule(static_cast<StyleRule*>(rule), hasDocumentSecurityOrigin, !scope); - else if (rule->isPageRule()) - addPageRule(static_cast<StyleRulePage*>(rule)); - else if (rule->isMediaRule()) { - StyleRuleMedia* mediaRule = static_cast<StyleRuleMedia*>(rule); - - if ((!mediaRule->mediaQueries() || medium.eval(mediaRule->mediaQueries(), resolver))) { - // Traverse child elements of the @media rule. - const Vector<RefPtr<StyleRuleBase> >& childRules = mediaRule->childRules(); - for (unsigned j = 0; j < childRules.size(); ++j) { - StyleRuleBase* childRule = childRules[j].get(); - if (childRule->isStyleRule()) - addStyleRule(static_cast<StyleRule*>(childRule), hasDocumentSecurityOrigin, !scope); - else if (childRule->isPageRule()) - addPageRule(static_cast<StyleRulePage*>(childRule)); - else if (childRule->isFontFaceRule() && resolver) { - // Add this font face to our set. - // FIXME(BUG 72461): We don't add @font-face rules of scoped style sheets for the moment. - if (scope) - continue; - const StyleRuleFontFace* fontFaceRule = static_cast<StyleRuleFontFace*>(childRule); - resolver->fontSelector()->addFontFaceRule(fontFaceRule); - resolver->invalidateMatchedPropertiesCache(); - } else if (childRule->isKeyframesRule() && resolver) { - // Add this keyframe rule to our set. - // FIXME(BUG 72462): We don't add @keyframe rules of scoped style sheets for the moment. - if (scope) - continue; - resolver->addKeyframeStyle(static_cast<StyleRuleKeyframes*>(childRule)); - } - } // for rules - } // if rules - } else if (rule->isFontFaceRule() && resolver) { - // Add this font face to our set. - // FIXME(BUG 72461): We don't add @font-face rules of scoped style sheets for the moment. - if (scope) - continue; - const StyleRuleFontFace* fontFaceRule = static_cast<StyleRuleFontFace*>(rule); - resolver->fontSelector()->addFontFaceRule(fontFaceRule); - resolver->invalidateMatchedPropertiesCache(); - } else if (rule->isKeyframesRule() && resolver) { - // FIXME (BUG 72462): We don't add @keyframe rules of scoped style sheets for the moment. - if (scope) - continue; - resolver->addKeyframeStyle(static_cast<StyleRuleKeyframes*>(rule)); - } -#if ENABLE(CSS_REGIONS) - else if (rule->isRegionRule() && resolver) { - // FIXME (BUG 72472): We don't add @-webkit-region rules of scoped style sheets for the moment. - if (scope) - continue; - addRegionRule(static_cast<StyleRuleRegion*>(rule), hasDocumentSecurityOrigin); - } -#endif - } - if (m_autoShrinkToFitEnabled) - shrinkToFit(); -} - -void RuleSet::addStyleRule(StyleRule* rule, bool hasDocumentSecurityOrigin, bool canUseFastCheckSelector, bool isInRegionRule) -{ - for (size_t selectorIndex = 0; selectorIndex != notFound; selectorIndex = rule->selectorList().indexOfNextSelectorAfter(selectorIndex)) - addRule(rule, selectorIndex, hasDocumentSecurityOrigin, canUseFastCheckSelector, isInRegionRule); -} - -static inline void shrinkMapVectorsToFit(RuleSet::AtomRuleMap& map) -{ - RuleSet::AtomRuleMap::iterator end = map.end(); - for (RuleSet::AtomRuleMap::iterator it = map.begin(); it != end; ++it) - it->second->shrinkToFit(); -} - -void RuleSet::shrinkToFit() -{ - shrinkMapVectorsToFit(m_idRules); - shrinkMapVectorsToFit(m_classRules); - shrinkMapVectorsToFit(m_tagRules); - shrinkMapVectorsToFit(m_shadowPseudoElementRules); - m_linkPseudoClassRules.shrinkToFit(); - m_focusPseudoClassRules.shrinkToFit(); - m_universalRules.shrinkToFit(); - m_pageRules.shrinkToFit(); -} - // ------------------------------------------------------------------------------------- // this is mostly boring stuff on how to apply a certain rule to the renderstyle... @@ -2942,7 +2361,7 @@ const StyleResolver::MatchedPropertiesCacheItem* StyleResolver::findFromMatchedP MatchedPropertiesCache::iterator it = m_matchedPropertiesCache.find(hash); if (it == m_matchedPropertiesCache.end()) return 0; - MatchedPropertiesCacheItem& cacheItem = it->second; + MatchedPropertiesCacheItem& cacheItem = it->value; size_t size = matchResult.matchedProperties.size(); if (size != cacheItem.matchedProperties.size()) @@ -3915,13 +3334,8 @@ void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value) setTextSizeAdjust(primitiveValue->getIdent() == CSSValueAuto); return; } -#if ENABLE(DASHBOARD_SUPPORT) || ENABLE(WIDGET_REGION) #if ENABLE(DASHBOARD_SUPPORT) case CSSPropertyWebkitDashboardRegion: -#endif -#if ENABLE(WIDGET_REGION) - case CSSPropertyWebkitWidgetRegion: -#endif { HANDLE_INHERIT_AND_INITIAL(dashboardRegions, DashboardRegions) if (!primitiveValue) @@ -3959,11 +3373,20 @@ void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value) region = region->m_next.get(); } - m_element->document()->setHasDashboardRegions(true); + m_element->document()->setHasAnnotatedRegions(true); return; } #endif +#if ENABLE(WIDGET_REGION) + case CSSPropertyWebkitAppRegion: { + if (!primitiveValue || !primitiveValue->getIdent()) + return; + m_style->setDraggableRegionMode(primitiveValue->getIdent() == CSSValueDrag ? DraggableRegionDrag : DraggableRegionNoDrag); + m_element->document()->setHasAnnotatedRegions(true); + return; + } +#endif case CSSPropertyWebkitTextStrokeWidth: { HANDLE_INHERIT_AND_INITIAL(textStrokeWidth, TextStrokeWidth) float width = 0; @@ -5778,27 +5201,20 @@ void StyleResolver::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const info.addMember(m_userStyle); info.addMember(m_siblingRuleSet); info.addMember(m_uncommonAttributeRuleSet); - info.addHashMap(m_keyframesRuleMap); - info.addHashMap(m_matchedPropertiesCache); - info.addInstrumentedMapValues(m_matchedPropertiesCache); + info.addMember(m_keyframesRuleMap); + info.addMember(m_matchedPropertiesCache); info.addMember(m_matchedRules); info.addMember(m_ruleList); - info.addHashMap(m_pendingImageProperties); - info.addInstrumentedMapValues(m_pendingImageProperties); + info.addMember(m_pendingImageProperties); info.addMember(m_lineHeightValue); info.addMember(m_viewportDependentMediaQueryResults); - info.addHashMap(m_styleRuleToCSSOMWrapperMap); - info.addInstrumentedMapEntries(m_styleRuleToCSSOMWrapperMap); - info.addInstrumentedHashSet(m_styleSheetCSSOMWrapperSet); + info.addMember(m_styleRuleToCSSOMWrapperMap); + info.addMember(m_styleSheetCSSOMWrapperSet); #if ENABLE(CSS_FILTERS) && ENABLE(SVG) - info.addHashMap(m_pendingSVGDocuments); -#endif -#if ENABLE(STYLE_SCOPED) - info.addHashMap(m_scopedAuthorStyles); - info.addInstrumentedMapEntries(m_scopedAuthorStyles); - info.addMember(m_scopeStack); + info.addMember(m_pendingSVGDocuments); #endif + info.addMember(m_scopeResolver); // FIXME: move this to a place where it would be called only once? info.addMember(defaultStyle); diff --git a/Source/WebCore/css/StyleResolver.h b/Source/WebCore/css/StyleResolver.h index 2e530f0e5..12098aa55 100644 --- a/Source/WebCore/css/StyleResolver.h +++ b/Source/WebCore/css/StyleResolver.h @@ -28,6 +28,7 @@ #include "LinkHash.h" #include "MediaQueryExp.h" #include "RenderStyle.h" +#include "RuleFeature.h" #include "SelectorChecker.h" #include "StyleInheritedData.h" #include <wtf/HashMap.h> @@ -73,6 +74,7 @@ class RuleSet; class Settings; class StaticCSSRuleList; class StyleBuilder; +class StyleScopeResolver; class StyleImage; class StyleKeyframe; class StylePendingImage; @@ -159,7 +161,8 @@ public: void setEffectiveZoom(float f) { m_fontDirty |= style()->setEffectiveZoom(f); } void setTextSizeAdjust(bool b) { m_fontDirty |= style()->setTextSizeAdjust(b); } bool hasParentNode() const { return m_parentNode; } - + + void resetAuthorStyle(); void appendAuthorStylesheets(unsigned firstNew, const Vector<RefPtr<StyleSheet> >&); // Find the ids or classes the selectors on a stylesheet are scoped to. The selectors only apply to elements in subtrees where the root element matches the scope. @@ -170,21 +173,13 @@ private: void initElement(Element*); void collectFeatures(); RenderStyle* locateSharedStyle(); - bool matchesRuleSet(RuleSet*); + bool styleSharingCandidateMatchesRuleSet(RuleSet*); Node* locateCousinList(Element* parent, unsigned& visitedNodeCount) const; StyledElement* findSiblingForStyleSharing(Node*, unsigned& count) const; bool canShareStyleWithElement(StyledElement*) const; PassRefPtr<RenderStyle> styleForKeyframe(const RenderStyle*, const StyleKeyframe*, KeyframeValue&); -#if ENABLE(STYLE_SCOPED) - void pushScope(const ContainerNode* scope, const ContainerNode* scopeParent); - void popScope(const ContainerNode* scope); -#else - void pushScope(const ContainerNode*, const ContainerNode*) { } - void popScope(const ContainerNode*) { } -#endif - public: // These methods will give back the set of rules that matched for a given element (or a pseudo-element). enum CSSRuleFilter { @@ -231,7 +226,7 @@ public: CSSFontSelector* fontSelector() const { return m_fontSelector.get(); } void addViewportDependentMediaQueryResult(const MediaQueryExp*, bool result); - + bool hasViewportDependentMediaQueries() const { return !m_viewportDependentMediaQueryResults.isEmpty(); } bool affectedByViewportChange() const; void allVisitedStateChanged() { m_checker.allVisitedStateChanged(); } @@ -273,31 +268,6 @@ public: void loadPendingResources(); - struct RuleFeature { - RuleFeature(StyleRule* rule, unsigned selectorIndex, bool hasDocumentSecurityOrigin) - : rule(rule) - , selectorIndex(selectorIndex) - , hasDocumentSecurityOrigin(hasDocumentSecurityOrigin) - { - } - StyleRule* rule; - unsigned selectorIndex; - bool hasDocumentSecurityOrigin; - }; - struct Features { - Features(); - ~Features(); - void add(const StyleResolver::Features&); - void clear(); - void reportMemoryUsage(MemoryObjectInfo*) const; - HashSet<AtomicStringImpl*> idsInRules; - HashSet<AtomicStringImpl*> attrsInRules; - Vector<RuleFeature> siblingRules; - Vector<RuleFeature> uncommonAttributeRules; - bool usesFirstLineRules; - bool usesBeforeAfterRules; - }; - private: // This function fixes up the default font size if it detects that the current generic font family has changed. -dwh void checkForGenericFamilyChange(RenderStyle*, RenderStyle* parentStyle); @@ -394,7 +364,7 @@ private: OwnPtr<RuleSet> m_authorStyle; OwnPtr<RuleSet> m_userStyle; - Features m_features; + RuleFeatureSet m_features; OwnPtr<RuleSet> m_siblingRuleSet; OwnPtr<RuleSet> m_uncommonAttributeRuleSet; @@ -516,34 +486,7 @@ private: HashMap<FilterOperation*, RefPtr<WebKitCSSSVGDocumentValue> > m_pendingSVGDocuments; #endif -#if ENABLE(STYLE_SCOPED) - const ContainerNode* determineScope(const CSSStyleSheet*); - - typedef HashMap<const ContainerNode*, OwnPtr<RuleSet> > ScopedRuleSetMap; - - RuleSet* ruleSetForScope(const ContainerNode*) const; - - void setupScopeStack(const ContainerNode*); - bool scopeStackIsConsistent(const ContainerNode* parent) const { return parent && parent == m_scopeStackParent; } - - ScopedRuleSetMap m_scopedAuthorStyles; - - struct ScopeStackFrame { - ScopeStackFrame() : m_scope(0), m_authorStyleBoundsIndex(0), m_ruleSet(0) { } - ScopeStackFrame(const ContainerNode* scope, int authorStyleBoundsIndex, RuleSet* ruleSet) : m_scope(scope), m_authorStyleBoundsIndex(authorStyleBoundsIndex), m_ruleSet(ruleSet) { } - const ContainerNode* m_scope; - int m_authorStyleBoundsIndex; - RuleSet* m_ruleSet; - }; - // Vector (used as stack) that keeps track of scoping elements (i.e., elements with a <style scoped> child) - // encountered during tree iteration for style resolution. - Vector<ScopeStackFrame> m_scopeStack; - // Element last seen as parent element when updating m_scopingElementStack. - // This is used to decide whether m_scopingElementStack is consistent, separately from SelectorChecker::m_parentStack. - const ContainerNode* m_scopeStackParent; - int m_scopeStackParentBoundsIndex; -#endif - + OwnPtr<StyleScopeResolver> m_scopeResolver; CSSToStyleMap m_styleMap; friend class StyleBuilder; diff --git a/Source/WebCore/css/StyleScopeResolver.cpp b/Source/WebCore/css/StyleScopeResolver.cpp new file mode 100644 index 000000000..87402baa5 --- /dev/null +++ b/Source/WebCore/css/StyleScopeResolver.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (C) 1999 Lars Knoll (knoll@kde.org) + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. + * 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 INC. 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 INC. 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. + */ + +#include "config.h" +#include "StyleScopeResolver.h" + +#if ENABLE(STYLE_SCOPED) || ENABLE(SHADOW_DOM) + +#include "CSSStyleSheet.h" +#include "ContextFeatures.h" +#include "HTMLNames.h" +#include "HTMLStyleElement.h" +#include "RuleFeature.h" +#include "RuleSet.h" +#include "ShadowRoot.h" +#include "WebCoreMemoryInstrumentation.h" +#include <wtf/MemoryInstrumentationHashMap.h> +#include <wtf/MemoryInstrumentationHashSet.h> +#include <wtf/MemoryInstrumentationVector.h> + +namespace WebCore { + +StyleScopeResolver::StyleScopeResolver() + : m_stackParent(0) + , m_stackParentBoundsIndex(0) +{ +} + +StyleScopeResolver::~StyleScopeResolver() +{ +} + +const ContainerNode* StyleScopeResolver::scopeFor(const CSSStyleSheet* sheet) +{ + ASSERT(sheet); + + Document* document = sheet->ownerDocument(); + if (!document) + return 0; + Node* ownerNode = sheet->ownerNode(); + if (!ownerNode || !ownerNode->isHTMLElement() || !ownerNode->hasTagName(HTMLNames::styleTag)) + return 0; + + HTMLStyleElement* styleElement = static_cast<HTMLStyleElement*>(ownerNode); + if (!styleElement->scoped()) + return styleElement->isInShadowTree() ? styleElement->shadowRoot() : 0; + + ContainerNode* parent = styleElement->parentNode(); + if (!parent) + return 0; + + return (parent->isElementNode() || parent->isShadowRoot()) ? parent : 0; +} + +inline RuleSet* StyleScopeResolver::ruleSetFor(const ContainerNode* scope) const +{ + if (!scope->hasScopedHTMLStyleChild()) + return 0; + ScopedRuleSetMap::const_iterator it = m_authorStyles.find(scope); + return it != m_authorStyles.end() ? it->value.get() : 0; +} + +RuleSet* StyleScopeResolver::ensureRuleSetFor(const ContainerNode* scope) +{ + ScopedRuleSetMap::AddResult addResult = m_authorStyles.add(scope, nullptr); + if (addResult.isNewEntry) + addResult.iterator->value = RuleSet::create(); + return addResult.iterator->value.get(); +} + +void StyleScopeResolver::setupStack(const ContainerNode* parent) +{ + // The scoping element stack shouldn't be used if <style scoped> isn't used anywhere. + ASSERT(!m_authorStyles.isEmpty()); + + m_stack.shrink(0); + int authorStyleBoundsIndex = 0; + for (const ContainerNode* scope = parent; scope; scope = scope->parentOrHostNode()) { + RuleSet* ruleSet = ruleSetFor(scope); + if (ruleSet) + m_stack.append(StackFrame(scope, authorStyleBoundsIndex, ruleSet)); + if (scope->isShadowRoot() && !toShadowRoot(scope)->applyAuthorStyles()) + --authorStyleBoundsIndex; + } + + m_stack.reverse(); + m_stackParent = parent; + m_stackParentBoundsIndex = 0; +} + +void StyleScopeResolver::push(const ContainerNode* scope, const ContainerNode* scopeParent) +{ + // Shortcut: Don't bother with the scoping element stack if <style scoped> isn't used anywhere. + if (m_authorStyles.isEmpty()) { + ASSERT(!m_stackParent); + ASSERT(m_stack.isEmpty()); + return; + } + + // In some wacky cases during style resolve we may get invoked for random elements. + // Recreate the whole scoping element stack in such cases. + if (!stackIsConsistent(scopeParent)) { + setupStack(scope); + return; + } + + if (scope->isShadowRoot() && !toShadowRoot(scope)->applyAuthorStyles()) + ++m_stackParentBoundsIndex; + // Otherwise just push the parent onto the stack. + RuleSet* ruleSet = ruleSetFor(scope); + if (ruleSet) + m_stack.append(StackFrame(scope, m_stackParentBoundsIndex, ruleSet)); + m_stackParent = scope; +} + +void StyleScopeResolver::pop(const ContainerNode* scope) +{ + // Only bother to update the scoping element stack if it is consistent. + if (stackIsConsistent(scope)) { + if (!m_stack.isEmpty() && m_stack.last().m_scope == scope) + m_stack.removeLast(); + if (scope->isShadowRoot() && !toShadowRoot(scope)->applyAuthorStyles()) + --m_stackParentBoundsIndex; + m_stackParent = scope->parentOrHostNode(); + } +} + +void StyleScopeResolver::collectFeaturesTo(RuleFeatureSet& features) +{ + for (ScopedRuleSetMap::iterator it = m_authorStyles.begin(); it != m_authorStyles.end(); ++it) + features.add(it->value->features()); +} + +void StyleScopeResolver::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const +{ + MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS); + info.addMember(m_authorStyles); + info.addMember(m_stack); +} + +} + +#endif // ENABLE(STYLE_SCOPED) diff --git a/Source/WebCore/css/StyleScopeResolver.h b/Source/WebCore/css/StyleScopeResolver.h new file mode 100644 index 000000000..5a32dfe79 --- /dev/null +++ b/Source/WebCore/css/StyleScopeResolver.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 1999 Lars Knoll (knoll@kde.org) + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. + * 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 INC. 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 INC. 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 StyleScopeResolver_h +#define StyleScopeResolver_h + +#include <wtf/Assertions.h> +#include <wtf/Forward.h> +#include <wtf/HashMap.h> +#include <wtf/OwnPtr.h> +#include <wtf/Vector.h> + +namespace WebCore { + +class ContainerNode; +class CSSStyleSheet; +class RuleSet; +class RuleFeatureSet; + +#if ENABLE(STYLE_SCOPED) || ENABLE(SHADOW_DOM) + +class StyleScopeResolver { +public: + typedef HashMap<const ContainerNode*, OwnPtr<RuleSet> > ScopedRuleSetMap; + + struct StackFrame { + StackFrame() : m_scope(0), m_authorStyleBoundsIndex(0), m_ruleSet(0) { } + StackFrame(const ContainerNode* scope, int authorStyleBoundsIndex, RuleSet* ruleSet) + : m_scope(scope), m_authorStyleBoundsIndex(authorStyleBoundsIndex), m_ruleSet(ruleSet) + { } + + const ContainerNode* m_scope; + int m_authorStyleBoundsIndex; + RuleSet* m_ruleSet; + }; + + StyleScopeResolver(); + ~StyleScopeResolver(); + + static const ContainerNode* scopeFor(const CSSStyleSheet*); + + void push(const ContainerNode* scope, const ContainerNode* scopeParent); + void pop(const ContainerNode* scope); + bool hasScopedStyles() const { return !m_authorStyles.isEmpty(); } + RuleSet* ensureRuleSetFor(const ContainerNode* scope); + bool ensureStackConsistency(ContainerNode*); + unsigned stackSize() const { return m_stack.size(); } + const StackFrame& stackFrameAt(unsigned index) const { return m_stack.at(index); } + bool matchesStyleBounds(const StackFrame& frame) const { return frame.m_authorStyleBoundsIndex == m_stackParentBoundsIndex; } + void collectFeaturesTo(RuleFeatureSet&); + + 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; } + + ScopedRuleSetMap m_authorStyles; + + // Vector (used as stack) that keeps track of scoping elements (i.e., elements with a <style scoped> child) + // encountered during tree iteration for style resolution. + Vector<StackFrame> m_stack; + // Element last seen as parent element when updating m_scopingElementStack. + // This is used to decide whether m_scopingElementStack is consistent, separately from SelectorChecker::m_parentStack. + const ContainerNode* m_stackParent; + int m_stackParentBoundsIndex; +}; + +inline bool StyleScopeResolver::ensureStackConsistency(ContainerNode* parent) +{ + // Match scoped author rules by traversing the scoped element stack (rebuild it if it got inconsistent). + if (!stackIsConsistent(parent)) + setupStack(parent); + return !m_stack.isEmpty(); +} + +#else + +class StyleScopeResolver { +public: + static const ContainerNode* scopeFor(const CSSStyleSheet*) { return 0; } + void push(const ContainerNode*, const ContainerNode*) { } + void pop(const ContainerNode*) { } + void collectFeaturesTo(RuleFeatureSet&) { } + RuleSet* ensureRuleSetFor(const ContainerNode*) { return 0; } +}; + +#endif // ENABLE(STYLE_SCOPED) + +} // namespace WebCore + +#endif // StyleScopeResolver_h diff --git a/Source/WebCore/css/StyleSheet.idl b/Source/WebCore/css/StyleSheet.idl index b8568bfb2..b2d3a11d5 100644 --- a/Source/WebCore/css/StyleSheet.idl +++ b/Source/WebCore/css/StyleSheet.idl @@ -18,29 +18,26 @@ * Boston, MA 02110-1301, USA. */ -module stylesheets { - - // Introduced in DOM Level 2: - interface [ - JSCustomMarkFunction, - JSGenerateIsReachable, - CustomToJSObject, - ObjCPolymorphic, - V8GenerateIsReachable=ImplOwnerNodeRoot - ] StyleSheet { - readonly attribute [TreatReturnedNullStringAs=Null] DOMString type; - attribute boolean disabled; - readonly attribute Node ownerNode; - readonly attribute StyleSheet parentStyleSheet; - readonly attribute [TreatReturnedNullStringAs=Null] DOMString href; - readonly attribute [TreatReturnedNullStringAs=Null] DOMString title; - readonly attribute MediaList media; +// Introduced in DOM Level 2: +[ + JSCustomMarkFunction, + JSGenerateIsReachable, + CustomToJSObject, + ObjCPolymorphic, + V8GenerateIsReachable=ImplOwnerNodeRoot +] interface StyleSheet { + [TreatReturnedNullStringAs=Null] readonly attribute DOMString type; + attribute boolean disabled; + readonly attribute Node ownerNode; + readonly attribute StyleSheet parentStyleSheet; + [TreatReturnedNullStringAs=Null] readonly attribute DOMString href; + [TreatReturnedNullStringAs=Null] readonly attribute DOMString title; + readonly attribute MediaList media; #if defined(LANGUAGE_CPP) && LANGUAGE_CPP - // Extra WebCore methods exposed to allowe compile-time casting in C++ - boolean isCSSStyleSheet(); + // Extra WebCore methods exposed to allowe compile-time casting in C++ + boolean isCSSStyleSheet(); #endif - }; +}; -} diff --git a/Source/WebCore/css/StyleSheetContents.cpp b/Source/WebCore/css/StyleSheetContents.cpp index 945f355a3..e7ce81eaa 100644 --- a/Source/WebCore/css/StyleSheetContents.cpp +++ b/Source/WebCore/css/StyleSheetContents.cpp @@ -33,6 +33,7 @@ #include "StyleRuleImport.h" #include "WebCoreMemoryInstrumentation.h" #include <wtf/Deque.h> +#include <wtf/MemoryInstrumentationHashMap.h> #include <wtf/MemoryInstrumentationVector.h> namespace WebCore { @@ -252,7 +253,7 @@ void StyleSheetContents::parserAddNamespace(const AtomicString& prefix, const At PrefixNamespaceURIMap::AddResult result = m_namespaces.add(prefix, uri); if (result.isNewEntry) return; - result.iterator->second = uri; + result.iterator->value = uri; } const AtomicString& StyleSheetContents::determineNamespace(const AtomicString& prefix) @@ -264,7 +265,7 @@ const AtomicString& StyleSheetContents::determineNamespace(const AtomicString& p PrefixNamespaceURIMap::const_iterator it = m_namespaces.find(prefix); if (it == m_namespaces.end()) return nullAtom; - return it->second; + return it->value; } void StyleSheetContents::parseAuthorStyleSheet(const CachedCSSStyleSheet* cachedStyleSheet, const SecurityOrigin* securityOrigin) @@ -485,6 +486,12 @@ void StyleSheetContents::removedFromMemoryCache() m_isInMemoryCache = false; } +void StyleSheetContents::shrinkToFit() +{ + m_importRules.shrinkToFit(); + m_childRules.shrinkToFit(); +} + void StyleSheetContents::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const { MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS); @@ -492,7 +499,7 @@ void StyleSheetContents::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) c info.addMember(m_encodingFromCharsetRule); info.addMember(m_importRules); info.addMember(m_childRules); - info.addHashMap(m_namespaces); + info.addMember(m_namespaces); info.addMember(m_clients); } diff --git a/Source/WebCore/css/StyleSheetContents.h b/Source/WebCore/css/StyleSheetContents.h index 9dd3eb235..1f2968b71 100644 --- a/Source/WebCore/css/StyleSheetContents.h +++ b/Source/WebCore/css/StyleSheetContents.h @@ -138,6 +138,8 @@ public: void reportMemoryUsage(MemoryObjectInfo*) const; + void shrinkToFit(); + private: StyleSheetContents(StyleRuleImport* ownerRule, const String& originalURL, const CSSParserContext&); StyleSheetContents(const StyleSheetContents&); diff --git a/Source/WebCore/css/StyleSheetList.idl b/Source/WebCore/css/StyleSheetList.idl index 3a7b185cd..fc9aea501 100644 --- a/Source/WebCore/css/StyleSheetList.idl +++ b/Source/WebCore/css/StyleSheetList.idl @@ -18,17 +18,14 @@ * Boston, MA 02110-1301, USA. */ -module stylesheets { +// Introduced in DOM Level 2: +[ + JSGenerateIsReachable=ImplDocument, + IndexedGetter, + NamedGetter, + V8DependentLifetime +] interface StyleSheetList { + readonly attribute unsigned long length; + StyleSheet item(in [Optional=DefaultIsUndefined] unsigned long index); +}; - // Introduced in DOM Level 2: - interface [ - JSGenerateIsReachable=ImplDocument, - IndexedGetter, - NamedGetter, - V8DependentLifetime - ] StyleSheetList { - readonly attribute unsigned long length; - StyleSheet item(in [Optional=DefaultIsUndefined] unsigned long index); - }; - -} diff --git a/Source/WebCore/css/WebKitCSSFilterValue.idl b/Source/WebCore/css/WebKitCSSFilterValue.idl index 3f219137b..e3a2eadd4 100644 --- a/Source/WebCore/css/WebKitCSSFilterValue.idl +++ b/Source/WebCore/css/WebKitCSSFilterValue.idl @@ -23,32 +23,29 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -module css { +[ + Conditional=CSS_FILTERS, + IndexedGetter, + DoNotCheckConstants +] interface WebKitCSSFilterValue : CSSValueList { - interface [ - Conditional=CSS_FILTERS, - IndexedGetter, - DoNotCheckConstants - ] WebKitCSSFilterValue : CSSValueList { + // OperationTypes - // OperationTypes - - const unsigned short CSS_FILTER_REFERENCE = 1; - const unsigned short CSS_FILTER_GRAYSCALE = 2; - const unsigned short CSS_FILTER_SEPIA = 3; - const unsigned short CSS_FILTER_SATURATE = 4; - const unsigned short CSS_FILTER_HUE_ROTATE = 5; - const unsigned short CSS_FILTER_INVERT = 6; - const unsigned short CSS_FILTER_OPACITY = 7; - const unsigned short CSS_FILTER_BRIGHTNESS = 8; - const unsigned short CSS_FILTER_CONTRAST = 9; - const unsigned short CSS_FILTER_BLUR = 10; - const unsigned short CSS_FILTER_DROP_SHADOW = 11; + const unsigned short CSS_FILTER_REFERENCE = 1; + const unsigned short CSS_FILTER_GRAYSCALE = 2; + const unsigned short CSS_FILTER_SEPIA = 3; + const unsigned short CSS_FILTER_SATURATE = 4; + const unsigned short CSS_FILTER_HUE_ROTATE = 5; + const unsigned short CSS_FILTER_INVERT = 6; + const unsigned short CSS_FILTER_OPACITY = 7; + const unsigned short CSS_FILTER_BRIGHTNESS = 8; + const unsigned short CSS_FILTER_CONTRAST = 9; + const unsigned short CSS_FILTER_BLUR = 10; + const unsigned short CSS_FILTER_DROP_SHADOW = 11; #if defined(ENABLE_CSS_SHADERS) && ENABLE_CSS_SHADERS - const unsigned short CSS_FILTER_CUSTOM = 12; + const unsigned short CSS_FILTER_CUSTOM = 12; #endif - readonly attribute unsigned short operationType; - }; -} + readonly attribute unsigned short operationType; +}; diff --git a/Source/WebCore/css/WebKitCSSKeyframeRule.idl b/Source/WebCore/css/WebKitCSSKeyframeRule.idl index f6eac7741..ea5bb137f 100644 --- a/Source/WebCore/css/WebKitCSSKeyframeRule.idl +++ b/Source/WebCore/css/WebKitCSSKeyframeRule.idl @@ -26,14 +26,11 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -module css { +// Introduced in DOM Level ?: +interface WebKitCSSKeyframeRule : CSSRule { - // Introduced in DOM Level ?: - interface WebKitCSSKeyframeRule : CSSRule { + attribute DOMString keyText; + readonly attribute CSSStyleDeclaration style; - attribute DOMString keyText; - readonly attribute CSSStyleDeclaration style; +}; - }; - -} diff --git a/Source/WebCore/css/WebKitCSSKeyframesRule.idl b/Source/WebCore/css/WebKitCSSKeyframesRule.idl index fa0ea2a1b..e1e167d1a 100644 --- a/Source/WebCore/css/WebKitCSSKeyframesRule.idl +++ b/Source/WebCore/css/WebKitCSSKeyframesRule.idl @@ -26,19 +26,16 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -module css { +// Introduced in DOM Level ?: +[ + IndexedGetter +] interface WebKitCSSKeyframesRule : CSSRule { - // Introduced in DOM Level ?: - interface [ - IndexedGetter - ] WebKitCSSKeyframesRule : CSSRule { + [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] attribute DOMString name; + readonly attribute CSSRuleList cssRules; + + void insertRule(in [Optional=DefaultIsUndefined] DOMString rule); + void deleteRule(in [Optional=DefaultIsUndefined] DOMString key); + WebKitCSSKeyframeRule findRule(in [Optional=DefaultIsUndefined] DOMString key); +}; - attribute [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] DOMString name; - readonly attribute CSSRuleList cssRules; - - void insertRule(in [Optional=DefaultIsUndefined] DOMString rule); - void deleteRule(in [Optional=DefaultIsUndefined] DOMString key); - WebKitCSSKeyframeRule findRule(in [Optional=DefaultIsUndefined] DOMString key); - }; - -} diff --git a/Source/WebCore/css/WebKitCSSMatrix.idl b/Source/WebCore/css/WebKitCSSMatrix.idl index 08c41aa12..9bc3f092a 100644 --- a/Source/WebCore/css/WebKitCSSMatrix.idl +++ b/Source/WebCore/css/WebKitCSSMatrix.idl @@ -23,84 +23,81 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -module css { +// Introduced in DOM Level ?: +[ + Constructor(in [Optional=DefaultIsNullString] DOMString cssValue), + ConstructorRaisesException, +] interface WebKitCSSMatrix { - // Introduced in DOM Level ?: - interface [ - Constructor(in [Optional=DefaultIsNullString] DOMString cssValue), - ConstructorRaisesException, - ] WebKitCSSMatrix { + // These attributes are simple aliases for certain elements of the 4x4 matrix + attribute double a; // alias for m11 + attribute double b; // alias for m12 + attribute double c; // alias for m21 + attribute double d; // alias for m22 + attribute double e; // alias for m41 + attribute double f; // alias for m42 - // These attributes are simple aliases for certain elements of the 4x4 matrix - attribute double a; // alias for m11 - attribute double b; // alias for m12 - attribute double c; // alias for m21 - attribute double d; // alias for m22 - attribute double e; // alias for m41 - attribute double f; // alias for m42 + attribute double m11; + attribute double m12; + attribute double m13; + attribute double m14; + attribute double m21; + attribute double m22; + attribute double m23; + attribute double m24; + attribute double m31; + attribute double m32; + attribute double m33; + attribute double m34; + attribute double m41; + attribute double m42; + attribute double m43; + attribute double m44; - attribute double m11; - attribute double m12; - attribute double m13; - attribute double m14; - attribute double m21; - attribute double m22; - attribute double m23; - attribute double m24; - attribute double m31; - attribute double m32; - attribute double m33; - attribute double m34; - attribute double m41; - attribute double m42; - attribute double m43; - attribute double m44; + void setMatrixValue(in [Optional=DefaultIsUndefined] DOMString string) raises (DOMException); + + // Multiply this matrix by secondMatrix, on the right (result = this * secondMatrix) + [Immutable] WebKitCSSMatrix multiply(in [Optional=DefaultIsUndefined] WebKitCSSMatrix secondMatrix); + + // Return the inverse of this matrix. Throw an exception if the matrix is not invertible + [Immutable] WebKitCSSMatrix inverse() raises (DOMException); + + // Return this matrix translated by the passed values. + // Passing a NaN will use a value of 0. This allows the 3D form to used for 2D operations + [Immutable] WebKitCSSMatrix translate(in [Optional=DefaultIsUndefined] double x, + in [Optional=DefaultIsUndefined] double y, + in [Optional=DefaultIsUndefined] double z); + + // Returns this matrix scaled by the passed values. + // Passing scaleX or scaleZ as NaN uses a value of 1, but passing scaleY of NaN + // makes it the same as scaleX. This allows the 3D form to used for 2D operations + [Immutable] WebKitCSSMatrix scale(in [Optional=DefaultIsUndefined] double scaleX, + in [Optional=DefaultIsUndefined] double scaleY, + in [Optional=DefaultIsUndefined] double scaleZ); + + // Returns this matrix rotated by the passed values. + // If rotY and rotZ are NaN, rotate about Z (rotX=0, rotateY=0, rotateZ=rotX). + // Otherwise use a rotation value of 0 for any passed NaN. + [Immutable] WebKitCSSMatrix rotate(in [Optional=DefaultIsUndefined] double rotX, + in [Optional=DefaultIsUndefined] double rotY, + in [Optional=DefaultIsUndefined] double rotZ); + + // Returns this matrix rotated about the passed axis by the passed angle. + // Passing a NaN will use a value of 0. If the axis is (0,0,0) use a value + // of (0,0,1). + [Immutable] WebKitCSSMatrix rotateAxisAngle(in [Optional=DefaultIsUndefined] double x, + in [Optional=DefaultIsUndefined] double y, + in [Optional=DefaultIsUndefined] double z, + in [Optional=DefaultIsUndefined] double angle); - void setMatrixValue(in [Optional=DefaultIsUndefined] DOMString string) raises (DOMException); - - // Multiply this matrix by secondMatrix, on the right (result = this * secondMatrix) - [Immutable] WebKitCSSMatrix multiply(in [Optional=DefaultIsUndefined] WebKitCSSMatrix secondMatrix); - - // Return the inverse of this matrix. Throw an exception if the matrix is not invertible - [Immutable] WebKitCSSMatrix inverse() raises (DOMException); - - // Return this matrix translated by the passed values. - // Passing a NaN will use a value of 0. This allows the 3D form to used for 2D operations - [Immutable] WebKitCSSMatrix translate(in [Optional=DefaultIsUndefined] double x, - in [Optional=DefaultIsUndefined] double y, - in [Optional=DefaultIsUndefined] double z); - - // Returns this matrix scaled by the passed values. - // Passing scaleX or scaleZ as NaN uses a value of 1, but passing scaleY of NaN - // makes it the same as scaleX. This allows the 3D form to used for 2D operations - [Immutable] WebKitCSSMatrix scale(in [Optional=DefaultIsUndefined] double scaleX, - in [Optional=DefaultIsUndefined] double scaleY, - in [Optional=DefaultIsUndefined] double scaleZ); - - // Returns this matrix rotated by the passed values. - // If rotY and rotZ are NaN, rotate about Z (rotX=0, rotateY=0, rotateZ=rotX). - // Otherwise use a rotation value of 0 for any passed NaN. - [Immutable] WebKitCSSMatrix rotate(in [Optional=DefaultIsUndefined] double rotX, - in [Optional=DefaultIsUndefined] double rotY, - in [Optional=DefaultIsUndefined] double rotZ); - - // Returns this matrix rotated about the passed axis by the passed angle. - // Passing a NaN will use a value of 0. If the axis is (0,0,0) use a value - // of (0,0,1). - [Immutable] WebKitCSSMatrix rotateAxisAngle(in [Optional=DefaultIsUndefined] double x, - in [Optional=DefaultIsUndefined] double y, - in [Optional=DefaultIsUndefined] double z, - in [Optional=DefaultIsUndefined] double angle); + // Returns this matrix skewed along the X axis by the passed values. + // Passing a NaN will use a value of 0. + [Immutable] WebKitCSSMatrix skewX(in [Optional=DefaultIsUndefined] double angle); - // Returns this matrix skewed along the X axis by the passed values. - // Passing a NaN will use a value of 0. - [Immutable] WebKitCSSMatrix skewX(in [Optional=DefaultIsUndefined] double angle); + // Returns this matrix skewed along the Y axis by the passed values. + // Passing a NaN will use a value of 0. + [Immutable] WebKitCSSMatrix skewY(in [Optional=DefaultIsUndefined] double angle); - // Returns this matrix skewed along the Y axis by the passed values. - // Passing a NaN will use a value of 0. - [Immutable] WebKitCSSMatrix skewY(in [Optional=DefaultIsUndefined] double angle); + [NotEnumerable] DOMString toString(); +}; - [NotEnumerable] DOMString toString(); - }; - -} diff --git a/Source/WebCore/css/WebKitCSSRegionRule.idl b/Source/WebCore/css/WebKitCSSRegionRule.idl index ec3e6d515..3ea6ef24f 100644 --- a/Source/WebCore/css/WebKitCSSRegionRule.idl +++ b/Source/WebCore/css/WebKitCSSRegionRule.idl @@ -27,12 +27,9 @@ * SUCH DAMAGE. */ -module css { +[ + Conditional=CSS_REGIONS, +] interface WebKitCSSRegionRule : CSSRule { + readonly attribute CSSRuleList cssRules; +}; - interface [ - Conditional=CSS_REGIONS, - ] WebKitCSSRegionRule : CSSRule { - readonly attribute CSSRuleList cssRules; - }; - -} diff --git a/Source/WebCore/css/WebKitCSSTransformValue.idl b/Source/WebCore/css/WebKitCSSTransformValue.idl index 92fde1d36..5e7aa79d8 100644 --- a/Source/WebCore/css/WebKitCSSTransformValue.idl +++ b/Source/WebCore/css/WebKitCSSTransformValue.idl @@ -26,38 +26,35 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -module css { +[ + IndexedGetter, + DoNotCheckConstants +] interface WebKitCSSTransformValue : CSSValueList { - interface [ - IndexedGetter, - DoNotCheckConstants - ] WebKitCSSTransformValue : CSSValueList { + // OperationTypes - // OperationTypes + const unsigned short CSS_TRANSLATE = 1; + const unsigned short CSS_TRANSLATEX = 2; + const unsigned short CSS_TRANSLATEY = 3; + const unsigned short CSS_ROTATE = 4; + const unsigned short CSS_SCALE = 5; + const unsigned short CSS_SCALEX = 6; + const unsigned short CSS_SCALEY = 7; + const unsigned short CSS_SKEW = 8; + const unsigned short CSS_SKEWX = 9; + const unsigned short CSS_SKEWY = 10; + const unsigned short CSS_MATRIX = 11; + const unsigned short CSS_TRANSLATEZ = 12; + const unsigned short CSS_TRANSLATE3D = 13; + const unsigned short CSS_ROTATEX = 14; + const unsigned short CSS_ROTATEY = 15; + const unsigned short CSS_ROTATEZ = 16; + const unsigned short CSS_ROTATE3D = 17; + const unsigned short CSS_SCALEZ = 18; + const unsigned short CSS_SCALE3D = 19; + const unsigned short CSS_PERSPECTIVE = 20; + const unsigned short CSS_MATRIX3D = 21; - const unsigned short CSS_TRANSLATE = 1; - const unsigned short CSS_TRANSLATEX = 2; - const unsigned short CSS_TRANSLATEY = 3; - const unsigned short CSS_ROTATE = 4; - const unsigned short CSS_SCALE = 5; - const unsigned short CSS_SCALEX = 6; - const unsigned short CSS_SCALEY = 7; - const unsigned short CSS_SKEW = 8; - const unsigned short CSS_SKEWX = 9; - const unsigned short CSS_SKEWY = 10; - const unsigned short CSS_MATRIX = 11; - const unsigned short CSS_TRANSLATEZ = 12; - const unsigned short CSS_TRANSLATE3D = 13; - const unsigned short CSS_ROTATEX = 14; - const unsigned short CSS_ROTATEY = 15; - const unsigned short CSS_ROTATEZ = 16; - const unsigned short CSS_ROTATE3D = 17; - const unsigned short CSS_SCALEZ = 18; - const unsigned short CSS_SCALE3D = 19; - const unsigned short CSS_PERSPECTIVE = 20; - const unsigned short CSS_MATRIX3D = 21; + readonly attribute unsigned short operationType; +}; - readonly attribute unsigned short operationType; - }; - -} diff --git a/Source/WebCore/css/fullscreenQuickTime.css b/Source/WebCore/css/fullscreenQuickTime.css index 27b088fea..cf07d93e2 100644 --- a/Source/WebCore/css/fullscreenQuickTime.css +++ b/Source/WebCore/css/fullscreenQuickTime.css @@ -51,7 +51,7 @@ video:-webkit-full-screen::-webkit-media-controls-panel { inset 0 1px 0 0px rgba(255, 255, 255, 0.15), inset 0 -1px 0 0px rgba(202, 202, 202, 0.09), 0 0 0 1px rgba(0, 0, 0, 0.5); - -webkit-border-radius: 8px !important; + border-radius: 8px !important; -webkit-transition: opacity 0.3s linear !important; } diff --git a/Source/WebCore/css/html.css b/Source/WebCore/css/html.css index 62d19cbb7..33af68864 100644 --- a/Source/WebCore/css/html.css +++ b/Source/WebCore/css/html.css @@ -396,7 +396,7 @@ button { /* Form controls don't go vertical. */ input, textarea, keygen, select, button, isindex, meter, progress { - -webkit-block-flow: tb !important; + -webkit-writing-mode: horizontal-tb !important; } input, textarea, keygen, select, button, isindex { @@ -410,7 +410,7 @@ input, textarea, keygen, select, button, isindex { text-indent: 0; text-shadow: none; display: inline-block; - text-align: -webkit-auto; + text-align: start; } input[type="hidden"] { @@ -429,7 +429,7 @@ input, input[type="password"], input[type="search"], isindex { input[type="search"] { -webkit-appearance: searchfield; - -webkit-box-sizing: border-box; + box-sizing: border-box; } input::-webkit-textfield-decoration-container { @@ -476,10 +476,37 @@ datalist { } #endif -#if defined(ENABLE_INPUT_TYPE_TIME_MULTIPLE_FIELDS) && ENABLE_INPUT_TYPE_TIME_MULTIPLE_FIELDS +#if defined(ENABLE_INPUT_MULTIPLE_FIELDS_UI) && ENABLE_INPUT_MULTIPLE_FIELDS_UI +#if defined(ENABLE_INPUT_TYPE_DATE) && ENABLE_INPUT_TYPE_DATE +input[type="date"] { + font-family: monospace; +} +#endif +#if defined(ENABLE_INPUT_TYPE_DATETIME) && ENABLE_INPUT_TYPE_DATETIME +input[type="datetime"] { + font-family: monospace; +} +#endif +#if defined(ENABLE_INPUT_TYPE_DATETIMELOCAL) && ENABLE_INPUT_TYPE_DATETIMELOCAL +input[type="datetime-local"] { + font-family: monospace; +} +#endif +#if defined(ENABLE_INPUT_TYPE_MONTH) && ENABLE_INPUT_TYPE_MONTH +input[type="month"] { + font-family: monospace; +} +#endif +#if defined(ENABLE_INPUT_TYPE_TIME) && ENABLE_INPUT_TYPE_TIME input[type="time"] { font-family: monospace; } +#endif +#if defined(ENABLE_INPUT_TYPE_WEEK) && ENABLE_INPUT_TYPE_WEEK +input[type="week"] { + font-family: monospace; +} +#endif input::-webkit-datetime-edit { -webkit-user-modify: read-only !important; @@ -495,6 +522,14 @@ input::-webkit-datetime-edit-ampm-field { 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; @@ -519,6 +554,14 @@ input::-webkit-datetime-edit-minute-field { 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; +} + /* This selector is used when step >= 3600 second but format contains minute field. */ input::-webkit-datetime-edit-minute-field[readonly] { color: GrayText; @@ -532,12 +575,37 @@ input::-webkit-datetime-edit-second-field { 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; +} + +input::-webkit-date-and-time-container { + display: -webkit-flex; + -webkit-align-items: center; +} + /* 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-second-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; @@ -548,6 +616,7 @@ input::-webkit-datetime-edit-second-field[readonly] { color: GrayText; } +input[type="month"]::-webkit-inner-spin-button, input[type="time"]::-webkit-inner-spin-button { margin-left: 0.2em; } @@ -579,7 +648,7 @@ input::-webkit-input-speech-button { #endif keygen, select { - -webkit-border-radius: 5px; + border-radius: 5px; } keygen::-webkit-keygen-select { @@ -665,7 +734,7 @@ input[type="button"], input[type="submit"], input[type="reset"], input[type="fil padding: 2px 6px 3px 6px; border: 2px outset ButtonFace; background-color: ButtonFace; - -webkit-box-sizing: border-box + box-sizing: border-box } input[type="range"] { @@ -679,7 +748,7 @@ input[type="range"] { input[type="range"]::-webkit-slider-container, input[type="range"]::-webkit-media-slider-container { -webkit-box-align: center; -webkit-box-orient: horizontal; /* This property is updated by C++ code. */ - -webkit-box-sizing: border-box; + box-sizing: border-box; -webkit-user-modify: read-only !important; display: -webkit-box; height: 100%; @@ -688,14 +757,14 @@ input[type="range"]::-webkit-slider-container, input[type="range"]::-webkit-medi input[type="range"]::-webkit-slider-runnable-track { -webkit-box-flex: 1; - -webkit-box-sizing: border-box; + box-sizing: border-box; -webkit-user-modify: read-only !important; display: block; } input[type="range"]::-webkit-slider-thumb, input[type="range"]::-webkit-media-slider-thumb { -webkit-appearance: sliderthumb-horizontal; - -webkit-box-sizing: border-box; + box-sizing: border-box; -webkit-user-modify: read-only !important; display: block; position: relative; @@ -722,12 +791,12 @@ area, param { input[type="checkbox"] { -webkit-appearance: checkbox; - -webkit-box-sizing: border-box; + box-sizing: border-box; } input[type="radio"] { -webkit-appearance: radio; - -webkit-box-sizing: border-box; + box-sizing: border-box; } #if defined(ENABLE_INPUT_TYPE_COLOR) && ENABLE_INPUT_TYPE_COLOR @@ -741,7 +810,7 @@ input[type="color"] { input[type="color"]::-webkit-color-swatch-wrapper { display:-webkit-box; padding: 4px 2px; - -webkit-box-sizing: border-box; + box-sizing: border-box; -webkit-user-modify: read-only !important; width: 100%; height: 100% @@ -790,7 +859,7 @@ input::-webkit-calendar-picker-indicator:hover { select { -webkit-appearance: menulist; - -webkit-box-sizing: border-box; + box-sizing: border-box; -webkit-box-align: center; border: 1px solid; white-space: pre; @@ -806,7 +875,7 @@ select[size][multiple] { -webkit-appearance: listbox; -webkit-box-align: start; border: 1px inset gray; - -webkit-border-radius: initial; + border-radius: initial; white-space: initial; } @@ -815,7 +884,7 @@ select[size="1"] { -webkit-appearance: menulist; -webkit-box-align: center; border: 1px solid; - -webkit-border-radius: 5px; + border-radius: 5px; white-space: pre; } @@ -856,7 +925,7 @@ output { border: solid 2px #400; background: -webkit-gradient(linear, left top, left bottom, from(#f8ecec), to(#e8cccc)); padding: 8px; - -webkit-border-radius: 8px; + border-radius: 8px; -webkit-box-shadow: 4px 4px 4px rgba(100,100,100,0.6), inset -2px -2px 1px #d0c4c4, inset 2px 2px 1px white; @@ -905,7 +974,7 @@ output { meter { -webkit-appearance: meter; - -webkit-box-sizing: border-box; + box-sizing: border-box; display: inline-block; height: 1em; width: 5em; @@ -914,7 +983,7 @@ meter { meter::-webkit-meter-inner-element { -webkit-appearance: inherit; - -webkit-box-sizing: inherit; + box-sizing: inherit; -webkit-user-modify: read-only !important; height: 100%; width: 100%; @@ -925,28 +994,28 @@ meter::-webkit-meter-bar { height: 100%; width: 100%; -webkit-user-modify: read-only !important; - -webkit-box-sizing: border-box; + box-sizing: border-box; } meter::-webkit-meter-optimum-value { background: -webkit-gradient(linear, left top, left bottom, from(#ad7), to(#ad7), color-stop(0.20, #cea), color-stop(0.45, #7a3), color-stop(0.55, #7a3)); height: 100%; -webkit-user-modify: read-only !important; - -webkit-box-sizing: border-box; + box-sizing: border-box; } meter::-webkit-meter-suboptimum-value { background: -webkit-gradient(linear, left top, left bottom, from(#fe7), to(#fe7), color-stop(0.20, #ffc), color-stop(0.45, #db3), color-stop(0.55, #db3)); height: 100%; -webkit-user-modify: read-only !important; - -webkit-box-sizing: border-box; + box-sizing: border-box; } meter::-webkit-meter-even-less-good-value { background: -webkit-gradient(linear, left top, left bottom, from(#f77), to(#f77), color-stop(0.20, #fcc), color-stop(0.45, #d44), color-stop(0.55, #d44)); height: 100%; -webkit-user-modify: read-only !important; - -webkit-box-sizing: border-box; + box-sizing: border-box; } #endif @@ -955,7 +1024,7 @@ meter::-webkit-meter-even-less-good-value { progress { -webkit-appearance: progress-bar; - -webkit-box-sizing: border-box; + box-sizing: border-box; display: inline-block; height: 1em; width: 10em; @@ -964,7 +1033,7 @@ progress { progress::-webkit-progress-inner-element { -webkit-appearance: inherit; - -webkit-box-sizing: inherit; + box-sizing: inherit; -webkit-user-modify: read-only; height: 100%; width: 100%; @@ -975,7 +1044,7 @@ progress::-webkit-progress-bar { height: 100%; width: 100%; -webkit-user-modify: read-only !important; - -webkit-box-sizing: border-box; + box-sizing: border-box; } progress::-webkit-progress-value { @@ -983,7 +1052,7 @@ progress::-webkit-progress-value { height: 100%; width: 50%; /* should be removed later */ -webkit-user-modify: read-only !important; - -webkit-box-sizing: border-box; + box-sizing: border-box; } #endif @@ -1103,7 +1172,7 @@ rt { ruby > rt { display: block; font-size: 50%; - text-align: -webkit-auto; + text-align: start; } ruby > rp { diff --git a/Source/WebCore/css/mediaControlsChromium.css b/Source/WebCore/css/mediaControlsChromium.css index 025c57901..9d6957714 100644 --- a/Source/WebCore/css/mediaControlsChromium.css +++ b/Source/WebCore/css/mediaControlsChromium.css @@ -160,7 +160,7 @@ input[type="range"]::-webkit-media-slider-container { display: -webkit-box; -webkit-box-align: center; -webkit-box-orient: horizontal; /* This property is updated by C++ code. */ - -webkit-box-sizing: border-box; + box-sizing: border-box; height: 100%; width: 100%; border: 1px solid rgba(230, 230, 230, 0.35); @@ -171,7 +171,7 @@ input[type="range"]::-webkit-media-slider-container { input[type="range"]::-webkit-media-slider-thumb { display: block; -webkit-appearance: sliderthumb-horizontal; - -webkit-box-sizing: border-box; + box-sizing: border-box; position: relative; bottom: 1px; margin-left: -7px; diff --git a/Source/WebCore/css/mediaControlsChromiumAndroid.css b/Source/WebCore/css/mediaControlsChromiumAndroid.css index 10f7f1e64..7ec74a999 100644 --- a/Source/WebCore/css/mediaControlsChromiumAndroid.css +++ b/Source/WebCore/css/mediaControlsChromiumAndroid.css @@ -82,13 +82,15 @@ audio::-webkit-media-controls-overlay-enclosure { video::-webkit-media-controls-overlay-enclosure { display: -webkit-box; -webkit-box-orient: horizontal; - -webkit-box-pack:center; - -webkit-box-align:center; - -webkit-box-flex:1; + -webkit-box-pack: center; + -webkit-box-align: center; + -webkit-box-flex: 1; width: 100%; + height: 100%; max-width: 800px; text-indent: 0; box-sizing: border-box; + overflow: hidden; } audio::-webkit-media-controls-mute-button, video::-webkit-media-controls-mute-button { @@ -175,7 +177,7 @@ input[type="range"]::-webkit-media-slider-container { display: -webkit-box; -webkit-box-align: center; -webkit-box-orient: horizontal; - -webkit-box-sizing: border-box; + box-sizing: border-box; height: 100%; width: 100%; border: 1px solid rgba(230, 230, 230, 0.35); @@ -186,7 +188,7 @@ input[type="range"]::-webkit-media-slider-container { input[type="range"]::-webkit-media-slider-thumb { display: block; -webkit-appearance: sliderthumb-horizontal; - -webkit-box-sizing: border-box; + box-sizing: border-box; position: relative; bottom: 1px; margin-left: -7px; diff --git a/Source/WebCore/css/mediaControlsEflFullscreen.css b/Source/WebCore/css/mediaControlsEflFullscreen.css index 1724d4032..6b3a51501 100644 --- a/Source/WebCore/css/mediaControlsEflFullscreen.css +++ b/Source/WebCore/css/mediaControlsEflFullscreen.css @@ -24,105 +24,44 @@ /* EFLWebKit media controls for fullscreen. */ -video::-webkit-media-controls-panel { - display: -webkit-box; - -webkit-box-orient: horizontal; - -webkit-box-align: center; - -webkit-user-select: none; - position: relative; - bottom: 0; - width: 100%; - z-index: 0; - overflow: hidden; - height: 20px; - text-align: right; -} - -video:-webkit-full-page-media::-webkit-media-controls-panel { +video:-webkit-full-screen:-webkit-full-page-media::-webkit-media-controls-panel { display: none; } -video::-webkit-media-controls-mute-button { +video:-webkit-full-screen::-webkit-media-controls-mute-button { display: none; } -video::-webkit-media-controls-play-button { - -webkit-appearance: media-play-button; - display: -webkit-box; - width: 20px; - height: 20px; - background-color: initial; - border: initial; - color: inherit; -} - -video::-webkit-media-controls-timeline-container { - -webkit-appearance: media-controls-background; - display: -webkit-box; - -webkit-box-orient: horizontal; - -webkit-box-align: center; - -webkit-box-pack: end; - -webkit-box-flex: 1; - -webkit-user-select: none; - height: 20px; -} - -video::-webkit-media-controls-current-time-display { - -webkit-appearance: media-current-time-display; - -webkit-user-select: none; - display: inline-block; - height: 20px; - padding: 4px; - text-align: center; - font-size: 10px; -} - -video::-webkit-media-controls-time-remaining-display { +video:-webkit-full-screen::-webkit-media-controls-time-remaining-display { display: none; } -video::-webkit-media-controls-timeline { - -webkit-appearance: media-slider; - display: -webkit-box; - -webkit-box-flex: 1; - height: 20px; - padding: 0px 2px; - background-color: initial; - border: initial; - color: inherit; - margin: initial; -} - -video::-webkit-media-controls-volume-slider-container { +video:-webkit-full-screen::-webkit-media-controls-volume-slider-container { -webkit-appearance: media-volume-slider-container; display: none; } -video::-webkit-media-controls-volume-slider { +video:-webkit-full-screen::-webkit-media-controls-volume-slider { -webkit-appearance: media-volume-slider; display: none; } -video::-webkit-media-controls-seek-back-button { - display: none; -} - -video::-webkit-media-controls-seek-forward-button { +video:-webkit-full-screen::-webkit-media-controls-seek-back-button { display: none; } -video::-webkit-media-controls-fullscreen-button { +video:-webkit-full-screen::-webkit-media-controls-seek-forward-button { display: none; } -video::-webkit-media-controls-rewind-button { +video:-webkit-full-screen::-webkit-media-controls-rewind-button { display: none; } -video::-webkit-media-controls-return-to-realtime-button { +video:-webkit-full-screen::-webkit-media-controls-return-to-realtime-button { display: none; } -video::-webkit-media-controls-toggle-closed-captions-button { +video:-webkit-full-screen::-webkit-media-controls-toggle-closed-captions-button { display: none; } diff --git a/Source/WebCore/css/quirks.css b/Source/WebCore/css/quirks.css index 52d07e678..4845591d6 100644 --- a/Source/WebCore/css/quirks.css +++ b/Source/WebCore/css/quirks.css @@ -39,7 +39,7 @@ table { font-variant: normal; font-style: normal; color: -webkit-text; - text-align: -webkit-auto + text-align: start; } /* This will apply only to text fields, since all other inputs already use border box sizing */ diff --git a/Source/WebCore/css/themeBlackBerry.css b/Source/WebCore/css/themeBlackBerry.css index c62845c44..120ce4981 100644 --- a/Source/WebCore/css/themeBlackBerry.css +++ b/Source/WebCore/css/themeBlackBerry.css @@ -21,7 +21,7 @@ textarea { } input, textarea { - -webkit-border-radius: 3px; + border-radius: 3px; } input[type="datetime"], diff --git a/Source/WebCore/css/themeChromiumAndroid.css b/Source/WebCore/css/themeChromiumAndroid.css index 346d836af..8d0679616 100644 --- a/Source/WebCore/css/themeChromiumAndroid.css +++ b/Source/WebCore/css/themeChromiumAndroid.css @@ -36,7 +36,7 @@ select[size][multiple] { -webkit-appearance: menulist; -webkit-box-align: center; border: 1px solid; - -webkit-border-radius: 5px; + border-radius: 5px; white-space: pre; } diff --git a/Source/WebCore/css/themeQtNoListboxes.css b/Source/WebCore/css/themeQtNoListboxes.css index 4c5e44ad7..399a61e9b 100644 --- a/Source/WebCore/css/themeQtNoListboxes.css +++ b/Source/WebCore/css/themeQtNoListboxes.css @@ -31,6 +31,6 @@ select[size][multiple] { -webkit-appearance: menulist; -webkit-box-align: center; border: 1px solid; - -webkit-border-radius: 5px; + border-radius: 5px; white-space: pre; } diff --git a/Source/WebCore/css/themeWin.css b/Source/WebCore/css/themeWin.css index 3dd1ccaad..d0e5e5430 100644 --- a/Source/WebCore/css/themeWin.css +++ b/Source/WebCore/css/themeWin.css @@ -43,7 +43,7 @@ input[type="number"], input[type="password"], input[type="tel"], input[type="text"], -#if !defined(ENABLE_INPUT_TYPE_TIME_MULTIPLE_FIELDS) || !ENABLE_INPUT_TYPE_TIME_MULTIPLE_FIELDS +#if !defined(ENABLE_INPUT_MULTIPLE_FIELDS_UI) || !ENABLE_INPUT_MULTIPLE_FIELDS_UI input[type="time"], #endif input[type="url"], @@ -118,7 +118,7 @@ keygen, select, select[size="0"], select[size="1"] { - -webkit-border-radius: 0; + border-radius: 0; } /* Option font must be inherited because we depend on computing the size of the diff --git a/Source/WebCore/css/view-source.css b/Source/WebCore/css/view-source.css index 129d28219..3825c5fbb 100644 --- a/Source/WebCore/css/view-source.css +++ b/Source/WebCore/css/view-source.css @@ -129,8 +129,8 @@ tbody:last-child .webkit-line-content:empty:before { } .webkit-html-message-bubble { - -webkit-box-shadow: black 0px 2px 5px; - -webkit-border-radius: 9px; + box-shadow: black 0px 2px 5px; + border-radius: 9px; -webkit-border-fit: lines; min-height: 13px; font-size: 9px; |