polyblock 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
+ */