maglev-database-explorer 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (688) hide show
  1. data/MIT-LICENSE +21 -0
  2. data/README.rdoc +3 -0
  3. data/Rakefile +40 -0
  4. data/app/assets/javascripts/maglev-database-explorer/application.js +17 -0
  5. data/app/assets/javascripts/maglev_database_explorer/def.js +2 -0
  6. data/app/assets/stylesheets/maglev-database-explorer/application.css +13 -0
  7. data/app/assets/stylesheets/maglev_database_explorer/def.css +4 -0
  8. data/app/controllers/maglev_database_explorer/application_controller.rb +4 -0
  9. data/app/controllers/maglev_database_explorer/code_controller.rb +101 -0
  10. data/app/controllers/maglev_database_explorer/object_controller.rb +60 -0
  11. data/app/controllers/maglev_database_explorer/object_explorer_controller.rb +9 -0
  12. data/app/helpers/maglev_database_explorer/application_helper.rb +4 -0
  13. data/app/views/layouts/maglev-database-explorer/application.html.erb +14 -0
  14. data/app/views/maglev_database_explorer/object_explorer/_workspace.html.erb +28 -0
  15. data/app/views/maglev_database_explorer/object_explorer/index.html.erb +92 -0
  16. data/config/routes.rb +15 -0
  17. data/lib/maglev-database-explorer.rb +17 -0
  18. data/lib/maglev-database-explorer/code_evaluation.rb +36 -0
  19. data/lib/maglev-database-explorer/database_views.rb +29 -0
  20. data/lib/maglev-database-explorer/database_views/abstract_dictionary.rb +69 -0
  21. data/lib/maglev-database-explorer/database_views/abstract_exception.rb +25 -0
  22. data/lib/maglev-database-explorer/database_views/array.rb +28 -0
  23. data/lib/maglev-database-explorer/database_views/boolean.rb +12 -0
  24. data/lib/maglev-database-explorer/database_views/class.rb +46 -0
  25. data/lib/maglev-database-explorer/database_views/exception.rb +3 -0
  26. data/lib/maglev-database-explorer/database_views/execblock.rb +5 -0
  27. data/lib/maglev-database-explorer/database_views/fixnum.rb +5 -0
  28. data/lib/maglev-database-explorer/database_views/float.rb +6 -0
  29. data/lib/maglev-database-explorer/database_views/globals.rb +2 -0
  30. data/lib/maglev-database-explorer/database_views/gsnmethod.rb +29 -0
  31. data/lib/maglev-database-explorer/database_views/hash.rb +5 -0
  32. data/lib/maglev-database-explorer/database_views/maglev_record.rb +43 -0
  33. data/lib/maglev-database-explorer/database_views/module.rb +104 -0
  34. data/lib/maglev-database-explorer/database_views/nilclass.rb +6 -0
  35. data/lib/maglev-database-explorer/database_views/object.rb +77 -0
  36. data/lib/maglev-database-explorer/database_views/proc.rb +4 -0
  37. data/lib/maglev-database-explorer/database_views/repository.rb +4 -0
  38. data/lib/maglev-database-explorer/database_views/ruby_workspace.rb +6 -0
  39. data/lib/maglev-database-explorer/database_views/smalltalk_classes.rb +35 -0
  40. data/lib/maglev-database-explorer/database_views/smalltalk_classes.st +60 -0
  41. data/lib/maglev-database-explorer/database_views/string.rb +27 -0
  42. data/lib/maglev-database-explorer/database_views/symbol.rb +33 -0
  43. data/lib/maglev-database-explorer/database_views/system.rb +48 -0
  44. data/lib/maglev-database-explorer/database_views/thread.rb +101 -0
  45. data/lib/maglev-database-explorer/debug_server.rb +22 -0
  46. data/lib/maglev-database-explorer/engine.rb +23 -0
  47. data/lib/maglev-database-explorer/engine_symlinks.rb +19 -0
  48. data/lib/maglev-database-explorer/halt.rb +33 -0
  49. data/lib/maglev-database-explorer/ruby_workspace.rb +31 -0
  50. data/lib/maglev-database-explorer/version.rb +3 -0
  51. data/lib/tasks/maglev-database-explorer_tasks.rake +4 -0
  52. data/public/LICENSE +35 -0
  53. data/public/amber/CHANGELOG +65 -0
  54. data/public/amber/LICENSE +22 -0
  55. data/public/amber/Makefile +53 -0
  56. data/public/amber/README.md +30 -0
  57. data/public/amber/bin/amber +3 -0
  58. data/public/amber/bin/amberc +352 -0
  59. data/public/amber/bin/nodecompile.js +33 -0
  60. data/public/amber/bin/server +3 -0
  61. data/public/amber/bin/server.bat +3 -0
  62. data/public/amber/css/amber-normalize.css +468 -0
  63. data/public/amber/css/amber-normalize.less +501 -0
  64. data/public/amber/css/amber.css +539 -0
  65. data/public/amber/css/documentation.css +84 -0
  66. data/public/amber/css/profstef.css +75 -0
  67. data/public/amber/css/style.css +313 -0
  68. data/public/amber/documentation.html +37 -0
  69. data/public/amber/examples/Makefile +23 -0
  70. data/public/amber/examples/README +4 -0
  71. data/public/amber/examples/android/helloamber/AndroidManifest.xml +19 -0
  72. data/public/amber/examples/android/helloamber/HelloAmber.st +13 -0
  73. data/public/amber/examples/android/helloamber/Makefile +56 -0
  74. data/public/amber/examples/android/helloamber/README.md +80 -0
  75. data/public/amber/examples/android/helloamber/ant.properties +17 -0
  76. data/public/amber/examples/android/helloamber/assets/index.html +15 -0
  77. data/public/amber/examples/android/helloamber/assets/jquery-1.7.2.min.js +4 -0
  78. data/public/amber/examples/android/helloamber/build.xml +83 -0
  79. data/public/amber/examples/android/helloamber/local.properties +10 -0
  80. data/public/amber/examples/android/helloamber/proguard-project.txt +20 -0
  81. data/public/amber/examples/android/helloamber/project.properties +14 -0
  82. data/public/amber/examples/android/helloamber/res/layout/main.xml +6 -0
  83. data/public/amber/examples/android/helloamber/res/values/strings.xml +4 -0
  84. data/public/amber/examples/android/helloamber/src/org/amberlang/android/helloamber/HelloAmber.java +59 -0
  85. data/public/amber/examples/myproject/index.html +16 -0
  86. data/public/amber/examples/nodejs/README +9 -0
  87. data/public/amber/examples/nodejs/benchfib/Benchfib.st +124 -0
  88. data/public/amber/examples/nodejs/benchfib/Makefile +8 -0
  89. data/public/amber/examples/nodejs/benchfib/benchfib +1 -0
  90. data/public/amber/examples/nodejs/hello/Hello.st +9 -0
  91. data/public/amber/examples/nodejs/hello/Makefile +8 -0
  92. data/public/amber/examples/nodejs/hello/README +13 -0
  93. data/public/amber/examples/nodejs/hello/hello +1 -0
  94. data/public/amber/examples/nodejs/meta/Makefile +8 -0
  95. data/public/amber/examples/nodejs/meta/MyScript.st +27 -0
  96. data/public/amber/examples/nodejs/meta/meta +1 -0
  97. data/public/amber/examples/nodejs/pystone/Makefile +8 -0
  98. data/public/amber/examples/nodejs/pystone/Pystone.st +306 -0
  99. data/public/amber/examples/nodejs/pystone/pystone +1 -0
  100. data/public/amber/examples/nodejs/trivialserver/Makefile +8 -0
  101. data/public/amber/examples/nodejs/trivialserver/TrivialServer.st +51 -0
  102. data/public/amber/examples/nodejs/trivialserver/trivial +1 -0
  103. data/public/amber/examples/presentation/esug2011/images/asterix.png +0 -0
  104. data/public/amber/examples/presentation/esug2011/images/background_box.png +0 -0
  105. data/public/amber/examples/presentation/esug2011/images/background_header.png +0 -0
  106. data/public/amber/examples/presentation/esug2011/images/balloon.jpg +0 -0
  107. data/public/amber/examples/presentation/esug2011/images/balloon_header.png +0 -0
  108. data/public/amber/examples/presentation/esug2011/images/devices.jpg +0 -0
  109. data/public/amber/examples/presentation/esug2011/images/enyo.png +0 -0
  110. data/public/amber/examples/presentation/esug2011/images/ide_star_wars.png +0 -0
  111. data/public/amber/examples/presentation/esug2011/images/nodejs.png +0 -0
  112. data/public/amber/examples/presentation/esug2011/images/terminal.png +0 -0
  113. data/public/amber/examples/presentation/esug2011/images/webos.png +0 -0
  114. data/public/amber/examples/presentation/fosdem2012/images/amber.png +0 -0
  115. data/public/amber/examples/presentation/fosdem2012/images/ambrhino.jpg +0 -0
  116. data/public/amber/examples/presentation/fosdem2012/images/nodejs.png +0 -0
  117. data/public/amber/examples/presentation/fosdem2012/images/pharo.png +0 -0
  118. data/public/amber/examples/presentation/fosdem2012/images/php.gif +0 -0
  119. data/public/amber/examples/presentation/fosdem2012/images/rails.png +0 -0
  120. data/public/amber/examples/presentation/fosdem2012/lib/booklet/images/arrow-next.png +0 -0
  121. data/public/amber/examples/presentation/fosdem2012/lib/booklet/images/arrow-prev.png +0 -0
  122. data/public/amber/examples/presentation/fosdem2012/lib/booklet/images/closedhand.cur +0 -0
  123. data/public/amber/examples/presentation/fosdem2012/lib/booklet/images/openhand.cur +0 -0
  124. data/public/amber/examples/presentation/fosdem2012/lib/booklet/images/shadow-top-back.png +0 -0
  125. data/public/amber/examples/presentation/fosdem2012/lib/booklet/images/shadow-top-forward.png +0 -0
  126. data/public/amber/examples/presentation/fosdem2012/lib/booklet/images/shadow.png +0 -0
  127. data/public/amber/examples/presentation/fosdem2012/lib/booklet/jquery.booklet.1.2.0.css +100 -0
  128. data/public/amber/examples/presentation/fosdem2012/lib/booklet/jquery.booklet.1.2.0.js +1232 -0
  129. data/public/amber/examples/presentation/fosdem2012/lib/booklet/jquery.booklet.1.2.0.min.js +13 -0
  130. data/public/amber/examples/presentation/fosdem2012/lib/booklet/jquery.easing.1.3.js +38 -0
  131. data/public/amber/examples/presentation/index.html +17 -0
  132. data/public/amber/examples/presentation/js/Presentation.deploy.js +1922 -0
  133. data/public/amber/examples/presentation/js/Presentation.js +2712 -0
  134. data/public/amber/examples/presentation/st/Presentation.st +1996 -0
  135. data/public/amber/examples/trysmalltalk/index.html +18 -0
  136. data/public/amber/examples/trysmalltalk/js/TrySmalltalk.deploy.js +837 -0
  137. data/public/amber/examples/trysmalltalk/js/TrySmalltalk.js +1206 -0
  138. data/public/amber/examples/trysmalltalk/st/TrySmalltalk.st +964 -0
  139. data/public/amber/examples/twitterwall/css/twitterwall.css +19 -0
  140. data/public/amber/examples/twitterwall/index.html +35 -0
  141. data/public/amber/examples/twitterwall/js/TwitterWall.deploy.js +116 -0
  142. data/public/amber/examples/twitterwall/js/TwitterWall.js +146 -0
  143. data/public/amber/examples/twitterwall/st/TwitterWall.st +91 -0
  144. data/public/amber/examples/webos/README +11 -0
  145. data/public/amber/examples/webos/eris/DuckQwaq.wav +0 -0
  146. data/public/amber/examples/webos/eris/EnyoAmber.st +36 -0
  147. data/public/amber/examples/webos/eris/Eris.css +0 -0
  148. data/public/amber/examples/webos/eris/Eris.st +86 -0
  149. data/public/amber/examples/webos/eris/Makefile +37 -0
  150. data/public/amber/examples/webos/eris/README +3 -0
  151. data/public/amber/examples/webos/eris/appinfo.json +10 -0
  152. data/public/amber/examples/webos/eris/depends.js +4 -0
  153. data/public/amber/examples/webos/eris/index.html +12 -0
  154. data/public/amber/examples/webos/helloamber/EnyoAmber.st +36 -0
  155. data/public/amber/examples/webos/helloamber/HelloAmber.st +86 -0
  156. data/public/amber/examples/webos/helloamber/Makefile +38 -0
  157. data/public/amber/examples/webos/helloamber/README +5 -0
  158. data/public/amber/examples/webos/helloamber/appinfo.json +10 -0
  159. data/public/amber/examples/webos/helloamber/depends.js +3 -0
  160. data/public/amber/examples/webos/helloamber/index.html +12 -0
  161. data/public/amber/favicon.ico +0 -0
  162. data/public/amber/images/amber.png +0 -0
  163. data/public/amber/images/amber.svg +706 -0
  164. data/public/amber/images/amber_small.png +0 -0
  165. data/public/amber/images/off.amber.png +0 -0
  166. data/public/amber/images/off.png +0 -0
  167. data/public/amber/images/offHover.amber.png +0 -0
  168. data/public/amber/images/offHover.png +0 -0
  169. data/public/amber/images/presentation.png +0 -0
  170. data/public/amber/images/profstef.png +0 -0
  171. data/public/amber/images/sprite.amber.png +0 -0
  172. data/public/amber/images/sprite.png +0 -0
  173. data/public/amber/images/tinylogo.amber.png +0 -0
  174. data/public/amber/images/tinylogo.png +0 -0
  175. data/public/amber/images/twitterwall.png +0 -0
  176. data/public/amber/index.html +55 -0
  177. data/public/amber/js/Additional-Examples.deploy.js +15 -0
  178. data/public/amber/js/Additional-Examples.js +21 -0
  179. data/public/amber/js/Benchfib.deploy.js +132 -0
  180. data/public/amber/js/Benchfib.js +167 -0
  181. data/public/amber/js/Canvas.deploy.js +2446 -0
  182. data/public/amber/js/Canvas.js +3547 -0
  183. data/public/amber/js/Compiler-Tests.deploy.js +97 -0
  184. data/public/amber/js/Compiler-Tests.js +137 -0
  185. data/public/amber/js/Compiler.deploy.js +1877 -0
  186. data/public/amber/js/Compiler.js +2622 -0
  187. data/public/amber/js/Documentation.deploy.js +961 -0
  188. data/public/amber/js/Documentation.js +1376 -0
  189. data/public/amber/js/Examples.deploy.js +53 -0
  190. data/public/amber/js/Examples.js +73 -0
  191. data/public/amber/js/IDE.deploy.js +3557 -0
  192. data/public/amber/js/IDE.js +5002 -0
  193. data/public/amber/js/Kernel-Announcements.deploy.js +107 -0
  194. data/public/amber/js/Kernel-Announcements.js +152 -0
  195. data/public/amber/js/Kernel-Classes.deploy.js +774 -0
  196. data/public/amber/js/Kernel-Classes.js +1095 -0
  197. data/public/amber/js/Kernel-Collections.deploy.js +3121 -0
  198. data/public/amber/js/Kernel-Collections.js +4427 -0
  199. data/public/amber/js/Kernel-Exceptions.deploy.js +244 -0
  200. data/public/amber/js/Kernel-Exceptions.js +349 -0
  201. data/public/amber/js/Kernel-Methods.deploy.js +573 -0
  202. data/public/amber/js/Kernel-Methods.js +807 -0
  203. data/public/amber/js/Kernel-Objects.deploy.js +2877 -0
  204. data/public/amber/js/Kernel-Objects.js +4107 -0
  205. data/public/amber/js/Kernel-Tests.deploy.js +1513 -0
  206. data/public/amber/js/Kernel-Tests.js +2053 -0
  207. data/public/amber/js/Kernel-Transcript.deploy.js +142 -0
  208. data/public/amber/js/Kernel-Transcript.js +202 -0
  209. data/public/amber/js/Maglev-Core.deploy.js +2967 -0
  210. data/public/amber/js/Maglev-Core.js +4202 -0
  211. data/public/amber/js/Maglev-Database-Explorer.deploy.js +4426 -0
  212. data/public/amber/js/Maglev-Database-Explorer.js +6162 -0
  213. data/public/amber/js/Maglev-Vendor.deploy.js +350 -0
  214. data/public/amber/js/Maglev-Vendor.js +465 -0
  215. data/public/amber/js/README.md +5 -0
  216. data/public/amber/js/SUnit.deploy.js +351 -0
  217. data/public/amber/js/SUnit.js +501 -0
  218. data/public/amber/js/amber.js +273 -0
  219. data/public/amber/js/boot.js +602 -0
  220. data/public/amber/js/compat.js +22 -0
  221. data/public/amber/js/init.js +9 -0
  222. data/public/amber/js/lib/CodeMirror/LICENSE +19 -0
  223. data/public/amber/js/lib/CodeMirror/active-line.js +39 -0
  224. data/public/amber/js/lib/CodeMirror/amber.css +21 -0
  225. data/public/amber/js/lib/CodeMirror/codemirror.css +67 -0
  226. data/public/amber/js/lib/CodeMirror/codemirror.js +2144 -0
  227. data/public/amber/js/lib/CodeMirror/smalltalk.js +134 -0
  228. data/public/amber/js/lib/jQuery/jquery-1.4.4.min.js +167 -0
  229. data/public/amber/js/lib/jQuery/jquery-1.6.4.min.js +4 -0
  230. data/public/amber/js/lib/jQuery/jquery-ui-1.8.16.custom.min.js +791 -0
  231. data/public/amber/js/lib/jQuery/jquery.textarea.js +267 -0
  232. data/public/amber/js/lib/peg-0.6.2.min.js +2 -0
  233. data/public/amber/js/lib/showdown.js +419 -0
  234. data/public/amber/js/parser.js +4222 -0
  235. data/public/amber/js/parser.pegjs +223 -0
  236. data/public/amber/learn.html +40 -0
  237. data/public/amber/repl/Makefile +8 -0
  238. data/public/amber/repl/REPL.js +124 -0
  239. data/public/amber/repl/REPL.st +56 -0
  240. data/public/amber/repl/amber.js +18085 -0
  241. data/public/amber/server/FileServer.st +576 -0
  242. data/public/amber/server/Makefile +8 -0
  243. data/public/amber/server/server.js +13049 -0
  244. data/public/amber/st/Benchfib.st +124 -0
  245. data/public/amber/st/Canvas.st +968 -0
  246. data/public/amber/st/Compiler-Tests.st +471 -0
  247. data/public/amber/st/Compiler.st +1445 -0
  248. data/public/amber/st/Documentation.st +758 -0
  249. data/public/amber/st/Examples.st +38 -0
  250. data/public/amber/st/IDE.st +2404 -0
  251. data/public/amber/st/Kernel-Announcements.st +61 -0
  252. data/public/amber/st/Kernel-Classes.st +462 -0
  253. data/public/amber/st/Kernel-Collections.st +1611 -0
  254. data/public/amber/st/Kernel-Exceptions.st +124 -0
  255. data/public/amber/st/Kernel-Methods.st +291 -0
  256. data/public/amber/st/Kernel-Objects.st +1587 -0
  257. data/public/amber/st/Kernel-Tests.st +953 -0
  258. data/public/amber/st/Kernel-Transcript.st +70 -0
  259. data/public/amber/st/Maglev-Core.st +1659 -0
  260. data/public/amber/st/Maglev-Database-Explorer.st +3085 -0
  261. data/public/amber/st/Maglev-Vendor.st +213 -0
  262. data/public/amber/st/Makefile +104 -0
  263. data/public/amber/st/README.md +4 -0
  264. data/public/amber/st/SUnit.st +172 -0
  265. data/public/css/bootstrap-combined.no-icons.min.css +731 -0
  266. data/public/css/bootstrap.css +6811 -0
  267. data/public/css/jquery-ui.min.css +5 -0
  268. data/public/css/smalltalk_code.css +42 -0
  269. data/public/css/style.css +209 -0
  270. data/public/images/maglev-logo.gif +0 -0
  271. data/public/images/rails_tiny.png +0 -0
  272. data/public/images/ruby.png +0 -0
  273. data/public/images/ruby_smalltalk_bridge.png +0 -0
  274. data/public/images/smalltalk.png +0 -0
  275. data/public/libs/bootstrap.min.js +7 -0
  276. data/public/libs/codemirror/CONTRIBUTING.md +72 -0
  277. data/public/libs/codemirror/LICENSE +23 -0
  278. data/public/libs/codemirror/README.md +11 -0
  279. data/public/libs/codemirror/addon/dialog/dialog.css +32 -0
  280. data/public/libs/codemirror/addon/dialog/dialog.js +80 -0
  281. data/public/libs/codemirror/addon/display/placeholder.js +54 -0
  282. data/public/libs/codemirror/addon/edit/closebrackets.js +54 -0
  283. data/public/libs/codemirror/addon/edit/closetag.js +86 -0
  284. data/public/libs/codemirror/addon/edit/continuecomment.js +44 -0
  285. data/public/libs/codemirror/addon/edit/continuelist.js +25 -0
  286. data/public/libs/codemirror/addon/edit/matchbrackets.js +82 -0
  287. data/public/libs/codemirror/addon/fold/brace-fold.js +31 -0
  288. data/public/libs/codemirror/addon/fold/foldcode.js +32 -0
  289. data/public/libs/codemirror/addon/fold/indent-fold.js +11 -0
  290. data/public/libs/codemirror/addon/fold/xml-fold.js +64 -0
  291. data/public/libs/codemirror/addon/hint/html-hint.js +582 -0
  292. data/public/libs/codemirror/addon/hint/javascript-hint.js +142 -0
  293. data/public/libs/codemirror/addon/hint/pig-hint.js +117 -0
  294. data/public/libs/codemirror/addon/hint/python-hint.js +93 -0
  295. data/public/libs/codemirror/addon/hint/show-hint.css +38 -0
  296. data/public/libs/codemirror/addon/hint/show-hint.js +180 -0
  297. data/public/libs/codemirror/addon/hint/xml-hint.js +118 -0
  298. data/public/libs/codemirror/addon/lint/javascript-lint.js +127 -0
  299. data/public/libs/codemirror/addon/lint/json-lint.js +14 -0
  300. data/public/libs/codemirror/addon/lint/lint.css +96 -0
  301. data/public/libs/codemirror/addon/lint/lint.js +197 -0
  302. data/public/libs/codemirror/addon/mode/loadmode.js +51 -0
  303. data/public/libs/codemirror/addon/mode/multiplex.js +95 -0
  304. data/public/libs/codemirror/addon/mode/overlay.js +59 -0
  305. data/public/libs/codemirror/addon/runmode/colorize.js +29 -0
  306. data/public/libs/codemirror/addon/runmode/runmode-standalone.js +130 -0
  307. data/public/libs/codemirror/addon/runmode/runmode.js +52 -0
  308. data/public/libs/codemirror/addon/runmode/runmode.node.js +89 -0
  309. data/public/libs/codemirror/addon/search/match-highlighter.js +60 -0
  310. data/public/libs/codemirror/addon/search/search.js +131 -0
  311. data/public/libs/codemirror/addon/search/searchcursor.js +133 -0
  312. data/public/libs/codemirror/addon/selection/active-line.js +39 -0
  313. data/public/libs/codemirror/addon/selection/mark-selection.js +34 -0
  314. data/public/libs/codemirror/bin/compress +91 -0
  315. data/public/libs/codemirror/bin/lint +11 -0
  316. data/public/libs/codemirror/demo/activeline.html +70 -0
  317. data/public/libs/codemirror/demo/bidi.html +61 -0
  318. data/public/libs/codemirror/demo/btree.html +87 -0
  319. data/public/libs/codemirror/demo/buffers.html +98 -0
  320. data/public/libs/codemirror/demo/changemode.html +50 -0
  321. data/public/libs/codemirror/demo/closebrackets.html +63 -0
  322. data/public/libs/codemirror/demo/closetag.html +37 -0
  323. data/public/libs/codemirror/demo/complete.html +70 -0
  324. data/public/libs/codemirror/demo/emacs.html +60 -0
  325. data/public/libs/codemirror/demo/folding.html +69 -0
  326. data/public/libs/codemirror/demo/fullscreen.html +147 -0
  327. data/public/libs/codemirror/demo/html5complete.html +92 -0
  328. data/public/libs/codemirror/demo/indentwrap.html +49 -0
  329. data/public/libs/codemirror/demo/lint.html +90 -0
  330. data/public/libs/codemirror/demo/loadmode.html +40 -0
  331. data/public/libs/codemirror/demo/marker.html +59 -0
  332. data/public/libs/codemirror/demo/markselection.html +36 -0
  333. data/public/libs/codemirror/demo/matchhighlighter.html +38 -0
  334. data/public/libs/codemirror/demo/multiplex.html +60 -0
  335. data/public/libs/codemirror/demo/mustache.html +59 -0
  336. data/public/libs/codemirror/demo/placeholder.html +36 -0
  337. data/public/libs/codemirror/demo/preview.html +76 -0
  338. data/public/libs/codemirror/demo/resize.html +49 -0
  339. data/public/libs/codemirror/demo/runmode.html +50 -0
  340. data/public/libs/codemirror/demo/search.html +85 -0
  341. data/public/libs/codemirror/demo/spanaffectswrapping_shim.html +73 -0
  342. data/public/libs/codemirror/demo/theme.html +89 -0
  343. data/public/libs/codemirror/demo/variableheight.html +52 -0
  344. data/public/libs/codemirror/demo/vim.html +65 -0
  345. data/public/libs/codemirror/demo/visibletabs.html +53 -0
  346. data/public/libs/codemirror/demo/widget.html +74 -0
  347. data/public/libs/codemirror/demo/xmlcomplete.html +81 -0
  348. data/public/libs/codemirror/doc/baboon.png +0 -0
  349. data/public/libs/codemirror/doc/baboon_vector.svg +153 -0
  350. data/public/libs/codemirror/doc/compress.html +200 -0
  351. data/public/libs/codemirror/doc/docs.css +167 -0
  352. data/public/libs/codemirror/doc/internals.html +505 -0
  353. data/public/libs/codemirror/doc/manual.html +1897 -0
  354. data/public/libs/codemirror/doc/modes.html +94 -0
  355. data/public/libs/codemirror/doc/oldrelease.html +492 -0
  356. data/public/libs/codemirror/doc/realworld.html +100 -0
  357. data/public/libs/codemirror/doc/reporting.html +60 -0
  358. data/public/libs/codemirror/doc/upgrade_v2.2.html +98 -0
  359. data/public/libs/codemirror/doc/upgrade_v3.html +227 -0
  360. data/public/libs/codemirror/index.html +487 -0
  361. data/public/libs/codemirror/keymap/emacs.js +30 -0
  362. data/public/libs/codemirror/keymap/vim.js +3044 -0
  363. data/public/libs/codemirror/lib/codemirror.css +253 -0
  364. data/public/libs/codemirror/lib/codemirror.js +5585 -0
  365. data/public/libs/codemirror/mode/apl/apl.js +160 -0
  366. data/public/libs/codemirror/mode/apl/index.html +61 -0
  367. data/public/libs/codemirror/mode/asterisk/asterisk.js +183 -0
  368. data/public/libs/codemirror/mode/asterisk/index.html +142 -0
  369. data/public/libs/codemirror/mode/clike/clike.js +302 -0
  370. data/public/libs/codemirror/mode/clike/index.html +103 -0
  371. data/public/libs/codemirror/mode/clike/scala.html +767 -0
  372. data/public/libs/codemirror/mode/clojure/clojure.js +222 -0
  373. data/public/libs/codemirror/mode/clojure/index.html +76 -0
  374. data/public/libs/codemirror/mode/coffeescript/LICENSE +22 -0
  375. data/public/libs/codemirror/mode/coffeescript/coffeescript.js +346 -0
  376. data/public/libs/codemirror/mode/coffeescript/index.html +728 -0
  377. data/public/libs/codemirror/mode/commonlisp/commonlisp.js +101 -0
  378. data/public/libs/codemirror/mode/commonlisp/index.html +165 -0
  379. data/public/libs/codemirror/mode/css/css.js +567 -0
  380. data/public/libs/codemirror/mode/css/index.html +58 -0
  381. data/public/libs/codemirror/mode/css/scss.html +145 -0
  382. data/public/libs/codemirror/mode/css/scss_test.js +80 -0
  383. data/public/libs/codemirror/mode/css/test.js +113 -0
  384. data/public/libs/codemirror/mode/d/d.js +205 -0
  385. data/public/libs/codemirror/mode/d/index.html +262 -0
  386. data/public/libs/codemirror/mode/diff/diff.js +32 -0
  387. data/public/libs/codemirror/mode/diff/index.html +105 -0
  388. data/public/libs/codemirror/mode/ecl/ecl.js +192 -0
  389. data/public/libs/codemirror/mode/ecl/index.html +39 -0
  390. data/public/libs/codemirror/mode/erlang/erlang.js +463 -0
  391. data/public/libs/codemirror/mode/erlang/index.html +64 -0
  392. data/public/libs/codemirror/mode/gas/gas.js +326 -0
  393. data/public/libs/codemirror/mode/gas/index.html +57 -0
  394. data/public/libs/codemirror/mode/gfm/gfm.js +96 -0
  395. data/public/libs/codemirror/mode/gfm/index.html +74 -0
  396. data/public/libs/codemirror/mode/gfm/test.js +112 -0
  397. data/public/libs/codemirror/mode/go/go.js +165 -0
  398. data/public/libs/codemirror/mode/go/index.html +74 -0
  399. data/public/libs/codemirror/mode/groovy/groovy.js +210 -0
  400. data/public/libs/codemirror/mode/groovy/index.html +73 -0
  401. data/public/libs/codemirror/mode/haskell/haskell.js +242 -0
  402. data/public/libs/codemirror/mode/haskell/index.html +62 -0
  403. data/public/libs/codemirror/mode/haxe/haxe.js +429 -0
  404. data/public/libs/codemirror/mode/haxe/index.html +90 -0
  405. data/public/libs/codemirror/mode/htmlembedded/htmlembedded.js +73 -0
  406. data/public/libs/codemirror/mode/htmlembedded/index.html +49 -0
  407. data/public/libs/codemirror/mode/htmlmixed/htmlmixed.js +104 -0
  408. data/public/libs/codemirror/mode/htmlmixed/index.html +73 -0
  409. data/public/libs/codemirror/mode/http/http.js +98 -0
  410. data/public/libs/codemirror/mode/http/index.html +32 -0
  411. data/public/libs/codemirror/mode/javascript/index.html +92 -0
  412. data/public/libs/codemirror/mode/javascript/javascript.js +467 -0
  413. data/public/libs/codemirror/mode/javascript/typescript.html +48 -0
  414. data/public/libs/codemirror/mode/jinja2/index.html +38 -0
  415. data/public/libs/codemirror/mode/jinja2/jinja2.js +42 -0
  416. data/public/libs/codemirror/mode/less/index.html +741 -0
  417. data/public/libs/codemirror/mode/less/less.js +266 -0
  418. data/public/libs/codemirror/mode/livescript/LICENSE +23 -0
  419. data/public/libs/codemirror/mode/livescript/index.html +446 -0
  420. data/public/libs/codemirror/mode/livescript/livescript.js +267 -0
  421. data/public/libs/codemirror/mode/livescript/livescript.ls +266 -0
  422. data/public/libs/codemirror/mode/lua/index.html +74 -0
  423. data/public/libs/codemirror/mode/lua/lua.js +140 -0
  424. data/public/libs/codemirror/mode/markdown/index.html +344 -0
  425. data/public/libs/codemirror/mode/markdown/markdown.js +526 -0
  426. data/public/libs/codemirror/mode/markdown/test.js +636 -0
  427. data/public/libs/codemirror/mode/meta.js +75 -0
  428. data/public/libs/codemirror/mode/mirc/index.html +149 -0
  429. data/public/libs/codemirror/mode/mirc/mirc.js +177 -0
  430. data/public/libs/codemirror/mode/ntriples/index.html +33 -0
  431. data/public/libs/codemirror/mode/ntriples/ntriples.js +170 -0
  432. data/public/libs/codemirror/mode/ocaml/index.html +131 -0
  433. data/public/libs/codemirror/mode/ocaml/ocaml.js +113 -0
  434. data/public/libs/codemirror/mode/pascal/LICENSE +7 -0
  435. data/public/libs/codemirror/mode/pascal/index.html +48 -0
  436. data/public/libs/codemirror/mode/pascal/pascal.js +94 -0
  437. data/public/libs/codemirror/mode/perl/LICENSE +19 -0
  438. data/public/libs/codemirror/mode/perl/index.html +62 -0
  439. data/public/libs/codemirror/mode/perl/perl.js +816 -0
  440. data/public/libs/codemirror/mode/php/index.html +51 -0
  441. data/public/libs/codemirror/mode/php/php.js +129 -0
  442. data/public/libs/codemirror/mode/pig/index.html +42 -0
  443. data/public/libs/codemirror/mode/pig/pig.js +171 -0
  444. data/public/libs/codemirror/mode/properties/index.html +41 -0
  445. data/public/libs/codemirror/mode/properties/properties.js +63 -0
  446. data/public/libs/codemirror/mode/python/LICENSE.txt +21 -0
  447. data/public/libs/codemirror/mode/python/index.html +135 -0
  448. data/public/libs/codemirror/mode/python/python.js +340 -0
  449. data/public/libs/codemirror/mode/q/index.html +131 -0
  450. data/public/libs/codemirror/mode/q/q.js +124 -0
  451. data/public/libs/codemirror/mode/r/LICENSE +24 -0
  452. data/public/libs/codemirror/mode/r/index.html +74 -0
  453. data/public/libs/codemirror/mode/r/r.js +141 -0
  454. data/public/libs/codemirror/mode/rpm/changes/changes.js +19 -0
  455. data/public/libs/codemirror/mode/rpm/changes/index.html +53 -0
  456. data/public/libs/codemirror/mode/rpm/spec/index.html +99 -0
  457. data/public/libs/codemirror/mode/rpm/spec/spec.css +5 -0
  458. data/public/libs/codemirror/mode/rpm/spec/spec.js +66 -0
  459. data/public/libs/codemirror/mode/rst/LICENSE.txt +21 -0
  460. data/public/libs/codemirror/mode/rst/index.html +524 -0
  461. data/public/libs/codemirror/mode/rst/rst.js +550 -0
  462. data/public/libs/codemirror/mode/ruby/LICENSE +24 -0
  463. data/public/libs/codemirror/mode/ruby/index.html +173 -0
  464. data/public/libs/codemirror/mode/ruby/ruby.js +197 -0
  465. data/public/libs/codemirror/mode/rust/index.html +48 -0
  466. data/public/libs/codemirror/mode/rust/rust.js +432 -0
  467. data/public/libs/codemirror/mode/sass/index.html +54 -0
  468. data/public/libs/codemirror/mode/sass/sass.js +349 -0
  469. data/public/libs/codemirror/mode/scheme/index.html +65 -0
  470. data/public/libs/codemirror/mode/scheme/scheme.js +230 -0
  471. data/public/libs/codemirror/mode/shell/index.html +51 -0
  472. data/public/libs/codemirror/mode/shell/shell.js +118 -0
  473. data/public/libs/codemirror/mode/sieve/LICENSE +19 -0
  474. data/public/libs/codemirror/mode/sieve/index.html +81 -0
  475. data/public/libs/codemirror/mode/sieve/sieve.js +183 -0
  476. data/public/libs/codemirror/mode/smalltalk/index.html +57 -0
  477. data/public/libs/codemirror/mode/smalltalk/smalltalk.js +141 -0
  478. data/public/libs/codemirror/mode/smarty/index.html +83 -0
  479. data/public/libs/codemirror/mode/smarty/smarty.js +148 -0
  480. data/public/libs/codemirror/mode/sparql/index.html +42 -0
  481. data/public/libs/codemirror/mode/sparql/sparql.js +143 -0
  482. data/public/libs/codemirror/mode/sql/index.html +68 -0
  483. data/public/libs/codemirror/mode/sql/sql.js +268 -0
  484. data/public/libs/codemirror/mode/stex/index.html +98 -0
  485. data/public/libs/codemirror/mode/stex/stex.js +246 -0
  486. data/public/libs/codemirror/mode/stex/test.js +117 -0
  487. data/public/libs/codemirror/mode/tcl/index.html +129 -0
  488. data/public/libs/codemirror/mode/tcl/tcl.js +131 -0
  489. data/public/libs/codemirror/mode/tiddlywiki/index.html +142 -0
  490. data/public/libs/codemirror/mode/tiddlywiki/tiddlywiki.css +14 -0
  491. data/public/libs/codemirror/mode/tiddlywiki/tiddlywiki.js +353 -0
  492. data/public/libs/codemirror/mode/tiki/index.html +81 -0
  493. data/public/libs/codemirror/mode/tiki/tiki.css +26 -0
  494. data/public/libs/codemirror/mode/tiki/tiki.js +308 -0
  495. data/public/libs/codemirror/mode/turtle/index.html +39 -0
  496. data/public/libs/codemirror/mode/turtle/turtle.js +145 -0
  497. data/public/libs/codemirror/mode/vb/LICENSE.txt +21 -0
  498. data/public/libs/codemirror/mode/vb/index.html +88 -0
  499. data/public/libs/codemirror/mode/vb/vb.js +259 -0
  500. data/public/libs/codemirror/mode/vbscript/index.html +42 -0
  501. data/public/libs/codemirror/mode/vbscript/vbscript.js +26 -0
  502. data/public/libs/codemirror/mode/velocity/index.html +103 -0
  503. data/public/libs/codemirror/mode/velocity/velocity.js +144 -0
  504. data/public/libs/codemirror/mode/verilog/index.html +121 -0
  505. data/public/libs/codemirror/mode/verilog/verilog.js +182 -0
  506. data/public/libs/codemirror/mode/xml/index.html +45 -0
  507. data/public/libs/codemirror/mode/xml/xml.js +328 -0
  508. data/public/libs/codemirror/mode/xquery/LICENSE +20 -0
  509. data/public/libs/codemirror/mode/xquery/index.html +221 -0
  510. data/public/libs/codemirror/mode/xquery/test.js +64 -0
  511. data/public/libs/codemirror/mode/xquery/xquery.js +450 -0
  512. data/public/libs/codemirror/mode/yaml/index.html +68 -0
  513. data/public/libs/codemirror/mode/yaml/yaml.js +95 -0
  514. data/public/libs/codemirror/mode/z80/index.html +39 -0
  515. data/public/libs/codemirror/mode/z80/z80.js +85 -0
  516. data/public/libs/codemirror/package.json +21 -0
  517. data/public/libs/codemirror/test/doc_test.js +329 -0
  518. data/public/libs/codemirror/test/driver.js +138 -0
  519. data/public/libs/codemirror/test/index.html +182 -0
  520. data/public/libs/codemirror/test/lint/acorn.js +1593 -0
  521. data/public/libs/codemirror/test/lint/lint.js +112 -0
  522. data/public/libs/codemirror/test/lint/parse-js.js +1372 -0
  523. data/public/libs/codemirror/test/lint/walk.js +216 -0
  524. data/public/libs/codemirror/test/mode_test.css +10 -0
  525. data/public/libs/codemirror/test/mode_test.js +192 -0
  526. data/public/libs/codemirror/test/phantom_driver.js +31 -0
  527. data/public/libs/codemirror/test/run.js +33 -0
  528. data/public/libs/codemirror/test/test.js +1400 -0
  529. data/public/libs/codemirror/test/vim_test.js +1688 -0
  530. data/public/libs/codemirror/theme/ambiance-mobile.css +5 -0
  531. data/public/libs/codemirror/theme/ambiance.css +75 -0
  532. data/public/libs/codemirror/theme/blackboard.css +25 -0
  533. data/public/libs/codemirror/theme/cobalt.css +18 -0
  534. data/public/libs/codemirror/theme/eclipse.css +25 -0
  535. data/public/libs/codemirror/theme/elegant.css +10 -0
  536. data/public/libs/codemirror/theme/erlang-dark.css +21 -0
  537. data/public/libs/codemirror/theme/lesser-dark.css +44 -0
  538. data/public/libs/codemirror/theme/midnight.css +52 -0
  539. data/public/libs/codemirror/theme/monokai.css +28 -0
  540. data/public/libs/codemirror/theme/neat.css +9 -0
  541. data/public/libs/codemirror/theme/night.css +21 -0
  542. data/public/libs/codemirror/theme/rubyblue.css +21 -0
  543. data/public/libs/codemirror/theme/solarized.css +207 -0
  544. data/public/libs/codemirror/theme/twilight.css +26 -0
  545. data/public/libs/codemirror/theme/vibrant-ink.css +27 -0
  546. data/public/libs/codemirror/theme/xq-dark.css +46 -0
  547. data/public/libs/codemirror/theme/xq-light.css +43 -0
  548. data/public/libs/font-awesome/css/font-awesome-ie7.css +983 -0
  549. data/public/libs/font-awesome/css/font-awesome-ie7.min.css +24 -0
  550. data/public/libs/font-awesome/css/font-awesome.css +1268 -0
  551. data/public/libs/font-awesome/css/font-awesome.min.css +24 -0
  552. data/public/libs/font-awesome/font/FontAwesome.otf +0 -0
  553. data/public/libs/font-awesome/font/fontawesome-webfont.eot +0 -0
  554. data/public/libs/font-awesome/font/fontawesome-webfont.svg +339 -0
  555. data/public/libs/font-awesome/font/fontawesome-webfont.ttf +0 -0
  556. data/public/libs/font-awesome/font/fontawesome-webfont.woff +0 -0
  557. data/public/libs/font-awesome/less/bootstrap.less +78 -0
  558. data/public/libs/font-awesome/less/core.less +132 -0
  559. data/public/libs/font-awesome/less/extras.less +79 -0
  560. data/public/libs/font-awesome/less/font-awesome-ie7.less +413 -0
  561. data/public/libs/font-awesome/less/font-awesome.less +32 -0
  562. data/public/libs/font-awesome/less/icons.less +330 -0
  563. data/public/libs/font-awesome/less/mixins.less +34 -0
  564. data/public/libs/font-awesome/less/path.less +15 -0
  565. data/public/libs/font-awesome/less/variables.less +9 -0
  566. data/public/libs/jquery-1.10.0.min.js +6 -0
  567. data/public/libs/jquery-ui.min.js +12 -0
  568. data/public/libs/jquery.jsPlumb-1.4.0-all.js +9571 -0
  569. data/public/libs/jquery.livequery.js +226 -0
  570. data/public/libs/jsPlumbInitializer.js +72 -0
  571. data/public/libs/jstree/README.txt +10 -0
  572. data/public/libs/jstree/_demo/_dump.sql +20 -0
  573. data/public/libs/jstree/_demo/_inc/__mysql_errors.log +0 -0
  574. data/public/libs/jstree/_demo/_inc/class._database.php +146 -0
  575. data/public/libs/jstree/_demo/_inc/class._database_i.php +152 -0
  576. data/public/libs/jstree/_demo/_inc/class.tree.php +602 -0
  577. data/public/libs/jstree/_demo/_install.txt +6 -0
  578. data/public/libs/jstree/_demo/config.php +14 -0
  579. data/public/libs/jstree/_demo/file.png +0 -0
  580. data/public/libs/jstree/_demo/folder.png +0 -0
  581. data/public/libs/jstree/_demo/index.html +461 -0
  582. data/public/libs/jstree/_demo/root.png +0 -0
  583. data/public/libs/jstree/_demo/server.php +69 -0
  584. data/public/libs/jstree/_docs/!style.css +48 -0
  585. data/public/libs/jstree/_docs/_drive.png +0 -0
  586. data/public/libs/jstree/_docs/_html_data.html +2 -0
  587. data/public/libs/jstree/_docs/_json_data.json +4 -0
  588. data/public/libs/jstree/_docs/_search_data.json +6 -0
  589. data/public/libs/jstree/_docs/_search_result.json +1 -0
  590. data/public/libs/jstree/_docs/_xml_flat.xml +12 -0
  591. data/public/libs/jstree/_docs/_xml_nest.xml +18 -0
  592. data/public/libs/jstree/_docs/checkbox.html +171 -0
  593. data/public/libs/jstree/_docs/contextmenu.html +121 -0
  594. data/public/libs/jstree/_docs/cookies.html +97 -0
  595. data/public/libs/jstree/_docs/core.html +689 -0
  596. data/public/libs/jstree/_docs/crrm.html +316 -0
  597. data/public/libs/jstree/_docs/dnd.html +199 -0
  598. data/public/libs/jstree/_docs/hotkeys.html +82 -0
  599. data/public/libs/jstree/_docs/html_data.html +175 -0
  600. data/public/libs/jstree/_docs/index.html +86 -0
  601. data/public/libs/jstree/_docs/json_data.html +249 -0
  602. data/public/libs/jstree/_docs/languages.html +152 -0
  603. data/public/libs/jstree/_docs/logo.png +0 -0
  604. data/public/libs/jstree/_docs/search.html +153 -0
  605. data/public/libs/jstree/_docs/sort.html +85 -0
  606. data/public/libs/jstree/_docs/syntax/!script.js +2232 -0
  607. data/public/libs/jstree/_docs/syntax/!style.css +511 -0
  608. data/public/libs/jstree/_docs/syntax/clipboard.swf +0 -0
  609. data/public/libs/jstree/_docs/syntax/help.png +0 -0
  610. data/public/libs/jstree/_docs/syntax/magnifier.png +0 -0
  611. data/public/libs/jstree/_docs/syntax/page_white_code.png +0 -0
  612. data/public/libs/jstree/_docs/syntax/page_white_copy.png +0 -0
  613. data/public/libs/jstree/_docs/syntax/printer.png +0 -0
  614. data/public/libs/jstree/_docs/syntax/wrapping.png +0 -0
  615. data/public/libs/jstree/_docs/themeroller.html +107 -0
  616. data/public/libs/jstree/_docs/themes.html +127 -0
  617. data/public/libs/jstree/_docs/types.html +178 -0
  618. data/public/libs/jstree/_docs/ui.html +197 -0
  619. data/public/libs/jstree/_docs/unique.html +85 -0
  620. data/public/libs/jstree/_docs/xml_data.html +218 -0
  621. data/public/libs/jstree/_lib/jquery.cookie.js +96 -0
  622. data/public/libs/jstree/_lib/jquery.hotkeys.js +99 -0
  623. data/public/libs/jstree/_lib/jquery.js +5 -0
  624. data/public/libs/jstree/jquery.jstree.js +4564 -0
  625. data/public/libs/jstree/themes/apple/bg.jpg +0 -0
  626. data/public/libs/jstree/themes/apple/d.png +0 -0
  627. data/public/libs/jstree/themes/apple/dot_for_ie.gif +0 -0
  628. data/public/libs/jstree/themes/apple/style.css +61 -0
  629. data/public/libs/jstree/themes/apple/throbber.gif +0 -0
  630. data/public/libs/jstree/themes/classic/d.gif +0 -0
  631. data/public/libs/jstree/themes/classic/d.png +0 -0
  632. data/public/libs/jstree/themes/classic/dot_for_ie.gif +0 -0
  633. data/public/libs/jstree/themes/classic/style.css +77 -0
  634. data/public/libs/jstree/themes/classic/throbber.gif +0 -0
  635. data/public/libs/jstree/themes/default-rtl/d.gif +0 -0
  636. data/public/libs/jstree/themes/default-rtl/d.png +0 -0
  637. data/public/libs/jstree/themes/default-rtl/dots.gif +0 -0
  638. data/public/libs/jstree/themes/default-rtl/style.css +84 -0
  639. data/public/libs/jstree/themes/default-rtl/throbber.gif +0 -0
  640. data/public/libs/jstree/themes/default/d.gif +0 -0
  641. data/public/libs/jstree/themes/default/d.png +0 -0
  642. data/public/libs/jstree/themes/default/style.css +74 -0
  643. data/public/libs/jstree/themes/default/throbber.gif +0 -0
  644. data/test/dummy/README.rdoc +261 -0
  645. data/test/dummy/Rakefile +7 -0
  646. data/test/dummy/app/assets/javascripts/application.js +15 -0
  647. data/test/dummy/app/assets/javascripts/demo_app.js +2 -0
  648. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  649. data/test/dummy/app/assets/stylesheets/demo_app.css +4 -0
  650. data/test/dummy/app/controllers/application_controller.rb +3 -0
  651. data/test/dummy/app/controllers/demo_app_controller.rb +6 -0
  652. data/test/dummy/app/helpers/application_helper.rb +2 -0
  653. data/test/dummy/app/helpers/demo_app_helper.rb +2 -0
  654. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  655. data/test/dummy/config.ru +4 -0
  656. data/test/dummy/config/application.rb +59 -0
  657. data/test/dummy/config/boot.rb +10 -0
  658. data/test/dummy/config/database.yml +25 -0
  659. data/test/dummy/config/environment.rb +5 -0
  660. data/test/dummy/config/environments/development.rb +37 -0
  661. data/test/dummy/config/environments/production.rb +67 -0
  662. data/test/dummy/config/environments/test.rb +37 -0
  663. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  664. data/test/dummy/config/initializers/inflections.rb +15 -0
  665. data/test/dummy/config/initializers/mime_types.rb +5 -0
  666. data/test/dummy/config/initializers/secret_token.rb +7 -0
  667. data/test/dummy/config/initializers/session_store.rb +8 -0
  668. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  669. data/test/dummy/config/locales/en.yml +5 -0
  670. data/test/dummy/config/routes.rb +6 -0
  671. data/test/dummy/db/test.sqlite3 +0 -0
  672. data/test/dummy/log/development.log +17606 -0
  673. data/test/dummy/public/404.html +26 -0
  674. data/test/dummy/public/422.html +26 -0
  675. data/test/dummy/public/500.html +25 -0
  676. data/test/dummy/public/favicon.ico +0 -0
  677. data/test/dummy/script/rails +6 -0
  678. data/test/dummy/test/functional/demo_app_controller_test.rb +7 -0
  679. data/test/dummy/test/unit/helpers/demo_app_helper_test.rb +4 -0
  680. data/test/dummy/tmp/cache/assets/D26/980/sprockets%2Fe04a37a0fa7f26c1183a1a4436e2a9c1 +0 -0
  681. data/test/dummy/tmp/cache/assets/D32/4F0/sprockets%2Fbd5441f3593e4ea157222202f3fddad6 +0 -0
  682. data/test/dummy/tmp/pids/server.pid +1 -0
  683. data/test/functional/maglev_database_explorer/def_controller_test.rb +9 -0
  684. data/test/integration/navigation_test.rb +10 -0
  685. data/test/maglev-database-explorer_test.rb +7 -0
  686. data/test/test_helper.rb +15 -0
  687. data/test/unit/helpers/maglev_database_explorer/def_helper_test.rb +6 -0
  688. metadata +813 -0
@@ -0,0 +1,167 @@
1
+ body {
2
+ font-family: Droid Sans, Arial, sans-serif;
3
+ line-height: 1.5;
4
+ max-width: 64.3em;
5
+ margin: 3em auto;
6
+ padding: 0 1em;
7
+ }
8
+
9
+ h1 {
10
+ letter-spacing: -3px;
11
+ font-size: 3.23em;
12
+ font-weight: bold;
13
+ margin: 0;
14
+ }
15
+
16
+ h2 {
17
+ font-size: 1.23em;
18
+ font-weight: bold;
19
+ margin: .5em 0;
20
+ letter-spacing: -1px;
21
+ }
22
+
23
+ h3 {
24
+ font-size: 1.1em;
25
+ font-weight: bold;
26
+ margin: .4em 0;
27
+ }
28
+
29
+ pre {
30
+ background-color: #eee;
31
+ -moz-border-radius: 6px;
32
+ -webkit-border-radius: 6px;
33
+ border-radius: 6px;
34
+ padding: 1em;
35
+ }
36
+
37
+ pre.code {
38
+ margin: 0 1em;
39
+ }
40
+
41
+ .grey {
42
+ background-color: #eee;
43
+ border-radius: 6px;
44
+ margin-bottom: 1.65em;
45
+ margin-top: 0.825em;
46
+ padding: 0.825em 1.65em;
47
+ position: relative;
48
+ }
49
+
50
+ img.logo {
51
+ position: absolute;
52
+ right: -1em;
53
+ bottom: 4px;
54
+ max-width: 23.6875em; /* Scale image down with text to prevent clipping */
55
+ }
56
+
57
+ .grey > pre {
58
+ background:none;
59
+ border-radius:0;
60
+ padding:0;
61
+ margin:0;
62
+ font-size:2.2em;
63
+ line-height:1.2em;
64
+ }
65
+
66
+ a:link, a:visited, .quasilink {
67
+ color: #df0019;
68
+ cursor: pointer;
69
+ text-decoration: none;
70
+ }
71
+
72
+ a:hover, .quasilink:hover {
73
+ color: #800004;
74
+ }
75
+
76
+ h1 a:link, h1 a:visited, h1 a:hover {
77
+ color: black;
78
+ }
79
+
80
+ ul {
81
+ margin: 0;
82
+ padding-left: 1.2em;
83
+ }
84
+
85
+ a.download {
86
+ color: white;
87
+ background-color: #df0019;
88
+ width: 100%;
89
+ display: block;
90
+ text-align: center;
91
+ font-size: 1.23em;
92
+ font-weight: bold;
93
+ text-decoration: none;
94
+ -moz-border-radius: 6px;
95
+ -webkit-border-radius: 6px;
96
+ border-radius: 6px;
97
+ padding: .5em 0;
98
+ margin-bottom: 1em;
99
+ }
100
+
101
+ a.download:hover {
102
+ background-color: #bb0010;
103
+ }
104
+
105
+ .rel {
106
+ margin-bottom: 0;
107
+ }
108
+
109
+ .rel-note {
110
+ color: #777;
111
+ font-size: .9em;
112
+ margin-top: .1em;
113
+ }
114
+
115
+ .logo-braces {
116
+ color: #df0019;
117
+ position: relative;
118
+ top: -4px;
119
+ }
120
+
121
+ .blk {
122
+ float: left;
123
+ }
124
+
125
+ .left {
126
+ margin-right: 20.68em;
127
+ max-width: 37em;
128
+ padding-right: 6.53em;
129
+ padding-bottom: 1em;
130
+ }
131
+
132
+ .left1 {
133
+ width: 15.24em;
134
+ padding-right: 6.45em;
135
+ }
136
+
137
+ .left2 {
138
+ max-width: 15.24em;
139
+ }
140
+
141
+ .right {
142
+ width: 20.68em;
143
+ margin-left: -20.68em;
144
+ }
145
+
146
+ .leftbig {
147
+ width: 42.44em;
148
+ padding-right: 6.53em;
149
+ }
150
+
151
+ .rightsmall {
152
+ width: 15.24em;
153
+ }
154
+
155
+ .clear:after {
156
+ visibility: hidden;
157
+ display: block;
158
+ font-size: 0;
159
+ content: " ";
160
+ clear: both;
161
+ height: 0;
162
+ }
163
+ .clear { display: inline-block; }
164
+ /* start commented backslash hack \*/
165
+ * html .clear { height: 1%; }
166
+ .clear { display: block; }
167
+ /* close commented backslash hack */
@@ -0,0 +1,505 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8"/>
5
+ <title>CodeMirror: Internals</title>
6
+ <link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Droid+Sans|Droid+Sans:bold"/>
7
+ <link rel="stylesheet" type="text/css" href="docs.css"/>
8
+ <style>dl dl {margin: 0;} .update {color: #d40 !important}</style>
9
+ </head>
10
+ <body>
11
+
12
+ <h1><span class="logo-braces">{ }</span> <a href="http://codemirror.net/">CodeMirror</a></h1>
13
+
14
+ <div class="grey">
15
+ <img src="baboon.png" class="logo" alt="logo"/>
16
+ <pre>
17
+ /* (Re-) Implementing A Syntax-
18
+ Highlighting Editor in JavaScript */
19
+ </pre>
20
+ </div>
21
+
22
+ <div class="clear"><div class="leftbig blk">
23
+
24
+ <p style="font-size: 85%" id="intro">
25
+ <strong>Topic:</strong> JavaScript, code editor implementation<br>
26
+ <strong>Author:</strong> Marijn Haverbeke<br>
27
+ <strong>Date:</strong> March 2nd 2011 (updated November 13th 2011)
28
+ </p>
29
+
30
+ <p style="padding: 0 3em 0 2em"><strong>Caution</strong>: this text was written briefly after
31
+ version 2 was initially written. It no longer (even including the
32
+ update at the bottom) fully represents the current implementation. I'm
33
+ leaving it here as a historic document. For more up-to-date
34
+ information, look at the entries
35
+ tagged <a href="http://marijnhaverbeke.nl/blog/#cm-internals">cm-internals</a>
36
+ on my blog.</p>
37
+
38
+ <p>This is a followup to
39
+ my <a href="http://codemirror.net/story.html">Brutal Odyssey to the
40
+ Dark Side of the DOM Tree</a> story. That one describes the
41
+ mind-bending process of implementing (what would become) CodeMirror 1.
42
+ This one describes the internals of CodeMirror 2, a complete rewrite
43
+ and rethink of the old code base. I wanted to give this piece another
44
+ Hunter Thompson copycat subtitle, but somehow that would be out of
45
+ place—the process this time around was one of straightforward
46
+ engineering, requiring no serious mind-bending whatsoever.</p>
47
+
48
+ <p>So, what is wrong with CodeMirror 1? I'd estimate, by mailing list
49
+ activity and general search-engine presence, that it has been
50
+ integrated into about a thousand systems by now. The most prominent
51
+ one, since a few weeks,
52
+ being <a href="http://googlecode.blogspot.com/2011/01/make-quick-fixes-quicker-on-google.html">Google
53
+ code's project hosting</a>. It works, and it's being used widely.</p>
54
+
55
+ <p>Still, I did not start replacing it because I was bored. CodeMirror
56
+ 1 was heavily reliant on <code>designMode</code>
57
+ or <code>contentEditable</code> (depending on the browser). Neither of
58
+ these are well specified (HTML5 tries
59
+ to <a href="http://www.w3.org/TR/html5/editing.html#contenteditable">specify</a>
60
+ their basics), and, more importantly, they tend to be one of the more
61
+ obscure and buggy areas of browser functionality—CodeMirror, by using
62
+ this functionality in a non-typical way, was constantly running up
63
+ against browser bugs. WebKit wouldn't show an empty line at the end of
64
+ the document, and in some releases would suddenly get unbearably slow.
65
+ Firefox would show the cursor in the wrong place. Internet Explorer
66
+ would insist on linkifying everything that looked like a URL or email
67
+ address, a behaviour that can't be turned off. Some bugs I managed to
68
+ work around (which was often a frustrating, painful process), others,
69
+ such as the Firefox cursor placement, I gave up on, and had to tell
70
+ user after user that they were known problems, but not something I
71
+ could help.</p>
72
+
73
+ <p>Also, there is the fact that <code>designMode</code> (which seemed
74
+ to be less buggy than <code>contentEditable</code> in Webkit and
75
+ Firefox, and was thus used by CodeMirror 1 in those browsers) requires
76
+ a frame. Frames are another tricky area. It takes some effort to
77
+ prevent getting tripped up by domain restrictions, they don't
78
+ initialize synchronously, behave strangely in response to the back
79
+ button, and, on several browsers, can't be moved around the DOM
80
+ without having them re-initialize. They did provide a very nice way to
81
+ namespace the library, though—CodeMirror 1 could freely pollute the
82
+ namespace inside the frame.</p>
83
+
84
+ <p>Finally, working with an editable document means working with
85
+ selection in arbitrary DOM structures. Internet Explorer (8 and
86
+ before) has an utterly different (and awkward) selection API than all
87
+ of the other browsers, and even among the different implementations of
88
+ <code>document.selection</code>, details about how exactly a selection
89
+ is represented vary quite a bit. Add to that the fact that Opera's
90
+ selection support tended to be very buggy until recently, and you can
91
+ imagine why CodeMirror 1 contains 700 lines of selection-handling
92
+ code.</p>
93
+
94
+ <p>And that brings us to the main issue with the CodeMirror 1
95
+ code base: The proportion of browser-bug-workarounds to real
96
+ application code was getting dangerously high. By building on top of a
97
+ few dodgy features, I put the system in a vulnerable position—any
98
+ incompatibility and bugginess in these features, I had to paper over
99
+ with my own code. Not only did I have to do some serious stunt-work to
100
+ get it to work on older browsers (as detailed in the
101
+ previous <a href="http://codemirror.net/story.html">story</a>), things
102
+ also kept breaking in newly released versions, requiring me to come up
103
+ with <em>new</em> scary hacks in order to keep up. This was starting
104
+ to lose its appeal.</p>
105
+
106
+ <h2 id="approach">General Approach</h2>
107
+
108
+ <p>What CodeMirror 2 does is try to sidestep most of the hairy hacks
109
+ that came up in version 1. I owe a lot to the
110
+ <a href="http://ace.ajax.org">ACE</a> editor for inspiration on how to
111
+ approach this.</p>
112
+
113
+ <p>I absolutely did not want to be completely reliant on key events to
114
+ generate my input. Every JavaScript programmer knows that key event
115
+ information is horrible and incomplete. Some people (most awesomely
116
+ Mihai Bazon with <a href="http://ymacs.org">Ymacs</a>) have been able
117
+ to build more or less functioning editors by directly reading key
118
+ events, but it takes a lot of work (the kind of never-ending, fragile
119
+ work I described earlier), and will never be able to properly support
120
+ things like multi-keystoke international character
121
+ input. <a href="#keymap" class="update">[see below for caveat]</a></p>
122
+
123
+ <p>So what I do is focus a hidden textarea, and let the browser
124
+ believe that the user is typing into that. What we show to the user is
125
+ a DOM structure we built to represent his document. If this is updated
126
+ quickly enough, and shows some kind of believable cursor, it feels
127
+ like a real text-input control.</p>
128
+
129
+ <p>Another big win is that this DOM representation does not have to
130
+ span the whole document. Some CodeMirror 1 users insisted that they
131
+ needed to put a 30 thousand line XML document into CodeMirror. Putting
132
+ all that into the DOM takes a while, especially since, for some
133
+ reason, an editable DOM tree is slower than a normal one on most
134
+ browsers. If we have full control over what we show, we must only
135
+ ensure that the visible part of the document has been added, and can
136
+ do the rest only when needed. (Fortunately, the <code>onscroll</code>
137
+ event works almost the same on all browsers, and lends itself well to
138
+ displaying things only as they are scrolled into view.)</p>
139
+
140
+ <h2 id="input">Input</h2>
141
+
142
+ <p>ACE uses its hidden textarea only as a text input shim, and does
143
+ all cursor movement and things like text deletion itself by directly
144
+ handling key events. CodeMirror's way is to let the browser do its
145
+ thing as much as possible, and not, for example, define its own set of
146
+ key bindings. One way to do this would have been to have the whole
147
+ document inside the hidden textarea, and after each key event update
148
+ the display DOM to reflect what's in that textarea.</p>
149
+
150
+ <p>That'd be simple, but it is not realistic. For even medium-sized
151
+ document the editor would be constantly munging huge strings, and get
152
+ terribly slow. What CodeMirror 2 does is put the current selection,
153
+ along with an extra line on the top and on the bottom, into the
154
+ textarea.</p>
155
+
156
+ <p>This means that the arrow keys (and their ctrl-variations), home,
157
+ end, etcetera, do not have to be handled specially. We just read the
158
+ cursor position in the textarea, and update our cursor to match it.
159
+ Also, copy and paste work pretty much for free, and people get their
160
+ native key bindings, without any special work on my part. For example,
161
+ I have emacs key bindings configured for Chrome and Firefox. There is
162
+ no way for a script to detect this. <a class="update"
163
+ href="#keymap">[no longer the case]</a></p>
164
+
165
+ <p>Of course, since only a small part of the document sits in the
166
+ textarea, keys like page up and ctrl-end won't do the right thing.
167
+ CodeMirror is catching those events and handling them itself.</p>
168
+
169
+ <h2 id="selection">Selection</h2>
170
+
171
+ <p>Getting and setting the selection range of a textarea in modern
172
+ browsers is trivial—you just use the <code>selectionStart</code>
173
+ and <code>selectionEnd</code> properties. On IE you have to do some
174
+ insane stuff with temporary ranges and compensating for the fact that
175
+ moving the selection by a 'character' will treat \r\n as a single
176
+ character, but even there it is possible to build functions that
177
+ reliably set and get the selection range.</p>
178
+
179
+ <p>But consider this typical case: When I'm somewhere in my document,
180
+ press shift, and press the up arrow, something gets selected. Then, if
181
+ I, still holding shift, press the up arrow again, the top of my
182
+ selection is adjusted. The selection remembers where its <em>head</em>
183
+ and its <em>anchor</em> are, and moves the head when we shift-move.
184
+ This is a generally accepted property of selections, and done right by
185
+ every editing component built in the past twenty years.</p>
186
+
187
+ <p>But not something that the browser selection APIs expose.</p>
188
+
189
+ <p>Great. So when someone creates an 'upside-down' selection, the next
190
+ time CodeMirror has to update the textarea, it'll re-create the
191
+ selection as an 'upside-up' selection, with the anchor at the top, and
192
+ the next cursor motion will behave in an unexpected way—our second
193
+ up-arrow press in the example above will not do anything, since it is
194
+ interpreted in exactly the same way as the first.</p>
195
+
196
+ <p>No problem. We'll just, ehm, detect that the selection is
197
+ upside-down (you can tell by the way it was created), and then, when
198
+ an upside-down selection is present, and a cursor-moving key is
199
+ pressed in combination with shift, we quickly collapse the selection
200
+ in the textarea to its start, allow the key to take effect, and then
201
+ combine its new head with its old anchor to get the <em>real</em>
202
+ selection.</p>
203
+
204
+ <p>In short, scary hacks could not be avoided entirely in CodeMirror
205
+ 2.</p>
206
+
207
+ <p>And, the observant reader might ask, how do you even know that a
208
+ key combo is a cursor-moving combo, if you claim you support any
209
+ native key bindings? Well, we don't, but we can learn. The editor
210
+ keeps a set known cursor-movement combos (initialized to the
211
+ predictable defaults), and updates this set when it observes that
212
+ pressing a certain key had (only) the effect of moving the cursor.
213
+ This, of course, doesn't work if the first time the key is used was
214
+ for extending an inverted selection, but it works most of the
215
+ time.</p>
216
+
217
+ <h2 id="update">Intelligent Updating</h2>
218
+
219
+ <p>One thing that always comes up when you have a complicated internal
220
+ state that's reflected in some user-visible external representation
221
+ (in this case, the displayed code and the textarea's content) is
222
+ keeping the two in sync. The naive way is to just update the display
223
+ every time you change your state, but this is not only error prone
224
+ (you'll forget), it also easily leads to duplicate work on big,
225
+ composite operations. Then you start passing around flags indicating
226
+ whether the display should be updated in an attempt to be efficient
227
+ again and, well, at that point you might as well give up completely.</p>
228
+
229
+ <p>I did go down that road, but then switched to a much simpler model:
230
+ simply keep track of all the things that have been changed during an
231
+ action, and then, only at the end, use this information to update the
232
+ user-visible display.</p>
233
+
234
+ <p>CodeMirror uses a concept of <em>operations</em>, which start by
235
+ calling a specific set-up function that clears the state and end by
236
+ calling another function that reads this state and does the required
237
+ updating. Most event handlers, and all the user-visible methods that
238
+ change state are wrapped like this. There's a method
239
+ called <code>operation</code> that accepts a function, and returns
240
+ another function that wraps the given function as an operation.</p>
241
+
242
+ <p>It's trivial to extend this (as CodeMirror does) to detect nesting,
243
+ and, when an operation is started inside an operation, simply
244
+ increment the nesting count, and only do the updating when this count
245
+ reaches zero again.</p>
246
+
247
+ <p>If we have a set of changed ranges and know the currently shown
248
+ range, we can (with some awkward code to deal with the fact that
249
+ changes can add and remove lines, so we're dealing with a changing
250
+ coordinate system) construct a map of the ranges that were left
251
+ intact. We can then compare this map with the part of the document
252
+ that's currently visible (based on scroll offset and editor height) to
253
+ determine whether something needs to be updated.</p>
254
+
255
+ <p>CodeMirror uses two update algorithms—a full refresh, where it just
256
+ discards the whole part of the DOM that contains the edited text and
257
+ rebuilds it, and a patch algorithm, where it uses the information
258
+ about changed and intact ranges to update only the out-of-date parts
259
+ of the DOM. When more than 30 percent (which is the current heuristic,
260
+ might change) of the lines need to be updated, the full refresh is
261
+ chosen (since it's faster to do than painstakingly finding and
262
+ updating all the changed lines), in the other case it does the
263
+ patching (so that, if you scroll a line or select another character,
264
+ the whole screen doesn't have to be
265
+ re-rendered). <span class="update">[the full-refresh
266
+ algorithm was dropped, it wasn't really faster than the patching
267
+ one]</span></p>
268
+
269
+ <p>All updating uses <code>innerHTML</code> rather than direct DOM
270
+ manipulation, since that still seems to be by far the fastest way to
271
+ build documents. There's a per-line function that combines the
272
+ highlighting, <a href="manual.html#markText">marking</a>, and
273
+ selection info for that line into a snippet of HTML. The patch updater
274
+ uses this to reset individual lines, the refresh updater builds an
275
+ HTML chunk for the whole visible document at once, and then uses a
276
+ single <code>innerHTML</code> update to do the refresh.</p>
277
+
278
+ <h2 id="parse">Parsers can be Simple</h2>
279
+
280
+ <p>When I wrote CodeMirror 1, I
281
+ thought <a href="http://codemirror.net/story.html#parser">interruptable
282
+ parsers</a> were a hugely scary and complicated thing, and I used a
283
+ bunch of heavyweight abstractions to keep this supposed complexity
284
+ under control: parsers
285
+ were <a href="http://bob.pythonmac.org/archives/2005/07/06/iteration-in-javascript/">iterators</a>
286
+ that consumed input from another iterator, and used funny
287
+ closure-resetting tricks to copy and resume themselves.</p>
288
+
289
+ <p>This made for a rather nice system, in that parsers formed strictly
290
+ separate modules, and could be composed in predictable ways.
291
+ Unfortunately, it was quite slow (stacking three or four iterators on
292
+ top of each other), and extremely intimidating to people not used to a
293
+ functional programming style.</p>
294
+
295
+ <p>With a few small changes, however, we can keep all those
296
+ advantages, but simplify the API and make the whole thing less
297
+ indirect and inefficient. CodeMirror
298
+ 2's <a href="manual.html#modeapi">mode API</a> uses explicit state
299
+ objects, and makes the parser/tokenizer a function that simply takes a
300
+ state and a character stream abstraction, advances the stream one
301
+ token, and returns the way the token should be styled. This state may
302
+ be copied, optionally in a mode-defined way, in order to be able to
303
+ continue a parse at a given point. Even someone who's never touched a
304
+ lambda in his life can understand this approach. Additionally, far
305
+ fewer objects are allocated in the course of parsing now.</p>
306
+
307
+ <p>The biggest speedup comes from the fact that the parsing no longer
308
+ has to touch the DOM though. In CodeMirror 1, on an older browser, you
309
+ could <em>see</em> the parser work its way through the document,
310
+ managing some twenty lines in each 50-millisecond time slice it got. It
311
+ was reading its input from the DOM, and updating the DOM as it went
312
+ along, which any experienced JavaScript programmer will immediately
313
+ spot as a recipe for slowness. In CodeMirror 2, the parser usually
314
+ finishes the whole document in a single 100-millisecond time slice—it
315
+ manages some 1500 lines during that time on Chrome. All it has to do
316
+ is munge strings, so there is no real reason for it to be slow
317
+ anymore.</p>
318
+
319
+ <h2 id="summary">What Gives?</h2>
320
+
321
+ <p>Given all this, what can you expect from CodeMirror 2?</p>
322
+
323
+ <ul>
324
+
325
+ <li><strong>Small.</strong> the base library is
326
+ some <span class="update">45k</span> when minified
327
+ now, <span class="update">17k</span> when gzipped. It's smaller than
328
+ its own logo.</li>
329
+
330
+ <li><strong>Lightweight.</strong> CodeMirror 2 initializes very
331
+ quickly, and does almost no work when it is not focused. This means
332
+ you can treat it almost like a textarea, have multiple instances on a
333
+ page without trouble.</li>
334
+
335
+ <li><strong>Huge document support.</strong> Since highlighting is
336
+ really fast, and no DOM structure is being built for non-visible
337
+ content, you don't have to worry about locking up your browser when a
338
+ user enters a megabyte-sized document.</li>
339
+
340
+ <li><strong>Extended API.</strong> Some things kept coming up in the
341
+ mailing list, such as marking pieces of text or lines, which were
342
+ extremely hard to do with CodeMirror 1. The new version has proper
343
+ support for these built in.</li>
344
+
345
+ <li><strong>Tab support.</strong> Tabs inside editable documents were,
346
+ for some reason, a no-go. At least six different people announced they
347
+ were going to add tab support to CodeMirror 1, none survived (I mean,
348
+ none delivered a working version). CodeMirror 2 no longer removes tabs
349
+ from your document.</li>
350
+
351
+ <li><strong>Sane styling.</strong> <code>iframe</code> nodes aren't
352
+ really known for respecting document flow. Now that an editor instance
353
+ is a plain <code>div</code> element, it is much easier to size it to
354
+ fit the surrounding elements. You don't even have to make it scroll if
355
+ you do not <a href="../demo/resize.html">want to</a>.</li>
356
+
357
+ </ul>
358
+
359
+ <p>On the downside, a CodeMirror 2 instance is <em>not</em> a native
360
+ editable component. Though it does its best to emulate such a
361
+ component as much as possible, there is functionality that browsers
362
+ just do not allow us to hook into. Doing select-all from the context
363
+ menu, for example, is not currently detected by CodeMirror.</p>
364
+
365
+ <p id="changes" style="margin-top: 2em;"><span style="font-weight:
366
+ bold">[Updates from November 13th 2011]</span> Recently, I've made
367
+ some changes to the codebase that cause some of the text above to no
368
+ longer be current. I've left the text intact, but added markers at the
369
+ passages that are now inaccurate. The new situation is described
370
+ below.</p>
371
+
372
+ <h2 id="btree">Content Representation</h2>
373
+
374
+ <p>The original implementation of CodeMirror 2 represented the
375
+ document as a flat array of line objects. This worked well—splicing
376
+ arrays will require the part of the array after the splice to be
377
+ moved, but this is basically just a simple <code>memmove</code> of a
378
+ bunch of pointers, so it is cheap even for huge documents.</p>
379
+
380
+ <p>However, I recently added line wrapping and code folding (line
381
+ collapsing, basically). Once lines start taking up a non-constant
382
+ amount of vertical space, looking up a line by vertical position
383
+ (which is needed when someone clicks the document, and to determine
384
+ the visible part of the document during scrolling) can only be done
385
+ with a linear scan through the whole array, summing up line heights as
386
+ you go. Seeing how I've been going out of my way to make big documents
387
+ fast, this is not acceptable.</p>
388
+
389
+ <p>The new representation is based on a B-tree. The leaves of the tree
390
+ contain arrays of line objects, with a fixed minimum and maximum size,
391
+ and the non-leaf nodes simply hold arrays of child nodes. Each node
392
+ stores both the amount of lines that live below them and the vertical
393
+ space taken up by these lines. This allows the tree to be indexed both
394
+ by line number and by vertical position, and all access has
395
+ logarithmic complexity in relation to the document size.</p>
396
+
397
+ <p>I gave line objects and tree nodes parent pointers, to the node
398
+ above them. When a line has to update its height, it can simply walk
399
+ these pointers to the top of the tree, adding or subtracting the
400
+ difference in height from each node it encounters. The parent pointers
401
+ also make it cheaper (in complexity terms, the difference is probably
402
+ tiny in normal-sized documents) to find the current line number when
403
+ given a line object. In the old approach, the whole document array had
404
+ to be searched. Now, we can just walk up the tree and count the sizes
405
+ of the nodes coming before us at each level.</p>
406
+
407
+ <p>I chose B-trees, not regular binary trees, mostly because they
408
+ allow for very fast bulk insertions and deletions. When there is a big
409
+ change to a document, it typically involves adding, deleting, or
410
+ replacing a chunk of subsequent lines. In a regular balanced tree, all
411
+ these inserts or deletes would have to be done separately, which could
412
+ be really expensive. In a B-tree, to insert a chunk, you just walk
413
+ down the tree once to find where it should go, insert them all in one
414
+ shot, and then break up the node if needed. This breaking up might
415
+ involve breaking up nodes further up, but only requires a single pass
416
+ back up the tree. For deletion, I'm somewhat lax in keeping things
417
+ balanced—I just collapse nodes into a leaf when their child count goes
418
+ below a given number. This means that there are some weird editing
419
+ patterns that may result in a seriously unbalanced tree, but even such
420
+ an unbalanced tree will perform well, unless you spend a day making
421
+ strangely repeating edits to a really big document.</p>
422
+
423
+ <h2 id="keymap">Keymaps</h2>
424
+
425
+ <p><a href="#approach">Above</a>, I claimed that directly catching key
426
+ events for things like cursor movement is impractical because it
427
+ requires some browser-specific kludges. I then proceeded to explain
428
+ some awful <a href="#selection">hacks</a> that were needed to make it
429
+ possible for the selection changes to be detected through the
430
+ textarea. In fact, the second hack is about as bad as the first.</p>
431
+
432
+ <p>On top of that, in the presence of user-configurable tab sizes and
433
+ collapsed and wrapped lines, lining up cursor movement in the textarea
434
+ with what's visible on the screen becomes a nightmare. Thus, I've
435
+ decided to move to a model where the textarea's selection is no longer
436
+ depended on.</p>
437
+
438
+ <p>So I moved to a model where all cursor movement is handled by my
439
+ own code. This adds support for a goal column, proper interaction of
440
+ cursor movement with collapsed lines, and makes it possible for
441
+ vertical movement to move through wrapped lines properly, instead of
442
+ just treating them like non-wrapped lines.</p>
443
+
444
+ <p>The key event handlers now translate the key event into a string,
445
+ something like <code>Ctrl-Home</code> or <code>Shift-Cmd-R</code>, and
446
+ use that string to look up an action to perform. To make keybinding
447
+ customizable, this lookup goes through
448
+ a <a href="manual.html#option_keyMap">table</a>, using a scheme that
449
+ allows such tables to be chained together (for example, the default
450
+ Mac bindings fall through to a table named 'emacsy', which defines
451
+ basic Emacs-style bindings like <code>Ctrl-F</code>, and which is also
452
+ used by the custom Emacs bindings).</p>
453
+
454
+ <p>A new
455
+ option <a href="manual.html#option_extraKeys"><code>extraKeys</code></a>
456
+ allows ad-hoc keybindings to be defined in a much nicer way than what
457
+ was possible with the
458
+ old <a href="manual.html#option_onKeyEvent"><code>onKeyEvent</code></a>
459
+ callback. You simply provide an object mapping key identifiers to
460
+ functions, instead of painstakingly looking at raw key events.</p>
461
+
462
+ <p>Built-in commands map to strings, rather than functions, for
463
+ example <code>"goLineUp"</code> is the default action bound to the up
464
+ arrow key. This allows new keymaps to refer to them without
465
+ duplicating any code. New commands can be defined by assigning to
466
+ the <code>CodeMirror.commands</code> object, which maps such commands
467
+ to functions.</p>
468
+
469
+ <p>The hidden textarea now only holds the current selection, with no
470
+ extra characters around it. This has a nice advantage: polling for
471
+ input becomes much, much faster. If there's a big selection, this text
472
+ does not have to be read from the textarea every time—when we poll,
473
+ just noticing that something is still selected is enough to tell us
474
+ that no new text was typed.</p>
475
+
476
+ <p>The reason that cheap polling is important is that many browsers do
477
+ not fire useful events on IME (input method engine) input, which is
478
+ the thing where people inputting a language like Japanese or Chinese
479
+ use multiple keystrokes to create a character or sequence of
480
+ characters. Most modern browsers fire <code>input</code> when the
481
+ composing is finished, but many don't fire anything when the character
482
+ is updated <em>during</em> composition. So we poll, whenever the
483
+ editor is focused, to provide immediate updates of the display.</p>
484
+
485
+ </div><div class="rightsmall blk">
486
+
487
+ <h2>Contents</h2>
488
+
489
+ <ul>
490
+ <li><a href="#intro">Introduction</a></li>
491
+ <li><a href="#approach">General Approach</a></li>
492
+ <li><a href="#input">Input</a></li>
493
+ <li><a href="#selection">Selection</a></li>
494
+ <li><a href="#update">Intelligent Updating</a></li>
495
+ <li><a href="#parse">Parsing</a></li>
496
+ <li><a href="#summary">What Gives?</a></li>
497
+ <li><a href="#btree">Content Representation</a></li>
498
+ <li><a href="#keymap">Key Maps</a></li>
499
+ </ul>
500
+
501
+ </div></div>
502
+
503
+ <div style="height: 2em">&nbsp;</div>
504
+
505
+ </body></html>