| 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 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 const Vector<CompactHTMLToken::Attribute>& attributes) { | 178 const Vector<CompactHTMLToken::Attribute>& attributes) { |
| 179 if (!m_tagImpl) | 179 if (!m_tagImpl) |
| 180 return; | 180 return; |
| 181 for (const CompactHTMLToken::Attribute& htmlTokenAttribute : attributes) | 181 for (const CompactHTMLToken::Attribute& htmlTokenAttribute : attributes) |
| 182 processAttribute(htmlTokenAttribute.name(), htmlTokenAttribute.value()); | 182 processAttribute(htmlTokenAttribute.name(), htmlTokenAttribute.value()); |
| 183 } | 183 } |
| 184 | 184 |
| 185 void handlePictureSourceURL(PictureData& pictureData) { | 185 void handlePictureSourceURL(PictureData& pictureData) { |
| 186 if (match(m_tagImpl, sourceTag) && m_matched && | 186 if (match(m_tagImpl, sourceTag) && m_matched && |
| 187 pictureData.sourceURL.isEmpty()) { | 187 pictureData.sourceURL.isEmpty()) { |
| 188 // Must create an isolatedCopy() since the srcset attribute value will | 188 // Must create an isolatedCopy() since the srcset attribute value will get |
| 189 // get sent back to the main thread between when we set this, and when we | 189 // sent back to the main thread between when we set this, and when we |
| 190 // process the closing tag which would clear m_pictureData. Having any | 190 // process the closing tag which would clear m_pictureData. Having any ref |
| 191 // ref to a string we're going to send will fail isSafeToSendToAnotherThre
ad(). | 191 // to a string we're going to send will fail |
| 192 // isSafeToSendToAnotherThread(). |
| 192 pictureData.sourceURL = m_srcsetImageCandidate.toString().isolatedCopy(); | 193 pictureData.sourceURL = m_srcsetImageCandidate.toString().isolatedCopy(); |
| 193 pictureData.sourceSizeSet = m_sourceSizeSet; | 194 pictureData.sourceSizeSet = m_sourceSizeSet; |
| 194 pictureData.sourceSize = m_sourceSize; | 195 pictureData.sourceSize = m_sourceSize; |
| 195 pictureData.picked = true; | 196 pictureData.picked = true; |
| 196 } else if (match(m_tagImpl, imgTag) && !pictureData.sourceURL.isEmpty()) { | 197 } else if (match(m_tagImpl, imgTag) && !pictureData.sourceURL.isEmpty()) { |
| 197 setUrlToLoad(pictureData.sourceURL, AllowURLReplacement); | 198 setUrlToLoad(pictureData.sourceURL, AllowURLReplacement); |
| 198 } | 199 } |
| 199 } | 200 } |
| 200 | 201 |
| 201 std::unique_ptr<PreloadRequest> createPreloadRequest( | 202 std::unique_ptr<PreloadRequest> createPreloadRequest( |
| (...skipping 26 matching lines...) Expand all Loading... |
| 228 } | 229 } |
| 229 if (sourceSizeSet) { | 230 if (sourceSizeSet) { |
| 230 resourceWidth.width = sourceSize; | 231 resourceWidth.width = sourceSize; |
| 231 resourceWidth.isSet = true; | 232 resourceWidth.isSet = true; |
| 232 } | 233 } |
| 233 | 234 |
| 234 Resource::Type type; | 235 Resource::Type type; |
| 235 if (!resourceType(type)) | 236 if (!resourceType(type)) |
| 236 return nullptr; | 237 return nullptr; |
| 237 | 238 |
| 238 // The element's 'referrerpolicy' attribute (if present) takes precedence ov
er the document's referrer policy. | 239 // The element's 'referrerpolicy' attribute (if present) takes precedence |
| 240 // over the document's referrer policy. |
| 239 ReferrerPolicy referrerPolicy = (m_referrerPolicy != ReferrerPolicyDefault) | 241 ReferrerPolicy referrerPolicy = (m_referrerPolicy != ReferrerPolicyDefault) |
| 240 ? m_referrerPolicy | 242 ? m_referrerPolicy |
| 241 : documentReferrerPolicy; | 243 : documentReferrerPolicy; |
| 242 std::unique_ptr<PreloadRequest> request = PreloadRequest::create( | 244 std::unique_ptr<PreloadRequest> request = PreloadRequest::create( |
| 243 initiatorFor(m_tagImpl), position, m_urlToLoad, predictedBaseURL, type, | 245 initiatorFor(m_tagImpl), position, m_urlToLoad, predictedBaseURL, type, |
| 244 referrerPolicy, resourceWidth, clientHintsPreferences, requestType); | 246 referrerPolicy, resourceWidth, clientHintsPreferences, requestType); |
| 245 request->setCrossOrigin(m_crossOrigin); | 247 request->setCrossOrigin(m_crossOrigin); |
| 246 request->setNonce(m_nonce); | 248 request->setNonce(m_nonce); |
| 247 request->setCharset(charset()); | 249 request->setCharset(charset()); |
| 248 request->setDefer(m_defer); | 250 request->setDefer(m_defer); |
| 249 request->setIntegrityMetadata(m_integrityMetadata); | 251 request->setIntegrityMetadata(m_integrityMetadata); |
| 250 | 252 |
| 251 // TODO(csharrison): Once this is deprecated, just abort the request | 253 // TODO(csharrison): Once this is deprecated, just abort the request here. |
| 252 // here. | |
| 253 if (match(m_tagImpl, scriptTag) && | 254 if (match(m_tagImpl, scriptTag) && |
| 254 !ScriptLoader::isValidScriptTypeAndLanguage( | 255 !ScriptLoader::isValidScriptTypeAndLanguage( |
| 255 m_typeAttributeValue, m_languageAttributeValue, | 256 m_typeAttributeValue, m_languageAttributeValue, |
| 256 ScriptLoader::AllowLegacyTypeInTypeAttribute)) | 257 ScriptLoader::AllowLegacyTypeInTypeAttribute)) |
| 257 request->setScriptHasInvalidTypeOrLanguage(); | 258 request->setScriptHasInvalidTypeOrLanguage(); |
| 258 return request; | 259 return request; |
| 259 } | 260 } |
| 260 | 261 |
| 261 private: | 262 private: |
| 262 template <typename NameType> | 263 template <typename NameType> |
| 263 void processScriptAttribute(const NameType& attributeName, | 264 void processScriptAttribute(const NameType& attributeName, |
| 264 const String& attributeValue) { | 265 const String& attributeValue) { |
| 265 // FIXME - Don't set crossorigin multiple times. | 266 // FIXME - Don't set crossorigin multiple times. |
| 266 if (match(attributeName, srcAttr)) | 267 if (match(attributeName, srcAttr)) |
| 267 setUrlToLoad(attributeValue, DisallowURLReplacement); | 268 setUrlToLoad(attributeValue, DisallowURLReplacement); |
| 268 else if (match(attributeName, crossoriginAttr)) | 269 else if (match(attributeName, crossoriginAttr)) |
| 269 setCrossOrigin(attributeValue); | 270 setCrossOrigin(attributeValue); |
| 270 else if (match(attributeName, nonceAttr)) | 271 else if (match(attributeName, nonceAttr)) |
| 271 setNonce(attributeValue); | 272 setNonce(attributeValue); |
| 272 else if (match(attributeName, asyncAttr)) | 273 else if (match(attributeName, asyncAttr)) |
| 273 setDefer(FetchRequest::LazyLoad); | 274 setDefer(FetchRequest::LazyLoad); |
| 274 else if (match(attributeName, deferAttr)) | 275 else if (match(attributeName, deferAttr)) |
| 275 setDefer(FetchRequest::LazyLoad); | 276 setDefer(FetchRequest::LazyLoad); |
| 276 // Note that only scripts need to have the integrity metadata set on | 277 // Note that only scripts need to have the integrity metadata set on |
| 277 // preloads. This is because script resources fetches, and only script | 278 // preloads. This is because script resources fetches, and only script |
| 278 // resource fetches, need to re-request resources if a cached version | 279 // resource fetches, need to re-request resources if a cached version has |
| 279 // has different metadata (including empty) from the metadata on the | 280 // different metadata (including empty) from the metadata on the request. |
| 280 // request. See the comment before the call to | 281 // See the comment before the call to mustRefetchDueToIntegrityMismatch() in |
| 281 // mustRefetchDueToIntegrityMismatch() in | 282 // Source/core/fetch/ResourceFetcher.cpp for a more complete explanation. |
| 282 // Source/core/fetch/ResourceFetcher.cpp for a more complete | |
| 283 // explanation. | |
| 284 else if (match(attributeName, integrityAttr)) | 283 else if (match(attributeName, integrityAttr)) |
| 285 SubresourceIntegrity::parseIntegrityAttribute(attributeValue, | 284 SubresourceIntegrity::parseIntegrityAttribute(attributeValue, |
| 286 m_integrityMetadata); | 285 m_integrityMetadata); |
| 287 else if (match(attributeName, typeAttr)) | 286 else if (match(attributeName, typeAttr)) |
| 288 m_typeAttributeValue = attributeValue; | 287 m_typeAttributeValue = attributeValue; |
| 289 else if (match(attributeName, languageAttr)) | 288 else if (match(attributeName, languageAttr)) |
| 290 m_languageAttributeValue = attributeValue; | 289 m_languageAttributeValue = attributeValue; |
| 291 } | 290 } |
| 292 | 291 |
| 293 template <typename NameType> | 292 template <typename NameType> |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.
html#attribute-name-state | 426 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.
html#attribute-name-state |
| 428 if (replacement == DisallowURLReplacement && !m_urlToLoad.isEmpty()) | 427 if (replacement == DisallowURLReplacement && !m_urlToLoad.isEmpty()) |
| 429 return; | 428 return; |
| 430 String url = stripLeadingAndTrailingHTMLSpaces(value); | 429 String url = stripLeadingAndTrailingHTMLSpaces(value); |
| 431 if (url.isEmpty()) | 430 if (url.isEmpty()) |
| 432 return; | 431 return; |
| 433 m_urlToLoad = url; | 432 m_urlToLoad = url; |
| 434 } | 433 } |
| 435 | 434 |
| 436 const String& charset() const { | 435 const String& charset() const { |
| 437 // FIXME: Its not clear that this if is needed, the loader probably ignores
charset for image requests anyway. | 436 // FIXME: Its not clear that this if is needed, the loader probably ignores |
| 437 // charset for image requests anyway. |
| 438 if (match(m_tagImpl, imgTag) || match(m_tagImpl, videoTag)) | 438 if (match(m_tagImpl, imgTag) || match(m_tagImpl, videoTag)) |
| 439 return emptyString(); | 439 return emptyString(); |
| 440 return m_charset; | 440 return m_charset; |
| 441 } | 441 } |
| 442 | 442 |
| 443 bool resourceType(Resource::Type& type) const { | 443 bool resourceType(Resource::Type& type) const { |
| 444 if (match(m_tagImpl, scriptTag)) { | 444 if (match(m_tagImpl, scriptTag)) { |
| 445 type = Resource::Script; | 445 type = Resource::Script; |
| 446 } else if (match(m_tagImpl, imgTag) || match(m_tagImpl, videoTag) || | 446 } else if (match(m_tagImpl, imgTag) || match(m_tagImpl, videoTag) || |
| 447 (match(m_tagImpl, inputTag) && m_inputIsImage)) { | 447 (match(m_tagImpl, inputTag) && m_inputIsImage)) { |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 | 542 |
| 543 TokenPreloadScannerCheckpoint TokenPreloadScanner::createCheckpoint() { | 543 TokenPreloadScannerCheckpoint TokenPreloadScanner::createCheckpoint() { |
| 544 TokenPreloadScannerCheckpoint checkpoint = m_checkpoints.size(); | 544 TokenPreloadScannerCheckpoint checkpoint = m_checkpoints.size(); |
| 545 m_checkpoints.append(Checkpoint(m_predictedBaseElementURL, m_inStyle, | 545 m_checkpoints.append(Checkpoint(m_predictedBaseElementURL, m_inStyle, |
| 546 m_inScript, m_templateCount)); | 546 m_inScript, m_templateCount)); |
| 547 return checkpoint; | 547 return checkpoint; |
| 548 } | 548 } |
| 549 | 549 |
| 550 void TokenPreloadScanner::rewindTo( | 550 void TokenPreloadScanner::rewindTo( |
| 551 TokenPreloadScannerCheckpoint checkpointIndex) { | 551 TokenPreloadScannerCheckpoint checkpointIndex) { |
| 552 ASSERT(checkpointIndex < | 552 // If this ASSERT fires, checkpointIndex is invalid. |
| 553 m_checkpoints | 553 ASSERT(checkpointIndex < m_checkpoints.size()); |
| 554 .size()); // If this ASSERT fires, checkpointIndex is invalid. | |
| 555 const Checkpoint& checkpoint = m_checkpoints[checkpointIndex]; | 554 const Checkpoint& checkpoint = m_checkpoints[checkpointIndex]; |
| 556 m_predictedBaseElementURL = checkpoint.predictedBaseElementURL; | 555 m_predictedBaseElementURL = checkpoint.predictedBaseElementURL; |
| 557 m_inStyle = checkpoint.inStyle; | 556 m_inStyle = checkpoint.inStyle; |
| 558 m_templateCount = checkpoint.templateCount; | 557 m_templateCount = checkpoint.templateCount; |
| 559 | 558 |
| 560 m_didRewind = true; | 559 m_didRewind = true; |
| 561 m_inScript = checkpoint.inScript; | 560 m_inScript = checkpoint.inScript; |
| 562 | 561 |
| 563 m_cssScanner.reset(); | 562 m_cssScanner.reset(); |
| 564 m_checkpoints.clear(); | 563 m_checkpoints.clear(); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 718 | 717 |
| 719 switch (token.type()) { | 718 switch (token.type()) { |
| 720 case HTMLToken::Character: { | 719 case HTMLToken::Character: { |
| 721 if (m_inStyle) { | 720 if (m_inStyle) { |
| 722 m_cssScanner.scan(token.data(), source, requests, | 721 m_cssScanner.scan(token.data(), source, requests, |
| 723 m_predictedBaseElementURL); | 722 m_predictedBaseElementURL); |
| 724 } else if (m_inScript && likelyDocumentWriteScript && !m_didRewind) { | 723 } else if (m_inScript && likelyDocumentWriteScript && !m_didRewind) { |
| 725 // Don't mark scripts for evaluation if the preloader rewound to a | 724 // Don't mark scripts for evaluation if the preloader rewound to a |
| 726 // previous checkpoint. This could cause re-evaluation of scripts if | 725 // previous checkpoint. This could cause re-evaluation of scripts if |
| 727 // care isn't given. | 726 // care isn't given. |
| 728 // TODO(csharrison): Revisit this if rewinds are low hanging fruit for t
he | 727 // TODO(csharrison): Revisit this if rewinds are low hanging fruit for |
| 729 // document.write evaluator. | 728 // the document.write evaluator. |
| 730 *likelyDocumentWriteScript = | 729 *likelyDocumentWriteScript = |
| 731 shouldEvaluateForDocumentWrite(token.data()); | 730 shouldEvaluateForDocumentWrite(token.data()); |
| 732 } | 731 } |
| 733 return; | 732 return; |
| 734 } | 733 } |
| 735 case HTMLToken::EndTag: { | 734 case HTMLToken::EndTag: { |
| 736 const StringImpl* tagImpl = tagImplFor(token.data()); | 735 const StringImpl* tagImpl = tagImplFor(token.data()); |
| 737 if (match(tagImpl, templateTag)) { | 736 if (match(tagImpl, templateTag)) { |
| 738 if (m_templateCount) | 737 if (m_templateCount) |
| 739 --m_templateCount; | 738 --m_templateCount; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 758 return; | 757 return; |
| 759 const StringImpl* tagImpl = tagImplFor(token.data()); | 758 const StringImpl* tagImpl = tagImplFor(token.data()); |
| 760 if (match(tagImpl, templateTag)) { | 759 if (match(tagImpl, templateTag)) { |
| 761 ++m_templateCount; | 760 ++m_templateCount; |
| 762 return; | 761 return; |
| 763 } | 762 } |
| 764 if (match(tagImpl, styleTag)) { | 763 if (match(tagImpl, styleTag)) { |
| 765 m_inStyle = true; | 764 m_inStyle = true; |
| 766 return; | 765 return; |
| 767 } | 766 } |
| 768 // Don't early return, because the StartTagScanner needs to look at | 767 // Don't early return, because the StartTagScanner needs to look at these |
| 769 // these too. | 768 // too. |
| 770 if (match(tagImpl, scriptTag)) { | 769 if (match(tagImpl, scriptTag)) { |
| 771 m_inScript = true; | 770 m_inScript = true; |
| 772 } | 771 } |
| 773 if (match(tagImpl, baseTag)) { | 772 if (match(tagImpl, baseTag)) { |
| 774 // The first <base> element is the one that wins. | 773 // The first <base> element is the one that wins. |
| 775 if (!m_predictedBaseElementURL.isEmpty()) | 774 if (!m_predictedBaseElementURL.isEmpty()) |
| 776 return; | 775 return; |
| 777 updatePredictedBaseURL(token); | 776 updatePredictedBaseURL(token); |
| 778 return; | 777 return; |
| 779 } | 778 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 843 | 842 |
| 844 HTMLPreloadScanner::~HTMLPreloadScanner() {} | 843 HTMLPreloadScanner::~HTMLPreloadScanner() {} |
| 845 | 844 |
| 846 void HTMLPreloadScanner::appendToEnd(const SegmentedString& source) { | 845 void HTMLPreloadScanner::appendToEnd(const SegmentedString& source) { |
| 847 m_source.append(source); | 846 m_source.append(source); |
| 848 } | 847 } |
| 849 | 848 |
| 850 void HTMLPreloadScanner::scanAndPreload(ResourcePreloader* preloader, | 849 void HTMLPreloadScanner::scanAndPreload(ResourcePreloader* preloader, |
| 851 const KURL& startingBaseElementURL, | 850 const KURL& startingBaseElementURL, |
| 852 ViewportDescriptionWrapper* viewport) { | 851 ViewportDescriptionWrapper* viewport) { |
| 853 ASSERT( | 852 // HTMLTokenizer::updateStateFor only works on the main thread. |
| 854 isMainThread()); // HTMLTokenizer::updateStateFor only works on the main
thread. | 853 ASSERT(isMainThread()); |
| 855 | 854 |
| 856 TRACE_EVENT1("blink", "HTMLPreloadScanner::scan", "source_length", | 855 TRACE_EVENT1("blink", "HTMLPreloadScanner::scan", "source_length", |
| 857 m_source.length()); | 856 m_source.length()); |
| 858 | 857 |
| 859 // When we start scanning, our best prediction of the baseElementURL is the re
al one! | 858 // When we start scanning, our best prediction of the baseElementURL is the |
| 859 // real one! |
| 860 if (!startingBaseElementURL.isEmpty()) | 860 if (!startingBaseElementURL.isEmpty()) |
| 861 m_scanner.setPredictedBaseElementURL(startingBaseElementURL); | 861 m_scanner.setPredictedBaseElementURL(startingBaseElementURL); |
| 862 | 862 |
| 863 PreloadRequestStream requests; | 863 PreloadRequestStream requests; |
| 864 | 864 |
| 865 while (m_tokenizer->nextToken(m_source, m_token)) { | 865 while (m_tokenizer->nextToken(m_source, m_token)) { |
| 866 if (m_token.type() == HTMLToken::StartTag) | 866 if (m_token.type() == HTMLToken::StartTag) |
| 867 m_tokenizer->updateStateFor( | 867 m_tokenizer->updateStateFor( |
| 868 attemptStaticStringCreation(m_token.name(), Likely8Bit)); | 868 attemptStaticStringCreation(m_token.name(), Likely8Bit)); |
| 869 bool isCSPMetaTag = false; | 869 bool isCSPMetaTag = false; |
| 870 m_scanner.scan(m_token, m_source, requests, viewport, &isCSPMetaTag); | 870 m_scanner.scan(m_token, m_source, requests, viewport, &isCSPMetaTag); |
| 871 m_token.clear(); | 871 m_token.clear(); |
| 872 // Don't preload anything if a CSP meta tag is found. We should never | 872 // Don't preload anything if a CSP meta tag is found. We should never really |
| 873 // really find them here because the HTMLPreloadScanner is only used for | 873 // find them here because the HTMLPreloadScanner is only used for |
| 874 // dynamically added markup. | 874 // dynamically added markup. |
| 875 if (isCSPMetaTag) | 875 if (isCSPMetaTag) |
| 876 return; | 876 return; |
| 877 } | 877 } |
| 878 | 878 |
| 879 preloader->takeAndPreload(requests); | 879 preloader->takeAndPreload(requests); |
| 880 } | 880 } |
| 881 | 881 |
| 882 CachedDocumentParameters::CachedDocumentParameters(Document* document) { | 882 CachedDocumentParameters::CachedDocumentParameters(Document* document) { |
| 883 ASSERT(isMainThread()); | 883 ASSERT(isMainThread()); |
| 884 ASSERT(document); | 884 ASSERT(document); |
| 885 doHtmlPreloadScanning = | 885 doHtmlPreloadScanning = |
| 886 !document->settings() || document->settings()->doHtmlPreloadScanning(); | 886 !document->settings() || document->settings()->doHtmlPreloadScanning(); |
| 887 doDocumentWritePreloadScanning = doHtmlPreloadScanning && document->frame() && | 887 doDocumentWritePreloadScanning = doHtmlPreloadScanning && document->frame() && |
| 888 document->frame()->isMainFrame(); | 888 document->frame()->isMainFrame(); |
| 889 defaultViewportMinWidth = document->viewportDefaultMinWidth(); | 889 defaultViewportMinWidth = document->viewportDefaultMinWidth(); |
| 890 viewportMetaZeroValuesQuirk = | 890 viewportMetaZeroValuesQuirk = |
| 891 document->settings() && | 891 document->settings() && |
| 892 document->settings()->viewportMetaZeroValuesQuirk(); | 892 document->settings()->viewportMetaZeroValuesQuirk(); |
| 893 viewportMetaEnabled = | 893 viewportMetaEnabled = |
| 894 document->settings() && document->settings()->viewportMetaEnabled(); | 894 document->settings() && document->settings()->viewportMetaEnabled(); |
| 895 referrerPolicy = document->getReferrerPolicy(); | 895 referrerPolicy = document->getReferrerPolicy(); |
| 896 } | 896 } |
| 897 | 897 |
| 898 } // namespace blink | 898 } // namespace blink |
| OLD | NEW |