summaryrefslogtreecommitdiff
path: root/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
commit32761a6cee1d0dee366b885b7b9c777e67885688 (patch)
treed6bec92bebfb216f4126356e55518842c2f476a1 /Source/WebCore/html/parser/HTMLPreloadScanner.cpp
parenta4e969f4965059196ca948db781e52f7cfebf19e (diff)
downloadWebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/WebCore/html/parser/HTMLPreloadScanner.cpp')
-rw-r--r--Source/WebCore/html/parser/HTMLPreloadScanner.cpp252
1 files changed, 86 insertions, 166 deletions
diff --git a/Source/WebCore/html/parser/HTMLPreloadScanner.cpp b/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
index dee9ea660..51c81e189 100644
--- a/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
+++ b/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
@@ -30,13 +30,9 @@
#include "HTMLNames.h"
#include "HTMLParserIdioms.h"
-#include "HTMLSrcsetParser.h"
#include "HTMLTokenizer.h"
#include "InputTypeNames.h"
#include "LinkRelAttribute.h"
-#include "MediaList.h"
-#include "MediaQueryEvaluator.h"
-#include "SourceSizeList.h"
#include <wtf/MainThread.h>
namespace WebCore {
@@ -60,19 +56,12 @@ TokenPreloadScanner::TagId TokenPreloadScanner::tagIdFor(const HTMLToken::DataVe
return TagId::Base;
if (tagName == templateTag)
return TagId::Template;
- if (tagName == metaTag)
- return TagId::Meta;
- if (tagName == pictureTag)
- return TagId::Picture;
- if (tagName == sourceTag)
- return TagId::Source;
return TagId::Unknown;
}
String TokenPreloadScanner::initiatorFor(TagId tagId)
{
switch (tagId) {
- case TagId::Source:
case TagId::Img:
return "img";
case TagId::Input:
@@ -85,8 +74,6 @@ String TokenPreloadScanner::initiatorFor(TagId tagId)
case TagId::Style:
case TagId::Base:
case TagId::Template:
- case TagId::Meta:
- case TagId::Picture:
ASSERT_NOT_REACHED();
return "unknown";
}
@@ -99,42 +86,27 @@ public:
explicit StartTagScanner(TagId tagId, float deviceScaleFactor = 1.0)
: m_tagId(tagId)
, m_linkIsStyleSheet(false)
- , m_metaIsViewport(false)
, m_inputIsImage(false)
, m_deviceScaleFactor(deviceScaleFactor)
{
}
- void processAttributes(const HTMLToken::AttributeList& attributes, Document& document, Vector<bool>& pictureState)
+ void processAttributes(const HTMLToken::AttributeList& attributes)
{
ASSERT(isMainThread());
if (m_tagId >= TagId::Unknown)
return;
-
- for (auto& attribute : attributes) {
- AtomicString attributeName(attribute.name);
- String attributeValue = StringImpl::create8BitIfPossible(attribute.value);
- processAttribute(attributeName, attributeValue, document, pictureState);
- }
-
- if (m_tagId == TagId::Source && !pictureState.isEmpty() && !pictureState.last() && m_mediaMatched && !m_srcSetAttribute.isEmpty()) {
- float sourceSize = parseSizesAttribute(m_sizesAttribute, document.renderView(), document.frame());
- ImageCandidate imageCandidate = bestFitSourceForImageAttributes(m_deviceScaleFactor, m_urlToLoad, m_srcSetAttribute, sourceSize);
- if (!imageCandidate.isEmpty()) {
- pictureState.last() = true;
- setUrlToLoad(imageCandidate.string.toString(), true);
- }
- }
-
- // Resolve between src and srcSet if we have them and the tag is img.
- if (m_tagId == TagId::Img && !m_srcSetAttribute.isEmpty()) {
- float sourceSize = parseSizesAttribute(m_sizesAttribute, document.renderView(), document.frame());
- ImageCandidate imageCandidate = bestFitSourceForImageAttributes(m_deviceScaleFactor, m_urlToLoad, m_srcSetAttribute, sourceSize);
- setUrlToLoad(imageCandidate.string.toString(), true);
+ for (HTMLToken::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) {
+ AtomicString attributeName(iter->name);
+ String attributeValue = StringImpl::create8BitIfPossible(iter->value);
+ processAttribute(attributeName, attributeValue);
}
- if (m_metaIsViewport && !m_metaContent.isNull())
- document.processViewport(m_metaContent, ViewportArguments::ViewportMeta);
+ // Resolve between src and srcSet if we have them.
+ if (!m_srcSetAttribute.isEmpty()) {
+ String srcMatchingScale = bestFitSourceForImageAttributes(m_deviceScaleFactor, m_urlToLoad, m_srcSetAttribute);
+ setUrlToLoad(srcMatchingScale, true);
+ }
}
std::unique_ptr<PreloadRequest> createPreloadRequest(const URL& predictedBaseURL)
@@ -156,92 +128,38 @@ public:
}
private:
- void processImageAndScriptAttribute(const AtomicString& attributeName, const String& attributeValue)
+ template<typename NameType>
+ void processAttribute(const NameType& attributeName, const String& attributeValue)
{
- if (match(attributeName, srcAttr))
- setUrlToLoad(attributeValue);
- else if (match(attributeName, crossoriginAttr) && !attributeValue.isNull())
- m_crossOriginMode = stripLeadingAndTrailingHTMLSpaces(attributeValue);
- else if (match(attributeName, charsetAttr))
+ if (match(attributeName, charsetAttr))
m_charset = attributeValue;
- }
- void processAttribute(const AtomicString& attributeName, const String& attributeValue, Document& document, const Vector<bool>& pictureState)
- {
- bool inPicture = !pictureState.isEmpty();
- bool alreadyMatchedSource = inPicture && pictureState.last();
-
- switch (m_tagId) {
- case TagId::Img:
- if (inPicture && alreadyMatchedSource)
- break;
- if (match(attributeName, srcsetAttr) && m_srcSetAttribute.isNull()) {
- m_srcSetAttribute = attributeValue;
- break;
- }
- if (match(attributeName, sizesAttr) && m_sizesAttribute.isNull()) {
- m_sizesAttribute = attributeValue;
- break;
- }
- processImageAndScriptAttribute(attributeName, attributeValue);
- break;
- case TagId::Source:
- if (inPicture && alreadyMatchedSource)
- break;
- if (match(attributeName, srcsetAttr) && m_srcSetAttribute.isNull()) {
+ if (m_tagId == TagId::Script || m_tagId == TagId::Img) {
+ if (match(attributeName, srcAttr))
+ setUrlToLoad(attributeValue);
+ else if (match(attributeName, srcsetAttr))
m_srcSetAttribute = attributeValue;
- break;
- }
- if (match(attributeName, sizesAttr) && m_sizesAttribute.isNull()) {
- m_sizesAttribute = attributeValue;
- break;
- }
- if (match(attributeName, mediaAttr) && m_mediaAttribute.isNull()) {
- m_mediaAttribute = attributeValue;
- Ref<MediaQuerySet> mediaSet = MediaQuerySet::createAllowingDescriptionSyntax(attributeValue);
- Vector<std::unique_ptr<MediaQueryResult>> viewportDependentMediaQueryResults;
- MediaQueryEvaluator evaluator(document.printing() ? "print" : "screen", document.frame(), document.documentElement() ? document.documentElement()->computedStyle() : nullptr);
- m_mediaMatched = evaluator.evalCheckingViewportDependentResults(mediaSet.ptr(), viewportDependentMediaQueryResults);
- }
- break;
- case TagId::Script:
- processImageAndScriptAttribute(attributeName, attributeValue);
- break;
- case TagId::Link:
+ else if (match(attributeName, crossoriginAttr) && !attributeValue.isNull())
+ m_crossOriginMode = stripLeadingAndTrailingHTMLSpaces(attributeValue);
+ } else if (m_tagId == TagId::Link) {
if (match(attributeName, hrefAttr))
setUrlToLoad(attributeValue);
else if (match(attributeName, relAttr))
m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue);
else if (match(attributeName, mediaAttr))
m_mediaAttribute = attributeValue;
- else if (match(attributeName, charsetAttr))
- m_charset = attributeValue;
- break;
- case TagId::Input:
+ } else if (m_tagId == TagId::Input) {
if (match(attributeName, srcAttr))
setUrlToLoad(attributeValue);
else if (match(attributeName, typeAttr))
- m_inputIsImage = equalLettersIgnoringASCIICase(attributeValue, "image");
- break;
- case TagId::Meta:
- if (match(attributeName, contentAttr))
- m_metaContent = attributeValue;
- else if (match(attributeName, nameAttr))
- m_metaIsViewport = equalLettersIgnoringASCIICase(attributeValue, "viewport");
- break;
- case TagId::Base:
- case TagId::Style:
- case TagId::Template:
- case TagId::Picture:
- case TagId::Unknown:
- break;
+ m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeNames::image());
}
}
static bool relAttributeIsStyleSheet(const String& attributeValue)
{
- LinkRelAttribute parsedAttribute { attributeValue };
- return parsedAttribute.isStyleSheet && !parsedAttribute.isAlternate && parsedAttribute.iconType == InvalidIcon && !parsedAttribute.isDNSPrefetch;
+ LinkRelAttribute rel(attributeValue);
+ return rel.m_isStyleSheet && !rel.m_isAlternate && rel.m_iconType == InvalidIcon && !rel.m_isDNSPrefetch;
}
void setUrlToLoad(const String& value, bool allowReplacement = false)
@@ -258,30 +176,20 @@ private:
const String& charset() const
{
+ // FIXME: Its not clear that this if is needed, the loader probably ignores charset for image requests anyway.
+ if (m_tagId == TagId::Img)
+ return emptyString();
return m_charset;
}
CachedResource::Type resourceType() const
{
- switch (m_tagId) {
- case TagId::Script:
+ if (m_tagId == TagId::Script)
return CachedResource::Script;
- case TagId::Img:
- case TagId::Input:
- case TagId::Source:
- ASSERT(m_tagId != TagId::Input || m_inputIsImage);
+ if (m_tagId == TagId::Img || (m_tagId == TagId::Input && m_inputIsImage))
return CachedResource::ImageResource;
- case TagId::Link:
- ASSERT(m_linkIsStyleSheet);
+ if (m_tagId == TagId::Link && m_linkIsStyleSheet)
return CachedResource::CSSStyleSheet;
- case TagId::Meta:
- case TagId::Unknown:
- case TagId::Style:
- case TagId::Base:
- case TagId::Template:
- case TagId::Picture:
- break;
- }
ASSERT_NOT_REACHED();
return CachedResource::RawResource;
}
@@ -291,9 +199,6 @@ private:
if (m_urlToLoad.isEmpty())
return false;
- if (protocolIs(m_urlToLoad, "data") || protocolIs(m_urlToLoad, "about"))
- return false;
-
if (m_tagId == TagId::Link && !m_linkIsStyleSheet)
return false;
@@ -305,41 +210,69 @@ private:
bool crossOriginModeAllowsCookies()
{
- return m_crossOriginMode.isNull() || equalLettersIgnoringASCIICase(m_crossOriginMode, "use-credentials");
+ return m_crossOriginMode.isNull() || equalIgnoringCase(m_crossOriginMode, "use-credentials");
}
TagId m_tagId;
String m_urlToLoad;
String m_srcSetAttribute;
- String m_sizesAttribute;
- bool m_mediaMatched { true };
String m_charset;
String m_crossOriginMode;
bool m_linkIsStyleSheet;
String m_mediaAttribute;
- String m_metaContent;
- bool m_metaIsViewport;
bool m_inputIsImage;
float m_deviceScaleFactor;
};
TokenPreloadScanner::TokenPreloadScanner(const URL& documentURL, float deviceScaleFactor)
: m_documentURL(documentURL)
+ , m_inStyle(false)
, m_deviceScaleFactor(deviceScaleFactor)
+#if ENABLE(TEMPLATE_ELEMENT)
+ , m_templateCount(0)
+#endif
+{
+}
+
+TokenPreloadScanner::~TokenPreloadScanner()
+{
+}
+
+TokenPreloadScannerCheckpoint TokenPreloadScanner::createCheckpoint()
+{
+ TokenPreloadScannerCheckpoint checkpoint = m_checkpoints.size();
+ m_checkpoints.append(Checkpoint(m_predictedBaseElementURL, m_inStyle
+#if ENABLE(TEMPLATE_ELEMENT)
+ , m_templateCount
+#endif
+ ));
+ return checkpoint;
+}
+
+void TokenPreloadScanner::rewindTo(TokenPreloadScannerCheckpoint checkpointIndex)
{
+ ASSERT(checkpointIndex < m_checkpoints.size()); // If this ASSERT fires, checkpointIndex is invalid.
+ const Checkpoint& checkpoint = m_checkpoints[checkpointIndex];
+ m_predictedBaseElementURL = checkpoint.predictedBaseElementURL;
+ m_inStyle = checkpoint.inStyle;
+#if ENABLE(TEMPLATE_ELEMENT)
+ m_templateCount = checkpoint.templateCount;
+#endif
+ m_cssScanner.reset();
+ m_checkpoints.clear();
}
-void TokenPreloadScanner::scan(const HTMLToken& token, Vector<std::unique_ptr<PreloadRequest>>& requests, Document& document)
+void TokenPreloadScanner::scan(const HTMLToken& token, Vector<std::unique_ptr<PreloadRequest>>& requests)
{
switch (token.type()) {
case HTMLToken::Character:
if (!m_inStyle)
return;
- m_cssScanner.scan(token.characters(), requests);
+ m_cssScanner.scan(token.data(), requests);
return;
case HTMLToken::EndTag: {
- TagId tagId = tagIdFor(token.name());
+ TagId tagId = tagIdFor(token.data());
#if ENABLE(TEMPLATE_ELEMENT)
if (tagId == TagId::Template) {
if (m_templateCount)
@@ -351,9 +284,7 @@ void TokenPreloadScanner::scan(const HTMLToken& token, Vector<std::unique_ptr<Pr
if (m_inStyle)
m_cssScanner.reset();
m_inStyle = false;
- } else if (tagId == TagId::Picture && !m_pictureSourceState.isEmpty())
- m_pictureSourceState.removeLast();
-
+ }
return;
}
@@ -362,7 +293,7 @@ void TokenPreloadScanner::scan(const HTMLToken& token, Vector<std::unique_ptr<Pr
if (m_templateCount)
return;
#endif
- TagId tagId = tagIdFor(token.name());
+ TagId tagId = tagIdFor(token.data());
#if ENABLE(TEMPLATE_ELEMENT)
if (tagId == TagId::Template) {
++m_templateCount;
@@ -380,15 +311,11 @@ void TokenPreloadScanner::scan(const HTMLToken& token, Vector<std::unique_ptr<Pr
updatePredictedBaseURL(token);
return;
}
- if (tagId == TagId::Picture) {
- m_pictureSourceState.append(false);
- return;
- }
StartTagScanner scanner(tagId, m_deviceScaleFactor);
- scanner.processAttributes(token.attributes(), document, m_pictureSourceState);
+ scanner.processAttributes(token.attributes());
if (auto request = scanner.createPreloadRequest(m_predictedBaseElementURL))
- requests.append(WTFMove(request));
+ requests.append(std::move(request));
return;
}
@@ -397,16 +324,21 @@ void TokenPreloadScanner::scan(const HTMLToken& token, Vector<std::unique_ptr<Pr
}
}
-void TokenPreloadScanner::updatePredictedBaseURL(const HTMLToken& token)
+template<typename Token>
+void TokenPreloadScanner::updatePredictedBaseURL(const Token& token)
{
ASSERT(m_predictedBaseElementURL.isEmpty());
- if (auto* hrefAttribute = findAttribute(token.attributes(), hrefAttr.localName().string()))
- m_predictedBaseElementURL = URL(m_documentURL, stripLeadingAndTrailingHTMLSpaces(StringImpl::create8BitIfPossible(hrefAttribute->value))).isolatedCopy();
+ if (const typename Token::Attribute* hrefAttribute = token.getAttributeItem(hrefAttr))
+ m_predictedBaseElementURL = URL(m_documentURL, stripLeadingAndTrailingHTMLSpaces(hrefAttribute->value)).copy();
}
HTMLPreloadScanner::HTMLPreloadScanner(const HTMLParserOptions& options, const URL& documentURL, float deviceScaleFactor)
: m_scanner(documentURL, deviceScaleFactor)
- , m_tokenizer(options)
+ , m_tokenizer(std::make_unique<HTMLTokenizer>(options))
+{
+}
+
+HTMLPreloadScanner::~HTMLPreloadScanner()
{
}
@@ -415,36 +347,24 @@ void HTMLPreloadScanner::appendToEnd(const SegmentedString& source)
m_source.append(source);
}
-void HTMLPreloadScanner::scan(HTMLResourcePreloader& preloader, Document& document)
+void HTMLPreloadScanner::scan(HTMLResourcePreloader* preloader, const URL& startingBaseElementURL)
{
ASSERT(isMainThread()); // HTMLTokenizer::updateStateFor only works on the main thread.
- const URL& startingBaseElementURL = document.baseElementURL();
-
// When we start scanning, our best prediction of the baseElementURL is the real one!
if (!startingBaseElementURL.isEmpty())
m_scanner.setPredictedBaseElementURL(startingBaseElementURL);
PreloadRequestStream requests;
- while (auto token = m_tokenizer.nextToken(m_source)) {
- if (token->type() == HTMLToken::StartTag)
- m_tokenizer.updateStateFor(AtomicString(token->name()));
- m_scanner.scan(*token, requests, document);
+ while (m_tokenizer->nextToken(m_source, m_token)) {
+ if (m_token.type() == HTMLToken::StartTag)
+ m_tokenizer->updateStateFor(AtomicString(m_token.name()));
+ m_scanner.scan(m_token, requests);
+ m_token.clear();
}
- preloader.preload(WTFMove(requests));
-}
-
-bool testPreloadScannerViewportSupport(Document* document)
-{
- ASSERT(document);
- HTMLParserOptions options(*document);
- HTMLPreloadScanner scanner(options, document->url());
- HTMLResourcePreloader preloader(*document);
- scanner.appendToEnd(String("<meta name=viewport content='width=400'>"));
- scanner.scan(preloader, *document);
- return (document->viewportArguments().width == 400);
+ preloader->preload(std::move(requests));
}
}