Skip to content

Instantly share code, notes, and snippets.

@centurianii
Last active September 27, 2018 11:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save centurianii/de0618291311253473214e25b1f282da to your computer and use it in GitHub Desktop.
Save centurianii/de0618291311253473214e25b1f282da to your computer and use it in GitHub Desktop.
Patch CodeMirror to trigger custom events on copy/cut to be used with a local buffer
// there are 2 patches, also see: https://github.com/codemirror/CodeMirror/issues/5594
// line 8703
function onCopyCut(e) {
if (signalDOMEvent(cm, e)) { return }
if (cm.somethingSelected()) {
setLastCopied({lineWise: false, text: cm.getSelections()})
if (e.type == "cut") { cm.replaceSelection("", null, "cut") }
} else if (!cm.options.lineWiseCopyCut) {
return
} else {
var ranges = copyableRanges(cm)
setLastCopied({lineWise: true, text: ranges.text})
if (e.type == "cut") {
cm.operation(function () {
cm.setSelections(ranges.ranges, 0, sel_dontScroll)
cm.replaceSelection("", null, "cut")
})
}
}
/* -----------
* |**patch**|
* -----------
* trigger custom event 'cut' or 'copy', just add a handler on a parent and
* look for "event.detail.data" or "event.detail.target",
* see: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events,
* https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent
*/
var event = new CustomEvent(e.type, {detail: {text: cm.getSelections(), target: cm.display.wrapper}, bubbles: true, cancelable: true});
cm.display.wrapper.dispatchEvent(event);
/* end */
if (e.clipboardData) {
e.clipboardData.clearData()
var content = lastCopied.text.join("\n")
// iOS exposes the clipboard API, but seems to discard content inserted into it
e.clipboardData.setData("Text", content)
if (e.clipboardData.getData("Text") == content) {
e.preventDefault()
return
}
}
// Old-fashioned briefly-focus-a-textarea hack
var kludge = hiddenTextarea(), te = kludge.firstChild
cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild)
te.value = lastCopied.text.join("\n")
var hadFocus = document.activeElement
selectInput(te)
setTimeout(function () {
cm.display.lineSpace.removeChild(kludge)
hadFocus.focus()
if (hadFocus == div) { input.showPrimarySelection() }
}, 50)
}
// after previous replacement look at line 9222
function prepareCopyCut(e) {
if (signalDOMEvent(cm, e)) { return }
if (cm.somethingSelected()) {
setLastCopied({lineWise: false, text: cm.getSelections()})
} else if (!cm.options.lineWiseCopyCut) {
return
} else {
var ranges = copyableRanges(cm)
setLastCopied({lineWise: true, text: ranges.text})
if (e.type == "cut") {
cm.setSelections(ranges.ranges, null, sel_dontScroll)
} else {
input.prevInput = ""
te.value = ranges.text.join("\n")
selectInput(te)
}
}
if (e.type == "cut") { cm.state.cutIncoming = true }
/* -----------
* |**patch**|
* -----------
* trigger custom event 'cut' or 'copy', just add a handler on a parent and
* look for "event.detail.data" or "event.detail.target",
* see: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events,
* https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent
*/
var event = new CustomEvent(e.type, {detail: {text: cm.getSelections(), target: te}, bubbles: true, cancelable: true});
te.parentNode.dispatchEvent(event);
/* end */
}
@centurianii
Copy link
Author

jQuery v3.1.1 has problems with event.originalEvent.detail, use addEventlistener or patch with jQuery trigger().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment