diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/editing/InsertListCommand.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/editing/InsertListCommand.cpp')
-rw-r--r-- | Source/WebCore/editing/InsertListCommand.cpp | 109 |
1 files changed, 58 insertions, 51 deletions
diff --git a/Source/WebCore/editing/InsertListCommand.cpp b/Source/WebCore/editing/InsertListCommand.cpp index d3ead9780..894a7cffc 100644 --- a/Source/WebCore/editing/InsertListCommand.cpp +++ b/Source/WebCore/editing/InsertListCommand.cpp @@ -10,10 +10,10 @@ * 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 + * THIS SOFTWARE IS PROVIDED BY APPLE 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 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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 @@ -24,15 +24,16 @@ */ #include "config.h" -#include "Element.h" -#include "ElementTraversal.h" #include "InsertListCommand.h" -#include "ExceptionCodePlaceholder.h" -#include "htmlediting.h" -#include "HTMLElement.h" + +#include "ElementTraversal.h" +#include "HTMLBRElement.h" +#include "HTMLLIElement.h" #include "HTMLNames.h" -#include "TextIterator.h" +#include "HTMLUListElement.h" +#include "Range.h" #include "VisibleUnits.h" +#include "htmlediting.h" namespace WebCore { @@ -46,7 +47,7 @@ static Node* enclosingListChild(Node* node, Node* listNode) return listChild; } -PassRefPtr<HTMLElement> InsertListCommand::insertList(Document& document, Type type) +RefPtr<HTMLElement> InsertListCommand::insertList(Document& document, Type type) { RefPtr<InsertListCommand> insertCommand = create(document, type); insertCommand->apply(); @@ -55,15 +56,15 @@ PassRefPtr<HTMLElement> InsertListCommand::insertList(Document& document, Type t HTMLElement* InsertListCommand::fixOrphanedListChild(Node* node) { - RefPtr<HTMLElement> listElement = createUnorderedListElement(document()); - insertNodeBefore(listElement, node); + auto listElement = HTMLUListElement::create(document()); + insertNodeBefore(listElement.copyRef(), node); removeNode(node); - appendNode(node, listElement); - m_listElement = listElement; - return listElement.get(); + appendNode(node, listElement.copyRef()); + m_listElement = listElement.copyRef(); + return listElement.ptr(); } -PassRefPtr<HTMLElement> InsertListCommand::mergeWithNeighboringLists(PassRefPtr<HTMLElement> passedList) +RefPtr<HTMLElement> InsertListCommand::mergeWithNeighboringLists(PassRefPtr<HTMLElement> passedList) { RefPtr<HTMLElement> list = passedList; Element* previousList = list->previousElementSibling(); @@ -71,17 +72,17 @@ PassRefPtr<HTMLElement> InsertListCommand::mergeWithNeighboringLists(PassRefPtr< mergeIdenticalElements(previousList, list); if (!list) - return 0; - Element* sibling = ElementTraversal::nextSibling(list.get()); - if (!sibling || !sibling->isHTMLElement()) - return list.release(); + return nullptr; + Element* sibling = ElementTraversal::nextSibling(*list); + if (!is<HTMLElement>(sibling)) + return list; - RefPtr<HTMLElement> nextList = toHTMLElement(sibling); + RefPtr<HTMLElement> nextList = downcast<HTMLElement>(sibling); if (canMergeLists(list.get(), nextList.get())) { mergeIdenticalElements(list, nextList); - return nextList.release(); + return nextList; } - return list.release(); + return list; } bool InsertListCommand::selectionHasListOfType(const VisibleSelection& selection, const QualifiedName& listTag) @@ -110,12 +111,9 @@ InsertListCommand::InsertListCommand(Document& document, Type type) void InsertListCommand::doApply() { - if (!endingSelection().isNonOrphanedCaretOrRange()) + if (endingSelection().isNoneOrOrphaned() || !endingSelection().isContentRichlyEditable()) return; - if (!endingSelection().rootEditableElement()) - return; - VisiblePosition visibleEnd = endingSelection().visibleEnd(); VisiblePosition visibleStart = endingSelection().visibleStart(); // When a selection ends at the start of a paragraph, we rarely paint @@ -126,10 +124,13 @@ void InsertListCommand::doApply() // FIXME: We paint the gap before some paragraphs that are indented with left // margin/padding, but not others. We should make the gap painting more consistent and // then use a left margin/padding rule here. - if (visibleEnd != visibleStart && isStartOfParagraph(visibleEnd, CanSkipOverEditingBoundary)) + if (visibleEnd != visibleStart && isStartOfParagraph(visibleEnd, CanSkipOverEditingBoundary)) { setEndingSelection(VisibleSelection(visibleStart, visibleEnd.previous(CannotCrossEditingBoundary), endingSelection().isDirectional())); + if (!endingSelection().rootEditableElement()) + return; + } - const QualifiedName& listTag = (m_type == OrderedList) ? olTag : ulTag; + auto& listTag = (m_type == OrderedList) ? olTag : ulTag; if (endingSelection().isRange()) { VisibleSelection selection = selectionForParagraphIteration(endingSelection()); ASSERT(selection.isRange()); @@ -148,7 +149,7 @@ void InsertListCommand::doApply() // infinite loop and because there is no more work to be done. // FIXME(<rdar://problem/5983974>): The endingSelection() may be incorrect here. Compute // the new location of endOfSelection and use it as the end of the new selection. - if (!startOfLastParagraph.deepEquivalent().anchorNode()->inDocument()) + if (!startOfLastParagraph.deepEquivalent().anchorNode()->isConnected()) return; setEndingSelection(startOfCurrentParagraph); @@ -191,7 +192,12 @@ void InsertListCommand::doApply() doApplyForSingleParagraph(false, listTag, endingSelection().firstRange().get()); } -void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const QualifiedName& listTag, Range* currentSelection) +EditAction InsertListCommand::editingAction() const +{ + return m_type == OrderedList ? EditActionInsertOrderedList : EditActionInsertUnorderedList; +} + +void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const HTMLQualifiedName& listTag, Range* currentSelection) { // FIXME: This will produce unexpected results for a selection that starts just before a // table and ends inside the first cell, selectionForParagraphIteration should probably @@ -206,31 +212,32 @@ void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const Qu listNode = fixOrphanedListChild(listChildNode); listNode = mergeWithNeighboringLists(listNode); } - if (!listNode->hasTagName(listTag)) + if (!listNode->hasTagName(listTag)) { // listChildNode will be removed from the list and a list of type m_type will be created. switchListType = true; + } // If the list is of the desired type, and we are not removing the list, then exit early. if (!switchListType && forceCreateList) return; // If the entire list is selected, then convert the whole list. - if (switchListType && isNodeVisiblyContainedWithin(listNode.get(), currentSelection)) { - bool rangeStartIsInList = visiblePositionBeforeNode(listNode.get()) == currentSelection->startPosition(); - bool rangeEndIsInList = visiblePositionAfterNode(listNode.get()) == currentSelection->endPosition(); + if (switchListType && isNodeVisiblyContainedWithin(*listNode, *currentSelection)) { + bool rangeStartIsInList = visiblePositionBeforeNode(*listNode) == currentSelection->startPosition(); + bool rangeEndIsInList = visiblePositionAfterNode(*listNode) == currentSelection->endPosition(); RefPtr<HTMLElement> newList = createHTMLElement(document(), listTag); insertNodeBefore(newList, listNode); - Node* firstChildInList = enclosingListChild(VisiblePosition(firstPositionInNode(listNode.get())).deepEquivalent().deprecatedNode(), listNode.get()); - Node* outerBlock = isBlockFlowElement(firstChildInList) ? firstChildInList : listNode.get(); + auto* firstChildInList = enclosingListChild(VisiblePosition(firstPositionInNode(listNode.get())).deepEquivalent().deprecatedNode(), listNode.get()); + Node* outerBlock = firstChildInList && isBlockFlowElement(*firstChildInList) ? firstChildInList : listNode.get(); moveParagraphWithClones(firstPositionInNode(listNode.get()), lastPositionInNode(listNode.get()), newList.get(), outerBlock); // Manually remove listNode because moveParagraphWithClones sometimes leaves it behind in the document. // See the bug 33668 and editing/execCommand/insert-list-orphaned-item-with-nested-lists.html. // FIXME: This might be a bug in moveParagraphWithClones or deleteSelection. - if (listNode && listNode->inDocument()) + if (listNode && listNode->isConnected()) removeNode(listNode); newList = mergeWithNeighboringLists(newList); @@ -238,9 +245,9 @@ void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const Qu // Restore the start and the end of current selection if they started inside listNode // because moveParagraphWithClones could have removed them. if (rangeStartIsInList && newList) - currentSelection->setStart(newList, 0, IGNORE_EXCEPTION); + currentSelection->setStart(*newList, 0); if (rangeEndIsInList && newList) - currentSelection->setEnd(newList, lastOffsetInNode(newList.get()), IGNORE_EXCEPTION); + currentSelection->setEnd(*newList, lastOffsetInNode(newList.get())); setEndingSelection(VisiblePosition(firstPositionInNode(newList.get()))); @@ -276,12 +283,12 @@ void InsertListCommand::unlistifyParagraph(const VisiblePosition& originalStart, } // When removing a list, we must always create a placeholder to act as a point of insertion // for the list content being removed. - RefPtr<Element> placeholder = createBreakElement(document()); + RefPtr<Element> placeholder = HTMLBRElement::create(document()); RefPtr<Element> nodeToInsert = placeholder; // If the content of the list item will be moved into another list, put it in a list item // so that we don't create an orphaned list child. if (enclosingList(listNode)) { - nodeToInsert = createListItemElement(document()); + nodeToInsert = HTMLLIElement::create(document()); appendNode(placeholder, nodeToInsert); } @@ -329,7 +336,7 @@ static Element* adjacentEnclosingList(const VisiblePosition& pos, const VisibleP return listNode; } -PassRefPtr<HTMLElement> InsertListCommand::listifyParagraph(const VisiblePosition& originalStart, const QualifiedName& listTag) +RefPtr<HTMLElement> InsertListCommand::listifyParagraph(const VisiblePosition& originalStart, const QualifiedName& listTag) { VisiblePosition start = startOfParagraph(originalStart, CanSkipOverEditingBoundary); VisiblePosition end = endOfParagraph(start, CanSkipOverEditingBoundary); @@ -338,29 +345,29 @@ PassRefPtr<HTMLElement> InsertListCommand::listifyParagraph(const VisiblePositio return 0; // Check for adjoining lists. - RefPtr<HTMLElement> listItemElement = createListItemElement(document()); - RefPtr<HTMLElement> placeholder = createBreakElement(document()); - appendNode(placeholder, listItemElement); + auto listItemElement = HTMLLIElement::create(document()); + auto placeholder = HTMLBRElement::create(document()); + appendNode(placeholder.copyRef(), listItemElement.copyRef()); // Place list item into adjoining lists. Element* previousList = adjacentEnclosingList(start.deepEquivalent(), start.previous(CannotCrossEditingBoundary), listTag); Element* nextList = adjacentEnclosingList(start.deepEquivalent(), end.next(CannotCrossEditingBoundary), listTag); RefPtr<HTMLElement> listElement; if (previousList) - appendNode(listItemElement, previousList); + appendNode(WTFMove(listItemElement), previousList); else if (nextList) - insertNodeAt(listItemElement, positionBeforeNode(nextList)); + insertNodeAt(WTFMove(listItemElement), positionBeforeNode(nextList)); else { // Create the list. listElement = createHTMLElement(document(), listTag); - appendNode(listItemElement, listElement); + appendNode(WTFMove(listItemElement), listElement); if (start == end && isBlock(start.deepEquivalent().deprecatedNode())) { // Inserting the list into an empty paragraph that isn't held open // by a br or a '\n', will invalidate start and end. Insert // a placeholder and then recompute start and end. - RefPtr<Node> placeholder = insertBlockPlaceholder(start.deepEquivalent()); - start = positionBeforeNode(placeholder.get()); + auto blockPlaceholder = insertBlockPlaceholder(start.deepEquivalent()); + start = positionBeforeNode(blockPlaceholder.get()); end = start; } @@ -388,7 +395,7 @@ PassRefPtr<HTMLElement> InsertListCommand::listifyParagraph(const VisiblePositio } } - moveParagraph(start, end, positionBeforeNode(placeholder.get()), true); + moveParagraph(start, end, positionBeforeNode(placeholder.ptr()), true); if (listElement) return mergeWithNeighboringLists(listElement); |