-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Remote editor exceptions #109
Merged
Merged
Changes from all commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
1fe50bc
fix: Open user-initiated link navigation in OS browser
dcalhoun c8e1185
refactor: Update preloaded data comments
dcalhoun fbdfbef
fix: Exclude remote scripts by ID rather than path
dcalhoun b329ad9
feat: Allow multiple siteApiNamespace values
dcalhoun 0452dd9
feat: Editor assets request utilizes site configuration
dcalhoun 0da1b48
feat: Allow excluding API paths from API namespacing
dcalhoun 8a40965
fix: Limit WebView navigation to allow list
dcalhoun c1b4b36
feat: Allowing host app setting JavaScript globals
dcalhoun d4fbf22
feat: Allow setting both bundled and site-specific editor URLs
dcalhoun bd97e67
feat: Android loads dedicated remote editor URL for plugin support
dcalhoun 32a5621
feat: Android siteApiNamespace accepts multiple strings
dcalhoun 39d660f
feat: Android allows excluding paths from namespacing
dcalhoun 9585f34
refactor: Android utilizes EditorConfiguration class
dcalhoun 4f55f2e
feat: Allow setting global properties within the Android editor WebView
dcalhoun a0ae338
refactor: Set Android global editor configuration on page start
dcalhoun ab566a3
task: Capture build output
dcalhoun 56c0e14
fix: Ensure inline CSS is not externalized
dcalhoun 03bf822
feat: Android loads remote editor bundle URL
dcalhoun f263817
task: Capture build output
dcalhoun d090d36
fix: Parcelize Android web view globals
dcalhoun 60efc7a
feat: Expand URLs managed by the Android WebView
dcalhoun e8b0b86
task: Makefile allows skipping dependency installation
dcalhoun 8144e7b
fix: Verify GBKit global configuration presence before initializing
dcalhoun b36a13e
refactor: Tidy working code
dcalhoun 07fdeca
feat: Improve editor load error handling
dcalhoun 62e3f0d
task: Capture build output
dcalhoun 56d7b13
task: Update Android example app configuration
dcalhoun ffd2e12
docs: Add inline comments
dcalhoun File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
155 changes: 155 additions & 0 deletions
155
android/Gutenberg/src/main/java/org/wordpress/gutenberg/EditorConfiguration.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
package org.wordpress.gutenberg | ||
|
||
import android.os.Parcelable | ||
import android.os.Parcel | ||
import kotlinx.parcelize.Parcelize | ||
|
||
@Parcelize | ||
sealed class WebViewGlobalValue : Parcelable { | ||
@Parcelize | ||
data class StringValue(val value: String) : WebViewGlobalValue() | ||
@Parcelize | ||
data class NumberValue(val value: Double) : WebViewGlobalValue() | ||
@Parcelize | ||
data class BooleanValue(val value: Boolean) : WebViewGlobalValue() | ||
@Parcelize | ||
data class ObjectValue(val value: Map<String, WebViewGlobalValue>) : WebViewGlobalValue() | ||
@Parcelize | ||
data class ArrayValue(val value: List<WebViewGlobalValue>) : WebViewGlobalValue() | ||
@Parcelize | ||
object NullValue : WebViewGlobalValue() | ||
|
||
fun toJavaScript(): String { | ||
return when (this) { | ||
is StringValue -> "\"${value.replace("\"", "\\\"").replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t")}\"" | ||
is NumberValue -> value.toString() | ||
is BooleanValue -> value.toString() | ||
is ObjectValue -> { | ||
val pairs = value.map { (key, value) -> "\"$key\": ${value.toJavaScript()}" } | ||
"{${pairs.joinToString(",")}}" | ||
} | ||
is ArrayValue -> "[${value.joinToString(",") { it.toJavaScript() }}]" | ||
is NullValue -> "null" | ||
} | ||
} | ||
} | ||
|
||
@Parcelize | ||
data class WebViewGlobal( | ||
val name: String, | ||
val value: WebViewGlobalValue | ||
) : Parcelable { | ||
init { | ||
require(name.matches(Regex("^[a-zA-Z_$][a-zA-Z0-9_$]*$"))) { | ||
"Invalid JavaScript identifier: $name" | ||
} | ||
} | ||
} | ||
|
||
@Parcelize | ||
open class EditorConfiguration constructor( | ||
val title: String, | ||
val content: String, | ||
val postId: Int?, | ||
val postType: String?, | ||
val themeStyles: Boolean, | ||
val plugins: Boolean, | ||
val hideTitle: Boolean, | ||
val siteURL: String, | ||
val siteApiRoot: String, | ||
val siteApiNamespace: Array<String>, | ||
val namespaceExcludedPaths: Array<String>, | ||
val authHeader: String, | ||
val webViewGlobals: List<WebViewGlobal> | ||
) : Parcelable { | ||
companion object { | ||
@JvmStatic | ||
fun builder(): Builder = Builder() | ||
} | ||
|
||
class Builder { | ||
private var title: String = "" | ||
private var content: String = "" | ||
private var postId: Int? = null | ||
private var postType: String? = null | ||
private var themeStyles: Boolean = false | ||
private var plugins: Boolean = false | ||
private var hideTitle: Boolean = false | ||
private var siteURL: String = "" | ||
private var siteApiRoot: String = "" | ||
private var siteApiNamespace: Array<String> = arrayOf() | ||
private var namespaceExcludedPaths: Array<String> = arrayOf() | ||
private var authHeader: String = "" | ||
private var webViewGlobals: List<WebViewGlobal> = emptyList() | ||
|
||
fun setTitle(title: String) = apply { this.title = title } | ||
fun setContent(content: String) = apply { this.content = content } | ||
fun setPostId(postId: Int?) = apply { this.postId = postId } | ||
fun setPostType(postType: String?) = apply { this.postType = postType } | ||
fun setThemeStyles(themeStyles: Boolean) = apply { this.themeStyles = themeStyles } | ||
fun setPlugins(plugins: Boolean) = apply { this.plugins = plugins } | ||
fun setHideTitle(hideTitle: Boolean) = apply { this.hideTitle = hideTitle } | ||
fun setSiteURL(siteURL: String) = apply { this.siteURL = siteURL } | ||
fun setSiteApiRoot(siteApiRoot: String) = apply { this.siteApiRoot = siteApiRoot } | ||
fun setSiteApiNamespace(siteApiNamespace: Array<String>) = apply { this.siteApiNamespace = siteApiNamespace } | ||
fun setNamespaceExcludedPaths(namespaceExcludedPaths: Array<String>) = apply { this.namespaceExcludedPaths = namespaceExcludedPaths } | ||
fun setAuthHeader(authHeader: String) = apply { this.authHeader = authHeader } | ||
fun setWebViewGlobals(webViewGlobals: List<WebViewGlobal>) = apply { this.webViewGlobals = webViewGlobals } | ||
|
||
fun build(): EditorConfiguration = EditorConfiguration( | ||
title = title, | ||
content = content, | ||
postId = postId, | ||
postType = postType, | ||
themeStyles = themeStyles, | ||
plugins = plugins, | ||
hideTitle = hideTitle, | ||
siteURL = siteURL, | ||
siteApiRoot = siteApiRoot, | ||
siteApiNamespace = siteApiNamespace, | ||
namespaceExcludedPaths = namespaceExcludedPaths, | ||
authHeader = authHeader, | ||
webViewGlobals = webViewGlobals | ||
) | ||
} | ||
|
||
override fun equals(other: Any?): Boolean { | ||
if (this === other) return true | ||
if (javaClass != other?.javaClass) return false | ||
|
||
other as EditorConfiguration | ||
|
||
if (title != other.title) return false | ||
if (content != other.content) return false | ||
if (postId != other.postId) return false | ||
if (postType != other.postType) return false | ||
if (themeStyles != other.themeStyles) return false | ||
if (plugins != other.plugins) return false | ||
if (hideTitle != other.hideTitle) return false | ||
if (siteURL != other.siteURL) return false | ||
if (siteApiRoot != other.siteApiRoot) return false | ||
if (!siteApiNamespace.contentEquals(other.siteApiNamespace)) return false | ||
if (!namespaceExcludedPaths.contentEquals(other.namespaceExcludedPaths)) return false | ||
if (authHeader != other.authHeader) return false | ||
if (webViewGlobals != other.webViewGlobals) return false | ||
|
||
return true | ||
} | ||
|
||
override fun hashCode(): Int { | ||
var result = title.hashCode() | ||
result = 31 * result + content.hashCode() | ||
result = 31 * result + (postId ?: 0) | ||
result = 31 * result + (postType?.hashCode() ?: 0) | ||
result = 31 * result + themeStyles.hashCode() | ||
result = 31 * result + plugins.hashCode() | ||
result = 31 * result + hideTitle.hashCode() | ||
result = 31 * result + siteURL.hashCode() | ||
result = 31 * result + siteApiRoot.hashCode() | ||
result = 31 * result + siteApiNamespace.contentHashCode() | ||
result = 31 * result + namespaceExcludedPaths.contentHashCode() | ||
result = 31 * result + authHeader.hashCode() | ||
result = 31 * result + webViewGlobals.hashCode() | ||
return result | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add
GUTENBERG_EDITOR_REMOTE_URL
to simplify running both the local (bundled) and remote (site-specific) editor servers at the same time.