@@ -1,7 +1,7 @@ | |||
// CodeMirror, copyright (c) by Marijn Haverbeke and others | |||
// Distributed under an MIT license: https://codemirror.net/LICENSE | |||
// Distributed under an MIT license: https://codemirror.net/5/LICENSE | |||
// This is CodeMirror (https://codemirror.net), a code editor | |||
// This is CodeMirror (https://codemirror.net/5), a code editor | |||
// implemented in JavaScript on top of the browser's DOM. | |||
// | |||
// You can find some technical background for some of the code below | |||
@@ -26,7 +26,8 @@ | |||
var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : +(edge || ie_11up)[1]); | |||
var webkit = !edge && /WebKit\//.test(userAgent); | |||
var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent); | |||
var chrome = !edge && /Chrome\//.test(userAgent); | |||
var chrome = !edge && /Chrome\/(\d+)/.exec(userAgent); | |||
var chrome_version = chrome && +chrome[1]; | |||
var presto = /Opera\//.test(userAgent); | |||
var safari = /Apple Computer/.test(navigator.vendor); | |||
var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent); | |||
@@ -111,15 +112,15 @@ | |||
} while (child = child.parentNode) | |||
} | |||
function activeElt() { | |||
function activeElt(doc) { | |||
// IE and Edge may throw an "Unspecified Error" when accessing document.activeElement. | |||
// IE < 10 will throw when accessed while the page is loading or in an iframe. | |||
// IE > 9 and Edge will throw when accessed in an iframe if document.body is unavailable. | |||
var activeElement; | |||
try { | |||
activeElement = document.activeElement; | |||
activeElement = doc.activeElement; | |||
} catch(e) { | |||
activeElement = document.body || null; | |||
activeElement = doc.body || null; | |||
} | |||
while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement) | |||
{ activeElement = activeElement.shadowRoot.activeElement; } | |||
@@ -143,6 +144,10 @@ | |||
else if (ie) // Suppress mysterious IE10 errors | |||
{ selectInput = function(node) { try { node.select(); } catch(_e) {} }; } | |||
function doc(cm) { return cm.display.wrapper.ownerDocument } | |||
function win(cm) { return doc(cm).defaultView } | |||
function bind(f) { | |||
var args = Array.prototype.slice.call(arguments, 1); | |||
return function(){return f.apply(null, args)} | |||
@@ -1543,7 +1548,7 @@ | |||
var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker); | |||
if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) { continue } | |||
if (fromCmp <= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.to, from) >= 0 : cmp(found.to, from) > 0) || | |||
FROMCmp >= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.from, to) <= 0 : cmp(found.from, to) < 0)) | |||
fromCmp >= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.from, to) <= 0 : cmp(found.from, to) < 0)) | |||
{ return true } | |||
} } | |||
} | |||
@@ -2572,16 +2577,16 @@ | |||
cm.display.lineNumChars = null; | |||
} | |||
function pageScrollX() { | |||
function pageScrollX(doc) { | |||
// Work around https://bugs.chromium.org/p/chromium/issues/detail?id=489206 | |||
// which causes page_Offset and bounding client rects to use | |||
// different reference viewports and invalidate our calculations. | |||
if (chrome && android) { return -(document.body.getBoundingClientRect().left - parseInt(getComputedStyle(document.body).marginLeft)) } | |||
return window.pageXOffset || (document.documentElement || document.body).scrollLeft | |||
if (chrome && android) { return -(doc.body.getBoundingClientRect().left - parseInt(getComputedStyle(doc.body).marginLeft)) } | |||
return doc.defaultView.pageXOffset || (doc.documentElement || doc.body).scrollLeft | |||
} | |||
function pageScrollY() { | |||
if (chrome && android) { return -(document.body.getBoundingClientRect().top - parseInt(getComputedStyle(document.body).marginTop)) } | |||
return window.pageYOffset || (document.documentElement || document.body).scrollTop | |||
function pageScrollY(doc) { | |||
if (chrome && android) { return -(doc.body.getBoundingClientRect().top - parseInt(getComputedStyle(doc.body).marginTop)) } | |||
return doc.defaultView.pageYOffset || (doc.documentElement || doc.body).scrollTop | |||
} | |||
function widgetTopHeight(lineObj) { | |||
@@ -2609,8 +2614,8 @@ | |||
else { yOff -= cm.display.viewOffset; } | |||
if (context == "page" || context == "window") { | |||
var lOff = cm.display.lineSpace.getBoundingClientRect(); | |||
yOff += lOff.top + (context == "window" ? 0 : pageScrollY()); | |||
var xOff = lOff.left + (context == "window" ? 0 : pageScrollX()); | |||
yOff += lOff.top + (context == "window" ? 0 : pageScrollY(doc(cm))); | |||
var xOff = lOff.left + (context == "window" ? 0 : pageScrollX(doc(cm))); | |||
rect.left += xOff; rect.right += xOff; | |||
} | |||
rect.top += yOff; rect.bottom += yOff; | |||
@@ -2624,8 +2629,8 @@ | |||
var left = coords.left, top = coords.top; | |||
// First move into "page" coordinate system | |||
if (context == "page") { | |||
left -= pageScrollX(); | |||
top -= pageScrollY(); | |||
left -= pageScrollX(doc(cm)); | |||
top -= pageScrollY(doc(cm)); | |||
} else if (context == "local" || !context) { | |||
var localBox = cm.display.sizer.getBoundingClientRect(); | |||
left += localBox.left; | |||
@@ -3423,10 +3428,10 @@ | |||
if (viewport && viewport.ensure) { | |||
var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line; | |||
if (ensureFrom < from) { | |||
FROM = ensureFrom; | |||
from = ensureFrom; | |||
to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight); | |||
} else if (Math.min(ensureTo, doc.lastLine()) >= to) { | |||
FROM = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight); | |||
from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight); | |||
to = ensureTo; | |||
} | |||
} | |||
@@ -3441,8 +3446,9 @@ | |||
if (signalDOMEvent(cm, "scrollCursorIntoView")) { return } | |||
var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null; | |||
var doc = display.wrapper.ownerDocument; | |||
if (rect.top + box.top < 0) { doScroll = true; } | |||
else if (rect.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) { doScroll = false; } | |||
else if (rect.bottom + box.top > (doc.defaultView.innerHeight || doc.documentElement.clientHeight)) { doScroll = false; } | |||
if (doScroll != null && !phantom) { | |||
var scrollNode = elt("div", "\u200b", null, ("position: absolute;\n top: " + (rect.top - display.viewOffset - paddingTop(cm.display)) + "px;\n height: " + (rect.bottom - rect.top + scrollGap(cm) + display.barHeight) + "px;\n left: " + (rect.left) + "px; width: " + (Math.max(2, rect.right - rect.left)) + "px;")); | |||
cm.display.lineSpace.appendChild(scrollNode); | |||
@@ -3696,13 +3702,13 @@ | |||
NativeScrollbars.prototype.zeroWidthHack = function () { | |||
var w = mac && !mac_geMountainLion ? "12px" : "18px"; | |||
this.horiz.style.height = this.vert.style.width = w; | |||
this.horiz.style.pointerEvents = this.vert.style.pointerEvents = "none"; | |||
this.horiz.style.visibility = this.vert.style.visibility = "hidden"; | |||
this.disableHoriz = new Delayed; | |||
this.disableVert = new Delayed; | |||
}; | |||
NativeScrollbars.prototype.enableZeroWidthBar = function (bar, delay, type) { | |||
bar.style.pointerEvents = "auto"; | |||
bar.style.visibility = ""; | |||
function maybeDisable() { | |||
// To find out whether the scrollbar is still visible, we | |||
// check whether the element under the pixel in the bottom | |||
@@ -3713,7 +3719,7 @@ | |||
var box = bar.getBoundingClientRect(); | |||
var elt = type == "vert" ? document.elementFromPoint(box.right - 1, (box.top + box.bottom) / 2) | |||
: document.elementFromPoint((box.right + box.left) / 2, box.bottom - 1); | |||
if (elt != bar) { bar.style.pointerEvents = "none"; } | |||
if (elt != bar) { bar.style.visibility = "hidden"; } | |||
else { delay.set(1000, maybeDisable); } | |||
} | |||
delay.set(1000, maybeDisable); | |||
@@ -3894,7 +3900,7 @@ | |||
cm.display.maxLineChanged = false; | |||
} | |||
var takeFocus = op.focus && op.focus == activeElt(); | |||
var takeFocus = op.focus && op.focus == activeElt(doc(cm)); | |||
if (op.preparedSelection) | |||
{ cm.display.input.showSelection(op.preparedSelection, takeFocus); } | |||
if (op.updatedDisplay || op.startHeight != cm.doc.height) | |||
@@ -4071,11 +4077,11 @@ | |||
function selectionSnapshot(cm) { | |||
if (cm.hasFocus()) { return null } | |||
var active = activeElt(); | |||
var active = activeElt(doc(cm)); | |||
if (!active || !contains(cm.display.lineDiv, active)) { return null } | |||
var result = {activeElt: active}; | |||
if (window.getSelection) { | |||
var sel = window.getSelection(); | |||
var sel = win(cm).getSelection(); | |||
if (sel.anchorNode && sel.extend && contains(cm.display.lineDiv, sel.anchorNode)) { | |||
result.anchorNode = sel.anchorNode; | |||
result.anchorOffset = sel.anchorOffset; | |||
@@ -4087,11 +4093,12 @@ | |||
} | |||
function restoreSelection(snapshot) { | |||
if (!snapshot || !snapshot.activeElt || snapshot.activeElt == activeElt()) { return } | |||
if (!snapshot || !snapshot.activeElt || snapshot.activeElt == activeElt(snapshot.activeElt.ownerDocument)) { return } | |||
snapshot.activeElt.focus(); | |||
if (!/^(INPUT|TEXTAREA)$/.test(snapshot.activeElt.nodeName) && | |||
snapshot.anchorNode && contains(document.body, snapshot.anchorNode) && contains(document.body, snapshot.focusNode)) { | |||
var sel = window.getSelection(), range = document.createRange(); | |||
var doc = snapshot.activeElt.ownerDocument; | |||
var sel = doc.defaultView.getSelection(), range = doc.createRange(); | |||
range.setEnd(snapshot.anchorNode, snapshot.anchorOffset); | |||
range.collapse(false); | |||
sel.removeAllRanges(); | |||
@@ -4130,7 +4137,7 @@ | |||
if (display.viewFrom < from && from - display.viewFrom < 20) { from = Math.max(doc.first, display.viewFrom); } | |||
if (display.viewTo > to && display.viewTo - to < 20) { to = Math.min(end, display.viewTo); } | |||
if (sawCollapsedSpans) { | |||
FROM = visualLineNo(cm.doc, from); | |||
from = visualLineNo(cm.doc, from); | |||
to = visualLineEndNo(cm.doc, to); | |||
} | |||
@@ -4408,6 +4415,8 @@ | |||
d.scroller.setAttribute("tabIndex", "-1"); | |||
// The element in which the editor lives. | |||
d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror"); | |||
// See #6982. FIXME remove when this has been fixed for a while in Chrome | |||
if (chrome && chrome_version >= 105) { d.wrapper.style.clipPath = "inset(0px)"; } | |||
// This attribute is respected by automatic translation systems such as Google Translate, | |||
// and may also be respected by tools used by human translators. | |||
@@ -4509,6 +4518,17 @@ | |||
} | |||
function onScrollWheel(cm, e) { | |||
// On Chrome 102, viewport updates somehow stop wheel-based | |||
// scrolling. Turning off pointer events during the scroll seems | |||
// to avoid the issue. | |||
if (chrome && chrome_version == 102) { | |||
if (cm.display.chromeScrollHack == null) { cm.display.sizer.style.pointerEvents = "none"; } | |||
else { clearTimeout(cm.display.chromeScrollHack); } | |||
cm.display.chromeScrollHack = setTimeout(function () { | |||
cm.display.chromeScrollHack = null; | |||
cm.display.sizer.style.pointerEvents = ""; | |||
}, 100); | |||
} | |||
var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y; | |||
var pixelsPerUnit = wheelPixelsPerUnit; | |||
if (e.deltaMode === 0) { | |||
@@ -5192,7 +5212,7 @@ | |||
var range = sel.ranges[i]; | |||
var old = sel.ranges.length == doc.sel.ranges.length && doc.sel.ranges[i]; | |||
var newAnchor = skipAtomic(doc, range.anchor, old && old.anchor, bias, mayClear); | |||
var newHead = skipAtomic(doc, range.head, old && old.head, bias, mayClear); | |||
var newHead = range.head == range.anchor ? newAnchor : skipAtomic(doc, range.head, old && old.head, bias, mayClear); | |||
if (out || newAnchor != range.anchor || newHead != range.head) { | |||
if (!out) { out = sel.ranges.slice(0, i); } | |||
out[i] = new Range(newAnchor, newHead); | |||
@@ -5276,7 +5296,7 @@ | |||
function filterChange(doc, change, update) { | |||
var obj = { | |||
canceled: false, | |||
FROM: change.from, | |||
from: change.from, | |||
to: change.to, | |||
text: change.text, | |||
origin: change.origin, | |||
@@ -5515,7 +5535,7 @@ | |||
var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change"); | |||
if (changeHandler || changesHandler) { | |||
var obj = { | |||
FROM: from, to: to, | |||
from: from, to: to, | |||
text: change.text, | |||
removed: change.removed, | |||
origin: change.origin | |||
@@ -5911,7 +5931,7 @@ | |||
var line = this.lines[i]; | |||
var span = getMarkedSpanFor(line.markedSpans, this); | |||
if (span.from != null) { | |||
FROM = Pos(lineObj ? line : lineNo(line), span.from); | |||
from = Pos(lineObj ? line : lineNo(line), span.from); | |||
if (side == -1) { return from } | |||
} | |||
if (span.to != null) { | |||
@@ -5989,7 +6009,7 @@ | |||
} | |||
if (marker.collapsed) { | |||
if (conflictingCollapsedRange(doc, from.line, from, to, marker) || | |||
FROM.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker)) | |||
from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker)) | |||
{ throw new Error("Inserting collapsed marker partially overlapping an existing one") } | |||
seeCollapsedSpans(); | |||
} | |||
@@ -6169,7 +6189,7 @@ | |||
setSelection(this, simpleSelection(top), sel_dontScroll); | |||
}), | |||
replaceRange: function(code, from, to, origin) { | |||
FROM = clipPos(this, from); | |||
from = clipPos(this, from); | |||
to = to ? clipPos(this, to) : from; | |||
replaceRange(this, code, from, to, origin); | |||
}, | |||
@@ -6413,7 +6433,7 @@ | |||
return markers | |||
}, | |||
findMarks: function(from, to, filter) { | |||
FROM = clipPos(this, from); to = clipPos(this, to); | |||
from = clipPos(this, from); to = clipPos(this, to); | |||
var found = [], lineNo = from.line; | |||
this.iter(from.line, to.line + 1, function (line) { | |||
var spans = line.markedSpans; | |||
@@ -6997,11 +7017,11 @@ | |||
} | |||
}); }, | |||
deleteLine: function (cm) { return deleteNearSelection(cm, function (range) { return ({ | |||
FROM: Pos(range.from().line, 0), | |||
from: Pos(range.from().line, 0), | |||
to: clipPos(cm.doc, Pos(range.to().line + 1, 0)) | |||
}); }); }, | |||
delLineLeft: function (cm) { return deleteNearSelection(cm, function (range) { return ({ | |||
FROM: Pos(range.from().line, 0), to: range.from() | |||
from: Pos(range.from().line, 0), to: range.from() | |||
}); }); }, | |||
delWrappedLineLeft: function (cm) { return deleteNearSelection(cm, function (range) { | |||
var top = cm.charCoords(range.head, "div").top + 5; | |||
@@ -7244,7 +7264,7 @@ | |||
function onKeyDown(e) { | |||
var cm = this; | |||
if (e.target && e.target != cm.display.input.getField()) { return } | |||
cm.curOp.focus = activeElt(); | |||
cm.curOp.focus = activeElt(doc(cm)); | |||
if (signalDOMEvent(cm, e)) { return } | |||
// IE does strange things with escape. | |||
if (ie && ie_version < 11 && e.keyCode == 27) { e.returnValue = false; } | |||
@@ -7351,7 +7371,7 @@ | |||
} | |||
if (clickInGutter(cm, e)) { return } | |||
var pos = posFromMouse(cm, e), button = e_button(e), repeat = pos ? clickRepeat(pos, button) : "single"; | |||
window.focus(); | |||
win(cm).focus(); | |||
// #3261: make sure, that we're not starting a second selection | |||
if (button == 1 && cm.state.selectingText) | |||
@@ -7406,7 +7426,7 @@ | |||
function leftButtonDown(cm, pos, repeat, event) { | |||
if (ie) { setTimeout(bind(ensureFocus, cm), 0); } | |||
else { cm.curOp.focus = activeElt(); } | |||
else { cm.curOp.focus = activeElt(doc(cm)); } | |||
var behavior = configureMouse(cm, repeat, event); | |||
@@ -7476,19 +7496,19 @@ | |||
// Normal selection, as opposed to text dragging. | |||
function leftButtonSelect(cm, event, start, behavior) { | |||
if (ie) { delayBlurEvent(cm); } | |||
var display = cm.display, doc = cm.doc; | |||
var display = cm.display, doc$1 = cm.doc; | |||
e_preventDefault(event); | |||
var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges; | |||
var ourRange, ourIndex, startSel = doc$1.sel, ranges = startSel.ranges; | |||
if (behavior.addNew && !behavior.extend) { | |||
ourIndex = doc.sel.contains(start); | |||
ourIndex = doc$1.sel.contains(start); | |||
if (ourIndex > -1) | |||
{ ourRange = ranges[ourIndex]; } | |||
else | |||
{ ourRange = new Range(start, start); } | |||
} else { | |||
ourRange = doc.sel.primary(); | |||
ourIndex = doc.sel.primIndex; | |||
ourRange = doc$1.sel.primary(); | |||
ourIndex = doc$1.sel.primIndex; | |||
} | |||
if (behavior.unit == "rectangle") { | |||
@@ -7505,18 +7525,18 @@ | |||
if (!behavior.addNew) { | |||
ourIndex = 0; | |||
setSelection(doc, new Selection([ourRange], 0), sel_mouse); | |||
startSel = doc.sel; | |||
setSelection(doc$1, new Selection([ourRange], 0), sel_mouse); | |||
startSel = doc$1.sel; | |||
} else if (ourIndex == -1) { | |||
ourIndex = ranges.length; | |||
setSelection(doc, normalizeSelection(cm, ranges.concat([ourRange]), ourIndex), | |||
setSelection(doc$1, normalizeSelection(cm, ranges.concat([ourRange]), ourIndex), | |||
{scroll: false, origin: "*mouse"}); | |||
} else if (ranges.length > 1 && ranges[ourIndex].empty() && behavior.unit == "char" && !behavior.extend) { | |||
setSelection(doc, normalizeSelection(cm, ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0), | |||
setSelection(doc$1, normalizeSelection(cm, ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0), | |||
{scroll: false, origin: "*mouse"}); | |||
startSel = doc.sel; | |||
startSel = doc$1.sel; | |||
} else { | |||
replaceOneSelection(doc, ourIndex, ourRange, sel_mouse); | |||
replaceOneSelection(doc$1, ourIndex, ourRange, sel_mouse); | |||
} | |||
var lastPos = start; | |||
@@ -7526,19 +7546,19 @@ | |||
if (behavior.unit == "rectangle") { | |||
var ranges = [], tabSize = cm.options.tabSize; | |||
var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize); | |||
var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize); | |||
var startCol = countColumn(getLine(doc$1, start.line).text, start.ch, tabSize); | |||
var posCol = countColumn(getLine(doc$1, pos.line).text, pos.ch, tabSize); | |||
var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol); | |||
for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line)); | |||
line <= end; line++) { | |||
var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize); | |||
var text = getLine(doc$1, line).text, leftPos = findColumn(text, left, tabSize); | |||
if (left == right) | |||
{ ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))); } | |||
else if (text.length > leftPos) | |||
{ ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))); } | |||
} | |||
if (!ranges.length) { ranges.push(new Range(start, start)); } | |||
setSelection(doc, normalizeSelection(cm, startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex), | |||
setSelection(doc$1, normalizeSelection(cm, startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex), | |||
{origin: "*mouse", scroll: false}); | |||
cm.scrollIntoView(pos); | |||
} else { | |||
@@ -7553,8 +7573,8 @@ | |||
anchor = maxPos(oldRange.to(), range.head); | |||
} | |||
var ranges$1 = startSel.ranges.slice(0); | |||
ranges$1[ourIndex] = bidiSimplify(cm, new Range(clipPos(doc, anchor), head)); | |||
setSelection(doc, normalizeSelection(cm, ranges$1, ourIndex), sel_mouse); | |||
ranges$1[ourIndex] = bidiSimplify(cm, new Range(clipPos(doc$1, anchor), head)); | |||
setSelection(doc$1, normalizeSelection(cm, ranges$1, ourIndex), sel_mouse); | |||
} | |||
} | |||
@@ -7570,9 +7590,9 @@ | |||
var cur = posFromMouse(cm, e, true, behavior.unit == "rectangle"); | |||
if (!cur) { return } | |||
if (cmp(cur, lastPos) != 0) { | |||
cm.curOp.focus = activeElt(); | |||
cm.curOp.focus = activeElt(doc(cm)); | |||
extendTo(cur); | |||
var visible = visibleLines(display, doc); | |||
var visible = visibleLines(display, doc$1); | |||
if (cur.line >= visible.to || cur.line < visible.from) | |||
{ setTimeout(operation(cm, function () {if (counter == curCount) { extend(e); }}), 150); } | |||
} else { | |||
@@ -7597,7 +7617,7 @@ | |||
} | |||
off(display.wrapper.ownerDocument, "mousemove", move); | |||
off(display.wrapper.ownerDocument, "mouseup", up); | |||
doc.history.lastSelOrigin = null; | |||
doc$1.history.lastSelOrigin = null; | |||
} | |||
var move = operation(cm, function (e) { | |||
@@ -7754,7 +7774,7 @@ | |||
for (var i = newBreaks.length - 1; i >= 0; i--) | |||
{ replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)); } | |||
}); | |||
option("specialChars", /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b\u200e\u200f\u2028\u2029\ufeff\ufff9-\ufffc]/g, function (cm, val, old) { | |||
option("specialChars", /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b\u200e\u200f\u2028\u2029\u202d\u202e\u2066\u2067\u2069\ufeff\ufff9-\ufffc]/g, function (cm, val, old) { | |||
cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g"); | |||
if (old != Init) { cm.refresh(); } | |||
}); | |||
@@ -8197,7 +8217,7 @@ | |||
var pasted = e.clipboardData && e.clipboardData.getData("Text"); | |||
if (pasted) { | |||
e.preventDefault(); | |||
if (!cm.isReadOnly() && !cm.options.disableInput) | |||
if (!cm.isReadOnly() && !cm.options.disableInput && cm.hasFocus()) | |||
{ runInOp(cm, function () { return applyTextInput(cm, pasted, 0, null, "paste"); }); } | |||
return true | |||
} | |||
@@ -8274,7 +8294,7 @@ | |||
CodeMirror.prototype = { | |||
constructor: CodeMirror, | |||
focus: function(){window.focus(); this.display.input.focus();}, | |||
focus: function(){win(this).focus(); this.display.input.focus();}, | |||
setOption: function(option, value) { | |||
var options = this.options, old = options[option]; | |||
@@ -8598,7 +8618,7 @@ | |||
signal(this, "overwriteToggle", this, this.state.overwrite); | |||
}, | |||
hasFocus: function() { return this.display.input.getField() == activeElt() }, | |||
hasFocus: function() { return this.display.input.getField() == activeElt(doc(this)) }, | |||
isReadOnly: function() { return !!(this.options.readOnly || this.doc.cantEdit) }, | |||
scrollTo: methodOp(function (x, y) { scrollToCoords(this, x, y); }), | |||
@@ -8779,7 +8799,7 @@ | |||
function findPosV(cm, pos, dir, unit) { | |||
var doc = cm.doc, x = pos.left, y; | |||
if (unit == "page") { | |||
var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight); | |||
var pageSize = Math.min(cm.display.wrapper.clientHeight, win(cm).innerHeight || doc(cm).documentElement.clientHeight); | |||
var moveAmount = Math.max(pageSize - .5 * textHeight(cm.display), 3); | |||
y = (dir > 0 ? pos.bottom : pos.top) + dir * moveAmount; | |||
@@ -8879,7 +8899,7 @@ | |||
var kludge = hiddenTextarea(), te = kludge.firstChild; | |||
cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild); | |||
te.value = lastCopied.text.join("\n"); | |||
var hadFocus = activeElt(); | |||
var hadFocus = activeElt(div.ownerDocument); | |||
selectInput(te); | |||
setTimeout(function () { | |||
cm.display.lineSpace.removeChild(kludge); | |||
@@ -8902,7 +8922,7 @@ | |||
ContentEditableInput.prototype.prepareSelection = function () { | |||
var result = prepareSelection(this.cm, false); | |||
result.focus = activeElt() == this.div; | |||
result.focus = activeElt(this.div.ownerDocument) == this.div; | |||
return result | |||
}; | |||
@@ -8998,7 +9018,7 @@ | |||
ContentEditableInput.prototype.focus = function () { | |||
if (this.cm.options.readOnly != "nocursor") { | |||
if (!this.selectionInEditor() || activeElt() != this.div) | |||
if (!this.selectionInEditor() || activeElt(this.div.ownerDocument) != this.div) | |||
{ this.showSelection(this.prepareSelection(), true); } | |||
this.div.focus(); | |||
} | |||
@@ -9073,11 +9093,11 @@ | |||
var fromIndex, fromLine, fromNode; | |||
if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) { | |||
FROMLine = lineNo(display.view[0].line); | |||
FROMNode = display.view[0].node; | |||
fromLine = lineNo(display.view[0].line); | |||
fromNode = display.view[0].node; | |||
} else { | |||
FROMLine = lineNo(display.view[fromIndex].line); | |||
FROMNode = display.view[fromIndex - 1].node.nextSibling; | |||
fromLine = lineNo(display.view[fromIndex].line); | |||
fromNode = display.view[fromIndex - 1].node.nextSibling; | |||
} | |||
var toIndex = findViewIndex(cm, to.line); | |||
var toLine, toNode; | |||
@@ -9254,7 +9274,7 @@ | |||
for (;;) { | |||
walk(from); | |||
if (from == to) { break } | |||
FROM = from.nextSibling; | |||
from = from.nextSibling; | |||
extraLinebreak = false; | |||
} | |||
return text | |||
@@ -9350,6 +9370,7 @@ | |||
// Used to work around IE issue with selection being forgotten when focus moves away from textarea | |||
this.hasSelection = false; | |||
this.composing = null; | |||
this.resetting = false; | |||
}; | |||
TextareaInput.prototype.init = function (display) { | |||
@@ -9482,8 +9503,9 @@ | |||
// Reset the input to correspond to the selection (or to be empty, | |||
// when not typing and nothing is selected) | |||
TextareaInput.prototype.reset = function (typing) { | |||
if (this.contextMenuPending || this.composing) { return } | |||
if (this.contextMenuPending || this.composing && typing) { return } | |||
var cm = this.cm; | |||
this.resetting = true; | |||
if (cm.somethingSelected()) { | |||
this.prevInput = ""; | |||
var content = cm.getSelection(); | |||
@@ -9494,6 +9516,7 @@ | |||
this.prevInput = this.textarea.value = ""; | |||
if (ie && ie_version >= 9) { this.hasSelection = null; } | |||
} | |||
this.resetting = false; | |||
}; | |||
TextareaInput.prototype.getField = function () { return this.textarea }; | |||
@@ -9501,7 +9524,7 @@ | |||
TextareaInput.prototype.supportsTouch = function () { return false }; | |||
TextareaInput.prototype.focus = function () { | |||
if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) { | |||
if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt(this.textarea.ownerDocument) != this.textarea)) { | |||
try { this.textarea.focus(); } | |||
catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM | |||
} | |||
@@ -9555,7 +9578,7 @@ | |||
// possible when it is clear that nothing happened. hasSelection | |||
// will be the case when there is a lot of text in the textarea, | |||
// in which case reading its value would be expensive. | |||
if (this.contextMenuPending || !cm.state.focused || | |||
if (this.contextMenuPending || this.resetting || !cm.state.focused || | |||
(hasSelection(input) && !prevInput && !this.composing) || | |||
cm.isReadOnly() || cm.options.disableInput || cm.state.keySeq) | |||
{ return false } | |||
@@ -9624,9 +9647,9 @@ | |||
input.wrapper.style.cssText = "position: static"; | |||
te.style.cssText = "position: absolute; width: 30px; height: 30px;\n top: " + (e.clientY - wrapperBox.top - 5) + "px; left: " + (e.clientX - wrapperBox.left - 5) + "px;\n z-index: 1000; background: " + (ie ? "rgba(255, 255, 255, .05)" : "transparent") + ";\n outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);"; | |||
var oldScrollY; | |||
if (webkit) { oldScrollY = window.scrollY; } // Work around Chrome issue (#2712) | |||
if (webkit) { oldScrollY = te.ownerDocument.defaultView.scrollY; } // Work around Chrome issue (#2712) | |||
display.input.focus(); | |||
if (webkit) { window.scrollTo(null, oldScrollY); } | |||
if (webkit) { te.ownerDocument.defaultView.scrollTo(null, oldScrollY); } | |||
display.input.reset(); | |||
// Adds "Select all" to context menu in FF | |||
if (!cm.somethingSelected()) { te.value = input.prevInput = " "; } | |||
@@ -9708,7 +9731,7 @@ | |||
// Set autofocus to true if this textarea is focused, or if it has | |||
// autofocus and no other element is focused. | |||
if (options.autofocus == null) { | |||
var hasFocus = activeElt(); | |||
var hasFocus = activeElt(textarea.ownerDocument); | |||
options.autofocus = hasFocus == textarea || | |||
textarea.getAttribute("autofocus") != null && hasFocus == document.body; | |||
} | |||
@@ -9842,7 +9865,7 @@ | |||
addLegacyProps(CodeMirror); | |||
CodeMirror.version = "5.65.3"; | |||
CodeMirror.version = "5.65.9"; | |||
return CodeMirror; | |||
@@ -1,5 +1,5 @@ | |||
// CodeMirror, copyright (c) by Marijn Haverbeke and others | |||
// Distributed under an MIT license: https://codemirror.net/LICENSE | |||
// Distributed under an MIT license: https://codemirror.net/5/LICENSE | |||
(function(mod) { | |||
if (typeof exports == "object" && typeof module == "object") // CommonJS | |||
@@ -0,0 +1,165 @@ | |||
// CodeMirror, copyright (c) by Marijn Haverbeke and others | |||
// Distributed under an MIT license: https://codemirror.net/5/LICENSE | |||
(function() { | |||
var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-c"); | |||
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); } | |||
MT("indent", | |||
"[type void] [def foo]([type void*] [variable a], [type int] [variable b]) {", | |||
" [type int] [variable c] [operator =] [variable b] [operator +]", | |||
" [number 1];", | |||
" [keyword return] [operator *][variable a];", | |||
"}"); | |||
MT("indent_switch", | |||
"[keyword switch] ([variable x]) {", | |||
" [keyword case] [number 10]:", | |||
" [keyword return] [number 20];", | |||
" [keyword default]:", | |||
" [variable printf]([string \"foo %c\"], [variable x]);", | |||
"}"); | |||
MT("def", | |||
"[type void] [def foo]() {}", | |||
"[keyword struct] [def bar]{}", | |||
"[keyword enum] [def zot]{}", | |||
"[keyword union] [def ugh]{}", | |||
"[type int] [type *][def baz]() {}"); | |||
MT("def_new_line", | |||
"::[variable std]::[variable SomeTerribleType][operator <][variable T][operator >]", | |||
"[def SomeLongMethodNameThatDoesntFitIntoOneLine]([keyword const] [variable MyType][operator &] [variable param]) {}") | |||
MT("double_block", | |||
"[keyword for] (;;)", | |||
" [keyword for] (;;)", | |||
" [variable x][operator ++];", | |||
"[keyword return];"); | |||
MT("preprocessor", | |||
"[meta #define FOO 3]", | |||
"[type int] [variable foo];", | |||
"[meta #define BAR\\]", | |||
"[meta 4]", | |||
"[type unsigned] [type int] [variable bar] [operator =] [number 8];", | |||
"[meta #include <baz> ][comment // comment]") | |||
MT("c_underscores", | |||
"[builtin __FOO];", | |||
"[builtin _Complex];", | |||
"[builtin __aName];", | |||
"[variable _aName];"); | |||
MT("c_types", | |||
"[type int];", | |||
"[type long];", | |||
"[type char];", | |||
"[type short];", | |||
"[type double];", | |||
"[type float];", | |||
"[type unsigned];", | |||
"[type signed];", | |||
"[type void];", | |||
"[type bool];", | |||
"[type foo_t];", | |||
"[variable foo_T];", | |||
"[variable _t];"); | |||
var mode_cpp = CodeMirror.getMode({indentUnit: 2}, "text/x-c++src"); | |||
function MTCPP(name) { test.mode(name, mode_cpp, Array.prototype.slice.call(arguments, 1)); } | |||
MTCPP("cpp14_literal", | |||
"[number 10'000];", | |||
"[number 0b10'000];", | |||
"[number 0x10'000];", | |||
"[string '100000'];"); | |||
MTCPP("ctor_dtor", | |||
"[def Foo::Foo]() {}", | |||
"[def Foo::~Foo]() {}"); | |||
MTCPP("cpp_underscores", | |||
"[builtin __FOO];", | |||
"[builtin _Complex];", | |||
"[builtin __aName];", | |||
"[variable _aName];"); | |||
var mode_objc = CodeMirror.getMode({indentUnit: 2}, "text/x-objectivec"); | |||
function MTOBJC(name) { test.mode(name, mode_objc, Array.prototype.slice.call(arguments, 1)); } | |||
MTOBJC("objc_underscores", | |||
"[builtin __FOO];", | |||
"[builtin _Complex];", | |||
"[builtin __aName];", | |||
"[variable _aName];"); | |||
MTOBJC("objc_interface", | |||
"[keyword @interface] [def foo] {", | |||
" [type int] [variable bar];", | |||
"}", | |||
"[keyword @property] ([keyword atomic], [keyword nullable]) [variable NSString][operator *] [variable a];", | |||
"[keyword @property] ([keyword nonatomic], [keyword assign]) [type int] [variable b];", | |||
"[operator -]([type instancetype])[variable initWithFoo]:([type int])[variable a] " + | |||
"[builtin NS_DESIGNATED_INITIALIZER];", | |||
"[keyword @end]"); | |||
MTOBJC("objc_implementation", | |||
"[keyword @implementation] [def foo] {", | |||
" [type int] [variable bar];", | |||
"}", | |||
"[keyword @property] ([keyword readwrite]) [type SEL] [variable a];", | |||
"[operator -]([type instancetype])[variable initWithFoo]:([type int])[variable a] {", | |||
" [keyword if](([keyword self] [operator =] [[[keyword super] [variable init] ]])) {}", | |||
" [keyword return] [keyword self];", | |||
"}", | |||
"[keyword @end]"); | |||
MTOBJC("objc_types", | |||
"[type int];", | |||
"[type foo_t];", | |||
"[variable foo_T];", | |||
"[type id];", | |||
"[type SEL];", | |||
"[type instancetype];", | |||
"[type Class];", | |||
"[type Protocol];", | |||
"[type BOOL];" | |||
); | |||
var mode_scala = CodeMirror.getMode({indentUnit: 2}, "text/x-scala"); | |||
function MTSCALA(name) { test.mode("scala_" + name, mode_scala, Array.prototype.slice.call(arguments, 1)); } | |||
MTSCALA("nested_comments", | |||
"[comment /*]", | |||
"[comment But wait /* this is a nested comment */ for real]", | |||
"[comment /**** let * me * show * you ****/]", | |||
"[comment ///// let / me / show / you /////]", | |||
"[comment */]"); | |||
var mode_java = CodeMirror.getMode({indentUnit: 2}, "text/x-java"); | |||
function MTJAVA(name) { test.mode("java_" + name, mode_java, Array.prototype.slice.call(arguments, 1)); } | |||
MTJAVA("types", | |||
"[type byte];", | |||
"[type short];", | |||
"[type int];", | |||
"[type long];", | |||
"[type float];", | |||
"[type double];", | |||
"[type boolean];", | |||
"[type char];", | |||
"[type void];", | |||
"[type Boolean];", | |||
"[type Byte];", | |||
"[type Character];", | |||
"[type Double];", | |||
"[type Float];", | |||
"[type Integer];", | |||
"[type Long];", | |||
"[type Number];", | |||
"[type Object];", | |||
"[type Short];", | |||
"[type String];", | |||
"[type StringBuffer];", | |||
"[type StringBuilder];", | |||
"[type Void];"); | |||
})(); |
@@ -1,5 +1,5 @@ | |||
// 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/5/LICENSE | |||
(function(mod) { | |||
if (typeof exports == "object" && typeof module == "object") // CommonJS | |||
@@ -29,7 +29,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) { | |||
valueKeywords = parserConfig.valueKeywords || {}, | |||
allowNested = parserConfig.allowNested, | |||
lineComment = parserConfig.lineComment, | |||
supportsAtComponent = parserConfig.supportsAtComponent === true; | |||
supportsAtComponent = parserConfig.supportsAtComponent === true, | |||
highlightNonStandardPropertyKeywords = config.highlightNonStandardPropertyKeywords !== false; | |||
var type, override; | |||
function ret(style, tp) { type = tp; return style; } | |||
@@ -63,7 +64,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) { | |||
if (/[\d.]/.test(stream.peek())) { | |||
stream.eatWhile(/[\w.%]/); | |||
return ret("number", "unit"); | |||
} else if (stream.match(/^-[\w\\\-]+/)) { | |||
} else if (stream.match(/^-[\w\\\-]*/)) { | |||
stream.eatWhile(/[\w\\\-]/); | |||
if (stream.match(/^\s*:/, false)) | |||
return ret("variable-2", "variable-definition"); | |||
@@ -77,12 +78,11 @@ CodeMirror.defineMode("css", function(config, parserConfig) { | |||
return ret("qualifier", "qualifier"); | |||
} else if (/[:;{}\[\]\(\)]/.test(ch)) { | |||
return ret(null, ch); | |||
} else if ((ch == "u" && stream.match(/rl(-prefix)?\(/)) || | |||
(ch == "d" && stream.match("omain(")) || | |||
(ch == "r" && stream.match("egexp("))) { | |||
stream.backUp(1); | |||
state.tokenize = tokenParenthesized; | |||
return ret("property", "word"); | |||
} else if (stream.match(/^[\w-.]+(?=\()/)) { | |||
if (/^(url(-prefix)?|domain|regexp)$/i.test(stream.current())) { | |||
state.tokenize = tokenParenthesized; | |||
} | |||
return ret("variable callee", "variable"); | |||
} else if (/[\w\\\-]/.test(ch)) { | |||
stream.eatWhile(/[\w\\\-]/); | |||
return ret("property", "word"); | |||
@@ -108,7 +108,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) { | |||
function tokenParenthesized(stream, state) { | |||
stream.next(); // Must be '(' | |||
if (!stream.match(/\s*[\"\')]/, false)) | |||
if (!stream.match(/^\s*[\"\')]/, false)) | |||
state.tokenize = tokenString(")"); | |||
else | |||
state.tokenize = null; | |||
@@ -162,16 +162,16 @@ CodeMirror.defineMode("css", function(config, parserConfig) { | |||
return pushContext(state, stream, "block"); | |||
} else if (type == "}" && state.context.prev) { | |||
return popContext(state); | |||
} else if (supportsAtComponent && /@component/.test(type)) { | |||
} else if (supportsAtComponent && /@component/i.test(type)) { | |||
return pushContext(state, stream, "atComponentBlock"); | |||
} else if (/^@(-moz-)?document$/.test(type)) { | |||
} else if (/^@(-moz-)?document$/i.test(type)) { | |||
return pushContext(state, stream, "documentTypes"); | |||
} else if (/^@(media|supports|(-moz-)?document|import)$/.test(type)) { | |||
} else if (/^@(media|supports|(-moz-)?document|import)$/i.test(type)) { | |||
return pushContext(state, stream, "atBlock"); | |||
} else if (/^@(font-face|counter-style)/.test(type)) { | |||
} else if (/^@(font-face|counter-style)/i.test(type)) { | |||
state.stateArg = type; | |||
return "restricted_atBlock_before"; | |||
} else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) { | |||
} else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/i.test(type)) { | |||
return "keyframes"; | |||
} else if (type && type.charAt(0) == "@") { | |||
return pushContext(state, stream, "at"); | |||
@@ -198,7 +198,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) { | |||
override = "property"; | |||
return "maybeprop"; | |||
} else if (nonStandardPropertyKeywords.hasOwnProperty(word)) { | |||
override = "string-2"; | |||
override = highlightNonStandardPropertyKeywords ? "string-2" : "property"; | |||
return "maybeprop"; | |||
} else if (allowNested) { | |||
override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag"; | |||
@@ -228,7 +228,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) { | |||
if (type == "}" || type == "{") return popAndPass(type, stream, state); | |||
if (type == "(") return pushContext(state, stream, "parens"); | |||
if (type == "hash" && !/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())) { | |||
if (type == "hash" && !/^#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(stream.current())) { | |||
override += " error"; | |||
} else if (type == "word") { | |||
wordAsValue(stream); | |||
@@ -292,7 +292,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) { | |||
else if (propertyKeywords.hasOwnProperty(word)) | |||
override = "property"; | |||
else if (nonStandardPropertyKeywords.hasOwnProperty(word)) | |||
override = "string-2"; | |||
override = highlightNonStandardPropertyKeywords ? "string-2" : "property"; | |||
else if (valueKeywords.hasOwnProperty(word)) | |||
override = "atom"; | |||
else if (colorKeywords.hasOwnProperty(word)) | |||
@@ -383,7 +383,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) { | |||
style = style[0]; | |||
} | |||
override = style; | |||
state.state = states[state.state](type, stream, state); | |||
if (type != "comment") | |||
state.state = states[state.state](type, stream, state); | |||
return override; | |||
}, | |||
@@ -401,7 +402,6 @@ CodeMirror.defineMode("css", function(config, parserConfig) { | |||
ch == "{" && (cx.type == "at" || cx.type == "atBlock")) { | |||
// Dedent relative to current context. | |||
indent = Math.max(0, cx.indent - indentUnit); | |||
cx = cx.prev; | |||
} | |||
} | |||
return indent; | |||
@@ -410,6 +410,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) { | |||
electricChars: "}", | |||
blockCommentStart: "/*", | |||
blockCommentEnd: "*/", | |||
blockCommentContinue: " * ", | |||
lineComment: lineComment, | |||
fold: "brace" | |||
}; | |||
@@ -442,117 +443,151 @@ CodeMirror.defineMode("css", function(config, parserConfig) { | |||
"monochrome", "min-monochrome", "max-monochrome", "resolution", | |||
"min-resolution", "max-resolution", "scan", "grid", "orientation", | |||
"device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio", | |||
"pointer", "any-pointer", "hover", "any-hover" | |||
"pointer", "any-pointer", "hover", "any-hover", "prefers-color-scheme", | |||
"dynamic-range", "video-dynamic-range" | |||
], mediaFeatures = keySet(mediaFeatures_); | |||
var mediaValueKeywords_ = [ | |||
"landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover", | |||
"interlace", "progressive" | |||
"interlace", "progressive", | |||
"dark", "light", | |||
"standard", "high" | |||
], mediaValueKeywords = keySet(mediaValueKeywords_); | |||
var propertyKeywords_ = [ | |||
"align-content", "align-items", "align-self", "alignment-adjust", | |||
"alignment-baseline", "anchor-point", "animation", "animation-delay", | |||
"alignment-baseline", "all", "anchor-point", "animation", "animation-delay", | |||
"animation-direction", "animation-duration", "animation-fill-mode", | |||
"animation-iteration-count", "animation-name", "animation-play-state", | |||
"animation-timing-function", "appearance", "azimuth", "backface-visibility", | |||
"background", "background-attachment", "background-blend-mode", "background-clip", | |||
"background-color", "background-image", "background-origin", "background-position", | |||
"background-repeat", "background-size", "baseline-shift", "binding", | |||
"bleed", "bookmark-label", "bookmark-level", "bookmark-state", | |||
"bookmark-target", "border", "border-bottom", "border-bottom-color", | |||
"border-bottom-left-radius", "border-bottom-right-radius", | |||
"border-bottom-style", "border-bottom-width", "border-collapse", | |||
"border-color", "border-image", "border-image-outset", | |||
"animation-timing-function", "appearance", "azimuth", "backdrop-filter", | |||
"backface-visibility", "background", "background-attachment", | |||
"background-blend-mode", "background-clip", "background-color", | |||
"background-image", "background-origin", "background-position", | |||
"background-position-x", "background-position-y", "background-repeat", | |||
"background-size", "baseline-shift", "binding", "bleed", "block-size", | |||
"bookmark-label", "bookmark-level", "bookmark-state", "bookmark-target", | |||
"border", "border-bottom", "border-bottom-color", "border-bottom-left-radius", | |||
"border-bottom-right-radius", "border-bottom-style", "border-bottom-width", | |||
"border-collapse", "border-color", "border-image", "border-image-outset", | |||
"border-image-repeat", "border-image-slice", "border-image-source", | |||
"border-image-width", "border-left", "border-left-color", | |||
"border-left-style", "border-left-width", "border-radius", "border-right", | |||
"border-right-color", "border-right-style", "border-right-width", | |||
"border-spacing", "border-style", "border-top", "border-top-color", | |||
"border-top-left-radius", "border-top-right-radius", "border-top-style", | |||
"border-top-width", "border-width", "bottom", "box-decoration-break", | |||
"box-shadow", "box-sizing", "break-after", "break-before", "break-inside", | |||
"caption-side", "clear", "clip", "color", "color-profile", "column-count", | |||
"column-fill", "column-gap", "column-rule", "column-rule-color", | |||
"column-rule-style", "column-rule-width", "column-span", "column-width", | |||
"columns", "content", "counter-increment", "counter-reset", "crop", "cue", | |||
"cue-after", "cue-before", "cursor", "direction", "display", | |||
"dominant-baseline", "drop-initial-after-adjust", | |||
"drop-initial-after-align", "drop-initial-before-adjust", | |||
"drop-initial-before-align", "drop-initial-size", "drop-initial-value", | |||
"elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis", | |||
"flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap", | |||
"float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings", | |||
"font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust", | |||
"font-stretch", "font-style", "font-synthesis", "font-variant", | |||
"font-variant-alternates", "font-variant-caps", "font-variant-east-asian", | |||
"font-variant-ligatures", "font-variant-numeric", "font-variant-position", | |||
"font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow", | |||
"grid-auto-rows", "grid-column", "grid-column-end", "grid-column-gap", | |||
"grid-column-start", "grid-gap", "grid-row", "grid-row-end", "grid-row-gap", | |||
"grid-row-start", "grid-template", "grid-template-areas", "grid-template-columns", | |||
"grid-template-rows", "hanging-punctuation", "height", "hyphens", | |||
"icon", "image-orientation", "image-rendering", "image-resolution", | |||
"inline-box-align", "justify-content", "left", "letter-spacing", | |||
"line-break", "line-height", "line-stacking", "line-stacking-ruby", | |||
"border-image-width", "border-left", "border-left-color", "border-left-style", | |||
"border-left-width", "border-radius", "border-right", "border-right-color", | |||
"border-right-style", "border-right-width", "border-spacing", "border-style", | |||
"border-top", "border-top-color", "border-top-left-radius", | |||
"border-top-right-radius", "border-top-style", "border-top-width", | |||
"border-width", "bottom", "box-decoration-break", "box-shadow", "box-sizing", | |||
"break-after", "break-before", "break-inside", "caption-side", "caret-color", | |||
"clear", "clip", "color", "color-profile", "column-count", "column-fill", | |||
"column-gap", "column-rule", "column-rule-color", "column-rule-style", | |||
"column-rule-width", "column-span", "column-width", "columns", "contain", | |||
"content", "counter-increment", "counter-reset", "crop", "cue", "cue-after", | |||
"cue-before", "cursor", "direction", "display", "dominant-baseline", | |||
"drop-initial-after-adjust", "drop-initial-after-align", | |||
"drop-initial-before-adjust", "drop-initial-before-align", "drop-initial-size", | |||
"drop-initial-value", "elevation", "empty-cells", "fit", "fit-content", "fit-position", | |||
"flex", "flex-basis", "flex-direction", "flex-flow", "flex-grow", | |||
"flex-shrink", "flex-wrap", "float", "float-offset", "flow-from", "flow-into", | |||
"font", "font-family", "font-feature-settings", "font-kerning", | |||
"font-language-override", "font-optical-sizing", "font-size", | |||
"font-size-adjust", "font-stretch", "font-style", "font-synthesis", | |||
"font-variant", "font-variant-alternates", "font-variant-caps", | |||
"font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric", | |||
"font-variant-position", "font-variation-settings", "font-weight", "gap", | |||
"grid", "grid-area", "grid-auto-columns", "grid-auto-flow", "grid-auto-rows", | |||
"grid-column", "grid-column-end", "grid-column-gap", "grid-column-start", | |||
"grid-gap", "grid-row", "grid-row-end", "grid-row-gap", "grid-row-start", | |||
"grid-template", "grid-template-areas", "grid-template-columns", | |||
"grid-template-rows", "hanging-punctuation", "height", "hyphens", "icon", | |||
"image-orientation", "image-rendering", "image-resolution", "inline-box-align", | |||
"inset", "inset-block", "inset-block-end", "inset-block-start", "inset-inline", | |||
"inset-inline-end", "inset-inline-start", "isolation", "justify-content", | |||
"justify-items", "justify-self", "left", "letter-spacing", "line-break", | |||
"line-height", "line-height-step", "line-stacking", "line-stacking-ruby", | |||
"line-stacking-shift", "line-stacking-strategy", "list-style", | |||
"list-style-image", "list-style-position", "list-style-type", "margin", | |||
"margin-bottom", "margin-left", "margin-right", "margin-top", | |||
"marks", "marquee-direction", "marquee-loop", | |||
"marquee-play-count", "marquee-speed", "marquee-style", "max-height", | |||
"max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index", | |||
"nav-left", "nav-right", "nav-up", "object-fit", "object-position", | |||
"opacity", "order", "orphans", "outline", | |||
"outline-color", "outline-offset", "outline-style", "outline-width", | |||
"overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y", | |||
"padding", "padding-bottom", "padding-left", "padding-right", "padding-top", | |||
"page", "page-break-after", "page-break-before", "page-break-inside", | |||
"page-policy", "pause", "pause-after", "pause-before", "perspective", | |||
"perspective-origin", "pitch", "pitch-range", "play-during", "position", | |||
"presentation-level", "punctuation-trim", "quotes", "region-break-after", | |||
"region-break-before", "region-break-inside", "region-fragment", | |||
"rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness", | |||
"right", "rotation", "rotation-point", "ruby-align", "ruby-overhang", | |||
"ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin", | |||
"shape-outside", "size", "speak", "speak-as", "speak-header", | |||
"speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set", | |||
"tab-size", "table-layout", "target", "target-name", "target-new", | |||
"target-position", "text-align", "text-align-last", "text-decoration", | |||
"margin-bottom", "margin-left", "margin-right", "margin-top", "marks", | |||
"marquee-direction", "marquee-loop", "marquee-play-count", "marquee-speed", | |||
"marquee-style", "mask-clip", "mask-composite", "mask-image", "mask-mode", | |||
"mask-origin", "mask-position", "mask-repeat", "mask-size","mask-type", | |||
"max-block-size", "max-height", "max-inline-size", | |||
"max-width", "min-block-size", "min-height", "min-inline-size", "min-width", | |||
"mix-blend-mode", "move-to", "nav-down", "nav-index", "nav-left", "nav-right", | |||
"nav-up", "object-fit", "object-position", "offset", "offset-anchor", | |||
"offset-distance", "offset-path", "offset-position", "offset-rotate", | |||
"opacity", "order", "orphans", "outline", "outline-color", "outline-offset", | |||
"outline-style", "outline-width", "overflow", "overflow-style", | |||
"overflow-wrap", "overflow-x", "overflow-y", "padding", "padding-bottom", | |||
"padding-left", "padding-right", "padding-top", "page", "page-break-after", | |||
"page-break-before", "page-break-inside", "page-policy", "pause", | |||
"pause-after", "pause-before", "perspective", "perspective-origin", "pitch", | |||
"pitch-range", "place-content", "place-items", "place-self", "play-during", | |||
"position", "presentation-level", "punctuation-trim", "quotes", | |||
"region-break-after", "region-break-before", "region-break-inside", | |||
"region-fragment", "rendering-intent", "resize", "rest", "rest-after", | |||
"rest-before", "richness", "right", "rotate", "rotation", "rotation-point", | |||
"row-gap", "ruby-align", "ruby-overhang", "ruby-position", "ruby-span", | |||
"scale", "scroll-behavior", "scroll-margin", "scroll-margin-block", | |||
"scroll-margin-block-end", "scroll-margin-block-start", "scroll-margin-bottom", | |||
"scroll-margin-inline", "scroll-margin-inline-end", | |||
"scroll-margin-inline-start", "scroll-margin-left", "scroll-margin-right", | |||
"scroll-margin-top", "scroll-padding", "scroll-padding-block", | |||
"scroll-padding-block-end", "scroll-padding-block-start", | |||
"scroll-padding-bottom", "scroll-padding-inline", "scroll-padding-inline-end", | |||
"scroll-padding-inline-start", "scroll-padding-left", "scroll-padding-right", | |||
"scroll-padding-top", "scroll-snap-align", "scroll-snap-type", | |||
"shape-image-threshold", "shape-inside", "shape-margin", "shape-outside", | |||
"size", "speak", "speak-as", "speak-header", "speak-numeral", | |||
"speak-punctuation", "speech-rate", "stress", "string-set", "tab-size", | |||
"table-layout", "target", "target-name", "target-new", "target-position", | |||
"text-align", "text-align-last", "text-combine-upright", "text-decoration", | |||
"text-decoration-color", "text-decoration-line", "text-decoration-skip", | |||
"text-decoration-style", "text-emphasis", "text-emphasis-color", | |||
"text-emphasis-position", "text-emphasis-style", "text-height", | |||
"text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow", | |||
"text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position", | |||
"text-wrap", "top", "transform", "transform-origin", "transform-style", | |||
"transition", "transition-delay", "transition-duration", | |||
"transition-property", "transition-timing-function", "unicode-bidi", | |||
"user-select", "vertical-align", "visibility", "voice-balance", "voice-duration", | |||
"voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress", | |||
"voice-volume", "volume", "white-space", "widows", "width", "will-change", "word-break", | |||
"word-spacing", "word-wrap", "z-index", | |||
"text-decoration-skip-ink", "text-decoration-style", "text-emphasis", | |||
"text-emphasis-color", "text-emphasis-position", "text-emphasis-style", | |||
"text-height", "text-indent", "text-justify", "text-orientation", | |||
"text-outline", "text-overflow", "text-rendering", "text-shadow", | |||
"text-size-adjust", "text-space-collapse", "text-transform", | |||
"text-underline-position", "text-wrap", "top", "touch-action", "transform", "transform-origin", | |||
"transform-style", "transition", "transition-delay", "transition-duration", | |||
"transition-property", "transition-timing-function", "translate", | |||
"unicode-bidi", "user-select", "vertical-align", "visibility", "voice-balance", | |||
"voice-duration", "voice-family", "voice-pitch", "voice-range", "voice-rate", | |||
"voice-stress", "voice-volume", "volume", "white-space", "widows", "width", | |||
"will-change", "word-break", "word-spacing", "word-wrap", "writing-mode", "z-index", | |||
// SVG-specific | |||
"clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color", | |||
"flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events", | |||
"color-interpolation", "color-interpolation-filters", | |||
"color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering", | |||
"marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke", | |||
"marker", "marker-end", "marker-mid", "marker-start", "paint-order", "shape-rendering", "stroke", | |||
"stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", | |||
"stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering", | |||
"baseline-shift", "dominant-baseline", "glyph-orientation-horizontal", | |||
"glyph-orientation-vertical", "text-anchor", "writing-mode" | |||
"glyph-orientation-vertical", "text-anchor", "writing-mode", | |||
], propertyKeywords = keySet(propertyKeywords_); | |||
var nonStandardPropertyKeywords_ = [ | |||
"accent-color", "aspect-ratio", "border-block", "border-block-color", "border-block-end", | |||
"border-block-end-color", "border-block-end-style", "border-block-end-width", | |||
"border-block-start", "border-block-start-color", "border-block-start-style", | |||
"border-block-start-width", "border-block-style", "border-block-width", | |||
"border-inline", "border-inline-color", "border-inline-end", | |||
"border-inline-end-color", "border-inline-end-style", | |||
"border-inline-end-width", "border-inline-start", "border-inline-start-color", | |||
"border-inline-start-style", "border-inline-start-width", | |||
"border-inline-style", "border-inline-width", "content-visibility", "margin-block", | |||
"margin-block-end", "margin-block-start", "margin-inline", "margin-inline-end", | |||
"margin-inline-start", "overflow-anchor", "overscroll-behavior", "padding-block", "padding-block-end", | |||
"padding-block-start", "padding-inline", "padding-inline-end", | |||
"padding-inline-start", "scroll-snap-stop", "scrollbar-3d-light-color", | |||
"scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color", | |||
"scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color", | |||
"scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside", | |||
"searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button", | |||
"searchfield-results-decoration", "zoom" | |||
"scrollbar-track-color", "searchfield-cancel-button", "searchfield-decoration", | |||
"searchfield-results-button", "searchfield-results-decoration", "shape-inside", "zoom" | |||
], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_); | |||
var fontProperties_ = [ | |||
"font-family", "src", "unicode-range", "font-variant", "font-feature-settings", | |||
"font-stretch", "font-weight", "font-style" | |||
"font-display", "font-family", "src", "unicode-range", "font-variant", | |||
"font-feature-settings", "font-stretch", "font-weight", "font-style" | |||
], fontProperties = keySet(fontProperties_); | |||
var counterDescriptors_ = [ | |||
@@ -565,16 +600,16 @@ CodeMirror.defineMode("css", function(config, parserConfig) { | |||
"bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", | |||
"burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", | |||
"cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", | |||
"darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen", | |||
"darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", | |||
"darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", | |||
"darkslateblue", "darkslategray", "darkturquoise", "darkviolet", | |||
"deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick", | |||
"darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", | |||
"deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", | |||
"floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", | |||
"gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", | |||
"hotpink", "indianred", "indigo", "ivory", "khaki", "lavender", | |||
"lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", | |||
"lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink", | |||
"lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", | |||
"lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", | |||
"lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", | |||
"lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", | |||
"maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", | |||
"mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", | |||
@@ -584,7 +619,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) { | |||
"papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", | |||
"purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown", | |||
"salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", | |||
"slateblue", "slategray", "snow", "springgreen", "steelblue", "tan", | |||
"slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", | |||
"teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", | |||
"whitesmoke", "yellow", "yellowgreen" | |||
], colorKeywords = keySet(colorKeywords_); | |||
@@ -594,22 +629,22 @@ CodeMirror.defineMode("css", function(config, parserConfig) { | |||
"after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate", | |||
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace", | |||
"arabic-indic", "armenian", "asterisks", "attr", "auto", "auto-flow", "avoid", "avoid-column", "avoid-page", | |||
"avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary", | |||
"bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box", | |||
"both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel", | |||
"avoid-region", "axis-pan", "background", "backwards", "baseline", "below", "bidi-override", "binary", | |||
"bengali", "blink", "block", "block-axis", "blur", "bold", "bolder", "border", "border-box", | |||
"both", "bottom", "break", "break-all", "break-word", "brightness", "bullets", "button", | |||
"buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian", | |||
"capitalize", "caps-lock-indicator", "caption", "captiontext", "caret", | |||
"cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch", | |||
"cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote", | |||
"col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse", | |||
"compact", "condensed", "contain", "content", "contents", | |||
"content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop", | |||
"cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal", | |||
"compact", "condensed", "conic-gradient", "contain", "content", "contents", | |||
"content-box", "context-menu", "continuous", "contrast", "copy", "counter", "counters", "cover", "crop", | |||
"cross", "crosshair", "cubic-bezier", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal", | |||
"decimal-leading-zero", "default", "default-button", "dense", "destination-atop", | |||
"destination-in", "destination-out", "destination-over", "devanagari", "difference", | |||
"disc", "discard", "disclosure-closed", "disclosure-open", "document", | |||
"dot-dash", "dot-dot-dash", | |||
"dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out", | |||
"dotted", "double", "down", "drop-shadow", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out", | |||
"element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede", | |||
"ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er", | |||
"ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er", | |||
@@ -618,11 +653,11 @@ CodeMirror.defineMode("css", function(config, parserConfig) { | |||
"ethiopic-halehame-sid-et", "ethiopic-halehame-so-et", | |||
"ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig", | |||
"ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed", | |||
"extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes", | |||
"forwards", "from", "geometricPrecision", "georgian", "graytext", "grid", "groove", | |||
"extra-expanded", "fantasy", "fast", "fill", "fill-box", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes", | |||
"forwards", "from", "geometricPrecision", "georgian", "grayscale", "graytext", "grid", "groove", | |||
"gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew", | |||
"help", "hidden", "hide", "higher", "highlight", "highlighttext", | |||
"hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "icon", "ignore", | |||
"hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "hue-rotate", "icon", "ignore", | |||
"inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite", | |||
"infobackground", "infotext", "inherit", "initial", "inline", "inline-axis", | |||
"inline-block", "inline-flex", "inline-grid", "inline-table", "inset", "inside", "intrinsic", "invert", | |||
@@ -633,41 +668,37 @@ CodeMirror.defineMode("css", function(config, parserConfig) { | |||
"line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem", | |||
"local", "logical", "loud", "lower", "lower-alpha", "lower-armenian", | |||
"lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian", | |||
"lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d", | |||
"media-controls-background", "media-current-time-display", | |||
"media-fullscreen-button", "media-mute-button", "media-play-button", | |||
"media-return-to-realtime-button", "media-rewind-button", | |||
"media-seek-back-button", "media-seek-forward-button", "media-slider", | |||
"media-sliderthumb", "media-time-remaining-display", "media-volume-slider", | |||
"media-volume-slider-container", "media-volume-sliderthumb", "medium", | |||
"menu", "menulist", "menulist-button", "menulist-text", | |||
"menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic", | |||
"mix", "mongolian", "monospace", "move", "multiple", "multiply", "myanmar", "n-resize", | |||
"lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "manipulation", "match", "matrix", "matrix3d", | |||
"media-play-button", "media-slider", "media-sliderthumb", | |||
"media-volume-slider", "media-volume-sliderthumb", "medium", | |||
"menu", "menulist", "menulist-button", | |||
"menutext", "message-box", "middle", "min-intrinsic", | |||
"mix", "mongolian", "monospace", "move", "multiple", "multiple_mask_images", "multiply", "myanmar", "n-resize", | |||
"narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop", | |||
"no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap", | |||
"ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "opacity", "open-quote", | |||
"optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset", | |||
"outside", "outside-shape", "overlay", "overline", "padding", "padding-box", | |||
"painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter", | |||
"painted", "page", "paused", "persian", "perspective", "pinch-zoom", "plus-darker", "plus-lighter", | |||
"pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", | |||
"progress", "push-button", "radial-gradient", "radio", "read-only", | |||
"read-write", "read-write-plaintext-only", "rectangle", "region", | |||
"relative", "repeat", "repeating-linear-gradient", | |||
"repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse", | |||
"relative", "repeat", "repeating-linear-gradient", "repeating-radial-gradient", | |||
"repeating-conic-gradient", "repeat-x", "repeat-y", "reset", "reverse", | |||
"rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY", | |||
"rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running", | |||
"s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen", | |||
"s-resize", "sans-serif", "saturate", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen", | |||
"scroll", "scrollbar", "scroll-position", "se-resize", "searchfield", | |||
"searchfield-cancel-button", "searchfield-decoration", | |||
"searchfield-results-button", "searchfield-results-decoration", | |||
"semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama", | |||
"searchfield-results-button", "searchfield-results-decoration", "self-start", "self-end", | |||
"semi-condensed", "semi-expanded", "separate", "sepia", "serif", "show", "sidama", | |||
"simp-chinese-formal", "simp-chinese-informal", "single", | |||
"skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal", | |||
"slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow", | |||
"small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali", | |||
"source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "spell-out", "square", | |||
"square-button", "start", "static", "status-bar", "stretch", "stroke", "sub", | |||
"subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "table", | |||
"source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "space-evenly", "spell-out", "square", | |||
"square-button", "start", "static", "status-bar", "stretch", "stroke", "stroke-box", "sub", | |||
"subpixel-antialiased", "svg_masks", "super", "sw-resize", "symbolic", "symbols", "system-ui", "table", | |||
"table-caption", "table-cell", "table-column", "table-column-group", | |||
"table-footer-group", "table-header-group", "table-row", "table-row-group", | |||
"tamil", | |||
@@ -677,10 +708,10 @@ CodeMirror.defineMode("css", function(config, parserConfig) { | |||
"tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top", | |||
"trad-chinese-formal", "trad-chinese-informal", "transform", | |||
"translate", "translate3d", "translateX", "translateY", "translateZ", | |||
"transparent", "ultra-condensed", "ultra-expanded", "underline", "unset", "up", | |||
"transparent", "ultra-condensed", "ultra-expanded", "underline", "unidirectional-pan", "unset", "up", | |||
"upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal", | |||
"upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", | |||
"var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted", | |||
"var", "vertical", "vertical-text", "view-box", "visible", "visibleFill", "visiblePainted", | |||
"visibleStroke", "visual", "w-resize", "wait", "wave", "wider", | |||
"window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor", | |||
"xx-large", "xx-small" | |||
@@ -748,8 +779,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) { | |||
} | |||
}, | |||
":": function(stream) { | |||
if (stream.match(/\s*\{/)) | |||
return [null, "{"]; | |||
if (stream.match(/^\s*\{/, false)) | |||
return [null, null] | |||
return false; | |||
}, | |||
"$": function(stream) { | |||
@@ -792,7 +823,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) { | |||
}, | |||
"@": function(stream) { | |||
if (stream.eat("{")) return [null, "interpolation"]; | |||
if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false; | |||
if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/i, false)) return false; | |||
stream.eatWhile(/[\w\\\-]/); | |||
if (stream.match(/^\s*:/, false)) | |||
return ["variable-2", "variable-definition"]; | |||
@@ -1,5 +1,5 @@ | |||
// 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/5/LICENSE | |||
(function() { | |||
"use strict"; | |||
@@ -1,5 +1,5 @@ | |||
// 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/5/LICENSE | |||
(function() { | |||
"use strict"; | |||
@@ -10,8 +10,8 @@ | |||
MT("variable", | |||
"[variable-2 @base]: [atom #f04615];", | |||
"[qualifier .class] {", | |||
" [property width]: [variable percentage]([number 0.5]); [comment // returns `50%`]", | |||
" [property color]: [variable saturate]([variable-2 @base], [number 5%]);", | |||
" [property width]: [variable&callee percentage]([number 0.5]); [comment // returns `50%`]", | |||
" [property color]: [variable&callee saturate]([variable-2 @base], [number 5%]);", | |||
"}"); | |||
MT("amp", | |||
@@ -26,10 +26,10 @@ | |||
MT("mixin", | |||
"[qualifier .mixin] ([variable dark]; [variable-2 @color]) {", | |||
" [property color]: [atom darken]([variable-2 @color], [number 10%]);", | |||
" [property color]: [variable&callee darken]([variable-2 @color], [number 10%]);", | |||
"}", | |||
"[qualifier .mixin] ([variable light]; [variable-2 @color]) {", | |||
" [property color]: [atom lighten]([variable-2 @color], [number 10%]);", | |||
" [property color]: [variable&callee lighten]([variable-2 @color], [number 10%]);", | |||
"}", | |||
"[qualifier .mixin] ([variable-2 @_]; [variable-2 @color]) {", | |||
" [property display]: [atom block];", | |||
@@ -1,24 +1,24 @@ | |||
// 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/5/LICENSE | |||
(function() { | |||
var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-scss"); | |||
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "scss"); } | |||
MT('url_with_quotation', | |||
"[tag foo] { [property background]:[atom url]([string test.jpg]) }"); | |||
"[tag foo] { [property background]:[variable&callee url]([string test.jpg]) }"); | |||
MT('url_with_double_quotes', | |||
"[tag foo] { [property background]:[atom url]([string \"test.jpg\"]) }"); | |||
"[tag foo] { [property background]:[variable&callee url]([string \"test.jpg\"]) }"); | |||
MT('url_with_single_quotes', | |||
"[tag foo] { [property background]:[atom url]([string \'test.jpg\']) }"); | |||
"[tag foo] { [property background]:[variable&callee url]([string \'test.jpg\']) }"); | |||
MT('string', | |||
"[def @import] [string \"compass/css3\"]"); | |||
MT('important_keyword', | |||
"[tag foo] { [property background]:[atom url]([string \'test.jpg\']) [keyword !important] }"); | |||
"[tag foo] { [property background]:[variable&callee url]([string \'test.jpg\']) [keyword !important] }"); | |||
MT('variable', | |||
"[variable-2 $blue]:[atom #333]"); | |||
@@ -95,7 +95,7 @@ | |||
MT('indent_parentheses', | |||
"[tag foo] {", | |||
" [property color]: [atom darken]([variable-2 $blue],", | |||
" [property color]: [variable&callee darken]([variable-2 $blue],", | |||
" [number 9%]);", | |||
"}"); | |||
@@ -1,5 +1,5 @@ | |||
// 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/5/LICENSE | |||
(function() { | |||
var mode = CodeMirror.getMode({indentUnit: 2}, "css"); | |||
@@ -24,6 +24,9 @@ | |||
MT("atMediaUnknownFeatureValueKeyword", | |||
"[def @media] ([property orientation]: [error upsidedown]) { }"); | |||
MT("atMediaUppercase", | |||
"[def @MEDIA] ([property orienTAtion]: [keyword landScape]) { }"); | |||
MT("tagSelector", | |||
"[tag foo] { }"); | |||
@@ -86,11 +89,11 @@ | |||
"[tag foo] { [property margin]: [number 0]; [property padding]: [number 0]; }"); | |||
MT("tagTwoPropertiesURL", | |||
"[tag foo] { [property background]: [atom url]([string //example.com/foo.png]); [property padding]: [number 0]; }"); | |||
"[tag foo] { [property background]: [variable&callee url]([string //example.com/foo.png]); [property padding]: [number 0]; }"); | |||
MT("indent_tagSelector", | |||
"[tag strong], [tag em] {", | |||
" [property background]: [atom rgba](", | |||
" [property background]: [variable&callee rgba](", | |||
" [number 255], [number 255], [number 0], [number .2]", | |||
" );", | |||
"}"); | |||
@@ -111,7 +114,7 @@ | |||
MT("indent_parentheses", | |||
"[tag foo]:[variable-3 before] {", | |||
" [property background]: [atom url](", | |||
" [property background]: [variable&callee url](", | |||
"[string blahblah]", | |||
"[string etc]", | |||
"[string ]) [keyword !important];", | |||
@@ -121,20 +124,20 @@ | |||
"[def @font-face] {", | |||
" [property font-family]: [string 'myfont'];", | |||
" [error nonsense]: [string 'abc'];", | |||
" [property src]: [atom url]([string http://blah]),", | |||
" [atom url]([string http://foo]);", | |||
" [property src]: [variable&callee url]([string http://blah]),", | |||
" [variable&callee url]([string http://foo]);", | |||
"}"); | |||
MT("empty_url", | |||
"[def @import] [atom url]() [attribute screen];"); | |||
"[def @import] [variable&callee url]() [attribute screen];"); | |||
MT("parens", | |||
"[qualifier .foo] {", | |||
" [property background-image]: [variable fade]([atom #000], [number 20%]);", | |||
" [property border-image]: [atom linear-gradient](", | |||
" [property background-image]: [variable&callee fade]([atom #000], [number 20%]);", | |||
" [property border-image]: [variable&callee linear-gradient](", | |||
" [atom to] [atom bottom],", | |||
" [variable fade]([atom #000], [number 20%]) [number 0%],", | |||
" [variable fade]([atom #000], [number 20%]) [number 100%]", | |||
" [variable&callee fade]([atom #000], [number 20%]) [number 0%],", | |||
" [variable&callee fade]([atom #000], [number 20%]) [number 100%]", | |||
" );", | |||
"}"); | |||
@@ -143,7 +146,15 @@ | |||
" [variable-2 --main-color]: [atom #06c];", | |||
"}", | |||
"[tag h1][builtin #foo] {", | |||
" [property color]: [atom var]([variable-2 --main-color]);", | |||
" [property color]: [variable&callee var]([variable-2 --main-color]);", | |||
"}"); | |||
MT("blank_css_variable", | |||
":[variable-3 root] {", | |||
" [variable-2 --]: [atom #06c];", | |||
"}", | |||
"[tag h1][builtin #foo] {", | |||
" [property color]: [variable&callee var]([variable-2 --]);", | |||
"}"); | |||
MT("supports", | |||
@@ -152,10 +163,10 @@ | |||
"}"); | |||
MT("document", | |||
"[def @document] [tag url]([string http://blah]),", | |||
" [tag url-prefix]([string https://]),", | |||
" [tag domain]([string blah.com]),", | |||
" [tag regexp]([string \".*blah.+\"]) {", | |||
"[def @document] [variable&callee url]([string http://blah]),", | |||
" [variable&callee url-prefix]([string https://]),", | |||
" [variable&callee domain]([string blah.com]),", | |||
" [variable&callee regexp]([string \".*blah.+\"]) {", | |||
" [builtin #id] {", | |||
" [property background-color]: [keyword white];", | |||
" }", | |||
@@ -165,16 +176,16 @@ | |||
"}"); | |||
MT("document_url", | |||
"[def @document] [tag url]([string http://blah]) { [qualifier .class] { } }"); | |||
"[def @document] [variable&callee url]([string http://blah]) { [qualifier .class] { } }"); | |||
MT("document_urlPrefix", | |||
"[def @document] [tag url-prefix]([string https://]) { [builtin #id] { } }"); | |||
"[def @document] [variable&callee url-prefix]([string https://]) { [builtin #id] { } }"); | |||
MT("document_domain", | |||
"[def @document] [tag domain]([string blah.com]) { [tag foo] { } }"); | |||
"[def @document] [variable&callee domain]([string blah.com]) { [tag foo] { } }"); | |||
MT("document_regexp", | |||
"[def @document] [tag regexp]([string \".*blah.+\"]) { [builtin #id] { } }"); | |||
"[def @document] [variable&callee regexp]([string \".*blah.+\"]) { [builtin #id] { } }"); | |||
MT("counter-style", | |||
"[def @counter-style] [variable binary] {", | |||
@@ -196,5 +207,11 @@ | |||
"[tag ol][qualifier .roman] { [property list-style]: [variable simple-roman]; }"); | |||
MT("counter-style-symbols", | |||
"[tag ol] { [property list-style]: [atom symbols]([atom cyclic] [string \"*\"] [string \"\\2020\"] [string \"\\2021\"] [string \"\\A7\"]); }"); | |||
"[tag ol] { [property list-style]: [variable&callee symbols]([atom cyclic] [string \"*\"] [string \"\\2020\"] [string \"\\2021\"] [string \"\\A7\"]); }"); | |||
MT("comment-does-not-disrupt", | |||
"[def @font-face] [comment /* foo */] {", | |||
" [property src]: [variable&callee url]([string x]);", | |||
" [property font-family]: [variable One];", | |||
"}") | |||
})(); |
@@ -1,5 +1,5 @@ | |||
// 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/5/LICENSE | |||
(function(mod) { | |||
if (typeof exports == "object" && typeof module == "object") // CommonJS | |||
@@ -50,7 +50,7 @@ | |||
} | |||
function getTagRegexp(tagName, anchored) { | |||
return new RegExp((anchored ? "^" : "") + "<\/\s*" + tagName + "\s*>", "i"); | |||
return new RegExp((anchored ? "^" : "") + "<\/\\s*" + tagName + "\\s*>", "i"); | |||
} | |||
function addTags(from, to) { | |||
@@ -74,7 +74,8 @@ | |||
name: "xml", | |||
htmlMode: true, | |||
multilineTagIndentFactor: parserConfig.multilineTagIndentFactor, | |||
multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag | |||
multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag, | |||
allowMissingTagName: parserConfig.allowMissingTagName, | |||
}); | |||
var tags = {}; | |||
@@ -105,7 +106,7 @@ | |||
return maybeBackup(stream, endTag, state.localMode.token(stream, state.localState)); | |||
}; | |||
state.localMode = mode; | |||
state.localState = CodeMirror.startState(mode, htmlMode.indent(state.htmlState, "")); | |||
state.localState = CodeMirror.startState(mode, htmlMode.indent(state.htmlState, "", "")); | |||
} else if (state.inTag) { | |||
state.inTag += stream.current() | |||
if (stream.eol()) state.inTag += " " | |||
@@ -133,11 +134,11 @@ | |||
return state.token(stream, state); | |||
}, | |||
indent: function (state, textAfter) { | |||
indent: function (state, textAfter, line) { | |||
if (!state.localMode || /^\s*<\//.test(textAfter)) | |||
return htmlMode.indent(state.htmlState, textAfter); | |||
return htmlMode.indent(state.htmlState, textAfter, line); | |||
else if (state.localMode.indent) | |||
return state.localMode.indent(state.localState, textAfter); | |||
return state.localMode.indent(state.localState, textAfter, line); | |||
else | |||
return CodeMirror.Pass; | |||
}, | |||
@@ -1,5 +1,5 @@ | |||
// 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/5/LICENSE | |||
(function(mod) { | |||
if (typeof exports == "object" && typeof module == "object") // CommonJS | |||
@@ -11,16 +11,12 @@ | |||
})(function(CodeMirror) { | |||
"use strict"; | |||
function expressionAllowed(stream, state, backUp) { | |||
return /^(?:operator|sof|keyword c|case|new|export|default|[\[{}\(,;:]|=>)$/.test(state.lastType) || | |||
(state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0)))) | |||
} | |||
CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
var indentUnit = config.indentUnit; | |||
var statementIndent = parserConfig.statementIndent; | |||
var jsonldMode = parserConfig.jsonld; | |||
var jsonMode = parserConfig.json || jsonldMode; | |||
var trackScope = parserConfig.trackScope !== false | |||
var isTS = parserConfig.typescript; | |||
var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/; | |||
@@ -28,56 +24,24 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
var keywords = function(){ | |||
function kw(type) {return {type: type, style: "keyword"};} | |||
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); | |||
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"), D = kw("keyword d"); | |||
var operator = kw("operator"), atom = {type: "atom", style: "atom"}; | |||
var jsKeywords = { | |||
return { | |||
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, | |||
"return": C, "break": C, "continue": C, "new": kw("new"), "delete": C, "throw": C, "debugger": C, | |||
"var": kw("var"), "const": kw("var"), "let": kw("var"), | |||
"return": D, "break": D, "continue": D, "new": kw("new"), "delete": C, "void": C, "throw": C, | |||
"debugger": kw("debugger"), "var": kw("var"), "const": kw("var"), "let": kw("var"), | |||
"function": kw("function"), "catch": kw("catch"), | |||
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), | |||
"in": operator, "typeof": operator, "instanceof": operator, | |||
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, | |||
"this": kw("this"), "class": kw("class"), "super": kw("atom"), | |||
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C, | |||
"await": C, "async": kw("async") | |||
"await": C | |||
}; | |||
// Extend the 'normal' keywords with the TypeScript language extensions | |||
if (isTS) { | |||
var type = {type: "variable", style: "variable-3"}; | |||
var tsKeywords = { | |||
// object-like things | |||
"interface": kw("class"), | |||
"implements": C, | |||
"namespace": C, | |||
"module": kw("module"), | |||
"enum": kw("module"), | |||
"type": kw("type"), | |||
// scope modifiers | |||
"public": kw("modifier"), | |||
"private": kw("modifier"), | |||
"protected": kw("modifier"), | |||
"abstract": kw("modifier"), | |||
// operators | |||
"as": operator, | |||
// types | |||
"string": type, "number": type, "boolean": type, "any": type | |||
}; | |||
for (var attr in tsKeywords) { | |||
jsKeywords[attr] = tsKeywords[attr]; | |||
} | |||
} | |||
return jsKeywords; | |||
}(); | |||
var isOperatorChar = /[+\-*&%=<>!?|~^]/; | |||
var isOperatorChar = /[+\-*&%=<>!?|~^@]/; | |||
var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/; | |||
function readRegexp(stream) { | |||
@@ -104,7 +68,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
if (ch == '"' || ch == "'") { | |||
state.tokenize = tokenString(ch); | |||
return state.tokenize(stream, state); | |||
} else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) { | |||
} else if (ch == "." && stream.match(/^\d[\d_]*(?:[eE][+\-]?[\d_]+)?/)) { | |||
return ret("number", "number"); | |||
} else if (ch == "." && stream.match("..")) { | |||
return ret("spread", "meta"); | |||
@@ -112,17 +76,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
return ret(ch); | |||
} else if (ch == "=" && stream.eat(">")) { | |||
return ret("=>", "operator"); | |||
} else if (ch == "0" && stream.eat(/x/i)) { | |||
stream.eatWhile(/[\da-f]/i); | |||
return ret("number", "number"); | |||
} else if (ch == "0" && stream.eat(/o/i)) { | |||
stream.eatWhile(/[0-7]/i); | |||
return ret("number", "number"); | |||
} else if (ch == "0" && stream.eat(/b/i)) { | |||
stream.eatWhile(/[01]/i); | |||
} else if (ch == "0" && stream.match(/^(?:x[\dA-Fa-f_]+|o[0-7_]+|b[01_]+)n?/)) { | |||
return ret("number", "number"); | |||
} else if (/\d/.test(ch)) { | |||
stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); | |||
stream.match(/^[\d_]*(?:n|(?:\.[\d_]*)?(?:[eE][+\-]?[\d_]+)?)?/); | |||
return ret("number", "number"); | |||
} else if (ch == "/") { | |||
if (stream.eat("*")) { | |||
@@ -133,27 +90,47 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
return ret("comment", "comment"); | |||
} else if (expressionAllowed(stream, state, 1)) { | |||
readRegexp(stream); | |||
stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/); | |||
stream.match(/^\b(([gimyus])(?![gimyus]*\2))+\b/); | |||
return ret("regexp", "string-2"); | |||
} else { | |||
stream.eatWhile(isOperatorChar); | |||
stream.eat("="); | |||
return ret("operator", "operator", stream.current()); | |||
} | |||
} else if (ch == "`") { | |||
state.tokenize = tokenQuasi; | |||
return tokenQuasi(stream, state); | |||
} else if (ch == "#") { | |||
} else if (ch == "#" && stream.peek() == "!") { | |||
stream.skipToEnd(); | |||
return ret("error", "error"); | |||
return ret("meta", "meta"); | |||
} else if (ch == "#" && stream.eatWhile(wordRE)) { | |||
return ret("variable", "property") | |||
} else if (ch == "<" && stream.match("!--") || | |||
(ch == "-" && stream.match("->") && !/\S/.test(stream.string.slice(0, stream.start)))) { | |||
stream.skipToEnd() | |||
return ret("comment", "comment") | |||
} else if (isOperatorChar.test(ch)) { | |||
if (ch != ">" || !state.lexical || state.lexical.type != ">") | |||
stream.eatWhile(isOperatorChar); | |||
if (ch != ">" || !state.lexical || state.lexical.type != ">") { | |||
if (stream.eat("=")) { | |||
if (ch == "!" || ch == "=") stream.eat("=") | |||
} else if (/[<>*+\-|&?]/.test(ch)) { | |||
stream.eat(ch) | |||
if (ch == ">") stream.eat(ch) | |||
} | |||
} | |||
if (ch == "?" && stream.eat(".")) return ret(".") | |||
return ret("operator", "operator", stream.current()); | |||
} else if (wordRE.test(ch)) { | |||
stream.eatWhile(wordRE); | |||
var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; | |||
return (known && state.lastType != ".") ? ret(known.type, known.style, word) : | |||
ret("variable", "variable", word); | |||
var word = stream.current() | |||
if (state.lastType != ".") { | |||
if (keywords.propertyIsEnumerable(word)) { | |||
var kw = keywords[word] | |||
return ret(kw.type, kw.style, word) | |||
} | |||
if (word == "async" && stream.match(/^(\s|\/\*([^*]|\*(?!\/))*?\*\/)*[\[\(\w]/, false)) | |||
return ret("async", "keyword", word) | |||
} | |||
return ret("variable", "variable", word) | |||
} | |||
} | |||
@@ -226,8 +203,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
++depth; | |||
} else if (wordRE.test(ch)) { | |||
sawSomething = true; | |||
} else if (/["'\/]/.test(ch)) { | |||
return; | |||
} else if (/["'\/`]/.test(ch)) { | |||
for (;; --pos) { | |||
if (pos == 0) return | |||
var next = stream.string.charAt(pos - 1) | |||
if (next == ch && stream.string.charAt(pos - 2) != "\\") { pos--; break } | |||
} | |||
} else if (sawSomething && !depth) { | |||
++pos; | |||
break; | |||
@@ -238,7 +219,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
// Parser | |||
var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true}; | |||
var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, | |||
"regexp": true, "this": true, "import": true, "jsonld-keyword": true}; | |||
function JSLexical(indented, column, type, align, prev, info) { | |||
this.indented = indented; | |||
@@ -250,6 +232,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
} | |||
function inScope(state, varname) { | |||
if (!trackScope) return false | |||
for (var v = state.localVars; v; v = v.next) | |||
if (v.name == varname) return true; | |||
for (var cx = state.context; cx; cx = cx.prev) { | |||
@@ -289,35 +272,70 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
pass.apply(null, arguments); | |||
return true; | |||
} | |||
function inList(name, list) { | |||
for (var v = list; v; v = v.next) if (v.name == name) return true | |||
return false; | |||
} | |||
function register(varname) { | |||
function inList(list) { | |||
for (var v = list; v; v = v.next) | |||
if (v.name == varname) return true; | |||
return false; | |||
} | |||
var state = cx.state; | |||
cx.marked = "def"; | |||
if (!trackScope) return | |||
if (state.context) { | |||
if (inList(state.localVars)) return; | |||
state.localVars = {name: varname, next: state.localVars}; | |||
if (state.lexical.info == "var" && state.context && state.context.block) { | |||
// FIXME function decls are also not block scoped | |||
var newContext = registerVarScoped(varname, state.context) | |||
if (newContext != null) { | |||
state.context = newContext | |||
return | |||
} | |||
} else if (!inList(varname, state.localVars)) { | |||
state.localVars = new Var(varname, state.localVars) | |||
return | |||
} | |||
} | |||
// Fall through means this is global | |||
if (parserConfig.globalVars && !inList(varname, state.globalVars)) | |||
state.globalVars = new Var(varname, state.globalVars) | |||
} | |||
function registerVarScoped(varname, context) { | |||
if (!context) { | |||
return null | |||
} else if (context.block) { | |||
var inner = registerVarScoped(varname, context.prev) | |||
if (!inner) return null | |||
if (inner == context.prev) return context | |||
return new Context(inner, context.vars, true) | |||
} else if (inList(varname, context.vars)) { | |||
return context | |||
} else { | |||
if (inList(state.globalVars)) return; | |||
if (parserConfig.globalVars) | |||
state.globalVars = {name: varname, next: state.globalVars}; | |||
return new Context(context.prev, new Var(varname, context.vars), false) | |||
} | |||
} | |||
function isModifier(name) { | |||
return name == "public" || name == "private" || name == "protected" || name == "abstract" || name == "readonly" | |||
} | |||
// Combinators | |||
var defaultVars = {name: "this", next: {name: "arguments"}}; | |||
function Context(prev, vars, block) { this.prev = prev; this.vars = vars; this.block = block } | |||
function Var(name, next) { this.name = name; this.next = next } | |||
var defaultVars = new Var("this", new Var("arguments", null)) | |||
function pushcontext() { | |||
cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; | |||
cx.state.localVars = defaultVars; | |||
cx.state.context = new Context(cx.state.context, cx.state.localVars, false) | |||
cx.state.localVars = defaultVars | |||
} | |||
function pushblockcontext() { | |||
cx.state.context = new Context(cx.state.context, cx.state.localVars, true) | |||
cx.state.localVars = null | |||
} | |||
pushcontext.lex = pushblockcontext.lex = true | |||
function popcontext() { | |||
cx.state.localVars = cx.state.context.vars; | |||
cx.state.context = cx.state.context.prev; | |||
cx.state.localVars = cx.state.context.vars | |||
cx.state.context = cx.state.context.prev | |||
} | |||
popcontext.lex = true | |||
function pushlex(type, info) { | |||
var result = function() { | |||
var state = cx.state, indent = state.indented; | |||
@@ -342,17 +360,19 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
function expect(wanted) { | |||
function exp(type) { | |||
if (type == wanted) return cont(); | |||
else if (wanted == ";") return pass(); | |||
else if (wanted == ";" || type == "}" || type == ")" || type == "]") return pass(); | |||
else return cont(exp); | |||
}; | |||
return exp; | |||
} | |||
function statement(type, value) { | |||
if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex); | |||
if (type == "var") return cont(pushlex("vardef", value), vardef, expect(";"), poplex); | |||
if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex); | |||
if (type == "keyword b") return cont(pushlex("form"), statement, poplex); | |||
if (type == "{") return cont(pushlex("}"), block, poplex); | |||
if (type == "keyword d") return cx.stream.match(/^\s*$/, false) ? cont() : cont(pushlex("stat"), maybeexpression, expect(";"), poplex); | |||
if (type == "debugger") return cont(expect(";")); | |||
if (type == "{") return cont(pushlex("}"), pushblockcontext, block, poplex, popcontext); | |||
if (type == ";") return cont(); | |||
if (type == "if") { | |||
if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex) | |||
@@ -360,44 +380,66 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
return cont(pushlex("form"), parenExpr, statement, poplex, maybeelse); | |||
} | |||
if (type == "function") return cont(functiondef); | |||
if (type == "for") return cont(pushlex("form"), forspec, statement, poplex); | |||
if (type == "variable") return cont(pushlex("stat"), maybelabel); | |||
if (type == "switch") return cont(pushlex("form"), parenExpr, pushlex("}", "switch"), expect("{"), | |||
block, poplex, poplex); | |||
if (type == "for") return cont(pushlex("form"), pushblockcontext, forspec, statement, popcontext, poplex); | |||
if (type == "class" || (isTS && value == "interface")) { | |||
cx.marked = "keyword" | |||
return cont(pushlex("form", type == "class" ? type : value), className, poplex) | |||
} | |||
if (type == "variable") { | |||
if (isTS && value == "declare") { | |||
cx.marked = "keyword" | |||
return cont(statement) | |||
} else if (isTS && (value == "module" || value == "enum" || value == "type") && cx.stream.match(/^\s*\w/, false)) { | |||
cx.marked = "keyword" | |||
if (value == "enum") return cont(enumdef); | |||
else if (value == "type") return cont(typename, expect("operator"), typeexpr, expect(";")); | |||
else return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex) | |||
} else if (isTS && value == "namespace") { | |||
cx.marked = "keyword" | |||
return cont(pushlex("form"), expression, statement, poplex) | |||
} else if (isTS && value == "abstract") { | |||
cx.marked = "keyword" | |||
return cont(statement) | |||
} else { | |||
return cont(pushlex("stat"), maybelabel); | |||
} | |||
} | |||
if (type == "switch") return cont(pushlex("form"), parenExpr, expect("{"), pushlex("}", "switch"), pushblockcontext, | |||
block, poplex, poplex, popcontext); | |||
if (type == "case") return cont(expression, expect(":")); | |||
if (type == "default") return cont(expect(":")); | |||
if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), | |||
statement, poplex, popcontext); | |||
if (type == "class") return cont(pushlex("form"), className, poplex); | |||
if (type == "catch") return cont(pushlex("form"), pushcontext, maybeCatchBinding, statement, poplex, popcontext); | |||
if (type == "export") return cont(pushlex("stat"), afterExport, poplex); | |||
if (type == "import") return cont(pushlex("stat"), afterImport, poplex); | |||
if (type == "module") return cont(pushlex("form"), pattern, pushlex("}"), expect("{"), block, poplex, poplex) | |||
if (type == "type") return cont(typeexpr, expect("operator"), typeexpr, expect(";")); | |||
if (type == "async") return cont(statement) | |||
if (value == "@") return cont(expression, statement) | |||
return pass(pushlex("stat"), expression, expect(";"), poplex); | |||
} | |||
function expression(type) { | |||
return expressionInner(type, false); | |||
function maybeCatchBinding(type) { | |||
if (type == "(") return cont(funarg, expect(")")) | |||
} | |||
function expressionNoComma(type) { | |||
return expressionInner(type, true); | |||
function expression(type, value) { | |||
return expressionInner(type, value, false); | |||
} | |||
function expressionNoComma(type, value) { | |||
return expressionInner(type, value, true); | |||
} | |||
function parenExpr(type) { | |||
if (type != "(") return pass() | |||
return cont(pushlex(")"), expression, expect(")"), poplex) | |||
return cont(pushlex(")"), maybeexpression, expect(")"), poplex) | |||
} | |||
function expressionInner(type, noComma) { | |||
function expressionInner(type, value, noComma) { | |||
if (cx.state.fatArrowAt == cx.stream.start) { | |||
var body = noComma ? arrowBodyNoComma : arrowBody; | |||
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext); | |||
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, expect("=>"), body, popcontext); | |||
else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext); | |||
} | |||
var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; | |||
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); | |||
if (type == "function") return cont(functiondef, maybeop); | |||
if (type == "class") return cont(pushlex("form"), classExpression, poplex); | |||
if (type == "keyword c" || type == "async") return cont(noComma ? maybeexpressionNoComma : maybeexpression); | |||
if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), classExpression, poplex); } | |||
if (type == "keyword c" || type == "async") return cont(noComma ? expressionNoComma : expression); | |||
if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop); | |||
if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression); | |||
if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop); | |||
@@ -410,13 +452,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
if (type.match(/[;\}\)\],]/)) return pass(); | |||
return pass(expression); | |||
} | |||
function maybeexpressionNoComma(type) { | |||
if (type.match(/[;\}\)\],]/)) return pass(); | |||
return pass(expressionNoComma); | |||
} | |||
function maybeoperatorComma(type, value) { | |||
if (type == ",") return cont(expression); | |||
if (type == ",") return cont(maybeexpression); | |||
return maybeoperatorNoComma(type, value, false); | |||
} | |||
function maybeoperatorNoComma(type, value, noComma) { | |||
@@ -424,7 +462,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
var expr = noComma == false ? expression : expressionNoComma; | |||
if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); | |||
if (type == "operator") { | |||
if (/\+\+|--/.test(value)) return cont(me); | |||
if (/\+\+|--/.test(value) || isTS && value == "!") return cont(me); | |||
if (isTS && value == "<" && cx.stream.match(/^([^<>]|<[^<>]*>)*>\s*\(/, false)) | |||
return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, me); | |||
if (value == "?") return cont(expression, expect(":"), expr); | |||
return cont(expr); | |||
} | |||
@@ -433,11 +473,17 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
if (type == "(") return contCommasep(expressionNoComma, ")", "call", me); | |||
if (type == ".") return cont(property, me); | |||
if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me); | |||
if (isTS && value == "as") { cx.marked = "keyword"; return cont(typeexpr, me) } | |||
if (type == "regexp") { | |||
cx.state.lastType = cx.marked = "operator" | |||
cx.stream.backUp(cx.stream.pos - cx.stream.start - 1) | |||
return cont(expr) | |||
} | |||
} | |||
function quasi(type, value) { | |||
if (type != "quasi") return pass(); | |||
if (value.slice(value.length - 2) != "${") return cont(quasi); | |||
return cont(expression, continueQuasi); | |||
return cont(maybeexpression, continueQuasi); | |||
} | |||
function continueQuasi(type) { | |||
if (type == "}") { | |||
@@ -457,6 +503,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
function maybeTarget(noComma) { | |||
return function(type) { | |||
if (type == ".") return cont(noComma ? targetNoComma : target); | |||
else if (type == "variable" && isTS) return cont(maybeTypeArgs, noComma ? maybeoperatorNoComma : maybeoperatorComma) | |||
else return pass(noComma ? expressionNoComma : expression); | |||
}; | |||
} | |||
@@ -480,18 +527,25 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
} else if (type == "variable" || cx.style == "keyword") { | |||
cx.marked = "property"; | |||
if (value == "get" || value == "set") return cont(getterSetter); | |||
var m // Work around fat-arrow-detection complication for detecting typescript typed arrow params | |||
if (isTS && cx.state.fatArrowAt == cx.stream.start && (m = cx.stream.match(/^\s*:\s*/, false))) | |||
cx.state.fatArrowAt = cx.stream.pos + m[0].length | |||
return cont(afterprop); | |||
} else if (type == "number" || type == "string") { | |||
cx.marked = jsonldMode ? "property" : (cx.style + " property"); | |||
return cont(afterprop); | |||
} else if (type == "jsonld-keyword") { | |||
return cont(afterprop); | |||
} else if (type == "modifier") { | |||
} else if (isTS && isModifier(value)) { | |||
cx.marked = "keyword" | |||
return cont(objprop) | |||
} else if (type == "[") { | |||
return cont(expression, expect("]"), afterprop); | |||
return cont(expression, maybetype, expect("]"), afterprop); | |||
} else if (type == "spread") { | |||
return cont(expression); | |||
return cont(expressionNoComma, afterprop); | |||
} else if (value == "*") { | |||
cx.marked = "keyword"; | |||
return cont(objprop); | |||
} else if (type == ":") { | |||
return pass(afterprop) | |||
} | |||
@@ -516,6 +570,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
}, proceed); | |||
} | |||
if (type == end || value == end) return cont(); | |||
if (sep && sep.indexOf(";") > -1) return pass(what) | |||
return cont(expect(end)); | |||
} | |||
return function(type, value) { | |||
@@ -538,42 +593,105 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
if (value == "?") return cont(maybetype); | |||
} | |||
} | |||
function typeexpr(type) { | |||
if (type == "variable") {cx.marked = "variable-3"; return cont(afterType);} | |||
function maybetypeOrIn(type, value) { | |||
if (isTS && (type == ":" || value == "in")) return cont(typeexpr) | |||
} | |||
function mayberettype(type) { | |||
if (isTS && type == ":") { | |||
if (cx.stream.match(/^\s*\w+\s+is\b/, false)) return cont(expression, isKW, typeexpr) | |||
else return cont(typeexpr) | |||
} | |||
} | |||
function isKW(_, value) { | |||
if (value == "is") { | |||
cx.marked = "keyword" | |||
return cont() | |||
} | |||
} | |||
function typeexpr(type, value) { | |||
if (value == "keyof" || value == "typeof" || value == "infer" || value == "readonly") { | |||
cx.marked = "keyword" | |||
return cont(value == "typeof" ? expressionNoComma : typeexpr) | |||
} | |||
if (type == "variable" || value == "void") { | |||
cx.marked = "type" | |||
return cont(afterType) | |||
} | |||
if (value == "|" || value == "&") return cont(typeexpr) | |||
if (type == "string" || type == "number" || type == "atom") return cont(afterType); | |||
if (type == "{") return cont(pushlex("}"), commasep(typeprop, "}", ",;"), poplex) | |||
if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType) | |||
if (type == "[") return cont(pushlex("]"), commasep(typeexpr, "]", ","), poplex, afterType) | |||
if (type == "{") return cont(pushlex("}"), typeprops, poplex, afterType) | |||
if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType, afterType) | |||
if (type == "<") return cont(commasep(typeexpr, ">"), typeexpr) | |||
if (type == "quasi") { return pass(quasiType, afterType); } | |||
} | |||
function maybeReturnType(type) { | |||
if (type == "=>") return cont(typeexpr) | |||
} | |||
function typeprops(type) { | |||
if (type.match(/[\}\)\]]/)) return cont() | |||
if (type == "," || type == ";") return cont(typeprops) | |||
return pass(typeprop, typeprops) | |||
} | |||
function typeprop(type, value) { | |||
if (type == "variable" || cx.style == "keyword") { | |||
cx.marked = "property" | |||
return cont(typeprop) | |||
} else if (value == "?") { | |||
} else if (value == "?" || type == "number" || type == "string") { | |||
return cont(typeprop) | |||
} else if (type == ":") { | |||
return cont(typeexpr) | |||
} else if (type == "[") { | |||
return cont(expect("variable"), maybetypeOrIn, expect("]"), typeprop) | |||
} else if (type == "(") { | |||
return pass(functiondecl, typeprop) | |||
} else if (!type.match(/[;\}\)\],]/)) { | |||
return cont() | |||
} | |||
} | |||
function quasiType(type, value) { | |||
if (type != "quasi") return pass(); | |||
if (value.slice(value.length - 2) != "${") return cont(quasiType); | |||
return cont(typeexpr, continueQuasiType); | |||
} | |||
function continueQuasiType(type) { | |||
if (type == "}") { | |||
cx.marked = "string-2"; | |||
cx.state.tokenize = tokenQuasi; | |||
return cont(quasiType); | |||
} | |||
} | |||
function typearg(type) { | |||
if (type == "variable") return cont(typearg) | |||
else if (type == ":") return cont(typeexpr) | |||
function typearg(type, value) { | |||
if (type == "variable" && cx.stream.match(/^\s*[?:]/, false) || value == "?") return cont(typearg) | |||
if (type == ":") return cont(typeexpr) | |||
if (type == "spread") return cont(typearg) | |||
return pass(typeexpr) | |||
} | |||
function afterType(type, value) { | |||
if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType) | |||
if (value == "|" || type == ".") return cont(typeexpr) | |||
if (type == "[") return cont(expect("]"), afterType) | |||
if (value == "|" || type == "." || value == "&") return cont(typeexpr) | |||
if (type == "[") return cont(typeexpr, expect("]"), afterType) | |||
if (value == "extends" || value == "implements") { cx.marked = "keyword"; return cont(typeexpr) } | |||
if (value == "?") return cont(typeexpr, expect(":"), typeexpr) | |||
} | |||
function maybeTypeArgs(_, value) { | |||
if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType) | |||
} | |||
function vardef() { | |||
function typeparam() { | |||
return pass(typeexpr, maybeTypeDefault) | |||
} | |||
function maybeTypeDefault(_, value) { | |||
if (value == "=") return cont(typeexpr) | |||
} | |||
function vardef(_, value) { | |||
if (value == "enum") {cx.marked = "keyword"; return cont(enumdef)} | |||
return pass(pattern, maybetype, maybeAssign, vardefCont); | |||
} | |||
function pattern(type, value) { | |||
if (type == "modifier") return cont(pattern) | |||
if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(pattern) } | |||
if (type == "variable") { register(value); return cont(); } | |||
if (type == "spread") return cont(pattern); | |||
if (type == "[") return contCommasep(pattern, "]"); | |||
if (type == "[") return contCommasep(eltpattern, "]"); | |||
if (type == "{") return contCommasep(proppattern, "}"); | |||
} | |||
function proppattern(type, value) { | |||
@@ -584,8 +702,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
if (type == "variable") cx.marked = "property"; | |||
if (type == "spread") return cont(pattern); | |||
if (type == "}") return pass(); | |||
if (type == "[") return cont(expression, expect(']'), expect(':'), proppattern); | |||
return cont(expect(":"), pattern, maybeAssign); | |||
} | |||
function eltpattern() { | |||
return pass(pattern, maybeAssign) | |||
} | |||
function maybeAssign(_type, value) { | |||
if (value == "=") return cont(expressionNoComma); | |||
} | |||
@@ -595,34 +717,46 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
function maybeelse(type, value) { | |||
if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex); | |||
} | |||
function forspec(type) { | |||
if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex); | |||
function forspec(type, value) { | |||
if (value == "await") return cont(forspec); | |||
if (type == "(") return cont(pushlex(")"), forspec1, poplex); | |||
} | |||
function forspec1(type) { | |||
if (type == "var") return cont(vardef, expect(";"), forspec2); | |||
if (type == ";") return cont(forspec2); | |||
if (type == "variable") return cont(formaybeinof); | |||
return pass(expression, expect(";"), forspec2); | |||
} | |||
function formaybeinof(_type, value) { | |||
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } | |||
return cont(maybeoperatorComma, forspec2); | |||
if (type == "var") return cont(vardef, forspec2); | |||
if (type == "variable") return cont(forspec2); | |||
return pass(forspec2) | |||
} | |||
function forspec2(type, value) { | |||
if (type == ";") return cont(forspec3); | |||
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } | |||
return pass(expression, expect(";"), forspec3); | |||
} | |||
function forspec3(type) { | |||
if (type != ")") cont(expression); | |||
if (type == ")") return cont() | |||
if (type == ";") return cont(forspec2) | |||
if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression, forspec2) } | |||
return pass(expression, forspec2) | |||
} | |||
function functiondef(type, value) { | |||
if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} | |||
if (type == "variable") {register(value); return cont(functiondef);} | |||
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, maybetype, statement, popcontext); | |||
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, mayberettype, statement, popcontext); | |||
if (isTS && value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondef) | |||
} | |||
function functiondecl(type, value) { | |||
if (value == "*") {cx.marked = "keyword"; return cont(functiondecl);} | |||
if (type == "variable") {register(value); return cont(functiondecl);} | |||
if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, mayberettype, popcontext); | |||
if (isTS && value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondecl) | |||
} | |||
function typename(type, value) { | |||
if (type == "keyword" || type == "variable") { | |||
cx.marked = "type" | |||
return cont(typename) | |||
} else if (value == "<") { | |||
return cont(pushlex(">"), commasep(typeparam, ">"), poplex) | |||
} | |||
} | |||
function funarg(type) { | |||
function funarg(type, value) { | |||
if (value == "@") cont(expression, funarg) | |||
if (type == "spread") return cont(funarg); | |||
if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(funarg); } | |||
if (isTS && type == "this") return cont(maybetype, maybeAssign) | |||
return pass(pattern, maybetype, maybeAssign); | |||
} | |||
function classExpression(type, value) { | |||
@@ -634,34 +768,44 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
if (type == "variable") {register(value); return cont(classNameAfter);} | |||
} | |||
function classNameAfter(type, value) { | |||
if (value == "extends" || value == "implements" || (isTS && type == ",")) | |||
if (value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, classNameAfter) | |||
if (value == "extends" || value == "implements" || (isTS && type == ",")) { | |||
if (value == "implements") cx.marked = "keyword"; | |||
return cont(isTS ? typeexpr : expression, classNameAfter); | |||
} | |||
if (type == "{") return cont(pushlex("}"), classBody, poplex); | |||
} | |||
function classBody(type, value) { | |||
if (type == "async" || | |||
(type == "variable" && | |||
(value == "static" || value == "get" || value == "set" || (isTS && isModifier(value))) && | |||
cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false))) { | |||
cx.marked = "keyword"; | |||
return cont(classBody); | |||
} | |||
if (type == "variable" || cx.style == "keyword") { | |||
if ((value == "async" || value == "static" || value == "get" || value == "set" || | |||
(isTS && (value == "public" || value == "private" || value == "protected" || value == "readonly" || value == "abstract"))) && | |||
cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false)) { | |||
cx.marked = "keyword"; | |||
return cont(classBody); | |||
} | |||
cx.marked = "property"; | |||
return cont(isTS ? classfield : functiondef, classBody); | |||
return cont(classfield, classBody); | |||
} | |||
if (type == "number" || type == "string") return cont(classfield, classBody); | |||
if (type == "[") | |||
return cont(expression, expect("]"), isTS ? classfield : functiondef, classBody) | |||
return cont(expression, maybetype, expect("]"), classfield, classBody) | |||
if (value == "*") { | |||
cx.marked = "keyword"; | |||
return cont(classBody); | |||
} | |||
if (type == ";") return cont(classBody); | |||
if (isTS && type == "(") return pass(functiondecl, classBody) | |||
if (type == ";" || type == ",") return cont(classBody); | |||
if (type == "}") return cont(); | |||
if (value == "@") return cont(expression, classBody) | |||
} | |||
function classfield(type, value) { | |||
if (value == "!") return cont(classfield) | |||
if (value == "?") return cont(classfield) | |||
if (type == ":") return cont(typeexpr, maybeAssign) | |||
return pass(functiondef) | |||
if (value == "=") return cont(expressionNoComma) | |||
var context = cx.state.lexical.prev, isInterface = context && context.info == "interface" | |||
return pass(isInterface ? functiondecl : functiondef) | |||
} | |||
function afterExport(type, value) { | |||
if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); } | |||
@@ -675,6 +819,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
} | |||
function afterImport(type) { | |||
if (type == "string") return cont(); | |||
if (type == "(") return pass(expression); | |||
if (type == ".") return pass(maybeoperatorComma); | |||
return pass(importSpec, maybeMoreImports, maybeFrom); | |||
} | |||
function importSpec(type, value) { | |||
@@ -696,6 +842,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
if (type == "]") return cont(); | |||
return pass(commasep(expressionNoComma, "]")); | |||
} | |||
function enumdef() { | |||
return pass(pushlex("form"), pattern, expect("{"), pushlex("}"), commasep(enummember, "}"), poplex, poplex) | |||
} | |||
function enummember() { | |||
return pass(pattern, maybeAssign); | |||
} | |||
function isContinuedStatement(state, textAfter) { | |||
return state.lastType == "operator" || state.lastType == "," || | |||
@@ -703,6 +855,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
/[,.]/.test(textAfter.charAt(0)); | |||
} | |||
function expressionAllowed(stream, state, backUp) { | |||
return state.tokenize == tokenBase && | |||
/^(?:operator|sof|keyword [bcd]|case|new|export|default|spread|[\[{}\(,;:]|=>)$/.test(state.lastType) || | |||
(state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0)))) | |||
} | |||
// Interface | |||
return { | |||
@@ -713,7 +871,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
cc: [], | |||
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), | |||
localVars: parserConfig.localVars, | |||
context: parserConfig.localVars && {vars: parserConfig.localVars}, | |||
context: parserConfig.localVars && new Context(null, null, false), | |||
indented: basecolumn || 0 | |||
}; | |||
if (parserConfig.globalVars && typeof parserConfig.globalVars == "object") | |||
@@ -736,14 +894,14 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
}, | |||
indent: function(state, textAfter) { | |||
if (state.tokenize == tokenComment) return CodeMirror.Pass; | |||
if (state.tokenize == tokenComment || state.tokenize == tokenQuasi) return CodeMirror.Pass; | |||
if (state.tokenize != tokenBase) return 0; | |||
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, top | |||
// Kludge to prevent 'maybelse' from blocking lexical scope pops | |||
if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) { | |||
var c = state.cc[i]; | |||
if (c == poplex) lexical = lexical.prev; | |||
else if (c != maybeelse) break; | |||
else if (c != maybeelse && c != popcontext) break; | |||
} | |||
while ((lexical.type == "stat" || lexical.type == "form") && | |||
(firstChar == "}" || ((top = state.cc[state.cc.length - 1]) && | |||
@@ -754,7 +912,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
lexical = lexical.prev; | |||
var type = lexical.type, closing = firstChar == type; | |||
if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0); | |||
if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info.length + 1 : 0); | |||
else if (type == "form" && firstChar == "{") return lexical.indented; | |||
else if (type == "form") return lexical.indented + indentUnit; | |||
else if (type == "stat") | |||
@@ -768,6 +926,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
electricInput: /^\s*(?:case .*?:|default:|\{|\})$/, | |||
blockCommentStart: jsonMode ? null : "/*", | |||
blockCommentEnd: jsonMode ? null : "*/", | |||
blockCommentContinue: jsonMode ? null : " * ", | |||
lineComment: jsonMode ? null : "//", | |||
fold: "brace", | |||
closeBrackets: "()[]{}''\"\"``", | |||
@@ -777,9 +936,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { | |||
jsonMode: jsonMode, | |||
expressionAllowed: expressionAllowed, | |||
skipExpression: function(state) { | |||
var top = state.cc[state.cc.length - 1] | |||
if (top == expression || top == expressionNoComma) state.cc.pop() | |||
parseJS(state, "atom", "atom", "true", new CodeMirror.StringStream("", 2, null)) | |||
} | |||
}; | |||
}); | |||
@@ -791,9 +950,10 @@ CodeMirror.defineMIME("text/ecmascript", "javascript"); | |||
CodeMirror.defineMIME("application/javascript", "javascript"); | |||
CodeMirror.defineMIME("application/x-javascript", "javascript"); | |||
CodeMirror.defineMIME("application/ecmascript", "javascript"); | |||
CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); | |||
CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); | |||
CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true}); | |||
CodeMirror.defineMIME("application/json", { name: "javascript", json: true }); | |||
CodeMirror.defineMIME("application/x-json", { name: "javascript", json: true }); | |||
CodeMirror.defineMIME("application/manifest+json", { name: "javascript", json: true }) | |||
CodeMirror.defineMIME("application/ld+json", { name: "javascript", jsonld: true }); | |||
CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true }); | |||
CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true }); | |||
@@ -1,5 +1,5 @@ | |||
// 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/5/LICENSE | |||
(function() { | |||
var mode = CodeMirror.getMode({indentUnit: 2}, "javascript"); | |||
@@ -63,6 +63,12 @@ | |||
MT("import_trailing_comma", | |||
"[keyword import] {[def foo], [def bar],} [keyword from] [string 'baz']") | |||
MT("import_dynamic", | |||
"[keyword import]([string 'baz']).[property then]") | |||
MT("import_dynamic", | |||
"[keyword const] [def t] [operator =] [keyword import]([string 'baz']).[property then]") | |||
MT("const", | |||
"[keyword function] [def f]() {", | |||
" [keyword const] [[ [def a], [def b] ]] [operator =] [[ [number 1], [number 2] ]];", | |||
@@ -71,12 +77,44 @@ | |||
MT("for/of", | |||
"[keyword for]([keyword let] [def of] [keyword of] [variable something]) {}"); | |||
MT("for await", | |||
"[keyword for] [keyword await]([keyword let] [def of] [keyword of] [variable something]) {}"); | |||
MT("generator", | |||
"[keyword function*] [def repeat]([def n]) {", | |||
" [keyword for]([keyword var] [def i] [operator =] [number 0]; [variable-2 i] [operator <] [variable-2 n]; [operator ++][variable-2 i])", | |||
" [keyword yield] [variable-2 i];", | |||
"}"); | |||
MT("let_scoping", | |||
"[keyword function] [def scoped]([def n]) {", | |||
" { [keyword var] [def i]; } [variable-2 i];", | |||
" { [keyword let] [def j]; [variable-2 j]; } [variable j];", | |||
" [keyword if] ([atom true]) { [keyword const] [def k]; [variable-2 k]; } [variable k];", | |||
"}"); | |||
MT("switch_scoping", | |||
"[keyword switch] ([variable x]) {", | |||
" [keyword default]:", | |||
" [keyword let] [def j];", | |||
" [keyword return] [variable-2 j]", | |||
"}", | |||
"[variable j];") | |||
MT("leaving_scope", | |||
"[keyword function] [def a]() {", | |||
" {", | |||
" [keyword const] [def x] [operator =] [number 1]", | |||
" [keyword if] ([atom true]) {", | |||
" [keyword let] [def y] [operator =] [number 2]", | |||
" [keyword var] [def z] [operator =] [number 3]", | |||
" [variable console].[property log]([variable-2 x], [variable-2 y], [variable-2 z])", | |||
" }", | |||
" [variable console].[property log]([variable-2 x], [variable y], [variable-2 z])", | |||
" }", | |||
" [variable console].[property log]([variable x], [variable y], [variable-2 z])", | |||
"}") | |||
MT("quotedStringAddition", | |||
"[keyword let] [def f] [operator =] [variable a] [operator +] [string 'fatarrow'] [operator +] [variable c];"); | |||
@@ -89,6 +127,9 @@ | |||
"[keyword let] [def f] [operator =] ([[ [def a], [def b] ]], [def c]) [operator =>] [variable-2 a] [operator +] [variable-2 c];", | |||
"[variable c];"); | |||
MT("fatArrow_stringDefault", | |||
"([def a], [def b] [operator =] [string 'x\\'y']) [operator =>] [variable-2 a] [operator +] [variable-2 b]") | |||
MT("spread", | |||
"[keyword function] [def f]([def a], [meta ...][def b]) {", | |||
" [variable something]([variable-2 a], [meta ...][variable-2 b]);", | |||
@@ -123,9 +164,9 @@ | |||
MT("indent_for", | |||
"[keyword for] ([keyword var] [def i] [operator =] [number 0];", | |||
" [variable i] [operator <] [number 100];", | |||
" [variable i][operator ++])", | |||
" [variable doSomething]([variable i]);", | |||
" [variable-2 i] [operator <] [number 100];", | |||
" [variable-2 i][operator ++])", | |||
" [variable doSomething]([variable-2 i]);", | |||
"[keyword debugger];"); | |||
MT("indent_c_style", | |||
@@ -188,6 +229,12 @@ | |||
" [keyword return] [variable-2 x];", | |||
"}"); | |||
MT( | |||
"param_destructuring", | |||
"[keyword function] [def foo]([def x] [operator =] [string-2 `foo${][number 10][string-2 }bar`]) {", | |||
" [keyword return] [variable-2 x];", | |||
"}"); | |||
MT("new_target", | |||
"[keyword function] [def F]([def target]) {", | |||
" [keyword if] ([variable-2 target] [operator &&] [keyword new].[keyword target].[property name]) {", | |||
@@ -205,7 +252,7 @@ | |||
MT("async_object", | |||
"[keyword let] [def obj] [operator =] { [property async]: [atom false] };"); | |||
// async be highlighet as keyword and foo as def, but it requires potentially expensive look-ahead. See #4173 | |||
// async be highlighted as keyword and foo as def, but it requires potentially expensive look-ahead. See #4173 | |||
MT("async_object_function", | |||
"[keyword let] [def obj] [operator =] { [property async] [property foo]([def args]) { [keyword return] [atom true]; } };"); | |||
@@ -226,21 +273,73 @@ | |||
" [property method]: [string 'GET']", | |||
"});"); | |||
MT("async_variable", | |||
"[keyword const] [def async] [operator =] {[property a]: [number 1]};", | |||
"[keyword const] [def foo] [operator =] [string-2 `bar ${][variable async].[property a][string-2 }`];") | |||
MT("bigint", "[number 1n] [operator +] [number 0x1afn] [operator +] [number 0o064n] [operator +] [number 0b100n];") | |||
MT("async_comment", | |||
"[keyword async] [comment /**/] [keyword function] [def foo]([def args]) { [keyword return] [atom true]; }"); | |||
MT("indent_switch", | |||
"[keyword switch] ([variable x]) {", | |||
" [keyword default]:", | |||
" [keyword return] [number 2]", | |||
"}") | |||
MT("regexp_corner_case", | |||
"[operator +]{} [operator /] [atom undefined];", | |||
"[[[meta ...][string-2 /\\//] ]];", | |||
"[keyword void] [string-2 /\\//];", | |||
"[keyword do] [string-2 /\\//]; [keyword while] ([number 0]);", | |||
"[keyword if] ([number 0]) {} [keyword else] [string-2 /\\//];", | |||
"[string-2 `${][variable async][operator ++][string-2 }//`];", | |||
"[string-2 `${]{} [operator /] [string-2 /\\//}`];") | |||
MT("return_eol", | |||
"[keyword return]", | |||
"{} [string-2 /5/]") | |||
MT("numeric separator", | |||
"[number 123_456];", | |||
"[number 0xdead_c0de];", | |||
"[number 0o123_456];", | |||
"[number 0b1101_1101];", | |||
"[number .123_456e0_1];", | |||
"[number 1E+123_456];", | |||
"[number 12_34_56n];") | |||
MT("underscore property", | |||
"[variable something].[property _property];", | |||
"[variable something].[property _123];", | |||
"[variable something].[property _for];", | |||
"[variable _for];", | |||
"[variable _123];") | |||
MT("private properties", | |||
"[keyword class] [def C] {", | |||
" [property #x] [operator =] [number 2];", | |||
" [property #read]() {", | |||
" [keyword return] [keyword this].[property #x]", | |||
" }", | |||
"}") | |||
var ts_mode = CodeMirror.getMode({indentUnit: 2}, "application/typescript") | |||
function TS(name) { | |||
test.mode(name, ts_mode, Array.prototype.slice.call(arguments, 1)) | |||
} | |||
TS("extend_type", | |||
"[keyword class] [def Foo] [keyword extends] [variable-3 Some][operator <][variable-3 Type][operator >] {}") | |||
TS("typescript_extend_type", | |||
"[keyword class] [def Foo] [keyword extends] [type Some][operator <][type Type][operator >] {}") | |||
TS("arrow_type", | |||
"[keyword let] [def x]: ([variable arg]: [variable-3 Type]) [operator =>] [variable-3 ReturnType]") | |||
TS("typescript_arrow_type", | |||
"[keyword let] [def x]: ([variable arg]: [type Type]) [operator =>] [type ReturnType]") | |||
TS("typescript_class", | |||
"[keyword class] [def Foo] {", | |||
" [keyword public] [keyword static] [property main]() {}", | |||
" [keyword private] [property _foo]: [variable-3 string];", | |||
" [keyword private] [property _foo]: [type string];", | |||
"}") | |||
TS("typescript_literal_types", | |||
@@ -249,46 +348,139 @@ | |||
" [property truthy]: [string 'true'] [operator |] [number 1] [operator |] [atom true];", | |||
" [property falsy]: [string 'false'] [operator |] [number 0] [operator |] [atom false];", | |||
"}", | |||
"[keyword interface] [def MyInstance] [keyword extends] [variable-3 Sequelize].[variable-3 Instance] [operator <] [variable-3 MyAttributes] [operator >] {", | |||
" [property rawAttributes]: [variable-3 MyAttributes];", | |||
"[keyword interface] [def MyInstance] [keyword extends] [type Sequelize].[type Instance] [operator <] [type MyAttributes] [operator >] {", | |||
" [property rawAttributes]: [type MyAttributes];", | |||
" [property truthy]: [string 'true'] [operator |] [number 1] [operator |] [atom true];", | |||
" [property falsy]: [string 'false'] [operator |] [number 0] [operator |] [atom false];", | |||
"}") | |||
TS("typescript_extend_operators", | |||
"[keyword export] [keyword interface] [def UserModel] [keyword extends]", | |||
" [variable-3 Sequelize].[variable-3 Model] [operator <] [variable-3 UserInstance], [variable-3 UserAttributes] [operator >] {", | |||
" [type Sequelize].[type Model] [operator <] [type UserInstance], [type UserAttributes] [operator >] {", | |||
" [property findById]: (", | |||
" [variable userId]: [variable-3 number]", | |||
" ) [operator =>] [variable-3 Promise] [operator <] [variable-3 Array] [operator <] { [property id], [property name] } [operator >>];", | |||
" [variable userId]: [type number]", | |||
" ) [operator =>] [type Promise] [operator <] [type Array] [operator <] { [property id], [property name] } [operator >>];", | |||
" [property updateById]: (", | |||
" [variable userId]: [variable-3 number],", | |||
" [variable isActive]: [variable-3 boolean]", | |||
" ) [operator =>] [variable-3 Promise] [operator <] [variable-3 AccountHolderNotificationPreferenceInstance] [operator >];", | |||
" [variable userId]: [type number],", | |||
" [variable isActive]: [type boolean]", | |||
" ) [operator =>] [type Promise] [operator <] [type AccountHolderNotificationPreferenceInstance] [operator >];", | |||
" }") | |||
TS("typescript_interface_with_const", | |||
"[keyword const] [def hello]: {", | |||
" [property prop1][operator ?]: [variable-3 string];", | |||
" [property prop2][operator ?]: [variable-3 string];", | |||
" [property prop1][operator ?]: [type string];", | |||
" [property prop2][operator ?]: [type string];", | |||
"} [operator =] {};") | |||
TS("typescript_double_extend", | |||
"[keyword export] [keyword interface] [def UserAttributes] {", | |||
" [property id][operator ?]: [variable-3 number];", | |||
" [property createdAt][operator ?]: [variable-3 Date];", | |||
" [property id][operator ?]: [type number];", | |||
" [property createdAt][operator ?]: [type Date];", | |||
"}", | |||
"[keyword export] [keyword interface] [def UserInstance] [keyword extends] [variable-3 Sequelize].[variable-3 Instance][operator <][variable-3 UserAttributes][operator >], [variable-3 UserAttributes] {", | |||
" [property id]: [variable-3 number];", | |||
" [property createdAt]: [variable-3 Date];", | |||
"[keyword export] [keyword interface] [def UserInstance] [keyword extends] [type Sequelize].[type Instance][operator <][type UserAttributes][operator >], [type UserAttributes] {", | |||
" [property id]: [type number];", | |||
" [property createdAt]: [type Date];", | |||
"}"); | |||
TS("typescript_index_signature", | |||
"[keyword interface] [def A] {", | |||
" [[ [variable prop]: [variable-3 string] ]]: [variable-3 any];", | |||
" [property prop1]: [variable-3 any];", | |||
" [[ [variable prop]: [type string] ]]: [type any];", | |||
" [property prop1]: [type any];", | |||
"}"); | |||
TS("typescript_generic_class", | |||
"[keyword class] [def Foo][operator <][type T][operator >] {", | |||
" [property bar]() {}", | |||
" [property foo](): [type Foo] {}", | |||
"}") | |||
TS("typescript_type_when_keyword", | |||
"[keyword export] [keyword type] [type AB] [operator =] [type A] [operator |] [type B];", | |||
"[keyword type] [type Flags] [operator =] {", | |||
" [property p1]: [type string];", | |||
" [property p2]: [type boolean];", | |||
"};") | |||
TS("typescript_type_when_not_keyword", | |||
"[keyword class] [def HasType] {", | |||
" [property type]: [type string];", | |||
" [property constructor]([def type]: [type string]) {", | |||
" [keyword this].[property type] [operator =] [variable-2 type];", | |||
" }", | |||
" [property setType]({ [def type] }: { [property type]: [type string]; }) {", | |||
" [keyword this].[property type] [operator =] [variable-2 type];", | |||
" }", | |||
"}") | |||
TS("typescript_function_generics", | |||
"[keyword function] [def a]() {}", | |||
"[keyword function] [def b][operator <][type IA] [keyword extends] [type object], [type IB] [keyword extends] [type object][operator >]() {}", | |||
"[keyword function] [def c]() {}") | |||
TS("typescript_complex_return_type", | |||
"[keyword function] [def A]() {", | |||
" [keyword return] [keyword this].[property property];", | |||
"}", | |||
"[keyword function] [def B](): [type Promise][operator <]{ [[ [variable key]: [type string] ]]: [type any] } [operator |] [atom null][operator >] {", | |||
" [keyword return] [keyword this].[property property];", | |||
"}") | |||
TS("typescript_complex_type_casting", | |||
"[keyword const] [def giftpay] [operator =] [variable config].[property get]([string 'giftpay']) [keyword as] { [[ [variable platformUuid]: [type string] ]]: { [property version]: [type number]; [property apiCode]: [type string]; } };") | |||
TS("typescript_keyof", | |||
"[keyword function] [def x][operator <][type T] [keyword extends] [keyword keyof] [type X][operator >]([def a]: [type T]) {", | |||
" [keyword return]") | |||
TS("typescript_new_typeargs", | |||
"[keyword let] [def x] [operator =] [keyword new] [variable Map][operator <][type string], [type Date][operator >]([string-2 `foo${][variable bar][string-2 }`])") | |||
TS("modifiers", | |||
"[keyword class] [def Foo] {", | |||
" [keyword public] [keyword abstract] [property bar]() {}", | |||
" [property constructor]([keyword readonly] [keyword private] [def x]) {}", | |||
"}") | |||
TS("arrow prop", | |||
"({[property a]: [def p] [operator =>] [variable-2 p]})") | |||
TS("generic in function call", | |||
"[keyword this].[property a][operator <][type Type][operator >]([variable foo]);", | |||
"[keyword this].[property a][operator <][variable Type][operator >][variable foo];") | |||
TS("type guard", | |||
"[keyword class] [def Appler] {", | |||
" [keyword static] [property assertApple]([def fruit]: [type Fruit]): [variable-2 fruit] [keyword is] [type Apple] {", | |||
" [keyword if] ([operator !]([variable-2 fruit] [keyword instanceof] [variable Apple]))", | |||
" [keyword throw] [keyword new] [variable Error]();", | |||
" }", | |||
"}") | |||
TS("type as variable", | |||
"[variable type] [operator =] [variable x] [keyword as] [type Bar];"); | |||
TS("enum body", | |||
"[keyword export] [keyword const] [keyword enum] [def CodeInspectionResultType] {", | |||
" [def ERROR] [operator =] [string 'problem_type_error'],", | |||
" [def WARNING] [operator =] [string 'problem_type_warning'],", | |||
" [def META],", | |||
"}") | |||
TS("parenthesized type", | |||
"[keyword class] [def Foo] {", | |||
" [property x] [operator =] [keyword new] [variable A][operator <][type B], [type string][operator |](() [operator =>] [type void])[operator >]();", | |||
" [keyword private] [property bar]();", | |||
"}") | |||
TS("abstract class", | |||
"[keyword export] [keyword abstract] [keyword class] [def Foo] {}") | |||
TS("interface without semicolons", | |||
"[keyword interface] [def Foo] {", | |||
" [property greet]([def x]: [type int]): [type blah]", | |||
" [property bar]: [type void]", | |||
"}") | |||
var jsonld_mode = CodeMirror.getMode( | |||
{indentUnit: 2}, | |||
{name: "javascript", jsonld: true} | |||
@@ -1,5 +1,5 @@ | |||
// 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/5/LICENSE | |||
(function() { | |||
var mode = CodeMirror.getMode({indentUnit: 2}, "php"); | |||
@@ -1,5 +1,5 @@ | |||
// 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/5/LICENSE | |||
(function() { | |||
var mode = CodeMirror.getMode({indentUnit: 2}, "xml"), mname = "xml"; | |||
@@ -1,5 +1,5 @@ | |||
// 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/5/LICENSE | |||
(function(mod) { | |||
if (typeof exports == "object" && typeof module == "object") // CommonJS | |||
@@ -52,6 +52,7 @@ var xmlConfig = { | |||
doNotIndent: {}, | |||
allowUnquoted: false, | |||
allowMissing: false, | |||
allowMissingTagName: false, | |||
caseFold: false | |||
} | |||
@@ -162,8 +163,9 @@ CodeMirror.defineMode("xml", function(editorConf, config_) { | |||
stream.next(); | |||
} | |||
return style; | |||
}; | |||
} | |||
} | |||
function doctype(depth) { | |||
return function(stream, state) { | |||
var ch; | |||
@@ -185,9 +187,13 @@ CodeMirror.defineMode("xml", function(editorConf, config_) { | |||
}; | |||
} | |||
function lower(tagName) { | |||
return tagName && tagName.toLowerCase(); | |||
} | |||
function Context(state, tagName, startOfLine) { | |||
this.prev = state.context; | |||
this.tagName = tagName; | |||
this.tagName = tagName || ""; | |||
this.indent = state.indented; | |||
this.startOfLine = startOfLine; | |||
if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent)) | |||
@@ -203,8 +209,8 @@ CodeMirror.defineMode("xml", function(editorConf, config_) { | |||
return; | |||
} | |||
parentTagName = state.context.tagName; | |||
if (!config.contextGrabbers.hasOwnProperty(parentTagName) || | |||
!config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) { | |||
if (!config.contextGrabbers.hasOwnProperty(lower(parentTagName)) || | |||
!config.contextGrabbers[lower(parentTagName)].hasOwnProperty(lower(nextTagName))) { | |||
return; | |||
} | |||
popContext(state); | |||
@@ -226,6 +232,9 @@ CodeMirror.defineMode("xml", function(editorConf, config_) { | |||
state.tagName = stream.current(); | |||
setStyle = "tag"; | |||
return attrState; | |||
} else if (config.allowMissingTagName && type == "endTag") { | |||
setStyle = "tag bracket"; | |||
return attrState(type, stream, state); | |||
} else { | |||
setStyle = "error"; | |||
return tagNameState; | |||
@@ -235,7 +244,7 @@ CodeMirror.defineMode("xml", function(editorConf, config_) { | |||
if (type == "word") { | |||
var tagName = stream.current(); | |||
if (state.context && state.context.tagName != tagName && | |||
config.implicitlyClosed.hasOwnProperty(state.context.tagName)) | |||
config.implicitlyClosed.hasOwnProperty(lower(state.context.tagName))) | |||
popContext(state); | |||
if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) { | |||
setStyle = "tag"; | |||
@@ -244,6 +253,9 @@ CodeMirror.defineMode("xml", function(editorConf, config_) { | |||
setStyle = "tag error"; | |||
return closeStateErr; | |||
} | |||
} else if (config.allowMissingTagName && type == "endTag") { | |||
setStyle = "tag bracket"; | |||
return closeState(type, stream, state); | |||
} else { | |||
setStyle = "error"; | |||
return closeStateErr; | |||
@@ -271,7 +283,7 @@ CodeMirror.defineMode("xml", function(editorConf, config_) { | |||
var tagName = state.tagName, tagStart = state.tagStart; | |||
state.tagName = state.tagStart = null; | |||
if (type == "selfcloseTag" || | |||
config.autoSelfClosers.hasOwnProperty(tagName)) { | |||
config.autoSelfClosers.hasOwnProperty(lower(tagName))) { | |||
maybePopContext(state, tagName); | |||
} else { | |||
maybePopContext(state, tagName); | |||
@@ -351,7 +363,7 @@ CodeMirror.defineMode("xml", function(editorConf, config_) { | |||
if (context.tagName == tagAfter[2]) { | |||
context = context.prev; | |||
break; | |||
} else if (config.implicitlyClosed.hasOwnProperty(context.tagName)) { | |||
} else if (config.implicitlyClosed.hasOwnProperty(lower(context.tagName))) { | |||
context = context.prev; | |||
} else { | |||
break; | |||
@@ -359,8 +371,8 @@ CodeMirror.defineMode("xml", function(editorConf, config_) { | |||
} | |||
} else if (tagAfter) { // Opening tag spotted | |||
while (context) { | |||
var grabbers = config.contextGrabbers[context.tagName]; | |||
if (grabbers && grabbers.hasOwnProperty(tagAfter[2])) | |||
var grabbers = config.contextGrabbers[lower(context.tagName)]; | |||
if (grabbers && grabbers.hasOwnProperty(lower(tagAfter[2]))) | |||
context = context.prev; | |||
else | |||
break; | |||
@@ -382,6 +394,17 @@ CodeMirror.defineMode("xml", function(editorConf, config_) { | |||
skipAttribute: function(state) { | |||
if (state.state == attrValueState) | |||
state.state = attrState | |||
}, | |||
xmlCurrentTag: function(state) { | |||
return state.tagName ? {name: state.tagName, close: state.type == "closeTag"} : null | |||
}, | |||
xmlCurrentContext: function(state) { | |||
var context = [] | |||
for (var cx = state.context; cx; cx = cx.prev) | |||
context.push(cx.tagName) | |||
return context.reverse() | |||
} | |||
}; | |||
}); | |||