Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does codemirror provide Cut, Copy and Paste API?

Tags:

codemirror

From http://codemirror.net/doc/manual.html, I only find getRange(), undo(), redo() etc, and I can't find cut(), copy() and paste API, and more when I try to run editor.execCommand("cut"), I get the error. Could you help me? Thanks!

like image 237
HelloCW Avatar asked Feb 29 '12 02:02

HelloCW


2 Answers

There are no CodeMirror APIs for cut/copy/paste because browser security restrictions forbid JavaScript from accessing the clipboard programmatically. Paste could be used to steal private data and Cut/Copy can be used as a more elaborate attack vector.

The browser's own native code handles user gestures that access the clipboard (keyboard shortcuts and context menu items), based solely on the currently selected text or focused text field.

This SO thread has a good summary of attempts to work around these restrictions. CodeMirror's approach is the first bullet: it uses a hidden textarea to ensure that user clipboard gestures work, but that still doesn't support programmatic APIs.

But there is a partial workaround: use a small Flash widget (this is the 2nd bullet in the thread above). Flash relaxes the restrictions on Copy/Cut (but not Paste) a bit. It still has to be triggered by some user event, but it could be something like clicking a button in your HTML UI. Wrappers like ZeroClipboard and Clippy make it simple to access to these capabilities without needing to know Flash. You'd need to write a little glue code to pull the appropriate string from CodeMirror when copying, but it shouldn't be too bad.

like image 84
peterflynn Avatar answered Oct 29 '22 11:10

peterflynn


Using clipboard.js, you can define the text() function to grab the value of the CodeMirror's inner document.

Store a reference to the (<textarea>) editor's selector for convenience.

var editorSelector = '#editor' // or '#editor + .CodeMirror';

Instantiate a new ClipBoard object with reference to your button.

new Clipboard('.clip-btn-native', {
    text: function(trigger) {
        return getCodeMirrorNative(editorSelector).getDoc().getValue();
    }
});

Retrieve a CodeMirror Instance via native JavaScript.

function getCodeMirrorNative(target) {
    var _target = target;
    if (typeof _target === 'string') {
        _target = document.querySelector(_target);
    }
    if (_target === null || !_target.tagName === undefined) {
        throw new Error('Element does not reference a CodeMirror instance.');
    }

    if (_target.className.indexOf('CodeMirror') > -1) {
        return _target.CodeMirror;
    }

    if (_target.tagName === 'TEXTAREA') {
        return _target.nextSibling.CodeMirror;
    }

    return null;
};

Demo

Please see complete; in-depth demo over at JSFiddle.

like image 23
Mr. Polywhirl Avatar answered Oct 29 '22 11:10

Mr. Polywhirl