| Index: Source/core/editing/StyledMarkupSerializer.cpp
|
| diff --git a/Source/core/editing/StyledMarkupSerializer.cpp b/Source/core/editing/StyledMarkupSerializer.cpp
|
| deleted file mode 100644
|
| index 3bcd75942c156413acb8989a62ffd075028856ed..0000000000000000000000000000000000000000
|
| --- a/Source/core/editing/StyledMarkupSerializer.cpp
|
| +++ /dev/null
|
| @@ -1,484 +0,0 @@
|
| -/*
|
| - * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
|
| - * Copyright (C) 2008, 2009, 2010, 2011 Google Inc. All rights reserved.
|
| - * Copyright (C) 2011 Igalia S.L.
|
| - * Copyright (C) 2011 Motorola Mobility. 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 APPLE COMPUTER, 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 APPLE COMPUTER, 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/editing/StyledMarkupSerializer.h"
|
| -
|
| -#include "core/css/StylePropertySet.h"
|
| -#include "core/dom/Document.h"
|
| -#include "core/dom/Element.h"
|
| -#include "core/dom/Text.h"
|
| -#include "core/dom/shadow/ElementShadow.h"
|
| -#include "core/editing/EditingStyle.h"
|
| -#include "core/editing/EditingUtilities.h"
|
| -#include "core/editing/Serialization.h"
|
| -#include "core/editing/VisibleSelection.h"
|
| -#include "core/editing/VisibleUnits.h"
|
| -#include "core/editing/iterators/TextIterator.h"
|
| -#include "core/html/HTMLBodyElement.h"
|
| -#include "core/html/HTMLElement.h"
|
| -#include "wtf/text/StringBuilder.h"
|
| -
|
| -namespace blink {
|
| -
|
| -namespace {
|
| -
|
| -template<typename Strategy>
|
| -TextOffset toTextOffset(const PositionAlgorithm<Strategy>& position)
|
| -{
|
| - if (position.isNull())
|
| - return TextOffset();
|
| -
|
| - if (!position.computeContainerNode()->isTextNode())
|
| - return TextOffset();
|
| -
|
| - return TextOffset(toText(position.computeContainerNode()), position.offsetInContainerNode());
|
| -}
|
| -
|
| -template<typename EditingStrategy>
|
| -static bool handleSelectionBoundary(const Node&);
|
| -
|
| -template<>
|
| -bool handleSelectionBoundary<EditingStrategy>(const Node&)
|
| -{
|
| - return false;
|
| -}
|
| -
|
| -template<>
|
| -bool handleSelectionBoundary<EditingInComposedTreeStrategy>(const Node& node)
|
| -{
|
| - if (!node.isElementNode())
|
| - return false;
|
| - ElementShadow* shadow = toElement(node).shadow();
|
| - if (!shadow)
|
| - return false;
|
| - return shadow->youngestShadowRoot()->type() == ShadowRootType::UserAgent;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -using namespace HTMLNames;
|
| -
|
| -template<typename Strategy>
|
| -class StyledMarkupTraverser {
|
| - WTF_MAKE_NONCOPYABLE(StyledMarkupTraverser);
|
| - STACK_ALLOCATED();
|
| -public:
|
| - StyledMarkupTraverser();
|
| - StyledMarkupTraverser(StyledMarkupAccumulator*, Node*);
|
| -
|
| - Node* traverse(Node*, Node*);
|
| - void wrapWithNode(ContainerNode&, PassRefPtrWillBeRawPtr<EditingStyle>);
|
| - RefPtrWillBeRawPtr<EditingStyle> createInlineStyleIfNeeded(Node&);
|
| -
|
| -private:
|
| - bool shouldAnnotate() const;
|
| - bool convertBlocksToInlines() const;
|
| - void appendStartMarkup(Node&);
|
| - void appendEndMarkup(Node&);
|
| - RefPtrWillBeRawPtr<EditingStyle> createInlineStyle(Element&);
|
| - bool needsInlineStyle(const Element&);
|
| - bool shouldApplyWrappingStyle(const Node&) const;
|
| -
|
| - StyledMarkupAccumulator* m_accumulator;
|
| - RefPtrWillBeMember<Node> m_lastClosed;
|
| - RefPtrWillBeMember<EditingStyle> m_wrappingStyle;
|
| -};
|
| -
|
| -template<typename Strategy>
|
| -bool StyledMarkupTraverser<Strategy>::shouldAnnotate() const
|
| -{
|
| - return m_accumulator->shouldAnnotate();
|
| -}
|
| -
|
| -template<typename Strategy>
|
| -bool StyledMarkupTraverser<Strategy>::convertBlocksToInlines() const
|
| -{
|
| - return m_accumulator->convertBlocksToInlines();
|
| -}
|
| -
|
| -template<typename Strategy>
|
| -StyledMarkupSerializer<Strategy>::StyledMarkupSerializer(EAbsoluteURLs shouldResolveURLs, EAnnotateForInterchange shouldAnnotate, const PositionAlgorithm<Strategy>& start, const PositionAlgorithm<Strategy>& end, Node* highestNodeToBeSerialized, ConvertBlocksToInlines convertBlocksToInlines)
|
| - : m_start(start)
|
| - , m_end(end)
|
| - , m_shouldResolveURLs(shouldResolveURLs)
|
| - , m_shouldAnnotate(shouldAnnotate)
|
| - , m_highestNodeToBeSerialized(highestNodeToBeSerialized)
|
| - , m_convertBlocksToInlines(convertBlocksToInlines)
|
| - , m_lastClosed(highestNodeToBeSerialized)
|
| -{
|
| -}
|
| -
|
| -static bool needInterchangeNewlineAfter(const VisiblePosition& v)
|
| -{
|
| - VisiblePosition next = v.next();
|
| - Node* upstreamNode = next.deepEquivalent().upstream().anchorNode();
|
| - Node* downstreamNode = v.deepEquivalent().downstream().anchorNode();
|
| - // Add an interchange newline if a paragraph break is selected and a br won't already be added to the markup to represent it.
|
| - return isEndOfParagraph(v) && isStartOfParagraph(next) && !(isHTMLBRElement(*upstreamNode) && upstreamNode == downstreamNode);
|
| -}
|
| -
|
| -static bool needInterchangeNewlineAt(const VisiblePosition& v)
|
| -{
|
| - // FIXME: |v.previous()| works on a DOM tree. We need to fix this to work on
|
| - // a composed tree.
|
| - return needInterchangeNewlineAfter(v.previous());
|
| -}
|
| -
|
| -template<typename Strategy>
|
| -static bool areSameRanges(Node* node, const PositionAlgorithm<Strategy>& startPosition, const PositionAlgorithm<Strategy>& endPosition)
|
| -{
|
| - ASSERT(node);
|
| - const EphemeralRange range = VisibleSelection::selectionFromContentsOfNode(node).toNormalizedEphemeralRange();
|
| - return toPositionInDOMTree(startPosition) == range.startPosition() && toPositionInDOMTree(endPosition) == range.endPosition();
|
| -}
|
| -
|
| -static PassRefPtrWillBeRawPtr<EditingStyle> styleFromMatchedRulesAndInlineDecl(const HTMLElement* element)
|
| -{
|
| - RefPtrWillBeRawPtr<EditingStyle> style = EditingStyle::create(element->inlineStyle());
|
| - // FIXME: Having to const_cast here is ugly, but it is quite a bit of work to untangle
|
| - // the non-const-ness of styleFromMatchedRulesForElement.
|
| - style->mergeStyleFromRules(const_cast<HTMLElement*>(element));
|
| - return style.release();
|
| -}
|
| -
|
| -template<typename Strategy>
|
| -String StyledMarkupSerializer<Strategy>::createMarkup()
|
| -{
|
| - StyledMarkupAccumulator markupAccumulator(m_shouldResolveURLs, toTextOffset(m_start.parentAnchoredEquivalent()), toTextOffset(m_end.parentAnchoredEquivalent()), m_start.document(), m_shouldAnnotate, m_convertBlocksToInlines);
|
| -
|
| - Node* pastEnd = m_end.nodeAsRangePastLastNode();
|
| -
|
| - Node* firstNode = m_start.nodeAsRangeFirstNode();
|
| - VisiblePosition visibleStart(m_start);
|
| - VisiblePosition visibleEnd(m_end);
|
| - if (shouldAnnotate() && needInterchangeNewlineAfter(visibleStart)) {
|
| - markupAccumulator.appendInterchangeNewline();
|
| - if (visibleStart.deepEquivalent() == visibleEnd.previous().deepEquivalent())
|
| - return markupAccumulator.takeResults();
|
| -
|
| - firstNode = visibleStart.next().deepEquivalent().anchorNode();
|
| -
|
| - if (pastEnd && PositionAlgorithm<Strategy>::beforeNode(firstNode).compareTo(PositionAlgorithm<Strategy>::beforeNode(pastEnd)) >= 0) {
|
| - // This condition hits in editing/pasteboard/copy-display-none.html.
|
| - return markupAccumulator.takeResults();
|
| - }
|
| - }
|
| -
|
| - if (!m_lastClosed)
|
| - m_lastClosed = StyledMarkupTraverser<Strategy>().traverse(firstNode, pastEnd);
|
| - StyledMarkupTraverser<Strategy> traverser(&markupAccumulator, m_lastClosed);
|
| - Node* lastClosed = traverser.traverse(firstNode, pastEnd);
|
| -
|
| - if (m_highestNodeToBeSerialized && lastClosed) {
|
| - // TODO(hajimehoshi): This is calculated at createMarkupInternal too.
|
| - Node* commonAncestor = Strategy::commonAncestor(*m_start.computeContainerNode(), *m_end.computeContainerNode());
|
| - ASSERT(commonAncestor);
|
| - HTMLBodyElement* body = toHTMLBodyElement(enclosingElementWithTag(firstPositionInNode(commonAncestor), bodyTag));
|
| - HTMLBodyElement* fullySelectedRoot = nullptr;
|
| - // FIXME: Do this for all fully selected blocks, not just the body.
|
| - if (body && areSameRanges(body, m_start, m_end))
|
| - fullySelectedRoot = body;
|
| -
|
| - // 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 && !markupAccumulator.convertBlocksToInlines()) {
|
| - RefPtrWillBeRawPtr<EditingStyle> fullySelectedRootStyle = styleFromMatchedRulesAndInlineDecl(fullySelectedRoot);
|
| -
|
| - // Bring the background attribute over, but not as an attribute because a background attribute on a div
|
| - // appears to have no effect.
|
| - if ((!fullySelectedRootStyle || !fullySelectedRootStyle->style() || !fullySelectedRootStyle->style()->getPropertyCSSValue(CSSPropertyBackgroundImage))
|
| - && fullySelectedRoot->hasAttribute(backgroundAttr))
|
| - fullySelectedRootStyle->style()->setProperty(CSSPropertyBackgroundImage, "url('" + fullySelectedRoot->getAttribute(backgroundAttr) + "')");
|
| -
|
| - if (fullySelectedRootStyle->style()) {
|
| - // Reset the CSS properties to avoid an assertion error in addStyleMarkup().
|
| - // This assertion is caused at least when we select all text of a <body> element whose
|
| - // 'text-decoration' property is "inherit", and copy it.
|
| - if (!propertyMissingOrEqualToNone(fullySelectedRootStyle->style(), CSSPropertyTextDecoration))
|
| - fullySelectedRootStyle->style()->setProperty(CSSPropertyTextDecoration, CSSValueNone);
|
| - if (!propertyMissingOrEqualToNone(fullySelectedRootStyle->style(), CSSPropertyWebkitTextDecorationsInEffect))
|
| - fullySelectedRootStyle->style()->setProperty(CSSPropertyWebkitTextDecorationsInEffect, CSSValueNone);
|
| - markupAccumulator.wrapWithStyleNode(fullySelectedRootStyle->style());
|
| - }
|
| - } else {
|
| - 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);
|
| - traverser.wrapWithNode(*ancestor, style);
|
| - }
|
| -
|
| - if (ancestor == m_highestNodeToBeSerialized)
|
| - break;
|
| - }
|
| - }
|
| -
|
| - // FIXME: The interchange newline should be placed in the block that it's in, not after all of the content, unconditionally.
|
| - if (shouldAnnotate() && needInterchangeNewlineAt(visibleEnd))
|
| - markupAccumulator.appendInterchangeNewline();
|
| -
|
| - return markupAccumulator.takeResults();
|
| -}
|
| -
|
| -template<typename Strategy>
|
| -StyledMarkupTraverser<Strategy>::StyledMarkupTraverser()
|
| - : StyledMarkupTraverser(nullptr, nullptr)
|
| -{
|
| -}
|
| -
|
| -template<typename Strategy>
|
| -StyledMarkupTraverser<Strategy>::StyledMarkupTraverser(StyledMarkupAccumulator* accumulator, Node* lastClosed)
|
| - : m_accumulator(accumulator)
|
| - , m_lastClosed(lastClosed)
|
| - , m_wrappingStyle(nullptr)
|
| -{
|
| - if (!m_accumulator) {
|
| - ASSERT(!m_lastClosed);
|
| - return;
|
| - }
|
| - if (!m_lastClosed)
|
| - return;
|
| - ContainerNode* parent = Strategy::parent(*m_lastClosed);
|
| - if (!parent)
|
| - return;
|
| - if (shouldAnnotate()) {
|
| - m_wrappingStyle = EditingStyle::wrappingStyleForAnnotatedSerialization(parent);
|
| - return;
|
| - }
|
| - m_wrappingStyle = EditingStyle::wrappingStyleForSerialization(parent);
|
| -}
|
| -
|
| -template<typename Strategy>
|
| -Node* StyledMarkupTraverser<Strategy>::traverse(Node* startNode, Node* pastEnd)
|
| -{
|
| - WillBeHeapVector<RawPtrWillBeMember<ContainerNode>> ancestorsToClose;
|
| - Node* next;
|
| - Node* lastClosed = nullptr;
|
| - for (Node* n = startNode; n && n != pastEnd; n = next) {
|
| - // If |n| is a selection boundary such as <input>, traverse the child
|
| - // nodes in the DOM tree instead of the composed tree.
|
| - if (handleSelectionBoundary<Strategy>(*n)) {
|
| - lastClosed = StyledMarkupTraverser<EditingStrategy>(m_accumulator, m_lastClosed.get()).traverse(n, EditingStrategy::nextSkippingChildren(*n));
|
| - next = EditingInComposedTreeStrategy::nextSkippingChildren(*n);
|
| - } else {
|
| - next = Strategy::next(*n);
|
| - if (isBlock(n) && canHaveChildrenForEditing(n) && next == pastEnd) {
|
| - // Don't write out empty block containers that aren't fully selected.
|
| - continue;
|
| - }
|
| -
|
| - if (!n->layoutObject() && !enclosingElementWithTag(firstPositionInOrBeforeNode(n), selectTag)) {
|
| - next = Strategy::nextSkippingChildren(*n);
|
| - // Don't skip over pastEnd.
|
| - if (pastEnd && Strategy::isDescendantOf(*pastEnd, *n))
|
| - next = pastEnd;
|
| - } else {
|
| - // Add the node to the markup if we're not skipping the descendants
|
| - appendStartMarkup(*n);
|
| -
|
| - // If node has no children, close the tag now.
|
| - if (Strategy::hasChildren(*n)) {
|
| - ancestorsToClose.append(toContainerNode(n));
|
| - continue;
|
| - }
|
| - appendEndMarkup(*n);
|
| - lastClosed = n;
|
| - }
|
| - }
|
| -
|
| - // If we didn't insert open tag and there's no more siblings or we're at the end of the traversal, take care of ancestors.
|
| - // FIXME: What happens if we just inserted open tag and reached the end?
|
| - if (Strategy::nextSibling(*n) && next != pastEnd)
|
| - continue;
|
| -
|
| - // Close up the ancestors.
|
| - while (!ancestorsToClose.isEmpty()) {
|
| - ContainerNode* ancestor = ancestorsToClose.last();
|
| - ASSERT(ancestor);
|
| - if (next && next != pastEnd && Strategy::isDescendantOf(*next, *ancestor))
|
| - break;
|
| - // Not at the end of the range, close ancestors up to sibling of next node.
|
| - appendEndMarkup(*ancestor);
|
| - lastClosed = ancestor;
|
| - ancestorsToClose.removeLast();
|
| - }
|
| -
|
| - // Surround the currently accumulated markup with markup for ancestors we never opened as we leave the subtree(s) rooted at those ancestors.
|
| - ContainerNode* nextParent = next ? Strategy::parent(*next) : nullptr;
|
| - if (next == pastEnd || n == nextParent)
|
| - continue;
|
| -
|
| - ASSERT(n);
|
| - Node* lastAncestorClosedOrSelf = (lastClosed && Strategy::isDescendantOf(*n, *lastClosed)) ? lastClosed : n;
|
| - for (ContainerNode* parent = Strategy::parent(*lastAncestorClosedOrSelf); parent && parent != nextParent; parent = Strategy::parent(*parent)) {
|
| - // All ancestors that aren't in the ancestorsToClose list should either be a) unrendered:
|
| - if (!parent->layoutObject())
|
| - continue;
|
| - // or b) ancestors that we never encountered during a pre-order traversal starting at startNode:
|
| - ASSERT(startNode);
|
| - ASSERT(Strategy::isDescendantOf(*startNode, *parent));
|
| - RefPtrWillBeRawPtr<EditingStyle> style = createInlineStyleIfNeeded(*parent);
|
| - wrapWithNode(*parent, style);
|
| - lastClosed = parent;
|
| - }
|
| - }
|
| -
|
| - return lastClosed;
|
| -}
|
| -
|
| -template<typename Strategy>
|
| -bool StyledMarkupTraverser<Strategy>::needsInlineStyle(const Element& element)
|
| -{
|
| - if (!element.isHTMLElement())
|
| - return false;
|
| - if (shouldAnnotate())
|
| - return true;
|
| - return convertBlocksToInlines() && isBlock(&element);
|
| -}
|
| -
|
| -template<typename Strategy>
|
| -void StyledMarkupTraverser<Strategy>::wrapWithNode(ContainerNode& node, PassRefPtrWillBeRawPtr<EditingStyle> style)
|
| -{
|
| - if (!m_accumulator)
|
| - return;
|
| - StringBuilder markup;
|
| - if (node.isDocumentNode()) {
|
| - MarkupFormatter::appendXMLDeclaration(markup, toDocument(node));
|
| - m_accumulator->pushMarkup(markup.toString());
|
| - return;
|
| - }
|
| - if (!node.isElementNode())
|
| - return;
|
| - Element& element = toElement(node);
|
| - if (shouldApplyWrappingStyle(element) || needsInlineStyle(element))
|
| - m_accumulator->appendElementWithInlineStyle(markup, element, style);
|
| - else
|
| - m_accumulator->appendElement(markup, element);
|
| - m_accumulator->pushMarkup(markup.toString());
|
| - m_accumulator->appendEndTag(toElement(node));
|
| -}
|
| -
|
| -template<typename Strategy>
|
| -RefPtrWillBeRawPtr<EditingStyle> StyledMarkupTraverser<Strategy>::createInlineStyleIfNeeded(Node& node)
|
| -{
|
| - if (!m_accumulator)
|
| - return nullptr;
|
| - if (!node.isElementNode())
|
| - return nullptr;
|
| - RefPtrWillBeRawPtr<EditingStyle> inlineStyle = createInlineStyle(toElement(node));
|
| - if (convertBlocksToInlines() && isBlock(&node))
|
| - inlineStyle->forceInline();
|
| - return inlineStyle;
|
| -}
|
| -
|
| -template<typename Strategy>
|
| -void StyledMarkupTraverser<Strategy>::appendStartMarkup(Node& node)
|
| -{
|
| - if (!m_accumulator)
|
| - return;
|
| - switch (node.nodeType()) {
|
| - case Node::TEXT_NODE: {
|
| - Text& text = toText(node);
|
| - if (text.parentElement() && isHTMLTextAreaElement(text.parentElement())) {
|
| - m_accumulator->appendText(text);
|
| - break;
|
| - }
|
| - RefPtrWillBeRawPtr<EditingStyle> inlineStyle = nullptr;
|
| - if (shouldApplyWrappingStyle(text)) {
|
| - inlineStyle = m_wrappingStyle->copy();
|
| - // FIXME: <rdar://problem/5371536> Style rules that match pasted content can change it's appearance
|
| - // Make sure spans are inline style in paste side e.g. span { display: block }.
|
| - inlineStyle->forceInline();
|
| - // FIXME: Should this be included in forceInline?
|
| - inlineStyle->style()->setProperty(CSSPropertyFloat, CSSValueNone);
|
| - }
|
| - m_accumulator->appendTextWithInlineStyle(text, inlineStyle);
|
| - break;
|
| - }
|
| - case Node::ELEMENT_NODE: {
|
| - Element& element = toElement(node);
|
| - if ((element.isHTMLElement() && shouldAnnotate()) || shouldApplyWrappingStyle(element)) {
|
| - RefPtrWillBeRawPtr<EditingStyle> inlineStyle = createInlineStyle(element);
|
| - m_accumulator->appendElementWithInlineStyle(element, inlineStyle);
|
| - break;
|
| - }
|
| - m_accumulator->appendElement(element);
|
| - break;
|
| - }
|
| - default:
|
| - m_accumulator->appendStartMarkup(node);
|
| - break;
|
| - }
|
| -}
|
| -
|
| -template<typename Strategy>
|
| -void StyledMarkupTraverser<Strategy>::appendEndMarkup(Node& node)
|
| -{
|
| - if (!m_accumulator || !node.isElementNode())
|
| - return;
|
| - m_accumulator->appendEndTag(toElement(node));
|
| -}
|
| -
|
| -template<typename Strategy>
|
| -bool StyledMarkupTraverser<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> StyledMarkupTraverser<Strategy>::createInlineStyle(Element& element)
|
| -{
|
| - RefPtrWillBeRawPtr<EditingStyle> inlineStyle = nullptr;
|
| -
|
| - if (shouldApplyWrappingStyle(element)) {
|
| - inlineStyle = m_wrappingStyle->copy();
|
| - inlineStyle->removePropertiesInElementDefaultStyle(&element);
|
| - inlineStyle->removeStyleConflictingWithStyleOfElement(&element);
|
| - } else {
|
| - inlineStyle = EditingStyle::create();
|
| - }
|
| -
|
| - if (element.isStyledElement() && element.inlineStyle())
|
| - inlineStyle->overrideWithStyle(element.inlineStyle());
|
| -
|
| - if (element.isHTMLElement() && shouldAnnotate())
|
| - inlineStyle->mergeStyleFromRulesForSerialization(&toHTMLElement(element));
|
| -
|
| - return inlineStyle;
|
| -}
|
| -
|
| -template class StyledMarkupSerializer<EditingStrategy>;
|
| -template class StyledMarkupSerializer<EditingInComposedTreeStrategy>;
|
| -
|
| -} // namespace blink
|
|
|