#include "config.h"
#include "core/html/parser/HTMLPreloadScanner.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
-#include "RuntimeEnabledFeatures.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/css/MediaList.h"
#include "core/css/MediaQueryEvaluator.h"
#include "core/css/MediaValues.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/parser/HTMLSrcsetParser.h"
#include "core/html/parser/HTMLTokenizer.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/TraceEvent.h"
#include "wtf/MainThread.h"
-namespace WebCore {
+namespace blink {
using namespace HTMLNames;
const StringImpl* result = tagName.impl();
if (result->isStatic())
return result;
- return 0;
+ return nullptr;
}
static const StringImpl* tagImplFor(const String& tagName)
const StringImpl* result = tagName.impl();
if (result->isStatic())
return result;
- return 0;
+ return nullptr;
}
static String initiatorFor(const StringImpl* tagImpl)
static bool mediaAttributeMatches(const MediaValues& mediaValues, const String& attributeValue)
{
RefPtrWillBeRawPtr<MediaQuerySet> mediaQueries = MediaQuerySet::createOffMainThread(attributeValue);
- MediaQueryEvaluator mediaQueryEvaluator("screen", mediaValues);
+ MediaQueryEvaluator mediaQueryEvaluator(mediaValues);
return mediaQueryEvaluator.eval(mediaQueries.get());
}
, m_linkIsStyleSheet(false)
, m_matchedMediaAttribute(true)
, m_inputIsImage(false)
- , m_imgSourceSize(0)
+ , m_sourceSize(0)
, m_sourceSizeSet(false)
, m_isCORSEnabled(false)
+ , m_defer(FetchRequest::NoDefer)
, 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(m_mediaValues, String()).length();
+ 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 {
ASSERT(isMainThread());
if (!m_tagImpl)
return;
- for (HTMLToken::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) {
- AtomicString attributeName(iter->name);
- String attributeValue = StringImpl::create8BitIfPossible(iter->value);
+ for (const HTMLToken::Attribute& htmlTokenAttribute : attributes) {
+ AtomicString attributeName(htmlTokenAttribute.name);
+ String attributeValue = StringImpl::create8BitIfPossible(htmlTokenAttribute.value);
processAttribute(attributeName, attributeValue);
}
}
{
if (!m_tagImpl)
return;
- for (Vector<CompactHTMLToken::Attribute>::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter)
- processAttribute(iter->name, iter->value);
+ for (const CompactHTMLToken::Attribute& htmlTokenAttribute : attributes)
+ processAttribute(htmlTokenAttribute.name, htmlTokenAttribute.value);
+ }
+
+ void handlePictureSourceURL(String& sourceURL)
+ {
+ if (match(m_tagImpl, sourceTag) && m_matchedMediaAttribute && sourceURL.isEmpty())
+ sourceURL = m_srcsetImageCandidate.toString();
+ else if (match(m_tagImpl, imgTag) && !sourceURL.isEmpty())
+ setUrlToLoad(sourceURL, AllowURLReplacement);
}
PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL, const SegmentedString& source)
if (isCORSEnabled())
request->setCrossOriginEnabled(allowStoredCredentials());
request->setCharset(charset());
+ request->setDefer(m_defer);
return request.release();
}
private:
template<typename NameType>
+ void processScriptAttribute(const NameType& attributeName, const String& attributeValue)
+ {
+ // FIXME - Don't set crossorigin multiple times.
+ if (match(attributeName, srcAttr))
+ setUrlToLoad(attributeValue, DisallowURLReplacement);
+ else if (match(attributeName, crossoriginAttr))
+ setCrossOriginAllowed(attributeValue);
+ else if (match(attributeName, asyncAttr))
+ setDefer(FetchRequest::LazyLoad);
+ else if (match(attributeName, deferAttr))
+ setDefer(FetchRequest::LazyLoad);
+ }
+
+ 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(m_mediaValues, attributeValue).length();
+ 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 - Don't set rel/media/crossorigin multiple times.
+ 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 - Don't set type multiple times.
+ 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(m_mediaValues, attributeValue).length();
+ m_sourceSizeSet = true;
+ if (!m_srcsetImageCandidate.isEmpty()) {
+ m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_mediaValues->devicePixelRatio(), m_sourceSize, m_srcsetAttributeValue);
+ }
+ } else if (match(attributeName, mediaAttr)) {
+ // FIXME - Don't match media multiple times.
+ 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)
m_allowCredentials = DoNotAllowStoredCredentials;
}
+ void setDefer(FetchRequest::DeferOption defer)
+ {
+ m_defer = defer;
+ }
+
+ bool defer() const
+ {
+ return m_defer;
+ }
+
const StringImpl* m_tagImpl;
String m_urlToLoad;
ImageCandidate m_srcsetImageCandidate;
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;
+ FetchRequest::DeferOption m_defer;
StoredCredentials m_allowCredentials;
RefPtr<MediaValues> m_mediaValues;
};
TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL, PassRefPtr<MediaValues> mediaValues)
: m_documentURL(documentURL)
, m_inStyle(false)
+ , m_inPicture(false)
, m_templateCount(0)
, m_mediaValues(mediaValues)
{
if (m_inStyle)
m_cssScanner.reset();
m_inStyle = false;
+ return;
}
+ if (match(tagImpl, pictureTag))
+ m_inPicture = false;
return;
}
case HTMLToken::StartTag: {
updatePredictedBaseURL(token);
return;
}
+ if (RuntimeEnabledFeatures::pictureEnabled() && (match(tagImpl, pictureTag))) {
+ m_inPicture = true;
+ m_pictureSourceURL = String();
+ return;
+ }
StartTagScanner scanner(tagImpl, m_mediaValues);
scanner.processAttributes(token.attributes());
+ if (m_inPicture)
+ scanner.handlePictureSourceURL(m_pictureSourceURL);
OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predictedBaseElementURL, source);
if (request)
requests.append(request.release());
{
ASSERT(isMainThread()); // HTMLTokenizer::updateStateFor only works on the main thread.
- TRACE_EVENT1("webkit", "HTMLPreloadScanner::scan", "source_length", m_source.length());
+ TRACE_EVENT1("blink", "HTMLPreloadScanner::scan", "source_length", m_source.length());
// When we start scanning, our best prediction of the baseElementURL is the real one!
if (!startingBaseElementURL.isEmpty())