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 |