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.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.ruby-version +2 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +577 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +42 -0
- data/LICENSE +22 -0
- data/README.md +75 -0
- data/README_RAILS.md +116 -0
- data/Rakefile +45 -0
- data/bower.json +26 -0
- data/design/animation-ghosting.txt +72 -0
- data/design/design.txt +34 -0
- data/design/draft.html.erb +48 -0
- data/design/draft.rb +9 -0
- data/design/ghost-debugging.txt +118 -0
- data/design/homepage.txt +236 -0
- data/design/rename.txt +0 -0
- data/dist/unpoly-bootstrap3.css +5 -0
- data/dist/unpoly-bootstrap3.js +28 -0
- data/dist/unpoly-bootstrap3.min.css +1 -0
- data/dist/unpoly-bootstrap3.min.js +1 -0
- data/dist/unpoly.css +98 -0
- data/dist/unpoly.js +9041 -0
- data/dist/unpoly.min.css +1 -0
- data/dist/unpoly.min.js +3 -0
- data/lib/assets/javascripts/unpoly-bootstrap3.js.coffee +2 -0
- data/lib/assets/javascripts/unpoly-bootstrap3/form-ext.js.coffee +1 -0
- data/lib/assets/javascripts/unpoly-bootstrap3/layout-ext.js.coffee +5 -0
- data/lib/assets/javascripts/unpoly-bootstrap3/modal-ext.js.coffee +11 -0
- data/lib/assets/javascripts/unpoly-bootstrap3/navigation-ext.js.coffee +3 -0
- data/lib/assets/javascripts/unpoly.js.coffee +20 -0
- data/lib/assets/javascripts/unpoly/browser.js.coffee +252 -0
- data/lib/assets/javascripts/unpoly/bus.js.coffee +393 -0
- data/lib/assets/javascripts/unpoly/flow.js.coffee +809 -0
- data/lib/assets/javascripts/unpoly/form.js.coffee +864 -0
- data/lib/assets/javascripts/unpoly/history.js.coffee +204 -0
- data/lib/assets/javascripts/unpoly/layout.js.coffee +529 -0
- data/lib/assets/javascripts/unpoly/link.js.coffee +496 -0
- data/lib/assets/javascripts/unpoly/log.js.coffee +73 -0
- data/lib/assets/javascripts/unpoly/modal.js.coffee +509 -0
- data/lib/assets/javascripts/unpoly/module.js.coffee +4 -0
- data/lib/assets/javascripts/unpoly/motion.js.coffee +690 -0
- data/lib/assets/javascripts/unpoly/navigation.js.coffee +219 -0
- data/lib/assets/javascripts/unpoly/popup.js.coffee +409 -0
- data/lib/assets/javascripts/unpoly/proxy.js.coffee +521 -0
- data/lib/assets/javascripts/unpoly/rails.js.coffee +36 -0
- data/lib/assets/javascripts/unpoly/syntax.js.coffee +337 -0
- data/lib/assets/javascripts/unpoly/tooltip.js.coffee +183 -0
- data/lib/assets/javascripts/unpoly/util.js.coffee +1593 -0
- data/lib/assets/stylesheets/unpoly-bootstrap3.css.sass +1 -0
- data/lib/assets/stylesheets/unpoly-bootstrap3/modal-ext.css.sass +9 -0
- data/lib/assets/stylesheets/unpoly.css.sass +1 -0
- data/lib/assets/stylesheets/unpoly/close.css.sass +2 -0
- data/lib/assets/stylesheets/unpoly/error.css.sass +15 -0
- data/lib/assets/stylesheets/unpoly/link.css.sass +2 -0
- data/lib/assets/stylesheets/unpoly/modal.css.sass +69 -0
- data/lib/assets/stylesheets/unpoly/popup.css.sass +8 -0
- data/lib/assets/stylesheets/unpoly/tooltip.css.sass +42 -0
- data/lib/unpoly-rails.rb +7 -0
- data/lib/unpoly/rails/engine.rb +6 -0
- data/lib/unpoly/rails/inspector.rb +78 -0
- data/lib/unpoly/rails/inspector_accessor.rb +30 -0
- data/lib/unpoly/rails/request_echo_headers.rb +27 -0
- data/lib/unpoly/rails/request_method_cookie.rb +36 -0
- data/lib/unpoly/rails/version.rb +9 -0
- data/spec_app/.firefox-version +1 -0
- data/spec_app/.gitignore +17 -0
- data/spec_app/.rspec +2 -0
- data/spec_app/Bowerfile +3 -0
- data/spec_app/Gemfile +29 -0
- data/spec_app/Gemfile.lock +212 -0
- data/spec_app/README.rdoc +28 -0
- data/spec_app/Rakefile +6 -0
- data/spec_app/app/assets/images/.keep +0 -0
- data/spec_app/app/assets/javascripts/application.js +20 -0
- data/spec_app/app/assets/stylesheets/application.css +17 -0
- data/spec_app/app/assets/stylesheets/blocks/card.css.sass +11 -0
- data/spec_app/app/assets/stylesheets/blocks/controls.css.sass +7 -0
- data/spec_app/app/assets/stylesheets/blocks/menu.css.sass +13 -0
- data/spec_app/app/assets/stylesheets/blocks/panel.css.sass +8 -0
- data/spec_app/app/assets/stylesheets/jasmine_specs.css +5 -0
- data/spec_app/app/controllers/application_controller.rb +6 -0
- data/spec_app/app/controllers/concerns/.keep +0 -0
- data/spec_app/app/controllers/test_controller.rb +28 -0
- data/spec_app/app/helpers/application_helper.rb +2 -0
- data/spec_app/app/mailers/.keep +0 -0
- data/spec_app/app/models/concerns/.keep +0 -0
- data/spec_app/app/views/layouts/application.html.erb +12 -0
- data/spec_app/bin/bundle +3 -0
- data/spec_app/bin/rails +8 -0
- data/spec_app/bin/rake +8 -0
- data/spec_app/bin/setup +29 -0
- data/spec_app/bin/spring +18 -0
- data/spec_app/config.ru +4 -0
- data/spec_app/config/application.rb +26 -0
- data/spec_app/config/boot.rb +3 -0
- data/spec_app/config/database.yml +25 -0
- data/spec_app/config/environment.rb +5 -0
- data/spec_app/config/environments/development.rb +41 -0
- data/spec_app/config/environments/production.rb +79 -0
- data/spec_app/config/environments/test.rb +42 -0
- data/spec_app/config/initializers/assets.rb +11 -0
- data/spec_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec_app/config/initializers/bower_rails.rb +16 -0
- data/spec_app/config/initializers/cookies_serializer.rb +3 -0
- data/spec_app/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec_app/config/initializers/inflections.rb +16 -0
- data/spec_app/config/initializers/mime_types.rb +4 -0
- data/spec_app/config/initializers/session_store.rb +3 -0
- data/spec_app/config/initializers/wrap_parameters.rb +14 -0
- data/spec_app/config/locales/en.yml +23 -0
- data/spec_app/config/routes.rb +8 -0
- data/spec_app/config/secrets.yml +22 -0
- data/spec_app/db/schema.rb +23 -0
- data/spec_app/db/seeds.rb +7 -0
- data/spec_app/lib/assets/.keep +0 -0
- data/spec_app/lib/tasks/.keep +0 -0
- data/spec_app/lib/tasks/cucumber.rake +65 -0
- data/spec_app/log/.keep +0 -0
- data/spec_app/public/404.html +67 -0
- data/spec_app/public/422.html +67 -0
- data/spec_app/public/500.html +66 -0
- data/spec_app/public/favicon.ico +0 -0
- data/spec_app/public/robots.txt +5 -0
- data/spec_app/script/cucumber +10 -0
- data/spec_app/spec/controllers/test_controller_spec.rb +76 -0
- data/spec_app/spec/javascripts/helpers/append_fixture.js.coffee +8 -0
- data/spec_app/spec/javascripts/helpers/browser_switches.js.coffee +9 -0
- data/spec_app/spec/javascripts/helpers/index.js.coffee +1 -0
- data/spec_app/spec/javascripts/helpers/knife.js.coffee +69 -0
- data/spec_app/spec/javascripts/helpers/last_request.js.coffee +22 -0
- data/spec_app/spec/javascripts/helpers/mock_ajax.js.coffee +5 -0
- data/spec_app/spec/javascripts/helpers/mock_clock.js.coffee +2 -0
- data/spec_app/spec/javascripts/helpers/remove_body_margin.js.coffee +5 -0
- data/spec_app/spec/javascripts/helpers/reset_knife.js.coffee +2 -0
- data/spec_app/spec/javascripts/helpers/reset_path.js.coffee +8 -0
- data/spec_app/spec/javascripts/helpers/reset_up.js.coffee +4 -0
- data/spec_app/spec/javascripts/helpers/restore_body_scroll.js.coffee +2 -0
- data/spec_app/spec/javascripts/helpers/set_timer.js.coffee +3 -0
- data/spec_app/spec/javascripts/helpers/to_be_around.js.coffee +5 -0
- data/spec_app/spec/javascripts/helpers/to_be_blank.js.coffee +5 -0
- data/spec_app/spec/javascripts/helpers/to_be_given.js.coffee +5 -0
- data/spec_app/spec/javascripts/helpers/to_be_missing.js.coffee +5 -0
- data/spec_app/spec/javascripts/helpers/to_be_present.js.coffee +5 -0
- data/spec_app/spec/javascripts/helpers/to_end_with.js.coffee +8 -0
- data/spec_app/spec/javascripts/helpers/to_equal_jquery.js.coffee +9 -0
- data/spec_app/spec/javascripts/helpers/to_have_request_method.js.coffee +8 -0
- data/spec_app/spec/javascripts/helpers/trigger.js.coffee +68 -0
- data/spec_app/spec/javascripts/support/jasmine.yml +51 -0
- data/spec_app/spec/javascripts/up/bus_spec.js.coffee +122 -0
- data/spec_app/spec/javascripts/up/flow_spec.js.coffee +755 -0
- data/spec_app/spec/javascripts/up/form_spec.js.coffee +471 -0
- data/spec_app/spec/javascripts/up/history_spec.js.coffee +96 -0
- data/spec_app/spec/javascripts/up/layout_spec.js.coffee +318 -0
- data/spec_app/spec/javascripts/up/link_spec.js.coffee +340 -0
- data/spec_app/spec/javascripts/up/modal_spec.js.coffee +265 -0
- data/spec_app/spec/javascripts/up/motion_spec.js.coffee +306 -0
- data/spec_app/spec/javascripts/up/navigation_spec.js.coffee +132 -0
- data/spec_app/spec/javascripts/up/popup_spec.js.coffee +220 -0
- data/spec_app/spec/javascripts/up/proxy_spec.js.coffee +371 -0
- data/spec_app/spec/javascripts/up/rails_spec.js.coffee +101 -0
- data/spec_app/spec/javascripts/up/syntax_spec.js.coffee +99 -0
- data/spec_app/spec/javascripts/up/tooltip_spec.js.coffee +60 -0
- data/spec_app/spec/javascripts/up/util_spec.js.coffee +325 -0
- data/spec_app/spec/spec_helper.rb +62 -0
- data/spec_app/test/controllers/.keep +0 -0
- data/spec_app/test/fixtures/.keep +0 -0
- data/spec_app/test/helpers/.keep +0 -0
- data/spec_app/test/integration/.keep +0 -0
- data/spec_app/test/mailers/.keep +0 -0
- data/spec_app/test/models/.keep +0 -0
- data/spec_app/test/test_helper.rb +10 -0
- data/spec_app/vendor/assets/.bowerrc +3 -0
- data/spec_app/vendor/assets/bower.json +8 -0
- data/spec_app/vendor/assets/bower_components/jasmine-ajax/.bower.json +43 -0
- data/spec_app/vendor/assets/bower_components/jasmine-ajax/MIT.LICENSE +20 -0
- data/spec_app/vendor/assets/bower_components/jasmine-ajax/README.markdown +289 -0
- data/spec_app/vendor/assets/bower_components/jasmine-ajax/bower.json +35 -0
- data/spec_app/vendor/assets/bower_components/jasmine-ajax/lib/mock-ajax.js +733 -0
- data/spec_app/vendor/assets/bower_components/jasmine-ajax/package.json +26 -0
- data/spec_app/vendor/assets/bower_components/jasmine-ajax/release_notes/2.0.2.md +50 -0
- data/spec_app/vendor/assets/bower_components/jasmine-ajax/release_notes/2.99.md +14 -0
- data/spec_app/vendor/assets/bower_components/jasmine-ajax/release_notes/3.0.md +28 -0
- data/spec_app/vendor/assets/bower_components/jasmine-ajax/release_notes/3.1.0.md +24 -0
- data/spec_app/vendor/assets/bower_components/jasmine-ajax/release_notes/3.1.1.md +23 -0
- data/spec_app/vendor/assets/bower_components/jasmine-ajax/release_notes/3.2.0.md +20 -0
- data/spec_app/vendor/assets/bower_components/jasmine-fixture/.bower.json +27 -0
- data/spec_app/vendor/assets/bower_components/jasmine-fixture/.gitignore +8 -0
- data/spec_app/vendor/assets/bower_components/jasmine-fixture/.npmignore +8 -0
- data/spec_app/vendor/assets/bower_components/jasmine-fixture/LICENSE.txt +24 -0
- data/spec_app/vendor/assets/bower_components/jasmine-fixture/README.md +118 -0
- data/spec_app/vendor/assets/bower_components/jasmine-fixture/bower.json +17 -0
- data/spec_app/vendor/assets/bower_components/jasmine-fixture/dist/jasmine-fixture.js +433 -0
- data/spec_app/vendor/assets/bower_components/jasmine-fixture/dist/jasmine-fixture.min.js +5 -0
- data/spec_app/vendor/assets/bower_components/jasmine-fixture/spec-e2e/basic-usage-spec.coffee +14 -0
- data/spec_app/vendor/assets/bower_components/jasmine-fixture/spec-e2e/helpers/invariants.coffee +17 -0
- data/spec_app/vendor/assets/bower_components/jasmine-fixture/spec-e2e/helpers/spec-within-a-spec.coffee +24 -0
- data/spec_app/vendor/assets/bower_components/jasmine-fixture/spec-e2e/helpers/tmp-files.coffee +8 -0
- data/spec_app/vendor/assets/bower_components/jasmine-fixture/spec-e2e/support/jasmine1-testem-config.json +11 -0
- data/spec_app/vendor/assets/bower_components/jasmine-fixture/spec-e2e/support/jasmine2-testem-config.json +11 -0
- data/spec_app/vendor/assets/bower_components/jasmine-fixture/vendor/js/jquery-1.11.0.js +10337 -0
- data/spec_app/vendor/assets/bower_components/jasmine-fixture/vendor/js/jquery-1.8.3.js +9472 -0
- data/spec_app/vendor/assets/bower_components/jasmine-fixture/vendor/js/jquery-2.1.0.js +9111 -0
- data/spec_app/vendor/assets/bower_components/jasmine-jquery/.bower.json +26 -0
- data/spec_app/vendor/assets/bower_components/jasmine-jquery/CONTRIBUTING.md +28 -0
- data/spec_app/vendor/assets/bower_components/jasmine-jquery/Gruntfile.js +49 -0
- data/spec_app/vendor/assets/bower_components/jasmine-jquery/LICENSE +20 -0
- data/spec_app/vendor/assets/bower_components/jasmine-jquery/README.md +367 -0
- data/spec_app/vendor/assets/bower_components/jasmine-jquery/bower.json +15 -0
- data/spec_app/vendor/assets/bower_components/jasmine-jquery/lib/jasmine-jquery.js +838 -0
- data/spec_app/vendor/assets/bower_components/jasmine-jquery/package.json +35 -0
- data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/fixture_with_checkbox_with_checked.html +6 -0
- data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/fixture_with_javascript.html +1 -0
- data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/fixture_with_javascript_block.html +1 -0
- data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/javascripts/jasmine_javascript_click.js +1 -0
- data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/javascripts/jasmine_javascript_hover.js +1 -0
- data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/json/jasmine_json_test.json +1 -0
- data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/real_non_mocked_fixture.html +1 -0
- data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/fixtures/real_non_mocked_fixture_style.css +1 -0
- data/spec_app/vendor/assets/bower_components/jasmine-jquery/spec/suites/jasmine-jquery-spec.js +1842 -0
- data/spec_app/vendor/assets/bower_components/jasmine/.bower.json +50 -0
- data/spec_app/vendor/assets/bower_components/jasmine/CONTRIBUTING.md +130 -0
- data/spec_app/vendor/assets/bower_components/jasmine/GOALS_2.0.md +64 -0
- data/spec_app/vendor/assets/bower_components/jasmine/MANIFEST.in +5 -0
- data/spec_app/vendor/assets/bower_components/jasmine/MIT.LICENSE +20 -0
- data/spec_app/vendor/assets/bower_components/jasmine/README.md +73 -0
- data/spec_app/vendor/assets/bower_components/jasmine/RELEASE.md +73 -0
- data/spec_app/vendor/assets/bower_components/jasmine/bower.json +41 -0
- data/spec_app/vendor/assets/bower_components/jasmine/images/jasmine-horizontal.png +0 -0
- data/spec_app/vendor/assets/bower_components/jasmine/images/jasmine-horizontal.svg +102 -0
- data/spec_app/vendor/assets/bower_components/jasmine/images/jasmine_favicon.png +0 -0
- data/spec_app/vendor/assets/bower_components/jasmine/lib/console/console.js +190 -0
- data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core.js +37 -0
- data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/boot.js +143 -0
- data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/example/node_example/lib/jasmine_examples/Player.js +24 -0
- data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/example/node_example/lib/jasmine_examples/Song.js +9 -0
- data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/jasmine-html.js +446 -0
- data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/jasmine.css +58 -0
- data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/jasmine.js +3298 -0
- data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/json2.js +489 -0
- data/spec_app/vendor/assets/bower_components/jasmine/lib/jasmine-core/node_boot.js +41 -0
- data/spec_app/vendor/assets/bower_components/jasmine/package.json +34 -0
- data/spec_app/vendor/assets/bower_components/jasmine/requirements.txt +1 -0
- data/spec_app/vendor/assets/bower_components/jquery/.bower.json +38 -0
- data/spec_app/vendor/assets/bower_components/jquery/MIT-LICENSE.txt +21 -0
- data/spec_app/vendor/assets/bower_components/jquery/bower.json +28 -0
- data/spec_app/vendor/assets/bower_components/jquery/dist/jquery.js +9210 -0
- data/spec_app/vendor/assets/bower_components/jquery/dist/jquery.min.js +5 -0
- data/spec_app/vendor/assets/bower_components/jquery/dist/jquery.min.map +1 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/ajax.js +786 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/ajax/jsonp.js +89 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/ajax/load.js +75 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/ajax/parseJSON.js +13 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/ajax/parseXML.js +28 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/ajax/script.js +64 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/ajax/var/nonce.js +5 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/ajax/var/rquery.js +3 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/ajax/xhr.js +136 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/attributes.js +11 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/attributes/attr.js +141 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/attributes/classes.js +158 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/attributes/prop.js +94 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/attributes/support.js +35 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/attributes/val.js +161 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/callbacks.js +205 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/core.js +502 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/core/access.js +60 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/core/init.js +123 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/core/parseHTML.js +39 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/core/ready.js +97 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/core/var/rsingleTag.js +4 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/css.js +450 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/css/addGetHookIf.js +22 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/css/curCSS.js +57 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/css/defaultDisplay.js +70 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/css/hiddenVisibleSelectors.js +15 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/css/support.js +96 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/css/swap.js +28 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/css/var/cssExpand.js +3 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/css/var/getStyles.js +12 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/css/var/isHidden.js +13 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/css/var/rmargin.js +3 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/css/var/rnumnonpx.js +5 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/data.js +178 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/data/Data.js +181 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/data/accepts.js +20 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/data/var/data_priv.js +5 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/data/var/data_user.js +5 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/deferred.js +149 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/deprecated.js +13 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/dimensions.js +50 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/effects.js +648 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/effects/Tween.js +114 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/effects/animatedSelector.js +13 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/event.js +868 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/event/ajax.js +13 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/event/alias.js +39 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/event/support.js +9 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/exports/amd.js +24 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/exports/global.js +32 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/intro.js +44 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/jquery.js +37 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/manipulation.js +580 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/manipulation/_evalUrl.js +18 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/manipulation/support.js +32 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/manipulation/var/rcheckableType.js +3 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/offset.js +207 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/outro.js +1 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/queue.js +142 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/queue/delay.js +22 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/selector-native.js +172 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/selector-sizzle.js +14 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/selector.js +1 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/serialize.js +111 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/sizzle/dist/sizzle.js +2067 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/sizzle/dist/sizzle.min.js +3 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/sizzle/dist/sizzle.min.map +1 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/traversing.js +199 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/traversing/findFilter.js +100 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/traversing/var/rneedsContext.js +6 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/var/arr.js +3 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/var/class2type.js +4 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/var/concat.js +5 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/var/hasOwn.js +5 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/var/indexOf.js +5 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/var/pnum.js +3 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/var/push.js +5 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/var/rnotwhite.js +3 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/var/slice.js +5 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/var/strundefined.js +3 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/var/support.js +4 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/var/toString.js +5 -0
- data/spec_app/vendor/assets/bower_components/jquery/src/wrap.js +79 -0
- data/spec_app/vendor/assets/javascripts/.keep +0 -0
- data/spec_app/vendor/assets/stylesheets/.keep +0 -0
- data/unpoly-rails.gemspec +24 -0
- metadata +423 -0
@@ -0,0 +1,204 @@
|
|
1
|
+
###*
|
2
|
+
Browser history
|
3
|
+
===============
|
4
|
+
|
5
|
+
\#\#\# Incomplete documentation!
|
6
|
+
|
7
|
+
We need to work on this page:
|
8
|
+
|
9
|
+
- Explain how the other modules manipulate history
|
10
|
+
- Decide whether we want to expose these methods as public API
|
11
|
+
- Document methods and parameters
|
12
|
+
|
13
|
+
@class up.history
|
14
|
+
###
|
15
|
+
up.history = (($) ->
|
16
|
+
|
17
|
+
u = up.util
|
18
|
+
|
19
|
+
###*
|
20
|
+
@property up.history.config
|
21
|
+
@param {Array} [config.popTargets=['body']]
|
22
|
+
An array of CSS selectors to replace when the user goes
|
23
|
+
back in history.
|
24
|
+
@param {Boolean} [config.restoreScroll=true]
|
25
|
+
Whether to restore the known scroll positions
|
26
|
+
when the user goes back or forward in history.
|
27
|
+
@stable
|
28
|
+
###
|
29
|
+
config = u.config
|
30
|
+
popTargets: ['body']
|
31
|
+
restoreScroll: true
|
32
|
+
|
33
|
+
###*
|
34
|
+
Returns the previous URL in the browser history.
|
35
|
+
|
36
|
+
Note that this will only work reliably for history changes that
|
37
|
+
were applied by [`up.history.push`](/up.history.replace) or
|
38
|
+
[`up.history.replace`](/up.history.replace).
|
39
|
+
|
40
|
+
@function up.history.previousUrl
|
41
|
+
@internal
|
42
|
+
###
|
43
|
+
previousUrl = undefined
|
44
|
+
nextPreviousUrl = undefined
|
45
|
+
|
46
|
+
reset = ->
|
47
|
+
config.reset()
|
48
|
+
previousUrl = undefined
|
49
|
+
nextPreviousUrl = undefined
|
50
|
+
|
51
|
+
normalizeUrl = (url) ->
|
52
|
+
u.normalizeUrl(url, hash: true)
|
53
|
+
|
54
|
+
###*
|
55
|
+
Returns a normalized URL for the current history entry.
|
56
|
+
|
57
|
+
@function up.history.url
|
58
|
+
@experimental
|
59
|
+
###
|
60
|
+
currentUrl = ->
|
61
|
+
normalizeUrl(up.browser.url())
|
62
|
+
|
63
|
+
isCurrentUrl = (url) ->
|
64
|
+
normalizeUrl(url) == currentUrl()
|
65
|
+
|
66
|
+
observeNewUrl = (url) ->
|
67
|
+
if nextPreviousUrl
|
68
|
+
previousUrl = nextPreviousUrl
|
69
|
+
nextPreviousUrl = undefined
|
70
|
+
nextPreviousUrl = url
|
71
|
+
|
72
|
+
###*
|
73
|
+
Replaces the current history entry and updates the
|
74
|
+
browser's location bar with the given URL.
|
75
|
+
|
76
|
+
When the user navigates to the replaced history entry at a later time,
|
77
|
+
Unpoly will [`replace`](/up.replace) the document body with
|
78
|
+
the body from that URL.
|
79
|
+
|
80
|
+
Note that functions like [`up.replace`](/up.replace) or
|
81
|
+
[`up.submit`](/up.submit) will automatically update the
|
82
|
+
browser's location bar for you.
|
83
|
+
|
84
|
+
@function up.history.replace
|
85
|
+
@param {String} url
|
86
|
+
@param {Boolean} [options.force=false]
|
87
|
+
@experimental
|
88
|
+
###
|
89
|
+
replace = (url, options) ->
|
90
|
+
manipulate('replace', url, options)
|
91
|
+
|
92
|
+
###*
|
93
|
+
Adds a new history entry and updates the browser's
|
94
|
+
address bar with the given URL.
|
95
|
+
|
96
|
+
When the user navigates to the added history entry at a later time,
|
97
|
+
Unpoly will [`replace`](/up.replace) the document body with
|
98
|
+
the body from that URL.
|
99
|
+
|
100
|
+
Note that functions like [`up.replace`](/up.replace) or
|
101
|
+
[`up.submit`](/up.submit) will automatically update the
|
102
|
+
browser's location bar for you.
|
103
|
+
|
104
|
+
@function up.history.push
|
105
|
+
@param {String} url
|
106
|
+
@experimental
|
107
|
+
###
|
108
|
+
push = (url, options) ->
|
109
|
+
up.puts("Current location is now %s", url)
|
110
|
+
manipulate('push', url, options)
|
111
|
+
|
112
|
+
manipulate = (method, url, options) ->
|
113
|
+
options = u.options(options, force: false)
|
114
|
+
if options.force || !isCurrentUrl(url)
|
115
|
+
if up.browser.canPushState()
|
116
|
+
fullMethod = "#{method}State" # resulting in either pushState or replaceState
|
117
|
+
state = buildState()
|
118
|
+
window.history[fullMethod](state, '', url)
|
119
|
+
observeNewUrl(currentUrl())
|
120
|
+
else
|
121
|
+
u.error "This browser doesn't support history.pushState"
|
122
|
+
|
123
|
+
buildState = ->
|
124
|
+
fromUp: true
|
125
|
+
|
126
|
+
restoreStateOnPop = (state) ->
|
127
|
+
if state?.fromUp
|
128
|
+
url = currentUrl()
|
129
|
+
up.log.group "Restoring URL %s", url, ->
|
130
|
+
popSelector = config.popTargets.join(', ')
|
131
|
+
up.replace popSelector, url,
|
132
|
+
history: false,
|
133
|
+
reveal: false,
|
134
|
+
transition: 'none',
|
135
|
+
saveScroll: false # since the URL was already changed by the browser, don't save scroll state
|
136
|
+
restoreScroll: config.restoreScroll
|
137
|
+
else
|
138
|
+
up.puts 'Ignoring a state not pushed by Unpoly (%o)', state
|
139
|
+
|
140
|
+
pop = (event) ->
|
141
|
+
up.log.group "History state popped to URL %s", currentUrl(), ->
|
142
|
+
observeNewUrl(currentUrl())
|
143
|
+
up.layout.saveScroll(url: previousUrl)
|
144
|
+
state = event.originalEvent.state
|
145
|
+
restoreStateOnPop(state)
|
146
|
+
|
147
|
+
# up.on 'framework:ready', ->
|
148
|
+
if up.browser.canPushState()
|
149
|
+
register = ->
|
150
|
+
$(window).on "popstate", pop
|
151
|
+
replace(currentUrl(), force: true)
|
152
|
+
|
153
|
+
if jasmine?
|
154
|
+
# Can't delay this in tests.
|
155
|
+
register()
|
156
|
+
else
|
157
|
+
# Defeat an unnecessary popstate that some browsers trigger
|
158
|
+
# on pageload (Safari, Chrome < 34).
|
159
|
+
# We should check in 2023 if we can remove this.
|
160
|
+
setTimeout register, 100
|
161
|
+
|
162
|
+
|
163
|
+
###*
|
164
|
+
Changes the link's destination so it points to the previous URL.
|
165
|
+
|
166
|
+
Note that this will *not* call `location.back()`, but will set
|
167
|
+
the link's `up-href` attribute to the actual, previous URL.
|
168
|
+
|
169
|
+
\#\#\#\# Under the hood
|
170
|
+
|
171
|
+
This link ...
|
172
|
+
|
173
|
+
<a href="/default" up-back>
|
174
|
+
Go back
|
175
|
+
</a>
|
176
|
+
|
177
|
+
... will be transformed to:
|
178
|
+
|
179
|
+
<a href="/default" up-href="/previous-page" up-restore-scroll up-follow>
|
180
|
+
Goback
|
181
|
+
</a>
|
182
|
+
|
183
|
+
@selector [up-back]
|
184
|
+
@stable
|
185
|
+
###
|
186
|
+
up.compiler '[up-back]', ($link) ->
|
187
|
+
if u.isPresent(previousUrl)
|
188
|
+
u.setMissingAttrs $link,
|
189
|
+
'up-href': previousUrl,
|
190
|
+
'up-restore-scroll': ''
|
191
|
+
$link.removeAttr 'up-back'
|
192
|
+
up.link.makeFollowable($link)
|
193
|
+
|
194
|
+
up.on 'up:framework:reset', reset
|
195
|
+
|
196
|
+
config: config
|
197
|
+
defaults: -> u.error('up.history.defaults(...) no longer exists. Set values on he up.history.config property instead.')
|
198
|
+
push: push
|
199
|
+
replace: replace
|
200
|
+
url: currentUrl
|
201
|
+
previousUrl: -> previousUrl
|
202
|
+
normalizeUrl: normalizeUrl
|
203
|
+
|
204
|
+
)(jQuery)
|
@@ -0,0 +1,529 @@
|
|
1
|
+
###*
|
2
|
+
Application layout
|
3
|
+
==================
|
4
|
+
|
5
|
+
This modules contains functions to scroll the viewport and reveal contained elements.
|
6
|
+
|
7
|
+
@class up.layout
|
8
|
+
###
|
9
|
+
up.layout = (($) ->
|
10
|
+
|
11
|
+
u = up.util
|
12
|
+
|
13
|
+
###*
|
14
|
+
Configures the application layout.
|
15
|
+
|
16
|
+
@property up.layout.config
|
17
|
+
@param {Array} [config.viewports]
|
18
|
+
An array of CSS selectors that find viewports
|
19
|
+
(containers that scroll their contents).
|
20
|
+
@param {Array} [config.fixedTop]
|
21
|
+
An array of CSS selectors that find elements fixed to the
|
22
|
+
top edge of the screen (using `position: fixed`).
|
23
|
+
@param {Array} [config.fixedBottom]
|
24
|
+
An array of CSS selectors that find elements fixed to the
|
25
|
+
bottom edge of the screen (using `position: fixed`).
|
26
|
+
@param {Array} [config.anchoredRight]
|
27
|
+
An array of CSS selectors that find elements anchored to the
|
28
|
+
right edge of the screen (using `position: fixed` or `position: absolute`).
|
29
|
+
@param {Number} [config.duration]
|
30
|
+
The duration of the scrolling animation in milliseconds.
|
31
|
+
Setting this to `0` will disable scrolling animations.
|
32
|
+
@param {String} [config.easing]
|
33
|
+
The timing function that controls the animation's acceleration.
|
34
|
+
See [W3C documentation](http://www.w3.org/TR/css3-transitions/#transition-timing-function)
|
35
|
+
for a list of pre-defined timing functions.
|
36
|
+
@param {Number} [config.snap]
|
37
|
+
When [revealing](/up.reveal) elements, Unpoly will scroll an viewport
|
38
|
+
to the top when the revealed element is closer to the top than `config.snap`.
|
39
|
+
@param {Number} [config.substance]
|
40
|
+
A number indicating how many top pixel rows of an element to [reveal](/up.reveal).
|
41
|
+
@stable
|
42
|
+
###
|
43
|
+
config = u.config
|
44
|
+
duration: 0
|
45
|
+
viewports: [document, '.up-modal', '[up-viewport]']
|
46
|
+
fixedTop: ['[up-fixed~=top]']
|
47
|
+
fixedBottom: ['[up-fixed~=bottom]']
|
48
|
+
anchoredRight: ['[up-anchored~=right]', '[up-fixed~=top]', '[up-fixed~=bottom]', '[up-fixed~=right]']
|
49
|
+
snap: 50
|
50
|
+
substance: 150
|
51
|
+
easing: 'swing'
|
52
|
+
|
53
|
+
lastScrollTops = u.cache
|
54
|
+
size: 30,
|
55
|
+
key: up.history.normalizeUrl
|
56
|
+
|
57
|
+
reset = ->
|
58
|
+
config.reset()
|
59
|
+
lastScrollTops.clear()
|
60
|
+
|
61
|
+
SCROLL_PROMISE_KEY = 'up-scroll-promise'
|
62
|
+
|
63
|
+
###*
|
64
|
+
Scrolls the given viewport to the given Y-position.
|
65
|
+
|
66
|
+
A "viewport" is an element that has scrollbars, e.g. `<body>` or
|
67
|
+
a container with `overflow-x: scroll`.
|
68
|
+
|
69
|
+
\#\#\#\# Example
|
70
|
+
|
71
|
+
This will scroll a `<div class="main">...</div>` to a Y-position of 100 pixels:
|
72
|
+
|
73
|
+
up.scroll('.main', 100);
|
74
|
+
|
75
|
+
\#\#\#\# Animating the scrolling motion
|
76
|
+
|
77
|
+
The scrolling can (optionally) be animated.
|
78
|
+
|
79
|
+
up.scroll('.main', 100, {
|
80
|
+
easing: 'swing',
|
81
|
+
duration: 250
|
82
|
+
});
|
83
|
+
|
84
|
+
If the given viewport is already in a scroll animation when `up.scroll`
|
85
|
+
is called a second time, the previous animation will instantly jump to the
|
86
|
+
last frame before the next animation is started.
|
87
|
+
|
88
|
+
@function up.scroll
|
89
|
+
@param {String|Element|jQuery} viewport
|
90
|
+
The container element to scroll.
|
91
|
+
@param {Number} scrollPos
|
92
|
+
The absolute number of pixels to set the scroll position to.
|
93
|
+
@param {Number}[options.duration]
|
94
|
+
The number of miliseconds for the scrolling's animation.
|
95
|
+
@param {String}[options.easing]
|
96
|
+
The timing function that controls the acceleration for the scrolling's animation.
|
97
|
+
@return {Deferred}
|
98
|
+
A promise that will be resolved when the scrolling ends.
|
99
|
+
@experimental
|
100
|
+
###
|
101
|
+
scroll = (viewport, scrollTop, options) ->
|
102
|
+
$viewport = $(viewport)
|
103
|
+
options = u.options(options)
|
104
|
+
duration = u.option(options.duration, config.duration)
|
105
|
+
easing = u.option(options.easing, config.easing)
|
106
|
+
|
107
|
+
finishScrolling($viewport)
|
108
|
+
|
109
|
+
if duration > 0
|
110
|
+
deferred = $.Deferred()
|
111
|
+
|
112
|
+
$viewport.data(SCROLL_PROMISE_KEY, deferred)
|
113
|
+
deferred.then ->
|
114
|
+
$viewport.removeData(SCROLL_PROMISE_KEY)
|
115
|
+
# Since we're scrolling using #animate, #finish can be
|
116
|
+
# used to jump to the last frame:
|
117
|
+
# https://api.jquery.com/finish/
|
118
|
+
$viewport.finish()
|
119
|
+
|
120
|
+
targetProps =
|
121
|
+
scrollTop: scrollTop
|
122
|
+
|
123
|
+
if $viewport.get(0) == document
|
124
|
+
$viewport = $('html, body') # FML
|
125
|
+
|
126
|
+
$viewport.animate targetProps,
|
127
|
+
duration: duration,
|
128
|
+
easing: easing,
|
129
|
+
complete: -> deferred.resolve()
|
130
|
+
|
131
|
+
deferred
|
132
|
+
else
|
133
|
+
$viewport.scrollTop(scrollTop)
|
134
|
+
u.resolvedDeferred()
|
135
|
+
|
136
|
+
###*
|
137
|
+
@function up.layout.finishScrolling
|
138
|
+
@param {String|Element|jQuery}
|
139
|
+
The element that might currently be scrolling.
|
140
|
+
@internal
|
141
|
+
###
|
142
|
+
finishScrolling = (elementOrSelector) ->
|
143
|
+
$(elementOrSelector).each ->
|
144
|
+
if existingScrolling = $(this).data(SCROLL_PROMISE_KEY)
|
145
|
+
existingScrolling.resolve()
|
146
|
+
|
147
|
+
###*
|
148
|
+
@function up.layout.anchoredRight
|
149
|
+
@internal
|
150
|
+
###
|
151
|
+
anchoredRight = ->
|
152
|
+
u.multiSelector(config.anchoredRight).select()
|
153
|
+
|
154
|
+
measureObstruction = ->
|
155
|
+
|
156
|
+
measurePosition = (obstructor, cssAttr) ->
|
157
|
+
$obstructor = $(obstructor)
|
158
|
+
anchorPosition = $obstructor.css(cssAttr)
|
159
|
+
unless u.isPresent(anchorPosition)
|
160
|
+
u.error("Fixed element %o must have a CSS attribute %s", $obstructor.get(0), cssAttr)
|
161
|
+
parseInt(anchorPosition) + $obstructor.height()
|
162
|
+
|
163
|
+
fixedTopBottoms = for obstructor in $(config.fixedTop.join(', '))
|
164
|
+
measurePosition(obstructor, 'top')
|
165
|
+
|
166
|
+
fixedBottomTops = for obstructor in $(config.fixedBottom.join(', '))
|
167
|
+
measurePosition(obstructor, 'bottom')
|
168
|
+
|
169
|
+
top: Math.max(0, fixedTopBottoms...)
|
170
|
+
bottom: Math.max(0, fixedBottomTops...)
|
171
|
+
|
172
|
+
###*
|
173
|
+
Scroll's the given element's viewport so the first rows of the
|
174
|
+
element are visible for the user.
|
175
|
+
|
176
|
+
By default Unpoly will always reveal an element before
|
177
|
+
updating it with Javascript functions like [`up.replace`](/up.replace)
|
178
|
+
or UJS behavior like [`[up-target]`](/up-target).
|
179
|
+
|
180
|
+
\#\#\#\# How Unpoly finds the viewport
|
181
|
+
|
182
|
+
The viewport (the container that is going to be scrolled)
|
183
|
+
is the closest parent of the element that is either:
|
184
|
+
|
185
|
+
- the currently open [modal](/up.modal)
|
186
|
+
- an element with the attribute `[up-viewport]`
|
187
|
+
- the `<body>` element
|
188
|
+
- an element matching the selector you have configured using `up.layout.config.viewports.push('my-custom-selector')`
|
189
|
+
|
190
|
+
\#\#\#\# Fixed elements obstruction the viewport
|
191
|
+
|
192
|
+
Many applications have a navigation bar fixed to the top or bottom,
|
193
|
+
obstructing the view on an element.
|
194
|
+
|
195
|
+
You can make `up.reveal` aware of these fixed elements
|
196
|
+
so it can scroll the viewport far enough so the revealed element is fully visible.
|
197
|
+
To make `up.reveal` aware fixed elements you can either:
|
198
|
+
|
199
|
+
- give the element an attribute [`up-fixed="top"`](/up-fixed-top) or [`up-fixed="bottom"`](up-fixed-bottom)
|
200
|
+
- [configure default options](/up.layout.config) for `fixedTop` or `fixedBottom`
|
201
|
+
|
202
|
+
@function up.reveal
|
203
|
+
@param {String|Element|jQuery} element
|
204
|
+
@param {Number} [options.duration]
|
205
|
+
@param {String} [options.easing]
|
206
|
+
@param {String} [options.snap]
|
207
|
+
@param {String|Element|jQuery} [options.viewport]
|
208
|
+
@param {Boolean} [options.top=false]
|
209
|
+
Whether to scroll the viewport so that the first element row aligns
|
210
|
+
with the top edge of the viewport.
|
211
|
+
@return {Deferred}
|
212
|
+
A promise that will be resolved when the element is revealed.
|
213
|
+
@stable
|
214
|
+
###
|
215
|
+
reveal = (elementOrSelector, options) ->
|
216
|
+
$element = $(elementOrSelector)
|
217
|
+
up.puts 'Revealing fragment %o', elementOrSelector.get(0)
|
218
|
+
options = u.options(options)
|
219
|
+
$viewport = if options.viewport then $(options.viewport) else viewportOf($element)
|
220
|
+
|
221
|
+
snap = u.option(options.snap, config.snap)
|
222
|
+
|
223
|
+
viewportIsDocument = $viewport.is(document)
|
224
|
+
viewportHeight = if viewportIsDocument then u.clientSize().height else $viewport.height()
|
225
|
+
originalScrollPos = $viewport.scrollTop()
|
226
|
+
newScrollPos = originalScrollPos
|
227
|
+
|
228
|
+
offsetShift = undefined
|
229
|
+
obstruction = undefined
|
230
|
+
|
231
|
+
if viewportIsDocument
|
232
|
+
obstruction = measureObstruction()
|
233
|
+
# Within the body, $.position will always return the distance
|
234
|
+
# from the document top and *not* the distance of the viewport
|
235
|
+
# top. This is what the calculations below expect, so don't shift.
|
236
|
+
offsetShift = 0
|
237
|
+
else
|
238
|
+
obstruction = { top: 0, bottom: 0 }
|
239
|
+
# When the scrolled element is not <body> but instead a container
|
240
|
+
# with overflow-y: scroll, $.position returns the position the
|
241
|
+
# viewport's top edge instead of the first row of the canvas buffer.
|
242
|
+
# http://codepen.io/anon/pen/jPojGE
|
243
|
+
offsetShift = originalScrollPos
|
244
|
+
|
245
|
+
predictFirstVisibleRow = -> newScrollPos + obstruction.top
|
246
|
+
predictLastVisibleRow = -> newScrollPos + viewportHeight - obstruction.bottom - 1
|
247
|
+
|
248
|
+
elementDims = u.measure($element, relative: $viewport)
|
249
|
+
firstElementRow = elementDims.top + offsetShift
|
250
|
+
|
251
|
+
lastElementRow = firstElementRow + Math.min(elementDims.height, config.substance) - 1
|
252
|
+
|
253
|
+
if lastElementRow > predictLastVisibleRow()
|
254
|
+
# Try to show the full height of the element
|
255
|
+
newScrollPos += (lastElementRow - predictLastVisibleRow())
|
256
|
+
|
257
|
+
if firstElementRow < predictFirstVisibleRow() || options.top
|
258
|
+
# If the full element does not fit, scroll to the first row
|
259
|
+
newScrollPos = firstElementRow - obstruction.top
|
260
|
+
|
261
|
+
if newScrollPos < snap
|
262
|
+
newScrollPos = 0
|
263
|
+
|
264
|
+
if newScrollPos != originalScrollPos
|
265
|
+
scroll($viewport, newScrollPos, options)
|
266
|
+
else
|
267
|
+
u.resolvedDeferred()
|
268
|
+
|
269
|
+
viewportSelector = ->
|
270
|
+
u.multiSelector(config.viewports)
|
271
|
+
|
272
|
+
###*
|
273
|
+
Returns the viewport for the given element.
|
274
|
+
|
275
|
+
Throws an error if no viewport could be found.
|
276
|
+
|
277
|
+
@function up.layout.viewportOf
|
278
|
+
@param {String|Element|jQuery} selectorOrElement
|
279
|
+
@internal
|
280
|
+
###
|
281
|
+
viewportOf = (selectorOrElement) ->
|
282
|
+
$element = $(selectorOrElement)
|
283
|
+
$viewport = viewportSelector().seekUp($element)
|
284
|
+
$viewport.length or u.error("Could not find viewport for %o", $element)
|
285
|
+
$viewport
|
286
|
+
|
287
|
+
###*
|
288
|
+
Returns a jQuery collection of all the viewports contained within the
|
289
|
+
given selector or element.
|
290
|
+
|
291
|
+
@function up.layout.viewportsWithin
|
292
|
+
@param {String|Element|jQuery} selectorOrElement
|
293
|
+
@return jQuery
|
294
|
+
@internal
|
295
|
+
###
|
296
|
+
viewportsWithin = (selectorOrElement) ->
|
297
|
+
$element = $(selectorOrElement)
|
298
|
+
viewportSelector().findWithSelf($element)
|
299
|
+
|
300
|
+
###*
|
301
|
+
Returns a jQuery collection of all the viewports on the screen.
|
302
|
+
|
303
|
+
@function up.layout.viewports
|
304
|
+
@internal
|
305
|
+
###
|
306
|
+
viewports = ->
|
307
|
+
viewportSelector().select()
|
308
|
+
|
309
|
+
###*
|
310
|
+
Returns a hash with scroll positions.
|
311
|
+
|
312
|
+
Each key in the hash is a viewport selector. The corresponding
|
313
|
+
value is the viewport's top scroll position:
|
314
|
+
|
315
|
+
up.layout.scrollTops()
|
316
|
+
=> { '.main': 0, '.sidebar': 73 }
|
317
|
+
|
318
|
+
@function up.layout.scrollTops
|
319
|
+
@return Object<String, Number>
|
320
|
+
@internal
|
321
|
+
###
|
322
|
+
scrollTops = ->
|
323
|
+
topsBySelector = {}
|
324
|
+
for viewport in config.viewports
|
325
|
+
$viewport = $(viewport)
|
326
|
+
if $viewport.length
|
327
|
+
key = viewport
|
328
|
+
key = 'document' if viewport == document
|
329
|
+
topsBySelector[key] = $viewport.scrollTop()
|
330
|
+
topsBySelector
|
331
|
+
|
332
|
+
###*
|
333
|
+
@function up.layout.fixedChildren
|
334
|
+
@internal
|
335
|
+
###
|
336
|
+
fixedChildren = (root = undefined) ->
|
337
|
+
root ||= document.body
|
338
|
+
$root = $(root)
|
339
|
+
$elements = $root.find('[up-fixed]')
|
340
|
+
$elements = $elements.add($root.find(config.fixedTop.join(', '))) if u.isPresent(config.fixedTop)
|
341
|
+
$elements = $elements.add($root.find(config.fixedBottom.join(', '))) if u.isPresent(config.fixedBottom)
|
342
|
+
$elements
|
343
|
+
|
344
|
+
###*
|
345
|
+
Saves the top scroll positions of all the
|
346
|
+
viewports configured in [`up.layout.config.viewports`](/up.layout.config).
|
347
|
+
|
348
|
+
The scroll positions will be associated with the current URL.
|
349
|
+
They can later be restored by calling [`up.layout.restoreScroll()`](/up.layout.restoreScroll)
|
350
|
+
at the same URL.
|
351
|
+
|
352
|
+
Unpoly automatically saves scroll positions whenever a fragment was updated on the page.
|
353
|
+
|
354
|
+
@function up.layout.saveScroll
|
355
|
+
@param {String} [options.url]
|
356
|
+
@param {Object<String, Number>} [options.tops]
|
357
|
+
@experimental
|
358
|
+
###
|
359
|
+
saveScroll = (options = {}) ->
|
360
|
+
url = u.option(options.url, up.history.url())
|
361
|
+
tops = u.option(options.tops, scrollTops())
|
362
|
+
up.puts('Saving scroll positions for URL %s (%o)', url, tops)
|
363
|
+
lastScrollTops.set(url, tops)
|
364
|
+
|
365
|
+
###*
|
366
|
+
Restores [previously saved](/up.layout.saveScroll) scroll positions of viewports
|
367
|
+
viewports configured in [`up.layout.config.viewports`](/up.layout.config).
|
368
|
+
|
369
|
+
Unpoly automatically restores scroll positions when the user presses the back button.
|
370
|
+
You can disable this behavior by setting [`up.history.config.restoreScroll = false`](/up.history.config).
|
371
|
+
|
372
|
+
@function up.layout.restoreScroll
|
373
|
+
@param {jQuery} [options.around]
|
374
|
+
If set, only restores viewports that are either an ancestor
|
375
|
+
or descendant of the given element.
|
376
|
+
@experimental
|
377
|
+
###
|
378
|
+
restoreScroll = (options = {}) ->
|
379
|
+
|
380
|
+
url = up.history.url()
|
381
|
+
|
382
|
+
$viewports = undefined
|
383
|
+
|
384
|
+
if options.around
|
385
|
+
$descendantViewports = viewportsWithin(options.around)
|
386
|
+
$ancestorViewports = viewportOf(options.around)
|
387
|
+
$viewports = $ancestorViewports.add($descendantViewports)
|
388
|
+
else
|
389
|
+
$viewports = viewports()
|
390
|
+
|
391
|
+
tops = lastScrollTops.get(url)
|
392
|
+
|
393
|
+
up.log.group 'Restoring scroll positions for URL %s to %o', url, tops, ->
|
394
|
+
for key, scrollTop of tops
|
395
|
+
right = if key == 'document' then document else key
|
396
|
+
$matchingViewport = $viewports.filter(right)
|
397
|
+
scroll($matchingViewport, scrollTop, duration: 0)
|
398
|
+
|
399
|
+
# Since scrolling happens without animation, we don't need to
|
400
|
+
# join promises from the up.scroll call above
|
401
|
+
u.resolvedDeferred()
|
402
|
+
|
403
|
+
###*
|
404
|
+
@function up.layout.revealOrRestoreScroll
|
405
|
+
@return {Deferred}
|
406
|
+
A promise for when the revealing or scroll restauration ends
|
407
|
+
@internal
|
408
|
+
###
|
409
|
+
revealOrRestoreScroll = (selectorOrElement, options) ->
|
410
|
+
$element = $(selectorOrElement)
|
411
|
+
if options.restoreScroll
|
412
|
+
restoreScroll(around: $element)
|
413
|
+
else if options.reveal
|
414
|
+
if options.source
|
415
|
+
parsed = u.parseUrl(options.source)
|
416
|
+
if parsed.hash && parsed.hash != '#'
|
417
|
+
id = parsed.hash.substr(1)
|
418
|
+
$target = u.findWithSelf($element, "##{id}, a[name='#{id}']")
|
419
|
+
$element = $target if $target.length
|
420
|
+
reveal($element)
|
421
|
+
else
|
422
|
+
u.resolvedDeferred()
|
423
|
+
|
424
|
+
|
425
|
+
###*
|
426
|
+
Marks this element as a scrolling container ("viewport").
|
427
|
+
|
428
|
+
Apply this attribute if your app uses a custom panel layout with fixed positioning
|
429
|
+
instead of scrolling `<body>`. As an alternative you can also push a selector
|
430
|
+
matching your custom viewport to the [`up.layout.config.viewports`](/up.layout.config) array.
|
431
|
+
|
432
|
+
[`up.reveal`](/up.reveal) will always try to scroll the viewport closest
|
433
|
+
to the element that is being revealed. By default this is the `<body>` element.
|
434
|
+
|
435
|
+
\#\#\#\# Example
|
436
|
+
|
437
|
+
Here is an example for a layout for an e-mail client, showing a list of e-mails
|
438
|
+
on the left side and the e-mail text on the right side:
|
439
|
+
|
440
|
+
.side {
|
441
|
+
position: fixed;
|
442
|
+
top: 0;
|
443
|
+
bottom: 0;
|
444
|
+
left: 0;
|
445
|
+
width: 100px;
|
446
|
+
overflow-y: scroll;
|
447
|
+
}
|
448
|
+
|
449
|
+
.main {
|
450
|
+
position: fixed;
|
451
|
+
top: 0;
|
452
|
+
bottom: 0;
|
453
|
+
left: 100px;
|
454
|
+
right: 0;
|
455
|
+
overflow-y: scroll;
|
456
|
+
}
|
457
|
+
|
458
|
+
This would be the HTML (notice the `up-viewport` attribute):
|
459
|
+
|
460
|
+
<div class=".side" up-viewport>
|
461
|
+
<a href="/emails/5001" up-target=".main">Re: Your invoice</a>
|
462
|
+
<a href="/emails/2023" up-target=".main">Quote for services</a>
|
463
|
+
<a href="/emails/9002" up-target=".main">Fwd: Room reservation</a>
|
464
|
+
</div>
|
465
|
+
|
466
|
+
<div class="main" up-viewport>
|
467
|
+
<h1>Re: Your Invoice</h1>
|
468
|
+
<p>
|
469
|
+
Lorem ipsum dolor sit amet, consetetur sadipscing elitr.
|
470
|
+
Stet clita kasd gubergren, no sea takimata sanctus est.
|
471
|
+
</p>
|
472
|
+
</div>
|
473
|
+
|
474
|
+
@selector [up-viewport]
|
475
|
+
@stable
|
476
|
+
###
|
477
|
+
|
478
|
+
###*
|
479
|
+
Marks this element as a navigation fixed to the top edge of the screen
|
480
|
+
using `position: fixed`.
|
481
|
+
|
482
|
+
[`up.reveal`](/up.reveal) is aware of fixed elements and will scroll
|
483
|
+
the viewport far enough so the revealed element is fully visible.
|
484
|
+
|
485
|
+
\#\#\#\# Example
|
486
|
+
|
487
|
+
<div class="top-nav" up-fixed="top">...</div>
|
488
|
+
|
489
|
+
@selector [up-fixed=top]
|
490
|
+
@stable
|
491
|
+
###
|
492
|
+
|
493
|
+
###*
|
494
|
+
Marks this element as a navigation fixed to the bottom edge of the screen
|
495
|
+
using `position: fixed`.
|
496
|
+
|
497
|
+
[`up.reveal`](/up.reveal) is aware of fixed elements and will scroll
|
498
|
+
the viewport far enough so the revealed element is fully visible.
|
499
|
+
|
500
|
+
\#\#\#\# Example
|
501
|
+
|
502
|
+
<div class="bottom-nav" up-fixed="bottom">...</div>
|
503
|
+
|
504
|
+
@selector [up-fixed=bottom]
|
505
|
+
@stable
|
506
|
+
###
|
507
|
+
|
508
|
+
up.on 'up:framework:reset', reset
|
509
|
+
|
510
|
+
knife: eval(Knife?.point)
|
511
|
+
reveal: reveal
|
512
|
+
scroll: scroll
|
513
|
+
finishScrolling: finishScrolling
|
514
|
+
config: config
|
515
|
+
defaults: -> u.error('up.layout.defaults(...) no longer exists. Set values on he up.layout.config property instead.')
|
516
|
+
viewportOf: viewportOf
|
517
|
+
viewportsWithin: viewportsWithin
|
518
|
+
viewports: viewports
|
519
|
+
scrollTops: scrollTops
|
520
|
+
saveScroll: saveScroll
|
521
|
+
restoreScroll: restoreScroll
|
522
|
+
revealOrRestoreScroll: revealOrRestoreScroll
|
523
|
+
anchoredRight: anchoredRight
|
524
|
+
fixedChildren: fixedChildren
|
525
|
+
|
526
|
+
)(jQuery)
|
527
|
+
|
528
|
+
up.scroll = up.layout.scroll
|
529
|
+
up.reveal = up.layout.reveal
|