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..c070c5af2bbf5ec81df537b08bf63c17091a41e7 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,19 @@ public: |
processAttribute(iter->name, iter->value); |
} |
+ void handlePictureSourceURL(Vector<String>& pictureSourceURLStack) |
+ { |
+ if (pictureSourceURLStack.isEmpty()) |
+ return; |
+ |
+ if (match(m_tagImpl, sourceTag) && pictureSourceURLStack.last().isEmpty() && m_matchedMediaAttribute) { |
+ pictureSourceURLStack.removeLast(); |
+ pictureSourceURLStack.append(m_srcsetImageCandidate.toString()); |
+ } else if (match(m_tagImpl, imgTag) && !pictureSourceURLStack.last().isEmpty()) { |
+ setUrlToLoad(pictureSourceURLStack.last(), AllowURLReplacement); |
+ } |
+ } |
+ |
PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL, const SegmentedString& source) |
{ |
if (!shouldPreload() || !m_matchedMediaAttribute) |
@@ -164,49 +180,93 @@ public: |
private: |
template<typename NameType> |
+ void processScriptAttribute(const NameType& attributeName, const String& attributeValue) |
+ { |
+ 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) |
+ { |
+ 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) |
+ { |
+ 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)) { |
+ 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 +345,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; |
@@ -308,7 +368,7 @@ TokenPreloadScanner::~TokenPreloadScanner() |
TokenPreloadScannerCheckpoint TokenPreloadScanner::createCheckpoint() |
{ |
TokenPreloadScannerCheckpoint checkpoint = m_checkpoints.size(); |
- m_checkpoints.append(Checkpoint(m_predictedBaseElementURL, m_inStyle, m_templateCount)); |
+ m_checkpoints.append(Checkpoint(m_predictedBaseElementURL, m_inStyle, m_pictureSourceURLStack, m_templateCount)); |
return checkpoint; |
} |
@@ -318,6 +378,7 @@ void TokenPreloadScanner::rewindTo(TokenPreloadScannerCheckpoint checkpointIndex |
const Checkpoint& checkpoint = m_checkpoints[checkpointIndex]; |
m_predictedBaseElementURL = checkpoint.predictedBaseElementURL; |
m_inStyle = checkpoint.inStyle; |
+ m_pictureSourceURLStack = checkpoint.pictureSourceURLStack; |
m_templateCount = checkpoint.templateCount; |
m_cssScanner.reset(); |
m_checkpoints.clear(); |
@@ -355,6 +416,8 @@ void TokenPreloadScanner::scanCommon(const Token& token, const SegmentedString& |
m_cssScanner.reset(); |
m_inStyle = false; |
} |
+ if (match(tagImpl, pictureTag)) |
+ m_pictureSourceURLStack.removeLast(); |
return; |
} |
case HTMLToken::StartTag: { |
@@ -376,9 +439,12 @@ void TokenPreloadScanner::scanCommon(const Token& token, const SegmentedString& |
updatePredictedBaseURL(token); |
return; |
} |
+ if (match(tagImpl, pictureTag)) |
+ m_pictureSourceURLStack.append(String()); |
StartTagScanner scanner(tagImpl, m_mediaValues); |
scanner.processAttributes(token.attributes()); |
+ scanner.handlePictureSourceURL(m_pictureSourceURLStack); |
OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predictedBaseElementURL, source); |
if (request) |
requests.append(request.release()); |