Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Unified Diff: Source/core/html/parser/HTMLPreloadScanner.cpp

Issue 265763010: Add preloader support for picture based source selection (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Fix algo issue with self closing tags Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/html/parser/HTMLPreloadScanner.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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());
« no previous file with comments | « Source/core/html/parser/HTMLPreloadScanner.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698