kms 0.9.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/{vendor/assets/bower_components/Responsive-Dashboard/src/img → app/assets/images}/avatar.jpg +0 -0
- data/app/assets/javascripts/kms/application.js +3 -0
- data/app/assets/javascripts/kms/application/controllers/assets_controller.coffee.erb +14 -7
- data/app/assets/javascripts/kms/application/controllers/pages_controller.coffee.erb +11 -3
- data/app/assets/javascripts/kms/application/controllers/snippets_controller.coffee.erb +3 -0
- data/app/assets/javascripts/kms/application/controllers/templates_controller.coffee.erb +3 -0
- data/app/assets/javascripts/kms/application/controllers/users_controller.coffee +4 -4
- data/app/assets/javascripts/kms/application/routes.coffee.erb +1 -1
- data/app/assets/javascripts/kms/application/services/transliteration_service.js +160 -0
- data/app/assets/javascripts/templates/assets/edit.html.slim +24 -2
- data/app/assets/javascripts/templates/assets/form.html.slim +23 -0
- data/app/assets/javascripts/templates/assets/index.html.slim +13 -12
- data/app/assets/javascripts/templates/assets/new.html.slim +1 -15
- data/app/assets/javascripts/templates/help.html.slim +1 -1
- data/app/assets/javascripts/templates/pages/index.html.slim +16 -5
- data/app/assets/javascripts/templates/snippets/index.html.slim +16 -5
- data/app/assets/javascripts/templates/templates/index.html.slim +16 -6
- data/app/assets/stylesheets/kms/application.css +2 -2
- data/app/assets/stylesheets/kms/custom.css.scss +38 -0
- data/app/controllers/kms/assets_controller.rb +8 -9
- data/app/controllers/kms/pages_controller.rb +10 -11
- data/app/controllers/kms/public/pages_controller.rb +5 -4
- data/app/controllers/kms/public/search_controller.rb +2 -0
- data/app/controllers/kms/settings_controller.rb +1 -1
- data/app/controllers/kms/snippets_controller.rb +2 -1
- data/app/controllers/kms/templates_controller.rb +6 -5
- data/app/controllers/kms/users_controller.rb +11 -8
- data/app/models/ability.rb +1 -0
- data/app/models/concerns/kms/permalinkable.rb +1 -1
- data/app/models/kms/page.rb +13 -4
- data/app/serializers/kms/asset_serializer.rb +6 -0
- data/app/serializers/kms/page_serializer.rb +5 -0
- data/app/serializers/kms/template_serializer.rb +5 -0
- data/app/serializers/kms/user_serializer.rb +5 -0
- data/app/services/kms/page_fetcher.rb +30 -0
- data/app/services/kms/search_service.rb +28 -3
- data/app/services/kms/template_processor.rb +19 -0
- data/app/views/devise/passwords/edit.html.erb +1 -1
- data/app/views/devise/passwords/new.html.erb +1 -1
- data/app/views/devise/registrations/new.html.erb +1 -1
- data/app/views/devise/sessions/new.html.erb +1 -1
- data/app/views/layouts/kms/devise.html.erb +1 -1
- data/app/views/layouts/kms/kms.html.erb +47 -18
- data/config/initializers/externals.rb +6 -32
- data/config/initializers/search.rb +1 -0
- data/config/locales/en.yml +17 -1
- data/config/locales/ru.yml +17 -1
- data/config/routes.rb +7 -6
- data/lib/kms/dependencies.rb +1 -4
- data/lib/kms/engine.rb +1 -2
- data/lib/kms/search_item.rb +18 -0
- data/lib/kms/version.rb +1 -1
- data/spec/controllers/kms/assets_controller_spec.rb +51 -0
- data/spec/controllers/kms/pages_controller_spec.rb +82 -0
- data/spec/controllers/kms/public/pages_controller_spec.rb +30 -0
- data/spec/controllers/kms/snippets_controller_spec.rb +61 -47
- data/spec/controllers/kms/templates_controller_spec.rb +51 -0
- data/spec/controllers/kms/users_controller_spec.rb +56 -0
- data/spec/factories/assets.rb +8 -0
- data/spec/factories/pages.rb +33 -0
- data/spec/factories/templates.rb +20 -0
- data/spec/factories/users.rb +9 -4
- data/spec/internal/config/routes.rb +12 -1
- data/spec/internal/log/test.log +81239 -0
- data/spec/internal/public/404.html +67 -0
- data/spec/internal/public/avatar.jpg +0 -0
- data/spec/internal/public/style.css +1 -0
- data/spec/internal/public/uploads/kms/asset/file/1/avatar.jpg +0 -0
- data/spec/internal/public/uploads/kms/asset/file/2/avatar.jpg +0 -0
- data/spec/internal/public/uploads/kms/asset/file/2/style.css +1 -0
- data/spec/internal/public/uploads/kms/asset/file/3/style.css +1 -0
- data/spec/internal/public/uploads/kms/asset/file/4/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500976987-41025-0002-0883/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500977082-41195-0002-6495/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500977109-41364-0002-4518/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500977152-41405-0002-2345/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500977327-41694-0002-5448/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500977376-41732-0002-7916/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500977392-41759-0002-7593/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500977410-42259-0002-7527/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500977429-42306-0002-5937/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500977437-42324-0002-5880/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500983228-53594-0002-4559/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500983284-53632-0002-6590/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500983360-53784-0002-7289/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500983469-54321-0002-0386/avatar.jpg +0 -0
- data/spec/internal/public/uploads/tmp/1500983469-54321-0004-5691/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500983511-54352-0002-5720/avatar.jpg +0 -0
- data/spec/internal/public/uploads/tmp/1500983511-54352-0004-1399/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500983610-54507-0002-4280/avatar.jpg +0 -0
- data/spec/internal/public/uploads/tmp/1500983610-54507-0004-9758/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500984466-57012-0002-4146/avatar.jpg +0 -0
- data/spec/internal/public/uploads/tmp/1500984466-57012-0004-5895/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500984509-57158-0002-9657/avatar.jpg +0 -0
- data/spec/internal/public/uploads/tmp/1500984509-57158-0004-5003/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500984616-57697-0002-7201/avatar.jpg +0 -0
- data/spec/internal/public/uploads/tmp/1500984616-57697-0004-6255/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500985257-58947-0002-3629/avatar.jpg +0 -0
- data/spec/internal/public/uploads/tmp/1500985257-58947-0004-5338/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500985407-58947-0006-5929/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500985473-59264-0002-0397/avatar.jpg +0 -0
- data/spec/internal/public/uploads/tmp/1500985473-59264-0004-6493/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500985475-59264-0007-8674/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500985538-59468-0002-9206/avatar.jpg +0 -0
- data/spec/internal/public/uploads/tmp/1500985538-59468-0004-2586/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500985538-59468-0007-6200/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500988358-65877-0002-4528/avatar.jpg +0 -0
- data/spec/internal/public/uploads/tmp/1500988358-65877-0004-5904/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500988358-65877-0007-7320/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500988407-65916-0002-3138/avatar.jpg +0 -0
- data/spec/internal/public/uploads/tmp/1500988407-65916-0004-5400/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500988407-65916-0007-1655/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500988421-65950-0002-9415/avatar.jpg +0 -0
- data/spec/internal/public/uploads/tmp/1500988421-65950-0004-7130/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500988421-65950-0007-9886/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500988435-65981-0002-3228/avatar.jpg +0 -0
- data/spec/internal/public/uploads/tmp/1500988435-65981-0004-3682/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500988435-65981-0007-1582/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500988475-66122-0002-9516/avatar.jpg +0 -0
- data/spec/internal/public/uploads/tmp/1500988475-66122-0004-5634/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500988530-66122-0007-2272/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500988554-66315-0002-6262/avatar.jpg +0 -0
- data/spec/internal/public/uploads/tmp/1500988554-66315-0004-6099/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500988554-66315-0007-1632/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500991751-73722-0002-9937/avatar.jpg +0 -0
- data/spec/internal/public/uploads/tmp/1500991751-73722-0004-8034/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1500991751-73722-0007-7763/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1501233238-34385-0002-3210/avatar.jpg +0 -0
- data/spec/internal/public/uploads/tmp/1501233238-34385-0004-5881/style.css +1 -0
- data/spec/internal/public/uploads/tmp/1501233238-34385-0007-6280/style.css +1 -0
- data/spec/models/kms/page_spec.rb +31 -0
- data/spec/models/kms/template_spec.rb +15 -0
- data/spec/services/kms/page_fetcher_spec.rb +36 -0
- data/spec/services/kms/search_service_spec.rb +53 -0
- data/spec/services/kms/template_processor_spec.rb +20 -0
- data/spec/support/controller_macros.rb +9 -1
- data/vendor/assets/bower.json +3 -2
- data/vendor/assets/bower_components/angular-ui-select/CHANGELOG.md +169 -0
- data/vendor/assets/bower_components/angular-ui-select/CONTRIBUTING.md +161 -0
- data/vendor/assets/bower_components/angular-ui-select/README.md +27 -13
- data/vendor/assets/bower_components/angular-ui-select/bower.json +6 -3
- data/vendor/assets/bower_components/angular-ui-select/composer.json +29 -0
- data/vendor/assets/bower_components/angular-ui-select/deploy-docs.sh +31 -0
- data/vendor/assets/bower_components/angular-ui-select/dist/select.css +48 -2
- data/vendor/assets/bower_components/angular-ui-select/dist/select.js +454 -111
- data/vendor/assets/bower_components/angular-ui-select/dist/select.min.css +2 -2
- data/vendor/assets/bower_components/angular-ui-select/dist/select.min.js +2 -2
- data/vendor/assets/bower_components/angular-ui-select/docs/assets/app.js +1 -0
- data/vendor/assets/bower_components/angular-ui-select/docs/assets/demo.js +461 -0
- data/vendor/assets/bower_components/angular-ui-select/docs/assets/docs.css +339 -0
- data/vendor/assets/bower_components/angular-ui-select/docs/assets/plunkr.js +110 -0
- data/vendor/assets/bower_components/angular-ui-select/docs/index.html +191 -0
- data/vendor/assets/bower_components/angular-ui-select/docs/partials/_footer.html +2 -0
- data/vendor/assets/bower_components/angular-ui-select/docs/partials/_header.html +64 -0
- data/vendor/assets/bower_components/angular-ui-select/index.js +2 -0
- data/vendor/assets/bower_components/angular-ui-select/package.json +36 -15
- data/vendor/assets/bower_components/bootstrap/CHANGELOG.md +5 -0
- data/vendor/assets/bower_components/bootstrap/Gemfile +6 -0
- data/vendor/assets/bower_components/bootstrap/Gemfile.lock +43 -0
- data/vendor/assets/bower_components/bootstrap/Gruntfile.js +176 -145
- data/vendor/assets/bower_components/bootstrap/ISSUE_TEMPLATE.md +22 -0
- data/vendor/assets/bower_components/bootstrap/LICENSE +1 -1
- data/vendor/assets/bower_components/bootstrap/README.md +55 -40
- data/vendor/assets/bower_components/bootstrap/bower.json +5 -9
- data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap-theme.css +204 -59
- data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap-theme.css.map +1 -1
- data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap-theme.min.css +4 -3
- data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap-theme.min.css.map +1 -0
- data/vendor/assets/bower_components/bootstrap/dist/css/{bootstrap.less → bootstrap.css} +881 -327
- data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap.css.map +1 -1
- data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap.min.css +6 -0
- data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap.min.css.map +1 -0
- data/vendor/assets/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.eot +0 -0
- data/vendor/assets/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.svg +272 -213
- data/vendor/assets/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/vendor/assets/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff +0 -0
- data/vendor/assets/bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2 +0 -0
- data/vendor/assets/bower_components/bootstrap/dist/js/bootstrap.js +549 -286
- data/vendor/assets/bower_components/bootstrap/dist/js/bootstrap.min.js +5 -4
- data/vendor/assets/bower_components/bootstrap/dist/js/npm.js +13 -0
- data/vendor/assets/bower_components/bootstrap/fonts/glyphicons-halflings-regular.eot +0 -0
- data/vendor/assets/bower_components/bootstrap/fonts/glyphicons-halflings-regular.svg +272 -213
- data/vendor/assets/bower_components/bootstrap/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/vendor/assets/bower_components/bootstrap/fonts/glyphicons-halflings-regular.woff +0 -0
- data/vendor/assets/bower_components/bootstrap/fonts/glyphicons-halflings-regular.woff2 +0 -0
- data/vendor/assets/bower_components/bootstrap/grunt/bs-commonjs-generator.js +30 -0
- data/vendor/assets/bower_components/bootstrap/grunt/bs-glyphicons-data-generator.js +5 -4
- data/vendor/assets/bower_components/bootstrap/grunt/bs-lessdoc-parser.js +13 -12
- data/vendor/assets/bower_components/bootstrap/grunt/bs-raw-files-generator.js +6 -8
- data/vendor/assets/bower_components/bootstrap/grunt/change-version.js +109 -0
- data/vendor/assets/bower_components/bootstrap/grunt/configBridge.json +46 -0
- data/vendor/assets/bower_components/bootstrap/grunt/npm-shrinkwrap.json +2679 -0
- data/vendor/assets/bower_components/bootstrap/grunt/sauce_browsers.yml +5 -5
- data/vendor/assets/bower_components/bootstrap/js/affix.js +46 -26
- data/vendor/assets/bower_components/bootstrap/js/alert.js +8 -6
- data/vendor/assets/bower_components/bootstrap/js/button.js +34 -19
- data/vendor/assets/bower_components/bootstrap/js/carousel.js +35 -21
- data/vendor/assets/bower_components/bootstrap/js/collapse.js +69 -27
- data/vendor/assets/bower_components/bootstrap/js/dropdown.js +55 -41
- data/vendor/assets/bower_components/bootstrap/js/modal.js +91 -32
- data/vendor/assets/bower_components/bootstrap/js/popover.js +5 -10
- data/vendor/assets/bower_components/bootstrap/js/scrollspy.js +28 -26
- data/vendor/assets/bower_components/bootstrap/js/tab.js +45 -18
- data/vendor/assets/bower_components/bootstrap/js/tooltip.js +117 -54
- data/vendor/assets/bower_components/bootstrap/js/transition.js +2 -2
- data/vendor/assets/bower_components/bootstrap/less/alerts.less +5 -0
- data/vendor/assets/bower_components/bootstrap/less/badges.less +14 -3
- data/vendor/assets/bower_components/bootstrap/less/bootstrap.less +6 -0
- data/vendor/assets/bower_components/bootstrap/less/button-groups.less +22 -18
- data/vendor/assets/bower_components/bootstrap/less/buttons.less +19 -10
- data/vendor/assets/bower_components/bootstrap/less/carousel.less +34 -7
- data/vendor/assets/bower_components/bootstrap/less/close.less +1 -0
- data/vendor/assets/bower_components/bootstrap/less/code.less +1 -0
- data/vendor/assets/bower_components/bootstrap/less/component-animations.less +3 -1
- data/vendor/assets/bower_components/bootstrap/less/dropdowns.less +9 -8
- data/vendor/assets/bower_components/bootstrap/less/forms.less +123 -50
- data/vendor/assets/bower_components/bootstrap/less/glyphicons.less +75 -3
- data/vendor/assets/bower_components/bootstrap/less/input-groups.less +8 -3
- data/vendor/assets/bower_components/bootstrap/less/jumbotron.less +10 -4
- data/vendor/assets/bower_components/bootstrap/less/list-group.less +10 -11
- data/vendor/assets/bower_components/bootstrap/less/media.less +40 -30
- data/vendor/assets/bower_components/bootstrap/less/mixins.less +1 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/background-variant.less +2 -1
- data/vendor/assets/bower_components/bootstrap/less/mixins/buttons.less +19 -4
- data/vendor/assets/bower_components/bootstrap/less/mixins/forms.less +5 -1
- data/vendor/assets/bower_components/bootstrap/less/mixins/grid-framework.less +4 -4
- data/vendor/assets/bower_components/bootstrap/less/mixins/grid.less +4 -4
- data/vendor/assets/bower_components/bootstrap/less/mixins/hide-text.less +2 -2
- data/vendor/assets/bower_components/bootstrap/less/mixins/image.less +0 -1
- data/vendor/assets/bower_components/bootstrap/less/mixins/labels.less +1 -1
- data/vendor/assets/bower_components/bootstrap/less/mixins/list-group.less +2 -1
- data/vendor/assets/bower_components/bootstrap/less/mixins/pagination.less +2 -1
- data/vendor/assets/bower_components/bootstrap/less/mixins/reset-text.less +18 -0
- data/vendor/assets/bower_components/bootstrap/less/mixins/responsive-visibility.less +1 -1
- data/vendor/assets/bower_components/bootstrap/less/mixins/tab-focus.less +3 -3
- data/vendor/assets/bower_components/bootstrap/less/mixins/text-emphasis.less +2 -1
- data/vendor/assets/bower_components/bootstrap/less/mixins/vendor-prefixes.less +8 -5
- data/vendor/assets/bower_components/bootstrap/less/modals.less +3 -3
- data/vendor/assets/bower_components/bootstrap/less/navbar.less +30 -25
- data/vendor/assets/bower_components/bootstrap/less/navs.less +1 -1
- data/vendor/assets/bower_components/bootstrap/less/normalize.less +12 -13
- data/vendor/assets/bower_components/bootstrap/less/pager.less +1 -2
- data/vendor/assets/bower_components/bootstrap/less/pagination.less +5 -4
- data/vendor/assets/bower_components/bootstrap/less/panels.less +33 -5
- data/vendor/assets/bower_components/bootstrap/less/popovers.less +5 -7
- data/vendor/assets/bower_components/bootstrap/less/print.less +96 -96
- data/vendor/assets/bower_components/bootstrap/less/progress-bars.less +1 -19
- data/vendor/assets/bower_components/bootstrap/less/responsive-embed.less +10 -9
- data/vendor/assets/bower_components/bootstrap/less/scaffolding.less +13 -2
- data/vendor/assets/bower_components/bootstrap/less/tables.less +14 -13
- data/vendor/assets/bower_components/bootstrap/less/theme.less +49 -16
- data/vendor/assets/bower_components/bootstrap/less/thumbnails.less +1 -1
- data/vendor/assets/bower_components/bootstrap/less/tooltip.less +13 -7
- data/vendor/assets/bower_components/bootstrap/less/type.less +2 -13
- data/vendor/assets/bower_components/bootstrap/less/utilities.less +0 -2
- data/vendor/assets/bower_components/bootstrap/less/variables.less +45 -22
- data/vendor/assets/bower_components/bootstrap/nuget/MyGet.ps1 +8 -0
- data/vendor/assets/bower_components/bootstrap/nuget/bootstrap.less.nuspec +28 -0
- data/vendor/assets/bower_components/bootstrap/nuget/bootstrap.nuspec +28 -0
- data/vendor/assets/bower_components/bootstrap/package.js +32 -0
- data/vendor/assets/bower_components/bootstrap/package.json +49 -41
- data/vendor/assets/bower_components/flow.js/README.md +79 -64
- data/vendor/assets/bower_components/flow.js/bower.json +6 -2
- data/vendor/assets/bower_components/flow.js/dist/flow.js +1635 -1532
- data/vendor/assets/bower_components/flow.js/dist/flow.min.js +2 -2
- data/vendor/assets/bower_components/flow.js/package.js +24 -0
- data/vendor/assets/bower_components/flow.js/travis.sh +19 -0
- data/vendor/assets/bower_components/font-awesome/scss/_path.scss +5 -5
- data/vendor/assets/bower_components/font-awesome/scss/_variables.scss +1 -2
- data/vendor/assets/bower_components/ng-flow/bower.json +1 -1
- data/vendor/assets/bower_components/ng-flow/dist/ng-flow-standalone.js +1655 -1542
- data/vendor/assets/bower_components/ng-flow/dist/ng-flow-standalone.min.js +2 -2
- data/vendor/assets/bower_components/ng-flow/dist/ng-flow.js +19 -9
- data/vendor/assets/bower_components/ng-flow/dist/ng-flow.min.js +2 -2
- data/vendor/assets/bower_components/ng-flow/index.js +3 -0
- data/vendor/assets/bower_components/ng-flow/package.js +25 -0
- data/vendor/assets/bower_components/ng-flow/src/directives/drag-events.js +2 -1
- data/vendor/assets/bower_components/ng-flow/src/directives/events.js +2 -1
- data/vendor/assets/bower_components/ng-flow/src/directives/init.js +7 -1
- data/vendor/assets/bower_components/ng-flow/travis.sh +19 -0
- data/vendor/assets/bower_components/{Responsive-Dashboard → rdash-ui}/LICENSE +21 -21
- data/vendor/assets/bower_components/rdash-ui/README.md +55 -0
- data/vendor/assets/bower_components/rdash-ui/bower.json +33 -0
- data/vendor/assets/bower_components/rdash-ui/dist/css/rdash.min.css +1 -0
- data/vendor/assets/bower_components/rdash-ui/dist/css/rdash.scss +489 -0
- data/vendor/assets/bower_components/{Responsive-Dashboard/src → rdash-ui/dist}/fonts/montserrat-regular-webfont.eot +0 -0
- data/vendor/assets/bower_components/{Responsive-Dashboard/src → rdash-ui/dist}/fonts/montserrat-regular-webfont.svg +1316 -1316
- data/vendor/assets/bower_components/{Responsive-Dashboard/src → rdash-ui/dist}/fonts/montserrat-regular-webfont.ttf +0 -0
- data/vendor/assets/bower_components/{Responsive-Dashboard/src → rdash-ui/dist}/fonts/montserrat-regular-webfont.woff +0 -0
- metadata +227 -180
- data/config/initializers/bower_rails.rb +0 -16
- data/vendor/assets/bower_components/Responsive-Dashboard/CONTRIBUTING.md +0 -21
- data/vendor/assets/bower_components/Responsive-Dashboard/README.md +0 -119
- data/vendor/assets/bower_components/Responsive-Dashboard/bower.json +0 -32
- data/vendor/assets/bower_components/Responsive-Dashboard/gulpfile.js +0 -81
- data/vendor/assets/bower_components/Responsive-Dashboard/package.json +0 -21
- data/vendor/assets/bower_components/Responsive-Dashboard/src/index.html +0 -413
- data/vendor/assets/bower_components/Responsive-Dashboard/src/js/dashboard/controllers/alerts-ctrl.js +0 -19
- data/vendor/assets/bower_components/Responsive-Dashboard/src/js/dashboard/controllers/master-ctrl.js +0 -51
- data/vendor/assets/bower_components/Responsive-Dashboard/src/js/dashboard/directives/loading.js +0 -13
- data/vendor/assets/bower_components/Responsive-Dashboard/src/js/dashboard/directives/widget-body.js +0 -16
- data/vendor/assets/bower_components/Responsive-Dashboard/src/js/dashboard/directives/widget-header.js +0 -17
- data/vendor/assets/bower_components/Responsive-Dashboard/src/js/dashboard/directives/widget.js +0 -16
- data/vendor/assets/bower_components/Responsive-Dashboard/src/js/dashboard/module.js +0 -1
- data/vendor/assets/bower_components/Responsive-Dashboard/src/js/dashboard/routes.js +0 -22
- data/vendor/assets/bower_components/Responsive-Dashboard/src/less/dashboard/content.less +0 -19
- data/vendor/assets/bower_components/Responsive-Dashboard/src/less/dashboard/hamburg.less +0 -29
- data/vendor/assets/bower_components/Responsive-Dashboard/src/less/dashboard/header.less +0 -92
- data/vendor/assets/bower_components/Responsive-Dashboard/src/less/dashboard/loading.less +0 -40
- data/vendor/assets/bower_components/Responsive-Dashboard/src/less/dashboard/main.less +0 -73
- data/vendor/assets/bower_components/Responsive-Dashboard/src/less/dashboard/mixins.less +0 -5
- data/vendor/assets/bower_components/Responsive-Dashboard/src/less/dashboard/sidebar.less +0 -122
- data/vendor/assets/bower_components/Responsive-Dashboard/src/less/dashboard/variables.less +0 -10
- data/vendor/assets/bower_components/Responsive-Dashboard/src/less/dashboard/widgets.less +0 -95
- data/vendor/assets/bower_components/bootstrap/dist/css/bootstrap.min.css.erb +0 -5
- data/vendor/assets/bower_components/flow.js/CHANGELOG.md +0 -37
- data/vendor/assets/bower_components/flow.js/Gruntfile.js +0 -132
- data/vendor/assets/bower_components/flow.js/karma.conf.js +0 -114
- data/vendor/assets/bower_components/flow.js/package.json +0 -50
- data/vendor/assets/bower_components/flow.js/src/flow.js +0 -1532
- data/vendor/assets/bower_components/jquery/MIT-LICENSE.txt +0 -21
- data/vendor/assets/bower_components/jquery/bower.json +0 -27
- data/vendor/assets/bower_components/jquery/dist/jquery.js +0 -9190
- data/vendor/assets/bower_components/jquery/dist/jquery.min.js +0 -5
- data/vendor/assets/bower_components/jquery/dist/jquery.min.map +0 -1
- data/vendor/assets/bower_components/jquery/src/ajax.js +0 -806
- data/vendor/assets/bower_components/jquery/src/ajax/jsonp.js +0 -89
- data/vendor/assets/bower_components/jquery/src/ajax/load.js +0 -75
- data/vendor/assets/bower_components/jquery/src/ajax/parseJSON.js +0 -13
- data/vendor/assets/bower_components/jquery/src/ajax/parseXML.js +0 -28
- data/vendor/assets/bower_components/jquery/src/ajax/script.js +0 -64
- data/vendor/assets/bower_components/jquery/src/ajax/var/nonce.js +0 -5
- data/vendor/assets/bower_components/jquery/src/ajax/var/rquery.js +0 -3
- data/vendor/assets/bower_components/jquery/src/ajax/xhr.js +0 -135
- data/vendor/assets/bower_components/jquery/src/attributes.js +0 -11
- data/vendor/assets/bower_components/jquery/src/attributes/attr.js +0 -143
- data/vendor/assets/bower_components/jquery/src/attributes/classes.js +0 -158
- data/vendor/assets/bower_components/jquery/src/attributes/prop.js +0 -96
- data/vendor/assets/bower_components/jquery/src/attributes/support.js +0 -35
- data/vendor/assets/bower_components/jquery/src/attributes/val.js +0 -163
- data/vendor/assets/bower_components/jquery/src/callbacks.js +0 -205
- data/vendor/assets/bower_components/jquery/src/core.js +0 -498
- data/vendor/assets/bower_components/jquery/src/core/access.js +0 -60
- data/vendor/assets/bower_components/jquery/src/core/init.js +0 -123
- data/vendor/assets/bower_components/jquery/src/core/parseHTML.js +0 -39
- data/vendor/assets/bower_components/jquery/src/core/ready.js +0 -97
- data/vendor/assets/bower_components/jquery/src/core/var/rsingleTag.js +0 -4
- data/vendor/assets/bower_components/jquery/src/css.js +0 -451
- data/vendor/assets/bower_components/jquery/src/css/addGetHookIf.js +0 -24
- data/vendor/assets/bower_components/jquery/src/css/curCSS.js +0 -57
- data/vendor/assets/bower_components/jquery/src/css/defaultDisplay.js +0 -70
- data/vendor/assets/bower_components/jquery/src/css/hiddenVisibleSelectors.js +0 -15
- data/vendor/assets/bower_components/jquery/src/css/support.js +0 -91
- data/vendor/assets/bower_components/jquery/src/css/swap.js +0 -28
- data/vendor/assets/bower_components/jquery/src/css/var/cssExpand.js +0 -3
- data/vendor/assets/bower_components/jquery/src/css/var/getStyles.js +0 -5
- data/vendor/assets/bower_components/jquery/src/css/var/isHidden.js +0 -13
- data/vendor/assets/bower_components/jquery/src/css/var/rmargin.js +0 -3
- data/vendor/assets/bower_components/jquery/src/css/var/rnumnonpx.js +0 -5
- data/vendor/assets/bower_components/jquery/src/data.js +0 -179
- data/vendor/assets/bower_components/jquery/src/data/Data.js +0 -181
- data/vendor/assets/bower_components/jquery/src/data/accepts.js +0 -20
- data/vendor/assets/bower_components/jquery/src/data/var/data_priv.js +0 -5
- data/vendor/assets/bower_components/jquery/src/data/var/data_user.js +0 -5
- data/vendor/assets/bower_components/jquery/src/deferred.js +0 -149
- data/vendor/assets/bower_components/jquery/src/deprecated.js +0 -13
- data/vendor/assets/bower_components/jquery/src/dimensions.js +0 -50
- data/vendor/assets/bower_components/jquery/src/effects.js +0 -649
- data/vendor/assets/bower_components/jquery/src/effects/Tween.js +0 -114
- data/vendor/assets/bower_components/jquery/src/effects/animatedSelector.js +0 -13
- data/vendor/assets/bower_components/jquery/src/event.js +0 -868
- data/vendor/assets/bower_components/jquery/src/event/alias.js +0 -39
- data/vendor/assets/bower_components/jquery/src/event/support.js +0 -9
- data/vendor/assets/bower_components/jquery/src/exports/amd.js +0 -24
- data/vendor/assets/bower_components/jquery/src/exports/global.js +0 -32
- data/vendor/assets/bower_components/jquery/src/intro.js +0 -44
- data/vendor/assets/bower_components/jquery/src/jquery.js +0 -36
- data/vendor/assets/bower_components/jquery/src/manipulation.js +0 -582
- data/vendor/assets/bower_components/jquery/src/manipulation/_evalUrl.js +0 -18
- data/vendor/assets/bower_components/jquery/src/manipulation/support.js +0 -31
- data/vendor/assets/bower_components/jquery/src/manipulation/var/rcheckableType.js +0 -3
- data/vendor/assets/bower_components/jquery/src/offset.js +0 -204
- data/vendor/assets/bower_components/jquery/src/outro.js +0 -1
- data/vendor/assets/bower_components/jquery/src/queue.js +0 -142
- data/vendor/assets/bower_components/jquery/src/queue/delay.js +0 -22
- data/vendor/assets/bower_components/jquery/src/selector-native.js +0 -172
- data/vendor/assets/bower_components/jquery/src/selector-sizzle.js +0 -14
- data/vendor/assets/bower_components/jquery/src/selector.js +0 -1
- data/vendor/assets/bower_components/jquery/src/serialize.js +0 -111
- data/vendor/assets/bower_components/jquery/src/sizzle/dist/sizzle.js +0 -2044
- data/vendor/assets/bower_components/jquery/src/sizzle/dist/sizzle.min.js +0 -3
- data/vendor/assets/bower_components/jquery/src/sizzle/dist/sizzle.min.map +0 -1
- data/vendor/assets/bower_components/jquery/src/traversing.js +0 -200
- data/vendor/assets/bower_components/jquery/src/traversing/findFilter.js +0 -100
- data/vendor/assets/bower_components/jquery/src/traversing/var/rneedsContext.js +0 -6
- data/vendor/assets/bower_components/jquery/src/var/arr.js +0 -3
- data/vendor/assets/bower_components/jquery/src/var/class2type.js +0 -4
- data/vendor/assets/bower_components/jquery/src/var/concat.js +0 -5
- data/vendor/assets/bower_components/jquery/src/var/hasOwn.js +0 -5
- data/vendor/assets/bower_components/jquery/src/var/indexOf.js +0 -5
- data/vendor/assets/bower_components/jquery/src/var/pnum.js +0 -3
- data/vendor/assets/bower_components/jquery/src/var/push.js +0 -5
- data/vendor/assets/bower_components/jquery/src/var/rnotwhite.js +0 -3
- data/vendor/assets/bower_components/jquery/src/var/slice.js +0 -5
- data/vendor/assets/bower_components/jquery/src/var/strundefined.js +0 -3
- data/vendor/assets/bower_components/jquery/src/var/support.js +0 -4
- data/vendor/assets/bower_components/jquery/src/var/toString.js +0 -5
- data/vendor/assets/bower_components/jquery/src/wrap.js +0 -78
|
@@ -1,1532 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license MIT
|
|
3
|
-
*/
|
|
4
|
-
(function(window, document, undefined) {'use strict';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Flow.js is a library providing multiple simultaneous, stable and
|
|
8
|
-
* resumable uploads via the HTML5 File API.
|
|
9
|
-
* @param [opts]
|
|
10
|
-
* @param {number} [opts.chunkSize]
|
|
11
|
-
* @param {bool} [opts.forceChunkSize]
|
|
12
|
-
* @param {number} [opts.simultaneousUploads]
|
|
13
|
-
* @param {bool} [opts.singleFile]
|
|
14
|
-
* @param {string} [opts.fileParameterName]
|
|
15
|
-
* @param {number} [opts.progressCallbacksInterval]
|
|
16
|
-
* @param {number} [opts.speedSmoothingFactor]
|
|
17
|
-
* @param {Object|Function} [opts.query]
|
|
18
|
-
* @param {Object|Function} [opts.headers]
|
|
19
|
-
* @param {bool} [opts.withCredentials]
|
|
20
|
-
* @param {Function} [opts.preprocess]
|
|
21
|
-
* @param {string} [opts.method]
|
|
22
|
-
* @param {bool} [opts.prioritizeFirstAndLastChunk]
|
|
23
|
-
* @param {string|Function} [opts.target]
|
|
24
|
-
* @param {number} [opts.maxChunkRetries]
|
|
25
|
-
* @param {number} [opts.chunkRetryInterval]
|
|
26
|
-
* @param {Array.<number>} [opts.permanentErrors]
|
|
27
|
-
* @param {Function} [opts.generateUniqueIdentifier]
|
|
28
|
-
* @constructor
|
|
29
|
-
*/
|
|
30
|
-
function Flow(opts) {
|
|
31
|
-
/**
|
|
32
|
-
* Supported by browser?
|
|
33
|
-
* @type {boolean}
|
|
34
|
-
*/
|
|
35
|
-
this.support = (
|
|
36
|
-
typeof File !== 'undefined' &&
|
|
37
|
-
typeof Blob !== 'undefined' &&
|
|
38
|
-
typeof FileList !== 'undefined' &&
|
|
39
|
-
(
|
|
40
|
-
!!Blob.prototype.slice || !!Blob.prototype.webkitSlice || !!Blob.prototype.mozSlice ||
|
|
41
|
-
false
|
|
42
|
-
) // slicing files support
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
if (!this.support) {
|
|
46
|
-
return ;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Check if directory upload is supported
|
|
51
|
-
* @type {boolean}
|
|
52
|
-
*/
|
|
53
|
-
this.supportDirectory = /WebKit/.test(window.navigator.userAgent);
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* List of FlowFile objects
|
|
57
|
-
* @type {Array.<FlowFile>}
|
|
58
|
-
*/
|
|
59
|
-
this.files = [];
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Default options for flow.js
|
|
63
|
-
* @type {Object}
|
|
64
|
-
*/
|
|
65
|
-
this.defaults = {
|
|
66
|
-
chunkSize: 1024 * 1024,
|
|
67
|
-
forceChunkSize: false,
|
|
68
|
-
simultaneousUploads: 3,
|
|
69
|
-
singleFile: false,
|
|
70
|
-
fileParameterName: 'file',
|
|
71
|
-
progressCallbacksInterval: 500,
|
|
72
|
-
speedSmoothingFactor: 0.1,
|
|
73
|
-
query: {},
|
|
74
|
-
headers: {},
|
|
75
|
-
withCredentials: false,
|
|
76
|
-
preprocess: null,
|
|
77
|
-
method: 'multipart',
|
|
78
|
-
prioritizeFirstAndLastChunk: false,
|
|
79
|
-
target: '/',
|
|
80
|
-
testChunks: true,
|
|
81
|
-
generateUniqueIdentifier: null,
|
|
82
|
-
maxChunkRetries: 0,
|
|
83
|
-
chunkRetryInterval: null,
|
|
84
|
-
permanentErrors: [404, 415, 500, 501],
|
|
85
|
-
onDropStopPropagation: false
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Current options
|
|
90
|
-
* @type {Object}
|
|
91
|
-
*/
|
|
92
|
-
this.opts = {};
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* List of events:
|
|
96
|
-
* key stands for event name
|
|
97
|
-
* value array list of callbacks
|
|
98
|
-
* @type {}
|
|
99
|
-
*/
|
|
100
|
-
this.events = {};
|
|
101
|
-
|
|
102
|
-
var $ = this;
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* On drop event
|
|
106
|
-
* @function
|
|
107
|
-
* @param {MouseEvent} event
|
|
108
|
-
*/
|
|
109
|
-
this.onDrop = function (event) {
|
|
110
|
-
if ($.opts.onDropStopPropagation) {
|
|
111
|
-
event.stopPropagation();
|
|
112
|
-
}
|
|
113
|
-
event.preventDefault();
|
|
114
|
-
var dataTransfer = event.dataTransfer;
|
|
115
|
-
if (dataTransfer.items && dataTransfer.items[0] &&
|
|
116
|
-
dataTransfer.items[0].webkitGetAsEntry) {
|
|
117
|
-
$.webkitReadDataTransfer(event);
|
|
118
|
-
} else {
|
|
119
|
-
$.addFiles(dataTransfer.files, event);
|
|
120
|
-
}
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Prevent default
|
|
125
|
-
* @function
|
|
126
|
-
* @param {MouseEvent} event
|
|
127
|
-
*/
|
|
128
|
-
this.preventEvent = function (event) {
|
|
129
|
-
event.preventDefault();
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Current options
|
|
135
|
-
* @type {Object}
|
|
136
|
-
*/
|
|
137
|
-
this.opts = Flow.extend({}, this.defaults, opts || {});
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
Flow.prototype = {
|
|
141
|
-
/**
|
|
142
|
-
* Set a callback for an event, possible events:
|
|
143
|
-
* fileSuccess(file), fileProgress(file), fileAdded(file, event),
|
|
144
|
-
* fileRetry(file), fileError(file, message), complete(),
|
|
145
|
-
* progress(), error(message, file), pause()
|
|
146
|
-
* @function
|
|
147
|
-
* @param {string} event
|
|
148
|
-
* @param {Function} callback
|
|
149
|
-
*/
|
|
150
|
-
on: function (event, callback) {
|
|
151
|
-
event = event.toLowerCase();
|
|
152
|
-
if (!this.events.hasOwnProperty(event)) {
|
|
153
|
-
this.events[event] = [];
|
|
154
|
-
}
|
|
155
|
-
this.events[event].push(callback);
|
|
156
|
-
},
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Remove event callback
|
|
160
|
-
* @function
|
|
161
|
-
* @param {string} [event] removes all events if not specified
|
|
162
|
-
* @param {Function} [fn] removes all callbacks of event if not specified
|
|
163
|
-
*/
|
|
164
|
-
off: function (event, fn) {
|
|
165
|
-
if (event !== undefined) {
|
|
166
|
-
event = event.toLowerCase();
|
|
167
|
-
if (fn !== undefined) {
|
|
168
|
-
if (this.events.hasOwnProperty(event)) {
|
|
169
|
-
arrayRemove(this.events[event], fn);
|
|
170
|
-
}
|
|
171
|
-
} else {
|
|
172
|
-
delete this.events[event];
|
|
173
|
-
}
|
|
174
|
-
} else {
|
|
175
|
-
this.events = {};
|
|
176
|
-
}
|
|
177
|
-
},
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Fire an event
|
|
181
|
-
* @function
|
|
182
|
-
* @param {string} event event name
|
|
183
|
-
* @param {...} args arguments of a callback
|
|
184
|
-
* @return {bool} value is false if at least one of the event handlers which handled this event
|
|
185
|
-
* returned false. Otherwise it returns true.
|
|
186
|
-
*/
|
|
187
|
-
fire: function (event, args) {
|
|
188
|
-
// `arguments` is an object, not array, in FF, so:
|
|
189
|
-
args = Array.prototype.slice.call(arguments);
|
|
190
|
-
event = event.toLowerCase();
|
|
191
|
-
var preventDefault = false;
|
|
192
|
-
if (this.events.hasOwnProperty(event)) {
|
|
193
|
-
each(this.events[event], function (callback) {
|
|
194
|
-
preventDefault = callback.apply(this, args.slice(1)) === false || preventDefault;
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
if (event != 'catchall') {
|
|
198
|
-
args.unshift('catchAll');
|
|
199
|
-
preventDefault = this.fire.apply(this, args) === false || preventDefault;
|
|
200
|
-
}
|
|
201
|
-
return !preventDefault;
|
|
202
|
-
},
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Read webkit dataTransfer object
|
|
206
|
-
* @param event
|
|
207
|
-
*/
|
|
208
|
-
webkitReadDataTransfer: function (event) {
|
|
209
|
-
var $ = this;
|
|
210
|
-
var queue = event.dataTransfer.items.length;
|
|
211
|
-
var files = [];
|
|
212
|
-
each(event.dataTransfer.items, function (item) {
|
|
213
|
-
var entry = item.webkitGetAsEntry();
|
|
214
|
-
if (!entry) {
|
|
215
|
-
decrement();
|
|
216
|
-
return ;
|
|
217
|
-
}
|
|
218
|
-
if (entry.isFile) {
|
|
219
|
-
// due to a bug in Chrome's File System API impl - #149735
|
|
220
|
-
fileReadSuccess(item.getAsFile(), entry.fullPath);
|
|
221
|
-
} else {
|
|
222
|
-
entry.createReader().readEntries(readSuccess, readError);
|
|
223
|
-
}
|
|
224
|
-
});
|
|
225
|
-
function readSuccess(entries) {
|
|
226
|
-
queue += entries.length;
|
|
227
|
-
each(entries, function(entry) {
|
|
228
|
-
if (entry.isFile) {
|
|
229
|
-
var fullPath = entry.fullPath;
|
|
230
|
-
entry.file(function (file) {
|
|
231
|
-
fileReadSuccess(file, fullPath);
|
|
232
|
-
}, readError);
|
|
233
|
-
} else if (entry.isDirectory) {
|
|
234
|
-
entry.createReader().readEntries(readSuccess, readError);
|
|
235
|
-
}
|
|
236
|
-
});
|
|
237
|
-
decrement();
|
|
238
|
-
}
|
|
239
|
-
function fileReadSuccess(file, fullPath) {
|
|
240
|
-
// relative path should not start with "/"
|
|
241
|
-
file.relativePath = fullPath.substring(1);
|
|
242
|
-
files.push(file);
|
|
243
|
-
decrement();
|
|
244
|
-
}
|
|
245
|
-
function readError(fileError) {
|
|
246
|
-
throw fileError;
|
|
247
|
-
}
|
|
248
|
-
function decrement() {
|
|
249
|
-
if (--queue == 0) {
|
|
250
|
-
$.addFiles(files, event);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
},
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Generate unique identifier for a file
|
|
257
|
-
* @function
|
|
258
|
-
* @param {FlowFile} file
|
|
259
|
-
* @returns {string}
|
|
260
|
-
*/
|
|
261
|
-
generateUniqueIdentifier: function (file) {
|
|
262
|
-
var custom = this.opts.generateUniqueIdentifier;
|
|
263
|
-
if (typeof custom === 'function') {
|
|
264
|
-
return custom(file);
|
|
265
|
-
}
|
|
266
|
-
// Some confusion in different versions of Firefox
|
|
267
|
-
var relativePath = file.relativePath || file.webkitRelativePath || file.fileName || file.name;
|
|
268
|
-
return file.size + '-' + relativePath.replace(/[^0-9a-zA-Z_-]/img, '');
|
|
269
|
-
},
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* Upload next chunk from the queue
|
|
273
|
-
* @function
|
|
274
|
-
* @returns {boolean}
|
|
275
|
-
* @private
|
|
276
|
-
*/
|
|
277
|
-
uploadNextChunk: function (preventEvents) {
|
|
278
|
-
// In some cases (such as videos) it's really handy to upload the first
|
|
279
|
-
// and last chunk of a file quickly; this let's the server check the file's
|
|
280
|
-
// metadata and determine if there's even a point in continuing.
|
|
281
|
-
var found = false;
|
|
282
|
-
if (this.opts.prioritizeFirstAndLastChunk) {
|
|
283
|
-
each(this.files, function (file) {
|
|
284
|
-
if (!file.paused && file.chunks.length &&
|
|
285
|
-
file.chunks[0].status() === 'pending' &&
|
|
286
|
-
file.chunks[0].preprocessState === 0) {
|
|
287
|
-
file.chunks[0].send();
|
|
288
|
-
found = true;
|
|
289
|
-
return false;
|
|
290
|
-
}
|
|
291
|
-
if (!file.paused && file.chunks.length > 1 &&
|
|
292
|
-
file.chunks[file.chunks.length - 1].status() === 'pending' &&
|
|
293
|
-
file.chunks[0].preprocessState === 0) {
|
|
294
|
-
file.chunks[file.chunks.length - 1].send();
|
|
295
|
-
found = true;
|
|
296
|
-
return false;
|
|
297
|
-
}
|
|
298
|
-
});
|
|
299
|
-
if (found) {
|
|
300
|
-
return found;
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
// Now, simply look for the next, best thing to upload
|
|
305
|
-
each(this.files, function (file) {
|
|
306
|
-
if (!file.paused) {
|
|
307
|
-
each(file.chunks, function (chunk) {
|
|
308
|
-
if (chunk.status() === 'pending' && chunk.preprocessState === 0) {
|
|
309
|
-
chunk.send();
|
|
310
|
-
found = true;
|
|
311
|
-
return false;
|
|
312
|
-
}
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
if (found) {
|
|
316
|
-
return false;
|
|
317
|
-
}
|
|
318
|
-
});
|
|
319
|
-
if (found) {
|
|
320
|
-
return true;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
// The are no more outstanding chunks to upload, check is everything is done
|
|
324
|
-
var outstanding = false;
|
|
325
|
-
each(this.files, function (file) {
|
|
326
|
-
if (!file.isComplete()) {
|
|
327
|
-
outstanding = true;
|
|
328
|
-
return false;
|
|
329
|
-
}
|
|
330
|
-
});
|
|
331
|
-
if (!outstanding && !preventEvents) {
|
|
332
|
-
// All chunks have been uploaded, complete
|
|
333
|
-
async(function () {
|
|
334
|
-
this.fire('complete');
|
|
335
|
-
}, this);
|
|
336
|
-
}
|
|
337
|
-
return false;
|
|
338
|
-
},
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
/**
|
|
342
|
-
* Assign a browse action to one or more DOM nodes.
|
|
343
|
-
* @function
|
|
344
|
-
* @param {Element|Array.<Element>} domNodes
|
|
345
|
-
* @param {boolean} isDirectory Pass in true to allow directories to
|
|
346
|
-
* @param {boolean} singleFile prevent multi file upload
|
|
347
|
-
* @param {Object} attributes set custom attributes:
|
|
348
|
-
* http://www.w3.org/TR/html-markup/input.file.html#input.file-attributes
|
|
349
|
-
* eg: accept: 'image/*'
|
|
350
|
-
* be selected (Chrome only).
|
|
351
|
-
*/
|
|
352
|
-
assignBrowse: function (domNodes, isDirectory, singleFile, attributes) {
|
|
353
|
-
if (typeof domNodes.length === 'undefined') {
|
|
354
|
-
domNodes = [domNodes];
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
each(domNodes, function (domNode) {
|
|
358
|
-
var input;
|
|
359
|
-
if (domNode.tagName === 'INPUT' && domNode.type === 'file') {
|
|
360
|
-
input = domNode;
|
|
361
|
-
} else {
|
|
362
|
-
input = document.createElement('input');
|
|
363
|
-
input.setAttribute('type', 'file');
|
|
364
|
-
// display:none - not working in opera 12
|
|
365
|
-
extend(input.style, {
|
|
366
|
-
visibility: 'hidden',
|
|
367
|
-
position: 'absolute'
|
|
368
|
-
});
|
|
369
|
-
// for opera 12 browser, input must be assigned to a document
|
|
370
|
-
domNode.appendChild(input);
|
|
371
|
-
// https://developer.mozilla.org/en/using_files_from_web_applications)
|
|
372
|
-
// event listener is executed two times
|
|
373
|
-
// first one - original mouse click event
|
|
374
|
-
// second - input.click(), input is inside domNode
|
|
375
|
-
domNode.addEventListener('click', function() {
|
|
376
|
-
input.click();
|
|
377
|
-
}, false);
|
|
378
|
-
}
|
|
379
|
-
if (!this.opts.singleFile && !singleFile) {
|
|
380
|
-
input.setAttribute('multiple', 'multiple');
|
|
381
|
-
}
|
|
382
|
-
if (isDirectory) {
|
|
383
|
-
input.setAttribute('webkitdirectory', 'webkitdirectory');
|
|
384
|
-
}
|
|
385
|
-
each(attributes, function (value, key) {
|
|
386
|
-
input.setAttribute(key, value);
|
|
387
|
-
});
|
|
388
|
-
// When new files are added, simply append them to the overall list
|
|
389
|
-
var $ = this;
|
|
390
|
-
input.addEventListener('change', function (e) {
|
|
391
|
-
$.addFiles(e.target.files, e);
|
|
392
|
-
e.target.value = '';
|
|
393
|
-
}, false);
|
|
394
|
-
}, this);
|
|
395
|
-
},
|
|
396
|
-
|
|
397
|
-
/**
|
|
398
|
-
* Assign one or more DOM nodes as a drop target.
|
|
399
|
-
* @function
|
|
400
|
-
* @param {Element|Array.<Element>} domNodes
|
|
401
|
-
*/
|
|
402
|
-
assignDrop: function (domNodes) {
|
|
403
|
-
if (typeof domNodes.length === 'undefined') {
|
|
404
|
-
domNodes = [domNodes];
|
|
405
|
-
}
|
|
406
|
-
each(domNodes, function (domNode) {
|
|
407
|
-
domNode.addEventListener('dragover', this.preventEvent, false);
|
|
408
|
-
domNode.addEventListener('dragenter', this.preventEvent, false);
|
|
409
|
-
domNode.addEventListener('drop', this.onDrop, false);
|
|
410
|
-
}, this);
|
|
411
|
-
},
|
|
412
|
-
|
|
413
|
-
/**
|
|
414
|
-
* Un-assign drop event from DOM nodes
|
|
415
|
-
* @function
|
|
416
|
-
* @param domNodes
|
|
417
|
-
*/
|
|
418
|
-
unAssignDrop: function (domNodes) {
|
|
419
|
-
if (typeof domNodes.length === 'undefined') {
|
|
420
|
-
domNodes = [domNodes];
|
|
421
|
-
}
|
|
422
|
-
each(domNodes, function (domNode) {
|
|
423
|
-
domNode.removeEventListener('dragover', this.preventEvent);
|
|
424
|
-
domNode.removeEventListener('dragenter', this.preventEvent);
|
|
425
|
-
domNode.removeEventListener('drop', this.onDrop);
|
|
426
|
-
}, this);
|
|
427
|
-
},
|
|
428
|
-
|
|
429
|
-
/**
|
|
430
|
-
* Returns a boolean indicating whether or not the instance is currently
|
|
431
|
-
* uploading anything.
|
|
432
|
-
* @function
|
|
433
|
-
* @returns {boolean}
|
|
434
|
-
*/
|
|
435
|
-
isUploading: function () {
|
|
436
|
-
var uploading = false;
|
|
437
|
-
each(this.files, function (file) {
|
|
438
|
-
if (file.isUploading()) {
|
|
439
|
-
uploading = true;
|
|
440
|
-
return false;
|
|
441
|
-
}
|
|
442
|
-
});
|
|
443
|
-
return uploading;
|
|
444
|
-
},
|
|
445
|
-
|
|
446
|
-
/**
|
|
447
|
-
* should upload next chunk
|
|
448
|
-
* @function
|
|
449
|
-
* @returns {boolean|number}
|
|
450
|
-
*/
|
|
451
|
-
_shouldUploadNext: function () {
|
|
452
|
-
var num = 0;
|
|
453
|
-
var should = true;
|
|
454
|
-
var simultaneousUploads = this.opts.simultaneousUploads;
|
|
455
|
-
each(this.files, function (file) {
|
|
456
|
-
each(file.chunks, function(chunk) {
|
|
457
|
-
if (chunk.status() === 'uploading') {
|
|
458
|
-
num++;
|
|
459
|
-
if (num >= simultaneousUploads) {
|
|
460
|
-
should = false;
|
|
461
|
-
return false;
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
});
|
|
465
|
-
});
|
|
466
|
-
// if should is true then return uploading chunks's length
|
|
467
|
-
return should && num;
|
|
468
|
-
},
|
|
469
|
-
|
|
470
|
-
/**
|
|
471
|
-
* Start or resume uploading.
|
|
472
|
-
* @function
|
|
473
|
-
*/
|
|
474
|
-
upload: function () {
|
|
475
|
-
// Make sure we don't start too many uploads at once
|
|
476
|
-
var ret = this._shouldUploadNext();
|
|
477
|
-
if (ret === false) {
|
|
478
|
-
return;
|
|
479
|
-
}
|
|
480
|
-
// Kick off the queue
|
|
481
|
-
this.fire('uploadStart');
|
|
482
|
-
var started = false;
|
|
483
|
-
for (var num = 1; num <= this.opts.simultaneousUploads - ret; num++) {
|
|
484
|
-
started = this.uploadNextChunk(true) || started;
|
|
485
|
-
}
|
|
486
|
-
if (!started) {
|
|
487
|
-
async(function () {
|
|
488
|
-
this.fire('complete');
|
|
489
|
-
}, this);
|
|
490
|
-
}
|
|
491
|
-
},
|
|
492
|
-
|
|
493
|
-
/**
|
|
494
|
-
* Resume uploading.
|
|
495
|
-
* @function
|
|
496
|
-
*/
|
|
497
|
-
resume: function () {
|
|
498
|
-
each(this.files, function (file) {
|
|
499
|
-
file.resume();
|
|
500
|
-
});
|
|
501
|
-
},
|
|
502
|
-
|
|
503
|
-
/**
|
|
504
|
-
* Pause uploading.
|
|
505
|
-
* @function
|
|
506
|
-
*/
|
|
507
|
-
pause: function () {
|
|
508
|
-
each(this.files, function (file) {
|
|
509
|
-
file.pause();
|
|
510
|
-
});
|
|
511
|
-
},
|
|
512
|
-
|
|
513
|
-
/**
|
|
514
|
-
* Cancel upload of all FlowFile objects and remove them from the list.
|
|
515
|
-
* @function
|
|
516
|
-
*/
|
|
517
|
-
cancel: function () {
|
|
518
|
-
for (var i = this.files.length - 1; i >= 0; i--) {
|
|
519
|
-
this.files[i].cancel();
|
|
520
|
-
}
|
|
521
|
-
},
|
|
522
|
-
|
|
523
|
-
/**
|
|
524
|
-
* Returns a number between 0 and 1 indicating the current upload progress
|
|
525
|
-
* of all files.
|
|
526
|
-
* @function
|
|
527
|
-
* @returns {number}
|
|
528
|
-
*/
|
|
529
|
-
progress: function () {
|
|
530
|
-
var totalDone = 0;
|
|
531
|
-
var totalSize = 0;
|
|
532
|
-
// Resume all chunks currently being uploaded
|
|
533
|
-
each(this.files, function (file) {
|
|
534
|
-
totalDone += file.progress() * file.size;
|
|
535
|
-
totalSize += file.size;
|
|
536
|
-
});
|
|
537
|
-
return totalSize > 0 ? totalDone / totalSize : 0;
|
|
538
|
-
},
|
|
539
|
-
|
|
540
|
-
/**
|
|
541
|
-
* Add a HTML5 File object to the list of files.
|
|
542
|
-
* @function
|
|
543
|
-
* @param {File} file
|
|
544
|
-
* @param {Event} [event] event is optional
|
|
545
|
-
*/
|
|
546
|
-
addFile: function (file, event) {
|
|
547
|
-
this.addFiles([file], event);
|
|
548
|
-
},
|
|
549
|
-
|
|
550
|
-
/**
|
|
551
|
-
* Add a HTML5 File object to the list of files.
|
|
552
|
-
* @function
|
|
553
|
-
* @param {FileList|Array} fileList
|
|
554
|
-
* @param {Event} [event] event is optional
|
|
555
|
-
*/
|
|
556
|
-
addFiles: function (fileList, event) {
|
|
557
|
-
var files = [];
|
|
558
|
-
each(fileList, function (file) {
|
|
559
|
-
// Directories have size `0` and name `.`
|
|
560
|
-
// Ignore already added files
|
|
561
|
-
if (!(file.size % 4096 === 0 && (file.name === '.' || file.fileName === '.')) &&
|
|
562
|
-
!this.getFromUniqueIdentifier(this.generateUniqueIdentifier(file))) {
|
|
563
|
-
var f = new FlowFile(this, file);
|
|
564
|
-
if (this.fire('fileAdded', f, event)) {
|
|
565
|
-
files.push(f);
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
}, this);
|
|
569
|
-
if (this.fire('filesAdded', files, event)) {
|
|
570
|
-
each(files, function (file) {
|
|
571
|
-
if (this.opts.singleFile && this.files.length > 0) {
|
|
572
|
-
this.removeFile(this.files[0]);
|
|
573
|
-
}
|
|
574
|
-
this.files.push(file);
|
|
575
|
-
}, this);
|
|
576
|
-
}
|
|
577
|
-
this.fire('filesSubmitted', files, event);
|
|
578
|
-
},
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
/**
|
|
582
|
-
* Cancel upload of a specific FlowFile object from the list.
|
|
583
|
-
* @function
|
|
584
|
-
* @param {FlowFile} file
|
|
585
|
-
*/
|
|
586
|
-
removeFile: function (file) {
|
|
587
|
-
for (var i = this.files.length - 1; i >= 0; i--) {
|
|
588
|
-
if (this.files[i] === file) {
|
|
589
|
-
this.files.splice(i, 1);
|
|
590
|
-
file.abort();
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
},
|
|
594
|
-
|
|
595
|
-
/**
|
|
596
|
-
* Look up a FlowFile object by its unique identifier.
|
|
597
|
-
* @function
|
|
598
|
-
* @param {string} uniqueIdentifier
|
|
599
|
-
* @returns {boolean|FlowFile} false if file was not found
|
|
600
|
-
*/
|
|
601
|
-
getFromUniqueIdentifier: function (uniqueIdentifier) {
|
|
602
|
-
var ret = false;
|
|
603
|
-
each(this.files, function (file) {
|
|
604
|
-
if (file.uniqueIdentifier === uniqueIdentifier) {
|
|
605
|
-
ret = file;
|
|
606
|
-
}
|
|
607
|
-
});
|
|
608
|
-
return ret;
|
|
609
|
-
},
|
|
610
|
-
|
|
611
|
-
/**
|
|
612
|
-
* Returns the total size of all files in bytes.
|
|
613
|
-
* @function
|
|
614
|
-
* @returns {number}
|
|
615
|
-
*/
|
|
616
|
-
getSize: function () {
|
|
617
|
-
var totalSize = 0;
|
|
618
|
-
each(this.files, function (file) {
|
|
619
|
-
totalSize += file.size;
|
|
620
|
-
});
|
|
621
|
-
return totalSize;
|
|
622
|
-
},
|
|
623
|
-
|
|
624
|
-
/**
|
|
625
|
-
* Returns the total size uploaded of all files in bytes.
|
|
626
|
-
* @function
|
|
627
|
-
* @returns {number}
|
|
628
|
-
*/
|
|
629
|
-
sizeUploaded: function () {
|
|
630
|
-
var size = 0;
|
|
631
|
-
each(this.files, function (file) {
|
|
632
|
-
size += file.sizeUploaded();
|
|
633
|
-
});
|
|
634
|
-
return size;
|
|
635
|
-
},
|
|
636
|
-
|
|
637
|
-
/**
|
|
638
|
-
* Returns remaining time to upload all files in seconds. Accuracy is based on average speed.
|
|
639
|
-
* If speed is zero, time remaining will be equal to positive infinity `Number.POSITIVE_INFINITY`
|
|
640
|
-
* @function
|
|
641
|
-
* @returns {number}
|
|
642
|
-
*/
|
|
643
|
-
timeRemaining: function () {
|
|
644
|
-
var sizeDelta = 0;
|
|
645
|
-
var averageSpeed = 0;
|
|
646
|
-
each(this.files, function (file) {
|
|
647
|
-
if (!file.paused && !file.error) {
|
|
648
|
-
sizeDelta += file.size - file.sizeUploaded();
|
|
649
|
-
averageSpeed += file.averageSpeed;
|
|
650
|
-
}
|
|
651
|
-
});
|
|
652
|
-
if (sizeDelta && !averageSpeed) {
|
|
653
|
-
return Number.POSITIVE_INFINITY;
|
|
654
|
-
}
|
|
655
|
-
if (!sizeDelta && !averageSpeed) {
|
|
656
|
-
return 0;
|
|
657
|
-
}
|
|
658
|
-
return Math.floor(sizeDelta / averageSpeed);
|
|
659
|
-
}
|
|
660
|
-
};
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
/**
|
|
668
|
-
* FlowFile class
|
|
669
|
-
* @name FlowFile
|
|
670
|
-
* @param {Flow} flowObj
|
|
671
|
-
* @param {File} file
|
|
672
|
-
* @constructor
|
|
673
|
-
*/
|
|
674
|
-
function FlowFile(flowObj, file) {
|
|
675
|
-
|
|
676
|
-
/**
|
|
677
|
-
* Reference to parent Flow instance
|
|
678
|
-
* @type {Flow}
|
|
679
|
-
*/
|
|
680
|
-
this.flowObj = flowObj;
|
|
681
|
-
|
|
682
|
-
/**
|
|
683
|
-
* Reference to file
|
|
684
|
-
* @type {File}
|
|
685
|
-
*/
|
|
686
|
-
this.file = file;
|
|
687
|
-
|
|
688
|
-
/**
|
|
689
|
-
* File name. Some confusion in different versions of Firefox
|
|
690
|
-
* @type {string}
|
|
691
|
-
*/
|
|
692
|
-
this.name = file.fileName || file.name;
|
|
693
|
-
|
|
694
|
-
/**
|
|
695
|
-
* File size
|
|
696
|
-
* @type {number}
|
|
697
|
-
*/
|
|
698
|
-
this.size = file.size;
|
|
699
|
-
|
|
700
|
-
/**
|
|
701
|
-
* Relative file path
|
|
702
|
-
* @type {string}
|
|
703
|
-
*/
|
|
704
|
-
this.relativePath = file.relativePath || file.webkitRelativePath || this.name;
|
|
705
|
-
|
|
706
|
-
/**
|
|
707
|
-
* File unique identifier
|
|
708
|
-
* @type {string}
|
|
709
|
-
*/
|
|
710
|
-
this.uniqueIdentifier = flowObj.generateUniqueIdentifier(file);
|
|
711
|
-
|
|
712
|
-
/**
|
|
713
|
-
* List of chunks
|
|
714
|
-
* @type {Array.<FlowChunk>}
|
|
715
|
-
*/
|
|
716
|
-
this.chunks = [];
|
|
717
|
-
|
|
718
|
-
/**
|
|
719
|
-
* Indicated if file is paused
|
|
720
|
-
* @type {boolean}
|
|
721
|
-
*/
|
|
722
|
-
this.paused = false;
|
|
723
|
-
|
|
724
|
-
/**
|
|
725
|
-
* Indicated if file has encountered an error
|
|
726
|
-
* @type {boolean}
|
|
727
|
-
*/
|
|
728
|
-
this.error = false;
|
|
729
|
-
|
|
730
|
-
/**
|
|
731
|
-
* Average upload speed
|
|
732
|
-
* @type {number}
|
|
733
|
-
*/
|
|
734
|
-
this.averageSpeed = 0;
|
|
735
|
-
|
|
736
|
-
/**
|
|
737
|
-
* Current upload speed
|
|
738
|
-
* @type {number}
|
|
739
|
-
*/
|
|
740
|
-
this.currentSpeed = 0;
|
|
741
|
-
|
|
742
|
-
/**
|
|
743
|
-
* Date then progress was called last time
|
|
744
|
-
* @type {number}
|
|
745
|
-
* @private
|
|
746
|
-
*/
|
|
747
|
-
this._lastProgressCallback = Date.now();
|
|
748
|
-
|
|
749
|
-
/**
|
|
750
|
-
* Previously uploaded file size
|
|
751
|
-
* @type {number}
|
|
752
|
-
* @private
|
|
753
|
-
*/
|
|
754
|
-
this._prevUploadedSize = 0;
|
|
755
|
-
|
|
756
|
-
/**
|
|
757
|
-
* Holds previous progress
|
|
758
|
-
* @type {number}
|
|
759
|
-
* @private
|
|
760
|
-
*/
|
|
761
|
-
this._prevProgress = 0;
|
|
762
|
-
|
|
763
|
-
this.bootstrap();
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
FlowFile.prototype = {
|
|
767
|
-
/**
|
|
768
|
-
* Update speed parameters
|
|
769
|
-
* @link http://stackoverflow.com/questions/2779600/how-to-estimate-download-time-remaining-accurately
|
|
770
|
-
* @function
|
|
771
|
-
*/
|
|
772
|
-
measureSpeed: function () {
|
|
773
|
-
var timeSpan = Date.now() - this._lastProgressCallback;
|
|
774
|
-
if (!timeSpan) {
|
|
775
|
-
return ;
|
|
776
|
-
}
|
|
777
|
-
var smoothingFactor = this.flowObj.opts.speedSmoothingFactor;
|
|
778
|
-
var uploaded = this.sizeUploaded();
|
|
779
|
-
// Prevent negative upload speed after file upload resume
|
|
780
|
-
this.currentSpeed = Math.max((uploaded - this._prevUploadedSize) / timeSpan * 1000, 0);
|
|
781
|
-
this.averageSpeed = smoothingFactor * this.currentSpeed + (1 - smoothingFactor) * this.averageSpeed;
|
|
782
|
-
this._prevUploadedSize = uploaded;
|
|
783
|
-
},
|
|
784
|
-
|
|
785
|
-
/**
|
|
786
|
-
* For internal usage only.
|
|
787
|
-
* Callback when something happens within the chunk.
|
|
788
|
-
* @function
|
|
789
|
-
* @param {string} event can be 'progress', 'success', 'error' or 'retry'
|
|
790
|
-
* @param {string} [message]
|
|
791
|
-
*/
|
|
792
|
-
chunkEvent: function (event, message) {
|
|
793
|
-
switch (event) {
|
|
794
|
-
case 'progress':
|
|
795
|
-
if (Date.now() - this._lastProgressCallback <
|
|
796
|
-
this.flowObj.opts.progressCallbacksInterval) {
|
|
797
|
-
break;
|
|
798
|
-
}
|
|
799
|
-
this.measureSpeed();
|
|
800
|
-
this.flowObj.fire('fileProgress', this);
|
|
801
|
-
this.flowObj.fire('progress');
|
|
802
|
-
this._lastProgressCallback = Date.now();
|
|
803
|
-
break;
|
|
804
|
-
case 'error':
|
|
805
|
-
this.error = true;
|
|
806
|
-
this.abort(true);
|
|
807
|
-
this.flowObj.fire('fileError', this, message);
|
|
808
|
-
this.flowObj.fire('error', message, this);
|
|
809
|
-
break;
|
|
810
|
-
case 'success':
|
|
811
|
-
if (this.error) {
|
|
812
|
-
return;
|
|
813
|
-
}
|
|
814
|
-
this.measureSpeed();
|
|
815
|
-
this.flowObj.fire('fileProgress', this);
|
|
816
|
-
this.flowObj.fire('progress');
|
|
817
|
-
this._lastProgressCallback = Date.now();
|
|
818
|
-
if (this.isComplete()) {
|
|
819
|
-
this.currentSpeed = 0;
|
|
820
|
-
this.averageSpeed = 0;
|
|
821
|
-
this.flowObj.fire('fileSuccess', this, message);
|
|
822
|
-
}
|
|
823
|
-
break;
|
|
824
|
-
case 'retry':
|
|
825
|
-
this.flowObj.fire('fileRetry', this);
|
|
826
|
-
break;
|
|
827
|
-
}
|
|
828
|
-
},
|
|
829
|
-
|
|
830
|
-
/**
|
|
831
|
-
* Pause file upload
|
|
832
|
-
* @function
|
|
833
|
-
*/
|
|
834
|
-
pause: function() {
|
|
835
|
-
this.paused = true;
|
|
836
|
-
this.abort();
|
|
837
|
-
},
|
|
838
|
-
|
|
839
|
-
/**
|
|
840
|
-
* Resume file upload
|
|
841
|
-
* @function
|
|
842
|
-
*/
|
|
843
|
-
resume: function() {
|
|
844
|
-
this.paused = false;
|
|
845
|
-
this.flowObj.upload();
|
|
846
|
-
},
|
|
847
|
-
|
|
848
|
-
/**
|
|
849
|
-
* Abort current upload
|
|
850
|
-
* @function
|
|
851
|
-
*/
|
|
852
|
-
abort: function (reset) {
|
|
853
|
-
this.currentSpeed = 0;
|
|
854
|
-
this.averageSpeed = 0;
|
|
855
|
-
var chunks = this.chunks;
|
|
856
|
-
if (reset) {
|
|
857
|
-
this.chunks = [];
|
|
858
|
-
}
|
|
859
|
-
each(chunks, function (c) {
|
|
860
|
-
if (c.status() === 'uploading') {
|
|
861
|
-
c.abort();
|
|
862
|
-
this.flowObj.uploadNextChunk();
|
|
863
|
-
}
|
|
864
|
-
}, this);
|
|
865
|
-
},
|
|
866
|
-
|
|
867
|
-
/**
|
|
868
|
-
* Cancel current upload and remove from a list
|
|
869
|
-
* @function
|
|
870
|
-
*/
|
|
871
|
-
cancel: function () {
|
|
872
|
-
this.flowObj.removeFile(this);
|
|
873
|
-
},
|
|
874
|
-
|
|
875
|
-
/**
|
|
876
|
-
* Retry aborted file upload
|
|
877
|
-
* @function
|
|
878
|
-
*/
|
|
879
|
-
retry: function () {
|
|
880
|
-
this.bootstrap();
|
|
881
|
-
this.flowObj.upload();
|
|
882
|
-
},
|
|
883
|
-
|
|
884
|
-
/**
|
|
885
|
-
* Clear current chunks and slice file again
|
|
886
|
-
* @function
|
|
887
|
-
*/
|
|
888
|
-
bootstrap: function () {
|
|
889
|
-
this.abort(true);
|
|
890
|
-
this.error = false;
|
|
891
|
-
// Rebuild stack of chunks from file
|
|
892
|
-
this._prevProgress = 0;
|
|
893
|
-
var round = this.flowObj.opts.forceChunkSize ? Math.ceil : Math.floor;
|
|
894
|
-
var chunks = Math.max(
|
|
895
|
-
round(this.file.size / this.flowObj.opts.chunkSize), 1
|
|
896
|
-
);
|
|
897
|
-
for (var offset = 0; offset < chunks; offset++) {
|
|
898
|
-
this.chunks.push(
|
|
899
|
-
new FlowChunk(this.flowObj, this, offset)
|
|
900
|
-
);
|
|
901
|
-
}
|
|
902
|
-
},
|
|
903
|
-
|
|
904
|
-
/**
|
|
905
|
-
* Get current upload progress status
|
|
906
|
-
* @function
|
|
907
|
-
* @returns {number} from 0 to 1
|
|
908
|
-
*/
|
|
909
|
-
progress: function () {
|
|
910
|
-
if (this.error) {
|
|
911
|
-
return 1;
|
|
912
|
-
}
|
|
913
|
-
if (this.chunks.length === 1) {
|
|
914
|
-
this._prevProgress = Math.max(this._prevProgress, this.chunks[0].progress());
|
|
915
|
-
return this._prevProgress;
|
|
916
|
-
}
|
|
917
|
-
// Sum up progress across everything
|
|
918
|
-
var bytesLoaded = 0;
|
|
919
|
-
each(this.chunks, function (c) {
|
|
920
|
-
// get chunk progress relative to entire file
|
|
921
|
-
bytesLoaded += c.progress() * (c.endByte - c.startByte);
|
|
922
|
-
});
|
|
923
|
-
var percent = bytesLoaded / this.size;
|
|
924
|
-
// We don't want to lose percentages when an upload is paused
|
|
925
|
-
this._prevProgress = Math.max(this._prevProgress, percent > 0.999 ? 1 : percent);
|
|
926
|
-
return this._prevProgress;
|
|
927
|
-
},
|
|
928
|
-
|
|
929
|
-
/**
|
|
930
|
-
* Indicates if file is being uploaded at the moment
|
|
931
|
-
* @function
|
|
932
|
-
* @returns {boolean}
|
|
933
|
-
*/
|
|
934
|
-
isUploading: function () {
|
|
935
|
-
var uploading = false;
|
|
936
|
-
each(this.chunks, function (chunk) {
|
|
937
|
-
if (chunk.status() === 'uploading') {
|
|
938
|
-
uploading = true;
|
|
939
|
-
return false;
|
|
940
|
-
}
|
|
941
|
-
});
|
|
942
|
-
return uploading;
|
|
943
|
-
},
|
|
944
|
-
|
|
945
|
-
/**
|
|
946
|
-
* Indicates if file is has finished uploading and received a response
|
|
947
|
-
* @function
|
|
948
|
-
* @returns {boolean}
|
|
949
|
-
*/
|
|
950
|
-
isComplete: function () {
|
|
951
|
-
var outstanding = false;
|
|
952
|
-
each(this.chunks, function (chunk) {
|
|
953
|
-
var status = chunk.status();
|
|
954
|
-
if (status === 'pending' || status === 'uploading' || chunk.preprocessState === 1) {
|
|
955
|
-
outstanding = true;
|
|
956
|
-
return false;
|
|
957
|
-
}
|
|
958
|
-
});
|
|
959
|
-
return !outstanding;
|
|
960
|
-
},
|
|
961
|
-
|
|
962
|
-
/**
|
|
963
|
-
* Count total size uploaded
|
|
964
|
-
* @function
|
|
965
|
-
* @returns {number}
|
|
966
|
-
*/
|
|
967
|
-
sizeUploaded: function () {
|
|
968
|
-
var size = 0;
|
|
969
|
-
each(this.chunks, function (chunk) {
|
|
970
|
-
size += chunk.sizeUploaded();
|
|
971
|
-
});
|
|
972
|
-
return size;
|
|
973
|
-
},
|
|
974
|
-
|
|
975
|
-
/**
|
|
976
|
-
* Returns remaining time to finish upload file in seconds. Accuracy is based on average speed.
|
|
977
|
-
* If speed is zero, time remaining will be equal to positive infinity `Number.POSITIVE_INFINITY`
|
|
978
|
-
* @function
|
|
979
|
-
* @returns {number}
|
|
980
|
-
*/
|
|
981
|
-
timeRemaining: function () {
|
|
982
|
-
if (this.paused || this.error) {
|
|
983
|
-
return 0;
|
|
984
|
-
}
|
|
985
|
-
var delta = this.size - this.sizeUploaded();
|
|
986
|
-
if (delta && !this.averageSpeed) {
|
|
987
|
-
return Number.POSITIVE_INFINITY;
|
|
988
|
-
}
|
|
989
|
-
if (!delta && !this.averageSpeed) {
|
|
990
|
-
return 0;
|
|
991
|
-
}
|
|
992
|
-
return Math.floor(delta / this.averageSpeed);
|
|
993
|
-
},
|
|
994
|
-
|
|
995
|
-
/**
|
|
996
|
-
* Get file type
|
|
997
|
-
* @function
|
|
998
|
-
* @returns {string}
|
|
999
|
-
*/
|
|
1000
|
-
getType: function () {
|
|
1001
|
-
return this.file.type && this.file.type.split('/')[1];
|
|
1002
|
-
},
|
|
1003
|
-
|
|
1004
|
-
/**
|
|
1005
|
-
* Get file extension
|
|
1006
|
-
* @function
|
|
1007
|
-
* @returns {string}
|
|
1008
|
-
*/
|
|
1009
|
-
getExtension: function () {
|
|
1010
|
-
return this.name.substr((~-this.name.lastIndexOf(".") >>> 0) + 2).toLowerCase();
|
|
1011
|
-
}
|
|
1012
|
-
};
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
/**
|
|
1022
|
-
* Class for storing a single chunk
|
|
1023
|
-
* @name FlowChunk
|
|
1024
|
-
* @param {Flow} flowObj
|
|
1025
|
-
* @param {FlowFile} fileObj
|
|
1026
|
-
* @param {number} offset
|
|
1027
|
-
* @constructor
|
|
1028
|
-
*/
|
|
1029
|
-
function FlowChunk(flowObj, fileObj, offset) {
|
|
1030
|
-
|
|
1031
|
-
/**
|
|
1032
|
-
* Reference to parent flow object
|
|
1033
|
-
* @type {Flow}
|
|
1034
|
-
*/
|
|
1035
|
-
this.flowObj = flowObj;
|
|
1036
|
-
|
|
1037
|
-
/**
|
|
1038
|
-
* Reference to parent FlowFile object
|
|
1039
|
-
* @type {FlowFile}
|
|
1040
|
-
*/
|
|
1041
|
-
this.fileObj = fileObj;
|
|
1042
|
-
|
|
1043
|
-
/**
|
|
1044
|
-
* File size
|
|
1045
|
-
* @type {number}
|
|
1046
|
-
*/
|
|
1047
|
-
this.fileObjSize = fileObj.size;
|
|
1048
|
-
|
|
1049
|
-
/**
|
|
1050
|
-
* File offset
|
|
1051
|
-
* @type {number}
|
|
1052
|
-
*/
|
|
1053
|
-
this.offset = offset;
|
|
1054
|
-
|
|
1055
|
-
/**
|
|
1056
|
-
* Indicates if chunk existence was checked on the server
|
|
1057
|
-
* @type {boolean}
|
|
1058
|
-
*/
|
|
1059
|
-
this.tested = false;
|
|
1060
|
-
|
|
1061
|
-
/**
|
|
1062
|
-
* Number of retries performed
|
|
1063
|
-
* @type {number}
|
|
1064
|
-
*/
|
|
1065
|
-
this.retries = 0;
|
|
1066
|
-
|
|
1067
|
-
/**
|
|
1068
|
-
* Pending retry
|
|
1069
|
-
* @type {boolean}
|
|
1070
|
-
*/
|
|
1071
|
-
this.pendingRetry = false;
|
|
1072
|
-
|
|
1073
|
-
/**
|
|
1074
|
-
* Preprocess state
|
|
1075
|
-
* @type {number} 0 = unprocessed, 1 = processing, 2 = finished
|
|
1076
|
-
*/
|
|
1077
|
-
this.preprocessState = 0;
|
|
1078
|
-
|
|
1079
|
-
/**
|
|
1080
|
-
* Bytes transferred from total request size
|
|
1081
|
-
* @type {number}
|
|
1082
|
-
*/
|
|
1083
|
-
this.loaded = 0;
|
|
1084
|
-
|
|
1085
|
-
/**
|
|
1086
|
-
* Total request size
|
|
1087
|
-
* @type {number}
|
|
1088
|
-
*/
|
|
1089
|
-
this.total = 0;
|
|
1090
|
-
|
|
1091
|
-
/**
|
|
1092
|
-
* Size of a chunk
|
|
1093
|
-
* @type {number}
|
|
1094
|
-
*/
|
|
1095
|
-
var chunkSize = this.flowObj.opts.chunkSize;
|
|
1096
|
-
|
|
1097
|
-
/**
|
|
1098
|
-
* Chunk start byte in a file
|
|
1099
|
-
* @type {number}
|
|
1100
|
-
*/
|
|
1101
|
-
this.startByte = this.offset * chunkSize;
|
|
1102
|
-
|
|
1103
|
-
/**
|
|
1104
|
-
* Chunk end byte in a file
|
|
1105
|
-
* @type {number}
|
|
1106
|
-
*/
|
|
1107
|
-
this.endByte = Math.min(this.fileObjSize, (this.offset + 1) * chunkSize);
|
|
1108
|
-
|
|
1109
|
-
/**
|
|
1110
|
-
* XMLHttpRequest
|
|
1111
|
-
* @type {XMLHttpRequest}
|
|
1112
|
-
*/
|
|
1113
|
-
this.xhr = null;
|
|
1114
|
-
|
|
1115
|
-
if (this.fileObjSize - this.endByte < chunkSize &&
|
|
1116
|
-
!this.flowObj.opts.forceChunkSize) {
|
|
1117
|
-
// The last chunk will be bigger than the chunk size,
|
|
1118
|
-
// but less than 2*chunkSize
|
|
1119
|
-
this.endByte = this.fileObjSize;
|
|
1120
|
-
}
|
|
1121
|
-
|
|
1122
|
-
var $ = this;
|
|
1123
|
-
|
|
1124
|
-
/**
|
|
1125
|
-
* Catch progress event
|
|
1126
|
-
* @param {ProgressEvent} event
|
|
1127
|
-
*/
|
|
1128
|
-
this.progressHandler = function(event) {
|
|
1129
|
-
if (event.lengthComputable) {
|
|
1130
|
-
$.loaded = event.loaded ;
|
|
1131
|
-
$.total = event.total;
|
|
1132
|
-
}
|
|
1133
|
-
$.fileObj.chunkEvent('progress');
|
|
1134
|
-
};
|
|
1135
|
-
|
|
1136
|
-
/**
|
|
1137
|
-
* Catch test event
|
|
1138
|
-
* @param {Event} event
|
|
1139
|
-
*/
|
|
1140
|
-
this.testHandler = function(event) {
|
|
1141
|
-
var status = $.status();
|
|
1142
|
-
if (status === 'success') {
|
|
1143
|
-
$.tested = true;
|
|
1144
|
-
$.fileObj.chunkEvent(status, $.message());
|
|
1145
|
-
$.flowObj.uploadNextChunk();
|
|
1146
|
-
} else if (!$.fileObj.paused) {// Error might be caused by file pause method
|
|
1147
|
-
$.tested = true;
|
|
1148
|
-
$.send();
|
|
1149
|
-
}
|
|
1150
|
-
};
|
|
1151
|
-
|
|
1152
|
-
/**
|
|
1153
|
-
* Upload has stopped
|
|
1154
|
-
* @param {Event} event
|
|
1155
|
-
*/
|
|
1156
|
-
this.doneHandler = function(event) {
|
|
1157
|
-
var status = $.status();
|
|
1158
|
-
if (status === 'success' || status === 'error') {
|
|
1159
|
-
$.fileObj.chunkEvent(status, $.message());
|
|
1160
|
-
$.flowObj.uploadNextChunk();
|
|
1161
|
-
} else {
|
|
1162
|
-
$.fileObj.chunkEvent('retry', $.message());
|
|
1163
|
-
$.pendingRetry = true;
|
|
1164
|
-
$.abort();
|
|
1165
|
-
$.retries++;
|
|
1166
|
-
var retryInterval = $.flowObj.opts.chunkRetryInterval;
|
|
1167
|
-
if (retryInterval !== null) {
|
|
1168
|
-
setTimeout(function () {
|
|
1169
|
-
$.send();
|
|
1170
|
-
}, retryInterval);
|
|
1171
|
-
} else {
|
|
1172
|
-
$.send();
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
1175
|
-
};
|
|
1176
|
-
}
|
|
1177
|
-
|
|
1178
|
-
FlowChunk.prototype = {
|
|
1179
|
-
/**
|
|
1180
|
-
* Get params for a request
|
|
1181
|
-
* @function
|
|
1182
|
-
*/
|
|
1183
|
-
getParams: function () {
|
|
1184
|
-
return {
|
|
1185
|
-
flowChunkNumber: this.offset + 1,
|
|
1186
|
-
flowChunkSize: this.flowObj.opts.chunkSize,
|
|
1187
|
-
flowCurrentChunkSize: this.endByte - this.startByte,
|
|
1188
|
-
flowTotalSize: this.fileObjSize,
|
|
1189
|
-
flowIdentifier: this.fileObj.uniqueIdentifier,
|
|
1190
|
-
flowFilename: this.fileObj.name,
|
|
1191
|
-
flowRelativePath: this.fileObj.relativePath,
|
|
1192
|
-
flowTotalChunks: this.fileObj.chunks.length
|
|
1193
|
-
};
|
|
1194
|
-
},
|
|
1195
|
-
|
|
1196
|
-
/**
|
|
1197
|
-
* Get target option with query params
|
|
1198
|
-
* @function
|
|
1199
|
-
* @param params
|
|
1200
|
-
* @returns {string}
|
|
1201
|
-
*/
|
|
1202
|
-
getTarget: function(target, params){
|
|
1203
|
-
if(target.indexOf('?') < 0) {
|
|
1204
|
-
target += '?';
|
|
1205
|
-
} else {
|
|
1206
|
-
target += '&';
|
|
1207
|
-
}
|
|
1208
|
-
return target + params.join('&');
|
|
1209
|
-
},
|
|
1210
|
-
|
|
1211
|
-
/**
|
|
1212
|
-
* Makes a GET request without any data to see if the chunk has already
|
|
1213
|
-
* been uploaded in a previous session
|
|
1214
|
-
* @function
|
|
1215
|
-
*/
|
|
1216
|
-
test: function () {
|
|
1217
|
-
// Set up request and listen for event
|
|
1218
|
-
this.xhr = new XMLHttpRequest();
|
|
1219
|
-
this.xhr.addEventListener("load", this.testHandler, false);
|
|
1220
|
-
this.xhr.addEventListener("error", this.testHandler, false);
|
|
1221
|
-
var data = this.prepareXhrRequest('GET', true);
|
|
1222
|
-
this.xhr.send(data);
|
|
1223
|
-
},
|
|
1224
|
-
|
|
1225
|
-
/**
|
|
1226
|
-
* Finish preprocess state
|
|
1227
|
-
* @function
|
|
1228
|
-
*/
|
|
1229
|
-
preprocessFinished: function () {
|
|
1230
|
-
this.preprocessState = 2;
|
|
1231
|
-
this.send();
|
|
1232
|
-
},
|
|
1233
|
-
|
|
1234
|
-
/**
|
|
1235
|
-
* Uploads the actual data in a POST call
|
|
1236
|
-
* @function
|
|
1237
|
-
*/
|
|
1238
|
-
send: function () {
|
|
1239
|
-
var preprocess = this.flowObj.opts.preprocess;
|
|
1240
|
-
if (typeof preprocess === 'function') {
|
|
1241
|
-
switch (this.preprocessState) {
|
|
1242
|
-
case 0:
|
|
1243
|
-
this.preprocessState = 1;
|
|
1244
|
-
preprocess(this);
|
|
1245
|
-
return;
|
|
1246
|
-
case 1:
|
|
1247
|
-
return;
|
|
1248
|
-
}
|
|
1249
|
-
}
|
|
1250
|
-
if (this.flowObj.opts.testChunks && !this.tested) {
|
|
1251
|
-
this.test();
|
|
1252
|
-
return;
|
|
1253
|
-
}
|
|
1254
|
-
|
|
1255
|
-
this.loaded = 0;
|
|
1256
|
-
this.total = 0;
|
|
1257
|
-
this.pendingRetry = false;
|
|
1258
|
-
|
|
1259
|
-
var func = (this.fileObj.file.slice ? 'slice' :
|
|
1260
|
-
(this.fileObj.file.mozSlice ? 'mozSlice' :
|
|
1261
|
-
(this.fileObj.file.webkitSlice ? 'webkitSlice' :
|
|
1262
|
-
'slice')));
|
|
1263
|
-
var bytes = this.fileObj.file[func](this.startByte, this.endByte, this.fileObj.file.type);
|
|
1264
|
-
|
|
1265
|
-
// Set up request and listen for event
|
|
1266
|
-
this.xhr = new XMLHttpRequest();
|
|
1267
|
-
this.xhr.upload.addEventListener('progress', this.progressHandler, false);
|
|
1268
|
-
this.xhr.addEventListener("load", this.doneHandler, false);
|
|
1269
|
-
this.xhr.addEventListener("error", this.doneHandler, false);
|
|
1270
|
-
|
|
1271
|
-
var data = this.prepareXhrRequest('POST', false, this.flowObj.opts.method, bytes);
|
|
1272
|
-
this.xhr.send(data);
|
|
1273
|
-
},
|
|
1274
|
-
|
|
1275
|
-
/**
|
|
1276
|
-
* Abort current xhr request
|
|
1277
|
-
* @function
|
|
1278
|
-
*/
|
|
1279
|
-
abort: function () {
|
|
1280
|
-
// Abort and reset
|
|
1281
|
-
var xhr = this.xhr;
|
|
1282
|
-
this.xhr = null;
|
|
1283
|
-
if (xhr) {
|
|
1284
|
-
xhr.abort();
|
|
1285
|
-
}
|
|
1286
|
-
},
|
|
1287
|
-
|
|
1288
|
-
/**
|
|
1289
|
-
* Retrieve current chunk upload status
|
|
1290
|
-
* @function
|
|
1291
|
-
* @returns {string} 'pending', 'uploading', 'success', 'error'
|
|
1292
|
-
*/
|
|
1293
|
-
status: function () {
|
|
1294
|
-
if (this.pendingRetry || this.preprocessState === 1) {
|
|
1295
|
-
// if pending retry then that's effectively the same as actively uploading,
|
|
1296
|
-
// there might just be a slight delay before the retry starts
|
|
1297
|
-
return 'uploading';
|
|
1298
|
-
} else if (!this.xhr) {
|
|
1299
|
-
return 'pending';
|
|
1300
|
-
} else if (this.xhr.readyState < 4) {
|
|
1301
|
-
// Status is really 'OPENED', 'HEADERS_RECEIVED'
|
|
1302
|
-
// or 'LOADING' - meaning that stuff is happening
|
|
1303
|
-
return 'uploading';
|
|
1304
|
-
} else {
|
|
1305
|
-
if (this.xhr.status == 200) {
|
|
1306
|
-
// HTTP 200, perfect
|
|
1307
|
-
return 'success';
|
|
1308
|
-
} else if (this.flowObj.opts.permanentErrors.indexOf(this.xhr.status) > -1 ||
|
|
1309
|
-
this.retries >= this.flowObj.opts.maxChunkRetries) {
|
|
1310
|
-
// HTTP 415/500/501, permanent error
|
|
1311
|
-
return 'error';
|
|
1312
|
-
} else {
|
|
1313
|
-
// this should never happen, but we'll reset and queue a retry
|
|
1314
|
-
// a likely case for this would be 503 service unavailable
|
|
1315
|
-
this.abort();
|
|
1316
|
-
return 'pending';
|
|
1317
|
-
}
|
|
1318
|
-
}
|
|
1319
|
-
},
|
|
1320
|
-
|
|
1321
|
-
/**
|
|
1322
|
-
* Get response from xhr request
|
|
1323
|
-
* @function
|
|
1324
|
-
* @returns {String}
|
|
1325
|
-
*/
|
|
1326
|
-
message: function () {
|
|
1327
|
-
return this.xhr ? this.xhr.responseText : '';
|
|
1328
|
-
},
|
|
1329
|
-
|
|
1330
|
-
/**
|
|
1331
|
-
* Get upload progress
|
|
1332
|
-
* @function
|
|
1333
|
-
* @returns {number}
|
|
1334
|
-
*/
|
|
1335
|
-
progress: function () {
|
|
1336
|
-
if (this.pendingRetry) {
|
|
1337
|
-
return 0;
|
|
1338
|
-
}
|
|
1339
|
-
var s = this.status();
|
|
1340
|
-
if (s === 'success' || s === 'error') {
|
|
1341
|
-
return 1;
|
|
1342
|
-
} else if (s === 'pending') {
|
|
1343
|
-
return 0;
|
|
1344
|
-
} else {
|
|
1345
|
-
return this.total > 0 ? this.loaded / this.total : 0;
|
|
1346
|
-
}
|
|
1347
|
-
},
|
|
1348
|
-
|
|
1349
|
-
/**
|
|
1350
|
-
* Count total size uploaded
|
|
1351
|
-
* @function
|
|
1352
|
-
* @returns {number}
|
|
1353
|
-
*/
|
|
1354
|
-
sizeUploaded: function () {
|
|
1355
|
-
var size = this.endByte - this.startByte;
|
|
1356
|
-
// can't return only chunk.loaded value, because it is bigger than chunk size
|
|
1357
|
-
if (this.status() !== 'success') {
|
|
1358
|
-
size = this.progress() * size;
|
|
1359
|
-
}
|
|
1360
|
-
return size;
|
|
1361
|
-
},
|
|
1362
|
-
|
|
1363
|
-
/**
|
|
1364
|
-
* Prepare Xhr request. Set query, headers and data
|
|
1365
|
-
* @param {string} method GET or POST
|
|
1366
|
-
* @param {bool} isTest is this a test request
|
|
1367
|
-
* @param {string} [paramsMethod] octet or form
|
|
1368
|
-
* @param {Blob} [blob] to send
|
|
1369
|
-
* @returns {FormData|Blob|Null} data to send
|
|
1370
|
-
*/
|
|
1371
|
-
prepareXhrRequest: function(method, isTest, paramsMethod, blob) {
|
|
1372
|
-
// Add data from the query options
|
|
1373
|
-
var query = evalOpts(this.flowObj.opts.query, this.fileObj, this, isTest);
|
|
1374
|
-
query = extend(this.getParams(), query);
|
|
1375
|
-
|
|
1376
|
-
var target = evalOpts(this.flowObj.opts.target, this.fileObj, this, isTest);
|
|
1377
|
-
var data = null;
|
|
1378
|
-
if (method === 'GET' || paramsMethod === 'octet') {
|
|
1379
|
-
// Add data from the query options
|
|
1380
|
-
var params = [];
|
|
1381
|
-
each(query, function (v, k) {
|
|
1382
|
-
params.push([encodeURIComponent(k), encodeURIComponent(v)].join('='));
|
|
1383
|
-
});
|
|
1384
|
-
target = this.getTarget(target, params);
|
|
1385
|
-
data = blob || null;
|
|
1386
|
-
} else {
|
|
1387
|
-
// Add data from the query options
|
|
1388
|
-
data = new FormData();
|
|
1389
|
-
each(query, function (v, k) {
|
|
1390
|
-
data.append(k, v);
|
|
1391
|
-
});
|
|
1392
|
-
data.append(this.flowObj.opts.fileParameterName, blob, this.fileObj.file.name);
|
|
1393
|
-
}
|
|
1394
|
-
|
|
1395
|
-
this.xhr.open(method, target, true);
|
|
1396
|
-
this.xhr.withCredentials = this.flowObj.opts.withCredentials;
|
|
1397
|
-
|
|
1398
|
-
// Add data from header options
|
|
1399
|
-
each(evalOpts(this.flowObj.opts.headers, this.fileObj, this, isTest), function (v, k) {
|
|
1400
|
-
this.xhr.setRequestHeader(k, v);
|
|
1401
|
-
}, this);
|
|
1402
|
-
|
|
1403
|
-
return data;
|
|
1404
|
-
}
|
|
1405
|
-
};
|
|
1406
|
-
|
|
1407
|
-
/**
|
|
1408
|
-
* Remove value from array
|
|
1409
|
-
* @param array
|
|
1410
|
-
* @param value
|
|
1411
|
-
*/
|
|
1412
|
-
function arrayRemove(array, value) {
|
|
1413
|
-
var index = array.indexOf(value);
|
|
1414
|
-
if (index > -1) {
|
|
1415
|
-
array.splice(index, 1);
|
|
1416
|
-
}
|
|
1417
|
-
}
|
|
1418
|
-
|
|
1419
|
-
/**
|
|
1420
|
-
* If option is a function, evaluate it with given params
|
|
1421
|
-
* @param {*} data
|
|
1422
|
-
* @param {...} args arguments of a callback
|
|
1423
|
-
* @returns {*}
|
|
1424
|
-
*/
|
|
1425
|
-
function evalOpts(data, args) {
|
|
1426
|
-
if (typeof data === "function") {
|
|
1427
|
-
// `arguments` is an object, not array, in FF, so:
|
|
1428
|
-
args = Array.prototype.slice.call(arguments);
|
|
1429
|
-
data = data.apply(null, args.slice(1));
|
|
1430
|
-
}
|
|
1431
|
-
return data;
|
|
1432
|
-
}
|
|
1433
|
-
Flow.evalOpts = evalOpts;
|
|
1434
|
-
|
|
1435
|
-
/**
|
|
1436
|
-
* Execute function asynchronously
|
|
1437
|
-
* @param fn
|
|
1438
|
-
* @param context
|
|
1439
|
-
*/
|
|
1440
|
-
function async(fn, context) {
|
|
1441
|
-
setTimeout(fn.bind(context), 0);
|
|
1442
|
-
}
|
|
1443
|
-
|
|
1444
|
-
/**
|
|
1445
|
-
* Extends the destination object `dst` by copying all of the properties from
|
|
1446
|
-
* the `src` object(s) to `dst`. You can specify multiple `src` objects.
|
|
1447
|
-
* @function
|
|
1448
|
-
* @param {Object} dst Destination object.
|
|
1449
|
-
* @param {...Object} src Source object(s).
|
|
1450
|
-
* @returns {Object} Reference to `dst`.
|
|
1451
|
-
*/
|
|
1452
|
-
function extend(dst, src) {
|
|
1453
|
-
each(arguments, function(obj) {
|
|
1454
|
-
if (obj !== dst) {
|
|
1455
|
-
each(obj, function(value, key){
|
|
1456
|
-
dst[key] = value;
|
|
1457
|
-
});
|
|
1458
|
-
}
|
|
1459
|
-
});
|
|
1460
|
-
return dst;
|
|
1461
|
-
}
|
|
1462
|
-
Flow.extend = extend;
|
|
1463
|
-
|
|
1464
|
-
/**
|
|
1465
|
-
* Iterate each element of an object
|
|
1466
|
-
* @function
|
|
1467
|
-
* @param {Array|Object} obj object or an array to iterate
|
|
1468
|
-
* @param {Function} callback first argument is a value and second is a key.
|
|
1469
|
-
* @param {Object=} context Object to become context (`this`) for the iterator function.
|
|
1470
|
-
*/
|
|
1471
|
-
function each(obj, callback, context) {
|
|
1472
|
-
if (!obj) {
|
|
1473
|
-
return ;
|
|
1474
|
-
}
|
|
1475
|
-
var key;
|
|
1476
|
-
// Is Array?
|
|
1477
|
-
if (typeof(obj.length) !== 'undefined') {
|
|
1478
|
-
for (key = 0; key < obj.length; key++) {
|
|
1479
|
-
if (callback.call(context, obj[key], key) === false) {
|
|
1480
|
-
return ;
|
|
1481
|
-
}
|
|
1482
|
-
}
|
|
1483
|
-
} else {
|
|
1484
|
-
for (key in obj) {
|
|
1485
|
-
if (obj.hasOwnProperty(key) && callback.call(context, obj[key], key) === false) {
|
|
1486
|
-
return ;
|
|
1487
|
-
}
|
|
1488
|
-
}
|
|
1489
|
-
}
|
|
1490
|
-
}
|
|
1491
|
-
Flow.each = each;
|
|
1492
|
-
|
|
1493
|
-
/**
|
|
1494
|
-
* FlowFile constructor
|
|
1495
|
-
* @type {FlowFile}
|
|
1496
|
-
*/
|
|
1497
|
-
Flow.FlowFile = FlowFile;
|
|
1498
|
-
|
|
1499
|
-
/**
|
|
1500
|
-
* FlowFile constructor
|
|
1501
|
-
* @type {FlowChunk}
|
|
1502
|
-
*/
|
|
1503
|
-
Flow.FlowChunk = FlowChunk;
|
|
1504
|
-
|
|
1505
|
-
/**
|
|
1506
|
-
* Library version
|
|
1507
|
-
* @type {string}
|
|
1508
|
-
*/
|
|
1509
|
-
Flow.version = '<%= version %>';
|
|
1510
|
-
|
|
1511
|
-
if ( typeof module === "object" && module && typeof module.exports === "object" ) {
|
|
1512
|
-
// Expose Flow as module.exports in loaders that implement the Node
|
|
1513
|
-
// module pattern (including browserify). Do not create the global, since
|
|
1514
|
-
// the user will be storing it themselves locally, and globals are frowned
|
|
1515
|
-
// upon in the Node module world.
|
|
1516
|
-
module.exports = Flow;
|
|
1517
|
-
} else {
|
|
1518
|
-
// Otherwise expose Flow to the global object as usual
|
|
1519
|
-
window.Flow = Flow;
|
|
1520
|
-
|
|
1521
|
-
// Register as a named AMD module, since Flow can be concatenated with other
|
|
1522
|
-
// files that may use define, but not via a proper concatenation script that
|
|
1523
|
-
// understands anonymous AMD modules. A named AMD is safest and most robust
|
|
1524
|
-
// way to register. Lowercase flow is used because AMD module names are
|
|
1525
|
-
// derived from file names, and Flow is normally delivered in a lowercase
|
|
1526
|
-
// file name. Do this after creating the global so that if an AMD module wants
|
|
1527
|
-
// to call noConflict to hide this version of Flow, it will work.
|
|
1528
|
-
if ( typeof define === "function" && define.amd ) {
|
|
1529
|
-
define( "flow", [], function () { return Flow; } );
|
|
1530
|
-
}
|
|
1531
|
-
}
|
|
1532
|
-
})(window, document);
|