Home | History | Annotate | Download | only in css
      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