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

Unified Diff: Source/core/editing/StyledMarkupSerializer.cpp

Issue 1188693005: Introduce StyledMarkupTraverser to StyledMarkupSerializer (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/editing/StyledMarkupSerializer.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/editing/StyledMarkupSerializer.cpp
diff --git a/Source/core/editing/StyledMarkupSerializer.cpp b/Source/core/editing/StyledMarkupSerializer.cpp
index d171a02c2eb223148fd75f7efa7adcf92688d47c..2a7c9916b68595770afa89e505ddb8d3ec32da2f 100644
--- a/Source/core/editing/StyledMarkupSerializer.cpp
+++ b/Source/core/editing/StyledMarkupSerializer.cpp
@@ -59,6 +59,38 @@ TextOffset toTextOffset(const PositionType& position)
return TextOffset(toText(position.containerNode()), position.offsetInContainerNode());
}
+template<typename Strategy>
+class Traverser {
+ WTF_MAKE_NONCOPYABLE(Traverser);
+ STACK_ALLOCATED();
+public:
+ Traverser()
+ : Traverser(nullptr, nullptr)
+ {
+ }
+ Traverser(StyledMarkupAccumulator* accumulator, Node* lastClosed)
yosin_UTC9 2015/06/17 13:07:57 How about moving this ctor before L244, I hope cod
hajimehoshi 2015/06/18 02:04:56 Done.
+ : m_accumulator(accumulator)
yosin_UTC9 2015/06/17 13:07:57 ASSERT(m_lastClosed || !m_accumlator)? I think wh
hajimehoshi 2015/06/18 02:04:56 Done.
+ , m_lastClosed(lastClosed)
yosin_UTC9 2015/06/17 13:07:58 It is better to initialize |m_wrappingStyle| to nu
hajimehoshi 2015/06/18 02:04:56 Done.
+ {
+ if (m_accumulator && m_lastClosed && Strategy::parent(*m_lastClosed))
yosin_UTC9 2015/06/17 13:07:58 Let's use early return pattern.
hajimehoshi 2015/06/18 02:04:56 Done.
+ m_wrappingStyle = EditingStyle::wrappingStyleForSerialization(Strategy::parent(*m_lastClosed), m_accumulator->shouldAnnotate());
yosin_UTC9 2015/06/17 13:31:02 Since, we use |m_accumulator->shouldAnnotate()| fo
hajimehoshi 2015/06/18 02:04:56 Done.
+ }
+ Node* traverseNodesForSerialization(Node*, Node*);
+ void wrapWithNode(ContainerNode&, PassRefPtrWillBeRawPtr<EditingStyle>);
+ RefPtrWillBeRawPtr<EditingStyle> createInlineStyleIfNeeded(Node&);
+
+private:
+ void appendStartMarkup(Node&);
+ void appendEndMarkup(Node&);
+ RefPtrWillBeRawPtr<EditingStyle> createInlineStyle(Element&);
+ bool needsInlineStyle(const Element&);
+ bool shouldApplyWrappingStyle(const Node&) const;
+
+ StyledMarkupAccumulator* m_accumulator;
+ Node* m_lastClosed;
+ RefPtrWillBeMember<EditingStyle> m_wrappingStyle;
+};
+
} // namespace
using namespace HTMLNames;
@@ -118,7 +150,7 @@ static PassRefPtrWillBeRawPtr<EditingStyle> styleFromMatchedRulesAndInlineDecl(c
template<typename Strategy>
String StyledMarkupSerializer<Strategy>::createMarkup()
{
- StyledMarkupAccumulator markupAccumulator(m_shouldResolveURLs, toTextOffset(m_start.parentAnchoredEquivalent()), toTextOffset(m_end.parentAnchoredEquivalent()), m_start.document(), m_shouldAnnotate);
+ StyledMarkupAccumulator markupAccumulator(m_shouldResolveURLs, toTextOffset(m_start.parentAnchoredEquivalent()), toTextOffset(m_end.parentAnchoredEquivalent()), m_start.document(), m_shouldAnnotate, m_convertBlocksToInlines);
Node* pastEnd = m_end.nodeAsRangePastLastNode();
@@ -138,7 +170,10 @@ String StyledMarkupSerializer<Strategy>::createMarkup()
}
}
- Node* lastClosed = serializeNodes(firstNode, pastEnd, &markupAccumulator);
+ if (!m_lastClosed)
+ m_lastClosed = Traverser<Strategy>().traverseNodesForSerialization(firstNode, pastEnd);
+ Traverser<Strategy> traverser(&markupAccumulator, m_lastClosed);
+ Node* lastClosed = traverser.traverseNodesForSerialization(firstNode, pastEnd);
if (m_highestNodeToBeSerialized && lastClosed) {
// TODO(hajimehoshi): This is calculated at createMarkupInternal too.
@@ -153,7 +188,7 @@ String StyledMarkupSerializer<Strategy>::createMarkup()
// Also include all of the ancestors of lastClosed up to this special ancestor.
// FIXME: What is ancestor?
for (ContainerNode* ancestor = Strategy::parent(*lastClosed); ancestor; ancestor = Strategy::parent(*ancestor)) {
- if (ancestor == fullySelectedRoot && !convertBlocksToInlines()) {
+ if (ancestor == fullySelectedRoot && !markupAccumulator.convertBlocksToInlines()) {
RefPtrWillBeRawPtr<EditingStyle> fullySelectedRootStyle = styleFromMatchedRulesAndInlineDecl(fullySelectedRoot);
// Bring the background attribute over, but not as an attribute because a background attribute on a div
@@ -173,14 +208,14 @@ String StyledMarkupSerializer<Strategy>::createMarkup()
markupAccumulator.wrapWithStyleNode(fullySelectedRootStyle->style());
}
} else {
- RefPtrWillBeRawPtr<EditingStyle> style = createInlineStyleIfNeeded(*ancestor);
+ RefPtrWillBeRawPtr<EditingStyle> style = traverser.createInlineStyleIfNeeded(*ancestor);
// Since this node and all the other ancestors are not in the selection we want
// styles that affect the exterior of the node not to be not included.
// If the node is not fully selected by the range, then we don't want to keep styles that affect its relationship to the nodes around it
// only the ones that affect it and the nodes within it.
if (style && style->style())
style->style()->removeProperty(CSSPropertyFloat);
- wrapWithNode(markupAccumulator, *ancestor, style);
+ traverser.wrapWithNode(*ancestor, style);
}
if (ancestor == m_highestNodeToBeSerialized)
@@ -196,17 +231,7 @@ String StyledMarkupSerializer<Strategy>::createMarkup()
}
template<typename Strategy>
-Node* StyledMarkupSerializer<Strategy>::serializeNodes(Node* startNode, Node* pastEnd, StyledMarkupAccumulator* markupAccumulator)
-{
- if (!m_lastClosed)
- m_lastClosed = traverseNodesForSerialization(startNode, pastEnd, nullptr);
- if (m_lastClosed && Strategy::parent(*m_lastClosed))
- m_wrappingStyle = EditingStyle::wrappingStyleForSerialization(Strategy::parent(*m_lastClosed), shouldAnnotate());
- return traverseNodesForSerialization(startNode, pastEnd, markupAccumulator);
-}
-
-template<typename Strategy>
-Node* StyledMarkupSerializer<Strategy>::traverseNodesForSerialization(Node* startNode, Node* pastEnd, StyledMarkupAccumulator* markupAccumulator)
+Node* Traverser<Strategy>::traverseNodesForSerialization(Node* startNode, Node* pastEnd)
{
WillBeHeapVector<RawPtrWillBeMember<ContainerNode>> ancestorsToClose;
Node* next;
@@ -234,16 +259,14 @@ Node* StyledMarkupSerializer<Strategy>::traverseNodesForSerialization(Node* star
next = pastEnd;
} else {
// Add the node to the markup if we're not skipping the descendants
- if (markupAccumulator)
- appendStartMarkup(*markupAccumulator, *n);
+ appendStartMarkup(*n);
// If node has no children, close the tag now.
if (Strategy::hasChildren(*n)) {
ancestorsToClose.append(toContainerNode(n));
continue;
}
- if (markupAccumulator && n->isElementNode())
- markupAccumulator->appendEndTag(toElement(*n));
+ appendEndMarkup(*n);
lastClosed = n;
}
@@ -259,8 +282,7 @@ Node* StyledMarkupSerializer<Strategy>::traverseNodesForSerialization(Node* star
if (next != pastEnd && Strategy::isDescendantOf(*next, *ancestor))
break;
// Not at the end of the range, close ancestors up to sibling of next node.
- if (markupAccumulator && ancestor->isElementNode())
- markupAccumulator->appendEndTag(toElement(*ancestor));
+ appendEndMarkup(*ancestor);
lastClosed = ancestor;
ancestorsToClose.removeLast();
}
@@ -279,10 +301,8 @@ Node* StyledMarkupSerializer<Strategy>::traverseNodesForSerialization(Node* star
// or b) ancestors that we never encountered during a pre-order traversal starting at startNode:
ASSERT(startNode);
ASSERT(Strategy::isDescendantOf(*startNode, *parent));
- if (markupAccumulator) {
- RefPtrWillBeRawPtr<EditingStyle> style = createInlineStyleIfNeeded(*parent);
- wrapWithNode(*markupAccumulator, *parent, style);
- }
+ RefPtrWillBeRawPtr<EditingStyle> style = createInlineStyleIfNeeded(*parent);
+ wrapWithNode(*parent, style);
lastClosed = parent;
}
}
@@ -291,54 +311,60 @@ Node* StyledMarkupSerializer<Strategy>::traverseNodesForSerialization(Node* star
}
template<typename Strategy>
-bool StyledMarkupSerializer<Strategy>::needsInlineStyle(const Element& element)
+bool Traverser<Strategy>::needsInlineStyle(const Element& element)
{
if (!element.isHTMLElement())
return false;
- if (shouldAnnotate())
+ if (m_accumulator->shouldAnnotate())
return true;
- return convertBlocksToInlines() && isBlock(&element);
+ return m_accumulator->convertBlocksToInlines() && isBlock(&element);
}
template<typename Strategy>
-void StyledMarkupSerializer<Strategy>::wrapWithNode(StyledMarkupAccumulator& accumulator, ContainerNode& node, PassRefPtrWillBeRawPtr<EditingStyle> style)
+void Traverser<Strategy>::wrapWithNode(ContainerNode& node, PassRefPtrWillBeRawPtr<EditingStyle> style)
{
+ if (!m_accumulator)
+ return;
StringBuilder markup;
if (node.isDocumentNode()) {
MarkupFormatter::appendXMLDeclaration(markup, toDocument(node));
- accumulator.pushMarkup(markup.toString());
+ m_accumulator->pushMarkup(markup.toString());
return;
}
if (!node.isElementNode())
return;
Element& element = toElement(node);
if (shouldApplyWrappingStyle(element) || needsInlineStyle(element))
yosin_UTC9 2015/06/17 14:33:06 Note: in ALL-IN-ONE, we check |shouldApplyWrapping
hajimehoshi 2015/06/18 02:04:56 As we talked, let's do such fix later.
- accumulator.appendElementWithInlineStyle(markup, element, style);
+ m_accumulator->appendElementWithInlineStyle(markup, element, style);
else
- accumulator.appendElement(markup, element);
- accumulator.pushMarkup(markup.toString());
- accumulator.appendEndTag(toElement(node));
+ m_accumulator->appendElement(markup, element);
+ m_accumulator->pushMarkup(markup.toString());
+ m_accumulator->appendEndTag(toElement(node));
}
template<typename Strategy>
-RefPtrWillBeRawPtr<EditingStyle> StyledMarkupSerializer<Strategy>::createInlineStyleIfNeeded(Node& node)
+RefPtrWillBeRawPtr<EditingStyle> Traverser<Strategy>::createInlineStyleIfNeeded(Node& node)
{
+ if (!m_accumulator)
+ return nullptr;
if (!node.isElementNode())
return nullptr;
RefPtrWillBeRawPtr<EditingStyle> inlineStyle = createInlineStyle(toElement(node));
- if (convertBlocksToInlines() && isBlock(&node))
+ if (m_accumulator->convertBlocksToInlines() && isBlock(&node))
yosin_UTC9 2015/06/17 14:06:28 We have two |m_accumulator->convertBlocksToInlines
hajimehoshi 2015/06/18 02:04:56 Done.
inlineStyle->forceInline();
return inlineStyle;
}
template<typename Strategy>
-void StyledMarkupSerializer<Strategy>::appendStartMarkup(StyledMarkupAccumulator& accumulator, Node& node)
+void Traverser<Strategy>::appendStartMarkup(Node& node)
{
+ if (!m_accumulator)
+ return;
switch (node.nodeType()) {
case Node::TEXT_NODE: {
Text& text = toText(node);
if (text.parentElement() && text.parentElement()->tagQName() == textareaTag) {
yosin_UTC9 2015/06/17 13:31:01 isHTMLTextAreaElement(text.parentElement())
hajimehoshi 2015/06/18 02:04:56 Done.
- accumulator.appendText(text);
+ m_accumulator->appendText(text);
break;
}
RefPtrWillBeRawPtr<EditingStyle> inlineStyle = nullptr;
@@ -350,34 +376,41 @@ void StyledMarkupSerializer<Strategy>::appendStartMarkup(StyledMarkupAccumulator
// FIXME: Should this be included in forceInline?
inlineStyle->style()->setProperty(CSSPropertyFloat, CSSValueNone);
}
- accumulator.appendTextWithInlineStyle(text, inlineStyle);
+ m_accumulator->appendTextWithInlineStyle(text, inlineStyle);
yosin_UTC9 2015/06/17 13:31:02 Note: For supporting composed tree, we should have
hajimehoshi 2015/06/18 02:04:56 As we talked, do such fix later.
break;
}
case Node::ELEMENT_NODE: {
Element& element = toElement(node);
- if ((element.isHTMLElement() && shouldAnnotate()) || shouldApplyWrappingStyle(element)) {
+ if ((element.isHTMLElement() && m_accumulator->shouldAnnotate()) || shouldApplyWrappingStyle(element)) {
RefPtrWillBeRawPtr<EditingStyle> inlineStyle = createInlineStyle(element);
- accumulator.appendElementWithInlineStyle(element, inlineStyle);
+ m_accumulator->appendElementWithInlineStyle(element, inlineStyle);
break;
}
- accumulator.appendElement(element);
+ m_accumulator->appendElement(element);
break;
}
default:
- accumulator.appendStartMarkup(node);
+ m_accumulator->appendStartMarkup(node);
break;
}
}
template<typename Strategy>
-bool StyledMarkupSerializer<Strategy>::shouldApplyWrappingStyle(const Node& node) const
+void Traverser<Strategy>::appendEndMarkup(Node& node)
+{
+ if (m_accumulator && node.isElementNode())
yosin_UTC9 2015/06/17 13:31:02 Let's use early return pattern.
hajimehoshi 2015/06/18 02:04:56 Done.
+ m_accumulator->appendEndTag(toElement(node));
yosin_UTC9 2015/06/17 14:06:28 We need to check whether we use empty tag or not,
hajimehoshi 2015/06/18 02:04:56 As we talked, do such fix later.
+}
+
+template<typename Strategy>
+bool Traverser<Strategy>::shouldApplyWrappingStyle(const Node& node) const
{
return m_lastClosed && Strategy::parent(*m_lastClosed) == Strategy::parent(node)
&& m_wrappingStyle && m_wrappingStyle->style();
}
template<typename Strategy>
-RefPtrWillBeRawPtr<EditingStyle> StyledMarkupSerializer<Strategy>::createInlineStyle(Element& element)
+RefPtrWillBeRawPtr<EditingStyle> Traverser<Strategy>::createInlineStyle(Element& element)
{
RefPtrWillBeRawPtr<EditingStyle> inlineStyle = nullptr;
@@ -392,7 +425,7 @@ RefPtrWillBeRawPtr<EditingStyle> StyledMarkupSerializer<Strategy>::createInlineS
if (element.isStyledElement() && element.inlineStyle())
inlineStyle->overrideWithStyle(element.inlineStyle());
- if (element.isHTMLElement() && shouldAnnotate())
+ if (element.isHTMLElement() && m_accumulator->shouldAnnotate())
inlineStyle->mergeStyleFromRulesForSerialization(&toHTMLElement(element));
return inlineStyle;
« no previous file with comments | « Source/core/editing/StyledMarkupSerializer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698