[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kfm-devel
Subject:    Re: patch + examples, change frameset.rows from js
From:       <koos.vriezen () xs4all ! nl>
Date:       2001-12-21 23:19:31
[Download RAW message or body]

> On Friday 21 December 2001 00:35, koos.vriezen@xs4all.nl wrote:
> > On Fri, 21 Dec 2001, David Faure wrote:
> >
> > > On Thursday 20 December 2001 23:59, koos.vriezen@xs4all.nl wrote:
> > > > So updateRendering is called on an inner document (as the heap goes up).
> > > > Both documents return NULL as parentNode() and I couldn't find a way to
> > > > get to this outer(=frameset) document.
> > >
> > > You can do that using the KHTMLPart's parentPart(), and then asking for
> > > the document of that part.
> > >
> > > BUT.... there's nothing that can tell us that it's the parent document
> > > that got modified. A frame could also modify another frame!
> > > I think the only option we have is to go to the most-toplevel khtmlpart
> > > (the parent frameset here, but framesets can also be nested!),
> > > and from there call updateRendering() on all child khtml parts,
> > > recursively (i.e. all child frames and framesets). Just in case the JS script
> > > changed anything in another frame/frameset.
> >
> > Maybe there should be a static lists of all documents. Or there could be a
> > static list of all changedNodes. The last option would be quite easy to
> > implement, just add static before QList<NodeImpl> changedNodes; in
> > ./xml/dom_docimpl.h. I think I will try that tomorrow.
>
> Interesting - you made me realize that a script can indeed modify another
> window (e.g. one that it opened itself), not only documents in the
> frameset/frame hierarchy.
> I don't see how you would deal with a static list of nodes, since the
> goal is to call updateRendering() on each document. What about
> a static list of "changedDocuments" instead, and keeping the changed
> nodes inside the document ? When doing doc->changedNodes.append(this)
> we would also do s_changedDocs->append(doc) if doc isn't already
> in s_changedDocs. Then after a script's execution we can call
> updateRendering on each changed doc.

Ok, here your second suggention. My first try with static changedNodes was
indeed to optimistic.

--- ./html/html_baseimpl.cpp.orig       Thu Dec 20 17:38:46 2001
+++ ./html/html_baseimpl.cpp    Fri Dec 21 12:47:34 2001
@@ -389,18 +389,12 @@
         m_rows = attr->val()->toLengthList();
         m_totalRows = m_rows->count();
         setChanged();
-        // ### nasty - usual change handling is not enough FIXIT!
-        if (m_render)
-            m_render->layout();
         break;
     case ATTR_COLS:
         delete m_cols;
         m_cols = attr->val()->toLengthList();
         m_totalCols = m_cols->count();
         setChanged();
-        // ### nasty - usual change handling is not enough FIXIT!
-        if (m_render)
-            m_render->layout();
         break;
     case ATTR_FRAMEBORDER:
         // false or "no" or "0"..
--- ./xml/dom_docimpl.h.orig    Fri Dec 21 13:00:01 2001
+++ ./xml/dom_docimpl.h Fri Dec 21 23:34:23 2001
@@ -179,9 +179,11 @@
                             bool entityReferenceExpansion);

     QList<NodeImpl> changedNodes;
+    static QList<DocumentImpl> changedDocuments;
     virtual void setChanged(bool b=true);
     virtual void recalcStyle();
     virtual void updateRendering();
+    static void updateDocumentsRendering();
     khtml::DocLoader *docLoader() { return m_docLoader; }

     void attach(KHTMLView *w=0);
@@ -270,7 +272,9 @@

     virtual DocumentImpl *getDocument()
         { return this; }
-
+    virtual bool isDocumentChanged()
+       { return m_docChanged; }
+    virtual void setDocumentChanged(bool);
     void attachNodeIterator(NodeIteratorImpl *ni);
     void detachNodeIterator(NodeIteratorImpl *ni);
     void notifyBeforeNodeRemoval(NodeImpl *n);
@@ -357,6 +361,7 @@
     bool m_loadingSheet;
     bool visuallyOrdered;
     bool m_bParsing;
+    bool m_docChanged;
 };

 class DocumentFragmentImpl : public NodeBaseImpl
--- ./xml/dom_docimpl.cpp.orig  Fri Dec 21 12:59:20 2001
+++ ./xml/dom_docimpl.cpp       Fri Dec 21 23:41:03 2001
@@ -127,6 +127,8 @@
     return new DocumentTypeImpl(this,0,qualifiedName,publicId,systemId);
 }

+QList<DocumentImpl> DocumentImpl::changedDocuments;
+
 DocumentImpl *DOMImplementationImpl::createDocument( const DOMString
&namespaceURI, const DOMString &qualifiedName,
                                                      const DocumentType
&doctype, int &exceptioncode )
 {
@@ -247,6 +249,7 @@
     visuallyOrdered = false;
     m_loadingSheet = false;
     m_bParsing = false;
+    m_docChanged = false;
     m_sheet = 0;
     m_elemSheet = 0;
     m_tokenizer = 0;
@@ -773,6 +776,15 @@
     return new TreeWalkerImpl;
 }

+void DocumentImpl::setDocumentChanged(bool b)
+{
+    if (b && !m_docChanged)
+        changedDocuments.append(this);
+    else if (!b && m_docChanged)
+        changedDocuments.remove(this);
+    m_docChanged = b;
+}
+
 void DocumentImpl::applyChanges(bool,bool force)
 {
     if ( !m_render && attached() ) return;
@@ -876,6 +888,13 @@
     }
     kdDebug() << "UPDATERENDERING orig="<<o<<" actual="<<a<<endl;
     changedNodes.clear();
+    setDocumentChanged(false);
+}
+
+void DocumentImpl::updateDocumentsRendering() {
+    for (QListIterator<DocumentImpl> it(changedDocuments); it.current(); )
+       if (it.current()->isDocumentChanged())
+           it.current()->updateRendering();
 }

 void DocumentImpl::attach(KHTMLView *w)
--- ./xml/dom_nodeimpl.cpp.orig Thu Dec 20 19:16:05 2001
+++ ./xml/dom_nodeimpl.cpp      Fri Dec 21 23:51:31 2001
@@ -384,12 +384,13 @@
 {
     if (b && !attached()) // changed compared to what?
         return;
-
     if (b && !changed() && ownerDocument())
         ownerDocument()->changedNodes.append(this);
     else if (!b && changed() && ownerDocument())
         ownerDocument()->changedNodes.remove(this);
     m_changed = b;
+    if (b)
+       ownerDocument()->setDocumentChanged(b);
 }

 void NodeImpl::printTree(int indent)
@@ -1519,10 +1520,11 @@
 void NodeBaseImpl::applyChanges(bool top, bool force)
 {

-    setChanged(false);

-    if (!attached())
+    if (!attached()) {
+           setChanged(false);
            return;
+    }

     int ow = (m_style?m_style->outlineWidth():0);

--- ./khtml_part.cpp.orig       Fri Dec 21 23:58:26 2001
+++ ./khtml_part.cpp    Fri Dec 21 23:57:48 2001
@@ -876,8 +876,7 @@
   d->m_runningScripts--;
   if (!d->m_runningScripts && d->m_doc && !d->m_doc->parsing() &&
d->m_submitForm )
       submitFormAgain();
-  if ( d->m_doc )
-    d->m_doc->updateRendering();
+    DocumentImpl::updateDocumentsRendering();

   //kdDebug(6070) << "KHTMLPart::executeScript - done" << endl;
   return ret;
@@ -4309,8 +4308,7 @@
   if (!proxy || proxy->paused())
     return QVariant();
   QVariant ret = proxy->evaluate(filename,baseLine,script, n );
-  if ( d->m_doc )
-    d->m_doc->updateRendering();
+  DocumentImpl::updateDocumentsRendering();
   return ret;
 }

This patch seems to work. Probably the change from
'd->m_doc->updateRendering()' to
'DocumentImpl::updateDocumentsRendering()'
should be done on more places where js is executed.

Please test/comment.

Regards,

Koos Vriezen



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic