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

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

Issue 23861003: Enable srcset support in HTMLImageElement (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Enable srcset support in HTMLImageElement Created 7 years, 3 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 if (match(tagImpl, linkTag)) 83 if (match(tagImpl, linkTag))
84 return linkTag.localName(); 84 return linkTag.localName();
85 if (match(tagImpl, scriptTag)) 85 if (match(tagImpl, scriptTag))
86 return scriptTag.localName(); 86 return scriptTag.localName();
87 ASSERT_NOT_REACHED(); 87 ASSERT_NOT_REACHED();
88 return emptyString(); 88 return emptyString();
89 } 89 }
90 90
91 class TokenPreloadScanner::StartTagScanner { 91 class TokenPreloadScanner::StartTagScanner {
92 public: 92 public:
93 explicit StartTagScanner(const StringImpl* tagImpl) 93 explicit StartTagScanner(const StringImpl* tagImpl, float deviceScaleFactor = 1.0)
94 : m_tagImpl(tagImpl) 94 : m_tagImpl(tagImpl)
95 , m_linkIsStyleSheet(false) 95 , m_linkIsStyleSheet(false)
96 , m_inputIsImage(false) 96 , m_inputIsImage(false)
97 , m_deviceScaleFactor(deviceScaleFactor)
97 { 98 {
98 if (!match(m_tagImpl, imgTag) 99 if (!match(m_tagImpl, imgTag)
99 && !match(m_tagImpl, inputTag) 100 && !match(m_tagImpl, inputTag)
100 && !match(m_tagImpl, linkTag) 101 && !match(m_tagImpl, linkTag)
101 && !match(m_tagImpl, scriptTag)) 102 && !match(m_tagImpl, scriptTag))
102 m_tagImpl = 0; 103 m_tagImpl = 0;
103 } 104 }
104 105
105 void processAttributes(const HTMLToken::AttributeList& attributes) 106 void processAttributes(const HTMLToken::AttributeList& attributes)
106 { 107 {
107 ASSERT(isMainThread()); 108 ASSERT(isMainThread());
108 if (!m_tagImpl) 109 if (!m_tagImpl)
109 return; 110 return;
110 for (HTMLToken::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) { 111 for (HTMLToken::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) {
111 AtomicString attributeName(iter->name); 112 AtomicString attributeName(iter->name);
112 String attributeValue = StringImpl::create8BitIfPossible(iter->value ); 113 String attributeValue = StringImpl::create8BitIfPossible(iter->value );
113 processAttribute(attributeName, attributeValue); 114 processAttribute(attributeName, attributeValue);
114 } 115 }
116
117 // Resolve between src and srcSet if we have them.
118 if (!m_srcSetAttribute.isEmpty()) {
119 String srcMatchingScale = bestFitSourceForImageAttributes(m_deviceSc aleFactor, m_urlToLoad, m_srcSetAttribute);
120 setUrlToLoad(srcMatchingScale, true);
121 }
115 } 122 }
116 123
117 void processAttributes(const Vector<CompactHTMLToken::Attribute>& attributes ) 124 void processAttributes(const Vector<CompactHTMLToken::Attribute>& attributes )
118 { 125 {
119 if (!m_tagImpl) 126 if (!m_tagImpl)
120 return; 127 return;
121 for (Vector<CompactHTMLToken::Attribute>::const_iterator iter = attribut es.begin(); iter != attributes.end(); ++iter) 128 for (Vector<CompactHTMLToken::Attribute>::const_iterator iter = attribut es.begin(); iter != attributes.end(); ++iter)
122 processAttribute(iter->name, iter->value); 129 processAttribute(iter->name, iter->value);
130
131 // Resolve between src and srcSet if we have them.
132 if (!m_srcSetAttribute.isEmpty()) {
133 String srcMatchingScale = bestFitSourceForImageAttributes(m_deviceSc aleFactor, m_urlToLoad, m_srcSetAttribute);
134 setUrlToLoad(srcMatchingScale, true);
135 }
123 } 136 }
124 137
125 PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL , const SegmentedString& source) 138 PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL , const SegmentedString& source)
126 { 139 {
127 if (!shouldPreload()) 140 if (!shouldPreload())
128 return nullptr; 141 return nullptr;
129 142
130 TRACE_EVENT_INSTANT1("net", "PreloadRequest", "url", m_urlToLoad.ascii() ); 143 TRACE_EVENT_INSTANT1("net", "PreloadRequest", "url", m_urlToLoad.ascii() );
131 TextPosition position = TextPosition(source.currentLine(), source.curren tColumn()); 144 TextPosition position = TextPosition(source.currentLine(), source.curren tColumn());
132 OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_t agImpl), position, m_urlToLoad, predictedBaseURL, resourceType(), m_mediaAttribu te); 145 OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_t agImpl), position, m_urlToLoad, predictedBaseURL, resourceType(), m_mediaAttribu te);
(...skipping 28 matching lines...) Expand all
161 m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeName s::image()); 174 m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeName s::image());
162 } 175 }
163 } 176 }
164 177
165 static bool relAttributeIsStyleSheet(const String& attributeValue) 178 static bool relAttributeIsStyleSheet(const String& attributeValue)
166 { 179 {
167 LinkRelAttribute rel(attributeValue); 180 LinkRelAttribute rel(attributeValue);
168 return rel.isStyleSheet() && !rel.isAlternate() && rel.iconType() == Inv alidIcon && !rel.isDNSPrefetch(); 181 return rel.isStyleSheet() && !rel.isAlternate() && rel.iconType() == Inv alidIcon && !rel.isDNSPrefetch();
169 } 182 }
170 183
171 void setUrlToLoad(const String& attributeValue) 184 void setUrlToLoad(const String& value, bool allowReplacement = false)
172 { 185 {
173 // We only respect the first src/href, per HTML5: 186 // We only respect the first src/href, per HTML5:
174 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenizat ion.html#attribute-name-state 187 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenizat ion.html#attribute-name-state
175 if (!m_urlToLoad.isEmpty()) 188 if (!allowReplacement && !m_urlToLoad.isEmpty())
176 return; 189 return;
177 m_urlToLoad = stripLeadingAndTrailingHTMLSpaces(attributeValue); 190 String url = stripLeadingAndTrailingHTMLSpaces(value);
191 if (url.isEmpty())
192 return;
193 m_urlToLoad = url;
178 } 194 }
179 195
180 const String& charset() const 196 const String& charset() const
181 { 197 {
182 // FIXME: Its not clear that this if is needed, the loader probably igno res charset for image requests anyway. 198 // FIXME: Its not clear that this if is needed, the loader probably igno res charset for image requests anyway.
183 if (match(m_tagImpl, imgTag)) 199 if (match(m_tagImpl, imgTag))
184 return emptyString(); 200 return emptyString();
185 return m_charset; 201 return m_charset;
186 } 202 }
187 203
(...skipping 20 matching lines...) Expand all
208 return true; 224 return true;
209 } 225 }
210 226
211 bool crossOriginModeAllowsCookies() 227 bool crossOriginModeAllowsCookies()
212 { 228 {
213 return m_crossOriginMode.isNull() || equalIgnoringCase(m_crossOriginMode , "use-credentials"); 229 return m_crossOriginMode.isNull() || equalIgnoringCase(m_crossOriginMode , "use-credentials");
214 } 230 }
215 231
216 const StringImpl* m_tagImpl; 232 const StringImpl* m_tagImpl;
217 String m_urlToLoad; 233 String m_urlToLoad;
234 String m_srcSetAttribute;
218 String m_charset; 235 String m_charset;
219 String m_crossOriginMode; 236 String m_crossOriginMode;
220 bool m_linkIsStyleSheet; 237 bool m_linkIsStyleSheet;
221 String m_mediaAttribute; 238 String m_mediaAttribute;
222 bool m_inputIsImage; 239 bool m_inputIsImage;
240 float m_deviceScaleFactor;
223 }; 241 };
224 242
225 TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL) 243 TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL, float deviceSc aleFactor)
226 : m_documentURL(documentURL) 244 : m_documentURL(documentURL)
227 , m_inStyle(false) 245 , m_inStyle(false)
246 , m_deviceScaleFactor(deviceScaleFactor)
228 , m_templateCount(0) 247 , m_templateCount(0)
229 { 248 {
230 } 249 }
231 250
232 TokenPreloadScanner::~TokenPreloadScanner() 251 TokenPreloadScanner::~TokenPreloadScanner()
233 { 252 {
234 } 253 }
235 254
236 TokenPreloadScannerCheckpoint TokenPreloadScanner::createCheckpoint() 255 TokenPreloadScannerCheckpoint TokenPreloadScanner::createCheckpoint()
237 { 256 {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 return; 317 return;
299 } 318 }
300 if (match(tagImpl, baseTag)) { 319 if (match(tagImpl, baseTag)) {
301 // The first <base> element is the one that wins. 320 // The first <base> element is the one that wins.
302 if (!m_predictedBaseElementURL.isEmpty()) 321 if (!m_predictedBaseElementURL.isEmpty())
303 return; 322 return;
304 updatePredictedBaseURL(token); 323 updatePredictedBaseURL(token);
305 return; 324 return;
306 } 325 }
307 326
308 StartTagScanner scanner(tagImpl); 327 StartTagScanner scanner(tagImpl, m_deviceScaleFactor);
309 scanner.processAttributes(token.attributes()); 328 scanner.processAttributes(token.attributes());
310 OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predicte dBaseElementURL, source); 329 OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predicte dBaseElementURL, source);
311 if (request) 330 if (request)
312 requests.append(request.release()); 331 requests.append(request.release());
313 return; 332 return;
314 } 333 }
315 default: { 334 default: {
316 return; 335 return;
317 } 336 }
318 } 337 }
319 } 338 }
320 339
321 template<typename Token> 340 template<typename Token>
322 void TokenPreloadScanner::updatePredictedBaseURL(const Token& token) 341 void TokenPreloadScanner::updatePredictedBaseURL(const Token& token)
323 { 342 {
324 ASSERT(m_predictedBaseElementURL.isEmpty()); 343 ASSERT(m_predictedBaseElementURL.isEmpty());
325 if (const typename Token::Attribute* hrefAttribute = token.getAttributeItem( hrefAttr)) 344 if (const typename Token::Attribute* hrefAttribute = token.getAttributeItem( hrefAttr))
326 m_predictedBaseElementURL = KURL(m_documentURL, stripLeadingAndTrailingH TMLSpaces(hrefAttribute->value)).copy(); 345 m_predictedBaseElementURL = KURL(m_documentURL, stripLeadingAndTrailingH TMLSpaces(hrefAttribute->value)).copy();
327 } 346 }
328 347
329 HTMLPreloadScanner::HTMLPreloadScanner(const HTMLParserOptions& options, const K URL& documentURL) 348 HTMLPreloadScanner::HTMLPreloadScanner(const HTMLParserOptions& options, const K URL& documentURL, float deviceScaleFactor)
330 : m_scanner(documentURL) 349 : m_scanner(documentURL, deviceScaleFactor)
331 , m_tokenizer(HTMLTokenizer::create(options)) 350 , m_tokenizer(HTMLTokenizer::create(options))
332 { 351 {
333 } 352 }
334 353
335 HTMLPreloadScanner::~HTMLPreloadScanner() 354 HTMLPreloadScanner::~HTMLPreloadScanner()
336 { 355 {
337 } 356 }
338 357
339 void HTMLPreloadScanner::appendToEnd(const SegmentedString& source) 358 void HTMLPreloadScanner::appendToEnd(const SegmentedString& source)
340 { 359 {
(...skipping 14 matching lines...) Expand all
355 if (m_token.type() == HTMLToken::StartTag) 374 if (m_token.type() == HTMLToken::StartTag)
356 m_tokenizer->updateStateFor(AtomicString(m_token.name())); 375 m_tokenizer->updateStateFor(AtomicString(m_token.name()));
357 m_scanner.scan(m_token, m_source, requests); 376 m_scanner.scan(m_token, m_source, requests);
358 m_token.clear(); 377 m_token.clear();
359 } 378 }
360 379
361 preloader->takeAndPreload(requests); 380 preloader->takeAndPreload(requests);
362 } 381 }
363 382
364 } 383 }
OLDNEW
« Source/core/html/parser/HTMLParserIdioms.cpp ('K') | « Source/core/html/parser/HTMLPreloadScanner.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698