Skip to content

Commit

Permalink
move webview package to plugin core (#1872)
Browse files Browse the repository at this point in the history
  • Loading branch information
Will-ShaoHua authored Apr 10, 2024
1 parent 9dac262 commit eddc005
Show file tree
Hide file tree
Showing 24 changed files with 102 additions and 46 deletions.
1 change: 0 additions & 1 deletion plugins/amazonq/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ dependencies {
implementation(project(":plugin-amazonq:codetransform"))
implementation(project(":plugin-amazonq:codewhisperer"))
implementation(project(":plugin-amazonq:mynah-ui"))
implementation(project(":plugin-amazonq:q-webview"))
implementation(project(":plugin-amazonq:shared"))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withTimeoutOrNull
import org.cef.CefApp
import org.cef.browser.CefBrowser
import org.cef.browser.CefFrame
import org.cef.network.CefRequest
import software.aws.toolkits.core.credentials.ToolkitBearerTokenProvider
import software.aws.toolkits.jetbrains.core.WebviewResourceHandlerFactory
import software.aws.toolkits.jetbrains.core.coroutines.projectCoroutineScope
import software.aws.toolkits.jetbrains.core.credentials.ManagedBearerSsoConnection
import software.aws.toolkits.jetbrains.core.credentials.ToolkitAuthManager
Expand All @@ -40,12 +38,10 @@ import software.aws.toolkits.jetbrains.core.credentials.sso.bearer.InteractiveBe
import software.aws.toolkits.jetbrains.core.region.AwsRegionProvider
import software.aws.toolkits.jetbrains.isDeveloperMode
import software.aws.toolkits.jetbrains.services.amazonq.util.createBrowser
import software.aws.toolkits.jetbrains.services.amazonq.webview.AssetResourceHandler
import software.aws.toolkits.telemetry.AwsTelemetry
import software.aws.toolkits.telemetry.CredentialType
import software.aws.toolkits.telemetry.Result
import java.awt.event.ActionListener
import java.io.IOException
import java.util.function.Function
import javax.swing.JButton
import javax.swing.JComponent
Expand Down Expand Up @@ -126,8 +122,11 @@ class WebviewBrowser(val project: Project) {
CefApp.getInstance()
.registerSchemeHandlerFactory(
"http",
"q-webview",
MyAssetResourceHandler.MyAssetResourceHandlerFactory(),
WebviewBrowser.DOMAIN,
WebviewResourceHandlerFactory(
domain = "http://${WebviewBrowser.DOMAIN}/",
assetUri = "/webview/assets/"
),
)

loadWebView()
Expand Down Expand Up @@ -325,38 +324,7 @@ class WebviewBrowser(val project: Project) {
}

companion object {
private const val WEB_SCRIPT_URI = "http://q-webview/js/getStart.js"
}
}

class MyAssetResourceHandler(data: ByteArray) : AssetResourceHandler(data) {
class MyAssetResourceHandlerFactory : AssetResourceHandler.AssetResourceHandlerFactory() {
override fun create(
browser: CefBrowser?,
frame: CefFrame?,
schemeName: String?,
request: CefRequest?,
): MyAssetResourceHandler? {
val resourceUri = request?.url ?: return null
if (!resourceUri.startsWith(LOCAL_RESOURCE_URL_PREFIX)) return null

val resource = resourceUri.replace(LOCAL_RESOURCE_URL_PREFIX, "/q-webview/assets/")
val resourceInputStream = this.javaClass.getResourceAsStream(resource)

try {
resourceInputStream.use {
if (resourceInputStream != null) {
return MyAssetResourceHandler(resourceInputStream.readAllBytes())
}
return null
}
} catch (e: IOException) {
throw RuntimeException(e)
}
}
}

companion object {
private const val LOCAL_RESOURCE_URL_PREFIX = "http://q-webview/"
private const val WEB_SCRIPT_URI = "http://webview/js/getStart.js"
private const val DOMAIN = "webview"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import org.cef.network.CefResponse
import java.io.IOException
import java.net.URLConnection

// TODO: delete this file as it's moved to core/WebviewResourceHandler
// TODO: maybe parameterize this class with the resource URI so that login UI and chat UI can share the same resource handler?
/**
* Loads assets from the /mynah-ui/assets/ directory on classpath if the CEF browser requests for
Expand Down
1 change: 1 addition & 0 deletions plugins/core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ dependencies {
implementation(project(":plugin-core:sdk-codegen"))
implementation(project(":plugin-core:jetbrains-community"))
implementation(project(":plugin-core:jetbrains-ultimate"))
implementation(project(":plugin-core:webview"))
}

configurations {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.jetbrains.core

import org.cef.browser.CefBrowser
import org.cef.browser.CefFrame
import org.cef.callback.CefCallback
import org.cef.callback.CefSchemeHandlerFactory
import org.cef.handler.CefResourceHandler
import org.cef.misc.IntRef
import org.cef.misc.StringRef
import org.cef.network.CefRequest
import org.cef.network.CefResponse
import java.io.IOException
import java.net.URLConnection

class WebviewResourceHandlerFactory(
val domain: String,
val assetUri: String
) : CefSchemeHandlerFactory {
override fun create(
browser: CefBrowser?,
frame: CefFrame?,
schemeName: String?,
request: CefRequest?,
): CefResourceHandler? {
val resourceUri = request?.url ?: return null
if (!resourceUri.startsWith(domain)) return null

val resource = resourceUri.replace(domain, assetUri)
val resourceInputStream = this.javaClass.getResourceAsStream(resource)

try {
resourceInputStream.use {
if (resourceInputStream != null) {
return AssetResourceHandler(resourceInputStream.readAllBytes())
}
return null
}
} catch (e: IOException) {
throw RuntimeException(e)
}
}
}

class AssetResourceHandler(var data: ByteArray) : CefResourceHandler {
/**
* Factory class for [AssetResourceHandler]. Ignores any request that doesn't begin with
* [AssetResourceHandler.LOCAL_RESOURCE_URL_PREFIX]
*/

private var offset = 0
private var resourceUri: String? = null
override fun processRequest(cefRequest: CefRequest, cefCallback: CefCallback): Boolean {
resourceUri = cefRequest.url
cefCallback.Continue()
return true
}

override fun getResponseHeaders(cefResponse: CefResponse, intRef: IntRef, stringRef: StringRef) {
intRef.set(data.size)
cefResponse.setHeaderByName("Access-Control-Allow-Origin", "*", true)
val mimeType = if (resourceUri?.endsWith(".wasm") == true) "application/wasm" else URLConnection.getFileNameMap().getContentTypeFor(resourceUri)
if (mimeType != null) cefResponse.mimeType = mimeType
cefResponse.status = 200
}

override fun readResponse(
outBuffer: ByteArray,
bytesToRead: Int,
bytesRead: IntRef,
cefCallback: CefCallback,
): Boolean {
if (offset >= data.size) {
cefCallback.cancel()
return false
}
var lenToRead = Math.min(outBuffer.size, bytesToRead)
lenToRead = Math.min(data.size - offset, lenToRead)
System.arraycopy(data, offset, outBuffer, 0, lenToRead)
bytesRead.set(lenToRead)
offset = offset + lenToRead
return true
}

override fun cancel() {}
}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ tasks.processResources {

tasks.jar {
from(buildGetStartUI) {
into("q-webview")
into("webview")
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "q-webview",
"name": "webview",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 0 additions & 1 deletion plugins/toolkit/jetbrains-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ dependencies {

// TODO: remove Q dependency when split is fully done
implementation(project(":plugin-amazonq:mynah-ui"))
implementation(project(":plugin-amazonq:q-webview"))
implementation(libs.bundles.jackson)
implementation(libs.zjsonpatch)
implementation(libs.commonmark)
Expand Down

0 comments on commit eddc005

Please sign in to comment.