1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@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@webkit.org>
7 * Copyright (C) 2007, 2008 Eric Seidel <eric@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 "UserAgentStyleSheets.h"
33 #include "core/css/MediaQueryEvaluator.h"
34 #include "core/css/RuleSet.h"
35 #include "core/css/StyleSheetContents.h"
36 #include "core/dom/FullscreenElementStack.h"
37 #include "core/html/HTMLAnchorElement.h"
38 #include "core/html/HTMLHtmlElement.h"
39 #include "core/html/HTMLVideoElement.h"
40 #include "core/rendering/RenderTheme.h"
41
42 namespace WebCore {
43
44 using namespace HTMLNames;
45
46 RuleSet* CSSDefaultStyleSheets::defaultStyle;
47 RuleSet* CSSDefaultStyleSheets::defaultViewportStyle;
48 RuleSet* CSSDefaultStyleSheets::defaultQuirksStyle;
49 RuleSet* CSSDefaultStyleSheets::defaultPrintStyle;
50 RuleSet* CSSDefaultStyleSheets::defaultViewSourceStyle;
51 RuleSet* CSSDefaultStyleSheets::defaultXHTMLMobileProfileStyle;
52
53 StyleSheetContents* CSSDefaultStyleSheets::defaultStyleSheet;
54 StyleSheetContents* CSSDefaultStyleSheets::viewportStyleSheet;
55 StyleSheetContents* CSSDefaultStyleSheets::quirksStyleSheet;
56 StyleSheetContents* CSSDefaultStyleSheets::svgStyleSheet;
57 StyleSheetContents* CSSDefaultStyleSheets::mediaControlsStyleSheet;
58 StyleSheetContents* CSSDefaultStyleSheets::fullscreenStyleSheet;
59
screenEval()60 static const MediaQueryEvaluator& screenEval()
61 {
62 DEFINE_STATIC_LOCAL(const MediaQueryEvaluator, staticScreenEval, ("screen"));
63 return staticScreenEval;
64 }
65
printEval()66 static const MediaQueryEvaluator& printEval()
67 {
68 DEFINE_STATIC_LOCAL(const MediaQueryEvaluator, staticPrintEval, ("print"));
69 return staticPrintEval;
70 }
71
parseUASheet(const String & str)72 static StyleSheetContents* parseUASheet(const String& str)
73 {
74 StyleSheetContents* sheet = StyleSheetContents::create(CSSParserContext(UASheetMode)).leakRef(); // leak the sheet on purpose
75 sheet->parseString(str);
76 return sheet;
77 }
78
parseUASheet(const char * characters,unsigned size)79 static StyleSheetContents* parseUASheet(const char* characters, unsigned size)
80 {
81 return parseUASheet(String(characters, size));
82 }
83
loadDefaultStylesheetIfNecessary()84 void CSSDefaultStyleSheets::loadDefaultStylesheetIfNecessary()
85 {
86 if (!defaultStyle)
87 loadDefaultStyle();
88 }
89
loadDefaultStyle()90 void CSSDefaultStyleSheets::loadDefaultStyle()
91 {
92 ASSERT(!defaultStyle);
93 defaultStyle = RuleSet::create().leakPtr();
94 defaultViewportStyle = RuleSet::create().leakPtr();
95 defaultPrintStyle = RuleSet::create().leakPtr();
96 defaultQuirksStyle = RuleSet::create().leakPtr();
97
98 // Strict-mode rules.
99 String defaultRules = String(htmlUserAgentStyleSheet, sizeof(htmlUserAgentStyleSheet)) + RenderTheme::theme().extraDefaultStyleSheet();
100 defaultStyleSheet = parseUASheet(defaultRules);
101 defaultStyle->addRulesFromSheet(defaultStyleSheet, screenEval());
102 #if OS(ANDROID)
103 String viewportRules(viewportAndroidUserAgentStyleSheet, sizeof(viewportAndroidUserAgentStyleSheet));
104 #else
105 String viewportRules;
106 #endif
107 viewportStyleSheet = parseUASheet(viewportRules);
108 defaultViewportStyle->addRulesFromSheet(viewportStyleSheet, screenEval());
109 defaultPrintStyle->addRulesFromSheet(defaultStyleSheet, printEval());
110
111 // Quirks-mode rules.
112 String quirksRules = String(quirksUserAgentStyleSheet, sizeof(quirksUserAgentStyleSheet)) + RenderTheme::theme().extraQuirksStyleSheet();
113 quirksStyleSheet = parseUASheet(quirksRules);
114 defaultQuirksStyle->addRulesFromSheet(quirksStyleSheet, screenEval());
115 }
116
viewSourceStyle()117 RuleSet* CSSDefaultStyleSheets::viewSourceStyle()
118 {
119 if (!defaultViewSourceStyle) {
120 defaultViewSourceStyle = RuleSet::create().leakPtr();
121 defaultViewSourceStyle->addRulesFromSheet(parseUASheet(sourceUserAgentStyleSheet, sizeof(sourceUserAgentStyleSheet)), screenEval());
122 }
123 return defaultViewSourceStyle;
124 }
125
xhtmlMobileProfileStyle()126 RuleSet* CSSDefaultStyleSheets::xhtmlMobileProfileStyle()
127 {
128 if (!defaultXHTMLMobileProfileStyle) {
129 defaultXHTMLMobileProfileStyle = RuleSet::create().leakPtr();
130 defaultXHTMLMobileProfileStyle->addRulesFromSheet(parseUASheet(xhtmlmpUserAgentStyleSheet, sizeof(xhtmlmpUserAgentStyleSheet)), screenEval());
131 }
132 return defaultXHTMLMobileProfileStyle;
133 }
134
ensureDefaultStyleSheetsForElement(Element * element,bool & changedDefaultStyle)135 void CSSDefaultStyleSheets::ensureDefaultStyleSheetsForElement(Element* element, bool& changedDefaultStyle)
136 {
137 // FIXME: We should assert that the sheet only styles SVG elements.
138 if (element->isSVGElement() && !svgStyleSheet) {
139 svgStyleSheet = parseUASheet(svgUserAgentStyleSheet, sizeof(svgUserAgentStyleSheet));
140 defaultStyle->addRulesFromSheet(svgStyleSheet, screenEval());
141 defaultPrintStyle->addRulesFromSheet(svgStyleSheet, printEval());
142 changedDefaultStyle = true;
143 }
144
145 // FIXME: We should assert that this sheet only contains rules for <video> and <audio>.
146 if (!mediaControlsStyleSheet && (isHTMLVideoElement(element) || element->hasTagName(audioTag))) {
147 String mediaRules = String(mediaControlsUserAgentStyleSheet, sizeof(mediaControlsUserAgentStyleSheet)) + RenderTheme::theme().extraMediaControlsStyleSheet();
148 mediaControlsStyleSheet = parseUASheet(mediaRules);
149 defaultStyle->addRulesFromSheet(mediaControlsStyleSheet, screenEval());
150 defaultPrintStyle->addRulesFromSheet(mediaControlsStyleSheet, printEval());
151 changedDefaultStyle = true;
152 }
153
154 // FIXME: This only works because we Force recalc the entire document so the new sheet
155 // is loaded for <html> and the correct styles apply to everyone.
156 if (!fullscreenStyleSheet && FullscreenElementStack::isFullScreen(&element->document())) {
157 String fullscreenRules = String(fullscreenUserAgentStyleSheet, sizeof(fullscreenUserAgentStyleSheet)) + RenderTheme::theme().extraFullScreenStyleSheet();
158 fullscreenStyleSheet = parseUASheet(fullscreenRules);
159 defaultStyle->addRulesFromSheet(fullscreenStyleSheet, screenEval());
160 defaultQuirksStyle->addRulesFromSheet(fullscreenStyleSheet, screenEval());
161 changedDefaultStyle = true;
162 }
163
164 ASSERT(defaultStyle->features().idsInRules.isEmpty());
165 ASSERT(defaultStyle->features().siblingRules.isEmpty());
166 }
167
168 } // namespace WebCore
169