summaryrefslogtreecommitdiff
path: root/chromium/third_party/WebKit/Source/core/html/parser
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/html/parser')
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/AtomicHTMLToken.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLInputStream.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLInputStream.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp24
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/CompactHTMLToken.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/CompactHTMLToken.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp224
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h82
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp26
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.cpp1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityParser.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLIdentifier.cpp125
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLIdentifier.h82
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLInputStream.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.cpp1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.cpp40
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.h40
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserOptions.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp56
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLSourceTracker.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLSourceTracker.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.cpp3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp123
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp120
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.cpp1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/InputStreamPreprocessor.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/MathMLAttributeNames.in26
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/MathMLTagNames.in12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.cpp91
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/XSSAuditorDelegate.cpp57
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/XSSAuditorDelegate.h5
48 files changed, 755 insertions, 599 deletions
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/AtomicHTMLToken.h b/chromium/third_party/WebKit/Source/core/html/parser/AtomicHTMLToken.h
index 2d74f8e1930..63e8c0c86dc 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/AtomicHTMLToken.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/AtomicHTMLToken.h
@@ -26,6 +26,7 @@
#ifndef AtomicHTMLToken_h
#define AtomicHTMLToken_h
+#include "HTMLElementLookupTrie.h"
#include "core/dom/Attribute.h"
#include "core/html/parser/CompactHTMLToken.h"
#include "core/html/parser/HTMLToken.h"
@@ -124,7 +125,10 @@ public:
case HTMLToken::StartTag:
case HTMLToken::EndTag: {
m_selfClosing = token.selfClosing();
- m_name = AtomicString(token.name());
+ if (StringImpl* tagName = lookupHTMLTag(token.name().data(), token.name().size()))
+ m_name = AtomicString(tagName);
+ else
+ m_name = AtomicString(token.name());
initializeAttributes(token.attributes());
break;
}
@@ -146,10 +150,10 @@ public:
ASSERT_NOT_REACHED();
break;
case HTMLToken::DOCTYPE:
- m_name = token.data().asString();
+ m_name = token.data();
m_doctypeData = adoptPtr(new DoctypeData());
m_doctypeData->m_hasPublicIdentifier = true;
- append(m_doctypeData->m_publicIdentifier, token.publicIdentifier().asString());
+ append(m_doctypeData->m_publicIdentifier, token.publicIdentifier());
m_doctypeData->m_hasSystemIdentifier = true;
append(m_doctypeData->m_systemIdentifier, token.systemIdentifier());
m_doctypeData->m_forceQuirks = token.doctypeForcesQuirks();
@@ -159,7 +163,7 @@ public:
case HTMLToken::StartTag:
m_attributes.reserveInitialCapacity(token.attributes().size());
for (Vector<CompactHTMLToken::Attribute>::const_iterator it = token.attributes().begin(); it != token.attributes().end(); ++it) {
- QualifiedName name(nullAtom, it->name.asString(), nullAtom);
+ QualifiedName name(nullAtom, it->name, nullAtom);
// FIXME: This is N^2 for the number of attributes.
if (!findAttributeInVector(m_attributes, name))
m_attributes.append(Attribute(name, it->value));
@@ -167,11 +171,11 @@ public:
// Fall through!
case HTMLToken::EndTag:
m_selfClosing = token.selfClosing();
- m_name = token.data().asString();
+ m_name = token.data();
break;
case HTMLToken::Character:
case HTMLToken::Comment:
- m_data = token.data().asString();
+ m_data = token.data();
break;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLInputStream.cpp b/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLInputStream.cpp
index 6f536082c63..05ccea8e021 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLInputStream.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLInputStream.cpp
@@ -31,6 +31,7 @@ namespace WebCore {
BackgroundHTMLInputStream::BackgroundHTMLInputStream()
: m_firstValidCheckpointIndex(0)
, m_firstValidSegmentIndex(0)
+ , m_totalCheckpointTokenCount(0)
{
}
@@ -45,10 +46,11 @@ void BackgroundHTMLInputStream::close()
m_current.close();
}
-HTMLInputCheckpoint BackgroundHTMLInputStream::createCheckpoint()
+HTMLInputCheckpoint BackgroundHTMLInputStream::createCheckpoint(size_t tokensExtractedSincePreviousCheckpoint)
{
HTMLInputCheckpoint checkpoint = m_checkpoints.size();
- m_checkpoints.append(Checkpoint(m_current, m_segments.size()));
+ m_checkpoints.append(Checkpoint(m_current, m_segments.size(), tokensExtractedSincePreviousCheckpoint));
+ m_totalCheckpointTokenCount += tokensExtractedSincePreviousCheckpoint;
return checkpoint;
}
@@ -70,6 +72,8 @@ void BackgroundHTMLInputStream::invalidateCheckpointsBefore(HTMLInputCheckpoint
for (size_t i = m_firstValidCheckpointIndex; i < newFirstValidCheckpointIndex; ++i)
m_checkpoints[i].clear();
m_firstValidCheckpointIndex = newFirstValidCheckpointIndex;
+
+ updateTotalCheckpointTokenCount();
}
void BackgroundHTMLInputStream::rewindTo(HTMLInputCheckpoint checkpointIndex, const String& unparsedInput)
@@ -99,6 +103,16 @@ void BackgroundHTMLInputStream::rewindTo(HTMLInputCheckpoint checkpointIndex, co
m_checkpoints.clear();
m_firstValidCheckpointIndex = 0;
m_firstValidSegmentIndex = 0;
+
+ updateTotalCheckpointTokenCount();
+}
+
+void BackgroundHTMLInputStream::updateTotalCheckpointTokenCount()
+{
+ m_totalCheckpointTokenCount = 0;
+ size_t lastCheckpointIndex = m_checkpoints.size();
+ for (size_t i = 0; i < lastCheckpointIndex; ++i)
+ m_totalCheckpointTokenCount += m_checkpoints[i].tokensExtractedSincePreviousCheckpoint;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLInputStream.h b/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLInputStream.h
index 3ffc16cba94..ba12b63e070 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLInputStream.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLInputStream.h
@@ -26,7 +26,7 @@
#ifndef BackgroundHTMLInputStream_h
#define BackgroundHTMLInputStream_h
-#include "core/platform/text/SegmentedString.h"
+#include "platform/text/SegmentedString.h"
#include "wtf/Vector.h"
#include "wtf/text/WTFString.h"
@@ -46,23 +46,24 @@ public:
// An HTMLInputCheckpoint is valid until the next call to rewindTo, at which
// point all outstanding checkpoints are invalidated.
- HTMLInputCheckpoint createCheckpoint();
+ HTMLInputCheckpoint createCheckpoint(size_t tokensExtractedSincePreviousCheckpoint);
void rewindTo(HTMLInputCheckpoint, const String& unparsedInput);
void invalidateCheckpointsBefore(HTMLInputCheckpoint);
- size_t outstandingCheckpointCount() const { return m_checkpoints.size() - m_firstValidCheckpointIndex; }
+ size_t totalCheckpointTokenCount() const { return m_totalCheckpointTokenCount; }
private:
struct Checkpoint {
- Checkpoint(const SegmentedString& i, size_t n) : input(i), numberOfSegmentsAlreadyAppended(n) { }
+ Checkpoint(const SegmentedString& i, size_t n, size_t t) : input(i), numberOfSegmentsAlreadyAppended(n), tokensExtractedSincePreviousCheckpoint(t) { }
SegmentedString input;
size_t numberOfSegmentsAlreadyAppended;
+ size_t tokensExtractedSincePreviousCheckpoint;
#ifndef NDEBUG
bool isNull() const { return input.isEmpty() && !numberOfSegmentsAlreadyAppended; }
#endif
- void clear() { input.clear(); numberOfSegmentsAlreadyAppended = 0; }
+ void clear() { input.clear(); numberOfSegmentsAlreadyAppended = 0; tokensExtractedSincePreviousCheckpoint = 0;}
};
SegmentedString m_current;
@@ -72,6 +73,9 @@ private:
// Note: These indicies may === vector.size(), in which case there are no valid checkpoints/segments at this time.
size_t m_firstValidCheckpointIndex;
size_t m_firstValidSegmentIndex;
+ size_t m_totalCheckpointTokenCount;
+
+ void updateTotalCheckpointTokenCount();
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp b/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp
index 23747edd7eb..b91dafd40b9 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp
@@ -28,7 +28,6 @@
#include "core/html/parser/HTMLDocumentParser.h"
#include "core/html/parser/HTMLParserThread.h"
-#include "core/html/parser/HTMLTokenizer.h"
#include "core/html/parser/XSSAuditor.h"
#include "wtf/MainThread.h"
#include "wtf/text/TextPosition.h"
@@ -39,14 +38,14 @@ namespace WebCore {
// with a fast CPU, we could end up speculatively tokenizing
// the whole document, well ahead of when the main-thread actually needs it.
// This is a waste of memory (and potentially time if the speculation fails).
-// So we limit our outstanding speculations arbitrarily to 10.
+// So we limit our outstanding tokens arbitrarily to 10,000.
// Our maximal memory spent speculating will be approximately:
-// outstandingCheckpointLimit * pendingTokenLimit * sizeof(CompactToken)
+// (outstandingTokenLimit + pendingTokenLimit) * sizeof(CompactToken)
// We use a separate low and high water mark to avoid constantly topping
// off the main thread's token buffer.
-// At time of writing, this is 10 * 1000 * 28 bytes = appox 280kb of memory.
+// At time of writing, this is (10000 + 1000) * 28 bytes = ~308kb of memory.
// These numbers have not been tuned.
-static const size_t outstandingCheckpointLimit = 10;
+static const size_t outstandingTokenLimit = 10000;
// We limit our chucks to 1000 tokens, to make sure the main
// thread is never waiting on the parser thread for tokens.
@@ -69,6 +68,12 @@ static void checkThatPreloadsAreSafeToSendToAnotherThread(const PreloadRequestSt
ASSERT(preloads[i]->isSafeToSendToAnotherThread());
}
+static void checkThatXSSInfosAreSafeToSendToAnotherThread(const XSSInfoStream& infos)
+{
+ for (size_t i = 0; i < infos.size(); ++i)
+ ASSERT(infos[i]->isSafeToSendToAnotherThread());
+}
+
#endif
BackgroundHTMLParser::BackgroundHTMLParser(PassRefPtr<WeakReference<BackgroundHTMLParser> > reference, PassOwnPtr<Configuration> config)
@@ -139,7 +144,7 @@ void BackgroundHTMLParser::markEndOfFile()
void BackgroundHTMLParser::pumpTokenizer()
{
// No need to start speculating until the main thread has almost caught up.
- if (m_input.outstandingCheckpointCount() > outstandingCheckpointLimit)
+ if (m_input.totalCheckpointTokenCount() > outstandingTokenLimit)
return;
while (true) {
@@ -171,7 +176,7 @@ void BackgroundHTMLParser::pumpTokenizer()
if (!m_treeBuilderSimulator.simulate(m_pendingTokens->last(), m_tokenizer.get()) || m_pendingTokens->size() >= pendingTokenLimit) {
sendTokensToMainThread();
// If we're far ahead of the main thread, yield for a bit to avoid consuming too much memory.
- if (m_input.outstandingCheckpointCount() > outstandingCheckpointLimit)
+ if (m_input.totalCheckpointTokenCount() > outstandingTokenLimit)
break;
}
}
@@ -185,16 +190,17 @@ void BackgroundHTMLParser::sendTokensToMainThread()
#ifndef NDEBUG
checkThatTokensAreSafeToSendToAnotherThread(m_pendingTokens.get());
checkThatPreloadsAreSafeToSendToAnotherThread(m_pendingPreloads);
+ checkThatXSSInfosAreSafeToSendToAnotherThread(m_pendingXSSInfos);
#endif
OwnPtr<HTMLDocumentParser::ParsedChunk> chunk = adoptPtr(new HTMLDocumentParser::ParsedChunk);
- chunk->tokens = m_pendingTokens.release();
chunk->preloads.swap(m_pendingPreloads);
chunk->xssInfos.swap(m_pendingXSSInfos);
chunk->tokenizerState = m_tokenizer->state();
chunk->treeBuilderState = m_treeBuilderSimulator.state();
- chunk->inputCheckpoint = m_input.createCheckpoint();
+ chunk->inputCheckpoint = m_input.createCheckpoint(m_pendingTokens->size());
chunk->preloadScannerCheckpoint = m_preloadScanner->createCheckpoint();
+ chunk->tokens = m_pendingTokens.release();
callOnMainThread(bind(&HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser, m_parser, chunk.release()));
m_pendingTokens = adoptPtr(new CompactHTMLTokenStream);
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp b/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp
index af3ff09d9cc..b1eea275aaa 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp
@@ -29,9 +29,8 @@
#include "core/html/parser/CSSPreloadScanner.h"
#include "FetchInitiatorTypeNames.h"
-#include "core/html/parser/HTMLIdentifier.h"
#include "core/html/parser/HTMLParserIdioms.h"
-#include "core/platform/text/SegmentedString.h"
+#include "platform/text/SegmentedString.h"
namespace WebCore {
@@ -66,16 +65,15 @@ void CSSPreloadScanner::scan(const HTMLToken::DataVector& data, const SegmentedS
scanCommon(data.data(), data.data() + data.size(), source, requests);
}
-void CSSPreloadScanner::scan(const HTMLIdentifier& identifier, const SegmentedString& source, PreloadRequestStream& requests)
+void CSSPreloadScanner::scan(const String& tagName, const SegmentedString& source, PreloadRequestStream& requests)
{
- const StringImpl* data = identifier.asStringImpl();
- if (data->is8Bit()) {
- const LChar* begin = data->characters8();
- scanCommon(begin, begin + data->length(), source, requests);
+ if (tagName.is8Bit()) {
+ const LChar* begin = tagName.characters8();
+ scanCommon(begin, begin + tagName.length(), source, requests);
return;
}
- const UChar* begin = data->characters16();
- scanCommon(begin, begin + data->length(), source, requests);
+ const UChar* begin = tagName.characters16();
+ scanCommon(begin, begin + tagName.length(), source, requests);
}
inline void CSSPreloadScanner::tokenize(UChar c, const SegmentedString& source)
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.h b/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.h
index 07e3b175d0c..7161a27434e 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.h
@@ -45,7 +45,7 @@ public:
void reset();
void scan(const HTMLToken::DataVector&, const SegmentedString&, PreloadRequestStream&);
- void scan(const HTMLIdentifier&, const SegmentedString&, PreloadRequestStream&);
+ void scan(const String&, const SegmentedString&, PreloadRequestStream&);
private:
enum State {
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/CompactHTMLToken.cpp b/chromium/third_party/WebKit/Source/core/html/parser/CompactHTMLToken.cpp
index 11c4f639e21..4a826e839b3 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/CompactHTMLToken.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/CompactHTMLToken.cpp
@@ -28,13 +28,12 @@
#include "core/dom/QualifiedName.h"
#include "core/html/parser/HTMLParserIdioms.h"
-#include "core/html/parser/HTMLToken.h"
namespace WebCore {
struct SameSizeAsCompactHTMLToken {
unsigned bitfields;
- HTMLIdentifier data;
+ String data;
Vector<Attribute> vector;
TextPosition textPosition;
};
@@ -52,10 +51,11 @@ CompactHTMLToken::CompactHTMLToken(const HTMLToken* token, const TextPosition& t
ASSERT_NOT_REACHED();
break;
case HTMLToken::DOCTYPE: {
- m_data = HTMLIdentifier(token->name(), Likely8Bit);
+ m_data = attemptStaticStringCreation(token->name(), Likely8Bit);
+
// There is only 1 DOCTYPE token per document, so to avoid increasing the
// size of CompactHTMLToken, we just use the m_attributes vector.
- m_attributes.append(Attribute(HTMLIdentifier(token->publicIdentifier(), Likely8Bit), String(token->systemIdentifier())));
+ m_attributes.append(Attribute(attemptStaticStringCreation(token->publicIdentifier(), Likely8Bit), String(token->systemIdentifier())));
m_doctypeForcesQuirks = token->forceQuirks();
break;
}
@@ -64,7 +64,7 @@ CompactHTMLToken::CompactHTMLToken(const HTMLToken* token, const TextPosition& t
case HTMLToken::StartTag:
m_attributes.reserveInitialCapacity(token->attributes().size());
for (Vector<HTMLToken::Attribute>::const_iterator it = token->attributes().begin(); it != token->attributes().end(); ++it)
- m_attributes.append(Attribute(HTMLIdentifier(it->name, Likely8Bit), StringImpl::create8BitIfPossible(it->value)));
+ m_attributes.append(Attribute(attemptStaticStringCreation(it->name, Likely8Bit), StringImpl::create8BitIfPossible(it->value)));
// Fall through!
case HTMLToken::EndTag:
m_selfClosing = token->selfClosing();
@@ -72,7 +72,7 @@ CompactHTMLToken::CompactHTMLToken(const HTMLToken* token, const TextPosition& t
case HTMLToken::Comment:
case HTMLToken::Character: {
m_isAll8BitData = token->isAll8BitData();
- m_data = HTMLIdentifier(token->data(), token->isAll8BitData() ? Force8Bit : Force16Bit);
+ m_data = attemptStaticStringCreation(token->data(), token->isAll8BitData() ? Force8Bit : Force16Bit);
break;
}
default:
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/CompactHTMLToken.h b/chromium/third_party/WebKit/Source/core/html/parser/CompactHTMLToken.h
index 89ef4ca6a02..3858e03a094 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/CompactHTMLToken.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/CompactHTMLToken.h
@@ -26,7 +26,6 @@
#ifndef CompactHTMLToken_h
#define CompactHTMLToken_h
-#include "core/html/parser/HTMLIdentifier.h"
#include "core/html/parser/HTMLToken.h"
#include "wtf/Vector.h"
#include "wtf/text/TextPosition.h"
@@ -39,13 +38,13 @@ class QualifiedName;
class CompactHTMLToken {
public:
struct Attribute {
- Attribute(const HTMLIdentifier& name, const String& value)
+ Attribute(const String& name, const String& value)
: name(name)
, value(value)
{
}
- HTMLIdentifier name;
+ String name;
String value;
};
@@ -54,7 +53,7 @@ public:
bool isSafeToSendToAnotherThread() const;
HTMLToken::Type type() const { return static_cast<HTMLToken::Type>(m_type); }
- const HTMLIdentifier& data() const { return m_data; }
+ const String& data() const { return m_data; }
bool selfClosing() const { return m_selfClosing; }
bool isAll8BitData() const { return m_isAll8BitData; }
const Vector<Attribute>& attributes() const { return m_attributes; }
@@ -63,7 +62,7 @@ public:
// There is only 1 DOCTYPE token per document, so to avoid increasing the
// size of CompactHTMLToken, we just use the m_attributes vector.
- const HTMLIdentifier& publicIdentifier() const { return m_attributes[0].name; }
+ const String& publicIdentifier() const { return m_attributes[0].name; }
const String& systemIdentifier() const { return m_attributes[0].value; }
bool doctypeForcesQuirks() const { return m_doctypeForcesQuirks; }
@@ -73,7 +72,7 @@ private:
unsigned m_isAll8BitData : 1;
unsigned m_doctypeForcesQuirks: 1;
- HTMLIdentifier m_data; // "name", "characters", or "data" depending on m_type
+ String m_data; // "name", "characters", or "data" depending on m_type
Vector<Attribute> m_attributes;
TextPosition m_textPosition;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
index 169f06711cc..96dc2484b4b 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
@@ -46,8 +46,9 @@
#include "core/html/parser/HTMLToken.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/page/Frame.h"
-#include "core/platform/NotImplemented.h"
+#include "core/frame/Frame.h"
+#include "platform/NotImplemented.h"
+#include "platform/text/TextBreakIterator.h"
#include <limits>
namespace WebCore {
@@ -82,6 +83,11 @@ static bool shouldUseLengthLimit(const ContainerNode* node)
&& !node->hasTagName(SVGNames::scriptTag);
}
+static unsigned textLengthLimitForContainer(const ContainerNode* node)
+{
+ return shouldUseLengthLimit(node) ? Text::defaultLengthLimit : std::numeric_limits<unsigned>::max();
+}
+
static inline bool isAllWhitespace(const String& string)
{
return string.isAllSpecialCharacters<isHTMLSpace<UChar> >();
@@ -93,10 +99,10 @@ static inline void insert(HTMLConstructionSiteTask& task)
task.parent = toHTMLTemplateElement(task.parent.get())->content();
if (ContainerNode* parent = task.child->parentNode())
- parent->parserRemoveChild(task.child.get());
+ parent->parserRemoveChild(*task.child);
if (task.nextChild)
- task.parent->parserInsertBefore(task.child.get(), task.nextChild.get());
+ task.parent->parserInsertBefore(task.child.get(), *task.nextChild);
else
task.parent->parserAppendChild(task.child.get());
}
@@ -113,12 +119,33 @@ static inline void executeInsertTask(HTMLConstructionSiteTask& task)
task.child->finishParsingChildren();
}
+static inline void executeInsertTextTask(HTMLConstructionSiteTask& task)
+{
+ ASSERT(task.operation == HTMLConstructionSiteTask::InsertText);
+ ASSERT(task.child->isTextNode());
+
+ // Merge text nodes into previous ones if possible:
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/tree-construction.html#insert-a-character
+ Text* newText = toText(task.child.get());
+ Node* previousChild = task.nextChild ? task.nextChild->previousSibling() : task.parent->lastChild();
+ if (previousChild && previousChild->isTextNode()) {
+ Text* previousText = toText(previousChild);
+ unsigned lengthLimit = textLengthLimitForContainer(task.parent.get());
+ if (previousText->length() + newText->length() < lengthLimit) {
+ previousText->parserAppendData(newText->data());
+ return;
+ }
+ }
+
+ insert(task);
+}
+
static inline void executeReparentTask(HTMLConstructionSiteTask& task)
{
ASSERT(task.operation == HTMLConstructionSiteTask::Reparent);
if (ContainerNode* parent = task.child->parentNode())
- parent->parserRemoveChild(task.child.get());
+ parent->parserRemoveChild(*task.child);
task.parent->parserAppendChild(task.child);
}
@@ -134,16 +161,18 @@ static inline void executeTakeAllChildrenTask(HTMLConstructionSiteTask& task)
{
ASSERT(task.operation == HTMLConstructionSiteTask::TakeAllChildren);
- task.parent->takeAllChildrenFrom(task.oldParent());
- // Notice that we don't need to manually attach the moved children
- // because takeAllChildrenFrom does that work for us.
+ task.parent->parserTakeAllChildrenFrom(*task.oldParent());
}
-static inline void executeTask(HTMLConstructionSiteTask& task)
+void HTMLConstructionSite::executeTask(HTMLConstructionSiteTask& task)
{
+ ASSERT(m_taskQueue.isEmpty());
if (task.operation == HTMLConstructionSiteTask::Insert)
return executeInsertTask(task);
+ if (task.operation == HTMLConstructionSiteTask::InsertText)
+ return executeInsertTextTask(task);
+
// All the cases below this point are only used by the adoption agency.
if (task.operation == HTMLConstructionSiteTask::InsertAlreadyParsedChild)
@@ -158,6 +187,88 @@ static inline void executeTask(HTMLConstructionSiteTask& task)
ASSERT_NOT_REACHED();
}
+// This is only needed for TextDocuments where we might have text nodes
+// approaching the default length limit (~64k) and we don't want to
+// break a text node in the middle of a combining character.
+static unsigned findBreakIndexBetween(const StringBuilder& string, unsigned currentPosition, unsigned proposedBreakIndex)
+{
+ ASSERT(currentPosition < proposedBreakIndex);
+ ASSERT(proposedBreakIndex <= string.length());
+ // The end of the string is always a valid break.
+ if (proposedBreakIndex == string.length())
+ return proposedBreakIndex;
+
+ // Latin-1 does not have breakable boundaries. If we ever moved to a differnet 8-bit encoding this could be wrong.
+ if (string.is8Bit())
+ return proposedBreakIndex;
+
+ const UChar* breakSearchCharacters = string.characters16() + currentPosition;
+ // We need at least two characters look-ahead to account for UTF-16 surrogates, but can't search off the end of the buffer!
+ unsigned breakSearchLength = std::min(proposedBreakIndex - currentPosition + 2, string.length() - currentPosition);
+ NonSharedCharacterBreakIterator it(breakSearchCharacters, breakSearchLength);
+
+ if (it.isBreak(proposedBreakIndex - currentPosition))
+ return proposedBreakIndex;
+
+ int adjustedBreakIndexInSubstring = it.preceding(proposedBreakIndex - currentPosition);
+ if (adjustedBreakIndexInSubstring > 0)
+ return currentPosition + adjustedBreakIndexInSubstring;
+ // We failed to find a breakable point, let the caller figure out what to do.
+ return 0;
+}
+
+static String atomizeIfAllWhitespace(const String& string, WhitespaceMode whitespaceMode)
+{
+ // Strings composed entirely of whitespace are likely to be repeated.
+ // Turn them into AtomicString so we share a single string for each.
+ if (whitespaceMode == AllWhitespace || (whitespaceMode == WhitespaceUnknown && isAllWhitespace(string)))
+ return AtomicString(string).string();
+ return string;
+}
+
+void HTMLConstructionSite::flushPendingText()
+{
+ if (m_pendingText.isEmpty())
+ return;
+
+ PendingText pendingText;
+ // Hold onto the current pending text on the stack so that queueTask doesn't recurse infinitely.
+ m_pendingText.swap(pendingText);
+ ASSERT(m_pendingText.isEmpty());
+
+ // Splitting text nodes into smaller chunks contradicts HTML5 spec, but is necessary
+ // for performance, see: https://bugs.webkit.org/show_bug.cgi?id=55898
+ unsigned lengthLimit = textLengthLimitForContainer(pendingText.parent.get());
+
+ unsigned currentPosition = 0;
+ const StringBuilder& string = pendingText.stringBuilder;
+ while (currentPosition < string.length()) {
+ unsigned proposedBreakIndex = std::min(currentPosition + lengthLimit, string.length());
+ unsigned breakIndex = findBreakIndexBetween(string, currentPosition, proposedBreakIndex);
+ ASSERT(breakIndex <= string.length());
+ String substring = string.substring(currentPosition, breakIndex - currentPosition);
+ substring = atomizeIfAllWhitespace(substring, pendingText.whitespaceMode);
+
+ HTMLConstructionSiteTask task(HTMLConstructionSiteTask::InsertText);
+ task.parent = pendingText.parent;
+ task.nextChild = pendingText.nextChild;
+ task.child = Text::create(task.parent->document(), substring);
+ queueTask(task);
+
+ ASSERT(breakIndex > currentPosition);
+ ASSERT(breakIndex - currentPosition == substring.length());
+ ASSERT(toText(task.child.get())->length() == substring.length());
+ currentPosition = breakIndex;
+ }
+}
+
+void HTMLConstructionSite::queueTask(const HTMLConstructionSiteTask& task)
+{
+ flushPendingText();
+ ASSERT(m_pendingText.isEmpty());
+ m_taskQueue.append(task);
+}
+
void HTMLConstructionSite::attachLater(ContainerNode* parent, PassRefPtr<Node> prpChild, bool selfClosing)
{
ASSERT(scriptingContentIsAllowed(m_parserContentPolicy) || !prpChild.get()->isElementNode() || !toScriptLoaderIfPossible(toElement(prpChild.get())));
@@ -178,11 +289,13 @@ void HTMLConstructionSite::attachLater(ContainerNode* parent, PassRefPtr<Node> p
task.parent = task.parent->parentNode();
ASSERT(task.parent);
- m_taskQueue.append(task);
+ queueTask(task);
}
void HTMLConstructionSite::executeQueuedTasks()
{
+ // This has no affect on pendingText, and we may have pendingText
+ // remaining after executing all other queued tasks.
const size_t size = m_taskQueue.size();
if (!size)
return;
@@ -222,10 +335,20 @@ HTMLConstructionSite::HTMLConstructionSite(DocumentFragment* fragment, ParserCon
HTMLConstructionSite::~HTMLConstructionSite()
{
+ // Depending on why we're being destroyed it might be OK
+ // to forget queued tasks, but currently we don't expect to.
+ ASSERT(m_taskQueue.isEmpty());
+ // Currently we assume that text will never be the last token in the
+ // document and that we'll always queue some additional task to cause it to flush.
+ ASSERT(m_pendingText.isEmpty());
}
void HTMLConstructionSite::detach()
{
+ // FIXME: We'd like to ASSERT here that we're canceling and not just discarding
+ // text that really should have made it into the DOM earlier, but there
+ // doesn't seem to be a nice way to do that.
+ m_pendingText.discard();
m_document = 0;
m_attachmentRoot = 0;
}
@@ -246,7 +369,7 @@ void HTMLConstructionSite::dispatchDocumentElementAvailableIfNeeded()
{
ASSERT(m_document);
if (m_document->frame() && !m_isParsingFragment)
- m_document->frame()->loader()->dispatchDocumentElementAvailable();
+ m_document->frame()->loader().dispatchDocumentElementAvailable();
}
void HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken* token)
@@ -392,8 +515,18 @@ void HTMLConstructionSite::setCompatibilityModeFromDoctype(const String& name, c
setCompatibilityMode(Document::NoQuirksMode);
}
+void HTMLConstructionSite::processEndOfFile()
+{
+ ASSERT(currentNode());
+ flush();
+ openElements()->popAll();
+}
+
void HTMLConstructionSite::finishedParsing()
{
+ // We shouldn't have any queued tasks but we might have pending text which we need to promote to tasks and execute.
+ ASSERT(m_taskQueue.isEmpty());
+ flush();
m_document->finishedParsing();
}
@@ -457,7 +590,7 @@ void HTMLConstructionSite::insertHTMLBodyElement(AtomicHTMLToken* token)
attachLater(currentNode(), body);
m_openElements.pushHTMLBodyElement(HTMLStackItem::create(body.release(), token));
if (Frame* frame = m_document->frame())
- frame->loader()->client()->dispatchWillInsertBody();
+ frame->loader().client()->dispatchWillInsertBody();
}
void HTMLConstructionSite::insertHTMLFormElement(AtomicHTMLToken* token, bool isDemoted)
@@ -506,7 +639,7 @@ void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken* token)
// those flags or effects thereof.
const bool parserInserted = m_parserContentPolicy != AllowScriptingContentAndDoNotMarkAlreadyStarted;
const bool alreadyStarted = m_isParsingFragment && parserInserted;
- RefPtr<HTMLScriptElement> element = HTMLScriptElement::create(scriptTag, ownerDocumentForCurrentNode(), parserInserted, alreadyStarted);
+ RefPtr<HTMLScriptElement> element = HTMLScriptElement::create(ownerDocumentForCurrentNode(), parserInserted, alreadyStarted);
setAttributes(element.get(), token, m_parserContentPolicy);
if (scriptingContentIsAllowed(m_parserContentPolicy))
attachLater(currentNode(), element);
@@ -525,49 +658,24 @@ void HTMLConstructionSite::insertForeignElement(AtomicHTMLToken* token, const At
m_openElements.push(HTMLStackItem::create(element.release(), token, namespaceURI));
}
-void HTMLConstructionSite::insertTextNode(const String& characters, WhitespaceMode whitespaceMode)
+void HTMLConstructionSite::insertTextNode(const String& string, WhitespaceMode whitespaceMode)
{
- HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert);
- task.parent = currentNode();
+ HTMLConstructionSiteTask dummyTask(HTMLConstructionSiteTask::Insert);
+ dummyTask.parent = currentNode();
if (shouldFosterParent())
- findFosterSite(task);
-
- if (task.parent->hasTagName(templateTag))
- task.parent = toHTMLTemplateElement(task.parent.get())->content();
+ findFosterSite(dummyTask);
- // Strings composed entirely of whitespace are likely to be repeated.
- // Turn them into AtomicString so we share a single string for each.
- bool shouldUseAtomicString = whitespaceMode == AllWhitespace
- || (whitespaceMode == WhitespaceUnknown && isAllWhitespace(characters));
+ // FIXME: This probably doesn't need to be done both here and in insert(Task).
+ if (dummyTask.parent->hasTagName(templateTag))
+ dummyTask.parent = toHTMLTemplateElement(dummyTask.parent.get())->content();
- unsigned currentPosition = 0;
- unsigned lengthLimit = shouldUseLengthLimit(task.parent.get()) ? Text::defaultLengthLimit : std::numeric_limits<unsigned>::max();
-
- // FIXME: Splitting text nodes into smaller chunks contradicts HTML5 spec, but is currently necessary
- // for performance, see <https://bugs.webkit.org/show_bug.cgi?id=55898>.
-
- Node* previousChild = task.nextChild ? task.nextChild->previousSibling() : task.parent->lastChild();
- if (previousChild && previousChild->isTextNode()) {
- // FIXME: We're only supposed to append to this text node if it
- // was the last text node inserted by the parser.
- currentPosition = toCharacterData(previousChild)->parserAppendData(characters, 0, lengthLimit);
- }
-
- while (currentPosition < characters.length()) {
- RefPtr<Text> textNode = Text::createWithLengthLimit(task.parent->document(), shouldUseAtomicString ? AtomicString(characters).string() : characters, currentPosition, lengthLimit);
- // If we have a whole string of unbreakable characters the above could lead to an infinite loop. Exceeding the length limit is the lesser evil.
- if (!textNode->length()) {
- String substring = characters.substring(currentPosition);
- textNode = Text::create(task.parent->document(), shouldUseAtomicString ? AtomicString(substring).string() : substring);
- }
-
- currentPosition += textNode->length();
- ASSERT(currentPosition <= characters.length());
- task.child = textNode.release();
-
- executeTask(task);
- }
+ // Unclear when parent != case occurs. Somehow we insert text into two separate nodes while processing the same Token.
+ // The nextChild != dummy.nextChild case occurs whenever foster parenting happened and we hit a new text node "<table>a</table>b"
+ // In either case we have to flush the pending text into the task queue before making more.
+ if (!m_pendingText.isEmpty() && (m_pendingText.parent != dummyTask.parent || m_pendingText.nextChild != dummyTask.nextChild))
+ flushPendingText();
+ m_pendingText.append(dummyTask.parent, dummyTask.nextChild, string, whitespaceMode);
}
void HTMLConstructionSite::reparent(HTMLElementStack::ElementRecord* newParent, HTMLElementStack::ElementRecord* child)
@@ -575,7 +683,7 @@ void HTMLConstructionSite::reparent(HTMLElementStack::ElementRecord* newParent,
HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Reparent);
task.parent = newParent->node();
task.child = child->node();
- m_taskQueue.append(task);
+ queueTask(task);
}
void HTMLConstructionSite::reparent(HTMLElementStack::ElementRecord* newParent, HTMLStackItem* child)
@@ -583,7 +691,7 @@ void HTMLConstructionSite::reparent(HTMLElementStack::ElementRecord* newParent,
HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Reparent);
task.parent = newParent->node();
task.child = child->node();
- m_taskQueue.append(task);
+ queueTask(task);
}
void HTMLConstructionSite::insertAlreadyParsedChild(HTMLStackItem* newParent, HTMLElementStack::ElementRecord* child)
@@ -596,7 +704,7 @@ void HTMLConstructionSite::insertAlreadyParsedChild(HTMLStackItem* newParent, HT
HTMLConstructionSiteTask task(HTMLConstructionSiteTask::InsertAlreadyParsedChild);
task.parent = newParent->node();
task.child = child->node();
- m_taskQueue.append(task);
+ queueTask(task);
}
void HTMLConstructionSite::takeAllChildren(HTMLStackItem* newParent, HTMLElementStack::ElementRecord* oldParent)
@@ -604,7 +712,7 @@ void HTMLConstructionSite::takeAllChildren(HTMLStackItem* newParent, HTMLElement
HTMLConstructionSiteTask task(HTMLConstructionSiteTask::TakeAllChildren);
task.parent = newParent->node();
task.child = oldParent->node();
- m_taskQueue.append(task);
+ queueTask(task);
}
PassRefPtr<Element> HTMLConstructionSite::createElement(AtomicHTMLToken* token, const AtomicString& namespaceURI)
@@ -624,7 +732,6 @@ inline Document& HTMLConstructionSite::ownerDocumentForCurrentNode()
PassRefPtr<Element> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* token)
{
- QualifiedName tagName(nullAtom, token->name(), xhtmlNamespaceURI);
Document& document = ownerDocumentForCurrentNode();
// Only associate the element with the current form if we're creating the new element
// in a document with a browsing context (rather than in <template> contents).
@@ -632,7 +739,7 @@ PassRefPtr<Element> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* tok
// FIXME: This can't use HTMLConstructionSite::createElement because we
// have to pass the current form element. We should rework form association
// to occur after construction to allow better code sharing here.
- RefPtr<Element> element = HTMLElementFactory::createHTMLElement(tagName, &document, form, true);
+ RefPtr<Element> element = HTMLElementFactory::createHTMLElement(token->name(), document, form, true);
setAttributes(element.get(), token, m_parserContentPolicy);
ASSERT(element->isHTMLElement());
return element.release();
@@ -746,8 +853,7 @@ void HTMLConstructionSite::fosterParent(PassRefPtr<Node> node)
findFosterSite(task);
task.child = node;
ASSERT(task.parent);
-
- m_taskQueue.append(task);
+ queueTask(task);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h
index ba03ce72d34..d4d812eb109 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h
@@ -34,13 +34,15 @@
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
#include "wtf/Vector.h"
+#include "wtf/text/StringBuilder.h"
namespace WebCore {
struct HTMLConstructionSiteTask {
enum Operation {
Insert,
- InsertAlreadyParsedChild,
+ InsertText, // Handles possible merging of text nodes.
+ InsertAlreadyParsedChild, // Insert w/o calling begin/end parsing.
Reparent,
TakeAllChildren,
};
@@ -74,10 +76,12 @@ template<> struct VectorTraits<WebCore::HTMLConstructionSiteTask> : SimpleClassV
namespace WebCore {
+// Note: These are intentionally ordered so that when we concatonate
+// strings and whitespaces the resulting whitespace is ws = min(ws1, ws2).
enum WhitespaceMode {
- AllWhitespace,
+ WhitespaceUnknown,
NotAllWhitespace,
- WhitespaceUnknown
+ AllWhitespace,
};
class AtomicHTMLToken;
@@ -93,9 +97,31 @@ public:
~HTMLConstructionSite();
void detach();
+
+ // executeQueuedTasks empties the queue but does not flush pending text.
+ // NOTE: Possible reentrancy via JavaScript execution.
void executeQueuedTasks();
+ // flushPendingText turns pending text into queued Text insertions, but does not execute them.
+ void flushPendingText();
+
+ // Called before every token in HTMLTreeBuilder::processToken, thus inlined:
+ void flush()
+ {
+ if (!hasPendingTasks())
+ return;
+ flushPendingText();
+ executeQueuedTasks(); // NOTE: Possible reentrancy via JavaScript execution.
+ ASSERT(!hasPendingTasks());
+ }
+
+ bool hasPendingTasks()
+ {
+ return !m_pendingText.isEmpty() || !m_taskQueue.isEmpty();
+ }
+
void setDefaultCompatibilityMode();
+ void processEndOfFile();
void finishedParsing();
void insertDoctype(AtomicHTMLToken*);
@@ -195,6 +221,9 @@ private:
void mergeAttributesFromTokenIntoElement(AtomicHTMLToken*, Element*);
void dispatchDocumentElementAvailableIfNeeded();
+ void executeTask(HTMLConstructionSiteTask&);
+ void queueTask(const HTMLConstructionSiteTask&);
+
Document* m_document;
// This is the root ContainerNode to which the parser attaches all newly
@@ -209,6 +238,53 @@ private:
TaskQueue m_taskQueue;
+ struct PendingText {
+ PendingText()
+ : whitespaceMode(WhitespaceUnknown)
+ {
+ }
+
+ void append(PassRefPtr<ContainerNode> newParent, PassRefPtr<Node> newNextChild, const String& newString, WhitespaceMode newWhitespaceMode)
+ {
+ ASSERT(!parent || parent == newParent);
+ parent = newParent;
+ ASSERT(!nextChild || nextChild == newNextChild);
+ nextChild = newNextChild;
+ stringBuilder.append(newString);
+ whitespaceMode = std::min(whitespaceMode, newWhitespaceMode);
+ }
+
+ void swap(PendingText& other)
+ {
+ std::swap(whitespaceMode, other.whitespaceMode);
+ parent.swap(other.parent);
+ nextChild.swap(other.nextChild);
+ stringBuilder.swap(other.stringBuilder);
+ }
+
+ void discard()
+ {
+ PendingText discardedText;
+ swap(discardedText);
+ }
+
+ bool isEmpty()
+ {
+ // When the stringbuilder is empty, the parent and whitespace should also be "empty".
+ ASSERT(stringBuilder.isEmpty() == !parent);
+ ASSERT(!stringBuilder.isEmpty() || !nextChild);
+ ASSERT(!stringBuilder.isEmpty() || (whitespaceMode == WhitespaceUnknown));
+ return stringBuilder.isEmpty();
+ }
+
+ RefPtr<ContainerNode> parent;
+ RefPtr<Node> nextChild;
+ StringBuilder stringBuilder;
+ WhitespaceMode whitespaceMode;
+ };
+
+ PendingText m_pendingText;
+
ParserContentPolicy m_parserContentPolicy;
bool m_isParsingFragment;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
index e377ee67132..2008ae5f0e1 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
@@ -32,17 +32,13 @@
#include "core/html/HTMLDocument.h"
#include "core/html/parser/AtomicHTMLToken.h"
#include "core/html/parser/BackgroundHTMLParser.h"
-#include "core/html/parser/CompactHTMLToken.h"
-#include "core/html/parser/HTMLIdentifier.h"
#include "core/html/parser/HTMLParserScheduler.h"
#include "core/html/parser/HTMLParserThread.h"
-#include "core/html/parser/HTMLPreloadScanner.h"
#include "core/html/parser/HTMLScriptRunner.h"
-#include "core/html/parser/HTMLTokenizer.h"
#include "core/html/parser/HTMLTreeBuilder.h"
#include "core/inspector/InspectorInstrumentation.h"
-#include "core/page/Frame.h"
-#include "core/platform/chromium/TraceEvent.h"
+#include "core/frame/Frame.h"
+#include "platform/TraceEvent.h"
#include "wtf/Functional.h"
namespace WebCore {
@@ -288,7 +284,7 @@ bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& ses
// parser to stop parsing cleanly. The problem is we're not
// perpared to do that at every point where we run JavaScript.
if (!isParsingFragment()
- && document()->frame() && document()->frame()->navigationScheduler()->locationChangePending())
+ && document()->frame() && document()->frame()->navigationScheduler().locationChangePending())
return false;
if (mode == AllowYield)
@@ -299,6 +295,8 @@ bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& ses
void HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(PassOwnPtr<ParsedChunk> chunk)
{
+ TRACE_EVENT0("webkit", "HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser");
+
// alert(), runModalDialog, and the JavaScript Debugger all run nested event loops
// which can cause this method to be re-entered. We detect re-entry using
// hasActiveParser(), save the chunk as a speculation, and return.
@@ -378,6 +376,8 @@ void HTMLDocumentParser::discardSpeculationsAndResumeFrom(PassOwnPtr<ParsedChunk
void HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<ParsedChunk> popChunk)
{
+ TRACE_EVENT0("webkit", "HTMLDocumentParser::processParsedChunkFromBackgroundParser");
+
ASSERT_WITH_SECURITY_IMPLICATION(!document()->activeParserCount());
ASSERT(!isParsingFragment());
ASSERT(!isWaitingForScripts());
@@ -407,7 +407,7 @@ void HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Parse
ASSERT(!isWaitingForScripts());
if (!isParsingFragment()
- && document()->frame() && document()->frame()->navigationScheduler()->locationChangePending()) {
+ && document()->frame() && document()->frame()->navigationScheduler().locationChangePending()) {
// To match main-thread parser behavior (which never checks locationChangePending on the EOF path)
// we peek to see if this chunk has an EOF and process it anyway.
@@ -553,6 +553,12 @@ void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
if (isStopped())
return;
+ // There should only be PendingText left since the tree-builder always flushes
+ // the task queue before returning. In case that ever changes, crash.
+ if (mode == ForceSynchronous)
+ m_treeBuilder->flush();
+ RELEASE_ASSERT(!isStopped());
+
if (session.needsYield)
m_parserScheduler->scheduleForResume();
@@ -614,6 +620,8 @@ void HTMLDocumentParser::insert(const SegmentedString& source)
if (isStopped())
return;
+ TRACE_EVENT0("webkit", "HTMLDocumentParser::insert");
+
// pumpTokenizer can cause this parser to be detached from the Document,
// but we need to ensure it isn't deleted yet.
RefPtr<HTMLDocumentParser> protect(this);
@@ -649,8 +657,6 @@ void HTMLDocumentParser::startBackgroundParser()
ASSERT(!m_haveBackgroundParser);
m_haveBackgroundParser = true;
- HTMLIdentifier::init();
-
RefPtr<WeakReference<BackgroundHTMLParser> > reference = WeakReference<BackgroundHTMLParser>::createUnbound();
m_backgroundParser = WeakPtr<BackgroundHTMLParser>(reference);
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h
index 4b3be11a9a8..40779561ad3 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h
@@ -29,6 +29,7 @@
#include "core/dom/ParserContentPolicy.h"
#include "core/dom/ScriptableDocumentParser.h"
#include "core/fetch/ResourceClient.h"
+#include "core/frame/UseCounter.h"
#include "core/html/parser/BackgroundHTMLInputStream.h"
#include "core/html/parser/CompactHTMLToken.h"
#include "core/html/parser/HTMLInputStream.h"
@@ -41,7 +42,7 @@
#include "core/html/parser/HTMLTreeBuilderSimulator.h"
#include "core/html/parser/XSSAuditor.h"
#include "core/html/parser/XSSAuditorDelegate.h"
-#include "core/platform/text/SegmentedString.h"
+#include "platform/text/SegmentedString.h"
#include "wtf/Deque.h"
#include "wtf/OwnPtr.h"
#include "wtf/WeakPtr.h"
@@ -96,6 +97,8 @@ public:
};
void didReceiveParsedChunkFromBackgroundParser(PassOwnPtr<ParsedChunk>);
+ UseCounter* useCounter() { return UseCounter::getFrom(contextForParsingSession()); }
+
protected:
virtual void insert(const SegmentedString&) OVERRIDE;
virtual void append(PassRefPtr<StringImpl>) OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.cpp
index 1a8227c9fdc..9adfdf1612c 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.cpp
@@ -34,7 +34,6 @@
#include "core/html/HTMLHtmlElement.h"
#include "core/html/HTMLOptGroupElement.h"
#include "core/html/HTMLTableElement.h"
-#include "wtf/PassOwnPtr.h"
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityParser.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityParser.h
index 12499c76c93..ed5d7e6652e 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityParser.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityParser.h
@@ -27,7 +27,7 @@
#ifndef HTMLEntityParser_h
#define HTMLEntityParser_h
-#include "core/platform/text/SegmentedString.h"
+#include "platform/text/SegmentedString.h"
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLIdentifier.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLIdentifier.cpp
deleted file mode 100644
index d12ea6a955c..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLIdentifier.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2013 Google, Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/html/parser/HTMLIdentifier.h"
-
-#include "HTMLNames.h"
-#include "wtf/HashMap.h"
-#include "wtf/MainThread.h"
-#include "wtf/text/StringHash.h"
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-typedef HashMap<unsigned, StringImpl*, AlreadyHashed> IdentifierTable;
-
-unsigned HTMLIdentifier::maxNameLength = 0;
-
-static IdentifierTable& identifierTable()
-{
- DEFINE_STATIC_LOCAL(IdentifierTable, table, ());
- ASSERT(isMainThread() || !table.isEmpty());
- return table;
-}
-
-#ifndef NDEBUG
-bool HTMLIdentifier::isKnown(const StringImpl* string)
-{
- const IdentifierTable& table = identifierTable();
- return table.contains(string->hash());
-}
-#endif
-
-StringImpl* HTMLIdentifier::findIfKnown(const UChar* characters, unsigned length)
-{
- // We don't need to try hashing if we know the string is too long.
- if (length > maxNameLength)
- return 0;
- // computeHashAndMaskTop8Bits is the function StringImpl::hash() uses.
- unsigned hash = StringHasher::computeHashAndMaskTop8Bits(characters, length);
- const IdentifierTable& table = identifierTable();
- ASSERT(!table.isEmpty());
-
- IdentifierTable::const_iterator it = table.find(hash);
- if (it == table.end())
- return 0;
- // It's possible to have hash collisions between arbitrary strings and
- // known identifiers (e.g. "bvvfg" collides with "script").
- // However ASSERTs in addNames() guard against there ever being collisions
- // between known identifiers.
- if (!equal(it->value, characters, length))
- return 0;
- return it->value;
-}
-
-const unsigned kHTMLNamesIndexOffset = 0;
-const unsigned kHTMLAttrsIndexOffset = 1000;
-COMPILE_ASSERT(kHTMLAttrsIndexOffset > HTMLTagsCount, kHTMLAttrsIndexOffset_should_be_larger_than_HTMLTagsCount);
-
-const String& HTMLIdentifier::asString() const
-{
- ASSERT(isMainThread());
- return m_string;
-}
-
-const StringImpl* HTMLIdentifier::asStringImpl() const
-{
- return m_string.impl();
-}
-
-void HTMLIdentifier::addNames(QualifiedName** names, unsigned namesCount, unsigned indexOffset)
-{
- IdentifierTable& table = identifierTable();
- for (unsigned i = 0; i < namesCount; ++i) {
- StringImpl* name = names[i]->localName().impl();
- unsigned hash = name->hash();
- IdentifierTable::AddResult addResult = table.add(hash, name);
- maxNameLength = std::max(maxNameLength, name->length());
- // Ensure we're using the same hashing algorithm to get and set.
- ASSERT_UNUSED(addResult, !addResult.isNewEntry || HTMLIdentifier::findIfKnown(String(name).charactersWithNullTermination().data(), name->length()) == name);
- // We expect some hash collisions, but only for identical strings.
- // Since all of these names are AtomicStrings pointers should be equal.
- // Note: If you hit this ASSERT, then we had a hash collision among
- // HTMLNames strings, and we need to re-design how we use this hash!
- ASSERT_UNUSED(addResult, !addResult.isNewEntry || name == addResult.iterator->value);
- }
-}
-
-void HTMLIdentifier::init()
-{
- ASSERT(isMainThread()); // Not technically necessary, but this is our current expected usage.
- static bool isInitialized = false;
- if (isInitialized)
- return;
- isInitialized = true;
-
- // FIXME: We should atomize small whitespace (\n, \n\n, etc.)
- addNames(getHTMLTags(), HTMLTagsCount, kHTMLNamesIndexOffset);
- addNames(getHTMLAttrs(), HTMLAttrsCount, kHTMLAttrsIndexOffset);
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLIdentifier.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLIdentifier.h
deleted file mode 100644
index 1aec5f7d7d7..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLIdentifier.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2013 Google, Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTMLIdentifier_h
-#define HTMLIdentifier_h
-
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-class QualifiedName;
-
-enum CharacterWidth {
- Likely8Bit,
- Force8Bit,
- Force16Bit
-};
-
-class HTMLIdentifier {
-public:
- HTMLIdentifier() { }
-
- template<size_t inlineCapacity>
- HTMLIdentifier(const Vector<UChar, inlineCapacity>& vector, CharacterWidth width)
- : m_string(findIfKnown(vector.data(), vector.size()))
- {
- if (m_string.impl())
- return;
- if (width == Likely8Bit)
- m_string = StringImpl::create8BitIfPossible(vector);
- else if (width == Force8Bit)
- m_string = String::make8BitFrom16BitSource(vector);
- else
- m_string = String(vector);
- }
-
- // asString should only be used on the main thread.
- const String& asString() const;
- // asStringImpl() is safe to call from any thread.
- const StringImpl* asStringImpl() const;
-
- static void init();
-
- bool isSafeToSendToAnotherThread() const { return m_string.isSafeToSendToAnotherThread(); }
-
-#ifndef NDEBUG
- static bool isKnown(const StringImpl*);
-#endif
-
-private:
- static unsigned maxNameLength;
- static StringImpl* findIfKnown(const UChar* characters, unsigned length);
- static void addNames(QualifiedName** names, unsigned namesCount, unsigned indexOffset);
-
- String m_string;
-};
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLInputStream.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLInputStream.h
index c7acd97d9ef..a121b131f12 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLInputStream.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLInputStream.h
@@ -27,7 +27,7 @@
#define HTMLInputStream_h
#include "core/html/parser/InputStreamPreprocessor.h"
-#include "core/platform/text/SegmentedString.h"
+#include "platform/text/SegmentedString.h"
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.cpp
index 7f3c34d8905..038c8a1e5fb 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.cpp
@@ -30,7 +30,6 @@
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/parser/HTMLParserOptions.h"
#include "core/html/parser/HTMLTokenizer.h"
-#include "wtf/text/TextCodec.h"
#include "wtf/text/TextEncodingRegistry.h"
#include "wtf/text/WTFString.h"
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.h
index 5ee8862ccd9..3393fca40d2 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.h
@@ -27,7 +27,7 @@
#define HTMLMetaCharsetParser_h
#include "core/html/parser/HTMLToken.h"
-#include "core/platform/text/SegmentedString.h"
+#include "platform/text/SegmentedString.h"
#include "wtf/Noncopyable.h"
#include "wtf/text/TextCodec.h"
#include "wtf/text/TextEncoding.h"
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.cpp
index 493627c1417..f538c54cc5b 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.cpp
@@ -26,12 +26,10 @@
#include "core/html/parser/HTMLParserIdioms.h"
#include <limits>
-#include "core/dom/QualifiedName.h"
-#include "core/html/parser/HTMLIdentifier.h"
-#include "core/platform/Decimal.h"
#include "wtf/MathExtras.h"
#include "wtf/text/AtomicString.h"
#include "wtf/text/StringBuilder.h"
+#include "wtf/text/StringHash.h"
namespace WebCore {
@@ -115,11 +113,6 @@ Decimal parseToDecimalForNumberType(const String& string, const Decimal& fallbac
return value.isZero() ? Decimal(0) : value;
}
-Decimal parseToDecimalForNumberType(const String& string)
-{
- return parseToDecimalForNumberType(string, Decimal::nan());
-}
-
double parseToDoubleForNumberType(const String& string, double fallbackValue)
{
// See HTML5 2.5.4.3 `Real numbers.'
@@ -147,11 +140,6 @@ double parseToDoubleForNumberType(const String& string, double fallbackValue)
return value ? value : 0;
}
-double parseToDoubleForNumberType(const String& string)
-{
- return parseToDoubleForNumberType(string, std::numeric_limits<double>::quiet_NaN());
-}
-
template <typename CharacterType>
static bool parseHTMLIntegerInternal(const CharacterType* position, const CharacterType* end, int& value)
{
@@ -291,9 +279,31 @@ bool threadSafeMatch(const QualifiedName& a, const QualifiedName& b)
return threadSafeEqual(a.localName().impl(), b.localName().impl());
}
-bool threadSafeMatch(const HTMLIdentifier& localName, const QualifiedName& qName)
+bool threadSafeMatch(const String& localName, const QualifiedName& qName)
+{
+ return threadSafeEqual(localName.impl(), qName.localName().impl());
+}
+
+StringImpl* findStringIfStatic(const UChar* characters, unsigned length)
{
- return threadSafeEqual(localName.asStringImpl(), qName.localName().impl());
+ // We don't need to try hashing if we know the string is too long.
+ if (length > StringImpl::highestStaticStringLength())
+ return 0;
+ // computeHashAndMaskTop8Bits is the function StringImpl::hash() uses.
+ unsigned hash = StringHasher::computeHashAndMaskTop8Bits(characters, length);
+ const WTF::StaticStringsTable& table = StringImpl::allStaticStrings();
+ ASSERT(!table.isEmpty());
+
+ WTF::StaticStringsTable::const_iterator it = table.find(hash);
+ if (it == table.end())
+ return 0;
+ // It's possible to have hash collisions between arbitrary strings and
+ // known identifiers (e.g. "bvvfg" collides with "script").
+ // However ASSERTs in StringImpl::createStatic guard against there ever being collisions
+ // between static strings.
+ if (!equal(it->value, characters, length))
+ return 0;
+ return it->value;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.h
index 5c3e9df9e84..16fd3eebe3c 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.h
@@ -26,14 +26,12 @@
#define HTMLParserIdioms_h
#include "core/dom/QualifiedName.h"
-#include "core/html/parser/HTMLIdentifier.h"
+#include "platform/Decimal.h"
#include "wtf/Forward.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
-class Decimal;
-
// Space characters as defined by the HTML specification.
bool isHTMLSpace(UChar);
bool isHTMLLineBreak(UChar);
@@ -54,10 +52,8 @@ String serializeForNumberType(double);
// Convert the specified string to a decimal/double. If the conversion fails, the return value is fallback value or NaN if not specified.
// Leading or trailing illegal characters cause failure, as does passing an empty string.
// The double* parameter may be 0 to check if the string can be parsed without getting the result.
-Decimal parseToDecimalForNumberType(const String&);
-Decimal parseToDecimalForNumberType(const String&, const Decimal& fallbackValue);
-double parseToDoubleForNumberType(const String&);
-double parseToDoubleForNumberType(const String&, double fallbackValue);
+Decimal parseToDecimalForNumberType(const String&, const Decimal& fallbackValue = Decimal::nan());
+double parseToDoubleForNumberType(const String&, double fallbackValue = std::numeric_limits<double>::quiet_NaN());
// http://www.whatwg.org/specs/web-apps/current-work/#rules-for-parsing-integers
bool parseHTMLInteger(const String&, int&);
@@ -101,15 +97,31 @@ inline bool isNotHTMLSpace(CharType character)
}
bool threadSafeMatch(const QualifiedName&, const QualifiedName&);
-bool threadSafeMatch(const HTMLIdentifier&, const QualifiedName&);
-inline bool threadSafeHTMLNamesMatch(const HTMLIdentifier& tagName, const QualifiedName& qName)
+bool threadSafeMatch(const String&, const QualifiedName&);
+
+StringImpl* findStringIfStatic(const UChar* characters, unsigned length);
+
+enum CharacterWidth {
+ Likely8Bit,
+ Force8Bit,
+ Force16Bit
+};
+
+template<size_t inlineCapacity>
+static String attemptStaticStringCreation(const Vector<UChar, inlineCapacity>& vector, CharacterWidth width)
{
- // When the QualifiedName is known to HTMLIdentifier,
- // all we have to do is a pointer compare.
- ASSERT(HTMLIdentifier::isKnown(qName.localName().impl()));
- return tagName.asStringImpl() == qName.localName().impl();
+ String string(findStringIfStatic(vector.data(), vector.size()));
+ if (string.impl())
+ return string;
+ if (width == Likely8Bit)
+ string = StringImpl::create8BitIfPossible(vector);
+ else if (width == Force8Bit)
+ string = String::make8BitFrom16BitSource(vector);
+ else
+ string = String(vector);
+
+ return string;
}
}
-
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserOptions.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserOptions.cpp
index 3ed04906ffe..98ceb68461d 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserOptions.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserOptions.cpp
@@ -29,16 +29,16 @@
#include "bindings/v8/ScriptController.h"
#include "core/dom/Document.h"
#include "core/loader/FrameLoader.h"
-#include "core/page/Frame.h"
-#include "core/page/Settings.h"
+#include "core/frame/Frame.h"
+#include "core/frame/Settings.h"
namespace WebCore {
HTMLParserOptions::HTMLParserOptions(Document* document)
{
Frame* frame = document ? document->frame() : 0;
- scriptEnabled = frame && frame->script()->canExecuteScripts(NotAboutToExecuteScript);
- pluginsEnabled = frame && frame->loader()->allowPlugins(NotAboutToInstantiatePlugin);
+ scriptEnabled = frame && frame->script().canExecuteScripts(NotAboutToExecuteScript);
+ pluginsEnabled = frame && frame->loader().allowPlugins(NotAboutToInstantiatePlugin);
Settings* settings = document ? document->settings() : 0;
// We force the main-thread parser for about:blank, javascript: and data: urls for compatibility
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp
index b5b38896df4..c74628479df 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp
@@ -28,7 +28,7 @@
#include "core/dom/Document.h"
#include "core/html/parser/HTMLDocumentParser.h"
-#include "core/page/FrameView.h"
+#include "core/frame/FrameView.h"
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h
index 01624b7940f..e8bfe493085 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h
@@ -27,7 +27,7 @@
#define HTMLParserScheduler_h
#include "core/html/parser/NestingLevelIncrementer.h"
-#include "core/platform/Timer.h"
+#include "platform/Timer.h"
#include "wtf/CurrentTime.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/RefPtr.h"
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.cpp
index 0ddc0587687..5a0e30c3e67 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.cpp
@@ -31,14 +31,14 @@
#include "config.h"
#include "core/html/parser/HTMLParserThread.h"
-#include "core/platform/Task.h"
-#include "wtf/PassOwnPtr.h"
+#include "platform/Task.h"
#include "public/platform/Platform.h"
+#include "wtf/PassOwnPtr.h"
namespace WebCore {
HTMLParserThread::HTMLParserThread()
- : m_thread(adoptPtr(WebKit::Platform::current()->createThread("HTMLParserThread")))
+ : m_thread(adoptPtr(blink::Platform::current()->createThread("HTMLParserThread")))
{
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.h
index 9e687de451a..e0b85f9399c 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.h
@@ -46,7 +46,7 @@ private:
HTMLParserThread();
~HTMLParserThread();
- OwnPtr<WebKit::WebThread> m_thread;
+ OwnPtr<blink::WebThread> m_thread;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
index e4a3abb3089..0d1e0645ad7 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
@@ -29,13 +29,13 @@
#include "core/html/parser/HTMLPreloadScanner.h"
#include "HTMLNames.h"
+#include "InputTypeNames.h"
#include "RuntimeEnabledFeatures.h"
#include "core/html/LinkRelAttribute.h"
-#include "core/html/forms/InputTypeNames.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/parser/HTMLSrcsetParser.h"
#include "core/html/parser/HTMLTokenizer.h"
-#include "core/platform/chromium/TraceEvent.h"
+#include "platform/TraceEvent.h"
#include "wtf/MainThread.h"
namespace WebCore {
@@ -47,17 +47,17 @@ static bool match(const StringImpl* impl, const QualifiedName& qName)
return impl == qName.localName().impl();
}
-static bool match(const HTMLIdentifier& name, const QualifiedName& qName)
-{
- return match(name.asStringImpl(), qName);
-}
-
static bool match(const AtomicString& name, const QualifiedName& qName)
{
ASSERT(isMainThread());
return qName.localName() == name;
}
+static bool match(const String& name, const QualifiedName& qName)
+{
+ return threadSafeMatch(name, qName);
+}
+
static const StringImpl* tagImplFor(const HTMLToken::DataVector& data)
{
AtomicString tagName(data);
@@ -67,9 +67,9 @@ static const StringImpl* tagImplFor(const HTMLToken::DataVector& data)
return 0;
}
-static const StringImpl* tagImplFor(const HTMLIdentifier& tagName)
+static const StringImpl* tagImplFor(const String& tagName)
{
- const StringImpl* result = tagName.asStringImpl();
+ const StringImpl* result = tagName.impl();
if (result->isStatic())
return result;
return 0;
@@ -98,6 +98,8 @@ public:
, m_inputIsImage(false)
, m_deviceScaleFactor(deviceScaleFactor)
, m_encounteredImgSrc(false)
+ , m_isCORSEnabled(false)
+ , m_allowCredentials(DoNotAllowStoredCredentials)
{
if (!match(m_tagImpl, imgTag)
&& !match(m_tagImpl, inputTag)
@@ -139,7 +141,8 @@ public:
TRACE_EVENT_INSTANT1("net", "PreloadRequest", "url", m_urlToLoad.ascii());
TextPosition position = TextPosition(source.currentLine(), source.currentColumn());
OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_tagImpl), position, m_urlToLoad, predictedBaseURL, resourceType(), m_mediaAttribute);
- request->setCrossOriginModeAllowsCookies(crossOriginModeAllowsCookies());
+ if (isCORSEnabled())
+ request->setCrossOriginEnabled(allowCredentials());
request->setCharset(charset());
return request.release();
}
@@ -154,14 +157,14 @@ private:
if (match(m_tagImpl, scriptTag)) {
if (match(attributeName, srcAttr))
setUrlToLoad(attributeValue, DisallowURLReplacement);
- else if (match(attributeName, crossoriginAttr) && !attributeValue.isNull())
- m_crossOriginMode = stripLeadingAndTrailingHTMLSpaces(attributeValue);
+ else if (match(attributeName, crossoriginAttr))
+ setCrossOriginAllowed(attributeValue);
} else if (match(m_tagImpl, imgTag)) {
if (match(attributeName, srcAttr) && !m_encounteredImgSrc) {
m_encounteredImgSrc = true;
setUrlToLoad(bestFitSourceForImageAttributes(m_deviceScaleFactor, attributeValue, m_srcsetImageCandidate), AllowURLReplacement);
- } else if (match(attributeName, crossoriginAttr) && !attributeValue.isNull()) {
- m_crossOriginMode = stripLeadingAndTrailingHTMLSpaces(attributeValue);
+ } else if (match(attributeName, crossoriginAttr)) {
+ setCrossOriginAllowed(attributeValue);
} else if (RuntimeEnabledFeatures::srcsetEnabled()
&& match(attributeName, srcsetAttr)
&& m_srcsetImageCandidate.isEmpty()) {
@@ -179,7 +182,7 @@ private:
if (match(attributeName, srcAttr))
setUrlToLoad(attributeValue, DisallowURLReplacement);
else if (match(attributeName, typeAttr))
- m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeNames::image());
+ m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeNames::image);
}
}
@@ -221,7 +224,7 @@ private:
return Resource::Raw;
}
- bool shouldPreload()
+ bool shouldPreload() const
{
if (m_urlToLoad.isEmpty())
return false;
@@ -232,21 +235,36 @@ private:
return true;
}
- bool crossOriginModeAllowsCookies()
+ bool isCORSEnabled() const
+ {
+ return m_isCORSEnabled;
+ }
+
+ StoredCredentials allowCredentials() const
+ {
+ return m_allowCredentials;
+ }
+
+ void setCrossOriginAllowed(const String& corsSetting)
{
- return m_crossOriginMode.isNull() || equalIgnoringCase(m_crossOriginMode, "use-credentials");
+ m_isCORSEnabled = true;
+ if (!corsSetting.isNull() && equalIgnoringCase(stripLeadingAndTrailingHTMLSpaces(corsSetting), "use-credentials"))
+ m_allowCredentials = AllowStoredCredentials;
+ else
+ m_allowCredentials = DoNotAllowStoredCredentials;
}
const StringImpl* m_tagImpl;
String m_urlToLoad;
ImageCandidate m_srcsetImageCandidate;
String m_charset;
- String m_crossOriginMode;
bool m_linkIsStyleSheet;
String m_mediaAttribute;
bool m_inputIsImage;
float m_deviceScaleFactor;
bool m_encounteredImgSrc;
+ bool m_isCORSEnabled;
+ StoredCredentials m_allowCredentials;
};
TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL, float deviceScaleFactor)
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h
index 50366d18f7f..956d30b3d28 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h
@@ -30,7 +30,7 @@
#include "core/html/parser/CSSPreloadScanner.h"
#include "core/html/parser/CompactHTMLToken.h"
#include "core/html/parser/HTMLToken.h"
-#include "core/platform/text/SegmentedString.h"
+#include "platform/text/SegmentedString.h"
#include "wtf/Vector.h"
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp
index 1d5317c4775..08e70a6a278 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp
@@ -32,8 +32,8 @@
#include "core/html/HTMLImport.h"
#include "core/css/MediaList.h"
#include "core/css/MediaQueryEvaluator.h"
-#include "core/platform/HistogramSupport.h"
#include "core/rendering/RenderObject.h"
+#include "public/platform/Platform.h"
namespace WebCore {
@@ -59,9 +59,8 @@ FetchRequest PreloadRequest::resourceRequest(Document* document)
initiatorInfo.position = m_initiatorPosition;
FetchRequest request(ResourceRequest(completeURL(document)), initiatorInfo);
- // FIXME: It's possible CORS should work for other request types?
- if (m_resourceType == Resource::Script)
- request.mutableResourceRequest().setAllowCookies(m_crossOriginModeAllowsCookies);
+ if (m_isCORSEnabled)
+ request.setCrossOriginAccessControl(document->securityOrigin(), m_allowCredentials);
return request;
}
@@ -93,7 +92,7 @@ void HTMLResourcePreloader::preload(PassOwnPtr<PreloadRequest> preload)
return;
FetchRequest request = preload->resourceRequest(m_document);
- HistogramSupport::histogramCustomCounts("WebCore.PreloadDelayMs", static_cast<int>(1000 * (monotonicallyIncreasingTime() - preload->discoveryTime())), 0, 2000, 20);
+ blink::Platform::current()->histogramCustomCounts("WebCore.PreloadDelayMs", static_cast<int>(1000 * (monotonicallyIncreasingTime() - preload->discoveryTime())), 0, 2000, 20);
loadingDocument->fetcher()->preload(preload->resourceType(), request, preload->charset());
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h
index 75c620d86a8..48686b6ca73 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h
@@ -53,7 +53,12 @@ public:
const String& media() const { return m_mediaAttribute; }
double discoveryTime() const { return m_discoveryTime; }
void setCharset(const String& charset) { m_charset = charset.isolatedCopy(); }
- void setCrossOriginModeAllowsCookies(bool allowsCookies) { m_crossOriginModeAllowsCookies = allowsCookies; }
+ void setCrossOriginEnabled(StoredCredentials allowCredentials)
+ {
+ m_isCORSEnabled = true;
+ m_allowCredentials = allowCredentials;
+ }
+
Resource::Type resourceType() const { return m_resourceType; }
private:
@@ -64,7 +69,8 @@ private:
, m_baseURL(baseURL.copy())
, m_resourceType(resourceType)
, m_mediaAttribute(mediaAttribute.isolatedCopy())
- , m_crossOriginModeAllowsCookies(false)
+ , m_isCORSEnabled(false)
+ , m_allowCredentials(DoNotAllowStoredCredentials)
, m_discoveryTime(monotonicallyIncreasingTime())
{
}
@@ -78,7 +84,8 @@ private:
String m_charset;
Resource::Type m_resourceType;
String m_mediaAttribute;
- bool m_crossOriginModeAllowsCookies;
+ bool m_isCORSEnabled;
+ StoredCredentials m_allowCredentials;
double m_discoveryTime;
};
@@ -89,18 +96,14 @@ class HTMLResourcePreloader {
public:
explicit HTMLResourcePreloader(Document* document)
: m_document(document)
- , m_weakFactory(this)
{
}
void takeAndPreload(PreloadRequestStream&);
void preload(PassOwnPtr<PreloadRequest>);
- WeakPtr<HTMLResourcePreloader> createWeakPtr() { return m_weakFactory.createWeakPtr(); }
-
private:
Document* m_document;
- WeakPtrFactory<HTMLResourcePreloader> m_weakFactory;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp
index f03d204314d..1cb6555c243 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp
@@ -28,7 +28,7 @@
#include "bindings/v8/ScriptSourceCode.h"
#include "core/dom/Element.h"
-#include "core/dom/Event.h"
+#include "core/events/Event.h"
#include "core/dom/IgnoreDestructiveWriteCountIncrementer.h"
#include "core/dom/Microtask.h"
#include "core/dom/ScriptLoader.h"
@@ -36,8 +36,8 @@
#include "core/html/parser/HTMLInputStream.h"
#include "core/html/parser/HTMLScriptRunnerHost.h"
#include "core/html/parser/NestingLevelIncrementer.h"
-#include "core/page/Frame.h"
-#include "core/platform/NotImplemented.h"
+#include "core/frame/Frame.h"
+#include "platform/NotImplemented.h"
namespace WebCore {
@@ -81,7 +81,7 @@ static KURL documentURLForScriptExecution(Document* document)
inline PassRefPtr<Event> createScriptLoadEvent()
{
- return Event::create(eventNames().loadEvent);
+ return Event::create(EventTypeNames::load);
}
ScriptSourceCode HTMLScriptRunner::sourceFromPendingScript(const PendingScript& script, bool& errorOccurred) const
@@ -137,8 +137,8 @@ void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendi
scriptLoader->dispatchErrorEvent();
else {
ASSERT(isExecutingScript());
- scriptLoader->executeScript(sourceCode);
- element->dispatchEvent(createScriptLoadEvent());
+ if (scriptLoader->executePotentiallyCrossOriginScript(sourceCode))
+ element->dispatchEvent(createScriptLoadEvent());
}
}
ASSERT(!isExecutingScript());
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLSourceTracker.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLSourceTracker.cpp
index ef802ba4ee7..af729fa4dc8 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLSourceTracker.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLSourceTracker.cpp
@@ -58,14 +58,17 @@ void HTMLSourceTracker::end(SegmentedString& currentInput, HTMLTokenizer* tokeni
String HTMLSourceTracker::sourceForToken(const HTMLToken& token)
{
- if (token.type() == HTMLToken::EndOfFile)
- return String(); // Hides the null character we use to mark the end of file.
-
if (!m_cachedSourceForToken.isEmpty())
return m_cachedSourceForToken;
- ASSERT(!token.startIndex());
- size_t length = static_cast<size_t>(token.endIndex() - token.startIndex());
+ size_t length;
+ if (token.type() == HTMLToken::EndOfFile) {
+ // Consume the remainder of the input, omitting the null character we use to mark the end of the file.
+ length = m_previousSource.length() + m_currentSource.length() - 1;
+ } else {
+ ASSERT(!token.startIndex());
+ length = static_cast<size_t>(token.endIndex() - token.startIndex());
+ }
StringBuilder source;
source.reserveCapacity(length);
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLSourceTracker.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLSourceTracker.h
index 63fec2b1bb9..083e6a93bf4 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLSourceTracker.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLSourceTracker.h
@@ -27,7 +27,7 @@
#define HTMLSourceTracker_h
#include "core/html/parser/HTMLToken.h"
-#include "core/platform/text/SegmentedString.h"
+#include "platform/text/SegmentedString.h"
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp
index 40c95a19643..7002dffab3b 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp
@@ -32,7 +32,7 @@
#include "core/html/parser/HTMLSrcsetParser.h"
#include "core/html/parser/HTMLParserIdioms.h"
-#include "core/platform/ParsingUtilities.h"
+#include "platform/ParsingUtilities.h"
namespace WebCore {
@@ -154,10 +154,13 @@ ImageCandidate bestFitSourceForSrcsetAttribute(float deviceScaleFactor, const St
return pickBestImageCandidate(deviceScaleFactor, imageCandidates);
}
-String bestFitSourceForImageAttributes(float deviceScaleFactor, const String& srcAttribute, const String& srcsetAttribute)
+ImageCandidate bestFitSourceForImageAttributes(float deviceScaleFactor, const String& srcAttribute, const String& srcsetAttribute)
{
- if (srcsetAttribute.isNull())
- return srcAttribute;
+ if (srcsetAttribute.isNull()) {
+ if (srcAttribute.isNull())
+ return ImageCandidate();
+ return ImageCandidate(srcAttribute, 0, srcAttribute.length(), 1);
+ }
Vector<ImageCandidate> imageCandidates;
@@ -166,7 +169,7 @@ String bestFitSourceForImageAttributes(float deviceScaleFactor, const String& sr
if (!srcAttribute.isEmpty())
imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.length(), 1.0));
- return pickBestImageCandidate(deviceScaleFactor, imageCandidates).toString();
+ return pickBestImageCandidate(deviceScaleFactor, imageCandidates);
}
String bestFitSourceForImageAttributes(float deviceScaleFactor, const String& srcAttribute, ImageCandidate& srcsetImageCandidate)
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.h
index bb53cb893c9..8964ffbcd5f 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.h
@@ -70,7 +70,7 @@ private:
ImageCandidate bestFitSourceForSrcsetAttribute(float deviceScaleFactor, const String& srcsetAttribute);
-String bestFitSourceForImageAttributes(float deviceScaleFactor, const String& srcAttribute, const String& srcsetAttribute);
+ImageCandidate bestFitSourceForImageAttributes(float deviceScaleFactor, const String& srcAttribute, const String& srcsetAttribute);
String bestFitSourceForImageAttributes(float deviceScaleFactor, const String& srcAttribute, ImageCandidate& srcsetImageCandidate);
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.cpp
index c78cd592941..ed8c954a64b 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.cpp
@@ -30,9 +30,8 @@
#include "HTMLNames.h"
#include "core/html/parser/HTMLEntityParser.h"
-#include "core/html/parser/HTMLToken.h"
#include "core/html/parser/HTMLTreeBuilder.h"
-#include "core/platform/NotImplemented.h"
+#include "platform/NotImplemented.h"
#include "core/xml/parser/MarkupTokenizerInlines.h"
#include "wtf/ASCIICType.h"
#include "wtf/text/AtomicString.h"
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.h
index bbfa0f2f9b2..aa7c059bf78 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.h
@@ -30,7 +30,7 @@
#include "core/html/parser/HTMLParserOptions.h"
#include "core/html/parser/HTMLToken.h"
#include "core/html/parser/InputStreamPreprocessor.h"
-#include "core/platform/text/SegmentedString.h"
+#include "platform/text/SegmentedString.h"
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp
index ac516a20d2e..4196cde09f0 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp
@@ -46,8 +46,8 @@
#include "core/html/parser/HTMLStackItem.h"
#include "core/html/parser/HTMLToken.h"
#include "core/html/parser/HTMLTokenizer.h"
-#include "core/platform/LocalizedStrings.h"
-#include "core/platform/NotImplemented.h"
+#include "platform/NotImplemented.h"
+#include "platform/text/PlatformLocale.h"
#include "wtf/MainThread.h"
#include "wtf/unicode/CharacterNames.h"
@@ -340,15 +340,14 @@ void HTMLTreeBuilder::detach()
HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext()
: m_fragment(0)
- , m_contextElement(0)
{
}
HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment* fragment, Element* contextElement)
: m_fragment(fragment)
- , m_contextElement(contextElement)
{
ASSERT(!fragment->hasChildNodes());
+ m_contextElementStackItem = HTMLStackItem::create(contextElement, HTMLStackItem::ItemForContextElement);
}
HTMLTreeBuilder::FragmentParsingContext::~FragmentParsingContext()
@@ -358,6 +357,7 @@ HTMLTreeBuilder::FragmentParsingContext::~FragmentParsingContext()
PassRefPtr<Element> HTMLTreeBuilder::takeScriptToProcess(TextPosition& scriptStartPosition)
{
ASSERT(m_scriptToProcess);
+ ASSERT(!m_tree.hasPendingTasks());
// Unpause ourselves, callers may pause us again when processing the script.
// The HTML5 spec is written as though scripts are executed inside the tree
// builder. We pause the parser to exit the tree builder, and then resume
@@ -375,10 +375,13 @@ void HTMLTreeBuilder::constructTree(AtomicHTMLToken* token)
processToken(token);
if (m_parser->tokenizer()) {
- bool inForeignContent = !m_tree.isEmpty()
- && !m_tree.currentStackItem()->isInHTMLNamespace()
- && !HTMLElementStack::isHTMLIntegrationPoint(m_tree.currentStackItem())
- && !HTMLElementStack::isMathMLTextIntegrationPoint(m_tree.currentStackItem());
+ bool inForeignContent = false;
+ if (!m_tree.isEmpty()) {
+ HTMLStackItem* adjustedCurrentNode = adjustedCurrentStackItem();
+ inForeignContent = !adjustedCurrentNode->isInHTMLNamespace()
+ && !HTMLElementStack::isHTMLIntegrationPoint(adjustedCurrentNode)
+ && !HTMLElementStack::isMathMLTextIntegrationPoint(adjustedCurrentNode);
+ }
m_parser->tokenizer()->setForceNullCharacterReplacement(m_insertionMode == TextMode || inForeignContent);
m_parser->tokenizer()->setShouldAllowCDATA(inForeignContent);
@@ -390,31 +393,34 @@ void HTMLTreeBuilder::constructTree(AtomicHTMLToken* token)
void HTMLTreeBuilder::processToken(AtomicHTMLToken* token)
{
+ if (token->type() == HTMLToken::Character) {
+ processCharacter(token);
+ return;
+ }
+
+ // Any non-character token needs to cause us to flush any pending text immediately.
+ // NOTE: flush() can cause any queued tasks to execute, possibly re-entering the parser.
+ m_tree.flush();
+ m_shouldSkipLeadingNewline = false;
+
switch (token->type()) {
case HTMLToken::Uninitialized:
+ case HTMLToken::Character:
ASSERT_NOT_REACHED();
break;
case HTMLToken::DOCTYPE:
- m_shouldSkipLeadingNewline = false;
processDoctypeToken(token);
break;
case HTMLToken::StartTag:
- m_shouldSkipLeadingNewline = false;
processStartTag(token);
break;
case HTMLToken::EndTag:
- m_shouldSkipLeadingNewline = false;
processEndTag(token);
break;
case HTMLToken::Comment:
- m_shouldSkipLeadingNewline = false;
processComment(token);
- return;
- case HTMLToken::Character:
- processCharacter(token);
break;
case HTMLToken::EndOfFile:
- m_shouldSkipLeadingNewline = false;
processEndOfFile(token);
break;
}
@@ -487,6 +493,10 @@ void HTMLTreeBuilder::processIsindexStartTagForInBody(AtomicHTMLToken* token)
{
ASSERT(token->type() == HTMLToken::StartTag);
ASSERT(token->name() == isindexTag);
+
+ if (m_parser->useCounter())
+ m_parser->useCounter()->count(UseCounter::IsIndexElement);
+
parseError(token);
if (m_tree.form())
return;
@@ -501,7 +511,7 @@ void HTMLTreeBuilder::processIsindexStartTagForInBody(AtomicHTMLToken* token)
if (promptAttribute)
processFakeCharacters(promptAttribute->value());
else
- processFakeCharacters(searchableIndexIntroduction());
+ processFakeCharacters(Locale::defaultLocale().queryString(blink::WebLocalizedString::SearchableIndexIntroduction));
processFakeStartTag(inputTag, attributesForIsindexInput(token));
notImplemented(); // This second set of characters may be needed by non-english locales.
processFakeEndTag(labelTag);
@@ -546,7 +556,7 @@ void HTMLTreeBuilder::processCloseWhenNestedTag(AtomicHTMLToken* token)
typedef HashMap<AtomicString, QualifiedName> PrefixedNameToQualifiedNameMap;
-static void mapLoweredLocalNameToName(PrefixedNameToQualifiedNameMap* map, QualifiedName** names, size_t length)
+static void mapLoweredLocalNameToName(PrefixedNameToQualifiedNameMap* map, const QualifiedName* const* names, size_t length)
{
for (size_t i = 0; i < length; ++i) {
const QualifiedName& name = *names[i];
@@ -562,7 +572,7 @@ static void adjustSVGTagNameCase(AtomicHTMLToken* token)
static PrefixedNameToQualifiedNameMap* caseMap = 0;
if (!caseMap) {
caseMap = new PrefixedNameToQualifiedNameMap;
- QualifiedName** svgTags = SVGNames::getSVGTags();
+ const QualifiedName* const* svgTags = SVGNames::getSVGTags();
mapLoweredLocalNameToName(caseMap, svgTags, SVGNames::SVGTagsCount);
}
@@ -572,13 +582,13 @@ static void adjustSVGTagNameCase(AtomicHTMLToken* token)
token->setName(casedName.localName());
}
-template<QualifiedName** getAttrs(), unsigned length>
+template<const QualifiedName* const* getAttrs(), unsigned length>
static void adjustAttributes(AtomicHTMLToken* token)
{
static PrefixedNameToQualifiedNameMap* caseMap = 0;
if (!caseMap) {
caseMap = new PrefixedNameToQualifiedNameMap;
- QualifiedName** attrs = getAttrs();
+ const QualifiedName* const* attrs = getAttrs();
mapLoweredLocalNameToName(caseMap, attrs, length);
}
@@ -600,10 +610,10 @@ static void adjustMathMLAttributes(AtomicHTMLToken* token)
adjustAttributes<MathMLNames::getMathMLAttrs, MathMLNames::MathMLAttrsCount>(token);
}
-static void addNamesWithPrefix(PrefixedNameToQualifiedNameMap* map, const AtomicString& prefix, QualifiedName** names, size_t length)
+static void addNamesWithPrefix(PrefixedNameToQualifiedNameMap* map, const AtomicString& prefix, const QualifiedName* const* names, size_t length)
{
for (size_t i = 0; i < length; ++i) {
- QualifiedName* name = names[i];
+ const QualifiedName* name = names[i];
const AtomicString& localName = name->localName();
AtomicString prefixColonLocalName = prefix + ':' + localName;
QualifiedName nameWithPrefix(prefix, localName, name->namespaceURI());
@@ -617,7 +627,7 @@ static void adjustForeignAttributes(AtomicHTMLToken* token)
if (!map) {
map = new PrefixedNameToQualifiedNameMap;
- QualifiedName** attrs = XLinkNames::getXLinkAttrs();
+ const QualifiedName* const* attrs = XLinkNames::getXLinkAttrs();
addNamesWithPrefix(map, xlinkAtom, attrs, XLinkNames::XLinkAttrsCount);
attrs = XMLNames::getXMLAttrs();
@@ -995,6 +1005,16 @@ bool HTMLTreeBuilder::processColgroupEndTagForInColumnGroup()
return true;
}
+// http://www.whatwg.org/specs/web-apps/current-work/#adjusted-current-node
+HTMLStackItem* HTMLTreeBuilder::adjustedCurrentStackItem() const
+{
+ ASSERT(!m_tree.isEmpty());
+ if (isParsingFragment() && m_tree.openElements()->hasOnlyOneElement())
+ return m_fragmentContext.contextElementStackItem();
+
+ return m_tree.currentStackItem();
+}
+
// http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#close-the-cell
void HTMLTreeBuilder::closeTheCell()
{
@@ -1144,6 +1164,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken* token)
|| token->name() == noframesTag
|| token->name() == scriptTag
|| token->name() == styleTag
+ || token->name() == templateTag
|| token->name() == titleTag) {
parseError(token);
ASSERT(m_tree.head());
@@ -1604,13 +1625,21 @@ void HTMLTreeBuilder::resetInsertionModeAppropriately()
while (1) {
RefPtr<HTMLStackItem> item = nodeRecord->stackItem();
if (item->node() == m_tree.openElements()->rootNode()) {
- ASSERT(isParsingFragment());
last = true;
- item = HTMLStackItem::create(m_fragmentContext.contextElement(), HTMLStackItem::ItemForContextElement);
+ if (isParsingFragment())
+ item = m_fragmentContext.contextElementStackItem();
}
if (item->hasTagName(templateTag))
return setInsertionMode(m_templateInsertionModes.last());
if (item->hasTagName(selectTag)) {
+ if (!last) {
+ while (item->node() != m_tree.openElements()->rootNode() && !item->hasTagName(templateTag)) {
+ nodeRecord = nodeRecord->next();
+ item = nodeRecord->stackItem();
+ if (isHTMLTableElement(item->node()))
+ return setInsertionMode(InSelectInTableMode);
+ }
+ }
return setInsertionMode(InSelectMode);
}
if (item->hasTagName(tdTag) || item->hasTagName(thTag))
@@ -1637,6 +1666,9 @@ void HTMLTreeBuilder::resetInsertionModeAppropriately()
return setInsertionMode(InFramesetMode);
}
if (isHTMLHtmlElement(item->node())) {
+ if (m_tree.headStackItem())
+ return setInsertionMode(AfterHeadMode);
+
ASSERT(isParsingFragment());
return setInsertionMode(BeforeHeadMode);
}
@@ -2514,8 +2546,7 @@ void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken* token)
return;
break;
}
- ASSERT(m_tree.currentNode());
- m_tree.openElements()->popAll();
+ m_tree.processEndOfFile();
}
void HTMLTreeBuilder::defaultForInitial()
@@ -2664,10 +2695,11 @@ bool HTMLTreeBuilder::shouldProcessTokenInForeignContent(AtomicHTMLToken* token)
{
if (m_tree.isEmpty())
return false;
- HTMLStackItem* item = m_tree.currentStackItem();
- if (item->isInHTMLNamespace())
+ HTMLStackItem* adjustedCurrentNode = adjustedCurrentStackItem();
+
+ if (adjustedCurrentNode->isInHTMLNamespace())
return false;
- if (HTMLElementStack::isMathMLTextIntegrationPoint(item)) {
+ if (HTMLElementStack::isMathMLTextIntegrationPoint(adjustedCurrentNode)) {
if (token->type() == HTMLToken::StartTag
&& token->name() != MathMLNames::mglyphTag
&& token->name() != MathMLNames::malignmarkTag)
@@ -2675,11 +2707,11 @@ bool HTMLTreeBuilder::shouldProcessTokenInForeignContent(AtomicHTMLToken* token)
if (token->type() == HTMLToken::Character)
return false;
}
- if (item->hasTagName(MathMLNames::annotation_xmlTag)
+ if (adjustedCurrentNode->hasTagName(MathMLNames::annotation_xmlTag)
&& token->type() == HTMLToken::StartTag
&& token->name() == SVGNames::svgTag)
return false;
- if (HTMLElementStack::isHTMLIntegrationPoint(item)) {
+ if (HTMLElementStack::isHTMLIntegrationPoint(adjustedCurrentNode)) {
if (token->type() == HTMLToken::StartTag)
return false;
if (token->type() == HTMLToken::Character)
@@ -2692,6 +2724,17 @@ bool HTMLTreeBuilder::shouldProcessTokenInForeignContent(AtomicHTMLToken* token)
void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken* token)
{
+ if (token->type() == HTMLToken::Character) {
+ const String& characters = token->characters();
+ m_tree.insertTextNode(characters);
+ if (m_framesetOk && !isAllWhitespaceOrReplacementCharacters(characters))
+ m_framesetOk = false;
+ return;
+ }
+
+ m_tree.flush();
+ HTMLStackItem* adjustedCurrentNode = adjustedCurrentStackItem();
+
switch (token->type()) {
case HTMLToken::Uninitialized:
ASSERT_NOT_REACHED();
@@ -2745,7 +2788,7 @@ void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken* token)
processStartTag(token);
return;
}
- const AtomicString& currentNamespace = m_tree.currentStackItem()->namespaceURI();
+ const AtomicString& currentNamespace = adjustedCurrentNode->namespaceURI();
if (currentNamespace == MathMLNames::mathmlNamespaceURI)
adjustMathMLAttributes(token);
if (currentNamespace == SVGNames::svgNamespaceURI) {
@@ -2757,7 +2800,7 @@ void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken* token)
break;
}
case HTMLToken::EndTag: {
- if (m_tree.currentStackItem()->namespaceURI() == SVGNames::svgNamespaceURI)
+ if (adjustedCurrentNode->namespaceURI() == SVGNames::svgNamespaceURI)
adjustSVGTagNameCase(token);
if (token->name() == SVGNames::scriptTag && m_tree.currentStackItem()->hasTagName(SVGNames::scriptTag)) {
@@ -2788,14 +2831,8 @@ void HTMLTreeBuilder::processTokenInForeignContent(AtomicHTMLToken* token)
}
case HTMLToken::Comment:
m_tree.insertComment(token);
- return;
- case HTMLToken::Character: {
- const String& characters = token->characters();
- m_tree.insertTextNode(characters);
- if (m_framesetOk && !isAllWhitespaceOrReplacementCharacters(characters))
- m_framesetOk = false;
break;
- }
+ case HTMLToken::Character:
case HTMLToken::EndOfFile:
ASSERT_NOT_REACHED();
break;
@@ -2817,4 +2854,4 @@ void HTMLTreeBuilder::parseError(AtomicHTMLToken*)
{
}
-}
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.h
index c434d56220c..60ead95f286 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.h
@@ -80,6 +80,9 @@ public:
// Done, close any open tags, etc.
void finished();
+ // Synchronously empty any queues, possibly creating more DOM nodes.
+ void flush() { m_tree.flush(); }
+
void setShouldSkipLeadingNewline(bool shouldSkip) { m_shouldSkipLeadingNewline = shouldSkip; }
private:
@@ -166,6 +169,7 @@ private:
void defaultForAfterHead();
void defaultForInTableText();
+ inline HTMLStackItem* adjustedCurrentStackItem() const;
inline bool shouldProcessTokenInForeignContent(AtomicHTMLToken*);
void processTokenInForeignContent(AtomicHTMLToken*);
@@ -197,11 +201,12 @@ private:
~FragmentParsingContext();
DocumentFragment* fragment() const { return m_fragment; }
- Element* contextElement() const { ASSERT(m_fragment); return m_contextElement; }
+ Element* contextElement() const { ASSERT(m_fragment); return m_contextElementStackItem->element(); }
+ HTMLStackItem* contextElementStackItem() const { ASSERT(m_fragment); return m_contextElementStackItem.get(); }
private:
DocumentFragment* m_fragment;
- Element* m_contextElement;
+ RefPtr<HTMLStackItem> m_contextElementStackItem;
};
bool m_framesetOk;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp
index 32ccaaf1ae9..37273cbaea0 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp
@@ -40,64 +40,64 @@ using namespace HTMLNames;
static bool tokenExitsForeignContent(const CompactHTMLToken& token)
{
// FIXME: This is copied from HTMLTreeBuilder::processTokenInForeignContent and changed to use threadSafeHTMLNamesMatch.
- const HTMLIdentifier& tagName = token.data();
- return threadSafeHTMLNamesMatch(tagName, bTag)
- || threadSafeHTMLNamesMatch(tagName, bigTag)
- || threadSafeHTMLNamesMatch(tagName, blockquoteTag)
- || threadSafeHTMLNamesMatch(tagName, bodyTag)
- || threadSafeHTMLNamesMatch(tagName, brTag)
- || threadSafeHTMLNamesMatch(tagName, centerTag)
- || threadSafeHTMLNamesMatch(tagName, codeTag)
- || threadSafeHTMLNamesMatch(tagName, ddTag)
- || threadSafeHTMLNamesMatch(tagName, divTag)
- || threadSafeHTMLNamesMatch(tagName, dlTag)
- || threadSafeHTMLNamesMatch(tagName, dtTag)
- || threadSafeHTMLNamesMatch(tagName, emTag)
- || threadSafeHTMLNamesMatch(tagName, embedTag)
- || threadSafeHTMLNamesMatch(tagName, h1Tag)
- || threadSafeHTMLNamesMatch(tagName, h2Tag)
- || threadSafeHTMLNamesMatch(tagName, h3Tag)
- || threadSafeHTMLNamesMatch(tagName, h4Tag)
- || threadSafeHTMLNamesMatch(tagName, h5Tag)
- || threadSafeHTMLNamesMatch(tagName, h6Tag)
- || threadSafeHTMLNamesMatch(tagName, headTag)
- || threadSafeHTMLNamesMatch(tagName, hrTag)
- || threadSafeHTMLNamesMatch(tagName, iTag)
- || threadSafeHTMLNamesMatch(tagName, imgTag)
- || threadSafeHTMLNamesMatch(tagName, liTag)
- || threadSafeHTMLNamesMatch(tagName, listingTag)
- || threadSafeHTMLNamesMatch(tagName, menuTag)
- || threadSafeHTMLNamesMatch(tagName, metaTag)
- || threadSafeHTMLNamesMatch(tagName, nobrTag)
- || threadSafeHTMLNamesMatch(tagName, olTag)
- || threadSafeHTMLNamesMatch(tagName, pTag)
- || threadSafeHTMLNamesMatch(tagName, preTag)
- || threadSafeHTMLNamesMatch(tagName, rubyTag)
- || threadSafeHTMLNamesMatch(tagName, sTag)
- || threadSafeHTMLNamesMatch(tagName, smallTag)
- || threadSafeHTMLNamesMatch(tagName, spanTag)
- || threadSafeHTMLNamesMatch(tagName, strongTag)
- || threadSafeHTMLNamesMatch(tagName, strikeTag)
- || threadSafeHTMLNamesMatch(tagName, subTag)
- || threadSafeHTMLNamesMatch(tagName, supTag)
- || threadSafeHTMLNamesMatch(tagName, tableTag)
- || threadSafeHTMLNamesMatch(tagName, ttTag)
- || threadSafeHTMLNamesMatch(tagName, uTag)
- || threadSafeHTMLNamesMatch(tagName, ulTag)
- || threadSafeHTMLNamesMatch(tagName, varTag)
- || (threadSafeHTMLNamesMatch(tagName, fontTag) && (token.getAttributeItem(colorAttr) || token.getAttributeItem(faceAttr) || token.getAttributeItem(sizeAttr)));
+ const String& tagName = token.data();
+ return threadSafeMatch(tagName, bTag)
+ || threadSafeMatch(tagName, bigTag)
+ || threadSafeMatch(tagName, blockquoteTag)
+ || threadSafeMatch(tagName, bodyTag)
+ || threadSafeMatch(tagName, brTag)
+ || threadSafeMatch(tagName, centerTag)
+ || threadSafeMatch(tagName, codeTag)
+ || threadSafeMatch(tagName, ddTag)
+ || threadSafeMatch(tagName, divTag)
+ || threadSafeMatch(tagName, dlTag)
+ || threadSafeMatch(tagName, dtTag)
+ || threadSafeMatch(tagName, emTag)
+ || threadSafeMatch(tagName, embedTag)
+ || threadSafeMatch(tagName, h1Tag)
+ || threadSafeMatch(tagName, h2Tag)
+ || threadSafeMatch(tagName, h3Tag)
+ || threadSafeMatch(tagName, h4Tag)
+ || threadSafeMatch(tagName, h5Tag)
+ || threadSafeMatch(tagName, h6Tag)
+ || threadSafeMatch(tagName, headTag)
+ || threadSafeMatch(tagName, hrTag)
+ || threadSafeMatch(tagName, iTag)
+ || threadSafeMatch(tagName, imgTag)
+ || threadSafeMatch(tagName, liTag)
+ || threadSafeMatch(tagName, listingTag)
+ || threadSafeMatch(tagName, menuTag)
+ || threadSafeMatch(tagName, metaTag)
+ || threadSafeMatch(tagName, nobrTag)
+ || threadSafeMatch(tagName, olTag)
+ || threadSafeMatch(tagName, pTag)
+ || threadSafeMatch(tagName, preTag)
+ || threadSafeMatch(tagName, rubyTag)
+ || threadSafeMatch(tagName, sTag)
+ || threadSafeMatch(tagName, smallTag)
+ || threadSafeMatch(tagName, spanTag)
+ || threadSafeMatch(tagName, strongTag)
+ || threadSafeMatch(tagName, strikeTag)
+ || threadSafeMatch(tagName, subTag)
+ || threadSafeMatch(tagName, supTag)
+ || threadSafeMatch(tagName, tableTag)
+ || threadSafeMatch(tagName, ttTag)
+ || threadSafeMatch(tagName, uTag)
+ || threadSafeMatch(tagName, ulTag)
+ || threadSafeMatch(tagName, varTag)
+ || (threadSafeMatch(tagName, fontTag) && (token.getAttributeItem(colorAttr) || token.getAttributeItem(faceAttr) || token.getAttributeItem(sizeAttr)));
}
static bool tokenExitsSVG(const CompactHTMLToken& token)
{
// FIXME: It's very fragile that we special case foreignObject here to be case-insensitive.
- return equalIgnoringCaseNonNull(token.data().asStringImpl(), SVGNames::foreignObjectTag.localName().impl());
+ return equalIgnoringCaseNonNull(token.data().impl(), SVGNames::foreignObjectTag.localName().impl());
}
static bool tokenExitsMath(const CompactHTMLToken& token)
{
// FIXME: This is copied from HTMLElementStack::isMathMLTextIntegrationPoint and changed to use threadSafeMatch.
- const HTMLIdentifier& tagName = token.data();
+ const String& tagName = token.data();
return threadSafeMatch(tagName, MathMLNames::miTag)
|| threadSafeMatch(tagName, MathMLNames::moTag)
|| threadSafeMatch(tagName, MathMLNames::mnTag)
@@ -132,7 +132,7 @@ HTMLTreeBuilderSimulator::State HTMLTreeBuilderSimulator::stateFor(HTMLTreeBuild
bool HTMLTreeBuilderSimulator::simulate(const CompactHTMLToken& token, HTMLTokenizer* tokenizer)
{
if (token.type() == HTMLToken::StartTag) {
- const HTMLIdentifier& tagName = token.data();
+ const String& tagName = token.data();
if (threadSafeMatch(tagName, SVGNames::svgTag))
m_namespaceStack.append(SVG);
if (threadSafeMatch(tagName, MathMLNames::mathTag))
@@ -144,30 +144,30 @@ bool HTMLTreeBuilderSimulator::simulate(const CompactHTMLToken& token, HTMLToken
m_namespaceStack.append(HTML);
if (!inForeignContent()) {
// FIXME: This is just a copy of Tokenizer::updateStateFor which uses threadSafeMatches.
- if (threadSafeHTMLNamesMatch(tagName, textareaTag) || threadSafeHTMLNamesMatch(tagName, titleTag))
+ if (threadSafeMatch(tagName, textareaTag) || threadSafeMatch(tagName, titleTag))
tokenizer->setState(HTMLTokenizer::RCDATAState);
- else if (threadSafeHTMLNamesMatch(tagName, plaintextTag))
+ else if (threadSafeMatch(tagName, plaintextTag))
tokenizer->setState(HTMLTokenizer::PLAINTEXTState);
- else if (threadSafeHTMLNamesMatch(tagName, scriptTag))
+ else if (threadSafeMatch(tagName, scriptTag))
tokenizer->setState(HTMLTokenizer::ScriptDataState);
- else if (threadSafeHTMLNamesMatch(tagName, styleTag)
- || threadSafeHTMLNamesMatch(tagName, iframeTag)
- || threadSafeHTMLNamesMatch(tagName, xmpTag)
- || (threadSafeHTMLNamesMatch(tagName, noembedTag) && m_options.pluginsEnabled)
- || threadSafeHTMLNamesMatch(tagName, noframesTag)
- || (threadSafeHTMLNamesMatch(tagName, noscriptTag) && m_options.scriptEnabled))
+ else if (threadSafeMatch(tagName, styleTag)
+ || threadSafeMatch(tagName, iframeTag)
+ || threadSafeMatch(tagName, xmpTag)
+ || (threadSafeMatch(tagName, noembedTag) && m_options.pluginsEnabled)
+ || threadSafeMatch(tagName, noframesTag)
+ || (threadSafeMatch(tagName, noscriptTag) && m_options.scriptEnabled))
tokenizer->setState(HTMLTokenizer::RAWTEXTState);
}
}
if (token.type() == HTMLToken::EndTag) {
- const HTMLIdentifier& tagName = token.data();
+ const String& tagName = token.data();
if ((m_namespaceStack.last() == SVG && threadSafeMatch(tagName, SVGNames::svgTag))
|| (m_namespaceStack.last() == MathML && threadSafeMatch(tagName, MathMLNames::mathTag))
|| (m_namespaceStack.contains(SVG) && m_namespaceStack.last() == HTML && tokenExitsSVG(token))
|| (m_namespaceStack.contains(MathML) && m_namespaceStack.last() == HTML && tokenExitsMath(token)))
m_namespaceStack.removeLast();
- if (threadSafeHTMLNamesMatch(tagName, scriptTag)) {
+ if (threadSafeMatch(tagName, scriptTag)) {
if (!inForeignContent())
tokenizer->setState(HTMLTokenizer::DataState);
return false;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.cpp
index de01ee274d1..b46ff5ad2e9 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.cpp
@@ -27,7 +27,6 @@
#include "core/html/parser/HTMLViewSourceParser.h"
#include "core/dom/DOMImplementation.h"
-#include "core/html/HTMLViewSourceDocument.h"
#include "core/html/parser/HTMLParserOptions.h"
#include "core/html/parser/HTMLToken.h"
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/InputStreamPreprocessor.h b/chromium/third_party/WebKit/Source/core/html/parser/InputStreamPreprocessor.h
index 842e948138b..a411d52d6a1 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/InputStreamPreprocessor.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/InputStreamPreprocessor.h
@@ -28,7 +28,7 @@
#ifndef InputStreamPreprocessor_h
#define InputStreamPreprocessor_h
-#include "core/platform/text/SegmentedString.h"
+#include "platform/text/SegmentedString.h"
#include "wtf/Noncopyable.h"
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/MathMLAttributeNames.in b/chromium/third_party/WebKit/Source/core/html/parser/MathMLAttributeNames.in
new file mode 100644
index 00000000000..45a6e3af507
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/parser/MathMLAttributeNames.in
@@ -0,0 +1,26 @@
+namespace="MathML"
+namespaceURI="http://www.w3.org/1998/Math/MathML"
+attrsNullNamespace
+
+alttext
+background
+close
+color
+columnspan
+definitionURL
+denomalign
+encoding
+fontfamily
+fontsize
+fontstyle
+fontweight
+linethickness
+mathbackground
+mathcolor
+mathsize
+mathvariant
+numalign
+open
+rowspan
+separators
+stretchy
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/MathMLTagNames.in b/chromium/third_party/WebKit/Source/core/html/parser/MathMLTagNames.in
new file mode 100644
index 00000000000..80d830f4750
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/parser/MathMLTagNames.in
@@ -0,0 +1,12 @@
+namespace="MathML"
+namespaceURI="http://www.w3.org/1998/Math/MathML"
+
+math
+mi
+mn
+mo
+mtext
+ms
+mglyph
+malignmark
+annotation-xml
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.cpp b/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.cpp
index bd70813edde..a43fca982b5 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.cpp
@@ -32,20 +32,25 @@
#include "XLinkNames.h"
#include "core/dom/Document.h"
#include "core/fetch/TextResourceDecoder.h"
+#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/Frame.h"
#include "core/html/HTMLParamElement.h"
#include "core/html/parser/HTMLDocumentParser.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/parser/XSSAuditorDelegate.h"
#include "core/loader/DocumentLoader.h"
-#include "core/page/ContentSecurityPolicy.h"
-#include "core/page/Frame.h"
-#include "core/page/Settings.h"
-#include "core/platform/JSONValues.h"
-#include "core/platform/network/FormData.h"
-#include "core/platform/text/DecodeEscapeSequences.h"
-#include "weborigin/KURL.h"
+#include "core/frame/Settings.h"
+#include "platform/JSONValues.h"
+#include "platform/network/FormData.h"
+#include "platform/text/DecodeEscapeSequences.h"
#include "wtf/MainThread.h"
-#include "wtf/text/TextEncoding.h"
+
+namespace {
+
+// SecurityOrigin::urlWithUniqueSecurityOrigin() can't be used cross-thread, or we'd use it instead.
+const char kURLWithUniqueOrigin[] = "data:,";
+
+} // namespace
namespace WebCore {
@@ -170,12 +175,12 @@ static String fullyDecodeString(const String& string, const WTF::TextEncoding& e
return workingString;
}
-static ContentSecurityPolicy::ReflectedXSSDisposition combineXSSProtectionHeaderAndCSP(ContentSecurityPolicy::ReflectedXSSDisposition xssProtection, ContentSecurityPolicy::ReflectedXSSDisposition reflectedXSS)
+static ReflectedXSSDisposition combineXSSProtectionHeaderAndCSP(ReflectedXSSDisposition xssProtection, ReflectedXSSDisposition reflectedXSS)
{
- ContentSecurityPolicy::ReflectedXSSDisposition result = std::max(xssProtection, reflectedXSS);
+ ReflectedXSSDisposition result = std::max(xssProtection, reflectedXSS);
- if (result == ContentSecurityPolicy::ReflectedXSSInvalid || result == ContentSecurityPolicy::FilterReflectedXSS || result == ContentSecurityPolicy::ReflectedXSSUnset)
- return ContentSecurityPolicy::FilterReflectedXSS;
+ if (result == ReflectedXSSInvalid || result == FilterReflectedXSS || result == ReflectedXSSUnset)
+ return FilterReflectedXSS;
return result;
}
@@ -198,7 +203,7 @@ static bool semicolonSeparatedValueContainsJavaScriptURL(const String& value)
XSSAuditor::XSSAuditor()
: m_isEnabled(false)
- , m_xssProtection(ContentSecurityPolicy::FilterReflectedXSS)
+ , m_xssProtection(FilterReflectedXSS)
, m_didSendValidCSPHeader(false)
, m_didSendValidXSSProtectionHeader(false)
, m_state(Uninitialized)
@@ -214,7 +219,7 @@ void XSSAuditor::initForFragment()
{
ASSERT(isMainThread());
ASSERT(m_state == Uninitialized);
- m_state = Initialized;
+ m_state = FilteringTokens;
// When parsing a fragment, we don't enable the XSS auditor because it's
// too much overhead.
ASSERT(!m_isEnabled);
@@ -226,10 +231,9 @@ void XSSAuditor::init(Document* document, XSSAuditorDelegate* auditorDelegate)
const int suffixTreeDepth = 5;
ASSERT(isMainThread());
- if (m_state == Initialized)
+ if (m_state != Uninitialized)
return;
- ASSERT(m_state == Uninitialized);
- m_state = Initialized;
+ m_state = FilteringTokens;
if (Settings* settings = document->settings())
m_isEnabled = settings->xssAuditorEnabled();
@@ -265,36 +269,36 @@ void XSSAuditor::init(Document* document, XSSAuditorDelegate* auditorDelegate)
m_decodedURL = String();
String httpBodyAsString;
- if (DocumentLoader* documentLoader = document->frame()->loader()->documentLoader()) {
- DEFINE_STATIC_LOCAL(String, XSSProtectionHeader, ("X-XSS-Protection"));
- String headerValue = documentLoader->response().httpHeaderField(XSSProtectionHeader);
+ if (DocumentLoader* documentLoader = document->frame()->loader().documentLoader()) {
+ DEFINE_STATIC_LOCAL(const AtomicString, XSSProtectionHeader, ("X-XSS-Protection", AtomicString::ConstructFromLiteral));
+ const AtomicString& headerValue = documentLoader->response().httpHeaderField(XSSProtectionHeader);
String errorDetails;
unsigned errorPosition = 0;
String reportURL;
KURL xssProtectionReportURL;
// Process the X-XSS-Protection header, then mix in the CSP header's value.
- ContentSecurityPolicy::ReflectedXSSDisposition xssProtectionHeader = parseXSSProtectionHeader(headerValue, errorDetails, errorPosition, reportURL);
- m_didSendValidXSSProtectionHeader = xssProtectionHeader != ContentSecurityPolicy::ReflectedXSSUnset && xssProtectionHeader != ContentSecurityPolicy::ReflectedXSSInvalid;
- if ((xssProtectionHeader == ContentSecurityPolicy::FilterReflectedXSS || xssProtectionHeader == ContentSecurityPolicy::BlockReflectedXSS) && !reportURL.isEmpty()) {
+ ReflectedXSSDisposition xssProtectionHeader = parseXSSProtectionHeader(headerValue, errorDetails, errorPosition, reportURL);
+ m_didSendValidXSSProtectionHeader = xssProtectionHeader != ReflectedXSSUnset && xssProtectionHeader != ReflectedXSSInvalid;
+ if ((xssProtectionHeader == FilterReflectedXSS || xssProtectionHeader == BlockReflectedXSS) && !reportURL.isEmpty()) {
xssProtectionReportURL = document->completeURL(reportURL);
if (MixedContentChecker::isMixedContent(document->securityOrigin(), xssProtectionReportURL)) {
errorDetails = "insecure reporting URL for secure page";
- xssProtectionHeader = ContentSecurityPolicy::ReflectedXSSInvalid;
+ xssProtectionHeader = ReflectedXSSInvalid;
xssProtectionReportURL = KURL();
}
}
- if (xssProtectionHeader == ContentSecurityPolicy::ReflectedXSSInvalid)
+ if (xssProtectionHeader == ReflectedXSSInvalid)
document->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Error parsing header X-XSS-Protection: " + headerValue + ": " + errorDetails + " at character position " + String::format("%u", errorPosition) + ". The default protections will be applied.");
- ContentSecurityPolicy::ReflectedXSSDisposition cspHeader = document->contentSecurityPolicy()->reflectedXSSDisposition();
- m_didSendValidCSPHeader = cspHeader != ContentSecurityPolicy::ReflectedXSSUnset && cspHeader != ContentSecurityPolicy::ReflectedXSSInvalid;
+ ReflectedXSSDisposition cspHeader = document->contentSecurityPolicy()->reflectedXSSDisposition();
+ m_didSendValidCSPHeader = cspHeader != ReflectedXSSUnset && cspHeader != ReflectedXSSInvalid;
m_xssProtection = combineXSSProtectionHeaderAndCSP(xssProtectionHeader, cspHeader);
// FIXME: Combine the two report URLs in some reasonable way.
if (auditorDelegate)
auditorDelegate->setReportURL(xssProtectionReportURL.copy());
- FormData* httpBody = documentLoader->originalRequest().httpBody();
+ FormData* httpBody = documentLoader->request().httpBody();
if (httpBody && !httpBody->isEmpty()) {
httpBodyAsString = httpBody->flattenToString();
if (!httpBodyAsString.isEmpty()) {
@@ -315,8 +319,8 @@ void XSSAuditor::init(Document* document, XSSAuditorDelegate* auditorDelegate)
PassOwnPtr<XSSInfo> XSSAuditor::filterToken(const FilterTokenRequest& request)
{
- ASSERT(m_state == Initialized);
- if (!m_isEnabled || m_xssProtection == ContentSecurityPolicy::AllowReflectedXSS)
+ ASSERT(m_state != Uninitialized);
+ if (!m_isEnabled || m_xssProtection == AllowReflectedXSS)
return nullptr;
bool didBlockScript = false;
@@ -330,7 +334,7 @@ PassOwnPtr<XSSInfo> XSSAuditor::filterToken(const FilterTokenRequest& request)
}
if (didBlockScript) {
- bool didBlockEntirePage = (m_xssProtection == ContentSecurityPolicy::BlockReflectedXSS);
+ bool didBlockEntirePage = (m_xssProtection == BlockReflectedXSS);
OwnPtr<XSSInfo> xssInfo = XSSInfo::create(m_documentURL, didBlockEntirePage, m_didSendValidXSSProtectionHeader, m_didSendValidCSPHeader);
return xssInfo.release();
}
@@ -339,6 +343,7 @@ PassOwnPtr<XSSInfo> XSSAuditor::filterToken(const FilterTokenRequest& request)
bool XSSAuditor::filterStartToken(const FilterTokenRequest& request)
{
+ m_state = FilteringTokens;
bool didBlockScript = eraseDangerousAttributesIfInjected(request);
if (hasName(request.token, scriptTag)) {
@@ -372,6 +377,7 @@ bool XSSAuditor::filterStartToken(const FilterTokenRequest& request)
void XSSAuditor::filterEndToken(const FilterTokenRequest& request)
{
ASSERT(m_scriptTagNestingLevel);
+ m_state = FilteringTokens;
if (hasName(request.token, scriptTag)) {
m_scriptTagNestingLevel--;
ASSERT(request.shouldAllowCDATA || !m_scriptTagNestingLevel);
@@ -381,11 +387,19 @@ void XSSAuditor::filterEndToken(const FilterTokenRequest& request)
bool XSSAuditor::filterCharacterToken(const FilterTokenRequest& request)
{
ASSERT(m_scriptTagNestingLevel);
- if (m_scriptTagFoundInRequest && isContainedInRequest(decodedSnippetForJavaScript(request))) {
+ ASSERT(m_state != Uninitialized);
+ if (m_state == PermittingAdjacentCharacterTokens)
+ return false;
+
+ if ((m_state == SuppressingAdjacentCharacterTokens)
+ || (m_scriptTagFoundInRequest && isContainedInRequest(decodedSnippetForJavaScript(request)))) {
request.token.eraseCharacters();
request.token.appendToCharacter(' '); // Technically, character tokens can't be empty.
+ m_state = SuppressingAdjacentCharacterTokens;
return true;
}
+
+ m_state = PermittingAdjacentCharacterTokens;
return false;
}
@@ -465,11 +479,10 @@ bool XSSAuditor::filterFrameToken(const FilterTokenRequest& request)
ASSERT(request.token.type() == HTMLToken::StartTag);
ASSERT(hasName(request.token, iframeTag) || hasName(request.token, frameTag));
- bool didBlockScript = false;
- if (isContainedInRequest(decodedSnippetForName(request))) {
+ bool didBlockScript = eraseAttributeIfInjected(request, srcdocAttr, String(), ScriptLikeAttribute);
+ if (isContainedInRequest(decodedSnippetForName(request)))
didBlockScript |= eraseAttributeIfInjected(request, srcAttr, String(), SrcLikeAttribute);
- didBlockScript |= eraseAttributeIfInjected(request, srcdocAttr, String(), ScriptLikeAttribute);
- }
+
return didBlockScript;
}
@@ -494,7 +507,7 @@ bool XSSAuditor::filterFormToken(const FilterTokenRequest& request)
ASSERT(request.token.type() == HTMLToken::StartTag);
ASSERT(hasName(request.token, formTag));
- return eraseAttributeIfInjected(request, actionAttr, blankURL().string());
+ return eraseAttributeIfInjected(request, actionAttr, kURLWithUniqueOrigin);
}
bool XSSAuditor::filterInputToken(const FilterTokenRequest& request)
@@ -502,7 +515,7 @@ bool XSSAuditor::filterInputToken(const FilterTokenRequest& request)
ASSERT(request.token.type() == HTMLToken::StartTag);
ASSERT(hasName(request.token, inputTag));
- return eraseAttributeIfInjected(request, formactionAttr, blankURL().string(), SrcLikeAttribute);
+ return eraseAttributeIfInjected(request, formactionAttr, kURLWithUniqueOrigin, SrcLikeAttribute);
}
bool XSSAuditor::filterButtonToken(const FilterTokenRequest& request)
@@ -510,7 +523,7 @@ bool XSSAuditor::filterButtonToken(const FilterTokenRequest& request)
ASSERT(request.token.type() == HTMLToken::StartTag);
ASSERT(hasName(request.token, buttonTag));
- return eraseAttributeIfInjected(request, formactionAttr, blankURL().string(), SrcLikeAttribute);
+ return eraseAttributeIfInjected(request, formactionAttr, kURLWithUniqueOrigin, SrcLikeAttribute);
}
bool XSSAuditor::eraseDangerousAttributesIfInjected(const FilterTokenRequest& request)
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.h b/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.h
index 5249479c630..db2655f4a8a 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.h
@@ -27,9 +27,9 @@
#define XSSAuditor_h
#include "core/html/parser/HTMLToken.h"
-#include "core/platform/network/HTTPParsers.h"
-#include "core/platform/text/SuffixTree.h"
-#include "weborigin/KURL.h"
+#include "platform/network/HTTPParsers.h"
+#include "platform/text/SuffixTree.h"
+#include "platform/weborigin/KURL.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/text/TextEncoding.h"
@@ -69,7 +69,9 @@ private:
enum State {
Uninitialized,
- Initialized
+ FilteringTokens,
+ PermittingAdjacentCharacterTokens,
+ SuppressingAdjacentCharacterTokens
};
enum AttributeKind {
@@ -107,7 +109,7 @@ private:
KURL m_documentURL;
bool m_isEnabled;
- ContentSecurityPolicy::ReflectedXSSDisposition m_xssProtection;
+ ReflectedXSSDisposition m_xssProtection;
bool m_didSendValidCSPHeader;
bool m_didSendValidXSSProtectionHeader;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditorDelegate.cpp b/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditorDelegate.cpp
index a5a4f52b73f..5ea9b66ccf7 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditorDelegate.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditorDelegate.cpp
@@ -27,40 +27,32 @@
#include "core/html/parser/XSSAuditorDelegate.h"
#include "core/dom/Document.h"
+#include "core/frame/Frame.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
#include "core/loader/PingLoader.h"
-#include "core/page/Frame.h"
-#include "core/platform/JSONValues.h"
-#include "core/platform/network/FormData.h"
-#include "weborigin/SecurityOrigin.h"
+#include "platform/JSONValues.h"
+#include "platform/network/FormData.h"
+#include "platform/weborigin/SecurityOrigin.h"
#include "wtf/text/StringBuilder.h"
namespace WebCore {
-XSSAuditorDelegate::XSSAuditorDelegate(Document* document)
- : m_document(document)
- , m_didSendNotifications(false)
-{
- ASSERT(isMainThread());
- ASSERT(m_document);
-}
-
-static inline String buildConsoleError(const XSSInfo& xssInfo)
+String XSSInfo::buildConsoleError() const
{
StringBuilder message;
message.append("The XSS Auditor ");
- message.append(xssInfo.m_didBlockEntirePage ? "blocked access to" : "refused to execute a script in");
+ message.append(m_didBlockEntirePage ? "blocked access to" : "refused to execute a script in");
message.append(" '");
- message.append(xssInfo.m_originalURL);
+ message.append(m_originalURL);
message.append("' because ");
- message.append(xssInfo.m_didBlockEntirePage ? "the source code of a script" : "its source code");
+ message.append(m_didBlockEntirePage ? "the source code of a script" : "its source code");
message.append(" was found within the request.");
- if (xssInfo.m_didSendCSPHeader)
+ if (m_didSendCSPHeader)
message.append(" The server sent a 'Content-Security-Policy' header requesting this behavior.");
- else if (xssInfo.m_didSendXSSProtectionHeader)
+ else if (m_didSendXSSProtectionHeader)
message.append(" The server sent an 'X-XSS-Protection' header requesting this behavior.");
else
message.append(" The auditor was enabled as the server sent neither an 'X-XSS-Protection' nor 'Content-Security-Policy' header.");
@@ -68,14 +60,27 @@ static inline String buildConsoleError(const XSSInfo& xssInfo)
return message.toString();
}
+bool XSSInfo::isSafeToSendToAnotherThread() const
+{
+ return m_originalURL.isSafeToSendToAnotherThread();
+}
+
+XSSAuditorDelegate::XSSAuditorDelegate(Document* document)
+ : m_document(document)
+ , m_didSendNotifications(false)
+{
+ ASSERT(isMainThread());
+ ASSERT(m_document);
+}
+
PassRefPtr<FormData> XSSAuditorDelegate::generateViolationReport(const XSSInfo& xssInfo)
{
ASSERT(isMainThread());
- FrameLoader* frameLoader = m_document->frame()->loader();
+ FrameLoader& frameLoader = m_document->frame()->loader();
String httpBody;
- if (frameLoader->documentLoader()) {
- if (FormData* formData = frameLoader->documentLoader()->originalRequest().httpBody())
+ if (frameLoader.documentLoader()) {
+ if (FormData* formData = frameLoader.documentLoader()->originalRequest().httpBody())
httpBody = formData->flattenToString();
}
@@ -93,25 +98,25 @@ void XSSAuditorDelegate::didBlockScript(const XSSInfo& xssInfo)
{
ASSERT(isMainThread());
- m_document->addConsoleMessage(JSMessageSource, ErrorMessageLevel, buildConsoleError(xssInfo));
+ m_document->addConsoleMessage(JSMessageSource, ErrorMessageLevel, xssInfo.buildConsoleError());
// stopAllLoaders can detach the Frame, so protect it.
RefPtr<Frame> protect(m_document->frame());
- FrameLoader* frameLoader = m_document->frame()->loader();
+ FrameLoader& frameLoader = m_document->frame()->loader();
if (xssInfo.m_didBlockEntirePage)
- frameLoader->stopAllLoaders();
+ frameLoader.stopAllLoaders();
if (!m_didSendNotifications) {
m_didSendNotifications = true;
- frameLoader->client()->didDetectXSS(m_document->url(), xssInfo.m_didBlockEntirePage);
+ frameLoader.client()->didDetectXSS(m_document->url(), xssInfo.m_didBlockEntirePage);
if (!m_reportURL.isEmpty())
PingLoader::sendViolationReport(m_document->frame(), m_reportURL, generateViolationReport(xssInfo), PingLoader::XSSAuditorViolationReport);
}
if (xssInfo.m_didBlockEntirePage)
- m_document->frame()->navigationScheduler()->scheduleLocationChange(m_document->securityOrigin(), SecurityOrigin::urlWithUniqueSecurityOrigin(), String());
+ m_document->frame()->navigationScheduler().scheduleLocationChange(m_document, SecurityOrigin::urlWithUniqueSecurityOrigin(), String());
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditorDelegate.h b/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditorDelegate.h
index 5dda5f5b5e2..1fbfb20b01c 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditorDelegate.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditorDelegate.h
@@ -26,7 +26,7 @@
#ifndef XSSAuditorDelegate_h
#define XSSAuditorDelegate_h
-#include "weborigin/KURL.h"
+#include "platform/weborigin/KURL.h"
#include "wtf/OwnPtr.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/Vector.h"
@@ -45,6 +45,9 @@ public:
return adoptPtr(new XSSInfo(originalURL, didBlockEntirePage, didSendXSSProtectionHeader, didSendCSPHeader));
}
+ String buildConsoleError() const;
+ bool isSafeToSendToAnotherThread() const;
+
String m_originalURL;
bool m_didBlockEntirePage;
bool m_didSendXSSProtectionHeader;