Skip to content
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

Clipboard not working #235

Closed
jdelrue opened this issue Dec 26, 2019 · 15 comments
Closed

Clipboard not working #235

jdelrue opened this issue Dec 26, 2019 · 15 comments

Comments

@jdelrue
Copy link

jdelrue commented Dec 26, 2019

Environment

Flutter version: 1.12.13+hotfix.5
Plugin version: 9c7ac0d
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
Copy link
Author

jdelrue commented Dec 27, 2019

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
Copy link

kaudy commented Jan 13, 2020

same problem here.

@virskor
Copy link

virskor commented Feb 17, 2020

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

@ohjs88
Copy link

ohjs88 commented Mar 14, 2020

same problem here.

@RickyJun
Copy link

RickyJun commented May 5, 2020

thank you so mmmmmmmmmmmmmuch! helped me a lot

@danieeelfc
Copy link

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
Copy link

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
Copy link
Owner

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
Copy link

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

@pichillilorenzo
Copy link
Owner

Thanks for your support! 👍

@mankeomorakort
Copy link

Is there any plan for fixing this issue?

@pichillilorenzo
Copy link
Owner

@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
Copy link
Owner

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

@mankeomorakort
Copy link

mankeomorakort commented May 27, 2020

@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?

This was referenced Jul 6, 2020
@reasje
Copy link

reasje commented Sep 19, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants