milksteak 0.0.1 → 0.0.2

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 (350) hide show
  1. data/.gitignore +1 -14
  2. data/.rspec +2 -0
  3. data/Gemfile +1 -1
  4. data/Guardfile +8 -0
  5. data/Rakefile +0 -1
  6. data/Readme.md +37 -0
  7. data/lib/helpers.rb +0 -0
  8. data/lib/milksteak/cms.rb +17 -0
  9. data/lib/milksteak/version.rb +1 -1
  10. data/lib/milksteak.rb +52 -1
  11. data/lib/models/page.rb +73 -0
  12. data/lib/models/user.rb +5 -0
  13. data/lib/public/milksteak/codemirror2/keymap/emacs.js +29 -0
  14. data/lib/public/milksteak/codemirror2/keymap/vim.js +347 -0
  15. data/lib/public/milksteak/codemirror2/lib/codemirror.css +110 -0
  16. data/lib/public/milksteak/codemirror2/lib/codemirror.js +2887 -0
  17. data/lib/public/milksteak/codemirror2/lib/util/dialog.css +23 -0
  18. data/lib/public/milksteak/codemirror2/lib/util/dialog.js +63 -0
  19. data/lib/public/milksteak/codemirror2/lib/util/foldcode.js +186 -0
  20. data/lib/public/milksteak/codemirror2/lib/util/formatting.js +294 -0
  21. data/lib/public/milksteak/codemirror2/lib/util/javascript-hint.js +132 -0
  22. data/lib/public/milksteak/codemirror2/lib/util/match-highlighter.js +44 -0
  23. data/lib/public/milksteak/codemirror2/lib/util/overlay.js +51 -0
  24. data/lib/public/milksteak/codemirror2/lib/util/runmode.js +49 -0
  25. data/lib/public/milksteak/codemirror2/lib/util/search.js +114 -0
  26. data/lib/public/milksteak/codemirror2/lib/util/searchcursor.js +117 -0
  27. data/lib/public/milksteak/codemirror2/lib/util/simple-hint.css +16 -0
  28. data/lib/public/milksteak/codemirror2/lib/util/simple-hint.js +66 -0
  29. data/lib/public/milksteak/codemirror2/mode/clike/clike.js +234 -0
  30. data/lib/public/milksteak/codemirror2/mode/clike/index.html +101 -0
  31. data/lib/public/milksteak/codemirror2/mode/clojure/clojure.js +207 -0
  32. data/lib/public/milksteak/codemirror2/mode/clojure/index.html +66 -0
  33. data/lib/public/milksteak/codemirror2/mode/coffeescript/LICENSE +22 -0
  34. data/lib/public/milksteak/codemirror2/mode/coffeescript/coffeescript.js +341 -0
  35. data/lib/public/milksteak/codemirror2/mode/coffeescript/index.html +721 -0
  36. data/lib/public/milksteak/codemirror2/mode/css/css.js +124 -0
  37. data/lib/public/milksteak/codemirror2/mode/css/index.html +55 -0
  38. data/lib/public/milksteak/codemirror2/mode/diff/diff.css +3 -0
  39. data/lib/public/milksteak/codemirror2/mode/diff/diff.js +13 -0
  40. data/lib/public/milksteak/codemirror2/mode/diff/index.html +99 -0
  41. data/lib/public/milksteak/codemirror2/mode/ecl/ecl.js +203 -0
  42. data/lib/public/milksteak/codemirror2/mode/ecl/index.html +42 -0
  43. data/lib/public/milksteak/codemirror2/mode/gfm/gfm.js +108 -0
  44. data/lib/public/milksteak/codemirror2/mode/gfm/index.html +47 -0
  45. data/lib/public/milksteak/codemirror2/mode/go/go.js +170 -0
  46. data/lib/public/milksteak/codemirror2/mode/go/index.html +72 -0
  47. data/lib/public/milksteak/codemirror2/mode/groovy/groovy.js +210 -0
  48. data/lib/public/milksteak/codemirror2/mode/groovy/index.html +71 -0
  49. data/lib/public/milksteak/codemirror2/mode/haskell/haskell.js +242 -0
  50. data/lib/public/milksteak/codemirror2/mode/haskell/index.html +60 -0
  51. data/lib/public/milksteak/codemirror2/mode/htmlembedded/htmlembedded.js +68 -0
  52. data/lib/public/milksteak/codemirror2/mode/htmlembedded/index.html +49 -0
  53. data/lib/public/milksteak/codemirror2/mode/htmlmixed/htmlmixed.js +83 -0
  54. data/lib/public/milksteak/codemirror2/mode/htmlmixed/index.html +51 -0
  55. data/lib/public/milksteak/codemirror2/mode/javascript/index.html +77 -0
  56. data/lib/public/milksteak/codemirror2/mode/javascript/javascript.js +360 -0
  57. data/lib/public/milksteak/codemirror2/mode/jinja2/index.html +37 -0
  58. data/lib/public/milksteak/codemirror2/mode/jinja2/jinja2.js +42 -0
  59. data/lib/public/milksteak/codemirror2/mode/less/index.html +577 -0
  60. data/lib/public/milksteak/codemirror2/mode/less/less.js +186 -0
  61. data/lib/public/milksteak/codemirror2/mode/lua/index.html +72 -0
  62. data/lib/public/milksteak/codemirror2/mode/lua/lua.js +140 -0
  63. data/lib/public/milksteak/codemirror2/mode/markdown/index.html +339 -0
  64. data/lib/public/milksteak/codemirror2/mode/markdown/markdown.js +276 -0
  65. data/lib/public/milksteak/codemirror2/mode/mysql/index.html +41 -0
  66. data/lib/public/milksteak/codemirror2/mode/mysql/mysql.js +188 -0
  67. data/lib/public/milksteak/codemirror2/mode/ntriples/index.html +32 -0
  68. data/lib/public/milksteak/codemirror2/mode/ntriples/ntriples.js +172 -0
  69. data/lib/public/milksteak/codemirror2/mode/pascal/LICENSE +7 -0
  70. data/lib/public/milksteak/codemirror2/mode/pascal/index.html +48 -0
  71. data/lib/public/milksteak/codemirror2/mode/pascal/pascal.js +94 -0
  72. data/lib/public/milksteak/codemirror2/mode/perl/LICENSE +19 -0
  73. data/lib/public/milksteak/codemirror2/mode/perl/index.html +62 -0
  74. data/lib/public/milksteak/codemirror2/mode/perl/perl.js +816 -0
  75. data/lib/public/milksteak/codemirror2/mode/php/index.html +48 -0
  76. data/lib/public/milksteak/codemirror2/mode/php/php.js +150 -0
  77. data/lib/public/milksteak/codemirror2/mode/plsql/index.html +62 -0
  78. data/lib/public/milksteak/codemirror2/mode/plsql/plsql.js +217 -0
  79. data/lib/public/milksteak/codemirror2/mode/properties/index.html +40 -0
  80. data/lib/public/milksteak/codemirror2/mode/properties/properties.css +3 -0
  81. data/lib/public/milksteak/codemirror2/mode/properties/properties.js +57 -0
  82. data/lib/public/milksteak/codemirror2/mode/python/LICENSE.txt +21 -0
  83. data/lib/public/milksteak/codemirror2/mode/python/index.html +122 -0
  84. data/lib/public/milksteak/codemirror2/mode/python/python.js +340 -0
  85. data/lib/public/milksteak/codemirror2/mode/r/LICENSE +24 -0
  86. data/lib/public/milksteak/codemirror2/mode/r/index.html +73 -0
  87. data/lib/public/milksteak/codemirror2/mode/r/r.js +141 -0
  88. data/lib/public/milksteak/codemirror2/mode/rpm/changes/changes.js +19 -0
  89. data/lib/public/milksteak/codemirror2/mode/rpm/changes/index.html +53 -0
  90. data/lib/public/milksteak/codemirror2/mode/rpm/spec/index.html +99 -0
  91. data/lib/public/milksteak/codemirror2/mode/rpm/spec/spec.css +5 -0
  92. data/lib/public/milksteak/codemirror2/mode/rpm/spec/spec.js +66 -0
  93. data/lib/public/milksteak/codemirror2/mode/rst/index.html +525 -0
  94. data/lib/public/milksteak/codemirror2/mode/rst/rst.js +326 -0
  95. data/lib/public/milksteak/codemirror2/mode/ruby/LICENSE +24 -0
  96. data/lib/public/milksteak/codemirror2/mode/ruby/index.html +171 -0
  97. data/lib/public/milksteak/codemirror2/mode/ruby/ruby.js +200 -0
  98. data/lib/public/milksteak/codemirror2/mode/rust/index.html +48 -0
  99. data/lib/public/milksteak/codemirror2/mode/rust/rust.js +432 -0
  100. data/lib/public/milksteak/codemirror2/mode/scheme/index.html +64 -0
  101. data/lib/public/milksteak/codemirror2/mode/scheme/scheme.js +202 -0
  102. data/lib/public/milksteak/codemirror2/mode/smalltalk/index.html +55 -0
  103. data/lib/public/milksteak/codemirror2/mode/smalltalk/smalltalk.js +139 -0
  104. data/lib/public/milksteak/codemirror2/mode/sparql/index.html +40 -0
  105. data/lib/public/milksteak/codemirror2/mode/sparql/sparql.js +143 -0
  106. data/lib/public/milksteak/codemirror2/mode/stex/index.html +95 -0
  107. data/lib/public/milksteak/codemirror2/mode/stex/stex.js +167 -0
  108. data/lib/public/milksteak/codemirror2/mode/tiddlywiki/index.html +183 -0
  109. data/lib/public/milksteak/codemirror2/mode/tiddlywiki/tiddlywiki.css +21 -0
  110. data/lib/public/milksteak/codemirror2/mode/tiddlywiki/tiddlywiki.js +374 -0
  111. data/lib/public/milksteak/codemirror2/mode/velocity/index.html +103 -0
  112. data/lib/public/milksteak/codemirror2/mode/velocity/velocity.js +146 -0
  113. data/lib/public/milksteak/codemirror2/mode/verilog/index.html +210 -0
  114. data/lib/public/milksteak/codemirror2/mode/verilog/verilog.js +194 -0
  115. data/lib/public/milksteak/codemirror2/mode/xml/index.html +45 -0
  116. data/lib/public/milksteak/codemirror2/mode/xml/xml.js +267 -0
  117. data/lib/public/milksteak/codemirror2/mode/xmlpure/index.html +59 -0
  118. data/lib/public/milksteak/codemirror2/mode/xmlpure/xmlpure.js +490 -0
  119. data/lib/public/milksteak/codemirror2/mode/yaml/index.html +67 -0
  120. data/lib/public/milksteak/codemirror2/mode/yaml/yaml.js +95 -0
  121. data/lib/public/milksteak/codemirror2/theme/cobalt.css +18 -0
  122. data/lib/public/milksteak/codemirror2/theme/eclipse.css +25 -0
  123. data/lib/public/milksteak/codemirror2/theme/elegant.css +10 -0
  124. data/lib/public/milksteak/codemirror2/theme/monokai.css +28 -0
  125. data/lib/public/milksteak/codemirror2/theme/neat.css +9 -0
  126. data/lib/public/milksteak/codemirror2/theme/night.css +21 -0
  127. data/lib/public/milksteak/codemirror2/theme/rubyblue.css +21 -0
  128. data/lib/public/milksteak/css/bootstrap-responsive.css +567 -0
  129. data/lib/public/milksteak/css/bootstrap-responsive.min.css +3 -0
  130. data/lib/public/milksteak/css/bootstrap.css +3365 -0
  131. data/lib/public/milksteak/css/bootstrap.min.css +610 -0
  132. data/lib/public/milksteak/css/calendrical.css +69 -0
  133. data/lib/public/milksteak/css/prettify.css +52 -0
  134. data/lib/public/milksteak/css/style.css +8 -0
  135. data/lib/public/milksteak/img/glyphicons-halflings-white.png +0 -0
  136. data/lib/public/milksteak/img/glyphicons-halflings.png +0 -0
  137. data/lib/public/milksteak/img/spinner.gif +0 -0
  138. data/lib/public/milksteak/jqueryFileTree/connectors/jqueryFileTree.asp +44 -0
  139. data/lib/public/milksteak/jqueryFileTree/connectors/jqueryFileTree.aspx +31 -0
  140. data/lib/public/milksteak/jqueryFileTree/connectors/jqueryFileTree.cf +19 -0
  141. data/lib/public/milksteak/jqueryFileTree/connectors/jqueryFileTree.jsp +49 -0
  142. data/lib/public/milksteak/jqueryFileTree/connectors/jqueryFileTree.php +43 -0
  143. data/lib/public/milksteak/jqueryFileTree/connectors/jqueryFileTree.pl +102 -0
  144. data/lib/public/milksteak/jqueryFileTree/connectors/jqueryFileTree.py +25 -0
  145. data/lib/public/milksteak/jqueryFileTree/connectors/jqueryFileTree.rb +61 -0
  146. data/lib/public/milksteak/jqueryFileTree/connectors/jqueryFileTree_huck.lasso +36 -0
  147. data/lib/public/milksteak/jqueryFileTree/connectors/jqueryFileTree_sabourdin.lasso +48 -0
  148. data/lib/public/milksteak/jqueryFileTree/images/application.png +0 -0
  149. data/lib/public/milksteak/jqueryFileTree/images/code.png +0 -0
  150. data/lib/public/milksteak/jqueryFileTree/images/css.png +0 -0
  151. data/lib/public/milksteak/jqueryFileTree/images/db.png +0 -0
  152. data/lib/public/milksteak/jqueryFileTree/images/directory.png +0 -0
  153. data/lib/public/milksteak/jqueryFileTree/images/doc.png +0 -0
  154. data/lib/public/milksteak/jqueryFileTree/images/file.png +0 -0
  155. data/lib/public/milksteak/jqueryFileTree/images/film.png +0 -0
  156. data/lib/public/milksteak/jqueryFileTree/images/flash.png +0 -0
  157. data/lib/public/milksteak/jqueryFileTree/images/folder_open.png +0 -0
  158. data/lib/public/milksteak/jqueryFileTree/images/html.png +0 -0
  159. data/lib/public/milksteak/jqueryFileTree/images/java.png +0 -0
  160. data/lib/public/milksteak/jqueryFileTree/images/linux.png +0 -0
  161. data/lib/public/milksteak/jqueryFileTree/images/music.png +0 -0
  162. data/lib/public/milksteak/jqueryFileTree/images/pdf.png +0 -0
  163. data/lib/public/milksteak/jqueryFileTree/images/php.png +0 -0
  164. data/lib/public/milksteak/jqueryFileTree/images/picture.png +0 -0
  165. data/lib/public/milksteak/jqueryFileTree/images/ppt.png +0 -0
  166. data/lib/public/milksteak/jqueryFileTree/images/psd.png +0 -0
  167. data/lib/public/milksteak/jqueryFileTree/images/ruby.png +0 -0
  168. data/lib/public/milksteak/jqueryFileTree/images/script.png +0 -0
  169. data/lib/public/milksteak/jqueryFileTree/images/spinner.gif +0 -0
  170. data/lib/public/milksteak/jqueryFileTree/images/txt.png +0 -0
  171. data/lib/public/milksteak/jqueryFileTree/images/xls.png +0 -0
  172. data/lib/public/milksteak/jqueryFileTree/images/zip.png +0 -0
  173. data/lib/public/milksteak/jqueryFileTree/jqueryFileTree.css +91 -0
  174. data/lib/public/milksteak/jqueryFileTree/jqueryFileTree.js +95 -0
  175. data/lib/public/milksteak/js/app.js +0 -0
  176. data/lib/public/milksteak/js/backbone.js +1290 -0
  177. data/lib/public/milksteak/js/bootstrap-alert.js +91 -0
  178. data/lib/public/milksteak/js/bootstrap-button.js +98 -0
  179. data/lib/public/milksteak/js/bootstrap-carousel.js +154 -0
  180. data/lib/public/milksteak/js/bootstrap-collapse.js +136 -0
  181. data/lib/public/milksteak/js/bootstrap-dropdown.js +92 -0
  182. data/lib/public/milksteak/js/bootstrap-modal.js +209 -0
  183. data/lib/public/milksteak/js/bootstrap-popover.js +95 -0
  184. data/lib/public/milksteak/js/bootstrap-scrollspy.js +125 -0
  185. data/lib/public/milksteak/js/bootstrap-tab.js +130 -0
  186. data/lib/public/milksteak/js/bootstrap-tooltip.js +270 -0
  187. data/lib/public/milksteak/js/bootstrap-transition.js +51 -0
  188. data/lib/public/milksteak/js/bootstrap-typeahead.js +271 -0
  189. data/lib/public/milksteak/js/bootstrap.js +1722 -0
  190. data/lib/public/milksteak/js/bootstrap.min.js +1 -0
  191. data/lib/public/milksteak/js/jquery-ui.min.js +15 -0
  192. data/lib/public/milksteak/js/jquery.calendrical.js +490 -0
  193. data/lib/public/milksteak/js/jquery.easing.js +146 -0
  194. data/lib/public/milksteak/js/jquery.js +9252 -0
  195. data/lib/public/milksteak/js/mustache.js +536 -0
  196. data/lib/public/milksteak/js/prettify.js +28 -0
  197. data/lib/public/milksteak/js/underscore.js +999 -0
  198. data/lib/public/milksteak/markitup/.DS_Store +0 -0
  199. data/lib/public/milksteak/markitup/jquery.markitup.js +593 -0
  200. data/lib/public/milksteak/markitup/sets/default/images/bold.png +0 -0
  201. data/lib/public/milksteak/markitup/sets/default/images/clean.png +0 -0
  202. data/lib/public/milksteak/markitup/sets/default/images/image.png +0 -0
  203. data/lib/public/milksteak/markitup/sets/default/images/italic.png +0 -0
  204. data/lib/public/milksteak/markitup/sets/default/images/link.png +0 -0
  205. data/lib/public/milksteak/markitup/sets/default/images/list-bullet.png +0 -0
  206. data/lib/public/milksteak/markitup/sets/default/images/list-numeric.png +0 -0
  207. data/lib/public/milksteak/markitup/sets/default/images/picture.png +0 -0
  208. data/lib/public/milksteak/markitup/sets/default/images/preview.png +0 -0
  209. data/lib/public/milksteak/markitup/sets/default/images/stroke.png +0 -0
  210. data/lib/public/milksteak/markitup/sets/default/set.js +30 -0
  211. data/lib/public/milksteak/markitup/sets/default/style.css +34 -0
  212. data/lib/public/milksteak/markitup/sets/textile/images/bold.png +0 -0
  213. data/lib/public/milksteak/markitup/sets/textile/images/code.png +0 -0
  214. data/lib/public/milksteak/markitup/sets/textile/images/h1.png +0 -0
  215. data/lib/public/milksteak/markitup/sets/textile/images/h2.png +0 -0
  216. data/lib/public/milksteak/markitup/sets/textile/images/h3.png +0 -0
  217. data/lib/public/milksteak/markitup/sets/textile/images/h4.png +0 -0
  218. data/lib/public/milksteak/markitup/sets/textile/images/h5.png +0 -0
  219. data/lib/public/milksteak/markitup/sets/textile/images/h6.png +0 -0
  220. data/lib/public/milksteak/markitup/sets/textile/images/italic.png +0 -0
  221. data/lib/public/milksteak/markitup/sets/textile/images/link.png +0 -0
  222. data/lib/public/milksteak/markitup/sets/textile/images/list-bullet.png +0 -0
  223. data/lib/public/milksteak/markitup/sets/textile/images/list-numeric.png +0 -0
  224. data/lib/public/milksteak/markitup/sets/textile/images/paragraph.png +0 -0
  225. data/lib/public/milksteak/markitup/sets/textile/images/picture.png +0 -0
  226. data/lib/public/milksteak/markitup/sets/textile/images/preview.png +0 -0
  227. data/lib/public/milksteak/markitup/sets/textile/images/quotes.png +0 -0
  228. data/lib/public/milksteak/markitup/sets/textile/images/stroke.png +0 -0
  229. data/lib/public/milksteak/markitup/sets/textile/set.js +33 -0
  230. data/lib/public/milksteak/markitup/sets/textile/style.css +60 -0
  231. data/lib/public/milksteak/markitup/skins/markitup/images/bg-container.png +0 -0
  232. data/lib/public/milksteak/markitup/skins/markitup/images/bg-editor-bbcode.png +0 -0
  233. data/lib/public/milksteak/markitup/skins/markitup/images/bg-editor-dotclear.png +0 -0
  234. data/lib/public/milksteak/markitup/skins/markitup/images/bg-editor-html.png +0 -0
  235. data/lib/public/milksteak/markitup/skins/markitup/images/bg-editor-json.png +0 -0
  236. data/lib/public/milksteak/markitup/skins/markitup/images/bg-editor-markdown.png +0 -0
  237. data/lib/public/milksteak/markitup/skins/markitup/images/bg-editor-textile.png +0 -0
  238. data/lib/public/milksteak/markitup/skins/markitup/images/bg-editor-wiki.png +0 -0
  239. data/lib/public/milksteak/markitup/skins/markitup/images/bg-editor-xml.png +0 -0
  240. data/lib/public/milksteak/markitup/skins/markitup/images/bg-editor.png +0 -0
  241. data/lib/public/milksteak/markitup/skins/markitup/images/handle.png +0 -0
  242. data/lib/public/milksteak/markitup/skins/markitup/images/menu.png +0 -0
  243. data/lib/public/milksteak/markitup/skins/markitup/images/submenu.png +0 -0
  244. data/lib/public/milksteak/markitup/skins/markitup/style.css +147 -0
  245. data/lib/public/milksteak/markitup/skins/simple/images/handle.png +0 -0
  246. data/lib/public/milksteak/markitup/skins/simple/images/menu.png +0 -0
  247. data/lib/public/milksteak/markitup/skins/simple/images/submenu.png +0 -0
  248. data/lib/public/milksteak/markitup/skins/simple/style.css +118 -0
  249. data/lib/public/milksteak/markitup/templates/preview.css +5 -0
  250. data/lib/public/milksteak/markitup/templates/preview.html +11 -0
  251. data/lib/public/milksteak/uploadify-v2.1.4/cancel.png +0 -0
  252. data/lib/public/milksteak/uploadify-v2.1.4/check.php +35 -0
  253. data/lib/public/milksteak/uploadify-v2.1.4/expressInstall.swf +0 -0
  254. data/lib/public/milksteak/uploadify-v2.1.4/jquery-1.4.2.min.js +154 -0
  255. data/lib/public/milksteak/uploadify-v2.1.4/jquery.uploadify.v2.1.4.js +296 -0
  256. data/lib/public/milksteak/uploadify-v2.1.4/jquery.uploadify.v2.1.4.min.js +26 -0
  257. data/lib/public/milksteak/uploadify-v2.1.4/swfobject.js +4 -0
  258. data/lib/public/milksteak/uploadify-v2.1.4/uploadify.allglyphs.swf +0 -0
  259. data/lib/public/milksteak/uploadify-v2.1.4/uploadify.css +53 -0
  260. data/lib/public/milksteak/uploadify-v2.1.4/uploadify.fla +0 -0
  261. data/lib/public/milksteak/uploadify-v2.1.4/uploadify.php +46 -0
  262. data/lib/public/milksteak/uploadify-v2.1.4/uploadify.swf +0 -0
  263. data/lib/public/milksteak/wmd/Markdown.Converter.js +1332 -0
  264. data/lib/public/milksteak/wmd/Markdown.Editor.js +2160 -0
  265. data/lib/public/milksteak/wmd/Markdown.Sanitizer.js +108 -0
  266. data/lib/public/milksteak/wmd/wmd-buttons.png +0 -0
  267. data/lib/public/milksteak/wmd/wmd.css +103 -0
  268. data/lib/public/milksteak/wymeditor/iframe/default/lbl-blockquote.png +0 -0
  269. data/lib/public/milksteak/wymeditor/iframe/default/lbl-h1.png +0 -0
  270. data/lib/public/milksteak/wymeditor/iframe/default/lbl-h2.png +0 -0
  271. data/lib/public/milksteak/wymeditor/iframe/default/lbl-h3.png +0 -0
  272. data/lib/public/milksteak/wymeditor/iframe/default/lbl-h4.png +0 -0
  273. data/lib/public/milksteak/wymeditor/iframe/default/lbl-h5.png +0 -0
  274. data/lib/public/milksteak/wymeditor/iframe/default/lbl-h6.png +0 -0
  275. data/lib/public/milksteak/wymeditor/iframe/default/lbl-p.png +0 -0
  276. data/lib/public/milksteak/wymeditor/iframe/default/lbl-pre.png +0 -0
  277. data/lib/public/milksteak/wymeditor/iframe/default/wymiframe.css +90 -0
  278. data/lib/public/milksteak/wymeditor/iframe/default/wymiframe.html +26 -0
  279. data/lib/public/milksteak/wymeditor/jquery.wymeditor.js +4688 -0
  280. data/lib/public/milksteak/wymeditor/jquery.wymeditor.min.js +1 -0
  281. data/lib/public/milksteak/wymeditor/jquery.wymeditor.pack.js +1 -0
  282. data/lib/public/milksteak/wymeditor/lang/bg.js +45 -0
  283. data/lib/public/milksteak/wymeditor/lang/ca.js +45 -0
  284. data/lib/public/milksteak/wymeditor/lang/cs.js +45 -0
  285. data/lib/public/milksteak/wymeditor/lang/cy.js +45 -0
  286. data/lib/public/milksteak/wymeditor/lang/de.js +45 -0
  287. data/lib/public/milksteak/wymeditor/lang/en.js +45 -0
  288. data/lib/public/milksteak/wymeditor/lang/es.js +45 -0
  289. data/lib/public/milksteak/wymeditor/lang/fa.js +46 -0
  290. data/lib/public/milksteak/wymeditor/lang/fi.js +44 -0
  291. data/lib/public/milksteak/wymeditor/lang/fr.js +45 -0
  292. data/lib/public/milksteak/wymeditor/lang/gl.js +45 -0
  293. data/lib/public/milksteak/wymeditor/lang/he.js +45 -0
  294. data/lib/public/milksteak/wymeditor/lang/hr.js +45 -0
  295. data/lib/public/milksteak/wymeditor/lang/hu.js +45 -0
  296. data/lib/public/milksteak/wymeditor/lang/it.js +45 -0
  297. data/lib/public/milksteak/wymeditor/lang/nb.js +45 -0
  298. data/lib/public/milksteak/wymeditor/lang/nl.js +45 -0
  299. data/lib/public/milksteak/wymeditor/lang/nn.js +45 -0
  300. data/lib/public/milksteak/wymeditor/lang/pl.js +45 -0
  301. data/lib/public/milksteak/wymeditor/lang/pt-br.js +45 -0
  302. data/lib/public/milksteak/wymeditor/lang/pt.js +45 -0
  303. data/lib/public/milksteak/wymeditor/lang/ru.js +45 -0
  304. data/lib/public/milksteak/wymeditor/lang/sv.js +45 -0
  305. data/lib/public/milksteak/wymeditor/lang/tr.js +45 -0
  306. data/lib/public/milksteak/wymeditor/lang/zh_cn.js +47 -0
  307. data/lib/public/milksteak/wymeditor/plugins/embed/jquery.wymeditor.embed.js +52 -0
  308. data/lib/public/milksteak/wymeditor/plugins/fullscreen/icon_fullscreen.gif +0 -0
  309. data/lib/public/milksteak/wymeditor/plugins/fullscreen/jquery.wymeditor.fullscreen.js +127 -0
  310. data/lib/public/milksteak/wymeditor/plugins/hovertools/jquery.wymeditor.hovertools.js +57 -0
  311. data/lib/public/milksteak/wymeditor/plugins/resizable/jquery.wymeditor.resizable.js +91 -0
  312. data/lib/public/milksteak/wymeditor/plugins/resizable/readme.txt +124 -0
  313. data/lib/public/milksteak/wymeditor/plugins/tidy/README +19 -0
  314. data/lib/public/milksteak/wymeditor/plugins/tidy/jquery.wymeditor.tidy.js +82 -0
  315. data/lib/public/milksteak/wymeditor/plugins/tidy/tidy.php +36 -0
  316. data/lib/public/milksteak/wymeditor/plugins/tidy/wand.png +0 -0
  317. data/lib/public/milksteak/wymeditor/skins/compact/icons.png +0 -0
  318. data/lib/public/milksteak/wymeditor/skins/compact/skin.css +134 -0
  319. data/lib/public/milksteak/wymeditor/skins/compact/skin.js +35 -0
  320. data/lib/public/milksteak/wymeditor/skins/default/icons.png +0 -0
  321. data/lib/public/milksteak/wymeditor/skins/default/skin.css +133 -0
  322. data/lib/public/milksteak/wymeditor/skins/default/skin.js +40 -0
  323. data/lib/public/milksteak/wymeditor/skins/minimal/images/bg.header.gif +0 -0
  324. data/lib/public/milksteak/wymeditor/skins/minimal/images/bg.selector.silver.gif +0 -0
  325. data/lib/public/milksteak/wymeditor/skins/minimal/images/bg.wymeditor.png +0 -0
  326. data/lib/public/milksteak/wymeditor/skins/minimal/images/icons.silver.gif +0 -0
  327. data/lib/public/milksteak/wymeditor/skins/minimal/skin.css +131 -0
  328. data/lib/public/milksteak/wymeditor/skins/minimal/skin.js +30 -0
  329. data/lib/public/milksteak/wymeditor/skins/silver/COPYING +674 -0
  330. data/lib/public/milksteak/wymeditor/skins/silver/README +27 -0
  331. data/lib/public/milksteak/wymeditor/skins/silver/images/bg.header.gif +0 -0
  332. data/lib/public/milksteak/wymeditor/skins/silver/images/bg.selector.silver.gif +0 -0
  333. data/lib/public/milksteak/wymeditor/skins/silver/images/bg.wymeditor.png +0 -0
  334. data/lib/public/milksteak/wymeditor/skins/silver/images/icons.silver.gif +0 -0
  335. data/lib/public/milksteak/wymeditor/skins/silver/skin.css +297 -0
  336. data/lib/public/milksteak/wymeditor/skins/silver/skin.js +61 -0
  337. data/lib/public/milksteak/wymeditor/skins/twopanels/icons.png +0 -0
  338. data/lib/public/milksteak/wymeditor/skins/twopanels/skin.css +134 -0
  339. data/lib/public/milksteak/wymeditor/skins/twopanels/skin.js +39 -0
  340. data/lib/public/milksteak/wymeditor/skins/wymeditor_icon.png +0 -0
  341. data/lib/views/layouts/admin.erb +8 -0
  342. data/lib/views/login.erb +1 -0
  343. data/milksteak.gemspec +30 -13
  344. data/spec/fixtures/pages/sample_page.yml +5 -0
  345. data/spec/lib/milksteak/cms_spec.rb +12 -0
  346. data/spec/models/page_spec.rb +58 -0
  347. data/spec/spec_helper.rb +19 -0
  348. metadata +429 -10
  349. data/LICENSE +0 -22
  350. data/README.md +0 -29
@@ -0,0 +1,23 @@
1
+ .CodeMirror-dialog {
2
+ position: relative;
3
+ }
4
+
5
+ .CodeMirror-dialog > div {
6
+ position: absolute;
7
+ top: 0; left: 0; right: 0;
8
+ background: white;
9
+ border-bottom: 1px solid #eee;
10
+ z-index: 15;
11
+ padding: .1em .8em;
12
+ overflow: hidden;
13
+ color: #333;
14
+ }
15
+
16
+ .CodeMirror-dialog input {
17
+ border: none;
18
+ outline: none;
19
+ background: transparent;
20
+ width: 20em;
21
+ color: inherit;
22
+ font-family: monospace;
23
+ }
@@ -0,0 +1,63 @@
1
+ // Open simple dialogs on top of an editor. Relies on dialog.css.
2
+
3
+ (function() {
4
+ function dialogDiv(cm, template) {
5
+ var wrap = cm.getWrapperElement();
6
+ var dialog = wrap.insertBefore(document.createElement("div"), wrap.firstChild);
7
+ dialog.className = "CodeMirror-dialog";
8
+ dialog.innerHTML = '<div>' + template + '</div>';
9
+ return dialog;
10
+ }
11
+
12
+ CodeMirror.defineExtension("openDialog", function(template, callback) {
13
+ var dialog = dialogDiv(this, template);
14
+ var closed = false, me = this;
15
+ function close() {
16
+ if (closed) return;
17
+ closed = true;
18
+ dialog.parentNode.removeChild(dialog);
19
+ }
20
+ var inp = dialog.getElementsByTagName("input")[0];
21
+ if (inp) {
22
+ CodeMirror.connect(inp, "keydown", function(e) {
23
+ if (e.keyCode == 13 || e.keyCode == 27) {
24
+ CodeMirror.e_stop(e);
25
+ close();
26
+ me.focus();
27
+ if (e.keyCode == 13) callback(inp.value);
28
+ }
29
+ });
30
+ inp.focus();
31
+ CodeMirror.connect(inp, "blur", close);
32
+ }
33
+ return close;
34
+ });
35
+
36
+ CodeMirror.defineExtension("openConfirm", function(template, callbacks) {
37
+ var dialog = dialogDiv(this, template);
38
+ var buttons = dialog.getElementsByTagName("button");
39
+ var closed = false, me = this, blurring = 1;
40
+ function close() {
41
+ if (closed) return;
42
+ closed = true;
43
+ dialog.parentNode.removeChild(dialog);
44
+ me.focus();
45
+ }
46
+ buttons[0].focus();
47
+ for (var i = 0; i < buttons.length; ++i) {
48
+ var b = buttons[i];
49
+ (function(callback) {
50
+ CodeMirror.connect(b, "click", function(e) {
51
+ CodeMirror.e_preventDefault(e);
52
+ close();
53
+ if (callback) callback(me);
54
+ });
55
+ })(callbacks[i]);
56
+ CodeMirror.connect(b, "blur", function() {
57
+ --blurring;
58
+ setTimeout(function() { if (blurring <= 0) close(); }, 200);
59
+ });
60
+ CodeMirror.connect(b, "focus", function() { ++blurring; });
61
+ }
62
+ });
63
+ })();
@@ -0,0 +1,186 @@
1
+ // the tagRangeFinder function is
2
+ // Copyright (C) 2011 by Daniel Glazman <daniel@glazman.org>
3
+ // released under the MIT license (../../LICENSE) like the rest of CodeMirror
4
+ CodeMirror.tagRangeFinder = function(cm, line) {
5
+ var nameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
6
+ var nameChar = nameStartChar + "\-\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
7
+ var xmlNAMERegExp = new RegExp("^[" + nameStartChar + "][" + nameChar + "]*");
8
+
9
+ var lineText = cm.getLine(line);
10
+ var found = false;
11
+ var tag = null;
12
+ var pos = 0;
13
+ while (!found) {
14
+ pos = lineText.indexOf("<", pos);
15
+ if (-1 == pos) // no tag on line
16
+ return;
17
+ if (pos + 1 < lineText.length && lineText[pos + 1] == "/") { // closing tag
18
+ pos++;
19
+ continue;
20
+ }
21
+ // ok we weem to have a start tag
22
+ if (!lineText.substr(pos + 1).match(xmlNAMERegExp)) { // not a tag name...
23
+ pos++;
24
+ continue;
25
+ }
26
+ var gtPos = lineText.indexOf(">", pos + 1);
27
+ if (-1 == gtPos) { // end of start tag not in line
28
+ var l = line + 1;
29
+ var foundGt = false;
30
+ var lastLine = cm.lineCount();
31
+ while (l < lastLine && !foundGt) {
32
+ var lt = cm.getLine(l);
33
+ var gt = lt.indexOf(">");
34
+ if (-1 != gt) { // found a >
35
+ foundGt = true;
36
+ var slash = lt.lastIndexOf("/", gt);
37
+ if (-1 != slash && slash < gt) {
38
+ var str = lineText.substr(slash, gt - slash + 1);
39
+ if (!str.match( /\/\s*\>/ )) // yep, that's the end of empty tag
40
+ return l+1;
41
+ }
42
+ }
43
+ l++;
44
+ }
45
+ found = true;
46
+ }
47
+ else {
48
+ var slashPos = lineText.lastIndexOf("/", gtPos);
49
+ if (-1 == slashPos) { // cannot be empty tag
50
+ found = true;
51
+ // don't continue
52
+ }
53
+ else { // empty tag?
54
+ // check if really empty tag
55
+ var str = lineText.substr(slashPos, gtPos - slashPos + 1);
56
+ if (!str.match( /\/\s*\>/ )) { // finally not empty
57
+ found = true;
58
+ // don't continue
59
+ }
60
+ }
61
+ }
62
+ if (found) {
63
+ var subLine = lineText.substr(pos + 1);
64
+ tag = subLine.match(xmlNAMERegExp);
65
+ if (tag) {
66
+ // we have an element name, wooohooo !
67
+ tag = tag[0];
68
+ // do we have the close tag on same line ???
69
+ if (-1 != lineText.indexOf("</" + tag + ">", pos)) // yep
70
+ {
71
+ found = false;
72
+ }
73
+ // we don't, so we have a candidate...
74
+ }
75
+ else
76
+ found = false;
77
+ }
78
+ if (!found)
79
+ pos++;
80
+ }
81
+
82
+ if (found) {
83
+ var startTag = "(\\<\\/" + tag + "\\>)|(\\<" + tag + "\\>)|(\\<" + tag + "\s)|(\\<" + tag + "$)";
84
+ var startTagRegExp = new RegExp(startTag, "g");
85
+ var endTag = "</" + tag + ">";
86
+ var depth = 1;
87
+ var l = line + 1;
88
+ var lastLine = cm.lineCount();
89
+ while (l < lastLine) {
90
+ lineText = cm.getLine(l);
91
+ var match = lineText.match(startTagRegExp);
92
+ if (match) {
93
+ for (var i = 0; i < match.length; i++) {
94
+ if (match[i] == endTag)
95
+ depth--;
96
+ else
97
+ depth++;
98
+ if (!depth)
99
+ return l+1;
100
+ }
101
+ }
102
+ l++;
103
+ }
104
+ return;
105
+ }
106
+ };
107
+
108
+ CodeMirror.braceRangeFinder = function(cm, line) {
109
+ var lineText = cm.getLine(line);
110
+ var startChar = lineText.lastIndexOf("{");
111
+ if (startChar < 0 || lineText.lastIndexOf("}") > startChar) return;
112
+ var tokenType = cm.getTokenAt({line: line, ch: startChar}).className;
113
+ var count = 1, lastLine = cm.lineCount(), end;
114
+ outer: for (var i = line + 1; i < lastLine; ++i) {
115
+ var text = cm.getLine(i), pos = 0;
116
+ for (;;) {
117
+ var nextOpen = text.indexOf("{", pos), nextClose = text.indexOf("}", pos);
118
+ if (nextOpen < 0) nextOpen = text.length;
119
+ if (nextClose < 0) nextClose = text.length;
120
+ pos = Math.min(nextOpen, nextClose);
121
+ if (pos == text.length) break;
122
+ if (cm.getTokenAt({line: i, ch: pos + 1}).className == tokenType) {
123
+ if (pos == nextOpen) ++count;
124
+ else if (!--count) { end = i; break outer; }
125
+ }
126
+ ++pos;
127
+ }
128
+ }
129
+ if (end == null || end == line + 1) return;
130
+ return end;
131
+ };
132
+
133
+ CodeMirror.indentRangeFinder = function(cm, line) {
134
+ var tabSize = cm.getOption("tabSize");
135
+ var myIndent = cm.getLineHandle(line).indentation(tabSize), last;
136
+ for (var i = line + 1, end = cm.lineCount(); i < end; ++i) {
137
+ var handle = cm.getLineHandle(i);
138
+ if (!/^\s*$/.test(handle.text)) {
139
+ if (handle.indentation(tabSize) <= myIndent) break;
140
+ last = i;
141
+ }
142
+ }
143
+ if (!last) return null;
144
+ return last + 1;
145
+ };
146
+
147
+ CodeMirror.newFoldFunction = function(rangeFinder, markText) {
148
+ var folded = [];
149
+ if (markText == null) markText = '<div style="position: absolute; left: 2px; color:#600">&#x25bc;</div>%N%';
150
+
151
+ function isFolded(cm, n) {
152
+ for (var i = 0; i < folded.length; ++i) {
153
+ var start = cm.lineInfo(folded[i].start);
154
+ if (!start) folded.splice(i--, 1);
155
+ else if (start.line == n) return {pos: i, region: folded[i]};
156
+ }
157
+ }
158
+
159
+ function expand(cm, region) {
160
+ cm.clearMarker(region.start);
161
+ for (var i = 0; i < region.hidden.length; ++i)
162
+ cm.showLine(region.hidden[i]);
163
+ }
164
+
165
+ return function(cm, line) {
166
+ cm.operation(function() {
167
+ var known = isFolded(cm, line);
168
+ if (known) {
169
+ folded.splice(known.pos, 1);
170
+ expand(cm, known.region);
171
+ } else {
172
+ var end = rangeFinder(cm, line);
173
+ if (end == null) return;
174
+ var hidden = [];
175
+ for (var i = line + 1; i < end; ++i) {
176
+ var handle = cm.hideLine(i);
177
+ if (handle) hidden.push(handle);
178
+ }
179
+ var first = cm.setMarker(line, markText);
180
+ var region = {start: first, hidden: hidden};
181
+ cm.onDeleteLine(first, function() { expand(cm, region); });
182
+ folded.push(region);
183
+ }
184
+ });
185
+ };
186
+ };
@@ -0,0 +1,294 @@
1
+ // ============== Formatting extensions ============================
2
+ // A common storage for all mode-specific formatting features
3
+ if (!CodeMirror.modeExtensions) CodeMirror.modeExtensions = {};
4
+
5
+ // Returns the extension of the editor's current mode
6
+ CodeMirror.defineExtension("getModeExt", function () {
7
+ var mname = CodeMirror.resolveMode(this.getOption("mode")).name;
8
+ var ext = CodeMirror.modeExtensions[mname];
9
+ if (!ext) throw new Error("No extensions found for mode " + mname);
10
+ return ext;
11
+ });
12
+
13
+ // If the current mode is 'htmlmixed', returns the extension of a mode located at
14
+ // the specified position (can be htmlmixed, css or javascript). Otherwise, simply
15
+ // returns the extension of the editor's current mode.
16
+ CodeMirror.defineExtension("getModeExtAtPos", function (pos) {
17
+ var token = this.getTokenAt(pos);
18
+ if (token && token.state && token.state.mode)
19
+ return CodeMirror.modeExtensions[token.state.mode == "html" ? "htmlmixed" : token.state.mode];
20
+ else
21
+ return this.getModeExt();
22
+ });
23
+
24
+ // Comment/uncomment the specified range
25
+ CodeMirror.defineExtension("commentRange", function (isComment, from, to) {
26
+ var curMode = this.getModeExtAtPos(this.getCursor());
27
+ if (isComment) { // Comment range
28
+ var commentedText = this.getRange(from, to);
29
+ this.replaceRange(curMode.commentStart + this.getRange(from, to) + curMode.commentEnd
30
+ , from, to);
31
+ if (from.line == to.line && from.ch == to.ch) { // An empty comment inserted - put cursor inside
32
+ this.setCursor(from.line, from.ch + curMode.commentStart.length);
33
+ }
34
+ }
35
+ else { // Uncomment range
36
+ var selText = this.getRange(from, to);
37
+ var startIndex = selText.indexOf(curMode.commentStart);
38
+ var endIndex = selText.lastIndexOf(curMode.commentEnd);
39
+ if (startIndex > -1 && endIndex > -1 && endIndex > startIndex) {
40
+ // Take string till comment start
41
+ selText = selText.substr(0, startIndex)
42
+ // From comment start till comment end
43
+ + selText.substring(startIndex + curMode.commentStart.length, endIndex)
44
+ // From comment end till string end
45
+ + selText.substr(endIndex + curMode.commentEnd.length);
46
+ }
47
+ this.replaceRange(selText, from, to);
48
+ }
49
+ });
50
+
51
+ // Applies automatic mode-aware indentation to the specified range
52
+ CodeMirror.defineExtension("autoIndentRange", function (from, to) {
53
+ var cmInstance = this;
54
+ this.operation(function () {
55
+ for (var i = from.line; i <= to.line; i++) {
56
+ cmInstance.indentLine(i, "smart");
57
+ }
58
+ });
59
+ });
60
+
61
+ // Applies automatic formatting to the specified range
62
+ CodeMirror.defineExtension("autoFormatRange", function (from, to) {
63
+ var absStart = this.indexFromPos(from);
64
+ var absEnd = this.indexFromPos(to);
65
+ // Insert additional line breaks where necessary according to the
66
+ // mode's syntax
67
+ var res = this.getModeExt().autoFormatLineBreaks(this.getValue(), absStart, absEnd);
68
+ var cmInstance = this;
69
+
70
+ // Replace and auto-indent the range
71
+ this.operation(function () {
72
+ cmInstance.replaceRange(res, from, to);
73
+ var startLine = cmInstance.posFromIndex(absStart).line;
74
+ var endLine = cmInstance.posFromIndex(absStart + res.length).line;
75
+ for (var i = startLine; i <= endLine; i++) {
76
+ cmInstance.indentLine(i, "smart");
77
+ }
78
+ });
79
+ });
80
+
81
+ // Define extensions for a few modes
82
+
83
+ CodeMirror.modeExtensions["css"] = {
84
+ commentStart: "/*",
85
+ commentEnd: "*/",
86
+ wordWrapChars: [";", "\\{", "\\}"],
87
+ autoFormatLineBreaks: function (text) {
88
+ return text.replace(new RegExp("(;|\\{|\\})([^\r\n])", "g"), "$1\n$2");
89
+ }
90
+ };
91
+
92
+ CodeMirror.modeExtensions["javascript"] = {
93
+ commentStart: "/*",
94
+ commentEnd: "*/",
95
+ wordWrapChars: [";", "\\{", "\\}"],
96
+
97
+ getNonBreakableBlocks: function (text) {
98
+ var nonBreakableRegexes = [
99
+ new RegExp("for\\s*?\\(([\\s\\S]*?)\\)"),
100
+ new RegExp("'([\\s\\S]*?)('|$)"),
101
+ new RegExp("\"([\\s\\S]*?)(\"|$)"),
102
+ new RegExp("//.*([\r\n]|$)")
103
+ ];
104
+ var nonBreakableBlocks = new Array();
105
+ for (var i = 0; i < nonBreakableRegexes.length; i++) {
106
+ var curPos = 0;
107
+ while (curPos < text.length) {
108
+ var m = text.substr(curPos).match(nonBreakableRegexes[i]);
109
+ if (m != null) {
110
+ nonBreakableBlocks.push({
111
+ start: curPos + m.index,
112
+ end: curPos + m.index + m[0].length
113
+ });
114
+ curPos += m.index + Math.max(1, m[0].length);
115
+ }
116
+ else { // No more matches
117
+ break;
118
+ }
119
+ }
120
+ }
121
+ nonBreakableBlocks.sort(function (a, b) {
122
+ return a.start - b.start;
123
+ });
124
+
125
+ return nonBreakableBlocks;
126
+ },
127
+
128
+ autoFormatLineBreaks: function (text) {
129
+ var curPos = 0;
130
+ var reLinesSplitter = new RegExp("(;|\\{|\\})([^\r\n])", "g");
131
+ var nonBreakableBlocks = this.getNonBreakableBlocks(text);
132
+ if (nonBreakableBlocks != null) {
133
+ var res = "";
134
+ for (var i = 0; i < nonBreakableBlocks.length; i++) {
135
+ if (nonBreakableBlocks[i].start > curPos) { // Break lines till the block
136
+ res += text.substring(curPos, nonBreakableBlocks[i].start).replace(reLinesSplitter, "$1\n$2");
137
+ curPos = nonBreakableBlocks[i].start;
138
+ }
139
+ if (nonBreakableBlocks[i].start <= curPos
140
+ && nonBreakableBlocks[i].end >= curPos) { // Skip non-breakable block
141
+ res += text.substring(curPos, nonBreakableBlocks[i].end);
142
+ curPos = nonBreakableBlocks[i].end;
143
+ }
144
+ }
145
+ if (curPos < text.length - 1) {
146
+ res += text.substr(curPos).replace(reLinesSplitter, "$1\n$2");
147
+ }
148
+ return res;
149
+ }
150
+ else {
151
+ return text.replace(reLinesSplitter, "$1\n$2");
152
+ }
153
+ }
154
+ };
155
+
156
+ CodeMirror.modeExtensions["xml"] = {
157
+ commentStart: "<!--",
158
+ commentEnd: "-->",
159
+ wordWrapChars: [">"],
160
+
161
+ autoFormatLineBreaks: function (text) {
162
+ var lines = text.split("\n");
163
+ var reProcessedPortion = new RegExp("(^\\s*?<|^[^<]*?)(.+)(>\\s*?$|[^>]*?$)");
164
+ var reOpenBrackets = new RegExp("<", "g");
165
+ var reCloseBrackets = new RegExp("(>)([^\r\n])", "g");
166
+ for (var i = 0; i < lines.length; i++) {
167
+ var mToProcess = lines[i].match(reProcessedPortion);
168
+ if (mToProcess != null && mToProcess.length > 3) { // The line starts with whitespaces and ends with whitespaces
169
+ lines[i] = mToProcess[1]
170
+ + mToProcess[2].replace(reOpenBrackets, "\n$&").replace(reCloseBrackets, "$1\n$2")
171
+ + mToProcess[3];
172
+ continue;
173
+ }
174
+ }
175
+
176
+ return lines.join("\n");
177
+ }
178
+ };
179
+
180
+ CodeMirror.modeExtensions["htmlmixed"] = {
181
+ commentStart: "<!--",
182
+ commentEnd: "-->",
183
+ wordWrapChars: [">", ";", "\\{", "\\}"],
184
+
185
+ getModeInfos: function (text, absPos) {
186
+ var modeInfos = new Array();
187
+ modeInfos[0] =
188
+ {
189
+ pos: 0,
190
+ modeExt: CodeMirror.modeExtensions["xml"],
191
+ modeName: "xml"
192
+ };
193
+
194
+ var modeMatchers = new Array();
195
+ modeMatchers[0] =
196
+ {
197
+ regex: new RegExp("<style[^>]*>([\\s\\S]*?)(</style[^>]*>|$)", "i"),
198
+ modeExt: CodeMirror.modeExtensions["css"],
199
+ modeName: "css"
200
+ };
201
+ modeMatchers[1] =
202
+ {
203
+ regex: new RegExp("<script[^>]*>([\\s\\S]*?)(</script[^>]*>|$)", "i"),
204
+ modeExt: CodeMirror.modeExtensions["javascript"],
205
+ modeName: "javascript"
206
+ };
207
+
208
+ var lastCharPos = (typeof (absPos) !== "undefined" ? absPos : text.length - 1);
209
+ // Detect modes for the entire text
210
+ for (var i = 0; i < modeMatchers.length; i++) {
211
+ var curPos = 0;
212
+ while (curPos <= lastCharPos) {
213
+ var m = text.substr(curPos).match(modeMatchers[i].regex);
214
+ if (m != null) {
215
+ if (m.length > 1 && m[1].length > 0) {
216
+ // Push block begin pos
217
+ var blockBegin = curPos + m.index + m[0].indexOf(m[1]);
218
+ modeInfos.push(
219
+ {
220
+ pos: blockBegin,
221
+ modeExt: modeMatchers[i].modeExt,
222
+ modeName: modeMatchers[i].modeName
223
+ });
224
+ // Push block end pos
225
+ modeInfos.push(
226
+ {
227
+ pos: blockBegin + m[1].length,
228
+ modeExt: modeInfos[0].modeExt,
229
+ modeName: modeInfos[0].modeName
230
+ });
231
+ curPos += m.index + m[0].length;
232
+ continue;
233
+ }
234
+ else {
235
+ curPos += m.index + Math.max(m[0].length, 1);
236
+ }
237
+ }
238
+ else { // No more matches
239
+ break;
240
+ }
241
+ }
242
+ }
243
+ // Sort mode infos
244
+ modeInfos.sort(function sortModeInfo(a, b) {
245
+ return a.pos - b.pos;
246
+ });
247
+
248
+ return modeInfos;
249
+ },
250
+
251
+ autoFormatLineBreaks: function (text, startPos, endPos) {
252
+ var modeInfos = this.getModeInfos(text);
253
+ var reBlockStartsWithNewline = new RegExp("^\\s*?\n");
254
+ var reBlockEndsWithNewline = new RegExp("\n\\s*?$");
255
+ var res = "";
256
+ // Use modes info to break lines correspondingly
257
+ if (modeInfos.length > 1) { // Deal with multi-mode text
258
+ for (var i = 1; i <= modeInfos.length; i++) {
259
+ var selStart = modeInfos[i - 1].pos;
260
+ var selEnd = (i < modeInfos.length ? modeInfos[i].pos : endPos);
261
+
262
+ if (selStart >= endPos) { // The block starts later than the needed fragment
263
+ break;
264
+ }
265
+ if (selStart < startPos) {
266
+ if (selEnd <= startPos) { // The block starts earlier than the needed fragment
267
+ continue;
268
+ }
269
+ selStart = startPos;
270
+ }
271
+ if (selEnd > endPos) {
272
+ selEnd = endPos;
273
+ }
274
+ var textPortion = text.substring(selStart, selEnd);
275
+ if (modeInfos[i - 1].modeName != "xml") { // Starting a CSS or JavaScript block
276
+ if (!reBlockStartsWithNewline.test(textPortion)
277
+ && selStart > 0) { // The block does not start with a line break
278
+ textPortion = "\n" + textPortion;
279
+ }
280
+ if (!reBlockEndsWithNewline.test(textPortion)
281
+ && selEnd < text.length - 1) { // The block does not end with a line break
282
+ textPortion += "\n";
283
+ }
284
+ }
285
+ res += modeInfos[i - 1].modeExt.autoFormatLineBreaks(textPortion);
286
+ }
287
+ }
288
+ else { // Single-mode text
289
+ res = modeInfos[0].modeExt.autoFormatLineBreaks(text.substring(startPos, endPos));
290
+ }
291
+
292
+ return res;
293
+ }
294
+ };
@@ -0,0 +1,132 @@
1
+ (function () {
2
+ function forEach(arr, f) {
3
+ for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
4
+ }
5
+
6
+ function arrayContains(arr, item) {
7
+ if (!Array.prototype.indexOf) {
8
+ var i = arr.length;
9
+ while (i--) {
10
+ if (arr[i] === item) {
11
+ return true;
12
+ }
13
+ }
14
+ return false;
15
+ }
16
+ return arr.indexOf(item) != -1;
17
+ }
18
+
19
+ function scriptHint(editor, keywords, getToken) {
20
+ // Find the token at the cursor
21
+ var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token;
22
+ // If it's not a 'word-style' token, ignore the token.
23
+ if (!/^[\w$_]*$/.test(token.string)) {
24
+ token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state,
25
+ className: token.string == "." ? "property" : null};
26
+ }
27
+ // If it is a property, find out what it is a property of.
28
+ while (tprop.className == "property") {
29
+ tprop = getToken(editor, {line: cur.line, ch: tprop.start});
30
+ if (tprop.string != ".") return;
31
+ tprop = getToken(editor, {line: cur.line, ch: tprop.start});
32
+ if (tprop.string == ')') {
33
+ var level = 1;
34
+ do {
35
+ tprop = getToken(editor, {line: cur.line, ch: tprop.start});
36
+ switch (tprop.string) {
37
+ case ')': level++; break;
38
+ case '(': level--; break;
39
+ default: break;
40
+ }
41
+ } while (level > 0)
42
+ tprop = getToken(editor, {line: cur.line, ch: tprop.start});
43
+ if (tprop.className == 'variable')
44
+ tprop.className = 'function';
45
+ else return; // no clue
46
+ }
47
+ if (!context) var context = [];
48
+ context.push(tprop);
49
+ }
50
+ return {list: getCompletions(token, context, keywords),
51
+ from: {line: cur.line, ch: token.start},
52
+ to: {line: cur.line, ch: token.end}};
53
+ }
54
+
55
+ CodeMirror.javascriptHint = function(editor) {
56
+ return scriptHint(editor, javascriptKeywords,
57
+ function (e, cur) {return e.getTokenAt(cur);});
58
+ }
59
+
60
+ function getCoffeeScriptToken(editor, cur) {
61
+ // This getToken, it is for coffeescript, imitates the behavior of
62
+ // getTokenAt method in javascript.js, that is, returning "property"
63
+ // type and treat "." as indepenent token.
64
+ var token = editor.getTokenAt(cur);
65
+ if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') {
66
+ token.end = token.start;
67
+ token.string = '.';
68
+ token.className = "property";
69
+ }
70
+ else if (/^\.[\w$_]*$/.test(token.string)) {
71
+ token.className = "property";
72
+ token.start++;
73
+ token.string = token.string.replace(/\./, '');
74
+ }
75
+ return token;
76
+ }
77
+
78
+ CodeMirror.coffeescriptHint = function(editor) {
79
+ return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken);
80
+ }
81
+
82
+ var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " +
83
+ "toUpperCase toLowerCase split concat match replace search").split(" ");
84
+ var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " +
85
+ "lastIndexOf every some filter forEach map reduce reduceRight ").split(" ");
86
+ var funcProps = "prototype apply call bind".split(" ");
87
+ var javascriptKeywords = ("break case catch continue debugger default delete do else false finally for function " +
88
+ "if in instanceof new null return switch throw true try typeof var void while with").split(" ");
89
+ var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " +
90
+ "if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" ");
91
+
92
+ function getCompletions(token, context, keywords) {
93
+ var found = [], start = token.string;
94
+ function maybeAdd(str) {
95
+ if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str);
96
+ }
97
+ function gatherCompletions(obj) {
98
+ if (typeof obj == "string") forEach(stringProps, maybeAdd);
99
+ else if (obj instanceof Array) forEach(arrayProps, maybeAdd);
100
+ else if (obj instanceof Function) forEach(funcProps, maybeAdd);
101
+ for (var name in obj) maybeAdd(name);
102
+ }
103
+
104
+ if (context) {
105
+ // If this is a property, see if it belongs to some object we can
106
+ // find in the current environment.
107
+ var obj = context.pop(), base;
108
+ if (obj.className == "variable")
109
+ base = window[obj.string];
110
+ else if (obj.className == "string")
111
+ base = "";
112
+ else if (obj.className == "atom")
113
+ base = 1;
114
+ else if (obj.className == "function") {
115
+ if (window.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') &&
116
+ (typeof jQuery == 'function')) base = jQuery();
117
+ else if (window._ != null && (obj.string == '_') && (typeof _ == 'function')) base = _();
118
+ }
119
+ while (base != null && context.length)
120
+ base = base[context.pop().string];
121
+ if (base != null) gatherCompletions(base);
122
+ }
123
+ else {
124
+ // If not, just look in the window object and any local scope
125
+ // (reading into JS mode internals to get at the local variables)
126
+ for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
127
+ gatherCompletions(window);
128
+ forEach(keywords, maybeAdd);
129
+ }
130
+ return found;
131
+ }
132
+ })();