diff --git a/IPython/frontend/html/notebook/static/codemirror-2.12/LICENSE b/IPython/frontend/html/notebook/static/codemirror/LICENSE
similarity index 100%
rename from IPython/frontend/html/notebook/static/codemirror-2.12/LICENSE
rename to IPython/frontend/html/notebook/static/codemirror/LICENSE
diff --git a/IPython/frontend/html/notebook/static/codemirror/README-IPython.rst b/IPython/frontend/html/notebook/static/codemirror/README-IPython.rst
new file mode 100644
index 0000000..aea3d76
--- /dev/null
+++ b/IPython/frontend/html/notebook/static/codemirror/README-IPython.rst
@@ -0,0 +1,33 @@
+=======================
+ CodeMirror in IPython
+=======================
+
+We carry a mostly unmodified copy of CodeMirror. The current version we use
+is (*please update this information when updating versions*)::
+
+ CodeMirror 2.15
+
+The only changes we've applied so far are these::
+
+ diff --git a/IPython/frontend/html/notebook/static/codemirror/mode/python/python.js b/IPython/frontend/html/notebook/static/codemirror/mode/python/python.js
+ index ca94e7a..fc9a503 100644
+ --- a/IPython/frontend/html/notebook/static/codemirror/mode/python/python.js
+ +++ b/IPython/frontend/html/notebook/static/codemirror/mode/python/python.js
+ @@ -5,7 +5,11 @@ CodeMirror.defineMode("python", function(conf, parserConf) {
+ return new RegExp("^((" + words.join(")|(") + "))\\b");
+ }
+
+ - var singleOperators = new RegExp("^[\\+\\-\\*/%&|\\^~<>!]");
+ + // IPython-specific changes: add '?' as recognized character.
+ + //var singleOperators = new RegExp("^[\\+\\-\\*/%&|\\^~<>!]");
+ + var singleOperators = new RegExp("^[\\+\\-\\*/%&|\\^~<>!\\?]");
+ + // End IPython changes.
+ +
+ var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\}@,:`=;\\.]');
+ var doubleOperators = new RegExp("^((==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//)|(\\*\\*))");
+ var doubleDelimiters = new RegExp("^((\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))");
+
+
+In practice it's just a one-line change, adding `\\?` to singleOperators,
+surrounded by a comment. We'll turn this into a proper patchset if it ever
+gets more complicated than this, but for now this note should be enough.
diff --git a/IPython/frontend/html/notebook/static/codemirror-2.12/README.md b/IPython/frontend/html/notebook/static/codemirror/README.md
similarity index 100%
rename from IPython/frontend/html/notebook/static/codemirror-2.12/README.md
rename to IPython/frontend/html/notebook/static/codemirror/README.md
diff --git a/IPython/frontend/html/notebook/static/codemirror-2.12/lib/codemirror.css b/IPython/frontend/html/notebook/static/codemirror/lib/codemirror.css
similarity index 99%
rename from IPython/frontend/html/notebook/static/codemirror-2.12/lib/codemirror.css
rename to IPython/frontend/html/notebook/static/codemirror/lib/codemirror.css
index d93e72d..aea1574 100644
--- a/IPython/frontend/html/notebook/static/codemirror-2.12/lib/codemirror.css
+++ b/IPython/frontend/html/notebook/static/codemirror/lib/codemirror.css
@@ -13,6 +13,7 @@
.CodeMirror-gutter {
position: absolute; left: 0; top: 0;
+ z-index: 10;
background-color: #f7f7f7;
border-right: 1px solid #eee;
min-width: 2em;
diff --git a/IPython/frontend/html/notebook/static/codemirror-2.12/lib/codemirror.js b/IPython/frontend/html/notebook/static/codemirror/lib/codemirror.js
similarity index 84%
rename from IPython/frontend/html/notebook/static/codemirror-2.12/lib/codemirror.js
rename to IPython/frontend/html/notebook/static/codemirror/lib/codemirror.js
index 27bec72..2e4531f 100644
--- a/IPython/frontend/html/notebook/static/codemirror-2.12/lib/codemirror.js
+++ b/IPython/frontend/html/notebook/static/codemirror/lib/codemirror.js
@@ -20,14 +20,15 @@ var CodeMirror = (function() {
// This mess creates the base DOM structure for the editor.
wrapper.innerHTML =
'
' + // Wraps and hides input textarea
- '
' +
+ '' +
'
' +
'
' + // Set to the height of the text, causes scrolling
'' +
'
' + // Moved around its parent to cover visible view
'
' +
// Provides positioning relative to (visible) text origin
- '
' +
+ '
' +
'
' + // Absolutely positioned blinky cursor
'' + // This DIV contains the actual code
'
';
@@ -59,10 +60,10 @@ var CodeMirror = (function() {
// whether the user is holding shift. reducedSelection is a hack
// to get around the fact that we can't create inverted
// selections. See below.
- var shiftSelecting, reducedSelection, lastDoubleClick;
+ var shiftSelecting, reducedSelection, lastClick, lastDoubleClick;
// Variables used by startOperation/endOperation to track what
// happened during the operation.
- var updateInput, changes, textChanged, selectionChanged, leaveInputAlone;
+ var updateInput, changes, textChanged, selectionChanged, leaveInputAlone, gutterDirty;
// Current visible range (may be bigger than the view window).
var showingFrom = 0, showingTo = 0, lastHeight = 0, curKeyId = null;
// editing will hold an object describing the things we put in the
@@ -79,12 +80,16 @@ var CodeMirror = (function() {
// Register our event handlers.
connect(scroller, "mousedown", operation(onMouseDown));
+ connect(lineSpace, "dragstart", onDragStart);
// Gecko browsers fire contextmenu *after* opening the menu, at
// which point we can't mess with it anymore. Context menu is
// handled in onMouseDown for Gecko.
if (!gecko) connect(scroller, "contextmenu", onContextMenu);
- connect(code, "dblclick", operation(onDblClick));
- connect(scroller, "scroll", function() {updateDisplay([]); if (options.onScroll) options.onScroll(instance);});
+ connect(scroller, "scroll", function() {
+ updateDisplay([]);
+ if (options.fixedGutter) gutter.style.left = scroller.scrollLeft + "px";
+ if (options.onScroll) options.onScroll(instance);
+ });
connect(window, "resize", function() {updateDisplay(true);});
connect(input, "keyup", operation(onKeyUp));
connect(input, "keydown", operation(onKeyDown));
@@ -98,8 +103,8 @@ var CodeMirror = (function() {
connect(scroller, "paste", function(){focusInput(); fastPoll();});
connect(input, "paste", function(){fastPoll();});
connect(input, "cut", function(){fastPoll();});
-
- // IE throws unspecified error in certain cases, when
+
+ // IE throws unspecified error in certain cases, when
// trying to access activeElement before onload
var hasFocus; try { hasFocus = (targetDocument.activeElement == input); } catch(e) { }
if (hasFocus) setTimeout(onFocus, 20);
@@ -111,7 +116,7 @@ var CodeMirror = (function() {
// range checking and/or clipping. operation is used to wrap the
// call so that changes it makes are tracked, and the display is
// updated afterwards.
- var instance = {
+ var instance = wrapper.CodeMirror = {
getValue: getValue,
setValue: operation(setValue),
getSelection: getSelection,
@@ -119,7 +124,8 @@ var CodeMirror = (function() {
focus: function(){focusInput(); onFocus(); fastPoll();},
setOption: function(option, value) {
options[option] = value;
- if (option == "lineNumbers" || option == "gutter") gutterChanged();
+ if (option == "lineNumbers" || option == "gutter" || option == "firstLineNumber")
+ operation(gutterChanged)();
else if (option == "mode" || option == "indentUnit") loadMode();
else if (option == "readOnly" && value == "nocursor") input.blur();
else if (option == "theme") scroller.className = scroller.className.replace(/cm-s-\w+/, "cm-s-" + value);
@@ -127,7 +133,9 @@ var CodeMirror = (function() {
getOption: function(option) {return options[option];},
undo: operation(undo),
redo: operation(redo),
- indentLine: operation(function(n) {if (isLine(n)) indentLine(n, "smart");}),
+ indentLine: operation(function(n, dir) {
+ if (isLine(n)) indentLine(n, dir == null ? "smart" : dir ? "add" : "subtract");
+ }),
historySize: function() {return {undo: history.done.length, redo: history.undone.length};},
matchBrackets: operation(function(){matchBrackets(true);}),
getTokenAt: function(pos) {
@@ -150,18 +158,17 @@ var CodeMirror = (function() {
},
getSearchCursor: function(query, pos, caseFold) {return new SearchCursor(query, pos, caseFold);},
markText: operation(function(a, b, c){return operation(markText(a, b, c));}),
- setMarker: addGutterMarker,
- clearMarker: removeGutterMarker,
+ setMarker: operation(addGutterMarker),
+ clearMarker: operation(removeGutterMarker),
setLineClass: operation(setLineClass),
lineInfo: lineInfo,
- addWidget: function(pos, node, scroll, where) {
+ addWidget: function(pos, node, scroll, vert, horiz) {
pos = localCoords(clipPos(pos));
var top = pos.yBot, left = pos.x;
node.style.position = "absolute";
code.appendChild(node);
- node.style.left = left + "px";
- if (where == "over") top = pos.y;
- else if (where == "near") {
+ if (vert == "over") top = pos.y;
+ else if (vert == "near") {
var vspace = Math.max(scroller.offsetHeight, lines.length * lineHeight()),
hspace = Math.max(code.clientWidth, lineSpace.clientWidth) - paddingLeft();
if (pos.yBot + node.offsetHeight > vspace && pos.y > node.offsetHeight)
@@ -170,7 +177,15 @@ var CodeMirror = (function() {
left = hspace - node.offsetWidth;
}
node.style.top = (top + paddingTop()) + "px";
- node.style.left = (left + paddingLeft()) + "px";
+ node.style.left = node.style.right = "";
+ if (horiz == "right") {
+ left = code.clientWidth - node.offsetWidth;
+ node.style.right = "0px";
+ } else {
+ if (horiz == "left") left = 0;
+ else if (horiz == "middle") left = (code.clientWidth - node.offsetWidth) / 2;
+ node.style.left = (left + paddingLeft()) + "px";
+ }
if (scroll)
scrollIntoView(left, top, left + node.offsetWidth, top + node.offsetHeight);
},
@@ -200,7 +215,8 @@ var CodeMirror = (function() {
refresh: function(){updateDisplay(true);},
getInputField: function(){return input;},
getWrapperElement: function(){return wrapper;},
- getScrollerElement: function(){return scroller;}
+ getScrollerElement: function(){return scroller;},
+ getGutterElement: function(){return gutter;}
};
function setValue(code) {
@@ -209,6 +225,7 @@ var CodeMirror = (function() {
updateLines(top, {line: lines.length - 1, ch: lines[lines.length-1].text.length},
splitLines(code), top, top);
history = new History();
+ updateInput = true;
}
function getValue(code) {
var text = [];
@@ -221,17 +238,17 @@ var CodeMirror = (function() {
// Check whether this is a click in a widget
for (var n = e_target(e); n != wrapper; n = n.parentNode)
if (n.parentNode == code && n != mover) return;
- var ld = lastDoubleClick; lastDoubleClick = null;
+
// First, see if this is a click in the gutter
for (var n = e_target(e); n != wrapper; n = n.parentNode)
if (n.parentNode == gutterText) {
if (options.onGutterClick)
- options.onGutterClick(instance, indexOf(gutterText.childNodes, n) + showingFrom);
+ options.onGutterClick(instance, indexOf(gutterText.childNodes, n) + showingFrom, e);
return e_preventDefault(e);
}
var start = posFromMouse(e);
-
+
switch (e_button(e)) {
case 3:
if (gecko && !mac) onContextMenu(e);
@@ -246,18 +263,26 @@ var CodeMirror = (function() {
if (!start) {if (e_target(e) == scroller) e_preventDefault(e); return;}
if (!focused) onFocus();
- e_preventDefault(e);
- if (ld && +new Date - ld < 400) return selectLine(start.line);
- setCursor(start.line, start.ch, true);
+ var now = +new Date;
+ if (lastDoubleClick > now - 400) {
+ e_preventDefault(e);
+ return selectLine(start.line);
+ } else if (lastClick > now - 400) {
+ lastDoubleClick = now;
+ e_preventDefault(e);
+ return selectWordAt(start);
+ } else { lastClick = now; }
+
var last = start, going;
- // And then we have to see if it's a drag event, in which case
- // the dragged-over text must be selected.
- function end() {
- focusInput();
- updateInput = true;
- move(); up();
+ if (dragAndDrop && !posEq(sel.from, sel.to) &&
+ !posLess(start, sel.from) && !posLess(sel.to, start)) {
+ // Let the drag handler handle this.
+ return;
}
+ e_preventDefault(e);
+ setCursor(start.line, start.ch, true);
+
function extend(e) {
var cur = posFromMouse(e, true);
if (cur && !posEq(cur, last)) {
@@ -281,16 +306,11 @@ var CodeMirror = (function() {
var cur = posFromMouse(e);
if (cur) setSelectionUser(start, cur);
e_preventDefault(e);
- end();
+ focusInput();
+ updateInput = true;
+ move(); up();
}), true);
}
- function onDblClick(e) {
- var pos = posFromMouse(e);
- if (!pos) return;
- selectWordAt(pos);
- e_preventDefault(e);
- lastDoubleClick = +new Date;
- }
function onDrop(e) {
e.preventDefault();
var pos = posFromMouse(e, true), files = e.dataTransfer.files;
@@ -315,6 +335,13 @@ var CodeMirror = (function() {
catch(e){}
}
}
+ function onDragStart(e) {
+ var txt = getSelection();
+ // This will reset escapeElement
+ htmlEscape(txt);
+ e.dataTransfer.setDragImage(escapeElement, 0, 0);
+ e.dataTransfer.setData("Text", txt);
+ }
function onKeyDown(e) {
if (!focused) onFocus();
@@ -340,6 +367,7 @@ var CodeMirror = (function() {
if (mod && code == 90) {undo(); return e_preventDefault(e);} // ctrl-z
if (mod && ((e.shiftKey && code == 90) || code == 89)) {redo(); return e_preventDefault(e);} // ctrl-shift-z, ctrl-y
}
+ if (code == 36) { if (options.smartHome) { smartHome(); return e_preventDefault(e); } }
// Key id to use in the movementKeys map. We also pass it to
// fastPoll in order to 'self learn'. We need this because
@@ -347,14 +375,16 @@ var CodeMirror = (function() {
// its start when it is inverted and a movement key is pressed
// (and later restore it again), shouldn't be used for
// non-movement keys.
- curKeyId = (mod ? "c" : "") + code;
- if (sel.inverted && movementKeys.hasOwnProperty(curKeyId)) {
+ curKeyId = (mod ? "c" : "") + (e.altKey ? "a" : "") + code;
+ if (sel.inverted && movementKeys[curKeyId] === true) {
var range = selRange(input);
if (range) {
reducedSelection = {anchor: range.start};
setSelRange(input, range.start, range.start);
}
}
+ // Don't save the key as a movementkey unless it had a modifier
+ if (!mod && !e.altKey) curKeyId = null;
fastPoll(curKeyId);
}
function onKeyUp(e) {
@@ -566,7 +596,10 @@ var CodeMirror = (function() {
function p() {
startOperation();
var changed = readInput();
- if (changed == "moved" && keyId) movementKeys[keyId] = true;
+ if (changed && keyId) {
+ if (changed == "moved" && movementKeys[keyId] == null) movementKeys[keyId] = true;
+ if (changed == "changed") movementKeys[keyId] = false;
+ }
if (!changed && !missed) {missed = true; poll.set(80, p);}
else {pollingFast = false; slowPoll();}
endOperation();
@@ -663,6 +696,12 @@ var CodeMirror = (function() {
if (options.readOnly != "nocursor") input.focus();
}
+ function scrollEditorIntoView() {
+ if (!cursor.getBoundingClientRect) return;
+ var rect = cursor.getBoundingClientRect();
+ var winH = window.innerHeight || document.body.offsetHeight || document.documentElement.offsetHeight;
+ if (rect.top < 0 || rect.bottom > winH) cursor.scrollIntoView();
+ }
function scrollCursorIntoView() {
var cursor = localCoords(sel.inverted ? sel.from : sel.to);
return scrollIntoView(cursor.x, cursor.y, cursor.x, cursor.yBot);
@@ -675,9 +714,10 @@ var CodeMirror = (function() {
else if (y2 > screentop + screen) {scroller.scrollTop = y2 + lh - screen; scrolled = true;}
var screenw = scroller.clientWidth, screenleft = scroller.scrollLeft;
- if (x1 < screenleft) {
+ var gutterw = options.fixedGutter ? gutter.clientWidth : 0;
+ if (x1 < screenleft + gutterw) {
if (x1 < 50) x1 = 0;
- scroller.scrollLeft = Math.max(0, x1 - 10);
+ scroller.scrollLeft = Math.max(0, x1 - 10 - gutterw);
scrolled = true;
}
else if (x2 > screenw + screenleft) {
@@ -745,6 +785,7 @@ var CodeMirror = (function() {
if (domPos != domEnd || pos != to) {
changedLines += Math.abs(to - pos);
updates.push({from: pos, to: to, domSize: domEnd - domPos, domStart: domPos});
+ if (to - pos != domEnd - domPos) gutterDirty = true;
}
if (!updates.length) return;
@@ -766,8 +807,8 @@ var CodeMirror = (function() {
if (different) {
lastHeight = scroller.clientHeight;
code.style.height = (lines.length * lineHeight() + 2 * paddingTop()) + "px";
- updateGutter();
}
+ if (different || gutterDirty) updateGutter();
if (maxWidth == null) maxWidth = stringWidth(maxLine);
if (maxWidth > scroller.clientWidth) {
@@ -868,13 +909,17 @@ var CodeMirror = (function() {
if (pad) firstNode.insertBefore(targetDocument.createTextNode(pad), firstNode.firstChild);
gutter.style.display = "";
lineSpace.style.marginLeft = gutter.offsetWidth + "px";
+ gutterDirty = false;
}
function updateCursor() {
var head = sel.inverted ? sel.from : sel.to, lh = lineHeight();
- var x = charX(head.line, head.ch) + "px", y = (head.line - showingFrom) * lh + "px";
- inputDiv.style.top = (head.line * lh - scroller.scrollTop) + "px";
+ var x = charX(head.line, head.ch);
+ var top = head.line * lh - scroller.scrollTop;
+ inputDiv.style.top = Math.max(Math.min(top, scroller.offsetHeight), 0) + "px";
+ inputDiv.style.left = (x - scroller.scrollLeft) + "px";
if (posEq(sel.from, sel.to)) {
- cursor.style.top = y; cursor.style.left = x;
+ cursor.style.top = (head.line - showingFrom) * lh + "px";
+ cursor.style.left = x + "px";
cursor.style.display = "";
}
else cursor.style.display = "none";
@@ -994,6 +1039,10 @@ var CodeMirror = (function() {
}
return true;
}
+ function smartHome() {
+ var firstNonWS = Math.max(0, lines[sel.from.line].text.search(/\S/));
+ setCursor(sel.from.line, sel.from.ch <= firstNonWS && sel.from.ch ? 0 : firstNonWS, true);
+ }
function indentLine(n, how) {
if (how == "smart") {
@@ -1036,7 +1085,7 @@ var CodeMirror = (function() {
function gutterChanged() {
var visible = options.gutter || options.lineNumbers;
gutter.style.display = visible ? "" : "none";
- if (visible) updateGutter();
+ if (visible) gutterDirty = true;
else lineDiv.parentNode.style.marginLeft = 0;
}
@@ -1073,13 +1122,13 @@ var CodeMirror = (function() {
function addGutterMarker(line, text, className) {
if (typeof line == "number") line = lines[clipLine(line)];
line.gutterMarker = {text: text, style: className};
- updateGutter();
+ gutterDirty = true;
return line;
}
function removeGutterMarker(line) {
if (typeof line == "number") line = lines[clipLine(line)];
line.gutterMarker = null;
- updateGutter();
+ gutterDirty = true;
}
function setLineClass(line, className) {
if (typeof line == "number") {
@@ -1190,8 +1239,8 @@ var CodeMirror = (function() {
var oldCSS = input.style.cssText;
inputDiv.style.position = "absolute";
- input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e_pageY(e) - 1) +
- "px; left: " + (e_pageX(e) - 1) + "px; z-index: 1000; background: white; " +
+ input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
+ "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: white; " +
"border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
leaveInputAlone = true;
var val = input.value = getSelection();
@@ -1206,7 +1255,7 @@ var CodeMirror = (function() {
prepareInput();
slowPoll();
}
-
+
if (gecko) {
e_stop(e);
var mouseup = connect(window, "mouseup", function() {
@@ -1284,7 +1333,7 @@ var CodeMirror = (function() {
if (line.stateAfter) return search;
var indented = line.indentation();
if (minline == null || minindent > indented) {
- minline = search;
+ minline = search - 1;
minindent = indented;
}
}
@@ -1321,25 +1370,26 @@ var CodeMirror = (function() {
if (state) state = copyState(mode, state);
else state = startState(mode);
- var unchanged = 0, compare = mode.compareStates;
+ var unchanged = 0, compare = mode.compareStates, realChange = false;
for (var i = start, l = lines.length; i < l; ++i) {
var line = lines[i], hadState = line.stateAfter;
if (+new Date > end) {
work.push(i);
startWorker(options.workDelay);
- changes.push({from: task, to: i + 1});
+ if (realChange) changes.push({from: task, to: i + 1});
return;
}
var changed = line.highlight(mode, state);
+ if (changed) realChange = true;
line.stateAfter = copyState(mode, state);
if (compare) {
if (hadState && compare(hadState, state)) break;
} else {
- if (changed || !hadState) unchanged = 0;
+ if (changed !== false || !hadState) unchanged = 0;
else if (++unchanged > 3) break;
}
}
- changes.push({from: task, to: i + 1});
+ if (realChange) changes.push({from: task, to: i + 1});
}
if (foundWork && options.onHighlightComplete)
options.onHighlightComplete(instance);
@@ -1360,9 +1410,12 @@ var CodeMirror = (function() {
var reScroll = false;
if (selectionChanged) reScroll = !scrollCursorIntoView();
if (changes.length) updateDisplay(changes);
- else if (selectionChanged) updateCursor();
+ else {
+ if (selectionChanged) updateCursor();
+ if (gutterDirty) updateGutter();
+ }
if (reScroll) scrollCursorIntoView();
- if (selectionChanged) restartBlink();
+ if (selectionChanged) {scrollEditorIntoView(); restartBlink();}
// updateInput can be set to a boolean value to force/prevent an
// update.
@@ -1525,8 +1578,10 @@ var CodeMirror = (function() {
onKeyEvent: null,
lineNumbers: false,
gutter: false,
+ fixedGutter: false,
firstLineNumber: 1,
readOnly: false,
+ smartHome: true,
onChange: null,
onCursorActivity: null,
onGutterClick: null,
@@ -1572,7 +1627,7 @@ var CodeMirror = (function() {
CodeMirror.listMIMEs = function() {
var list = [];
for (var m in mimeModes)
- if (mimeModes.propertyIsEnumerable(m)) list.push(m);
+ if (mimeModes.propertyIsEnumerable(m)) list.push({mime: m, mode: mimeModes[m]});
return list;
};
@@ -1660,7 +1715,7 @@ var CodeMirror = (function() {
if (ok) {++this.pos; return ch;}
},
eatWhile: function(match) {
- var start = this.start;
+ var start = this.pos;
while (this.eat(match)){}
return this.pos > start;
},
@@ -1769,10 +1824,10 @@ var CodeMirror = (function() {
}
if (st.length != pos) {st.length = pos; changed = true;}
if (pos && st[pos-2] != prevWord) changed = true;
- // Short lines with simple highlights always count as changed,
- // because they are likely to highlight the same way in various
- // contexts.
- return changed || (st.length < 5 && this.text.length < 10);
+ // Short lines with simple highlights return null, and are
+ // counted as changed by the driver because they are likely to
+ // highlight the same way in various contexts.
+ return changed || (st.length < 5 && this.text.length < 10 ? null : false);
},
// Fetch the parser token for a given character. Useful for hacks
// that want to inspect the mode state (say, for completion).
@@ -1930,16 +1985,6 @@ var CodeMirror = (function() {
else if (e.button & 2) return 3;
else if (e.button & 4) return 2;
}
- function e_pageX(e) {
- if (e.pageX != null) return e.pageX;
- var doc = e_target(e).ownerDocument;
- return e.clientX + doc.body.scrollLeft + doc.documentElement.scrollLeft;
- }
- function e_pageY(e) {
- if (e.pageY != null) return e.pageY;
- var doc = e_target(e).ownerDocument;
- return e.clientY + doc.body.scrollTop + doc.documentElement.scrollTop;
- }
// Event handler registration. If disconnect is true, it'll return a
// function that unregisters the handler.
@@ -1965,6 +2010,15 @@ var CodeMirror = (function() {
pre.innerHTML = " "; return !pre.innerHTML;
})();
+ // Detect drag-and-drop
+ var dragAndDrop = (function() {
+ // IE8 has ondragstart and ondrop properties, but doesn't seem to
+ // actually support ondragstart the way it's supposed to work.
+ if (/MSIE [1-8]\b/.test(navigator.userAgent)) return false;
+ var div = document.createElement('div');
+ return "ondragstart" in div && "ondrop" in div;
+ })();
+
var gecko = /gecko\/\d{7}/i.test(navigator.userAgent);
var ie = /MSIE \d/.test(navigator.userAgent);
var safari = /Apple Computer/.test(navigator.vendor);
@@ -2140,5 +2194,4 @@ var CodeMirror = (function() {
CodeMirror.defineMIME("text/plain", "null");
return CodeMirror;
-})()
-;
\ No newline at end of file
+})();
diff --git a/IPython/frontend/html/notebook/static/codemirror-2.12/lib/overlay.js b/IPython/frontend/html/notebook/static/codemirror/lib/overlay.js
similarity index 100%
rename from IPython/frontend/html/notebook/static/codemirror-2.12/lib/overlay.js
rename to IPython/frontend/html/notebook/static/codemirror/lib/overlay.js
index c4cdf9f..b2ae21f 100644
--- a/IPython/frontend/html/notebook/static/codemirror-2.12/lib/overlay.js
+++ b/IPython/frontend/html/notebook/static/codemirror/lib/overlay.js
@@ -42,7 +42,7 @@ CodeMirror.overlayParser = function(base, overlay, combine) {
if (state.baseCur != null && combine) return state.baseCur + " " + state.overlayCur;
else return state.overlayCur;
},
-
+
indent: function(state, textAfter) {
return base.indent(state.base, textAfter);
},
diff --git a/IPython/frontend/html/notebook/static/codemirror-2.12/lib/runmode.js b/IPython/frontend/html/notebook/static/codemirror/lib/runmode.js
similarity index 100%
rename from IPython/frontend/html/notebook/static/codemirror-2.12/lib/runmode.js
rename to IPython/frontend/html/notebook/static/codemirror/lib/runmode.js
diff --git a/IPython/frontend/html/notebook/static/codemirror-2.12/mode/css/css.js b/IPython/frontend/html/notebook/static/codemirror/mode/css/css.js
similarity index 96%
rename from IPython/frontend/html/notebook/static/codemirror-2.12/mode/css/css.js
rename to IPython/frontend/html/notebook/static/codemirror/mode/css/css.js
index 6c239fc..45170a3 100644
--- a/IPython/frontend/html/notebook/static/codemirror-2.12/mode/css/css.js
+++ b/IPython/frontend/html/notebook/static/codemirror/mode/css/css.js
@@ -4,7 +4,7 @@ CodeMirror.defineMode("css", function(config) {
function tokenBase(stream, state) {
var ch = stream.next();
- if (ch == "@") {stream.eatWhile(/\w/); return ret("meta", stream.current());}
+ if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("meta", stream.current());}
else if (ch == "/" && stream.eat("*")) {
state.tokenize = tokenCComment;
return tokenCComment(stream, state);
@@ -20,7 +20,7 @@ CodeMirror.defineMode("css", function(config) {
return state.tokenize(stream, state);
}
else if (ch == "#") {
- stream.eatWhile(/\w/);
+ stream.eatWhile(/[\w\\\-]/);
return ret("atom", "hash");
}
else if (ch == "!") {
@@ -38,7 +38,7 @@ CodeMirror.defineMode("css", function(config) {
return ret(null, ch);
}
else {
- stream.eatWhile(/[\w\\\-_]/);
+ stream.eatWhile(/[\w\\\-]/);
return ret("variable", "variable");
}
}
diff --git a/IPython/frontend/html/notebook/static/codemirror-2.12/mode/css/index.html b/IPython/frontend/html/notebook/static/codemirror/mode/css/index.html
similarity index 100%
rename from IPython/frontend/html/notebook/static/codemirror-2.12/mode/css/index.html
rename to IPython/frontend/html/notebook/static/codemirror/mode/css/index.html
diff --git a/IPython/frontend/html/notebook/static/codemirror-2.12/mode/htmlmixed/htmlmixed.js b/IPython/frontend/html/notebook/static/codemirror/mode/htmlmixed/htmlmixed.js
similarity index 100%
rename from IPython/frontend/html/notebook/static/codemirror-2.12/mode/htmlmixed/htmlmixed.js
rename to IPython/frontend/html/notebook/static/codemirror/mode/htmlmixed/htmlmixed.js
diff --git a/IPython/frontend/html/notebook/static/codemirror-2.12/mode/htmlmixed/index.html b/IPython/frontend/html/notebook/static/codemirror/mode/htmlmixed/index.html
similarity index 100%
rename from IPython/frontend/html/notebook/static/codemirror-2.12/mode/htmlmixed/index.html
rename to IPython/frontend/html/notebook/static/codemirror/mode/htmlmixed/index.html
diff --git a/IPython/frontend/html/notebook/static/codemirror-2.12/mode/javascript/index.html b/IPython/frontend/html/notebook/static/codemirror/mode/javascript/index.html
similarity index 100%
rename from IPython/frontend/html/notebook/static/codemirror-2.12/mode/javascript/index.html
rename to IPython/frontend/html/notebook/static/codemirror/mode/javascript/index.html
diff --git a/IPython/frontend/html/notebook/static/codemirror-2.12/mode/javascript/javascript.js b/IPython/frontend/html/notebook/static/codemirror/mode/javascript/javascript.js
similarity index 95%
rename from IPython/frontend/html/notebook/static/codemirror-2.12/mode/javascript/javascript.js
rename to IPython/frontend/html/notebook/static/codemirror/mode/javascript/javascript.js
index bdf9952..4e0f7ff 100644
--- a/IPython/frontend/html/notebook/static/codemirror-2.12/mode/javascript/javascript.js
+++ b/IPython/frontend/html/notebook/static/codemirror/mode/javascript/javascript.js
@@ -52,7 +52,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
else if (ch == "0" && stream.eat(/x/i)) {
stream.eatWhile(/[\da-f]/i);
return ret("number", "number");
- }
+ }
else if (/\d/.test(ch)) {
stream.match(/^\d*(?:\.\d*)?(?:e[+\-]?\d+)?/);
return ret("number", "number");
@@ -75,6 +75,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
return ret("operator", null, stream.current());
}
}
+ else if (ch == "#") {
+ stream.skipToEnd();
+ return ret("error", "error");
+ }
else if (isOperatorChar.test(ch)) {
stream.eatWhile(isOperatorChar);
return ret("operator", null, stream.current());
@@ -130,7 +134,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
// Communicate our context to the combinators.
// (Less wasteful than consing up a hundred closures on every call.)
cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
-
+
if (!state.lexical.hasOwnProperty("align"))
state.lexical.align = true;
diff --git a/IPython/frontend/html/notebook/static/codemirror/mode/markdown/index.html b/IPython/frontend/html/notebook/static/codemirror/mode/markdown/index.html
new file mode 100644
index 0000000..5e782a5
--- /dev/null
+++ b/IPython/frontend/html/notebook/static/codemirror/mode/markdown/index.html
@@ -0,0 +1,340 @@
+
+
+
+ CodeMirror 2: Markdown mode
+
+
+
+
+
+
+
+
+
+
+