unpoly-rails 0.20.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of unpoly-rails might be problematic. Click here for more details.

Files changed (339) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.ruby-version +2 -0
  4. data/.yardopts +1 -0
  5. data/CHANGELOG.md +577 -0
  6. data/Gemfile +8 -0
  7. data/Gemfile.lock +42 -0
  8. data/LICENSE +22 -0
  9. data/README.md +75 -0
  10. data/README_RAILS.md +116 -0
  11. data/Rakefile +45 -0
  12. data/bower.json +26 -0
  13. data/design/animation-ghosting.txt +72 -0
  14. data/design/design.txt +34 -0
  15. data/design/draft.html.erb +48 -0
  16. data/design/draft.rb +9 -0
  17. data/design/ghost-debugging.txt +118 -0
  18. data/design/homepage.txt +236 -0
  19. data/design/rename.txt +0 -0
  20. data/dist/unpoly-bootstrap3.css +5 -0
  21. data/dist/unpoly-bootstrap3.js +28 -0
  22. data/dist/unpoly-bootstrap3.min.css +1 -0
  23. data/dist/unpoly-bootstrap3.min.js +1 -0
  24. data/dist/unpoly.css +98 -0
  25. data/dist/unpoly.js +9041 -0
  26. data/dist/unpoly.min.css +1 -0
  27. data/dist/unpoly.min.js +3 -0
  28. data/lib/assets/javascripts/unpoly-bootstrap3.js.coffee +2 -0
  29. data/lib/assets/javascripts/unpoly-bootstrap3/form-ext.js.coffee +1 -0
  30. data/lib/assets/javascripts/unpoly-bootstrap3/layout-ext.js.coffee +5 -0
  31. data/lib/assets/javascripts/unpoly-bootstrap3/modal-ext.js.coffee +11 -0
  32. data/lib/assets/javascripts/unpoly-bootstrap3/navigation-ext.js.coffee +3 -0
  33. data/lib/assets/javascripts/unpoly.js.coffee +20 -0
  34. data/lib/assets/javascripts/unpoly/browser.js.coffee +252 -0
  35. data/lib/assets/javascripts/unpoly/bus.js.coffee +393 -0
  36. data/lib/assets/javascripts/unpoly/flow.js.coffee +809 -0
  37. data/lib/assets/javascripts/unpoly/form.js.coffee +864 -0
  38. data/lib/assets/javascripts/unpoly/history.js.coffee +204 -0
  39. data/lib/assets/javascripts/unpoly/layout.js.coffee +529 -0
  40. data/lib/assets/javascripts/unpoly/link.js.coffee +496 -0
  41. data/lib/assets/javascripts/unpoly/log.js.coffee +73 -0
  42. data/lib/assets/javascripts/unpoly/modal.js.coffee +509 -0
  43. data/lib/assets/javascripts/unpoly/module.js.coffee +4 -0
  44. data/lib/assets/javascripts/unpoly/motion.js.coffee +690 -0
  45. data/lib/assets/javascripts/unpoly/navigation.js.coffee +219 -0
  46. data/lib/assets/javascripts/unpoly/popup.js.coffee +409 -0
  47. data/lib/assets/javascripts/unpoly/proxy.js.coffee +521 -0
  48. data/lib/assets/javascripts/unpoly/rails.js.coffee +36 -0
  49. data/lib/assets/javascripts/unpoly/syntax.js.coffee +337 -0
  50. data/lib/assets/javascripts/unpoly/tooltip.js.coffee +183 -0
  51. data/lib/assets/javascripts/unpoly/util.js.coffee +1593 -0
  52. data/lib/assets/stylesheets/unpoly-bootstrap3.css.sass +1 -0
  53. data/lib/assets/stylesheets/unpoly-bootstrap3/modal-ext.css.sass +9 -0
  54. data/lib/assets/stylesheets/unpoly.css.sass +1 -0
  55. data/lib/assets/stylesheets/unpoly/close.css.sass +2 -0
  56. data/lib/assets/stylesheets/unpoly/error.css.sass +15 -0
  57. data/lib/assets/stylesheets/unpoly/link.css.sass +2 -0
  58. data/lib/assets/stylesheets/unpoly/modal.css.sass +69 -0
  59. data/lib/assets/stylesheets/unpoly/popup.css.sass +8 -0
  60. data/lib/assets/stylesheets/unpoly/tooltip.css.sass +42 -0
  61. data/lib/unpoly-rails.rb +7 -0
  62. data/lib/unpoly/rails/engine.rb +6 -0
  63. data/lib/unpoly/rails/inspector.rb +78 -0
  64. data/lib/unpoly/rails/inspector_accessor.rb +30 -0
  65. data/lib/unpoly/rails/request_echo_headers.rb +27 -0
  66. data/lib/unpoly/rails/request_method_cookie.rb +36 -0
  67. data/lib/unpoly/rails/version.rb +9 -0
  68. data/spec_app/.firefox-version +1 -0
  69. data/spec_app/.gitignore +17 -0
  70. data/spec_app/.rspec +2 -0
  71. data/spec_app/Bowerfile +3 -0
  72. data/spec_app/Gemfile +29 -0
  73. data/spec_app/Gemfile.lock +212 -0
  74. data/spec_app/README.rdoc +28 -0
  75. data/spec_app/Rakefile +6 -0
  76. data/spec_app/app/assets/images/.keep +0 -0
  77. data/spec_app/app/assets/javascripts/application.js +20 -0
  78. data/spec_app/app/assets/stylesheets/application.css +17 -0
  79. data/spec_app/app/assets/stylesheets/blocks/card.css.sass +11 -0
  80. data/spec_app/app/assets/stylesheets/blocks/controls.css.sass +7 -0
  81. data/spec_app/app/assets/stylesheets/blocks/menu.css.sass +13 -0
  82. data/spec_app/app/assets/stylesheets/blocks/panel.css.sass +8 -0
  83. data/spec_app/app/assets/stylesheets/jasmine_specs.css +5 -0
  84. data/spec_app/app/controllers/application_controller.rb +6 -0
  85. data/spec_app/app/controllers/concerns/.keep +0 -0
  86. data/spec_app/app/controllers/test_controller.rb +28 -0
  87. data/spec_app/app/helpers/application_helper.rb +2 -0
  88. data/spec_app/app/mailers/.keep +0 -0
  89. data/spec_app/app/models/concerns/.keep +0 -0
  90. data/spec_app/app/views/layouts/application.html.erb +12 -0
  91. data/spec_app/bin/bundle +3 -0
  92. data/spec_app/bin/rails +8 -0
  93. data/spec_app/bin/rake +8 -0
  94. data/spec_app/bin/setup +29 -0
  95. data/spec_app/bin/spring +18 -0
  96. data/spec_app/config.ru +4 -0
  97. data/spec_app/config/application.rb +26 -0
  98. data/spec_app/config/boot.rb +3 -0
  99. data/spec_app/config/database.yml +25 -0
  100. data/spec_app/config/environment.rb +5 -0
  101. data/spec_app/config/environments/development.rb +41 -0
  102. data/spec_app/config/environments/production.rb +79 -0
  103. data/spec_app/config/environments/test.rb +42 -0
  104. data/spec_app/config/initializers/assets.rb +11 -0
  105. data/spec_app/config/initializers/backtrace_silencers.rb +7 -0
  106. data/spec_app/config/initializers/bower_rails.rb +16 -0
  107. data/spec_app/config/initializers/cookies_serializer.rb +3 -0
  108. data/spec_app/config/initializers/filter_parameter_logging.rb +4 -0
  109. data/spec_app/config/initializers/inflections.rb +16 -0
  110. data/spec_app/config/initializers/mime_types.rb +4 -0
  111. data/spec_app/config/initializers/session_store.rb +3 -0
  112. data/spec_app/config/initializers/wrap_parameters.rb +14 -0
  113. data/spec_app/config/locales/en.yml +23 -0
  114. data/spec_app/config/routes.rb +8 -0
  115. data/spec_app/config/secrets.yml +22 -0
  116. data/spec_app/db/schema.rb +23 -0
  117. data/spec_app/db/seeds.rb +7 -0
  118. data/spec_app/lib/assets/.keep +0 -0
  119. data/spec_app/lib/tasks/.keep +0 -0
  120. data/spec_app/lib/tasks/cucumber.rake +65 -0
  121. data/spec_app/log/.keep +0 -0
  122. data/spec_app/public/404.html +67 -0
  123. data/spec_app/public/422.html +67 -0
  124. data/spec_app/public/500.html +66 -0
  125. data/spec_app/public/favicon.ico +0 -0
  126. data/spec_app/public/robots.txt +5 -0
  127. data/spec_app/script/cucumber +10 -0
  128. data/spec_app/spec/controllers/test_controller_spec.rb +76 -0
  129. data/spec_app/spec/javascripts/helpers/append_fixture.js.coffee +8 -0
  130. data/spec_app/spec/javascripts/helpers/browser_switches.js.coffee +9 -0
  131. data/spec_app/spec/javascripts/helpers/index.js.coffee +1 -0
  132. data/spec_app/spec/javascripts/helpers/knife.js.coffee +69 -0
  133. data/spec_app/spec/javascripts/helpers/last_request.js.coffee +22 -0
  134. data/spec_app/spec/javascripts/helpers/mock_ajax.js.coffee +5 -0
  135. data/spec_app/spec/javascripts/helpers/mock_clock.js.coffee +2 -0
  136. data/spec_app/spec/javascripts/helpers/remove_body_margin.js.coffee +5 -0
  137. data/spec_app/spec/javascripts/helpers/reset_knife.js.coffee +2 -0
  138. data/spec_app/spec/javascripts/helpers/reset_path.js.coffee +8 -0
  139. data/spec_app/spec/javascripts/helpers/reset_up.js.coffee +4 -0
  140. data/spec_app/spec/javascripts/helpers/restore_body_scroll.js.coffee +2 -0
  141. data/spec_app/spec/javascripts/helpers/set_timer.js.coffee +3 -0
  142. data/spec_app/spec/javascripts/helpers/to_be_around.js.coffee +5 -0
  143. data/spec_app/spec/javascripts/helpers/to_be_blank.js.coffee +5 -0
  144. data/spec_app/spec/javascripts/helpers/to_be_given.js.coffee +5 -0
  145. data/spec_app/spec/javascripts/helpers/to_be_missing.js.coffee +5 -0
  146. data/spec_app/spec/javascripts/helpers/to_be_present.js.coffee +5 -0
  147. data/spec_app/spec/javascripts/helpers/to_end_with.js.coffee +8 -0
  148. data/spec_app/spec/javascripts/helpers/to_equal_jquery.js.coffee +9 -0
  149. data/spec_app/spec/javascripts/helpers/to_have_request_method.js.coffee +8 -0
  150. data/spec_app/spec/javascripts/helpers/trigger.js.coffee +68 -0
  151. data/spec_app/spec/javascripts/support/jasmine.yml +51 -0
  152. data/spec_app/spec/javascripts/up/bus_spec.js.coffee +122 -0
  153. data/spec_app/spec/javascripts/up/flow_spec.js.coffee +755 -0
  154. data/spec_app/spec/javascripts/up/form_spec.js.coffee +471 -0
  155. data/spec_app/spec/javascripts/up/history_spec.js.coffee +96 -0
  156. data/spec_app/spec/javascripts/up/layout_spec.js.coffee +318 -0
  157. data/spec_app/spec/javascripts/up/link_spec.js.coffee +340 -0
  158. data/spec_app/spec/javascripts/up/modal_spec.js.coffee +265 -0
  159. data/spec_app/spec/javascripts/up/motion_spec.js.coffee +306 -0
  160. data/spec_app/spec/javascripts/up/navigation_spec.js.coffee +132 -0
  161. data/spec_app/spec/javascripts/up/popup_spec.js.coffee +220 -0
  162. data/spec_app/spec/javascripts/up/proxy_spec.js.coffee +371 -0
  163. data/spec_app/spec/javascripts/up/rails_spec.js.coffee +101 -0
  164. data/spec_app/spec/javascripts/up/syntax_spec.js.coffee +99 -0
  165. data/spec_app/spec/javascripts/up/tooltip_spec.js.coffee +60 -0
  166. data/spec_app/spec/javascripts/up/util_spec.js.coffee +325 -0
  167. data/spec_app/spec/spec_helper.rb +62 -0
  168. data/spec_app/test/controllers/.keep +0 -0
  169. data/spec_app/test/fixtures/.keep +0 -0
  170. data/spec_app/test/helpers/.keep +0 -0
  171. data/spec_app/test/integration/.keep +0 -0
  172. data/spec_app/test/mailers/.keep +0 -0
  173. data/spec_app/test/models/.keep +0 -0
  174. data/spec_app/test/test_helper.rb +10 -0
  175. data/spec_app/vendor/assets/.bowerrc +3 -0
  176. data/spec_app/vendor/assets/bower.json +8 -0
  177. data/spec_app/vendor/assets/bower_components/jasmine-ajax/.bower.json +43 -0
  178. data/spec_app/vendor/assets/bower_components/jasmine-ajax/MIT.LICENSE +20 -0
  179. data/spec_app/vendor/assets/bower_components/jasmine-ajax/README.markdown +289 -0
  180. data/spec_app/vendor/assets/bower_components/jasmine-ajax/bower.json +35 -0
  181. data/spec_app/vendor/assets/bower_components/jasmine-ajax/lib/mock-ajax.js +733 -0
  182. data/spec_app/vendor/assets/bower_components/jasmine-ajax/package.json +26 -0
  183. data/spec_app/vendor/assets/bower_components/jasmine-ajax/release_notes/2.0.2.md +50 -0
  184. data/spec_app/vendor/assets/bower_components/jasmine-ajax/release_notes/2.99.md +14 -0
  185. data/spec_app/vendor/assets/bower_components/jasmine-ajax/release_notes/3.0.md +28 -0
  186. data/spec_app/vendor/assets/bower_components/jasmine-ajax/release_notes/3.1.0.md +24 -0
  187. data/spec_app/vendor/assets/bower_components/jasmine-ajax/release_notes/3.1.1.md +23 -0
  188. data/spec_app/vendor/assets/bower_components/jasmine-ajax/release_notes/3.2.0.md +20 -0
  189. data/spec_app/vendor/assets/bower_components/jasmine-fixture/.bower.json +27 -0
  190. data/spec_app/vendor/assets/bower_components/jasmine-fixture/.gitignore +8 -0
  191. data/spec_app/vendor/assets/bower_components/jasmine-fixture/.npmignore +8 -0
  192. data/spec_app/vendor/assets/bower_components/jasmine-fixture/LICENSE.txt +24 -0
  193. data/spec_app/vendor/assets/bower_components/jasmine-fixture/README.md +118 -0
  194. data/spec_app/vendor/assets/bower_components/jasmine-fixture/bower.json +17 -0
  195. data/spec_app/vendor/assets/bower_components/jasmine-fixture/dist/jasmine-fixture.js +433 -0
  196. data/spec_app/vendor/assets/bower_components/jasmine-fixture/dist/jasmine-fixture.min.js +5 -0
  197. data/spec_app/vendor/assets/bower_components/jasmine-fixture/spec-e2e/basic-usage-spec.coffee +14 -0
  198. data/spec_app/vendor/assets/bower_components/jasmine-fixture/spec-e2e/helpers/invariants.coffee +17 -0
  199. data/spec_app/vendor/assets/bower_components/jasmine-fixture/spec-e2e/helpers/spec-within-a-spec.coffee +24 -0
  200. data/spec_app/vendor/assets/bower_components/jasmine-fixture/spec-e2e/helpers/tmp-files.coffee +8 -0
  201. data/spec_app/vendor/assets/bower_components/jasmine-fixture/spec-e2e/support/jasmine1-testem-config.json +11 -0
  202. data/spec_app/vendor/assets/bower_components/jasmine-fixture/spec-e2e/support/jasmine2-testem-config.json +11 -0
  203. data/spec_app/vendor/assets/bower_components/jasmine-fixture/vendor/js/jquery-1.11.0.js +10337 -0
  204. data/spec_app/vendor/assets/bower_components/jasmine-fixture/vendor/js/jquery-1.8.3.js +9472 -0
  205. data/spec_app/vendor/assets/bower_components/jasmine-fixture/vendor/js/jquery-2.1.0.js +9111 -0
  206. data/spec_app/vendor/assets/bower_components/jasmine-jquery/.bower.json +26 -0
  207. data/spec_app/vendor/assets/bower_components/jasmine-jquery/CONTRIBUTING.md +28 -0
  208. data/spec_app/vendor/assets/bower_components/jasmine-jquery/Gruntfile.js +49 -0
  209. data/spec_app/vendor/assets/bower_components/jasmine-jquery/LICENSE +20 -0
  210. data/spec_app/vendor/assets/bower_components/jasmine-jquery/README.md +367 -0
  211. data/spec_app/vendor/assets/bower_components/jasmine-jquery/bower.json +15 -0
  212. data/spec_app/vendor/assets/bower_components/jasmine-jquery/lib/jasmine-jquery.js +838 -0
  213. data/spec_app/vendor/assets/bower_components/jasmine-jquery/package.json +35 -0
  214. data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/fixture_with_checkbox_with_checked.html +6 -0
  215. data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/fixture_with_javascript.html +1 -0
  216. data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/fixture_with_javascript_block.html +1 -0
  217. data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/javascripts/jasmine_javascript_click.js +1 -0
  218. data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/javascripts/jasmine_javascript_hover.js +1 -0
  219. data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/json/jasmine_json_test.json +1 -0
  220. data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/real_non_mocked_fixture.html +1 -0
  221. data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/real_non_mocked_fixture_style.css +1 -0
  222. data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/suites/jasmine-jquery-spec.js +1842 -0
  223. data/spec_app/vendor/assets/bower_components/jasmine/.bower.json +50 -0
  224. data/spec_app/vendor/assets/bower_components/jasmine/CONTRIBUTING.md +130 -0
  225. data/spec_app/vendor/assets/bower_components/jasmine/GOALS_2.0.md +64 -0
  226. data/spec_app/vendor/assets/bower_components/jasmine/MANIFEST.in +5 -0
  227. data/spec_app/vendor/assets/bower_components/jasmine/MIT.LICENSE +20 -0
  228. data/spec_app/vendor/assets/bower_components/jasmine/README.md +73 -0
  229. data/spec_app/vendor/assets/bower_components/jasmine/RELEASE.md +73 -0
  230. data/spec_app/vendor/assets/bower_components/jasmine/bower.json +41 -0
  231. data/spec_app/vendor/assets/bower_components/jasmine/images/jasmine-horizontal.png +0 -0
  232. data/spec_app/vendor/assets/bower_components/jasmine/images/jasmine-horizontal.svg +102 -0
  233. data/spec_app/vendor/assets/bower_components/jasmine/images/jasmine_favicon.png +0 -0
  234. data/spec_app/vendor/assets/bower_components/jasmine/lib/console/console.js +190 -0
  235. data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core.js +37 -0
  236. data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/boot.js +143 -0
  237. data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/example/node_example/lib/jasmine_examples/Player.js +24 -0
  238. data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/example/node_example/lib/jasmine_examples/Song.js +9 -0
  239. data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/jasmine-html.js +446 -0
  240. data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/jasmine.css +58 -0
  241. data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/jasmine.js +3298 -0
  242. data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/json2.js +489 -0
  243. data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/node_boot.js +41 -0
  244. data/spec_app/vendor/assets/bower_components/jasmine/package.json +34 -0
  245. data/spec_app/vendor/assets/bower_components/jasmine/requirements.txt +1 -0
  246. data/spec_app/vendor/assets/bower_components/jquery/.bower.json +38 -0
  247. data/spec_app/vendor/assets/bower_components/jquery/MIT-LICENSE.txt +21 -0
  248. data/spec_app/vendor/assets/bower_components/jquery/bower.json +28 -0
  249. data/spec_app/vendor/assets/bower_components/jquery/dist/jquery.js +9210 -0
  250. data/spec_app/vendor/assets/bower_components/jquery/dist/jquery.min.js +5 -0
  251. data/spec_app/vendor/assets/bower_components/jquery/dist/jquery.min.map +1 -0
  252. data/spec_app/vendor/assets/bower_components/jquery/src/ajax.js +786 -0
  253. data/spec_app/vendor/assets/bower_components/jquery/src/ajax/jsonp.js +89 -0
  254. data/spec_app/vendor/assets/bower_components/jquery/src/ajax/load.js +75 -0
  255. data/spec_app/vendor/assets/bower_components/jquery/src/ajax/parseJSON.js +13 -0
  256. data/spec_app/vendor/assets/bower_components/jquery/src/ajax/parseXML.js +28 -0
  257. data/spec_app/vendor/assets/bower_components/jquery/src/ajax/script.js +64 -0
  258. data/spec_app/vendor/assets/bower_components/jquery/src/ajax/var/nonce.js +5 -0
  259. data/spec_app/vendor/assets/bower_components/jquery/src/ajax/var/rquery.js +3 -0
  260. data/spec_app/vendor/assets/bower_components/jquery/src/ajax/xhr.js +136 -0
  261. data/spec_app/vendor/assets/bower_components/jquery/src/attributes.js +11 -0
  262. data/spec_app/vendor/assets/bower_components/jquery/src/attributes/attr.js +141 -0
  263. data/spec_app/vendor/assets/bower_components/jquery/src/attributes/classes.js +158 -0
  264. data/spec_app/vendor/assets/bower_components/jquery/src/attributes/prop.js +94 -0
  265. data/spec_app/vendor/assets/bower_components/jquery/src/attributes/support.js +35 -0
  266. data/spec_app/vendor/assets/bower_components/jquery/src/attributes/val.js +161 -0
  267. data/spec_app/vendor/assets/bower_components/jquery/src/callbacks.js +205 -0
  268. data/spec_app/vendor/assets/bower_components/jquery/src/core.js +502 -0
  269. data/spec_app/vendor/assets/bower_components/jquery/src/core/access.js +60 -0
  270. data/spec_app/vendor/assets/bower_components/jquery/src/core/init.js +123 -0
  271. data/spec_app/vendor/assets/bower_components/jquery/src/core/parseHTML.js +39 -0
  272. data/spec_app/vendor/assets/bower_components/jquery/src/core/ready.js +97 -0
  273. data/spec_app/vendor/assets/bower_components/jquery/src/core/var/rsingleTag.js +4 -0
  274. data/spec_app/vendor/assets/bower_components/jquery/src/css.js +450 -0
  275. data/spec_app/vendor/assets/bower_components/jquery/src/css/addGetHookIf.js +22 -0
  276. data/spec_app/vendor/assets/bower_components/jquery/src/css/curCSS.js +57 -0
  277. data/spec_app/vendor/assets/bower_components/jquery/src/css/defaultDisplay.js +70 -0
  278. data/spec_app/vendor/assets/bower_components/jquery/src/css/hiddenVisibleSelectors.js +15 -0
  279. data/spec_app/vendor/assets/bower_components/jquery/src/css/support.js +96 -0
  280. data/spec_app/vendor/assets/bower_components/jquery/src/css/swap.js +28 -0
  281. data/spec_app/vendor/assets/bower_components/jquery/src/css/var/cssExpand.js +3 -0
  282. data/spec_app/vendor/assets/bower_components/jquery/src/css/var/getStyles.js +12 -0
  283. data/spec_app/vendor/assets/bower_components/jquery/src/css/var/isHidden.js +13 -0
  284. data/spec_app/vendor/assets/bower_components/jquery/src/css/var/rmargin.js +3 -0
  285. data/spec_app/vendor/assets/bower_components/jquery/src/css/var/rnumnonpx.js +5 -0
  286. data/spec_app/vendor/assets/bower_components/jquery/src/data.js +178 -0
  287. data/spec_app/vendor/assets/bower_components/jquery/src/data/Data.js +181 -0
  288. data/spec_app/vendor/assets/bower_components/jquery/src/data/accepts.js +20 -0
  289. data/spec_app/vendor/assets/bower_components/jquery/src/data/var/data_priv.js +5 -0
  290. data/spec_app/vendor/assets/bower_components/jquery/src/data/var/data_user.js +5 -0
  291. data/spec_app/vendor/assets/bower_components/jquery/src/deferred.js +149 -0
  292. data/spec_app/vendor/assets/bower_components/jquery/src/deprecated.js +13 -0
  293. data/spec_app/vendor/assets/bower_components/jquery/src/dimensions.js +50 -0
  294. data/spec_app/vendor/assets/bower_components/jquery/src/effects.js +648 -0
  295. data/spec_app/vendor/assets/bower_components/jquery/src/effects/Tween.js +114 -0
  296. data/spec_app/vendor/assets/bower_components/jquery/src/effects/animatedSelector.js +13 -0
  297. data/spec_app/vendor/assets/bower_components/jquery/src/event.js +868 -0
  298. data/spec_app/vendor/assets/bower_components/jquery/src/event/ajax.js +13 -0
  299. data/spec_app/vendor/assets/bower_components/jquery/src/event/alias.js +39 -0
  300. data/spec_app/vendor/assets/bower_components/jquery/src/event/support.js +9 -0
  301. data/spec_app/vendor/assets/bower_components/jquery/src/exports/amd.js +24 -0
  302. data/spec_app/vendor/assets/bower_components/jquery/src/exports/global.js +32 -0
  303. data/spec_app/vendor/assets/bower_components/jquery/src/intro.js +44 -0
  304. data/spec_app/vendor/assets/bower_components/jquery/src/jquery.js +37 -0
  305. data/spec_app/vendor/assets/bower_components/jquery/src/manipulation.js +580 -0
  306. data/spec_app/vendor/assets/bower_components/jquery/src/manipulation/_evalUrl.js +18 -0
  307. data/spec_app/vendor/assets/bower_components/jquery/src/manipulation/support.js +32 -0
  308. data/spec_app/vendor/assets/bower_components/jquery/src/manipulation/var/rcheckableType.js +3 -0
  309. data/spec_app/vendor/assets/bower_components/jquery/src/offset.js +207 -0
  310. data/spec_app/vendor/assets/bower_components/jquery/src/outro.js +1 -0
  311. data/spec_app/vendor/assets/bower_components/jquery/src/queue.js +142 -0
  312. data/spec_app/vendor/assets/bower_components/jquery/src/queue/delay.js +22 -0
  313. data/spec_app/vendor/assets/bower_components/jquery/src/selector-native.js +172 -0
  314. data/spec_app/vendor/assets/bower_components/jquery/src/selector-sizzle.js +14 -0
  315. data/spec_app/vendor/assets/bower_components/jquery/src/selector.js +1 -0
  316. data/spec_app/vendor/assets/bower_components/jquery/src/serialize.js +111 -0
  317. data/spec_app/vendor/assets/bower_components/jquery/src/sizzle/dist/sizzle.js +2067 -0
  318. data/spec_app/vendor/assets/bower_components/jquery/src/sizzle/dist/sizzle.min.js +3 -0
  319. data/spec_app/vendor/assets/bower_components/jquery/src/sizzle/dist/sizzle.min.map +1 -0
  320. data/spec_app/vendor/assets/bower_components/jquery/src/traversing.js +199 -0
  321. data/spec_app/vendor/assets/bower_components/jquery/src/traversing/findFilter.js +100 -0
  322. data/spec_app/vendor/assets/bower_components/jquery/src/traversing/var/rneedsContext.js +6 -0
  323. data/spec_app/vendor/assets/bower_components/jquery/src/var/arr.js +3 -0
  324. data/spec_app/vendor/assets/bower_components/jquery/src/var/class2type.js +4 -0
  325. data/spec_app/vendor/assets/bower_components/jquery/src/var/concat.js +5 -0
  326. data/spec_app/vendor/assets/bower_components/jquery/src/var/hasOwn.js +5 -0
  327. data/spec_app/vendor/assets/bower_components/jquery/src/var/indexOf.js +5 -0
  328. data/spec_app/vendor/assets/bower_components/jquery/src/var/pnum.js +3 -0
  329. data/spec_app/vendor/assets/bower_components/jquery/src/var/push.js +5 -0
  330. data/spec_app/vendor/assets/bower_components/jquery/src/var/rnotwhite.js +3 -0
  331. data/spec_app/vendor/assets/bower_components/jquery/src/var/slice.js +5 -0
  332. data/spec_app/vendor/assets/bower_components/jquery/src/var/strundefined.js +3 -0
  333. data/spec_app/vendor/assets/bower_components/jquery/src/var/support.js +4 -0
  334. data/spec_app/vendor/assets/bower_components/jquery/src/var/toString.js +5 -0
  335. data/spec_app/vendor/assets/bower_components/jquery/src/wrap.js +79 -0
  336. data/spec_app/vendor/assets/javascripts/.keep +0 -0
  337. data/spec_app/vendor/assets/stylesheets/.keep +0 -0
  338. data/unpoly-rails.gemspec +24 -0
  339. metadata +423 -0
@@ -0,0 +1,864 @@
1
+ ###*
2
+ Forms
3
+ =====
4
+
5
+ Unpoly comes with functionality to [submit](/form-up-target) and [validate](/up-validate)
6
+ forms without leaving the current page. This means you can replace page fragments,
7
+ open dialogs with sub-forms, etc. all without losing form state.
8
+
9
+ @class up.form
10
+ ###
11
+ up.form = (($) ->
12
+
13
+ u = up.util
14
+
15
+ ###*
16
+ Sets default options for form submission and validation.
17
+
18
+ @property up.form.config
19
+ @param {Number} [config.observeDelay=0]
20
+ The number of miliseconds to wait before [`up.observe`](/up.observe) runs the callback
21
+ after the input value changes. Use this to limit how often the callback
22
+ will be invoked for a fast typist.
23
+ @param {Array} [config.validateTargets=['[up-fieldset]:has(&)', 'fieldset:has(&)', 'label:has(&)', 'form:has(&)']]
24
+ An array of CSS selectors that are searched around a form field
25
+ that wants to [validate](/up.validate). The first matching selector
26
+ will be updated with the validation messages from the server.
27
+
28
+ By default this looks for a `<fieldset>`, `<label>` or `<form>`
29
+ around the validating input field, or any element with an
30
+ `up-fieldset` attribute.
31
+ @param {String} [config.fields]
32
+ An array of CSS selectors that represent form fields, such as `input` or `select`.
33
+ @stable
34
+ ###
35
+ config = u.config
36
+ validateTargets: ['[up-fieldset]:has(&)', 'fieldset:has(&)', 'label:has(&)', 'form:has(&)']
37
+ fields: [':input']
38
+ observeDelay: 0
39
+
40
+ reset = ->
41
+ config.reset()
42
+
43
+ ###*
44
+ Submits a form via AJAX and updates a page fragment with the response.
45
+
46
+ up.submit('form.new-user', { target: '.main' })
47
+
48
+ Instead of loading a new page, the form is submitted via AJAX.
49
+ The response is parsed for a CSS selector and the matching elements will
50
+ replace corresponding elements on the current page.
51
+
52
+ The UJS variant of this is the [`form[up-target]`](/form-up-target) selector.
53
+ See the documentation for [`form[up-target]`](/form-up-target) for more
54
+ information on how AJAX form submissions work in Unpoly.
55
+
56
+ @function up.submit
57
+ @param {Element|jQuery|String} formOrSelector
58
+ A reference or selector for the form to submit.
59
+ If the argument points to an element that is not a form,
60
+ Unpoly will search its ancestors for the closest form.
61
+ @param {String} [options.url]
62
+ The URL where to submit the form.
63
+ Defaults to the form's `action` attribute, or to the current URL of the browser window.
64
+ @param {String} [options.method]
65
+ The HTTP method used for the form submission.
66
+ Defaults to the form's `up-method`, `data-method` or `method` attribute, or to `'post'`
67
+ if none of these attributes are given.
68
+ @param {String} [options.target]
69
+ The selector to update when the form submission succeeds (server responds with status 200).
70
+ Defaults to the form's `up-target` attribute, or to `'body'`.
71
+ @param {String} [options.failTarget]
72
+ The selector to update when the form submission fails (server responds with non-200 status).
73
+ Defaults to the form's `up-fail-target` attribute, or to an auto-generated
74
+ selector that matches the form itself.
75
+ @param {Boolean|String} [options.history=true]
76
+ Successful form submissions will add a history entry and change the browser's
77
+ location bar if the form either uses the `GET` method or the response redirected
78
+ to another page (this requires the `unpoly-rails` gem).
79
+ If want to prevent history changes in any case, set this to `false`.
80
+ If you pass a `String`, it is used as the URL for the browser history.
81
+ @param {String} [options.transition='none']
82
+ The transition to use when a successful form submission updates the `options.target` selector.
83
+ Defaults to the form's `up-transition` attribute, or to `'none'`.
84
+ @param {String} [options.failTransition='none']
85
+ The transition to use when a failed form submission updates the `options.failTarget` selector.
86
+ Defaults to the form's `up-fail-transition` attribute, or to `options.transition`, or to `'none'`.
87
+ @param {Number} [options.duration]
88
+ The duration of the transition. See [`up.morph`](/up.morph).
89
+ @param {Number} [options.delay]
90
+ The delay before the transition starts. See [`up.morph`](/up.morph).
91
+ @param {String} [options.easing]
92
+ The timing function that controls the transition's acceleration. [`up.morph`](/up.morph).
93
+ @param {Element|jQuery|String} [options.reveal]
94
+ Whether to reveal the target element within its viewport.
95
+ @param {Boolean} [options.restoreScroll]
96
+ If set to `true`, this will attempt to [`restore scroll positions`](/up.restoreScroll)
97
+ previously seen on the destination URL.
98
+ @param {Boolean} [options.cache]
99
+ Whether to force the use of a cached response (`true`)
100
+ or never use the cache (`false`)
101
+ or make an educated guess (`undefined`).
102
+
103
+ By default only responses to `GET` requests are cached
104
+ for a few minutes.
105
+ @param {Object} [options.headers={}]
106
+ An object of additional header key/value pairs to send along
107
+ with the request.
108
+ @return {Promise}
109
+ A promise for the successful form submission.
110
+ @stable
111
+ ###
112
+ submit = (formOrSelector, options) ->
113
+
114
+ $form = $(formOrSelector).closest('form')
115
+
116
+ options = u.options(options)
117
+ target = u.option(options.target, $form.attr('up-target'), 'body')
118
+ url = u.option(options.url, $form.attr('action'), up.browser.url())
119
+ options.failTarget = u.option(options.failTarget, $form.attr('up-fail-target')) || u.selectorForElement($form)
120
+ options.history = u.option(options.history, u.castedAttr($form, 'up-history'), true)
121
+ options.transition = u.option(options.transition, u.castedAttr($form, 'up-transition'), 'none')
122
+ options.failTransition = u.option(options.failTransition, u.castedAttr($form, 'up-fail-transition'), 'none')
123
+ options.method = u.option(options.method, $form.attr('up-method'), $form.attr('data-method'), $form.attr('method'), 'post').toUpperCase()
124
+ options.headers = u.option(options.headers, {})
125
+ options.reveal = u.option(options.reveal, u.castedAttr($form, 'up-reveal'), true)
126
+ options.cache = u.option(options.cache, u.castedAttr($form, 'up-cache'))
127
+ options.restoreScroll = u.option(options.restoreScroll, u.castedAttr($form, 'up-restore-scroll'))
128
+ options.origin = u.option(options.origin, $form)
129
+ options.data = $form.serializeArray()
130
+ options = u.merge(options, up.motion.animateOptions(options, $form))
131
+
132
+ hasFileInputs = $form.find('input[type=file]').length
133
+
134
+ if options.validate
135
+ options.headers ||= {}
136
+ options.headers['X-Up-Validate'] = options.validate
137
+ # Since we cannot (yet) submit file inputs via AJAX, we cannot
138
+ # offer inline validation for such forms.
139
+ if hasFileInputs
140
+ return u.unresolvablePromise()
141
+
142
+ $form.addClass('up-active')
143
+
144
+ if hasFileInputs || (!up.browser.canPushState() && options.history != false)
145
+ $form.get(0).submit()
146
+ return u.unresolvablePromise()
147
+
148
+ promise = up.replace(target, url, options)
149
+ promise.always -> $form.removeClass('up-active')
150
+ return promise
151
+
152
+ ###*
153
+ Observes a field or form and runs a callback when a value changes.
154
+
155
+ This is useful for observing text fields while the user is typing.
156
+
157
+ The UJS variant of this is the [`up-observe`](/up-observe) attribute.
158
+
159
+ \#\#\#\# Example
160
+
161
+ The following would submit the form whenever the
162
+ text field value changes:
163
+
164
+ up.observe('input[name=query]', function(value, $input) {
165
+ up.submit($input)
166
+ });
167
+
168
+ \#\#\#\# Preventing concurrency
169
+
170
+ Firing asynchronous code after a form field can cause
171
+ [concurrency issues](https://makandracards.com/makandra/961-concurrency-issues-with-find-as-you-type-boxes).
172
+
173
+ To mitigate this, `up.observe` will try to never run a callback
174
+ before the previous callback has completed.
175
+ To take advantage of this, your callback code must return a promise.
176
+ Note that all asynchronous Unpoly functions return promises.
177
+
178
+ \#\#\#\# Throttling
179
+
180
+ If you are concerned about fast typists causing too much
181
+ load on your server, you can use a `delay` option to wait
182
+ a few miliseconds before executing the callback:
183
+
184
+ up.observe('input', { delay: 100 }, function(value, $input) {
185
+ up.submit($input)
186
+ });
187
+
188
+ @function up.observe
189
+ @param {Element|jQuery|String} fieldOrSelector
190
+ @param {Number} [options.delay=up.form.config.observeDelay]
191
+ The number of miliseconds to wait before executing the callback
192
+ after the input value changes. Use this to limit how often the callback
193
+ will be invoked for a fast typist.
194
+ @param {Function(value, $field)|String} onChange
195
+ The callback to execute when the field's value changes.
196
+ If given as a function, it must take two arguments (`value`, `$field`).
197
+ If given as a string, it will be evaled as Javascript code in a context where
198
+ (`value`, `$field`) are set.
199
+ @return {Function}
200
+ A destructor function that removes the observe watch when called.
201
+ @stable
202
+ ###
203
+ observe = (selectorOrElement, args...) ->
204
+
205
+ options = {}
206
+ callbackArg = undefined
207
+ if args.length == 1
208
+ callbackArg = args[0]
209
+ if args.length > 1
210
+ options = u.options(args[0])
211
+ callbackArg = args[1]
212
+
213
+ $element = $(selectorOrElement)
214
+ options = u.options(options)
215
+ delay = u.option($element.attr('up-delay'), options.delay, config.observeDelay)
216
+ delay = parseInt(delay)
217
+
218
+ callback = null
219
+
220
+ if u.isGiven(options.change)
221
+ u.error('up.observe now takes the change callback as the last argument')
222
+
223
+ rawCallback = u.option(u.presentAttr($element, 'op-observe'), callbackArg)
224
+ if u.isString(rawCallback)
225
+ callback = (value, $field) -> eval(rawCallback)
226
+ else
227
+ callback = rawCallback or u.error('up.observe: No change callback given')
228
+
229
+ if $element.is('form')
230
+ return observeForm($element, options, callback)
231
+
232
+ knownValue = null
233
+ callbackTimer = null
234
+ callbackPromise = u.resolvedPromise()
235
+
236
+ # This holds the next callback function, curried with `value` and `$field`.
237
+ # Since we're waiting for callback promises to resolve before running
238
+ # another callback, this might be overwritten while we're waiting for a
239
+ # previous callback to finish.
240
+ nextCallback = null
241
+
242
+ runNextCallback = ->
243
+ if nextCallback
244
+ returnValue = nextCallback()
245
+ nextCallback = null
246
+ returnValue
247
+
248
+ check = ->
249
+ value = $element.val()
250
+ # don't run the callback for the check during initialization
251
+ skipCallback = u.isNull(knownValue)
252
+ if knownValue != value
253
+ knownValue = value
254
+ unless skipCallback
255
+ clearTimer()
256
+ nextCallback = -> callback.apply($element.get(0), [value, $element])
257
+ runAndChain = ->
258
+ # Only run the callback once the previous callback's
259
+ # promise resolves.
260
+ callbackPromise.then ->
261
+ returnValue = runNextCallback()
262
+ # If the callback returns a promise, we will remember it
263
+ # and chain additional callback invocations to it.
264
+ if u.isPromise(returnValue)
265
+ callbackPromise = returnValue
266
+ else
267
+ callbackPromise = u.resolvedPromise()
268
+ if delay == 0
269
+ runAndChain()
270
+ else
271
+ setTimeout(runAndChain, delay)
272
+
273
+ clearTimer = ->
274
+ clearTimeout(callbackTimer)
275
+
276
+ changeEvents = if up.browser.canInputEvent()
277
+ # Actually we only need `input`, but we want to notice
278
+ # if another script manually triggers `change` on the element.
279
+ 'input change'
280
+ else
281
+ # Actually we won't ever get `input` from the user in this browser,
282
+ # but we want to notice if another script manually triggers `input`
283
+ # on the element.
284
+ 'input change keypress paste cut click propertychange'
285
+ $element.on(changeEvents, check)
286
+
287
+ check()
288
+
289
+ # return destructor
290
+ return ->
291
+ $element.off(changeEvents, check)
292
+ clearTimer()
293
+
294
+ ###*
295
+ @function observeForm
296
+ @internal
297
+ ###
298
+ observeForm = ($form, options, callback) ->
299
+ $fields = u.multiSelector(config.fields).find($form)
300
+ destructors = u.map $fields, ($field) ->
301
+ observe($field, callback)
302
+ ->
303
+ destructor() for destructor in destructors
304
+
305
+ ###*
306
+ [Observes](/up.observe) a field or form and submits the form when a value changes.
307
+
308
+ The changed form field will be assigned a CSS class [`up-active`](/up-active)
309
+ while the autosubmitted form is processing.
310
+
311
+ The UJS variant of this is the [`up-autosubmit`](/up-autosubmit) attribute.
312
+
313
+ @function up.autosubmit
314
+ @param {String|Element|jQuery} selectorOrElement
315
+ The form field to observe.
316
+ @param {Object} [options]
317
+ See options for [`up.observe`](/up.observe)
318
+ @return {Function}
319
+ A destructor function that removes the observe watch when called.
320
+ @stable
321
+ ###
322
+ autosubmit = (selectorOrElement, options) ->
323
+ observe(selectorOrElement, options, (value, $field) ->
324
+ $form = $field.closest('form')
325
+ $field.addClass('up-active')
326
+ submit($form).always -> $field.removeClass('up-active')
327
+ )
328
+
329
+ resolveValidateTarget = ($field, options) ->
330
+ target = u.option(options.target, $field.attr('up-validate'))
331
+ if u.isBlank(target)
332
+ target ||= u.detect(config.validateTargets, (defaultTarget) ->
333
+ resolvedDefault = up.flow.resolveSelector(defaultTarget, options.origin)
334
+ $field.closest(resolvedDefault).length
335
+ )
336
+ if u.isBlank(target)
337
+ u.error('Could not find default validation target for %o (tried ancestors %o)', $field.get(0), config.validateTargets)
338
+ unless u.isString(target)
339
+ target = u.selectorForElement(target)
340
+ target
341
+
342
+ ###*
343
+ Performs a server-side validation of a form and update the form
344
+ with validation messages.
345
+
346
+ `up.validate` submits the given field's form with an additional `X-Up-Validate`
347
+ HTTP header. Upon seeing this header, the server is expected to validate (but not save)
348
+ the form submission and render a new copy of the form with validation errors.
349
+
350
+ The UJS variant of this is the [`[up-validate]`](/up-validate) selector.
351
+ See the documentation for [`[up-validate]`](/up-validate) for more information
352
+ on how server-side validation works in Unpoly.
353
+
354
+ \#\#\#\# Example
355
+
356
+ up.validate('input[name=email]', { target: '.email-errors' })
357
+
358
+ @function up.validate
359
+ @param {String|Element|jQuery} fieldOrSelector
360
+ @param {String|Element|jQuery} [options.target]
361
+ @return {Promise}
362
+ A promise that is resolved when the server-side
363
+ validation is received and the form was updated.
364
+ @stable
365
+ ###
366
+ validate = (fieldOrSelector, options) ->
367
+ $field = $(fieldOrSelector)
368
+ options = u.options(options)
369
+ options.origin = $field
370
+ options.target = resolveValidateTarget($field, options)
371
+ options.failTarget = options.target
372
+ options.history = false
373
+ options.headers = u.option(options.headers, {})
374
+ # Make sure the X-Up-Validate header is present, so the server-side
375
+ # knows that it should not persist the form submission
376
+ options.validate = ($field.attr('name') || '__none__')
377
+ options = u.merge(options, up.motion.animateOptions(options, $field))
378
+ $form = $field.closest('form')
379
+ promise = up.submit($form, options)
380
+ promise
381
+
382
+ currentValuesForToggle = ($field) ->
383
+ values = undefined
384
+ if $field.is('input[type=checkbox]')
385
+ if $field.is(':checked')
386
+ values = [':checked', ':present', $field.val()]
387
+ else
388
+ values = [':unchecked', ':blank']
389
+ else if $field.is('input[type=radio]')
390
+ $checkedButton = $field.closest('form, body').find("input[type='radio'][name='#{$field.attr('name')}']:checked")
391
+ if $checkedButton.length
392
+ values = [':checked', ':present', $checkedButton.val()]
393
+ else
394
+ values = [':unchecked', ':blank']
395
+ else
396
+ value = $field.val()
397
+ if u.isPresent(value)
398
+ values = [':present', value]
399
+ else
400
+ values = [':blank']
401
+ values
402
+
403
+ currentValuesForToggle = ($field) ->
404
+ if $field.is('input[type=checkbox]')
405
+ if $field.is(':checked')
406
+ value = $field.val()
407
+ meta = ':checked'
408
+ else
409
+ meta = ':unchecked'
410
+ else if $field.is('input[type=radio]')
411
+ $checkedButton = $field.closest('form, body').find("input[type='radio'][name='#{$field.attr('name')}']:checked")
412
+ if $checkedButton.length
413
+ meta = ':checked'
414
+ value = $checkedButton.val()
415
+ else
416
+ meta = ':unchecked'
417
+ else
418
+ value = $field.val()
419
+ values = []
420
+ if u.isPresent(value)
421
+ values.push(value)
422
+ values.push(':present')
423
+ else
424
+ values.push(':blank')
425
+ if u.isPresent(meta)
426
+ values.push(meta)
427
+ values
428
+
429
+ ###*
430
+ Shows or hides a target selector depending on the value.
431
+
432
+ See [`[up-toggle]`](/up-toggle) for more documentation and examples.
433
+
434
+ This function does not currently have a very useful API outside
435
+ of our use for `up-toggle`'s UJS behavior, that's why it's currently
436
+ still marked `@internal`.
437
+
438
+ @function up.form.toggle
439
+ @param {String|Element|jQuery} fieldOrSelector
440
+ @param {String} [options.target]
441
+ The target selectors to toggle.
442
+ Defaults to an `up-toggle` attribute on the given field.
443
+ @internal
444
+ ###
445
+ toggleTargets = (fieldOrSelector, options) ->
446
+ $field = $(fieldOrSelector)
447
+ options = u.options(options)
448
+ targets = u.option(options.target, $field.attr('up-toggle'))
449
+ u.isPresent(targets) or u.error("No toggle target given for %o", $field.get(0))
450
+ fieldValues = currentValuesForToggle($field)
451
+ $(targets).each ->
452
+ $target = $(this)
453
+ if hideValues = $target.attr('up-hide-for')
454
+ hideValues = hideValues.split(' ')
455
+ show = u.intersect(fieldValues, hideValues).length == 0
456
+ else
457
+ if showValues = $target.attr('up-show-for')
458
+ showValues = showValues.split(' ')
459
+ else
460
+ # If the target has neither up-show-for or up-hide-for attributes,
461
+ # assume the user wants the target to be visible whenever anything
462
+ # is checked or entered.
463
+ showValues = [':present', ':checked']
464
+ show = u.intersect(fieldValues, showValues).length > 0
465
+ $target.toggle(show)
466
+
467
+ ###*
468
+ Forms with an `up-target` attribute are [submitted via AJAX](/up.submit)
469
+ instead of triggering a full page reload.
470
+
471
+ <form method="post" action="/users" up-target=".main">
472
+ ...
473
+ </form>
474
+
475
+ The server response is searched for the selector given in `up-target`.
476
+ The selector content is then [replaced](/up.replace) in the current page.
477
+
478
+ The programmatic variant of this is the [`up.submit`](/up.submit) function.
479
+
480
+ \#\#\#\# Failed submission
481
+
482
+ When the server was unable to save the form due to invalid data,
483
+ it will usually re-render an updated copy of the form with
484
+ validation messages.
485
+
486
+ For Unpoly to be able to detect a failed form submission,,
487
+ the form must be re-rendered with a non-200 HTTP status code.
488
+ We recommend to use either 400 (bad request) or
489
+ 422 (unprocessable entity).
490
+
491
+ In Ruby on Rails, you can pass a
492
+ [`:status` option to `render`](http://guides.rubyonrails.org/layouts_and_rendering.html#the-status-option)
493
+ for this:
494
+
495
+ class UsersController < ApplicationController
496
+
497
+ def create
498
+ user_params = params[:user].permit(:email, :password)
499
+ @user = User.new(user_params)
500
+ if @user.save?
501
+ sign_in @user
502
+ else
503
+ render 'form', status: :bad_request
504
+ end
505
+ end
506
+
507
+ end
508
+
509
+ Note that you can also use the
510
+ [`up-validate`](/up-validate) attribute to perform server-side
511
+ validations while the user is completing fields.
512
+
513
+ \#\#\#\# Redirects
514
+
515
+ Unpoly requires two additional response headers to detect redirects,
516
+ which are otherwise undetectable for an AJAX client.
517
+
518
+ When the form's action performs a redirect, the server should echo
519
+ the new request's URL as a response header `X-Up-Location`
520
+ and the request's HTTP method as `X-Up-Method: GET`.
521
+
522
+ If you are using Unpoly via the `unpoly-rails` gem, these headers
523
+ are set automatically for every request.
524
+
525
+ \#\#\#\# Giving feedback while the form is processing
526
+
527
+ The `<form>` element will be assigned a CSS class `up-active` while
528
+ the submission is loading.
529
+
530
+ You can also [implement a spinner](/up.proxy/#spinners)
531
+ by [listening](/up.on) to the [`up:proxy:busy`](/up:proxy:busy)
532
+ and [`up:proxy:idle`](/up:proxy:idle) events.
533
+
534
+ @selector form[up-target]
535
+ @param {String} up-target
536
+ The selector to [replace](/up.replace) if the form submission is successful (200 status code).
537
+ @param {String} [up-fail-target]
538
+ The selector to [replace](/up.replace) if the form submission is not successful (non-200 status code).
539
+ If omitted, Unpoly will replace the `<form>` tag itself, assuming that the
540
+ server has echoed the form with validation errors.
541
+ @param {String} [up-transition]
542
+ The animation to use when the form is replaced after a successful submission.
543
+ @param {String} [up-fail-transition]
544
+ The animation to use when the form is replaced after a failed submission.
545
+ @param [up-history]
546
+ Set this to `'false'` to prevent the current URL from being updated.
547
+ @param {String} [up-method]
548
+ The HTTP method to be used to submit the form (`get`, `post`, `put`, `delete`, `patch`).
549
+ Alternately you can use an attribute `data-method`
550
+ ([Rails UJS](https://github.com/rails/jquery-ujs/wiki/Unobtrusive-scripting-support-for-jQuery))
551
+ or `method` (vanilla HTML) for the same purpose.
552
+ @param {String} [up-reveal='true']
553
+ Whether to reveal the target element within its viewport before updating.
554
+ @param {String} [up-restore-scroll='false']
555
+ Whether to restore previously known scroll position of all viewports
556
+ within the target selector.
557
+ @param {String} [up-cache]
558
+ Whether to force the use of a cached response (`true`)
559
+ or never use the cache (`false`)
560
+ or make an educated guess (`undefined`).
561
+
562
+ By default only responses to `GET` requests are cached for a few minutes.
563
+ @stable
564
+ ###
565
+ up.on 'submit', 'form[up-target]', (event, $form) ->
566
+ event.preventDefault()
567
+ submit($form)
568
+
569
+ ###*
570
+ When a form field with this attribute is changed,
571
+ the form is validated on the server and is updated with
572
+ validation messages.
573
+
574
+ The programmatic variant of this is the [`up.validate`](/up.validate) function.
575
+
576
+ \#\#\#\# Example
577
+
578
+ Let's look at a standard registration form that asks for an e-mail and password:
579
+
580
+ <form action="/users">
581
+
582
+ <label>
583
+ E-mail: <input type="text" name="email" />
584
+ </label>
585
+
586
+ <label>
587
+ Password: <input type="password" name="password" />
588
+ </label>
589
+
590
+ <button type="submit">Register</button>
591
+
592
+ </form>
593
+
594
+ When the user changes the `email` field, we want to validate that
595
+ the e-mail address is valid and still available. Also we want to
596
+ change the `password` field for the minimum required password length.
597
+ We can do this by giving both fields an `up-validate` attribute:
598
+
599
+ <form action="/users">
600
+
601
+ <label>
602
+ E-mail: <input type="text" name="email" up-validate />
603
+ </label>
604
+
605
+ <label>
606
+ Password: <input type="password" name="password" up-validate />
607
+ </label>
608
+
609
+ <button type="submit">Register</button>
610
+
611
+ </form>
612
+
613
+ Whenever a field with `up-validate` changes, the form is POSTed to
614
+ `/users` with an additional `X-Up-Validate` HTTP header.
615
+ Upon seeing this header, the server is expected to validate (but not save)
616
+ the form submission and render a new copy of the form with validation errors.
617
+
618
+ In Ruby on Rails the processing action should behave like this:
619
+
620
+ class UsersController < ApplicationController
621
+
622
+ # This action handles POST /users
623
+ def create
624
+ user_params = params[:user].permit(:email, :password)
625
+ @user = User.new(user_params)
626
+ if request.headers['X-Up-Validate']
627
+ @user.valid? # run validations, but don't save to the database
628
+ render 'form' # render form with error messages
629
+ elsif @user.save?
630
+ sign_in @user
631
+ else
632
+ render 'form', status: :bad_request
633
+ end
634
+ end
635
+
636
+ end
637
+
638
+ Note that if you're using the `unpoly-rails` gem you can simply say `up.validate?`
639
+ instead of manually checking for `request.headers['X-Up-Validate']`.
640
+
641
+ The server now renders an updated copy of the form with eventual validation errors:
642
+
643
+ <form action="/users">
644
+
645
+ <label class="has-error">
646
+ E-mail: <input type="text" name="email" value="foo@bar.com" />
647
+ Has already been taken!
648
+ </label>
649
+
650
+ <button type="submit">Register</button>
651
+
652
+ </form>
653
+
654
+ The `<label>` around the e-mail field is now updated to have the `has-error`
655
+ class and display the validation message.
656
+
657
+ \#\#\#\# How validation results are displayed
658
+
659
+ Although the server will usually respond to a validation with a complete,
660
+ fresh copy of the form, Unpoly will by default not update the entire form.
661
+ This is done in order to preserve volatile state such as the scroll position
662
+ of `<textarea>` elements.
663
+
664
+ By default Unpoly looks for a `<fieldset>`, `<label>` or `<form>`
665
+ around the validating input field, or any element with an
666
+ `up-fieldset` attribute.
667
+ With the Bootstrap bindings, Unpoly will also look
668
+ for a container with the `form-group` class.
669
+
670
+ You can change this default behavior by setting `up.config.validateTargets`:
671
+
672
+ // Always update the entire form containing the current field ("&")
673
+ up.form.config.validateTargets = ['form &']
674
+
675
+ You can also individually override what to update by setting the `up-validate`
676
+ attribute to a CSS selector:
677
+
678
+ <input type="text" name="email" up-validate=".email-errors">
679
+ <span class="email-errors"></span>
680
+
681
+ \#\#\#\# Updating dependent fields
682
+
683
+ The `[up-validate]` behavior is also a great way to partially update a form
684
+ when one fields depends on the value of another field.
685
+
686
+ Let's say you have a form with one `<select>` to pick a department (sales, engineering, ...)
687
+ and another `<select>` to pick an employeee from the selected department:
688
+
689
+ <form action="/contracts">
690
+ <select name="department">...</select> <!-- options for all departments -->
691
+ <select name="employeed">...</select> <!-- options for employees of selected department -->
692
+ </form>
693
+
694
+ The list of employees needs to be updated as the appartment changes:
695
+
696
+ <form action="/contracts">
697
+ <select name="department" up-validate="[name=employee]">...</select>
698
+ <select name="employee">...</select>
699
+ </form>
700
+
701
+ In order to update the `department` field in addition to the `employee` field, you could say
702
+ `up-validate="&, [name=employee]"`, or simply `up-validate="form"` to update the entire form.
703
+
704
+ @selector [up-validate]
705
+ @param {String} up-validate
706
+ The CSS selector to update with the server response.
707
+
708
+ This defaults to a fieldset or form group around the validating field.
709
+ @stable
710
+ ###
711
+ up.on 'change', '[up-validate]', (event, $field) ->
712
+ validate($field)
713
+
714
+ ###*
715
+ Show or hide part of a form if certain options are selected or boxes are checked.
716
+
717
+ \#\#\#\# Example
718
+
719
+ The triggering input gets an `up-toggle` attribute with a selector for the elements to show or hide:
720
+
721
+ <select name="advancedness" up-toggle=".target">
722
+ <option value="basic">Basic parts</option>
723
+ <option value="advanced">Advanced parts</option>
724
+ <option value="very-advanced">Very advanced parts</option>
725
+ </select>
726
+
727
+ The target elements get a space-separated list of select values for which they are shown or hidden:
728
+
729
+ <div class="target" up-show-for="basic">
730
+ only shown for advancedness = basic
731
+ </div>
732
+
733
+ <div class="target" up-hide-for="basic">
734
+ hidden for advancedness = basic
735
+ </div>
736
+
737
+ <div class="target" up-show-for="advanced very-advanced">
738
+ shown for advancedness = advanced or very-advanced
739
+ </div>
740
+
741
+ For checkboxes you can also use the pseudo-values `:checked` or `:unchecked` like so:
742
+
743
+ <input type="checkbox" name="flag" up-toggle=".target">
744
+
745
+ <div class="target" up-show-for=":checked">
746
+ only shown when checkbox is checked
747
+ </div>
748
+
749
+ You can also use the pseudo-values `:blank` to match an empty input value,
750
+ or `:present` to match a non-empty input value:
751
+
752
+ <input type="text" name="email" up-toggle=".target">
753
+
754
+ <div class="target" up-show-for=":blank">
755
+ please enter an email address
756
+ </div>
757
+
758
+ @selector [up-toggle]
759
+ @stable
760
+ ###
761
+
762
+ ###*
763
+ Show this element only if a form field has a given value.
764
+
765
+ See [`[up-toggle]`](/up-toggle) for more documentation and examples.
766
+
767
+ @selector [up-show-for]
768
+ @param up-show-for
769
+ A space-separated list of values for which to show this element.
770
+ @stable
771
+ ###
772
+
773
+ ###*
774
+ Hide this element if a form field has a given value.
775
+
776
+ See [`[up-toggle]`](/up-toggle) for more documentation and examples.
777
+
778
+ @selector [up-hide-for]
779
+ @param up-hide-for
780
+ A space-separated list of values for which to hide this element.
781
+ @stable
782
+ ###
783
+
784
+ up.on 'change', '[up-toggle]', (event, $field) ->
785
+ console.log("CHANGE EVENT")
786
+ toggleTargets($field)
787
+
788
+ up.compiler '[up-toggle]', ($field) ->
789
+ toggleTargets($field)
790
+
791
+ ###*
792
+ Observes this field or form and runs a callback when a value changes.
793
+
794
+ This is useful for observing text fields while the user is typing.
795
+
796
+ The programmatic variant of this is the [`up.observe`](/up.observe) function.
797
+
798
+ \#\#\#\# Example
799
+
800
+ The following would run a global `showSuggestions(value)` function
801
+ whenever the `<input>` changes:
802
+
803
+ <form>
804
+ <input type="query" up-observe="showSuggestions(value)">
805
+ </form>
806
+
807
+ \#\#\#\# Callback context
808
+
809
+ The script given to `up-observe` runs with the following context:
810
+
811
+ | Name | Type | Description |
812
+ | -------- | --------- | ------------------------------------- |
813
+ | `value` | `String` | The current value of the field |
814
+ | `this` | `Element` | The form field |
815
+ | `$field` | `jQuery` | The form field as a jQuery collection |
816
+
817
+ @selector [up-observe]
818
+ @param {String} up-observe
819
+ The code to run when the field's value changes.
820
+ @param {String} up-delay
821
+ The number of miliseconds to wait after a change before the code is run.
822
+ @stable
823
+ ###
824
+ up.compiler '[up-observe]', ($formOrField) -> observe($formOrField)
825
+
826
+ ###*
827
+ [Observes](/up.observe) this field or form and submits the form when a value changes.
828
+
829
+ The form field will be assigned a CSS class [`up-active`](/up-active)
830
+ while the autosubmitted form is processing.
831
+
832
+ The programmatic variant of this is the [`up.autosubmit`](/up.autosubmit) function.
833
+
834
+ \#\#\#\# Example
835
+
836
+ The following would submit the form whenever the
837
+ text field value changes:
838
+
839
+ <form method="GET" action="/search" up-autosubmit>
840
+ <input type="query">
841
+ </form>
842
+
843
+ @selector [up-autosubmit]
844
+ @param {String} up-delay
845
+ The number of miliseconds to wait after the change before the form is submitted.
846
+ @stable
847
+ ###
848
+ up.compiler '[up-autosubmit]', ($formOrField) -> autosubmit($formOrField)
849
+
850
+ up.on 'up:framework:reset', reset
851
+
852
+ knife: eval(Knife?.point)
853
+ config: config
854
+ submit: submit
855
+ observe: observe
856
+ validate: validate
857
+ toggleTargets: toggleTargets
858
+
859
+ )(jQuery)
860
+
861
+ up.submit = up.form.submit
862
+ up.observe = up.form.observe
863
+ up.autosubmit = up.form.autosubmit
864
+ up.validate = up.form.validate