Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(872)

Side by Side Diff: Source/core/html/parser/HTMLPreloadScanner.cpp

Issue 1152043005: Add <link rel=preconnect> support to the HTMLPreloadScanner (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 RefPtrWillBeRawPtr<MediaQuerySet> mediaQueries = MediaQuerySet::createOffMai nThread(attributeValue); 104 RefPtrWillBeRawPtr<MediaQuerySet> mediaQueries = MediaQuerySet::createOffMai nThread(attributeValue);
105 MediaQueryEvaluator mediaQueryEvaluator(mediaValues); 105 MediaQueryEvaluator mediaQueryEvaluator(mediaValues);
106 return mediaQueryEvaluator.eval(mediaQueries.get()); 106 return mediaQueryEvaluator.eval(mediaQueries.get());
107 } 107 }
108 108
109 class TokenPreloadScanner::StartTagScanner { 109 class TokenPreloadScanner::StartTagScanner {
110 public: 110 public:
111 StartTagScanner(const StringImpl* tagImpl, PassRefPtr<MediaValues> mediaValu es) 111 StartTagScanner(const StringImpl* tagImpl, PassRefPtr<MediaValues> mediaValu es)
112 : m_tagImpl(tagImpl) 112 : m_tagImpl(tagImpl)
113 , m_linkIsStyleSheet(false) 113 , m_linkIsStyleSheet(false)
114 , m_linkIsPreconnect(false)
114 , m_matchedMediaAttribute(true) 115 , m_matchedMediaAttribute(true)
115 , m_inputIsImage(false) 116 , m_inputIsImage(false)
116 , m_sourceSize(0) 117 , m_sourceSize(0)
117 , m_sourceSizeSet(false) 118 , m_sourceSizeSet(false)
118 , m_isCORSEnabled(false) 119 , m_isCORSEnabled(false)
119 , m_defer(FetchRequest::NoDefer) 120 , m_defer(FetchRequest::NoDefer)
120 , m_allowCredentials(DoNotAllowStoredCredentials) 121 , m_allowCredentials(DoNotAllowStoredCredentials)
121 , m_mediaValues(mediaValues) 122 , m_mediaValues(mediaValues)
122 { 123 {
123 ASSERT(m_mediaValues->isCached()); 124 ASSERT(m_mediaValues->isCached());
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 } 160 }
160 161
161 void handlePictureSourceURL(String& sourceURL) 162 void handlePictureSourceURL(String& sourceURL)
162 { 163 {
163 if (match(m_tagImpl, sourceTag) && m_matchedMediaAttribute && sourceURL. isEmpty()) 164 if (match(m_tagImpl, sourceTag) && m_matchedMediaAttribute && sourceURL. isEmpty())
164 sourceURL = m_srcsetImageCandidate.toString(); 165 sourceURL = m_srcsetImageCandidate.toString();
165 else if (match(m_tagImpl, imgTag) && !sourceURL.isEmpty()) 166 else if (match(m_tagImpl, imgTag) && !sourceURL.isEmpty())
166 setUrlToLoad(sourceURL, AllowURLReplacement); 167 setUrlToLoad(sourceURL, AllowURLReplacement);
167 } 168 }
168 169
169 PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL , const SegmentedString& source, const ClientHintsPreferences& clientHintsPrefer ences) 170 void preconnectHost(PreconnecterHost* preconnecter, KURL baseURL)
170 { 171 {
172 KURL host(baseURL, m_urlToLoad);
173 if (!host.isValid())
174 return;
175 // TODO(yoav): Add a real cross attribute value here once it's no longer a no-op.
Mike West 2015/06/02 11:18:33 I see. Ok, yes, please add this TODO to the test a
176 preconnecter->preconnect(host, CrossOriginAttributeNotSet);
177 }
178
179 PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL , const SegmentedString& source, const ClientHintsPreferences& clientHintsPrefer ences, PreconnecterHost* preconnecter)
180 {
181 if (shouldPreconnect()) {
182 preconnectHost(preconnecter, predictedBaseURL);
183 return nullptr;
184 }
171 if (!shouldPreload() || !m_matchedMediaAttribute) 185 if (!shouldPreload() || !m_matchedMediaAttribute)
172 return nullptr; 186 return nullptr;
173 187
174 TextPosition position = TextPosition(source.currentLine(), source.curren tColumn()); 188 TextPosition position = TextPosition(source.currentLine(), source.curren tColumn());
175 FetchRequest::ResourceWidth resourceWidth; 189 FetchRequest::ResourceWidth resourceWidth;
176 if (m_sourceSizeSet && m_srcsetImageCandidate.resourceWidth() != Uniniti alizedDescriptor) { 190 if (m_sourceSizeSet && m_srcsetImageCandidate.resourceWidth() != Uniniti alizedDescriptor) {
177 resourceWidth.width = m_sourceSize; 191 resourceWidth.width = m_sourceSize;
178 resourceWidth.isSet = true; 192 resourceWidth.isSet = true;
179 } 193 }
180 OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_t agImpl), position, m_urlToLoad, predictedBaseURL, resourceType(), resourceWidth, clientHintsPreferences); 194 OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_t agImpl), position, m_urlToLoad, predictedBaseURL, resourceType(), resourceWidth, clientHintsPreferences);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 } 236 }
223 } 237 }
224 238
225 template<typename NameType> 239 template<typename NameType>
226 void processLinkAttribute(const NameType& attributeName, const String& attri buteValue) 240 void processLinkAttribute(const NameType& attributeName, const String& attri buteValue)
227 { 241 {
228 // FIXME - Don't set rel/media/crossorigin multiple times. 242 // FIXME - Don't set rel/media/crossorigin multiple times.
229 if (match(attributeName, hrefAttr)) 243 if (match(attributeName, hrefAttr))
230 setUrlToLoad(attributeValue, DisallowURLReplacement); 244 setUrlToLoad(attributeValue, DisallowURLReplacement);
231 else if (match(attributeName, relAttr)) 245 else if (match(attributeName, relAttr))
232 m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue); 246 checkRelAttribute(attributeValue, m_linkIsStyleSheet, m_linkIsPrecon nect);
233 else if (match(attributeName, mediaAttr)) 247 else if (match(attributeName, mediaAttr))
234 m_matchedMediaAttribute = mediaAttributeMatches(*m_mediaValues, attr ibuteValue); 248 m_matchedMediaAttribute = mediaAttributeMatches(*m_mediaValues, attr ibuteValue);
235 else if (match(attributeName, crossoriginAttr)) 249 else if (match(attributeName, crossoriginAttr))
236 setCrossOriginAllowed(attributeValue); 250 setCrossOriginAllowed(attributeValue);
237 } 251 }
238 252
239 template<typename NameType> 253 template<typename NameType>
240 void processInputAttribute(const NameType& attributeName, const String& attr ibuteValue) 254 void processInputAttribute(const NameType& attributeName, const String& attr ibuteValue)
241 { 255 {
242 // FIXME - Don't set type multiple times. 256 // FIXME - Don't set type multiple times.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 else if (match(m_tagImpl, linkTag)) 298 else if (match(m_tagImpl, linkTag))
285 processLinkAttribute(attributeName, attributeValue); 299 processLinkAttribute(attributeName, attributeValue);
286 else if (match(m_tagImpl, inputTag)) 300 else if (match(m_tagImpl, inputTag))
287 processInputAttribute(attributeName, attributeValue); 301 processInputAttribute(attributeName, attributeValue);
288 else if (match(m_tagImpl, sourceTag)) 302 else if (match(m_tagImpl, sourceTag))
289 processSourceAttribute(attributeName, attributeValue); 303 processSourceAttribute(attributeName, attributeValue);
290 else if (match(m_tagImpl, videoTag)) 304 else if (match(m_tagImpl, videoTag))
291 processVideoAttribute(attributeName, attributeValue); 305 processVideoAttribute(attributeName, attributeValue);
292 } 306 }
293 307
294 static bool relAttributeIsStyleSheet(const String& attributeValue) 308 static void checkRelAttribute(const String& attributeValue, bool& isStyleShe et, bool& isPreconnect)
295 { 309 {
296 LinkRelAttribute rel(attributeValue); 310 LinkRelAttribute rel(attributeValue);
297 return rel.isStyleSheet() && !rel.isAlternate() && rel.iconType() == Inv alidIcon && !rel.isDNSPrefetch(); 311 isStyleSheet = rel.isStyleSheet() && !rel.isAlternate() && rel.iconType( ) == InvalidIcon && !rel.isDNSPrefetch();
Mike West 2015/06/02 11:18:33 Is this used anywhere else? I'd rather see it inli
312 isPreconnect = rel.isPreconnect();
298 } 313 }
299 314
300 void setUrlToLoad(const String& value, URLReplacement replacement) 315 void setUrlToLoad(const String& value, URLReplacement replacement)
301 { 316 {
302 // We only respect the first src/href, per HTML5: 317 // We only respect the first src/href, per HTML5:
303 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenizat ion.html#attribute-name-state 318 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenizat ion.html#attribute-name-state
304 if (replacement == DisallowURLReplacement && !m_urlToLoad.isEmpty()) 319 if (replacement == DisallowURLReplacement && !m_urlToLoad.isEmpty())
305 return; 320 return;
306 String url = stripLeadingAndTrailingHTMLSpaces(value); 321 String url = stripLeadingAndTrailingHTMLSpaces(value);
307 if (url.isEmpty()) 322 if (url.isEmpty())
(...skipping 14 matching lines...) Expand all
322 if (match(m_tagImpl, scriptTag)) 337 if (match(m_tagImpl, scriptTag))
323 return Resource::Script; 338 return Resource::Script;
324 if (match(m_tagImpl, imgTag) || match(m_tagImpl, videoTag) || (match(m_t agImpl, inputTag) && m_inputIsImage)) 339 if (match(m_tagImpl, imgTag) || match(m_tagImpl, videoTag) || (match(m_t agImpl, inputTag) && m_inputIsImage))
325 return Resource::Image; 340 return Resource::Image;
326 if (match(m_tagImpl, linkTag) && m_linkIsStyleSheet) 341 if (match(m_tagImpl, linkTag) && m_linkIsStyleSheet)
327 return Resource::CSSStyleSheet; 342 return Resource::CSSStyleSheet;
328 ASSERT_NOT_REACHED(); 343 ASSERT_NOT_REACHED();
329 return Resource::Raw; 344 return Resource::Raw;
330 } 345 }
331 346
347 bool shouldPreconnect() const
348 {
349 return (match(m_tagImpl, linkTag) && m_linkIsPreconnect && !m_urlToLoad. isEmpty());
Mike West 2015/06/02 11:18:33 Nit: Drop the outer ().
350 }
351
332 bool shouldPreload() const 352 bool shouldPreload() const
333 { 353 {
334 if (m_urlToLoad.isEmpty()) 354 if (m_urlToLoad.isEmpty())
335 return false; 355 return false;
336 if (match(m_tagImpl, linkTag) && !m_linkIsStyleSheet) 356 if (match(m_tagImpl, linkTag) && !m_linkIsStyleSheet)
337 return false; 357 return false;
338 if (match(m_tagImpl, inputTag) && !m_inputIsImage) 358 if (match(m_tagImpl, inputTag) && !m_inputIsImage)
339 return false; 359 return false;
340 return true; 360 return true;
341 } 361 }
(...skipping 25 matching lines...) Expand all
367 bool defer() const 387 bool defer() const
368 { 388 {
369 return m_defer; 389 return m_defer;
370 } 390 }
371 391
372 const StringImpl* m_tagImpl; 392 const StringImpl* m_tagImpl;
373 String m_urlToLoad; 393 String m_urlToLoad;
374 ImageCandidate m_srcsetImageCandidate; 394 ImageCandidate m_srcsetImageCandidate;
375 String m_charset; 395 String m_charset;
376 bool m_linkIsStyleSheet; 396 bool m_linkIsStyleSheet;
397 bool m_linkIsPreconnect;
377 bool m_matchedMediaAttribute; 398 bool m_matchedMediaAttribute;
378 bool m_inputIsImage; 399 bool m_inputIsImage;
379 String m_imgSrcUrl; 400 String m_imgSrcUrl;
380 String m_srcsetAttributeValue; 401 String m_srcsetAttributeValue;
381 float m_sourceSize; 402 float m_sourceSize;
382 bool m_sourceSizeSet; 403 bool m_sourceSizeSet;
383 bool m_isCORSEnabled; 404 bool m_isCORSEnabled;
384 FetchRequest::DeferOption m_defer; 405 FetchRequest::DeferOption m_defer;
385 StoredCredentials m_allowCredentials; 406 StoredCredentials m_allowCredentials;
386 RefPtr<MediaValues> m_mediaValues; 407 RefPtr<MediaValues> m_mediaValues;
387 }; 408 };
388 409
389 TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL, PassOwnPtr<Cac hedDocumentParameters> documentParameters) 410 TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL, PassOwnPtr<Cac hedDocumentParameters> documentParameters, PassOwnPtr<PreconnecterHost> preconne cter)
390 : m_documentURL(documentURL) 411 : m_documentURL(documentURL)
391 , m_inStyle(false) 412 , m_inStyle(false)
392 , m_inPicture(false) 413 , m_inPicture(false)
393 , m_isAppCacheEnabled(false) 414 , m_isAppCacheEnabled(false)
394 , m_isCSPEnabled(false) 415 , m_isCSPEnabled(false)
395 , m_templateCount(0) 416 , m_templateCount(0)
396 , m_documentParameters(documentParameters) 417 , m_documentParameters(documentParameters)
418 , m_preconnecter(preconnecter)
397 { 419 {
398 ASSERT(m_documentParameters.get()); 420 ASSERT(m_documentParameters.get());
399 ASSERT(m_documentParameters->mediaValues.get()); 421 ASSERT(m_documentParameters->mediaValues.get());
400 ASSERT(m_documentParameters->mediaValues->isCached()); 422 ASSERT(m_documentParameters->mediaValues->isCached());
401 } 423 }
402 424
403 TokenPreloadScanner::~TokenPreloadScanner() 425 TokenPreloadScanner::~TokenPreloadScanner()
404 { 426 {
405 } 427 }
406 428
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 if (match(tagImpl, pictureTag)) { 549 if (match(tagImpl, pictureTag)) {
528 m_inPicture = true; 550 m_inPicture = true;
529 m_pictureSourceURL = String(); 551 m_pictureSourceURL = String();
530 return; 552 return;
531 } 553 }
532 554
533 StartTagScanner scanner(tagImpl, m_documentParameters->mediaValues); 555 StartTagScanner scanner(tagImpl, m_documentParameters->mediaValues);
534 scanner.processAttributes(token.attributes()); 556 scanner.processAttributes(token.attributes());
535 if (m_inPicture) 557 if (m_inPicture)
536 scanner.handlePictureSourceURL(m_pictureSourceURL); 558 scanner.handlePictureSourceURL(m_pictureSourceURL);
537 OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predicte dBaseElementURL, source, m_clientHintsPreferences); 559 OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predicte dBaseElementURL, source, m_clientHintsPreferences, m_preconnecter.get());
538 if (request) 560 if (request)
539 requests.append(request.release()); 561 requests.append(request.release());
540 return; 562 return;
541 } 563 }
542 default: { 564 default: {
543 return; 565 return;
544 } 566 }
545 } 567 }
546 } 568 }
547 569
548 template<typename Token> 570 template<typename Token>
549 void TokenPreloadScanner::updatePredictedBaseURL(const Token& token) 571 void TokenPreloadScanner::updatePredictedBaseURL(const Token& token)
550 { 572 {
551 ASSERT(m_predictedBaseElementURL.isEmpty()); 573 ASSERT(m_predictedBaseElementURL.isEmpty());
552 if (const typename Token::Attribute* hrefAttribute = token.getAttributeItem( hrefAttr)) { 574 if (const typename Token::Attribute* hrefAttribute = token.getAttributeItem( hrefAttr)) {
553 KURL url(m_documentURL, stripLeadingAndTrailingHTMLSpaces(hrefAttribute- >value)); 575 KURL url(m_documentURL, stripLeadingAndTrailingHTMLSpaces(hrefAttribute- >value));
554 m_predictedBaseElementURL = url.isValid() ? url.copy() : KURL(); 576 m_predictedBaseElementURL = url.isValid() ? url.copy() : KURL();
555 } 577 }
556 } 578 }
557 579
558 HTMLPreloadScanner::HTMLPreloadScanner(const HTMLParserOptions& options, const K URL& documentURL, PassOwnPtr<CachedDocumentParameters> documentParameters) 580 HTMLPreloadScanner::HTMLPreloadScanner(const HTMLParserOptions& options, const K URL& documentURL, PassOwnPtr<CachedDocumentParameters> documentParameters, PassO wnPtr<PreconnecterHost> preconnecter)
559 : m_scanner(documentURL, documentParameters) 581 : m_scanner(documentURL, documentParameters, preconnecter)
560 , m_tokenizer(HTMLTokenizer::create(options)) 582 , m_tokenizer(HTMLTokenizer::create(options))
561 { 583 {
562 } 584 }
563 585
564 HTMLPreloadScanner::~HTMLPreloadScanner() 586 HTMLPreloadScanner::~HTMLPreloadScanner()
565 { 587 {
566 } 588 }
567 589
568 void HTMLPreloadScanner::appendToEnd(const SegmentedString& source) 590 void HTMLPreloadScanner::appendToEnd(const SegmentedString& source)
569 { 591 {
(...skipping 30 matching lines...) Expand all
600 mediaValues = givenMediaValues; 622 mediaValues = givenMediaValues;
601 else 623 else
602 mediaValues = MediaValuesCached::create(*document); 624 mediaValues = MediaValuesCached::create(*document);
603 ASSERT(mediaValues->isSafeToSendToAnotherThread()); 625 ASSERT(mediaValues->isSafeToSendToAnotherThread());
604 defaultViewportMinWidth = document->viewportDefaultMinWidth(); 626 defaultViewportMinWidth = document->viewportDefaultMinWidth();
605 viewportMetaZeroValuesQuirk = document->settings() && document->settings()-> viewportMetaZeroValuesQuirk(); 627 viewportMetaZeroValuesQuirk = document->settings() && document->settings()-> viewportMetaZeroValuesQuirk();
606 viewportMetaEnabled = document->settings() && document->settings()->viewport MetaEnabled(); 628 viewportMetaEnabled = document->settings() && document->settings()->viewport MetaEnabled();
607 } 629 }
608 630
609 } 631 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698