Skip to content
Permalink
Browse files
3 of the new HTML5 loading events need to be asynchronous.
Reviewed by Darin Adler.

Laying the groundwork for:
https://bugs.webkit.org/show_bug.cgi?id=36201
https://bugs.webkit.org/show_bug.cgi?id=36202
https://bugs.webkit.org/show_bug.cgi?id=36334
https://bugs.webkit.org/show_bug.cgi?id=36335

Document already had an asynchronous event delivery mechanism for storage events, so
we can repurpose that for all async events.

No new tests. (No change in behavior)

* dom/Document.cpp:
(WebCore::Document::Document):
(WebCore::Document::implicitClose): Use Document::schedule* for the related events.
(WebCore::Document::enqueueEvent): Renamed from enqueueStorageEvent
(WebCore::Document::pendingEventTimerFired): Renamed from "storageEventTimerFired"
(WebCore::Document::statePopped): Use Document::schedulePopstateEvent
(WebCore::Document::enqueuePageshowEvent): All Pageshow events are piped through here.
  This will be made asynchronous in a separate patch.
(WebCore::Document::enqueueHashchangeEvent): All Hashchange events are piped through here.
  This will be made asynchronous in a separate patch.
(WebCore::Document::enqueuePopstateEvent): All Popstate events are piped through here.
  This will be made asynchronous in a separate patch.
* dom/Document.h:
(WebCore::):

* history/CachedFrame.cpp:
(WebCore::CachedFrameBase::restore): Use Document::enqueuePageshowEvent

* loader/FrameLoader.cpp:
(WebCore::FrameLoader::loadInSameDocument): Use Document::enqueueHashchangeEvent

* storage/StorageEventDispatcher.cpp:
(WebCore::StorageEventDispatcher::dispatch): Use Document::enqueueEvent



Canonical link: https://commits.webkit.org/47543@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@56249 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
beidson committed Mar 19, 2010
1 parent 10f33fc commit 99b0b503b149170ec56eb066d33d2398a5a92a65
Showing 6 changed files with 96 additions and 23 deletions.
@@ -1,3 +1,44 @@
2010-03-19 Brady Eidson <beidson@apple.com>

Reviewed by Darin Adler.

3 of the new HTML5 loading events need to be asynchronous.

Laying the groundwork for:
https://bugs.webkit.org/show_bug.cgi?id=36201
https://bugs.webkit.org/show_bug.cgi?id=36202
https://bugs.webkit.org/show_bug.cgi?id=36334
https://bugs.webkit.org/show_bug.cgi?id=36335

Document already had an asynchronous event delivery mechanism for storage events, so
we can repurpose that for all async events.

No new tests. (No change in behavior)

* dom/Document.cpp:
(WebCore::Document::Document):
(WebCore::Document::implicitClose): Use Document::schedule* for the related events.
(WebCore::Document::enqueueEvent): Renamed from enqueueStorageEvent
(WebCore::Document::pendingEventTimerFired): Renamed from "storageEventTimerFired"
(WebCore::Document::statePopped): Use Document::schedulePopstateEvent
(WebCore::Document::enqueuePageshowEvent): All Pageshow events are piped through here.
This will be made asynchronous in a separate patch.
(WebCore::Document::enqueueHashchangeEvent): All Hashchange events are piped through here.
This will be made asynchronous in a separate patch.
(WebCore::Document::enqueuePopstateEvent): All Popstate events are piped through here.
This will be made asynchronous in a separate patch.
* dom/Document.h:
(WebCore::):

* history/CachedFrame.cpp:
(WebCore::CachedFrameBase::restore): Use Document::enqueuePageshowEvent

* loader/FrameLoader.cpp:
(WebCore::FrameLoader::loadInSameDocument): Use Document::enqueueHashchangeEvent

* storage/StorageEventDispatcher.cpp:
(WebCore::StorageEventDispatcher::dispatch): Use Document::enqueueEvent

2010-03-19 Kevin Decker <kdecker@apple.com>

Reviewed by Darin Adler and Brady Eidson.
@@ -390,7 +390,7 @@ Document::Document(Frame* frame, bool isXHTML, bool isHTML)
, m_normalWorldWrapperCache(0)
#endif
, m_usingGeolocation(false)
, m_storageEventTimer(this, &Document::storageEventTimerFired)
, m_pendingEventTimer(this, &Document::pendingEventTimerFired)
#if ENABLE(WML)
, m_containsWMLContent(false)
#endif
@@ -1820,9 +1820,9 @@ void Document::implicitClose()
ImageLoader::dispatchPendingBeforeLoadEvents();
ImageLoader::dispatchPendingLoadEvents();
dispatchWindowLoadEvent();
dispatchWindowEvent(PageTransitionEvent::create(eventNames().pageshowEvent, false), this);
enqueuePageshowEvent(PageshowEventNotPersisted);
if (m_pendingStateObject)
dispatchWindowEvent(PopStateEvent::create(m_pendingStateObject.release()));
enqueuePopstateEvent(m_pendingStateObject.release());

if (f)
f->loader()->handledOnloadEvents();
@@ -2993,22 +2993,22 @@ void Document::dispatchWindowLoadEvent()
domWindow->dispatchLoadEvent();
}

void Document::enqueueStorageEvent(PassRefPtr<Event> storageEvent)
void Document::enqueueEvent(PassRefPtr<Event> event)
{
m_storageEventQueue.append(storageEvent);
if (!m_storageEventTimer.isActive())
m_storageEventTimer.startOneShot(0);
m_pendingEventQueue.append(event);
if (!m_pendingEventTimer.isActive())
m_pendingEventTimer.startOneShot(0);
}

void Document::storageEventTimerFired(Timer<Document>*)
void Document::pendingEventTimerFired(Timer<Document>*)
{
ASSERT(!m_storageEventTimer.isActive());
Vector<RefPtr<Event> > storageEventQueue;
storageEventQueue.swap(m_storageEventQueue);
ASSERT(!m_pendingEventTimer.isActive());
Vector<RefPtr<Event> > eventQueue;
eventQueue.swap(m_pendingEventQueue);

typedef Vector<RefPtr<Event> >::const_iterator Iterator;
Iterator end = storageEventQueue.end();
for (Iterator it = storageEventQueue.begin(); it != end; ++it)
Iterator end = eventQueue.end();
for (Iterator it = eventQueue.begin(); it != end; ++it)
dispatchWindowEvent(*it);
}

@@ -4501,7 +4501,7 @@ void Document::statePopped(SerializedScriptValue* stateObject)
return;

if (f->loader()->isComplete())
dispatchWindowEvent(PopStateEvent::create(stateObject));
enqueuePopstateEvent(stateObject);
else
m_pendingStateObject = stateObject;
}
@@ -4757,6 +4757,26 @@ void Document::displayBufferModifiedByEncoding(UChar* buffer, unsigned len) cons
m_decoder->encoding().displayBuffer(buffer, len);
}

void Document::enqueuePageshowEvent(PageshowEventPersistence persisted)
{
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=36334 Pageshow event needs to fire asynchronously.
dispatchWindowEvent(PageTransitionEvent::create(eventNames().pageshowEvent, persisted), this);
}

void Document::enqueueHashchangeEvent(const String& /*oldURL*/, const String& /*newURL*/)
{
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=36201 Hashchange event needs to fire asynchronously.
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=36335 Hashchange event is now its own interface and takes two
// URL arguments which we need to pass in here.
dispatchWindowEvent(Event::create(eventNames().hashchangeEvent, false, false));
}

void Document::enqueuePopstateEvent(PassRefPtr<SerializedScriptValue> stateObject)
{
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=36202 Popstate event needs to fire asynchronously
dispatchWindowEvent(PopStateEvent::create(stateObject));
}

#if ENABLE(XHTMLMP)
bool Document::isXHTMLMPDocument() const
{
@@ -175,6 +175,11 @@ struct FormElementKeyHashTraits : WTF::GenericHashTraits<FormElementKey> {
static bool isDeletedValue(const FormElementKey& value) { return value.isHashTableDeletedValue(); }
};

enum PageshowEventPersistence {
PageshowEventNotPersisted = 0,
PageshowEventPersisted = 1
};

class Document : public ContainerNode, public ScriptExecutionContext {
public:
static PassRefPtr<Document> create(Frame* frame)
@@ -627,9 +632,6 @@ class Document : public ContainerNode, public ScriptExecutionContext {
void dispatchWindowEvent(PassRefPtr<Event>, PassRefPtr<EventTarget> = 0);
void dispatchWindowLoadEvent();

void enqueueStorageEvent(PassRefPtr<Event>);
void storageEventTimerFired(Timer<Document>*);

PassRefPtr<Event> createEvent(const String& eventType, ExceptionCode&);

// keep track of what types of event listeners are registered, so we don't
@@ -960,6 +962,10 @@ class Document : public ContainerNode, public ScriptExecutionContext {
bool containsValidityStyleRules() const { return m_containsValidityStyleRules; }
void setContainsValidityStyleRules() { m_containsValidityStyleRules = true; }

void enqueueEvent(PassRefPtr<Event>);
void enqueuePageshowEvent(PageshowEventPersistence);
void enqueueHashchangeEvent(const String& oldURL, const String& newURL);

protected:
Document(Frame*, bool isXHTML, bool isHTML);

@@ -998,6 +1004,9 @@ class Document : public ContainerNode, public ScriptExecutionContext {

void createStyleSelector();

void enqueuePopstateEvent(PassRefPtr<SerializedScriptValue> stateObject);
void pendingEventTimerFired(Timer<Document>*);

OwnPtr<CSSStyleSelector> m_styleSelector;
bool m_didCalculateStyleSelector;

@@ -1215,8 +1224,8 @@ class Document : public ContainerNode, public ScriptExecutionContext {

bool m_usingGeolocation;

Timer<Document> m_storageEventTimer;
Vector<RefPtr<Event> > m_storageEventQueue;
Timer<Document> m_pendingEventTimer;
Vector<RefPtr<Event> > m_pendingEventQueue;

#if ENABLE(WML)
bool m_containsWMLContent;
@@ -105,7 +105,7 @@ void CachedFrameBase::restore()
for (unsigned i = 0; i < m_childFrames.size(); ++i)
m_childFrames[i]->open();

m_document->dispatchWindowEvent(PageTransitionEvent::create(eventNames().pageshowEvent, true), m_document);
m_document->enqueuePageshowEvent(PageshowEventPersisted);
#if ENABLE(TOUCH_EVENTS)
if (m_document->hasListenerType(Document::TOUCH_LISTENER))
m_document->page()->chrome()->client()->needTouchEvents(true);
@@ -1743,7 +1743,10 @@ void FrameLoader::loadInSameDocument(const KURL& url, SerializedScriptValue* sta
history()->updateBackForwardListForFragmentScroll();
}

String oldURL;
bool hashChange = equalIgnoringFragmentIdentifier(url, m_URL) && url.fragmentIdentifier() != m_URL.fragmentIdentifier();
oldURL = m_URL;

m_URL = url;
history()->updateForSameDocumentNavigation();

@@ -1778,7 +1781,7 @@ void FrameLoader::loadInSameDocument(const KURL& url, SerializedScriptValue* sta
}

if (hashChange) {
m_frame->document()->dispatchWindowEvent(Event::create(eventNames().hashchangeEvent, false, false));
m_frame->document()->enqueueHashchangeEvent(oldURL, m_URL);
m_client->dispatchDidChangeLocationWithinPage();
}

@@ -55,7 +55,7 @@ void StorageEventDispatcher::dispatch(const String& key, const String& oldValue,
}

for (unsigned i = 0; i < frames.size(); ++i)
frames[i]->document()->enqueueStorageEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), frames[i]->domWindow()->sessionStorage()));
frames[i]->document()->enqueueEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), frames[i]->domWindow()->sessionStorage()));
} else {
// Send events to every page.
const HashSet<Page*>& pages = page->group().pages();
@@ -71,7 +71,7 @@ void StorageEventDispatcher::dispatch(const String& key, const String& oldValue,
ExceptionCode ec = 0;
Storage* storage = frames[i]->domWindow()->localStorage(ec);
if (!ec)
frames[i]->document()->enqueueStorageEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), storage));
frames[i]->document()->enqueueEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), storage));
}
}
}

0 comments on commit 99b0b50

Please sign in to comment.