maglev-webtools 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. data/LICENSE.txt +25 -0
  2. data/README.rdoc +121 -0
  3. data/bin/webtools +15 -0
  4. data/lib/web_tools/#debugger.rb# +212 -0
  5. data/lib/web_tools/browser.rb +45 -0
  6. data/lib/web_tools/debugger.rb +219 -0
  7. data/lib/web_tools/info.rb +29 -0
  8. data/lib/web_tools/middleware/debugger.rb +118 -0
  9. data/lib/web_tools/support/app_model.rb +117 -0
  10. data/lib/web_tools/support/code_browser.rb +109 -0
  11. data/lib/web_tools/support/ruby.rb +132 -0
  12. data/lib/web_tools/support/service_helper.rb +22 -0
  13. data/lib/web_tools/support/smalltalk_extensions.rb +65 -0
  14. data/lib/web_tools/support/smalltalk_tools.rb +16 -0
  15. data/lib/web_tools/ui.rb +67 -0
  16. data/lib/web_tools.rb +10 -0
  17. data/public/images/favicon.ico +0 -0
  18. data/public/javascript/CodeMirror/LICENSE +23 -0
  19. data/public/javascript/CodeMirror/css/Smalltalk.css +34 -0
  20. data/public/javascript/CodeMirror/js/codemirror.js +582 -0
  21. data/public/javascript/CodeMirror/js/editor.js +1671 -0
  22. data/public/javascript/CodeMirror/js/highlight.js +68 -0
  23. data/public/javascript/CodeMirror/js/parseSmalltalk.js +126 -0
  24. data/public/javascript/CodeMirror/js/parsedummy.js +32 -0
  25. data/public/javascript/CodeMirror/js/select.js +699 -0
  26. data/public/javascript/CodeMirror/js/stringstream.js +159 -0
  27. data/public/javascript/CodeMirror/js/tokenize.js +57 -0
  28. data/public/javascript/CodeMirror/js/undo.js +413 -0
  29. data/public/javascript/CodeMirror/js/util.js +133 -0
  30. data/public/javascript/CodeMirror/testSmalltalkParser.html +116 -0
  31. data/public/javascript/ace/ace-uncompressed.js +17299 -0
  32. data/public/javascript/ace/ace.js +1 -0
  33. data/public/javascript/ace/keybinding-emacs.js +1 -0
  34. data/public/javascript/ace/keybinding-vim.js +1 -0
  35. data/public/javascript/ace/mode-c_cpp.js +1 -0
  36. data/public/javascript/ace/mode-clojure.js +1 -0
  37. data/public/javascript/ace/mode-coffee.js +1 -0
  38. data/public/javascript/ace/mode-csharp.js +1 -0
  39. data/public/javascript/ace/mode-css.js +1 -0
  40. data/public/javascript/ace/mode-groovy.js +1 -0
  41. data/public/javascript/ace/mode-html.js +1 -0
  42. data/public/javascript/ace/mode-java.js +1 -0
  43. data/public/javascript/ace/mode-javascript.js +1 -0
  44. data/public/javascript/ace/mode-json.js +1 -0
  45. data/public/javascript/ace/mode-lua.js +1 -0
  46. data/public/javascript/ace/mode-markdown.js +1 -0
  47. data/public/javascript/ace/mode-ocaml.js +1 -0
  48. data/public/javascript/ace/mode-perl.js +1 -0
  49. data/public/javascript/ace/mode-php.js +1 -0
  50. data/public/javascript/ace/mode-python.js +1 -0
  51. data/public/javascript/ace/mode-ruby.js +1 -0
  52. data/public/javascript/ace/mode-scad.js +1 -0
  53. data/public/javascript/ace/mode-scala.js +1 -0
  54. data/public/javascript/ace/mode-scss.js +1 -0
  55. data/public/javascript/ace/mode-svg.js +1 -0
  56. data/public/javascript/ace/mode-textile.js +1 -0
  57. data/public/javascript/ace/mode-xml.js +1 -0
  58. data/public/javascript/ace/theme-clouds.js +1 -0
  59. data/public/javascript/ace/theme-clouds_midnight.js +1 -0
  60. data/public/javascript/ace/theme-cobalt.js +1 -0
  61. data/public/javascript/ace/theme-crimson_editor.js +1 -0
  62. data/public/javascript/ace/theme-dawn.js +1 -0
  63. data/public/javascript/ace/theme-eclipse.js +1 -0
  64. data/public/javascript/ace/theme-idle_fingers.js +1 -0
  65. data/public/javascript/ace/theme-kr_theme.js +1 -0
  66. data/public/javascript/ace/theme-merbivore.js +1 -0
  67. data/public/javascript/ace/theme-merbivore_soft.js +1 -0
  68. data/public/javascript/ace/theme-mono_industrial.js +1 -0
  69. data/public/javascript/ace/theme-monokai.js +1 -0
  70. data/public/javascript/ace/theme-pastel_on_dark.js +1 -0
  71. data/public/javascript/ace/theme-solarized_dark.js +1 -0
  72. data/public/javascript/ace/theme-solarized_light.js +1 -0
  73. data/public/javascript/ace/theme-textmate.js +1 -0
  74. data/public/javascript/ace/theme-twilight.js +1 -0
  75. data/public/javascript/ace/theme-vibrant_ink.js +1 -0
  76. data/public/javascript/ace/worker-coffee.js +1 -0
  77. data/public/javascript/ace/worker-css.js +1 -0
  78. data/public/javascript/ace/worker-javascript.js +1 -0
  79. data/public/javascript/webtools/#debugger.coffee# +253 -0
  80. data/public/javascript/webtools/browser.js +260 -0
  81. data/public/javascript/webtools/debugger.coffee +286 -0
  82. data/public/javascript/webtools/debugger.js +366 -0
  83. data/public/javascript/webtools/sessions.coffee +17 -0
  84. data/public/javascript/webtools/sessions.js +27 -0
  85. data/public/javascript/webtools/version.coffee +14 -0
  86. data/public/javascript/webtools/version.js +20 -0
  87. data/public/stylesheets/base/images/ui-anim_basic_16x16.gif +0 -0
  88. data/public/stylesheets/base/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  89. data/public/stylesheets/base/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  90. data/public/stylesheets/base/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  91. data/public/stylesheets/base/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  92. data/public/stylesheets/base/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  93. data/public/stylesheets/base/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  94. data/public/stylesheets/base/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  95. data/public/stylesheets/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  96. data/public/stylesheets/base/images/ui-icons_222222_256x240.png +0 -0
  97. data/public/stylesheets/base/images/ui-icons_2e83ff_256x240.png +0 -0
  98. data/public/stylesheets/base/images/ui-icons_454545_256x240.png +0 -0
  99. data/public/stylesheets/base/images/ui-icons_888888_256x240.png +0 -0
  100. data/public/stylesheets/base/images/ui-icons_cd0a0a_256x240.png +0 -0
  101. data/public/stylesheets/base/jquery.ui.accordion.css +12 -0
  102. data/public/stylesheets/base/jquery.ui.all.css +2 -0
  103. data/public/stylesheets/base/jquery.ui.autocomplete.css +39 -0
  104. data/public/stylesheets/base/jquery.ui.base.css +11 -0
  105. data/public/stylesheets/base/jquery.ui.button.css +35 -0
  106. data/public/stylesheets/base/jquery.ui.core.css +37 -0
  107. data/public/stylesheets/base/jquery.ui.datepicker.css +61 -0
  108. data/public/stylesheets/base/jquery.ui.dialog.css +13 -0
  109. data/public/stylesheets/base/jquery.ui.progressbar.css +4 -0
  110. data/public/stylesheets/base/jquery.ui.resizable.css +13 -0
  111. data/public/stylesheets/base/jquery.ui.selectable.css +3 -0
  112. data/public/stylesheets/base/jquery.ui.slider.css +17 -0
  113. data/public/stylesheets/base/jquery.ui.tabs.css +11 -0
  114. data/public/stylesheets/base/jquery.ui.theme.css +247 -0
  115. data/public/stylesheets/jquery.contextMenu.css +62 -0
  116. data/public/stylesheets/reset.css +18 -0
  117. data/public/stylesheets/webtools.css +53 -0
  118. data/public/test.html +47 -0
  119. data/views/browser.rhtml +63 -0
  120. data/views/debugger.rhtml +59 -0
  121. data/views/index.rhtml +8 -0
  122. data/views/layout.rhtml +24 -0
  123. data/views/sessions.rhtml +12 -0
  124. data/views/version.rhtml +10 -0
  125. metadata +316 -0
@@ -0,0 +1,34 @@
1
+ html {
2
+ cursor: text;
3
+ }
4
+
5
+ .editbox {
6
+ margin: .4em;
7
+ padding: 0;
8
+ font-family: monospace;
9
+ font-size: 10pt;
10
+ color: black;
11
+ }
12
+
13
+ .editbox p {
14
+ margin: 0;
15
+ }
16
+
17
+ span.st-character { color: rgb(128,0,128); }
18
+ span.st-comment { color: rgb(0,200,0); font-style: italic; }
19
+ span.st-string { color: rgb(128,0,128); }
20
+ span.st-symbol { color: rgb(128,0,128); }
21
+ span.st-boolean { color: rgb(0,0,128); }
22
+ span.st-self { color: rgb(0,0,128); }
23
+ span.st-super { color: rgb(0,0,128); }
24
+ span.st-nil { color: rgb(0,0,128); }
25
+ span.st-return { color: rgb(160,0,0); }
26
+ span.st-keyword { color: rgb(0,0,255); }
27
+ span.st-global { font-weight: bold; }
28
+
29
+ /*
30
+ number: 0 127 127
31
+ special selector: 0 0 127
32
+ brace highlight: 255 128 0
33
+ brace mismatch: 255 0 0
34
+ */
@@ -0,0 +1,582 @@
1
+ /* CodeMirror main module (http://codemirror.net/)
2
+ *
3
+ * Implements the CodeMirror constructor and prototype, which take care
4
+ * of initializing the editor frame, and providing the outside interface.
5
+ */
6
+
7
+ // The CodeMirrorConfig object is used to specify a default
8
+ // configuration. If you specify such an object before loading this
9
+ // file, the values you put into it will override the defaults given
10
+ // below. You can also assign to it after loading.
11
+ var CodeMirrorConfig = window.CodeMirrorConfig || {};
12
+
13
+ var CodeMirror = (function(){
14
+ function setDefaults(object, defaults) {
15
+ for (var option in defaults) {
16
+ if (!object.hasOwnProperty(option))
17
+ object[option] = defaults[option];
18
+ }
19
+ }
20
+ function forEach(array, action) {
21
+ for (var i = 0; i < array.length; i++)
22
+ action(array[i]);
23
+ }
24
+ function createHTMLElement(el) {
25
+ if (document.createElementNS && document.documentElement.namespaceURI !== null)
26
+ return document.createElementNS("http://www.w3.org/1999/xhtml", el)
27
+ else
28
+ return document.createElement(el)
29
+ }
30
+
31
+ // These default options can be overridden by passing a set of
32
+ // options to a specific CodeMirror constructor. See manual.html for
33
+ // their meaning.
34
+ setDefaults(CodeMirrorConfig, {
35
+ stylesheet: [],
36
+ path: "",
37
+ parserfile: [],
38
+ basefiles: ["util.js", "stringstream.js", "select.js", "undo.js", "editor.js", "tokenize.js"],
39
+ iframeClass: null,
40
+ passDelay: 200,
41
+ passTime: 50,
42
+ lineNumberDelay: 200,
43
+ lineNumberTime: 50,
44
+ continuousScanning: false,
45
+ saveFunction: null,
46
+ onLoad: null,
47
+ onChange: null,
48
+ undoDepth: 50,
49
+ undoDelay: 800,
50
+ disableSpellcheck: true,
51
+ textWrapping: true,
52
+ readOnly: false,
53
+ width: "",
54
+ height: "300px",
55
+ minHeight: 100,
56
+ autoMatchParens: false,
57
+ markParen: null,
58
+ unmarkParen: null,
59
+ parserConfig: null,
60
+ tabMode: "indent", // or "spaces", "default", "shift"
61
+ enterMode: "indent", // or "keep", "flat"
62
+ electricChars: true,
63
+ reindentOnLoad: false,
64
+ activeTokens: null,
65
+ onCursorActivity: null,
66
+ lineNumbers: false,
67
+ firstLineNumber: 1,
68
+ onLineNumberClick: null,
69
+ indentUnit: 2,
70
+ domain: null,
71
+ noScriptCaching: false,
72
+ incrementalLoading: false
73
+ });
74
+
75
+ function addLineNumberDiv(container, firstNum) {
76
+ var nums = createHTMLElement("div"),
77
+ scroller = createHTMLElement("div");
78
+ nums.style.position = "absolute";
79
+ nums.style.height = "100%";
80
+ if (nums.style.setExpression) {
81
+ try {nums.style.setExpression("height", "this.previousSibling.offsetHeight + 'px'");}
82
+ catch(e) {} // Seems to throw 'Not Implemented' on some IE8 versions
83
+ }
84
+ nums.style.top = "0px";
85
+ nums.style.left = "0px";
86
+ nums.style.overflow = "hidden";
87
+ container.appendChild(nums);
88
+ scroller.className = "CodeMirror-line-numbers";
89
+ nums.appendChild(scroller);
90
+ scroller.innerHTML = "<div>" + firstNum + "</div>";
91
+ return nums;
92
+ }
93
+
94
+ function frameHTML(options) {
95
+ if (typeof options.parserfile == "string")
96
+ options.parserfile = [options.parserfile];
97
+ if (typeof options.basefiles == "string")
98
+ options.basefiles = [options.basefiles];
99
+ if (typeof options.stylesheet == "string")
100
+ options.stylesheet = [options.stylesheet];
101
+
102
+ var sp = " spellcheck=\"" + (options.disableSpellcheck ? "false" : "true") + "\"";
103
+ var html = ["<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\"><html" + sp + "><head>"];
104
+ // Hack to work around a bunch of IE8-specific problems.
105
+ html.push("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=EmulateIE7\"/>");
106
+ var queryStr = options.noScriptCaching ? "?nocache=" + new Date().getTime().toString(16) : "";
107
+ forEach(options.stylesheet, function(file) {
108
+ html.push("<link rel=\"stylesheet\" type=\"text/css\" href=\"" + file + queryStr + "\"/>");
109
+ });
110
+ forEach(options.basefiles.concat(options.parserfile), function(file) {
111
+ if (!/^https?:/.test(file)) file = options.path + file;
112
+ html.push("<script type=\"text/javascript\" src=\"" + file + queryStr + "\"><" + "/script>");
113
+ });
114
+ html.push("</head><body style=\"border-width: 0;\" class=\"editbox\"" + sp + "></body></html>");
115
+ return html.join("");
116
+ }
117
+
118
+ var internetExplorer = document.selection && window.ActiveXObject && /MSIE/.test(navigator.userAgent);
119
+
120
+ function CodeMirror(place, options) {
121
+ // Use passed options, if any, to override defaults.
122
+ this.options = options = options || {};
123
+ setDefaults(options, CodeMirrorConfig);
124
+
125
+ // Backward compatibility for deprecated options.
126
+ if (options.dumbTabs) options.tabMode = "spaces";
127
+ else if (options.normalTab) options.tabMode = "default";
128
+ if (options.cursorActivity) options.onCursorActivity = options.cursorActivity;
129
+
130
+ var frame = this.frame = createHTMLElement("iframe");
131
+ if (options.iframeClass) frame.className = options.iframeClass;
132
+ frame.frameBorder = 0;
133
+ frame.style.border = "0";
134
+ frame.style.width = '100%';
135
+ frame.style.height = '100%';
136
+ // display: block occasionally suppresses some Firefox bugs, so we
137
+ // always add it, redundant as it sounds.
138
+ frame.style.display = "block";
139
+
140
+ var div = this.wrapping = createHTMLElement("div");
141
+ div.style.position = "relative";
142
+ div.className = "CodeMirror-wrapping";
143
+ div.style.width = options.width;
144
+ div.style.height = (options.height == "dynamic") ? options.minHeight + "px" : options.height;
145
+ // This is used by Editor.reroutePasteEvent
146
+ var teHack = this.textareaHack = createHTMLElement("textarea");
147
+ div.appendChild(teHack);
148
+ teHack.style.position = "absolute";
149
+ teHack.style.left = "-10000px";
150
+ teHack.style.width = "10px";
151
+ teHack.tabIndex = 100000;
152
+
153
+ // Link back to this object, so that the editor can fetch options
154
+ // and add a reference to itself.
155
+ frame.CodeMirror = this;
156
+ if (options.domain && internetExplorer) {
157
+ this.html = frameHTML(options);
158
+ frame.src = "javascript:(function(){document.open();" +
159
+ (options.domain ? "document.domain=\"" + options.domain + "\";" : "") +
160
+ "document.write(window.frameElement.CodeMirror.html);document.close();})()";
161
+ }
162
+ else {
163
+ frame.src = "javascript:;";
164
+ }
165
+
166
+ if (place.appendChild) place.appendChild(div);
167
+ else place(div);
168
+ div.appendChild(frame);
169
+ if (options.lineNumbers) this.lineNumbers = addLineNumberDiv(div, options.firstLineNumber);
170
+
171
+ this.win = frame.contentWindow;
172
+ if (!options.domain || !internetExplorer) {
173
+ this.win.document.open();
174
+ this.win.document.write(frameHTML(options));
175
+ this.win.document.close();
176
+ }
177
+ }
178
+
179
+ CodeMirror.prototype = {
180
+ init: function() {
181
+ // Deprecated, but still supported.
182
+ if (this.options.initCallback) this.options.initCallback(this);
183
+ if (this.options.onLoad) this.options.onLoad(this);
184
+ if (this.options.lineNumbers) this.activateLineNumbers();
185
+ if (this.options.reindentOnLoad) this.reindent();
186
+ if (this.options.height == "dynamic") this.setDynamicHeight();
187
+ },
188
+
189
+ getCode: function() {return this.editor.getCode();},
190
+ setCode: function(code) {this.editor.importCode(code);},
191
+ selection: function() {this.focusIfIE(); return this.editor.selectedText();},
192
+ reindent: function() {this.editor.reindent();},
193
+ reindentSelection: function() {this.focusIfIE(); this.editor.reindentSelection(null);},
194
+
195
+ focusIfIE: function() {
196
+ // in IE, a lot of selection-related functionality only works when the frame is focused
197
+ if (this.win.select.ie_selection && document.activeElement != this.frame)
198
+ this.focus();
199
+ },
200
+ focus: function() {
201
+ this.win.focus();
202
+ if (this.editor.selectionSnapshot) // IE hack
203
+ this.win.select.setBookmark(this.win.document.body, this.editor.selectionSnapshot);
204
+ },
205
+ replaceSelection: function(text) {
206
+ this.focus();
207
+ this.editor.replaceSelection(text);
208
+ return true;
209
+ },
210
+ replaceChars: function(text, start, end) {
211
+ this.editor.replaceChars(text, start, end);
212
+ },
213
+ getSearchCursor: function(string, fromCursor, caseFold) {
214
+ return this.editor.getSearchCursor(string, fromCursor, caseFold);
215
+ },
216
+
217
+ undo: function() {this.editor.history.undo();},
218
+ redo: function() {this.editor.history.redo();},
219
+ historySize: function() {return this.editor.history.historySize();},
220
+ clearHistory: function() {this.editor.history.clear();},
221
+
222
+ grabKeys: function(callback, filter) {this.editor.grabKeys(callback, filter);},
223
+ ungrabKeys: function() {this.editor.ungrabKeys();},
224
+
225
+ setParser: function(name, parserConfig) {this.editor.setParser(name, parserConfig);},
226
+ setSpellcheck: function(on) {this.win.document.body.spellcheck = on;},
227
+ setStylesheet: function(names) {
228
+ if (typeof names === "string") names = [names];
229
+ var activeStylesheets = {};
230
+ var matchedNames = {};
231
+ var links = this.win.document.getElementsByTagName("link");
232
+ // Create hashes of active stylesheets and matched names.
233
+ // This is O(n^2) but n is expected to be very small.
234
+ for (var x = 0, link; link = links[x]; x++) {
235
+ if (link.rel.indexOf("stylesheet") !== -1) {
236
+ for (var y = 0; y < names.length; y++) {
237
+ var name = names[y];
238
+ if (link.href.substring(link.href.length - name.length) === name) {
239
+ activeStylesheets[link.href] = true;
240
+ matchedNames[name] = true;
241
+ }
242
+ }
243
+ }
244
+ }
245
+ // Activate the selected stylesheets and disable the rest.
246
+ for (var x = 0, link; link = links[x]; x++) {
247
+ if (link.rel.indexOf("stylesheet") !== -1) {
248
+ link.disabled = !(link.href in activeStylesheets);
249
+ }
250
+ }
251
+ // Create any new stylesheets.
252
+ for (var y = 0; y < names.length; y++) {
253
+ var name = names[y];
254
+ if (!(name in matchedNames)) {
255
+ var link = this.win.document.createElement("link");
256
+ link.rel = "stylesheet";
257
+ link.type = "text/css";
258
+ link.href = name;
259
+ this.win.document.getElementsByTagName('head')[0].appendChild(link);
260
+ }
261
+ }
262
+ },
263
+ setTextWrapping: function(on) {
264
+ if (on == this.options.textWrapping) return;
265
+ this.win.document.body.style.whiteSpace = on ? "" : "nowrap";
266
+ this.options.textWrapping = on;
267
+ if (this.lineNumbers) {
268
+ this.setLineNumbers(false);
269
+ this.setLineNumbers(true);
270
+ }
271
+ },
272
+ setIndentUnit: function(unit) {this.win.indentUnit = unit;},
273
+ setUndoDepth: function(depth) {this.editor.history.maxDepth = depth;},
274
+ setTabMode: function(mode) {this.options.tabMode = mode;},
275
+ setEnterMode: function(mode) {this.options.enterMode = mode;},
276
+ setLineNumbers: function(on) {
277
+ if (on && !this.lineNumbers) {
278
+ this.lineNumbers = addLineNumberDiv(this.wrapping,this.options.firstLineNumber);
279
+ this.activateLineNumbers();
280
+ }
281
+ else if (!on && this.lineNumbers) {
282
+ this.wrapping.removeChild(this.lineNumbers);
283
+ this.wrapping.style.paddingLeft = "";
284
+ this.lineNumbers = null;
285
+ }
286
+ },
287
+
288
+ cursorPosition: function(start) {this.focusIfIE(); return this.editor.cursorPosition(start);},
289
+ firstLine: function() {return this.editor.firstLine();},
290
+ lastLine: function() {return this.editor.lastLine();},
291
+ nextLine: function(line) {return this.editor.nextLine(line);},
292
+ prevLine: function(line) {return this.editor.prevLine(line);},
293
+ lineContent: function(line) {return this.editor.lineContent(line);},
294
+ setLineContent: function(line, content) {this.editor.setLineContent(line, content);},
295
+ removeLine: function(line){this.editor.removeLine(line);},
296
+ insertIntoLine: function(line, position, content) {this.editor.insertIntoLine(line, position, content);},
297
+ selectLines: function(startLine, startOffset, endLine, endOffset) {
298
+ this.win.focus();
299
+ this.editor.selectLines(startLine, startOffset, endLine, endOffset);
300
+ },
301
+ nthLine: function(n) {
302
+ var line = this.firstLine();
303
+ for (; n > 1 && line !== false; n--)
304
+ line = this.nextLine(line);
305
+ return line;
306
+ },
307
+ lineNumber: function(line) {
308
+ var num = 0;
309
+ while (line !== false) {
310
+ num++;
311
+ line = this.prevLine(line);
312
+ }
313
+ return num;
314
+ },
315
+ jumpToLine: function(line) {
316
+ if (typeof line == "number") line = this.nthLine(line);
317
+ this.selectLines(line, 0);
318
+ this.win.focus();
319
+ },
320
+ currentLine: function() { // Deprecated, but still there for backward compatibility
321
+ return this.lineNumber(this.cursorLine());
322
+ },
323
+ cursorLine: function() {
324
+ return this.cursorPosition().line;
325
+ },
326
+ cursorCoords: function(start) {return this.editor.cursorCoords(start);},
327
+
328
+ activateLineNumbers: function() {
329
+ var frame = this.frame, win = frame.contentWindow, doc = win.document, body = doc.body,
330
+ nums = this.lineNumbers, scroller = nums.firstChild, self = this;
331
+ var barWidth = null;
332
+
333
+ nums.onclick = function(e) {
334
+ var handler = self.options.onLineNumberClick;
335
+ if (handler) {
336
+ var div = (e || window.event).target || (e || window.event).srcElement;
337
+ var num = div == nums ? NaN : Number(div.innerHTML);
338
+ if (!isNaN(num)) handler(num, div);
339
+ }
340
+ };
341
+
342
+ function sizeBar() {
343
+ if (frame.offsetWidth == 0) return;
344
+ for (var root = frame; root.parentNode; root = root.parentNode){}
345
+ if (!nums.parentNode || root != document || !win.Editor) {
346
+ // Clear event handlers (their nodes might already be collected, so try/catch)
347
+ try{clear();}catch(e){}
348
+ clearInterval(sizeInterval);
349
+ return;
350
+ }
351
+
352
+ if (nums.offsetWidth != barWidth) {
353
+ barWidth = nums.offsetWidth;
354
+ frame.parentNode.style.paddingLeft = barWidth + "px";
355
+ }
356
+ }
357
+ function doScroll() {
358
+ nums.scrollTop = body.scrollTop || doc.documentElement.scrollTop || 0;
359
+ }
360
+ // Cleanup function, registered by nonWrapping and wrapping.
361
+ var clear = function(){};
362
+ sizeBar();
363
+ var sizeInterval = setInterval(sizeBar, 500);
364
+
365
+ function ensureEnoughLineNumbers(fill) {
366
+ var lineHeight = scroller.firstChild.offsetHeight;
367
+ if (lineHeight == 0) return;
368
+ var targetHeight = 50 + Math.max(body.offsetHeight, Math.max(frame.offsetHeight, body.scrollHeight || 0)),
369
+ lastNumber = Math.ceil(targetHeight / lineHeight);
370
+ for (var i = scroller.childNodes.length; i <= lastNumber; i++) {
371
+ var div = createHTMLElement("div");
372
+ div.appendChild(document.createTextNode(fill ? String(i + self.options.firstLineNumber) : "\u00a0"));
373
+ scroller.appendChild(div);
374
+ }
375
+ }
376
+
377
+ function nonWrapping() {
378
+ function update() {
379
+ ensureEnoughLineNumbers(true);
380
+ doScroll();
381
+ }
382
+ self.updateNumbers = update;
383
+ var onScroll = win.addEventHandler(win, "scroll", doScroll, true),
384
+ onResize = win.addEventHandler(win, "resize", update, true);
385
+ clear = function(){
386
+ onScroll(); onResize();
387
+ if (self.updateNumbers == update) self.updateNumbers = null;
388
+ };
389
+ update();
390
+ }
391
+
392
+ function wrapping() {
393
+ var node, lineNum, next, pos, changes = [], styleNums = self.options.styleNumbers;
394
+
395
+ function setNum(n, node) {
396
+ // Does not typically happen (but can, if you mess with the
397
+ // document during the numbering)
398
+ if (!lineNum) lineNum = scroller.appendChild(createHTMLElement("div"));
399
+ if (styleNums) styleNums(lineNum, node, n);
400
+ // Changes are accumulated, so that the document layout
401
+ // doesn't have to be recomputed during the pass
402
+ changes.push(lineNum); changes.push(n);
403
+ pos = lineNum.offsetHeight + lineNum.offsetTop;
404
+ lineNum = lineNum.nextSibling;
405
+ }
406
+ function commitChanges() {
407
+ for (var i = 0; i < changes.length; i += 2)
408
+ changes[i].innerHTML = changes[i + 1];
409
+ changes = [];
410
+ }
411
+ function work() {
412
+ if (!scroller.parentNode || scroller.parentNode != self.lineNumbers) return;
413
+
414
+ var endTime = new Date().getTime() + self.options.lineNumberTime;
415
+ while (node) {
416
+ setNum(next++, node.previousSibling);
417
+ for (; node && !win.isBR(node); node = node.nextSibling) {
418
+ var bott = node.offsetTop + node.offsetHeight;
419
+ while (scroller.offsetHeight && bott - 3 > pos) {
420
+ var oldPos = pos;
421
+ setNum("&nbsp;");
422
+ if (pos <= oldPos) break;
423
+ }
424
+ }
425
+ if (node) node = node.nextSibling;
426
+ if (new Date().getTime() > endTime) {
427
+ commitChanges();
428
+ pending = setTimeout(work, self.options.lineNumberDelay);
429
+ return;
430
+ }
431
+ }
432
+ while (lineNum) setNum(next++);
433
+ commitChanges();
434
+ doScroll();
435
+ }
436
+ function start(firstTime) {
437
+ doScroll();
438
+ ensureEnoughLineNumbers(firstTime);
439
+ node = body.firstChild;
440
+ lineNum = scroller.firstChild;
441
+ pos = 0;
442
+ next = self.options.firstLineNumber;
443
+ work();
444
+ }
445
+
446
+ start(true);
447
+ var pending = null;
448
+ function update() {
449
+ if (pending) clearTimeout(pending);
450
+ if (self.editor.allClean()) start();
451
+ else pending = setTimeout(update, 200);
452
+ }
453
+ self.updateNumbers = update;
454
+ var onScroll = win.addEventHandler(win, "scroll", doScroll, true),
455
+ onResize = win.addEventHandler(win, "resize", update, true);
456
+ clear = function(){
457
+ if (pending) clearTimeout(pending);
458
+ if (self.updateNumbers == update) self.updateNumbers = null;
459
+ onScroll();
460
+ onResize();
461
+ };
462
+ }
463
+ (this.options.textWrapping || this.options.styleNumbers ? wrapping : nonWrapping)();
464
+ },
465
+
466
+ setDynamicHeight: function() {
467
+ var self = this, activity = self.options.onCursorActivity, win = self.win, body = win.document.body,
468
+ lineHeight = null, timeout = null, vmargin = 2 * self.frame.offsetTop;
469
+ body.style.overflowY = "hidden";
470
+ win.document.documentElement.style.overflowY = "hidden";
471
+ this.frame.scrolling = "no";
472
+
473
+ function updateHeight() {
474
+ var trailingLines = 0, node = body.lastChild, computedHeight;
475
+ while (node && win.isBR(node)) {
476
+ if (!node.hackBR) trailingLines++;
477
+ node = node.previousSibling;
478
+ }
479
+ if (node) {
480
+ lineHeight = node.offsetHeight;
481
+ computedHeight = node.offsetTop + (1 + trailingLines) * lineHeight;
482
+ }
483
+ else if (lineHeight) {
484
+ computedHeight = trailingLines * lineHeight;
485
+ }
486
+ if (computedHeight)
487
+ self.wrapping.style.height = Math.max(vmargin + computedHeight, self.options.minHeight) + "px";
488
+ }
489
+ setTimeout(updateHeight, 300);
490
+ self.options.onCursorActivity = function(x) {
491
+ if (activity) activity(x);
492
+ clearTimeout(timeout);
493
+ timeout = setTimeout(updateHeight, 100);
494
+ };
495
+ }
496
+ };
497
+
498
+ CodeMirror.InvalidLineHandle = {toString: function(){return "CodeMirror.InvalidLineHandle";}};
499
+
500
+ CodeMirror.replace = function(element) {
501
+ if (typeof element == "string")
502
+ element = document.getElementById(element);
503
+ return function(newElement) {
504
+ element.parentNode.replaceChild(newElement, element);
505
+ };
506
+ };
507
+
508
+ CodeMirror.fromTextArea = function(area, options) {
509
+ if (typeof area == "string")
510
+ area = document.getElementById(area);
511
+
512
+ options = options || {};
513
+ if (area.style.width && options.width == null)
514
+ options.width = area.style.width;
515
+ if (area.style.height && options.height == null)
516
+ options.height = area.style.height;
517
+ if (options.content == null) options.content = area.value;
518
+
519
+ function updateField() {
520
+ area.value = mirror.getCode();
521
+ }
522
+ if (area.form) {
523
+ if (typeof area.form.addEventListener == "function")
524
+ area.form.addEventListener("submit", updateField, false);
525
+ else
526
+ area.form.attachEvent("onsubmit", updateField);
527
+ var realSubmit = area.form.submit;
528
+ function wrapSubmit() {
529
+ updateField();
530
+ // Can't use realSubmit.apply because IE6 is too stupid
531
+ area.form.submit = realSubmit;
532
+ area.form.submit();
533
+ area.form.submit = wrapSubmit;
534
+ }
535
+ try {area.form.submit = wrapSubmit;} catch(e){}
536
+ }
537
+
538
+ function insert(frame) {
539
+ if (area.nextSibling)
540
+ area.parentNode.insertBefore(frame, area.nextSibling);
541
+ else
542
+ area.parentNode.appendChild(frame);
543
+ }
544
+
545
+ area.style.display = "none";
546
+ var mirror = new CodeMirror(insert, options);
547
+ mirror.save = updateField;
548
+ mirror.toTextArea = function() {
549
+ updateField();
550
+ area.parentNode.removeChild(mirror.wrapping);
551
+ area.style.display = "";
552
+ if (area.form) {
553
+ try {area.form.submit = realSubmit;} catch(e) {}
554
+ if (typeof area.form.removeEventListener == "function")
555
+ area.form.removeEventListener("submit", updateField, false);
556
+ else
557
+ area.form.detachEvent("onsubmit", updateField);
558
+ }
559
+ };
560
+
561
+ return mirror;
562
+ };
563
+
564
+ CodeMirror.isProbablySupported = function() {
565
+ // This is rather awful, but can be useful.
566
+ var match;
567
+ if (window.opera)
568
+ return Number(window.opera.version()) >= 9.52;
569
+ else if (/Apple Computer, Inc/.test(navigator.vendor) && (match = navigator.userAgent.match(/Version\/(\d+(?:\.\d+)?)\./)))
570
+ return Number(match[1]) >= 3;
571
+ else if (document.selection && window.ActiveXObject && (match = navigator.userAgent.match(/MSIE (\d+(?:\.\d*)?)\b/)))
572
+ return Number(match[1]) >= 6;
573
+ else if (match = navigator.userAgent.match(/gecko\/(\d{8})/i))
574
+ return Number(match[1]) >= 20050901;
575
+ else if (match = navigator.userAgent.match(/AppleWebKit\/(\d+)/))
576
+ return Number(match[1]) >= 525;
577
+ else
578
+ return null;
579
+ };
580
+
581
+ return CodeMirror;
582
+ })();