WKWebView's frames accessor should return a traversable type
authorachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Mar 2020 20:35:46 +0000 (20:35 +0000)
committerachristensen@apple.com <achristensen@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Mar 2020 20:35:46 +0000 (20:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=208591

Reviewed by Brady Eidson.

Source/WebKit:

Rather than return an array of information that can technically be used to reconstruct a tree,
let's just return the root of a tree. This introduces _WKFrameTreeNode which inherits from WKFrameInfo.
Covered by API tests.

* Shared/API/APIObject.h:
* Shared/Cocoa/APIObject.mm:
(API::Object::newObject):
* Shared/FrameInfoData.cpp:
(WebKit::FrameInfoData::encode const):
(WebKit::FrameInfoData::decode):
* Shared/FrameInfoData.h:
* Shared/FrameTreeNodeData.h: Added.
(WebKit::FrameTreeNodeData::encode const):
(WebKit::FrameTreeNodeData::decode):
* Sources.txt:
* SourcesCocoa.txt:
* UIProcess/API/APIFrameInfo.cpp:
(API::FrameInfo::parentFrameHandle const): Deleted.
(API::FrameInfo::childFrameHandles const): Deleted.
* UIProcess/API/APIFrameInfo.h:
* UIProcess/API/APIFrameTreeNode.cpp: Added.
(API::FrameTreeNode::handle const):
* UIProcess/API/APIFrameTreeNode.h: Added.
* UIProcess/API/Cocoa/WKFrameInfo.mm:
(-[WKFrameInfo _parentFrameHandle]): Deleted.
(-[WKFrameInfo _childFrameHandles]): Deleted.
* UIProcess/API/Cocoa/WKFrameInfoPrivate.h:
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _frames:]):
(-[WKWebView _allFrames:]): Deleted.
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/API/Cocoa/_WKFrameTreeNode.h: Added.
* UIProcess/API/Cocoa/_WKFrameTreeNode.mm: Added.
(-[_WKFrameTreeNode dealloc]):
(-[_WKFrameTreeNode isMainFrame]):
(-[_WKFrameTreeNode request]):
(-[_WKFrameTreeNode securityOrigin]):
(-[_WKFrameTreeNode webView]):
(-[_WKFrameTreeNode childFrames]):
(-[_WKFrameTreeNode copyWithZone:]):
(-[_WKFrameTreeNode _handle]):
(-[_WKFrameTreeNode _apiObject]):
* UIProcess/API/Cocoa/_WKFrameTreeNodeInternal.h: Added.
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::getAllFrames):
* UIProcess/WebPageProxy.h:
* WebKit.xcodeproj/project.pbxproj:
* WebProcess/Geolocation/GeolocationPermissionRequestManager.cpp:
* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):
* WebProcess/WebPage/WebFrame.cpp:
(WebKit::WebFrame::info const):
(WebKit::WebFrame::childFrameIDs const): Deleted.
* WebProcess/WebPage/WebFrame.h:
(WebKit::WebFrame::frameID const):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::frameTreeNodeData):
(WebKit::WebPage::getAllFrames):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm:

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

31 files changed:
Source/WebKit/ChangeLog
Source/WebKit/Shared/API/APIObject.h
Source/WebKit/Shared/Cocoa/APIObject.mm
Source/WebKit/Shared/FrameInfoData.cpp
Source/WebKit/Shared/FrameInfoData.h
Source/WebKit/Shared/FrameTreeNodeData.h [new file with mode: 0644]
Source/WebKit/Sources.txt
Source/WebKit/SourcesCocoa.txt
Source/WebKit/UIProcess/API/APIFrameInfo.cpp
Source/WebKit/UIProcess/API/APIFrameInfo.h
Source/WebKit/UIProcess/API/APIFrameTreeNode.cpp [new file with mode: 0644]
Source/WebKit/UIProcess/API/APIFrameTreeNode.h [new file with mode: 0644]
Source/WebKit/UIProcess/API/Cocoa/WKFrameInfo.mm
Source/WebKit/UIProcess/API/Cocoa/WKFrameInfoPrivate.h
Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h
Source/WebKit/UIProcess/API/Cocoa/_WKFrameTreeNode.h [new file with mode: 0644]
Source/WebKit/UIProcess/API/Cocoa/_WKFrameTreeNode.mm [new file with mode: 0644]
Source/WebKit/UIProcess/API/Cocoa/_WKFrameTreeNodeInternal.h [new file with mode: 0644]
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/WebKit.xcodeproj/project.pbxproj
Source/WebKit/WebProcess/Geolocation/GeolocationPermissionRequestManager.cpp
Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
Source/WebKit/WebProcess/WebPage/WebFrame.cpp
Source/WebKit/WebProcess/WebPage/WebFrame.h
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKit/WebProcess/WebPage/WebPage.h
Source/WebKit/WebProcess/WebPage/WebPage.messages.in
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm

index 8ccf3f4..1479d57 100644 (file)
@@ -1,3 +1,71 @@
+2020-03-04  Alex Christensen  <achristensen@webkit.org>
+
+        WKWebView's frames accessor should return a traversable type
+        https://bugs.webkit.org/show_bug.cgi?id=208591
+
+        Reviewed by Brady Eidson.
+
+        Rather than return an array of information that can technically be used to reconstruct a tree,
+        let's just return the root of a tree. This introduces _WKFrameTreeNode which inherits from WKFrameInfo.
+        Covered by API tests.
+
+        * Shared/API/APIObject.h:
+        * Shared/Cocoa/APIObject.mm:
+        (API::Object::newObject):
+        * Shared/FrameInfoData.cpp:
+        (WebKit::FrameInfoData::encode const):
+        (WebKit::FrameInfoData::decode):
+        * Shared/FrameInfoData.h:
+        * Shared/FrameTreeNodeData.h: Added.
+        (WebKit::FrameTreeNodeData::encode const):
+        (WebKit::FrameTreeNodeData::decode):
+        * Sources.txt:
+        * SourcesCocoa.txt:
+        * UIProcess/API/APIFrameInfo.cpp:
+        (API::FrameInfo::parentFrameHandle const): Deleted.
+        (API::FrameInfo::childFrameHandles const): Deleted.
+        * UIProcess/API/APIFrameInfo.h:
+        * UIProcess/API/APIFrameTreeNode.cpp: Added.
+        (API::FrameTreeNode::handle const):
+        * UIProcess/API/APIFrameTreeNode.h: Added.
+        * UIProcess/API/Cocoa/WKFrameInfo.mm:
+        (-[WKFrameInfo _parentFrameHandle]): Deleted.
+        (-[WKFrameInfo _childFrameHandles]): Deleted.
+        * UIProcess/API/Cocoa/WKFrameInfoPrivate.h:
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _frames:]):
+        (-[WKWebView _allFrames:]): Deleted.
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/API/Cocoa/_WKFrameTreeNode.h: Added.
+        * UIProcess/API/Cocoa/_WKFrameTreeNode.mm: Added.
+        (-[_WKFrameTreeNode dealloc]):
+        (-[_WKFrameTreeNode isMainFrame]):
+        (-[_WKFrameTreeNode request]):
+        (-[_WKFrameTreeNode securityOrigin]):
+        (-[_WKFrameTreeNode webView]):
+        (-[_WKFrameTreeNode childFrames]):
+        (-[_WKFrameTreeNode copyWithZone:]):
+        (-[_WKFrameTreeNode _handle]):
+        (-[_WKFrameTreeNode _apiObject]):
+        * UIProcess/API/Cocoa/_WKFrameTreeNodeInternal.h: Added.
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::getAllFrames):
+        * UIProcess/WebPageProxy.h:
+        * WebKit.xcodeproj/project.pbxproj:
+        * WebProcess/Geolocation/GeolocationPermissionRequestManager.cpp:
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+        (WebKit::WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction):
+        * WebProcess/WebPage/WebFrame.cpp:
+        (WebKit::WebFrame::info const):
+        (WebKit::WebFrame::childFrameIDs const): Deleted.
+        * WebProcess/WebPage/WebFrame.h:
+        (WebKit::WebFrame::frameID const):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::frameTreeNodeData):
+        (WebKit::WebPage::getAllFrames):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+
 2020-03-04  Antoine Quint  <graouts@apple.com>
 
         Add an SPI to allow UserStyleSheet injection to target a specific WKWebView
index 27b7e3a..4a68dff 100644 (file)
@@ -125,6 +125,7 @@ public:
         Frame,
         FrameInfo,
         FramePolicyListener,
+        FrameTreeNode,
         FullScreenManager,
         GeolocationManager,
         GeolocationPermissionRequest,
index b05f7cb..b9d11da 100644 (file)
@@ -76,6 +76,7 @@
 #import "_WKDownloadInternal.h"
 #import "_WKExperimentalFeatureInternal.h"
 #import "_WKFrameHandleInternal.h"
+#import "_WKFrameTreeNodeInternal.h"
 #import "_WKGeolocationPositionInternal.h"
 #import "_WKHitTestResultInternal.h"
 #import "_WKInspectorDebuggableInfoInternal.h"
@@ -241,6 +242,9 @@ void* Object::newObject(size_t size, Type type)
         wrapper = [WKFrameInfo alloc];
         break;
 
+    case Type::FrameTreeNode:
+        wrapper = [_WKFrameTreeNode alloc];
+        break;
 #if PLATFORM(IOS_FAMILY)
     case Type::GeolocationPosition:
         wrapper = [_WKGeolocationPosition alloc];
index cdc4745..47809c5 100644 (file)
@@ -36,8 +36,6 @@ void FrameInfoData::encode(IPC::Encoder& encoder) const
     encoder << request;
     encoder << securityOrigin;
     encoder << frameID;
-    encoder << parentFrameID;
-    encoder << childFrameIDs;
 }
 
 Optional<FrameInfoData> FrameInfoData::decode(IPC::Decoder& decoder)
@@ -62,23 +60,11 @@ Optional<FrameInfoData> FrameInfoData::decode(IPC::Decoder& decoder)
     if (!frameID)
         return WTF::nullopt;
 
-    Optional<Optional<WebCore::FrameIdentifier>> parentFrameID;
-    decoder >> parentFrameID;
-    if (!frameID)
-        return WTF::nullopt;
-
-    Optional<Vector<WebCore::FrameIdentifier>> childFrameIDs;
-    decoder >> childFrameIDs;
-    if (!frameID)
-        return WTF::nullopt;
-
     return {{
         WTFMove(*isMainFrame),
         WTFMove(*request),
         WTFMove(*securityOrigin),
-        WTFMove(*frameID),
-        WTFMove(*parentFrameID),
-        WTFMove(*childFrameIDs)
+        WTFMove(*frameID)
     }};
 }
 
index ee11a3f..8923a18 100644 (file)
@@ -44,8 +44,6 @@ struct FrameInfoData {
     WebCore::ResourceRequest request;
     WebCore::SecurityOriginData securityOrigin;
     Optional<WebCore::FrameIdentifier> frameID;
-    Optional<WebCore::FrameIdentifier> parentFrameID;
-    Vector<WebCore::FrameIdentifier> childFrameIDs;
 };
 
 }
diff --git a/Source/WebKit/Shared/FrameTreeNodeData.h b/Source/WebKit/Shared/FrameTreeNodeData.h
new file mode 100644 (file)
index 0000000..44636d2
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2020 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
+
+#import "ArgumentCoders.h"
+#import "FrameInfoData.h"
+
+namespace WebKit {
+
+struct FrameTreeNodeData {
+
+    FrameInfoData info;
+    Vector<FrameTreeNodeData> children;
+
+    void encode(IPC::Encoder& encoder) const
+    {
+        encoder << info;
+        encoder << children;
+    }
+
+    static Optional<FrameTreeNodeData> decode(IPC::Decoder& decoder)
+    {
+        Optional<FrameInfoData> info;
+        decoder >> info;
+        if (!info)
+            return WTF::nullopt;
+        
+        Optional<Vector<FrameTreeNodeData>> children;
+        decoder >> children;
+        if (!children)
+            return WTF::nullopt;
+        
+        return {{
+            WTFMove(*info),
+            WTFMove(*children)
+        }};
+    }
+};
+
+}
index 6d0e8c6..0fba549 100644 (file)
@@ -334,6 +334,7 @@ UIProcess/API/APIContextMenuElementInfo.cpp
 UIProcess/API/APIDebuggableInfo.cpp
 UIProcess/API/APIExperimentalFeature.cpp
 UIProcess/API/APIFrameInfo.cpp
+UIProcess/API/APIFrameTreeNode.cpp
 UIProcess/API/APIHTTPCookieStore.cpp
 UIProcess/API/APIHitTestResult.cpp
 UIProcess/API/APIInternalDebugFeature.cpp
index 25cba97..9269b0a 100644 (file)
@@ -255,6 +255,7 @@ UIProcess/API/Cocoa/_WKDownload.mm
 UIProcess/API/Cocoa/_WKElementAction.mm
 UIProcess/API/Cocoa/_WKErrorRecoveryAttempting.mm
 UIProcess/API/Cocoa/_WKExperimentalFeature.mm
+UIProcess/API/Cocoa/_WKFrameTreeNode.mm
 UIProcess/API/Cocoa/_WKGeolocationPosition.mm
 UIProcess/API/Cocoa/_WKInspector.mm
 UIProcess/API/Cocoa/_WKInspectorDebuggableInfo.mm
index 815ad94..d8ba613 100644 (file)
@@ -49,20 +49,4 @@ Ref<FrameHandle> FrameInfo::handle() const
     return FrameHandle::create(m_data.frameID ? *m_data.frameID : WebCore::FrameIdentifier { });
 }
 
-RefPtr<FrameHandle> FrameInfo::parentFrameHandle() const
-{
-    if (!m_data.parentFrameID)
-        return nullptr;
-    return FrameHandle::create(*m_data.parentFrameID);
-}
-
-Vector<Ref<FrameHandle>> FrameInfo::childFrameHandles() const
-{
-    Vector<Ref<FrameHandle>> handles;
-    handles.reserveInitialCapacity(m_data.childFrameIDs.size());
-    for (auto& childFrameID : m_data.childFrameIDs)
-        handles.uncheckedAppend(FrameHandle::create(childFrameID));
-    return handles;
-}
-
 } // namespace API
index 5628f10..a88dc68 100644 (file)
@@ -53,8 +53,6 @@ public:
     const WebCore::ResourceRequest& request() const { return m_data.request; }
     WebCore::SecurityOriginData& securityOrigin() { return m_data.securityOrigin; }
     Ref<FrameHandle> handle() const;
-    RefPtr<FrameHandle> parentFrameHandle() const;
-    Vector<Ref<FrameHandle>> childFrameHandles() const;
     WebKit::WebPageProxy* page() { return m_page.get(); }
 
 private:
diff --git a/Source/WebKit/UIProcess/API/APIFrameTreeNode.cpp b/Source/WebKit/UIProcess/API/APIFrameTreeNode.cpp
new file mode 100644 (file)
index 0000000..d731194
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2020 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 "APIFrameTreeNode.h"
+
+#include "APIFrameHandle.h"
+#include "WebPageProxy.h"
+
+namespace API {
+
+FrameTreeNode::~FrameTreeNode() = default;
+
+Ref<FrameHandle> FrameTreeNode::handle() const
+{
+    return FrameHandle::create(m_data.info.frameID ? *m_data.info.frameID : WebCore::FrameIdentifier { });
+}
+
+} // namespace API
diff --git a/Source/WebKit/UIProcess/API/APIFrameTreeNode.h b/Source/WebKit/UIProcess/API/APIFrameTreeNode.h
new file mode 100644 (file)
index 0000000..9d6598d
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2020 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 "APIObject.h"
+#include "FrameTreeNodeData.h"
+
+namespace WebKit {
+class WebPageProxy;
+}
+
+namespace API {
+
+class FrameHandle;
+
+class FrameTreeNode final : public ObjectImpl<Object::Type::FrameTreeNode> {
+public:
+    static Ref<FrameTreeNode> create(WebKit::FrameTreeNodeData&& data, WebKit::WebPageProxy& page) { return adoptRef(*new FrameTreeNode(WTFMove(data), page)); }
+    virtual ~FrameTreeNode();
+
+    WebKit::WebPageProxy& page() { return m_page.get(); }
+    bool isMainFrame() const { return m_data.info.isMainFrame; }
+    const WebCore::ResourceRequest& request() const { return m_data.info.request; }
+    const WebCore::SecurityOriginData& securityOrigin() const { return m_data.info.securityOrigin; }
+    const Vector<WebKit::FrameTreeNodeData>& childFrames() const { return m_data.children; }
+    Ref<FrameHandle> handle() const;
+
+private:
+    FrameTreeNode(WebKit::FrameTreeNodeData&& data, WebKit::WebPageProxy& page)
+        : m_data(WTFMove(data))
+        , m_page(page) { }
+
+    WebKit::FrameTreeNodeData m_data;
+    Ref<WebKit::WebPageProxy> m_page;
+};
+
+} // namespace API
index 4316618..87dfd66 100644 (file)
     return [[wrapper(_frameInfo->handle()) retain] autorelease];
 }
 
-- (_WKFrameHandle *)_parentFrameHandle
-{
-    return [[wrapper(_frameInfo->parentFrameHandle()) retain] autorelease];
-}
-
-- (NSArray<_WKFrameHandle *> *)_childFrameHandles
-{
-    const auto& handles = _frameInfo->childFrameHandles();
-    if (!handles.size())
-        return nil;
-    NSMutableArray<_WKFrameHandle *> *set = [NSMutableArray arrayWithCapacity:handles.size()];
-    for (auto& handle : handles)
-        [set addObject:wrapper(handle.get())];
-    return set;
-}
-
 @end
index b49f526..654add7 100644 (file)
@@ -30,7 +30,5 @@
 @interface WKFrameInfo (WKPrivate)
 
 @property (nonatomic, readonly, copy, nonnull) _WKFrameHandle *_handle WK_API_AVAILABLE(macos(10.12), ios(10.0));
-@property (nonatomic, readonly, copy, nullable) _WKFrameHandle *_parentFrameHandle WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
-@property (nonatomic, readonly, copy, nullable) NSArray<_WKFrameHandle *> *_childFrameHandles WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 @end
index 727db2f..7490bfe 100644 (file)
@@ -27,6 +27,7 @@
 #import "WKWebViewInternal.h"
 
 #import "APIFormClient.h"
+#import "APIFrameTreeNode.h"
 #import "APIPageConfiguration.h"
 #import "APISerializedScriptValue.h"
 #import "AttributedString.h"
@@ -97,6 +98,7 @@
 #import "_WKDiagnosticLoggingDelegate.h"
 #import "_WKFindDelegate.h"
 #import "_WKFrameHandleInternal.h"
+#import "_WKFrameTreeNodeInternal.h"
 #import "_WKFullscreenDelegate.h"
 #import "_WKHitTestResultInternal.h"
 #import "_WKInputDelegate.h"
@@ -1582,13 +1584,11 @@ FOR_EACH_PRIVATE_WKCONTENTVIEW_ACTION(FORWARD_ACTION_TO_WKCONTENTVIEW)
     return _page->pageLoadState().hasNegotiatedLegacyTLS();
 }
 
-- (void)_allFrames:(void (^)(NSArray<WKFrameInfo *> *))completionHandler
+- (void)_frames:(void (^)(_WKFrameTreeNode *))completionHandler
 {
-    _page->getAllFrames([completionHandler = makeBlockPtr(completionHandler), page = makeRefPtr(_page.get())] (Vector<WebKit::FrameInfoData>&& frames) {
-        NSMutableArray<WKFrameInfo *> *apiFrames = [NSMutableArray arrayWithCapacity:frames.size()];
-        for (auto& frame : WTFMove(frames))
-            [apiFrames addObject:wrapper(API::FrameInfo::create(WTFMove(frame), page.get()))];
-        completionHandler(apiFrames);
+    _page->getAllFrames([completionHandler = makeBlockPtr(completionHandler), page = makeRef(*_page.get())] (WebKit::FrameTreeNodeData&& data) {
+        _WKFrameTreeNode *node = [[wrapper(API::FrameTreeNode::create(WTFMove(data), page.get())) retain] autorelease];
+        completionHandler(node);
     });
 }
 
index bb40206..3127225 100644 (file)
@@ -105,9 +105,9 @@ typedef NS_OPTIONS(NSUInteger, _WKRectEdge) {
 
 @class WKBrowsingContextHandle;
 @class WKWebpagePreferences;
-@class WKFrameInfo;
 @class _WKApplicationManifest;
 @class _WKFrameHandle;
+@class _WKFrameTreeNode;
 @class _WKHitTestResult;
 @class _WKInspector;
 @class _WKRemoteObjectRegistry;
@@ -172,7 +172,7 @@ for this property.
 */
 @property (nonatomic, readonly) BOOL _negotiatedLegacyTLS WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 
-- (void)_allFrames:(void (^)(NSArray<WKFrameInfo *> *))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+- (void)_frames:(void (^)(_WKFrameTreeNode *))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 // FIXME: Remove these once nobody is using them.
 @property (nonatomic, readonly) NSData *_sessionStateData;
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKFrameTreeNode.h b/Source/WebKit/UIProcess/API/Cocoa/_WKFrameTreeNode.h
new file mode 100644 (file)
index 0000000..cdc6cb4
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#import <Foundation/Foundation.h>
+#import <WebKit/WKFoundation.h>
+#import <WebKit/WKFrameInfo.h>
+
+WK_CLASS_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA))
+@interface _WKFrameTreeNode : WKFrameInfo
+
++ (instancetype)new NS_UNAVAILABLE;
+- (instancetype)init NS_UNAVAILABLE;
+
+@property (nonatomic, readonly) NSArray<_WKFrameTreeNode *> *childFrames;
+
+@end
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKFrameTreeNode.mm b/Source/WebKit/UIProcess/API/Cocoa/_WKFrameTreeNode.mm
new file mode 100644 (file)
index 0000000..7322bd6
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#import "config.h"
+
+#import "WKSecurityOriginInternal.h"
+#import "WKWebViewInternal.h"
+#import "_WKFrameHandleInternal.h"
+#import "_WKFrameTreeNodeInternal.h"
+
+@implementation _WKFrameTreeNode
+
+- (void)dealloc
+{
+    _node->API::FrameTreeNode::~FrameTreeNode();
+    [super dealloc];
+}
+
+- (BOOL)isMainFrame
+{
+    return _node->isMainFrame();
+}
+
+- (NSURLRequest *)request
+{
+    return _node->request().nsURLRequest(WebCore::HTTPBodyUpdatePolicy::DoNotUpdateHTTPBody);
+}
+
+- (WKSecurityOrigin *)securityOrigin
+{
+    auto& data = _node->securityOrigin();
+    auto apiOrigin = API::SecurityOrigin::create(data.protocol, data.host, data.port);
+    return [[wrapper(apiOrigin.get()) retain] autorelease];
+}
+
+- (WKWebView *)webView
+{
+    return [[fromWebPageProxy(_node->page()) retain] autorelease];
+}
+
+- (NSArray<_WKFrameTreeNode *> *)childFrames
+{
+    const auto& children = _node->childFrames();
+    NSMutableArray<_WKFrameTreeNode *> *array = [NSMutableArray arrayWithCapacity:children.size()];
+    for (const auto& child : children)
+        [array addObject:wrapper(API::FrameTreeNode::create(WebKit::FrameTreeNodeData(child), _node->page()))];
+    return array;
+}
+
+- (id)copyWithZone:(NSZone *)zone
+{
+    return [self retain];
+}
+
+- (_WKFrameHandle *)_handle
+{
+    return [[wrapper(_node->handle()) retain] autorelease];
+}
+
+- (API::Object&)_apiObject
+{
+    return *_node;
+}
+
+@end
diff --git a/Source/WebKit/UIProcess/API/Cocoa/_WKFrameTreeNodeInternal.h b/Source/WebKit/UIProcess/API/Cocoa/_WKFrameTreeNodeInternal.h
new file mode 100644 (file)
index 0000000..6e532d8
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#import "APIFrameTreeNode.h"
+#import "WKObject.h"
+#import "_WKFrameTreeNode.h"
+
+namespace WebKit {
+
+template<> struct WrapperTraits<API::FrameTreeNode> {
+    using WrapperClass = _WKFrameTreeNode;
+};
+
+}
+
+@interface _WKFrameTreeNode () <WKObject> {
+@package
+    API::ObjectStorage<API::FrameTreeNode> _node;
+}
+@end
index a0425bd..c0e0e23 100644 (file)
@@ -4051,7 +4051,7 @@ void WebPageProxy::getContentsAsAttributedString(CompletionHandler<void(const At
 }
 #endif
 
-void WebPageProxy::getAllFrames(CompletionHandler<void(Vector<FrameInfoData>&&)>&& completionHandler)
+void WebPageProxy::getAllFrames(CompletionHandler<void(FrameTreeNodeData&&)>&& completionHandler)
 {
     sendWithAsyncReply(Messages::WebPage::GetAllFrames(), WTFMove(completionHandler));
 }
index 8f21734..87984c9 100644 (file)
@@ -321,6 +321,7 @@ struct DocumentEditingContext;
 struct DocumentEditingContextRequest;
 struct EditingRange;
 struct EditorState;
+struct FrameTreeNodeData;
 struct FocusedElementInformation;
 struct FontInfo;
 struct FrameInfoData;
@@ -504,7 +505,7 @@ public:
     void destroyInspectorTarget(const String& targetId);
     void sendMessageToInspectorFrontend(const String& targetId, const String& message);
 
-    void getAllFrames(CompletionHandler<void(Vector<FrameInfoData>&&)>&&);
+    void getAllFrames(CompletionHandler<void(FrameTreeNodeData&&)>&&);
 
 #if ENABLE(REMOTE_INSPECTOR)
     void setIndicating(bool);
index d531313..e89de69 100644 (file)
                58E977DF21C49A00005D92A6 /* NetworkHTTPSUpgradeChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 58E977DD21C49A00005D92A6 /* NetworkHTTPSUpgradeChecker.h */; };
                5C0B17781E7C880E00E9123C /* NetworkSocketStreamMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C0B17741E7C879C00E9123C /* NetworkSocketStreamMessageReceiver.cpp */; };
                5C0B17791E7C882100E9123C /* WebSocketStreamMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C0B17761E7C879C00E9123C /* WebSocketStreamMessageReceiver.cpp */; };
+               5C121E842410208D00486F9B /* FrameTreeNodeData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C121E8324101F7000486F9B /* FrameTreeNodeData.h */; };
+               5C121E89241029C900486F9B /* _WKFrameTreeNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C121E882410290D00486F9B /* _WKFrameTreeNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
                5C1426ED1C23F80900D41183 /* NetworkProcessCreationParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C1426E31C23F80500D41183 /* NetworkProcessCreationParameters.h */; };
                5C1426EE1C23F80900D41183 /* NetworkProcessSupplement.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C1426E41C23F80500D41183 /* NetworkProcessSupplement.h */; };
                5C1426F01C23F80900D41183 /* NetworkResourceLoadParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C1426E61C23F80500D41183 /* NetworkResourceLoadParameters.h */; };
                5C0B177E1E7C886700E9123C /* NetworkSocketStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkSocketStream.h; sourceTree = "<group>"; };
                5C0B177F1E7C886700E9123C /* NetworkSocketStream.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = NetworkSocketStream.messages.in; sourceTree = "<group>"; };
                5C0B17801E7C888000E9123C /* WebSocketStream.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = WebSocketStream.messages.in; path = Network/WebSocketStream.messages.in; sourceTree = "<group>"; };
+               5C121E8324101F7000486F9B /* FrameTreeNodeData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FrameTreeNodeData.h; sourceTree = "<group>"; };
+               5C121E852410276F00486F9B /* APIFrameTreeNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIFrameTreeNode.h; sourceTree = "<group>"; };
+               5C121E862410290D00486F9B /* _WKFrameTreeNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKFrameTreeNode.mm; sourceTree = "<group>"; };
+               5C121E872410290D00486F9B /* _WKFrameTreeNodeInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKFrameTreeNodeInternal.h; sourceTree = "<group>"; };
+               5C121E882410290D00486F9B /* _WKFrameTreeNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKFrameTreeNode.h; sourceTree = "<group>"; };
+               5C121E8B2410306600486F9B /* APIFrameTreeNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = APIFrameTreeNode.cpp; sourceTree = "<group>"; };
                5C13024A1FE341A7000D9B31 /* WebsitePoliciesData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebsitePoliciesData.h; sourceTree = "<group>"; };
                5C1426E21C23F80500D41183 /* NetworkProcessCreationParameters.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkProcessCreationParameters.cpp; sourceTree = "<group>"; };
                5C1426E31C23F80500D41183 /* NetworkProcessCreationParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkProcessCreationParameters.h; sourceTree = "<group>"; };
                                BCE81D8B1319F7EF00241910 /* FontInfo.h */,
                                1A14F8DF1D74C834006CBEC6 /* FrameInfoData.cpp */,
                                1A14F8E01D74C834006CBEC6 /* FrameInfoData.h */,
+                               5C121E8324101F7000486F9B /* FrameTreeNodeData.h */,
                                1AC75A1A1B3368270056745B /* HangDetectionDisabler.h */,
                                BCCF6B2312C93E7A008F9C35 /* ImageOptions.h */,
                                1A92DC1212F8BAB90017AF65 /* LayerTreeContext.cpp */,
                                2DEAC5CE1AC368BB00A195D8 /* _WKFindOptions.h */,
                                2E7A94491BBD95C600945547 /* _WKFocusedElementInfo.h */,
                                37A64E5618F38F4600EB30F1 /* _WKFormInputSession.h */,
+                               5C121E882410290D00486F9B /* _WKFrameTreeNode.h */,
+                               5C121E862410290D00486F9B /* _WKFrameTreeNode.mm */,
+                               5C121E872410290D00486F9B /* _WKFrameTreeNodeInternal.h */,
                                CD78E1181DB7E5AD0014A2DE /* _WKFullscreenDelegate.h */,
                                63FABE191E970D65003011D5 /* _WKGeolocationCoreLocationProvider.h */,
                                63C32C241E9810D900699BD0 /* _WKGeolocationPosition.h */,
                                37E25D6D18FDE5D6005D3A00 /* APIFormClient.h */,
                                2DF9EEE31A781FB400B6CFBE /* APIFrameInfo.cpp */,
                                2DF9EEE41A781FB400B6CFBE /* APIFrameInfo.h */,
+                               5C121E8B2410306600486F9B /* APIFrameTreeNode.cpp */,
+                               5C121E852410276F00486F9B /* APIFrameTreeNode.h */,
                                CD78E1161DB7DC0A0014A2DE /* APIFullscreenClient.h */,
                                7AB6EA461EEAB6B000037B2B /* APIGeolocationProvider.h */,
                                2DABA7751A82B42100EF0F1A /* APIHistoryClient.h */,
                                37A64E5718F38F4600EB30F1 /* _WKFormInputSession.h in Headers */,
                                373D122318A473010066D9CC /* _WKFrameHandle.h in Headers */,
                                373D122718A473F60066D9CC /* _WKFrameHandleInternal.h in Headers */,
+                               5C121E89241029C900486F9B /* _WKFrameTreeNode.h in Headers */,
                                CD78E1191DB7E5AD0014A2DE /* _WKFullscreenDelegate.h in Headers */,
                                636353A51E9858DF0009F8AF /* _WKGeolocationCoreLocationProvider.h in Headers */,
                                63C32C261E9810D900699BD0 /* _WKGeolocationPosition.h in Headers */,
                                BCE81D8D1319F7EF00241910 /* FontInfo.h in Headers */,
                                1A14F8E21D74C834006CBEC6 /* FrameInfoData.h in Headers */,
                                1AE00D611831792100087DD7 /* FrameLoadState.h in Headers */,
+                               5C121E842410208D00486F9B /* FrameTreeNodeData.h in Headers */,
                                2D4AF0892044C3C4006C8817 /* FrontBoardServicesSPI.h in Headers */,
                                CD78E1151DB7D7ED0014A2DE /* FullscreenClient.h in Headers */,
                                CD19D2EA2046406F0017074A /* FullscreenTouchSecheuristic.h in Headers */,
index 174be71..d4cd885 100644 (file)
@@ -944,22 +944,14 @@ void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const Navigat
 
     auto* requestingFrame = requester.frameID() ? WebProcess::singleton().webFrame(requester.frameID()) : nullptr;
     Optional<WebCore::FrameIdentifier> originatingFrameID;
-    Optional<WebCore::FrameIdentifier> parentFrameID;
-    Vector<WebCore::FrameIdentifier> childFrameIDs;
-    if (requestingFrame) {
+    if (requestingFrame)
         originatingFrameID = requestingFrame->frameID();
-        childFrameIDs = requestingFrame->childFrameIDs();
-        if (auto* parentFrame = requestingFrame->parentFrame())
-            parentFrameID = parentFrame->frameID();
-    }
 
     FrameInfoData originatingFrameInfoData {
         navigationAction.initiatedByMainFrame() == InitiatedByMainFrame::Yes,
         ResourceRequest { requester.url() },
         requester.securityOrigin().data(),
-        WTFMove(originatingFrameID),
-        WTFMove(parentFrameID),
-        WTFMove(childFrameIDs)
+        WTFMove(originatingFrameID)
     };
 
     Optional<WebPageProxyIdentifier> originatingPageID;
index 4bbaf79..3d04081 100644 (file)
@@ -186,28 +186,14 @@ WebFrame* WebFrame::fromCoreFrame(const Frame& frame)
     return webFrameLoaderClient->webFrame();
 }
 
-Vector<WebCore::FrameIdentifier> WebFrame::childFrameIDs() const
-{
-    Vector<WebCore::FrameIdentifier> identifiers;
-    for (auto* childFrame = m_coreFrame->tree().firstChild(); childFrame; childFrame = childFrame->tree().nextSibling()) {
-        if (auto* childWebFrame = WebFrame::fromCoreFrame(*childFrame))
-            identifiers.append(childWebFrame->frameID());
-    }
-    return identifiers;
-};
-
 FrameInfoData WebFrame::info() const
 {
-    auto* parent = parentFrame();
-
     FrameInfoData info {
         isMainFrame(),
         // FIXME: This should use the full request.
         ResourceRequest(URL(URL(), url())),
         SecurityOriginData::fromFrame(m_coreFrame),
-        m_frameID,
-        parent ? Optional<WebCore::FrameIdentifier> { parent->frameID() } : WTF::nullopt,
-        childFrameIDs()
+        m_frameID
     };
 
     return info;
index a73dd67..363cbbc 100644 (file)
@@ -79,7 +79,6 @@ public:
 
     FrameInfoData info() const;
     WebCore::FrameIdentifier frameID() const { return m_frameID; }
-    Vector<WebCore::FrameIdentifier> childFrameIDs() const;
 
     enum class ForNavigationAction { No, Yes };
     uint64_t setUpPolicyListener(WebCore::PolicyCheckIdentifier, WebCore::FramePolicyFunction&&, ForNavigationAction);
index 011ccb6..63afe7c 100644 (file)
@@ -38,6 +38,7 @@
 #include "EventDispatcher.h"
 #include "FindController.h"
 #include "FormDataReference.h"
+#include "FrameTreeNodeData.h"
 #include "GeolocationPermissionRequestManager.h"
 #include "InjectUserScriptImmediately.h"
 #include "InjectedBundle.h"
@@ -1751,14 +1752,26 @@ WebPage& WebPage::fromCorePage(Page& page)
     return static_cast<WebChromeClient&>(page.chrome().client()).page();
 }
 
-void WebPage::getAllFrames(CompletionHandler<void(Vector<FrameInfoData>&&)>&& completionHandler)
+static Optional<FrameTreeNodeData> frameTreeNodeData(Frame& frame)
 {
-    Vector<FrameInfoData> data;
-    for (auto* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
-        if (auto* webFrame = WebFrame::fromCoreFrame(*frame))
-            data.append(webFrame->info());
+    Optional<FrameTreeNodeData> info;
+    if (auto* webFrame = WebFrame::fromCoreFrame(frame)) {
+        Vector<FrameTreeNodeData> children;
+        for (auto* childFrame = frame.tree().firstChild(); childFrame; childFrame = childFrame->tree().nextSibling()) {
+            if (auto childInfo = frameTreeNodeData(*childFrame))
+                children.append(WTFMove(*childInfo));
+        }
+        info = FrameTreeNodeData {
+            webFrame->info(),
+            WTFMove(children)
+        };
     }
-    completionHandler(WTFMove(data));
+    return info;
+}
+
+void WebPage::getAllFrames(CompletionHandler<void(FrameTreeNodeData&&)>&& completionHandler)
+{
+    completionHandler(*frameTreeNodeData(m_page->mainFrame()));
 }
 
 void WebPage::setSize(const WebCore::IntSize& viewSize)
index 5508200..a4c90f7 100644 (file)
@@ -278,6 +278,7 @@ struct DataDetectionResult;
 struct DocumentEditingContext;
 struct DocumentEditingContextRequest;
 struct EditorState;
+struct FrameTreeNodeData;
 struct FontInfo;
 struct InsertTextOptions;
 struct InteractionInformationAtPosition;
@@ -1288,7 +1289,7 @@ public:
     WebCore::AllowsContentJavaScript allowsContentJavaScriptFromMostRecentNavigation() const { return m_allowsContentJavaScriptFromMostRecentNavigation; }
     void setAllowsContentJavaScriptFromMostRecentNavigation(WebCore::AllowsContentJavaScript allows) { m_allowsContentJavaScriptFromMostRecentNavigation = allows; }
 
-    void getAllFrames(CompletionHandler<void(Vector<FrameInfoData>&&)>&&);
+    void getAllFrames(CompletionHandler<void(FrameTreeNodeData&&)>&&);
 
     void setIsNavigatingToAppBoundDomainTesting(bool, CompletionHandler<void()>&&);
     void setIsNavigatingToAppBoundDomain(NavigatingToAppBoundDomain isNavigatingToAppBoundDomain) { m_isNavigatingToAppBoundDomain = isNavigatingToAppBoundDomain; }
index 2ae1ce2..df44c32 100644 (file)
@@ -195,7 +195,7 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType
 
     # Callbacks.
     GetContentsAsString(enum:bool WebKit::ContentAsStringIncludesChildFrames inChildFrames, WebKit::CallbackID callbackID)
-    GetAllFrames() -> (Vector<WebKit::FrameInfoData> frames) Async
+    GetAllFrames() -> (struct WebKit::FrameTreeNodeData mainFrame) Async
 #if PLATFORM(COCOA)
     GetContentsAsAttributedString() -> (struct WebKit::AttributedString result) Async
 #endif
index 7eae0ff..ed6ab94 100644 (file)
@@ -1,3 +1,12 @@
+2020-03-04  Alex Christensen  <achristensen@webkit.org>
+
+        WKWebView's frames accessor should return a traversable type
+        https://bugs.webkit.org/show_bug.cgi?id=208591
+
+        Reviewed by Brady Eidson.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/WKURLSchemeHandler-1.mm:
+
 2020-03-04  Antoine Quint  <graouts@apple.com>
 
         Add an SPI to allow UserStyleSheet injection to target a specific WKWebView
index a163f3e..c81ee8f 100644 (file)
@@ -38,6 +38,7 @@
 #import <WebKit/WKWebViewConfigurationPrivate.h>
 #import <WebKit/WebKit.h>
 #import <WebKit/_WKFrameHandle.h>
+#import <WebKit/_WKFrameTreeNode.h>
 #import <wtf/BlockPtr.h>
 #import <wtf/HashMap.h>
 #import <wtf/RetainPtr.h>
@@ -1019,44 +1020,66 @@ TEST(URLSchemeHandler, Frames)
 {
     auto configuration = adoptNS([WKWebViewConfiguration new]);
     auto handler = adoptNS([TestURLSchemeHandler new]);
-    __block size_t framesLoaded = 0;
+    __block size_t grandchildFramesLoaded = 0;
     [handler setStartURLSchemeTaskHandler:^(WKWebView *, id<WKURLSchemeTask> task) {
         NSString *responseString = nil;
         if ([task.request.URL.absoluteString isEqualToString:@"frame://host1/"])
             responseString = @"<iframe src='frame://host2/'></iframe>";
         else if ([task.request.URL.absoluteString isEqualToString:@"frame://host2/"])
-            responseString = @"<iframe src='frame://host3/'></iframe><iframe src='frame://host4/'></iframe>";
+            responseString = @"<iframe src='frame://host3/' onload='fetch(\"loadedGrandchildFrame\")'></iframe><iframe src='frame://host4/' onload='fetch(\"loadedGrandchildFrame\")'></iframe>";
         else if ([task.request.URL.absoluteString isEqualToString:@"frame://host3/"])
             responseString = @"frame content";
         else if ([task.request.URL.absoluteString isEqualToString:@"frame://host4/"])
             responseString = @"frame content";
+        else if ([task.request.URL.path isEqualToString:@"/loadedGrandchildFrame"]) {
+            responseString = @"fetched content";
+            ++grandchildFramesLoaded;
+        }
 
         ASSERT(responseString);
         auto response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:responseString.length textEncodingName:nil]);
         [task didReceiveResponse:response.get()];
         [task didReceiveData:[responseString dataUsingEncoding:NSUTF8StringEncoding]];
         [task didFinish];
-        ++framesLoaded;
     }];
     [configuration setURLSchemeHandler:handler.get() forURLScheme:@"frame"];
     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
     [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"frame://host1/"]]];
 
-    while (framesLoaded < 4)
+    while (grandchildFramesLoaded < 2)
         TestWebKitAPI::Util::spinRunLoop();
     
-    [webView _allFrames:^(NSArray<WKFrameInfo *> *frames) {
-        EXPECT_EQ(frames.count, framesLoaded);
-        EXPECT_NULL(frames[0]._parentFrameHandle);
-        EXPECT_EQ(frames[0]._childFrameHandles.count, 1u);
-        EXPECT_EQ(frames[1]._parentFrameHandle.frameID, frames[0]._handle.frameID);
-        EXPECT_EQ(frames[1]._childFrameHandles.count, 2u);
-        EXPECT_EQ(frames[1]._childFrameHandles[0].frameID, frames[2]._handle.frameID);
-        EXPECT_EQ(frames[1]._childFrameHandles[1].frameID, frames[3]._handle.frameID);
-        EXPECT_EQ(frames[2]._parentFrameHandle.frameID, frames[1]._handle.frameID);
-        EXPECT_NULL(frames[2]._childFrameHandles);
-        EXPECT_EQ(frames[3]._parentFrameHandle.frameID, frames[1]._handle.frameID);
-        EXPECT_NULL(frames[3]._childFrameHandles);
+    [webView _frames:^(_WKFrameTreeNode *mainFrame) {
+        EXPECT_WK_STREQ(mainFrame.securityOrigin.host, "host1");
+        EXPECT_WK_STREQ(mainFrame.request.URL.host, "host1");
+        EXPECT_EQ(mainFrame.childFrames.count, 1u);
+        EXPECT_TRUE(mainFrame.isMainFrame);
+
+        _WKFrameTreeNode *child = mainFrame.childFrames[0];
+        EXPECT_WK_STREQ(child.request.URL.host, "host2");
+        EXPECT_WK_STREQ(child.securityOrigin.host, "host2");
+        EXPECT_EQ(child.childFrames.count, 2u);
+        EXPECT_FALSE(child.isMainFrame);
+
+        _WKFrameTreeNode *grandchild1 = child.childFrames[0];
+        EXPECT_WK_STREQ(grandchild1.request.URL.host, "host3");
+        EXPECT_WK_STREQ(grandchild1.securityOrigin.host, "host3");
+        EXPECT_EQ(grandchild1.childFrames.count, 0u);
+        EXPECT_FALSE(grandchild1.isMainFrame);
+
+        _WKFrameTreeNode *grandchild2 = child.childFrames[1];
+        EXPECT_WK_STREQ(grandchild2.request.URL.host, "host4");
+        EXPECT_WK_STREQ(grandchild2.securityOrigin.host, "host4");
+        EXPECT_EQ(grandchild2.childFrames.count, 0u);
+        EXPECT_FALSE(grandchild2.isMainFrame);
+
+        EXPECT_NE(mainFrame._handle.frameID, child._handle.frameID);
+        EXPECT_NE(mainFrame._handle.frameID, grandchild1._handle.frameID);
+        EXPECT_NE(mainFrame._handle.frameID, grandchild2._handle.frameID);
+        EXPECT_NE(child._handle.frameID, grandchild1._handle.frameID);
+        EXPECT_NE(child._handle.frameID, grandchild2._handle.frameID);
+        EXPECT_NE(grandchild1._handle.frameID, grandchild2._handle.frameID);
+
         done = true;
     }];
     TestWebKitAPI::Util::run(&done);