[ContentChangeObserver] Content observation should be limited to the current document.
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 4 Mar 2019 06:05:44 +0000 (06:05 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 4 Mar 2019 06:05:44 +0000 (06:05 +0000)
https://bugs.webkit.org/show_bug.cgi?id=195256
<rdar://problem/48544402>

Source/WebCore:

Move ContentChangeObserver from Page to Document.
It limits content observation to the target node's owner document.

Reviewed by Simon Fraser.

* dom/Document.cpp:
(WebCore::m_contentChangeObserver):
(WebCore::Document::updateStyleIfNeeded):
(WebCore::Document::willDetachPage):
(WebCore::Document::platformSuspendOrStopActiveDOMObjects):
(WebCore::m_undoManager): Deleted.
* dom/Document.h:
(WebCore::Document::contentChangeObserver):
* page/DOMTimer.cpp:
(WebCore::DOMTimer::install):
(WebCore::DOMTimer::removeById):
(WebCore::DOMTimer::fired):
* page/Frame.cpp:
(WebCore::Frame::willDetachPage):
* page/Page.cpp:
(WebCore::Page::Page):
* page/Page.h:
(WebCore::Page::pointerLockController const):
(WebCore::Page::contentChangeObserver): Deleted.
* page/ios/ContentChangeObserver.cpp:
(WebCore::ContentChangeObserver::ContentChangeObserver):
(WebCore::ContentChangeObserver::didInstallDOMTimer):
(WebCore::ContentChangeObserver::stopObservingDOMTimerExecute):
(WebCore::ContentChangeObserver::stopObservingStyleRecalc):
(WebCore::ContentChangeObserver::clearTimersAndReportContentChange):
(WebCore::ContentChangeObserver::startObservingMouseMoved):
(WebCore::ContentChangeObserver::hasDeterminateState const):
(WebCore::ContentChangeObserver::adjustObservedState):
(WebCore::ContentChangeObserver::notifyContentChangeIfNeeded):
(WebCore::ContentChangeObserver::StyleChangeScope::StyleChangeScope):
(WebCore::ContentChangeObserver::StyleChangeScope::~StyleChangeScope):
(WebCore::ContentChangeObserver::MouseMovedScope::MouseMovedScope):
(WebCore::ContentChangeObserver::MouseMovedScope::~MouseMovedScope):
(WebCore::ContentChangeObserver::StyleRecalcScope::StyleRecalcScope):
(WebCore::ContentChangeObserver::StyleRecalcScope::~StyleRecalcScope):
(WebCore::ContentChangeObserver::DOMTimerScope::DOMTimerScope):
(WebCore::ContentChangeObserver::DOMTimerScope::~DOMTimerScope):
(WebCore::hasPendingStyleRecalc): Deleted.
* page/ios/ContentChangeObserver.h:
* page/ios/EventHandlerIOS.mm:
(WebCore::EventHandler::mouseMoved):
* rendering/updating/RenderTreeUpdater.cpp:
(WebCore::RenderTreeUpdater::updateElementRenderer):

Source/WebKit:

Reviewed by Simon Fraser.

* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::handleSyntheticClick):
(WebKit::WebPage::completePendingSyntheticClickForContentChangeObserver):
(WebKit::WebPage::completeSyntheticClick):
(WebKit::WebPage::handleTap):
(WebKit::WebPage::handleTwoFingerTapAtPoint):
(WebKit::WebPage::commitPotentialTap):

Source/WebKitLegacy/ios:

Reviewed by Simon Fraser.

* WebCoreSupport/WebChromeClientIOS.mm:
(WebChromeClientIOS::observedContentChange):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242340 268f45cc-cd09-0410-ab3c-d52691b4dbfc

16 files changed:
Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/page/DOMTimer.cpp
Source/WebCore/page/Frame.cpp
Source/WebCore/page/Page.cpp
Source/WebCore/page/Page.h
Source/WebCore/page/ios/ContentChangeObserver.cpp
Source/WebCore/page/ios/ContentChangeObserver.h
Source/WebCore/page/ios/EventHandlerIOS.mm
Source/WebCore/rendering/updating/RenderTreeUpdater.cpp
Source/WebKit/ChangeLog
Source/WebKit/WebProcess/WebPage/WebPage.h
Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
Source/WebKitLegacy/ios/ChangeLog
Source/WebKitLegacy/ios/WebCoreSupport/WebChromeClientIOS.mm

index 4b450d2..adf8e20 100644 (file)
@@ -1,3 +1,58 @@
+2019-03-03  Zalan Bujtas  <zalan@apple.com>
+
+        [ContentChangeObserver] Content observation should be limited to the current document.
+        https://bugs.webkit.org/show_bug.cgi?id=195256
+        <rdar://problem/48544402>
+
+        Move ContentChangeObserver from Page to Document.
+        It limits content observation to the target node's owner document.
+
+        Reviewed by Simon Fraser.
+
+        * dom/Document.cpp:
+        (WebCore::m_contentChangeObserver):
+        (WebCore::Document::updateStyleIfNeeded):
+        (WebCore::Document::willDetachPage):
+        (WebCore::Document::platformSuspendOrStopActiveDOMObjects):
+        (WebCore::m_undoManager): Deleted.
+        * dom/Document.h:
+        (WebCore::Document::contentChangeObserver):
+        * page/DOMTimer.cpp:
+        (WebCore::DOMTimer::install):
+        (WebCore::DOMTimer::removeById):
+        (WebCore::DOMTimer::fired):
+        * page/Frame.cpp:
+        (WebCore::Frame::willDetachPage):
+        * page/Page.cpp:
+        (WebCore::Page::Page):
+        * page/Page.h:
+        (WebCore::Page::pointerLockController const):
+        (WebCore::Page::contentChangeObserver): Deleted.
+        * page/ios/ContentChangeObserver.cpp:
+        (WebCore::ContentChangeObserver::ContentChangeObserver):
+        (WebCore::ContentChangeObserver::didInstallDOMTimer):
+        (WebCore::ContentChangeObserver::stopObservingDOMTimerExecute):
+        (WebCore::ContentChangeObserver::stopObservingStyleRecalc):
+        (WebCore::ContentChangeObserver::clearTimersAndReportContentChange):
+        (WebCore::ContentChangeObserver::startObservingMouseMoved):
+        (WebCore::ContentChangeObserver::hasDeterminateState const):
+        (WebCore::ContentChangeObserver::adjustObservedState):
+        (WebCore::ContentChangeObserver::notifyContentChangeIfNeeded):
+        (WebCore::ContentChangeObserver::StyleChangeScope::StyleChangeScope):
+        (WebCore::ContentChangeObserver::StyleChangeScope::~StyleChangeScope):
+        (WebCore::ContentChangeObserver::MouseMovedScope::MouseMovedScope):
+        (WebCore::ContentChangeObserver::MouseMovedScope::~MouseMovedScope):
+        (WebCore::ContentChangeObserver::StyleRecalcScope::StyleRecalcScope):
+        (WebCore::ContentChangeObserver::StyleRecalcScope::~StyleRecalcScope):
+        (WebCore::ContentChangeObserver::DOMTimerScope::DOMTimerScope):
+        (WebCore::ContentChangeObserver::DOMTimerScope::~DOMTimerScope):
+        (WebCore::hasPendingStyleRecalc): Deleted.
+        * page/ios/ContentChangeObserver.h:
+        * page/ios/EventHandlerIOS.mm:
+        (WebCore::EventHandler::mouseMoved):
+        * rendering/updating/RenderTreeUpdater.cpp:
+        (WebCore::RenderTreeUpdater::updateElementRenderer):
+
 2019-03-02  Simon Fraser  <simon.fraser@apple.com>
 
         Share more code for updating the state of frame scrolling nodes
index ded0f9c..1429278 100644 (file)
@@ -2051,7 +2051,7 @@ bool Document::updateStyleIfNeeded()
     }
 
 #if PLATFORM(IOS_FAMILY)
-    ContentChangeObserver::StyleRecalcScope observingScope(page());
+    ContentChangeObserver::StyleRecalcScope observingScope(*this);
 #endif
     // The early exit above for !needsStyleRecalc() is needed when updateWidgetPositions() is called in runOrScheduleAsynchronousTasks().
     RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(isSafeToUpdateStyleOrLayout(*this));
@@ -2383,7 +2383,9 @@ void Document::frameDestroyed()
 void Document::willDetachPage()
 {
     FrameDestructionObserver::willDetachPage();
-
+#if PLATFORM(IOS_FAMILY)
+    contentChangeObserver().willDetachPage();
+#endif
     if (domWindow() && frame())
         InspectorInstrumentation::frameWindowDiscarded(*frame(), domWindow());
 }
@@ -2632,8 +2634,7 @@ bool Document::shouldBypassMainWorldContentSecurityPolicy() const
 void Document::platformSuspendOrStopActiveDOMObjects()
 {
 #if PLATFORM(IOS_FAMILY)
-    if (auto* page = this->page())
-        page->contentChangeObserver().didSuspendActiveDOMObjects();
+    contentChangeObserver().didSuspendActiveDOMObjects();
 #endif
 }
 
@@ -8683,4 +8684,13 @@ void Document::updateTouchActionElements(Element& element, const RenderStyle& st
 }
 #endif
 
+#if PLATFORM(IOS_FAMILY)
+ContentChangeObserver& Document::contentChangeObserver()
+{
+    if (!m_contentChangeObserver)
+        m_contentChangeObserver = std::make_unique<ContentChangeObserver>(*this);
+    return *m_contentChangeObserver; 
+}
+#endif
+
 } // namespace WebCore
index 4b5ac30..4ca7011 100644 (file)
@@ -99,6 +99,7 @@ class CanvasRenderingContext2D;
 class CharacterData;
 class Comment;
 class ConstantPropertyMap;
+class ContentChangeObserver;
 class DOMImplementation;
 class DOMSelection;
 class DOMWindow;
@@ -871,6 +872,8 @@ public:
 
     // Called when <meta name="apple-mobile-web-app-orientations"> changes.
     void processWebAppOrientations();
+
+    ContentChangeObserver& contentChangeObserver();
 #endif
     
     void processViewport(const String& features, ViewportArguments::Type origin);
@@ -2077,6 +2080,9 @@ private:
     bool m_isRunningUserScripts { false };
 
     Ref<UndoManager> m_undoManager;
+#if PLATFORM(IOS_FAMILY)
+    std::unique_ptr<ContentChangeObserver> m_contentChangeObserver;
+#endif
 };
 
 Element* eventTargetElementForDocument(Document*);
index 56c9a29..64f2654 100644 (file)
@@ -222,8 +222,8 @@ int DOMTimer::install(ScriptExecutionContext& context, std::unique_ptr<Scheduled
     if (NestedTimersMap* nestedTimers = NestedTimersMap::instanceForContext(context))
         nestedTimers->add(timer->m_timeoutId, *timer);
 #if PLATFORM(IOS_FAMILY)
-    if (is<Document>(context) && downcast<Document>(context).page())
-        downcast<Document>(context).page()->contentChangeObserver().didInstallDOMTimer(*timer, timeout, singleShot);
+    if (is<Document>(context))
+        downcast<Document>(context).contentChangeObserver().didInstallDOMTimer(*timer, timeout, singleShot);
 #endif
     return timer->m_timeoutId;
 }
@@ -237,10 +237,10 @@ void DOMTimer::removeById(ScriptExecutionContext& context, int timeoutId)
         return;
 
 #if PLATFORM(IOS_FAMILY)
-    if (is<Document>(context) && downcast<Document>(context).page()) {
+    if (is<Document>(context)) {
         auto& document = downcast<Document>(context);
         if (auto* timer = document.findTimeout(timeoutId))
-            document.page()->contentChangeObserver().didRemoveDOMTimer(*timer);
+            document.contentChangeObserver().didRemoveDOMTimer(*timer);
     }
 #endif
 
@@ -343,7 +343,7 @@ void DOMTimer::fired()
         nestedTimers->startTracking();
 
 #if PLATFORM(IOS_FAMILY)
-    ContentChangeObserver::DOMTimerScope observingScope(is<Document>(context) ? downcast<Document>(context).page() : nullptr, *this);
+    ContentChangeObserver::DOMTimerScope observingScope(is<Document>(context) ? &downcast<Document>(context) : nullptr, *this);
 #endif
     m_action->execute(context);
 
index 4fe2bc9..7d60fdf 100644 (file)
 #include <wtf/StdLibExtras.h>
 #include <wtf/text/StringBuilder.h>
 
-#if PLATFORM(IOS_FAMILY)
-#include "ContentChangeObserver.h"
-#endif
-
 namespace WebCore {
 
 using namespace HTMLNames;
@@ -843,11 +839,6 @@ void Frame::willDetachPage()
     if (page() && page()->scrollingCoordinator() && m_view)
         page()->scrollingCoordinator()->willDestroyScrollableArea(*m_view);
 
-#if PLATFORM(IOS_FAMILY)
-    if (auto* page = this->page())
-        page->contentChangeObserver().willDetachPage();
-#endif
-
     script().clearScriptObjects();
     script().updatePlatformScriptObjects();
 
index ec6d60d..c7b1b02 100644 (file)
 #include "SelectionRect.h"
 #endif
 
-#if PLATFORM(IOS_FAMILY)
-#include "ContentChangeObserver.h"
-#endif
-
 namespace WebCore {
 
 static HashSet<Page*>& allPages()
@@ -235,9 +231,6 @@ Page::Page(PageConfiguration&& pageConfiguration)
     , m_performanceLoggingClient(WTFMove(pageConfiguration.performanceLoggingClient))
     , m_webGLStateTracker(WTFMove(pageConfiguration.webGLStateTracker))
     , m_libWebRTCProvider(WTFMove(pageConfiguration.libWebRTCProvider))
-#if PLATFORM(IOS_FAMILY)
-    , m_contentChangeObserver(std::make_unique<ContentChangeObserver>(*this))
-#endif
     , m_verticalScrollElasticity(ScrollElasticityAllowed)
     , m_horizontalScrollElasticity(ScrollElasticityAllowed)
     , m_domTimerAlignmentInterval(DOMTimer::defaultAlignmentInterval())
index 061907c..8617bd4 100644 (file)
@@ -86,9 +86,6 @@ class CacheStorageProvider;
 class Chrome;
 class ChromeClient;
 class Color;
-#if PLATFORM(IOS_FAMILY)
-class ContentChangeObserver;
-#endif
 class ContextMenuClient;
 class ContextMenuController;
 class CookieJar;
@@ -255,9 +252,6 @@ public:
 #if ENABLE(POINTER_LOCK)
     PointerLockController& pointerLockController() const { return *m_pointerLockController; }
 #endif
-#if PLATFORM(IOS_FAMILY)
-    ContentChangeObserver& contentChangeObserver() { return *m_contentChangeObserver; }
-#endif
     LibWebRTCProvider& libWebRTCProvider() { return m_libWebRTCProvider.get(); }
     RTCController& rtcController() { return m_rtcController; }
     WEBCORE_EXPORT void disableICECandidateFiltering();
@@ -818,7 +812,6 @@ private:
 
 #if PLATFORM(IOS_FAMILY)
     bool m_enclosedInScrollableAncestorView { false };
-    std::unique_ptr<ContentChangeObserver> m_contentChangeObserver;
 #endif
     
     bool m_useSystemAppearance { false };
index dab2a21..65ae858 100644 (file)
 #include "Chrome.h"
 #include "ChromeClient.h"
 #include "DOMTimer.h"
+#include "Document.h"
 #include "Logging.h"
 #include "NodeRenderStyle.h"
 #include "Page.h"
 
 namespace WebCore {
 
-static bool hasPendingStyleRecalc(const Page& page)
-{
-    for (auto* frame = &page.mainFrame(); frame; frame = frame->tree().traverseNext()) {
-        if (auto* document = frame->document()) {
-            if (document->hasPendingStyleRecalc())
-                return true;
-        }
-    }
-    return false;
-}
-
-ContentChangeObserver::ContentChangeObserver(Page& page)
-    : m_page(page)
+ContentChangeObserver::ContentChangeObserver(Document& document)
+    : m_document(document)
 {
 }
 
 void ContentChangeObserver::didInstallDOMTimer(const DOMTimer& timer, Seconds timeout, bool singleShot)
 {
-    if (!m_page.mainFrame().document())
-        return;
-    if (m_page.mainFrame().document()->activeDOMObjectsAreSuspended())
+    if (m_document.activeDOMObjectsAreSuspended())
         return;
     if (timeout > 250_ms || !singleShot)
         return;
@@ -95,7 +83,7 @@ void ContentChangeObserver::stopObservingDOMTimerExecute(const DOMTimer& timer)
 
     m_isObservingContentChanges = false;
     unregisterDOMTimer(timer);
-    setShouldObserveStyleRecalc(WebCore::hasPendingStyleRecalc(m_page));
+    setShouldObserveStyleRecalc(m_document.hasPendingStyleRecalc());
     notifyContentChangeIfNeeded();
 }
 
@@ -117,6 +105,7 @@ void ContentChangeObserver::stopObservingStyleRecalc()
     LOG(ContentObservation, "stopObservingStyleRecalc: stop observing style recalc");
 
     setShouldObserveStyleRecalc(false);
+    m_isObservingContentChanges = false;
     adjustObservedState(Event::StyleRecalcFinished);
     notifyContentChangeIfNeeded();
 }
@@ -128,7 +117,9 @@ void ContentChangeObserver::clearTimersAndReportContentChange()
     LOG_WITH_STREAM(ContentObservation, stream << "clearTimersAndReportContentChange: remove registered timers and report content change." << observedContentChange());
 
     clearObservedDOMTimers();
-    m_page.chrome().client().observedContentChange(m_page.mainFrame());
+    ASSERT(m_document.page());
+    ASSERT(m_document.frame());
+    m_document.page()->chrome().client().observedContentChange(*m_document.frame());
 }
 
 void ContentChangeObserver::didSuspendActiveDOMObjects()
@@ -149,7 +140,7 @@ void ContentChangeObserver::contentVisibilityDidChange()
 
 void ContentChangeObserver::startObservingMouseMoved()
 {
-    ASSERT(!hasPendingStyleRecalc(m_page));
+    ASSERT(!m_document.hasPendingStyleRecalc());
     clearObservedDOMTimers();
     startObservingDOMTimerScheduling();
     m_isObservingContentChanges = true;
@@ -190,7 +181,7 @@ bool ContentChangeObserver::hasDeterminateState() const
 {
     if (hasVisibleChangeState())
         return true;
-    return observedContentChange() == WKContentNoChange && !hasObservedDOMTimer() && !hasPendingStyleRecalc(m_page);
+    return observedContentChange() == WKContentNoChange && !hasObservedDOMTimer() && !m_document.hasPendingStyleRecalc();
 }
 
 void ContentChangeObserver::adjustObservedState(Event event)
@@ -207,7 +198,7 @@ void ContentChangeObserver::adjustObservedState(Event event)
     case Event::RemovedDOMTimer:
     case Event::StyleRecalcFinished:
         // Demote to "no change" when there's no pending activity anymore.
-        if (observedContentChange() == WKContentIndeterminateChange && !hasObservedDOMTimer() && !hasPendingStyleRecalc(m_page))
+        if (observedContentChange() == WKContentIndeterminateChange && !hasObservedDOMTimer() && !m_document.hasPendingStyleRecalc())
             setHasNoChangeState();
         break;
     case Event::ContentVisibilityChanged:
@@ -223,7 +214,9 @@ void ContentChangeObserver::notifyContentChangeIfNeeded()
         return;
     }
     LOG_WITH_STREAM(ContentObservation, stream << "notifyContentChangeIfNeeded: sending observedContentChange ->" << observedContentChange());
-    m_page.chrome().client().observedContentChange(m_page.mainFrame());
+    ASSERT(m_document.page());
+    ASSERT(m_document.frame());
+    m_document.page()->chrome().client().observedContentChange(*m_document.frame());
 }
 
 
@@ -250,10 +243,10 @@ static Visibility elementImplicitVisibility(const Element& element)
     return Visibility::Visible;
 }
 
-ContentChangeObserver::StyleChangeScope::StyleChangeScope(Page* page, const Element& element)
-    : m_contentChangeObserver(page ? &page->contentChangeObserver() : nullptr)
+ContentChangeObserver::StyleChangeScope::StyleChangeScope(Document& document, const Element& element)
+    : m_contentChangeObserver(document.contentChangeObserver())
     , m_element(element)
-    , m_needsObserving(m_contentChangeObserver && m_contentChangeObserver->isObservingContentChanges() && m_contentChangeObserver->observedContentChange() != WKContentVisibilityChange)
+    , m_needsObserving(m_contentChangeObserver.isObservingContentChanges() && m_contentChangeObserver.observedContentChange() != WKContentVisibilityChange)
 {
     if (m_needsObserving) {
         m_previousDisplay = element.renderStyle() ? element.renderStyle()->display() : DisplayType::None;
@@ -284,37 +277,33 @@ ContentChangeObserver::StyleChangeScope::~StyleChangeScope()
     if ((m_previousDisplay == DisplayType::None && style->display() != DisplayType::None)
         || (m_previousVisibility == Visibility::Hidden && style->visibility() != Visibility::Hidden)
         || (m_previousImplicitVisibility == Visibility::Hidden && elementImplicitVisibility(m_element) == Visibility::Visible))
-        m_contentChangeObserver->contentVisibilityDidChange();
+        m_contentChangeObserver.contentVisibilityDidChange();
 }
 
-ContentChangeObserver::MouseMovedScope::MouseMovedScope(Page* page)
-    : m_contentChangeObserver(page ? &page->contentChangeObserver() : nullptr)
+ContentChangeObserver::MouseMovedScope::MouseMovedScope(Document& document)
+    : m_contentChangeObserver(document.contentChangeObserver())
 {
-    if (m_contentChangeObserver)
-        m_contentChangeObserver->startObservingMouseMoved();
+    m_contentChangeObserver.startObservingMouseMoved();
 }
 
 ContentChangeObserver::MouseMovedScope::~MouseMovedScope()
 {
-    if (m_contentChangeObserver)
-        m_contentChangeObserver->stopObservingMouseMoved();
+    m_contentChangeObserver.stopObservingMouseMoved();
 }
 
-ContentChangeObserver::StyleRecalcScope::StyleRecalcScope(Page* page)
-    : m_contentChangeObserver(page ? &page->contentChangeObserver() : nullptr)
+ContentChangeObserver::StyleRecalcScope::StyleRecalcScope(Document& document)
+    : m_contentChangeObserver(document.contentChangeObserver())
 {
-    if (m_contentChangeObserver)
-        m_contentChangeObserver->startObservingStyleRecalc();
+    m_contentChangeObserver.startObservingStyleRecalc();
 }
 
 ContentChangeObserver::StyleRecalcScope::~StyleRecalcScope()
 {
-    if (m_contentChangeObserver)
-        m_contentChangeObserver->stopObservingStyleRecalc();
+    m_contentChangeObserver.stopObservingStyleRecalc();
 }
 
-ContentChangeObserver::DOMTimerScope::DOMTimerScope(Page* page, const DOMTimer& domTimer)
-    : m_contentChangeObserver(page ? &page->contentChangeObserver() : nullptr)
+ContentChangeObserver::DOMTimerScope::DOMTimerScope(Document* document, const DOMTimer& domTimer)
+    : m_contentChangeObserver(document ? &document->contentChangeObserver() : nullptr)
     , m_domTimer(domTimer)
 {
     if (m_contentChangeObserver)
index 73ae578..07b5ec9 100644 (file)
 namespace WebCore {
 
 class DOMTimer;
-class Page;
+class Document;
 
 class ContentChangeObserver {
 public:
-    ContentChangeObserver(Page&);
+    ContentChangeObserver(Document&);
 
     WEBCORE_EXPORT WKContentChange observedContentChange() const;
 
@@ -48,11 +48,11 @@ public:
 
     class StyleChangeScope {
     public:
-        StyleChangeScope(Page*, const Element&);
+        StyleChangeScope(Document&, const Element&);
         ~StyleChangeScope();
 
     private:
-        ContentChangeObserver* m_contentChangeObserver { nullptr };
+        ContentChangeObserver& m_contentChangeObserver;
         const Element& m_element;
         bool m_needsObserving { false };
         DisplayType m_previousDisplay;
@@ -62,23 +62,23 @@ public:
 
     class MouseMovedScope {
     public:
-        WEBCORE_EXPORT MouseMovedScope(Page*);
+        WEBCORE_EXPORT MouseMovedScope(Document&);
         WEBCORE_EXPORT ~MouseMovedScope();
     private:
-        ContentChangeObserver* m_contentChangeObserver { nullptr };
+        ContentChangeObserver& m_contentChangeObserver;
     };
 
     class StyleRecalcScope {
     public:
-        StyleRecalcScope(Page*);
+        StyleRecalcScope(Document&);
         ~StyleRecalcScope();
     private:
-        ContentChangeObserver* m_contentChangeObserver { nullptr };
+        ContentChangeObserver& m_contentChangeObserver;
     };
 
     class DOMTimerScope {
     public:
-        DOMTimerScope(Page*, const DOMTimer&);
+        DOMTimerScope(Document*, const DOMTimer&);
         ~DOMTimerScope();
     private:
         ContentChangeObserver* m_contentChangeObserver { nullptr };
@@ -130,7 +130,7 @@ private:
     };
     void adjustObservedState(Event);
 
-    Page& m_page;
+    Document& m_document;
     HashSet<const DOMTimer*> m_DOMTimerList;
     bool m_shouldObserveStyleRecalc { false };
     bool m_isObservingDOMTimerScheduling { false };
index 4f7003b..d006d41 100644 (file)
@@ -496,7 +496,7 @@ void EventHandler::mouseMoved(WebEvent *event)
     document.updateStyleIfNeeded();
     CurrentEventScope scope(event);
     {
-        ContentChangeObserver::MouseMovedScope observingScope(document.page());
+        ContentChangeObserver::MouseMovedScope observingScope(document);
         event.wasHandled = mouseMoved(currentPlatformMouseEvent());
         // Run style recalc to be able to capture content changes as the result of the mouse move event.
         document.updateStyleIfNeeded();
index c5f4350..dc1c41f 100644 (file)
@@ -293,7 +293,7 @@ void RenderTreeUpdater::updateRendererStyle(RenderElement& renderer, RenderStyle
 void RenderTreeUpdater::updateElementRenderer(Element& element, const Style::ElementUpdate& update)
 {
 #if PLATFORM(IOS_FAMILY)
-    ContentChangeObserver::StyleChangeScope observingScope(m_document.page(), element);
+    ContentChangeObserver::StyleChangeScope observingScope(m_document, element);
 #endif
 
     bool shouldTearDownRenderers = update.change == Style::Detach && (element.renderer() || element.hasDisplayContents());
index e9910bc..766eeb9 100644 (file)
@@ -1,3 +1,20 @@
+2019-03-03  Zalan Bujtas  <zalan@apple.com>
+
+        [ContentChangeObserver] Content observation should be limited to the current document.
+        https://bugs.webkit.org/show_bug.cgi?id=195256
+        <rdar://problem/48544402>
+
+        Reviewed by Simon Fraser.
+
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::handleSyntheticClick):
+        (WebKit::WebPage::completePendingSyntheticClickForContentChangeObserver):
+        (WebKit::WebPage::completeSyntheticClick):
+        (WebKit::WebPage::handleTap):
+        (WebKit::WebPage::handleTwoFingerTapAtPoint):
+        (WebKit::WebPage::commitPotentialTap):
+
 2019-03-03  Tim Horton  <timothy_horton@apple.com>
 
         Rid the world of WK_API_ENABLED
index fc9f9f5..d21eafb 100644 (file)
@@ -1189,8 +1189,8 @@ private:
     RefPtr<WebCore::Range> rangeForWebSelectionAtPosition(const WebCore::IntPoint&, const WebCore::VisiblePosition&, SelectionFlags&);
     void getFocusedElementInformation(FocusedElementInformation&);
     void platformInitializeAccessibility();
-    void handleSyntheticClick(WebCore::Node* nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebKit::WebEvent::Modifier>);
-    void completeSyntheticClick(WebCore::Node* nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebKit::WebEvent::Modifier>, WebCore::SyntheticClickType);
+    void handleSyntheticClick(WebCore::Node& nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebKit::WebEvent::Modifier>);
+    void completeSyntheticClick(WebCore::Node& nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebKit::WebEvent::Modifier>, WebCore::SyntheticClickType);
     void sendTapHighlightForNodeIfNecessary(uint64_t requestID, WebCore::Node*);
     void resetTextAutosizing();
     WebCore::VisiblePosition visiblePositionInFocusedNodeForPoint(const WebCore::Frame&, const WebCore::IntPoint&, bool isInteractingWithFocusedElement);
index bbce20f..42ee757 100644 (file)
@@ -535,20 +535,19 @@ void WebPage::updateSelectionAppearance()
         didChangeSelection();
 }
 
-void WebPage::handleSyntheticClick(Node* nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebEvent::Modifier> modifiers)
+void WebPage::handleSyntheticClick(Node& nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebEvent::Modifier> modifiers)
 {
     IntPoint roundedAdjustedPoint = roundedIntPoint(location);
-    auto& mainframe = m_page->mainFrame();
-    auto& contentChangeObserver = m_page->contentChangeObserver();
-
+    auto& respondingDocument = nodeRespondingToClick.document();
     // FIXME: Pass caps lock state.
     bool shiftKey = modifiers.contains(WebEvent::Modifier::ShiftKey);
     bool ctrlKey = modifiers.contains(WebEvent::Modifier::ControlKey);
     bool altKey = modifiers.contains(WebEvent::Modifier::AltKey);
     bool metaKey = modifiers.contains(WebEvent::Modifier::MetaKey);
     {
-        LOG_WITH_STREAM(ContentObservation, stream << "handleSyntheticClick: node(" << nodeRespondingToClick << ") " << location);
-        ContentChangeObserver::MouseMovedScope observingScope(m_page.get());
+        LOG_WITH_STREAM(ContentObservation, stream << "handleSyntheticClick: node(" << &nodeRespondingToClick << ") " << location);
+        ContentChangeObserver::MouseMovedScope observingScope(respondingDocument);
+        auto& mainframe = m_page->mainFrame();
         mainframe.eventHandler().mouseMoved(PlatformMouseEvent(roundedAdjustedPoint, roundedAdjustedPoint, NoButton, PlatformEvent::MouseMoved, 0, shiftKey, ctrlKey, altKey, metaKey, WallTime::now(), WebCore::ForceAtClick, WebCore::NoTap));
         mainframe.document()->updateStyleIfNeeded();
     }
@@ -560,14 +559,14 @@ void WebPage::handleSyntheticClick(Node* nodeRespondingToClick, const WebCore::F
     if (m_isClosed)
         return;
 
-    switch (contentChangeObserver.observedContentChange()) {
+    switch (respondingDocument.contentChangeObserver().observedContentChange()) {
     case WKContentVisibilityChange:
         // The move event caused new contents to appear. Don't send the click event.
         LOG(ContentObservation, "handleSyntheticClick: Observed meaningful visible change -> hover.");
         return;
     case WKContentIndeterminateChange: {
         // Wait for callback to completePendingSyntheticClickForContentChangeObserver() to decide whether to send the click event.
-        m_pendingSyntheticClickNode = nodeRespondingToClick;
+        m_pendingSyntheticClickNode = &nodeRespondingToClick;
         m_pendingSyntheticClickLocation = location;
         m_pendingSyntheticClickModifiers = modifiers;
         LOG(ContentObservation, "handleSyntheticClick: Observed some change, but can't decide it yet -> wait.");
@@ -585,10 +584,11 @@ void WebPage::completePendingSyntheticClickForContentChangeObserver()
     LOG_WITH_STREAM(ContentObservation, stream << "completePendingSyntheticClickForContentChangeObserver: pending target node(" << m_pendingSyntheticClickNode << ")");
     if (!m_pendingSyntheticClickNode)
         return;
+    auto observedContentChange = m_pendingSyntheticClickNode->document().contentChangeObserver().observedContentChange();
     // Only dispatch the click if the document didn't get changed by any timers started by the move event.
-    if (m_page->contentChangeObserver().observedContentChange() == WKContentNoChange) {
+    if (observedContentChange == WKContentNoChange) {
         LOG(ContentObservation, "No chage was observed -> click.");
-        completeSyntheticClick(m_pendingSyntheticClickNode.get(), m_pendingSyntheticClickLocation, m_pendingSyntheticClickModifiers, WebCore::OneFingerTap);
+        completeSyntheticClick(*m_pendingSyntheticClickNode, m_pendingSyntheticClickLocation, m_pendingSyntheticClickModifiers, WebCore::OneFingerTap);
     } else
         LOG(ContentObservation, "Observed meaningful visible change -> hover.");
 
@@ -597,7 +597,7 @@ void WebPage::completePendingSyntheticClickForContentChangeObserver()
     m_pendingSyntheticClickModifiers = { };
 }
 
-void WebPage::completeSyntheticClick(Node* nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebEvent::Modifier> modifiers, SyntheticClickType syntheticClickType)
+void WebPage::completeSyntheticClick(Node& nodeRespondingToClick, const WebCore::FloatPoint& location, OptionSet<WebEvent::Modifier> modifiers, SyntheticClickType syntheticClickType)
 {
     IntPoint roundedAdjustedPoint = roundedIntPoint(location);
     Frame& mainframe = m_page->mainFrame();
@@ -634,7 +634,7 @@ void WebPage::completeSyntheticClick(Node* nodeRespondingToClick, const WebCore:
     if (newFocusedElement && newFocusedElement == oldFocusedElement)
         elementDidRefocus(*newFocusedElement);
 
-    if (!tapWasHandled || !nodeRespondingToClick || !nodeRespondingToClick->isElementNode())
+    if (!tapWasHandled || !nodeRespondingToClick.isElementNode())
         send(Messages::WebPageProxy::DidNotHandleTapAsClick(roundedIntPoint(location)));
     
     send(Messages::WebPageProxy::DidCompleteSyntheticClick());
@@ -657,7 +657,7 @@ void WebPage::handleTap(const IntPoint& point, OptionSet<WebEvent::Modifier> mod
     }
 #endif
     else
-        handleSyntheticClick(nodeRespondingToClick, adjustedPoint, modifiers);
+        handleSyntheticClick(*nodeRespondingToClick, adjustedPoint, modifiers);
 }
 
 void WebPage::requestFocusedElementInformation(WebKit::CallbackID callbackID)
@@ -768,7 +768,7 @@ void WebPage::handleTwoFingerTapAtPoint(const WebCore::IntPoint& point, OptionSe
         send(Messages::WebPageProxy::DidNotHandleTapAsClick(roundedIntPoint(adjustedPoint)));
     } else
 #endif
-        completeSyntheticClick(nodeRespondingToClick, adjustedPoint, modifiers, WebCore::TwoFingerTap);
+        completeSyntheticClick(*nodeRespondingToClick, adjustedPoint, modifiers, WebCore::TwoFingerTap);
 }
 
 void WebPage::handleStylusSingleTapAtPoint(const WebCore::IntPoint& point, uint64_t requestID)
@@ -837,7 +837,7 @@ void WebPage::commitPotentialTap(OptionSet<WebEvent::Modifier> modifiers, uint64
             commitPotentialTapFailed();
         } else
 #endif
-            handleSyntheticClick(nodeRespondingToClick, adjustedPoint, modifiers);
+            handleSyntheticClick(*nodeRespondingToClick, adjustedPoint, modifiers);
     } else
         commitPotentialTapFailed();
 
index 0a0fba3..342e989 100644 (file)
@@ -1,3 +1,14 @@
+2019-03-03  Zalan Bujtas  <zalan@apple.com>
+
+        [ContentChangeObserver] Content observation should be limited to the current document.
+        https://bugs.webkit.org/show_bug.cgi?id=195256
+        <rdar://problem/48544402>
+
+        Reviewed by Simon Fraser.
+
+        * WebCoreSupport/WebChromeClientIOS.mm:
+        (WebChromeClientIOS::observedContentChange):
+
 2019-02-26  Zalan Bujtas  <zalan@apple.com>
 
         [ContentChangeObserver] clearContentChangeObservers should be internal to ContentChangeObserver class
index 88ccec9..786431f 100644 (file)
@@ -184,9 +184,9 @@ void WebChromeClientIOS::setNeedsScrollNotifications(WebCore::Frame& frame, bool
 
 void WebChromeClientIOS::observedContentChange(WebCore::Frame& frame)
 {
-    if (!frame.page())
+    if (!frame.document())
         return;
-    [[webView() _UIKitDelegateForwarder] webView:webView() didObserveDeferredContentChange:frame.page()->contentChangeObserver().observedContentChange() forFrame:kit(&frame)];
+    [[webView() _UIKitDelegateForwarder] webView:webView() didObserveDeferredContentChange:frame.document()->contentChangeObserver().observedContentChange() forFrame:kit(&frame)];
 }
 
 static inline NSString *nameForViewportFitValue(ViewportFit value)