Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TinyMCE copy paste from notepad (clipboard) with javafx WebView on java 1.8

I embedded tinymce editor into javafx WebWiew. I load the editor with webEngine.load method. Problems occurs on copy paste. When I copy some content from notepad into tinymce, it is pasted. Next, when i copy some content from tinymce into tinymce, it is pasted. No problem. But once i have pasted some content from tinyme to tinymce itself, I can not copy from outside of tinymce(webView) anymore. For example when I copy from notepad a text and perform a paste, the value copied from notepad is ignored and the previous value copied from tinymce is pasted again.

I added listener to webView and checked the clipboard values, they are in all cases correct:

webView.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
    @Override
    public void handle(KeyEvent arg0) {
          if (arg0.isControlDown() && arg0.getCode() == KeyCode.V) {
              final ClipBoard clipBoard = ClipBoard.getSystemClipBoard();
              System.out.println(clipBoard.getContent(DataFormat.PLAIN_TEXT));
..

And on the editor side, while initializing the TinyMCE editor: As you see on the third try, the args.content is wrong and doens not contain the value in the clipboard.

tinymce.init {
    paste_preprocess : function(plugin,args) {
       debug(args.content);

Step1: [OK]

value copied from notepad ABCDE

java system out for clipboard: ABCDE

editor html debug says: ABCDE

Step2: [OK]

value copied from tinymce editor XYZQ

java system out for clipboard: XYZQ

editor html debug says: XYZQ

Step3: [FAIL]

value copied from notepad ASDFG

java system out for clipboard: ASDFG

editor html debug says: XYZQ

The system properties:

TinyMCE 4.2.2

Windows 7

The problem occurs on java 1.8.65 and 1.8.66

The problem does not occur on java 1.7.40

Solution: I can manually sent content from java to javafx(editor) by using executing scripts etc and override the value in the paste_preprocess function of tinymce. But why such thing happens? (Case not occurs on java 1.7)There must be a better solution.

like image 510
benchpresser Avatar asked Nov 10 '22 00:11

benchpresser


1 Answers

I had the same problem but still needed a solution for being able to paste HTML or Word XML into TinyMCE and not just plain text.

The solution was to basically ignore the original paste event and then use the paste plugin's pasteHtml() to insert clipboard data from Java. The reason for this is that at the point where paste_preprocess is called, the clipboard content is already formatted to HTML by TinyMCE, thus I cannot simply set args.content to whatever is in the Java clipboard.

There exist both an AWT and FX implementation of clipboards which I use both. The FX implementation provides some useful methods for getting HTML from the clipboard.

JavaScript code

var regularPaste = false;

tinyMCE.init({
  ...
    paste_preprocess : function(plugin, args) {
      if(!regularPaste) {
        regularPaste = true;

        var clipboardData = window.java.getClipboardData();

        plugin.clipboard.pasteHtml(clipboardData); // This will call paste_preprocess again

        args.content = ""; // Ignore what TinyMCE think it should insert
      }

      regularPaste = false;
    },
  ...
});

Java code

public class Bridge {

  public String getClipboardData() {
    javafx.scene.input.Clipboard clipboardFx = javafx.scene.input.Clipboard.getSystemClipboard();
    java.awt.datatransfer.Clipboard clipboardAwt = Toolkit.getDefaultToolkit().getSystemClipboard();

    String data = "";

    try {
      if (clipboardFx.hasHtml()) {
        data = clipboardFx.getHtml();
      } else {
        // We use the AWT clipboard if we want to retreive text because the FX implementation delivers funky characters
        // when pasting from e.g. Command Prompt
        data = (String) clipboardAwt.getData(DataFlavor.stringFlavor);
        data = data.replaceAll("(\n|\r|\n\r|\r\n)", "<br />");
      }
    } catch (Exception e) {
      System.out.println("Failed getting clipboard data");
    }

    return data;
  }

}

Where your WebView are you need to register an instance of the Bridge class.

JSObject window = (JSObject) webView.getEngine().executeScript("window");
window.setMember("java", new Bridge());
like image 143
CleanUp Avatar answered Nov 15 '22 04:11

CleanUp