OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. | 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. |
3 * Copyright (C) 2009 Torch Mobile, Inc. http://www.torchmobile.com/ | 3 * Copyright (C) 2009 Torch Mobile, Inc. http://www.torchmobile.com/ |
4 * Copyright (C) 2010 Google Inc. All Rights Reserved. | 4 * Copyright (C) 2010 Google Inc. All Rights Reserved. |
5 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 16 matching lines...) Expand all Loading... |
27 | 27 |
28 #include "config.h" | 28 #include "config.h" |
29 #include "HTMLPreloadScanner.h" | 29 #include "HTMLPreloadScanner.h" |
30 | 30 |
31 #include "HTMLNames.h" | 31 #include "HTMLNames.h" |
32 #include "HTMLParserIdioms.h" | 32 #include "HTMLParserIdioms.h" |
33 #include "HTMLParserOptions.h" | 33 #include "HTMLParserOptions.h" |
34 #include "HTMLTokenizer.h" | 34 #include "HTMLTokenizer.h" |
35 #include "InputTypeNames.h" | 35 #include "InputTypeNames.h" |
36 #include "LinkRelAttribute.h" | 36 #include "LinkRelAttribute.h" |
37 #include "MediaList.h" | |
38 #include "MediaQueryEvaluator.h" | |
39 #include <wtf/Functional.h> | 37 #include <wtf/Functional.h> |
40 #include <wtf/MainThread.h> | 38 #include <wtf/MainThread.h> |
41 | 39 |
42 namespace WebCore { | 40 namespace WebCore { |
43 | 41 |
44 using namespace HTMLNames; | 42 using namespace HTMLNames; |
45 | 43 |
46 TokenPreloadScanner::TagId TokenPreloadScanner::tagIdFor(const HTMLToken::DataVe
ctor& data) | 44 TokenPreloadScanner::TagId TokenPreloadScanner::tagIdFor(const HTMLToken::DataVe
ctor& data) |
47 { | 45 { |
48 AtomicString tagName(data); | 46 AtomicString tagName(data); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 } | 102 } |
105 ASSERT_NOT_REACHED(); | 103 ASSERT_NOT_REACHED(); |
106 return "unknown"; | 104 return "unknown"; |
107 } | 105 } |
108 | 106 |
109 class TokenPreloadScanner::StartTagScanner { | 107 class TokenPreloadScanner::StartTagScanner { |
110 public: | 108 public: |
111 explicit StartTagScanner(TagId tagId) | 109 explicit StartTagScanner(TagId tagId) |
112 : m_tagId(tagId) | 110 : m_tagId(tagId) |
113 , m_linkIsStyleSheet(false) | 111 , m_linkIsStyleSheet(false) |
114 , m_linkMediaAttributeIsScreen(true) | |
115 , m_inputIsImage(false) | 112 , m_inputIsImage(false) |
116 { | 113 { |
117 } | 114 } |
118 | 115 |
119 void processAttributes(const HTMLToken::AttributeList& attributes) | 116 void processAttributes(const HTMLToken::AttributeList& attributes) |
120 { | 117 { |
121 ASSERT(isMainThread()); | 118 ASSERT(isMainThread()); |
122 if (m_tagId >= UnknownTagId) | 119 if (m_tagId >= UnknownTagId) |
123 return; | 120 return; |
124 for (HTMLToken::AttributeList::const_iterator iter = attributes.begin();
iter != attributes.end(); ++iter) { | 121 for (HTMLToken::AttributeList::const_iterator iter = attributes.begin();
iter != attributes.end(); ++iter) { |
(...skipping 11 matching lines...) Expand all Loading... |
136 for (Vector<CompactHTMLToken::Attribute>::const_iterator iter = attribut
es.begin(); iter != attributes.end(); ++iter) | 133 for (Vector<CompactHTMLToken::Attribute>::const_iterator iter = attribut
es.begin(); iter != attributes.end(); ++iter) |
137 processAttribute(iter->name, iter->value); | 134 processAttribute(iter->name, iter->value); |
138 } | 135 } |
139 #endif | 136 #endif |
140 | 137 |
141 PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL
) | 138 PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL
) |
142 { | 139 { |
143 if (!shouldPreload()) | 140 if (!shouldPreload()) |
144 return nullptr; | 141 return nullptr; |
145 | 142 |
146 OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_t
agId), m_urlToLoad, predictedBaseURL, resourceType()); | 143 OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_t
agId), m_urlToLoad, predictedBaseURL, resourceType(), m_mediaAttribute); |
147 request->setCrossOriginModeAllowsCookies(crossOriginModeAllowsCookies())
; | 144 request->setCrossOriginModeAllowsCookies(crossOriginModeAllowsCookies())
; |
148 request->setCharset(charset()); | 145 request->setCharset(charset()); |
149 return request.release(); | 146 return request.release(); |
150 } | 147 } |
151 | 148 |
152 static bool match(const AtomicString& name, const QualifiedName& qName) | 149 static bool match(const AtomicString& name, const QualifiedName& qName) |
153 { | 150 { |
154 ASSERT(isMainThread()); | 151 ASSERT(isMainThread()); |
155 return qName.localName() == name; | 152 return qName.localName() == name; |
156 } | 153 } |
(...skipping 16 matching lines...) Expand all Loading... |
173 if (match(attributeName, srcAttr)) | 170 if (match(attributeName, srcAttr)) |
174 setUrlToLoad(attributeValue); | 171 setUrlToLoad(attributeValue); |
175 else if (match(attributeName, crossoriginAttr) && !attributeValue.is
Null()) | 172 else if (match(attributeName, crossoriginAttr) && !attributeValue.is
Null()) |
176 m_crossOriginMode = stripLeadingAndTrailingHTMLSpaces(attributeV
alue); | 173 m_crossOriginMode = stripLeadingAndTrailingHTMLSpaces(attributeV
alue); |
177 } else if (m_tagId == LinkTagId) { | 174 } else if (m_tagId == LinkTagId) { |
178 if (match(attributeName, hrefAttr)) | 175 if (match(attributeName, hrefAttr)) |
179 setUrlToLoad(attributeValue); | 176 setUrlToLoad(attributeValue); |
180 else if (match(attributeName, relAttr)) | 177 else if (match(attributeName, relAttr)) |
181 m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue); | 178 m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue); |
182 else if (match(attributeName, mediaAttr)) | 179 else if (match(attributeName, mediaAttr)) |
183 m_linkMediaAttributeIsScreen = linkMediaAttributeIsScreen(attrib
uteValue); | 180 m_mediaAttribute = attributeValue; |
184 } else if (m_tagId == InputTagId) { | 181 } else if (m_tagId == InputTagId) { |
185 if (match(attributeName, srcAttr)) | 182 if (match(attributeName, srcAttr)) |
186 setUrlToLoad(attributeValue); | 183 setUrlToLoad(attributeValue); |
187 else if (match(attributeName, typeAttr)) | 184 else if (match(attributeName, typeAttr)) |
188 m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeName
s::image()); | 185 m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeName
s::image()); |
189 } | 186 } |
190 } | 187 } |
191 | 188 |
192 static bool relAttributeIsStyleSheet(const String& attributeValue) | 189 static bool relAttributeIsStyleSheet(const String& attributeValue) |
193 { | 190 { |
194 LinkRelAttribute rel(attributeValue); | 191 LinkRelAttribute rel(attributeValue); |
195 return rel.m_isStyleSheet && !rel.m_isAlternate && rel.m_iconType == Inv
alidIcon && !rel.m_isDNSPrefetch; | 192 return rel.m_isStyleSheet && !rel.m_isAlternate && rel.m_iconType == Inv
alidIcon && !rel.m_isDNSPrefetch; |
196 } | 193 } |
197 | 194 |
198 static bool linkMediaAttributeIsScreen(const String& attributeValue) | |
199 { | |
200 if (attributeValue.isEmpty()) | |
201 return true; | |
202 RefPtr<MediaQuerySet> mediaQueries = MediaQuerySet::createAllowingDescri
ptionSyntax(attributeValue); | |
203 | |
204 // Only preload screen media stylesheets. Used this way, the evaluator e
valuates to true for any | |
205 // rules containing complex queries (full evaluation is possible but it
requires a frame and a style selector which | |
206 // may be problematic here). | |
207 MediaQueryEvaluator mediaQueryEvaluator("screen"); | |
208 return mediaQueryEvaluator.eval(mediaQueries.get()); | |
209 } | |
210 | |
211 void setUrlToLoad(const String& attributeValue) | 195 void setUrlToLoad(const String& attributeValue) |
212 { | 196 { |
213 // We only respect the first src/href, per HTML5: | 197 // We only respect the first src/href, per HTML5: |
214 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenizat
ion.html#attribute-name-state | 198 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenizat
ion.html#attribute-name-state |
215 if (!m_urlToLoad.isEmpty()) | 199 if (!m_urlToLoad.isEmpty()) |
216 return; | 200 return; |
217 m_urlToLoad = stripLeadingAndTrailingHTMLSpaces(attributeValue); | 201 m_urlToLoad = stripLeadingAndTrailingHTMLSpaces(attributeValue); |
218 } | 202 } |
219 | 203 |
220 const String& charset() const | 204 const String& charset() const |
221 { | 205 { |
222 // FIXME: Its not clear that this if is needed, the loader probably igno
res charset for image requests anyway. | 206 // FIXME: Its not clear that this if is needed, the loader probably igno
res charset for image requests anyway. |
223 if (m_tagId == ImgTagId) | 207 if (m_tagId == ImgTagId) |
224 return emptyString(); | 208 return emptyString(); |
225 return m_charset; | 209 return m_charset; |
226 } | 210 } |
227 | 211 |
228 CachedResource::Type resourceType() const | 212 CachedResource::Type resourceType() const |
229 { | 213 { |
230 if (m_tagId == ScriptTagId) | 214 if (m_tagId == ScriptTagId) |
231 return CachedResource::Script; | 215 return CachedResource::Script; |
232 if (m_tagId == ImgTagId || (m_tagId == InputTagId && m_inputIsImage)) | 216 if (m_tagId == ImgTagId || (m_tagId == InputTagId && m_inputIsImage)) |
233 return CachedResource::ImageResource; | 217 return CachedResource::ImageResource; |
234 if (m_tagId == LinkTagId && m_linkIsStyleSheet && m_linkMediaAttributeIs
Screen) | 218 if (m_tagId == LinkTagId && m_linkIsStyleSheet) |
235 return CachedResource::CSSStyleSheet; | 219 return CachedResource::CSSStyleSheet; |
236 ASSERT_NOT_REACHED(); | 220 ASSERT_NOT_REACHED(); |
237 return CachedResource::RawResource; | 221 return CachedResource::RawResource; |
238 } | 222 } |
239 | 223 |
240 bool shouldPreload() | 224 bool shouldPreload() |
241 { | 225 { |
242 if (m_urlToLoad.isEmpty()) | 226 if (m_urlToLoad.isEmpty()) |
243 return false; | 227 return false; |
244 | 228 |
245 if (m_tagId == LinkTagId && (!m_linkIsStyleSheet || !m_linkMediaAttribut
eIsScreen)) | 229 if (m_tagId == LinkTagId && !m_linkIsStyleSheet) |
246 return false; | 230 return false; |
247 | 231 |
248 if (m_tagId == InputTagId && !m_inputIsImage) | 232 if (m_tagId == InputTagId && !m_inputIsImage) |
249 return false; | 233 return false; |
250 | 234 |
251 return true; | 235 return true; |
252 } | 236 } |
253 | 237 |
254 bool crossOriginModeAllowsCookies() | 238 bool crossOriginModeAllowsCookies() |
255 { | 239 { |
256 return m_crossOriginMode.isNull() || equalIgnoringCase(m_crossOriginMode
, "use-credentials"); | 240 return m_crossOriginMode.isNull() || equalIgnoringCase(m_crossOriginMode
, "use-credentials"); |
257 } | 241 } |
258 | 242 |
259 TagId m_tagId; | 243 TagId m_tagId; |
260 String m_urlToLoad; | 244 String m_urlToLoad; |
261 String m_charset; | 245 String m_charset; |
262 String m_crossOriginMode; | 246 String m_crossOriginMode; |
263 bool m_linkIsStyleSheet; | 247 bool m_linkIsStyleSheet; |
264 bool m_linkMediaAttributeIsScreen; | 248 String m_mediaAttribute; |
265 bool m_inputIsImage; | 249 bool m_inputIsImage; |
266 }; | 250 }; |
267 | 251 |
268 TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL) | 252 TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL) |
269 : m_documentURL(documentURL) | 253 : m_documentURL(documentURL) |
270 , m_inStyle(false) | 254 , m_inStyle(false) |
271 , m_templateCount(0) | 255 , m_templateCount(0) |
272 { | 256 { |
273 } | 257 } |
274 | 258 |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 if (m_token.type() == HTMLToken::StartTag) | 384 if (m_token.type() == HTMLToken::StartTag) |
401 m_tokenizer->updateStateFor(AtomicString(m_token.name())); | 385 m_tokenizer->updateStateFor(AtomicString(m_token.name())); |
402 m_scanner.scan(m_token, requests); | 386 m_scanner.scan(m_token, requests); |
403 m_token.clear(); | 387 m_token.clear(); |
404 } | 388 } |
405 | 389 |
406 preloader->takeAndPreload(requests); | 390 preloader->takeAndPreload(requests); |
407 } | 391 } |
408 | 392 |
409 } | 393 } |
OLD | NEW |