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 11 matching lines...) Expand all Loading... | |
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 */ | 26 */ |
27 | 27 |
28 #include "config.h" | 28 #include "config.h" |
29 #include "core/html/parser/HTMLPreloadScanner.h" | 29 #include "core/html/parser/HTMLPreloadScanner.h" |
30 | 30 |
31 #include "HTMLNames.h" | 31 #include "HTMLNames.h" |
32 #include "RuntimeEnabledFeatures.h" | |
32 #include "core/html/InputTypeNames.h" | 33 #include "core/html/InputTypeNames.h" |
33 #include "core/html/LinkRelAttribute.h" | 34 #include "core/html/LinkRelAttribute.h" |
34 #include "core/html/parser/HTMLParserIdioms.h" | 35 #include "core/html/parser/HTMLParserIdioms.h" |
35 #include "core/html/parser/HTMLTokenizer.h" | 36 #include "core/html/parser/HTMLTokenizer.h" |
36 #include "core/platform/chromium/TraceEvent.h" | 37 #include "core/platform/chromium/TraceEvent.h" |
37 #include "wtf/MainThread.h" | 38 #include "wtf/MainThread.h" |
38 | 39 |
39 namespace WebCore { | 40 namespace WebCore { |
40 | 41 |
41 using namespace HTMLNames; | 42 using namespace HTMLNames; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
83 if (match(tagImpl, linkTag)) | 84 if (match(tagImpl, linkTag)) |
84 return linkTag.localName(); | 85 return linkTag.localName(); |
85 if (match(tagImpl, scriptTag)) | 86 if (match(tagImpl, scriptTag)) |
86 return scriptTag.localName(); | 87 return scriptTag.localName(); |
87 ASSERT_NOT_REACHED(); | 88 ASSERT_NOT_REACHED(); |
88 return emptyString(); | 89 return emptyString(); |
89 } | 90 } |
90 | 91 |
91 class TokenPreloadScanner::StartTagScanner { | 92 class TokenPreloadScanner::StartTagScanner { |
92 public: | 93 public: |
93 explicit StartTagScanner(const StringImpl* tagImpl) | 94 explicit StartTagScanner(const StringImpl* tagImpl, float deviceScaleFactor = 1.0) |
94 : m_tagImpl(tagImpl) | 95 : m_tagImpl(tagImpl) |
95 , m_linkIsStyleSheet(false) | 96 , m_linkIsStyleSheet(false) |
96 , m_inputIsImage(false) | 97 , m_inputIsImage(false) |
98 , m_deviceScaleFactor(deviceScaleFactor) | |
97 { | 99 { |
98 if (!match(m_tagImpl, imgTag) | 100 if (!match(m_tagImpl, imgTag) |
99 && !match(m_tagImpl, inputTag) | 101 && !match(m_tagImpl, inputTag) |
100 && !match(m_tagImpl, linkTag) | 102 && !match(m_tagImpl, linkTag) |
101 && !match(m_tagImpl, scriptTag)) | 103 && !match(m_tagImpl, scriptTag)) |
102 m_tagImpl = 0; | 104 m_tagImpl = 0; |
103 } | 105 } |
104 | 106 |
105 void processAttributes(const HTMLToken::AttributeList& attributes) | 107 void processAttributes(const HTMLToken::AttributeList& attributes) |
106 { | 108 { |
107 ASSERT(isMainThread()); | 109 ASSERT(isMainThread()); |
108 if (!m_tagImpl) | 110 if (!m_tagImpl) |
109 return; | 111 return; |
110 for (HTMLToken::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) { | 112 for (HTMLToken::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) { |
111 AtomicString attributeName(iter->name); | 113 AtomicString attributeName(iter->name); |
112 String attributeValue = StringImpl::create8BitIfPossible(iter->value ); | 114 String attributeValue = StringImpl::create8BitIfPossible(iter->value ); |
113 processAttribute(attributeName, attributeValue); | 115 processAttribute(attributeName, attributeValue); |
114 } | 116 } |
117 | |
118 // Resolve between src and srcSet if we have them. | |
119 if (!m_srcSetAttribute.isEmpty()) { | |
do-not-use
2013/09/12 08:23:53
Is it normal the one below is enabled at runtime b
Yoav Weiss
2013/09/12 09:30:20
No, it's not. Good catch! :)
| |
120 String srcMatchingScale = bestFitSourceForImageAttributes(m_deviceSc aleFactor, m_urlToLoad, m_srcSetAttribute); | |
121 setUrlToLoad(srcMatchingScale, true); | |
122 } | |
115 } | 123 } |
116 | 124 |
117 void processAttributes(const Vector<CompactHTMLToken::Attribute>& attributes ) | 125 void processAttributes(const Vector<CompactHTMLToken::Attribute>& attributes ) |
118 { | 126 { |
119 if (!m_tagImpl) | 127 if (!m_tagImpl) |
120 return; | 128 return; |
121 for (Vector<CompactHTMLToken::Attribute>::const_iterator iter = attribut es.begin(); iter != attributes.end(); ++iter) | 129 for (Vector<CompactHTMLToken::Attribute>::const_iterator iter = attribut es.begin(); iter != attributes.end(); ++iter) |
122 processAttribute(iter->name, iter->value); | 130 processAttribute(iter->name, iter->value); |
131 | |
132 // Resolve between src and srcSet if we have them. | |
133 if (RuntimeEnabledFeatures::srcsetEnabled() && !m_srcSetAttribute.isEmpt y()) { | |
134 String srcMatchingScale = bestFitSourceForImageAttributes(m_deviceSc aleFactor, m_urlToLoad, m_srcSetAttribute); | |
135 setUrlToLoad(srcMatchingScale, true); | |
136 } | |
123 } | 137 } |
124 | 138 |
125 PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL , const SegmentedString& source) | 139 PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL , const SegmentedString& source) |
126 { | 140 { |
127 if (!shouldPreload()) | 141 if (!shouldPreload()) |
128 return nullptr; | 142 return nullptr; |
129 | 143 |
130 TRACE_EVENT_INSTANT1("net", "PreloadRequest", "url", m_urlToLoad.ascii() ); | 144 TRACE_EVENT_INSTANT1("net", "PreloadRequest", "url", m_urlToLoad.ascii() ); |
131 TextPosition position = TextPosition(source.currentLine(), source.curren tColumn()); | 145 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); | 146 OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_t agImpl), position, m_urlToLoad, predictedBaseURL, resourceType(), m_mediaAttribu te); |
(...skipping 28 matching lines...) Expand all Loading... | |
161 m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeName s::image()); | 175 m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeName s::image()); |
162 } | 176 } |
163 } | 177 } |
164 | 178 |
165 static bool relAttributeIsStyleSheet(const String& attributeValue) | 179 static bool relAttributeIsStyleSheet(const String& attributeValue) |
166 { | 180 { |
167 LinkRelAttribute rel(attributeValue); | 181 LinkRelAttribute rel(attributeValue); |
168 return rel.isStyleSheet() && !rel.isAlternate() && rel.iconType() == Inv alidIcon && !rel.isDNSPrefetch(); | 182 return rel.isStyleSheet() && !rel.isAlternate() && rel.iconType() == Inv alidIcon && !rel.isDNSPrefetch(); |
169 } | 183 } |
170 | 184 |
171 void setUrlToLoad(const String& attributeValue) | 185 void setUrlToLoad(const String& value, bool allowReplacement = false) |
172 { | 186 { |
173 // We only respect the first src/href, per HTML5: | 187 // 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 | 188 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenizat ion.html#attribute-name-state |
175 if (!m_urlToLoad.isEmpty()) | 189 if (!allowReplacement && !m_urlToLoad.isEmpty()) |
176 return; | 190 return; |
177 m_urlToLoad = stripLeadingAndTrailingHTMLSpaces(attributeValue); | 191 String url = stripLeadingAndTrailingHTMLSpaces(value); |
192 if (url.isEmpty()) | |
193 return; | |
194 m_urlToLoad = url; | |
178 } | 195 } |
179 | 196 |
180 const String& charset() const | 197 const String& charset() const |
181 { | 198 { |
182 // FIXME: Its not clear that this if is needed, the loader probably igno res charset for image requests anyway. | 199 // 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)) | 200 if (match(m_tagImpl, imgTag)) |
184 return emptyString(); | 201 return emptyString(); |
185 return m_charset; | 202 return m_charset; |
186 } | 203 } |
187 | 204 |
(...skipping 20 matching lines...) Expand all Loading... | |
208 return true; | 225 return true; |
209 } | 226 } |
210 | 227 |
211 bool crossOriginModeAllowsCookies() | 228 bool crossOriginModeAllowsCookies() |
212 { | 229 { |
213 return m_crossOriginMode.isNull() || equalIgnoringCase(m_crossOriginMode , "use-credentials"); | 230 return m_crossOriginMode.isNull() || equalIgnoringCase(m_crossOriginMode , "use-credentials"); |
214 } | 231 } |
215 | 232 |
216 const StringImpl* m_tagImpl; | 233 const StringImpl* m_tagImpl; |
217 String m_urlToLoad; | 234 String m_urlToLoad; |
235 String m_srcSetAttribute; | |
218 String m_charset; | 236 String m_charset; |
219 String m_crossOriginMode; | 237 String m_crossOriginMode; |
220 bool m_linkIsStyleSheet; | 238 bool m_linkIsStyleSheet; |
221 String m_mediaAttribute; | 239 String m_mediaAttribute; |
222 bool m_inputIsImage; | 240 bool m_inputIsImage; |
241 float m_deviceScaleFactor; | |
223 }; | 242 }; |
224 | 243 |
225 TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL) | 244 TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL, float deviceSc aleFactor) |
226 : m_documentURL(documentURL) | 245 : m_documentURL(documentURL) |
227 , m_inStyle(false) | 246 , m_inStyle(false) |
247 , m_deviceScaleFactor(deviceScaleFactor) | |
228 , m_templateCount(0) | 248 , m_templateCount(0) |
229 { | 249 { |
230 } | 250 } |
231 | 251 |
232 TokenPreloadScanner::~TokenPreloadScanner() | 252 TokenPreloadScanner::~TokenPreloadScanner() |
233 { | 253 { |
234 } | 254 } |
235 | 255 |
236 TokenPreloadScannerCheckpoint TokenPreloadScanner::createCheckpoint() | 256 TokenPreloadScannerCheckpoint TokenPreloadScanner::createCheckpoint() |
237 { | 257 { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
298 return; | 318 return; |
299 } | 319 } |
300 if (match(tagImpl, baseTag)) { | 320 if (match(tagImpl, baseTag)) { |
301 // The first <base> element is the one that wins. | 321 // The first <base> element is the one that wins. |
302 if (!m_predictedBaseElementURL.isEmpty()) | 322 if (!m_predictedBaseElementURL.isEmpty()) |
303 return; | 323 return; |
304 updatePredictedBaseURL(token); | 324 updatePredictedBaseURL(token); |
305 return; | 325 return; |
306 } | 326 } |
307 | 327 |
308 StartTagScanner scanner(tagImpl); | 328 StartTagScanner scanner(tagImpl, m_deviceScaleFactor); |
309 scanner.processAttributes(token.attributes()); | 329 scanner.processAttributes(token.attributes()); |
310 OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predicte dBaseElementURL, source); | 330 OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predicte dBaseElementURL, source); |
311 if (request) | 331 if (request) |
312 requests.append(request.release()); | 332 requests.append(request.release()); |
313 return; | 333 return; |
314 } | 334 } |
315 default: { | 335 default: { |
316 return; | 336 return; |
317 } | 337 } |
318 } | 338 } |
319 } | 339 } |
320 | 340 |
321 template<typename Token> | 341 template<typename Token> |
322 void TokenPreloadScanner::updatePredictedBaseURL(const Token& token) | 342 void TokenPreloadScanner::updatePredictedBaseURL(const Token& token) |
323 { | 343 { |
324 ASSERT(m_predictedBaseElementURL.isEmpty()); | 344 ASSERT(m_predictedBaseElementURL.isEmpty()); |
325 if (const typename Token::Attribute* hrefAttribute = token.getAttributeItem( hrefAttr)) | 345 if (const typename Token::Attribute* hrefAttribute = token.getAttributeItem( hrefAttr)) |
326 m_predictedBaseElementURL = KURL(m_documentURL, stripLeadingAndTrailingH TMLSpaces(hrefAttribute->value)).copy(); | 346 m_predictedBaseElementURL = KURL(m_documentURL, stripLeadingAndTrailingH TMLSpaces(hrefAttribute->value)).copy(); |
327 } | 347 } |
328 | 348 |
329 HTMLPreloadScanner::HTMLPreloadScanner(const HTMLParserOptions& options, const K URL& documentURL) | 349 HTMLPreloadScanner::HTMLPreloadScanner(const HTMLParserOptions& options, const K URL& documentURL, float deviceScaleFactor) |
330 : m_scanner(documentURL) | 350 : m_scanner(documentURL, deviceScaleFactor) |
331 , m_tokenizer(HTMLTokenizer::create(options)) | 351 , m_tokenizer(HTMLTokenizer::create(options)) |
332 { | 352 { |
333 } | 353 } |
334 | 354 |
335 HTMLPreloadScanner::~HTMLPreloadScanner() | 355 HTMLPreloadScanner::~HTMLPreloadScanner() |
336 { | 356 { |
337 } | 357 } |
338 | 358 |
339 void HTMLPreloadScanner::appendToEnd(const SegmentedString& source) | 359 void HTMLPreloadScanner::appendToEnd(const SegmentedString& source) |
340 { | 360 { |
(...skipping 14 matching lines...) Expand all Loading... | |
355 if (m_token.type() == HTMLToken::StartTag) | 375 if (m_token.type() == HTMLToken::StartTag) |
356 m_tokenizer->updateStateFor(AtomicString(m_token.name())); | 376 m_tokenizer->updateStateFor(AtomicString(m_token.name())); |
357 m_scanner.scan(m_token, m_source, requests); | 377 m_scanner.scan(m_token, m_source, requests); |
358 m_token.clear(); | 378 m_token.clear(); |
359 } | 379 } |
360 | 380 |
361 preloader->takeAndPreload(requests); | 381 preloader->takeAndPreload(requests); |
362 } | 382 } |
363 | 383 |
364 } | 384 } |
OLD | NEW |