Chromium Code Reviews| Index: Source/core/html/parser/HTMLPreloadScanner.cpp |
| diff --git a/Source/core/html/parser/HTMLPreloadScanner.cpp b/Source/core/html/parser/HTMLPreloadScanner.cpp |
| index 706fb0e51034b954e74e60534ba1610ac8e53691..8906ed97f50073500f67a3ba514697dfcf357d44 100644 |
| --- a/Source/core/html/parser/HTMLPreloadScanner.cpp |
| +++ b/Source/core/html/parser/HTMLPreloadScanner.cpp |
| @@ -108,19 +108,22 @@ public: |
| , m_linkIsStyleSheet(false) |
| , m_matchedMediaAttribute(true) |
| , m_inputIsImage(false) |
| - , m_imgSourceSize(0) |
| + , m_sourceSize(0) |
| , m_sourceSizeSet(false) |
| , m_isCORSEnabled(false) |
| , m_allowCredentials(DoNotAllowStoredCredentials) |
| , m_mediaValues(mediaValues) |
| { |
| - if (!match(m_tagImpl, imgTag) |
| - && !match(m_tagImpl, inputTag) |
| + if (match(m_tagImpl, imgTag) |
| + || match(m_tagImpl, sourceTag)) { |
| + if (RuntimeEnabledFeatures::pictureSizesEnabled()) |
| + m_sourceSize = SizesAttributeParser::findEffectiveSize(String(), m_mediaValues); |
| + return; |
| + } |
| + if ( !match(m_tagImpl, inputTag) |
| && !match(m_tagImpl, linkTag) |
| && !match(m_tagImpl, scriptTag)) |
| m_tagImpl = 0; |
| - if (RuntimeEnabledFeatures::pictureSizesEnabled()) |
| - m_imgSourceSize = SizesAttributeParser::findEffectiveSize(String(), m_mediaValues); |
| } |
| enum URLReplacement { |
| @@ -148,6 +151,18 @@ public: |
| processAttribute(iter->name, iter->value); |
| } |
| + void handlePictureSourceURL(Vector<Parent>& pictureParentStack) |
| + { |
| + if (pictureParentStack.isEmpty() || !match(pictureParentStack.last().tagImpl, pictureTag)) |
| + return; |
| + |
| + Parent& parent = pictureParentStack.last(); |
| + if (match(m_tagImpl, sourceTag) && m_matchedMediaAttribute && parent.sourceURL.isEmpty()) |
| + parent.sourceURL = m_srcsetImageCandidate.toString(); |
| + else if (match(m_tagImpl, imgTag) && !parent.sourceURL.isEmpty()) |
| + setUrlToLoad(parent.sourceURL, AllowURLReplacement); |
| + } |
| + |
| PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL, const SegmentedString& source) |
| { |
| if (!shouldPreload() || !m_matchedMediaAttribute) |
| @@ -164,49 +179,98 @@ public: |
| private: |
| template<typename NameType> |
| + void processScriptAttribute(const NameType& attributeName, const String& attributeValue) |
| + { |
| + // FIXME - What should happen if we have multiple crossOrigin attributes with different values? |
|
eseidel
2014/05/21 22:44:18
I figured last one, but it looks like first does:
|
| + if (match(attributeName, srcAttr)) |
| + setUrlToLoad(attributeValue, DisallowURLReplacement); |
| + else if (match(attributeName, crossoriginAttr)) |
| + setCrossOriginAllowed(attributeValue); |
| + } |
| + |
| + template<typename NameType> |
| + void processImgAttribute(const NameType& attributeName, const String& attributeValue) |
| + { |
| + if (match(attributeName, srcAttr) && m_imgSrcUrl.isNull()) { |
| + m_imgSrcUrl = attributeValue; |
| + setUrlToLoad(bestFitSourceForImageAttributes(m_mediaValues->devicePixelRatio(), m_sourceSize, attributeValue, m_srcsetImageCandidate), AllowURLReplacement); |
| + } else if (match(attributeName, crossoriginAttr)) { |
| + setCrossOriginAllowed(attributeValue); |
| + } else if (match(attributeName, srcsetAttr) && m_srcsetImageCandidate.isEmpty()) { |
| + m_srcsetAttributeValue = attributeValue; |
| + m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_mediaValues->devicePixelRatio(), m_sourceSize, attributeValue); |
| + setUrlToLoad(bestFitSourceForImageAttributes(m_mediaValues->devicePixelRatio(), m_sourceSize, m_imgSrcUrl, m_srcsetImageCandidate), AllowURLReplacement); |
| + } else if (RuntimeEnabledFeatures::pictureSizesEnabled() && match(attributeName, sizesAttr) && !m_sourceSizeSet) { |
| + m_sourceSize = SizesAttributeParser::findEffectiveSize(attributeValue, m_mediaValues); |
| + m_sourceSizeSet = true; |
| + if (!m_srcsetImageCandidate.isEmpty()) { |
| + m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_mediaValues->devicePixelRatio(), m_sourceSize, m_srcsetAttributeValue); |
| + setUrlToLoad(bestFitSourceForImageAttributes(m_mediaValues->devicePixelRatio(), m_sourceSize, m_imgSrcUrl, m_srcsetImageCandidate), AllowURLReplacement); |
| + } |
| + } |
| + } |
| + |
| + template<typename NameType> |
| + void processLinkAttribute(const NameType& attributeName, const String& attributeValue) |
| + { |
| + // FIXME - What should happen if we have multiple rel/media/crossOrigin attributes of the same name, with different values? |
| + if (match(attributeName, hrefAttr)) |
| + setUrlToLoad(attributeValue, DisallowURLReplacement); |
| + else if (match(attributeName, relAttr)) |
| + m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue); |
| + else if (match(attributeName, mediaAttr)) |
| + m_matchedMediaAttribute = mediaAttributeMatches(*m_mediaValues, attributeValue); |
| + else if (match(attributeName, crossoriginAttr)) |
| + setCrossOriginAllowed(attributeValue); |
| + } |
| + |
| + template<typename NameType> |
| + void processInputAttribute(const NameType& attributeName, const String& attributeValue) |
| + { |
| + // FIXME - What should happen if we have multiple type attributes with different values? |
| + if (match(attributeName, srcAttr)) |
| + setUrlToLoad(attributeValue, DisallowURLReplacement); |
| + else if (match(attributeName, typeAttr)) |
| + m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeNames::image); |
| + } |
| + |
| + template<typename NameType> |
| + void processSourceAttribute(const NameType& attributeName, const String& attributeValue) |
| + { |
| + if (!RuntimeEnabledFeatures::pictureEnabled()) |
| + return; |
| + if (match(attributeName, srcsetAttr) && m_srcsetImageCandidate.isEmpty()) { |
| + m_srcsetAttributeValue = attributeValue; |
| + m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_mediaValues->devicePixelRatio(), m_sourceSize, attributeValue); |
| + } else if (match(attributeName, sizesAttr) && !m_sourceSizeSet) { |
| + m_sourceSize = SizesAttributeParser::findEffectiveSize(attributeValue, m_mediaValues); |
| + m_sourceSizeSet = true; |
| + if (!m_srcsetImageCandidate.isEmpty()) { |
| + m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_mediaValues->devicePixelRatio(), m_sourceSize, m_srcsetAttributeValue); |
| + } |
| + } else if (match(attributeName, mediaAttr)) { |
| + // FIXME - What should happen if we have multiple media attributes??? |
| + m_matchedMediaAttribute = mediaAttributeMatches(*m_mediaValues, attributeValue); |
| + } |
| + |
| + } |
| + |
| + template<typename NameType> |
| void processAttribute(const NameType& attributeName, const String& attributeValue) |
| { |
| if (match(attributeName, charsetAttr)) |
| m_charset = attributeValue; |
| - if (match(m_tagImpl, scriptTag)) { |
| - if (match(attributeName, srcAttr)) |
| - setUrlToLoad(attributeValue, DisallowURLReplacement); |
| - else if (match(attributeName, crossoriginAttr)) |
| - setCrossOriginAllowed(attributeValue); |
| - } else if (match(m_tagImpl, imgTag)) { |
| - if (match(attributeName, srcAttr) && m_imgSrcUrl.isNull()) { |
| - m_imgSrcUrl = attributeValue; |
| - setUrlToLoad(bestFitSourceForImageAttributes(m_mediaValues->devicePixelRatio(), m_imgSourceSize, attributeValue, m_srcsetImageCandidate), AllowURLReplacement); |
| - } else if (match(attributeName, crossoriginAttr)) { |
| - setCrossOriginAllowed(attributeValue); |
| - } else if (match(attributeName, srcsetAttr) && m_srcsetImageCandidate.isEmpty()) { |
| - m_imgSrcsetAttributeValue = attributeValue; |
| - m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_mediaValues->devicePixelRatio(), m_imgSourceSize, attributeValue); |
| - setUrlToLoad(bestFitSourceForImageAttributes(m_mediaValues->devicePixelRatio(), m_imgSourceSize, m_imgSrcUrl, m_srcsetImageCandidate), AllowURLReplacement); |
| - } else if (RuntimeEnabledFeatures::pictureSizesEnabled() && match(attributeName, sizesAttr) && !m_sourceSizeSet) { |
| - m_imgSourceSize = SizesAttributeParser::findEffectiveSize(attributeValue, m_mediaValues); |
| - m_sourceSizeSet = true; |
| - if (!m_srcsetImageCandidate.isEmpty()) { |
| - m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_mediaValues->devicePixelRatio(), m_imgSourceSize, m_imgSrcsetAttributeValue); |
| - setUrlToLoad(bestFitSourceForImageAttributes(m_mediaValues->devicePixelRatio(), m_imgSourceSize, m_imgSrcUrl, m_srcsetImageCandidate), AllowURLReplacement); |
| - } |
| - } |
| - } else if (match(m_tagImpl, linkTag)) { |
| - if (match(attributeName, hrefAttr)) |
| - setUrlToLoad(attributeValue, DisallowURLReplacement); |
| - else if (match(attributeName, relAttr)) |
| - m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue); |
| - else if (match(attributeName, mediaAttr)) |
| - m_matchedMediaAttribute = mediaAttributeMatches(*m_mediaValues, attributeValue); |
| - else if (match(attributeName, crossoriginAttr)) |
| - setCrossOriginAllowed(attributeValue); |
| - } else if (match(m_tagImpl, inputTag)) { |
| - if (match(attributeName, srcAttr)) |
| - setUrlToLoad(attributeValue, DisallowURLReplacement); |
| - else if (match(attributeName, typeAttr)) |
| - m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeNames::image); |
| - } |
| + if (match(m_tagImpl, scriptTag)) |
| + processScriptAttribute(attributeName, attributeValue); |
| + else if (match(m_tagImpl, imgTag)) |
| + processImgAttribute(attributeName, attributeValue); |
| + else if (match(m_tagImpl, linkTag)) |
| + processLinkAttribute(attributeName, attributeValue); |
| + else if (match(m_tagImpl, inputTag)) |
| + processInputAttribute(attributeName, attributeValue); |
| + else if (match(m_tagImpl, sourceTag)) |
| + processSourceAttribute(attributeName, attributeValue); |
| } |
| static bool relAttributeIsStyleSheet(const String& attributeValue) |
| @@ -285,8 +349,8 @@ private: |
| bool m_matchedMediaAttribute; |
| bool m_inputIsImage; |
| String m_imgSrcUrl; |
| - String m_imgSrcsetAttributeValue; |
| - unsigned m_imgSourceSize; |
| + String m_srcsetAttributeValue; |
| + unsigned m_sourceSize; |
| bool m_sourceSizeSet; |
| bool m_isCORSEnabled; |
| StoredCredentials m_allowCredentials; |
| @@ -333,6 +397,25 @@ void TokenPreloadScanner::scan(const CompactHTMLToken& token, const SegmentedStr |
| scanCommon(token, source, requests); |
| } |
| +static bool startNesting(const StringImpl* tagImpl) |
|
eseidel
2014/05/21 22:44:18
Can you give this a more descriptive name?
|
| +{ |
| + if (match(tagImpl, sourceTag) |
| + || match(tagImpl, imgTag) |
| + || match(tagImpl, areaTag) |
| + || match(tagImpl, baseTag) |
| + || match(tagImpl, brTag) |
| + || match(tagImpl, colTag) |
| + || match(tagImpl, hrTag) |
| + || match(tagImpl, inputTag) |
| + || match(tagImpl, linkTag) |
| + || match(tagImpl, metaTag) |
| + || match(tagImpl, paramTag) |
| + || match(tagImpl, commandTag) |
| + || match(tagImpl, keygenTag)) |
| + return false; |
| + return true; |
| +} |
| + |
| template<typename Token> |
| void TokenPreloadScanner::scanCommon(const Token& token, const SegmentedString& source, PreloadRequestStream& requests) |
| { |
| @@ -350,6 +433,8 @@ void TokenPreloadScanner::scanCommon(const Token& token, const SegmentedString& |
| --m_templateCount; |
| return; |
| } |
| + if (!m_pictureParentStack.isEmpty() && startNesting(tagImpl) && m_pictureParentStack.last().tagImpl == tagImpl) |
| + m_pictureParentStack.removeLast(); |
| if (match(tagImpl, styleTag)) { |
| if (m_inStyle) |
| m_cssScanner.reset(); |
| @@ -361,6 +446,10 @@ void TokenPreloadScanner::scanCommon(const Token& token, const SegmentedString& |
| if (m_templateCount) |
| return; |
| const StringImpl* tagImpl = tagImplFor(token.data()); |
| + if (RuntimeEnabledFeatures::pictureEnabled() |
| + && ((match(tagImpl, pictureTag)) || (!m_pictureParentStack.isEmpty() && startNesting(tagImpl)))) { |
| + m_pictureParentStack.append(Parent(tagImpl)); |
| + } |
| if (match(tagImpl, templateTag)) { |
| ++m_templateCount; |
| return; |
| @@ -379,6 +468,7 @@ void TokenPreloadScanner::scanCommon(const Token& token, const SegmentedString& |
| StartTagScanner scanner(tagImpl, m_mediaValues); |
| scanner.processAttributes(token.attributes()); |
| + scanner.handlePictureSourceURL(m_pictureParentStack); |
| OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predictedBaseElementURL, source); |
| if (request) |
| requests.append(request.release()); |