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 "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 
     60 static const MediaQueryEvaluator& screenEval()
     61 {
     62     DEFINE_STATIC_LOCAL(const MediaQueryEvaluator, staticScreenEval, ("screen"));
     63     return staticScreenEval;
     64 }
     65 
     66 static const MediaQueryEvaluator& printEval()
     67 {
     68     DEFINE_STATIC_LOCAL(const MediaQueryEvaluator, staticPrintEval, ("print"));
     69     return staticPrintEval;
     70 }
     71 
     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 
     79 static StyleSheetContents* parseUASheet(const char* characters, unsigned size)
     80 {
     81     return parseUASheet(String(characters, size));
     82 }
     83 
     84 void CSSDefaultStyleSheets::loadDefaultStylesheetIfNecessary()
     85 {
     86     if (!defaultStyle)
     87         loadDefaultStyle();
     88 }
     89 
     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 
    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 
    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 
    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