From d21687528ac19ad5ec14ee33286287a5a5e84a39 Mon Sep 17 00:00:00 2001 From: Jeremy Massel <1123407+jkmassel@users.noreply.github.com> Date: Thu, 29 May 2025 16:18:25 -0600 Subject: [PATCH 1/3] Fix weird spacing Fixup --- ios/Demo-iOS/Sources/ContentView.swift | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ios/Demo-iOS/Sources/ContentView.swift b/ios/Demo-iOS/Sources/ContentView.swift index 2f628d4c..f8fc918e 100644 --- a/ios/Demo-iOS/Sources/ContentView.swift +++ b/ios/Demo-iOS/Sources/ContentView.swift @@ -5,9 +5,11 @@ let editorURL: URL? = ProcessInfo.processInfo.environment["GUTENBERG_EDITOR_URL" struct ContentView: View { var body: some View { - NavigationView { - EditorView(editorURL: editorURL) - } + NavigationSplitView(preferredCompactColumn: .constant(.detail), sidebar: { + EmptyView() + }, detail: { + EditorView(editorURL: editorURL).navigationBarBackButtonHidden() + }) } } From 2d9783a0ffcfe4b41c28a3982295625676e1345d Mon Sep 17 00:00:00 2001 From: Jeremy Massel <1123407+jkmassel@users.noreply.github.com> Date: Thu, 29 May 2025 16:17:55 -0600 Subject: [PATCH 2/3] Add iOS cookie support --- ios/Demo-iOS/Sources/ContentView.swift | 11 ++++++++- ios/Demo-iOS/Sources/EditorView.swift | 24 +++++++++++++++---- .../Sources/EditorConfiguration.swift | 1 + .../Sources/EditorViewController.swift | 6 +++++ 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/ios/Demo-iOS/Sources/ContentView.swift b/ios/Demo-iOS/Sources/ContentView.swift index f8fc918e..acdd06c6 100644 --- a/ios/Demo-iOS/Sources/ContentView.swift +++ b/ios/Demo-iOS/Sources/ContentView.swift @@ -4,11 +4,20 @@ import GutenbergKit let editorURL: URL? = ProcessInfo.processInfo.environment["GUTENBERG_EDITOR_URL"].flatMap(URL.init) struct ContentView: View { + private let configuration: EditorConfiguration + + init(configuration: EditorConfiguration = .default) { + self.configuration = configuration + } + var body: some View { NavigationSplitView(preferredCompactColumn: .constant(.detail), sidebar: { EmptyView() }, detail: { - EditorView(editorURL: editorURL).navigationBarBackButtonHidden() + EditorView( + editorURL: editorURL, + editorConfiguration: configuration + ).navigationBarBackButtonHidden() }) } } diff --git a/ios/Demo-iOS/Sources/EditorView.swift b/ios/Demo-iOS/Sources/EditorView.swift index f1f3394b..a29ce597 100644 --- a/ios/Demo-iOS/Sources/EditorView.swift +++ b/ios/Demo-iOS/Sources/EditorView.swift @@ -2,10 +2,18 @@ import SwiftUI import GutenbergKit struct EditorView: View { - var editorURL: URL? + + private let editorURL: URL? + + private let editorConfiguration: EditorConfiguration + + init(editorURL: URL? = nil, editorConfiguration: EditorConfiguration = .default) { + self.editorURL = editorURL + self.editorConfiguration = editorConfiguration + } var body: some View { - _EditorView(editorURL: editorURL) + _EditorView(editorURL: editorURL, configuration: editorConfiguration) .toolbar { ToolbarItemGroup(placement: .topBarLeading) { Button(action: {}, label: { @@ -69,10 +77,18 @@ struct EditorView: View { } private struct _EditorView: UIViewControllerRepresentable { - var editorURL: URL? + + private let editorURL: URL? + + private let configuration: EditorConfiguration + + init(editorURL: URL? = nil, configuration: EditorConfiguration) { + self.editorURL = editorURL + self.configuration = configuration + } func makeUIViewController(context: Context) -> EditorViewController { - let viewController = EditorViewController() + let viewController = EditorViewController(configuration: self.configuration) viewController.editorURL = editorURL if #available(iOS 16.4, *) { viewController.webView.isInspectable = true diff --git a/ios/Sources/GutenbergKit/Sources/EditorConfiguration.swift b/ios/Sources/GutenbergKit/Sources/EditorConfiguration.swift index 6f671ab9..d15083b5 100644 --- a/ios/Sources/GutenbergKit/Sources/EditorConfiguration.swift +++ b/ios/Sources/GutenbergKit/Sources/EditorConfiguration.swift @@ -21,6 +21,7 @@ public struct EditorConfiguration { public var editorSettings: [String: Any]? /// The locale to use for translations public var locale = "en" + public var cookies: [HTTPCookie] = [] public init(title: String = "", content: String = "") { self.title = title diff --git a/ios/Sources/GutenbergKit/Sources/EditorViewController.swift b/ios/Sources/GutenbergKit/Sources/EditorViewController.swift index 289f3148..3691f47c 100644 --- a/ios/Sources/GutenbergKit/Sources/EditorViewController.swift +++ b/ios/Sources/GutenbergKit/Sources/EditorViewController.swift @@ -41,6 +41,12 @@ public final class EditorViewController: UIViewController, GutenbergEditorContro config.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs") config.setValue(true, forKey: "allowUniversalAccessFromFileURLs") + // The editor shouldn't try to persist cookies – we want complete control over how they're handled + config.websiteDataStore = WKWebsiteDataStore.nonPersistent() + for cookie in configuration.cookies { + config.websiteDataStore.httpCookieStore.setCookie(cookie) + } + // Set-up communications with the editor. config.userContentController.add(controller, name: "editorDelegate") From d1de5513ef18eeacfa7eb695fe8e2566278de81e Mon Sep 17 00:00:00 2001 From: Jeremy Massel <1123407+jkmassel@users.noreply.github.com> Date: Thu, 29 May 2025 16:21:16 -0600 Subject: [PATCH 3/3] Add Android cookie support --- .../gutenberg/EditorConfiguration.kt | 12 ++++++++--- .../org/wordpress/gutenberg/GutenbergView.kt | 21 +++++++++++++++++-- .../com/example/gutenbergkit/MainActivity.kt | 2 +- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/android/Gutenberg/src/main/java/org/wordpress/gutenberg/EditorConfiguration.kt b/android/Gutenberg/src/main/java/org/wordpress/gutenberg/EditorConfiguration.kt index 307d99e7..21ceaa8d 100644 --- a/android/Gutenberg/src/main/java/org/wordpress/gutenberg/EditorConfiguration.kt +++ b/android/Gutenberg/src/main/java/org/wordpress/gutenberg/EditorConfiguration.kt @@ -61,8 +61,9 @@ open class EditorConfiguration constructor( val authHeader: String, val webViewGlobals: List, val editorSettings: String?, - val locale: String? -) : Parcelable { + val locale: String?, + val cookies: Map +): Parcelable { companion object { @JvmStatic fun builder(): Builder = Builder() @@ -84,6 +85,7 @@ open class EditorConfiguration constructor( private var webViewGlobals: List = emptyList() private var editorSettings: String? = null private var locale: String? = "en" + private var cookies: Map = mapOf() fun setTitle(title: String) = apply { this.title = title } fun setContent(content: String) = apply { this.content = content } @@ -100,6 +102,7 @@ open class EditorConfiguration constructor( fun setWebViewGlobals(webViewGlobals: List) = apply { this.webViewGlobals = webViewGlobals } fun setEditorSettings(editorSettings: String?) = apply { this.editorSettings = editorSettings } fun setLocale(locale: String?) = apply { this.locale = locale } + fun setCookies(cookies: Map) = apply { this.cookies = cookies } fun build(): EditorConfiguration = EditorConfiguration( title = title, @@ -116,7 +119,8 @@ open class EditorConfiguration constructor( authHeader = authHeader, webViewGlobals = webViewGlobals, editorSettings = editorSettings, - locale = locale + locale = locale, + cookies = cookies ) } @@ -141,6 +145,7 @@ open class EditorConfiguration constructor( if (webViewGlobals != other.webViewGlobals) return false if (editorSettings != other.editorSettings) return false if (locale != other.locale) return false + if (cookies != other.cookies) return false return true } @@ -161,6 +166,7 @@ open class EditorConfiguration constructor( result = 31 * result + webViewGlobals.hashCode() result = 31 * result + (editorSettings?.hashCode() ?: 0) result = 31 * result + (locale?.hashCode() ?: 0) + result = 31 * result + cookies.hashCode() return result } } diff --git a/android/Gutenberg/src/main/java/org/wordpress/gutenberg/GutenbergView.kt b/android/Gutenberg/src/main/java/org/wordpress/gutenberg/GutenbergView.kt index d537f31f..ddeef035 100644 --- a/android/Gutenberg/src/main/java/org/wordpress/gutenberg/GutenbergView.kt +++ b/android/Gutenberg/src/main/java/org/wordpress/gutenberg/GutenbergView.kt @@ -11,12 +11,14 @@ import android.util.AttributeSet import android.util.Log import android.view.View import android.webkit.ConsoleMessage +import android.webkit.CookieManager import android.webkit.JavascriptInterface import android.webkit.ValueCallback import android.webkit.WebChromeClient import android.webkit.WebResourceError import android.webkit.WebResourceRequest import android.webkit.WebResourceResponse +import android.webkit.WebStorage import android.webkit.WebView import android.webkit.WebViewClient import androidx.webkit.WebViewAssetLoader @@ -245,9 +247,24 @@ class GutenbergView : WebView { } else { ASSET_URL } - this.loadUrl(editorUrl) - Log.i("GutenbergView", "Startup Complete") + WebStorage.getInstance().deleteAllData() + this.clearCache(true) + // All cookies are third-party cookies because the root of this document + // lives under `https://appassets.androidplatform.net` + CookieManager.getInstance().setAcceptThirdPartyCookies(this, true); + + // Erase all local cookies before loading the URL – we don't want to persist + // anything between uses – otherwise we might send the wrong cookies + CookieManager.getInstance().removeAllCookies { + CookieManager.getInstance().flush() + for(cookie in configuration.cookies) { + CookieManager.getInstance().setCookie(cookie.key, cookie.value) + } + this.loadUrl(editorUrl) + + Log.i("GutenbergView", "Startup Complete") + } } private fun setGlobalJavaScriptVariables() { diff --git a/android/app/src/main/java/com/example/gutenbergkit/MainActivity.kt b/android/app/src/main/java/com/example/gutenbergkit/MainActivity.kt index 8061fdc0..421f5807 100644 --- a/android/app/src/main/java/com/example/gutenbergkit/MainActivity.kt +++ b/android/app/src/main/java/com/example/gutenbergkit/MainActivity.kt @@ -1,7 +1,6 @@ package com.example.gutenbergkit import android.os.Bundle -import android.util.Log import android.webkit.WebView import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity @@ -39,6 +38,7 @@ class MainActivity : AppCompatActivity() { .setNamespaceExcludedPaths(arrayOf()) .setAuthHeader("") .setWebViewGlobals(emptyList()) + .setCookies(emptyMap()) .build() gbView.start(config)