1 /* 2 * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org) 3 * (C) 2004-2005 Allan Sandfeld Jensen (kde (at) carewolf.com) 4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit (at) nickshanks.com) 5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 6 * Copyright (C) 2007 Alexey Proskuryakov <ap (at) webkit.org> 7 * Copyright (C) 2007, 2008 Eric Seidel <eric (at) webkit.org> 8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) 9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved. 10 * Copyright (C) Research In Motion Limited 2011. All rights reserved. 11 * Copyright (C) 2012 Google Inc. All rights reserved. 12 * 13 * This library is free software; you can redistribute it and/or 14 * modify it under the terms of the GNU Library General Public 15 * License as published by the Free Software Foundation; either 16 * version 2 of the License, or (at your option) any later version. 17 * 18 * This library is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 * Library General Public License for more details. 22 * 23 * You should have received a copy of the GNU Library General Public License 24 * along with this library; see the file COPYING.LIB. If not, write to 25 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 26 * Boston, MA 02110-1301, USA. 27 */ 28 29 #include "config.h" 30 #include "core/css/CSSDefaultStyleSheets.h" 31 32 #include "core/MathMLNames.h" 33 #include "core/UserAgentStyleSheets.h" 34 #include "core/css/MediaQueryEvaluator.h" 35 #include "core/css/RuleSet.h" 36 #include "core/css/StyleSheetContents.h" 37 #include "core/dom/Fullscreen.h" 38 #include "core/html/HTMLAnchorElement.h" 39 #include "core/html/HTMLHtmlElement.h" 40 #include "core/rendering/RenderTheme.h" 41 #include "wtf/LeakAnnotations.h" 42 43 namespace blink { 44 45 using namespace HTMLNames; 46 47 CSSDefaultStyleSheets& CSSDefaultStyleSheets::instance() 48 { 49 DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<CSSDefaultStyleSheets>, cssDefaultStyleSheets, (adoptPtrWillBeNoop(new CSSDefaultStyleSheets()))); 50 return *cssDefaultStyleSheets; 51 } 52 53 static const MediaQueryEvaluator& screenEval() 54 { 55 DEFINE_STATIC_LOCAL(const MediaQueryEvaluator, staticScreenEval, ("screen")); 56 return staticScreenEval; 57 } 58 59 static const MediaQueryEvaluator& printEval() 60 { 61 DEFINE_STATIC_LOCAL(const MediaQueryEvaluator, staticPrintEval, ("print")); 62 return staticPrintEval; 63 } 64 65 static PassRefPtrWillBeRawPtr<StyleSheetContents> parseUASheet(const String& str) 66 { 67 RefPtrWillBeRawPtr<StyleSheetContents> sheet = StyleSheetContents::create(CSSParserContext(UASheetMode, 0)); 68 sheet->parseString(str); 69 // User Agent stylesheets are parsed once for the lifetime of the renderer 70 // and are intentionally leaked. 71 WTF_ANNOTATE_LEAKING_OBJECT_PTR(sheet.get()); 72 return sheet.release(); 73 } 74 75 static PassRefPtrWillBeRawPtr<StyleSheetContents> parseUASheet(const char* characters, unsigned size) 76 { 77 return parseUASheet(String(characters, size)); 78 } 79 80 CSSDefaultStyleSheets::CSSDefaultStyleSheets() 81 : m_defaultStyle(nullptr) 82 , m_defaultViewportStyle(nullptr) 83 , m_defaultQuirksStyle(nullptr) 84 , m_defaultPrintStyle(nullptr) 85 , m_defaultViewSourceStyle(nullptr) 86 , m_defaultXHTMLMobileProfileStyle(nullptr) 87 , m_defaultTransitionStyle(nullptr) 88 , m_defaultStyleSheet(nullptr) 89 , m_viewportStyleSheet(nullptr) 90 , m_quirksStyleSheet(nullptr) 91 , m_svgStyleSheet(nullptr) 92 , m_mathmlStyleSheet(nullptr) 93 , m_mediaControlsStyleSheet(nullptr) 94 , m_fullscreenStyleSheet(nullptr) 95 { 96 m_defaultStyle = RuleSet::create(); 97 m_defaultViewportStyle = RuleSet::create(); 98 m_defaultPrintStyle = RuleSet::create(); 99 m_defaultQuirksStyle = RuleSet::create(); 100 101 // Strict-mode rules. 102 String defaultRules = String(htmlCss, sizeof(htmlCss)) + RenderTheme::theme().extraDefaultStyleSheet(); 103 m_defaultStyleSheet = parseUASheet(defaultRules); 104 m_defaultStyle->addRulesFromSheet(defaultStyleSheet(), screenEval()); 105 #if OS(ANDROID) 106 String viewportRules(viewportAndroidCss, sizeof(viewportAndroidCss)); 107 #else 108 String viewportRules; 109 #endif 110 m_viewportStyleSheet = parseUASheet(viewportRules); 111 m_defaultViewportStyle->addRulesFromSheet(viewportStyleSheet(), screenEval()); 112 m_defaultPrintStyle->addRulesFromSheet(defaultStyleSheet(), printEval()); 113 114 // Quirks-mode rules. 115 String quirksRules = String(quirksCss, sizeof(quirksCss)) + RenderTheme::theme().extraQuirksStyleSheet(); 116 m_quirksStyleSheet = parseUASheet(quirksRules); 117 m_defaultQuirksStyle->addRulesFromSheet(quirksStyleSheet(), screenEval()); 118 } 119 120 RuleSet* CSSDefaultStyleSheets::defaultViewSourceStyle() 121 { 122 if (!m_defaultViewSourceStyle) { 123 m_defaultViewSourceStyle = RuleSet::create(); 124 // Loaded stylesheet is leaked on purpose. 125 RefPtrWillBeRawPtr<StyleSheetContents> stylesheet = parseUASheet(viewSourceCss, sizeof(viewSourceCss)); 126 m_defaultViewSourceStyle->addRulesFromSheet(stylesheet.release().leakRef(), screenEval()); 127 } 128 return m_defaultViewSourceStyle.get(); 129 } 130 131 RuleSet* CSSDefaultStyleSheets::defaultTransitionStyle() 132 { 133 if (!m_defaultTransitionStyle) { 134 m_defaultTransitionStyle = RuleSet::create(); 135 // Loaded stylesheet is leaked on purpose. 136 RefPtrWillBeRawPtr<StyleSheetContents> stylesheet = parseUASheet(navigationTransitionsCss, sizeof(navigationTransitionsCss)); 137 m_defaultTransitionStyle->addRulesFromSheet(stylesheet.release().leakRef(), screenEval()); 138 } 139 return m_defaultTransitionStyle.get(); 140 } 141 142 RuleSet* CSSDefaultStyleSheets::defaultXHTMLMobileProfileStyle() 143 { 144 if (!m_defaultXHTMLMobileProfileStyle) { 145 m_defaultXHTMLMobileProfileStyle = RuleSet::create(); 146 // Loaded stylesheet is leaked on purpose. 147 RefPtrWillBeRawPtr<StyleSheetContents> stylesheet = parseUASheet(xhtmlmpCss, sizeof(xhtmlmpCss)); 148 m_defaultXHTMLMobileProfileStyle->addRulesFromSheet(stylesheet.release().leakRef(), screenEval()); 149 } 150 return m_defaultXHTMLMobileProfileStyle.get(); 151 } 152 153 void CSSDefaultStyleSheets::ensureDefaultStyleSheetsForElement(Element* element, bool& changedDefaultStyle) 154 { 155 // FIXME: We should assert that the sheet only styles SVG elements. 156 if (element->isSVGElement() && !m_svgStyleSheet) { 157 m_svgStyleSheet = parseUASheet(svgCss, sizeof(svgCss)); 158 m_defaultStyle->addRulesFromSheet(svgStyleSheet(), screenEval()); 159 m_defaultPrintStyle->addRulesFromSheet(svgStyleSheet(), printEval()); 160 changedDefaultStyle = true; 161 } 162 163 // FIXME: We should assert that the sheet only styles MathML elements. 164 if (element->namespaceURI() == MathMLNames::mathmlNamespaceURI 165 && !m_mathmlStyleSheet) { 166 m_mathmlStyleSheet = parseUASheet(mathmlCss, sizeof(mathmlCss)); 167 m_defaultStyle->addRulesFromSheet(mathmlStyleSheet(), screenEval()); 168 m_defaultPrintStyle->addRulesFromSheet(mathmlStyleSheet(), printEval()); 169 changedDefaultStyle = true; 170 } 171 172 // FIXME: We should assert that this sheet only contains rules for <video> and <audio>. 173 if (!m_mediaControlsStyleSheet && (isHTMLVideoElement(*element) || isHTMLAudioElement(*element))) { 174 String mediaRules = String(mediaControlsCss, sizeof(mediaControlsCss)) + RenderTheme::theme().extraMediaControlsStyleSheet(); 175 m_mediaControlsStyleSheet = parseUASheet(mediaRules); 176 m_defaultStyle->addRulesFromSheet(mediaControlsStyleSheet(), screenEval()); 177 m_defaultPrintStyle->addRulesFromSheet(mediaControlsStyleSheet(), printEval()); 178 changedDefaultStyle = true; 179 } 180 181 // FIXME: This only works because we Force recalc the entire document so the new sheet 182 // is loaded for <html> and the correct styles apply to everyone. 183 if (!m_fullscreenStyleSheet && Fullscreen::isFullScreen(element->document())) { 184 String fullscreenRules = String(fullscreenCss, sizeof(fullscreenCss)) + RenderTheme::theme().extraFullScreenStyleSheet(); 185 m_fullscreenStyleSheet = parseUASheet(fullscreenRules); 186 m_defaultStyle->addRulesFromSheet(fullscreenStyleSheet(), screenEval()); 187 m_defaultQuirksStyle->addRulesFromSheet(fullscreenStyleSheet(), screenEval()); 188 changedDefaultStyle = true; 189 } 190 191 ASSERT(!m_defaultStyle->features().hasIdsInSelectors()); 192 ASSERT(m_defaultStyle->features().siblingRules.isEmpty()); 193 } 194 195 void CSSDefaultStyleSheets::trace(Visitor* visitor) 196 { 197 visitor->trace(m_defaultStyle); 198 visitor->trace(m_defaultViewportStyle); 199 visitor->trace(m_defaultQuirksStyle); 200 visitor->trace(m_defaultPrintStyle); 201 visitor->trace(m_defaultViewSourceStyle); 202 visitor->trace(m_defaultXHTMLMobileProfileStyle); 203 visitor->trace(m_defaultTransitionStyle); 204 visitor->trace(m_defaultStyleSheet); 205 visitor->trace(m_viewportStyleSheet); 206 visitor->trace(m_quirksStyleSheet); 207 visitor->trace(m_svgStyleSheet); 208 visitor->trace(m_mathmlStyleSheet); 209 visitor->trace(m_mediaControlsStyleSheet); 210 visitor->trace(m_fullscreenStyleSheet); 211 } 212 213 } // namespace blink 214