pichillilorenzo / flutter_inappwebview

A Flutter plugin that allows you to add an inline webview, to use a headless webview, and to open an in-app browser window.
https://inappwebview.dev
Apache License 2.0
3.26k stars 1.6k forks source link

Clipboard not working #235

Closed jdelrue closed 4 years ago

jdelrue commented 4 years ago

Environment

Flutter version: 1.12.13+hotfix.5 Plugin version: 9c7ac0da8f01ceb40430da58397bdb31968ca5b1 Android version: 8.1.0 iOS version: Xcode version:
Device information: Xaomi Redmi 6

Description

Cannot copy or paste from within webview Expected behavior: Copy and paste from clipboard working Current behavior: Copy and paste from clipboard not working

jdelrue commented 4 years ago

Seems like this is an issue in Android, the copy/paste buttons cannot be clicked. For now we have fixed it with html/css injection.

ClipboardHack.dart

import 'package:flutter/services.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';

void copy(List<dynamic> params) {
  Clipboard.setData(new ClipboardData(text: params[0]));
}

Future<String> paste(List<dynamic> params) async {
  return (await Clipboard.getData('text/plain')).text.toString();
}

void addClipboardHack(InAppWebViewController webview) {
  webview.injectJavascriptFileFromAsset(
      assetFilePath: 'assets/clipboardhack.js');
  addClipboardHandlersOnly(webview);
}

void addClipboardHandlersOnly(InAppWebViewController webview) {
  webview.addJavaScriptHandler(handlerName: "COPY", callback: copy);
  webview.addJavaScriptHandler(handlerName: "PASTE", callback: paste);
}

clipboardhack.js (put in assets folder)

if (document.getElementById('webview_copy') == null) {
    let cbh_css = `
    #cbh-custom-menu {
        user-select: none;
        all: initial;
        display: none;
        z-index: 1000;
        position: fixed;
        background-color: #fff;
        border: 1px solid #ddd;
        overflow: hidden;
        width: 120px;
        white-space: nowrap;
        font-family: sans-serif;
        box-shadow: 2px 2px 7px 0px rgba(50, 50, 50, 0.5);
    }

    #cbh-custom-menu li {

        padding: 5px 10px;
    }

    #cbh-custom-menu li:hover {
        background-color: #4679BD;
        color: #fff;
        cursor: pointer;
    }
`;

    var cbh_html = `
<ul id='cbh-custom-menu'>
    <li id="webview_copy">Copy</li>
    <li id="webview_paste">Paste</li>
</ul>
`;

    /* inject CSS */
    let cbh_head = document.head || document.getElementsByTagName('head')[0];
    let cbh_style = document.createElement('style');
    cbh_style.type = 'text/css';
    cbh_style.appendChild(document.createTextNode(cbh_css));
    console.log(cbh_style);
    cbh_head.appendChild(cbh_style);
    document.body.innerHTML += cbh_html;

    /* JS code */

    var webview_copy_value = '';
    var webview_selected_item = {};
    window.addEventListener('click', function (e) {
        let cbh_menu = document.getElementById('cbh-custom-menu');
        cbh_menu.style.display = 'none';

    }, true);

    document.addEventListener('contextmenu', function (evt) {
        webview_selected_item = evt.path[0];
        webview_copy_value = window.getSelection().toString();
        let cbh_menu = document.getElementById('cbh-custom-menu');
        cbh_menu.style.top = `${evt.clientY}px`;
        cbh_menu.style.left = `${evt.clientX}px`;
        cbh_menu.style.display = 'block';
        evt.preventDefault();
    }, false);

    document.getElementById('webview_copy').onclick = function () {
        console.log("copy!!", webview_copy_value);

        window.flutter_inappwebview.callHandler('COPY', webview_copy_value).then(function (result) {

        });
    }
    document.getElementById('webview_paste').onclick = function () {

        window.flutter_inappwebview.callHandler('PASTE', webview_copy_value).then(function (result) {
            webview_selected_item.select();
            document.execCommand("insertHTML", false, result);
        });
    }

}
kaudy commented 4 years ago

same problem here.

virskor commented 4 years ago

@ jdelrue your code helped me a lot. same problem here

ohjs88 commented 4 years ago

same problem here.

RickyJun commented 4 years ago

thank you so mmmmmmmmmmmmmuch! helped me a lot

danieeelfc commented 4 years ago

In some compilations it shows the hacky menu and in others it doens't (with exact same code). Does someone know how to explain this strange behavior?

In fact I had to ditch the ClipboardHack.dart and did the following (I don't need paste function): webView.loadData(data: fullText); webView.injectJavascriptFileFromAsset(assetFilePath: 'assets/clipboardhack.js'); webView.addJavaScriptHandler(handlerName: "COPY", callback: copy);

danieeelfc commented 4 years ago

In case anyone is interested, after 7 days I've managed to solve the behavior described.

Method addClipboardHack MUST be called in webviews's onLoadStop event, as exemplified here by the plugin author: https://stackoverflow.com/a/59125391/854257

pichillilorenzo commented 4 years ago

Clipboard is somehow broken on Android, probably because on how Flutter manages native views inside its widgets tree. I will work as soon as possible on implementing the html + css + js workaround.

danieeelfc commented 4 years ago

Thank you @pichillilorenzo for your hard work. Best for you all in Italy.

pichillilorenzo commented 4 years ago

Thanks for your support! 👍

mankeomorakort commented 4 years ago

Is there any plan for fixing this issue?

pichillilorenzo commented 4 years ago

@ManKeomorakort yes, I'm working on it. I found a workaround to fix it using native components and a little bit of JavaScript (so, to make it work properly, JavaScript must be enabled!). It should be available in the next release. Maybe today or tomorrow 👍

pichillilorenzo commented 4 years ago

Published new version 3.2.0. Please, refer to ContextMenu to know about it.

mankeomorakort commented 4 years ago

@ManKeomorakort yes, I'm working on it. I found a workaround to fix it using native components and a little bit of JavaScript (so, to make it work properly, JavaScript must be enabled!). It should be available in the next release. Maybe today or tomorrow 👍

@pichillilorenzo Thank a lot :) does it work with copy and paste feature?

reasje commented 1 year ago

One better solution that I found that doesn't block other injections and is simple is this.

github-actions[bot] commented 2 weeks ago

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug and a minimal reproduction of the issue.