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