[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
mitz at apple.com
mitz at apple.com
Wed Dec 22 13:19:45 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit 685d89caae6ec4f4d8e60665ffe3ffc10450f8f6
Author: mitz at apple.com <mitz at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Sat Sep 11 05:55:18 2010 +0000
<rdar://problem/8414282> Can’t dynamically change first-letter to/from floating
Reviewed by Darin Adler.
WebCore:
Test: fast/dynamic/first-letter-display-change.html
* rendering/RenderBlock.cpp:
(WebCore::styleForFirstLetter): Factored this helper function out.
(WebCore::RenderBlock::updateFirstLetter): Renamed variables so that the
“update style” and “create new” branches use the same terminology. In the
update case, if the style change requires a new renderer, handle it.
* rendering/RenderTextFragment.h:
(WebCore::toRenderTextFragment): Added.
LayoutTests:
* fast/dynamic/first-letter-display-change-expected.checksum: Added.
* fast/dynamic/first-letter-display-change-expected.png: Added.
* fast/dynamic/first-letter-display-change-expected.txt: Added.
* fast/dynamic/first-letter-display-change.html: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@67281 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index cf5e202..dca4ba8 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,14 @@
+2010-09-10 Dan Bernstein <mitz at apple.com>
+
+ Reviewed by Darin Adler.
+
+ <rdar://problem/8414282> Can’t dynamically change first-letter to/from floating
+
+ * fast/dynamic/first-letter-display-change-expected.checksum: Added.
+ * fast/dynamic/first-letter-display-change-expected.png: Added.
+ * fast/dynamic/first-letter-display-change-expected.txt: Added.
+ * fast/dynamic/first-letter-display-change.html: Added.
+
2010-09-10 Ryosuke Niwa <rniwa at webkit.org>
Unreviewed.
diff --git a/LayoutTests/fast/dynamic/first-letter-display-change-expected.checksum b/LayoutTests/fast/dynamic/first-letter-display-change-expected.checksum
new file mode 100644
index 0000000..048cc48
--- /dev/null
+++ b/LayoutTests/fast/dynamic/first-letter-display-change-expected.checksum
@@ -0,0 +1 @@
+cfc8dcb729284e0b5680cf5827f1a4c8
\ No newline at end of file
diff --git a/LayoutTests/fast/dynamic/first-letter-display-change-expected.png b/LayoutTests/fast/dynamic/first-letter-display-change-expected.png
new file mode 100644
index 0000000..1a7bf86
Binary files /dev/null and b/LayoutTests/fast/dynamic/first-letter-display-change-expected.png differ
diff --git a/LayoutTests/fast/dynamic/first-letter-display-change-expected.txt b/LayoutTests/fast/dynamic/first-letter-display-change-expected.txt
new file mode 100644
index 0000000..436408b
--- /dev/null
+++ b/LayoutTests/fast/dynamic/first-letter-display-change-expected.txt
@@ -0,0 +1,11 @@
+layer at (0,0) size 800x600
+ RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+ RenderBlock {HTML} at (0,0) size 800x600
+ RenderBody {BODY} at (8,8) size 784x584
+ RenderBlock {DIV} at (0,0) size 784x16
+ RenderInline (generated) at (0,0) size 16x16 [color=#0000FF]
+ RenderText {#text} at (0,0) size 16x16
+ text run at (0,0) width 16: "L"
+ RenderText {#text} at (16,0) size 400x16
+ text run at (16,0) width 400: "orem ipsum dolor sit amet"
diff --git a/LayoutTests/fast/dynamic/first-letter-display-change.html b/LayoutTests/fast/dynamic/first-letter-display-change.html
new file mode 100644
index 0000000..3d6cfb7
--- /dev/null
+++ b/LayoutTests/fast/dynamic/first-letter-display-change.html
@@ -0,0 +1,10 @@
+<style>
+ .a:first-letter { float: right; font-size: 2em; }
+ .b:first-letter { color: blue; }
+</style>
+<div id="target" style="font-family: ahem;" class="a">Lorem ipsum dolor sit amet</div>
+<script>
+ var target = document.getElementById("target");
+ target.offsetTop;
+ target.className = "b";
+</script>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 44d1d12..afa54bf 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,19 @@
+2010-09-10 Dan Bernstein <mitz at apple.com>
+
+ Reviewed by Darin Adler.
+
+ <rdar://problem/8414282> Can’t dynamically change first-letter to/from floating
+
+ Test: fast/dynamic/first-letter-display-change.html
+
+ * rendering/RenderBlock.cpp:
+ (WebCore::styleForFirstLetter): Factored this helper function out.
+ (WebCore::RenderBlock::updateFirstLetter): Renamed variables so that the
+ “update style” and “create new” branches use the same terminology. In the
+ update case, if the style change requires a new renderer, handle it.
+ * rendering/RenderTextFragment.h:
+ (WebCore::toRenderTextFragment): Added.
+
2010-09-10 Sam Weinig <sam at webkit.org>
Reviewed by Darin Adler.
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index 87ef3e9..cfa86cf 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -5093,6 +5093,16 @@ RenderBlock* RenderBlock::firstLineBlock() const
return firstLineBlock;
}
+static RenderStyle* styleForFirstLetter(RenderObject* firstLetterBlock, RenderObject* firstLetterContainer)
+{
+ RenderStyle* pseudoStyle = firstLetterBlock->getCachedPseudoStyle(FIRST_LETTER, firstLetterContainer->firstLineStyle());
+ // Force inline display (except for floating first-letters).
+ pseudoStyle->setDisplay(pseudoStyle->isFloating() ? BLOCK : INLINE);
+ // CSS2 says first-letter can't be positioned.
+ pseudoStyle->setPosition(StaticPosition);
+ return pseudoStyle;
+}
+
void RenderBlock::updateFirstLetter()
{
if (!document()->usesFirstLetterRules())
@@ -5142,84 +5152,110 @@ void RenderBlock::updateFirstLetter()
if (!currChild)
return;
- RenderObject* firstLetterContainer = currChild->parent();
-
// If the child already has style, then it has already been created, so we just want
// to update it.
- if (firstLetterContainer->style()->styleType() == FIRST_LETTER) {
- RenderStyle* pseudo = firstLetterBlock->getCachedPseudoStyle(FIRST_LETTER,
- firstLetterContainer->parent()->firstLineStyle());
- firstLetterContainer->setStyle(pseudo);
- for (RenderObject* genChild = firstLetterContainer->firstChild(); genChild; genChild = genChild->nextSibling()) {
+ if (currChild->parent()->style()->styleType() == FIRST_LETTER) {
+ RenderObject* firstLetter = currChild->parent();
+ RenderObject* firstLetterContainer = firstLetter->parent();
+ RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
+
+ if (Node::diff(firstLetter->style(), pseudoStyle) == Node::Detach) {
+ // The first-letter renderer needs to be replaced. Create a new renderer of the right type.
+ RenderObject* newFirstLetter;
+ if (pseudoStyle->display() == INLINE)
+ newFirstLetter = new (renderArena()) RenderInline(document());
+ else
+ newFirstLetter = new (renderArena()) RenderBlock(document());
+ newFirstLetter->setStyle(pseudoStyle);
+
+ // Move the first letter into the new renderer.
+ view()->disableLayoutState();
+ while (RenderObject* child = firstLetter->firstChild()) {
+ if (child->isText())
+ toRenderText(child)->dirtyLineBoxes(true);
+ firstLetter->removeChild(child);
+ newFirstLetter->addChild(child, 0);
+ }
+ RenderTextFragment* remainingText = toRenderTextFragment(firstLetter->nextSibling());
+ ASSERT(remainingText->node()->renderer() == remainingText);
+ // Replace the old renderer with the new one.
+ remainingText->setFirstLetter(newFirstLetter);
+ firstLetter->destroy();
+ firstLetter = newFirstLetter;
+ firstLetterContainer->addChild(firstLetter, remainingText);
+ view()->enableLayoutState();
+ } else
+ firstLetter->setStyle(pseudoStyle);
+
+ for (RenderObject* genChild = firstLetter->firstChild(); genChild; genChild = genChild->nextSibling()) {
if (genChild->isText())
- genChild->setStyle(pseudo);
+ genChild->setStyle(pseudoStyle);
}
+
return;
}
+ if (!currChild->isText() || currChild->isBR())
+ return;
+
// If the child does not already have style, we create it here.
- if (currChild->isText() && !currChild->isBR() && currChild->parent()->style()->styleType() != FIRST_LETTER) {
- // Our layout state is not valid for the repaints we are going to trigger by
- // adding and removing children of firstLetterContainer.
- view()->disableLayoutState();
+ RenderObject* firstLetterContainer = currChild->parent();
- RenderText* textObj = toRenderText(currChild);
-
- // Create our pseudo style now that we have our firstLetterContainer determined.
- RenderStyle* pseudoStyle = firstLetterBlock->getCachedPseudoStyle(FIRST_LETTER,
- firstLetterContainer->firstLineStyle());
+ // Our layout state is not valid for the repaints we are going to trigger by
+ // adding and removing children of firstLetterContainer.
+ view()->disableLayoutState();
- // Force inline display (except for floating first-letters)
- pseudoStyle->setDisplay(pseudoStyle->isFloating() ? BLOCK : INLINE);
- pseudoStyle->setPosition(StaticPosition); // CSS2 says first-letter can't be positioned.
-
- RenderObject* firstLetter = 0;
- if (pseudoStyle->display() == INLINE)
- firstLetter = new (renderArena()) RenderInline(document());
- else
- firstLetter = new (renderArena()) RenderBlock(document());
- firstLetter->setStyle(pseudoStyle);
- firstLetterContainer->addChild(firstLetter, currChild);
-
- // The original string is going to be either a generated content string or a DOM node's
- // string. We want the original string before it got transformed in case first-letter has
- // no text-transform or a different text-transform applied to it.
- RefPtr<StringImpl> oldText = textObj->originalText();
- ASSERT(oldText);
-
- if (oldText && oldText->length() > 0) {
- unsigned int length = 0;
-
- // account for leading spaces and punctuation
- while (length < oldText->length() && (isSpaceOrNewline((*oldText)[length]) || Unicode::isPunct((*oldText)[length])))
- length++;
-
- // account for first letter
+ RenderText* textObj = toRenderText(currChild);
+
+ // Create our pseudo style now that we have our firstLetterContainer determined.
+ RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
+
+ RenderObject* firstLetter = 0;
+ if (pseudoStyle->display() == INLINE)
+ firstLetter = new (renderArena()) RenderInline(document());
+ else
+ firstLetter = new (renderArena()) RenderBlock(document());
+ firstLetter->setStyle(pseudoStyle);
+ firstLetterContainer->addChild(firstLetter, currChild);
+
+ // The original string is going to be either a generated content string or a DOM node's
+ // string. We want the original string before it got transformed in case first-letter has
+ // no text-transform or a different text-transform applied to it.
+ RefPtr<StringImpl> oldText = textObj->originalText();
+ ASSERT(oldText);
+
+ if (oldText && oldText->length() > 0) {
+ unsigned length = 0;
+
+ // account for leading spaces and punctuation
+ while (length < oldText->length() && (isSpaceOrNewline((*oldText)[length]) || Unicode::isPunct((*oldText)[length])))
length++;
-
- // construct text fragment for the text after the first letter
- // NOTE: this might empty
- RenderTextFragment* remainingText =
- new (renderArena()) RenderTextFragment(textObj->node() ? textObj->node() : textObj->document(), oldText.get(), length, oldText->length() - length);
- remainingText->setStyle(textObj->style());
- if (remainingText->node())
- remainingText->node()->setRenderer(remainingText);
-
- RenderObject* nextObj = textObj->nextSibling();
- firstLetterContainer->removeChild(textObj);
- firstLetterContainer->addChild(remainingText, nextObj);
- remainingText->setFirstLetter(firstLetter);
-
- // construct text fragment for the first letter
- RenderTextFragment* letter =
- new (renderArena()) RenderTextFragment(remainingText->node() ? remainingText->node() : remainingText->document(), oldText.get(), 0, length);
- letter->setStyle(pseudoStyle);
- firstLetter->addChild(letter);
- textObj->destroy();
- }
- view()->enableLayoutState();
+ // account for first letter
+ length++;
+
+ // construct text fragment for the text after the first letter
+ // NOTE: this might empty
+ RenderTextFragment* remainingText =
+ new (renderArena()) RenderTextFragment(textObj->node() ? textObj->node() : textObj->document(), oldText.get(), length, oldText->length() - length);
+ remainingText->setStyle(textObj->style());
+ if (remainingText->node())
+ remainingText->node()->setRenderer(remainingText);
+
+ RenderObject* nextObj = textObj->nextSibling();
+ firstLetterContainer->removeChild(textObj);
+ firstLetterContainer->addChild(remainingText, nextObj);
+ remainingText->setFirstLetter(firstLetter);
+
+ // construct text fragment for the first letter
+ RenderTextFragment* letter =
+ new (renderArena()) RenderTextFragment(remainingText->node() ? remainingText->node() : remainingText->document(), oldText.get(), 0, length);
+ letter->setStyle(pseudoStyle);
+ firstLetter->addChild(letter);
+
+ textObj->destroy();
}
+ view()->enableLayoutState();
}
// Helper methods for obtaining the last line, computing line counts and heights for line counts
diff --git a/WebCore/rendering/RenderTextFragment.h b/WebCore/rendering/RenderTextFragment.h
index e351436..e023042 100644
--- a/WebCore/rendering/RenderTextFragment.h
+++ b/WebCore/rendering/RenderTextFragment.h
@@ -59,6 +59,21 @@ private:
RenderObject* m_firstLetter;
};
+inline RenderTextFragment* toRenderTextFragment(RenderObject* object)
+{
+ ASSERT(!object || toRenderText(object)->isTextFragment());
+ return static_cast<RenderTextFragment*>(object);
+}
+
+inline const RenderTextFragment* toRenderTextFragment(const RenderObject* object)
+{
+ ASSERT(!object || toRenderText(object)->isTextFragment());
+ return static_cast<const RenderTextFragment*>(object);
+}
+
+// This will catch anyone doing an unnecessary cast.
+void toRenderTextFragment(const RenderTextFragment*);
+
} // namespace WebCore
#endif // RenderTextFragment_h
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list