| 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 "core/css/MediaList.h" |
| 33 #include "core/css/MediaQueryEvaluator.h" |
| 32 #include "core/html/InputTypeNames.h" | 34 #include "core/html/InputTypeNames.h" |
| 33 #include "core/html/LinkRelAttribute.h" | 35 #include "core/html/LinkRelAttribute.h" |
| 34 #include "core/html/parser/HTMLParserIdioms.h" | 36 #include "core/html/parser/HTMLParserIdioms.h" |
| 35 #include "core/html/parser/HTMLTokenizer.h" | 37 #include "core/html/parser/HTMLTokenizer.h" |
| 36 #include "wtf/MainThread.h" | 38 #include "wtf/MainThread.h" |
| 37 | |
| 38 namespace WebCore { | 39 namespace WebCore { |
| 39 | 40 |
| 40 using namespace HTMLNames; | 41 using namespace HTMLNames; |
| 41 | 42 |
| 42 static bool match(const StringImpl* impl, const QualifiedName& qName) | 43 static bool match(const StringImpl* impl, const QualifiedName& qName) |
| 43 { | 44 { |
| 44 return impl == qName.localName().impl(); | 45 return impl == qName.localName().impl(); |
| 45 } | 46 } |
| 46 | 47 |
| 47 static bool match(const HTMLIdentifier& name, const QualifiedName& qName) | 48 static bool match(const HTMLIdentifier& name, const QualifiedName& qName) |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 if (match(tagImpl, inputTag)) | 81 if (match(tagImpl, inputTag)) |
| 81 return inputTag.localName(); | 82 return inputTag.localName(); |
| 82 if (match(tagImpl, linkTag)) | 83 if (match(tagImpl, linkTag)) |
| 83 return linkTag.localName(); | 84 return linkTag.localName(); |
| 84 if (match(tagImpl, scriptTag)) | 85 if (match(tagImpl, scriptTag)) |
| 85 return scriptTag.localName(); | 86 return scriptTag.localName(); |
| 86 ASSERT_NOT_REACHED(); | 87 ASSERT_NOT_REACHED(); |
| 87 return "unknown"; | 88 return "unknown"; |
| 88 } | 89 } |
| 89 | 90 |
| 91 static bool mediaAttributeMatches(const MediaValues* mediaValues, const String&
attributeValue) |
| 92 { |
| 93 RefPtr<MediaQuerySet> mediaQueries = MediaQuerySet::create(attributeValue); |
| 94 MediaQueryEvaluator mediaQueryEvaluator("screen", mediaValues, false); |
| 95 bool ret = mediaQueryEvaluator.eval(mediaQueries.get()); |
| 96 return ret; |
| 97 } |
| 98 |
| 90 class TokenPreloadScanner::StartTagScanner { | 99 class TokenPreloadScanner::StartTagScanner { |
| 91 public: | 100 public: |
| 92 explicit StartTagScanner(const StringImpl* tagImpl) | 101 explicit StartTagScanner(const StringImpl* tagImpl, PassRefPtr<MediaValues>
mediaValues) |
| 93 : m_tagImpl(tagImpl) | 102 : m_tagImpl(tagImpl) |
| 94 , m_linkIsStyleSheet(false) | 103 , m_linkIsStyleSheet(false) |
| 95 , m_inputIsImage(false) | 104 , m_inputIsImage(false) |
| 105 , m_mediaMatch(true) |
| 106 , m_mediaValues(MediaValues::copy(mediaValues.get())) |
| 96 { | 107 { |
| 97 if (!match(m_tagImpl, imgTag) | 108 if (!match(m_tagImpl, imgTag) |
| 98 && !match(m_tagImpl, inputTag) | 109 && !match(m_tagImpl, inputTag) |
| 99 && !match(m_tagImpl, linkTag) | 110 && !match(m_tagImpl, linkTag) |
| 100 && !match(m_tagImpl, scriptTag)) | 111 && !match(m_tagImpl, scriptTag)) |
| 101 m_tagImpl = 0; | 112 m_tagImpl = 0; |
| 102 } | 113 } |
| 103 | 114 |
| 104 void processAttributes(const HTMLToken::AttributeList& attributes) | 115 void processAttributes(const HTMLToken::AttributeList& attributes) |
| 105 { | 116 { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 116 void processAttributes(const Vector<CompactHTMLToken::Attribute>& attributes
) | 127 void processAttributes(const Vector<CompactHTMLToken::Attribute>& attributes
) |
| 117 { | 128 { |
| 118 if (!m_tagImpl) | 129 if (!m_tagImpl) |
| 119 return; | 130 return; |
| 120 for (Vector<CompactHTMLToken::Attribute>::const_iterator iter = attribut
es.begin(); iter != attributes.end(); ++iter) | 131 for (Vector<CompactHTMLToken::Attribute>::const_iterator iter = attribut
es.begin(); iter != attributes.end(); ++iter) |
| 121 processAttribute(iter->name, iter->value); | 132 processAttribute(iter->name, iter->value); |
| 122 } | 133 } |
| 123 | 134 |
| 124 PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL
, const SegmentedString& source) | 135 PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL
, const SegmentedString& source) |
| 125 { | 136 { |
| 126 if (!shouldPreload()) | 137 if (!shouldPreload() || !m_mediaMatch) |
| 127 return nullptr; | 138 return nullptr; |
| 128 | 139 |
| 129 TextPosition position = TextPosition(source.currentLine(), source.curren
tColumn()); | 140 TextPosition position = TextPosition(source.currentLine(), source.curren
tColumn()); |
| 130 OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_t
agImpl), position, m_urlToLoad, predictedBaseURL, resourceType(), m_mediaAttribu
te); | 141 OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_t
agImpl), position, m_urlToLoad, predictedBaseURL, resourceType()); |
| 131 request->setCrossOriginModeAllowsCookies(crossOriginModeAllowsCookies())
; | 142 request->setCrossOriginModeAllowsCookies(crossOriginModeAllowsCookies())
; |
| 132 request->setCharset(charset()); | 143 request->setCharset(charset()); |
| 133 return request.release(); | 144 return request.release(); |
| 134 } | 145 } |
| 135 | 146 |
| 136 private: | 147 private: |
| 148 |
| 137 template<typename NameType> | 149 template<typename NameType> |
| 138 void processAttribute(const NameType& attributeName, const String& attribute
Value) | 150 void processAttribute(const NameType& attributeName, const String& attribute
Value) |
| 139 { | 151 { |
| 140 if (match(attributeName, charsetAttr)) | 152 if (match(attributeName, charsetAttr)) |
| 141 m_charset = attributeValue; | 153 m_charset = attributeValue; |
| 142 | 154 |
| 143 if (match(m_tagImpl, scriptTag) || match(m_tagImpl, imgTag)) { | 155 if (match(m_tagImpl, scriptTag) || match(m_tagImpl, imgTag)) { |
| 144 if (match(attributeName, srcAttr)) | 156 if (match(attributeName, srcAttr)) |
| 145 setUrlToLoad(attributeValue); | 157 setUrlToLoad(attributeValue); |
| 146 else if (match(attributeName, crossoriginAttr) && !attributeValue.is
Null()) | 158 else if (match(attributeName, crossoriginAttr) && !attributeValue.is
Null()) |
| 147 m_crossOriginMode = stripLeadingAndTrailingHTMLSpaces(attributeV
alue); | 159 m_crossOriginMode = stripLeadingAndTrailingHTMLSpaces(attributeV
alue); |
| 148 } else if (match(m_tagImpl, linkTag)) { | 160 } else if (match(m_tagImpl, linkTag)) { |
| 149 if (match(attributeName, hrefAttr)) | 161 if (match(attributeName, hrefAttr)) |
| 150 setUrlToLoad(attributeValue); | 162 setUrlToLoad(attributeValue); |
| 151 else if (match(attributeName, relAttr)) | 163 else if (match(attributeName, relAttr)) |
| 152 m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue); | 164 m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue); |
| 153 else if (match(attributeName, mediaAttr)) | 165 else if (match(attributeName, mediaAttr)) |
| 154 m_mediaAttribute = attributeValue; | 166 m_mediaMatch = mediaAttributeMatches(m_mediaValues.get(), attrib
uteValue); |
| 155 } else if (match(m_tagImpl, inputTag)) { | 167 } else if (match(m_tagImpl, inputTag)) { |
| 156 if (match(attributeName, srcAttr)) | 168 if (match(attributeName, srcAttr)) |
| 157 setUrlToLoad(attributeValue); | 169 setUrlToLoad(attributeValue); |
| 158 else if (match(attributeName, typeAttr)) | 170 else if (match(attributeName, typeAttr)) |
| 159 m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeName
s::image()); | 171 m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeName
s::image()); |
| 160 } | 172 } |
| 161 } | 173 } |
| 162 | 174 |
| 163 static bool relAttributeIsStyleSheet(const String& attributeValue) | 175 static bool relAttributeIsStyleSheet(const String& attributeValue) |
| 164 { | 176 { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 bool crossOriginModeAllowsCookies() | 221 bool crossOriginModeAllowsCookies() |
| 210 { | 222 { |
| 211 return m_crossOriginMode.isNull() || equalIgnoringCase(m_crossOriginMode
, "use-credentials"); | 223 return m_crossOriginMode.isNull() || equalIgnoringCase(m_crossOriginMode
, "use-credentials"); |
| 212 } | 224 } |
| 213 | 225 |
| 214 const StringImpl* m_tagImpl; | 226 const StringImpl* m_tagImpl; |
| 215 String m_urlToLoad; | 227 String m_urlToLoad; |
| 216 String m_charset; | 228 String m_charset; |
| 217 String m_crossOriginMode; | 229 String m_crossOriginMode; |
| 218 bool m_linkIsStyleSheet; | 230 bool m_linkIsStyleSheet; |
| 219 String m_mediaAttribute; | 231 bool m_mediaMatch; |
| 220 bool m_inputIsImage; | 232 bool m_inputIsImage; |
| 233 RefPtr<MediaValues> m_mediaValues; |
| 221 }; | 234 }; |
| 222 | 235 |
| 223 TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL) | 236 TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL, PassRefPtr<Med
iaValues> mediaValues) |
| 224 : m_documentURL(documentURL) | 237 : m_documentURL(documentURL) |
| 225 , m_inStyle(false) | 238 , m_inStyle(false) |
| 226 , m_templateCount(0) | 239 , m_templateCount(0) |
| 240 , m_mediaValues(mediaValues) |
| 227 { | 241 { |
| 228 } | 242 } |
| 229 | 243 |
| 230 TokenPreloadScanner::~TokenPreloadScanner() | 244 TokenPreloadScanner::~TokenPreloadScanner() |
| 231 { | 245 { |
| 232 } | 246 } |
| 233 | 247 |
| 234 TokenPreloadScannerCheckpoint TokenPreloadScanner::createCheckpoint() | 248 TokenPreloadScannerCheckpoint TokenPreloadScanner::createCheckpoint() |
| 235 { | 249 { |
| 236 TokenPreloadScannerCheckpoint checkpoint = m_checkpoints.size(); | 250 TokenPreloadScannerCheckpoint checkpoint = m_checkpoints.size(); |
| 237 m_checkpoints.append(Checkpoint(m_predictedBaseElementURL, m_inStyle, m_temp
lateCount)); | 251 m_checkpoints.append(Checkpoint(m_predictedBaseElementURL, m_inStyle, m_temp
lateCount)); |
| 238 return checkpoint; | 252 return checkpoint; |
| 239 } | 253 } |
| 240 | 254 |
| 255 |
| 241 void TokenPreloadScanner::rewindTo(TokenPreloadScannerCheckpoint checkpointIndex
) | 256 void TokenPreloadScanner::rewindTo(TokenPreloadScannerCheckpoint checkpointIndex
) |
| 242 { | 257 { |
| 243 ASSERT(checkpointIndex < m_checkpoints.size()); // If this ASSERT fires, che
ckpointIndex is invalid. | 258 ASSERT(checkpointIndex < m_checkpoints.size()); // If this ASSERT fires, che
ckpointIndex is invalid. |
| 244 const Checkpoint& checkpoint = m_checkpoints[checkpointIndex]; | 259 const Checkpoint& checkpoint = m_checkpoints[checkpointIndex]; |
| 245 m_predictedBaseElementURL = checkpoint.predictedBaseElementURL; | 260 m_predictedBaseElementURL = checkpoint.predictedBaseElementURL; |
| 246 m_inStyle = checkpoint.inStyle; | 261 m_inStyle = checkpoint.inStyle; |
| 247 m_templateCount = checkpoint.templateCount; | 262 m_templateCount = checkpoint.templateCount; |
| 248 m_cssScanner.reset(); | 263 m_cssScanner.reset(); |
| 249 m_checkpoints.clear(); | 264 m_checkpoints.clear(); |
| 250 } | 265 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 return; | 311 return; |
| 297 } | 312 } |
| 298 if (match(tagImpl, baseTag)) { | 313 if (match(tagImpl, baseTag)) { |
| 299 // The first <base> element is the one that wins. | 314 // The first <base> element is the one that wins. |
| 300 if (!m_predictedBaseElementURL.isEmpty()) | 315 if (!m_predictedBaseElementURL.isEmpty()) |
| 301 return; | 316 return; |
| 302 updatePredictedBaseURL(token); | 317 updatePredictedBaseURL(token); |
| 303 return; | 318 return; |
| 304 } | 319 } |
| 305 | 320 |
| 306 StartTagScanner scanner(tagImpl); | 321 StartTagScanner scanner(tagImpl, m_mediaValues); |
| 307 scanner.processAttributes(token.attributes()); | 322 scanner.processAttributes(token.attributes()); |
| 308 OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predicte
dBaseElementURL, source); | 323 OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predicte
dBaseElementURL, source); |
| 309 if (request) | 324 if (request) |
| 310 requests.append(request.release()); | 325 requests.append(request.release()); |
| 311 return; | 326 return; |
| 312 } | 327 } |
| 313 default: { | 328 default: { |
| 314 return; | 329 return; |
| 315 } | 330 } |
| 316 } | 331 } |
| 317 } | 332 } |
| 318 | 333 |
| 319 template<typename Token> | 334 template<typename Token> |
| 320 void TokenPreloadScanner::updatePredictedBaseURL(const Token& token) | 335 void TokenPreloadScanner::updatePredictedBaseURL(const Token& token) |
| 321 { | 336 { |
| 322 ASSERT(m_predictedBaseElementURL.isEmpty()); | 337 ASSERT(m_predictedBaseElementURL.isEmpty()); |
| 323 if (const typename Token::Attribute* hrefAttribute = token.getAttributeItem(
hrefAttr)) | 338 if (const typename Token::Attribute* hrefAttribute = token.getAttributeItem(
hrefAttr)) |
| 324 m_predictedBaseElementURL = KURL(m_documentURL, stripLeadingAndTrailingH
TMLSpaces(hrefAttribute->value)).copy(); | 339 m_predictedBaseElementURL = KURL(m_documentURL, stripLeadingAndTrailingH
TMLSpaces(hrefAttribute->value)).copy(); |
| 325 } | 340 } |
| 326 | 341 |
| 327 HTMLPreloadScanner::HTMLPreloadScanner(const HTMLParserOptions& options, const K
URL& documentURL) | 342 HTMLPreloadScanner::HTMLPreloadScanner(const HTMLParserOptions& options, const K
URL& documentURL, PassRefPtr<MediaValues> mediaValues) |
| 328 : m_scanner(documentURL) | 343 : m_scanner(documentURL, mediaValues) |
| 329 , m_tokenizer(HTMLTokenizer::create(options)) | 344 , m_tokenizer(HTMLTokenizer::create(options)) |
| 330 { | 345 { |
| 331 } | 346 } |
| 332 | 347 |
| 333 HTMLPreloadScanner::~HTMLPreloadScanner() | 348 HTMLPreloadScanner::~HTMLPreloadScanner() |
| 334 { | 349 { |
| 335 } | 350 } |
| 336 | 351 |
| 337 void HTMLPreloadScanner::appendToEnd(const SegmentedString& source) | 352 void HTMLPreloadScanner::appendToEnd(const SegmentedString& source) |
| 338 { | 353 { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 353 if (m_token.type() == HTMLToken::StartTag) | 368 if (m_token.type() == HTMLToken::StartTag) |
| 354 m_tokenizer->updateStateFor(AtomicString(m_token.name())); | 369 m_tokenizer->updateStateFor(AtomicString(m_token.name())); |
| 355 m_scanner.scan(m_token, m_source, requests); | 370 m_scanner.scan(m_token, m_source, requests); |
| 356 m_token.clear(); | 371 m_token.clear(); |
| 357 } | 372 } |
| 358 | 373 |
| 359 preloader->takeAndPreload(requests); | 374 preloader->takeAndPreload(requests); |
| 360 } | 375 } |
| 361 | 376 |
| 362 } | 377 } |
| OLD | NEW |