2 * Copyright (C) 2008, 2010 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.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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.
29 #include "core/html/parser/CSSPreloadScanner.h"
31 #include "core/FetchInitiatorTypeNames.h"
32 #include "core/html/parser/HTMLParserIdioms.h"
33 #include "platform/text/SegmentedString.h"
37 CSSPreloadScanner::CSSPreloadScanner()
43 CSSPreloadScanner::~CSSPreloadScanner()
47 void CSSPreloadScanner::reset()
54 template<typename Char>
55 void CSSPreloadScanner::scanCommon(const Char* begin, const Char* end, const SegmentedString& source, PreloadRequestStream& requests)
57 m_requests = &requests;
58 for (const Char* it = begin; it != end && m_state != DoneParsingImportRules; ++it)
59 tokenize(*it, source);
63 void CSSPreloadScanner::scan(const HTMLToken::DataVector& data, const SegmentedString& source, PreloadRequestStream& requests)
65 scanCommon(data.data(), data.data() + data.size(), source, requests);
68 void CSSPreloadScanner::scan(const String& tagName, const SegmentedString& source, PreloadRequestStream& requests)
70 if (tagName.is8Bit()) {
71 const LChar* begin = tagName.characters8();
72 scanCommon(begin, begin + tagName.length(), source, requests);
75 const UChar* begin = tagName.characters16();
76 scanCommon(begin, begin + tagName.length(), source, requests);
79 inline void CSSPreloadScanner::tokenize(UChar c, const SegmentedString& source)
81 // We are just interested in @import rules, no need for real tokenization here
82 // Searching for other types of resources is probably low payoff.
85 if (isHTMLSpace<UChar>(c))
90 m_state = MaybeComment;
92 m_state = DoneParsingImportRules;
102 m_state = MaybeCommentEnd;
104 case MaybeCommentEnd:
113 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
122 if (isHTMLSpace<UChar>(c))
130 if (isHTMLSpace<UChar>(c))
135 m_state = DoneParsingImportRules;
138 m_ruleValue.append(c);
142 if (isHTMLSpace<UChar>(c))
143 m_state = AfterRuleValue;
147 m_ruleValue.append(c);
150 if (isHTMLSpace<UChar>(c))
155 m_state = DoneParsingImportRules;
157 // FIXME: media rules
161 case DoneParsingImportRules:
162 ASSERT_NOT_REACHED();
167 static String parseCSSStringOrURL(const String& string)
170 size_t reducedLength = string.length();
172 while (reducedLength && isHTMLSpace<UChar>(string[offset])) {
176 while (reducedLength && isHTMLSpace<UChar>(string[offset + reducedLength - 1]))
179 if (reducedLength >= 5
180 && (string[offset] == 'u' || string[offset] == 'U')
181 && (string[offset + 1] == 'r' || string[offset + 1] == 'R')
182 && (string[offset + 2] == 'l' || string[offset + 2] == 'L')
183 && string[offset + 3] == '('
184 && string[offset + reducedLength - 1] == ')') {
189 while (reducedLength && isHTMLSpace<UChar>(string[offset])) {
193 while (reducedLength && isHTMLSpace<UChar>(string[offset + reducedLength - 1]))
196 if (reducedLength < 2 || string[offset] != string[offset + reducedLength - 1] || !(string[offset] == '\'' || string[offset] == '"'))
201 while (reducedLength && isHTMLSpace<UChar>(string[offset])) {
205 while (reducedLength && isHTMLSpace<UChar>(string[offset + reducedLength - 1]))
208 return string.substring(offset, reducedLength);
211 void CSSPreloadScanner::emitRule(const SegmentedString& source)
213 if (equalIgnoringCase(m_rule, "import")) {
214 String url = parseCSSStringOrURL(m_ruleValue.toString());
215 if (!url.isEmpty()) {
216 KURL baseElementURL; // FIXME: This should be passed in from the HTMLPreloadScaner via scan()!
217 TextPosition position = TextPosition(source.currentLine(), source.currentColumn());
218 OwnPtr<PreloadRequest> request = PreloadRequest::create(FetchInitiatorTypeNames::css, position, url, baseElementURL, Resource::CSSStyleSheet);
219 // FIXME: Should this be including the charset in the preload request?
220 m_requests->append(request.release());
223 } else if (equalIgnoringCase(m_rule, "charset"))
226 m_state = DoneParsingImportRules;