unpoly-rails 0.62.1 → 2.0.0.pre.rc2

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 (340) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -1
  3. data/CHANGELOG.md +53 -1
  4. data/README.md +1 -1
  5. data/README_RAILS.md +295 -14
  6. data/dist/unpoly-bootstrap3.css +9 -14
  7. data/dist/unpoly-bootstrap3.js +4 -18
  8. data/dist/unpoly-bootstrap3.min.css +1 -1
  9. data/dist/unpoly-bootstrap3.min.js +1 -1
  10. data/dist/unpoly-bootstrap4.css +9 -0
  11. data/dist/unpoly-bootstrap4.js +16 -0
  12. data/dist/unpoly-bootstrap4.min.css +1 -0
  13. data/dist/unpoly-bootstrap4.min.js +1 -0
  14. data/dist/unpoly-bootstrap5.css +9 -0
  15. data/dist/unpoly-bootstrap5.js +14 -0
  16. data/dist/unpoly-bootstrap5.min.css +1 -0
  17. data/dist/unpoly-bootstrap5.min.js +1 -0
  18. data/dist/unpoly-migrate.js +1213 -0
  19. data/dist/unpoly-migrate.min.js +1 -0
  20. data/dist/unpoly.css +109 -140
  21. data/dist/unpoly.js +15377 -10465
  22. data/dist/unpoly.min.css +1 -1
  23. data/dist/unpoly.min.js +6 -4
  24. data/lib/unpoly-rails.rb +9 -3
  25. data/lib/unpoly/rails/change.rb +372 -0
  26. data/lib/unpoly/rails/change/cache.rb +26 -0
  27. data/lib/unpoly/rails/change/context.rb +80 -0
  28. data/lib/unpoly/rails/change/field.rb +117 -0
  29. data/lib/unpoly/rails/change/field_definition.rb +74 -0
  30. data/lib/unpoly/rails/change/layer.rb +60 -0
  31. data/lib/unpoly/rails/controller.rb +47 -0
  32. data/lib/unpoly/rails/error.rb +5 -0
  33. data/lib/unpoly/rails/request_echo_headers.rb +2 -2
  34. data/lib/unpoly/rails/version.rb +1 -1
  35. data/lib/unpoly/tasks.rb +45 -0
  36. metadata +43 -313
  37. data/.gitignore +0 -10
  38. data/.ruby-version +0 -1
  39. data/Gemfile +0 -8
  40. data/Gemfile.lock +0 -45
  41. data/Rakefile +0 -145
  42. data/bower.json +0 -27
  43. data/design/animation-ghosting.txt +0 -72
  44. data/design/design.txt +0 -34
  45. data/design/draft.html.erb +0 -48
  46. data/design/draft.rb +0 -9
  47. data/design/es6.js +0 -32
  48. data/design/ghost-debugging.txt +0 -118
  49. data/design/homepage.txt +0 -236
  50. data/design/ie11.txt +0 -9
  51. data/design/measure_import_node.js +0 -330
  52. data/design/measure_jquery/element_list.js +0 -41
  53. data/design/measure_jquery/up.on_vs_addEventListener.js +0 -56
  54. data/design/positioning.txt +0 -28
  55. data/design/query-params-in-form-actions/cases.html +0 -125
  56. data/design/rename.txt +0 -0
  57. data/design/test_rejected_promise.txt +0 -5
  58. data/design/unpoly errors.txt +0 -19
  59. data/lib/assets/javascripts/unpoly-bootstrap3.coffee +0 -2
  60. data/lib/assets/javascripts/unpoly-bootstrap3/feedback-ext.coffee +0 -5
  61. data/lib/assets/javascripts/unpoly-bootstrap3/form-ext.coffee +0 -1
  62. data/lib/assets/javascripts/unpoly-bootstrap3/modal-ext.coffee +0 -14
  63. data/lib/assets/javascripts/unpoly-bootstrap3/viewport-ext.coffee +0 -5
  64. data/lib/assets/javascripts/unpoly.coffee +0 -28
  65. data/lib/assets/javascripts/unpoly/browser.coffee.erb +0 -240
  66. data/lib/assets/javascripts/unpoly/classes/body_shifter.coffee +0 -45
  67. data/lib/assets/javascripts/unpoly/classes/cache.coffee +0 -127
  68. data/lib/assets/javascripts/unpoly/classes/compile_pass.coffee +0 -93
  69. data/lib/assets/javascripts/unpoly/classes/config.coffee +0 -9
  70. data/lib/assets/javascripts/unpoly/classes/css_transition.coffee +0 -118
  71. data/lib/assets/javascripts/unpoly/classes/divertible_chain.coffee +0 -39
  72. data/lib/assets/javascripts/unpoly/classes/event_listener.coffee +0 -116
  73. data/lib/assets/javascripts/unpoly/classes/extract_cascade.coffee +0 -86
  74. data/lib/assets/javascripts/unpoly/classes/extract_plan.coffee +0 -111
  75. data/lib/assets/javascripts/unpoly/classes/field_observer.coffee +0 -80
  76. data/lib/assets/javascripts/unpoly/classes/focus_follower.coffee +0 -29
  77. data/lib/assets/javascripts/unpoly/classes/follow_variant.coffee +0 -64
  78. data/lib/assets/javascripts/unpoly/classes/html_parser.coffee +0 -46
  79. data/lib/assets/javascripts/unpoly/classes/motion_controller.coffee +0 -157
  80. data/lib/assets/javascripts/unpoly/classes/params.coffee.erb +0 -544
  81. data/lib/assets/javascripts/unpoly/classes/record.coffee +0 -22
  82. data/lib/assets/javascripts/unpoly/classes/rect.js +0 -21
  83. data/lib/assets/javascripts/unpoly/classes/request.coffee +0 -246
  84. data/lib/assets/javascripts/unpoly/classes/response.coffee +0 -157
  85. data/lib/assets/javascripts/unpoly/classes/reveal_motion.coffee +0 -102
  86. data/lib/assets/javascripts/unpoly/classes/scroll_motion.coffee +0 -67
  87. data/lib/assets/javascripts/unpoly/classes/selector.coffee +0 -60
  88. data/lib/assets/javascripts/unpoly/classes/store/memory.coffee +0 -26
  89. data/lib/assets/javascripts/unpoly/classes/store/session.coffee +0 -59
  90. data/lib/assets/javascripts/unpoly/classes/tether.coffee +0 -105
  91. data/lib/assets/javascripts/unpoly/classes/url_set.coffee +0 -32
  92. data/lib/assets/javascripts/unpoly/cookie.coffee +0 -56
  93. data/lib/assets/javascripts/unpoly/element.coffee.erb +0 -1126
  94. data/lib/assets/javascripts/unpoly/event.coffee.erb +0 -445
  95. data/lib/assets/javascripts/unpoly/feedback.coffee +0 -353
  96. data/lib/assets/javascripts/unpoly/form.coffee.erb +0 -1075
  97. data/lib/assets/javascripts/unpoly/fragment.coffee.erb +0 -928
  98. data/lib/assets/javascripts/unpoly/framework.coffee +0 -67
  99. data/lib/assets/javascripts/unpoly/history.coffee +0 -268
  100. data/lib/assets/javascripts/unpoly/legacy.coffee +0 -60
  101. data/lib/assets/javascripts/unpoly/link.coffee.erb +0 -622
  102. data/lib/assets/javascripts/unpoly/log.coffee +0 -248
  103. data/lib/assets/javascripts/unpoly/modal.coffee.erb +0 -827
  104. data/lib/assets/javascripts/unpoly/motion.coffee.erb +0 -668
  105. data/lib/assets/javascripts/unpoly/namespace.coffee.erb +0 -5
  106. data/lib/assets/javascripts/unpoly/popup.coffee.erb +0 -515
  107. data/lib/assets/javascripts/unpoly/protocol.coffee +0 -298
  108. data/lib/assets/javascripts/unpoly/proxy.coffee +0 -672
  109. data/lib/assets/javascripts/unpoly/radio.coffee +0 -60
  110. data/lib/assets/javascripts/unpoly/rails.coffee +0 -24
  111. data/lib/assets/javascripts/unpoly/syntax.coffee.erb +0 -476
  112. data/lib/assets/javascripts/unpoly/toast.coffee +0 -67
  113. data/lib/assets/javascripts/unpoly/tooltip.coffee +0 -276
  114. data/lib/assets/javascripts/unpoly/util.coffee.erb +0 -1676
  115. data/lib/assets/javascripts/unpoly/viewport.coffee.erb +0 -830
  116. data/lib/assets/stylesheets/unpoly-bootstrap3.sass +0 -1
  117. data/lib/assets/stylesheets/unpoly-bootstrap3/modal-ext.sass +0 -27
  118. data/lib/assets/stylesheets/unpoly.sass +0 -1
  119. data/lib/assets/stylesheets/unpoly/close.sass +0 -2
  120. data/lib/assets/stylesheets/unpoly/dom.sass +0 -5
  121. data/lib/assets/stylesheets/unpoly/layout.sass +0 -2
  122. data/lib/assets/stylesheets/unpoly/link.sass +0 -2
  123. data/lib/assets/stylesheets/unpoly/modal.sass +0 -116
  124. data/lib/assets/stylesheets/unpoly/popup.sass +0 -7
  125. data/lib/assets/stylesheets/unpoly/toast.sass +0 -33
  126. data/lib/assets/stylesheets/unpoly/tooltip.sass +0 -62
  127. data/lib/unpoly/rails/inspector.rb +0 -149
  128. data/lib/unpoly/rails/inspector_accessor.rb +0 -30
  129. data/package.json +0 -38
  130. data/spec_app/.firefox-version +0 -1
  131. data/spec_app/.gitignore +0 -17
  132. data/spec_app/.rspec +0 -2
  133. data/spec_app/Gemfile +0 -30
  134. data/spec_app/Gemfile.lock +0 -229
  135. data/spec_app/README.rdoc +0 -28
  136. data/spec_app/Rakefile +0 -6
  137. data/spec_app/app/assets/images/.keep +0 -0
  138. data/spec_app/app/assets/images/favicon.png +0 -0
  139. data/spec_app/app/assets/images/grid.png +0 -0
  140. data/spec_app/app/assets/javascripts/bootstrap_manifest.coffee +0 -6
  141. data/spec_app/app/assets/javascripts/integration_test.coffee +0 -6
  142. data/spec_app/app/assets/javascripts/jasmine_specs.coffee +0 -6
  143. data/spec_app/app/assets/stylesheets/_helpers.sass +0 -5
  144. data/spec_app/app/assets/stylesheets/bootstrap_manifest.sass +0 -2
  145. data/spec_app/app/assets/stylesheets/integration_test.sass +0 -88
  146. data/spec_app/app/assets/stylesheets/jasmine_specs.sass +0 -20
  147. data/spec_app/app/controllers/application_controller.rb +0 -14
  148. data/spec_app/app/controllers/binding_test_controller.rb +0 -51
  149. data/spec_app/app/controllers/compiler_test_controller.rb +0 -5
  150. data/spec_app/app/controllers/css_test_controller.rb +0 -5
  151. data/spec_app/app/controllers/error_test_controller.rb +0 -5
  152. data/spec_app/app/controllers/form_test/basics_controller.rb +0 -14
  153. data/spec_app/app/controllers/form_test/redirects_controller.rb +0 -17
  154. data/spec_app/app/controllers/form_test/uploads_controller.rb +0 -15
  155. data/spec_app/app/controllers/hash_test_controller.rb +0 -5
  156. data/spec_app/app/controllers/method_test_controller.rb +0 -16
  157. data/spec_app/app/controllers/motion_test_controller.rb +0 -5
  158. data/spec_app/app/controllers/pages_controller.rb +0 -9
  159. data/spec_app/app/controllers/replace_test_controller.rb +0 -5
  160. data/spec_app/app/controllers/reveal_test_controller.rb +0 -5
  161. data/spec_app/app/controllers/scroll_test_controller.rb +0 -5
  162. data/spec_app/app/helpers/application_helper.rb +0 -2
  163. data/spec_app/app/mailers/.keep +0 -0
  164. data/spec_app/app/models/concerns/.keep +0 -0
  165. data/spec_app/app/views/compiler_test/timestamp.erb +0 -9
  166. data/spec_app/app/views/css_test/modal.erb +0 -47
  167. data/spec_app/app/views/css_test/modal_contents.erb +0 -5
  168. data/spec_app/app/views/css_test/modal_contents_wide.erb +0 -5
  169. data/spec_app/app/views/css_test/popup.erb +0 -81
  170. data/spec_app/app/views/css_test/popup_contents.erb +0 -5
  171. data/spec_app/app/views/css_test/tooltip.erb +0 -48
  172. data/spec_app/app/views/error_test/trigger.erb +0 -80
  173. data/spec_app/app/views/error_test/unexpected_response.erb +0 -3
  174. data/spec_app/app/views/form_test/basics/new.erb +0 -60
  175. data/spec_app/app/views/form_test/redirects/new.erb +0 -27
  176. data/spec_app/app/views/form_test/redirects/target.erb +0 -4
  177. data/spec_app/app/views/form_test/submission_result.erb +0 -30
  178. data/spec_app/app/views/form_test/uploads/new.erb +0 -44
  179. data/spec_app/app/views/hash_test/unpoly.erb +0 -30
  180. data/spec_app/app/views/hash_test/vanilla.erb +0 -13
  181. data/spec_app/app/views/layouts/integration_test.erb +0 -22
  182. data/spec_app/app/views/layouts/jasmine_rails/spec_runner.html.erb +0 -20
  183. data/spec_app/app/views/method_test/form_target.erb +0 -17
  184. data/spec_app/app/views/method_test/page1.erb +0 -11
  185. data/spec_app/app/views/method_test/page2.erb +0 -6
  186. data/spec_app/app/views/motion_test/animations.erb +0 -16
  187. data/spec_app/app/views/motion_test/transitions.erb +0 -13
  188. data/spec_app/app/views/pages/start.erb +0 -79
  189. data/spec_app/app/views/replace_test/_nav.erb +0 -6
  190. data/spec_app/app/views/replace_test/page1.erb +0 -14
  191. data/spec_app/app/views/replace_test/page2.erb +0 -14
  192. data/spec_app/app/views/replace_test/table.erb +0 -16
  193. data/spec_app/app/views/reveal_test/long1.erb +0 -17
  194. data/spec_app/app/views/reveal_test/long2.erb +0 -17
  195. data/spec_app/app/views/reveal_test/within_document_viewport.erb +0 -24
  196. data/spec_app/app/views/reveal_test/within_overflowing_div_viewport.erb +0 -28
  197. data/spec_app/app/views/scroll_test/long1.erb +0 -30
  198. data/spec_app/bin/bundle +0 -3
  199. data/spec_app/bin/rails +0 -8
  200. data/spec_app/bin/rake +0 -8
  201. data/spec_app/bin/setup +0 -29
  202. data/spec_app/bin/spring +0 -18
  203. data/spec_app/config.ru +0 -4
  204. data/spec_app/config/application.rb +0 -28
  205. data/spec_app/config/boot.rb +0 -3
  206. data/spec_app/config/database.yml +0 -25
  207. data/spec_app/config/environment.rb +0 -5
  208. data/spec_app/config/environments/development.rb +0 -41
  209. data/spec_app/config/environments/production.rb +0 -79
  210. data/spec_app/config/environments/test.rb +0 -42
  211. data/spec_app/config/initializers/assets.rb +0 -19
  212. data/spec_app/config/initializers/backtrace_silencers.rb +0 -7
  213. data/spec_app/config/initializers/bower_rails.rb +0 -16
  214. data/spec_app/config/initializers/cookies_serializer.rb +0 -3
  215. data/spec_app/config/initializers/filter_parameter_logging.rb +0 -4
  216. data/spec_app/config/initializers/inflections.rb +0 -16
  217. data/spec_app/config/initializers/mime_types.rb +0 -4
  218. data/spec_app/config/initializers/session_store.rb +0 -3
  219. data/spec_app/config/initializers/wrap_parameters.rb +0 -14
  220. data/spec_app/config/locales/en.yml +0 -23
  221. data/spec_app/config/routes.rb +0 -30
  222. data/spec_app/config/secrets.yml +0 -22
  223. data/spec_app/db/schema.rb +0 -23
  224. data/spec_app/db/seeds.rb +0 -7
  225. data/spec_app/lib/assets/.keep +0 -0
  226. data/spec_app/lib/tasks/.keep +0 -0
  227. data/spec_app/lib/tasks/cucumber.rake +0 -65
  228. data/spec_app/log/.keep +0 -0
  229. data/spec_app/public/404.html +0 -67
  230. data/spec_app/public/422.html +0 -67
  231. data/spec_app/public/500.html +0 -66
  232. data/spec_app/public/favicon.ico +0 -0
  233. data/spec_app/public/robots.txt +0 -5
  234. data/spec_app/script/cucumber +0 -10
  235. data/spec_app/spec/controllers/binding_test_controller_spec.rb +0 -248
  236. data/spec_app/spec/javascripts/helpers/agent_detector.coffee +0 -20
  237. data/spec_app/spec/javascripts/helpers/async_sequence.js.coffee +0 -103
  238. data/spec_app/spec/javascripts/helpers/browser_switches.js.coffee +0 -21
  239. data/spec_app/spec/javascripts/helpers/enable_logging.js.coffee +0 -2
  240. data/spec_app/spec/javascripts/helpers/fixture.js.coffee +0 -25
  241. data/spec_app/spec/javascripts/helpers/index.js.coffee +0 -1
  242. data/spec_app/spec/javascripts/helpers/jquery_no_conflict.js +0 -1
  243. data/spec_app/spec/javascripts/helpers/knife.js.coffee +0 -69
  244. data/spec_app/spec/javascripts/helpers/last_request.js.coffee +0 -25
  245. data/spec_app/spec/javascripts/helpers/mock_ajax.js.coffee +0 -8
  246. data/spec_app/spec/javascripts/helpers/mock_clock.js.coffee +0 -2
  247. data/spec_app/spec/javascripts/helpers/parse_form_data.js.coffee +0 -24
  248. data/spec_app/spec/javascripts/helpers/promise_state.js +0 -18
  249. data/spec_app/spec/javascripts/helpers/protect_jasmine_runner.coffee +0 -12
  250. data/spec_app/spec/javascripts/helpers/remove_body_margin.js.coffee +0 -8
  251. data/spec_app/spec/javascripts/helpers/reset_history.js.coffee +0 -23
  252. data/spec_app/spec/javascripts/helpers/reset_knife.js.coffee +0 -2
  253. data/spec_app/spec/javascripts/helpers/reset_up.js.coffee +0 -25
  254. data/spec_app/spec/javascripts/helpers/restore_body_scroll.js.coffee +0 -5
  255. data/spec_app/spec/javascripts/helpers/show_lib_versions.coffee +0 -12
  256. data/spec_app/spec/javascripts/helpers/spec_util.coffee +0 -47
  257. data/spec_app/spec/javascripts/helpers/to_be_around.js.coffee +0 -8
  258. data/spec_app/spec/javascripts/helpers/to_be_array.coffee +0 -5
  259. data/spec_app/spec/javascripts/helpers/to_be_attached.coffee +0 -9
  260. data/spec_app/spec/javascripts/helpers/to_be_blank.js.coffee +0 -8
  261. data/spec_app/spec/javascripts/helpers/to_be_detached.coffee +0 -9
  262. data/spec_app/spec/javascripts/helpers/to_be_element.js.coffee +0 -8
  263. data/spec_app/spec/javascripts/helpers/to_be_error.coffee +0 -8
  264. data/spec_app/spec/javascripts/helpers/to_be_given.js.coffee +0 -8
  265. data/spec_app/spec/javascripts/helpers/to_be_hidden.js.coffee +0 -8
  266. data/spec_app/spec/javascripts/helpers/to_be_jquery.js.coffee +0 -5
  267. data/spec_app/spec/javascripts/helpers/to_be_missing.js.coffee +0 -8
  268. data/spec_app/spec/javascripts/helpers/to_be_present.js.coffee +0 -8
  269. data/spec_app/spec/javascripts/helpers/to_be_scrolled_to.coffee +0 -11
  270. data/spec_app/spec/javascripts/helpers/to_be_visible.js.coffee +0 -9
  271. data/spec_app/spec/javascripts/helpers/to_contain.js.coffee +0 -8
  272. data/spec_app/spec/javascripts/helpers/to_end_with.js.coffee +0 -11
  273. data/spec_app/spec/javascripts/helpers/to_equal_jquery.js.coffee +0 -8
  274. data/spec_app/spec/javascripts/helpers/to_equal_node_list.coffee +0 -7
  275. data/spec_app/spec/javascripts/helpers/to_equal_via_is_equal.js.coffee +0 -7
  276. data/spec_app/spec/javascripts/helpers/to_have_class.js.coffee +0 -10
  277. data/spec_app/spec/javascripts/helpers/to_have_descendant.js.coffee +0 -10
  278. data/spec_app/spec/javascripts/helpers/to_have_length.js.coffee +0 -8
  279. data/spec_app/spec/javascripts/helpers/to_have_opacity.coffee +0 -15
  280. data/spec_app/spec/javascripts/helpers/to_have_own_property.js.coffee +0 -8
  281. data/spec_app/spec/javascripts/helpers/to_have_request_method.js.coffee +0 -16
  282. data/spec_app/spec/javascripts/helpers/to_have_text.js.coffee +0 -9
  283. data/spec_app/spec/javascripts/helpers/to_have_unhandled_rejections.coffee +0 -18
  284. data/spec_app/spec/javascripts/helpers/to_match_list.coffee +0 -14
  285. data/spec_app/spec/javascripts/helpers/to_match_selector.coffee +0 -8
  286. data/spec_app/spec/javascripts/helpers/to_match_text.js.coffee +0 -13
  287. data/spec_app/spec/javascripts/helpers/to_match_url.coffee +0 -14
  288. data/spec_app/spec/javascripts/helpers/trigger.js.coffee +0 -200
  289. data/spec_app/spec/javascripts/helpers/wait_until_dom_ready.js.coffee +0 -5
  290. data/spec_app/spec/javascripts/support/jasmine.yml +0 -51
  291. data/spec_app/spec/javascripts/up/browser_spec.js.coffee +0 -150
  292. data/spec_app/spec/javascripts/up/classes/cache_spec.js.coffee +0 -82
  293. data/spec_app/spec/javascripts/up/classes/config_spec.coffee +0 -24
  294. data/spec_app/spec/javascripts/up/classes/divertible_chain_spec.coffee +0 -45
  295. data/spec_app/spec/javascripts/up/classes/focus_tracker_spec.coffee +0 -34
  296. data/spec_app/spec/javascripts/up/classes/params_spec.coffee +0 -557
  297. data/spec_app/spec/javascripts/up/classes/request_spec.coffee +0 -50
  298. data/spec_app/spec/javascripts/up/classes/scroll_motion_spec.js.coffee +0 -51
  299. data/spec_app/spec/javascripts/up/classes/store/memory_spec.js.coffee +0 -70
  300. data/spec_app/spec/javascripts/up/classes/store/session_spec.js.coffee +0 -114
  301. data/spec_app/spec/javascripts/up/element_spec.coffee +0 -897
  302. data/spec_app/spec/javascripts/up/event_spec.js.coffee +0 -530
  303. data/spec_app/spec/javascripts/up/feedback_spec.js.coffee +0 -401
  304. data/spec_app/spec/javascripts/up/form_spec.js.coffee +0 -1527
  305. data/spec_app/spec/javascripts/up/fragment_spec.js.coffee +0 -2624
  306. data/spec_app/spec/javascripts/up/history_spec.js.coffee +0 -340
  307. data/spec_app/spec/javascripts/up/jquery_spec.js.coffee +0 -4
  308. data/spec_app/spec/javascripts/up/legacy_spec.js.coffee +0 -27
  309. data/spec_app/spec/javascripts/up/link_spec.js.coffee +0 -1098
  310. data/spec_app/spec/javascripts/up/log_spec.js.coffee +0 -119
  311. data/spec_app/spec/javascripts/up/modal_spec.js.coffee +0 -939
  312. data/spec_app/spec/javascripts/up/motion_spec.js.coffee +0 -582
  313. data/spec_app/spec/javascripts/up/popup_spec.js.coffee +0 -508
  314. data/spec_app/spec/javascripts/up/protocol_spec.js.coffee +0 -39
  315. data/spec_app/spec/javascripts/up/proxy_spec.js.coffee +0 -1137
  316. data/spec_app/spec/javascripts/up/radio_spec.js.coffee +0 -212
  317. data/spec_app/spec/javascripts/up/rails_spec.js.coffee +0 -118
  318. data/spec_app/spec/javascripts/up/spec_spec.js.coffee +0 -9
  319. data/spec_app/spec/javascripts/up/syntax_spec.js.coffee +0 -304
  320. data/spec_app/spec/javascripts/up/toast_spec.js.coffee +0 -37
  321. data/spec_app/spec/javascripts/up/tooltip_spec.js.coffee +0 -163
  322. data/spec_app/spec/javascripts/up/util_spec.js.coffee +0 -1420
  323. data/spec_app/spec/javascripts/up/viewport_spec.js.coffee +0 -655
  324. data/spec_app/spec/spec_helper.rb +0 -62
  325. data/spec_app/test/controllers/.keep +0 -0
  326. data/spec_app/test/fixtures/.keep +0 -0
  327. data/spec_app/test/helpers/.keep +0 -0
  328. data/spec_app/test/integration/.keep +0 -0
  329. data/spec_app/test/mailers/.keep +0 -0
  330. data/spec_app/test/models/.keep +0 -0
  331. data/spec_app/test/test_helper.rb +0 -10
  332. data/spec_app/vendor/asset-libs/es6-promise-4.1.6/es6-promise.auto.js +0 -1159
  333. data/spec_app/vendor/asset-libs/jasmine-ajax-3.3.1/.bower.json +0 -43
  334. data/spec_app/vendor/asset-libs/jasmine-ajax-3.3.1/.gitignore +0 -6
  335. data/spec_app/vendor/asset-libs/jasmine-ajax-3.3.1/.npmignore +0 -10
  336. data/spec_app/vendor/asset-libs/jasmine-ajax-3.3.1/.pairs +0 -6
  337. data/spec_app/vendor/asset-libs/jasmine-ajax-3.3.1/.travis.yml +0 -56
  338. data/spec_app/vendor/asset-libs/jasmine-ajax-3.3.1/jasmine-ajax.js +0 -790
  339. data/spec_app/vendor/assets/.keep +0 -0
  340. data/unpoly-rails.gemspec +0 -24
@@ -1,248 +0,0 @@
1
- ###**
2
- Logging
3
- =======
4
-
5
- Unpoly can print debugging information to the developer console, e.g.:
6
-
7
- - Which [events](/up.event) are called
8
- - When we're [making requests to the network](/up.proxy)
9
- - Which [compilers](/up.syntax) are applied to which elements
10
-
11
- You can activate logging by calling [`up.log.enable()`](/up.log.enable).
12
- The output can be configured using the [`up.log.config`](/up.log.config) property.
13
-
14
- @module up.log
15
- ###
16
- up.log = do ->
17
-
18
- u = up.util
19
- b = up.browser
20
-
21
- sessionStore = new up.store.Session('up.log')
22
-
23
- ###**
24
- Configures the logging output on the developer console.
25
-
26
- @property up.log.config
27
- @param {boolean} [options.enabled=false]
28
- Whether Unpoly will print debugging information to the developer console.
29
-
30
- Debugging information includes which elements are being [compiled](/up.syntax)
31
- and which [events](/up.event) are being emitted.
32
- Note that errors will always be printed, regardless of this setting.
33
- @param {boolean} [options.collapse=false]
34
- Whether debugging information is printed as a collapsed tree.
35
-
36
- Set this to `true` if you are overwhelmed by the debugging information Unpoly
37
- prints to the developer console.
38
- @param {string} [options.prefix='[UP] ']
39
- A string to prepend to Unpoly's logging messages so you can distinguish it from your own messages.
40
- @stable
41
- ###
42
- config = new up.Config
43
- prefix: '[UP] '
44
- enabled: sessionStore.get('enabled')
45
- collapse: false
46
-
47
- reset = ->
48
- config.reset()
49
-
50
- prefix = (message) ->
51
- "#{config.prefix}#{message}"
52
-
53
- ###**
54
- A cross-browser way to interact with `console.log`, `console.error`, etc.
55
-
56
- This function falls back to `console.log` if the output stream is not implemented.
57
- It also prints substitution strings (e.g. `console.log("From %o to %o", "a", "b")`)
58
- as a single string if the browser console does not support substitution strings.
59
-
60
- \#\#\# Example
61
-
62
- up.browser.puts('log', 'Hi world')
63
- up.browser.puts('error', 'There was an error in %o', obj)
64
-
65
- @function up.browser.puts
66
- @internal
67
- ###
68
- callConsole = (stream, args...) ->
69
- console[stream](args...)
70
-
71
- CONSOLE_PLACEHOLDERS = /\%[odisf]/g
72
-
73
- stringifyArg = (arg) ->
74
- maxLength = 200
75
- closer = ''
76
-
77
- if u.isString(arg)
78
- string = arg.replace(/[\n\r\t ]+/g, ' ')
79
- string = string.replace(/^[\n\r\t ]+/, '')
80
- string = string.replace(/[\n\r\t ]$/, '')
81
- string = "\"#{string}\""
82
- closer = '"'
83
- else if u.isUndefined(arg)
84
- # JSON.stringify(undefined) is actually undefined
85
- string = 'undefined'
86
- else if u.isNumber(arg) || u.isFunction(arg)
87
- string = arg.toString()
88
- else if u.isArray(arg)
89
- string = "[#{u.map(arg, stringifyArg).join(', ')}]"
90
- closer = ']'
91
- else if u.isJQuery(arg)
92
- string = "$(#{u.map(arg, stringifyArg).join(', ')})"
93
- closer = ')'
94
- else if u.isElement(arg)
95
- string = "<#{arg.tagName.toLowerCase()}"
96
- for attr in ['id', 'name', 'class']
97
- if value = arg.getAttribute(attr)
98
- string += " #{attr}=\"#{value}\""
99
- string += ">"
100
- closer = '>'
101
- else # object
102
- string = JSON.stringify(arg)
103
- if string.length > maxLength
104
- string = "#{string.substr(0, maxLength)} …"
105
- string += closer
106
- string
107
-
108
- ###**
109
- See https://developer.mozilla.org/en-US/docs/Web/API/Console#Using_string_substitutions
110
-
111
- @function up.browser.sprintf
112
- @internal
113
- ###
114
- sprintf = (message, args...) ->
115
- sprintfWithFormattedArgs(u.identity, message, args...)
116
-
117
- ###**
118
- @function up.browser.sprintfWithFormattedArgs
119
- @internal
120
- ###
121
- sprintfWithFormattedArgs = (formatter, message, args...) ->
122
- return '' if u.isBlank(message)
123
-
124
- i = 0
125
- message.replace CONSOLE_PLACEHOLDERS, ->
126
- arg = args[i]
127
- arg = formatter(stringifyArg(arg))
128
- i += 1
129
- arg
130
-
131
- ###**
132
- Prints a debugging message to the browser console.
133
-
134
- @function up.log.debug
135
- @param {string} message
136
- @param {Array} ...args
137
- @internal
138
- ###
139
- debug = (message, args...) ->
140
- if config.enabled && message
141
- console.debug(prefix(message), args...)
142
-
143
- ###**
144
- Prints a logging message to the browser console.
145
-
146
- @function up.puts
147
- @param {string} message
148
- @param {Array} ...args
149
- @internal
150
- ###
151
- puts = (message, args...) ->
152
- if config.enabled && message
153
- console.log(prefix(message), args...)
154
-
155
- ###**
156
- @function up.warn
157
- @internal
158
- ###
159
- warn = (message, args...) ->
160
- if message
161
- console.warn(prefix(message), args...)
162
-
163
- ###**
164
- - Makes sure the group always closes
165
- - Does not make a group if the message is nil
166
-
167
- @function up.log.group
168
- @internal
169
- ###
170
- group = (message, args...) ->
171
- block = args.pop() # Coffeescript copies the arguments array
172
- if config.enabled && message
173
- fn = if config.collapse then 'groupCollapsed' else 'group'
174
- console[fn](prefix(message), args...)
175
- try
176
- block()
177
- finally
178
- console.groupEnd() if message
179
- else
180
- block()
181
-
182
- ###**
183
- @function up.log.error
184
- @internal
185
- ###
186
- error = (message, args...) ->
187
- if message
188
- console.error(prefix(message), args...)
189
-
190
- printBanner = ->
191
- # The ASCII art looks broken in code since we need to escape backslashes
192
- banner = " __ _____ ___ ___ / /_ __\n" +
193
- "/ // / _ \\/ _ \\/ _ \\/ / // / #{up.version}\n" +
194
- "\\___/_//_/ .__/\\___/_/\\_. / \n" +
195
- " / / / /\n" +
196
- "\n"
197
- if config.enabled
198
- banner += "Call `up.log.disable()` to disable logging for this session."
199
- else
200
- banner += "Call `up.log.enable()` to enable logging for this session."
201
- console.log(banner)
202
-
203
- up.on 'up:framework:booted', printBanner
204
- up.on 'up:framework:reset', reset
205
-
206
- setEnabled = (value) ->
207
- sessionStore.set('enabled', value)
208
- config.enabled = value
209
-
210
- ###**
211
- Makes future Unpoly events print vast amounts of debugging information to the developer console.
212
-
213
- Debugging information includes which elements are being [compiled](/up.syntax)
214
- and which [events](/up.event) are being emitted.
215
-
216
- @function up.log.enable
217
- @stable
218
- ###
219
- enable = ->
220
- setEnabled(true)
221
-
222
- ###**
223
- Prevents future Unpoly events from printing vast amounts of debugging information to the developer console.
224
-
225
- Errors will still be printed, even with logging disabled.
226
-
227
- @function up.log.disable
228
- @stable
229
- ###
230
- disable = ->
231
- setEnabled(false)
232
-
233
- puts: puts
234
- sprintf: sprintf
235
- sprintfWithFormattedArgs: sprintfWithFormattedArgs
236
- puts: puts
237
- debug: debug
238
- error: error
239
- warn: warn
240
- group: group
241
- config: config
242
- enable: enable
243
- disable: disable
244
- isEnabled: -> config.enabled
245
-
246
- up.puts = up.log.puts
247
- up.warn = up.log.warn
248
-
@@ -1,827 +0,0 @@
1
- ###**
2
- Modal dialogs
3
- =============
4
-
5
- Instead of [linking to a page fragment](/up.link), you can choose to show a fragment
6
- in a modal dialog. The existing page will remain open in the background.
7
-
8
- To open a modal, add an [`[up-modal]`](/a-up-modal) attribute to a link:
9
-
10
- <a href="/blogs" up-modal=".blog-list">Switch blog</a>
11
-
12
- When this link is clicked, Unpoly will request the path `/blogs` and extract
13
- an element matching the selector `.blog-list` from the response. The matching element
14
- will then be placed in a modal dialog.
15
-
16
-
17
- \#\#\# Closing behavior
18
-
19
- By default the dialog automatically closes
20
- *when a link inside a modal changes a fragment behind the modal*.
21
- This is useful to have the dialog interact with the page that
22
- opened it, e.g. by updating parts of a larger form.
23
-
24
- To disable this behavior, give the opening link an [`up-sticky`](/a-up-modal#up-sticky) attribute:
25
-
26
-
27
- \#\#\# Customizing the dialog design
28
-
29
- Dialogs have a minimal default design:
30
-
31
- - Contents are displayed in a white box with a subtle box shadow
32
- - The box will grow to fit the dialog contents, but never grow larger than the screen
33
- - The box is placed over a semi-transparent backdrop to dim the rest of the page
34
- - There is a button to close the dialog in the top-right corner
35
-
36
- The easiest way to change how the dialog looks is to override the
37
- [default CSS styles](https://github.com/unpoly/unpoly/blob/master/lib/assets/stylesheets/unpoly/modal.sass).
38
-
39
- By default the dialog uses the following DOM structure:
40
-
41
- <div class="up-modal">
42
- <div class="up-modal-backdrop">
43
- <div class="up-modal-viewport">
44
- <div class="up-modal-dialog">
45
- <div class="up-modal-content">
46
- <!-- the matching element will be placed here -->
47
- </div>
48
- <div class="up-modal-close" up-close>X</div>
49
- </div>
50
- </div>
51
- </div>
52
-
53
- You can change this structure by setting [`up.modal.config.template`](/up.modal.config#config.template) to a new template string
54
- or function.
55
-
56
-
57
- @module up.modal
58
- ###
59
- up.modal = do ->
60
-
61
- u = up.util
62
- e = up.element
63
-
64
- ###**
65
- Sets default options for future modals.
66
-
67
- @property up.modal.config
68
- @param {string} [config.history=true]
69
- Whether opening a modal will add a browser history entry.
70
- @param {number} [config.width]
71
- The width of the dialog as a CSS value like `'400px'` or `'50%'`.
72
-
73
- Defaults to `undefined`, meaning that the dialog will grow to fit its contents
74
- until it reaches `config.maxWidth`. Leaving this as `undefined` will
75
- also allow you to control the width using CSS on `.up-modal-dialog´.
76
- @param {number} [config.maxWidth]
77
- The width of the dialog as a CSS value like `'400px'` or `50%`.
78
- You can set this to `undefined` to make the dialog fit its contents.
79
- Be aware however, that e.g. Bootstrap stretches input elements
80
- to `width: 100%`, meaning the dialog will also stretch to the full
81
- width of the screen.
82
- @param {number} [config.height='auto']
83
- The height of the dialog in pixels.
84
- Defaults to `undefined`, meaning that the dialog will grow to fit its contents.
85
- @param {string|Function(config): string} [config.template]
86
- A string containing the HTML structure of the modal.
87
- You can supply an alternative template string, but make sure that it
88
- defines tag with the classes `up-modal`, `up-modal-dialog` and `up-modal-content`.
89
-
90
- You can also supply a function that returns a HTML string.
91
- The function will be called with the modal options (merged from these defaults
92
- and any per-open overrides) whenever a modal opens.
93
- @param {string} [config.closeLabel='×']
94
- The label of the button that closes the dialog.
95
- @param {boolean} [config.closable=true]
96
- When `true`, the modal will render a close icon and close when the user
97
- clicks on the backdrop or presses Escape.
98
-
99
- When `false`, you need to either supply an element with `[up-close]` or
100
- close the modal manually with `up.modal.close()`.
101
- @param {string} [config.openAnimation='fade-in']
102
- The animation used to open the viewport around the dialog.
103
- @param {string} [config.closeAnimation='fade-out']
104
- The animation used to close the viewport the dialog.
105
- @param {string} [config.backdropOpenAnimation='fade-in']
106
- The animation used to open the backdrop that dims the page below the dialog.
107
- @param {string} [config.backdropCloseAnimation='fade-out']
108
- The animation used to close the backdrop that dims the page below the dialog.
109
- @param {number} [config.openDuration]
110
- The duration of the open animation (in milliseconds).
111
- @param {number} [config.closeDuration]
112
- The duration of the close animation (in milliseconds).
113
- @param {string} [config.openEasing]
114
- The timing function controlling the acceleration of the opening animation.
115
- @param {string} [config.closeEasing]
116
- The timing function controlling the acceleration of the closing animation.
117
- @param {boolean} [options.sticky=false]
118
- If set to `true`, the modal remains
119
- open even it changes the page in the background.
120
- @param {string} [options.flavor='default']
121
- The default [flavor](/up.modal.flavors).
122
- @stable
123
- ###
124
- config = new up.Config
125
- maxWidth: null
126
- width: null
127
- height: null
128
- history: true
129
- openAnimation: 'fade-in'
130
- closeAnimation: 'fade-out'
131
- openDuration: null
132
- closeDuration: null
133
- openEasing: null
134
- closeEasing: null
135
- backdropOpenAnimation: 'fade-in'
136
- backdropCloseAnimation: 'fade-out'
137
- closeLabel: '×'
138
- closable: true
139
- sticky: false
140
- flavor: 'default'
141
- position: null
142
- template: (options) ->
143
- """
144
- <div class="up-modal">
145
- <div class="up-modal-backdrop"></div>
146
- <div class="up-modal-viewport">
147
- <div class="up-modal-dialog">
148
- <div class="up-modal-content"></div>
149
- <div class="up-modal-close" up-close>#{options.closeLabel}</div>
150
- </div>
151
- </div>
152
- </div>
153
- """
154
-
155
- ###**
156
- Define modal variants with their own default configuration, CSS or HTML template.
157
-
158
- \#\#\# Example
159
-
160
- Unpoly's [`[up-drawer]`](/a-up-drawer) is implemented as a modal flavor:
161
-
162
- up.modal.flavors.drawer = {
163
- openAnimation: 'move-from-right',
164
- closeAnimation: 'move-to-right'
165
- }
166
-
167
- Modals with that flavor will have a container with an `up-flavor` attribute:
168
-
169
- <div class='up-modal' up-flavor='drawer'>
170
- ...
171
- </div>
172
-
173
- We can target the `up-flavor` attribute to override the default dialog styles:
174
-
175
- .up-modal[up-flavor='drawer'] {
176
-
177
- .up-modal-dialog {
178
- margin: 0; // Remove margin so drawer starts at the screen edge
179
- max-width: 350px; // Set drawer size
180
- }
181
-
182
- .up-modal-content {
183
- min-height: 100vh; // Stretch background to full window height
184
- }
185
- }
186
-
187
- @property up.modal.flavors
188
- @param {Object} flavors
189
- An object where the keys are flavor names (e.g. `'drawer') and
190
- the values are the respective default configurations.
191
- @experimental
192
- ###
193
- flavors = new up.Config
194
- default: {}
195
-
196
- ###**
197
- Returns the source URL for the fragment displayed in the current modal overlay,
198
- or `undefined` if no modal is currently open.
199
-
200
- @function up.modal.url
201
- @return {string}
202
- the source URL
203
- @stable
204
- ###
205
-
206
- ###**
207
- Returns the URL of the page behind the modal overlay.
208
-
209
- @function up.modal.coveredUrl
210
- @return {string}
211
- @experimental
212
- ###
213
-
214
- state = new up.Config
215
- phase: 'closed' # can be 'opening', 'opened', 'closing' and 'closed'
216
- anchorElement: null # the element to which the tooltip is anchored
217
- modalElement: null # the modal container
218
- sticky: null
219
- closable: null
220
- flavor: null
221
- url: null
222
- coveredUrl: null
223
- coveredTitle: null
224
- position: null
225
-
226
- bodyShifter = new up.BodyShifter()
227
-
228
- chain = new up.DivertibleChain()
229
-
230
- reset = ->
231
- e.remove(state.modalElement) if state.modalElement
232
- bodyShifter.unshift()
233
- state.reset()
234
- chain.reset()
235
- config.reset()
236
- flavors.reset()
237
-
238
- templateHtml = ->
239
- template = flavorDefault('template')
240
- u.evalOption(template, closeLabel: flavorDefault('closeLabel'))
241
-
242
- discardHistory = ->
243
- state.coveredTitle = null
244
- state.coveredUrl = null
245
-
246
- part = (name) ->
247
- selector = ".up-modal-#{name}"
248
- state.modalElement.querySelector(selector)
249
-
250
- createHiddenFrame = (target, options) ->
251
- html = templateHtml()
252
- state.modalElement = modalElement = e.createFromHtml(html)
253
- modalElement.setAttribute('aria-modal', 'true') # tell modern screen readers to make all other elements inert
254
- modalElement.setAttribute('up-flavor', state.flavor)
255
- modalElement.setAttribute('up-position', state.position) if u.isPresent(state.position)
256
-
257
- dialogStyles = u.only(options, 'width', 'maxWidth', 'height')
258
- e.setStyle(part('dialog'), dialogStyles)
259
-
260
- unless state.closable
261
- closeElement = part('close')
262
- e.remove(closeElement)
263
-
264
- contentElement = part('content')
265
- # Create an empty element that will match the
266
- # selector that is being replaced.
267
- up.fragment.createPlaceholder(target, contentElement)
268
- e.hide(modalElement)
269
- document.body.appendChild(modalElement)
270
-
271
- unveilFrame = ->
272
- e.show(state.modalElement)
273
-
274
- ###**
275
- Returns whether a modal is currently open.
276
-
277
- This also returns `true` if the modal is in an opening or closing animation.
278
-
279
- @function up.modal.isOpen
280
- @return {boolean}
281
- @stable
282
- ###
283
- isOpen = ->
284
- state.phase == 'opened' || state.phase == 'opening'
285
-
286
- ###**
287
- Opens the given link's destination in a modal overlay:
288
-
289
- var link = document.querySelector('a')
290
- up.modal.follow(link)
291
-
292
- Any option attributes for [`a[up-modal]`](/a-up-modal) will be honored.
293
-
294
- Emits events [`up:modal:open`](/up:modal:open) and [`up:modal:opened`](/up:modal:opened).
295
-
296
- @function up.modal.follow
297
- @param {Element|jQuery|string} linkOrSelector
298
- The link to follow.
299
- @param {string} [options.target]
300
- The selector to extract from the response and open in a modal dialog.
301
- @param {number} [options.width]
302
- The width of the dialog in pixels.
303
- By [default](/up.modal.config) the dialog will grow to fit its contents.
304
- @param {number} [options.height]
305
- The width of the dialog in pixels.
306
- By [default](/up.modal.config) the dialog will grow to fit its contents.
307
- @param {boolean} [options.sticky=false]
308
- If set to `true`, the modal remains
309
- open even it changes the page in the background.
310
- @param {boolean} [config.closable=true]
311
- When `true`, the modal will render a close icon and close when the user
312
- clicks on the backdrop or presses Escape.
313
-
314
- When `false`, you need to either supply an element with `[up-close]` or
315
- close the modal manually with `up.modal.close()`.
316
- @param {string} [options.confirm]
317
- A message that will be displayed in a cancelable confirmation dialog
318
- before the modal is being opened.
319
- @param {string} [options.method="GET"]
320
- Override the request method.
321
- @param {boolean} [options.history=true]
322
- Whether to add a browser history entry for the modal's source URL.
323
- @param {string} [options.animation]
324
- The animation to use when opening the modal.
325
- @param {number} [options.duration]
326
- The duration of the animation. See [`up.animate()`](/up.animate).
327
- @param {number} [options.delay]
328
- The delay before the animation starts. See [`up.animate()`](/up.animate).
329
- @param {string} [options.easing]
330
- The timing function that controls the animation's acceleration. [`up.animate()`](/up.animate).
331
- @return {Promise}
332
- A promise that will be fulfilled when the modal has been loaded and
333
- the opening animation has completed.
334
- @stable
335
- ###
336
- followAsap = (linkOrSelector, options) ->
337
- options = u.options(options)
338
- options.link = e.get(linkOrSelector)
339
- openAsap(options)
340
-
341
- preloadNow = (link, options) ->
342
- options = u.options(options)
343
- options.link = link
344
- options.preload = true
345
- # Use openNow() and not openAsap() so (1) we don't close a currently open modal
346
- # and (2) our pending AJAX request does not prevent other modals from opening
347
- openNow(options)
348
-
349
- ###**
350
- Opens a modal for the given URL.
351
-
352
- \#\#\# Example
353
-
354
- up.modal.visit('/foo', { target: '.list' })
355
-
356
- This will request `/foo`, extract the `.list` selector from the response
357
- and open the selected container in a modal dialog.
358
-
359
- Emits events [`up:modal:open`](/up:modal:open) and [`up:modal:opened`](/up:modal:opened).
360
-
361
- @function up.modal.visit
362
- @param {string} url
363
- The URL to load.
364
- @param {string} options.target
365
- The CSS selector to extract from the response.
366
- The extracted content will be placed into the dialog window.
367
- @param {Object} options
368
- See options for [`up.modal.follow()`](/up.modal.follow).
369
- @return {Promise}
370
- A promise that will be fulfilled when the modal has been loaded and the opening
371
- animation has completed.
372
- @stable
373
- ###
374
- visitAsap = (url, options) ->
375
- options = u.options(options)
376
- options.url = url
377
- openAsap(options)
378
-
379
- ###**
380
- [Extracts](/up.extract) the given CSS selector from the given HTML string and
381
- opens the results in a modal.
382
-
383
- \#\#\# Example
384
-
385
- var html = 'before <div class="content">inner</div> after';
386
- up.modal.extract('.content', html)
387
-
388
- The would open a modal with the following contents:
389
-
390
- <div class="content">inner</div>
391
-
392
- Emits events [`up:modal:open`](/up:modal:open) and [`up:modal:opened`](/up:modal:opened).
393
-
394
- @function up.modal.extract
395
- @param {string} selector
396
- The CSS selector to extract from the HTML.
397
- @param {string} html
398
- The HTML containing the modal content.
399
- @param {Object} options
400
- See options for [`up.modal.follow()`](/up.modal.follow).
401
- @return {Promise}
402
- A promise that will be fulfilled when the modal has been opened and the opening
403
- animation has completed.
404
- @stable
405
- ###
406
- extractAsap = (selector, html, options) ->
407
- options = u.options(options)
408
- options.html = html
409
- options.history ?= false
410
- options.target = selector
411
- openAsap(options)
412
-
413
- openAsap = (options) ->
414
- chain.asap closeNow, (-> openNow(options))
415
-
416
- openNow = (options) ->
417
- options = u.options(options)
418
- link = u.pluckKey(options, 'link') || e.none()
419
- url = u.pluckKey(options, 'url') ? link.getAttribute('up-href') ? link.getAttribute('href')
420
- html = u.pluckKey(options, 'html')
421
- target = u.pluckKey(options, 'target') ? link.getAttribute('up-modal')
422
- validateTarget(target)
423
- options.flavor ?= link.getAttribute('up-flavor') ? config.flavor
424
- options.position ?= link.getAttribute('up-position') ? flavorDefault('position', options.flavor)
425
- options.position = u.evalOption(options.position, { link })
426
- options.width ?= link.getAttribute('up-width') ? flavorDefault('width', options.flavor)
427
- options.maxWidth ?= link.getAttribute('up-max-width') ? flavorDefault('maxWidth', options.flavor)
428
- options.height ?= link.getAttribute('up-height') ? flavorDefault('height')
429
- options.animation ?= link.getAttribute('up-animation') ? flavorDefault('openAnimation', options.flavor)
430
- options.animation = u.evalOption(options.animation, position: options.position)
431
- options.backdropAnimation ?= link.getAttribute('up-backdrop-animation') ? flavorDefault('backdropOpenAnimation', options.flavor)
432
- options.backdropAnimation = u.evalOption(options.backdropAnimation, position: options.position)
433
- options.sticky ?= e.booleanAttr(link, 'up-sticky') ? flavorDefault('sticky', options.flavor)
434
- options.closable ?= e.booleanAttr(link, 'up-closable') ? flavorDefault('closable', options.flavor)
435
- options.confirm ?= link.getAttribute('up-confirm')
436
- options.method = up.link.followMethod(link, options)
437
- options.layer = 'modal'
438
- options.failTarget ?= link.getAttribute('up-fail-target')
439
- options.failLayer ?= link.getAttribute('up-fail-layer') ? 'auto'
440
- options.cache ?= e.booleanAttr(link, 'up-cache')
441
-
442
- animateOptions = up.motion.animateOptions(options, link, duration: flavorDefault('openDuration', options.flavor), easing: flavorDefault('openEasing', options.flavor))
443
-
444
- # Although we usually fall back to full page loads if a browser doesn't support pushState,
445
- # in the case of modals we assume that the developer would rather see a dialog
446
- # without an URL update.
447
- options.history ?= e.booleanOrStringAttr(link, 'up-history') ? flavorDefault('history', options.flavor)
448
- options.history = false unless up.browser.canPushState()
449
-
450
- # This will prevent up.replace() from looking for fallbacks, since
451
- # it knows the target will always exist.
452
- options.provideTarget = -> createHiddenFrame(target, options)
453
-
454
- if options.preload
455
- return up.replace(target, url, options)
456
-
457
- up.browser.whenConfirmed(options).then ->
458
- up.event.whenEmitted('up:modal:open', url: url, log: 'Opening modal').then ->
459
- state.phase = 'opening'
460
- state.flavor = options.flavor
461
- state.sticky = options.sticky
462
- state.closable = options.closable
463
- state.position = options.position
464
- if options.history
465
- state.coveredUrl = up.browser.url()
466
- state.coveredTitle = document.title
467
- extractOptions = u.merge(options, animation: false)
468
- if html
469
- promise = up.extract(target, html, extractOptions)
470
- else
471
- promise = up.replace(target, url, extractOptions)
472
- promise = promise.then ->
473
- bodyShifter.shift()
474
- unveilFrame()
475
- animate(options.animation, options.backdropAnimation, animateOptions)
476
- promise = promise.then ->
477
- state.phase = 'opened'
478
- up.emit('up:modal:opened', log: 'Modal opened')
479
- promise
480
-
481
- validateTarget = (target) ->
482
- if u.isBlank(target)
483
- up.fail('Cannot open a modal without a target selector')
484
- else if target == 'body'
485
- up.fail('Cannot open the <body> in a modal')
486
-
487
- ###**
488
- This event is [emitted](/up.emit) when a modal dialog is starting to open.
489
-
490
- @event up:modal:open
491
- @param event.preventDefault()
492
- Event listeners may call this method to prevent the modal from opening.
493
- @stable
494
- ###
495
-
496
- ###**
497
- This event is [emitted](/up.emit) when a modal dialog has finished opening.
498
-
499
- @event up:modal:opened
500
- @stable
501
- ###
502
-
503
- ###**
504
- Closes a currently opened modal overlay.
505
-
506
- Does nothing if no modal is currently open.
507
-
508
- Emits events [`up:modal:close`](/up:modal:close) and [`up:modal:closed`](/up:modal:closed).
509
-
510
- @function up.modal.close
511
- @param {Object} options
512
- See options for [`up.animate()`](/up.animate)
513
- @return {Promise}
514
- A promise that will be fulfilled once the modal's close
515
- animation has finished.
516
- @stable
517
- ###
518
- closeAsap = (options) ->
519
- chain.asap -> closeNow(options)
520
-
521
- closeNow = (options) ->
522
- options = u.options(options)
523
-
524
- unless isOpen()
525
- return Promise.resolve()
526
-
527
- viewportCloseAnimation = options.animation ? flavorDefault('closeAnimation')
528
- viewportCloseAnimation = u.evalOption(viewportCloseAnimation, position: state.position)
529
- backdropCloseAnimation = options.backdropAnimation ? flavorDefault('backdropCloseAnimation')
530
- backdropCloseAnimation = u.evalOption(backdropCloseAnimation, position: state.position)
531
- animateOptions = up.motion.animateOptions(options, duration: flavorDefault('closeDuration'), easing: flavorDefault('closeEasing'))
532
-
533
- destroyOptions = u.options(
534
- u.except(options, 'animation', 'duration', 'easing', 'delay'),
535
- history: state.coveredUrl,
536
- title: state.coveredTitle
537
- )
538
-
539
- up.event.whenEmitted(state.modalElement, 'up:modal:close', log: 'Closing modal').then ->
540
- state.phase = 'closing'
541
- # the current URL must be deleted *before* calling up.destroy,
542
- # since up.feedback listens to up:fragment:destroyed and then
543
- # re-assigns .up-current classes.
544
- state.url = null
545
- state.coveredUrl = null
546
- state.coveredTitle = null
547
-
548
- promise = animate(viewportCloseAnimation, backdropCloseAnimation, animateOptions)
549
-
550
- promise = promise.then ->
551
- up.destroy(state.modalElement, destroyOptions)
552
-
553
- promise = promise.then ->
554
- bodyShifter.unshift()
555
- state.phase = 'closed'
556
- state.modalElement = null
557
- state.flavor = null
558
- state.sticky = null
559
- state.closable = null
560
- state.position = null
561
- up.emit('up:modal:closed', log: 'Modal closed')
562
-
563
- promise
564
-
565
- markAsAnimating = (isAnimating = true) ->
566
- e.toggleClass(state.modalElement, 'up-modal-animating', isAnimating)
567
-
568
- animate = (viewportAnimation, backdropAnimation, animateOptions) ->
569
- # If we're not animating the dialog, don't animate the backdrop either
570
- if up.motion.isNone(viewportAnimation)
571
- Promise.resolve()
572
- else
573
- markAsAnimating()
574
-
575
- promise = Promise.all([
576
- up.animate(part('viewport'), viewportAnimation, animateOptions),
577
- up.animate(part('backdrop'), backdropAnimation, animateOptions)
578
- ])
579
- promise = promise.then -> markAsAnimating(false)
580
- promise
581
-
582
- ###**
583
- This event is [emitted](/up.emit) when a modal dialog
584
- is starting to [close](/up.modal.close).
585
-
586
- @event up:modal:close
587
- @param event.preventDefault()
588
- Event listeners may call this method to prevent the modal from closing.
589
- @stable
590
- ###
591
-
592
- ###**
593
- This event is [emitted](/up.emit) when a modal dialog
594
- is done [closing](/up.modal.close).
595
-
596
- @event up:modal:closed
597
- @stable
598
- ###
599
-
600
- autoclose = ->
601
- unless state.sticky
602
- discardHistory()
603
- closeAsap()
604
-
605
- ###**
606
- Returns whether the given element or selector is contained
607
- within the current modal.
608
-
609
- @function up.modal.contains
610
- @param {string} elementOrSelector
611
- The element to test
612
- @return {boolean}
613
- @stable
614
- ###
615
- contains = (elementOrSelector) ->
616
- element = e.get(elementOrSelector)
617
- !!e.closest(element, '.up-modal')
618
-
619
- flavor = (name, overrideConfig = {}) ->
620
- up.legacy.warn('up.modal.flavor() is deprecated. Use the up.modal.flavors property instead.')
621
- u.assign(flavorOverrides(name), overrideConfig)
622
-
623
- ###**
624
- Returns a config object for the given flavor.
625
- Properties in that config should be preferred to the defaults in
626
- [`/up.modal.config`](/up.modal.config).
627
-
628
- @function flavorOverrides
629
- @internal
630
- ###
631
- flavorOverrides = (flavor) ->
632
- flavors[flavor] ||= {}
633
-
634
- ###**
635
- Returns the config option for the current flavor.
636
-
637
- @function flavorDefault
638
- @internal
639
- ###
640
- flavorDefault = (key, flavorName = state.flavor) ->
641
- value = flavorOverrides(flavorName)[key] if flavorName
642
- value = config[key] if u.isMissing(value)
643
- value
644
-
645
- ###**
646
- Clicking this link will load the destination via AJAX and open
647
- the given selector in a modal dialog.
648
-
649
- \#\#\# Example
650
-
651
- <a href="/blogs" up-modal=".blog-list">Switch blog</a>
652
-
653
- Clicking would request the path `/blog` and select `.blog-list` from
654
- the HTML response. Unpoly will dim the page
655
- and place the matching `.blog-list` tag in
656
- a modal dialog.
657
-
658
- @selector a[up-modal]
659
- @param {string} up-modal
660
- The CSS selector that will be extracted from the response and displayed in a modal dialog.
661
- @param {string} [up-confirm]
662
- A message that will be displayed in a cancelable confirmation dialog
663
- before the modal is opened.
664
- @param {string} [up-method='GET']
665
- Override the request method.
666
- @param {string} [up-sticky]
667
- If set to `"true"`, the modal remains
668
- open even if the page changes in the background.
669
- @param {boolean} [up-closable]
670
- When `true`, the modal will render a close icon and close when the user
671
- clicks on the backdrop or presses Escape.
672
-
673
- When `false`, you need to either supply an element with `[up-close]` or
674
- close the modal manually with `up.modal.close()`.
675
- @param {string} [up-animation]
676
- The animation to use when opening the viewport containing the dialog.
677
- @param {string} [up-backdrop-animation]
678
- The animation to use when opening the backdrop that dims the page below the dialog.
679
- @param {string} [up-height]
680
- The width of the dialog in pixels.
681
- By [default](/up.modal.config) the dialog will grow to fit its contents.
682
- @param {string} [up-width]
683
- The width of the dialog in pixels.
684
- By [default](/up.modal.config) the dialog will grow to fit its contents.
685
- @param {string} [up-history]
686
- Whether to push an entry to the browser history for the modal's source URL.
687
-
688
- Set this to `'false'` to prevent the URL bar from being updated.
689
- Set this to a URL string to update the history with the given URL.
690
-
691
- @stable
692
- ###
693
- up.link.addFollowVariant '[up-modal]',
694
- # Don't just pass the `follow` function reference so we can stub it in tests
695
- follow: (link, options) -> followAsap(link, options)
696
- preload: (link, options) -> preloadNow(link, options)
697
-
698
- # Close the modal when someone clicks outside the dialog (but not on a modal opener).
699
- # We register the event on .up-modal, which covers the *entire* viewport, not just
700
- # the dialog area.
701
- #
702
- # Note that we cannot listen to clicks on .up-modal-backdrop, which is a sister element
703
- # of .up-modal-viewport. Since the user will effectively click on the viewport, not
704
- # the backdrop, backdrop will not receive a bubbling event.
705
- up.on('click', '.up-modal', (event) ->
706
- return unless state.closable
707
-
708
- target = event.target
709
- unless e.closest(target, '.up-modal-dialog') || e.closest(target, '[up-modal]')
710
- up.event.consumeAction(event)
711
- u.muteRejection closeAsap()
712
- )
713
-
714
- up.on('up:fragment:inserted', (event, fragment) ->
715
- if contains(fragment)
716
- if newSource = fragment.getAttribute('up-source')
717
- state.url = newSource
718
- else if event.origin && contains(event.origin) && !up.popup.contains(fragment)
719
- u.muteRejection autoclose()
720
- )
721
-
722
- # Close the pop-up overlay when the user presses ESC.
723
- up.event.onEscape ->
724
- if state.closable
725
- u.muteRejection closeAsap()
726
-
727
- ###**
728
- When this element is clicked, closes a currently open dialog.
729
-
730
- Does nothing if no modal is currently open.
731
-
732
- To make a link that closes the current modal, but follows to
733
- a fallback destination if no modal is open:
734
-
735
- <a href="/fallback" up-close>Okay</a>
736
-
737
- @selector .up-modal [up-close]
738
- @stable
739
- ###
740
- up.on('click', '.up-modal [up-close]', (event) ->
741
- u.muteRejection closeAsap()
742
- # If the user closes the modal by clicking on the background, we want to halt the event chain here.
743
- # The event should not trigger anything else. The user needs to click again for another interaction.
744
- # Also only prevent the default when we actually closed a modal.
745
- # This way we can have buttons that close a modal when within a modal, but link to a destination if not.
746
- up.event.consumeAction(event)
747
- )
748
-
749
- ###**
750
- Clicking this link will load the destination via AJAX and open
751
- the given selector in a modal drawer that slides in from the edge of the screen.
752
-
753
- You can configure drawers using the [`up.modal.flavors.drawer`](/up.modal.flavors.drawer) property.
754
-
755
- \#\#\# Example
756
-
757
- <a href="/blogs" up-drawer=".blog-list">Switch blog</a>
758
-
759
- Clicking would request the path `/blog` and select `.blog-list` from
760
- the HTML response. Unpoly will dim the page
761
- and place the matching `.blog-list` tag will be placed in
762
- a modal drawer.
763
-
764
- @selector a[up-drawer]
765
- @param {string} up-drawer
766
- The CSS selector to extract from the response and open in the drawer.
767
- @param {string} [up-position='auto']
768
- The side from which the drawer slides in.
769
-
770
- Valid values are `'left'`, `'right'` and `'auto'`. If set to `'auto'`, the
771
- drawer will slide in from left if the opening link is on the left half of the screen.
772
- Otherwise it will slide in from the right.
773
- @stable
774
- ###
775
- up.macro 'a[up-drawer], [up-href][up-drawer]', (link) ->
776
- target = link.getAttribute('up-drawer')
777
- e.setAttrs link,
778
- 'up-modal': target
779
- 'up-flavor': 'drawer'
780
-
781
- ###**
782
- Sets default options for future drawers.
783
-
784
- @property up.modal.flavors.drawer
785
- @param {Object} config
786
- Default options for future drawers.
787
-
788
- See [`up.modal.config`](/up.modal.config) for available options.
789
- @experimental
790
- ###
791
- flavors.drawer =
792
- openAnimation: (options) ->
793
- switch options.position
794
- when 'left' then 'move-from-left'
795
- when 'right' then 'move-from-right'
796
- closeAnimation: (options) ->
797
- switch options.position
798
- when 'left' then 'move-to-left'
799
- when 'right' then 'move-to-right'
800
- position: (options) ->
801
- if u.isPresent(options.link)
802
- u.horizontalScreenHalf(options.link)
803
- else
804
- # In case the drawer was opened programmatically through Javascript,
805
- # we might now know the link that was clicked on.
806
- 'left'
807
-
808
- # When the user uses the back button we will usually restore <body> or a base container.
809
- # We close any open modal because it probably won't match the restored state.
810
- up.on 'up:history:restore', ->
811
- u.muteRejection closeAsap()
812
-
813
- # The framework is reset between tests
814
- up.on 'up:framework:reset', reset
815
-
816
- <% if ENV['JS_KNIFE'] %>knife: eval(Knife.point)<% end %>
817
- visit: visitAsap
818
- follow: followAsap
819
- extract: extractAsap
820
- close: closeAsap
821
- url: -> state.url
822
- coveredUrl: -> state.coveredUrl
823
- config: config
824
- flavors: flavors
825
- contains: contains
826
- isOpen: isOpen
827
- flavor: flavor # deprecated