XML Patch For FOUC

David Hyatt hyatt@apple.com
Tue, 14 Jan 2003 16:58:39 -0800


This patch makes FOUC work for XML PIs.  I am making the assumption  
that you guys haven't added support for alternates, title, or disabled  
sheets yet in your version of XML (since 3.0.2).  If you have, then  
this logic will have to be improved to more closely copy the code on  
the <link> element.

Index: khtml/xml/dom_xmlimpl.cpp
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom_xmlimpl.cpp,v
retrieving revision 1.2
diff -u -r1.2 dom_xmlimpl.cpp
--- dom_xmlimpl.cpp	2002/03/22 00:31:19	1.2
+++ dom_xmlimpl.cpp	2003/01/15 00:21:21
@@ -257,6 +257,7 @@
      m_localHref = 0;
      m_sheet = 0;
      m_cachedSheet = 0;
+    m_loading = false;
  }

  ProcessingInstructionImpl::ProcessingInstructionImpl(DocumentPtr *doc,  
DOMString _target, DOMString _data) : NodeBaseImpl(doc)
@@ -378,6 +379,8 @@
              {
                  // ### some validation on the URL?
                  // ### FIXME charset
+                m_loading = true;
+                getDocument()->addPendingSheet();
                  if (m_cachedSheet) m_cachedSheet->deref(this);
                  m_cachedSheet =  
getDocument()->docLoader()->requestStyleSheet(getDocument()- 
 >completeURL(href.string()), QString::null);
                  if (m_cachedSheet)
@@ -393,6 +396,19 @@
      return m_sheet;
  }

+bool ProcessingInstructionImpl::isLoading() const
+{
+    if(m_loading) return true;
+    if(!m_sheet) return false;
+    return static_cast<CSSStyleSheetImpl *>(m_sheet)->isLoading();
+}
+
+void ProcessingInstructionImpl::sheetLoaded()
+{
+    if (!isLoading())
+        getDocument()->stylesheetLoaded();
+}
+
  void ProcessingInstructionImpl::setStyleSheet(const DOM::DOMString  
&url, const DOM::DOMString &sheet)
  {
      if (m_sheet)
@@ -403,8 +419,12 @@
      if (m_cachedSheet)
  	m_cachedSheet->deref(this);
      m_cachedSheet = 0;
+
+    m_loading = false;

-    getDocument()->updateStyleSelector();
+    // Tell the doc about the sheet.
+    if (!isLoading() && m_sheet)
+        getDocument()->stylesheetLoaded();
  }

  void ProcessingInstructionImpl::setStyleSheet(CSSStyleSheetImpl* sheet)
Index: khtml/xml/dom_xmlimpl.h
===================================================================
RCS file: /local/home/cvs/Labyrinth/WebCore/khtml/xml/dom_xmlimpl.h,v
retrieving revision 1.5
diff -u -r1.5 dom_xmlimpl.h
--- dom_xmlimpl.h	2002/10/26 23:21:43	1.5
+++ dom_xmlimpl.h	2003/01/15 00:21:21
@@ -152,7 +152,9 @@
      void checkStyleSheet();
      virtual void setStyleSheet(const DOM::DOMString &url, const  
DOM::DOMString &sheet);
      virtual void setStyleSheet(CSSStyleSheetImpl* sheet);
-
+    bool isLoading() const;
+    void sheetLoaded();
+
  #if APPLE_CHANGES
      static ProcessingInstruction  
createInstance(ProcessingInstructionImpl *impl);
  #endif
@@ -163,6 +165,7 @@
      DOMStringImpl *m_localHref;
      khtml::CachedCSSStyleSheet *m_cachedSheet;
      CSSStyleSheetImpl *m_sheet;
+    bool m_loading;
  };

  class XMLAttributeReader : public QXmlDefaultHandler
Index: khtml/html/html_baseimpl.cpp
===================================================================
RCS file:  
/local/home/cvs/Labyrinth/WebCore/khtml/html/html_baseimpl.cpp,v
retrieving revision 1.20
diff -u -r1.20 html_baseimpl.cpp
--- html_baseimpl.cpp	2003/01/09 07:07:26	1.20
+++ html_baseimpl.cpp	2003/01/15 00:21:21
@@ -185,17 +185,18 @@
  {
      assert(!m_render);
      assert(parentNode());
-    assert(parentNode()->renderer());
-
-    RenderStyle* style =  
getDocument()->styleSelector()->styleForElement(this);
-    style->ref();
-    if (style->display() != NONE) {
-        m_render = new (getDocument()->renderArena()) RenderBody(this);
-        m_render->setStyle(style);
-        parentNode()->renderer()->addChild(m_render, nextRenderer());
+
+    if (parentNode()->renderer()) {
+        RenderStyle* style =  
getDocument()->styleSelector()->styleForElement(this);
+        style->ref();
+        if (style->display() != NONE) {
+            m_render = new (getDocument()->renderArena())  
RenderBody(this);
+            m_render->setStyle(style);
+            parentNode()->renderer()->addChild(m_render,  
nextRenderer());
+        }
+        style->deref();
      }
-    style->deref();
-
+
      NodeBaseImpl::attach();
  }