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()); |