#include "config.h"
#include "core/editing/CompositeEditCommand.h"
-#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "bindings/core/v8/ExceptionStatePlaceholder.h"
#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/DocumentFragment.h"
#include "core/editing/markup.h"
#include "core/events/ScopedEventQueue.h"
#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLBRElement.h"
+#include "core/html/HTMLDivElement.h"
#include "core/html/HTMLElement.h"
+#include "core/html/HTMLLIElement.h"
+#include "core/html/HTMLQuoteElement.h"
+#include "core/html/HTMLSpanElement.h"
#include "core/rendering/InlineTextBox.h"
#include "core/rendering/RenderBlock.h"
#include "core/rendering/RenderListItem.h"
#include "core/rendering/RenderText.h"
-namespace WebCore {
+namespace blink {
using namespace HTMLNames;
if (!isHTMLDivElement(*node))
return false;
- ContainerNode* parentNode = node->parentNode();
+ const HTMLDivElement& element = toHTMLDivElement(*node);
+ ContainerNode* parentNode = element.parentNode();
if (parentNode && parentNode->firstChild() != parentNode->lastChild())
return false;
- if (!toElement(node)->hasAttributes())
+ if (!element.hasAttributes())
return true;
return false;
void CompositeEditCommand::removeChildrenInRange(PassRefPtrWillBeRawPtr<Node> node, unsigned from, unsigned to)
{
WillBeHeapVector<RefPtrWillBeMember<Node> > children;
- Node* child = node->traverseToChildAt(from);
+ Node* child = NodeTraversal::childAt(*node, from);
for (unsigned i = from; child && i < to; i++, child = child->nextSibling())
children.append(child);
position.moveToOffset(offset);
}
-HTMLElement* CompositeEditCommand::replaceElementWithSpanPreservingChildrenAndAttributes(PassRefPtrWillBeRawPtr<HTMLElement> node)
+HTMLSpanElement* CompositeEditCommand::replaceElementWithSpanPreservingChildrenAndAttributes(PassRefPtrWillBeRawPtr<HTMLElement> node)
{
// It would also be possible to implement all of ReplaceNodeWithSpanCommand
// as a series of existing smaller edit commands. Someone who wanted to
{
Position start = endingSelection().start();
Position end = endingSelection().end();
- if (start.containerNode() != end.containerNode() || !start.containerNode()->isTextNode() || isTabSpanTextNode(start.containerNode()))
+ if (start.containerNode() != end.containerNode() || !start.containerNode()->isTextNode() || isTabHTMLSpanElementTextNode(start.containerNode()))
return Position();
RefPtrWillBeRawPtr<Text> textNode = start.containerText();
return Position(textNode.release(), start.offsetInContainerNode() + text.length());
}
-static void copyMarkers(const WillBeHeapVector<DocumentMarker*>& markerPointers, Vector<DocumentMarker>& markers)
+static void copyMarkerTypesAndDescriptions(const DocumentMarkerVector& markerPointers, Vector<DocumentMarker::MarkerType>& types, Vector<String>& descriptions)
{
size_t arraySize = markerPointers.size();
- markers.reserveCapacity(arraySize);
- for (size_t i = 0; i < arraySize; ++i)
- markers.append(*markerPointers[i]);
+ types.reserveCapacity(arraySize);
+ descriptions.reserveCapacity(arraySize);
+ for (size_t i = 0; i < arraySize; ++i) {
+ types.append(markerPointers[i]->type());
+ descriptions.append(markerPointers[i]->description());
+ }
}
void CompositeEditCommand::replaceTextInNodePreservingMarkers(PassRefPtrWillBeRawPtr<Text> prpNode, unsigned offset, unsigned count, const String& replacementText)
{
RefPtrWillBeRawPtr<Text> node(prpNode);
DocumentMarkerController& markerController = document().markers();
- Vector<DocumentMarker> markers;
- copyMarkers(markerController.markersInRange(Range::create(document(), node.get(), offset, node.get(), offset + count).get(), DocumentMarker::AllMarkers()), markers);
+ Vector<DocumentMarker::MarkerType> types;
+ Vector<String> descriptions;
+ copyMarkerTypesAndDescriptions(markerController.markersInRange(Range::create(document(), node.get(), offset, node.get(), offset + count).get(), DocumentMarker::AllMarkers()), types, descriptions);
replaceTextInNode(node, offset, count, replacementText);
RefPtrWillBeRawPtr<Range> newRange = Range::create(document(), node.get(), offset, node.get(), offset + replacementText.length());
- for (size_t i = 0; i < markers.size(); ++i)
- markerController.addMarker(newRange.get(), markers[i].type(), markers[i].description());
+ ASSERT(types.size() == descriptions.size());
+ for (size_t i = 0; i < types.size(); ++i)
+ markerController.addMarker(newRange.get(), types[i], descriptions[i]);
}
Position CompositeEditCommand::positionOutsideTabSpan(const Position& pos)
{
- if (!isTabSpanTextNode(pos.anchorNode()))
+ if (!isTabHTMLSpanElementTextNode(pos.anchorNode()))
return pos;
switch (pos.anchorType()) {
return positionInParentAfterNode(*pos.anchorNode());
}
- Node* tabSpan = tabSpanNode(pos.containerNode());
+ HTMLSpanElement* tabSpan = tabSpanElement(pos.containerNode());
ASSERT(tabSpan);
if (pos.offsetInContainerNode() <= caretMinOffset(pos.containerNode()))
applyCommandToComposite(RemoveCSSPropertyCommand::create(document(), element, property));
}
-void CompositeEditCommand::removeNodeAttribute(PassRefPtrWillBeRawPtr<Element> element, const QualifiedName& attribute)
+void CompositeEditCommand::removeElementAttribute(PassRefPtrWillBeRawPtr<Element> element, const QualifiedName& attribute)
{
setNodeAttribute(element, attribute, AtomicString());
}
if (textNode->length() == 0)
return false;
- RenderObject* renderer = textNode->renderer();
+ RenderText* renderer = textNode->renderer();
if (renderer && !renderer->style()->collapseWhiteSpace())
return false;
if (textNode->length() == 0)
return;
- RenderObject* renderer = textNode->renderer();
+ RenderText* renderer = textNode->renderer();
if (renderer && !renderer->style()->collapseWhiteSpace())
return;
document().updateLayout();
- RenderText* textRenderer = toRenderText(textNode->renderer());
+ RenderText* textRenderer = textNode->renderer();
if (!textRenderer)
return;
deleteInsignificantText(pos, end);
}
-PassRefPtrWillBeRawPtr<Node> CompositeEditCommand::appendBlockPlaceholder(PassRefPtrWillBeRawPtr<Element> container)
+PassRefPtrWillBeRawPtr<HTMLBRElement> CompositeEditCommand::appendBlockPlaceholder(PassRefPtrWillBeRawPtr<Element> container)
{
if (!container)
return nullptr;
// Should assert isRenderBlockFlow || isInlineFlow when deletion improves. See 4244964.
ASSERT(container->renderer());
- RefPtrWillBeRawPtr<Node> placeholder = createBlockPlaceholderElement(document());
+ RefPtrWillBeRawPtr<HTMLBRElement> placeholder = createBlockPlaceholderElement(document());
appendNode(placeholder, container);
return placeholder.release();
}
-PassRefPtrWillBeRawPtr<Node> CompositeEditCommand::insertBlockPlaceholder(const Position& pos)
+PassRefPtrWillBeRawPtr<HTMLBRElement> CompositeEditCommand::insertBlockPlaceholder(const Position& pos)
{
if (pos.isNull())
return nullptr;
// Should assert isRenderBlockFlow || isInlineFlow when deletion improves. See 4244964.
ASSERT(pos.deprecatedNode()->renderer());
- RefPtrWillBeRawPtr<Node> placeholder = createBlockPlaceholderElement(document());
+ RefPtrWillBeRawPtr<HTMLBRElement> placeholder = createBlockPlaceholderElement(document());
insertNodeAt(placeholder, pos);
return placeholder.release();
}
-PassRefPtrWillBeRawPtr<Node> CompositeEditCommand::addBlockPlaceholderIfNeeded(Element* container)
+PassRefPtrWillBeRawPtr<HTMLBRElement> CompositeEditCommand::addBlockPlaceholderIfNeeded(Element* container)
{
if (!container)
return nullptr;
// append the placeholder to make sure it follows
// any unrendered blocks
- RenderBlock* block = toRenderBlock(renderer);
+ RenderBlockFlow* block = toRenderBlockFlow(renderer);
if (block->height() == 0 || (block->isListItem() && toRenderListItem(block)->isEmpty()))
return appendBlockPlaceholder(container);
deleteTextFromNode(toText(p.anchorNode()), p.offsetInContainerNode(), 1);
}
-PassRefPtrWillBeRawPtr<Element> CompositeEditCommand::insertNewDefaultParagraphElementAt(const Position& position)
+PassRefPtrWillBeRawPtr<HTMLElement> CompositeEditCommand::insertNewDefaultParagraphElementAt(const Position& position)
{
- RefPtrWillBeRawPtr<Element> paragraphElement = createDefaultParagraphElement(document());
+ RefPtrWillBeRawPtr<HTMLElement> paragraphElement = createDefaultParagraphElement(document());
paragraphElement->appendChild(createBreakElement(document()));
insertNodeAt(paragraphElement, position);
return paragraphElement.release();
// If the paragraph is not entirely within it's own block, create one and move the paragraph into
// it, and return that block. Otherwise return 0.
-PassRefPtrWillBeRawPtr<Element> CompositeEditCommand::moveParagraphContentsToNewBlockIfNecessary(const Position& pos)
+PassRefPtrWillBeRawPtr<HTMLElement> CompositeEditCommand::moveParagraphContentsToNewBlockIfNecessary(const Position& pos)
{
ASSERT(isEditablePosition(pos, ContentIsEditable, DoNotUpdateStyle));
if (visibleParagraphEnd.isNull())
return nullptr;
- RefPtrWillBeRawPtr<Element> newBlock = insertNewDefaultParagraphElementAt(upstreamStart);
+ RefPtrWillBeRawPtr<HTMLElement> newBlock = insertNewDefaultParagraphElementAt(upstreamStart);
bool endWasBr = isHTMLBRElement(*visibleParagraphEnd.deepEquivalent().deprecatedNode());
return newBlock.release();
}
-void CompositeEditCommand::pushAnchorElementDown(Node* anchorNode)
+void CompositeEditCommand::pushAnchorElementDown(Element* anchorNode)
{
if (!anchorNode)
return;
ASSERT(anchorNode->isLink());
setEndingSelection(VisibleSelection::selectionFromContentsOfNode(anchorNode));
- applyStyledElement(toElement(anchorNode));
+ applyStyledElement(anchorNode);
// Clones of anchorNode have been pushed down, now remove it.
if (anchorNode->inDocument())
removeNodePreservingChildren(anchorNode);
if (outerNode->isRootEditableElement()) {
lastNode = blockElement;
} else {
- lastNode = outerNode->cloneNode(isRenderedTableElement(outerNode.get()));
+ lastNode = outerNode->cloneNode(isRenderedHTMLTableElement(outerNode.get()));
appendNode(lastNode, blockElement);
}
for (size_t i = ancestors.size(); i != 0; --i) {
Node* item = ancestors[i - 1].get();
- RefPtrWillBeRawPtr<Node> child = item->cloneNode(isRenderedTableElement(item));
+ RefPtrWillBeRawPtr<Node> child = item->cloneNode(isRenderedHTMLTableElement(item));
appendNode(child, toElement(lastNode));
lastNode = child.release();
}
// The blockElement parameter is the element to move the paragraph to,
// outerNode is the top element of the paragraph hierarchy.
-void CompositeEditCommand::moveParagraphWithClones(const VisiblePosition& startOfParagraphToMove, const VisiblePosition& endOfParagraphToMove, Element* blockElement, Node* outerNode)
+void CompositeEditCommand::moveParagraphWithClones(const VisiblePosition& startOfParagraphToMove, const VisiblePosition& endOfParagraphToMove, HTMLElement* blockElement, Node* outerNode)
{
ASSERT(outerNode);
ASSERT(blockElement);
beforeParagraph = VisiblePosition(beforeParagraph.deepEquivalent());
afterParagraph = VisiblePosition(afterParagraph.deepEquivalent());
- if (beforeParagraph.isNotNull() && !isRenderedTable(beforeParagraph.deepEquivalent().deprecatedNode())
+ if (beforeParagraph.isNotNull() && !isRenderedTableElement(beforeParagraph.deepEquivalent().deprecatedNode())
&& ((!isEndOfParagraph(beforeParagraph) && !isStartOfParagraph(beforeParagraph)) || beforeParagraph == afterParagraph)) {
// FIXME: Trim text between beforeParagraph and afterParagraph if they aren't equal.
insertNodeAt(createBreakElement(document()), beforeParagraph.deepEquivalent());
// FIXME: Can't we do something better when the immediate parent wasn't a list node?
if (!listNode
|| (!isHTMLUListElement(*listNode) && !isHTMLOListElement(*listNode))
- || !listNode->rendererIsEditable()
+ || !listNode->hasEditableStyle()
|| listNode == emptyListItem->rootEditableElement())
return false;
- RefPtrWillBeRawPtr<Element> newBlock = nullptr;
+ RefPtrWillBeRawPtr<HTMLElement> newBlock = nullptr;
if (ContainerNode* blockEnclosingList = listNode->parentNode()) {
if (isHTMLLIElement(*blockEnclosingList)) { // listNode is inside another list item
if (visiblePositionAfterNode(*blockEnclosingList) == visiblePositionAfterNode(*listNode)) {
RefPtrWillBeRawPtr<Node> previousListNode = emptyListItem->isElementNode() ? ElementTraversal::previousSibling(*emptyListItem): emptyListItem->previousSibling();
RefPtrWillBeRawPtr<Node> nextListNode = emptyListItem->isElementNode() ? ElementTraversal::nextSibling(*emptyListItem): emptyListItem->nextSibling();
- if (isListItem(nextListNode.get()) || isListElement(nextListNode.get())) {
+ if (isListItem(nextListNode.get()) || isHTMLListElement(nextListNode.get())) {
// If emptyListItem follows another list item or nested list, split the list node.
- if (isListItem(previousListNode.get()) || isListElement(previousListNode.get()))
+ if (isListItem(previousListNode.get()) || isHTMLListElement(previousListNode.get()))
splitElement(toElement(listNode), emptyListItem);
// If emptyListItem is followed by other list item or nested list, then insert newBlock before the list node.
// When emptyListItem does not follow any list item or nested list, insert newBlock after the enclosing list node.
// Remove the enclosing node if emptyListItem is the only child; otherwise just remove emptyListItem.
insertNodeAfter(newBlock, listNode);
- removeNode(isListItem(previousListNode.get()) || isListElement(previousListNode.get()) ? emptyListItem.get() : listNode.get());
+ removeNode(isListItem(previousListNode.get()) || isHTMLListElement(previousListNode.get()) ? emptyListItem.get() : listNode.get());
}
appendBlockPlaceholder(newBlock);
return false;
VisiblePosition caret(endingSelection().visibleStart());
- Node* highestBlockquote = highestEnclosingNodeOfType(caret.deepEquivalent(), &isMailBlockquote);
+ HTMLQuoteElement* highestBlockquote = toHTMLQuoteElement(highestEnclosingNodeOfType(caret.deepEquivalent(), &isMailHTMLBlockquoteElement));
if (!highestBlockquote)
return false;
VisiblePosition previous(caret.previous(CannotCrossEditingBoundary));
// Only move forward if there's nothing before the caret, or if there's unquoted content before it.
- if (enclosingNodeOfType(previous.deepEquivalent(), &isMailBlockquote))
+ if (enclosingNodeOfType(previous.deepEquivalent(), &isMailHTMLBlockquoteElement))
return false;
- RefPtrWillBeRawPtr<Node> br = createBreakElement(document());
+ RefPtrWillBeRawPtr<HTMLBRElement> br = createBreakElement(document());
// We want to replace this quoted paragraph with an unquoted one, so insert a br
// to hold the caret before the highest blockquote.
insertNodeBefore(br, highestBlockquote);
return original;
VisiblePosition visiblePos(original);
- Node* enclosingAnchor = enclosingAnchorElement(original);
+ Element* enclosingAnchor = enclosingAnchorElement(original);
Position result = original;
if (!enclosingAnchor)
RefPtrWillBeRawPtr<Node> endNode = end;
RefPtrWillBeRawPtr<Node> node = nullptr;
for (node = start; node->parentNode() != endNode; node = node->parentNode()) {
- if (!node->parentNode()->isElementNode())
+ Element* parentElement = node->parentElement();
+ if (!parentElement)
break;
// Do not split a node when doing so introduces an empty node.
- VisiblePosition positionInParent(firstPositionInNode(node->parentNode()));
+ VisiblePosition positionInParent(firstPositionInNode(parentElement));
VisiblePosition positionInNode(firstPositionInOrBeforeNode(node.get()));
if (positionInParent != positionInNode)
- splitElement(toElement(node->parentNode()), node);
+ splitElement(parentElement, node);
}
return node.release();
}
-PassRefPtrWillBeRawPtr<Element> createBlockPlaceholderElement(Document& document)
-{
- return document.createElement(brTag, false);
-}
-
void CompositeEditCommand::trace(Visitor* visitor)
{
visitor->trace(m_commands);
EditCommand::trace(visitor);
}
-} // namespace WebCore
+} // namespace blink