| Index: trunk/Source/core/dom/Document.cpp
|
| ===================================================================
|
| --- trunk/Source/core/dom/Document.cpp (revision 177995)
|
| +++ trunk/Source/core/dom/Document.cpp (working copy)
|
| @@ -2201,6 +2201,9 @@
|
|
|
| m_styleEngine->didDetach();
|
|
|
| + if (Document* parentDoc = parentDocument())
|
| + parentDoc->didClearTouchEventHandlers(this);
|
| +
|
| // This is required, as our LocalFrame might delete itself as soon as it detaches
|
| // us. However, this violates Node::detach() semantics, as it's never
|
| // possible to re-attach. Eventually Document::detach() should be renamed,
|
| @@ -2214,6 +2217,12 @@
|
| lifecycleNotifier().notifyDocumentWasDetached();
|
| m_lifecycle.advanceTo(DocumentLifecycle::Stopped);
|
| #if ENABLE(OILPAN)
|
| + // This mirrors the clearing of the document object's touch
|
| + // handlers that happens when the LocalDOMWindow is destructed in a
|
| + // non-Oilpan setting (LocalDOMWindow::removeAllEventListeners()),
|
| + // except that it is now done during detach instead.
|
| + didClearTouchEventHandlers(this);
|
| +
|
| // Done with the window, explicitly clear to hasten its
|
| // destruction.
|
| clearDOMWindow();
|
| @@ -5254,6 +5263,80 @@
|
| return TouchList::create(touches);
|
| }
|
|
|
| +void Document::didAddTouchEventHandler(Node* handler)
|
| +{
|
| + // The node should either be in this document, or be the Document node of a child
|
| + // of this document.
|
| + ASSERT(&handler->document() == this
|
| + || (handler->isDocumentNode() && toDocument(handler)->parentDocument() == this));
|
| + if (!m_touchEventTargets.get())
|
| + m_touchEventTargets = adoptPtr(new TouchEventTargetSet);
|
| + bool isFirstHandler = m_touchEventTargets->isEmpty();
|
| +
|
| + if (!m_touchEventTargets->add(handler).isNewEntry) {
|
| + // Just incremented refcount, no real change.
|
| + // If this is a child document node, then the count should never go above 1.
|
| + ASSERT(!handler->isDocumentNode() || &handler->document() == this);
|
| + return;
|
| + }
|
| +
|
| + if (isFirstHandler) {
|
| + if (Document* parent = parentDocument()) {
|
| + parent->didAddTouchEventHandler(this);
|
| + } else {
|
| + // This is the first touch handler on the whole page.
|
| + if (FrameHost* frameHost = this->frameHost())
|
| + frameHost->chrome().client().needTouchEvents(true);
|
| + }
|
| + }
|
| +
|
| + // When we're all done with all frames, ensure touch hit rects are marked as dirty.
|
| + if (!handler->isDocumentNode() || handler == this) {
|
| + if (Page* page = this->page()) {
|
| + if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
|
| + scrollingCoordinator->touchEventTargetRectsDidChange();
|
| + }
|
| + }
|
| +}
|
| +
|
| +void Document::didRemoveTouchEventHandler(Node* handler, bool clearAll)
|
| +{
|
| + // Note that we can't assert that |handler| is in this document because it might be in
|
| + // the process of moving out of it.
|
| + ASSERT(clearAll || m_touchEventTargets->contains(handler));
|
| + if (!m_touchEventTargets.get())
|
| + return;
|
| +
|
| + if (clearAll) {
|
| + if (!m_touchEventTargets->contains(handler))
|
| + return;
|
| + m_touchEventTargets->removeAll(handler);
|
| + } else {
|
| + if (!m_touchEventTargets->remove(handler))
|
| + // Just decremented refcount, no real update.
|
| + return;
|
| + }
|
| +
|
| + if (m_touchEventTargets->isEmpty()) {
|
| + if (Document* parent = parentDocument()) {
|
| + // This was the last handler in this document, update the parent document too.
|
| + parent->didRemoveTouchEventHandler(this, clearAll);
|
| + } else {
|
| + // We just removed the last touch handler on the whole page.
|
| + if (FrameHost* frameHost = this->frameHost())
|
| + frameHost->chrome().client().needTouchEvents(false);
|
| + }
|
| + }
|
| +
|
| + // When we're all done with all frames, ensure touch hit rects are marked as dirty.
|
| + if (!handler->isDocumentNode() || handler == this) {
|
| + if (Page* page = this->page()) {
|
| + if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
|
| + scrollingCoordinator->touchEventTargetRectsDidChange();
|
| + }
|
| + }
|
| +}
|
| +
|
| DocumentLoader* Document::loader() const
|
| {
|
| if (!m_frame)
|
| @@ -5693,6 +5776,17 @@
|
| {
|
| if (m_axObjectCache)
|
| m_axObjectCache->clearWeakMembers(visitor);
|
| +
|
| + // FIXME: Oilpan: Use a weak counted set instead.
|
| + if (m_touchEventTargets) {
|
| + Vector<Node*> deadNodes;
|
| + for (TouchEventTargetSet::iterator it = m_touchEventTargets->begin(); it != m_touchEventTargets->end(); ++it) {
|
| + if (!visitor->isAlive(it->key))
|
| + deadNodes.append(it->key);
|
| + }
|
| + for (unsigned i = 0; i < deadNodes.size(); ++i)
|
| + didClearTouchEventHandlers(deadNodes[i]);
|
| + }
|
| }
|
|
|
| void Document::trace(Visitor* visitor)
|
|
|