[webkit-changes] [WebKit/WebKit] b57715: [SwiftUI] Support download functionality

Richard Robinson noreply at github.com
Thu Jan 2 21:44:42 PST 2025


  Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: b577152034d7c8f68bf50523cc8d6f4481a80f66
      https://github.com/WebKit/WebKit/commit/b577152034d7c8f68bf50523cc8d6f4481a80f66
  Author: Richard Robinson <richard_robinson2 at apple.com>
  Date:   2025-01-02 (Thu, 02 Jan 2025)

  Changed paths:
    A Source/WebKit/UIProcess/API/Swift/DownloadCoordinator.swift
    A Source/WebKit/UIProcess/API/Swift/WKDownloadDelegateAdapter.swift
    M Source/WebKit/UIProcess/API/Swift/WKNavigationDelegateAdapter.swift
    A Source/WebKit/UIProcess/API/Swift/WebPage+Download.swift
    M Source/WebKit/UIProcess/API/Swift/WebPage+FrameInfo.swift
    M Source/WebKit/UIProcess/API/Swift/WebPage.swift
    M Source/WebKit/WebKit.xcodeproj/project.pbxproj
    M Source/WebKit/WebProcess/WebCoreSupport/WebContextMenuClient.cpp
    M Tools/SwiftBrowser/Resources/SwiftBrowser.entitlements
    M Tools/SwiftBrowser/Resources/iOS/Info.plist
    R Tools/SwiftBrowser/Source/AppStorageKeys.swift
    R Tools/SwiftBrowser/Source/BrowserView.swift
    R Tools/SwiftBrowser/Source/BrowserViewModel.swift
    R Tools/SwiftBrowser/Source/ContentView.swift
    A Tools/SwiftBrowser/Source/Extensions/URLResponse+Extras.swift
    R Tools/SwiftBrowser/Source/SettingsView.swift
    M Tools/SwiftBrowser/Source/SwiftBrowser.swift
    A Tools/SwiftBrowser/Source/ViewModel/AppStorageKeys.swift
    A Tools/SwiftBrowser/Source/ViewModel/BrowserViewModel.swift
    A Tools/SwiftBrowser/Source/ViewModel/DialogPresenter.swift
    A Tools/SwiftBrowser/Source/ViewModel/DownloadCoordinator.swift
    A Tools/SwiftBrowser/Source/ViewModel/Downloadable.swift
    A Tools/SwiftBrowser/Source/ViewModel/NavigationDecider.swift
    A Tools/SwiftBrowser/Source/Views/BrowserView.swift
    A Tools/SwiftBrowser/Source/Views/ContentView.swift
    A Tools/SwiftBrowser/Source/Views/DownloadsView.swift
    A Tools/SwiftBrowser/Source/Views/SettingsView.swift
    M Tools/SwiftBrowser/SwiftBrowser.xcodeproj/project.pbxproj

  Log Message:
  -----------
  [SwiftUI] Support download functionality
https://bugs.webkit.org/show_bug.cgi?id=285225
rdar://141109043

Reviewed by Aditya Keerthi.

In WebKit, there are several ways of initiating a download for a particular resource:

* Using the WebKit API directly to create a download using a specific `URLRequest`.

* Using the WebKit API directly to create a download using the data from a previously-cancelled download.

* A download can be created via web content before a request is sent by indicating a navigation action policy of `.download`.
This is typically used to download from a download attribute on an `<a>` tag.

* A download can be created via web content in the response after the HTTP headers have been received by indicating a navigation
response policy of `.download`. This is typically used to download a file with a 'Content-Disposition: attachment' HTTP header.

* A download can be created using one of the "Download linked file" default context menu items.

======

The new interface for creating and managing downloadable resources is described as follows:

* A download may be created or resumed by an API client using the respective functions on `WebPage`; these return an identifier
for the new download.

* In implementations of the navigation action and navigation response policy decision functions, clients can return a value of
`.download` to indicate the web content should be downloaded.

* A new protocol `DownloadCoordinator` is introduced.

* The `destination(forDownload:)` function of `DownloadCoordinator` is required to be implemented by clients so that WebKit can know
where to place the download. If this is not implemented, downloads are immediately cancelled. Downloads are also cancelled and an
exception raised if the file URL can not be created or already exists.

* The remaining functions of `DownloadCoordinator` are used to implement various policy decisions.

* WebPage now has an observable `downloads` property which is an async sequence of download events. Each download event has a
pecific kind to represent the download's progress, and an associated download value.

======

SwiftBrowser is updated to excercise this new functionality:

* Various types are refactored for better organization

* The app's sandbox is expanded to allow for access to the user's Downloads directory.

* Downloads now work as expected and download into the Downloads directory.

* A new Downloads window is added to view current downloads, with functionality to cancel ongoing downloads, and show finished downloads
in Finder.

=====

Misc:

* Remove a debug assertion that gets triggered when activating a context menu item that begins a download. While the comment above it
still holds true, the codepath will still be called regardless even though it doesn’t actually do anything, which is expected.

* Source/WebKit/UIProcess/API/Swift/DownloadCoordinator.swift: Added.
(DownloadCoordinator.destination(forDownload:response:suggestedFilename:)):
(DownloadCoordinator.authenticationChallengeDisposition(forDownload:challenge:URLCredential:)):
(DownloadCoordinator.httpRedirectionPolicy(forDownload:response:newRequest:)):
(DownloadCoordinator.placeholderPolicy(forDownload:)):
* Source/WebKit/UIProcess/API/Swift/WKDownloadDelegateAdapter.swift: Added.
(WKDownloadDelegateAdapter.owner):
(WKDownloadDelegateAdapter.downloadDidFinish(_:)):
(WKDownloadDelegateAdapter.download(_:didReceivePlaceholderURL:)):
(WKDownloadDelegateAdapter.download(_:didFailWithError:resumeData:)):
(WKDownloadDelegateAdapter.download(_:didReceiveFinalURL:)):
(WKDownloadDelegateAdapter.download(_:decideDestinationUsing:suggestedFilename:)):
(WKDownloadDelegateAdapter.download(_:willPerformHTTPRedirection:newRequest:)):
(WKDownloadDelegateAdapter.download(_:respondTo:URLCredential:)):
(WKDownloadDelegateAdapter.placeholderPolicy(forDownload:URL:)):
* Source/WebKit/UIProcess/API/Swift/WKNavigationDelegateAdapter.swift:
(WKNavigationDelegateAdapter.yieldDownloadProgress(_:download:)):
(WKNavigationDelegateAdapter.webView(_:navigationAction:didBecome:)):
(WKNavigationDelegateAdapter.webView(_:navigationResponse:didBecome:)):
* Source/WebKit/UIProcess/API/Swift/WebPage+Download.swift: Added.
(originalRequest):
(isUserInitiated):
(originatingFrame):
(progress):
(id):
(cancel):
(Downloads.makeAsyncIterator):
(Iterator.source):
(Iterator.next):
* Source/WebKit/UIProcess/API/Swift/WebPage+FrameInfo.swift:
(FrameInfo.wrapped):
* Source/WebKit/UIProcess/API/Swift/WebPage.swift:
(startDownload(using:)):
(resumeDownload(fromResumeData:)):
* Source/WebKit/WebKit.xcodeproj/project.pbxproj:
* Tools/SwiftBrowser/Resources/SwiftBrowser.entitlements:
* Tools/SwiftBrowser/Source/DownloadsView.swift: Added.
(DownloadsView.body):
* Tools/SwiftBrowser/Source/Extensions/URLResponse+Extras.swift: Copied from Source/WebKit/UIProcess/API/Swift/WebPage+FrameInfo.swift.
(URLResponse.hasAttachment):
* Tools/SwiftBrowser/Source/SwiftBrowser.swift:
(SwiftBrowserApp.body):
* Tools/SwiftBrowser/Source/ViewModel/AppStorageKeys.swift: Copied from Tools/SwiftBrowser/Source/AppStorageKeys.swift.
* Tools/SwiftBrowser/Source/ViewModel/BrowserViewModel.swift: Renamed from Tools/SwiftBrowser/Source/BrowserViewModel.swift.
(PDF.transferRepresentation):
(BrowserViewModel.decideSensorAuthorization(_:frame:origin:)):
(BrowserViewModel.displayedURL):
(BrowserViewModel.exportedPDF):
(BrowserViewModel.currentDialog):
(BrowserViewModel.currentFilePicker):
(BrowserViewModel.openURL(_:)):
(BrowserViewModel.didReceiveNavigationEvent(_:)):
(BrowserViewModel.navigateToSubmittedURL):
(BrowserViewModel.exportAsPDF):
(BrowserViewModel.didExportPDF(_:any:)):
(BrowserViewModel.didImportFiles(_:any:)):
(BrowserViewModel.setCameraCaptureState(_:)):
(BrowserViewModel.setMicrophoneCaptureState(_:)):
* Tools/SwiftBrowser/Source/ViewModel/DialogPresenter.swift: Added.
(hash(into:)):
(owner):
(handleJavaScriptAlert(_:initiatedBy:)):
(handleJavaScriptConfirm(_:initiatedBy:)):
(handleJavaScriptPrompt(_:defaultText:initiatedBy:)):
(handleFileInputPrompt(_:initiatedBy:)):
* Tools/SwiftBrowser/Source/ViewModel/DownloadCoordinator.swift: Added.
(DownloadCoordinator.downloads):
(DownloadCoordinator.didReceiveDownloadEvent(_:)):
(DownloadCoordinator.destination(forDownload:response:suggestedFilename:)):
(DownloadItem.url):
(DownloadItem.finished):
(DownloadItem.cancel):
(DownloadItem.hash(into:)):
* Tools/SwiftBrowser/Source/ViewModel/Downloadable.swift: Renamed from Tools/SwiftBrowser/Source/AppStorageKeys.swift.
(Downloadable.progress):
(Downloadable.url):
(Downloadable.finished):
(Downloadable.cancel):
* Tools/SwiftBrowser/Source/ViewModel/NavigationDecider.swift: Copied from Source/WebKit/UIProcess/API/Swift/WebPage+FrameInfo.swift.
(NavigationDecider.decidePolicy(for:preferences:)):
(NavigationDecider.decidePolicy(for:)):
* Tools/SwiftBrowser/Source/Views/BrowserView.swift: Renamed from Tools/SwiftBrowser/Source/BrowserView.swift.
(BrowserView.url):
(BrowserView.body):
(url):
* Tools/SwiftBrowser/Source/Views/ContentView.swift: Renamed from Tools/SwiftBrowser/Source/ContentView.swift.
(body):
(LabelConfiguration.body):
(PrincipalToolbarGroup.body):
(DialogActionsView.body):
(DialogMessageView.body):
(ContentView.url):
(ContentView.body):
(url):
* Tools/SwiftBrowser/Source/Views/DownloadsView.swift: Added.
(DownloadView.formattedSize):
(DownloadView.body):
(DownloadsList.body):
(Download.cancel):
* Tools/SwiftBrowser/Source/Views/SettingsView.swift: Renamed from Tools/SwiftBrowser/Source/SettingsView.swift.
(PermissionDecisionView.permissionDecision):
(PermissionDecisionView.body):
(GeneralSettingsView.body):
(SettingsView.body):
* Tools/SwiftBrowser/SwiftBrowser.xcodeproj/project.pbxproj:

Canonical link: https://commits.webkit.org/288395@main



To unsubscribe from these emails, change your notification settings at https://github.com/WebKit/WebKit/settings/notifications


More information about the webkit-changes mailing list