| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006, 2007, 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 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 bool CompositeEditCommand::canRebalance(const Position& position) const | 614 bool CompositeEditCommand::canRebalance(const Position& position) const |
| 615 { | 615 { |
| 616 Node* node = position.containerNode(); | 616 Node* node = position.containerNode(); |
| 617 if (position.anchorType() != Position::PositionIsOffsetInAnchor || !node ||
!node->isTextNode()) | 617 if (position.anchorType() != Position::PositionIsOffsetInAnchor || !node ||
!node->isTextNode()) |
| 618 return false; | 618 return false; |
| 619 | 619 |
| 620 Text* textNode = toText(node); | 620 Text* textNode = toText(node); |
| 621 if (textNode->length() == 0) | 621 if (textNode->length() == 0) |
| 622 return false; | 622 return false; |
| 623 | 623 |
| 624 LayoutText* renderer = textNode->renderer(); | 624 LayoutText* renderer = textNode->layoutObject(); |
| 625 if (renderer && !renderer->style()->collapseWhiteSpace()) | 625 if (renderer && !renderer->style()->collapseWhiteSpace()) |
| 626 return false; | 626 return false; |
| 627 | 627 |
| 628 return true; | 628 return true; |
| 629 } | 629 } |
| 630 | 630 |
| 631 // FIXME: Doesn't go into text nodes that contribute adjacent text (siblings, co
usins, etc). | 631 // FIXME: Doesn't go into text nodes that contribute adjacent text (siblings, co
usins, etc). |
| 632 void CompositeEditCommand::rebalanceWhitespaceAt(const Position& position) | 632 void CompositeEditCommand::rebalanceWhitespaceAt(const Position& position) |
| 633 { | 633 { |
| 634 Node* node = position.containerNode(); | 634 Node* node = position.containerNode(); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 683 | 683 |
| 684 void CompositeEditCommand::prepareWhitespaceAtPositionForSplit(Position& positio
n) | 684 void CompositeEditCommand::prepareWhitespaceAtPositionForSplit(Position& positio
n) |
| 685 { | 685 { |
| 686 Node* node = position.deprecatedNode(); | 686 Node* node = position.deprecatedNode(); |
| 687 if (!node || !node->isTextNode()) | 687 if (!node || !node->isTextNode()) |
| 688 return; | 688 return; |
| 689 Text* textNode = toText(node); | 689 Text* textNode = toText(node); |
| 690 | 690 |
| 691 if (textNode->length() == 0) | 691 if (textNode->length() == 0) |
| 692 return; | 692 return; |
| 693 LayoutText* renderer = textNode->renderer(); | 693 LayoutText* renderer = textNode->layoutObject(); |
| 694 if (renderer && !renderer->style()->collapseWhiteSpace()) | 694 if (renderer && !renderer->style()->collapseWhiteSpace()) |
| 695 return; | 695 return; |
| 696 | 696 |
| 697 // Delete collapsed whitespace so that inserting nbsps doesn't uncollapse it
. | 697 // Delete collapsed whitespace so that inserting nbsps doesn't uncollapse it
. |
| 698 Position upstreamPos = position.upstream(); | 698 Position upstreamPos = position.upstream(); |
| 699 deleteInsignificantText(upstreamPos, position.downstream()); | 699 deleteInsignificantText(upstreamPos, position.downstream()); |
| 700 position = upstreamPos.downstream(); | 700 position = upstreamPos.downstream(); |
| 701 | 701 |
| 702 VisiblePosition visiblePos(position); | 702 VisiblePosition visiblePos(position); |
| 703 VisiblePosition previousVisiblePos(visiblePos.previous()); | 703 VisiblePosition previousVisiblePos(visiblePos.previous()); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 726 rebalanceWhitespaceAt(selection.end()); | 726 rebalanceWhitespaceAt(selection.end()); |
| 727 } | 727 } |
| 728 | 728 |
| 729 void CompositeEditCommand::deleteInsignificantText(PassRefPtrWillBeRawPtr<Text>
textNode, unsigned start, unsigned end) | 729 void CompositeEditCommand::deleteInsignificantText(PassRefPtrWillBeRawPtr<Text>
textNode, unsigned start, unsigned end) |
| 730 { | 730 { |
| 731 if (!textNode || start >= end) | 731 if (!textNode || start >= end) |
| 732 return; | 732 return; |
| 733 | 733 |
| 734 document().updateLayout(); | 734 document().updateLayout(); |
| 735 | 735 |
| 736 LayoutText* textRenderer = textNode->renderer(); | 736 LayoutText* textRenderer = textNode->layoutObject(); |
| 737 if (!textRenderer) | 737 if (!textRenderer) |
| 738 return; | 738 return; |
| 739 | 739 |
| 740 Vector<InlineTextBox*> sortedTextBoxes; | 740 Vector<InlineTextBox*> sortedTextBoxes; |
| 741 size_t sortedTextBoxesPosition = 0; | 741 size_t sortedTextBoxesPosition = 0; |
| 742 | 742 |
| 743 for (InlineTextBox* textBox = textRenderer->firstTextBox(); textBox; textBox
= textBox->nextTextBox()) | 743 for (InlineTextBox* textBox = textRenderer->firstTextBox(); textBox; textBox
= textBox->nextTextBox()) |
| 744 sortedTextBoxes.append(textBox); | 744 sortedTextBoxes.append(textBox); |
| 745 | 745 |
| 746 // If there is mixed directionality text, the boxes can be out of order, | 746 // If there is mixed directionality text, the boxes can be out of order, |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 837 } | 837 } |
| 838 | 838 |
| 839 PassRefPtrWillBeRawPtr<HTMLBRElement> CompositeEditCommand::appendBlockPlacehold
er(PassRefPtrWillBeRawPtr<Element> container) | 839 PassRefPtrWillBeRawPtr<HTMLBRElement> CompositeEditCommand::appendBlockPlacehold
er(PassRefPtrWillBeRawPtr<Element> container) |
| 840 { | 840 { |
| 841 if (!container) | 841 if (!container) |
| 842 return nullptr; | 842 return nullptr; |
| 843 | 843 |
| 844 document().updateLayoutIgnorePendingStylesheets(); | 844 document().updateLayoutIgnorePendingStylesheets(); |
| 845 | 845 |
| 846 // Should assert isLayoutBlockFlow || isInlineFlow when deletion improves. S
ee 4244964. | 846 // Should assert isLayoutBlockFlow || isInlineFlow when deletion improves. S
ee 4244964. |
| 847 ASSERT(container->renderer()); | 847 ASSERT(container->layoutObject()); |
| 848 | 848 |
| 849 RefPtrWillBeRawPtr<HTMLBRElement> placeholder = createBlockPlaceholderElemen
t(document()); | 849 RefPtrWillBeRawPtr<HTMLBRElement> placeholder = createBlockPlaceholderElemen
t(document()); |
| 850 appendNode(placeholder, container); | 850 appendNode(placeholder, container); |
| 851 return placeholder.release(); | 851 return placeholder.release(); |
| 852 } | 852 } |
| 853 | 853 |
| 854 PassRefPtrWillBeRawPtr<HTMLBRElement> CompositeEditCommand::insertBlockPlacehold
er(const Position& pos) | 854 PassRefPtrWillBeRawPtr<HTMLBRElement> CompositeEditCommand::insertBlockPlacehold
er(const Position& pos) |
| 855 { | 855 { |
| 856 if (pos.isNull()) | 856 if (pos.isNull()) |
| 857 return nullptr; | 857 return nullptr; |
| 858 | 858 |
| 859 // Should assert isLayoutBlockFlow || isInlineFlow when deletion improves. S
ee 4244964. | 859 // Should assert isLayoutBlockFlow || isInlineFlow when deletion improves. S
ee 4244964. |
| 860 ASSERT(pos.deprecatedNode()->renderer()); | 860 ASSERT(pos.deprecatedNode()->layoutObject()); |
| 861 | 861 |
| 862 RefPtrWillBeRawPtr<HTMLBRElement> placeholder = createBlockPlaceholderElemen
t(document()); | 862 RefPtrWillBeRawPtr<HTMLBRElement> placeholder = createBlockPlaceholderElemen
t(document()); |
| 863 insertNodeAt(placeholder, pos); | 863 insertNodeAt(placeholder, pos); |
| 864 return placeholder.release(); | 864 return placeholder.release(); |
| 865 } | 865 } |
| 866 | 866 |
| 867 PassRefPtrWillBeRawPtr<HTMLBRElement> CompositeEditCommand::addBlockPlaceholderI
fNeeded(Element* container) | 867 PassRefPtrWillBeRawPtr<HTMLBRElement> CompositeEditCommand::addBlockPlaceholderI
fNeeded(Element* container) |
| 868 { | 868 { |
| 869 if (!container) | 869 if (!container) |
| 870 return nullptr; | 870 return nullptr; |
| 871 | 871 |
| 872 document().updateLayoutIgnorePendingStylesheets(); | 872 document().updateLayoutIgnorePendingStylesheets(); |
| 873 | 873 |
| 874 LayoutObject* renderer = container->renderer(); | 874 LayoutObject* renderer = container->layoutObject(); |
| 875 if (!renderer || !renderer->isLayoutBlockFlow()) | 875 if (!renderer || !renderer->isLayoutBlockFlow()) |
| 876 return nullptr; | 876 return nullptr; |
| 877 | 877 |
| 878 // append the placeholder to make sure it follows | 878 // append the placeholder to make sure it follows |
| 879 // any unrendered blocks | 879 // any unrendered blocks |
| 880 LayoutBlockFlow* block = toLayoutBlockFlow(renderer); | 880 LayoutBlockFlow* block = toLayoutBlockFlow(renderer); |
| 881 if (block->size().height() == 0 || (block->isListItem() && toLayoutListItem(
block)->isEmpty())) | 881 if (block->size().height() == 0 || (block->isListItem() && toLayoutListItem(
block)->isEmpty())) |
| 882 return appendBlockPlaceholder(container); | 882 return appendBlockPlaceholder(container); |
| 883 | 883 |
| 884 return nullptr; | 884 return nullptr; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 928 if (comparePositions(pos, upstreamStart) < 0) | 928 if (comparePositions(pos, upstreamStart) < 0) |
| 929 return nullptr; | 929 return nullptr; |
| 930 | 930 |
| 931 // Perform some checks to see if we need to perform work in this function. | 931 // Perform some checks to see if we need to perform work in this function. |
| 932 if (isBlock(upstreamStart.deprecatedNode())) { | 932 if (isBlock(upstreamStart.deprecatedNode())) { |
| 933 // If the block is the root editable element, always move content to a n
ew block, | 933 // If the block is the root editable element, always move content to a n
ew block, |
| 934 // since it is illegal to modify attributes on the root editable element
for editing. | 934 // since it is illegal to modify attributes on the root editable element
for editing. |
| 935 if (upstreamStart.deprecatedNode() == editableRootForPosition(upstreamSt
art)) { | 935 if (upstreamStart.deprecatedNode() == editableRootForPosition(upstreamSt
art)) { |
| 936 // If the block is the root editable element and it contains no visi
ble content, create a new | 936 // If the block is the root editable element and it contains no visi
ble content, create a new |
| 937 // block but don't try and move content into it, since there's nothi
ng for moveParagraphs to move. | 937 // block but don't try and move content into it, since there's nothi
ng for moveParagraphs to move. |
| 938 if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(upstream
Start.deprecatedNode()->renderer())) | 938 if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(upstream
Start.deprecatedNode()->layoutObject())) |
| 939 return insertNewDefaultParagraphElementAt(upstreamStart); | 939 return insertNewDefaultParagraphElementAt(upstreamStart); |
| 940 } else if (isBlock(upstreamEnd.deprecatedNode())) { | 940 } else if (isBlock(upstreamEnd.deprecatedNode())) { |
| 941 if (!upstreamEnd.deprecatedNode()->isDescendantOf(upstreamStart.depr
ecatedNode())) { | 941 if (!upstreamEnd.deprecatedNode()->isDescendantOf(upstreamStart.depr
ecatedNode())) { |
| 942 // If the paragraph end is a descendant of paragraph start, then
we need to run | 942 // If the paragraph end is a descendant of paragraph start, then
we need to run |
| 943 // the rest of this function. If not, we can bail here. | 943 // the rest of this function. If not, we can bail here. |
| 944 return nullptr; | 944 return nullptr; |
| 945 } | 945 } |
| 946 } else if (enclosingBlock(upstreamEnd.deprecatedNode()) != upstreamStart
.deprecatedNode()) { | 946 } else if (enclosingBlock(upstreamEnd.deprecatedNode()) != upstreamStart
.deprecatedNode()) { |
| 947 // It should be an ancestor of the paragraph start. | 947 // It should be an ancestor of the paragraph start. |
| 948 // We can bail as we have a full block to work with. | 948 // We can bail as we have a full block to work with. |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1383 if (!isStartOfParagraph(atBR)) | 1383 if (!isStartOfParagraph(atBR)) |
| 1384 insertNodeBefore(createBreakElement(document()), br); | 1384 insertNodeBefore(createBreakElement(document()), br); |
| 1385 setEndingSelection(VisibleSelection(atBR, endingSelection().isDirectional())
); | 1385 setEndingSelection(VisibleSelection(atBR, endingSelection().isDirectional())
); |
| 1386 | 1386 |
| 1387 // If this is an empty paragraph there must be a line break here. | 1387 // If this is an empty paragraph there must be a line break here. |
| 1388 if (!lineBreakExistsAtVisiblePosition(caret)) | 1388 if (!lineBreakExistsAtVisiblePosition(caret)) |
| 1389 return false; | 1389 return false; |
| 1390 | 1390 |
| 1391 Position caretPos(caret.deepEquivalent().downstream()); | 1391 Position caretPos(caret.deepEquivalent().downstream()); |
| 1392 // A line break is either a br or a preserved newline. | 1392 // A line break is either a br or a preserved newline. |
| 1393 ASSERT(isHTMLBRElement(caretPos.deprecatedNode()) || (caretPos.deprecatedNod
e()->isTextNode() && caretPos.deprecatedNode()->renderer()->style()->preserveNew
line())); | 1393 ASSERT(isHTMLBRElement(caretPos.deprecatedNode()) || (caretPos.deprecatedNod
e()->isTextNode() && caretPos.deprecatedNode()->layoutObject()->style()->preserv
eNewline())); |
| 1394 | 1394 |
| 1395 if (isHTMLBRElement(*caretPos.deprecatedNode())) | 1395 if (isHTMLBRElement(*caretPos.deprecatedNode())) |
| 1396 removeNodeAndPruneAncestors(caretPos.deprecatedNode()); | 1396 removeNodeAndPruneAncestors(caretPos.deprecatedNode()); |
| 1397 else if (caretPos.deprecatedNode()->isTextNode()) { | 1397 else if (caretPos.deprecatedNode()->isTextNode()) { |
| 1398 ASSERT(caretPos.deprecatedEditingOffset() == 0); | 1398 ASSERT(caretPos.deprecatedEditingOffset() == 0); |
| 1399 Text* textNode = toText(caretPos.deprecatedNode()); | 1399 Text* textNode = toText(caretPos.deprecatedNode()); |
| 1400 ContainerNode* parentNode = textNode->parentNode(); | 1400 ContainerNode* parentNode = textNode->parentNode(); |
| 1401 // The preserved newline must be the first thing in the node, since othe
rwise the previous | 1401 // The preserved newline must be the first thing in the node, since othe
rwise the previous |
| 1402 // paragraph would be quoted, and we verified that it wasn't above. | 1402 // paragraph would be quoted, and we verified that it wasn't above. |
| 1403 deleteTextFromNode(textNode, 0, 1); | 1403 deleteTextFromNode(textNode, 0, 1); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1498 } | 1498 } |
| 1499 | 1499 |
| 1500 DEFINE_TRACE(CompositeEditCommand) | 1500 DEFINE_TRACE(CompositeEditCommand) |
| 1501 { | 1501 { |
| 1502 visitor->trace(m_commands); | 1502 visitor->trace(m_commands); |
| 1503 visitor->trace(m_composition); | 1503 visitor->trace(m_composition); |
| 1504 EditCommand::trace(visitor); | 1504 EditCommand::trace(visitor); |
| 1505 } | 1505 } |
| 1506 | 1506 |
| 1507 } // namespace blink | 1507 } // namespace blink |
| OLD | NEW |