Skip to content

Commit

Permalink
Fork info, bulid tools, prettier
Browse files Browse the repository at this point in the history
  • Loading branch information
kuba-orlik committed Aug 27, 2024
1 parent 48d159a commit e3db921
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 77 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

[![Build Status](https://github.com/codemirror/codemirror5/workflows/main/badge.svg)](https://github.com/codemirror/codemirror5/actions)

This is a Sealcode fork of CodeMirror that adds clipboard mime types information
to the paste event to enable pasting from formatted text in Sealcode's fork of
SimpleMDE (https://github.com/sealcode/sealmde-markdown-editor)

CodeMirror is a versatile text editor implemented in JavaScript for
the browser. It is specialized for editing code, and comes with over
100 language modes and various addons that implement more advanced
Expand Down
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "codemirror",
"version": "5.65.17",
"name": "sealcodemirror",
"version": "5.70-beta",
"main": "lib/codemirror.js",
"style": "lib/codemirror.css",
"author": {
Expand All @@ -26,7 +26,7 @@
"cm5-vim": "^0.0.5",
"node-static": "0.7.11",
"puppeteer": "^1.20.0",
"rollup": "^1.26.3",
"rollup": "^1.32.1",
"rollup-plugin-copy": "^3.4.0"
},
"bugs": "http://github.com/codemirror/CodeMirror/issues",
Expand All @@ -45,7 +45,6 @@
"dependencies": {},
"devDependencies": {}
},
"dependencies": {},
"publishConfig": {
"tag": "version5"
}
Expand Down
194 changes: 121 additions & 73 deletions src/input/input.js
Original file line number Diff line number Diff line change
@@ -1,134 +1,182 @@
import { runInOp } from "../display/operations.js"
import { ensureCursorVisible } from "../display/scrolling.js"
import { Pos } from "../line/pos.js"
import { getLine } from "../line/utils_line.js"
import { makeChange } from "../model/changes.js"
import { ios, webkit } from "../util/browser.js"
import { elt } from "../util/dom.js"
import { lst, map } from "../util/misc.js"
import { signalLater } from "../util/operation_group.js"
import { splitLinesAuto } from "../util/feature_detection.js"
import { runInOp } from "../display/operations.js";
import { ensureCursorVisible } from "../display/scrolling.js";
import { Pos } from "../line/pos.js";
import { getLine } from "../line/utils_line.js";
import { makeChange } from "../model/changes.js";
import { ios, webkit } from "../util/browser.js";
import { elt } from "../util/dom.js";
import { lst, map } from "../util/misc.js";
import { signalLater } from "../util/operation_group.js";
import { splitLinesAuto } from "../util/feature_detection.js";

import { indentLine } from "./indent.js"
import { indentLine } from "./indent.js";

// This will be set to a {lineWise: bool, text: [string]} object, so
// that, when pasting, we know what kind of selections the copied
// text was made out of.
export let lastCopied = null
export let lastCopied = null;

export function setLastCopied(newLastCopied) {
lastCopied = newLastCopied
lastCopied = newLastCopied;
}

export function applyTextInput(cm, inserted, deleted, sel, origin) {
let doc = cm.doc
cm.display.shift = false
if (!sel) sel = doc.sel
let doc = cm.doc;
cm.display.shift = false;
if (!sel) sel = doc.sel;

let recent = +new Date - 200
let paste = origin == "paste" || cm.state.pasteIncoming > recent
let textLines = splitLinesAuto(inserted), multiPaste = null
let recent = +new Date() - 200;
let paste = origin == "paste" || cm.state.pasteIncoming > recent;
let textLines = splitLinesAuto(inserted),
multiPaste = null;
// When pasting N lines into N selections, insert one line per selection
if (paste && sel.ranges.length > 1) {
if (lastCopied && lastCopied.text.join("\n") == inserted) {
if (sel.ranges.length % lastCopied.text.length == 0) {
multiPaste = []
multiPaste = [];
for (let i = 0; i < lastCopied.text.length; i++)
multiPaste.push(doc.splitLines(lastCopied.text[i]))
multiPaste.push(doc.splitLines(lastCopied.text[i]));
}
} else if (textLines.length == sel.ranges.length && cm.options.pasteLinesPerSelection) {
multiPaste = map(textLines, l => [l])
} else if (
textLines.length == sel.ranges.length &&
cm.options.pasteLinesPerSelection
) {
multiPaste = map(textLines, (l) => [l]);
}
}

let updateInput = cm.curOp.updateInput
let updateInput = cm.curOp.updateInput;
// Normal behavior is to insert the new text into every selection
for (let i = sel.ranges.length - 1; i >= 0; i--) {
let range = sel.ranges[i]
let from = range.from(), to = range.to()
let range = sel.ranges[i];
let from = range.from(),
to = range.to();
if (range.empty()) {
if (deleted && deleted > 0) // Handle deletion
from = Pos(from.line, from.ch - deleted)
else if (cm.state.overwrite && !paste) // Handle overwrite
to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length))
else if (paste && lastCopied && lastCopied.lineWise && lastCopied.text.join("\n") == textLines.join("\n"))
from = to = Pos(from.line, 0)
if (deleted && deleted > 0)
// Handle deletion
from = Pos(from.line, from.ch - deleted);
else if (cm.state.overwrite && !paste)
// Handle overwrite
to = Pos(
to.line,
Math.min(
getLine(doc, to.line).text.length,
to.ch + lst(textLines).length
)
);
else if (
paste &&
lastCopied &&
lastCopied.lineWise &&
lastCopied.text.join("\n") == textLines.join("\n")
)
from = to = Pos(from.line, 0);
}
let changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines,
origin: origin || (paste ? "paste" : cm.state.cutIncoming > recent ? "cut" : "+input")}
makeChange(cm.doc, changeEvent)
signalLater(cm, "inputRead", cm, changeEvent)
let changeEvent = {
from: from,
to: to,
text: multiPaste ? multiPaste[i % multiPaste.length] : textLines,
origin:
origin ||
(paste ? "paste" : cm.state.cutIncoming > recent ? "cut" : "+input"),
};
makeChange(cm.doc, changeEvent);
signalLater(cm, "inputRead", cm, changeEvent);
}
if (inserted && !paste)
triggerElectric(cm, inserted)
if (inserted && !paste) triggerElectric(cm, inserted);

ensureCursorVisible(cm)
if (cm.curOp.updateInput < 2) cm.curOp.updateInput = updateInput
cm.curOp.typing = true
cm.state.pasteIncoming = cm.state.cutIncoming = -1
ensureCursorVisible(cm);
if (cm.curOp.updateInput < 2) cm.curOp.updateInput = updateInput;
cm.curOp.typing = true;
cm.state.pasteIncoming = cm.state.cutIncoming = -1;
}

export function handlePaste(e, cm) {
let pasted = e.clipboardData && e.clipboardData.getData("Text")
console.log("Paste!", e);
let pasted = e.clipboardData && e.clipboardData.getData("Text");
if (pasted) {
e.preventDefault()
e.preventDefault();
if (!cm.isReadOnly() && !cm.options.disableInput && cm.hasFocus())
runInOp(cm, () => applyTextInput(cm, pasted, 0, null, "paste"))
return true
runInOp(cm, () => applyTextInput(cm, pasted, 0, null, "paste"));
return true;
}
}

export function triggerElectric(cm, inserted) {
// When an 'electric' character is inserted, immediately trigger a reindent
if (!cm.options.electricChars || !cm.options.smartIndent) return
let sel = cm.doc.sel
if (!cm.options.electricChars || !cm.options.smartIndent) return;
let sel = cm.doc.sel;

for (let i = sel.ranges.length - 1; i >= 0; i--) {
let range = sel.ranges[i]
if (range.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range.head.line)) continue
let mode = cm.getModeAt(range.head)
let indented = false
let range = sel.ranges[i];
if (
range.head.ch > 100 ||
(i && sel.ranges[i - 1].head.line == range.head.line)
)
continue;
let mode = cm.getModeAt(range.head);
let indented = false;
if (mode.electricChars) {
for (let j = 0; j < mode.electricChars.length; j++)
if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {
indented = indentLine(cm, range.head.line, "smart")
break
indented = indentLine(cm, range.head.line, "smart");
break;
}
} else if (mode.electricInput) {
if (mode.electricInput.test(getLine(cm.doc, range.head.line).text.slice(0, range.head.ch)))
indented = indentLine(cm, range.head.line, "smart")
if (
mode.electricInput.test(
getLine(cm.doc, range.head.line).text.slice(0, range.head.ch)
)
)
indented = indentLine(cm, range.head.line, "smart");
}
if (indented) signalLater(cm, "electricInput", cm, range.head.line)
if (indented) signalLater(cm, "electricInput", cm, range.head.line);
}
}

export function copyableRanges(cm) {
let text = [], ranges = []
let text = [],
ranges = [];
for (let i = 0; i < cm.doc.sel.ranges.length; i++) {
let line = cm.doc.sel.ranges[i].head.line
let lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)}
ranges.push(lineRange)
text.push(cm.getRange(lineRange.anchor, lineRange.head))
let line = cm.doc.sel.ranges[i].head.line;
let lineRange = { anchor: Pos(line, 0), head: Pos(line + 1, 0) };
ranges.push(lineRange);
text.push(cm.getRange(lineRange.anchor, lineRange.head));
}
return {text: text, ranges: ranges}
return { text: text, ranges: ranges };
}

export function disableBrowserMagic(field, spellcheck, autocorrect, autocapitalize) {
field.setAttribute("autocorrect", autocorrect ? "on" : "off")
field.setAttribute("autocapitalize", autocapitalize ? "on" : "off")
field.setAttribute("spellcheck", !!spellcheck)
export function disableBrowserMagic(
field,
spellcheck,
autocorrect,
autocapitalize
) {
field.setAttribute("autocorrect", autocorrect ? "on" : "off");
field.setAttribute("autocapitalize", autocapitalize ? "on" : "off");
field.setAttribute("spellcheck", !!spellcheck);
}

export function hiddenTextarea() {
let te = elt("textarea", null, null, "position: absolute; bottom: -1em; padding: 0; width: 1px; height: 1em; min-height: 1em; outline: none")
let div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;")
let te = elt(
"textarea",
null,
null,
"position: absolute; bottom: -1em; padding: 0; width: 1px; height: 1em; min-height: 1em; outline: none"
);
let div = elt(
"div",
[te],
null,
"overflow: hidden; position: relative; width: 3px; height: 0px;"
);
// The textarea is kept positioned near the cursor to prevent the
// fact that it'll be scrolled into view on input from scrolling
// our fake cursor out of view. On webkit, when wrap=off, paste is
// very slow. So make the area wide instead.
if (webkit) te.style.width = "1000px"
else te.setAttribute("wrap", "off")
if (webkit) te.style.width = "1000px";
else te.setAttribute("wrap", "off");
// If border: 0; -- iOS fails to open keyboard (issue #1287)
if (ios) te.style.border = "1px solid black"
return div
if (ios) te.style.border = "1px solid black";
return div;
}

0 comments on commit e3db921

Please sign in to comment.