Remove the ability to parse HTML fragments

Also, removed a bunch of show() function from the custom element microtask
queue that bottom out in innerHTML.

R=eseidel@chromium.org

Review URL: https://codereview.chromium.org/665613003
This commit is contained in:
Adam Barth 2014-10-24 16:51:11 -07:00
parent 34bed5e6a7
commit b07dff7033
22 changed files with 2 additions and 332 deletions

View File

@ -68,9 +68,4 @@ PassRefPtrWillBeRawPtr<Node> DocumentFragment::cloneNode(bool deep)
return clone.release();
}
void DocumentFragment::parseHTML(const String& source, Element* contextElement)
{
HTMLDocumentParser::parseDocumentFragment(source, this, contextElement);
}
} // namespace blink

View File

@ -33,8 +33,6 @@ class DocumentFragment : public ContainerNode {
public:
static PassRefPtrWillBeRawPtr<DocumentFragment> create(Document&);
void parseHTML(const String&, Element* contextElement);
virtual bool canContainRangeEndPoint() const override final { return true; }
virtual bool isTemplateContent() const { return false; }

View File

@ -1541,55 +1541,6 @@ void Element::dispatchFocusOutEvent(const AtomicString& eventType, Element* newF
dispatchScopedEventDispatchMediator(FocusOutEventDispatchMediator::create(FocusEvent::create(eventType, true, false, document().domWindow(), 0, newFocusedElement)));
}
String Element::innerHTML() const
{
return createMarkup(this, ChildrenOnly);
}
String Element::outerHTML() const
{
return createMarkup(this);
}
void Element::setInnerHTML(const String& html, ExceptionState& exceptionState)
{
if (RefPtrWillBeRawPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, this, "innerHTML", exceptionState)) {
ContainerNode* container = this;
if (isHTMLTemplateElement(*this))
container = toHTMLTemplateElement(this)->content();
replaceChildrenWithFragment(container, fragment.release(), exceptionState);
}
}
void Element::setOuterHTML(const String& html, ExceptionState& exceptionState)
{
Node* p = parentNode();
if (!p) {
exceptionState.throwDOMException(NoModificationAllowedError, "This element has no parent node.");
return;
}
if (!p->isElementNode()) {
exceptionState.throwDOMException(NoModificationAllowedError, "This element's parent is of type '" + p->nodeName() + "', which is not an element node.");
return;
}
RefPtrWillBeRawPtr<Element> parent = toElement(p);
RefPtrWillBeRawPtr<Node> prev = previousSibling();
RefPtrWillBeRawPtr<Node> next = nextSibling();
RefPtrWillBeRawPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, parent.get(), "outerHTML", exceptionState);
if (exceptionState.hadException())
return;
parent->replaceChild(fragment.release(), this, exceptionState);
RefPtrWillBeRawPtr<Node> node = next ? next->previousSibling() : 0;
if (!exceptionState.hadException() && node && node->isTextNode())
mergeWithNextTextNode(toText(node.get()), exceptionState);
if (!exceptionState.hadException() && prev && prev->isTextNode())
mergeWithNextTextNode(toText(prev.get()), exceptionState);
}
String Element::innerText()
{
// We need to update layout, since plainText uses line boxes in the render tree.

View File

@ -308,10 +308,6 @@ public:
String innerText();
String outerText();
String innerHTML() const;
String outerHTML() const;
void setInnerHTML(const String&, ExceptionState&);
void setOuterHTML(const String&, ExceptionState&);
String textFromChildren();

View File

@ -94,12 +94,4 @@ void CustomElementMicrotaskImportStep::trace(Visitor* visitor)
CustomElementMicrotaskStep::trace(visitor);
}
#if !defined(NDEBUG)
void CustomElementMicrotaskImportStep::show(unsigned indent)
{
fprintf(stderr, "%*sImport(wait=%d sync=%d, url=%s)\n", indent, "", shouldWaitForImport(), m_import && m_import->isSync(), m_import ? m_import->url().string().utf8().data() : "null");
m_queue->show(indent + 1);
}
#endif
} // namespace blink

View File

@ -74,9 +74,6 @@ private:
// CustomElementMicrotaskStep
virtual Result process() override final;
#if !defined(NDEBUG)
virtual void show(unsigned indent) override;
#endif
WeakPtrWillBeWeakMember<HTMLImportChild> m_import;
#if !ENABLE(OILPAN)
WeakPtrFactory<CustomElementMicrotaskImportStep> m_weakFactory;

View File

@ -22,16 +22,4 @@ void CustomElementMicrotaskQueueBase::trace(Visitor* visitor)
visitor->trace(m_queue);
}
#if !defined(NDEBUG)
void CustomElementMicrotaskQueueBase::show(unsigned indent)
{
for (unsigned q = 0; q < m_queue.size(); ++q) {
if (m_queue[q])
m_queue[q]->show(indent);
else
fprintf(stderr, "%*snull\n", indent, "");
}
}
#endif
} // namespace blink

View File

@ -26,10 +26,6 @@ public:
void trace(Visitor*);
#if !defined(NDEBUG)
void show(unsigned indent);
#endif
protected:
CustomElementMicrotaskQueueBase() : m_inDispatch(false) { }
virtual void doDispatch() = 0;

View File

@ -65,12 +65,4 @@ void CustomElementMicrotaskResolutionStep::trace(Visitor* visitor)
CustomElementMicrotaskStep::trace(visitor);
}
#if !defined(NDEBUG)
void CustomElementMicrotaskResolutionStep::show(unsigned indent)
{
fprintf(stderr, "%*sResolution: ", indent, "");
m_element->outerHTML().show();
}
#endif
} // namespace blink

View File

@ -57,10 +57,6 @@ private:
virtual Result process() override;
#if !defined(NDEBUG)
virtual void show(unsigned indent) override;
#endif
RefPtrWillBeMember<CustomElementRegistrationContext> m_context;
RefPtrWillBeMember<Element> m_element;
CustomElementDescriptor m_descriptor;

View File

@ -66,14 +66,4 @@ bool CustomElementMicrotaskRunQueue::isEmpty() const
return m_syncQueue->isEmpty() && m_asyncQueue->isEmpty();
}
#if !defined(NDEBUG)
void CustomElementMicrotaskRunQueue::show(unsigned indent)
{
fprintf(stderr, "Sync:\n");
m_syncQueue->show(indent);
fprintf(stderr, "Async:\n");
m_asyncQueue->show(indent);
}
#endif
} // namespace blink

View File

@ -27,10 +27,6 @@ public:
void trace(Visitor*);
#if !defined(NDEBUG)
void show(unsigned indent);
#endif
private:
CustomElementMicrotaskRunQueue();

View File

@ -50,10 +50,6 @@ public:
virtual Result process() = 0;
virtual void trace(Visitor*) { }
#if !defined(NDEBUG)
virtual void show(unsigned indent) = 0;
#endif
};
}

View File

@ -103,22 +103,6 @@ PassRefPtrWillBeRawPtr<Node> ShadowRoot::cloneNode(bool, ExceptionState& excepti
return nullptr;
}
String ShadowRoot::innerHTML() const
{
return createMarkup(this, ChildrenOnly);
}
void ShadowRoot::setInnerHTML(const String& markup, ExceptionState& exceptionState)
{
if (isOrphan()) {
exceptionState.throwDOMException(InvalidAccessError, "The ShadowRoot does not have a host.");
return;
}
if (RefPtrWillBeRawPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, host(), "innerHTML", exceptionState))
replaceChildrenWithFragment(this, fragment.release(), exceptionState);
}
void ShadowRoot::recalcStyle(StyleRecalcChange change)
{
// ShadowRoot doesn't support custom callbacks.

View File

@ -102,9 +102,6 @@ public:
ShadowRoot* olderShadowRoot() const { return next(); }
String innerHTML() const;
void setInnerHTML(const String&, ExceptionState&);
PassRefPtrWillBeRawPtr<Node> cloneNode(bool, ExceptionState&);
PassRefPtrWillBeRawPtr<Node> cloneNode(ExceptionState& exceptionState) { return cloneNode(true, exceptionState); }

View File

@ -28,8 +28,6 @@ interface ShadowRoot : DocumentFragment {
readonly attribute Element activeElement;
readonly attribute ShadowRoot olderShadowRoot;
[TreatNullAs=NullString, CustomElementCallbacks, RaisesException=Setter] attribute DOMString innerHTML;
[RaisesException] Node cloneNode([Default=Undefined] optional boolean deep);
Selection getSelection();
Element getElementById([Default=Undefined] optional DOMString elementId);

View File

@ -971,116 +971,8 @@ void CompositeEditCommand::moveParagraph(const VisiblePosition& startOfParagraph
void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagraphToMove, const VisiblePosition& endOfParagraphToMove, const VisiblePosition& destination, bool preserveSelection, bool preserveStyle, Node* constrainingAncestor)
{
if (startOfParagraphToMove == destination || startOfParagraphToMove.isNull())
return;
int startIndex = -1;
int endIndex = -1;
int destinationIndex = -1;
bool originalIsDirectional = endingSelection().isDirectional();
if (preserveSelection && !endingSelection().isNone()) {
VisiblePosition visibleStart = endingSelection().visibleStart();
VisiblePosition visibleEnd = endingSelection().visibleEnd();
bool startAfterParagraph = comparePositions(visibleStart, endOfParagraphToMove) > 0;
bool endBeforeParagraph = comparePositions(visibleEnd, startOfParagraphToMove) < 0;
if (!startAfterParagraph && !endBeforeParagraph) {
bool startInParagraph = comparePositions(visibleStart, startOfParagraphToMove) >= 0;
bool endInParagraph = comparePositions(visibleEnd, endOfParagraphToMove) <= 0;
startIndex = 0;
if (startInParagraph) {
RefPtrWillBeRawPtr<Range> startRange = Range::create(document(), startOfParagraphToMove.deepEquivalent().parentAnchoredEquivalent(), visibleStart.deepEquivalent().parentAnchoredEquivalent());
startIndex = TextIterator::rangeLength(startRange.get(), true);
}
endIndex = 0;
if (endInParagraph) {
RefPtrWillBeRawPtr<Range> endRange = Range::create(document(), startOfParagraphToMove.deepEquivalent().parentAnchoredEquivalent(), visibleEnd.deepEquivalent().parentAnchoredEquivalent());
endIndex = TextIterator::rangeLength(endRange.get(), true);
}
}
}
VisiblePosition beforeParagraph = startOfParagraphToMove.previous(CannotCrossEditingBoundary);
VisiblePosition afterParagraph(endOfParagraphToMove.next(CannotCrossEditingBoundary));
// We upstream() the end and downstream() the start so that we don't include collapsed whitespace in the move.
// When we paste a fragment, spaces after the end and before the start are treated as though they were rendered.
Position start = startOfParagraphToMove.deepEquivalent().downstream();
Position end = endOfParagraphToMove.deepEquivalent().upstream();
// start and end can't be used directly to create a Range; they are "editing positions"
Position startRangeCompliant = start.parentAnchoredEquivalent();
Position endRangeCompliant = end.parentAnchoredEquivalent();
RefPtrWillBeRawPtr<Range> range = Range::create(document(), startRangeCompliant.deprecatedNode(), startRangeCompliant.deprecatedEditingOffset(), endRangeCompliant.deprecatedNode(), endRangeCompliant.deprecatedEditingOffset());
// FIXME: This is an inefficient way to preserve style on nodes in the paragraph to move. It
// shouldn't matter though, since moved paragraphs will usually be quite small.
RefPtrWillBeRawPtr<DocumentFragment> fragment = startOfParagraphToMove != endOfParagraphToMove ?
createFragmentFromMarkup(document(), createMarkup(range.get(), 0, DoNotAnnotateForInterchange, true, DoNotResolveURLs, constrainingAncestor)) : nullptr;
// A non-empty paragraph's style is moved when we copy and move it. We don't move
// anything if we're given an empty paragraph, but an empty paragraph can have style
// too, <div><b><br></b></div> for example. Save it so that we can preserve it later.
RefPtrWillBeRawPtr<EditingStyle> styleInEmptyParagraph = nullptr;
if (startOfParagraphToMove == endOfParagraphToMove && preserveStyle) {
styleInEmptyParagraph = EditingStyle::create(startOfParagraphToMove.deepEquivalent());
styleInEmptyParagraph->mergeTypingStyle(&document());
// The moved paragraph should assume the block style of the destination.
styleInEmptyParagraph->removeBlockProperties();
}
// FIXME (5098931): We should add a new insert action "WebViewInsertActionMoved" and call shouldInsertFragment here.
setEndingSelection(VisibleSelection(start, end, DOWNSTREAM));
document().frame()->spellChecker().clearMisspellingsAndBadGrammar(endingSelection());
deleteSelection(false, false, false);
ASSERT(destination.deepEquivalent().inDocument());
cleanupAfterDeletion(destination);
ASSERT(destination.deepEquivalent().inDocument());
// Add a br if pruning an empty block level element caused a collapse. For example:
// foo^
// <div>bar</div>
// baz
// Imagine moving 'bar' to ^. 'bar' will be deleted and its div pruned. That would
// cause 'baz' to collapse onto the line with 'foobar' unless we insert a br.
// Must recononicalize these two VisiblePositions after the pruning above.
beforeParagraph = VisiblePosition(beforeParagraph.deepEquivalent());
afterParagraph = VisiblePosition(afterParagraph.deepEquivalent());
if (beforeParagraph.isNotNull() && (!isEndOfParagraph(beforeParagraph) || beforeParagraph == afterParagraph)) {
// Need an updateLayout here in case inserting the br has split a text node.
document().updateLayoutIgnorePendingStylesheets();
}
RefPtrWillBeRawPtr<Range> startToDestinationRange(Range::create(document(), firstPositionInNode(document().documentElement()), destination.deepEquivalent().parentAnchoredEquivalent()));
destinationIndex = TextIterator::rangeLength(startToDestinationRange.get(), true);
setEndingSelection(VisibleSelection(destination, originalIsDirectional));
ASSERT(endingSelection().isCaretOrRange());
ReplaceSelectionCommand::CommandOptions options = ReplaceSelectionCommand::SelectReplacement | ReplaceSelectionCommand::MovingParagraph;
if (!preserveStyle)
options |= ReplaceSelectionCommand::MatchStyle;
applyCommandToComposite(ReplaceSelectionCommand::create(document(), fragment, options));
document().frame()->spellChecker().markMisspellingsAndBadGrammar(endingSelection());
if (preserveSelection && startIndex != -1) {
if (Element* documentElement = document().documentElement()) {
// Fragment creation (using createMarkup) incorrectly uses regular
// spaces instead of nbsps for some spaces that were rendered (11475), which
// causes spaces to be collapsed during the move operation. This results
// in a call to rangeFromLocationAndLength with a location past the end
// of the document (which will return null).
RefPtrWillBeRawPtr<Range> start = PlainTextRange(destinationIndex + startIndex).createRangeForSelection(*documentElement);
RefPtrWillBeRawPtr<Range> end = PlainTextRange(destinationIndex + endIndex).createRangeForSelection(*documentElement);
if (start && end)
setEndingSelection(VisibleSelection(start->startPosition(), end->startPosition(), DOWNSTREAM, originalIsDirectional));
}
}
// FIXME(sky): Remove.
// We've probably broken editiing badly by deleting this function...
}
// FIXME: Send an appropriate shouldDeleteRange call.

View File

@ -529,13 +529,6 @@ String createMarkup(const Range* range, WillBeHeapVector<RawPtrWillBeMember<Node
return createMarkupInternal(document, range, updatedRange, nodes, shouldAnnotate, convertBlocksToInlines, shouldResolveURLs, constrainingAncestor);
}
PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentFromMarkup(Document& document, const String& markup)
{
RefPtrWillBeRawPtr<DocumentFragment> fragment = DocumentFragment::create(document);
fragment->parseHTML(markup, nullptr);
return fragment.release();
}
String createMarkup(const Node* node, EChildrenOnly childrenOnly, WillBeHeapVector<RawPtrWillBeMember<Node> >* nodes, EAbsoluteURLs shouldResolveURLs, Vector<QualifiedName>* tagNamesToSkip)
{
if (!node)
@ -545,15 +538,6 @@ String createMarkup(const Node* node, EChildrenOnly childrenOnly, WillBeHeapVect
return accumulator.serializeNodes(const_cast<Node&>(*node), childrenOnly, tagNamesToSkip);
}
PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentForInnerOuterHTML(const String& markup, Element* contextElement, const char* method, ExceptionState& exceptionState)
{
ASSERT(contextElement);
Document& document = isHTMLTemplateElement(*contextElement) ? contextElement->document().ensureTemplateDocument() : contextElement->document();
RefPtrWillBeRawPtr<DocumentFragment> fragment = DocumentFragment::create(document);
fragment->parseHTML(markup, contextElement);
return fragment;
}
void replaceChildrenWithFragment(ContainerNode* container, PassRefPtrWillBeRawPtr<DocumentFragment> fragment, ExceptionState& exceptionState)
{
ASSERT(container);

View File

@ -46,9 +46,6 @@ class Range;
enum EChildrenOnly { IncludeNode, ChildrenOnly };
enum EAbsoluteURLs { DoNotResolveURLs, ResolveAllURLs, ResolveNonLocalURLs };
PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentFromMarkup(Document&, const String& markup);
PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentForInnerOuterHTML(const String&, Element*, const char* method, ExceptionState&);
// These methods are used by HTMLElement & ShadowRoot to replace the
// children with respected fragment/text.
void replaceChildrenWithFragment(ContainerNode*, PassRefPtrWillBeRawPtr<DocumentFragment>, ExceptionState&);

View File

@ -167,14 +167,3 @@ v8::Handle<v8::Object> HTMLElement::wrap(v8::Handle<v8::Object> creationContext,
}
} // namespace blink
#ifndef NDEBUG
// For use in the debugger
void dumpInnerHTML(blink::HTMLElement*);
void dumpInnerHTML(blink::HTMLElement* element)
{
printf("%s\n", element->innerHTML().ascii().data());
}
#endif

View File

@ -29,7 +29,6 @@
#include "base/bind.h"
#include "core/HTMLNames.h"
#include "core/css/MediaValuesCached.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/Element.h"
#include "core/frame/LocalFrame.h"
#include "core/html/HTMLDocument.h"
@ -46,22 +45,6 @@
namespace blink {
// This is a direct transcription of step 4 from:
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#fragment-case
static HTMLTokenizer::State tokenizerStateForContextElement(Element* contextElement, bool reportErrors, const HTMLParserOptions& options)
{
if (!contextElement)
return HTMLTokenizer::DataState;
const QualifiedName& contextTag = contextElement->tagQName();
if (contextTag == HTMLNames::styleTag)
return HTMLTokenizer::RAWTEXTState;
if (contextTag == HTMLNames::scriptTag)
return HTMLTokenizer::ScriptDataState;
return HTMLTokenizer::DataState;
}
HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document, bool reportErrors)
: DecodedDataDocumentParser(document)
, m_options(&document)
@ -78,25 +61,6 @@ HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document, bool reportErrors
ASSERT(shouldUseThreading() || (m_token && m_tokenizer));
}
// FIXME: Member variables should be grouped into self-initializing structs to
// minimize code duplication between these constructors.
HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* contextElement)
: DecodedDataDocumentParser(fragment->document())
, m_options(&fragment->document())
, m_token(adoptPtr(new HTMLToken))
, m_tokenizer(HTMLTokenizer::create(m_options))
, m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, m_options))
, m_weakFactory(this)
, m_isFragment(true)
, m_endWasDelayed(false)
, m_haveBackgroundParser(false)
, m_pumpSessionNestingLevel(0)
{
ASSERT(!shouldUseThreading());
bool reportErrors = false; // For now document fragment parsing never reports errors.
m_tokenizer->setState(tokenizerStateForContextElement(contextElement, reportErrors, m_options));
}
HTMLDocumentParser::~HTMLDocumentParser()
{
#if ENABLE(OILPAN)
@ -702,15 +666,6 @@ void HTMLDocumentParser::executeScriptsWaitingForResources()
resumeParsingAfterScriptExecution();
}
void HTMLDocumentParser::parseDocumentFragment(const String& source, DocumentFragment* fragment, Element* contextElement)
{
RefPtrWillBeRawPtr<HTMLDocumentParser> parser = HTMLDocumentParser::create(fragment, contextElement);
parser->insert(source); // Use insert() so that the parser will not yield.
parser->finish();
ASSERT(!parser->processingData()); // Make sure we're done. <rdar://problem/3963151>
parser->detach(); // Allows ~DocumentParser to assert it was detached before destruction.
}
void HTMLDocumentParser::appendBytes(const char* data, size_t length)
{
if (!length || isStopped())

View File

@ -48,7 +48,6 @@ namespace blink {
class BackgroundHTMLParser;
class CompactHTMLToken;
class Document;
class DocumentFragment;
class Element;
class HTMLDocument;
class HTMLParserScheduler;
@ -72,8 +71,6 @@ public:
// Exposed for HTMLParserScheduler
void resumeParsingAfterYield();
static void parseDocumentFragment(const String&, DocumentFragment*, Element* contextElement);
HTMLTokenizer* tokenizer() const { return m_tokenizer.get(); }
TextPosition textPosition() const;
@ -99,16 +96,10 @@ protected:
virtual void finish() override final;
HTMLDocumentParser(HTMLDocument&, bool reportErrors);
HTMLDocumentParser(DocumentFragment*, Element* contextElement);
HTMLTreeBuilder* treeBuilder() const { return m_treeBuilder.get(); }
private:
static PassRefPtrWillBeRawPtr<HTMLDocumentParser> create(DocumentFragment* fragment, Element* contextElement)
{
return adoptRefWillBeNoop(new HTMLDocumentParser(fragment, contextElement));
}
virtual HTMLDocumentParser* asHTMLDocumentParser() override final { return this; }
// DocumentParser