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 13 matching lines...) Expand all Loading... |
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 */ | 26 */ |
27 | 27 |
28 #include "config.h" | 28 #include "config.h" |
29 #include "core/html/parser/HTMLPreloadScanner.h" | 29 #include "core/html/parser/HTMLPreloadScanner.h" |
30 | 30 |
31 #include "HTMLNames.h" | 31 #include "HTMLNames.h" |
32 #include "InputTypeNames.h" | 32 #include "InputTypeNames.h" |
33 #include "RuntimeEnabledFeatures.h" | 33 #include "RuntimeEnabledFeatures.h" |
| 34 #include "core/css/MediaList.h" |
| 35 #include "core/css/MediaQueryEvaluator.h" |
| 36 #include "core/css/MediaValues.h" |
34 #include "core/html/LinkRelAttribute.h" | 37 #include "core/html/LinkRelAttribute.h" |
35 #include "core/html/parser/HTMLParserIdioms.h" | 38 #include "core/html/parser/HTMLParserIdioms.h" |
36 #include "core/html/parser/HTMLSrcsetParser.h" | 39 #include "core/html/parser/HTMLSrcsetParser.h" |
37 #include "core/html/parser/HTMLTokenizer.h" | 40 #include "core/html/parser/HTMLTokenizer.h" |
38 #include "platform/TraceEvent.h" | 41 #include "platform/TraceEvent.h" |
39 #include "wtf/MainThread.h" | 42 #include "wtf/MainThread.h" |
40 | 43 |
41 namespace WebCore { | 44 namespace WebCore { |
42 | 45 |
43 using namespace HTMLNames; | 46 using namespace HTMLNames; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 if (match(tagImpl, inputTag)) | 86 if (match(tagImpl, inputTag)) |
84 return inputTag.localName(); | 87 return inputTag.localName(); |
85 if (match(tagImpl, linkTag)) | 88 if (match(tagImpl, linkTag)) |
86 return linkTag.localName(); | 89 return linkTag.localName(); |
87 if (match(tagImpl, scriptTag)) | 90 if (match(tagImpl, scriptTag)) |
88 return scriptTag.localName(); | 91 return scriptTag.localName(); |
89 ASSERT_NOT_REACHED(); | 92 ASSERT_NOT_REACHED(); |
90 return emptyString(); | 93 return emptyString(); |
91 } | 94 } |
92 | 95 |
| 96 static bool mediaAttributeMatches(const MediaValues& mediaValues, const String&
attributeValue) |
| 97 { |
| 98 RefPtr<MediaQuerySet> mediaQueries = MediaQuerySet::create(attributeValue); |
| 99 MediaQueryEvaluator mediaQueryEvaluator("screen", mediaValues); |
| 100 return mediaQueryEvaluator.eval(mediaQueries.get()); |
| 101 } |
| 102 |
93 class TokenPreloadScanner::StartTagScanner { | 103 class TokenPreloadScanner::StartTagScanner { |
94 public: | 104 public: |
95 StartTagScanner(const StringImpl* tagImpl, float deviceScaleFactor) | 105 StartTagScanner(const StringImpl* tagImpl, PassRefPtr<MediaValues> mediaValu
es) |
96 : m_tagImpl(tagImpl) | 106 : m_tagImpl(tagImpl) |
97 , m_linkIsStyleSheet(false) | 107 , m_linkIsStyleSheet(false) |
| 108 , m_matchedMediaAttribute(true) |
98 , m_inputIsImage(false) | 109 , m_inputIsImage(false) |
99 , m_deviceScaleFactor(deviceScaleFactor) | |
100 , m_encounteredImgSrc(false) | 110 , m_encounteredImgSrc(false) |
101 , m_isCORSEnabled(false) | 111 , m_isCORSEnabled(false) |
102 , m_allowCredentials(DoNotAllowStoredCredentials) | 112 , m_allowCredentials(DoNotAllowStoredCredentials) |
| 113 , m_mediaValues(mediaValues) |
103 { | 114 { |
104 if (!match(m_tagImpl, imgTag) | 115 if (!match(m_tagImpl, imgTag) |
105 && !match(m_tagImpl, inputTag) | 116 && !match(m_tagImpl, inputTag) |
106 && !match(m_tagImpl, linkTag) | 117 && !match(m_tagImpl, linkTag) |
107 && !match(m_tagImpl, scriptTag)) | 118 && !match(m_tagImpl, scriptTag)) |
108 m_tagImpl = 0; | 119 m_tagImpl = 0; |
109 } | 120 } |
110 | 121 |
111 enum URLReplacement { | 122 enum URLReplacement { |
112 AllowURLReplacement, | 123 AllowURLReplacement, |
(...skipping 15 matching lines...) Expand all Loading... |
128 void processAttributes(const Vector<CompactHTMLToken::Attribute>& attributes
) | 139 void processAttributes(const Vector<CompactHTMLToken::Attribute>& attributes
) |
129 { | 140 { |
130 if (!m_tagImpl) | 141 if (!m_tagImpl) |
131 return; | 142 return; |
132 for (Vector<CompactHTMLToken::Attribute>::const_iterator iter = attribut
es.begin(); iter != attributes.end(); ++iter) | 143 for (Vector<CompactHTMLToken::Attribute>::const_iterator iter = attribut
es.begin(); iter != attributes.end(); ++iter) |
133 processAttribute(iter->name, iter->value); | 144 processAttribute(iter->name, iter->value); |
134 } | 145 } |
135 | 146 |
136 PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL
, const SegmentedString& source) | 147 PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL
, const SegmentedString& source) |
137 { | 148 { |
138 if (!shouldPreload()) | 149 if (!shouldPreload() || !m_matchedMediaAttribute) |
139 return nullptr; | 150 return nullptr; |
140 | 151 |
141 TRACE_EVENT_INSTANT1("net", "PreloadRequest", "url", m_urlToLoad.ascii()
); | 152 TRACE_EVENT_INSTANT1("net", "PreloadRequest", "url", m_urlToLoad.ascii()
); |
142 TextPosition position = TextPosition(source.currentLine(), source.curren
tColumn()); | 153 TextPosition position = TextPosition(source.currentLine(), source.curren
tColumn()); |
143 OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_t
agImpl), position, m_urlToLoad, predictedBaseURL, resourceType(), m_mediaAttribu
te); | 154 OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_t
agImpl), position, m_urlToLoad, predictedBaseURL, resourceType()); |
144 if (isCORSEnabled()) | 155 if (isCORSEnabled()) |
145 request->setCrossOriginEnabled(allowStoredCredentials()); | 156 request->setCrossOriginEnabled(allowStoredCredentials()); |
146 request->setCharset(charset()); | 157 request->setCharset(charset()); |
147 return request.release(); | 158 return request.release(); |
148 } | 159 } |
149 | 160 |
150 private: | 161 private: |
151 template<typename NameType> | 162 template<typename NameType> |
152 void processAttribute(const NameType& attributeName, const String& attribute
Value) | 163 void processAttribute(const NameType& attributeName, const String& attribute
Value) |
153 { | 164 { |
154 if (match(attributeName, charsetAttr)) | 165 if (match(attributeName, charsetAttr)) |
155 m_charset = attributeValue; | 166 m_charset = attributeValue; |
156 | 167 |
157 if (match(m_tagImpl, scriptTag)) { | 168 if (match(m_tagImpl, scriptTag)) { |
158 if (match(attributeName, srcAttr)) | 169 if (match(attributeName, srcAttr)) |
159 setUrlToLoad(attributeValue, DisallowURLReplacement); | 170 setUrlToLoad(attributeValue, DisallowURLReplacement); |
160 else if (match(attributeName, crossoriginAttr)) | 171 else if (match(attributeName, crossoriginAttr)) |
161 setCrossOriginAllowed(attributeValue); | 172 setCrossOriginAllowed(attributeValue); |
162 } else if (match(m_tagImpl, imgTag)) { | 173 } else if (match(m_tagImpl, imgTag)) { |
163 if (match(attributeName, srcAttr) && !m_encounteredImgSrc) { | 174 if (match(attributeName, srcAttr) && !m_encounteredImgSrc) { |
164 m_encounteredImgSrc = true; | 175 m_encounteredImgSrc = true; |
165 setUrlToLoad(bestFitSourceForImageAttributes(m_deviceScaleFactor
, attributeValue, m_srcsetImageCandidate), AllowURLReplacement); | 176 setUrlToLoad(bestFitSourceForImageAttributes(m_mediaValues->devi
cePixelRatio(), attributeValue, m_srcsetImageCandidate), AllowURLReplacement); |
166 } else if (match(attributeName, crossoriginAttr)) { | 177 } else if (match(attributeName, crossoriginAttr)) { |
167 setCrossOriginAllowed(attributeValue); | 178 setCrossOriginAllowed(attributeValue); |
168 } else if (RuntimeEnabledFeatures::srcsetEnabled() | 179 } else if (RuntimeEnabledFeatures::srcsetEnabled() |
169 && match(attributeName, srcsetAttr) | 180 && match(attributeName, srcsetAttr) |
170 && m_srcsetImageCandidate.isEmpty()) { | 181 && m_srcsetImageCandidate.isEmpty()) { |
171 m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_devic
eScaleFactor, attributeValue); | 182 m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_media
Values->devicePixelRatio(), attributeValue); |
172 setUrlToLoad(bestFitSourceForImageAttributes(m_deviceScaleFactor
, m_urlToLoad, m_srcsetImageCandidate), AllowURLReplacement); | 183 setUrlToLoad(bestFitSourceForImageAttributes(m_mediaValues->devi
cePixelRatio(), m_urlToLoad, m_srcsetImageCandidate), AllowURLReplacement); |
173 } | 184 } |
174 } else if (match(m_tagImpl, linkTag)) { | 185 } else if (match(m_tagImpl, linkTag)) { |
175 if (match(attributeName, hrefAttr)) | 186 if (match(attributeName, hrefAttr)) |
176 setUrlToLoad(attributeValue, DisallowURLReplacement); | 187 setUrlToLoad(attributeValue, DisallowURLReplacement); |
177 else if (match(attributeName, relAttr)) | 188 else if (match(attributeName, relAttr)) |
178 m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue); | 189 m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue); |
179 else if (match(attributeName, mediaAttr)) | 190 else if (match(attributeName, mediaAttr)) |
180 m_mediaAttribute = attributeValue; | 191 m_matchedMediaAttribute = mediaAttributeMatches(*m_mediaValues,
attributeValue); |
181 else if (match(attributeName, crossoriginAttr)) | 192 else if (match(attributeName, crossoriginAttr)) |
182 setCrossOriginAllowed(attributeValue); | 193 setCrossOriginAllowed(attributeValue); |
183 } else if (match(m_tagImpl, inputTag)) { | 194 } else if (match(m_tagImpl, inputTag)) { |
184 if (match(attributeName, srcAttr)) | 195 if (match(attributeName, srcAttr)) |
185 setUrlToLoad(attributeValue, DisallowURLReplacement); | 196 setUrlToLoad(attributeValue, DisallowURLReplacement); |
186 else if (match(attributeName, typeAttr)) | 197 else if (match(attributeName, typeAttr)) |
187 m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeName
s::image); | 198 m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeName
s::image); |
188 } | 199 } |
189 } | 200 } |
190 | 201 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 m_allowCredentials = AllowStoredCredentials; | 265 m_allowCredentials = AllowStoredCredentials; |
255 else | 266 else |
256 m_allowCredentials = DoNotAllowStoredCredentials; | 267 m_allowCredentials = DoNotAllowStoredCredentials; |
257 } | 268 } |
258 | 269 |
259 const StringImpl* m_tagImpl; | 270 const StringImpl* m_tagImpl; |
260 String m_urlToLoad; | 271 String m_urlToLoad; |
261 ImageCandidate m_srcsetImageCandidate; | 272 ImageCandidate m_srcsetImageCandidate; |
262 String m_charset; | 273 String m_charset; |
263 bool m_linkIsStyleSheet; | 274 bool m_linkIsStyleSheet; |
264 String m_mediaAttribute; | 275 bool m_matchedMediaAttribute; |
265 bool m_inputIsImage; | 276 bool m_inputIsImage; |
266 float m_deviceScaleFactor; | |
267 bool m_encounteredImgSrc; | 277 bool m_encounteredImgSrc; |
268 bool m_isCORSEnabled; | 278 bool m_isCORSEnabled; |
269 StoredCredentials m_allowCredentials; | 279 StoredCredentials m_allowCredentials; |
| 280 RefPtr<MediaValues> m_mediaValues; |
270 }; | 281 }; |
271 | 282 |
272 TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL, float deviceSc
aleFactor) | 283 TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL, PassRefPtr<Med
iaValues> mediaValues) |
273 : m_documentURL(documentURL) | 284 : m_documentURL(documentURL) |
274 , m_inStyle(false) | 285 , m_inStyle(false) |
275 , m_deviceScaleFactor(deviceScaleFactor) | |
276 , m_templateCount(0) | 286 , m_templateCount(0) |
| 287 , m_mediaValues(mediaValues) |
277 { | 288 { |
278 } | 289 } |
279 | 290 |
280 TokenPreloadScanner::~TokenPreloadScanner() | 291 TokenPreloadScanner::~TokenPreloadScanner() |
281 { | 292 { |
282 } | 293 } |
283 | 294 |
284 TokenPreloadScannerCheckpoint TokenPreloadScanner::createCheckpoint() | 295 TokenPreloadScannerCheckpoint TokenPreloadScanner::createCheckpoint() |
285 { | 296 { |
286 TokenPreloadScannerCheckpoint checkpoint = m_checkpoints.size(); | 297 TokenPreloadScannerCheckpoint checkpoint = m_checkpoints.size(); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 return; | 357 return; |
347 } | 358 } |
348 if (match(tagImpl, baseTag)) { | 359 if (match(tagImpl, baseTag)) { |
349 // The first <base> element is the one that wins. | 360 // The first <base> element is the one that wins. |
350 if (!m_predictedBaseElementURL.isEmpty()) | 361 if (!m_predictedBaseElementURL.isEmpty()) |
351 return; | 362 return; |
352 updatePredictedBaseURL(token); | 363 updatePredictedBaseURL(token); |
353 return; | 364 return; |
354 } | 365 } |
355 | 366 |
356 StartTagScanner scanner(tagImpl, m_deviceScaleFactor); | 367 StartTagScanner scanner(tagImpl, m_mediaValues); |
357 scanner.processAttributes(token.attributes()); | 368 scanner.processAttributes(token.attributes()); |
358 OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predicte
dBaseElementURL, source); | 369 OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predicte
dBaseElementURL, source); |
359 if (request) | 370 if (request) |
360 requests.append(request.release()); | 371 requests.append(request.release()); |
361 return; | 372 return; |
362 } | 373 } |
363 default: { | 374 default: { |
364 return; | 375 return; |
365 } | 376 } |
366 } | 377 } |
367 } | 378 } |
368 | 379 |
369 template<typename Token> | 380 template<typename Token> |
370 void TokenPreloadScanner::updatePredictedBaseURL(const Token& token) | 381 void TokenPreloadScanner::updatePredictedBaseURL(const Token& token) |
371 { | 382 { |
372 ASSERT(m_predictedBaseElementURL.isEmpty()); | 383 ASSERT(m_predictedBaseElementURL.isEmpty()); |
373 if (const typename Token::Attribute* hrefAttribute = token.getAttributeItem(
hrefAttr)) | 384 if (const typename Token::Attribute* hrefAttribute = token.getAttributeItem(
hrefAttr)) |
374 m_predictedBaseElementURL = KURL(m_documentURL, stripLeadingAndTrailingH
TMLSpaces(hrefAttribute->value)).copy(); | 385 m_predictedBaseElementURL = KURL(m_documentURL, stripLeadingAndTrailingH
TMLSpaces(hrefAttribute->value)).copy(); |
375 } | 386 } |
376 | 387 |
377 HTMLPreloadScanner::HTMLPreloadScanner(const HTMLParserOptions& options, const K
URL& documentURL, float deviceScaleFactor) | 388 HTMLPreloadScanner::HTMLPreloadScanner(const HTMLParserOptions& options, const K
URL& documentURL, PassRefPtr<MediaValues> mediaValues) |
378 : m_scanner(documentURL, deviceScaleFactor) | 389 : m_scanner(documentURL, mediaValues) |
379 , m_tokenizer(HTMLTokenizer::create(options)) | 390 , m_tokenizer(HTMLTokenizer::create(options)) |
380 { | 391 { |
381 } | 392 } |
382 | 393 |
383 HTMLPreloadScanner::~HTMLPreloadScanner() | 394 HTMLPreloadScanner::~HTMLPreloadScanner() |
384 { | 395 { |
385 } | 396 } |
386 | 397 |
387 void HTMLPreloadScanner::appendToEnd(const SegmentedString& source) | 398 void HTMLPreloadScanner::appendToEnd(const SegmentedString& source) |
388 { | 399 { |
(...skipping 14 matching lines...) Expand all Loading... |
403 if (m_token.type() == HTMLToken::StartTag) | 414 if (m_token.type() == HTMLToken::StartTag) |
404 m_tokenizer->updateStateFor(attemptStaticStringCreation(m_token.name
(), Likely8Bit)); | 415 m_tokenizer->updateStateFor(attemptStaticStringCreation(m_token.name
(), Likely8Bit)); |
405 m_scanner.scan(m_token, m_source, requests); | 416 m_scanner.scan(m_token, m_source, requests); |
406 m_token.clear(); | 417 m_token.clear(); |
407 } | 418 } |
408 | 419 |
409 preloader->takeAndPreload(requests); | 420 preloader->takeAndPreload(requests); |
410 } | 421 } |
411 | 422 |
412 } | 423 } |
OLD | NEW |