webengine/osswebengine/WebCore/bindings/js/kjs_window.cpp
branchRCL_3
changeset 48 79859ed3eea9
parent 47 e1bea15f9a39
child 49 919f36ff910f
--- a/webengine/osswebengine/WebCore/bindings/js/kjs_window.cpp	Thu Aug 19 10:58:56 2010 +0300
+++ b/webengine/osswebengine/WebCore/bindings/js/kjs_window.cpp	Tue Aug 31 16:17:46 2010 +0300
@@ -72,12 +72,6 @@
 #include <wtf/MathExtras.h>
 #include "symbian/kjs_console.h"
 
-// for JTimerBase
-#include "SystemTime.h"
-#include <wtf/HashSet.h>
-#include <wtf/Vector.h>
-
-
 #if ENABLE(XSLT)
 #include "JSXSLTProcessor.h"
 #endif
@@ -91,8 +85,7 @@
 
 static int timerNestingLevel = 0;
 const int cMaxTimerNestingLevel = 5;
-const double cMinimumTimerInterval = 0.020; // lower values can block CPU if periodic timers are used
-
+const double cMinimumTimerInterval = 0.010;
 
 struct WindowPrivate {
     WindowPrivate()
@@ -100,7 +93,6 @@
         , m_evt(0)
         , m_dialogArguments(0)
         , m_returnValueSlot(0)
-        , m_paused(false)
     {
     }
 
@@ -114,546 +106,9 @@
     JSValue** m_returnValueSlot;
     typedef HashMap<int, DOMWindowTimer*> TimeoutsMap;
     TimeoutsMap m_timeouts;
-    RArray<int> m_timersToBeCleared;
-    bool m_paused;
-};
-
-// ==========================================================================================
-// Base class for JavaScript timers - start
-// ==========================================================================================
-using namespace std;
-class JTimerBase : Noncopyable {
-public:
-    JTimerBase();
-    virtual ~JTimerBase();
-
-    void start(double nextFireInterval, double repeatInterval);
-    void startRepeating(double repeatInterval) { start(repeatInterval, repeatInterval); }
-    void startOneShot(double interval) { start(interval, 0); }
-    void stop();
-    bool isActive() const;
-    double nextFireInterval() const;
-    double repeatInterval() const { return m_repeatInterval; }
-    void augmentRepeatInterval(double delta) { setNextFireTime(m_nextFireTime + delta); m_repeatInterval += delta; }
-    
-    
-    static void setDeferringTimers(bool);
-    static void shutdownSharedTimer();    
-    double m_nextFireTime; // 0 if inactive
-    double m_repeatInterval; // 0 if not repeating
-    int m_heapIndex; // -1 if not in heap
-private:
-    virtual void fired() = 0; // to be implemented in derived class
-    void checkConsistency() const;
-    void checkHeapIndex() const;
-    void setNextFireTime(double);
-    bool inHeap() const { return m_heapIndex != -1; }
-    void heapDecreaseKey();
-    void heapDelete();
-    void heapDeleteMin();
-    void heapIncreaseKey();
-    void heapInsert();
-    void heapPop();
-    void heapPopMin();
-
-    //static void fireTimersInNestedEventLoop();
-    static void deleteTimerHeap();
-    static void collectFiringTimers(double fireTime, Vector<JTimerBase*>&);
-    static void fireTimers(double fireTime, const Vector<JTimerBase*>&);
-    
-    //shared timer functions
-    static void sharedTimerFired();
-    static TInt TimerFn( TAny* /*aPtr*/ );
-    static void setSharedTimerFireTime(double fireTime);
-    static bool isDeferringTimers();    
-    static void updateSharedTimer();
-    static void stopSharedTimer();
-    static void initSharedTimer();
-    
-    friend class TimerHeapElement;
-    friend bool operator<(const TimerHeapElement&, const TimerHeapElement&);
-};
-
-static bool deferringTimers;
-static Vector<JTimerBase*>* timerHeap;
-static HashSet<const JTimerBase*>* timersReadyToFire;
-
-struct JTimerCleaner {
-    ~JTimerCleaner() {
-        if( timerHeap ) {
-            delete timerHeap;
-            timerHeap = 0;
-            JTimerBase::shutdownSharedTimer();
-        }
-    }
-};
-struct JTimerCleaner jCleanTimer;
-
-// ----------------
-
-// Class to represent elements in the heap when calling the standard library heap algorithms.
-// Maintains the m_heapIndex value in the timers themselves, which allows us to do efficient
-// modification of the heap.
-class TimerHeapElement {
-public:
-    explicit TimerHeapElement(int i) : m_index(i), m_timer((*timerHeap)[m_index]) { checkConsistency(); }
-
-    TimerHeapElement(const TimerHeapElement&);
-    TimerHeapElement& operator=(const TimerHeapElement&);
-
-    JTimerBase* timer() const { return m_timer; }
-
-    void checkConsistency() const {
-        ASSERT(m_index >= 0);
-        ASSERT(m_index < (timerHeap ? static_cast<int>(timerHeap->size()) : 0));
-    }
-
-private:
-    TimerHeapElement();
-
-    int m_index;
-    JTimerBase* m_timer;
-};
-
-inline TimerHeapElement::TimerHeapElement(const TimerHeapElement& o)
-    : m_index(-1), m_timer(o.timer())
-{
-}
-
-inline TimerHeapElement& TimerHeapElement::operator=(const TimerHeapElement& o)
-{
-    JTimerBase* t = o.timer();
-    m_timer = t;
-    if (m_index != -1) {
-        checkConsistency();
-        (*timerHeap)[m_index] = t;
-        t->m_heapIndex = m_index;
-    }
-    return *this;
-}
-
-inline bool operator<(const TimerHeapElement& a, const TimerHeapElement& b)
-{
-    // Note, this is "backwards" because the heap puts the largest element first
-    // and we want the lowest time to be the first one in the heap.
-    return b.timer()->m_nextFireTime < a.timer()->m_nextFireTime;
-}
-
-// ----------------
-
-// Class to represent iterators in the heap when calling the standard library heap algorithms.
-// Returns TimerHeapElement for elements in the heap rather than the JTimerBase pointers themselves.
-class TimerHeapIterator : public iterator<random_access_iterator_tag, TimerHeapElement, int> {
-public:
-    TimerHeapIterator() : m_index(-1) { }
-    TimerHeapIterator(int i) : m_index(i) { checkConsistency(); }
-
-    TimerHeapIterator& operator++() { checkConsistency(); ++m_index; checkConsistency(); return *this; }
-    TimerHeapIterator operator++(int) { checkConsistency(); checkConsistency(1); return m_index++; }
-
-    TimerHeapIterator& operator--() { checkConsistency(); --m_index; checkConsistency(); return *this; }
-    TimerHeapIterator operator--(int) { checkConsistency(); checkConsistency(-1); return m_index--; }
-
-    TimerHeapIterator& operator+=(int i) { checkConsistency(); m_index += i; checkConsistency(); return *this; }
-    TimerHeapIterator& operator-=(int i) { checkConsistency(); m_index -= i; checkConsistency(); return *this; }
-
-    TimerHeapElement operator*() const { return TimerHeapElement(m_index); }
-    TimerHeapElement operator[](int i) const { return TimerHeapElement(m_index + i); }
-
-    int index() const { return m_index; }
-
-    void checkConsistency(int offset = 0) const {
-        ASSERT(m_index + offset >= 0);
-        ASSERT(m_index + offset <= (timerHeap ? static_cast<int>(timerHeap->size()) : 0));
-    }
-
-private:
-    int m_index;
 };
 
-inline bool operator==(TimerHeapIterator a, TimerHeapIterator b) { return a.index() == b.index(); }
-inline bool operator!=(TimerHeapIterator a, TimerHeapIterator b) { return a.index() != b.index(); }
-inline bool operator<(TimerHeapIterator a, TimerHeapIterator b) { return a.index() < b.index(); }
-
-inline TimerHeapIterator operator+(TimerHeapIterator a, int b) { return a.index() + b; }
-inline TimerHeapIterator operator+(int a, TimerHeapIterator b) { return a + b.index(); }
-
-inline TimerHeapIterator operator-(TimerHeapIterator a, int b) { return a.index() - b; }
-inline int operator-(TimerHeapIterator a, TimerHeapIterator b) { return a.index() - b.index(); }
-
-// ----------------
-
-static TInt64 remainingMicro = 0;
-static bool shutdownInProgress = false;
-static CPeriodic* sharedTimer;
-
-void shutdownJSTimer()
-    {
-    JTimerBase::shutdownSharedTimer();
-    }
-
-void setDeferringJSTimers(bool defer)
-    {
-    JTimerBase::setDeferringTimers(defer);
-    }
-
-void JTimerBase::shutdownSharedTimer()
-    {
-    shutdownInProgress = true;
-    stopSharedTimer();
-    JTimerBase::deleteTimerHeap();
-    }
-
-void JTimerBase::initSharedTimer()
-    {
-    shutdownInProgress = false;
-    }
-
-
-TInt JTimerBase::TimerFn( TAny* /*aPtr*/ )
-    {
-    if (shutdownInProgress)
-        {
-        return KErrNone;
-        }
-    if( remainingMicro == 0 )
-        {
-            sharedTimerFired();
-        }
-    else
-        {
-        setSharedTimerFireTime( -1 );
-        }
-    return KErrNone;
-    }
-
-
-void JTimerBase::setSharedTimerFireTime(double fireTime)
-    {
-    if (shutdownInProgress)
-        {
-        return;
-        }
-
-    if (sharedTimer)
-        {
-        sharedTimer->Cancel();
-        delete sharedTimer;
-        sharedTimer = NULL;
-        }
-    if (fireTime != -1)
-        remainingMicro = 0;
-
-    sharedTimer = CPeriodic::New( CActive::EPriorityIdle );
-    if( sharedTimer )
-        {
-        TInt64 interval( remainingMicro );
-        if( remainingMicro == 0 )
-            {
-            // fireTime comes in second resolution
-            TTime fireDate( TTime(fireTime * 1000000 ).Int64() );
-
-            TTime time;
-            time.HomeTime();
-            interval = fireDate.Int64() - time.Int64();
-            }
-        interval = interval < 0 ? 0 : interval;
-        //
-        TInt t;
-        if (interval<(TInt)(KMaxTInt32))
-            {
-            t = interval;
-            remainingMicro = 0;
-            }
-        else
-            {
-            t = KMaxTInt32;
-            remainingMicro = interval - KMaxTInt32;
-            }
-        sharedTimer->Start( t, 0, JTimerBase::TimerFn);
-        }
-    }
-
-
-void JTimerBase::stopSharedTimer()
-    {
-    if (sharedTimer)
-        {
-        sharedTimer->Cancel();
-        delete sharedTimer;
-        sharedTimer = NULL;
-        }
-    remainingMicro = 0;
-    /*
-     * The static boolean variable shutdownInProgress, must be reset in scenario's where a browser control instance is deleted and a new
-     * instance is created without actually closing the application.
-     */
-    shutdownInProgress = false ;
-    }
-
-void JTimerBase::updateSharedTimer()
-{
-    if (timersReadyToFire || deferringTimers || !timerHeap || timerHeap->isEmpty())
-        stopSharedTimer();
-    else
-        setSharedTimerFireTime(timerHeap->first()->m_nextFireTime);
-}
-
-bool JTimerBase::isDeferringTimers()
-{
-    return deferringTimers;
-}
-
-void JTimerBase::setDeferringTimers(bool shouldDefer)
-{
-    if (shouldDefer == deferringTimers)
-        return;
-    deferringTimers = shouldDefer;
-    updateSharedTimer();
-}
-
-// ----------------
-
-JTimerBase::JTimerBase() : m_nextFireTime(0), m_repeatInterval(0), m_heapIndex(-1)
-{
-}
-
-JTimerBase::~JTimerBase()
-{
-    stop();
-
-    ASSERT(!inHeap());
-}
-
-void JTimerBase::start(double nextFireInterval, double repeatInterval)
-{
-    m_repeatInterval = repeatInterval;
-    setNextFireTime(currentTime() + nextFireInterval);
-}
-
-void JTimerBase::stop()
-{
-    m_repeatInterval = 0;
-    setNextFireTime(0);
-
-    ASSERT(m_nextFireTime == 0);
-    ASSERT(m_repeatInterval == 0);
-    ASSERT(!inHeap());
-}
-
-bool JTimerBase::isActive() const
-{
-    return m_nextFireTime || (timersReadyToFire && timersReadyToFire->contains(this));
-}
-
-double JTimerBase::nextFireInterval() const
-{
-    ASSERT(isActive());
-    double current = currentTime();
-    if (m_nextFireTime < current)
-        return 0;
-    return m_nextFireTime - current;
-}
-
-inline void JTimerBase::checkHeapIndex() const
-{
-    ASSERT(timerHeap);
-    ASSERT(!timerHeap->isEmpty());
-    ASSERT(m_heapIndex >= 0);
-    ASSERT(m_heapIndex < static_cast<int>(timerHeap->size()));
-    ASSERT((*timerHeap)[m_heapIndex] == this);
-}
-
-inline void JTimerBase::checkConsistency() const
-{
-    // Timers should be in the heap if and only if they have a non-zero next fire time.
-    ASSERT(inHeap() == (m_nextFireTime != 0));
-    if (inHeap())
-        checkHeapIndex();
-}
-
-void JTimerBase::heapDecreaseKey()
-{
-    ASSERT(m_nextFireTime != 0);
-    checkHeapIndex();
-    #if PLATFORM(SYMBIAN)
-    // check for valid heap index
-    if(m_heapIndex < static_cast<int>(timerHeap->size()))
-    #endif
-        {
-        push_heap(TimerHeapIterator(0), TimerHeapIterator(m_heapIndex + 1));
-        }
-    checkHeapIndex();
-}
-
-inline void JTimerBase::heapDelete()
-{
-    ASSERT(m_nextFireTime == 0);
-    heapPop();
-    timerHeap->removeLast();
-    m_heapIndex = -1;
-}
-
-inline void JTimerBase::heapDeleteMin()
-{
-    ASSERT(m_nextFireTime == 0);
-    heapPopMin();
-    timerHeap->removeLast();
-    m_heapIndex = -1;
-}
-
-inline void JTimerBase::heapIncreaseKey()
-{
-    ASSERT(m_nextFireTime != 0);
-    heapPop();
-    heapDecreaseKey();
-}
-
-inline void JTimerBase::heapInsert()
-{
-    ASSERT(!inHeap());
-    if (!timerHeap)
-        timerHeap = new Vector<JTimerBase*>;
-    timerHeap->append(this);
-    m_heapIndex = timerHeap->size() - 1;
-    heapDecreaseKey();
-}
-
-inline void JTimerBase::heapPop()
-{
-    // Temporarily force this timer to have the minimum key so we can pop it.
-    double fireTime = m_nextFireTime;
-    m_nextFireTime = -numeric_limits<double>::infinity();
-    heapDecreaseKey();
-    heapPopMin();
-    m_nextFireTime = fireTime;
-}
-
-void JTimerBase::heapPopMin()
-{
-    ASSERT(this == timerHeap->first());
-    checkHeapIndex();
-    pop_heap(TimerHeapIterator(0), TimerHeapIterator(timerHeap->size()));
-    checkHeapIndex();
-    ASSERT(this == timerHeap->last());
-}
-
-void JTimerBase::setNextFireTime(double newTime)
-{
-    // Keep heap valid while changing the next-fire time.
-
-    if (timersReadyToFire)
-        timersReadyToFire->remove(this);
-
-    double oldTime = m_nextFireTime;
-    if (oldTime != newTime) {
-        m_nextFireTime = newTime;
-
-        bool wasFirstTimerInHeap = m_heapIndex == 0;
-
-        if (oldTime == 0)
-            heapInsert();
-        else if (newTime == 0)
-            heapDelete();
-        else if (newTime < oldTime)
-            heapDecreaseKey();
-        else
-            heapIncreaseKey();
-
-        bool isFirstTimerInHeap = m_heapIndex == 0;
-
-        if (wasFirstTimerInHeap || isFirstTimerInHeap)
-            updateSharedTimer();
-    }
-
-    checkConsistency();
-}
-
-void JTimerBase::collectFiringTimers(double fireTime, Vector<JTimerBase*>& firingTimers)
-{
-    while (!timerHeap->isEmpty() && timerHeap->first()->m_nextFireTime <= fireTime) {
-        JTimerBase* timer = timerHeap->first();
-        firingTimers.append(timer);
-        timersReadyToFire->add(timer);
-        timer->m_nextFireTime = 0;
-        timer->heapDeleteMin();
-    }
-}
-
-void JTimerBase::fireTimers(double fireTime, const Vector<JTimerBase*>& firingTimers)
-{
-    int size = firingTimers.size();
-    for (int i = 0; i != size; ++i) {
-        JTimerBase* timer = firingTimers[i];
-
-        // If not in the set, this timer has been deleted or re-scheduled in another timer's fired function.
-        // So either we don't want to fire it at all or we will fire it next time the shared timer goes off.
-        // It might even have been deleted; that's OK because we won't do anything else with the pointer.
-        if (!timersReadyToFire->contains(timer))
-            continue;
-
-        // Setting the next fire time has a side effect of removing the timer from the firing timers set.
-        double interval = timer->repeatInterval();
-        timer->setNextFireTime(interval ? fireTime + interval : 0);
-
-        // Once the timer has been fired, it may be deleted, so do nothing else with it after this point.
-        timer->fired();
-
-        // Catch the case where the timer asked timers to fire in a nested event loop.
-        if (!timersReadyToFire)
-            break;
-    }
-}
-
-void JTimerBase::sharedTimerFired()
-{
-    // Do a re-entrancy check.
-    if (timersReadyToFire)
-        return;
-
-    double fireTime = currentTime();
-    Vector<JTimerBase*> firingTimers;
-    HashSet<const JTimerBase*> firingTimersSet;
-
-    timersReadyToFire = &firingTimersSet;
-
-    collectFiringTimers(fireTime, firingTimers);
-    fireTimers(fireTime, firingTimers);
-
-    timersReadyToFire = 0;
-
-    updateSharedTimer();
-}
-/*
-void JTimerBase::fireTimersInNestedEventLoop()
-{
-    timersReadyToFire = 0;
-    updateSharedTimer();
-}
-*/
-
-void JTimerBase::deleteTimerHeap()
-{
-    if (timerHeap)
-    {
-        while (!timerHeap->isEmpty())
-        {
-            JTimerBase* timer = timerHeap->first();
-            timer->m_nextFireTime = 0;
-            timer->heapDeleteMin();        
-        }
-        delete timerHeap ;
-        timerHeap = NULL ;
-    }
-}
-
-
-// ==========================================================================================
-// Base class for JavaScript timers - end
-// ==========================================================================================
-
-
-class DOMWindowTimer : public JTimerBase {
+class DOMWindowTimer : public TimerBase {
 public:
     DOMWindowTimer(int timeoutId, int nestingLevel, Window* o, ScheduledAction* a)
         : m_timeoutId(timeoutId), m_nestingLevel(nestingLevel), m_object(o), m_action(a) { }
@@ -775,8 +230,7 @@
 Window::~Window()
 {
     clearAllTimeouts();
-    d->m_timersToBeCleared.Close();
-    
+
     // Clear any backpointers to the window
 
     ListenersMap::iterator i2 = d->jsEventListeners.begin();
@@ -2089,17 +1543,7 @@
     
 #if PLATFORM(SYMBIAN)
     if (d->m_evt && d->m_evt->type() == "mouseover")  {
-        if (singleShot) {
-            double interval = max(0.010, t * 0.001);
-            if (interval < cMinimumTimerInterval && (timerNestingLevel + 1) >= cMaxTimerNestingLevel) {
-                interval = cMinimumTimerInterval;
-            }
-            impl()->frame()->page()->chrome()->wait(interval);
-            a->execute(this);
-            // clear the event after it is handled. 
-            d->m_evt = 0; 
-            return lastUsedTimeoutId;
-        }
+        impl()->frame()->page()->chrome()->setElementVisibilityChanged(true);
     }
 #endif        
 
@@ -2111,15 +1555,13 @@
     // Use a minimum interval of 10 ms to match other browsers, but only once we've
     // nested enough to notice that we're repeating.
     // Faster timers might be "better", but they're incompatible.
-    double interval = max(0.010, t * 0.001); // min interval for mobile device
+    double interval = max(0.001, t * 0.001);
     if (interval < cMinimumTimerInterval && nestLevel >= cMaxTimerNestingLevel)
         interval = cMinimumTimerInterval;
     if (singleShot)
         timer->startOneShot(interval);
-    else {
-        interval = max(0.030, t * 0.001); // keep periodic timers less frequent
+    else
         timer->startRepeating(interval);
-	}
     return timeoutId;
 }
 
@@ -2139,7 +1581,6 @@
     if (count == 0)
         return 0;
 
-    d->m_paused = true;
     PausedTimeout* t = new PausedTimeout [count];
     PausedTimeouts* result = new PausedTimeouts(t, count);
 
@@ -2169,21 +1610,15 @@
     PausedTimeout* array = timeouts->takeTimeouts();
     for (size_t i = 0; i != count; ++i) {
         int timeoutId = array[i].timeoutId;
-        if (KErrNotFound == d->m_timersToBeCleared.Find(timeoutId)) {
-            DOMWindowTimer* timer = new DOMWindowTimer(timeoutId, array[i].nestingLevel, this, array[i].action);
-            d->m_timeouts.set(timeoutId, timer);
-            timer->start(array[i].nextFireInterval, array[i].repeatInterval);
-        }
+        DOMWindowTimer* timer = new DOMWindowTimer(timeoutId, array[i].nestingLevel, this, array[i].action);
+        d->m_timeouts.set(timeoutId, timer);
+        timer->start(array[i].nextFireInterval, array[i].repeatInterval);
     }
     delete [] array;
-    d->m_timersToBeCleared.Reset();
-    d->m_paused = false;
 }
 
 void Window::clearTimeout(int timeoutId, bool delAction)
 {
-    if(d->m_paused)
-        d->m_timersToBeCleared.Append(timeoutId);
     WindowPrivate::TimeoutsMap::iterator it = d->m_timeouts.find(timeoutId);
     if (it == d->m_timeouts.end())
         return;
@@ -2199,14 +1634,7 @@
         int timeoutId = timer->timeoutId();
 
         timer->action()->execute(this);
-	
-    	// The DOMWindowTimer object may have been deleted or replaced during execution, 
-    	// so we re-fetch it. 
-    	timer = d->m_timeouts.get(timeoutId); 
-    	if (!timer) 
-    	   	return; 
-	 
-        if (timer->repeatInterval() && timer->repeatInterval() < cMinimumTimerInterval) {        
+        if (d->m_timeouts.contains(timeoutId) && timer->repeatInterval() && timer->repeatInterval() < cMinimumTimerInterval) {
             timer->setNestingLevel(timer->nestingLevel() + 1);
             if (timer->nestingLevel() >= cMaxTimerNestingLevel)
                 timer->augmentRepeatInterval(cMinimumTimerInterval - timer->repeatInterval());