| 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |