codemirror是否提供剪切,复制和粘贴API?

时间:2012-02-29 02:38:07

标签: codemirror

http://codemirror.net/doc/manual.html开始,我只找到getRange(), undo(),redo()等,我找不到cut(),copy()和粘贴API, 当我尝试运行editor.execCommand("cut")时,我得到错误。 你可以帮帮我吗?谢谢!

3 个答案:

答案 0 :(得分:9)

使用clipboard.js,您可以定义text()函数来获取CodeMirror内部文档的值。

为方便起见,存储对(<textarea>)编辑器选择器的引用。

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

参考您的按钮实例化一个新的ClipBoard对象。

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

通过原生JavaScript检索CodeMirror实例。

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;
};

演示

请看完整;在JSFiddle进行深入演示。

答案 1 :(得分:2)

没有用于剪切/复制/粘贴的CodeMirror API,因为浏览器安全限制禁止JavaScript以编程方式访问剪贴板。粘贴可用于窃取私人数据,剪切/复制可用作more elaborate attack vector

浏览器自己的本机代码仅根据当前选定的文本或焦点文本字段处理访问剪贴板的用户手势(键盘快捷键和上下文菜单项)。

This SO thread对尝试解决这些限制有很好的总结。 CodeMirror的方法是第一个方法:它使用隐藏的textarea来确保用户剪贴板手势工作,但仍然不支持编程API。

但是部分解决方法:使用一个小的Flash小部件(这是上面线程中的第二个子弹)。复制/剪切(但不粘贴)时闪烁relaxes the restrictions。它仍然必须由某些用户事件触发,但它可能类似于单击HTML UI中的按钮。像ZeroClipboardClippy这样的包装使得访问这些功能变得简单,而无需了解Flash。你需要编写一些胶水代码,以便在复制时从CodeMirror中提取相应的字符串,但这不应该太糟糕。

答案 2 :(得分:1)

将隐藏的内容可编辑div添加到textarea编辑器包装器中。可内容编辑的div尊重复制代码时我们需要的新行和新标签。

这是我的CodePen demo

var content = $('.content');
var toCopy = content.find('.copy-this');
// initialize the editor
var editorOptions = {
  autoRefresh: true,
  firstLineNumber: 1,
  lineNumbers: true,
  smartIndent: true,
  lineWrapping: true,
  indentWithTabs: true,
  refresh: true,
  mode: 'javascript'
};
var editor = CodeMirror.fromTextArea(content.find(".editor")[0], editorOptions);
content[0].editor = editor;
editor.save();

// set editors value from the textarea
var text = content.find('.editor').text();
editor.setValue(text);

// setting with editor.getValue() so that it respects \n and \t
toCopy.text(editor.getValue());

$(document).on('click', '.copy-code', function() {
  var content = $(this).closest('.content');
  var editor = content[0].editor;
  var toCopy = content.find('.copy-this')[0];

  var innerText = toCopy.innerText  // using innerText here because it preserves newlines

  // write the text to the clipboard
  navigator.clipboard.writeText(innerText);

});
.content {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.CodeMirror {
  height: fit-content !important;
}
.copy-code {
  background: #339af0;
  width: fit-content;
  cursor: pointer;
}
<!-- resources -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.35.0/codemirror.css" />
<script src="https://codemirror.net/lib/codemirror.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.40.0/mode/javascript/javascript.min.js"></script>
<script src=""></script>
<script src=""></script>
<script src=""></script>
<script src=""></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<div class="content">
  <!-- button to copy the editor -->
  <div class="copy-code" title="copy code">copy</div>
  <!-- add contenteditable div as it respects new lines when copying unlike textarea -->
  <div class="copy-this" contenteditable style="display: none"></div>
  <textarea class="editor" style="display: none;">// here is a comment
// here is another comment 
  </textarea>
</div>