Skip to content

Android editor can be replaced by another document without recovering #732

Description

@dcalhoun

Description

On Android, a script running in the editor can replace the editor document with another page, and nothing recovers from it. I expect the editor to stay loaded, with other documents kept out of its WebView or opened in the browser. Instead:

  • shouldOverrideUrlLoading allows blob:, data:, about: and file: URLs in the main frame, not only in the subframes that need them (such as the inserter's pattern previews).
  • The WebView doesn't enable multiple windows or handle onCreateWindow, and javaScriptCanOpenWindowsAutomatically is on. So window.open() and target="_blank" load into the editor's own WebView.
  • When another page starts, onEditorPageStarted marks the editor not ready, but the host isn't notified. The host keeps showing editor UI, commands are dropped, and getTitleAndContent fails, so unsaved changes can be lost.
  • reloadEditor() calls webView.reload(), which reloads the replacement page rather than the editor.

The trigger is any editor-page script, such as a plugin's editor script calling window.open(blobUrl) for a preview or export.

Related, and not yet confirmed: every URL the policy doesn't allow goes to startActivity(ACTION_VIEW) with no ActivityNotFoundException handling. A main-frame navigation to a URL no app can open, such as an unknown scheme, could crash the host app.

Step-by-step reproduction instructions

Worked out from the code; not yet confirmed on a device.

  1. In the demo app, open a post and connect to the editor WebView with chrome://inspect.
  2. In the console, run:
    window.top.location.href = URL.createObjectURL(
      new Blob(["<h1>Not the editor</h1>"], { type: "text/html" }),
    );
  3. The editor is replaced by "Not the editor", while the app still shows editor controls that no longer work.
  4. window.open( URL.createObjectURL( new Blob( [ '<h1>Popup</h1>' ], { type: 'text/html' } ) ) ) should do the same.

Screenshots, screen recording, code snippet

Possible fix:

  • Allow blob/data/about/file only when !request.isForMainFrame, and block them in the main frame without launching an intent.
  • Enable multiple windows and handle onCreateWindow: open http(s) URLs in the browser and ignore the rest.
  • Catch ActivityNotFoundException around startActivity.
  • If a non-editor page still starts in the main frame (POST forms, history, a host loadUrl), load the editor URL again. LatestContentProvider restores the content. reloadEditor() should load the editor URL too.

Environment info

  • GutenbergKit trunk (Android library), demo app
  • Android emulator, WordPress via wp-env

Please confirm that you have searched existing issues in the repo.

  • Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

  • Yes (not applicable: the reproduction runs from the console and doesn't depend on plugins)

Please confirm which theme type you used for testing.

  • Block
  • Classic
  • Hybrid (e.g. classic with theme.json)
  • Not sure

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Android[Type] BugAn existing feature does not function as intended

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions