Diff
Modified: trunk/Source/WebCore/ChangeLog (115335 => 115336)
--- trunk/Source/WebCore/ChangeLog 2012-04-26 18:24:48 UTC (rev 115335)
+++ trunk/Source/WebCore/ChangeLog 2012-04-26 18:44:30 UTC (rev 115336)
@@ -1,3 +1,53 @@
+2012-04-26 Antti Koivisto <[email protected]>
+
+ Implement StyleSheetInternal copying
+ https://bugs.webkit.org/show_bug.cgi?id=84969
+
+ Reviewed by Andreas Kling.
+
+ We need to be able to copy stylesheets to cache them. Copying is already implement for
+ most of the stylesheet data types but StyleSheetInternal::copy() is still missing.
+
+ Preparation for stylesheet caching. The copying code is not used yet.
+
+ * css/CSSNamespace.h:
+
+ Instead of making it copyable, remove CSSNamespace class.
+
+ * css/CSSParser.cpp:
+ (WebCore::operator==):
+ (WebCore):
+ (WebCore::CSSParser::addNamespace):
+
+ Avoid ping-ponging to StyleSheetInternal and back to set the default namespace.
+
+ * css/CSSParserMode.h:
+ (WebCore):
+ (WebCore::operator!=):
+
+ Add equality comparison operator to CSSParseMode. This will be needed to determine
+ if a cached copy can be used.
+
+ * css/CSSStyleSheet.cpp:
+ (WebCore::StyleSheetInternal::StyleSheetInternal):
+ (WebCore):
+ (WebCore::StyleSheetInternal::isCacheable):
+ (WebCore::StyleSheetInternal::parserAddNamespace):
+ (WebCore::StyleSheetInternal::determineNamespace):
+
+ Use HashMap instead of iterating a linked list of CSSNamespaces.
+
+ (WebCore::StyleSheetInternal::styleSheetChanged):
+
+ Add mutation bit.
+
+ * css/CSSStyleSheet.h:
+ (WebCore):
+ (StyleSheetInternal):
+ (WebCore::StyleSheetInternal::copy):
+
+ Copy constructor. It only usable for cacheable stylesheets.
+
2012-04-26 Philip Rogers <[email protected]>
Fix Skia's SkPathContainsPoint to work with sub-pixel accuracy
Modified: trunk/Source/WebCore/css/CSSNamespace.h (115335 => 115336)
--- trunk/Source/WebCore/css/CSSNamespace.h 2012-04-26 18:24:48 UTC (rev 115335)
+++ trunk/Source/WebCore/css/CSSNamespace.h 2012-04-26 18:44:30 UTC (rev 115336)
@@ -1,55 +1 @@
-/*
- * Copyright (C) 1999-2003 Lars Knoll ([email protected])
- * 1999 Waldo Bastian ([email protected])
- * Copyright (C) 2004, 2006, 2010 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 CSSNamespace_h
-#define CSSNamespace_h
-
-#include <wtf/text/AtomicString.h>
-
-namespace WebCore {
-
- struct CSSNamespace {
- WTF_MAKE_NONCOPYABLE(CSSNamespace); WTF_MAKE_FAST_ALLOCATED;
- public:
- AtomicString prefix;
- AtomicString uri;
- OwnPtr<CSSNamespace> parent;
-
- CSSNamespace(const AtomicString& prefix, const AtomicString& uri, PassOwnPtr<CSSNamespace> parent)
- : prefix(prefix)
- , uri(uri)
- , parent(parent)
- {
- }
-
- CSSNamespace* namespaceForPrefix(const AtomicString& prefix)
- {
- for (CSSNamespace* candidate = this; candidate; candidate = candidate->parent.get()) {
- if (candidate->prefix == prefix)
- return candidate;
- }
- return 0;
- }
- };
-
-} // namespace WebCore
-
-#endif // CSSNamespace_h
+// FIXME: Remove this file.
Modified: trunk/Source/WebCore/css/CSSParser.cpp (115335 => 115336)
--- trunk/Source/WebCore/css/CSSParser.cpp 2012-04-26 18:24:48 UTC (rev 115335)
+++ trunk/Source/WebCore/css/CSSParser.cpp 2012-04-26 18:44:30 UTC (rev 115336)
@@ -204,6 +204,18 @@
{
}
+bool operator==(const CSSParserContext& a, const CSSParserContext& b)
+{
+ return a.baseURL == b.baseURL
+ && a.charset == b.charset
+ && a.mode == b.mode
+ && a.isHTMLDocument == b.isHTMLDocument
+ && a.isCSSCustomFilterEnabled == b.isCSSCustomFilterEnabled
+ && a.isCSSRegionsEnabled == b.isCSSRegionsEnabled
+ && a.needsSiteSpecificQuirks == b.needsSiteSpecificQuirks
+ && a.enforcesCSSMIMETypeInNoQuirksMode == b.enforcesCSSMIMETypeInNoQuirksMode;
+}
+
CSSParser::CSSParser(const CSSParserContext& context)
: m_context(context)
, m_important(false)
@@ -9075,7 +9087,9 @@
if (!m_styleSheet || !m_allowNamespaceDeclarations)
return;
m_allowImportRules = false;
- m_styleSheet->addNamespace(this, prefix, uri);
+ m_styleSheet->parserAddNamespace(prefix, uri);
+ if (prefix.isEmpty() && !uri.isNull())
+ m_defaultNamespace = uri;
}
void CSSParser::updateSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector* specifiers)
Modified: trunk/Source/WebCore/css/CSSParserMode.h (115335 => 115336)
--- trunk/Source/WebCore/css/CSSParserMode.h 2012-04-26 18:24:48 UTC (rev 115335)
+++ trunk/Source/WebCore/css/CSSParserMode.h 2012-04-26 18:44:30 UTC (rev 115336)
@@ -68,6 +68,9 @@
bool enforcesCSSMIMETypeInNoQuirksMode;
};
+bool operator==(const CSSParserContext&, const CSSParserContext&);
+inline bool operator!=(const CSSParserContext& a, const CSSParserContext& b) { return !(a == b); }
+
const CSSParserContext& strictCSSParserContext();
};
Modified: trunk/Source/WebCore/css/CSSStyleSheet.cpp (115335 => 115336)
--- trunk/Source/WebCore/css/CSSStyleSheet.cpp 2012-04-26 18:24:48 UTC (rev 115335)
+++ trunk/Source/WebCore/css/CSSStyleSheet.cpp 2012-04-26 18:44:30 UTC (rev 115336)
@@ -24,7 +24,6 @@
#include "CSSCharsetRule.h"
#include "CSSFontFaceRule.h"
#include "CSSImportRule.h"
-#include "CSSNamespace.h"
#include "CSSParser.h"
#include "CSSRuleList.h"
#include "CSSStyleRule.h"
@@ -82,15 +81,64 @@
, m_hasSyntacticallyValidCSSHeader(true)
, m_didLoadErrorOccur(false)
, m_usesRemUnits(false)
+ , m_hasMutated(false)
, m_parserContext(context)
{
}
+StyleSheetInternal::StyleSheetInternal(const StyleSheetInternal& o)
+ : RefCounted<StyleSheetInternal>()
+ , m_ownerRule(0)
+ , m_originalURL(o.m_originalURL)
+ , m_finalURL(o.m_finalURL)
+ , m_title(o.m_title)
+ , m_encodingFromCharsetRule(o.m_encodingFromCharsetRule)
+ , m_importRules(o.m_importRules.size())
+ , m_childRules(o.m_childRules.size())
+ , m_namespaces(o.m_namespaces)
+ , m_mediaQueries(o.m_mediaQueries ? o.m_mediaQueries->copy() : 0)
+ , m_loadCompleted(true)
+ , m_isUserStyleSheet(o.m_isUserStyleSheet)
+ , m_hasSyntacticallyValidCSSHeader(o.m_hasSyntacticallyValidCSSHeader)
+ , m_didLoadErrorOccur(false)
+ , m_usesRemUnits(o.m_usesRemUnits)
+ , m_hasMutated(false)
+ , m_parserContext(o.m_parserContext)
+{
+ ASSERT(o.isCacheable());
+
+ // FIXME: Copy import rules.
+ ASSERT(o.m_importRules.isEmpty());
+
+ for (unsigned i = 0; i < m_childRules.size(); ++i)
+ m_childRules[i] = o.m_childRules[i]->copy();
+}
+
StyleSheetInternal::~StyleSheetInternal()
{
clearRules();
}
+bool StyleSheetInternal::isCacheable() const
+{
+ // FIXME: Support copying import rules.
+ if (!m_importRules.isEmpty())
+ return false;
+ // This would require dealing with multiple clients for load callbacks.
+ if (!m_loadCompleted)
+ return false;
+ if (m_didLoadErrorOccur)
+ return false;
+ // It is not the original sheet anymore.
+ if (m_hasMutated)
+ return false;
+ // If the header is valid we are not going to need to check the SecurityOrigin.
+ // FIXME: Valid mime type avoids the check too.
+ if (!m_hasSyntacticallyValidCSSHeader)
+ return false;
+ return true;
+}
+
void StyleSheetInternal::parserAppendRule(PassRefPtr<StyleRuleBase> rule)
{
ASSERT(!rule->isCharsetRule());
@@ -217,17 +265,11 @@
styleSheetChanged();
}
-void StyleSheetInternal::addNamespace(CSSParser* p, const AtomicString& prefix, const AtomicString& uri)
+void StyleSheetInternal::parserAddNamespace(const AtomicString& prefix, const AtomicString& uri)
{
- if (uri.isNull())
+ if (uri.isNull() || prefix.isNull())
return;
-
- m_namespaces = adoptPtr(new CSSNamespace(prefix, uri, m_namespaces.release()));
-
- if (prefix.isEmpty())
- // Set the default namespace on the parser so that selectors that omit namespace info will
- // be able to pick it up easily.
- p->m_defaultNamespace = uri;
+ m_namespaces.add(prefix, uri);
}
const AtomicString& StyleSheetInternal::determineNamespace(const AtomicString& prefix)
@@ -236,11 +278,10 @@
return nullAtom; // No namespace. If an element/attribute has a namespace, we won't match it.
if (prefix == starAtom)
return starAtom; // We'll match any namespace.
- if (m_namespaces) {
- if (CSSNamespace* namespaceForPrefix = m_namespaces->namespaceForPrefix(prefix))
- return namespaceForPrefix->uri;
- }
- return nullAtom; // Assume we won't match any namespaces.
+ PrefixNamespaceURIMap::const_iterator it = m_namespaces.find(prefix);
+ if (it == m_namespaces.end())
+ return nullAtom;
+ return it->second;
}
void StyleSheetInternal::parseUserStyleSheet(const CachedCSSStyleSheet* cachedStyleSheet, const SecurityOrigin* securityOrigin)
@@ -365,6 +406,8 @@
void StyleSheetInternal::styleSheetChanged()
{
+ m_hasMutated = true;
+
Document* ownerDocument = singleOwnerDocument();
if (!ownerDocument)
return;
Modified: trunk/Source/WebCore/css/CSSStyleSheet.h (115335 => 115336)
--- trunk/Source/WebCore/css/CSSStyleSheet.h 2012-04-26 18:24:48 UTC (rev 115335)
+++ trunk/Source/WebCore/css/CSSStyleSheet.h 2012-04-26 18:44:30 UTC (rev 115336)
@@ -23,6 +23,8 @@
#include "CSSParserMode.h"
#include "StyleSheet.h"
+#include <wtf/HashMap.h>
+#include <wtf/text/AtomicStringHash.h>
namespace WebCore {
@@ -39,7 +41,6 @@
class SecurityOrigin;
class StyleRuleBase;
class StyleRuleImport;
-struct CSSNamespace;
typedef int ExceptionCode;
@@ -62,7 +63,6 @@
const CSSParserContext& parserContext() const { return m_parserContext; }
- void addNamespace(CSSParser*, const AtomicString& prefix, const AtomicString& uri);
const AtomicString& determineNamespace(const AtomicString& prefix);
void styleSheetChanged();
@@ -71,6 +71,8 @@
bool parseString(const String&);
bool parseStringAtLine(const String&, int startLineNumber);
+ bool isCacheable() const;
+
bool isLoading() const;
void checkLoaded();
@@ -92,6 +94,7 @@
void setHasSyntacticallyValidCSSHeader(bool b) { m_hasSyntacticallyValidCSSHeader = b; }
bool hasSyntacticallyValidCSSHeader() const { return m_hasSyntacticallyValidCSSHeader; }
+ void parserAddNamespace(const AtomicString& prefix, const AtomicString& uri);
void parserAppendRule(PassRefPtr<StyleRuleBase>);
void parserSetEncodingFromCharsetRule(const String& encoding);
void parserSetUsesRemUnits(bool b) { m_usesRemUnits = b; }
@@ -130,12 +133,15 @@
PassRefPtr<CSSRule> createChildRuleCSSOMWrapper(unsigned index, CSSStyleSheet* parentWrapper);
+ PassRefPtr<StyleSheetInternal> copy() const { return adoptRef(new StyleSheetInternal(*this)); }
+
void registerClient(CSSStyleSheet*);
void unregisterClient(CSSStyleSheet*);
private:
StyleSheetInternal(StyleRuleImport* ownerRule, const String& originalURL, const KURL& baseURL, const CSSParserContext&);
-
+ StyleSheetInternal(const StyleSheetInternal&);
+
void clearCharsetRule();
bool hasCharsetRule() const { return !m_encodingFromCharsetRule.isNull(); }
@@ -150,7 +156,8 @@
String m_encodingFromCharsetRule;
Vector<RefPtr<StyleRuleImport> > m_importRules;
Vector<RefPtr<StyleRuleBase> > m_childRules;
- OwnPtr<CSSNamespace> m_namespaces;
+ typedef HashMap<AtomicString, AtomicString> PrefixNamespaceURIMap;
+ PrefixNamespaceURIMap m_namespaces;
RefPtr<MediaQuerySet> m_mediaQueries;
bool m_loadCompleted : 1;
@@ -158,6 +165,7 @@
bool m_hasSyntacticallyValidCSSHeader : 1;
bool m_didLoadErrorOccur : 1;
bool m_usesRemUnits : 1;
+ bool m_hasMutated : 1;
CSSParserContext m_parserContext;