pull/2/head
Raymond Hill 6 years ago
parent 956b79816b
commit d42abee957
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2

@ -1,4 +1,5 @@
# CodeMirror # CodeMirror
[![Build Status](https://travis-ci.org/codemirror/CodeMirror.svg)](https://travis-ci.org/codemirror/CodeMirror) [![Build Status](https://travis-ci.org/codemirror/CodeMirror.svg)](https://travis-ci.org/codemirror/CodeMirror)
[![NPM version](https://img.shields.io/npm/v/codemirror.svg)](https://www.npmjs.org/package/codemirror) [![NPM version](https://img.shields.io/npm/v/codemirror.svg)](https://www.npmjs.org/package/codemirror)
[![Join the chat at https://gitter.im/codemirror/CodeMirror](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/codemirror/CodeMirror) [![Join the chat at https://gitter.im/codemirror/CodeMirror](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/codemirror/CodeMirror)
@ -15,8 +16,8 @@ customizing CodeMirror to fit your application, and extending it with
new functionality. new functionality.
You can find more information (and the You can find more information (and the
[manual](http://codemirror.net/doc/manual.html)) on the [project [manual](https://codemirror.net/doc/manual.html)) on the [project
page](http://codemirror.net). For questions and discussion, use the page](https://codemirror.net). For questions and discussion, use the
[discussion forum](https://discuss.codemirror.net/). [discussion forum](https://discuss.codemirror.net/).
See See
@ -28,6 +29,19 @@ The CodeMirror community aims to be welcoming to everybody. We use the
(1.1)](http://contributor-covenant.org/version/1/1/0/) as our code of (1.1)](http://contributor-covenant.org/version/1/1/0/) as our code of
conduct. conduct.
### Installation
Either get the [zip file](https://codemirror.net/codemirror.zip) with
the latest version, or make sure you have [Node](https://nodejs.org/)
installed and run:
npm install codemirror
**NOTE**: This is the source repository for the library, and not the
distribution channel. Cloning it is not the recommended way to install
the library, and will in fact not work unless you also run the build
step.
### Quickstart ### Quickstart
To build the project, make sure you have Node.js installed (at least version 6) To build the project, make sure you have Node.js installed (at least version 6)

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE // Distributed under an MIT license: https://codemirror.net/LICENSE
// declare global: diff_match_patch, DIFF_INSERT, DIFF_DELETE, DIFF_EQUAL // declare global: diff_match_patch, DIFF_INSERT, DIFF_DELETE, DIFF_EQUAL
@ -43,6 +43,7 @@
if (!this.edit.state.trackAlignable) this.edit.state.trackAlignable = new TrackAlignable(this.edit) if (!this.edit.state.trackAlignable) this.edit.state.trackAlignable = new TrackAlignable(this.edit)
this.orig.state.trackAlignable = new TrackAlignable(this.orig) this.orig.state.trackAlignable = new TrackAlignable(this.orig)
} }
this.lockButton.title = this.edit.phrase("Toggle locked scrolling");
this.orig.state.diffViews = [this]; this.orig.state.diffViews = [this];
var classLocation = options.chunkClassLocation || "background"; var classLocation = options.chunkClassLocation || "background";
@ -500,7 +501,7 @@
var copy = dv.copyButtons.appendChild(elt("div", dv.type == "left" ? "\u21dd" : "\u21dc", var copy = dv.copyButtons.appendChild(elt("div", dv.type == "left" ? "\u21dd" : "\u21dc",
"CodeMirror-merge-copy")); "CodeMirror-merge-copy"));
var editOriginals = dv.mv.options.allowEditingOriginals; var editOriginals = dv.mv.options.allowEditingOriginals;
copy.title = editOriginals ? "Push to left" : "Revert chunk"; copy.title = dv.edit.phrase(editOriginals ? "Push to left" : "Revert chunk");
copy.chunk = chunk; copy.chunk = chunk;
copy.style.top = (chunk.origTo > chunk.origFrom ? top : dv.edit.heightAtLine(chunk.editFrom, "local") - sTopEdit) + "px"; copy.style.top = (chunk.origTo > chunk.origFrom ? top : dv.edit.heightAtLine(chunk.editFrom, "local") - sTopEdit) + "px";
@ -594,7 +595,6 @@
function buildGap(dv) { function buildGap(dv) {
var lock = dv.lockButton = elt("div", null, "CodeMirror-merge-scrolllock"); var lock = dv.lockButton = elt("div", null, "CodeMirror-merge-scrolllock");
lock.title = "Toggle locked scrolling";
var lockWrap = elt("div", [lock], "CodeMirror-merge-scrolllock-wrap"); var lockWrap = elt("div", [lock], "CodeMirror-merge-scrolllock-wrap");
CodeMirror.on(lock, "click", function() { setScrollLock(dv, !dv.lockScroll); }); CodeMirror.on(lock, "click", function() { setScrollLock(dv, !dv.lockScroll); });
var gapElts = [lockWrap]; var gapElts = [lockWrap];
@ -728,7 +728,7 @@
cm.addLineClass(from, "wrap", "CodeMirror-merge-collapsed-line"); cm.addLineClass(from, "wrap", "CodeMirror-merge-collapsed-line");
var widget = document.createElement("span"); var widget = document.createElement("span");
widget.className = "CodeMirror-merge-collapsed-widget"; widget.className = "CodeMirror-merge-collapsed-widget";
widget.title = "Identical text collapsed. Click to expand."; widget.title = cm.phrase("Identical text collapsed. Click to expand.");
var mark = cm.markText(Pos(from, 0), Pos(to - 1), { var mark = cm.markText(Pos(from, 0), Pos(to - 1), {
inclusiveLeft: true, inclusiveLeft: true,
inclusiveRight: true, inclusiveRight: true,

@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE // Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) { (function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS if (typeof exports == "object" && typeof module == "object") // CommonJS

@ -1,7 +1,7 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE // Distributed under an MIT license: https://codemirror.net/LICENSE
// This is CodeMirror (http://codemirror.net), a code editor // This is CodeMirror (https://codemirror.net), a code editor
// implemented in JavaScript on top of the browser's DOM. // implemented in JavaScript on top of the browser's DOM.
// //
// You can find some technical background for some of the code below // You can find some technical background for some of the code below
@ -746,6 +746,16 @@ function collapsedSpanAtSide(line, start) {
function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true) } function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true) }
function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false) } function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false) }
function collapsedSpanAround(line, ch) {
var sps = sawCollapsedSpans && line.markedSpans, found
if (sps) { for (var i = 0; i < sps.length; ++i) {
var sp = sps[i]
if (sp.marker.collapsed && (sp.from == null || sp.from < ch) && (sp.to == null || sp.to > ch) &&
(!found || compareCollapsedMarkers(found, sp.marker) < 0)) { found = sp.marker }
} }
return found
}
// Test whether there exists a collapsed span that partially // Test whether there exists a collapsed span that partially
// overlaps (covers the start or end, but not both) of a new span. // overlaps (covers the start or end, but not both) of a new span.
// Such overlap is not allowed. // Such overlap is not allowed.
@ -1810,7 +1820,7 @@ function buildLineContent(cm, lineView) {
var builder = {pre: eltP("pre", [content], "CodeMirror-line"), content: content, var builder = {pre: eltP("pre", [content], "CodeMirror-line"), content: content,
col: 0, pos: 0, cm: cm, col: 0, pos: 0, cm: cm,
trailingSpace: false, trailingSpace: false,
splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")} splitSpaces: cm.getOption("lineWrapping")}
lineView.measure = {} lineView.measure = {}
// Iterate over the logical lines that make up this visual line. // Iterate over the logical lines that make up this visual line.
@ -1931,6 +1941,8 @@ function buildToken(builder, text, style, startStyle, endStyle, title, css) {
builder.content.appendChild(content) builder.content.appendChild(content)
} }
// Change some spaces to NBSP to prevent the browser from collapsing
// trailing spaces at the end of a line when rendering text (issue #1362).
function splitSpaces(text, trailingBefore) { function splitSpaces(text, trailingBefore) {
if (text.length > 1 && !/ /.test(text)) { return text } if (text.length > 1 && !/ /.test(text)) { return text }
var spaceBefore = trailingBefore, result = "" var spaceBefore = trailingBefore, result = ""
@ -2778,12 +2790,11 @@ function coordsChar(cm, x, y) {
var lineObj = getLine(doc, lineN) var lineObj = getLine(doc, lineN)
for (;;) { for (;;) {
var found = coordsCharInner(cm, lineObj, lineN, x, y) var found = coordsCharInner(cm, lineObj, lineN, x, y)
var merged = collapsedSpanAtEnd(lineObj) var collapsed = collapsedSpanAround(lineObj, found.ch + (found.xRel > 0 ? 1 : 0))
var mergedPos = merged && merged.find(0, true) if (!collapsed) { return found }
if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0)) var rangeEnd = collapsed.find(1)
{ lineN = lineNo(lineObj = mergedPos.to.line) } if (rangeEnd.line == lineN) { return rangeEnd }
else lineObj = getLine(doc, lineN = rangeEnd.line)
{ return found }
} }
} }
@ -3543,6 +3554,7 @@ var NativeScrollbars = function(place, scroll, cm) {
this.cm = cm this.cm = cm
var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar") var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar")
var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar") var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar")
vert.tabIndex = horiz.tabIndex = -1
place(vert); place(horiz) place(vert); place(horiz)
on(vert, "scroll", function () { on(vert, "scroll", function () {
@ -4783,7 +4795,7 @@ function addChangeToHistory(doc, change, selAfter, opId) {
if ((hist.lastOp == opId || if ((hist.lastOp == opId ||
hist.lastOrigin == change.origin && change.origin && hist.lastOrigin == change.origin && change.origin &&
((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) || ((change.origin.charAt(0) == "+" && hist.lastModTime > time - (doc.cm ? doc.cm.options.historyEventDelay : 500)) ||
change.origin.charAt(0) == "*")) && change.origin.charAt(0) == "*")) &&
(cur = lastChangeEvent(hist, hist.lastOp == opId))) { (cur = lastChangeEvent(hist, hist.lastOp == opId))) {
// Merge this change into the last event // Merge this change into the last event
@ -5684,7 +5696,7 @@ LineWidget.prototype.changed = function () {
this.height = null this.height = null
var diff = widgetHeight(this) - oldH var diff = widgetHeight(this) - oldH
if (!diff) { return } if (!diff) { return }
updateLineHeight(line, line.height + diff) if (!lineIsHidden(this.doc, line)) { updateLineHeight(line, line.height + diff) }
if (cm) { if (cm) {
runInOp(cm, function () { runInOp(cm, function () {
cm.curOp.forceUpdate = true cm.curOp.forceUpdate = true
@ -6567,8 +6579,6 @@ function registerGlobalHandlers() {
// Called when the window resizes // Called when the window resizes
function onResize(cm) { function onResize(cm) {
var d = cm.display var d = cm.display
if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth)
{ return }
// Might be a text scaling operation, clear size caches. // Might be a text scaling operation, clear size caches.
d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null
d.scrollbarsClipped = false d.scrollbarsClipped = false
@ -6614,7 +6624,7 @@ keyMap.pcDefault = {
"Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll", "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
"Ctrl-[": "indentLess", "Ctrl-]": "indentMore", "Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
"Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection", "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection",
fallthrough: "basic" "fallthrough": "basic"
} }
// Very basic readline/emacs-style bindings, which are standard on Mac. // Very basic readline/emacs-style bindings, which are standard on Mac.
keyMap.emacsy = { keyMap.emacsy = {
@ -6632,7 +6642,7 @@ keyMap.macDefault = {
"Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll", "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
"Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight", "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight",
"Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd", "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd",
fallthrough: ["basic", "emacsy"] "fallthrough": ["basic", "emacsy"]
} }
keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault
@ -7234,8 +7244,9 @@ function onMouseDown(e) {
} }
return return
} }
if (clickInGutter(cm, e)) { return } var button = e_button(e)
var pos = posFromMouse(cm, e), button = e_button(e), repeat = pos ? clickRepeat(pos, button) : "single" if (button == 3 && captureRightClick ? contextMenuInGutter(cm, e) : clickInGutter(cm, e)) { return }
var pos = posFromMouse(cm, e), repeat = pos ? clickRepeat(pos, button) : "single"
window.focus() window.focus()
// #3261: make sure, that we're not starting a second selection // #3261: make sure, that we're not starting a second selection
@ -7312,8 +7323,8 @@ function leftButtonStartDrag(cm, event, pos, behavior) {
var dragEnd = operation(cm, function (e) { var dragEnd = operation(cm, function (e) {
if (webkit) { display.scroller.draggable = false } if (webkit) { display.scroller.draggable = false }
cm.state.draggingText = false cm.state.draggingText = false
off(document, "mouseup", dragEnd) off(display.wrapper.ownerDocument, "mouseup", dragEnd)
off(document, "mousemove", mouseMove) off(display.wrapper.ownerDocument, "mousemove", mouseMove)
off(display.scroller, "dragstart", dragStart) off(display.scroller, "dragstart", dragStart)
off(display.scroller, "drop", dragEnd) off(display.scroller, "drop", dragEnd)
if (!moved) { if (!moved) {
@ -7322,7 +7333,7 @@ function leftButtonStartDrag(cm, event, pos, behavior) {
{ extendSelection(cm.doc, pos, null, null, behavior.extend) } { extendSelection(cm.doc, pos, null, null, behavior.extend) }
// Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081) // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081)
if (webkit || ie && ie_version == 9) if (webkit || ie && ie_version == 9)
{ setTimeout(function () {document.body.focus(); display.input.focus()}, 20) } { setTimeout(function () {display.wrapper.ownerDocument.body.focus(); display.input.focus()}, 20) }
else else
{ display.input.focus() } { display.input.focus() }
} }
@ -7337,8 +7348,8 @@ function leftButtonStartDrag(cm, event, pos, behavior) {
dragEnd.copy = !behavior.moveOnDrag dragEnd.copy = !behavior.moveOnDrag
// IE's approach to draggable // IE's approach to draggable
if (display.scroller.dragDrop) { display.scroller.dragDrop() } if (display.scroller.dragDrop) { display.scroller.dragDrop() }
on(document, "mouseup", dragEnd) on(display.wrapper.ownerDocument, "mouseup", dragEnd)
on(document, "mousemove", mouseMove) on(display.wrapper.ownerDocument, "mousemove", mouseMove)
on(display.scroller, "dragstart", dragStart) on(display.scroller, "dragstart", dragStart)
on(display.scroller, "drop", dragEnd) on(display.scroller, "drop", dragEnd)
@ -7470,19 +7481,19 @@ function leftButtonSelect(cm, event, start, behavior) {
counter = Infinity counter = Infinity
e_preventDefault(e) e_preventDefault(e)
display.input.focus() display.input.focus()
off(document, "mousemove", move) off(display.wrapper.ownerDocument, "mousemove", move)
off(document, "mouseup", up) off(display.wrapper.ownerDocument, "mouseup", up)
doc.history.lastSelOrigin = null doc.history.lastSelOrigin = null
} }
var move = operation(cm, function (e) { var move = operation(cm, function (e) {
if (!e_button(e)) { done(e) } if (e.buttons === 0 || !e_button(e)) { done(e) }
else { extend(e) } else { extend(e) }
}) })
var up = operation(cm, done) var up = operation(cm, done)
cm.state.selectingText = up cm.state.selectingText = up
on(document, "mousemove", move) on(display.wrapper.ownerDocument, "mousemove", move)
on(document, "mouseup", up) on(display.wrapper.ownerDocument, "mouseup", up)
} }
// Used when mouse-selecting to adjust the anchor to the proper side // Used when mouse-selecting to adjust the anchor to the proper side
@ -7714,6 +7725,7 @@ function defineOptions(CodeMirror) {
option("tabindex", null, function (cm, val) { return cm.display.input.getField().tabIndex = val || ""; }) option("tabindex", null, function (cm, val) { return cm.display.input.getField().tabIndex = val || ""; })
option("autofocus", null) option("autofocus", null)
option("direction", "ltr", function (cm, val) { return cm.doc.setDirection(val); }, true) option("direction", "ltr", function (cm, val) { return cm.doc.setDirection(val); }, true)
option("phrases", null)
} }
function guttersChanged(cm) { function guttersChanged(cm) {
@ -7765,6 +7777,7 @@ function CodeMirror(place, options) {
var doc = options.value var doc = options.value
if (typeof doc == "string") { doc = new Doc(doc, options.mode, null, options.lineSeparator, options.direction) } if (typeof doc == "string") { doc = new Doc(doc, options.mode, null, options.lineSeparator, options.direction) }
else if (options.mode) { doc.modeOption = options.mode }
this.doc = doc this.doc = doc
var input = new CodeMirror.inputStyles[options.inputStyle](this) var input = new CodeMirror.inputStyles[options.inputStyle](this)
@ -8551,6 +8564,11 @@ function addEditorMethods(CodeMirror) {
return old return old
}), }),
phrase: function(phraseText) {
var phrases = this.options.phrases
return phrases && Object.prototype.hasOwnProperty.call(phrases, phraseText) ? phrases[phraseText] : phraseText
},
getInputField: function(){return this.display.input.getField()}, getInputField: function(){return this.display.input.getField()},
getWrapperElement: function(){return this.display.wrapper}, getWrapperElement: function(){return this.display.wrapper},
getScrollerElement: function(){return this.display.scroller}, getScrollerElement: function(){return this.display.scroller},
@ -8755,8 +8773,12 @@ ContentEditableInput.prototype.showSelection = function (info, takeFocus) {
this.showMultipleSelections(info) this.showMultipleSelections(info)
}; };
ContentEditableInput.prototype.getSelection = function () {
return this.cm.display.wrapper.ownerDocument.getSelection()
};
ContentEditableInput.prototype.showPrimarySelection = function () { ContentEditableInput.prototype.showPrimarySelection = function () {
var sel = window.getSelection(), cm = this.cm, prim = cm.doc.sel.primary() var sel = this.getSelection(), cm = this.cm, prim = cm.doc.sel.primary()
var from = prim.from(), to = prim.to() var from = prim.from(), to = prim.to()
if (cm.display.viewTo == cm.display.viewFrom || from.line >= cm.display.viewTo || to.line < cm.display.viewFrom) { if (cm.display.viewTo == cm.display.viewFrom || from.line >= cm.display.viewTo || to.line < cm.display.viewFrom) {
@ -8823,13 +8845,13 @@ ContentEditableInput.prototype.showMultipleSelections = function (info) {
}; };
ContentEditableInput.prototype.rememberSelection = function () { ContentEditableInput.prototype.rememberSelection = function () {
var sel = window.getSelection() var sel = this.getSelection()
this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset
this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset
}; };
ContentEditableInput.prototype.selectionInEditor = function () { ContentEditableInput.prototype.selectionInEditor = function () {
var sel = window.getSelection() var sel = this.getSelection()
if (!sel.rangeCount) { return false } if (!sel.rangeCount) { return false }
var node = sel.getRangeAt(0).commonAncestorContainer var node = sel.getRangeAt(0).commonAncestorContainer
return contains(this.div, node) return contains(this.div, node)
@ -8864,14 +8886,14 @@ ContentEditableInput.prototype.receivedFocus = function () {
}; };
ContentEditableInput.prototype.selectionChanged = function () { ContentEditableInput.prototype.selectionChanged = function () {
var sel = window.getSelection() var sel = this.getSelection()
return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset || return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset ||
sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset
}; };
ContentEditableInput.prototype.pollSelection = function () { ContentEditableInput.prototype.pollSelection = function () {
if (this.readDOMTimeout != null || this.gracePeriod || !this.selectionChanged()) { return } if (this.readDOMTimeout != null || this.gracePeriod || !this.selectionChanged()) { return }
var sel = window.getSelection(), cm = this.cm var sel = this.getSelection(), cm = this.cm
// On Android Chrome (version 56, at least), backspacing into an // On Android Chrome (version 56, at least), backspacing into an
// uneditable block element will put the cursor in that element, // uneditable block element will put the cursor in that element,
// and then, because it's not editable, hide the virtual keyboard. // and then, because it's not editable, hide the virtual keyboard.
@ -9005,7 +9027,7 @@ ContentEditableInput.prototype.setUneditable = function (node) {
}; };
ContentEditableInput.prototype.onKeyPress = function (e) { ContentEditableInput.prototype.onKeyPress = function (e) {
if (e.charCode == 0) { return } if (e.charCode == 0 || this.composing) { return }
e.preventDefault() e.preventDefault()
if (!this.cm.isReadOnly()) if (!this.cm.isReadOnly())
{ operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0) } { operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0) }
@ -9045,12 +9067,13 @@ function isInGutter(node) {
function badPos(pos, bad) { if (bad) { pos.bad = true; } return pos } function badPos(pos, bad) { if (bad) { pos.bad = true; } return pos }
function domTextBetween(cm, from, to, fromLine, toLine) { function domTextBetween(cm, from, to, fromLine, toLine) {
var text = "", closing = false, lineSep = cm.doc.lineSeparator() var text = "", closing = false, lineSep = cm.doc.lineSeparator(), extraLinebreak = false
function recognizeMarker(id) { return function (marker) { return marker.id == id; } } function recognizeMarker(id) { return function (marker) { return marker.id == id; } }
function close() { function close() {
if (closing) { if (closing) {
text += lineSep text += lineSep
closing = false if (extraLinebreak) { text += lineSep }
closing = extraLinebreak = false
} }
} }
function addText(str) { function addText(str) {
@ -9062,8 +9085,8 @@ function domTextBetween(cm, from, to, fromLine, toLine) {
function walk(node) { function walk(node) {
if (node.nodeType == 1) { if (node.nodeType == 1) {
var cmText = node.getAttribute("cm-text") var cmText = node.getAttribute("cm-text")
if (cmText != null) { if (cmText) {
addText(cmText || node.textContent.replace(/\u200b/g, "")) addText(cmText)
return return
} }
var markerID = node.getAttribute("cm-marker"), range var markerID = node.getAttribute("cm-marker"), range
@ -9074,19 +9097,24 @@ function domTextBetween(cm, from, to, fromLine, toLine) {
return return
} }
if (node.getAttribute("contenteditable") == "false") { return } if (node.getAttribute("contenteditable") == "false") { return }
var isBlock = /^(pre|div|p)$/i.test(node.nodeName) var isBlock = /^(pre|div|p|li|table|br)$/i.test(node.nodeName)
if (!/^br$/i.test(node.nodeName) && node.textContent.length == 0) { return }
if (isBlock) { close() } if (isBlock) { close() }
for (var i = 0; i < node.childNodes.length; i++) for (var i = 0; i < node.childNodes.length; i++)
{ walk(node.childNodes[i]) } { walk(node.childNodes[i]) }
if (/^(pre|p)$/i.test(node.nodeName)) { extraLinebreak = true }
if (isBlock) { closing = true } if (isBlock) { closing = true }
} else if (node.nodeType == 3) { } else if (node.nodeType == 3) {
addText(node.nodeValue) addText(node.nodeValue.replace(/\u200b/g, "").replace(/\u00a0/g, " "))
} }
} }
for (;;) { for (;;) {
walk(from) walk(from)
if (from == to) { break } if (from == to) { break }
from = from.nextSibling from = from.nextSibling
extraLinebreak = false
} }
return text return text
} }
@ -9187,13 +9215,10 @@ TextareaInput.prototype.init = function (display) {
var this$1 = this; var this$1 = this;
var input = this, cm = this.cm var input = this, cm = this.cm
this.createField(display)
var te = this.textarea
// Wraps and hides input textarea display.wrapper.insertBefore(this.wrapper, display.wrapper.firstChild)
var div = this.wrapper = hiddenTextarea()
// The semihidden textarea that is focused when the editor is
// focused, and receives input.
var te = this.textarea = div.firstChild
display.wrapper.insertBefore(div, display.wrapper.firstChild)
// Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore) // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore)
if (ios) { te.style.width = "0px" } if (ios) { te.style.width = "0px" }
@ -9260,6 +9285,14 @@ TextareaInput.prototype.init = function (display) {
}) })
}; };
TextareaInput.prototype.createField = function (_display) {
// Wraps and hides input textarea
this.wrapper = hiddenTextarea()
// The semihidden textarea that is focused when the editor is
// focused, and receives input.
this.textarea = this.wrapper.firstChild
};
TextareaInput.prototype.prepareSelection = function () { TextareaInput.prototype.prepareSelection = function () {
// Redraw the selection and/or cursor // Redraw the selection and/or cursor
var cm = this.cm, display = cm.display, doc = cm.doc var cm = this.cm, display = cm.display, doc = cm.doc
@ -9653,7 +9686,7 @@ CodeMirror.fromTextArea = fromTextArea
addLegacyProps(CodeMirror) addLegacyProps(CodeMirror)
CodeMirror.version = "5.35.0" CodeMirror.version = "5.40.2"
return CodeMirror; return CodeMirror;

Loading…
Cancel
Save