| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005, 2006, 2008, 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006, 2008, 2009 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 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 int startIndex = TextIterator::rangeLength(startRange, true); | 258 int startIndex = TextIterator::rangeLength(startRange, true); |
| 259 int endIndex = TextIterator::rangeLength(endRange, true); | 259 int endIndex = TextIterator::rangeLength(endRange, true); |
| 260 | 260 |
| 261 VisiblePosition paragraphStart(startOfParagraph(visibleStart)); | 261 VisiblePosition paragraphStart(startOfParagraph(visibleStart)); |
| 262 VisiblePosition nextParagraphStart(endOfParagraph(paragraphStart).next()); | 262 VisiblePosition nextParagraphStart(endOfParagraph(paragraphStart).next()); |
| 263 VisiblePosition beyondEnd(endOfParagraph(visibleEnd).next()); | 263 VisiblePosition beyondEnd(endOfParagraph(visibleEnd).next()); |
| 264 while (paragraphStart.isNotNull() && paragraphStart != beyondEnd) { | 264 while (paragraphStart.isNotNull() && paragraphStart != beyondEnd) { |
| 265 HandleScope scope; | 265 HandleScope scope; |
| 266 StyleChange styleChange(style, paragraphStart.deepEquivalent()); | 266 StyleChange styleChange(style, paragraphStart.deepEquivalent()); |
| 267 if (styleChange.cssStyle().length() || m_removeOnly) { | 267 if (styleChange.cssStyle().length() || m_removeOnly) { |
| 268 Handle<Node> block = enclosingBlock(paragraphStart.deepEquivalent().
deprecatedNode().handle().raw()); | 268 Handle<Node> block = enclosingBlock(paragraphStart.deepEquivalent().
deprecatedNode()); |
| 269 if (!m_removeOnly) { | 269 if (!m_removeOnly) { |
| 270 Handle<Node> newBlock = moveParagraphContentsToNewBlockIfNecessa
ry(paragraphStart.deepEquivalent()); | 270 Handle<Node> newBlock = moveParagraphContentsToNewBlockIfNecessa
ry(paragraphStart.deepEquivalent()); |
| 271 if (newBlock) | 271 if (newBlock) |
| 272 block = newBlock; | 272 block = newBlock; |
| 273 } | 273 } |
| 274 ASSERT(!block || block->isHTMLElement()); | 274 ASSERT(!block || block->isHTMLElement()); |
| 275 if (block && block->isHTMLElement()) { | 275 if (block && block->isHTMLElement()) { |
| 276 removeCSSStyle(style, toHTMLElement(block)); | 276 removeCSSStyle(style, toHTMLElement(block)); |
| 277 if (!m_removeOnly) | 277 if (!m_removeOnly) |
| 278 addBlockStyle(styleChange, toHTMLElement(block)); | 278 addBlockStyle(styleChange, toHTMLElement(block)); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 // If the end node is before the start node (can only happen if the end node
is | 350 // If the end node is before the start node (can only happen if the end node
is |
| 351 // an ancestor of the start node), we gather nodes up to the next sibling of
the end node | 351 // an ancestor of the start node), we gather nodes up to the next sibling of
the end node |
| 352 Handle<Node> beyondEnd; | 352 Handle<Node> beyondEnd; |
| 353 if (start.deprecatedNode()->isDescendantOf(end.deprecatedNode().handle().raw
())) | 353 if (start.deprecatedNode()->isDescendantOf(end.deprecatedNode().handle().raw
())) |
| 354 beyondEnd = NodeTraversal::nextSkippingChildren(end.deprecatedNode()); | 354 beyondEnd = NodeTraversal::nextSkippingChildren(end.deprecatedNode()); |
| 355 else | 355 else |
| 356 beyondEnd = NodeTraversal::next(end.deprecatedNode()); | 356 beyondEnd = NodeTraversal::next(end.deprecatedNode()); |
| 357 | 357 |
| 358 start = start.upstream(); // Move upstream to ensure we do not add redundant
spans. | 358 start = start.upstream(); // Move upstream to ensure we do not add redundant
spans. |
| 359 Handle<Node> startNode = start.deprecatedNode(); | 359 Handle<Node> startNode = start.deprecatedNode(); |
| 360 if (startNode->isTextNode() && start.deprecatedEditingOffset() >= caretMaxOf
fset(startNode.raw())) // Move out of text node if range does not include its ch
aracters. | 360 if (startNode->isTextNode() && start.deprecatedEditingOffset() >= caretMaxOf
fset(startNode)) // Move out of text node if range does not include its characte
rs. |
| 361 startNode = NodeTraversal::next(startNode); | 361 startNode = NodeTraversal::next(startNode); |
| 362 | 362 |
| 363 // Store away font size before making any changes to the document. | 363 // Store away font size before making any changes to the document. |
| 364 // This ensures that changes to one node won't effect another. | 364 // This ensures that changes to one node won't effect another. |
| 365 CollectionRoot<HashMap<Member<Node>, float> > startingFontSizes; | 365 CollectionRoot<HashMap<Member<Node>, float> > startingFontSizes; |
| 366 for (Handle<Node> node = startNode; node != beyondEnd; node = NodeTraversal:
:next(node)) { | 366 for (Handle<Node> node = startNode; node != beyondEnd; node = NodeTraversal:
:next(node)) { |
| 367 HandleScope scope; | 367 HandleScope scope; |
| 368 startingFontSizes->set(node, computedFontSize(node)); | 368 startingFontSizes->set(node, computedFontSize(node)); |
| 369 } | 369 } |
| 370 | 370 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 if (isSpanWithoutAttributesOrUnstyledStyleSpan(node)) | 445 if (isSpanWithoutAttributesOrUnstyledStyleSpan(node)) |
| 446 removeNodePreservingChildren(node); | 446 removeNodePreservingChildren(node); |
| 447 node = next; | 447 node = next; |
| 448 } | 448 } |
| 449 } | 449 } |
| 450 | 450 |
| 451 Result<HTMLElement> ApplyStyleCommand::splitAncestorsWithUnicodeBidi(const Handl
e<Node>& node, bool before, WritingDirection allowedDirection) | 451 Result<HTMLElement> ApplyStyleCommand::splitAncestorsWithUnicodeBidi(const Handl
e<Node>& node, bool before, WritingDirection allowedDirection) |
| 452 { | 452 { |
| 453 // We are allowed to leave the highest ancestor with unicode-bidi unsplit if
it is unicode-bidi: embed and direction: allowedDirection. | 453 // We are allowed to leave the highest ancestor with unicode-bidi unsplit if
it is unicode-bidi: embed and direction: allowedDirection. |
| 454 // In that case, we return the unsplit ancestor. Otherwise, we return 0. | 454 // In that case, we return the unsplit ancestor. Otherwise, we return 0. |
| 455 Handle<Node> block = enclosingBlock(node.raw()); | 455 Handle<Node> block = enclosingBlock(node); |
| 456 if (!block) | 456 if (!block) |
| 457 return nullptr; | 457 return nullptr; |
| 458 | 458 |
| 459 Handle<Node> highestAncestorWithUnicodeBidi; | 459 Handle<Node> highestAncestorWithUnicodeBidi; |
| 460 Handle<Node> nextHighestAncestorWithUnicodeBidi; | 460 Handle<Node> nextHighestAncestorWithUnicodeBidi; |
| 461 int highestAncestorUnicodeBidi = 0; | 461 int highestAncestorUnicodeBidi = 0; |
| 462 for (Handle<Node> n = node->parentNode(); n != block; n = n->parentNode()) { | 462 for (Handle<Node> n = node->parentNode(); n != block; n = n->parentNode()) { |
| 463 HandleScope scope; | 463 HandleScope scope; |
| 464 Handle<CSSStyleDeclaration> styleDeclaration = CSSComputedStyleDeclarati
on::create(n); | 464 Handle<CSSStyleDeclaration> styleDeclaration = CSSComputedStyleDeclarati
on::create(n); |
| 465 int unicodeBidi = getIdentifierValue(styleDeclaration, CSSPropertyUnicod
eBidi); | 465 int unicodeBidi = getIdentifierValue(styleDeclaration, CSSPropertyUnicod
eBidi); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 splitElement(parent, before ? currentNode : currentNode->nextSibling
().handle()); | 497 splitElement(parent, before ? currentNode : currentNode->nextSibling
().handle()); |
| 498 if (parent == highestAncestorWithUnicodeBidi) | 498 if (parent == highestAncestorWithUnicodeBidi) |
| 499 break; | 499 break; |
| 500 currentNode = parent; | 500 currentNode = parent; |
| 501 } | 501 } |
| 502 return unsplitAncestor; | 502 return unsplitAncestor; |
| 503 } | 503 } |
| 504 | 504 |
| 505 void ApplyStyleCommand::removeEmbeddingUpToEnclosingBlock(const Handle<Node>& no
de, const Handle<Node>& unsplitAncestor) | 505 void ApplyStyleCommand::removeEmbeddingUpToEnclosingBlock(const Handle<Node>& no
de, const Handle<Node>& unsplitAncestor) |
| 506 { | 506 { |
| 507 Handle<Node> block = enclosingBlock(node.raw()); | 507 Handle<Node> block = enclosingBlock(node); |
| 508 if (!block) | 508 if (!block) |
| 509 return; | 509 return; |
| 510 | 510 |
| 511 Handle<Node> parent; | 511 Handle<Node> parent; |
| 512 for (Handle<Node> n = node->parentNode(); n != block && n != unsplitAncestor
; n = parent) { | 512 for (Handle<Node> n = node->parentNode(); n != block && n != unsplitAncestor
; n = parent) { |
| 513 HandleScope scope; | 513 HandleScope scope; |
| 514 parent = n->parentNode(); | 514 parent = n->parentNode(); |
| 515 if (!n->isStyledElement()) | 515 if (!n->isStyledElement()) |
| 516 continue; | 516 continue; |
| 517 | 517 |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 652 } | 652 } |
| 653 | 653 |
| 654 // update document layout once before running the rest of the function | 654 // update document layout once before running the rest of the function |
| 655 // so that we avoid the expense of updating before each and every call | 655 // so that we avoid the expense of updating before each and every call |
| 656 // to check a computed style | 656 // to check a computed style |
| 657 document()->updateLayoutIgnorePendingStylesheets(); | 657 document()->updateLayoutIgnorePendingStylesheets(); |
| 658 | 658 |
| 659 RefPtr<EditingStyle> styleToApply = style; | 659 RefPtr<EditingStyle> styleToApply = style; |
| 660 if (hasTextDirection) { | 660 if (hasTextDirection) { |
| 661 // Avoid applying the unicode-bidi and direction properties beneath ance
stors that already have them. | 661 // Avoid applying the unicode-bidi and direction properties beneath ance
stors that already have them. |
| 662 Handle<Node> embeddingStartNode = highestEmbeddingAncestor(start.depreca
tedNode(), enclosingBlock(start.deprecatedNode().handle().raw())); | 662 Handle<Node> embeddingStartNode = highestEmbeddingAncestor(start.depreca
tedNode(), enclosingBlock(start.deprecatedNode())); |
| 663 Handle<Node> embeddingEndNode = highestEmbeddingAncestor(end.deprecatedN
ode(), enclosingBlock(end.deprecatedNode().handle().raw())); | 663 Handle<Node> embeddingEndNode = highestEmbeddingAncestor(end.deprecatedN
ode(), enclosingBlock(end.deprecatedNode())); |
| 664 | 664 |
| 665 if (embeddingStartNode || embeddingEndNode) { | 665 if (embeddingStartNode || embeddingEndNode) { |
| 666 Position embeddingApplyStart = embeddingStartNode ? positionInParent
AfterNode(embeddingStartNode) : start; | 666 Position embeddingApplyStart = embeddingStartNode ? positionInParent
AfterNode(embeddingStartNode) : start; |
| 667 Position embeddingApplyEnd = embeddingEndNode ? positionInParentBefo
reNode(embeddingEndNode) : end; | 667 Position embeddingApplyEnd = embeddingEndNode ? positionInParentBefo
reNode(embeddingEndNode) : end; |
| 668 ASSERT(embeddingApplyStart.isNotNull() && embeddingApplyEnd.isNotNul
l()); | 668 ASSERT(embeddingApplyStart.isNotNull() && embeddingApplyEnd.isNotNul
l()); |
| 669 | 669 |
| 670 if (!embeddingStyle) { | 670 if (!embeddingStyle) { |
| 671 styleWithoutEmbedding = style->copy(); | 671 styleWithoutEmbedding = style->copy(); |
| 672 embeddingStyle = styleWithoutEmbedding->extractAndRemoveTextDire
ction(); | 672 embeddingStyle = styleWithoutEmbedding->extractAndRemoveTextDire
ction(); |
| 673 } | 673 } |
| 674 fixRangeAndApplyInlineStyle(embeddingStyle.get(), embeddingApplyStar
t, embeddingApplyEnd); | 674 fixRangeAndApplyInlineStyle(embeddingStyle.get(), embeddingApplyStar
t, embeddingApplyEnd); |
| 675 | 675 |
| 676 styleToApply = styleWithoutEmbedding; | 676 styleToApply = styleWithoutEmbedding; |
| 677 } | 677 } |
| 678 } | 678 } |
| 679 | 679 |
| 680 fixRangeAndApplyInlineStyle(styleToApply.get(), start, end); | 680 fixRangeAndApplyInlineStyle(styleToApply.get(), start, end); |
| 681 | 681 |
| 682 // Remove dummy style spans created by splitting text elements. | 682 // Remove dummy style spans created by splitting text elements. |
| 683 cleanupUnstyledAppleStyleSpans(startDummySpanAncestor); | 683 cleanupUnstyledAppleStyleSpans(startDummySpanAncestor); |
| 684 if (endDummySpanAncestor != startDummySpanAncestor) | 684 if (endDummySpanAncestor != startDummySpanAncestor) |
| 685 cleanupUnstyledAppleStyleSpans(endDummySpanAncestor); | 685 cleanupUnstyledAppleStyleSpans(endDummySpanAncestor); |
| 686 } | 686 } |
| 687 | 687 |
| 688 void ApplyStyleCommand::fixRangeAndApplyInlineStyle(EditingStyle* style, const P
osition& start, const Position& end) | 688 void ApplyStyleCommand::fixRangeAndApplyInlineStyle(EditingStyle* style, const P
osition& start, const Position& end) |
| 689 { | 689 { |
| 690 Handle<Node> startNode = start.deprecatedNode(); | 690 Handle<Node> startNode = start.deprecatedNode(); |
| 691 | 691 |
| 692 if (start.deprecatedEditingOffset() >= caretMaxOffset(start.deprecatedNode()
.handle().raw())) { | 692 if (start.deprecatedEditingOffset() >= caretMaxOffset(start.deprecatedNode()
)) { |
| 693 startNode = NodeTraversal::next(startNode); | 693 startNode = NodeTraversal::next(startNode); |
| 694 if (!startNode || comparePositions(end, firstPositionInOrBeforeNode(star
tNode.raw())) < 0) | 694 if (!startNode || comparePositions(end, firstPositionInOrBeforeNode(star
tNode)) < 0) |
| 695 return; | 695 return; |
| 696 } | 696 } |
| 697 | 697 |
| 698 Handle<Node> pastEndNode = end.deprecatedNode(); | 698 Handle<Node> pastEndNode = end.deprecatedNode(); |
| 699 if (end.deprecatedEditingOffset() >= caretMaxOffset(end.deprecatedNode().han
dle().raw())) | 699 if (end.deprecatedEditingOffset() >= caretMaxOffset(end.deprecatedNode())) |
| 700 pastEndNode = NodeTraversal::nextSkippingChildren(end.deprecatedNode()); | 700 pastEndNode = NodeTraversal::nextSkippingChildren(end.deprecatedNode()); |
| 701 | 701 |
| 702 // FIXME: Callers should perform this operation on a Range that includes the
br | 702 // FIXME: Callers should perform this operation on a Range that includes the
br |
| 703 // if they want style applied to the empty line. | 703 // if they want style applied to the empty line. |
| 704 if (start == end && start.deprecatedNode()->hasTagName(brTag)) | 704 if (start == end && start.deprecatedNode()->hasTagName(brTag)) |
| 705 pastEndNode = NodeTraversal::next(start.deprecatedNode()); | 705 pastEndNode = NodeTraversal::next(start.deprecatedNode()); |
| 706 | 706 |
| 707 // Start from the highest fully selected ancestor so that we can modify the
fully selected node. | 707 // Start from the highest fully selected ancestor so that we can modify the
fully selected node. |
| 708 // e.g. When applying font-size: large on <font color="blue">hello</font>, w
e need to include the font element in our run | 708 // e.g. When applying font-size: large on <font color="blue">hello</font>, w
e need to include the font element in our run |
| 709 // to generate <font color="blue" size="4">hello</font> instead of <font col
or="blue"><font size="4">hello</font></font> | 709 // to generate <font color="blue" size="4">hello</font> instead of <font col
or="blue"><font size="4">hello</font></font> |
| 710 Handle<Range> range = Range::create(startNode->document(), start, end); | 710 Handle<Range> range = Range::create(startNode->document(), start, end); |
| 711 Handle<Element> editableRoot = startNode->rootEditableElement(); | 711 Handle<Element> editableRoot = startNode->rootEditableElement(); |
| 712 if (startNode != editableRoot) { | 712 if (startNode != editableRoot) { |
| 713 while (1) { | 713 while (1) { |
| 714 HandleScope scope; | 714 HandleScope scope; |
| 715 if (!editableRoot || startNode->parentNode() == editableRoot || !isN
odeVisiblyContainedWithin(startNode->parentNode().handle().raw(), range)) | 715 if (!editableRoot || startNode->parentNode() == editableRoot || !isN
odeVisiblyContainedWithin(startNode->parentNode(), range)) |
| 716 break; | 716 break; |
| 717 startNode = startNode->parentNode(); | 717 startNode = startNode->parentNode(); |
| 718 } | 718 } |
| 719 } | 719 } |
| 720 | 720 |
| 721 applyInlineStyleToNodeRange(style, startNode, pastEndNode); | 721 applyInlineStyleToNodeRange(style, startNode, pastEndNode); |
| 722 } | 722 } |
| 723 | 723 |
| 724 static bool containsNonEditableRegion(const Handle<Node>& node) | 724 static bool containsNonEditableRegion(const Handle<Node>& node) |
| 725 { | 725 { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 782 break; | 782 break; |
| 783 // Add to this element's inline style and skip over its contents. | 783 // Add to this element's inline style and skip over its contents. |
| 784 Handle<HTMLElement> element = toHTMLElement(node); | 784 Handle<HTMLElement> element = toHTMLElement(node); |
| 785 Handle<StylePropertySet> inlineStyle = copyStyleOrCreateEmpty(elemen
t->inlineStyle()); | 785 Handle<StylePropertySet> inlineStyle = copyStyleOrCreateEmpty(elemen
t->inlineStyle()); |
| 786 inlineStyle->mergeAndOverrideOnConflict(style->style()); | 786 inlineStyle->mergeAndOverrideOnConflict(style->style()); |
| 787 setNodeAttribute(element, styleAttr, inlineStyle->asText()); | 787 setNodeAttribute(element, styleAttr, inlineStyle->asText()); |
| 788 next = NodeTraversal::nextSkippingChildren(node); | 788 next = NodeTraversal::nextSkippingChildren(node); |
| 789 continue; | 789 continue; |
| 790 } | 790 } |
| 791 | 791 |
| 792 if (isBlock(node.raw())) | 792 if (isBlock(node)) |
| 793 continue; | 793 continue; |
| 794 | 794 |
| 795 if (node->childNodeCount()) { | 795 if (node->childNodeCount()) { |
| 796 if (node->contains(pastEndNode) || containsNonEditableRegion(node) |
| !node->parentNode()->rendererIsEditable()) | 796 if (node->contains(pastEndNode) || containsNonEditableRegion(node) |
| !node->parentNode()->rendererIsEditable()) |
| 797 continue; | 797 continue; |
| 798 if (editingIgnoresContent(node.raw())) { | 798 if (editingIgnoresContent(node)) { |
| 799 next = NodeTraversal::nextSkippingChildren(node); | 799 next = NodeTraversal::nextSkippingChildren(node); |
| 800 continue; | 800 continue; |
| 801 } | 801 } |
| 802 } | 802 } |
| 803 | 803 |
| 804 Handle<Node> runStart = node; | 804 Handle<Node> runStart = node; |
| 805 Handle<Node> runEnd = node; | 805 Handle<Node> runEnd = node; |
| 806 Handle<Node> sibling = node->nextSibling(); | 806 Handle<Node> sibling = node->nextSibling(); |
| 807 while (1) { | 807 while (1) { |
| 808 HandleScope scope; | 808 HandleScope scope; |
| 809 if (!sibling || sibling == pastEndNode || sibling->contains(pastEndN
ode) | 809 if (!sibling || sibling == pastEndNode || sibling->contains(pastEndN
ode) |
| 810 || (isBlock(sibling.raw()) && !sibling->hasTagName(brTag)) | 810 || (isBlock(sibling) && !sibling->hasTagName(brTag)) |
| 811 || containsNonEditableRegion(sibling)) | 811 || containsNonEditableRegion(sibling)) |
| 812 break; | 812 break; |
| 813 runEnd = sibling; | 813 runEnd = sibling; |
| 814 sibling = runEnd->nextSibling(); | 814 sibling = runEnd->nextSibling(); |
| 815 } | 815 } |
| 816 next = NodeTraversal::nextSkippingChildren(runEnd); | 816 next = NodeTraversal::nextSkippingChildren(runEnd); |
| 817 | 817 |
| 818 Handle<Node> pastEndNode = NodeTraversal::nextSkippingChildren(runEnd); | 818 Handle<Node> pastEndNode = NodeTraversal::nextSkippingChildren(runEnd); |
| 819 if (!shouldApplyInlineStyleToRun(style, runStart, pastEndNode)) | 819 if (!shouldApplyInlineStyleToRun(style, runStart, pastEndNode)) |
| 820 continue; | 820 continue; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 867 } | 867 } |
| 868 return false; | 868 return false; |
| 869 } | 869 } |
| 870 | 870 |
| 871 void ApplyStyleCommand::removeConflictingInlineStyleFromRun(EditingStyle* style,
Persistent<Node>& runStart, Persistent<Node>& runEnd, const Handle<Node>& pastE
ndNode) | 871 void ApplyStyleCommand::removeConflictingInlineStyleFromRun(EditingStyle* style,
Persistent<Node>& runStart, Persistent<Node>& runEnd, const Handle<Node>& pastE
ndNode) |
| 872 { | 872 { |
| 873 ASSERT(runStart && runEnd); | 873 ASSERT(runStart && runEnd); |
| 874 Handle<Node> next = runStart; | 874 Handle<Node> next = runStart; |
| 875 for (Handle<Node> node = next; node && node->inDocument() && node != pastEnd
Node; node = next) { | 875 for (Handle<Node> node = next; node && node->inDocument() && node != pastEnd
Node; node = next) { |
| 876 HandleScope scope; | 876 HandleScope scope; |
| 877 if (editingIgnoresContent(node.raw())) { | 877 if (editingIgnoresContent(node)) { |
| 878 ASSERT(!node->contains(pastEndNode)); | 878 ASSERT(!node->contains(pastEndNode)); |
| 879 next = NodeTraversal::nextSkippingChildren(node); | 879 next = NodeTraversal::nextSkippingChildren(node); |
| 880 } else | 880 } else |
| 881 next = NodeTraversal::next(node); | 881 next = NodeTraversal::next(node); |
| 882 if (!node->isHTMLElement()) | 882 if (!node->isHTMLElement()) |
| 883 continue; | 883 continue; |
| 884 | 884 |
| 885 Handle<Node> previousSibling = node->previousSibling(); | 885 Handle<Node> previousSibling = node->previousSibling(); |
| 886 Handle<Node> nextSibling = node->nextSibling(); | 886 Handle<Node> nextSibling = node->nextSibling(); |
| 887 Handle<ContainerNode> parent = node->parentNode(); | 887 Handle<ContainerNode> parent = node->parentNode(); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 991 | 991 |
| 992 return true; | 992 return true; |
| 993 } | 993 } |
| 994 | 994 |
| 995 Result<HTMLElement> ApplyStyleCommand::highestAncestorWithConflictingInlineStyle
(EditingStyle* style, const Handle<Node>& node) | 995 Result<HTMLElement> ApplyStyleCommand::highestAncestorWithConflictingInlineStyle
(EditingStyle* style, const Handle<Node>& node) |
| 996 { | 996 { |
| 997 if (!node) | 997 if (!node) |
| 998 return nullptr; | 998 return nullptr; |
| 999 | 999 |
| 1000 Handle<HTMLElement> result; | 1000 Handle<HTMLElement> result; |
| 1001 Handle<Node> unsplittableElement = unsplittableElementForPosition(firstPosit
ionInOrBeforeNode(node.raw())); | 1001 Handle<Node> unsplittableElement = unsplittableElementForPosition(firstPosit
ionInOrBeforeNode(node)); |
| 1002 | 1002 |
| 1003 for (Handle<Node> n = node; n; n = n->parentNode()) { | 1003 for (Handle<Node> n = node; n; n = n->parentNode()) { |
| 1004 HandleScope scope; | 1004 HandleScope scope; |
| 1005 if (n->isHTMLElement() && shouldRemoveInlineStyleFromElement(style, toHT
MLElement(n))) | 1005 if (n->isHTMLElement() && shouldRemoveInlineStyleFromElement(style, toHT
MLElement(n))) |
| 1006 result = toHTMLElement(n); | 1006 result = toHTMLElement(n); |
| 1007 // Should stop at the editable root (cannot cross editing boundary) and | 1007 // Should stop at the editable root (cannot cross editing boundary) and |
| 1008 // also stop at the unsplittable element to be consistent with other UAs | 1008 // also stop at the unsplittable element to be consistent with other UAs |
| 1009 if (n == unsplittableElement) | 1009 if (n == unsplittableElement) |
| 1010 break; | 1010 break; |
| 1011 } | 1011 } |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1129 // are removed from the document during the work of this function. | 1129 // are removed from the document during the work of this function. |
| 1130 // If pushDownInlineStyleAroundNode has pruned start.deprecatedNode() or end
.deprecatedNode(), | 1130 // If pushDownInlineStyleAroundNode has pruned start.deprecatedNode() or end
.deprecatedNode(), |
| 1131 // use pushDownStart or pushDownEnd instead, which pushDownInlineStyleAround
Node won't prune. | 1131 // use pushDownStart or pushDownEnd instead, which pushDownInlineStyleAround
Node won't prune. |
| 1132 Position s = start.isNull() || start.isOrphan() ? pushDownStart : start; | 1132 Position s = start.isNull() || start.isOrphan() ? pushDownStart : start; |
| 1133 Position e = end.isNull() || end.isOrphan() ? pushDownEnd : end; | 1133 Position e = end.isNull() || end.isOrphan() ? pushDownEnd : end; |
| 1134 | 1134 |
| 1135 Handle<Node> node = start.deprecatedNode(); | 1135 Handle<Node> node = start.deprecatedNode(); |
| 1136 while (node) { | 1136 while (node) { |
| 1137 HandleScope scope; | 1137 HandleScope scope; |
| 1138 Handle<Node> next; | 1138 Handle<Node> next; |
| 1139 if (editingIgnoresContent(node.raw())) { | 1139 if (editingIgnoresContent(node)) { |
| 1140 ASSERT(node == end.deprecatedNode() || !node->contains(end.deprecate
dNode())); | 1140 ASSERT(node == end.deprecatedNode() || !node->contains(end.deprecate
dNode())); |
| 1141 next = NodeTraversal::nextSkippingChildren(node); | 1141 next = NodeTraversal::nextSkippingChildren(node); |
| 1142 } else | 1142 } else |
| 1143 next = NodeTraversal::next(node); | 1143 next = NodeTraversal::next(node); |
| 1144 if (node->isHTMLElement() && nodeFullySelected(node, start, end)) { | 1144 if (node->isHTMLElement() && nodeFullySelected(node, start, end)) { |
| 1145 Handle<HTMLElement> elem = toHTMLElement(node); | 1145 Handle<HTMLElement> elem = toHTMLElement(node); |
| 1146 Handle<Node> prevNode = NodeTraversal::previousPostOrder(elem); | 1146 Handle<Node> prevNode = NodeTraversal::previousPostOrder(elem); |
| 1147 Handle<Node> nextNode = NodeTraversal::next(elem); | 1147 Handle<Node> nextNode = NodeTraversal::next(elem); |
| 1148 RefPtr<EditingStyle> styleToPushDown; | 1148 RefPtr<EditingStyle> styleToPushDown; |
| 1149 Handle<Node> childNode; | 1149 Handle<Node> childNode; |
| 1150 if (isStyledInlineElementToRemove(elem)) { | 1150 if (isStyledInlineElementToRemove(elem)) { |
| 1151 styleToPushDown = EditingStyle::create(); | 1151 styleToPushDown = EditingStyle::create(); |
| 1152 childNode = elem->firstChild(); | 1152 childNode = elem->firstChild(); |
| 1153 } | 1153 } |
| 1154 | 1154 |
| 1155 removeInlineStyleFromElement(style, elem, RemoveIfNeeded, styleToPus
hDown.get()); | 1155 removeInlineStyleFromElement(style, elem, RemoveIfNeeded, styleToPus
hDown.get()); |
| 1156 if (!elem->inDocument()) { | 1156 if (!elem->inDocument()) { |
| 1157 if (s.deprecatedNode() == elem) { | 1157 if (s.deprecatedNode() == elem) { |
| 1158 // Since elem must have been fully selected, and it is at th
e start | 1158 // Since elem must have been fully selected, and it is at th
e start |
| 1159 // of the selection, it is clear we can set the new s offset
to 0. | 1159 // of the selection, it is clear we can set the new s offset
to 0. |
| 1160 ASSERT(s.anchorType() == Position::PositionIsBeforeAnchor ||
s.offsetInContainerNode() <= 0); | 1160 ASSERT(s.anchorType() == Position::PositionIsBeforeAnchor ||
s.offsetInContainerNode() <= 0); |
| 1161 s = firstPositionInOrBeforeNode(nextNode.raw()); | 1161 s = firstPositionInOrBeforeNode(nextNode); |
| 1162 } | 1162 } |
| 1163 if (e.deprecatedNode() == elem) { | 1163 if (e.deprecatedNode() == elem) { |
| 1164 // Since elem must have been fully selected, and it is at th
e end | 1164 // Since elem must have been fully selected, and it is at th
e end |
| 1165 // of the selection, it is clear we can set the new e offset
to | 1165 // of the selection, it is clear we can set the new e offset
to |
| 1166 // the max range offset of prevNode. | 1166 // the max range offset of prevNode. |
| 1167 ASSERT(s.anchorType() == Position::PositionIsAfterAnchor ||
!offsetIsBeforeLastNodeOffset(s.offsetInContainerNode(), s.containerNode())); | 1167 ASSERT(s.anchorType() == Position::PositionIsAfterAnchor ||
!offsetIsBeforeLastNodeOffset(s.offsetInContainerNode(), s.containerNode())); |
| 1168 e = lastPositionInOrAfterNode(prevNode.raw()); | 1168 e = lastPositionInOrAfterNode(prevNode); |
| 1169 } | 1169 } |
| 1170 } | 1170 } |
| 1171 | 1171 |
| 1172 if (styleToPushDown) { | 1172 if (styleToPushDown) { |
| 1173 for (; childNode; childNode = childNode->nextSibling()) | 1173 for (; childNode; childNode = childNode->nextSibling()) |
| 1174 applyInlineStyleToPushDown(childNode, styleToPushDown.get())
; | 1174 applyInlineStyleToPushDown(childNode, styleToPushDown.get())
; |
| 1175 } | 1175 } |
| 1176 } | 1176 } |
| 1177 if (node == end.deprecatedNode()) | 1177 if (node == end.deprecatedNode()) |
| 1178 break; | 1178 break; |
| 1179 node = next; | 1179 node = next; |
| 1180 } | 1180 } |
| 1181 | 1181 |
| 1182 updateStartEnd(s, e); | 1182 updateStartEnd(s, e); |
| 1183 } | 1183 } |
| 1184 | 1184 |
| 1185 bool ApplyStyleCommand::nodeFullySelected(const Handle<Node>& node, const Positi
on &start, const Position &end) const | 1185 bool ApplyStyleCommand::nodeFullySelected(const Handle<Node>& node, const Positi
on &start, const Position &end) const |
| 1186 { | 1186 { |
| 1187 ASSERT(node); | 1187 ASSERT(node); |
| 1188 ASSERT(node->isElementNode()); | 1188 ASSERT(node->isElementNode()); |
| 1189 | 1189 |
| 1190 // The tree may have changed and Position::upstream() relies on an up-to-dat
e layout. | 1190 // The tree may have changed and Position::upstream() relies on an up-to-dat
e layout. |
| 1191 node->document()->updateLayoutIgnorePendingStylesheets(); | 1191 node->document()->updateLayoutIgnorePendingStylesheets(); |
| 1192 | 1192 |
| 1193 return comparePositions(firstPositionInOrBeforeNode(node.raw()), start) >= 0 | 1193 return comparePositions(firstPositionInOrBeforeNode(node), start) >= 0 |
| 1194 && comparePositions(lastPositionInOrAfterNode(node.raw()).upstream(), en
d) <= 0; | 1194 && comparePositions(lastPositionInOrAfterNode(node).upstream(), end) <=
0; |
| 1195 } | 1195 } |
| 1196 | 1196 |
| 1197 bool ApplyStyleCommand::nodeFullyUnselected(const Handle<Node>& node, const Posi
tion &start, const Position &end) const | 1197 bool ApplyStyleCommand::nodeFullyUnselected(const Handle<Node>& node, const Posi
tion &start, const Position &end) const |
| 1198 { | 1198 { |
| 1199 ASSERT(node); | 1199 ASSERT(node); |
| 1200 ASSERT(node->isElementNode()); | 1200 ASSERT(node->isElementNode()); |
| 1201 | 1201 |
| 1202 bool isFullyBeforeStart = comparePositions(lastPositionInOrAfterNode(node.ra
w()).upstream(), start) < 0; | 1202 bool isFullyBeforeStart = comparePositions(lastPositionInOrAfterNode(node).u
pstream(), start) < 0; |
| 1203 bool isFullyAfterEnd = comparePositions(firstPositionInOrBeforeNode(node.raw
()), end) > 0; | 1203 bool isFullyAfterEnd = comparePositions(firstPositionInOrBeforeNode(node), e
nd) > 0; |
| 1204 | 1204 |
| 1205 return isFullyBeforeStart || isFullyAfterEnd; | 1205 return isFullyBeforeStart || isFullyAfterEnd; |
| 1206 } | 1206 } |
| 1207 | 1207 |
| 1208 void ApplyStyleCommand::splitTextAtStart(const Position& start, const Position&
end) | 1208 void ApplyStyleCommand::splitTextAtStart(const Position& start, const Position&
end) |
| 1209 { | 1209 { |
| 1210 ASSERT(start.containerNode()->isTextNode()); | 1210 ASSERT(start.containerNode()->isTextNode()); |
| 1211 | 1211 |
| 1212 Position newEnd; | 1212 Position newEnd; |
| 1213 if (end.anchorType() == Position::PositionIsOffsetInAnchor && start.containe
rNode() == end.containerNode()) | 1213 if (end.anchorType() == Position::PositionIsOffsetInAnchor && start.containe
rNode() == end.containerNode()) |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1271 bool ApplyStyleCommand::shouldSplitTextElement(const Handle<Element>& element, E
ditingStyle* style) | 1271 bool ApplyStyleCommand::shouldSplitTextElement(const Handle<Element>& element, E
ditingStyle* style) |
| 1272 { | 1272 { |
| 1273 if (!element || !element->isHTMLElement()) | 1273 if (!element || !element->isHTMLElement()) |
| 1274 return false; | 1274 return false; |
| 1275 | 1275 |
| 1276 return shouldRemoveInlineStyleFromElement(style, toHTMLElement(element)); | 1276 return shouldRemoveInlineStyleFromElement(style, toHTMLElement(element)); |
| 1277 } | 1277 } |
| 1278 | 1278 |
| 1279 bool ApplyStyleCommand::isValidCaretPositionInTextNode(const Position& position) | 1279 bool ApplyStyleCommand::isValidCaretPositionInTextNode(const Position& position) |
| 1280 { | 1280 { |
| 1281 Node* node = position.containerNode().handle().raw(); | 1281 Handle<Node> node = position.containerNode(); |
| 1282 if (position.anchorType() != Position::PositionIsOffsetInAnchor || !node->is
TextNode()) | 1282 if (position.anchorType() != Position::PositionIsOffsetInAnchor || !node->is
TextNode()) |
| 1283 return false; | 1283 return false; |
| 1284 int offsetInText = position.offsetInContainerNode(); | 1284 int offsetInText = position.offsetInContainerNode(); |
| 1285 return offsetInText > caretMinOffset(node) && offsetInText < caretMaxOffset(
node); | 1285 return offsetInText > caretMinOffset(node) && offsetInText < caretMaxOffset(
node); |
| 1286 } | 1286 } |
| 1287 | 1287 |
| 1288 bool ApplyStyleCommand::mergeStartWithPreviousIfIdentical(const Position& start,
const Position& end) | 1288 bool ApplyStyleCommand::mergeStartWithPreviousIfIdentical(const Position& start,
const Position& end) |
| 1289 { | 1289 { |
| 1290 Node* startNode = start.containerNode().handle().raw(); | 1290 Handle<Node> startNode = start.containerNode(); |
| 1291 int startOffset = start.computeOffsetInContainerNode(); | 1291 int startOffset = start.computeOffsetInContainerNode(); |
| 1292 if (startOffset) | 1292 if (startOffset) |
| 1293 return false; | 1293 return false; |
| 1294 | 1294 |
| 1295 if (isAtomicNode(startNode)) { | 1295 if (isAtomicNode(startNode)) { |
| 1296 // note: prior siblings could be unrendered elements. it's silly to miss
the | 1296 // note: prior siblings could be unrendered elements. it's silly to miss
the |
| 1297 // merge opportunity just for that. | 1297 // merge opportunity just for that. |
| 1298 if (startNode->previousSibling()) | 1298 if (startNode->previousSibling()) |
| 1299 return false; | 1299 return false; |
| 1300 | 1300 |
| 1301 startNode = startNode->parentNode().handle().raw(); | 1301 startNode = startNode->parentNode(); |
| 1302 startOffset = 0; | 1302 startOffset = 0; |
| 1303 } | 1303 } |
| 1304 | 1304 |
| 1305 if (!startNode->isElementNode()) | 1305 if (!startNode->isElementNode()) |
| 1306 return false; | 1306 return false; |
| 1307 | 1307 |
| 1308 Handle<Node> previousSibling = startNode->previousSibling(); | 1308 Handle<Node> previousSibling = startNode->previousSibling(); |
| 1309 | 1309 |
| 1310 if (previousSibling && areIdenticalElements(startNode, previousSibling.raw()
)) { | 1310 if (previousSibling && areIdenticalElements(startNode, previousSibling)) { |
| 1311 Handle<Element> previousElement = toElement(previousSibling); | 1311 Handle<Element> previousElement = toElement(previousSibling); |
| 1312 Handle<Element> element = adoptRawResult(toElement(startNode)); | 1312 Handle<Element> element = toElement(startNode); |
| 1313 Handle<Node> startChild = element->firstChild(); | 1313 Handle<Node> startChild = element->firstChild(); |
| 1314 ASSERT(startChild); | 1314 ASSERT(startChild); |
| 1315 mergeIdenticalElements(previousElement, element); | 1315 mergeIdenticalElements(previousElement, element); |
| 1316 | 1316 |
| 1317 int startOffsetAdjustment = startChild->nodeIndex(); | 1317 int startOffsetAdjustment = startChild->nodeIndex(); |
| 1318 int endOffsetAdjustment = startNode == end.deprecatedNode() ? startOffse
tAdjustment : 0; | 1318 int endOffsetAdjustment = startNode == end.deprecatedNode() ? startOffse
tAdjustment : 0; |
| 1319 updateStartEnd(Position(adoptRawResult(startNode), startOffsetAdjustment
, Position::PositionIsOffsetInAnchor), | 1319 updateStartEnd(Position(startNode, startOffsetAdjustment, Position::Posi
tionIsOffsetInAnchor), |
| 1320 Position(end.deprecatedNode(), end.deprecatedEditingOffse
t() + endOffsetAdjustment, Position::PositionIsOffsetInAnchor)); | 1320 Position(end.deprecatedNode(), end.deprecatedEditingOffse
t() + endOffsetAdjustment, Position::PositionIsOffsetInAnchor)); |
| 1321 return true; | 1321 return true; |
| 1322 } | 1322 } |
| 1323 | 1323 |
| 1324 return false; | 1324 return false; |
| 1325 } | 1325 } |
| 1326 | 1326 |
| 1327 bool ApplyStyleCommand::mergeEndWithNextIfIdentical(const Position& start, const
Position& end) | 1327 bool ApplyStyleCommand::mergeEndWithNextIfIdentical(const Position& start, const
Position& end) |
| 1328 { | 1328 { |
| 1329 Handle<Node> endNode = end.containerNode(); | 1329 Handle<Node> endNode = end.containerNode(); |
| 1330 int endOffset = end.computeOffsetInContainerNode(); | 1330 int endOffset = end.computeOffsetInContainerNode(); |
| 1331 | 1331 |
| 1332 if (isAtomicNode(endNode.raw())) { | 1332 if (isAtomicNode(endNode)) { |
| 1333 if (offsetIsBeforeLastNodeOffset(endOffset, endNode)) | 1333 if (offsetIsBeforeLastNodeOffset(endOffset, endNode)) |
| 1334 return false; | 1334 return false; |
| 1335 | 1335 |
| 1336 unsigned parentLastOffset = end.deprecatedNode()->parentNode()->childNod
es()->length() - 1; | 1336 unsigned parentLastOffset = end.deprecatedNode()->parentNode()->childNod
es()->length() - 1; |
| 1337 if (end.deprecatedNode()->nextSibling()) | 1337 if (end.deprecatedNode()->nextSibling()) |
| 1338 return false; | 1338 return false; |
| 1339 | 1339 |
| 1340 endNode = end.deprecatedNode()->parentNode(); | 1340 endNode = end.deprecatedNode()->parentNode(); |
| 1341 endOffset = parentLastOffset; | 1341 endOffset = parentLastOffset; |
| 1342 } | 1342 } |
| 1343 | 1343 |
| 1344 if (!endNode->isElementNode() || endNode->hasTagName(brTag)) | 1344 if (!endNode->isElementNode() || endNode->hasTagName(brTag)) |
| 1345 return false; | 1345 return false; |
| 1346 | 1346 |
| 1347 Handle<Node> nextSibling = endNode->nextSibling(); | 1347 Handle<Node> nextSibling = endNode->nextSibling(); |
| 1348 if (nextSibling && areIdenticalElements(endNode.raw(), nextSibling.raw())) { | 1348 if (nextSibling && areIdenticalElements(endNode, nextSibling)) { |
| 1349 Handle<Element> nextElement = toElement(nextSibling); | 1349 Handle<Element> nextElement = toElement(nextSibling); |
| 1350 Handle<Element> element = adoptRawResult(toElement(endNode.raw())); | 1350 Handle<Element> element = toElement(endNode); |
| 1351 Handle<Node> nextChild = nextElement->firstChild(); | 1351 Handle<Node> nextChild = nextElement->firstChild(); |
| 1352 | 1352 |
| 1353 mergeIdenticalElements(element, nextElement); | 1353 mergeIdenticalElements(element, nextElement); |
| 1354 | 1354 |
| 1355 bool shouldUpdateStart = start.containerNode() == endNode; | 1355 bool shouldUpdateStart = start.containerNode() == endNode; |
| 1356 int endOffset = nextChild ? nextChild->nodeIndex() : nextElement->childN
odes()->length(); | 1356 int endOffset = nextChild ? nextChild->nodeIndex() : nextElement->childN
odes()->length(); |
| 1357 updateStartEnd(shouldUpdateStart ? Position(nextElement, start.offsetInC
ontainerNode(), Position::PositionIsOffsetInAnchor) : start, | 1357 updateStartEnd(shouldUpdateStart ? Position(nextElement, start.offsetInC
ontainerNode(), Position::PositionIsOffsetInAnchor) : start, |
| 1358 Position(nextElement, endOffset, Position::PositionIsOffsetInAnchor)
); | 1358 Position(nextElement, endOffset, Position::PositionIsOffsetInAnchor)
); |
| 1359 return true; | 1359 return true; |
| 1360 } | 1360 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1380 appendNode(node, element); | 1380 appendNode(node, element); |
| 1381 } | 1381 } |
| 1382 if (node.raw() == endNode) | 1382 if (node.raw() == endNode) |
| 1383 break; | 1383 break; |
| 1384 node = next; | 1384 node = next; |
| 1385 } | 1385 } |
| 1386 | 1386 |
| 1387 Handle<Node> nextSibling = element->nextSibling(); | 1387 Handle<Node> nextSibling = element->nextSibling(); |
| 1388 Handle<Node> previousSibling = element->previousSibling(); | 1388 Handle<Node> previousSibling = element->previousSibling(); |
| 1389 if (nextSibling && nextSibling->isElementNode() && nextSibling->rendererIsEd
itable() | 1389 if (nextSibling && nextSibling->isElementNode() && nextSibling->rendererIsEd
itable() |
| 1390 && areIdenticalElements(element.raw(), toElement(nextSibling).handle().r
aw())) | 1390 && areIdenticalElements(element, toElement(nextSibling))) |
| 1391 mergeIdenticalElements(element, toElement(nextSibling)); | 1391 mergeIdenticalElements(element, toElement(nextSibling)); |
| 1392 | 1392 |
| 1393 if (previousSibling && previousSibling->isElementNode() && previousSibling->
rendererIsEditable()) { | 1393 if (previousSibling && previousSibling->isElementNode() && previousSibling->
rendererIsEditable()) { |
| 1394 Handle<Node> mergedElement = previousSibling->nextSibling(); | 1394 Handle<Node> mergedElement = previousSibling->nextSibling(); |
| 1395 if (mergedElement->isElementNode() && mergedElement->rendererIsEditable(
) | 1395 if (mergedElement->isElementNode() && mergedElement->rendererIsEditable(
) |
| 1396 && areIdenticalElements(toElement(previousSibling).handle().raw(), t
oElement(mergedElement).handle().raw())) | 1396 && areIdenticalElements(toElement(previousSibling), toElement(merged
Element))) |
| 1397 mergeIdenticalElements(toElement(previousSibling), toElement(mergedE
lement)); | 1397 mergeIdenticalElements(toElement(previousSibling), toElement(mergedE
lement)); |
| 1398 } | 1398 } |
| 1399 | 1399 |
| 1400 // FIXME: We should probably call updateStartEnd if the start or end was in
the node | 1400 // FIXME: We should probably call updateStartEnd if the start or end was in
the node |
| 1401 // range so that the endingSelection() is canonicalized. See the comments a
t the end of | 1401 // range so that the endingSelection() is canonicalized. See the comments a
t the end of |
| 1402 // VisibleSelection::validate(). | 1402 // VisibleSelection::validate(). |
| 1403 } | 1403 } |
| 1404 | 1404 |
| 1405 void ApplyStyleCommand::addBlockStyle(const StyleChange& styleChange, const Hand
le<HTMLElement>& block) | 1405 void ApplyStyleCommand::addBlockStyle(const StyleChange& styleChange, const Hand
le<HTMLElement>& block) |
| 1406 { | 1406 { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1438 Position ApplyStyleCommand::positionToComputeInlineStyleChange(const Handle<Node
>& startNode, Persistent<Node>& dummyElement) | 1438 Position ApplyStyleCommand::positionToComputeInlineStyleChange(const Handle<Node
>& startNode, Persistent<Node>& dummyElement) |
| 1439 { | 1439 { |
| 1440 // It's okay to obtain the style at the startNode because we've removed all
relevant styles from the current run. | 1440 // It's okay to obtain the style at the startNode because we've removed all
relevant styles from the current run. |
| 1441 Position positionForStyleComparison; | 1441 Position positionForStyleComparison; |
| 1442 if (!startNode->isElementNode()) { | 1442 if (!startNode->isElementNode()) { |
| 1443 dummyElement = createStyleSpanElement(document()); | 1443 dummyElement = createStyleSpanElement(document()); |
| 1444 insertNodeAt(dummyElement, positionBeforeNode(startNode)); | 1444 insertNodeAt(dummyElement, positionBeforeNode(startNode)); |
| 1445 return positionBeforeNode(dummyElement); | 1445 return positionBeforeNode(dummyElement); |
| 1446 } | 1446 } |
| 1447 | 1447 |
| 1448 return firstPositionInOrBeforeNode(startNode.raw()); | 1448 return firstPositionInOrBeforeNode(startNode); |
| 1449 } | 1449 } |
| 1450 | 1450 |
| 1451 void ApplyStyleCommand::applyInlineStyleChange(const Handle<Node>& passedStart,
const Handle<Node>& passedEnd, StyleChange& styleChange, EAddStyledElement addSt
yledElement) | 1451 void ApplyStyleCommand::applyInlineStyleChange(const Handle<Node>& passedStart,
const Handle<Node>& passedEnd, StyleChange& styleChange, EAddStyledElement addSt
yledElement) |
| 1452 { | 1452 { |
| 1453 Handle<Node> startNode = passedStart; | 1453 Handle<Node> startNode = passedStart; |
| 1454 Handle<Node> endNode = passedEnd; | 1454 Handle<Node> endNode = passedEnd; |
| 1455 ASSERT(startNode->inDocument()); | 1455 ASSERT(startNode->inDocument()); |
| 1456 ASSERT(endNode->inDocument()); | 1456 ASSERT(endNode->inDocument()); |
| 1457 | 1457 |
| 1458 // Find appropriate font and span elements top-down. | 1458 // Find appropriate font and span elements top-down. |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1579 String textToMove = nextText->data(); | 1579 String textToMove = nextText->data(); |
| 1580 insertTextIntoNode(childText, childText->length(), textToMove); | 1580 insertTextIntoNode(childText, childText->length(), textToMove); |
| 1581 removeNode(next); | 1581 removeNode(next); |
| 1582 // don't move child node pointer. it may want to merge with more text no
des. | 1582 // don't move child node pointer. it may want to merge with more text no
des. |
| 1583 } | 1583 } |
| 1584 | 1584 |
| 1585 updateStartEnd(newStart, newEnd); | 1585 updateStartEnd(newStart, newEnd); |
| 1586 } | 1586 } |
| 1587 | 1587 |
| 1588 } | 1588 } |
| OLD | NEW |