Changeset 160500 in webkit
- Timestamp:
- Dec 12, 2013 11:52:46 AM (10 years ago)
- Location:
- trunk/Source/WebInspectorUI
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebInspectorUI/ChangeLog
r160483 r160500 1 2013-12-12 Laszlo Vidacs <lac@inf.u-szeged.hu> 2 3 Web Inspector: ES6: JavaScript syntax highlighting and recognition of for..of 4 https://bugs.webkit.org/show_bug.cgi?id=122868 5 6 Reviewed by Timothy Hatcher. 7 8 Update to CodeMirror 3.20 including javascript ES6 updates. 9 10 * Tools/PrettyPrinting/codemirror.css: 11 * Tools/PrettyPrinting/codemirror.js: Minor local change due to error from jsmin.py 12 * Tools/PrettyPrinting/css.js: 13 * Tools/PrettyPrinting/javascript.js: 14 * UserInterface/External/CodeMirror/codemirror.css: 15 * UserInterface/External/CodeMirror/codemirror.js: Minor local change due to error from jsmin.py 16 * UserInterface/External/CodeMirror/coffeescript.js: 17 * UserInterface/External/CodeMirror/css.js: 18 * UserInterface/External/CodeMirror/htmlmixed.js: 19 * UserInterface/External/CodeMirror/javascript.js: 20 * UserInterface/External/CodeMirror/less.js: 21 * UserInterface/External/CodeMirror/matchbrackets.js: 22 * UserInterface/External/CodeMirror/placeholder.js: 23 * UserInterface/External/CodeMirror/runmode.js: 24 * UserInterface/External/CodeMirror/searchcursor.js: 25 * UserInterface/External/CodeMirror/sql.js: 26 * UserInterface/External/CodeMirror/xml.js: 27 1 28 2013-12-12 Antoine Quint <graouts@apple.com> 2 29 -
trunk/Source/WebInspectorUI/Tools/PrettyPrinting/codemirror.css
r155659 r160500 75 75 .cm-s-default .cm-string-2 {color: #f50;} 76 76 .cm-s-default .cm-meta {color: #555;} 77 .cm-s-default .cm-error {color: #f00;}78 77 .cm-s-default .cm-qualifier {color: #555;} 79 78 .cm-s-default .cm-builtin {color: #30a;} … … 92 91 .cm-link {text-decoration: underline;} 93 92 93 .cm-s-default .cm-error {color: #f00;} 94 94 .cm-invalidchar {color: #f00;} 95 95 -
trunk/Source/WebInspectorUI/Tools/PrettyPrinting/codemirror.js
r155659 r160500 8 8 // bugs and behavior differences. 9 9 var gecko = /gecko\/\d/i.test(navigator.userAgent); 10 // IE11 currently doesn't count as 'ie', since it has almost none of 11 // the same bugs as earlier versions. Use ie_gt10 to handle 12 // incompatibilities in that version. 10 13 var ie = /MSIE \d/.test(navigator.userAgent); 11 14 var ie_lt8 = ie && (document.documentMode == null || document.documentMode < 8); 12 15 var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9); 16 var ie_gt10 = /Trident\/([7-9]|\d{2,})\./.test(navigator.userAgent); 13 17 var webkit = /WebKit\//.test(navigator.userAgent); 14 18 var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent); … … 310 314 } else if (found > -1 && !options.lineNumbers) { 311 315 options.gutters = options.gutters.slice(0); 312 options.gutters.splice( i, 1);316 options.gutters.splice(found, 1); 313 317 } 314 318 } … … 354 358 } else d.gutterFiller.style.display = ""; 355 359 356 if (mac_geLion && scrollbarWidth(d.measure) === 0) 360 if (mac_geLion && scrollbarWidth(d.measure) === 0) { 357 361 d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = mac_geMountainLion ? "18px" : "12px"; 362 d.scrollbarV.style.pointerEvents = d.scrollbarH.style.pointerEvents = "none"; 363 } 358 364 } 359 365 … … 410 416 var oldFrom = cm.display.showingFrom, oldTo = cm.display.showingTo, updated; 411 417 var visible = visibleLines(cm.display, cm.doc, viewPort); 412 for ( ;;) {418 for (var first = true;; first = false) { 413 419 var oldWidth = cm.display.scroller.clientWidth; 414 420 if (!updateDisplayInner(cm, changes, visible, forced)) break; … … 417 423 updateSelection(cm); 418 424 updateScrollbars(cm); 419 if ( cm.options.lineWrapping && oldWidth != cm.display.scroller.clientWidth) {425 if (first && cm.options.lineWrapping && oldWidth != cm.display.scroller.clientWidth) { 420 426 forced = true; 421 427 continue; … … 905 911 if (doc.frontier >= cm.display.showingFrom) { // Visible 906 912 var oldStyles = line.styles; 907 line.styles = highlightLine(cm, line, state );913 line.styles = highlightLine(cm, line, state, true); 908 914 var ischange = !oldStyles || oldStyles.length != line.styles.length; 909 915 for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i]; … … 914 920 line.stateAfter = copyState(doc.mode, state); 915 921 } else { 916 processLine(cm, line , state);922 processLine(cm, line.text, state); 917 923 line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null; 918 924 } … … 936 942 // parse correctly. 937 943 function findStartLine(cm, n, precise) { 938 var minindent, minline, doc = cm.doc, maxScan = cm.doc.mode.innerMode ? 1000 : 100; 939 for (var search = n, lim = n - maxScan; search > lim; --search) { 944 var minindent, minline, doc = cm.doc; 945 var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100); 946 for (var search = n; search > lim; --search) { 940 947 if (search <= doc.first) return doc.first; 941 948 var line = getLine(doc, search - 1); … … 957 964 else state = copyState(doc.mode, state); 958 965 doc.iter(pos, n, function(line) { 959 processLine(cm, line , state);966 processLine(cm, line.text, state); 960 967 var save = pos == n - 1 || pos % 5 == 0 || pos >= display.showingFrom && pos < display.showingTo; 961 968 line.stateAfter = save ? copyState(doc.mode, state) : null; 962 969 ++pos; 963 970 }); 971 if (precise) doc.frontier = pos; 964 972 return state; 965 973 } … … 1002 1010 if (memo.text == line.text && memo.markedSpans == line.markedSpans && 1003 1011 cm.display.scroller.clientWidth == memo.width && 1004 memo.classes == line.textClass + "|" + line. bgClass + "|" + line.wrapClass)1012 memo.classes == line.textClass + "|" + line.wrapClass) 1005 1013 return memo; 1006 1014 } … … 1022 1030 var memo = {text: line.text, width: cm.display.scroller.clientWidth, 1023 1031 markedSpans: line.markedSpans, measure: measure, 1024 classes: line.textClass + "|" + line. bgClass + "|" + line.wrapClass};1032 classes: line.textClass + "|" + line.wrapClass}; 1025 1033 if (cache.length == 16) cache[++cm.display.measureLineCachePos % 16] = memo; 1026 1034 else cache.push(memo); … … 1380 1388 if (!updated && op.selectionChanged) updateSelection(cm); 1381 1389 if (op.updateScrollPos) { 1382 display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = newScrollPos.scrollTop; 1383 display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = newScrollPos.scrollLeft; 1390 var top = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, newScrollPos.scrollTop)); 1391 var left = Math.max(0, Math.min(display.scroller.scrollWidth - display.scroller.clientWidth, newScrollPos.scrollLeft)); 1392 display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = top; 1393 display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = left; 1384 1394 alignHorizontally(cm); 1385 1395 if (op.scrollToPos) 1386 scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos), op.scrollToPosMargin); 1396 scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos.from), 1397 clipPos(cm.doc, op.scrollToPos.to), op.scrollToPos.margin); 1387 1398 } else if (newScrollPos) { 1388 1399 scrollCursorIntoView(cm); … … 1606 1617 if (e.keyCode == 16) cm.doc.sel.shift = false; 1607 1618 })); 1608 on(d.input, "input", bind(fastPoll, cm)); 1619 on(d.input, "input", function() { 1620 if (ie && !ie_lt9 && cm.display.inputHasSelection) cm.display.inputHasSelection = null; 1621 fastPoll(cm); 1622 }); 1609 1623 on(d.input, "keydown", operation(cm, onKeyDown)); 1610 1624 on(d.input, "keypress", operation(cm, onKeyPress)); … … 1896 1910 cm.replaceSelection(text, null, "paste"); 1897 1911 focusInput(cm); 1898 onFocus(cm);1899 1912 } 1900 1913 } … … 2177 2190 var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop; 2178 2191 if (!pos || opera) return; // Opera is difficult. 2179 if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to)) 2192 2193 // Reset the current text selection only if the click is done outside of the selection 2194 // and 'resetSelectionOnContextMenu' option is true. 2195 var reset = cm.options.resetSelectionOnContextMenu; 2196 if (reset && (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to))) 2180 2197 operation(cm, setSelection)(cm.doc, pos, pos); 2181 2198 … … 2327 2344 2328 2345 function makeChangeNoReadonly(doc, change, selUpdate) { 2346 if (change.text.length == 1 && change.text[0] == "" && posEq(change.from, change.to)) return; 2329 2347 var selAfter = computeSelAfterChange(doc, change, selUpdate); 2330 2348 addToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN); … … 2627 2645 2628 2646 function scrollCursorIntoView(cm) { 2629 var coords = scrollPosIntoView(cm, cm.doc.sel.head, cm.options.cursorScrollMargin);2647 var coords = scrollPosIntoView(cm, cm.doc.sel.head, null, cm.options.cursorScrollMargin); 2630 2648 if (!cm.state.focused) return; 2631 2649 var display = cm.display, box = getRect(display.sizer), doScroll = null; … … 2644 2662 } 2645 2663 2646 function scrollPosIntoView(cm, pos, margin) {2664 function scrollPosIntoView(cm, pos, end, margin) { 2647 2665 if (margin == null) margin = 0; 2648 2666 for (;;) { 2649 2667 var changed = false, coords = cursorCoords(cm, pos); 2650 var scrollPos = calculateScrollPos(cm, coords.left, coords.top - margin, coords.left, coords.bottom + margin); 2668 var endCoords = !end || end == pos ? coords : cursorCoords(cm, end); 2669 var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left), 2670 Math.min(coords.top, endCoords.top) - margin, 2671 Math.max(coords.left, endCoords.left), 2672 Math.max(coords.bottom, endCoords.bottom) + margin); 2651 2673 var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft; 2652 2674 if (scrollPos.scrollTop != null) { … … 2745 2767 if (indentString != curSpaceString) 2746 2768 replaceRange(cm.doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input"); 2769 else if (doc.sel.head.line == n && doc.sel.head.ch < curSpaceString.length) 2770 setSelection(doc, Pos(n, curSpaceString.length), Pos(n, curSpaceString.length), 1); 2747 2771 line.stateAfter = null; 2748 2772 } … … 2845 2869 CodeMirror.prototype = { 2846 2870 constructor: CodeMirror, 2847 focus: function(){window.focus(); focusInput(this); onFocus(this);fastPoll(this);},2871 focus: function(){window.focus(); focusInput(this); fastPoll(this);}, 2848 2872 2849 2873 setOption: function(option, value) { … … 3166 3190 }, 3167 3191 3168 scrollIntoView: operation(null, function(pos, margin) { 3169 if (typeof pos == "number") pos = Pos(pos, 0); 3192 scrollIntoView: operation(null, function(range, margin) { 3193 if (range == null) range = {from: this.doc.sel.head, to: null}; 3194 else if (typeof range == "number") range = {from: Pos(range, 0), to: null}; 3195 else if (range.from == null) range = {from: range, to: null}; 3196 if (!range.to) range.to = range.from; 3170 3197 if (!margin) margin = 0; 3171 var coords = pos; 3172 3173 if (!pos || pos.line != null) { 3174 this.curOp.scrollToPos = pos ? clipPos(this.doc, pos) : this.doc.sel.head; 3175 this.curOp.scrollToPosMargin = margin; 3176 coords = cursorCoords(this, this.curOp.scrollToPos); 3177 } 3178 var sPos = calculateScrollPos(this, coords.left, coords.top - margin, coords.right, coords.bottom + margin); 3198 3199 var coords = range; 3200 if (range.from.line != null) { 3201 this.curOp.scrollToPos = {from: range.from, to: range.to, margin: margin}; 3202 coords = {from: cursorCoords(this, range.from), 3203 to: cursorCoords(this, range.to)}; 3204 } 3205 var sPos = calculateScrollPos(this, Math.min(coords.from.left, coords.to.left), 3206 Math.min(coords.from.top, coords.to.top) - margin, 3207 Math.max(coords.from.right, coords.to.right), 3208 Math.max(coords.from.bottom, coords.to.bottom) + margin); 3179 3209 updateScrollPos(this, sPos.scrollLeft, sPos.scrollTop); 3180 3210 }), … … 3208 3238 resetInput(this, true); 3209 3239 updateScrollPos(this, doc.scrollLeft, doc.scrollTop); 3240 signalLater(this, "swapDoc", this, old); 3210 3241 return old; 3211 3242 }), … … 3251 3282 regChange(cm); 3252 3283 }, true); 3284 option("specialChars", /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\ufeff]/g, function(cm, val) { 3285 cm.options.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g"); 3286 cm.refresh(); 3287 }, true); 3288 option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true); 3253 3289 option("electricChars", true); 3254 3290 option("rtlMoveVisually", !windows); 3291 option("wholeLineUpdateBefore", true); 3255 3292 3256 3293 option("theme", "default", function(cm) { … … 3282 3319 option("showCursorWhenSelecting", false, updateSelection, true); 3283 3320 3321 option("resetSelectionOnContextMenu", true); 3322 3284 3323 option("readOnly", false, function(cm, val) { 3285 if (val == "nocursor") {onBlur(cm); cm.display.input.blur();} 3286 else if (!val) resetInput(cm, true); 3324 if (val == "nocursor") { 3325 onBlur(cm); 3326 cm.display.input.blur(); 3327 cm.display.disabled = true; 3328 } else { 3329 cm.display.disabled = false; 3330 if (!val) resetInput(cm, true); 3331 } 3287 3332 }); 3288 3333 option("dragDrop", true); … … 3518 3563 "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown", 3519 3564 "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown", 3520 "Delete": "delCharAfter", "Backspace": "delCharBefore", "Tab": "defaultTab", "Shift-Tab": "indentAuto", 3565 "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore", 3566 "Tab": "defaultTab", "Shift-Tab": "indentAuto", 3521 3567 "Enter": "newlineAndIndent", "Insert": "toggleOverwrite" 3522 3568 }; … … 3824 3870 3825 3871 var marker = new TextMarker(doc, type); 3826 if (type == "range" && !posLess(from, to)) return marker; 3872 if (posLess(to, from) || posEq(from, to) && type == "range" && 3873 !(options.inclusiveLeft && options.inclusiveRight)) 3874 return marker; 3827 3875 if (options) copyObj(options, marker); 3828 3876 if (marker.replacedWith) { … … 3940 3988 var span = old[i], marker = span.marker; 3941 3989 var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh); 3942 if (startsBefore || marker.type == "bookmark" && span.from == startCh && (!isInsert || !span.marker.insertLeft)) { 3990 if (startsBefore || 3991 (marker.inclusiveLeft && marker.inclusiveRight || marker.type == "bookmark") && 3992 span.from == startCh && (!isInsert || !span.marker.insertLeft)) { 3943 3993 var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh); 3944 3994 (nw || (nw = [])).push({from: span.from, … … 4213 4263 }; 4214 4264 eventMixin(Line); 4265 Line.prototype.lineNo = function() { return lineNo(this); }; 4215 4266 4216 4267 function updateLine(line, text, markedSpans, estimateHeight) { … … 4233 4284 // array, which contains alternating fragments of text and CSS 4234 4285 // classes. 4235 function runMode(cm, text, mode, state, f ) {4286 function runMode(cm, text, mode, state, f, forceToEnd) { 4236 4287 var flattenSpans = mode.flattenSpans; 4237 4288 if (flattenSpans == null) flattenSpans = cm.options.flattenSpans; … … 4242 4293 if (stream.pos > cm.options.maxHighlightLength) { 4243 4294 flattenSpans = false; 4295 if (forceToEnd) processLine(cm, text, state, stream.pos); 4244 4296 stream.pos = text.length; 4245 4297 style = null; … … 4261 4313 } 4262 4314 4263 function highlightLine(cm, line, state ) {4315 function highlightLine(cm, line, state, forceToEnd) { 4264 4316 // A styles array always starts with a number identifying the 4265 4317 // mode/overlays that it is based on (for easy invalidation). 4266 4318 var st = [cm.state.modeGen]; 4267 4319 // Compute the base array of styles 4268 runMode(cm, line.text, cm.doc.mode, state, function(end, style) {st.push(end, style);}); 4320 runMode(cm, line.text, cm.doc.mode, state, function(end, style) { 4321 st.push(end, style); 4322 }, forceToEnd); 4269 4323 4270 4324 // Run overlays, adjust style array. … … 4305 4359 // Lightweight form of highlight -- proceed over this line and 4306 4360 // update state, but don't save a style array. 4307 function processLine(cm, line, state) {4361 function processLine(cm, text, state, startAt) { 4308 4362 var mode = cm.doc.mode; 4309 var stream = new StringStream(line.text, cm.options.tabSize); 4310 if (line.text == "" && mode.blankLine) mode.blankLine(state); 4363 var stream = new StringStream(text, cm.options.tabSize); 4364 stream.start = stream.pos = startAt || 0; 4365 if (text == "" && mode.blankLine) mode.blankLine(state); 4311 4366 while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) { 4312 4367 mode.token(stream, state); … … 4365 4420 // direction spans on IE (issue #1129). See also the comment in 4366 4421 // cursorCoords. 4367 if (measure && ie&& (order = getOrder(line))) {4422 if (measure && (ie || ie_gt10) && (order = getOrder(line))) { 4368 4423 var l = order.length - 1; 4369 4424 if (order[l].from == order[l].to) --l; … … 4383 4438 } 4384 4439 4385 var tokenSpecialChars = /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\uFEFF]/g; 4440 function defaultSpecialCharPlaceholder(ch) { 4441 var token = elt("span", "\u2022", "cm-invalidchar"); 4442 token.title = "\\u" + ch.charCodeAt(0).toString(16); 4443 return token; 4444 } 4445 4386 4446 function buildToken(builder, text, style, startStyle, endStyle, title) { 4387 4447 if (!text) return; 4388 if (!tokenSpecialChars.test(text)) { 4448 var special = builder.cm.options.specialChars; 4449 if (!special.test(text)) { 4389 4450 builder.col += text.length; 4390 4451 var content = document.createTextNode(text); … … 4392 4453 var content = document.createDocumentFragment(), pos = 0; 4393 4454 while (true) { 4394 tokenSpecialChars.lastIndex = pos;4395 var m = tokenSpecialChars.exec(text);4455 special.lastIndex = pos; 4456 var m = special.exec(text); 4396 4457 var skipped = m ? m.index - pos : text.length - pos; 4397 4458 if (skipped) { … … 4406 4467 builder.col += tabWidth; 4407 4468 } else { 4408 var token = elt("span", "\u2022", "cm-invalidchar"); 4409 token.title = "\\u" + m[0].charCodeAt(0).toString(16); 4469 var token = builder.cm.options.specialCharPlaceholder(m[0]); 4410 4470 content.appendChild(token); 4411 4471 builder.col += 1; … … 4458 4518 } 4459 4519 return function(builder, text, style, startStyle, endStyle, title) { 4460 return inner(builder, text.replace(/ {3,}/ , split), style, startStyle, endStyle, title);4520 return inner(builder, text.replace(/ {3,}/g, split), style, startStyle, endStyle, title); 4461 4521 }; 4462 4522 } … … 4560 4620 4561 4621 // First adjust the line structure 4562 if (from.ch == 0 && to.ch == 0 && lastText == "") { 4622 if (from.ch == 0 && to.ch == 0 && lastText == "" && 4623 (!doc.cm || doc.cm.options.wholeLineUpdateBefore)) { 4563 4624 // This is a whole-line replace. Treated specially to make 4564 4625 // sure line objects move the way they are supposed to. … … 5447 5508 } 5448 5509 5449 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\u A670-\uA672\uA674-\uA67D\uA69F\udc00-\udfff]/;5510 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\u1DC0–\u1DFF\u20D0–\u20FF\uA670-\uA672\uA674-\uA67D\uA69F\udc00-\udfff\uFE20–\uFE2F]/; 5450 5511 5451 5512 // DOM UTILITIES … … 5521 5582 if (i > 2 && /[\d\.,]/.test(str.charAt(i - 2)) && /[\d\.,]/.test(str.charAt(i))) return false; 5522 5583 } 5523 var result = /[~!#%&*)=+}\] |\"\.>,:;][({[<]|-[^\-?\.\u2010-\u201f\u2026]|\?[\w~`@#$%\^&*(_=+{[|><]|…[\w~`@#$%\^&*(_=+{[><]/.test(str.slice(i - 1, i + 1));5584 var result = /[~!#%&*)=+}\]\\|\"\.>,:;][({[<]|-[^\-?\.\u2010-\u201f\u2026]|\?[\w~`@#$%\^&*(_=+{[|><]|…[\w~`@#$%\^&*(_=+{[><]/.test(str.slice(i - 1, i + 1)); 5524 5585 return result; 5525 5586 }; … … 5878 5939 // THE END 5879 5940 5880 CodeMirror.version = "3. 16.1";5941 CodeMirror.version = "3.20.0"; 5881 5942 5882 5943 return CodeMirror; -
trunk/Source/WebInspectorUI/Tools/PrettyPrinting/css.js
r155659 r160500 4 4 if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css"); 5 5 6 var indentUnit = config.indentUnit ,6 var indentUnit = config.indentUnit || config.tabSize || 2, 7 7 hooks = parserConfig.hooks || {}, 8 8 atMediaTypes = parserConfig.atMediaTypes || {}, … … 38 38 return ret("keyword", "important"); 39 39 } 40 else if (/\d/.test(ch) ) {40 else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) { 41 41 stream.eatWhile(/[\w.%]/); 42 42 return ret("number", "unit"); … … 260 260 else if (type == "}") { 261 261 if (context == "interpolation") style = "operator"; 262 state.stack.pop(); 263 if (context == "propertyValue") state.stack.pop(); 262 // Pop off end of array until { is reached 263 while(state.stack.length){ 264 var removed = state.stack.pop(); 265 if(removed.indexOf("{") > -1 || removed == "block" || removed == "rule"){ 266 break; 267 } 268 } 264 269 } 265 270 else if (type == "interpolation") state.stack.push("interpolation"); … … 279 284 } 280 285 else if (type == ")") { 281 if (context == "propertyValue") { 282 // In @mediaType( without closing ; after propertyValue 283 state.stack.pop(); 284 } 285 state.stack.pop(); 286 // Pop off end of array until ( is reached 287 while(state.stack.length){ 288 var removed = state.stack.pop(); 289 if(removed.indexOf("(") > -1){ 290 break; 291 } 292 } 286 293 } 287 294 else if (type == ":" && state.lastToken == "property") state.stack.push("propertyValue"); … … 603 610 return ["variable", "variable"]; 604 611 }, 612 ",": function(stream, state) { 613 if (state.stack[state.stack.length - 1] == "propertyValue" && stream.match(/^ *\$/, false)) { 614 return ["operator", ";"]; 615 } 616 }, 605 617 "/": function(stream, state) { 606 618 if (stream.eat("/")) { -
trunk/Source/WebInspectorUI/Tools/PrettyPrinting/javascript.js
r154456 r160500 22 22 "in": operator, "typeof": operator, "instanceof": operator, 23 23 "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, 24 "this": kw("this") 24 "this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"), 25 "yield": C, "export": kw("export"), "import": kw("import"), "extends": C 25 26 }; 26 27 … … 31 32 // object-like things 32 33 "interface": kw("interface"), 33 "class": kw("class"),34 34 "extends": kw("extends"), 35 35 "constructor": kw("constructor"), … … 41 41 "static": kw("static"), 42 42 43 "super": kw("super"),44 45 43 // types 46 44 "string": type, "number": type, "bool": type, "any": type … … 56 54 57 55 var isOperatorChar = /[+\-*&%=<>!?|~^]/; 58 59 function chain(stream, state, f) {60 state.tokenize = f;61 return f(stream, state);62 }63 56 64 57 function nextUntilUnescaped(stream, end) { … … 79 72 return style; 80 73 } 81 function jsTokenBase(stream, state) {74 function tokenBase(stream, state) { 82 75 var ch = stream.next(); 83 if (ch == '"' || ch == "'") 84 return chain(stream, state, jsTokenString(ch)); 85 else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) 76 if (ch == '"' || ch == "'") { 77 state.tokenize = tokenString(ch); 78 return state.tokenize(stream, state); 79 } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) { 86 80 return ret("number", "number"); 87 else if (/[\[\]{}\(\),;\:\.]/.test(ch)) 81 } else if (ch == "." && stream.match("..")) { 82 return ret("spread", "meta"); 83 } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) { 88 84 return ret(ch); 89 else if (ch == "0" && stream.eat(/x/i)) { 85 } else if (ch == "=" && stream.eat(">")) { 86 return ret("=>"); 87 } else if (ch == "0" && stream.eat(/x/i)) { 90 88 stream.eatWhile(/[\da-f]/i); 91 89 return ret("number", "number"); 92 } 93 else if (/\d/.test(ch)) { 90 } else if (/\d/.test(ch)) { 94 91 stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); 95 92 return ret("number", "number"); 96 } 97 else if (ch == "/") { 93 } else if (ch == "/") { 98 94 if (stream.eat("*")) { 99 return chain(stream, state, jsTokenComment);100 }101 else if (stream.eat("/")) {95 state.tokenize = tokenComment; 96 return tokenComment(stream, state); 97 } else if (stream.eat("/")) { 102 98 stream.skipToEnd(); 103 99 return ret("comment", "comment"); 104 } 105 else if (state.lastType == "operator" || state.lastType == "keyword c" || 106 /^[\[{}\(,;:]$/.test(state.lastType)) { 100 } else if (state.lastType == "operator" || state.lastType == "keyword c" || 101 state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) { 107 102 nextUntilUnescaped(stream, "/"); 108 103 stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla 109 104 return ret("regexp", "string-2"); 110 } 111 else { 105 } else { 112 106 stream.eatWhile(isOperatorChar); 113 107 return ret("operator", null, stream.current()); 114 108 } 115 } 116 else if (ch == "#") { 109 } else if (ch == "`") { 110 state.tokenize = tokenQuasi; 111 return tokenQuasi(stream, state); 112 } else if (ch == "#") { 117 113 stream.skipToEnd(); 118 114 return ret("error", "error"); 119 } 120 else if (isOperatorChar.test(ch)) { 115 } else if (isOperatorChar.test(ch)) { 121 116 stream.eatWhile(isOperatorChar); 122 117 return ret("operator", null, stream.current()); 123 } 124 else { 118 } else { 125 119 stream.eatWhile(/[\w\$_]/); 126 120 var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; … … 130 124 } 131 125 132 function jsTokenString(quote) {126 function tokenString(quote) { 133 127 return function(stream, state) { 134 128 if (!nextUntilUnescaped(stream, quote)) 135 state.tokenize = jsTokenBase;129 state.tokenize = tokenBase; 136 130 return ret("string", "string"); 137 131 }; 138 132 } 139 133 140 function jsTokenComment(stream, state) {134 function tokenComment(stream, state) { 141 135 var maybeEnd = false, ch; 142 136 while (ch = stream.next()) { 143 137 if (ch == "/" && maybeEnd) { 144 state.tokenize = jsTokenBase;138 state.tokenize = tokenBase; 145 139 break; 146 140 } … … 148 142 } 149 143 return ret("comment", "comment"); 144 } 145 146 function tokenQuasi(stream, state) { 147 var escaped = false, next; 148 while ((next = stream.next()) != null) { 149 if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) { 150 state.tokenize = tokenBase; 151 break; 152 } 153 escaped = !escaped && next == "\\"; 154 } 155 return ret("quasi", "string-2", stream.current()); 156 } 157 158 var brackets = "([{}])"; 159 // This is a crude lookahead trick to try and notice that we're 160 // parsing the argument patterns for a fat-arrow function before we 161 // actually hit the arrow token. It only works if the arrow is on 162 // the same line as the arguments and there's no strange noise 163 // (comments) in between. Fallback is to only notice when we hit the 164 // arrow, and not declare the arguments as locals for the arrow 165 // body. 166 function findFatArrow(stream, state) { 167 if (state.fatArrowAt) state.fatArrowAt = null; 168 var arrow = stream.string.indexOf("=>", stream.start); 169 if (arrow < 0) return; 170 171 var depth = 0, sawSomething = false; 172 for (var pos = arrow - 1; pos >= 0; --pos) { 173 var ch = stream.string.charAt(pos); 174 var bracket = brackets.indexOf(ch); 175 if (bracket >= 0 && bracket < 3) { 176 if (!depth) { ++pos; break; } 177 if (--depth == 0) break; 178 } else if (bracket >= 3 && bracket < 6) { 179 ++depth; 180 } else if (/[$\w]/.test(ch)) { 181 sawSomething = true; 182 } else if (sawSomething && !depth) { 183 ++pos; 184 break; 185 } 186 } 187 if (sawSomething && !depth) state.fatArrowAt = pos; 150 188 } 151 189 … … 166 204 for (var v = state.localVars; v; v = v.next) 167 205 if (v.name == varname) return true; 206 for (var cx = state.context; cx; cx = cx.prev) { 207 for (var v = cx.vars; v; v = v.next) 208 if (v.name == varname) return true; 209 } 168 210 } 169 211 … … 212 254 } else { 213 255 if (inList(state.globalVars)) return; 214 state.globalVars = {name: varname, next: state.globalVars}; 256 if (parserConfig.globalVars) 257 state.globalVars = {name: varname, next: state.globalVars}; 215 258 } 216 259 } … … 254 297 } 255 298 256 function statement(type ) {257 if (type == "var") return cont(pushlex("vardef" ), vardef1, expect(";"), poplex);299 function statement(type, value) { 300 if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex); 258 301 if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); 259 302 if (type == "keyword b") return cont(pushlex("form"), statement, poplex); … … 262 305 if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse); 263 306 if (type == "function") return cont(functiondef); 264 if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"), 265 poplex, statement, poplex); 307 if (type == "for") return cont(pushlex("form"), forspec, poplex, statement, poplex); 266 308 if (type == "variable") return cont(pushlex("stat"), maybelabel); 267 309 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), … … 271 313 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), 272 314 statement, poplex, popcontext); 315 if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex); 316 if (type == "class") return cont(pushlex("form"), className, objlit, poplex); 317 if (type == "export") return cont(pushlex("form"), afterExport, poplex); 318 if (type == "import") return cont(pushlex("form"), afterImport, poplex); 273 319 return pass(pushlex("stat"), expression, expect(";"), poplex); 274 320 } … … 280 326 } 281 327 function expressionInner(type, noComma) { 328 if (cx.state.fatArrowAt == cx.stream.start) { 329 var body = noComma ? arrowBodyNoComma : arrowBody; 330 if (type == "(") return cont(pushcontext, commasep(pattern, ")"), expect("=>"), body, popcontext); 331 else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext); 332 } 333 282 334 var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; 283 335 if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); 284 336 if (type == "function") return cont(functiondef); 285 337 if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression); 286 if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);287 if (type == "operator" ) return cont(noComma ? expressionNoComma : expression);288 if (type == "[") return cont(pushlex("]"), commasep(expressionNoComma, "]"), poplex, maybeop);289 if (type == "{") return cont( pushlex("}"), commasep(objprop, "}"), poplex, maybeop);338 if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop); 339 if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression); 340 if (type == "[") return cont(pushlex("]"), expressionNoComma, maybeArrayComprehension, poplex, maybeop); 341 if (type == "{") return cont(commasep(objprop, "}"), maybeop); 290 342 return cont(); 291 343 } … … 306 358 var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; 307 359 var expr = noComma == false ? expression : expressionNoComma; 360 if (value == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); 308 361 if (type == "operator") { 309 362 if (/\+\+|--/.test(value)) return cont(me); … … 311 364 return cont(expr); 312 365 } 366 if (type == "quasi") { cx.cc.push(me); return quasi(value); } 313 367 if (type == ";") return; 314 if (type == "(") return cont( pushlex(")", "call"), commasep(expressionNoComma, ")"), poplex, me);368 if (type == "(") return cont(commasep(expressionNoComma, ")", "call"), me); 315 369 if (type == ".") return cont(property, me); 316 370 if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me); 371 } 372 function quasi(value) { 373 if (!value) debugger; 374 if (value.slice(value.length - 2) != "${") return cont(); 375 return cont(expression, continueQuasi); 376 } 377 function continueQuasi(type) { 378 if (type == "}") { 379 cx.marked = "string-2"; 380 cx.state.tokenize = tokenQuasi; 381 return cont(); 382 } 383 } 384 function arrowBody(type) { 385 findFatArrow(cx.stream, cx.state); 386 if (type == "{") return pass(statement); 387 return pass(expression); 388 } 389 function arrowBodyNoComma(type) { 390 findFatArrow(cx.stream, cx.state); 391 if (type == "{") return pass(statement); 392 return pass(expressionNoComma); 317 393 } 318 394 function maybelabel(type) { … … 329 405 } else if (type == "number" || type == "string") { 330 406 cx.marked = type + " property"; 331 } 332 if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expressionNoComma); 407 } else if (type == "[") { 408 return cont(expression, expect("]"), afterprop); 409 } 410 if (atomicTypes.hasOwnProperty(type)) return cont(afterprop); 333 411 } 334 412 function getterSetter(type) { 335 if (type == ":") return cont(expression); 336 if (type != "variable") return cont(expect(":"), expression); 413 if (type != "variable") return pass(afterprop); 337 414 cx.marked = "property"; 338 415 return cont(functiondef); 339 416 } 340 function commasep(what, end) { 417 function afterprop(type) { 418 if (type == ":") return cont(expressionNoComma); 419 if (type == "(") return pass(functiondef); 420 } 421 function commasep(what, end, info) { 341 422 function proceed(type) { 342 423 if (type == ",") { … … 350 431 return function(type) { 351 432 if (type == end) return cont(); 352 else return pass(what, proceed); 433 if (info === false) return pass(what, proceed); 434 return pass(pushlex(end, info), what, proceed, poplex); 353 435 }; 354 436 } … … 358 440 } 359 441 function maybetype(type) { 360 if (type == ":") return cont(typedef); 361 return pass(); 442 if (isTS && type == ":") return cont(typedef); 362 443 } 363 444 function typedef(type) { 364 445 if (type == "variable"){cx.marked = "variable-3"; return cont();} 365 return pass(); 366 } 367 function vardef1(type, value) { 368 if (type == "variable") { 446 } 447 function vardef() { 448 return pass(pattern, maybetype, maybeAssign, vardefCont); 449 } 450 function pattern(type, value) { 451 if (type == "variable") { register(value); return cont(); } 452 if (type == "[") return cont(commasep(pattern, "]")); 453 if (type == "{") return cont(commasep(proppattern, "}")); 454 } 455 function proppattern(type, value) { 456 if (type == "variable" && !cx.stream.match(/^\s*:/, false)) { 369 457 register(value); 370 return isTS ? cont(maybetype, vardef2) : cont(vardef2); 371 } 372 return pass(); 373 } 374 function vardef2(type, value) { 375 if (value == "=") return cont(expressionNoComma, vardef2); 376 if (type == ",") return cont(vardef1); 458 return cont(maybeAssign); 459 } 460 if (type == "variable") cx.marked = "property"; 461 return cont(expect(":"), pattern, maybeAssign); 462 } 463 function maybeAssign(_type, value) { 464 if (value == "=") return cont(expressionNoComma); 465 } 466 function vardefCont(type) { 467 if (type == ",") return cont(vardef); 377 468 } 378 469 function maybeelse(type, value) { 379 470 if (type == "keyword b" && value == "else") return cont(pushlex("form"), statement, poplex); 380 471 } 472 function forspec(type) { 473 if (type == "(") return cont(pushlex(")"), forspec1, expect(")")); 474 } 381 475 function forspec1(type) { 382 if (type == "var") return cont(vardef 1, expect(";"), forspec2);476 if (type == "var") return cont(vardef, expect(";"), forspec2); 383 477 if (type == ";") return cont(forspec2); 384 if (type == "variable") return cont(formaybein );478 if (type == "variable") return cont(formaybeinof); 385 479 return pass(expression, expect(";"), forspec2); 386 480 } 387 function formaybein (_type, value) {388 if (value == "in" ) return cont(expression);481 function formaybeinof(_type, value) { 482 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } 389 483 return cont(maybeoperatorComma, forspec2); 390 484 } 391 485 function forspec2(type, value) { 392 486 if (type == ";") return cont(forspec3); 393 if (value == "in" ) return cont(expression);487 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } 394 488 return pass(expression, expect(";"), forspec3); 395 489 } … … 398 492 } 399 493 function functiondef(type, value) { 494 if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} 400 495 if (type == "variable") {register(value); return cont(functiondef);} 401 if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext); 402 } 403 function funarg(type, value) { 404 if (type == "variable") {register(value); return isTS ? cont(maybetype) : cont();} 496 if (type == "(") return cont(pushcontext, commasep(funarg, ")"), statement, popcontext); 497 } 498 function funarg(type) { 499 if (type == "spread") return cont(funarg); 500 return pass(pattern, maybetype); 501 } 502 function className(type, value) { 503 if (type == "variable") {register(value); return cont(classNameAfter);} 504 } 505 function classNameAfter(_type, value) { 506 if (value == "extends") return cont(expression); 507 } 508 function objlit(type) { 509 if (type == "{") return cont(commasep(objprop, "}")); 510 } 511 function afterModule(type, value) { 512 if (type == "string") return cont(statement); 513 if (type == "variable") { register(value); return cont(maybeFrom); } 514 } 515 function afterExport(_type, value) { 516 if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); } 517 if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); } 518 return pass(statement); 519 } 520 function afterImport(type) { 521 if (type == "string") return cont(); 522 return pass(importSpec, maybeFrom); 523 } 524 function importSpec(type, value) { 525 if (type == "{") return cont(commasep(importSpec, "}")); 526 if (type == "variable") register(value); 527 return cont(); 528 } 529 function maybeFrom(_type, value) { 530 if (value == "from") { cx.marked = "keyword"; return cont(expression); } 531 } 532 function maybeArrayComprehension(type) { 533 if (type == "for") return pass(comprehension); 534 if (type == ",") return cont(commasep(expressionNoComma, "]", false)); 535 return pass(commasep(expressionNoComma, "]", false)); 536 } 537 function comprehension(type) { 538 if (type == "for") return cont(forspec, comprehension); 539 if (type == "if") return cont(expression, comprehension); 405 540 } 406 541 … … 409 544 return { 410 545 startState: function(basecolumn) { 411 return{412 tokenize: jsTokenBase,413 lastType: null,546 var state = { 547 tokenize: tokenBase, 548 lastType: "sof", 414 549 cc: [], 415 550 lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), 416 551 localVars: parserConfig.localVars, 417 globalVars: parserConfig.globalVars,418 552 context: parserConfig.localVars && {vars: parserConfig.localVars}, 419 553 indented: 0 420 554 }; 555 if (parserConfig.globalVars) state.globalVars = parserConfig.globalVars; 556 return state; 421 557 }, 422 558 … … 426 562 state.lexical.align = false; 427 563 state.indented = stream.indentation(); 428 } 429 if (state.tokenize != jsTokenComment && stream.eatSpace()) return null; 564 findFatArrow(stream, state); 565 } 566 if (state.tokenize != tokenComment && stream.eatSpace()) return null; 430 567 var style = state.tokenize(stream, state); 431 568 if (type == "comment") return style; … … 435 572 436 573 indent: function(state, textAfter) { 437 if (state.tokenize == jsTokenComment) return CodeMirror.Pass;438 if (state.tokenize != jsTokenBase) return 0;574 if (state.tokenize == tokenComment) return CodeMirror.Pass; 575 if (state.tokenize != tokenBase) return 0; 439 576 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical; 440 577 // Kludge to prevent 'maybelse' from blocking lexical scope pops … … 442 579 var c = state.cc[i]; 443 580 if (c == poplex) lexical = lexical.prev; 444 else if (c != maybeelse || /^else\b/.test(textAfter)) break;581 else if (c != maybeelse) break; 445 582 } 446 583 if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; … … 449 586 var type = lexical.type, closing = firstChar == type; 450 587 451 if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? 4: 0);588 if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0); 452 589 else if (type == "form" && firstChar == "{") return lexical.indented; 453 590 else if (type == "form") return lexical.indented + indentUnit; -
trunk/Source/WebInspectorUI/UserInterface/External/CodeMirror/codemirror.css
r155659 r160500 75 75 .cm-s-default .cm-string-2 {color: #f50;} 76 76 .cm-s-default .cm-meta {color: #555;} 77 .cm-s-default .cm-error {color: #f00;}78 77 .cm-s-default .cm-qualifier {color: #555;} 79 78 .cm-s-default .cm-builtin {color: #30a;} … … 92 91 .cm-link {text-decoration: underline;} 93 92 93 .cm-s-default .cm-error {color: #f00;} 94 94 .cm-invalidchar {color: #f00;} 95 95 -
trunk/Source/WebInspectorUI/UserInterface/External/CodeMirror/codemirror.js
r155659 r160500 8 8 // bugs and behavior differences. 9 9 var gecko = /gecko\/\d/i.test(navigator.userAgent); 10 // IE11 currently doesn't count as 'ie', since it has almost none of 11 // the same bugs as earlier versions. Use ie_gt10 to handle 12 // incompatibilities in that version. 10 13 var ie = /MSIE \d/.test(navigator.userAgent); 11 14 var ie_lt8 = ie && (document.documentMode == null || document.documentMode < 8); 12 15 var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9); 16 var ie_gt10 = /Trident\/([7-9]|\d{2,})\./.test(navigator.userAgent); 13 17 var webkit = /WebKit\//.test(navigator.userAgent); 14 18 var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent); … … 310 314 } else if (found > -1 && !options.lineNumbers) { 311 315 options.gutters = options.gutters.slice(0); 312 options.gutters.splice( i, 1);316 options.gutters.splice(found, 1); 313 317 } 314 318 } … … 354 358 } else d.gutterFiller.style.display = ""; 355 359 356 if (mac_geLion && scrollbarWidth(d.measure) === 0) 360 if (mac_geLion && scrollbarWidth(d.measure) === 0) { 357 361 d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = mac_geMountainLion ? "18px" : "12px"; 362 d.scrollbarV.style.pointerEvents = d.scrollbarH.style.pointerEvents = "none"; 363 } 358 364 } 359 365 … … 410 416 var oldFrom = cm.display.showingFrom, oldTo = cm.display.showingTo, updated; 411 417 var visible = visibleLines(cm.display, cm.doc, viewPort); 412 for ( ;;) {418 for (var first = true;; first = false) { 413 419 var oldWidth = cm.display.scroller.clientWidth; 414 420 if (!updateDisplayInner(cm, changes, visible, forced)) break; … … 417 423 updateSelection(cm); 418 424 updateScrollbars(cm); 419 if ( cm.options.lineWrapping && oldWidth != cm.display.scroller.clientWidth) {425 if (first && cm.options.lineWrapping && oldWidth != cm.display.scroller.clientWidth) { 420 426 forced = true; 421 427 continue; … … 905 911 if (doc.frontier >= cm.display.showingFrom) { // Visible 906 912 var oldStyles = line.styles; 907 line.styles = highlightLine(cm, line, state );913 line.styles = highlightLine(cm, line, state, true); 908 914 var ischange = !oldStyles || oldStyles.length != line.styles.length; 909 915 for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i]; … … 914 920 line.stateAfter = copyState(doc.mode, state); 915 921 } else { 916 processLine(cm, line , state);922 processLine(cm, line.text, state); 917 923 line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null; 918 924 } … … 936 942 // parse correctly. 937 943 function findStartLine(cm, n, precise) { 938 var minindent, minline, doc = cm.doc, maxScan = cm.doc.mode.innerMode ? 1000 : 100; 939 for (var search = n, lim = n - maxScan; search > lim; --search) { 944 var minindent, minline, doc = cm.doc; 945 var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100); 946 for (var search = n; search > lim; --search) { 940 947 if (search <= doc.first) return doc.first; 941 948 var line = getLine(doc, search - 1); … … 957 964 else state = copyState(doc.mode, state); 958 965 doc.iter(pos, n, function(line) { 959 processLine(cm, line , state);966 processLine(cm, line.text, state); 960 967 var save = pos == n - 1 || pos % 5 == 0 || pos >= display.showingFrom && pos < display.showingTo; 961 968 line.stateAfter = save ? copyState(doc.mode, state) : null; 962 969 ++pos; 963 970 }); 971 if (precise) doc.frontier = pos; 964 972 return state; 965 973 } … … 1002 1010 if (memo.text == line.text && memo.markedSpans == line.markedSpans && 1003 1011 cm.display.scroller.clientWidth == memo.width && 1004 memo.classes == line.textClass + "|" + line. bgClass + "|" + line.wrapClass)1012 memo.classes == line.textClass + "|" + line.wrapClass) 1005 1013 return memo; 1006 1014 } … … 1022 1030 var memo = {text: line.text, width: cm.display.scroller.clientWidth, 1023 1031 markedSpans: line.markedSpans, measure: measure, 1024 classes: line.textClass + "|" + line. bgClass + "|" + line.wrapClass};1032 classes: line.textClass + "|" + line.wrapClass}; 1025 1033 if (cache.length == 16) cache[++cm.display.measureLineCachePos % 16] = memo; 1026 1034 else cache.push(memo); … … 1380 1388 if (!updated && op.selectionChanged) updateSelection(cm); 1381 1389 if (op.updateScrollPos) { 1382 display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = newScrollPos.scrollTop; 1383 display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = newScrollPos.scrollLeft; 1390 var top = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, newScrollPos.scrollTop)); 1391 var left = Math.max(0, Math.min(display.scroller.scrollWidth - display.scroller.clientWidth, newScrollPos.scrollLeft)); 1392 display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = top; 1393 display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = left; 1384 1394 alignHorizontally(cm); 1385 1395 if (op.scrollToPos) 1386 scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos), op.scrollToPosMargin); 1396 scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos.from), 1397 clipPos(cm.doc, op.scrollToPos.to), op.scrollToPos.margin); 1387 1398 } else if (newScrollPos) { 1388 1399 scrollCursorIntoView(cm); … … 1606 1617 if (e.keyCode == 16) cm.doc.sel.shift = false; 1607 1618 })); 1608 on(d.input, "input", bind(fastPoll, cm)); 1619 on(d.input, "input", function() { 1620 if (ie && !ie_lt9 && cm.display.inputHasSelection) cm.display.inputHasSelection = null; 1621 fastPoll(cm); 1622 }); 1609 1623 on(d.input, "keydown", operation(cm, onKeyDown)); 1610 1624 on(d.input, "keypress", operation(cm, onKeyPress)); … … 1896 1910 cm.replaceSelection(text, null, "paste"); 1897 1911 focusInput(cm); 1898 onFocus(cm);1899 1912 } 1900 1913 } … … 2177 2190 var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop; 2178 2191 if (!pos || opera) return; // Opera is difficult. 2179 if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to)) 2192 2193 // Reset the current text selection only if the click is done outside of the selection 2194 // and 'resetSelectionOnContextMenu' option is true. 2195 var reset = cm.options.resetSelectionOnContextMenu; 2196 if (reset && (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to))) 2180 2197 operation(cm, setSelection)(cm.doc, pos, pos); 2181 2198 … … 2327 2344 2328 2345 function makeChangeNoReadonly(doc, change, selUpdate) { 2346 if (change.text.length == 1 && change.text[0] == "" && posEq(change.from, change.to)) return; 2329 2347 var selAfter = computeSelAfterChange(doc, change, selUpdate); 2330 2348 addToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN); … … 2627 2645 2628 2646 function scrollCursorIntoView(cm) { 2629 var coords = scrollPosIntoView(cm, cm.doc.sel.head, cm.options.cursorScrollMargin);2647 var coords = scrollPosIntoView(cm, cm.doc.sel.head, null, cm.options.cursorScrollMargin); 2630 2648 if (!cm.state.focused) return; 2631 2649 var display = cm.display, box = getRect(display.sizer), doScroll = null; … … 2644 2662 } 2645 2663 2646 function scrollPosIntoView(cm, pos, margin) {2664 function scrollPosIntoView(cm, pos, end, margin) { 2647 2665 if (margin == null) margin = 0; 2648 2666 for (;;) { 2649 2667 var changed = false, coords = cursorCoords(cm, pos); 2650 var scrollPos = calculateScrollPos(cm, coords.left, coords.top - margin, coords.left, coords.bottom + margin); 2668 var endCoords = !end || end == pos ? coords : cursorCoords(cm, end); 2669 var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left), 2670 Math.min(coords.top, endCoords.top) - margin, 2671 Math.max(coords.left, endCoords.left), 2672 Math.max(coords.bottom, endCoords.bottom) + margin); 2651 2673 var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft; 2652 2674 if (scrollPos.scrollTop != null) { … … 2745 2767 if (indentString != curSpaceString) 2746 2768 replaceRange(cm.doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input"); 2769 else if (doc.sel.head.line == n && doc.sel.head.ch < curSpaceString.length) 2770 setSelection(doc, Pos(n, curSpaceString.length), Pos(n, curSpaceString.length), 1); 2747 2771 line.stateAfter = null; 2748 2772 } … … 2845 2869 CodeMirror.prototype = { 2846 2870 constructor: CodeMirror, 2847 focus: function(){window.focus(); focusInput(this); onFocus(this);fastPoll(this);},2871 focus: function(){window.focus(); focusInput(this); fastPoll(this);}, 2848 2872 2849 2873 setOption: function(option, value) { … … 3166 3190 }, 3167 3191 3168 scrollIntoView: operation(null, function(pos, margin) { 3169 if (typeof pos == "number") pos = Pos(pos, 0); 3192 scrollIntoView: operation(null, function(range, margin) { 3193 if (range == null) range = {from: this.doc.sel.head, to: null}; 3194 else if (typeof range == "number") range = {from: Pos(range, 0), to: null}; 3195 else if (range.from == null) range = {from: range, to: null}; 3196 if (!range.to) range.to = range.from; 3170 3197 if (!margin) margin = 0; 3171 var coords = pos; 3172 3173 if (!pos || pos.line != null) { 3174 this.curOp.scrollToPos = pos ? clipPos(this.doc, pos) : this.doc.sel.head; 3175 this.curOp.scrollToPosMargin = margin; 3176 coords = cursorCoords(this, this.curOp.scrollToPos); 3177 } 3178 var sPos = calculateScrollPos(this, coords.left, coords.top - margin, coords.right, coords.bottom + margin); 3198 3199 var coords = range; 3200 if (range.from.line != null) { 3201 this.curOp.scrollToPos = {from: range.from, to: range.to, margin: margin}; 3202 coords = {from: cursorCoords(this, range.from), 3203 to: cursorCoords(this, range.to)}; 3204 } 3205 var sPos = calculateScrollPos(this, Math.min(coords.from.left, coords.to.left), 3206 Math.min(coords.from.top, coords.to.top) - margin, 3207 Math.max(coords.from.right, coords.to.right), 3208 Math.max(coords.from.bottom, coords.to.bottom) + margin); 3179 3209 updateScrollPos(this, sPos.scrollLeft, sPos.scrollTop); 3180 3210 }), … … 3208 3238 resetInput(this, true); 3209 3239 updateScrollPos(this, doc.scrollLeft, doc.scrollTop); 3240 signalLater(this, "swapDoc", this, old); 3210 3241 return old; 3211 3242 }), … … 3251 3282 regChange(cm); 3252 3283 }, true); 3284 option("specialChars", /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\ufeff]/g, function(cm, val) { 3285 cm.options.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g"); 3286 cm.refresh(); 3287 }, true); 3288 option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true); 3253 3289 option("electricChars", true); 3254 3290 option("rtlMoveVisually", !windows); 3291 option("wholeLineUpdateBefore", true); 3255 3292 3256 3293 option("theme", "default", function(cm) { … … 3282 3319 option("showCursorWhenSelecting", false, updateSelection, true); 3283 3320 3321 option("resetSelectionOnContextMenu", true); 3322 3284 3323 option("readOnly", false, function(cm, val) { 3285 if (val == "nocursor") {onBlur(cm); cm.display.input.blur();} 3286 else if (!val) resetInput(cm, true); 3324 if (val == "nocursor") { 3325 onBlur(cm); 3326 cm.display.input.blur(); 3327 cm.display.disabled = true; 3328 } else { 3329 cm.display.disabled = false; 3330 if (!val) resetInput(cm, true); 3331 } 3287 3332 }); 3288 3333 option("dragDrop", true); … … 3518 3563 "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown", 3519 3564 "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown", 3520 "Delete": "delCharAfter", "Backspace": "delCharBefore", "Tab": "defaultTab", "Shift-Tab": "indentAuto", 3565 "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore", 3566 "Tab": "defaultTab", "Shift-Tab": "indentAuto", 3521 3567 "Enter": "newlineAndIndent", "Insert": "toggleOverwrite" 3522 3568 }; … … 3824 3870 3825 3871 var marker = new TextMarker(doc, type); 3826 if (type == "range" && !posLess(from, to)) return marker; 3872 if (posLess(to, from) || posEq(from, to) && type == "range" && 3873 !(options.inclusiveLeft && options.inclusiveRight)) 3874 return marker; 3827 3875 if (options) copyObj(options, marker); 3828 3876 if (marker.replacedWith) { … … 3940 3988 var span = old[i], marker = span.marker; 3941 3989 var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh); 3942 if (startsBefore || marker.type == "bookmark" && span.from == startCh && (!isInsert || !span.marker.insertLeft)) { 3990 if (startsBefore || 3991 (marker.inclusiveLeft && marker.inclusiveRight || marker.type == "bookmark") && 3992 span.from == startCh && (!isInsert || !span.marker.insertLeft)) { 3943 3993 var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh); 3944 3994 (nw || (nw = [])).push({from: span.from, … … 4213 4263 }; 4214 4264 eventMixin(Line); 4265 Line.prototype.lineNo = function() { return lineNo(this); }; 4215 4266 4216 4267 function updateLine(line, text, markedSpans, estimateHeight) { … … 4233 4284 // array, which contains alternating fragments of text and CSS 4234 4285 // classes. 4235 function runMode(cm, text, mode, state, f ) {4286 function runMode(cm, text, mode, state, f, forceToEnd) { 4236 4287 var flattenSpans = mode.flattenSpans; 4237 4288 if (flattenSpans == null) flattenSpans = cm.options.flattenSpans; … … 4242 4293 if (stream.pos > cm.options.maxHighlightLength) { 4243 4294 flattenSpans = false; 4295 if (forceToEnd) processLine(cm, text, state, stream.pos); 4244 4296 stream.pos = text.length; 4245 4297 style = null; … … 4261 4313 } 4262 4314 4263 function highlightLine(cm, line, state ) {4315 function highlightLine(cm, line, state, forceToEnd) { 4264 4316 // A styles array always starts with a number identifying the 4265 4317 // mode/overlays that it is based on (for easy invalidation). 4266 4318 var st = [cm.state.modeGen]; 4267 4319 // Compute the base array of styles 4268 runMode(cm, line.text, cm.doc.mode, state, function(end, style) {st.push(end, style);}); 4320 runMode(cm, line.text, cm.doc.mode, state, function(end, style) { 4321 st.push(end, style); 4322 }, forceToEnd); 4269 4323 4270 4324 // Run overlays, adjust style array. … … 4305 4359 // Lightweight form of highlight -- proceed over this line and 4306 4360 // update state, but don't save a style array. 4307 function processLine(cm, line, state) {4361 function processLine(cm, text, state, startAt) { 4308 4362 var mode = cm.doc.mode; 4309 var stream = new StringStream(line.text, cm.options.tabSize); 4310 if (line.text == "" && mode.blankLine) mode.blankLine(state); 4363 var stream = new StringStream(text, cm.options.tabSize); 4364 stream.start = stream.pos = startAt || 0; 4365 if (text == "" && mode.blankLine) mode.blankLine(state); 4311 4366 while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) { 4312 4367 mode.token(stream, state); … … 4365 4420 // direction spans on IE (issue #1129). See also the comment in 4366 4421 // cursorCoords. 4367 if (measure && ie&& (order = getOrder(line))) {4422 if (measure && (ie || ie_gt10) && (order = getOrder(line))) { 4368 4423 var l = order.length - 1; 4369 4424 if (order[l].from == order[l].to) --l; … … 4383 4438 } 4384 4439 4385 var tokenSpecialChars = /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\uFEFF]/g; 4440 function defaultSpecialCharPlaceholder(ch) { 4441 var token = elt("span", "\u2022", "cm-invalidchar"); 4442 token.title = "\\u" + ch.charCodeAt(0).toString(16); 4443 return token; 4444 } 4445 4386 4446 function buildToken(builder, text, style, startStyle, endStyle, title) { 4387 4447 if (!text) return; 4388 if (!tokenSpecialChars.test(text)) { 4448 var special = builder.cm.options.specialChars; 4449 if (!special.test(text)) { 4389 4450 builder.col += text.length; 4390 4451 var content = document.createTextNode(text); … … 4392 4453 var content = document.createDocumentFragment(), pos = 0; 4393 4454 while (true) { 4394 tokenSpecialChars.lastIndex = pos;4395 var m = tokenSpecialChars.exec(text);4455 special.lastIndex = pos; 4456 var m = special.exec(text); 4396 4457 var skipped = m ? m.index - pos : text.length - pos; 4397 4458 if (skipped) { … … 4406 4467 builder.col += tabWidth; 4407 4468 } else { 4408 var token = elt("span", "\u2022", "cm-invalidchar"); 4409 token.title = "\\u" + m[0].charCodeAt(0).toString(16); 4469 var token = builder.cm.options.specialCharPlaceholder(m[0]); 4410 4470 content.appendChild(token); 4411 4471 builder.col += 1; … … 4458 4518 } 4459 4519 return function(builder, text, style, startStyle, endStyle, title) { 4460 return inner(builder, text.replace(/ {3,}/ , split), style, startStyle, endStyle, title);4520 return inner(builder, text.replace(/ {3,}/g, split), style, startStyle, endStyle, title); 4461 4521 }; 4462 4522 } … … 4560 4620 4561 4621 // First adjust the line structure 4562 if (from.ch == 0 && to.ch == 0 && lastText == "") { 4622 if (from.ch == 0 && to.ch == 0 && lastText == "" && 4623 (!doc.cm || doc.cm.options.wholeLineUpdateBefore)) { 4563 4624 // This is a whole-line replace. Treated specially to make 4564 4625 // sure line objects move the way they are supposed to. … … 5447 5508 } 5448 5509 5449 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\u A670-\uA672\uA674-\uA67D\uA69F\udc00-\udfff]/;5510 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\u1DC0–\u1DFF\u20D0–\u20FF\uA670-\uA672\uA674-\uA67D\uA69F\udc00-\udfff\uFE20–\uFE2F]/; 5450 5511 5451 5512 // DOM UTILITIES … … 5521 5582 if (i > 2 && /[\d\.,]/.test(str.charAt(i - 2)) && /[\d\.,]/.test(str.charAt(i))) return false; 5522 5583 } 5523 var result = /[~!#%&*)=+}\] |\"\.>,:;][({[<]|-[^\-?\.\u2010-\u201f\u2026]|\?[\w~`@#$%\^&*(_=+{[|><]|…[\w~`@#$%\^&*(_=+{[><]/.test(str.slice(i - 1, i + 1));5584 var result = /[~!#%&*)=+}\]\\|\"\.>,:;][({[<]|-[^\-?\.\u2010-\u201f\u2026]|\?[\w~`@#$%\^&*(_=+{[|><]|…[\w~`@#$%\^&*(_=+{[><]/.test(str.slice(i - 1, i + 1)); 5524 5585 return result; 5525 5586 }; … … 5878 5939 // THE END 5879 5940 5880 CodeMirror.version = "3. 16.1";5941 CodeMirror.version = "3.20.0"; 5881 5942 5882 5943 return CodeMirror; -
trunk/Source/WebInspectorUI/UserInterface/External/CodeMirror/coffeescript.js
r155659 r160500 3 3 * https://github.com/pickhardt/coffeescript-codemirror-mode 4 4 */ 5 CodeMirror.defineMode('coffeescript', function(conf) { 6 var ERRORCLASS = 'error'; 7 8 function wordRegexp(words) { 9 return new RegExp("^((" + words.join(")|(") + "))\\b"); 10 } 11 12 var singleOperators = new RegExp("^[\\+\\-\\*/%&|\\^~<>!\?]"); 13 var singleDelimiters = new RegExp('^[\\(\\)\\[\\]\\{\\},:`=;\\.]'); 14 var doubleOperators = new RegExp("^((\->)|(\=>)|(\\+\\+)|(\\+\\=)|(\\-\\-)|(\\-\\=)|(\\*\\*)|(\\*\\=)|(\\/\\/)|(\\/\\=)|(==)|(!=)|(<=)|(>=)|(<>)|(<<)|(>>)|(//))"); 15 var doubleDelimiters = new RegExp("^((\\.\\.)|(\\+=)|(\\-=)|(\\*=)|(%=)|(/=)|(&=)|(\\|=)|(\\^=))"); 16 var tripleDelimiters = new RegExp("^((\\.\\.\\.)|(//=)|(>>=)|(<<=)|(\\*\\*=))"); 17 var identifiers = new RegExp("^[_A-Za-z$][_A-Za-z$0-9]*"); 18 var properties = new RegExp("^(@|this\.)[_A-Za-z$][_A-Za-z$0-9]*"); 19 20 var wordOperators = wordRegexp(['and', 'or', 'not', 21 'is', 'isnt', 'in', 22 'instanceof', 'typeof']); 23 var indentKeywords = ['for', 'while', 'loop', 'if', 'unless', 'else', 24 'switch', 'try', 'catch', 'finally', 'class']; 25 var commonKeywords = ['break', 'by', 'continue', 'debugger', 'delete', 26 'do', 'in', 'of', 'new', 'return', 'then', 27 'this', 'throw', 'when', 'until']; 28 29 var keywords = wordRegexp(indentKeywords.concat(commonKeywords)); 30 31 indentKeywords = wordRegexp(indentKeywords); 32 33 34 var stringPrefixes = new RegExp("^('{3}|\"{3}|['\"])"); 35 var regexPrefixes = new RegExp("^(/{3}|/)"); 36 var commonConstants = ['Infinity', 'NaN', 'undefined', 'null', 'true', 'false', 'on', 'off', 'yes', 'no']; 37 var constants = wordRegexp(commonConstants); 38 39 // Tokenizers 40 function tokenBase(stream, state) { 41 // Handle scope changes 42 if (stream.sol()) { 43 var scopeOffset = state.scopes[0].offset; 44 if (stream.eatSpace()) { 45 var lineOffset = stream.indentation(); 46 if (lineOffset > scopeOffset) { 47 return 'indent'; 48 } else if (lineOffset < scopeOffset) { 49 return 'dedent'; 50 } 51 return null; 52 } else { 53 if (scopeOffset > 0) { 54 dedent(stream, state); 55 } 56 } 57 } 58 if (stream.eatSpace()) { 59 return null; 60 } 61 62 var ch = stream.peek(); 63 64 // Handle docco title comment (single line) 65 if (stream.match("####")) { 66 stream.skipToEnd(); 67 return 'comment'; 68 } 69 70 // Handle multi line comments 71 if (stream.match("###")) { 72 state.tokenize = longComment; 73 return state.tokenize(stream, state); 74 } 75 76 // Single line comment 77 if (ch === '#') { 78 stream.skipToEnd(); 79 return 'comment'; 80 } 81 82 // Handle number literals 83 if (stream.match(/^-?[0-9\.]/, false)) { 84 var floatLiteral = false; 85 // Floats 86 if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) { 87 floatLiteral = true; 88 } 89 if (stream.match(/^-?\d+\.\d*/)) { 90 floatLiteral = true; 91 } 92 if (stream.match(/^-?\.\d+/)) { 93 floatLiteral = true; 94 } 95 96 if (floatLiteral) { 97 // prevent from getting extra . on 1.. 98 if (stream.peek() == "."){ 99 stream.backUp(1); 100 } 101 return 'number'; 102 } 103 // Integers 104 var intLiteral = false; 105 // Hex 106 if (stream.match(/^-?0x[0-9a-f]+/i)) { 107 intLiteral = true; 108 } 109 // Decimal 110 if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) { 111 intLiteral = true; 112 } 113 // Zero by itself with no other piece of number. 114 if (stream.match(/^-?0(?![\dx])/i)) { 115 intLiteral = true; 116 } 117 if (intLiteral) { 118 return 'number'; 119 } 120 } 121 122 // Handle strings 123 if (stream.match(stringPrefixes)) { 124 state.tokenize = tokenFactory(stream.current(), 'string'); 125 return state.tokenize(stream, state); 126 } 127 // Handle regex literals 128 if (stream.match(regexPrefixes)) { 129 if (stream.current() != '/' || stream.match(/^.*\//, false)) { // prevent highlight of division 130 state.tokenize = tokenFactory(stream.current(), 'string-2'); 131 return state.tokenize(stream, state); 132 } else { 133 stream.backUp(1); 134 } 135 } 136 137 // Handle operators and delimiters 138 if (stream.match(tripleDelimiters) || stream.match(doubleDelimiters)) { 139 return 'punctuation'; 140 } 141 if (stream.match(doubleOperators) 142 || stream.match(singleOperators) 143 || stream.match(wordOperators)) { 144 return 'operator'; 145 } 146 if (stream.match(singleDelimiters)) { 147 return 'punctuation'; 148 } 149 150 if (stream.match(constants)) { 151 return 'atom'; 152 } 153 154 if (stream.match(keywords)) { 155 return 'keyword'; 156 } 157 158 if (stream.match(identifiers)) { 159 return 'variable'; 160 } 161 162 if (stream.match(properties)) { 163 return 'property'; 164 } 165 166 // Handle non-detected items 167 stream.next(); 5 CodeMirror.defineMode("coffeescript", function(conf) { 6 var ERRORCLASS = "error"; 7 8 function wordRegexp(words) { 9 return new RegExp("^((" + words.join(")|(") + "))\\b"); 10 } 11 12 var operators = /^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?)/; 13 var delimiters = /^(?:[()\[\]{},:`=;]|\.\.?\.?)/; 14 var identifiers = /^[_A-Za-z$][_A-Za-z$0-9]*/; 15 var properties = /^(@|this\.)[_A-Za-z$][_A-Za-z$0-9]*/; 16 17 var wordOperators = wordRegexp(["and", "or", "not", 18 "is", "isnt", "in", 19 "instanceof", "typeof"]); 20 var indentKeywords = ["for", "while", "loop", "if", "unless", "else", 21 "switch", "try", "catch", "finally", "class"]; 22 var commonKeywords = ["break", "by", "continue", "debugger", "delete", 23 "do", "in", "of", "new", "return", "then", 24 "this", "throw", "when", "until"]; 25 26 var keywords = wordRegexp(indentKeywords.concat(commonKeywords)); 27 28 indentKeywords = wordRegexp(indentKeywords); 29 30 31 var stringPrefixes = /^('{3}|\"{3}|['\"])/; 32 var regexPrefixes = /^(\/{3}|\/)/; 33 var commonConstants = ["Infinity", "NaN", "undefined", "null", "true", "false", "on", "off", "yes", "no"]; 34 var constants = wordRegexp(commonConstants); 35 36 // Tokenizers 37 function tokenBase(stream, state) { 38 // Handle scope changes 39 if (stream.sol()) { 40 if (state.scope.align === null) state.scope.align = false; 41 var scopeOffset = state.scope.offset; 42 if (stream.eatSpace()) { 43 var lineOffset = stream.indentation(); 44 if (lineOffset > scopeOffset && state.scope.type == "coffee") { 45 return "indent"; 46 } else if (lineOffset < scopeOffset) { 47 return "dedent"; 48 } 49 return null; 50 } else { 51 if (scopeOffset > 0) { 52 dedent(stream, state); 53 } 54 } 55 } 56 if (stream.eatSpace()) { 57 return null; 58 } 59 60 var ch = stream.peek(); 61 62 // Handle docco title comment (single line) 63 if (stream.match("####")) { 64 stream.skipToEnd(); 65 return "comment"; 66 } 67 68 // Handle multi line comments 69 if (stream.match("###")) { 70 state.tokenize = longComment; 71 return state.tokenize(stream, state); 72 } 73 74 // Single line comment 75 if (ch === "#") { 76 stream.skipToEnd(); 77 return "comment"; 78 } 79 80 // Handle number literals 81 if (stream.match(/^-?[0-9\.]/, false)) { 82 var floatLiteral = false; 83 // Floats 84 if (stream.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)) { 85 floatLiteral = true; 86 } 87 if (stream.match(/^-?\d+\.\d*/)) { 88 floatLiteral = true; 89 } 90 if (stream.match(/^-?\.\d+/)) { 91 floatLiteral = true; 92 } 93 94 if (floatLiteral) { 95 // prevent from getting extra . on 1.. 96 if (stream.peek() == "."){ 97 stream.backUp(1); 98 } 99 return "number"; 100 } 101 // Integers 102 var intLiteral = false; 103 // Hex 104 if (stream.match(/^-?0x[0-9a-f]+/i)) { 105 intLiteral = true; 106 } 107 // Decimal 108 if (stream.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)) { 109 intLiteral = true; 110 } 111 // Zero by itself with no other piece of number. 112 if (stream.match(/^-?0(?![\dx])/i)) { 113 intLiteral = true; 114 } 115 if (intLiteral) { 116 return "number"; 117 } 118 } 119 120 // Handle strings 121 if (stream.match(stringPrefixes)) { 122 state.tokenize = tokenFactory(stream.current(), "string"); 123 return state.tokenize(stream, state); 124 } 125 // Handle regex literals 126 if (stream.match(regexPrefixes)) { 127 if (stream.current() != "/" || stream.match(/^.*\//, false)) { // prevent highlight of division 128 state.tokenize = tokenFactory(stream.current(), "string-2"); 129 return state.tokenize(stream, state); 130 } else { 131 stream.backUp(1); 132 } 133 } 134 135 // Handle operators and delimiters 136 if (stream.match(operators) || stream.match(wordOperators)) { 137 return "operator"; 138 } 139 if (stream.match(delimiters)) { 140 return "punctuation"; 141 } 142 143 if (stream.match(constants)) { 144 return "atom"; 145 } 146 147 if (stream.match(keywords)) { 148 return "keyword"; 149 } 150 151 if (stream.match(identifiers)) { 152 return "variable"; 153 } 154 155 if (stream.match(properties)) { 156 return "property"; 157 } 158 159 // Handle non-detected items 160 stream.next(); 161 return ERRORCLASS; 162 } 163 164 function tokenFactory(delimiter, outclass) { 165 var singleline = delimiter.length == 1; 166 return function(stream, state) { 167 while (!stream.eol()) { 168 stream.eatWhile(/[^'"\/\\]/); 169 if (stream.eat("\\")) { 170 stream.next(); 171 if (singleline && stream.eol()) { 172 return outclass; 173 } 174 } else if (stream.match(delimiter)) { 175 state.tokenize = tokenBase; 176 return outclass; 177 } else { 178 stream.eat(/['"\/]/); 179 } 180 } 181 if (singleline) { 182 if (conf.mode.singleLineStringErrors) { 183 outclass = ERRORCLASS; 184 } else { 185 state.tokenize = tokenBase; 186 } 187 } 188 return outclass; 189 }; 190 } 191 192 function longComment(stream, state) { 193 while (!stream.eol()) { 194 stream.eatWhile(/[^#]/); 195 if (stream.match("###")) { 196 state.tokenize = tokenBase; 197 break; 198 } 199 stream.eatWhile("#"); 200 } 201 return "comment"; 202 } 203 204 function indent(stream, state, type) { 205 type = type || "coffee"; 206 var offset = 0, align = false, alignOffset = null; 207 for (var scope = state.scope; scope; scope = scope.prev) { 208 if (scope.type === "coffee") { 209 offset = scope.offset + conf.indentUnit; 210 break; 211 } 212 } 213 if (type !== "coffee") { 214 align = null; 215 alignOffset = stream.column() + stream.current().length; 216 } else if (state.scope.align) { 217 state.scope.align = false; 218 } 219 state.scope = { 220 offset: offset, 221 type: type, 222 prev: state.scope, 223 align: align, 224 alignOffset: alignOffset 225 }; 226 } 227 228 function dedent(stream, state) { 229 if (!state.scope.prev) return; 230 if (state.scope.type === "coffee") { 231 var _indent = stream.indentation(); 232 var matched = false; 233 for (var scope = state.scope; scope; scope = scope.prev) { 234 if (_indent === scope.offset) { 235 matched = true; 236 break; 237 } 238 } 239 if (!matched) { 240 return true; 241 } 242 while (state.scope.prev && state.scope.offset !== _indent) { 243 state.scope = state.scope.prev; 244 } 245 return false; 246 } else { 247 state.scope = state.scope.prev; 248 return false; 249 } 250 } 251 252 function tokenLexer(stream, state) { 253 var style = state.tokenize(stream, state); 254 var current = stream.current(); 255 256 // Handle "." connected identifiers 257 if (current === ".") { 258 style = state.tokenize(stream, state); 259 current = stream.current(); 260 if (/^\.[\w$]+$/.test(current)) { 261 return "variable"; 262 } else { 168 263 return ERRORCLASS; 169 } 170 171 function tokenFactory(delimiter, outclass) { 172 var singleline = delimiter.length == 1; 173 return function(stream, state) { 174 while (!stream.eol()) { 175 stream.eatWhile(/[^'"\/\\]/); 176 if (stream.eat('\\')) { 177 stream.next(); 178 if (singleline && stream.eol()) { 179 return outclass; 180 } 181 } else if (stream.match(delimiter)) { 182 state.tokenize = tokenBase; 183 return outclass; 184 } else { 185 stream.eat(/['"\/]/); 186 } 187 } 188 if (singleline) { 189 if (conf.mode.singleLineStringErrors) { 190 outclass = ERRORCLASS; 191 } else { 192 state.tokenize = tokenBase; 193 } 194 } 195 return outclass; 196 }; 197 } 198 199 function longComment(stream, state) { 200 while (!stream.eol()) { 201 stream.eatWhile(/[^#]/); 202 if (stream.match("###")) { 203 state.tokenize = tokenBase; 204 break; 205 } 206 stream.eatWhile("#"); 207 } 208 return "comment"; 209 } 210 211 function indent(stream, state, type) { 212 type = type || 'coffee'; 213 var indentUnit = 0; 214 if (type === 'coffee') { 215 for (var i = 0; i < state.scopes.length; i++) { 216 if (state.scopes[i].type === 'coffee') { 217 indentUnit = state.scopes[i].offset + conf.indentUnit; 218 break; 219 } 220 } 221 } else { 222 indentUnit = stream.column() + stream.current().length; 223 } 224 state.scopes.unshift({ 225 offset: indentUnit, 226 type: type 227 }); 228 } 229 230 function dedent(stream, state) { 231 if (state.scopes.length == 1) return; 232 if (state.scopes[0].type === 'coffee') { 233 var _indent = stream.indentation(); 234 var _indent_index = -1; 235 for (var i = 0; i < state.scopes.length; ++i) { 236 if (_indent === state.scopes[i].offset) { 237 _indent_index = i; 238 break; 239 } 240 } 241 if (_indent_index === -1) { 242 return true; 243 } 244 while (state.scopes[0].offset !== _indent) { 245 state.scopes.shift(); 246 } 247 return false; 248 } else { 249 state.scopes.shift(); 250 return false; 251 } 252 } 253 254 function tokenLexer(stream, state) { 255 var style = state.tokenize(stream, state); 256 var current = stream.current(); 257 258 // Handle '.' connected identifiers 259 if (current === '.') { 260 style = state.tokenize(stream, state); 261 current = stream.current(); 262 if (/^\.[\w$]+$/.test(current)) { 263 return 'variable'; 264 } else { 265 return ERRORCLASS; 266 } 267 } 268 269 // Handle scope changes. 270 if (current === 'return') { 271 state.dedent += 1; 272 } 273 if (((current === '->' || current === '=>') && 274 !state.lambda && 275 state.scopes[0].type == 'coffee' && 276 stream.peek() === '') 277 || style === 'indent') { 278 indent(stream, state); 279 } 280 var delimiter_index = '[({'.indexOf(current); 281 if (delimiter_index !== -1) { 282 indent(stream, state, '])}'.slice(delimiter_index, delimiter_index+1)); 283 } 284 if (indentKeywords.exec(current)){ 285 indent(stream, state); 286 } 287 if (current == 'then'){ 288 dedent(stream, state); 289 } 290 291 292 if (style === 'dedent') { 293 if (dedent(stream, state)) { 294 return ERRORCLASS; 295 } 296 } 297 delimiter_index = '])}'.indexOf(current); 298 if (delimiter_index !== -1) { 299 if (dedent(stream, state)) { 300 return ERRORCLASS; 301 } 302 } 303 if (state.dedent > 0 && stream.eol() && state.scopes[0].type == 'coffee') { 304 if (state.scopes.length > 1) state.scopes.shift(); 305 state.dedent -= 1; 306 } 307 308 return style; 309 } 310 311 var external = { 312 startState: function(basecolumn) { 313 return { 314 tokenize: tokenBase, 315 scopes: [{offset:basecolumn || 0, type:'coffee'}], 316 lastToken: null, 317 lambda: false, 318 dedent: 0 319 }; 320 }, 321 322 token: function(stream, state) { 323 var style = tokenLexer(stream, state); 324 325 state.lastToken = {style:style, content: stream.current()}; 326 327 if (stream.eol() && stream.lambda) { 328 state.lambda = false; 329 } 330 331 return style; 332 }, 333 334 indent: function(state) { 335 if (state.tokenize != tokenBase) { 336 return 0; 337 } 338 339 return state.scopes[0].offset; 340 }, 341 342 lineComment: "#", 343 fold: "indent" 344 }; 345 return external; 264 } 265 } 266 267 // Handle scope changes. 268 if (current === "return") { 269 state.dedent += 1; 270 } 271 if (((current === "->" || current === "=>") && 272 !state.lambda && 273 !stream.peek()) 274 || style === "indent") { 275 indent(stream, state); 276 } 277 var delimiter_index = "[({".indexOf(current); 278 if (delimiter_index !== -1) { 279 indent(stream, state, "])}".slice(delimiter_index, delimiter_index+1)); 280 } 281 if (indentKeywords.exec(current)){ 282 indent(stream, state); 283 } 284 if (current == "then"){ 285 dedent(stream, state); 286 } 287 288 289 if (style === "dedent") { 290 if (dedent(stream, state)) { 291 return ERRORCLASS; 292 } 293 } 294 delimiter_index = "])}".indexOf(current); 295 if (delimiter_index !== -1) { 296 while (state.scope.type == "coffee" && state.scope.prev) 297 state.scope = state.scope.prev; 298 if (state.scope.type == current) 299 state.scope = state.scope.prev; 300 } 301 if (state.dedent > 0 && stream.eol() && state.scope.type == "coffee") { 302 if (state.scope.prev) state.scope = state.scope.prev; 303 state.dedent -= 1; 304 } 305 306 return style; 307 } 308 309 var external = { 310 startState: function(basecolumn) { 311 return { 312 tokenize: tokenBase, 313 scope: {offset:basecolumn || 0, type:"coffee", prev: null, align: false}, 314 lastToken: null, 315 lambda: false, 316 dedent: 0 317 }; 318 }, 319 320 token: function(stream, state) { 321 var fillAlign = state.scope.align === null && state.scope; 322 if (fillAlign && stream.sol()) fillAlign.align = false; 323 324 var style = tokenLexer(stream, state); 325 if (fillAlign && style && style != "comment") fillAlign.align = true; 326 327 state.lastToken = {style:style, content: stream.current()}; 328 329 if (stream.eol() && stream.lambda) { 330 state.lambda = false; 331 } 332 333 return style; 334 }, 335 336 indent: function(state, text) { 337 if (state.tokenize != tokenBase) return 0; 338 var scope = state.scope; 339 var closer = text && "])}".indexOf(text.charAt(0)) > -1; 340 if (closer) while (scope.type == "coffee" && scope.prev) scope = scope.prev; 341 var closes = closer && scope.type === text.charAt(0); 342 if (scope.align) 343 return scope.alignOffset - (closes ? 1 : 0); 344 else 345 return (closes ? scope.prev : scope).offset; 346 }, 347 348 lineComment: "#", 349 fold: "indent" 350 }; 351 return external; 346 352 }); 347 353 348 CodeMirror.defineMIME( 'text/x-coffeescript', 'coffeescript');354 CodeMirror.defineMIME("text/x-coffeescript", "coffeescript"); -
trunk/Source/WebInspectorUI/UserInterface/External/CodeMirror/css.js
r155659 r160500 4 4 if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css"); 5 5 6 var indentUnit = config.indentUnit ,6 var indentUnit = config.indentUnit || config.tabSize || 2, 7 7 hooks = parserConfig.hooks || {}, 8 8 atMediaTypes = parserConfig.atMediaTypes || {}, … … 38 38 return ret("keyword", "important"); 39 39 } 40 else if (/\d/.test(ch) ) {40 else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) { 41 41 stream.eatWhile(/[\w.%]/); 42 42 return ret("number", "unit"); … … 260 260 else if (type == "}") { 261 261 if (context == "interpolation") style = "operator"; 262 state.stack.pop(); 263 if (context == "propertyValue") state.stack.pop(); 262 // Pop off end of array until { is reached 263 while(state.stack.length){ 264 var removed = state.stack.pop(); 265 if(removed.indexOf("{") > -1 || removed == "block" || removed == "rule"){ 266 break; 267 } 268 } 264 269 } 265 270 else if (type == "interpolation") state.stack.push("interpolation"); … … 279 284 } 280 285 else if (type == ")") { 281 if (context == "propertyValue") { 282 // In @mediaType( without closing ; after propertyValue 283 state.stack.pop(); 284 } 285 state.stack.pop(); 286 // Pop off end of array until ( is reached 287 while(state.stack.length){ 288 var removed = state.stack.pop(); 289 if(removed.indexOf("(") > -1){ 290 break; 291 } 292 } 286 293 } 287 294 else if (type == ":" && state.lastToken == "property") state.stack.push("propertyValue"); … … 603 610 return ["variable", "variable"]; 604 611 }, 612 ",": function(stream, state) { 613 if (state.stack[state.stack.length - 1] == "propertyValue" && stream.match(/^ *\$/, false)) { 614 return ["operator", ";"]; 615 } 616 }, 605 617 "/": function(stream, state) { 606 618 if (stream.eat("/")) { -
trunk/Source/WebInspectorUI/UserInterface/External/CodeMirror/htmlmixed.js
r151453 r160500 45 45 else if (m = cur.match(/<\/?$/)) { 46 46 stream.backUp(cur.length); 47 if (!stream.match(pat, false)) stream.match(cur [0]);47 if (!stream.match(pat, false)) stream.match(cur); 48 48 } 49 49 return style; -
trunk/Source/WebInspectorUI/UserInterface/External/CodeMirror/javascript.js
r154456 r160500 22 22 "in": operator, "typeof": operator, "instanceof": operator, 23 23 "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, 24 "this": kw("this") 24 "this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"), 25 "yield": C, "export": kw("export"), "import": kw("import"), "extends": C 25 26 }; 26 27 … … 31 32 // object-like things 32 33 "interface": kw("interface"), 33 "class": kw("class"),34 34 "extends": kw("extends"), 35 35 "constructor": kw("constructor"), … … 41 41 "static": kw("static"), 42 42 43 "super": kw("super"),44 45 43 // types 46 44 "string": type, "number": type, "bool": type, "any": type … … 56 54 57 55 var isOperatorChar = /[+\-*&%=<>!?|~^]/; 58 59 function chain(stream, state, f) {60 state.tokenize = f;61 return f(stream, state);62 }63 56 64 57 function nextUntilUnescaped(stream, end) { … … 79 72 return style; 80 73 } 81 function jsTokenBase(stream, state) {74 function tokenBase(stream, state) { 82 75 var ch = stream.next(); 83 if (ch == '"' || ch == "'") 84 return chain(stream, state, jsTokenString(ch)); 85 else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) 76 if (ch == '"' || ch == "'") { 77 state.tokenize = tokenString(ch); 78 return state.tokenize(stream, state); 79 } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) { 86 80 return ret("number", "number"); 87 else if (/[\[\]{}\(\),;\:\.]/.test(ch)) 81 } else if (ch == "." && stream.match("..")) { 82 return ret("spread", "meta"); 83 } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) { 88 84 return ret(ch); 89 else if (ch == "0" && stream.eat(/x/i)) { 85 } else if (ch == "=" && stream.eat(">")) { 86 return ret("=>"); 87 } else if (ch == "0" && stream.eat(/x/i)) { 90 88 stream.eatWhile(/[\da-f]/i); 91 89 return ret("number", "number"); 92 } 93 else if (/\d/.test(ch)) { 90 } else if (/\d/.test(ch)) { 94 91 stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); 95 92 return ret("number", "number"); 96 } 97 else if (ch == "/") { 93 } else if (ch == "/") { 98 94 if (stream.eat("*")) { 99 return chain(stream, state, jsTokenComment);100 }101 else if (stream.eat("/")) {95 state.tokenize = tokenComment; 96 return tokenComment(stream, state); 97 } else if (stream.eat("/")) { 102 98 stream.skipToEnd(); 103 99 return ret("comment", "comment"); 104 } 105 else if (state.lastType == "operator" || state.lastType == "keyword c" || 106 /^[\[{}\(,;:]$/.test(state.lastType)) { 100 } else if (state.lastType == "operator" || state.lastType == "keyword c" || 101 state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) { 107 102 nextUntilUnescaped(stream, "/"); 108 103 stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla 109 104 return ret("regexp", "string-2"); 110 } 111 else { 105 } else { 112 106 stream.eatWhile(isOperatorChar); 113 107 return ret("operator", null, stream.current()); 114 108 } 115 } 116 else if (ch == "#") { 109 } else if (ch == "`") { 110 state.tokenize = tokenQuasi; 111 return tokenQuasi(stream, state); 112 } else if (ch == "#") { 117 113 stream.skipToEnd(); 118 114 return ret("error", "error"); 119 } 120 else if (isOperatorChar.test(ch)) { 115 } else if (isOperatorChar.test(ch)) { 121 116 stream.eatWhile(isOperatorChar); 122 117 return ret("operator", null, stream.current()); 123 } 124 else { 118 } else { 125 119 stream.eatWhile(/[\w\$_]/); 126 120 var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; … … 130 124 } 131 125 132 function jsTokenString(quote) {126 function tokenString(quote) { 133 127 return function(stream, state) { 134 128 if (!nextUntilUnescaped(stream, quote)) 135 state.tokenize = jsTokenBase;129 state.tokenize = tokenBase; 136 130 return ret("string", "string"); 137 131 }; 138 132 } 139 133 140 function jsTokenComment(stream, state) {134 function tokenComment(stream, state) { 141 135 var maybeEnd = false, ch; 142 136 while (ch = stream.next()) { 143 137 if (ch == "/" && maybeEnd) { 144 state.tokenize = jsTokenBase;138 state.tokenize = tokenBase; 145 139 break; 146 140 } … … 148 142 } 149 143 return ret("comment", "comment"); 144 } 145 146 function tokenQuasi(stream, state) { 147 var escaped = false, next; 148 while ((next = stream.next()) != null) { 149 if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) { 150 state.tokenize = tokenBase; 151 break; 152 } 153 escaped = !escaped && next == "\\"; 154 } 155 return ret("quasi", "string-2", stream.current()); 156 } 157 158 var brackets = "([{}])"; 159 // This is a crude lookahead trick to try and notice that we're 160 // parsing the argument patterns for a fat-arrow function before we 161 // actually hit the arrow token. It only works if the arrow is on 162 // the same line as the arguments and there's no strange noise 163 // (comments) in between. Fallback is to only notice when we hit the 164 // arrow, and not declare the arguments as locals for the arrow 165 // body. 166 function findFatArrow(stream, state) { 167 if (state.fatArrowAt) state.fatArrowAt = null; 168 var arrow = stream.string.indexOf("=>", stream.start); 169 if (arrow < 0) return; 170 171 var depth = 0, sawSomething = false; 172 for (var pos = arrow - 1; pos >= 0; --pos) { 173 var ch = stream.string.charAt(pos); 174 var bracket = brackets.indexOf(ch); 175 if (bracket >= 0 && bracket < 3) { 176 if (!depth) { ++pos; break; } 177 if (--depth == 0) break; 178 } else if (bracket >= 3 && bracket < 6) { 179 ++depth; 180 } else if (/[$\w]/.test(ch)) { 181 sawSomething = true; 182 } else if (sawSomething && !depth) { 183 ++pos; 184 break; 185 } 186 } 187 if (sawSomething && !depth) state.fatArrowAt = pos; 150 188 } 151 189 … … 166 204 for (var v = state.localVars; v; v = v.next) 167 205 if (v.name == varname) return true; 206 for (var cx = state.context; cx; cx = cx.prev) { 207 for (var v = cx.vars; v; v = v.next) 208 if (v.name == varname) return true; 209 } 168 210 } 169 211 … … 212 254 } else { 213 255 if (inList(state.globalVars)) return; 214 state.globalVars = {name: varname, next: state.globalVars}; 256 if (parserConfig.globalVars) 257 state.globalVars = {name: varname, next: state.globalVars}; 215 258 } 216 259 } … … 254 297 } 255 298 256 function statement(type ) {257 if (type == "var") return cont(pushlex("vardef" ), vardef1, expect(";"), poplex);299 function statement(type, value) { 300 if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex); 258 301 if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); 259 302 if (type == "keyword b") return cont(pushlex("form"), statement, poplex); … … 262 305 if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse); 263 306 if (type == "function") return cont(functiondef); 264 if (type == "for") return cont(pushlex("form"), expect("("), pushlex(")"), forspec1, expect(")"), 265 poplex, statement, poplex); 307 if (type == "for") return cont(pushlex("form"), forspec, poplex, statement, poplex); 266 308 if (type == "variable") return cont(pushlex("stat"), maybelabel); 267 309 if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), … … 271 313 if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), 272 314 statement, poplex, popcontext); 315 if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex); 316 if (type == "class") return cont(pushlex("form"), className, objlit, poplex); 317 if (type == "export") return cont(pushlex("form"), afterExport, poplex); 318 if (type == "import") return cont(pushlex("form"), afterImport, poplex); 273 319 return pass(pushlex("stat"), expression, expect(";"), poplex); 274 320 } … … 280 326 } 281 327 function expressionInner(type, noComma) { 328 if (cx.state.fatArrowAt == cx.stream.start) { 329 var body = noComma ? arrowBodyNoComma : arrowBody; 330 if (type == "(") return cont(pushcontext, commasep(pattern, ")"), expect("=>"), body, popcontext); 331 else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext); 332 } 333 282 334 var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; 283 335 if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); 284 336 if (type == "function") return cont(functiondef); 285 337 if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression); 286 if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);287 if (type == "operator" ) return cont(noComma ? expressionNoComma : expression);288 if (type == "[") return cont(pushlex("]"), commasep(expressionNoComma, "]"), poplex, maybeop);289 if (type == "{") return cont( pushlex("}"), commasep(objprop, "}"), poplex, maybeop);338 if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop); 339 if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression); 340 if (type == "[") return cont(pushlex("]"), expressionNoComma, maybeArrayComprehension, poplex, maybeop); 341 if (type == "{") return cont(commasep(objprop, "}"), maybeop); 290 342 return cont(); 291 343 } … … 306 358 var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; 307 359 var expr = noComma == false ? expression : expressionNoComma; 360 if (value == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); 308 361 if (type == "operator") { 309 362 if (/\+\+|--/.test(value)) return cont(me); … … 311 364 return cont(expr); 312 365 } 366 if (type == "quasi") { cx.cc.push(me); return quasi(value); } 313 367 if (type == ";") return; 314 if (type == "(") return cont( pushlex(")", "call"), commasep(expressionNoComma, ")"), poplex, me);368 if (type == "(") return cont(commasep(expressionNoComma, ")", "call"), me); 315 369 if (type == ".") return cont(property, me); 316 370 if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me); 371 } 372 function quasi(value) { 373 if (!value) debugger; 374 if (value.slice(value.length - 2) != "${") return cont(); 375 return cont(expression, continueQuasi); 376 } 377 function continueQuasi(type) { 378 if (type == "}") { 379 cx.marked = "string-2"; 380 cx.state.tokenize = tokenQuasi; 381 return cont(); 382 } 383 } 384 function arrowBody(type) { 385 findFatArrow(cx.stream, cx.state); 386 if (type == "{") return pass(statement); 387 return pass(expression); 388 } 389 function arrowBodyNoComma(type) { 390 findFatArrow(cx.stream, cx.state); 391 if (type == "{") return pass(statement); 392 return pass(expressionNoComma); 317 393 } 318 394 function maybelabel(type) { … … 329 405 } else if (type == "number" || type == "string") { 330 406 cx.marked = type + " property"; 331 } 332 if (atomicTypes.hasOwnProperty(type)) return cont(expect(":"), expressionNoComma); 407 } else if (type == "[") { 408 return cont(expression, expect("]"), afterprop); 409 } 410 if (atomicTypes.hasOwnProperty(type)) return cont(afterprop); 333 411 } 334 412 function getterSetter(type) { 335 if (type == ":") return cont(expression); 336 if (type != "variable") return cont(expect(":"), expression); 413 if (type != "variable") return pass(afterprop); 337 414 cx.marked = "property"; 338 415 return cont(functiondef); 339 416 } 340 function commasep(what, end) { 417 function afterprop(type) { 418 if (type == ":") return cont(expressionNoComma); 419 if (type == "(") return pass(functiondef); 420 } 421 function commasep(what, end, info) { 341 422 function proceed(type) { 342 423 if (type == ",") { … … 350 431 return function(type) { 351 432 if (type == end) return cont(); 352 else return pass(what, proceed); 433 if (info === false) return pass(what, proceed); 434 return pass(pushlex(end, info), what, proceed, poplex); 353 435 }; 354 436 } … … 358 440 } 359 441 function maybetype(type) { 360 if (type == ":") return cont(typedef); 361 return pass(); 442 if (isTS && type == ":") return cont(typedef); 362 443 } 363 444 function typedef(type) { 364 445 if (type == "variable"){cx.marked = "variable-3"; return cont();} 365 return pass(); 366 } 367 function vardef1(type, value) { 368 if (type == "variable") { 446 } 447 function vardef() { 448 return pass(pattern, maybetype, maybeAssign, vardefCont); 449 } 450 function pattern(type, value) { 451 if (type == "variable") { register(value); return cont(); } 452 if (type == "[") return cont(commasep(pattern, "]")); 453 if (type == "{") return cont(commasep(proppattern, "}")); 454 } 455 function proppattern(type, value) { 456 if (type == "variable" && !cx.stream.match(/^\s*:/, false)) { 369 457 register(value); 370 return isTS ? cont(maybetype, vardef2) : cont(vardef2); 371 } 372 return pass(); 373 } 374 function vardef2(type, value) { 375 if (value == "=") return cont(expressionNoComma, vardef2); 376 if (type == ",") return cont(vardef1); 458 return cont(maybeAssign); 459 } 460 if (type == "variable") cx.marked = "property"; 461 return cont(expect(":"), pattern, maybeAssign); 462 } 463 function maybeAssign(_type, value) { 464 if (value == "=") return cont(expressionNoComma); 465 } 466 function vardefCont(type) { 467 if (type == ",") return cont(vardef); 377 468 } 378 469 function maybeelse(type, value) { 379 470 if (type == "keyword b" && value == "else") return cont(pushlex("form"), statement, poplex); 380 471 } 472 function forspec(type) { 473 if (type == "(") return cont(pushlex(")"), forspec1, expect(")")); 474 } 381 475 function forspec1(type) { 382 if (type == "var") return cont(vardef 1, expect(";"), forspec2);476 if (type == "var") return cont(vardef, expect(";"), forspec2); 383 477 if (type == ";") return cont(forspec2); 384 if (type == "variable") return cont(formaybein );478 if (type == "variable") return cont(formaybeinof); 385 479 return pass(expression, expect(";"), forspec2); 386 480 } 387 function formaybein (_type, value) {388 if (value == "in" ) return cont(expression);481 function formaybeinof(_type, value) { 482 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } 389 483 return cont(maybeoperatorComma, forspec2); 390 484 } 391 485 function forspec2(type, value) { 392 486 if (type == ";") return cont(forspec3); 393 if (value == "in" ) return cont(expression);487 if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } 394 488 return pass(expression, expect(";"), forspec3); 395 489 } … … 398 492 } 399 493 function functiondef(type, value) { 494 if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} 400 495 if (type == "variable") {register(value); return cont(functiondef);} 401 if (type == "(") return cont(pushlex(")"), pushcontext, commasep(funarg, ")"), poplex, statement, popcontext); 402 } 403 function funarg(type, value) { 404 if (type == "variable") {register(value); return isTS ? cont(maybetype) : cont();} 496 if (type == "(") return cont(pushcontext, commasep(funarg, ")"), statement, popcontext); 497 } 498 function funarg(type) { 499 if (type == "spread") return cont(funarg); 500 return pass(pattern, maybetype); 501 } 502 function className(type, value) { 503 if (type == "variable") {register(value); return cont(classNameAfter);} 504 } 505 function classNameAfter(_type, value) { 506 if (value == "extends") return cont(expression); 507 } 508 function objlit(type) { 509 if (type == "{") return cont(commasep(objprop, "}")); 510 } 511 function afterModule(type, value) { 512 if (type == "string") return cont(statement); 513 if (type == "variable") { register(value); return cont(maybeFrom); } 514 } 515 function afterExport(_type, value) { 516 if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); } 517 if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); } 518 return pass(statement); 519 } 520 function afterImport(type) { 521 if (type == "string") return cont(); 522 return pass(importSpec, maybeFrom); 523 } 524 function importSpec(type, value) { 525 if (type == "{") return cont(commasep(importSpec, "}")); 526 if (type == "variable") register(value); 527 return cont(); 528 } 529 function maybeFrom(_type, value) { 530 if (value == "from") { cx.marked = "keyword"; return cont(expression); } 531 } 532 function maybeArrayComprehension(type) { 533 if (type == "for") return pass(comprehension); 534 if (type == ",") return cont(commasep(expressionNoComma, "]", false)); 535 return pass(commasep(expressionNoComma, "]", false)); 536 } 537 function comprehension(type) { 538 if (type == "for") return cont(forspec, comprehension); 539 if (type == "if") return cont(expression, comprehension); 405 540 } 406 541 … … 409 544 return { 410 545 startState: function(basecolumn) { 411 return{412 tokenize: jsTokenBase,413 lastType: null,546 var state = { 547 tokenize: tokenBase, 548 lastType: "sof", 414 549 cc: [], 415 550 lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), 416 551 localVars: parserConfig.localVars, 417 globalVars: parserConfig.globalVars,418 552 context: parserConfig.localVars && {vars: parserConfig.localVars}, 419 553 indented: 0 420 554 }; 555 if (parserConfig.globalVars) state.globalVars = parserConfig.globalVars; 556 return state; 421 557 }, 422 558 … … 426 562 state.lexical.align = false; 427 563 state.indented = stream.indentation(); 428 } 429 if (state.tokenize != jsTokenComment && stream.eatSpace()) return null; 564 findFatArrow(stream, state); 565 } 566 if (state.tokenize != tokenComment && stream.eatSpace()) return null; 430 567 var style = state.tokenize(stream, state); 431 568 if (type == "comment") return style; … … 435 572 436 573 indent: function(state, textAfter) { 437 if (state.tokenize == jsTokenComment) return CodeMirror.Pass;438 if (state.tokenize != jsTokenBase) return 0;574 if (state.tokenize == tokenComment) return CodeMirror.Pass; 575 if (state.tokenize != tokenBase) return 0; 439 576 var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical; 440 577 // Kludge to prevent 'maybelse' from blocking lexical scope pops … … 442 579 var c = state.cc[i]; 443 580 if (c == poplex) lexical = lexical.prev; 444 else if (c != maybeelse || /^else\b/.test(textAfter)) break;581 else if (c != maybeelse) break; 445 582 } 446 583 if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; … … 449 586 var type = lexical.type, closing = firstChar == type; 450 587 451 if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? 4: 0);588 if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0); 452 589 else if (type == "form" && firstChar == "{") return lexical.indented; 453 590 else if (type == "form") return lexical.indented + indentUnit; -
trunk/Source/WebInspectorUI/UserInterface/External/CodeMirror/less.js
r155659 r160500 33 33 } else { 34 34 if(type == "string" || type == "(") return ret("string", "string"); 35 if(state.stack[state.stack.length-1] != undefined) return ret(null, ch);35 if(state.stack[state.stack.length-1] !== undefined) return ret(null, ch); 36 36 stream.eatWhile(/[\a-zA-Z0-9\-_.\s]/); 37 if( /\/|\)|#/.test(stream.peek() || (stream.eatSpace() && stream.peek() == ")")) || stream.eol() )return ret("string", "string"); // let url(/images/logo.png) without quotes return as string37 if( /\/|\)|#/.test(stream.peek() || (stream.eatSpace() && stream.peek() === ")")) || stream.eol() )return ret("string", "string"); // let url(/images/logo.png) without quotes return as string 38 38 } 39 39 } else if (ch == "!") { … … 67 67 } 68 68 } else if (ch == ".") { 69 if(type == "(" || type == "string")return ret("string", "string"); // allow url(../image.png)69 if(type == "(")return ret("string", "string"); // allow url(../image.png) 70 70 stream.eatWhile(/[\a-zA-Z0-9\-_]/); 71 if(stream.peek() == " ")stream.eatSpace(); 72 if(stream.peek() == ")")return ret("number", "unit");//rgba(0,0,0,.25); 71 if(stream.peek() === " ")stream.eatSpace(); 72 if(stream.peek() === ")" || type === ":")return ret("number", "unit");//rgba(0,0,0,.25); 73 else if(stream.current().length >1){ 74 if(state.stack[state.stack.length-1] === "rule" && stream.peek().match(/{|,|\+|\(/) === null)return ret("number", "unit"); 75 } 73 76 return ret("tag", "tag"); 74 77 } else if (ch == "#") { … … 83 86 stream.eatSpace(); 84 87 //when hex value declaration doesn't end with [;,] but is does with a slash/cc comment treat it as an id, just like the other hex values that don't end with[;,] 85 if( /[\/<>.(){!$%^&*_\-\\?=+\|#'~`]/.test(stream.peek()) )return ret("atom", "tag"); 88 if( /[\/<>.(){!$%^&*_\-\\?=+\|#'~`]/.test(stream.peek()) ){ 89 if(type === "select-op")return ret("number", "unit"); else return ret("atom", "tag"); 90 } 86 91 //#time { color: #aaa } 87 92 else if(stream.peek() == "}" )return ret("number", "unit"); 88 93 //we have a valid hex color value, parse as id whenever an element/class is defined after the hex(id) value e.g. #eee aaa || #eee .aaa 89 94 else if( /[a-zA-Z\\]/.test(stream.peek()) )return ret("atom", "tag"); 90 95 //when a hex value is on the end of a line, parse as id 91 96 else if(stream.eol())return ret("atom", "tag"); 92 97 //default 93 98 else return ret("number", "unit"); 94 99 } else {//when not a valid hexvalue in the current stream e.g. #footer 95 100 stream.eatWhile(/[\w\\\-]/); 96 return ret("atom", "tag");101 return ret("atom", stream.current()); 97 102 } 98 103 } else {//when not a valid hexvalue length 99 104 stream.eatWhile(/[\w\\\-]/); 105 if(state.stack[state.stack.length-1] === "rule")return ret("atom", stream.current());return ret("atom", stream.current()); 100 106 return ret("atom", "tag"); 101 107 } … … 105 111 } else { 106 112 stream.eatWhile(/[\w\\\-_%.{]/); 107 if(type == "string"){ 108 return ret("string", "string"); 113 if(stream.current().match(/\\/) !== null){ 114 if(stream.current().charAt(stream.current().length-1) === "\\"){ 115 stream.eat(/\'|\"|\)|\(/); 116 while(stream.eatWhile(/[\w\\\-_%.{]/)){ 117 stream.eat(/\'|\"|\)|\(/); 118 } 119 return ret("string", stream.current()); 120 } 121 } //else if(type === "tag")return ret("tag", "tag"); 122 else if(type == "string"){ 123 if(state.stack[state.stack.length-1] === "{" && stream.peek() === ":")return ret("variable", "variable"); 124 if(stream.peek() === "/")stream.eatWhile(/[\w\\\-_%.{:\/]/); 125 return ret(type, stream.current()); 109 126 } else if(stream.current().match(/(^http$|^https$)/) != null){ 110 127 stream.eatWhile(/[\w\\\-_%.{:\/]/); 128 if(stream.peek() === "/")stream.eatWhile(/[\w\\\-_%.{:\/]/); 111 129 return ret("string", "string"); 112 130 } else if(stream.peek() == "<" || stream.peek() == ">" || stream.peek() == "+"){ 131 if(type === "(" && (stream.current() === "n" || stream.current() === "-n"))return ret("string", stream.current()); 113 132 return ret("tag", "tag"); 114 133 } else if( /\(/.test(stream.peek()) ){ 134 if(stream.current() === "when")return ret("variable","variable"); 135 else if(state.stack[state.stack.length-1] === "@media" && stream.current() === "and")return ret("variable",stream.current()); 115 136 return ret(null, ch); 116 } else if (stream.peek() == "/" && state.stack[state.stack.length-1] != undefined){ // url(dir/center/image.png) 117 return ret("string", "string"); 137 } else if (stream.peek() == "/" && state.stack[state.stack.length-1] !== undefined){ // url(dir/center/image.png) 138 if(stream.peek() === "/")stream.eatWhile(/[\w\\\-_%.{:\/]/); 139 return ret("string", stream.current()); 118 140 } else if( stream.current().match(/\-\d|\-.\d/) ){ // match e.g.: -5px -0.4 etc... only colorize the minus sign 119 141 //commment out these 2 comment if you want the minus sign to be parsed as null -500px … … 130 152 return ret("string", "string"); // let url(/images/logo.png) without quotes return as string 131 153 } else if( stream.eol() || stream.peek() == "[" || stream.peek() == "#" || type == "tag" ){ 154 132 155 if(stream.current().substring(stream.current().length-1,stream.current().length) == "{")stream.backUp(1); 156 else if(state.stack[state.stack.length-1] === "border-color" || state.stack[state.stack.length-1] === "background-position" || state.stack[state.stack.length-1] === "font-family")return ret(null, stream.current()); 157 else if(type === "tag")return ret("tag", "tag"); 158 else if((type === ":" || type === "unit") && state.stack[state.stack.length-1] === "rule")return ret(null, stream.current()); 159 else if(state.stack[state.stack.length-1] === "rule" && type === "tag")return ret("string", stream.current()); 160 else if(state.stack[state.stack.length-1] === ";" && type === ":")return ret(null, stream.current()); 161 //else if(state.stack[state.stack.length-1] === ";" || type === "")return ret("variable", stream.current()); 162 else if(stream.peek() === "#" && type !== undefined && type.match(/\+|,|tag|select\-op|}|{|;/g) === null)return ret("string", stream.current()); 163 else if(type === "variable")return ret(null, stream.current()); 164 else if(state.stack[state.stack.length-1] === "{" && type === "comment")return ret("variable", stream.current()); 165 else if(state.stack.length === 0 && (type === ";" || type === "comment"))return ret("tag", stream.current()); 166 else if((state.stack[state.stack.length-1] === "{" || type === ";") && state.stack[state.stack.length-1] !== "@media{")return ret("variable", stream.current()); 167 else if(state.stack[state.stack.length-2] === "{" && state.stack[state.stack.length-1] === ";")return ret("variable", stream.current()); 168 133 169 return ret("tag", "tag"); 134 170 } else if(type == "compare" || type == "a" || type == "("){ 135 171 return ret("string", "string"); 136 172 } else if(type == "|" || stream.current() == "-" || type == "["){ 137 if(type == "|" )return ret("tag", "tag"); 173 if(type == "|" && stream.peek().match(/\]|=|\~/) !== null)return ret("number", stream.current()); 174 else if(type == "|" )return ret("tag", "tag"); 175 else if(type == "["){ 176 stream.eatWhile(/\w\-/); 177 return ret("number", stream.current()); 178 } 138 179 return ret(null, ch); 139 } else if( stream.peek() == ":") {180 } else if((stream.peek() == ":") || ( stream.eatSpace() && stream.peek() == ":")) { 140 181 stream.next(); 141 182 var t_v = stream.peek() == ":" ? true : false; … … 153 194 } 154 195 if(t_v)return ret("tag", "tag"); else return ret("variable", "variable"); 155 } else if(state.stack[state.stack.length-1] === "font-family" ){196 } else if(state.stack[state.stack.length-1] === "font-family" || state.stack[state.stack.length-1] === "background-position" || state.stack[state.stack.length-1] === "border-color"){ 156 197 return ret(null, null); 157 198 } else { 158 if(state.stack[state.stack.length-1] === "{" || type === "select-op" || (state.stack[state.stack.length-1] === "rule" && type === ",") )return ret("tag", "tag"); 159 return ret("variable", "variable"); 199 200 if(state.stack[state.stack.length-1] === null && type === ":")return ret(null, stream.current()); 201 202 //else if((type === ")" && state.stack[state.stack.length-1] === "rule") || (state.stack[state.stack.length-2] === "{" && state.stack[state.stack.length-1] === "rule" && type === "variable"))return ret(null, stream.current()); 203 204 else if(/\^|\$/.test(stream.current()) && stream.peek().match(/\~|=/) !== null)return ret("string", "string");//att^=val 205 206 else if(type === "unit" && state.stack[state.stack.length-1] === "rule")return ret(null, "unit"); 207 else if(type === "unit" && state.stack[state.stack.length-1] === ";")return ret(null, "unit"); 208 else if(type === ")" && state.stack[state.stack.length-1] === "rule")return ret(null, "unit"); 209 else if(type && type.match("@") !== null && state.stack[state.stack.length-1] === "rule")return ret(null, "unit"); 210 //else if(type === "unit" && state.stack[state.stack.length-1] === "rule")return ret(null, stream.current()); 211 212 else if((type === ";" || type === "}" || type === ",") && state.stack[state.stack.length-1] === ";")return ret("tag", stream.current()); 213 else if((type === ";" && stream.peek() !== undefined && stream.peek().match(/{|./) === null) || (type === ";" && stream.eatSpace() && stream.peek().match(/{|./) === null))return ret("variable", stream.current()); 214 else if((type === "@media" && state.stack[state.stack.length-1] === "@media") || type === "@namespace")return ret("tag", stream.current()); 215 216 else if(type === "{" && state.stack[state.stack.length-1] === ";" && stream.peek() === "{")return ret("tag", "tag"); 217 else if((type === "{" || type === ":") && state.stack[state.stack.length-1] === ";")return ret(null, stream.current()); 218 else if((state.stack[state.stack.length-1] === "{" && stream.eatSpace() && stream.peek().match(/.|#/) === null) || type === "select-op" || (state.stack[state.stack.length-1] === "rule" && type === ",") )return ret("tag", "tag"); 219 else if(type === "variable" && state.stack[state.stack.length-1] === "rule")return ret("tag", "tag"); 220 else if((stream.eatSpace() && stream.peek() === "{") || stream.eol() || stream.peek() === "{")return ret("tag", "tag"); 221 //this one messes up indentation 222 //else if((type === "}" && stream.peek() !== ":") || (type === "}" && stream.eatSpace() && stream.peek() !== ":"))return(type, "tag"); 223 224 else if(type === ")" && (stream.current() == "and" || stream.current() == "and "))return ret("variable", "variable"); 225 else if(type === ")" && (stream.current() == "when" || stream.current() == "when "))return ret("variable", "variable"); 226 else if(type === ")" || type === "comment" || type === "{")return ret("tag", "tag"); 227 else if(stream.sol())return ret("tag", "tag"); 228 else if((stream.eatSpace() && stream.peek() === "#") || stream.peek() === "#")return ret("tag", "tag"); 229 else if(state.stack.length === 0)return ret("tag", "tag"); 230 else if(type === ";" && stream.peek() !== undefined && stream.peek().match(/^[.|\#]/g) !== null)return ret("tag", "tag"); 231 232 else if(type === ":"){stream.eatSpace();return ret(null, stream.current());} 233 234 else if(stream.current() === "and " || stream.current() === "and")return ret("variable", stream.current()); 235 else if(type === ";" && state.stack[state.stack.length-1] === "{")return ret("variable", stream.current()); 236 237 else if(state.stack[state.stack.length-1] === "rule")return ret(null, stream.current()); 238 239 return ret("tag", stream.current()); 160 240 } 161 241 } … … 235 315 else if (type == "@media") state.stack.push("@media"); 236 316 else if (stream.current() === "font-family") state.stack[state.stack.length-1] = "font-family"; 317 else if (stream.current() === "background-position") state.stack[state.stack.length-1] = "background-position"; 318 else if (stream.current() === "border-color") state.stack[state.stack.length-1] = "border-color"; 237 319 else if (context == "{" && type != "comment" && type !== "tag") state.stack.push("rule"); 238 320 else if (stream.peek() === ":" && stream.current().match(/@|#/) === null) style = type; 321 if(type === ";" && (state.stack[state.stack.length-1] == "font-family" || state.stack[state.stack.length-1] == "background-position" || state.stack[state.stack.length-1] == "border-color"))state.stack[state.stack.length-1] = stream.current(); 322 else if(type === "tag" && stream.peek() === ")" && stream.current().match(/\:/) === null){type = null; style = null;} 323 // ???? 324 else if((type === "variable" && stream.peek() === ")") || (type === "variable" && stream.eatSpace() && stream.peek() === ")"))return ret(null,stream.current()); 239 325 return style; 240 326 }, … … 242 328 indent: function(state, textAfter) { 243 329 var n = state.stack.length; 244 245 330 if (/^\}/.test(textAfter)) 246 n -= state.stack[state.stack.length-1] == "rule" ? 2 : 1; 331 n -= state.stack[state.stack.length-1] === "rule" ? 2 : 1; 332 else if (state.stack[state.stack.length-2] === "{") 333 n -= state.stack[state.stack.length-1] === "rule" ? 1 : 0; 247 334 return state.baseIndent + n * indentUnit; 248 335 }, 249 336 250 electricChars: "}" 337 electricChars: "}", 338 blockCommentStart: "/*", 339 blockCommentEnd: "*/", 340 lineComment: "//" 251 341 }; 252 342 }); -
trunk/Source/WebInspectorUI/UserInterface/External/CodeMirror/matchbrackets.js
r152669 r160500 9 9 var state = cm.state.matchBrackets; 10 10 var maxScanLen = (state && state.maxScanLineLength) || 10000; 11 var maxScanLines = (state && state.maxScanLines) || 100; 11 12 12 13 var cur = where || cm.getCursor(), line = cm.getLineHandle(cur.line), pos = cur.ch - 1; … … 33 34 } 34 35 } 35 for (var i = cur.line, found, e = forward ? Math.min(i + 100, cm.lineCount()) : Math.max(-1, i - 100); i != e; i+=d) {36 for (var i = cur.line, found, e = forward ? Math.min(i + maxScanLines, cm.lineCount()) : Math.max(-1, i - maxScanLines); i != e; i+=d) { 36 37 if (i == cur.line) found = scan(line, i, pos); 37 38 else found = scan(cm.getLineHandle(i), i); -
trunk/Source/WebInspectorUI/UserInterface/External/CodeMirror/placeholder.js
r151453 r160500 3 3 var prev = old && old != CodeMirror.Init; 4 4 if (val && !prev) { 5 cm.on("focus", onFocus);6 5 cm.on("blur", onBlur); 7 6 cm.on("change", onChange); 8 7 onChange(cm); 9 8 } else if (!val && prev) { 10 cm.off("focus", onFocus);11 9 cm.off("blur", onBlur); 12 10 cm.off("change", onChange); … … 34 32 } 35 33 36 function onFocus(cm) {37 clearPlaceholder(cm);38 }39 34 function onBlur(cm) { 40 35 if (isEmpty(cm)) setPlaceholder(cm); … … 44 39 wrapper.className = wrapper.className.replace(" CodeMirror-empty", "") + (empty ? " CodeMirror-empty" : ""); 45 40 46 if (cm.hasFocus()) return;47 41 if (empty) setPlaceholder(cm); 48 42 else clearPlaceholder(cm); -
trunk/Source/WebInspectorUI/UserInterface/External/CodeMirror/runmode.js
r151453 r160500 50 50 while (!stream.eol()) { 51 51 var style = mode.token(stream, state); 52 callback(stream.current(), style, i, stream.start );52 callback(stream.current(), style, i, stream.start, state); 53 53 stream.start = stream.pos; 54 54 } -
trunk/Source/WebInspectorUI/UserInterface/External/CodeMirror/searchcursor.js
r151453 r160500 70 70 var ln = pos.line, idx = (reverse ? target.length - 1 : 0), match = target[idx], line = fold(doc.getLine(ln)); 71 71 var offsetA = (reverse ? line.indexOf(match) + match.length : line.lastIndexOf(match)); 72 if (reverse ? offsetA > =pos.ch || offsetA != match.length73 : offsetA < =pos.ch || offsetA != line.length - match.length)72 if (reverse ? offsetA > pos.ch || offsetA != match.length 73 : offsetA < pos.ch || offsetA != line.length - match.length) 74 74 return; 75 75 for (;;) { -
trunk/Source/WebInspectorUI/UserInterface/External/CodeMirror/sql.js
r155659 r160500 263 263 }); 264 264 265 CodeMirror.defineMIME("text/x-mssql", { 266 name: "sql", 267 client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"), 268 keywords: set(sqlKeywords + "begin trigger proc view index for add constraint key primary foreign collate clustered nonclustered"), 269 builtin: set("bigint numeric bit smallint decimal smallmoney int tinyint money float real char varchar text nchar nvarchar ntext binary varbinary image cursor timestamp hierarchyid uniqueidentifier sql_variant xml table "), 270 atoms: set("false true null unknown"), 271 operatorChars: /^[*+\-%<>!=]/, 272 dateSQL: set("date datetimeoffset datetime2 smalldatetime datetime time"), 273 hooks: { 274 "@": hookVar 275 } 276 }); 277 265 278 CodeMirror.defineMIME("text/x-mysql", { 266 279 name: "sql", 267 280 client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"), 268 keywords: set(sqlKeywords + "accessible action add after algorithm all analyze asensitive at authors auto_increment autocommit avg avg_row_length before binary binlog both btree cache call cascade cascaded case catalog_name chain change changed character check checkpoint checksum class_origin client_statistics close coalesce code collate collation collations column columns comment commit committed completion concurrent condition connection consistent constraint contains continue contributors convert cross current _date current_time current_timestamp current_user cursor data database databases day_hour day_microsecond day_minute day_second deallocate dec declare default delay_key_write delayed delimiter des_key_file describe deterministic dev_pop dev_samp deviance directory disable discard distinctrow div dual dumpfile each elseif enable enclosed end ends engine engines enum errors escape escaped even event events every execute exists exit explain extended fast fetch field fields first flush for force foreign found_rows full fulltext function generalglobal grant grants group groupby_concat handler hash help high_priority hosts hour_microsecond hour_minute hour_second if ignore ignore_server_ids import index index_statistics infile inner innodb inout insensitive insert_method install interval invoker isolation iterate key keys kill language last leading leave left level limit linear lines list load local localtime localtimestamp lock logs low_priority master master_heartbeat_period master_ssl_verify_server_cert masters match max max_rows maxvalue message_text middleint migrate min min_rows minute_microsecond minute_second mod mode modifies modify mutex mysql_errno natural next no no_write_to_binlog offline offset one online open optimize option optionally out outer outfile pack_keys parser partition partitions password phase plugin plugins prepare preserve prev primary privileges procedure processlist profile profiles purge query quick range read read_write reads real rebuild recover references regexp relaylog release remove rename reorganize repair repeatable replace require resignal restrict resume return returns revoke right rlike rollback rollup row row_format rtree savepoint schedule schema schema_name schemas second_microsecond security sensitive separator serializable server session share show signal slave slow smallint snapshot soname spatial specific sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sqlexception sqlstate sqlwarning ssl start starting starts status std stddev stddev_pop stddev_samp storage straight_join subclass_origin sum suspend table_name table_statistics tables tablespace temporary terminated to trailing transaction trigger triggers truncate uncommitted undo uninstall unique unlock upgrade usage use use_frm user user_resources user_statistics using utc_date utc_time utc_timestamp value variables varying view views warnings when while with work write xa xor year_month zerofill begin do then else loop repeat"),269 builtin: set("bool boolean bit blob decimal double enumfloat long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision date datetime year unsigned signed numeric"),281 keywords: set(sqlKeywords + "accessible action add after algorithm all analyze asensitive at authors auto_increment autocommit avg avg_row_length before binary binlog both btree cache call cascade cascaded case catalog_name chain change changed character check checkpoint checksum class_origin client_statistics close coalesce code collate collation collations column columns comment commit committed completion concurrent condition connection consistent constraint contains continue contributors convert cross current current_date current_time current_timestamp current_user cursor data database databases day_hour day_microsecond day_minute day_second deallocate dec declare default delay_key_write delayed delimiter des_key_file describe deterministic dev_pop dev_samp deviance diagnostics directory disable discard distinctrow div dual dumpfile each elseif enable enclosed end ends engine engines enum errors escape escaped even event events every execute exists exit explain extended fast fetch field fields first flush for force foreign found_rows full fulltext function general get global grant grants group groupby_concat handler hash help high_priority hosts hour_microsecond hour_minute hour_second if ignore ignore_server_ids import index index_statistics infile inner innodb inout insensitive insert_method install interval invoker isolation iterate key keys kill language last leading leave left level limit linear lines list load local localtime localtimestamp lock logs low_priority master master_heartbeat_period master_ssl_verify_server_cert masters match max max_rows maxvalue message_text middleint migrate min min_rows minute_microsecond minute_second mod mode modifies modify mutex mysql_errno natural next no no_write_to_binlog offline offset one online open optimize option optionally out outer outfile pack_keys parser partition partitions password phase plugin plugins prepare preserve prev primary privileges procedure processlist profile profiles purge query quick range read read_write reads real rebuild recover references regexp relaylog release remove rename reorganize repair repeatable replace require resignal restrict resume return returns revoke right rlike rollback rollup row row_format rtree savepoint schedule schema schema_name schemas second_microsecond security sensitive separator serializable server session share show signal slave slow smallint snapshot soname spatial specific sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sqlexception sqlstate sqlwarning ssl start starting starts status std stddev stddev_pop stddev_samp storage straight_join subclass_origin sum suspend table_name table_statistics tables tablespace temporary terminated to trailing transaction trigger triggers truncate uncommitted undo uninstall unique unlock upgrade usage use use_frm user user_resources user_statistics using utc_date utc_time utc_timestamp value variables varying view views warnings when while with work write xa xor year_month zerofill begin do then else loop repeat"), 282 builtin: set("bool boolean bit blob decimal double float long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision date datetime year unsigned signed numeric"), 270 283 atoms: set("false true null unknown"), 271 284 operatorChars: /^[*+\-%<>!=&|^]/, … … 282 295 name: "sql", 283 296 client: set("charset clear connect edit ego exit go help nopager notee nowarning pager print prompt quit rehash source status system tee"), 284 keywords: set(sqlKeywords + "accessible action add after algorithm all always analyze asensitive at authors auto_increment autocommit avg avg_row_length before binary binlog both btree cache call cascade cascaded case catalog_name chain change changed character check checkpoint checksum class_origin client_statistics close coalesce code collate collation collations column columns comment commit committed completion concurrent condition connection consistent constraint contains continue contributors convert cross current _date current_time current_timestamp current_user cursor data database databases day_hour day_microsecond day_minute day_second deallocate dec declare default delay_key_write delayed delimiter des_key_file describe deterministic dev_pop dev_samp deviance directory disable discard distinctrow div dual dumpfile each elseif enable enclosed end ends engine engines enum errors escape escaped even event events every execute exists exit explain extended fast fetch field fields first flush for force foreign found_rows full fulltext function general generated global grant grants group groupby_concat handler hard hash help high_priority hosts hour_microsecond hour_minute hour_second if ignore ignore_server_ids import index index_statistics infile inner innodb inout insensitive insert_method install interval invoker isolation iterate key keys kill language last leading leave left level limit linear lines list load local localtime localtimestamp lock logs low_priority master master_heartbeat_period master_ssl_verify_server_cert masters match max max_rows maxvalue message_text middleint migrate min min_rows minute_microsecond minute_second mod mode modifies modify mutex mysql_errno natural next no no_write_to_binlog offline offset one online open optimize option optionally out outer outfile pack_keys parser partition partitions password persistent phase plugin plugins prepare preserve prev primary privileges procedure processlist profile profiles purge query quick range read read_write reads real rebuild recover references regexp relaylog release remove rename reorganize repair repeatable replace require resignal restrict resume return returns revoke right rlike rollback rollup row row_format rtree savepoint schedule schema schema_name schemas second_microsecond security sensitive separator serializable server session share showsignal slave slow smallint snapshot soft soname spatial specific sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sqlexception sqlstate sqlwarning ssl start starting starts status std stddev stddev_pop stddev_samp storage straight_join subclass_origin sum suspend table_name table_statistics tables tablespace temporary terminated to trailing transaction trigger triggers truncate uncommitted undo uninstall unique unlock upgrade usage use use_frm user user_resources user_statistics using utc_date utc_time utc_timestamp value variables varying view views virtual warnings when while with work write xa xor year_month zerofill begin do then else loop repeat"),285 builtin: set("bool boolean bit blob decimal double enumfloat long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision date datetime year unsigned signed numeric"),297 keywords: set(sqlKeywords + "accessible action add after algorithm all always analyze asensitive at authors auto_increment autocommit avg avg_row_length before binary binlog both btree cache call cascade cascaded case catalog_name chain change changed character check checkpoint checksum class_origin client_statistics close coalesce code collate collation collations column columns comment commit committed completion concurrent condition connection consistent constraint contains continue contributors convert cross current current_date current_time current_timestamp current_user cursor data database databases day_hour day_microsecond day_minute day_second deallocate dec declare default delay_key_write delayed delimiter des_key_file describe deterministic dev_pop dev_samp deviance diagnostics directory disable discard distinctrow div dual dumpfile each elseif enable enclosed end ends engine engines enum errors escape escaped even event events every execute exists exit explain extended fast fetch field fields first flush for force foreign found_rows full fulltext function general generated get global grant grants group groupby_concat handler hard hash help high_priority hosts hour_microsecond hour_minute hour_second if ignore ignore_server_ids import index index_statistics infile inner innodb inout insensitive insert_method install interval invoker isolation iterate key keys kill language last leading leave left level limit linear lines list load local localtime localtimestamp lock logs low_priority master master_heartbeat_period master_ssl_verify_server_cert masters match max max_rows maxvalue message_text middleint migrate min min_rows minute_microsecond minute_second mod mode modifies modify mutex mysql_errno natural next no no_write_to_binlog offline offset one online open optimize option optionally out outer outfile pack_keys parser partition partitions password persistent phase plugin plugins prepare preserve prev primary privileges procedure processlist profile profiles purge query quick range read read_write reads real rebuild recover references regexp relaylog release remove rename reorganize repair repeatable replace require resignal restrict resume return returns revoke right rlike rollback rollup row row_format rtree savepoint schedule schema schema_name schemas second_microsecond security sensitive separator serializable server session share show shutdown signal slave slow smallint snapshot soft soname spatial specific sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sqlexception sqlstate sqlwarning ssl start starting starts status std stddev stddev_pop stddev_samp storage straight_join subclass_origin sum suspend table_name table_statistics tables tablespace temporary terminated to trailing transaction trigger triggers truncate uncommitted undo uninstall unique unlock upgrade usage use use_frm user user_resources user_statistics using utc_date utc_time utc_timestamp value variables varying view views virtual warnings when while with work write xa xor year_month zerofill begin do then else loop repeat"), 298 builtin: set("bool boolean bit blob decimal double float long longblob longtext medium mediumblob mediumint mediumtext time timestamp tinyblob tinyint tinytext text bigint int int1 int2 int3 int4 int8 integer float float4 float8 double char varbinary varchar varcharacter precision date datetime year unsigned signed numeric"), 286 299 atoms: set("false true null unknown"), 287 300 operatorChars: /^[*+\-%<>!=&|^]/, … … 314 327 client: set("appinfo arraysize autocommit autoprint autorecovery autotrace blockterminator break btitle cmdsep colsep compatibility compute concat copycommit copytypecheck define describe echo editfile embedded escape exec execute feedback flagger flush heading headsep instance linesize lno loboffset logsource long longchunksize markup native newpage numformat numwidth pagesize pause pno recsep recsepchar release repfooter repheader serveroutput shiftinout show showmode size spool sqlblanklines sqlcase sqlcode sqlcontinue sqlnumber sqlpluscompatibility sqlprefix sqlprompt sqlterminator suffix tab term termout time timing trimout trimspool ttitle underline verify version wrap"), 315 328 keywords: set("abort accept access add all alter and any array arraylen as asc assert assign at attributes audit authorization avg base_table begin between binary_integer body boolean by case cast char char_base check close cluster clusters colauth column comment commit compress connect connected constant constraint crash create current currval cursor data_base database date dba deallocate debugoff debugon decimal declare default definition delay delete desc digits dispose distinct do drop else elsif enable end entry escape exception exception_init exchange exclusive exists exit external fast fetch file for force form from function generic goto grant group having identified if immediate in increment index indexes indicator initial initrans insert interface intersect into is key level library like limited local lock log logging long loop master maxextents maxtrans member minextents minus mislabel mode modify multiset new next no noaudit nocompress nologging noparallel not nowait number_base object of off offline on online only open option or order out package parallel partition pctfree pctincrease pctused pls_integer positive positiven pragma primary prior private privileges procedure public raise range raw read rebuild record ref references refresh release rename replace resource restrict return returning reverse revoke rollback row rowid rowlabel rownum rows run savepoint schema segment select separate session set share snapshot some space split sql start statement storage subtype successful synonym tabauth table tables tablespace task terminate then to trigger truncate type union unique unlimited unrecoverable unusable update use using validate value values variable view views when whenever where while with work"), 316 functions: set("abs acos add_months ascii asin atan atan2 average bfilename ceil chartorowid chr concat convert cos cosh count decode deref dual dump dup_val_on_index empty error exp false floor found glb greatest hextoraw initcap instr instrb isopen last_day least lenght lenghtb ln lower lpad ltrim lub make_ref max min mod months_between new_time next_day nextval nls_charset_decl_len nls_charset_id nls_charset_name nls_initcap nls_lower nls_sort nls_upper nlssort no_data_found notfound null nvl others power rawtohex reftohex round rowcount rowidtochar rpad rtrim sign sin sinh soundex sqlcode sqlerrm sqrt stddev substr substrb sum sysdate tan tanh to_char to_date to_label to_multi_byte to_number to_single_byte translate true trunc uid upper user userenv variance vsize"), 317 builtin: set("bfile blob character clob dec float int integer mlslabel natural naturaln nchar nclob number numeric nvarchar2 real rowtype signtype smallint string varchar varchar2"), 329 builtin: set("bfile blob character clob dec float int integer mlslabel natural naturaln nchar nclob number numeric nvarchar2 real rowtype signtype smallint string varchar varchar2 abs acos add_months ascii asin atan atan2 average bfilename ceil chartorowid chr concat convert cos cosh count decode deref dual dump dup_val_on_index empty error exp false floor found glb greatest hextoraw initcap instr instrb isopen last_day least lenght lenghtb ln lower lpad ltrim lub make_ref max min mod months_between new_time next_day nextval nls_charset_decl_len nls_charset_id nls_charset_name nls_initcap nls_lower nls_sort nls_upper nlssort no_data_found notfound null nvl others power rawtohex reftohex round rowcount rowidtochar rpad rtrim sign sin sinh soundex sqlcode sqlerrm sqrt stddev substr substrb sum sysdate tan tanh to_char to_date to_label to_multi_byte to_number to_single_byte translate true trunc uid upper user userenv variance vsize"), 318 330 operatorChars: /^[*+\-%<>!=~]/, 319 331 dateSQL: set("date time timestamp"), -
trunk/Source/WebInspectorUI/UserInterface/External/CodeMirror/xml.js
r154456 r160500 77 77 var c; 78 78 while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c; 79 if (!tagName) return " error";79 if (!tagName) return "tag error"; 80 80 type = isClose ? "closeTag" : "openTag"; 81 81 state.tokenize = inTag; … … 110 110 return null; 111 111 } else if (ch == "<") { 112 return "error"; 112 state.tokenize = inText; 113 var next = state.tokenize(stream, state); 114 return next ? next + " error" : "error"; 113 115 } else if (/[\'\"]/.test(ch)) { 114 116 state.tokenize = inAttribute(ch); … … 299 301 } 300 302 state.startOfLine = false; 301 return setStyle || style; 303 if (setStyle) 304 style = setStyle == "error" ? style + " error" : setStyle; 305 return style; 302 306 }, 303 307
Note: See TracChangeset
for help on using the changeset viewer.