maglev-webtools 0.2.1 → 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (296) hide show
  1. data/README.rdoc +38 -29
  2. data/bin/webtools +22 -1
  3. data/lib/web_tools/code_browser.rb +156 -0
  4. data/lib/web_tools/debugger.rb +96 -199
  5. data/lib/web_tools/info.rb +1 -3
  6. data/lib/web_tools/method_list.rb +67 -0
  7. data/lib/web_tools/middleware/debugger.rb +10 -16
  8. data/lib/web_tools/object_log.rb +24 -0
  9. data/lib/web_tools/session_list.rb +119 -0
  10. data/lib/web_tools/shared_page_cache.rb +30 -0
  11. data/lib/web_tools/stat_process.rb +24 -0
  12. data/lib/web_tools/statistics.rb +14 -0
  13. data/lib/web_tools/support/app_model.rb +66 -101
  14. data/lib/web_tools/support/code_browser.rb +88 -86
  15. data/lib/web_tools/support/debugger.rb +303 -0
  16. data/lib/web_tools/support/error_log.rb +33 -0
  17. data/lib/web_tools/support/ruby.rb +60 -121
  18. data/lib/web_tools/support/service_helper.rb +38 -10
  19. data/lib/web_tools/support/smalltalk_extensions.rb +12 -0
  20. data/lib/web_tools/tool.rb +48 -0
  21. data/lib/web_tools/ui.rb +14 -53
  22. data/lib/web_tools/version_report.rb +29 -0
  23. data/lib/web_tools/workspace.rb +77 -0
  24. data/lib/web_tools.rb +14 -4
  25. data/public/CodeBrowser.html +51 -0
  26. data/public/CodeMirror/LICENSE +19 -0
  27. data/public/CodeMirror/css/codemirror.css +67 -0
  28. data/public/CodeMirror/css/default.css +18 -0
  29. data/public/CodeMirror/js/codemirror.js +2131 -0
  30. data/public/CodeMirror/js/ruby.js +195 -0
  31. data/public/CodeMirror/js/smalltalk.js +139 -0
  32. data/public/Debugger.html +28 -0
  33. data/public/MethodList.html +20 -0
  34. data/public/ObjectLog.html +20 -0
  35. data/public/SessionList.html +31 -0
  36. data/public/SharedPageCache.html +78 -0
  37. data/public/Statistics.html +64 -0
  38. data/public/VersionReport.html +50 -0
  39. data/public/Workspace.html +39 -0
  40. data/public/css/CodeBrowser.css +24 -0
  41. data/public/css/Debugger.css +32 -0
  42. data/public/css/MethodList.css +8 -0
  43. data/public/css/ObjectLog.css +5 -0
  44. data/public/css/SessionList.css +9 -0
  45. data/public/css/Statistics.css +24 -0
  46. data/public/{stylesheets → css}/base/images/ui-anim_basic_16x16.gif +0 -0
  47. data/public/{stylesheets → css}/base/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  48. data/public/{stylesheets → css}/base/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  49. data/public/{stylesheets → css}/base/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  50. data/public/{stylesheets → css}/base/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  51. data/public/{stylesheets → css}/base/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  52. data/public/{stylesheets → css}/base/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  53. data/public/{stylesheets → css}/base/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  54. data/public/{stylesheets → css}/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  55. data/public/{stylesheets → css}/base/images/ui-icons_222222_256x240.png +0 -0
  56. data/public/{stylesheets → css}/base/images/ui-icons_2e83ff_256x240.png +0 -0
  57. data/public/{stylesheets → css}/base/images/ui-icons_454545_256x240.png +0 -0
  58. data/public/{stylesheets → css}/base/images/ui-icons_888888_256x240.png +0 -0
  59. data/public/{stylesheets → css}/base/images/ui-icons_cd0a0a_256x240.png +0 -0
  60. data/public/{stylesheets → css}/base/jquery.ui.accordion.css +0 -0
  61. data/public/{stylesheets → css}/base/jquery.ui.all.css +0 -0
  62. data/public/{stylesheets → css}/base/jquery.ui.autocomplete.css +0 -0
  63. data/public/{stylesheets → css}/base/jquery.ui.base.css +0 -0
  64. data/public/{stylesheets → css}/base/jquery.ui.button.css +0 -0
  65. data/public/{stylesheets → css}/base/jquery.ui.core.css +0 -0
  66. data/public/{stylesheets → css}/base/jquery.ui.datepicker.css +0 -0
  67. data/public/{stylesheets → css}/base/jquery.ui.dialog.css +0 -0
  68. data/public/{stylesheets → css}/base/jquery.ui.progressbar.css +0 -0
  69. data/public/{stylesheets → css}/base/jquery.ui.resizable.css +0 -0
  70. data/public/{stylesheets → css}/base/jquery.ui.selectable.css +0 -0
  71. data/public/{stylesheets → css}/base/jquery.ui.slider.css +0 -0
  72. data/public/{stylesheets → css}/base/jquery.ui.tabs.css +0 -0
  73. data/public/{stylesheets → css}/base/jquery.ui.theme.css +0 -0
  74. data/public/css/editor.css +25 -0
  75. data/public/css/jjmenu.css +33 -0
  76. data/public/css/menuitem.gif +0 -0
  77. data/public/css/more.gif +0 -0
  78. data/public/{stylesheets → css}/reset.css +1 -1
  79. data/public/css/smoothness/images/ui-anim_basic_16x16.gif +0 -0
  80. data/public/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  81. data/public/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  82. data/public/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  83. data/public/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  84. data/public/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  85. data/public/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  86. data/public/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  87. data/public/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  88. data/public/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
  89. data/public/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  90. data/public/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
  91. data/public/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
  92. data/public/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  93. data/public/css/smoothness/jquery-ui.css +489 -0
  94. data/public/css/ui-lightness/images/ui-anim_basic_16x16.gif +0 -0
  95. data/public/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  96. data/public/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  97. data/public/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png +0 -0
  98. data/public/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  99. data/public/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  100. data/public/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  101. data/public/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  102. data/public/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  103. data/public/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  104. data/public/css/ui-lightness/images/ui-icons_222222_256x240.png +0 -0
  105. data/public/css/ui-lightness/images/ui-icons_228ef1_256x240.png +0 -0
  106. data/public/css/ui-lightness/images/ui-icons_ef8c08_256x240.png +0 -0
  107. data/public/css/ui-lightness/images/ui-icons_ffd27a_256x240.png +0 -0
  108. data/public/css/ui-lightness/images/ui-icons_ffffff_256x240.png +0 -0
  109. data/public/css/ui-lightness/jquery-ui.css +489 -0
  110. data/public/css/webtools.css +65 -0
  111. data/public/favicon.ico +0 -0
  112. data/public/flot/API.txt +1201 -0
  113. data/public/flot/FAQ.txt +76 -0
  114. data/public/flot/LICENSE.txt +22 -0
  115. data/public/flot/Makefile +9 -0
  116. data/public/flot/NEWS.txt +508 -0
  117. data/public/flot/PLUGINS.txt +137 -0
  118. data/public/flot/README.txt +90 -0
  119. data/public/flot/examples/ajax.html +143 -0
  120. data/public/flot/examples/annotating.html +75 -0
  121. data/public/flot/examples/arrow-down.gif +0 -0
  122. data/public/flot/examples/arrow-left.gif +0 -0
  123. data/public/flot/examples/arrow-right.gif +0 -0
  124. data/public/flot/examples/arrow-up.gif +0 -0
  125. data/public/flot/examples/basic.html +38 -0
  126. data/public/flot/examples/data-eu-gdp-growth-1.json +4 -0
  127. data/public/flot/examples/data-eu-gdp-growth-2.json +4 -0
  128. data/public/flot/examples/data-eu-gdp-growth-3.json +4 -0
  129. data/public/flot/examples/data-eu-gdp-growth-4.json +4 -0
  130. data/public/flot/examples/data-eu-gdp-growth-5.json +4 -0
  131. data/public/flot/examples/data-eu-gdp-growth.json +4 -0
  132. data/public/flot/examples/data-japan-gdp-growth.json +4 -0
  133. data/public/flot/examples/data-usa-gdp-growth.json +4 -0
  134. data/public/flot/examples/graph-types.html +75 -0
  135. data/public/flot/examples/hs-2004-27-a-large_web.jpg +0 -0
  136. data/public/flot/examples/image.html +45 -0
  137. data/public/flot/examples/index.html +44 -0
  138. data/public/flot/examples/interacting-axes.html +97 -0
  139. data/public/flot/examples/interacting.html +93 -0
  140. data/public/flot/examples/layout.css +6 -0
  141. data/public/flot/examples/multiple-axes.html +60 -0
  142. data/public/flot/examples/navigate.html +118 -0
  143. data/public/flot/examples/percentiles.html +57 -0
  144. data/public/flot/examples/pie.html +756 -0
  145. data/public/flot/examples/realtime.html +83 -0
  146. data/public/flot/examples/resize.html +61 -0
  147. data/public/flot/examples/selection.html +114 -0
  148. data/public/flot/examples/setting-options.html +61 -0
  149. data/public/flot/examples/stacking.html +77 -0
  150. data/public/flot/examples/symbols.html +49 -0
  151. data/public/flot/examples/thresholding.html +54 -0
  152. data/public/flot/examples/time.html +71 -0
  153. data/public/flot/examples/tracking.html +95 -0
  154. data/public/flot/examples/turning-series.html +98 -0
  155. data/public/flot/examples/visitors.html +90 -0
  156. data/public/flot/examples/zooming.html +98 -0
  157. data/public/flot/excanvas.js +1427 -0
  158. data/public/flot/excanvas.min.js +1 -0
  159. data/public/flot/jquery.colorhelpers.js +179 -0
  160. data/public/flot/jquery.colorhelpers.min.js +1 -0
  161. data/public/flot/jquery.flot.crosshair.js +167 -0
  162. data/public/flot/jquery.flot.crosshair.min.js +1 -0
  163. data/public/flot/jquery.flot.fillbetween.js +183 -0
  164. data/public/flot/jquery.flot.fillbetween.min.js +1 -0
  165. data/public/flot/jquery.flot.image.js +238 -0
  166. data/public/flot/jquery.flot.image.min.js +1 -0
  167. data/public/flot/jquery.flot.js +2599 -0
  168. data/public/flot/jquery.flot.min.js +6 -0
  169. data/public/flot/jquery.flot.navigate.js +336 -0
  170. data/public/flot/jquery.flot.navigate.min.js +1 -0
  171. data/public/flot/jquery.flot.pie.js +750 -0
  172. data/public/flot/jquery.flot.pie.min.js +1 -0
  173. data/public/flot/jquery.flot.resize.js +60 -0
  174. data/public/flot/jquery.flot.resize.min.js +1 -0
  175. data/public/flot/jquery.flot.selection.js +344 -0
  176. data/public/flot/jquery.flot.selection.min.js +1 -0
  177. data/public/flot/jquery.flot.stack.js +184 -0
  178. data/public/flot/jquery.flot.stack.min.js +1 -0
  179. data/public/flot/jquery.flot.symbol.js +70 -0
  180. data/public/flot/jquery.flot.symbol.min.js +1 -0
  181. data/public/flot/jquery.flot.threshold.js +103 -0
  182. data/public/flot/jquery.flot.threshold.min.js +1 -0
  183. data/public/flot/jquery.js +8316 -0
  184. data/public/flot/jquery.min.js +23 -0
  185. data/public/genPacking.pl +30 -0
  186. data/public/index.html +28 -0
  187. data/public/install.tpz +66 -0
  188. data/public/installAndRun.tpz +5 -0
  189. data/public/jsTree/jquery.jstree.js +3510 -0
  190. data/public/jsTree/themes/default/d.gif +0 -0
  191. data/public/jsTree/themes/default/d.png +0 -0
  192. data/public/jsTree/themes/default/style.css +73 -0
  193. data/public/jsTree/themes/default/throbber.gif +0 -0
  194. data/public/readMe.txt +9 -0
  195. data/public/scripts/CodeBrowser.js +645 -0
  196. data/public/scripts/Debugger.js +134 -0
  197. data/public/scripts/MethodList.js +72 -0
  198. data/public/scripts/ObjectLog.js +59 -0
  199. data/public/scripts/SessionList.js +164 -0
  200. data/public/scripts/Statistics.js +266 -0
  201. data/public/scripts/editor.js +430 -0
  202. data/public/scripts/jjmenu.js +375 -0
  203. data/public/scripts/jquery-ui.js +1012 -0
  204. data/public/scripts/jquery.js +154 -0
  205. data/public/scripts/webtools.js +374 -0
  206. data/public/src/CodeBrowser.gs +416 -0
  207. data/public/src/Debugger.gs +132 -0
  208. data/public/src/MethodList.gs +130 -0
  209. data/public/src/ObjectLog.gs +73 -0
  210. data/public/src/Server.gs +544 -0
  211. data/public/src/SessionList.gs +172 -0
  212. data/public/src/SharedPageCache.gs +66 -0
  213. data/public/src/StatProcess.gs +280 -0
  214. data/public/src/StatProcessType.gs +242 -0
  215. data/public/src/StatStatistic.gs +381 -0
  216. data/public/src/Statistics.gs +222 -0
  217. data/public/src/Statmonitor.gs +490 -0
  218. data/public/src/Tool.gs +86 -0
  219. data/public/src/VersionReport.gs +52 -0
  220. data/public/src/Workspace.gs +163 -0
  221. data/views/debugger.rhtml +6 -9
  222. metadata +344 -243
  223. data/lib/web_tools/#debugger.rb# +0 -212
  224. data/lib/web_tools/browser.rb +0 -45
  225. data/public/images/favicon.ico +0 -0
  226. data/public/javascript/CodeMirror/LICENSE +0 -23
  227. data/public/javascript/CodeMirror/css/Smalltalk.css +0 -34
  228. data/public/javascript/CodeMirror/js/codemirror.js +0 -582
  229. data/public/javascript/CodeMirror/js/editor.js +0 -1671
  230. data/public/javascript/CodeMirror/js/highlight.js +0 -68
  231. data/public/javascript/CodeMirror/js/parseSmalltalk.js +0 -126
  232. data/public/javascript/CodeMirror/js/parsedummy.js +0 -32
  233. data/public/javascript/CodeMirror/js/select.js +0 -699
  234. data/public/javascript/CodeMirror/js/stringstream.js +0 -159
  235. data/public/javascript/CodeMirror/js/tokenize.js +0 -57
  236. data/public/javascript/CodeMirror/js/undo.js +0 -413
  237. data/public/javascript/CodeMirror/js/util.js +0 -133
  238. data/public/javascript/CodeMirror/testSmalltalkParser.html +0 -116
  239. data/public/javascript/ace/ace-uncompressed.js +0 -17299
  240. data/public/javascript/ace/ace.js +0 -1
  241. data/public/javascript/ace/keybinding-emacs.js +0 -1
  242. data/public/javascript/ace/keybinding-vim.js +0 -1
  243. data/public/javascript/ace/mode-c_cpp.js +0 -1
  244. data/public/javascript/ace/mode-clojure.js +0 -1
  245. data/public/javascript/ace/mode-coffee.js +0 -1
  246. data/public/javascript/ace/mode-csharp.js +0 -1
  247. data/public/javascript/ace/mode-css.js +0 -1
  248. data/public/javascript/ace/mode-groovy.js +0 -1
  249. data/public/javascript/ace/mode-html.js +0 -1
  250. data/public/javascript/ace/mode-java.js +0 -1
  251. data/public/javascript/ace/mode-javascript.js +0 -1
  252. data/public/javascript/ace/mode-json.js +0 -1
  253. data/public/javascript/ace/mode-lua.js +0 -1
  254. data/public/javascript/ace/mode-markdown.js +0 -1
  255. data/public/javascript/ace/mode-ocaml.js +0 -1
  256. data/public/javascript/ace/mode-perl.js +0 -1
  257. data/public/javascript/ace/mode-php.js +0 -1
  258. data/public/javascript/ace/mode-python.js +0 -1
  259. data/public/javascript/ace/mode-ruby.js +0 -1
  260. data/public/javascript/ace/mode-scad.js +0 -1
  261. data/public/javascript/ace/mode-scala.js +0 -1
  262. data/public/javascript/ace/mode-scss.js +0 -1
  263. data/public/javascript/ace/mode-svg.js +0 -1
  264. data/public/javascript/ace/mode-textile.js +0 -1
  265. data/public/javascript/ace/mode-xml.js +0 -1
  266. data/public/javascript/ace/theme-clouds.js +0 -1
  267. data/public/javascript/ace/theme-clouds_midnight.js +0 -1
  268. data/public/javascript/ace/theme-cobalt.js +0 -1
  269. data/public/javascript/ace/theme-crimson_editor.js +0 -1
  270. data/public/javascript/ace/theme-dawn.js +0 -1
  271. data/public/javascript/ace/theme-eclipse.js +0 -1
  272. data/public/javascript/ace/theme-idle_fingers.js +0 -1
  273. data/public/javascript/ace/theme-kr_theme.js +0 -1
  274. data/public/javascript/ace/theme-merbivore.js +0 -1
  275. data/public/javascript/ace/theme-merbivore_soft.js +0 -1
  276. data/public/javascript/ace/theme-mono_industrial.js +0 -1
  277. data/public/javascript/ace/theme-monokai.js +0 -1
  278. data/public/javascript/ace/theme-pastel_on_dark.js +0 -1
  279. data/public/javascript/ace/theme-solarized_dark.js +0 -1
  280. data/public/javascript/ace/theme-solarized_light.js +0 -1
  281. data/public/javascript/ace/theme-textmate.js +0 -1
  282. data/public/javascript/ace/theme-twilight.js +0 -1
  283. data/public/javascript/ace/theme-vibrant_ink.js +0 -1
  284. data/public/javascript/ace/worker-coffee.js +0 -1
  285. data/public/javascript/ace/worker-css.js +0 -1
  286. data/public/javascript/ace/worker-javascript.js +0 -1
  287. data/public/javascript/webtools/browser.js +0 -260
  288. data/public/javascript/webtools/debugger.coffee +0 -286
  289. data/public/javascript/webtools/debugger.js +0 -366
  290. data/public/javascript/webtools/sessions.coffee +0 -17
  291. data/public/javascript/webtools/sessions.js +0 -27
  292. data/public/javascript/webtools/version.coffee +0 -14
  293. data/public/javascript/webtools/version.js +0 -20
  294. data/public/stylesheets/jquery.contextMenu.css +0 -62
  295. data/public/stylesheets/webtools.css +0 -53
  296. data/public/test.html +0 -47
@@ -1,68 +0,0 @@
1
- // Minimal framing needed to use CodeMirror-style parsers to highlight
2
- // code. Load this along with tokenize.js, stringstream.js, and your
3
- // parser. Then call highlightText, passing a string as the first
4
- // argument, and as the second argument either a callback function
5
- // that will be called with an array of SPAN nodes for every line in
6
- // the code, or a DOM node to which to append these spans, and
7
- // optionally (not needed if you only loaded one parser) a parser
8
- // object.
9
-
10
- // Stuff from util.js that the parsers are using.
11
- var StopIteration = {toString: function() {return "StopIteration"}};
12
-
13
- var Editor = {};
14
- var indentUnit = 2;
15
-
16
- (function(){
17
- function normaliseString(string) {
18
- var tab = "";
19
- for (var i = 0; i < indentUnit; i++) tab += " ";
20
-
21
- string = string.replace(/\t/g, tab).replace(/\u00a0/g, " ").replace(/\r\n?/g, "\n");
22
- var pos = 0, parts = [], lines = string.split("\n");
23
- for (var line = 0; line < lines.length; line++) {
24
- if (line != 0) parts.push("\n");
25
- parts.push(lines[line]);
26
- }
27
-
28
- return {
29
- next: function() {
30
- if (pos < parts.length) return parts[pos++];
31
- else throw StopIteration;
32
- }
33
- };
34
- }
35
-
36
- window.highlightText = function(string, callback, parser) {
37
- parser = (parser || Editor.Parser).make(stringStream(normaliseString(string)));
38
- var line = [];
39
- if (callback.nodeType == 1) {
40
- var node = callback;
41
- callback = function(line) {
42
- for (var i = 0; i < line.length; i++)
43
- node.appendChild(line[i]);
44
- node.appendChild(document.createElement("br"));
45
- };
46
- }
47
-
48
- try {
49
- while (true) {
50
- var token = parser.next();
51
- if (token.value == "\n") {
52
- callback(line);
53
- line = [];
54
- }
55
- else {
56
- var span = document.createElement("span");
57
- span.className = token.style;
58
- span.appendChild(document.createTextNode(token.value));
59
- line.push(span);
60
- }
61
- }
62
- }
63
- catch (e) {
64
- if (e != StopIteration) throw e;
65
- }
66
- if (line.length) callback(line);
67
- }
68
- })();
@@ -1,126 +0,0 @@
1
- /* Simple parser for Smalltalk */
2
-
3
- var SmalltalkParser = (function() {
4
- var tokenizeSmalltalk = (function() {
5
- var identifierTest = /[A-Za-z0-9_]/;
6
- function normal(source, setState) {
7
- var char = source.next();
8
- if (char == ' ' || char == '\t') {
9
- return 'whitespace';
10
- }
11
- if (char == '\n') {
12
- return 'newline';
13
- }
14
- if (/[A-Za-z]/.test(char) || (char == '_' && identifierTest.test(source.peek()))) {
15
- source.nextWhileMatches(identifierTest);
16
- if (!source.endOfLine() && source.peek() == ':') {
17
- source.next();
18
- return 'st-keyword';
19
- }
20
- return 'st-identifier';
21
- }
22
- if (char == '$') {
23
- if (source.endOfLine()) return 'st-error';
24
- source.next();
25
- return 'st-character';
26
- }
27
- if (char == '^') {
28
- return 'st-return';
29
- }
30
- else if (char == "'") {
31
- setState(inString("'", 'st-string'));
32
- return null;
33
- }
34
- else if (char == '"') {
35
- setState(inString('"', 'st-comment'));
36
- return null;
37
- }
38
- else if (char == '#') {
39
- if (source.endOfLine()) return 'st-error';
40
- char = source.next();
41
- if (char == "'") {
42
- setState(inString("'", 'st-symbol'));
43
- return null;
44
- } else {
45
- if (/[A-Za-z]/.test(char) || (char == '_' && identifierTest.test(source.peek()))) {
46
- source.nextWhileMatches(/[A-Za-z0-9_:]/);
47
- return 'st-symbol';
48
- }
49
- }
50
- return 'st-error';
51
- }
52
- return 'st-other';
53
- }
54
-
55
- function inString(endChar, styleClass) {
56
- return function(source, setState) {
57
- while (true) {
58
- if (source.endOfLine())
59
- return styleClass;
60
- if (source.next() == endChar) {
61
- if (!source.endOfLine() && source.peek() == endChar)
62
- source.next();
63
- else
64
- break;
65
- }
66
- }
67
- setState(normal);
68
- return styleClass;
69
- }
70
- }
71
- return function(source, startState) {
72
- return tokenizer(source, startState || normal);
73
- };
74
- })();
75
- function parseSmalltalk(source, basecolumn) {
76
- var tokens = tokenizeSmalltalk(source);
77
- var iter = {
78
- next: function() {
79
- var token = tokens.next()
80
- , style = token.style
81
- , content = token.content
82
- ;
83
- if (style == 'newline') {
84
- token['indentation'] = function(text, current, direction) { };
85
- return token;
86
- }
87
- if (style == 'st-identifier') {
88
- if (content == 'true' || content == 'false') {
89
- token.style = 'st-boolean';
90
- return token;
91
- }
92
- if (content == 'self') {
93
- token.style = 'st-self';
94
- return token;
95
- }
96
- if (content == 'super') {
97
- token.style = 'st-super';
98
- return token;
99
- }
100
- if (content == 'nil') {
101
- token.style = 'st-nil';
102
- return token;
103
- }
104
- if (content.substring(0,1) == content.substring(0,1).toUpperCase()) {
105
- token.style = 'st-global';
106
- return token;
107
- }
108
- }
109
- return token;
110
- },
111
- copy: function() {
112
- var _tokenState = tokens.state;
113
- return function(source) {
114
- tokens = tokenizeSmalltalk(source, _tokenState);
115
- return iter;
116
- };
117
- }
118
- };
119
- return iter;
120
- }
121
- return { make: parseSmalltalk };
122
- })();
123
-
124
- if (Editor) {
125
- Editor.Parser = SmalltalkParser;
126
- }
@@ -1,32 +0,0 @@
1
- var DummyParser = Editor.Parser = (function() {
2
- function tokenizeDummy(source) {
3
- while (!source.endOfLine()) source.next();
4
- return "text";
5
- }
6
- function parseDummy(source) {
7
- function indentTo(n) {return function() {return n;}}
8
- source = tokenizer(source, tokenizeDummy);
9
- var space = 0;
10
-
11
- var iter = {
12
- next: function() {
13
- var tok = source.next();
14
- if (tok.type == "whitespace") {
15
- if (tok.value == "\n") tok.indentation = indentTo(space);
16
- else space = tok.value.length;
17
- }
18
- return tok;
19
- },
20
- copy: function() {
21
- var _space = space;
22
- return function(_source) {
23
- space = _space;
24
- source = tokenizer(_source, tokenizeDummy);
25
- return iter;
26
- };
27
- }
28
- };
29
- return iter;
30
- }
31
- return {make: parseDummy};
32
- })();
@@ -1,699 +0,0 @@
1
- /* Functionality for finding, storing, and restoring selections
2
- *
3
- * This does not provide a generic API, just the minimal functionality
4
- * required by the CodeMirror system.
5
- */
6
-
7
- // Namespace object.
8
- var select = {};
9
-
10
- (function() {
11
- select.ie_selection = document.selection && document.selection.createRangeCollection;
12
-
13
- // Find the 'top-level' (defined as 'a direct child of the node
14
- // passed as the top argument') node that the given node is
15
- // contained in. Return null if the given node is not inside the top
16
- // node.
17
- function topLevelNodeAt(node, top) {
18
- while (node && node.parentNode != top)
19
- node = node.parentNode;
20
- return node;
21
- }
22
-
23
- // Find the top-level node that contains the node before this one.
24
- function topLevelNodeBefore(node, top) {
25
- while (!node.previousSibling && node.parentNode != top)
26
- node = node.parentNode;
27
- return topLevelNodeAt(node.previousSibling, top);
28
- }
29
-
30
- var fourSpaces = "\u00a0\u00a0\u00a0\u00a0";
31
-
32
- select.scrollToNode = function(node, cursor) {
33
- if (!node) return;
34
- var element = node, body = document.body,
35
- html = document.documentElement,
36
- atEnd = !element.nextSibling || !element.nextSibling.nextSibling
37
- || !element.nextSibling.nextSibling.nextSibling;
38
- // In Opera (and recent Webkit versions), BR elements *always*
39
- // have a offsetTop property of zero.
40
- var compensateHack = 0;
41
- while (element && !element.offsetTop) {
42
- compensateHack++;
43
- element = element.previousSibling;
44
- }
45
- // atEnd is another kludge for these browsers -- if the cursor is
46
- // at the end of the document, and the node doesn't have an
47
- // offset, just scroll to the end.
48
- if (compensateHack == 0) atEnd = false;
49
-
50
- // WebKit has a bad habit of (sometimes) happily returning bogus
51
- // offsets when the document has just been changed. This seems to
52
- // always be 5/5, so we don't use those.
53
- if (webkit && element && element.offsetTop == 5 && element.offsetLeft == 5)
54
- return;
55
-
56
- var y = compensateHack * (element ? element.offsetHeight : 0), x = 0,
57
- width = (node ? node.offsetWidth : 0), pos = element;
58
- while (pos && pos.offsetParent) {
59
- y += pos.offsetTop;
60
- // Don't count X offset for <br> nodes
61
- if (!isBR(pos))
62
- x += pos.offsetLeft;
63
- pos = pos.offsetParent;
64
- }
65
-
66
- var scroll_x = body.scrollLeft || html.scrollLeft || 0,
67
- scroll_y = body.scrollTop || html.scrollTop || 0,
68
- scroll = false, screen_width = window.innerWidth || html.clientWidth || 0;
69
-
70
- if (cursor || width < screen_width) {
71
- if (cursor) {
72
- var off = select.offsetInNode(node), size = nodeText(node).length;
73
- if (size) x += width * (off / size);
74
- }
75
- var screen_x = x - scroll_x;
76
- if (screen_x < 0 || screen_x > screen_width) {
77
- scroll_x = x;
78
- scroll = true;
79
- }
80
- }
81
- var screen_y = y - scroll_y;
82
- if (screen_y < 0 || atEnd || screen_y > (window.innerHeight || html.clientHeight || 0) - 50) {
83
- scroll_y = atEnd ? 1e6 : y;
84
- scroll = true;
85
- }
86
- if (scroll) window.scrollTo(scroll_x, scroll_y);
87
- };
88
-
89
- select.scrollToCursor = function(container) {
90
- select.scrollToNode(select.selectionTopNode(container, true) || container.firstChild, true);
91
- };
92
-
93
- // Used to prevent restoring a selection when we do not need to.
94
- var currentSelection = null;
95
-
96
- select.snapshotChanged = function() {
97
- if (currentSelection) currentSelection.changed = true;
98
- };
99
-
100
- // Find the 'leaf' node (BR or text) after the given one.
101
- function baseNodeAfter(node) {
102
- var next = node.nextSibling;
103
- if (next) {
104
- while (next.firstChild) next = next.firstChild;
105
- if (next.nodeType == 3 || isBR(next)) return next;
106
- else return baseNodeAfter(next);
107
- }
108
- else {
109
- var parent = node.parentNode;
110
- while (parent && !parent.nextSibling) parent = parent.parentNode;
111
- return parent && baseNodeAfter(parent);
112
- }
113
- }
114
-
115
- // This is called by the code in editor.js whenever it is replacing
116
- // a text node. The function sees whether the given oldNode is part
117
- // of the current selection, and updates this selection if it is.
118
- // Because nodes are often only partially replaced, the length of
119
- // the part that gets replaced has to be taken into account -- the
120
- // selection might stay in the oldNode if the newNode is smaller
121
- // than the selection's offset. The offset argument is needed in
122
- // case the selection does move to the new object, and the given
123
- // length is not the whole length of the new node (part of it might
124
- // have been used to replace another node).
125
- select.snapshotReplaceNode = function(from, to, length, offset) {
126
- if (!currentSelection) return;
127
-
128
- function replace(point) {
129
- if (from == point.node) {
130
- currentSelection.changed = true;
131
- if (length && point.offset > length) {
132
- point.offset -= length;
133
- }
134
- else {
135
- point.node = to;
136
- point.offset += (offset || 0);
137
- }
138
- }
139
- else if (select.ie_selection && point.offset == 0 && point.node == baseNodeAfter(from)) {
140
- currentSelection.changed = true;
141
- }
142
- }
143
- replace(currentSelection.start);
144
- replace(currentSelection.end);
145
- };
146
-
147
- select.snapshotMove = function(from, to, distance, relative, ifAtStart) {
148
- if (!currentSelection) return;
149
-
150
- function move(point) {
151
- if (from == point.node && (!ifAtStart || point.offset == 0)) {
152
- currentSelection.changed = true;
153
- point.node = to;
154
- if (relative) point.offset = Math.max(0, point.offset + distance);
155
- else point.offset = distance;
156
- }
157
- }
158
- move(currentSelection.start);
159
- move(currentSelection.end);
160
- };
161
-
162
- // Most functions are defined in two ways, one for the IE selection
163
- // model, one for the W3C one.
164
- if (select.ie_selection) {
165
- function selRange() {
166
- var sel = document.selection;
167
- if (!sel) return null;
168
- if (sel.createRange) return sel.createRange();
169
- else return sel.createTextRange();
170
- }
171
-
172
- function selectionNode(start) {
173
- var range = selRange();
174
- range.collapse(start);
175
-
176
- function nodeAfter(node) {
177
- var found = null;
178
- while (!found && node) {
179
- found = node.nextSibling;
180
- node = node.parentNode;
181
- }
182
- return nodeAtStartOf(found);
183
- }
184
-
185
- function nodeAtStartOf(node) {
186
- while (node && node.firstChild) node = node.firstChild;
187
- return {node: node, offset: 0};
188
- }
189
-
190
- var containing = range.parentElement();
191
- if (!isAncestor(document.body, containing)) return null;
192
- if (!containing.firstChild) return nodeAtStartOf(containing);
193
-
194
- var working = range.duplicate();
195
- working.moveToElementText(containing);
196
- working.collapse(true);
197
- for (var cur = containing.firstChild; cur; cur = cur.nextSibling) {
198
- if (cur.nodeType == 3) {
199
- var size = cur.nodeValue.length;
200
- working.move("character", size);
201
- }
202
- else {
203
- working.moveToElementText(cur);
204
- working.collapse(false);
205
- }
206
-
207
- var dir = range.compareEndPoints("StartToStart", working);
208
- if (dir == 0) return nodeAfter(cur);
209
- if (dir == 1) continue;
210
- if (cur.nodeType != 3) return nodeAtStartOf(cur);
211
-
212
- working.setEndPoint("StartToEnd", range);
213
- return {node: cur, offset: size - working.text.length};
214
- }
215
- return nodeAfter(containing);
216
- }
217
-
218
- select.markSelection = function() {
219
- currentSelection = null;
220
- var sel = document.selection;
221
- if (!sel) return;
222
- var start = selectionNode(true),
223
- end = selectionNode(false);
224
- if (!start || !end) return;
225
- currentSelection = {start: start, end: end, changed: false};
226
- };
227
-
228
- select.selectMarked = function() {
229
- if (!currentSelection || !currentSelection.changed) return;
230
-
231
- function makeRange(point) {
232
- var range = document.body.createTextRange(),
233
- node = point.node;
234
- if (!node) {
235
- range.moveToElementText(document.body);
236
- range.collapse(false);
237
- }
238
- else if (node.nodeType == 3) {
239
- range.moveToElementText(node.parentNode);
240
- var offset = point.offset;
241
- while (node.previousSibling) {
242
- node = node.previousSibling;
243
- offset += (node.innerText || "").length;
244
- }
245
- range.move("character", offset);
246
- }
247
- else {
248
- range.moveToElementText(node);
249
- range.collapse(true);
250
- }
251
- return range;
252
- }
253
-
254
- var start = makeRange(currentSelection.start), end = makeRange(currentSelection.end);
255
- start.setEndPoint("StartToEnd", end);
256
- start.select();
257
- };
258
-
259
- select.offsetInNode = function(node) {
260
- var range = selRange();
261
- if (!range) return 0;
262
- var range2 = range.duplicate();
263
- try {range2.moveToElementText(node);} catch(e){return 0;}
264
- range.setEndPoint("StartToStart", range2);
265
- return range.text.length;
266
- };
267
-
268
- // Get the top-level node that one end of the cursor is inside or
269
- // after. Note that this returns false for 'no cursor', and null
270
- // for 'start of document'.
271
- select.selectionTopNode = function(container, start) {
272
- var range = selRange();
273
- if (!range) return false;
274
- var range2 = range.duplicate();
275
- range.collapse(start);
276
- var around = range.parentElement();
277
- if (around && isAncestor(container, around)) {
278
- // Only use this node if the selection is not at its start.
279
- range2.moveToElementText(around);
280
- if (range.compareEndPoints("StartToStart", range2) == 1)
281
- return topLevelNodeAt(around, container);
282
- }
283
-
284
- // Move the start of a range to the start of a node,
285
- // compensating for the fact that you can't call
286
- // moveToElementText with text nodes.
287
- function moveToNodeStart(range, node) {
288
- if (node.nodeType == 3) {
289
- var count = 0, cur = node.previousSibling;
290
- while (cur && cur.nodeType == 3) {
291
- count += cur.nodeValue.length;
292
- cur = cur.previousSibling;
293
- }
294
- if (cur) {
295
- try{range.moveToElementText(cur);}
296
- catch(e){return false;}
297
- range.collapse(false);
298
- }
299
- else range.moveToElementText(node.parentNode);
300
- if (count) range.move("character", count);
301
- }
302
- else {
303
- try{range.moveToElementText(node);}
304
- catch(e){return false;}
305
- }
306
- return true;
307
- }
308
-
309
- // Do a binary search through the container object, comparing
310
- // the start of each node to the selection
311
- var start = 0, end = container.childNodes.length - 1;
312
- while (start < end) {
313
- var middle = Math.ceil((end + start) / 2), node = container.childNodes[middle];
314
- if (!node) return false; // Don't ask. IE6 manages this sometimes.
315
- if (!moveToNodeStart(range2, node)) return false;
316
- if (range.compareEndPoints("StartToStart", range2) == 1)
317
- start = middle;
318
- else
319
- end = middle - 1;
320
- }
321
-
322
- if (start == 0) {
323
- var test1 = selRange(), test2 = test1.duplicate();
324
- try {
325
- test2.moveToElementText(container);
326
- } catch(exception) {
327
- return null;
328
- }
329
- if (test1.compareEndPoints("StartToStart", test2) == 0)
330
- return null;
331
- }
332
- return container.childNodes[start] || null;
333
- };
334
-
335
- // Place the cursor after this.start. This is only useful when
336
- // manually moving the cursor instead of restoring it to its old
337
- // position.
338
- select.focusAfterNode = function(node, container) {
339
- var range = document.body.createTextRange();
340
- range.moveToElementText(node || container);
341
- range.collapse(!node);
342
- range.select();
343
- };
344
-
345
- select.somethingSelected = function() {
346
- var range = selRange();
347
- return range && (range.text != "");
348
- };
349
-
350
- function insertAtCursor(html) {
351
- var range = selRange();
352
- if (range) {
353
- range.pasteHTML(html);
354
- range.collapse(false);
355
- range.select();
356
- }
357
- }
358
-
359
- // Used to normalize the effect of the enter key, since browsers
360
- // do widely different things when pressing enter in designMode.
361
- select.insertNewlineAtCursor = function() {
362
- insertAtCursor("<br>");
363
- };
364
-
365
- select.insertTabAtCursor = function() {
366
- insertAtCursor(fourSpaces);
367
- };
368
-
369
- // Get the BR node at the start of the line on which the cursor
370
- // currently is, and the offset into the line. Returns null as
371
- // node if cursor is on first line.
372
- select.cursorPos = function(container, start) {
373
- var range = selRange();
374
- if (!range) return null;
375
-
376
- var topNode = select.selectionTopNode(container, start);
377
- while (topNode && !isBR(topNode))
378
- topNode = topNode.previousSibling;
379
-
380
- var range2 = range.duplicate();
381
- range.collapse(start);
382
- if (topNode) {
383
- range2.moveToElementText(topNode);
384
- range2.collapse(false);
385
- }
386
- else {
387
- // When nothing is selected, we can get all kinds of funky errors here.
388
- try { range2.moveToElementText(container); }
389
- catch (e) { return null; }
390
- range2.collapse(true);
391
- }
392
- range.setEndPoint("StartToStart", range2);
393
-
394
- return {node: topNode, offset: range.text.length};
395
- };
396
-
397
- select.setCursorPos = function(container, from, to) {
398
- function rangeAt(pos) {
399
- var range = document.body.createTextRange();
400
- if (!pos.node) {
401
- range.moveToElementText(container);
402
- range.collapse(true);
403
- }
404
- else {
405
- range.moveToElementText(pos.node);
406
- range.collapse(false);
407
- }
408
- range.move("character", pos.offset);
409
- return range;
410
- }
411
-
412
- var range = rangeAt(from);
413
- if (to && to != from)
414
- range.setEndPoint("EndToEnd", rangeAt(to));
415
- range.select();
416
- }
417
-
418
- // Some hacks for storing and re-storing the selection when the editor loses and regains focus.
419
- select.getBookmark = function (container) {
420
- var from = select.cursorPos(container, true), to = select.cursorPos(container, false);
421
- if (from && to) return {from: from, to: to};
422
- };
423
-
424
- // Restore a stored selection.
425
- select.setBookmark = function(container, mark) {
426
- if (!mark) return;
427
- select.setCursorPos(container, mark.from, mark.to);
428
- };
429
- }
430
- // W3C model
431
- else {
432
- // Find the node right at the cursor, not one of its
433
- // ancestors with a suitable offset. This goes down the DOM tree
434
- // until a 'leaf' is reached (or is it *up* the DOM tree?).
435
- function innerNode(node, offset) {
436
- while (node.nodeType != 3 && !isBR(node)) {
437
- var newNode = node.childNodes[offset] || node.nextSibling;
438
- offset = 0;
439
- while (!newNode && node.parentNode) {
440
- node = node.parentNode;
441
- newNode = node.nextSibling;
442
- }
443
- node = newNode;
444
- if (!newNode) break;
445
- }
446
- return {node: node, offset: offset};
447
- }
448
-
449
- // Store start and end nodes, and offsets within these, and refer
450
- // back to the selection object from those nodes, so that this
451
- // object can be updated when the nodes are replaced before the
452
- // selection is restored.
453
- select.markSelection = function () {
454
- var selection = window.getSelection();
455
- if (!selection || selection.rangeCount == 0)
456
- return (currentSelection = null);
457
- var range = selection.getRangeAt(0);
458
-
459
- currentSelection = {
460
- start: innerNode(range.startContainer, range.startOffset),
461
- end: innerNode(range.endContainer, range.endOffset),
462
- changed: false
463
- };
464
- };
465
-
466
- select.selectMarked = function () {
467
- var cs = currentSelection;
468
- // on webkit-based browsers, it is apparently possible that the
469
- // selection gets reset even when a node that is not one of the
470
- // endpoints get messed with. the most common situation where
471
- // this occurs is when a selection is deleted or overwitten. we
472
- // check for that here.
473
- function focusIssue() {
474
- if (cs.start.node == cs.end.node && cs.start.offset == cs.end.offset) {
475
- var selection = window.getSelection();
476
- if (!selection || selection.rangeCount == 0) return true;
477
- var range = selection.getRangeAt(0), point = innerNode(range.startContainer, range.startOffset);
478
- return cs.start.node != point.node || cs.start.offset != point.offset;
479
- }
480
- }
481
- if (!cs || !(cs.changed || (webkit && focusIssue()))) return;
482
- var range = document.createRange();
483
-
484
- function setPoint(point, which) {
485
- if (point.node) {
486
- // Some magic to generalize the setting of the start and end
487
- // of a range.
488
- if (point.offset == 0)
489
- range["set" + which + "Before"](point.node);
490
- else
491
- range["set" + which](point.node, point.offset);
492
- }
493
- else {
494
- range.setStartAfter(document.body.lastChild || document.body);
495
- }
496
- }
497
-
498
- setPoint(cs.end, "End");
499
- setPoint(cs.start, "Start");
500
- selectRange(range);
501
- };
502
-
503
- // Helper for selecting a range object.
504
- function selectRange(range) {
505
- var selection = window.getSelection();
506
- if (!selection) return;
507
- selection.removeAllRanges();
508
- selection.addRange(range);
509
- }
510
- function selectionRange() {
511
- var selection = window.getSelection();
512
- if (!selection || selection.rangeCount == 0)
513
- return false;
514
- else
515
- return selection.getRangeAt(0);
516
- }
517
-
518
- // Finding the top-level node at the cursor in the W3C is, as you
519
- // can see, quite an involved process.
520
- select.selectionTopNode = function(container, start) {
521
- var range = selectionRange();
522
- if (!range) return false;
523
-
524
- var node = start ? range.startContainer : range.endContainer;
525
- var offset = start ? range.startOffset : range.endOffset;
526
- // Work around (yet another) bug in Opera's selection model.
527
- if (window.opera && !start && range.endContainer == container && range.endOffset == range.startOffset + 1 &&
528
- container.childNodes[range.startOffset] && isBR(container.childNodes[range.startOffset]))
529
- offset--;
530
-
531
- // For text nodes, we look at the node itself if the cursor is
532
- // inside, or at the node before it if the cursor is at the
533
- // start.
534
- if (node.nodeType == 3){
535
- if (offset > 0)
536
- return topLevelNodeAt(node, container);
537
- else
538
- return topLevelNodeBefore(node, container);
539
- }
540
- // Occasionally, browsers will return the HTML node as
541
- // selection. If the offset is 0, we take the start of the frame
542
- // ('after null'), otherwise, we take the last node.
543
- else if (node.nodeName.toUpperCase() == "HTML") {
544
- return (offset == 1 ? null : container.lastChild);
545
- }
546
- // If the given node is our 'container', we just look up the
547
- // correct node by using the offset.
548
- else if (node == container) {
549
- return (offset == 0) ? null : node.childNodes[offset - 1];
550
- }
551
- // In any other case, we have a regular node. If the cursor is
552
- // at the end of the node, we use the node itself, if it is at
553
- // the start, we use the node before it, and in any other
554
- // case, we look up the child before the cursor and use that.
555
- else {
556
- if (offset == node.childNodes.length)
557
- return topLevelNodeAt(node, container);
558
- else if (offset == 0)
559
- return topLevelNodeBefore(node, container);
560
- else
561
- return topLevelNodeAt(node.childNodes[offset - 1], container);
562
- }
563
- };
564
-
565
- select.focusAfterNode = function(node, container) {
566
- var range = document.createRange();
567
- range.setStartBefore(container.firstChild || container);
568
- // In Opera, setting the end of a range at the end of a line
569
- // (before a BR) will cause the cursor to appear on the next
570
- // line, so we set the end inside of the start node when
571
- // possible.
572
- if (node && !node.firstChild)
573
- range.setEndAfter(node);
574
- else if (node)
575
- range.setEnd(node, node.childNodes.length);
576
- else
577
- range.setEndBefore(container.firstChild || container);
578
- range.collapse(false);
579
- selectRange(range);
580
- };
581
-
582
- select.somethingSelected = function() {
583
- var range = selectionRange();
584
- return range && !range.collapsed;
585
- };
586
-
587
- select.offsetInNode = function(node) {
588
- var range = selectionRange();
589
- if (!range) return 0;
590
- range = range.cloneRange();
591
- range.setStartBefore(node);
592
- return range.toString().length;
593
- };
594
-
595
- select.insertNodeAtCursor = function(node) {
596
- var range = selectionRange();
597
- if (!range) return;
598
-
599
- range.deleteContents();
600
- range.insertNode(node);
601
- webkitLastLineHack(document.body);
602
-
603
- // work around weirdness where Opera will magically insert a new
604
- // BR node when a BR node inside a span is moved around. makes
605
- // sure the BR ends up outside of spans.
606
- if (window.opera && isBR(node) && isSpan(node.parentNode)) {
607
- var next = node.nextSibling, p = node.parentNode, outer = p.parentNode;
608
- outer.insertBefore(node, p.nextSibling);
609
- var textAfter = "";
610
- for (; next && next.nodeType == 3; next = next.nextSibling) {
611
- textAfter += next.nodeValue;
612
- removeElement(next);
613
- }
614
- outer.insertBefore(makePartSpan(textAfter, document), node.nextSibling);
615
- }
616
- range = document.createRange();
617
- range.selectNode(node);
618
- range.collapse(false);
619
- selectRange(range);
620
- }
621
-
622
- select.insertNewlineAtCursor = function() {
623
- select.insertNodeAtCursor(document.createElement("BR"));
624
- };
625
-
626
- select.insertTabAtCursor = function() {
627
- select.insertNodeAtCursor(document.createTextNode(fourSpaces));
628
- };
629
-
630
- select.cursorPos = function(container, start) {
631
- var range = selectionRange();
632
- if (!range) return;
633
-
634
- var topNode = select.selectionTopNode(container, start);
635
- while (topNode && !isBR(topNode))
636
- topNode = topNode.previousSibling;
637
-
638
- range = range.cloneRange();
639
- range.collapse(start);
640
- if (topNode)
641
- range.setStartAfter(topNode);
642
- else
643
- range.setStartBefore(container);
644
-
645
- var text = range.toString();
646
- return {node: topNode, offset: text.length};
647
- };
648
-
649
- select.setCursorPos = function(container, from, to) {
650
- var range = document.createRange();
651
-
652
- function setPoint(node, offset, side) {
653
- if (offset == 0 && node && !node.nextSibling) {
654
- range["set" + side + "After"](node);
655
- return true;
656
- }
657
-
658
- if (!node)
659
- node = container.firstChild;
660
- else
661
- node = node.nextSibling;
662
-
663
- if (!node) return;
664
-
665
- if (offset == 0) {
666
- range["set" + side + "Before"](node);
667
- return true;
668
- }
669
-
670
- var backlog = []
671
- function decompose(node) {
672
- if (node.nodeType == 3)
673
- backlog.push(node);
674
- else
675
- forEach(node.childNodes, decompose);
676
- }
677
- while (true) {
678
- while (node && !backlog.length) {
679
- decompose(node);
680
- node = node.nextSibling;
681
- }
682
- var cur = backlog.shift();
683
- if (!cur) return false;
684
-
685
- var length = cur.nodeValue.length;
686
- if (length >= offset) {
687
- range["set" + side](cur, offset);
688
- return true;
689
- }
690
- offset -= length;
691
- }
692
- }
693
-
694
- to = to || from;
695
- if (setPoint(to.node, to.offset, "End") && setPoint(from.node, from.offset, "Start"))
696
- selectRange(range);
697
- };
698
- }
699
- })();