Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2007 David Smith (catfish.man@gmail.com) | 4 * (C) 2007 David Smith (catfish.man@gmail.com) |
| 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. | 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved. |
| 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
| 7 * | 7 * |
| 8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
| 10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 #include "config.h" | 24 #include "config.h" |
| 25 #include "core/rendering/RenderBlock.h" | 25 #include "core/rendering/RenderBlock.h" |
| 26 | 26 |
| 27 #include "HTMLFormElement.h" | 27 #include "HTMLFormElement.h" |
| 28 #include "HTMLNames.h" | 28 #include "HTMLNames.h" |
| 29 #include "core/accessibility/AXObjectCache.h" | 29 #include "core/accessibility/AXObjectCache.h" |
| 30 #include "core/dom/Document.h" | 30 #include "core/dom/Document.h" |
| 31 #include "core/dom/Element.h" | 31 #include "core/dom/Element.h" |
| 32 #include "core/dom/OverflowEvent.h" | 32 #include "core/dom/OverflowEvent.h" |
| 33 #include "core/dom/ShadowRoot.h" | 33 #include "core/dom/ShadowRoot.h" |
| 34 #include "core/dom/Text.h" | |
| 34 #include "core/dom/WebCoreMemoryInstrumentation.h" | 35 #include "core/dom/WebCoreMemoryInstrumentation.h" |
| 35 #include "core/editing/Editor.h" | 36 #include "core/editing/Editor.h" |
| 36 #include "core/editing/FrameSelection.h" | 37 #include "core/editing/FrameSelection.h" |
| 37 #include "core/page/Frame.h" | 38 #include "core/page/Frame.h" |
| 38 #include "core/page/FrameView.h" | 39 #include "core/page/FrameView.h" |
| 39 #include "core/page/Page.h" | 40 #include "core/page/Page.h" |
| 40 #include "core/page/Settings.h" | 41 #include "core/page/Settings.h" |
| 41 #include "core/platform/PODFreeListArena.h" | 42 #include "core/platform/PODFreeListArena.h" |
| 42 #include "core/platform/graphics/FloatQuad.h" | 43 #include "core/platform/graphics/FloatQuad.h" |
| 43 #include "core/platform/graphics/GraphicsContext.h" | 44 #include "core/platform/graphics/GraphicsContext.h" |
| (...skipping 6569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6613 firstLetterContainer->addChild(firstLetter, nextSibling); | 6614 firstLetterContainer->addChild(firstLetter, nextSibling); |
| 6614 } else | 6615 } else |
| 6615 firstLetter->setStyle(pseudoStyle); | 6616 firstLetter->setStyle(pseudoStyle); |
| 6616 | 6617 |
| 6617 for (RenderObject* genChild = firstLetter->firstChild(); genChild; genChild = genChild->nextSibling()) { | 6618 for (RenderObject* genChild = firstLetter->firstChild(); genChild; genChild = genChild->nextSibling()) { |
| 6618 if (genChild->isText()) | 6619 if (genChild->isText()) |
| 6619 genChild->setStyle(pseudoStyle); | 6620 genChild->setStyle(pseudoStyle); |
| 6620 } | 6621 } |
| 6621 } | 6622 } |
| 6622 | 6623 |
| 6624 static inline unsigned whiteSpaceLength(PassRefPtr<StringImpl> oldText) | |
|
esprehn
2013/05/06 20:43:58
Just take a String not a RefPtr<StringImpl>
| |
| 6625 { | |
| 6626 unsigned length = 0; | |
| 6627 // Account for leading spaces and punctuation. | |
| 6628 while (length < oldText->length() && shouldSkipForFirstLetter((*oldText)[len gth])) | |
| 6629 length++; | |
| 6630 | |
| 6631 // Account for first letter. | |
| 6632 length++; | |
| 6633 | |
| 6634 // Keep looking for whitespace and allowed punctuation, but avoid | |
| 6635 // accumulating just whitespace into the :first-letter. | |
| 6636 for (unsigned scanLength = length; scanLength < oldText->length(); ++scanLen gth) { | |
| 6637 UChar c = (*oldText)[scanLength]; | |
| 6638 | |
| 6639 if (!shouldSkipForFirstLetter(c)) | |
| 6640 break; | |
| 6641 | |
| 6642 if (isPunctuationForFirstLetter(c)) | |
| 6643 length = scanLength + 1; | |
| 6644 } | |
| 6645 | |
| 6646 return length; | |
| 6647 } | |
| 6648 | |
| 6623 void RenderBlock::createFirstLetterRenderer(RenderObject* firstLetterBlock, Rend erObject* currentChild) | 6649 void RenderBlock::createFirstLetterRenderer(RenderObject* firstLetterBlock, Rend erObject* currentChild) |
| 6624 { | 6650 { |
| 6625 RenderObject* firstLetterContainer = currentChild->parent(); | 6651 RenderObject* firstLetterContainer = currentChild->parent(); |
| 6626 RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetter Container); | 6652 RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetter Container); |
| 6627 RenderObject* firstLetter = 0; | 6653 RenderObject* firstLetter = 0; |
| 6628 if (pseudoStyle->display() == INLINE) | 6654 if (pseudoStyle->display() == INLINE) |
| 6629 firstLetter = RenderInline::createAnonymous(document()); | 6655 firstLetter = RenderInline::createAnonymous(document()); |
| 6630 else | 6656 else |
| 6631 firstLetter = RenderBlock::createAnonymous(document()); | 6657 firstLetter = RenderBlock::createAnonymous(document()); |
| 6632 firstLetter->setStyle(pseudoStyle); | 6658 firstLetter->setStyle(pseudoStyle); |
| 6633 firstLetterContainer->addChild(firstLetter, currentChild); | 6659 firstLetterContainer->addChild(firstLetter, currentChild); |
| 6634 | 6660 |
| 6635 RenderText* textObj = toRenderText(currentChild); | 6661 RenderText* textObj = toRenderText(currentChild); |
| 6636 | 6662 |
| 6637 // The original string is going to be either a generated content string or a DOM node's | 6663 // The original string is going to be either a generated content string or a DOM node's |
| 6638 // string. We want the original string before it got transformed in case fi rst-letter has | 6664 // string. We want the original string before it got transformed in case fi rst-letter has |
| 6639 // no text-transform or a different text-transform applied to it. | 6665 // no text-transform or a different text-transform applied to it. |
| 6640 RefPtr<StringImpl> oldText = textObj->originalText(); | 6666 RefPtr<StringImpl> oldText = textObj->originalText(); |
|
esprehn
2013/05/06 20:43:58
Change to String
| |
| 6641 ASSERT(oldText); | 6667 ASSERT(oldText); |
| 6642 | 6668 |
| 6643 if (oldText && oldText->length() > 0) { | 6669 if (oldText && oldText->length() > 0) { |
| 6644 unsigned length = 0; | 6670 unsigned length = 0; |
| 6671 length = whiteSpaceLength(oldText); | |
| 6645 | 6672 |
| 6646 // Account for leading spaces and punctuation. | |
| 6647 while (length < oldText->length() && shouldSkipForFirstLetter((*oldText) [length])) | |
| 6648 length++; | |
| 6649 | |
| 6650 // Account for first letter. | |
| 6651 length++; | |
| 6652 | |
| 6653 // Keep looking for whitespace and allowed punctuation, but avoid | |
| 6654 // accumulating just whitespace into the :first-letter. | |
| 6655 for (unsigned scanLength = length; scanLength < oldText->length(); ++sca nLength) { | |
| 6656 UChar c = (*oldText)[scanLength]; | |
| 6657 | |
| 6658 if (!shouldSkipForFirstLetter(c)) | |
| 6659 break; | |
| 6660 | |
| 6661 if (isPunctuationForFirstLetter(c)) | |
| 6662 length = scanLength + 1; | |
| 6663 } | |
| 6664 | |
| 6665 // Construct a text fragment for the text after the first letter. | 6673 // Construct a text fragment for the text after the first letter. |
| 6666 // This text fragment might be empty. | 6674 // This text fragment might be empty. |
| 6667 RenderTextFragment* remainingText = | 6675 RenderTextFragment* remainingText = |
| 6668 new (renderArena()) RenderTextFragment(textObj->node() ? textObj->no de() : textObj->document(), oldText.get(), length, oldText->length() - length); | 6676 new (renderArena()) RenderTextFragment(textObj->node() ? textObj->no de() : textObj->document(), oldText.get(), length, oldText->length() - length); |
| 6669 remainingText->setStyle(textObj->style()); | 6677 remainingText->setStyle(textObj->style()); |
| 6670 if (remainingText->node()) | 6678 if (remainingText->node()) |
| 6671 remainingText->node()->setRenderer(remainingText); | 6679 remainingText->node()->setRenderer(remainingText); |
| 6672 | 6680 |
| 6673 firstLetterContainer->addChild(remainingText, textObj); | 6681 firstLetterContainer->addChild(remainingText, textObj); |
| 6674 firstLetterContainer->removeChild(textObj); | 6682 firstLetterContainer->removeChild(textObj); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 6694 return; | 6702 return; |
| 6695 | 6703 |
| 6696 // FIXME: We need to destroy the first-letter object if it is no longer the first child. Need to find | 6704 // FIXME: We need to destroy the first-letter object if it is no longer the first child. Need to find |
| 6697 // an efficient way to check for that situation though before implementing a nything. | 6705 // an efficient way to check for that situation though before implementing a nything. |
| 6698 RenderObject* firstLetterBlock = findFirstLetterBlock(this); | 6706 RenderObject* firstLetterBlock = findFirstLetterBlock(this); |
| 6699 if (!firstLetterBlock) | 6707 if (!firstLetterBlock) |
| 6700 return; | 6708 return; |
| 6701 | 6709 |
| 6702 // Drill into inlines looking for our first text child. | 6710 // Drill into inlines looking for our first text child. |
| 6703 RenderObject* currChild = firstLetterBlock->firstChild(); | 6711 RenderObject* currChild = firstLetterBlock->firstChild(); |
| 6712 RenderObject* firstLetter = currChild; | |
| 6713 | |
| 6704 while (currChild) { | 6714 while (currChild) { |
| 6705 if (currChild->isText()) | 6715 if (currChild->isText()) |
| 6706 break; | 6716 break; |
| 6707 if (currChild->isListMarker()) | 6717 if (currChild->isListMarker()) |
| 6708 currChild = currChild->nextSibling(); | 6718 currChild = currChild->nextSibling(); |
| 6709 else if (currChild->isFloatingOrOutOfFlowPositioned()) { | 6719 else if (currChild->isFloatingOrOutOfFlowPositioned()) { |
| 6710 if (currChild->style()->styleType() == FIRST_LETTER) { | 6720 if (currChild->style()->styleType() == FIRST_LETTER) { |
| 6711 currChild = currChild->firstChild(); | 6721 currChild = currChild->firstChild(); |
| 6712 break; | 6722 break; |
| 6713 } | 6723 } |
| 6714 currChild = currChild->nextSibling(); | 6724 currChild = currChild->nextSibling(); |
| 6715 } else if (currChild->isReplaced() || currChild->isRenderButton() || cur rChild->isMenuList()) | 6725 } else if (currChild->isReplaced() || currChild->isRenderButton() || cur rChild->isMenuList()) |
| 6716 break; | 6726 break; |
| 6717 else if (currChild->style()->hasPseudoStyle(FIRST_LETTER) && currChild-> canHaveGeneratedChildren()) { | 6727 else if (currChild->style()->hasPseudoStyle(FIRST_LETTER) && currChild-> canHaveGeneratedChildren()) { |
| 6718 // We found a lower-level node with first-letter, which supersedes t he higher-level style | 6728 // We found a lower-level node with first-letter, which supersedes t he higher-level style |
| 6719 firstLetterBlock = currChild; | 6729 firstLetterBlock = currChild; |
| 6720 currChild = currChild->firstChild(); | 6730 currChild = currChild->firstChild(); |
| 6721 } else | 6731 } else |
| 6722 currChild = currChild->firstChild(); | 6732 currChild = currChild->firstChild(); |
| 6723 } | 6733 } |
| 6724 | 6734 |
| 6725 if (!currChild) | 6735 if (!currChild) |
| 6726 return; | 6736 return; |
| 6727 | 6737 |
| 6728 // If the child already has style, then it has already been created, so we j ust want | 6738 // If the child already has style, then it has already been created, so we j ust want |
| 6729 // to update it. | 6739 // to update it. |
| 6730 if (currChild->parent()->style()->styleType() == FIRST_LETTER) { | 6740 if (currChild->parent()->style()->styleType() == FIRST_LETTER) { |
| 6741 RenderText* remainingText = toRenderText(currChild->parent()->nextSiblin g()); | |
| 6742 // When the first line is changed by adding a new text at its start, | |
| 6743 // the first letter has to be updated. | |
| 6744 if (toRenderBoxModelObject(firstLetter)->firstLetterRemainingText() != r emainingText) { | |
| 6745 RenderText* firstLetterText = toRenderText(currChild); | |
| 6746 RefPtr<StringImpl> updatedTextImp = remainingText->originalText(); | |
|
esprehn
2013/05/06 20:43:58
Just use String. A String is just a RefPtr to a St
| |
| 6747 ASSERT(updatedTextImp); | |
|
esprehn
2013/05/06 20:43:58
This assert should be inside whiteSpaceLength
| |
| 6748 unsigned length = 0; | |
| 6749 if (updatedTextImp && updatedTextImp->length() > 0) | |
|
esprehn
2013/05/06 20:43:58
This check should be inside whiteSpaceLength() and
| |
| 6750 length = whiteSpaceLength(updatedTextImp); | |
| 6751 | |
| 6752 firstLetterText->setText(updatedTextImp->substring(0, length)); | |
| 6753 remainingText->setText(updatedTextImp->substring(length)); | |
| 6754 | |
| 6755 RenderObject* oldRemainingText = currChild->parent()->nextSibling()- >nextSibling(); | |
|
esprehn
2013/05/06 20:43:58
This doesn't look safe at all. How do you know you
| |
| 6756 // Replace the previous remaining text with the original text. | |
| 6757 // because it doesn't have the first letter. | |
| 6758 if (oldRemainingText->isText()) { | |
| 6759 RefPtr<StringImpl> oldString = toText(oldRemainingText->node())- >dataImpl(); | |
|
esprehn
2013/05/06 20:43:58
This is going to crash if it's an anonymous text r
| |
| 6760 | |
| 6761 // Before calling setText, we need to set m_firstLetter to 0 in order not to delete it. | |
| 6762 if (toRenderText(oldRemainingText)->isTextFragment()) | |
| 6763 toRenderTextFragment(oldRemainingText)->setFirstLetter(0); | |
| 6764 | |
| 6765 toRenderText(oldRemainingText)->setText(oldString); | |
| 6766 } | |
| 6767 toRenderBoxModelObject(firstLetter)->setFirstLetterRemainingText(rem ainingText); | |
| 6768 } | |
| 6769 | |
| 6731 updateFirstLetterStyle(firstLetterBlock, currChild); | 6770 updateFirstLetterStyle(firstLetterBlock, currChild); |
| 6732 return; | 6771 return; |
| 6733 } | 6772 } |
| 6734 | 6773 |
| 6735 if (!currChild->isText() || currChild->isBR()) | 6774 if (!currChild->isText() || currChild->isBR()) |
| 6736 return; | 6775 return; |
| 6737 | 6776 |
| 6738 // Our layout state is not valid for the repaints we are going to trigger by | 6777 // Our layout state is not valid for the repaints we are going to trigger by |
| 6739 // adding and removing children of firstLetterContainer. | 6778 // adding and removing children of firstLetterContainer. |
| 6740 LayoutStateDisabler layoutStateDisabler(view()); | 6779 LayoutStateDisabler layoutStateDisabler(view()); |
| (...skipping 1373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8114 { | 8153 { |
| 8115 memoryInstrumentation->addRootObject(gColumnInfoMap, WebCoreMemoryTypes::Ren deringStructures); | 8154 memoryInstrumentation->addRootObject(gColumnInfoMap, WebCoreMemoryTypes::Ren deringStructures); |
| 8116 memoryInstrumentation->addRootObject(gPositionedDescendantsMap, WebCoreMemor yTypes::RenderingStructures); | 8155 memoryInstrumentation->addRootObject(gPositionedDescendantsMap, WebCoreMemor yTypes::RenderingStructures); |
| 8117 memoryInstrumentation->addRootObject(gPercentHeightDescendantsMap, WebCoreMe moryTypes::RenderingStructures); | 8156 memoryInstrumentation->addRootObject(gPercentHeightDescendantsMap, WebCoreMe moryTypes::RenderingStructures); |
| 8118 memoryInstrumentation->addRootObject(gPositionedContainerMap, WebCoreMemoryT ypes::RenderingStructures); | 8157 memoryInstrumentation->addRootObject(gPositionedContainerMap, WebCoreMemoryT ypes::RenderingStructures); |
| 8119 memoryInstrumentation->addRootObject(gPercentHeightContainerMap, WebCoreMemo ryTypes::RenderingStructures); | 8158 memoryInstrumentation->addRootObject(gPercentHeightContainerMap, WebCoreMemo ryTypes::RenderingStructures); |
| 8120 memoryInstrumentation->addRootObject(gDelayedUpdateScrollInfoSet, WebCoreMem oryTypes::RenderingStructures); | 8159 memoryInstrumentation->addRootObject(gDelayedUpdateScrollInfoSet, WebCoreMem oryTypes::RenderingStructures); |
| 8121 } | 8160 } |
| 8122 | 8161 |
| 8123 } // namespace WebCore | 8162 } // namespace WebCore |
| OLD | NEW |