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

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

Issue 265763010: Add preloader support for picture based source selection (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Modified fixmes Created 6 years, 7 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
« no previous file with comments | « Source/core/html/parser/HTMLPreloadScanner.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 return mediaQueryEvaluator.eval(mediaQueries.get()); 101 return mediaQueryEvaluator.eval(mediaQueries.get());
102 } 102 }
103 103
104 class TokenPreloadScanner::StartTagScanner { 104 class TokenPreloadScanner::StartTagScanner {
105 public: 105 public:
106 StartTagScanner(const StringImpl* tagImpl, PassRefPtr<MediaValues> mediaValu es) 106 StartTagScanner(const StringImpl* tagImpl, PassRefPtr<MediaValues> mediaValu es)
107 : m_tagImpl(tagImpl) 107 : m_tagImpl(tagImpl)
108 , m_linkIsStyleSheet(false) 108 , m_linkIsStyleSheet(false)
109 , m_matchedMediaAttribute(true) 109 , m_matchedMediaAttribute(true)
110 , m_inputIsImage(false) 110 , m_inputIsImage(false)
111 , m_imgSourceSize(0) 111 , m_sourceSize(0)
112 , m_sourceSizeSet(false) 112 , m_sourceSizeSet(false)
113 , m_isCORSEnabled(false) 113 , m_isCORSEnabled(false)
114 , m_allowCredentials(DoNotAllowStoredCredentials) 114 , m_allowCredentials(DoNotAllowStoredCredentials)
115 , m_mediaValues(mediaValues) 115 , m_mediaValues(mediaValues)
116 { 116 {
117 if (!match(m_tagImpl, imgTag) 117 if (match(m_tagImpl, imgTag)
118 && !match(m_tagImpl, inputTag) 118 || match(m_tagImpl, sourceTag)) {
119 if (RuntimeEnabledFeatures::pictureSizesEnabled())
120 m_sourceSize = SizesAttributeParser::findEffectiveSize(String(), m_mediaValues);
121 return;
122 }
123 if ( !match(m_tagImpl, inputTag)
119 && !match(m_tagImpl, linkTag) 124 && !match(m_tagImpl, linkTag)
120 && !match(m_tagImpl, scriptTag)) 125 && !match(m_tagImpl, scriptTag))
121 m_tagImpl = 0; 126 m_tagImpl = 0;
122 if (RuntimeEnabledFeatures::pictureSizesEnabled())
123 m_imgSourceSize = SizesAttributeParser::findEffectiveSize(String(), m_mediaValues);
124 } 127 }
125 128
126 enum URLReplacement { 129 enum URLReplacement {
127 AllowURLReplacement, 130 AllowURLReplacement,
128 DisallowURLReplacement 131 DisallowURLReplacement
129 }; 132 };
130 133
131 void processAttributes(const HTMLToken::AttributeList& attributes) 134 void processAttributes(const HTMLToken::AttributeList& attributes)
132 { 135 {
133 ASSERT(isMainThread()); 136 ASSERT(isMainThread());
134 if (!m_tagImpl) 137 if (!m_tagImpl)
135 return; 138 return;
136 for (HTMLToken::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) { 139 for (HTMLToken::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) {
137 AtomicString attributeName(iter->name); 140 AtomicString attributeName(iter->name);
138 String attributeValue = StringImpl::create8BitIfPossible(iter->value ); 141 String attributeValue = StringImpl::create8BitIfPossible(iter->value );
139 processAttribute(attributeName, attributeValue); 142 processAttribute(attributeName, attributeValue);
140 } 143 }
141 } 144 }
142 145
143 void processAttributes(const Vector<CompactHTMLToken::Attribute>& attributes ) 146 void processAttributes(const Vector<CompactHTMLToken::Attribute>& attributes )
144 { 147 {
145 if (!m_tagImpl) 148 if (!m_tagImpl)
146 return; 149 return;
147 for (Vector<CompactHTMLToken::Attribute>::const_iterator iter = attribut es.begin(); iter != attributes.end(); ++iter) 150 for (Vector<CompactHTMLToken::Attribute>::const_iterator iter = attribut es.begin(); iter != attributes.end(); ++iter)
148 processAttribute(iter->name, iter->value); 151 processAttribute(iter->name, iter->value);
149 } 152 }
150 153
154 void handlePictureSourceURL(String& sourceURL)
155 {
156 if (match(m_tagImpl, sourceTag) && m_matchedMediaAttribute && sourceURL. isEmpty())
157 sourceURL = m_srcsetImageCandidate.toString();
158 else if (match(m_tagImpl, imgTag) && !sourceURL.isEmpty())
159 setUrlToLoad(sourceURL, AllowURLReplacement);
160 }
161
151 PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL , const SegmentedString& source) 162 PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL , const SegmentedString& source)
152 { 163 {
153 if (!shouldPreload() || !m_matchedMediaAttribute) 164 if (!shouldPreload() || !m_matchedMediaAttribute)
154 return nullptr; 165 return nullptr;
155 166
156 TRACE_EVENT_INSTANT1("net", "PreloadRequest", "url", m_urlToLoad.ascii() ); 167 TRACE_EVENT_INSTANT1("net", "PreloadRequest", "url", m_urlToLoad.ascii() );
157 TextPosition position = TextPosition(source.currentLine(), source.curren tColumn()); 168 TextPosition position = TextPosition(source.currentLine(), source.curren tColumn());
158 OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_t agImpl), position, m_urlToLoad, predictedBaseURL, resourceType()); 169 OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_t agImpl), position, m_urlToLoad, predictedBaseURL, resourceType());
159 if (isCORSEnabled()) 170 if (isCORSEnabled())
160 request->setCrossOriginEnabled(allowStoredCredentials()); 171 request->setCrossOriginEnabled(allowStoredCredentials());
161 request->setCharset(charset()); 172 request->setCharset(charset());
162 return request.release(); 173 return request.release();
163 } 174 }
164 175
165 private: 176 private:
166 template<typename NameType> 177 template<typename NameType>
178 void processScriptAttribute(const NameType& attributeName, const String& att ributeValue)
179 {
180 // FIXME - Don't set crossorigin multiple times.
181 if (match(attributeName, srcAttr))
182 setUrlToLoad(attributeValue, DisallowURLReplacement);
183 else if (match(attributeName, crossoriginAttr))
184 setCrossOriginAllowed(attributeValue);
185 }
186
187 template<typename NameType>
188 void processImgAttribute(const NameType& attributeName, const String& attrib uteValue)
189 {
190 if (match(attributeName, srcAttr) && m_imgSrcUrl.isNull()) {
191 m_imgSrcUrl = attributeValue;
192 setUrlToLoad(bestFitSourceForImageAttributes(m_mediaValues->devicePi xelRatio(), m_sourceSize, attributeValue, m_srcsetImageCandidate), AllowURLRepla cement);
193 } else if (match(attributeName, crossoriginAttr)) {
194 setCrossOriginAllowed(attributeValue);
195 } else if (match(attributeName, srcsetAttr) && m_srcsetImageCandidate.is Empty()) {
196 m_srcsetAttributeValue = attributeValue;
197 m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_mediaValu es->devicePixelRatio(), m_sourceSize, attributeValue);
198 setUrlToLoad(bestFitSourceForImageAttributes(m_mediaValues->devicePi xelRatio(), m_sourceSize, m_imgSrcUrl, m_srcsetImageCandidate), AllowURLReplacem ent);
199 } else if (RuntimeEnabledFeatures::pictureSizesEnabled() && match(attrib uteName, sizesAttr) && !m_sourceSizeSet) {
200 m_sourceSize = SizesAttributeParser::findEffectiveSize(attributeValu e, m_mediaValues);
201 m_sourceSizeSet = true;
202 if (!m_srcsetImageCandidate.isEmpty()) {
203 m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_media Values->devicePixelRatio(), m_sourceSize, m_srcsetAttributeValue);
204 setUrlToLoad(bestFitSourceForImageAttributes(m_mediaValues->devi cePixelRatio(), m_sourceSize, m_imgSrcUrl, m_srcsetImageCandidate), AllowURLRepl acement);
205 }
206 }
207 }
208
209 template<typename NameType>
210 void processLinkAttribute(const NameType& attributeName, const String& attri buteValue)
211 {
212 // FIXME - Don't set rel/media/crossorigin multiple times.
213 if (match(attributeName, hrefAttr))
214 setUrlToLoad(attributeValue, DisallowURLReplacement);
215 else if (match(attributeName, relAttr))
216 m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue);
217 else if (match(attributeName, mediaAttr))
218 m_matchedMediaAttribute = mediaAttributeMatches(*m_mediaValues, attr ibuteValue);
219 else if (match(attributeName, crossoriginAttr))
220 setCrossOriginAllowed(attributeValue);
221 }
222
223 template<typename NameType>
224 void processInputAttribute(const NameType& attributeName, const String& attr ibuteValue)
225 {
226 // FIXME - Don't set type multiple times.
227 if (match(attributeName, srcAttr))
228 setUrlToLoad(attributeValue, DisallowURLReplacement);
229 else if (match(attributeName, typeAttr))
230 m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeNames::i mage);
231 }
232
233 template<typename NameType>
234 void processSourceAttribute(const NameType& attributeName, const String& att ributeValue)
235 {
236 if (!RuntimeEnabledFeatures::pictureEnabled())
237 return;
238 if (match(attributeName, srcsetAttr) && m_srcsetImageCandidate.isEmpty() ) {
239 m_srcsetAttributeValue = attributeValue;
240 m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_mediaValu es->devicePixelRatio(), m_sourceSize, attributeValue);
241 } else if (match(attributeName, sizesAttr) && !m_sourceSizeSet) {
242 m_sourceSize = SizesAttributeParser::findEffectiveSize(attributeValu e, m_mediaValues);
243 m_sourceSizeSet = true;
244 if (!m_srcsetImageCandidate.isEmpty()) {
245 m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_media Values->devicePixelRatio(), m_sourceSize, m_srcsetAttributeValue);
246 }
247 } else if (match(attributeName, mediaAttr)) {
248 // FIXME - Don't match media multiple times.
249 m_matchedMediaAttribute = mediaAttributeMatches(*m_mediaValues, attr ibuteValue);
250 }
251
252 }
253
254 template<typename NameType>
167 void processAttribute(const NameType& attributeName, const String& attribute Value) 255 void processAttribute(const NameType& attributeName, const String& attribute Value)
168 { 256 {
169 if (match(attributeName, charsetAttr)) 257 if (match(attributeName, charsetAttr))
170 m_charset = attributeValue; 258 m_charset = attributeValue;
171 259
172 if (match(m_tagImpl, scriptTag)) { 260 if (match(m_tagImpl, scriptTag))
173 if (match(attributeName, srcAttr)) 261 processScriptAttribute(attributeName, attributeValue);
174 setUrlToLoad(attributeValue, DisallowURLReplacement); 262 else if (match(m_tagImpl, imgTag))
175 else if (match(attributeName, crossoriginAttr)) 263 processImgAttribute(attributeName, attributeValue);
176 setCrossOriginAllowed(attributeValue); 264 else if (match(m_tagImpl, linkTag))
177 } else if (match(m_tagImpl, imgTag)) { 265 processLinkAttribute(attributeName, attributeValue);
178 if (match(attributeName, srcAttr) && m_imgSrcUrl.isNull()) { 266 else if (match(m_tagImpl, inputTag))
179 m_imgSrcUrl = attributeValue; 267 processInputAttribute(attributeName, attributeValue);
180 setUrlToLoad(bestFitSourceForImageAttributes(m_mediaValues->devi cePixelRatio(), m_imgSourceSize, attributeValue, m_srcsetImageCandidate), AllowU RLReplacement); 268 else if (match(m_tagImpl, sourceTag))
181 } else if (match(attributeName, crossoriginAttr)) { 269 processSourceAttribute(attributeName, attributeValue);
182 setCrossOriginAllowed(attributeValue);
183 } else if (match(attributeName, srcsetAttr) && m_srcsetImageCandidat e.isEmpty()) {
184 m_imgSrcsetAttributeValue = attributeValue;
185 m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_media Values->devicePixelRatio(), m_imgSourceSize, attributeValue);
186 setUrlToLoad(bestFitSourceForImageAttributes(m_mediaValues->devi cePixelRatio(), m_imgSourceSize, m_imgSrcUrl, m_srcsetImageCandidate), AllowURLR eplacement);
187 } else if (RuntimeEnabledFeatures::pictureSizesEnabled() && match(at tributeName, sizesAttr) && !m_sourceSizeSet) {
188 m_imgSourceSize = SizesAttributeParser::findEffectiveSize(attrib uteValue, m_mediaValues);
189 m_sourceSizeSet = true;
190 if (!m_srcsetImageCandidate.isEmpty()) {
191 m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_m ediaValues->devicePixelRatio(), m_imgSourceSize, m_imgSrcsetAttributeValue);
192 setUrlToLoad(bestFitSourceForImageAttributes(m_mediaValues-> devicePixelRatio(), m_imgSourceSize, m_imgSrcUrl, m_srcsetImageCandidate), Allow URLReplacement);
193 }
194 }
195 } else if (match(m_tagImpl, linkTag)) {
196 if (match(attributeName, hrefAttr))
197 setUrlToLoad(attributeValue, DisallowURLReplacement);
198 else if (match(attributeName, relAttr))
199 m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue);
200 else if (match(attributeName, mediaAttr))
201 m_matchedMediaAttribute = mediaAttributeMatches(*m_mediaValues, attributeValue);
202 else if (match(attributeName, crossoriginAttr))
203 setCrossOriginAllowed(attributeValue);
204 } else if (match(m_tagImpl, inputTag)) {
205 if (match(attributeName, srcAttr))
206 setUrlToLoad(attributeValue, DisallowURLReplacement);
207 else if (match(attributeName, typeAttr))
208 m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeName s::image);
209 }
210 } 270 }
211 271
212 static bool relAttributeIsStyleSheet(const String& attributeValue) 272 static bool relAttributeIsStyleSheet(const String& attributeValue)
213 { 273 {
214 LinkRelAttribute rel(attributeValue); 274 LinkRelAttribute rel(attributeValue);
215 return rel.isStyleSheet() && !rel.isAlternate() && rel.iconType() == Inv alidIcon && !rel.isDNSPrefetch(); 275 return rel.isStyleSheet() && !rel.isAlternate() && rel.iconType() == Inv alidIcon && !rel.isDNSPrefetch();
216 } 276 }
217 277
218 void setUrlToLoad(const String& value, URLReplacement replacement) 278 void setUrlToLoad(const String& value, URLReplacement replacement)
219 { 279 {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 } 338 }
279 339
280 const StringImpl* m_tagImpl; 340 const StringImpl* m_tagImpl;
281 String m_urlToLoad; 341 String m_urlToLoad;
282 ImageCandidate m_srcsetImageCandidate; 342 ImageCandidate m_srcsetImageCandidate;
283 String m_charset; 343 String m_charset;
284 bool m_linkIsStyleSheet; 344 bool m_linkIsStyleSheet;
285 bool m_matchedMediaAttribute; 345 bool m_matchedMediaAttribute;
286 bool m_inputIsImage; 346 bool m_inputIsImage;
287 String m_imgSrcUrl; 347 String m_imgSrcUrl;
288 String m_imgSrcsetAttributeValue; 348 String m_srcsetAttributeValue;
289 unsigned m_imgSourceSize; 349 unsigned m_sourceSize;
290 bool m_sourceSizeSet; 350 bool m_sourceSizeSet;
291 bool m_isCORSEnabled; 351 bool m_isCORSEnabled;
292 StoredCredentials m_allowCredentials; 352 StoredCredentials m_allowCredentials;
293 RefPtr<MediaValues> m_mediaValues; 353 RefPtr<MediaValues> m_mediaValues;
294 }; 354 };
295 355
296 TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL, PassRefPtr<Med iaValues> mediaValues) 356 TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL, PassRefPtr<Med iaValues> mediaValues)
297 : m_documentURL(documentURL) 357 : m_documentURL(documentURL)
298 , m_inStyle(false) 358 , m_inStyle(false)
359 , m_inPicture(false)
299 , m_templateCount(0) 360 , m_templateCount(0)
300 , m_mediaValues(mediaValues) 361 , m_mediaValues(mediaValues)
301 { 362 {
302 } 363 }
303 364
304 TokenPreloadScanner::~TokenPreloadScanner() 365 TokenPreloadScanner::~TokenPreloadScanner()
305 { 366 {
306 } 367 }
307 368
308 TokenPreloadScannerCheckpoint TokenPreloadScanner::createCheckpoint() 369 TokenPreloadScannerCheckpoint TokenPreloadScanner::createCheckpoint()
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 const StringImpl* tagImpl = tagImplFor(token.data()); 408 const StringImpl* tagImpl = tagImplFor(token.data());
348 if (match(tagImpl, templateTag)) { 409 if (match(tagImpl, templateTag)) {
349 if (m_templateCount) 410 if (m_templateCount)
350 --m_templateCount; 411 --m_templateCount;
351 return; 412 return;
352 } 413 }
353 if (match(tagImpl, styleTag)) { 414 if (match(tagImpl, styleTag)) {
354 if (m_inStyle) 415 if (m_inStyle)
355 m_cssScanner.reset(); 416 m_cssScanner.reset();
356 m_inStyle = false; 417 m_inStyle = false;
418 return;
357 } 419 }
420 if (match(tagImpl, pictureTag))
421 m_inPicture = false;
358 return; 422 return;
359 } 423 }
360 case HTMLToken::StartTag: { 424 case HTMLToken::StartTag: {
361 if (m_templateCount) 425 if (m_templateCount)
362 return; 426 return;
363 const StringImpl* tagImpl = tagImplFor(token.data()); 427 const StringImpl* tagImpl = tagImplFor(token.data());
364 if (match(tagImpl, templateTag)) { 428 if (match(tagImpl, templateTag)) {
365 ++m_templateCount; 429 ++m_templateCount;
366 return; 430 return;
367 } 431 }
368 if (match(tagImpl, styleTag)) { 432 if (match(tagImpl, styleTag)) {
369 m_inStyle = true; 433 m_inStyle = true;
370 return; 434 return;
371 } 435 }
372 if (match(tagImpl, baseTag)) { 436 if (match(tagImpl, baseTag)) {
373 // The first <base> element is the one that wins. 437 // The first <base> element is the one that wins.
374 if (!m_predictedBaseElementURL.isEmpty()) 438 if (!m_predictedBaseElementURL.isEmpty())
375 return; 439 return;
376 updatePredictedBaseURL(token); 440 updatePredictedBaseURL(token);
377 return; 441 return;
378 } 442 }
443 if (RuntimeEnabledFeatures::pictureEnabled() && (match(tagImpl, pictureT ag))) {
444 m_inPicture = true;
445 m_pictureSourceURL = String();
446 return;
447 }
379 448
380 StartTagScanner scanner(tagImpl, m_mediaValues); 449 StartTagScanner scanner(tagImpl, m_mediaValues);
381 scanner.processAttributes(token.attributes()); 450 scanner.processAttributes(token.attributes());
451 if (m_inPicture)
452 scanner.handlePictureSourceURL(m_pictureSourceURL);
382 OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predicte dBaseElementURL, source); 453 OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predicte dBaseElementURL, source);
383 if (request) 454 if (request)
384 requests.append(request.release()); 455 requests.append(request.release());
385 return; 456 return;
386 } 457 }
387 default: { 458 default: {
388 return; 459 return;
389 } 460 }
390 } 461 }
391 } 462 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 if (m_token.type() == HTMLToken::StartTag) 500 if (m_token.type() == HTMLToken::StartTag)
430 m_tokenizer->updateStateFor(attemptStaticStringCreation(m_token.name (), Likely8Bit)); 501 m_tokenizer->updateStateFor(attemptStaticStringCreation(m_token.name (), Likely8Bit));
431 m_scanner.scan(m_token, m_source, requests); 502 m_scanner.scan(m_token, m_source, requests);
432 m_token.clear(); 503 m_token.clear();
433 } 504 }
434 505
435 preloader->takeAndPreload(requests); 506 preloader->takeAndPreload(requests);
436 } 507 }
437 508
438 } 509 }
OLDNEW
« no previous file with comments | « Source/core/html/parser/HTMLPreloadScanner.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698