| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All r
ights reserved. | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All r
ights reserved. |
| 3 * Copyright (C) 2005 Alexey Proskuryakov. | 3 * Copyright (C) 2005 Alexey Proskuryakov. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 | 197 |
| 198 TextIterator::~TextIterator() | 198 TextIterator::~TextIterator() |
| 199 { | 199 { |
| 200 } | 200 } |
| 201 | 201 |
| 202 bool TextIterator::isInsideReplacedElement() const | 202 bool TextIterator::isInsideReplacedElement() const |
| 203 { | 203 { |
| 204 if (atEnd() || length() != 1 || !m_node) | 204 if (atEnd() || length() != 1 || !m_node) |
| 205 return false; | 205 return false; |
| 206 | 206 |
| 207 RenderObject* renderer = m_node->renderer(); | 207 LayoutObject* renderer = m_node->renderer(); |
| 208 return renderer && renderer->isReplaced(); | 208 return renderer && renderer->isReplaced(); |
| 209 } | 209 } |
| 210 | 210 |
| 211 void TextIterator::advance() | 211 void TextIterator::advance() |
| 212 { | 212 { |
| 213 if (m_shouldStop) | 213 if (m_shouldStop) |
| 214 return; | 214 return; |
| 215 | 215 |
| 216 ASSERT(!m_node || !m_node->document().needsRenderTreeUpdate()); | 216 ASSERT(!m_node || !m_node->document().needsRenderTreeUpdate()); |
| 217 | 217 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 // if the range ends at offset 0 of an element, represent the | 253 // if the range ends at offset 0 of an element, represent the |
| 254 // position, but not the content, of that element e.g. if the | 254 // position, but not the content, of that element e.g. if the |
| 255 // node is a blockflow element, emit a newline that | 255 // node is a blockflow element, emit a newline that |
| 256 // precedes the element | 256 // precedes the element |
| 257 if (m_node == m_endContainer && !m_endOffset) { | 257 if (m_node == m_endContainer && !m_endOffset) { |
| 258 representNodeOffsetZero(); | 258 representNodeOffsetZero(); |
| 259 m_node = nullptr; | 259 m_node = nullptr; |
| 260 return; | 260 return; |
| 261 } | 261 } |
| 262 | 262 |
| 263 RenderObject* renderer = m_node->renderer(); | 263 LayoutObject* renderer = m_node->renderer(); |
| 264 if (!renderer) { | 264 if (!renderer) { |
| 265 if (m_node->isShadowRoot()) { | 265 if (m_node->isShadowRoot()) { |
| 266 // A shadow root doesn't have a renderer, but we want to visit c
hildren anyway. | 266 // A shadow root doesn't have a renderer, but we want to visit c
hildren anyway. |
| 267 m_iterationProgress = m_iterationProgress < HandledNode ? Handle
dNode : m_iterationProgress; | 267 m_iterationProgress = m_iterationProgress < HandledNode ? Handle
dNode : m_iterationProgress; |
| 268 } else { | 268 } else { |
| 269 m_iterationProgress = HandledChildren; | 269 m_iterationProgress = HandledChildren; |
| 270 } | 270 } |
| 271 } else { | 271 } else { |
| 272 // Enter author shadow roots, from youngest, if any and if necessary
. | 272 // Enter author shadow roots, from youngest, if any and if necessary
. |
| 273 if (m_iterationProgress < HandledAuthorShadowRoots) { | 273 if (m_iterationProgress < HandledAuthorShadowRoots) { |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 { | 617 { |
| 618 m_handledFirstLetter = true; | 618 m_handledFirstLetter = true; |
| 619 | 619 |
| 620 if (!renderer->isRemainingTextRenderer()) | 620 if (!renderer->isRemainingTextRenderer()) |
| 621 return; | 621 return; |
| 622 | 622 |
| 623 FirstLetterPseudoElement* firstLetterElement = renderer->firstLetterPseudoEl
ement(); | 623 FirstLetterPseudoElement* firstLetterElement = renderer->firstLetterPseudoEl
ement(); |
| 624 if (!firstLetterElement) | 624 if (!firstLetterElement) |
| 625 return; | 625 return; |
| 626 | 626 |
| 627 RenderObject* pseudoRenderer = firstLetterElement->renderer(); | 627 LayoutObject* pseudoRenderer = firstLetterElement->renderer(); |
| 628 if (pseudoRenderer->style()->visibility() != VISIBLE && !m_ignoresStyleVisib
ility) | 628 if (pseudoRenderer->style()->visibility() != VISIBLE && !m_ignoresStyleVisib
ility) |
| 629 return; | 629 return; |
| 630 | 630 |
| 631 RenderObject* firstLetter = pseudoRenderer->slowFirstChild(); | 631 LayoutObject* firstLetter = pseudoRenderer->slowFirstChild(); |
| 632 ASSERT(firstLetter); | 632 ASSERT(firstLetter); |
| 633 | 633 |
| 634 m_remainingTextBox = m_textBox; | 634 m_remainingTextBox = m_textBox; |
| 635 m_textBox = toRenderText(firstLetter)->firstTextBox(); | 635 m_textBox = toRenderText(firstLetter)->firstTextBox(); |
| 636 m_sortedTextBoxes.clear(); | 636 m_sortedTextBoxes.clear(); |
| 637 m_firstLetterText = toRenderText(firstLetter); | 637 m_firstLetterText = toRenderText(firstLetter); |
| 638 } | 638 } |
| 639 | 639 |
| 640 bool TextIterator::supportsAltText(Node* m_node) | 640 bool TextIterator::supportsAltText(Node* m_node) |
| 641 { | 641 { |
| 642 if (!m_node->isHTMLElement()) | 642 if (!m_node->isHTMLElement()) |
| 643 return false; | 643 return false; |
| 644 HTMLElement& element = toHTMLElement(*m_node); | 644 HTMLElement& element = toHTMLElement(*m_node); |
| 645 | 645 |
| 646 // FIXME: Add isSVGImageElement. | 646 // FIXME: Add isSVGImageElement. |
| 647 if (isHTMLImageElement(element)) | 647 if (isHTMLImageElement(element)) |
| 648 return true; | 648 return true; |
| 649 if (isHTMLInputElement(toHTMLElement(*m_node)) && toHTMLInputElement(*m_node
).isImage()) | 649 if (isHTMLInputElement(toHTMLElement(*m_node)) && toHTMLInputElement(*m_node
).isImage()) |
| 650 return true; | 650 return true; |
| 651 return false; | 651 return false; |
| 652 } | 652 } |
| 653 | 653 |
| 654 bool TextIterator::handleReplacedElement() | 654 bool TextIterator::handleReplacedElement() |
| 655 { | 655 { |
| 656 if (m_fullyClippedStack.top()) | 656 if (m_fullyClippedStack.top()) |
| 657 return false; | 657 return false; |
| 658 | 658 |
| 659 RenderObject* renderer = m_node->renderer(); | 659 LayoutObject* renderer = m_node->renderer(); |
| 660 if (renderer->style()->visibility() != VISIBLE && !m_ignoresStyleVisibility) | 660 if (renderer->style()->visibility() != VISIBLE && !m_ignoresStyleVisibility) |
| 661 return false; | 661 return false; |
| 662 | 662 |
| 663 if (m_emitsObjectReplacementCharacter) { | 663 if (m_emitsObjectReplacementCharacter) { |
| 664 emitCharacter(objectReplacementCharacter, m_node->parentNode(), m_node,
0, 1); | 664 emitCharacter(objectReplacementCharacter, m_node->parentNode(), m_node,
0, 1); |
| 665 return true; | 665 return true; |
| 666 } | 666 } |
| 667 | 667 |
| 668 if (m_lastTextNodeEndedWithCollapsedSpace) { | 668 if (m_lastTextNodeEndedWithCollapsedSpace) { |
| 669 emitCharacter(space, m_lastTextNode->parentNode(), m_lastTextNode, 1, 1)
; | 669 emitCharacter(space, m_lastTextNode->parentNode(), m_lastTextNode, 1, 1)
; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 712 return true; | 712 return true; |
| 713 | 713 |
| 714 if (!renderer->isTextFragment()) | 714 if (!renderer->isTextFragment()) |
| 715 return false; | 715 return false; |
| 716 | 716 |
| 717 RenderTextFragment* fragment = toRenderTextFragment(renderer); | 717 RenderTextFragment* fragment = toRenderTextFragment(renderer); |
| 718 if (!fragment->isRemainingTextRenderer()) | 718 if (!fragment->isRemainingTextRenderer()) |
| 719 return false; | 719 return false; |
| 720 | 720 |
| 721 ASSERT(fragment->firstLetterPseudoElement()); | 721 ASSERT(fragment->firstLetterPseudoElement()); |
| 722 RenderObject* pseudoElementRenderer = fragment->firstLetterPseudoElement()->
renderer(); | 722 LayoutObject* pseudoElementRenderer = fragment->firstLetterPseudoElement()->
renderer(); |
| 723 return pseudoElementRenderer && pseudoElementRenderer->style()->visibility()
== VISIBLE; | 723 return pseudoElementRenderer && pseudoElementRenderer->style()->visibility()
== VISIBLE; |
| 724 } | 724 } |
| 725 | 725 |
| 726 bool TextIterator::shouldEmitTabBeforeNode(Node* node) | 726 bool TextIterator::shouldEmitTabBeforeNode(Node* node) |
| 727 { | 727 { |
| 728 RenderObject* r = node->renderer(); | 728 LayoutObject* r = node->renderer(); |
| 729 | 729 |
| 730 // Table cells are delimited by tabs. | 730 // Table cells are delimited by tabs. |
| 731 if (!r || !isTableCell(node)) | 731 if (!r || !isTableCell(node)) |
| 732 return false; | 732 return false; |
| 733 | 733 |
| 734 // Want a tab before every cell other than the first one | 734 // Want a tab before every cell other than the first one |
| 735 LayoutTableCell* rc = toLayoutTableCell(r); | 735 LayoutTableCell* rc = toLayoutTableCell(r); |
| 736 LayoutTable* t = rc->table(); | 736 LayoutTable* t = rc->table(); |
| 737 return t && (t->cellBefore(rc) || t->cellAbove(rc)); | 737 return t && (t->cellBefore(rc) || t->cellAbove(rc)); |
| 738 } | 738 } |
| 739 | 739 |
| 740 bool TextIterator::shouldEmitNewlineForNode(Node* node, bool emitsOriginalText) | 740 bool TextIterator::shouldEmitNewlineForNode(Node* node, bool emitsOriginalText) |
| 741 { | 741 { |
| 742 RenderObject* renderer = node->renderer(); | 742 LayoutObject* renderer = node->renderer(); |
| 743 | 743 |
| 744 if (renderer ? !renderer->isBR() : !isHTMLBRElement(node)) | 744 if (renderer ? !renderer->isBR() : !isHTMLBRElement(node)) |
| 745 return false; | 745 return false; |
| 746 return emitsOriginalText || !(node->isInShadowTree() && isHTMLInputElement(*
node->shadowHost())); | 746 return emitsOriginalText || !(node->isInShadowTree() && isHTMLInputElement(*
node->shadowHost())); |
| 747 } | 747 } |
| 748 | 748 |
| 749 static bool shouldEmitNewlinesBeforeAndAfterNode(Node& node) | 749 static bool shouldEmitNewlinesBeforeAndAfterNode(Node& node) |
| 750 { | 750 { |
| 751 // Block flow (versus inline flow) is represented by having | 751 // Block flow (versus inline flow) is represented by having |
| 752 // a newline both before and after the element. | 752 // a newline both before and after the element. |
| 753 RenderObject* r = node.renderer(); | 753 LayoutObject* r = node.renderer(); |
| 754 if (!r) { | 754 if (!r) { |
| 755 return (node.hasTagName(blockquoteTag) | 755 return (node.hasTagName(blockquoteTag) |
| 756 || node.hasTagName(ddTag) | 756 || node.hasTagName(ddTag) |
| 757 || node.hasTagName(divTag) | 757 || node.hasTagName(divTag) |
| 758 || node.hasTagName(dlTag) | 758 || node.hasTagName(dlTag) |
| 759 || node.hasTagName(dtTag) | 759 || node.hasTagName(dtTag) |
| 760 || node.hasTagName(h1Tag) | 760 || node.hasTagName(h1Tag) |
| 761 || node.hasTagName(h2Tag) | 761 || node.hasTagName(h2Tag) |
| 762 || node.hasTagName(h3Tag) | 762 || node.hasTagName(h3Tag) |
| 763 || node.hasTagName(h4Tag) | 763 || node.hasTagName(h4Tag) |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 815 { | 815 { |
| 816 return shouldEmitNewlinesBeforeAndAfterNode(node); | 816 return shouldEmitNewlinesBeforeAndAfterNode(node); |
| 817 } | 817 } |
| 818 | 818 |
| 819 static bool shouldEmitExtraNewlineForNode(Node* node) | 819 static bool shouldEmitExtraNewlineForNode(Node* node) |
| 820 { | 820 { |
| 821 // When there is a significant collapsed bottom margin, emit an extra | 821 // When there is a significant collapsed bottom margin, emit an extra |
| 822 // newline for a more realistic result. We end up getting the right | 822 // newline for a more realistic result. We end up getting the right |
| 823 // result even without margin collapsing. For example: <div><p>text</p></div
> | 823 // result even without margin collapsing. For example: <div><p>text</p></div
> |
| 824 // will work right even if both the <div> and the <p> have bottom margins. | 824 // will work right even if both the <div> and the <p> have bottom margins. |
| 825 RenderObject* r = node->renderer(); | 825 LayoutObject* r = node->renderer(); |
| 826 if (!r || !r->isBox()) | 826 if (!r || !r->isBox()) |
| 827 return false; | 827 return false; |
| 828 | 828 |
| 829 // NOTE: We only do this for a select set of nodes, and fwiw WinIE appears | 829 // NOTE: We only do this for a select set of nodes, and fwiw WinIE appears |
| 830 // not to do this at all | 830 // not to do this at all |
| 831 if (node->hasTagName(h1Tag) | 831 if (node->hasTagName(h1Tag) |
| 832 || node->hasTagName(h2Tag) | 832 || node->hasTagName(h2Tag) |
| 833 || node->hasTagName(h3Tag) | 833 || node->hasTagName(h3Tag) |
| 834 || node->hasTagName(h4Tag) | 834 || node->hasTagName(h4Tag) |
| 835 || node->hasTagName(h5Tag) | 835 || node->hasTagName(h5Tag) |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1178 return createPlainText(it); | 1178 return createPlainText(it); |
| 1179 } | 1179 } |
| 1180 | 1180 |
| 1181 String plainText(const Position& start, const Position& end, TextIteratorBehavio
rFlags behavior) | 1181 String plainText(const Position& start, const Position& end, TextIteratorBehavio
rFlags behavior) |
| 1182 { | 1182 { |
| 1183 TextIterator it(start, end, behavior); | 1183 TextIterator it(start, end, behavior); |
| 1184 return createPlainText(it); | 1184 return createPlainText(it); |
| 1185 } | 1185 } |
| 1186 | 1186 |
| 1187 } | 1187 } |
| OLD | NEW |