| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 | 36 |
| 37 namespace WebCore { | 37 namespace WebCore { |
| 38 | 38 |
| 39 using namespace HTMLNames; | 39 using namespace HTMLNames; |
| 40 | 40 |
| 41 static bool isListOrIndentBlockquote(const Node* node) | 41 static bool isListOrIndentBlockquote(const Node* node) |
| 42 { | 42 { |
| 43 return node && (node->hasTagName(ulTag) || node->hasTagName(olTag) || node->
hasTagName(blockquoteTag)); | 43 return node && (node->hasTagName(ulTag) || node->hasTagName(olTag) || node->
hasTagName(blockquoteTag)); |
| 44 } | 44 } |
| 45 | 45 |
| 46 IndentOutdentCommand::IndentOutdentCommand(Document* document, EIndentType typeO
fAction, int marginInPixels) | 46 IndentOutdentCommand::IndentOutdentCommand(Document& document, EIndentType typeO
fAction, int marginInPixels) |
| 47 : ApplyBlockElementCommand(document, blockquoteTag, "margin: 0 0 0 40px; bor
der: none; padding: 0px;") | 47 : ApplyBlockElementCommand(document, blockquoteTag, "margin: 0 0 0 40px; bor
der: none; padding: 0px;") |
| 48 , m_typeOfAction(typeOfAction) | 48 , m_typeOfAction(typeOfAction) |
| 49 , m_marginInPixels(marginInPixels) | 49 , m_marginInPixels(marginInPixels) |
| 50 { | 50 { |
| 51 } | 51 } |
| 52 | 52 |
| 53 bool IndentOutdentCommand::tryIndentingAsListItem(const Position& start, const P
osition& end) | 53 bool IndentOutdentCommand::tryIndentingAsListItem(const Position& start, const P
osition& end) |
| 54 { | 54 { |
| 55 // If our selection is not inside a list, bail out. | 55 // If our selection is not inside a list, bail out. |
| 56 Node* lastNodeInSelectedParagraph = start.deprecatedNode(); | 56 Node* lastNodeInSelectedParagraph = start.deprecatedNode(); |
| 57 RefPtr<Element> listNode = enclosingList(lastNodeInSelectedParagraph); | 57 RefPtr<Element> listNode = enclosingList(lastNodeInSelectedParagraph); |
| 58 if (!listNode) | 58 if (!listNode) |
| 59 return false; | 59 return false; |
| 60 | 60 |
| 61 // Find the block that we want to indent. If it's not a list item (e.g., a
div inside a list item), we bail out. | 61 // Find the block that we want to indent. If it's not a list item (e.g., a
div inside a list item), we bail out. |
| 62 Element* selectedListItem = enclosingBlock(lastNodeInSelectedParagraph); | 62 Element* selectedListItem = enclosingBlock(lastNodeInSelectedParagraph); |
| 63 | 63 |
| 64 // FIXME: we need to deal with the case where there is no li (malformed HTML
) | 64 // FIXME: we need to deal with the case where there is no li (malformed HTML
) |
| 65 if (!selectedListItem->hasTagName(liTag)) | 65 if (!selectedListItem->hasTagName(liTag)) |
| 66 return false; | 66 return false; |
| 67 | 67 |
| 68 // FIXME: previousElementSibling does not ignore non-rendered content like <
span></span>. Should we? | 68 // FIXME: previousElementSibling does not ignore non-rendered content like <
span></span>. Should we? |
| 69 Element* previousList = selectedListItem->previousElementSibling(); | 69 Element* previousList = selectedListItem->previousElementSibling(); |
| 70 Element* nextList = selectedListItem->nextElementSibling(); | 70 Element* nextList = selectedListItem->nextElementSibling(); |
| 71 | 71 |
| 72 RefPtr<Element> newList = document()->createElement(listNode->tagQName(), fa
lse); | 72 RefPtr<Element> newList = document().createElement(listNode->tagQName(), fal
se); |
| 73 insertNodeBefore(newList, selectedListItem); | 73 insertNodeBefore(newList, selectedListItem); |
| 74 | 74 |
| 75 moveParagraphWithClones(start, end, newList.get(), selectedListItem); | 75 moveParagraphWithClones(start, end, newList.get(), selectedListItem); |
| 76 | 76 |
| 77 if (canMergeLists(previousList, newList.get())) | 77 if (canMergeLists(previousList, newList.get())) |
| 78 mergeIdenticalElements(previousList, newList); | 78 mergeIdenticalElements(previousList, newList); |
| 79 if (canMergeLists(newList.get(), nextList)) | 79 if (canMergeLists(newList.get(), nextList)) |
| 80 mergeIdenticalElements(newList, nextList); | 80 mergeIdenticalElements(newList, nextList); |
| 81 | 81 |
| 82 return true; | 82 return true; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 // just removed one, then this assumption isn't true. By splitting the n
ext containing blockquote after this node, we keep this assumption true | 149 // just removed one, then this assumption isn't true. By splitting the n
ext containing blockquote after this node, we keep this assumption true |
| 150 if (splitPoint) { | 150 if (splitPoint) { |
| 151 if (ContainerNode* splitPointParent = splitPoint->parentNode()) { | 151 if (ContainerNode* splitPointParent = splitPoint->parentNode()) { |
| 152 if (splitPointParent->hasTagName(blockquoteTag) | 152 if (splitPointParent->hasTagName(blockquoteTag) |
| 153 && !splitPoint->hasTagName(blockquoteTag) | 153 && !splitPoint->hasTagName(blockquoteTag) |
| 154 && splitPointParent->parentNode()->rendererIsEditable()) //
We can't outdent if there is no place to go! | 154 && splitPointParent->parentNode()->rendererIsEditable()) //
We can't outdent if there is no place to go! |
| 155 splitElement(toElement(splitPointParent), splitPoint); | 155 splitElement(toElement(splitPointParent), splitPoint); |
| 156 } | 156 } |
| 157 } | 157 } |
| 158 | 158 |
| 159 document()->updateLayoutIgnorePendingStylesheets(); | 159 document().updateLayoutIgnorePendingStylesheets(); |
| 160 visibleStartOfParagraph = VisiblePosition(visibleStartOfParagraph.deepEq
uivalent()); | 160 visibleStartOfParagraph = VisiblePosition(visibleStartOfParagraph.deepEq
uivalent()); |
| 161 visibleEndOfParagraph = VisiblePosition(visibleEndOfParagraph.deepEquiva
lent()); | 161 visibleEndOfParagraph = VisiblePosition(visibleEndOfParagraph.deepEquiva
lent()); |
| 162 if (visibleStartOfParagraph.isNotNull() && !isStartOfParagraph(visibleSt
artOfParagraph)) | 162 if (visibleStartOfParagraph.isNotNull() && !isStartOfParagraph(visibleSt
artOfParagraph)) |
| 163 insertNodeAt(createBreakElement(document()), visibleStartOfParagraph
.deepEquivalent()); | 163 insertNodeAt(createBreakElement(&document()), visibleStartOfParagrap
h.deepEquivalent()); |
| 164 if (visibleEndOfParagraph.isNotNull() && !isEndOfParagraph(visibleEndOfP
aragraph)) | 164 if (visibleEndOfParagraph.isNotNull() && !isEndOfParagraph(visibleEndOfP
aragraph)) |
| 165 insertNodeAt(createBreakElement(document()), visibleEndOfParagraph.d
eepEquivalent()); | 165 insertNodeAt(createBreakElement(&document()), visibleEndOfParagraph.
deepEquivalent()); |
| 166 | 166 |
| 167 return; | 167 return; |
| 168 } | 168 } |
| 169 Node* enclosingBlockFlow = enclosingBlock(visibleStartOfParagraph.deepEquiva
lent().deprecatedNode()); | 169 Node* enclosingBlockFlow = enclosingBlock(visibleStartOfParagraph.deepEquiva
lent().deprecatedNode()); |
| 170 RefPtr<Node> splitBlockquoteNode = enclosingNode; | 170 RefPtr<Node> splitBlockquoteNode = enclosingNode; |
| 171 if (enclosingBlockFlow != enclosingNode) | 171 if (enclosingBlockFlow != enclosingNode) |
| 172 splitBlockquoteNode = splitTreeToNode(enclosingBlockFlow, enclosingNode,
true); | 172 splitBlockquoteNode = splitTreeToNode(enclosingBlockFlow, enclosingNode,
true); |
| 173 else { | 173 else { |
| 174 // We split the blockquote at where we start outdenting. | 174 // We split the blockquote at where we start outdenting. |
| 175 Node* highestInlineNode = highestEnclosingNodeOfType(visibleStartOfParag
raph.deepEquivalent(), isInline, CannotCrossEditingBoundary, enclosingBlockFlow)
; | 175 Node* highestInlineNode = highestEnclosingNodeOfType(visibleStartOfParag
raph.deepEquivalent(), isInline, CannotCrossEditingBoundary, enclosingBlockFlow)
; |
| 176 splitElement(toElement(enclosingNode), (highestInlineNode) ? highestInli
neNode : visibleStartOfParagraph.deepEquivalent().deprecatedNode()); | 176 splitElement(toElement(enclosingNode), (highestInlineNode) ? highestInli
neNode : visibleStartOfParagraph.deepEquivalent().deprecatedNode()); |
| 177 } | 177 } |
| 178 RefPtr<Node> placeholder = createBreakElement(document()); | 178 RefPtr<Node> placeholder = createBreakElement(&document()); |
| 179 insertNodeBefore(placeholder, splitBlockquoteNode); | 179 insertNodeBefore(placeholder, splitBlockquoteNode); |
| 180 moveParagraph(startOfParagraph(visibleStartOfParagraph), endOfParagraph(visi
bleEndOfParagraph), positionBeforeNode(placeholder.get()), true); | 180 moveParagraph(startOfParagraph(visibleStartOfParagraph), endOfParagraph(visi
bleEndOfParagraph), positionBeforeNode(placeholder.get()), true); |
| 181 } | 181 } |
| 182 | 182 |
| 183 // FIXME: We should merge this function with ApplyBlockElementCommand::formatSel
ection | 183 // FIXME: We should merge this function with ApplyBlockElementCommand::formatSel
ection |
| 184 void IndentOutdentCommand::outdentRegion(const VisiblePosition& startOfSelection
, const VisiblePosition& endOfSelection) | 184 void IndentOutdentCommand::outdentRegion(const VisiblePosition& startOfSelection
, const VisiblePosition& endOfSelection) |
| 185 { | 185 { |
| 186 VisiblePosition endOfLastParagraph = endOfParagraph(endOfSelection); | 186 VisiblePosition endOfLastParagraph = endOfParagraph(endOfSelection); |
| 187 | 187 |
| 188 if (endOfParagraph(startOfSelection) == endOfLastParagraph) { | 188 if (endOfParagraph(startOfSelection) == endOfLastParagraph) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 | 227 |
| 228 void IndentOutdentCommand::formatRange(const Position& start, const Position& en
d, const Position&, RefPtr<Element>& blockquoteForNextIndent) | 228 void IndentOutdentCommand::formatRange(const Position& start, const Position& en
d, const Position&, RefPtr<Element>& blockquoteForNextIndent) |
| 229 { | 229 { |
| 230 if (tryIndentingAsListItem(start, end)) | 230 if (tryIndentingAsListItem(start, end)) |
| 231 blockquoteForNextIndent = 0; | 231 blockquoteForNextIndent = 0; |
| 232 else | 232 else |
| 233 indentIntoBlockquote(start, end, blockquoteForNextIndent); | 233 indentIntoBlockquote(start, end, blockquoteForNextIndent); |
| 234 } | 234 } |
| 235 | 235 |
| 236 } | 236 } |
| OLD | NEW |