| 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 |