Skip to content

feat: add WebView Plugin API#2525

Open
RohitKushvaha01 wants to merge 8 commits into
Acode-Foundation:mainfrom
RohitKushvaha01:feat/webview-plugin-api
Open

feat: add WebView Plugin API#2525
RohitKushvaha01 wants to merge 8 commits into
Acode-Foundation:mainfrom
RohitKushvaha01:feat/webview-plugin-api

Conversation

@RohitKushvaha01

@RohitKushvaha01 RohitKushvaha01 commented Jul 22, 2026

Copy link
Copy Markdown
Member

Add cordova-plugin-acode-webview allowing plugins to create and manage isolated WebView instances with fullscreen, window, panel, and hidden modes.

Features:

  • Create independent WebView instances via acode.webview.create()
  • Load URLs, HTML content, and execute JavaScript
  • Bidirectional messaging between plugin and WebView
  • Lifecycle management: show, hide, reload, destroy
  • Lifecycle events: pageFinished, titleChanged, closed

Pre/Post Merge To-do:

  • Plugin types updation.
  • Plugin Docs updation.

Closes #2281

Add cordova-plugin-acode-webview allowing plugins to create and manage
isolated WebView instances with fullscreen, window, panel, and hidden modes.

Features:
- Create independent WebView instances via acode.webview.create()
- Load URLs, HTML content, and execute JavaScript
- Bidirectional messaging between plugin and WebView
- Lifecycle management: show, hide, reload, destroy
- Lifecycle events: pageFinished, titleChanged, closed
Fullscreen mode is now a clean full-screen WebView with no chrome.
Back button handles navigation and closing.
@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR introduces cordova-plugin-acode-webview, a new Cordova plugin that lets Acode plugins create and manage isolated Android WebView instances supporting fullscreen and hidden (headless) modes. The JS layer (src/lib/webview.js) wraps the native bridge with a clean class-based API, bidirectional messaging, and lifecycle events.

  • New plugin (src/plugins/webview/): three Java source files cover the Cordova plugin dispatch (WebViewPlugin), per-instance WebView lifecycle and messaging bridge (WebViewInstance), and the fullscreen-hosting Activity. URL sanitization enforces http/https-only loading, file system access is disabled, and the JS bridge is re-injected on every page navigation.
  • JS integration (src/lib/webview.js, src/lib/acode.js): a single global message-callback channel routes events and messages to the correct WebView instance; listener dispatch, "closed" cleanup, and _destroyed guarding are handled correctly.
  • TypeScript types (src/index.d.ts): WebViewOptions, AcodeWebView, and AcodeWebViewAPI are added and accurately reflect the implemented surface.

Confidence Score: 5/5

The Java and JS implementation is solid — URL sandboxing, bridge re-injection, and fullscreen lifecycle management are all handled correctly. The remaining comments are non-blocking quality improvements.

The core correctness issues flagged in earlier review rounds (null plugin singleton, lifecycle listeners not firing, navigation removing the message bridge, file-origin access) have all been fixed. The findings in this pass are a deprecated API, a potential double-fire of the closed event on explicit destroy, and use of a plain HashMap across threads — none of which cause data loss or broken functionality in normal use.

Files Needing Attention: WebViewActivity.java and WebViewPlugin.java are worth a second glance for the unconditional closed event dispatch and the HashMap threading model.

Important Files Changed

Filename Overview
src/plugins/webview/src/android/com/foxdebug/webview/WebViewPlugin.java Core plugin dispatch layer; correctly handles all actions and lifecycle; instances uses a plain HashMap accessed from both the UI thread (create) and the Cordova thread (all other operations) without synchronization.
src/plugins/webview/src/android/com/foxdebug/webview/WebViewInstance.java WebView lifecycle and messaging implementation; bridge is correctly re-injected on every page load; URL sanitization limits to http(s) only; file access is disabled; pending-content pattern for deferred fullscreen creation is sound.
src/plugins/webview/src/android/com/foxdebug/webview/WebViewActivity.java Fullscreen hosting activity; singleton plugin lookup is now correct; sendEventToCordova("closed") is called unconditionally in onDestroy() including when JS calls destroy(), and onBackPressed() uses the deprecated API.
src/lib/webview.js JS WebView wrapper; listener dispatch, message routing, and destroy/closed-event cleanup are all correct; mode is properly restricted to "fullscreen" and "hidden".
src/plugins/webview/www/webview.js Thin Cordova bridge; correctly wraps each native action as a promise and forwards the long-lived message callback.
src/index.d.ts Adds WebViewOptions, AcodeWebView, and AcodeWebViewAPI interfaces; types accurately reflect the JS implementation.
src/plugins/webview/plugin.xml Cordova plugin manifest; registers the plugin feature, activity, and source files correctly.

Sequence Diagram

sequenceDiagram
    participant Plugin as Plugin JS
    participant WebviewJS as src/lib/webview.js
    participant Bridge as www/webview.js (Cordova)
    participant WVPlugin as WebViewPlugin.java
    participant WVInstance as WebViewInstance.java
    participant WVActivity as WebViewActivity.java

    Plugin->>WebviewJS: "acode.webview.create({ mode, visible })"
    WebviewJS->>Bridge: setMessageCallback (once, ensureInit)
    WebviewJS->>Bridge: create(options)
    Bridge->>WVPlugin: execute(create, options)
    WVPlugin->>WVInstance: new WebViewInstance(id, mode, ...)
    alt "mode === fullscreen && visible"
        WVPlugin->>WVActivity: startActivity(intent + webviewId)
        WVActivity->>WVInstance: createWebView(activity)
        WVInstance->>WVInstance: injectBridge()
    else "mode === hidden"
        WVPlugin->>WVInstance: createWebView(activity)
        WVInstance->>WVInstance: injectBridge()
    end
    WVPlugin-->>Bridge: callbackContext.success(id)
    Bridge-->>WebviewJS: Promise resolves with id
    WebviewJS-->>Plugin: new WebView(id) instance

    Plugin->>WebviewJS: wv.loadURL(url)
    WebviewJS->>Bridge: loadURL(id, url)
    Bridge->>WVPlugin: execute(loadURL, ...)
    WVPlugin->>WVInstance: loadURL(safeUrl)
    WVInstance->>WVInstance: sanitizeUrl - http/https only
    WVInstance-->>Bridge: callbackContext.success()

    WVInstance->>WVPlugin: sendEventToCordova(id, pageFinished, data)
    WVPlugin-->>Bridge: PluginResult keepCallback
    Bridge-->>WebviewJS: message callback fires
    WebviewJS-->>Plugin: on pageFinished listeners

    Plugin->>WebviewJS: wv.destroy()
    WebviewJS->>Bridge: destroy(id)
    Bridge->>WVPlugin: execute(destroy, id)
    WVPlugin->>WVInstance: instance.destroy()
    WVInstance->>WVActivity: hosting.finish()
    WVActivity->>WVPlugin: sendEventToCordova(webviewId, closed, null)
    WVActivity-->>WVPlugin: onDestroy complete
    WVPlugin-->>Bridge: callbackContext.success()
    Bridge-->>WebviewJS: destroy() resolves
Loading

Reviews (4): Last reviewed commit: "fix: lock" | Re-trigger Greptile

Comment thread src/lib/webview.js Outdated
Comment thread src/plugins/webview/src/android/com/foxdebug/webview/WebViewPlugin.java Outdated
Comment thread src/plugins/webview/src/android/com/foxdebug/webview/WebViewPlugin.java Outdated
Comment thread src/plugins/webview/src/android/com/foxdebug/webview/WebViewInstance.java Outdated
Comment thread src/plugins/webview/src/android/com/foxdebug/webview/WebViewInstance.java Outdated
Comment thread src/plugins/webview/src/android/com/foxdebug/webview/WebViewInstance.java Outdated
@RohitKushvaha01
RohitKushvaha01 marked this pull request as draft July 22, 2026 13:35
- Fix event dispatch: filter callbacks by event name instead of
  calling {event,callback} objects as functions (webview.js)
- Make hidden WebViews showable: attachToActivity() on first show()
- Remove universal file access (setAllowFileAccessFromFileURLs,
  setAllowUniversalAccessFromFileURLs) for untrusted content
- Clean up fullscreen path: remove throwaway WebView in Activity,
  register instance cleanup in onDestroy
- Add deprecated shouldOverrideUrlLoading(String) for compat
- Use Handler(Looper.getMainLooper()) instead of View.post()
  so hidden WebViews can process loadURL/evaluate without a window
- Remove unused constructor params (title, x, y, initiallyVisible)
@RohitKushvaha01

Copy link
Copy Markdown
Member Author

@greptile ai

Comment thread src/plugins/webview/src/android/com/foxdebug/webview/WebViewPlugin.java Outdated
@RohitKushvaha01 RohitKushvaha01 self-assigned this Jul 26, 2026
@RohitKushvaha01
RohitKushvaha01 marked this pull request as ready for review July 26, 2026 17:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

[Plugin API] Api to create webview instances

1 participant