spec/dummy/tmp/cache/assets/D0E/2E0/sprockets%2F4a4bfb6542664b7912f800e18ce7e4c2 in locomotivecms-search-0.2.8 vs spec/dummy/tmp/cache/assets/D0E/2E0/sprockets%2F4a4bfb6542664b7912f800e18ce7e4c2 in locomotivecms-search-0.3.0
- old
+ new
@@ -1,8 +1,8 @@
-o: ActiveSupport::Cache::Entry :@compressedF:@expires_in0:@created_atf1384093249.403806:@value"Ö•{I"
+o: ActiveSupport::Cache::Entry :@compressedF:@expires_in0:@created_atf1396022042.161833:@value"{I"
class:ETI"BundledAsset; FI"logical_path; TI"locomotive.js; TI"
pathname; TI"V/Users/didier/Documents/LocomotiveCMS/engine/app/assets/javascripts/locomotive.js; FI"content_type; TI"application/javascript; TI"
-mtime; TI"2013-11-09T00:10:51+01:00; TI"length; Tiñ“I"digest; TI"%d158eb94073c745799928c8d2623a160; FI"source; TI"ñ“/*!
+mtime; TI"2014-03-20T10:46:19+01:00; TI"length; Ti3I"digest; TI"%2f328578df55c9afe9bb5173af68e1cf; FI"source; TI"3/*!
* jQuery JavaScript Library v1.8.3
* http://jquery.com/
*
* Includes Sizzle.js
* http://sizzlejs.com/
@@ -27303,24 +27303,30 @@
var urlError = function() {
throw new Error('A "url" property or function must be specified');
};
}).call(this);
-// CodeMirror version 3.16
+// CodeMirror version 3.22
//
// CodeMirror is the only global var we claim
window.CodeMirror = (function() {
"use strict";
// BROWSER SNIFFING
// Crude, but necessary to handle a number of hard-to-feature-detect
// bugs and behavior differences.
var gecko = /gecko\/\d/i.test(navigator.userAgent);
- var ie = /MSIE \d/.test(navigator.userAgent);
- var ie_lt8 = ie && (document.documentMode == null || document.documentMode < 8);
- var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
+ // IE11 currently doesn't count as 'ie', since it has almost none of
+ // the same bugs as earlier versions. Use ie_gt10 to handle
+ // incompatibilities in that version.
+ 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);
var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
var chrome = /Chrome\//.test(navigator.userAgent);
var opera = /Opera\//.test(navigator.userAgent);
var safari = /Apple Computer/.test(navigator.vendor);
@@ -27364,11 +27370,12 @@
this.state = {keyMaps: [],
overlays: [],
modeGen: 0,
overwrite: false, focused: false,
- suppressEdits: false, pasteIncoming: false,
+ suppressEdits: false,
+ pasteIncoming: false, cutIncoming: false,
draggingText: false,
highlight: new Delayed()};
themeChanged(this);
if (options.lineWrapping)
@@ -27378,11 +27385,11 @@
if (typeof doc == "string") doc = new Doc(options.value, options.mode);
operation(this, attachDoc)(this, doc);
// Override magic textarea content restore that IE sometimes does
// on our hidden textarea on reload
- if (ie) setTimeout(bind(resetInput, this, true), 20);
+ if (old_ie) setTimeout(bind(resetInput, this, true), 20);
registerEventHandlers(this);
// IE throws unspecified error in certain cases, when
// trying to access activeElement before onload
var hasFocus; try { hasFocus = (document.activeElement == display.input); } catch(e) { }
@@ -27400,11 +27407,11 @@
// DISPLAY CONSTRUCTOR
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)
if (ios) input.style.border = "1px solid black";
input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off"); input.setAttribute("spellcheck", "false");
@@ -27472,11 +27479,11 @@
// intensively.
d.pollingFast = false;
// 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;
// Tracks when resetInput has punted to just putting a short
// string instead of the (large) selection.
@@ -27498,10 +27505,14 @@
// Used to get the editor into a consistent state again when options change.
function loadMode(cm) {
cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption);
+ resetModeState(cm);
+ }
+
+ function resetModeState(cm) {
cm.doc.iter(function(line) {
if (line.stateAfter) line.stateAfter = null;
if (line.styles) line.styles = null;
});
cm.doc.frontier = cm.doc.first;
@@ -27547,11 +27558,10 @@
function keyMapChanged(cm) {
var map = keyMap[cm.options.keyMap], style = map.style;
cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-keymap-\S+/g, "") +
(style ? " cm-keymap-" + style : "");
- cm.state.disableInput = map.disableInput;
}
function themeChanged(cm) {
cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
@@ -27611,19 +27621,17 @@
}
// Make sure the gutters options contains the element
// "CodeMirror-linenumbers" when the lineNumbers option is true.
function setGuttersForLineNumbers(options) {
- var found = false;
- for (var i = 0; i < options.gutters.length; ++i) {
- if (options.gutters[i] == "CodeMirror-linenumbers") {
- if (options.lineNumbers) found = true;
- else options.gutters.splice(i--, 1);
- }
+ var found = indexOf(options.gutters, "CodeMirror-linenumbers");
+ if (found == -1 && options.lineNumbers) {
+ options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]);
+ } else if (found > -1 && !options.lineNumbers) {
+ options.gutters = options.gutters.slice(0);
+ options.gutters.splice(found, 1);
}
- if (!found && options.lineNumbers)
- options.gutters.push("CodeMirror-linenumbers");
}
// SCROLLBARS
// Re-synchronize the fake scrollbars with the actual size of the
@@ -27637,12 +27645,13 @@
var needsH = d.scroller.scrollWidth > (d.scroller.clientWidth + 1);
var needsV = scrollHeight > (d.scroller.clientHeight + 1);
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";
}
if (needsH) {
@@ -27662,12 +27671,14 @@
d.gutterFiller.style.display = "block";
d.gutterFiller.style.height = scrollbarWidth(d.measure) + "px";
d.gutterFiller.style.width = d.gutters.offsetWidth + "px";
} else d.gutterFiller.style.display = "";
- if (mac_geLion && scrollbarWidth(d.measure) === 0)
+ 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";
+ }
}
function visibleLines(display, doc, viewPort) {
var top = display.scroller.scrollTop, height = display.wrapper.clientHeight;
if (typeof viewPort == "number") top = viewPort;
@@ -27718,25 +27729,30 @@
// DISPLAY DRAWING
function updateDisplay(cm, changes, viewPort, forced) {
var oldFrom = cm.display.showingFrom, oldTo = cm.display.showingTo, updated;
var visible = visibleLines(cm.display, cm.doc, viewPort);
- for (;;) {
+ for (var first = true;; first = false) {
+ var oldWidth = cm.display.scroller.clientWidth;
if (!updateDisplayInner(cm, changes, visible, forced)) break;
- forced = false;
updated = true;
+ changes = [];
updateSelection(cm);
updateScrollbars(cm);
+ if (first && cm.options.lineWrapping && oldWidth != cm.display.scroller.clientWidth) {
+ forced = true;
+ continue;
+ }
+ forced = false;
// Clip forced viewport to actual scrollable area
if (viewPort)
viewPort = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight,
typeof viewPort == "number" ? viewPort : viewPort.top);
visible = visibleLines(cm.display, cm.doc, viewPort);
if (visible.from >= cm.display.showingFrom && visible.to <= cm.display.showingTo)
break;
- changes = [];
}
if (updated) {
signalLater(cm, "update", cm);
if (cm.display.showingFrom != oldFrom || cm.display.showingTo != oldTo)
@@ -27748,11 +27764,11 @@
// Uses a set of changes plus the current scroll position to
// determine which DOM updates have to be made, and makes the
// updates.
function updateDisplayInner(cm, changes, visible, forced) {
var display = cm.display, doc = cm.doc;
- if (!display.wrapper.clientWidth) {
+ if (!display.wrapper.offsetWidth) {
display.showingFrom = display.showingTo = doc.first;
display.viewOffset = 0;
return;
}
@@ -27833,10 +27849,11 @@
display.lastSizeC = display.wrapper.clientHeight;
startWorker(cm, 400);
}
display.showingFrom = from; display.showingTo = to;
+ display.gutters.style.height = "";
updateHeightsInViewport(cm);
updateViewOffset(cm);
return true;
}
@@ -27970,14 +27987,15 @@
});
while (cur) cur = rm(cur);
}
function buildLineElement(cm, line, lineNo, dims, reuse) {
- var lineElement = lineContent(cm, line);
+ var built = buildLineContent(cm, line), lineElement = built.pre;
var markers = line.gutterMarkers, display = cm.display, wrap;
- if (!cm.options.lineNumbers && !markers && !line.bgClass && !line.wrapClass && !line.widgets)
+ var bgClass = built.bgClass ? built.bgClass + " " + (line.bgClass || "") : line.bgClass;
+ if (!cm.options.lineNumbers && !markers && !bgClass && !line.wrapClass && !line.widgets)
return lineElement;
// Lines with gutter elements, widgets or a background class need
// to be wrapped again, and have the extra elements added to the
// wrapper div
@@ -28011,16 +28029,16 @@
if (!wrap) {
wrap = elt("div", null, line.wrapClass, "position: relative");
wrap.appendChild(lineElement);
}
// Kludge to make sure the styled element lies behind the selection (by z-index)
- if (line.bgClass)
- wrap.insertBefore(elt("div", null, line.bgClass + " CodeMirror-linebackground"), wrap.firstChild);
+ if (bgClass)
+ wrap.insertBefore(elt("div", null, bgClass + " CodeMirror-linebackground"), wrap.firstChild);
if (cm.options.lineNumbers || markers) {
- var gutterWrap = wrap.insertBefore(elt("div", null, null, "position: absolute; left: " +
+ var gutterWrap = wrap.insertBefore(elt("div", null, "CodeMirror-gutter-wrapper", "position: absolute; left: " +
(cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"),
- wrap.firstChild);
+ lineElement);
if (cm.options.fixedGutter) (wrap.alignable || (wrap.alignable = [])).push(gutterWrap);
if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
wrap.lineNumber = gutterWrap.appendChild(
elt("div", lineNumberFor(cm.options, lineNo),
"CodeMirror-linenumber CodeMirror-gutter-elt",
@@ -28109,16 +28127,16 @@
// Highlight selection
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"));
}
function drawForLine(line, fromArg, toArg) {
var lineObj = getLine(doc, line);
@@ -28137,22 +28155,22 @@
rightPos = coords(to - 1, "right");
if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; }
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};
}
@@ -28164,17 +28182,17 @@
var leftEnd = drawForLine(sel.from.line, sel.from.ch, singleVLine ? fromLine.text.length : null).end;
var rightStart = drawForLine(sel.to.line, singleVLine ? 0 : null, sel.to.ch).start;
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);
display.selectionDiv.style.display = "";
}
@@ -28207,20 +28225,20 @@
var state = copyState(doc.mode, getStateBefore(cm, doc.frontier));
var changed = [], prevChange;
doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.showingTo + 500), function(line) {
if (doc.frontier >= cm.display.showingFrom) { // Visible
var oldStyles = line.styles;
- line.styles = highlightLine(cm, line, state);
+ line.styles = highlightLine(cm, line, state, true);
var ischange = !oldStyles || oldStyles.length != line.styles.length;
for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];
if (ischange) {
if (prevChange && prevChange.end == doc.frontier) prevChange.end++;
else changed.push(prevChange = {start: doc.frontier, end: doc.frontier + 1});
}
line.stateAfter = copyState(doc.mode, state);
} else {
- processLine(cm, line, state);
+ processLine(cm, line.text, state);
line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;
}
++doc.frontier;
if (+new Date > end) {
startWorker(cm, cm.options.workDelay);
@@ -28238,12 +28256,13 @@
// find a line with a stateAfter, so that it can start with a
// valid state. If that fails, it returns the line with the
// smallest indentation, which tends to need the least context to
// parse correctly.
function findStartLine(cm, n, precise) {
- var minindent, minline, doc = cm.doc, maxScan = cm.doc.mode.innerMode ? 1000 : 100;
- for (var search = n, lim = n - maxScan; search > lim; --search) {
+ var minindent, minline, doc = cm.doc;
+ var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100);
+ for (var search = n; search > lim; --search) {
if (search <= doc.first) return doc.first;
var line = getLine(doc, search - 1);
if (line.stateAfter && (!precise || search <= doc.frontier)) return search;
var indented = countColumn(line.text, null, cm.options.tabSize);
if (minline == null || minindent > indented) {
@@ -28259,30 +28278,38 @@
if (!doc.mode.startState) return true;
var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter;
if (!state) state = startState(doc.mode);
else state = copyState(doc.mode, state);
doc.iter(pos, n, function(line) {
- processLine(cm, line, state);
+ processLine(cm, line.text, state);
var save = pos == n - 1 || pos % 5 == 0 || pos >= display.showingFrom && pos < display.showingTo;
line.stateAfter = save ? copyState(doc.mode, state) : null;
++pos;
});
+ if (precise) doc.frontier = pos;
return state;
}
// POSITION MEASUREMENT
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) {
var dir = -1;
data = data || measureLine(cm, line);
+ if (data.crude) {
+ var left = data.left + ch * data.width;
+ return {left: left, right: left + data.width, top: data.top, bottom: data.bottom};
+ }
for (var pos = ch;; pos += dir) {
var r = data[pos];
if (r) break;
if (dir < 0 && pos == 0) dir = 1;
@@ -28300,11 +28327,11 @@
var cache = cm.display.measureLineCache;
for (var i = 0; i < cache.length; ++i) {
var memo = cache[i];
if (memo.text == line.text && memo.markedSpans == line.markedSpans &&
cm.display.scroller.clientWidth == memo.width &&
- memo.classes == line.textClass + "|" + line.bgClass + "|" + line.wrapClass)
+ memo.classes == line.textClass + "|" + line.wrapClass)
return memo;
}
}
function clearCachedMeasurement(cm, line) {
@@ -28320,19 +28347,22 @@
// Failing that, recompute and store result in cache
var measure = measureLineInner(cm, line);
var cache = cm.display.measureLineCache;
var memo = {text: line.text, width: cm.display.scroller.clientWidth,
markedSpans: line.markedSpans, measure: measure,
- classes: line.textClass + "|" + line.bgClass + "|" + line.wrapClass};
+ classes: line.textClass + "|" + line.wrapClass};
if (cache.length == 16) cache[++cm.display.measureLineCachePos % 16] = memo;
else cache.push(memo);
return measure;
}
function measureLineInner(cm, line) {
+ if (!cm.options.lineWrapping && line.text.length >= cm.options.crudeMeasuringFrom)
+ return crudelyMeasureLine(cm, line);
+
var display = cm.display, measure = emptyArray(line.text.length);
- var pre = lineContent(cm, line, measure, true);
+ var pre = buildLineContent(cm, line, measure, true).pre;
// IE does not cache element positions of inline elements between
// calls to getBoundingClientRect. This makes the loop below,
// which gathers the positions of all the characters on the line,
// do an amount of layout work quadratic to the number of
@@ -28341,11 +28371,11 @@
// that IE can reuse most of the layout information from caches
// for those blocks. This does interfere with line wrapping, so it
// doesn't work when wrapping is on, but in that case the
// situation is slightly better, since IE does cache line-wrapping
// information and only recomputes per-line.
- if (ie && !ie_lt8 && !cm.options.lineWrapping && pre.childNodes.length > 100) {
+ if (old_ie && !ie_lt8 && !cm.options.lineWrapping && pre.childNodes.length > 100) {
var fragment = document.createDocumentFragment();
var chunk = 10, n = pre.childNodes.length;
for (var i = 0, chunks = Math.ceil(n / chunk); i < chunks; ++i) {
var wrap = elt("div", null, null, "display: inline-block");
for (var j = 0; j < chunk && n; ++j) {
@@ -28401,11 +28431,11 @@
rect = data[i] = measureRect(rects[0]);
rect.rightSide = measureRect(rects[rects.length - 1]);
}
}
if (!rect) rect = data[i] = measureRect(getRect(node));
- if (cur.measureRight) rect.right = getRect(cur.measureRight).left;
+ if (cur.measureRight) rect.right = getRect(cur.measureRight).left - outer.left;
if (cur.leftSide) rect.leftSide = measureRect(getRect(cur.leftSide));
}
removeChildren(cm.display.measure);
for (var i = 0, cur; i < data.length; ++i) if (cur = data[i]) {
finishRect(cur);
@@ -28413,28 +28443,38 @@
if (cur.rightSide) finishRect(cur.rightSide);
}
return data;
}
+ function crudelyMeasureLine(cm, line) {
+ var copy = new Line(line.text.slice(0, 100), null);
+ if (line.textClass) copy.textClass = line.textClass;
+ var measure = measureLineInner(cm, copy);
+ var left = measureChar(cm, copy, 0, measure, "left");
+ var right = measureChar(cm, copy, 99, measure, "right");
+ return {crude: true, top: left.top, left: left.left, bottom: left.bottom, width: (right.right - left.left) / 100};
+ }
+
function measureLineWidth(cm, line) {
var hasBadSpan = false;
if (line.markedSpans) for (var i = 0; i < line.markedSpans; ++i) {
var sp = line.markedSpans[i];
if (sp.collapsed && (sp.to == null || sp.to == line.text.length)) hasBadSpan = true;
}
var cached = !hasBadSpan && findCachedMeasurement(cm, line);
- if (cached) return measureChar(cm, line, line.text.length, cached.measure, "right").right;
+ if (cached || line.text.length >= cm.options.crudeMeasuringFrom)
+ return measureChar(cm, line, line.text.length, cached && cached.measure, "right").right;
- var pre = lineContent(cm, line, null, true);
+ 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;
}
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;
}
function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; }
@@ -28567,11 +28607,11 @@
// Do a binary search between these bounds.
for (;;) {
if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) {
var ch = x < fromX || x - fromX <= toX - x ? from : to;
var xDiff = x - (ch == from ? fromX : toX);
- while (isExtendingChar.test(lineObj.text.charAt(ch))) ++ch;
+ while (isExtendingChar(lineObj.text.charAt(ch))) ++ch;
var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside,
xDiff < 0 ? -1 : xDiff ? 1 : 0);
return pos;
}
var step = Math.ceil(dist / 2), middle = from + step;
@@ -28646,11 +28686,11 @@
cm.curOp = null;
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)
setScrollLeft(cm, Math.min(display.scroller.scrollLeft, maxScrollLeft), true);
}
@@ -28665,15 +28705,18 @@
updated = updateDisplay(cm, op.changes, newScrollPos && newScrollPos.scrollTop, op.forceUpdate);
if (cm.display.scroller.offsetHeight) cm.doc.scrollTop = cm.display.scroller.scrollTop;
}
if (!updated && op.selectionChanged) updateSelection(cm);
if (op.updateScrollPos) {
- display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = newScrollPos.scrollTop;
- display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = newScrollPos.scrollLeft;
+ var top = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, newScrollPos.scrollTop));
+ var left = Math.max(0, Math.min(display.scroller.scrollWidth - display.scroller.clientWidth, newScrollPos.scrollLeft));
+ display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = top;
+ display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = left;
alignHorizontally(cm);
if (op.scrollToPos)
- scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos), op.scrollToPosMargin);
+ scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos.from),
+ clipPos(cm.doc, op.scrollToPos.to), op.scrollToPos.margin);
} else if (newScrollPos) {
scrollCursorIntoView(cm);
}
if (op.selectionChanged) restartBlink(cm);
@@ -28756,11 +28799,11 @@
// compared to the previous content instead. (Modern browsers have
// events that indicate IME taking place, but these are not widely
// supported or compatible enough yet to rely on.)
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.state.disableInput) return false;
+ 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;
@@ -28774,26 +28817,36 @@
if (withOp) startOperation(cm);
sel.shift = false;
var same = 0, l = Math.min(prevInput.length, text.length);
while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;
var from = sel.from, to = sel.to;
+ var inserted = text.slice(same);
if (same < prevInput.length)
from = Pos(from.line, from.ch - (prevInput.length - same));
else if (cm.state.overwrite && posEq(from, to) && !cm.state.pasteIncoming)
- to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + (text.length - same)));
+ to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + inserted.length));
var updateInput = cm.curOp.updateInput;
- var changeEvent = {from: from, to: to, text: splitLines(text.slice(same)),
- origin: cm.state.pasteIncoming ? "paste" : "+input"};
+ var changeEvent = {from: from, to: to, text: splitLines(inserted),
+ origin: cm.state.pasteIncoming ? "paste" : cm.state.cutIncoming ? "cut" : "+input"};
makeChange(cm.doc, changeEvent, "end");
cm.curOp.updateInput = updateInput;
signalLater(cm, "inputRead", cm, changeEvent);
+ if (inserted && !cm.state.pasteIncoming && cm.options.electricChars &&
+ cm.options.smartIndent && sel.head.ch < 100) {
+ var electric = cm.getModeAt(sel.head).electricChars;
+ if (electric) for (var i = 0; i < electric.length; i++)
+ if (inserted.indexOf(electric.charAt(i)) > -1) {
+ indentLine(cm, sel.head.line, "smart");
+ break;
+ }
+ }
if (text.length > 1000 || text.indexOf("\n") > -1) input.value = cm.display.prevInput = "";
else cm.display.prevInput = text;
if (withOp) endOperation(cm);
- cm.state.pasteIncoming = false;
+ cm.state.pasteIncoming = cm.state.cutIncoming = false;
return true;
}
function resetInput(cm, user) {
var minimal, selected, doc = cm.doc;
@@ -28815,20 +28868,24 @@
function focusInput(cm) {
if (cm.options.readOnly != "nocursor" && (!mobile || document.activeElement != cm.display.input))
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;
}
// EVENT HANDLERS
function registerEventHandlers(cm) {
var d = cm.display;
on(d.scroller, "mousedown", operation(cm, onMouseDown));
- if (ie)
+ if (old_ie)
on(d.scroller, "dblclick", operation(cm, function(e) {
if (signalDOMEvent(cm, e)) return;
var pos = posFromMouse(cm, e);
if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return;
e_preventDefault(e);
@@ -28871,11 +28928,11 @@
var resizeTimer;
function onResize() {
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);
}
on(window, "resize", onResize);
@@ -28887,15 +28944,15 @@
if (p) setTimeout(unregister, 5000);
else off(window, "resize", onResize);
}
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, "input", bind(fastPoll, cm));
+ 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);
+ });
on(d.input, "keydown", operation(cm, onKeyDown));
on(d.input, "keypress", operation(cm, onKeyPress));
on(d.input, "focus", bind(onFocus, cm));
on(d.input, "blur", bind(onBlur, cm));
@@ -28927,25 +28984,26 @@
}
cm.state.pasteIncoming = true;
fastPoll(cm);
});
- function prepareCopy() {
+ function prepareCopy(e) {
if (d.inaccurateSelection) {
d.prevInput = "";
d.inaccurateSelection = false;
d.input.value = cm.getSelection();
selectInput(d.input);
}
+ if (e.type == "cut") cm.state.cutIncoming = true;
}
on(d.input, "cut", prepareCopy);
on(d.input, "copy", prepareCopy);
// Needed to handle Tab key in KHTML
if (khtml) on(d.sizer, "mouseup", function() {
- if (document.activeElement == d.input) d.input.blur();
- focusInput(cm);
+ if (document.activeElement == d.input) d.input.blur();
+ focusInput(cm);
});
}
function eventInWidget(display, e) {
for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
@@ -28980,10 +29038,11 @@
}
return;
}
if (clickInGutter(cm, e)) return;
var start = posFromMouse(cm, e);
+ window.focus();
switch (e_button(e)) {
case 3:
if (captureMiddleClick) onContextMenu.call(cm, cm, e);
return;
@@ -28997,11 +29056,11 @@
// For button 1, if it was clicked inside the editor
// (posFromMouse returning non-null), we have to adjust the
// 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)) {
type = "triple";
e_preventDefault(e);
@@ -29025,10 +29084,13 @@
off(display.scroller, "drop", dragEnd);
if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
e_preventDefault(e2);
extendSelection(cm.doc, start);
focusInput(cm);
+ // Work around unexplainable focus problem in IE9 (#2127)
+ if (old_ie && !ie_lt9)
+ setTimeout(function() {document.body.focus(); focusInput(cm);}, 20);
}
});
// Let the drag handler handle this.
if (webkit) display.scroller.draggable = true;
cm.state.draggingText = dragEnd;
@@ -29074,11 +29136,11 @@
function extend(e) {
var curCount = ++counter;
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);
if (cur.line >= visible.to || cur.line < visible.from)
setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150);
@@ -29099,43 +29161,50 @@
off(document, "mousemove", move);
off(document, "mouseup", up);
}
var move = operation(cm, function(e) {
- if (!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);
on(document, "mousemove", move);
on(document, "mouseup", up);
}
- function clickInGutter(cm, e) {
- var display = cm.display;
+ function gutterEvent(cm, e, type, prevent, signalfn) {
try { var mX = e.clientX, mY = e.clientY; }
catch(e) { return false; }
+ if (mX >= Math.floor(getRect(cm.display.gutters).right)) return false;
+ if (prevent) e_preventDefault(e);
- if (mX >= Math.floor(getRect(display.gutters).right)) return false;
- e_preventDefault(e);
- if (!hasHandler(cm, "gutterClick")) return true;
-
+ var display = cm.display;
var lineBox = getRect(display.lineDiv);
- if (mY > lineBox.bottom) return true;
+
+ if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e);
mY -= lineBox.top - display.viewOffset;
for (var i = 0; i < cm.options.gutters.length; ++i) {
var g = display.gutters.childNodes[i];
if (g && getRect(g).right >= mX) {
var line = lineAtHeight(cm.doc, mY);
var gutter = cm.options.gutters[i];
- signalLater(cm, "gutterClick", cm, line, gutter, e);
- break;
+ signalfn(cm, type, cm, line, gutter, e);
+ return e_defaultPrevented(e);
}
}
- return true;
}
+ function contextMenuInGutter(cm, e) {
+ if (!hasHandler(cm, "gutterContextMenu")) return false;
+ return gutterEvent(cm, e, "gutterContextMenu", false, signal);
+ }
+
+ function clickInGutter(cm, e) {
+ return gutterEvent(cm, e, "gutterClick", true, signalLater);
+ }
+
// Kludge to work around strange IE behavior where it'll sometimes
// re-fire a series of drag-related events right after the drop (#1551)
var lastDrop = 0;
function onDrop(e) {
@@ -29174,11 +29243,10 @@
var curFrom = cm.doc.sel.from, curTo = cm.doc.sel.to;
setSelection(cm.doc, pos, pos);
if (cm.state.draggingText) replaceRange(cm.doc, "", curFrom, curTo, "paste");
cm.replaceSelection(text, null, "paste");
focusInput(cm);
- onFocus(cm);
}
}
catch(e){}
}
}
@@ -29192,10 +29260,11 @@
// Use dummy image instead of default browsers image.
// Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
if (e.dataTransfer.setDragImage && !safari) {
var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
+ img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
if (opera) {
img.width = img.height = 1;
cm.display.wrapper.appendChild(img);
// Force a relayout, or Opera won't use our image for some obscure reason
img._top = img.offsetTop;
@@ -29386,16 +29455,22 @@
signalLater(cm, "keyHandled", cm, "'" + ch + "'", e);
}
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 (ie && e.keyCode == 27) e.returnValue = false;
+ if (old_ie && e.keyCode == 27) e.returnValue = false;
var code = e.keyCode;
// IE does strange things with escape.
cm.doc.sel.shift = code == 16 || e.shiftKey;
// First give onKeyEvent option a chance to handle this.
var handled = handleKeyBinding(cm, e);
@@ -29412,14 +29487,10 @@
if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
var keyCode = e.keyCode, charCode = e.charCode;
if (opera && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
if (((opera && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return;
var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
- if (this.options.electricChars && this.doc.mode.electricChars &&
- this.options.smartIndent && !isReadOnly(this) &&
- this.doc.mode.electricChars.indexOf(ch) > -1)
- setTimeout(operation(cm, function() {indentLine(cm, cm.doc.sel.to.line, "smart");}), 75);
if (handleCharBinding(cm, e, ch)) return;
if (ie && !ie_lt9) cm.display.inputHasSelection = null;
fastPoll(cm);
}
@@ -29450,31 +29521,35 @@
var detectingSelectAll;
function onContextMenu(cm, e) {
if (signalDOMEvent(cm, e, "contextmenu")) return;
var display = cm.display, sel = cm.doc.sel;
- if (eventInWidget(display, e)) return;
+ if (eventInWidget(display, e) || contextMenuInGutter(cm, e)) return;
var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
if (!pos || opera) return; // Opera is difficult.
- if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to))
+
+ // Reset the current text selection only if the click is done outside of the selection
+ // and 'resetSelectionOnContextMenu' option is true.
+ var reset = cm.options.resetSelectionOnContextMenu;
+ if (reset && (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to)))
operation(cm, setSelection)(cm.doc, pos, pos);
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: white; outline: none;" +
+ "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);";
focusInput(cm);
resetInput(cm, true);
// Adds "Select all" to context menu in FF
if (posEq(sel.from, sel.to)) display.input.value = display.prevInput = " ";
function prepareSelectAllHack() {
if (display.input.selectionStart != null) {
- var extval = display.input.value = " " + (posEq(sel.from, sel.to) ? "" : display.input.value);
- display.prevInput = " ";
+ var extval = display.input.value = "\u200b" + (posEq(sel.from, sel.to) ? "" : display.input.value);
+ display.prevInput = "\u200b";
display.input.selectionStart = 1; display.input.selectionEnd = extval.length;
}
}
function rehide() {
display.inputDiv.style.position = "relative";
@@ -29485,11 +29560,11 @@
// Try to detect the user choosing select-all
if (display.input.selectionStart != null) {
if (!ie || ie_lt9) prepareSelectAllHack();
clearTimeout(detectingSelectAll);
var i = 0, poll = function(){
- if (display.prevInput == " " && display.input.selectionStart == 0)
+ if (display.prevInput == "\u200b" && display.input.selectionStart == 0)
operation(cm, commands.selectAll)(cm);
else if (i++ < 10) detectingSelectAll = setTimeout(poll, 500);
else resetInput(cm);
};
detectingSelectAll = setTimeout(poll, 200);
@@ -29604,10 +29679,11 @@
makeChangeNoReadonly(doc, change, selUpdate);
}
}
function makeChangeNoReadonly(doc, change, selUpdate) {
+ if (change.text.length == 1 && change.text[0] == "" && posEq(change.from, change.to)) return;
var selAfter = computeSelAfterChange(doc, change, selUpdate);
addToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);
makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));
var rebased = [];
@@ -29766,10 +29842,11 @@
}
CodeMirror.Pos = Pos;
function posEq(a, b) {return a.line == b.line && a.ch == b.ch;}
function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);}
+ function cmp(a, b) {return a.line - b.line || a.ch - b.ch;}
function copyPos(x) {return Pos(x.line, x.ch);}
// SELECTION
function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));}
@@ -29826,10 +29903,11 @@
anchor = filtered.anchor;
}
var sel = doc.sel;
sel.goalColumn = null;
+ if (bias == null) bias = posLess(head, sel.head) ? -1 : 1;
// Skip over atomic spans.
if (checkAtomic || !posEq(anchor, sel.anchor))
anchor = skipAtomic(doc, anchor, bias, checkAtomic != "push");
if (checkAtomic || !posEq(head, sel.head))
head = skipAtomic(doc, head, bias, checkAtomic != "push");
@@ -29903,32 +29981,35 @@
}
// SCROLLING
function scrollCursorIntoView(cm) {
- var coords = scrollPosIntoView(cm, cm.doc.sel.head, cm.options.cursorScrollMargin);
+ var coords = scrollPosIntoView(cm, cm.doc.sel.head, null, cm.options.cursorScrollMargin);
if (!cm.state.focused) return;
var display = cm.display, box = getRect(display.sizer), doScroll = null;
if (coords.top + box.top < 0) doScroll = true;
else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
if (doScroll != null && !phantom) {
- var hidden = display.cursor.style.display == "none";
- if (hidden) {
- display.cursor.style.display = "";
- display.cursor.style.left = coords.left + "px";
- display.cursor.style.top = (coords.top - display.viewOffset) + "px";
- }
- display.cursor.scrollIntoView(doScroll);
- if (hidden) display.cursor.style.display = "none";
+ var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " +
+ (coords.top - display.viewOffset) + "px; height: " +
+ (coords.bottom - coords.top + scrollerCutOff) + "px; left: " +
+ coords.left + "px; width: 2px;");
+ cm.display.lineSpace.appendChild(scrollNode);
+ scrollNode.scrollIntoView(doScroll);
+ cm.display.lineSpace.removeChild(scrollNode);
}
}
- function scrollPosIntoView(cm, pos, margin) {
+ function scrollPosIntoView(cm, pos, end, margin) {
if (margin == null) margin = 0;
for (;;) {
var changed = false, coords = cursorCoords(cm, pos);
- var scrollPos = calculateScrollPos(cm, coords.left, coords.top - margin, coords.left, coords.bottom + margin);
+ var endCoords = !end || end == pos ? coords : cursorCoords(cm, end);
+ var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left),
+ Math.min(coords.top, endCoords.top) - margin,
+ Math.max(coords.left, endCoords.left),
+ Math.max(coords.bottom, endCoords.bottom) + margin);
var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;
if (scrollPos.scrollTop != null) {
setScrollTop(cm, scrollPos.scrollTop);
if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true;
}
@@ -29985,21 +30066,25 @@
}
// 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 (how == "smart") {
+ if (!aggressive && !/\S/.test(line.text)) {
+ indentation = 0;
+ how = "not";
+ } else if (how == "smart") {
indentation = cm.doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text);
if (indentation == Pass) {
if (!aggressive) return;
how = "prev";
}
@@ -30021,10 +30106,12 @@
for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";}
if (pos < indentation) indentString += spaceStr(indentation - pos);
if (indentString != curSpaceString)
replaceRange(cm.doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input");
+ else if (doc.sel.head.line == n && doc.sel.head.ch < curSpaceString.length)
+ setSelection(doc, Pos(n, curSpaceString.length), Pos(n, curSpaceString.length), 1);
line.stateAfter = null;
}
function changeLine(cm, handle, op) {
var no = handle, line = handle, doc = cm.doc;
@@ -30063,17 +30150,19 @@
var sawType = null, group = unit == "group";
for (var first = true;; first = false) {
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;
}
}
var result = skipAtomic(doc, Pos(line, ch), origDir, true);
@@ -30121,11 +30210,11 @@
// The publicly visible API. Note that operation(null, f) means
// 'wrap f in an operation, performed on its `this` parameter'
CodeMirror.prototype = {
constructor: CodeMirror,
- focus: function(){window.focus(); focusInput(this); onFocus(this); fastPoll(this);},
+ focus: function(){window.focus(); focusInput(this); fastPoll(this);},
setOption: function(option, value) {
var options = this.options, old = options[option];
if (options[option] == value && option != "mode") return;
options[option] = value;
@@ -30175,11 +30264,11 @@
}
if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive);
}),
indentSelection: operation(null, function(how) {
var sel = this.doc.sel;
- if (posEq(sel.from, sel.to)) return indentLine(this, sel.from.line, how);
+ if (posEq(sel.from, sel.to)) return indentLine(this, sel.from.line, how, true);
var e = sel.to.line - (sel.to.ch ? 0 : 1);
for (var i = sel.from.line; i <= e; ++i) indentLine(this, i, how);
}),
// Fetch the parser token for a given character. Useful for hacks
@@ -30220,15 +30309,35 @@
if (!mode.innerMode) return mode;
return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode;
},
getHelper: function(pos, type) {
- if (!helpers.hasOwnProperty(type)) return;
+ return this.getHelpers(pos, type)[0];
+ },
+
+ getHelpers: function(pos, type) {
+ var found = [];
+ if (!helpers.hasOwnProperty(type)) return helpers;
var help = helpers[type], mode = this.getModeAt(pos);
- return mode[type] && help[mode[type]] ||
- mode.helperType && help[mode.helperType] ||
- help[mode.name];
+ if (typeof mode[type] == "string") {
+ if (help[mode[type]]) found.push(help[mode[type]]);
+ } else if (mode[type]) {
+ for (var i = 0; i < mode[type].length; i++) {
+ var val = help[mode[type][i]];
+ if (val) found.push(val);
+ }
+ } else if (mode.helperType && help[mode.helperType]) {
+ found.push(help[mode.helperType]);
+ } else if (help[mode.name]) {
+ found.push(help[mode.name]);
+ }
+ for (var i = 0; i < help._global.length; i++) {
+ var cur = help._global[i];
+ if (cur.pred(mode, this) && indexOf(found, cur.val) == -1)
+ found.push(cur.val);
+ }
+ return found;
},
getStateAfter: function(line, precise) {
var doc = this.doc;
line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);
@@ -30370,12 +30479,17 @@
if (scroll)
scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight);
},
triggerOnKeyDown: operation(null, onKeyDown),
+ triggerOnKeyPress: operation(null, onKeyPress),
+ triggerOnKeyUp: operation(null, onKeyUp),
- execCommand: function(cmd) {return commands[cmd](this);},
+ execCommand: function(cmd) {
+ if (commands.hasOwnProperty(cmd))
+ return commands[cmd](this);
+ },
findPosH: function(from, amount, unit, visually) {
var dir = 1;
if (amount < 0) { dir = -1; amount = -amount; }
for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
@@ -30413,28 +30527,34 @@
}
return cur;
},
moveV: operation(null, function(dir, unit) {
- var sel = this.doc.sel;
- var pos = cursorCoords(this, sel.head, "div");
- if (sel.goalColumn != null) pos.left = sel.goalColumn;
- var target = findPosV(this, pos, dir, unit);
-
- if (unit == "page") addToScrollPos(this, 0, charCoords(this, target, "div").top - pos.top);
+ var sel = this.doc.sel, target, goal;
+ if (sel.shift || sel.extend || posEq(sel.from, sel.to)) {
+ var pos = cursorCoords(this, sel.head, "div");
+ if (sel.goalColumn != null) pos.left = sel.goalColumn;
+ target = findPosV(this, pos, dir, unit);
+ if (unit == "page") addToScrollPos(this, 0, charCoords(this, target, "div").top - pos.top);
+ goal = pos.left;
+ } else {
+ target = dir < 0 ? sel.from : sel.to;
+ }
extendSelection(this.doc, target, target, dir);
- sel.goalColumn = pos.left;
+ if (goal != null) sel.goalColumn = goal;
}),
toggleOverwrite: function(value) {
if (value != null && value == this.state.overwrite) return;
if (this.state.overwrite = !this.state.overwrite)
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);
}),
getScrollInfo: function() {
@@ -30442,21 +30562,27 @@
return {left: scroller.scrollLeft, top: scroller.scrollTop,
height: scroller.scrollHeight - co, width: scroller.scrollWidth - co,
clientHeight: scroller.clientHeight - co, clientWidth: scroller.clientWidth - co};
},
- scrollIntoView: operation(null, function(pos, margin) {
- if (typeof pos == "number") pos = Pos(pos, 0);
+ scrollIntoView: operation(null, function(range, margin) {
+ if (range == null) range = {from: this.doc.sel.head, to: null};
+ else if (typeof range == "number") range = {from: Pos(range, 0), to: null};
+ else if (range.from == null) range = {from: range, to: null};
+ if (!range.to) range.to = range.from;
if (!margin) margin = 0;
- var coords = pos;
- if (!pos || pos.line != null) {
- this.curOp.scrollToPos = pos ? clipPos(this.doc, pos) : this.doc.sel.head;
- this.curOp.scrollToPosMargin = margin;
- coords = cursorCoords(this, this.curOp.scrollToPos);
+ var coords = range;
+ if (range.from.line != null) {
+ this.curOp.scrollToPos = {from: range.from, to: range.to, margin: margin};
+ coords = {from: cursorCoords(this, range.from),
+ to: cursorCoords(this, range.to)};
}
- var sPos = calculateScrollPos(this, coords.left, coords.top - margin, coords.right, coords.bottom + margin);
+ var sPos = calculateScrollPos(this, Math.min(coords.from.left, coords.to.left),
+ Math.min(coords.from.top, coords.to.top) - margin,
+ Math.max(coords.from.right, coords.to.right),
+ Math.max(coords.from.bottom, coords.to.bottom) + margin);
updateScrollPos(this, sPos.scrollLeft, sPos.scrollTop);
}),
setSize: operation(null, function(width, height) {
function interpret(val) {
@@ -30465,27 +30591,33 @@
if (width != null) this.display.wrapper.style.width = interpret(width);
if (height != null) this.display.wrapper.style.height = interpret(height);
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 oldHeight = this.display.cachedTextHeight;
clearCaches(this);
updateScrollPos(this, this.doc.scrollLeft, this.doc.scrollTop);
regChange(this);
+ if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)
+ estimateLineHeights(this);
+ signal(this, "refresh", this);
}),
swapDoc: operation(null, function(doc) {
var old = this.doc;
old.cm = null;
attachDoc(this, doc);
clearCaches(this);
resetInput(this, true);
updateScrollPos(this, doc.scrollLeft, doc.scrollTop);
+ signalLater(this, "swapDoc", this, old);
return old;
}),
getInputField: function(){return this.display.input;},
getWrapperElement: function(){return this.display.wrapper;},
@@ -30521,16 +30653,22 @@
option("indentUnit", 2, loadMode, true);
option("indentWithTabs", false);
option("smartIndent", true);
option("tabSize", 4, function(cm) {
- loadMode(cm);
+ resetModeState(cm);
clearCaches(cm);
regChange(cm);
}, true);
+ option("specialChars", /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\ufeff]/g, function(cm, val) {
+ cm.options.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
+ cm.refresh();
+ }, true);
+ option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true);
option("electricChars", true);
option("rtlMoveVisually", !windows);
+ option("wholeLineUpdateBefore", true);
option("theme", "default", function(cm) {
themeChanged(cm);
guttersChanged(cm);
}, true);
@@ -30556,27 +30694,38 @@
}, true);
option("firstLineNumber", 1, guttersChanged, true);
option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true);
option("showCursorWhenSelecting", false, updateSelection, true);
+ option("resetSelectionOnContextMenu", true);
+
option("readOnly", false, function(cm, val) {
- if (val == "nocursor") {onBlur(cm); cm.display.input.blur();}
- else if (!val) resetInput(cm, true);
+ if (val == "nocursor") {
+ onBlur(cm);
+ cm.display.input.blur();
+ cm.display.disabled = true;
+ } else {
+ cm.display.disabled = false;
+ if (!val) resetInput(cm, true);
+ }
});
+ option("disableInput", false, function(cm, val) {if (!val) resetInput(cm, true);}, true);
option("dragDrop", true);
option("cursorBlinkRate", 530);
option("cursorScrollMargin", 0);
option("cursorHeight", 1);
option("workTime", 100);
option("workDelay", 100);
- option("flattenSpans", true);
+ option("flattenSpans", true, resetModeState, true);
+ option("addModeClass", false, resetModeState, true);
option("pollInterval", 100);
option("undoDepth", 40, function(cm, val){cm.doc.history.undoDepth = val;});
option("historyEventDelay", 500);
option("viewportMargin", 10, function(cm){cm.refresh();}, true);
- option("maxHighlightLength", 10000, function(cm){loadMode(cm); cm.refresh();}, true);
+ option("maxHighlightLength", 10000, resetModeState, true);
+ option("crudeMeasuringFrom", 10000);
option("moveInputWithCursor", true, function(cm, val) {
if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0;
});
option("tabindex", null, function(cm, val) {
@@ -30605,10 +30754,11 @@
CodeMirror.resolveMode = function(spec) {
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
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)) {
return CodeMirror.resolveMode("application/xml");
}
@@ -30628,10 +30778,13 @@
if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop];
modeObj[prop] = exts[prop];
}
}
modeObj.name = spec.name;
+ if (spec.helperType) modeObj.helperType = spec.helperType;
+ if (spec.modeProps) for (var prop in spec.modeProps)
+ modeObj[prop] = spec.modeProps[prop];
return modeObj;
};
CodeMirror.defineMode("null", function() {
@@ -30658,13 +30811,17 @@
var initHooks = [];
CodeMirror.defineInitHook = function(f) {initHooks.push(f);};
var helpers = CodeMirror.helpers = {};
CodeMirror.registerHelper = function(type, name, value) {
- if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {};
+ if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {_global: []};
helpers[type][name] = value;
};
+ CodeMirror.registerGlobalHelper = function(type, name, predicate, value) {
+ CodeMirror.registerHelper(type, name, value);
+ helpers[type]._global.push({pred: predicate, val: value});
+ };
// UTILITIES
CodeMirror.isWordChar = isWordChar;
@@ -30710,11 +30867,11 @@
cm.replaceRange("", from, Pos(from.line + 1, 0), "+delete");
else cm.replaceRange("", from, sel ? to : Pos(from.line), "+delete");
},
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();
cm.replaceRange("", Pos(cur.line, 0), cur, "+delete");
},
@@ -30765,11 +30922,13 @@
delGroupBefore: function(cm) {cm.deleteH(-1, "group");},
delGroupAfter: function(cm) {cm.deleteH(1, "group");},
indentAuto: function(cm) {cm.indentSelection("smart");},
indentMore: function(cm) {cm.indentSelection("add");},
indentLess: function(cm) {cm.indentSelection("subtract");},
- insertTab: function(cm) {cm.replaceSelection("\t", "end", "+input");},
+ insertTab: function(cm) {
+ cm.replaceSelection("\t", "end", "+input");
+ },
defaultTab: function(cm) {
if (cm.somethingSelected()) cm.indentSelection("add");
else cm.replaceSelection("\t", "end", "+input");
},
transposeChars: function(cm) {
@@ -30791,18 +30950,19 @@
var keyMap = CodeMirror.keyMap = {};
keyMap.basic = {
"Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
"End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
- "Delete": "delCharAfter", "Backspace": "delCharBefore", "Tab": "defaultTab", "Shift-Tab": "indentAuto",
+ "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore",
+ "Tab": "defaultTab", "Shift-Tab": "indentAuto",
"Enter": "newlineAndIndent", "Insert": "toggleOverwrite"
};
// Note that the save and find-related commands aren't defined by
// 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",
"Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
fallthrough: "basic"
@@ -30937,15 +31097,16 @@
function StringStream(string, tabSize) {
this.pos = this.start = 0;
this.string = string;
this.tabSize = tabSize || 8;
this.lastColumnPos = this.lastColumnValue = 0;
+ this.lineStart = 0;
}
StringStream.prototype = {
eol: function() {return this.pos >= this.string.length;},
- sol: function() {return this.pos == 0;},
+ sol: function() {return this.pos == this.lineStart;},
peek: function() {return this.string.charAt(this.pos) || undefined;},
next: function() {
if (this.pos < this.string.length)
return this.string.charAt(this.pos++);
},
@@ -30974,13 +31135,16 @@
column: function() {
if (this.lastColumnPos < this.start) {
this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
this.lastColumnPos = this.start;
}
- return this.lastColumnValue;
+ return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
},
- indentation: function() {return countColumn(this.string, null, this.tabSize);},
+ indentation: function() {
+ return countColumn(this.string, null, this.tabSize) -
+ (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
+ },
match: function(pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
var substr = this.string.substr(this.pos, pattern.length);
if (cased(substr) == cased(pattern)) {
@@ -30992,11 +31156,16 @@
if (match && match.index > 0) return null;
if (match && consume !== false) this.pos += match[0].length;
return match;
}
},
- current: function(){return this.string.slice(this.start, this.pos);}
+ current: function(){return this.string.slice(this.start, this.pos);},
+ hideFirstChars: function(n, inner) {
+ this.lineStart += n;
+ try { return inner(); }
+ finally { this.lineStart -= n; }
+ }
};
CodeMirror.StringStream = StringStream;
// TEXTMARKERS
@@ -31044,22 +31213,22 @@
if (cm) reCheckSelection(cm);
}
if (withOp) endOperation(cm);
};
- TextMarker.prototype.find = function() {
+ TextMarker.prototype.find = function(bothSides) {
var from, to;
for (var i = 0; i < this.lines.length; ++i) {
var line = this.lines[i];
var span = getMarkedSpanFor(line.markedSpans, this);
if (span.from != null || span.to != null) {
var found = lineNo(line);
if (span.from != null) from = Pos(found, span.from);
if (span.to != null) to = Pos(found, span.to);
}
}
- if (this.type == "bookmark") return from;
+ if (this.type == "bookmark" && !bothSides) return from;
return from && {from: from, to: to};
};
TextMarker.prototype.changed = function() {
var pos = this.find(), cm = this.doc.cm;
@@ -31092,41 +31261,44 @@
var op = this.doc.cm.curOp;
(op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
}
};
+ var nextMarkerId = 0;
+
function markText(doc, from, to, options, type) {
if (options && options.shared) return markTextShared(doc, from, to, options, type);
if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);
var marker = new TextMarker(doc, type);
- if (type == "range" && !posLess(from, to)) return marker;
if (options) copyObj(options, marker);
+ if (posLess(to, from) || posEq(from, to) && marker.clearWhenEmpty !== false)
+ return marker;
if (marker.replacedWith) {
marker.collapsed = true;
marker.replacedWith = elt("span", [marker.replacedWith], "CodeMirror-widget");
if (!options.handleMouseEvents) marker.replacedWith.ignoreEvents = true;
}
- if (marker.collapsed) sawCollapsedSpans = true;
+ if (marker.collapsed) {
+ if (conflictingCollapsedRange(doc, from.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");
+ sawCollapsedSpans = true;
+ }
if (marker.addToHistory)
addToHistory(doc, {from: from, to: to, origin: "markText"},
{head: doc.sel.head, anchor: doc.sel.anchor}, NaN);
- var curLine = from.line, size = 0, collapsedAtStart, collapsedAtEnd, cm = doc.cm, updateMaxLine;
+ var curLine = from.line, cm = doc.cm, updateMaxLine;
doc.iter(curLine, to.line + 1, function(line) {
if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(doc, line) == cm.display.maxLine)
updateMaxLine = true;
var span = {from: null, to: null, marker: marker};
- size += line.text.length;
- if (curLine == from.line) {span.from = from.ch; size -= from.ch;}
- if (curLine == to.line) {span.to = to.ch; size -= line.text.length - to.ch;}
- if (marker.collapsed) {
- if (curLine == to.line) collapsedAtEnd = collapsedSpanAt(line, to.ch);
- if (curLine == from.line) collapsedAtStart = collapsedSpanAt(line, from.ch);
- else updateLineHeight(line, 0);
- }
+ if (curLine == from.line) span.from = from.ch;
+ if (curLine == to.line) span.to = to.ch;
+ if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0);
addMarkedSpan(line, span);
++curLine;
});
if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) {
if (lineIsHidden(doc, line)) updateLineHeight(line, 0);
@@ -31138,13 +31310,11 @@
sawReadOnlySpans = true;
if (doc.history.done.length || doc.history.undone.length)
doc.clearHistory();
}
if (marker.collapsed) {
- if (collapsedAtStart != collapsedAtEnd)
- throw new Error("Inserting collapsed marker overlapping an existing one");
- marker.size = size;
+ marker.id = ++nextMarkerId;
marker.atomic = true;
}
if (cm) {
if (updateMaxLine) cm.curOp.updateMaxLine = true;
if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.collapsed)
@@ -31213,11 +31383,11 @@
function markedSpansBefore(old, startCh, isInsert) {
if (old) for (var i = 0, nw; i < old.length; ++i) {
var span = old[i], marker = span.marker;
var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
- if (startsBefore || marker.type == "bookmark" && span.from == startCh && (!isInsert || !span.marker.insertLeft)) {
+ if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) {
var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
(nw || (nw = [])).push({from: span.from,
to: endsAfter ? null : span.to,
marker: marker});
}
@@ -31227,11 +31397,11 @@
function markedSpansAfter(old, endCh, isInsert) {
if (old) for (var i = 0, nw; i < old.length; ++i) {
var span = old[i], marker = span.marker;
var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
- if (endsAfter || marker.type == "bookmark" && span.from == endCh && (!isInsert || span.marker.insertLeft)) {
+ if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) {
var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);
(nw || (nw = [])).push({from: startsBefore ? null : span.from - endCh,
to: span.to == null ? null : span.to - endCh,
marker: marker});
}
@@ -31277,17 +31447,13 @@
span.from += offset;
if (sameLine) (first || (first = [])).push(span);
}
}
}
- if (sameLine && first) {
- // Make sure we didn't create any zero-length spans
- for (var i = 0; i < first.length; ++i)
- if (first[i].from != null && first[i].from == first[i].to && first[i].marker.type != "bookmark")
- first.splice(i--, 1);
- if (!first.length) first = null;
- }
+ // Make sure we didn't create any zero-length spans
+ if (first) first = clearEmptySpans(first);
+ if (last && last != first) last = clearEmptySpans(last);
var newMarkers = [first];
if (!sameLine) {
// Fill gap with whole-line-spans
var gap = change.text.length - 2, gapMarkers;
@@ -31300,10 +31466,20 @@
newMarkers.push(last);
}
return newMarkers;
}
+ function clearEmptySpans(spans) {
+ for (var i = 0; i < spans.length; ++i) {
+ var span = spans[i];
+ if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false)
+ spans.splice(i--, 1);
+ }
+ if (!spans.length) return null;
+ return spans;
+ }
+
function mergeOldSpans(doc, change) {
var old = getOldSpans(doc, change);
var stretched = stretchSpansOverChange(doc, change);
if (!old) return stretched;
if (!stretched) return old;
@@ -31350,25 +31526,53 @@
}
}
return parts;
}
- function collapsedSpanAt(line, ch) {
+ function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0; }
+ function extraRight(marker) { return marker.inclusiveRight ? 1 : 0; }
+
+ function compareCollapsedMarkers(a, b) {
+ var lenDiff = a.lines.length - b.lines.length;
+ if (lenDiff != 0) return lenDiff;
+ var aPos = a.find(), bPos = b.find();
+ var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b);
+ if (fromCmp) return -fromCmp;
+ var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b);
+ if (toCmp) return toCmp;
+ return b.id - a.id;
+ }
+
+ function collapsedSpanAtSide(line, start) {
var sps = sawCollapsedSpans && line.markedSpans, found;
if (sps) for (var sp, i = 0; i < sps.length; ++i) {
sp = sps[i];
- if (!sp.marker.collapsed) continue;
- if ((sp.from == null || sp.from < ch) &&
- (sp.to == null || sp.to > ch) &&
- (!found || found.width < sp.marker.width))
+ if (sp.marker.collapsed && (start ? sp.from : sp.to) == null &&
+ (!found || compareCollapsedMarkers(found, sp.marker) < 0))
found = sp.marker;
}
return found;
}
- function collapsedSpanAtStart(line) { return collapsedSpanAt(line, -1); }
- function collapsedSpanAtEnd(line) { return collapsedSpanAt(line, line.text.length + 1); }
+ function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true); }
+ function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false); }
+ function conflictingCollapsedRange(doc, lineNo, from, to, marker) {
+ var line = getLine(doc, lineNo);
+ var sps = sawCollapsedSpans && line.markedSpans;
+ if (sps) for (var i = 0; i < sps.length; ++i) {
+ var sp = sps[i];
+ if (!sp.marker.collapsed) continue;
+ var found = sp.marker.find(true);
+ var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(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 && (cmp(found.to, from) || extraRight(sp.marker) - extraLeft(marker)) > 0 ||
+ fromCmp >= 0 && (cmp(found.from, to) || extraLeft(sp.marker) - extraRight(marker)) < 0)
+ return true;
+ }
+ }
+
function visualLine(doc, line) {
var merged;
while (merged = collapsedSpanAtStart(line))
line = getLine(doc, merged.find().from.line);
return line;
@@ -31393,10 +31597,11 @@
if (span.marker.inclusiveRight && span.to == line.text.length)
return true;
for (var sp, i = 0; i < line.markedSpans.length; ++i) {
sp = line.markedSpans[i];
if (sp.marker.collapsed && !sp.marker.replacedWith && sp.from == span.to &&
+ (sp.to == null || sp.to != span.from) &&
(sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
lineIsHiddenInner(doc, line, sp)) return true;
}
}
@@ -31470,10 +31675,11 @@
widget.line = line;
if (!lineIsHidden(cm.doc, line) || widget.showIfHidden) {
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;
});
return widget;
}
@@ -31486,10 +31692,11 @@
this.text = text;
attachMarkedSpans(this, markedSpans);
this.height = estimateHeight ? estimateHeight(this) : 1;
};
eventMixin(Line);
+ Line.prototype.lineNo = function() { return lineNo(this); };
function updateLine(line, text, markedSpans, estimateHeight) {
line.text = text;
if (line.stateAfter) line.stateAfter = null;
if (line.styles) line.styles = null;
@@ -31506,40 +31713,51 @@
}
// Run the given mode's parser over a line, update the styles
// array, which contains alternating fragments of text and CSS
// classes.
- function runMode(cm, text, mode, state, f) {
+ function runMode(cm, text, mode, state, f, forceToEnd) {
var flattenSpans = mode.flattenSpans;
if (flattenSpans == null) flattenSpans = cm.options.flattenSpans;
var curStart = 0, curStyle = null;
var stream = new StringStream(text, cm.options.tabSize), style;
if (text == "" && mode.blankLine) mode.blankLine(state);
while (!stream.eol()) {
if (stream.pos > cm.options.maxHighlightLength) {
flattenSpans = false;
- // Webkit seems to refuse to render text nodes longer than 57444 characters
- stream.pos = Math.min(text.length, stream.start + 50000);
+ if (forceToEnd) processLine(cm, text, state, stream.pos);
+ stream.pos = text.length;
style = null;
} else {
style = mode.token(stream, state);
}
+ if (cm.options.addModeClass) {
+ var mName = CodeMirror.innerMode(mode, state).mode.name;
+ if (mName) style = "m-" + (style ? mName + " " + style : mName);
+ }
if (!flattenSpans || curStyle != style) {
if (curStart < stream.start) f(stream.start, curStyle);
curStart = stream.start; curStyle = style;
}
stream.start = stream.pos;
}
- if (curStart < stream.pos) f(stream.pos, curStyle);
+ while (curStart < stream.pos) {
+ // Webkit seems to refuse to render text nodes longer than 57444 characters
+ var pos = Math.min(stream.pos, curStart + 50000);
+ f(pos, curStyle);
+ curStart = pos;
+ }
}
- function highlightLine(cm, line, state) {
+ function highlightLine(cm, line, state, forceToEnd) {
// A styles array always starts with a number identifying the
// mode/overlays that it is based on (for easy invalidation).
var st = [cm.state.modeGen];
// Compute the base array of styles
- runMode(cm, line.text, cm.doc.mode, state, function(end, style) {st.push(end, style);});
+ runMode(cm, line.text, cm.doc.mode, state, function(end, style) {
+ st.push(end, style);
+ }, forceToEnd);
// Run overlays, adjust style array.
for (var o = 0; o < cm.state.overlays.length; ++o) {
var overlay = cm.state.overlays[o], i = 1, at = 0;
runMode(cm, line.text, overlay.mode, true, function(end, style) {
@@ -31574,36 +31792,48 @@
return line.styles;
}
// Lightweight form of highlight -- proceed over this line and
// update state, but don't save a style array.
- function processLine(cm, line, state) {
+ function processLine(cm, text, state, startAt) {
var mode = cm.doc.mode;
- var stream = new StringStream(line.text, cm.options.tabSize);
- if (line.text == "" && mode.blankLine) mode.blankLine(state);
+ var stream = new StringStream(text, cm.options.tabSize);
+ stream.start = stream.pos = startAt || 0;
+ if (text == "" && mode.blankLine) mode.blankLine(state);
while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) {
mode.token(stream, state);
stream.start = stream.pos;
}
}
- var styleToClassCache = {};
- function styleToClass(style) {
+ var styleToClassCache = {}, styleToClassCacheWithMode = {};
+ function interpretTokenStyle(style, builder) {
if (!style) return null;
- return styleToClassCache[style] ||
- (styleToClassCache[style] = "cm-" + style.replace(/ +/g, " cm-"));
+ for (;;) {
+ 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";
+ if (builder[prop] == null)
+ builder[prop] = lineClass[2];
+ 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] = style.replace(/\S+/g, "cm-$&"));
}
- function lineContent(cm, realLine, measure, copyWidgets) {
+ function buildLineContent(cm, realLine, measure, copyWidgets) {
var merged, line = realLine, empty = true;
while (merged = collapsedSpanAtStart(line))
line = getLine(cm.doc, merged.find().from.line);
var builder = {pre: elt("pre"), col: 0, pos: 0,
measure: null, measuredSomething: false, cm: cm,
copyWidgets: copyWidgets};
- if (line.textClass) builder.pre.className = line.textClass;
do {
if (line.text) empty = false;
builder.measure = line == realLine && measure;
builder.pos = 0;
@@ -31636,25 +31866,34 @@
if (span) span.parentNode.insertBefore(span.measureRight = zeroWidthElement(cm.display.measure),
span.nextSibling);
}
}
+ var textClass = builder.textClass ? builder.textClass + " " + (realLine.textClass || "") : realLine.textClass;
+ if (textClass) builder.pre.className = textClass;
+
signal(cm, "renderLine", cm, realLine, builder.pre);
- return builder.pre;
+ return builder;
}
- var tokenSpecialChars = /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\uFEFF]/g;
+ function defaultSpecialCharPlaceholder(ch) {
+ var token = elt("span", "\u2022", "cm-invalidchar");
+ token.title = "\\u" + ch.charCodeAt(0).toString(16);
+ return token;
+ }
+
function buildToken(builder, text, style, startStyle, endStyle, title) {
if (!text) return;
- if (!tokenSpecialChars.test(text)) {
+ var special = builder.cm.options.specialChars;
+ if (!special.test(text)) {
builder.col += text.length;
var content = document.createTextNode(text);
} else {
var content = document.createDocumentFragment(), pos = 0;
while (true) {
- tokenSpecialChars.lastIndex = pos;
- var m = tokenSpecialChars.exec(text);
+ special.lastIndex = pos;
+ var m = special.exec(text);
var skipped = m ? m.index - pos : text.length - pos;
if (skipped) {
content.appendChild(document.createTextNode(text.slice(pos, pos + skipped)));
builder.col += skipped;
}
@@ -31663,12 +31902,11 @@
if (m[0] == "\t") {
var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
builder.col += tabWidth;
} else {
- var token = elt("span", "\u2022", "cm-invalidchar");
- token.title = "\\u" + m[0].charCodeAt(0).toString(16);
+ var token = builder.cm.options.specialCharPlaceholder(m[0]);
content.appendChild(token);
builder.col += 1;
}
}
}
@@ -31684,26 +31922,25 @@
}
function buildTokenMeasure(builder, text, style, startStyle, endStyle) {
var wrapping = builder.cm.options.lineWrapping;
for (var i = 0; i < text.length; ++i) {
- var ch = text.charAt(i), start = i == 0;
- if (ch >= "\ud800" && ch < "\udbff" && i < text.length - 1) {
- ch = text.slice(i, i + 2);
- ++i;
- } else if (i && wrapping && spanAffectsWrapping(text, i)) {
+ var start = i == 0, to = i + 1;
+ while (to < text.length && isExtendingChar(text.charAt(to))) ++to;
+ var ch = text.slice(i, to);
+ i = to - 1;
+ if (i && wrapping && spanAffectsWrapping(text, i))
builder.pre.appendChild(elt("wbr"));
- }
var old = builder.measure[builder.pos];
var span = builder.measure[builder.pos] =
buildToken(builder, ch, style,
start && startStyle, i == text.length - 1 && endStyle);
if (old) span.leftSide = old.leftSide || old;
// In IE single-space nodes wrap differently than spaces
// embedded in larger text nodes, except when set to
// white-space: normal (issue #1268).
- if (ie && wrapping && ch == " " && i && !/\s/.test(text.charAt(i - 1)) &&
+ if (old_ie && wrapping && ch == " " && i && !/\s/.test(text.charAt(i - 1)) &&
i < text.length - 1 && !/\s/.test(text.charAt(i + 1)))
span.style.whiteSpace = "normal";
builder.pos += ch.length;
}
if (text.length) builder.measuredSomething = true;
@@ -31715,11 +31952,11 @@
for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0";
out += " ";
return out;
}
return function(builder, text, style, startStyle, endStyle, title) {
- return inner(builder, text.replace(/ {3,}/, split), style, startStyle, endStyle, title);
+ return inner(builder, text.replace(/ {3,}/g, split), style, startStyle, endStyle, title);
};
}
function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
var widget = !ignoreWidget && marker.replacedWith;
@@ -31748,11 +31985,11 @@
// and marked text into account.
function insertLineContent(line, builder, styles) {
var spans = line.markedSpans, allText = line.text, at = 0;
if (!spans) {
for (var i = 1; i < styles.length; i+=2)
- builder.addToken(builder, allText.slice(at, at = styles[i]), styleToClass(styles[i+1]));
+ builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder));
return;
}
var len = allText.length, pos = 0, i = 1, text = "", style;
var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;
@@ -31767,11 +32004,11 @@
if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = ""; }
if (m.className) spanStyle += " " + m.className;
if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle;
if (m.title && !title) title = m.title;
- if (m.collapsed && (!collapsed || collapsed.marker.size < m.size))
+ if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0))
collapsed = sp;
} else if (sp.from > pos && nextChange > sp.from) {
nextChange = sp.from;
}
if (m.type == "bookmark" && sp.from == pos && m.replacedWith) foundBookmarks.push(m);
@@ -31798,11 +32035,11 @@
if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
pos = end;
spanStartStyle = "";
}
text = allText.slice(at, at = styles[i++]);
- style = styleToClass(styles[i++]);
+ style = interpretTokenStyle(styles[i++], builder);
}
}
}
// DOCUMENT DATA STRUCTURE
@@ -31817,11 +32054,12 @@
var from = change.from, to = change.to, text = change.text;
var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
// First adjust the line structure
- if (from.ch == 0 && to.ch == 0 && lastText == "") {
+ if (from.ch == 0 && to.ch == 0 && lastText == "" &&
+ (!doc.cm || doc.cm.options.wholeLineUpdateBefore)) {
// This is a whole-line replace. Treated specially to make
// sure line objects move the way they are supposed to.
for (var i = 0, e = text.length - 1, added = []; i < e; ++i)
added.push(new Line(text[i], spansFor(i), estimateHeight));
update(lastLine, lastLine.text, lastSpans);
@@ -32099,14 +32337,15 @@
return {undo: hist.done.length, redo: hist.undone.length};
},
clearHistory: function() {this.history = makeHistory(this.history.maxGeneration);},
markClean: function() {
- this.cleanGeneration = this.changeGeneration();
+ this.cleanGeneration = this.changeGeneration(true);
},
- changeGeneration: function() {
- this.history.lastOp = this.history.lastOrigin = null;
+ changeGeneration: function(forceSplit) {
+ if (forceSplit)
+ this.history.lastOp = this.history.lastOrigin = null;
return this.history.generation;
},
isClean: function (gen) {
return this.history.generation == (gen || this.cleanGeneration);
},
@@ -32124,11 +32363,12 @@
markText: function(from, to, options) {
return markText(this, clipPos(this, from), clipPos(this, to), options, "range");
},
setBookmark: function(pos, options) {
var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
- insertLeft: options && options.insertLeft};
+ insertLeft: options && options.insertLeft,
+ clearWhenEmpty: false};
pos = clipPos(this, pos);
return markText(this, pos, pos, realOpts, "bookmark");
},
findMarksAt: function(pos) {
pos = clipPos(this, pos);
@@ -32139,10 +32379,26 @@
(span.to == null || span.to >= pos.ch))
markers.push(span.marker.parent || span.marker);
}
return markers;
},
+ findMarks: function(from, to) {
+ from = clipPos(this, from); to = clipPos(this, to);
+ var found = [], lineNo = from.line;
+ this.iter(from.line, to.line + 1, function(line) {
+ var spans = line.markedSpans;
+ 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))
+ found.push(span.marker.parent || span.marker);
+ }
+ ++lineNo;
+ });
+ return found;
+ },
getAllMarks: function() {
var markers = [];
this.iter(function(line) {
var sps = line.markedSpans;
if (sps) for (var i = 0; i < sps.length; ++i)
@@ -32405,17 +32661,19 @@
cur = {changes: [historyChangeFromChange(doc, change)],
generation: hist.generation,
anchorBefore: doc.sel.anchor, headBefore: doc.sel.head,
anchorAfter: selAfter.anchor, headAfter: selAfter.head};
hist.done.push(cur);
- hist.generation = ++hist.maxGeneration;
while (hist.done.length > hist.undoDepth)
hist.done.shift();
}
+ hist.generation = ++hist.maxGeneration;
hist.lastTime = time;
hist.lastOp = opId;
hist.lastOrigin = change.origin;
+
+ if (!last) signal(doc, "historyAdded");
}
function removeClearedSpans(spans) {
if (!spans) return null;
for (var i = 0, out; i < spans.length; ++i) {
@@ -32693,22 +32951,23 @@
function bind(f) {
var args = Array.prototype.slice.call(arguments, 1);
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));
}
function isEmpty(obj) {
for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false;
return true;
}
- var isExtendingChar = /[\u0300-\u036F\u0483-\u0487\u0488-\u0489\u0591-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\uA66F\uA670-\uA672\uA674-\uA67D\uA69F\udc00-\udfff]/;
+ var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;
+ function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch); }
// DOM UTILITIES
function elt(tag, content, className, style) {
var e = document.createElement(tag);
@@ -32766,17 +33025,22 @@
};
else if (safari && !/Version\/([6-9]|\d\d)\b/.test(navigator.userAgent))
spanAffectsWrapping = function(str, i) {
return /\-[^ \-?]|\?[^ !\'\"\),.\-\/:;\?\]\}]/.test(str.slice(i - 1, i + 1));
};
- else if (webkit && !/Chrome\/(?:29|[3-9]\d|\d\d\d)\./.test(navigator.userAgent))
+ else if (webkit && /Chrome\/(?:29|[3-9]\d|\d\d\d)\./.test(navigator.userAgent))
spanAffectsWrapping = function(str, i) {
+ var code = str.charCodeAt(i - 1);
+ return code >= 8208 && code <= 8212;
+ };
+ else if (webkit)
+ spanAffectsWrapping = function(str, i) {
if (i > 1 && str.charCodeAt(i - 1) == 45) {
if (/\w/.test(str.charAt(i - 2)) && /[^\-?\.]/.test(str.charAt(i))) return true;
if (i > 2 && /[\d\.,]/.test(str.charAt(i - 2)) && /[\d\.,]/.test(str.charAt(i))) return false;
}
- return /[~!#%&*)=+}\]|\"\.>,:;][({[<]|-[^\-?\.\u2010-\u201f\u2026]|\?[\w~`@#$%\^&*(_=+{[|><]|…[\w~`@#$%\^&*(_=+{[><]/.test(str.slice(i - 1, i + 1));
+ return /[~!#%&*)=+}\]\\|\"\.>,:;][({[<]|-[^\-?\.\u2010-\u201f\u2026]|\?[\w~`@#$%\^&*(_=+{[|><]|\u2026[\w~`@#$%\^&*(_=+{[><]/.test(str.slice(i - 1, i + 1));
};
var knownScrollbarWidth;
function scrollbarWidth(measure) {
if (knownScrollbarWidth != null) return knownScrollbarWidth;
@@ -32840,18 +33104,18 @@
// KEY NAMING
var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
- 46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod", 109: "-", 107: "=", 127: "Delete",
- 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
- 221: "]", 222: "'", 63276: "PageUp", 63277: "PageDown", 63275: "End", 63273: "Home",
- 63234: "Left", 63232: "Up", 63235: "Right", 63233: "Down", 63302: "Insert", 63272: "Delete"};
+ 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", 107: "=", 109: "-", 127: "Delete",
+ 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
+ 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
+ 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"};
CodeMirror.keyNames = keyNames;
(function() {
// Number keys
- for (var i = 0; i < 10; i++) keyNames[i + 48] = String(i);
+ for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i);
// Alphabetic keys
for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
// Function keys
for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
})();
@@ -32904,33 +33168,33 @@
if (b == linedir) return false;
return a < b;
}
var bidiOther;
function getBidiPartAt(order, pos) {
+ bidiOther = null;
for (var i = 0, found; i < order.length; ++i) {
var cur = order[i];
- if (cur.from < pos && cur.to > pos) { bidiOther = null; return i; }
- if (cur.from == pos || cur.to == pos) {
+ if (cur.from < pos && cur.to > pos) return i;
+ if ((cur.from == pos || cur.to == pos)) {
if (found == null) {
found = i;
} else if (compareBidiLevel(order, cur.level, order[found].level)) {
- bidiOther = found;
+ if (cur.from != cur.to) bidiOther = found;
return i;
} else {
- bidiOther = i;
+ if (cur.from != cur.to) bidiOther = i;
return found;
}
}
}
- bidiOther = null;
return found;
}
function moveInLine(line, pos, dir, byUnit) {
if (!byUnit) return pos + dir;
do pos += dir;
- while (pos > 0 && isExtendingChar.test(line.text.charAt(pos)));
+ while (pos > 0 && isExtendingChar(line.text.charAt(pos)));
return pos;
}
// This is somewhat involved. It is needed in order to move
// 'visually' through bi-directional text -- i.e., pressing left
@@ -32961,11 +33225,11 @@
}
}
function moveLogically(line, start, dir, byUnit) {
var target = start + dir;
- if (byUnit) while (target > 0 && isExtendingChar.test(line.text.charAt(target))) target += dir;
+ if (byUnit) while (target > 0 && isExtendingChar(line.text.charAt(target))) target += dir;
return target < 0 || target > line.text.length ? null : target;
}
// Bidirectional ordering algorithm
// See http://unicode.org/reports/tr9/tr9-13.html for the algorithm
@@ -33053,11 +33317,11 @@
for (var i = 0; i < len; ++i) {
var type = types[i];
if (type == ",") types[i] = "N";
else if (type == "%") {
for (var end = i + 1; end < len && types[end] == "%"; ++end) {}
- var replace = (i && types[i-1] == "!") || (end < len - 1 && types[end] == "1") ? "1" : "N";
+ var replace = (i && types[i-1] == "!") || (end < len && types[end] == "1") ? "1" : "N";
for (var j = i; j < end; ++j) types[j] = replace;
i = end - 1;
}
}
@@ -33078,11 +33342,11 @@
// N2. Any remaining neutrals take the embedding direction.
for (var i = 0; i < len; ++i) {
if (isNeutral.test(types[i])) {
for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {}
var before = (i ? types[i-1] : outerType) == "L";
- var after = (end < len - 1 ? types[end] : outerType) == "L";
+ var after = (end < len ? types[end] : outerType) == "L";
var replace = before || after ? "L" : "R";
for (var j = i; j < end; ++j) types[j] = replace;
i = end - 1;
}
}
@@ -33128,11 +33392,11 @@
};
})();
// THE END
- CodeMirror.version = "3.16.0";
+ CodeMirror.version = "3.22.0";
return CodeMirror;
})();
window.tinyMCEPreInit = window.tinyMCEPreInit || {
base: '/assets/tinymce',
@@ -36256,312 +36520,337 @@
if (base.blankLine) base.blankLine(state.base);
if (overlay.blankLine) overlay.blankLine(state.overlay);
}
};
};
-CodeMirror.defineMode("css", function(config) {
- return CodeMirror.getMode(config, "text/css");
-});
-
-CodeMirror.defineMode("css-base", function(config, parserConfig) {
+CodeMirror.defineMode("css", function(config, parserConfig) {
"use strict";
+ if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
+
var indentUnit = config.indentUnit,
- hooks = parserConfig.hooks || {},
- atMediaTypes = parserConfig.atMediaTypes || {},
- atMediaFeatures = parserConfig.atMediaFeatures || {},
+ tokenHooks = parserConfig.tokenHooks,
+ mediaTypes = parserConfig.mediaTypes || {},
+ mediaFeatures = parserConfig.mediaFeatures || {},
propertyKeywords = parserConfig.propertyKeywords || {},
colorKeywords = parserConfig.colorKeywords || {},
valueKeywords = parserConfig.valueKeywords || {},
- allowNested = !!parserConfig.allowNested,
- type = null;
+ fontProperties = parserConfig.fontProperties || {},
+ allowNested = parserConfig.allowNested;
+ var type, override;
function ret(style, tp) { type = tp; return style; }
+ // Tokenizers
+
function tokenBase(stream, state) {
var ch = stream.next();
- if (hooks[ch]) {
- // result[0] is style and result[1] is type
- var result = hooks[ch](stream, state);
+ if (tokenHooks[ch]) {
+ var result = tokenHooks[ch](stream, state);
if (result !== false) return result;
}
- if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("def", stream.current());}
- else if (ch == "=") ret(null, "compare");
- else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
- else if (ch == "\"" || ch == "'") {
+ if (ch == "@") {
+ stream.eatWhile(/[\w\\\-]/);
+ return ret("def", stream.current());
+ } else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
+ return ret(null, "compare");
+ } else if (ch == "\"" || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
- }
- else if (ch == "#") {
+ } else if (ch == "#") {
stream.eatWhile(/[\w\\\-]/);
return ret("atom", "hash");
- }
- else if (ch == "!") {
+ } else if (ch == "!") {
stream.match(/^\s*\w*/);
return ret("keyword", "important");
- }
- else if (/\d/.test(ch)) {
+ } else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
stream.eatWhile(/[\w.%]/);
return ret("number", "unit");
- }
- else if (ch === "-") {
- if (/\d/.test(stream.peek())) {
+ } else if (ch === "-") {
+ if (/[\d.]/.test(stream.peek())) {
stream.eatWhile(/[\w.%]/);
return ret("number", "unit");
} else if (stream.match(/^[^-]+-/)) {
return ret("meta", "meta");
}
- }
- else if (/[,+>*\/]/.test(ch)) {
+ } else if (/[,+>*\/]/.test(ch)) {
return ret(null, "select-op");
- }
- else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
+ } else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
return ret("qualifier", "qualifier");
- }
- else if (ch == ":") {
- return ret("operator", ch);
- }
- else if (/[;{}\[\]\(\)]/.test(ch)) {
+ } else if (/[:;{}\[\]\(\)]/.test(ch)) {
return ret(null, ch);
- }
- else if (ch == "u" && stream.match("rl(")) {
+ } else if (ch == "u" && stream.match("rl(")) {
stream.backUp(1);
state.tokenize = tokenParenthesized;
- return ret("property", "variable");
- }
- else {
+ return ret("property", "word");
+ } else if (/[\w\\\-]/.test(ch)) {
stream.eatWhile(/[\w\\\-]/);
- return ret("property", "variable");
+ return ret("property", "word");
+ } else {
+ return ret(null, null);
}
}
- function tokenString(quote, nonInclusive) {
+ function tokenString(quote) {
return function(stream, state) {
var escaped = false, ch;
while ((ch = stream.next()) != null) {
- if (ch == quote && !escaped)
+ if (ch == quote && !escaped) {
+ if (quote == ")") stream.backUp(1);
break;
+ }
escaped = !escaped && ch == "\\";
}
- if (!escaped) {
- if (nonInclusive) stream.backUp(1);
- state.tokenize = tokenBase;
- }
+ if (ch == quote || !escaped && quote != ")") state.tokenize = null;
return ret("string", "string");
};
}
function tokenParenthesized(stream, state) {
stream.next(); // Must be '('
if (!stream.match(/\s*[\"\']/, false))
- state.tokenize = tokenString(")", true);
+ state.tokenize = tokenString(")");
else
- state.tokenize = tokenBase;
+ state.tokenize = null;
return ret(null, "(");
}
- return {
- startState: function(base) {
- return {tokenize: tokenBase,
- baseIndent: base || 0,
- stack: [],
- lastToken: null};
- },
+ // Context management
- token: function(stream, state) {
+ function Context(type, indent, prev) {
+ this.type = type;
+ this.indent = indent;
+ this.prev = prev;
+ }
- // Use these terms when applicable (see http://www.xanthir.com/blog/b4E50)
- //
- // rule** or **ruleset:
- // A selector + braces combo, or an at-rule.
- //
- // declaration block:
- // A sequence of declarations.
- //
- // declaration:
- // A property + colon + value combo.
- //
- // property value:
- // The entire value of a property.
- //
- // component value:
- // A single piece of a property value. Like the 5px in
- // text-shadow: 0 0 5px blue;. Can also refer to things that are
- // multiple terms, like the 1-4 terms that make up the background-size
- // portion of the background shorthand.
- //
- // term:
- // The basic unit of author-facing CSS, like a single number (5),
- // dimension (5px), string ("foo"), or function. Officially defined
- // by the CSS 2.1 grammar (look for the 'term' production)
- //
- //
- // simple selector:
- // A single atomic selector, like a type selector, an attr selector, a
- // class selector, etc.
- //
- // compound selector:
- // One or more simple selectors without a combinator. div.example is
- // compound, div > .example is not.
- //
- // complex selector:
- // One or more compound selectors chained with combinators.
- //
- // combinator:
- // The parts of selectors that express relationships. There are four
- // currently - the space (descendant combinator), the greater-than
- // bracket (child combinator), the plus sign (next sibling combinator),
- // and the tilda (following sibling combinator).
- //
- // sequence of selectors:
- // One or more of the named type of selector chained with commas.
+ function pushContext(state, stream, type) {
+ state.context = new Context(type, stream.indentation() + indentUnit, state.context);
+ return type;
+ }
- state.tokenize = state.tokenize || tokenBase;
- if (state.tokenize == tokenBase && stream.eatSpace()) return null;
- var style = state.tokenize(stream, state);
- if (style && typeof style != "string") style = ret(style[0], style[1]);
+ function popContext(state) {
+ state.context = state.context.prev;
+ return state.context.type;
+ }
- // Changing style returned based on context
- var context = state.stack[state.stack.length-1];
- if (style == "variable") {
- if (type == "variable-definition") state.stack.push("propertyValue");
- return state.lastToken = "variable-2";
- } else if (style == "property") {
- var word = stream.current().toLowerCase();
- if (context == "propertyValue") {
- if (valueKeywords.hasOwnProperty(word)) {
- style = "string-2";
- } else if (colorKeywords.hasOwnProperty(word)) {
- style = "keyword";
- } else {
- style = "variable-2";
- }
- } else if (context == "rule") {
- if (!propertyKeywords.hasOwnProperty(word)) {
- style += " error";
- }
- } else if (context == "block") {
- // if a value is present in both property, value, or color, the order
- // of preference is property -> color -> value
- if (propertyKeywords.hasOwnProperty(word)) {
- style = "property";
- } else if (colorKeywords.hasOwnProperty(word)) {
- style = "keyword";
- } else if (valueKeywords.hasOwnProperty(word)) {
- style = "string-2";
- } else {
- style = "tag";
- }
- } else if (!context || context == "@media{") {
- style = "tag";
- } else if (context == "@media") {
- if (atMediaTypes[stream.current()]) {
- style = "attribute"; // Known attribute
- } else if (/^(only|not)$/.test(word)) {
- style = "keyword";
- } else if (word == "and") {
- style = "error"; // "and" is only allowed in @mediaType
- } else if (atMediaFeatures.hasOwnProperty(word)) {
- style = "error"; // Known property, should be in @mediaType(
- } else {
- // Unknown, expecting keyword or attribute, assuming attribute
- style = "attribute error";
- }
- } else if (context == "@mediaType") {
- if (atMediaTypes.hasOwnProperty(word)) {
- style = "attribute";
- } else if (word == "and") {
- style = "operator";
- } else if (/^(only|not)$/.test(word)) {
- style = "error"; // Only allowed in @media
- } else {
- // Unknown attribute or property, but expecting property (preceded
- // by "and"). Should be in parentheses
- style = "error";
- }
- } else if (context == "@mediaType(") {
- if (propertyKeywords.hasOwnProperty(word)) {
- // do nothing, remains "property"
- } else if (atMediaTypes.hasOwnProperty(word)) {
- style = "error"; // Known property, should be in parentheses
- } else if (word == "and") {
- style = "operator";
- } else if (/^(only|not)$/.test(word)) {
- style = "error"; // Only allowed in @media
- } else {
- style += " error";
- }
- } else if (context == "@import") {
- style = "tag";
- } else {
- style = "error";
- }
- } else if (style == "atom") {
- if(!context || context == "@media{" || context == "block") {
- style = "builtin";
- } else if (context == "propertyValue") {
- if (!/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
- style += " error";
- }
- } else {
- style = "error";
- }
- } else if (context == "@media" && type == "{") {
- style = "error";
- }
+ function pass(type, stream, state) {
+ return states[state.context.type](type, stream, state);
+ }
+ function popAndPass(type, stream, state, n) {
+ for (var i = n || 1; i > 0; i--)
+ state.context = state.context.prev;
+ return pass(type, stream, state);
+ }
- // Push/pop context stack
- if (type == "{") {
- if (context == "@media" || context == "@mediaType") {
- state.stack[state.stack.length-1] = "@media{";
- }
- else {
- var newContext = allowNested ? "block" : "rule";
- state.stack.push(newContext);
- }
+ // Parser
+
+ function wordAsValue(stream) {
+ var word = stream.current().toLowerCase();
+ if (valueKeywords.hasOwnProperty(word))
+ override = "atom";
+ else if (colorKeywords.hasOwnProperty(word))
+ override = "keyword";
+ else
+ override = "variable";
+ }
+
+ var states = {};
+
+ states.top = function(type, stream, state) {
+ if (type == "{") {
+ return pushContext(state, stream, "block");
+ } else if (type == "}" && state.context.prev) {
+ return popContext(state);
+ } else if (type == "@media") {
+ return pushContext(state, stream, "media");
+ } else if (type == "@font-face") {
+ return "font_face_before";
+ } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) {
+ return "keyframes";
+ } else if (type && type.charAt(0) == "@") {
+ return pushContext(state, stream, "at");
+ } else if (type == "hash") {
+ override = "builtin";
+ } else if (type == "word") {
+ override = "tag";
+ } else if (type == "variable-definition") {
+ return "maybeprop";
+ } else if (type == "interpolation") {
+ return pushContext(state, stream, "interpolation");
+ } else if (type == ":") {
+ return "pseudo";
+ } else if (allowNested && type == "(") {
+ return pushContext(state, stream, "params");
+ }
+ return state.context.type;
+ };
+
+ states.block = function(type, stream, state) {
+ if (type == "word") {
+ if (propertyKeywords.hasOwnProperty(stream.current().toLowerCase())) {
+ override = "property";
+ return "maybeprop";
+ } else if (allowNested) {
+ override = stream.match(/^\s*:/, false) ? "property" : "tag";
+ return "block";
+ } else {
+ override += " error";
+ return "maybeprop";
}
- else if (type == "}") {
- if (context == "interpolation") style = "operator";
- state.stack.pop();
- if (context == "propertyValue") state.stack.pop();
- }
- else if (type == "interpolation") state.stack.push("interpolation");
- else if (type == "@media") state.stack.push("@media");
- else if (type == "@import") state.stack.push("@import");
- else if (context == "@media" && /\b(keyword|attribute)\b/.test(style))
- state.stack[state.stack.length-1] = "@mediaType";
- else if (context == "@mediaType" && stream.current() == ",")
- state.stack[state.stack.length-1] = "@media";
- else if (type == "(") {
- if (context == "@media" || context == "@mediaType") {
- // Make sure @mediaType is used to avoid error on {
- state.stack[state.stack.length-1] = "@mediaType";
- state.stack.push("@mediaType(");
- }
- }
- else if (type == ")") {
- if (context == "propertyValue" && state.stack[state.stack.length-2] == "@mediaType(") {
- // In @mediaType( without closing ; after propertyValue
- state.stack.pop();
- state.stack.pop();
- }
- else if (context == "@mediaType(") {
- state.stack.pop();
- }
- }
- else if (type == ":" && state.lastToken == "property") state.stack.push("propertyValue");
- else if (context == "propertyValue" && type == ";") state.stack.pop();
- else if (context == "@import" && type == ";") state.stack.pop();
+ } else if (type == "meta") {
+ return "block";
+ } else if (!allowNested && (type == "hash" || type == "qualifier")) {
+ override = "error";
+ return "block";
+ } else {
+ return states.top(type, stream, state);
+ }
+ };
- return state.lastToken = style;
+ states.maybeprop = function(type, stream, state) {
+ if (type == ":") return pushContext(state, stream, "prop");
+ return pass(type, stream, state);
+ };
+
+ states.prop = function(type, stream, state) {
+ if (type == ";") return popContext(state);
+ if (type == "{" && allowNested) return pushContext(state, stream, "propBlock");
+ if (type == "}" || type == "{") return popAndPass(type, stream, state);
+ if (type == "(") return pushContext(state, stream, "parens");
+
+ if (type == "hash" && !/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
+ override += " error";
+ } else if (type == "word") {
+ wordAsValue(stream);
+ } else if (type == "interpolation") {
+ return pushContext(state, stream, "interpolation");
+ }
+ return "prop";
+ };
+
+ states.propBlock = function(type, _stream, state) {
+ if (type == "}") return popContext(state);
+ if (type == "word") { override = "property"; return "maybeprop"; }
+ return state.context.type;
+ };
+
+ states.parens = function(type, stream, state) {
+ if (type == "{" || type == "}") return popAndPass(type, stream, state);
+ if (type == ")") return popContext(state);
+ return "parens";
+ };
+
+ states.pseudo = function(type, stream, state) {
+ if (type == "word") {
+ override = "variable-3";
+ return state.context.type;
+ }
+ return pass(type, stream, state);
+ };
+
+ states.media = function(type, stream, state) {
+ if (type == "(") return pushContext(state, stream, "media_parens");
+ if (type == "}") return popAndPass(type, stream, state);
+ if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
+
+ if (type == "word") {
+ var word = stream.current().toLowerCase();
+ if (word == "only" || word == "not" || word == "and")
+ override = "keyword";
+ else if (mediaTypes.hasOwnProperty(word))
+ override = "attribute";
+ else if (mediaFeatures.hasOwnProperty(word))
+ override = "property";
+ else
+ override = "error";
+ }
+ return state.context.type;
+ };
+
+ states.media_parens = function(type, stream, state) {
+ if (type == ")") return popContext(state);
+ if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
+ return states.media(type, stream, state);
+ };
+
+ states.font_face_before = function(type, stream, state) {
+ if (type == "{")
+ return pushContext(state, stream, "font_face");
+ return pass(type, stream, state);
+ };
+
+ states.font_face = function(type, stream, state) {
+ if (type == "}") return popContext(state);
+ if (type == "word") {
+ if (!fontProperties.hasOwnProperty(stream.current().toLowerCase()))
+ override = "error";
+ else
+ override = "property";
+ return "maybeprop";
+ }
+ return "font_face";
+ };
+
+ states.keyframes = function(type, stream, state) {
+ if (type == "word") { override = "variable"; return "keyframes"; }
+ if (type == "{") return pushContext(state, stream, "top");
+ return pass(type, stream, state);
+ };
+
+ states.at = function(type, stream, state) {
+ if (type == ";") return popContext(state);
+ if (type == "{" || type == "}") return popAndPass(type, stream, state);
+ if (type == "word") override = "tag";
+ else if (type == "hash") override = "builtin";
+ return "at";
+ };
+
+ states.interpolation = function(type, stream, state) {
+ if (type == "}") return popContext(state);
+ if (type == "{" || type == ";") return popAndPass(type, stream, state);
+ if (type != "variable") override = "error";
+ return "interpolation";
+ };
+
+ states.params = function(type, stream, state) {
+ if (type == ")") return popContext(state);
+ if (type == "{" || type == "}") return popAndPass(type, stream, state);
+ if (type == "word") wordAsValue(stream);
+ return "params";
+ };
+
+ return {
+ startState: function(base) {
+ return {tokenize: null,
+ state: "top",
+ context: new Context("top", base || 0, null)};
},
+ token: function(stream, state) {
+ if (!state.tokenize && stream.eatSpace()) return null;
+ var style = (state.tokenize || tokenBase)(stream, state);
+ if (style && typeof style == "object") {
+ type = style[1];
+ style = style[0];
+ }
+ override = style;
+ state.state = states[state.state](type, stream, state);
+ return override;
+ },
+
indent: function(state, textAfter) {
- var n = state.stack.length;
- if (/^\}/.test(textAfter))
- n -= state.stack[n-1] == "propertyValue" ? 2 : 1;
- return state.baseIndent + n * indentUnit;
+ var cx = state.context, ch = textAfter && textAfter.charAt(0);
+ var indent = cx.indent;
+ if (cx.type == "prop" && ch == "}") cx = cx.prev;
+ if (cx.prev &&
+ (ch == "}" && (cx.type == "block" || cx.type == "top" || cx.type == "interpolation" || cx.type == "font_face") ||
+ ch == ")" && (cx.type == "parens" || cx.type == "params" || cx.type == "media_parens") ||
+ ch == "{" && (cx.type == "at" || cx.type == "media"))) {
+ indent = cx.indent - indentUnit;
+ cx = cx.prev;
+ }
+ return indent;
},
electricChars: "}",
blockCommentStart: "/*",
blockCommentEnd: "*/",
@@ -36576,33 +36865,33 @@
keys[array[i]] = true;
}
return keys;
}
- var atMediaTypes = keySet([
+ var mediaTypes_ = [
"all", "aural", "braille", "handheld", "print", "projection", "screen",
"tty", "tv", "embossed"
- ]);
+ ], mediaTypes = keySet(mediaTypes_);
- var atMediaFeatures = keySet([
+ var mediaFeatures_ = [
"width", "min-width", "max-width", "height", "min-height", "max-height",
"device-width", "min-device-width", "max-device-width", "device-height",
"min-device-height", "max-device-height", "aspect-ratio",
"min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
"min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
"max-color", "color-index", "min-color-index", "max-color-index",
"monochrome", "min-monochrome", "max-monochrome", "resolution",
"min-resolution", "max-resolution", "scan", "grid"
- ]);
+ ], mediaFeatures = keySet(mediaFeatures_);
- var propertyKeywords = keySet([
+ var propertyKeywords_ = [
"align-content", "align-items", "align-self", "alignment-adjust",
"alignment-baseline", "anchor-point", "animation", "animation-delay",
- "animation-direction", "animation-duration", "animation-iteration-count",
- "animation-name", "animation-play-state", "animation-timing-function",
- "appearance", "azimuth", "backface-visibility", "background",
- "background-attachment", "background-clip", "background-color",
+ "animation-direction", "animation-duration", "animation-fill-mode",
+ "animation-iteration-count", "animation-name", "animation-play-state",
+ "animation-timing-function", "appearance", "azimuth", "backface-visibility",
+ "background", "background-attachment", "background-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",
@@ -36629,14 +36918,15 @@
"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-cell", "grid-column", "grid-column-align",
- "grid-column-sizing", "grid-column-span", "grid-columns", "grid-flow",
- "grid-row", "grid-row-align", "grid-row-sizing", "grid-row-span",
- "grid-rows", "grid-template", "hanging-punctuation", "height", "hyphens",
+ "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
+ "grid-auto-position", "grid-auto-rows", "grid-column", "grid-column-end",
+ "grid-column-start", "grid-row", "grid-row-end", "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",
"line-stacking-shift", "line-stacking-strategy", "list-style",
"list-style-image", "list-style-position", "list-style-type", "margin",
@@ -36680,13 +36970,13 @@
"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"
- ]);
+ ], propertyKeywords = keySet(propertyKeywords_);
- var colorKeywords = keySet([
+ var colorKeywords_ = [
"aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
"bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
"burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
"cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
"darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
@@ -36709,13 +36999,13 @@
"purple", "red", "rosybrown", "royalblue", "saddlebrown", "salmon",
"sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
"slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
"teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
"whitesmoke", "yellow", "yellowgreen"
- ]);
+ ], colorKeywords = keySet(colorKeywords_);
- var valueKeywords = keySet([
+ var valueKeywords_ = [
"above", "absolute", "activeborder", "activecaption", "afar",
"after-white-space", "ahead", "alias", "all", "all-scroll", "alternate",
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
"arabic-indic", "armenian", "asterisks", "auto", "avoid", "avoid-column", "avoid-page",
"avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
@@ -36794,12 +37084,20 @@
"upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
"vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
"visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
"window", "windowframe", "windowtext", "x-large", "x-small", "xor",
"xx-large", "xx-small"
- ]);
+ ], valueKeywords = keySet(valueKeywords_);
+ var fontProperties_ = [
+ "font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
+ "font-stretch", "font-weight", "font-style"
+ ], fontProperties = keySet(fontProperties_);
+
+ var allWords = mediaTypes_.concat(mediaFeatures_).concat(propertyKeywords_).concat(colorKeywords_).concat(valueKeywords_);
+ CodeMirror.registerHelper("hintWords", "css", allWords);
+
function tokenCComment(stream, state) {
var maybeEnd = false, ch;
while ((ch = stream.next()) != null) {
if (maybeEnd && ch == "/") {
state.tokenize = null;
@@ -36808,60 +37106,51 @@
maybeEnd = (ch == "*");
}
return ["comment", "comment"];
}
+ function tokenSGMLComment(stream, state) {
+ if (stream.skipTo("-->")) {
+ stream.match("-->");
+ state.tokenize = null;
+ } else {
+ stream.skipToEnd();
+ }
+ return ["comment", "comment"];
+ }
+
CodeMirror.defineMIME("text/css", {
- atMediaTypes: atMediaTypes,
- atMediaFeatures: atMediaFeatures,
+ mediaTypes: mediaTypes,
+ mediaFeatures: mediaFeatures,
propertyKeywords: propertyKeywords,
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
- hooks: {
+ fontProperties: fontProperties,
+ tokenHooks: {
"<": function(stream, state) {
- function tokenSGMLComment(stream, state) {
- var dashes = 0, ch;
- while ((ch = stream.next()) != null) {
- if (dashes >= 2 && ch == ">") {
- state.tokenize = null;
- break;
- }
- dashes = (ch == "-") ? dashes + 1 : 0;
- }
- return ["comment", "comment"];
- }
- if (stream.eat("!")) {
- state.tokenize = tokenSGMLComment;
- return tokenSGMLComment(stream, state);
- }
+ if (!stream.match("!--")) return false;
+ state.tokenize = tokenSGMLComment;
+ return tokenSGMLComment(stream, state);
},
"/": function(stream, state) {
- if (stream.eat("*")) {
- state.tokenize = tokenCComment;
- return tokenCComment(stream, state);
- }
- return false;
+ if (!stream.eat("*")) return false;
+ state.tokenize = tokenCComment;
+ return tokenCComment(stream, state);
}
},
- name: "css-base"
+ name: "css"
});
CodeMirror.defineMIME("text/x-scss", {
- atMediaTypes: atMediaTypes,
- atMediaFeatures: atMediaFeatures,
+ mediaTypes: mediaTypes,
+ mediaFeatures: mediaFeatures,
propertyKeywords: propertyKeywords,
colorKeywords: colorKeywords,
valueKeywords: valueKeywords,
+ fontProperties: fontProperties,
allowNested: true,
- hooks: {
- "$": function(stream) {
- stream.match(/^[\w-]+/);
- if (stream.peek() == ":") {
- return ["variable", "variable-definition"];
- }
- return ["variable", "variable"];
- },
+ tokenHooks: {
"/": function(stream, state) {
if (stream.eat("/")) {
stream.skipToEnd();
return ["comment", "comment"];
} else if (stream.eat("*")) {
@@ -36869,28 +37158,72 @@
return tokenCComment(stream, state);
} else {
return ["operator", "operator"];
}
},
+ ":": function(stream) {
+ if (stream.match(/\s*{/))
+ return [null, "{"];
+ return false;
+ },
+ "$": function(stream) {
+ stream.match(/^[\w-]+/);
+ if (stream.match(/^\s*:/, false))
+ return ["variable-2", "variable-definition"];
+ return ["variable-2", "variable"];
+ },
"#": function(stream) {
- if (stream.eat("{")) {
- return ["operator", "interpolation"];
+ if (!stream.eat("{")) return false;
+ return [null, "interpolation"];
+ }
+ },
+ name: "css",
+ helperType: "scss"
+ });
+
+ CodeMirror.defineMIME("text/x-less", {
+ mediaTypes: mediaTypes,
+ mediaFeatures: mediaFeatures,
+ propertyKeywords: propertyKeywords,
+ colorKeywords: colorKeywords,
+ valueKeywords: valueKeywords,
+ fontProperties: fontProperties,
+ allowNested: true,
+ tokenHooks: {
+ "/": function(stream, state) {
+ if (stream.eat("/")) {
+ stream.skipToEnd();
+ return ["comment", "comment"];
+ } else if (stream.eat("*")) {
+ state.tokenize = tokenCComment;
+ return tokenCComment(stream, state);
} else {
- stream.eatWhile(/[\w\\\-]/);
- return ["atom", "hash"];
+ return ["operator", "operator"];
}
+ },
+ "@": function(stream) {
+ if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false;
+ stream.eatWhile(/[\w\\\-]/);
+ if (stream.match(/^\s*:/, false))
+ return ["variable-2", "variable-definition"];
+ return ["variable-2", "variable"];
+ },
+ "&": function() {
+ return ["atom", "atom"];
}
},
- name: "css-base"
+ name: "css",
+ helperType: "less"
});
})();
// TODO actually recognize syntax of TypeScript constructs
CodeMirror.defineMode("javascript", function(config, parserConfig) {
var indentUnit = config.indentUnit;
var statementIndent = parserConfig.statementIndent;
- var jsonMode = parserConfig.json;
+ var jsonldMode = parserConfig.jsonld;
+ var jsonMode = parserConfig.json || jsonldMode;
var isTS = parserConfig.typescript;
// Tokenizer
var keywords = function(){
@@ -36898,37 +37231,35 @@
var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
var operator = kw("operator"), atom = {type: "atom", style: "atom"};
var jsKeywords = {
"if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
- "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C,
+ "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C,
"var": kw("var"), "const": kw("var"), "let": kw("var"),
"function": kw("function"), "catch": kw("catch"),
"for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
"in": operator, "typeof": operator, "instanceof": operator,
"true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
- "this": kw("this")
+ "this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"),
+ "yield": C, "export": kw("export"), "import": kw("import"), "extends": 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("interface"),
- "class": kw("class"),
"extends": kw("extends"),
"constructor": kw("constructor"),
// scope modifiers
"public": kw("public"),
"private": kw("private"),
"protected": kw("protected"),
"static": kw("static"),
- "super": kw("super"),
-
// types
"string": type, "number": type, "bool": type, "any": type
};
for (var attr in tsKeywords) {
@@ -36938,107 +37269,158 @@
return jsKeywords;
}();
var isOperatorChar = /[+\-*&%=<>!?|~^]/;
+ var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
- function chain(stream, state, f) {
- state.tokenize = f;
- return f(stream, state);
- }
-
- function nextUntilUnescaped(stream, end) {
- var escaped = false, next;
+ function readRegexp(stream) {
+ var escaped = false, next, inSet = false;
while ((next = stream.next()) != null) {
- if (next == end && !escaped)
- return false;
+ if (!escaped) {
+ if (next == "/" && !inSet) return;
+ if (next == "[") inSet = true;
+ else if (inSet && next == "]") inSet = false;
+ }
escaped = !escaped && next == "\\";
}
- return escaped;
}
// Used as scratch variables to communicate multiple values without
// consing up tons of objects.
var type, content;
function ret(tp, style, cont) {
type = tp; content = cont;
return style;
}
- function jsTokenBase(stream, state) {
+ function tokenBase(stream, state) {
var ch = stream.next();
- if (ch == '"' || ch == "'")
- return chain(stream, state, jsTokenString(ch));
- else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/))
+ if (ch == '"' || ch == "'") {
+ state.tokenize = tokenString(ch);
+ return state.tokenize(stream, state);
+ } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
return ret("number", "number");
- else if (/[\[\]{}\(\),;\:\.]/.test(ch))
+ } else if (ch == "." && stream.match("..")) {
+ return ret("spread", "meta");
+ } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
return ret(ch);
- else if (ch == "0" && stream.eat(/x/i)) {
+ } else if (ch == "=" && stream.eat(">")) {
+ return ret("=>", "operator");
+ } else if (ch == "0" && stream.eat(/x/i)) {
stream.eatWhile(/[\da-f]/i);
return ret("number", "number");
- }
- else if (/\d/.test(ch)) {
+ } else if (/\d/.test(ch)) {
stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
return ret("number", "number");
- }
- else if (ch == "/") {
+ } else if (ch == "/") {
if (stream.eat("*")) {
- return chain(stream, state, jsTokenComment);
- }
- else if (stream.eat("/")) {
+ state.tokenize = tokenComment;
+ return tokenComment(stream, state);
+ } else if (stream.eat("/")) {
stream.skipToEnd();
return ret("comment", "comment");
- }
- else if (state.lastType == "operator" || state.lastType == "keyword c" ||
- /^[\[{}\(,;:]$/.test(state.lastType)) {
- nextUntilUnescaped(stream, "/");
+ } else if (state.lastType == "operator" || state.lastType == "keyword c" ||
+ state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
+ readRegexp(stream);
stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
return ret("regexp", "string-2");
- }
- else {
+ } else {
stream.eatWhile(isOperatorChar);
- return ret("operator", null, stream.current());
+ return ret("operator", "operator", stream.current());
}
- }
- else if (ch == "#") {
+ } else if (ch == "`") {
+ state.tokenize = tokenQuasi;
+ return tokenQuasi(stream, state);
+ } else if (ch == "#") {
stream.skipToEnd();
return ret("error", "error");
- }
- else if (isOperatorChar.test(ch)) {
+ } else if (isOperatorChar.test(ch)) {
stream.eatWhile(isOperatorChar);
- return ret("operator", null, stream.current());
- }
- else {
+ return ret("operator", "operator", stream.current());
+ } else {
stream.eatWhile(/[\w\$_]/);
var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
ret("variable", "variable", word);
}
}
- function jsTokenString(quote) {
+ function tokenString(quote) {
return function(stream, state) {
- if (!nextUntilUnescaped(stream, quote))
- state.tokenize = jsTokenBase;
+ var escaped = false, next;
+ if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){
+ state.tokenize = tokenBase;
+ return ret("jsonld-keyword", "meta");
+ }
+ while ((next = stream.next()) != null) {
+ if (next == quote && !escaped) break;
+ escaped = !escaped && next == "\\";
+ }
+ if (!escaped) state.tokenize = tokenBase;
return ret("string", "string");
};
}
- function jsTokenComment(stream, state) {
+ function tokenComment(stream, state) {
var maybeEnd = false, ch;
while (ch = stream.next()) {
if (ch == "/" && maybeEnd) {
- state.tokenize = jsTokenBase;
+ state.tokenize = tokenBase;
break;
}
maybeEnd = (ch == "*");
}
return ret("comment", "comment");
}
+ function tokenQuasi(stream, state) {
+ var escaped = false, next;
+ while ((next = stream.next()) != null) {
+ if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
+ state.tokenize = tokenBase;
+ break;
+ }
+ escaped = !escaped && next == "\\";
+ }
+ return ret("quasi", "string-2", stream.current());
+ }
+
+ var brackets = "([{}])";
+ // This is a crude lookahead trick to try and notice that we're
+ // parsing the argument patterns for a fat-arrow function before we
+ // actually hit the arrow token. It only works if the arrow is on
+ // the same line as the arguments and there's no strange noise
+ // (comments) in between. Fallback is to only notice when we hit the
+ // arrow, and not declare the arguments as locals for the arrow
+ // body.
+ function findFatArrow(stream, state) {
+ if (state.fatArrowAt) state.fatArrowAt = null;
+ var arrow = stream.string.indexOf("=>", stream.start);
+ if (arrow < 0) return;
+
+ var depth = 0, sawSomething = false;
+ for (var pos = arrow - 1; pos >= 0; --pos) {
+ var ch = stream.string.charAt(pos);
+ var bracket = brackets.indexOf(ch);
+ if (bracket >= 0 && bracket < 3) {
+ if (!depth) { ++pos; break; }
+ if (--depth == 0) break;
+ } else if (bracket >= 3 && bracket < 6) {
+ ++depth;
+ } else if (/[$\w]/.test(ch)) {
+ sawSomething = true;
+ } else if (sawSomething && !depth) {
+ ++pos;
+ break;
+ }
+ }
+ if (sawSomething && !depth) state.fatArrowAt = pos;
+ }
+
// Parser
- var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true};
+ var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true};
function JSLexical(indented, column, type, align, prev, info) {
this.indented = indented;
this.column = column;
this.type = type;
@@ -37048,10 +37430,14 @@
}
function inScope(state, varname) {
for (var v = state.localVars; v; v = v.next)
if (v.name == varname) return true;
+ for (var cx = state.context; cx; cx = cx.prev) {
+ for (var v = cx.vars; v; v = v.next)
+ if (v.name == varname) return true;
+ }
}
function parseJS(state, style, type, content, stream) {
var cc = state.cc;
// Communicate our context to the combinators.
@@ -37094,11 +37480,12 @@
cx.marked = "def";
if (inList(state.localVars)) return;
state.localVars = {name: varname, next: state.localVars};
} else {
if (inList(state.globalVars)) return;
- state.globalVars = {name: varname, next: state.globalVars};
+ if (parserConfig.globalVars)
+ state.globalVars = {name: varname, next: state.globalVars};
}
}
// Combinators
@@ -37136,44 +37523,53 @@
else if (wanted == ";") return pass();
else return cont(arguments.callee);
};
}
- function statement(type) {
- if (type == "var") return cont(pushlex("vardef"), vardef1, expect(";"), poplex);
+ function statement(type, value) {
+ if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
if (type == "{") return cont(pushlex("}"), block, poplex);
if (type == ";") return cont();
if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse);
if (type == "function") return cont(functiondef);
- if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"),
- poplex, statement, poplex);
+ 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"), expression, pushlex("}", "switch"), expect("{"),
block, poplex, poplex);
if (type == "case") return cont(expression, expect(":"));
if (type == "default") return cont(expect(":"));
if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
statement, poplex, popcontext);
+ if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex);
+ if (type == "class") return cont(pushlex("form"), className, objlit, poplex);
+ if (type == "export") return cont(pushlex("form"), afterExport, poplex);
+ if (type == "import") return cont(pushlex("form"), afterImport, poplex);
return pass(pushlex("stat"), expression, expect(";"), poplex);
}
function expression(type) {
return expressionInner(type, false);
}
function expressionNoComma(type) {
return expressionInner(type, true);
}
function expressionInner(type, noComma) {
+ if (cx.state.fatArrowAt == cx.stream.start) {
+ var body = noComma ? arrowBodyNoComma : arrowBody;
+ if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
+ else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
+ }
+
var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
if (type == "function") return cont(functiondef);
if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
- if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
- if (type == "operator") return cont(noComma ? expressionNoComma : expression);
- if (type == "[") return cont(pushlex("]"), commasep(expressionNoComma, "]"), poplex, maybeop);
- if (type == "{") return cont(pushlex("}"), commasep(objprop, "}"), poplex, maybeop);
+ if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
+ if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
+ if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
+ if (type == "{") return contCommasep(objprop, "}", null, maybeop);
return cont();
}
function maybeexpression(type) {
if (type.match(/[;\}\)\],]/)) return pass();
return pass(expression);
@@ -37188,20 +37584,43 @@
return maybeoperatorNoComma(type, value, false);
}
function maybeoperatorNoComma(type, value, noComma) {
var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
var expr = noComma == false ? expression : expressionNoComma;
+ if (value == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
if (type == "operator") {
if (/\+\+|--/.test(value)) return cont(me);
if (value == "?") return cont(expression, expect(":"), expr);
return cont(expr);
}
+ if (type == "quasi") { cx.cc.push(me); return quasi(value); }
if (type == ";") return;
- if (type == "(") return cont(pushlex(")", "call"), commasep(expressionNoComma, ")"), poplex, me);
+ if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
if (type == ".") return cont(property, me);
if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
}
+ function quasi(value) {
+ if (value.slice(value.length - 2) != "${") return cont();
+ return cont(expression, continueQuasi);
+ }
+ function continueQuasi(type) {
+ if (type == "}") {
+ cx.marked = "string-2";
+ cx.state.tokenize = tokenQuasi;
+ return cont();
+ }
+ }
+ function arrowBody(type) {
+ findFatArrow(cx.stream, cx.state);
+ if (type == "{") return pass(statement);
+ return pass(expression);
+ }
+ function arrowBodyNoComma(type) {
+ findFatArrow(cx.stream, cx.state);
+ if (type == "{") return pass(statement);
+ return pass(expressionNoComma);
+ }
function maybelabel(type) {
if (type == ":") return cont(poplex, statement);
return pass(maybeoperatorComma, expect(";"), poplex);
}
function property(type) {
@@ -37210,20 +37629,25 @@
function objprop(type, value) {
if (type == "variable") {
cx.marked = "property";
if (value == "get" || value == "set") return cont(getterSetter);
} else if (type == "number" || type == "string") {
- cx.marked = type + " property";
+ cx.marked = jsonldMode ? "property" : (type + " property");
+ } else if (type == "[") {
+ return cont(expression, expect("]"), afterprop);
}
- if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expressionNoComma);
+ if (atomicTypes.hasOwnProperty(type)) return cont(afterprop);
}
function getterSetter(type) {
- if (type == ":") return cont(expression);
- if (type != "variable") return cont(expect(":"), expression);
+ if (type != "variable") return pass(afterprop);
cx.marked = "property";
return cont(functiondef);
}
+ function afterprop(type) {
+ if (type == ":") return cont(expressionNoComma);
+ if (type == "(") return pass(functiondef);
+ }
function commasep(what, end) {
function proceed(type) {
if (type == ",") {
var lex = cx.state.lexical;
if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
@@ -37232,110 +37656,174 @@
if (type == end) return cont();
return cont(expect(end));
}
return function(type) {
if (type == end) return cont();
- else return pass(what, proceed);
+ return pass(what, proceed);
};
}
+ function contCommasep(what, end, info) {
+ for (var i = 3; i < arguments.length; i++)
+ cx.cc.push(arguments[i]);
+ return cont(pushlex(end, info), commasep(what, end), poplex);
+ }
function block(type) {
if (type == "}") return cont();
return pass(statement, block);
}
function maybetype(type) {
- if (type == ":") return cont(typedef);
- return pass();
+ if (isTS && type == ":") return cont(typedef);
}
function typedef(type) {
if (type == "variable"){cx.marked = "variable-3"; return cont();}
- return pass();
}
- function vardef1(type, value) {
- if (type == "variable") {
+ function vardef() {
+ return pass(pattern, maybetype, maybeAssign, vardefCont);
+ }
+ function pattern(type, value) {
+ if (type == "variable") { register(value); return cont(); }
+ if (type == "[") return contCommasep(pattern, "]");
+ if (type == "{") return contCommasep(proppattern, "}");
+ }
+ function proppattern(type, value) {
+ if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
register(value);
- return isTS ? cont(maybetype, vardef2) : cont(vardef2);
+ return cont(maybeAssign);
}
- return pass();
+ if (type == "variable") cx.marked = "property";
+ return cont(expect(":"), pattern, maybeAssign);
}
- function vardef2(type, value) {
- if (value == "=") return cont(expressionNoComma, vardef2);
- if (type == ",") return cont(vardef1);
+ function maybeAssign(_type, value) {
+ if (value == "=") return cont(expressionNoComma);
}
+ function vardefCont(type) {
+ if (type == ",") return cont(vardef);
+ }
function maybeelse(type, value) {
if (type == "keyword b" && value == "else") return cont(pushlex("form"), statement, poplex);
}
+ function forspec(type) {
+ if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
+ }
function forspec1(type) {
- if (type == "var") return cont(vardef1, expect(";"), forspec2);
+ if (type == "var") return cont(vardef, expect(";"), forspec2);
if (type == ";") return cont(forspec2);
- if (type == "variable") return cont(formaybein);
+ if (type == "variable") return cont(formaybeinof);
return pass(expression, expect(";"), forspec2);
}
- function formaybein(_type, value) {
- if (value == "in") return cont(expression);
+ function formaybeinof(_type, value) {
+ if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
return cont(maybeoperatorComma, forspec2);
}
function forspec2(type, value) {
if (type == ";") return cont(forspec3);
- if (value == "in") return cont(expression);
+ if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
return pass(expression, expect(";"), forspec3);
}
function forspec3(type) {
if (type != ")") cont(expression);
}
function functiondef(type, value) {
+ if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
if (type == "variable") {register(value); return cont(functiondef);}
- if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext);
+ if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext);
}
- function funarg(type, value) {
- if (type == "variable") {register(value); return isTS ? cont(maybetype) : cont();}
+ function funarg(type) {
+ if (type == "spread") return cont(funarg);
+ return pass(pattern, maybetype);
}
+ function className(type, value) {
+ if (type == "variable") {register(value); return cont(classNameAfter);}
+ }
+ function classNameAfter(_type, value) {
+ if (value == "extends") return cont(expression);
+ }
+ function objlit(type) {
+ if (type == "{") return contCommasep(objprop, "}");
+ }
+ function afterModule(type, value) {
+ if (type == "string") return cont(statement);
+ if (type == "variable") { register(value); return cont(maybeFrom); }
+ }
+ function afterExport(_type, value) {
+ if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
+ if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
+ return pass(statement);
+ }
+ function afterImport(type) {
+ if (type == "string") return cont();
+ return pass(importSpec, maybeFrom);
+ }
+ function importSpec(type, value) {
+ if (type == "{") return contCommasep(importSpec, "}");
+ if (type == "variable") register(value);
+ return cont();
+ }
+ function maybeFrom(_type, value) {
+ if (value == "from") { cx.marked = "keyword"; return cont(expression); }
+ }
+ function arrayLiteral(type) {
+ if (type == "]") return cont();
+ return pass(expressionNoComma, maybeArrayComprehension);
+ }
+ function maybeArrayComprehension(type) {
+ if (type == "for") return pass(comprehension, expect("]"));
+ if (type == ",") return cont(commasep(expressionNoComma, "]"));
+ return pass(commasep(expressionNoComma, "]"));
+ }
+ function comprehension(type) {
+ if (type == "for") return cont(forspec, comprehension);
+ if (type == "if") return cont(expression, comprehension);
+ }
// Interface
return {
startState: function(basecolumn) {
- return {
- tokenize: jsTokenBase,
- lastType: null,
+ var state = {
+ tokenize: tokenBase,
+ lastType: "sof",
cc: [],
lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
localVars: parserConfig.localVars,
- globalVars: parserConfig.globalVars,
context: parserConfig.localVars && {vars: parserConfig.localVars},
indented: 0
};
+ if (parserConfig.globalVars) state.globalVars = parserConfig.globalVars;
+ return state;
},
token: function(stream, state) {
if (stream.sol()) {
if (!state.lexical.hasOwnProperty("align"))
state.lexical.align = false;
state.indented = stream.indentation();
+ findFatArrow(stream, state);
}
- if (state.tokenize != jsTokenComment && stream.eatSpace()) return null;
+ if (state.tokenize != tokenComment && stream.eatSpace()) return null;
var style = state.tokenize(stream, state);
if (type == "comment") return style;
state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
return parseJS(state, style, type, content, stream);
},
indent: function(state, textAfter) {
- if (state.tokenize == jsTokenComment) return CodeMirror.Pass;
- if (state.tokenize != jsTokenBase) return 0;
+ if (state.tokenize == tokenComment) return CodeMirror.Pass;
+ if (state.tokenize != tokenBase) return 0;
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
// Kludge to prevent 'maybelse' from blocking lexical scope pops
for (var i = state.cc.length - 1; i >= 0; --i) {
var c = state.cc[i];
if (c == poplex) lexical = lexical.prev;
- else if (c != maybeelse || /^else\b/.test(textAfter)) break;
+ else if (c != maybeelse) break;
}
if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
lexical = lexical.prev;
var type = lexical.type, closing = firstChar == type;
- if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? 4 : 0);
+ if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
else if (type == "form" && firstChar == "{") return lexical.indented;
else if (type == "form") return lexical.indented + indentUnit;
else if (type == "stat")
return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? statementIndent || indentUnit : 0);
else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
@@ -37349,26 +37837,29 @@
blockCommentEnd: jsonMode ? null : "*/",
lineComment: jsonMode ? null : "//",
fold: "brace",
helperType: jsonMode ? "json" : "javascript",
+ jsonldMode: jsonldMode,
jsonMode: jsonMode
};
});
CodeMirror.defineMIME("text/javascript", "javascript");
CodeMirror.defineMIME("text/ecmascript", "javascript");
CodeMirror.defineMIME("application/javascript", "javascript");
CodeMirror.defineMIME("application/ecmascript", "javascript");
CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
+CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true});
CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
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,
'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
@@ -37408,11 +37899,11 @@
allowMissing: false
};
var alignCDATA = parserConfig.alignCDATA;
// Return variables for tokenizers
- var tagName, type;
+ var tagName, type, setStyle;
function inText(stream, state) {
function chain(parser) {
state.tokenize = parser;
return parser(stream, state);
@@ -37439,11 +37930,11 @@
} else {
var isClose = stream.eat("/");
tagName = "";
var c;
while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c;
- if (!tagName) return "error";
+ if (!tagName) return "tag error";
type = isClose ? "closeTag" : "openTag";
state.tokenize = inTag;
return "tag";
}
} else if (ch == "&") {
@@ -37472,11 +37963,15 @@
return "tag";
} else if (ch == "=") {
type = "equals";
return null;
} else if (ch == "<") {
- return "error";
+ state.tokenize = inText;
+ state.state = baseState;
+ state.tagName = state.tagStart = null;
+ var next = state.tokenize(stream, state);
+ return next ? next + " error" : "error";
} else if (/[\'\"]/.test(ch)) {
state.tokenize = inAttribute(ch);
state.stringStartCol = stream.column();
return state.tokenize(stream, state);
} else {
@@ -37530,152 +38025,139 @@
}
return "meta";
};
}
- var curState, curStream, setStyle;
- function pass() {
- for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);
+ function Context(state, tagName, startOfLine) {
+ this.prev = state.context;
+ this.tagName = tagName;
+ this.indent = state.indented;
+ this.startOfLine = startOfLine;
+ if (Kludges.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
+ this.noIndent = true;
}
- function cont() {
- pass.apply(null, arguments);
- return true;
+ function popContext(state) {
+ if (state.context) state.context = state.context.prev;
}
-
- function pushContext(tagName, startOfLine) {
- var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent);
- curState.context = {
- prev: curState.context,
- tagName: tagName,
- indent: curState.indented,
- startOfLine: startOfLine,
- noIndent: noIndent
- };
+ function maybePopContext(state, nextTagName) {
+ var parentTagName;
+ while (true) {
+ if (!state.context) {
+ return;
+ }
+ parentTagName = state.context.tagName.toLowerCase();
+ if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
+ !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
+ return;
+ }
+ popContext(state);
+ }
}
- function popContext() {
- if (curState.context) curState.context = curState.context.prev;
- }
- function element(type) {
+ function baseState(type, stream, state) {
if (type == "openTag") {
- curState.tagName = tagName;
- curState.tagStart = curStream.column();
- return cont(attributes, endtag(curState.startOfLine));
+ state.tagName = tagName;
+ state.tagStart = stream.column();
+ return attrState;
} else if (type == "closeTag") {
var err = false;
- if (curState.context) {
- if (curState.context.tagName != tagName) {
- if (Kludges.implicitlyClosed.hasOwnProperty(curState.context.tagName.toLowerCase())) {
- popContext();
- }
- err = !curState.context || curState.context.tagName != tagName;
+ 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 cont(endclosetag(err));
+ return err ? closeStateErr : closeState;
+ } else {
+ return baseState;
}
- return cont();
}
- function endtag(startOfLine) {
- return function(type) {
- var tagName = curState.tagName;
- curState.tagName = curState.tagStart = null;
- if (type == "selfcloseTag" ||
- (type == "endTag" && Kludges.autoSelfClosers.hasOwnProperty(tagName.toLowerCase()))) {
- maybePopContext(tagName.toLowerCase());
- return cont();
- }
- if (type == "endTag") {
- maybePopContext(tagName.toLowerCase());
- pushContext(tagName, startOfLine);
- return cont();
- }
- return cont();
- };
- }
- function endclosetag(err) {
- return function(type) {
- if (err) setStyle = "error";
- if (type == "endTag") { popContext(); return cont(); }
+ function closeState(type, _stream, state) {
+ if (type != "endTag") {
setStyle = "error";
- return cont(arguments.callee);
- };
- }
- function maybePopContext(nextTagName) {
- var parentTagName;
- while (true) {
- if (!curState.context) {
- return;
- }
- parentTagName = curState.context.tagName.toLowerCase();
- if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) ||
- !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
- return;
- }
- popContext();
+ return closeState;
}
+ popContext(state);
+ return baseState;
}
+ function closeStateErr(type, stream, state) {
+ setStyle = "error";
+ return closeState(type, stream, state);
+ }
- function attributes(type) {
- if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);}
- if (type == "endTag" || type == "selfcloseTag") return pass();
+ function attrState(type, _stream, state) {
+ if (type == "word") {
+ setStyle = "attribute";
+ return attrEqState;
+ } else if (type == "endTag" || type == "selfcloseTag") {
+ var tagName = state.tagName, tagStart = state.tagStart;
+ state.tagName = state.tagStart = null;
+ if (type == "selfcloseTag" ||
+ Kludges.autoSelfClosers.hasOwnProperty(tagName.toLowerCase())) {
+ maybePopContext(state, tagName.toLowerCase());
+ } else {
+ maybePopContext(state, tagName.toLowerCase());
+ state.context = new Context(state, tagName, tagStart == state.indented);
+ }
+ return baseState;
+ }
setStyle = "error";
- return cont(attributes);
+ return attrState;
}
- function attribute(type) {
- if (type == "equals") return cont(attvalue, attributes);
+ function attrEqState(type, stream, state) {
+ if (type == "equals") return attrValueState;
if (!Kludges.allowMissing) setStyle = "error";
- else if (type == "word") {setStyle = "attribute"; return cont(attribute, attributes);}
- return (type == "endTag" || type == "selfcloseTag") ? pass() : cont();
+ return attrState(type, stream, state);
}
- function attvalue(type) {
- if (type == "string") return cont(attvaluemaybe);
- if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return cont();}
+ function attrValueState(type, stream, state) {
+ if (type == "string") return attrContinuedState;
+ if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return attrState;}
setStyle = "error";
- return (type == "endTag" || type == "selfCloseTag") ? pass() : cont();
+ return attrState(type, stream, state);
}
- function attvaluemaybe(type) {
- if (type == "string") return cont(attvaluemaybe);
- else return pass();
+ function attrContinuedState(type, stream, state) {
+ if (type == "string") return attrContinuedState;
+ return attrState(type, stream, state);
}
return {
startState: function() {
- return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, tagStart: null, context: null};
+ return {tokenize: inText,
+ state: baseState,
+ indented: 0,
+ tagName: null, tagStart: null,
+ context: null};
},
token: function(stream, state) {
- if (!state.tagName && stream.sol()) {
- state.startOfLine = true;
+ if (!state.tagName && stream.sol())
state.indented = stream.indentation();
- }
- if (stream.eatSpace()) return null;
- setStyle = type = tagName = null;
+ if (stream.eatSpace()) return null;
+ tagName = type = null;
var style = state.tokenize(stream, state);
- state.type = type;
if ((style || type) && style != "comment") {
- curState = state; curStream = stream;
- while (true) {
- var comb = state.cc.pop() || element;
- if (comb(type || style)) break;
- }
+ setStyle = null;
+ state.state = state.state(type || style, stream, state);
+ if (setStyle)
+ style = setStyle == "error" ? style + " error" : setStyle;
}
- state.startOfLine = false;
- return setStyle || style;
+ return style;
},
indent: function(state, textAfter, fullLine) {
var context = state.context;
// Indent multi-line strings (e.g. css).
if (state.tokenize.isInAttribute) {
return state.stringStartCol + 1;
}
- if ((state.tokenize != inTag && state.tokenize != inText) ||
- context && context.noIndent)
+ if (context && context.noIndent) return CodeMirror.Pass;
+ if (state.tokenize != inTag && state.tokenize != inText)
return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
// Indent the starts of attribute names.
if (state.tagName) {
if (multilineTagIndentPastTag)
return state.tagStart + state.tagName.length + 2;
@@ -37703,11 +38185,14 @@
CodeMirror.defineMIME("text/xml", "xml");
CodeMirror.defineMIME("application/xml", "xml");
if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
CodeMirror.defineMode("htmlmixed", function(config, parserConfig) {
- var htmlMode = CodeMirror.getMode(config, {name: "xml", htmlMode: true});
+ var htmlMode = CodeMirror.getMode(config, {name: "xml",
+ htmlMode: true,
+ multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
+ multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag});
var cssMode = CodeMirror.getMode(config, "css");
var scriptTypes = [], scriptTypesConf = parserConfig && parserConfig.scriptTypes;
scriptTypes.push({matches: /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i,
mode: CodeMirror.getMode(config, "javascript")});
@@ -37748,11 +38233,11 @@
var cur = stream.current();
var close = cur.search(pat), m;
if (close > -1) stream.backUp(cur.length - close);
else if (m = cur.match(/<\/?$/)) {
stream.backUp(cur.length);
- if (!stream.match(pat, false)) stream.match(cur[0]);
+ if (!stream.match(pat, false)) stream.match(cur);
}
return style;
}
function script(stream, state) {
if (stream.match(/^<\/\s*script\s*>/i, false)) {
@@ -37797,12 +38282,10 @@
return state.localMode.indent(state.localState, textAfter);
else
return CodeMirror.Pass;
},
- electricChars: "/{}:",
-
innerMode: function(state) {
return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
}
};
}, "xml", "javascript", "css");
@@ -38509,13 +38992,26 @@
// Default JSON-request options.
var params = _.extend({
type: type,
dataType: 'json',
- beforeSend: function( xhr ) {
+ beforeSend: function(xhr, settings) {
var token = $('meta[name="csrf-token"]').prop('content');
if (token) xhr.setRequestHeader('X-CSRF-Token', token);
+ },
+ xhr: function() {
+ var xhr = new window.XMLHttpRequest();
+
+ xhr.upload.addEventListener('progress', function(evt){
+ if (evt.lengthComputable) {
+ if (options.progress) {
+ options.progress(event.loaded, event.total)
+ }
+ }
+ }, false);
+
+ return xhr;
}
}, options);
if (!params.url) {
params.url = getUrl(model) || urlError();
@@ -43898,11 +44394,11 @@
return buf;
}
String.prototype.truncate = function(length) {
if (this.length > length) {
- return this.slice(0, length - 3) + "...";
+ return this.slice(0, length - 3) + '...';
} else {
return this;
}
}
@@ -44086,20 +44582,18 @@
})(Locomotive.Models.Account);
}).call(this);
(function() {
- var _ref, _ref1,
- __hasProp = {}.hasOwnProperty,
+ var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Locomotive.Models.ContentAsset = (function(_super) {
__extends(ContentAsset, _super);
function ContentAsset() {
- _ref = ContentAsset.__super__.constructor.apply(this, arguments);
- return _ref;
+ return ContentAsset.__super__.constructor.apply(this, arguments);
}
ContentAsset.prototype.paramRoot = 'content_asset';
ContentAsset.prototype.urlRoot = "" + Locomotive.mounted_on + "/content_assets";
@@ -44107,26 +44601,37 @@
ContentAsset.prototype.initialize = function() {
return this.prepare();
};
ContentAsset.prototype.prepare = function() {
+ if (this.get('uploading')) {
+ this.set({
+ filename: this.get('source').name.truncate(15)
+ });
+ }
this.set({
- image: this.get('content_type') === 'image'
+ image: this.get('content_type') === 'image',
+ with_thumbnail: this.get('content_type') === 'image' || this.get('content_type') === 'pdf'
});
return this;
};
+ ContentAsset.prototype.toJSONForSave = function() {
+ return {
+ source: this.get('source')
+ };
+ };
+
return ContentAsset;
})(Backbone.Model);
Locomotive.Models.ContentAssetsCollection = (function(_super) {
__extends(ContentAssetsCollection, _super);
function ContentAssetsCollection() {
- _ref1 = ContentAssetsCollection.__super__.constructor.apply(this, arguments);
- return _ref1;
+ return ContentAssetsCollection.__super__.constructor.apply(this, arguments);
}
ContentAssetsCollection.prototype.model = Locomotive.Models.ContentAsset;
ContentAssetsCollection.prototype.url = "" + Locomotive.mounted_on + "/content_assets";
@@ -44135,124 +44640,136 @@
})(Backbone.Collection);
}).call(this);
(function() {
- var _ref, _ref1,
- __hasProp = {}.hasOwnProperty,
+ var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Locomotive.Models.ContentEntry = (function(_super) {
__extends(ContentEntry, _super);
function ContentEntry() {
- _ref = ContentEntry.__super__.constructor.apply(this, arguments);
- return _ref;
+ return ContentEntry.__super__.constructor.apply(this, arguments);
}
ContentEntry.prototype.paramRoot = 'content_entry';
ContentEntry.prototype.urlRoot = "" + Locomotive.mounted_on + "/content_types/:slug/entries";
ContentEntry.prototype.initialize = function() {
- var _this = this;
this.urlRoot = this.urlRoot.replace(':slug', this.get('content_type_slug'));
- _.each(this.get('has_many_custom_fields'), function(field) {
- var collection, name;
- name = field[0];
- collection = new Locomotive.Models.ContentEntriesCollection(_this.get(name));
- return _this.set_attribute(name, collection);
- });
- return _.each(this.get('many_to_many_custom_fields'), function(field) {
- var collection, name;
- name = field[0];
- collection = new Locomotive.Models.ContentEntriesCollection(_this.get(name));
- collection.comparator = function(entry) {
- return entry.get('__position') || 0;
+ _.each(this.get('has_many_custom_fields'), (function(_this) {
+ return function(field) {
+ var collection, name;
+ name = field[0];
+ collection = new Locomotive.Models.ContentEntriesCollection(_this.get(name));
+ return _this.set_attribute(name, collection);
};
- return _this.set_attribute(name, collection);
- });
+ })(this));
+ return _.each(this.get('many_to_many_custom_fields'), (function(_this) {
+ return function(field) {
+ var collection, name;
+ name = field[0];
+ collection = new Locomotive.Models.ContentEntriesCollection(_this.get(name));
+ collection.comparator = function(entry) {
+ return entry.get('__position') || 0;
+ };
+ return _this.set_attribute(name, collection);
+ };
+ })(this));
};
ContentEntry.prototype.set_attribute = function(attribute, value) {
var data;
data = {};
data[attribute] = value;
return this.set(data);
};
ContentEntry.prototype.update_attributes = function(attributes) {
- var _this = this;
- return _.each(this.get('file_custom_fields'), function(field) {
- var attribute;
- attribute = "" + field + "_url";
- _this.set_attribute(attribute, attributes[attribute]);
- return _this.set_attribute("remove_" + field, false);
- });
+ return _.each(this.get('file_custom_fields'), (function(_this) {
+ return function(field) {
+ var attribute;
+ attribute = "" + field + "_url";
+ _this.set_attribute(attribute, attributes[attribute]);
+ return _this.set_attribute("remove_" + field, false);
+ };
+ })(this));
};
+ ContentEntry.prototype.reset_attributes = function() {
+ return _.each(_.keys(this.attributes), (function(_this) {
+ return function(name) {
+ return _this.set_attribute(name, null);
+ };
+ })(this));
+ };
+
ContentEntry.prototype.toMinJSON = function() {
- var _this = this;
- return _.tap({}, function(hash) {
- return _.each(_this.attributes, function(val, key) {
- if (key === 'id' || key === '_destroy' || key.indexOf('position_in_') === 0) {
- return hash[key] = val;
- }
- });
- });
+ return _.tap({}, (function(_this) {
+ return function(hash) {
+ return _.each(_this.attributes, function(val, key) {
+ if (key === 'id' || key === '_destroy' || key.indexOf('position_in_') === 0) {
+ return hash[key] = val;
+ }
+ });
+ };
+ })(this));
};
ContentEntry.prototype.toJSON = function() {
- var _this = this;
- return _.tap(ContentEntry.__super__.toJSON.apply(this, arguments), function(hash) {
- if (hash['_slug'] === null) {
- hash['_slug'] = '';
- }
- _.each(_.keys(hash), function(key) {
- if (!_.include(_this.get('safe_attributes'), key)) {
- return delete hash[key];
+ return _.tap(ContentEntry.__super__.toJSON.apply(this, arguments), (function(_this) {
+ return function(hash) {
+ if (hash['_slug'] === null) {
+ hash['_slug'] = '';
}
- });
- _.each(_this.get('has_many_custom_fields'), function(field) {
- var name;
- name = field[0];
- if (_this.get(name).length > 0) {
- return hash["" + name + "_attributes"] = _this.get(name).toMinJSON();
- }
- });
- return _.each(_this.get('many_to_many_custom_fields'), function(field) {
- var name, setter_name;
- name = field[0];
- setter_name = field[1];
- return hash[setter_name] = _this.get(name).sort().map(function(entry) {
- return entry.id;
+ _.each(_.keys(hash), function(key) {
+ if (!_.include(_this.get('safe_attributes'), key)) {
+ return delete hash[key];
+ }
});
- });
- });
+ _.each(_this.get('has_many_custom_fields'), function(field) {
+ var name;
+ name = field[0];
+ if (_this.get(name).length > 0) {
+ return hash["" + name + "_attributes"] = _this.get(name).toMinJSON();
+ }
+ });
+ return _.each(_this.get('many_to_many_custom_fields'), function(field) {
+ var name, setter_name;
+ name = field[0];
+ setter_name = field[1];
+ return hash[setter_name] = _this.get(name).sort().map(function(entry) {
+ return entry.id;
+ });
+ });
+ };
+ })(this));
};
return ContentEntry;
})(Backbone.Model);
Locomotive.Models.ContentEntriesCollection = (function(_super) {
__extends(ContentEntriesCollection, _super);
function ContentEntriesCollection() {
- _ref1 = ContentEntriesCollection.__super__.constructor.apply(this, arguments);
- return _ref1;
+ return ContentEntriesCollection.__super__.constructor.apply(this, arguments);
}
ContentEntriesCollection.prototype.model = Locomotive.Models.ContentEntry;
ContentEntriesCollection.prototype.url = "" + Locomotive.mounted_on + "/content_types/:slug/entries";
ContentEntriesCollection.prototype.toMinJSON = function() {
- var _this = this;
- return this.map(function(entry) {
- return entry.toMinJSON();
- });
+ return this.map((function(_this) {
+ return function(entry) {
+ return entry.toMinJSON();
+ };
+ })(this));
};
return ContentEntriesCollection;
})(Backbone.Collection);
@@ -45032,22 +45549,21 @@
})(Backbone.View);
}).call(this);
(function() {
- var _base, _ref,
+ var _base,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
(_base = Locomotive.Views).ContentAssets || (_base.ContentAssets = {});
Locomotive.Views.ContentAssets.PickerItemView = (function(_super) {
__extends(PickerItemView, _super);
function PickerItemView() {
- _ref = PickerItemView.__super__.constructor.apply(this, arguments);
- return _ref;
+ return PickerItemView.__super__.constructor.apply(this, arguments);
}
PickerItemView.prototype.tagName = 'li';
PickerItemView.prototype.className = 'asset';
@@ -45060,10 +45576,23 @@
PickerItemView.prototype.render = function() {
$(this.el).html(ich.content_asset(this.model.toJSON()));
return this;
};
+ PickerItemView.prototype.refresh = function() {
+ return $(this.el).html(ich.content_asset(this.model.toJSON()));
+ };
+
+ PickerItemView.prototype.uploaded_at = function(loaded, total) {
+ var percentage;
+ percentage = (loaded / total) * 100;
+ if (percentage < 20) {
+ percentage = 20;
+ }
+ return this.$('.uploading .progress-bar').css('width', "" + percentage + "%");
+ };
+
PickerItemView.prototype.select_asset = function(event) {
event.stopPropagation() & event.preventDefault();
return this.on_select(this.model);
};
@@ -45086,22 +45615,21 @@
})(Backbone.View);
}).call(this);
(function() {
- var _base, _ref,
+ var _base,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
(_base = Locomotive.Views).Shared || (_base.Shared = {});
Locomotive.Views.Shared.AssetPickerView = (function(_super) {
__extends(AssetPickerView, _super);
function AssetPickerView() {
- _ref = AssetPickerView.__super__.constructor.apply(this, arguments);
- return _ref;
+ return AssetPickerView.__super__.constructor.apply(this, arguments);
}
AssetPickerView.prototype.tag = 'div';
AssetPickerView.prototype.initialize = function() {
@@ -45122,33 +45650,44 @@
AssetPickerView.prototype.fetch_assets = function() {};
AssetPickerView.prototype.build_uploader = function(el, link) {};
AssetPickerView.prototype.create_dialog = function() {
- var _this = this;
return this.dialog || (this.dialog = $(this.el).dialog({
autoOpen: false,
modal: true,
zIndex: window.application_view.unique_dialog_zindex(),
- width: 650,
- create: function(event, ui) {
- var actions, input, link;
- $(_this.el).prev().find('.ui-dialog-title').html(_this.$('h2').html());
- _this.$('h2').remove();
- actions = _this.$('.dialog-actions').appendTo($(_this.el).parent()).addClass('ui-dialog-buttonpane ui-widget-content ui-helper-clearfix');
- actions.find('#close-link').click(function(event) {
- return _this.close(event);
- });
- input = actions.find('input[type=file]');
- link = actions.find('#upload-link');
- return _this.build_uploader(input, link);
- },
- open: function(event, ui, extra) {
- return $(_this.el).dialog('overlayEl').bind('click', function() {
- return _this.close();
- });
- }
+ dialogClass: this.dialog_class(),
+ width: 615,
+ minHeight: 520,
+ create: (function(_this) {
+ return function(event, ui) {
+ var actions, input, link;
+ $(_this.el).prev().find('.ui-dialog-title').html(_this.$('h2').html());
+ _this.$('h2').remove();
+ actions = _this.$('.dialog-actions').appendTo($(_this.el).parent()).addClass('ui-dialog-buttonpane ui-widget-content ui-helper-clearfix');
+ actions.find('#close-link').click(function(event) {
+ return _this.close(event);
+ });
+ input = actions.find('input[type=file]');
+ link = actions.find('#upload-link');
+ return _this.build_uploader(input, link);
+ };
+ })(this),
+ open: (function(_this) {
+ return function(event, ui, extra) {
+ $(_this.el).dialog('overlayEl').bind('click', function() {
+ return _this.close();
+ });
+ return $(document.body).addClass('stop-scrolling');
+ };
+ })(this),
+ close: (function(_this) {
+ return function(event, ui, extra) {
+ return $(document.body).removeClass('stop-scrolling');
+ };
+ })(this)
}));
};
AssetPickerView.prototype.open = function() {
return $(this.el).dialog('open');
@@ -45171,31 +45710,42 @@
AssetPickerView.prototype.center = function() {
return $(this.el).dialog('option', 'position', 'center');
};
AssetPickerView.prototype.add_assets = function(collection) {
- var _this = this;
- collection.each(function(asset) {
- return _this.add_asset(asset, true);
- });
+ collection.each((function(_this) {
+ return function(asset) {
+ return _this.add_asset(asset, true);
+ };
+ })(this));
return this._refresh();
};
AssetPickerView.prototype.add_asset = function(asset, first) {};
AssetPickerView.prototype.remove_asset = function(asset) {};
+ AssetPickerView.prototype.dialog_class = function() {
+ return 'asset-picker-dialog';
+ };
+
AssetPickerView.prototype._move_to_last_asset = function() {
var limit;
limit = this.$('ul.list li.clear').position();
if (limit != null) {
return this.$('ul.list').animate({
scrollTop: limit.top
}, 100);
}
};
+ AssetPickerView.prototype._move_to_top = function() {
+ return this.$('ul.list').animate({
+ scrollTop: 0
+ }, 100);
+ };
+
AssetPickerView.prototype._refresh = function() {
if (this.collection.length === 0) {
this.$('ul.list').hide() & this.$('p.no-items').show();
} else {
this.$('p.no-items').hide() & this.$('ul.list').show();
@@ -45214,85 +45764,172 @@
})(Backbone.View);
}).call(this);
(function() {
- var _base, _ref,
+ var _base,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
(_base = Locomotive.Views).ContentAssets || (_base.ContentAssets = {});
Locomotive.Views.ContentAssets.PickerView = (function(_super) {
__extends(PickerView, _super);
function PickerView() {
- _ref = PickerView.__super__.constructor.apply(this, arguments);
- return _ref;
+ return PickerView.__super__.constructor.apply(this, arguments);
}
PickerView.prototype.number_items_per_row = 4;
+ PickerView.prototype.page = 1;
+
+ PickerView.prototype.per_page = 12;
+
+ PickerView.prototype.total_pages = null;
+
+ PickerView.prototype.uploading = false;
+
PickerView.prototype._item_views = [];
+ PickerView.prototype.events = {
+ 'click .btn': 'toggle_filter_by_type',
+ 'change input[name=query]': 'fetch_assets'
+ };
+
+ PickerView.prototype.render = function() {
+ PickerView.__super__.render.apply(this, arguments);
+ this.enable_dropzone();
+ this.enable_infinite_scroll();
+ return this;
+ };
+
PickerView.prototype.template = function() {
return ich.content_asset_picker;
};
- PickerView.prototype.fetch_assets = function() {
- var _this = this;
+ PickerView.prototype.fetch_assets = function(event) {
+ var xhr;
this._reset();
- return this.collection.fetch({
- success: function() {
- return _this.open();
- }
+ xhr = this.collection.fetch({
+ data: this._fetch_options(),
+ reset: true,
+ success: (function(_this) {
+ return function() {
+ return _this.open();
+ };
+ })(this)
});
+ return xhr.done((function(_this) {
+ return function() {
+ return _this._get_pagination_info(xhr);
+ };
+ })(this));
};
+ PickerView.prototype.toggle_filter_by_type = function(event) {
+ $(event.target).toggleClass('on');
+ return this.fetch_assets();
+ };
+
PickerView.prototype.build_uploader = function(el, link) {
- var _this = this;
link.bind('click', function(event) {
event.stopPropagation() & event.preventDefault();
- console.log(el);
- window.foo = el;
return el.click();
});
- return el.bind('change', function(event) {
- return _.each(event.target.files, function(file) {
- var asset;
- asset = new Locomotive.Models.ContentAsset({
- source: file
- });
- return asset.save({}, {
- headers: {
- 'X-Flash': true
- },
- success: function(model, response) {
- return _this.collection.add(model.prepare());
- },
- error: function() {
- return _this.shake();
- }
- });
- });
- });
+ return el.bind('change', (function(_this) {
+ return function(event) {
+ return _this._persist_files(event);
+ };
+ })(this));
};
PickerView.prototype.add_asset = function(asset, first) {
var view;
view = new Locomotive.Views.ContentAssets.PickerItemView({
model: asset,
parent: this
});
(this._item_views || (this._item_views = [])).push(view);
- this.$('ul.list .clear').before(view.render().el);
- this._refresh();
- if (first !== true) {
- return this._move_to_last_asset();
+ if (this.uploading) {
+ this.$('ul.list').prepend(view.render().el);
+ return this._refresh();
+ } else {
+ this.$('ul.list .clear').before(view.render().el);
+ this._refresh();
+ if (first !== true) {
+ return this._move_to_last_asset();
+ }
}
};
+ PickerView.prototype.enable_dropzone = function() {
+ var dropzone;
+ if (!(window.File && window.FileList && window.FileReader)) {
+ return;
+ }
+ dropzone = this.$('ul.list').parent();
+ dropzone.on('dragover', (function(_this) {
+ return function(event) {
+ _this._stop_event(event);
+ return dropzone.addClass('hovered');
+ };
+ })(this));
+ dropzone.on('dragleave', (function(_this) {
+ return function(event) {
+ _this._stop_event(event);
+ return dropzone.removeClass('hovered');
+ };
+ })(this));
+ dropzone.on('dragenter', (function(_this) {
+ return function(event) {
+ return _this._stop_event(event);
+ };
+ })(this));
+ return dropzone.on('drop', (function(_this) {
+ return function(event) {
+ _this._stop_event(event);
+ dropzone.removeClass('hovered');
+ return _this._persist_files(event);
+ };
+ })(this));
+ };
+
+ PickerView.prototype.enable_infinite_scroll = function() {
+ var $list;
+ $list = this.$('ul.list');
+ return $list.on('scroll', (function(_this) {
+ return function(event) {
+ if (_this.throttle_timer != null) {
+ clearTimeout(_this.throttle_timer);
+ }
+ return _this.throttle_timer = setTimeout(function() {
+ var height, isScrolledToEnd, scroll, xhr;
+ height = $list[0].scrollHeight - $list.innerHeight();
+ scroll = $list.scrollTop();
+ isScrolledToEnd = scroll >= height;
+ if (isScrolledToEnd && _this.page < _this.total_pages) {
+ _this.page += 1;
+ xhr = _this.collection.fetch({
+ data: {
+ page: _this.page,
+ per_page: _this.per_page
+ },
+ success: function() {
+ _this._refresh();
+ return $list.scrollTop(scroll);
+ }
+ });
+ return xhr.done(function() {
+ return _this._get_pagination_info(xhr);
+ });
+ }
+ }, 100);
+ };
+ })(this));
+ };
+
PickerView.prototype.remove_asset = function(asset) {
var view;
view = _.find(this._item_views, function(tmp) {
return tmp.model === asset;
});
@@ -45300,10 +45937,84 @@
view.remove();
}
return this._refresh();
};
+ PickerView.prototype.dialog_class = function() {
+ return 'content-asset-picker-dialog';
+ };
+
+ PickerView.prototype._fetch_options = function() {
+ return _.tap({
+ per_page: this.per_page
+ }, (function(_this) {
+ return function(options) {
+ options.types = [];
+ _this.$('.asset-types .btn.on').each(function() {
+ return options.types.push($(this).data('type'));
+ });
+ return options.query = _this.$('input[name=query]').val();
+ };
+ })(this));
+ };
+
+ PickerView.prototype._persist_files = function(event) {
+ var files;
+ files = event.target.files || event.originalEvent.dataTransfer.files;
+ this._move_to_top();
+ this.uploading = true;
+ _.each(files, (function(_this) {
+ return function(file) {
+ var asset, view;
+ asset = new Locomotive.Models.ContentAsset({
+ uploading: true,
+ source: file
+ });
+ _this.collection.add(asset.prepare(), {
+ at: 0
+ });
+ view = _this._find_view_by_asset(asset);
+ return asset.save({}, {
+ headers: {
+ 'X-Flash': true
+ },
+ success: function(model, response) {
+ asset.set({
+ uploading: false
+ });
+ asset.prepare();
+ return view.refresh();
+ },
+ error: function() {
+ return _this.shake();
+ },
+ progress: function(loaded, total) {
+ return view.uploaded_at(loaded, total);
+ }
+ });
+ };
+ })(this));
+ this.uploading = false;
+ return this._recalculate_pagination(_.size(files));
+ };
+
+ PickerView.prototype._recalculate_pagination = function(number_assets_added) {
+ var number_assets_to_delete, previous_total_pages;
+ previous_total_pages = this.total_pages;
+ if (this.page < this.total_pages) {
+ number_assets_to_delete = number_assets_added % this.per_page;
+ while (number_assets_to_delete -= 1) {
+ this.collection.pop();
+ }
+ }
+ this.total_entries += number_assets_added;
+ this.total_pages = Math.ceil(this.total_entries / this.per_page);
+ if (this.page === previous_total_pages || previous_total_pages === 0) {
+ return this.page = this.total_pages;
+ }
+ };
+
PickerView.prototype._on_refresh = function() {
var self;
self = this;
return this.$('ul.list li.asset').each(function(index) {
if ((index + 1) % self.number_items_per_row === 0) {
@@ -45312,11 +46023,29 @@
return $(this).removeClass('last');
}
});
};
+ PickerView.prototype._find_view_by_asset = function(asset) {
+ return _.find(this._item_views || [], function(view) {
+ return view.model.cid === asset.cid;
+ });
+ };
+
+ PickerView.prototype._stop_event = function(event) {
+ return event.stopPropagation() & event.preventDefault();
+ };
+
+ PickerView.prototype._get_pagination_info = function(xhr) {
+ this.total_pages = parseInt(xhr.getResponseHeader('X-Total-Pages'));
+ this.per_page = parseInt(xhr.getResponseHeader('X-Per-Page'));
+ return this.total_entries = parseInt(xhr.getResponseHeader('X-Total-Entries'));
+ };
+
PickerView.prototype._reset = function() {
+ this.page = 1;
+ this.total_pages = null;
_.each(this._item_views || [], function(view) {
return view.remove();
});
return PickerView.__super__._reset.call(this);
};
@@ -45533,22 +46262,21 @@
})(Backbone.View);
}).call(this);
(function() {
- var _base, _ref,
+ var _base,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
(_base = Locomotive.Views).ContentEntries || (_base.ContentEntries = {});
Locomotive.Views.ContentEntries.FormView = (function(_super) {
__extends(FormView, _super);
function FormView() {
- _ref = FormView.__super__.constructor.apply(this, arguments);
- return _ref;
+ return FormView.__super__.constructor.apply(this, arguments);
}
FormView.prototype.el = '#content';
FormView.prototype._select_field_view = null;
@@ -45608,181 +46336,193 @@
showTime: false
});
};
FormView.prototype.enable_richtexteditor = function() {
- var _this = this;
- return _.each(this.$('li.input.rte textarea.html'), function(textarea) {
- var settings;
- settings = _.extend({}, _this.tinyMCE_settings(), {
- oninit: (function(editor) {
- return $.cmd('S', (function() {
+ return _.each(this.$('li.input.rte textarea.html'), (function(_this) {
+ return function(textarea) {
+ var settings;
+ settings = _.extend({}, _this.tinyMCE_settings(), {
+ oninit: (function(editor) {
+ return $.cmd('S', (function() {
+ editor.save();
+ $(textarea).trigger('changeSilently');
+ return _this.$('form').trigger('submit');
+ }), [], {
+ ignoreCase: true,
+ document: editor.dom.doc
+ });
+ }),
+ onchange_callback: function(editor) {
editor.save();
- $(textarea).trigger('changeSilently');
- return _this.$('form').trigger('submit');
- }), [], {
- ignoreCase: true,
- document: editor.dom.doc
- });
- }),
- onchange_callback: function(editor) {
- editor.save();
- return $(textarea).trigger('changeSilently');
- }
- });
- return $(textarea).tinymce(settings);
- });
+ return $(textarea).trigger('changeSilently');
+ }
+ });
+ return $(textarea).tinymce(settings);
+ };
+ })(this));
};
FormView.prototype.enable_select_fields = function() {
- var _this = this;
this._select_field_view = new Locomotive.Views.Shared.Fields.SelectView({
model: this.content_type
});
- return _.each(this.model.get('select_custom_fields'), function(name) {
- var $input_wrapper;
- $input_wrapper = _this.$("#" + _this.model.paramRoot + "_" + name + "_id_input");
- $input_wrapper.append(ich.edit_select_options_button());
- return $input_wrapper.find('a.edit-options-button').bind('click', function(event) {
- event.stopPropagation() & event.preventDefault();
- return _this._select_field_view.render_for(name, function(options) {
- var $select;
- $select = $input_wrapper.find('select');
- $select.find('option[value!=""]').remove();
- return _.each(options, function(option) {
- if (!option.destroyed()) {
- return $select.append(new Option(option.get('name'), option.get('id'), false, option.get('id') === _this.model.get("" + name + "_id")));
- }
+ return _.each(this.model.get('select_custom_fields'), (function(_this) {
+ return function(name) {
+ var $input_wrapper;
+ $input_wrapper = _this.$("#" + _this.model.paramRoot + "_" + name + "_id_input");
+ $input_wrapper.append(ich.edit_select_options_button());
+ return $input_wrapper.find('a.edit-options-button').bind('click', function(event) {
+ event.stopPropagation() & event.preventDefault();
+ return _this._select_field_view.render_for(name, function(options) {
+ var $select;
+ $select = $input_wrapper.find('select');
+ $select.find('option[value!=""]').remove();
+ return _.each(options, function(option) {
+ if (!option.destroyed()) {
+ return $select.append(new Option(option.get('name'), option.get('id'), false, option.get('id') === _this.model.get("" + name + "_id")));
+ }
+ });
});
});
- });
- });
+ };
+ })(this));
};
FormView.prototype.enable_belongs_to_fields = function() {
- var prefix,
- _this = this;
+ var prefix;
prefix = this.namespace != null ? "" + this.namespace + "_" : '';
- return _.each(this.model.get('belongs_to_custom_fields'), function(name) {
- var $el, view;
- $el = _this.$("#" + prefix + _this.model.paramRoot + "_" + name + "_id");
- if ($el.length > 0) {
- view = new Locomotive.Views.Shared.Fields.BelongsToView({
- model: _this.model,
- name: name,
- el: $el
- });
- _this._belongs_to_field_views.push(view);
- return view.render();
- }
- });
+ return _.each(this.model.get('belongs_to_custom_fields'), (function(_this) {
+ return function(name) {
+ var $el, view;
+ $el = _this.$("#" + prefix + _this.model.paramRoot + "_" + name + "_id");
+ if ($el.length > 0) {
+ view = new Locomotive.Views.Shared.Fields.BelongsToView({
+ model: _this.model,
+ name: name,
+ el: $el
+ });
+ _this._belongs_to_field_views.push(view);
+ return view.render();
+ }
+ };
+ })(this));
};
FormView.prototype.enable_file_fields = function() {
- var prefix,
- _this = this;
+ var prefix;
prefix = this.namespace != null ? "" + this.namespace + "_" : '';
- return _.each(this.model.get('file_custom_fields'), function(name) {
- var view;
- view = new Locomotive.Views.Shared.Fields.FileView({
- model: _this.model,
- name: name,
- namespace: _this.namespace
- });
- _this._file_field_views.push(view);
- return _this.$("#" + prefix + _this.model.paramRoot + "_" + name + "_input label").after(view.render().el);
- });
+ return _.each(this.model.get('file_custom_fields'), (function(_this) {
+ return function(name) {
+ var view;
+ view = new Locomotive.Views.Shared.Fields.FileView({
+ model: _this.model,
+ name: name,
+ namespace: _this.namespace
+ });
+ _this._file_field_views.push(view);
+ return _this.$("#" + prefix + _this.model.paramRoot + "_" + name + "_input label").after(view.render().el);
+ };
+ })(this));
};
FormView.prototype.enable_has_many_fields = function() {
- var _this = this;
if (!this.model.isNew()) {
- return _.each(this.model.get('has_many_custom_fields'), function(field) {
- var inverse_of, name, new_entry, view;
+ return _.each(this.model.get('has_many_custom_fields'), (function(_this) {
+ return function(field) {
+ var inverse_of, name, new_entry, view;
+ name = field[0];
+ inverse_of = field[1];
+ new_entry = new Locomotive.Models.ContentEntry(_this.options["" + name + "_new_entry"]);
+ view = new Locomotive.Views.Shared.Fields.HasManyView({
+ model: _this.model,
+ name: name,
+ new_entry: new_entry,
+ inverse_of: inverse_of
+ });
+ if (view.ui_enabled()) {
+ _this._has_many_field_views.push(view);
+ return _this.$("#" + _this.model.paramRoot + "_" + name + "_input label").after(view.render().el);
+ }
+ };
+ })(this));
+ }
+ };
+
+ FormView.prototype.enable_many_to_many_fields = function() {
+ return _.each(this.model.get('many_to_many_custom_fields'), (function(_this) {
+ return function(field) {
+ var name, view;
name = field[0];
- inverse_of = field[1];
- new_entry = new Locomotive.Models.ContentEntry(_this.options["" + name + "_new_entry"]);
- view = new Locomotive.Views.Shared.Fields.HasManyView({
+ view = new Locomotive.Views.Shared.Fields.ManyToManyView({
model: _this.model,
name: name,
- new_entry: new_entry,
- inverse_of: inverse_of
+ all_entries: _this.options["all_" + name + "_entries"]
});
if (view.ui_enabled()) {
- _this._has_many_field_views.push(view);
+ _this._many_to_many_field_views.push(view);
return _this.$("#" + _this.model.paramRoot + "_" + name + "_input label").after(view.render().el);
}
- });
- }
+ };
+ })(this));
};
- FormView.prototype.enable_many_to_many_fields = function() {
- var _this = this;
- return _.each(this.model.get('many_to_many_custom_fields'), function(field) {
- var name, view;
- name = field[0];
- view = new Locomotive.Views.Shared.Fields.ManyToManyView({
- model: _this.model,
- name: name,
- all_entries: _this.options["all_" + name + "_entries"]
- });
- if (view.ui_enabled()) {
- _this._many_to_many_field_views.push(view);
- return _this.$("#" + _this.model.paramRoot + "_" + name + "_input label").after(view.render().el);
- }
- });
- };
-
FormView.prototype.slugify_label_field = function() {
return this.$('li.input.highlighted > input[type=text]').slugify({
target: this.$('#content_entry__slug'),
url: window.permalink_service_url
});
};
FormView.prototype.refresh_file_fields = function() {
- var _this = this;
- return _.each(this._file_field_views, function(view) {
- return view.refresh();
- });
+ return _.each(this._file_field_views, (function(_this) {
+ return function(view) {
+ return view.refresh();
+ };
+ })(this));
};
FormView.prototype.refresh = function() {
- var _this = this;
this.$('li.input.toggle input[type=checkbox]').checkToggle('sync');
- return _.each(this._file_field_views, function(view) {
- return view.refresh();
- });
+ return this.refresh_file_fields();
};
FormView.prototype.reset = function() {
- var _this = this;
this.$('li.input.string input[type=text], li.input.text textarea, li.input.date input[type=text]').val('').trigger('change');
- _.each(this.$('li.input.rte textarea.html'), function(textarea) {
- $(textarea).tinymce().setContent('');
- return $(textarea).trigger('change');
- });
- _.each(this._file_field_views, function(view) {
- return view.reset();
- });
+ _.each(this.$('li.input.rte textarea.html'), (function(_this) {
+ return function(textarea) {
+ $(textarea).tinymce().setContent('');
+ return $(textarea).trigger('change');
+ };
+ })(this));
+ _.each(this._file_field_views, (function(_this) {
+ return function(view) {
+ return view.reset();
+ };
+ })(this));
return this.$('li.input.toggle input[type=checkbox]').checkToggle('sync');
};
FormView.prototype.remove = function() {
- var _this = this;
this.$('li.input.date input[type=text]').datepicker('destroy');
this.$('li.input.date_time input[type=text]').datetimepicker('destroy');
this._select_field_view.remove();
- _.each(this._file_field_views, function(view) {
- return view.remove();
- });
- _.each(this._has_many_field_views, function(view) {
- return view.remove();
- });
- _.each(this._many_to_many_field_views, function(view) {
- return view.remove();
- });
+ _.each(this._file_field_views, (function(_this) {
+ return function(view) {
+ return view.remove();
+ };
+ })(this));
+ _.each(this._has_many_field_views, (function(_this) {
+ return function(view) {
+ return view.remove();
+ };
+ })(this));
+ _.each(this._many_to_many_field_views, (function(_this) {
+ return function(view) {
+ return view.remove();
+ };
+ })(this));
return FormView.__super__.remove.apply(this, arguments);
};
FormView.prototype.tinyMCE_settings = function() {
return window.Locomotive.tinyMCE.defaultSettings;
@@ -45792,11 +46532,11 @@
})(Locomotive.Views.Shared.FormView);
}).call(this);
(function() {
- var _base, _ref,
+ var _base,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
(_base = Locomotive.Views).ContentEntries || (_base.ContentEntries = {});
@@ -45804,12 +46544,11 @@
Locomotive.Views.ContentEntries.PopupFormView = (function(_super) {
__extends(PopupFormView, _super);
function PopupFormView() {
this.reset = __bind(this.reset, this);
- _ref = PopupFormView.__super__.constructor.apply(this, arguments);
- return _ref;
+ return PopupFormView.__super__.constructor.apply(this, arguments);
}
PopupFormView.prototype.initialize = function() {
this.create_dialog();
return PopupFormView.__super__.initialize.call(this);
@@ -45819,55 +46558,60 @@
PopupFormView.__super__.render.call(this);
return this;
};
PopupFormView.prototype.save = function(event) {
- var _this = this;
+ this.touch_richtexteditor();
return this.save_in_ajax(event, {
headers: {
'X-Flash': true
},
- on_success: function(response, xhr) {
- var entry;
- entry = new Locomotive.Models.ContentEntry(JSON.parse(xhr.responseText));
- _this.options.parent_view.insert_or_update_entry(entry);
- return _this.close();
- }
+ on_success: (function(_this) {
+ return function(response, xhr) {
+ var entry;
+ entry = new Locomotive.Models.ContentEntry(JSON.parse(xhr.responseText));
+ _this.options.parent_view.insert_or_update_entry(entry);
+ return _this.close();
+ };
+ })(this)
});
};
PopupFormView.prototype.create_dialog = function() {
- var _this = this;
return this.dialog = $(this.el).dialog({
autoOpen: false,
modal: true,
dialogClass: 'content-entry-popup',
zIndex: window.application_view.unique_dialog_zindex(),
width: 770,
- create: function(event, ui) {
- var actions;
- $(_this.el).prev().find('.ui-dialog-title').html(_this.$('h2').html());
- _this.$('h2').remove();
- actions = _this.$('.dialog-actions').appendTo($(_this.el).parent()).addClass('ui-dialog-buttonpane ui-widget-content ui-helper-clearfix');
- actions.find('#close-link').click(function(event) {
- return _this.close(event);
- });
- return actions.find('input[type=submit]').click(function(event) {
- var $buttons_pane, $form;
- $form = _this.$el.find('form');
- $buttons_pane = $(event.target).parent();
- $.rails.disableFormElements($buttons_pane);
- return $form.trigger('submit').bind('ajax:complete', function() {
- return $.rails.enableFormElements($buttons_pane);
+ create: (function(_this) {
+ return function(event, ui) {
+ var actions;
+ $(_this.el).prev().find('.ui-dialog-title').html(_this.$('h2').html());
+ _this.$('h2').remove();
+ actions = _this.$('.dialog-actions').appendTo($(_this.el).parent()).addClass('ui-dialog-buttonpane ui-widget-content ui-helper-clearfix');
+ actions.find('#close-link').click(function(event) {
+ return _this.close(event);
});
- });
- },
- open: function(event, ui, extra) {
- return $(_this.el).dialog('overlayEl').bind('click', function() {
- return _this.close();
- });
- }
+ return actions.find('input[type=submit]').click(function(event) {
+ var $buttons_pane, $form;
+ $form = _this.$el.find('form');
+ $buttons_pane = $(event.target).parent();
+ $.rails.disableFormElements($buttons_pane);
+ return $form.trigger('submit').bind('ajax:complete', function() {
+ return $.rails.enableFormElements($buttons_pane);
+ });
+ });
+ };
+ })(this),
+ open: (function(_this) {
+ return function(event, ui, extra) {
+ return $(_this.el).dialog('overlayEl').bind('click', function() {
+ return _this.close();
+ });
+ };
+ })(this)
});
};
PopupFormView.prototype.open = function() {
var parent_el;
@@ -45895,10 +46639,11 @@
PopupFormView.prototype.center = function() {
return $(this.el).dialog('option', 'position', 'center');
};
PopupFormView.prototype.reset = function(entry) {
+ this.model.reset_attributes();
this.model.set(entry.attributes);
if (entry.isNew()) {
this.model.id = null;
return PopupFormView.__super__.reset.call(this);
} else {
@@ -45910,10 +46655,18 @@
PopupFormView.prototype.enable_has_many_fields = function() {};
PopupFormView.prototype.enable_many_to_many_fields = function() {};
+ PopupFormView.prototype.touch_richtexteditor = function() {
+ return _.each(this.$('li.input.rte textarea.html'), (function(_this) {
+ return function(textarea) {
+ return $(textarea).tinymce().save();
+ };
+ })(this));
+ };
+
PopupFormView.prototype.tinyMCE_settings = function() {
return window.Locomotive.tinyMCE.popupSettings;
};
return PopupFormView;
@@ -47286,22 +48039,21 @@
})(Backbone.View);
}).call(this);
(function() {
- var _base, _ref,
+ var _base,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
(_base = Locomotive.Views).InlineEditor || (_base.InlineEditor = {});
Locomotive.Views.InlineEditor.ApplicationView = (function(_super) {
__extends(ApplicationView, _super);
function ApplicationView() {
- _ref = ApplicationView.__super__.constructor.apply(this, arguments);
- return _ref;
+ return ApplicationView.__super__.constructor.apply(this, arguments);
}
ApplicationView.prototype.el = 'body';
ApplicationView.prototype.initialize = function() {
@@ -47322,65 +48074,67 @@
this.toolbar_view.render();
return this.content_assets_picker_view.render();
};
ApplicationView.prototype.enable_iframe_autoheight = function() {
- var iframe,
- _this = this;
+ var iframe;
iframe = this.iframe;
- return iframe.load(function() {
- var iframe_content;
- if (_this._$('meta[name=inline-editor]').size() > 0) {
- iframe_content = iframe.contents();
- iframe_content.resize(function() {
- var elem;
- elem = $(this);
- if (elem.outerHeight(true) > iframe.outerHeight(true)) {
- return iframe.css({
- height: elem.outerHeight(true)
- });
- }
- });
- return iframe_content.resize();
- } else {
- _this.toolbar_view.show_status('disabled', true).hide_editing_mode_block();
- return _this.enhance_iframe_links();
- }
- });
+ return iframe.load((function(_this) {
+ return function() {
+ var iframe_content;
+ if (_this._$('meta[name=inline-editor]').size() > 0) {
+ iframe_content = iframe.contents();
+ iframe_content.resize(function() {
+ var elem;
+ elem = $(this);
+ if (elem.outerHeight(true) > iframe.outerHeight(true)) {
+ return iframe.css({
+ height: elem.outerHeight(true)
+ });
+ }
+ });
+ return iframe_content.resize();
+ } else {
+ _this.toolbar_view.show_status('disabled', true).hide_editing_mode_block();
+ return _this.enhance_iframe_links();
+ }
+ };
+ })(this));
};
ApplicationView.prototype.set_page = function(attributes) {
this.page = new Locomotive.Models.Page(attributes);
this.toolbar_view.model = this.page;
this.enhance_iframe();
return this.toolbar_view.refresh();
};
ApplicationView.prototype.enhance_iframe = function() {
- var _window,
- _this = this;
+ var _window;
_window = this._window();
_window.Aloha.settings.locale = window.locale;
window.document.title = _window.document.title;
window.history.replaceState('OBJECT', 'TITLE', _window.location.href.replace('_edit', '_admin'));
if ($.browser.webkit) {
window.history.pushState('OBJECT', 'TITLE', _window.location.href.replace('_edit', '_admin'));
}
this.enhance_iframe_links(_window.Aloha.jQuery);
- return _window.Aloha.bind('aloha-editable-deactivated', function(event, editable) {
- return _this.toolbar_view.notify(editable.editable);
- });
+ return _window.Aloha.bind('aloha-editable-deactivated', (function(_this) {
+ return function(event, editable) {
+ return _this.toolbar_view.notify(editable.editable);
+ };
+ })(this));
};
ApplicationView.prototype.enhance_iframe_links = function(_jQuery) {
var toolbar_view, _window;
toolbar_view = this.toolbar_view;
_jQuery || (_jQuery = this._$);
_window = this._window();
return _jQuery('a[class!="ui-tabs-anchor"]').live('click', function(event) {
var link, url;
- link = _jQuery(event.target);
+ link = _jQuery(this);
url = link.attr('href');
if ((url != null) && url.indexOf('#') !== 0 && /^(www|http)/.exec(url) === null && /(\/_edit)$/.exec(url) === null && /^\/sites\//.exec(url) === null) {
if (!link.parents('div.editable-long-text, div.editable-short-text').hasClass('aloha-editable')) {
if (url === '/') {
url = '/index';
@@ -47653,22 +48407,21 @@
})(Locomotive.Views.Shared.FormView);
}).call(this);
(function() {
- var _base, _ref,
+ var _base,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
(_base = Locomotive.Views).Pages || (_base.Pages = {});
Locomotive.Views.Pages.FormView = (function(_super) {
__extends(FormView, _super);
function FormView() {
- _ref = FormView.__super__.constructor.apply(this, arguments);
- return _ref;
+ return FormView.__super__.constructor.apply(this, arguments);
}
FormView.prototype.el = '#content';
FormView.prototype.events = {
@@ -47718,42 +48471,44 @@
this.editor.replaceSelection(text);
return this.image_picker_view.close();
};
FormView.prototype.replace_template = function(event) {
- var link,
- _this = this;
+ var link;
event.stopPropagation() & event.preventDefault();
link = $(event.target).closest('a');
return $.rails.ajax({
url: link.attr('href'),
type: 'get',
dataType: 'json',
- success: function(data) {
- return _this.editor.setValue(data.raw_template);
- }
+ success: (function(_this) {
+ return function(data) {
+ return _this.editor.setValue(data.raw_template);
+ };
+ })(this)
});
};
FormView.prototype.enable_liquid_editing = function() {
- var input,
- _this = this;
+ var input;
input = this.$('#page_raw_template');
if (input.size() > 0) {
this.editor = CodeMirror.fromTextArea(input.get()[0], {
mode: 'liquid',
autoMatchParens: false,
lineNumbers: true,
passDelay: 50,
tabMode: 'shift',
theme: 'default'
});
- return this.editor.on('change', function(editor, change) {
- return _this.model.set({
- raw_template: editor.getValue()
- });
- });
+ return this.editor.on('change', (function(_this) {
+ return function(editor, change) {
+ return _this.model.set({
+ raw_template: editor.getValue()
+ });
+ };
+ })(this));
}
};
FormView.prototype.after_inputs_fold = function() {
return this.editor.refresh();
@@ -47775,101 +48530,109 @@
this.editable_elements_view.collection = this.model.get('editable_elements');
return this.editable_elements_view.refresh();
};
FormView.prototype.slugify_title = function() {
- var _this = this;
this.$('#page_title').slugify({
target: this.$('#page_slug'),
url: window.permalink_service_url
});
- return this.$('#page_slug').bind('change', (function(event) {
- return _this.touched_url = true;
- }));
+ return this.$('#page_slug').bind('change', ((function(_this) {
+ return function(event) {
+ return _this.touched_url = true;
+ };
+ })(this)));
};
FormView.prototype.listen_for_url_changes = function() {
- var _this = this;
- return setInterval((function() {
- if (_this.touched_url) {
- return _this.change_page_url() & (_this.touched_url = false);
- }
- }), 1200);
+ return setInterval(((function(_this) {
+ return function() {
+ if (_this.touched_url) {
+ return _this.change_page_url() & (_this.touched_url = false);
+ }
+ };
+ })(this)), 1200);
};
FormView.prototype.change_page_url = function() {
- var _this = this;
return $.rails.ajax({
url: this.$('#page_slug').data('url'),
type: 'get',
dataType: 'json',
data: {
parent_id: this.$('#page_parent_id').val(),
slug: this.$('#page_slug').val()
},
- success: function(data) {
- _this.$('#page_slug_input .inline-hints').html(data.url).effect('highlight');
- if (data.templatized_parent) {
- _this.$('li#page_slug_input').show();
- return _this.$('li#page_templatized_input, li#page_target_klass_name_input').hide();
- } else {
- if (!_this.model.get('redirect')) {
- return _this.$('li#page_templatized_input').show();
+ success: (function(_this) {
+ return function(data) {
+ _this.$('#page_slug_input .inline-hints').html(data.url).effect('highlight');
+ if (data.templatized_parent) {
+ _this.$('li#page_slug_input').show();
+ return _this.$('li#page_templatized_input, li#page_target_klass_name_input').hide();
+ } else {
+ if (!_this.model.get('redirect')) {
+ return _this.$('li#page_templatized_input').show();
+ }
}
- }
- }
+ };
+ })(this)
});
};
FormView.prototype.enable_response_type_select = function() {
- var _this = this;
- return this.$('li#page_response_type_input').change(function(event) {
- if ($(event.target).val() === 'text/html') {
- return _this.$('li#page_redirect_input, li#page_redirect_url_input, li#page_redirect_type_input').show();
- } else {
- _this.model.set({
- redirect: false
- });
- return _this.$('li#page_redirect_input, li#page_redirect_url_input, li#page_redirect_type_input').hide();
- }
- });
+ return this.$('li#page_response_type_input').change((function(_this) {
+ return function(event) {
+ if ($(event.target).val() === 'text/html') {
+ return _this.$('li#page_redirect_input, li#page_redirect_url_input, li#page_redirect_type_input').show();
+ } else {
+ _this.model.set({
+ redirect: false
+ });
+ return _this.$('li#page_redirect_input, li#page_redirect_url_input, li#page_redirect_type_input').hide();
+ }
+ };
+ })(this));
};
FormView.prototype.enable_templatized_checkbox = function() {
- var _this = this;
this._enable_checkbox('templatized', {
features: ['slug', 'redirect', 'listed'],
- on_callback: function() {
- return _this.$('li#page_target_klass_name_input').show();
- },
- off_callback: function() {
- return _this.$('li#page_target_klass_name_input').hide();
- }
+ on_callback: (function(_this) {
+ return function() {
+ return _this.$('li#page_target_klass_name_input').show();
+ };
+ })(this),
+ off_callback: (function(_this) {
+ return function() {
+ return _this.$('li#page_target_klass_name_input').hide();
+ };
+ })(this)
});
if (this.model.get('templatized_from_parent') === true) {
return this.$('li#page_templatized_input').hide();
}
};
FormView.prototype.enable_redirect_checkbox = function() {
- var _this = this;
return this._enable_checkbox('redirect', {
features: ['templatized', 'cache_strategy'],
- on_callback: function() {
- return _this.$('li#page_redirect_url_input, li#page_redirect_type_input').show();
- },
- off_callback: function() {
- return _this.$('li#page_redirect_url_input, li#page_redirect_type_input').hide();
- }
+ on_callback: (function(_this) {
+ return function() {
+ return _this.$('li#page_redirect_url_input, li#page_redirect_type_input').show();
+ };
+ })(this),
+ off_callback: (function(_this) {
+ return function() {
+ return _this.$('li#page_redirect_url_input, li#page_redirect_type_input').hide();
+ };
+ })(this)
});
};
FormView.prototype.enable_other_checkboxes = function() {
- var _this = this;
- return _.each(['published', 'listed'], function(exp) {
- return _this.$('li#page_' + exp + '_input input[type=checkbox]').checkToggle();
- });
+ this.$('li.toggle input[type=checkbox].simple-toggle').checkToggle();
+ return this.$('li.toggle.simple-toggle input[type=checkbox]').checkToggle();
};
return FormView;
})(Locomotive.Views.Shared.FormView);
@@ -48049,79 +48812,135 @@
})(Locomotive.Views.Pages.FormView);
}).call(this);
(function() {
- var _base, _base1, _ref,
+ var _base, _base1,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
(_base = Locomotive.Views).Shared || (_base.Shared = {});
(_base1 = Locomotive.Views.Shared).Fields || (_base1.Fields = {});
- Locomotive.Views.Shared.Fields.BelongsToView = (function(_super) {
- __extends(BelongsToView, _super);
+ Locomotive.Views.Shared.Fields.RelationshipView = (function(_super) {
+ __extends(RelationshipView, _super);
- function BelongsToView() {
- _ref = BelongsToView.__super__.constructor.apply(this, arguments);
- return _ref;
+ function RelationshipView() {
+ return RelationshipView.__super__.constructor.apply(this, arguments);
}
- BelongsToView.prototype.render = function() {
- this.enable_select2();
- return this;
- };
-
- BelongsToView.prototype.enable_select2 = function() {
- var options,
- _this = this;
- options = $(this.el).data();
- $(this.el).select2({
+ RelationshipView.prototype.enable_select2 = function(element, options) {
+ options || (options = {});
+ options.init_selection_fn || (options.init_selection_fn = function(element, callback) {
+ return null;
+ });
+ return element.select2({
width: '50%',
minimumInputLength: 1,
quietMillis: 100,
allowClear: true,
placeholder: ' ',
+ initSelection: options.init_selection_fn,
ajax: {
url: options.url,
data: function(term, page) {
return {
q: term,
page: page
};
},
- results: function(data, page) {
- return {
- results: data.map(function(item) {
- return {
- id: item._id,
- text: item._label || ''
- };
- }),
- more: data.length === options.perPage
+ results: (function(_this) {
+ return function(data, page) {
+ return {
+ results: _this.build_results(data, options.groupBy),
+ more: data.length === options.perPage
+ };
};
- }
- },
- initSelection: function(el, callback) {
- return callback({
- id: el.val(),
- text: options.value
- });
+ })(this)
}
});
- return $(this.el).on('select2-selecting', function(el) {
- return _this.model.set("" + _this.options.name + "_id", el.val);
- });
};
- return BelongsToView;
+ RelationshipView.prototype.build_results = function(raw_data, group_by) {
+ return _.tap([], (function(_this) {
+ return function(list) {
+ return _.each(raw_data, function(data) {
+ var group, group_name;
+ if ((_this.collection == null) || (_this.collection.get(data._id) == null)) {
+ data.text = data._label;
+ if (group_by != null) {
+ group_name = _.result(data, group_by);
+ group = _.find(list, function(_group) {
+ return _group.text === group_name;
+ });
+ if (group == null) {
+ group = {
+ text: group_name,
+ children: []
+ };
+ list.push(group);
+ }
+ return group.children.push(data);
+ } else {
+ return list.push(data);
+ }
+ }
+ });
+ };
+ })(this));
+ };
+ return RelationshipView;
+
})(Backbone.View);
}).call(this);
(function() {
+ var _base, _base1,
+ __hasProp = {}.hasOwnProperty,
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
+
+ (_base = Locomotive.Views).Shared || (_base.Shared = {});
+
+ (_base1 = Locomotive.Views.Shared).Fields || (_base1.Fields = {});
+
+ Locomotive.Views.Shared.Fields.BelongsToView = (function(_super) {
+ __extends(BelongsToView, _super);
+
+ function BelongsToView() {
+ return BelongsToView.__super__.constructor.apply(this, arguments);
+ }
+
+ BelongsToView.prototype.render = function() {
+ this.enable_select2();
+ return this;
+ };
+
+ BelongsToView.prototype.enable_select2 = function() {
+ var options;
+ options = $(this.el).data();
+ options.init_selection_fn = function(el, callback) {
+ return callback({
+ id: el.val(),
+ text: options.value
+ });
+ };
+ BelongsToView.__super__.enable_select2.call(this, $(this.el), options);
+ return $(this.el).on('select2-selecting', (function(_this) {
+ return function(el) {
+ return _this.model.set("" + _this.options.name + "_id", el.val);
+ };
+ })(this));
+ };
+
+ return BelongsToView;
+
+ })(Locomotive.Views.Shared.Fields.RelationshipView);
+
+}).call(this);
+(function() {
var _base, _base1, _ref,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
(_base = Locomotive.Views).Shared || (_base.Shared = {});
@@ -48415,11 +49234,11 @@
})(Backbone.View);
}).call(this);
(function() {
- var _base, _base1, _ref,
+ var _base, _base1,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
(_base = Locomotive.Views).Shared || (_base.Shared = {});
@@ -48427,21 +49246,20 @@
Locomotive.Views.Shared.Fields.ManyToManyView = (function(_super) {
__extends(ManyToManyView, _super);
function ManyToManyView() {
- _ref = ManyToManyView.__super__.constructor.apply(this, arguments);
- return _ref;
+ return ManyToManyView.__super__.constructor.apply(this, arguments);
}
ManyToManyView.prototype.tagName = 'div';
ManyToManyView.prototype.className = 'list';
ManyToManyView.prototype.events = {
'click .new-entry a.add': 'add_entry',
- 'keypress .new-entry select': 'add_entry',
+ 'keypress .new-entry input.selected-entry': 'add_entry',
'click ul span.actions a.remove': 'remove_entry'
};
ManyToManyView.prototype.template = function() {
return ich["" + this.options.name + "_list"];
@@ -48451,32 +49269,32 @@
return ich["" + this.options.name + "_entry"];
};
ManyToManyView.prototype.initialize = function() {
_.bindAll(this, 'refresh_position_entries');
- this.collection = this.model.get(this.options.name);
- return this.all_entries = this.options.all_entries;
+ return this.collection = this.model.get(this.options.name);
};
ManyToManyView.prototype.render = function() {
$(this.el).html(this.template()()).attr('id', "" + this.model.paramRoot + "_" + this.options.name + "_ids");
this.insert_entries();
this.make_entries_sortable();
- this.refresh_select_field();
+ this.enable_select2();
return this;
};
ManyToManyView.prototype.ui_enabled = function() {
return this.template() != null;
};
ManyToManyView.prototype.insert_entries = function() {
- var _this = this;
if (this.collection.length > 0) {
- return this.collection.each(function(entry) {
- return _this.insert_entry(entry);
- });
+ return this.collection.each((function(_this) {
+ return function(entry) {
+ return _this.insert_entry(entry);
+ };
+ })(this));
} else {
return this.$('.empty').show();
}
};
@@ -48501,29 +49319,30 @@
update: this.refresh_position_entries
});
};
ManyToManyView.prototype.refresh_position_entries = function() {
- var _this = this;
- return this.$('> ul > li').each(function(index, entry_html) {
- var entry, id;
- id = $(entry_html).data('data-entry-id');
- entry = _this.collection.get(id);
- return entry.set_attribute("__position", index);
- });
+ return this.$('> ul > li').each((function(_this) {
+ return function(index, entry_html) {
+ var entry, id;
+ id = $(entry_html).data('data-entry-id');
+ entry = _this.collection.get(id);
+ return entry.set_attribute("__position", index);
+ };
+ })(this));
};
ManyToManyView.prototype.add_entry = function(event) {
- var entry, entry_id;
+ var data, entry;
event.stopPropagation() & event.preventDefault();
- entry_id = this.$('.new-entry select').val();
- entry = this.get_entry_from_id(entry_id);
- if (entry == null) {
+ data = this.$('.new-entry .selected-entry').select2('data');
+ if ((data == null) || _.isArray(data)) {
return;
}
+ entry = new Locomotive.Models.ContentEntry(data);
this.insert_entry(entry);
- return this.refresh_select_field();
+ return this.$('.new-entry .selected-entry').select2('val', '');
};
ManyToManyView.prototype.remove_entry = function(event) {
var entry;
event.stopPropagation() & event.preventDefault();
@@ -48532,70 +49351,31 @@
this.collection.remove(entry);
$(event.target).closest('li').remove();
if (this.$('> ul > li').size() === 0) {
this.$('.empty').show();
}
- return this.refresh_position_entries() & this.refresh_select_field();
+ return this.refresh_position_entries();
}
};
- ManyToManyView.prototype.refresh_select_field = function() {
- var _this = this;
- this.$('.new-entry select optgroup, .new-entry select option').remove();
- return _.each(this.all_entries, function(entry_or_group) {
- var group_html, option;
- if (_.isArray(entry_or_group.entries)) {
- group_html = $('<optgroup/>').attr('label', entry_or_group.name);
- _.each(entry_or_group.entries, function(entry) {
- var option;
- if (_this.collection.get(entry._id) == null) {
- option = new Option(entry._label, entry._id, false);
- return group_html.append(option);
- }
- });
- return _this.$('.new-entry select').append(group_html);
- } else {
- if (_this.collection.get(entry_or_group._id) == null) {
- option = new Option(entry_or_group._label, entry_or_group._id, false);
- return _this.$('.new-entry select').append(option);
- }
- }
- });
+ ManyToManyView.prototype.enable_select2 = function() {
+ var $input, options;
+ $input = this.$('.new-entry .selected-entry');
+ options = $input.data();
+ return ManyToManyView.__super__.enable_select2.call(this, $input, options);
};
ManyToManyView.prototype.get_entry_from_element = function(element) {
var entry_html, id;
entry_html = $(element).closest('li');
id = $(entry_html).data('data-entry-id');
return this.collection.get(id);
};
- ManyToManyView.prototype.get_entry_from_id = function(id) {
- var entry,
- _this = this;
- entry = null;
- _.each(this.all_entries, function(entry_or_group) {
- if (_.isArray(entry_or_group.entries)) {
- return entry || (entry = _.detect(entry_or_group.entries, function(_entry) {
- return _entry._id === id;
- }));
- } else {
- if (entry_or_group._id === id) {
- return entry = entry_or_group;
- }
- }
- });
- if (entry != null) {
- return new Locomotive.Models.ContentEntry(entry);
- } else {
- return null;
- }
- };
-
return ManyToManyView;
- })(Backbone.View);
+ })(Locomotive.Views.Shared.Fields.RelationshipView);
}).call(this);
(function() {
var _base, _base1, _ref,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
@@ -49073,22 +49853,21 @@
})(Locomotive.Views.Shared.FormView);
}).call(this);
(function() {
- var _base, _ref,
+ var _base,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
(_base = Locomotive.Views).Snippets || (_base.Snippets = {});
Locomotive.Views.Snippets.FormView = (function(_super) {
__extends(FormView, _super);
function FormView() {
- _ref = FormView.__super__.constructor.apply(this, arguments);
- return _ref;
+ return FormView.__super__.constructor.apply(this, arguments);
}
FormView.prototype.el = '#content';
FormView.prototype.events = {
@@ -49116,12 +49895,11 @@
};
FormView.prototype.slugify_name = function() {
return this.$('#snippet_name').slugify({
target: this.$('#snippet_slug'),
- url: window.permalink_service_url,
- underscore: true
+ url: window.permalink_service_url
});
};
FormView.prototype.open_image_picker = function(event) {
event.stopPropagation() & event.preventDefault();
@@ -49135,41 +49913,43 @@
this.editor.replaceSelection(text);
return this.image_picker_view.close();
};
FormView.prototype.replace_template = function(event) {
- var link,
- _this = this;
+ var link;
event.stopPropagation() & event.preventDefault();
link = $(event.target).closest('a');
return $.rails.ajax({
url: link.attr('href'),
type: 'get',
dataType: 'json',
- success: function(data) {
- return _this.editor.setValue(data.template);
- }
+ success: (function(_this) {
+ return function(data) {
+ return _this.editor.setValue(data.template);
+ };
+ })(this)
});
};
FormView.prototype.enable_liquid_editing = function() {
- var input,
- _this = this;
+ var input;
input = this.$('#snippet_template');
this.editor = CodeMirror.fromTextArea(input.get()[0], {
mode: 'liquid',
autoMatchParens: false,
lineNumbers: false,
passDelay: 50,
tabMode: 'shift',
theme: 'default medium'
});
- return this.editor.on('change', function(editor, change) {
- return _this.model.set({
- template: editor.getValue()
- });
- });
+ return this.editor.on('change', (function(_this) {
+ return function(editor, change) {
+ return _this.model.set({
+ template: editor.getValue()
+ });
+ };
+ })(this));
};
FormView.prototype.after_inputs_fold = function() {
return this.editor.refresh();
};
@@ -49481,22 +50261,21 @@
})(Locomotive.Views.ThemeAssets.FormView);
}).call(this);
(function() {
- var _base, _ref,
+ var _base,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
(_base = Locomotive.Views).ThemeAssets || (_base.ThemeAssets = {});
Locomotive.Views.ThemeAssets.ImagePickerView = (function(_super) {
__extends(ImagePickerView, _super);
function ImagePickerView() {
- _ref = ImagePickerView.__super__.constructor.apply(this, arguments);
- return _ref;
+ return ImagePickerView.__super__.constructor.apply(this, arguments);
}
ImagePickerView.prototype.events = {
'click ul.list a': 'select_asset'
};
@@ -49509,47 +50288,49 @@
ImagePickerView.prototype.template = function() {
return ich.theme_image_picker;
};
ImagePickerView.prototype.fetch_assets = function() {
- var _this = this;
this._reset();
return this.collection.fetch({
data: {
content_type: 'image'
},
- success: function() {
- return _this.open();
- }
+ success: (function(_this) {
+ return function() {
+ return _this.open();
+ };
+ })(this)
});
};
ImagePickerView.prototype.build_uploader = function(el, link) {
- var _this = this;
link.bind('click', function(event) {
event.stopPropagation() & event.preventDefault();
return el.click();
});
- return el.bind('change', function(event) {
- return _.each(event.target.files, function(file) {
- var asset;
- asset = new Locomotive.Models.ThemeAsset({
- source: file
+ return el.bind('change', (function(_this) {
+ return function(event) {
+ return _.each(event.target.files, function(file) {
+ var asset;
+ asset = new Locomotive.Models.ThemeAsset({
+ source: file
+ });
+ return asset.save({}, {
+ headers: {
+ 'X-Flash': true
+ },
+ success: function(model) {
+ return _this.collection.add(model);
+ },
+ error: function() {
+ return _this.shake();
+ }
+ });
});
- return asset.save({}, {
- headers: {
- 'X-Flash': true
- },
- success: function(model) {
- return _this.collection.add(model);
- },
- error: function() {
- return _this.shake();
- }
- });
- });
- });
+ };
+ })(this));
};
ImagePickerView.prototype.select_asset = function(event) {
event.stopPropagation() & event.preventDefault();
if (this.options.on_select) {
@@ -49925,6 +50706,6 @@
$(document).ready(function() {
$.datepicker.setDefaults($.datepicker.regional[window.locale]);
});
-; TI"required_assets_digest; TI"%3278809b02741b32a867a3bf3c0a4b25; FI"
_version; TI"%ffd318ca8b794f42f5029101c2cf5d91; F
+; TI"required_assets_digest; TI"%b00294ded64bfd6313083a653b4b4b7a; FI"
_version; TI"%ffd318ca8b794f42f5029101c2cf5d91; F
\ No newline at end of file