[webkit-changes] cvs commit: WebCore/kwq KWQKHTMLPart.h KWQKHTMLPart.mm KWQObject.h KWQObject.mm KWQPageState.h KWQPageState.mm KWQTimer.h KWQTimer.mm WebCoreBridge.mm

Tim tomernic at opensource.apple.com
Tue Nov 8 18:46:34 PST 2005


tomernic    05/11/08 18:46:33

  Modified:    .        ChangeLog
               khtml/ecma kjs_window.cpp kjs_window.h
               kwq      KWQKHTMLPart.h KWQKHTMLPart.mm KWQObject.h
                        KWQObject.mm KWQPageState.h KWQPageState.mm
                        KWQTimer.h KWQTimer.mm WebCoreBridge.mm
  Log:
  	<http://bugzilla.opendarwin.org/show_bug.cgi?id=5665> (REGRESSION: Crash in deleteTimer)
  
  	Rolled back Darin's timer changes from 2005-11-07, as they caused a couple of regressions.
  
  Revision  Changes    Path
  1.348     +6 -0      WebCore/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/WebCore/ChangeLog,v
  retrieving revision 1.347
  retrieving revision 1.348
  diff -u -r1.347 -r1.348
  --- ChangeLog	8 Nov 2005 21:54:17 -0000	1.347
  +++ ChangeLog	9 Nov 2005 02:46:21 -0000	1.348
  @@ -1,3 +1,9 @@
  +2005-11-08  Tim Omernick  <timo at apple.com>
  +	
  +	<http://bugzilla.opendarwin.org/show_bug.cgi?id=5665> (REGRESSION: Crash in deleteTimer)
  +	
  +	Rolled back Darin's timer changes from 2005-11-07, as they caused a couple of regressions.
  +	
   2005-11-08  Adele Peterson  <adele at apple.com>
   
           Reviewed by Darin.
  
  
  
  1.187     +199 -109  WebCore/khtml/ecma/kjs_window.cpp
  
  Index: kjs_window.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/ecma/kjs_window.cpp,v
  retrieving revision 1.186
  retrieving revision 1.187
  diff -u -r1.186 -r1.187
  --- kjs_window.cpp	7 Nov 2005 20:52:09 -0000	1.186
  +++ kjs_window.cpp	9 Nov 2005 02:46:27 -0000	1.187
  @@ -80,25 +80,30 @@
   // <cmath> and <math.h> the macros necessary for functions like
   // isnan are not defined.
   #include <cmath>
  -using std::isnan;
   
  -using namespace DOM;
  -using namespace EventNames;
  +using namespace DOM::EventNames;
   
  -using namespace khtml;
  +using DOM::AtomicString;
  +using DOM::DocumentImpl;
  +using DOM::DOMString;
  +using DOM::ElementImpl;
  +using DOM::EventImpl;
  +using DOM::HTMLCollectionImpl;
  +using DOM::HTMLDocumentImpl;
  +using DOM::HTMLElementImpl;
  +using DOM::NodeImpl;
  +using DOM::Position;
  +
  +using khtml::TypingCommand;
  +
  +using KParts::ReadOnlyPart;
  +using KParts::URLArgs;
  +using KParts::WindowArgs;
   
  -using namespace KParts;
  +using std::isnan;
   
   namespace KJS {
   
  -class PausedTimeout {
  -public:
  -    int timerId;
  -    int nextFireInterval;
  -    int repeatInterval;
  -    ScheduledAction *action;
  -};
  -
   ////////////////////// History Object ////////////////////////
   
     class History : public ObjectImp {
  @@ -1257,11 +1262,47 @@
     return !m_part.isNull();
   }
   
  +int Window::installTimeout(const UString &handler, int t, bool singleShot)
  +{
  +  return winq->installTimeout(handler, t, singleShot);
  +}
  +
  +int Window::installTimeout(ValueImp *function, List &args, int t, bool singleShot)
  +{
  +  return winq->installTimeout(function, args, t, singleShot);
  +}
  +
  +void Window::clearTimeout(int timerId)
  +{
  +  winq->clearTimeout(timerId);
  +}
  +
  +#if APPLE_CHANGES
  +bool Window::hasTimeouts()
  +{
  +    return winq->hasTimeouts();
  +}
  +
  +QMap<int, ScheduledAction*> *Window::pauseTimeouts(const void *key)
  +{
  +    return winq->pauseTimeouts(key);
  +}
  +
  +void Window::resumeTimeouts(QMap<int, ScheduledAction*> *sa, const void *key)
  +{
  +    return winq->resumeTimeouts(sa, key);
  +}
  +#endif
  +
   void Window::scheduleClose()
   {
     kdDebug(6070) << "Window::scheduleClose window.close() " << m_part << endl;
     Q_ASSERT(winq);
  +#if APPLE_CHANGES
     KWQ(m_part)->scheduleClose();
  +#else
  +  QTimer::singleShot( 0, winq, SLOT( timeoutClose() ) );
  +#endif
   }
   
   static bool shouldLoadAsEmptyDocument(const KURL &url)
  @@ -1986,141 +2027,200 @@
       docimpl->updateLayoutIgnorePendingStylesheets();
   }
   
  +
   ////////////////////// ScheduledAction ////////////////////////
   
  -void ScheduledAction::execute(Window *window)
  +ScheduledAction::ScheduledAction(ObjectImp *_func, List _args, bool _singleShot)
   {
  -    if (!window->m_part)
  -        return;
  +  //kdDebug(6070) << "ScheduledAction::ScheduledAction(isFunction) " << this << endl;
  +  func = _func;
  +  args = _args;
  +  isFunction = true;
  +  singleShot = _singleShot;
  +}
  +
  +ScheduledAction::ScheduledAction(const QString &_code, bool _singleShot)
  +{
  +  //kdDebug(6070) << "ScheduledAction::ScheduledAction(!isFunction) " << this << endl;
  +  //func = 0;
  +  //args = 0;
  +  code = _code;
  +  isFunction = false;
  +  singleShot = _singleShot;
  +}
   
  -    ScriptInterpreter *interpreter = static_cast<ScriptInterpreter *>(KJSProxy::proxy(window->m_part)->interpreter());
   
  -    interpreter->setProcessingTimerCallback(true);
  +void ScheduledAction::execute(Window *window)
  +{
  +  ScriptInterpreter *interpreter = static_cast<ScriptInterpreter *>(KJSProxy::proxy(window->m_part)->interpreter());
     
  -    if (m_func) {
  -        if (m_func->isObject() && static_cast<ObjectImp *>(m_func.get())->implementsCall()) {
  -            ExecState *exec = interpreter->globalExec();
  -            assert(window == interpreter->globalObject());
  -            InterpreterLock lock;
  -            static_cast<ObjectImp *>(m_func.get())->call(exec, window, m_args);
  -            if (exec->hadException()) {
  -                ObjectImp *exception = exec->exception()->toObject(exec);
  -                exec->clearException();
  -                QString message = exception->get(exec, messagePropertyName)->toString(exec).qstring();
  -                int lineNumber = exception->get(exec, "line")->toInt32(exec);
  -                if (Interpreter::shouldPrintExceptions())
  -                    printf("(timer):%s\n", message.utf8().data());
  -                KWQ(window->m_part)->addMessageToConsole(message, lineNumber, QString());
  -            }
  +  interpreter->setProcessingTimerCallback(true);
  +  
  +  //kdDebug(6070) << "ScheduledAction::execute " << this << endl;
  +  if (isFunction) {
  +    if (func->implementsCall()) {
  +      // #### check this
  +      Q_ASSERT(window->m_part);
  +      if (window->m_part) {
  +        Interpreter *interpreter = KJSProxy::proxy(window->m_part)->interpreter();
  +        ExecState *exec = interpreter->globalExec();
  +        Q_ASSERT(window == interpreter->globalObject());
  +        ObjectImp *obj(window);
  +	InterpreterLock lock;
  +        func->call(exec, obj, args); // note that call() creates its own execution state for the func call
  +	if (exec->hadException()) {
  +          char *message = exec->exception()->toObject(exec)->get(exec, messagePropertyName)->toString(exec).ascii();
  +          int lineNumber = exec->exception()->toObject(exec)->get(exec, "line")->toInt32(exec);
  +	  if (Interpreter::shouldPrintExceptions()) {
  +	    printf("(timer):%s\n", message);
  +            
  +            KWQ(window->m_part)->addMessageToConsole(message, lineNumber, QString());
  +          }
  +	  exec->clearException();
           }
  -    } else
  -        window->m_part->executeScript(m_code);
  +      }
  +    }
  +  } else
  +    window->m_part->executeScript(code);
     
  -    // Update our document's rendering following the execution of the timeout callback.
  -    // FIXME: Why? Why not other documents, for example?
  -    DocumentImpl *doc = window->m_part->xmlDocImpl();
  -    if (doc)
  -        doc->updateRendering();
  +  // Update our document's rendering following the execution of the timeout callback.
  +  if (DocumentImpl *doc = window->m_part->xmlDocImpl())
  +    doc->updateRendering();
     
  -    interpreter->setProcessingTimerCallback(false);
  +  interpreter->setProcessingTimerCallback(false);
   }
   
   ////////////////////// WindowQObject ////////////////////////
   
   WindowQObject::WindowQObject(Window *w)
  -    : m_parent(w)
  +  : parent(w)
   {
  -    connect(w->m_part, SIGNAL(destroyed()), this, SLOT(parentDestroyed()));
  +  //kdDebug(6070) << "WindowQObject::WindowQObject " << this << endl;
  +  part = parent->m_part;
  +  connect( parent->m_part, SIGNAL( destroyed() ),
  +           this, SLOT( parentDestroyed() ) );
  +}
  +
  +WindowQObject::~WindowQObject()
  +{
  +  //kdDebug(6070) << "WindowQObject::~WindowQObject " << this << endl;
  +  parentDestroyed(); // reuse same code
   }
   
   void WindowQObject::parentDestroyed()
   {
  -    killTimers();
  -    for (QMapIterator<int, ScheduledAction *> it = m_timeouts.begin(); it != m_timeouts.end(); ++it)
  -        delete *it;
  -    m_timeouts.clear();
  +  //kdDebug(6070) << "WindowQObject::parentDestroyed " << this << " we have " << scheduledActions.count() << " actions in the map" << endl;
  +  killTimers();
  +  QMapIterator<int,ScheduledAction*> it;
  +  for (it = scheduledActions.begin(); it != scheduledActions.end(); ++it) {
  +    ScheduledAction *action = *it;
  +    //kdDebug(6070) << "WindowQObject::parentDestroyed deleting action " << action << endl;
  +    delete action;
  +  }
  +  scheduledActions.clear();
   }
   
  -int WindowQObject::installTimeout(const UString& handler, int t, bool singleShot)
  +int WindowQObject::installTimeout(const UString &handler, int t, bool singleShot)
   {
  -    int id = startTimer(t);
  -    ScheduledAction *action = new ScheduledAction(handler.qstring(), singleShot);
  -    m_timeouts.insert(id, action);
  -    return id;
  +  //kdDebug(6070) << "WindowQObject::installTimeout " << this << " " << handler.ascii() << endl;
  +  int id = startTimer(t);
  +  ScheduledAction *action = new ScheduledAction(handler.qstring(),singleShot);
  +  scheduledActions.insert(id, action);
  +  //kdDebug(6070) << this << " got id=" << id << " action=" << action << " - now having " << scheduledActions.count() << " actions"<<endl;
  +  return id;
   }
   
  -int WindowQObject::installTimeout(ValueImp *func, const List& args, int t, bool singleShot)
  +int WindowQObject::installTimeout(ValueImp *func, List args, int t, bool singleShot)
   {
  -    int id = startTimer(t);
  -    m_timeouts.insert(id, new ScheduledAction(func, args, singleShot));
  -    return id;
  +  ObjectImp *objFunc = static_cast<ObjectImp *>(func);
  +  int id = startTimer(t);
  +  scheduledActions.insert(id, new ScheduledAction(objFunc,args,singleShot));
  +  return id;
   }
   
  -PausedTimeouts *WindowQObject::pauseTimeouts()
  +QMap<int, ScheduledAction*> *WindowQObject::pauseTimeouts(const void *key)
   {
  -    size_t count = m_timeouts.count();
  -    if (count == 0)
  -        return 0;
  -    PausedTimeout *t = new PausedTimeout [count];
  -    PausedTimeouts *result = new PausedTimeouts(t, count);
  -    for (QMapIterator<int, ScheduledAction *> it = m_timeouts.begin(); it != m_timeouts.end(); ++it) {
  +    QMapIterator<int,ScheduledAction*> it;
  +
  +    QMap<int, ScheduledAction*>*pausedActions = new QMap<int, ScheduledAction*>;
  +    for (it = scheduledActions.begin(); it != scheduledActions.end(); ++it) {
           int timerId = it.key();
  -        timerIntervals(timerId, t->nextFireInterval, t->repeatInterval);
  -        t->timerId = timerId;
  -        t->action = it.data();
  -        ++t;
  -        killTimer(timerId);
  +        pauseTimer (timerId, key);
  +        pausedActions->insert(timerId, it.data());
       }
  -    m_timeouts.clear();
  -    return result;
  +    scheduledActions.clear();
  +    return pausedActions;
   }
   
  -void WindowQObject::resumeTimeouts(PausedTimeouts *timeouts)
  +void WindowQObject::resumeTimeouts(QMap<int, ScheduledAction*> *sa, const void *key)
   {
  -    if (!timeouts)
  -        return;
  -    size_t count = timeouts->numTimeouts();
  -    PausedTimeout *array = timeouts->takeTimeouts();
  -    for (size_t i = 0; i != count; ++i) {
  -        int timerId = array[i].timerId;
  -        m_timeouts.insert(timerId, array[i].action);
  -        restartTimer(timerId, array[i].nextFireInterval, array[i].repeatInterval);
  +    QMapIterator<int,ScheduledAction*> it;
  +    for (it = sa->begin(); it != sa->end(); ++it) {
  +        int timerId = it.key();
  +        scheduledActions.insert(timerId, it.data());
       }
  -    delete [] array;
  +    sa->clear();
  +    resumeTimers (key, this);
   }
   
   void WindowQObject::clearTimeout(int timerId, bool delAction)
   {
  -    killTimer(timerId);
  -    if (delAction) {
  -        QMapIterator<int, ScheduledAction *> it = m_timeouts.find(timerId);
  -        if (it != m_timeouts.end()) {
  -            delete *it;
  -            m_timeouts.remove(it);
  -        }
  +  //kdDebug(6070) << "WindowQObject::clearTimeout " << this << " timerId=" << timerId << " delAction=" << delAction << endl;
  +  killTimer(timerId);
  +  if (delAction) {
  +    QMapIterator<int,ScheduledAction*> it = scheduledActions.find(timerId);
  +    if (it != scheduledActions.end()) {
  +      ScheduledAction *action = *it;
  +      scheduledActions.remove(it);
  +      delete action;
       }
  +  }
   }
   
   void WindowQObject::timerEvent(QTimerEvent *e)
   {
  -    QMapIterator<int, ScheduledAction *> it = m_timeouts.find(e->timerId());
  +  QMapIterator<int,ScheduledAction*> it = scheduledActions.find(e->timerId());
  +  if (it != scheduledActions.end()) {
       ScheduledAction *action = *it;
  -    bool singleShot = action->singleShot();
  +    bool singleShot = action->singleShot;
  +    //kdDebug(6070) << "WindowQObject::timerEvent " << this << " action=" << action << " singleShot:" << singleShot << endl;
   
  -    // remove single shots before executing
  -    if (singleShot) {
  -        clearTimeout(e->timerId(), false);
  -        m_timeouts.remove(it);
  +    // remove single shots installed by setTimeout()
  +    if (singleShot)
  +    {
  +      clearTimeout(e->timerId(),false);
  +      scheduledActions.remove(it);
       }
  +        
  +    if (!parent->part().isNull())
  +      action->execute(parent);
   
  -    action->execute(m_parent);
  -
  -    // It is important not to use action->singleShot here.
  -    // The action could have been deleted already if not single shot the
  +    // It is important to test singleShot and not action->singleShot here - the
  +    // action could have been deleted already if not single shot and if the
       // JS code called by execute() calls clearTimeout().
       if (singleShot)
  -        delete action;
  +      delete action;
  +  } else
  +    kdWarning(6070) << "WindowQObject::timerEvent this=" << this << " timer " << e->timerId()
  +                    << " not found (" << scheduledActions.count() << " actions in map)" << endl;
  +}
  +
  +void WindowQObject::timeoutClose()
  +{
  +  if (!parent->part().isNull())
  +  {
  +    //kdDebug(6070) << "WindowQObject::timeoutClose -> closing window" << endl;
  +    delete parent->m_part;
  +  }
  +}
  +
  +#if APPLE_CHANGES
  +bool WindowQObject::hasTimeouts()
  +{
  +    return scheduledActions.count();
   }
  +#endif
  +
   
   const ClassInfo FrameArray::info = { "FrameArray", 0, &FrameArrayTable, 0 };
   
  @@ -2131,6 +2231,7 @@
   @end
   */
   
  +
   ValueImp *FrameArray::getValueProperty(ExecState *exec, int token)
   {
     switch (token) {
  @@ -2707,17 +2808,6 @@
   
   /////////////////////////////////////////////////////////////////////////////
   
  -PausedTimeouts::~PausedTimeouts()
  -{
  -    PausedTimeout *array = m_array;
  -    if (!array)
  -        return;
  -    size_t count = m_length;
  -    for (size_t i = 0; i != count; ++i)
  -        delete array[i].action;
  -    delete [] array;
  -}
  -
   } // namespace KJS
   
   #include "kjs_window.moc"
  
  
  
  1.56      +58 -73    WebCore/khtml/ecma/kjs_window.h
  
  Index: kjs_window.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/ecma/kjs_window.h,v
  retrieving revision 1.55
  retrieving revision 1.56
  diff -u -r1.55 -r1.56
  --- kjs_window.h	7 Nov 2005 20:52:09 -0000	1.55
  +++ kjs_window.h	9 Nov 2005 02:46:27 -0000	1.56
  @@ -40,57 +40,17 @@
   
   namespace KJS {
   
  -    class BarInfo;
  -    class FrameArray;
  -    class History;
  -    class JSEventListener;
  -    class JSLazyEventListener;
  -    class JSUnprotectedEventListener;
  -    class Location;
  -    class PausedTimeout;
  -    class ScheduledAction;
  -    class Selection;
  -    class Window;
  -    class WindowFunc;
  -
  -    class PausedTimeouts {
  -    public:
  -        PausedTimeouts(PausedTimeout *a, size_t length) : m_array(a), m_length(length) { }
  -        ~PausedTimeouts();
  -
  -        size_t numTimeouts() const { return m_length; }
  -        PausedTimeout *takeTimeouts()
  -            { PausedTimeout *a = m_array; m_array = 0; return a; }
  -
  -    private:
  -        PausedTimeout *m_array;
  -        size_t m_length;
  -
  -        PausedTimeouts(const PausedTimeouts&);
  -        PausedTimeouts& operator=(const PausedTimeouts&);
  -    };
  -
  -    class WindowQObject : public QObject {
  -        Q_OBJECT
  -    public:
  -        WindowQObject(Window *);
  -        ~WindowQObject() { parentDestroyed(); }
  -
  -        int installTimeout(const UString &handler, int interval, bool singleShot);
  -        int installTimeout(ValueImp *function, const List &, int interval, bool singleShot);
  -        void clearTimeout(int timerId, bool delAction = true);
  -
  -        PausedTimeouts *pauseTimeouts();
  -        void resumeTimeouts(PausedTimeouts *);
  -
  -    private slots:
  -        void parentDestroyed();
  -    private:
  -        virtual void timerEvent(QTimerEvent *);
  -
  -        Window *m_parent;
  -        QMap<int, ScheduledAction *> m_timeouts;
  -  };
  +  class WindowFunc;
  +  class WindowQObject;
  +  class Location;
  +  class Selection;
  +  class BarInfo;
  +  class History;
  +  class FrameArray;
  +  class JSEventListener;
  +  class JSUnprotectedEventListener;
  +  class JSLazyEventListener;
  +  class ScheduledAction;
   
     class Screen : public ObjectImp {
     public:
  @@ -138,19 +98,21 @@
       ValueImp *getValueProperty(ExecState *exec, int token) const;
       virtual void put(ExecState *exec, const Identifier &propertyName, ValueImp *value, int attr = None);
       virtual bool toBoolean(ExecState *exec) const;
  -
  -    int installTimeout(const UString &handler, int t, bool singleShot) { return winq->installTimeout(handler, t, singleShot); }
  -    int installTimeout(ValueImp *function, List &args, int t, bool singleShot) { return winq->installTimeout(function, args, t, singleShot); }
  -    void clearTimeout(int timerId) { winq->clearTimeout(timerId); }
  -    PausedTimeouts *pauseTimeouts() { return winq->pauseTimeouts(); }
  -    void resumeTimeouts(PausedTimeouts *t) { winq->resumeTimeouts(t); }
  +    int installTimeout(const UString &handler, int t, bool singleShot);
  +    int installTimeout(ValueImp *function, List &args, int t, bool singleShot);
  +    void clearTimeout(int timerId);
  +#ifdef APPLE_CHANGES
  +    bool hasTimeouts();
  +    QMap<int, ScheduledAction*> *pauseTimeouts(const void *key);
  +    void resumeTimeouts(QMap<int, ScheduledAction*>*sa, const void *key);
       
       KJS::Interpreter *interpreter() const;
   
  +    static bool isSafeScript (const KJS::ScriptInterpreter *origin, const KJS::ScriptInterpreter *target);
  +#endif
       void scheduleClose();
           
       bool isSafeScript(ExecState *exec) const;
  -    static bool isSafeScript(const ScriptInterpreter *origin, const ScriptInterpreter *target);
       Location *location() const;
       Selection *selection() const;
       BarInfo *locationbar(ExecState *exec) const;
  @@ -224,21 +186,44 @@
      * time interval, either once or repeatedly. Used for window.setTimeout()
      * and window.setInterval()
      */
  -    class ScheduledAction {
  -    public:
  -        ScheduledAction(ValueImp *func, const List& args, bool singleShot)
  -            : m_func(func), m_args(args), m_singleShot(singleShot) { }
  -        ScheduledAction(const QString& code, bool singleShot)
  -            : m_code(code), m_singleShot(singleShot) { }
  -        void execute(Window *);
  -        bool singleShot() const { return m_singleShot; }
  -
  -    private:
  -        ProtectedPtr<ValueImp> m_func;
  -        List m_args;
  -        QString m_code;
  -        bool m_singleShot;
  -    };
  +  class ScheduledAction {
  +  public:
  +    ScheduledAction(ObjectImp *_func, List _args, bool _singleShot);
  +    ScheduledAction(const QString &_code, bool _singleShot);
  +    void execute(Window *window);
  +
  +    ProtectedPtr<ObjectImp> func;
  +    List args;
  +    QString code;
  +    bool isFunction;
  +    bool singleShot;
  +  };
  +
  +  class WindowQObject : public QObject {
  +    Q_OBJECT
  +  public:
  +    WindowQObject(Window *w);
  +    ~WindowQObject();
  +    int installTimeout(const UString &handler, int t, bool singleShot);
  +    int installTimeout(ValueImp *func, List args, int t, bool singleShot);
  +    void clearTimeout(int timerId, bool delAction = true);
  +#ifdef APPLE_CHANGES
  +    bool hasTimeouts();
  +    QMap<int, ScheduledAction*> *WindowQObject::pauseTimeouts(const void *key);
  +    void WindowQObject::resumeTimeouts(QMap<int, ScheduledAction*> *sa, const void *key);
  +#endif
  +
  +  public slots:
  +    void timeoutClose();
  +  protected slots:
  +    void parentDestroyed();
  +  protected:
  +    void timerEvent(QTimerEvent *e);
  +  private:
  +    Window *parent;
  +    KHTMLPart *part;   		// not guarded, may be dangling
  +    QMap<int, ScheduledAction*> scheduledActions;
  +  };
   
     class Location : public ObjectImp {
     public:
  
  
  
  1.232     +2 -3      WebCore/kwq/KWQKHTMLPart.h
  
  Index: KWQKHTMLPart.h
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQKHTMLPart.h,v
  retrieving revision 1.231
  retrieving revision 1.232
  diff -u -r1.231 -r1.232
  --- KWQKHTMLPart.h	7 Nov 2005 20:52:10 -0000	1.231
  +++ KWQKHTMLPart.h	9 Nov 2005 02:46:28 -0000	1.232
  @@ -61,7 +61,6 @@
   }
   
   namespace KJS {
  -    class PausedTimeouts;
       class SavedProperties;
       class SavedBuiltins;
       class ScheduledAction;
  @@ -161,8 +160,8 @@
   
       void unfocusWindow();
   
  -    KJS::PausedTimeouts *pauseTimeouts();
  -    void resumeTimeouts(KJS::PausedTimeouts *);
  +    QMap<int, KJS::ScheduledAction*> *pauseActions(const void *key);
  +    void resumeActions(QMap<int, KJS::ScheduledAction*> *actions, const void *key);
       
       bool canCachePage();
       void saveWindowProperties(KJS::SavedProperties *windowProperties);
  
  
  
  1.686     +104 -30   WebCore/kwq/KWQKHTMLPart.mm
  
  Index: KWQKHTMLPart.mm
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQKHTMLPart.mm,v
  retrieving revision 1.685
  retrieving revision 1.686
  diff -u -r1.685 -r1.686
  --- KWQKHTMLPart.mm	7 Nov 2005 20:52:10 -0000	1.685
  +++ KWQKHTMLPart.mm	9 Nov 2005 02:46:28 -0000	1.686
  @@ -88,18 +88,87 @@
   
   #undef _KWQ_TIMING
   
  -using namespace DOM;
  -using namespace EventNames;
  -using namespace HTMLNames;
  +using namespace DOM::EventNames;
  +using namespace DOM::HTMLNames;
   
  -using namespace KJS;
  -using namespace Bindings;
  +using DOM::AtomicString;
  +using DOM::ClipboardEventImpl;
  +using DOM::DocumentFragmentImpl;
  +using DOM::DocumentImpl;
  +using DOM::DocumentMarker;
  +using DOM::DOMString;
  +using DOM::ElementImpl;
  +using DOM::EventImpl;
  +using DOM::HTMLDocumentImpl;
  +using DOM::HTMLElementImpl;
  +using DOM::HTMLFormElementImpl;
  +using DOM::HTMLFrameElementImpl;
  +using DOM::HTMLGenericFormElementImpl;
  +using DOM::HTMLTableCellElementImpl;
  +using DOM::Node;
  +using DOM::NodeImpl;
  +using DOM::Position;
  +using DOM::Range;
  +using DOM::RangeImpl;
  +using DOM::TextImpl;
  +
  +using khtml::Cache;
  +using khtml::CharacterIterator;
  +using khtml::ChildFrame;
  +using khtml::Decoder;
  +using khtml::DashboardRegionValue;
  +using khtml::EditCommandPtr;
  +using khtml::endOfWord;
  +using khtml::findPlainText;
  +using khtml::FocusState;
  +using khtml::InlineTextBox;
  +using khtml::LeftWordIfOnBoundary;
  +using khtml::MouseDoubleClickEvent;
  +using khtml::MouseMoveEvent;
  +using khtml::MousePressEvent;
  +using khtml::MouseReleaseEvent;
  +using khtml::parseURL;
  +using khtml::PRE;
  +using khtml::RenderCanvas;
  +using khtml::RenderImage;
  +using khtml::RenderLayer;
  +using khtml::RenderListItem;
  +using khtml::RenderObject;
  +using khtml::RenderStyle;
  +using khtml::RenderTableCell;
  +using khtml::RenderText;
  +using khtml::theme;
  +using khtml::RenderWidget;
  +using khtml::RightWordIfOnBoundary;
  +using khtml::SelectionController;
  +using khtml::SELECT_IGNORE;
  +using khtml::setEnd;
  +using khtml::setStart;
  +using khtml::ShadowData;
  +using khtml::startOfWord;
  +using khtml::startVisiblePosition;
  +using khtml::StyleDashboardRegion;
  +using khtml::TextIterator;
  +using khtml::DOWNSTREAM;
  +using khtml::VP_UPSTREAM_IF_POSSIBLE;
  +using khtml::VISIBLE;
  +using khtml::VisiblePosition;
  +using khtml::WordAwareIterator;
  +
  +using KIO::Job;
  +
  +using KJS::Interpreter;
  +using KJS::InterpreterLock;
  +using KJS::Location;
  +using KJS::SavedBuiltins;
  +using KJS::SavedProperties;
  +using KJS::ScheduledAction;
  +using KJS::Window;
   
  -using namespace khtml;
  +using KJS::Bindings::Instance;
   
  -using namespace KIO;
  -
  -using namespace KParts;
  +using KParts::ReadOnlyPart;
  +using KParts::URLArgs;
   
   NSEvent *KWQKHTMLPart::_currentEvent = nil;
   
  @@ -1078,13 +1147,11 @@
       
       KWQ_BLOCK_EXCEPTIONS;
       if (d->m_redirectionTimer.isActive()) {
  -        NSDate *fireDate = [[NSDate alloc] initWithTimeIntervalSinceReferenceDate:d->m_redirectionTimer.fireDate()];
           [_bridge reportClientRedirectToURL:KURL(d->m_redirectURL).getNSURL()
                                        delay:d->m_delayRedirect
  -                                  fireDate:fireDate
  +                                  fireDate:[d->m_redirectionTimer.getNSTimer() fireDate]
                                  lockHistory:d->m_redirectLockHistory
                                  isJavaScriptFormAction:d->m_executingJavaScriptFormAction];
  -        [fireDate release];
       } else {
           [_bridge reportClientRedirectCancelled:d->m_cancelWithLoadInProgress];
       }
  @@ -1405,22 +1472,24 @@
       [_bridge windowObjectCleared];
   }
   
  -PausedTimeouts *KWQKHTMLPart::pauseTimeouts()
  +QMap<int, ScheduledAction*> *KWQKHTMLPart::pauseActions(const void *key)
   {
       if (d->m_doc && d->m_jscript) {
           Window *w = Window::retrieveWindow(this);
  -        if (w)
  -            return w->pauseTimeouts();
  +        if (w && w->hasTimeouts()) {
  +            return w->pauseTimeouts(key);
  +        }
       }
       return 0;
   }
   
  -void KWQKHTMLPart::resumeTimeouts(PausedTimeouts *t)
  +void KWQKHTMLPart::resumeActions(QMap<int, ScheduledAction*> *actions, const void *key)
   {
       if (d->m_doc && d->m_jscript && d->m_bJScriptEnabled) {
           Window *w = Window::retrieveWindow(this);
  -        if (w)
  -            w->resumeTimeouts(t);
  +        if (w) {
  +            w->resumeTimeouts(actions, key);
  +        }
       }
   }
   
  @@ -1503,13 +1572,14 @@
       SavedProperties *windowProperties = [state windowProperties];
       SavedProperties *locationProperties = [state locationProperties];
       SavedBuiltins *interpreterBuiltins = [state interpreterBuiltins];
  -    PausedTimeouts *timeouts = [state pausedTimeouts];
  +    QMap<int, ScheduledAction*> *actions = [state pausedActions];
       
       cancelRedirection();
   
       // We still have to close the previous part page.
  -    if (!d->m_restored)
  +    if (!d->m_restored){
           closeURL();
  +    }
               
       d->m_bComplete = false;
       
  @@ -1517,12 +1587,13 @@
       d->m_bLoadEventEmitted = true;
       
       // delete old status bar msg's from kjs (if it _was_ activated on last URL)
  -    if (d->m_bJScriptEnabled) {
  +    if( d->m_bJScriptEnabled )
  +    {
           d->m_kjsStatusBarText = QString::null;
           d->m_kjsDefaultStatusBarText = QString::null;
       }
   
  -    ASSERT(url);
  +    ASSERT (url);
       
       m_url = *url;
       
  @@ -1556,24 +1627,27 @@
       d->m_mousePressNode.reset(mousePressNode);
       
       Decoder *decoder = doc->decoder();
  -    if (decoder)
  +    if (decoder) {
           decoder->ref();
  -    if (d->m_decoder)
  +    }
  +    if (d->m_decoder) {
           d->m_decoder->deref();
  +    }
       d->m_decoder = decoder;
   
  -    doc->setParseMode([state parseMode]);
  +    doc->setParseMode ([state parseMode]);
       
       updatePolicyBaseURL();
   
       { // scope the lock
           InterpreterLock lock;
  -        restoreWindowProperties(windowProperties);
  -        restoreLocationProperties(locationProperties);
  -        restoreInterpreterBuiltins(*interpreterBuiltins);
  +        restoreWindowProperties (windowProperties);
  +        restoreLocationProperties (locationProperties);
  +        restoreInterpreterBuiltins (*interpreterBuiltins);
       }
   
  -    resumeTimeouts(timeouts);
  +    if (actions)
  +        resumeActions (actions, state);
       
       checkCompleted();
   }
  @@ -4158,7 +4232,7 @@
       int exception = 0;
   
       ASSERT(!range || range->startContainer(exception) == range->endContainer(exception));
  -    ASSERT(!range || range->collapsed(exception) || range->startContainer(exception)->nodeType() == DOM::Node::TEXT_NODE);
  +    ASSERT(!range || range->collapsed(exception) || range->startContainer(exception)->nodeType() == Node::TEXT_NODE);
   
       if (attributes == nil) {
           m_markedTextUsesUnderlines = false;
  
  
  
  1.38      +33 -20    WebCore/kwq/KWQObject.h
  
  Index: KWQObject.h
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQObject.h,v
  retrieving revision 1.37
  retrieving revision 1.38
  diff -u -r1.37 -r1.38
  --- KWQObject.h	7 Nov 2005 20:52:11 -0000	1.37
  +++ KWQObject.h	9 Nov 2005 02:46:29 -0000	1.38
  @@ -26,10 +26,14 @@
   #ifndef QOBJECT_H_
   #define QOBJECT_H_
   
  -#include "KWQEvent.h"
  -#include "KWQPtrList.h"
  +#include "KWQDef.h"
   #include "KWQSignal.h"
  +
  +#include "KWQNamespace.h"
  +#include "KWQString.h"
  +#include "KWQEvent.h"
   #include "KWQStringList.h"
  +#include "KWQPtrList.h"
   
   #define slots : public
   #define SLOT(x) "SLOT:" #x
  @@ -39,30 +43,36 @@
   #define Q_OBJECT
   #define Q_PROPERTY(text)
   
  -class QBitmap;
  -class QBrush;
  -class QColor;
  -class QColorGroup;
   class QEvent;
  -class QFont;
  -class QFontMetrics;
  -class QImage;
  -class QMovie;
   class QPaintDevice;
   class QPaintDeviceMetrics;
  -class QPainter;
  +class QWidget;
  +class QColor;
  +class QColorGroup;
   class QPalette;
  -class QRect;
  +class QPainter;
   class QRegion;
   class QSize;
   class QSizePolicy;
  +class QRect;
  +class QFont;
  +class QFontMetrics;
  +class QBrush;
  +class QBitmap;
  +class QMovie;
   class QTimer;
  +class QImage;
   class QVariant;
  -class QWidget;
   
   class KWQGuardedPtrBase;
   class KWQSignal;
   
  +#ifdef __OBJC__
  + at class NSTimer;
  +#else
  +class NSTimer;
  +#endif
  +
   class QObject : public Qt {
   public:
       QObject(QObject *parent = 0, const char *name = 0);
  @@ -75,11 +85,12 @@
   
       bool inherits(const char *className) const;
   
  -    int startTimer(int interval);
  -    void killTimer(int timerId);
  +    int startTimer(int);
  +    void killTimer(int);
       void killTimers();
  -    void timerIntervals(int timerId, int& nextFireInterval, int& repeatInterval) const;
  -    void restartTimer(int timerId, int nextFireInterval, int repeatInterval);
  +    void pauseTimer(int _timerId, const void *key);
  +    void resumeTimers(const void *key, QObject *target);
  +    static void clearPausedTimers (const void *key);
       
       virtual void timerEvent(QTimerEvent *);
   
  @@ -106,6 +117,8 @@
       virtual bool isQScrollView() const;
   
   private:
  +    void _addTimer(NSTimer *timer, int _timerId);
  +
       // no copying or assignment
       QObject(const QObject &);
       QObject &operator=(const QObject &);
  @@ -132,11 +145,11 @@
   class KWQObjectSenderScope
   {
   public:
  -    KWQObjectSenderScope(const QObject *o) : m_savedSender(QObject::_sender) { QObject::_sender = o; }
  -    ~KWQObjectSenderScope() { QObject::_sender = m_savedSender; }
  +    KWQObjectSenderScope(const QObject *);
  +    ~KWQObjectSenderScope();
   
   private:
  -    const QObject *m_savedSender;
  +    const QObject *_savedSender;
   };
   
   #endif
  
  
  
  1.51      +224 -140  WebCore/kwq/KWQObject.mm
  
  Index: KWQObject.mm
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQObject.mm,v
  retrieving revision 1.50
  retrieving revision 1.51
  diff -u -r1.50 -r1.51
  --- KWQObject.mm	8 Nov 2005 21:54:23 -0000	1.50
  +++ KWQObject.mm	9 Nov 2005 02:46:29 -0000	1.51
  @@ -28,53 +28,48 @@
   
   #import "KWQVariant.h"
   #import <kxmlcore/Assertions.h>
  -#import <kxmlcore/FastMalloc.h>
   
  -struct KWQObjectTimer {
  -    QObject *target;
  -    int timerId;
  -    CFRunLoopTimerRef runLoopTimer; // non-0 for running timers
  -    CFIndex deferredTimerArrayIndex; // kCFNotFound if not deferred
  -};
  +// The Foundation-level Cocoa calls here (NSTimer, NSDate, NSArray,
  +// NSDictionary) should be exception-free, so no need to block
  +// exceptions.
   
   const QObject *QObject::_sender;
   bool QObject::_defersTimers;
   
   static CFMutableDictionaryRef timerDictionaries;
  -static CFMutableArrayRef deferredTimers;
  +static CFMutableDictionaryRef allPausedTimers;
  +static NSMutableArray *deferredTimers;
   static bool deferringTimers;
  -static CFRunLoopTimerRef sendDeferredTimerEventsTimer;
   
  -static int lastTimerIdUsed;
  -
  -QObject::QObject(QObject *parent, const char *name)
  -    : _signalListHead(0), _signalsBlocked(false)
  -    , _destroyed(this, SIGNAL(destroyed()))
  -    , _eventFilterObject(0)
  + at interface KWQObjectTimerTarget : NSObject
   {
  -    _guardedPtrDummyList.append(this);
  + at public
  +    QObject *target;
  +    int timerId;
  +    NSTimeInterval remainingTime;
   }
   
  -QObject::~QObject()
  -{
  -    _destroyed.call();
  -    ASSERT(_signalListHead == &_destroyed);
  -    killTimers();
  -}
  +- initWithQObject:(QObject *)object timerId:(int)timerId;
  +- (void)timerFired;
  +
  + at end
   
   KWQSignal *QObject::findSignal(const char *signalName) const
   {
  -    for (KWQSignal *signal = _signalListHead; signal; signal = signal->_next)
  -        if (KWQNamesMatch(signalName, signal->_name))
  +    for (KWQSignal *signal = _signalListHead; signal; signal = signal->_next) {
  +        if (KWQNamesMatch(signalName, signal->_name)) {
               return signal;
  +        }
  +    }
       return 0;
   }
   
   void QObject::connect(const QObject *sender, const char *signalName, const QObject *receiver, const char *member)
   {
  -    // FIXME: Assert that sender is not 0 rather than doing the if statement, then fix callers who call with 0.
  -    if (!sender)
  +    // FIXME: Assert that sender is not NULL rather than doing the if statement.
  +    if (!sender) {
           return;
  +    }
       
       KWQSignal *signal = sender->findSignal(signalName);
       if (!signal) {
  @@ -88,7 +83,7 @@
               && !KWQNamesMatch(member, SLOT(slotShowDocument(const QString &, const QString &)))
               && !KWQNamesMatch(member, SLOT(slotViewCleared())) // FIXME: Should implement this one!
               )
  -        ERROR("connecting member %s to signal %s, but that signal was not found", member, signalName);
  +	ERROR("connecting member %s to signal %s, but that signal was not found", member, signalName);
   #endif
           return;
       }
  @@ -97,160 +92,206 @@
   
   void QObject::disconnect(const QObject *sender, const char *signalName, const QObject *receiver, const char *member)
   {
  -    // FIXME: Assert that sender is not 0 rather than doing the if statement, then fix callers who call with 0.
  +    // FIXME: Assert that sender is not NULL rather than doing the if statement.
       if (!sender)
           return;
       
       KWQSignal *signal = sender->findSignal(signalName);
       if (!signal) {
  -        // FIXME: Put a call to ERROR here and clean up callers who do this.
  +        // FIXME: ERROR
           return;
       }
       signal->disconnect(KWQSlot(const_cast<QObject *>(receiver), member));
   }
   
  -void QObject::timerEvent(QTimerEvent *)
  +KWQObjectSenderScope::KWQObjectSenderScope(const QObject *o)
  +    : _savedSender(QObject::_sender)
   {
  +    QObject::_sender = o;
   }
   
  -bool QObject::event(QEvent *)
  +KWQObjectSenderScope::~KWQObjectSenderScope()
   {
  -    return false;
  +    QObject::_sender = _savedSender;
   }
   
  -static void timerFired(CFRunLoopTimerRef runLoopTimer, void *info)
  +QObject::QObject(QObject *parent, const char *name)
  +    : _signalListHead(0), _signalsBlocked(false)
  +    , _destroyed(this, SIGNAL(destroyed()))
  +    , _eventFilterObject(0)
   {
  -    KWQObjectTimer *timer = static_cast<KWQObjectTimer *>(info);
  -    if (deferringTimers) {
  -        if (timer->deferredTimerArrayIndex == kCFNotFound) {
  -            if (!deferredTimers)
  -                deferredTimers = CFArrayCreateMutable(0, 0, 0);
  -            timer->deferredTimerArrayIndex = CFArrayGetCount(deferredTimers);
  -            CFArrayAppendValue(deferredTimers, timer);
  -        }
  -    } else {
  -        QTimerEvent event(timer->timerId);
  -        timer->target->timerEvent(&event);
  -    }
  +    _guardedPtrDummyList.append(this);
   }
   
  -int QObject::startTimer(int interval)
  +QObject::~QObject()
   {
  -    int timerId = ++lastTimerIdUsed;
  -    restartTimer(timerId, interval, interval);
  -    return timerId;
  +    _destroyed.call();
  +    ASSERT(_signalListHead == &_destroyed);
  +    killTimers();
   }
   
  -void QObject::restartTimer(int timerId, int nextFireInterval, int repeatInterval)
  +void QObject::timerEvent(QTimerEvent *te)
   {
  -    ASSERT(timerId > 0);
  -    ASSERT(timerId <= lastTimerIdUsed);
  -
  -    if (!timerDictionaries)
  -        timerDictionaries = CFDictionaryCreateMutable(0, 0, 0, &kCFTypeDictionaryValueCallBacks);
  -
  -    CFMutableDictionaryRef timers = (CFMutableDictionaryRef)CFDictionaryGetValue(timerDictionaries, this);
  -    if (!timers) {
  -        timers = CFDictionaryCreateMutable(0, 0, 0, 0);
  -        CFDictionarySetValue(timerDictionaries, this, timers);
  -        CFRelease(timers);
  -    }
  -
  -    ASSERT(!CFDictionaryGetValue(timers, reinterpret_cast<void *>(timerId)));
  -
  -    KWQObjectTimer *timer = static_cast<KWQObjectTimer *>(fastMalloc(sizeof(KWQObjectTimer)));
  -    timer->target = this;
  -    timer->timerId = timerId;
  -    CFRunLoopTimerContext context = { 0, timer, 0, 0, 0 };
  -    CFRunLoopTimerRef runLoopTimer = CFRunLoopTimerCreate(0, CFAbsoluteTimeGetCurrent() + nextFireInterval * 0.001,
  -        repeatInterval * 0.001, 0, 0, timerFired, &context);
  -    timer->runLoopTimer = runLoopTimer;
  -    timer->deferredTimerArrayIndex = kCFNotFound;
  -
  -    CFDictionarySetValue(timers, reinterpret_cast<void *>(timerId), timer);
  +}
   
  -    CFRunLoopAddTimer(CFRunLoopGetCurrent(), runLoopTimer, kCFRunLoopDefaultMode);
  +bool QObject::event(QEvent *)
  +{
  +    return false;
   }
   
  -void QObject::timerIntervals(int timerId, int& nextFireInterval, int& repeatInterval) const
  +void QObject::pauseTimer (int _timerId, const void *key)
   {
  -    nextFireInterval = -1;
  -    repeatInterval = -1;
  -    if (!timerDictionaries)
  -        return;
  -    CFMutableDictionaryRef timers = (CFMutableDictionaryRef)CFDictionaryGetValue(timerDictionaries, this);
  -    if (!timers)
  -        return;
  -    KWQObjectTimer *timer = (KWQObjectTimer *)CFDictionaryGetValue(timers, reinterpret_cast<void *>(timerId));
  -    if (!timer)
  -        return;
  -    nextFireInterval = (int)((CFRunLoopTimerGetNextFireDate(timer->runLoopTimer) - CFAbsoluteTimeGetCurrent()) * 1000);
  -    repeatInterval = (int)(CFRunLoopTimerGetInterval(timer->runLoopTimer) * 1000);
  +    NSMutableDictionary *timers = (NSMutableDictionary *)CFDictionaryGetValue(timerDictionaries, this);
  +    NSNumber *timerId = [NSNumber numberWithInt:_timerId];
  +    NSTimer *timer = (NSTimer *)[timers objectForKey:timerId];
  +
  +    if ([timer isValid]){
  +        KWQObjectTimerTarget *target = (KWQObjectTimerTarget *)[timer userInfo];
  +
  +        if (target){
  +            NSDate *fireDate = [timer fireDate];
  +            NSTimeInterval remainingTime = [fireDate timeIntervalSinceDate: [NSDate date]];
  +        
  +            if (remainingTime < 0)
  +                remainingTime = DBL_EPSILON;
  +            
  +            if (allPausedTimers == NULL) {
  +                // The global targets dictionary itself leaks, but the contents are removed
  +                // when each timer fires or is killed.
  +                allPausedTimers = CFDictionaryCreateMutable(NULL, 0, NULL, &kCFTypeDictionaryValueCallBacks);
  +            }
  +    
  +            NSMutableArray *pausedTimers = (NSMutableArray *)CFDictionaryGetValue(allPausedTimers, key);
  +            if (pausedTimers == nil) {
  +                pausedTimers = [[NSMutableArray alloc] init];
  +                CFDictionarySetValue(allPausedTimers, key, pausedTimers);
  +                [pausedTimers release];
  +            }
  +            
  +            target->remainingTime = remainingTime;
  +            [pausedTimers addObject:target];
  +                    
  +            [timer invalidate];
  +            [timers removeObjectForKey:timerId];
  +        }
  +    }
   }
   
  -static void deleteTimer(KWQObjectTimer *timer)
  +void QObject::_addTimer(NSTimer *timer, int _timerId)
   {
  -    CFRunLoopTimerInvalidate(timer->runLoopTimer);
  -    CFRelease(timer->runLoopTimer);
  +    NSMutableDictionary *timers = (NSMutableDictionary *)CFDictionaryGetValue(timerDictionaries, this);
  +    if (timers == nil) {
  +        timers = [[NSMutableDictionary alloc] init];
  +        CFDictionarySetValue(timerDictionaries, this, timers);
  +        [timers release];
  +    }
  +    [timers setObject:timer forKey:[NSNumber numberWithInt:_timerId]];
  +}
   
  -    CFIndex i = timer->deferredTimerArrayIndex;
  -    if (i != kCFNotFound)
  -        CFArraySetValueAtIndex(deferredTimers, i, 0);
  +static int nextTimerID = 1;
   
  -    fastFree(timer);
  +void QObject::clearPausedTimers (const void *key)
  +{
  +    if (allPausedTimers)
  +        CFDictionaryRemoveValue(allPausedTimers, key);
   }
   
  -void QObject::killTimer(int timerId)
  +void QObject::resumeTimers (const void *key, QObject *_target)
   {
  -    if (!timerDictionaries)
  -        return;
  -    CFMutableDictionaryRef timers = (CFMutableDictionaryRef)CFDictionaryGetValue(timerDictionaries, this);
  -    if (!timers)
  +    if (allPausedTimers == NULL) {
           return;
  -    KWQObjectTimer *timer = (KWQObjectTimer *)CFDictionaryGetValue(timers, reinterpret_cast<void *>(timerId));
  -    if (!timer)
  -        return;
  -    deleteTimer(timer);
  -    CFDictionaryRemoveValue(timers, reinterpret_cast<void *>(timerId));
  +    }
  +    
  +    int maxId = MAX(0, nextTimerID);
  +        
  +    NSMutableArray *pausedTimers = (NSMutableArray *)CFDictionaryGetValue(allPausedTimers, key);
  +    if (pausedTimers == nil)
  +        return;
  +
  +    int count = [pausedTimers count];
  +    while (count--){
  +        KWQObjectTimerTarget *target = [pausedTimers objectAtIndex: count];
  +        target->target = _target;
  +        NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:target->remainingTime
  +            target:target
  +            selector:@selector(timerFired)
  +            userInfo:target
  +            repeats:YES];
  +        [pausedTimers removeLastObject];
  +
  +        maxId = MAX (maxId, target->timerId);
  +                        
  +        _addTimer (timer, target->timerId);
  +    }
  +    nextTimerID = maxId+1;
  +    
  +    CFDictionaryRemoveValue(allPausedTimers, key);
   }
   
  -static void deleteOneTimer(const void *key, const void *value, void *context)
  +int QObject::startTimer(int milliseconds)
   {
  -    deleteTimer((KWQObjectTimer *)value);
  +    if (timerDictionaries == NULL) {
  +        // The global timers dictionary itself lives forever, but the contents are removed
  +        // when each timer fires or is killed.
  +        timerDictionaries = CFDictionaryCreateMutable(NULL, 0, NULL, &kCFTypeDictionaryValueCallBacks);
  +    }
  +    
  +    NSMutableDictionary *timers = (NSMutableDictionary *)CFDictionaryGetValue(timerDictionaries, this);
  +    if (timers == nil) {
  +        timers = [[NSMutableDictionary alloc] init];
  +        CFDictionarySetValue(timerDictionaries, this, timers);
  +        [timers release];
  +    }
  +
  +    KWQObjectTimerTarget *target = [[KWQObjectTimerTarget alloc] initWithQObject:this timerId:nextTimerID];
  +    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:milliseconds / 1000.0
  +          target:target
  +        selector:@selector(timerFired)
  +        userInfo:target
  +         repeats:YES];
  +    [target release];
  +    
  +    _addTimer (timer, nextTimerID);
  +    
  +    return nextTimerID++;    
   }
   
  -void QObject::killTimers()
  +void QObject::killTimer(int _timerId)
   {
  -    if (!timerDictionaries)
  +    if (_timerId == 0) {
           return;
  -    CFMutableDictionaryRef timers = (CFMutableDictionaryRef)CFDictionaryGetValue(timerDictionaries, this);
  -    if (!timers)
  +    }
  +    if (timerDictionaries == NULL) {
           return;
  -    CFDictionaryApplyFunction(timers, deleteOneTimer, 0);
  -    CFDictionaryRemoveValue(timerDictionaries, this);
  +    }
  +    NSMutableDictionary *timers = (NSMutableDictionary *)CFDictionaryGetValue(timerDictionaries, this);
  +    NSNumber *timerId = [NSNumber numberWithInt:_timerId];
  +    NSTimer *timer = (NSTimer *)[timers objectForKey:timerId];
  +    // Only try to remove the timer is it hasn't fired (and is therefore valid).  It is NOT
  +    // permissible to reference a timer's userInfo if it is invalid.
  +    if ([timer isValid]){
  +        [deferredTimers removeObject:(KWQObjectTimerTarget *)[timer userInfo]];
  +        [timer invalidate];
  +    }
  +    [timers removeObjectForKey:timerId];
   }
   
  -static void sendDeferredTimerEvent(const void *value, void *context)
  +void QObject::killTimers()
   {
  -    KWQObjectTimer *timer = (KWQObjectTimer *)value;
  -    if (!timer)
  +    if (timerDictionaries == NULL) {
           return;
  -    QTimerEvent event(timer->timerId);
  -    timer->target->timerEvent(&event);
  -}
  -
  -static void sendDeferredTimerEvents(CFRunLoopTimerRef, void *)
  -{
  -    CFRelease(sendDeferredTimerEventsTimer);
  -    sendDeferredTimerEventsTimer = 0;
  -
  -    CFArrayRef timers = deferredTimers;
  -    deferredTimers = 0;
  -
  -    if (timers) {
  -        CFArrayApplyFunction(timers, CFRangeMake(0, CFArrayGetCount(timers)), sendDeferredTimerEvent, 0);
  -        CFRelease(timers);
       }
  +    NSMutableDictionary *timers = (NSMutableDictionary *)CFDictionaryGetValue(timerDictionaries, this);
  +    if (timers == nil) {
  +        return;
  +    }
  +    NSEnumerator *e = [timers keyEnumerator];
  +    NSNumber *timerId;
  +    while ((timerId = [e nextObject]) != nil) {
  +	killTimer([timerId intValue]);
  +    }
  +
  +    CFDictionaryRemoveValue(timerDictionaries, this);
   }
   
   void QObject::setDefersTimers(bool defers)
  @@ -258,24 +299,67 @@
       if (defers) {
           _defersTimers = true;
           deferringTimers = true;
  -        if (sendDeferredTimerEventsTimer) {
  -            CFRunLoopTimerInvalidate(sendDeferredTimerEventsTimer);
  -            CFRelease(sendDeferredTimerEventsTimer);
  -            sendDeferredTimerEventsTimer = 0;
  -        }
  +        [NSObject cancelPreviousPerformRequestsWithTarget:[KWQObjectTimerTarget class]];
           return;
       }
       
       if (_defersTimers) {
           _defersTimers = false;
           if (deferringTimers) {
  -            sendDeferredTimerEventsTimer = CFRunLoopTimerCreate(0, CFAbsoluteTimeGetCurrent(),
  -                0, 0, 0, sendDeferredTimerEvents, 0);
  -            CFRunLoopAddTimer(CFRunLoopGetCurrent(), sendDeferredTimerEventsTimer, kCFRunLoopDefaultMode);
  +            [KWQObjectTimerTarget performSelector:@selector(stopDeferringTimers) withObject:nil afterDelay:0];
  +        }
  +    }
  +}
  +
  + at implementation KWQObjectTimerTarget
  +
  +- initWithQObject:(QObject *)qo timerId:(int)t
  +{
  +    [super init];
  +    target = qo;
  +    timerId = t;
  +    return self;
  +}
  +
  +- (void)sendTimerEvent
  +{
  +    QTimerEvent event(timerId);
  +    target->timerEvent(&event);
  +}
  +
  +- (void)timerFired
  +{
  +    if (deferringTimers) {
  +        if (deferredTimers == nil) {
  +            deferredTimers = [[NSMutableArray alloc] init];
           }
  +	if (![deferredTimers containsObject:self]) {
  +	    [deferredTimers addObject:self];
  +	}
  +    } else {
  +        [self sendTimerEvent];
       }
   }
   
  ++ (void)stopDeferringTimers
  +{
  +    ASSERT(deferringTimers);
  +    while ([deferredTimers count] != 0) {
  +	// remove before sending the timer event, in case the timer
  +	// callback cancels the timer - we don't want to remove too
  +	// much in that case.
  +	KWQObjectTimerTarget *timerTarget = [deferredTimers objectAtIndex:0];
  +	[timerTarget retain];
  +	[deferredTimers removeObjectAtIndex:0];
  +        [timerTarget sendTimerEvent];
  +	[timerTarget release];
  +    }
  +
  +    deferringTimers = false;
  +}
  +
  + at end
  +
   bool QObject::inherits(const char *className) const
   {
       if (strcmp(className, "KHTMLPart") == 0) {
  
  
  
  1.9       +14 -6     WebCore/kwq/KWQPageState.h
  
  Index: KWQPageState.h
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQPageState.h,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- KWQPageState.h	7 Nov 2005 20:52:11 -0000	1.8
  +++ KWQPageState.h	9 Nov 2005 02:46:29 -0000	1.9
  @@ -25,12 +25,19 @@
   
   #import <Foundation/Foundation.h>
   
  -#import "dom_docimpl.h"
  +#include <qmap.h>
  +
  +#include "kjs_window.h"
  +#include "dom_docimpl.h"
  +
  +class KURL;
  +
  +namespace DOM {
  +    class DocumentImpl;
  +}
   
   namespace KJS {
  -    class SavedBuiltins;
       class SavedProperties;
  -    class PausedTimeouts;
   }
   
   @interface KWQPageState : NSObject
  @@ -41,11 +48,11 @@
       KJS::SavedProperties *windowProperties;
       KJS::SavedProperties *locationProperties;
       KJS::SavedBuiltins *interpreterBuiltins;
  -    KJS::PausedTimeouts *pausedTimeouts;
  +    QMap<int, KJS::ScheduledAction*> *pausedActions;
       DOM::DocumentImpl::ParseMode parseMode;
   }
   
  -- initWithDocument:(DOM::DocumentImpl *)doc URL:(const KURL &)u windowProperties:(KJS::SavedProperties *)wp locationProperties:(KJS::SavedProperties *)lp interpreterBuiltins:(KJS::SavedBuiltins *)ib pausedTimeouts:(KJS::PausedTimeouts *)pt;
  +- initWithDocument:(DOM::DocumentImpl *)doc URL:(const KURL &)u windowProperties:(KJS::SavedProperties *)wp locationProperties:(KJS::SavedProperties *)lp interpreterBuiltins:(KJS::SavedBuiltins *)ib;
   
   - (DOM::DocumentImpl *)document;
   - (DOM::DocumentImpl::ParseMode)parseMode;
  @@ -54,7 +61,8 @@
   - (KJS::SavedProperties *)windowProperties;
   - (KJS::SavedProperties *)locationProperties;
   - (KJS::SavedBuiltins *)interpreterBuiltins;
  -- (KJS::PausedTimeouts *)pausedTimeouts;
  +- (void)setPausedActions: (QMap<int, KJS::ScheduledAction*> *)pa;
  +- (QMap<int, KJS::ScheduledAction*> *)pausedActions;
   - (void)invalidate;
   
   @end
  
  
  
  1.23      +44 -31    WebCore/kwq/KWQPageState.mm
  
  Index: KWQPageState.mm
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQPageState.mm,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- KWQPageState.mm	7 Nov 2005 20:52:11 -0000	1.22
  +++ KWQPageState.mm	9 Nov 2005 02:46:29 -0000	1.23
  @@ -23,7 +23,7 @@
    * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
    */
   
  -#import "config.h"
  +#include "config.h"
   #import "KWQPageState.h"
   
   #import <JavaScriptCore/interpreter.h>
  @@ -37,50 +37,65 @@
   #import "KWQFoundationExtras.h"
   #import "KWQKHTMLPart.h"
   
  -using namespace DOM;
  +using DOM::DocumentImpl;
   
  -using namespace khtml;
  +using khtml::RenderObject;
   
  -using namespace KJS;
  +using KJS::Interpreter;
  +using KJS::InterpreterLock;
  +using KJS::SavedProperties;
  +using KJS::SavedBuiltins;
   
   @implementation KWQPageState
   
  -- initWithDocument:(DocumentImpl *)doc URL:(const KURL &)u windowProperties:(SavedProperties *)wp locationProperties:(SavedProperties *)lp interpreterBuiltins:(SavedBuiltins *)ib pausedTimeouts:(PausedTimeouts *)pt
  +- initWithDocument:(DocumentImpl *)doc URL:(const KURL &)u windowProperties:(SavedProperties *)wp locationProperties:(SavedProperties *)lp interpreterBuiltins:(SavedBuiltins *)ib
   {
       [super init];
  -
       doc->ref();
       document = doc;
  -    doc->setInPageCache(YES);
  -    mousePressNode = static_cast<KWQKHTMLPart *>(doc->part())->mousePressNode();
  -    if (mousePressNode)
  +    document->setInPageCache(YES);
  +    parseMode = document->parseMode();
  +    document->view()->ref();
  +    mousePressNode = static_cast<KWQKHTMLPart *>(document->part())->mousePressNode();
  +    if (mousePressNode) {
           mousePressNode->ref();
  +    }
       URL = new KURL(u);
       windowProperties = wp;
       locationProperties = lp;
       interpreterBuiltins = ib;
  -    pausedTimeouts = pt;
  -    parseMode = doc->parseMode();
  +    return self;
  +}
   
  -    doc->view()->ref();
  +- (DOM::DocumentImpl::ParseMode)parseMode { return parseMode; }
   
  -    return self;
  +- (void)setPausedActions: (QMap<int, KJS::ScheduledAction*> *)pa
  +{
  +    pausedActions = pa;
   }
   
  -- (DocumentImpl::ParseMode)parseMode
  +- (QMap<int, KJS::ScheduledAction*> *)pausedActions
   {
  -    return parseMode;
  +    return pausedActions;
   }
   
  -- (PausedTimeouts *)pausedTimeouts
  +- (void)_cleanupPausedActions
   {
  -    return pausedTimeouts;
  +    if (pausedActions){
  +        QMapIterator<int,KJS::ScheduledAction*> it;
  +        for (it = pausedActions->begin(); it != pausedActions->end(); ++it) {
  +            KJS::ScheduledAction *action = *it;
  +            delete action;
  +        }
  +        delete pausedActions;
  +        pausedActions = 0;
  +    }
  +    QObject::clearPausedTimers(self);
   }
   
   - (void)clear
   {
  -    if (mousePressNode)
  -        mousePressNode->deref();        
  +    document = 0;
       mousePressNode = 0;
   
       delete URL;
  @@ -95,8 +110,7 @@
       delete interpreterBuiltins;
       interpreterBuiltins = 0;
   
  -    delete pausedTimeouts;
  -    pausedTimeouts = 0;
  +    [self _cleanupPausedActions];
   }
   
   - (void)invalidate
  @@ -106,22 +120,19 @@
       ASSERT(document->view());
       ASSERT(!document->inPageCache());
   
  -    if (document) {
  -        KHTMLView *view = document->view();
  -        if (view)
  -            view->deref();
  +    if (document && document->view()) {
  +        document->view()->deref();
           document->deref();
  -        document = 0;
       }
  -
  +    
       [self clear];
   }
   
   - (void)dealloc
   {
       if (document) {
  -        ASSERT(document->view());
           ASSERT(document->inPageCache());
  +        ASSERT(document->view());
   
           KHTMLView *view = document->view();
   
  @@ -134,7 +145,10 @@
               document->removeAllEventListenersFromAllNodes();
           }
           document->deref();
  -        document = 0;
  +        
  +        if (mousePressNode) {
  +            mousePressNode->deref();
  +        }
           
           if (view) {
               view->clearPart();
  @@ -167,7 +181,6 @@
               document->removeAllEventListenersFromAllNodes();
           }
           document->deref();
  -        document = 0;
           
           if (view) {
               view->clearPart();
  @@ -185,7 +198,7 @@
       return document;
   }
   
  -- (NodeImpl *)mousePressNode
  +- (DOM::NodeImpl *)mousePressNode
   {
       return mousePressNode;
   }
  
  
  
  1.14      +15 -10    WebCore/kwq/KWQTimer.h
  
  Index: KWQTimer.h
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQTimer.h,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- KWQTimer.h	7 Nov 2005 20:52:11 -0000	1.13
  +++ KWQTimer.h	9 Nov 2005 02:46:29 -0000	1.14
  @@ -1,5 +1,5 @@
   /*
  - * Copyright (C) 2003, 2005 Apple Computer, Inc.  All rights reserved.
  + * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions
  @@ -27,34 +27,39 @@
   #define QTIMER_H_
   
   #include "KWQObject.h"
  +#include "KWQSignal.h"
  +
  +#ifdef __OBJC__
  + at class NSTimer;
  +#else
  +class NSTimer;
  +#endif
   
   class QTimer : public QObject {
   public:
  -    QTimer() : m_runLoopTimer(0), m_monitorFunction(0), m_timeoutSignal(this, SIGNAL(timeout())) { }
  +    QTimer(QObject *parent = 0);
       ~QTimer() { stop(); }
       
  -    bool isActive() const { return m_runLoopTimer; }
  +    bool isActive() const;
       void start(int msec, bool singleShot = false);
       void stop();
       void fire();
       
       static void singleShot(int msec, QObject *receiver, const char *member);
  +    
  +    static void immediateSingleShotOnMainThread(void (*func)());
   
       // This is just a hack used by KWQKHTMLPart. The monitor function
       // gets called when the timer starts and when it is stopped before firing,
       // but not when the timer fires.
       void setMonitor(void (*monitorFunction)(void *context), void *context);
  +    NSTimer *getNSTimer() { return m_timer; }
   
  -    CFAbsoluteTime fireDate() const { return CFRunLoopTimerGetNextFireDate(m_runLoopTimer); }
  -
  -private:
  -    CFRunLoopTimerRef m_runLoopTimer;
  +private:    
  +    NSTimer *m_timer;
       void (*m_monitorFunction)(void *context);
       void *m_monitorFunctionContext;
       KWQSignal m_timeoutSignal;
  -
  -    QTimer(const QTimer&);
  -    QTimer& operator=(const QTimer&);
   };
   
   #endif
  
  
  
  1.21      +125 -30   WebCore/kwq/KWQTimer.mm
  
  Index: KWQTimer.mm
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/KWQTimer.mm,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- KWQTimer.mm	7 Nov 2005 20:52:11 -0000	1.20
  +++ KWQTimer.mm	9 Nov 2005 02:46:29 -0000	1.21
  @@ -1,5 +1,5 @@
   /*
  - * Copyright (C) 2003, 2005 Apple Computer, Inc.  All rights reserved.
  + * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions
  @@ -27,37 +27,111 @@
   #import "KWQTimer.h"
   
   #import <kxmlcore/Assertions.h>
  +#import "KWQLogging.h"
  +#import "KWQFoundationExtras.h"
   
  -static void timerFired(CFRunLoopTimerRef, void *info)
  +// We know the Cocoa calls in this file are safe because they are all
  +// to the simple ObjC class defined here, or simple NSTimer calls that
  +// can't throw.
  +
  + at interface KWQTimerTarget : NSObject
  +{
  +    QTimer *timer;
  +}
  ++ (KWQTimerTarget *)targetWithQTimer:(QTimer *)timer;
  +- (void)timerFired:(id)userInfo;
  + at end
  +
  + at interface KWQSingleShotTimerTarget : NSObject
  +{
  +    KWQSlot *slot;
  +}
  ++ (KWQSingleShotTimerTarget *)targetWithQObject:(QObject *)object member:(const char *)member;
  +- (void)timerFired:(id)userInfo;
  + at end
  +
  + at implementation KWQTimerTarget
  +
  ++ (KWQTimerTarget *)targetWithQTimer:(QTimer *)t
  +{
  +    KWQTimerTarget *target = [[[self alloc] init] autorelease];
  +    target->timer = t;
  +    return target;
  +}
  +
  +- (void)timerFired:(id)userInfo
  +{
  +    timer->fire();
  +}
  +
  + at end
  +
  + at implementation KWQSingleShotTimerTarget
  +
  ++ (KWQSingleShotTimerTarget *)targetWithQObject:(QObject *)object member:(const char *)member
  +{
  +    KWQSingleShotTimerTarget *target = [[[self alloc] init] autorelease];
  +    target->slot = new KWQSlot(object, member);
  +    return target;
  +}
  +
  +- (void)dealloc
  +{
  +    delete slot;
  +    [super dealloc];
  +}
  +
  +- (void)finalize
  +{
  +    delete slot;
  +    [super finalize];
  +}
  +
  +- (void)timerFired:(id)userInfo
   {
  -    ((QTimer *)info)->fire();
  +    slot->call();
  +}
  +
  + at end
  +
  +QTimer::QTimer(QObject *parent)
  +    : m_timer(nil), m_monitorFunction(0), m_timeoutSignal(this, SIGNAL(timeout()))
  +{
  +    if (parent) LOG(NotYetImplemented, "Parent pointer ignored.  QTimer will be leaked and may fire after parent dealloc causing crash.");
  +}
  +
  +bool QTimer::isActive() const
  +{
  +    return m_timer;
   }
   
   void QTimer::start(int msec, bool singleShot)
   {
       stop();
  +    m_timer = KWQRetain([NSTimer scheduledTimerWithTimeInterval:(msec / 1000.0)
  +                                                target:[KWQTimerTarget targetWithQTimer:this]
  +                                              selector:@selector(timerFired:)
  +                                              userInfo:nil
  +                                               repeats:!singleShot]);
   
  -    CFTimeInterval interval = msec * 0.001;
  -    CFRunLoopTimerContext context = { 0, this, 0, 0, 0 };
  -    m_runLoopTimer = CFRunLoopTimerCreate(0, CFAbsoluteTimeGetCurrent() + interval,
  -        singleShot ? 0 : interval, 0, 0, timerFired, &context);
  -    CFRunLoopAddTimer(CFRunLoopGetCurrent(), m_runLoopTimer, kCFRunLoopDefaultMode);
  -
  -    if (m_monitorFunction)
  +    if (m_monitorFunction) {
           m_monitorFunction(m_monitorFunctionContext);
  +    }
   }
   
   void QTimer::stop()
   {
  -    if (!m_runLoopTimer)
  +    if (m_timer == nil) {
           return;
  +    }
       
  -    CFRunLoopTimerInvalidate(m_runLoopTimer);
  -    CFRelease(m_runLoopTimer);
  -    m_runLoopTimer = 0;
  +    [m_timer invalidate];
  +    KWQRelease(m_timer);
  +    m_timer = nil;
   
  -    if (m_monitorFunction)
  +    if (m_monitorFunction) {
           m_monitorFunction(m_monitorFunctionContext);
  +    }
   }
   
   void QTimer::setMonitor(void (*monitorFunction)(void *context), void *context)
  @@ -69,31 +143,52 @@
   
   void QTimer::fire()
   {
  -    if (m_runLoopTimer && !CFRunLoopTimerIsValid(m_runLoopTimer)) {
  -        CFRunLoopTimerInvalidate(m_runLoopTimer);
  -        CFRelease(m_runLoopTimer);
  -        m_runLoopTimer = 0;
  -    }
  +    // Ensure that m_timer is kept around for duration of callback.
  +    // Final reference will eventually be released in stop(), which may be called 
  +    // in this frame, hence the need to ensure the timer is kept around until
  +    // the pool is released. 
  +    [[m_timer retain] autorelease];
   
       // Note: This call may destroy the QTimer, so be sure not to touch any fields afterward.
       m_timeoutSignal.call();
   }
   
  -static void deleteKWQSlot(const void *info)
  +void QTimer::singleShot(int msec, QObject *receiver, const char *member)
   {
  -    delete (KWQSlot *)info;
  +    [NSTimer scheduledTimerWithTimeInterval:(msec / 1000.0)
  +                                     target:[KWQSingleShotTimerTarget targetWithQObject:receiver member:member]
  +                                   selector:@selector(timerFired:)
  +                                   userInfo:nil
  +                                    repeats:NO];
   }
   
  -static void singleShotTimerFired(CFRunLoopTimerRef, void *info)
  + at interface KWQMainThreadPerformTarget : NSObject
   {
  -    ((KWQSlot *)info)->call();
  +    void (*_func)();
   }
   
  -void QTimer::singleShot(int msec, QObject *receiver, const char *member)
  +- (id)initWithFunction:(void (*)())func;
  +- (void)callFunction:(id)ignore;
  + at end
  +
  + at implementation KWQMainThreadPerformTarget
  +- (id)initWithFunction:(void (*)())func
  +{
  +    if ((self = [super init])) {
  +        _func = func;
  +    }
  +    return self;
  +}
  +
  +- (void)callFunction:(id)ignore
  +{
  +    _func();
  +}
  +
  + at end
  +
  +void QTimer::immediateSingleShotOnMainThread(void (*func)())
   {
  -    CFRunLoopTimerContext context = { 0, new KWQSlot(receiver, member), 0, deleteKWQSlot, 0 };
  -    CFRunLoopTimerRef timer = CFRunLoopTimerCreate(0, CFAbsoluteTimeGetCurrent() + msec * 0.001,
  -        0, 0, 0, singleShotTimerFired, &context);
  -    CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopDefaultMode);
  -    CFRelease(timer);
  +    [[[KWQMainThreadPerformTarget alloc] initWithFunction:func] performSelectorOnMainThread:@selector(callFunction) withObject:nil waitUntilDone:NO];
   }
  +
  
  
  
  1.426     +12 -14    WebCore/kwq/WebCoreBridge.mm
  
  Index: WebCoreBridge.mm
  ===================================================================
  RCS file: /cvs/root/WebCore/kwq/WebCoreBridge.mm,v
  retrieving revision 1.425
  retrieving revision 1.426
  diff -u -r1.425 -r1.426
  --- WebCoreBridge.mm	7 Nov 2005 20:52:11 -0000	1.425
  +++ WebCoreBridge.mm	9 Nov 2005 02:46:29 -0000	1.426
  @@ -476,11 +476,13 @@
   - (BOOL)saveDocumentToPageCache
   {
       DocumentImpl *doc = _part->xmlDocImpl();
  -    if (!doc)
  +    if (!doc) {
           return NO;
  -    if (!doc->view())
  +    }
  +    
  +    if (!doc->view()) {
           return NO;
  -
  +    }
       _part->clearTimers();
   
       InterpreterLock lock;
  @@ -494,18 +496,14 @@
       SavedBuiltins *interpreterBuiltins = new SavedBuiltins;
       _part->saveInterpreterBuiltins(*interpreterBuiltins);
   
  -    KWQPageState *pageState = [[KWQPageState alloc] initWithDocument:doc
  -                                                                 URL:_part->m_url
  -                                                    windowProperties:windowProperties
  -                                                  locationProperties:locationProperties
  -                                                 interpreterBuiltins:interpreterBuiltins
  -                                                      pausedTimeouts:_part->pauseTimeouts()];
  -
  -    BOOL result = [self saveDocumentToPageCache:pageState];
  -
  -    [pageState release];
  +    KWQPageState *pageState = [[[KWQPageState alloc] initWithDocument:doc
  +                                                                  URL:_part->m_url
  +                                                     windowProperties:windowProperties
  +                                                   locationProperties:locationProperties
  +				                  interpreterBuiltins:interpreterBuiltins] autorelease];
  +    [pageState setPausedActions: _part->pauseActions((const void *)pageState)];
   
  -    return result;
  +    return [self saveDocumentToPageCache:pageState];
   }
   
   - (BOOL)canCachePage
  
  
  



More information about the webkit-changes mailing list