unpoly-rails 1.0.3 → 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 (344) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -1
  3. data/CHANGELOG.md +43 -25
  4. data/README.md +5 -6
  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 +15376 -10484
  22. data/dist/unpoly.min.css +1 -1
  23. data/dist/unpoly.min.js +6 -4
  24. data/lib/unpoly/rails/change/cache.rb +26 -0
  25. data/lib/unpoly/rails/change/context.rb +80 -0
  26. data/lib/unpoly/rails/change/field.rb +117 -0
  27. data/lib/unpoly/rails/change/field_definition.rb +74 -0
  28. data/lib/unpoly/rails/change/layer.rb +60 -0
  29. data/lib/unpoly/rails/change.rb +372 -0
  30. data/lib/unpoly/rails/controller.rb +47 -0
  31. data/lib/unpoly/rails/error.rb +5 -0
  32. data/lib/unpoly/rails/request_echo_headers.rb +2 -2
  33. data/lib/unpoly/rails/version.rb +1 -1
  34. data/lib/unpoly/tasks.rb +45 -0
  35. data/lib/unpoly-rails.rb +9 -3
  36. metadata +42 -316
  37. data/.gitignore +0 -10
  38. data/.ruby-version +0 -1
  39. data/Gemfile +0 -7
  40. data/Gemfile.lock +0 -39
  41. data/Rakefile +0 -154
  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/browser.coffee.erb +0 -240
  60. data/lib/assets/javascripts/unpoly/classes/body_shifter.coffee +0 -45
  61. data/lib/assets/javascripts/unpoly/classes/cache.coffee +0 -127
  62. data/lib/assets/javascripts/unpoly/classes/compile_pass.coffee +0 -93
  63. data/lib/assets/javascripts/unpoly/classes/config.coffee +0 -9
  64. data/lib/assets/javascripts/unpoly/classes/css_transition.coffee +0 -118
  65. data/lib/assets/javascripts/unpoly/classes/divertible_chain.coffee +0 -39
  66. data/lib/assets/javascripts/unpoly/classes/event_listener.coffee +0 -116
  67. data/lib/assets/javascripts/unpoly/classes/extract_cascade.coffee +0 -86
  68. data/lib/assets/javascripts/unpoly/classes/extract_plan.coffee +0 -111
  69. data/lib/assets/javascripts/unpoly/classes/field_observer.coffee +0 -80
  70. data/lib/assets/javascripts/unpoly/classes/focus_follower.coffee +0 -29
  71. data/lib/assets/javascripts/unpoly/classes/follow_variant.coffee +0 -64
  72. data/lib/assets/javascripts/unpoly/classes/html_parser.coffee +0 -46
  73. data/lib/assets/javascripts/unpoly/classes/motion_controller.coffee +0 -157
  74. data/lib/assets/javascripts/unpoly/classes/params.coffee.erb +0 -544
  75. data/lib/assets/javascripts/unpoly/classes/record.coffee +0 -22
  76. data/lib/assets/javascripts/unpoly/classes/rect.js +0 -21
  77. data/lib/assets/javascripts/unpoly/classes/request.coffee +0 -247
  78. data/lib/assets/javascripts/unpoly/classes/response.coffee +0 -157
  79. data/lib/assets/javascripts/unpoly/classes/reveal_motion.coffee +0 -102
  80. data/lib/assets/javascripts/unpoly/classes/scroll_motion.coffee +0 -67
  81. data/lib/assets/javascripts/unpoly/classes/selector.coffee +0 -60
  82. data/lib/assets/javascripts/unpoly/classes/store/memory.coffee +0 -26
  83. data/lib/assets/javascripts/unpoly/classes/store/session.coffee +0 -59
  84. data/lib/assets/javascripts/unpoly/classes/tether.coffee +0 -105
  85. data/lib/assets/javascripts/unpoly/classes/url_set.coffee +0 -32
  86. data/lib/assets/javascripts/unpoly/cookie.coffee +0 -56
  87. data/lib/assets/javascripts/unpoly/element.coffee.erb +0 -1129
  88. data/lib/assets/javascripts/unpoly/event.coffee.erb +0 -445
  89. data/lib/assets/javascripts/unpoly/feedback.coffee +0 -353
  90. data/lib/assets/javascripts/unpoly/form.coffee.erb +0 -1084
  91. data/lib/assets/javascripts/unpoly/fragment.coffee.erb +0 -928
  92. data/lib/assets/javascripts/unpoly/framework.coffee +0 -65
  93. data/lib/assets/javascripts/unpoly/history.coffee +0 -268
  94. data/lib/assets/javascripts/unpoly/legacy.coffee +0 -60
  95. data/lib/assets/javascripts/unpoly/link.coffee.erb +0 -622
  96. data/lib/assets/javascripts/unpoly/log.coffee +0 -253
  97. data/lib/assets/javascripts/unpoly/modal.coffee.erb +0 -827
  98. data/lib/assets/javascripts/unpoly/motion.coffee.erb +0 -668
  99. data/lib/assets/javascripts/unpoly/namespace.coffee.erb +0 -5
  100. data/lib/assets/javascripts/unpoly/popup.coffee.erb +0 -515
  101. data/lib/assets/javascripts/unpoly/protocol.coffee +0 -300
  102. data/lib/assets/javascripts/unpoly/proxy.coffee +0 -672
  103. data/lib/assets/javascripts/unpoly/radio.coffee +0 -60
  104. data/lib/assets/javascripts/unpoly/rails.coffee +0 -24
  105. data/lib/assets/javascripts/unpoly/syntax.coffee.erb +0 -476
  106. data/lib/assets/javascripts/unpoly/toast.coffee +0 -67
  107. data/lib/assets/javascripts/unpoly/tooltip.coffee +0 -276
  108. data/lib/assets/javascripts/unpoly/util.coffee.erb +0 -1677
  109. data/lib/assets/javascripts/unpoly/viewport.coffee.erb +0 -830
  110. data/lib/assets/javascripts/unpoly-bootstrap3/feedback-ext.coffee +0 -5
  111. data/lib/assets/javascripts/unpoly-bootstrap3/form-ext.coffee +0 -1
  112. data/lib/assets/javascripts/unpoly-bootstrap3/modal-ext.coffee +0 -14
  113. data/lib/assets/javascripts/unpoly-bootstrap3/viewport-ext.coffee +0 -5
  114. data/lib/assets/javascripts/unpoly-bootstrap3.coffee +0 -2
  115. data/lib/assets/javascripts/unpoly.coffee +0 -28
  116. data/lib/assets/stylesheets/unpoly/close.sass +0 -2
  117. data/lib/assets/stylesheets/unpoly/dom.sass +0 -5
  118. data/lib/assets/stylesheets/unpoly/layout.sass +0 -2
  119. data/lib/assets/stylesheets/unpoly/link.sass +0 -2
  120. data/lib/assets/stylesheets/unpoly/modal.sass +0 -116
  121. data/lib/assets/stylesheets/unpoly/popup.sass +0 -7
  122. data/lib/assets/stylesheets/unpoly/toast.sass +0 -33
  123. data/lib/assets/stylesheets/unpoly/tooltip.sass +0 -62
  124. data/lib/assets/stylesheets/unpoly-bootstrap3/modal-ext.sass +0 -27
  125. data/lib/assets/stylesheets/unpoly-bootstrap3.sass +0 -1
  126. data/lib/assets/stylesheets/unpoly.sass +0 -1
  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 -29
  134. data/spec_app/Gemfile.lock +0 -223
  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 -5
  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/boot_test_controller.rb +0 -31
  150. data/spec_app/app/controllers/compiler_test_controller.rb +0 -5
  151. data/spec_app/app/controllers/css_test_controller.rb +0 -5
  152. data/spec_app/app/controllers/error_test_controller.rb +0 -5
  153. data/spec_app/app/controllers/form_test/basics_controller.rb +0 -14
  154. data/spec_app/app/controllers/form_test/redirects_controller.rb +0 -17
  155. data/spec_app/app/controllers/form_test/uploads_controller.rb +0 -15
  156. data/spec_app/app/controllers/hash_test_controller.rb +0 -5
  157. data/spec_app/app/controllers/method_test_controller.rb +0 -16
  158. data/spec_app/app/controllers/motion_test_controller.rb +0 -5
  159. data/spec_app/app/controllers/pages_controller.rb +0 -17
  160. data/spec_app/app/controllers/replace_test_controller.rb +0 -5
  161. data/spec_app/app/controllers/reveal_test_controller.rb +0 -5
  162. data/spec_app/app/controllers/scroll_test_controller.rb +0 -5
  163. data/spec_app/app/helpers/application_helper.rb +0 -11
  164. data/spec_app/app/mailers/.keep +0 -0
  165. data/spec_app/app/models/concerns/.keep +0 -0
  166. data/spec_app/app/views/boot_test/defer.erb +0 -18
  167. data/spec_app/app/views/boot_test/module.erb +0 -18
  168. data/spec_app/app/views/boot_test/sync.erb +0 -17
  169. data/spec_app/app/views/compiler_test/timestamp.erb +0 -10
  170. data/spec_app/app/views/css_test/modal.erb +0 -47
  171. data/spec_app/app/views/css_test/modal_contents.erb +0 -5
  172. data/spec_app/app/views/css_test/modal_contents_wide.erb +0 -5
  173. data/spec_app/app/views/css_test/popup.erb +0 -81
  174. data/spec_app/app/views/css_test/popup_contents.erb +0 -5
  175. data/spec_app/app/views/css_test/tooltip.erb +0 -48
  176. data/spec_app/app/views/error_test/trigger.erb +0 -80
  177. data/spec_app/app/views/error_test/unexpected_response.erb +0 -3
  178. data/spec_app/app/views/form_test/basics/new.erb +0 -60
  179. data/spec_app/app/views/form_test/redirects/new.erb +0 -27
  180. data/spec_app/app/views/form_test/redirects/target.erb +0 -6
  181. data/spec_app/app/views/form_test/submission_result.erb +0 -30
  182. data/spec_app/app/views/form_test/uploads/new.erb +0 -44
  183. data/spec_app/app/views/hash_test/unpoly.erb +0 -30
  184. data/spec_app/app/views/hash_test/vanilla.erb +0 -13
  185. data/spec_app/app/views/layouts/integration_test.erb +0 -22
  186. data/spec_app/app/views/layouts/jasmine_rails/spec_runner.html.erb +0 -20
  187. data/spec_app/app/views/method_test/form_target.erb +0 -17
  188. data/spec_app/app/views/method_test/page1.erb +0 -11
  189. data/spec_app/app/views/method_test/page2.erb +0 -6
  190. data/spec_app/app/views/motion_test/animations.erb +0 -16
  191. data/spec_app/app/views/motion_test/transitions.erb +0 -13
  192. data/spec_app/app/views/pages/start.erb +0 -82
  193. data/spec_app/app/views/replace_test/_nav.erb +0 -6
  194. data/spec_app/app/views/replace_test/page1.erb +0 -14
  195. data/spec_app/app/views/replace_test/page2.erb +0 -14
  196. data/spec_app/app/views/replace_test/table.erb +0 -16
  197. data/spec_app/app/views/reveal_test/long1.erb +0 -17
  198. data/spec_app/app/views/reveal_test/long2.erb +0 -17
  199. data/spec_app/app/views/reveal_test/within_document_viewport.erb +0 -24
  200. data/spec_app/app/views/reveal_test/within_overflowing_div_viewport.erb +0 -28
  201. data/spec_app/app/views/scroll_test/long1.erb +0 -30
  202. data/spec_app/bin/bundle +0 -3
  203. data/spec_app/bin/rails +0 -8
  204. data/spec_app/bin/rake +0 -8
  205. data/spec_app/bin/setup +0 -29
  206. data/spec_app/bin/spring +0 -18
  207. data/spec_app/config/application.rb +0 -28
  208. data/spec_app/config/boot.rb +0 -3
  209. data/spec_app/config/database.yml +0 -25
  210. data/spec_app/config/environment.rb +0 -5
  211. data/spec_app/config/environments/development.rb +0 -41
  212. data/spec_app/config/environments/production.rb +0 -79
  213. data/spec_app/config/environments/test.rb +0 -42
  214. data/spec_app/config/initializers/assets.rb +0 -19
  215. data/spec_app/config/initializers/backtrace_silencers.rb +0 -7
  216. data/spec_app/config/initializers/bower_rails.rb +0 -16
  217. data/spec_app/config/initializers/cookies_serializer.rb +0 -3
  218. data/spec_app/config/initializers/filter_parameter_logging.rb +0 -4
  219. data/spec_app/config/initializers/inflections.rb +0 -16
  220. data/spec_app/config/initializers/mime_types.rb +0 -4
  221. data/spec_app/config/initializers/session_store.rb +0 -3
  222. data/spec_app/config/initializers/wrap_parameters.rb +0 -14
  223. data/spec_app/config/locales/en.yml +0 -23
  224. data/spec_app/config/routes.rb +0 -33
  225. data/spec_app/config/secrets.yml +0 -22
  226. data/spec_app/config.ru +0 -4
  227. data/spec_app/db/schema.rb +0 -23
  228. data/spec_app/db/seeds.rb +0 -7
  229. data/spec_app/lib/assets/.keep +0 -0
  230. data/spec_app/lib/tasks/.keep +0 -0
  231. data/spec_app/lib/tasks/cucumber.rake +0 -65
  232. data/spec_app/log/.keep +0 -0
  233. data/spec_app/public/404.html +0 -67
  234. data/spec_app/public/422.html +0 -67
  235. data/spec_app/public/500.html +0 -66
  236. data/spec_app/public/favicon.ico +0 -0
  237. data/spec_app/public/robots.txt +0 -5
  238. data/spec_app/script/cucumber +0 -10
  239. data/spec_app/spec/controllers/binding_test_controller_spec.rb +0 -248
  240. data/spec_app/spec/javascripts/helpers/agent_detector.coffee +0 -20
  241. data/spec_app/spec/javascripts/helpers/async_sequence.js.coffee +0 -103
  242. data/spec_app/spec/javascripts/helpers/browser_switches.js.coffee +0 -21
  243. data/spec_app/spec/javascripts/helpers/enable_logging.js.coffee +0 -2
  244. data/spec_app/spec/javascripts/helpers/fixture.js.coffee +0 -25
  245. data/spec_app/spec/javascripts/helpers/index.js.coffee +0 -1
  246. data/spec_app/spec/javascripts/helpers/jquery_no_conflict.js +0 -1
  247. data/spec_app/spec/javascripts/helpers/knife.js.coffee +0 -69
  248. data/spec_app/spec/javascripts/helpers/last_request.js.coffee +0 -25
  249. data/spec_app/spec/javascripts/helpers/mock_ajax.js.coffee +0 -8
  250. data/spec_app/spec/javascripts/helpers/mock_clock.js.coffee +0 -2
  251. data/spec_app/spec/javascripts/helpers/parse_form_data.js.coffee +0 -24
  252. data/spec_app/spec/javascripts/helpers/promise_state.js +0 -18
  253. data/spec_app/spec/javascripts/helpers/protect_jasmine_runner.coffee +0 -12
  254. data/spec_app/spec/javascripts/helpers/remove_body_margin.js.coffee +0 -8
  255. data/spec_app/spec/javascripts/helpers/reset_history.js.coffee +0 -23
  256. data/spec_app/spec/javascripts/helpers/reset_knife.js.coffee +0 -2
  257. data/spec_app/spec/javascripts/helpers/reset_up.js.coffee +0 -25
  258. data/spec_app/spec/javascripts/helpers/restore_body_scroll.js.coffee +0 -5
  259. data/spec_app/spec/javascripts/helpers/show_lib_versions.coffee +0 -12
  260. data/spec_app/spec/javascripts/helpers/spec_util.coffee +0 -47
  261. data/spec_app/spec/javascripts/helpers/to_be_around.js.coffee +0 -8
  262. data/spec_app/spec/javascripts/helpers/to_be_array.coffee +0 -5
  263. data/spec_app/spec/javascripts/helpers/to_be_attached.coffee +0 -9
  264. data/spec_app/spec/javascripts/helpers/to_be_blank.js.coffee +0 -8
  265. data/spec_app/spec/javascripts/helpers/to_be_detached.coffee +0 -9
  266. data/spec_app/spec/javascripts/helpers/to_be_element.js.coffee +0 -8
  267. data/spec_app/spec/javascripts/helpers/to_be_error.coffee +0 -8
  268. data/spec_app/spec/javascripts/helpers/to_be_given.js.coffee +0 -8
  269. data/spec_app/spec/javascripts/helpers/to_be_hidden.js.coffee +0 -8
  270. data/spec_app/spec/javascripts/helpers/to_be_jquery.js.coffee +0 -5
  271. data/spec_app/spec/javascripts/helpers/to_be_missing.js.coffee +0 -8
  272. data/spec_app/spec/javascripts/helpers/to_be_present.js.coffee +0 -8
  273. data/spec_app/spec/javascripts/helpers/to_be_scrolled_to.coffee +0 -11
  274. data/spec_app/spec/javascripts/helpers/to_be_visible.js.coffee +0 -9
  275. data/spec_app/spec/javascripts/helpers/to_contain.js.coffee +0 -8
  276. data/spec_app/spec/javascripts/helpers/to_end_with.js.coffee +0 -11
  277. data/spec_app/spec/javascripts/helpers/to_equal_jquery.js.coffee +0 -8
  278. data/spec_app/spec/javascripts/helpers/to_equal_node_list.coffee +0 -7
  279. data/spec_app/spec/javascripts/helpers/to_equal_via_is_equal.js.coffee +0 -7
  280. data/spec_app/spec/javascripts/helpers/to_have_class.js.coffee +0 -10
  281. data/spec_app/spec/javascripts/helpers/to_have_descendant.js.coffee +0 -10
  282. data/spec_app/spec/javascripts/helpers/to_have_length.js.coffee +0 -8
  283. data/spec_app/spec/javascripts/helpers/to_have_opacity.coffee +0 -15
  284. data/spec_app/spec/javascripts/helpers/to_have_own_property.js.coffee +0 -8
  285. data/spec_app/spec/javascripts/helpers/to_have_request_method.js.coffee +0 -16
  286. data/spec_app/spec/javascripts/helpers/to_have_text.js.coffee +0 -9
  287. data/spec_app/spec/javascripts/helpers/to_have_unhandled_rejections.coffee +0 -18
  288. data/spec_app/spec/javascripts/helpers/to_match_list.coffee +0 -14
  289. data/spec_app/spec/javascripts/helpers/to_match_selector.coffee +0 -8
  290. data/spec_app/spec/javascripts/helpers/to_match_text.js.coffee +0 -13
  291. data/spec_app/spec/javascripts/helpers/to_match_url.coffee +0 -14
  292. data/spec_app/spec/javascripts/helpers/trigger.js.coffee +0 -200
  293. data/spec_app/spec/javascripts/helpers/wait_until_dom_ready.js.coffee +0 -5
  294. data/spec_app/spec/javascripts/support/jasmine.yml +0 -51
  295. data/spec_app/spec/javascripts/up/browser_spec.js.coffee +0 -150
  296. data/spec_app/spec/javascripts/up/classes/cache_spec.js.coffee +0 -82
  297. data/spec_app/spec/javascripts/up/classes/config_spec.coffee +0 -24
  298. data/spec_app/spec/javascripts/up/classes/divertible_chain_spec.coffee +0 -45
  299. data/spec_app/spec/javascripts/up/classes/focus_tracker_spec.coffee +0 -34
  300. data/spec_app/spec/javascripts/up/classes/params_spec.coffee +0 -557
  301. data/spec_app/spec/javascripts/up/classes/request_spec.coffee +0 -50
  302. data/spec_app/spec/javascripts/up/classes/scroll_motion_spec.js.coffee +0 -51
  303. data/spec_app/spec/javascripts/up/classes/store/memory_spec.js.coffee +0 -70
  304. data/spec_app/spec/javascripts/up/classes/store/session_spec.js.coffee +0 -114
  305. data/spec_app/spec/javascripts/up/element_spec.coffee +0 -897
  306. data/spec_app/spec/javascripts/up/event_spec.js.coffee +0 -530
  307. data/spec_app/spec/javascripts/up/feedback_spec.js.coffee +0 -401
  308. data/spec_app/spec/javascripts/up/form_spec.js.coffee +0 -1527
  309. data/spec_app/spec/javascripts/up/fragment_spec.js.coffee +0 -2624
  310. data/spec_app/spec/javascripts/up/history_spec.js.coffee +0 -340
  311. data/spec_app/spec/javascripts/up/jquery_spec.js.coffee +0 -4
  312. data/spec_app/spec/javascripts/up/legacy_spec.js.coffee +0 -27
  313. data/spec_app/spec/javascripts/up/link_spec.js.coffee +0 -1098
  314. data/spec_app/spec/javascripts/up/log_spec.js.coffee +0 -119
  315. data/spec_app/spec/javascripts/up/modal_spec.js.coffee +0 -939
  316. data/spec_app/spec/javascripts/up/motion_spec.js.coffee +0 -582
  317. data/spec_app/spec/javascripts/up/popup_spec.js.coffee +0 -508
  318. data/spec_app/spec/javascripts/up/protocol_spec.js.coffee +0 -39
  319. data/spec_app/spec/javascripts/up/proxy_spec.js.coffee +0 -1145
  320. data/spec_app/spec/javascripts/up/radio_spec.js.coffee +0 -212
  321. data/spec_app/spec/javascripts/up/rails_spec.js.coffee +0 -118
  322. data/spec_app/spec/javascripts/up/spec_spec.js.coffee +0 -9
  323. data/spec_app/spec/javascripts/up/syntax_spec.js.coffee +0 -304
  324. data/spec_app/spec/javascripts/up/toast_spec.js.coffee +0 -37
  325. data/spec_app/spec/javascripts/up/tooltip_spec.js.coffee +0 -163
  326. data/spec_app/spec/javascripts/up/util_spec.js.coffee +0 -1434
  327. data/spec_app/spec/javascripts/up/viewport_spec.js.coffee +0 -655
  328. data/spec_app/spec/spec_helper.rb +0 -62
  329. data/spec_app/test/controllers/.keep +0 -0
  330. data/spec_app/test/fixtures/.keep +0 -0
  331. data/spec_app/test/helpers/.keep +0 -0
  332. data/spec_app/test/integration/.keep +0 -0
  333. data/spec_app/test/mailers/.keep +0 -0
  334. data/spec_app/test/models/.keep +0 -0
  335. data/spec_app/test/test_helper.rb +0 -10
  336. data/spec_app/vendor/asset-libs/es6-promise-4.1.6/es6-promise.auto.js +0 -1159
  337. data/spec_app/vendor/asset-libs/jasmine-ajax-3.3.1/.bower.json +0 -43
  338. data/spec_app/vendor/asset-libs/jasmine-ajax-3.3.1/.gitignore +0 -6
  339. data/spec_app/vendor/asset-libs/jasmine-ajax-3.3.1/.npmignore +0 -10
  340. data/spec_app/vendor/asset-libs/jasmine-ajax-3.3.1/.pairs +0 -6
  341. data/spec_app/vendor/asset-libs/jasmine-ajax-3.3.1/.travis.yml +0 -56
  342. data/spec_app/vendor/asset-libs/jasmine-ajax-3.3.1/jasmine-ajax.js +0 -790
  343. data/spec_app/vendor/assets/.keep +0 -0
  344. data/unpoly-rails.gemspec +0 -24
@@ -1,1129 +0,0 @@
1
- #= require ./classes/selector
2
-
3
- ###**
4
- DOM helpers
5
- ===========
6
-
7
- The `up.element` module offers functions for DOM manipulation and traversal.
8
-
9
- It complements [native `Element` methods](https://www.w3schools.com/jsref/dom_obj_all.asp) and works across all [supported browsers](/up.browser).
10
-
11
- @module up.element
12
- ###
13
- up.element = do ->
14
-
15
- u = up.util
16
-
17
- ###**
18
- Returns a null-object that mostly behaves like an `Element`.
19
-
20
- @function up.element.none()
21
- @internal
22
- ###
23
- NONE = { getAttribute: -> undefined }
24
-
25
- ###**
26
- Matches all elements that have a descendant matching the given selector.
27
-
28
- \#\#\# Example
29
-
30
- `up.element.all('div:has(span)')` matches all `<div>` elements with at least one `<span>` among its descendants:
31
-
32
- ```html
33
- <div>
34
- <span>Will be matched</span>
35
- </div>
36
- <div>
37
- Will NOT be matched
38
- </div>
39
- <div>
40
- <span>Will be matched</span>
41
- </div>
42
- ```
43
-
44
- \#\#\# Compatibility
45
-
46
- `:has()` is supported by all Unpoly functions (like `up.element.all()`) and
47
- selectors (like `a[up-target]`).
48
-
49
- As a [level 4 CSS selector](https://drafts.csswg.org/selectors-4/#relational),
50
- `:has()` [has yet to be implemented](https://caniuse.com/#feat=css-has)
51
- in native browser functions like [`document.querySelectorAll()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelectorAll).
52
-
53
- You can also use [`:has()` in jQuery](https://api.jquery.com/has-selector/).
54
-
55
- @selector :has()
56
- @experimental
57
- ###
58
-
59
- parseSelector = (selector) ->
60
- up.Selector.parse(selector)
61
-
62
- ###**
63
- Returns the first descendant element matching the given selector.
64
-
65
- It is similar to [`element.querySelector()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector),
66
- but also supports the [`:has()`](/has) selector.
67
-
68
- @function up.element.first
69
- @param {Element} [parent=document]
70
- The parent element whose descendants to search.
71
-
72
- If omitted, all elements in the `document` will be searched.
73
- @param {string} selector
74
- The CSS selector to match.
75
- @return {Element|undefined|null}
76
- The first element matching the selector.
77
-
78
- Returns `null` or `undefined` if no element macthes.
79
- @experimental
80
- ###
81
- first = (args...) ->
82
- selector = args.pop()
83
- parent = args[0] ? document
84
- parseSelector(selector).descendant(parent)
85
-
86
- ###**
87
- Returns all descendant elements matching the given selector.
88
-
89
- @function up.element.all
90
- @param {Element} [parent=document]
91
- The parent element whose descendants to search.
92
-
93
- If omitted, all elements in the `document` will be searched.
94
- @param {string} selector
95
- The CSS selector to match.
96
- @return {NodeList<Element>|Array<Element>}
97
- A list of all elements matching the selector.
98
-
99
- Returns an empty list if there are no matches.
100
- @experimental
101
- ###
102
- all = (args...) ->
103
- selector = args.pop()
104
- parent = args[0] ? document
105
- parseSelector(selector).descendants(parent)
106
-
107
- ###**
108
- Returns a list of the given parent's descendants matching the given selector.
109
- The list will also include the parent element if it matches the selector itself.
110
-
111
- @function up.element.subtree
112
- @param {Element} parent
113
- The parent element for the search.
114
- @param {string} selector
115
- The CSS selector to match.
116
- @return {NodeList<Element>|Array<Element>}
117
- A list of all matching elements.
118
- @experimental
119
- ###
120
- subtree = (root, selector) ->
121
- parseSelector(selector).subtree(root)
122
-
123
- ###**
124
- Returns the first element that matches the selector by testing the element itself
125
- and traversing up through its ancestors in the DOM tree.
126
-
127
- @function up.element.closest
128
- @param {Element} element
129
- The element on which to start the search.
130
- @param {string} selector
131
- The CSS selector to match.
132
- @return {Element|null|undefined} element
133
- The matching element.
134
-
135
- Returns `null` or `undefined` if no element matches.
136
- @experimental
137
- ###
138
- closest = (element, selector) ->
139
- parseSelector(selector).closest(element)
140
-
141
- ###**
142
- Returns whether the given element matches the given CSS selector.
143
-
144
- @function up.element.matches
145
- @param {Element} element
146
- The element to check.
147
- @param {string} selector
148
- The CSS selector to match.
149
- @return {boolean}
150
- Whether `element` matches `selector`.
151
- @experimental
152
- ###
153
- matches = (element, selector) ->
154
- parseSelector(selector).matches(element)
155
-
156
- ###**
157
- @function up.element.ancestor
158
- @internal
159
- ###
160
- ancestor = (element, selector) ->
161
- parseSelector(selector).ancestor(element)
162
-
163
- ###**
164
- Casts the given value to a native [Element](https://developer.mozilla.org/en-US/docs/Web/API/Element).
165
-
166
- This is useful when working with jQuery values, or to allow callers to pass CSS selectors
167
- instead of elements.
168
-
169
- \#\#\# Casting rules
170
-
171
- - If given an element, returns that element.
172
- - If given a CSS selector string, returns the [first element matching](/up.element.first) that selector.
173
- - If given a jQuery collection , returns the first element in the collection.
174
- Throws an error if the collection contains more than one element.
175
- - If given any other argument (`undefined`, `null`, `document`, `window`…), returns the argument unchanged.
176
-
177
- @function up.element.get
178
- @param {Element|jQuery|string} value
179
- The value to cast.
180
- @return {Element}
181
- The obtained `Element`.
182
- @experimental
183
- ###
184
- getOne = (value) ->
185
- if u.isElement(value) # Return an element before we run any other expensive checks
186
- value
187
- else if u.isString(value)
188
- first(value)
189
- else if u.isJQuery(value)
190
- if value.length > 1
191
- up.fail('up.element.get(): Cannot cast multiple elements (%o) to a single element', value)
192
- value[0]
193
- else
194
- # undefined, null, Window, Document, DocumentFragment, ...
195
- value
196
-
197
- ###**
198
- Composes a list of elements from the given arguments.
199
-
200
- \#\#\# Casting rules
201
-
202
- - If given a string, returns the all elements matching that string.
203
- - If given any other argument, returns the argument [wrapped as a list](/up.util.wrapList).
204
-
205
- \#\#\# Example
206
-
207
- ```javascript
208
- $jquery = $('.jquery') // returns jQuery (2) [div.jquery, div.jquery]
209
- nodeList = document.querySelectorAll('.node') // returns NodeList (2) [div.node, div.node]
210
- element = document.querySelector('.element') // returns Element div.element
211
- selector = '.selector' // returns String '.selector'
212
-
213
- elements = up.element.list($jquery, nodeList, undefined, element, selector)
214
- // returns [div.jquery, div.jquery, div.node, div.node, div.element, div.selector]
215
- ```
216
-
217
- @function up.element.list
218
- @param {Array<jQuery|Element|Array<Element>|String|undefined|null>} ...args
219
- @return {Array<Element>}
220
- @internal
221
- ###
222
- getList = (args...) ->
223
- u.flatMap args, valueToList
224
-
225
- valueToList = (value) ->
226
- if u.isString(value)
227
- all(value)
228
- else
229
- u.wrapList(value)
230
-
231
- # assertIsElement = (element) ->
232
- # unless u.isElement(element)
233
- # up.fail('Not an element: %o', element)
234
-
235
- ###**
236
- Removes the given element from the DOM tree.
237
-
238
- If you don't need IE11 support you may also use the built-in
239
- [`Element#remove()`](https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove) to the same effect.
240
-
241
- @function up.element.remove
242
- @param {Element} element
243
- The element to remove.
244
- @experimental
245
- ###
246
- remove = (element) ->
247
- if element.remove
248
- element.remove()
249
- # IE does not support Element#remove()
250
- else if parent = element.parentNode
251
- parent.removeChild(element)
252
-
253
- ###**
254
- Hides the given element.
255
-
256
- The element is hidden by setting an [inline style](https://www.codecademy.com/articles/html-inline-styles)
257
- of `{ display: none }`.
258
-
259
- Also see `up.element.show()`.
260
-
261
- @function up.element.hide
262
- @param {Element} element
263
- @experimental
264
- ###
265
- hide = (element) ->
266
- element.style.display = 'none'
267
-
268
- ###**
269
- Shows the given element.
270
-
271
- Also see `up.element.hide()`.
272
-
273
- \#\#\# Limitations
274
-
275
- The element is shown by setting an [inline style](https://www.codecademy.com/articles/html-inline-styles)
276
- of `{ display: '' }`.
277
-
278
- You might have CSS rules causing the element to remain hidden after calling `up.element.show(element)`.
279
- Unpoly will not handle such cases in order to keep this function performant. As a workaround, you may
280
- manually set the `element.style.display` property. Also see discussion
281
- in jQuery issues [#88](https://github.com/jquery/jquery.com/issues/88),
282
- [#2057](https://github.com/jquery/jquery/issues/2057) and
283
- [this WHATWG mailing list post](http://lists.w3.org/Archives/Public/public-whatwg-archive/2014Apr/0094.html).
284
-
285
- @function up.element.show
286
- @param {Element} element
287
- @experimental
288
- ###
289
- show = (element) ->
290
- element.style.display = ''
291
-
292
- ###**
293
- Display or hide the given element, depending on its current visibility.
294
-
295
- @function up.element.toggle
296
- @param {Element} element
297
- @param {Boolean} [newVisible]
298
- Pass `true` to show the element or `false` to hide it.
299
-
300
- If omitted, the element will be hidden if shown and shown if hidden.
301
- @experimental
302
- ###
303
- toggle = (element, newVisible) ->
304
- newVisible ?= !isVisible(element)
305
- if newVisible
306
- show(element)
307
- else
308
- hide(element)
309
-
310
- # trace = (fn) ->
311
- # (args...) ->
312
- # console.debug("Calling %o with %o", fn, args)
313
- # fn(args...)
314
-
315
- ###**
316
- Adds or removes the given class from the given element.
317
-
318
- If you don't need IE11 support you may also use the built-in
319
- [`Element#classList.toggle(className)`](https://developer.mozilla.org/en-US/docs/Web/API/Element/classList) to the same effect.
320
-
321
- @function up.element.toggleClass
322
- @param {Element} element
323
- The element for which to add or remove the class.
324
- @param {String} className
325
- The class which should be added or removed.
326
- @param {Boolean} [newPresent]
327
- Pass `true` to add the class to the element or `false` to remove it.
328
-
329
- If omitted, the class will be added if missing and removed if present.
330
- @experimental
331
- ###
332
- toggleClass = (element, klass, newPresent) ->
333
- list = element.classList
334
- newPresent ?= !list.contains(klass)
335
- if newPresent
336
- list.add(klass)
337
- else
338
- list.remove(klass)
339
-
340
- ###**
341
- Sets all key/values from the given object as attributes on the given element.
342
-
343
- \#\#\# Example
344
-
345
- up.element.setAttrs(element, { title: 'Tooltip', tabindex: 1 })
346
-
347
- @function up.element.setAttrs
348
- @param {Element} element
349
- The element on which to set attributes.
350
- @param {object} attributes
351
- An object of attributes to set.
352
- @experimental
353
- ###
354
- setAttrs = (element, attributes) ->
355
- for key, value of attributes
356
- element.setAttribute(key, value)
357
-
358
- ###**
359
- @function up.element.metaContent
360
- @internal
361
- ###
362
- metaContent = (name) ->
363
- selector = "meta" + attributeSelector('name', name)
364
- first(selector)?.getAttribute('content')
365
-
366
- ###**
367
- @function up.element.insertBefore
368
- @internal
369
- ###
370
- insertBefore = (existingElement, newElement) ->
371
- existingElement.insertAdjacentElement('beforebegin', newElement)
372
-
373
- # insertAfter = (existingElement, newElement) ->
374
- # existingElement.insertAdjacentElement('afterend', newElement)
375
-
376
- ###**
377
- Replaces the given old element with the given new element.
378
-
379
- The old element will be removed from the DOM tree.
380
-
381
- If you don't need IE11 support you may also use the built-in
382
- [`Element#replaceWith()`](https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/replaceWith) to the same effect.
383
-
384
- @function up.element.replace
385
- @param {Element} oldElement
386
- @param {Element} newElement
387
- @experimental
388
- ###
389
- replace = (oldElement, newElement) ->
390
- oldElement.parentElement.replaceChild(newElement, oldElement)
391
-
392
- ###**
393
- Creates an element matching the given CSS selector.
394
-
395
- The created element will not yet be attached to the DOM tree.
396
- Attach it with [`Element#appendChild()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild)
397
- or use `up.element.affix()` to create an attached element.
398
-
399
- \#\#\# Examples
400
-
401
- To create an element with a given tag name:
402
-
403
- element = up.element.createFromSelector('span')
404
- // element is <span></span>
405
-
406
- To create an element with a given class:
407
-
408
- element = up.element.createFromSelector('.klass')
409
- // element is <div class="klass"></div>
410
-
411
- To create an element with a given ID:
412
-
413
- element = up.element.createFromSelector('#foo')
414
- // element is <div id="foo"></div>
415
-
416
- To create an element with a given boolean attribute:
417
-
418
- element = up.element.createFromSelector('[attr]')
419
- // element is <div attr></div>
420
-
421
- To create an element with a given attribute value:
422
-
423
- element = up.element.createFromSelector('[attr="value"]')
424
- // element is <div attr="value"></div>
425
-
426
- You may also pass an object of attribute names/values as a second argument:
427
-
428
- element = up.element.createFromSelector('div', { attr: 'value' })
429
- // element is <div attr="value"></div>
430
-
431
- You may set the element's inner text by passing a `{ text }` option:
432
-
433
- element = up.element.createFromSelector('div', { text: 'inner text' })
434
- // element is <div>inner text</div>
435
-
436
- You may set inline styles by passing an object of CSS properties as a second argument:
437
-
438
- element = up.element.createFromSelector('div', { style: { color: 'red' }})
439
- // element is <div style="color: red"></div>
440
-
441
- @function up.element.createFromSelector
442
- @param {string} selector
443
- The CSS selector from which to create an element.
444
- @param {Object} [attrs]
445
- An object of attributes to set on the created element.
446
- @param {Object} [attrs.text]
447
- The [text content](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent) of the created element.
448
- @param {Object} [attrs.style]
449
- An object of CSS properties that will be set as the inline style
450
- of the created element.
451
- @return {Element}
452
- The created element.
453
- @experimental
454
- ###
455
- createFromSelector = (selector, attrs) ->
456
- # Extract attribute values before we do anything else.
457
- # Attribute values might contain spaces, and then we would incorrectly
458
- # split depths at that space.
459
- attrValues = []
460
- selectorWithoutAttrValues = selector.replace /\[([\w-]+)(?:=(["'])?([^"'\]]*?)\2)?\]/g, (_match, attrName, _quote, attrValue) ->
461
- attrValues.push(attrValue || '')
462
- "[#{attrName}]"
463
-
464
- depths = selectorWithoutAttrValues.split(/[ >]+/)
465
- rootElement = undefined
466
- depthElement = undefined
467
- previousElement = undefined
468
-
469
- for depthSelector in depths
470
- tagName = undefined
471
-
472
- depthSelector = depthSelector.replace /^[\w-]+/, (match) ->
473
- tagName = match
474
- ''
475
-
476
- depthElement = document.createElement(tagName || 'div')
477
- rootElement ||= depthElement
478
-
479
- depthSelector = depthSelector.replace /\#([\w-]+)/, (_match, id) ->
480
- depthElement.id = id
481
- ''
482
-
483
- depthSelector = depthSelector.replace /\.([\w-]+)/g, (_match, className) ->
484
- depthElement.classList.add(className)
485
- ''
486
-
487
- # If we have stripped out attrValues at the beginning of the function,
488
- # they have been replaced with the attribute name only (as "[name]").
489
- if attrValues.length
490
- depthSelector = depthSelector.replace /\[([\w-]+)\]/g, (_match, attrName) ->
491
- depthElement.setAttribute(attrName, attrValues.shift())
492
- ''
493
-
494
- unless depthSelector == ''
495
- throw new Error('Cannot parse selector: ' + selector)
496
-
497
- previousElement?.appendChild(depthElement)
498
- previousElement = depthElement
499
-
500
- if attrs
501
- if classValue = u.pluckKey(attrs, 'class')
502
- for klass in u.wrapList(classValue)
503
- rootElement.classList.add(klass)
504
- if styleValue = u.pluckKey(attrs, 'style')
505
- setInlineStyle(rootElement, styleValue)
506
- if textValue = u.pluckKey(attrs, 'text')
507
- rootElement.innerText = textValue
508
- setAttrs(rootElement, attrs)
509
-
510
- rootElement
511
-
512
- ###**
513
- Creates an element matching the given CSS selector and attaches it to the given parent element.
514
-
515
- To create a detached element from a selector,
516
- see `up.element.createFromSelector()`.
517
-
518
- \#\#\# Example
519
-
520
- element = up.element.affix(document.body, '.klass')
521
- element.parentElement // returns document.body
522
- element.className // returns 'klass'
523
-
524
- @function up.element.affix
525
- @param {Element} parent
526
- The parent to which to attach the created element.
527
- @param {string} selector
528
- The CSS selector from which to create an element.
529
- @param {Object} attrs
530
- An object of attributes to set on the created element.
531
- @param {Object} attrs.text
532
- The [text content](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent) of the created element.
533
- @param {Object} attrs.style
534
- An object of CSS properties that will be set as the inline style
535
- of the created element.
536
- @return {Element}
537
- The created element.
538
- @experimental
539
- ###
540
- affix = (parent, selector, attributes) ->
541
- element = createFromSelector(selector, attributes)
542
- parent.appendChild(element)
543
- element
544
-
545
- ###**
546
- Returns a CSS selector that matches the given element as good as possible.
547
-
548
- To build the selector, the following element properties are used in decreasing
549
- order of priority:
550
-
551
- - The element's `[up-id]` attribute
552
- - The element's `[id]` attribute
553
- - The element's `[name]` attribute
554
- - The element's `[class]` names
555
- - The element's [`[aria-label]`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute) attribute
556
- - The element's tag name
557
-
558
- \#\#\# Example
559
-
560
- element = document.createElement('span')
561
- element.className = 'klass'
562
- selector = up.element.toSelector(element) // returns '.klass'
563
-
564
- @function up.element.toSelector
565
- @param {string|Element|jQuery}
566
- The element for which to create a selector.
567
- @experimental
568
- ###
569
- toSelector = (element) ->
570
- return element if u.isString(element)
571
-
572
- # resolveSelector() might be called with jQuery collections
573
- element = getOne(element)
574
-
575
- selector = undefined
576
-
577
- if isSingleton(element)
578
- selector = elementTagName(element)
579
- else if upId = element.getAttribute("up-id")
580
- selector = attributeSelector('up-id', upId)
581
- else if id = element.getAttribute("id")
582
- if id.match(/^[a-z0-9\-_]+$/i)
583
- selector = "##{id}"
584
- else
585
- selector = attributeSelector('id', id)
586
- else if name = element.getAttribute("name")
587
- selector = elementTagName(element) + attributeSelector('name', name)
588
- else if classes = u.presence(nonUpClasses(element))
589
- selector = ''
590
- for klass in classes
591
- selector += ".#{klass}"
592
- else if ariaLabel = element.getAttribute("aria-label")
593
- selector = attributeSelector('aria-label', ariaLabel)
594
- else
595
- selector = elementTagName(element)
596
-
597
- return selector
598
-
599
- ###**
600
- Sets an unique identifier for this element.
601
-
602
- This identifier is used by `up.element.toSelector()`
603
- to create a CSS selector that matches this element precisely.
604
-
605
- If the element already has other attributes that make a good identifier,
606
- like a `[id]`, `[class]` or `[aria-label]`, it is not necessary to
607
- set `[up-id]`.
608
-
609
- \#\#\# Example
610
-
611
- Take this element:
612
-
613
- <a href="/">Homepage</a>
614
-
615
- Unpoly cannot generate a good CSS selector for this element:
616
-
617
- up.element.toSelector(element)
618
- // returns 'a'
619
-
620
- We can improve this by assigning an `[up-id]`:
621
-
622
- <a href="/" up-id="link-to-home">Open user 4</a>
623
-
624
- The attribute value is used to create a better selector:
625
-
626
- up.element.toSelector(element)
627
- // returns '[up-id="link-to-home"]'
628
-
629
- @selector [up-id]
630
- @param {string} up-id
631
- A string that uniquely identifies this element.
632
- @stable
633
- ###
634
-
635
- ###**
636
- @function up.element.isSingleton
637
- @internal
638
- ###
639
- isSingleton = (element) ->
640
- matches(element, 'html, body, head, title')
641
-
642
- elementTagName = (element) ->
643
- element.tagName.toLowerCase()
644
-
645
- ###**
646
- @function up.element.attributeSelector
647
- @internal
648
- ###
649
- attributeSelector = (attribute, value) ->
650
- value = value.replace(/"/g, '\\"')
651
- "[#{attribute}=\"#{value}\"]"
652
-
653
- nonUpClasses = (element) ->
654
- classString = element.className
655
- classes = u.splitValues(classString)
656
- u.reject classes, (klass) -> klass.match(/^up-/)
657
-
658
- ###**
659
- @function up.element.createDocumentFromHtml
660
- @internal
661
- ###
662
- createDocumentFromHtml = (html) ->
663
- # IE9 cannot set innerHTML on a <html> or <head> element.
664
- parser = new DOMParser()
665
- return parser.parseFromString(html, 'text/html')
666
-
667
- ###**
668
- Creates an element from the given HTML fragment.
669
-
670
- \#\#\# Example
671
-
672
- element = up.element.createFromHtml('<div class="foo"><span>text</span></div>')
673
- element.className // returns 'foo'
674
- element.children[0] // returns <span> element
675
- element.children[0].textContent // returns 'text'
676
-
677
- @function up.element.createFromHtml
678
- @experimental
679
- ###
680
- createFromHtml = (html) ->
681
- doc = createDocumentFromHtml(html)
682
- return doc.body.children[0]
683
-
684
- ###**
685
- @function up.element.root
686
- @internal
687
- ###
688
- getRoot = ->
689
- document.documentElement
690
-
691
- ###**
692
- Forces the browser to paint the given element now.
693
-
694
- @function up.element.paint
695
- @internal
696
- ###
697
- paint = (element) ->
698
- element.offsetHeight
699
-
700
- ###**
701
- @function up.element.concludeCssTransition
702
- @internal
703
- ###
704
- concludeCssTransition = (element) ->
705
- undo = setTemporaryStyle(element, transition: 'none')
706
- # Browsers need to paint at least one frame without a transition to stop the
707
- # animation. In theory we could just wait until the next paint, but in case
708
- # someone will set another transition after us, let's force a repaint here.
709
- paint(element)
710
- return undo
711
-
712
- ###**
713
- Returns whether the given element has a CSS transition set.
714
-
715
- @function up.element.hasCssTransition
716
- @return {boolean}
717
- @internal
718
- ###
719
- hasCssTransition = (elementOrStyleHash) ->
720
- if u.isOptions(elementOrStyleHash)
721
- styleHash = elementOrStyleHash
722
- else
723
- styleHash = computedStyle(elementOrStyleHash)
724
-
725
- prop = styleHash.transitionProperty
726
- duration = styleHash.transitionDuration
727
- # The default transition for elements is actually "all 0s ease 0s"
728
- # instead of "none", although that has the same effect as "none".
729
- noTransition = (prop == 'none' || (prop == 'all' && duration == 0))
730
- not noTransition
731
-
732
- ###**
733
- @function up.element.fixedToAbsolute
734
- @internal
735
- ###
736
- fixedToAbsolute = (element) ->
737
- elementRectAsFixed = element.getBoundingClientRect()
738
-
739
- # Set the position to 'absolute' so it gains an offsetParent
740
- element.style.position = 'absolute'
741
-
742
- offsetParentRect = element.offsetParent.getBoundingClientRect()
743
-
744
- setInlineStyle element,
745
- left: elementRectAsFixed.left - computedStyleNumber(element, 'margin-left') - offsetParentRect.left
746
- top: elementRectAsFixed.top - computedStyleNumber(element, 'margin-top') - offsetParentRect.top
747
- right: ''
748
- bottom: ''
749
-
750
- ###**
751
- On the given element, set attributes that are still missing.
752
-
753
- @function up.element.setMissingAttrs
754
- @internal
755
- ###
756
- setMissingAttrs = (element, attrs) ->
757
- for key, value of attrs
758
- if u.isMissing(element.getAttribute(key))
759
- element.setAttribute(key, value)
760
-
761
- ###**
762
- @function up.element.unwrap
763
- @internal
764
- ###
765
- unwrap = (wrapper) ->
766
- parent = wrapper.parentNode;
767
- wrappedNodes = u.toArray(wrapper.childNodes)
768
- u.each wrappedNodes, (wrappedNode) ->
769
- parent.insertBefore(wrappedNode, wrapper)
770
- parent.removeChild(wrapper)
771
-
772
- # ###**
773
- # Returns the value of the given attribute on the given element, if the value is [present](/up.util.isPresent).
774
- #
775
- # Returns `undefined` if the attribute is not set, or if it is set to an empty string.
776
- #
777
- # @function up.element.presentAttr
778
- # @param {Element} element
779
- # The element from which to retrieve the attribute value.
780
- # @param {String} attribute
781
- # The attribute name.
782
- # @return {string|undefined}
783
- # The attribute value, if present.
784
- # @experimental
785
- # ###
786
- # presentAttr = (element, attribute) ->
787
- # value = element.getAttribute(attribute)
788
- # u.presence(value)
789
-
790
- ###**
791
- Returns the value of the given attribute on the given element, cast as a boolean value.
792
-
793
- If the attribute value cannot be cast to `true` or `false`, `undefined` is returned.
794
-
795
- \#\#\# Casting rules
796
-
797
- This function deviates from the
798
- [HTML Standard for boolean attributes](https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes)
799
- in order to allow `undefined` values. When an attribute is missing, Unpoly considers the value to be `undefined`
800
- (where the standard would assume `false`).
801
-
802
- Unpoly also allows `"true"` and `"false"` as attribute values.
803
-
804
- The table below shows return values for `up.element.booleanAttr(element, 'foo')` given different elements:
805
-
806
- | Element | Return value |
807
- |---------------------|--------------|
808
- | `<div foo>` | `true` |
809
- | `<div foo="foo">` | `true` |
810
- | `<div foo="true">` | `true` |
811
- | `<div foo="">` | `true` |
812
- | `<div foo="false">` | `false` |
813
- | `<div>` | `undefined` |
814
- | `<div foo="bar">` | `undefined` |
815
-
816
- @function up.element.booleanAttr
817
- @param {Element} element
818
- The element from which to retrieve the attribute value.
819
- @param {String} attribute
820
- The attribute name.
821
- @return {boolean|undefined}
822
- The cast attribute value.
823
- @experimental
824
- ###
825
- booleanAttr = (element, attribute, pass) ->
826
- value = element.getAttribute(attribute)
827
- switch value
828
- when 'false'
829
- false
830
- when 'true', '', attribute
831
- true
832
- else
833
- value if pass
834
-
835
- ###**
836
- Returns the given attribute value cast as boolean.
837
-
838
- If the attribute value cannot be cast, returns the attribute value unchanged.
839
-
840
- @internal
841
- ###
842
- booleanOrStringAttr = (element, attribute) ->
843
- booleanAttr(element, attribute, true)
844
-
845
- ###**
846
- Returns the value of the given attribute on the given element, cast to a number.
847
-
848
- If the attribute value cannot be cast to a number, `undefined` is returned.
849
-
850
- @function up.element.numberAttr
851
- @param {Element} element
852
- The element from which to retrieve the attribute value.
853
- @param {String} attribute
854
- The attribute name.
855
- @return {number|undefined}
856
- The cast attribute value.
857
- @experimental
858
- ###
859
- numberAttr = (element, attribute) ->
860
- value = element.getAttribute(attribute)
861
- if value?.match(/^[\d\.]+$/)
862
- parseFloat(value)
863
-
864
- ###**
865
- Reads the given attribute from the element, parsed as [JSON](https://www.json.org/).
866
-
867
- Returns `undefined` if the attribute value is [blank](/up.util.isBlank).
868
-
869
- Throws a `SyntaxError` if the attribute value is an invalid JSON string.
870
-
871
- @function up.element.jsonAttr
872
- @param {Element} element
873
- The element from which to retrieve the attribute value.
874
- @param {String} attribute
875
- The attribute name.
876
- @return {Object|undefined}
877
- The cast attribute value.
878
- @experimental
879
- ###
880
- jsonAttr = (element, attribute) ->
881
- # The document does not respond to #getAttribute()
882
- if json = element.getAttribute?(attribute)?.trim()
883
- JSON.parse(json)
884
-
885
- ###**
886
- Temporarily sets the inline CSS styles on the given element.
887
-
888
- Returns a function that restores the original inline styles when called.
889
-
890
- \#\#\# Example
891
-
892
- element = document.querySelector('div')
893
- unhide = up.element.setTemporaryStyle(element, { 'visibility': 'hidden' })
894
- // do things while element is invisible
895
- unhide()
896
- // element is visible again
897
-
898
- @function up.element.setTemporaryStyle
899
- @param {Element} element
900
- The element to style.
901
- @param {Object} styles
902
- An object of CSS property names and values.
903
- @return {Function()}
904
- A function that restores the original inline styles when called.
905
- @internal
906
- ###
907
- setTemporaryStyle = (element, newStyles, block) ->
908
- oldStyles = inlineStyle(element, Object.keys(newStyles))
909
- setInlineStyle(element, newStyles)
910
- return -> setInlineStyle(element, oldStyles)
911
-
912
- ###**
913
- Receives [computed CSS styles](https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle)
914
- for the given element.
915
-
916
- \#\#\# Examples
917
-
918
- When requesting a single CSS property, its value will be returned as a string:
919
-
920
- value = up.element.style(element, 'font-size')
921
- // value is '16px'
922
-
923
- When requesting multiple CSS properties, the function returns an object of property names and values:
924
-
925
- value = up.element.style(element, ['font-size', 'margin-top'])
926
- // value is { 'font-size': '16px', 'margin-top': '10px' }
927
-
928
- @function up.element.style
929
- @param {Element} element
930
- @param {String|Array} propOrProps
931
- One or more CSS property names in kebab-case or camelCase.
932
- @return {string|object}
933
- @experimental
934
- ###
935
- computedStyle = (element, props) ->
936
- style = window.getComputedStyle(element)
937
- extractFromStyleObject(style, props)
938
-
939
- ###**
940
- Receives a [computed CSS property value](https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle)
941
- for the given element, casted as a number.
942
-
943
- The value is casted by removing the property's [unit](https://www.w3schools.com/cssref/css_units.asp) (which is usually `px` for computed properties).
944
- The result is then parsed as a floating point number.
945
-
946
- Returns `undefined` if the property value is missing, or if it cannot
947
- be parsed as a number.
948
-
949
- \#\#\# Examples
950
-
951
- When requesting a single CSS property, its value will be returned as a string:
952
-
953
- value = up.element.style(element, 'font-size')
954
- // value is '16px'
955
-
956
- value = up.element.styleNumber(element, 'font-size')
957
- // value is 16
958
-
959
- @function up.element.styleNumber
960
- @param {Element} element
961
- @param {String} prop
962
- A single property name in kebab-case or camelCase.
963
- @return {number|undefined}
964
- @experimental
965
- ###
966
- computedStyleNumber = (element, prop) ->
967
- rawValue = computedStyle(element, prop)
968
- if u.isGiven(rawValue)
969
- parseFloat(rawValue)
970
- else
971
- undefined
972
-
973
- ###**
974
- Gets the given inline style(s) from the given element's `[style]` attribute.
975
-
976
- @function up.element.inlineStyle
977
- @param {Element} element
978
- @param {String|Array} propOrProps
979
- One or more CSS property names in kebab-case or camelCase.
980
- @return {string|object}
981
- @internal
982
- ###
983
- inlineStyle = (element, props) ->
984
- style = element.style
985
- extractFromStyleObject(style, props)
986
-
987
- extractFromStyleObject = (style, keyOrKeys) ->
988
- if u.isString(keyOrKeys)
989
- style[keyOrKeys]
990
- else # array
991
- u.only(style, keyOrKeys...)
992
-
993
- ###**
994
- Sets the given CSS properties as inline styles on the given element.
995
-
996
- @function up.element.setStyle
997
- @param {Element} element
998
- @param {Object} props
999
- One or more CSS properties with kebab-case keys or camelCase keys.
1000
- @return {string|object}
1001
- @experimental
1002
- ###
1003
- setInlineStyle = (element, props) ->
1004
- style = element.style
1005
- for key, value of props
1006
- value = normalizeStyleValueForWrite(key, value)
1007
- style[key] = value
1008
-
1009
- normalizeStyleValueForWrite = (key, value) ->
1010
- if u.isMissing(value)
1011
- value = ''
1012
- else if CSS_LENGTH_PROPS.has(key.toLowerCase().replace(/-/, ''))
1013
- value = cssLength(value)
1014
- value
1015
-
1016
- CSS_LENGTH_PROPS = u.arrayToSet [
1017
- 'top', 'right', 'bottom', 'left',
1018
- 'padding', 'paddingtop', 'paddingright', 'paddingbottom', 'paddingleft',
1019
- 'margin', 'margintop', 'marginright', 'marginbottom', 'marginleft',
1020
- 'borderwidth', 'bordertopwidth', 'borderrightwidth', 'borderbottomwidth', 'borderleftwidth'
1021
- 'width', 'height',
1022
- 'maxwidth', 'maxheight',
1023
- 'minwidth', 'minheight',
1024
- ]
1025
-
1026
- ###**
1027
- Converts the given value to a CSS length value, adding a `px` unit if required.
1028
-
1029
- @function cssLength
1030
- @internal
1031
- ###
1032
- cssLength = (obj) ->
1033
- if u.isNumber(obj) || (u.isString(obj) && /^\d+$/.test(obj))
1034
- obj.toString() + "px"
1035
- else
1036
- obj
1037
-
1038
- ###**
1039
- Resolves the given CSS selector (which might contain `&` references)
1040
- to a full CSS selector without ampersands.
1041
-
1042
- If passed an `Element` or `jQuery` element, returns a CSS selector string
1043
- for that element.
1044
-
1045
- @function up.element.resolveSelector
1046
- @param {string|Element|jQuery} selectorOrElement
1047
- @param {string|Element|jQuery} origin
1048
- The element that this selector resolution is relative to.
1049
- That element's selector will be substituted for `&` ([like in Sass](https://sass-lang.com/documentation/file.SASS_REFERENCE.html#parent-selector)).
1050
- @return {string}
1051
- @internal
1052
- ###
1053
- resolveSelector = (selectorOrElement, origin) ->
1054
- if u.isString(selectorOrElement)
1055
- selector = selectorOrElement
1056
- if u.contains(selector, '&')
1057
- if u.isPresent(origin) # isPresent returns false for empty jQuery collection
1058
- originSelector = toSelector(origin)
1059
- selector = selector.replace(/\&/, originSelector)
1060
- else
1061
- up.fail("Found origin reference (%s) in selector %s, but no origin was given", '&', selector)
1062
- else
1063
- selector = toSelector(selectorOrElement)
1064
- selector
1065
-
1066
- ###**
1067
- Returns whether the given element is currently visible.
1068
-
1069
- An element is considered visible if it consumes space in the document.
1070
- Elements with `{ visibility: hidden }` or `{ opacity: 0 }` are considered visible, since they still consume space in the layout.
1071
-
1072
- Elements not attached to the DOM are considered hidden.
1073
-
1074
- @function up.element.isVisible
1075
- @param {Element} element
1076
- The element to check.
1077
- @experimental
1078
- ###
1079
- isVisible = (element) ->
1080
- # From https://github.com/jquery/jquery/blame/9cb162f6b62b6d4403060a0f0d2065d3ae96bbcc/src/css/hiddenVisibleSelectors.js#L12
1081
- !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length)
1082
-
1083
- <% if ENV['JS_KNIFE'] %>knife: eval(Knife.point)<% end %>
1084
- # also document :has()!
1085
- first: first # same as document.querySelector
1086
- all: all # same as document.querySelectorAll
1087
- subtree: subtree # practical
1088
- closest: closest # needed for IE11
1089
- matches: matches # needed for IE11
1090
- ancestor: ancestor # not practical. we use it to implement closest
1091
- get: getOne # practical for code that also works with jQuery
1092
- list: getList # practical for composing multiple collections, or wrapping.
1093
- remove: remove # needed for IE11
1094
- toggle: toggle # practical
1095
- toggleClass: toggleClass # practical
1096
- hide: hide # practical
1097
- show: show # practical
1098
- metaContent: metaContent # internal
1099
- replace: replace # needed for IE11
1100
- insertBefore: insertBefore # internal shortcut, people can use insertAdjacentElement and i don't want to support insertAfter when I don't need it.
1101
- createFromSelector: createFromSelector # practical for element creation.
1102
- setAttrs: setAttrs # practical
1103
- affix: affix # practical for element creation
1104
- toSelector: toSelector # practical
1105
- isSingleton: isSingleton # internal
1106
- attributeSelector: attributeSelector # internal
1107
- createDocumentFromHtml: createDocumentFromHtml # internal
1108
- createFromHtml: createFromHtml # practical for element creation
1109
- root: getRoot # internal
1110
- paint: paint # internal
1111
- concludeCssTransition: concludeCssTransition # internal
1112
- hasCssTransition: hasCssTransition # internal
1113
- fixedToAbsolute: fixedToAbsolute # internal
1114
- setMissingAttrs: setMissingAttrs # internal
1115
- unwrap: unwrap # practical for jQuery migration
1116
- # presentAttr: presentAttr # experimental
1117
- booleanAttr: booleanAttr # it's practical, but i cannot find a good name. people might expect it to cast to number, too. but i don't need that for my own code. maybe booleanAttr?
1118
- numberAttr: numberAttr # practical
1119
- jsonAttr: jsonAttr # practical
1120
- booleanOrStringAttr: booleanOrStringAttr
1121
- setTemporaryStyle: setTemporaryStyle # practical
1122
- style: computedStyle # practical.
1123
- styleNumber: computedStyleNumber # practical.
1124
- inlineStyle: inlineStyle # internal
1125
- setStyle: setInlineStyle # practical.
1126
- resolveSelector: resolveSelector # internal
1127
- none: -> NONE # internal
1128
- isVisible: isVisible # practical
1129
-