Fix for relpositioned inlines. This was reviewed a long time ago, but I can't recal...
authorhyatt <hyatt@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 5 Nov 2004 02:59:48 +0000 (02:59 +0000)
committerhyatt <hyatt@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 5 Nov 2004 02:59:48 +0000 (02:59 +0000)
darin or ken).

        Reviewed by darin or ken

        * khtml/rendering/bidi.cpp:
        (khtml::appendRunsForObject):
        (khtml::RenderBlock::skipWhitespace):
        (khtml::RenderBlock::findNextLineBreak):
        * khtml/rendering/render_block.cpp:
        (khtml::RenderBlock::lowestPosition):
        (khtml::RenderBlock::rightmostPosition):
        (khtml::RenderBlock::leftmostPosition):
        * khtml/rendering/render_box.cpp:
        (RenderBox::position):
        * khtml/rendering/render_box.h:
        (khtml::RenderBox::staticX):
        (khtml::RenderBox::staticY):
        * khtml/rendering/render_layer.cpp:
        (RenderLayer::updateLayerPosition):
        (RenderLayer::convertToLayerCoords):
        * khtml/rendering/render_line.cpp:
        (khtml::InlineFlowBox::placeBoxesHorizontally):
        * khtml/rendering/render_object.h:
        (khtml::RenderObject::staticX):
        (khtml::RenderObject::staticY):

Finish turning on XSLT.  Make sure child stylesheets can load.

        * khtml/xsl/xslt_processorimpl.cpp:
        (DOM::stylesheetLoadFunc):
        (DOM::XSLTProcessorImpl::transformDocument):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@7941 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog-2005-08-23
WebCore/khtml/rendering/bidi.cpp
WebCore/khtml/rendering/render_block.cpp
WebCore/khtml/rendering/render_box.cpp
WebCore/khtml/rendering/render_box.h
WebCore/khtml/rendering/render_layer.cpp
WebCore/khtml/rendering/render_line.cpp
WebCore/khtml/rendering/render_object.h
WebCore/khtml/xsl/xslt_processorimpl.cpp

index 57cf1e114a6150fbbd61c659a5c75cbfe6def49e..bcbc183643b5a8906effe104c29c7cbc38d07b88 100644 (file)
@@ -1,3 +1,38 @@
+2004-11-04  David Hyatt  <hyatt@apple.com>
+
+       Fix for relpositioned inlines.  This was reviewed a long time ago, but I can't recall who reviewed it (either
+       darin or ken).
+       
+        Reviewed by darin or ken
+
+        * khtml/rendering/bidi.cpp:
+        (khtml::appendRunsForObject):
+        (khtml::RenderBlock::skipWhitespace):
+        (khtml::RenderBlock::findNextLineBreak):
+        * khtml/rendering/render_block.cpp:
+        (khtml::RenderBlock::lowestPosition):
+        (khtml::RenderBlock::rightmostPosition):
+        (khtml::RenderBlock::leftmostPosition):
+        * khtml/rendering/render_box.cpp:
+        (RenderBox::position):
+        * khtml/rendering/render_box.h:
+        (khtml::RenderBox::staticX):
+        (khtml::RenderBox::staticY):
+        * khtml/rendering/render_layer.cpp:
+        (RenderLayer::updateLayerPosition):
+        (RenderLayer::convertToLayerCoords):
+        * khtml/rendering/render_line.cpp:
+        (khtml::InlineFlowBox::placeBoxesHorizontally):
+        * khtml/rendering/render_object.h:
+        (khtml::RenderObject::staticX):
+        (khtml::RenderObject::staticY):
+
+       Finish turning on XSLT.  Make sure child stylesheets can load.
+       
+        * khtml/xsl/xslt_processorimpl.cpp:
+        (DOM::stylesheetLoadFunc):
+        (DOM::XSLTProcessorImpl::transformDocument):
+
 2004-11-04  David Hyatt  <hyatt@apple.com>
 
        Implement CSS3 support for multiple backgrounds.  Also fix a bug with background propagation so that it only
index 8ec51ba40d31425f6a5470b147d883537807b57b..9a412b17eb2423d59946ac7303060dc176ef9910 100644 (file)
@@ -499,7 +499,7 @@ static void addMidpoint(const BidiIterator& midpoint)
 static void appendRunsForObject(int start, int end, RenderObject* obj, BidiState &bidi)
 {
     if (start > end || obj->isFloating() ||
-        (obj->isPositioned() && !obj->hasStaticX() && !obj->hasStaticY()))
+        (obj->isPositioned() && !obj->hasStaticX() && !obj->hasStaticY() && !obj->container()->isInlineFlow()))
         return;
 
     bool haveNextMidpoint = (smidpoints && sCurrMidpoint < sNumMidpoints);
@@ -1755,7 +1755,11 @@ inline bool RenderBlock::skipNonBreakingSpace(BidiIterator &it)
 
 int RenderBlock::skipWhitespace(BidiIterator &it, BidiState &bidi)
 {
-    int width = lineWidth(m_height);
+    // FIXME: The entire concept of the skipWhitespace function is flawed, since we really need to be building
+    // line boxes even for containers that may ultimately collapse away.  Otherwise we'll never get positioned
+    // elements quite right.  In other words, we need to build this function's work into the normal line
+    // object iteration process.
+    int w = lineWidth(m_height);
     while (!it.atEnd() && (it.obj->isInlineFlow() || (it.obj->style()->whiteSpace() != PRE && !it.obj->isBR() &&
           (it.current() == ' ' || it.current() == '\n' || 
            skipNonBreakingSpace(it) || it.obj->isFloatingOrPositioned())))) {
@@ -1765,13 +1769,32 @@ int RenderBlock::skipWhitespace(BidiIterator &it, BidiState &bidi)
             if (o->isFloating()) {
                 insertFloatingObject(o);
                 positionNewFloats();
-                width = lineWidth(m_height);
+                w = lineWidth(m_height);
             }
             else if (o->isPositioned()) {
-                if (o->hasStaticX())
-                    o->setStaticX(style()->direction() == LTR ?
-                                  borderLeft()+paddingLeft() :
-                                  borderRight()+paddingRight());
+                // FIXME: The math here is actually not really right.  It's a best-guess approximation that
+                // will work for the common cases
+                RenderObject* c = o->container();
+                if (c->isInlineFlow()) {
+                    // A relative positioned inline encloses us.  In this case, we also have to determine our
+                    // position as though we were an inline.  Set |staticX| and |staticY| on the relative positioned
+                    // inline so that we can obtain the value later.
+                    c->setStaticX(style()->direction() == LTR ?
+                                  leftOffset(m_height) : rightOffset(m_height));
+                    c->setStaticY(m_height);
+                }
+                
+                if (o->hasStaticX()) {
+                    bool wasInline = o->style()->isOriginalDisplayInlineType();
+                    if (wasInline)
+                        o->setStaticX(style()->direction() == LTR ?
+                                      leftOffset(m_height) :
+                                      width() - rightOffset(m_height));
+                    else
+                        o->setStaticX(style()->direction() == LTR ?
+                                      borderLeft() + paddingLeft() :
+                                      borderRight() + paddingRight());
+                }
                 if (o->hasStaticY())
                     o->setStaticY(m_height);
             }
@@ -1781,7 +1804,7 @@ int RenderBlock::skipWhitespace(BidiIterator &it, BidiState &bidi)
         it.increment(bidi);
         adjustEmbedding = false;
     }
-    return width;
+    return w;
 }
 
 BidiIterator RenderBlock::findNextLineBreak(BidiIterator &start, BidiState &bidi)
@@ -1796,10 +1819,8 @@ BidiIterator RenderBlock::findNextLineBreak(BidiIterator &start, BidiState &bidi
 
     // eliminate spaces at beginning of line
     width = skipWhitespace(start, bidi);
-    
-    if ( start.atEnd() ){
+    if (start.atEnd())
         return start;
-    }
 
     // This variable is used only if whitespace isn't set to PRE, and it tells us whether
     // or not we are currently ignoring whitespace.
@@ -1882,9 +1903,14 @@ BidiIterator RenderBlock::findNextLineBreak(BidiIterator &start, BidiState &bidi
                     needToSetStaticY = false;
                 }
                 
+                bool needToCreateLineBox = needToSetStaticX || needToSetStaticY;
+                RenderObject* c = o->container();
+                if (c->isInlineFlow() && (!needToSetStaticX || !needToSetStaticY))
+                    needToCreateLineBox = true;
+
                 // If we're ignoring spaces, we have to stop and include this object and
                 // then start ignoring spaces again.
-                if (needToSetStaticX || needToSetStaticY) {
+                if (needToCreateLineBox) {
                     trailingSpaceObject = 0;
                     ignoreStart.obj = o;
                     ignoreStart.pos = 0;
index cc8328a122f313a7594492bfa3352ebc478cee90..61c6b8e8ac4f60a8fb2ba141fb9b42bf0e803843 100644 (file)
@@ -2013,7 +2013,9 @@ RenderBlock::lowestPosition(bool includeOverflowInterior, bool includeSelf) cons
         RenderObject* r;
         QPtrListIterator<RenderObject> it(*m_positionedObjects);
         for ( ; (r = it.current()); ++it ) {
-            int lp = r->yPos() + r->lowestPosition(false);
+            // Use the layer's position, since it has been corrected for crazy relpositioned inline
+            // edge cases.
+            int lp = r->layer()->yPos() + r->lowestPosition(false);
             bottom = kMax(bottom, lp);
         }
     }
@@ -2049,7 +2051,9 @@ int RenderBlock::rightmostPosition(bool includeOverflowInterior, bool includeSel
         RenderObject* r;
         QPtrListIterator<RenderObject> it(*m_positionedObjects);
         for ( ; (r = it.current()); ++it ) {
-            int rp = r->xPos() + r->rightmostPosition(false);
+            // Use the layer's position, since it has been corrected for crazy relpositioned inline
+            // edge cases.
+            int rp = r->layer()->xPos() + r->rightmostPosition(false);
             right = kMax(right, rp);
         }
     }
@@ -2087,7 +2091,9 @@ int RenderBlock::leftmostPosition(bool includeOverflowInterior, bool includeSelf
         RenderObject* r;
         QPtrListIterator<RenderObject> it(*m_positionedObjects);
         for ( ; (r = it.current()); ++it ) {
-            int lp = r->xPos() + r->leftmostPosition(false);
+            // Use the layer's position, since it has been corrected for crazy relpositioned inline
+            // edge cases.
+            int lp = r->layer()->xPos() + r->leftmostPosition(false);
             left = kMin(left, lp);
         }
     }
index f1cd636afc367e926af783f2e09730cfbe6c74e0..ccd9fd7df3d1e0addd188f17f77b548d6215e380 100644 (file)
@@ -585,8 +585,7 @@ void RenderBox::position(InlineBox* box, int from, int len, bool reverse)
 {
     if (isPositioned()) {
         // Cache the x position only if we were an INLINE type originally.
-        bool wasInline = style()->originalDisplay() == INLINE ||
-                         style()->originalDisplay() == INLINE_TABLE;
+        bool wasInline = style()->isOriginalDisplayInlineType();
         if (wasInline && hasStaticX()) {
             // The value is cached in the xPos of the box.  We only need this value if
             // our object was inline originally, since otherwise it would have ended up underneath
index 2dd310027eac6f56314e216dbc164392e82a71f8..62602b7880e9e607fdd3c97f66eb28bd36db9cb2 100644 (file)
@@ -138,6 +138,8 @@ public:
 
     virtual void setStaticX(int staticX);
     virtual void setStaticY(int staticY);
+    virtual int staticX() const { return m_staticX; }
+    virtual int staticY() const { return m_staticY; }
 
 protected:
     virtual void paintBoxDecorations(PaintInfo& i, int _tx, int _ty);
index 365c450674a59bcb5142fe9d122704e07913cd42..f247cd588693248feb6daca7358cac483b32d57f 100644 (file)
@@ -182,9 +182,44 @@ void RenderLayer::updateLayerPosition()
     }
     
     // Subtract our parent's scroll offset.
-    if (m_object->isPositioned())
+    if (m_object->isPositioned()) {
+        RenderLayer* positionedParent = enclosingPositionedAncestor();
+
         // For positioned layers, we subtract out the enclosing positioned layer's scroll offset.
-        enclosingPositionedAncestor()->subtractScrollOffset(x, y);
+        positionedParent->subtractScrollOffset(x, y);
+        
+        if (m_object->isPositioned() && positionedParent->renderer()->isRelPositioned() &&
+            positionedParent->renderer()->isInlineFlow()) {
+            // When we have an enclosing relpositioned inline, we need to add in the offset of the first line
+            // box from the rest of the content, but only in the cases where we know we're positioned
+            // relative to the inline itself.
+            RenderFlow* flow = static_cast<RenderFlow*>(positionedParent->renderer());
+            int sx = 0, sy = 0;
+            if (flow->firstLineBox()) {
+                sx = flow->firstLineBox()->xPos();
+                sy = flow->firstLineBox()->yPos();
+            }
+            else {
+                sx = flow->staticX();
+                sy = flow->staticY();
+            }
+            bool isInlineType = m_object->style()->isOriginalDisplayInlineType();
+            
+            if (!m_object->hasStaticX())
+                x += sx;
+            
+            // This is not terribly intuitive, but we have to match other browsers.  Despite being a block display type inside
+            // an inline, we still keep our x locked to the left of the relative positioned inline.  Arguably the correct
+            // behavior would be to go flush left to the block that contains the inline, but that isn't what other browsers
+            // do.
+            if (m_object->hasStaticX() && !isInlineType)
+                // Avoid adding in the left border/padding of the containing block twice.  Subtract it out.
+                x += sx - (m_object->containingBlock()->borderLeft() + m_object->containingBlock()->paddingLeft());
+            
+            if (!m_object->hasStaticY())
+                y += sy;
+        }
+    }
     else
         parent()->subtractScrollOffset(x, y);
     
@@ -398,21 +433,6 @@ RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& x, int&
     
     parentLayer->convertToLayerCoords(ancestorLayer, x, y);
 
-    if (m_object->style()->position() == ABSOLUTE && parentLayer->renderer()->style()->position() == RELATIVE &&
-        parentLayer->renderer()->isInline() && !parentLayer->renderer()->isReplaced()) {
-        // When we have an enclosing relpositioned inline, we need to add in the offset of the first line
-        // box from the rest of the content, but only in the cases where we know we're positioned
-        // relative to the inline itself.
-        RenderFlow* flow = static_cast<RenderFlow*>(parentLayer->renderer());
-        if (flow->firstLineBox()) {
-            bool isInlineType = m_object->style()->isOriginalDisplayInlineType();
-            if (!m_object->hasStaticX() || (m_object->hasStaticX() && !isInlineType))
-                x += flow->firstLineBox()->xPos();
-            if (!m_object->hasStaticY())
-                y += flow->firstLineBox()->yPos();
-        }
-    }
-    
     x += xPos();
     y += yPos();
 }
index dbb07b9d5a2f391b30f5948e7d5bb821244024f0..e2cd3b7f83c1f2da8fcaf045b873c123f3dba144 100644 (file)
@@ -452,15 +452,11 @@ int InlineFlowBox::placeBoxesHorizontally(int x)
             if (curr->object()->isPositioned()) {
                 if (curr->object()->parent()->style()->direction() == LTR)
                     curr->setXPos(x);
-                else {
+                else
                     // Our offset that we cache needs to be from the edge of the right border box and
                     // not the left border box.  We have to subtract |x| from the width of the block
-                    // (which can be obtained by walking up to the root line box).
-                    InlineBox* root = this;
-                    while (!root->isRootInlineBox())
-                        root = root->parent();
-                    curr->setXPos(root->object()->width()-x);
-                }
+                    // (which can be obtained from the root line box).
+                    curr->setXPos(root()->object()->width()-x);
                 continue; // The positioned object has no effect on the width.
             }
             if (curr->object()->isInlineFlow()) {
index 2a78d4c055dc412db8fb53595c1cc34682c2dc0a..8b5fb98dd1996196dacbd89afaa47e94d89ca3f9 100644 (file)
@@ -186,6 +186,8 @@ public:
     bool hasStaticY() const;
     virtual void setStaticX(int staticX) {};
     virtual void setStaticY(int staticY) {};
+    virtual int staticX() const { return 0; }
+    virtual int staticY() const { return 0; }
     
     // RenderObject tree manipulation
     //////////////////////////////////////////
index c540671d99d967318f0af7bfe521fef2ce57116c..8bd8eb91079fb2f9eda97d9b4fc0b7643f79a493 100644 (file)
@@ -54,7 +54,6 @@ XSLTProcessorImpl::~XSLTProcessorImpl()
         m_sourceDocument->deref();
 }
 
-#ifdef NOT_YET_READY
 static XSLStyleSheetImpl* globalSheet = 0;
 static xmlDocPtr stylesheetLoadFunc(const xmlChar* uri,
                                     xmlDictPtr dict,
@@ -69,7 +68,6 @@ static xmlDocPtr stylesheetLoadFunc(const xmlChar* uri,
         return NULL;
     return globalSheet->locateStylesheetSubResource(((xsltStylesheetPtr)ctxt)->doc, uri);
 }
-#endif
 
 DocumentImpl* XSLTProcessorImpl::transformDocument(DocumentImpl* doc)
 {
@@ -79,17 +77,13 @@ DocumentImpl* XSLTProcessorImpl::transformDocument(DocumentImpl* doc)
 
     if (!m_stylesheet || !m_stylesheet->document()) return 0;
         
-#ifdef NOT_YET_READY
     globalSheet = m_stylesheet;
     xsltSetLoaderFunc(stylesheetLoadFunc);
-#endif
 
     xsltStylesheetPtr sheet = m_stylesheet->compileStyleSheet();
 
-#ifdef NOT_YET_READY
     globalSheet = 0;
     xsltSetLoaderFunc(0);
-#endif
 
     if (!sheet) return 0;
     m_stylesheet->clearDocuments();