| 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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 | 72 |
| 73 return pos; | 73 return pos; |
| 74 } | 74 } |
| 75 | 75 |
| 76 void InsertTextCommand::setEndingSelectionWithoutValidation( | 76 void InsertTextCommand::setEndingSelectionWithoutValidation( |
| 77 const Position& startPosition, | 77 const Position& startPosition, |
| 78 const Position& endPosition) { | 78 const Position& endPosition) { |
| 79 // We could have inserted a part of composed character sequence, | 79 // We could have inserted a part of composed character sequence, |
| 80 // so we are basically treating ending selection as a range to avoid | 80 // so we are basically treating ending selection as a range to avoid |
| 81 // validation. <http://bugs.webkit.org/show_bug.cgi?id=15781> | 81 // validation. <http://bugs.webkit.org/show_bug.cgi?id=15781> |
| 82 VisibleSelection forcedEndingSelection; | 82 setEndingSelection(SelectionInDOMTree::Builder() |
| 83 forcedEndingSelection.setWithoutValidation(startPosition, endPosition); | 83 .collapse(startPosition) |
| 84 forcedEndingSelection.setIsDirectional(endingSelection().isDirectional()); | 84 .extend(endPosition) |
| 85 setEndingSelection(forcedEndingSelection); | 85 .setIsDirectional(endingSelection().isDirectional()) |
| 86 .build()); |
| 86 } | 87 } |
| 87 | 88 |
| 88 // This avoids the expense of a full fledged delete operation, and avoids a | 89 // This avoids the expense of a full fledged delete operation, and avoids a |
| 89 // layout that typically results from text removal. | 90 // layout that typically results from text removal. |
| 90 bool InsertTextCommand::performTrivialReplace(const String& text, | 91 bool InsertTextCommand::performTrivialReplace(const String& text, |
| 91 bool selectInsertedText) { | 92 bool selectInsertedText) { |
| 92 if (!endingSelection().isRange()) | 93 if (!endingSelection().isRange()) |
| 93 return false; | 94 return false; |
| 94 | 95 |
| 95 if (text.contains('\t') || text.contains(' ') || text.contains('\n')) | 96 if (text.contains('\t') || text.contains(' ') || text.contains('\n')) |
| 96 return false; | 97 return false; |
| 97 | 98 |
| 98 Position start = endingSelection().start(); | 99 Position start = endingSelection().start(); |
| 99 Position endPosition = replaceSelectedTextInNode(text); | 100 Position endPosition = replaceSelectedTextInNode(text); |
| 100 if (endPosition.isNull()) | 101 if (endPosition.isNull()) |
| 101 return false; | 102 return false; |
| 102 | 103 |
| 103 setEndingSelectionWithoutValidation(start, endPosition); | 104 setEndingSelectionWithoutValidation(start, endPosition); |
| 104 if (selectInsertedText) | 105 if (selectInsertedText) |
| 105 return true; | 106 return true; |
| 106 document().updateStyleAndLayoutIgnorePendingStylesheets(); | 107 setEndingSelection(SelectionInDOMTree::Builder() |
| 107 setEndingSelection(createVisibleSelection( | 108 .collapse(endingSelection().end()) |
| 108 SelectionInDOMTree::Builder() | 109 .setIsDirectional(endingSelection().isDirectional()) |
| 109 .collapse(endingSelection().end()) | 110 .build()); |
| 110 .setIsDirectional(endingSelection().isDirectional()) | |
| 111 .build())); | |
| 112 return true; | 111 return true; |
| 113 } | 112 } |
| 114 | 113 |
| 115 bool InsertTextCommand::performOverwrite(const String& text, | 114 bool InsertTextCommand::performOverwrite(const String& text, |
| 116 bool selectInsertedText) { | 115 bool selectInsertedText) { |
| 117 Position start = endingSelection().start(); | 116 Position start = endingSelection().start(); |
| 118 if (start.isNull() || !start.isOffsetInAnchor() || | 117 if (start.isNull() || !start.isOffsetInAnchor() || |
| 119 !start.computeContainerNode()->isTextNode()) | 118 !start.computeContainerNode()->isTextNode()) |
| 120 return false; | 119 return false; |
| 121 Text* textNode = toText(start.computeContainerNode()); | 120 Text* textNode = toText(start.computeContainerNode()); |
| 122 if (!textNode) | 121 if (!textNode) |
| 123 return false; | 122 return false; |
| 124 | 123 |
| 125 unsigned count = std::min(text.length(), | 124 unsigned count = std::min(text.length(), |
| 126 textNode->length() - start.offsetInContainerNode()); | 125 textNode->length() - start.offsetInContainerNode()); |
| 127 if (!count) | 126 if (!count) |
| 128 return false; | 127 return false; |
| 129 | 128 |
| 130 replaceTextInNode(textNode, start.offsetInContainerNode(), count, text); | 129 replaceTextInNode(textNode, start.offsetInContainerNode(), count, text); |
| 131 | 130 |
| 132 Position endPosition = | 131 Position endPosition = |
| 133 Position(textNode, start.offsetInContainerNode() + text.length()); | 132 Position(textNode, start.offsetInContainerNode() + text.length()); |
| 134 setEndingSelectionWithoutValidation(start, endPosition); | 133 setEndingSelectionWithoutValidation(start, endPosition); |
| 135 if (selectInsertedText) | 134 if (selectInsertedText || endingSelection().isNone()) |
| 136 return true; | 135 return true; |
| 137 document().updateStyleAndLayoutIgnorePendingStylesheets(); | 136 setEndingSelection(SelectionInDOMTree::Builder() |
| 138 if (endingSelection().isNone()) | 137 .collapse(endingSelection().end()) |
| 139 return true; | 138 .setIsDirectional(endingSelection().isDirectional()) |
| 140 setEndingSelection(createVisibleSelection( | 139 .build()); |
| 141 SelectionInDOMTree::Builder() | |
| 142 .collapse(endingSelection().end()) | |
| 143 .setIsDirectional(endingSelection().isDirectional()) | |
| 144 .build())); | |
| 145 return true; | 140 return true; |
| 146 } | 141 } |
| 147 | 142 |
| 148 void InsertTextCommand::doApply(EditingState* editingState) { | 143 void InsertTextCommand::doApply(EditingState* editingState) { |
| 149 DCHECK_EQ(m_text.find('\n'), kNotFound); | 144 DCHECK_EQ(m_text.find('\n'), kNotFound); |
| 150 | 145 |
| 151 if (!endingSelection().isNonOrphanedCaretOrRange()) | 146 if (!endingSelection().isNonOrphanedCaretOrRange()) |
| 152 return; | 147 return; |
| 153 | 148 |
| 154 // Delete the current selection. | 149 // Delete the current selection. |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 typingStyle->prepareToApplyAt(endPosition, | 270 typingStyle->prepareToApplyAt(endPosition, |
| 276 EditingStyle::PreserveWritingDirection); | 271 EditingStyle::PreserveWritingDirection); |
| 277 if (!typingStyle->isEmpty()) { | 272 if (!typingStyle->isEmpty()) { |
| 278 applyStyle(typingStyle, editingState); | 273 applyStyle(typingStyle, editingState); |
| 279 if (editingState->isAborted()) | 274 if (editingState->isAborted()) |
| 280 return; | 275 return; |
| 281 } | 276 } |
| 282 } | 277 } |
| 283 | 278 |
| 284 if (!m_selectInsertedText) { | 279 if (!m_selectInsertedText) { |
| 285 document().updateStyleAndLayoutIgnorePendingStylesheets(); | |
| 286 SelectionInDOMTree::Builder builder; | 280 SelectionInDOMTree::Builder builder; |
| 287 builder.setAffinity(endingSelection().affinity()); | 281 builder.setAffinity(endingSelection().affinity()); |
| 288 builder.setIsDirectional(endingSelection().isDirectional()); | 282 builder.setIsDirectional(endingSelection().isDirectional()); |
| 289 if (endingSelection().end().isNotNull()) | 283 if (endingSelection().end().isNotNull()) |
| 290 builder.collapse(endingSelection().end()); | 284 builder.collapse(endingSelection().end()); |
| 291 setEndingSelection(createVisibleSelection(builder.build())); | 285 setEndingSelection(builder.build()); |
| 292 } | 286 } |
| 293 } | 287 } |
| 294 | 288 |
| 295 Position InsertTextCommand::insertTab(const Position& pos, | 289 Position InsertTextCommand::insertTab(const Position& pos, |
| 296 EditingState* editingState) { | 290 EditingState* editingState) { |
| 297 document().updateStyleAndLayoutIgnorePendingStylesheets(); | 291 document().updateStyleAndLayoutIgnorePendingStylesheets(); |
| 298 | 292 |
| 299 Position insertPos = createVisiblePosition(pos).deepEquivalent(); | 293 Position insertPos = createVisiblePosition(pos).deepEquivalent(); |
| 300 if (insertPos.isNull()) | 294 if (insertPos.isNull()) |
| 301 return pos; | 295 return pos; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 331 } | 325 } |
| 332 } | 326 } |
| 333 if (editingState->isAborted()) | 327 if (editingState->isAborted()) |
| 334 return Position(); | 328 return Position(); |
| 335 | 329 |
| 336 // return the position following the new tab | 330 // return the position following the new tab |
| 337 return Position::lastPositionInNode(spanElement); | 331 return Position::lastPositionInNode(spanElement); |
| 338 } | 332 } |
| 339 | 333 |
| 340 } // namespace blink | 334 } // namespace blink |
| OLD | NEW |