| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006 Apple Computer, 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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 | 64 |
| 65 void InsertLineBreakCommand::doApply(EditingState* editingState) { | 65 void InsertLineBreakCommand::doApply(EditingState* editingState) { |
| 66 deleteSelection(editingState); | 66 deleteSelection(editingState); |
| 67 if (editingState->isAborted()) | 67 if (editingState->isAborted()) |
| 68 return; | 68 return; |
| 69 VisibleSelection selection = endingSelection(); | 69 VisibleSelection selection = endingSelection(); |
| 70 if (!selection.isNonOrphanedCaretOrRange()) | 70 if (!selection.isNonOrphanedCaretOrRange()) |
| 71 return; | 71 return; |
| 72 | 72 |
| 73 VisiblePosition caret(selection.visibleStartDeprecated()); | 73 VisiblePosition caret(selection.visibleStartDeprecated()); |
| 74 // FIXME: If the node is hidden, we should still be able to insert text. | 74 // FIXME: If the node is hidden, we should still be able to insert text. For |
| 75 // For now, we return to avoid a crash. https://bugs.webkit.org/show_bug.cgi?
id=40342 | 75 // now, we return to avoid a crash. |
| 76 // https://bugs.webkit.org/show_bug.cgi?id=40342 |
| 76 if (caret.isNull()) | 77 if (caret.isNull()) |
| 77 return; | 78 return; |
| 78 | 79 |
| 79 Position pos(caret.deepEquivalent()); | 80 Position pos(caret.deepEquivalent()); |
| 80 | 81 |
| 81 pos = positionAvoidingSpecialElementBoundary(pos, editingState); | 82 pos = positionAvoidingSpecialElementBoundary(pos, editingState); |
| 82 if (editingState->isAborted()) | 83 if (editingState->isAborted()) |
| 83 return; | 84 return; |
| 84 | 85 |
| 85 pos = positionOutsideTabSpan(pos); | 86 pos = positionOutsideTabSpan(pos); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 VisiblePosition::beforeNode(nodeToInsert))) { | 133 VisiblePosition::beforeNode(nodeToInsert))) { |
| 133 insertNodeBefore(nodeToInsert->cloneNode(false), nodeToInsert, | 134 insertNodeBefore(nodeToInsert->cloneNode(false), nodeToInsert, |
| 134 editingState); | 135 editingState); |
| 135 if (editingState->isAborted()) | 136 if (editingState->isAborted()) |
| 136 return; | 137 return; |
| 137 } | 138 } |
| 138 | 139 |
| 139 setEndingSelection(createVisibleSelectionDeprecated( | 140 setEndingSelection(createVisibleSelectionDeprecated( |
| 140 Position::inParentAfterNode(*nodeToInsert), TextAffinity::Downstream, | 141 Position::inParentAfterNode(*nodeToInsert), TextAffinity::Downstream, |
| 141 endingSelection().isDirectional())); | 142 endingSelection().isDirectional())); |
| 142 // If we're inserting after all of the rendered text in a text node, or into
a non-text node, | 143 // If we're inserting after all of the rendered text in a text node, or into |
| 143 // a simple insertion is sufficient. | 144 // a non-text node, a simple insertion is sufficient. |
| 144 } else if (!pos.anchorNode()->isTextNode() || | 145 } else if (!pos.anchorNode()->isTextNode() || |
| 145 pos.computeOffsetInContainerNode() >= | 146 pos.computeOffsetInContainerNode() >= |
| 146 caretMaxOffset(pos.anchorNode())) { | 147 caretMaxOffset(pos.anchorNode())) { |
| 147 insertNodeAt(nodeToInsert, pos, editingState); | 148 insertNodeAt(nodeToInsert, pos, editingState); |
| 148 if (editingState->isAborted()) | 149 if (editingState->isAborted()) |
| 149 return; | 150 return; |
| 150 setEndingSelection(createVisibleSelectionDeprecated( | 151 setEndingSelection(createVisibleSelectionDeprecated( |
| 151 Position::inParentAfterNode(*nodeToInsert), TextAffinity::Downstream, | 152 Position::inParentAfterNode(*nodeToInsert), TextAffinity::Downstream, |
| 152 endingSelection().isDirectional())); | 153 endingSelection().isDirectional())); |
| 153 } else if (pos.anchorNode()->isTextNode()) { | 154 } else if (pos.anchorNode()->isTextNode()) { |
| 154 // Split a text node | 155 // Split a text node |
| 155 Text* textNode = toText(pos.anchorNode()); | 156 Text* textNode = toText(pos.anchorNode()); |
| 156 splitTextNode(textNode, pos.computeOffsetInContainerNode()); | 157 splitTextNode(textNode, pos.computeOffsetInContainerNode()); |
| 157 insertNodeBefore(nodeToInsert, textNode, editingState); | 158 insertNodeBefore(nodeToInsert, textNode, editingState); |
| 158 if (editingState->isAborted()) | 159 if (editingState->isAborted()) |
| 159 return; | 160 return; |
| 160 Position endingPosition = Position::firstPositionInNode(textNode); | 161 Position endingPosition = Position::firstPositionInNode(textNode); |
| 161 | 162 |
| 162 // Handle whitespace that occurs after the split | 163 // Handle whitespace that occurs after the split |
| 163 document().updateStyleAndLayoutIgnorePendingStylesheets(); | 164 document().updateStyleAndLayoutIgnorePendingStylesheets(); |
| 164 // TODO(yosin) |isRenderedCharacter()| should be removed, and we should | 165 // TODO(yosin) |isRenderedCharacter()| should be removed, and we should |
| 165 // use |VisiblePosition::characterAfter()|. | 166 // use |VisiblePosition::characterAfter()|. |
| 166 if (!isRenderedCharacter(endingPosition)) { | 167 if (!isRenderedCharacter(endingPosition)) { |
| 167 Position positionBeforeTextNode(Position::inParentBeforeNode(*textNode)); | 168 Position positionBeforeTextNode(Position::inParentBeforeNode(*textNode)); |
| 168 // Clear out all whitespace and insert one non-breaking space | 169 // Clear out all whitespace and insert one non-breaking space |
| 169 deleteInsignificantTextDownstream(endingPosition); | 170 deleteInsignificantTextDownstream(endingPosition); |
| 170 DCHECK(!textNode->layoutObject() || | 171 DCHECK(!textNode->layoutObject() || |
| 171 textNode->layoutObject()->style()->collapseWhiteSpace()); | 172 textNode->layoutObject()->style()->collapseWhiteSpace()); |
| 172 // Deleting insignificant whitespace will remove textNode if it contains n
othing but insignificant whitespace. | 173 // Deleting insignificant whitespace will remove textNode if it contains |
| 174 // nothing but insignificant whitespace. |
| 173 if (textNode->isConnected()) { | 175 if (textNode->isConnected()) { |
| 174 insertTextIntoNode(textNode, 0, nonBreakingSpaceString()); | 176 insertTextIntoNode(textNode, 0, nonBreakingSpaceString()); |
| 175 } else { | 177 } else { |
| 176 Text* nbspNode = document().createTextNode(nonBreakingSpaceString()); | 178 Text* nbspNode = document().createTextNode(nonBreakingSpaceString()); |
| 177 insertNodeAt(nbspNode, positionBeforeTextNode, editingState); | 179 insertNodeAt(nbspNode, positionBeforeTextNode, editingState); |
| 178 if (editingState->isAborted()) | 180 if (editingState->isAborted()) |
| 179 return; | 181 return; |
| 180 endingPosition = Position::firstPositionInNode(nbspNode); | 182 endingPosition = Position::firstPositionInNode(nbspNode); |
| 181 } | 183 } |
| 182 } | 184 } |
| 183 | 185 |
| 184 setEndingSelection(createVisibleSelectionDeprecated( | 186 setEndingSelection(createVisibleSelectionDeprecated( |
| 185 endingPosition, TextAffinity::Downstream, | 187 endingPosition, TextAffinity::Downstream, |
| 186 endingSelection().isDirectional())); | 188 endingSelection().isDirectional())); |
| 187 } | 189 } |
| 188 | 190 |
| 189 // Handle the case where there is a typing style. | 191 // Handle the case where there is a typing style. |
| 190 | 192 |
| 191 EditingStyle* typingStyle = document().frame()->selection().typingStyle(); | 193 EditingStyle* typingStyle = document().frame()->selection().typingStyle(); |
| 192 | 194 |
| 193 if (typingStyle && !typingStyle->isEmpty()) { | 195 if (typingStyle && !typingStyle->isEmpty()) { |
| 194 // Apply the typing style to the inserted line break, so that if the selecti
on | 196 // Apply the typing style to the inserted line break, so that if the |
| 195 // leaves and then comes back, new input will have the right style. | 197 // selection leaves and then comes back, new input will have the right |
| 198 // style. |
| 196 // FIXME: We shouldn't always apply the typing style to the line break here, | 199 // FIXME: We shouldn't always apply the typing style to the line break here, |
| 197 // see <rdar://problem/5794462>. | 200 // see <rdar://problem/5794462>. |
| 198 applyStyle(typingStyle, firstPositionInOrBeforeNode(nodeToInsert), | 201 applyStyle(typingStyle, firstPositionInOrBeforeNode(nodeToInsert), |
| 199 lastPositionInOrAfterNode(nodeToInsert), editingState); | 202 lastPositionInOrAfterNode(nodeToInsert), editingState); |
| 200 if (editingState->isAborted()) | 203 if (editingState->isAborted()) |
| 201 return; | 204 return; |
| 202 // Even though this applyStyle operates on a Range, it still sets an endingS
election(). | 205 // Even though this applyStyle operates on a Range, it still sets an |
| 203 // It tries to set a VisibleSelection around the content it operated on. So,
that VisibleSelection | 206 // endingSelection(). It tries to set a VisibleSelection around the content |
| 204 // will either (a) select the line break we inserted, or it will (b) be a ca
ret just | 207 // it operated on. So, that VisibleSelection will either |
| 205 // before the line break (if the line break is at the end of a block it isn'
t selectable). | 208 // (a) select the line break we inserted, or it will |
| 206 // So, this next call sets the endingSelection() to a caret just after the l
ine break | 209 // (b) be a caret just before the line break (if the line break is at the |
| 207 // that we inserted, or just before it if it's at the end of a block. | 210 // end of a block it isn't selectable). |
| 211 // So, this next call sets the endingSelection() to a caret just after the |
| 212 // line break that we inserted, or just before it if it's at the end of a |
| 213 // block. |
| 208 setEndingSelection(endingSelection().visibleEndDeprecated()); | 214 setEndingSelection(endingSelection().visibleEndDeprecated()); |
| 209 } | 215 } |
| 210 | 216 |
| 211 rebalanceWhitespace(); | 217 rebalanceWhitespace(); |
| 212 } | 218 } |
| 213 | 219 |
| 214 } // namespace blink | 220 } // namespace blink |
| OLD | NEW |