Diff
Modified: trunk/Source/WebCore/ChangeLog (287216 => 287217)
--- trunk/Source/WebCore/ChangeLog 2021-12-18 02:30:09 UTC (rev 287216)
+++ trunk/Source/WebCore/ChangeLog 2021-12-18 03:06:39 UTC (rev 287217)
@@ -1,3 +1,49 @@
+2021-12-17 Wenson Hsieh <wenson_hs...@apple.com>
+
+ Add support for detecting modal containers that contain a given search term
+ https://bugs.webkit.org/show_bug.cgi?id=234214
+
+ Reviewed by Tim Horton and Devin Rousso.
+
+ Introduce ModalContainerObserver (a helper class that searches for a substring vended by the client layer in
+ text inside viewport-constrained renderers). If found, we keep track of the viewport-constrained container with
+ the matching text for use in future patches.
+
+ There is no change in behavior yet.
+
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * dom/Document.cpp:
+ (WebCore::Document::modalContainerObserver):
+
+ Returns the document's ModalContainerObserver, creating it only if needed (per the modal container observation
+ policy vended by the client).
+
+ (WebCore::Document::modalContainerObserverIfExists const):
+ * dom/Document.h:
+ * page/ChromeClient.h:
+ (WebCore::ChromeClient::searchStringForModalContainerObserver const):
+ * page/FrameView.cpp:
+ (WebCore::FrameView::performPostLayoutTasks):
+
+ Add a hook to create and call into ModalContainerObserver to search for a modal container (if necessary).
+
+ * page/ModalContainerObserver.cpp: Added.
+ (WebCore::ModalContainerObserver::isNeededFor):
+
+ Add a helper method to determine whether this "modal container observer" should be created and used for the
+ current document.
+
+ (WebCore::matchesSearchTerm):
+ (WebCore::ModalContainerObserver::updateModalContainerIfNeeded):
+
+ Iterates through all viewport-constrained render objects in the FrameView, in search of one that matches the
+ search term given by the client. This currently ensures that we only search any viewport-constrained element at
+ most once by maintaining a weak `m_elementsToIgnoreWhenSearching` set, but we may need a mechanism in the future
+ to remove elements from this set upon changing text content.
+
+ * page/ModalContainerObserver.h: Added.
+
2021-12-17 Myles C. Maxfield <mmaxfi...@apple.com>
Add comment to r287208.
Modified: trunk/Source/WebCore/Sources.txt (287216 => 287217)
--- trunk/Source/WebCore/Sources.txt 2021-12-18 02:30:09 UTC (rev 287216)
+++ trunk/Source/WebCore/Sources.txt 2021-12-18 03:06:39 UTC (rev 287217)
@@ -1743,6 +1743,7 @@
page/Location.cpp
page/LoggedInStatus.cpp
page/MemoryRelease.cpp
+page/ModalContainerObserver.cpp
page/MouseEventWithHitTestResults.cpp
page/Navigator.cpp
page/NavigatorBase.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (287216 => 287217)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-12-18 02:30:09 UTC (rev 287216)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-12-18 03:06:39 UTC (rev 287217)
@@ -3269,6 +3269,7 @@
A10BB58B1484E3B300B2E87A /* RenderSVGShape.h in Headers */ = {isa = PBXBuildFile; fileRef = A10BB5891484E3B300B2E87A /* RenderSVGShape.h */; };
A10DBF4718F92317000D70C6 /* LegacyPreviewLoaderClient.h in Headers */ = {isa = PBXBuildFile; fileRef = A10DBF4618F92317000D70C6 /* LegacyPreviewLoaderClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
A10DC76B14747BAB005E2471 /* StyleGridData.h in Headers */ = {isa = PBXBuildFile; fileRef = A10DC76914747BAB005E2471 /* StyleGridData.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ A10F7C73273100D0008FA9AF /* ModalContainerObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = A10F7C7027310073008FA9AF /* ModalContainerObserver.h */; settings = {ATTRIBUTES = (Private, ); }; };
A110DB9B14F5DF7700A03B93 /* StyleGridItemData.h in Headers */ = {isa = PBXBuildFile; fileRef = A110DB9A14F5DF7700A03B93 /* StyleGridItemData.h */; settings = {ATTRIBUTES = (Private, ); }; };
A113E02823318293009C33A0 /* PaymentSessionError.h in Headers */ = {isa = PBXBuildFile; fileRef = A113E02723318293009C33A0 /* PaymentSessionError.h */; settings = {ATTRIBUTES = (Private, ); }; };
A113E02E2331A134009C33A0 /* ApplePayCancelEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = A113E02B2331A0E4009C33A0 /* ApplePayCancelEvent.h */; };
@@ -13355,6 +13356,8 @@
A10DBF4618F92317000D70C6 /* LegacyPreviewLoaderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LegacyPreviewLoaderClient.h; sourceTree = "<group>"; };
A10DC76814747BAB005E2471 /* StyleGridData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleGridData.cpp; sourceTree = "<group>"; };
A10DC76914747BAB005E2471 /* StyleGridData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleGridData.h; sourceTree = "<group>"; };
+ A10F7C7027310073008FA9AF /* ModalContainerObserver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ModalContainerObserver.h; sourceTree = "<group>"; };
+ A10F7C7127310073008FA9AF /* ModalContainerObserver.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ModalContainerObserver.cpp; sourceTree = "<group>"; };
A110DB9A14F5DF7700A03B93 /* StyleGridItemData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleGridItemData.h; sourceTree = "<group>"; };
A110DB9C14F5DF8700A03B93 /* StyleGridItemData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleGridItemData.cpp; sourceTree = "<group>"; };
A113E02723318293009C33A0 /* PaymentSessionError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PaymentSessionError.h; sourceTree = "<group>"; };
@@ -23947,6 +23950,8 @@
52E2CAFB19FF0207001EEB4F /* MediaProducer.h */,
413E00771DB0E4DE002341D2 /* MemoryRelease.cpp */,
413E00781DB0E4DE002341D2 /* MemoryRelease.h */,
+ A10F7C7127310073008FA9AF /* ModalContainerObserver.cpp */,
+ A10F7C7027310073008FA9AF /* ModalContainerObserver.h */,
93EB355E09E37FD600F43799 /* MouseEventWithHitTestResults.cpp */,
935C476209AC4CE600A6AAB4 /* MouseEventWithHitTestResults.h */,
6B507A23234BF34100BE7C62 /* Navigator+IsLoggedIn.idl */,
@@ -36092,6 +36097,7 @@
CDF2B0171820540700F2B424 /* MockSourceBufferPrivate.h in Headers */,
CDF2B0191820540700F2B424 /* MockTracks.h in Headers */,
5715610C234C1CA1008FC7AB /* MockWebAuthenticationConfiguration.h in Headers */,
+ A10F7C73273100D0008FA9AF /* ModalContainerObserver.h in Headers */,
2DC8D39825F2FE9700CFCBAB /* Model.h in Headers */,
313E79EA273C86B80097F905 /* ModelDocument.h in Headers */,
BC2B41172732F41E00A2D191 /* ModelPlayer.h in Headers */,
Modified: trunk/Source/WebCore/dom/Document.cpp (287216 => 287217)
--- trunk/Source/WebCore/dom/Document.cpp 2021-12-18 02:30:09 UTC (rev 287216)
+++ trunk/Source/WebCore/dom/Document.cpp 2021-12-18 03:06:39 UTC (rev 287217)
@@ -148,6 +148,7 @@
#include "MediaQueryMatcher.h"
#include "MediaStream.h"
#include "MessageEvent.h"
+#include "ModalContainerObserver.h"
#include "MouseEventWithHitTestResults.h"
#include "MutationEvent.h"
#include "NameNodeList.h"
@@ -9083,6 +9084,18 @@
return builder.toString();
}
+ModalContainerObserver* Document::modalContainerObserver()
+{
+ if (!m_modalContainerObserver && ModalContainerObserver::isNeededFor(*this))
+ m_modalContainerObserver = makeUnique<ModalContainerObserver>();
+ return m_modalContainerObserver.get();
+}
+
+ModalContainerObserver* Document::modalContainerObserverIfExists() const
+{
+ return m_modalContainerObserver.get();
+}
+
TextStream& operator<<(TextStream& ts, const Document& document)
{
ts << document.debugDescription();
Modified: trunk/Source/WebCore/dom/Document.h (287216 => 287217)
--- trunk/Source/WebCore/dom/Document.h 2021-12-18 02:30:09 UTC (rev 287216)
+++ trunk/Source/WebCore/dom/Document.h 2021-12-18 03:06:39 UTC (rev 287217)
@@ -183,6 +183,7 @@
class MediaQueryList;
class MediaQueryMatcher;
class MessagePortChannelProvider;
+class ModalContainerObserver;
class MouseEventWithHitTestResults;
class NodeFilter;
class NodeIterator;
@@ -1663,6 +1664,9 @@
URL fallbackBaseURL() const;
+ ModalContainerObserver* modalContainerObserver();
+ ModalContainerObserver* modalContainerObserverIfExists() const;
+
protected:
enum ConstructionFlags { Synthesized = 1, NonRenderedPlaceholder = 1 << 1 };
WEBCORE_EXPORT Document(Frame*, const Settings&, const URL&, DocumentClasses = { }, unsigned constructionFlags = 0);
@@ -2249,6 +2253,8 @@
#if ENABLE(WEB_RTC)
RefPtr<RTCNetworkManager> m_rtcNetworkManager;
#endif
+
+ std::unique_ptr<ModalContainerObserver> m_modalContainerObserver;
};
Element* eventTargetElementForDocument(Document*);
Modified: trunk/Source/WebCore/page/ChromeClient.h (287216 => 287217)
--- trunk/Source/WebCore/page/ChromeClient.h 2021-12-18 02:30:09 UTC (rev 287216)
+++ trunk/Source/WebCore/page/ChromeClient.h 2021-12-18 03:06:39 UTC (rev 287217)
@@ -623,6 +623,8 @@
virtual void requestCookieConsent(CompletionHandler<void(CookieConsentDecisionResult)>&&) = 0;
+ virtual const AtomString& searchStringForModalContainerObserver() const { return nullAtom(); }
+
protected:
virtual ~ChromeClient() = default;
};
Modified: trunk/Source/WebCore/page/FrameView.cpp (287216 => 287217)
--- trunk/Source/WebCore/page/FrameView.cpp 2021-12-18 02:30:09 UTC (rev 287216)
+++ trunk/Source/WebCore/page/FrameView.cpp 2021-12-18 03:06:39 UTC (rev 287217)
@@ -72,6 +72,7 @@
#include "LegacyRenderSVGRoot.h"
#include "Logging.h"
#include "MemoryCache.h"
+#include "ModalContainerObserver.h"
#include "NullGraphicsContext.h"
#include "OverflowEvent.h"
#include "Page.h"
@@ -3433,6 +3434,9 @@
if (AXObjectCache* cache = frame().document()->existingAXObjectCache())
cache->performDeferredCacheUpdate();
+
+ if (auto* observer = frame().document()->modalContainerObserver())
+ observer->updateModalContainerIfNeeded(*this);
}
IntSize FrameView::sizeForResizeEvent() const
Added: trunk/Source/WebCore/page/ModalContainerObserver.cpp (0 => 287217)
--- trunk/Source/WebCore/page/ModalContainerObserver.cpp (rev 0)
+++ trunk/Source/WebCore/page/ModalContainerObserver.cpp 2021-12-18 03:06:39 UTC (rev 287217)
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ModalContainerObserver.h"
+
+#include "Chrome.h"
+#include "ChromeClient.h"
+#include "Document.h"
+#include "DocumentLoader.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "HTMLBodyElement.h"
+#include "HTMLDocument.h"
+#include "HTMLElement.h"
+#include "Page.h"
+#include "RenderDescendantIterator.h"
+#include "RenderText.h"
+#include "RenderView.h"
+#include "Text.h"
+#include <wtf/URL.h>
+
+namespace WebCore {
+
+bool ModalContainerObserver::isNeededFor(const Document& document)
+{
+ RefPtr documentLoader = document.loader();
+ if (!documentLoader || documentLoader->modalContainerObservationPolicy() == ModalContainerObservationPolicy::Disabled)
+ return false;
+
+ if (!document.url().protocolIsInHTTPFamily())
+ return false;
+
+ if (!document.isTopDocument()) {
+ // FIXME (234446): Need to properly support subframes.
+ return false;
+ }
+
+ if (document.inDesignMode() || !is<HTMLDocument>(document))
+ return false;
+
+ auto* frame = document.frame();
+ if (!frame)
+ return false;
+
+ auto* page = frame->page();
+ if (!page || page->isEditable())
+ return false;
+
+ return true;
+}
+
+ModalContainerObserver::ModalContainerObserver() = default;
+ModalContainerObserver::~ModalContainerObserver() = default;
+
+static bool matchesSearchTerm(const Text& textNode, const AtomString& searchTerm)
+{
+ RefPtr parent = textNode.parentElementInComposedTree();
+ bool shouldSearchNode = ([&] {
+ if (!is<HTMLElement>(parent.get()))
+ return false;
+
+ return parent->hasTagName(HTMLNames::aTag) || parent->hasTagName(HTMLNames::divTag) || parent->hasTagName(HTMLNames::pTag) || parent->hasTagName(HTMLNames::spanTag) || parent->hasTagName(HTMLNames::sectionTag);
+ })();
+
+ if (!shouldSearchNode)
+ return false;
+
+ if (LIKELY(!textNode.data().containsIgnoringASCIICase(searchTerm)))
+ return false;
+
+ return true;
+}
+
+void ModalContainerObserver::updateModalContainerIfNeeded(const FrameView& view)
+{
+ if (m_container)
+ return;
+
+ if (!view.hasViewportConstrainedObjects())
+ return;
+
+ auto* page = view.frame().page();
+ if (!page)
+ return;
+
+ auto& searchTerm = page->chrome().client().searchStringForModalContainerObserver();
+ if (searchTerm.isNull())
+ return;
+
+ for (auto& renderer : *view.viewportConstrainedObjects()) {
+ RefPtr element = renderer.element();
+ if (!element || is<HTMLBodyElement>(*element) || element->isDocumentNode())
+ continue;
+
+ if (!m_elementsToIgnoreWhenSearching.add(*element).isNewEntry)
+ continue;
+
+ for (auto& textRenderer : descendantsOfType<RenderText>(renderer)) {
+ if (RefPtr textNode = textRenderer.textNode(); textNode && matchesSearchTerm(*textNode, searchTerm)) {
+ m_container = element.get();
+ return;
+ }
+ }
+ }
+}
+
+} // namespace WebCore
Added: trunk/Source/WebCore/page/ModalContainerObserver.h (0 => 287217)
--- trunk/Source/WebCore/page/ModalContainerObserver.h (rev 0)
+++ trunk/Source/WebCore/page/ModalContainerObserver.h 2021-12-18 03:06:39 UTC (rev 287217)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/FastMalloc.h>
+#include <wtf/WeakHashSet.h>
+#include <wtf/WeakPtr.h>
+
+namespace WebCore {
+
+class Document;
+class Element;
+class FrameView;
+
+class ModalContainerObserver {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ static bool isNeededFor(const Document&);
+
+ ModalContainerObserver();
+ ~ModalContainerObserver();
+
+ void updateModalContainerIfNeeded(const FrameView&);
+
+private:
+ WeakHashSet<Element> m_elementsToIgnoreWhenSearching;
+ WeakPtr<Element> m_container;
+};
+
+} // namespace WebCore
Modified: trunk/Source/WebKit/ChangeLog (287216 => 287217)
--- trunk/Source/WebKit/ChangeLog 2021-12-18 02:30:09 UTC (rev 287216)
+++ trunk/Source/WebKit/ChangeLog 2021-12-18 03:06:39 UTC (rev 287217)
@@ -1,3 +1,16 @@
+2021-12-17 Wenson Hsieh <wenson_hs...@apple.com>
+
+ Add support for detecting modal containers that contain a given search term
+ https://bugs.webkit.org/show_bug.cgi?id=234214
+
+ Reviewed by Tim Horton and Devin Rousso.
+
+ Add a WebKitAdditions hook that implements a new chrome client method. See WebCore/ChangeLog for more details.
+
+ * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+ (WebKit::WebChromeClient::searchStringForModalContainerObserver const):
+ * WebProcess/WebCoreSupport/WebChromeClient.h:
+
2021-12-17 Alex Christensen <achristen...@webkit.org>
Remove API::Object::Type::BundlePageGroup
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp (287216 => 287217)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp 2021-12-18 02:30:09 UTC (rev 287216)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp 2021-12-18 03:06:39 UTC (rev 287217)
@@ -1568,4 +1568,13 @@
m_page.sendWithAsyncReply(Messages::WebPageProxy::RequestCookieConsent(), WTFMove(completion));
}
+#if USE(APPLE_INTERNAL_SDK)
+#include <WebKitAdditions/WebChromeClientAdditions.cpp>
+#else
+const AtomString& WebChromeClient::searchStringForModalContainerObserver() const
+{
+ return nullAtom();
+}
+#endif
+
} // namespace WebKit
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h (287216 => 287217)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h 2021-12-18 02:30:09 UTC (rev 287216)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h 2021-12-18 03:06:39 UTC (rev 287217)
@@ -466,6 +466,8 @@
void requestCookieConsent(CompletionHandler<void(WebCore::CookieConsentDecisionResult)>&&) final;
+ const AtomString& searchStringForModalContainerObserver() const final;
+
mutable bool m_cachedMainFrameHasHorizontalScrollbar { false };
mutable bool m_cachedMainFrameHasVerticalScrollbar { false };