css/StyleResolver.cpp
css/StyleRule.cpp
css/StyleSheet.cpp
+ css/StyleSheetContents.cpp
css/StyleSheetList.cpp
css/WebKitCSSFilterValue.cpp
css/WebKitCSSKeyframeRule.cpp
+2012-05-24 Antti Koivisto <antti@apple.com>
+
+ Move StyleSheetContents to a separate file
+ https://bugs.webkit.org/show_bug.cgi?id=87354
+
+ Reviewed by Eric Seidel.
+
+ Move StyleSheetContents class to StyleSheetContents.h/cpp.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * Target.pri:
+ * WebCore.gypi:
+ * WebCore.vcproj/WebCore.vcproj:
+ * WebCore.xcodeproj/project.pbxproj:
+ * css/CSSFontFaceSrcValue.cpp:
+ * css/CSSGrammar.y:
+ * css/CSSImportRule.cpp:
+ * css/CSSParser.cpp:
+ * css/CSSPrimitiveValue.cpp:
+ * css/CSSRule.cpp:
+ * css/CSSStyleSheet.cpp:
+ (WebCore::CSSStyleSheet::create):
+ (WebCore::CSSStyleSheet::href):
+ (WebCore):
+ (WebCore::CSSStyleSheet::baseURL):
+ (WebCore::CSSStyleSheet::isLoading):
+ * css/CSSStyleSheet.h:
+ (WebCore):
+ (CSSStyleSheet):
+ * css/StylePropertySet.cpp:
+ * css/StyleResolver.cpp:
+ * css/StyleSheetContents.cpp: Copied from css/CSSStyleSheet.cpp.
+ (WebCore):
+ * css/StyleSheetContents.h: Copied from css/CSSStyleSheet.h.
+ (WebCore):
+ * dom/DOMImplementation.cpp:
+ (WebCore::XMLMIMETypeRegExp::XMLMIMETypeRegExp):
+ * dom/Document.cpp:
+ * dom/ProcessingInstruction.cpp:
+ * dom/StyleElement.cpp:
+ * html/HTMLLinkElement.cpp:
+ * html/HTMLStyleElement.cpp:
+ * inspector/InspectorStyleSheet.cpp:
+ * loader/cache/CachedCSSStyleSheet.cpp:
+ * page/PageSerializer.cpp:
+
2012-05-24 Kristóf Kosztyó <kkristof@inf.u-szeged.hu>
[Qt] Buildfix for the minimal build because the r118197 broke it.
Source/WebCore/css/StyleRule.h \
Source/WebCore/css/StyleSheet.cpp \
Source/WebCore/css/StyleSheet.h \
+ Source/WebCore/css/StyleSheetContents.cpp \
+ Source/WebCore/css/StyleSheetContents.h \
Source/WebCore/css/StyleSheetList.cpp \
Source/WebCore/css/StyleSheetList.h \
Source/WebCore/css/SVGCSSComputedStyleDeclaration.cpp \
css/StyleResolver.cpp \
css/StyleRule.cpp \
css/StyleSheet.cpp \
+ css/StyleSheetContents.cpp \
css/StyleSheetList.cpp \
css/WebKitCSSFilterValue.cpp \
css/WebKitCSSKeyframeRule.cpp \
css/StyleResolver.h \
css/StyleRule.h \
css/StyleSheet.h \
+ css/StyleSheetContents.h \
css/StyleSheetList.h \
css/WebKitCSSFilterValue.h \
css/WebKitCSSKeyframeRule.h \
'css/StyleRule.h',
'css/StyleSheet.cpp',
'css/StyleSheet.h',
+ 'css/StyleSheetContents.cpp',
+ 'css/StyleSheetContents.h',
'css/StyleSheetList.cpp',
'css/StyleSheetList.h',
'css/WebKitCSSFilterValue.cpp',
>
</File>
<File
+ RelativePath="..\css\StyleSheetContents.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\css\StyleSheetContents.h"
+ >
+ </File>
+ <File
RelativePath="..\css\StyleSheetList.cpp"
>
</File>
1432E8490C51493F00B1500F /* GCController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1432E8480C51493F00B1500F /* GCController.cpp */; };
1449E24C107D4A8400B5793F /* JSCallbackData.h in Headers */ = {isa = PBXBuildFile; fileRef = 1449E24A107D4A8400B5793F /* JSCallbackData.h */; };
1449E287107D4DB400B5793F /* JSCallbackData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1449E286107D4DB400B5793F /* JSCallbackData.cpp */; };
- 1482E0C6156C36DE00965065 /* FractionalLayoutBoxExtent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1482E0C4156C36DE00965065 /* FractionalLayoutBoxExtent.cpp */; };
- 1482E0C7156C36DE00965065 /* FractionalLayoutBoxExtent.h in Headers */ = {isa = PBXBuildFile; fileRef = 1482E0C5156C36DE00965065 /* FractionalLayoutBoxExtent.h */; settings = {ATTRIBUTES = (Private, ); }; };
144FCE5214EC79BC000D17A3 /* FractionalLayoutUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 144FCE5114EC79BC000D17A3 /* FractionalLayoutUnit.h */; settings = {ATTRIBUTES = (Private, ); }; };
144FCE5D14EC79E7000D17A3 /* FractionalLayoutSize.h in Headers */ = {isa = PBXBuildFile; fileRef = 144FCE5814EC79E7000D17A3 /* FractionalLayoutSize.h */; settings = {ATTRIBUTES = (Private, ); }; };
144FCFE014EF2509000D17A3 /* FractionalLayoutRect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 144FCFDE14EF2509000D17A3 /* FractionalLayoutRect.cpp */; };
1479FAF2109AE37500DED655 /* RenderRubyRun.h in Headers */ = {isa = PBXBuildFile; fileRef = 1479FAEA109AE37500DED655 /* RenderRubyRun.h */; };
1479FAF3109AE37500DED655 /* RenderRubyText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1479FAEB109AE37500DED655 /* RenderRubyText.cpp */; };
1479FAF4109AE37500DED655 /* RenderRubyText.h in Headers */ = {isa = PBXBuildFile; fileRef = 1479FAEC109AE37500DED655 /* RenderRubyText.h */; };
+ 1482E0C6156C36DE00965065 /* FractionalLayoutBoxExtent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1482E0C4156C36DE00965065 /* FractionalLayoutBoxExtent.cpp */; };
+ 1482E0C7156C36DE00965065 /* FractionalLayoutBoxExtent.h in Headers */ = {isa = PBXBuildFile; fileRef = 1482E0C5156C36DE00965065 /* FractionalLayoutBoxExtent.h */; settings = {ATTRIBUTES = (Private, ); }; };
148AFDA50AF58360008CC700 /* ExceptionHandlers.h in Headers */ = {isa = PBXBuildFile; fileRef = 148AFDA30AF58360008CC700 /* ExceptionHandlers.h */; settings = {ATTRIBUTES = (Private, ); }; };
148AFDA60AF58360008CC700 /* ExceptionHandlers.mm in Sources */ = {isa = PBXBuildFile; fileRef = 148AFDA40AF58360008CC700 /* ExceptionHandlers.mm */; };
14947FFD12F80CD200A0F631 /* DocumentOrderedMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14947FFB12F80CD200A0F631 /* DocumentOrderedMap.cpp */; };
E4C279590CF9741900E97B98 /* RenderMedia.h in Headers */ = {isa = PBXBuildFile; fileRef = E4C279570CF9741900E97B98 /* RenderMedia.h */; };
E4D687770ED7AE3D006EA978 /* PurgeableBufferMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4D687760ED7AE3D006EA978 /* PurgeableBufferMac.cpp */; };
E4D687790ED7AE4F006EA978 /* PurgeableBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D687780ED7AE4F006EA978 /* PurgeableBuffer.h */; };
+ E4F9EEF2156D9FFA00D23E7E /* StyleSheetContents.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4F9EEF0156D84C400D23E7E /* StyleSheetContents.cpp */; };
+ E4F9EEF3156DA00700D23E7E /* StyleSheetContents.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */; };
E55F497A151B888000BB67DB /* LengthFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E55F4979151B888000BB67DB /* LengthFunctions.cpp */; };
E5BA7D63151437CA00FE1E3F /* LengthFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = E5BA7D62151437CA00FE1E3F /* LengthFunctions.h */; settings = {ATTRIBUTES = (Private, ); }; };
ED2BA83C09A24B91006C0AC4 /* DocumentMarker.h in Headers */ = {isa = PBXBuildFile; fileRef = ED2BA83B09A24B91006C0AC4 /* DocumentMarker.h */; settings = {ATTRIBUTES = (Private, ); }; };
1432E8480C51493F00B1500F /* GCController.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GCController.cpp; sourceTree = "<group>"; };
1449E24A107D4A8400B5793F /* JSCallbackData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCallbackData.h; sourceTree = "<group>"; };
1449E286107D4DB400B5793F /* JSCallbackData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCallbackData.cpp; sourceTree = "<group>"; };
- 1482E0C4156C36DE00965065 /* FractionalLayoutBoxExtent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FractionalLayoutBoxExtent.cpp; sourceTree = "<group>"; };
- 1482E0C5156C36DE00965065 /* FractionalLayoutBoxExtent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FractionalLayoutBoxExtent.h; sourceTree = "<group>"; };
144FCE5114EC79BC000D17A3 /* FractionalLayoutUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FractionalLayoutUnit.h; sourceTree = "<group>"; };
144FCE5414EC79E7000D17A3 /* FractionalLayoutPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FractionalLayoutPoint.h; sourceTree = "<group>"; };
144FCE5814EC79E7000D17A3 /* FractionalLayoutSize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FractionalLayoutSize.h; sourceTree = "<group>"; };
1479FAEB109AE37500DED655 /* RenderRubyText.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderRubyText.cpp; sourceTree = "<group>"; };
1479FAEC109AE37500DED655 /* RenderRubyText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderRubyText.h; sourceTree = "<group>"; };
14813BF309EDF88E00F757E1 /* IDLParser.pm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.perl; name = IDLParser.pm; path = scripts/IDLParser.pm; sourceTree = "<group>"; };
+ 1482E0C4156C36DE00965065 /* FractionalLayoutBoxExtent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FractionalLayoutBoxExtent.cpp; sourceTree = "<group>"; };
+ 1482E0C5156C36DE00965065 /* FractionalLayoutBoxExtent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FractionalLayoutBoxExtent.h; sourceTree = "<group>"; };
148AFDA30AF58360008CC700 /* ExceptionHandlers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ExceptionHandlers.h; sourceTree = "<group>"; };
148AFDA40AF58360008CC700 /* ExceptionHandlers.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = ExceptionHandlers.mm; sourceTree = "<group>"; };
14947FFB12F80CD200A0F631 /* DocumentOrderedMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentOrderedMap.cpp; sourceTree = "<group>"; };
E4C279570CF9741900E97B98 /* RenderMedia.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderMedia.h; sourceTree = "<group>"; };
E4D687760ED7AE3D006EA978 /* PurgeableBufferMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PurgeableBufferMac.cpp; sourceTree = "<group>"; };
E4D687780ED7AE4F006EA978 /* PurgeableBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PurgeableBuffer.h; sourceTree = "<group>"; };
+ E4F9EEF0156D84C400D23E7E /* StyleSheetContents.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleSheetContents.cpp; sourceTree = "<group>"; };
+ E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleSheetContents.h; sourceTree = "<group>"; };
E55F4979151B888000BB67DB /* LengthFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LengthFunctions.cpp; sourceTree = "<group>"; };
E5BA7D62151437CA00FE1E3F /* LengthFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LengthFunctions.h; sourceTree = "<group>"; };
ED2BA83B09A24B91006C0AC4 /* DocumentMarker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DocumentMarker.h; sourceTree = "<group>"; };
A8EA80050A19516E00A8EF5F /* StyleSheet.cpp */,
A8EA80040A19516E00A8EF5F /* StyleSheet.h */,
850656DC0AAB44D9002D15C0 /* StyleSheet.idl */,
+ E4F9EEF0156D84C400D23E7E /* StyleSheetContents.cpp */,
+ E4F9EEF1156D84C400D23E7E /* StyleSheetContents.h */,
A8EA80030A19516E00A8EF5F /* StyleSheetList.cpp */,
A8EA80020A19516E00A8EF5F /* StyleSheetList.h */,
850656DF0AAB454F002D15C0 /* StyleSheetList.idl */,
FDB052E01561A42C00B500D6 /* AudioSummingJunction.h in Headers */,
371941971566B37200A276D8 /* WebCoreNSCellExtras.h in Headers */,
1482E0C7156C36DE00965065 /* FractionalLayoutBoxExtent.h in Headers */,
+ E4F9EEF3156DA00700D23E7E /* StyleSheetContents.h in Headers */,
BC1BDF25156C18C7001C1243 /* DOMError.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
371941961566B37200A276D8 /* WebCoreNSCellExtras.m in Sources */,
146CC115156988E400109E37 /* LengthBox.cpp in Sources */,
1482E0C6156C36DE00965065 /* FractionalLayoutBoxExtent.cpp in Sources */,
+ E4F9EEF2156D9FFA00D23E7E /* StyleSheetContents.cpp in Sources */,
BC1BDF24156C1883001C1243 /* DOMError.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
#include "config.h"
#include "CSSFontFaceSrcValue.h"
-#include "CSSStyleSheet.h"
#include "CachedFont.h"
#include "CachedResourceLoader.h"
#include "Document.h"
#include "FontCustomPlatformData.h"
#include "Node.h"
+#include "StyleSheetContents.h"
namespace WebCore {
#include "CSSPropertyNames.h"
#include "CSSSelector.h"
#include "CSSSelectorList.h"
-#include "CSSStyleSheet.h"
#include "Document.h"
#include "HTMLNames.h"
#include "MediaList.h"
#include "MediaQueryExp.h"
#include "StyleRule.h"
+#include "StyleSheetContents.h"
#include "WebKitCSSKeyframeRule.h"
#include "WebKitCSSKeyframesRule.h"
#include <wtf/FastMalloc.h>
#include "MediaList.h"
#include "SecurityOrigin.h"
#include "Settings.h"
+#include "StyleSheetContents.h"
#include <wtf/StdLibExtras.h>
#include <wtf/text/StringBuilder.h>
#include "CSSReflectValue.h"
#include "CSSSelector.h"
#include "CSSStyleRule.h"
-#include "CSSStyleSheet.h"
#include "CSSTimingFunctionValue.h"
#include "CSSUnicodeRangeValue.h"
#include "CSSValueKeywords.h"
#include "StylePropertySet.h"
#include "StylePropertyShorthand.h"
#include "StyleRule.h"
+#include "StyleSheetContents.h"
#include "TextEncoding.h"
#if ENABLE(CSS_FILTERS)
#include "WebKitCSSFilterValue.h"
#include "CSSHelper.h"
#include "CSSParser.h"
#include "CSSPropertyNames.h"
-#include "CSSStyleSheet.h"
#include "CSSValueKeywords.h"
#include "CSSWrapShapes.h"
#include "CalculationValue.h"
#include "RGBColor.h"
#include "Rect.h"
#include "RenderStyle.h"
+#include "StyleSheetContents.h"
#include <wtf/ASCIICType.h>
#include <wtf/DecimalNumber.h>
#include <wtf/StdLibExtras.h>
#include "WebKitCSSRegionRule.h"
#include "NotImplemented.h"
#include "StyleRule.h"
+#include "StyleSheetContents.h"
namespace WebCore {
#include "Node.h"
#include "SVGNames.h"
#include "SecurityOrigin.h"
-#include "StylePropertySet.h"
#include "StyleRule.h"
-#include <wtf/Deque.h>
+#include "StyleSheetContents.h"
namespace WebCore {
}
#endif
-// Rough size estimate for the memory cache.
-unsigned StyleSheetContents::estimatedSizeInBytes() const
-{
- // Note that this does not take into account size of the strings hanging from various objects.
- // The assumption is that nearly all of of them are atomic and would exist anyway.
- unsigned size = sizeof(*this);
-
- // FIXME: This ignores the children of media and region rules.
- // Most rules are StyleRules.
- size += ruleCount() * StyleRule::averageSizeInBytes();
-
- for (unsigned i = 0; i < m_importRules.size(); ++i) {
- if (StyleSheetContents* sheet = m_importRules[i]->styleSheet())
- size += sheet->estimatedSizeInBytes();
- }
- return size;
-}
-
-StyleSheetContents::StyleSheetContents(StyleRuleImport* ownerRule, const String& originalURL, const KURL& finalURL, const CSSParserContext& context)
- : m_ownerRule(ownerRule)
- , m_originalURL(originalURL)
- , m_finalURL(finalURL)
- , m_loadCompleted(false)
- , m_isUserStyleSheet(ownerRule && ownerRule->parentStyleSheet() && ownerRule->parentStyleSheet()->isUserStyleSheet())
- , m_hasSyntacticallyValidCSSHeader(true)
- , m_didLoadErrorOccur(false)
- , m_usesRemUnits(false)
- , m_isMutable(false)
- , m_isInMemoryCache(false)
- , m_parserContext(context)
-{
-}
-
-StyleSheetContents::StyleSheetContents(const StyleSheetContents& o)
- : RefCounted<StyleSheetContents>()
- , m_ownerRule(0)
- , m_originalURL(o.m_originalURL)
- , m_finalURL(o.m_finalURL)
- , m_encodingFromCharsetRule(o.m_encodingFromCharsetRule)
- , m_importRules(o.m_importRules.size())
- , m_childRules(o.m_childRules.size())
- , m_namespaces(o.m_namespaces)
- , m_loadCompleted(true)
- , m_isUserStyleSheet(o.m_isUserStyleSheet)
- , m_hasSyntacticallyValidCSSHeader(o.m_hasSyntacticallyValidCSSHeader)
- , m_didLoadErrorOccur(false)
- , m_usesRemUnits(o.m_usesRemUnits)
- , m_isMutable(false)
- , m_isInMemoryCache(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();
-}
-
-StyleSheetContents::~StyleSheetContents()
-{
- clearRules();
-}
-
-bool StyleSheetContents::isCacheable() const
-{
- // FIXME: Support copying import rules.
- if (!m_importRules.isEmpty())
- return false;
- // FIXME: Support cached stylesheets in import rules.
- if (m_ownerRule)
- 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_isMutable)
- 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 StyleSheetContents::parserAppendRule(PassRefPtr<StyleRuleBase> rule)
-{
- ASSERT(!rule->isCharsetRule());
- if (rule->isImportRule()) {
- // Parser enforces that @import rules come before anything else except @charset.
- ASSERT(m_childRules.isEmpty());
- m_importRules.append(static_cast<StyleRuleImport*>(rule.get()));
- m_importRules.last()->setParentStyleSheet(this);
- m_importRules.last()->requestStyleSheet();
- return;
- }
- m_childRules.append(rule);
-}
-
-StyleRuleBase* StyleSheetContents::ruleAt(unsigned index) const
-{
- ASSERT(index < ruleCount());
-
- unsigned childVectorIndex = index;
- if (hasCharsetRule()) {
- if (index == 0)
- return 0;
- --childVectorIndex;
- }
- if (childVectorIndex < m_importRules.size())
- return m_importRules[childVectorIndex].get();
-
- childVectorIndex -= m_importRules.size();
- return m_childRules[childVectorIndex].get();
-}
-
-unsigned StyleSheetContents::ruleCount() const
-{
- unsigned result = 0;
- result += hasCharsetRule() ? 1 : 0;
- result += m_importRules.size();
- result += m_childRules.size();
- return result;
-}
-
-void StyleSheetContents::clearCharsetRule()
-{
- m_encodingFromCharsetRule = String();
-}
-
-void StyleSheetContents::clearRules()
-{
- for (unsigned i = 0; i < m_importRules.size(); ++i) {
- ASSERT(m_importRules.at(i)->parentStyleSheet() == this);
- m_importRules[i]->clearParentStyleSheet();
- }
- m_importRules.clear();
- m_childRules.clear();
- clearCharsetRule();
-}
-
-void StyleSheetContents::parserSetEncodingFromCharsetRule(const String& encoding)
-{
- // Parser enforces that there is ever only one @charset.
- ASSERT(m_encodingFromCharsetRule.isNull());
- m_encodingFromCharsetRule = encoding;
-}
-
-bool StyleSheetContents::wrapperInsertRule(PassRefPtr<StyleRuleBase> rule, unsigned index)
-{
- ASSERT(m_isMutable);
- ASSERT(index <= ruleCount());
- // Parser::parseRule doesn't currently allow @charset so we don't need to deal with it.
- ASSERT(!rule->isCharsetRule());
-
- unsigned childVectorIndex = index;
- // m_childRules does not contain @charset which is always in index 0 if it exists.
- if (hasCharsetRule()) {
- if (childVectorIndex == 0) {
- // Nothing can be inserted before @charset.
- return false;
- }
- --childVectorIndex;
- }
-
- if (childVectorIndex < m_importRules.size() || (childVectorIndex == m_importRules.size() && rule->isImportRule())) {
- // Inserting non-import rule before @import is not allowed.
- if (!rule->isImportRule())
- return false;
- m_importRules.insert(childVectorIndex, static_cast<StyleRuleImport*>(rule.get()));
- m_importRules[childVectorIndex]->setParentStyleSheet(this);
- m_importRules[childVectorIndex]->requestStyleSheet();
- // FIXME: Stylesheet doesn't actually change meaningfully before the imported sheets are loaded.
- return true;
- }
- // Inserting @import rule after a non-import rule is not allowed.
- if (rule->isImportRule())
- return false;
- childVectorIndex -= m_importRules.size();
-
- m_childRules.insert(childVectorIndex, rule);
- return true;
-}
-
-void StyleSheetContents::wrapperDeleteRule(unsigned index)
-{
- ASSERT(m_isMutable);
- ASSERT(index < ruleCount());
-
- unsigned childVectorIndex = index;
- if (hasCharsetRule()) {
- if (childVectorIndex == 0) {
- clearCharsetRule();
- return;
- }
- --childVectorIndex;
- }
- if (childVectorIndex < m_importRules.size()) {
- m_importRules[childVectorIndex]->clearParentStyleSheet();
- m_importRules.remove(childVectorIndex);
- return;
- }
- childVectorIndex -= m_importRules.size();
-
- m_childRules.remove(childVectorIndex);
-}
-
-void StyleSheetContents::parserAddNamespace(const AtomicString& prefix, const AtomicString& uri)
-{
- if (uri.isNull() || prefix.isNull())
- return;
- m_namespaces.add(prefix, uri);
-}
-
-const AtomicString& StyleSheetContents::determineNamespace(const AtomicString& prefix)
-{
- if (prefix.isNull())
- 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.
- PrefixNamespaceURIMap::const_iterator it = m_namespaces.find(prefix);
- if (it == m_namespaces.end())
- return nullAtom;
- return it->second;
-}
-
-void StyleSheetContents::parseAuthorStyleSheet(const CachedCSSStyleSheet* cachedStyleSheet, const SecurityOrigin* securityOrigin)
-{
- // Check to see if we should enforce the MIME type of the CSS resource in strict mode.
- // Running in iWeb 2 is one example of where we don't want to - <rdar://problem/6099748>
- bool enforceMIMEType = isStrictParserMode(m_parserContext.mode) && m_parserContext.enforcesCSSMIMETypeInNoQuirksMode;
- bool hasValidMIMEType = false;
- String sheetText = cachedStyleSheet->sheetText(enforceMIMEType, &hasValidMIMEType);
-
- CSSParser p(parserContext());
- p.parseSheet(this, sheetText, 0);
-
- // If we're loading a stylesheet cross-origin, and the MIME type is not standard, require the CSS
- // to at least start with a syntactically valid CSS rule.
- // This prevents an attacker playing games by injecting CSS strings into HTML, XML, JSON, etc. etc.
- if (!hasValidMIMEType && !hasSyntacticallyValidCSSHeader()) {
- bool isCrossOriginCSS = !securityOrigin || !securityOrigin->canRequest(finalURL());
- if (isCrossOriginCSS) {
- clearRules();
- return;
- }
- }
- if (m_parserContext.needsSiteSpecificQuirks && isStrictParserMode(m_parserContext.mode)) {
- // Work around <https://bugs.webkit.org/show_bug.cgi?id=28350>.
- DEFINE_STATIC_LOCAL(const String, slashKHTMLFixesDotCss, ("/KHTMLFixes.css"));
- DEFINE_STATIC_LOCAL(const String, mediaWikiKHTMLFixesStyleSheet, ("/* KHTML fix stylesheet */\n/* work around the horizontal scrollbars */\n#column-content { margin-left: 0; }\n\n"));
- // There are two variants of KHTMLFixes.css. One is equal to mediaWikiKHTMLFixesStyleSheet,
- // while the other lacks the second trailing newline.
- if (finalURL().string().endsWith(slashKHTMLFixesDotCss) && !sheetText.isNull() && mediaWikiKHTMLFixesStyleSheet.startsWith(sheetText)
- && sheetText.length() >= mediaWikiKHTMLFixesStyleSheet.length() - 1)
- clearRules();
- }
-}
-
-bool StyleSheetContents::parseString(const String& sheetText)
-{
- return parseStringAtLine(sheetText, 0);
-}
-
-bool StyleSheetContents::parseStringAtLine(const String& sheetText, int startLineNumber)
-{
- CSSParser p(parserContext());
- p.parseSheet(this, sheetText, startLineNumber);
-
- return true;
-}
-
-bool StyleSheetContents::isLoading() const
-{
- for (unsigned i = 0; i < m_importRules.size(); ++i) {
- if (m_importRules[i]->isLoading())
- return true;
- }
- return false;
-}
-
-void StyleSheetContents::checkLoaded()
-{
- if (isLoading())
- return;
-
- // Avoid |this| being deleted by scripts that run via
- // ScriptableDocumentParser::executeScriptsWaitingForStylesheets().
- // See <rdar://problem/6622300>.
- RefPtr<StyleSheetContents> protector(this);
- StyleSheetContents* parentSheet = parentStyleSheet();
- if (parentSheet) {
- parentSheet->checkLoaded();
- m_loadCompleted = true;
- return;
- }
- RefPtr<Node> ownerNode = singleOwnerNode();
- if (!ownerNode) {
- m_loadCompleted = true;
- return;
- }
- m_loadCompleted = ownerNode->sheetLoaded();
- if (m_loadCompleted)
- ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOccur);
-}
-
-void StyleSheetContents::notifyLoadedSheet(const CachedCSSStyleSheet* sheet)
-{
- ASSERT(sheet);
- m_didLoadErrorOccur |= sheet->errorOccurred();
-}
-
-void StyleSheetContents::startLoadingDynamicSheet()
-{
- if (Node* owner = singleOwnerNode())
- owner->startLoadingDynamicSheet();
-}
-
-StyleSheetContents* StyleSheetContents::rootStyleSheet() const
-{
- const StyleSheetContents* root = this;
- while (root->parentStyleSheet())
- root = root->parentStyleSheet();
- return const_cast<StyleSheetContents*>(root);
-}
-
-Node* StyleSheetContents::singleOwnerNode() const
-{
- StyleSheetContents* root = rootStyleSheet();
- if (root->m_clients.isEmpty())
- return 0;
- ASSERT(root->m_clients.size() == 1);
- return root->m_clients[0]->ownerNode();
-}
-
-Document* StyleSheetContents::singleOwnerDocument() const
-{
- Node* ownerNode = singleOwnerNode();
- return ownerNode ? ownerNode->document() : 0;
-}
-
-KURL StyleSheetContents::completeURL(const String& url) const
-{
- return CSSParser::completeURL(m_parserContext, url);
-}
-
-void StyleSheetContents::addSubresourceStyleURLs(ListHashSet<KURL>& urls)
-{
- Deque<StyleSheetContents*> styleSheetQueue;
- styleSheetQueue.append(this);
-
- while (!styleSheetQueue.isEmpty()) {
- StyleSheetContents* styleSheet = styleSheetQueue.takeFirst();
-
- for (unsigned i = 0; i < styleSheet->m_importRules.size(); ++i) {
- StyleRuleImport* importRule = styleSheet->m_importRules[i].get();
- if (importRule->styleSheet()) {
- styleSheetQueue.append(importRule->styleSheet());
- addSubresourceURL(urls, importRule->styleSheet()->baseURL());
- }
- }
- for (unsigned i = 0; i < styleSheet->m_childRules.size(); ++i) {
- StyleRuleBase* rule = styleSheet->m_childRules[i].get();
- if (rule->isStyleRule())
- static_cast<StyleRule*>(rule)->properties()->addSubresourceStyleURLs(urls, this);
- else if (rule->isFontFaceRule())
- static_cast<StyleRuleFontFace*>(rule)->properties()->addSubresourceStyleURLs(urls, this);
- }
- }
-}
-
-StyleSheetContents* StyleSheetContents::parentStyleSheet() const
-{
- return m_ownerRule ? m_ownerRule->parentStyleSheet() : 0;
-}
-
-void StyleSheetContents::registerClient(CSSStyleSheet* sheet)
-{
- ASSERT(!m_clients.contains(sheet));
- m_clients.append(sheet);
-}
-
-void StyleSheetContents::unregisterClient(CSSStyleSheet* sheet)
-{
- size_t position = m_clients.find(sheet);
- ASSERT(position != notFound);
- m_clients.remove(position);
-}
-
-void StyleSheetContents::addedToMemoryCache()
-{
- ASSERT(!m_isInMemoryCache);
- ASSERT(isCacheable());
- m_isInMemoryCache = true;
+PassRefPtr<CSSStyleSheet> CSSStyleSheet::create(PassRefPtr<StyleSheetContents> sheet, CSSImportRule* ownerRule)
+{
+ return adoptRef(new CSSStyleSheet(sheet, ownerRule));
}
-void StyleSheetContents::removedFromMemoryCache()
-{
- ASSERT(m_isInMemoryCache);
- ASSERT(isCacheable());
- m_isInMemoryCache = false;
+PassRefPtr<CSSStyleSheet> CSSStyleSheet::create(PassRefPtr<StyleSheetContents> sheet, Node* ownerNode)
+{
+ return adoptRef(new CSSStyleSheet(sheet, ownerNode));
}
PassRefPtr<CSSStyleSheet> CSSStyleSheet::createInline(Node* ownerNode, const KURL& baseURL, const String& encoding)
return m_ruleListCSSOMWrapper.get();
}
+String CSSStyleSheet::href() const
+{
+ return m_contents->originalURL();
+}
+
+KURL CSSStyleSheet::baseURL() const
+{
+ return m_contents->baseURL();
+}
+
+bool CSSStyleSheet::isLoading() const
+{
+ return m_contents->isLoading();
+}
+
MediaList* CSSStyleSheet::media() const
{
if (!m_mediaQueries)
class CSSRuleList;
class CSSStyleSheet;
class CachedCSSStyleSheet;
-class CachedResourceLoader;
class Document;
class MediaQuerySet;
class SecurityOrigin;
-class StyleRuleBase;
-class StyleRuleImport;
+class StyleSheetContents;
typedef int ExceptionCode;
-class StyleSheetContents : public RefCounted<StyleSheetContents> {
-public:
- static PassRefPtr<StyleSheetContents> create(const CSSParserContext& context = CSSParserContext(CSSStrictMode))
- {
- return adoptRef(new StyleSheetContents(0, String(), KURL(), context));
- }
- static PassRefPtr<StyleSheetContents> create(const String& originalURL, const KURL& finalURL, const CSSParserContext& context)
- {
- return adoptRef(new StyleSheetContents(0, originalURL, finalURL, context));
- }
- static PassRefPtr<StyleSheetContents> create(StyleRuleImport* ownerRule, const String& originalURL, const KURL& finalURL, const CSSParserContext& context)
- {
- return adoptRef(new StyleSheetContents(ownerRule, originalURL, finalURL, context));
- }
-
- ~StyleSheetContents();
-
- const CSSParserContext& parserContext() const { return m_parserContext; }
-
- const AtomicString& determineNamespace(const AtomicString& prefix);
-
- void parseAuthorStyleSheet(const CachedCSSStyleSheet*, const SecurityOrigin*);
- bool parseString(const String&);
- bool parseStringAtLine(const String&, int startLineNumber);
-
- bool isCacheable() const;
-
- bool isLoading() const;
-
- void checkLoaded();
- void startLoadingDynamicSheet();
-
- StyleSheetContents* rootStyleSheet() const;
- Node* singleOwnerNode() const;
- Document* singleOwnerDocument() const;
-
- const String& charset() const { return m_parserContext.charset; }
-
- bool loadCompleted() const { return m_loadCompleted; }
-
- KURL completeURL(const String& url) const;
- void addSubresourceStyleURLs(ListHashSet<KURL>&);
-
- void setIsUserStyleSheet(bool b) { m_isUserStyleSheet = b; }
- bool isUserStyleSheet() const { return m_isUserStyleSheet; }
- 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; }
-
- void clearRules();
-
- bool hasCharsetRule() const { return !m_encodingFromCharsetRule.isNull(); }
- String encodingFromCharsetRule() const { return m_encodingFromCharsetRule; }
- // Rules other than @charset and @import.
- const Vector<RefPtr<StyleRuleBase> >& childRules() const { return m_childRules; }
- const Vector<RefPtr<StyleRuleImport> >& importRules() const { return m_importRules; }
-
- void notifyLoadedSheet(const CachedCSSStyleSheet*);
-
- StyleSheetContents* parentStyleSheet() const;
- StyleRuleImport* ownerRule() const { return m_ownerRule; }
- void clearOwnerRule() { m_ownerRule = 0; }
-
- // Note that href is the URL that started the redirect chain that led to
- // this style sheet. This property probably isn't useful for much except
- // the JavaScript binding (which needs to use this value for security).
- String originalURL() const { return m_originalURL; }
-
- const KURL& finalURL() const { return m_finalURL; }
- const KURL& baseURL() const { return m_parserContext.baseURL; }
-
- unsigned ruleCount() const;
- StyleRuleBase* ruleAt(unsigned index) const;
-
- bool usesRemUnits() const { return m_usesRemUnits; }
-
- unsigned estimatedSizeInBytes() const;
-
- bool wrapperInsertRule(PassRefPtr<StyleRuleBase>, unsigned index);
- void wrapperDeleteRule(unsigned index);
-
- PassRefPtr<StyleSheetContents> copy() const { return adoptRef(new StyleSheetContents(*this)); }
-
- void registerClient(CSSStyleSheet*);
- void unregisterClient(CSSStyleSheet*);
- bool hasOneClient() { return m_clients.size() == 1; }
-
- bool isMutable() const { return m_isMutable; }
- void setMutable() { m_isMutable = true; }
-
- bool isInMemoryCache() const { return m_isInMemoryCache; }
- void addedToMemoryCache();
- void removedFromMemoryCache();
-
-private:
- StyleSheetContents(StyleRuleImport* ownerRule, const String& originalURL, const KURL& baseURL, const CSSParserContext&);
- StyleSheetContents(const StyleSheetContents&);
-
- void clearCharsetRule();
-
- StyleRuleImport* m_ownerRule;
-
- String m_originalURL;
- KURL m_finalURL;
-
- String m_encodingFromCharsetRule;
- Vector<RefPtr<StyleRuleImport> > m_importRules;
- Vector<RefPtr<StyleRuleBase> > m_childRules;
- typedef HashMap<AtomicString, AtomicString> PrefixNamespaceURIMap;
- PrefixNamespaceURIMap m_namespaces;
-
- bool m_loadCompleted : 1;
- bool m_isUserStyleSheet : 1;
- bool m_hasSyntacticallyValidCSSHeader : 1;
- bool m_didLoadErrorOccur : 1;
- bool m_usesRemUnits : 1;
- bool m_isMutable : 1;
- bool m_isInMemoryCache : 1;
-
- CSSParserContext m_parserContext;
-
- Vector<CSSStyleSheet*> m_clients;
-};
-
class CSSStyleSheet : public StyleSheet {
public:
- static RefPtr<CSSStyleSheet> create(PassRefPtr<StyleSheetContents> sheet, CSSImportRule* ownerRule = 0)
- {
- return adoptRef(new CSSStyleSheet(sheet, ownerRule));
- }
- static RefPtr<CSSStyleSheet> create(PassRefPtr<StyleSheetContents> sheet, Node* ownerNode)
- {
- return adoptRef(new CSSStyleSheet(sheet, ownerNode));
- }
+ static PassRefPtr<CSSStyleSheet> create(PassRefPtr<StyleSheetContents>, CSSImportRule* ownerRule = 0);
+ static PassRefPtr<CSSStyleSheet> create(PassRefPtr<StyleSheetContents>, Node* ownerNode);
static PassRefPtr<CSSStyleSheet> createInline(Node*, const KURL&, const String& encoding = String());
virtual ~CSSStyleSheet();
virtual CSSStyleSheet* parentStyleSheet() const OVERRIDE;
virtual Node* ownerNode() const OVERRIDE { return m_ownerNode; }
virtual MediaList* media() const OVERRIDE;
- virtual String href() const OVERRIDE { return m_contents->originalURL(); }
+ virtual String href() const OVERRIDE;
virtual String title() const OVERRIDE { return m_title; }
virtual bool disabled() const OVERRIDE { return m_isDisabled; }
virtual void setDisabled(bool) OVERRIDE;
virtual void clearOwnerNode() OVERRIDE { m_ownerNode = 0; }
virtual CSSImportRule* ownerRule() const OVERRIDE { return m_ownerRule; }
- virtual KURL baseURL() const OVERRIDE { return m_contents->baseURL(); }
- virtual bool isLoading() const OVERRIDE { return m_contents->isLoading(); }
+ virtual KURL baseURL() const OVERRIDE;
+ virtual bool isLoading() const OVERRIDE;
void clearOwnerRule() { m_ownerRule = 0; }
Document* ownerDocument() const;
#include "StylePropertySet.h"
#include "CSSParser.h"
-#include "CSSStyleSheet.h"
#include "CSSValueKeywords.h"
#include "CSSValueList.h"
#include "CSSValuePool.h"
#include "Document.h"
#include "PropertySetCSSStyleDeclaration.h"
#include "StylePropertyShorthand.h"
+#include "StyleSheetContents.h"
#include <wtf/BitArray.h>
#include <wtf/text/StringBuilder.h>
#include "StyleGeneratedImage.h"
#include "StylePendingImage.h"
#include "StyleRule.h"
+#include "StyleSheetContents.h"
#include "StyleSheetList.h"
#include "Text.h"
#include "TransformationMatrix.h"
--- /dev/null
+/*
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2006, 2007, 2012 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.
+ */
+
+#include "config.h"
+#include "StyleSheetContents.h"
+
+#include "CSSImportRule.h"
+#include "CSSParser.h"
+#include "CSSStyleSheet.h"
+#include "CachedCSSStyleSheet.h"
+#include "Document.h"
+#include "Node.h"
+#include "SecurityOrigin.h"
+#include "StylePropertySet.h"
+#include "StyleRule.h"
+#include <wtf/Deque.h>
+
+namespace WebCore {
+
+// Rough size estimate for the memory cache.
+unsigned StyleSheetContents::estimatedSizeInBytes() const
+{
+ // Note that this does not take into account size of the strings hanging from various objects.
+ // The assumption is that nearly all of of them are atomic and would exist anyway.
+ unsigned size = sizeof(*this);
+
+ // FIXME: This ignores the children of media and region rules.
+ // Most rules are StyleRules.
+ size += ruleCount() * StyleRule::averageSizeInBytes();
+
+ for (unsigned i = 0; i < m_importRules.size(); ++i) {
+ if (StyleSheetContents* sheet = m_importRules[i]->styleSheet())
+ size += sheet->estimatedSizeInBytes();
+ }
+ return size;
+}
+
+StyleSheetContents::StyleSheetContents(StyleRuleImport* ownerRule, const String& originalURL, const KURL& finalURL, const CSSParserContext& context)
+ : m_ownerRule(ownerRule)
+ , m_originalURL(originalURL)
+ , m_finalURL(finalURL)
+ , m_loadCompleted(false)
+ , m_isUserStyleSheet(ownerRule && ownerRule->parentStyleSheet() && ownerRule->parentStyleSheet()->isUserStyleSheet())
+ , m_hasSyntacticallyValidCSSHeader(true)
+ , m_didLoadErrorOccur(false)
+ , m_usesRemUnits(false)
+ , m_isMutable(false)
+ , m_isInMemoryCache(false)
+ , m_parserContext(context)
+{
+}
+
+StyleSheetContents::StyleSheetContents(const StyleSheetContents& o)
+ : RefCounted<StyleSheetContents>()
+ , m_ownerRule(0)
+ , m_originalURL(o.m_originalURL)
+ , m_finalURL(o.m_finalURL)
+ , m_encodingFromCharsetRule(o.m_encodingFromCharsetRule)
+ , m_importRules(o.m_importRules.size())
+ , m_childRules(o.m_childRules.size())
+ , m_namespaces(o.m_namespaces)
+ , m_loadCompleted(true)
+ , m_isUserStyleSheet(o.m_isUserStyleSheet)
+ , m_hasSyntacticallyValidCSSHeader(o.m_hasSyntacticallyValidCSSHeader)
+ , m_didLoadErrorOccur(false)
+ , m_usesRemUnits(o.m_usesRemUnits)
+ , m_isMutable(false)
+ , m_isInMemoryCache(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();
+}
+
+StyleSheetContents::~StyleSheetContents()
+{
+ clearRules();
+}
+
+bool StyleSheetContents::isCacheable() const
+{
+ // FIXME: Support copying import rules.
+ if (!m_importRules.isEmpty())
+ return false;
+ // FIXME: Support cached stylesheets in import rules.
+ if (m_ownerRule)
+ 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_isMutable)
+ 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 StyleSheetContents::parserAppendRule(PassRefPtr<StyleRuleBase> rule)
+{
+ ASSERT(!rule->isCharsetRule());
+ if (rule->isImportRule()) {
+ // Parser enforces that @import rules come before anything else except @charset.
+ ASSERT(m_childRules.isEmpty());
+ m_importRules.append(static_cast<StyleRuleImport*>(rule.get()));
+ m_importRules.last()->setParentStyleSheet(this);
+ m_importRules.last()->requestStyleSheet();
+ return;
+ }
+ m_childRules.append(rule);
+}
+
+StyleRuleBase* StyleSheetContents::ruleAt(unsigned index) const
+{
+ ASSERT(index < ruleCount());
+
+ unsigned childVectorIndex = index;
+ if (hasCharsetRule()) {
+ if (index == 0)
+ return 0;
+ --childVectorIndex;
+ }
+ if (childVectorIndex < m_importRules.size())
+ return m_importRules[childVectorIndex].get();
+
+ childVectorIndex -= m_importRules.size();
+ return m_childRules[childVectorIndex].get();
+}
+
+unsigned StyleSheetContents::ruleCount() const
+{
+ unsigned result = 0;
+ result += hasCharsetRule() ? 1 : 0;
+ result += m_importRules.size();
+ result += m_childRules.size();
+ return result;
+}
+
+void StyleSheetContents::clearCharsetRule()
+{
+ m_encodingFromCharsetRule = String();
+}
+
+void StyleSheetContents::clearRules()
+{
+ for (unsigned i = 0; i < m_importRules.size(); ++i) {
+ ASSERT(m_importRules.at(i)->parentStyleSheet() == this);
+ m_importRules[i]->clearParentStyleSheet();
+ }
+ m_importRules.clear();
+ m_childRules.clear();
+ clearCharsetRule();
+}
+
+void StyleSheetContents::parserSetEncodingFromCharsetRule(const String& encoding)
+{
+ // Parser enforces that there is ever only one @charset.
+ ASSERT(m_encodingFromCharsetRule.isNull());
+ m_encodingFromCharsetRule = encoding;
+}
+
+bool StyleSheetContents::wrapperInsertRule(PassRefPtr<StyleRuleBase> rule, unsigned index)
+{
+ ASSERT(m_isMutable);
+ ASSERT(index <= ruleCount());
+ // Parser::parseRule doesn't currently allow @charset so we don't need to deal with it.
+ ASSERT(!rule->isCharsetRule());
+
+ unsigned childVectorIndex = index;
+ // m_childRules does not contain @charset which is always in index 0 if it exists.
+ if (hasCharsetRule()) {
+ if (childVectorIndex == 0) {
+ // Nothing can be inserted before @charset.
+ return false;
+ }
+ --childVectorIndex;
+ }
+
+ if (childVectorIndex < m_importRules.size() || (childVectorIndex == m_importRules.size() && rule->isImportRule())) {
+ // Inserting non-import rule before @import is not allowed.
+ if (!rule->isImportRule())
+ return false;
+ m_importRules.insert(childVectorIndex, static_cast<StyleRuleImport*>(rule.get()));
+ m_importRules[childVectorIndex]->setParentStyleSheet(this);
+ m_importRules[childVectorIndex]->requestStyleSheet();
+ // FIXME: Stylesheet doesn't actually change meaningfully before the imported sheets are loaded.
+ return true;
+ }
+ // Inserting @import rule after a non-import rule is not allowed.
+ if (rule->isImportRule())
+ return false;
+ childVectorIndex -= m_importRules.size();
+
+ m_childRules.insert(childVectorIndex, rule);
+ return true;
+}
+
+void StyleSheetContents::wrapperDeleteRule(unsigned index)
+{
+ ASSERT(m_isMutable);
+ ASSERT(index < ruleCount());
+
+ unsigned childVectorIndex = index;
+ if (hasCharsetRule()) {
+ if (childVectorIndex == 0) {
+ clearCharsetRule();
+ return;
+ }
+ --childVectorIndex;
+ }
+ if (childVectorIndex < m_importRules.size()) {
+ m_importRules[childVectorIndex]->clearParentStyleSheet();
+ m_importRules.remove(childVectorIndex);
+ return;
+ }
+ childVectorIndex -= m_importRules.size();
+
+ m_childRules.remove(childVectorIndex);
+}
+
+void StyleSheetContents::parserAddNamespace(const AtomicString& prefix, const AtomicString& uri)
+{
+ if (uri.isNull() || prefix.isNull())
+ return;
+ m_namespaces.add(prefix, uri);
+}
+
+const AtomicString& StyleSheetContents::determineNamespace(const AtomicString& prefix)
+{
+ if (prefix.isNull())
+ 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.
+ PrefixNamespaceURIMap::const_iterator it = m_namespaces.find(prefix);
+ if (it == m_namespaces.end())
+ return nullAtom;
+ return it->second;
+}
+
+void StyleSheetContents::parseAuthorStyleSheet(const CachedCSSStyleSheet* cachedStyleSheet, const SecurityOrigin* securityOrigin)
+{
+ // Check to see if we should enforce the MIME type of the CSS resource in strict mode.
+ // Running in iWeb 2 is one example of where we don't want to - <rdar://problem/6099748>
+ bool enforceMIMEType = isStrictParserMode(m_parserContext.mode) && m_parserContext.enforcesCSSMIMETypeInNoQuirksMode;
+ bool hasValidMIMEType = false;
+ String sheetText = cachedStyleSheet->sheetText(enforceMIMEType, &hasValidMIMEType);
+
+ CSSParser p(parserContext());
+ p.parseSheet(this, sheetText, 0);
+
+ // If we're loading a stylesheet cross-origin, and the MIME type is not standard, require the CSS
+ // to at least start with a syntactically valid CSS rule.
+ // This prevents an attacker playing games by injecting CSS strings into HTML, XML, JSON, etc. etc.
+ if (!hasValidMIMEType && !hasSyntacticallyValidCSSHeader()) {
+ bool isCrossOriginCSS = !securityOrigin || !securityOrigin->canRequest(finalURL());
+ if (isCrossOriginCSS) {
+ clearRules();
+ return;
+ }
+ }
+ if (m_parserContext.needsSiteSpecificQuirks && isStrictParserMode(m_parserContext.mode)) {
+ // Work around <https://bugs.webkit.org/show_bug.cgi?id=28350>.
+ DEFINE_STATIC_LOCAL(const String, slashKHTMLFixesDotCss, ("/KHTMLFixes.css"));
+ DEFINE_STATIC_LOCAL(const String, mediaWikiKHTMLFixesStyleSheet, ("/* KHTML fix stylesheet */\n/* work around the horizontal scrollbars */\n#column-content { margin-left: 0; }\n\n"));
+ // There are two variants of KHTMLFixes.css. One is equal to mediaWikiKHTMLFixesStyleSheet,
+ // while the other lacks the second trailing newline.
+ if (finalURL().string().endsWith(slashKHTMLFixesDotCss) && !sheetText.isNull() && mediaWikiKHTMLFixesStyleSheet.startsWith(sheetText)
+ && sheetText.length() >= mediaWikiKHTMLFixesStyleSheet.length() - 1)
+ clearRules();
+ }
+}
+
+bool StyleSheetContents::parseString(const String& sheetText)
+{
+ return parseStringAtLine(sheetText, 0);
+}
+
+bool StyleSheetContents::parseStringAtLine(const String& sheetText, int startLineNumber)
+{
+ CSSParser p(parserContext());
+ p.parseSheet(this, sheetText, startLineNumber);
+
+ return true;
+}
+
+bool StyleSheetContents::isLoading() const
+{
+ for (unsigned i = 0; i < m_importRules.size(); ++i) {
+ if (m_importRules[i]->isLoading())
+ return true;
+ }
+ return false;
+}
+
+void StyleSheetContents::checkLoaded()
+{
+ if (isLoading())
+ return;
+
+ // Avoid |this| being deleted by scripts that run via
+ // ScriptableDocumentParser::executeScriptsWaitingForStylesheets().
+ // See <rdar://problem/6622300>.
+ RefPtr<StyleSheetContents> protector(this);
+ StyleSheetContents* parentSheet = parentStyleSheet();
+ if (parentSheet) {
+ parentSheet->checkLoaded();
+ m_loadCompleted = true;
+ return;
+ }
+ RefPtr<Node> ownerNode = singleOwnerNode();
+ if (!ownerNode) {
+ m_loadCompleted = true;
+ return;
+ }
+ m_loadCompleted = ownerNode->sheetLoaded();
+ if (m_loadCompleted)
+ ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOccur);
+}
+
+void StyleSheetContents::notifyLoadedSheet(const CachedCSSStyleSheet* sheet)
+{
+ ASSERT(sheet);
+ m_didLoadErrorOccur |= sheet->errorOccurred();
+}
+
+void StyleSheetContents::startLoadingDynamicSheet()
+{
+ if (Node* owner = singleOwnerNode())
+ owner->startLoadingDynamicSheet();
+}
+
+StyleSheetContents* StyleSheetContents::rootStyleSheet() const
+{
+ const StyleSheetContents* root = this;
+ while (root->parentStyleSheet())
+ root = root->parentStyleSheet();
+ return const_cast<StyleSheetContents*>(root);
+}
+
+Node* StyleSheetContents::singleOwnerNode() const
+{
+ StyleSheetContents* root = rootStyleSheet();
+ if (root->m_clients.isEmpty())
+ return 0;
+ ASSERT(root->m_clients.size() == 1);
+ return root->m_clients[0]->ownerNode();
+}
+
+Document* StyleSheetContents::singleOwnerDocument() const
+{
+ Node* ownerNode = singleOwnerNode();
+ return ownerNode ? ownerNode->document() : 0;
+}
+
+KURL StyleSheetContents::completeURL(const String& url) const
+{
+ return CSSParser::completeURL(m_parserContext, url);
+}
+
+void StyleSheetContents::addSubresourceStyleURLs(ListHashSet<KURL>& urls)
+{
+ Deque<StyleSheetContents*> styleSheetQueue;
+ styleSheetQueue.append(this);
+
+ while (!styleSheetQueue.isEmpty()) {
+ StyleSheetContents* styleSheet = styleSheetQueue.takeFirst();
+
+ for (unsigned i = 0; i < styleSheet->m_importRules.size(); ++i) {
+ StyleRuleImport* importRule = styleSheet->m_importRules[i].get();
+ if (importRule->styleSheet()) {
+ styleSheetQueue.append(importRule->styleSheet());
+ addSubresourceURL(urls, importRule->styleSheet()->baseURL());
+ }
+ }
+ for (unsigned i = 0; i < styleSheet->m_childRules.size(); ++i) {
+ StyleRuleBase* rule = styleSheet->m_childRules[i].get();
+ if (rule->isStyleRule())
+ static_cast<StyleRule*>(rule)->properties()->addSubresourceStyleURLs(urls, this);
+ else if (rule->isFontFaceRule())
+ static_cast<StyleRuleFontFace*>(rule)->properties()->addSubresourceStyleURLs(urls, this);
+ }
+ }
+}
+
+StyleSheetContents* StyleSheetContents::parentStyleSheet() const
+{
+ return m_ownerRule ? m_ownerRule->parentStyleSheet() : 0;
+}
+
+void StyleSheetContents::registerClient(CSSStyleSheet* sheet)
+{
+ ASSERT(!m_clients.contains(sheet));
+ m_clients.append(sheet);
+}
+
+void StyleSheetContents::unregisterClient(CSSStyleSheet* sheet)
+{
+ size_t position = m_clients.find(sheet);
+ ASSERT(position != notFound);
+ m_clients.remove(position);
+}
+
+void StyleSheetContents::addedToMemoryCache()
+{
+ ASSERT(!m_isInMemoryCache);
+ ASSERT(isCacheable());
+ m_isInMemoryCache = true;
+}
+
+void StyleSheetContents::removedFromMemoryCache()
+{
+ ASSERT(m_isInMemoryCache);
+ ASSERT(isCacheable());
+ m_isInMemoryCache = false;
+}
+
+}
--- /dev/null
+/*
+ * (C) 1999-2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010, 2012 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 StyleSheetContents_h
+#define StyleSheetContents_h
+
+#include "CSSParserMode.h"
+#include "KURL.h"
+#include <wtf/HashMap.h>
+#include <wtf/ListHashSet.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+#include <wtf/text/AtomicStringHash.h>
+
+namespace WebCore {
+
+class CSSStyleSheet;
+class CachedCSSStyleSheet;
+class Document;
+class Node;
+class SecurityOrigin;
+class StyleRuleBase;
+class StyleRuleImport;
+
+class StyleSheetContents : public RefCounted<StyleSheetContents> {
+public:
+ static PassRefPtr<StyleSheetContents> create(const CSSParserContext& context = CSSParserContext(CSSStrictMode))
+ {
+ return adoptRef(new StyleSheetContents(0, String(), KURL(), context));
+ }
+ static PassRefPtr<StyleSheetContents> create(const String& originalURL, const KURL& finalURL, const CSSParserContext& context)
+ {
+ return adoptRef(new StyleSheetContents(0, originalURL, finalURL, context));
+ }
+ static PassRefPtr<StyleSheetContents> create(StyleRuleImport* ownerRule, const String& originalURL, const KURL& finalURL, const CSSParserContext& context)
+ {
+ return adoptRef(new StyleSheetContents(ownerRule, originalURL, finalURL, context));
+ }
+
+ ~StyleSheetContents();
+
+ const CSSParserContext& parserContext() const { return m_parserContext; }
+
+ const AtomicString& determineNamespace(const AtomicString& prefix);
+
+ void parseAuthorStyleSheet(const CachedCSSStyleSheet*, const SecurityOrigin*);
+ bool parseString(const String&);
+ bool parseStringAtLine(const String&, int startLineNumber);
+
+ bool isCacheable() const;
+
+ bool isLoading() const;
+
+ void checkLoaded();
+ void startLoadingDynamicSheet();
+
+ StyleSheetContents* rootStyleSheet() const;
+ Node* singleOwnerNode() const;
+ Document* singleOwnerDocument() const;
+
+ const String& charset() const { return m_parserContext.charset; }
+
+ bool loadCompleted() const { return m_loadCompleted; }
+
+ KURL completeURL(const String& url) const;
+ void addSubresourceStyleURLs(ListHashSet<KURL>&);
+
+ void setIsUserStyleSheet(bool b) { m_isUserStyleSheet = b; }
+ bool isUserStyleSheet() const { return m_isUserStyleSheet; }
+ 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; }
+
+ void clearRules();
+
+ bool hasCharsetRule() const { return !m_encodingFromCharsetRule.isNull(); }
+ String encodingFromCharsetRule() const { return m_encodingFromCharsetRule; }
+ // Rules other than @charset and @import.
+ const Vector<RefPtr<StyleRuleBase> >& childRules() const { return m_childRules; }
+ const Vector<RefPtr<StyleRuleImport> >& importRules() const { return m_importRules; }
+
+ void notifyLoadedSheet(const CachedCSSStyleSheet*);
+
+ StyleSheetContents* parentStyleSheet() const;
+ StyleRuleImport* ownerRule() const { return m_ownerRule; }
+ void clearOwnerRule() { m_ownerRule = 0; }
+
+ // Note that href is the URL that started the redirect chain that led to
+ // this style sheet. This property probably isn't useful for much except
+ // the JavaScript binding (which needs to use this value for security).
+ String originalURL() const { return m_originalURL; }
+
+ const KURL& finalURL() const { return m_finalURL; }
+ const KURL& baseURL() const { return m_parserContext.baseURL; }
+
+ unsigned ruleCount() const;
+ StyleRuleBase* ruleAt(unsigned index) const;
+
+ bool usesRemUnits() const { return m_usesRemUnits; }
+
+ unsigned estimatedSizeInBytes() const;
+
+ bool wrapperInsertRule(PassRefPtr<StyleRuleBase>, unsigned index);
+ void wrapperDeleteRule(unsigned index);
+
+ PassRefPtr<StyleSheetContents> copy() const { return adoptRef(new StyleSheetContents(*this)); }
+
+ void registerClient(CSSStyleSheet*);
+ void unregisterClient(CSSStyleSheet*);
+ bool hasOneClient() { return m_clients.size() == 1; }
+
+ bool isMutable() const { return m_isMutable; }
+ void setMutable() { m_isMutable = true; }
+
+ bool isInMemoryCache() const { return m_isInMemoryCache; }
+ void addedToMemoryCache();
+ void removedFromMemoryCache();
+
+private:
+ StyleSheetContents(StyleRuleImport* ownerRule, const String& originalURL, const KURL& baseURL, const CSSParserContext&);
+ StyleSheetContents(const StyleSheetContents&);
+
+ void clearCharsetRule();
+
+ StyleRuleImport* m_ownerRule;
+
+ String m_originalURL;
+ KURL m_finalURL;
+
+ String m_encodingFromCharsetRule;
+ Vector<RefPtr<StyleRuleImport> > m_importRules;
+ Vector<RefPtr<StyleRuleBase> > m_childRules;
+ typedef HashMap<AtomicString, AtomicString> PrefixNamespaceURIMap;
+ PrefixNamespaceURIMap m_namespaces;
+
+ bool m_loadCompleted : 1;
+ bool m_isUserStyleSheet : 1;
+ bool m_hasSyntacticallyValidCSSHeader : 1;
+ bool m_didLoadErrorOccur : 1;
+ bool m_usesRemUnits : 1;
+ bool m_isMutable : 1;
+ bool m_isInMemoryCache : 1;
+
+ CSSParserContext m_parserContext;
+
+ Vector<CSSStyleSheet*> m_clients;
+};
+
+} // namespace
+
+#endif
#include "RegularExpression.h"
#include "SecurityOrigin.h"
#include "Settings.h"
+#include "StyleSheetContents.h"
#include "TextDocument.h"
#include "ThreadGlobalData.h"
#include "XMLNames.h"
static const char* const validXMLMIMETypeChars = "[0-9a-zA-Z_\\-+~!$\\^{}|.%'`#&*]"; // per RFCs: 3023, 2045
-XMLMIMETypeRegExp::XMLMIMETypeRegExp() :
- m_regex(adoptPtr(new RegularExpression(WTF::makeString("^", validXMLMIMETypeChars, "+/", validXMLMIMETypeChars, "+\\+xml$"), TextCaseSensitive)))
+XMLMIMETypeRegExp::XMLMIMETypeRegExp()
+ : m_regex(adoptPtr(new RegularExpression(WTF::makeString("^", validXMLMIMETypeChars, "+/", validXMLMIMETypeChars, "+\\+xml$"), TextCaseSensitive)))
{
}
#include "ShadowRoot.h"
#include "StaticHashSetNodeList.h"
#include "StyleResolver.h"
+#include "StyleSheetContents.h"
#include "StyleSheetList.h"
#include "TextResourceDecoder.h"
#include "Timer.h"
#include "XSLStyleSheet.h"
#include "XMLDocumentParser.h" // for parseAttributes()
#include "MediaList.h"
+#include "StyleSheetContents.h"
namespace WebCore {
#include "MediaList.h"
#include "MediaQueryEvaluator.h"
#include "ScriptableDocumentParser.h"
+#include "StyleSheetContents.h"
#include <wtf/text/StringBuilder.h>
namespace WebCore {
#include "SecurityOrigin.h"
#include "Settings.h"
#include "StyleResolver.h"
+#include "StyleSheetContents.h"
#include <wtf/StdLibExtras.h>
namespace WebCore {
#include "RuntimeEnabledFeatures.h"
#include "ScriptEventListener.h"
#include "ScriptableDocumentParser.h"
-
+#include "StyleSheetContents.h"
namespace WebCore {
#include "SVGNames.h"
#include "StyleResolver.h"
#include "StyleRule.h"
+#include "StyleSheetContents.h"
#include "StyleSheetList.h"
#include "WebKitCSSKeyframesRule.h"
#include "HTTPParsers.h"
#include "MemoryCache.h"
#include "SharedBuffer.h"
+#include "StyleSheetContents.h"
#include "TextResourceDecoder.h"
#include <wtf/CurrentTime.h>
#include <wtf/Vector.h>
#include "StyleCachedImage.h"
#include "StyleImage.h"
#include "StyleRule.h"
+#include "StyleSheetContents.h"
#include "Text.h"
#include "TextEncoding.h"
#include <wtf/text/CString.h>
#include "AXObjectCache.h"
#include "CSSParserMode.h"
-#include "CSSStyleSheet.h"
#include "Document.h"
#include "DocumentLoader.h"
#include "DocumentType.h"
#include "HTMLHeadElement.h"
#include "NodeList.h"
#include "SecurityOrigin.h"
+#include "StyleSheetContents.h"
#include "WebAccessibilityObject.h"
#include "WebDOMEvent.h"
#include "WebDocumentType.h"