Diff
Modified: trunk/LayoutTests/ChangeLog (112199 => 112200)
--- trunk/LayoutTests/ChangeLog 2012-03-27 02:58:28 UTC (rev 112199)
+++ trunk/LayoutTests/ChangeLog 2012-03-27 03:16:34 UTC (rev 112200)
@@ -1,3 +1,15 @@
+2012-03-26 Ken Buchanan <[email protected]>
+
+ Assert failure from capitalized RenderTextFragment
+ https://bugs.webkit.org/show_bug.cgi?id=82096
+
+ Reviewed by Ryosuke Niwa.
+
+ Test that exercises failure condition in bug 82096.
+
+ * fast/css/first-letter-capitalized-edit-select-crash-expected.txt: Added
+ * fast/css/first-letter-capitalized-edit-select-crash.html: Added
+
2012-03-26 Shinya Kawanaka <[email protected]>
Triggers assertion if dragging from outside of <meter> in a shadow tree to inside of it.
Added: trunk/LayoutTests/fast/css/first-letter-capitalized-edit-select-crash-expected.txt (0 => 112200)
--- trunk/LayoutTests/fast/css/first-letter-capitalized-edit-select-crash-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/css/first-letter-capitalized-edit-select-crash-expected.txt 2012-03-27 03:16:34 UTC (rev 112200)
@@ -0,0 +1,3 @@
+Pass if no crash or assert in debug
+
+
Added: trunk/LayoutTests/fast/css/first-letter-capitalized-edit-select-crash.html (0 => 112200)
--- trunk/LayoutTests/fast/css/first-letter-capitalized-edit-select-crash.html (rev 0)
+++ trunk/LayoutTests/fast/css/first-letter-capitalized-edit-select-crash.html 2012-03-27 03:16:34 UTC (rev 112200)
@@ -0,0 +1,20 @@
+<style>
+.writable{-webkit-user-modify:read-write;}
+.list{content:normal;display:list-item;}
+*:first-letter{stroke-linecap:round;}
+*:only-child{-webkit-font-variant-ligatures:common-ligatures;text-transform:capitalize;</style>
+</style>
+Pass if no crash or assert in debug
+<span class="writable" id="span">
+<label class="list">
+<code>
+<object></object>
+</code></label></span>
+<script>
+window._onload_=function()
+{
+ document.getElementById('span').focus();
+ if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+};
+</script>
Modified: trunk/Source/WebCore/ChangeLog (112199 => 112200)
--- trunk/Source/WebCore/ChangeLog 2012-03-27 02:58:28 UTC (rev 112199)
+++ trunk/Source/WebCore/ChangeLog 2012-03-27 03:16:34 UTC (rev 112200)
@@ -1,3 +1,38 @@
+2012-03-26 Ken Buchanan <[email protected]>
+
+ Assert failure from capitalized RenderTextFragment
+ https://bugs.webkit.org/show_bug.cgi?id=82096
+
+ Reviewed by Ryosuke Niwa.
+
+ The cause of this bug was the call to RenderTextFragment::setTextInternal
+ resulting from a style change from RenderObject::addChild. The idea here
+ is to better separate the code path for transforming existing text from
+ the code path for replacing the underlying text of a node. For
+ RenderTextFragment this has to be clear because only in the latter case
+ does the first-letter get reset.
+
+ * rendering/RenderObject.cpp:
+ (WebCore::RenderObject::addChild): Added call to transformText
+ * rendering/RenderText.cpp:
+ (WebCore::RenderText::styleDidChange): Added call to transformText
+ (WebCore::RenderText::transformText): Added
+ * rendering/RenderText.h:
+ (WebCore::RenderText::setText): Changed to virtual so RenderTextFragment can override
+ (WebCore::RenderText::transformText): Added
+ * rendering/RenderTextFragment.cpp:
+ (WebCore::RenderTextFragment::styleDidChange): Removed references to
+ m_allowFragmentReset which was the previous approach to separating the
+ code paths
+ (WebCore::RenderTextFragment::setTextInternal): Deleted
+ (WebCore::RenderTextFragment::setText): Added with most of logic that was
+ previously in setTextInternal
+ (WebCore::RenderTextFragment::transformText): Added
+ * rendering/RenderTextFragment.h:
+ (WebCore::RenderTextFragment::setText): Added
+ (WebCore::RenderTextFragment::transformText): Added
+ (WebCore::RenderTextFragment::setTextInternal): Deleted
+
2012-03-26 Adam Klein <[email protected]>
Always set V8 wrappers via V8DOMWrapper::setJSWrapperFor* instead of WeakReferenceMap::set()
Modified: trunk/Source/WebCore/rendering/RenderObject.cpp (112199 => 112200)
--- trunk/Source/WebCore/rendering/RenderObject.cpp 2012-03-27 02:58:28 UTC (rev 112199)
+++ trunk/Source/WebCore/rendering/RenderObject.cpp 2012-03-27 03:16:34 UTC (rev 112200)
@@ -332,11 +332,8 @@
children->insertChildNode(this, newChild, beforeChild);
}
- if (newChild->isText() && newChild->style()->textTransform() == CAPITALIZE) {
- RefPtr<StringImpl> textToTransform = toRenderText(newChild)->originalText();
- if (textToTransform)
- toRenderText(newChild)->setText(textToTransform.release(), true);
- }
+ if (newChild->isText() && newChild->style()->textTransform() == CAPITALIZE)
+ toRenderText(newChild)->transformText();
// SVG creates renderers for <g display="none">, as SVG requires children of hidden
// <g>s to have renderers - at least that's how our implementation works. Consider:
Modified: trunk/Source/WebCore/rendering/RenderText.cpp (112199 => 112200)
--- trunk/Source/WebCore/rendering/RenderText.cpp 2012-03-27 02:58:28 UTC (rev 112199)
+++ trunk/Source/WebCore/rendering/RenderText.cpp 2012-03-27 03:16:34 UTC (rev 112200)
@@ -201,10 +201,8 @@
ETextTransform oldTransform = oldStyle ? oldStyle->textTransform() : TTNONE;
ETextSecurity oldSecurity = oldStyle ? oldStyle->textSecurity() : TSNONE;
- if (needsResetText || oldTransform != newStyle->textTransform() || oldSecurity != newStyle->textSecurity()) {
- if (RefPtr<StringImpl> textToTransform = originalText())
- setText(textToTransform.release(), true);
- }
+ if (needsResetText || oldTransform != newStyle->textTransform() || oldSecurity != newStyle->textSecurity())
+ transformText();
}
void RenderText::removeAndDestroyTextBoxes()
@@ -1238,6 +1236,12 @@
setText(text, force);
}
+void RenderText::transformText()
+{
+ if (RefPtr<StringImpl> textToTransform = originalText())
+ setText(textToTransform.release(), true);
+}
+
static inline bool isInlineFlowOrEmptyText(const RenderObject* o)
{
if (o->isRenderInline())
Modified: trunk/Source/WebCore/rendering/RenderText.h (112199 => 112200)
--- trunk/Source/WebCore/rendering/RenderText.h 2012-03-27 02:58:28 UTC (rev 112199)
+++ trunk/Source/WebCore/rendering/RenderText.h 2012-03-27 03:16:34 UTC (rev 112200)
@@ -89,9 +89,11 @@
float firstRunX() const;
float firstRunY() const;
- void setText(PassRefPtr<StringImpl>, bool force = false);
+ virtual void setText(PassRefPtr<StringImpl>, bool force = false);
void setTextWithOffset(PassRefPtr<StringImpl>, unsigned offset, unsigned len, bool force = false);
+ virtual void transformText();
+
virtual bool canBeSelectionLeaf() const { return true; }
virtual void setSelectionState(SelectionState s);
virtual LayoutRect selectionRectForRepaint(RenderBoxModelObject* repaintContainer, bool clipToVisibleContent = true);
@@ -160,7 +162,6 @@
bool isAllASCII() const { return m_isAllASCII; }
void updateNeedsTranscoding();
- inline void transformText(String&) const;
void secureText(UChar mask);
float m_minWidth; // here to minimize padding in 64-bit.
Modified: trunk/Source/WebCore/rendering/RenderTextFragment.cpp (112199 => 112200)
--- trunk/Source/WebCore/rendering/RenderTextFragment.cpp 2012-03-27 02:58:28 UTC (rev 112199)
+++ trunk/Source/WebCore/rendering/RenderTextFragment.cpp 2012-03-27 03:16:34 UTC (rev 112200)
@@ -33,7 +33,6 @@
, m_start(startOffset)
, m_end(length)
, m_firstLetter(0)
- , m_allowFragmentReset(true)
{
}
@@ -43,7 +42,6 @@
, m_end(str ? str->length() : 0)
, m_contentString(str)
, m_firstLetter(0)
- , m_allowFragmentReset(true)
{
}
@@ -62,9 +60,7 @@
void RenderTextFragment::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
- m_allowFragmentReset = false;
RenderText::styleDidChange(diff, oldStyle);
- m_allowFragmentReset = true;
if (RenderBlock* block = blockForAccompanyingFirstLetter()) {
block->style()->removeCachedPseudoStyle(FIRST_LETTER);
@@ -79,25 +75,30 @@
RenderText::willBeDestroyed();
}
-void RenderTextFragment::setTextInternal(PassRefPtr<StringImpl> text)
+void RenderTextFragment::setText(PassRefPtr<StringImpl> text, bool force)
{
- RenderText::setTextInternal(text);
+ RenderText::setText(text, force);
- if (m_allowFragmentReset) {
- m_start = 0;
- m_end = textLength();
- if (m_firstLetter) {
- ASSERT(!m_contentString);
- m_firstLetter->destroy();
- m_firstLetter = 0;
- if (Node* t = node()) {
- ASSERT(!t->renderer());
- t->setRenderer(this);
- }
+ m_start = 0;
+ m_end = textLength();
+ if (m_firstLetter) {
+ ASSERT(!m_contentString);
+ m_firstLetter->destroy();
+ m_firstLetter = 0;
+ if (Node* t = node()) {
+ ASSERT(!t->renderer());
+ t->setRenderer(this);
}
}
}
+void RenderTextFragment::transformText()
+{
+ // Don't reset first-letter here because we are only transforming the truncated fragment.
+ if (RefPtr<StringImpl> textToTransform = originalText())
+ RenderText::setText(textToTransform.release(), true);
+}
+
UChar RenderTextFragment::previousCharacter() const
{
if (start()) {
Modified: trunk/Source/WebCore/rendering/RenderTextFragment.h (112199 => 112200)
--- trunk/Source/WebCore/rendering/RenderTextFragment.h 2012-03-27 02:58:28 UTC (rev 112199)
+++ trunk/Source/WebCore/rendering/RenderTextFragment.h 2012-03-27 03:16:34 UTC (rev 112200)
@@ -50,13 +50,16 @@
StringImpl* contentString() const { return m_contentString.get(); }
virtual PassRefPtr<StringImpl> originalText() const;
+ virtual void setText(PassRefPtr<StringImpl>, bool force = false) OVERRIDE;
+
+ virtual void transformText() OVERRIDE;
+
protected:
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
private:
virtual void willBeDestroyed();
- virtual void setTextInternal(PassRefPtr<StringImpl>);
virtual UChar previousCharacter() const;
RenderBlock* blockForAccompanyingFirstLetter() const;
@@ -64,7 +67,6 @@
unsigned m_end;
RefPtr<StringImpl> m_contentString;
RenderObject* m_firstLetter;
- bool m_allowFragmentReset;
};
inline RenderTextFragment* toRenderTextFragment(RenderObject* object)