| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,155 @@ | ||
| CodeMirror.showHint = function(cm, getHints, options) { | ||
| if (!options) options = {}; | ||
| var startCh = cm.getCursor().ch, continued = false; | ||
|
|
||
| function startHinting() { | ||
| // We want a single cursor position. | ||
| if (cm.somethingSelected()) return; | ||
|
|
||
| if (options.async) | ||
| getHints(cm, showHints, options); | ||
| else | ||
| return showHints(getHints(cm, options)); | ||
| } | ||
|
|
||
| function showHints(data) { | ||
| if (!data || !data.list.length) return; | ||
| var completions = data.list; | ||
| // When there is only one completion, use it directly. | ||
| if (!continued && options.completeSingle !== false && completions.length == 1) { | ||
| cm.replaceRange(completions[0], data.from, data.to); | ||
| return true; | ||
| } | ||
|
|
||
| // Build the select widget | ||
| var hints = document.createElement("ul"), selectedHint = 0; | ||
| hints.className = "CodeMirror-hints"; | ||
| for (var i = 0; i < completions.length; ++i) { | ||
| var elt = hints.appendChild(document.createElement("li")); | ||
| elt.className = "CodeMirror-hint" + (i ? "" : " CodeMirror-hint-active"); | ||
| elt.appendChild(document.createTextNode(completions[i])); | ||
| elt.hintId = i; | ||
| } | ||
| var pos = cm.cursorCoords(options.alignWithWord !== false ? data.from : null); | ||
| var left = pos.left, top = pos.bottom, below = true; | ||
| hints.style.left = left + "px"; | ||
| hints.style.top = top + "px"; | ||
| document.body.appendChild(hints); | ||
|
|
||
| // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor. | ||
| var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth); | ||
| var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight); | ||
| var box = hints.getBoundingClientRect(); | ||
| var overlapX = box.right - winW, overlapY = box.bottom - winH; | ||
| if (overlapX > 0) { | ||
| if (box.right - box.left > winW) { | ||
| hints.style.width = (winW - 5) + "px"; | ||
| overlapX -= (box.right - box.left) - winW; | ||
| } | ||
| hints.style.left = (left = pos.left - overlapX) + "px"; | ||
| } | ||
| if (overlapY > 0) { | ||
| var height = box.bottom - box.top; | ||
| if (box.top - (pos.bottom - pos.top) - height > 0) { | ||
| overlapY = height + (pos.bottom - pos.top); | ||
| below = false; | ||
| } else if (height > winH) { | ||
| hints.style.height = (winH - 5) + "px"; | ||
| overlapY -= height - winH; | ||
| } | ||
| hints.style.top = (top = pos.bottom - overlapY) + "px"; | ||
| } | ||
|
|
||
| function changeActive(i) { | ||
| i = Math.max(0, Math.min(i, completions.length - 1)); | ||
| if (selectedHint == i) return; | ||
| hints.childNodes[selectedHint].className = "CodeMirror-hint"; | ||
| var node = hints.childNodes[selectedHint = i]; | ||
| node.className = "CodeMirror-hint CodeMirror-hint-active"; | ||
| if (node.offsetTop < hints.scrollTop) | ||
| hints.scrollTop = node.offsetTop - 3; | ||
| else if (node.offsetTop + node.offsetHeight > hints.scrollTop + hints.clientHeight) | ||
| hints.scrollTop = node.offsetTop + node.offsetHeight - hints.clientHeight + 3; | ||
| } | ||
|
|
||
| function screenAmount() { | ||
| return Math.floor(hints.clientHeight / hints.firstChild.offsetHeight) || 1; | ||
| } | ||
|
|
||
| var ourMap = { | ||
| Up: function() {changeActive(selectedHint - 1);}, | ||
| Down: function() {changeActive(selectedHint + 1);}, | ||
| PageUp: function() {changeActive(selectedHint - screenAmount());}, | ||
| PageDown: function() {changeActive(selectedHint + screenAmount());}, | ||
| Home: function() {changeActive(0);}, | ||
| End: function() {changeActive(completions.length - 1);}, | ||
| Enter: pick, | ||
| Tab: pick, | ||
| Esc: close | ||
| }; | ||
| if (options.customKeys) for (var key in options.customKeys) if (options.customKeys.hasOwnProperty(key)) { | ||
| var val = options.customKeys[key]; | ||
| if (/^(Up|Down|Enter|Esc)$/.test(key)) val = ourMap[val]; | ||
| ourMap[key] = val; | ||
| } | ||
|
|
||
| cm.addKeyMap(ourMap); | ||
| cm.on("cursorActivity", cursorActivity); | ||
| var closingOnBlur; | ||
| function onBlur(){ closingOnBlur = setTimeout(close, 100); }; | ||
| function onFocus(){ clearTimeout(closingOnBlur); }; | ||
| cm.on("blur", onBlur); | ||
| cm.on("focus", onFocus); | ||
| var startScroll = cm.getScrollInfo(); | ||
| function onScroll() { | ||
| var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect(); | ||
| var newTop = top + startScroll.top - curScroll.top, point = newTop; | ||
| if (!below) point += hints.offsetHeight; | ||
| if (point <= editor.top || point >= editor.bottom) return close(); | ||
| hints.style.top = newTop + "px"; | ||
| hints.style.left = (left + startScroll.left - curScroll.left) + "px"; | ||
| } | ||
| cm.on("scroll", onScroll); | ||
| CodeMirror.on(hints, "dblclick", function(e) { | ||
| var t = e.target || e.srcElement; | ||
| if (t.hintId != null) {selectedHint = t.hintId; pick();} | ||
| setTimeout(function(){cm.focus();}, 20); | ||
| }); | ||
| CodeMirror.on(hints, "click", function(e) { | ||
| var t = e.target || e.srcElement; | ||
| if (t.hintId != null) changeActive(t.hintId); | ||
| setTimeout(function(){cm.focus();}, 20); | ||
| }); | ||
|
|
||
| var done = false, once; | ||
| function close() { | ||
| if (done) return; | ||
| done = true; | ||
| clearTimeout(once); | ||
| hints.parentNode.removeChild(hints); | ||
| cm.removeKeyMap(ourMap); | ||
| cm.off("cursorActivity", cursorActivity); | ||
| cm.off("blur", onBlur); | ||
| cm.off("focus", onFocus); | ||
| cm.off("scroll", onScroll); | ||
| } | ||
| function pick() { | ||
| cm.replaceRange(completions[selectedHint], data.from, data.to); | ||
| close(); | ||
| } | ||
| var once, lastPos = cm.getCursor(), lastLen = cm.getLine(lastPos.line).length; | ||
| function cursorActivity() { | ||
| clearTimeout(once); | ||
|
|
||
| var pos = cm.getCursor(), len = cm.getLine(pos.line).length; | ||
| if (pos.line != lastPos.line || len - pos.ch != lastLen - lastPos.ch || | ||
| pos.ch < startCh || cm.somethingSelected()) | ||
| close(); | ||
| else | ||
| once = setTimeout(function(){close(); continued = true; startHinting();}, 70); | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| return startHinting(); | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,121 @@ | ||
| (function() { | ||
|
|
||
| var bogus = [ "Dangerous comment" ]; | ||
|
|
||
| var warnings = [ [ "Expected '{'", | ||
| "Statement body should be inside '{ }' braces." ] ]; | ||
|
|
||
| var errors = [ "Missing semicolon", "Extra comma", "Missing property name", | ||
| "Unmatched ", " and instead saw", " is not defined", | ||
| "Unclosed string", "Stopping, unable to continue" ]; | ||
|
|
||
| CodeMirror.javascriptValidator = function(text) { | ||
| JSHINT(text); | ||
| var errors = JSHINT.data().errors, result = []; | ||
| if (errors) parseErrors(errors, result); | ||
| return result; | ||
| }; | ||
|
|
||
| function cleanup(error) { | ||
| // All problems are warnings by default | ||
| fixWith(error, warnings, "warning", true); | ||
| fixWith(error, errors, "error"); | ||
|
|
||
| return isBogus(error) ? null : error; | ||
| } | ||
|
|
||
| function fixWith(error, fixes, severity, force) { | ||
| var description, fix, find, replace, found; | ||
|
|
||
| description = error.description; | ||
|
|
||
| for ( var i = 0; i < fixes.length; i++) { | ||
| fix = fixes[i]; | ||
| find = (typeof fix === "string" ? fix : fix[0]); | ||
| replace = (typeof fix === "string" ? null : fix[1]); | ||
| found = description.indexOf(find) !== -1; | ||
|
|
||
| if (force || found) { | ||
| error.severity = severity; | ||
| } | ||
| if (found && replace) { | ||
| error.description = replace; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| function isBogus(error) { | ||
| var description = error.description; | ||
| for ( var i = 0; i < bogus.length; i++) { | ||
| if (description.indexOf(bogus[i]) !== -1) { | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| function parseErrors(errors, output) { | ||
| for ( var i = 0; i < errors.length; i++) { | ||
| var error = errors[i]; | ||
| if (error) { | ||
| var linetabpositions, index; | ||
|
|
||
| linetabpositions = []; | ||
|
|
||
| // This next block is to fix a problem in jshint. Jshint | ||
| // replaces | ||
| // all tabs with spaces then performs some checks. The error | ||
| // positions (character/space) are then reported incorrectly, | ||
| // not taking the replacement step into account. Here we look | ||
| // at the evidence line and try to adjust the character position | ||
| // to the correct value. | ||
| if (error.evidence) { | ||
| // Tab positions are computed once per line and cached | ||
| var tabpositions = linetabpositions[error.line]; | ||
| if (!tabpositions) { | ||
| var evidence = error.evidence; | ||
| tabpositions = []; | ||
| // ugggh phantomjs does not like this | ||
| // forEachChar(evidence, function(item, index) { | ||
| Array.prototype.forEach.call(evidence, function(item, | ||
| index) { | ||
| if (item === '\t') { | ||
| // First col is 1 (not 0) to match error | ||
| // positions | ||
| tabpositions.push(index + 1); | ||
| } | ||
| }); | ||
| linetabpositions[error.line] = tabpositions; | ||
| } | ||
| if (tabpositions.length > 0) { | ||
| var pos = error.character; | ||
| tabpositions.forEach(function(tabposition) { | ||
| if (pos > tabposition) pos -= 1; | ||
| }); | ||
| error.character = pos; | ||
| } | ||
| } | ||
|
|
||
| var start = error.character - 1, end = start + 1; | ||
| if (error.evidence) { | ||
| index = error.evidence.substring(start).search(/.\b/); | ||
| if (index > -1) { | ||
| end += index; | ||
| } | ||
| } | ||
|
|
||
| // Convert to format expected by validation service | ||
| error.description = error.reason;// + "(jshint)"; | ||
| error.start = error.character; | ||
| error.end = end; | ||
| error = cleanup(error); | ||
|
|
||
| if (error) | ||
| output.push({message: error.description, | ||
| severity: error.severity, | ||
| from: CodeMirror.Pos(error.line - 1, start), | ||
| to: CodeMirror.Pos(error.line - 1, end)}); | ||
| } | ||
| } | ||
| } | ||
| })(); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| // Depends on jsonlint.js from https://github.com/zaach/jsonlint | ||
|
|
||
| CodeMirror.jsonValidator = function(text) { | ||
| var found = []; | ||
| jsonlint.parseError = function(str, hash) { | ||
| var loc = hash.loc; | ||
| found.push({from: CodeMirror.Pos(loc.first_line - 1, loc.first_column), | ||
| to: CodeMirror.Pos(loc.last_line - 1, loc.last_column), | ||
| message: str}); | ||
| }; | ||
| try { jsonlint.parse(text); } | ||
| catch(e) {} | ||
| return found; | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| /* The lint marker gutter */ | ||
| .CodeMirror-lint-markers { | ||
| width: 16px; | ||
| } | ||
|
|
||
| .CodeMirror-lint-tooltip { | ||
| background-color: infobackground; | ||
| border: 1px solid black; | ||
| border-radius: 4px 4px 4px 4px; | ||
| color: infotext; | ||
| font-family: monospace; | ||
| font-size: 10pt; | ||
| overflow: hidden; | ||
| padding: 2px 5px; | ||
| position: fixed; | ||
| white-space: pre; | ||
| z-index: 100; | ||
| max-width: 600px; | ||
| opacity: 0; | ||
| transition: opacity .4s; | ||
| -moz-transition: opacity .4s; | ||
| -webkit-transition: opacity .4s; | ||
| -o-transition: opacity .4s; | ||
| -ms-transition: opacity .4s; | ||
| } | ||
|
|
||
| .CodeMirror-lint-span-error, .CodeMirror-lint-span-warning { | ||
| background-position: left bottom; | ||
| background-repeat: repeat-x; | ||
| } | ||
|
|
||
| .CodeMirror-lint-span-error { | ||
| background-image: | ||
| url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==") | ||
| ; | ||
| } | ||
|
|
||
| .CodeMirror-lint-span-warning { | ||
| background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJFhQXEbhTg7YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII="); | ||
| } | ||
|
|
||
| .CodeMirror-lint-marker-error, .CodeMirror-lint-marker-warning { | ||
| background-position: center center; | ||
| background-repeat: no-repeat; | ||
| cursor: pointer; | ||
| display: inline-block; | ||
| height: 16px; | ||
| width: 16px; | ||
| vertical-align: middle; | ||
| position: relative; | ||
| } | ||
|
|
||
| .CodeMirror-lint-message-error, .CodeMirror-lint-message-warning { | ||
| padding-left: 18px; | ||
| background-position: top left; | ||
| background-repeat: no-repeat; | ||
| } | ||
|
|
||
| .CodeMirror-lint-marker-error, .CodeMirror-lint-message-error { | ||
| background-image: url("data:image/gif;base64,R0lGODlhEAAQANUAAPVvcvWHiPVucvRuc+ttcfV6f91KVN5LU99PV/FZY/JhaM4oN84pONE4Rd1ATfJLWutVYPRgbdxpcsgWKMgZKs4lNfE/UvE/U+artcpdSc5uXveimslHPuBhW/eJhfV5efaCgO2CgP+/v+PExP///////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACUALAAAAAAQABAAAAZ+wJJwSCwaScgkySgkjTQZTkYzWhadnE5oE+pwqkSshwQqkzxfa4kkQXxEpA9J9EFI1KQGQQBAigYCBA14ExEWF0gXihETeA0QD3AkD5QQg0NsDnAJmwkOd5gYFSQKpXAFDBhqaxgLBwQBBAapq00YEg0UDRKqTGtKSL7Cw8JBADs="); | ||
| } | ||
|
|
||
| .CodeMirror-lint-marker-warning, .CodeMirror-lint-message-warning { | ||
| background-image: url("data:image/gif;base64,R0lGODlhEAAQANUAAP7bc//egf/ij/7ijv/jl/7kl//mnv7lnv/uwf7CTP7DTf7DT/7IW//Na/7Na//NbP7QdP/dmbltAIJNAF03AMSAJMSCLKqASa2DS6uBSquCSrGHTq6ETbCHT7WKUrKIUcCVXL+UXMOYX8GWXsSZYMiib6+ETbOIUcOXX86uhd3Muf///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACsALAAAAAAQABAAAAZowJVwSCwaj0ihikRSJYcoBEL0XKlGkcjImQQhJBREKFnyICoThKeE/AAW6AXgdPyUAgrLJBEo0YsbAQyDhAEdRRwDDw8OaA4NDQImRBgFEJdglxAEGEQZKQcHBqOkKRpFF6mqq1WtrUEAOw=="); | ||
| } | ||
|
|
||
| .CodeMirror-lint-marker-multiple { | ||
| background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAAXNSR0IArs4c6QAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJEAQvB2JVdrAAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAD1JREFUCNdtjkESADAEAzemf69f66HMqGlOIhYiFRFRtSQBWAY7mzx+EDTL6sSgb1jTk7Q87rxyqe37fXsAa78gLyZnRgEAAAAASUVORK5CYII="); | ||
| background-repeat: no-repeat; | ||
| background-position: right bottom; | ||
| width: 100%; height: 100%; | ||
| } | ||
|
|
||
| /* Styles for the overview ruler | ||
| .annotationOverview { | ||
| cursor: pointer; | ||
| border-radius: 2px; | ||
| left: 2px; | ||
| width: 8px; | ||
| } | ||
| .annotationOverview.error { | ||
| background-color: lightcoral; | ||
| border: 1px solid darkred; | ||
| } | ||
| .annotationOverview.warning { | ||
| background-color: Gold; | ||
| border: 1px solid black; | ||
| } | ||
| .annotationHTML.overlay { | ||
| background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAAXNSR0IArs4c6QAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJEAQvB2JVdrAAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAD1JREFUCNdtjkESADAEAzemf69f66HMqGlOIhYiFRFRtSQBWAY7mzx+EDTL6sSgb1jTk7Q87rxyqe37fXsAa78gLyZnRgEAAAAASUVORK5CYII="); | ||
| background-position: right bottom; | ||
| position: relative; | ||
| top: -16px; | ||
| } | ||
| */ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,182 @@ | ||
| CodeMirror.validate = (function() { | ||
| var GUTTER_ID = "CodeMirror-lint-markers"; | ||
| var SEVERITIES = /^(?:error|warning)$/; | ||
|
|
||
| function showTooltip(e, content) { | ||
| var tt = document.createElement("div"); | ||
| tt.className = "CodeMirror-lint-tooltip"; | ||
| tt.appendChild(content.cloneNode(true)); | ||
| document.body.appendChild(tt); | ||
|
|
||
| function position(e) { | ||
| if (!tt.parentNode) return CodeMirror.off(document, "mousemove", position); | ||
| tt.style.top = (e.clientY - tt.offsetHeight - 5) + "px"; | ||
| tt.style.left = (e.clientX + 5) + "px"; | ||
| } | ||
| CodeMirror.on(document, "mousemove", position); | ||
| position(e); | ||
| tt.style.opacity = 1; | ||
| return tt; | ||
| } | ||
| function rm(elt) { | ||
| if (elt.parentNode) elt.parentNode.removeChild(elt); | ||
| } | ||
| function hideTooltip(tt) { | ||
| if (!tt.parentNode) return; | ||
| if (tt.style.opacity == null) rm(tt); | ||
| tt.style.opacity = 0; | ||
| setTimeout(function() { rm(tt); }, 600); | ||
| } | ||
|
|
||
| function LintState(cm, options, hasGutter) { | ||
| this.marked = []; | ||
| this.options = options; | ||
| this.timeout = null; | ||
| this.hasGutter = hasGutter; | ||
| this.onMouseOver = function(e) { onMouseOver(cm, e); }; | ||
| } | ||
|
|
||
| function parseOptions(options) { | ||
| if (options instanceof Function) return {getAnnotations: options}; | ||
| else if (!options || !options.getAnnotations) throw new Error("Required option 'getAnnotations' missing (lint addon)"); | ||
| return options; | ||
| } | ||
|
|
||
| function clearMarks(cm) { | ||
| var state = cm._lintState; | ||
| if (state.hasGutter) cm.clearGutter(GUTTER_ID); | ||
| for (var i = 0; i < state.marked.length; ++i) | ||
| state.marked[i].clear(); | ||
| state.marked.length = 0; | ||
| } | ||
|
|
||
| function makeMarker(labels, severity, multiple) { | ||
| var marker = document.createElement("div"), inner = marker; | ||
| marker.className = "CodeMirror-lint-marker-" + severity; | ||
| if (multiple) { | ||
| inner = marker.appendChild(document.createElement("div")); | ||
| inner.className = "CodeMirror-lint-marker-multiple"; | ||
| } | ||
|
|
||
| var tooltip; | ||
| CodeMirror.on(inner, "mouseover", function(e) { tooltip = showTooltip(e, labels); }); | ||
| CodeMirror.on(inner, "mouseout", function() { if (tooltip) hideTooltip(tooltip); }); | ||
|
|
||
| return marker; | ||
| } | ||
|
|
||
| function getMaxSeverity(a, b) { | ||
| if (a == "error") return a; | ||
| else return b; | ||
| } | ||
|
|
||
| function groupByLine(annotations) { | ||
| var lines = []; | ||
| for (var i = 0; i < annotations.length; ++i) { | ||
| var ann = annotations[i], line = ann.from.line; | ||
| (lines[line] || (lines[line] = [])).push(ann); | ||
| } | ||
| return lines; | ||
| } | ||
|
|
||
| function annotationTooltip(ann) { | ||
| var severity = ann.severity; | ||
| if (!SEVERITIES.test(severity)) severity = "error"; | ||
| var tip = document.createElement("div"); | ||
| tip.className = "CodeMirror-lint-message-" + severity; | ||
| tip.appendChild(document.createTextNode(ann.message)); | ||
| return tip; | ||
| } | ||
|
|
||
| function startLinting(cm) { | ||
| var state = cm._lintState, options = state.options; | ||
| if (options.async) | ||
| options.getAnnotations(cm, updateLinting, options); | ||
| else | ||
| updateLinting(cm, options.getAnnotations(cm.getValue())); | ||
| } | ||
|
|
||
| function updateLinting(cm, annotationsNotSorted) { | ||
| clearMarks(cm); | ||
| var state = cm._lintState, options = state.options; | ||
|
|
||
| var annotations = groupByLine(annotationsNotSorted); | ||
|
|
||
| for (var line = 0; line < annotations.length; ++line) { | ||
| var anns = annotations[line]; | ||
| if (!anns) continue; | ||
|
|
||
| var maxSeverity = null; | ||
| var tipLabel = state.hasGutter && document.createDocumentFragment(); | ||
|
|
||
| for (var i = 0; i < anns.length; ++i) { | ||
| var ann = anns[i]; | ||
| var severity = ann.severity; | ||
| if (!SEVERITIES.test(severity)) severity = "error"; | ||
| maxSeverity = getMaxSeverity(maxSeverity, severity); | ||
|
|
||
| if (options.formatAnnotation) ann = options.formatAnnotation(ann); | ||
| if (state.hasGutter) tipLabel.appendChild(annotationTooltip(ann)); | ||
|
|
||
| if (ann.to) state.marked.push(cm.markText(ann.from, ann.to, { | ||
| className: "CodeMirror-lint-span-" + severity, | ||
| __annotation: ann | ||
| })); | ||
| } | ||
|
|
||
| if (state.hasGutter) | ||
| cm.setGutterMarker(line, GUTTER_ID, makeMarker(tipLabel, maxSeverity, anns.length > 1)); | ||
| } | ||
| } | ||
|
|
||
| function onChange(cm) { | ||
| var state = cm._lintState; | ||
| clearTimeout(state.timeout); | ||
| state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500); | ||
| } | ||
|
|
||
| function popupSpanTooltip(ann, e) { | ||
| var tooltip = showTooltip(e, annotationTooltip(ann)); | ||
| var target = e.target || e.srcElement; | ||
| CodeMirror.on(target, "mouseout", hide); | ||
| function hide() { | ||
| CodeMirror.off(target, "mouseout", hide); | ||
| hideTooltip(tooltip); | ||
| } | ||
| } | ||
|
|
||
| // When the mouseover fires, the cursor might not actually be over | ||
| // the character itself yet. These pairs of x,y offsets are used to | ||
| // probe a few nearby points when no suitable marked range is found. | ||
| var nearby = [0, 0, 0, 5, 0, -5, 5, 0, -5, 0]; | ||
|
|
||
| function onMouseOver(cm, e) { | ||
| if (!/\bCodeMirror-lint-span-/.test((e.target || e.srcElement).className)) return; | ||
| for (var i = 0; i < nearby.length; i += 2) { | ||
| var spans = cm.findMarksAt(cm.coordsChar({left: e.clientX + nearby[i], | ||
| top: e.clientY + nearby[i + 1]})); | ||
| for (var j = 0; j < spans.length; ++j) { | ||
| var span = spans[j], ann = span.__annotation; | ||
| if (ann) return popupSpanTooltip(ann, e); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| CodeMirror.defineOption("lintWith", false, function(cm, val, old) { | ||
| if (old && old != CodeMirror.Init) { | ||
| clearMarks(cm); | ||
| cm.off("change", onChange); | ||
| CodeMirror.off(cm.getWrapperElement(), "mouseover", cm._lintState.onMouseOver); | ||
| delete cm._lintState; | ||
| } | ||
|
|
||
| if (val) { | ||
| var gutters = cm.getOption("gutters"), hasLintGutter = false; | ||
| for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true; | ||
| var state = cm._lintState = new LintState(cm, parseOptions(val), hasLintGutter); | ||
| cm.on("change", onChange); | ||
| CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver); | ||
| startLinting(cm); | ||
| } | ||
| }); | ||
| })(); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,46 +1,60 @@ | ||
| // Highlighting text that matches the selection | ||
| // | ||
| // Defines an option highlightSelectionMatches, which, when enabled, | ||
| // will style strings that match the selection throughout the | ||
| // document. | ||
| // | ||
| // The option can be set to true to simply enable it, or to a | ||
| // {minChars, style} object to explicitly configure it. minChars is | ||
| // the minimum amount of characters that should be selected for the | ||
| // behavior to occur, and style is the token style to apply to the | ||
| // matches. This will be prefixed by "cm-" to create an actual CSS | ||
| // class name. | ||
|
|
||
| (function() { | ||
| var DEFAULT_MIN_CHARS = 2; | ||
| var DEFAULT_TOKEN_STYLE = "matchhighlight"; | ||
|
|
||
| function State(options) { | ||
| this.minChars = typeof options == "object" && options.minChars || DEFAULT_MIN_CHARS; | ||
| this.style = typeof options == "object" && options.style || DEFAULT_TOKEN_STYLE; | ||
| this.overlay = null; | ||
| } | ||
|
|
||
| CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) { | ||
| var prev = old && old != CodeMirror.Init; | ||
| if (val && !prev) { | ||
| cm._matchHighlightState = new State(val); | ||
| cm.on("cursorActivity", highlightMatches); | ||
| } else if (!val && prev) { | ||
| var over = cm._matchHighlightState.overlay; | ||
| if (over) cm.removeOverlay(over); | ||
| cm._matchHighlightState = null; | ||
| cm.off("cursorActivity", highlightMatches); | ||
| } | ||
| }); | ||
|
|
||
| function highlightMatches(cm) { | ||
| cm.operation(function() { | ||
| var state = cm._matchHighlightState; | ||
| if (state.overlay) { | ||
| cm.removeOverlay(state.overlay); | ||
| state.overlay = null; | ||
| } | ||
|
|
||
| if (!cm.somethingSelected()) return; | ||
| var selection = cm.getSelection().replace(/^\s+|\s+$/g, ""); | ||
| if (selection.length < state.minChars) return; | ||
|
|
||
| cm.addOverlay(state.overlay = makeOverlay(selection, state.style)); | ||
| }); | ||
| } | ||
|
|
||
| function makeOverlay(query, style) { | ||
| return {token: function(stream) { | ||
| if (stream.match(query)) return style; | ||
| stream.next(); | ||
| stream.skipTo(query.charAt(0)) || stream.skipToEnd(); | ||
| }}; | ||
| } | ||
| })(); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| // Because sometimes you need to style the cursor's line. | ||
| // | ||
| // Adds an option 'styleActiveLine' which, when enabled, gives the | ||
| // active line's wrapping <div> the CSS class "CodeMirror-activeline", | ||
| // and gives its background <div> the class "CodeMirror-activeline-background". | ||
|
|
||
| (function() { | ||
| "use strict"; | ||
| var WRAP_CLASS = "CodeMirror-activeline"; | ||
| var BACK_CLASS = "CodeMirror-activeline-background"; | ||
|
|
||
| CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) { | ||
| var prev = old && old != CodeMirror.Init; | ||
| if (val && !prev) { | ||
| updateActiveLine(cm); | ||
| cm.on("cursorActivity", updateActiveLine); | ||
| } else if (!val && prev) { | ||
| cm.off("cursorActivity", updateActiveLine); | ||
| clearActiveLine(cm); | ||
| delete cm._activeLine; | ||
| } | ||
| }); | ||
|
|
||
| function clearActiveLine(cm) { | ||
| if ("_activeLine" in cm) { | ||
| cm.removeLineClass(cm._activeLine, "wrap", WRAP_CLASS); | ||
| cm.removeLineClass(cm._activeLine, "background", BACK_CLASS); | ||
| } | ||
| } | ||
|
|
||
| function updateActiveLine(cm) { | ||
| var line = cm.getLineHandle(cm.getCursor().line); | ||
| if (cm._activeLine == line) return; | ||
| clearActiveLine(cm); | ||
| cm.addLineClass(line, "wrap", WRAP_CLASS); | ||
| cm.addLineClass(line, "background", BACK_CLASS); | ||
| cm._activeLine = line; | ||
| } | ||
| })(); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| // Because sometimes you need to mark the selected *text*. | ||
| // | ||
| // Adds an option 'styleSelectedText' which, when enabled, gives | ||
| // selected text the CSS class "CodeMirror-selectedtext". | ||
|
|
||
| (function() { | ||
| "use strict"; | ||
|
|
||
| CodeMirror.defineOption("styleSelectedText", false, function(cm, val, old) { | ||
| var prev = old && old != CodeMirror.Init; | ||
| if (val && !prev) { | ||
| updateSelectedText(cm); | ||
| cm.on("cursorActivity", updateSelectedText); | ||
| } else if (!val && prev) { | ||
| cm.off("cursorActivity", updateSelectedText); | ||
| clearSelectedText(cm); | ||
| delete cm._selectionMark; | ||
| } | ||
| }); | ||
|
|
||
| function clearSelectedText(cm) { | ||
| if (cm._selectionMark) cm._selectionMark.clear(); | ||
| } | ||
|
|
||
| function updateSelectedText(cm) { | ||
| clearSelectedText(cm); | ||
|
|
||
| if (cm.somethingSelected()) | ||
| cm._selectionMark = cm.markText(cm.getCursor("start"), cm.getCursor("end"), | ||
| {className: "CodeMirror-selectedtext"}); | ||
| else | ||
| cm._selectionMark = null; | ||
| } | ||
| })(); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| <!doctype html> | ||
| <html> | ||
| <head> | ||
| <meta charset="utf-8"> | ||
| <title>CodeMirror: Bi-directional Text Demo</title> | ||
| <link rel="stylesheet" href="../lib/codemirror.css"> | ||
| <script src="../lib/codemirror.js"></script> | ||
| <script src="../mode/xml/xml.js"></script> | ||
| <link rel="stylesheet" href="../doc/docs.css"> | ||
|
|
||
| <style type="text/css"> | ||
| .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;} | ||
| </style> | ||
| </head> | ||
| <body> | ||
| <h1>CodeMirror: Bi-directional Text Demo</h1> | ||
|
|
||
| <form><textarea id="code" name="code"><!-- Piece of the CodeMirror manual, 'translated' into Arabic by | ||
| Google Translate --> | ||
|
|
||
| <dl> | ||
| <dt id=option_value><code>value (string or Doc)</code></dt> | ||
| <dd>قيمة البداية المحرر. يمكن أن تكون سلسلة، أو. كائن مستند.</dd> | ||
| <dt id=option_mode><code>mode (string or object)</code></dt> | ||
| <dd>وضع الاستخدام. عندما لا تعطى، وهذا الافتراضي إلى الطريقة الاولى | ||
| التي تم تحميلها. قد يكون من سلسلة، والتي إما أسماء أو ببساطة هو وضع | ||
| MIME نوع المرتبطة اسطة. بدلا من ذلك، قد يكون من كائن يحتوي على | ||
| خيارات التكوين لواسطة، مع <code>name</code> الخاصية التي وضع أسماء | ||
| (على سبيل المثال <code>{name: "javascript", json: true}</code>). | ||
| صفحات التجريبي لكل وضع تحتوي على معلومات حول ما معلمات تكوين وضع | ||
| يدعمها. يمكنك أن تطلب CodeMirror التي تم تعريفها طرق وأنواع MIME | ||
| الكشف على <code>CodeMirror.modes</code> | ||
| و <code>CodeMirror.mimeModes</code> الكائنات. وضع خرائط الأسماء | ||
| الأولى لمنشئات الخاصة بهم، وخرائط لأنواع MIME 2 المواصفات | ||
| واسطة.</dd> | ||
| <dt id=option_theme><code>theme (string)</code></dt> | ||
| <dd>موضوع لنمط المحرر مع. يجب عليك التأكد من الملف CSS تحديد | ||
| المقابلة <code>.cm-s-[name]</code> يتم تحميل أنماط (انظر | ||
| <a href=../theme/><code>theme</code></a> الدليل في التوزيع). | ||
| الافتراضي هو <code>"default"</code> ، والتي تم تضمينها في | ||
| الألوان <code>codemirror.css</code>. فمن الممكن استخدام فئات متعددة | ||
| في تطبيق السمات مرة واحدة على سبيل المثال <code>"foo bar"</code> | ||
| سيتم تعيين كل من <code>cm-s-foo</code> و <code>cm-s-bar</code> | ||
| الطبقات إلى المحرر.</dd> | ||
| </dl> | ||
| </textarea></form> | ||
|
|
||
| <script> | ||
| var editor = CodeMirror.fromTextArea(document.getElementById("code"), { | ||
| mode: "text/html", | ||
| lineNumbers: true, | ||
| lineWrapping: true | ||
| }); | ||
| </script> | ||
|
|
||
| <p>Demonstration of bi-directional text support. See | ||
| the <a href="http://marijnhaverbeke.nl/blog/cursor-in-bidi-text.html">related | ||
| blog post</a> for more background.</p> | ||
|
|
||
| </body> | ||
| </html> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| <!doctype html> | ||
| <html> | ||
| <head> | ||
| <meta charset="utf-8"> | ||
| <title>CodeMirror: Multiple Buffer & Split View Demo</title> | ||
| <link rel="stylesheet" href="../lib/codemirror.css"> | ||
| <script src="../lib/codemirror.js"></script> | ||
| <script src="../mode/javascript/javascript.js"></script> | ||
| <script src="../mode/css/css.js"></script> | ||
| <link rel="stylesheet" href="../doc/docs.css"> | ||
|
|
||
| <style type="text/css" id=style> | ||
| .CodeMirror {border: 1px solid black; height: 250px;} | ||
| </style> | ||
| </head> | ||
| <body> | ||
| <h1>CodeMirror: Multiple Buffer & Split View Demo</h1> | ||
|
|
||
| <div id=code_top></div> | ||
| <div> | ||
| Select buffer: <select id=buffers_top></select> | ||
| <button onclick="newBuf('top')">New buffer</button> | ||
| </div> | ||
| <div id=code_bot></div> | ||
| <div> | ||
| Select buffer: <select id=buffers_bot></select> | ||
| <button onclick="newBuf('bot')">New buffer</button> | ||
| </div> | ||
|
|
||
| <script id=script> | ||
| var sel_top = document.getElementById("buffers_top"); | ||
| CodeMirror.on(sel_top, "change", function() { | ||
| selectBuffer(ed_top, sel_top.options[sel_top.selectedIndex].value); | ||
| }); | ||
|
|
||
| var sel_bot = document.getElementById("buffers_bot"); | ||
| CodeMirror.on(sel_bot, "change", function() { | ||
| selectBuffer(ed_bot, sel_bot.options[sel_bot.selectedIndex].value); | ||
| }); | ||
|
|
||
| var buffers = {}; | ||
|
|
||
| function openBuffer(name, text, mode) { | ||
| buffers[name] = CodeMirror.Doc(text, mode); | ||
| var opt = document.createElement("option"); | ||
| opt.appendChild(document.createTextNode(name)); | ||
| sel_top.appendChild(opt); | ||
| sel_bot.appendChild(opt.cloneNode(true)); | ||
| } | ||
|
|
||
| function newBuf(where) { | ||
| var name = prompt("Name for the buffer", "*scratch*"); | ||
| if (name == null) return; | ||
| if (buffers.hasOwnProperty(name)) { | ||
| alert("There's already a buffer by that name."); | ||
| return; | ||
| } | ||
| openBuffer(name, "", "javascript"); | ||
| selectBuffer(where == "top" ? ed_top : ed_bot, name); | ||
| var sel = where == "top" ? sel_top : sel_bot; | ||
| sel.value = name; | ||
| } | ||
|
|
||
| function selectBuffer(editor, name) { | ||
| var buf = buffers[name]; | ||
| if (buf.getEditor()) buf = buf.linkedDoc({sharedHist: true}); | ||
| var old = editor.swapDoc(buf); | ||
| var linked = old.iterLinkedDocs(function(doc) {linked = doc;}); | ||
| if (linked) { | ||
| // Make sure the document in buffers is the one the other view is looking at | ||
| for (var name in buffers) if (buffers[name] == old) buffers[name] = linked; | ||
| old.unlinkDoc(linked); | ||
| } | ||
| editor.focus(); | ||
| } | ||
|
|
||
| function nodeContent(id) { | ||
| var node = document.getElementById(id), val = node.textContent || node.innerText; | ||
| val = val.slice(val.match(/^\s*/)[0].length, val.length - val.match(/\s*$/)[0].length) + "\n"; | ||
| return val; | ||
| } | ||
| openBuffer("js", nodeContent("script"), "javascript"); | ||
| openBuffer("css", nodeContent("style"), "css"); | ||
|
|
||
| var ed_top = CodeMirror(document.getElementById("code_top"), {lineNumbers: true}); | ||
| selectBuffer(ed_top, "js"); | ||
| var ed_bot = CodeMirror(document.getElementById("code_bot"), {lineNumbers: true}); | ||
| selectBuffer(ed_bot, "js"); | ||
| </script> | ||
|
|
||
| <p>Demonstration of | ||
| using <a href="../doc/manual.html#linkedDoc">linked documents</a> | ||
| to provide a split view on a document, and | ||
| using <a href="../doc/manual.html#swapDoc"><code>swapDoc</code></a> | ||
| to use a single editor to display multiple documents.</p> | ||
|
|
||
| </body> | ||
| </html> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| <!doctype html> | ||
| <html> | ||
| <head> | ||
| <meta charset="utf-8"> | ||
| <title>CodeMirror: Closebrackets Demo</title> | ||
| <link rel="stylesheet" href="../lib/codemirror.css"> | ||
| <script src="../lib/codemirror.js"></script> | ||
| <script src="../addon/edit/closebrackets.js"></script> | ||
| <script src="../mode/javascript/javascript.js"></script> | ||
| <link rel="stylesheet" href="../doc/docs.css"> | ||
| <style type="text/css"> | ||
| .CodeMirror {border-top: 1px solid #888; border-bottom: 1px solid #888;} | ||
| </style> | ||
| </head> | ||
| <body> | ||
|
|
||
| <h1>CodeMirror: Closebrackets Demo</h1> | ||
|
|
||
| <p>Type a bracket like '[', '(', '{', '"', or ''' | ||
| and <a href="../doc/manual.html#addon_closebrackets">the addon</a> | ||
| will auto-close it. Type the closing variant when directly in | ||
| front of a matching character and it will overwrite it.</p> | ||
|
|
||
| <form><textarea id="code" name="code">(function() { | ||
| var DEFAULT_BRACKETS = "()[]{}''\"\""; | ||
|
|
||
| CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) { | ||
| var wasOn = old && old != CodeMirror.Init; | ||
| if (val && !wasOn) | ||
| cm.addKeyMap(buildKeymap(typeof val == "string" ? val : DEFAULT_BRACKETS)); | ||
| else if (!val && wasOn) | ||
| cm.removeKeyMap("autoCloseBrackets"); | ||
| }); | ||
|
|
||
| function buildKeymap(pairs) { | ||
| var map = {name : "autoCloseBrackets"}; | ||
| for (var i = 0; i < pairs.length; i += 2) (function(left, right) { | ||
| function maybeOverwrite(cm) { | ||
| var cur = cm.getCursor(), ahead = cm.getRange(cur, CodeMirror.Pos(cur.line, cur.ch + 1)); | ||
| if (ahead != right) return CodeMirror.Pass; | ||
| else cm.execCommand("goCharRight"); | ||
| } | ||
| map["'" + left + "'"] = function(cm) { | ||
| if (left == right && maybeOverwrite(cm) != CodeMirror.Pass) return; | ||
| var cur = cm.getCursor(), ahead = CodeMirror.Pos(cur.line, cur.ch + 1); | ||
| cm.replaceSelection(left + right, {head: ahead, anchor: ahead}); | ||
| }; | ||
| if (left != right) map["'" + right + "'"] = maybeOverwrite; | ||
| })(pairs.charAt(i), pairs.charAt(i + 1)); | ||
| return map; | ||
| } | ||
| })(); | ||
| </textarea></form> | ||
|
|
||
| <script type="text/javascript"> | ||
| var editor = CodeMirror.fromTextArea(document.getElementById("code"), {autoCloseBrackets: true}); | ||
| </script> | ||
| </body> | ||
| </html> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| <!doctype html> | ||
| <html> | ||
| <head> | ||
| <meta charset="utf-8"> | ||
| <title>CodeMirror: Linter Demo</title> | ||
| <link rel="stylesheet" href="../lib/codemirror.css"> | ||
| <script src="../lib/codemirror.js"></script> | ||
| <script src="../mode/javascript/javascript.js"></script> | ||
| <script src="http://ajax.aspnetcdn.com/ajax/jshint/r07/jshint.js"></script> | ||
| <script src="https://raw.github.com/zaach/jsonlint/79b553fb65c192add9066da64043458981b3972b/lib/jsonlint.js"></script> | ||
| <link rel="stylesheet" href="../doc/docs.css"> | ||
| <link rel="stylesheet" href="../addon/lint/lint.css"> | ||
| <script src="../addon/lint/lint.js"></script> | ||
| <script src="../addon/lint/javascript-lint.js"></script> | ||
| <script src="../addon/lint/json-lint.js"></script> | ||
|
|
||
| <style type="text/css"> | ||
| .CodeMirror {border: 1px solid black;} | ||
| </style> | ||
| </head> | ||
| <body> | ||
| <h1>CodeMirror: Linter Demo</h1> | ||
|
|
||
| <p><textarea id="code-js">var widgets = [] | ||
| function updateHints() { | ||
| editor.operation(function(){ | ||
| for (var i = 0; i < widgets.length; ++i) | ||
| editor.removeLineWidget(widgets[i]); | ||
| widgets.length = 0; | ||
|
|
||
| JSHINT(editor.getValue()); | ||
| for (var i = 0; i < JSHINT.errors.length; ++i) { | ||
| var err = JSHINT.errors[i]; | ||
| if (!err) continue; | ||
| var msg = document.createElement("div"); | ||
| var icon = msg.appendChild(document.createElement("span")); | ||
| icon.innerHTML = "!!"; | ||
| icon.className = "lint-error-icon"; | ||
| msg.appendChild(document.createTextNode(err.reason)); | ||
| msg.className = "lint-error"; | ||
| widgets.push(editor.addLineWidget(err.line - 1, msg, {coverGutter: false, noHScroll: true})); | ||
| } | ||
| }); | ||
| var info = editor.getScrollInfo(); | ||
| var after = editor.charCoords({line: editor.getCursor().line + 1, ch: 0}, "local").top; | ||
| if (info.top + info.clientHeight < after) | ||
| editor.scrollTo(null, after - info.clientHeight + 3); | ||
| } | ||
| </textarea></p> | ||
|
|
||
| <p><textarea id="code-json">[ | ||
| { | ||
| _id: "post 1", | ||
| "author": "Bob", | ||
| "content": "...", | ||
| "page_views": 5 | ||
| }, | ||
| { | ||
| "_id": "post 2", | ||
| "author": "Bob", | ||
| "content": "...", | ||
| "page_views": 9 | ||
| }, | ||
| { | ||
| "_id": "post 3", | ||
| "author": "Bob", | ||
| "content": "...", | ||
| "page_views": 8 | ||
| } | ||
| ] | ||
| </textarea></p> | ||
|
|
||
| <script> | ||
| var editor = CodeMirror.fromTextArea(document.getElementById("code-js"), { | ||
| lineNumbers: true, | ||
| mode: "javascript", | ||
| gutters: ["CodeMirror-lint-markers"], | ||
| lintWith: CodeMirror.javascriptValidator | ||
| }); | ||
|
|
||
| var editor_json = CodeMirror.fromTextArea(document.getElementById("code-json"), { | ||
| lineNumbers: true, | ||
| mode: "application/json", | ||
| gutters: ["CodeMirror-lint-markers"], | ||
| lintWith: CodeMirror.jsonValidator | ||
| }); | ||
| </script> | ||
|
|
||
| </body> | ||
| </html> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| <!doctype html> | ||
| <html> | ||
| <head> | ||
| <meta charset="utf-8"> | ||
| <title>CodeMirror: Match Highlighter Demo</title> | ||
| <link rel="stylesheet" href="../lib/codemirror.css"> | ||
| <script src="../lib/codemirror.js"></script> | ||
| <script src="../addon/search/searchcursor.js"></script> | ||
| <script src="../addon/selection/mark-selection.js"></script> | ||
| <link rel="stylesheet" href="../doc/docs.css"> | ||
|
|
||
| <style type="text/css"> | ||
| .CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;} | ||
| .CodeMirror-selected { background-color: blue !important; } | ||
| .CodeMirror-selectedtext { color: white; } | ||
| </style> | ||
| </head> | ||
| <body> | ||
| <h1>CodeMirror: Mark Selection Demo</h1> | ||
|
|
||
| <form><textarea id="code" name="code">Select something from here. | ||
| You'll see that the selection's foreground color changes to white! | ||
| Since, by default, CodeMirror only puts an independent "marker" layer | ||
| behind the text, you'll need something like this to change its colour.</textarea></form> | ||
|
|
||
| <script> | ||
| var editor = CodeMirror.fromTextArea(document.getElementById("code"), { | ||
| lineNumbers: true, | ||
| styleSelectedText: true | ||
| }); | ||
| </script> | ||
|
|
||
| <p>Simple addon to easily mark (and style) selected text.</p> | ||
|
|
||
| </body> | ||
| </html> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,7 +21,7 @@ h2 { | |
| } | ||
|
|
||
| h3 { | ||
| font-size: 1.1em; | ||
| font-weight: bold; | ||
| margin: .4em 0; | ||
| } | ||
|
|
||