2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 06:39:11 +00:00

codemirror: update to version 3.24

git-svn-id: https://svn.fhem.de/fhem/trunk@5647 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
betateilchen 2014-04-25 20:58:29 +00:00
parent 84a6d10d4e
commit d29d48cf6a
6 changed files with 306 additions and 156 deletions

View File

@ -1,4 +1,4 @@
Copyright (C) 2013 by Marijn Haverbeke <marijnh@gmail.com> and others
Copyright (C) 2014 by Marijn Haverbeke <marijnh@gmail.com> and others
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -36,6 +36,8 @@
min-width: 20px;
text-align: right;
color: #999;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
/* CURSOR */
@ -59,17 +61,23 @@
.cm-tab { display: inline-block; }
.CodeMirror-ruler {
border-left: 1px solid #ccc;
position: absolute;
}
/* DEFAULT THEME */
.cm-s-default .cm-keyword {color: #708;}
.cm-s-default .cm-atom {color: #219;}
.cm-s-default .cm-number {color: #164;}
.cm-s-default .cm-def {color: #00f;}
.cm-s-default .cm-variable {color: black;}
.cm-s-default .cm-variable,
.cm-s-default .cm-punctuation,
.cm-s-default .cm-property,
.cm-s-default .cm-operator {}
.cm-s-default .cm-variable-2 {color: #05a;}
.cm-s-default .cm-variable-3 {color: #085;}
.cm-s-default .cm-property {color: black;}
.cm-s-default .cm-operator {color: black;}
.cm-s-default .cm-comment {color: #a50;}
.cm-s-default .cm-string {color: #a11;}
.cm-s-default .cm-string-2 {color: #f50;}
@ -114,7 +122,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
/* 30px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
margin-bottom: -30px; margin-right: -30px;
padding-bottom: 30px; padding-right: 30px;
padding-bottom: 30px;
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
@ -123,6 +131,9 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
}
.CodeMirror-sizer {
position: relative;
border-right: 30px solid transparent;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
@ -197,16 +208,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
white-space: pre-wrap;
word-break: normal;
}
.CodeMirror-code pre {
border-right: 30px solid transparent;
width: -webkit-fit-content;
width: -moz-fit-content;
width: fit-content;
}
.CodeMirror-wrap .CodeMirror-code pre {
border-right: none;
width: auto;
}
.CodeMirror-linebackground {
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;

View File

@ -1,5 +1,3 @@
// CodeMirror version 3.21
//
// CodeMirror is the only global var we claim
window.CodeMirror = (function() {
"use strict";
@ -15,6 +13,7 @@ window.CodeMirror = (function() {
var old_ie = /MSIE \d/.test(navigator.userAgent);
var ie_lt8 = old_ie && (document.documentMode == null || document.documentMode < 8);
var ie_lt9 = old_ie && (document.documentMode == null || document.documentMode < 9);
var ie_lt10 = old_ie && (document.documentMode == null || document.documentMode < 10);
var ie_gt10 = /Trident\/([7-9]|\d{2,})\./.test(navigator.userAgent);
var ie = old_ie || ie_gt10;
var webkit = /WebKit\//.test(navigator.userAgent);
@ -38,7 +37,7 @@ window.CodeMirror = (function() {
if (opera_version && opera_version >= 15) { opera = false; webkit = true; }
// Some browsers use the wrong event properties to signal cmd/ctrl on OS X
var flipCtrlCmd = mac && (qtwebkit || opera && (opera_version == null || opera_version < 12.11));
var captureMiddleClick = gecko || (old_ie && !ie_lt9);
var captureMiddleClick = gecko || (ie && !ie_lt9);
// Optimize some code when these features are not used
var sawReadOnlySpans = false, sawCollapsedSpans = false;
@ -101,7 +100,7 @@ window.CodeMirror = (function() {
function makeDisplay(place, docStart) {
var d = {};
var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none; font-size: 4px;");
var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none");
if (webkit) input.style.width = "1000px";
else input.setAttribute("wrap", "off");
// if border: 0; -- iOS fails to open keyboard (issue #1287)
@ -111,8 +110,8 @@ window.CodeMirror = (function() {
// Wraps and hides input textarea
d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
// The actual fake scrollbars.
d.scrollbarH = elt("div", [elt("div", null, null, "height: 1px")], "CodeMirror-hscrollbar");
d.scrollbarV = elt("div", [elt("div", null, null, "width: 1px")], "CodeMirror-vscrollbar");
d.scrollbarH = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar");
d.scrollbarV = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar");
d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
// DIVs containing the selection and the actual code
@ -173,7 +172,7 @@ window.CodeMirror = (function() {
// Self-resetting timeout for the poller
d.poll = new Delayed();
d.cachedCharWidth = d.cachedTextHeight = null;
d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
d.measureLineCache = [];
d.measureLineCachePos = 0;
@ -231,12 +230,17 @@ window.CodeMirror = (function() {
var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
return function(line) {
if (lineIsHidden(cm.doc, line))
return 0;
else if (wrapping)
return (Math.ceil(line.text.length / perLine) || 1) * th;
if (lineIsHidden(cm.doc, line)) return 0;
var widgetsHeight = 0;
if (line.widgets) for (var i = 0; i < line.widgets.length; i++) {
if (line.widgets[i].height) widgetsHeight += line.widgets[i].height;
}
if (wrapping)
return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th;
else
return th;
return widgetsHeight + th;
};
}
@ -334,13 +338,14 @@ window.CodeMirror = (function() {
d.sizer.style.minHeight = d.heightForcer.style.top = totalHeight + "px";
d.gutters.style.height = Math.max(totalHeight, d.scroller.clientHeight - scrollerCutOff) + "px";
var scrollHeight = Math.max(totalHeight, d.scroller.scrollHeight);
var needsH = d.scroller.scrollWidth > (d.scroller.clientWidth + 1);
var needsV = scrollHeight > (d.scroller.clientHeight + 1);
var needsH = d.scroller.scrollWidth > d.scroller.clientWidth;
var needsV = scrollHeight > d.scroller.clientHeight;
if (needsV) {
d.scrollbarV.style.display = "block";
d.scrollbarV.style.bottom = needsH ? scrollbarWidth(d.measure) + "px" : "0";
// A bug in IE8 can cause this value to be negative, so guard it.
d.scrollbarV.firstChild.style.height =
(scrollHeight - d.scroller.clientHeight + d.scrollbarV.clientHeight) + "px";
Math.max(0, scrollHeight - d.scroller.clientHeight + d.scrollbarV.clientHeight) + "px";
} else {
d.scrollbarV.style.display = "";
d.scrollbarV.firstChild.style.height = "0";
@ -366,7 +371,12 @@ window.CodeMirror = (function() {
if (mac_geLion && scrollbarWidth(d.measure) === 0) {
d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = mac_geMountainLion ? "18px" : "12px";
d.scrollbarV.style.pointerEvents = d.scrollbarH.style.pointerEvents = "none";
var barMouseDown = function(e) {
if (e_target(e) != d.scrollbarV && e_target(e) != d.scrollbarH)
operation(cm, onMouseDown)(e);
};
on(d.scrollbarV, "mousedown", barMouseDown);
on(d.scrollbarH, "mousedown", barMouseDown);
}
}
@ -820,12 +830,12 @@ window.CodeMirror = (function() {
function updateSelectionRange(cm) {
var display = cm.display, doc = cm.doc, sel = cm.doc.sel;
var fragment = document.createDocumentFragment();
var clientWidth = display.lineSpace.offsetWidth, pl = paddingLeft(cm.display);
var padding = paddingH(cm.display), leftSide = padding.left, rightSide = display.lineSpace.offsetWidth - padding.right;
function add(left, top, width, bottom) {
if (top < 0) top = 0;
fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left +
"px; top: " + top + "px; width: " + (width == null ? clientWidth - left : width) +
"px; top: " + top + "px; width: " + (width == null ? rightSide - left : width) +
"px; height: " + (bottom - top) + "px"));
}
@ -848,18 +858,18 @@ window.CodeMirror = (function() {
left = leftPos.left;
right = rightPos.right;
}
if (fromArg == null && from == 0) left = pl;
if (fromArg == null && from == 0) left = leftSide;
if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part
add(left, leftPos.top, null, leftPos.bottom);
left = pl;
left = leftSide;
if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top);
}
if (toArg == null && to == lineLen) right = clientWidth;
if (toArg == null && to == lineLen) right = rightSide;
if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)
start = leftPos;
if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)
end = rightPos;
if (left < pl + 1) left = pl;
if (left < leftSide + 1) left = leftSide;
add(left, rightPos.top, right - left, rightPos.bottom);
});
return {start: start, end: end};
@ -875,13 +885,13 @@ window.CodeMirror = (function() {
if (singleVLine) {
if (leftEnd.top < rightStart.top - 2) {
add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);
add(pl, rightStart.top, rightStart.left, rightStart.bottom);
add(leftSide, rightStart.top, rightStart.left, rightStart.bottom);
} else {
add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);
}
}
if (leftEnd.bottom < rightStart.top)
add(pl, leftEnd.bottom, null, rightStart.top);
add(leftSide, leftEnd.bottom, null, rightStart.top);
}
removeChildrenAndAdd(display.selectionDiv, fragment);
@ -984,9 +994,12 @@ window.CodeMirror = (function() {
function paddingTop(display) {return display.lineSpace.offsetTop;}
function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;}
function paddingLeft(display) {
var e = removeChildrenAndAdd(display.measure, elt("pre", null, null, "text-align: left")).appendChild(elt("span", "x"));
return e.offsetLeft;
function paddingH(display) {
if (display.cachedPaddingH) return display.cachedPaddingH;
var e = removeChildrenAndAdd(display.measure, elt("pre", "x"));
var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle;
return display.cachedPaddingH = {left: parseInt(style.paddingLeft),
right: parseInt(style.paddingRight)};
}
function measureChar(cm, line, ch, data, bias) {
@ -1155,12 +1168,17 @@ window.CodeMirror = (function() {
var pre = buildLineContent(cm, line, null, true).pre;
var end = pre.appendChild(zeroWidthElement(cm.display.measure));
removeChildrenAndAdd(cm.display.measure, pre);
return getRect(end).right - getRect(cm.display.lineDiv).left;
var rect = getRect(end);
if (rect.right == 0 && rect.bottom == 0) {
end = pre.appendChild(elt("span", "\u00a0"));
rect = getRect(end);
}
return rect.left - getRect(cm.display.lineDiv).left;
}
function clearCaches(cm) {
cm.display.measureLineCache.length = cm.display.measureLineCachePos = 0;
cm.display.cachedCharWidth = cm.display.cachedTextHeight = null;
cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null;
if (!cm.options.lineWrapping) cm.display.maxLineChanged = true;
cm.display.lineNumChars = null;
}
@ -1376,7 +1394,7 @@ window.CodeMirror = (function() {
if (op.updateMaxLine) computeMaxLength(cm);
if (display.maxLineChanged && !cm.options.lineWrapping && display.maxLine) {
var width = measureLineWidth(cm, display.maxLine);
display.sizer.style.minWidth = Math.max(0, width + 3 + scrollerCutOff) + "px";
display.sizer.style.minWidth = Math.max(0, width + 3) + "px";
display.maxLineChanged = false;
var maxScrollLeft = Math.max(0, display.sizer.offsetLeft + display.sizer.offsetWidth - display.scroller.clientWidth);
if (maxScrollLeft < doc.scrollLeft && !op.updateScrollPos)
@ -1490,10 +1508,6 @@ window.CodeMirror = (function() {
function readInput(cm) {
var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc, sel = doc.sel;
if (!cm.state.focused || hasSelection(input) || isReadOnly(cm) || cm.options.disableInput) return false;
if (cm.state.pasteIncoming && cm.state.fakedLastChar) {
input.value = input.value.substring(0, input.value.length - 1);
cm.state.fakedLastChar = false;
}
var text = input.value;
if (text == prevInput && posEq(sel.from, sel.to)) return false;
if (ie && !ie_lt9 && cm.display.inputHasSelection === text) {
@ -1558,6 +1572,10 @@ window.CodeMirror = (function() {
cm.display.input.focus();
}
function ensureFocus(cm) {
if (!cm.state.focused) { focusInput(cm); onFocus(cm); }
}
function isReadOnly(cm) {
return cm.options.readOnly || cm.doc.cantEdit;
}
@ -1614,7 +1632,7 @@ window.CodeMirror = (function() {
if (resizeTimer == null) resizeTimer = setTimeout(function() {
resizeTimer = null;
// Might be a text scaling operation, clear size caches.
d.cachedCharWidth = d.cachedTextHeight = knownScrollbarWidth = null;
d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = knownScrollbarWidth = null;
clearCaches(cm);
runInOp(cm, bind(regChange, cm));
}, 100);
@ -1630,10 +1648,7 @@ window.CodeMirror = (function() {
}
setTimeout(unregister, 5000);
on(d.input, "keyup", operation(cm, function(e) {
if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
if (e.keyCode == 16) cm.doc.sel.shift = false;
}));
on(d.input, "keyup", operation(cm, onKeyUp));
on(d.input, "input", function() {
if (ie && !ie_lt9 && cm.display.inputHasSelection) cm.display.inputHasSelection = null;
fastPoll(cm);
@ -1659,16 +1674,6 @@ window.CodeMirror = (function() {
fastPoll(cm);
});
on(d.input, "paste", function() {
// Workaround for webkit bug https://bugs.webkit.org/show_bug.cgi?id=90206
// Add a char to the end of textarea before paste occur so that
// selection doesn't span to the end of textarea.
if (webkit && !cm.state.fakedLastChar && !(new Date - cm.state.lastMiddleDown < 200)) {
var start = d.input.selectionStart, end = d.input.selectionEnd;
d.input.value += "$";
d.input.selectionStart = start;
d.input.selectionEnd = end;
cm.state.fakedLastChar = true;
}
cm.state.pasteIncoming = true;
fastPoll(cm);
});
@ -1702,8 +1707,7 @@ window.CodeMirror = (function() {
var display = cm.display;
if (!liberal) {
var target = e_target(e);
if (target == display.scrollbarH || target == display.scrollbarH.firstChild ||
target == display.scrollbarV || target == display.scrollbarV.firstChild ||
if (target == display.scrollbarH || target == display.scrollbarV ||
target == display.scrollbarFiller || target == display.gutterFiller) return null;
}
var x, y, space = getRect(display.lineSpace);
@ -1727,6 +1731,7 @@ window.CodeMirror = (function() {
}
if (clickInGutter(cm, e)) return;
var start = posFromMouse(cm, e);
window.focus();
switch (e_button(e)) {
case 3:
@ -1744,7 +1749,7 @@ window.CodeMirror = (function() {
// selection.
if (!start) {if (e_target(e) == display.scroller) e_preventDefault(e); return;}
if (!cm.state.focused) onFocus(cm);
setTimeout(bind(ensureFocus, cm), 0);
var now = +new Date, type = "single";
if (lastDoubleClick && lastDoubleClick.time > now - 400 && posEq(lastDoubleClick.pos, start)) {
@ -1824,7 +1829,7 @@ window.CodeMirror = (function() {
var cur = posFromMouse(cm, e, true);
if (!cur) return;
if (!posEq(cur, last)) {
if (!cm.state.focused) onFocus(cm);
ensureFocus(cm);
last = cur;
doSelect(cur);
var visible = visibleLines(display, doc);
@ -1849,7 +1854,7 @@ window.CodeMirror = (function() {
}
var move = operation(cm, function(e) {
if (!old_ie && !e_button(e)) done(e);
if ((ie && !ie_lt10) ? !e.buttons : !e_button(e)) done(e);
else extend(e);
});
var up = operation(cm, done);
@ -1994,7 +1999,7 @@ window.CodeMirror = (function() {
// know one. These don't have to be accurate -- the result of them
// being wrong would just be a slight flicker on the first wheel
// scroll (if it is large enough).
if (old_ie) wheelPixelsPerUnit = -.53;
if (ie) wheelPixelsPerUnit = -.53;
else if (gecko) wheelPixelsPerUnit = 15;
else if (chrome) wheelPixelsPerUnit = -.7;
else if (safari) wheelPixelsPerUnit = -1/3;
@ -2143,10 +2148,16 @@ window.CodeMirror = (function() {
return handled;
}
function onKeyUp(e) {
var cm = this;
if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
if (e.keyCode == 16) cm.doc.sel.shift = false;
}
var lastStoppedKey = null;
function onKeyDown(e) {
var cm = this;
if (!cm.state.focused) onFocus(cm);
ensureFocus(cm);
if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
if (old_ie && e.keyCode == 27) e.returnValue = false;
var code = e.keyCode;
@ -2217,8 +2228,9 @@ window.CodeMirror = (function() {
var oldCSS = display.input.style.cssText;
display.inputDiv.style.position = "absolute";
display.input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
"px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: transparent; outline: none;" +
"border-width: 0; outline: none; overflow: hidden; opacity: .05; -ms-opacity: .05; filter: alpha(opacity=5);";
"px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: " +
(ie ? "rgba(255, 255, 255, .05)" : "transparent") +
"; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
focusInput(cm);
resetInput(cm, true);
// Adds "Select all" to context menu in FF
@ -2239,7 +2251,7 @@ window.CodeMirror = (function() {
// Try to detect the user choosing select-all
if (display.input.selectionStart != null) {
if (!old_ie || ie_lt9) prepareSelectAllHack();
if (!ie || ie_lt9) prepareSelectAllHack();
clearTimeout(detectingSelectAll);
var i = 0, poll = function(){
if (display.prevInput == "\u200b" && display.input.selectionStart == 0)
@ -2251,7 +2263,7 @@ window.CodeMirror = (function() {
}
}
if (old_ie && !ie_lt9) prepareSelectAllHack();
if (ie && !ie_lt9) prepareSelectAllHack();
if (captureMiddleClick) {
e_stop(e);
var mouseup = function() {
@ -2748,15 +2760,16 @@ window.CodeMirror = (function() {
// API UTILITIES
function indentLine(cm, n, how, aggressive) {
var doc = cm.doc;
var doc = cm.doc, state;
if (how == null) how = "add";
if (how == "smart") {
if (!cm.doc.mode.indent) how = "prev";
else var state = getStateBefore(cm, n);
else state = getStateBefore(cm, n);
}
var tabSize = cm.options.tabSize;
var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize);
if (line.stateAfter) line.stateAfter = null;
var curSpaceString = line.text.match(/^\s*/)[0], indentation;
if (!aggressive && !/\S/.test(line.text)) {
indentation = 0;
@ -2798,7 +2811,6 @@ window.CodeMirror = (function() {
else no = lineNo(handle);
if (no == null) return null;
if (op(line, no)) regChange(cm, no, no + 1);
else return null;
return line;
}
@ -2831,13 +2843,15 @@ window.CodeMirror = (function() {
if (dir < 0 && !moveOnce(!first)) break;
var cur = lineObj.text.charAt(ch) || "\n";
var type = isWordChar(cur) ? "w"
: !group ? null
: /\s/.test(cur) ? null
: group && cur == "\n" ? "n"
: !group || /\s/.test(cur) ? null
: "p";
if (group && !first && !type) type = "s";
if (sawType && sawType != type) {
if (dir < 0) {dir = 1; moveOnce();}
break;
}
if (type) sawType = type;
if (dir > 0 && !moveOnce(!first)) break;
}
@ -3048,7 +3062,7 @@ window.CodeMirror = (function() {
else if (line > last) { line = last; end = true; }
var lineObj = getLine(this.doc, line);
return intoCoordSystem(this, getLine(this.doc, line), {top: 0, left: 0}, mode || "page").top +
(end ? lineObj.height : 0);
(end ? this.doc.height - heightAtLine(this, lineObj) : 0);
},
defaultTextHeight: function() { return textHeight(this.display); },
@ -3158,6 +3172,8 @@ window.CodeMirror = (function() {
},
triggerOnKeyDown: operation(null, onKeyDown),
triggerOnKeyPress: operation(null, onKeyPress),
triggerOnKeyUp: operation(null, onKeyUp),
execCommand: function(cmd) {
if (commands.hasOwnProperty(cmd))
@ -3224,8 +3240,10 @@ window.CodeMirror = (function() {
this.display.cursor.className += " CodeMirror-overwrite";
else
this.display.cursor.className = this.display.cursor.className.replace(" CodeMirror-overwrite", "");
signal(this, "overwriteToggle", this, this.state.overwrite);
},
hasFocus: function() { return this.state.focused; },
hasFocus: function() { return document.activeElement == this.display.input; },
scrollTo: operation(null, function(x, y) {
updateScrollPos(this, x, y);
@ -3266,16 +3284,19 @@ window.CodeMirror = (function() {
if (this.options.lineWrapping)
this.display.measureLineCache.length = this.display.measureLineCachePos = 0;
this.curOp.forceUpdate = true;
signal(this, "refresh", this);
}),
operation: function(f){return runInOp(this, f);},
refresh: operation(null, function() {
var badHeight = this.display.cachedTextHeight == null;
var oldHeight = this.display.cachedTextHeight;
clearCaches(this);
updateScrollPos(this, this.doc.scrollLeft, this.doc.scrollTop);
regChange(this);
if (badHeight) estimateLineHeights(this);
if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)
estimateLineHeights(this);
signal(this, "refresh", this);
}),
swapDoc: operation(null, function(doc) {
@ -3426,6 +3447,7 @@ window.CodeMirror = (function() {
spec = mimeModes[spec];
} else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
var found = mimeModes[spec.name];
if (typeof found == "string") found = {name: found};
spec = createObj(found, spec);
spec.name = found.name;
} else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
@ -3538,7 +3560,7 @@ window.CodeMirror = (function() {
},
deleteLine: function(cm) {
var l = cm.getCursor().line;
cm.replaceRange("", Pos(l, 0), Pos(l), "+delete");
cm.replaceRange("", Pos(l, 0), Pos(l + 1, 0), "+delete");
},
delLineLeft: function(cm) {
var cur = cm.getCursor();
@ -3596,6 +3618,11 @@ window.CodeMirror = (function() {
insertTab: function(cm) {
cm.replaceSelection("\t", "end", "+input");
},
insertSoftTab: function(cm) {
var pos = cm.getCursor("from"), tabSize = cm.options.tabSize;
var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize);
cm.replaceSelection(new Array(tabSize - col % tabSize + 1).join(" "), "end", "+input");
},
defaultTab: function(cm) {
if (cm.somethingSelected()) cm.indentSelection("add");
else cm.replaceSelection("\t", "end", "+input");
@ -3629,7 +3656,7 @@ window.CodeMirror = (function() {
// default. Unknown commands are simply ignored.
keyMap.pcDefault = {
"Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
"Ctrl-Home": "goDocStart", "Alt-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd",
"Ctrl-Home": "goDocStart", "Ctrl-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd",
"Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
"Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
"Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
@ -3881,7 +3908,9 @@ window.CodeMirror = (function() {
this.doc.cantEdit = false;
if (cm) reCheckSelection(cm);
}
if (cm) signalLater(cm, "markerCleared", cm, this);
if (withOp) endOperation(cm);
if (this.parent) this.parent.clear();
};
TextMarker.prototype.find = function(bothSides) {
@ -3939,7 +3968,7 @@ window.CodeMirror = (function() {
if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);
var marker = new TextMarker(doc, type);
if (options) copyObj(options, marker);
if (options) copyObj(options, marker, false);
if (posLess(to, from) || posEq(from, to) && marker.clearWhenEmpty !== false)
return marker;
if (marker.replacedWith) {
@ -3989,6 +4018,7 @@ window.CodeMirror = (function() {
if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.collapsed)
regChange(cm, from.line, to.line + 1);
if (marker.atomic) reCheckSelection(cm);
signalLater(cm, "markerAdded", cm, marker);
}
return marker;
}
@ -3998,10 +4028,8 @@ window.CodeMirror = (function() {
function SharedTextMarker(markers, primary) {
this.markers = markers;
this.primary = primary;
for (var i = 0, me = this; i < markers.length; ++i) {
for (var i = 0; i < markers.length; ++i)
markers[i].parent = this;
on(markers[i], "clear", function(){me.clear();});
}
}
CodeMirror.SharedTextMarker = SharedTextMarker;
eventMixin(SharedTextMarker);
@ -4032,6 +4060,37 @@ window.CodeMirror = (function() {
return new SharedTextMarker(markers, primary);
}
function findSharedMarkers(doc) {
return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())),
function(m) { return m.parent; });
}
function copySharedMarkers(doc, markers) {
for (var i = 0; i < markers.length; i++) {
var marker = markers[i], pos = marker.find();
var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to);
if (cmp(mFrom, mTo)) {
var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type);
marker.markers.push(subMark);
subMark.parent = marker;
}
}
}
function detachSharedMarkers(markers) {
for (var i = 0; i < markers.length; i++) {
var marker = markers[i], linked = [marker.primary.doc];;
linkedDocs(marker.primary.doc, function(d) { linked.push(d); });
for (var j = 0; j < marker.markers.length; j++) {
var subMarker = marker.markers[j];
if (indexOf(linked, subMarker.doc) == -1) {
subMarker.parent = null;
marker.markers.splice(j--, 1);
}
}
}
}
// TEXTMARKER SPANS
function getMarkedSpanFor(spans, marker) {
@ -4314,6 +4373,7 @@ window.CodeMirror = (function() {
if (!ws.length) this.line.widgets = null;
var aboveVisible = heightAtLine(this.cm, this.line) < this.cm.doc.scrollTop;
updateLineHeight(this.line, Math.max(0, this.line.height - widgetHeight(this)));
this.cm.curOp.forceUpdate = true;
if (aboveVisible) addToScrollPos(this.cm, 0, -this.height);
regChange(this.cm, no, no + 1);
});
@ -4323,6 +4383,7 @@ window.CodeMirror = (function() {
var diff = widgetHeight(this) - oldH;
if (!diff) return;
updateLineHeight(this.line, this.line.height + diff);
this.cm.curOp.forceUpdate = true;
var no = lineNo(this.line);
regChange(this.cm, no, no + 1);
});
@ -4346,6 +4407,7 @@ window.CodeMirror = (function() {
var aboveVisible = heightAtLine(cm, line) < cm.doc.scrollTop;
updateLineHeight(line, line.height + widgetHeight(widget));
if (aboveVisible) addToScrollPos(cm, 0, widget.height);
cm.curOp.forceUpdate = true;
}
return true;
});
@ -4477,7 +4539,7 @@ window.CodeMirror = (function() {
function interpretTokenStyle(style, builder) {
if (!style) return null;
for (;;) {
var lineClass = style.match(/(?:^|\s)line-(background-)?(\S+)/);
var lineClass = style.match(/(?:^|\s+)line-(background-)?(\S+)/);
if (!lineClass) break;
style = style.slice(0, lineClass.index) + style.slice(lineClass.index + lineClass[0].length);
var prop = lineClass[1] ? "bgClass" : "textClass";
@ -4486,9 +4548,10 @@ window.CodeMirror = (function() {
else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(builder[prop]))
builder[prop] += " " + lineClass[2];
}
if (/^\s*$/.test(style)) return null;
var cache = builder.cm.options.addModeClass ? styleToClassCacheWithMode : styleToClassCache;
return cache[style] ||
(cache[style] = "cm-" + style.replace(/ +/g, " cm-"));
(cache[style] = style.replace(/\S+/g, "cm-$&"));
}
function buildLineContent(cm, realLine, measure, copyWidgets) {
@ -4505,7 +4568,7 @@ window.CodeMirror = (function() {
builder.measure = line == realLine && measure;
builder.pos = 0;
builder.addToken = builder.measure ? buildTokenMeasure : buildToken;
if ((old_ie || webkit) && cm.getOption("lineWrapping"))
if ((ie || webkit) && cm.getOption("lineWrapping"))
builder.addToken = buildTokenSplitSpaces(builder.addToken);
var next = insertLineContent(line, builder, getLineStyles(cm, line));
if (measure && line == realLine && !builder.measuredSomething) {
@ -4998,6 +5061,7 @@ window.CodeMirror = (function() {
redo: docOperation(function() {makeChangeFromHistory(this, "redo");}),
setExtending: function(val) {this.sel.extend = val;},
getExtending: function() {return this.sel.extend;},
historySize: function() {
var hist = this.history;
@ -5048,6 +5112,23 @@ window.CodeMirror = (function() {
}
return markers;
},
findMarks: function(from, to, filter) {
from = clipPos(this, from); to = clipPos(this, to);
var found = [], lineNo = from.line;
this.iter(from.line, to.line + 1, function(line) {
var spans = line.markedSpans;
if (spans) for (var i = 0; i < spans.length; i++) {
var span = spans[i];
if (!(lineNo == from.line && from.ch > span.to ||
span.from == null && lineNo != from.line||
lineNo == to.line && span.from > to.ch) &&
(!filter || filter(span.marker)))
found.push(span.marker.parent || span.marker);
}
++lineNo;
});
return found;
},
getAllMarks: function() {
var markers = [];
this.iter(function(line) {
@ -5099,6 +5180,7 @@ window.CodeMirror = (function() {
if (options.sharedHist) copy.history = this.history;
(this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
copySharedMarkers(copy, findSharedMarkers(this));
return copy;
},
unlinkDoc: function(other) {
@ -5108,6 +5190,7 @@ window.CodeMirror = (function() {
if (link.doc != other) continue;
this.linked.splice(i, 1);
other.unlinkDoc(this);
detachSharedMarkers(findSharedMarkers(this));
break;
}
// If the histories were shared, split them again
@ -5321,6 +5404,8 @@ window.CodeMirror = (function() {
hist.lastTime = time;
hist.lastOp = opId;
hist.lastOrigin = change.origin;
if (!last) signal(doc, "historyAdded");
}
function removeClearedSpans(spans) {
@ -5586,9 +5671,11 @@ window.CodeMirror = (function() {
return inst;
}
function copyObj(obj, target) {
function copyObj(obj, target, overwrite) {
if (!target) target = {};
for (var prop in obj) if (obj.hasOwnProperty(prop)) target[prop] = obj[prop];
for (var prop in obj)
if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
target[prop] = obj[prop];
return target;
}
@ -5602,7 +5689,7 @@ window.CodeMirror = (function() {
return function(){return f.apply(null, args);};
}
var nonASCIISingleCaseWordChar = /[\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
var nonASCIISingleCaseWordChar = /[\u00df\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
function isWordChar(ch) {
return /\w/.test(ch) || ch > "\x80" &&
(ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));
@ -6043,7 +6130,7 @@ window.CodeMirror = (function() {
// THE END
CodeMirror.version = "3.21.0";
CodeMirror.version = "3.24.0";
return CodeMirror;
})();

View File

@ -8,6 +8,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
mediaTypes = parserConfig.mediaTypes || {},
mediaFeatures = parserConfig.mediaFeatures || {},
propertyKeywords = parserConfig.propertyKeywords || {},
nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
colorKeywords = parserConfig.colorKeywords || {},
valueKeywords = parserConfig.valueKeywords || {},
fontProperties = parserConfig.fontProperties || {},
@ -83,7 +84,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
function tokenParenthesized(stream, state) {
stream.next(); // Must be '('
if (!stream.match(/\s*[\"\']/, false))
if (!stream.match(/\s*[\"\')]/, false))
state.tokenize = tokenString(")");
else
state.tokenize = null;
@ -162,9 +163,13 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
states.block = function(type, stream, state) {
if (type == "word") {
if (propertyKeywords.hasOwnProperty(stream.current().toLowerCase())) {
var word = stream.current().toLowerCase();
if (propertyKeywords.hasOwnProperty(word)) {
override = "property";
return "maybeprop";
} else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
override = "string-2";
return "maybeprop";
} else if (allowNested) {
override = stream.match(/^\s*:/, false) ? "property" : "tag";
return "block";
@ -437,19 +442,27 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"vertical-align", "visibility", "voice-balance", "voice-duration",
"voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
"voice-volume", "volume", "white-space", "widows", "width", "word-break",
"word-spacing", "word-wrap", "z-index", "zoom",
"word-spacing", "word-wrap", "z-index",
// SVG-specific
"clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
"flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
"color-interpolation", "color-interpolation-filters", "color-profile",
"color-interpolation", "color-interpolation-filters",
"color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
"marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
"stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
"stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
"baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
"glyph-orientation-vertical", "kerning", "text-anchor", "writing-mode"
"glyph-orientation-vertical", "text-anchor", "writing-mode"
], propertyKeywords = keySet(propertyKeywords_);
var nonStandardPropertyKeywords = [
"scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
"scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
"scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
"searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
"searchfield-results-decoration", "zoom"
], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords);
var colorKeywords_ = [
"aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
"bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
@ -569,7 +582,8 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
"font-stretch", "font-weight", "font-style"
], fontProperties = keySet(fontProperties_);
var allWords = mediaTypes_.concat(mediaFeatures_).concat(propertyKeywords_).concat(colorKeywords_).concat(valueKeywords_);
var allWords = mediaTypes_.concat(mediaFeatures_).concat(propertyKeywords_)
.concat(nonStandardPropertyKeywords).concat(colorKeywords_).concat(valueKeywords_);
CodeMirror.registerHelper("hintWords", "css", allWords);
function tokenCComment(stream, state) {
@ -598,6 +612,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
mediaTypes: mediaTypes,
mediaFeatures: mediaFeatures,
propertyKeywords: propertyKeywords,
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
fontProperties: fontProperties,
@ -620,6 +635,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
mediaTypes: mediaTypes,
mediaFeatures: mediaFeatures,
propertyKeywords: propertyKeywords,
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
fontProperties: fontProperties,
@ -660,6 +676,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
mediaTypes: mediaTypes,
mediaFeatures: mediaFeatures,
propertyKeywords: propertyKeywords,
nonStandardPropertyKeywords: nonStandardPropertyKeywords,
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
fontProperties: fontProperties,

View File

@ -46,7 +46,7 @@
pick: function(data, i) {
var completion = data.list[i];
if (completion.hint) completion.hint(this.cm, data, completion);
else this.cm.replaceRange(getText(completion), data.from, data.to);
else this.cm.replaceRange(getText(completion), completion.from||data.from, completion.to||data.to);
CodeMirror.signal(data, "pick", completion);
this.close();
},
@ -93,6 +93,7 @@
data = data_;
if (finished) return;
if (!data || !data.list.length) return done();
if (completion.widget) completion.widget.close();
completion.widget = new Widget(completion, data);
}
@ -193,8 +194,24 @@
var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
(options.container || document.body).appendChild(hints);
var box = hints.getBoundingClientRect();
var overlapX = box.right - winW, overlapY = box.bottom - winH;
var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
if (overlapY > 0) {
var height = box.bottom - box.top, curTop = box.top - (pos.bottom - pos.top);
if (curTop - height > 0) { // Fits above cursor
hints.style.top = (top = curTop - height) + "px";
below = false;
} else if (height > winH) {
hints.style.height = (winH - 5) + "px";
hints.style.top = (top = pos.bottom - box.top) + "px";
var cursor = cm.getCursor();
if (data.from.ch != cursor.ch) {
pos = cm.cursorCoords(cursor);
hints.style.left = (left = pos.left) + "px";
box = hints.getBoundingClientRect();
}
}
}
var overlapX = box.left - winW;
if (overlapX > 0) {
if (box.right - box.left > winW) {
hints.style.width = (winW - 5) + "px";
@ -202,17 +219,6 @@
}
hints.style.left = (left = pos.left - overlapX) + "px";
}
if (overlapY > 0) {
var height = box.bottom - box.top;
if (box.top - (pos.bottom - pos.top) - height > 0) {
overlapY = height + (pos.bottom - pos.top);
below = false;
} else if (height > winH) {
hints.style.height = (winH - 5) + "px";
overlapY -= height - winH;
}
hints.style.top = (top = pos.bottom - overlapY) + "px";
}
cm.addKeyMap(this.keyMap = buildKeyMap(options, {
moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
@ -220,7 +226,8 @@
menuSize: function() { return widget.screenAmount(); },
length: completions.length,
close: function() { completion.close(); },
pick: function() { widget.pick(); }
pick: function() { widget.pick(); },
data: data
}));
if (options.closeOnUnfocus !== false) {
@ -303,15 +310,16 @@
};
CodeMirror.registerHelper("hint", "auto", function(cm, options) {
var helpers = cm.getHelpers(cm.getCursor(), "hint");
var helpers = cm.getHelpers(cm.getCursor(), "hint"), words;
if (helpers.length) {
for (var i = 0; i < helpers.length; i++) {
var cur = helpers[i](cm, options);
if (cur && cur.list.length) return cur;
}
} else {
var words = cm.getHelper(cm.getCursor(), "hintWords");
} else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
if (words) return CodeMirror.hint.fromList(cm, {words: words});
} else if (CodeMirror.hint.anyword) {
return CodeMirror.hint.anyword(cm, options);
}
});

View File

@ -1,7 +1,8 @@
CodeMirror.defineMode("xml", function(config, parserConfig) {
var indentUnit = config.indentUnit;
var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1;
var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag || true;
var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag;
if (multilineTagIndentPastTag == null) multilineTagIndentPastTag = true;
var Kludges = parserConfig.htmlMode ? {
autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
@ -33,19 +34,21 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
},
doNotIndent: {"pre": true},
allowUnquoted: true,
allowMissing: true
allowMissing: true,
caseFold: true
} : {
autoSelfClosers: {},
implicitlyClosed: {},
contextGrabbers: {},
doNotIndent: {},
allowUnquoted: false,
allowMissing: false
allowMissing: false,
caseFold: false
};
var alignCDATA = parserConfig.alignCDATA;
// Return variables for tokenizers
var tagName, type, setStyle;
var type, setStyle;
function inText(stream, state) {
function chain(parser) {
@ -72,14 +75,9 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
state.tokenize = inBlock("meta", "?>");
return "meta";
} else {
var isClose = stream.eat("/");
tagName = "";
var c;
while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
if (!tagName) return "tag error";
type = isClose ? "closeTag" : "openTag";
type = stream.eat("/") ? "closeTag" : "openTag";
state.tokenize = inTag;
return "tag";
return "tag bracket";
}
} else if (ch == "&") {
var ok;
@ -104,7 +102,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
if (ch == ">" || (ch == "/" && stream.eat(">"))) {
state.tokenize = inText;
type = ch == ">" ? "endTag" : "selfcloseTag";
return "tag";
return "tag bracket";
} else if (ch == "=") {
type = "equals";
return null;
@ -119,7 +117,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
state.stringStartCol = stream.column();
return state.tokenize(stream, state);
} else {
stream.eatWhile(/[^\s\u00a0=<>\"\']/);
stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/);
return "word";
}
}
@ -188,7 +186,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
if (!state.context) {
return;
}
parentTagName = state.context.tagName.toLowerCase();
parentTagName = state.context.tagName;
if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
!Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
return;
@ -199,26 +197,42 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
function baseState(type, stream, state) {
if (type == "openTag") {
state.tagName = tagName;
state.tagStart = stream.column();
return attrState;
return tagNameState;
} else if (type == "closeTag") {
var err = false;
if (state.context) {
if (state.context.tagName != tagName) {
if (Kludges.implicitlyClosed.hasOwnProperty(state.context.tagName.toLowerCase()))
popContext(state);
err = !state.context || state.context.tagName != tagName;
}
} else {
err = true;
}
if (err) setStyle = "error";
return err ? closeStateErr : closeState;
return closeTagNameState;
} else {
return baseState;
}
}
function tagNameState(type, stream, state) {
if (type == "word") {
state.tagName = stream.current();
setStyle = "tag";
return attrState;
} else {
setStyle = "error";
return tagNameState;
}
}
function closeTagNameState(type, stream, state) {
if (type == "word") {
var tagName = stream.current();
if (state.context && state.context.tagName != tagName &&
Kludges.implicitlyClosed.hasOwnProperty(state.context.tagName))
popContext(state);
if (state.context && state.context.tagName == tagName) {
setStyle = "tag";
return closeState;
} else {
setStyle = "tag error";
return closeStateErr;
}
} else {
setStyle = "error";
return closeStateErr;
}
}
function closeState(type, _stream, state) {
if (type != "endTag") {
setStyle = "error";
@ -240,10 +254,10 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
var tagName = state.tagName, tagStart = state.tagStart;
state.tagName = state.tagStart = null;
if (type == "selfcloseTag" ||
Kludges.autoSelfClosers.hasOwnProperty(tagName.toLowerCase())) {
maybePopContext(state, tagName.toLowerCase());
Kludges.autoSelfClosers.hasOwnProperty(tagName)) {
maybePopContext(state, tagName);
} else {
maybePopContext(state, tagName.toLowerCase());
maybePopContext(state, tagName);
state.context = new Context(state, tagName, tagStart == state.indented);
}
return baseState;
@ -281,7 +295,7 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
state.indented = stream.indentation();
if (stream.eatSpace()) return null;
tagName = type = null;
type = null;
var style = state.tokenize(stream, state);
if ((style || type) && style != "comment") {
setStyle = null;
@ -296,7 +310,10 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
var context = state.context;
// Indent multi-line strings (e.g. css).
if (state.tokenize.isInAttribute) {
return state.stringStartCol + 1;
if (state.tagStart == state.indented)
return state.stringStartCol + 1;
else
return state.indented + indentUnit;
}
if (context && context.noIndent) return CodeMirror.Pass;
if (state.tokenize != inTag && state.tokenize != inText)
@ -309,8 +326,27 @@ CodeMirror.defineMode("xml", function(config, parserConfig) {
return state.tagStart + indentUnit * multilineTagIndentFactor;
}
if (alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
if (context && /^<\//.test(textAfter))
context = context.prev;
var tagAfter = textAfter && /^<(\/)?(\w*)/.exec(textAfter);
if (tagAfter && tagAfter[1]) { // Closing tag spotted
while (context) {
if (context.tagName == tagAfter[2]) {
context = context.prev;
break;
} else if (Kludges.implicitlyClosed.hasOwnProperty(context.tagName)) {
context = context.prev;
} else {
break;
}
}
} else if (tagAfter) { // Opening tag spotted
while (context) {
var grabbers = Kludges.contextGrabbers[context.tagName];
if (grabbers && grabbers.hasOwnProperty(tagAfter[2]))
context = context.prev;
else
break;
}
}
while (context && !context.startOfLine)
context = context.prev;
if (context) return context.indent + indentUnit;