# HG changeset patch # User Marcin Kuzminski # Date 1354052908 -3600 # Node ID 31f98c85062333fd37e763095ba9f73e7a2451db # Parent fb1709520112a418db67f23fa519ca6a339ec8f3 updated codemirror version diff -r fb1709520112 -r 31f98c850623 rhodecode/public/css/codemirror.css --- a/rhodecode/public/css/codemirror.css Tue Nov 27 22:20:31 2012 +0100 +++ b/rhodecode/public/css/codemirror.css Tue Nov 27 22:48:28 2012 +0100 @@ -80,6 +80,7 @@ word-wrap: normal; line-height: inherit; color: inherit; + overflow: visible; } .CodeMirror-wrap pre { diff -r fb1709520112 -r 31f98c850623 rhodecode/public/js/codemirror.js --- a/rhodecode/public/js/codemirror.js Tue Nov 27 22:20:31 2012 +0100 +++ b/rhodecode/public/js/codemirror.js Tue Nov 27 22:48:28 2012 +0100 @@ -75,7 +75,7 @@ // Selection-related flags. shiftSelecting obviously tracks // whether the user is holding shift. var shiftSelecting, lastClick, lastDoubleClick, lastScrollTop = 0, draggingText, - overwrite = false, suppressEdits = false; + overwrite = false, suppressEdits = false, pasteIncoming = false; // Variables used by startOperation/endOperation to track what // happened during the operation. var updateInput, userSelChange, changes, textChanged, selectionChanged, @@ -128,7 +128,7 @@ connect(scroller, "drop", operation(onDrop)); } connect(scroller, "paste", function(){focusInput(); fastPoll();}); - connect(input, "paste", fastPoll); + connect(input, "paste", function(){pasteIncoming = true; fastPoll();}); connect(input, "cut", operation(function(){ if (!options.readOnly) replaceSelection(""); })); @@ -167,6 +167,7 @@ else if (option == "lineWrapping" && oldVal != value) operation(wrappingChanged)(); else if (option == "tabSize") updateDisplay(true); else if (option == "keyMap") keyMapChanged(); + else if (option == "tabindex") input.tabIndex = value; if (option == "lineNumbers" || option == "gutter" || option == "firstLineNumber" || option == "theme" || option == "lineNumberFormatter") { gutterChanged(); @@ -229,6 +230,7 @@ var off = eltOffset(lineSpace); return coordsChar(coords.x - off.left, coords.y - off.top); }, + defaultTextHeight: function() { return textHeight(); }, markText: operation(markText), setBookmark: setBookmark, findMarksAt: findMarksAt, @@ -343,6 +345,11 @@ return {x: scroller.scrollLeft, y: scrollbar.scrollTop, height: scrollbar.scrollHeight, width: scroller.scrollWidth}; }, + scrollIntoView: function(pos) { + var coords = localCoords(pos ? clipPos(pos) : sel.inverted ? sel.from : sel.to); + scrollIntoView(coords.x, coords.y, coords.x, coords.yBot); + }, + setSize: function(width, height) { function interpret(val) { val = String(val); @@ -392,7 +399,7 @@ } function onScrollBar(e) { - if (scrollbar.scrollTop != lastScrollTop) { + if (Math.abs(scrollbar.scrollTop - lastScrollTop) > 1) { lastScrollTop = scroller.scrollTop = scrollbar.scrollTop; updateDisplay([]); } @@ -401,7 +408,7 @@ function onScrollMain(e) { if (options.fixedGutter && gutter.style.left != scroller.scrollLeft + "px") gutter.style.left = scroller.scrollLeft + "px"; - if (scroller.scrollTop != lastScrollTop) { + if (Math.abs(scroller.scrollTop - lastScrollTop) > 1) { lastScrollTop = scroller.scrollTop; if (scrollbar.scrollTop != lastScrollTop) scrollbar.scrollTop = lastScrollTop; @@ -634,7 +641,7 @@ if (handled) { e_preventDefault(e); restartBlink(); - if (ie) { e.oldKeyCode = e.keyCode; e.keyCode = 0; } + if (ie_lt9) { e.oldKeyCode = e.keyCode; e.keyCode = 0; } } return handled; } @@ -954,12 +961,13 @@ while (same < l && prevInput[same] == text[same]) ++same; if (same < prevInput.length) sel.from = {line: sel.from.line, ch: sel.from.ch - (prevInput.length - same)}; - else if (overwrite && posEq(sel.from, sel.to)) + else if (overwrite && posEq(sel.from, sel.to) && !pasteIncoming) sel.to = {line: sel.to.line, ch: Math.min(getLine(sel.to.line).text.length, sel.to.ch + (text.length - same))}; replaceSelection(text.slice(same), "end"); if (text.length > 1000) { input.value = prevInput = ""; } else prevInput = text; if (!nestedOperation) endOperation(); + pasteIncoming = false; return true; } function resetInput(user) { @@ -1416,7 +1424,7 @@ var startChar = line.charAt(start); var check = isWordChar(startChar) ? isWordChar : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);} : - function(ch) {return !/\s/.test(ch) && !isWordChar(ch);}; + function(ch) {return !/\s/.test(ch) && isWordChar(ch);}; while (start > 0 && check(line.charAt(start - 1))) --start; while (end < line.length && check(line.charAt(end))) ++end; } @@ -1460,6 +1468,7 @@ if (indentString != curSpaceString) replaceRange(indentString, {line: n, ch: 0}, {line: n, ch: curSpaceString.length}); + line.stateAfter = null; } function loadMode() { @@ -1505,18 +1514,17 @@ function TextMarker(type, style) { this.lines = []; this.type = type; if (style) this.style = style; } TextMarker.prototype.clear = operation(function() { - var min = Infinity, max = -Infinity; + var min, max; for (var i = 0; i < this.lines.length; ++i) { var line = this.lines[i]; - var span = getMarkedSpanFor(line.markedSpans, this, true); - if (span.from != null || span.to != null) { - var lineN = lineNo(line); - min = Math.min(min, lineN); max = Math.max(max, lineN); - } + var span = getMarkedSpanFor(line.markedSpans, this); + if (span.from != null) min = lineNo(line); + if (span.to != null) max = lineNo(line); + line.markedSpans = removeMarkedSpan(line.markedSpans, span); } - if (min != Infinity) - changes.push({from: min, to: max + 1}); + if (min != null) changes.push({from: min, to: max + 1}); this.lines.length = 0; + this.explicitlyCleared = true; }); TextMarker.prototype.find = function() { var from, to; @@ -1543,7 +1551,7 @@ var span = {from: curLine == from.line ? from.ch : null, to: curLine == to.line ? to.ch : null, marker: marker}; - (line.markedSpans || (line.markedSpans = [])).push(span); + line.markedSpans = (line.markedSpans || []).concat([span]); marker.lines.push(line); ++curLine; }); @@ -1554,8 +1562,9 @@ function setBookmark(pos) { pos = clipPos(pos); var marker = new TextMarker("bookmark"), line = getLine(pos.line); + history.addChange(pos.line, 1, [newHL(line.text, line.markedSpans)], true); var span = {from: pos.ch, to: pos.ch, marker: marker}; - (line.markedSpans || (line.markedSpans = [])).push(span); + line.markedSpans = (line.markedSpans || []).concat([span]); marker.lines.push(line); return marker; } @@ -1644,8 +1653,6 @@ function measureLine(line, ch) { if (ch == 0) return {top: 0, left: 0}; - var wbr = options.lineWrapping && ch < line.text.length && - spanAffectsWrapping.test(line.text.slice(ch - 1, ch + 1)); var pre = lineContent(line, ch); removeChildrenAndAdd(measure, pre); var anchor = pre.anchor; @@ -1978,6 +1985,7 @@ if (extensions.propertyIsEnumerable(ext) && !instance.propertyIsEnumerable(ext)) instance[ext] = extensions[ext]; + for (var i = 0; i < initHooks.length; ++i) initHooks[i](instance); return instance; } // (end of function CodeMirror) @@ -2075,6 +2083,9 @@ extensions[name] = func; }; + var initHooks = []; + CodeMirror.defineInitHook = function(f) {initHooks.push(f);}; + var modeExtensions = CodeMirror.modeExtensions = {}; CodeMirror.extendMode = function(mode, properties) { var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); @@ -2167,7 +2178,7 @@ keyMap.emacsy = { "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown", "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd", - "Ctrl-V": "goPageUp", "Shift-Ctrl-V": "goPageDown", "Ctrl-D": "delCharRight", "Ctrl-H": "delCharLeft", + "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharRight", "Ctrl-H": "delCharLeft", "Alt-D": "delWordRight", "Alt-Backspace": "delWordLeft", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars" }; @@ -2204,6 +2215,7 @@ var name = keyNames[e_prop(event, "keyCode")]; return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod"; } + CodeMirror.isModifierKey = isModifierKey; CodeMirror.fromTextArea = function(textarea, options) { if (!options) options = {}; @@ -2224,15 +2236,13 @@ if (textarea.form) { // Deplorable hack to make the submit method do the right thing. var rmSubmit = connect(textarea.form, "submit", save, true); - if (typeof textarea.form.submit == "function") { - var realSubmit = textarea.form.submit; - textarea.form.submit = function wrappedSubmit() { - save(); - textarea.form.submit = realSubmit; - textarea.form.submit(); - textarea.form.submit = wrappedSubmit; - }; - } + var realSubmit = textarea.form.submit; + textarea.form.submit = function wrappedSubmit() { + save(); + textarea.form.submit = realSubmit; + textarea.form.submit(); + textarea.form.submit = wrappedSubmit; + }; } textarea.style.display = "none"; @@ -2353,16 +2363,20 @@ this.from = from; this.to = to; this.marker = marker; } - function getMarkedSpanFor(spans, marker, del) { + function getMarkedSpanFor(spans, marker) { if (spans) for (var i = 0; i < spans.length; ++i) { var span = spans[i]; - if (span.marker == marker) { - if (del) spans.splice(i, 1); - return span; - } + if (span.marker == marker) return span; } } + function removeMarkedSpan(spans, span) { + var r; + for (var i = 0; i < spans.length; ++i) + if (spans[i] != span) (r || (r = [])).push(spans[i]); + return r; + } + function markedSpansBefore(old, startCh, endCh) { if (old) for (var i = 0, nw; i < old.length; ++i) { var span = old[i], marker = span.marker; @@ -2446,7 +2460,15 @@ // hl stands for history-line, a data structure that can be either a // string (line without markers) or a {text, markedSpans} object. function hlText(val) { return typeof val == "string" ? val : val.text; } - function hlSpans(val) { return typeof val == "string" ? null : val.markedSpans; } + function hlSpans(val) { + if (typeof val == "string") return null; + var spans = val.markedSpans, out = null; + for (var i = 0; i < spans.length; ++i) { + if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); } + else if (out) out.push(spans[i]); + } + return !out ? spans : out.length ? out : null; + } function newHL(text, spans) { return spans ? {text: text, markedSpans: spans} : text; } function detachMarkedSpans(line) { @@ -2582,13 +2604,17 @@ span = function(html, text, style) { var l = text.length; if (wrapAt >= outPos && wrapAt < outPos + l) { - if (wrapAt > outPos) { - span_(html, text.slice(0, wrapAt - outPos), style); + var cut = wrapAt - outPos; + if (cut) { + span_(html, text.slice(0, cut), style); // See comment at the definition of spanAffectsWrapping - if (compensateForWrapping) html.appendChild(elt("wbr")); + if (compensateForWrapping) { + var view = text.slice(cut - 1, cut + 1); + if (spanAffectsWrapping.test(view)) html.appendChild(elt("wbr")); + else if (!ie_lt8 && /\w\w/.test(view)) html.appendChild(document.createTextNode("\u200d")); + } } html.appendChild(anchor); - var cut = wrapAt - outPos; span_(anchor, opera ? text.slice(cut, cut + 1) : text.slice(cut), style); if (opera) span_(html, text.slice(cut + 1), style); wrapAt--; @@ -2872,7 +2898,7 @@ var time = +new Date, cur = lst(this.done), last = cur && lst(cur); var dtime = time - this.time; - if (this.compound && cur && !this.closed) { + if (cur && !this.closed && this.compound) { cur.push({start: start, added: added, old: old}); } else if (dtime > 400 || !last || this.closed || last.start > start + old.length || last.start + last.added < start) { @@ -3078,8 +3104,10 @@ if (collection[i] == elt) return i; return -1; } + var nonASCIISingleCaseWordChar = /[\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc]/; function isWordChar(ch) { - return /\w/.test(ch) || ch.toUpperCase() != ch.toLowerCase(); + return /\w/.test(ch) || ch > "\x80" && + (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)); } // See if "".split is the broken IE version, if so, provide an @@ -3135,7 +3163,7 @@ for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i; })(); - CodeMirror.version = "2.34"; + CodeMirror.version = "2.36"; return CodeMirror; })();