pseudo element patch part 2
David Hyatt
hyatt at apple.com
Thu Oct 23 16:33:30 CEST 2003
Here's the rest of it. first-letter/line inheritance are much better
now with this patch.
-------------- next part --------------
Index: khtml/rendering/render_block.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_block.cpp,v
retrieving revision 1.69
diff -u -p -r1.69 khtml/rendering/render_block.cpp
--- khtml/rendering/render_block.cpp 2003/10/21 22:14:37 1.69
+++ khtml/rendering/render_block.cpp 2003/10/23 21:15:57
@@ -101,69 +101,6 @@ void RenderBlock::addChildToFlow(RenderO
bool madeBoxesNonInline = FALSE;
- RenderStyle* pseudoStyle=0;
- if ((!firstChild() || firstChild() == beforeChild) &&
- (newChild->isInline() || (newChild->isText() && !newChild->isBR())) &&
- (pseudoStyle=getPseudoStyle(RenderStyle::FIRST_LETTER, style(true))))
- {
- // Drill into inlines looking for our first text child.
- RenderObject* textChild = newChild;
- while (textChild && !(textChild->isText() && !textChild->isBR()))
- textChild = textChild->firstChild();
-
- if (textChild) {
- RenderObject* firstLetterContainer = textChild->parent();
- if (!firstLetterContainer)
- firstLetterContainer = this;
-
- RenderText* textObj = static_cast<RenderText*>(textChild);
- //kdDebug( 6040 ) << "first letter" << endl;
-
- // Force inline display (except for floating first-letters)
- pseudoStyle->setDisplay( pseudoStyle->isFloating() ? BLOCK : INLINE);
- pseudoStyle->setPosition( STATIC ); // CSS2 says first-letter can't be positioned.
-
- RenderObject* firstLetter = RenderFlow::createAnonymousFlow(document(), pseudoStyle); // anonymous box
- firstLetterContainer->addChild(firstLetter, firstLetterContainer->firstChild());
-
- // 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.
- DOMStringImpl* oldText = textObj->originalString();
-
- if (oldText->l >= 1) {
- unsigned int length = 0;
- while ( length < oldText->l &&
- ( (oldText->s+length)->isSpace() || (oldText->s+length)->isPunct() ) )
- length++;
- length++;
- //kdDebug( 6040 ) << "letter= '" << DOMString(oldText->substring(0,length)).string() << "'" << endl;
-
- RenderTextFragment* remainingText =
- new (renderArena()) RenderTextFragment(textObj->node(), oldText, length, oldText->l-length);
- remainingText->setStyle(textObj->style());
- if (remainingText->element())
- remainingText->element()->setRenderer(remainingText);
- if (textObj->parent()) {
- RenderObject* nextObj = textObj->nextSibling();
- firstLetterContainer->removeChild(textObj);
- firstLetterContainer->addChild(remainingText, nextObj);
- }
- else {
- newChild->detach();
- newChild = remainingText;
- }
-
- RenderTextFragment* letter =
- new (renderArena()) RenderTextFragment(remainingText->node(), oldText, 0, length);
- RenderStyle* newStyle = new RenderStyle();
- newStyle->inheritFrom(pseudoStyle);
- letter->setStyle(newStyle);
- firstLetter->addChild(letter);
- }
- }
- }
-
// If the requested beforeChild is not one of our children, then this is most likely because
// there is an anonymous block box within this object that contains the beforeChild. So
// just insert the child into the anonymous block box instead of here.
@@ -428,7 +365,7 @@ void RenderBlock::layoutBlock(bool relay
setNeedsLayout(false);
return;
}
-
+
#ifdef INCREMENTAL_REPAINTING
QRect oldBounds, oldFullBounds;
bool checkForRepaint = checkForRepaintDuringLayout();
@@ -2493,6 +2430,102 @@ InlineFlowBox* RenderBlock::getFirstLine
}
return 0;
+}
+
+RenderBlock* RenderBlock::firstLineBlock() const
+{
+ const RenderObject* firstLineBlock = this;
+ bool hasPseudo = false;
+ while (true) {
+ hasPseudo = firstLineBlock->style()->hasPseudoStyle(RenderStyle::FIRST_LINE);
+ if (hasPseudo)
+ break;
+ RenderObject* parentBlock = firstLineBlock->parent();
+ if (!parentBlock || parentBlock->firstChild() != firstLineBlock || !parentBlock->isBlockFlow())
+ break;
+ firstLineBlock = parentBlock;
+ }
+
+ if (!hasPseudo)
+ return 0;
+
+ return (RenderBlock*)(firstLineBlock);
+}
+
+void RenderBlock::updateFirstLetter()
+{
+ // FIXME: We need to destroy the first-letter object if it is no longer the first child. Need to find
+ // an efficient way to check for that situation though before implementing anything.
+ RenderObject* firstLetterBlock = this;
+ bool hasPseudoStyle = false;
+ while (true) {
+ hasPseudoStyle = firstLetterBlock->style()->hasPseudoStyle(RenderStyle::FIRST_LETTER);
+ if (hasPseudoStyle)
+ break;
+ RenderObject* parentBlock = firstLetterBlock->parent();
+ if (!parentBlock || parentBlock->firstChild() != firstLetterBlock || !parentBlock->isBlockFlow())
+ break;
+ firstLetterBlock = parentBlock;
+ }
+
+ if (!hasPseudoStyle)
+ return;
+
+ // Drill into inlines looking for our first text child.
+ RenderObject* textChild = firstLetterBlock->firstChild();
+ while (textChild && textChild->needsLayout() && !textChild->isReplaced() && !textChild->isText())
+ textChild = textChild->firstChild();
+
+ if (textChild && textChild->isText() && !textChild->isBR() &&
+ textChild->parent()->style()->styleType() != RenderStyle::FIRST_LETTER) {
+ RenderObject* firstLetterContainer = textChild->parent();
+ if (!firstLetterContainer)
+ firstLetterContainer = this;
+
+ RenderText* textObj = static_cast<RenderText*>(textChild);
+
+ // Create our pseudo style now that we have our firstLetterContainer determined.
+ RenderStyle* pseudoStyle = firstLetterBlock->getPseudoStyle(RenderStyle::FIRST_LETTER,
+ firstLetterContainer->style(true));
+
+ // Force inline display (except for floating first-letters)
+ pseudoStyle->setDisplay( pseudoStyle->isFloating() ? BLOCK : INLINE);
+ pseudoStyle->setPosition( STATIC ); // CSS2 says first-letter can't be positioned.
+
+ RenderObject* firstLetter = RenderFlow::createAnonymousFlow(document(), pseudoStyle); // anonymous box
+ firstLetterContainer->addChild(firstLetter, firstLetterContainer->firstChild());
+
+ // 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.
+ DOMStringImpl* oldText = textObj->originalString();
+
+ if (oldText->l >= 1) {
+ unsigned int length = 0;
+ while ( length < oldText->l &&
+ ( (oldText->s+length)->isSpace() || (oldText->s+length)->isPunct() ) )
+ length++;
+ length++;
+ //kdDebug( 6040 ) << "letter= '" << DOMString(oldText->substring(0,length)).string() << "'" << endl;
+
+ RenderTextFragment* remainingText =
+ new (renderArena()) RenderTextFragment(textObj->node(), oldText, length, oldText->l-length);
+ remainingText->setStyle(textObj->style());
+ if (remainingText->element())
+ remainingText->element()->setRenderer(remainingText);
+
+ RenderObject* nextObj = textObj->nextSibling();
+ firstLetterContainer->removeChild(textObj);
+ firstLetterContainer->addChild(remainingText, nextObj);
+
+ RenderTextFragment* letter =
+ new (renderArena()) RenderTextFragment(remainingText->node(), oldText, 0, length);
+ RenderStyle* newStyle = new RenderStyle();
+ newStyle->inheritFrom(pseudoStyle);
+ letter->setStyle(newStyle);
+ firstLetter->addChild(letter);
+ }
+ }
}
const char *RenderBlock::renderName() const
Index: khtml/rendering/render_block.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_block.h,v
retrieving revision 1.26
diff -u -p -r1.26 khtml/rendering/render_block.h
--- khtml/rendering/render_block.h 2003/10/07 04:43:23 1.26
+++ khtml/rendering/render_block.h 2003/10/23 21:15:57
@@ -44,7 +44,7 @@ public:
virtual short baselinePosition(bool b, bool isRootLineBox=false) const;
virtual bool isRenderBlock() const { return true; }
- virtual bool isBlockFlow() const { return !isInline() && !isTable(); }
+ virtual bool isBlockFlow() const { return (!isInline() || isReplaced()) && !isTable(); }
virtual bool isInlineFlow() const { return isInline() && !isReplaced(); }
virtual bool isInlineBlockOrInlineTable() const { return isInline() && isReplaced(); }
@@ -179,6 +179,11 @@ public:
// overrides RenderObject
virtual bool requiresLayer();
+ // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
+ // children.
+ virtual RenderBlock* firstLineBlock() const;
+ virtual void updateFirstLetter();
+
#ifndef NDEBUG
virtual void printTree(int indent=0) const;
virtual void dump(QTextStream *stream, QString ind = "") const;
@@ -186,7 +191,7 @@ public:
protected:
void newLine();
-
+
protected:
struct FloatingObject {
enum Type {
Index: khtml/rendering/render_line.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_line.cpp,v
retrieving revision 1.11
diff -u -p -r1.11 khtml/rendering/render_line.cpp
--- khtml/rendering/render_line.cpp 2003/09/25 16:51:10 1.11
+++ khtml/rendering/render_line.cpp 2003/10/23 21:15:57
@@ -499,7 +499,8 @@ void InlineFlowBox::paintBackgroundAndBo
// You can use p::first-line to specify a background. If so, the root line boxes for
// a line may actually have to paint a background.
RenderStyle* styleToUse = object()->style(m_firstLine);
- if (object()->hasFirstLine() || (parent() && object()->shouldPaintBackgroundOrBorder())) {
+ if ((!parent() && m_firstLine && styleToUse != object()->style()) ||
+ (parent() && object()->shouldPaintBackgroundOrBorder())) {
CachedImage* bg = styleToUse->backgroundImage();
bool hasBackgroundImage = bg && (bg->pixmap_size() == bg->valid_rect().size()) &&
!bg->isTransparent() && !bg->isErrorImage();
Index: khtml/rendering/render_list.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_list.cpp,v
retrieving revision 1.48
diff -u -p -r1.48 khtml/rendering/render_list.cpp
--- khtml/rendering/render_list.cpp 2003/10/09 22:20:53 1.48
+++ khtml/rendering/render_list.cpp 2003/10/23 21:15:57
@@ -138,7 +138,9 @@ void RenderListItem::setStyle(RenderStyl
(style()->listStyleImage() && !style()->listStyleImage()->isErrorImage())) {
RenderStyle *newStyle = new RenderStyle();
newStyle->ref();
- newStyle->inheritFrom(style());
+ // The marker always inherits from the list item, regardless of where it might end
+ // up (e.g., in some deeply nested line box). See CSS3 spec.
+ newStyle->inheritFrom(style());
if (!m_marker) {
m_marker = new (renderArena()) RenderListMarker(document());
m_marker->setStyle(newStyle);
Index: khtml/rendering/render_object.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_object.cpp,v
retrieving revision 1.106
diff -u -p -r1.106 khtml/rendering/render_object.cpp
--- khtml/rendering/render_object.cpp 2003/10/21 22:14:37 1.106
+++ khtml/rendering/render_object.cpp 2003/10/23 21:15:57
@@ -146,7 +146,6 @@ m_inline( true ),
m_replaced( false ),
m_mouseInside( false ),
-m_hasFirstLine( false ),
m_isSelectionBorder( false )
{
}
@@ -327,6 +326,14 @@ bool RenderObject::requiresLayer()
return isRoot() || isPositioned() || isRelPositioned() || style()->opacity() < 1.0f;
}
+RenderBlock* RenderObject::firstLineBlock() const
+{
+ return 0;
+}
+
+void RenderObject::updateFirstLetter()
+{}
+
int RenderObject::offsetLeft() const
{
int x = xPos();
@@ -1071,7 +1078,6 @@ void RenderObject::dump(QTextStream *str
if (needsLayout()) { *stream << " needsLayout"; }
if (minMaxKnown()) { *stream << " minMaxKnown"; }
if (overhangingContents()) { *stream << " overhangingContents"; }
- if (hasFirstLine()) { *stream << " hasFirstLine"; }
*stream << endl;
RenderObject *child = firstChild();
@@ -1210,8 +1216,7 @@ void RenderObject::setStyle(RenderStyle
setShouldPaintBackgroundOrBorder(m_style->backgroundColor().isValid() ||
m_style->hasBorder() || nb );
- m_hasFirstLine = getPseudoStyle(RenderStyle::FIRST_LINE);
-
+
if (affectsParentBlock)
handleDynamicFloatPositionChange();
@@ -1687,6 +1692,9 @@ void RenderObject::recalcMinMaxWidths()
kdDebug( 6040 ) << renderName() << " recalcMinMaxWidths() this=" << this <<endl;
#endif
+ if (m_recalcMinMax)
+ updateFirstLetter();
+
RenderObject *child = firstChild();
while( child ) {
// gcc sucks. if anybody knows a trick to get rid of the
@@ -1749,10 +1757,22 @@ InlineBox* RenderObject::createInlineBox
RenderStyle* RenderObject::style(bool firstLine) const {
RenderStyle *s = m_style;
- if (firstLine && hasFirstLine()) {
- RenderStyle *pseudoStyle = getPseudoStyle(RenderStyle::FIRST_LINE);
- if (pseudoStyle)
- s = pseudoStyle;
+ if (firstLine) {
+ const RenderObject* obj = isText() ? parent() : this;
+ if (obj->isBlockFlow()) {
+ RenderBlock* firstLineBlock = obj->firstLineBlock();
+ if (firstLineBlock)
+ s = firstLineBlock->getPseudoStyle(RenderStyle::FIRST_LINE, style());
+ }
+ else if (!obj->isAnonymous() && obj->isInlineFlow()) {
+ RenderStyle* parentStyle = obj->parent()->style(true);
+ if (parentStyle != obj->parent()->style()) {
+ // A first-line style is in effect. We need to cache a first-line style
+ // for ourselves.
+ style()->setHasPseudoStyle(RenderStyle::FIRST_LINE_INHERITED);
+ s = obj->getPseudoStyle(RenderStyle::FIRST_LINE_INHERITED, parentStyle);
+ }
+ }
}
return s;
}
@@ -1762,15 +1782,26 @@ RenderStyle* RenderObject::getPseudoStyl
if (!style()->hasPseudoStyle(pseudo))
return 0;
+ if (!parentStyle)
+ parentStyle = style();
+
+ RenderStyle* result = style()->getPseudoStyle(pseudo);
+ if (result) return result;
+
DOM::NodeImpl* node = element();
if (isText())
node = element()->parentNode();
if (!node) return 0;
- if (!parentStyle)
- parentStyle = style();
-
- return document()->styleSelector()->pseudoStyleForElement(pseudo, static_cast<DOM::ElementImpl*>(node), parentStyle);
+ if (pseudo == RenderStyle::FIRST_LINE_INHERITED)
+ result = document()->styleSelector()->styleForElement(static_cast<DOM::ElementImpl*>(node),
+ parentStyle);
+ else
+ result = document()->styleSelector()->pseudoStyleForElement(pseudo, static_cast<DOM::ElementImpl*>(node),
+ parentStyle);
+ if (result)
+ style()->addPseudoStyle(result);
+ return result;
}
void RenderObject::getTextDecorationColors(int decorations, QColor& underline, QColor& overline,
Index: khtml/rendering/render_object.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_object.h,v
retrieving revision 1.87
diff -u -p -r1.87 khtml/rendering/render_object.h
--- khtml/rendering/render_object.h 2003/10/21 22:14:37 1.87
+++ khtml/rendering/render_object.h 2003/10/23 21:15:57
@@ -140,6 +140,11 @@ public:
virtual int getBaselineOfFirstLineBox() { return -1; } // Tables and blocks implement this.
virtual InlineFlowBox* getFirstLineBox() { return 0; } // Tables and blocks implement this.
+ // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
+ // children.
+ virtual RenderBlock* firstLineBlock() const;
+ virtual void updateFirstLetter();
+
// Called when an object that was floating or positioned becomes a normal flow object
// again. We have to make sure the render tree updates as needed to accommodate the new
// normal flow object.
@@ -249,7 +254,6 @@ public:
bool normalChildNeedsLayout() const { return m_normalChildNeedsLayout; }
bool minMaxKnown() const{ return m_minMaxKnown; }
bool overhangingContents() const { return m_overhangingContents; }
- bool hasFirstLine() const { return m_hasFirstLine; }
bool isSelectionBorder() const { return m_isSelectionBorder; }
bool recalcMinMax() const { return m_recalcMinMax; }
@@ -709,7 +713,6 @@ private:
bool m_inline : 1;
bool m_replaced : 1;
bool m_mouseInside : 1;
- bool m_hasFirstLine : 1;
bool m_isSelectionBorder : 1;
void arenaDelete(RenderArena *arena, void *objectBase);
Index: khtml/rendering/render_style.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_style.cpp,v
retrieving revision 1.30
diff -u -p -r1.30 khtml/rendering/render_style.cpp
--- khtml/rendering/render_style.cpp 2003/10/21 22:14:37 1.30
+++ khtml/rendering/render_style.cpp 2003/10/23 21:15:57
@@ -333,7 +333,7 @@ bool RenderStyle::isStyleAvailable() con
}
enum EPseudoBit { NO_BIT = 0x0, BEFORE_BIT = 0x1, AFTER_BIT = 0x2, FIRST_LINE_BIT = 0x4,
- FIRST_LETTER_BIT = 0x8, SELECTION_BIT = 0x10 };
+ FIRST_LETTER_BIT = 0x8, SELECTION_BIT = 0x10, FIRST_LINE_INHERITED_BIT = 0x20 };
static int pseudoBit(RenderStyle::PseudoId pseudo)
{
@@ -348,6 +348,8 @@ static int pseudoBit(RenderStyle::Pseudo
return FIRST_LETTER_BIT;
case RenderStyle::SELECTION:
return SELECTION_BIT;
+ case RenderStyle::FIRST_LINE_INHERITED:
+ return FIRST_LINE_INHERITED_BIT;
default:
return NO_BIT;
}
Index: khtml/rendering/render_style.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_style.h,v
retrieving revision 1.33
diff -u -p -r1.33 khtml/rendering/render_style.h
--- khtml/rendering/render_style.h 2003/10/21 22:14:37 1.33
+++ khtml/rendering/render_style.h 2003/10/23 21:15:57
@@ -618,7 +618,7 @@ public:
static void cleanup();
// static pseudo styles. Dynamic ones are produced on the fly.
- enum PseudoId { NOPSEUDO, FIRST_LINE, FIRST_LETTER, BEFORE, AFTER, SELECTION };
+ enum PseudoId { NOPSEUDO, FIRST_LINE, FIRST_LETTER, BEFORE, AFTER, SELECTION, FIRST_LINE_INHERITED };
protected:
@@ -708,7 +708,7 @@ protected:
PseudoId _styleType : 3;
bool _affectedByHover : 1;
bool _affectedByActive : 1;
- int _pseudoBits : 5;
+ int _pseudoBits : 6;
EUnicodeBidi _unicodeBidi : 2;
} noninherited_flags;
Index: khtml/rendering/render_table.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_table.cpp,v
retrieving revision 1.80
diff -u -p -r1.80 khtml/rendering/render_table.cpp
--- khtml/rendering/render_table.cpp 2003/10/20 06:57:29 1.80
+++ khtml/rendering/render_table.cpp 2003/10/23 21:15:57
@@ -817,6 +817,14 @@ RenderTableCell* RenderTable::cellRight(
return (result == (RenderTableCell*)-1) ? 0 : result;
}
+RenderBlock* RenderTable::firstLineBlock() const
+{
+ return 0;
+}
+
+void RenderTable::updateFirstLetter()
+{}
+
#ifndef NDEBUG
void RenderTable::dump(QTextStream *stream, QString ind) const
{
Index: khtml/rendering/render_table.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_table.h,v
retrieving revision 1.29
diff -u -p -r1.29 khtml/rendering/render_table.h
--- khtml/rendering/render_table.h 2003/10/17 22:32:14 1.29
+++ khtml/rendering/render_table.h 2003/10/23 21:15:57
@@ -110,6 +110,9 @@ public:
virtual void calcMinMaxWidth();
virtual void close();
+ virtual RenderBlock* firstLineBlock() const;
+ virtual void updateFirstLetter();
+
virtual void setCellWidths( );
virtual void calcWidth();
Index: khtml/rendering/render_text.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/rendering/render_text.cpp,v
retrieving revision 1.89
diff -u -p -r1.89 khtml/rendering/render_text.cpp
--- khtml/rendering/render_text.cpp 2003/10/23 00:10:53 1.89
+++ khtml/rendering/render_text.cpp 2003/10/23 21:15:57
@@ -577,7 +577,8 @@ void RenderText::paintObject(QPainter *p
int tx, int ty, PaintAction paintAction)
{
int ow = style()->outlineWidth();
- RenderStyle* pseudoStyle = hasFirstLine() ? getPseudoStyle(RenderStyle::FIRST_LINE) : 0;
+ RenderStyle* pseudoStyle = style(true);
+ if (pseudoStyle == style()) pseudoStyle = 0;
int d = style()->textDecorationsInEffect();
InlineTextBox f(0, y-ty);
int si = m_lines.findFirstMatching(&f);
@@ -1335,15 +1336,7 @@ const QFontMetrics &RenderText::metrics(
const Font *RenderText::htmlFont(bool firstLine) const
{
- const Font *f = 0;
- if( firstLine && hasFirstLine() ) {
- RenderStyle* pseudoStyle = getPseudoStyle(RenderStyle::FIRST_LINE);
- if ( pseudoStyle )
- f = &pseudoStyle->htmlFont();
- } else {
- f = &style()->htmlFont();
- }
- return f;
+ return &style(firstLine)->htmlFont();
}
void RenderText::paintTextOutline(QPainter *p, int tx, int ty, const QRect &lastline, const QRect &thisline, const QRect &nextline)
Index: khtml/xml/dom_elementimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom_elementimpl.cpp,v
retrieving revision 1.22
diff -u -p -r1.22 khtml/xml/dom_elementimpl.cpp
--- khtml/xml/dom_elementimpl.cpp 2003/10/01 20:22:52 1.22
+++ khtml/xml/dom_elementimpl.cpp 2003/10/23 21:15:57
@@ -357,22 +357,20 @@ void ElementImpl::recalcStyle( StyleChan
qDebug("recalcStyle(%d: %s)[%p: %s]", change, debug, this, tagName().string().latin1());
#endif
if ( hasParentRenderer && (change >= Inherit || changed()) ) {
- EDisplay oldDisplay = _style ? _style->display() : NONE;
-
RenderStyle *newStyle = getDocument()->styleSelector()->styleForElement(this);
newStyle->ref();
StyleChange ch = diff( _style, newStyle );
- if ( ch != NoChange ) {
- if (oldDisplay != newStyle->display()) {
- if (attached()) detach();
- // ### Suboptimal. Style gets calculated again.
- attach();
- // attach recalulates the style for all children. No need to do it twice.
- setChanged( false );
- setHasChangedChild( false );
- newStyle->deref();
- return;
- }
+ if (ch == Detach) {
+ if (attached()) detach();
+ // ### Suboptimal. Style gets calculated again.
+ attach();
+ // attach recalulates the style for all children. No need to do it twice.
+ setChanged( false );
+ setHasChangedChild( false );
+ newStyle->deref();
+ return;
+ }
+ else if (ch != NoChange) {
if( m_render && newStyle ) {
//qDebug("--> setting style on render element bgcolor=%s", newStyle->backgroundColor().name().latin1());
m_render->setStyle(newStyle);
Index: khtml/xml/dom_nodeimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom_nodeimpl.cpp,v
retrieving revision 1.41
diff -u -p -r1.41 khtml/xml/dom_nodeimpl.cpp
--- khtml/xml/dom_nodeimpl.cpp 2003/10/20 17:28:10 1.41
+++ khtml/xml/dom_nodeimpl.cpp 2003/10/23 21:15:57
@@ -929,7 +929,13 @@ NodeImpl::StyleChange NodeImpl::diff( kh
// explicit inheritance of non-inherited properties and so you end up not re-resolving
// style in cases where you need to.
StyleChange ch = NoInherit;
- if ( !s1 || !s2 )
+ EDisplay display1 = s1 ? s1->display() : NONE;
+ bool fl1 = s1 ? s1->hasPseudoStyle(RenderStyle::FIRST_LETTER) : false;
+ EDisplay display2 = s2 ? s2->display() : NONE;
+ bool fl2 = s2 ? s2->hasPseudoStyle(RenderStyle::FIRST_LETTER) : false;
+ if (display1 != display2 || fl1 != fl2)
+ ch = Detach;
+ else if ( !s1 || !s2 )
ch = Inherit;
else if ( *s1 == *s2 )
ch = NoChange;
Index: khtml/xml/dom_nodeimpl.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom_nodeimpl.h,v
retrieving revision 1.23
diff -u -p -r1.23 khtml/xml/dom_nodeimpl.h
--- khtml/xml/dom_nodeimpl.h 2003/10/20 07:07:54 1.23
+++ khtml/xml/dom_nodeimpl.h 2003/10/23 21:15:57
@@ -213,7 +213,7 @@ public:
virtual void getCursor(int offset, int &_x, int &_y, int &height);
virtual QRect getRect() const;
- enum StyleChange { NoChange, NoInherit, Inherit, Force };
+ enum StyleChange { NoChange, NoInherit, Inherit, Detach, Force };
virtual void recalcStyle( StyleChange = NoChange ) {}
StyleChange diff( khtml::RenderStyle *s1, khtml::RenderStyle *s2 ) const;
-------------- next part --------------
dave
More information about the Khtml-devel
mailing list