polyblock 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (264) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +34 -0
  5. data/app/assets/javascripts/beautify-css.js +264 -0
  6. data/app/assets/javascripts/beautify-html.js +838 -0
  7. data/app/assets/javascripts/beautify.js +1632 -0
  8. data/app/assets/javascripts/ckeditor/config.js +81 -0
  9. data/app/assets/javascripts/ckeditor/lang/en.js +5 -0
  10. data/app/assets/javascripts/ckeditor/plugins/sourcedialog/dialogs/sourcedialog.js +78 -0
  11. data/app/assets/javascripts/ckeditor/plugins/sourcedialog/icons/hidpi/sourcedialog-rtl.png +0 -0
  12. data/app/assets/javascripts/ckeditor/plugins/sourcedialog/icons/hidpi/sourcedialog.png +0 -0
  13. data/app/assets/javascripts/ckeditor/plugins/sourcedialog/icons/sourcedialog-rtl.png +0 -0
  14. data/app/assets/javascripts/ckeditor/plugins/sourcedialog/icons/sourcedialog.png +0 -0
  15. data/app/assets/javascripts/ckeditor/plugins/sourcedialog/plugin.js +27 -0
  16. data/app/assets/javascripts/ckeditor/plugins/sourcedialog/samples/sourcedialog.html +118 -0
  17. data/app/assets/javascripts/clientside-haml.js +2302 -0
  18. data/app/assets/javascripts/polyblock/application.js +24 -0
  19. data/app/assets/javascripts/polyblock/polyblock.js.coffee +143 -0
  20. data/app/assets/javascripts/transit.js +9 -0
  21. data/app/assets/javascripts/underscore.string.js +600 -0
  22. data/app/assets/stylesheets/polyblock/application.css +13 -0
  23. data/app/assets/stylesheets/polyblock/polyblocks.css +4 -0
  24. data/app/controllers/polyblock/application_controller.rb +4 -0
  25. data/app/controllers/polyblock/polyblocks_controller.rb +41 -0
  26. data/app/helpers/polyblock/application_helper.rb +29 -0
  27. data/app/helpers/polyblock/polyblocks_helper.rb +4 -0
  28. data/app/models/ckeditor/asset.rb +4 -0
  29. data/app/models/ckeditor/attachment_file.rb +12 -0
  30. data/app/models/ckeditor/picture.rb +13 -0
  31. data/app/models/polyblock/block.rb +7 -0
  32. data/app/views/layouts/polyblock/application.html.erb +14 -0
  33. data/app/views/polyblock/_editor_bar.html.erb +26 -0
  34. data/config/initializers/ckeditor.rb +21 -0
  35. data/config/routes.rb +7 -0
  36. data/db/migrate/20131201144424_create_ckeditor_assets.rb +26 -0
  37. data/db/migrate/20131201194124_create_polyblock_blocks.rb +12 -0
  38. data/lib/polyblock/engine.rb +12 -0
  39. data/lib/polyblock/version.rb +3 -0
  40. data/lib/polyblock.rb +4 -0
  41. data/lib/tasks/polyblock_tasks.rake +4 -0
  42. data/test/controllers/polyblock/polyblocks_controller_test.rb +9 -0
  43. data/test/dummy/README.rdoc +28 -0
  44. data/test/dummy/Rakefile +6 -0
  45. data/test/dummy/app/assets/javascripts/application.js +14 -0
  46. data/test/dummy/app/assets/javascripts/home.js +2 -0
  47. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  48. data/test/dummy/app/assets/stylesheets/home.css +4 -0
  49. data/test/dummy/app/controllers/application_controller.rb +5 -0
  50. data/test/dummy/app/controllers/home_controller.rb +7 -0
  51. data/test/dummy/app/helpers/application_helper.rb +2 -0
  52. data/test/dummy/app/helpers/home_helper.rb +2 -0
  53. data/test/dummy/app/views/home/index.html.erb +2 -0
  54. data/test/dummy/app/views/layouts/application.html.erb +15 -0
  55. data/test/dummy/bin/bundle +3 -0
  56. data/test/dummy/bin/rails +4 -0
  57. data/test/dummy/bin/rake +4 -0
  58. data/test/dummy/config/application.rb +23 -0
  59. data/test/dummy/config/boot.rb +5 -0
  60. data/test/dummy/config/database.yml +25 -0
  61. data/test/dummy/config/environment.rb +5 -0
  62. data/test/dummy/config/environments/development.rb +29 -0
  63. data/test/dummy/config/environments/production.rb +80 -0
  64. data/test/dummy/config/environments/test.rb +36 -0
  65. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  66. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  67. data/test/dummy/config/initializers/inflections.rb +16 -0
  68. data/test/dummy/config/initializers/mime_types.rb +5 -0
  69. data/test/dummy/config/initializers/secret_token.rb +12 -0
  70. data/test/dummy/config/initializers/session_store.rb +3 -0
  71. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  72. data/test/dummy/config/locales/en.yml +23 -0
  73. data/test/dummy/config/routes.rb +4 -0
  74. data/test/dummy/config.ru +4 -0
  75. data/test/dummy/db/development.sqlite3 +0 -0
  76. data/test/dummy/db/schema.rb +50 -0
  77. data/test/dummy/log/development.log +8760 -0
  78. data/test/dummy/public/404.html +58 -0
  79. data/test/dummy/public/422.html +58 -0
  80. data/test/dummy/public/500.html +57 -0
  81. data/test/dummy/public/favicon.ico +0 -0
  82. data/test/dummy/test/controllers/home_controller_test.rb +7 -0
  83. data/test/dummy/test/helpers/home_helper_test.rb +4 -0
  84. data/test/dummy/tmp/cache/assets/development/sprockets/01d10ffd358eeb0b021cc9183f39ae68 +0 -0
  85. data/test/dummy/tmp/cache/assets/development/sprockets/020cd4251b379e7f2ec729509bca3e41 +0 -0
  86. data/test/dummy/tmp/cache/assets/development/sprockets/0298cd9551a53c73ed306982bb488f21 +0 -0
  87. data/test/dummy/tmp/cache/assets/development/sprockets/033f9ad8b2cb2b403008de33db1e8b30 +0 -0
  88. data/test/dummy/tmp/cache/assets/development/sprockets/03759dc8759159b0cb33071eaa445eb0 +0 -0
  89. data/test/dummy/tmp/cache/assets/development/sprockets/054e6644a2f22ee98494c2f140e3a1e4 +0 -0
  90. data/test/dummy/tmp/cache/assets/development/sprockets/0c77775fe25328089569a112cb862dd4 +0 -0
  91. data/test/dummy/tmp/cache/assets/development/sprockets/0e895aeb087b1fb9e26b4e2398dcd1bd +0 -0
  92. data/test/dummy/tmp/cache/assets/development/sprockets/0f975357b9b6fee1af11ec65211c80bf +0 -0
  93. data/test/dummy/tmp/cache/assets/development/sprockets/12aa9b2820181ab345ef05ee8396ba2b +0 -0
  94. data/test/dummy/tmp/cache/assets/development/sprockets/131c3cd884f330627e5f5eab9b908861 +0 -0
  95. data/test/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  96. data/test/dummy/tmp/cache/assets/development/sprockets/1518dfe3536e63b395cefe2dc1e2b2be +0 -0
  97. data/test/dummy/tmp/cache/assets/development/sprockets/161b71d479fc0fa4a60bf309f585d6c7 +0 -0
  98. data/test/dummy/tmp/cache/assets/development/sprockets/1825f57b27296afe7285b26c07446d43 +0 -0
  99. data/test/dummy/tmp/cache/assets/development/sprockets/183add279724180686cad2786c68835f +0 -0
  100. data/test/dummy/tmp/cache/assets/development/sprockets/18b273e17be07c99fb48b37938c1f91e +0 -0
  101. data/test/dummy/tmp/cache/assets/development/sprockets/1926295578648cdc013840b112b4549a +0 -0
  102. data/test/dummy/tmp/cache/assets/development/sprockets/198ac8a69bf3249985d9888cbe072828 +0 -0
  103. data/test/dummy/tmp/cache/assets/development/sprockets/1a2a68c52d72fd360df1534fb62d80e5 +0 -0
  104. data/test/dummy/tmp/cache/assets/development/sprockets/1ba6042344298db56baa871bda8def48 +0 -0
  105. data/test/dummy/tmp/cache/assets/development/sprockets/1c3bf4812b7668021d8dbca7a8365f1a +0 -0
  106. data/test/dummy/tmp/cache/assets/development/sprockets/1c9faaf28d05409b88ad3113374d613c +0 -0
  107. data/test/dummy/tmp/cache/assets/development/sprockets/1dcf2f066cb7d1f61053762f665026f0 +0 -0
  108. data/test/dummy/tmp/cache/assets/development/sprockets/1eeb828973d38ac019484de910989d1a +0 -0
  109. data/test/dummy/tmp/cache/assets/development/sprockets/1f9c2e5e8f8f4274f29c2db2392b7443 +0 -0
  110. data/test/dummy/tmp/cache/assets/development/sprockets/1fb5c44086b9680362505e609ea1c3ba +0 -0
  111. data/test/dummy/tmp/cache/assets/development/sprockets/2032a9b15f933605f9e1348b938692ca +0 -0
  112. data/test/dummy/tmp/cache/assets/development/sprockets/222ae44e85a1c2658302687309a33440 +0 -0
  113. data/test/dummy/tmp/cache/assets/development/sprockets/227fcecc68de591c070de5ee5383f6aa +0 -0
  114. data/test/dummy/tmp/cache/assets/development/sprockets/2822de3b22c28bd5e718c9bf500457b2 +0 -0
  115. data/test/dummy/tmp/cache/assets/development/sprockets/284d60c07fb8c32b968c2bf0653a0c51 +0 -0
  116. data/test/dummy/tmp/cache/assets/development/sprockets/28a13e927d6f8c4f2df07ffa043a022d +0 -0
  117. data/test/dummy/tmp/cache/assets/development/sprockets/2904d9c64f7dcf593dd93db977330071 +0 -0
  118. data/test/dummy/tmp/cache/assets/development/sprockets/293760eecba440378055bf9964e26ef5 +0 -0
  119. data/test/dummy/tmp/cache/assets/development/sprockets/2e8261e97a81367a52002c140e9d4d4c +0 -0
  120. data/test/dummy/tmp/cache/assets/development/sprockets/2ef35d1c258b156746998a0e8bfb2512 +0 -0
  121. data/test/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  122. data/test/dummy/tmp/cache/assets/development/sprockets/2f98ed9544591a552d4a27e8d6fe52e7 +0 -0
  123. data/test/dummy/tmp/cache/assets/development/sprockets/30372050d03c549f832d0a229f054a09 +0 -0
  124. data/test/dummy/tmp/cache/assets/development/sprockets/3105a0833af87dbcd24616a1aa326624 +0 -0
  125. data/test/dummy/tmp/cache/assets/development/sprockets/31242785b0b30c2926a0a001ba15c37b +0 -0
  126. data/test/dummy/tmp/cache/assets/development/sprockets/346013835dd9a50f5c9e047b3c8c6036 +0 -0
  127. data/test/dummy/tmp/cache/assets/development/sprockets/355e62a84da5c2155a31fe4addaf3fab +0 -0
  128. data/test/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  129. data/test/dummy/tmp/cache/assets/development/sprockets/35dc797930ef7be4efb807233bb4089a +0 -0
  130. data/test/dummy/tmp/cache/assets/development/sprockets/38034a7a583e8b4c116cd9427c6a65a6 +0 -0
  131. data/test/dummy/tmp/cache/assets/development/sprockets/39bf3443ada31f4751a7d4f5992eabfa +0 -0
  132. data/test/dummy/tmp/cache/assets/development/sprockets/3aa98dd2b45d207a9fea94c6d3fc4c93 +0 -0
  133. data/test/dummy/tmp/cache/assets/development/sprockets/3b9ed85ea6b3c17f3357272f88edec81 +0 -0
  134. data/test/dummy/tmp/cache/assets/development/sprockets/40fc2f3d2a468a00e463f1d313cb1683 +0 -0
  135. data/test/dummy/tmp/cache/assets/development/sprockets/41f903e59539965c348dbac12f651853 +0 -0
  136. data/test/dummy/tmp/cache/assets/development/sprockets/42079241bc34a6f7a1ea3d085e9e81a1 +0 -0
  137. data/test/dummy/tmp/cache/assets/development/sprockets/469a23499ce29fb0b21239db80139b48 +0 -0
  138. data/test/dummy/tmp/cache/assets/development/sprockets/46e74a11aa3f8c919696fae111869929 +0 -0
  139. data/test/dummy/tmp/cache/assets/development/sprockets/483f8189cba7c0aee7a46a04febdc197 +0 -0
  140. data/test/dummy/tmp/cache/assets/development/sprockets/494fc186abfedc09409786fc8b2ba340 +0 -0
  141. data/test/dummy/tmp/cache/assets/development/sprockets/4b886bd84e18901aa1bfbaafded1ea74 +0 -0
  142. data/test/dummy/tmp/cache/assets/development/sprockets/4bac9705448d2568d956a6b580565d0e +0 -0
  143. data/test/dummy/tmp/cache/assets/development/sprockets/4bf84fc546d1736be7f5e49f37d9e373 +0 -0
  144. data/test/dummy/tmp/cache/assets/development/sprockets/4ce319d4627e6065afffeaec20f27c2c +0 -0
  145. data/test/dummy/tmp/cache/assets/development/sprockets/507329c12ad1da334c124a54ac840247 +0 -0
  146. data/test/dummy/tmp/cache/assets/development/sprockets/5080e3e500303e0b993d3147ca0c0747 +0 -0
  147. data/test/dummy/tmp/cache/assets/development/sprockets/50e76ce60f5fc61ca3e70b70d8766d75 +0 -0
  148. data/test/dummy/tmp/cache/assets/development/sprockets/52a652f96849ad97a147a7d9fe45d374 +0 -0
  149. data/test/dummy/tmp/cache/assets/development/sprockets/52d05185fe8ef8d067c2ba8f196d9afb +0 -0
  150. data/test/dummy/tmp/cache/assets/development/sprockets/5418c4cf54e69db24470c9dccd42b524 +0 -0
  151. data/test/dummy/tmp/cache/assets/development/sprockets/54e6936a11d8f5cdf5fa2f48475d2207 +0 -0
  152. data/test/dummy/tmp/cache/assets/development/sprockets/54f23a17d564a036a8942b34853d62af +0 -0
  153. data/test/dummy/tmp/cache/assets/development/sprockets/5688d74639deb1904bb099823a2b9078 +0 -0
  154. data/test/dummy/tmp/cache/assets/development/sprockets/5cf14a014ac60aeddff4e9dad4971824 +0 -0
  155. data/test/dummy/tmp/cache/assets/development/sprockets/5d5d4bb119e1e543a75ebf4c1a795a64 +0 -0
  156. data/test/dummy/tmp/cache/assets/development/sprockets/5e7c59533e1b5ef0c92e0d46f0848a2c +0 -0
  157. data/test/dummy/tmp/cache/assets/development/sprockets/60f1796bd046463c321db1046bc1c26a +0 -0
  158. data/test/dummy/tmp/cache/assets/development/sprockets/61dbe29abaf1d38eeeaed7fa9dce6ea3 +0 -0
  159. data/test/dummy/tmp/cache/assets/development/sprockets/649a30c83a617bd43d47acf786140f34 +0 -0
  160. data/test/dummy/tmp/cache/assets/development/sprockets/64d65db775748acbf392e1eacf59032d +0 -0
  161. data/test/dummy/tmp/cache/assets/development/sprockets/65a5689d2de3f83bcc1531b0bd7918ce +0 -0
  162. data/test/dummy/tmp/cache/assets/development/sprockets/66a715b5252355fae8785a848f07890c +0 -0
  163. data/test/dummy/tmp/cache/assets/development/sprockets/67068ab8480c236e15cc6d7507e52eec +0 -0
  164. data/test/dummy/tmp/cache/assets/development/sprockets/67af580bfcbac793745a2bdc2344880a +0 -0
  165. data/test/dummy/tmp/cache/assets/development/sprockets/69f01b85f9dbad9d568e46c5a81d3cef +0 -0
  166. data/test/dummy/tmp/cache/assets/development/sprockets/6aa08eaf51a818834385dea1b64100f0 +0 -0
  167. data/test/dummy/tmp/cache/assets/development/sprockets/6beb01ae124bf2ebfb1a82617e2b6098 +0 -0
  168. data/test/dummy/tmp/cache/assets/development/sprockets/6dabc2eb7494578b1bd175f001055ec8 +0 -0
  169. data/test/dummy/tmp/cache/assets/development/sprockets/6f75f19c6e3573a6696df41ac5d31cca +0 -0
  170. data/test/dummy/tmp/cache/assets/development/sprockets/71069975441a8fde10d210b51585a5a3 +0 -0
  171. data/test/dummy/tmp/cache/assets/development/sprockets/7276854d4022c2d37882818af409c467 +0 -0
  172. data/test/dummy/tmp/cache/assets/development/sprockets/73c99b0656c98ebf9f4f9a69565fa0b7 +0 -0
  173. data/test/dummy/tmp/cache/assets/development/sprockets/749930e2a2cdc8a72fb497359f83181e +0 -0
  174. data/test/dummy/tmp/cache/assets/development/sprockets/75b1e158df9657689b214b7ccd2e4cf7 +0 -0
  175. data/test/dummy/tmp/cache/assets/development/sprockets/75d065741331d0ad6ae16498b7108723 +0 -0
  176. data/test/dummy/tmp/cache/assets/development/sprockets/76ad604881ad72473bf07bd1d19c8494 +0 -0
  177. data/test/dummy/tmp/cache/assets/development/sprockets/773d7acc6545de12f1a86b77cef2e40e +0 -0
  178. data/test/dummy/tmp/cache/assets/development/sprockets/786af69fbff630e129664087cb879e57 +0 -0
  179. data/test/dummy/tmp/cache/assets/development/sprockets/78cf370d910b9a1721891b28a7c7fec0 +0 -0
  180. data/test/dummy/tmp/cache/assets/development/sprockets/7c72a7ab5a27c2ea4fe3a2d8ba0e1890 +0 -0
  181. data/test/dummy/tmp/cache/assets/development/sprockets/7e8e0833a197f1f272edbd4c74d55c8c +0 -0
  182. data/test/dummy/tmp/cache/assets/development/sprockets/8098a2ad06e177efc27a63d1ea20c17a +0 -0
  183. data/test/dummy/tmp/cache/assets/development/sprockets/80a9daa2db75d17e5e24d7442ccb41bc +0 -0
  184. data/test/dummy/tmp/cache/assets/development/sprockets/818c2000c1301a3f2f526dda13afe15c +0 -0
  185. data/test/dummy/tmp/cache/assets/development/sprockets/82bfcea3fa5e6c4fa34a2ebbb5d6f075 +0 -0
  186. data/test/dummy/tmp/cache/assets/development/sprockets/8340810a445a06118e27eaaad32e862d +0 -0
  187. data/test/dummy/tmp/cache/assets/development/sprockets/8631041495ef144973adaf1fba193a22 +0 -0
  188. data/test/dummy/tmp/cache/assets/development/sprockets/87f6abdf4627b5b8072bafbca388aa98 +0 -0
  189. data/test/dummy/tmp/cache/assets/development/sprockets/885519ac7f861d48be489733a6941bd0 +0 -0
  190. data/test/dummy/tmp/cache/assets/development/sprockets/8cea52541f58190ce0a4c5512c7355cb +0 -0
  191. data/test/dummy/tmp/cache/assets/development/sprockets/8cfd23d116cf0a7c9e1d68c2b769add7 +0 -0
  192. data/test/dummy/tmp/cache/assets/development/sprockets/8e4aca87eaa40ed7cff1b11eba46e8d5 +0 -0
  193. data/test/dummy/tmp/cache/assets/development/sprockets/8f0e003323d409b4bea8e37f8e210b37 +0 -0
  194. data/test/dummy/tmp/cache/assets/development/sprockets/8f4c36636517f6b49c072538a63a6d59 +0 -0
  195. data/test/dummy/tmp/cache/assets/development/sprockets/908b5ae11b8473493d1e9467124d1ee4 +0 -0
  196. data/test/dummy/tmp/cache/assets/development/sprockets/98c83dce67cf84818203c6f995f4ba36 +0 -0
  197. data/test/dummy/tmp/cache/assets/development/sprockets/9b261f00d3607a34f3df29dcc0beece1 +0 -0
  198. data/test/dummy/tmp/cache/assets/development/sprockets/a21978d1a823d6011c10799dd1fbb65c +0 -0
  199. data/test/dummy/tmp/cache/assets/development/sprockets/a366043ecf7a23398dd9230018ae5ee3 +0 -0
  200. data/test/dummy/tmp/cache/assets/development/sprockets/a39be73154e19325e4f93210251924f4 +0 -0
  201. data/test/dummy/tmp/cache/assets/development/sprockets/a82a85e8fa40ed62eabb9818404726cb +0 -0
  202. data/test/dummy/tmp/cache/assets/development/sprockets/a9f028f7a492b5907ed80268be8f50f4 +0 -0
  203. data/test/dummy/tmp/cache/assets/development/sprockets/aa3eca8179472bb088a8474f35f6c5ce +0 -0
  204. data/test/dummy/tmp/cache/assets/development/sprockets/aafb9cc161f1b35b684b6367c1d63373 +0 -0
  205. data/test/dummy/tmp/cache/assets/development/sprockets/abaf826b99cbedf45dd5304d096bdfaa +0 -0
  206. data/test/dummy/tmp/cache/assets/development/sprockets/ac34c01b1f09105c80ff6687bdc1493e +0 -0
  207. data/test/dummy/tmp/cache/assets/development/sprockets/ac9510df8de841f1abc8c72c6fd0e295 +0 -0
  208. data/test/dummy/tmp/cache/assets/development/sprockets/ad37bb314723ee3d230eb29326b47a46 +0 -0
  209. data/test/dummy/tmp/cache/assets/development/sprockets/ae401c4518969dbd6ecab0274940df4d +0 -0
  210. data/test/dummy/tmp/cache/assets/development/sprockets/b0a603111ad6abfe5bf08255eaf8573a +0 -0
  211. data/test/dummy/tmp/cache/assets/development/sprockets/b7e3984da49e9c18ea6f4344b6ddedf1 +0 -0
  212. data/test/dummy/tmp/cache/assets/development/sprockets/b878faf942403e313a5b103e5d80488e +0 -0
  213. data/test/dummy/tmp/cache/assets/development/sprockets/b8d45418a0dec849026e7832c6922595 +0 -0
  214. data/test/dummy/tmp/cache/assets/development/sprockets/ba41d761ded85fc461ab0cabbeaef53e +0 -0
  215. data/test/dummy/tmp/cache/assets/development/sprockets/ba83646bf2099832ad8ac75379b763df +0 -0
  216. data/test/dummy/tmp/cache/assets/development/sprockets/bafcd897244753eeb0b64f544a77a19c +0 -0
  217. data/test/dummy/tmp/cache/assets/development/sprockets/bd8633c99ac4b7825a5cca6cf494d940 +0 -0
  218. data/test/dummy/tmp/cache/assets/development/sprockets/bdea69b9c406739ca4e7a36da20e7b53 +0 -0
  219. data/test/dummy/tmp/cache/assets/development/sprockets/be9eeaafba005e1d57455b8fef64f7c6 +0 -0
  220. data/test/dummy/tmp/cache/assets/development/sprockets/bf5b075f964da07102907d7ce6811ed5 +0 -0
  221. data/test/dummy/tmp/cache/assets/development/sprockets/c22f6c78a77ef39e7e33f9b216b805f2 +0 -0
  222. data/test/dummy/tmp/cache/assets/development/sprockets/c4f8e04fa248664e0d9e375a092b5efe +0 -0
  223. data/test/dummy/tmp/cache/assets/development/sprockets/c58e57990b87dfd6f4bc915907ff45ea +0 -0
  224. data/test/dummy/tmp/cache/assets/development/sprockets/c805b4d29a0e91011768405e87f70817 +0 -0
  225. data/test/dummy/tmp/cache/assets/development/sprockets/ca03d7c3a02b5b9c3223a83873f07581 +0 -0
  226. data/test/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  227. data/test/dummy/tmp/cache/assets/development/sprockets/d2a5ab24b7b9dd1e4686b22bde66a4f4 +0 -0
  228. data/test/dummy/tmp/cache/assets/development/sprockets/d4175e149c21384fc6b3fb79c9d45c66 +0 -0
  229. data/test/dummy/tmp/cache/assets/development/sprockets/d41b25d3ec25b4c3b2fe8eb9cf82d595 +0 -0
  230. data/test/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  231. data/test/dummy/tmp/cache/assets/development/sprockets/da1acabb815f02640e2aedd90a85df93 +0 -0
  232. data/test/dummy/tmp/cache/assets/development/sprockets/de51a9a54870e5d9f22775e2e3bedf38 +0 -0
  233. data/test/dummy/tmp/cache/assets/development/sprockets/df139027ce9ac098fd00f4ab7611bbac +0 -0
  234. data/test/dummy/tmp/cache/assets/development/sprockets/e03b3a3f08af68514f0a4224b38dc19a +0 -0
  235. data/test/dummy/tmp/cache/assets/development/sprockets/e08a13a79de686909616cc3861bd2ff6 +0 -0
  236. data/test/dummy/tmp/cache/assets/development/sprockets/e0ca554821c153076d2dd8e72eb33cdb +0 -0
  237. data/test/dummy/tmp/cache/assets/development/sprockets/e4cb660bbc6515fd08140519e66368fd +0 -0
  238. data/test/dummy/tmp/cache/assets/development/sprockets/e6968aa068b3fe46c56ea816e7d3c6cf +0 -0
  239. data/test/dummy/tmp/cache/assets/development/sprockets/e736ecc7279b661ef9d3ca9882196708 +0 -0
  240. data/test/dummy/tmp/cache/assets/development/sprockets/eae7257fcd4b160c2d782e66ba0c5438 +0 -0
  241. data/test/dummy/tmp/cache/assets/development/sprockets/edbef6e0d0a4742346cf479f2c522eb0 +0 -0
  242. data/test/dummy/tmp/cache/assets/development/sprockets/ef21be926e9fa6ad4e7dbdd19e0fc91a +0 -0
  243. data/test/dummy/tmp/cache/assets/development/sprockets/ef79b2be98e4232ac86c5bd6dc8cf77f +0 -0
  244. data/test/dummy/tmp/cache/assets/development/sprockets/f1087ef68b351492e06aa6cfd82d0438 +0 -0
  245. data/test/dummy/tmp/cache/assets/development/sprockets/f22c23c07479937e88c5642915d72652 +0 -0
  246. data/test/dummy/tmp/cache/assets/development/sprockets/f3c90764c8cfc0c04c179baeeb54f7d9 +0 -0
  247. data/test/dummy/tmp/cache/assets/development/sprockets/f4e04263f04511317e283b7afd5ac9fc +0 -0
  248. data/test/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  249. data/test/dummy/tmp/cache/assets/development/sprockets/f999e530403d0f45b1fb283186785dc5 +0 -0
  250. data/test/dummy/tmp/cache/assets/development/sprockets/f99bfcf75bfe60e1e9c19f03fd1c476c +0 -0
  251. data/test/dummy/tmp/cache/assets/development/sprockets/f9a99df6b5884accbebff708f1fa861d +0 -0
  252. data/test/dummy/tmp/cache/assets/development/sprockets/fa2a1a439527d340ac07907157929b8d +0 -0
  253. data/test/dummy/tmp/cache/assets/development/sprockets/fa735568b6074e46bd157a4391e6627f +0 -0
  254. data/test/dummy/tmp/cache/assets/development/sprockets/fb2945554eacf0950f8c100ed8f07cb8 +0 -0
  255. data/test/dummy/tmp/cache/assets/development/sprockets/fc543306aa02516980ce1817fc19d3d5 +0 -0
  256. data/test/dummy/tmp/cache/assets/development/sprockets/fd51120226fc9ccf01d5893be1032b5b +0 -0
  257. data/test/dummy/tmp/cache/assets/development/sprockets/fdee4c39a777bb7c2f1c9f29cad9601a +0 -0
  258. data/test/fixtures/polyblock/blocks.yml +13 -0
  259. data/test/helpers/polyblock/polyblocks_helper_test.rb +6 -0
  260. data/test/integration/navigation_test.rb +10 -0
  261. data/test/models/polyblock/block_test.rb +9 -0
  262. data/test/polyblock_test.rb +7 -0
  263. data/test/test_helper.rb +15 -0
  264. metadata +653 -0
@@ -0,0 +1,2302 @@
1
+ // Generated by CoffeeScript 1.6.2
2
+ /*
3
+ clientside HAML compiler for Javascript and Coffeescript (Version 5)
4
+
5
+ Copyright 2011-12, Ronald Holshausen (https://github.com/uglyog)
6
+ Released under the MIT License (http://www.opensource.org/licenses/MIT)
7
+ */
8
+
9
+
10
+ (function() {
11
+ var Buffer, CodeGenerator, CoffeeCodeGenerator, HamlRuntime, JsCodeGenerator, ProductionJsCodeGenerator, Tokeniser, filters, haml, root, _ref,
12
+ __hasProp = {}.hasOwnProperty,
13
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
14
+
15
+ root = this;
16
+
17
+ /*
18
+ Haml runtime functions. These are used both by the compiler and the generated template functions
19
+ */
20
+
21
+
22
+ HamlRuntime = {
23
+ /*
24
+ Taken from underscore.string.js escapeHTML, and replace the apos entity with character 39 so that it renders
25
+ correctly in IE7
26
+ */
27
+
28
+ escapeHTML: function(str) {
29
+ return String(str || '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, "&#39;");
30
+ },
31
+ /*
32
+ Provides the implementation to preserve the whitespace as per the HAML reference
33
+ */
34
+
35
+ perserveWhitespace: function(str) {
36
+ var i, out, re, result;
37
+
38
+ re = /<[a-zA-Z]+>[^<]*<\/[a-zA-Z]+>/g;
39
+ out = '';
40
+ i = 0;
41
+ result = re.exec(str);
42
+ if (result) {
43
+ while (result) {
44
+ out += str.substring(i, result.index);
45
+ out += result[0].replace(/\n/g, '&#x000A;');
46
+ i = result.index + result[0].length;
47
+ result = re.exec(str);
48
+ }
49
+ out += str.substring(i);
50
+ } else {
51
+ out = str;
52
+ }
53
+ return out;
54
+ },
55
+ /*
56
+ Generates a error message including the current line in the source where the error occurred
57
+ */
58
+
59
+ templateError: function(lineNumber, characterNumber, currentLine, error) {
60
+ var i, message;
61
+
62
+ message = error + " at line " + lineNumber + " and character " + characterNumber + ":\n" + currentLine + '\n';
63
+ i = 0;
64
+ while (i < characterNumber - 1) {
65
+ message += '-';
66
+ i++;
67
+ }
68
+ message += '^';
69
+ return message;
70
+ },
71
+ /*
72
+ Generates the attributes for the element by combining all the various sources together
73
+ */
74
+
75
+ generateElementAttributes: function(context, id, classes, objRefFn, attrList, attrFunction, lineNumber, characterNumber, currentLine, handleError) {
76
+ var attr, attributes, className, e, ex, hash, html, object, objectId, value;
77
+
78
+ if (handleError == null) {
79
+ handleError = this._raiseError;
80
+ }
81
+ attributes = {};
82
+ attributes = this.combineAttributes(attributes, 'id', id);
83
+ if (classes.length > 0 && classes[0].length > 0) {
84
+ attributes = this.combineAttributes(attributes, 'class', classes);
85
+ }
86
+ if (attrList != null) {
87
+ for (attr in attrList) {
88
+ if (!__hasProp.call(attrList, attr)) continue;
89
+ value = attrList[attr];
90
+ attributes = this.combineAttributes(attributes, attr, value);
91
+ }
92
+ }
93
+ if (objRefFn != null) {
94
+ try {
95
+ object = objRefFn.call(context, context);
96
+ if (object != null) {
97
+ objectId = null;
98
+ if (object.id != null) {
99
+ objectId = object.id;
100
+ } else if (object.get) {
101
+ objectId = object.get('id');
102
+ }
103
+ attributes = this.combineAttributes(attributes, 'id', objectId);
104
+ className = null;
105
+ if (object['class']) {
106
+ className = object['class'];
107
+ } else if (object.get) {
108
+ className = object.get('class');
109
+ }
110
+ attributes = this.combineAttributes(attributes, 'class', className);
111
+ }
112
+ } catch (_error) {
113
+ e = _error;
114
+ handleError(haml.HamlRuntime.templateError(lineNumber, characterNumber, currentLine, "Error evaluating object reference - " + e));
115
+ }
116
+ }
117
+ if (attrFunction != null) {
118
+ try {
119
+ hash = attrFunction.call(context, context);
120
+ if (hash != null) {
121
+ hash = this._flattenHash(null, hash);
122
+ for (attr in hash) {
123
+ if (!__hasProp.call(hash, attr)) continue;
124
+ value = hash[attr];
125
+ attributes = this.combineAttributes(attributes, attr, value);
126
+ }
127
+ }
128
+ } catch (_error) {
129
+ ex = _error;
130
+ handleError(haml.HamlRuntime.templateError(lineNumber, characterNumber, currentLine, "Error evaluating attribute hash - " + ex));
131
+ }
132
+ }
133
+ html = '';
134
+ if (attributes) {
135
+ for (attr in attributes) {
136
+ if (!__hasProp.call(attributes, attr)) continue;
137
+ if (haml.hasValue(attributes[attr])) {
138
+ if ((attr === 'id' || attr === 'for') && attributes[attr] instanceof Array) {
139
+ html += ' ' + attr + '="' + _(attributes[attr]).flatten().join('-') + '"';
140
+ } else if (attr === 'class' && attributes[attr] instanceof Array) {
141
+ html += ' ' + attr + '="' + _(attributes[attr]).flatten().join(' ') + '"';
142
+ } else {
143
+ html += ' ' + attr + '="' + haml.attrValue(attr, attributes[attr]) + '"';
144
+ }
145
+ }
146
+ }
147
+ }
148
+ return html;
149
+ },
150
+ /*
151
+ Returns a white space string with a length of indent * 2
152
+ */
153
+
154
+ indentText: function(indent) {
155
+ var i, text;
156
+
157
+ text = '';
158
+ i = 0;
159
+ while (i < indent) {
160
+ text += ' ';
161
+ i++;
162
+ }
163
+ return text;
164
+ },
165
+ /*
166
+ Combines the attributes in the attributres hash with the given attribute and value
167
+ ID, FOR and CLASS attributes will expand to arrays when multiple values are provided
168
+ */
169
+
170
+ combineAttributes: function(attributes, attrName, attrValue) {
171
+ var classes;
172
+
173
+ if (haml.hasValue(attrValue)) {
174
+ if (attrName === 'id' && attrValue.toString().length > 0) {
175
+ if (attributes && attributes.id instanceof Array) {
176
+ attributes.id.unshift(attrValue);
177
+ } else if (attributes && attributes.id) {
178
+ attributes.id = [attributes.id, attrValue];
179
+ } else if (attributes) {
180
+ attributes.id = attrValue;
181
+ } else {
182
+ attributes = {
183
+ id: attrValue
184
+ };
185
+ }
186
+ } else if (attrName === 'for' && attrValue.toString().length > 0) {
187
+ if (attributes && attributes['for'] instanceof Array) {
188
+ attributes['for'].unshift(attrValue);
189
+ } else if (attributes && attributes['for']) {
190
+ attributes['for'] = [attributes['for'], attrValue];
191
+ } else if (attributes) {
192
+ attributes['for'] = attrValue;
193
+ } else {
194
+ attributes = {
195
+ 'for': attrValue
196
+ };
197
+ }
198
+ } else if (attrName === 'class') {
199
+ classes = [];
200
+ if (attrValue instanceof Array) {
201
+ classes = classes.concat(attrValue);
202
+ } else {
203
+ classes.push(attrValue);
204
+ }
205
+ if (attributes && attributes['class']) {
206
+ attributes['class'] = attributes['class'].concat(classes);
207
+ } else if (attributes) {
208
+ attributes['class'] = classes;
209
+ } else {
210
+ attributes = {
211
+ 'class': classes
212
+ };
213
+ }
214
+ } else if (attrName !== 'id') {
215
+ attributes || (attributes = {});
216
+ attributes[attrName] = attrValue;
217
+ }
218
+ }
219
+ return attributes;
220
+ },
221
+ /*
222
+ Flattens a deeply nested hash into a single hash by combining the keys with a minus
223
+ */
224
+
225
+ _flattenHash: function(rootKey, object) {
226
+ var attr, flattenedValue, key, keys, newKey, newValue, result, value;
227
+
228
+ result = {};
229
+ if (this._isHash(object)) {
230
+ for (attr in object) {
231
+ if (!__hasProp.call(object, attr)) continue;
232
+ value = object[attr];
233
+ keys = [];
234
+ if (rootKey != null) {
235
+ keys.push(rootKey);
236
+ }
237
+ keys.push(attr);
238
+ key = keys.join('-');
239
+ flattenedValue = this._flattenHash(key, value);
240
+ if (this._isHash(flattenedValue)) {
241
+ for (newKey in flattenedValue) {
242
+ if (!__hasProp.call(flattenedValue, newKey)) continue;
243
+ newValue = flattenedValue[newKey];
244
+ result[newKey] = newValue;
245
+ }
246
+ } else {
247
+ result[key] = flattenedValue;
248
+ }
249
+ }
250
+ } else if (rootKey != null) {
251
+ result[rootKey] = object;
252
+ } else {
253
+ result = object;
254
+ }
255
+ return result;
256
+ },
257
+ _isHash: function(object) {
258
+ return (object != null) && typeof object === 'object' && !(object instanceof Array || object instanceof Date);
259
+ },
260
+ _logError: function(message) {
261
+ return typeof console !== "undefined" && console !== null ? console.log(message) : void 0;
262
+ },
263
+ _raiseError: function(message) {
264
+ throw new Error(message);
265
+ },
266
+ /*
267
+ trims the first number of characters from a string
268
+ */
269
+
270
+ trim: function(str, chars) {
271
+ return str.substring(chars);
272
+ }
273
+ };
274
+
275
+ /*
276
+ HAML Tokiniser: This class is responsible for parsing the haml source into tokens
277
+ */
278
+
279
+
280
+ Tokeniser = (function() {
281
+ Tokeniser.prototype.currentLineMatcher = /[^\n]*/g;
282
+
283
+ Tokeniser.prototype.tokenMatchers = {
284
+ whitespace: /[ \t]+/g,
285
+ element: /%[a-zA-Z][a-zA-Z0-9]*/g,
286
+ idSelector: /#[a-zA-Z_\-][a-zA-Z0-9_\-]*/g,
287
+ classSelector: /\.[a-zA-Z0-9_\-]+/g,
288
+ identifier: /[a-zA-Z][a-zA-Z0-9\-]*/g,
289
+ quotedString: /[\'][^\'\n]*[\']/g,
290
+ quotedString2: /[\"][^\"\n]*[\"]/g,
291
+ comment: /\-#/g,
292
+ escapeHtml: /\&=/g,
293
+ unescapeHtml: /\!=/g,
294
+ objectReference: /\[[a-zA-Z_@][a-zA-Z0-9_]*\]/g,
295
+ doctype: /!!!/g,
296
+ continueLine: /\|\s*\n/g,
297
+ filter: /:\w+/g
298
+ };
299
+
300
+ function Tokeniser(options) {
301
+ var errorFn, successFn, template,
302
+ _this = this;
303
+
304
+ this.buffer = null;
305
+ this.bufferIndex = null;
306
+ this.prevToken = null;
307
+ this.token = null;
308
+ if (options.templateId != null) {
309
+ template = document.getElementById(options.templateId);
310
+ if (template) {
311
+ this.buffer = template.text;
312
+ this.bufferIndex = 0;
313
+ } else {
314
+ throw "Did not find a template with ID '" + options.templateId + "'";
315
+ }
316
+ } else if (options.template != null) {
317
+ this.buffer = options.template;
318
+ this.bufferIndex = 0;
319
+ } else if (options.templateUrl != null) {
320
+ errorFn = function(jqXHR, textStatus, errorThrown) {
321
+ throw "Failed to fetch haml template at URL " + options.templateUrl + ": " + textStatus + " " + errorThrown;
322
+ };
323
+ successFn = function(data) {
324
+ _this.buffer = data;
325
+ return _this.bufferIndex = 0;
326
+ };
327
+ jQuery.ajax({
328
+ url: options.templateUrl,
329
+ success: successFn,
330
+ error: errorFn,
331
+ dataType: 'text',
332
+ async: false,
333
+ beforeSend: function(xhr) {
334
+ return xhr.withCredentials = true;
335
+ }
336
+ });
337
+ }
338
+ }
339
+
340
+ /*
341
+ Try to match a token with the given regexp
342
+ */
343
+
344
+
345
+ Tokeniser.prototype.matchToken = function(matcher) {
346
+ var result;
347
+
348
+ matcher.lastIndex = this.bufferIndex;
349
+ result = matcher.exec(this.buffer);
350
+ if ((result != null ? result.index : void 0) === this.bufferIndex) {
351
+ return result[0];
352
+ }
353
+ };
354
+
355
+ /*
356
+ Match a multi-character token
357
+ */
358
+
359
+
360
+ Tokeniser.prototype.matchMultiCharToken = function(matcher, token, tokenStr) {
361
+ var matched, _ref;
362
+
363
+ if (!this.token) {
364
+ matched = this.matchToken(matcher);
365
+ if (matched) {
366
+ this.token = token;
367
+ this.token.tokenString = (_ref = typeof tokenStr === "function" ? tokenStr(matched) : void 0) != null ? _ref : matched;
368
+ this.token.matched = matched;
369
+ return this.advanceCharsInBuffer(matched.length);
370
+ }
371
+ }
372
+ };
373
+
374
+ /*
375
+ Match a single character token
376
+ */
377
+
378
+
379
+ Tokeniser.prototype.matchSingleCharToken = function(ch, token) {
380
+ if (!this.token && this.buffer.charAt(this.bufferIndex) === ch) {
381
+ this.token = token;
382
+ this.token.tokenString = ch;
383
+ this.token.matched = ch;
384
+ return this.advanceCharsInBuffer(1);
385
+ }
386
+ };
387
+
388
+ /*
389
+ Match and return the next token in the input buffer
390
+ */
391
+
392
+
393
+ Tokeniser.prototype.getNextToken = function() {
394
+ var ch, ch1, str;
395
+
396
+ if (isNaN(this.bufferIndex)) {
397
+ throw haml.HamlRuntime.templateError(this.lineNumber, this.characterNumber, this.currentLine, "An internal parser error has occurred in the HAML parser");
398
+ }
399
+ this.prevToken = this.token;
400
+ this.token = null;
401
+ if (this.buffer === null || this.buffer.length === this.bufferIndex) {
402
+ this.token = {
403
+ eof: true,
404
+ token: 'EOF'
405
+ };
406
+ } else {
407
+ this.initLine();
408
+ if (!this.token) {
409
+ ch = this.buffer.charCodeAt(this.bufferIndex);
410
+ ch1 = this.buffer.charCodeAt(this.bufferIndex + 1);
411
+ if (ch === 10 || (ch === 13 && ch1 === 10)) {
412
+ this.token = {
413
+ eol: true,
414
+ token: 'EOL'
415
+ };
416
+ if (ch === 13 && ch1 === 10) {
417
+ this.advanceCharsInBuffer(2);
418
+ this.token.matched = String.fromCharCode(ch) + String.fromCharCode(ch1);
419
+ } else {
420
+ this.advanceCharsInBuffer(1);
421
+ this.token.matched = String.fromCharCode(ch);
422
+ }
423
+ this.characterNumber = 0;
424
+ this.currentLine = this.getCurrentLine();
425
+ }
426
+ }
427
+ this.matchMultiCharToken(this.tokenMatchers.whitespace, {
428
+ ws: true,
429
+ token: 'WS'
430
+ });
431
+ this.matchMultiCharToken(this.tokenMatchers.continueLine, {
432
+ continueLine: true,
433
+ token: 'CONTINUELINE'
434
+ });
435
+ this.matchMultiCharToken(this.tokenMatchers.element, {
436
+ element: true,
437
+ token: 'ELEMENT'
438
+ }, function(matched) {
439
+ return matched.substring(1);
440
+ });
441
+ this.matchMultiCharToken(this.tokenMatchers.idSelector, {
442
+ idSelector: true,
443
+ token: 'ID'
444
+ }, function(matched) {
445
+ return matched.substring(1);
446
+ });
447
+ this.matchMultiCharToken(this.tokenMatchers.classSelector, {
448
+ classSelector: true,
449
+ token: 'CLASS'
450
+ }, function(matched) {
451
+ return matched.substring(1);
452
+ });
453
+ this.matchMultiCharToken(this.tokenMatchers.identifier, {
454
+ identifier: true,
455
+ token: 'IDENTIFIER'
456
+ });
457
+ this.matchMultiCharToken(this.tokenMatchers.doctype, {
458
+ doctype: true,
459
+ token: 'DOCTYPE'
460
+ });
461
+ this.matchMultiCharToken(this.tokenMatchers.filter, {
462
+ filter: true,
463
+ token: 'FILTER'
464
+ }, function(matched) {
465
+ return matched.substring(1);
466
+ });
467
+ if (!this.token) {
468
+ str = this.matchToken(this.tokenMatchers.quotedString);
469
+ if (!str) {
470
+ str = this.matchToken(this.tokenMatchers.quotedString2);
471
+ }
472
+ if (str) {
473
+ this.token = {
474
+ string: true,
475
+ token: 'STRING',
476
+ tokenString: str.substring(1, str.length - 1),
477
+ matched: str
478
+ };
479
+ this.advanceCharsInBuffer(str.length);
480
+ }
481
+ }
482
+ this.matchMultiCharToken(this.tokenMatchers.comment, {
483
+ comment: true,
484
+ token: 'COMMENT'
485
+ });
486
+ this.matchMultiCharToken(this.tokenMatchers.escapeHtml, {
487
+ escapeHtml: true,
488
+ token: 'ESCAPEHTML'
489
+ });
490
+ this.matchMultiCharToken(this.tokenMatchers.unescapeHtml, {
491
+ unescapeHtml: true,
492
+ token: 'UNESCAPEHTML'
493
+ });
494
+ this.matchMultiCharToken(this.tokenMatchers.objectReference, {
495
+ objectReference: true,
496
+ token: 'OBJECTREFERENCE'
497
+ }, function(matched) {
498
+ return matched.substring(1, matched.length - 1);
499
+ });
500
+ if (!this.token && this.buffer && this.buffer.charAt(this.bufferIndex) === '{') {
501
+ this.matchJavascriptHash();
502
+ }
503
+ this.matchSingleCharToken('(', {
504
+ openBracket: true,
505
+ token: 'OPENBRACKET'
506
+ });
507
+ this.matchSingleCharToken(')', {
508
+ closeBracket: true,
509
+ token: 'CLOSEBRACKET'
510
+ });
511
+ this.matchSingleCharToken('=', {
512
+ equal: true,
513
+ token: 'EQUAL'
514
+ });
515
+ this.matchSingleCharToken('/', {
516
+ slash: true,
517
+ token: 'SLASH'
518
+ });
519
+ this.matchSingleCharToken('!', {
520
+ exclamation: true,
521
+ token: 'EXCLAMATION'
522
+ });
523
+ this.matchSingleCharToken('-', {
524
+ minus: true,
525
+ token: 'MINUS'
526
+ });
527
+ this.matchSingleCharToken('&', {
528
+ amp: true,
529
+ token: 'AMP'
530
+ });
531
+ this.matchSingleCharToken('<', {
532
+ lt: true,
533
+ token: 'LT'
534
+ });
535
+ this.matchSingleCharToken('>', {
536
+ gt: true,
537
+ token: 'GT'
538
+ });
539
+ this.matchSingleCharToken('~', {
540
+ tilde: true,
541
+ token: 'TILDE'
542
+ });
543
+ if (this.token === null) {
544
+ this.token = {
545
+ unknown: true,
546
+ token: 'UNKNOWN',
547
+ matched: this.buffer.charAt(this.bufferIndex)
548
+ };
549
+ this.advanceCharsInBuffer(1);
550
+ }
551
+ }
552
+ return this.token;
553
+ };
554
+
555
+ /*
556
+ Look ahead a number of tokens and return the token found
557
+ */
558
+
559
+
560
+ Tokeniser.prototype.lookAhead = function(numberOfTokens) {
561
+ var bufferIndex, characterNumber, currentLine, currentToken, i, lineNumber, prevToken, token;
562
+
563
+ token = null;
564
+ if (numberOfTokens > 0) {
565
+ currentToken = this.token;
566
+ prevToken = this.prevToken;
567
+ currentLine = this.currentLine;
568
+ lineNumber = this.lineNumber;
569
+ characterNumber = this.characterNumber;
570
+ bufferIndex = this.bufferIndex;
571
+ i = 0;
572
+ while (i++ < numberOfTokens) {
573
+ token = this.getNextToken();
574
+ }
575
+ this.token = currentToken;
576
+ this.prevToken = prevToken;
577
+ this.currentLine = currentLine;
578
+ this.lineNumber = lineNumber;
579
+ this.characterNumber = characterNumber;
580
+ this.bufferIndex = bufferIndex;
581
+ }
582
+ return token;
583
+ };
584
+
585
+ /*
586
+ Initilise the line and character counters
587
+ */
588
+
589
+
590
+ Tokeniser.prototype.initLine = function() {
591
+ if (!this.currentLine && this.currentLine !== "") {
592
+ this.currentLine = this.getCurrentLine();
593
+ this.lineNumber = 1;
594
+ return this.characterNumber = 0;
595
+ }
596
+ };
597
+
598
+ /*
599
+ Returns the current line in the input buffer
600
+ */
601
+
602
+
603
+ Tokeniser.prototype.getCurrentLine = function(index) {
604
+ var line;
605
+
606
+ this.currentLineMatcher.lastIndex = this.bufferIndex + (index != null ? index : 0);
607
+ line = this.currentLineMatcher.exec(this.buffer);
608
+ if (line) {
609
+ return line[0];
610
+ } else {
611
+ return '';
612
+ }
613
+ };
614
+
615
+ /*
616
+ Returns an error string filled out with the line and character counters
617
+ */
618
+
619
+
620
+ Tokeniser.prototype.parseError = function(error) {
621
+ return haml.HamlRuntime.templateError(this.lineNumber, this.characterNumber, this.currentLine, error);
622
+ };
623
+
624
+ /*
625
+ Skips to the end of the line and returns the string that was skipped
626
+ */
627
+
628
+
629
+ Tokeniser.prototype.skipToEOLorEOF = function() {
630
+ var contents, line, text;
631
+
632
+ text = '';
633
+ if (!(this.token.eof || this.token.eol)) {
634
+ if (this.token.matched != null) {
635
+ text += this.token.matched;
636
+ }
637
+ this.currentLineMatcher.lastIndex = this.bufferIndex;
638
+ line = this.currentLineMatcher.exec(this.buffer);
639
+ if (line && line.index === this.bufferIndex) {
640
+ contents = (_.str || _).rtrim(line[0]);
641
+ if ((_.str || _).endsWith(contents, '|')) {
642
+ text += contents.substring(0, contents.length - 1);
643
+ this.advanceCharsInBuffer(contents.length - 1);
644
+ this.getNextToken();
645
+ text += this.parseMultiLine();
646
+ } else {
647
+ text += line[0];
648
+ this.advanceCharsInBuffer(line[0].length);
649
+ this.getNextToken();
650
+ }
651
+ }
652
+ }
653
+ return text;
654
+ };
655
+
656
+ /*
657
+ Parses a multiline code block and returns the parsed text
658
+ */
659
+
660
+
661
+ Tokeniser.prototype.parseMultiLine = function() {
662
+ var contents, line, text;
663
+
664
+ text = '';
665
+ while (this.token.continueLine) {
666
+ this.currentLineMatcher.lastIndex = this.bufferIndex;
667
+ line = this.currentLineMatcher.exec(this.buffer);
668
+ if (line && line.index === this.bufferIndex) {
669
+ contents = (_.str || _).rtrim(line[0]);
670
+ if ((_.str || _).endsWith(contents, '|')) {
671
+ text += contents.substring(0, contents.length - 1);
672
+ this.advanceCharsInBuffer(contents.length - 1);
673
+ }
674
+ this.getNextToken();
675
+ }
676
+ }
677
+ return text;
678
+ };
679
+
680
+ /*
681
+ Advances the input buffer pointer by a number of characters, updating the line and character counters
682
+ */
683
+
684
+
685
+ Tokeniser.prototype.advanceCharsInBuffer = function(numChars) {
686
+ var ch, ch1, i;
687
+
688
+ i = 0;
689
+ while (i < numChars) {
690
+ ch = this.buffer.charCodeAt(this.bufferIndex + i);
691
+ ch1 = this.buffer.charCodeAt(this.bufferIndex + i + 1);
692
+ if (ch === 13 && ch1 === 10) {
693
+ this.lineNumber++;
694
+ this.characterNumber = 0;
695
+ this.currentLine = this.getCurrentLine(i);
696
+ i++;
697
+ } else if (ch === 10) {
698
+ this.lineNumber++;
699
+ this.characterNumber = 0;
700
+ this.currentLine = this.getCurrentLine(i);
701
+ } else {
702
+ this.characterNumber++;
703
+ }
704
+ i++;
705
+ }
706
+ return this.bufferIndex += numChars;
707
+ };
708
+
709
+ /*
710
+ Returns the current line and character counters
711
+ */
712
+
713
+
714
+ Tokeniser.prototype.currentParsePoint = function() {
715
+ return {
716
+ lineNumber: this.lineNumber,
717
+ characterNumber: this.characterNumber,
718
+ currentLine: this.currentLine
719
+ };
720
+ };
721
+
722
+ /*
723
+ Pushes back the current token onto the front of the input buffer
724
+ */
725
+
726
+
727
+ Tokeniser.prototype.pushBackToken = function() {
728
+ if (!this.token.eof) {
729
+ this.bufferIndex -= this.token.matched.length;
730
+ return this.token = this.prevToken;
731
+ }
732
+ };
733
+
734
+ /*
735
+ Is the current token an end of line or end of input buffer
736
+ */
737
+
738
+
739
+ Tokeniser.prototype.isEolOrEof = function() {
740
+ return this.token.eol || this.token.eof;
741
+ };
742
+
743
+ /*
744
+ Match a Javascript Hash {...}
745
+ */
746
+
747
+
748
+ Tokeniser.prototype.matchJavascriptHash = function() {
749
+ var braceCount, ch, chCode, characterNumberStart, currentIndent, i, lineNumberStart;
750
+
751
+ currentIndent = this.calculateCurrentIndent();
752
+ i = this.bufferIndex + 1;
753
+ characterNumberStart = this.characterNumber;
754
+ lineNumberStart = this.lineNumber;
755
+ braceCount = 1;
756
+ while (i < this.buffer.length && (braceCount > 1 || this.buffer.charAt(i) !== '}')) {
757
+ ch = this.buffer.charAt(i);
758
+ chCode = this.buffer.charCodeAt(i);
759
+ if (ch === '{') {
760
+ braceCount++;
761
+ i++;
762
+ } else if (ch === '}') {
763
+ braceCount--;
764
+ i++;
765
+ } else if (chCode === 10 || chCode === 13) {
766
+ i++;
767
+ } else {
768
+ i++;
769
+ }
770
+ }
771
+ if (i === this.buffer.length) {
772
+ this.characterNumber = characterNumberStart + 1;
773
+ this.lineNumber = lineNumberStart;
774
+ throw this.parseError('Error parsing attribute hash - Did not find a terminating "}"');
775
+ } else {
776
+ this.token = {
777
+ attributeHash: true,
778
+ token: 'ATTRHASH',
779
+ tokenString: this.buffer.substring(this.bufferIndex, i + 1),
780
+ matched: this.buffer.substring(this.bufferIndex, i + 1)
781
+ };
782
+ return this.advanceCharsInBuffer(i - this.bufferIndex + 1);
783
+ }
784
+ };
785
+
786
+ /*
787
+ Calculate the indent value of the current line
788
+ */
789
+
790
+
791
+ Tokeniser.prototype.calculateCurrentIndent = function() {
792
+ var result;
793
+
794
+ this.tokenMatchers.whitespace.lastIndex = 0;
795
+ result = this.tokenMatchers.whitespace.exec(this.currentLine);
796
+ if ((result != null ? result.index : void 0) === 0) {
797
+ return this.calculateIndent(result[0]);
798
+ } else {
799
+ return 0;
800
+ }
801
+ };
802
+
803
+ /*
804
+ Calculate the indent level of the provided whitespace
805
+ */
806
+
807
+
808
+ Tokeniser.prototype.calculateIndent = function(whitespace) {
809
+ var i, indent;
810
+
811
+ indent = 0;
812
+ i = 0;
813
+ while (i < whitespace.length) {
814
+ if (whitespace.charCodeAt(i) === 9) {
815
+ indent += 2;
816
+ } else {
817
+ indent++;
818
+ }
819
+ i++;
820
+ }
821
+ return Math.floor((indent + 1) / 2);
822
+ };
823
+
824
+ return Tokeniser;
825
+
826
+ })();
827
+
828
+ /*
829
+ Provides buffering between the generated javascript and html contents
830
+ */
831
+
832
+
833
+ Buffer = (function() {
834
+ function Buffer(generator) {
835
+ this.generator = generator;
836
+ this.buffer = '';
837
+ this.outputBuffer = '';
838
+ }
839
+
840
+ Buffer.prototype.append = function(str) {
841
+ if ((this.generator != null) && this.buffer.length === 0) {
842
+ this.generator.mark();
843
+ }
844
+ if ((str != null ? str.length : void 0) > 0) {
845
+ return this.buffer += str;
846
+ }
847
+ };
848
+
849
+ Buffer.prototype.appendToOutputBuffer = function(str) {
850
+ if ((str != null ? str.length : void 0) > 0) {
851
+ this.flush();
852
+ return this.outputBuffer += str;
853
+ }
854
+ };
855
+
856
+ Buffer.prototype.flush = function() {
857
+ var _ref;
858
+
859
+ if (((_ref = this.buffer) != null ? _ref.length : void 0) > 0) {
860
+ this.outputBuffer += this.generator.generateFlush(this.buffer);
861
+ }
862
+ return this.buffer = '';
863
+ };
864
+
865
+ Buffer.prototype.output = function() {
866
+ return this.outputBuffer;
867
+ };
868
+
869
+ Buffer.prototype.trimWhitespace = function() {
870
+ var ch, i;
871
+
872
+ if (this.buffer.length > 0) {
873
+ i = this.buffer.length - 1;
874
+ while (i > 0) {
875
+ ch = this.buffer.charAt(i);
876
+ if (this._isWhitespace(ch)) {
877
+ i--;
878
+ } else if (i > 1 && (ch === 'n' || ch === 't') && (this.buffer.charAt(i - 1) === '\\')) {
879
+ i -= 2;
880
+ } else {
881
+ break;
882
+ }
883
+ }
884
+ if (i > 0 && i < this.buffer.length - 1) {
885
+ return this.buffer = this.buffer.substring(0, i + 1);
886
+ } else if (i === 0 && this._isWhitespace(this.buffer.charAt(0))) {
887
+ return this.buffer = '';
888
+ }
889
+ }
890
+ };
891
+
892
+ Buffer.prototype._isWhitespace = function(ch) {
893
+ return ch === ' ' || ch === '\t' || ch === '\n';
894
+ };
895
+
896
+ return Buffer;
897
+
898
+ })();
899
+
900
+ /*
901
+ Common code shared across all code generators
902
+ */
903
+
904
+
905
+ CodeGenerator = (function() {
906
+ function CodeGenerator() {}
907
+
908
+ CodeGenerator.prototype.embeddedCodeBlockMatcher = /#{([^}]*)}/g;
909
+
910
+ return CodeGenerator;
911
+
912
+ })();
913
+
914
+ /*
915
+ Code generator that generates a Javascript function body
916
+ */
917
+
918
+
919
+ JsCodeGenerator = (function(_super) {
920
+ __extends(JsCodeGenerator, _super);
921
+
922
+ function JsCodeGenerator(options) {
923
+ this.options = options;
924
+ this.outputBuffer = new haml.Buffer(this);
925
+ }
926
+
927
+ /*
928
+ Append a line with embedded javascript code
929
+ */
930
+
931
+
932
+ JsCodeGenerator.prototype.appendEmbeddedCode = function(indentText, expression, escapeContents, perserveWhitespace, currentParsePoint) {
933
+ this.outputBuffer.flush();
934
+ this.outputBuffer.appendToOutputBuffer(indentText + 'try {\n');
935
+ this.outputBuffer.appendToOutputBuffer(indentText + ' var value = eval("' + (_.str || _).trim(expression).replace(/"/g, '\\"').replace(/\\n/g, '\\\\n') + '");\n');
936
+ this.outputBuffer.appendToOutputBuffer(indentText + ' value = value === null ? "" : value;');
937
+ if (escapeContents) {
938
+ this.outputBuffer.appendToOutputBuffer(indentText + ' html.push(haml.HamlRuntime.escapeHTML(String(value)));\n');
939
+ } else if (perserveWhitespace) {
940
+ this.outputBuffer.appendToOutputBuffer(indentText + ' html.push(haml.HamlRuntime.perserveWhitespace(String(value)));\n');
941
+ } else {
942
+ this.outputBuffer.appendToOutputBuffer(indentText + ' html.push(String(value));\n');
943
+ }
944
+ this.outputBuffer.appendToOutputBuffer(indentText + '} catch (e) {\n');
945
+ this.outputBuffer.appendToOutputBuffer(indentText + ' handleError(haml.HamlRuntime.templateError(' + currentParsePoint.lineNumber + ', ' + currentParsePoint.characterNumber + ', "' + this.escapeCode(currentParsePoint.currentLine) + '",\n');
946
+ this.outputBuffer.appendToOutputBuffer(indentText + ' "Error evaluating expression - " + e));\n');
947
+ return this.outputBuffer.appendToOutputBuffer(indentText + '}\n');
948
+ };
949
+
950
+ /*
951
+ Initilising the output buffer with any variables or code
952
+ */
953
+
954
+
955
+ JsCodeGenerator.prototype.initOutput = function() {
956
+ var _ref;
957
+
958
+ if ((_ref = this.options) != null ? _ref.tolerateFaults : void 0) {
959
+ this.outputBuffer.appendToOutputBuffer(' var handleError = haml.HamlRuntime._logError;');
960
+ } else {
961
+ this.outputBuffer.appendToOutputBuffer(' var handleError = haml.HamlRuntime._raiseError;');
962
+ }
963
+ return this.outputBuffer.appendToOutputBuffer('var html = [];\nvar hashFunction = null, hashObject = null, objRef = null, objRefFn = null;\nwith (context || {}) {');
964
+ };
965
+
966
+ /*
967
+ Flush and close the output buffer and return the contents
968
+ */
969
+
970
+
971
+ JsCodeGenerator.prototype.closeAndReturnOutput = function() {
972
+ this.outputBuffer.flush();
973
+ return this.outputBuffer.output() + ' }\n return html.join("");\n';
974
+ };
975
+
976
+ /*
977
+ Append a line of code to the output buffer
978
+ */
979
+
980
+
981
+ JsCodeGenerator.prototype.appendCodeLine = function(line, eol) {
982
+ this.outputBuffer.flush();
983
+ this.outputBuffer.appendToOutputBuffer(HamlRuntime.indentText(this.indent));
984
+ this.outputBuffer.appendToOutputBuffer(line);
985
+ return this.outputBuffer.appendToOutputBuffer(eol);
986
+ };
987
+
988
+ /*
989
+ Does the current line end with a function declaration?
990
+ */
991
+
992
+
993
+ JsCodeGenerator.prototype.lineMatchesStartFunctionBlock = function(line) {
994
+ return line.match(/function\s*\((,?\s*\w+)*\)\s*\{\s*$/);
995
+ };
996
+
997
+ /*
998
+ Does the current line end with a starting code block
999
+ */
1000
+
1001
+
1002
+ JsCodeGenerator.prototype.lineMatchesStartBlock = function(line) {
1003
+ return line.match(/\{\s*$/);
1004
+ };
1005
+
1006
+ /*
1007
+ Generate the code to close off a code block
1008
+ */
1009
+
1010
+
1011
+ JsCodeGenerator.prototype.closeOffCodeBlock = function(tokeniser) {
1012
+ if (!(tokeniser.token.minus && tokeniser.matchToken(/\s*\}/g))) {
1013
+ this.outputBuffer.flush();
1014
+ return this.outputBuffer.appendToOutputBuffer(HamlRuntime.indentText(this.indent) + '}\n');
1015
+ }
1016
+ };
1017
+
1018
+ /*
1019
+ Generate the code to close off a function parameter
1020
+ */
1021
+
1022
+
1023
+ JsCodeGenerator.prototype.closeOffFunctionBlock = function(tokeniser) {
1024
+ if (!(tokeniser.token.minus && tokeniser.matchToken(/\s*\}/g))) {
1025
+ this.outputBuffer.flush();
1026
+ return this.outputBuffer.appendToOutputBuffer(HamlRuntime.indentText(this.indent) + '});\n');
1027
+ }
1028
+ };
1029
+
1030
+ /*
1031
+ Generate the code for dynamic attributes ({} form)
1032
+ */
1033
+
1034
+
1035
+ JsCodeGenerator.prototype.generateCodeForDynamicAttributes = function(id, classes, attributeList, attributeHash, objectRef, currentParsePoint) {
1036
+ this.outputBuffer.flush();
1037
+ if (attributeHash.length > 0) {
1038
+ attributeHash = this.replaceReservedWordsInHash(attributeHash);
1039
+ this.outputBuffer.appendToOutputBuffer(' hashFunction = function () { return eval("hashObject = ' + attributeHash.replace(/"/g, '\\"').replace(/\n/g, '\\n') + '"); };\n');
1040
+ } else {
1041
+ this.outputBuffer.appendToOutputBuffer(' hashFunction = null;\n');
1042
+ }
1043
+ if (objectRef.length > 0) {
1044
+ this.outputBuffer.appendToOutputBuffer(' objRefFn = function () { return eval("objRef = ' + objectRef.replace(/"/g, '\\"') + '"); };\n');
1045
+ } else {
1046
+ this.outputBuffer.appendToOutputBuffer(' objRefFn = null;\n');
1047
+ }
1048
+ return this.outputBuffer.appendToOutputBuffer(' html.push(haml.HamlRuntime.generateElementAttributes(context, "' + id + '", ["' + classes.join('","') + '"], objRefFn, ' + JSON.stringify(attributeList) + ', hashFunction, ' + currentParsePoint.lineNumber + ', ' + currentParsePoint.characterNumber + ', "' + this.escapeCode(currentParsePoint.currentLine) + '", handleError));\n');
1049
+ };
1050
+
1051
+ /*
1052
+ Clean any reserved words in the given hash
1053
+ */
1054
+
1055
+
1056
+ JsCodeGenerator.prototype.replaceReservedWordsInHash = function(hash) {
1057
+ var reservedWord, resultHash, _i, _len, _ref;
1058
+
1059
+ resultHash = hash;
1060
+ _ref = ['class', 'for'];
1061
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
1062
+ reservedWord = _ref[_i];
1063
+ resultHash = resultHash.replace(reservedWord + ':', '"' + reservedWord + '":');
1064
+ }
1065
+ return resultHash;
1066
+ };
1067
+
1068
+ /*
1069
+ Escape the line so it is safe to put into a javascript string
1070
+ */
1071
+
1072
+
1073
+ JsCodeGenerator.prototype.escapeCode = function(jsStr) {
1074
+ return jsStr.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n').replace(/\r/g, '\\r');
1075
+ };
1076
+
1077
+ /*
1078
+ Generate a function from the function body
1079
+ */
1080
+
1081
+
1082
+ JsCodeGenerator.prototype.generateJsFunction = function(functionBody) {
1083
+ var e;
1084
+
1085
+ try {
1086
+ return new Function('context', functionBody);
1087
+ } catch (_error) {
1088
+ e = _error;
1089
+ throw "Incorrect embedded code has resulted in an invalid Haml function - " + e + "\nGenerated Function:\n" + functionBody;
1090
+ }
1091
+ };
1092
+
1093
+ /*
1094
+ Generate the code required to support a buffer flush
1095
+ */
1096
+
1097
+
1098
+ JsCodeGenerator.prototype.generateFlush = function(bufferStr) {
1099
+ return ' html.push("' + this.escapeCode(bufferStr) + '");\n';
1100
+ };
1101
+
1102
+ /*
1103
+ Set the current indent level
1104
+ */
1105
+
1106
+
1107
+ JsCodeGenerator.prototype.setIndent = function(indent) {
1108
+ return this.indent = indent;
1109
+ };
1110
+
1111
+ /*
1112
+ Save the current indent level if required
1113
+ */
1114
+
1115
+
1116
+ JsCodeGenerator.prototype.mark = function() {};
1117
+
1118
+ /*
1119
+ Append the text contents to the buffer, expanding any embedded code
1120
+ */
1121
+
1122
+
1123
+ JsCodeGenerator.prototype.appendTextContents = function(text, shouldInterpolate, currentParsePoint, options) {
1124
+ if (options == null) {
1125
+ options = {};
1126
+ }
1127
+ if (shouldInterpolate && text.match(/#{[^}]*}/)) {
1128
+ return this.interpolateString(text, currentParsePoint, options);
1129
+ } else {
1130
+ return this.outputBuffer.append(this.processText(text, options));
1131
+ }
1132
+ };
1133
+
1134
+ /*
1135
+ Interpolate any embedded code in the text
1136
+ */
1137
+
1138
+
1139
+ JsCodeGenerator.prototype.interpolateString = function(text, currentParsePoint, options) {
1140
+ var index, precheedingChar, precheedingChar2, result;
1141
+
1142
+ index = 0;
1143
+ result = this.embeddedCodeBlockMatcher.exec(text);
1144
+ while (result) {
1145
+ if (result.index > 0) {
1146
+ precheedingChar = text.charAt(result.index - 1);
1147
+ }
1148
+ if (result.index > 1) {
1149
+ precheedingChar2 = text.charAt(result.index - 2);
1150
+ }
1151
+ if (precheedingChar === '\\' && precheedingChar2 !== '\\') {
1152
+ if (result.index !== 0) {
1153
+ this.outputBuffer.append(this.processText(text.substring(index, result.index - 1), options));
1154
+ }
1155
+ this.outputBuffer.append(this.processText(result[0]), options);
1156
+ } else {
1157
+ this.outputBuffer.append(this.processText(text.substring(index, result.index)), options);
1158
+ this.appendEmbeddedCode(HamlRuntime.indentText(this.indent + 1), result[1], options.escapeHTML, options.perserveWhitespace, currentParsePoint);
1159
+ }
1160
+ index = this.embeddedCodeBlockMatcher.lastIndex;
1161
+ result = this.embeddedCodeBlockMatcher.exec(text);
1162
+ }
1163
+ if (index < text.length) {
1164
+ return this.outputBuffer.append(this.processText(text.substring(index), options));
1165
+ }
1166
+ };
1167
+
1168
+ /*
1169
+ process text based on escape and preserve flags
1170
+ */
1171
+
1172
+
1173
+ JsCodeGenerator.prototype.processText = function(text, options) {
1174
+ if (options != null ? options.escapeHTML : void 0) {
1175
+ return haml.HamlRuntime.escapeHTML(text);
1176
+ } else if (options != null ? options.perserveWhitespace : void 0) {
1177
+ return haml.HamlRuntime.perserveWhitespace(text);
1178
+ } else {
1179
+ return text;
1180
+ }
1181
+ };
1182
+
1183
+ return JsCodeGenerator;
1184
+
1185
+ })(CodeGenerator);
1186
+
1187
+ /*
1188
+ Code generator that generates javascript code without runtime evaluation
1189
+ */
1190
+
1191
+
1192
+ ProductionJsCodeGenerator = (function(_super) {
1193
+ __extends(ProductionJsCodeGenerator, _super);
1194
+
1195
+ function ProductionJsCodeGenerator() {
1196
+ _ref = ProductionJsCodeGenerator.__super__.constructor.apply(this, arguments);
1197
+ return _ref;
1198
+ }
1199
+
1200
+ /*
1201
+ Append a line with embedded javascript code
1202
+ */
1203
+
1204
+
1205
+ ProductionJsCodeGenerator.prototype.appendEmbeddedCode = function(indentText, expression, escapeContents, perserveWhitespace, currentParsePoint) {
1206
+ this.outputBuffer.flush();
1207
+ this.outputBuffer.appendToOutputBuffer(indentText + ' value = ' + (_.str || _).trim(expression) + ';\n');
1208
+ this.outputBuffer.appendToOutputBuffer(indentText + ' value = value === null ? "" : value;');
1209
+ if (escapeContents) {
1210
+ return this.outputBuffer.appendToOutputBuffer(indentText + ' html.push(haml.HamlRuntime.escapeHTML(String(value)));\n');
1211
+ } else if (perserveWhitespace) {
1212
+ return this.outputBuffer.appendToOutputBuffer(indentText + ' html.push(haml.HamlRuntime.perserveWhitespace(String(value)));\n');
1213
+ } else {
1214
+ return this.outputBuffer.appendToOutputBuffer(indentText + ' html.push(String(value));\n');
1215
+ }
1216
+ };
1217
+
1218
+ /*
1219
+ Generate the code for dynamic attributes ({} form)
1220
+ */
1221
+
1222
+
1223
+ ProductionJsCodeGenerator.prototype.generateCodeForDynamicAttributes = function(id, classes, attributeList, attributeHash, objectRef, currentParsePoint) {
1224
+ this.outputBuffer.flush();
1225
+ if (attributeHash.length > 0) {
1226
+ attributeHash = this.replaceReservedWordsInHash(attributeHash);
1227
+ this.outputBuffer.appendToOutputBuffer(' hashFunction = function () { return ' + attributeHash + '; };\n');
1228
+ } else {
1229
+ this.outputBuffer.appendToOutputBuffer(' hashFunction = null;\n');
1230
+ }
1231
+ if (objectRef.length > 0) {
1232
+ this.outputBuffer.appendToOutputBuffer(' objRefFn = function () { return ' + objectRef + '; };\n');
1233
+ } else {
1234
+ this.outputBuffer.appendToOutputBuffer(' objRefFn = null;\n');
1235
+ }
1236
+ return this.outputBuffer.appendToOutputBuffer(' html.push(haml.HamlRuntime.generateElementAttributes(context, "' + id + '", ["' + classes.join('","') + '"], objRefFn, ' + JSON.stringify(attributeList) + ', hashFunction, ' + currentParsePoint.lineNumber + ', ' + currentParsePoint.characterNumber + ', "' + this.escapeCode(currentParsePoint.currentLine) + '"));\n');
1237
+ };
1238
+
1239
+ /*
1240
+ Initilising the output buffer with any variables or code
1241
+ */
1242
+
1243
+
1244
+ ProductionJsCodeGenerator.prototype.initOutput = function() {
1245
+ return this.outputBuffer.appendToOutputBuffer(' var html = [];\n' + ' var hashFunction = null, hashObject = null, objRef = null, objRefFn = null, value= null;\n with (context || {}) {\n');
1246
+ };
1247
+
1248
+ return ProductionJsCodeGenerator;
1249
+
1250
+ })(JsCodeGenerator);
1251
+
1252
+ /*
1253
+ Code generator that generates a coffeescript function body
1254
+ */
1255
+
1256
+
1257
+ CoffeeCodeGenerator = (function(_super) {
1258
+ __extends(CoffeeCodeGenerator, _super);
1259
+
1260
+ function CoffeeCodeGenerator(options) {
1261
+ this.options = options;
1262
+ this.outputBuffer = new haml.Buffer(this);
1263
+ }
1264
+
1265
+ CoffeeCodeGenerator.prototype.appendEmbeddedCode = function(indentText, expression, escapeContents, perserveWhitespace, currentParsePoint) {
1266
+ var indent;
1267
+
1268
+ this.outputBuffer.flush();
1269
+ indent = this.calcCodeIndent();
1270
+ this.outputBuffer.appendToOutputBuffer(indent + "try\n");
1271
+ this.outputBuffer.appendToOutputBuffer(indent + " exp = CoffeeScript.compile('" + expression.replace(/'/g, "\\'").replace(/\\n/g, '\\\\n') + "', bare: true)\n");
1272
+ this.outputBuffer.appendToOutputBuffer(indent + " value = eval(exp)\n");
1273
+ this.outputBuffer.appendToOutputBuffer(indent + " value ?= ''\n");
1274
+ if (escapeContents) {
1275
+ this.outputBuffer.appendToOutputBuffer(indent + " html.push(haml.HamlRuntime.escapeHTML(String(value)))\n");
1276
+ } else if (perserveWhitespace) {
1277
+ this.outputBuffer.appendToOutputBuffer(indent + " html.push(haml.HamlRuntime.perserveWhitespace(String(value)))\n");
1278
+ } else {
1279
+ this.outputBuffer.appendToOutputBuffer(indent + " html.push(String(value))\n");
1280
+ }
1281
+ this.outputBuffer.appendToOutputBuffer(indent + "catch e \n");
1282
+ this.outputBuffer.appendToOutputBuffer(indent + " handleError new Error(haml.HamlRuntime.templateError(" + currentParsePoint.lineNumber + ", " + currentParsePoint.characterNumber + ", '" + this.escapeCode(currentParsePoint.currentLine) + "',\n");
1283
+ return this.outputBuffer.appendToOutputBuffer(indent + " 'Error evaluating expression - ' + e))\n");
1284
+ };
1285
+
1286
+ CoffeeCodeGenerator.prototype.initOutput = function() {
1287
+ var _ref1;
1288
+
1289
+ if ((_ref1 = this.options) != null ? _ref1.tolerateFaults : void 0) {
1290
+ this.outputBuffer.appendToOutputBuffer('handleError = haml.HamlRuntime._logError\n');
1291
+ } else {
1292
+ this.outputBuffer.appendToOutputBuffer('handleError = haml.HamlRuntime._raiseError\n');
1293
+ }
1294
+ return this.outputBuffer.appendToOutputBuffer('html = []\n');
1295
+ };
1296
+
1297
+ CoffeeCodeGenerator.prototype.closeAndReturnOutput = function() {
1298
+ this.outputBuffer.flush();
1299
+ return this.outputBuffer.output() + 'return html.join("")\n';
1300
+ };
1301
+
1302
+ CoffeeCodeGenerator.prototype.appendCodeLine = function(line, eol) {
1303
+ this.outputBuffer.flush();
1304
+ this.outputBuffer.appendToOutputBuffer(this.calcCodeIndent());
1305
+ this.outputBuffer.appendToOutputBuffer((_.str || _).trim(line));
1306
+ this.outputBuffer.appendToOutputBuffer(eol);
1307
+ return this.prevCodeIndent = this.indent;
1308
+ };
1309
+
1310
+ CoffeeCodeGenerator.prototype.lineMatchesStartFunctionBlock = function(line) {
1311
+ return line.match(/\) [\-=]>\s*$/);
1312
+ };
1313
+
1314
+ CoffeeCodeGenerator.prototype.lineMatchesStartBlock = function(line) {
1315
+ return true;
1316
+ };
1317
+
1318
+ CoffeeCodeGenerator.prototype.closeOffCodeBlock = function(tokeniser) {
1319
+ return this.outputBuffer.flush();
1320
+ };
1321
+
1322
+ CoffeeCodeGenerator.prototype.closeOffFunctionBlock = function(tokeniser) {
1323
+ return this.outputBuffer.flush();
1324
+ };
1325
+
1326
+ CoffeeCodeGenerator.prototype.generateCodeForDynamicAttributes = function(id, classes, attributeList, attributeHash, objectRef, currentParsePoint) {
1327
+ var indent;
1328
+
1329
+ this.outputBuffer.flush();
1330
+ indent = this.calcCodeIndent();
1331
+ if (attributeHash.length > 0) {
1332
+ attributeHash = this.replaceReservedWordsInHash(attributeHash);
1333
+ this.outputBuffer.appendToOutputBuffer(indent + "hashFunction = () -> s = CoffeeScript.compile('" + attributeHash.replace(/'/g, "\\'").replace(/\n/g, '\\n') + "', bare: true); eval 'hashObject = ' + s\n");
1334
+ } else {
1335
+ this.outputBuffer.appendToOutputBuffer(indent + "hashFunction = null\n");
1336
+ }
1337
+ if (objectRef.length > 0) {
1338
+ this.outputBuffer.appendToOutputBuffer(indent + "objRefFn = () -> s = CoffeeScript.compile('" + objectRef.replace(/'/g, "\\'") + "', bare: true); eval 'objRef = ' + s\n");
1339
+ } else {
1340
+ this.outputBuffer.appendToOutputBuffer(indent + "objRefFn = null\n");
1341
+ }
1342
+ return this.outputBuffer.appendToOutputBuffer(indent + "html.push(haml.HamlRuntime.generateElementAttributes(this, '" + id + "', ['" + classes.join("','") + "'], objRefFn ? null, " + JSON.stringify(attributeList) + ", hashFunction ? null, " + currentParsePoint.lineNumber + ", " + currentParsePoint.characterNumber + ", '" + this.escapeCode(currentParsePoint.currentLine) + "', handleError))\n");
1343
+ };
1344
+
1345
+ CoffeeCodeGenerator.prototype.replaceReservedWordsInHash = function(hash) {
1346
+ var reservedWord, resultHash, _i, _len, _ref1;
1347
+
1348
+ resultHash = hash;
1349
+ _ref1 = ['class', 'for'];
1350
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
1351
+ reservedWord = _ref1[_i];
1352
+ resultHash = resultHash.replace(reservedWord + ':', "'" + reservedWord + "':");
1353
+ }
1354
+ return resultHash;
1355
+ };
1356
+
1357
+ /*
1358
+ Escapes the string for insertion into the generated code. Embedded code blocks in strings must not be escaped
1359
+ */
1360
+
1361
+
1362
+ CoffeeCodeGenerator.prototype.escapeCode = function(str) {
1363
+ var index, outString, precheedingChar, precheedingChar2, result;
1364
+
1365
+ outString = '';
1366
+ index = 0;
1367
+ result = this.embeddedCodeBlockMatcher.exec(str);
1368
+ while (result) {
1369
+ if (result.index > 0) {
1370
+ precheedingChar = str.charAt(result.index - 1);
1371
+ }
1372
+ if (result.index > 1) {
1373
+ precheedingChar2 = str.charAt(result.index - 2);
1374
+ }
1375
+ if (precheedingChar === '\\' && precheedingChar2 !== '\\') {
1376
+ if (result.index !== 0) {
1377
+ outString += this._escapeText(str.substring(index, result.index - 1));
1378
+ }
1379
+ outString += this._escapeText('\\' + result[0]);
1380
+ } else {
1381
+ outString += this._escapeText(str.substring(index, result.index));
1382
+ outString += result[0];
1383
+ }
1384
+ index = this.embeddedCodeBlockMatcher.lastIndex;
1385
+ result = this.embeddedCodeBlockMatcher.exec(str);
1386
+ }
1387
+ if (index < str.length) {
1388
+ outString += this._escapeText(str.substring(index));
1389
+ }
1390
+ return outString;
1391
+ };
1392
+
1393
+ CoffeeCodeGenerator.prototype._escapeText = function(text) {
1394
+ return text.replace(/\\/g, '\\\\').replace(/'/g, '\\\'').replace(/"/g, '\\\"').replace(/\n/g, '\\n').replace(/(^|[^\\]{2})\\\\#{/g, '$1\\#{');
1395
+ };
1396
+
1397
+ /*
1398
+ Generates the javascript function by compiling the given code with coffeescript compiler
1399
+ */
1400
+
1401
+
1402
+ CoffeeCodeGenerator.prototype.generateJsFunction = function(functionBody) {
1403
+ var e, fn;
1404
+
1405
+ try {
1406
+ fn = CoffeeScript.compile(functionBody, {
1407
+ bare: true
1408
+ });
1409
+ return new Function(fn);
1410
+ } catch (_error) {
1411
+ e = _error;
1412
+ throw "Incorrect embedded code has resulted in an invalid Haml function - " + e + "\nGenerated Function:\n" + fn;
1413
+ }
1414
+ };
1415
+
1416
+ CoffeeCodeGenerator.prototype.generateFlush = function(bufferStr) {
1417
+ return this.calcCodeIndent() + "html.push('" + this.escapeCode(bufferStr) + "')\n";
1418
+ };
1419
+
1420
+ CoffeeCodeGenerator.prototype.setIndent = function(indent) {
1421
+ return this.indent = indent;
1422
+ };
1423
+
1424
+ CoffeeCodeGenerator.prototype.mark = function() {
1425
+ return this.prevIndent = this.indent;
1426
+ };
1427
+
1428
+ CoffeeCodeGenerator.prototype.calcCodeIndent = function() {
1429
+ var codeIndent, i, _i, _ref1, _ref2, _ref3;
1430
+
1431
+ codeIndent = 0;
1432
+ for (i = _i = 0, _ref1 = this.indent; 0 <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = 0 <= _ref1 ? ++_i : --_i) {
1433
+ if (((_ref2 = this.elementStack[i]) != null ? _ref2.block : void 0) || ((_ref3 = this.elementStack[i]) != null ? _ref3.fnBlock : void 0)) {
1434
+ codeIndent += 1;
1435
+ }
1436
+ }
1437
+ return HamlRuntime.indentText(codeIndent);
1438
+ };
1439
+
1440
+ /*
1441
+ Append the text contents to the buffer (interpolating embedded code not required for coffeescript)
1442
+ */
1443
+
1444
+
1445
+ CoffeeCodeGenerator.prototype.appendTextContents = function(text, shouldInterpolate, currentParsePoint, options) {
1446
+ var prefix, suffix;
1447
+
1448
+ if (shouldInterpolate && text.match(/#{[^}]*}/)) {
1449
+ this.outputBuffer.flush();
1450
+ prefix = suffix = '';
1451
+ if (options != null ? options.escapeHTML : void 0) {
1452
+ prefix = 'haml.HamlRuntime.escapeHTML(';
1453
+ suffix = ')';
1454
+ } else if (options != null ? options.perserveWhitespace : void 0) {
1455
+ prefix = 'haml.HamlRuntime.perserveWhitespace(';
1456
+ suffix = ')';
1457
+ }
1458
+ return this.outputBuffer.appendToOutputBuffer(this.calcCodeIndent() + 'html.push(' + prefix + '"' + this.escapeCode(text) + '"' + suffix + ')\n');
1459
+ } else {
1460
+ if (options != null ? options.escapeHTML : void 0) {
1461
+ text = haml.HamlRuntime.escapeHTML(text);
1462
+ }
1463
+ if (options != null ? options.perserveWhitespace : void 0) {
1464
+ text = haml.HamlRuntime.perserveWhitespace(text);
1465
+ }
1466
+ return this.outputBuffer.append(text);
1467
+ }
1468
+ };
1469
+
1470
+ return CoffeeCodeGenerator;
1471
+
1472
+ })(CodeGenerator);
1473
+
1474
+ /*
1475
+ HAML filters are functions that take 3 parameters
1476
+ contents: The contents block for the filter an array of lines of text
1477
+ generator: The current generator for the compiled function
1478
+ indent: The current indent level
1479
+ currentParsePoint: line and character counters for the current parse point in the input buffer
1480
+ */
1481
+
1482
+
1483
+ filters = {
1484
+ /*
1485
+ Plain filter, just renders the text in the block
1486
+ */
1487
+
1488
+ plain: function(contents, generator, indent, currentParsePoint) {
1489
+ var line, _i, _len;
1490
+
1491
+ for (_i = 0, _len = contents.length; _i < _len; _i++) {
1492
+ line = contents[_i];
1493
+ generator.appendTextContents(haml.HamlRuntime.indentText(indent - 1) + line + '\n', true, currentParsePoint);
1494
+ }
1495
+ return true;
1496
+ },
1497
+ /*
1498
+ Wraps the filter block in a javascript tag
1499
+ */
1500
+
1501
+ javascript: function(contents, generator, indent, currentParsePoint) {
1502
+ var line, _i, _len;
1503
+
1504
+ generator.outputBuffer.append(haml.HamlRuntime.indentText(indent) + "<script type=\"text/javascript\">\n");
1505
+ generator.outputBuffer.append(haml.HamlRuntime.indentText(indent + 1) + "//<![CDATA[\n");
1506
+ for (_i = 0, _len = contents.length; _i < _len; _i++) {
1507
+ line = contents[_i];
1508
+ generator.appendTextContents(haml.HamlRuntime.indentText(indent + 1) + line + '\n', true, currentParsePoint);
1509
+ }
1510
+ generator.outputBuffer.append(haml.HamlRuntime.indentText(indent + 1) + "//]]>\n");
1511
+ return generator.outputBuffer.append(haml.HamlRuntime.indentText(indent) + "</script>\n");
1512
+ },
1513
+ /*
1514
+ Wraps the filter block in a style tag
1515
+ */
1516
+
1517
+ css: function(contents, generator, indent, currentParsePoint) {
1518
+ var line, _i, _len;
1519
+
1520
+ generator.outputBuffer.append(haml.HamlRuntime.indentText(indent) + "<style type=\"text/css\">\n");
1521
+ generator.outputBuffer.append(haml.HamlRuntime.indentText(indent + 1) + "/*<![CDATA[*/\n");
1522
+ for (_i = 0, _len = contents.length; _i < _len; _i++) {
1523
+ line = contents[_i];
1524
+ generator.appendTextContents(haml.HamlRuntime.indentText(indent + 1) + line + '\n', true, currentParsePoint);
1525
+ }
1526
+ generator.outputBuffer.append(haml.HamlRuntime.indentText(indent + 1) + "/*]]>*/\n");
1527
+ return generator.outputBuffer.append(haml.HamlRuntime.indentText(indent) + "</style>\n");
1528
+ },
1529
+ /*
1530
+ Wraps the filter block in a CDATA tag
1531
+ */
1532
+
1533
+ cdata: function(contents, generator, indent, currentParsePoint) {
1534
+ var line, _i, _len;
1535
+
1536
+ generator.outputBuffer.append(haml.HamlRuntime.indentText(indent) + "<![CDATA[\n");
1537
+ for (_i = 0, _len = contents.length; _i < _len; _i++) {
1538
+ line = contents[_i];
1539
+ generator.appendTextContents(haml.HamlRuntime.indentText(indent) + line + '\n', true, currentParsePoint);
1540
+ }
1541
+ return generator.outputBuffer.append(haml.HamlRuntime.indentText(indent) + "]]>\n");
1542
+ },
1543
+ /*
1544
+ Preserve filter, preserved blocks of text aren't indented, and newlines are replaced with the HTML escape code for newlines
1545
+ */
1546
+
1547
+ preserve: function(contents, generator, indent, currentParsePoint) {
1548
+ var line;
1549
+
1550
+ generator.appendTextContents(haml.HamlRuntime.indentText(indent), false, currentParsePoint);
1551
+ return generator.appendTextContents(((function() {
1552
+ var _i, _len, _results;
1553
+
1554
+ _results = [];
1555
+ for (_i = 0, _len = contents.length; _i < _len; _i++) {
1556
+ line = contents[_i];
1557
+ _results.push(haml.HamlRuntime.trim(line, 2));
1558
+ }
1559
+ return _results;
1560
+ })()).join('&#x000A; ') + '\n', true, currentParsePoint);
1561
+ },
1562
+ /*
1563
+ Escape filter, renders the text in the block with html escaped
1564
+ */
1565
+
1566
+ escaped: function(contents, generator, indent, currentParsePoint) {
1567
+ var line, _i, _len;
1568
+
1569
+ for (_i = 0, _len = contents.length; _i < _len; _i++) {
1570
+ line = contents[_i];
1571
+ generator.appendTextContents(haml.HamlRuntime.indentText(indent - 1) + line + '\n', true, currentParsePoint, {
1572
+ escapeHTML: true
1573
+ });
1574
+ }
1575
+ return true;
1576
+ }
1577
+ };
1578
+
1579
+ /*
1580
+ Main haml compiler implemtation
1581
+ */
1582
+
1583
+
1584
+ haml = {
1585
+ /*
1586
+ Compiles the haml provided in the parameters to a Javascipt function
1587
+
1588
+ Parameter:
1589
+ String: Looks for a haml template in dom with this ID
1590
+ Option Hash: The following options determines how haml sources and compiles the template
1591
+ source - This contains the template in string form
1592
+ sourceId - This contains the element ID in the dom which contains the haml source
1593
+ sourceUrl - This contains the URL where the template can be fetched from
1594
+ outputFormat - This determines what is returned, and has the following values:
1595
+ string - The javascript source code
1596
+ function - A javascript function (default)
1597
+ generator - Which code generator to use
1598
+ javascript (default)
1599
+ coffeescript
1600
+ productionjavascript
1601
+ tolerateErrors - switch the compiler into fault tolerant mode (defaults to false)
1602
+
1603
+ Returns a javascript function
1604
+ */
1605
+
1606
+ compileHaml: function(options) {
1607
+ var codeGenerator, result, tokinser;
1608
+
1609
+ if (typeof options === 'string') {
1610
+ return this._compileHamlTemplate(options, new haml.JsCodeGenerator());
1611
+ } else {
1612
+ codeGenerator = (function() {
1613
+ switch (options.generator) {
1614
+ case 'coffeescript':
1615
+ return new haml.CoffeeCodeGenerator(options);
1616
+ case 'productionjavascript':
1617
+ return new haml.ProductionJsCodeGenerator(options);
1618
+ default:
1619
+ return new haml.JsCodeGenerator(options);
1620
+ }
1621
+ })();
1622
+ if (options.source != null) {
1623
+ tokinser = new haml.Tokeniser({
1624
+ template: options.source
1625
+ });
1626
+ } else if (options.sourceId != null) {
1627
+ tokinser = new haml.Tokeniser({
1628
+ templateId: options.sourceId
1629
+ });
1630
+ } else if (options.sourceUrl != null) {
1631
+ tokinser = new haml.Tokeniser({
1632
+ templateUrl: options.sourceUrl
1633
+ });
1634
+ } else {
1635
+ throw "No template source specified for compileHaml. You need to provide a source, sourceId or sourceUrl option";
1636
+ }
1637
+ result = this._compileHamlToJs(tokinser, codeGenerator, options);
1638
+ if (options.outputFormat !== 'string') {
1639
+ return codeGenerator.generateJsFunction(result);
1640
+ } else {
1641
+ return "function (context) {\n" + result + "}\n";
1642
+ }
1643
+ }
1644
+ },
1645
+ /*
1646
+ Compiles the haml in the script block with ID templateId using the coffeescript generator
1647
+ Returns a javascript function
1648
+ */
1649
+
1650
+ compileCoffeeHaml: function(templateId) {
1651
+ return this._compileHamlTemplate(templateId, new haml.CoffeeCodeGenerator());
1652
+ },
1653
+ /*
1654
+ Compiles the haml in the passed in string
1655
+ Returns a javascript function
1656
+ */
1657
+
1658
+ compileStringToJs: function(string) {
1659
+ var codeGenerator, result;
1660
+
1661
+ codeGenerator = new haml.JsCodeGenerator();
1662
+ result = this._compileHamlToJs(new haml.Tokeniser({
1663
+ template: string
1664
+ }), codeGenerator);
1665
+ return codeGenerator.generateJsFunction(result);
1666
+ },
1667
+ /*
1668
+ Compiles the haml in the passed in string using the coffeescript generator
1669
+ Returns a javascript function
1670
+ */
1671
+
1672
+ compileCoffeeHamlFromString: function(string) {
1673
+ var codeGenerator, result;
1674
+
1675
+ codeGenerator = new haml.CoffeeCodeGenerator();
1676
+ result = this._compileHamlToJs(new haml.Tokeniser({
1677
+ template: string
1678
+ }), codeGenerator);
1679
+ return codeGenerator.generateJsFunction(result);
1680
+ },
1681
+ /*
1682
+ Compiles the haml in the passed in string
1683
+ Returns the javascript function source
1684
+
1685
+ This is mainly used for precompiling the haml templates so they can be packaged.
1686
+ */
1687
+
1688
+ compileHamlToJsString: function(string) {
1689
+ var result;
1690
+
1691
+ result = 'function (context) {\n';
1692
+ result += this._compileHamlToJs(new haml.Tokeniser({
1693
+ template: string
1694
+ }), new haml.JsCodeGenerator());
1695
+ return result += '}\n';
1696
+ },
1697
+ _compileHamlTemplate: function(templateId, codeGenerator) {
1698
+ var fn, result;
1699
+
1700
+ haml.cache || (haml.cache = {});
1701
+ if (haml.cache[templateId]) {
1702
+ return haml.cache[templateId];
1703
+ }
1704
+ result = this._compileHamlToJs(new haml.Tokeniser({
1705
+ templateId: templateId
1706
+ }), codeGenerator);
1707
+ fn = codeGenerator.generateJsFunction(result);
1708
+ haml.cache[templateId] = fn;
1709
+ return fn;
1710
+ },
1711
+ _compileHamlToJs: function(tokeniser, generator, options) {
1712
+ var e, indent;
1713
+
1714
+ if (options == null) {
1715
+ options = {};
1716
+ }
1717
+ generator.elementStack = [];
1718
+ generator.initOutput();
1719
+ tokeniser.getNextToken();
1720
+ while (!tokeniser.token.eof) {
1721
+ if (!tokeniser.token.eol) {
1722
+ try {
1723
+ indent = this._whitespace(tokeniser);
1724
+ generator.setIndent(indent);
1725
+ if (tokeniser.token.eol) {
1726
+ generator.outputBuffer.append(HamlRuntime.indentText(indent) + tokeniser.token.matched);
1727
+ tokeniser.getNextToken();
1728
+ } else if (tokeniser.token.doctype) {
1729
+ this._doctype(tokeniser, indent, generator);
1730
+ } else if (tokeniser.token.exclamation) {
1731
+ this._ignoredLine(tokeniser, indent, generator.elementStack, generator);
1732
+ } else if (tokeniser.token.equal || tokeniser.token.escapeHtml || tokeniser.token.unescapeHtml || tokeniser.token.tilde) {
1733
+ this._embeddedJs(tokeniser, indent, generator.elementStack, {
1734
+ innerWhitespace: true
1735
+ }, generator);
1736
+ } else if (tokeniser.token.minus) {
1737
+ this._jsLine(tokeniser, indent, generator.elementStack, generator);
1738
+ } else if (tokeniser.token.comment || tokeniser.token.slash) {
1739
+ this._commentLine(tokeniser, indent, generator.elementStack, generator);
1740
+ } else if (tokeniser.token.amp) {
1741
+ this._escapedLine(tokeniser, indent, generator.elementStack, generator);
1742
+ } else if (tokeniser.token.filter) {
1743
+ this._filter(tokeniser, indent, generator, options);
1744
+ } else {
1745
+ this._templateLine(tokeniser, generator.elementStack, indent, generator, options);
1746
+ }
1747
+ } catch (_error) {
1748
+ e = _error;
1749
+ this._handleError(options, {
1750
+ skipTo: true
1751
+ }, tokeniser, e);
1752
+ }
1753
+ } else {
1754
+ generator.outputBuffer.append(tokeniser.token.matched);
1755
+ tokeniser.getNextToken();
1756
+ }
1757
+ }
1758
+ this._closeElements(0, generator.elementStack, tokeniser, generator);
1759
+ return generator.closeAndReturnOutput();
1760
+ },
1761
+ _doctype: function(tokeniser, indent, generator) {
1762
+ var contents, params;
1763
+
1764
+ if (tokeniser.token.doctype) {
1765
+ generator.outputBuffer.append(HamlRuntime.indentText(indent));
1766
+ tokeniser.getNextToken();
1767
+ if (tokeniser.token.ws) {
1768
+ tokeniser.getNextToken();
1769
+ }
1770
+ contents = tokeniser.skipToEOLorEOF();
1771
+ if (contents && contents.length > 0) {
1772
+ params = contents.split(/\s+/);
1773
+ switch (params[0]) {
1774
+ case 'XML':
1775
+ if (params.length > 1) {
1776
+ generator.outputBuffer.append("<?xml version='1.0' encoding='" + params[1] + "' ?>");
1777
+ } else {
1778
+ generator.outputBuffer.append("<?xml version='1.0' encoding='utf-8' ?>");
1779
+ }
1780
+ break;
1781
+ case 'Strict':
1782
+ generator.outputBuffer.append('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">');
1783
+ break;
1784
+ case 'Frameset':
1785
+ generator.outputBuffer.append('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">');
1786
+ break;
1787
+ case '5':
1788
+ generator.outputBuffer.append('<!DOCTYPE html>');
1789
+ break;
1790
+ case '1.1':
1791
+ generator.outputBuffer.append('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">');
1792
+ break;
1793
+ case 'Basic':
1794
+ generator.outputBuffer.append('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">');
1795
+ break;
1796
+ case 'Mobile':
1797
+ generator.outputBuffer.append('<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">');
1798
+ break;
1799
+ case 'RDFa':
1800
+ generator.outputBuffer.append('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">');
1801
+ }
1802
+ } else {
1803
+ generator.outputBuffer.append('<!DOCTYPE html>');
1804
+ }
1805
+ generator.outputBuffer.append(this._newline(tokeniser));
1806
+ return tokeniser.getNextToken();
1807
+ }
1808
+ },
1809
+ _filter: function(tokeniser, indent, generator, options) {
1810
+ var filter, filterBlock, i, line;
1811
+
1812
+ if (tokeniser.token.filter) {
1813
+ filter = tokeniser.token.tokenString;
1814
+ if (!haml.filters[filter]) {
1815
+ this._handleError(options, {
1816
+ skipTo: indent
1817
+ }, tokeniser, tokeniser.parseError("Filter '" + filter + "' not registered. Filter functions need to be added to 'haml.filters'."));
1818
+ return;
1819
+ }
1820
+ tokeniser.skipToEOLorEOF();
1821
+ tokeniser.getNextToken();
1822
+ i = haml._whitespace(tokeniser);
1823
+ filterBlock = [];
1824
+ while (!tokeniser.token.eof && i > indent) {
1825
+ tokeniser.pushBackToken();
1826
+ line = tokeniser.skipToEOLorEOF();
1827
+ filterBlock.push(HamlRuntime.trim(line, 2 * indent));
1828
+ tokeniser.getNextToken();
1829
+ i = haml._whitespace(tokeniser);
1830
+ }
1831
+ haml.filters[filter](filterBlock, generator, indent, tokeniser.currentParsePoint());
1832
+ return tokeniser.pushBackToken();
1833
+ }
1834
+ },
1835
+ _commentLine: function(tokeniser, indent, elementStack, generator) {
1836
+ var contents, i;
1837
+
1838
+ if (tokeniser.token.comment) {
1839
+ tokeniser.skipToEOLorEOF();
1840
+ tokeniser.getNextToken();
1841
+ i = this._whitespace(tokeniser);
1842
+ while (!tokeniser.token.eof && i > indent) {
1843
+ tokeniser.skipToEOLorEOF();
1844
+ tokeniser.getNextToken();
1845
+ i = this._whitespace(tokeniser);
1846
+ }
1847
+ if (i > 0) {
1848
+ return tokeniser.pushBackToken();
1849
+ }
1850
+ } else if (tokeniser.token.slash) {
1851
+ haml._closeElements(indent, elementStack, tokeniser, generator);
1852
+ generator.outputBuffer.append(HamlRuntime.indentText(indent));
1853
+ generator.outputBuffer.append("<!--");
1854
+ tokeniser.getNextToken();
1855
+ contents = tokeniser.skipToEOLorEOF();
1856
+ if (contents && contents.length > 0) {
1857
+ generator.outputBuffer.append(contents);
1858
+ }
1859
+ if (contents && (_.str || _).startsWith(contents, '[') && contents.match(/\]\s*$/)) {
1860
+ elementStack[indent] = {
1861
+ htmlConditionalComment: true,
1862
+ eol: this._newline(tokeniser)
1863
+ };
1864
+ generator.outputBuffer.append(">");
1865
+ } else {
1866
+ elementStack[indent] = {
1867
+ htmlComment: true,
1868
+ eol: this._newline(tokeniser)
1869
+ };
1870
+ }
1871
+ if (haml._tagHasContents(indent, tokeniser)) {
1872
+ generator.outputBuffer.append("\n");
1873
+ }
1874
+ return tokeniser.getNextToken();
1875
+ }
1876
+ },
1877
+ _escapedLine: function(tokeniser, indent, elementStack, generator) {
1878
+ var contents;
1879
+
1880
+ if (tokeniser.token.amp) {
1881
+ haml._closeElements(indent, elementStack, tokeniser, generator);
1882
+ generator.outputBuffer.append(HamlRuntime.indentText(indent));
1883
+ tokeniser.getNextToken();
1884
+ contents = tokeniser.skipToEOLorEOF();
1885
+ if (contents && contents.length > 0) {
1886
+ generator.outputBuffer.append(haml.HamlRuntime.escapeHTML(contents));
1887
+ }
1888
+ generator.outputBuffer.append(this._newline(tokeniser));
1889
+ return tokeniser.getNextToken();
1890
+ }
1891
+ },
1892
+ _ignoredLine: function(tokeniser, indent, elementStack, generator) {
1893
+ var contents;
1894
+
1895
+ if (tokeniser.token.exclamation) {
1896
+ tokeniser.getNextToken();
1897
+ if (tokeniser.token.ws) {
1898
+ indent += haml._whitespace(tokeniser);
1899
+ }
1900
+ haml._closeElements(indent, elementStack, tokeniser, generator);
1901
+ contents = tokeniser.skipToEOLorEOF();
1902
+ return generator.outputBuffer.append(HamlRuntime.indentText(indent) + contents);
1903
+ }
1904
+ },
1905
+ _embeddedJs: function(tokeniser, indent, elementStack, tagOptions, generator) {
1906
+ var currentParsePoint, escapeHtml, expression, indentText, perserveWhitespace;
1907
+
1908
+ if (elementStack) {
1909
+ haml._closeElements(indent, elementStack, tokeniser, generator);
1910
+ }
1911
+ if (tokeniser.token.equal || tokeniser.token.escapeHtml || tokeniser.token.unescapeHtml || tokeniser.token.tilde) {
1912
+ escapeHtml = tokeniser.token.escapeHtml || tokeniser.token.equal;
1913
+ perserveWhitespace = tokeniser.token.tilde;
1914
+ currentParsePoint = tokeniser.currentParsePoint();
1915
+ tokeniser.getNextToken();
1916
+ expression = tokeniser.skipToEOLorEOF();
1917
+ indentText = HamlRuntime.indentText(indent);
1918
+ if (!tagOptions || tagOptions.innerWhitespace) {
1919
+ generator.outputBuffer.append(indentText);
1920
+ }
1921
+ generator.appendEmbeddedCode(indentText, expression, escapeHtml, perserveWhitespace, currentParsePoint);
1922
+ if (!tagOptions || tagOptions.innerWhitespace) {
1923
+ generator.outputBuffer.append(this._newline(tokeniser));
1924
+ if (tokeniser.token.eol) {
1925
+ return tokeniser.getNextToken();
1926
+ }
1927
+ }
1928
+ }
1929
+ },
1930
+ _jsLine: function(tokeniser, indent, elementStack, generator) {
1931
+ var line;
1932
+
1933
+ if (tokeniser.token.minus) {
1934
+ haml._closeElements(indent, elementStack, tokeniser, generator);
1935
+ tokeniser.getNextToken();
1936
+ line = tokeniser.skipToEOLorEOF();
1937
+ generator.setIndent(indent);
1938
+ generator.appendCodeLine(line, this._newline(tokeniser));
1939
+ if (tokeniser.token.eol) {
1940
+ tokeniser.getNextToken();
1941
+ }
1942
+ if (generator.lineMatchesStartFunctionBlock(line)) {
1943
+ return elementStack[indent] = {
1944
+ fnBlock: true
1945
+ };
1946
+ } else if (generator.lineMatchesStartBlock(line)) {
1947
+ return elementStack[indent] = {
1948
+ block: true
1949
+ };
1950
+ }
1951
+ }
1952
+ },
1953
+ _templateLine: function(tokeniser, elementStack, indent, generator, options) {
1954
+ var attrList, attributesHash, classes, contents, currentParsePoint, hasContents, id, identifier, indentText, lineHasElement, objectRef, shouldInterpolate, tagOptions;
1955
+
1956
+ if (!tokeniser.token.eol) {
1957
+ this._closeElements(indent, elementStack, tokeniser, generator);
1958
+ }
1959
+ identifier = this._element(tokeniser);
1960
+ id = this._idSelector(tokeniser);
1961
+ classes = this._classSelector(tokeniser);
1962
+ objectRef = this._objectReference(tokeniser);
1963
+ attrList = this._attributeList(tokeniser, options);
1964
+ currentParsePoint = tokeniser.currentParsePoint();
1965
+ attributesHash = this._attributeHash(tokeniser);
1966
+ tagOptions = {
1967
+ selfClosingTag: false,
1968
+ innerWhitespace: true,
1969
+ outerWhitespace: true
1970
+ };
1971
+ lineHasElement = this._lineHasElement(identifier, id, classes);
1972
+ if (tokeniser.token.slash) {
1973
+ tagOptions.selfClosingTag = true;
1974
+ tokeniser.getNextToken();
1975
+ }
1976
+ if (tokeniser.token.gt && lineHasElement) {
1977
+ tagOptions.outerWhitespace = false;
1978
+ tokeniser.getNextToken();
1979
+ }
1980
+ if (tokeniser.token.lt && lineHasElement) {
1981
+ tagOptions.innerWhitespace = false;
1982
+ tokeniser.getNextToken();
1983
+ }
1984
+ if (lineHasElement) {
1985
+ if (!tagOptions.selfClosingTag) {
1986
+ tagOptions.selfClosingTag = haml._isSelfClosingTag(identifier) && !haml._tagHasContents(indent, tokeniser);
1987
+ }
1988
+ this._openElement(currentParsePoint, indent, identifier, id, classes, objectRef, attrList, attributesHash, elementStack, tagOptions, generator);
1989
+ }
1990
+ hasContents = false;
1991
+ if (tokeniser.token.ws) {
1992
+ tokeniser.getNextToken();
1993
+ }
1994
+ if (tokeniser.token.equal || tokeniser.token.escapeHtml || tokeniser.token.unescapeHtml) {
1995
+ this._embeddedJs(tokeniser, indent + 1, null, tagOptions, generator);
1996
+ hasContents = true;
1997
+ } else {
1998
+ contents = '';
1999
+ shouldInterpolate = false;
2000
+ if (tokeniser.token.exclamation) {
2001
+ tokeniser.getNextToken();
2002
+ contents = tokeniser.skipToEOLorEOF();
2003
+ } else {
2004
+ contents = tokeniser.skipToEOLorEOF();
2005
+ if (contents.match(/^\\/)) {
2006
+ contents = contents.substring(1);
2007
+ }
2008
+ shouldInterpolate = true;
2009
+ }
2010
+ hasContents = contents.length > 0;
2011
+ if (hasContents) {
2012
+ if (tagOptions.innerWhitespace && lineHasElement || (!lineHasElement && haml._parentInnerWhitespace(elementStack, indent))) {
2013
+ indentText = HamlRuntime.indentText(identifier.length > 0 ? indent + 1 : indent);
2014
+ } else {
2015
+ indentText = '';
2016
+ contents = (_.str || _).trim(contents);
2017
+ }
2018
+ generator.appendTextContents(indentText + contents, shouldInterpolate, currentParsePoint);
2019
+ generator.outputBuffer.append(this._newline(tokeniser));
2020
+ }
2021
+ this._eolOrEof(tokeniser);
2022
+ }
2023
+ if (tagOptions.selfClosingTag && hasContents) {
2024
+ return this._handleError(options, null, tokeniser, haml.HamlRuntime.templateError(currentParsePoint.lineNumber, currentParsePoint.characterNumber, currentParsePoint.currentLine, "A self-closing tag can not have any contents"));
2025
+ }
2026
+ },
2027
+ _attributeHash: function(tokeniser) {
2028
+ var attr;
2029
+
2030
+ attr = '';
2031
+ if (tokeniser.token.attributeHash) {
2032
+ attr = tokeniser.token.tokenString;
2033
+ tokeniser.getNextToken();
2034
+ }
2035
+ return attr;
2036
+ },
2037
+ _objectReference: function(tokeniser) {
2038
+ var attr;
2039
+
2040
+ attr = '';
2041
+ if (tokeniser.token.objectReference) {
2042
+ attr = tokeniser.token.tokenString;
2043
+ tokeniser.getNextToken();
2044
+ }
2045
+ return attr;
2046
+ },
2047
+ _attributeList: function(tokeniser, options) {
2048
+ var attr, attrList;
2049
+
2050
+ attrList = {};
2051
+ if (tokeniser.token.openBracket) {
2052
+ tokeniser.getNextToken();
2053
+ while (!tokeniser.token.closeBracket) {
2054
+ attr = haml._attribute(tokeniser);
2055
+ if (attr) {
2056
+ attrList[attr.name] = attr.value;
2057
+ } else {
2058
+ if (tokeniser.token.ws || tokeniser.token.eol) {
2059
+ tokeniser.getNextToken();
2060
+ } else if (!tokeniser.token.closeBracket && !tokeniser.token.identifier) {
2061
+ this._handleError(options, null, tokeniser, tokeniser.parseError("Expecting either an attribute name to continue the attibutes or a closing " + "bracket to end"));
2062
+ return attrList;
2063
+ }
2064
+ }
2065
+ }
2066
+ tokeniser.getNextToken();
2067
+ }
2068
+ return attrList;
2069
+ },
2070
+ _attribute: function(tokeniser) {
2071
+ var attr, name;
2072
+
2073
+ attr = null;
2074
+ if (tokeniser.token.identifier) {
2075
+ name = tokeniser.token.tokenString;
2076
+ tokeniser.getNextToken();
2077
+ haml._whitespace(tokeniser);
2078
+ if (!tokeniser.token.equal) {
2079
+ throw tokeniser.parseError("Expected '=' after attribute name");
2080
+ }
2081
+ tokeniser.getNextToken();
2082
+ haml._whitespace(tokeniser);
2083
+ if (!tokeniser.token.string && !tokeniser.token.identifier) {
2084
+ throw tokeniser.parseError("Expected a quoted string or an identifier for the attribute value");
2085
+ }
2086
+ attr = {
2087
+ name: name,
2088
+ value: tokeniser.token.tokenString
2089
+ };
2090
+ tokeniser.getNextToken();
2091
+ }
2092
+ return attr;
2093
+ },
2094
+ _closeElement: function(indent, elementStack, tokeniser, generator) {
2095
+ var innerWhitespace, outerWhitespace;
2096
+
2097
+ if (elementStack[indent]) {
2098
+ generator.setIndent(indent);
2099
+ if (elementStack[indent].htmlComment) {
2100
+ generator.outputBuffer.append(HamlRuntime.indentText(indent) + '-->' + elementStack[indent].eol);
2101
+ } else if (elementStack[indent].htmlConditionalComment) {
2102
+ generator.outputBuffer.append(HamlRuntime.indentText(indent) + '<![endif]-->' + elementStack[indent].eol);
2103
+ } else if (elementStack[indent].block) {
2104
+ generator.closeOffCodeBlock(tokeniser);
2105
+ } else if (elementStack[indent].fnBlock) {
2106
+ generator.closeOffFunctionBlock(tokeniser);
2107
+ } else {
2108
+ innerWhitespace = !elementStack[indent].tagOptions || elementStack[indent].tagOptions.innerWhitespace;
2109
+ if (innerWhitespace) {
2110
+ generator.outputBuffer.append(HamlRuntime.indentText(indent));
2111
+ } else {
2112
+ generator.outputBuffer.trimWhitespace();
2113
+ }
2114
+ generator.outputBuffer.append('</' + elementStack[indent].tag + '>');
2115
+ outerWhitespace = !elementStack[indent].tagOptions || elementStack[indent].tagOptions.outerWhitespace;
2116
+ if (haml._parentInnerWhitespace(elementStack, indent) && outerWhitespace) {
2117
+ generator.outputBuffer.append('\n');
2118
+ }
2119
+ }
2120
+ elementStack[indent] = null;
2121
+ return generator.mark();
2122
+ }
2123
+ },
2124
+ _closeElements: function(indent, elementStack, tokeniser, generator) {
2125
+ var i, _results;
2126
+
2127
+ i = elementStack.length - 1;
2128
+ _results = [];
2129
+ while (i >= indent) {
2130
+ _results.push(this._closeElement(i--, elementStack, tokeniser, generator));
2131
+ }
2132
+ return _results;
2133
+ },
2134
+ _openElement: function(currentParsePoint, indent, identifier, id, classes, objectRef, attributeList, attributeHash, elementStack, tagOptions, generator) {
2135
+ var element, parentInnerWhitespace, tagOuterWhitespace;
2136
+
2137
+ element = identifier.length === 0 ? "div" : identifier;
2138
+ parentInnerWhitespace = this._parentInnerWhitespace(elementStack, indent);
2139
+ tagOuterWhitespace = !tagOptions || tagOptions.outerWhitespace;
2140
+ if (!tagOuterWhitespace) {
2141
+ generator.outputBuffer.trimWhitespace();
2142
+ }
2143
+ if (indent > 0 && parentInnerWhitespace && tagOuterWhitespace) {
2144
+ generator.outputBuffer.append(HamlRuntime.indentText(indent));
2145
+ }
2146
+ generator.outputBuffer.append('<' + element);
2147
+ if (attributeHash.length > 0 || objectRef.length > 0) {
2148
+ generator.generateCodeForDynamicAttributes(id, classes, attributeList, attributeHash, objectRef, currentParsePoint);
2149
+ } else {
2150
+ generator.outputBuffer.append(HamlRuntime.generateElementAttributes(null, id, classes, null, attributeList, null, currentParsePoint.lineNumber, currentParsePoint.characterNumber, currentParsePoint.currentLine));
2151
+ }
2152
+ if (tagOptions.selfClosingTag) {
2153
+ generator.outputBuffer.append("/>");
2154
+ if (tagOptions.outerWhitespace) {
2155
+ return generator.outputBuffer.append("\n");
2156
+ }
2157
+ } else {
2158
+ generator.outputBuffer.append(">");
2159
+ elementStack[indent] = {
2160
+ tag: element,
2161
+ tagOptions: tagOptions
2162
+ };
2163
+ if (tagOptions.innerWhitespace) {
2164
+ return generator.outputBuffer.append("\n");
2165
+ }
2166
+ }
2167
+ },
2168
+ _isSelfClosingTag: function(tag) {
2169
+ return tag === 'meta' || tag === 'img' || tag === 'link' || tag === 'script' || tag === 'br' || tag === 'hr';
2170
+ },
2171
+ _tagHasContents: function(indent, tokeniser) {
2172
+ var nextToken;
2173
+
2174
+ if (!tokeniser.isEolOrEof()) {
2175
+ return true;
2176
+ } else {
2177
+ nextToken = tokeniser.lookAhead(1);
2178
+ return nextToken.ws && nextToken.tokenString.length / 2 > indent;
2179
+ }
2180
+ },
2181
+ _parentInnerWhitespace: function(elementStack, indent) {
2182
+ return indent === 0 || (!elementStack[indent - 1] || !elementStack[indent - 1].tagOptions || elementStack[indent - 1].tagOptions.innerWhitespace);
2183
+ },
2184
+ _lineHasElement: function(identifier, id, classes) {
2185
+ return identifier.length > 0 || id.length > 0 || classes.length > 0;
2186
+ },
2187
+ hasValue: function(value) {
2188
+ return (value != null) && value !== false;
2189
+ },
2190
+ attrValue: function(attr, value) {
2191
+ if (attr === 'selected' || attr === 'checked' || attr === 'disabled') {
2192
+ return attr;
2193
+ } else {
2194
+ return value;
2195
+ }
2196
+ },
2197
+ _whitespace: function(tokeniser) {
2198
+ var indent;
2199
+
2200
+ indent = 0;
2201
+ if (tokeniser.token.ws) {
2202
+ indent = tokeniser.calculateIndent(tokeniser.token.tokenString);
2203
+ tokeniser.getNextToken();
2204
+ }
2205
+ return indent;
2206
+ },
2207
+ _element: function(tokeniser) {
2208
+ var identifier;
2209
+
2210
+ identifier = '';
2211
+ if (tokeniser.token.element) {
2212
+ identifier = tokeniser.token.tokenString;
2213
+ tokeniser.getNextToken();
2214
+ }
2215
+ return identifier;
2216
+ },
2217
+ _eolOrEof: function(tokeniser) {
2218
+ if (tokeniser.token.eol || tokeniser.token.continueLine) {
2219
+ return tokeniser.getNextToken();
2220
+ } else if (!tokeniser.token.eof) {
2221
+ throw tokeniser.parseError("Expected EOL or EOF");
2222
+ }
2223
+ },
2224
+ _idSelector: function(tokeniser) {
2225
+ var id;
2226
+
2227
+ id = '';
2228
+ if (tokeniser.token.idSelector) {
2229
+ id = tokeniser.token.tokenString;
2230
+ tokeniser.getNextToken();
2231
+ }
2232
+ return id;
2233
+ },
2234
+ _classSelector: function(tokeniser) {
2235
+ var classes;
2236
+
2237
+ classes = [];
2238
+ while (tokeniser.token.classSelector) {
2239
+ classes.push(tokeniser.token.tokenString);
2240
+ tokeniser.getNextToken();
2241
+ }
2242
+ return classes;
2243
+ },
2244
+ _newline: function(tokeniser) {
2245
+ if (tokeniser.token.eol) {
2246
+ return tokeniser.token.matched;
2247
+ } else if (tokeniser.token.continueLine) {
2248
+ return tokeniser.token.matched.substring(1);
2249
+ } else {
2250
+ return "\n";
2251
+ }
2252
+ },
2253
+ _handleError: function(options, action, tokeniser, error) {
2254
+ if (options != null ? options.tolerateFaults : void 0) {
2255
+ console.log(error);
2256
+ if (action != null ? action.skipTo : void 0) {
2257
+ return this._skipToNextLineWithIndent(tokeniser, action.skipTo);
2258
+ }
2259
+ } else {
2260
+ throw error;
2261
+ }
2262
+ },
2263
+ _skipToNextLineWithIndent: function(tokeniser, indent) {
2264
+ var lineIndent;
2265
+
2266
+ tokeniser.skipToEOLorEOF();
2267
+ tokeniser.getNextToken();
2268
+ lineIndent = this._whitespace(tokeniser);
2269
+ while (lineIndent > indent) {
2270
+ tokeniser.skipToEOLorEOF();
2271
+ tokeniser.getNextToken();
2272
+ lineIndent = this._whitespace(tokeniser);
2273
+ }
2274
+ return tokeniser.pushBackToken();
2275
+ }
2276
+ };
2277
+
2278
+ haml.Tokeniser = Tokeniser;
2279
+
2280
+ haml.Buffer = Buffer;
2281
+
2282
+ haml.JsCodeGenerator = JsCodeGenerator;
2283
+
2284
+ haml.ProductionJsCodeGenerator = ProductionJsCodeGenerator;
2285
+
2286
+ haml.CoffeeCodeGenerator = CoffeeCodeGenerator;
2287
+
2288
+ haml.HamlRuntime = HamlRuntime;
2289
+
2290
+ haml.filters = filters;
2291
+
2292
+ if ((typeof module !== "undefined" && module !== null ? module.exports : void 0) != null) {
2293
+ module.exports = haml;
2294
+ } else {
2295
+ root.haml = haml;
2296
+ }
2297
+
2298
+ }).call(this);
2299
+
2300
+ /*
2301
+ //@ sourceMappingURL=haml.map
2302
+ */