annotate .cms/lib/codemirror/src/edit/drop_events.js @ 0:78edf6b517a0 draft

24.10
author Coffee CMS <info@coffee-cms.ru>
date Fri, 11 Oct 2024 22:40:23 +0000
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
1 import { drawSelectionCursor } from "../display/selection.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
2 import { operation } from "../display/operations.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
3 import { clipPos } from "../line/pos.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
4 import { posFromMouse } from "../measurement/position_measurement.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
5 import { eventInWidget } from "../measurement/widgets.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
6 import { makeChange, replaceRange } from "../model/changes.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
7 import { changeEnd } from "../model/change_measurement.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
8 import { simpleSelection } from "../model/selection.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
9 import { setSelectionNoUndo, setSelectionReplaceHistory } from "../model/selection_updates.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
10 import { ie, presto, safari } from "../util/browser.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
11 import { elt, removeChildrenAndAdd } from "../util/dom.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
12 import { e_preventDefault, e_stop, signalDOMEvent } from "../util/event.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
13 import { indexOf } from "../util/misc.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
14
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
15 // Kludge to work around strange IE behavior where it'll sometimes
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
16 // re-fire a series of drag-related events right after the drop (#1551)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
17 let lastDrop = 0
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
18
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
19 export function onDrop(e) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
20 let cm = this
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
21 clearDragCursor(cm)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
22 if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
23 return
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
24 e_preventDefault(e)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
25 if (ie) lastDrop = +new Date
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
26 let pos = posFromMouse(cm, e, true), files = e.dataTransfer.files
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
27 if (!pos || cm.isReadOnly()) return
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
28 // Might be a file drop, in which case we simply extract the text
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
29 // and insert it.
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
30 if (files && files.length && window.FileReader && window.File) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
31 let n = files.length, text = Array(n), read = 0
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
32 const markAsReadAndPasteIfAllFilesAreRead = () => {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
33 if (++read == n) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
34 operation(cm, () => {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
35 pos = clipPos(cm.doc, pos)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
36 let change = {from: pos, to: pos,
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
37 text: cm.doc.splitLines(
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
38 text.filter(t => t != null).join(cm.doc.lineSeparator())),
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
39 origin: "paste"}
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
40 makeChange(cm.doc, change)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
41 setSelectionReplaceHistory(cm.doc, simpleSelection(clipPos(cm.doc, pos), clipPos(cm.doc, changeEnd(change))))
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
42 })()
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
43 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
44 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
45 const readTextFromFile = (file, i) => {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
46 if (cm.options.allowDropFileTypes &&
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
47 indexOf(cm.options.allowDropFileTypes, file.type) == -1) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
48 markAsReadAndPasteIfAllFilesAreRead()
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
49 return
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
50 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
51 let reader = new FileReader
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
52 reader.onerror = () => markAsReadAndPasteIfAllFilesAreRead()
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
53 reader.onload = () => {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
54 let content = reader.result
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
55 if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
56 markAsReadAndPasteIfAllFilesAreRead()
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
57 return
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
58 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
59 text[i] = content
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
60 markAsReadAndPasteIfAllFilesAreRead()
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
61 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
62 reader.readAsText(file)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
63 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
64 for (let i = 0; i < files.length; i++) readTextFromFile(files[i], i)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
65 } else { // Normal drop
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
66 // Don't do a replace if the drop happened inside of the selected text.
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
67 if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
68 cm.state.draggingText(e)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
69 // Ensure the editor is re-focused
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
70 setTimeout(() => cm.display.input.focus(), 20)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
71 return
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
72 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
73 try {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
74 let text = e.dataTransfer.getData("Text")
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
75 if (text) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
76 let selected
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
77 if (cm.state.draggingText && !cm.state.draggingText.copy)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
78 selected = cm.listSelections()
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
79 setSelectionNoUndo(cm.doc, simpleSelection(pos, pos))
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
80 if (selected) for (let i = 0; i < selected.length; ++i)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
81 replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag")
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
82 cm.replaceSelection(text, "around", "paste")
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
83 cm.display.input.focus()
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
84 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
85 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
86 catch(e){}
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
87 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
88 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
89
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
90 export function onDragStart(cm, e) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
91 if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
92 if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
93
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
94 e.dataTransfer.setData("Text", cm.getSelection())
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
95 e.dataTransfer.effectAllowed = "copyMove"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
96
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
97 // Use dummy image instead of default browsers image.
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
98 // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
99 if (e.dataTransfer.setDragImage && !safari) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
100 let img = elt("img", null, null, "position: fixed; left: 0; top: 0;")
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
101 img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
102 if (presto) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
103 img.width = img.height = 1
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
104 cm.display.wrapper.appendChild(img)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
105 // Force a relayout, or Opera won't use our image for some obscure reason
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
106 img._top = img.offsetTop
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
107 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
108 e.dataTransfer.setDragImage(img, 0, 0)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
109 if (presto) img.parentNode.removeChild(img)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
110 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
111 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
112
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
113 export function onDragOver(cm, e) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
114 let pos = posFromMouse(cm, e)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
115 if (!pos) return
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
116 let frag = document.createDocumentFragment()
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
117 drawSelectionCursor(cm, pos, frag)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
118 if (!cm.display.dragCursor) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
119 cm.display.dragCursor = elt("div", null, "CodeMirror-cursors CodeMirror-dragcursors")
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
120 cm.display.lineSpace.insertBefore(cm.display.dragCursor, cm.display.cursorDiv)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
121 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
122 removeChildrenAndAdd(cm.display.dragCursor, frag)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
123 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
124
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
125 export function clearDragCursor(cm) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
126 if (cm.display.dragCursor) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
127 cm.display.lineSpace.removeChild(cm.display.dragCursor)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
128 cm.display.dragCursor = null
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
129 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
130 }