PATCH: safari patch splitup: FOUC fixups (update)

Alexander Kellett lypanov at kde.org
Thu Jan 9 20:48:19 GMT 2003


hiya dirk / lars / rest,

a new patch, last one had a crash on chromium/x15 page
found the relevant (and ugly by the looks of it) fix.
can't crash it any more.

mvg,
Alex

-- 
"[...] Konqueror open source project. Weighing in at less than
            one tenth the size of another open source renderer"
Apple,  Jan 2003 (http://www.apple.com/safari/)
-------------- next part --------------
Index: css/cssstyleselector.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/css/cssstyleselector.cpp,v
retrieving revision 1.246
diff -u -p -B -w -r1.246 cssstyleselector.cpp
--- css/cssstyleselector.cpp	9 Jan 2003 07:14:24 -0000	1.246
+++ css/cssstyleselector.cpp	9 Jan 2003 20:47:46 -0000
@@ -73,6 +73,7 @@ CSSStyleSelectorList *CSSStyleSelector::
 CSSStyleSelectorList *CSSStyleSelector::defaultQuirksStyle = 0;
 CSSStyleSelectorList *CSSStyleSelector::defaultPrintStyle = 0;
 CSSStyleSheetImpl *CSSStyleSelector::defaultSheet = 0;
+RenderStyle* CSSStyleSelector::styleNotYetAvailable = 0;
 
 enum PseudoState { PseudoUnknown, PseudoNone, PseudoLink, PseudoVisited};
 static PseudoState pseudoState;
@@ -220,10 +221,12 @@ void CSSStyleSelector::clear()
     delete defaultQuirksStyle;
     delete defaultPrintStyle;
     delete defaultSheet;
+    delete styleNotYetAvailable;
     defaultStyle = 0;
     defaultQuirksStyle = 0;
     defaultPrintStyle = 0;
     defaultSheet = 0;
+    styleNotYetAvailable = 0;
 }
 
 #define MAXFONTSIZES 15
@@ -292,6 +295,15 @@ static inline void bubbleSort( CSSOrdere
 
 RenderStyle *CSSStyleSelector::styleForElement(ElementImpl *e, int state)
 {
+    if (!e->getDocument()->haveStylesheetsLoaded()) {
+        if (!styleNotYetAvailable) {
+            styleNotYetAvailable = new RenderStyle();
+            styleNotYetAvailable->setDisplay(NONE);
+            styleNotYetAvailable->ref();
+        }
+        return styleNotYetAvailable;
+    }
+
     // set some variables we will need
     dynamicState = state;
     usedDynamicStates = StyleSelector::None;
Index: css/cssstyleselector.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/css/cssstyleselector.h,v
retrieving revision 1.30
diff -u -p -B -w -r1.30 cssstyleselector.h
--- css/cssstyleselector.h	8 Jan 2003 18:15:50 -0000	1.30
+++ css/cssstyleselector.h	9 Jan 2003 20:47:46 -0000
@@ -162,6 +162,9 @@ namespace khtml
 	CSSStyleSelectorList *authorStyle;
         CSSStyleSelectorList *userStyle;
         DOM::CSSStyleSheetImpl *userSheet;
+     public:
+	static RenderStyle *styleNotYetAvailable;
+    
 
 public:
     private:
Index: html/html_baseimpl.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/html/html_baseimpl.cpp,v
retrieving revision 1.174
diff -u -p -B -w -r1.174 html_baseimpl.cpp
--- html/html_baseimpl.cpp	9 Jan 2003 14:25:00 -0000	1.174
+++ html/html_baseimpl.cpp	9 Jan 2003 20:47:46 -0000
@@ -297,7 +297,6 @@ void HTMLFrameElementImpl::attach()
 {
     assert(!attached());
     assert(parentNode());
-    assert(parentNode()->renderer());
 
     // we should first look up via id, then via name.
     // this shortterm hack fixes the ugly case. ### rewrite needed for next release
@@ -322,7 +321,7 @@ void HTMLFrameElementImpl::attach()
     // ignore display: none for this element!
     KHTMLView* w = getDocument()->view();
 
-    if (isURLAllowed())  {
+    if (isURLAllowed() && parentNode()->renderer())  {
         m_render = new RenderFrame(this);
         m_render->setStyle(getDocument()->styleSelector()->styleForElement(this));
         parentNode()->renderer()->addChild(m_render, nextRenderer());
@@ -369,12 +368,14 @@ void HTMLFrameElementImpl::setFocus(bool
 
 DocumentImpl* HTMLFrameElementImpl::contentDocument() const
 {
-    if ( !m_render ) return 0;
-
-    RenderPart* render = static_cast<RenderPart*>( m_render );
+    KHTMLView* w = getDocument()->view();
 
-    if(render->widget() && render->widget()->inherits("KHTMLView"))
-        return static_cast<KHTMLView*>( render->widget() )->part()->xmlDocImpl();
+    if (w) {
+        KHTMLPart *part = w->part()->findFrame( name.string() );
+        if (part) {
+            return part->xmlDocImpl();
+        }
+    }
 
     return 0;
 }
@@ -476,10 +477,16 @@ void HTMLFrameSetElementImpl::attach()
         node = static_cast<HTMLElementImpl*>(node->parentNode());
     }
 
-    // ignore display: none
+    // ignore display: none but do pay attention if a stylesheet has caused us to delay
+    // our loading.
+    RenderStyle* style = getDocument()->styleSelector()->styleForElement(this);
+    style->ref();
+    if (style->isStyleAvailable()) {
     m_render = new RenderFrameSet(this);
-    m_render->setStyle(getDocument()->styleSelector()->styleForElement(this));
+        m_render->setStyle(style);
     parentNode()->renderer()->addChild(m_render, nextRenderer());
+    }
+    style->deref();
 
     NodeBaseImpl::attach();
 }
Index: html/html_documentimpl.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/html/html_documentimpl.cpp,v
retrieving revision 1.144
diff -u -p -B -w -r1.144 html_documentimpl.cpp
--- html/html_documentimpl.cpp	8 Jan 2003 18:16:56 -0000	1.144
+++ html/html_documentimpl.cpp	9 Jan 2003 20:47:46 -0000
@@ -303,6 +303,13 @@ void HTMLDocumentImpl::close()
             getDocument()->dispatchWindowEvent(EventImpl::LOAD_EVENT, false, false);
 
         updateRendering();
+
+        // Always do a layout/repaint after loading.
+        if (renderer()) {
+            if (!renderer()->layouted())
+                renderer()->layout();
+            renderer()->repaint();
+        }
     }
 }
 
Index: html/html_elementimpl.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/html/html_elementimpl.cpp,v
retrieving revision 1.150
diff -u -p -B -w -r1.150 html_elementimpl.cpp
--- html/html_elementimpl.cpp	9 Dec 2002 07:21:44 -0000	1.150
+++ html/html_elementimpl.cpp	9 Jan 2003 20:47:46 -0000
@@ -56,6 +56,48 @@ HTMLElementImpl::~HTMLElementImpl()
 {
 }
 
+bool HTMLElementImpl::isInline() const
+{
+    if (renderer())
+        return ElementImpl::isInline();
+
+    switch(id()) {
+        case ID_A:
+        case ID_FONT:
+        case ID_TT:
+        case ID_U:
+        case ID_B:
+        case ID_I:
+        case ID_S:
+        case ID_STRIKE:
+        case ID_BIG:
+        case ID_SMALL:
+
+            // %phrase
+        case ID_EM:
+        case ID_STRONG:
+        case ID_DFN:
+        case ID_CODE:
+        case ID_SAMP:
+        case ID_KBD:
+        case ID_VAR:
+        case ID_CITE:
+        case ID_ABBR:
+        case ID_ACRONYM:
+
+            // %special
+        case ID_SUB:
+        case ID_SUP:
+        case ID_SPAN:
+        case ID_NOBR:
+        case ID_WBR:
+            return true;
+
+        default:
+            return ElementImpl::isInline();
+    }
+}
+
 void HTMLElementImpl::parseAttribute(AttributeImpl *attr)
 {
     DOMString indexstring;
Index: html/html_elementimpl.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/html/html_elementimpl.h,v
retrieving revision 1.61
diff -u -p -B -w -r1.61 html_elementimpl.h
--- html/html_elementimpl.h	9 Dec 2002 07:21:44 -0000	1.61
+++ html/html_elementimpl.h	9 Jan 2003 20:47:46 -0000
@@ -41,6 +41,8 @@ public:
 
     virtual bool isHTMLElement() const { return true; }
 
+    virtual bool isInline() const;
+
     virtual Id id() const = 0;
 
     virtual void parseAttribute(AttributeImpl *token);
Index: html/html_formimpl.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/html/html_formimpl.cpp,v
retrieving revision 1.307
diff -u -p -B -w -r1.307 html_formimpl.cpp
--- html/html_formimpl.cpp	7 Jan 2003 17:12:09 -0000	1.307
+++ html/html_formimpl.cpp	9 Jan 2003 20:47:46 -0000
@@ -583,10 +583,16 @@ void HTMLGenericFormElementImpl::attach(
     if (m_render) {
         assert(m_render->style());
         parentNode()->renderer()->addChild(m_render, nextRenderer());
-        m_render->updateFromElement();
     }
 
     NodeBaseImpl::attach();
+
+    // The call to updateFromElement() needs to go after the call through
+    // to the base class's attach() because that can sometimes do a close
+    // on the renderer.
+    if (m_render)
+        m_render->updateFromElement();
+
 }
 
 HTMLFormElementImpl *HTMLGenericFormElementImpl::getForm() const
Index: html/html_headimpl.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/html/html_headimpl.cpp,v
retrieving revision 1.95
diff -u -p -B -w -r1.95 html_headimpl.cpp
--- html/html_headimpl.cpp	9 Dec 2002 07:21:44 -0000	1.95
+++ html/html_headimpl.cpp	9 Jan 2003 20:47:46 -0000
@@ -158,6 +158,13 @@ void HTMLLinkElementImpl::process()
         // ### there may be in some situations e.g. for an editor or script to manipulate
         if( m_media.isNull() || m_media.contains("screen") || m_media.contains("all") || m_media.contains("print") ) {
             m_loading = true;
+
+            // Add ourselves as a pending sheet, but only if we aren't an alternate
+            // stylesheet.  Alternate stylesheets don't hold up render tree construction.
+            m_alternate = rel.contains("alternate");
+            if (!isAlternate())
+                getDocument()->addPendingSheet();
+
             QString chset = getAttribute( ATTR_CHARSET ).string();
             if (m_cachedSheet)
 		m_cachedSheet->deref(this);
@@ -203,7 +210,9 @@ void HTMLLinkElementImpl::setStyleSheet(
 
     m_loading = false;
 
-    getDocument()->updateStyleSelector();
+    // Tell the doc about the sheet.
+    if (!isLoading() && m_sheet && !isAlternate())
+        getDocument()->stylesheetLoaded();
 }
 
 bool HTMLLinkElementImpl::isLoading() const
@@ -217,7 +226,8 @@ bool HTMLLinkElementImpl::isLoading() co
 
 void HTMLLinkElementImpl::sheetLoaded()
 {
-    getDocument()->updateStyleSelector();
+    if (!isLoading() && !isAlternate())
+        getDocument()->stylesheetLoaded();
 }
 
 // -------------------------------------------------------------------------
@@ -315,12 +325,14 @@ void HTMLStyleElementImpl::parseAttribut
 void HTMLStyleElementImpl::insertedIntoDocument()
 {
     HTMLElementImpl::insertedIntoDocument();
+    if (m_sheet)
     getDocument()->updateStyleSelector();
 }
 
 void HTMLStyleElementImpl::removedFromDocument()
 {
     HTMLElementImpl::removedFromDocument();
+    if (m_sheet)
     getDocument()->updateStyleSelector();
 }
 
@@ -337,23 +349,36 @@ void HTMLStyleElementImpl::childrenChang
 	    text += c->nodeValue();
     }
 
-    if(m_sheet)
+    if (m_sheet) {
 	m_sheet->deref();
+        m_sheet = 0;
+    }
+
+    m_loading = false;
+
+    getDocument()->addPendingSheet();
+    m_loading = true;
     m_sheet = new CSSStyleSheetImpl(this);
     m_sheet->ref();
     m_sheet->parseString( text, (getDocument()->parseMode() == DocumentImpl::Strict) );
-    getDocument()->updateStyleSelector();
+    m_loading = false;
+
+    if (!isLoading() && m_sheet)
+        getDocument()->stylesheetLoaded();
+
 }
 
 bool HTMLStyleElementImpl::isLoading() const
 {
+    if(m_loading) return true;
     if(!m_sheet) return false;
     return static_cast<CSSStyleSheetImpl *>(m_sheet)->isLoading();
 }
 
 void HTMLStyleElementImpl::sheetLoaded()
 {
-    getDocument()->updateStyleSelector();
+    if (!isLoading())
+        getDocument()->stylesheetLoaded();
 }
 
 // -------------------------------------------------------------------------
Index: html/html_headimpl.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/html/html_headimpl.h,v
retrieving revision 1.38
diff -u -p -B -w -r1.38 html_headimpl.h
--- html/html_headimpl.h	9 Dec 2002 07:21:44 -0000	1.38
+++ html/html_headimpl.h	9 Jan 2003 20:47:46 -0000
@@ -71,7 +71,7 @@ class HTMLLinkElementImpl : public khtml
 {
 public:
     HTMLLinkElementImpl(DocumentPtr *doc)
-        : HTMLElementImpl(doc), m_cachedSheet(0), m_sheet(0), m_loading(false) {}
+        : HTMLElementImpl(doc), m_cachedSheet(0), m_sheet(0), m_loading(false), m_alternate(false) {}
 
     ~HTMLLinkElementImpl();
 
@@ -92,6 +92,7 @@ public:
     bool isLoading() const;
     void sheetLoaded();
 
+    bool isAlternate() const { return m_alternate; }
 
 protected:
     khtml::CachedCSSStyleSheet *m_cachedSheet;
@@ -101,6 +102,8 @@ protected:
     QString m_media;
     DOMString m_rel;
     bool m_loading;
+    bool m_alternate;
+
     QString m_data; // needed for temporarily storing the loaded style sheet data
 };
 
@@ -143,7 +146,7 @@ class HTMLStyleElementImpl : public HTML
 {
 public:
     HTMLStyleElementImpl(DocumentPtr *doc)
-        : HTMLElementImpl(doc), m_sheet(0) {}
+        : HTMLElementImpl(doc), m_sheet(0), m_loading(false) {}
     ~HTMLStyleElementImpl();
 
     virtual Id id() const;
@@ -161,6 +164,7 @@ public:
 
 protected:
     StyleSheetImpl *m_sheet;
+    bool m_loading;
 };
 
 // -------------------------------------------------------------------------
Index: html/html_inlineimpl.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/html/html_inlineimpl.cpp,v
retrieving revision 1.116
diff -u -p -B -w -r1.116 html_inlineimpl.cpp
--- html/html_inlineimpl.cpp	9 Jan 2003 06:16:58 -0000	1.116
+++ html/html_inlineimpl.cpp	9 Jan 2003 20:47:46 -0000
@@ -196,11 +196,18 @@ void HTMLBRElementImpl::attach()
     assert(!m_render);
     assert(parentNode());
 
-    if (parentNode()->renderer()) {
+    RenderObject *parentRenderer = parentNode()->renderer();
+    if (parentRenderer) {
+        RenderStyle *style = getDocument()->styleSelector()->styleForElement(this);
+        style->ref();
+        if (style->display() != NONE) {
         m_render = new RenderBR(this);
-        m_render->setStyle(getDocument()->styleSelector()->styleForElement(this));
-        parentNode()->renderer()->addChild(m_render, nextRenderer());
+            m_render->setStyle(style);
+            parentRenderer->addChild(m_render, nextRenderer());
     }
+        style->deref();
+    }
+
     NodeImpl::attach();
 }
 
Index: html/html_objectimpl.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/html/html_objectimpl.cpp,v
retrieving revision 1.95
diff -u -p -B -w -r1.95 html_objectimpl.cpp
--- html/html_objectimpl.cpp	23 Oct 2002 17:03:31 -0000	1.95
+++ html/html_objectimpl.cpp	9 Jan 2003 20:47:46 -0000
@@ -421,12 +421,13 @@ void HTMLObjectElementImpl::attach()
     NodeBaseImpl::attach();
 
   // ### do this when we are actually finished loading instead
+  if (m_render)
   dispatchHTMLEvent(EventImpl::LOAD_EVENT,false,false);
 }
 
 void HTMLObjectElementImpl::detach()
 {
-    if (attached())
+  if (attached() && m_render)
         // ### do this when we are actualy removed from document instead
         dispatchHTMLEvent(EventImpl::UNLOAD_EVENT,false,false);
 
Index: html/htmlparser.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/html/htmlparser.cpp,v
retrieving revision 1.315
diff -u -p -B -w -r1.315 htmlparser.cpp
--- html/htmlparser.cpp	6 Jan 2003 12:52:53 -0000	1.315
+++ html/htmlparser.cpp	9 Jan 2003 20:47:46 -0000
@@ -331,8 +331,7 @@ bool KHTMLParser::insertNode(NodeImpl *n
                 QString state(document->document()->nextState());
                 if (!state.isNull()) n->restoreState(state);
             }
-            if(n->renderer())
-                n->renderer()->close();
+            n->closeRenderer();
 #endif
 	    if(n->isInline()) m_inline = true;
         }
@@ -1187,8 +1186,7 @@ void KHTMLParser::popOneBlock()
             QString state(document->document()->nextState());
             if (!state.isNull()) current->restoreState(state);
         }
-        if (current->renderer())
-            current->renderer()->close();
+        current->closeRenderer();
     }
 #endif
 
Index: rendering/render_container.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/rendering/render_container.cpp,v
retrieving revision 1.35
diff -u -p -B -w -r1.35 render_container.cpp
--- rendering/render_container.cpp	9 Dec 2002 04:05:45 -0000	1.35
+++ rendering/render_container.cpp	9 Jan 2003 20:47:46 -0000
@@ -188,12 +188,16 @@ void RenderContainer::insertPseudoChild(
         if (pseudo->contentType()==CONTENT_TEXT)
         {
             RenderObject* po = new RenderFlow(0 /* anonymous box */);
+            po->setParent(this);
             po->setStyle(pseudo);
+            po->setParent(0);
 
             addChild(po, beforeChild);
 
             RenderText* t = new RenderText(0 /*anonymous object */, pseudo->contentText());
+            t->setParent(po);
             t->setStyle(pseudo);
+            t->setParent(0);
 
 //            kdDebug() << DOM::DOMString(pseudo->contentText()).string() << endl;
 
@@ -206,7 +210,9 @@ void RenderContainer::insertPseudoChild(
         {
             RenderObject* po = new RenderImage(0);
             po->setStyle(pseudo);
+            po->setParent(this);
             addChild(po, beforeChild);
+            po->setParent(0);
             po->close();
         }
 
Index: rendering/render_style.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/rendering/render_style.cpp,v
retrieving revision 1.55
diff -u -p -B -w -r1.55 render_style.cpp
--- rendering/render_style.cpp	8 Jan 2003 06:23:16 -0000	1.55
+++ rendering/render_style.cpp	9 Jan 2003 20:47:46 -0000
@@ -25,6 +25,7 @@
  */
 
 #include "xml/dom_stringimpl.h"
+#include "css/cssstyleselector.h"
 
 #include "render_style.h"
 
@@ -231,6 +232,11 @@ bool RenderStyle::operator==(const Rende
             background == o.background &&
             surround == o.surround &&
             inherited == o.inherited);
+}
+
+bool RenderStyle::isStyleAvailable() const
+{
+    return this != CSSStyleSelector::styleNotYetAvailable;
 }
 
 RenderStyle* RenderStyle::getPseudoStyle(PseudoId pid)
Index: rendering/render_style.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/rendering/render_style.h,v
retrieving revision 1.80
diff -u -p -B -w -r1.80 render_style.h
--- rendering/render_style.h	28 Dec 2002 14:05:05 -0000	1.80
+++ rendering/render_style.h	9 Jan 2003 20:47:46 -0000
@@ -640,6 +640,8 @@ public:
     bool visuallyOrdered() const { return inherited_flags._visuallyOrdered; }
     void setVisuallyOrdered(bool b) {  inherited_flags._visuallyOrdered = b; }
 
+    bool isStyleAvailable() const;
+
 // attribute getter methods
 
     EDisplay 	display() const { return noninherited_flags._display; }
Index: xml/dom_docimpl.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/xml/dom_docimpl.cpp,v
retrieving revision 1.210
diff -u -p -B -w -r1.210 dom_docimpl.cpp
--- xml/dom_docimpl.cpp	8 Jan 2003 19:29:56 -0000	1.210
+++ xml/dom_docimpl.cpp	9 Jan 2003 20:47:46 -0000
@@ -287,6 +287,7 @@ DocumentImpl::DocumentImpl(DOMImplementa
     m_windowEventListeners.setAutoDelete(true);
 
     m_inStyleRecalc = false;
+    m_pendingStylesheets = 0;
 }
 
 DocumentImpl::~DocumentImpl()
@@ -1744,8 +1745,22 @@ StyleSheetListImpl* DocumentImpl::styleS
     return m_styleSheets;
 }
 
+// This method is called whenever a top-level stylesheet has finished loading.
+void DocumentImpl::stylesheetLoaded()
+{
+    // Make sure we knew this sheet was pending, and that our count isn't out of sync.
+    assert(m_pendingStylesheets > 0);
+
+    m_pendingStylesheets--;
+    updateStyleSelector();
+}
+
 void DocumentImpl::updateStyleSelector()
 {
+    // Don't bother updating, since we haven't loaded all our style info yet.
+    if (m_pendingStylesheets > 0)
+        return;
+
     recalcStyleSelector();
     recalcStyle(Force);
 #if 0
Index: xml/dom_docimpl.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/xml/dom_docimpl.h,v
retrieving revision 1.102
diff -u -p -B -w -r1.102 dom_docimpl.h
--- xml/dom_docimpl.h	8 Jan 2003 18:17:25 -0000	1.102
+++ xml/dom_docimpl.h	9 Jan 2003 20:47:46 -0000
@@ -162,6 +162,24 @@ public:
     khtml::CSSStyleSelector *styleSelector() { return m_styleSelector; }
 
     /**
+     * Updates the pending sheet count and then calls updateStyleSelector.
+     */
+    void stylesheetLoaded();
+
+    /**
+     * This method returns true if all top-level stylesheets have loaded (including
+     * any @imports that they may be loading).
+     */
+    bool haveStylesheetsLoaded() { return m_pendingStylesheets <= 0; }
+
+    /**
+     * Increments the number of pending sheets.  The <link> elements
+     * invoke this to add themselves to the loading list.
+     */
+    void addPendingSheet() { m_pendingStylesheets++; }
+
+
+    /**
      * Called when one or more stylesheets in the document may have been added, removed or changed.
      *
      * Creates a new style selector and assign it to this document. This is done by iterating through all nodes in
@@ -392,6 +410,12 @@ protected:
     QString m_usersheet;
     QString m_printSheet;
     QStringList m_availableSheets;
+
+    // Track the number of currently loading top-level stylesheets.  Sheets
+    // loaded using the @import directive are not included in this count.
+    // We use this count of pending sheets to detect when we can begin attaching
+    // elements.
+    int m_pendingStylesheets;
 
     CSSStyleSheetImpl *m_elemSheet;
 
Index: xml/dom_nodeimpl.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/xml/dom_nodeimpl.cpp,v
retrieving revision 1.199
diff -u -p -B -w -r1.199 dom_nodeimpl.cpp
--- xml/dom_nodeimpl.cpp	8 Jan 2003 19:23:01 -0000	1.199
+++ xml/dom_nodeimpl.cpp	9 Jan 2003 20:47:46 -0000
@@ -62,7 +62,8 @@ NodeImpl::NodeImpl(DocumentPtr *doc)
       m_focused( false ),
       m_active( false ),
       m_styleElement( false ),
-      m_implicit( false )
+      m_implicit( false ),
+      m_rendererNeedsClose( false )
 {
     if (document)
         document->ref();
@@ -888,10 +889,28 @@ void NodeImpl::dump(QTextStream *stream,
 }
 #endif
 
+void NodeImpl::closeRenderer()
+{
+    // It's important that we close the renderer, even if it hasn't been
+    // created yet. This happens even more because of the FOUC fixes we did
+    // at Apple, which prevent renderers from being created until the stylesheets
+    // are all loaded. If the renderer is not here to be closed, we set a flag,
+    // then close it later when it's attached.
+    assert(!m_rendererNeedsClose);
+    if (m_render)
+        m_render->close();
+    else
+        m_rendererNeedsClose = true;
+}
+
 void NodeImpl::attach()
 {
     assert(!attached());
     assert(!m_render || (m_render->style() && m_render->parent()));
+    if (m_render && m_rendererNeedsClose) {
+       m_render->close();
+       m_rendererNeedsClose = false;
+    }
     m_attached = true;
 }
 
Index: xml/dom_nodeimpl.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/xml/dom_nodeimpl.h,v
retrieving revision 1.140
diff -u -p -B -w -r1.140 dom_nodeimpl.h
--- xml/dom_nodeimpl.h	8 Jan 2003 19:24:00 -0000	1.140
+++ xml/dom_nodeimpl.h	9 Jan 2003 20:47:46 -0000
@@ -290,6 +290,8 @@ public:
      */
     virtual void detach();
 
+    void closeRenderer();
+
     // -----------------------------------------------------------------------------
     // Methods for maintaining the state of the element between history navigation
 
@@ -371,8 +373,9 @@ protected:
     bool m_active : 1;
     bool m_styleElement : 1; // contains stylesheet text
     bool m_implicit : 1; // implicitely generated by the parser
+    bool m_rendererNeedsClose : 1;
 
-    // 2 bits unused
+    // 1 bits unused
 };
 
 // this is the full Node Implementation with parents and children.
Index: xml/xml_tokenizer.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/xml/xml_tokenizer.cpp,v
retrieving revision 1.40
diff -u -p -B -w -r1.40 xml_tokenizer.cpp
--- xml/xml_tokenizer.cpp	11 Dec 2002 21:11:53 -0000	1.40
+++ xml/xml_tokenizer.cpp	9 Jan 2003 20:47:46 -0000
@@ -113,8 +113,7 @@ bool XMLHandler::endElement( const QStri
     if (m_currentNode->nodeType() == Node::TEXT_NODE)
         exitText();
     if (m_currentNode->parentNode() != 0) {
-        if (m_currentNode->renderer())
-            m_currentNode->renderer()->close();
+        m_currentNode->closeRenderer();
         m_currentNode = m_currentNode->parentNode();
     }
 // ###  else error
@@ -385,9 +384,9 @@ void XMLTokenizer::finish()
 
         // Close the renderers so that they update their display correctly
         // ### this should not be necessary, but requires changes in the rendering code...
-        h1->renderer()->close();
-        pre->renderer()->close();
-        body->renderer()->close();
+        h1->closeRenderer();
+        pre->closeRenderer();
+        body->closeRenderer();
 
         m_doc->document()->recalcStyle( NodeImpl::Inherit );
         m_doc->document()->updateRendering();


More information about the kfm-devel mailing list