Browse Source

升级组件

tags/6.2.0
xushubieli 1 year ago
parent
commit
149d256fd0
16 changed files with 1279 additions and 553 deletions
  1. +104
    -81
      src/admin/js/codemirror.js
  2. +1
    -1
      src/admin/js/mode/clike/clike.js
  3. +165
    -0
      src/admin/js/mode/clike/test.js
  4. +172
    -141
      src/admin/js/mode/css/css.js
  5. +1
    -1
      src/admin/js/mode/css/gss_test.js
  6. +5
    -5
      src/admin/js/mode/css/less_test.js
  7. +6
    -6
      src/admin/js/mode/css/scss_test.js
  8. +38
    -21
      src/admin/js/mode/css/test.js
  9. +8
    -7
      src/admin/js/mode/htmlmixed/htmlmixed.js
  10. +323
    -163
      src/admin/js/mode/javascript/javascript.js
  11. +219
    -27
      src/admin/js/mode/javascript/test.js
  12. +12
    -12
      src/admin/js/mode/php/php.js
  13. +1
    -1
      src/admin/js/mode/php/test.js
  14. +190
    -76
      src/admin/js/mode/sql/sql.js
  15. +1
    -1
      src/admin/js/mode/xml/test.js
  16. +33
    -10
      src/admin/js/mode/xml/xml.js

+ 104
- 81
src/admin/js/codemirror.js View File

@@ -1,7 +1,7 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: 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. // implemented in JavaScript on top of the browser's DOM.
// //
// You can find some technical background for some of the code below // You can find some technical background for some of the code below
@@ -26,7 +26,8 @@
var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : +(edge || ie_11up)[1]); var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : +(edge || ie_11up)[1]);
var webkit = !edge && /WebKit\//.test(userAgent); var webkit = !edge && /WebKit\//.test(userAgent);
var qtwebkit = webkit && /Qt\/\d+\.\d+/.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 presto = /Opera\//.test(userAgent);
var safari = /Apple Computer/.test(navigator.vendor); var safari = /Apple Computer/.test(navigator.vendor);
var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent); var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent);
@@ -111,15 +112,15 @@
} while (child = child.parentNode) } while (child = child.parentNode)
} }


function activeElt() {
function activeElt(doc) {
// IE and Edge may throw an "Unspecified Error" when accessing document.activeElement. // 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 < 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. // IE > 9 and Edge will throw when accessed in an iframe if document.body is unavailable.
var activeElement; var activeElement;
try { try {
activeElement = document.activeElement;
activeElement = doc.activeElement;
} catch(e) { } catch(e) {
activeElement = document.body || null;
activeElement = doc.body || null;
} }
while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement) while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement)
{ activeElement = activeElement.shadowRoot.activeElement; } { activeElement = activeElement.shadowRoot.activeElement; }
@@ -143,6 +144,10 @@
else if (ie) // Suppress mysterious IE10 errors else if (ie) // Suppress mysterious IE10 errors
{ selectInput = function(node) { try { node.select(); } catch(_e) {} }; } { 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) { function bind(f) {
var args = Array.prototype.slice.call(arguments, 1); var args = Array.prototype.slice.call(arguments, 1);
return function(){return f.apply(null, args)} return function(){return f.apply(null, args)}
@@ -1543,7 +1548,7 @@
var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker); var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker);
if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) { continue } 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) || 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 } { return true }
} } } }
} }
@@ -2572,16 +2577,16 @@
cm.display.lineNumChars = null; cm.display.lineNumChars = null;
} }


function pageScrollX() {
function pageScrollX(doc) {
// Work around https://bugs.chromium.org/p/chromium/issues/detail?id=489206 // Work around https://bugs.chromium.org/p/chromium/issues/detail?id=489206
// which causes page_Offset and bounding client rects to use // which causes page_Offset and bounding client rects to use
// different reference viewports and invalidate our calculations. // 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) { function widgetTopHeight(lineObj) {
@@ -2609,8 +2614,8 @@
else { yOff -= cm.display.viewOffset; } else { yOff -= cm.display.viewOffset; }
if (context == "page" || context == "window") { if (context == "page" || context == "window") {
var lOff = cm.display.lineSpace.getBoundingClientRect(); 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.left += xOff; rect.right += xOff;
} }
rect.top += yOff; rect.bottom += yOff; rect.top += yOff; rect.bottom += yOff;
@@ -2624,8 +2629,8 @@
var left = coords.left, top = coords.top; var left = coords.left, top = coords.top;
// First move into "page" coordinate system // First move into "page" coordinate system
if (context == "page") { if (context == "page") {
left -= pageScrollX();
top -= pageScrollY();
left -= pageScrollX(doc(cm));
top -= pageScrollY(doc(cm));
} else if (context == "local" || !context) { } else if (context == "local" || !context) {
var localBox = cm.display.sizer.getBoundingClientRect(); var localBox = cm.display.sizer.getBoundingClientRect();
left += localBox.left; left += localBox.left;
@@ -3423,10 +3428,10 @@
if (viewport && viewport.ensure) { if (viewport && viewport.ensure) {
var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line; var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line;
if (ensureFrom < from) { if (ensureFrom < from) {
FROM = ensureFrom;
from = ensureFrom;
to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight); to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight);
} else if (Math.min(ensureTo, doc.lastLine()) >= to) { } 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; to = ensureTo;
} }
} }
@@ -3441,8 +3446,9 @@
if (signalDOMEvent(cm, "scrollCursorIntoView")) { return } if (signalDOMEvent(cm, "scrollCursorIntoView")) { return }


var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null; var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null;
var doc = display.wrapper.ownerDocument;
if (rect.top + box.top < 0) { doScroll = true; } 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) { 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;")); 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); cm.display.lineSpace.appendChild(scrollNode);
@@ -3696,13 +3702,13 @@
NativeScrollbars.prototype.zeroWidthHack = function () { NativeScrollbars.prototype.zeroWidthHack = function () {
var w = mac && !mac_geMountainLion ? "12px" : "18px"; var w = mac && !mac_geMountainLion ? "12px" : "18px";
this.horiz.style.height = this.vert.style.width = w; 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.disableHoriz = new Delayed;
this.disableVert = new Delayed; this.disableVert = new Delayed;
}; };


NativeScrollbars.prototype.enableZeroWidthBar = function (bar, delay, type) { NativeScrollbars.prototype.enableZeroWidthBar = function (bar, delay, type) {
bar.style.pointerEvents = "auto";
bar.style.visibility = "";
function maybeDisable() { function maybeDisable() {
// To find out whether the scrollbar is still visible, we // To find out whether the scrollbar is still visible, we
// check whether the element under the pixel in the bottom // check whether the element under the pixel in the bottom
@@ -3713,7 +3719,7 @@
var box = bar.getBoundingClientRect(); var box = bar.getBoundingClientRect();
var elt = type == "vert" ? document.elementFromPoint(box.right - 1, (box.top + box.bottom) / 2) var elt = type == "vert" ? document.elementFromPoint(box.right - 1, (box.top + box.bottom) / 2)
: document.elementFromPoint((box.right + box.left) / 2, box.bottom - 1); : 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); } else { delay.set(1000, maybeDisable); }
} }
delay.set(1000, maybeDisable); delay.set(1000, maybeDisable);
@@ -3894,7 +3900,7 @@
cm.display.maxLineChanged = false; cm.display.maxLineChanged = false;
} }


var takeFocus = op.focus && op.focus == activeElt();
var takeFocus = op.focus && op.focus == activeElt(doc(cm));
if (op.preparedSelection) if (op.preparedSelection)
{ cm.display.input.showSelection(op.preparedSelection, takeFocus); } { cm.display.input.showSelection(op.preparedSelection, takeFocus); }
if (op.updatedDisplay || op.startHeight != cm.doc.height) if (op.updatedDisplay || op.startHeight != cm.doc.height)
@@ -4071,11 +4077,11 @@


function selectionSnapshot(cm) { function selectionSnapshot(cm) {
if (cm.hasFocus()) { return null } if (cm.hasFocus()) { return null }
var active = activeElt();
var active = activeElt(doc(cm));
if (!active || !contains(cm.display.lineDiv, active)) { return null } if (!active || !contains(cm.display.lineDiv, active)) { return null }
var result = {activeElt: active}; var result = {activeElt: active};
if (window.getSelection) { if (window.getSelection) {
var sel = window.getSelection();
var sel = win(cm).getSelection();
if (sel.anchorNode && sel.extend && contains(cm.display.lineDiv, sel.anchorNode)) { if (sel.anchorNode && sel.extend && contains(cm.display.lineDiv, sel.anchorNode)) {
result.anchorNode = sel.anchorNode; result.anchorNode = sel.anchorNode;
result.anchorOffset = sel.anchorOffset; result.anchorOffset = sel.anchorOffset;
@@ -4087,11 +4093,12 @@
} }


function restoreSelection(snapshot) { 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(); snapshot.activeElt.focus();
if (!/^(INPUT|TEXTAREA)$/.test(snapshot.activeElt.nodeName) && if (!/^(INPUT|TEXTAREA)$/.test(snapshot.activeElt.nodeName) &&
snapshot.anchorNode && contains(document.body, snapshot.anchorNode) && contains(document.body, snapshot.focusNode)) { 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.setEnd(snapshot.anchorNode, snapshot.anchorOffset);
range.collapse(false); range.collapse(false);
sel.removeAllRanges(); sel.removeAllRanges();
@@ -4130,7 +4137,7 @@
if (display.viewFrom < from && from - display.viewFrom < 20) { from = Math.max(doc.first, display.viewFrom); } 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 (display.viewTo > to && display.viewTo - to < 20) { to = Math.min(end, display.viewTo); }
if (sawCollapsedSpans) { if (sawCollapsedSpans) {
FROM = visualLineNo(cm.doc, from);
from = visualLineNo(cm.doc, from);
to = visualLineEndNo(cm.doc, to); to = visualLineEndNo(cm.doc, to);
} }


@@ -4408,6 +4415,8 @@
d.scroller.setAttribute("tabIndex", "-1"); d.scroller.setAttribute("tabIndex", "-1");
// The element in which the editor lives. // The element in which the editor lives.
d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror"); 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, // This attribute is respected by automatic translation systems such as Google Translate,
// and may also be respected by tools used by human translators. // and may also be respected by tools used by human translators.
@@ -4509,6 +4518,17 @@
} }


function onScrollWheel(cm, e) { 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 delta = wheelEventDelta(e), dx = delta.x, dy = delta.y;
var pixelsPerUnit = wheelPixelsPerUnit; var pixelsPerUnit = wheelPixelsPerUnit;
if (e.deltaMode === 0) { if (e.deltaMode === 0) {
@@ -5192,7 +5212,7 @@
var range = sel.ranges[i]; var range = sel.ranges[i];
var old = sel.ranges.length == doc.sel.ranges.length && doc.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 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 || newAnchor != range.anchor || newHead != range.head) {
if (!out) { out = sel.ranges.slice(0, i); } if (!out) { out = sel.ranges.slice(0, i); }
out[i] = new Range(newAnchor, newHead); out[i] = new Range(newAnchor, newHead);
@@ -5276,7 +5296,7 @@
function filterChange(doc, change, update) { function filterChange(doc, change, update) {
var obj = { var obj = {
canceled: false, canceled: false,
FROM: change.from,
from: change.from,
to: change.to, to: change.to,
text: change.text, text: change.text,
origin: change.origin, origin: change.origin,
@@ -5515,7 +5535,7 @@
var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change"); var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change");
if (changeHandler || changesHandler) { if (changeHandler || changesHandler) {
var obj = { var obj = {
FROM: from, to: to,
from: from, to: to,
text: change.text, text: change.text,
removed: change.removed, removed: change.removed,
origin: change.origin origin: change.origin
@@ -5911,7 +5931,7 @@
var line = this.lines[i]; var line = this.lines[i];
var span = getMarkedSpanFor(line.markedSpans, this); var span = getMarkedSpanFor(line.markedSpans, this);
if (span.from != null) { 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 (side == -1) { return from }
} }
if (span.to != null) { if (span.to != null) {
@@ -5989,7 +6009,7 @@
} }
if (marker.collapsed) { if (marker.collapsed) {
if (conflictingCollapsedRange(doc, from.line, from, to, marker) || 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") } { throw new Error("Inserting collapsed marker partially overlapping an existing one") }
seeCollapsedSpans(); seeCollapsedSpans();
} }
@@ -6169,7 +6189,7 @@
setSelection(this, simpleSelection(top), sel_dontScroll); setSelection(this, simpleSelection(top), sel_dontScroll);
}), }),
replaceRange: function(code, from, to, origin) { replaceRange: function(code, from, to, origin) {
FROM = clipPos(this, from);
from = clipPos(this, from);
to = to ? clipPos(this, to) : from; to = to ? clipPos(this, to) : from;
replaceRange(this, code, from, to, origin); replaceRange(this, code, from, to, origin);
}, },
@@ -6413,7 +6433,7 @@
return markers return markers
}, },
findMarks: function(from, to, filter) { 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; var found = [], lineNo = from.line;
this.iter(from.line, to.line + 1, function (line) { this.iter(from.line, to.line + 1, function (line) {
var spans = line.markedSpans; var spans = line.markedSpans;
@@ -6997,11 +7017,11 @@
} }
}); }, }); },
deleteLine: function (cm) { return deleteNearSelection(cm, function (range) { return ({ 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)) to: clipPos(cm.doc, Pos(range.to().line + 1, 0))
}); }); }, }); }); },
delLineLeft: function (cm) { return deleteNearSelection(cm, function (range) { return ({ 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) { delWrappedLineLeft: function (cm) { return deleteNearSelection(cm, function (range) {
var top = cm.charCoords(range.head, "div").top + 5; var top = cm.charCoords(range.head, "div").top + 5;
@@ -7244,7 +7264,7 @@
function onKeyDown(e) { function onKeyDown(e) {
var cm = this; var cm = this;
if (e.target && e.target != cm.display.input.getField()) { return } 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 } if (signalDOMEvent(cm, e)) { return }
// IE does strange things with escape. // IE does strange things with escape.
if (ie && ie_version < 11 && e.keyCode == 27) { e.returnValue = false; } if (ie && ie_version < 11 && e.keyCode == 27) { e.returnValue = false; }
@@ -7351,7 +7371,7 @@
} }
if (clickInGutter(cm, e)) { return } if (clickInGutter(cm, e)) { return }
var pos = posFromMouse(cm, e), button = e_button(e), repeat = pos ? clickRepeat(pos, button) : "single"; 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 // #3261: make sure, that we're not starting a second selection
if (button == 1 && cm.state.selectingText) if (button == 1 && cm.state.selectingText)
@@ -7406,7 +7426,7 @@


function leftButtonDown(cm, pos, repeat, event) { function leftButtonDown(cm, pos, repeat, event) {
if (ie) { setTimeout(bind(ensureFocus, cm), 0); } 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); var behavior = configureMouse(cm, repeat, event);


@@ -7476,19 +7496,19 @@
// Normal selection, as opposed to text dragging. // Normal selection, as opposed to text dragging.
function leftButtonSelect(cm, event, start, behavior) { function leftButtonSelect(cm, event, start, behavior) {
if (ie) { delayBlurEvent(cm); } if (ie) { delayBlurEvent(cm); }
var display = cm.display, doc = cm.doc;
var display = cm.display, doc$1 = cm.doc;
e_preventDefault(event); 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) { if (behavior.addNew && !behavior.extend) {
ourIndex = doc.sel.contains(start);
ourIndex = doc$1.sel.contains(start);
if (ourIndex > -1) if (ourIndex > -1)
{ ourRange = ranges[ourIndex]; } { ourRange = ranges[ourIndex]; }
else else
{ ourRange = new Range(start, start); } { ourRange = new Range(start, start); }
} else { } else {
ourRange = doc.sel.primary();
ourIndex = doc.sel.primIndex;
ourRange = doc$1.sel.primary();
ourIndex = doc$1.sel.primIndex;
} }


if (behavior.unit == "rectangle") { if (behavior.unit == "rectangle") {
@@ -7505,18 +7525,18 @@


if (!behavior.addNew) { if (!behavior.addNew) {
ourIndex = 0; 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) { } else if (ourIndex == -1) {
ourIndex = ranges.length; ourIndex = ranges.length;
setSelection(doc, normalizeSelection(cm, ranges.concat([ourRange]), ourIndex),
setSelection(doc$1, normalizeSelection(cm, ranges.concat([ourRange]), ourIndex),
{scroll: false, origin: "*mouse"}); {scroll: false, origin: "*mouse"});
} else if (ranges.length > 1 && ranges[ourIndex].empty() && behavior.unit == "char" && !behavior.extend) { } 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"}); {scroll: false, origin: "*mouse"});
startSel = doc.sel;
startSel = doc$1.sel;
} else { } else {
replaceOneSelection(doc, ourIndex, ourRange, sel_mouse);
replaceOneSelection(doc$1, ourIndex, ourRange, sel_mouse);
} }


var lastPos = start; var lastPos = start;
@@ -7526,19 +7546,19 @@


if (behavior.unit == "rectangle") { if (behavior.unit == "rectangle") {
var ranges = [], tabSize = cm.options.tabSize; 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); 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)); for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line));
line <= end; 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) if (left == right)
{ ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))); } { ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))); }
else if (text.length > leftPos) else if (text.length > leftPos)
{ ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))); } { ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))); }
} }
if (!ranges.length) { ranges.push(new Range(start, start)); } 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}); {origin: "*mouse", scroll: false});
cm.scrollIntoView(pos); cm.scrollIntoView(pos);
} else { } else {
@@ -7553,8 +7573,8 @@
anchor = maxPos(oldRange.to(), range.head); anchor = maxPos(oldRange.to(), range.head);
} }
var ranges$1 = startSel.ranges.slice(0); 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"); var cur = posFromMouse(cm, e, true, behavior.unit == "rectangle");
if (!cur) { return } if (!cur) { return }
if (cmp(cur, lastPos) != 0) { if (cmp(cur, lastPos) != 0) {
cm.curOp.focus = activeElt();
cm.curOp.focus = activeElt(doc(cm));
extendTo(cur); extendTo(cur);
var visible = visibleLines(display, doc);
var visible = visibleLines(display, doc$1);
if (cur.line >= visible.to || cur.line < visible.from) if (cur.line >= visible.to || cur.line < visible.from)
{ setTimeout(operation(cm, function () {if (counter == curCount) { extend(e); }}), 150); } { setTimeout(operation(cm, function () {if (counter == curCount) { extend(e); }}), 150); }
} else { } else {
@@ -7597,7 +7617,7 @@
} }
off(display.wrapper.ownerDocument, "mousemove", move); off(display.wrapper.ownerDocument, "mousemove", move);
off(display.wrapper.ownerDocument, "mouseup", up); off(display.wrapper.ownerDocument, "mouseup", up);
doc.history.lastSelOrigin = null;
doc$1.history.lastSelOrigin = null;
} }


var move = operation(cm, function (e) { var move = operation(cm, function (e) {
@@ -7754,7 +7774,7 @@
for (var i = newBreaks.length - 1; i >= 0; i--) for (var i = newBreaks.length - 1; i >= 0; i--)
{ replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)); } { 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"); cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
if (old != Init) { cm.refresh(); } if (old != Init) { cm.refresh(); }
}); });
@@ -8197,7 +8217,7 @@
var pasted = e.clipboardData && e.clipboardData.getData("Text"); var pasted = e.clipboardData && e.clipboardData.getData("Text");
if (pasted) { if (pasted) {
e.preventDefault(); 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"); }); } { runInOp(cm, function () { return applyTextInput(cm, pasted, 0, null, "paste"); }); }
return true return true
} }
@@ -8274,7 +8294,7 @@


CodeMirror.prototype = { CodeMirror.prototype = {
constructor: CodeMirror, constructor: CodeMirror,
focus: function(){window.focus(); this.display.input.focus();},
focus: function(){win(this).focus(); this.display.input.focus();},


setOption: function(option, value) { setOption: function(option, value) {
var options = this.options, old = options[option]; var options = this.options, old = options[option];
@@ -8598,7 +8618,7 @@


signal(this, "overwriteToggle", this, this.state.overwrite); 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) }, isReadOnly: function() { return !!(this.options.readOnly || this.doc.cantEdit) },


scrollTo: methodOp(function (x, y) { scrollToCoords(this, x, y); }), scrollTo: methodOp(function (x, y) { scrollToCoords(this, x, y); }),
@@ -8779,7 +8799,7 @@
function findPosV(cm, pos, dir, unit) { function findPosV(cm, pos, dir, unit) {
var doc = cm.doc, x = pos.left, y; var doc = cm.doc, x = pos.left, y;
if (unit == "page") { 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); var moveAmount = Math.max(pageSize - .5 * textHeight(cm.display), 3);
y = (dir > 0 ? pos.bottom : pos.top) + dir * moveAmount; y = (dir > 0 ? pos.bottom : pos.top) + dir * moveAmount;


@@ -8879,7 +8899,7 @@
var kludge = hiddenTextarea(), te = kludge.firstChild; var kludge = hiddenTextarea(), te = kludge.firstChild;
cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild); cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild);
te.value = lastCopied.text.join("\n"); te.value = lastCopied.text.join("\n");
var hadFocus = activeElt();
var hadFocus = activeElt(div.ownerDocument);
selectInput(te); selectInput(te);
setTimeout(function () { setTimeout(function () {
cm.display.lineSpace.removeChild(kludge); cm.display.lineSpace.removeChild(kludge);
@@ -8902,7 +8922,7 @@


ContentEditableInput.prototype.prepareSelection = function () { ContentEditableInput.prototype.prepareSelection = function () {
var result = prepareSelection(this.cm, false); var result = prepareSelection(this.cm, false);
result.focus = activeElt() == this.div;
result.focus = activeElt(this.div.ownerDocument) == this.div;
return result return result
}; };


@@ -8998,7 +9018,7 @@


ContentEditableInput.prototype.focus = function () { ContentEditableInput.prototype.focus = function () {
if (this.cm.options.readOnly != "nocursor") { 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.showSelection(this.prepareSelection(), true); }
this.div.focus(); this.div.focus();
} }
@@ -9073,11 +9093,11 @@


var fromIndex, fromLine, fromNode; var fromIndex, fromLine, fromNode;
if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) { 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 { } 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 toIndex = findViewIndex(cm, to.line);
var toLine, toNode; var toLine, toNode;
@@ -9254,7 +9274,7 @@
for (;;) { for (;;) {
walk(from); walk(from);
if (from == to) { break } if (from == to) { break }
FROM = from.nextSibling;
from = from.nextSibling;
extraLinebreak = false; extraLinebreak = false;
} }
return text return text
@@ -9350,6 +9370,7 @@
// Used to work around IE issue with selection being forgotten when focus moves away from textarea // Used to work around IE issue with selection being forgotten when focus moves away from textarea
this.hasSelection = false; this.hasSelection = false;
this.composing = null; this.composing = null;
this.resetting = false;
}; };


TextareaInput.prototype.init = function (display) { TextareaInput.prototype.init = function (display) {
@@ -9482,8 +9503,9 @@
// Reset the input to correspond to the selection (or to be empty, // Reset the input to correspond to the selection (or to be empty,
// when not typing and nothing is selected) // when not typing and nothing is selected)
TextareaInput.prototype.reset = function (typing) { TextareaInput.prototype.reset = function (typing) {
if (this.contextMenuPending || this.composing) { return }
if (this.contextMenuPending || this.composing && typing) { return }
var cm = this.cm; var cm = this.cm;
this.resetting = true;
if (cm.somethingSelected()) { if (cm.somethingSelected()) {
this.prevInput = ""; this.prevInput = "";
var content = cm.getSelection(); var content = cm.getSelection();
@@ -9494,6 +9516,7 @@
this.prevInput = this.textarea.value = ""; this.prevInput = this.textarea.value = "";
if (ie && ie_version >= 9) { this.hasSelection = null; } if (ie && ie_version >= 9) { this.hasSelection = null; }
} }
this.resetting = false;
}; };


TextareaInput.prototype.getField = function () { return this.textarea }; TextareaInput.prototype.getField = function () { return this.textarea };
@@ -9501,7 +9524,7 @@
TextareaInput.prototype.supportsTouch = function () { return false }; TextareaInput.prototype.supportsTouch = function () { return false };


TextareaInput.prototype.focus = function () { 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(); } try { this.textarea.focus(); }
catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM 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 // possible when it is clear that nothing happened. hasSelection
// will be the case when there is a lot of text in the textarea, // will be the case when there is a lot of text in the textarea,
// in which case reading its value would be expensive. // 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) || (hasSelection(input) && !prevInput && !this.composing) ||
cm.isReadOnly() || cm.options.disableInput || cm.state.keySeq) cm.isReadOnly() || cm.options.disableInput || cm.state.keySeq)
{ return false } { return false }
@@ -9624,9 +9647,9 @@
input.wrapper.style.cssText = "position: static"; 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);"; 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; 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(); display.input.focus();
if (webkit) { window.scrollTo(null, oldScrollY); }
if (webkit) { te.ownerDocument.defaultView.scrollTo(null, oldScrollY); }
display.input.reset(); display.input.reset();
// Adds "Select all" to context menu in FF // Adds "Select all" to context menu in FF
if (!cm.somethingSelected()) { te.value = input.prevInput = " "; } if (!cm.somethingSelected()) { te.value = input.prevInput = " "; }
@@ -9708,7 +9731,7 @@
// Set autofocus to true if this textarea is focused, or if it has // Set autofocus to true if this textarea is focused, or if it has
// autofocus and no other element is focused. // autofocus and no other element is focused.
if (options.autofocus == null) { if (options.autofocus == null) {
var hasFocus = activeElt();
var hasFocus = activeElt(textarea.ownerDocument);
options.autofocus = hasFocus == textarea || options.autofocus = hasFocus == textarea ||
textarea.getAttribute("autofocus") != null && hasFocus == document.body; textarea.getAttribute("autofocus") != null && hasFocus == document.body;
} }
@@ -9842,7 +9865,7 @@


addLegacyProps(CodeMirror); addLegacyProps(CodeMirror);


CodeMirror.version = "5.65.3";
CodeMirror.version = "5.65.9";


return CodeMirror; return CodeMirror;




+ 1
- 1
src/admin/js/mode/clike/clike.js View File

@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/5/LICENSE


(function(mod) { (function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS if (typeof exports == "object" && typeof module == "object") // CommonJS


+ 165
- 0
src/admin/js/mode/clike/test.js View File

@@ -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];");
})();

+ 172
- 141
src/admin/js/mode/css/css.js View File

@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/5/LICENSE


(function(mod) { (function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -29,7 +29,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
valueKeywords = parserConfig.valueKeywords || {}, valueKeywords = parserConfig.valueKeywords || {},
allowNested = parserConfig.allowNested, allowNested = parserConfig.allowNested,
lineComment = parserConfig.lineComment, lineComment = parserConfig.lineComment,
supportsAtComponent = parserConfig.supportsAtComponent === true;
supportsAtComponent = parserConfig.supportsAtComponent === true,
highlightNonStandardPropertyKeywords = config.highlightNonStandardPropertyKeywords !== false;


var type, override; var type, override;
function ret(style, tp) { type = tp; return style; } function ret(style, tp) { type = tp; return style; }
@@ -63,7 +64,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
if (/[\d.]/.test(stream.peek())) { if (/[\d.]/.test(stream.peek())) {
stream.eatWhile(/[\w.%]/); stream.eatWhile(/[\w.%]/);
return ret("number", "unit"); return ret("number", "unit");
} else if (stream.match(/^-[\w\\\-]+/)) {
} else if (stream.match(/^-[\w\\\-]*/)) {
stream.eatWhile(/[\w\\\-]/); stream.eatWhile(/[\w\\\-]/);
if (stream.match(/^\s*:/, false)) if (stream.match(/^\s*:/, false))
return ret("variable-2", "variable-definition"); return ret("variable-2", "variable-definition");
@@ -77,12 +78,11 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
return ret("qualifier", "qualifier"); return ret("qualifier", "qualifier");
} else if (/[:;{}\[\]\(\)]/.test(ch)) { } else if (/[:;{}\[\]\(\)]/.test(ch)) {
return ret(null, 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)) { } else if (/[\w\\\-]/.test(ch)) {
stream.eatWhile(/[\w\\\-]/); stream.eatWhile(/[\w\\\-]/);
return ret("property", "word"); return ret("property", "word");
@@ -108,7 +108,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {


function tokenParenthesized(stream, state) { function tokenParenthesized(stream, state) {
stream.next(); // Must be '(' stream.next(); // Must be '('
if (!stream.match(/\s*[\"\')]/, false))
if (!stream.match(/^\s*[\"\')]/, false))
state.tokenize = tokenString(")"); state.tokenize = tokenString(")");
else else
state.tokenize = null; state.tokenize = null;
@@ -162,16 +162,16 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
return pushContext(state, stream, "block"); return pushContext(state, stream, "block");
} else if (type == "}" && state.context.prev) { } else if (type == "}" && state.context.prev) {
return popContext(state); return popContext(state);
} else if (supportsAtComponent && /@component/.test(type)) {
} else if (supportsAtComponent && /@component/i.test(type)) {
return pushContext(state, stream, "atComponentBlock"); return pushContext(state, stream, "atComponentBlock");
} else if (/^@(-moz-)?document$/.test(type)) {
} else if (/^@(-moz-)?document$/i.test(type)) {
return pushContext(state, stream, "documentTypes"); 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"); 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; state.stateArg = type;
return "restricted_atBlock_before"; 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"; return "keyframes";
} else if (type && type.charAt(0) == "@") { } else if (type && type.charAt(0) == "@") {
return pushContext(state, stream, "at"); return pushContext(state, stream, "at");
@@ -198,7 +198,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
override = "property"; override = "property";
return "maybeprop"; return "maybeprop";
} else if (nonStandardPropertyKeywords.hasOwnProperty(word)) { } else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
override = "string-2";
override = highlightNonStandardPropertyKeywords ? "string-2" : "property";
return "maybeprop"; return "maybeprop";
} else if (allowNested) { } else if (allowNested) {
override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag"; 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 == "}" || type == "{") return popAndPass(type, stream, state);
if (type == "(") return pushContext(state, stream, "parens"); 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"; override += " error";
} else if (type == "word") { } else if (type == "word") {
wordAsValue(stream); wordAsValue(stream);
@@ -292,7 +292,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
else if (propertyKeywords.hasOwnProperty(word)) else if (propertyKeywords.hasOwnProperty(word))
override = "property"; override = "property";
else if (nonStandardPropertyKeywords.hasOwnProperty(word)) else if (nonStandardPropertyKeywords.hasOwnProperty(word))
override = "string-2";
override = highlightNonStandardPropertyKeywords ? "string-2" : "property";
else if (valueKeywords.hasOwnProperty(word)) else if (valueKeywords.hasOwnProperty(word))
override = "atom"; override = "atom";
else if (colorKeywords.hasOwnProperty(word)) else if (colorKeywords.hasOwnProperty(word))
@@ -383,7 +383,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
style = style[0]; style = style[0];
} }
override = style; override = style;
state.state = states[state.state](type, stream, state);
if (type != "comment")
state.state = states[state.state](type, stream, state);
return override; return override;
}, },


@@ -401,7 +402,6 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
ch == "{" && (cx.type == "at" || cx.type == "atBlock")) { ch == "{" && (cx.type == "at" || cx.type == "atBlock")) {
// Dedent relative to current context. // Dedent relative to current context.
indent = Math.max(0, cx.indent - indentUnit); indent = Math.max(0, cx.indent - indentUnit);
cx = cx.prev;
} }
} }
return indent; return indent;
@@ -410,6 +410,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
electricChars: "}", electricChars: "}",
blockCommentStart: "/*", blockCommentStart: "/*",
blockCommentEnd: "*/", blockCommentEnd: "*/",
blockCommentContinue: " * ",
lineComment: lineComment, lineComment: lineComment,
fold: "brace" fold: "brace"
}; };
@@ -442,117 +443,151 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"monochrome", "min-monochrome", "max-monochrome", "resolution", "monochrome", "min-monochrome", "max-monochrome", "resolution",
"min-resolution", "max-resolution", "scan", "grid", "orientation", "min-resolution", "max-resolution", "scan", "grid", "orientation",
"device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio", "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_); ], mediaFeatures = keySet(mediaFeatures_);


var mediaValueKeywords_ = [ var mediaValueKeywords_ = [
"landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover", "landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover",
"interlace", "progressive"
"interlace", "progressive",
"dark", "light",
"standard", "high"
], mediaValueKeywords = keySet(mediaValueKeywords_); ], mediaValueKeywords = keySet(mediaValueKeywords_);


var propertyKeywords_ = [ var propertyKeywords_ = [
"align-content", "align-items", "align-self", "alignment-adjust", "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-direction", "animation-duration", "animation-fill-mode",
"animation-iteration-count", "animation-name", "animation-play-state", "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-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", "line-stacking-shift", "line-stacking-strategy", "list-style",
"list-style-image", "list-style-position", "list-style-type", "margin", "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-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 // SVG-specific
"clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color", "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
"flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events", "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
"color-interpolation", "color-interpolation-filters", "color-interpolation", "color-interpolation-filters",
"color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering", "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-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
"stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering", "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
"baseline-shift", "dominant-baseline", "glyph-orientation-horizontal", "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
"glyph-orientation-vertical", "text-anchor", "writing-mode"
"glyph-orientation-vertical", "text-anchor", "writing-mode",
], propertyKeywords = keySet(propertyKeywords_); ], propertyKeywords = keySet(propertyKeywords_);


var nonStandardPropertyKeywords_ = [ 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-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
"scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-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_); ], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);


var fontProperties_ = [ 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_); ], fontProperties = keySet(fontProperties_);


var counterDescriptors_ = [ var counterDescriptors_ = [
@@ -565,16 +600,16 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
"burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
"cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
"darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
"darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen",
"darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "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", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
"gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
"hotpink", "indianred", "indigo", "ivory", "khaki", "lavender", "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
"lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "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", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
"maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
"mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
@@ -584,7 +619,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
"purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown", "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
"salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "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", "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
"whitesmoke", "yellow", "yellowgreen" "whitesmoke", "yellow", "yellowgreen"
], colorKeywords = keySet(colorKeywords_); ], colorKeywords = keySet(colorKeywords_);
@@ -594,22 +629,22 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate", "after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate",
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace", "always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
"arabic-indic", "armenian", "asterisks", "attr", "auto", "auto-flow", "avoid", "avoid-column", "avoid-page", "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", "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian",
"capitalize", "caps-lock-indicator", "caption", "captiontext", "caret", "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
"cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch", "cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
"cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote", "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
"col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse", "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", "decimal-leading-zero", "default", "default-button", "dense", "destination-atop",
"destination-in", "destination-out", "destination-over", "devanagari", "difference", "destination-in", "destination-out", "destination-over", "devanagari", "difference",
"disc", "discard", "disclosure-closed", "disclosure-open", "document", "disc", "discard", "disclosure-closed", "disclosure-open", "document",
"dot-dash", "dot-dot-dash", "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", "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
"ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er", "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
"ethiopic-abegede-ti-et", "ethiopic-halehame-aa-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-sid-et", "ethiopic-halehame-so-et",
"ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig", "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
"ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed", "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", "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew",
"help", "hidden", "hide", "higher", "highlight", "highlighttext", "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", "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
"infobackground", "infotext", "inherit", "initial", "inline", "inline-axis", "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
"inline-block", "inline-flex", "inline-grid", "inline-table", "inset", "inside", "intrinsic", "invert", "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", "line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
"local", "logical", "loud", "lower", "lower-alpha", "lower-armenian", "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
"lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian", "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", "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
"no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap", "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
"ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "opacity", "open-quote", "ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "opacity", "open-quote",
"optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset", "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
"outside", "outside-shape", "overlay", "overline", "padding", "padding-box", "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", "pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d",
"progress", "push-button", "radial-gradient", "radio", "read-only", "progress", "push-button", "radial-gradient", "radio", "read-only",
"read-write", "read-write-plaintext-only", "rectangle", "region", "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", "rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
"rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running", "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", "scroll", "scrollbar", "scroll-position", "se-resize", "searchfield",
"searchfield-cancel-button", "searchfield-decoration", "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", "simp-chinese-formal", "simp-chinese-informal", "single",
"skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal", "skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
"slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow", "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
"small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali", "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-caption", "table-cell", "table-column", "table-column-group",
"table-footer-group", "table-header-group", "table-row", "table-row-group", "table-footer-group", "table-header-group", "table-row", "table-row-group",
"tamil", "tamil",
@@ -677,10 +708,10 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top", "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
"trad-chinese-formal", "trad-chinese-informal", "transform", "trad-chinese-formal", "trad-chinese-informal", "transform",
"translate", "translate3d", "translateX", "translateY", "translateZ", "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-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
"upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", "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", "visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
"window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor", "window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor",
"xx-large", "xx-small" "xx-large", "xx-small"
@@ -748,8 +779,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
} }
}, },
":": function(stream) { ":": function(stream) {
if (stream.match(/\s*\{/))
return [null, "{"];
if (stream.match(/^\s*\{/, false))
return [null, null]
return false; return false;
}, },
"$": function(stream) { "$": function(stream) {
@@ -792,7 +823,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
}, },
"@": function(stream) { "@": function(stream) {
if (stream.eat("{")) return [null, "interpolation"]; 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\\\-]/); stream.eatWhile(/[\w\\\-]/);
if (stream.match(/^\s*:/, false)) if (stream.match(/^\s*:/, false))
return ["variable-2", "variable-definition"]; return ["variable-2", "variable-definition"];


+ 1
- 1
src/admin/js/mode/css/gss_test.js View File

@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/5/LICENSE


(function() { (function() {
"use strict"; "use strict";


+ 5
- 5
src/admin/js/mode/css/less_test.js View File

@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/5/LICENSE


(function() { (function() {
"use strict"; "use strict";
@@ -10,8 +10,8 @@
MT("variable", MT("variable",
"[variable-2 @base]: [atom #f04615];", "[variable-2 @base]: [atom #f04615];",
"[qualifier .class] {", "[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", MT("amp",
@@ -26,10 +26,10 @@


MT("mixin", MT("mixin",
"[qualifier .mixin] ([variable dark]; [variable-2 @color]) {", "[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]) {", "[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]) {", "[qualifier .mixin] ([variable-2 @_]; [variable-2 @color]) {",
" [property display]: [atom block];", " [property display]: [atom block];",


+ 6
- 6
src/admin/js/mode/css/scss_test.js View File

@@ -1,24 +1,24 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/5/LICENSE


(function() { (function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-scss"); var mode = CodeMirror.getMode({indentUnit: 2}, "text/x-scss");
function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "scss"); } function MT(name) { test.mode(name, mode, Array.prototype.slice.call(arguments, 1), "scss"); }


MT('url_with_quotation', 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', 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', 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', MT('string',
"[def @import] [string \"compass/css3\"]"); "[def @import] [string \"compass/css3\"]");


MT('important_keyword', 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', MT('variable',
"[variable-2 $blue]:[atom #333]"); "[variable-2 $blue]:[atom #333]");
@@ -95,7 +95,7 @@


MT('indent_parentheses', MT('indent_parentheses',
"[tag foo] {", "[tag foo] {",
" [property color]: [atom darken]([variable-2 $blue],",
" [property color]: [variable&callee darken]([variable-2 $blue],",
" [number 9%]);", " [number 9%]);",
"}"); "}");




+ 38
- 21
src/admin/js/mode/css/test.js View File

@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/5/LICENSE


(function() { (function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "css"); var mode = CodeMirror.getMode({indentUnit: 2}, "css");
@@ -24,6 +24,9 @@
MT("atMediaUnknownFeatureValueKeyword", MT("atMediaUnknownFeatureValueKeyword",
"[def @media] ([property orientation]: [error upsidedown]) { }"); "[def @media] ([property orientation]: [error upsidedown]) { }");


MT("atMediaUppercase",
"[def @MEDIA] ([property orienTAtion]: [keyword landScape]) { }");

MT("tagSelector", MT("tagSelector",
"[tag foo] { }"); "[tag foo] { }");


@@ -86,11 +89,11 @@
"[tag foo] { [property margin]: [number 0]; [property padding]: [number 0]; }"); "[tag foo] { [property margin]: [number 0]; [property padding]: [number 0]; }");


MT("tagTwoPropertiesURL", 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", MT("indent_tagSelector",
"[tag strong], [tag em] {", "[tag strong], [tag em] {",
" [property background]: [atom rgba](",
" [property background]: [variable&callee rgba](",
" [number 255], [number 255], [number 0], [number .2]", " [number 255], [number 255], [number 0], [number .2]",
" );", " );",
"}"); "}");
@@ -111,7 +114,7 @@


MT("indent_parentheses", MT("indent_parentheses",
"[tag foo]:[variable-3 before] {", "[tag foo]:[variable-3 before] {",
" [property background]: [atom url](",
" [property background]: [variable&callee url](",
"[string blahblah]", "[string blahblah]",
"[string etc]", "[string etc]",
"[string ]) [keyword !important];", "[string ]) [keyword !important];",
@@ -121,20 +124,20 @@
"[def @font-face] {", "[def @font-face] {",
" [property font-family]: [string 'myfont'];", " [property font-family]: [string 'myfont'];",
" [error nonsense]: [string 'abc'];", " [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", MT("empty_url",
"[def @import] [atom url]() [attribute screen];");
"[def @import] [variable&callee url]() [attribute screen];");


MT("parens", MT("parens",
"[qualifier .foo] {", "[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],", " [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];", " [variable-2 --main-color]: [atom #06c];",
"}", "}",
"[tag h1][builtin #foo] {", "[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", MT("supports",
@@ -152,10 +163,10 @@
"}"); "}");


MT("document", 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] {", " [builtin #id] {",
" [property background-color]: [keyword white];", " [property background-color]: [keyword white];",
" }", " }",
@@ -165,16 +176,16 @@
"}"); "}");


MT("document_url", 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", 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", 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", MT("document_regexp",
"[def @document] [tag regexp]([string \".*blah.+\"]) { [builtin #id] { } }");
"[def @document] [variable&callee regexp]([string \".*blah.+\"]) { [builtin #id] { } }");


MT("counter-style", MT("counter-style",
"[def @counter-style] [variable binary] {", "[def @counter-style] [variable binary] {",
@@ -196,5 +207,11 @@
"[tag ol][qualifier .roman] { [property list-style]: [variable simple-roman]; }"); "[tag ol][qualifier .roman] { [property list-style]: [variable simple-roman]; }");


MT("counter-style-symbols", 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];",
"}")
})(); })();

+ 8
- 7
src/admin/js/mode/htmlmixed/htmlmixed.js View File

@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/5/LICENSE


(function(mod) { (function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -50,7 +50,7 @@
} }


function getTagRegexp(tagName, anchored) { function getTagRegexp(tagName, anchored) {
return new RegExp((anchored ? "^" : "") + "<\/\s*" + tagName + "\s*>", "i");
return new RegExp((anchored ? "^" : "") + "<\/\\s*" + tagName + "\\s*>", "i");
} }


function addTags(from, to) { function addTags(from, to) {
@@ -74,7 +74,8 @@
name: "xml", name: "xml",
htmlMode: true, htmlMode: true,
multilineTagIndentFactor: parserConfig.multilineTagIndentFactor, multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag
multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag,
allowMissingTagName: parserConfig.allowMissingTagName,
}); });


var tags = {}; var tags = {};
@@ -105,7 +106,7 @@
return maybeBackup(stream, endTag, state.localMode.token(stream, state.localState)); return maybeBackup(stream, endTag, state.localMode.token(stream, state.localState));
}; };
state.localMode = mode; 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) { } else if (state.inTag) {
state.inTag += stream.current() state.inTag += stream.current()
if (stream.eol()) state.inTag += " " if (stream.eol()) state.inTag += " "
@@ -133,11 +134,11 @@
return state.token(stream, state); return state.token(stream, state);
}, },


indent: function (state, textAfter) {
indent: function (state, textAfter, line) {
if (!state.localMode || /^\s*<\//.test(textAfter)) if (!state.localMode || /^\s*<\//.test(textAfter))
return htmlMode.indent(state.htmlState, textAfter);
return htmlMode.indent(state.htmlState, textAfter, line);
else if (state.localMode.indent) else if (state.localMode.indent)
return state.localMode.indent(state.localState, textAfter);
return state.localMode.indent(state.localState, textAfter, line);
else else
return CodeMirror.Pass; return CodeMirror.Pass;
}, },


+ 323
- 163
src/admin/js/mode/javascript/javascript.js View File

@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/5/LICENSE


(function(mod) { (function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -11,16 +11,12 @@
})(function(CodeMirror) { })(function(CodeMirror) {
"use strict"; "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) { CodeMirror.defineMode("javascript", function(config, parserConfig) {
var indentUnit = config.indentUnit; var indentUnit = config.indentUnit;
var statementIndent = parserConfig.statementIndent; var statementIndent = parserConfig.statementIndent;
var jsonldMode = parserConfig.jsonld; var jsonldMode = parserConfig.jsonld;
var jsonMode = parserConfig.json || jsonldMode; var jsonMode = parserConfig.json || jsonldMode;
var trackScope = parserConfig.trackScope !== false
var isTS = parserConfig.typescript; var isTS = parserConfig.typescript;
var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/; var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;


@@ -28,56 +24,24 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {


var keywords = function(){ var keywords = function(){
function kw(type) {return {type: type, style: "keyword"};} 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 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, "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"), "function": kw("function"), "catch": kw("catch"),
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
"in": operator, "typeof": operator, "instanceof": operator, "in": operator, "typeof": operator, "instanceof": operator,
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
"this": kw("this"), "class": kw("class"), "super": kw("atom"), "this": kw("this"), "class": kw("class"), "super": kw("atom"),
"yield": C, "export": kw("export"), "import": kw("import"), "extends": C, "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)"/; var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;


function readRegexp(stream) { function readRegexp(stream) {
@@ -104,7 +68,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (ch == '"' || ch == "'") { if (ch == '"' || ch == "'") {
state.tokenize = tokenString(ch); state.tokenize = tokenString(ch);
return state.tokenize(stream, state); 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"); return ret("number", "number");
} else if (ch == "." && stream.match("..")) { } else if (ch == "." && stream.match("..")) {
return ret("spread", "meta"); return ret("spread", "meta");
@@ -112,17 +76,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
return ret(ch); return ret(ch);
} else if (ch == "=" && stream.eat(">")) { } else if (ch == "=" && stream.eat(">")) {
return ret("=>", "operator"); 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"); return ret("number", "number");
} else if (/\d/.test(ch)) { } else if (/\d/.test(ch)) {
stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
stream.match(/^[\d_]*(?:n|(?:\.[\d_]*)?(?:[eE][+\-]?[\d_]+)?)?/);
return ret("number", "number"); return ret("number", "number");
} else if (ch == "/") { } else if (ch == "/") {
if (stream.eat("*")) { if (stream.eat("*")) {
@@ -133,27 +90,47 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
return ret("comment", "comment"); return ret("comment", "comment");
} else if (expressionAllowed(stream, state, 1)) { } else if (expressionAllowed(stream, state, 1)) {
readRegexp(stream); readRegexp(stream);
stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
stream.match(/^\b(([gimyus])(?![gimyus]*\2))+\b/);
return ret("regexp", "string-2"); return ret("regexp", "string-2");
} else { } else {
stream.eatWhile(isOperatorChar);
stream.eat("=");
return ret("operator", "operator", stream.current()); return ret("operator", "operator", stream.current());
} }
} else if (ch == "`") { } else if (ch == "`") {
state.tokenize = tokenQuasi; state.tokenize = tokenQuasi;
return tokenQuasi(stream, state); return tokenQuasi(stream, state);
} else if (ch == "#") {
} else if (ch == "#" && stream.peek() == "!") {
stream.skipToEnd(); 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)) { } 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()); return ret("operator", "operator", stream.current());
} else if (wordRE.test(ch)) { } else if (wordRE.test(ch)) {
stream.eatWhile(wordRE); 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; ++depth;
} else if (wordRE.test(ch)) { } else if (wordRE.test(ch)) {
sawSomething = true; 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) { } else if (sawSomething && !depth) {
++pos; ++pos;
break; break;
@@ -238,7 +219,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {


// Parser // 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) { function JSLexical(indented, column, type, align, prev, info) {
this.indented = indented; this.indented = indented;
@@ -250,6 +232,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
} }


function inScope(state, varname) { function inScope(state, varname) {
if (!trackScope) return false
for (var v = state.localVars; v; v = v.next) for (var v = state.localVars; v; v = v.next)
if (v.name == varname) return true; if (v.name == varname) return true;
for (var cx = state.context; cx; cx = cx.prev) { for (var cx = state.context; cx; cx = cx.prev) {
@@ -289,35 +272,70 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
pass.apply(null, arguments); pass.apply(null, arguments);
return true; 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 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; var state = cx.state;
cx.marked = "def"; cx.marked = "def";
if (!trackScope) return
if (state.context) { 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 { } 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 // 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() { 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() { 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) { function pushlex(type, info) {
var result = function() { var result = function() {
var state = cx.state, indent = state.indented; var state = cx.state, indent = state.indented;
@@ -342,17 +360,19 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function expect(wanted) { function expect(wanted) {
function exp(type) { function exp(type) {
if (type == wanted) return cont(); if (type == wanted) return cont();
else if (wanted == ";") return pass();
else if (wanted == ";" || type == "}" || type == ")" || type == "]") return pass();
else return cont(exp); else return cont(exp);
}; };
return exp; return exp;
} }


function statement(type, value) { 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 a") return cont(pushlex("form"), parenExpr, statement, poplex);
if (type == "keyword b") return cont(pushlex("form"), 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 == ";") return cont();
if (type == "if") { if (type == "if") {
if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex) 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); return cont(pushlex("form"), parenExpr, statement, poplex, maybeelse);
} }
if (type == "function") return cont(functiondef); 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 == "case") return cont(expression, expect(":"));
if (type == "default") return cont(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 == "export") return cont(pushlex("stat"), afterExport, poplex);
if (type == "import") return cont(pushlex("stat"), afterImport, 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 (type == "async") return cont(statement)
if (value == "@") return cont(expression, statement)
return pass(pushlex("stat"), expression, expect(";"), poplex); 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) { function parenExpr(type) {
if (type != "(") return pass() 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) { if (cx.state.fatArrowAt == cx.stream.start) {
var body = noComma ? arrowBodyNoComma : arrowBody; 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); else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
} }


var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
if (type == "function") return cont(functiondef, 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 == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression); if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop); if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
@@ -410,13 +452,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type.match(/[;\}\)\],]/)) return pass(); if (type.match(/[;\}\)\],]/)) return pass();
return pass(expression); return pass(expression);
} }
function maybeexpressionNoComma(type) {
if (type.match(/[;\}\)\],]/)) return pass();
return pass(expressionNoComma);
}


function maybeoperatorComma(type, value) { function maybeoperatorComma(type, value) {
if (type == ",") return cont(expression);
if (type == ",") return cont(maybeexpression);
return maybeoperatorNoComma(type, value, false); return maybeoperatorNoComma(type, value, false);
} }
function maybeoperatorNoComma(type, value, noComma) { function maybeoperatorNoComma(type, value, noComma) {
@@ -424,7 +462,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var expr = noComma == false ? expression : expressionNoComma; var expr = noComma == false ? expression : expressionNoComma;
if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
if (type == "operator") { 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); if (value == "?") return cont(expression, expect(":"), expr);
return cont(expr); return cont(expr);
} }
@@ -433,11 +473,17 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "(") return contCommasep(expressionNoComma, ")", "call", me); if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
if (type == ".") return cont(property, me); if (type == ".") return cont(property, me);
if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, 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) { function quasi(type, value) {
if (type != "quasi") return pass(); if (type != "quasi") return pass();
if (value.slice(value.length - 2) != "${") return cont(quasi); if (value.slice(value.length - 2) != "${") return cont(quasi);
return cont(expression, continueQuasi);
return cont(maybeexpression, continueQuasi);
} }
function continueQuasi(type) { function continueQuasi(type) {
if (type == "}") { if (type == "}") {
@@ -457,6 +503,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function maybeTarget(noComma) { function maybeTarget(noComma) {
return function(type) { return function(type) {
if (type == ".") return cont(noComma ? targetNoComma : target); if (type == ".") return cont(noComma ? targetNoComma : target);
else if (type == "variable" && isTS) return cont(maybeTypeArgs, noComma ? maybeoperatorNoComma : maybeoperatorComma)
else return pass(noComma ? expressionNoComma : expression); else return pass(noComma ? expressionNoComma : expression);
}; };
} }
@@ -480,18 +527,25 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
} else if (type == "variable" || cx.style == "keyword") { } else if (type == "variable" || cx.style == "keyword") {
cx.marked = "property"; cx.marked = "property";
if (value == "get" || value == "set") return cont(getterSetter); 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); return cont(afterprop);
} else if (type == "number" || type == "string") { } else if (type == "number" || type == "string") {
cx.marked = jsonldMode ? "property" : (cx.style + " property"); cx.marked = jsonldMode ? "property" : (cx.style + " property");
return cont(afterprop); return cont(afterprop);
} else if (type == "jsonld-keyword") { } else if (type == "jsonld-keyword") {
return cont(afterprop); return cont(afterprop);
} else if (type == "modifier") {
} else if (isTS && isModifier(value)) {
cx.marked = "keyword"
return cont(objprop) return cont(objprop)
} else if (type == "[") { } else if (type == "[") {
return cont(expression, expect("]"), afterprop);
return cont(expression, maybetype, expect("]"), afterprop);
} else if (type == "spread") { } else if (type == "spread") {
return cont(expression);
return cont(expressionNoComma, afterprop);
} else if (value == "*") {
cx.marked = "keyword";
return cont(objprop);
} else if (type == ":") { } else if (type == ":") {
return pass(afterprop) return pass(afterprop)
} }
@@ -516,6 +570,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}, proceed); }, proceed);
} }
if (type == end || value == end) return cont(); if (type == end || value == end) return cont();
if (sep && sep.indexOf(";") > -1) return pass(what)
return cont(expect(end)); return cont(expect(end));
} }
return function(type, value) { return function(type, value) {
@@ -538,42 +593,105 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (value == "?") return cont(maybetype); 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 == "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) { function maybeReturnType(type) {
if (type == "=>") return cont(typeexpr) 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) { function typeprop(type, value) {
if (type == "variable" || cx.style == "keyword") { if (type == "variable" || cx.style == "keyword") {
cx.marked = "property" cx.marked = "property"
return cont(typeprop) return cont(typeprop)
} else if (value == "?") {
} else if (value == "?" || type == "number" || type == "string") {
return cont(typeprop) return cont(typeprop)
} else if (type == ":") { } else if (type == ":") {
return cont(typeexpr) 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) { function afterType(type, value) {
if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType) 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); return pass(pattern, maybetype, maybeAssign, vardefCont);
} }
function pattern(type, value) { 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 == "variable") { register(value); return cont(); }
if (type == "spread") return cont(pattern); if (type == "spread") return cont(pattern);
if (type == "[") return contCommasep(pattern, "]");
if (type == "[") return contCommasep(eltpattern, "]");
if (type == "{") return contCommasep(proppattern, "}"); if (type == "{") return contCommasep(proppattern, "}");
} }
function proppattern(type, value) { function proppattern(type, value) {
@@ -584,8 +702,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "variable") cx.marked = "property"; if (type == "variable") cx.marked = "property";
if (type == "spread") return cont(pattern); if (type == "spread") return cont(pattern);
if (type == "}") return pass(); if (type == "}") return pass();
if (type == "[") return cont(expression, expect(']'), expect(':'), proppattern);
return cont(expect(":"), pattern, maybeAssign); return cont(expect(":"), pattern, maybeAssign);
} }
function eltpattern() {
return pass(pattern, maybeAssign)
}
function maybeAssign(_type, value) { function maybeAssign(_type, value) {
if (value == "=") return cont(expressionNoComma); if (value == "=") return cont(expressionNoComma);
} }
@@ -595,34 +717,46 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
function maybeelse(type, value) { function maybeelse(type, value) {
if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex); 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) { 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) { 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) { function functiondef(type, value) {
if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
if (type == "variable") {register(value); 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 (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); return pass(pattern, maybetype, maybeAssign);
} }
function classExpression(type, value) { function classExpression(type, value) {
@@ -634,34 +768,44 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "variable") {register(value); return cont(classNameAfter);} if (type == "variable") {register(value); return cont(classNameAfter);}
} }
function classNameAfter(type, value) { 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); return cont(isTS ? typeexpr : expression, classNameAfter);
}
if (type == "{") return cont(pushlex("}"), classBody, poplex); if (type == "{") return cont(pushlex("}"), classBody, poplex);
} }
function classBody(type, value) { 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 (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"; cx.marked = "property";
return cont(isTS ? classfield : functiondef, classBody);
return cont(classfield, classBody);
} }
if (type == "number" || type == "string") return cont(classfield, classBody);
if (type == "[") if (type == "[")
return cont(expression, expect("]"), isTS ? classfield : functiondef, classBody)
return cont(expression, maybetype, expect("]"), classfield, classBody)
if (value == "*") { if (value == "*") {
cx.marked = "keyword"; cx.marked = "keyword";
return cont(classBody); 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 (type == "}") return cont();
if (value == "@") return cont(expression, classBody)
} }
function classfield(type, value) { function classfield(type, value) {
if (value == "!") return cont(classfield)
if (value == "?") return cont(classfield) if (value == "?") return cont(classfield)
if (type == ":") return cont(typeexpr, maybeAssign) 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) { function afterExport(type, value) {
if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); } if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
@@ -675,6 +819,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
} }
function afterImport(type) { function afterImport(type) {
if (type == "string") return cont(); if (type == "string") return cont();
if (type == "(") return pass(expression);
if (type == ".") return pass(maybeoperatorComma);
return pass(importSpec, maybeMoreImports, maybeFrom); return pass(importSpec, maybeMoreImports, maybeFrom);
} }
function importSpec(type, value) { function importSpec(type, value) {
@@ -696,6 +842,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if (type == "]") return cont(); if (type == "]") return cont();
return pass(commasep(expressionNoComma, "]")); 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) { function isContinuedStatement(state, textAfter) {
return state.lastType == "operator" || state.lastType == "," || return state.lastType == "operator" || state.lastType == "," ||
@@ -703,6 +855,12 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
/[,.]/.test(textAfter.charAt(0)); /[,.]/.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 // Interface


return { return {
@@ -713,7 +871,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
cc: [], cc: [],
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
localVars: parserConfig.localVars, localVars: parserConfig.localVars,
context: parserConfig.localVars && {vars: parserConfig.localVars},
context: parserConfig.localVars && new Context(null, null, false),
indented: basecolumn || 0 indented: basecolumn || 0
}; };
if (parserConfig.globalVars && typeof parserConfig.globalVars == "object") if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
@@ -736,14 +894,14 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}, },


indent: function(state, textAfter) { 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; if (state.tokenize != tokenBase) return 0;
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, top var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, top
// Kludge to prevent 'maybelse' from blocking lexical scope pops // 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) { if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
var c = state.cc[i]; var c = state.cc[i];
if (c == poplex) lexical = lexical.prev; 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") && while ((lexical.type == "stat" || lexical.type == "form") &&
(firstChar == "}" || ((top = state.cc[state.cc.length - 1]) && (firstChar == "}" || ((top = state.cc[state.cc.length - 1]) &&
@@ -754,7 +912,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
lexical = lexical.prev; lexical = lexical.prev;
var type = lexical.type, closing = firstChar == type; 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" && firstChar == "{") return lexical.indented;
else if (type == "form") return lexical.indented + indentUnit; else if (type == "form") return lexical.indented + indentUnit;
else if (type == "stat") else if (type == "stat")
@@ -768,6 +926,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
electricInput: /^\s*(?:case .*?:|default:|\{|\})$/, electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
blockCommentStart: jsonMode ? null : "/*", blockCommentStart: jsonMode ? null : "/*",
blockCommentEnd: jsonMode ? null : "*/", blockCommentEnd: jsonMode ? null : "*/",
blockCommentContinue: jsonMode ? null : " * ",
lineComment: jsonMode ? null : "//", lineComment: jsonMode ? null : "//",
fold: "brace", fold: "brace",
closeBrackets: "()[]{}''\"\"``", closeBrackets: "()[]{}''\"\"``",
@@ -777,9 +936,9 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
jsonMode: jsonMode, jsonMode: jsonMode,


expressionAllowed: expressionAllowed, expressionAllowed: expressionAllowed,

skipExpression: function(state) { 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/javascript", "javascript");
CodeMirror.defineMIME("application/x-javascript", "javascript"); CodeMirror.defineMIME("application/x-javascript", "javascript");
CodeMirror.defineMIME("application/ecmascript", "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("text/typescript", { name: "javascript", typescript: true });
CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true }); CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });




+ 219
- 27
src/admin/js/mode/javascript/test.js View File

@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/5/LICENSE


(function() { (function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "javascript"); var mode = CodeMirror.getMode({indentUnit: 2}, "javascript");
@@ -63,6 +63,12 @@
MT("import_trailing_comma", MT("import_trailing_comma",
"[keyword import] {[def foo], [def bar],} [keyword from] [string 'baz']") "[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", MT("const",
"[keyword function] [def f]() {", "[keyword function] [def f]() {",
" [keyword const] [[ [def a], [def b] ]] [operator =] [[ [number 1], [number 2] ]];", " [keyword const] [[ [def a], [def b] ]] [operator =] [[ [number 1], [number 2] ]];",
@@ -71,12 +77,44 @@
MT("for/of", MT("for/of",
"[keyword for]([keyword let] [def of] [keyword of] [variable something]) {}"); "[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", MT("generator",
"[keyword function*] [def repeat]([def n]) {", "[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 for]([keyword var] [def i] [operator =] [number 0]; [variable-2 i] [operator <] [variable-2 n]; [operator ++][variable-2 i])",
" [keyword yield] [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", MT("quotedStringAddition",
"[keyword let] [def f] [operator =] [variable a] [operator +] [string 'fatarrow'] [operator +] [variable c];"); "[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];", "[keyword let] [def f] [operator =] ([[ [def a], [def b] ]], [def c]) [operator =>] [variable-2 a] [operator +] [variable-2 c];",
"[variable c];"); "[variable c];");


MT("fatArrow_stringDefault",
"([def a], [def b] [operator =] [string 'x\\'y']) [operator =>] [variable-2 a] [operator +] [variable-2 b]")

MT("spread", MT("spread",
"[keyword function] [def f]([def a], [meta ...][def b]) {", "[keyword function] [def f]([def a], [meta ...][def b]) {",
" [variable something]([variable-2 a], [meta ...][variable-2 b]);", " [variable something]([variable-2 a], [meta ...][variable-2 b]);",
@@ -123,9 +164,9 @@


MT("indent_for", MT("indent_for",
"[keyword for] ([keyword var] [def i] [operator =] [number 0];", "[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];"); "[keyword debugger];");


MT("indent_c_style", MT("indent_c_style",
@@ -188,6 +229,12 @@
" [keyword return] [variable-2 x];", " [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", MT("new_target",
"[keyword function] [def F]([def target]) {", "[keyword function] [def F]([def target]) {",
" [keyword if] ([variable-2 target] [operator &&] [keyword new].[keyword target].[property name]) {", " [keyword if] ([variable-2 target] [operator &&] [keyword new].[keyword target].[property name]) {",
@@ -205,7 +252,7 @@
MT("async_object", MT("async_object",
"[keyword let] [def obj] [operator =] { [property async]: [atom false] };"); "[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", MT("async_object_function",
"[keyword let] [def obj] [operator =] { [property async] [property foo]([def args]) { [keyword return] [atom true]; } };"); "[keyword let] [def obj] [operator =] { [property async] [property foo]([def args]) { [keyword return] [atom true]; } };");


@@ -226,21 +273,73 @@
" [property method]: [string 'GET']", " [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") var ts_mode = CodeMirror.getMode({indentUnit: 2}, "application/typescript")
function TS(name) { function TS(name) {
test.mode(name, ts_mode, Array.prototype.slice.call(arguments, 1)) 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", TS("typescript_class",
"[keyword class] [def Foo] {", "[keyword class] [def Foo] {",
" [keyword public] [keyword static] [property main]() {}", " [keyword public] [keyword static] [property main]() {}",
" [keyword private] [property _foo]: [variable-3 string];",
" [keyword private] [property _foo]: [type string];",
"}") "}")


TS("typescript_literal_types", TS("typescript_literal_types",
@@ -249,46 +348,139 @@
" [property truthy]: [string 'true'] [operator |] [number 1] [operator |] [atom true];", " [property truthy]: [string 'true'] [operator |] [number 1] [operator |] [atom true];",
" [property falsy]: [string 'false'] [operator |] [number 0] [operator |] [atom false];", " [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 truthy]: [string 'true'] [operator |] [number 1] [operator |] [atom true];",
" [property falsy]: [string 'false'] [operator |] [number 0] [operator |] [atom false];", " [property falsy]: [string 'false'] [operator |] [number 0] [operator |] [atom false];",
"}") "}")


TS("typescript_extend_operators", TS("typescript_extend_operators",
"[keyword export] [keyword interface] [def UserModel] [keyword extends]", "[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]: (", " [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]: (", " [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", TS("typescript_interface_with_const",
"[keyword const] [def hello]: {", "[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 =] {};") "} [operator =] {};")


TS("typescript_double_extend", TS("typescript_double_extend",
"[keyword export] [keyword interface] [def UserAttributes] {", "[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", TS("typescript_index_signature",
"[keyword interface] [def A] {", "[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( var jsonld_mode = CodeMirror.getMode(
{indentUnit: 2}, {indentUnit: 2},
{name: "javascript", jsonld: true} {name: "javascript", jsonld: true}


+ 12
- 12
src/admin/js/mode/php/php.js
File diff suppressed because it is too large
View File


+ 1
- 1
src/admin/js/mode/php/test.js View File

@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/5/LICENSE


(function() { (function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "php"); var mode = CodeMirror.getMode({indentUnit: 2}, "php");


+ 190
- 76
src/admin/js/mode/sql/sql.js
File diff suppressed because it is too large
View File


+ 1
- 1
src/admin/js/mode/xml/test.js View File

@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/5/LICENSE


(function() { (function() {
var mode = CodeMirror.getMode({indentUnit: 2}, "xml"), mname = "xml"; var mode = CodeMirror.getMode({indentUnit: 2}, "xml"), mname = "xml";


+ 33
- 10
src/admin/js/mode/xml/xml.js View File

@@ -1,5 +1,5 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others // CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
// Distributed under an MIT license: https://codemirror.net/5/LICENSE


(function(mod) { (function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS if (typeof exports == "object" && typeof module == "object") // CommonJS
@@ -52,6 +52,7 @@ var xmlConfig = {
doNotIndent: {}, doNotIndent: {},
allowUnquoted: false, allowUnquoted: false,
allowMissing: false, allowMissing: false,
allowMissingTagName: false,
caseFold: false caseFold: false
} }


@@ -162,8 +163,9 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
stream.next(); stream.next();
} }
return style; return style;
};
}
} }

function doctype(depth) { function doctype(depth) {
return function(stream, state) { return function(stream, state) {
var ch; var ch;
@@ -185,9 +187,13 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
}; };
} }


function lower(tagName) {
return tagName && tagName.toLowerCase();
}

function Context(state, tagName, startOfLine) { function Context(state, tagName, startOfLine) {
this.prev = state.context; this.prev = state.context;
this.tagName = tagName;
this.tagName = tagName || "";
this.indent = state.indented; this.indent = state.indented;
this.startOfLine = startOfLine; this.startOfLine = startOfLine;
if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent)) if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
@@ -203,8 +209,8 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
return; return;
} }
parentTagName = state.context.tagName; 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; return;
} }
popContext(state); popContext(state);
@@ -226,6 +232,9 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
state.tagName = stream.current(); state.tagName = stream.current();
setStyle = "tag"; setStyle = "tag";
return attrState; return attrState;
} else if (config.allowMissingTagName && type == "endTag") {
setStyle = "tag bracket";
return attrState(type, stream, state);
} else { } else {
setStyle = "error"; setStyle = "error";
return tagNameState; return tagNameState;
@@ -235,7 +244,7 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
if (type == "word") { if (type == "word") {
var tagName = stream.current(); var tagName = stream.current();
if (state.context && state.context.tagName != tagName && if (state.context && state.context.tagName != tagName &&
config.implicitlyClosed.hasOwnProperty(state.context.tagName))
config.implicitlyClosed.hasOwnProperty(lower(state.context.tagName)))
popContext(state); popContext(state);
if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) { if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) {
setStyle = "tag"; setStyle = "tag";
@@ -244,6 +253,9 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
setStyle = "tag error"; setStyle = "tag error";
return closeStateErr; return closeStateErr;
} }
} else if (config.allowMissingTagName && type == "endTag") {
setStyle = "tag bracket";
return closeState(type, stream, state);
} else { } else {
setStyle = "error"; setStyle = "error";
return closeStateErr; return closeStateErr;
@@ -271,7 +283,7 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
var tagName = state.tagName, tagStart = state.tagStart; var tagName = state.tagName, tagStart = state.tagStart;
state.tagName = state.tagStart = null; state.tagName = state.tagStart = null;
if (type == "selfcloseTag" || if (type == "selfcloseTag" ||
config.autoSelfClosers.hasOwnProperty(tagName)) {
config.autoSelfClosers.hasOwnProperty(lower(tagName))) {
maybePopContext(state, tagName); maybePopContext(state, tagName);
} else { } else {
maybePopContext(state, tagName); maybePopContext(state, tagName);
@@ -351,7 +363,7 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
if (context.tagName == tagAfter[2]) { if (context.tagName == tagAfter[2]) {
context = context.prev; context = context.prev;
break; break;
} else if (config.implicitlyClosed.hasOwnProperty(context.tagName)) {
} else if (config.implicitlyClosed.hasOwnProperty(lower(context.tagName))) {
context = context.prev; context = context.prev;
} else { } else {
break; break;
@@ -359,8 +371,8 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
} }
} else if (tagAfter) { // Opening tag spotted } else if (tagAfter) { // Opening tag spotted
while (context) { 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; context = context.prev;
else else
break; break;
@@ -382,6 +394,17 @@ CodeMirror.defineMode("xml", function(editorConf, config_) {
skipAttribute: function(state) { skipAttribute: function(state) {
if (state.state == attrValueState) if (state.state == attrValueState)
state.state = attrState 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()
} }
}; };
}); });


Loading…
Cancel
Save