WebCore/html/CSSPreloadScanner.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
       
     3  * Copyright (C) 2009 Torch Mobile, Inc. http://www.torchmobile.com/
       
     4  * Copyright (C) 2010 Google Inc. All Rights Reserved.
       
     5  *
       
     6  * Redistribution and use in source and binary forms, with or without
       
     7  * modification, are permitted provided that the following conditions
       
     8  * are met:
       
     9  * 1. Redistributions of source code must retain the above copyright
       
    10  *    notice, this list of conditions and the following disclaimer.
       
    11  * 2. Redistributions in binary form must reproduce the above copyright
       
    12  *    notice, this list of conditions and the following disclaimer in the
       
    13  *    documentation and/or other materials provided with the distribution.
       
    14  *
       
    15  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
       
    16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
    17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       
    18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
       
    19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
       
    20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
       
    21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
       
    22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
       
    23  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
       
    26  */
       
    27 
       
    28 #include "config.h"
       
    29 #include "CSSPreloadScanner.h"
       
    30 
       
    31 #include "CSSHelper.h"
       
    32 #include "CachedCSSStyleSheet.h"
       
    33 #include "DocLoader.h"
       
    34 #include "Document.h"
       
    35 #include "HTMLToken.h"
       
    36 
       
    37 namespace WebCore {
       
    38 
       
    39 static inline bool isWhitespace(UChar c)
       
    40 {
       
    41     return c == ' ' || c == '\n' || c == '\r' || c == '\t';
       
    42 }
       
    43 
       
    44 CSSPreloadScanner::CSSPreloadScanner(Document* document)
       
    45     : m_document(document)
       
    46 {
       
    47     reset();
       
    48 }
       
    49 
       
    50 void CSSPreloadScanner::reset()
       
    51 {
       
    52     m_state = Initial;
       
    53     m_rule.clear();
       
    54     m_ruleValue.clear();
       
    55 }
       
    56 
       
    57 void CSSPreloadScanner::scan(const HTMLToken& token, bool scanningBody)
       
    58 {
       
    59     m_scanningBody = scanningBody;
       
    60 
       
    61     const HTMLToken::DataVector& characters = token.characters();
       
    62     for (HTMLToken::DataVector::const_iterator iter = characters.begin();
       
    63          iter != characters.end(); ++iter) {
       
    64         tokenize(*iter);
       
    65     }
       
    66 }
       
    67 
       
    68 inline void CSSPreloadScanner::tokenize(UChar c)
       
    69 {
       
    70     // We are just interested in @import rules, no need for real tokenization here
       
    71     // Searching for other types of resources is probably low payoff.
       
    72     switch (m_state) {
       
    73     case Initial:
       
    74         if (c == '@')
       
    75             m_state = RuleStart;
       
    76         else if (c == '/')
       
    77             m_state = MaybeComment;
       
    78         break;
       
    79     case MaybeComment:
       
    80         if (c == '*')
       
    81             m_state = Comment;
       
    82         else
       
    83             m_state = Initial;
       
    84         break;
       
    85     case Comment:
       
    86         if (c == '*')
       
    87             m_state = MaybeCommentEnd;
       
    88         break;
       
    89     case MaybeCommentEnd:
       
    90         if (c == '/')
       
    91             m_state = Initial;
       
    92         else if (c == '*')
       
    93             ;
       
    94         else
       
    95             m_state = Comment;
       
    96         break;
       
    97     case RuleStart:
       
    98         if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
       
    99             m_rule.clear();
       
   100             m_ruleValue.clear();
       
   101             m_rule.append(c);
       
   102             m_state = Rule;
       
   103         } else
       
   104             m_state = Initial;
       
   105         break;
       
   106     case Rule:
       
   107         if (isWhitespace(c))
       
   108             m_state = AfterRule;
       
   109         else if (c == ';')
       
   110             m_state = Initial;
       
   111         else
       
   112             m_rule.append(c);
       
   113         break;
       
   114     case AfterRule:
       
   115         if (isWhitespace(c))
       
   116             ;
       
   117         else if (c == ';')
       
   118             m_state = Initial;
       
   119         else {
       
   120             m_state = RuleValue;
       
   121             m_ruleValue.append(c);
       
   122         }
       
   123         break;
       
   124     case RuleValue:
       
   125         if (isWhitespace(c))
       
   126             m_state = AfterRuleValue;
       
   127         else if (c == ';') {
       
   128             emitRule();
       
   129             m_state = Initial;
       
   130         } else 
       
   131             m_ruleValue.append(c);
       
   132         break;
       
   133     case AfterRuleValue:
       
   134         if (isWhitespace(c))
       
   135             ;
       
   136         else if (c == ';') {
       
   137             emitRule();
       
   138             m_state = Initial;
       
   139         } else {
       
   140             // FIXME: media rules
       
   141             m_state = Initial;
       
   142         }
       
   143         break;
       
   144     }
       
   145 }
       
   146 
       
   147 void CSSPreloadScanner::emitRule()
       
   148 {
       
   149     String rule(m_rule.data(), m_rule.size());
       
   150     if (equalIgnoringCase(rule, "import") && !m_ruleValue.isEmpty()) {
       
   151         String value(m_ruleValue.data(), m_ruleValue.size());
       
   152         String url = deprecatedParseURL(value);
       
   153         if (!url.isEmpty())
       
   154             m_document->docLoader()->preload(CachedResource::CSSStyleSheet, url, String(), m_scanningBody);
       
   155     }
       
   156     m_rule.clear();
       
   157     m_ruleValue.clear();
       
   158 }
       
   159 
       
   160 }