unpoly-rails 0.20.0

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

Potentially problematic release.


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

Files changed (339) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.ruby-version +2 -0
  4. data/.yardopts +1 -0
  5. data/CHANGELOG.md +577 -0
  6. data/Gemfile +8 -0
  7. data/Gemfile.lock +42 -0
  8. data/LICENSE +22 -0
  9. data/README.md +75 -0
  10. data/README_RAILS.md +116 -0
  11. data/Rakefile +45 -0
  12. data/bower.json +26 -0
  13. data/design/animation-ghosting.txt +72 -0
  14. data/design/design.txt +34 -0
  15. data/design/draft.html.erb +48 -0
  16. data/design/draft.rb +9 -0
  17. data/design/ghost-debugging.txt +118 -0
  18. data/design/homepage.txt +236 -0
  19. data/design/rename.txt +0 -0
  20. data/dist/unpoly-bootstrap3.css +5 -0
  21. data/dist/unpoly-bootstrap3.js +28 -0
  22. data/dist/unpoly-bootstrap3.min.css +1 -0
  23. data/dist/unpoly-bootstrap3.min.js +1 -0
  24. data/dist/unpoly.css +98 -0
  25. data/dist/unpoly.js +9041 -0
  26. data/dist/unpoly.min.css +1 -0
  27. data/dist/unpoly.min.js +3 -0
  28. data/lib/assets/javascripts/unpoly-bootstrap3.js.coffee +2 -0
  29. data/lib/assets/javascripts/unpoly-bootstrap3/form-ext.js.coffee +1 -0
  30. data/lib/assets/javascripts/unpoly-bootstrap3/layout-ext.js.coffee +5 -0
  31. data/lib/assets/javascripts/unpoly-bootstrap3/modal-ext.js.coffee +11 -0
  32. data/lib/assets/javascripts/unpoly-bootstrap3/navigation-ext.js.coffee +3 -0
  33. data/lib/assets/javascripts/unpoly.js.coffee +20 -0
  34. data/lib/assets/javascripts/unpoly/browser.js.coffee +252 -0
  35. data/lib/assets/javascripts/unpoly/bus.js.coffee +393 -0
  36. data/lib/assets/javascripts/unpoly/flow.js.coffee +809 -0
  37. data/lib/assets/javascripts/unpoly/form.js.coffee +864 -0
  38. data/lib/assets/javascripts/unpoly/history.js.coffee +204 -0
  39. data/lib/assets/javascripts/unpoly/layout.js.coffee +529 -0
  40. data/lib/assets/javascripts/unpoly/link.js.coffee +496 -0
  41. data/lib/assets/javascripts/unpoly/log.js.coffee +73 -0
  42. data/lib/assets/javascripts/unpoly/modal.js.coffee +509 -0
  43. data/lib/assets/javascripts/unpoly/module.js.coffee +4 -0
  44. data/lib/assets/javascripts/unpoly/motion.js.coffee +690 -0
  45. data/lib/assets/javascripts/unpoly/navigation.js.coffee +219 -0
  46. data/lib/assets/javascripts/unpoly/popup.js.coffee +409 -0
  47. data/lib/assets/javascripts/unpoly/proxy.js.coffee +521 -0
  48. data/lib/assets/javascripts/unpoly/rails.js.coffee +36 -0
  49. data/lib/assets/javascripts/unpoly/syntax.js.coffee +337 -0
  50. data/lib/assets/javascripts/unpoly/tooltip.js.coffee +183 -0
  51. data/lib/assets/javascripts/unpoly/util.js.coffee +1593 -0
  52. data/lib/assets/stylesheets/unpoly-bootstrap3.css.sass +1 -0
  53. data/lib/assets/stylesheets/unpoly-bootstrap3/modal-ext.css.sass +9 -0
  54. data/lib/assets/stylesheets/unpoly.css.sass +1 -0
  55. data/lib/assets/stylesheets/unpoly/close.css.sass +2 -0
  56. data/lib/assets/stylesheets/unpoly/error.css.sass +15 -0
  57. data/lib/assets/stylesheets/unpoly/link.css.sass +2 -0
  58. data/lib/assets/stylesheets/unpoly/modal.css.sass +69 -0
  59. data/lib/assets/stylesheets/unpoly/popup.css.sass +8 -0
  60. data/lib/assets/stylesheets/unpoly/tooltip.css.sass +42 -0
  61. data/lib/unpoly-rails.rb +7 -0
  62. data/lib/unpoly/rails/engine.rb +6 -0
  63. data/lib/unpoly/rails/inspector.rb +78 -0
  64. data/lib/unpoly/rails/inspector_accessor.rb +30 -0
  65. data/lib/unpoly/rails/request_echo_headers.rb +27 -0
  66. data/lib/unpoly/rails/request_method_cookie.rb +36 -0
  67. data/lib/unpoly/rails/version.rb +9 -0
  68. data/spec_app/.firefox-version +1 -0
  69. data/spec_app/.gitignore +17 -0
  70. data/spec_app/.rspec +2 -0
  71. data/spec_app/Bowerfile +3 -0
  72. data/spec_app/Gemfile +29 -0
  73. data/spec_app/Gemfile.lock +212 -0
  74. data/spec_app/README.rdoc +28 -0
  75. data/spec_app/Rakefile +6 -0
  76. data/spec_app/app/assets/images/.keep +0 -0
  77. data/spec_app/app/assets/javascripts/application.js +20 -0
  78. data/spec_app/app/assets/stylesheets/application.css +17 -0
  79. data/spec_app/app/assets/stylesheets/blocks/card.css.sass +11 -0
  80. data/spec_app/app/assets/stylesheets/blocks/controls.css.sass +7 -0
  81. data/spec_app/app/assets/stylesheets/blocks/menu.css.sass +13 -0
  82. data/spec_app/app/assets/stylesheets/blocks/panel.css.sass +8 -0
  83. data/spec_app/app/assets/stylesheets/jasmine_specs.css +5 -0
  84. data/spec_app/app/controllers/application_controller.rb +6 -0
  85. data/spec_app/app/controllers/concerns/.keep +0 -0
  86. data/spec_app/app/controllers/test_controller.rb +28 -0
  87. data/spec_app/app/helpers/application_helper.rb +2 -0
  88. data/spec_app/app/mailers/.keep +0 -0
  89. data/spec_app/app/models/concerns/.keep +0 -0
  90. data/spec_app/app/views/layouts/application.html.erb +12 -0
  91. data/spec_app/bin/bundle +3 -0
  92. data/spec_app/bin/rails +8 -0
  93. data/spec_app/bin/rake +8 -0
  94. data/spec_app/bin/setup +29 -0
  95. data/spec_app/bin/spring +18 -0
  96. data/spec_app/config.ru +4 -0
  97. data/spec_app/config/application.rb +26 -0
  98. data/spec_app/config/boot.rb +3 -0
  99. data/spec_app/config/database.yml +25 -0
  100. data/spec_app/config/environment.rb +5 -0
  101. data/spec_app/config/environments/development.rb +41 -0
  102. data/spec_app/config/environments/production.rb +79 -0
  103. data/spec_app/config/environments/test.rb +42 -0
  104. data/spec_app/config/initializers/assets.rb +11 -0
  105. data/spec_app/config/initializers/backtrace_silencers.rb +7 -0
  106. data/spec_app/config/initializers/bower_rails.rb +16 -0
  107. data/spec_app/config/initializers/cookies_serializer.rb +3 -0
  108. data/spec_app/config/initializers/filter_parameter_logging.rb +4 -0
  109. data/spec_app/config/initializers/inflections.rb +16 -0
  110. data/spec_app/config/initializers/mime_types.rb +4 -0
  111. data/spec_app/config/initializers/session_store.rb +3 -0
  112. data/spec_app/config/initializers/wrap_parameters.rb +14 -0
  113. data/spec_app/config/locales/en.yml +23 -0
  114. data/spec_app/config/routes.rb +8 -0
  115. data/spec_app/config/secrets.yml +22 -0
  116. data/spec_app/db/schema.rb +23 -0
  117. data/spec_app/db/seeds.rb +7 -0
  118. data/spec_app/lib/assets/.keep +0 -0
  119. data/spec_app/lib/tasks/.keep +0 -0
  120. data/spec_app/lib/tasks/cucumber.rake +65 -0
  121. data/spec_app/log/.keep +0 -0
  122. data/spec_app/public/404.html +67 -0
  123. data/spec_app/public/422.html +67 -0
  124. data/spec_app/public/500.html +66 -0
  125. data/spec_app/public/favicon.ico +0 -0
  126. data/spec_app/public/robots.txt +5 -0
  127. data/spec_app/script/cucumber +10 -0
  128. data/spec_app/spec/controllers/test_controller_spec.rb +76 -0
  129. data/spec_app/spec/javascripts/helpers/append_fixture.js.coffee +8 -0
  130. data/spec_app/spec/javascripts/helpers/browser_switches.js.coffee +9 -0
  131. data/spec_app/spec/javascripts/helpers/index.js.coffee +1 -0
  132. data/spec_app/spec/javascripts/helpers/knife.js.coffee +69 -0
  133. data/spec_app/spec/javascripts/helpers/last_request.js.coffee +22 -0
  134. data/spec_app/spec/javascripts/helpers/mock_ajax.js.coffee +5 -0
  135. data/spec_app/spec/javascripts/helpers/mock_clock.js.coffee +2 -0
  136. data/spec_app/spec/javascripts/helpers/remove_body_margin.js.coffee +5 -0
  137. data/spec_app/spec/javascripts/helpers/reset_knife.js.coffee +2 -0
  138. data/spec_app/spec/javascripts/helpers/reset_path.js.coffee +8 -0
  139. data/spec_app/spec/javascripts/helpers/reset_up.js.coffee +4 -0
  140. data/spec_app/spec/javascripts/helpers/restore_body_scroll.js.coffee +2 -0
  141. data/spec_app/spec/javascripts/helpers/set_timer.js.coffee +3 -0
  142. data/spec_app/spec/javascripts/helpers/to_be_around.js.coffee +5 -0
  143. data/spec_app/spec/javascripts/helpers/to_be_blank.js.coffee +5 -0
  144. data/spec_app/spec/javascripts/helpers/to_be_given.js.coffee +5 -0
  145. data/spec_app/spec/javascripts/helpers/to_be_missing.js.coffee +5 -0
  146. data/spec_app/spec/javascripts/helpers/to_be_present.js.coffee +5 -0
  147. data/spec_app/spec/javascripts/helpers/to_end_with.js.coffee +8 -0
  148. data/spec_app/spec/javascripts/helpers/to_equal_jquery.js.coffee +9 -0
  149. data/spec_app/spec/javascripts/helpers/to_have_request_method.js.coffee +8 -0
  150. data/spec_app/spec/javascripts/helpers/trigger.js.coffee +68 -0
  151. data/spec_app/spec/javascripts/support/jasmine.yml +51 -0
  152. data/spec_app/spec/javascripts/up/bus_spec.js.coffee +122 -0
  153. data/spec_app/spec/javascripts/up/flow_spec.js.coffee +755 -0
  154. data/spec_app/spec/javascripts/up/form_spec.js.coffee +471 -0
  155. data/spec_app/spec/javascripts/up/history_spec.js.coffee +96 -0
  156. data/spec_app/spec/javascripts/up/layout_spec.js.coffee +318 -0
  157. data/spec_app/spec/javascripts/up/link_spec.js.coffee +340 -0
  158. data/spec_app/spec/javascripts/up/modal_spec.js.coffee +265 -0
  159. data/spec_app/spec/javascripts/up/motion_spec.js.coffee +306 -0
  160. data/spec_app/spec/javascripts/up/navigation_spec.js.coffee +132 -0
  161. data/spec_app/spec/javascripts/up/popup_spec.js.coffee +220 -0
  162. data/spec_app/spec/javascripts/up/proxy_spec.js.coffee +371 -0
  163. data/spec_app/spec/javascripts/up/rails_spec.js.coffee +101 -0
  164. data/spec_app/spec/javascripts/up/syntax_spec.js.coffee +99 -0
  165. data/spec_app/spec/javascripts/up/tooltip_spec.js.coffee +60 -0
  166. data/spec_app/spec/javascripts/up/util_spec.js.coffee +325 -0
  167. data/spec_app/spec/spec_helper.rb +62 -0
  168. data/spec_app/test/controllers/.keep +0 -0
  169. data/spec_app/test/fixtures/.keep +0 -0
  170. data/spec_app/test/helpers/.keep +0 -0
  171. data/spec_app/test/integration/.keep +0 -0
  172. data/spec_app/test/mailers/.keep +0 -0
  173. data/spec_app/test/models/.keep +0 -0
  174. data/spec_app/test/test_helper.rb +10 -0
  175. data/spec_app/vendor/assets/.bowerrc +3 -0
  176. data/spec_app/vendor/assets/bower.json +8 -0
  177. data/spec_app/vendor/assets/bower_components/jasmine-ajax/.bower.json +43 -0
  178. data/spec_app/vendor/assets/bower_components/jasmine-ajax/MIT.LICENSE +20 -0
  179. data/spec_app/vendor/assets/bower_components/jasmine-ajax/README.markdown +289 -0
  180. data/spec_app/vendor/assets/bower_components/jasmine-ajax/bower.json +35 -0
  181. data/spec_app/vendor/assets/bower_components/jasmine-ajax/lib/mock-ajax.js +733 -0
  182. data/spec_app/vendor/assets/bower_components/jasmine-ajax/package.json +26 -0
  183. data/spec_app/vendor/assets/bower_components/jasmine-ajax/release_notes/2.0.2.md +50 -0
  184. data/spec_app/vendor/assets/bower_components/jasmine-ajax/release_notes/2.99.md +14 -0
  185. data/spec_app/vendor/assets/bower_components/jasmine-ajax/release_notes/3.0.md +28 -0
  186. data/spec_app/vendor/assets/bower_components/jasmine-ajax/release_notes/3.1.0.md +24 -0
  187. data/spec_app/vendor/assets/bower_components/jasmine-ajax/release_notes/3.1.1.md +23 -0
  188. data/spec_app/vendor/assets/bower_components/jasmine-ajax/release_notes/3.2.0.md +20 -0
  189. data/spec_app/vendor/assets/bower_components/jasmine-fixture/.bower.json +27 -0
  190. data/spec_app/vendor/assets/bower_components/jasmine-fixture/.gitignore +8 -0
  191. data/spec_app/vendor/assets/bower_components/jasmine-fixture/.npmignore +8 -0
  192. data/spec_app/vendor/assets/bower_components/jasmine-fixture/LICENSE.txt +24 -0
  193. data/spec_app/vendor/assets/bower_components/jasmine-fixture/README.md +118 -0
  194. data/spec_app/vendor/assets/bower_components/jasmine-fixture/bower.json +17 -0
  195. data/spec_app/vendor/assets/bower_components/jasmine-fixture/dist/jasmine-fixture.js +433 -0
  196. data/spec_app/vendor/assets/bower_components/jasmine-fixture/dist/jasmine-fixture.min.js +5 -0
  197. data/spec_app/vendor/assets/bower_components/jasmine-fixture/spec-e2e/basic-usage-spec.coffee +14 -0
  198. data/spec_app/vendor/assets/bower_components/jasmine-fixture/spec-e2e/helpers/invariants.coffee +17 -0
  199. data/spec_app/vendor/assets/bower_components/jasmine-fixture/spec-e2e/helpers/spec-within-a-spec.coffee +24 -0
  200. data/spec_app/vendor/assets/bower_components/jasmine-fixture/spec-e2e/helpers/tmp-files.coffee +8 -0
  201. data/spec_app/vendor/assets/bower_components/jasmine-fixture/spec-e2e/support/jasmine1-testem-config.json +11 -0
  202. data/spec_app/vendor/assets/bower_components/jasmine-fixture/spec-e2e/support/jasmine2-testem-config.json +11 -0
  203. data/spec_app/vendor/assets/bower_components/jasmine-fixture/vendor/js/jquery-1.11.0.js +10337 -0
  204. data/spec_app/vendor/assets/bower_components/jasmine-fixture/vendor/js/jquery-1.8.3.js +9472 -0
  205. data/spec_app/vendor/assets/bower_components/jasmine-fixture/vendor/js/jquery-2.1.0.js +9111 -0
  206. data/spec_app/vendor/assets/bower_components/jasmine-jquery/.bower.json +26 -0
  207. data/spec_app/vendor/assets/bower_components/jasmine-jquery/CONTRIBUTING.md +28 -0
  208. data/spec_app/vendor/assets/bower_components/jasmine-jquery/Gruntfile.js +49 -0
  209. data/spec_app/vendor/assets/bower_components/jasmine-jquery/LICENSE +20 -0
  210. data/spec_app/vendor/assets/bower_components/jasmine-jquery/README.md +367 -0
  211. data/spec_app/vendor/assets/bower_components/jasmine-jquery/bower.json +15 -0
  212. data/spec_app/vendor/assets/bower_components/jasmine-jquery/lib/jasmine-jquery.js +838 -0
  213. data/spec_app/vendor/assets/bower_components/jasmine-jquery/package.json +35 -0
  214. data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/fixture_with_checkbox_with_checked.html +6 -0
  215. data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/fixture_with_javascript.html +1 -0
  216. data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/fixture_with_javascript_block.html +1 -0
  217. data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/javascripts/jasmine_javascript_click.js +1 -0
  218. data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/javascripts/jasmine_javascript_hover.js +1 -0
  219. data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/json/jasmine_json_test.json +1 -0
  220. data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/real_non_mocked_fixture.html +1 -0
  221. data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/real_non_mocked_fixture_style.css +1 -0
  222. data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/suites/jasmine-jquery-spec.js +1842 -0
  223. data/spec_app/vendor/assets/bower_components/jasmine/.bower.json +50 -0
  224. data/spec_app/vendor/assets/bower_components/jasmine/CONTRIBUTING.md +130 -0
  225. data/spec_app/vendor/assets/bower_components/jasmine/GOALS_2.0.md +64 -0
  226. data/spec_app/vendor/assets/bower_components/jasmine/MANIFEST.in +5 -0
  227. data/spec_app/vendor/assets/bower_components/jasmine/MIT.LICENSE +20 -0
  228. data/spec_app/vendor/assets/bower_components/jasmine/README.md +73 -0
  229. data/spec_app/vendor/assets/bower_components/jasmine/RELEASE.md +73 -0
  230. data/spec_app/vendor/assets/bower_components/jasmine/bower.json +41 -0
  231. data/spec_app/vendor/assets/bower_components/jasmine/images/jasmine-horizontal.png +0 -0
  232. data/spec_app/vendor/assets/bower_components/jasmine/images/jasmine-horizontal.svg +102 -0
  233. data/spec_app/vendor/assets/bower_components/jasmine/images/jasmine_favicon.png +0 -0
  234. data/spec_app/vendor/assets/bower_components/jasmine/lib/console/console.js +190 -0
  235. data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core.js +37 -0
  236. data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/boot.js +143 -0
  237. data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/example/node_example/lib/jasmine_examples/Player.js +24 -0
  238. data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/example/node_example/lib/jasmine_examples/Song.js +9 -0
  239. data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/jasmine-html.js +446 -0
  240. data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/jasmine.css +58 -0
  241. data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/jasmine.js +3298 -0
  242. data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/json2.js +489 -0
  243. data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/node_boot.js +41 -0
  244. data/spec_app/vendor/assets/bower_components/jasmine/package.json +34 -0
  245. data/spec_app/vendor/assets/bower_components/jasmine/requirements.txt +1 -0
  246. data/spec_app/vendor/assets/bower_components/jquery/.bower.json +38 -0
  247. data/spec_app/vendor/assets/bower_components/jquery/MIT-LICENSE.txt +21 -0
  248. data/spec_app/vendor/assets/bower_components/jquery/bower.json +28 -0
  249. data/spec_app/vendor/assets/bower_components/jquery/dist/jquery.js +9210 -0
  250. data/spec_app/vendor/assets/bower_components/jquery/dist/jquery.min.js +5 -0
  251. data/spec_app/vendor/assets/bower_components/jquery/dist/jquery.min.map +1 -0
  252. data/spec_app/vendor/assets/bower_components/jquery/src/ajax.js +786 -0
  253. data/spec_app/vendor/assets/bower_components/jquery/src/ajax/jsonp.js +89 -0
  254. data/spec_app/vendor/assets/bower_components/jquery/src/ajax/load.js +75 -0
  255. data/spec_app/vendor/assets/bower_components/jquery/src/ajax/parseJSON.js +13 -0
  256. data/spec_app/vendor/assets/bower_components/jquery/src/ajax/parseXML.js +28 -0
  257. data/spec_app/vendor/assets/bower_components/jquery/src/ajax/script.js +64 -0
  258. data/spec_app/vendor/assets/bower_components/jquery/src/ajax/var/nonce.js +5 -0
  259. data/spec_app/vendor/assets/bower_components/jquery/src/ajax/var/rquery.js +3 -0
  260. data/spec_app/vendor/assets/bower_components/jquery/src/ajax/xhr.js +136 -0
  261. data/spec_app/vendor/assets/bower_components/jquery/src/attributes.js +11 -0
  262. data/spec_app/vendor/assets/bower_components/jquery/src/attributes/attr.js +141 -0
  263. data/spec_app/vendor/assets/bower_components/jquery/src/attributes/classes.js +158 -0
  264. data/spec_app/vendor/assets/bower_components/jquery/src/attributes/prop.js +94 -0
  265. data/spec_app/vendor/assets/bower_components/jquery/src/attributes/support.js +35 -0
  266. data/spec_app/vendor/assets/bower_components/jquery/src/attributes/val.js +161 -0
  267. data/spec_app/vendor/assets/bower_components/jquery/src/callbacks.js +205 -0
  268. data/spec_app/vendor/assets/bower_components/jquery/src/core.js +502 -0
  269. data/spec_app/vendor/assets/bower_components/jquery/src/core/access.js +60 -0
  270. data/spec_app/vendor/assets/bower_components/jquery/src/core/init.js +123 -0
  271. data/spec_app/vendor/assets/bower_components/jquery/src/core/parseHTML.js +39 -0
  272. data/spec_app/vendor/assets/bower_components/jquery/src/core/ready.js +97 -0
  273. data/spec_app/vendor/assets/bower_components/jquery/src/core/var/rsingleTag.js +4 -0
  274. data/spec_app/vendor/assets/bower_components/jquery/src/css.js +450 -0
  275. data/spec_app/vendor/assets/bower_components/jquery/src/css/addGetHookIf.js +22 -0
  276. data/spec_app/vendor/assets/bower_components/jquery/src/css/curCSS.js +57 -0
  277. data/spec_app/vendor/assets/bower_components/jquery/src/css/defaultDisplay.js +70 -0
  278. data/spec_app/vendor/assets/bower_components/jquery/src/css/hiddenVisibleSelectors.js +15 -0
  279. data/spec_app/vendor/assets/bower_components/jquery/src/css/support.js +96 -0
  280. data/spec_app/vendor/assets/bower_components/jquery/src/css/swap.js +28 -0
  281. data/spec_app/vendor/assets/bower_components/jquery/src/css/var/cssExpand.js +3 -0
  282. data/spec_app/vendor/assets/bower_components/jquery/src/css/var/getStyles.js +12 -0
  283. data/spec_app/vendor/assets/bower_components/jquery/src/css/var/isHidden.js +13 -0
  284. data/spec_app/vendor/assets/bower_components/jquery/src/css/var/rmargin.js +3 -0
  285. data/spec_app/vendor/assets/bower_components/jquery/src/css/var/rnumnonpx.js +5 -0
  286. data/spec_app/vendor/assets/bower_components/jquery/src/data.js +178 -0
  287. data/spec_app/vendor/assets/bower_components/jquery/src/data/Data.js +181 -0
  288. data/spec_app/vendor/assets/bower_components/jquery/src/data/accepts.js +20 -0
  289. data/spec_app/vendor/assets/bower_components/jquery/src/data/var/data_priv.js +5 -0
  290. data/spec_app/vendor/assets/bower_components/jquery/src/data/var/data_user.js +5 -0
  291. data/spec_app/vendor/assets/bower_components/jquery/src/deferred.js +149 -0
  292. data/spec_app/vendor/assets/bower_components/jquery/src/deprecated.js +13 -0
  293. data/spec_app/vendor/assets/bower_components/jquery/src/dimensions.js +50 -0
  294. data/spec_app/vendor/assets/bower_components/jquery/src/effects.js +648 -0
  295. data/spec_app/vendor/assets/bower_components/jquery/src/effects/Tween.js +114 -0
  296. data/spec_app/vendor/assets/bower_components/jquery/src/effects/animatedSelector.js +13 -0
  297. data/spec_app/vendor/assets/bower_components/jquery/src/event.js +868 -0
  298. data/spec_app/vendor/assets/bower_components/jquery/src/event/ajax.js +13 -0
  299. data/spec_app/vendor/assets/bower_components/jquery/src/event/alias.js +39 -0
  300. data/spec_app/vendor/assets/bower_components/jquery/src/event/support.js +9 -0
  301. data/spec_app/vendor/assets/bower_components/jquery/src/exports/amd.js +24 -0
  302. data/spec_app/vendor/assets/bower_components/jquery/src/exports/global.js +32 -0
  303. data/spec_app/vendor/assets/bower_components/jquery/src/intro.js +44 -0
  304. data/spec_app/vendor/assets/bower_components/jquery/src/jquery.js +37 -0
  305. data/spec_app/vendor/assets/bower_components/jquery/src/manipulation.js +580 -0
  306. data/spec_app/vendor/assets/bower_components/jquery/src/manipulation/_evalUrl.js +18 -0
  307. data/spec_app/vendor/assets/bower_components/jquery/src/manipulation/support.js +32 -0
  308. data/spec_app/vendor/assets/bower_components/jquery/src/manipulation/var/rcheckableType.js +3 -0
  309. data/spec_app/vendor/assets/bower_components/jquery/src/offset.js +207 -0
  310. data/spec_app/vendor/assets/bower_components/jquery/src/outro.js +1 -0
  311. data/spec_app/vendor/assets/bower_components/jquery/src/queue.js +142 -0
  312. data/spec_app/vendor/assets/bower_components/jquery/src/queue/delay.js +22 -0
  313. data/spec_app/vendor/assets/bower_components/jquery/src/selector-native.js +172 -0
  314. data/spec_app/vendor/assets/bower_components/jquery/src/selector-sizzle.js +14 -0
  315. data/spec_app/vendor/assets/bower_components/jquery/src/selector.js +1 -0
  316. data/spec_app/vendor/assets/bower_components/jquery/src/serialize.js +111 -0
  317. data/spec_app/vendor/assets/bower_components/jquery/src/sizzle/dist/sizzle.js +2067 -0
  318. data/spec_app/vendor/assets/bower_components/jquery/src/sizzle/dist/sizzle.min.js +3 -0
  319. data/spec_app/vendor/assets/bower_components/jquery/src/sizzle/dist/sizzle.min.map +1 -0
  320. data/spec_app/vendor/assets/bower_components/jquery/src/traversing.js +199 -0
  321. data/spec_app/vendor/assets/bower_components/jquery/src/traversing/findFilter.js +100 -0
  322. data/spec_app/vendor/assets/bower_components/jquery/src/traversing/var/rneedsContext.js +6 -0
  323. data/spec_app/vendor/assets/bower_components/jquery/src/var/arr.js +3 -0
  324. data/spec_app/vendor/assets/bower_components/jquery/src/var/class2type.js +4 -0
  325. data/spec_app/vendor/assets/bower_components/jquery/src/var/concat.js +5 -0
  326. data/spec_app/vendor/assets/bower_components/jquery/src/var/hasOwn.js +5 -0
  327. data/spec_app/vendor/assets/bower_components/jquery/src/var/indexOf.js +5 -0
  328. data/spec_app/vendor/assets/bower_components/jquery/src/var/pnum.js +3 -0
  329. data/spec_app/vendor/assets/bower_components/jquery/src/var/push.js +5 -0
  330. data/spec_app/vendor/assets/bower_components/jquery/src/var/rnotwhite.js +3 -0
  331. data/spec_app/vendor/assets/bower_components/jquery/src/var/slice.js +5 -0
  332. data/spec_app/vendor/assets/bower_components/jquery/src/var/strundefined.js +3 -0
  333. data/spec_app/vendor/assets/bower_components/jquery/src/var/support.js +4 -0
  334. data/spec_app/vendor/assets/bower_components/jquery/src/var/toString.js +5 -0
  335. data/spec_app/vendor/assets/bower_components/jquery/src/wrap.js +79 -0
  336. data/spec_app/vendor/assets/javascripts/.keep +0 -0
  337. data/spec_app/vendor/assets/stylesheets/.keep +0 -0
  338. data/unpoly-rails.gemspec +24 -0
  339. metadata +423 -0
@@ -0,0 +1,1593 @@
1
+ ###*
2
+ Utility functions
3
+ =================
4
+
5
+ Unpoly comes with a number of utility functions
6
+ that might save you from loading something like [Underscore.js](http://underscorejs.org/).
7
+
8
+ @class up.util
9
+ ###
10
+ up.util = (($) ->
11
+
12
+ ###*
13
+ @function up.util.memoize
14
+ @internal
15
+ ###
16
+ memoize = (func) ->
17
+ cache = undefined
18
+ cached = false
19
+ (args...) ->
20
+ if cached
21
+ cache
22
+ else
23
+ cached = true
24
+ cache = func(args...)
25
+
26
+ ###*
27
+ Returns if the given port is the default port for the given protocol.
28
+
29
+ @function up.util.isStandardPort
30
+ @internal
31
+ ###
32
+ isStandardPort = (protocol, port) ->
33
+ port = port.toString()
34
+ ((port == "" || port == "80") && protocol == 'http:') || (port == "443" && protocol == 'https:')
35
+
36
+ ###*
37
+ Normalizes relative paths and absolute paths to a full URL
38
+ that can be checked for equality with other normalized URLs.
39
+
40
+ By default hashes are ignored, search queries are included.
41
+
42
+ @function up.util.normalizeUrl
43
+ @param {Boolean} [options.hash=false]
44
+ Whether to include an `#hash` anchor in the normalized URL
45
+ @param {Boolean} [options.search=true]
46
+ Whether to include a `?query` string in the normalized URL
47
+ @param {Boolean} [options.stripTrailingSlash=false]
48
+ Whether to strip a trailing slash from the pathname
49
+ @internal
50
+ ###
51
+ normalizeUrl = (urlOrAnchor, options) ->
52
+ anchor = parseUrl(urlOrAnchor)
53
+ normalized = anchor.protocol + "//" + anchor.hostname
54
+ normalized += ":#{anchor.port}" unless isStandardPort(anchor.protocol, anchor.port)
55
+ pathname = anchor.pathname
56
+ # Some IEs don't include a leading slash in the #pathname property.
57
+ # We have seen this in IE11 and W3Schools claims it happens in IE9 or earlier
58
+ # http://www.w3schools.com/jsref/prop_anchor_pathname.asp
59
+ pathname = "/#{pathname}" unless pathname[0] == '/'
60
+ pathname = pathname.replace(/\/$/, '') if options?.stripTrailingSlash == true
61
+ normalized += pathname
62
+ normalized += anchor.hash if options?.hash == true
63
+ normalized += anchor.search unless options?.search == false
64
+ normalized
65
+
66
+ ###*
67
+ Parses the given URL into components such as hostname and path.
68
+
69
+ If the given URL is not fully qualified, it is assumed to be relative
70
+ to the current page.
71
+
72
+ @function up.util.parseUrl
73
+ @return {Object}
74
+ The parsed URL as an object with
75
+ `protocol`, `hostname`, `port`, `pathname`, `search` and `hash`
76
+ properties.
77
+ @experimental
78
+ ###
79
+ parseUrl = (urlOrAnchor) ->
80
+ anchor = null
81
+ if isString(urlOrAnchor)
82
+ anchor = $('<a>').attr(href: urlOrAnchor).get(0)
83
+ # In IE11 the #hostname and #port properties of such a link are empty
84
+ # strings. However, we can fix this by assigning the anchor its own
85
+ # href because computer:
86
+ # https://gist.github.com/jlong/2428561#comment-1461205
87
+ anchor.href = anchor.href if isBlank(anchor.hostname)
88
+ else
89
+ anchor = unJQuery(urlOrAnchor)
90
+ anchor
91
+
92
+ ###*
93
+ @function up.util.normalizeMethod
94
+ @internal
95
+ ###
96
+ normalizeMethod = (method) ->
97
+ if method
98
+ method.toUpperCase()
99
+ else
100
+ 'GET'
101
+
102
+ ###*
103
+ @function $createElementFromSelector
104
+ @internal
105
+ ###
106
+ $createElementFromSelector = (selector) ->
107
+ path = selector.split(/[ >]/)
108
+ $root = null
109
+ for depthSelector, iteration in path
110
+ conjunction = depthSelector.match(/(^|\.|\#)[A-Za-z0-9\-_]+/g)
111
+ tag = "div"
112
+ classes = []
113
+ id = null
114
+ for expression in conjunction
115
+ switch expression[0]
116
+ when "."
117
+ classes.push expression.substr(1)
118
+ when "#"
119
+ id = expression.substr(1)
120
+ else
121
+ tag = expression
122
+ html = "<" + tag
123
+ html += " class=\"" + classes.join(" ") + "\"" if classes.length
124
+ html += " id=\"" + id + "\"" if id
125
+ html += ">"
126
+ $element = $(html)
127
+ $element.appendTo($parent) if $parent
128
+ $root = $element if iteration == 0
129
+ $parent = $element
130
+ $root
131
+
132
+ createElement = (tagName, html) ->
133
+ element = document.createElement(tagName)
134
+ element.innerHTML = html if isPresent(html)
135
+ element
136
+
137
+ ###*
138
+ @function $create
139
+ ###
140
+ $createPlaceholder = (selector, container = document.body) ->
141
+ $placeholder = $createElementFromSelector(selector)
142
+ $placeholder.addClass('up-placeholder')
143
+ $placeholder.appendTo(container)
144
+ $placeholder
145
+
146
+ ###*
147
+ Returns a CSS selector that matches the given element as good as possible.
148
+
149
+ This uses, in decreasing order of priority:
150
+
151
+ - The element's `up-id` attribute
152
+ - The element's ID
153
+ - The element's name
154
+ - The element's classes
155
+ - The element's tag names
156
+
157
+ @function up.util.selectorForElement
158
+ @param {String|Element|jQuery}
159
+ The element for which to create a selector.
160
+ @experimental
161
+ ###
162
+ selectorForElement = (element) ->
163
+ $element = $(element)
164
+ selector = undefined
165
+
166
+ up.puts("Creating selector from element %o", $element.get(0))
167
+
168
+ if upId = presence($element.attr("up-id"))
169
+ selector = "[up-id='#{upId}']"
170
+ else if id = presence($element.attr("id"))
171
+ selector = "##{id}"
172
+ else if name = presence($element.attr("name"))
173
+ selector = "[name='#{name}']"
174
+ else if classes = presence(nonUpClasses($element))
175
+ selector = ''
176
+ for klass in classes
177
+ selector += ".#{klass}"
178
+ else
179
+ selector = $element.prop('tagName').toLowerCase()
180
+ selector
181
+
182
+ nonUpClasses = ($element) ->
183
+ classString = $element.attr('class') || ''
184
+ classes = classString.split(' ')
185
+ select classes, (klass) -> isPresent(klass) && !klass.match(/^up-/)
186
+
187
+ # jQuery's implementation of $(...) cannot create elements that have
188
+ # an <html> or <body> tag. So we're using native elements.
189
+ # Also IE9 cannot set innerHTML on a <html> or <head> element.
190
+ createElementFromHtml = (html) ->
191
+
192
+ openTag = (tag) -> "<#{tag}(?: [^>]*)?>"
193
+ closeTag = (tag) -> "</#{tag}>"
194
+ anything = '(?:.|\\n)*?'
195
+ capture = (pattern) -> "(#{pattern})"
196
+
197
+ titlePattern = new RegExp(
198
+ openTag('head') +
199
+ anything +
200
+ openTag('title') +
201
+ capture(anything) +
202
+ closeTag('title') +
203
+ anything +
204
+ closeTag('body'),
205
+ 'i')
206
+
207
+ bodyPattern = new RegExp(
208
+ openTag('body') +
209
+ capture(anything) +
210
+ closeTag('body'),
211
+ 'i')
212
+
213
+ if bodyMatch = html.match(bodyPattern)
214
+
215
+ htmlElement = document.createElement('html')
216
+ bodyElement = createElement('body', bodyMatch[1])
217
+ htmlElement.appendChild(bodyElement)
218
+
219
+ if titleMatch = html.match(titlePattern)
220
+ headElement = createElement('head')
221
+ htmlElement.appendChild(headElement)
222
+ titleElement = createElement('title', titleMatch[1])
223
+ headElement.appendChild(titleElement)
224
+
225
+ htmlElement
226
+
227
+ else
228
+
229
+ # we possibly received a layout-less fragment
230
+ createElement('div', html)
231
+
232
+ ###*
233
+ Merge the contents of two or more objects together into the first object.
234
+
235
+ @function up.util.extend
236
+ @param {Object} target
237
+ @param {Array<Object>} sources...
238
+ @stable
239
+ ###
240
+ extend = $.extend
241
+
242
+ ###*
243
+ Returns a new string with whitespace removed from the beginning
244
+ and end of the given string.
245
+
246
+ @param {String}
247
+ A string that might have whitespace at the beginning and end.
248
+ @return {String}
249
+ The trimmed string.
250
+ @stable
251
+ ###
252
+ trim = $.trim
253
+
254
+ ###*
255
+ Calls the given function for each element (and, optional, index)
256
+ of the given array.
257
+
258
+ @function up.util.each
259
+ @param {Array} array
260
+ @param {Function<Object, Number>} block
261
+ A function that will be called with each element and (optional) iteration index.
262
+ @stable
263
+ ###
264
+ each = (array, block) ->
265
+ block(item, index) for item, index in array
266
+
267
+ ###*
268
+ Translate all items in an array to new array of items.
269
+
270
+ @function up.util.map
271
+ @param {Array} array
272
+ @param {Function<Object, Number>} block
273
+ A function that will be called with each element and (optional) iteration index.
274
+ @return {Array}
275
+ A new array containing the result of each function call.
276
+ @stable
277
+ ###
278
+ map = each
279
+
280
+ ###*
281
+ Calls the given function for the given number of times.
282
+
283
+ @function up.util.times
284
+ @param {Number} count
285
+ @param {Function} block
286
+ @stable
287
+ ###
288
+ times = (count, block) ->
289
+ block(iteration) for iteration in [0..(count - 1)]
290
+
291
+ ###*
292
+ Returns whether the given argument is `null`.
293
+
294
+ @function up.util.isNull
295
+ @param object
296
+ @return {Boolean}
297
+ @stable
298
+ ###
299
+ isNull = (object) ->
300
+ object == null
301
+
302
+ ###*
303
+ Returns whether the given argument is `undefined`.
304
+
305
+ @function up.util.isUndefined
306
+ @param object
307
+ @return {Boolean}
308
+ @stable
309
+ ###
310
+ isUndefined = (object) ->
311
+ object == `void(0)`
312
+
313
+ ###*
314
+ Returns whether the given argument is not `undefined`.
315
+
316
+ @function up.util.isDefined
317
+ @param object
318
+ @return {Boolean}
319
+ @stable
320
+ ###
321
+ isDefined = (object) ->
322
+ !isUndefined(object)
323
+
324
+ ###*
325
+ Returns whether the given argument is either `undefined` or `null`.
326
+
327
+ Note that empty strings or zero are *not* considered to be "missing".
328
+
329
+ For the opposite of `up.util.isMissing` see [`up.util.isGiven`](/up.util.isGiven).
330
+
331
+ @function up.util.isMissing
332
+ @param object
333
+ @return {Boolean}
334
+ @stable
335
+ ###
336
+ isMissing = (object) ->
337
+ isUndefined(object) || isNull(object)
338
+
339
+ ###*
340
+ Returns whether the given argument is neither `undefined` nor `null`.
341
+
342
+ Note that empty strings or zero *are* considered to be "given".
343
+
344
+ For the opposite of `up.util.isGiven` see [`up.util.isMissing`](/up.util.isMissing).
345
+
346
+ @function up.util.isGiven
347
+ @param object
348
+ @return {Boolean}
349
+ @stable
350
+ ###
351
+ isGiven = (object) ->
352
+ !isMissing(object)
353
+
354
+ ###*
355
+ Return whether the given argument is considered to be blank.
356
+
357
+ This returns `true` for:
358
+
359
+ - `undefined`
360
+ - `null`
361
+ - Empty strings
362
+ - Empty arrays
363
+ - An object without own enumerable properties
364
+
365
+ All other arguments return `false`.
366
+
367
+ @function up.util.isBlank
368
+ @param object
369
+ @return {Boolean}
370
+ @stable
371
+ ###
372
+ isBlank = (object) ->
373
+ isMissing(object) || # null or undefined
374
+ (isObject(object) && Object.keys(object).length == 0) ||
375
+ (object.length == 0) # String, Array, jQuery
376
+
377
+ ###*
378
+ Returns the given argument if the argument is [present](/up.util.isPresent),
379
+ otherwise returns `undefined`.
380
+
381
+ @function up.util.presence
382
+ @param object
383
+ @param {Function<T>} [tester=up.util.isPresent]
384
+ The function that will be used to test whether the argument is present.
385
+ @return {T|Undefined}
386
+ @stable
387
+ ###
388
+ presence = (object, tester = isPresent) ->
389
+ if tester(object) then object else undefined
390
+
391
+ ###*
392
+ Returns whether the given argument is not [blank](/up.util.isBlank).
393
+
394
+ @function up.util.isPresent
395
+ @param object
396
+ @return {Boolean}
397
+ @stable
398
+ ###
399
+ isPresent = (object) ->
400
+ !isBlank(object)
401
+
402
+ ###*
403
+ Returns whether the given argument is a function.
404
+
405
+ @function up.util.isFunction
406
+ @param object
407
+ @return {Boolean}
408
+ @stable
409
+ ###
410
+ isFunction = (object) ->
411
+ typeof(object) == 'function'
412
+
413
+ ###*
414
+ Returns whether the given argument is a string.
415
+
416
+ @function up.util.isString
417
+ @param object
418
+ @return {Boolean}
419
+ @stable
420
+ ###
421
+ isString = (object) ->
422
+ typeof(object) == 'string'
423
+
424
+ ###*
425
+ Returns whether the given argument is a number.
426
+
427
+ Note that this will check the argument's *type*.
428
+ It will return `false` for a string like `"123"`.
429
+
430
+ @function up.util.isNumber
431
+ @param object
432
+ @return {Boolean}
433
+ @stable
434
+ ###
435
+ isNumber = (object) ->
436
+ typeof(object) == 'number'
437
+
438
+ ###*
439
+ Returns whether the given argument is an object, but not a function.
440
+
441
+ @function up.util.isHash
442
+ @param object
443
+ @return {Boolean}
444
+ @stable
445
+ ###
446
+ isHash = (object) ->
447
+ typeof(object) == 'object' && !!object
448
+
449
+ ###*
450
+ Returns whether the given argument is an object.
451
+
452
+ This also returns `true` for functions, which may behave like objects in Javascript.
453
+ For an alternative that returns `false` for functions, see [`up.util.isHash`](/up.util.isHash).
454
+
455
+ @function up.util.isObject
456
+ @param object
457
+ @return {Boolean}
458
+ @stable
459
+ ###
460
+ isObject = (object) ->
461
+ isHash(object) || (typeof object == 'function')
462
+
463
+ ###*
464
+ Returns whether the given argument is a DOM element.
465
+
466
+ @function up.util.isElement
467
+ @param object
468
+ @return {Boolean}
469
+ @stable
470
+ ###
471
+ isElement = (object) ->
472
+ !!(object && object.nodeType == 1)
473
+
474
+ ###*
475
+ Returns whether the given argument is a jQuery collection.
476
+
477
+ @function up.util.isJQuery
478
+ @param object
479
+ @return {Boolean}
480
+ @stable
481
+ ###
482
+ isJQuery = (object) ->
483
+ object instanceof jQuery
484
+
485
+ ###*
486
+ Returns whether the given argument is an object with a `then` method.
487
+
488
+ @function up.util.isPromise
489
+ @param object
490
+ @return {Boolean}
491
+ @stable
492
+ ###
493
+ isPromise = (object) ->
494
+ isObject(object) && isFunction(object.then)
495
+
496
+ ###*
497
+ Returns whether the given argument is an object with `then` and `resolve` methods.
498
+
499
+ @function up.util.isDeferred
500
+ @param object
501
+ @return {Boolean}
502
+ @stable
503
+ ###
504
+ isDeferred = (object) ->
505
+ isPromise(object) && isFunction(object.resolve)
506
+
507
+ ###*
508
+ Returns whether the given argument is an array.
509
+
510
+ @function up.util.isArray
511
+ @param object
512
+ @return {Boolean}
513
+ @stable
514
+ ###
515
+ # https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
516
+ isArray = Array.isArray ||
517
+ (object) -> Object.prototype.toString.call(object) == '[object Array]'
518
+
519
+ ###*
520
+ Converts the given array-like argument into an array.
521
+
522
+ Returns the array.
523
+
524
+ @function up.util.isDeferred
525
+ @param object
526
+ @return {Array}
527
+ @stable
528
+ ###
529
+ toArray = (object) ->
530
+ Array.prototype.slice.call(object)
531
+
532
+ ###*
533
+ Shallow-copies the given array or object into a new array or object.
534
+
535
+ Returns the new array or object.
536
+
537
+ @function up.util.copy
538
+ @param {Object|Array} object
539
+ @return {Object|Array}
540
+ @stable
541
+ ###
542
+ copy = (object) ->
543
+ if isArray(object)
544
+ object.slice()
545
+ else
546
+ extend({}, object)
547
+
548
+ ###*
549
+ If given a jQuery collection, returns the underlying array of DOM element.
550
+ If given any other argument, returns the argument unchanged.
551
+
552
+ @function up.util.unJQuery
553
+ @param object
554
+ @internal
555
+ ###
556
+ unJQuery = (object) ->
557
+ if isJQuery(object)
558
+ object.get(0)
559
+ else
560
+ object
561
+
562
+ ###*
563
+ Creates a new object by merging together the properties from the given objects.
564
+
565
+ @function up.util.merge
566
+ @param {Array<Object>} sources...
567
+ @return Object
568
+ @stable
569
+ ###
570
+ merge = (sources...) ->
571
+ extend({}, sources...)
572
+
573
+ ###*
574
+ Creates an options hash from the given argument and some defaults.
575
+
576
+ The semantics of this function are confusing.
577
+ We want to get rid of this in the future.
578
+
579
+ @function up.util.options
580
+ @param {Object} object
581
+ @param {Object} [defaults]
582
+ @return {Object}
583
+ @internal
584
+ ###
585
+ options = (object, defaults) ->
586
+ merged = if object then copy(object) else {}
587
+ if defaults
588
+ for key, defaultValue of defaults
589
+ value = merged[key]
590
+ if !isGiven(value)
591
+ merged[key] = defaultValue
592
+ else if isObject(defaultValue) && isObject(value)
593
+ merged[key] = options(value, defaultValue)
594
+ merged
595
+
596
+ ###*
597
+ Returns the first argument that is considered present.
598
+
599
+ This function is useful when you have multiple option sources and the value can be boolean.
600
+ In that case you cannot change the sources with a `||` operator
601
+ (since that doesn't short-circuit at `false`).
602
+
603
+ @function up.util.option
604
+ @param {Array} args...
605
+ @internal
606
+ ###
607
+ option = (args...) ->
608
+ detect(args, isGiven)
609
+
610
+ ###*
611
+ Passes each element in the given array to the given function.
612
+ Returns the first element for which the function returns a truthy value.
613
+
614
+ If no object matches, returns `undefined`.
615
+
616
+ @function up.util.detect
617
+ @param {Array<T>} array
618
+ @param {Function<T>} tester
619
+ @return {T|Undefined}
620
+ @stable
621
+ ###
622
+ detect = (array, tester) ->
623
+ match = undefined
624
+ for element in array
625
+ if tester(element)
626
+ match = element
627
+ break
628
+ match
629
+
630
+ ###*
631
+ Returns whether the given function returns a truthy value
632
+ for any element in the given array.
633
+
634
+ @function up.util.any
635
+ @param {Array<T>} array
636
+ @param {Function<T>} tester
637
+ @return {Boolean}
638
+ @experimental
639
+ ###
640
+ any = (array, tester) ->
641
+ match = false
642
+ for element in array
643
+ if tester(element)
644
+ match = true
645
+ break
646
+ match
647
+
648
+ ###*
649
+ Returns whether the given function returns a truthy value
650
+ for all elements in the given array.
651
+
652
+ @function up.util.all
653
+ @param {Array<T>} array
654
+ @param {Function<T>} tester
655
+ @return {Boolean}
656
+ @experimental
657
+ ###
658
+ all = (array, tester) ->
659
+ match = true
660
+ for element in array
661
+ unless tester(element)
662
+ match = false
663
+ break
664
+ match
665
+
666
+ ###*
667
+ Returns all elements from the given array that are
668
+ neither `null` or `undefined`.
669
+
670
+ @function up.util.compact
671
+ @param {Array<T>} array
672
+ @return {Array<T>}
673
+ @stable
674
+ ###
675
+ compact = (array) ->
676
+ select array, isGiven
677
+
678
+ ###*
679
+ Returns the given array without duplicates.
680
+
681
+ @function up.util.uniq
682
+ @param {Array<T>} array
683
+ @return {Array<T>}
684
+ @stable
685
+ ###
686
+ uniq = (array) ->
687
+ seen = {}
688
+ select array, (element) ->
689
+ if seen.hasOwnProperty(element)
690
+ false
691
+ else
692
+ seen[element] = true
693
+
694
+ ###*
695
+ Returns all elements from the given array that return
696
+ a truthy value when passed to the given function.
697
+
698
+ @function up.util.select
699
+ @param {Array<T>} array
700
+ @return {Array<T>}
701
+ @stable
702
+ ###
703
+ select = (array, tester) ->
704
+ matches = []
705
+ each array, (element) ->
706
+ if tester(element)
707
+ matches.push(element)
708
+ matches
709
+
710
+ ###*
711
+ Returns all elements from the given array that do not return
712
+ a truthy value when passed to the given function.
713
+
714
+ @function up.util.reject
715
+ @param {Array<T>} array
716
+ @return {Array<T>}
717
+ @stable
718
+ ###
719
+ reject = (array, tester) ->
720
+ select(array, (element) -> !tester(element))
721
+
722
+ ###*
723
+ Returns the intersection of the given two arrays.
724
+
725
+ Implementation is not optimized. Don't use it for large arrays.
726
+
727
+ @function up.util.intersect
728
+ @internal
729
+ ###
730
+ intersect = (array1, array2) ->
731
+ select array1, (element) ->
732
+ contains(array2, element)
733
+
734
+ ###*
735
+ Returns the first [present](/up.util.isPresent) element attribute
736
+ among the given list of attribute names.
737
+
738
+ @function up.util.presentAttr
739
+ @internal
740
+ ###
741
+ presentAttr = ($element, attrNames...) ->
742
+ values = ($element.attr(attrName) for attrName in attrNames)
743
+ detect(values, isPresent)
744
+
745
+ ###*
746
+ Schedules the given function to be called in the
747
+ next Javascript execution frame.
748
+
749
+ @function up.util.nextFrame
750
+ @param {Function} block
751
+ @stable
752
+ ###
753
+ nextFrame = (block) ->
754
+ setTimeout(block, 0)
755
+
756
+ ###*
757
+ Returns the last element of the given array.
758
+
759
+ @function up.util.last
760
+ @param {Array<T>} array
761
+ @return {T}
762
+ ###
763
+ last = (array) ->
764
+ array[array.length - 1]
765
+
766
+ ###*
767
+ Measures the drawable area of the document.
768
+
769
+ @function up.util.clientSize
770
+ @internal
771
+ ###
772
+ clientSize = ->
773
+ element = document.documentElement
774
+ width: element.clientWidth
775
+ height: element.clientHeight
776
+
777
+ ###*
778
+ Returns the width of a scrollbar.
779
+
780
+ This only runs once per page load.
781
+
782
+ @function up.util.scrollbarWidth
783
+ @internal
784
+ ###
785
+ scrollbarWidth = memoize ->
786
+ # This is how Bootstrap does it also:
787
+ # https://github.com/twbs/bootstrap/blob/c591227602996c542b9fd0cb65cff3cc9519bdd5/dist/js/bootstrap.js#L1187
788
+ $outer = $('<div>').css
789
+ position: 'absolute'
790
+ top: '0'
791
+ left: '0'
792
+ width: '50px'
793
+ height: '50px'
794
+ overflowY: 'scroll'
795
+ $outer.appendTo(document.body)
796
+ outer = $outer.get(0)
797
+ width = outer.offsetWidth - outer.clientWidth
798
+ $outer.remove()
799
+ width
800
+
801
+ ###*
802
+ Modifies the given function so it only runs once.
803
+ Subsequent calls will return the previous return value.
804
+
805
+ @function up.util.once
806
+ @param {Function} fun
807
+ @experimental
808
+ ###
809
+ once = (fun) ->
810
+ result = undefined
811
+ (args...) ->
812
+ result = fun(args...) if fun?
813
+ fun = undefined
814
+ result
815
+
816
+ ###*
817
+ Temporarily sets the CSS for the given element.
818
+
819
+ @function up.util.temporaryCss
820
+ @param {jQuery} $element
821
+ @param {Object} css
822
+ @param {Function} [block]
823
+ If given, the CSS is set, the block is called and
824
+ the old CSS is restored.
825
+ @return {Function}
826
+ A function that restores the original CSS when called.
827
+ @internal
828
+ ###
829
+ temporaryCss = ($element, css, block) ->
830
+ oldCss = $element.css(Object.keys(css))
831
+ $element.css(css)
832
+ memo = -> $element.css(oldCss)
833
+ if block
834
+ block()
835
+ memo()
836
+ else
837
+ once(memo)
838
+
839
+ ###*
840
+ Forces the given jQuery element into an accelerated compositing layer.
841
+
842
+ @function up.util.forceCompositing
843
+ @internal
844
+ ###
845
+ forceCompositing = ($element) ->
846
+ oldTransforms = $element.css(['transform', '-webkit-transform'])
847
+ if isBlank(oldTransforms) || oldTransforms['transform'] == 'none'
848
+ memo = -> $element.css(oldTransforms)
849
+ $element.css
850
+ 'transform': 'translateZ(0)'
851
+ '-webkit-transform': 'translateZ(0)' # Safari
852
+ else
853
+ # Since the element already has a transform, it is already
854
+ # drawn using compositing. Do nothing.
855
+ memo = ->
856
+ memo
857
+
858
+ ###*
859
+ Animates the given element's CSS properties using CSS transitions.
860
+
861
+ If the element is already being animated, the previous animation
862
+ will instantly jump to its last frame before the new animation begins.
863
+
864
+ To improve performance, the element will be forced into compositing for
865
+ the duration of the animation.
866
+
867
+ @function up.util.cssAnimate
868
+ @param {Element|jQuery|String} elementOrSelector
869
+ The element to animate.
870
+ @param {Object} lastFrame
871
+ The CSS properties that should be transitioned to.
872
+ @param {Number} [options.duration=300]
873
+ The duration of the animation, in milliseconds.
874
+ @param {Number} [options.delay=0]
875
+ The delay before the animation starts, in milliseconds.
876
+ @param {String} [options.easing='ease']
877
+ The timing function that controls the animation's acceleration.
878
+ See [W3C documentation](http://www.w3.org/TR/css3-transitions/#transition-timing-function)
879
+ for a list of pre-defined timing functions.
880
+ @return
881
+ A promise for the animation's end.
882
+ @internal
883
+ ###
884
+ cssAnimate = (elementOrSelector, lastFrame, opts) ->
885
+ $element = $(elementOrSelector)
886
+ opts = options(opts,
887
+ duration: 300,
888
+ delay: 0,
889
+ easing: 'ease'
890
+ )
891
+ # We don't finish an existing animation here, since
892
+ # the public API `up.motion.animate` already does this.
893
+ deferred = $.Deferred()
894
+ transition =
895
+ 'transition-property': Object.keys(lastFrame).join(', ')
896
+ 'transition-duration': "#{opts.duration}ms"
897
+ 'transition-delay': "#{opts.delay}ms"
898
+ 'transition-timing-function': opts.easing
899
+ withoutCompositing = forceCompositing($element)
900
+ withoutTransition = temporaryCss($element, transition)
901
+ $element.css(lastFrame)
902
+ deferred.then(withoutCompositing)
903
+ deferred.then(withoutTransition)
904
+ $element.data(ANIMATION_PROMISE_KEY, deferred)
905
+ deferred.then(-> $element.removeData(ANIMATION_PROMISE_KEY))
906
+ endTimeout = setTimeout((-> deferred.resolve()), opts.duration + opts.delay)
907
+ deferred.then(-> clearTimeout(endTimeout)) # clean up in case we're canceled
908
+ # Return the whole deferred and not just return a thenable.
909
+ # Other code will need the possibility to cancel the animation
910
+ # by resolving the deferred.
911
+ deferred
912
+
913
+ ANIMATION_PROMISE_KEY = 'up-animation-promise'
914
+
915
+ ###*
916
+ Completes the animation for the given element by jumping
917
+ to the last frame instantly. All callbacks chained to
918
+ the original animation's promise will be called.
919
+
920
+ Does nothing if the given element is not currently animating.
921
+
922
+ Also see [`up.motion.finish`](/up.motion.finish).
923
+
924
+ @function up.util.finishCssAnimate
925
+ @param {Element|jQuery|String} elementOrSelector
926
+ @internal
927
+ ###
928
+ finishCssAnimate = (elementOrSelector) ->
929
+ $(elementOrSelector).each ->
930
+ if existingAnimation = $(this).data(ANIMATION_PROMISE_KEY)
931
+ existingAnimation.resolve()
932
+
933
+ ###*
934
+ Measures the given element.
935
+
936
+ @function up.util.measure
937
+ @internal
938
+ ###
939
+ measure = ($element, opts) ->
940
+ opts = options(opts, relative: false, inner: false, full: false)
941
+
942
+ if opts.relative
943
+ if opts.relative == true
944
+ coordinates = $element.position()
945
+ else
946
+ $context = $(opts.relative)
947
+ elementCoords = $element.offset()
948
+ if $context.is(document)
949
+ # The document is always at the origin
950
+ coordinates = elementCoords
951
+ else
952
+ contextCoords = $context.offset()
953
+ coordinates =
954
+ left: elementCoords.left - contextCoords.left
955
+ top: elementCoords.top - contextCoords.top
956
+ else
957
+ coordinates = $element.offset()
958
+
959
+ box =
960
+ left: coordinates.left
961
+ top: coordinates.top
962
+
963
+ if opts.inner
964
+ box.width = $element.width()
965
+ box.height = $element.height()
966
+ else
967
+ box.width = $element.outerWidth()
968
+ box.height = $element.outerHeight()
969
+
970
+ if opts.full
971
+ viewport = clientSize()
972
+ box.right = viewport.width - (box.left + box.width)
973
+ box.bottom = viewport.height - (box.top + box.height)
974
+ box
975
+
976
+ ###*
977
+ Copies all attributes from the source element to the target element.
978
+
979
+ @function up.util.copyAttributes
980
+ @internal
981
+ ###
982
+ copyAttributes = ($source, $target) ->
983
+ for attr in $source.get(0).attributes
984
+ if attr.specified
985
+ $target.attr(attr.name, attr.value)
986
+
987
+ ###*
988
+ Looks for the given selector in the element and its descendants.
989
+
990
+ @function up.util.findWithSelf
991
+ @internal
992
+ ###
993
+ findWithSelf = ($element, selector) ->
994
+ $element.find(selector).addBack(selector)
995
+
996
+ ###*
997
+ Returns whether the given keyboard event involved the ESC key.
998
+
999
+ @function up.util.escapePressed
1000
+ @internal
1001
+ ###
1002
+ escapePressed = (event) ->
1003
+ event.keyCode == 27
1004
+
1005
+ ###*
1006
+ Returns whether the given array or string contains the given element or substring.
1007
+
1008
+ @function up.util.contains
1009
+ @param {Array|String} arrayOrString
1010
+ @param elementOrSubstring
1011
+ @stable
1012
+ ###
1013
+ contains = (arrayOrString, elementOrSubstring) ->
1014
+ arrayOrString.indexOf(elementOrSubstring) >= 0
1015
+
1016
+ ###*
1017
+ @function up.util.castedAttr
1018
+ @internal
1019
+ ###
1020
+ castedAttr = ($element, attrName) ->
1021
+ value = $element.attr(attrName)
1022
+ switch value
1023
+ when 'false' then false
1024
+ when 'true' then true
1025
+ when '' then true
1026
+ else value # other strings, undefined, null, ...
1027
+
1028
+ # castsToTrue = (object) ->
1029
+ # String(object) == "true"
1030
+ #
1031
+ # castsToFalse = (object) ->
1032
+ # String(object) == "false"
1033
+
1034
+ ###*
1035
+ @function up.util.locationFromXhr
1036
+ @internal
1037
+ ###
1038
+ locationFromXhr = (xhr) ->
1039
+ xhr.getResponseHeader('X-Up-Location')
1040
+
1041
+ ###*
1042
+ @function up.util.titleFromXhr
1043
+ @internal
1044
+ ###
1045
+ titleFromXhr = (xhr) ->
1046
+ xhr.getResponseHeader('X-Up-Title')
1047
+
1048
+ ###*
1049
+ @function up.util.methodFromXhr
1050
+ @internal
1051
+ ###
1052
+ methodFromXhr = (xhr) ->
1053
+ xhr.getResponseHeader('X-Up-Method')
1054
+
1055
+ ###*
1056
+ Returns a copy of the given object that only contains
1057
+ the given properties.
1058
+
1059
+ @function up.util.only
1060
+ @param {Object} object
1061
+ @param {Array} keys...
1062
+ @stable
1063
+ ###
1064
+ only = (object, properties...) ->
1065
+ filtered = {}
1066
+ for property in properties
1067
+ if object.hasOwnProperty(property)
1068
+ filtered[property] = object[property]
1069
+ filtered
1070
+
1071
+ ###*
1072
+ Returns a copy of the given object that contains all except
1073
+ the given properties.
1074
+
1075
+ @function up.util.except
1076
+ @param {Object} object
1077
+ @param {Array} keys...
1078
+ @stable
1079
+ ###
1080
+ except = (object, properties...) ->
1081
+ filtered = copy(object)
1082
+ for property in properties
1083
+ delete filtered[property]
1084
+ filtered
1085
+
1086
+ ###*
1087
+ @function up.util.isUnmodifiedKeyEvent
1088
+ @internal
1089
+ ###
1090
+ isUnmodifiedKeyEvent = (event) ->
1091
+ not (event.metaKey or event.shiftKey or event.ctrlKey)
1092
+
1093
+ ###*
1094
+ @function up.util.isUnmodifiedMouseEvent
1095
+ @internal
1096
+ ###
1097
+ isUnmodifiedMouseEvent = (event) ->
1098
+ isLeftButton = isUndefined(event.button) || event.button == 0
1099
+ isLeftButton && isUnmodifiedKeyEvent(event)
1100
+
1101
+ ###*
1102
+ Returns a [Deferred object](https://api.jquery.com/category/deferred-object/) that is
1103
+ already resolved.
1104
+
1105
+ @function up.util.resolvedDeferred
1106
+ @return {Deferred}
1107
+ @stable
1108
+ ###
1109
+ resolvedDeferred = ->
1110
+ deferred = $.Deferred()
1111
+ deferred.resolve()
1112
+ deferred
1113
+
1114
+ ###*
1115
+ Returns a promise that is already resolved.
1116
+
1117
+ @function up.util.resolvedPromise
1118
+ @return {Promise}
1119
+ @stable
1120
+ ###
1121
+ resolvedPromise = ->
1122
+ resolvedDeferred().promise()
1123
+
1124
+ ###*
1125
+ Returns a [Deferred object](https://api.jquery.com/category/deferred-object/) that will never be resolved.
1126
+
1127
+ @function up.util.unresolvableDeferred
1128
+ @return {Deferred}
1129
+ @experimental
1130
+ ###
1131
+ unresolvableDeferred = ->
1132
+ $.Deferred()
1133
+
1134
+ ###*
1135
+ Returns a promise that will never be resolved.
1136
+
1137
+ @function up.util.unresolvablePromise
1138
+ @experimental
1139
+ ###
1140
+ unresolvablePromise = ->
1141
+ unresolvableDeferred().promise()
1142
+
1143
+ ###*
1144
+ Returns an empty jQuery collection.
1145
+
1146
+ @function up.util.nullJQuery
1147
+ @internal
1148
+ ###
1149
+ nullJQuery = ->
1150
+ $()
1151
+
1152
+ ###*
1153
+ Returns a new promise that resolves once all promises in arguments resolve.
1154
+
1155
+ Other then [`$.when` from jQuery](https://api.jquery.com/jquery.when/),
1156
+ the combined promise will have a `resolve` method. This `resolve` method
1157
+ will resolve all the wrapped promises.
1158
+
1159
+ @function up.util.resolvableWhen
1160
+ @internal
1161
+ ###
1162
+ resolvableWhen = (deferreds...) ->
1163
+ joined = $.when(deferreds...)
1164
+ joined.resolve = ->
1165
+ each deferreds, (deferred) -> deferred.resolve?()
1166
+ joined
1167
+
1168
+ # resolvableSequence = (first, callbacks...) ->
1169
+ # sequence = $.Deferred().promise()
1170
+ # values = [first]
1171
+ # current = first
1172
+ # for callback in callbacks
1173
+ # current = current.then ->
1174
+ # value = callback()
1175
+ # values.push(value) if u.isPromise(value)
1176
+ # value
1177
+ # sequence.resolve = ->
1178
+ # each values, (deferred) -> deferred.resolve?()
1179
+ # sequence
1180
+
1181
+ ###*
1182
+ On the given element, set attributes that are still missing.
1183
+
1184
+ @function up.util.setMissingAttrs
1185
+ @internal
1186
+ ###
1187
+ setMissingAttrs = ($element, attrs) ->
1188
+ for key, value of attrs
1189
+ if isMissing($element.attr(key))
1190
+ $element.attr(key, value)
1191
+
1192
+ ###*
1193
+ Removes the given element from the given array.
1194
+
1195
+ This changes the given array.
1196
+
1197
+ @function up.util.remove
1198
+ @param {Array<T>} array
1199
+ @param {T} element
1200
+ @stable
1201
+ ###
1202
+ remove = (array, element) ->
1203
+ index = array.indexOf(element)
1204
+ if index >= 0
1205
+ array.splice(index, 1)
1206
+ element
1207
+
1208
+ ###*
1209
+ @function up.util.multiSelector
1210
+ @internal
1211
+ ###
1212
+ multiSelector = (parts) ->
1213
+
1214
+ obj = {}
1215
+ selectors = []
1216
+ elements = []
1217
+
1218
+ for part in parts
1219
+ if isString(part)
1220
+ selectors.push(part)
1221
+ else
1222
+ elements.push(part)
1223
+
1224
+ obj.parsed = elements
1225
+
1226
+ if selectors.length
1227
+ # Although other methods would work with an array of
1228
+ # selectors, we combine them to a single separator for
1229
+ # performance reasons.
1230
+ combinedSelector = selectors.join(', ')
1231
+ obj.parsed.push(combinedSelector)
1232
+
1233
+ obj.select = ->
1234
+ obj.find(undefined)
1235
+
1236
+ obj.find = ($root) ->
1237
+ $result = nullJQuery()
1238
+ for selector in obj.parsed
1239
+ $matches = if $root then $root.find(selector) else $(selector)
1240
+ $result = $result.add($matches)
1241
+ $result
1242
+
1243
+ obj.findWithSelf = ($start) ->
1244
+ $matches = obj.find($start)
1245
+ $matches = $matches.add($start) if obj.doesMatch($start)
1246
+ $matches
1247
+
1248
+ obj.doesMatch = (element) ->
1249
+ $element = $(element)
1250
+ any obj.parsed, (selector) -> $element.is(selector)
1251
+
1252
+ obj.seekUp = (start) ->
1253
+ $start = $(start)
1254
+ $element = $start
1255
+ $result = undefined
1256
+ while $element.length
1257
+ if obj.doesMatch($element)
1258
+ $result = $element
1259
+ break
1260
+ $element = $element.parent()
1261
+ $result || nullJQuery()
1262
+
1263
+ obj
1264
+
1265
+ ###*
1266
+ @function up.util.cache
1267
+ @param {Number|Function} [config.size]
1268
+ Maximum number of cache entries.
1269
+ Set to `undefined` to not limit the cache size.
1270
+ @param {Number|Function} [config.expiry]
1271
+ The number of milliseconds after which a cache entry
1272
+ will be discarded.
1273
+ @param {String} [config.log]
1274
+ A prefix for log entries printed by this cache object.
1275
+ @param {Function<Object>} [config.key]
1276
+ A function that takes an argument and returns a `String` key
1277
+ for storage. If omitted, `toString()` is called on the argument.
1278
+ @internal
1279
+ ###
1280
+ cache = (config = {}) ->
1281
+
1282
+ store = undefined
1283
+
1284
+ clear = ->
1285
+ store = {}
1286
+
1287
+ clear()
1288
+
1289
+ log = (args...) ->
1290
+ if config.log
1291
+ args[0] = "[#{config.log}] #{args[0]}"
1292
+ up.puts(args...)
1293
+
1294
+ keys = ->
1295
+ Object.keys(store)
1296
+
1297
+ maxSize = ->
1298
+ if isMissing(config.size)
1299
+ undefined
1300
+ else if isFunction(config.size)
1301
+ config.size()
1302
+ else if isNumber(config.size)
1303
+ config.size
1304
+ else
1305
+ error("Invalid size config: %o", config.size)
1306
+
1307
+ expiryMilis = ->
1308
+ if isMissing(config.expiry)
1309
+ undefined
1310
+ else if isFunction(config.expiry)
1311
+ config.expiry()
1312
+ else if isNumber(config.expiry)
1313
+ config.expiry
1314
+ else
1315
+ error("Invalid expiry config: %o", config.expiry)
1316
+
1317
+ normalizeStoreKey = (key) ->
1318
+ if config.key
1319
+ config.key(key)
1320
+ else
1321
+ key.toString()
1322
+
1323
+ trim = ->
1324
+ storeKeys = copy(keys())
1325
+ size = maxSize()
1326
+ if size && storeKeys.length > size
1327
+ oldestKey = null
1328
+ oldestTimestamp = null
1329
+ each storeKeys, (key) ->
1330
+ promise = store[key] # we don't need to call cacheKey here
1331
+ timestamp = promise.timestamp
1332
+ if !oldestTimestamp || oldestTimestamp > timestamp
1333
+ oldestKey = key
1334
+ oldestTimestamp = timestamp
1335
+ delete store[oldestKey] if oldestKey
1336
+
1337
+ alias = (oldKey, newKey) ->
1338
+ value = get(oldKey, silent: true)
1339
+ if isDefined(value)
1340
+ set(newKey, value)
1341
+
1342
+ timestamp = ->
1343
+ (new Date()).valueOf()
1344
+
1345
+ set = (key, value) ->
1346
+ storeKey = normalizeStoreKey(key)
1347
+ store[storeKey] =
1348
+ timestamp: timestamp()
1349
+ value: value
1350
+
1351
+ remove = (key) ->
1352
+ storeKey = normalizeStoreKey(key)
1353
+ delete store[storeKey]
1354
+
1355
+ isFresh = (entry) ->
1356
+ expiry = expiryMilis()
1357
+ if expiry
1358
+ timeSinceTouch = timestamp() - entry.timestamp
1359
+ timeSinceTouch < expiryMilis()
1360
+ else
1361
+ true
1362
+
1363
+ get = (key, options = {}) ->
1364
+ storeKey = normalizeStoreKey(key)
1365
+ if entry = store[storeKey]
1366
+ if isFresh(entry)
1367
+ log("Cache hit for '%s'", key) unless options.silent
1368
+ entry.value
1369
+ else
1370
+ log("Discarding stale cache entry for '%s'", key) unless options.silent
1371
+ remove(key)
1372
+ undefined
1373
+ else
1374
+ log("Cache miss for '%s'", key) unless options.silent
1375
+ undefined
1376
+
1377
+ alias: alias
1378
+ get: get
1379
+ set: set
1380
+ remove: remove
1381
+ clear: clear
1382
+ keys: keys
1383
+
1384
+ ###*
1385
+ @function up.util.config
1386
+ @internal
1387
+ ###
1388
+ config = (factoryOptions = {}) ->
1389
+ hash = {}
1390
+ hash.reset = -> extend(hash, factoryOptions)
1391
+ hash.reset()
1392
+ Object.preventExtensions(hash)
1393
+ hash
1394
+
1395
+ ###*
1396
+ @function up.util.unwrapElement
1397
+ @internal
1398
+ ###
1399
+ unwrapElement = (wrapper) ->
1400
+ wrapper = unJQuery(wrapper)
1401
+ parent = wrapper.parentNode;
1402
+ wrappedNodes = toArray(wrapper.childNodes)
1403
+ each wrappedNodes, (wrappedNode) ->
1404
+ parent.insertBefore(wrappedNode, wrapper)
1405
+ parent.removeChild(wrapper)
1406
+
1407
+ ###*
1408
+ @function up.util.offsetParent
1409
+ @internal
1410
+ ###
1411
+ offsetParent = ($element) ->
1412
+ $match = undefined
1413
+ while ($element = $element.parent()) && $element.length
1414
+ position = $element.css('position')
1415
+ if position == 'absolute' || position == 'relative' || $element.is('body')
1416
+ $match = $element
1417
+ break
1418
+ $match
1419
+
1420
+ ###*
1421
+ @function up.util.fixedToAbsolute
1422
+ @internal
1423
+ ###
1424
+ fixedToAbsolute = (element, $viewport) ->
1425
+ $element = $(element)
1426
+ $futureOffsetParent = offsetParent($element)
1427
+ # To get a fixed elements distance from the edge of the screen,
1428
+ # use position(), not offset(). offset() would include the current
1429
+ # scrollTop of the viewport.
1430
+ elementCoords = $element.position()
1431
+ futureParentCoords = $futureOffsetParent.offset()
1432
+ $element.css
1433
+ position: 'absolute'
1434
+ left: elementCoords.left - futureParentCoords.left
1435
+ top: elementCoords.top - futureParentCoords.top + $viewport.scrollTop()
1436
+ right: ''
1437
+ bottom: ''
1438
+
1439
+ # argNames = (fun) ->
1440
+ # code = fun.toString()
1441
+ # pattern = new RegExp('\\(([^\\)]*)\\)')
1442
+ # if match = code.match(pattern)
1443
+ # match[1].split(/\s*,\s*/)
1444
+ # else
1445
+ # error('Could not parse argument names of %o', fun)
1446
+
1447
+ ###*
1448
+ Normalizes the given params object to the form returned by
1449
+ [`jQuery.serializeArray`](https://api.jquery.com/serializeArray/).
1450
+
1451
+ @function up.util.requestDataAsArray
1452
+ @param {Object|Array|Undefined|Null} data
1453
+ @internal
1454
+ ###
1455
+ requestDataAsArray = (data) ->
1456
+ query = requestDataAsQuery(data)
1457
+ array = []
1458
+ for part in query.split('&')
1459
+ if isPresent(part)
1460
+ pair = part.split('=')
1461
+ array.push
1462
+ name: decodeURIComponent(pair[0])
1463
+ value: decodeURIComponent(pair[1])
1464
+ array
1465
+
1466
+ ###*
1467
+ Returns an URL-encoded query string for the given params object.
1468
+
1469
+ @function up.util.requestDataAsQuery
1470
+ @param {Object|Array|Undefined|Null} data
1471
+ @internal
1472
+ ###
1473
+ requestDataAsQuery = (data) ->
1474
+ if data
1475
+ query = $.param(data)
1476
+ query = query.replace(/\+/g, '%20')
1477
+ query
1478
+ else
1479
+ ""
1480
+
1481
+ ###*
1482
+ Throws a fatal error with the given message.
1483
+
1484
+ - The error will be printed to the [error console](https://developer.mozilla.org/en-US/docs/Web/API/Console/error)
1485
+ - An [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) (exception) will be thrown, unwinding the current call stack
1486
+ - The error message will be printed in a corner of the screen
1487
+
1488
+ \#\#\#\# Examples
1489
+
1490
+ up.error('Division by zero')
1491
+ up.error('Unexpected result %o', result)
1492
+
1493
+ @experimental
1494
+ ###
1495
+ error = (args...) ->
1496
+ up.log.error(args...)
1497
+ asString = up.browser.sprintf(args...)
1498
+ $error = presence($('.up-error')) || $('<div class="up-error"></div>').prependTo('body')
1499
+ $error.addClass('up-error')
1500
+ $error.text(asString)
1501
+ throw new Error(asString)
1502
+
1503
+ requestDataAsArray: requestDataAsArray
1504
+ requestDataAsQuery: requestDataAsQuery
1505
+ offsetParent: offsetParent
1506
+ fixedToAbsolute: fixedToAbsolute
1507
+ presentAttr: presentAttr
1508
+ createElement: createElement
1509
+ parseUrl: parseUrl
1510
+ normalizeUrl: normalizeUrl
1511
+ normalizeMethod: normalizeMethod
1512
+ createElementFromHtml: createElementFromHtml
1513
+ $createElementFromSelector: $createElementFromSelector
1514
+ $createPlaceholder: $createPlaceholder
1515
+ selectorForElement: selectorForElement
1516
+ extend: extend
1517
+ copy: copy
1518
+ merge: merge
1519
+ options: options
1520
+ option: option
1521
+ error: error
1522
+ each: each
1523
+ map: map
1524
+ times: times
1525
+ any: any
1526
+ all: all
1527
+ detect: detect
1528
+ select: select
1529
+ reject: reject
1530
+ intersect: intersect
1531
+ compact: compact
1532
+ uniq: uniq
1533
+ last: last
1534
+ isNull: isNull
1535
+ isDefined: isDefined
1536
+ isUndefined: isUndefined
1537
+ isGiven: isGiven
1538
+ isMissing: isMissing
1539
+ isPresent: isPresent
1540
+ isBlank: isBlank
1541
+ presence: presence
1542
+ isObject: isObject
1543
+ isFunction: isFunction
1544
+ isString: isString
1545
+ isElement: isElement
1546
+ isJQuery: isJQuery
1547
+ isPromise: isPromise
1548
+ isDeferred: isDeferred
1549
+ isHash: isHash
1550
+ isUnmodifiedKeyEvent: isUnmodifiedKeyEvent
1551
+ isUnmodifiedMouseEvent: isUnmodifiedMouseEvent
1552
+ nullJQuery: nullJQuery
1553
+ unJQuery: unJQuery
1554
+ nextFrame: nextFrame
1555
+ measure: measure
1556
+ temporaryCss: temporaryCss
1557
+ cssAnimate: cssAnimate
1558
+ finishCssAnimate: finishCssAnimate
1559
+ forceCompositing: forceCompositing
1560
+ escapePressed: escapePressed
1561
+ copyAttributes: copyAttributes
1562
+ findWithSelf: findWithSelf
1563
+ contains: contains
1564
+ isArray: isArray
1565
+ toArray: toArray
1566
+ # castsToTrue: castsToTrue
1567
+ # castsToFalse: castsToFalse
1568
+ castedAttr: castedAttr
1569
+ locationFromXhr: locationFromXhr
1570
+ titleFromXhr: titleFromXhr
1571
+ methodFromXhr: methodFromXhr
1572
+ clientSize: clientSize
1573
+ only: only
1574
+ except: except
1575
+ trim: trim
1576
+ unresolvableDeferred: unresolvableDeferred
1577
+ unresolvablePromise: unresolvablePromise
1578
+ resolvedPromise: resolvedPromise
1579
+ resolvedDeferred: resolvedDeferred
1580
+ resolvableWhen: resolvableWhen
1581
+ setMissingAttrs: setMissingAttrs
1582
+ remove: remove
1583
+ memoize: memoize
1584
+ scrollbarWidth: scrollbarWidth
1585
+ config: config
1586
+ cache: cache
1587
+ unwrapElement: unwrapElement
1588
+ multiSelector: multiSelector
1589
+ error: error
1590
+
1591
+ )($)
1592
+
1593
+ up.error = up.util.error