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 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 || isTableCell(startBlock.get()) | 176 || isTableCell(startBlock.get()) |
177 || isHTMLFormElement(*startBlock) | 177 || isHTMLFormElement(*startBlock) |
178 // FIXME: If the node is hidden, we don't have a canonical position so w
e will do the wrong thing for tables and <hr>. https://bugs.webkit.org/show_bug.
cgi?id=40342 | 178 // FIXME: If the node is hidden, we don't have a canonical position so w
e will do the wrong thing for tables and <hr>. https://bugs.webkit.org/show_bug.
cgi?id=40342 |
179 || (!canonicalPos.isNull() && isRenderedTableElement(canonicalPos.anchor
Node())) | 179 || (!canonicalPos.isNull() && isRenderedTableElement(canonicalPos.anchor
Node())) |
180 || (!canonicalPos.isNull() && isHTMLHRElement(*canonicalPos.anchorNode()
))) { | 180 || (!canonicalPos.isNull() && isHTMLHRElement(*canonicalPos.anchorNode()
))) { |
181 applyCommandToComposite(InsertLineBreakCommand::create(document())); | 181 applyCommandToComposite(InsertLineBreakCommand::create(document())); |
182 return; | 182 return; |
183 } | 183 } |
184 | 184 |
185 // Use the leftmost candidate. | 185 // Use the leftmost candidate. |
186 insertionPosition = insertionPosition.upstream(); | 186 insertionPosition = mostBackwardCaretPosition(insertionPosition); |
187 if (!isVisuallyEquivalentCandidate(insertionPosition)) | 187 if (!isVisuallyEquivalentCandidate(insertionPosition)) |
188 insertionPosition = insertionPosition.downstream(); | 188 insertionPosition = mostForwardCaretPosition(insertionPosition); |
189 | 189 |
190 // Adjust the insertion position after the delete | 190 // Adjust the insertion position after the delete |
191 insertionPosition = positionAvoidingSpecialElementBoundary(insertionPosition
); | 191 insertionPosition = positionAvoidingSpecialElementBoundary(insertionPosition
); |
192 VisiblePosition visiblePos(insertionPosition, affinity); | 192 VisiblePosition visiblePos(insertionPosition, affinity); |
193 calculateStyleBeforeInsertion(insertionPosition); | 193 calculateStyleBeforeInsertion(insertionPosition); |
194 | 194 |
195 //--------------------------------------------------------------------- | 195 //--------------------------------------------------------------------- |
196 // Handle special case of typing return on an empty list item | 196 // Handle special case of typing return on an empty list item |
197 if (breakOutOfEmptyListItem()) | 197 if (breakOutOfEmptyListItem()) |
198 return; | 198 return; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 ASSERT(startBlock->hasChildren()); | 283 ASSERT(startBlock->hasChildren()); |
284 refNode = startBlock->firstChild(); | 284 refNode = startBlock->firstChild(); |
285 } else if (insertionPosition.anchorNode() == startBlock && nestNewBlock)
{ | 285 } else if (insertionPosition.anchorNode() == startBlock && nestNewBlock)
{ |
286 refNode = NodeTraversal::childAt(*startBlock, insertionPosition.comp
uteEditingOffset()); | 286 refNode = NodeTraversal::childAt(*startBlock, insertionPosition.comp
uteEditingOffset()); |
287 ASSERT(refNode); // must be true or we'd be in the end of block case | 287 ASSERT(refNode); // must be true or we'd be in the end of block case |
288 } else { | 288 } else { |
289 refNode = insertionPosition.anchorNode(); | 289 refNode = insertionPosition.anchorNode(); |
290 } | 290 } |
291 | 291 |
292 // find ending selection position easily before inserting the paragraph | 292 // find ending selection position easily before inserting the paragraph |
293 insertionPosition = insertionPosition.downstream(); | 293 insertionPosition = mostForwardCaretPosition(insertionPosition); |
294 | 294 |
295 if (refNode) | 295 if (refNode) |
296 insertNodeBefore(blockToInsert, refNode); | 296 insertNodeBefore(blockToInsert, refNode); |
297 | 297 |
298 // Recreate the same structure in the new paragraph. | 298 // Recreate the same structure in the new paragraph. |
299 | 299 |
300 WillBeHeapVector<RefPtrWillBeMember<Element>> ancestors; | 300 WillBeHeapVector<RefPtrWillBeMember<Element>> ancestors; |
301 getAncestorsInsideBlock(positionAvoidingSpecialElementBoundary(positionO
utsideTabSpan(insertionPosition)).anchorNode(), startBlock.get(), ancestors); | 301 getAncestorsInsideBlock(positionAvoidingSpecialElementBoundary(positionO
utsideTabSpan(insertionPosition)).anchorNode(), startBlock.get(), ancestors); |
302 | 302 |
303 appendBlockPlaceholder(cloneHierarchyUnderNewBlock(ancestors, blockToIns
ert)); | 303 appendBlockPlaceholder(cloneHierarchyUnderNewBlock(ancestors, blockToIns
ert)); |
(...skipping 17 matching lines...) Expand all Loading... |
321 // If the insertion point is a break element, there is nothing else | 321 // If the insertion point is a break element, there is nothing else |
322 // we need to do. | 322 // we need to do. |
323 if (visiblePos.deepEquivalent().anchorNode()->layoutObject()->isBR()) { | 323 if (visiblePos.deepEquivalent().anchorNode()->layoutObject()->isBR()) { |
324 setEndingSelection(VisibleSelection(insertionPosition, TextAffinity:
:Downstream, endingSelection().isDirectional())); | 324 setEndingSelection(VisibleSelection(insertionPosition, TextAffinity:
:Downstream, endingSelection().isDirectional())); |
325 return; | 325 return; |
326 } | 326 } |
327 } | 327 } |
328 | 328 |
329 // Move downstream. Typing style code will take care of carrying along the | 329 // Move downstream. Typing style code will take care of carrying along the |
330 // style of the upstream position. | 330 // style of the upstream position. |
331 insertionPosition = insertionPosition.downstream(); | 331 insertionPosition = mostForwardCaretPosition(insertionPosition); |
332 | 332 |
333 // At this point, the insertionPosition's node could be a container, and we
want to make sure we include | 333 // At this point, the insertionPosition's node could be a container, and we
want to make sure we include |
334 // all of the correct nodes when building the ancestor list. So this needs
to be the deepest representation of the position | 334 // all of the correct nodes when building the ancestor list. So this needs
to be the deepest representation of the position |
335 // before we walk the DOM tree. | 335 // before we walk the DOM tree. |
336 insertionPosition = positionOutsideTabSpan(VisiblePosition(insertionPosition
).deepEquivalent()); | 336 insertionPosition = positionOutsideTabSpan(VisiblePosition(insertionPosition
).deepEquivalent()); |
337 | 337 |
338 // If the returned position lies either at the end or at the start of an ele
ment that is ignored by editing | 338 // If the returned position lies either at the end or at the start of an ele
ment that is ignored by editing |
339 // we should move to its upstream or downstream position. | 339 // we should move to its upstream or downstream position. |
340 if (editingIgnoresContent(insertionPosition.anchorNode())) { | 340 if (editingIgnoresContent(insertionPosition.anchorNode())) { |
341 if (insertionPosition.atLastEditingPositionForNode()) | 341 if (insertionPosition.atLastEditingPositionForNode()) |
342 insertionPosition = insertionPosition.downstream(); | 342 insertionPosition = mostForwardCaretPosition(insertionPosition); |
343 else if (insertionPosition.atFirstEditingPositionForNode()) | 343 else if (insertionPosition.atFirstEditingPositionForNode()) |
344 insertionPosition = insertionPosition.upstream(); | 344 insertionPosition = mostBackwardCaretPosition(insertionPosition); |
345 } | 345 } |
346 | 346 |
347 // Make sure we do not cause a rendered space to become unrendered. | 347 // Make sure we do not cause a rendered space to become unrendered. |
348 // FIXME: We need the affinity for pos, but pos.downstream() does not give i
t | 348 // FIXME: We need the affinity for pos, but mostForwardCaretPosition does no
t give it |
349 Position leadingWhitespace = leadingWhitespacePosition(insertionPosition, VP
_DEFAULT_AFFINITY); | 349 Position leadingWhitespace = leadingWhitespacePosition(insertionPosition, VP
_DEFAULT_AFFINITY); |
350 // FIXME: leadingWhitespacePosition is returning the position before preserv
ed newlines for positions | 350 // FIXME: leadingWhitespacePosition is returning the position before preserv
ed newlines for positions |
351 // after the preserved newline, causing the newline to be turned into a nbsp
. | 351 // after the preserved newline, causing the newline to be turned into a nbsp
. |
352 if (leadingWhitespace.isNotNull() && leadingWhitespace.anchorNode()->isTextN
ode()) { | 352 if (leadingWhitespace.isNotNull() && leadingWhitespace.anchorNode()->isTextN
ode()) { |
353 Text* textNode = toText(leadingWhitespace.anchorNode()); | 353 Text* textNode = toText(leadingWhitespace.anchorNode()); |
354 ASSERT(!textNode->layoutObject() || textNode->layoutObject()->style()->c
ollapseWhiteSpace()); | 354 ASSERT(!textNode->layoutObject() || textNode->layoutObject()->style()->c
ollapseWhiteSpace()); |
355 replaceTextInNodePreservingMarkers(textNode, leadingWhitespace.computeOf
fsetInContainerNode(), 1, nonBreakingSpaceString()); | 355 replaceTextInNodePreservingMarkers(textNode, leadingWhitespace.computeOf
fsetInContainerNode(), 1, nonBreakingSpaceString()); |
356 } | 356 } |
357 | 357 |
358 // Split at pos if in the middle of a text node. | 358 // Split at pos if in the middle of a text node. |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 } | 433 } |
434 | 434 |
435 DEFINE_TRACE(InsertParagraphSeparatorCommand) | 435 DEFINE_TRACE(InsertParagraphSeparatorCommand) |
436 { | 436 { |
437 visitor->trace(m_style); | 437 visitor->trace(m_style); |
438 CompositeEditCommand::trace(visitor); | 438 CompositeEditCommand::trace(visitor); |
439 } | 439 } |
440 | 440 |
441 | 441 |
442 } // namespace blink | 442 } // namespace blink |
OLD | NEW |