Make sure the class attribute works when newlines are present in the attribute.
authorhyatt <hyatt@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 Dec 2004 00:36:32 +0000 (00:36 +0000)
committerhyatt <hyatt@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 Dec 2004 00:36:32 +0000 (00:36 +0000)
        Reviewed by kocienda

        * khtml/html/html_elementimpl.cpp:
        (HTMLNamedAttrMapImpl::parseClassAttribute):

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

LayoutTests/fast/css/008-expected.txt [new file with mode: 0644]
LayoutTests/fast/css/008.html [new file with mode: 0644]
WebCore/ChangeLog-2005-08-23
WebCore/khtml/html/html_elementimpl.cpp
WebCore/khtml/rendering/render_block.cpp
WebCore/khtml/rendering/render_block.h

diff --git a/LayoutTests/fast/css/008-expected.txt b/LayoutTests/fast/css/008-expected.txt
new file mode 100644 (file)
index 0000000..05fc6c4
--- /dev/null
@@ -0,0 +1,10 @@
+layer at (0,0) size 800x600
+  RenderCanvas 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 784x48 [border: (10px solid #808000)]
+        RenderText {TEXT} at (10,10) size 563x28
+          text run at (10,10) width 180: "You should see 24"
+          text run at (190,10) width 177: "px text inside a 10"
+          text run at (367,10) width 206: "px solid olive border."
diff --git a/LayoutTests/fast/css/008.html b/LayoutTests/fast/css/008.html
new file mode 100644 (file)
index 0000000..da72826
--- /dev/null
@@ -0,0 +1,11 @@
+<head>
+<style>
+.a { border:10px solid olive; }
+.b { font-size: 24px; }
+</style>
+</head>
+<body>
+<div class="a
+b">
+You should see 24px text inside a 10px solid olive border.
+</div>
index 12a12b0..dcf754f 100644 (file)
@@ -1,3 +1,27 @@
+2004-12-14  David Hyatt  <hyatt@apple.com>
+
+       Make sure the class attribute works when newlines are present in the attribute.
+
+        Reviewed by kocienda
+
+        * khtml/html/html_elementimpl.cpp:
+        (HTMLNamedAttrMapImpl::parseClassAttribute):
+
+2004-12-14  David Hyatt  <hyatt@apple.com>
+
+       Fix for 3724938, float element is duplicated and paints twice.  The logic for when to paint floats was
+       actually fairly screwed up.  This patch simplifies the logic and makes addOverhangingFloats easier to
+       read by splitting it into two separate functions.
+       
+        Reviewed by kocienda
+
+        * khtml/rendering/render_block.cpp:
+        (khtml::RenderBlock::layoutBlockChildren):
+        (khtml::RenderBlock::clearFloats):
+        (khtml::RenderBlock::addOverhangingFloats):
+        (khtml::RenderBlock::addIntrudingFloats):
+        * khtml/rendering/render_block.h:
+
 2004-12-14  John Sullivan  <sullivan@apple.com>
 
         Reviewed by Ken.
 2004-12-14  John Sullivan  <sullivan@apple.com>
 
         Reviewed by Ken.
index e1bdd19..ab0ca2c 100644 (file)
@@ -179,15 +179,15 @@ void HTMLNamedAttrMapImpl::parseClassAttribute(const DOMString& classStr)
         (classStr.implementation()->isLower() ? classStr : DOMString(classStr.implementation()->lower())) :
         classStr;
     
         (classStr.implementation()->isLower() ? classStr : DOMString(classStr.implementation()->lower())) :
         classStr;
     
-    if (classAttr.find(' ') == -1)
+    if (classAttr.find(' ') == -1 && classAttr.find('\n') == -1)
         m_classList.setString(AtomicString(classAttr));
     else {
         QString val = classAttr.string();
         m_classList.setString(AtomicString(classAttr));
     else {
         QString val = classAttr.string();
+        val.replace('\n', ' ');
         QStringList list = QStringList::split(' ', val);
         
         AtomicStringList* curr = 0;
         QStringList list = QStringList::split(' ', val);
         
         AtomicStringList* curr = 0;
-        for (QStringList::Iterator it = list.begin(); it != list.end(); ++it)
-        {
+        for (QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
             const QString& singleClass = *it;
             if (!singleClass.isEmpty()) {
                 if (curr) {
             const QString& singleClass = *it;
             if (!singleClass.isEmpty()) {
                 if (curr) {
index 30438e7..705d414 100644 (file)
@@ -1090,10 +1090,9 @@ void RenderBlock::layoutBlockChildren(bool relayoutChildren)
         if (m_height + overflowDelta > m_overflowHeight)
             m_overflowHeight = m_height + overflowDelta;
 
         if (m_height + overflowDelta > m_overflowHeight)
             m_overflowHeight = m_height + overflowDelta;
 
-        if (child->hasOverhangingFloats() && !child->hasOverflowClip())
-            // need to add the child's floats to our floating objects list, but not in the case where
-            // overflow is auto/scroll
-            addOverHangingFloats(static_cast<RenderBlock *>(child), -child->xPos(), -child->yPos(), true);
+        // If the child has overhanging floats that intrude into following siblings (or possibly out
+        // of this block), then the parent gets notified of the floats now.
+        addOverhangingFloats(static_cast<RenderBlock *>(child), -child->xPos(), -child->yPos());
 
         // See if this child has made our overflow need to grow.
         int rightChildPos = child->xPos() + kMax(child->overflowWidth(false), child->width());
 
         // See if this child has made our overflow need to grow.
         int rightChildPos = child->xPos() + kMax(child->overflowWidth(false), child->width());
@@ -2217,8 +2216,8 @@ RenderBlock::clearFloats()
     // First add in floats from the parent.
     int offset = m_y;
     if (parentHasFloats)
     // First add in floats from the parent.
     int offset = m_y;
     if (parentHasFloats)
-        addOverHangingFloats( static_cast<RenderBlock *>( parent() ),
-                              parent()->borderLeft() + parent()->paddingLeft(), offset, false );
+        addIntrudingFloats(static_cast<RenderBlock *>(parent()),
+                           parent()->borderLeft() + parent()->paddingLeft(), offset);
 
     int xoffset = 0;
     if (prev)
 
     int xoffset = 0;
     if (prev)
@@ -2234,68 +2233,103 @@ RenderBlock::clearFloats()
     RenderBlock* block = static_cast<RenderBlock *>(prev);
     if (!block->m_floatingObjects) return;
     if (block->floatBottom() > offset)
     RenderBlock* block = static_cast<RenderBlock *>(prev);
     if (!block->m_floatingObjects) return;
     if (block->floatBottom() > offset)
-        addOverHangingFloats(block, xoffset, offset);
+        addIntrudingFloats(block, xoffset, offset);
 }
 
 }
 
-void RenderBlock::addOverHangingFloats( RenderBlock *flow, int xoff, int offset, bool child )
+void RenderBlock::addOverhangingFloats(RenderBlock* child, int xoff, int yoff)
 {
 {
-#ifdef DEBUG_LAYOUT
-    kdDebug( 6040 ) << (void *)this << ": adding overhanging floats xoff=" << xoff << "  offset=" << offset << " child=" << child << endl;
-#endif
-
     // Prevent floats from being added to the canvas by the root element, e.g., <html>.
     // Prevent floats from being added to the canvas by the root element, e.g., <html>.
-    if ( !flow->m_floatingObjects || (child && flow->isRoot()) )
+    if (child->hasOverflowClip() || !child->hasOverhangingFloats() || child->isRoot())
         return;
 
         return;
 
-    // we have overhanging floats
-    if (!m_floatingObjects) {
-        m_floatingObjects = new QPtrList<FloatingObject>;
-        m_floatingObjects->setAutoDelete(true);
-    }
+    QPtrListIterator<FloatingObject> it(*child->m_floatingObjects);
+    for (FloatingObject *r; (r = it.current()); ++it) {
+        if (child->yPos() + r->endY > height()) {
+            // The object may already be in our list. Check for it up front to avoid
+            // creating duplicate entries.
+            FloatingObject* f = 0;
+            if (m_floatingObjects) {
+                QPtrListIterator<FloatingObject> it(*m_floatingObjects);
+                while ((f = it.current())) {
+                    if (f->node == r->node) break;
+                    ++it;
+                }
+            }
 
 
-    QPtrListIterator<FloatingObject> it(*flow->m_floatingObjects);
-    FloatingObject *r;
-    for ( ; (r = it.current()); ++it ) {
-        if ( ( !child && r->endY > offset ) ||
-             ( child && flow->yPos() + r->endY > height() ) ) {
+            // If the object is not in the list, we add it now.
+            if (!f) {
+                FloatingObject *floatingObj = new FloatingObject(r->type);
+                floatingObj->startY = r->startY - yoff;
+                floatingObj->endY = r->endY - yoff;
+                floatingObj->left = r->left - xoff;
+                
+                // The nearest enclosing layer always paints the float (so that zindex and stacking
+                // behaves properly).  We always want to propagate the desire to paint the float as
+                // far out as we can, to the outermost block that overlaps the float, stopping only
+                // if we hit a layer boundary.
+                if (r->noPaint || child->enclosingLayer() != enclosingLayer())
+                    floatingObj->noPaint = true;
+                else {
+                    floatingObj->noPaint = false;
+                    r->noPaint = true;
+                }
 
 
-            if (child && (flow->enclosingLayer() == enclosingLayer()))
-                // Set noPaint to true only if we didn't cross layers.
-                r->noPaint = true;
+                floatingObj->width = r->width;
+                floatingObj->node = r->node;
+                
+                // We create the floating object list lazily.
+                if (!m_floatingObjects) {
+                    m_floatingObjects = new QPtrList<FloatingObject>;
+                    m_floatingObjects->setAutoDelete(true);
+                }
+                m_floatingObjects->append(floatingObj);
+            }
+        }
+    }
+}
+
+void RenderBlock::addIntrudingFloats(RenderBlock* prev, int xoff, int yoff)
+{
+    // If the parent or previous sibling doesn't have any floats to add, don't bother.
+    if (!prev->m_floatingObjects)
+        return;
 
 
+    QPtrListIterator<FloatingObject> it(*prev->m_floatingObjects);
+    for (FloatingObject *r; (r = it.current()); ++it) {
+        if (r->endY > yoff) {
+            // The object may already be in our list. Check for it up front to avoid
+            // creating duplicate entries.
             FloatingObject* f = 0;
             FloatingObject* f = 0;
-            // don't insert it twice!
-            QPtrListIterator<FloatingObject> it(*m_floatingObjects);
-            while ( (f = it.current()) ) {
-                if (f->node == r->node) break;
-                ++it;
+            if (m_floatingObjects) {
+                QPtrListIterator<FloatingObject> it(*m_floatingObjects);
+                while ((f = it.current())) {
+                    if (f->node == r->node) break;
+                    ++it;
+                }
             }
             }
-            if ( !f ) {
+            if (!f) {
                 FloatingObject *floatingObj = new FloatingObject(r->type);
                 FloatingObject *floatingObj = new FloatingObject(r->type);
-                floatingObj->startY = r->startY - offset;
-                floatingObj->endY = r->endY - offset;
+                floatingObj->startY = r->startY - yoff;
+                floatingObj->endY = r->endY - yoff;
                 floatingObj->left = r->left - xoff;
                 // Applying the child's margin makes no sense in the case where the child was passed in.
                 // since his own margin was added already through the subtraction of the |xoff| variable
                 // above.  |xoff| will equal -flow->marginLeft() in this case, so it's already been taken
                 // into account.  Only apply this code if |child| is false, since otherwise the left margin
                 // will get applied twice.
                 floatingObj->left = r->left - xoff;
                 // Applying the child's margin makes no sense in the case where the child was passed in.
                 // since his own margin was added already through the subtraction of the |xoff| variable
                 // above.  |xoff| will equal -flow->marginLeft() in this case, so it's already been taken
                 // into account.  Only apply this code if |child| is false, since otherwise the left margin
                 // will get applied twice.
-                if (!child && flow != parent())
-                    floatingObj->left += flow->marginLeft();
-                if ( !child ) {
-                    floatingObj->left -= marginLeft();
-                    floatingObj->noPaint = true;
-                }
-                else
-                    // Only paint if |flow| isn't.
-                    floatingObj->noPaint = !r->noPaint;
-                
+                if (prev != parent())
+                    floatingObj->left += prev->marginLeft();
+                floatingObj->left -= marginLeft();
+                floatingObj->noPaint = true;
                 floatingObj->width = r->width;
                 floatingObj->node = r->node;
                 floatingObj->width = r->width;
                 floatingObj->node = r->node;
+                
+                // We create the floating object list lazily.
+                if (!m_floatingObjects) {
+                    m_floatingObjects = new QPtrList<FloatingObject>;
+                    m_floatingObjects->setAutoDelete(true);
+                }
                 m_floatingObjects->append(floatingObj);
                 m_floatingObjects->append(floatingObj);
-#ifdef DEBUG_LAYOUT
-                kdDebug( 6040 ) << "addOverHangingFloats x/y= (" << floatingObj->left << "/" << floatingObj->startY << "-" << floatingObj->width << "/" << floatingObj->endY - floatingObj->startY << ")" << endl;
-#endif
             }
         }
     }
             }
         }
     }
index f85c263..e36e6e1 100644 (file)
@@ -154,8 +154,9 @@ public:
     virtual bool containsFloat(RenderObject* o);
 
     virtual bool hasOverhangingFloats() { return floatBottom() > m_height; }
     virtual bool containsFloat(RenderObject* o);
 
     virtual bool hasOverhangingFloats() { return floatBottom() > m_height; }
-    void addOverHangingFloats( RenderBlock *block, int xoffset, int yoffset, bool child = false );
-    
+    void addIntrudingFloats(RenderBlock* prev, int xoffset, int yoffset);
+    void addOverhangingFloats(RenderBlock* child, int xoffset, int yoffset);
+
     int nearestFloatBottom(int height) const;
     int floatBottom() const;
     inline int leftBottom();
     int nearestFloatBottom(int height) const;
     int floatBottom() const;
     inline int leftBottom();