Changeset 4948
- Timestamp:
- 10/30/09 10:04:57 (4 weeks ago)
- Location:
- branches/greyhound/mt-static/codemirror/js
- Files:
-
- 4 modified
Legend:
- Unmodified
- Added
- Removed
-
branches/greyhound/mt-static/codemirror/js/codemirror.js
r4932 r4948 27 27 // their meaning. 28 28 setDefaults(CodeMirrorConfig, { 29 lang: "en",30 29 stylesheet: "", 31 30 path: "", … … 35 34 passDelay: 200, 36 35 passTime: 50, 36 lineNumberDelay: 200, 37 lineNumberTime: 50, 37 38 continuousScanning: false, 38 39 saveFunction: null, … … 43 44 textWrapping: true, 44 45 readOnly: false, 45 width: " 100%",46 width: "", 46 47 height: "300px", 47 48 autoMatchParens: false, … … 72 73 } 73 74 74 function activateLineNumbers(frame, nums) {75 var win = frame.contentWindow, doc = win.document,76 scroller = nums.firstChild;77 78 var nextNum = 1, barWidth = null;79 function sizeBar() {80 for (var root = frame; root.parentNode; root = root.parentNode);81 if (!nums.parentNode || root != document || !win.Editor) {82 // Clear event handlers (their nodes might already be collected, so try/catch)83 try{onScroll();}catch(e){}84 try{onResize();}catch(e){}85 clearInterval(sizeInterval);86 return;87 }88 89 if (nums.offsetWidth != barWidth) {90 barWidth = nums.offsetWidth;91 nums.style.left = "-" + (frame.parentNode.style.marginLeft = barWidth + "px");92 }93 }94 function update() {95 var diff = 20 + Math.max(doc.body.offsetHeight, frame.offsetHeight) - scroller.offsetHeight;96 for (var n = Math.ceil(diff / 10); n > 0; n--) {97 var div = document.createElement("DIV");98 div.appendChild(document.createTextNode(nextNum++));99 scroller.appendChild(div);100 }101 nums.scrollTop = doc.body.scrollTop || doc.documentElement.scrollTop || 0;102 }103 var onScroll = win.addEventHandler(win, "scroll", update, true),104 onResize = win.addEventHandler(win, "resize", update, true),105 sizeInterval = setInterval(sizeBar, 500);106 sizeBar();107 update();108 }109 110 75 function CodeMirror(place, options) { 111 76 // Backward compatibility for deprecated options. … … 122 87 frame.src = "javascript:false;"; 123 88 frame.style.border = "0"; 124 frame.style.width = options.width;125 frame.style.height = options.height;89 frame.style.width = '100%'; 90 frame.style.height = '100%'; 126 91 // display: block occasionally suppresses some Firefox bugs, so we 127 92 // always add it, redundant as it sounds. … … 131 96 div.style.position = "relative"; 132 97 div.className = "CodeMirror-wrapping"; 98 div.style.width = options.width; 99 div.style.height = options.height; 100 133 101 if (place.appendChild) place.appendChild(div); 134 102 else place(div); … … 146 114 options.stylesheet = [options.stylesheet]; 147 115 148 var html = ["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\"><html lang="+options.lang+"><head>"];116 var html = ["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\"><html><head>"]; 149 117 // Hack to work around a bunch of IE8-specific problems. 150 118 html.push("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=EmulateIE7\"/>"); … … 167 135 init: function() { 168 136 if (this.options.initCallback) this.options.initCallback(this); 169 if (this. lineNumbers) activateLineNumbers(this.frame, this.lineNumbers);137 if (this.options.lineNumbers) this.activateLineNumbers(); 170 138 if (this.options.reindentOnLoad) this.reindent(); 171 139 }, … … 208 176 setParser: function(name) {this.editor.setParser(name);}, 209 177 setSpellcheck: function(on) {this.win.document.body.spellcheck = on;}, 210 setTextWrapping: function(on) {this.win.document.body.style.whiteSpace = on ? "" : "nowrap";}, 178 setTextWrapping: function(on) { 179 if (on == this.options.textWrapping) return; 180 this.win.document.body.style.whiteSpace = on ? "" : "nowrap"; 181 this.options.textWrapping = on; 182 if (this.lineNumbers) { 183 this.setLineNumbers(false); 184 this.setLineNumbers(true); 185 } 186 }, 211 187 setIndentUnit: function(unit) {this.win.indentUnit = unit;}, 212 188 setUndoDepth: function(depth) {this.editor.history.maxDepth = depth;}, … … 215 191 if (on && !this.lineNumbers) { 216 192 this.lineNumbers = addLineNumberDiv(this.wrapping); 217 activateLineNumbers(this.frame, this.lineNumbers);193 this.activateLineNumbers(); 218 194 } 219 195 else if (!on && this.lineNumbers) { … … 258 234 currentLine: function() { 259 235 return this.lineNumber(this.cursorPosition().line); 236 }, 237 238 activateLineNumbers: function() { 239 var frame = this.frame, win = frame.contentWindow, doc = win.document, body = doc.body, 240 nums = this.lineNumbers, scroller = nums.firstChild, self = this; 241 var barWidth = null; 242 243 function sizeBar() { 244 for (var root = frame; root.parentNode; root = root.parentNode); 245 if (!nums.parentNode || root != document || !win.Editor) { 246 // Clear event handlers (their nodes might already be collected, so try/catch) 247 try{clear();}catch(e){} 248 clearInterval(sizeInterval); 249 return; 250 } 251 252 if (nums.offsetWidth != barWidth) { 253 barWidth = nums.offsetWidth; 254 nums.style.left = "-" + (frame.parentNode.style.marginLeft = barWidth + "px"); 255 } 256 } 257 function doScroll() { 258 nums.scrollTop = body.scrollTop || doc.documentElement.scrollTop || 0; 259 } 260 // Cleanup function, registered by nonWrapping and wrapping. 261 var clear = function(){}; 262 sizeBar(); 263 sizeInterval = setInterval(sizeBar, 500); 264 265 function nonWrapping() { 266 var nextNum = 1; 267 function update() { 268 var target = 50 + Math.max(body.offsetHeight, frame.offsetHeight); 269 while (scroller.offsetHeight < target) { 270 scroller.appendChild(document.createElement("DIV")); 271 scroller.lastChild.innerHTML = nextNum++; 272 } 273 doScroll(); 274 } 275 var onScroll = win.addEventHandler(win, "scroll", update, true), 276 onResize = win.addEventHandler(win, "resize", update, true); 277 clear = function(){onScroll(); onResize();}; 278 } 279 function wrapping() { 280 var node, lineNum, next, pos; 281 282 function addNum(n) { 283 if (!lineNum) lineNum = scroller.appendChild(document.createElement("DIV")); 284 lineNum.innerHTML = n; 285 pos = lineNum.offsetHeight + lineNum.offsetTop; 286 lineNum = lineNum.nextSibling; 287 } 288 function work() { 289 if (!scroller.parentNode || scroller.parentNode != self.lineNumbers) return; 290 291 var endTime = new Date().getTime() + self.options.lineNumberTime; 292 while (node) { 293 addNum(next++); 294 for (; node && !win.isBR(node); node = node.nextSibling) { 295 var bott = node.offsetTop + node.offsetHeight; 296 while (bott - 3 > pos) addNum(" "); 297 } 298 if (node) node = node.nextSibling; 299 if (new Date().getTime() > endTime) { 300 pending = setTimeout(work, self.options.lineNumberDelay); 301 return; 302 } 303 } 304 // While there are un-processed number DIVs, or the scroller is smaller than the frame... 305 var target = 50 + Math.max(body.offsetHeight, frame.offsetHeight); 306 while (lineNum || scroller.offsetHeight < target) addNum(next++); 307 doScroll(); 308 } 309 function start() { 310 doScroll(); 311 node = body.firstChild; 312 lineNum = scroller.firstChild; 313 pos = 0; 314 next = 1; 315 work(); 316 } 317 318 start(); 319 var pending = null; 320 function update() { 321 if (pending) clearTimeout(pending); 322 pending = setTimeout(start, self.options.lineNumberDelay); 323 } 324 self.updateNumbers = update; 325 var onScroll = win.addEventHandler(win, "scroll", doScroll, true), 326 onResize = win.addEventHandler(win, "resize", update, true); 327 clear = function(){ 328 if (pending) clearTimeout(pending); 329 if (self.updateNumbers == update) self.updateNumbers == null; 330 onScroll(); 331 onResize(); 332 }; 333 } 334 (this.options.textWrapping ? wrapping : nonWrapping)(); 260 335 } 261 336 }; -
branches/greyhound/mt-static/codemirror/js/editor.js
r4932 r4948 125 125 var point = null; 126 126 127 // This an Opera-specific hack -- always insert an empty span 128 // between two BRs, because Opera's cursor code gets terribly 129 // confused when the cursor is between two BRs. 130 var afterBR = true; 131 127 132 // Insert a normalized node at the current point. If it is a text 128 133 // node, wrap it in a <span>, and give that span a currentText … … 137 142 part = makePartSpan(part, owner); 138 143 text = part.currentText; 144 afterBR = false; 145 } 146 else { 147 if (afterBR && window.opera) 148 point(makePartSpan(""), owner); 149 afterBR = true; 139 150 } 140 151 part.dirty = true; … … 174 185 if (partNode(node)){ 175 186 nodeQueue.push(node); 187 afterBR = false; 176 188 return yield(node.currentText, c); 177 189 } 178 190 else if (isBR(node)) { 191 if (afterBR && window.opera) 192 node.parentNode.insertBefore(makePartSpan("", owner), node); 179 193 nodeQueue.push(node); 194 afterBR = true; 180 195 return yield("\n", c); 181 196 } … … 354 369 var container = this.container = this.doc.body; 355 370 this.win = window; 356 this.history = new History(container, options.undoDepth, options.undoDelay, 357 this, options.onChange); 371 this.history = new History(container, options.undoDepth, options.undoDelay, this); 358 372 var self = this; 359 373 … … 369 383 if (options.content) 370 384 this.importCode(options.content); 385 this.history.onChange = options.onChange; 371 386 372 387 if (!options.readOnly) { … … 419 434 catch(e) {} 420 435 if (text !== null) { 436 event.stop(); 421 437 self.replaceSelection(text); 422 438 select.scrollToCursor(this.container); 423 event.stop();424 439 } 425 440 }); … … 431 446 container.style.whiteSpace = "nowrap"; 432 447 } 433 }448 } 434 449 435 450 function isSafeKey(code) { … … 764 779 keyUp: function(event) { 765 780 this.cursorActivity(isSafeKey(event.keyCode)); 781 if (event.keyCode == 13) 782 this.scheduleHighlight(); 766 783 }, 767 784 … … 835 852 if (this.highlight(pos, endOfLine(to, this.container), true, 20) === false) 836 853 return false; 837 select.selectMarked();838 854 return true; 839 855 }, … … 1010 1026 this.selectionSnapshot = select.getBookmark(this.container); 1011 1027 } 1028 if (window.frameElement && window.frameElement.CodeMirror.updateNumbers) { 1029 window.frameElement.CodeMirror.updateNumbers(); 1030 } 1012 1031 1013 1032 var activity = this.options.cursorActivity; … … 1018 1037 if (activity) activity(cursor); 1019 1038 if (!safe) { 1020 // this.scheduleHighlight();1021 1039 this.addDirtyNode(cursor); 1022 1040 } … … 1066 1084 // longer in the document, it should not be returned. 1067 1085 while (found && found.parentNode != this.container) 1068 found = found.parentNode 1086 found = found.parentNode; 1069 1087 if (found && (found.dirty || found.nodeType == 3)) 1070 1088 return found; … … 1200 1218 stream = stringStream(traversal), 1201 1219 parsed = from ? from.parserFromHere(stream) : Editor.Parser.make(stream); 1220 1221 function surroundedByBRs(node) { 1222 return (node.previousSibling == null || isBR(node.previousSibling)) && 1223 (node.nextSibling == null || isBR(node.nextSibling)); 1224 } 1202 1225 1203 1226 // parts is an interface to make it possible to 'delay' fetching … … 1232 1255 // insertNewlineAtCursor). 1233 1256 while (part && isSpan(part) && part.currentText == "") { 1234 var old = part; 1235 this.remove(); 1236 part = this.get(); 1237 // Adjust selection information, if any. See select.js for details. 1238 select.snapshotMove(old.firstChild, part && (part.firstChild || part), 0); 1257 // Leave empty nodes that are alone on a line alone in 1258 // Opera, since that browsers doesn't deal well with 1259 // having 2 BRs in a row. 1260 if (window.opera && surroundedByBRs(part)) { 1261 this.next(); 1262 part = this.get(); 1263 } 1264 else { 1265 var old = part; 1266 this.remove(); 1267 part = this.get(); 1268 // Adjust selection information, if any. See select.js for details. 1269 select.snapshotMove(old.firstChild, part && (part.firstChild || part), 0); 1270 } 1239 1271 } 1272 1240 1273 return part; 1241 1274 } -
branches/greyhound/mt-static/codemirror/js/select.js
r4932 r4948 67 67 } 68 68 if (screen_y < 0 || atEnd || screen_y > (win.innerHeight || html.clientHeight || 0) - 50) { 69 scroll_y = atEnd ? 1e 10: y;69 scroll_y = atEnd ? 1e6 : y; 70 70 scroll = true; 71 71 } -
branches/greyhound/mt-static/codemirror/js/undo.js
r4932 r4948 27 27 // unfortunately, the 'parent' window -- a window that is not in 28 28 // designMode, and on which setTimeout works in every browser. 29 function History(container, maxDepth, commitDelay, editor , onChange) {29 function History(container, maxDepth, commitDelay, editor) { 30 30 this.container = container; 31 31 this.maxDepth = maxDepth; this.commitDelay = commitDelay; 32 32 this.editor = editor; this.parent = editor.parent; 33 this.onChange = onChange;34 33 // This line object represents the initial, empty editor. 35 34 var initial = {text: "", from: null, to: null};
