| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005 Apple Computer, Inc. All rights reserved. | 2 * Copyright (C) 2005 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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 | 94 |
| 95 if (text.contains('\t') || text.contains(' ') || text.contains('\n')) | 95 if (text.contains('\t') || text.contains(' ') || text.contains('\n')) |
| 96 return false; | 96 return false; |
| 97 | 97 |
| 98 Position start = endingSelection().start(); | 98 Position start = endingSelection().start(); |
| 99 Position endPosition = replaceSelectedTextInNode(text); | 99 Position endPosition = replaceSelectedTextInNode(text); |
| 100 if (endPosition.isNull()) | 100 if (endPosition.isNull()) |
| 101 return false; | 101 return false; |
| 102 | 102 |
| 103 setEndingSelectionWithoutValidation(start, endPosition); | 103 setEndingSelectionWithoutValidation(start, endPosition); |
| 104 if (!selectInsertedText) | 104 if (!selectInsertedText) { |
| 105 setEndingSelection(createVisibleSelectionDeprecated( | 105 document().updateStyleAndLayoutIgnorePendingStylesheets(); |
| 106 endingSelection().visibleEndDeprecated(), | 106 setEndingSelection(createVisibleSelection( |
| 107 endingSelection().isDirectional())); | 107 endingSelection().visibleEnd(), endingSelection().isDirectional())); |
| 108 } |
| 108 | 109 |
| 109 return true; | 110 return true; |
| 110 } | 111 } |
| 111 | 112 |
| 112 bool InsertTextCommand::performOverwrite(const String& text, | 113 bool InsertTextCommand::performOverwrite(const String& text, |
| 113 bool selectInsertedText) { | 114 bool selectInsertedText) { |
| 114 Position start = endingSelection().start(); | 115 Position start = endingSelection().start(); |
| 115 if (start.isNull() || !start.isOffsetInAnchor() || | 116 if (start.isNull() || !start.isOffsetInAnchor() || |
| 116 !start.computeContainerNode()->isTextNode()) | 117 !start.computeContainerNode()->isTextNode()) |
| 117 return false; | 118 return false; |
| 118 Text* textNode = toText(start.computeContainerNode()); | 119 Text* textNode = toText(start.computeContainerNode()); |
| 119 if (!textNode) | 120 if (!textNode) |
| 120 return false; | 121 return false; |
| 121 | 122 |
| 122 unsigned count = std::min(text.length(), | 123 unsigned count = std::min(text.length(), |
| 123 textNode->length() - start.offsetInContainerNode()); | 124 textNode->length() - start.offsetInContainerNode()); |
| 124 if (!count) | 125 if (!count) |
| 125 return false; | 126 return false; |
| 126 | 127 |
| 127 replaceTextInNode(textNode, start.offsetInContainerNode(), count, text); | 128 replaceTextInNode(textNode, start.offsetInContainerNode(), count, text); |
| 128 | 129 |
| 129 Position endPosition = | 130 Position endPosition = |
| 130 Position(textNode, start.offsetInContainerNode() + text.length()); | 131 Position(textNode, start.offsetInContainerNode() + text.length()); |
| 131 setEndingSelectionWithoutValidation(start, endPosition); | 132 setEndingSelectionWithoutValidation(start, endPosition); |
| 132 if (!selectInsertedText) | 133 if (!selectInsertedText) { |
| 133 setEndingSelection(createVisibleSelectionDeprecated( | 134 document().updateStyleAndLayoutIgnorePendingStylesheets(); |
| 134 endingSelection().visibleEndDeprecated(), | 135 setEndingSelection(createVisibleSelection( |
| 135 endingSelection().isDirectional())); | 136 endingSelection().visibleEnd(), endingSelection().isDirectional())); |
| 137 } |
| 136 | 138 |
| 137 return true; | 139 return true; |
| 138 } | 140 } |
| 139 | 141 |
| 140 void InsertTextCommand::doApply(EditingState* editingState) { | 142 void InsertTextCommand::doApply(EditingState* editingState) { |
| 141 DCHECK_EQ(m_text.find('\n'), kNotFound); | 143 DCHECK_EQ(m_text.find('\n'), kNotFound); |
| 142 | 144 |
| 143 if (!endingSelection().isNonOrphanedCaretOrRange()) | 145 if (!endingSelection().isNonOrphanedCaretOrRange()) |
| 144 return; | 146 return; |
| 145 | 147 |
| 146 // Delete the current selection. | 148 // Delete the current selection. |
| 147 // FIXME: This delete operation blows away the typing style. | 149 // FIXME: This delete operation blows away the typing style. |
| 148 if (endingSelection().isRange()) { | 150 if (endingSelection().isRange()) { |
| 149 if (performTrivialReplace(m_text, m_selectInsertedText)) | 151 if (performTrivialReplace(m_text, m_selectInsertedText)) |
| 150 return; | 152 return; |
| 153 document().updateStyleAndLayoutIgnorePendingStylesheets(); |
| 151 bool endOfSelectionWasAtStartOfBlock = | 154 bool endOfSelectionWasAtStartOfBlock = |
| 152 isStartOfBlock(endingSelection().visibleEndDeprecated()); | 155 isStartOfBlock(endingSelection().visibleEnd()); |
| 153 deleteSelection(editingState, false, true, false, false); | 156 deleteSelection(editingState, false, true, false, false); |
| 154 if (editingState->isAborted()) | 157 if (editingState->isAborted()) |
| 155 return; | 158 return; |
| 156 // deleteSelection eventually makes a new endingSelection out of a Position. | 159 // deleteSelection eventually makes a new endingSelection out of a Position. |
| 157 // If that Position doesn't have a layoutObject (e.g. it is on a <frameset> | 160 // If that Position doesn't have a layoutObject (e.g. it is on a <frameset> |
| 158 // in the DOM), the VisibleSelection cannot be canonicalized to anything | 161 // in the DOM), the VisibleSelection cannot be canonicalized to anything |
| 159 // other than NoSelection. The rest of this function requires a real | 162 // other than NoSelection. The rest of this function requires a real |
| 160 // endingSelection, so bail out. | 163 // endingSelection, so bail out. |
| 161 if (endingSelection().isNone()) | 164 if (endingSelection().isNone()) |
| 162 return; | 165 return; |
| 163 if (endOfSelectionWasAtStartOfBlock) { | 166 if (endOfSelectionWasAtStartOfBlock) { |
| 164 if (EditingStyle* typingStyle = | 167 if (EditingStyle* typingStyle = |
| 165 document().frame()->selection().typingStyle()) | 168 document().frame()->selection().typingStyle()) |
| 166 typingStyle->removeBlockProperties(); | 169 typingStyle->removeBlockProperties(); |
| 167 } | 170 } |
| 168 } else if (document().frame()->editor().isOverwriteModeEnabled()) { | 171 } else if (document().frame()->editor().isOverwriteModeEnabled()) { |
| 169 if (performOverwrite(m_text, m_selectInsertedText)) | 172 if (performOverwrite(m_text, m_selectInsertedText)) |
| 170 return; | 173 return; |
| 171 } | 174 } |
| 172 | 175 |
| 176 document().updateStyleAndLayoutIgnorePendingStylesheets(); |
| 177 |
| 173 Position startPosition(endingSelection().start()); | 178 Position startPosition(endingSelection().start()); |
| 174 | 179 |
| 175 Position placeholder; | 180 Position placeholder; |
| 176 // We want to remove preserved newlines and brs that will collapse (and thus | 181 // We want to remove preserved newlines and brs that will collapse (and thus |
| 177 // become unnecessary) when content is inserted just before them. | 182 // become unnecessary) when content is inserted just before them. |
| 178 // FIXME: We shouldn't really have to do this, but removing placeholders is a | 183 // FIXME: We shouldn't really have to do this, but removing placeholders is a |
| 179 // workaround for 9661. | 184 // workaround for 9661. |
| 180 // If the caret is just before a placeholder, downstream will normalize the | 185 // If the caret is just before a placeholder, downstream will normalize the |
| 181 // caret to it. | 186 // caret to it. |
| 182 Position downstream(mostForwardCaretPosition(startPosition)); | 187 Position downstream(mostForwardCaretPosition(startPosition)); |
| 183 if (lineBreakExistsAtPosition(downstream)) { | 188 if (lineBreakExistsAtPosition(downstream)) { |
| 184 // FIXME: This doesn't handle placeholders at the end of anonymous blocks. | 189 // FIXME: This doesn't handle placeholders at the end of anonymous blocks. |
| 185 VisiblePosition caret = createVisiblePositionDeprecated(startPosition); | 190 VisiblePosition caret = createVisiblePosition(startPosition); |
| 186 if (isEndOfBlock(caret) && isStartOfParagraphDeprecated(caret)) | 191 if (isEndOfBlock(caret) && isStartOfParagraph(caret)) |
| 187 placeholder = downstream; | 192 placeholder = downstream; |
| 188 // Don't remove the placeholder yet, otherwise the block we're inserting | 193 // Don't remove the placeholder yet, otherwise the block we're inserting |
| 189 // into would collapse before we get a chance to insert into it. We check | 194 // into would collapse before we get a chance to insert into it. We check |
| 190 // for a placeholder now, though, because doing so requires the creation of | 195 // for a placeholder now, though, because doing so requires the creation of |
| 191 // a VisiblePosition, and if we did that post-insertion it would force a | 196 // a VisiblePosition, and if we did that post-insertion it would force a |
| 192 // layout. | 197 // layout. |
| 193 } | 198 } |
| 194 | 199 |
| 195 // Insert the character at the leftmost candidate. | 200 // Insert the character at the leftmost candidate. |
| 196 startPosition = mostBackwardCaretPosition(startPosition); | 201 startPosition = mostBackwardCaretPosition(startPosition); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 document().frame()->selection().typingStyle()) { | 268 document().frame()->selection().typingStyle()) { |
| 264 typingStyle->prepareToApplyAt(endPosition, | 269 typingStyle->prepareToApplyAt(endPosition, |
| 265 EditingStyle::PreserveWritingDirection); | 270 EditingStyle::PreserveWritingDirection); |
| 266 if (!typingStyle->isEmpty()) { | 271 if (!typingStyle->isEmpty()) { |
| 267 applyStyle(typingStyle, editingState); | 272 applyStyle(typingStyle, editingState); |
| 268 if (editingState->isAborted()) | 273 if (editingState->isAborted()) |
| 269 return; | 274 return; |
| 270 } | 275 } |
| 271 } | 276 } |
| 272 | 277 |
| 273 if (!m_selectInsertedText) | 278 if (!m_selectInsertedText) { |
| 274 setEndingSelection(createVisibleSelectionDeprecated( | 279 document().updateStyleAndLayoutIgnorePendingStylesheets(); |
| 280 setEndingSelection(createVisibleSelection( |
| 275 endingSelection().end(), endingSelection().affinity(), | 281 endingSelection().end(), endingSelection().affinity(), |
| 276 endingSelection().isDirectional())); | 282 endingSelection().isDirectional())); |
| 283 } |
| 277 } | 284 } |
| 278 | 285 |
| 279 Position InsertTextCommand::insertTab(const Position& pos, | 286 Position InsertTextCommand::insertTab(const Position& pos, |
| 280 EditingState* editingState) { | 287 EditingState* editingState) { |
| 281 Position insertPos = createVisiblePositionDeprecated(pos).deepEquivalent(); | 288 document().updateStyleAndLayoutIgnorePendingStylesheets(); |
| 289 |
| 290 Position insertPos = createVisiblePosition(pos).deepEquivalent(); |
| 282 if (insertPos.isNull()) | 291 if (insertPos.isNull()) |
| 283 return pos; | 292 return pos; |
| 284 | 293 |
| 285 Node* node = insertPos.computeContainerNode(); | 294 Node* node = insertPos.computeContainerNode(); |
| 286 unsigned offset = node->isTextNode() ? insertPos.offsetInContainerNode() : 0; | 295 unsigned offset = node->isTextNode() ? insertPos.offsetInContainerNode() : 0; |
| 287 | 296 |
| 288 // keep tabs coalesced in tab span | 297 // keep tabs coalesced in tab span |
| 289 if (isTabHTMLSpanElementTextNode(node)) { | 298 if (isTabHTMLSpanElementTextNode(node)) { |
| 290 Text* textNode = toText(node); | 299 Text* textNode = toText(node); |
| 291 insertTextIntoNode(textNode, offset, "\t"); | 300 insertTextIntoNode(textNode, offset, "\t"); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 313 } | 322 } |
| 314 } | 323 } |
| 315 if (editingState->isAborted()) | 324 if (editingState->isAborted()) |
| 316 return Position(); | 325 return Position(); |
| 317 | 326 |
| 318 // return the position following the new tab | 327 // return the position following the new tab |
| 319 return Position::lastPositionInNode(spanElement); | 328 return Position::lastPositionInNode(spanElement); |
| 320 } | 329 } |
| 321 | 330 |
| 322 } // namespace blink | 331 } // namespace blink |
| OLD | NEW |