| 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 { | 78 { |
| 79 ASSERT(tagImpl); | 79 ASSERT(tagImpl); |
| 80 if (match(tagImpl, imgTag)) | 80 if (match(tagImpl, imgTag)) |
| 81 return imgTag.localName(); | 81 return imgTag.localName(); |
| 82 if (match(tagImpl, inputTag)) | 82 if (match(tagImpl, inputTag)) |
| 83 return inputTag.localName(); | 83 return inputTag.localName(); |
| 84 if (match(tagImpl, linkTag)) | 84 if (match(tagImpl, linkTag)) |
| 85 return linkTag.localName(); | 85 return linkTag.localName(); |
| 86 if (match(tagImpl, scriptTag)) | 86 if (match(tagImpl, scriptTag)) |
| 87 return scriptTag.localName(); | 87 return scriptTag.localName(); |
| 88 #if ENABLE(PICTURE) |
| 89 if (match(tagImpl, sourceTag)) |
| 90 return sourceTag.localName(); |
| 91 if (match(tagImpl, pictureTag)) |
| 92 return pictureTag.localName(); |
| 93 #endif |
| 88 ASSERT_NOT_REACHED(); | 94 ASSERT_NOT_REACHED(); |
| 89 return "unknown"; | 95 return "unknown"; |
| 90 } | 96 } |
| 91 | 97 |
| 92 class TokenPreloadScanner::StartTagScanner { | 98 class TokenPreloadScanner::StartTagScanner { |
| 93 public: | 99 public: |
| 94 explicit StartTagScanner(const StringImpl* tagImpl) | 100 explicit StartTagScanner(const StringImpl* tagImpl |
| 101 #if ENABLE(PICTURE) |
| 102 , bool inPicture |
| 103 #endif |
| 104 ) |
| 95 : m_tagImpl(tagImpl) | 105 : m_tagImpl(tagImpl) |
| 96 , m_linkIsStyleSheet(false) | 106 , m_linkIsStyleSheet(false) |
| 97 , m_inputIsImage(false) | 107 , m_inputIsImage(false) |
| 108 #if ENABLE(PICTURE) |
| 109 , m_tagInPicture(inPicture) |
| 110 #endif |
| 98 { | 111 { |
| 99 if (!match(m_tagImpl, imgTag) | 112 if (!match(m_tagImpl, imgTag) |
| 100 && !match(m_tagImpl, inputTag) | 113 && !match(m_tagImpl, inputTag) |
| 101 && !match(m_tagImpl, linkTag) | 114 && !match(m_tagImpl, linkTag) |
| 115 #if ENABLE(PICTURE) |
| 116 && !match(m_tagImpl, pictureTag) |
| 117 && !match(m_tagImpl, sourceTag) |
| 118 #endif |
| 102 && !match(m_tagImpl, scriptTag)) | 119 && !match(m_tagImpl, scriptTag)) |
| 103 m_tagImpl = 0; | 120 m_tagImpl = 0; |
| 104 } | 121 } |
| 105 | 122 |
| 106 void processAttributes(const HTMLToken::AttributeList& attributes) | 123 void processAttributes(const HTMLToken::AttributeList& attributes) |
| 107 { | 124 { |
| 108 ASSERT(isMainThread()); | 125 ASSERT(isMainThread()); |
| 109 if (!m_tagImpl) | 126 if (!m_tagImpl) |
| 110 return; | 127 return; |
| 111 for (HTMLToken::AttributeList::const_iterator iter = attributes.begin();
iter != attributes.end(); ++iter) { | 128 for (HTMLToken::AttributeList::const_iterator iter = attributes.begin();
iter != attributes.end(); ++iter) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 127 { | 144 { |
| 128 if (!shouldPreload()) | 145 if (!shouldPreload()) |
| 129 return nullptr; | 146 return nullptr; |
| 130 | 147 |
| 131 OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_t
agImpl), m_urlToLoad, predictedBaseURL, resourceType(), m_mediaAttribute); | 148 OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_t
agImpl), m_urlToLoad, predictedBaseURL, resourceType(), m_mediaAttribute); |
| 132 request->setCrossOriginModeAllowsCookies(crossOriginModeAllowsCookies())
; | 149 request->setCrossOriginModeAllowsCookies(crossOriginModeAllowsCookies())
; |
| 133 request->setCharset(charset()); | 150 request->setCharset(charset()); |
| 134 return request.release(); | 151 return request.release(); |
| 135 } | 152 } |
| 136 | 153 |
| 154 #if ENABLE(PICTURE) |
| 155 bool inPicture() { return m_tagInPicture; } |
| 156 #endif |
| 137 private: | 157 private: |
| 138 template<typename NameType> | 158 template<typename NameType> |
| 139 void processAttribute(const NameType& attributeName, const String& attribute
Value) | 159 void processAttribute(const NameType& attributeName, const String& attribute
Value) |
| 140 { | 160 { |
| 141 if (match(attributeName, charsetAttr)) | 161 if (match(attributeName, charsetAttr)) |
| 142 m_charset = attributeValue; | 162 m_charset = attributeValue; |
| 143 | 163 |
| 144 if (match(m_tagImpl, scriptTag) || match(m_tagImpl, imgTag)) { | 164 if (match(m_tagImpl, scriptTag) |
| 165 || match(m_tagImpl, imgTag) |
| 166 #if ENABLE(PICTURE) |
| 167 || match(m_tagImpl, pictureTag) |
| 168 #endif |
| 169 ) { |
| 170 if (match(attributeName, srcAttr)) { |
| 171 setUrlToLoad(attributeValue); |
| 172 #if ENABLE(PICTURE) |
| 173 m_tagInPicture = false; |
| 174 #endif |
| 175 } |
| 176 else if (match(attributeName, crossoriginAttr) && !attributeValue.is
Null()) |
| 177 m_crossOriginMode = stripLeadingAndTrailingHTMLSpaces(attributeV
alue); |
| 178 #if ENABLE(PICTURE) |
| 179 } else if (match(m_tagImpl, sourceTag) && m_tagInPicture) { |
| 145 if (match(attributeName, srcAttr)) | 180 if (match(attributeName, srcAttr)) |
| 146 setUrlToLoad(attributeValue); | 181 setUrlToLoad(attributeValue); |
| 147 else if (match(attributeName, crossoriginAttr) && !attributeValue.is
Null()) | 182 else if (match(attributeName, mediaAttr)) |
| 148 m_crossOriginMode = stripLeadingAndTrailingHTMLSpaces(attributeV
alue); | 183 m_mediaAttribute = attributeValue; |
| 184 #endif |
| 149 } else if (match(m_tagImpl, linkTag)) { | 185 } else if (match(m_tagImpl, linkTag)) { |
| 150 if (match(attributeName, hrefAttr)) | 186 if (match(attributeName, hrefAttr)) |
| 151 setUrlToLoad(attributeValue); | 187 setUrlToLoad(attributeValue); |
| 152 else if (match(attributeName, relAttr)) | 188 else if (match(attributeName, relAttr)) |
| 153 m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue); | 189 m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue); |
| 154 else if (match(attributeName, mediaAttr)) | 190 else if (match(attributeName, mediaAttr)) |
| 155 m_mediaAttribute = attributeValue; | 191 m_mediaAttribute = attributeValue; |
| 156 } else if (match(m_tagImpl, inputTag)) { | 192 } else if (match(m_tagImpl, inputTag)) { |
| 157 if (match(attributeName, srcAttr)) | 193 if (match(attributeName, srcAttr)) |
| 158 setUrlToLoad(attributeValue); | 194 setUrlToLoad(attributeValue); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 181 // FIXME: Its not clear that this if is needed, the loader probably igno
res charset for image requests anyway. | 217 // FIXME: Its not clear that this if is needed, the loader probably igno
res charset for image requests anyway. |
| 182 if (match(m_tagImpl, imgTag)) | 218 if (match(m_tagImpl, imgTag)) |
| 183 return emptyString(); | 219 return emptyString(); |
| 184 return m_charset; | 220 return m_charset; |
| 185 } | 221 } |
| 186 | 222 |
| 187 CachedResource::Type resourceType() const | 223 CachedResource::Type resourceType() const |
| 188 { | 224 { |
| 189 if (match(m_tagImpl, scriptTag)) | 225 if (match(m_tagImpl, scriptTag)) |
| 190 return CachedResource::Script; | 226 return CachedResource::Script; |
| 191 if (match(m_tagImpl, imgTag) || (match(m_tagImpl, inputTag) && m_inputIs
Image)) | 227 if (match(m_tagImpl, imgTag) |
| 228 || (match(m_tagImpl, inputTag) && m_inputIsImage) |
| 229 #if ENABLE(PICTURE) |
| 230 || (match(m_tagImpl, pictureTag)) |
| 231 || (match(m_tagImpl, sourceTag)) |
| 232 #endif |
| 233 ) |
| 192 return CachedResource::ImageResource; | 234 return CachedResource::ImageResource; |
| 193 if (match(m_tagImpl, linkTag) && m_linkIsStyleSheet) | 235 if (match(m_tagImpl, linkTag) && m_linkIsStyleSheet) |
| 194 return CachedResource::CSSStyleSheet; | 236 return CachedResource::CSSStyleSheet; |
| 195 ASSERT_NOT_REACHED(); | 237 ASSERT_NOT_REACHED(); |
| 196 return CachedResource::RawResource; | 238 return CachedResource::RawResource; |
| 197 } | 239 } |
| 198 | 240 |
| 199 bool shouldPreload() | 241 bool shouldPreload() |
| 200 { | 242 { |
| 201 if (m_urlToLoad.isEmpty()) | 243 if (m_urlToLoad.isEmpty()) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 212 return m_crossOriginMode.isNull() || equalIgnoringCase(m_crossOriginMode
, "use-credentials"); | 254 return m_crossOriginMode.isNull() || equalIgnoringCase(m_crossOriginMode
, "use-credentials"); |
| 213 } | 255 } |
| 214 | 256 |
| 215 const StringImpl* m_tagImpl; | 257 const StringImpl* m_tagImpl; |
| 216 String m_urlToLoad; | 258 String m_urlToLoad; |
| 217 String m_charset; | 259 String m_charset; |
| 218 String m_crossOriginMode; | 260 String m_crossOriginMode; |
| 219 bool m_linkIsStyleSheet; | 261 bool m_linkIsStyleSheet; |
| 220 String m_mediaAttribute; | 262 String m_mediaAttribute; |
| 221 bool m_inputIsImage; | 263 bool m_inputIsImage; |
| 264 #if ENABLE(PICTURE) |
| 265 bool m_tagInPicture; |
| 266 #endif |
| 222 }; | 267 }; |
| 223 | 268 |
| 269 static void appendBundleRequest(PreloadRequestStream& requests, bool start, bool
end) |
| 270 { |
| 271 OwnPtr<PreloadRequest> request = PreloadRequest::create(start, end); |
| 272 if (request) |
| 273 requests.append(request.release()); |
| 274 } |
| 275 |
| 224 TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL) | 276 TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL) |
| 225 : m_documentURL(documentURL) | 277 : m_documentURL(documentURL) |
| 226 , m_inStyle(false) | 278 , m_inStyle(false) |
| 227 , m_templateCount(0) | 279 , m_templateCount(0) |
| 228 { | 280 { |
| 229 } | 281 } |
| 230 | 282 |
| 231 TokenPreloadScanner::~TokenPreloadScanner() | 283 TokenPreloadScanner::~TokenPreloadScanner() |
| 232 { | 284 { |
| 233 } | 285 } |
| 234 | 286 |
| 235 TokenPreloadScannerCheckpoint TokenPreloadScanner::createCheckpoint() | 287 TokenPreloadScannerCheckpoint TokenPreloadScanner::createCheckpoint() |
| 236 { | 288 { |
| 237 TokenPreloadScannerCheckpoint checkpoint = m_checkpoints.size(); | 289 TokenPreloadScannerCheckpoint checkpoint = m_checkpoints.size(); |
| 238 m_checkpoints.append(Checkpoint(m_predictedBaseElementURL, m_inStyle, m_temp
lateCount)); | 290 m_checkpoints.append(Checkpoint(m_predictedBaseElementURL, m_inStyle, m_temp
lateCount)); |
| 239 return checkpoint; | 291 return checkpoint; |
| 240 } | 292 } |
| 241 | 293 |
| 242 void TokenPreloadScanner::rewindTo(TokenPreloadScannerCheckpoint checkpointIndex
) | 294 void TokenPreloadScanner::rewindTo(TokenPreloadScannerCheckpoint checkpointIndex
) |
| 243 { | 295 { |
| 244 ASSERT(checkpointIndex < m_checkpoints.size()); // If this ASSERT fires, che
ckpointIndex is invalid. | 296 ASSERT(checkpointIndex < m_checkpoints.size()); // If this ASSERT fires, che
ckpointIndex is invalid. |
| 245 const Checkpoint& checkpoint = m_checkpoints[checkpointIndex]; | 297 const Checkpoint& checkpoint = m_checkpoints[checkpointIndex]; |
| 246 m_predictedBaseElementURL = checkpoint.predictedBaseElementURL; | 298 m_predictedBaseElementURL = checkpoint.predictedBaseElementURL; |
| 247 m_inStyle = checkpoint.inStyle; | 299 m_inStyle = checkpoint.inStyle; |
| 248 m_templateCount = checkpoint.templateCount; | 300 m_templateCount = checkpoint.templateCount; |
| 249 m_cssScanner.reset(); | 301 m_cssScanner.reset(); |
| 250 m_checkpoints.clear(); | 302 m_checkpoints.clear(); |
| 251 } | 303 } |
| 252 | 304 |
| 253 void TokenPreloadScanner::scan(const HTMLToken& token, Vector<OwnPtr<PreloadRequ
est> >& requests) | 305 void TokenPreloadScanner::scan(const HTMLToken& token, PreloadRequestStream& req
uests) |
| 254 { | 306 { |
| 255 scanCommon(token, requests); | 307 scanCommon(token, requests); |
| 256 } | 308 } |
| 257 | 309 |
| 258 void TokenPreloadScanner::scan(const CompactHTMLToken& token, Vector<OwnPtr<Prel
oadRequest> >& requests) | 310 void TokenPreloadScanner::scan(const CompactHTMLToken& token, PreloadRequestStre
am& requests) |
| 259 { | 311 { |
| 260 scanCommon(token, requests); | 312 scanCommon(token, requests); |
| 261 } | 313 } |
| 262 | 314 |
| 263 template<typename Token> | 315 template<typename Token> |
| 264 void TokenPreloadScanner::scanCommon(const Token& token, Vector<OwnPtr<PreloadRe
quest> >& requests) | 316 void TokenPreloadScanner::scanCommon(const Token& token, PreloadRequestStream& r
equests) |
| 265 { | 317 { |
| 266 switch (token.type()) { | 318 switch (token.type()) { |
| 267 case HTMLToken::Character: { | 319 case HTMLToken::Character: { |
| 268 if (!m_inStyle) | 320 if (!m_inStyle) |
| 269 return; | 321 return; |
| 270 m_cssScanner.scan(token.data(), requests); | 322 m_cssScanner.scan(token.data(), requests); |
| 271 return; | 323 return; |
| 272 } | 324 } |
| 273 case HTMLToken::EndTag: { | 325 case HTMLToken::EndTag: { |
| 274 const StringImpl* tagImpl = tagImplFor(token.data()); | 326 const StringImpl* tagImpl = tagImplFor(token.data()); |
| 275 if (match(tagImpl, templateTag)) { | 327 if (match(tagImpl, templateTag)) { |
| 276 if (m_templateCount) | 328 if (m_templateCount) |
| 277 --m_templateCount; | 329 --m_templateCount; |
| 278 return; | 330 return; |
| 279 } | 331 } |
| 280 if (match(tagImpl, styleTag)) { | 332 if (match(tagImpl, styleTag)) { |
| 281 if (m_inStyle) | 333 if (m_inStyle) |
| 282 m_cssScanner.reset(); | 334 m_cssScanner.reset(); |
| 283 m_inStyle = false; | 335 m_inStyle = false; |
| 284 } | 336 } |
| 337 #if ENABLE(PICTURE) |
| 338 else if (match(tagImpl, pictureTag)) { |
| 339 m_inPicture = false; |
| 340 appendBundleRequest(requests, false, true); |
| 341 } |
| 342 #endif |
| 285 return; | 343 return; |
| 286 } | 344 } |
| 287 case HTMLToken::StartTag: { | 345 case HTMLToken::StartTag: { |
| 288 if (m_templateCount) | 346 if (m_templateCount) |
| 289 return; | 347 return; |
| 290 const StringImpl* tagImpl = tagImplFor(token.data()); | 348 const StringImpl* tagImpl = tagImplFor(token.data()); |
| 291 if (match(tagImpl, templateTag)) { | 349 if (match(tagImpl, templateTag)) { |
| 292 ++m_templateCount; | 350 ++m_templateCount; |
| 293 return; | 351 return; |
| 294 } | 352 } |
| 295 if (match(tagImpl, styleTag)) { | 353 if (match(tagImpl, styleTag)) { |
| 296 m_inStyle = true; | 354 m_inStyle = true; |
| 297 return; | 355 return; |
| 298 } | 356 } |
| 357 #if ENABLE(PICTURE) |
| 358 if (match(tagImpl, pictureTag)) { |
| 359 m_inPicture = true; |
| 360 appendBundleRequest(requests, true, false); |
| 361 } |
| 362 #endif |
| 299 if (match(tagImpl, baseTag)) { | 363 if (match(tagImpl, baseTag)) { |
| 300 // The first <base> element is the one that wins. | 364 // The first <base> element is the one that wins. |
| 301 if (!m_predictedBaseElementURL.isEmpty()) | 365 if (!m_predictedBaseElementURL.isEmpty()) |
| 302 return; | 366 return; |
| 303 updatePredictedBaseURL(token); | 367 updatePredictedBaseURL(token); |
| 304 return; | 368 return; |
| 305 } | 369 } |
| 306 | 370 |
| 307 StartTagScanner scanner(tagImpl); | 371 StartTagScanner scanner(tagImpl |
| 372 #if ENABLE(PICTURE) |
| 373 , m_inPicture |
| 374 #endif |
| 375 ); |
| 308 scanner.processAttributes(token.attributes()); | 376 scanner.processAttributes(token.attributes()); |
| 377 #if ENABLE(PICTURE) |
| 378 m_inPicture = scanner.inPicture(); |
| 379 #endif |
| 309 OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predicte
dBaseElementURL); | 380 OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predicte
dBaseElementURL); |
| 310 if (request) | 381 if (request) |
| 311 requests.append(request.release()); | 382 requests.append(request.release()); |
| 312 return; | 383 return; |
| 313 } | 384 } |
| 314 default: { | 385 default: { |
| 315 return; | 386 return; |
| 316 } | 387 } |
| 317 } | 388 } |
| 318 } | 389 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 if (m_token.type() == HTMLToken::StartTag) | 425 if (m_token.type() == HTMLToken::StartTag) |
| 355 m_tokenizer->updateStateFor(AtomicString(m_token.name())); | 426 m_tokenizer->updateStateFor(AtomicString(m_token.name())); |
| 356 m_scanner.scan(m_token, requests); | 427 m_scanner.scan(m_token, requests); |
| 357 m_token.clear(); | 428 m_token.clear(); |
| 358 } | 429 } |
| 359 | 430 |
| 360 preloader->takeAndPreload(requests); | 431 preloader->takeAndPreload(requests); |
| 361 } | 432 } |
| 362 | 433 |
| 363 } | 434 } |
| OLD | NEW |