diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..507d3c6 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +# These are supported funding model platforms + +github: [ValentinH] diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..6028c0c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,26 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +Demo: https://jsfiddle.net/wm3ce8jb/ (fork this example and update the link) + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. diff --git a/.gitignore b/.gitignore index 8b13917..b2fa3c1 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,7 @@ node_modules/ bower_components/ temp/ tests/coverage/ +yarn.lock +cypress/videos +npm-debug.log +.history/ \ No newline at end of file diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..5660f81 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +registry=https://registry.npmjs.org/ \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..36301bc --- /dev/null +++ b/.prettierrc @@ -0,0 +1,5 @@ +{ + "semi": false, + "singleQuote": true, + "trailingComma": "es5" +} diff --git a/.travis.yml b/.travis.yml index e87b13f..6c95131 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,5 +14,6 @@ before_script: - npm run build script: - npm run test + - npm run e2e after_success: - npm run report-coverage diff --git a/CHANGELOG.md b/CHANGELOG.md index dd28de7..ed21eeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,103 +1,375 @@ +# 7.0.1 (2021-09-06) + +## Bug fix + +- chore(styles): add parentheses around division-like expr's (#679) + +# 7.0.0 (2019-02-23) + +## Feature + +- feat(transition): slider moves are now animated. (this can be disabled via the `disableAnimation` option) + +## Bug fix + +- fix(vertical): Support switching between horizontal and vertical + +## Breaking change + +The module name was renamed from `rzModule` to `rzSlider`. + +# 6.7.0 (2019-02-23) + +## Feature + +- feat(ticks): add the option to use ticksArray as array of objects (#662, thanks @vdiez) + +# 6.6.0 (2018-06-29) + +## Feature + +- feat(range): adds the `restrictedRange` option (#638, thanks @DanielReid) + +## ⚠️ Unwanted breaking change ⚠️ + +Sorry for this, but this version is breaking if you are using the `rz-slider-tpl-url` attribute. You need to update your template to have the correct number of elements. + +# 6.5.1 (2018-03-30) + +## Bug fix + +- revert: onStart: Remove stop propagation call so events will bubble up (#612) + +# 6.5.0 (2018-02-06) + +## Feature + +- feat(\$compile): adds labelOverlapSeparator as an option (#616) + +# 6.4.4 (2018-01-24) + +## Bug fix + +- onStart: Remove stop propagation call so events will bubble up (#612) + +# 6.4.3 (2017-12-01) + +## Bug fix + +- Remove the semicolon at the end of the `dist/rzslider.css` file. It was introduced by previous release. + +# 6.4.2 (2017-11-30) + +## Bug fix + +- Add a semicolon at the end of the `dist/rzslider.js` file. It avoids errors when people concat this file with other libs without using the minified version. + +# 6.4.1 (2017-11-17) + +## Bug fix + +- Options: react to changes of options of Function type (#590) + +# 6.4.0 (2017-08-12) + +## Feature + +- Add the `showOuterSelectionBars` option (#553). + +# 6.3.0 (2017-08-07) + +## Feature + +- Handle different values for `showTicks` and `showTicksValues` (#550). + +# 6.2.3 (2017-07-08) + +## Tooling + +- Add Typescript definition file. + +# 6.2.2 (2017-05-16) + +## Fixes + +- Fix (again) onEnd event de-registration. + +# 6.2.1 (2017-05-15) + +## Fixes + +- Fix onEnd event being sent several times on non-mobiles devices (#536) + +# 6.2.0 (2017-05-25) + +## New Feature + +- Handle multi touch events on separate sliders (#535). Thanks @daniela-mateescu :) + +# 6.1.2 (2017-05-15) + +## Fixes + +- Fix ticks and values at intermediate positions on IE (#531) + +# 6.1.1 (2017-03-29) + +## Fixes + +- Add vendor prefixes for transform property in JS code (#518) + +# 6.1.0 (2017-03-06) + +## Features + +- Add labelling options for a11y (#505) + +# 6.0.2 (2017-03-02) + +## Fixes + +- Update the combined labels on separation (#502) + +# 6.0.1 (2017-02-14) + +## Fixes + +- Ensure model value is current when custom translate function runs for tick values + +# 6.0.0 (2017-01-02) + +## Refactoring + +- Refactor/simplify the css rules to ease the customisation. + +**You might want to check that all your custom styles are still correctly applied...** + +# 5.9.0 (2016-12-12) + +## Features + +- Add selectionBarGradient option to customize the selection bar (#473) + +# 5.8.9 (2016-12-11) + +## Improvement + +- Add autoprefixer for CSS builds (#472) + +# 5.8.8 (2016-12-11) + +## Fix + +- Prevent angular being loaded twice when using with browserify (#474) + +# 5.8.7 (2016-11-09) + +## Fix + +- Add Math.round for positions and dimensions - thanks to @DmitryKrekota (#454) + +# 5.8.6 (2016-11-08) + +## Fix + +- Apply the pushRange with maxRange - thanks to @GuilloOme (#456) + +# 5.8.5 (2016-11-05) + +## Fix + +- Fix overlapping max and ceil labels in some cases (#396) + +# 5.8.4 (2016-11-05) + +## Improvement + +- Refactor autoHiding algorithm for labels (fix #446) + +# 5.8.3 (2016-11-03) + +## Improvement + +- Generate a SCSS file (simple copy of the css file) in the dist folder so it can be imported (#449) + +# 5.8.2 (2016-11-03) + +## Fix + +- Fix ceil label positioning (#448) + +# 5.8.1 (2016-10-27) + +## Fix + +- Enable using with Browserify (#436) + +# 5.8.0 (2016-10-22) + +## Features + +- Handle Date object in stepsArray (#424 ) + +## Fixes + +- Fix style for disabled range slider and ticks (#394) +- Fix slider goes back when moved and scaled (#346) + +# 5.7.0 (2016-10-16) + +## Features + +- Add a `logScale` option to display the slider using a logarithmic scale (#280). +- Add `customValueToPosition` and `customPositionToValue` options to display the slider using a custom scale (#280). + +# 5.6.0 (2016-10-16) + +## Features + +- Add a `ticksArray` option to display ticks at specific positions (#426). + +To enable this new feature, the way the ticks are rendered has been changed. Now each tick is positioned absolutely using a `transform: translate()` instruction. + # 5.5.1 (2016-09-22) + ## Fix + - Prevent losing focus when slider is rerendered (#415). # 5.5.0 (2016-09-06) + ## Features -- Add an autoHideLimitLabels to disable the auto-hiding of limit labels (#405). + +- Add an `autoHideLimitLabels` to disable the auto-hiding of limit labels (#405). # 5.4.3 (2016-08-07) + ## Fix + - Fix minLimit/maxLimit bugged for draggableRange (#384). # 5.4.2 (2016-08-02) + ## Fix + - Fix minimum value goes below floor when using maxRange (#377). # 5.4.1 (2016-07-17) + ## Fix + - Fix showing limit labels when pointer labels are always hidden (#373). # 5.4.0 (2016-07-13) + ## Features + - Add function to customize color of ticks (#372). # 5.3.0 (2016-07-11) + ## Features + - Expose labels on scope in template (#358). # 5.2.0 (2016-07-07) + ## Features + - Add a `customTemplateScope` option (#354). # 5.1.1 (2016-07-06) + ## Fix + - Fix the way to check when event properties are undefined (#365). # 5.1.0 (2016-07-02) + ## Features + - Add a `pushRange` option (#341). # 5.0.1 (2016-07-01) + ## Fix + - Switch from using opacity to visibility to show/hide elements (#362). # 5.0.0 (2016-06-30) + ## Fix + - AMD/CommonJS exported module: export module name instead of module (#360). ## Breaking change + Code that relies on the module object to be exported (accessing the name via .name for example) will break, since the name is now directly returned. # 4.1.0 (2016-06-30) + ## Improvement + - Add a `bindIndexForStepsArray` option that enable to use `stepsArray` with the same behavior as before 4.0 (#345). ## Fix + - Hide floor/ceil label when overlapped on combo label (#357). - Fix switching from steps array to regular steps (#361). # 4.0.2 (2016-06-07) + ## Improvement + - Add a `mergeRangeLabelsIfSame` option (#245). # 4.0.1 (2016-06-04) + ## Improvement + - Add a pointerType arg for the callbacks (onStart, onChange and onEnd) to identify which handle is used (#339). # 4.0.0 (2016-06-04) + ## Improvement + - `stepsArray`: Bind rzSliderModel and rzSliderHigh to the actual value (#335). ## Breaking changes + - From now on, when using the `stepsArray` feature, you should directly provide the actual value to rzSliderModel and rzSliderHigh instead of passing the index of this value. -Thus, you need to update your config like in the following example: + Thus, you need to update your config like in the following example: + ```js /* before 4.0 version */ vm.slider = { - value: 4, // index of the 'E' value in the array - options: { - stepsArray: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('') - } + value: 4, // index of the 'E' value in the array + options: { + stepsArray: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''), + }, } /* from 4.0 version */ vm.slider = { - value: 'E', - options: { - stepsArray: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('') - } + value: 'E', + options: { + stepsArray: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''), + }, } ``` # 3.0.0 (2016-06-02) + ## Features + - Add IE8 support (#314). - Consolidate onStart, onChange and onEnd for keyboard (#319). - Added `rz-floor` and `rz-ceil` classes to floor and ceil label to allow styling (#337). ## Breaking changes + - From now on, to allow the IE8 support, the directive is configured with `replace: true`. Thus, you need to update your custom CSS rules like in the following example: + ```css /* before 3.0 version */ rzslider { @@ -111,125 +383,174 @@ rzslider { ``` # 2.14.0 (2016-05-22) + ## Features + - Add `minLimit` and `maxLimit` options (#332). - Add a `maxRange` option (#333). - Add `boundPointerLabels` option (#323). # 2.13.0 (2016-04-24) + ## Features -- Add a `getLegend` option (#318). + +- Add a `getLegend` option (#318). - Handle objects in `stepsArray` that can contain `value` and `legend` properties. # 2.12.0 (2016-04-22) + ## Features + - Accept numbers for showTicks/showTicksValues to display ticks at intermediate positions (#264). # 2.11.0 (2016-04-01) + ## Features + - Add a hidePointerLabels option (#273). ## Fix + - Position long labels on vertical sliders correctly (#306). # 2.10.4 (2016-03-16) + ## Fix + - Fix the floor limit when floor is different than 0 (#293). # 2.10.3 (2016-03-14) + ## Fix + - Prefix all CSS classes with rz- to prevent conflicts (#292). # 2.10.2 (2016-03-01) + ## Bug fixes + - Remove the dist folder from gitignore. # 2.10.1 (2016-03-01) + ## Bug fixes + - Republish the npm module since dist files were missing. # 2.10.0 (2016-02-29) + ## Features + - Added `rightToLeft` option for RTL support (#270). Thanks @Liam-Ryan :). # 2.9.0 (2016-02-18) + ## Features + - Change `rzSliderOptions` to use expression binding (#266). # 2.8.0 (2016-02-08) + ## Features + - Add a `getPointerColor` option to dynamically change the pointers color (#253). # 2.7.1 (2016-02-06) + ## Fix + - Fix high label positioning when size is different than the ceil one. # 2.7.0 (2016-02-06) + ## Features + - Add an `enforceStep` option (defaults to true) (#246). - Add a `showSelectionBarFromValue` options (#250). - Use jqLite html() method to display label values so the translate function can return formated content (#251). - Pass a label string as third arg to the `translate` function to differentiate the labels (#252). ## Fix + - Improve combined label position and show only one value if min==max (#245). # 2.6.0 (2016-01-31) + ## Features + - Add a `noSwitching` option to prevent the user from switching the min and max handles (#233). ## Bug fixes + - Refactor the internal `roundStep` function that was too strict (5d130f09d). # 2.5.0 (2016-01-24) + ## Features + - Add a `minRange` option to set a minimal range (#231). - Pass the slider values to the `onStart`, `onChange` and `onEnd` callbacks. - Rollback and improve the callback changes brought with 2.4.1 that were no applying the last update to the scope anymore. # 2.4.1 (2016-01-15) + ## Performance improvements -- Remove the $timeout call in the init method (#223). -- Remove the $timeout call in the onStart callback. -- Remove the $timeout call in the onChange callback (#229). + +- Remove the \$timeout call in the init method (#223). +- Remove the \$timeout call in the onStart callback. +- Remove the \$timeout call in the onChange callback (#229). # 2.4.0 (2015-12-30) + ## Features + - Add an `enforceRange` options to round the `rzSliderModel` and `rzSliderHigh` to the slider range even when modified from outside the slider.(#208). - Add a `ticksTooltip` option used to display a tooltip when a tick is hovered (#209). - Add an `onlyBindHandles` option to only bind events on slider handles (#212). - Add a `showSelectionBarEnd` option to display the selection bar after the value (#214). ## Bug fixes + - Fix reset of maxH element (#204). - Change the watchers order to prevent unwanted model modifications (#207). # 2.3.0 (2015-12-22) + ## Features + - Add keyboard support (activated by default with `keyboardSupport` set to true) (#191). - Add a `draggableRangeOnly` options (#203). # 2.2.0 (2015-12-17) + ## Features + - Add a `getSelectionBarColor` option to dynamically change the selection bar color (#197). ## Bug fixes + - Fix negative float values rendering (#190). # 2.1.0 (2015-11-29) + ## Features + - Add a `vertical` options to display vertical sliders (#185). - Pass the options.id to the onStart, onChange and onEnd callbacks (#182). - Force labels to stay contained within element containing slider (#175). ## Bug fixes + - add vendor-prefix to `display: flex` used by ticks (#160). # 2.0.0 (2015-11-12) + ## Breaking changes + - All attributes except `rzSliderModel` and `rzSliderHigh` are moved to `rzSliderOptions`. (See the new documentation in ReadMe) ## Features + - Add a `rzSliderOptions` attribute to pass options to the slider. - Add a `RzSliderOptions.options()` method to set global options. - Add a `scale` option to fix sliders displayed in an element that uses `transform: scale(0.5)`. @@ -238,41 +559,42 @@ rzslider { - Add a `ticksValuesTooltip` option that is used to display a tooltip on the ticks values (requires angular-ui bootstrap). # 1.1.0 (2015-11-07) + ## Features + - Configurable update interval (#153) ## Bug fixes + - Update floor label so that it hides correctly when using single slider. (#155) - Fix ticks values when step is a float. - Remove the delta checking in updateLowHandle because it leads to hard-to-debug bugs. # 1.0.0 (2015-10-13) + - Rename the NPM package from jusas-angularjs-slider to angularjs-slider because jusas was added by mistake during a PR.- Start to use semantic versioning. # 0.1.36 (2015-10-12) ## Features -* Separate the LESS variables from the main file to ease versioning of local customisations. - +- Separate the LESS variables from the main file to ease versioning of local customisations. # 0.1.35 (2015-10-08) ## Features -* Add enabled/disabled option for slider: `rz-slider-disabled="boolean"` - +- Add enabled/disabled option for slider: `rz-slider-disabled="boolean"` # 0.1.34 (2015-10-03) ## Features -* Support ticks for range sliders and slider with always visible bars. - +- Support ticks for range sliders and slider with always visible bars. # 0.1.33 (2015-10-02) ## Features -* Add a `rzSliderShowTicks` to show a tick on each step. -* Add a `rzSliderShowTicksValue ` to show a tick and its value on each step. +- Add a `rzSliderShowTicks` to show a tick on each step. +- Add a `rzSliderShowTicksValue` to show a tick and its value on each step. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..e67b3eb --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at valentin@hervi.eu. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3cbd476..73b2fc3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,24 +1,28 @@ ## Reporting issues + Make sure the report is accompanied by a reproducible demo. The ideal demo is created by forking [our standard jsFiddle](http://jsfiddle.net/cwhgLcjv/), adding your own code and stripping it down to an absolute minimum needed to demonstrate the bug. +## Prettier + +This project use [Prettier](https://github.com/prettier/prettier) for its code formatting. The goal is to be sure that all code pushed to this repository has the same style. A git hook is set up to format all the edited files on commit. ## Submittting a Pull Request To contribute to the project, please follow these steps: -1. Get approval for the idea by filing an issue and talking with me about the changes -2. Fork the repo -3. Make a branch for your change -4. Run `npm install` -5. Run `npm run test` -6. Make your changes -7. Test your changes (if you need a new test file, please copy the `test-template.js` file in the tests/specs folder.) -8. Run `npm run build` to generate the dist files -9. Run `git add -A` to add your changes -10. Run `npm run commit` (**Do not** use `git commit`) - follow the prompts to create your git message +1. Get approval for the idea by filing an issue and talking with me about the changes +2. Fork the repo +3. Make a branch for your change +4. Run `yarn` +5. Run `yarn test` +6. Make your changes +7. Test your changes (if you need a new test file, please copy the `test-template.js` file in the tests/specs folder.) +8. Run `yarn build` to generate the dist files +9. Run `git add -A` to add your changes +10. Run `yarn commit` (**Do not** use `git commit`) - follow the prompts to create your git message 11. Push your changes with `git push` 12. Create the Pull Request (a demo showing what the PR does is always good so you can fork [this fiddle](http://jsfiddle.net/cwhgLcjv/)) 13. If there are several commits, please [rebase](https://github.com/edx/edx-platform/wiki/How-to-Rebase-a-Pull-Request) and [squash](https://github.com/edx/edx-platform/wiki/How-to-Rebase-a-Pull-Request#squash-your-changes) everything to only get one commit. 14. Get merged and celebrate -**Working on your first Pull Request?** You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) +**Working on your first Pull Request?** You can learn how from this _free_ series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) diff --git a/Gruntfile.js b/Gruntfile.js index 8899fae..8d403f2 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,49 +1,47 @@ module.exports = function(grunt) { - var banner = '/*! <%= pkg.name %> - v<%= pkg.version %> - \n' + - ' (c) <%= pkg.author %> - \n'+ - ' <%= pkg.repository.url %> - \n' + - ' <%= grunt.template.today("yyyy-mm-dd") %> */\n', - minBanner = banner.replace(/\n/g, '') + '\n'; + var banner = + '/*! <%= pkg.name %> - v<%= pkg.version %> - \n' + + ' (c) <%= pkg.author %> - \n' + + ' <%= pkg.repository.url %> - \n' + + ' <%= grunt.template.today("yyyy-mm-dd") %> */\n', + minBanner = banner.replace(/\n/g, '') + '\n' // Project configuration. grunt.initConfig({ - pkg: grunt.file.readJSON('package.json'), minBanner: minBanner, recess: { options: { - compile: true + compile: true, }, slider: { src: ['src/rzslider.less'], - dest: 'dist/rzslider.css' + dest: 'dist/rzslider.css', }, min: { options: { compress: true, - banner: '<%= minBanner %>' + banner: '<%= minBanner %>', }, src: ['dist/rzslider.css'], - dest: 'dist/rzslider.min.css' - } + dest: 'dist/rzslider.min.css', + }, }, uglify: { options: { report: 'min', - banner: '<%= minBanner %>' + banner: '<%= minBanner %>', }, rzslider: { files: { - 'dist/rzslider.min.js': [ - 'dist/rzslider.js' - ] - } - } + 'dist/rzslider.min.js': ['dist/rzslider.js'], + }, + }, }, ngtemplates: { @@ -59,110 +57,158 @@ module.exports = function(grunt) { removeEmptyAttributes: true, removeRedundantAttributes: true, removeScriptTypeAttributes: true, - removeStyleLinkTypeAttributes: true + removeStyleLinkTypeAttributes: true, }, - module: 'rzModule', + module: 'rzSlider', url: function(url) { - return url.replace('src/', ''); + return url.replace('src/', '') }, bootstrap: function(module, script) { - return 'module.run(function($templateCache) {\n' + script + '\n});'; - } - } - } + return 'module.run(function($templateCache) {\n' + script + '\n});' + }, + }, + }, }, replace: { dist: { options: { - patterns: [{ - match: /\/\*templateReplacement\*\//, - replacement: '<%= grunt.file.read("temp/templates.js") %>' - }] + patterns: [ + { + match: /\/\*templateReplacement\*\//, + replacement: '<%= grunt.file.read("temp/templates.js") %>', + }, + ], }, - files: [{ - expand: true, - flatten: true, - src: ['src/rzslider.js'], - dest: 'dist/' - }] - } + files: [ + { + expand: true, + flatten: true, + src: ['src/rzslider.js', 'rzslider.d.ts'], + dest: 'dist/', + }, + ], + }, }, concat: { options: { stripBanners: true, - banner: banner + banner: banner, }, js: { src: ['dist/rzslider.js'], - dest: 'dist/rzslider.js' + dest: 'dist/rzslider.js', + options: { + footer: ';', // to prevent error when people concat the file and don't use the min version + }, }, css: { src: ['dist/rzslider.css'], - dest: 'dist/rzslider.css' - } + dest: 'dist/rzslider.css', + }, }, ngAnnotate: { options: { - singleQuotes: true + singleQuotes: true, }, rzslider: { - files: [{ - 'dist/rzslider.js': 'dist/rzslider.js' - }, { - expand: true, - src: ['dist/rzslider.js'] - }] - } + files: [ + { + 'dist/rzslider.js': 'dist/rzslider.js', + }, + { + expand: true, + src: ['dist/rzslider.js'], + }, + ], + }, }, watch: { all: { files: ['dist/*', 'demo/*'], options: { - livereload: true - } + livereload: true, + }, }, js: { files: ['src/*.js', 'src/*.html'], - tasks: ['js'] + tasks: ['js'], }, less: { files: ['src/*.less'], - tasks: ['css'] + tasks: ['css'], }, test: { files: ['src/*.js', 'tests/specs/**/*.js'], - tasks: ['test'] - } + tasks: ['test'], + }, }, serve: { options: { - port: 9000 - } + port: 9000, + }, }, karma: { unit: { configFile: 'karma.conf.js', - singleRun: true - } - } - }); + singleRun: true, + }, + }, + + copy: { + copyToSass: { + files: [ + { + expand: false, + src: ['dist/rzslider.css'], + dest: 'dist/rzslider.scss', + }, + ], + }, + }, + postcss: { + options: { + map: true, + processors: [ + require('autoprefixer')({ + browsers: ['> 1%', 'last 2 versions', 'Firefox ESR'], + }), + ], + }, + dist: { + src: 'dist/rzslider.css', + }, + }, + }) - grunt.loadNpmTasks('grunt-contrib-uglify'); - grunt.loadNpmTasks('grunt-recess'); - grunt.loadNpmTasks('grunt-angular-templates'); - grunt.loadNpmTasks('grunt-replace'); - grunt.loadNpmTasks('grunt-contrib-concat'); - grunt.loadNpmTasks('grunt-ng-annotate'); - grunt.loadNpmTasks('grunt-contrib-watch'); - grunt.loadNpmTasks('grunt-serve'); - grunt.loadNpmTasks('grunt-karma'); + grunt.loadNpmTasks('grunt-contrib-uglify') + grunt.loadNpmTasks('grunt-recess') + grunt.loadNpmTasks('grunt-angular-templates') + grunt.loadNpmTasks('grunt-replace') + grunt.loadNpmTasks('grunt-contrib-concat') + grunt.loadNpmTasks('grunt-ng-annotate') + grunt.loadNpmTasks('grunt-contrib-watch') + grunt.loadNpmTasks('grunt-serve') + grunt.loadNpmTasks('grunt-karma') + grunt.loadNpmTasks('grunt-contrib-copy') + grunt.loadNpmTasks('grunt-postcss') - grunt.registerTask('default', ['css', 'js']); - grunt.registerTask('test', ['karma']); + grunt.registerTask('default', ['css', 'js']) + grunt.registerTask('test', ['karma']) - grunt.registerTask('css', ['recess','concat:css']); - grunt.registerTask('js', ['ngtemplates', 'replace','concat:js', 'ngAnnotate', 'uglify']); -}; + grunt.registerTask('css', [ + 'recess', + 'concat:css', + 'postcss:dist', + 'copy:copyToSass', + ]) + grunt.registerTask('js', [ + 'ngtemplates', + 'replace', + 'concat:js', + 'ngAnnotate', + 'uglify', + ]) +} diff --git a/README.md b/README.md index ed9e77e..d75b95d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,11 @@ ## AngularJS 1.X slider directive with no external dependencies +Looking for an Angular version (> 1.X)? We got you covered: https://github.com/angular-slider/ngx-slider (Thanks [@piotrdz](https://github.com/piotrdz) :heart: )! + +
+ Status: +![Maintenance](https://img.shields.io/maintenance/support-only/2017.svg?style=flat-square) [![npm version](https://img.shields.io/npm/v/angularjs-slider.svg?style=flat-square)](https://www.npmjs.com/package/angularjs-slider) [![npm downloads](https://img.shields.io/npm/dm/angularjs-slider.svg?style=flat-square)](http://npm-stat.com/charts.html?package=angularjs-slider&from=2015-01-01) [![Build Status](https://img.shields.io/travis/angular-slider/angularjs-slider/master.svg?style=flat-square)](https://travis-ci.org/angular-slider/angularjs-slider) @@ -11,6 +16,8 @@ Links: [![Join the chat at https://gitter.im/rzajac/angularjs-slider](https://img.shields.io/badge/GITTER-join%20chat-1dce73.svg?style=flat-square)](https://gitter.im/rzajac/angularjs-slider?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) +> I'm looking for a maintainer for this project. I have lost my [Open Source Stamina](https://kentcdodds.com/blog/open-source-stamina) for this project and I will probably not push any code to this project anymore (unless, I find some motivation later). I will try to merge pull requests if some are submitted, but only if they are really clean. + Slider directive implementation for AngularJS 1.X, without any dependencies: [http://angular-slider.github.io/angularjs-slider](http://angular-slider.github.io/angularjs-slider/index.html). - Mobile friendly @@ -30,77 +37,109 @@ Slider directive implementation for AngularJS 1.X, without any dependencies: [ht ![image](https://cloud.githubusercontent.com/assets/2678610/11419099/7f4c0e76-9425-11e5-98c6-615412291df1.png) +**Custom style** +![image](https://cloud.githubusercontent.com/assets/2678610/21595997/df0bb468-d134-11e6-8272-008baffedccd.png) + ## Examples +- **Simple example for single slider:** [http://jsfiddle.net/ValentinH/qjvxn4fc/](http://jsfiddle.net/ValentinH/qjvxn4fc/) +- **Simple example for double slider:** [http://jsfiddle.net/ValentinH/hnyL2axs/](http://jsfiddle.net/ValentinH/hnyL2axs/) - **Various examples:** [http://angular-slider.github.io/angularjs-slider](http://angular-slider.github.io/angularjs-slider/index.html) - **Same examples with live code:** https://jsfiddle.net/ValentinH/954eve2L/ ## Reporting issues -Make sure the report is accompanied by a reproducible demo. The ideal demo is created by forking [our standard jsFiddle](http://jsfiddle.net/cwhgLcjv/), adding your own code and stripping it down to an absolute minimum needed to demonstrate the bug. + +Make sure the report is accompanied by a reproducible demo. The ideal demo is created by forking [our standard jsFiddle](http://jsfiddle.net/ValentinH/qjvxn4fc/), adding your own code and stripping it down to an absolute minimum needed to demonstrate the bug. ## Common issues + ### My slider is not rendered correctly on load + If the slider's parent element is not visible during slider initialization, the slider can't know when its parent becomes visible. For instance, when displaying a slider inside an element which visibility is toggled using ng-show, you need to send an event to force it to redraw when you set your ng-show to true. Here's an example of `refreshSlider` method that you should call whenever the slider becomes visible. + ```js -vm.refreshSlider = function () { - $timeout(function () { - $scope.$broadcast('rzSliderForceRender'); - }); -}; +vm.refreshSlider = function() { + $timeout(function() { + $scope.$broadcast('rzSliderForceRender') + }) +} ``` + if you get some flickering issues, you can try to replace to `$timeout` call by `$scope.$$postDigest` as suggested by @maknapp in [this issue](https://github.com/angular-slider/angularjs-slider/issues/79#issuecomment-219213647). -**ng-show-example**: http://jsfiddle.net/3jjye1cL/ +**ng-show-example**: http://jsfiddle.net/ValentinH/nzL6ax43/ -**UI-Boostrap tabs example**: http://jsfiddle.net/0f7sd7dw/ +**UI-Boostrap tabs example**: http://jsfiddle.net/ValentinH/bo23er5w/ ### Decimal value can't be typed in an input field linked to the slider + By default, the slider value is always rounded to the nearest step. A side effect is that when a input field is linked to the slider in order to enable a user to directly type a value, the value is rounded when it doesn't match the step. Even worse, when using decimal values, when a user will type "0.", the `.` will directly be truncated since the value is rounded. **Solution**: To avoid the value to be rounded, you need to use the `enforceStep: false` option. Thus, the value can be modified externally without taking care of the step. See [#298](https://github.com/angular-slider/angularjs-slider/issues/298). - ## Installation ### NPM + ``` npm i angularjs-slider ``` + +or + +``` +yarn add angularjs-slider +``` + +#### Typescript Support + +Typescript definition files are provided with this project. To use them, be sure you have the angular type definition peer dependency installed. + +``` +npm i @types/angular +``` + or + ### Bower + ``` $ bower install --save angularjs-slider ``` or + ### CDNJS + Directly use (replace `X.X.X` by the version you want to use): + - `https://cdnjs.cloudflare.com/ajax/libs/angularjs-slider/X.X.X/rzslider.min.js` - `https://cdnjs.cloudflare.com/ajax/libs/angularjs-slider/X.X.X/rzslider.min.css` - ## Project integration ### Imports + ```html - + - + ``` ### Module + ```javascript -angular.module('yourApp', ['rzModule']); +angular.module('yourApp', ['rzSlider']) ``` ### Single slider ```javascript // In your controller -$scope.priceSlider = 150; +$scope.priceSlider = 150 ``` ```html @@ -118,17 +157,19 @@ Above example would render a slider from 0 to 150. If you need floor and ceiling rz-slider-options="slider.options"> ``` + ```js $scope.slider = { value: 150, options: { floor: 0, - ceil: 450 - } -}; + ceil: 450, + }, +} ``` If you don't want to bother with an object set in your javascript file, you can pass an anonymous object literal to the slider options: + ```html
``` + ```js -$scope.value = 150; +$scope.value = 150 ``` ### Range slider @@ -149,9 +191,9 @@ $scope.slider = { max: 180, options: { floor: 0, - ceil: 450 - } -}; + ceil: 450, + }, +} ``` ```html @@ -176,6 +218,7 @@ $scope.slider = { > If you need to use a custom template, you can do so by providing a template URL to the `rz-slider-tpl-url` attribute. The default template is [this one](https://github.com/angular-slider/angularjs-slider/blob/master/src/rzSliderTpl.html). The following variables are available in the template as scope variables. + - `floorLabel`: The value set to `floor` in `rz-slider-options` - `ceilLabel`: The value set to `ceil` in `rz-slider-options` - `modelLabel`: The value set to `rz-slider-model` @@ -191,6 +234,7 @@ See the [Custom template to use angular directive for label](./demo/directiveInC > An object with all the other options of the slider. Each option can be updated at runtime and the slider will automatically be re-rendered. The default options are: + ```js { floor: 0, @@ -199,6 +243,8 @@ The default options are: precision: 0, minLimit: null, maxLimit: null, + restrictedRange: null, + skipRestrictedRangesWithArrowKeys: null, minRange: null, maxRange: null, pushRange: false, @@ -211,6 +257,7 @@ The default options are: draggableRangeOnly: false, showSelectionBar: false, showSelectionBarEnd: false, + showOuterSelectionBars: false, showSelectionBarFromValue: null, hidePointerLabels: false, hideLimitLabels: false, @@ -220,6 +267,7 @@ The default options are: interval: 350, showTicks: false, showTicksValues: false, + ticksArray: null, ticksTooltip: null, ticksValuesTooltip: null, vertical: false, @@ -236,11 +284,22 @@ The default options are: onChange: null, onEnd: null, rightToLeft: false, + reversedControls: false, boundPointerLabels: true, mergeRangeLabelsIfSame: false, - customTemplateScope: null + labelOverlapSeparator: ' - ', + customTemplateScope: null, + logScale: false, + customValueToPosition: null, + customPositionToValue: null, + selectionBarGradient: null, + ariaLabel: null, + ariaLabelledBy: null, + ariaLabelHigh: null, + ariaLabelledByHigh: null, + disableAnimation: false } -```` +``` **floor** - _Number (defaults to 0)_: Minimum value for a slider. @@ -248,27 +307,33 @@ The default options are: **step** - _Number (defaults to 1)_: Step between each value. -**precision** - _Number (defaults to 0)_: The precision to display values with. The `toFixed()` is used internally for this. +**precision** - _Number (defaults to 0)_: The precision to display values with (number of decimals to be displayed). The `toFixed()` is used internally for this. **minLimit** - _Number (defaults to null)_: The minimum value authorized on the slider. **maxLimit** - _Number (defaults to null)_: The maximum value authorized on the slider. -**minRange** - _Number (defaults to null)_: The minimum range authorized on the slider. *Applies to range slider only.* +**restrictedRange** - _Object (defaults to null)_: Has two _Number_ properties, _from_ and _to_ that determine the bounds of an area that is not authorized for values. Can also use an array. _Applies to range slider only._ -**maxRange** - _Number (defaults to null)_: The maximum range authorized on the slider. *Applies to range slider only.* +**skipRestrictedRangesWithArrowKeys** - _Boolean (defaults to null)_: Set to true to skip restricted ranges with arrow keys. -**pushRange** - _Boolean (defaults to false)_: Set to true to have a push behavior. When the min handle goes above the max, the max is moved as well (and vice-versa). The range between min and max is defined by the `step` option (defaults to 1) and can also be override by the `minRange` option. *Applies to range slider only.* +**minRange** - _Number (defaults to null)_: The minimum range authorized on the slider. _Applies to range slider only._ + +**maxRange** - _Number (defaults to null)_: The maximum range authorized on the slider. _Applies to range slider only._ + +**pushRange** - _Boolean (defaults to false)_: Set to true to have a push behavior. When the min handle goes above the max, the max is moved as well (and vice-versa). The range between min and max is defined by the `step` option (defaults to 1) and can also be override by the `minRange` option. _Applies to range slider only._ **translate** - _Function(value, sliderId, label)_: Custom translate function. Use this if you want to translate values displayed on the slider. `sliderId` can be used to determine the slider for which we are translating the value. `label` is a string that can take the following values: - - *'model'*: the model label - - *'high'*: the high label - - *'floor'*: the floor label - - *'ceil'*: the ceil label - - *'tick-value'*: the ticks labels + +- _'model'_: the model label +- _'high'_: the high label +- _'floor'_: the floor label +- _'ceil'_: the ceil label +- _'tick-value'_: the ticks labels For example if you want to display dollar amounts instead of just numbers: + ```html
``` + ```js $scope.slider = { value: 0, @@ -283,13 +349,14 @@ $scope.slider = { floor: 0, ceil: 100, translate: function(value) { - return '$' + value; - } - } -}; + return '$' + value + }, + }, +} ``` -**getLegend** - _Function(value, sliderId)_: Use to display legend under ticks. The function will be called with each tick value and returned content will be displayed under the tick as a legend. If the returned value is null, then no legend is displayed under the corresponding tick. +**getLegend** - _Function(value, sliderId)_: Use to display legend under ticks (thus, it needs to be used along with `showTicks` or `showTicksValues`). The function will be called with each tick value and returned content will be displayed under the tick as a legend. If the returned value is null, then no legend is displayed under the corresponding tick.You can also directly provide the legend values in the `stepsArray` option. + > In order to get enough space to display legends under the slider, you need to add the `with-legend` class to the slider component. The default margin-bottom is then 40px which is enough for legends that are displayed on 2 lines. If you need more, simply override the style for the class. **id** - _Any (defaults to null)_: If you want to use the same `translate` function for several sliders, just set the `id` to anything you want, and it will be passed to the `translate(value, sliderId)` function as a second argument. @@ -297,32 +364,36 @@ $scope.slider = { **stepsArray** - _Array_: If you want to display a slider with non linear/number steps. Just pass an array with each slider value and that's it; the floor, ceil and step settings of the slider will be computed automatically. By default, the `rz-slider-model` and `rz-slider-high` values will be the value of the selected item in the stepsArray. They can also be bound to the index of the selected item by setting the `bindIndexForStepsArray` option to `true`. -`stepsArray` can also be an array of objects like: +`stepsArray` can also be an array of objects or Dates like: ```js -[ - {value: 'A'}, // the display value will be *A* - {value: 10, legend: 'Legend for 10'} // the display value will be 10 and a legend will be displayed under the corresponding tick. +;[ + { value: 'A' }, // the display value will be *A* + { value: 10, legend: 'Legend for 10' }, // the display value will be 10 and a legend will be displayed under the corresponding tick. + new Date(2016, 7, 12), // the display value will be the default format of Date. To customize it, use the `translate` option + { value: new Date(2016, 7, 12), legend: 'Legend for 10' }, // same as above but with a legend ] -```` +``` **bindIndexForStepsArray** - _Boolean (defaults to false)_: Set to true to bind the index of the selected item to `rz-slider-model` and `rz-slider-high`. (This was the default behavior prior to 4.0). -**draggableRange** - _Boolean (defaults to false)_: When set to true and using a range slider, the range can be dragged by the selection bar. *Applies to range slider only.* +**draggableRange** - _Boolean (defaults to false)_: When set to true and using a range slider, the range can be dragged by the selection bar. _Applies to range slider only._ -**draggableRangeOnly** - _Boolean (defaults to false)_: Same as draggableRange but the slider range can't be changed. *Applies to range slider only.* +**draggableRangeOnly** - _Boolean (defaults to false)_: Same as draggableRange but the slider range can't be changed. _Applies to range slider only._ **showSelectionBar** - _Boolean (defaults to false)_: Set to true to always show the selection bar before the slider handle. **showSelectionBarEnd** - _Boolean (defaults to false)_: Set to true to always show the selection bar after the slider handle. +**showOuterSelectionBars** - _Boolean (defaults to false)_: Only for range slider. Set to true to visualize in different colour the areas on the left/right (top/bottom for vertical range slider) of selection bar between the handles. + **showSelectionBarFromValue** - _Number (defaults to null)_: Set a number to draw the selection bar between this value and the slider handle. -**getSelectionBarColor** - _Function(value) or Function(minVal, maxVal) (defaults to null)_: Function that returns the current color of the selection bar. *If your color won't changed, don't use this option but set it through CSS.* If the returned color depends on a model value (either `rzScopeModel`or `'rzSliderHigh`), you should use the argument passed to the function. Indeed, when the function is called, there is no certainty that the model has already been updated. +**getSelectionBarColor** - _Function(value) or Function(minVal, maxVal) (defaults to null)_: Function that returns the current color of the selection bar. _If your color won't changed, don't use this option but set it through CSS._ If the returned color depends on a model value (either `rzScopeModel`or `'rzSliderHigh`), you should use the argument passed to the function. Indeed, when the function is called, there is no certainty that the model has already been updated. **getTickColor** - _Function(value) (defaults to null)_: Function that returns the color of a tick. showTicks must be enabled. -**getPointerColor** - _Function(value, pointerType) (defaults to null)_: Function that returns the current color of a pointer. *If your color won't changed, don't use this option but set it through CSS.* If the returned color depends on a model value (either `rzScopeModel`or `'rzSliderHigh`), you should use the argument passed to the function. Indeed, when the function is called, there is no certainty that the model has already been updated. To handle range slider pointers independently, you should evaluate pointerType within the given function where "min" stands for `rzScopeModel` and "max" for `rzScopeHigh` values. +**getPointerColor** - _Function(value, pointerType) (defaults to null)_: Function that returns the current color of a pointer. _If your color won't changed, don't use this option but set it through CSS._ If the returned color depends on a model value (either `rzScopeModel`or `'rzSliderHigh`), you should use the argument passed to the function. Indeed, when the function is called, there is no certainty that the model has already been updated. To handle range slider pointers independently, you should evaluate pointerType within the given function where "min" stands for `rzScopeModel` and "max" for `rzScopeHigh` values. **hidePointerLabels** - _Boolean (defaults to false)_: Set to true to hide pointer labels @@ -340,6 +411,8 @@ Just pass an array with each slider value and that's it; the floor, ceil and ste **showTicksValues** - _Boolean or Number (defaults to false)_: Set to true to display a tick and the step value for each step of the slider. Set a number to display ticks and the step value at intermediate positions. This number corresponds to the step between each tick. +**ticksArray** - _Array (defaults to null)_: Use to display ticks at specific positions. The array contains the index of the ticks that should be displayed. For example, [0, 1, 5] will display a tick for the first, second and sixth values. It also supports the `{ value: 0, legend: 'Bad' }` format to display a legend for each tick. + **ticksTooltip** - _Function(value) (defaults to null)_: (requires angular-ui bootstrap) Used to display a tooltip when a tick is hovered. Set to a function that returns the tooltip content for a given value. **ticksValuesTooltip** - _Function(value) (defaults to null)_: Same as `ticksTooltip` but for ticks values. @@ -350,7 +423,7 @@ Just pass an array with each slider value and that's it; the floor, ceil and ste **enforceRange** - _Boolean (defaults to false)_: Set to true to round the `rzSliderModel` and `rzSliderHigh` to the slider range even when modified from outside the slider. When set to false, if the model values are modified from outside the slider, they are not rounded but they are still rendered properly on the slider. -**noSwitching** - _Boolean (defaults to false)_: Set to true to prevent to user from switching the min and max handles. *Applies to range slider only.* +**noSwitching** - _Boolean (defaults to false)_: Set to true to prevent to user from switching the min and max handles. _Applies to range slider only._ **onlyBindHandles** - _Boolean (defaults to false)_: Set to true to only bind events on slider handles. @@ -358,6 +431,8 @@ Just pass an array with each slider value and that's it; the floor, ceil and ste **mergeRangeLabelsIfSame** - _Boolean (defaults to false)_: Set to true to merge the range labels if they are the same. For instance, if min and max are 50, the label will be "50 - 50" if `mergeRangeLabelsIfSame: false`, else "50". +**labelOverlapSeparator** - _String (defaults to ' - ')_: Separator to use when the labels overlap. For instance, if min and max are -1 and 1, the label will be "-1 .. 1" if `labelOverlapSeparator: ' .. '`. + **onStart** - _Function(sliderId, modelValue, highValue, pointerType)_: Function to be called when a slider update is started. If an id was set in the options, then it's passed to this callback. This callback is called before any update on the model. `pointerType` is either 'min' or 'max' depending on which handle is used. **onChange** - _Function(sliderId, modelValue, highValue, pointerType)_: Function to be called when rz-slider-model or rz-slider-high change. If an id was set in the options, then it's passed to this callback. `pointerType` is either 'min' or 'max' depending on which handle is used. @@ -370,23 +445,50 @@ Just pass an array with each slider value and that's it; the floor, ceil and ste _Changing this value at runtime is not currently supported._ **keyboardSupport** - _Boolean (defaults to true)_: Handles are focusable (on click or with tab) and can be modified using the following keyboard controls: - - Left/bottom arrows: -1 - - Right/top arrows: +1 - - Page-down: -10% - - Page-up: +10% - - Home: minimum value - - End: maximum value + +- Left/bottom arrows: -1 +- Right/top arrows: +1 +- Page-down: -10% +- Page-up: +10% +- Home: minimum value +- End: maximum value + +**reversedControls** - _Boolean (defaults to false)_: Set to true to reverse keyboard navigation: + +- Right/top arrows: -1 +- Left/bottom arrows: +1 +- Page-up: -10% +- Page-down: +10% +- End: minimum value +- Home: maximum value **customTemplateScope** - _Object (default to null)_: The properties defined in this object will be exposed in the slider template under `custom.X`. +**logScale** - _Boolean (defaults to false)_: Set to true to use a logarithmic scale to display the slider. + +For custom scales: + +**customValueToPosition** - _Function(val, minVal, maxVal): percent_: Function that returns the position on the slider for a given value. The position must be a percentage between 0 and 1. + +**customPositionToValue** - _Function(percent, minVal, maxVal): value_: Function that returns the value for a given position on the slider. The position is a percentage between 0 and 1. + +**selectionBarGradient** - _Object (default to null)_: Use to display the selection bar as a gradient. The given object must contain `from` and `to` properties which are colors. + +**ariaLabel and ariaLabelHigh** - _String (default to null)_: Use to add a label directly to the slider(s) for accessibility. Adds the `aria-label` attribute. + +**ariaLabelledBy and ariaLabelledByHigh** - _String (default to null)_: Use instead of ariaLabel and ariaLabelHigh to reference the id of an element which will be used to label the slider(s). Adds the `aria-labelledby` attribute. + +**disableAnimation** - _Boolean (defaults to false)_: Set to true to disable slider animation. + ## Change default options + If you want the change the default options for all the sliders displayed in your application, you can set them using the `RzSliderOptions.options()` method: + ```js -angular.module('App', ['rzModule']) - .run(function( RzSliderOptions ) { - // show ticks for all sliders - RzSliderOptions.options( { showTicks: true } ); - }); +angular.module('App', ['rzSlider']).run(function(RzSliderOptions) { + // show ticks for all sliders + RzSliderOptions.options({ showTicks: true }) +}) ``` ## Slider events @@ -398,9 +500,9 @@ You can also force redraw with **rzSliderForceRender** event. At the end of each "slide" slider emits `slideEnded` event. ```javascript -$scope.$on("slideEnded", function() { - // user finished sliding a handle -}); +$scope.$on('slideEnded', function() { + // user finished sliding a handle +}) ``` ## Browser support diff --git a/bower.json b/bower.json index a785a4e..e1e88c1 100644 --- a/bower.json +++ b/bower.json @@ -1,29 +1,18 @@ { "name": "angularjs-slider", - "version": "5.5.1", + "version": "7.0.1", "homepage": "https://github.com/angular-slider/angularjs-slider", "authors": [ "Rafal Zajac ", - "Valentin Hervieu ", + "Valentin Hervieu ", "Jussi Saarivirta " ], - "description": "AngularJS slider directive with no external dependencies. Mobile friendly!", - "main": [ - "dist/rzslider.js", - "dist/rzslider.css" - ], - "keywords": [ - "angularjs", - "slider" - ], + "description": + "AngularJS slider directive with no external dependencies. Mobile friendly!", + "main": ["dist/rzslider.js", "dist/rzslider.css"], + "keywords": ["angularjs", "slider"], "license": "MIT", - "ignore": [ - "**/.*", - "node_modules", - "bower_components", - "test", - "tests" - ], + "ignore": ["**/.*", "node_modules", "bower_components", "test", "tests"], "devDependencies": { "angular": "~1.4.0" } diff --git a/cypress.json b/cypress.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/cypress.json @@ -0,0 +1 @@ +{} diff --git a/cypress/integration/simple_spec.js b/cypress/integration/simple_spec.js new file mode 100644 index 0000000..72b1f20 --- /dev/null +++ b/cypress/integration/simple_spec.js @@ -0,0 +1,7 @@ +describe("My First Test", function() { + it("Visits the debug page", function() { + cy.visit("http://127.0.0.1:8080/demo/debug.html"); + cy.get("li.rz-tick:nth-of-type(8)").click(); + cy.get(".rz-model-value").should("have.text", "35"); + }); +}); diff --git a/demo/debug.html b/demo/debug.html new file mode 100644 index 0000000..b1b5c8f --- /dev/null +++ b/demo/debug.html @@ -0,0 +1,34 @@ + + + + + + + AngularJS Touch Slider + + + + + + + + + +
+ +
+

Debug slider

+ +
+ +
+ + + + + + + diff --git a/demo/demo.css b/demo/demo.css index 41cd771..9ebf616 100644 --- a/demo/demo.css +++ b/demo/demo.css @@ -1,13 +1,45 @@ -* { margin: 0; padding: 0; } -body { font-family: 'Open Sans', sans-serif; color: #1f2636; font-size: 14px; padding-bottom: 40px; } -header { background: #0db9f0; color: #fff; margin: -40px; margin-bottom: 40px; text-align: center; padding: 40px 0; } -h1 { font-weight: 300; } -h2 {margin-bottom:10px;} -.wrapper { background: #fff; padding: 40px; } -article { margin-bottom: 10px; } -.tab-pane{ +* { + margin: 0; + padding: 0; +} + +body { + font-family: 'Open Sans', sans-serif; + color: #1f2636; + font-size: 14px; + padding-bottom: 40px; +} + +header { + background: #0db9f0; + color: #fff; + margin: -40px; + margin-bottom: 40px; + text-align: center; + padding: 40px 0; +} + +h1 { + font-weight: 300; +} + +h2 { + margin-bottom: 10px; +} + +.wrapper { + background: #fff; + padding: 40px; +} + +article { + margin-bottom: 10px; +} + +.tab-pane { padding-top: 10px; } + .field-title { width: 100px; } @@ -15,6 +47,52 @@ article { margin-bottom: 10px; } .vertical-sliders { margin: 0; } + .vertical-sliders > div { height: 250px; } + +.custom-slider.rzslider .rz-bar { + background: #ffe4d1; + height: 2px; +} + +.custom-slider.rzslider .rz-selection { + background: orange; +} + +.custom-slider.rzslider .rz-pointer { + width: 8px; + height: 16px; + top: auto; /* to remove the default positioning */ + bottom: 0; + background-color: #333; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} + +.custom-slider.rzslider .rz-pointer:after { + display: none; +} + +.custom-slider.rzslider .rz-bubble { + bottom: 14px; +} + +.custom-slider.rzslider .rz-limit { + font-weight: bold; + color: orange; +} + +.custom-slider.rzslider .rz-tick { + width: 1px; + height: 10px; + margin-left: 4px; + border-radius: 0; + background: #ffe4d1; + top: -1px; +} + +.custom-slider.rzslider .rz-tick.rz-selected { + background: orange; +} diff --git a/demo/demo.js b/demo/demo.js index 08e3660..0911e87 100644 --- a/demo/demo.js +++ b/demo/demo.js @@ -1,10 +1,21 @@ -var app = angular.module('rzSliderDemo', ['rzModule', 'ui.bootstrap']); +var app = angular.module('rzSliderDemo', ['rzSlider', 'ui.bootstrap']) -app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { +app.controller('MainCtrl', function($scope, $rootScope, $timeout, $uibModal) { //Minimal slider config $scope.minSlider = { - value: 10 - }; + value: 10, + } + $scope.debugSlider = { + value: 50, + options: { + showTicks: 5, + showTicksValues: 10, + floor: 0, + ceil: 100, + step: 5, + showSelectionBar: true, + }, + } //Range slider config $scope.rangeSlider = { @@ -13,9 +24,20 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { options: { floor: 0, ceil: 100, - step: 1 - } - }; + step: 1, + }, + } + + $scope.customSlider = { + minValue: 10, + maxValue: 90, + options: { + floor: 0, + ceil: 100, + step: 10, + showTicks: true, + }, + } //Range slider with minLimit and maxLimit config $scope.minMaxLimitSlider = { @@ -25,9 +47,40 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { ceil: 100, step: 1, minLimit: 10, - maxLimit: 90 - } - }; + maxLimit: 90, + }, + } + + $scope.restrictedRangeSlider = { + minValue: 10, + maxValue: 90, + options: { + restrictedRange: { + from: 30, + to: 70, + }, + floor: 0, + ceil: 100, + step: 1, + }, + } + + // Restricted range with multiple array and the feature skipRestrictedRangesWithArrowKeys + $scope.multipleRestrictedRangeSlider = { + minValue: 10, + maxValue: 90, + options: { + restrictedRange: [ + { from: 20, to: 30 }, + { from: 50, to: 60 }, + { from: 75, to: 85 }, + ], + skipRestrictedRangesWithArrowKeys: true, + floor: 0, + ceil: 100, + step: 1, + }, + } //Range slider with minRange and maxRange config $scope.minMaxRangeSlider = { @@ -38,9 +91,9 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { ceil: 100, step: 1, minRange: 10, - maxRange: 50 - } - }; + maxRange: 50, + }, + } //Range slider with noSwitching config $scope.noSwitchingSlider = { @@ -50,9 +103,9 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { floor: 0, ceil: 100, step: 1, - noSwitching: true - } - }; + noSwitching: true, + }, + } //Range slider with minRange and pushRange config $scope.minPushRangeSlider = { @@ -62,26 +115,37 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { floor: 0, ceil: 100, minRange: 10, - pushRange: true - } - }; + pushRange: true, + }, + } + + $scope.outerBarsRangeSlider = { + minValue: 30, + maxValue: 70, + options: { + floor: 0, + ceil: 100, + step: 1, + showOuterSelectionBars: true, + }, + } //Slider with selection bar $scope.slider_visible_bar = { value: 10, options: { - showSelectionBar: true - } - }; + showSelectionBar: true, + }, + } //Slider with selection bar end $scope.slider_visible_bar_end = { value: 10, options: { ceil: 100, - showSelectionBarEnd: true - } - }; + showSelectionBarEnd: true, + }, + } //Slider with selection bar from value $scope.slider_visible_bar_from_value = { @@ -90,9 +154,23 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { floor: -100, ceil: 100, step: 10, - showSelectionBarFromValue: 0 - } - }; + showSelectionBarFromValue: 0, + }, + } + + //Slider with selection bar gradient + $scope.gradient_slider_bar = { + minValue: 0, + maxValue: 33, + options: { + ceil: 100, + showSelectionBar: true, + selectionBarGradient: { + from: 'white', + to: '#0db9f0', + }, + }, + } //Slider with selection bar color $scope.color_slider_bar = { @@ -100,53 +178,26 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { options: { showSelectionBar: true, getSelectionBarColor: function(value) { - if (value <= 3) - return 'red'; - if (value <= 6) - return 'orange'; - if (value <= 9) - return 'yellow'; - return '#2AE02A'; - } - } - }; + if (value <= 3) return 'red' + if (value <= 6) return 'orange' + if (value <= 9) return 'yellow' + return '#2AE02A' + }, + }, + } //Slider with pointer color $scope.color_slider_pointer = { value: 12, options: { getPointerColor: function(value) { - if (value <= 3) - return 'red'; - if (value <= 6) - return 'orange'; - if (value <= 9) - return 'yellow'; - return '#2AE02A'; - } - } - }; - - //Slider with custom tick formatting - $scope.slider_tick_color = { - value: 0, - options: { - ceil: 1200, - floor: 0, - step: 50, - showSelectionBar: true, - showTicks: true, - getTickColor: function(value){ - if (value < 300) - return 'red'; - if (value < 600) - return 'orange'; - if (value < 900) - return 'yellow'; - return '#2AE02A'; - } - } - }; + if (value <= 3) return 'red' + if (value <= 6) return 'orange' + if (value <= 9) return 'yellow' + return '#2AE02A' + }, + }, + } //Slider config with floor, ceil and step $scope.slider_floor_ceil = { @@ -154,9 +205,44 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { options: { floor: 10, ceil: 100, - step: 5 - } - }; + step: 5, + }, + } + + //Slider config with logarithmic scale + $scope.slider_log = { + value: 1, + options: { + floor: 1, + ceil: 100, + logScale: true, + showTicks: true, + }, + } + + //Slider config with custom scale + $scope.slider_custom_scale = { + value: 50, + options: { + floor: 0, + ceil: 100, + step: 10, + showTicksValues: true, + customValueToPosition: function(val, minVal, maxVal) { + val = Math.sqrt(val) + minVal = Math.sqrt(minVal) + maxVal = Math.sqrt(maxVal) + var range = maxVal - minVal + return (val - minVal) / range + }, + customPositionToValue: function(percent, minVal, maxVal) { + minVal = Math.sqrt(minVal) + maxVal = Math.sqrt(maxVal) + var value = percent * (maxVal - minVal) + minVal + return Math.pow(value, 2) + }, + }, + } //Right to left slider with floor, ceil and step $scope.slider_floor_ceil_rtl = { @@ -165,34 +251,34 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { floor: 10, ceil: 100, step: 5, - rightToLeft: true - } - }; + rightToLeft: true, + }, + } //Slider config with callbacks $scope.slider_callbacks = { value: 100, options: { onStart: function(id, newValue, highValue, pointerType) { - console.info('start', id, newValue, pointerType); - $scope.otherData.start = newValue * 10; + console.info('start', id, newValue, pointerType) + $scope.otherData.start = newValue * 10 }, onChange: function(id, newValue, highValue, pointerType) { - console.info('change', id, newValue, pointerType); - $scope.otherData.change = newValue * 10; + console.info('change', id, newValue, pointerType) + $scope.otherData.change = newValue * 10 }, onEnd: function(id, newValue, highValue, pointerType) { - console.info('end', id, newValue, pointerType); - $scope.otherData.end = newValue * 10; - } - } - }; + console.info('end', id, newValue, pointerType) + $scope.otherData.end = newValue * 10 + }, + }, + } $scope.otherData = { start: 0, change: 0, - end: 0 - }; + end: 0, + } //Slider config with custom display function $scope.slider_translate = { @@ -203,11 +289,11 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { floor: 0, id: 'translate-slider', translate: function(value, id, which) { - console.info(value, id, which); - return '$' + value; - } - } - }; + console.info(value, id, which) + return '$' + value + }, + }, + } //Slider config with custom display function using html formatting $scope.slider_translate_html = { @@ -219,32 +305,23 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { translate: function(value, sliderId, label) { switch (label) { case 'model': - return 'Min price: $' + value; + return 'Min price: $' + value case 'high': - return 'Max price: $' + value; + return 'Max price: $' + value default: return '$' + value } - } - } - }; - //Slider config with angular directive inside custom template - $scope.slider_custom_directive_inside_template = { - minValue: 20, - maxValue: 80, - options: { - floor: 0, - ceil: 100 - } - }; + }, + }, + } //Slider config with steps array of letters $scope.slider_alphabet = { value: 'E', options: { - stepsArray: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('') - } - }; + stepsArray: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''), + }, + } //Slider with ticks $scope.slider_ticks = { @@ -252,9 +329,19 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { options: { ceil: 10, floor: 0, - showTicks: true - } - }; + showTicks: true, + }, + } + + //Slider with ticks at specific positions + $scope.slider_ticks_array = { + value: 5, + options: { + ceil: 10, + floor: 0, + ticksArray: [0, 1, 3, 8, 10], + }, + } //Slider with ticks and tooltip $scope.slider_ticks_tooltip = { @@ -264,10 +351,10 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { floor: 0, showTicks: true, ticksTooltip: function(v) { - return 'Tooltip for ' + v; - } - } - }; + return 'Tooltip for ' + v + }, + }, + } //Slider with ticks and values $scope.slider_ticks_values = { @@ -277,10 +364,10 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { floor: 0, showTicksValues: true, ticksValuesTooltip: function(v) { - return 'Tooltip for ' + v; - } - } - }; + return 'Tooltip for ' + v + }, + }, + } //Range slider with ticks and values $scope.range_slider_ticks_values = { @@ -289,9 +376,9 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { options: { ceil: 10, floor: 0, - showTicksValues: true - } - }; + showTicksValues: true, + }, + } //Slider with ticks at intermediate positions $scope.slider_ticks_at = { @@ -299,9 +386,9 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { options: { ceil: 1000, floor: 0, - showTicks: 100 - } - }; + showTicks: 100, + }, + } //Slider with ticks and values at intermediate positions $scope.slider_ticks_values_at = { @@ -309,9 +396,9 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { options: { ceil: 1000, floor: 0, - showTicksValues: 100 - } - }; + showTicksValues: 100, + }, + } //Slider with ticks values and legend $scope.slider_ticks_legend = { @@ -319,18 +406,51 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { options: { showTicksValues: true, stepsArray: [ - {value: 1, legend: 'Very poor'}, - {value: 2}, - {value: 3, legend: 'Fair'}, - {value: 4}, - {value: 5, legend: 'Average'}, - {value: 6}, - {value: 7, legend: 'Good'}, - {value: 8}, - {value: 9, legend: 'Excellent'} - ] - } - }; + { value: 1, legend: 'Very poor' }, + { value: 2 }, + { value: 3, legend: 'Fair' }, + { value: 4 }, + { value: 5, legend: 'Average' }, + { value: 6 }, + { value: 7, legend: 'Good' }, + { value: 8 }, + { value: 9, legend: 'Excellent' }, + ], + }, + } + + //Slider with custom tick formatting + $scope.slider_tick_color = { + value: 0, + options: { + ceil: 1200, + floor: 0, + step: 50, + showSelectionBar: true, + showTicks: true, + getTickColor: function(value) { + if (value < 300) return 'red' + if (value < 600) return 'orange' + if (value < 900) return 'yellow' + return '#2AE02A' + }, + }, + } + + var dates = [] + for (var i = 1; i <= 31; i++) { + dates.push(new Date(2016, 7, i)) + } + $scope.slider_dates = { + value: new Date(2016, 7, 10), + options: { + stepsArray: dates, + translate: function(date) { + if (date != null) return date.toDateString() + return '' + }, + }, + } //Slider with draggable range $scope.slider_draggable_range = { @@ -339,9 +459,9 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { options: { ceil: 10, floor: 0, - draggableRange: true - } - }; + draggableRange: true, + }, + } //Slider with draggable range only $scope.slider_draggable_range_only = { @@ -350,9 +470,9 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { options: { ceil: 10, floor: 0, - draggableRangeOnly: true - } - }; + draggableRangeOnly: true, + }, + } //Vertical sliders $scope.verticalSlider1 = { @@ -360,27 +480,28 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { options: { floor: 0, ceil: 10, - vertical: true - } - }; + vertical: true, + }, + } $scope.verticalSlider2 = { minValue: 20, maxValue: 80, options: { floor: 0, ceil: 100, - vertical: true - } - }; + vertical: true, + }, + } $scope.verticalSlider3 = { value: 5, options: { floor: 0, ceil: 10, vertical: true, - showTicks: true - } - }; + ticksArray: [0, 1, 5, 10], + showTicksValues: true, + }, + } $scope.verticalSlider4 = { minValue: 1, maxValue: 5, @@ -388,18 +509,18 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { floor: 0, ceil: 6, vertical: true, - showTicksValues: true - } - }; + showTicksValues: true, + }, + } $scope.verticalSlider5 = { value: 50, options: { floor: 0, ceil: 100, vertical: true, - showSelectionBar: true - } - }; + showSelectionBar: true, + }, + } $scope.verticalSlider6 = { value: 6, options: { @@ -409,10 +530,10 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { showSelectionBar: true, showTicksValues: true, ticksValuesTooltip: function(v) { - return 'Tooltip for ' + v; - } - } - }; + return 'Tooltip for ' + v + }, + }, + } //Read-only slider $scope.read_only_slider = { @@ -420,105 +541,115 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { options: { ceil: 100, floor: 0, - readOnly: true - } - }; + readOnly: true, + }, + } //Disabled slider $scope.disabled_slider = { - value: 50, + minValue: 20, + maxValue: 80, options: { ceil: 100, floor: 0, - disabled: true - } - }; + showTicks: 10, + disabled: true, + draggableRange: true, + }, + } // Slider inside ng-show - $scope.visible = false; + $scope.visible = false $scope.slider_toggle = { value: 5, options: { ceil: 10, - floor: 0 - } - }; + floor: 0, + }, + } $scope.toggle = function() { - $scope.visible = !$scope.visible; + $scope.visible = !$scope.visible $timeout(function() { - $scope.$broadcast('rzSliderForceRender'); - }); - }; + $scope.$broadcast('rzSliderForceRender') + }) + } //Slider inside modal $scope.percentages = { normal: { - low: 15 + low: 15, }, range: { low: 10, - high: 50 - } - }; + high: 50, + }, + } $scope.openModal = function() { - var modalInstance = $modal.open({ + var modalInstance = $uibModal.open({ templateUrl: 'sliderModal.html', - controller: function($scope, $modalInstance, values) { - $scope.percentages = JSON.parse(JSON.stringify(values)); //Copy of the object in order to keep original values in $scope.percentages in parent controller. - + controller: function($scope, $uibModalInstance, values) { + $scope.percentages = JSON.parse(JSON.stringify(values)) //Copy of the object in order to keep original values in $scope.percentages in parent controller. var formatToPercentage = function(value) { - return value + '%'; - }; + return value + '%' + } $scope.percentages.normal.options = { floor: 0, ceil: 100, translate: formatToPercentage, - showSelectionBar: true - }; + showSelectionBar: true, + } $scope.percentages.range.options = { floor: 0, ceil: 100, - translate: formatToPercentage - }; + translate: formatToPercentage, + } $scope.ok = function() { - $modalInstance.close($scope.percentages); - }; + $uibModalInstance.close($scope.percentages) + } $scope.cancel = function() { - $modalInstance.dismiss(); - }; + $uibModalInstance.dismiss() + } }, resolve: { values: function() { - return $scope.percentages; - } - } - }); + return $scope.percentages + }, + }, + }) modalInstance.result.then(function(percentages) { - $scope.percentages = percentages; - }); + $scope.percentages = percentages + }) modalInstance.rendered.then(function() { - $rootScope.$broadcast('rzSliderForceRender'); //Force refresh sliders on render. Otherwise bullets are aligned at left side. - }); - }; - + $rootScope.$broadcast('rzSliderForceRender') //Force refresh sliders on render. Otherwise bullets are aligned at left side. + }) + } //Slider inside tabs $scope.tabSliders = { slider1: { - value: 100 + value: 100, }, slider2: { - value: 200 - } - }; + value: 200, + }, + } $scope.refreshSlider = function() { $timeout(function() { - $scope.$broadcast('rzSliderForceRender'); - }); - }; + $scope.$broadcast('rzSliderForceRender') + }) + } + //Slider config with angular directive inside custom template + $scope.slider_custom_directive_inside_template = { + minValue: 20, + maxValue: 80, + options: { + floor: 0, + ceil: 100, + }, + } //Slider with draggable range $scope.slider_all_options = { @@ -534,28 +665,30 @@ app.controller('MainCtrl', function($scope, $rootScope, $timeout, $modal) { readOnly: false, disabled: false, showTicks: false, - showTicksValues: false - } - }; + showTicksValues: false, + vertical: false, + }, + } $scope.toggleHighValue = function() { if ($scope.slider_all_options.maxValue != null) { - $scope.slider_all_options.maxValue = undefined; + $scope.slider_all_options.maxValue = undefined } else { - $scope.slider_all_options.maxValue = 8; + $scope.slider_all_options.maxValue = 8 } } -}); +}) app.directive('clickableLabel', function() { return { restrict: 'E', - scope: {label: '='}, + scope: { label: '=' }, replace: true, - template: "", - link: function(scope, elem, attrs){ - scope.onclick = function(label){ - alert("I'm " + label); - }; - } - }; -}); + template: + "", + link: function(scope, elem, attrs) { + scope.onclick = function(label) { + alert("I'm " + label) + } + }, + } +}) diff --git a/demo/directiveInCustomTemplate.html b/demo/directiveInCustomTemplate.html index a2d001a..6009f92 100644 --- a/demo/directiveInCustomTemplate.html +++ b/demo/directiveInCustomTemplate.html @@ -1,8 +1,17 @@
+ + + + + + - - - + + + + + + {{floorLabel}} diff --git a/demo/index.html b/demo/index.html index 6c9a3b4..59c8798 100644 --- a/demo/index.html +++ b/demo/index.html @@ -36,6 +36,16 @@

Range slider

> +
+

Slider with custom style

+ +
+

Range slider with min limit set to 10 and max limit set to 90

Range slider with min limit set to 10 and max limit set to 90 >
+
+

Range slider with restricted area from 30 to 70

+ +
+ +
+

Range slider with multiple restricted area from 20 to 30, 50 to 60 and 75 to 85 +
+ and the feature that skip restricted ranges with arrow keys +

+ +
+

Range slider with minimum range of 10 and maximum of 50

Range slider with minimum range of 10 and pushRange option >
+
+

Range slider with coloured bars outside the selected range

+ +
+

Slider with visible selection bar

Slider with visible selection bar from a value >
+
+

Slider with selection bar gradient

+ +
+

Slider with dynamic selection bar colors

Slider with dynamic pointer color
-

Slider with dynamic tick color

+

Slider with custom floor/ceil/step

-

Slider with custom floor/ceil/step

+

Slider with logarithmic scale

+
+ +
+

Slider with custom scale

+
@@ -165,16 +222,6 @@

Slider with custom display function using html formatting

> -
-

Slider with angular directive inside custom template

- -
-

Slider with Alphabet

Current letter: {{ slider_alphabet.value }} @@ -192,6 +239,14 @@

Slider with ticks

>
+
+

Slider with ticks at specific positions

+ +
+

Slider with ticks and tooltips

Slider with ticks values and legend >
+
+

Slider with dynamic tick color

+ +
+ +
+

Slider with date values

+ +
+

Slider with draggable range

Vertical sliders

Disabled slider

@@ -328,14 +400,24 @@

Sliders inside a modal

Sliders inside tabs

Price 1: {{tabSliders.slider1.value}}

Price 2: {{tabSliders.slider2.value}}

- - + + - - + + - - + + + + +
+

Slider with angular directive inside custom template

+
@@ -359,7 +441,9 @@

Slider with all options demo




- +
+
+
, Valentin Hervieu , Jussi Saarivirta , Angelin Sirbu - +/*! angularjs-slider - v7.1.0 - + (c) Rafal Zajac , Valentin Hervieu , Jussi Saarivirta , Angelin Sirbu - https://github.com/angular-slider/angularjs-slider - - 2016-09-22 */ + 2022-05-26 */ .rzslider { position: relative; display: inline-block; @@ -15,6 +15,10 @@ user-select: none; } +.rzslider.noanimate * { + transition: none !important; +} + .rzslider.with-legend { margin-bottom: 40px; } @@ -28,6 +32,22 @@ background-color: #d8e0f3; } +.rzslider[disabled] .rz-draggable { + cursor: not-allowed; +} + +.rzslider[disabled] .rz-selection { + background: #8b91a2; +} + +.rzslider[disabled] .rz-tick { + cursor: not-allowed; +} + +.rzslider[disabled] .rz-tick.rz-selected { + background: #8b91a2; +} + .rzslider span { position: absolute; display: inline-block; @@ -48,9 +68,10 @@ padding-top: 16px; margin-top: -16px; box-sizing: border-box; + transition: all linear 0.3s; } -.rzslider .rz-bar-wrapper.rz-draggable { +.rzslider .rz-draggable { cursor: move; } @@ -60,17 +81,32 @@ width: 100%; height: 4px; background: #d8e0f3; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; + border-radius: 2px; +} + +.rzslider .rz-bar-wrapper.rz-transparent .rz-bar { + background: transparent; +} + +.rzslider .rz-bar-wrapper.rz-left-out-selection .rz-bar { + background: #df002d; +} + +.rzslider .rz-bar-wrapper.rz-right-out-selection .rz-bar { + background: #03a688; } -.rzslider .rz-bar.rz-selection { +.rzslider .rz-selection { z-index: 2; background: #0db9f0; - -webkit-border-radius: 2px; - -moz-border-radius: 2px; - border-radius: 2px; + border-radius: 2px; + transition: background-color linear 0.3s; +} + +.rzslider .rz-restricted { + z-index: 3; + background: #ff0000; + border-radius: 2px; } .rzslider .rz-pointer { @@ -80,9 +116,8 @@ height: 32px; cursor: pointer; background-color: #0db9f0; - -webkit-border-radius: 16px; - -moz-border-radius: 16px; - border-radius: 16px; + border-radius: 16px; + transition: all linear 0.3s; } .rzslider .rz-pointer:after { @@ -92,9 +127,7 @@ width: 8px; height: 8px; background: #ffffff; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; + border-radius: 4px; content: ''; } @@ -115,14 +148,12 @@ padding: 1px 3px; color: #55637d; cursor: default; -} - -.rzslider .rz-bubble.rz-selection { - top: 16px; + transition: all linear 0.3s; } .rzslider .rz-bubble.rz-limit { color: #55637d; + transition: none; } .rzslider .rz-ticks { @@ -130,40 +161,43 @@ top: -3px; left: 0; z-index: 1; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; width: 100%; height: 0; - padding: 0 11px; margin: 0; list-style: none; box-sizing: border-box; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; } -.rzslider .rz-ticks .rz-tick { +.rzslider .rz-ticks-values-under .rz-tick-value { + top: auto; + bottom: -32px; +} + +.rzslider .rz-tick { + position: absolute; + top: 0; + left: 0; width: 10px; height: 10px; + margin-left: 11px; text-align: center; cursor: pointer; background: #d8e0f3; border-radius: 50%; + transition: background-color linear 0.3s; } -.rzslider .rz-ticks .rz-tick.rz-selected { +.rzslider .rz-tick.rz-selected { background: #0db9f0; } -.rzslider .rz-ticks .rz-tick .rz-tick-value { +.rzslider .rz-tick-value { position: absolute; top: -30px; transform: translate(-50%, 0); } -.rzslider .rz-ticks .rz-tick .rz-tick-legend { +.rzslider .rz-tick-legend { position: absolute; top: 24px; max-width: 50px; @@ -171,11 +205,6 @@ transform: translate(-50%, 0); } -.rzslider .rz-ticks.rz-ticks-values-under .rz-tick-value { - top: initial; - bottom: -40px; -} - .rzslider.rz-vertical { position: relative; width: 4px; @@ -219,43 +248,37 @@ margin-left: 3px; } -.rzslider.rz-vertical .rz-bubble.rz-selection { - top: auto; - left: 16px !important; -} - .rzslider.rz-vertical .rz-ticks { top: 0; left: -3px; z-index: 1; width: 0; height: 100%; - padding: 11px 0; - -webkit-flex-direction: column-reverse; - -ms-flex-direction: column-reverse; - flex-direction: column-reverse; } -.rzslider.rz-vertical .rz-ticks .rz-tick { +.rzslider.rz-vertical .rz-tick { + margin-top: 11px; + margin-left: auto; vertical-align: middle; } -.rzslider.rz-vertical .rz-ticks .rz-tick .rz-tick-value { - top: initial; - left: 22px; +.rzslider.rz-vertical .rz-tick-value { + top: auto; + left: 24px; transform: translate(0, -28%); } -.rzslider.rz-vertical .rz-ticks .rz-tick .rz-tick-legend { - top: initial; +.rzslider.rz-vertical .rz-tick-legend { + top: auto; right: 24px; max-width: none; white-space: nowrap; transform: translate(0, -28%); } -.rzslider.rz-vertical .rz-ticks.rz-ticks-values-under .rz-tick-value { - right: 12px; - bottom: initial; - left: initial; -} \ No newline at end of file +.rzslider.rz-vertical .rz-ticks-values-under .rz-tick-value { + right: 24px; + bottom: auto; + left: auto; +} +/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInJ6c2xpZGVyLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O2NBR2M7QUFDZDtFQUNFLG1CQUFtQjtFQUNuQixzQkFBc0I7RUFDdEIsWUFBWTtFQUNaLFlBQVk7RUFDWixzQkFBc0I7RUFDdEIsdUJBQXVCO0VBQ3ZCLDBCQUFrQjtLQUFsQix1QkFBa0I7TUFBbEIsc0JBQWtCO1VBQWxCLGtCQUFrQjtDQUNuQjs7QUFFRDtFQUNFLDRCQUE0QjtDQUM3Qjs7QUFFRDtFQUNFLG9CQUFvQjtDQUNyQjs7QUFFRDtFQUNFLG9CQUFvQjtDQUNyQjs7QUFFRDtFQUNFLG9CQUFvQjtFQUNwQiwwQkFBMEI7Q0FDM0I7O0FBRUQ7RUFDRSxvQkFBb0I7Q0FDckI7O0FBRUQ7RUFDRSxvQkFBb0I7Q0FDckI7O0FBRUQ7RUFDRSxvQkFBb0I7Q0FDckI7O0FBRUQ7RUFDRSxvQkFBb0I7Q0FDckI7O0FBRUQ7RUFDRSxtQkFBbUI7RUFDbkIsc0JBQXNCO0VBQ3RCLG9CQUFvQjtDQUNyQjs7QUFFRDtFQUNFLFlBQVk7RUFDWixhQUFhO0VBQ2IsV0FBVztDQUNaOztBQUVEO0VBQ0UsUUFBUTtFQUNSLFdBQVc7RUFDWCxZQUFZO0VBQ1osYUFBYTtFQUNiLGtCQUFrQjtFQUNsQixrQkFBa0I7RUFDbEIsdUJBQXVCO0VBQ3ZCLDRCQUE0QjtDQUM3Qjs7QUFFRDtFQUNFLGFBQWE7Q0FDZDs7QUFFRDtFQUNFLFFBQVE7RUFDUixXQUFXO0VBQ1gsWUFBWTtFQUNaLFlBQVk7RUFDWixvQkFBb0I7RUFHWixtQkFBbUI7Q0FDNUI7O0FBRUQ7RUFDRSx3QkFBd0I7Q0FDekI7O0FBRUQ7RUFDRSxvQkFBb0I7Q0FDckI7O0FBRUQ7RUFDRSxvQkFBb0I7Q0FDckI7O0FBRUQ7RUFDRSxXQUFXO0VBQ1gsb0JBQW9CO0VBR1osbUJBQW1CO0VBQzNCLHlDQUF5QztDQUMxQzs7QUFFRDtFQUNFLFdBQVc7RUFDWCxvQkFBb0I7RUFHWixtQkFBbUI7Q0FDNUI7O0FBRUQ7RUFDRSxXQUFXO0VBQ1gsV0FBVztFQUNYLFlBQVk7RUFDWixhQUFhO0VBQ2IsZ0JBQWdCO0VBQ2hCLDBCQUEwQjtFQUdsQixvQkFBb0I7RUFDNUIsNEJBQTRCO0NBQzdCOztBQUVEO0VBQ0UsbUJBQW1CO0VBQ25CLFVBQVU7RUFDVixXQUFXO0VBQ1gsV0FBVztFQUNYLFlBQVk7RUFDWixvQkFBb0I7RUFHWixtQkFBbUI7RUFDM0IsWUFBWTtDQUNiOztBQUVEO0VBQ0UsMEJBQTBCO0NBQzNCOztBQUVEO0VBQ0UsV0FBVztDQUNaOztBQUVEO0VBQ0UsMEJBQTBCO0NBQzNCOztBQUVEO0VBQ0UsYUFBYTtFQUNiLGlCQUFpQjtFQUNqQixlQUFlO0VBQ2YsZ0JBQWdCO0VBQ2hCLDRCQUE0QjtDQUM3Qjs7QUFFRDtFQUNFLGVBQWU7RUFDZixpQkFBaUI7Q0FDbEI7O0FBRUQ7RUFDRSxtQkFBbUI7RUFDbkIsVUFBVTtFQUNWLFFBQVE7RUFDUixXQUFXO0VBQ1gsWUFBWTtFQUNaLFVBQVU7RUFDVixVQUFVO0VBQ1YsaUJBQWlCO0VBQ2pCLHVCQUF1QjtDQUN4Qjs7QUFFRDtFQUNFLFVBQVU7RUFDVixjQUFjO0NBQ2Y7O0FBRUQ7RUFDRSxtQkFBbUI7RUFDbkIsT0FBTztFQUNQLFFBQVE7RUFDUixZQUFZO0VBQ1osYUFBYTtFQUNiLGtCQUFrQjtFQUNsQixtQkFBbUI7RUFDbkIsZ0JBQWdCO0VBQ2hCLG9CQUFvQjtFQUNwQixtQkFBbUI7RUFDbkIseUNBQXlDO0NBQzFDOztBQUVEO0VBQ0Usb0JBQW9CO0NBQ3JCOztBQUVEO0VBQ0UsbUJBQW1CO0VBQ25CLFdBQVc7RUFDWCw4QkFBOEI7Q0FDL0I7O0FBRUQ7RUFDRSxtQkFBbUI7RUFDbkIsVUFBVTtFQUNWLGdCQUFnQjtFQUNoQixvQkFBb0I7RUFDcEIsOEJBQThCO0NBQy9COztBQUVEO0VBQ0UsbUJBQW1CO0VBQ25CLFdBQVc7RUFDWCxhQUFhO0VBQ2IsV0FBVztFQUNYLGVBQWU7RUFDZix5QkFBeUI7Q0FDMUI7O0FBRUQ7RUFDRSxZQUFZO0VBQ1osYUFBYTtFQUNiLFdBQVc7Q0FDWjs7QUFFRDtFQUNFLFVBQVU7RUFDVixRQUFRO0VBQ1IsWUFBWTtFQUNaLGFBQWE7RUFDYixvQkFBb0I7RUFDcEIsb0JBQW9CO0NBQ3JCOztBQUVEO0VBQ0UsVUFBVTtFQUNWLFdBQVc7RUFDWCxXQUFXO0VBQ1gsYUFBYTtDQUNkOztBQUVEO0VBQ0UsVUFBVTtFQUNWLFVBQVU7RUFDVix1QkFBdUI7Q0FDeEI7O0FBRUQ7RUFDRSxVQUFVO0VBQ1Ysc0JBQXNCO0VBQ3RCLGlCQUFpQjtDQUNsQjs7QUFFRDtFQUNFLE9BQU87RUFDUCxXQUFXO0VBQ1gsV0FBVztFQUNYLFNBQVM7RUFDVCxhQUFhO0NBQ2Q7O0FBRUQ7RUFDRSxpQkFBaUI7RUFDakIsa0JBQWtCO0VBQ2xCLHVCQUF1QjtDQUN4Qjs7QUFFRDtFQUNFLFVBQVU7RUFDVixXQUFXO0VBQ1gsOEJBQThCO0NBQy9COztBQUVEO0VBQ0UsVUFBVTtFQUNWLFlBQVk7RUFDWixnQkFBZ0I7RUFDaEIsb0JBQW9CO0VBQ3BCLDhCQUE4QjtDQUMvQjs7QUFFRDtFQUNFLFlBQVk7RUFDWixhQUFhO0VBQ2IsV0FBVztDQUNaIiwiZmlsZSI6InJ6c2xpZGVyLmNzcyIsInNvdXJjZXNDb250ZW50IjpbIi8qISBhbmd1bGFyanMtc2xpZGVyIC0gdjcuMS4wIC0gXG4gKGMpIFJhZmFsIFphamFjIDxyemFqYWNAZ21haWwuY29tPiwgVmFsZW50aW4gSGVydmlldSA8dmFsZW50aW5AaGVydmkuZXU+LCBKdXNzaSBTYWFyaXZpcnRhIDxqdXNhc2lAZ21haWwuY29tPiwgQW5nZWxpbiBTaXJidSA8YW5nZWxpbi5zaXJidUBnbWFpbC5jb20+IC0gXG4gaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXItc2xpZGVyL2FuZ3VsYXJqcy1zbGlkZXIgLSBcbiAyMDIyLTA1LTI2ICovXG4ucnpzbGlkZXIge1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogNHB4O1xuICBtYXJnaW46IDM1cHggMCAxNXB4IDA7XG4gIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG4gIHVzZXItc2VsZWN0OiBub25lO1xufVxuXG4ucnpzbGlkZXIubm9hbmltYXRlICoge1xuICB0cmFuc2l0aW9uOiBub25lICFpbXBvcnRhbnQ7XG59XG5cbi5yenNsaWRlci53aXRoLWxlZ2VuZCB7XG4gIG1hcmdpbi1ib3R0b206IDQwcHg7XG59XG5cbi5yenNsaWRlcltkaXNhYmxlZF0ge1xuICBjdXJzb3I6IG5vdC1hbGxvd2VkO1xufVxuXG4ucnpzbGlkZXJbZGlzYWJsZWRdIC5yei1wb2ludGVyIHtcbiAgY3Vyc29yOiBub3QtYWxsb3dlZDtcbiAgYmFja2dyb3VuZC1jb2xvcjogI2Q4ZTBmMztcbn1cblxuLnJ6c2xpZGVyW2Rpc2FibGVkXSAucnotZHJhZ2dhYmxlIHtcbiAgY3Vyc29yOiBub3QtYWxsb3dlZDtcbn1cblxuLnJ6c2xpZGVyW2Rpc2FibGVkXSAucnotc2VsZWN0aW9uIHtcbiAgYmFja2dyb3VuZDogIzhiOTFhMjtcbn1cblxuLnJ6c2xpZGVyW2Rpc2FibGVkXSAucnotdGljayB7XG4gIGN1cnNvcjogbm90LWFsbG93ZWQ7XG59XG5cbi5yenNsaWRlcltkaXNhYmxlZF0gLnJ6LXRpY2sucnotc2VsZWN0ZWQge1xuICBiYWNrZ3JvdW5kOiAjOGI5MWEyO1xufVxuXG4ucnpzbGlkZXIgc3BhbiB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xufVxuXG4ucnpzbGlkZXIgLnJ6LWJhc2Uge1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAxMDAlO1xuICBwYWRkaW5nOiAwO1xufVxuXG4ucnpzbGlkZXIgLnJ6LWJhci13cmFwcGVyIHtcbiAgbGVmdDogMDtcbiAgei1pbmRleDogMTtcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogMzJweDtcbiAgcGFkZGluZy10b3A6IDE2cHg7XG4gIG1hcmdpbi10b3A6IC0xNnB4O1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICB0cmFuc2l0aW9uOiBhbGwgbGluZWFyIDAuM3M7XG59XG5cbi5yenNsaWRlciAucnotZHJhZ2dhYmxlIHtcbiAgY3Vyc29yOiBtb3ZlO1xufVxuXG4ucnpzbGlkZXIgLnJ6LWJhciB7XG4gIGxlZnQ6IDA7XG4gIHotaW5kZXg6IDE7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDRweDtcbiAgYmFja2dyb3VuZDogI2Q4ZTBmMztcbiAgLXdlYmtpdC1ib3JkZXItcmFkaXVzOiAycHg7XG4gICAgIC1tb3otYm9yZGVyLXJhZGl1czogMnB4O1xuICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDJweDtcbn1cblxuLnJ6c2xpZGVyIC5yei1iYXItd3JhcHBlci5yei10cmFuc3BhcmVudCAucnotYmFyIHtcbiAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG59XG5cbi5yenNsaWRlciAucnotYmFyLXdyYXBwZXIucnotbGVmdC1vdXQtc2VsZWN0aW9uIC5yei1iYXIge1xuICBiYWNrZ3JvdW5kOiAjZGYwMDJkO1xufVxuXG4ucnpzbGlkZXIgLnJ6LWJhci13cmFwcGVyLnJ6LXJpZ2h0LW91dC1zZWxlY3Rpb24gLnJ6LWJhciB7XG4gIGJhY2tncm91bmQ6ICMwM2E2ODg7XG59XG5cbi5yenNsaWRlciAucnotc2VsZWN0aW9uIHtcbiAgei1pbmRleDogMjtcbiAgYmFja2dyb3VuZDogIzBkYjlmMDtcbiAgLXdlYmtpdC1ib3JkZXItcmFkaXVzOiAycHg7XG4gICAgIC1tb3otYm9yZGVyLXJhZGl1czogMnB4O1xuICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgdHJhbnNpdGlvbjogYmFja2dyb3VuZC1jb2xvciBsaW5lYXIgMC4zcztcbn1cblxuLnJ6c2xpZGVyIC5yei1yZXN0cmljdGVkIHtcbiAgei1pbmRleDogMztcbiAgYmFja2dyb3VuZDogI2ZmMDAwMDtcbiAgLXdlYmtpdC1ib3JkZXItcmFkaXVzOiAycHg7XG4gICAgIC1tb3otYm9yZGVyLXJhZGl1czogMnB4O1xuICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDJweDtcbn1cblxuLnJ6c2xpZGVyIC5yei1wb2ludGVyIHtcbiAgdG9wOiAtMTRweDtcbiAgei1pbmRleDogMztcbiAgd2lkdGg6IDMycHg7XG4gIGhlaWdodDogMzJweDtcbiAgY3Vyc29yOiBwb2ludGVyO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjMGRiOWYwO1xuICAtd2Via2l0LWJvcmRlci1yYWRpdXM6IDE2cHg7XG4gICAgIC1tb3otYm9yZGVyLXJhZGl1czogMTZweDtcbiAgICAgICAgICBib3JkZXItcmFkaXVzOiAxNnB4O1xuICB0cmFuc2l0aW9uOiBhbGwgbGluZWFyIDAuM3M7XG59XG5cbi5yenNsaWRlciAucnotcG9pbnRlcjphZnRlciB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgdG9wOiAxMnB4O1xuICBsZWZ0OiAxMnB4O1xuICB3aWR0aDogOHB4O1xuICBoZWlnaHQ6IDhweDtcbiAgYmFja2dyb3VuZDogI2ZmZmZmZjtcbiAgLXdlYmtpdC1ib3JkZXItcmFkaXVzOiA0cHg7XG4gICAgIC1tb3otYm9yZGVyLXJhZGl1czogNHB4O1xuICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgY29udGVudDogJyc7XG59XG5cbi5yenNsaWRlciAucnotcG9pbnRlcjpob3ZlcjphZnRlciB7XG4gIGJhY2tncm91bmQtY29sb3I6ICNmZmZmZmY7XG59XG5cbi5yenNsaWRlciAucnotcG9pbnRlci5yei1hY3RpdmUge1xuICB6LWluZGV4OiA0O1xufVxuXG4ucnpzbGlkZXIgLnJ6LXBvaW50ZXIucnotYWN0aXZlOmFmdGVyIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogIzQ1MWFmZjtcbn1cblxuLnJ6c2xpZGVyIC5yei1idWJibGUge1xuICBib3R0b206IDE2cHg7XG4gIHBhZGRpbmc6IDFweCAzcHg7XG4gIGNvbG9yOiAjNTU2MzdkO1xuICBjdXJzb3I6IGRlZmF1bHQ7XG4gIHRyYW5zaXRpb246IGFsbCBsaW5lYXIgMC4zcztcbn1cblxuLnJ6c2xpZGVyIC5yei1idWJibGUucnotbGltaXQge1xuICBjb2xvcjogIzU1NjM3ZDtcbiAgdHJhbnNpdGlvbjogbm9uZTtcbn1cblxuLnJ6c2xpZGVyIC5yei10aWNrcyB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgdG9wOiAtM3B4O1xuICBsZWZ0OiAwO1xuICB6LWluZGV4OiAxO1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAwO1xuICBtYXJnaW46IDA7XG4gIGxpc3Qtc3R5bGU6IG5vbmU7XG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG59XG5cbi5yenNsaWRlciAucnotdGlja3MtdmFsdWVzLXVuZGVyIC5yei10aWNrLXZhbHVlIHtcbiAgdG9wOiBhdXRvO1xuICBib3R0b206IC0zMnB4O1xufVxuXG4ucnpzbGlkZXIgLnJ6LXRpY2sge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogMDtcbiAgbGVmdDogMDtcbiAgd2lkdGg6IDEwcHg7XG4gIGhlaWdodDogMTBweDtcbiAgbWFyZ2luLWxlZnQ6IDExcHg7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgY3Vyc29yOiBwb2ludGVyO1xuICBiYWNrZ3JvdW5kOiAjZDhlMGYzO1xuICBib3JkZXItcmFkaXVzOiA1MCU7XG4gIHRyYW5zaXRpb246IGJhY2tncm91bmQtY29sb3IgbGluZWFyIDAuM3M7XG59XG5cbi5yenNsaWRlciAucnotdGljay5yei1zZWxlY3RlZCB7XG4gIGJhY2tncm91bmQ6ICMwZGI5ZjA7XG59XG5cbi5yenNsaWRlciAucnotdGljay12YWx1ZSB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgdG9wOiAtMzBweDtcbiAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgMCk7XG59XG5cbi5yenNsaWRlciAucnotdGljay1sZWdlbmQge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogMjRweDtcbiAgbWF4LXdpZHRoOiA1MHB4O1xuICB3aGl0ZS1zcGFjZTogbm9ybWFsO1xuICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSgtNTAlLCAwKTtcbn1cblxuLnJ6c2xpZGVyLnJ6LXZlcnRpY2FsIHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICB3aWR0aDogNHB4O1xuICBoZWlnaHQ6IDEwMCU7XG4gIHBhZGRpbmc6IDA7XG4gIG1hcmdpbjogMCAyMHB4O1xuICB2ZXJ0aWNhbC1hbGlnbjogYmFzZWxpbmU7XG59XG5cbi5yenNsaWRlci5yei12ZXJ0aWNhbCAucnotYmFzZSB7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDEwMCU7XG4gIHBhZGRpbmc6IDA7XG59XG5cbi5yenNsaWRlci5yei12ZXJ0aWNhbCAucnotYmFyLXdyYXBwZXIge1xuICB0b3A6IGF1dG87XG4gIGxlZnQ6IDA7XG4gIHdpZHRoOiAzMnB4O1xuICBoZWlnaHQ6IDEwMCU7XG4gIHBhZGRpbmc6IDAgMCAwIDE2cHg7XG4gIG1hcmdpbjogMCAwIDAgLTE2cHg7XG59XG5cbi5yenNsaWRlci5yei12ZXJ0aWNhbCAucnotYmFyIHtcbiAgYm90dG9tOiAwO1xuICBsZWZ0OiBhdXRvO1xuICB3aWR0aDogNHB4O1xuICBoZWlnaHQ6IDEwMCU7XG59XG5cbi5yenNsaWRlci5yei12ZXJ0aWNhbCAucnotcG9pbnRlciB7XG4gIHRvcDogYXV0bztcbiAgYm90dG9tOiAwO1xuICBsZWZ0OiAtMTRweCAhaW1wb3J0YW50O1xufVxuXG4ucnpzbGlkZXIucnotdmVydGljYWwgLnJ6LWJ1YmJsZSB7XG4gIGJvdHRvbTogMDtcbiAgbGVmdDogMTZweCAhaW1wb3J0YW50O1xuICBtYXJnaW4tbGVmdDogM3B4O1xufVxuXG4ucnpzbGlkZXIucnotdmVydGljYWwgLnJ6LXRpY2tzIHtcbiAgdG9wOiAwO1xuICBsZWZ0OiAtM3B4O1xuICB6LWluZGV4OiAxO1xuICB3aWR0aDogMDtcbiAgaGVpZ2h0OiAxMDAlO1xufVxuXG4ucnpzbGlkZXIucnotdmVydGljYWwgLnJ6LXRpY2sge1xuICBtYXJnaW4tdG9wOiAxMXB4O1xuICBtYXJnaW4tbGVmdDogYXV0bztcbiAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcbn1cblxuLnJ6c2xpZGVyLnJ6LXZlcnRpY2FsIC5yei10aWNrLXZhbHVlIHtcbiAgdG9wOiBhdXRvO1xuICBsZWZ0OiAyNHB4O1xuICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSgwLCAtMjglKTtcbn1cblxuLnJ6c2xpZGVyLnJ6LXZlcnRpY2FsIC5yei10aWNrLWxlZ2VuZCB7XG4gIHRvcDogYXV0bztcbiAgcmlnaHQ6IDI0cHg7XG4gIG1heC13aWR0aDogbm9uZTtcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoMCwgLTI4JSk7XG59XG5cbi5yenNsaWRlci5yei12ZXJ0aWNhbCAucnotdGlja3MtdmFsdWVzLXVuZGVyIC5yei10aWNrLXZhbHVlIHtcbiAgcmlnaHQ6IDI0cHg7XG4gIGJvdHRvbTogYXV0bztcbiAgbGVmdDogYXV0bztcbn0iXX0= */ \ No newline at end of file diff --git a/dist/rzslider.d.ts b/dist/rzslider.d.ts new file mode 100644 index 0000000..e9ec697 --- /dev/null +++ b/dist/rzslider.d.ts @@ -0,0 +1,217 @@ +/** + * Typescript type definition file. + */ + +import * as angular from "angular"; + +declare module "angular" { + export namespace RzSlider { + type RzLabelType = "model"|"high"|"floor"|"ceil"|"tick-value"; + type RzPointerType = "min"|"max"; + type RzCallback = (id: string, modelValue: number, highValue: number, pointerType: "min"|"max") => void; + type RzTranslate = (value: number, sliderId: string, label: RzLabelType) => string; + + /** RZ slider options typing */ + interface RzOptions { + /** Number (defaults to 0): Minimum value for a slider. */ + floor?: number; + /** Number (defaults to rz-slider-modelvalue): Maximum value for a slider. */ + ceil?: number; + /** Number (defaults to 1): Step between each value. */ + step?: number; + /** Number (defaults to 0): The precision to display values with. The toFixed() is used internally for this. */ + precision?: number; + /** Number (defaults to null): The minimum value authorized on the slider. */ + minLimit?: number; + /** Number (defaults to null): The maximum value authorized on the slider. */ + maxLimit?: number; + /** + * Object(defaults to null): Has two _Number_ properties, _from_ and _to_ that determine + * the bounds of an area that is not authorized for values. _Applies to range slider only._ + */ + restrictedRange?: { from: number, to: number } | Array<{from: number, to: number}>; + /** Number (defaults to null): The minimum range authorized on the slider. Applies to range slider only. Can also use an array.*/ + skipRestrictedRangesWithArrowKeys?: boolean + /** Set to true to skip restricted ranges with arrow keys. */ + minRange?: number; + /** Number (defaults to null): The maximum range authorized on the slider. Applies to range slider only. */ + maxRange?: number; + /** + * Boolean (defaults to false): Set to true to have a push behavior. When the min handle goes above the max, + * the max is moved as well (and vice-versa). The range between min and max is defined by the step option + * (defaults to 1) and can also be override by the minRange option. Applies to range slider only. + */ + pushRange?: boolean; + /** + * Custom translate function. Use this if you want to translate values displayed on the slider. + * sliderId can be used to determine the slider for which we are translating the value. + * label is a string that can take the following values: + * 'model': the model label + * 'high': the high label + * 'floor': the floor label + * 'ceil': the ceil label + * 'tick-value': the ticks labels + */ + translate?: RzTranslate; + /** + * Function(value, sliderId): Use to display legend under ticks. The function will be called with each tick + * value and returned content will be displayed under the tick as a legend. If the returned value is null, + * then no legend is displayed under the corresponding tick. + */ + getLegend?: (value: number, sliderId: string) => string; + /** + * Any (defaults to null): If you want to use the same translate function for several sliders, + * just set the id to anything you want, and it will be passed to the translate(value, sliderId) + * function as a second argument. + */ + id?: string; + /** + * Array: If you want to display a slider with non linear/number steps. Just pass an array with each slider + * value and that's it; the floor, ceil and step settings of the slider will be computed automatically. + * By default, the rz-slider-model and rz-slider-high values will be the value of the selected item in the stepsArray. + * They can also be bound to the index of the selected item by setting the bindIndexForStepsArray option to true. + * + * stepsArray can also be an array of objects like: + * [ + * {value: 'A'}, // the display value will be *A* + * {value: 10, legend: 'Legend for 10'} // the display value will be 10 and a legend will be displayed under the corresponding tick. + * ] + */ + stepsArray?: number[] | Array<{value: number; legend?: string}>; + /** + * Boolean (defaults to false): Set to true to bind the index of the selected item to rz-slider-model and rz-slider-high. + * (This was the default behavior prior to 4.0). + */ + bindIndexForStepsArray?: boolean; + /** Boolean (defaults to false): When set to true and using a range slider, the range can be dragged by the selection bar. Applies to range slider only. */ + draggableRange?: boolean; + /** Boolean (defaults to false): Same as draggableRange but the slider range can't be changed. Applies to range slider only. */ + draggableRangeOnly?: boolean; + /** Boolean (defaults to false): Set to true to always show the selection bar before the slider handle. */ + showSelectionBar?: boolean; + /** Boolean (defaults to false): Set to true to always show the selection bar after the slider handle. */ + showSelectionBarEnd?: boolean; + /** Boolean (defaults to false): Only for range slider. Set to true to visualize in different colour the areas on the left/right (top/bottom for vertical range slider) of selection bar between the handles. */ + showOuterSelectionBars?: boolean; + /** Number (defaults to null): Set a number to draw the selection bar between this value and the slider handle. */ + showSelectionBarFromValue?: number; + /** + * Function(value) or Function(minVal, maxVal) (defaults to null): Function that returns the current color of the + * selection bar. If your color won't changed, don't use this option but set it through CSS. If the returned color + * depends on a model value (either rzScopeModelor 'rzSliderHigh), you should use the argument passed to the function. + * Indeed, when the function is called, there is no certainty that the model has already been updated. + */ + getSelectionBarColor?: (minVal: number, maxVal?: number) => string; + /** Function(value) (defaults to null): Function that returns the color of a tick. showTicks must be enabled. */ + getTickColor?: (value: number) => string; + /** + * Function(value, pointerType) (defaults to null): Function that returns the current color of a pointer. + * If your color won't changed, don't use this option but set it through CSS. If the returned color depends + * on a model value (either rzScopeModelor 'rzSliderHigh), you should use the argument passed to the function. + * Indeed, when the function is called, there is no certainty that the model has already been updated. + * To handle range slider pointers independently, you should evaluate pointerType within the given function + * where "min" stands for rzScopeModel and "max" for rzScopeHigh values. + */ + getPointerColor?: (value: number, pointerType: RzPointerType) => string; + /** Boolean (defaults to false): Set to true to hide pointer labels */ + hidePointerLabels?: boolean; + /** Boolean (defaults to false): Set to true to hide min / max labels */ + hideLimitLabels?: boolean; + /** Boolean (defaults to true): Set to false to disable the auto- hiding behavior of the limit labels. */ + autoHideLimitLabels?: boolean; + /** Boolean (defaults to false): Set to true to make the slider read-only. */ + readOnly?: boolean; + /** Boolean (defaults to false): Set to true to disable the slider. */ + disabled?: boolean; + /** + * Number in ms (defaults to 350): Internally, a throttle function (See http://underscorejs.org/#throttle) is used + * when the model or high values of the slider are changed from outside the slider. This is to prevent from re-rendering + * the slider too many times in a row. interval is the number of milliseconds to wait between two updates of the slider. + */ + interval?: number; + /** Boolean or Number (defaults to false): Set to true to display a tick for each step of the slider. Set an integer to display ticks at intermediate positions. */ + showTicks?: boolean | number; + /** Boolean or Number (defaults to false): Set to true to display a tick and the step value for each step of the slider. Set an integer to display ticks and the step value at intermediate positions. */ + showTicksValues?: boolean | number; + /** Array (defaults to null): Use to display ticks at specific positions. The array contains the index of the ticks that should be displayed. For example, [0, 1, 5] will display a tick for the first, second and sixth values. It also supports the { value: 0, legend: 'Bad' } format to display a legend for each tick. */ + ticksArray?: number[] | Array<{value: number; legend?: string}>; + /** Function(value) (defaults to null): (requires angular-ui bootstrap) Used to display a tooltip when a tick is hovered. Set to a function that returns the tooltip content for a given value. */ + ticksTooltip?: (value: number) => string; + /** Function(value) (defaults to null): Same as ticksTooltip but for ticks values. */ + ticksValuesTooltip?: (value: number) => string; + /** Number (defaults to 1): If you display the slider in an element that uses transform: scale(0.5), set the scale value to 2 so that the slider is rendered properly and the events are handled correctly. */ + scale?: number; + /** Boolean (defaults to true): Set to true to force the value to be rounded to the step, even when modified from the outside.. When set to false, if the model values are modified from outside the slider, they are not rounded and can be between two steps. */ + enforceStep?: boolean; + /** Boolean (defaults to false): Set to true to round the rzSliderModel and rzSliderHigh to the slider range even when modified from outside the slider. When set to false, if the model values are modified from outside the slider, they are not rounded but they are still rendered properly on the slider. */ + enforceRange?: boolean; + /** Boolean (defaults to false): Set to true to prevent to user from switching the min and max handles. Applies to range slider only. */ + noSwitching?: boolean; + /** Boolean (defaults to false): Set to true to only bind events on slider handles. */ + onlyBindHandles?: boolean; + /** Boolean (defaults to true): Set to true to keep the slider labels inside the slider bounds. */ + boundPointerLabels?: boolean; + /** Boolean (defaults to false): Set to true to merge the range labels if they are the same. For instance, if min and max are 50, the label will be "50 - 50" if mergeRangeLabelsIfSame: false, else "50". */ + mergeRangeLabelsIfSame?: boolean; + /** String (defaults to ' - '): Separator to use when the labels overlap. For instance, if min and max are -1 and 1, the label will be "-1 .. 1" if `labelOverlapSeparator: ' .. '`. */ + labelOverlapSeparator?: string; + /** Function(sliderId, modelValue, highValue, pointerType): Function to be called when a slider update is started. If an id was set in the options, then it's passed to this callback. This callback is called before any update on the model. pointerType is either 'min' or 'max' depending on which handle is used. */ + onStart?: RzCallback; + /** + * Function to be called when rz-slider-model or rz-slider-high change. If an id was set in the options, + * then it's passed to this callback. pointerType is either 'min' or 'max' depending + * on which handle is used. + */ + onChange?: RzCallback; + /** Function(sliderId, modelValue, highValue, pointerType): Function to be called when a slider update is ended. If an id was set in the options, then it's passed to this callback. pointerType is either 'min' or 'max' depending on which handle is used. */ + onEnd?: RzCallback; + /** Boolean (defaults to false): Set to true to show graphs right to left. If vertical is true it will be from top to bottom and left / right arrow functions reversed. */ + rightToLeft?: boolean; + /** + * Boolean (defaults to false): Set to true to display the slider vertically. The slider will take the full height of its parent. + * Changing this value at runtime is not currently supported. + */ + vertical?: boolean; + /** + * Boolean (defaults to true): Handles are focusable (on click or with tab) and can be modified using the following keyboard controls: + * - Left/bottom arrows: -1 + * - Right/top arrows: +1 + * - Page-down: -10% + * - Page-up: +10% + * - Home: minimum value + * - End: maximum value + */ + keyboardSupport?: boolean; + /** + * Boolean (defaults to false): Set to true to reverse keyboard navigation: + * - Right/top arrows: -1 + * - Left/bottom arrows: +1 + * - Page-up: -10% + * - Page-down: +10% + * - End: minimum value + * - Home: maximum value + */ + reversedControls?: boolean; + /** Object (default to null): The properties defined in this object will be exposed in the slider template under custom.X. */ + customTemplateScope?: any; + /** Boolean (defaults to false): Set to true to use a logarithmic scale to display the slider. */ + logScale?: boolean; + /** Function(val, minVal, maxVal): percent: Function that returns the position on the slider for a given value.The position must be a percentage between 0 and 1. */ + customValueToPosition?: (val: number, minVal: number, maxVal: number) => number; + /** Function(percent, minVal, maxVal): value: Function that returns the value for a given position on the slider. The position is a percentage between 0 and 1. */ + customPositionToValue?: (percent: number, minVal: number, maxVal: number) => number; + /** Object(default to null): Use to display the selection bar as a gradient. The given object must contain from and to properties which are colors. */ + selectionBarGradient?: {from: string, to: string}; + /** String(default to null): Use to add a label directly to the slider(s) for accessibility. Adds the aria-label attribute. */ + ariaLabel?: string; + /** String(default to null): Use to add a label directly to the slider(s) for accessibility. Adds the aria-label attribute. */ + ariaLabelHigh?: string; + /** String(default to null): Use instead of ariaLabel and ariaLabelHigh to reference the id of an element which will be used to label the slider(s). Adds the aria-labelledby attribute. */ + ariaLabelledBy?: string; + /** String(default to null): Use instead of ariaLabel and ariaLabelHigh to reference the id of an element which will be used to label the slider(s). Adds the aria-labelledby attribute. */ + ariaLabelledByHigh?: string; + /** Boolean (defaults to false): Set to true to disable slider animation. */ + disableAnimation?: boolean; + } + } +} diff --git a/dist/rzslider.js b/dist/rzslider.js index 763de5d..c8fdfd5 100644 --- a/dist/rzslider.js +++ b/dist/rzslider.js @@ -1,2175 +1,2845 @@ -/*! angularjs-slider - v5.5.1 - - (c) Rafal Zajac , Valentin Hervieu , Jussi Saarivirta , Angelin Sirbu - +/*! angularjs-slider - v7.1.0 - + (c) Rafal Zajac , Valentin Hervieu , Jussi Saarivirta , Angelin Sirbu - https://github.com/angular-slider/angularjs-slider - - 2016-09-22 */ + 2022-05-26 */ /*jslint unparam: true */ /*global angular: false, console: false, define, module */ -(function(root, factory) { - 'use strict'; +;(function(root, factory) { + 'use strict' /* istanbul ignore next */ if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. - define(['angular'], factory); + define(['angular'], factory) } else if (typeof module === 'object' && module.exports) { // Node. Does not work with strict CommonJS, but // only CommonJS-like environments that support module.exports, // like Node. // to support bundler like browserify - module.exports = factory(require('angular')); + var angularObj = angular || require('angular') + if ((!angularObj || !angularObj.module) && typeof angular != 'undefined') { + angularObj = angular + } + module.exports = factory(angularObj) } else { // Browser globals (root is window) - factory(root.angular); + factory(root.angular) } +})(this, function(angular) { + 'use strict' + var module = angular + .module('rzSlider', []) + .factory('RzSliderOptions', function() { + var defaultOptions = { + floor: 0, + ceil: null, //defaults to rz-slider-model + step: 1, + precision: 0, + minRange: null, + maxRange: null, + restrictedRange: null, + skipRestrictedRangesWithArrowKeys: null, + pushRange: false, + minLimit: null, + maxLimit: null, + id: null, + translate: null, + getLegend: null, + stepsArray: null, + bindIndexForStepsArray: false, + draggableRange: false, + draggableRangeOnly: false, + showSelectionBar: false, + showSelectionBarEnd: false, + showSelectionBarFromValue: null, + showOuterSelectionBars: false, + hidePointerLabels: false, + hideLimitLabels: false, + autoHideLimitLabels: true, + readOnly: false, + disabled: false, + interval: 350, + showTicks: false, + showTicksValues: false, + ticksArray: null, + ticksTooltip: null, + ticksValuesTooltip: null, + vertical: false, + getSelectionBarColor: null, + getTickColor: null, + getPointerColor: null, + keyboardSupport: true, + scale: 1, + enforceStep: true, + enforceRange: false, + noSwitching: false, + onlyBindHandles: false, + disableAnimation: false, + onStart: null, + onChange: null, + onEnd: null, + rightToLeft: false, + reversedControls: false, + boundPointerLabels: true, + mergeRangeLabelsIfSame: false, + labelOverlapSeparator: ' - ', + customTemplateScope: null, + logScale: false, + customValueToPosition: null, + customPositionToValue: null, + selectionBarGradient: null, + ariaLabel: null, + ariaLabelledBy: null, + ariaLabelHigh: null, + ariaLabelledByHigh: null, + } + var globalOptions = {} -}(this, function(angular) { - 'use strict'; - var module = angular.module('rzModule', []) - - .factory('RzSliderOptions', function() { - var defaultOptions = { - floor: 0, - ceil: null, //defaults to rz-slider-model - step: 1, - precision: 0, - minRange: null, - maxRange: null, - pushRange: false, - minLimit: null, - maxLimit: null, - id: null, - translate: null, - getLegend: null, - stepsArray: null, - bindIndexForStepsArray: false, - draggableRange: false, - draggableRangeOnly: false, - showSelectionBar: false, - showSelectionBarEnd: false, - showSelectionBarFromValue: null, - hidePointerLabels: false, - hideLimitLabels: false, - autoHideLimitLabels: true, - readOnly: false, - disabled: false, - interval: 350, - showTicks: false, - showTicksValues: false, - ticksTooltip: null, - ticksValuesTooltip: null, - vertical: false, - getSelectionBarColor: null, - getTickColor: null, - getPointerColor: null, - keyboardSupport: true, - scale: 1, - enforceStep: true, - enforceRange: false, - noSwitching: false, - onlyBindHandles: false, - onStart: null, - onChange: null, - onEnd: null, - rightToLeft: false, - boundPointerLabels: true, - mergeRangeLabelsIfSame: false, - customTemplateScope: null - }; - var globalOptions = {}; - - var factory = {}; - /** - * `options({})` allows global configuration of all sliders in the - * application. - * - * var app = angular.module( 'App', ['rzModule'], function( RzSliderOptions ) { - * // show ticks for all sliders - * RzSliderOptions.options( { showTicks: true } ); - * }); - */ - factory.options = function(value) { - angular.extend(globalOptions, value); - }; - - factory.getOptions = function(options) { - return angular.extend({}, defaultOptions, globalOptions, options); - }; - - return factory; - }) - - .factory('rzThrottle', ['$timeout', function($timeout) { - /** - * rzThrottle - * - * Taken from underscore project - * - * @param {Function} func - * @param {number} wait - * @param {ThrottleOptions} options - * @returns {Function} - */ - return function(func, wait, options) { - 'use strict'; - /* istanbul ignore next */ - var getTime = (Date.now || function() { - return new Date().getTime(); - }); - var context, args, result; - var timeout = null; - var previous = 0; - options = options || {}; - var later = function() { - previous = getTime(); - timeout = null; - result = func.apply(context, args); - context = args = null; - }; - return function() { - var now = getTime(); - var remaining = wait - (now - previous); - context = this; - args = arguments; - if (remaining <= 0) { - $timeout.cancel(timeout); - timeout = null; - previous = now; - result = func.apply(context, args); - context = args = null; - } else if (!timeout && options.trailing !== false) { - timeout = $timeout(later, remaining); - } - return result; - }; - } - }]) - - .factory('RzSlider', ['$timeout', '$document', '$window', '$compile', 'RzSliderOptions', 'rzThrottle', function($timeout, $document, $window, $compile, RzSliderOptions, rzThrottle) { - 'use strict'; - - /** - * Slider - * - * @param {ngScope} scope The AngularJS scope - * @param {Element} sliderElem The slider directive element wrapped in jqLite - * @constructor - */ - var Slider = function(scope, sliderElem) { + var factory = {} /** - * The slider's scope + * `options({})` allows global configuration of all sliders in the + * application. * - * @type {ngScope} - */ - this.scope = scope; - - /** - * The slider inner low value (linked to rzSliderModel) - * @type {number} - */ - this.lowValue = 0; - - /** - * The slider inner high value (linked to rzSliderHigh) - * @type {number} + * var app = angular.module( 'App', ['rzSlider'], function( RzSliderOptions ) { + * // show ticks for all sliders + * RzSliderOptions.options( { showTicks: true } ); + * }); */ - this.highValue = 0; + factory.options = function(value) { + angular.extend(globalOptions, value) + } - /** - * Slider element wrapped in jqLite - * - * @type {jqLite} - */ - this.sliderElem = sliderElem; + factory.getOptions = function(options) { + return angular.extend({}, defaultOptions, globalOptions, options) + } + return factory + }) + .factory('rzThrottle', ['$timeout', function($timeout) { /** - * Slider type + * rzThrottle * - * @type {boolean} Set to true for range slider - */ - this.range = this.scope.rzSliderModel !== undefined && this.scope.rzSliderHigh !== undefined; - - /** - * Values recorded when first dragging the bar + * Taken from underscore project * - * @type {Object} + * @param {Function} func + * @param {number} wait + * @param {ThrottleOptions} options + * @returns {Function} */ - this.dragging = { - active: false, - value: 0, - difference: 0, - offset: 0, - lowLimit: 0, - highLimit: 0 - }; - - /** - * property that handle position (defaults to left for horizontal) - * @type {string} - */ - this.positionProperty = 'left'; + return function(func, wait, options) { + 'use strict' + /* istanbul ignore next */ + var getTime = + Date.now || + function() { + return new Date().getTime() + } + var context, args, result + var timeout = null + var previous = 0 + options = options || {} + var later = function() { + previous = getTime() + timeout = null + result = func.apply(context, args) + context = args = null + } + return function() { + var now = getTime() + var remaining = wait - (now - previous) + context = this + args = arguments + if (remaining <= 0) { + $timeout.cancel(timeout) + timeout = null + previous = now + result = func.apply(context, args) + context = args = null + } else if (!timeout && options.trailing !== false) { + timeout = $timeout(later, remaining) + } + return result + } + } + }]) + .factory('RzSlider', ['$timeout', '$document', '$window', '$compile', 'RzSliderOptions', 'rzThrottle', function( + $timeout, + $document, + $window, + $compile, + RzSliderOptions, + rzThrottle + ) { + 'use strict' + + /** + * Slider + * + * @param {ngScope} scope The AngularJS scope + * @param {Element} sliderElem The slider directive element wrapped in jqLite + * @constructor + */ + var Slider = function(scope, sliderElem) { + /** + * The slider's scope + * + * @type {ngScope} + */ + this.scope = scope - /** - * property that handle dimension (defaults to width for horizontal) - * @type {string} - */ - this.dimensionProperty = 'width'; + /** + * The slider inner low value (linked to rzSliderModel) + * @type {number} + */ + this.lowValue = 0 - /** - * Half of the width or height of the slider handles - * - * @type {number} - */ - this.handleHalfDim = 0; + /** + * The slider inner high value (linked to rzSliderHigh) + * @type {number} + */ + this.highValue = 0 - /** - * Maximum position the slider handle can have - * - * @type {number} - */ - this.maxPos = 0; + /** + * Slider element wrapped in jqLite + * + * @type {jqLite} + */ + this.sliderElem = sliderElem - /** - * Precision - * - * @type {number} - */ - this.precision = 0; + /** + * Slider type + * + * @type {boolean} Set to true for range slider + */ + this.range = + this.scope.rzSliderModel !== undefined && + this.scope.rzSliderHigh !== undefined + + /** + * Values recorded when first dragging the bar + * + * @type {Object} + */ + this.dragging = { + active: false, + value: 0, + difference: 0, + position: 0, + lowLimit: 0, + highLimit: 0, + } - /** - * Step - * - * @type {number} - */ - this.step = 1; + /** + * property that handle position (defaults to left for horizontal) + * @type {string} + */ + this.positionProperty = 'left' - /** - * The name of the handle we are currently tracking - * - * @type {string} - */ - this.tracking = ''; + /** + * property that handle dimension (defaults to width for horizontal) + * @type {string} + */ + this.dimensionProperty = 'width' - /** - * Minimum value (floor) of the model - * - * @type {number} - */ - this.minValue = 0; + /** + * Half of the width or height of the slider handles + * + * @type {number} + */ + this.handleHalfDim = 0 - /** - * Maximum value (ceiling) of the model - * - * @type {number} - */ - this.maxValue = 0; + /** + * Maximum position the slider handle can have + * + * @type {number} + */ + this.maxPos = 0 + /** + * Precision + * + * @type {number} + */ + this.precision = 0 - /** - * The delta between min and max value - * - * @type {number} - */ - this.valueRange = 0; + /** + * Step + * + * @type {number} + */ + this.step = 1 + /** + * The name of the handle we are currently tracking + * + * @type {string} + */ + this.tracking = '' - /** - * If showTicks/showTicksValues options are number. - * In this case, ticks values should be displayed below the slider. - * @type {boolean} - */ - this.intermediateTicks = false; + /** + * Minimum value (floor) of the model + * + * @type {number} + */ + this.minValue = 0 - /** - * Set to true if init method already executed - * - * @type {boolean} - */ - this.initHasRun = false; + /** + * Maximum value (ceiling) of the model + * + * @type {number} + */ + this.maxValue = 0 - /** - * Used to call onStart on the first keydown event - * - * @type {boolean} - */ - this.firstKeyDown = false; + /** + * The delta between min and max value + * + * @type {number} + */ + this.valueRange = 0 - /** - * Internal flag to prevent watchers to be called when the sliders value are modified internally. - * @type {boolean} - */ - this.internalChange = false; + /** + * If showTicks/showTicksValues options are number. + * In this case, ticks values should be displayed below the slider. + * @type {boolean} + */ + this.intermediateTicks = false - /** - * Internal flag to keep track of the visibility of combo label - * @type {boolean} - */ - this.cmbLabelShown = false; + /** + * Set to true if init method already executed + * + * @type {boolean} + */ + this.initHasRun = false - /** - * Internal variable to keep track of the focus element - */ - this.currentFocusElement = null; - - // Slider DOM elements wrapped in jqLite - this.fullBar = null; // The whole slider bar - this.selBar = null; // Highlight between two handles - this.minH = null; // Left slider handle - this.maxH = null; // Right slider handle - this.flrLab = null; // Floor label - this.ceilLab = null; // Ceiling label - this.minLab = null; // Label above the low value - this.maxLab = null; // Label above the high value - this.cmbLab = null; // Combined label - this.ticks = null; // The ticks - - // Initialize slider - this.init(); - }; - - // Add instance methods - Slider.prototype = { + /** + * Used to call onStart on the first keydown event + * + * @type {boolean} + */ + this.firstKeyDown = false - /** - * Initialize slider - * - * @returns {undefined} - */ - init: function() { - var thrLow, thrHigh, - self = this; - - var calcDimFn = function() { - self.calcViewDimensions(); - }; - - this.applyOptions(); - this.syncLowValue(); - if (this.range) - this.syncHighValue(); - this.initElemHandles(); - this.manageElementsStyle(); - this.setDisabledState(); - this.calcViewDimensions(); - this.setMinAndMax(); - this.addAccessibility(); - this.updateCeilLab(); - this.updateFloorLab(); - this.initHandles(); - this.manageEventsBindings(); - - // Recalculate slider view dimensions - this.scope.$on('reCalcViewDimensions', calcDimFn); - - // Recalculate stuff if view port dimensions have changed - angular.element($window).on('resize', calcDimFn); - - this.initHasRun = true; - - // Watch for changes to the model - thrLow = rzThrottle(function() { - self.onLowHandleChange(); - }, self.options.interval); - - thrHigh = rzThrottle(function() { - self.onHighHandleChange(); - }, self.options.interval); - - this.scope.$on('rzSliderForceRender', function() { - self.resetLabelsValue(); - thrLow(); - if (self.range) { - thrHigh(); - } - self.resetSlider(); - }); - - // Watchers (order is important because in case of simultaneous change, - // watchers will be called in the same order) - this.scope.$watch('rzSliderOptions()', function(newValue, oldValue) { - if (newValue === oldValue) - return; - self.applyOptions(); // need to be called before synchronizing the values - self.syncLowValue(); - if (self.range) - self.syncHighValue(); - self.resetSlider(); - }, true); - - this.scope.$watch('rzSliderModel', function(newValue, oldValue) { - if (self.internalChange) - return; - if (newValue === oldValue) - return; - thrLow(); - }); - - this.scope.$watch('rzSliderHigh', function(newValue, oldValue) { - if (self.internalChange) - return; - if (newValue === oldValue) - return; - if (newValue != null) - thrHigh(); - if (self.range && newValue == null || !self.range && newValue != null) { - self.applyOptions(); - self.resetSlider(); - } - }); - - this.scope.$on('$destroy', function() { - self.unbindEvents(); - angular.element($window).off('resize', calcDimFn); - self.currentFocusElement = null; - }); - }, - - findStepIndex: function(modelValue) { - var index = 0; - for (var i = 0; i < this.options.stepsArray.length; i++) { - var step = this.options.stepsArray[i]; - if (step === modelValue) { - index = i; - break; - } - else if (angular.isObject(step) && step.value === modelValue) { - index = i; - break; - } - } - return index; - }, + /** + * Internal flag to prevent watchers to be called when the sliders value are modified internally. + * @type {boolean} + */ + this.internalChange = false - syncLowValue: function() { - if (this.options.stepsArray) { - if (!this.options.bindIndexForStepsArray) - this.lowValue = this.findStepIndex(this.scope.rzSliderModel); - else - this.lowValue = this.scope.rzSliderModel - } - else - this.lowValue = this.scope.rzSliderModel; - }, - - syncHighValue: function() { - if (this.options.stepsArray) { - if (!this.options.bindIndexForStepsArray) - this.highValue = this.findStepIndex(this.scope.rzSliderHigh); - else - this.highValue = this.scope.rzSliderHigh - } - else - this.highValue = this.scope.rzSliderHigh; - }, - - getStepValue: function(sliderValue) { - var step = this.options.stepsArray[sliderValue]; - if (angular.isObject(step)) - return step.value; - return step; - }, - - applyLowValue: function() { - if (this.options.stepsArray) { - if (!this.options.bindIndexForStepsArray) - this.scope.rzSliderModel = this.getStepValue(this.lowValue); - else - this.scope.rzSliderModel = this.lowValue - } - else - this.scope.rzSliderModel = this.lowValue; - }, - - applyHighValue: function() { - if (this.options.stepsArray) { - if (!this.options.bindIndexForStepsArray) - this.scope.rzSliderHigh = this.getStepValue(this.highValue); - else - this.scope.rzSliderHigh = this.highValue - } - else - this.scope.rzSliderHigh = this.highValue; - }, + /** + * Internal flag to keep track of the visibility of combo label + * @type {boolean} + */ + this.cmbLabelShown = false - /* - * Reflow the slider when the low handle changes (called with throttle) - */ - onLowHandleChange: function() { - this.syncLowValue(); - if (this.range) - this.syncHighValue(); - this.setMinAndMax(); - this.updateLowHandle(this.valueToOffset(this.lowValue)); - this.updateSelectionBar(); - this.updateTicksScale(); - this.updateAriaAttributes(); - if (this.range) { - this.updateCmbLabel(); - } - }, + /** + * Internal variable to keep track of the focus element + */ + this.currentFocusElement = null - /* - * Reflow the slider when the high handle changes (called with throttle) - */ - onHighHandleChange: function() { - this.syncLowValue(); - this.syncHighValue(); - this.setMinAndMax(); - this.updateHighHandle(this.valueToOffset(this.highValue)); - this.updateSelectionBar(); - this.updateTicksScale(); - this.updateCmbLabel(); - this.updateAriaAttributes(); - }, + /** + * Internal variable to know if we are already moving + */ + this.moving = false + + // Slider DOM elements wrapped in jqLite + this.fullBar = null // The whole slider bar + this.selBar = null // Highlight between two handles + this.minH = null // Left slider handle + this.maxH = null // Right slider handle + this.flrLab = null // Floor label + this.ceilLab = null // Ceiling label + this.minLab = null // Label above the low value + this.maxLab = null // Label above the high value + this.cmbLab = null // Combined label + this.ticks = null // The ticks + + // Initialize slider + this.init() + } - /** - * Read the user options and apply them to the slider model - */ - applyOptions: function() { - var sliderOptions; - if (this.scope.rzSliderOptions) - sliderOptions = this.scope.rzSliderOptions(); - else - sliderOptions = {}; - - this.options = RzSliderOptions.getOptions(sliderOptions); - - if (this.options.step <= 0) - this.options.step = 1; - - this.range = this.scope.rzSliderModel !== undefined && this.scope.rzSliderHigh !== undefined; - this.options.draggableRange = this.range && this.options.draggableRange; - this.options.draggableRangeOnly = this.range && this.options.draggableRangeOnly; - if (this.options.draggableRangeOnly) { - this.options.draggableRange = true; - } + // Add instance methods + Slider.prototype = { + /** + * Initialize slider + * + * @returns {undefined} + */ + init: function() { + var thrLow, + thrHigh, + self = this - this.options.showTicks = this.options.showTicks || this.options.showTicksValues; - this.scope.showTicks = this.options.showTicks; //scope is used in the template - if (angular.isNumber(this.options.showTicks)) - this.intermediateTicks = true; + var calcDimFn = function() { + self.calcViewDimensions() + } - this.options.showSelectionBar = this.options.showSelectionBar || this.options.showSelectionBarEnd - || this.options.showSelectionBarFromValue !== null; + this.applyOptions() + this.syncLowValue() + if (this.range) this.syncHighValue() + this.initElemHandles() + this.manageElementsStyle() + this.setDisabledState() + this.calcViewDimensions() + this.setMinAndMax() + this.updateRestrictionBar() + this.addAccessibility() + this.updateCeilLab() + this.updateFloorLab() + this.initHandles() + this.manageEventsBindings() + + // Recalculate slider view dimensions + this.scope.$on('reCalcViewDimensions', calcDimFn) + + // Recalculate stuff if view port dimensions have changed + angular.element($window).on('resize', calcDimFn) + + this.initHasRun = true + + if (this.options.disableAnimation) { + this.sliderElem.addClass('noanimate') + } - if (this.options.stepsArray) { - this.parseStepsArray(); - } else { - if (this.options.translate) - this.customTrFn = this.options.translate; - else - this.customTrFn = function(value) { - return String(value); - }; + // Watch for changes to the model + thrLow = rzThrottle(function() { + self.onLowHandleChange() + }, self.options.interval) - this.getLegend = this.options.getLegend; - } + thrHigh = rzThrottle(function() { + self.onHighHandleChange() + }, self.options.interval) - if (this.options.vertical) { - this.positionProperty = 'bottom'; - this.dimensionProperty = 'height'; - } + this.scope.$on('rzSliderForceRender', function() { + self.resetLabelsValue() + thrLow() + if (self.range) { + thrHigh() + } + self.resetSlider() + }) + + // Watchers (order is important because in case of simultaneous change, + // watchers will be called in the same order) + this.scope.$watchCollection('rzSliderOptions()', function( + newValue, + oldValue + ) { + if (newValue === oldValue) return + self.applyOptions() // need to be called before synchronizing the values + self.syncLowValue() + if (self.range) self.syncHighValue() + self.resetSlider() + }) + + this.scope.$watch('rzSliderModel', function(newValue, oldValue) { + if (self.internalChange) return + if (newValue === oldValue) return + thrLow() + }) + + this.scope.$watch('rzSliderHigh', function(newValue, oldValue) { + if (self.internalChange) return + if (newValue === oldValue) return + if (newValue != null) thrHigh() + if ( + (self.range && newValue == null) || + (!self.range && newValue != null) + ) { + self.applyOptions() + self.resetSlider() + } + }) + + this.scope.$on('$destroy', function() { + self.unbindEvents() + angular.element($window).off('resize', calcDimFn) + self.currentFocusElement = null + }) + }, + + findStepIndex: function(modelValue) { + var index = 0 + for (var i = 0; i < this.options.stepsArray.length; i++) { + var step = this.options.stepsArray[i] + if (step === modelValue) { + index = i + break + } else if (angular.isDate(step)) { + if (step.getTime() === modelValue.getTime()) { + index = i + break + } + } else if (angular.isObject(step)) { + if ( + (angular.isDate(step.value) && + step.value.getTime() === modelValue.getTime()) || + step.value === modelValue + ) { + index = i + break + } + } + } + return index + }, + + syncLowValue: function() { + if (this.options.stepsArray) { + if (!this.options.bindIndexForStepsArray) + this.lowValue = this.findStepIndex(this.scope.rzSliderModel) + else this.lowValue = this.scope.rzSliderModel + } else this.lowValue = this.scope.rzSliderModel + }, + + syncHighValue: function() { + if (this.options.stepsArray) { + if (!this.options.bindIndexForStepsArray) + this.highValue = this.findStepIndex(this.scope.rzSliderHigh) + else this.highValue = this.scope.rzSliderHigh + } else this.highValue = this.scope.rzSliderHigh + }, + + getStepValue: function(sliderValue) { + var step = this.options.stepsArray[sliderValue] + if (angular.isDate(step)) return step + if (angular.isObject(step)) return step.value + return step + }, + + applyLowValue: function() { + if (this.options.stepsArray) { + if (!this.options.bindIndexForStepsArray) + this.scope.rzSliderModel = this.getStepValue(this.lowValue) + else this.scope.rzSliderModel = this.lowValue + } else this.scope.rzSliderModel = this.lowValue + }, + + applyHighValue: function() { + if (this.options.stepsArray) { + if (!this.options.bindIndexForStepsArray) + this.scope.rzSliderHigh = this.getStepValue(this.highValue) + else this.scope.rzSliderHigh = this.highValue + } else this.scope.rzSliderHigh = this.highValue + }, - if (this.options.customTemplateScope) - this.scope.custom = this.options.customTemplateScope; - }, + /* + * Reflow the slider when the low handle changes (called with throttle) + */ + onLowHandleChange: function() { + this.syncLowValue() + if (this.range) this.syncHighValue() + this.setMinAndMax() + this.updateLowHandle(this.valueToPosition(this.lowValue)) + this.updateSelectionBar() + this.updateTicksScale() + this.updateAriaAttributes() + if (this.range) { + this.updateCmbLabel() + } + }, - parseStepsArray: function() { - this.options.floor = 0; - this.options.ceil = this.options.stepsArray.length - 1; - this.options.step = 1; + /* + * Reflow the slider when the high handle changes (called with throttle) + */ + onHighHandleChange: function() { + this.syncLowValue() + this.syncHighValue() + this.setMinAndMax() + this.updateHighHandle(this.valueToPosition(this.highValue)) + this.updateSelectionBar() + this.updateTicksScale() + this.updateCmbLabel() + this.updateAriaAttributes() + }, + + /** + * Read the user options and apply them to the slider model + */ + applyOptions: function() { + var sliderOptions + if (this.scope.rzSliderOptions) + sliderOptions = this.scope.rzSliderOptions() + else sliderOptions = {} + + this.options = RzSliderOptions.getOptions(sliderOptions) + + if (this.options.step <= 0) this.options.step = 1 + + this.range = + this.scope.rzSliderModel !== undefined && + this.scope.rzSliderHigh !== undefined + this.options.draggableRange = + this.range && this.options.draggableRange + this.options.draggableRangeOnly = + this.range && this.options.draggableRangeOnly + if (this.options.draggableRangeOnly) { + this.options.draggableRange = true + } - if (this.options.translate) { - this.customTrFn = this.options.translate; - } - else { - this.customTrFn = function(modelValue) { - if (this.options.bindIndexForStepsArray) - return this.getStepValue(modelValue); - return modelValue; - }; - } + this.options.showTicks = + this.options.showTicks || + this.options.showTicksValues || + !!this.options.ticksArray + this.scope.showTicks = this.options.showTicks //scope is used in the template + if ( + angular.isNumber(this.options.showTicks) || + this.options.ticksArray + ) + this.intermediateTicks = true + + this.options.showSelectionBar = + this.options.showSelectionBar || + this.options.showSelectionBarEnd || + this.options.showSelectionBarFromValue !== null + + if (this.options.stepsArray) { + this.parseStepsArray() + } else { + if (this.options.translate) this.customTrFn = this.options.translate + else + this.customTrFn = function(value) { + return String(value) + } - this.getLegend = function(index) { - var step = this.options.stepsArray[index]; - if (angular.isObject(step)) - return step.legend; - return null; - }; - }, + this.getLegend = this.options.getLegend + } - /** - * Resets slider - * - * @returns {undefined} - */ - resetSlider: function() { - this.manageElementsStyle(); - this.addAccessibility(); - this.setMinAndMax(); - this.updateCeilLab(); - this.updateFloorLab(); - this.unbindEvents(); - this.manageEventsBindings(); - this.setDisabledState(); - this.calcViewDimensions(); - this.refocusPointerIfNeeded(); - }, - - refocusPointerIfNeeded: function() { - if (this.currentFocusElement) { - this.onPointerFocus(this.currentFocusElement.pointer, this.currentFocusElement.ref); - this.focusElement(this.currentFocusElement.pointer) - } - }, + if (this.options.vertical) { + this.positionProperty = 'bottom' + this.dimensionProperty = 'height' + } else { + this.positionProperty = 'left' + this.dimensionProperty = 'width' + } - /** - * Set the slider children to variables for easy access - * - * Run only once during initialization - * - * @returns {undefined} - */ - initElemHandles: function() { - // Assign all slider elements to object properties for easy access - angular.forEach(this.sliderElem.children(), function(elem, index) { - var jElem = angular.element(elem); - - switch (index) { - case 0: - this.fullBar = jElem; - break; - case 1: - this.selBar = jElem; - break; - case 2: - this.minH = jElem; - break; - case 3: - this.maxH = jElem; - break; - case 4: - this.flrLab = jElem; - break; - case 5: - this.ceilLab = jElem; - break; - case 6: - this.minLab = jElem; - break; - case 7: - this.maxLab = jElem; - break; - case 8: - this.cmbLab = jElem; - break; - case 9: - this.ticks = jElem; - break; - } - - }, this); - - // Initialize offset cache properties - this.selBar.rzsp = 0; - this.minH.rzsp = 0; - this.maxH.rzsp = 0; - this.flrLab.rzsp = 0; - this.ceilLab.rzsp = 0; - this.minLab.rzsp = 0; - this.maxLab.rzsp = 0; - this.cmbLab.rzsp = 0; - }, + if (this.options.customTemplateScope) + this.scope.custom = this.options.customTemplateScope + }, - /** - * Update each elements style based on options - */ - manageElementsStyle: function() { + parseStepsArray: function() { + this.options.floor = 0 + this.options.ceil = this.options.stepsArray.length - 1 + this.options.step = 1 - if (!this.range) - this.maxH.css('display', 'none'); - else - this.maxH.css('display', ''); + if (this.options.translate) { + this.customTrFn = this.options.translate + } else { + this.customTrFn = function(modelValue) { + if (this.options.bindIndexForStepsArray) + return this.getStepValue(modelValue) + return modelValue + } + } + this.getLegend = function(index) { + var step = this.options.stepsArray[index] + if (angular.isObject(step)) return step.legend + return null + } + }, - this.alwaysHide(this.flrLab, this.options.showTicksValues || this.options.hideLimitLabels); - this.alwaysHide(this.ceilLab, this.options.showTicksValues || this.options.hideLimitLabels); + /** + * Resets slider + * + * @returns {undefined} + */ + resetSlider: function() { + this.resetLabelsValue() + this.manageElementsStyle() + this.addAccessibility() + this.setMinAndMax() + this.updateCeilLab() + this.updateFloorLab() + this.unbindEvents() + this.manageEventsBindings() + this.setDisabledState() + this.calcViewDimensions() + this.updateRestrictionBar() + this.refocusPointerIfNeeded() + }, + + refocusPointerIfNeeded: function() { + if (this.currentFocusElement) { + this.onPointerFocus( + this.currentFocusElement.pointer, + this.currentFocusElement.ref + ) + this.focusElement(this.currentFocusElement.pointer) + } + }, + + /** + * Check if the restrictedRange option using multiple or not + * + * Run only once during initialization and only in case 4 + * + * @returns {undefined} + */ - var hideLabelsForTicks = this.options.showTicksValues && !this.intermediateTicks; - this.alwaysHide(this.minLab, hideLabelsForTicks || this.options.hidePointerLabels); - this.alwaysHide(this.maxLab, hideLabelsForTicks || !this.range || this.options.hidePointerLabels); - this.alwaysHide(this.cmbLab, hideLabelsForTicks || !this.range || this.options.hidePointerLabels); - this.alwaysHide(this.selBar, !this.range && !this.options.showSelectionBar); + ensureRestrictedBarIsArray: function(elem) { + var jElem = angular.element(elem) + this.restrictedBar = [] + if (this.options.restrictedRange) { + // this.options.restrictedRange converting to an array even if it's not entered as array. + this.options.restrictedRange = !Array.isArray( + this.options.restrictedRange + ) + ? [this.options.restrictedRange] + : this.options.restrictedRange + this.restrictedBar[0] = jElem + var mainDiv = elem.parentElement + for (var i = 1; i < this.options.restrictedRange.length; i++) { + var sp = document.createElement('span') + sp.setAttribute('class', 'rz-bar-wrapper') + sp.innerHTML = + '' + mainDiv.appendChild(sp) + this.restrictedBar[i] = angular.element(sp) + } + } else { + elem.style.visibility = 'hidden' + this.restrictedBar = null + } + }, + + /** + * Set the slider children to variables for easy access + * + * Run only once during initialization + * + * @returns {undefined} + */ + initElemHandles: function() { + // Assign all slider elements to object properties for easy access + angular.forEach( + this.sliderElem.children(), + function(elem, index) { + var jElem = angular.element(elem) + + switch (index) { + case 0: + this.leftOutSelBar = jElem + break + case 1: + this.rightOutSelBar = jElem + break + case 2: + this.fullBar = jElem + break + case 3: + this.selBar = jElem + break + case 4: + this.ensureRestrictedBarIsArray(elem) + break + case 5: + this.minH = jElem + break + case 6: + this.maxH = jElem + break + case 7: + this.flrLab = jElem + break + case 8: + this.ceilLab = jElem + break + case 9: + this.minLab = jElem + break + case 10: + this.maxLab = jElem + break + case 11: + this.cmbLab = jElem + break + case 12: + this.ticks = jElem + break + } + }, + this + ) + + // Initialize position cache properties + this.selBar.rzsp = 0 + this.minH.rzsp = 0 + this.maxH.rzsp = 0 + this.flrLab.rzsp = 0 + this.ceilLab.rzsp = 0 + this.minLab.rzsp = 0 + this.maxLab.rzsp = 0 + this.cmbLab.rzsp = 0 + }, + + /** + * Update each elements style based on options + */ + manageElementsStyle: function() { + if (!this.range) this.maxH.css('display', 'none') + else this.maxH.css('display', '') + + this.alwaysHide( + this.flrLab, + this.options.showTicksValues || this.options.hideLimitLabels + ) + this.alwaysHide( + this.ceilLab, + this.options.showTicksValues || this.options.hideLimitLabels + ) + + var hideLabelsForTicks = + this.options.showTicksValues && !this.intermediateTicks + this.alwaysHide( + this.minLab, + hideLabelsForTicks || this.options.hidePointerLabels + ) + this.alwaysHide( + this.maxLab, + hideLabelsForTicks || !this.range || this.options.hidePointerLabels + ) + this.alwaysHide( + this.cmbLab, + hideLabelsForTicks || !this.range || this.options.hidePointerLabels + ) + this.alwaysHide( + this.selBar, + !this.range && !this.options.showSelectionBar + ) + this.alwaysHide( + this.leftOutSelBar, + !this.range || !this.options.showOuterSelectionBars + ) + + // this.restrictedBar is everytime an array + for (var r in this.restrictedBar) { + if (this.restrictedBar[r]) + this.alwaysHide( + this.restrictedBar[r], + !this.options.restrictedRange[r] + ) + } - if (this.options.vertical) - this.sliderElem.addClass('rz-vertical'); + this.alwaysHide( + this.rightOutSelBar, + !this.range || !this.options.showOuterSelectionBars + ) - if (this.options.draggableRange) - this.selBar.addClass('rz-draggable'); - else - this.selBar.removeClass('rz-draggable'); + if (this.range && this.options.showOuterSelectionBars) { + this.fullBar.addClass('rz-transparent') + } - if (this.intermediateTicks && this.options.showTicksValues) - this.ticks.addClass('rz-ticks-values-under'); - }, + if (this.options.vertical) { + this.sliderElem.addClass('rz-vertical') + } else { + this.sliderElem.removeClass('rz-vertical') + } - alwaysHide: function(el, hide) { - el.rzAlwaysHide = hide; - if (hide) - this.hideEl(el); - else - this.showEl(el) - }, + if (this.options.draggableRange) this.selBar.addClass('rz-draggable') + else this.selBar.removeClass('rz-draggable') - /** - * Manage the events bindings based on readOnly and disabled options - * - * @returns {undefined} - */ - manageEventsBindings: function() { - if (this.options.disabled || this.options.readOnly) - this.unbindEvents(); - else - this.bindEvents(); - }, + if (this.intermediateTicks && this.options.showTicksValues) + this.ticks.addClass('rz-ticks-values-under') + }, - /** - * Set the disabled state based on rzSliderDisabled - * - * @returns {undefined} - */ - setDisabledState: function() { - if (this.options.disabled) { - this.sliderElem.attr('disabled', 'disabled'); - } else { - this.sliderElem.attr('disabled', null); - } - }, + alwaysHide: function(el, hide) { + el.rzAlwaysHide = hide + if (hide) this.hideEl(el) + else this.showEl(el) + }, - /** - * Reset label values - * - * @return {undefined} - */ - resetLabelsValue: function() { - this.minLab.rzsv = undefined; - this.maxLab.rzsv = undefined; - }, + /** + * Manage the events bindings based on readOnly and disabled options + * + * @returns {undefined} + */ + manageEventsBindings: function() { + if (this.options.disabled || this.options.readOnly) + this.unbindEvents() + else this.bindEvents() + }, + + /** + * Set the disabled state based on rzSliderDisabled + * + * @returns {undefined} + */ + setDisabledState: function() { + if (this.options.disabled) { + this.sliderElem.attr('disabled', 'disabled') + } else { + this.sliderElem.attr('disabled', null) + } + }, - /** - * Initialize slider handles positions and labels - * - * Run only once during initialization and every time view port changes size - * - * @returns {undefined} - */ - initHandles: function() { - this.updateLowHandle(this.valueToOffset(this.lowValue)); + /** + * Reset label values + * + * @return {undefined} + */ + resetLabelsValue: function() { + this.minLab.rzsv = undefined + this.maxLab.rzsv = undefined + this.flrLab.rzsv = undefined + this.ceilLab.rzsv = undefined + this.cmbLab.rzsv = undefined + this.resetPosition(this.flrLab) + this.resetPosition(this.ceilLab) + this.resetPosition(this.cmbLab) + this.resetPosition(this.minLab) + this.resetPosition(this.maxLab) + }, + + /** + * Initialize slider handles positions and labels + * + * Run only once during initialization and every time view port changes size + * + * @returns {undefined} + */ + initHandles: function() { + this.updateLowHandle(this.valueToPosition(this.lowValue)) - /* + /* the order here is important since the selection bar should be updated after the high handle but before the combined label */ - if (this.range) - this.updateHighHandle(this.valueToOffset(this.highValue)); - this.updateSelectionBar(); - if (this.range) - this.updateCmbLabel(); - - this.updateTicksScale(); - }, - - /** - * Translate value to human readable format - * - * @param {number|string} value - * @param {jqLite} label - * @param {String} which - * @param {boolean} [useCustomTr] - * @returns {undefined} - */ - translateFn: function(value, label, which, useCustomTr) { - useCustomTr = useCustomTr === undefined ? true : useCustomTr; - - var valStr = '', - getDimension = false, - noLabelInjection = label.hasClass('no-label-injection'); + if (this.range) + this.updateHighHandle(this.valueToPosition(this.highValue)) + this.updateSelectionBar() + if (this.range) this.updateCmbLabel() + + this.updateTicksScale() + }, + + /** + * Translate value to human readable format + * + * @param {number|string} value + * @param {jqLite} label + * @param {String} which + * @param {boolean} [useCustomTr] + * @returns {undefined} + */ + translateFn: function(value, label, which, useCustomTr) { + useCustomTr = useCustomTr === undefined ? true : useCustomTr - if (useCustomTr) { - if (this.options.stepsArray && !this.options.bindIndexForStepsArray) - value = this.getStepValue(value); - valStr = String(this.customTrFn(value, this.options.id, which)); - } - else { - valStr = String(value) - } + var valStr = '', + getDimension = false, + noLabelInjection = label.hasClass('no-label-injection') - if (label.rzsv === undefined || label.rzsv.length !== valStr.length || (label.rzsv.length > 0 && label.rzsd === 0)) { - getDimension = true; - label.rzsv = valStr; - } + if (useCustomTr) { + if (this.options.stepsArray && !this.options.bindIndexForStepsArray) + value = this.getStepValue(value) + valStr = String(this.customTrFn(value, this.options.id, which)) + } else { + valStr = String(value) + } - if (!noLabelInjection) { - label.html(valStr); - } - ; + if ( + label.rzsv === undefined || + label.rzsv.length !== valStr.length || + (label.rzsv.length > 0 && label.rzsd === 0) + ) { + getDimension = true + label.rzsv = valStr + } - this.scope[which + 'Label'] = valStr; + if (!noLabelInjection) { + label.html(valStr) + } + this.scope[which + 'Label'] = valStr - // Update width only when length of the label have changed - if (getDimension) { - this.getDimension(label); - } - }, + // Update width only when length of the label have changed + if (getDimension) { + this.getDimension(label) + } + }, - /** - * Set maximum and minimum values for the slider and ensure the model and high - * value match these limits - * @returns {undefined} - */ - setMinAndMax: function() { + /** + * Set maximum and minimum values for the slider and ensure the model and high + * value match these limits + * @returns {undefined} + */ + setMinAndMax: function() { + this.step = +this.options.step + this.precision = +this.options.precision - this.step = +this.options.step; - this.precision = +this.options.precision; + this.minValue = this.options.floor + if (this.options.logScale && this.minValue === 0) + throw Error("Can't use floor=0 with logarithmic scale") - this.minValue = this.options.floor; + if (this.options.enforceStep) { + this.lowValue = this.roundStep(this.lowValue) + if (this.range) this.highValue = this.roundStep(this.highValue) + } - if (this.options.enforceStep) { - this.lowValue = this.roundStep(this.lowValue); - if (this.range) - this.highValue = this.roundStep(this.highValue); - } + if (this.options.ceil != null) this.maxValue = this.options.ceil + else + this.maxValue = this.options.ceil = this.range + ? this.highValue + : this.lowValue - if (this.options.ceil != null) - this.maxValue = this.options.ceil; - else - this.maxValue = this.options.ceil = this.range ? this.highValue : this.lowValue; + if (this.options.enforceRange) { + this.lowValue = this.sanitizeValue(this.lowValue) + if (this.range) this.highValue = this.sanitizeValue(this.highValue) + } - if (this.options.enforceRange) { - this.lowValue = this.sanitizeValue(this.lowValue); - if (this.range) - this.highValue = this.sanitizeValue(this.highValue); - } + this.applyLowValue() + if (this.range) this.applyHighValue() - this.applyLowValue(); - if (this.range) - this.applyHighValue(); + this.valueRange = this.maxValue - this.minValue + }, - this.valueRange = this.maxValue - this.minValue; - }, + /** + * Adds accessibility attributes + * + * Run only once during initialization + * + * @returns {undefined} + */ + addAccessibility: function() { + this.minH.attr('role', 'slider') + this.updateAriaAttributes() + if ( + this.options.keyboardSupport && + !(this.options.readOnly || this.options.disabled) + ) + this.minH.attr('tabindex', '0') + else this.minH.attr('tabindex', '') + if (this.options.vertical) { + this.minH.attr('aria-orientation', 'vertical') + } else { + this.minH.attr('aria-orientation', 'horizontal') + } + if (this.options.ariaLabel) + this.minH.attr('aria-label', this.options.ariaLabel) + else if (this.options.ariaLabelledBy) + this.minH.attr('aria-labelledby', this.options.ariaLabelledBy) - /** - * Adds accessibility attributes - * - * Run only once during initialization - * - * @returns {undefined} - */ - addAccessibility: function() { - this.minH.attr('role', 'slider'); - this.updateAriaAttributes(); - if (this.options.keyboardSupport && !(this.options.readOnly || this.options.disabled)) - this.minH.attr('tabindex', '0'); - else - this.minH.attr('tabindex', ''); - if (this.options.vertical) - this.minH.attr('aria-orientation', 'vertical'); - - if (this.range) { - this.maxH.attr('role', 'slider'); - if (this.options.keyboardSupport && !(this.options.readOnly || this.options.disabled)) - this.maxH.attr('tabindex', '0'); - else - this.maxH.attr('tabindex', ''); - if (this.options.vertical) - this.maxH.attr('aria-orientation', 'vertical'); - } - }, + if (this.range) { + this.maxH.attr('role', 'slider') + if ( + this.options.keyboardSupport && + !(this.options.readOnly || this.options.disabled) + ) + this.maxH.attr('tabindex', '0') + else this.maxH.attr('tabindex', '') + if (this.options.vertical) + this.maxH.attr('aria-orientation', 'vertical') + else this.maxH.attr('aria-orientation', 'horizontal') + if (this.options.ariaLabelHigh) + this.maxH.attr('aria-label', this.options.ariaLabelHigh) + else if (this.options.ariaLabelledByHigh) + this.maxH.attr('aria-labelledby', this.options.ariaLabelledByHigh) + } + }, - /** - * Updates aria attributes according to current values - */ - updateAriaAttributes: function() { - this.minH.attr({ - 'aria-valuenow': this.scope.rzSliderModel, - 'aria-valuetext': this.customTrFn(this.scope.rzSliderModel, this.options.id, 'model'), - 'aria-valuemin': this.minValue, - 'aria-valuemax': this.maxValue - }); - if (this.range) { - this.maxH.attr({ - 'aria-valuenow': this.scope.rzSliderHigh, - 'aria-valuetext': this.customTrFn(this.scope.rzSliderHigh, this.options.id, 'high'), + /** + * Updates aria attributes according to current values + */ + updateAriaAttributes: function() { + this.minH.attr({ + 'aria-valuenow': this.scope.rzSliderModel, + 'aria-valuetext': this.customTrFn( + this.scope.rzSliderModel, + this.options.id, + 'model' + ), 'aria-valuemin': this.minValue, - 'aria-valuemax': this.maxValue - }); - } - }, - - /** - * Calculate dimensions that are dependent on view port size - * - * Run once during initialization and every time view port changes size. - * - * @returns {undefined} - */ - calcViewDimensions: function() { - var handleWidth = this.getDimension(this.minH); + 'aria-valuemax': this.maxValue, + }) + if (this.range) { + this.maxH.attr({ + 'aria-valuenow': this.scope.rzSliderHigh, + 'aria-valuetext': this.customTrFn( + this.scope.rzSliderHigh, + this.options.id, + 'high' + ), + 'aria-valuemin': this.minValue, + 'aria-valuemax': this.maxValue, + }) + } + }, + + /** + * Calculate dimensions that are dependent on view port size + * + * Run once during initialization and every time view port changes size. + * + * @returns {undefined} + */ + calcViewDimensions: function() { + var handleWidth = this.getDimension(this.minH) + + this.handleHalfDim = handleWidth / 2 + this.barDimension = this.getDimension(this.fullBar) + + this.maxPos = this.barDimension - handleWidth + + this.getDimension(this.sliderElem) + this.sliderElem.rzsp = this.sliderElem[0].getBoundingClientRect()[ + this.positionProperty + ] + + if (this.initHasRun) { + this.updateFloorLab() + this.updateCeilLab() + this.initHandles() + var self = this + $timeout(function() { + self.updateTicksScale() + }) + } + }, - this.handleHalfDim = handleWidth / 2; - this.barDimension = this.getDimension(this.fullBar); + /** + * Update the ticks position + * + * @returns {undefined} + */ + updateTicksScale: function() { + if (!this.options.showTicks) return - this.maxPos = this.barDimension - handleWidth; + var ticksArray = this.options.ticksArray || this.getTicksArray(), + translate = this.options.vertical ? 'translateY' : 'translateX', + self = this - this.getDimension(this.sliderElem); - this.sliderElem.rzsp = this.sliderElem[0].getBoundingClientRect()[this.positionProperty]; + if (this.options.rightToLeft) ticksArray.reverse() - if (this.initHasRun) { - this.updateFloorLab(); - this.updateCeilLab(); - this.initHandles(); - } - }, + this.scope.ticks = ticksArray.map(function(value) { + var legend = null + if (angular.isObject(value)) { + legend = value.legend + value = value.value + } - /** - * Update the ticks position - * - * @returns {undefined} - */ - updateTicksScale: function() { - if (!this.options.showTicks) return; - var step = this.step; - if (this.intermediateTicks) - step = this.options.showTicks; - var ticksCount = Math.round((this.maxValue - this.minValue) / step) + 1; - this.scope.ticks = []; - for (var i = 0; i < ticksCount; i++) { - var value = this.roundStep(this.minValue + i * step); - var tick = { - selected: this.isTickSelected(value) - }; - if (tick.selected && this.options.getSelectionBarColor) { - tick.style = { - 'background-color': this.getSelectionBarColor() - }; - } - if (!tick.selected && this.options.getTickColor) { - tick.style = { - 'background-color': this.getTickColor(value) + var position = self.valueToPosition(value) + + if (self.options.vertical) position = self.maxPos - position + + var translation = translate + '(' + Math.round(position) + 'px)' + var tick = { + legend: legend, + selected: self.isTickSelected(value), + style: { + '-webkit-transform': translation, + '-moz-transform': translation, + '-o-transform': translation, + '-ms-transform': translation, + transform: translation, + }, } - } - if (this.options.ticksTooltip) { - tick.tooltip = this.options.ticksTooltip(value); - tick.tooltipPlacement = this.options.vertical ? 'right' : 'top'; - } - if (this.options.showTicksValues) { - tick.value = this.getDisplayValue(value, 'tick-value'); - if (this.options.ticksValuesTooltip) { - tick.valueTooltip = this.options.ticksValuesTooltip(value); - tick.valueTooltipPlacement = this.options.vertical ? 'right' : 'top'; + if (tick.selected && self.options.getSelectionBarColor) { + tick.style['background-color'] = self.getSelectionBarColor() } - } - if (this.getLegend) { - var legend = this.getLegend(value, this.options.id); - if (legend) - tick.legend = legend; - } - if (!this.options.rightToLeft) { - this.scope.ticks.push(tick); + if (!tick.selected && self.options.getTickColor) { + tick.style['background-color'] = self.getTickColor(value) + } + if (self.options.ticksTooltip) { + tick.tooltip = self.options.ticksTooltip(value) + tick.tooltipPlacement = self.options.vertical ? 'right' : 'top' + } + if ( + self.options.showTicksValues === true || + value % self.options.showTicksValues === 0 + ) { + tick.value = self.getDisplayValue(value, 'tick-value') + if (self.options.ticksValuesTooltip) { + tick.valueTooltip = self.options.ticksValuesTooltip(value) + tick.valueTooltipPlacement = self.options.vertical + ? 'right' + : 'top' + } + } + if (self.getLegend) { + legend = self.getLegend(value, self.options.id) + if (legend) tick.legend = legend + } + return tick + }) + }, + + getTicksArray: function() { + var step = this.step, + ticksArray = [] + if (this.intermediateTicks) step = this.options.showTicks + for ( + var value = this.minValue; + value <= this.maxValue; + value += step + ) { + ticksArray.push(value) + } + return ticksArray + }, + + isTickSelected: function(value) { + if (!this.range) { + if (this.options.showSelectionBarFromValue !== null) { + var center = this.options.showSelectionBarFromValue + if ( + this.lowValue > center && + value >= center && + value <= this.lowValue + ) + return true + else if ( + this.lowValue < center && + value <= center && + value >= this.lowValue + ) + return true + } else if (this.options.showSelectionBarEnd) { + if (value >= this.lowValue) return true + } else if (this.options.showSelectionBar && value <= this.lowValue) + return true + } + if (this.range && value >= this.lowValue && value <= this.highValue) + return true + return false + }, + + /** + * Update position of the floor label + * + * @returns {undefined} + */ + updateFloorLab: function() { + this.translateFn(this.minValue, this.flrLab, 'floor') + this.getDimension(this.flrLab) + var position = this.options.rightToLeft + ? this.barDimension - this.flrLab.rzsd + : 0 + this.setPosition(this.flrLab, position) + }, + + /** + * Update position of the ceiling label + * + * @returns {undefined} + */ + updateCeilLab: function() { + this.translateFn(this.maxValue, this.ceilLab, 'ceil') + this.getDimension(this.ceilLab) + var position = this.options.rightToLeft + ? 0 + : this.barDimension - this.ceilLab.rzsd + this.setPosition(this.ceilLab, position) + }, + + /** + * Update slider handles and label positions + * + * @param {string} which + * @param {number} newPos + */ + updateHandles: function(which, newPos) { + if (which === 'lowValue') this.updateLowHandle(newPos) + else this.updateHighHandle(newPos) + + this.updateSelectionBar() + this.updateTicksScale() + if (this.range) this.updateCmbLabel() + }, + + /** + * Helper function to work out the position for handle labels depending on RTL or not + * + * @param {string} labelName maxLab or minLab + * @param newPos + * + * @returns {number} + */ + getHandleLabelPos: function(labelName, newPos) { + var labelRzsd = this[labelName].rzsd, + nearHandlePos = newPos - labelRzsd / 2 + this.handleHalfDim, + endOfBarPos = this.barDimension - labelRzsd + + if (!this.options.boundPointerLabels) return nearHandlePos + + if ( + (this.options.rightToLeft && labelName === 'minLab') || + (!this.options.rightToLeft && labelName === 'maxLab') + ) { + return Math.min(nearHandlePos, endOfBarPos) } else { - this.scope.ticks.unshift(tick); + return Math.min(Math.max(nearHandlePos, 0), endOfBarPos) } - } - }, - - isTickSelected: function(value) { - if (!this.range) { - if (this.options.showSelectionBarFromValue !== null) { - var center = this.options.showSelectionBarFromValue; - if (this.lowValue > center && value >= center && value <= this.lowValue) - return true; - else if (this.lowValue < center && value <= center && value >= this.lowValue) - return true; - } - else if (this.options.showSelectionBarEnd) { - if (value >= this.lowValue) - return true; - } - else if (this.options.showSelectionBar && value <= this.lowValue) - return true; - } - if (this.range && value >= this.lowValue && value <= this.highValue) - return true; - return false; - }, - - /** - * Update position of the floor label - * - * @returns {undefined} - */ - updateFloorLab: function() { - this.translateFn(this.minValue, this.flrLab, 'floor'); - this.getDimension(this.flrLab); - var position = this.options.rightToLeft ? this.barDimension - this.flrLab.rzsd : 0; - this.setPosition(this.flrLab, position); - }, - - /** - * Update position of the ceiling label - * - * @returns {undefined} - */ - updateCeilLab: function() { - this.translateFn(this.maxValue, this.ceilLab, 'ceil'); - this.getDimension(this.ceilLab); - var position = this.options.rightToLeft ? 0 : this.barDimension - this.ceilLab.rzsd; - this.setPosition(this.ceilLab, position); - }, - - /** - * Update slider handles and label positions - * - * @param {string} which - * @param {number} newOffset - */ - updateHandles: function(which, newOffset) { - if (which === 'lowValue') - this.updateLowHandle(newOffset); - else - this.updateHighHandle(newOffset); - - this.updateSelectionBar(); - this.updateTicksScale(); - if (this.range) - this.updateCmbLabel(); - }, + }, - /** - * Helper function to work out the position for handle labels depending on RTL or not - * - * @param {string} labelName maxLab or minLab - * @param newOffset - * - * @returns {number} - */ - getHandleLabelPos: function(labelName, newOffset) { - var labelRzsd = this[labelName].rzsd, - nearHandlePos = newOffset - labelRzsd / 2 + this.handleHalfDim, - endOfBarPos = this.barDimension - labelRzsd; - - if (!this.options.boundPointerLabels) - return nearHandlePos; - - if (this.options.rightToLeft && labelName === 'minLab' || !this.options.rightToLeft && labelName === 'maxLab') { - return Math.min(nearHandlePos, endOfBarPos); - } else { - return Math.min(Math.max(nearHandlePos, 0), endOfBarPos); - } - }, + /** + * Update low slider handle position and label + * + * @param {number} newPos + * @returns {undefined} + */ + updateLowHandle: function(newPos) { + this.setPosition(this.minH, newPos) + this.translateFn(this.lowValue, this.minLab, 'model') + this.setPosition( + this.minLab, + this.getHandleLabelPos('minLab', newPos) + ) + + if (this.options.getPointerColor) { + var pointercolor = this.getPointerColor('min') + this.scope.minPointerStyle = { + backgroundColor: pointercolor, + } + } - /** - * Update low slider handle position and label - * - * @param {number} newOffset - * @returns {undefined} - */ - updateLowHandle: function(newOffset) { - this.setPosition(this.minH, newOffset); - this.translateFn(this.lowValue, this.minLab, 'model'); - this.setPosition(this.minLab, this.getHandleLabelPos('minLab', newOffset)); - - if (this.options.getPointerColor) { - var pointercolor = this.getPointerColor('min'); - this.scope.minPointerStyle = { - backgroundColor: pointercolor - }; - } + if (this.options.autoHideLimitLabels) { + this.shFloorCeil() + } + }, - if (this.options.autoHideLimitLabels) { - this.shFloorCeil(); - } - }, + /** + * Update high slider handle position and label + * + * @param {number} newPos + * @returns {undefined} + */ + updateHighHandle: function(newPos) { + this.setPosition(this.maxH, newPos) + this.translateFn(this.highValue, this.maxLab, 'high') + this.setPosition( + this.maxLab, + this.getHandleLabelPos('maxLab', newPos) + ) + + if (this.options.getPointerColor) { + var pointercolor = this.getPointerColor('max') + this.scope.maxPointerStyle = { + backgroundColor: pointercolor, + } + } + if (this.options.autoHideLimitLabels) { + this.shFloorCeil() + } + }, - /** - * Update high slider handle position and label - * - * @param {number} newOffset - * @returns {undefined} - */ - updateHighHandle: function(newOffset) { - this.setPosition(this.maxH, newOffset); - this.translateFn(this.highValue, this.maxLab, 'high'); - this.setPosition(this.maxLab, this.getHandleLabelPos('maxLab', newOffset)); - - if (this.options.getPointerColor) { - var pointercolor = this.getPointerColor('max'); - this.scope.maxPointerStyle = { - backgroundColor: pointercolor - }; - } - if (this.options.autoHideLimitLabels) { - this.shFloorCeil(); - } + /** + * Show/hide floor/ceiling label + * + * @returns {undefined} + */ + shFloorCeil: function() { + // Show based only on hideLimitLabels if pointer labels are hidden + if (this.options.hidePointerLabels) { + return + } + var flHidden = false, + clHidden = false, + isMinLabAtFloor = this.isLabelBelowFloorLab(this.minLab), + isMinLabAtCeil = this.isLabelAboveCeilLab(this.minLab), + isMaxLabAtCeil = this.isLabelAboveCeilLab(this.maxLab), + isCmbLabAtFloor = this.isLabelBelowFloorLab(this.cmbLab), + isCmbLabAtCeil = this.isLabelAboveCeilLab(this.cmbLab) + + if (isMinLabAtFloor) { + flHidden = true + this.hideEl(this.flrLab) + } else { + flHidden = false + this.showEl(this.flrLab) + } - }, + if (isMinLabAtCeil) { + clHidden = true + this.hideEl(this.ceilLab) + } else { + clHidden = false + this.showEl(this.ceilLab) + } - /** - * Show/hide floor/ceiling label - * - * @returns {undefined} - */ - shFloorCeil: function() { - // Show based only on hideLimitLabels if pointer labels are hidden - if (this.options.hidePointerLabels) { - return; - } - var flHidden = false, - clHidden = false, - isRTL = this.options.rightToLeft, - flrLabPos = this.flrLab.rzsp, - flrLabDim = this.flrLab.rzsd, - minLabPos = this.minLab.rzsp, - minLabDim = this.minLab.rzsd, - maxLabPos = this.maxLab.rzsp, - maxLabDim = this.maxLab.rzsd, - cmbLabPos = this.cmbLab.rzsp, - cmbLabDim = this.cmbLab.rzsd, - ceilLabPos = this.ceilLab.rzsp, - halfHandle = this.handleHalfDim, - isMinLabAtFloor = isRTL ? minLabPos + minLabDim >= flrLabPos - flrLabDim - 5 : minLabPos <= flrLabPos + flrLabDim + 5, - isMinLabAtCeil = isRTL ? minLabPos - minLabDim <= ceilLabPos + halfHandle + 10 : minLabPos + minLabDim >= ceilLabPos - halfHandle - 10, - isMaxLabAtFloor = isRTL ? maxLabPos >= flrLabPos - flrLabDim - halfHandle : maxLabPos <= flrLabPos + flrLabDim + halfHandle, - isMaxLabAtCeil = isRTL ? maxLabPos - maxLabDim <= ceilLabPos + 10 : maxLabPos + maxLabDim >= ceilLabPos - 10, - isCmbLabAtFloor = isRTL ? cmbLabPos >= flrLabPos - flrLabDim - halfHandle : cmbLabPos <= flrLabPos + flrLabDim + halfHandle, - isCmbLabAtCeil = isRTL ? cmbLabPos - cmbLabDim <= ceilLabPos + 10 : cmbLabPos + cmbLabDim >= ceilLabPos - 10 - - - if (isMinLabAtFloor) { - flHidden = true; - this.hideEl(this.flrLab); - } else { - flHidden = false; - this.showEl(this.flrLab); - } + if (this.range) { + var hideCeil = this.cmbLabelShown ? isCmbLabAtCeil : isMaxLabAtCeil + var hideFloor = this.cmbLabelShown + ? isCmbLabAtFloor + : isMinLabAtFloor + + if (hideCeil) { + this.hideEl(this.ceilLab) + } else if (!clHidden) { + this.showEl(this.ceilLab) + } - if (isMinLabAtCeil) { - clHidden = true; - this.hideEl(this.ceilLab); - } else { - clHidden = false; - this.showEl(this.ceilLab); - } + // Hide or show floor label + if (hideFloor) { + this.hideEl(this.flrLab) + } else if (!flHidden) { + this.showEl(this.flrLab) + } + } + }, + + isLabelBelowFloorLab: function(label) { + var isRTL = this.options.rightToLeft, + pos = label.rzsp, + dim = label.rzsd, + floorPos = this.flrLab.rzsp, + floorDim = this.flrLab.rzsd + return isRTL + ? pos + dim >= floorPos - 2 + : pos <= floorPos + floorDim + 2 + }, + + isLabelAboveCeilLab: function(label) { + var isRTL = this.options.rightToLeft, + pos = label.rzsp, + dim = label.rzsd, + ceilPos = this.ceilLab.rzsp, + ceilDim = this.ceilLab.rzsd + return isRTL ? pos <= ceilPos + ceilDim + 2 : pos + dim >= ceilPos - 2 + }, + + /** + * Update restricted area bar + * + * @returns {undefined} + */ + updateRestrictionBar: function() { + var position = 0, + dimension = 0 + if (this.options.restrictedRange) { + this.options.restrictedRange = !Array.isArray( + this.options.restrictedRange + ) + ? [this.options.restrictedRange] + : this.options.restrictedRange + for (var i in this.options.restrictedRange) { + var from = this.valueToPosition( + this.options.restrictedRange[i].from + ), + to = this.valueToPosition(this.options.restrictedRange[i].to) + dimension = Math.abs(to - from) + position = this.options.rightToLeft + ? to + this.handleHalfDim + : from + this.handleHalfDim + this.setDimension(this.restrictedBar[i], dimension) + this.setPosition(this.restrictedBar[i], position) + } + } + }, - if (this.range) { - var hideCeil = this.cmbLabelShown ? isCmbLabAtCeil : isMaxLabAtCeil; - var hideFloor = this.cmbLabelShown ? isCmbLabAtFloor : isMinLabAtFloor; + /** + * Update slider selection bar, combined label and range label + * + * @returns {undefined} + */ + updateSelectionBar: function() { + var position = 0, + dimension = 0, + isSelectionBarFromRight = this.options.rightToLeft + ? !this.options.showSelectionBarEnd + : this.options.showSelectionBarEnd, + positionForRange = this.options.rightToLeft + ? this.maxH.rzsp + this.handleHalfDim + : this.minH.rzsp + this.handleHalfDim - if (hideCeil) { - this.hideEl(this.ceilLab); - } else if (!clHidden) { - this.showEl(this.ceilLab); + if (this.range) { + dimension = Math.abs(this.maxH.rzsp - this.minH.rzsp) + position = positionForRange + } else { + if (this.options.showSelectionBarFromValue !== null) { + var center = this.options.showSelectionBarFromValue, + centerPosition = this.valueToPosition(center), + isModelGreaterThanCenter = this.options.rightToLeft + ? this.lowValue <= center + : this.lowValue > center + if (isModelGreaterThanCenter) { + dimension = this.minH.rzsp - centerPosition + position = centerPosition + this.handleHalfDim + } else { + dimension = centerPosition - this.minH.rzsp + position = this.minH.rzsp + this.handleHalfDim + } + } else if (isSelectionBarFromRight) { + dimension = + Math.abs(this.maxPos - this.minH.rzsp) + this.handleHalfDim + position = this.minH.rzsp + this.handleHalfDim + } else { + dimension = this.minH.rzsp + this.handleHalfDim + position = 0 + } } - - // Hide or show floor label - if (hideFloor) { - this.hideEl(this.flrLab); - } else if (!flHidden) { - this.showEl(this.flrLab); + this.setDimension(this.selBar, dimension) + this.setPosition(this.selBar, position) + if (this.range && this.options.showOuterSelectionBars) { + if (this.options.rightToLeft) { + this.setDimension(this.rightOutSelBar, position) + this.setPosition(this.rightOutSelBar, 0) + this.setDimension( + this.leftOutSelBar, + this.getDimension(this.fullBar) - (position + dimension) + ) + this.setPosition(this.leftOutSelBar, position + dimension) + } else { + this.setDimension(this.leftOutSelBar, position) + this.setPosition(this.leftOutSelBar, 0) + this.setDimension( + this.rightOutSelBar, + this.getDimension(this.fullBar) - (position + dimension) + ) + this.setPosition(this.rightOutSelBar, position + dimension) + } } - } - }, - - /** - * Update slider selection bar, combined label and range label - * - * @returns {undefined} - */ - updateSelectionBar: function() { - var position = 0, - dimension = 0, - isSelectionBarFromRight = this.options.rightToLeft ? !this.options.showSelectionBarEnd : this.options.showSelectionBarEnd, - positionForRange = this.options.rightToLeft ? this.maxH.rzsp + this.handleHalfDim : this.minH.rzsp + this.handleHalfDim; - - if (this.range) { - dimension = Math.abs(this.maxH.rzsp - this.minH.rzsp); - position = positionForRange; - } - else { - if (this.options.showSelectionBarFromValue !== null) { - var center = this.options.showSelectionBarFromValue, - centerPosition = this.valueToOffset(center), - isModelGreaterThanCenter = this.options.rightToLeft ? this.lowValue <= center : this.lowValue > center; - if (isModelGreaterThanCenter) { - dimension = this.minH.rzsp - centerPosition; - position = centerPosition + this.handleHalfDim; + if (this.options.getSelectionBarColor) { + var color = this.getSelectionBarColor() + this.scope.barStyle = { + backgroundColor: color, + } + } else if (this.options.selectionBarGradient) { + var offset = + this.options.showSelectionBarFromValue !== null + ? this.valueToPosition(this.options.showSelectionBarFromValue) + : 0, + reversed = (offset - position > 0) ^ isSelectionBarFromRight, + direction = this.options.vertical + ? reversed + ? 'bottom' + : 'top' + : reversed + ? 'left' + : 'right' + this.scope.barStyle = { + backgroundImage: + 'linear-gradient(to ' + + direction + + ', ' + + this.options.selectionBarGradient.from + + ' 0%,' + + this.options.selectionBarGradient.to + + ' 100%)', } - else { - dimension = centerPosition - this.minH.rzsp; - position = this.minH.rzsp + this.handleHalfDim; + if (this.options.vertical) { + this.scope.barStyle.backgroundPosition = + 'center ' + + (offset + + dimension + + position + + (reversed ? -this.handleHalfDim : 0)) + + 'px' + this.scope.barStyle.backgroundSize = + '100% ' + (this.barDimension - this.handleHalfDim) + 'px' + } else { + this.scope.barStyle.backgroundPosition = + offset - + position + + (reversed ? this.handleHalfDim : 0) + + 'px center' + this.scope.barStyle.backgroundSize = + this.barDimension - this.handleHalfDim + 'px 100%' } } - else if (isSelectionBarFromRight) { - dimension = Math.abs(this.maxPos - this.minH.rzsp) + this.handleHalfDim; - position = this.minH.rzsp + this.handleHalfDim; + }, + + /** + * Wrapper around the getSelectionBarColor of the user to pass to + * correct parameters + */ + getSelectionBarColor: function() { + if (this.range) + return this.options.getSelectionBarColor( + this.scope.rzSliderModel, + this.scope.rzSliderHigh + ) + return this.options.getSelectionBarColor(this.scope.rzSliderModel) + }, + + /** + * Wrapper around the getPointerColor of the user to pass to + * correct parameters + */ + getPointerColor: function(pointerType) { + if (pointerType === 'max') { + return this.options.getPointerColor( + this.scope.rzSliderHigh, + pointerType + ) + } + return this.options.getPointerColor( + this.scope.rzSliderModel, + pointerType + ) + }, + + /** + * Wrapper around the getTickColor of the user to pass to + * correct parameters + */ + getTickColor: function(value) { + return this.options.getTickColor(value) + }, + + /** + * Update combined label position and value + * + * @returns {undefined} + */ + updateCmbLabel: function() { + var isLabelOverlap = null + if (this.options.rightToLeft) { + isLabelOverlap = + this.minLab.rzsp - this.minLab.rzsd - 10 <= this.maxLab.rzsp } else { - dimension = Math.abs(this.maxH.rzsp - this.minH.rzsp) + this.handleHalfDim; - position = 0; + isLabelOverlap = + this.minLab.rzsp + this.minLab.rzsd + 10 >= this.maxLab.rzsp } - } - this.setDimension(this.selBar, dimension); - this.setPosition(this.selBar, position); - if (this.options.getSelectionBarColor) { - var color = this.getSelectionBarColor(); - this.scope.barStyle = { - backgroundColor: color - }; - } - }, - - /** - * Wrapper around the getSelectionBarColor of the user to pass to - * correct parameters - */ - getSelectionBarColor: function() { - if (this.range) - return this.options.getSelectionBarColor(this.scope.rzSliderModel, this.scope.rzSliderHigh); - return this.options.getSelectionBarColor(this.scope.rzSliderModel); - }, - /** - * Wrapper around the getPointerColor of the user to pass to - * correct parameters - */ - getPointerColor: function(pointerType) { - if (pointerType === 'max') { - return this.options.getPointerColor(this.scope.rzSliderHigh, pointerType); - } - return this.options.getPointerColor(this.scope.rzSliderModel, pointerType); - }, - - /** - * Wrapper around the getTickColor of the user to pass to - * correct parameters - */ - getTickColor: function(value) { - return this.options.getTickColor(value); - }, - - /** - * Update combined label position and value - * - * @returns {undefined} - */ - updateCmbLabel: function() { - var isLabelOverlap = null; - if (this.options.rightToLeft) { - isLabelOverlap = this.minLab.rzsp - this.minLab.rzsd - 10 <= this.maxLab.rzsp; - } else { - isLabelOverlap = this.minLab.rzsp + this.minLab.rzsd + 10 >= this.maxLab.rzsp; - } + if (isLabelOverlap) { + var lowTr = this.getDisplayValue(this.lowValue, 'model'), + highTr = this.getDisplayValue(this.highValue, 'high'), + labelVal = '' + if (this.options.mergeRangeLabelsIfSame && lowTr === highTr) { + labelVal = lowTr + } else { + labelVal = this.options.rightToLeft + ? highTr + this.options.labelOverlapSeparator + lowTr + : lowTr + this.options.labelOverlapSeparator + highTr + } - if (isLabelOverlap) { - var lowTr = this.getDisplayValue(this.lowValue, 'model'), - highTr = this.getDisplayValue(this.highValue, 'high'), - labelVal = ''; - if (this.options.mergeRangeLabelsIfSame && lowTr === highTr) { - labelVal = lowTr; + this.translateFn(labelVal, this.cmbLab, 'cmb', false) + var pos = this.options.boundPointerLabels + ? Math.min( + Math.max( + this.selBar.rzsp + + this.selBar.rzsd / 2 - + this.cmbLab.rzsd / 2, + 0 + ), + this.barDimension - this.cmbLab.rzsd + ) + : this.selBar.rzsp + this.selBar.rzsd / 2 - this.cmbLab.rzsd / 2 + + this.setPosition(this.cmbLab, pos) + this.cmbLabelShown = true + this.hideEl(this.minLab) + this.hideEl(this.maxLab) + this.showEl(this.cmbLab) } else { - labelVal = this.options.rightToLeft ? highTr + ' - ' + lowTr : lowTr + ' - ' + highTr; + this.cmbLabelShown = false + this.updateHighHandle(this.valueToPosition(this.highValue)) + this.updateLowHandle(this.valueToPosition(this.lowValue)) + this.showEl(this.maxLab) + this.showEl(this.minLab) + this.hideEl(this.cmbLab) + } + if (this.options.autoHideLimitLabels) { + this.shFloorCeil() } + }, - this.translateFn(labelVal, this.cmbLab, 'cmb', false); - var pos = this.options.boundPointerLabels ? Math.min( - Math.max( - this.selBar.rzsp + this.selBar.rzsd / 2 - this.cmbLab.rzsd / 2, - 0 - ), - this.barDimension - this.cmbLab.rzsd - ) : this.selBar.rzsp + this.selBar.rzsd / 2 - this.cmbLab.rzsd / 2; - - this.setPosition(this.cmbLab, pos); - this.cmbLabelShown = true; - this.hideEl(this.minLab); - this.hideEl(this.maxLab); - this.showEl(this.cmbLab); - } else { - this.cmbLabelShown = false; - this.showEl(this.maxLab); - this.showEl(this.minLab); - this.hideEl(this.cmbLab); - } - }, + /** + * Return the translated value if a translate function is provided else the original value + * @param value + * @param which if it's min or max handle + * @returns {*} + */ + getDisplayValue: function(value, which) { + if (this.options.stepsArray && !this.options.bindIndexForStepsArray) { + value = this.getStepValue(value) + } + return this.customTrFn(value, this.options.id, which) + }, + + /** + * Round value to step and precision based on minValue + * + * @param {number} value + * @param {number} customStep a custom step to override the defined step + * @returns {number} + */ + roundStep: function(value, customStep) { + var step = customStep ? customStep : this.step, + steppedDifference = parseFloat( + (value - this.minValue) / step + ).toPrecision(12) + steppedDifference = Math.round(+steppedDifference) * step + var newValue = (this.minValue + steppedDifference).toFixed( + this.precision + ) + return +newValue + }, + + /** + * Hide element + * + * @param element + * @returns {jqLite} The jqLite wrapped DOM element + */ + hideEl: function(element) { + return element.css({ + visibility: 'hidden', + }) + }, + + /** + * Show element + * + * @param element The jqLite wrapped DOM element + * @returns {jqLite} The jqLite + */ + showEl: function(element) { + if (!!element.rzAlwaysHide) { + return element + } - /** - * Return the translated value if a translate function is provided else the original value - * @param value - * @param which if it's min or max handle - * @returns {*} - */ - getDisplayValue: function(value, which) { - if (this.options.stepsArray && !this.options.bindIndexForStepsArray) { - value = this.getStepValue(value); - } - return this.customTrFn(value, this.options.id, which); - }, + return element.css({ + visibility: 'visible', + }) + }, + + /** + * Set element left/top position depending on whether slider is horizontal or vertical + * + * @param {jqLite} elem The jqLite wrapped DOM element + * @param {number} pos + * @returns {number} + */ + setPosition: function(elem, pos) { + elem.rzsp = pos + var css = {} + css[this.positionProperty] = Math.round(pos) + 'px' + elem.css(css) + return pos + }, + + resetPosition: function(elem) { + elem.css({ + left: null, + bottom: null, + }) + }, + + /** + * Get element width/height depending on whether slider is horizontal or vertical + * + * @param {jqLite} elem The jqLite wrapped DOM element + * @returns {number} + */ + getDimension: function(elem) { + var val = elem[0].getBoundingClientRect() + if (this.options.vertical) + elem.rzsd = (val.bottom - val.top) * this.options.scale + else elem.rzsd = (val.right - val.left) * this.options.scale + return elem.rzsd + }, + + /** + * Set element width/height depending on whether slider is horizontal or vertical + * + * @param {jqLite} elem The jqLite wrapped DOM element + * @param {number} dim + * @returns {number} + */ + setDimension: function(elem, dim) { + elem.rzsd = dim + var css = {} + css[this.dimensionProperty] = Math.round(dim) + 'px' + elem.css(css) + return dim + }, + + /** + * Returns a value that is within slider range + * + * @param {number} val + * @returns {number} + */ + sanitizeValue: function(val) { + return Math.min(Math.max(val, this.minValue), this.maxValue) + }, + + /** + * Translate value to pixel position + * + * @param {number} val + * @returns {number} + */ + valueToPosition: function(val) { + var fn = this.linearValueToPosition + if (this.options.customValueToPosition) + fn = this.options.customValueToPosition + else if (this.options.logScale) fn = this.logValueToPosition + + val = this.sanitizeValue(val) + var percent = fn(val, this.minValue, this.maxValue) || 0 + if (this.options.rightToLeft) percent = 1 - percent + return percent * this.maxPos + }, + + linearValueToPosition: function(val, minVal, maxVal) { + var range = maxVal - minVal + return (val - minVal) / range + }, + + logValueToPosition: function(val, minVal, maxVal) { + val = Math.log(val) + minVal = Math.log(minVal) + maxVal = Math.log(maxVal) + var range = maxVal - minVal + return (val - minVal) / range + }, + + /** + * Translate position to model value + * + * @param {number} position + * @returns {number} + */ + positionToValue: function(position) { + var percent = position / this.maxPos + if (this.options.rightToLeft) percent = 1 - percent + var fn = this.linearPositionToValue + if (this.options.customPositionToValue) + fn = this.options.customPositionToValue + else if (this.options.logScale) fn = this.logPositionToValue + return fn(percent, this.minValue, this.maxValue) || 0 + }, + + linearPositionToValue: function(percent, minVal, maxVal) { + return percent * (maxVal - minVal) + minVal + }, + + logPositionToValue: function(percent, minVal, maxVal) { + minVal = Math.log(minVal) + maxVal = Math.log(maxVal) + var value = percent * (maxVal - minVal) + minVal + return Math.exp(value) + }, + + getEventAttr: function(event, attr) { + return event.originalEvent === undefined + ? event[attr] + : event.originalEvent[attr] + }, + + // Events + /** + * Get the X-coordinate or Y-coordinate of an event + * + * @param {Object} event The event + * @param targetTouchId The identifier of the touch with the X/Y coordinates + * @returns {number} + */ + getEventXY: function(event, targetTouchId) { + /* http://stackoverflow.com/a/12336075/282882 */ + //noinspection JSLint + var clientXY = this.options.vertical ? 'clientY' : 'clientX' + if (event[clientXY] !== undefined) { + return event[clientXY] + } - /** - * Round value to step and precision based on minValue - * - * @param {number} value - * @param {number} customStep a custom step to override the defined step - * @returns {number} - */ - roundStep: function(value, customStep) { - var step = customStep ? customStep : this.step, - steppedDifference = parseFloat((value - this.minValue) / step).toPrecision(12); - steppedDifference = Math.round(+steppedDifference) * step; - var newValue = (this.minValue + steppedDifference).toFixed(this.precision); - return +newValue; - }, + var touches = this.getEventAttr(event, 'touches') - /** - * Hide element - * - * @param element - * @returns {jqLite} The jqLite wrapped DOM element - */ - hideEl: function(element) { - return element.css({ - visibility: 'hidden' - }); - }, + if (targetTouchId !== undefined) { + for (var i = 0; i < touches.length; i++) { + if (touches[i].identifier === targetTouchId) { + return touches[i][clientXY] + } + } + } - /** - * Show element - * - * @param element The jqLite wrapped DOM element - * @returns {jqLite} The jqLite - */ - showEl: function(element) { - if (!!element.rzAlwaysHide) { - return element; - } + // If no target touch or the target touch was not found in the event + // returns the coordinates of the first touch + return touches[0][clientXY] + }, - return element.css({ - visibility: 'visible' - }); - }, + /** + * Compute the event position depending on whether the slider is horizontal or vertical + * @param event + * @param targetTouchId If targetTouchId is provided it will be considered the position of that + * @returns {number} + */ + getEventPosition: function(event, targetTouchId) { + var sliderPos = this.sliderElem.rzsp, + eventPos = 0 + if (this.options.vertical) + eventPos = -this.getEventXY(event, targetTouchId) + sliderPos + else eventPos = this.getEventXY(event, targetTouchId) - sliderPos + return eventPos * this.options.scale - this.handleHalfDim // #346 handleHalfDim is already scaled + }, + + /** + * Get event names for move and event end + * + * @param {Event} event The event + * + * @return {{moveEvent: string, endEvent: string}} + */ + getEventNames: function(event) { + var eventNames = { + moveEvent: '', + endEvent: '', + } - /** - * Set element left/top offset depending on whether slider is horizontal or vertical - * - * @param {jqLite} elem The jqLite wrapped DOM element - * @param {number} pos - * @returns {number} - */ - setPosition: function(elem, pos) { - elem.rzsp = pos; - var css = {}; - css[this.positionProperty] = pos + 'px'; - elem.css(css); - return pos; - }, + if (this.getEventAttr(event, 'touches')) { + eventNames.moveEvent = 'touchmove' + eventNames.endEvent = 'touchend' + } else { + eventNames.moveEvent = 'mousemove' + eventNames.endEvent = 'mouseup' + } - /** - * Get element width/height depending on whether slider is horizontal or vertical - * - * @param {jqLite} elem The jqLite wrapped DOM element - * @returns {number} - */ - getDimension: function(elem) { - var val = elem[0].getBoundingClientRect(); - if (this.options.vertical) - elem.rzsd = (val.bottom - val.top) * this.options.scale; - else - elem.rzsd = (val.right - val.left) * this.options.scale; - return elem.rzsd; - }, + return eventNames + }, - /** - * Set element width/height depending on whether slider is horizontal or vertical - * - * @param {jqLite} elem The jqLite wrapped DOM element - * @param {number} dim - * @returns {number} - */ - setDimension: function(elem, dim) { - elem.rzsd = dim; - var css = {}; - css[this.dimensionProperty] = dim + 'px'; - elem.css(css); - return dim; - }, + /** + * Get the handle closest to an event. + * + * @param event {Event} The event + * @returns {jqLite} The handle closest to the event. + */ + getNearestHandle: function(event) { + if (!this.range) { + return this.minH + } + var position = this.getEventPosition(event), + distanceMin = Math.abs(position - this.minH.rzsp), + distanceMax = Math.abs(position - this.maxH.rzsp) + if (distanceMin < distanceMax) return this.minH + else if (distanceMin > distanceMax) return this.maxH + else if (!this.options.rightToLeft) + //if event is at the same distance from min/max then if it's at left of minH, we return minH else maxH + return position < this.minH.rzsp ? this.minH : this.maxH + //reverse in rtl + else return position > this.minH.rzsp ? this.minH : this.maxH + }, + + /** + * Wrapper function to focus an angular element + * + * @param el {AngularElement} the element to focus + */ + focusElement: function(el) { + var DOM_ELEMENT = 0 + el[DOM_ELEMENT].focus() + }, + + /** + * Bind mouse and touch events to slider handles + * + * @returns {undefined} + */ + bindEvents: function() { + var barTracking, barStart, barMove - /** - * Translate value to pixel offset - * - * @param {number} val - * @returns {number} - */ - valueToOffset: function(val) { - if (this.options.rightToLeft) { - return (this.maxValue - this.sanitizeValue(val)) * this.maxPos / this.valueRange || 0; - } - return (this.sanitizeValue(val) - this.minValue) * this.maxPos / this.valueRange || 0; - }, + if (this.options.draggableRange) { + barTracking = 'rzSliderDrag' + barStart = this.onDragStart + barMove = this.onDragMove + } else { + barTracking = 'lowValue' + barStart = this.onStart + barMove = this.onMove + } - /** - * Returns a value that is within slider range - * - * @param {number} val - * @returns {number} - */ - sanitizeValue: function(val) { - return Math.min(Math.max(val, this.minValue), this.maxValue); - }, + if (!this.options.onlyBindHandles) { + this.selBar.on( + 'mousedown', + angular.bind(this, barStart, null, barTracking) + ) + this.selBar.on( + 'mousedown', + angular.bind(this, barMove, this.selBar) + ) + } - /** - * Translate offset to model value - * - * @param {number} offset - * @returns {number} - */ - offsetToValue: function(offset) { - if (this.options.rightToLeft) { - return (1 - (offset / this.maxPos)) * this.valueRange + this.minValue; - } - return (offset / this.maxPos) * this.valueRange + this.minValue; - }, + if (this.options.draggableRangeOnly) { + this.minH.on( + 'mousedown', + angular.bind(this, barStart, null, barTracking) + ) + this.maxH.on( + 'mousedown', + angular.bind(this, barStart, null, barTracking) + ) + } else { + this.minH.on( + 'mousedown', + angular.bind(this, this.onStart, this.minH, 'lowValue') + ) + if (this.range) { + this.maxH.on( + 'mousedown', + angular.bind(this, this.onStart, this.maxH, 'highValue') + ) + } + if (!this.options.onlyBindHandles) { + this.fullBar.on( + 'mousedown', + angular.bind(this, this.onStart, null, null) + ) + this.fullBar.on( + 'mousedown', + angular.bind(this, this.onMove, this.fullBar) + ) + this.ticks.on( + 'mousedown', + angular.bind(this, this.onStart, null, null) + ) + this.ticks.on( + 'mousedown', + angular.bind(this, this.onTickClick, this.ticks) + ) + } + } - // Events + if (!this.options.onlyBindHandles) { + this.selBar.on( + 'touchstart', + angular.bind(this, barStart, null, barTracking) + ) + this.selBar.on( + 'touchstart', + angular.bind(this, barMove, this.selBar) + ) + } + if (this.options.draggableRangeOnly) { + this.minH.on( + 'touchstart', + angular.bind(this, barStart, null, barTracking) + ) + this.maxH.on( + 'touchstart', + angular.bind(this, barStart, null, barTracking) + ) + } else { + this.minH.on( + 'touchstart', + angular.bind(this, this.onStart, this.minH, 'lowValue') + ) + if (this.range) { + this.maxH.on( + 'touchstart', + angular.bind(this, this.onStart, this.maxH, 'highValue') + ) + } + if (!this.options.onlyBindHandles) { + this.fullBar.on( + 'touchstart', + angular.bind(this, this.onStart, null, null) + ) + this.fullBar.on( + 'touchstart', + angular.bind(this, this.onMove, this.fullBar) + ) + this.ticks.on( + 'touchstart', + angular.bind(this, this.onStart, null, null) + ) + this.ticks.on( + 'touchstart', + angular.bind(this, this.onTickClick, this.ticks) + ) + } + } - /** - * Get the X-coordinate or Y-coordinate of an event - * - * @param {Object} event The event - * @returns {number} - */ - getEventXY: function(event) { - /* http://stackoverflow.com/a/12336075/282882 */ - //noinspection JSLint - var clientXY = this.options.vertical ? 'clientY' : 'clientX'; - if (event[clientXY] !== undefined) { - return event[clientXY]; - } + if (this.options.keyboardSupport) { + this.minH.on( + 'focus', + angular.bind(this, this.onPointerFocus, this.minH, 'lowValue') + ) + if (this.range) { + this.maxH.on( + 'focus', + angular.bind(this, this.onPointerFocus, this.maxH, 'highValue') + ) + } + } + }, - return event.originalEvent === undefined ? - event.touches[0][clientXY] : event.originalEvent.touches[0][clientXY]; - }, + /** + * Unbind mouse and touch events to slider handles + * + * @returns {undefined} + */ + unbindEvents: function() { + this.minH.off() + this.maxH.off() + this.fullBar.off() + this.selBar.off() + this.ticks.off() + }, + + /** + * onStart event handler + * + * @param {?Object} pointer The jqLite wrapped DOM element; if null, the closest handle is used + * @param {?string} ref The name of the handle being changed; if null, the closest handle's value is modified + * @param {Event} event The event + * @returns {undefined} + */ + onStart: function(pointer, ref, event) { + var ehMove, + ehEnd, + eventNames = this.getEventNames(event) - /** - * Compute the event position depending on whether the slider is horizontal or vertical - * @param event - * @returns {number} - */ - getEventPosition: function(event) { - var sliderPos = this.sliderElem.rzsp, - eventPos = 0; - if (this.options.vertical) - eventPos = -this.getEventXY(event) + sliderPos; - else - eventPos = this.getEventXY(event) - sliderPos; - return (eventPos - this.handleHalfDim) * this.options.scale; - }, + event.stopPropagation() + event.preventDefault() - /** - * Get event names for move and event end - * - * @param {Event} event The event - * - * @return {{moveEvent: string, endEvent: string}} - */ - getEventNames: function(event) { - var eventNames = { - moveEvent: '', - endEvent: '' - }; - - if (event.touches || (event.originalEvent !== undefined && event.originalEvent.touches)) { - eventNames.moveEvent = 'touchmove'; - eventNames.endEvent = 'touchend'; - } else { - eventNames.moveEvent = 'mousemove'; - eventNames.endEvent = 'mouseup'; - } + // We have to do this in case the HTML where the sliders are on + // have been animated into view. + this.calcViewDimensions() - return eventNames; - }, + if (pointer) { + this.tracking = ref + } else { + pointer = this.getNearestHandle(event) + this.tracking = pointer === this.minH ? 'lowValue' : 'highValue' + } - /** - * Get the handle closest to an event. - * - * @param event {Event} The event - * @returns {jqLite} The handle closest to the event. - */ - getNearestHandle: function(event) { - if (!this.range) { - return this.minH; - } - var offset = this.getEventPosition(event), - distanceMin = Math.abs(offset - this.minH.rzsp), - distanceMax = Math.abs(offset - this.maxH.rzsp); - if (distanceMin < distanceMax) - return this.minH; - else if (distanceMin > distanceMax) - return this.maxH; - else if (!this.options.rightToLeft) - //if event is at the same distance from min/max then if it's at left of minH, we return minH else maxH - return offset < this.minH.rzsp ? this.minH : this.maxH; - else - //reverse in rtl - return offset > this.minH.rzsp ? this.minH : this.maxH; - }, + pointer.addClass('rz-active') - /** - * Wrapper function to focus an angular element - * - * @param el {AngularElement} the element to focus - */ - focusElement: function(el) { - var DOM_ELEMENT = 0; - el[DOM_ELEMENT].focus(); - }, + if (this.options.keyboardSupport) this.focusElement(pointer) - /** - * Bind mouse and touch events to slider handles - * - * @returns {undefined} - */ - bindEvents: function() { - var barTracking, barStart, barMove; - - if (this.options.draggableRange) { - barTracking = 'rzSliderDrag'; - barStart = this.onDragStart; - barMove = this.onDragMove; - } else { - barTracking = 'lowValue'; - barStart = this.onStart; - barMove = this.onMove; - } + ehMove = angular.bind( + this, + this.dragging.active ? this.onDragMove : this.onMove, + pointer + ) + ehEnd = angular.bind(this, this.onEnd, ehMove) - if (!this.options.onlyBindHandles) { - this.selBar.on('mousedown', angular.bind(this, barStart, null, barTracking)); - this.selBar.on('mousedown', angular.bind(this, barMove, this.selBar)); - } + $document.on(eventNames.moveEvent, ehMove) + $document.on(eventNames.endEvent, ehEnd) + this.endHandlerToBeRemovedOnEnd = ehEnd - if (this.options.draggableRangeOnly) { - this.minH.on('mousedown', angular.bind(this, barStart, null, barTracking)); - this.maxH.on('mousedown', angular.bind(this, barStart, null, barTracking)); - } else { - this.minH.on('mousedown', angular.bind(this, this.onStart, this.minH, 'lowValue')); - if (this.range) { - this.maxH.on('mousedown', angular.bind(this, this.onStart, this.maxH, 'highValue')); - } - if (!this.options.onlyBindHandles) { - this.fullBar.on('mousedown', angular.bind(this, this.onStart, null, null)); - this.fullBar.on('mousedown', angular.bind(this, this.onMove, this.fullBar)); - this.ticks.on('mousedown', angular.bind(this, this.onStart, null, null)); - this.ticks.on('mousedown', angular.bind(this, this.onTickClick, this.ticks)); - } - } + this.callOnStart() - if (!this.options.onlyBindHandles) { - this.selBar.on('touchstart', angular.bind(this, barStart, null, barTracking)); - this.selBar.on('touchstart', angular.bind(this, barMove, this.selBar)); - } - if (this.options.draggableRangeOnly) { - this.minH.on('touchstart', angular.bind(this, barStart, null, barTracking)); - this.maxH.on('touchstart', angular.bind(this, barStart, null, barTracking)); - } else { - this.minH.on('touchstart', angular.bind(this, this.onStart, this.minH, 'lowValue')); - if (this.range) { - this.maxH.on('touchstart', angular.bind(this, this.onStart, this.maxH, 'highValue')); + var changedTouches = this.getEventAttr(event, 'changedTouches') + if (changedTouches) { + // Store the touch identifier + if (!this.touchId) { + this.isDragging = true + this.touchId = changedTouches[0].identifier + } } - if (!this.options.onlyBindHandles) { - this.fullBar.on('touchstart', angular.bind(this, this.onStart, null, null)); - this.fullBar.on('touchstart', angular.bind(this, this.onMove, this.fullBar)); - this.ticks.on('touchstart', angular.bind(this, this.onStart, null, null)); - this.ticks.on('touchstart', angular.bind(this, this.onTickClick, this.ticks)); + }, + + /** + * onMove event handler + * + * @param {jqLite} pointer + * @param {Event} event The event + * @param {boolean} fromTick if the event occured on a tick or not + * @returns {undefined} + */ + onMove: function(pointer, event, fromTick) { + if (!this.options.disableAnimation) { + if (this.moving) { + this.sliderElem.addClass('noanimate') + } } - } - - if (this.options.keyboardSupport) { - this.minH.on('focus', angular.bind(this, this.onPointerFocus, this.minH, 'lowValue')); - if (this.range) { - this.maxH.on('focus', angular.bind(this, this.onPointerFocus, this.maxH, 'highValue')); + this.moving = true + var changedTouches = this.getEventAttr(event, 'changedTouches') + var touchForThisSlider + if (changedTouches) { + for (var i = 0; i < changedTouches.length; i++) { + if (changedTouches[i].identifier === this.touchId) { + touchForThisSlider = changedTouches[i] + break + } + } } - } - }, - /** - * Unbind mouse and touch events to slider handles - * - * @returns {undefined} - */ - unbindEvents: function() { - this.minH.off(); - this.maxH.off(); - this.fullBar.off(); - this.selBar.off(); - this.ticks.off(); - }, - - /** - * onStart event handler - * - * @param {?Object} pointer The jqLite wrapped DOM element; if null, the closest handle is used - * @param {?string} ref The name of the handle being changed; if null, the closest handle's value is modified - * @param {Event} event The event - * @returns {undefined} - */ - onStart: function(pointer, ref, event) { - var ehMove, ehEnd, - eventNames = this.getEventNames(event); - - event.stopPropagation(); - event.preventDefault(); - - // We have to do this in case the HTML where the sliders are on - // have been animated into view. - this.calcViewDimensions(); - - if (pointer) { - this.tracking = ref; - } else { - pointer = this.getNearestHandle(event); - this.tracking = pointer === this.minH ? 'lowValue' : 'highValue'; - } - - pointer.addClass('rz-active'); + if (changedTouches && !touchForThisSlider) { + return + } - if (this.options.keyboardSupport) - this.focusElement(pointer); + var newPos = this.getEventPosition( + event, + touchForThisSlider ? touchForThisSlider.identifier : undefined + ), + newValue, + ceilValue = this.options.rightToLeft + ? this.minValue + : this.maxValue, + flrValue = this.options.rightToLeft ? this.maxValue : this.minValue + + if (newPos <= 0) { + newValue = flrValue + } else if (newPos >= this.maxPos) { + newValue = ceilValue + } else { + newValue = this.positionToValue(newPos) + if (fromTick && angular.isNumber(this.options.showTicks)) + newValue = this.roundStep(newValue, this.options.showTicks) + else newValue = this.roundStep(newValue) + } + this.positionTrackingHandle(newValue) + }, + + /** + * onEnd event handler + * + * @param {Event} event The event + * @param {Function} ehMove The bound move event handler + * @returns {undefined} + */ + onEnd: function(ehMove, event) { + this.moving = false + if (!this.options.disableAnimation) { + this.sliderElem.removeClass('noanimate') + } + var changedTouches = this.getEventAttr(event, 'changedTouches') + if (changedTouches && changedTouches[0].identifier !== this.touchId) { + return + } + this.isDragging = false + this.touchId = null - ehMove = angular.bind(this, this.dragging.active ? this.onDragMove : this.onMove, pointer); - ehEnd = angular.bind(this, this.onEnd, ehMove); + if (!this.options.keyboardSupport) { + this.minH.removeClass('rz-active') + this.maxH.removeClass('rz-active') + this.tracking = '' + } + this.dragging.active = false + + var eventName = this.getEventNames(event) + $document.off(eventName.moveEvent, ehMove) + $document.off(eventName.endEvent, this.endHandlerToBeRemovedOnEnd) + this.endHandlerToBeRemovedOnEnd = null + this.callOnEnd() + }, + + onTickClick: function(pointer, event) { + this.onMove(pointer, event, true) + }, + + onPointerFocus: function(pointer, ref) { + this.tracking = ref + pointer.one('blur', angular.bind(this, this.onPointerBlur, pointer)) + pointer.on('keydown', angular.bind(this, this.onKeyboardEvent)) + pointer.on('keyup', angular.bind(this, this.onKeyUp)) + this.firstKeyDown = true + pointer.addClass('rz-active') + + this.currentFocusElement = { + pointer: pointer, + ref: ref, + } + }, + + onKeyUp: function() { + this.firstKeyDown = true + this.callOnEnd() + }, + + onPointerBlur: function(pointer) { + pointer.off('keydown') + pointer.off('keyup') + pointer.removeClass('rz-active') + if (!this.isDragging) { + this.tracking = '' + this.currentFocusElement = null + } + }, + + /** + * Skip restricted range function when arrow keys use + * + * @param {number} currentValue value of the slider + * @param {number} key arrow key used + * + * @returns {number} currentValue value of the slider + */ - $document.on(eventNames.moveEvent, ehMove); - $document.one(eventNames.endEvent, ehEnd); - this.callOnStart(); - }, + skipRestrictedRanges: function(key, currentValue) { + if ( + this.options.restrictedRange && + Array.isArray(this.options.restrictedRange) + ) { + for (var i in this.options.restrictedRange) { + var range = this.options.restrictedRange[i] + // if it first or last value + if ( + (range.from === 0 && + currentValue === 0 && + [37, 40].includes(key)) || // LEFT or DOWN + (range.to >= + this.options.restrictedRange[ + this.options.restrictedRange.length - 1 + ].to && + currentValue >= + this.options.restrictedRange[ + this.options.restrictedRange.length - 1 + ].to && + [38, 39].includes(key)) // UP or RIGHT + ) { + return currentValue + } + if (range.to > currentValue && currentValue > range.from) { + if ( + Math.abs(range.to - currentValue) > + Math.abs(range.from - currentValue) + ) { + currentValue = range.to + } else { + currentValue = range.from + } + } + } + } - /** - * onMove event handler - * - * @param {jqLite} pointer - * @param {Event} event The event - * @param {boolean} fromTick if the event occured on a tick or not - * @returns {undefined} - */ - onMove: function(pointer, event, fromTick) { - var newOffset = this.getEventPosition(event), - newValue, - ceilValue = this.options.rightToLeft ? this.minValue : this.maxValue, - flrValue = this.options.rightToLeft ? this.maxValue : this.minValue; - - if (newOffset <= 0) { - newValue = flrValue; - } else if (newOffset >= this.maxPos) { - newValue = ceilValue; - } else { - newValue = this.offsetToValue(newOffset); - if (fromTick && angular.isNumber(this.options.showTicks)) - newValue = this.roundStep(newValue, this.options.showTicks); - else - newValue = this.roundStep(newValue); - } - this.positionTrackingHandle(newValue); - }, + return currentValue + }, - /** - * onEnd event handler - * - * @param {Event} event The event - * @param {Function} ehMove The the bound move event handler - * @returns {undefined} - */ - onEnd: function(ehMove, event) { - var moveEventName = this.getEventNames(event).moveEvent; - - if (!this.options.keyboardSupport) { - this.minH.removeClass('rz-active'); - this.maxH.removeClass('rz-active'); - this.tracking = ''; - } - this.dragging.active = false; - - $document.off(moveEventName, ehMove); - this.callOnEnd(); - }, - - onTickClick: function(pointer, event) { - this.onMove(pointer, event, true); - }, - - onPointerFocus: function(pointer, ref) { - this.tracking = ref; - pointer.one('blur', angular.bind(this, this.onPointerBlur, pointer)); - pointer.on('keydown', angular.bind(this, this.onKeyboardEvent)); - pointer.on('keyup', angular.bind(this, this.onKeyUp)); - this.firstKeyDown = true; - pointer.addClass('rz-active'); - - this.currentFocusElement = { - pointer: pointer, - ref: ref - }; - }, - - onKeyUp: function() { - this.firstKeyDown = true; - this.callOnEnd(); - }, - - onPointerBlur: function(pointer) { - pointer.off('keydown'); - pointer.off('keyup'); - this.tracking = ''; - pointer.removeClass('rz-active'); - this.currentFocusElement = null - }, + /** + * Key actions helper function + * + * @param {number} currentValue value of the slider + * + * @returns {?Object} action value mappings + */ + getKeyActions: function(currentValue) { + var increaseStep = currentValue + this.step, + decreaseStep = currentValue - this.step, + increasePage = currentValue + this.valueRange / 10, + decreasePage = currentValue - this.valueRange / 10 + + if (this.options.reversedControls) { + increaseStep = currentValue - this.step + decreaseStep = currentValue + this.step + increasePage = currentValue - this.valueRange / 10 + decreasePage = currentValue + this.valueRange / 10 + } - /** - * Key actions helper function - * - * @param {number} currentValue value of the slider - * - * @returns {?Object} action value mappings - */ - getKeyActions: function(currentValue) { - var increaseStep = currentValue + this.step, - decreaseStep = currentValue - this.step, - increasePage = currentValue + this.valueRange / 10, - decreasePage = currentValue - this.valueRange / 10; - - //Left to right default actions - var actions = { - 'UP': increaseStep, - 'DOWN': decreaseStep, - 'LEFT': decreaseStep, - 'RIGHT': increaseStep, - 'PAGEUP': increasePage, - 'PAGEDOWN': decreasePage, - 'HOME': this.minValue, - 'END': this.maxValue - }; - //right to left means swapping right and left arrows - if (this.options.rightToLeft) { - actions.LEFT = increaseStep; - actions.RIGHT = decreaseStep; - // right to left and vertical means we also swap up and down - if (this.options.vertical) { - actions.UP = decreaseStep; - actions.DOWN = increaseStep; + //Left to right default actions + var actions = { + UP: increaseStep, + DOWN: decreaseStep, + LEFT: decreaseStep, + RIGHT: increaseStep, + PAGEUP: increasePage, + PAGEDOWN: decreasePage, + HOME: this.options.reversedControls ? this.maxValue : this.minValue, + END: this.options.reversedControls ? this.minValue : this.maxValue, + } + //right to left means swapping right and left arrows + if (this.options.rightToLeft) { + actions.LEFT = increaseStep + actions.RIGHT = decreaseStep + // right to left and vertical means we also swap up and down + if (this.options.vertical) { + actions.UP = decreaseStep + actions.DOWN = increaseStep + } + } + return actions + }, + + onKeyboardEvent: function(event) { + var keyCode = event.keyCode || event.which + var currentValue = this[this.tracking] + var keys = { + 38: 'UP', + 40: 'DOWN', + 37: 'LEFT', + 39: 'RIGHT', + 33: 'PAGEUP', + 34: 'PAGEDOWN', + 36: 'HOME', + 35: 'END', + }, + actions = this.getKeyActions(currentValue), + key = keys[keyCode], + action = actions[key] + if (action == null || this.tracking === '') return + event.preventDefault() + + if (this.firstKeyDown) { + this.firstKeyDown = false + this.callOnStart() } - } - return actions; - }, - - onKeyboardEvent: function(event) { - var currentValue = this[this.tracking], - keyCode = event.keyCode || event.which, - keys = { - 38: 'UP', - 40: 'DOWN', - 37: 'LEFT', - 39: 'RIGHT', - 33: 'PAGEUP', - 34: 'PAGEDOWN', - 36: 'HOME', - 35: 'END' - }, - actions = this.getKeyActions(currentValue), - key = keys[keyCode], - action = actions[key]; - if (action == null || this.tracking === '') return; - event.preventDefault(); - - if (this.firstKeyDown) { - this.firstKeyDown = false; - this.callOnStart(); - } - var self = this; - $timeout(function() { - var newValue = self.roundStep(self.sanitizeValue(action)); - if (!self.options.draggableRangeOnly) { - self.positionTrackingHandle(newValue); - } - else { - var difference = self.highValue - self.lowValue, - newMinValue, newMaxValue; - if (self.tracking === 'lowValue') { - newMinValue = newValue; - newMaxValue = newValue + difference; - if (newMaxValue > self.maxValue) { - newMaxValue = self.maxValue; - newMinValue = newMaxValue - difference; - } + var self = this + $timeout(function() { + var newValue = self.roundStep(self.sanitizeValue(action)) + newValue = self.options.skipRestrictedRangesWithArrowKeys + ? self.skipRestrictedRanges(keyCode, newValue) + : newValue + if (!self.options.draggableRangeOnly) { + self.positionTrackingHandle(newValue) } else { - newMaxValue = newValue; - newMinValue = newValue - difference; - if (newMinValue < self.minValue) { - newMinValue = self.minValue; - newMaxValue = newMinValue + difference; + var difference = self.highValue - self.lowValue, + newMinValue, + newMaxValue + if (self.tracking === 'lowValue') { + newMinValue = newValue + newMaxValue = newValue + difference + if (newMaxValue > self.maxValue) { + newMaxValue = self.maxValue + newMinValue = newMaxValue - difference + } + } else { + newMaxValue = newValue + newMinValue = newValue - difference + if (newMinValue < self.minValue) { + newMinValue = self.minValue + newMaxValue = newMinValue + difference + } } + self.positionTrackingBar(newMinValue, newMaxValue) } - self.positionTrackingBar(newMinValue, newMaxValue); + }) + }, + + /** + * onDragStart event handler + * + * Handles dragging of the middle bar. + * + * @param {Object} pointer The jqLite wrapped DOM element + * @param {string} ref One of the refLow, refHigh values + * @param {Event} event The event + * @returns {undefined} + */ + onDragStart: function(pointer, ref, event) { + var position = this.getEventPosition(event) + this.dragging = { + active: true, + value: this.positionToValue(position), + difference: this.highValue - this.lowValue, + lowLimit: this.options.rightToLeft + ? this.minH.rzsp - position + : position - this.minH.rzsp, + highLimit: this.options.rightToLeft + ? position - this.maxH.rzsp + : this.maxH.rzsp - position, } - }); - }, - - /** - * onDragStart event handler - * - * Handles dragging of the middle bar. - * - * @param {Object} pointer The jqLite wrapped DOM element - * @param {string} ref One of the refLow, refHigh values - * @param {Event} event The event - * @returns {undefined} - */ - onDragStart: function(pointer, ref, event) { - var offset = this.getEventPosition(event); - this.dragging = { - active: true, - value: this.offsetToValue(offset), - difference: this.highValue - this.lowValue, - lowLimit: this.options.rightToLeft ? this.minH.rzsp - offset : offset - this.minH.rzsp, - highLimit: this.options.rightToLeft ? offset - this.maxH.rzsp : this.maxH.rzsp - offset - }; - - this.onStart(pointer, ref, event); - }, - /** - * getValue helper function - * - * gets max or min value depending on whether the newOffset is outOfBounds above or below the bar and rightToLeft - * - * @param {string} type 'max' || 'min' The value we are calculating - * @param {number} newOffset The new offset - * @param {boolean} outOfBounds Is the new offset above or below the max/min? - * @param {boolean} isAbove Is the new offset above the bar if out of bounds? - * - * @returns {number} - */ - getValue: function(type, newOffset, outOfBounds, isAbove) { - var isRTL = this.options.rightToLeft, - value = null; - - if (type === 'min') { - if (outOfBounds) { - if (isAbove) { - value = isRTL ? this.minValue : this.maxValue - this.dragging.difference; + this.onStart(pointer, ref, event) + }, + + /** + * getValue helper function + * + * gets max or min value depending on whether the newPos is outOfBounds above or below the bar and rightToLeft + * + * @param {string} type 'max' || 'min' The value we are calculating + * @param {number} newPos The new position + * @param {boolean} outOfBounds Is the new position above or below the max/min? + * @param {boolean} isAbove Is the new position above the bar if out of bounds? + * + * @returns {number} + */ + getValue: function(type, newPos, outOfBounds, isAbove) { + var isRTL = this.options.rightToLeft, + value = null + + if (type === 'min') { + if (outOfBounds) { + if (isAbove) { + value = isRTL + ? this.minValue + : this.maxValue - this.dragging.difference + } else { + value = isRTL + ? this.maxValue - this.dragging.difference + : this.minValue + } } else { - value = isRTL ? this.maxValue - this.dragging.difference : this.minValue; + value = isRTL + ? this.positionToValue(newPos + this.dragging.lowLimit) + : this.positionToValue(newPos - this.dragging.lowLimit) } } else { - value = isRTL ? this.offsetToValue(newOffset + this.dragging.lowLimit) : this.offsetToValue(newOffset - this.dragging.lowLimit) - } - } else { - if (outOfBounds) { - if (isAbove) { - value = isRTL ? this.minValue + this.dragging.difference : this.maxValue; + if (outOfBounds) { + if (isAbove) { + value = isRTL + ? this.minValue + this.dragging.difference + : this.maxValue + } else { + value = isRTL + ? this.maxValue + : this.minValue + this.dragging.difference + } } else { - value = isRTL ? this.maxValue : this.minValue + this.dragging.difference; + if (isRTL) { + value = + this.positionToValue(newPos + this.dragging.lowLimit) + + this.dragging.difference + } else { + value = + this.positionToValue(newPos - this.dragging.lowLimit) + + this.dragging.difference + } + } + } + return this.roundStep(value) + }, + + /** + * onDragMove event handler + * + * Handles dragging of the middle bar. + * + * @param {jqLite} pointer + * @param {Event} event The event + * @returns {undefined} + */ + onDragMove: function(pointer, event) { + if (!this.options.disableAnimation) { + if (this.moving) { + this.sliderElem.addClass('noanimate') } + } + this.moving = true + var newPos = this.getEventPosition(event), + newMinValue, + newMaxValue, + ceilLimit, + flrLimit, + isUnderFlrLimit, + isOverCeilLimit, + flrH, + ceilH + + if (this.options.rightToLeft) { + ceilLimit = this.dragging.lowLimit + flrLimit = this.dragging.highLimit + flrH = this.maxH + ceilH = this.minH + } else { + ceilLimit = this.dragging.highLimit + flrLimit = this.dragging.lowLimit + flrH = this.minH + ceilH = this.maxH + } + isUnderFlrLimit = newPos <= flrLimit + isOverCeilLimit = newPos >= this.maxPos - ceilLimit + + if (isUnderFlrLimit) { + if (flrH.rzsp === 0) return + newMinValue = this.getValue('min', newPos, true, false) + newMaxValue = this.getValue('max', newPos, true, false) + } else if (isOverCeilLimit) { + if (ceilH.rzsp === this.maxPos) return + newMaxValue = this.getValue('max', newPos, true, true) + newMinValue = this.getValue('min', newPos, true, true) } else { - if (isRTL) { - value = this.offsetToValue(newOffset + this.dragging.lowLimit) + this.dragging.difference + newMinValue = this.getValue('min', newPos, false) + newMaxValue = this.getValue('max', newPos, false) + } + this.positionTrackingBar(newMinValue, newMaxValue) + }, + + /** + * Set the new value and position for the entire bar + * + * @param {number} newMinValue the new minimum value + * @param {number} newMaxValue the new maximum value + */ + positionTrackingBar: function(newMinValue, newMaxValue) { + if ( + this.options.minLimit != null && + newMinValue < this.options.minLimit + ) { + newMinValue = this.options.minLimit + newMaxValue = newMinValue + this.dragging.difference + } + if ( + this.options.maxLimit != null && + newMaxValue > this.options.maxLimit + ) { + newMaxValue = this.options.maxLimit + newMinValue = newMaxValue - this.dragging.difference + } + + this.lowValue = newMinValue + this.highValue = newMaxValue + this.applyLowValue() + if (this.range) this.applyHighValue() + this.applyModel(true) + this.updateHandles('lowValue', this.valueToPosition(newMinValue)) + this.updateHandles('highValue', this.valueToPosition(newMaxValue)) + }, + + /** + * Set the new value and position to the current tracking handle + * + * @param {number} newValue new model value + */ + positionTrackingHandle: function(newValue) { + var valueChanged = false + newValue = this.applyMinMaxLimit(newValue) + newValue = this.applyRestrictedRange(newValue) + if (this.range) { + if (this.options.pushRange) { + newValue = this.applyPushRange(newValue) + valueChanged = true } else { - value = this.offsetToValue(newOffset - this.dragging.lowLimit) + this.dragging.difference; + if (this.options.noSwitching) { + if (this.tracking === 'lowValue' && newValue > this.highValue) + newValue = this.applyMinMaxRange(this.highValue) + else if ( + this.tracking === 'highValue' && + newValue < this.lowValue + ) + newValue = this.applyMinMaxRange(this.lowValue) + } + newValue = this.applyMinMaxRange(newValue) + /* This is to check if we need to switch the min and max handles */ + if (this.tracking === 'lowValue' && newValue > this.highValue) { + this.lowValue = this.highValue + this.applyLowValue() + this.applyModel() + this.updateHandles(this.tracking, this.maxH.rzsp) + this.updateAriaAttributes() + this.tracking = 'highValue' + this.minH.removeClass('rz-active') + this.maxH.addClass('rz-active') + if (this.options.keyboardSupport) this.focusElement(this.maxH) + valueChanged = true + } else if ( + this.tracking === 'highValue' && + newValue < this.lowValue + ) { + this.highValue = this.lowValue + this.applyHighValue() + this.applyModel() + this.updateHandles(this.tracking, this.minH.rzsp) + this.updateAriaAttributes() + this.tracking = 'lowValue' + this.maxH.removeClass('rz-active') + this.minH.addClass('rz-active') + if (this.options.keyboardSupport) this.focusElement(this.minH) + valueChanged = true + } } } - } - return this.roundStep(value); - }, - - /** - * onDragMove event handler - * - * Handles dragging of the middle bar. - * - * @param {jqLite} pointer - * @param {Event} event The event - * @returns {undefined} - */ - onDragMove: function(pointer, event) { - var newOffset = this.getEventPosition(event), - newMinValue, newMaxValue, - ceilLimit, flrLimit, - isUnderFlrLimit, isOverCeilLimit, - flrH, ceilH; - - if (this.options.rightToLeft) { - ceilLimit = this.dragging.lowLimit; - flrLimit = this.dragging.highLimit; - flrH = this.maxH; - ceilH = this.minH; - } else { - ceilLimit = this.dragging.highLimit; - flrLimit = this.dragging.lowLimit; - flrH = this.minH; - ceilH = this.maxH; - } - isUnderFlrLimit = newOffset <= flrLimit; - isOverCeilLimit = newOffset >= this.maxPos - ceilLimit; - - if (isUnderFlrLimit) { - if (flrH.rzsp === 0) - return; - newMinValue = this.getValue('min', newOffset, true, false); - newMaxValue = this.getValue('max', newOffset, true, false); - } else if (isOverCeilLimit) { - if (ceilH.rzsp === this.maxPos) - return; - newMaxValue = this.getValue('max', newOffset, true, true); - newMinValue = this.getValue('min', newOffset, true, true); - } else { - newMinValue = this.getValue('min', newOffset, false); - newMaxValue = this.getValue('max', newOffset, false); - } - this.positionTrackingBar(newMinValue, newMaxValue); - }, - /** - * Set the new value and offset for the entire bar - * - * @param {number} newMinValue the new minimum value - * @param {number} newMaxValue the new maximum value - */ - positionTrackingBar: function(newMinValue, newMaxValue) { - - if (this.options.minLimit != null && newMinValue < this.options.minLimit) { - newMinValue = this.options.minLimit; - newMaxValue = newMinValue + this.dragging.difference; - } - if (this.options.maxLimit != null && newMaxValue > this.options.maxLimit) { - newMaxValue = this.options.maxLimit; - newMinValue = newMaxValue - this.dragging.difference; - } - - this.lowValue = newMinValue; - this.highValue = newMaxValue; - this.applyLowValue(); - if (this.range) - this.applyHighValue(); - this.applyModel(); - this.updateHandles('lowValue', this.valueToOffset(newMinValue)); - this.updateHandles('highValue', this.valueToOffset(newMaxValue)); - }, + if (this[this.tracking] !== newValue) { + this[this.tracking] = newValue + if (this.tracking === 'lowValue') this.applyLowValue() + else this.applyHighValue() + this.applyModel() + this.updateHandles(this.tracking, this.valueToPosition(newValue)) + this.updateAriaAttributes() + valueChanged = true + } - /** - * Set the new value and offset to the current tracking handle - * - * @param {number} newValue new model value - */ - positionTrackingHandle: function(newValue) { - var valueChanged = false; - - newValue = this.applyMinMaxLimit(newValue); - if (this.range) { - if (this.options.pushRange) { - newValue = this.applyPushRange(newValue); - valueChanged = true; - } - else { - if (this.options.noSwitching) { - if (this.tracking === 'lowValue' && newValue > this.highValue) - newValue = this.applyMinMaxRange(this.highValue); - else if (this.tracking === 'highValue' && newValue < this.lowValue) - newValue = this.applyMinMaxRange(this.lowValue); + if (valueChanged) this.applyModel(true) + }, + + applyMinMaxLimit: function(newValue) { + if (this.options.minLimit != null && newValue < this.options.minLimit) + return this.options.minLimit + if (this.options.maxLimit != null && newValue > this.options.maxLimit) + return this.options.maxLimit + return newValue + }, + + applyMinMaxRange: function(newValue) { + var oppositeValue = + this.tracking === 'lowValue' ? this.highValue : this.lowValue, + difference = Math.abs(newValue - oppositeValue) + if (this.options.minRange != null) { + if (difference < this.options.minRange) { + if (this.tracking === 'lowValue') + return this.highValue - this.options.minRange + else return this.lowValue + this.options.minRange } - newValue = this.applyMinMaxRange(newValue); - /* This is to check if we need to switch the min and max handles */ - if (this.tracking === 'lowValue' && newValue > this.highValue) { - this.lowValue = this.highValue; - this.applyLowValue(); - this.updateHandles(this.tracking, this.maxH.rzsp); - this.updateAriaAttributes(); - this.tracking = 'highValue'; - this.minH.removeClass('rz-active'); - this.maxH.addClass('rz-active'); - if (this.options.keyboardSupport) - this.focusElement(this.maxH); - valueChanged = true; + } + if (this.options.maxRange != null) { + if (difference > this.options.maxRange) { + if (this.tracking === 'lowValue') + return this.highValue - this.options.maxRange + else return this.lowValue + this.options.maxRange } - else if (this.tracking === 'highValue' && newValue < this.lowValue) { - this.highValue = this.lowValue; - this.applyHighValue(); - this.updateHandles(this.tracking, this.minH.rzsp); - this.updateAriaAttributes(); - this.tracking = 'lowValue'; - this.maxH.removeClass('rz-active'); - this.minH.addClass('rz-active'); - if (this.options.keyboardSupport) - this.focusElement(this.minH); - valueChanged = true; + } + return newValue + }, + + applyRestrictedRange: function(newValue) { + for (var i in this.options.restrictedRange) { + if ( + this.options.restrictedRange[i] != null && + newValue > this.options.restrictedRange[i].from && + newValue < this.options.restrictedRange[i].to + ) { + var halfWidth = + (this.options.restrictedRange[i].to - + this.options.restrictedRange[i].from) / + 2 + if (this.tracking === 'lowValue') { + return newValue > + this.options.restrictedRange[i].from + halfWidth + ? this.options.restrictedRange[i].to + : this.options.restrictedRange[i].from + } + if (this.tracking === 'highValue') { + return newValue < this.options.restrictedRange[i].to - halfWidth + ? this.options.restrictedRange[i].from + : this.options.restrictedRange[i].to + } } } - } - - if (this[this.tracking] !== newValue) { - this[this.tracking] = newValue; - if (this.tracking === 'lowValue') - this.applyLowValue(); - else - this.applyHighValue(); - this.updateHandles(this.tracking, this.valueToOffset(newValue)); - this.updateAriaAttributes(); - valueChanged = true; - } - if (valueChanged) - this.applyModel(); - }, - - applyMinMaxLimit: function(newValue) { - if (this.options.minLimit != null && newValue < this.options.minLimit) - return this.options.minLimit; - if (this.options.maxLimit != null && newValue > this.options.maxLimit) - return this.options.maxLimit; - return newValue; - }, - - applyMinMaxRange: function(newValue) { - var oppositeValue = this.tracking === 'lowValue' ? this.highValue : this.lowValue, - difference = Math.abs(newValue - oppositeValue); - if (this.options.minRange != null) { - if (difference < this.options.minRange) { - if (this.tracking === 'lowValue') - return this.highValue - this.options.minRange; - else - return this.lowValue + this.options.minRange; - } - } - if (this.options.maxRange != null) { - if (difference > this.options.maxRange) { - if (this.tracking === 'lowValue') - return this.highValue - this.options.maxRange; - else - return this.lowValue + this.options.maxRange; + return newValue + }, + + applyPushRange: function(newValue) { + var difference = + this.tracking === 'lowValue' + ? this.highValue - newValue + : newValue - this.lowValue, + minRange = + this.options.minRange !== null + ? this.options.minRange + : this.options.step, + maxRange = this.options.maxRange + // if smaller than minRange + if (difference < minRange) { + if (this.tracking === 'lowValue') { + this.highValue = Math.min(newValue + minRange, this.maxValue) + newValue = this.highValue - minRange + this.applyHighValue() + this.updateHandles( + 'highValue', + this.valueToPosition(this.highValue) + ) + } else { + this.lowValue = Math.max(newValue - minRange, this.minValue) + newValue = this.lowValue + minRange + this.applyLowValue() + this.updateHandles( + 'lowValue', + this.valueToPosition(this.lowValue) + ) + } + this.updateAriaAttributes() + } else if (maxRange !== null && difference > maxRange) { + // if greater than maxRange + if (this.tracking === 'lowValue') { + this.highValue = newValue + maxRange + this.applyHighValue() + this.updateHandles( + 'highValue', + this.valueToPosition(this.highValue) + ) + } else { + this.lowValue = newValue - maxRange + this.applyLowValue() + this.updateHandles( + 'lowValue', + this.valueToPosition(this.lowValue) + ) + } + this.updateAriaAttributes() } - } - return newValue; - }, - - applyPushRange: function(newValue) { - var difference = this.tracking === 'lowValue' ? this.highValue - newValue : newValue - this.lowValue, - range = this.options.minRange !== null ? this.options.minRange : this.options.step; - if (difference < range) { - if (this.tracking === 'lowValue') { - this.highValue = Math.min(newValue + range, this.maxValue); - newValue = this.highValue - range; - this.applyHighValue(); - this.updateHandles('highValue', this.valueToOffset(this.highValue)); - } - else { - this.lowValue = Math.max(newValue - range, this.minValue); - newValue = this.lowValue + range; - this.applyLowValue(); - this.updateHandles('lowValue', this.valueToOffset(this.lowValue)); - } - this.updateAriaAttributes(); - } - return newValue; - }, - - /** - * Apply the model values using scope.$apply. - * We wrap it with the internalChange flag to avoid the watchers to be called - */ - applyModel: function() { - this.internalChange = true; - this.scope.$apply(); - this.callOnChange(); - this.internalChange = false; - }, + return newValue + }, - /** - * Call the onStart callback if defined - * The callback call is wrapped in a $evalAsync to ensure that its result will be applied to the scope. - * - * @returns {undefined} - */ - callOnStart: function() { - if (this.options.onStart) { - var self = this, - pointerType = this.tracking === 'lowValue' ? 'min' : 'max'; - this.scope.$evalAsync(function() { - self.options.onStart(self.options.id, self.scope.rzSliderModel, self.scope.rzSliderHigh, pointerType); - }); - } - }, + /** + * Apply the model values using scope.$apply. + * We wrap it with the internalChange flag to avoid the watchers to be called + */ + applyModel: function(callOnChange) { + this.internalChange = true + this.scope.$apply() + callOnChange && this.callOnChange() + this.internalChange = false + }, + + /** + * Call the onStart callback if defined + * The callback call is wrapped in a $evalAsync to ensure that its result will be applied to the scope. + * + * @returns {undefined} + */ + callOnStart: function() { + if (this.options.onStart) { + var self = this, + pointerType = this.tracking === 'lowValue' ? 'min' : 'max' + this.scope.$evalAsync(function() { + self.options.onStart( + self.options.id, + self.scope.rzSliderModel, + self.scope.rzSliderHigh, + pointerType + ) + }) + } + }, - /** - * Call the onChange callback if defined - * The callback call is wrapped in a $evalAsync to ensure that its result will be applied to the scope. - * - * @returns {undefined} - */ - callOnChange: function() { - if (this.options.onChange) { - var self = this, - pointerType = this.tracking === 'lowValue' ? 'min' : 'max'; - this.scope.$evalAsync(function() { - self.options.onChange(self.options.id, self.scope.rzSliderModel, self.scope.rzSliderHigh, pointerType); - }); - } - }, + /** + * Call the onChange callback if defined + * The callback call is wrapped in a $evalAsync to ensure that its result will be applied to the scope. + * + * @returns {undefined} + */ + callOnChange: function() { + if (this.options.onChange) { + var self = this, + pointerType = this.tracking === 'lowValue' ? 'min' : 'max' + this.scope.$evalAsync(function() { + self.options.onChange( + self.options.id, + self.scope.rzSliderModel, + self.scope.rzSliderHigh, + pointerType + ) + }) + } + }, - /** - * Call the onEnd callback if defined - * The callback call is wrapped in a $evalAsync to ensure that its result will be applied to the scope. - * - * @returns {undefined} - */ - callOnEnd: function() { - if (this.options.onEnd) { - var self = this, - pointerType = this.tracking === 'lowValue' ? 'min' : 'max'; - this.scope.$evalAsync(function() { - self.options.onEnd(self.options.id, self.scope.rzSliderModel, self.scope.rzSliderHigh, pointerType); - }); - } - this.scope.$emit('slideEnded'); + /** + * Call the onEnd callback if defined + * The callback call is wrapped in a $evalAsync to ensure that its result will be applied to the scope. + * + * @returns {undefined} + */ + callOnEnd: function() { + if (this.options.onEnd) { + var self = this, + pointerType = this.tracking === 'lowValue' ? 'min' : 'max' + this.scope.$evalAsync(function() { + self.options.onEnd( + self.options.id, + self.scope.rzSliderModel, + self.scope.rzSliderHigh, + pointerType + ) + }) + } + this.scope.$emit('slideEnded') + }, } - }; - - return Slider; - }]) - - .directive('rzslider', ['RzSlider', function(RzSlider) { - 'use strict'; - - return { - restrict: 'AE', - replace: true, - scope: { - rzSliderModel: '=?', - rzSliderHigh: '=?', - rzSliderOptions: '&?', - rzSliderTplUrl: '@' - }, - /** - * Return template URL - * - * @param {jqLite} elem - * @param {Object} attrs - * @return {string} - */ - templateUrl: function(elem, attrs) { - //noinspection JSUnresolvedVariable - return attrs.rzSliderTplUrl || 'rzSliderTpl.html'; - }, - - link: function(scope, elem) { - scope.slider = new RzSlider(scope, elem); //attach on scope so we can test it + return Slider + }]) + .directive('rzslider', ['RzSlider', function(RzSlider) { + 'use strict' + + return { + restrict: 'AE', + replace: true, + scope: { + rzSliderModel: '=?', + rzSliderHigh: '=?', + rzSliderOptions: '&?', + rzSliderTplUrl: '@', + }, + + /** + * Return template URL + * + * @param {jqLite} elem + * @param {Object} attrs + * @return {string} + */ + templateUrl: function(elem, attrs) { + //noinspection JSUnresolvedVariable + return attrs.rzSliderTplUrl || 'rzSliderTpl.html' + }, + + link: function(scope, elem) { + scope.slider = new RzSlider(scope, elem) //attach on scope so we can test it + }, } - }; - }]); + }]) // IDE assist @@ -2184,7 +2854,7 @@ /** * @name jqLite * - * @property {number|undefined} rzsp rzslider label position offset + * @property {number|undefined} rzsp rzslider label position position * @property {number|undefined} rzsd rzslider element dimension * @property {string|undefined} rzsv rzslider label value/text * @property {Function} css @@ -2208,10 +2878,11 @@ 'use strict'; $templateCache.put('rzSliderTpl.html', - "
  • {{ t.value }} {{ t.legend }}
" + "
  • {{ t.value }} {{ t.legend }}
" ); }]); return module.name -})); +}) +; \ No newline at end of file diff --git a/dist/rzslider.min.css b/dist/rzslider.min.css index 6b035d4..ab1f8c9 100644 --- a/dist/rzslider.min.css +++ b/dist/rzslider.min.css @@ -1,2 +1,2 @@ -/*! angularjs-slider - v5.5.1 - (c) Rafal Zajac , Valentin Hervieu , Jussi Saarivirta , Angelin Sirbu - https://github.com/angular-slider/angularjs-slider - 2016-09-22 */ -.rzslider{position:relative;display:inline-block;width:100%;height:4px;margin:35px 0 15px 0;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.rzslider.with-legend{margin-bottom:40px}.rzslider[disabled]{cursor:not-allowed}.rzslider[disabled] .rz-pointer{cursor:not-allowed;background-color:#d8e0f3}.rzslider span{position:absolute;display:inline-block;white-space:nowrap}.rzslider .rz-base{width:100%;height:100%;padding:0}.rzslider .rz-bar-wrapper{left:0;z-index:1;width:100%;height:32px;padding-top:16px;margin-top:-16px;box-sizing:border-box}.rzslider .rz-bar-wrapper.rz-draggable{cursor:move}.rzslider .rz-bar{left:0;z-index:1;width:100%;height:4px;background:#d8e0f3;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.rzslider .rz-bar.rz-selection{z-index:2;background:#0db9f0;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.rzslider .rz-pointer{top:-14px;z-index:3;width:32px;height:32px;cursor:pointer;background-color:#0db9f0;-webkit-border-radius:16px;-moz-border-radius:16px;border-radius:16px}.rzslider .rz-pointer:after{position:absolute;top:12px;left:12px;width:8px;height:8px;background:#fff;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;content:''}.rzslider .rz-pointer:hover:after{background-color:#fff}.rzslider .rz-pointer.rz-active{z-index:4}.rzslider .rz-pointer.rz-active:after{background-color:#451aff}.rzslider .rz-bubble{bottom:16px;padding:1px 3px;color:#55637d;cursor:default}.rzslider .rz-bubble.rz-selection{top:16px}.rzslider .rz-bubble.rz-limit{color:#55637d}.rzslider .rz-ticks{position:absolute;top:-3px;left:0;z-index:1;display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;height:0;padding:0 11px;margin:0;list-style:none;box-sizing:border-box;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.rzslider .rz-ticks .rz-tick{width:10px;height:10px;text-align:center;cursor:pointer;background:#d8e0f3;border-radius:50%}.rzslider .rz-ticks .rz-tick.rz-selected{background:#0db9f0}.rzslider .rz-ticks .rz-tick .rz-tick-value{position:absolute;top:-30px;transform:translate(-50%,0)}.rzslider .rz-ticks .rz-tick .rz-tick-legend{position:absolute;top:24px;max-width:50px;white-space:normal;transform:translate(-50%,0)}.rzslider .rz-ticks.rz-ticks-values-under .rz-tick-value{top:initial;bottom:-40px}.rzslider.rz-vertical{position:relative;width:4px;height:100%;padding:0;margin:0 20px;vertical-align:baseline}.rzslider.rz-vertical .rz-base{width:100%;height:100%;padding:0}.rzslider.rz-vertical .rz-bar-wrapper{top:auto;left:0;width:32px;height:100%;padding:0 0 0 16px;margin:0 0 0 -16px}.rzslider.rz-vertical .rz-bar{bottom:0;left:auto;width:4px;height:100%}.rzslider.rz-vertical .rz-pointer{top:auto;bottom:0;left:-14px!important}.rzslider.rz-vertical .rz-bubble{bottom:0;left:16px!important;margin-left:3px}.rzslider.rz-vertical .rz-bubble.rz-selection{top:auto;left:16px!important}.rzslider.rz-vertical .rz-ticks{top:0;left:-3px;z-index:1;width:0;height:100%;padding:11px 0;-webkit-flex-direction:column-reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.rzslider.rz-vertical .rz-ticks .rz-tick{vertical-align:middle}.rzslider.rz-vertical .rz-ticks .rz-tick .rz-tick-value{top:initial;left:22px;transform:translate(0,-28%)}.rzslider.rz-vertical .rz-ticks .rz-tick .rz-tick-legend{top:initial;right:24px;max-width:none;white-space:nowrap;transform:translate(0,-28%)}.rzslider.rz-vertical .rz-ticks.rz-ticks-values-under .rz-tick-value{right:12px;bottom:initial;left:initial} \ No newline at end of file +/*! angularjs-slider - v7.1.0 - (c) Rafal Zajac , Valentin Hervieu , Jussi Saarivirta , Angelin Sirbu - https://github.com/angular-slider/angularjs-slider - 2022-05-26 */ +.rzslider{position:relative;display:inline-block;width:100%;height:4px;margin:35px 0 15px 0;vertical-align:middle;user-select:none}.rzslider.noanimate *{transition:none!important}.rzslider.with-legend{margin-bottom:40px}.rzslider[disabled]{cursor:not-allowed}.rzslider[disabled] .rz-pointer{cursor:not-allowed;background-color:#d8e0f3}.rzslider[disabled] .rz-draggable{cursor:not-allowed}.rzslider[disabled] .rz-selection{background:#8b91a2}.rzslider[disabled] .rz-tick{cursor:not-allowed}.rzslider[disabled] .rz-tick.rz-selected{background:#8b91a2}.rzslider span{position:absolute;display:inline-block;white-space:nowrap}.rzslider .rz-base{width:100%;height:100%;padding:0}.rzslider .rz-bar-wrapper{left:0;z-index:1;width:100%;height:32px;padding-top:16px;margin-top:-16px;box-sizing:border-box;transition:all linear .3s}.rzslider .rz-draggable{cursor:move}.rzslider .rz-bar{left:0;z-index:1;width:100%;height:4px;background:#d8e0f3;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.rzslider .rz-bar-wrapper.rz-transparent .rz-bar{background:transparent}.rzslider .rz-bar-wrapper.rz-left-out-selection .rz-bar{background:#df002d}.rzslider .rz-bar-wrapper.rz-right-out-selection .rz-bar{background:#03a688}.rzslider .rz-selection{z-index:2;background:#0db9f0;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;transition:background-color linear .3s}.rzslider .rz-restricted{z-index:3;background:#f00;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.rzslider .rz-pointer{top:-14px;z-index:3;width:32px;height:32px;cursor:pointer;background-color:#0db9f0;-webkit-border-radius:16px;-moz-border-radius:16px;border-radius:16px;transition:all linear .3s}.rzslider .rz-pointer:after{position:absolute;top:12px;left:12px;width:8px;height:8px;background:#fff;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;content:''}.rzslider .rz-pointer:hover:after{background-color:#fff}.rzslider .rz-pointer.rz-active{z-index:4}.rzslider .rz-pointer.rz-active:after{background-color:#451aff}.rzslider .rz-bubble{bottom:16px;padding:1px 3px;color:#55637d;cursor:default;transition:all linear .3s}.rzslider .rz-bubble.rz-limit{color:#55637d;transition:none}.rzslider .rz-ticks{position:absolute;top:-3px;left:0;z-index:1;width:100%;height:0;margin:0;list-style:none;box-sizing:border-box}.rzslider .rz-ticks-values-under .rz-tick-value{top:auto;bottom:-32px}.rzslider .rz-tick{position:absolute;top:0;left:0;width:10px;height:10px;margin-left:11px;text-align:center;cursor:pointer;background:#d8e0f3;border-radius:50%;transition:background-color linear .3s}.rzslider .rz-tick.rz-selected{background:#0db9f0}.rzslider .rz-tick-value{position:absolute;top:-30px;transform:translate(-50%,0)}.rzslider .rz-tick-legend{position:absolute;top:24px;max-width:50px;white-space:normal;transform:translate(-50%,0)}.rzslider.rz-vertical{position:relative;width:4px;height:100%;padding:0;margin:0 20px;vertical-align:baseline}.rzslider.rz-vertical .rz-base{width:100%;height:100%;padding:0}.rzslider.rz-vertical .rz-bar-wrapper{top:auto;left:0;width:32px;height:100%;padding:0 0 0 16px;margin:0 0 0 -16px}.rzslider.rz-vertical .rz-bar{bottom:0;left:auto;width:4px;height:100%}.rzslider.rz-vertical .rz-pointer{top:auto;bottom:0;left:-14px!important}.rzslider.rz-vertical .rz-bubble{bottom:0;left:16px!important;margin-left:3px}.rzslider.rz-vertical .rz-ticks{top:0;left:-3px;z-index:1;width:0;height:100%}.rzslider.rz-vertical .rz-tick{margin-top:11px;margin-left:auto;vertical-align:middle}.rzslider.rz-vertical .rz-tick-value{top:auto;left:24px;transform:translate(0,-28%)}.rzslider.rz-vertical .rz-tick-legend{top:auto;right:24px;max-width:none;white-space:nowrap;transform:translate(0,-28%)}.rzslider.rz-vertical .rz-ticks-values-under .rz-tick-value{right:24px;bottom:auto;left:auto} \ No newline at end of file diff --git a/dist/rzslider.min.js b/dist/rzslider.min.js index 65fd2fd..e0e5927 100644 --- a/dist/rzslider.min.js +++ b/dist/rzslider.min.js @@ -1,2 +1,3 @@ -/*! angularjs-slider - v5.5.1 - (c) Rafal Zajac , Valentin Hervieu , Jussi Saarivirta , Angelin Sirbu - https://github.com/angular-slider/angularjs-slider - 2016-09-22 */ -!function(a,b){"use strict";"function"==typeof define&&define.amd?define(["angular"],b):"object"==typeof module&&module.exports?module.exports=b(require("angular")):b(a.angular)}(this,function(a){"use strict";var b=a.module("rzModule",[]).factory("RzSliderOptions",function(){var b={floor:0,ceil:null,step:1,precision:0,minRange:null,maxRange:null,pushRange:!1,minLimit:null,maxLimit:null,id:null,translate:null,getLegend:null,stepsArray:null,bindIndexForStepsArray:!1,draggableRange:!1,draggableRangeOnly:!1,showSelectionBar:!1,showSelectionBarEnd:!1,showSelectionBarFromValue:null,hidePointerLabels:!1,hideLimitLabels:!1,autoHideLimitLabels:!0,readOnly:!1,disabled:!1,interval:350,showTicks:!1,showTicksValues:!1,ticksTooltip:null,ticksValuesTooltip:null,vertical:!1,getSelectionBarColor:null,getTickColor:null,getPointerColor:null,keyboardSupport:!0,scale:1,enforceStep:!0,enforceRange:!1,noSwitching:!1,onlyBindHandles:!1,onStart:null,onChange:null,onEnd:null,rightToLeft:!1,boundPointerLabels:!0,mergeRangeLabelsIfSame:!1,customTemplateScope:null},c={},d={};return d.options=function(b){a.extend(c,b)},d.getOptions=function(d){return a.extend({},b,c,d)},d}).factory("rzThrottle",["$timeout",function(a){return function(b,c,d){var e,f,g,h=Date.now||function(){return(new Date).getTime()},i=null,j=0;d=d||{};var k=function(){j=h(),i=null,g=b.apply(e,f),e=f=null};return function(){var l=h(),m=c-(l-j);return e=this,f=arguments,0>=m?(a.cancel(i),i=null,j=l,g=b.apply(e,f),e=f=null):i||d.trailing===!1||(i=a(k,m)),g}}}]).factory("RzSlider",["$timeout","$document","$window","$compile","RzSliderOptions","rzThrottle",function(b,c,d,e,f,g){var h=function(a,b){this.scope=a,this.lowValue=0,this.highValue=0,this.sliderElem=b,this.range=void 0!==this.scope.rzSliderModel&&void 0!==this.scope.rzSliderHigh,this.dragging={active:!1,value:0,difference:0,offset:0,lowLimit:0,highLimit:0},this.positionProperty="left",this.dimensionProperty="width",this.handleHalfDim=0,this.maxPos=0,this.precision=0,this.step=1,this.tracking="",this.minValue=0,this.maxValue=0,this.valueRange=0,this.intermediateTicks=!1,this.initHasRun=!1,this.firstKeyDown=!1,this.internalChange=!1,this.cmbLabelShown=!1,this.currentFocusElement=null,this.fullBar=null,this.selBar=null,this.minH=null,this.maxH=null,this.flrLab=null,this.ceilLab=null,this.minLab=null,this.maxLab=null,this.cmbLab=null,this.ticks=null,this.init()};return h.prototype={init:function(){var b,c,e=this,f=function(){e.calcViewDimensions()};this.applyOptions(),this.syncLowValue(),this.range&&this.syncHighValue(),this.initElemHandles(),this.manageElementsStyle(),this.setDisabledState(),this.calcViewDimensions(),this.setMinAndMax(),this.addAccessibility(),this.updateCeilLab(),this.updateFloorLab(),this.initHandles(),this.manageEventsBindings(),this.scope.$on("reCalcViewDimensions",f),a.element(d).on("resize",f),this.initHasRun=!0,b=g(function(){e.onLowHandleChange()},e.options.interval),c=g(function(){e.onHighHandleChange()},e.options.interval),this.scope.$on("rzSliderForceRender",function(){e.resetLabelsValue(),b(),e.range&&c(),e.resetSlider()}),this.scope.$watch("rzSliderOptions()",function(a,b){a!==b&&(e.applyOptions(),e.syncLowValue(),e.range&&e.syncHighValue(),e.resetSlider())},!0),this.scope.$watch("rzSliderModel",function(a,c){e.internalChange||a!==c&&b()}),this.scope.$watch("rzSliderHigh",function(a,b){e.internalChange||a!==b&&(null!=a&&c(),(e.range&&null==a||!e.range&&null!=a)&&(e.applyOptions(),e.resetSlider()))}),this.scope.$on("$destroy",function(){e.unbindEvents(),a.element(d).off("resize",f),e.currentFocusElement=null})},findStepIndex:function(b){for(var c=0,d=0;d0&&0===b.rzsd)&&(f=!0,b.rzsv=e),g||b.html(e),this.scope[c+"Label"]=e,f&&this.getDimension(b)},setMinAndMax:function(){this.step=+this.options.step,this.precision=+this.options.precision,this.minValue=this.options.floor,this.options.enforceStep&&(this.lowValue=this.roundStep(this.lowValue),this.range&&(this.highValue=this.roundStep(this.highValue))),null!=this.options.ceil?this.maxValue=this.options.ceil:this.maxValue=this.options.ceil=this.range?this.highValue:this.lowValue,this.options.enforceRange&&(this.lowValue=this.sanitizeValue(this.lowValue),this.range&&(this.highValue=this.sanitizeValue(this.highValue))),this.applyLowValue(),this.range&&this.applyHighValue(),this.valueRange=this.maxValue-this.minValue},addAccessibility:function(){this.minH.attr("role","slider"),this.updateAriaAttributes(),!this.options.keyboardSupport||this.options.readOnly||this.options.disabled?this.minH.attr("tabindex",""):this.minH.attr("tabindex","0"),this.options.vertical&&this.minH.attr("aria-orientation","vertical"),this.range&&(this.maxH.attr("role","slider"),!this.options.keyboardSupport||this.options.readOnly||this.options.disabled?this.maxH.attr("tabindex",""):this.maxH.attr("tabindex","0"),this.options.vertical&&this.maxH.attr("aria-orientation","vertical"))},updateAriaAttributes:function(){this.minH.attr({"aria-valuenow":this.scope.rzSliderModel,"aria-valuetext":this.customTrFn(this.scope.rzSliderModel,this.options.id,"model"),"aria-valuemin":this.minValue,"aria-valuemax":this.maxValue}),this.range&&this.maxH.attr({"aria-valuenow":this.scope.rzSliderHigh,"aria-valuetext":this.customTrFn(this.scope.rzSliderHigh,this.options.id,"high"),"aria-valuemin":this.minValue,"aria-valuemax":this.maxValue})},calcViewDimensions:function(){var a=this.getDimension(this.minH);this.handleHalfDim=a/2,this.barDimension=this.getDimension(this.fullBar),this.maxPos=this.barDimension-a,this.getDimension(this.sliderElem),this.sliderElem.rzsp=this.sliderElem[0].getBoundingClientRect()[this.positionProperty],this.initHasRun&&(this.updateFloorLab(),this.updateCeilLab(),this.initHandles())},updateTicksScale:function(){if(this.options.showTicks){var a=this.step;this.intermediateTicks&&(a=this.options.showTicks);var b=Math.round((this.maxValue-this.minValue)/a)+1;this.scope.ticks=[];for(var c=0;b>c;c++){var d=this.roundStep(this.minValue+c*a),e={selected:this.isTickSelected(d)};if(e.selected&&this.options.getSelectionBarColor&&(e.style={"background-color":this.getSelectionBarColor()}),!e.selected&&this.options.getTickColor&&(e.style={"background-color":this.getTickColor(d)}),this.options.ticksTooltip&&(e.tooltip=this.options.ticksTooltip(d),e.tooltipPlacement=this.options.vertical?"right":"top"),this.options.showTicksValues&&(e.value=this.getDisplayValue(d,"tick-value"),this.options.ticksValuesTooltip&&(e.valueTooltip=this.options.ticksValuesTooltip(d),e.valueTooltipPlacement=this.options.vertical?"right":"top")),this.getLegend){var f=this.getLegend(d,this.options.id);f&&(e.legend=f)}this.options.rightToLeft?this.scope.ticks.unshift(e):this.scope.ticks.push(e)}}},isTickSelected:function(a){if(!this.range)if(null!==this.options.showSelectionBarFromValue){var b=this.options.showSelectionBarFromValue;if(this.lowValue>b&&a>=b&&a<=this.lowValue)return!0;if(this.lowValue=a&&a>=this.lowValue)return!0}else if(this.options.showSelectionBarEnd){if(a>=this.lowValue)return!0}else if(this.options.showSelectionBar&&a<=this.lowValue)return!0;return this.range&&a>=this.lowValue&&a<=this.highValue?!0:!1},updateFloorLab:function(){this.translateFn(this.minValue,this.flrLab,"floor"),this.getDimension(this.flrLab);var a=this.options.rightToLeft?this.barDimension-this.flrLab.rzsd:0;this.setPosition(this.flrLab,a)},updateCeilLab:function(){this.translateFn(this.maxValue,this.ceilLab,"ceil"),this.getDimension(this.ceilLab);var a=this.options.rightToLeft?0:this.barDimension-this.ceilLab.rzsd;this.setPosition(this.ceilLab,a)},updateHandles:function(a,b){"lowValue"===a?this.updateLowHandle(b):this.updateHighHandle(b),this.updateSelectionBar(),this.updateTicksScale(),this.range&&this.updateCmbLabel()},getHandleLabelPos:function(a,b){var c=this[a].rzsd,d=b-c/2+this.handleHalfDim,e=this.barDimension-c;return this.options.boundPointerLabels?this.options.rightToLeft&&"minLab"===a||!this.options.rightToLeft&&"maxLab"===a?Math.min(d,e):Math.min(Math.max(d,0),e):d},updateLowHandle:function(a){if(this.setPosition(this.minH,a),this.translateFn(this.lowValue,this.minLab,"model"),this.setPosition(this.minLab,this.getHandleLabelPos("minLab",a)),this.options.getPointerColor){var b=this.getPointerColor("min");this.scope.minPointerStyle={backgroundColor:b}}this.options.autoHideLimitLabels&&this.shFloorCeil()},updateHighHandle:function(a){if(this.setPosition(this.maxH,a),this.translateFn(this.highValue,this.maxLab,"high"),this.setPosition(this.maxLab,this.getHandleLabelPos("maxLab",a)),this.options.getPointerColor){var b=this.getPointerColor("max");this.scope.maxPointerStyle={backgroundColor:b}}this.options.autoHideLimitLabels&&this.shFloorCeil()},shFloorCeil:function(){if(!this.options.hidePointerLabels){var a=!1,b=!1,c=this.options.rightToLeft,d=this.flrLab.rzsp,e=this.flrLab.rzsd,f=this.minLab.rzsp,g=this.minLab.rzsd,h=this.maxLab.rzsp,i=this.maxLab.rzsd,j=this.cmbLab.rzsp,k=this.cmbLab.rzsd,l=this.ceilLab.rzsp,m=this.handleHalfDim,n=c?f+g>=d-e-5:d+e+5>=f,o=c?l+m+10>=f-g:f+g>=l-m-10,p=c?l+10>=h-i:h+i>=l-10,q=c?j>=d-e-m:d+e+m>=j,r=c?l+10>=j-k:j+k>=l-10;if(n?(a=!0,this.hideEl(this.flrLab)):(a=!1,this.showEl(this.flrLab)),o?(b=!0,this.hideEl(this.ceilLab)):(b=!1,this.showEl(this.ceilLab)),this.range){var s=this.cmbLabelShown?r:p,t=this.cmbLabelShown?q:n;s?this.hideEl(this.ceilLab):b||this.showEl(this.ceilLab),t?this.hideEl(this.flrLab):a||this.showEl(this.flrLab)}}},updateSelectionBar:function(){var a=0,b=0,c=this.options.rightToLeft?!this.options.showSelectionBarEnd:this.options.showSelectionBarEnd,d=this.options.rightToLeft?this.maxH.rzsp+this.handleHalfDim:this.minH.rzsp+this.handleHalfDim;if(this.range)b=Math.abs(this.maxH.rzsp-this.minH.rzsp),a=d;else if(null!==this.options.showSelectionBarFromValue){var e=this.options.showSelectionBarFromValue,f=this.valueToOffset(e),g=this.options.rightToLeft?this.lowValue<=e:this.lowValue>e;g?(b=this.minH.rzsp-f,a=f+this.handleHalfDim):(b=f-this.minH.rzsp,a=this.minH.rzsp+this.handleHalfDim)}else c?(b=Math.abs(this.maxPos-this.minH.rzsp)+this.handleHalfDim,a=this.minH.rzsp+this.handleHalfDim):(b=Math.abs(this.maxH.rzsp-this.minH.rzsp)+this.handleHalfDim,a=0);if(this.setDimension(this.selBar,b),this.setPosition(this.selBar,a),this.options.getSelectionBarColor){var h=this.getSelectionBarColor();this.scope.barStyle={backgroundColor:h}}},getSelectionBarColor:function(){return this.range?this.options.getSelectionBarColor(this.scope.rzSliderModel,this.scope.rzSliderHigh):this.options.getSelectionBarColor(this.scope.rzSliderModel)},getPointerColor:function(a){return"max"===a?this.options.getPointerColor(this.scope.rzSliderHigh,a):this.options.getPointerColor(this.scope.rzSliderModel,a)},getTickColor:function(a){return this.options.getTickColor(a)},updateCmbLabel:function(){var a=null;if(a=this.options.rightToLeft?this.minLab.rzsp-this.minLab.rzsd-10<=this.maxLab.rzsp:this.minLab.rzsp+this.minLab.rzsd+10>=this.maxLab.rzsp){var b=this.getDisplayValue(this.lowValue,"model"),c=this.getDisplayValue(this.highValue,"high"),d="";d=this.options.mergeRangeLabelsIfSame&&b===c?b:this.options.rightToLeft?c+" - "+b:b+" - "+c,this.translateFn(d,this.cmbLab,"cmb",!1);var e=this.options.boundPointerLabels?Math.min(Math.max(this.selBar.rzsp+this.selBar.rzsd/2-this.cmbLab.rzsd/2,0),this.barDimension-this.cmbLab.rzsd):this.selBar.rzsp+this.selBar.rzsd/2-this.cmbLab.rzsd/2;this.setPosition(this.cmbLab,e),this.cmbLabelShown=!0,this.hideEl(this.minLab),this.hideEl(this.maxLab),this.showEl(this.cmbLab)}else this.cmbLabelShown=!1,this.showEl(this.maxLab),this.showEl(this.minLab),this.hideEl(this.cmbLab)},getDisplayValue:function(a,b){return this.options.stepsArray&&!this.options.bindIndexForStepsArray&&(a=this.getStepValue(a)),this.customTrFn(a,this.options.id,b)},roundStep:function(a,b){var c=b?b:this.step,d=parseFloat((a-this.minValue)/c).toPrecision(12);d=Math.round(+d)*c;var e=(this.minValue+d).toFixed(this.precision);return+e},hideEl:function(a){return a.css({visibility:"hidden"})},showEl:function(a){return a.rzAlwaysHide?a:a.css({visibility:"visible"})},setPosition:function(a,b){a.rzsp=b;var c={};return c[this.positionProperty]=b+"px",a.css(c),b},getDimension:function(a){var b=a[0].getBoundingClientRect();return this.options.vertical?a.rzsd=(b.bottom-b.top)*this.options.scale:a.rzsd=(b.right-b.left)*this.options.scale,a.rzsd},setDimension:function(a,b){a.rzsd=b;var c={};return c[this.dimensionProperty]=b+"px",a.css(c),b},valueToOffset:function(a){return this.options.rightToLeft?(this.maxValue-this.sanitizeValue(a))*this.maxPos/this.valueRange||0:(this.sanitizeValue(a)-this.minValue)*this.maxPos/this.valueRange||0},sanitizeValue:function(a){return Math.min(Math.max(a,this.minValue),this.maxValue)},offsetToValue:function(a){return this.options.rightToLeft?(1-a/this.maxPos)*this.valueRange+this.minValue:a/this.maxPos*this.valueRange+this.minValue},getEventXY:function(a){var b=this.options.vertical?"clientY":"clientX";return void 0!==a[b]?a[b]:void 0===a.originalEvent?a.touches[0][b]:a.originalEvent.touches[0][b]},getEventPosition:function(a){var b=this.sliderElem.rzsp,c=0;return c=this.options.vertical?-this.getEventXY(a)+b:this.getEventXY(a)-b,(c-this.handleHalfDim)*this.options.scale},getEventNames:function(a){var b={moveEvent:"",endEvent:""};return a.touches||void 0!==a.originalEvent&&a.originalEvent.touches?(b.moveEvent="touchmove",b.endEvent="touchend"):(b.moveEvent="mousemove",b.endEvent="mouseup"),b},getNearestHandle:function(a){if(!this.range)return this.minH;var b=this.getEventPosition(a),c=Math.abs(b-this.minH.rzsp),d=Math.abs(b-this.maxH.rzsp);return d>c?this.minH:c>d?this.maxH:this.options.rightToLeft?b>this.minH.rzsp?this.minH:this.maxH:b=f?e=h:f>=this.maxPos?e=g:(e=this.offsetToValue(f),e=d&&a.isNumber(this.options.showTicks)?this.roundStep(e,this.options.showTicks):this.roundStep(e)),this.positionTrackingHandle(e)},onEnd:function(a,b){var d=this.getEventNames(b).moveEvent;this.options.keyboardSupport||(this.minH.removeClass("rz-active"),this.maxH.removeClass("rz-active"),this.tracking=""),this.dragging.active=!1,c.off(d,a),this.callOnEnd()},onTickClick:function(a,b){this.onMove(a,b,!0)},onPointerFocus:function(b,c){this.tracking=c,b.one("blur",a.bind(this,this.onPointerBlur,b)),b.on("keydown",a.bind(this,this.onKeyboardEvent)),b.on("keyup",a.bind(this,this.onKeyUp)),this.firstKeyDown=!0,b.addClass("rz-active"),this.currentFocusElement={pointer:b,ref:c}},onKeyUp:function(){this.firstKeyDown=!0,this.callOnEnd()},onPointerBlur:function(a){a.off("keydown"),a.off("keyup"),this.tracking="",a.removeClass("rz-active"),this.currentFocusElement=null},getKeyActions:function(a){var b=a+this.step,c=a-this.step,d=a+this.valueRange/10,e=a-this.valueRange/10,f={UP:b,DOWN:c,LEFT:c,RIGHT:b,PAGEUP:d,PAGEDOWN:e,HOME:this.minValue,END:this.maxValue};return this.options.rightToLeft&&(f.LEFT=b,f.RIGHT=c,this.options.vertical&&(f.UP=c,f.DOWN=b)),f},onKeyboardEvent:function(a){var c=this[this.tracking],d=a.keyCode||a.which,e={38:"UP",40:"DOWN",37:"LEFT",39:"RIGHT",33:"PAGEUP",34:"PAGEDOWN",36:"HOME",35:"END"},f=this.getKeyActions(c),g=e[d],h=f[g];if(null!=h&&""!==this.tracking){a.preventDefault(),this.firstKeyDown&&(this.firstKeyDown=!1,this.callOnStart());var i=this;b(function(){var a=i.roundStep(i.sanitizeValue(h));if(i.options.draggableRangeOnly){var b,c,d=i.highValue-i.lowValue;"lowValue"===i.tracking?(b=a,c=a+d,c>i.maxValue&&(c=i.maxValue,b=c-d)):(c=a,b=a-d,b=k,h=k>=this.maxPos-e,g){if(0===i.rzsp)return;c=this.getValue("min",k,!0,!1),d=this.getValue("max",k,!0,!1)}else if(h){if(j.rzsp===this.maxPos)return;d=this.getValue("max",k,!0,!0),c=this.getValue("min",k,!0,!0)}else c=this.getValue("min",k,!1),d=this.getValue("max",k,!1);this.positionTrackingBar(c,d)},positionTrackingBar:function(a,b){null!=this.options.minLimit&&athis.options.maxLimit&&(b=this.options.maxLimit,a=b-this.dragging.difference),this.lowValue=a,this.highValue=b,this.applyLowValue(),this.range&&this.applyHighValue(),this.applyModel(),this.updateHandles("lowValue",this.valueToOffset(a)),this.updateHandles("highValue",this.valueToOffset(b))},positionTrackingHandle:function(a){var b=!1;a=this.applyMinMaxLimit(a),this.range&&(this.options.pushRange?(a=this.applyPushRange(a),b=!0):(this.options.noSwitching&&("lowValue"===this.tracking&&a>this.highValue?a=this.applyMinMaxRange(this.highValue):"highValue"===this.tracking&&athis.highValue?(this.lowValue=this.highValue,this.applyLowValue(),this.updateHandles(this.tracking,this.maxH.rzsp),this.updateAriaAttributes(),this.tracking="highValue",this.minH.removeClass("rz-active"),this.maxH.addClass("rz-active"),this.options.keyboardSupport&&this.focusElement(this.maxH),b=!0):"highValue"===this.tracking&&athis.options.maxLimit?this.options.maxLimit:a},applyMinMaxRange:function(a){var b="lowValue"===this.tracking?this.highValue:this.lowValue,c=Math.abs(a-b);return null!=this.options.minRange&&cthis.options.maxRange?"lowValue"===this.tracking?this.highValue-this.options.maxRange:this.lowValue+this.options.maxRange:a},applyPushRange:function(a){var b="lowValue"===this.tracking?this.highValue-a:a-this.lowValue,c=null!==this.options.minRange?this.options.minRange:this.options.step;return c>b&&("lowValue"===this.tracking?(this.highValue=Math.min(a+c,this.maxValue),a=this.highValue-c,this.applyHighValue(),this.updateHandles("highValue",this.valueToOffset(this.highValue))):(this.lowValue=Math.max(a-c,this.minValue),a=this.lowValue+c,this.applyLowValue(),this.updateHandles("lowValue",this.valueToOffset(this.lowValue))),this.updateAriaAttributes()),a},applyModel:function(){this.internalChange=!0,this.scope.$apply(),this.callOnChange(),this.internalChange=!1},callOnStart:function(){if(this.options.onStart){var a=this,b="lowValue"===this.tracking?"min":"max";this.scope.$evalAsync(function(){a.options.onStart(a.options.id,a.scope.rzSliderModel,a.scope.rzSliderHigh,b)})}},callOnChange:function(){if(this.options.onChange){var a=this,b="lowValue"===this.tracking?"min":"max";this.scope.$evalAsync(function(){a.options.onChange(a.options.id,a.scope.rzSliderModel,a.scope.rzSliderHigh,b)})}},callOnEnd:function(){if(this.options.onEnd){var a=this,b="lowValue"===this.tracking?"min":"max";this.scope.$evalAsync(function(){a.options.onEnd(a.options.id,a.scope.rzSliderModel,a.scope.rzSliderHigh,b)})}this.scope.$emit("slideEnded")}},h}]).directive("rzslider",["RzSlider",function(a){return{restrict:"AE",replace:!0,scope:{rzSliderModel:"=?",rzSliderHigh:"=?",rzSliderOptions:"&?",rzSliderTplUrl:"@"},templateUrl:function(a,b){return b.rzSliderTplUrl||"rzSliderTpl.html"},link:function(b,c){b.slider=new a(b,c)}}}]);return b.run(["$templateCache",function(a){a.put("rzSliderTpl.html",'
  • {{ t.value }} {{ t.legend }}
')}]),b.name}); \ No newline at end of file +/*! angularjs-slider - v7.1.0 - (c) Rafal Zajac , Valentin Hervieu , Jussi Saarivirta , Angelin Sirbu - https://github.com/angular-slider/angularjs-slider - 2022-05-26 */ +!function(a,b){"use strict";if("function"==typeof define&&define.amd)define(["angular"],b);else if("object"==typeof module&&module.exports){var c=angular||require("angular");c&&c.module||"undefined"==typeof angular||(c=angular),module.exports=b(c)}else b(a.angular)}(this,function(a){"use strict";var b=a.module("rzSlider",[]).factory("RzSliderOptions",function(){var b={floor:0,ceil:null,step:1,precision:0,minRange:null,maxRange:null,restrictedRange:null,skipRestrictedRangesWithArrowKeys:null,pushRange:!1,minLimit:null,maxLimit:null,id:null,translate:null,getLegend:null,stepsArray:null,bindIndexForStepsArray:!1,draggableRange:!1,draggableRangeOnly:!1,showSelectionBar:!1,showSelectionBarEnd:!1,showSelectionBarFromValue:null,showOuterSelectionBars:!1,hidePointerLabels:!1,hideLimitLabels:!1,autoHideLimitLabels:!0,readOnly:!1,disabled:!1,interval:350,showTicks:!1,showTicksValues:!1,ticksArray:null,ticksTooltip:null,ticksValuesTooltip:null,vertical:!1,getSelectionBarColor:null,getTickColor:null,getPointerColor:null,keyboardSupport:!0,scale:1,enforceStep:!0,enforceRange:!1,noSwitching:!1,onlyBindHandles:!1,disableAnimation:!1,onStart:null,onChange:null,onEnd:null,rightToLeft:!1,reversedControls:!1,boundPointerLabels:!0,mergeRangeLabelsIfSame:!1,labelOverlapSeparator:" - ",customTemplateScope:null,logScale:!1,customValueToPosition:null,customPositionToValue:null,selectionBarGradient:null,ariaLabel:null,ariaLabelledBy:null,ariaLabelHigh:null,ariaLabelledByHigh:null},c={},d={};return d.options=function(b){a.extend(c,b)},d.getOptions=function(d){return a.extend({},b,c,d)},d}).factory("rzThrottle",["$timeout",function(a){return function(b,c,d){var e,f,g,h=Date.now||function(){return(new Date).getTime()},i=null,j=0;d=d||{};var k=function(){j=h(),i=null,g=b.apply(e,f),e=f=null};return function(){var l=h(),m=c-(l-j);return e=this,f=arguments,0>=m?(a.cancel(i),i=null,j=l,g=b.apply(e,f),e=f=null):i||d.trailing===!1||(i=a(k,m)),g}}}]).factory("RzSlider",["$timeout","$document","$window","$compile","RzSliderOptions","rzThrottle",function(b,c,d,e,f,g){var h=function(a,b){this.scope=a,this.lowValue=0,this.highValue=0,this.sliderElem=b,this.range=void 0!==this.scope.rzSliderModel&&void 0!==this.scope.rzSliderHigh,this.dragging={active:!1,value:0,difference:0,position:0,lowLimit:0,highLimit:0},this.positionProperty="left",this.dimensionProperty="width",this.handleHalfDim=0,this.maxPos=0,this.precision=0,this.step=1,this.tracking="",this.minValue=0,this.maxValue=0,this.valueRange=0,this.intermediateTicks=!1,this.initHasRun=!1,this.firstKeyDown=!1,this.internalChange=!1,this.cmbLabelShown=!1,this.currentFocusElement=null,this.moving=!1,this.fullBar=null,this.selBar=null,this.minH=null,this.maxH=null,this.flrLab=null,this.ceilLab=null,this.minLab=null,this.maxLab=null,this.cmbLab=null,this.ticks=null,this.init()};return h.prototype={init:function(){var b,c,e=this,f=function(){e.calcViewDimensions()};this.applyOptions(),this.syncLowValue(),this.range&&this.syncHighValue(),this.initElemHandles(),this.manageElementsStyle(),this.setDisabledState(),this.calcViewDimensions(),this.setMinAndMax(),this.updateRestrictionBar(),this.addAccessibility(),this.updateCeilLab(),this.updateFloorLab(),this.initHandles(),this.manageEventsBindings(),this.scope.$on("reCalcViewDimensions",f),a.element(d).on("resize",f),this.initHasRun=!0,this.options.disableAnimation&&this.sliderElem.addClass("noanimate"),b=g(function(){e.onLowHandleChange()},e.options.interval),c=g(function(){e.onHighHandleChange()},e.options.interval),this.scope.$on("rzSliderForceRender",function(){e.resetLabelsValue(),b(),e.range&&c(),e.resetSlider()}),this.scope.$watchCollection("rzSliderOptions()",function(a,b){a!==b&&(e.applyOptions(),e.syncLowValue(),e.range&&e.syncHighValue(),e.resetSlider())}),this.scope.$watch("rzSliderModel",function(a,c){e.internalChange||a!==c&&b()}),this.scope.$watch("rzSliderHigh",function(a,b){e.internalChange||a!==b&&(null!=a&&c(),(e.range&&null==a||!e.range&&null!=a)&&(e.applyOptions(),e.resetSlider()))}),this.scope.$on("$destroy",function(){e.unbindEvents(),a.element(d).off("resize",f),e.currentFocusElement=null})},findStepIndex:function(b){for(var c=0,d=0;d',d.appendChild(f),this.restrictedBar[e]=a.element(f)}}else b.style.visibility="hidden",this.restrictedBar=null},initElemHandles:function(){a.forEach(this.sliderElem.children(),function(b,c){var d=a.element(b);switch(c){case 0:this.leftOutSelBar=d;break;case 1:this.rightOutSelBar=d;break;case 2:this.fullBar=d;break;case 3:this.selBar=d;break;case 4:this.ensureRestrictedBarIsArray(b);break;case 5:this.minH=d;break;case 6:this.maxH=d;break;case 7:this.flrLab=d;break;case 8:this.ceilLab=d;break;case 9:this.minLab=d;break;case 10:this.maxLab=d;break;case 11:this.cmbLab=d;break;case 12:this.ticks=d}},this),this.selBar.rzsp=0,this.minH.rzsp=0,this.maxH.rzsp=0,this.flrLab.rzsp=0,this.ceilLab.rzsp=0,this.minLab.rzsp=0,this.maxLab.rzsp=0,this.cmbLab.rzsp=0},manageElementsStyle:function(){this.range?this.maxH.css("display",""):this.maxH.css("display","none"),this.alwaysHide(this.flrLab,this.options.showTicksValues||this.options.hideLimitLabels),this.alwaysHide(this.ceilLab,this.options.showTicksValues||this.options.hideLimitLabels);var a=this.options.showTicksValues&&!this.intermediateTicks;this.alwaysHide(this.minLab,a||this.options.hidePointerLabels),this.alwaysHide(this.maxLab,a||!this.range||this.options.hidePointerLabels),this.alwaysHide(this.cmbLab,a||!this.range||this.options.hidePointerLabels),this.alwaysHide(this.selBar,!this.range&&!this.options.showSelectionBar),this.alwaysHide(this.leftOutSelBar,!this.range||!this.options.showOuterSelectionBars);for(var b in this.restrictedBar)this.restrictedBar[b]&&this.alwaysHide(this.restrictedBar[b],!this.options.restrictedRange[b]);this.alwaysHide(this.rightOutSelBar,!this.range||!this.options.showOuterSelectionBars),this.range&&this.options.showOuterSelectionBars&&this.fullBar.addClass("rz-transparent"),this.options.vertical?this.sliderElem.addClass("rz-vertical"):this.sliderElem.removeClass("rz-vertical"),this.options.draggableRange?this.selBar.addClass("rz-draggable"):this.selBar.removeClass("rz-draggable"),this.intermediateTicks&&this.options.showTicksValues&&this.ticks.addClass("rz-ticks-values-under")},alwaysHide:function(a,b){a.rzAlwaysHide=b,b?this.hideEl(a):this.showEl(a)},manageEventsBindings:function(){this.options.disabled||this.options.readOnly?this.unbindEvents():this.bindEvents()},setDisabledState:function(){this.options.disabled?this.sliderElem.attr("disabled","disabled"):this.sliderElem.attr("disabled",null)},resetLabelsValue:function(){this.minLab.rzsv=void 0,this.maxLab.rzsv=void 0,this.flrLab.rzsv=void 0,this.ceilLab.rzsv=void 0,this.cmbLab.rzsv=void 0,this.resetPosition(this.flrLab),this.resetPosition(this.ceilLab),this.resetPosition(this.cmbLab),this.resetPosition(this.minLab),this.resetPosition(this.maxLab)},initHandles:function(){this.updateLowHandle(this.valueToPosition(this.lowValue)),this.range&&this.updateHighHandle(this.valueToPosition(this.highValue)),this.updateSelectionBar(),this.range&&this.updateCmbLabel(),this.updateTicksScale()},translateFn:function(a,b,c,d){d=void 0===d?!0:d;var e="",f=!1,g=b.hasClass("no-label-injection");d?(this.options.stepsArray&&!this.options.bindIndexForStepsArray&&(a=this.getStepValue(a)),e=String(this.customTrFn(a,this.options.id,c))):e=String(a),(void 0===b.rzsv||b.rzsv.length!==e.length||b.rzsv.length>0&&0===b.rzsd)&&(f=!0,b.rzsv=e),g||b.html(e),this.scope[c+"Label"]=e,f&&this.getDimension(b)},setMinAndMax:function(){if(this.step=+this.options.step,this.precision=+this.options.precision,this.minValue=this.options.floor,this.options.logScale&&0===this.minValue)throw Error("Can't use floor=0 with logarithmic scale");this.options.enforceStep&&(this.lowValue=this.roundStep(this.lowValue),this.range&&(this.highValue=this.roundStep(this.highValue))),null!=this.options.ceil?this.maxValue=this.options.ceil:this.maxValue=this.options.ceil=this.range?this.highValue:this.lowValue,this.options.enforceRange&&(this.lowValue=this.sanitizeValue(this.lowValue),this.range&&(this.highValue=this.sanitizeValue(this.highValue))),this.applyLowValue(),this.range&&this.applyHighValue(),this.valueRange=this.maxValue-this.minValue},addAccessibility:function(){this.minH.attr("role","slider"),this.updateAriaAttributes(),!this.options.keyboardSupport||this.options.readOnly||this.options.disabled?this.minH.attr("tabindex",""):this.minH.attr("tabindex","0"),this.options.vertical?this.minH.attr("aria-orientation","vertical"):this.minH.attr("aria-orientation","horizontal"),this.options.ariaLabel?this.minH.attr("aria-label",this.options.ariaLabel):this.options.ariaLabelledBy&&this.minH.attr("aria-labelledby",this.options.ariaLabelledBy),this.range&&(this.maxH.attr("role","slider"),!this.options.keyboardSupport||this.options.readOnly||this.options.disabled?this.maxH.attr("tabindex",""):this.maxH.attr("tabindex","0"),this.options.vertical?this.maxH.attr("aria-orientation","vertical"):this.maxH.attr("aria-orientation","horizontal"),this.options.ariaLabelHigh?this.maxH.attr("aria-label",this.options.ariaLabelHigh):this.options.ariaLabelledByHigh&&this.maxH.attr("aria-labelledby",this.options.ariaLabelledByHigh))},updateAriaAttributes:function(){this.minH.attr({"aria-valuenow":this.scope.rzSliderModel,"aria-valuetext":this.customTrFn(this.scope.rzSliderModel,this.options.id,"model"),"aria-valuemin":this.minValue,"aria-valuemax":this.maxValue}),this.range&&this.maxH.attr({"aria-valuenow":this.scope.rzSliderHigh,"aria-valuetext":this.customTrFn(this.scope.rzSliderHigh,this.options.id,"high"),"aria-valuemin":this.minValue,"aria-valuemax":this.maxValue})},calcViewDimensions:function(){var a=this.getDimension(this.minH);if(this.handleHalfDim=a/2,this.barDimension=this.getDimension(this.fullBar),this.maxPos=this.barDimension-a,this.getDimension(this.sliderElem),this.sliderElem.rzsp=this.sliderElem[0].getBoundingClientRect()[this.positionProperty],this.initHasRun){this.updateFloorLab(),this.updateCeilLab(),this.initHandles();var c=this;b(function(){c.updateTicksScale()})}},updateTicksScale:function(){if(this.options.showTicks){var b=this.options.ticksArray||this.getTicksArray(),c=this.options.vertical?"translateY":"translateX",d=this;this.options.rightToLeft&&b.reverse(),this.scope.ticks=b.map(function(b){var e=null;a.isObject(b)&&(e=b.legend,b=b.value);var f=d.valueToPosition(b);d.options.vertical&&(f=d.maxPos-f);var g=c+"("+Math.round(f)+"px)",h={legend:e,selected:d.isTickSelected(b),style:{"-webkit-transform":g,"-moz-transform":g,"-o-transform":g,"-ms-transform":g,transform:g}};return h.selected&&d.options.getSelectionBarColor&&(h.style["background-color"]=d.getSelectionBarColor()),!h.selected&&d.options.getTickColor&&(h.style["background-color"]=d.getTickColor(b)),d.options.ticksTooltip&&(h.tooltip=d.options.ticksTooltip(b),h.tooltipPlacement=d.options.vertical?"right":"top"),(d.options.showTicksValues===!0||b%d.options.showTicksValues===0)&&(h.value=d.getDisplayValue(b,"tick-value"),d.options.ticksValuesTooltip&&(h.valueTooltip=d.options.ticksValuesTooltip(b),h.valueTooltipPlacement=d.options.vertical?"right":"top")),d.getLegend&&(e=d.getLegend(b,d.options.id),e&&(h.legend=e)),h})}},getTicksArray:function(){var a=this.step,b=[];this.intermediateTicks&&(a=this.options.showTicks);for(var c=this.minValue;c<=this.maxValue;c+=a)b.push(c);return b},isTickSelected:function(a){if(!this.range)if(null!==this.options.showSelectionBarFromValue){var b=this.options.showSelectionBarFromValue;if(this.lowValue>b&&a>=b&&a<=this.lowValue)return!0;if(this.lowValue=a&&a>=this.lowValue)return!0}else if(this.options.showSelectionBarEnd){if(a>=this.lowValue)return!0}else if(this.options.showSelectionBar&&a<=this.lowValue)return!0;return this.range&&a>=this.lowValue&&a<=this.highValue?!0:!1},updateFloorLab:function(){this.translateFn(this.minValue,this.flrLab,"floor"),this.getDimension(this.flrLab);var a=this.options.rightToLeft?this.barDimension-this.flrLab.rzsd:0;this.setPosition(this.flrLab,a)},updateCeilLab:function(){this.translateFn(this.maxValue,this.ceilLab,"ceil"),this.getDimension(this.ceilLab);var a=this.options.rightToLeft?0:this.barDimension-this.ceilLab.rzsd;this.setPosition(this.ceilLab,a)},updateHandles:function(a,b){"lowValue"===a?this.updateLowHandle(b):this.updateHighHandle(b),this.updateSelectionBar(),this.updateTicksScale(),this.range&&this.updateCmbLabel()},getHandleLabelPos:function(a,b){var c=this[a].rzsd,d=b-c/2+this.handleHalfDim,e=this.barDimension-c;return this.options.boundPointerLabels?this.options.rightToLeft&&"minLab"===a||!this.options.rightToLeft&&"maxLab"===a?Math.min(d,e):Math.min(Math.max(d,0),e):d},updateLowHandle:function(a){if(this.setPosition(this.minH,a),this.translateFn(this.lowValue,this.minLab,"model"),this.setPosition(this.minLab,this.getHandleLabelPos("minLab",a)),this.options.getPointerColor){var b=this.getPointerColor("min");this.scope.minPointerStyle={backgroundColor:b}}this.options.autoHideLimitLabels&&this.shFloorCeil()},updateHighHandle:function(a){if(this.setPosition(this.maxH,a),this.translateFn(this.highValue,this.maxLab,"high"),this.setPosition(this.maxLab,this.getHandleLabelPos("maxLab",a)),this.options.getPointerColor){var b=this.getPointerColor("max");this.scope.maxPointerStyle={backgroundColor:b}}this.options.autoHideLimitLabels&&this.shFloorCeil()},shFloorCeil:function(){if(!this.options.hidePointerLabels){var a=!1,b=!1,c=this.isLabelBelowFloorLab(this.minLab),d=this.isLabelAboveCeilLab(this.minLab),e=this.isLabelAboveCeilLab(this.maxLab),f=this.isLabelBelowFloorLab(this.cmbLab),g=this.isLabelAboveCeilLab(this.cmbLab);if(c?(a=!0,this.hideEl(this.flrLab)):(a=!1,this.showEl(this.flrLab)),d?(b=!0,this.hideEl(this.ceilLab)):(b=!1,this.showEl(this.ceilLab)),this.range){var h=this.cmbLabelShown?g:e,i=this.cmbLabelShown?f:c;h?this.hideEl(this.ceilLab):b||this.showEl(this.ceilLab),i?this.hideEl(this.flrLab):a||this.showEl(this.flrLab)}}},isLabelBelowFloorLab:function(a){var b=this.options.rightToLeft,c=a.rzsp,d=a.rzsd,e=this.flrLab.rzsp,f=this.flrLab.rzsd;return b?c+d>=e-2:e+f+2>=c},isLabelAboveCeilLab:function(a){var b=this.options.rightToLeft,c=a.rzsp,d=a.rzsd,e=this.ceilLab.rzsp,f=this.ceilLab.rzsd;return b?e+f+2>=c:c+d>=e-2},updateRestrictionBar:function(){var a=0,b=0;if(this.options.restrictedRange){this.options.restrictedRange=Array.isArray(this.options.restrictedRange)?this.options.restrictedRange:[this.options.restrictedRange];for(var c in this.options.restrictedRange){var d=this.valueToPosition(this.options.restrictedRange[c].from),e=this.valueToPosition(this.options.restrictedRange[c].to);b=Math.abs(e-d),a=this.options.rightToLeft?e+this.handleHalfDim:d+this.handleHalfDim,this.setDimension(this.restrictedBar[c],b),this.setPosition(this.restrictedBar[c],a)}}},updateSelectionBar:function(){var a=0,b=0,c=this.options.rightToLeft?!this.options.showSelectionBarEnd:this.options.showSelectionBarEnd,d=this.options.rightToLeft?this.maxH.rzsp+this.handleHalfDim:this.minH.rzsp+this.handleHalfDim;if(this.range)b=Math.abs(this.maxH.rzsp-this.minH.rzsp),a=d;else if(null!==this.options.showSelectionBarFromValue){var e=this.options.showSelectionBarFromValue,f=this.valueToPosition(e),g=this.options.rightToLeft?this.lowValue<=e:this.lowValue>e;g?(b=this.minH.rzsp-f,a=f+this.handleHalfDim):(b=f-this.minH.rzsp,a=this.minH.rzsp+this.handleHalfDim)}else c?(b=Math.abs(this.maxPos-this.minH.rzsp)+this.handleHalfDim,a=this.minH.rzsp+this.handleHalfDim):(b=this.minH.rzsp+this.handleHalfDim,a=0);if(this.setDimension(this.selBar,b),this.setPosition(this.selBar,a),this.range&&this.options.showOuterSelectionBars&&(this.options.rightToLeft?(this.setDimension(this.rightOutSelBar,a),this.setPosition(this.rightOutSelBar,0),this.setDimension(this.leftOutSelBar,this.getDimension(this.fullBar)-(a+b)),this.setPosition(this.leftOutSelBar,a+b)):(this.setDimension(this.leftOutSelBar,a),this.setPosition(this.leftOutSelBar,0),this.setDimension(this.rightOutSelBar,this.getDimension(this.fullBar)-(a+b)),this.setPosition(this.rightOutSelBar,a+b))),this.options.getSelectionBarColor){var h=this.getSelectionBarColor();this.scope.barStyle={backgroundColor:h}}else if(this.options.selectionBarGradient){var i=null!==this.options.showSelectionBarFromValue?this.valueToPosition(this.options.showSelectionBarFromValue):0,j=i-a>0^c,k=this.options.vertical?j?"bottom":"top":j?"left":"right";this.scope.barStyle={backgroundImage:"linear-gradient(to "+k+", "+this.options.selectionBarGradient.from+" 0%,"+this.options.selectionBarGradient.to+" 100%)"},this.options.vertical?(this.scope.barStyle.backgroundPosition="center "+(i+b+a+(j?-this.handleHalfDim:0))+"px",this.scope.barStyle.backgroundSize="100% "+(this.barDimension-this.handleHalfDim)+"px"):(this.scope.barStyle.backgroundPosition=i-a+(j?this.handleHalfDim:0)+"px center",this.scope.barStyle.backgroundSize=this.barDimension-this.handleHalfDim+"px 100%")}},getSelectionBarColor:function(){return this.range?this.options.getSelectionBarColor(this.scope.rzSliderModel,this.scope.rzSliderHigh):this.options.getSelectionBarColor(this.scope.rzSliderModel)},getPointerColor:function(a){return"max"===a?this.options.getPointerColor(this.scope.rzSliderHigh,a):this.options.getPointerColor(this.scope.rzSliderModel,a)},getTickColor:function(a){return this.options.getTickColor(a)},updateCmbLabel:function(){var a=null;if(a=this.options.rightToLeft?this.minLab.rzsp-this.minLab.rzsd-10<=this.maxLab.rzsp:this.minLab.rzsp+this.minLab.rzsd+10>=this.maxLab.rzsp){var b=this.getDisplayValue(this.lowValue,"model"),c=this.getDisplayValue(this.highValue,"high"),d="";d=this.options.mergeRangeLabelsIfSame&&b===c?b:this.options.rightToLeft?c+this.options.labelOverlapSeparator+b:b+this.options.labelOverlapSeparator+c,this.translateFn(d,this.cmbLab,"cmb",!1);var e=this.options.boundPointerLabels?Math.min(Math.max(this.selBar.rzsp+this.selBar.rzsd/2-this.cmbLab.rzsd/2,0),this.barDimension-this.cmbLab.rzsd):this.selBar.rzsp+this.selBar.rzsd/2-this.cmbLab.rzsd/2;this.setPosition(this.cmbLab,e),this.cmbLabelShown=!0,this.hideEl(this.minLab),this.hideEl(this.maxLab),this.showEl(this.cmbLab)}else this.cmbLabelShown=!1,this.updateHighHandle(this.valueToPosition(this.highValue)),this.updateLowHandle(this.valueToPosition(this.lowValue)),this.showEl(this.maxLab),this.showEl(this.minLab),this.hideEl(this.cmbLab);this.options.autoHideLimitLabels&&this.shFloorCeil()},getDisplayValue:function(a,b){return this.options.stepsArray&&!this.options.bindIndexForStepsArray&&(a=this.getStepValue(a)),this.customTrFn(a,this.options.id,b)},roundStep:function(a,b){var c=b?b:this.step,d=parseFloat((a-this.minValue)/c).toPrecision(12);d=Math.round(+d)*c;var e=(this.minValue+d).toFixed(this.precision);return+e},hideEl:function(a){return a.css({visibility:"hidden"})},showEl:function(a){return a.rzAlwaysHide?a:a.css({visibility:"visible"})},setPosition:function(a,b){a.rzsp=b;var c={};return c[this.positionProperty]=Math.round(b)+"px",a.css(c),b},resetPosition:function(a){a.css({left:null,bottom:null})},getDimension:function(a){var b=a[0].getBoundingClientRect();return this.options.vertical?a.rzsd=(b.bottom-b.top)*this.options.scale:a.rzsd=(b.right-b.left)*this.options.scale,a.rzsd},setDimension:function(a,b){a.rzsd=b;var c={};return c[this.dimensionProperty]=Math.round(b)+"px",a.css(c),b},sanitizeValue:function(a){return Math.min(Math.max(a,this.minValue),this.maxValue)},valueToPosition:function(a){var b=this.linearValueToPosition;this.options.customValueToPosition?b=this.options.customValueToPosition:this.options.logScale&&(b=this.logValueToPosition),a=this.sanitizeValue(a);var c=b(a,this.minValue,this.maxValue)||0;return this.options.rightToLeft&&(c=1-c),c*this.maxPos},linearValueToPosition:function(a,b,c){var d=c-b;return(a-b)/d},logValueToPosition:function(a,b,c){a=Math.log(a),b=Math.log(b),c=Math.log(c);var d=c-b;return(a-b)/d},positionToValue:function(a){var b=a/this.maxPos;this.options.rightToLeft&&(b=1-b);var c=this.linearPositionToValue;return this.options.customPositionToValue?c=this.options.customPositionToValue:this.options.logScale&&(c=this.logPositionToValue),c(b,this.minValue,this.maxValue)||0},linearPositionToValue:function(a,b,c){return a*(c-b)+b},logPositionToValue:function(a,b,c){b=Math.log(b),c=Math.log(c);var d=a*(c-b)+b;return Math.exp(d)},getEventAttr:function(a,b){return void 0===a.originalEvent?a[b]:a.originalEvent[b]},getEventXY:function(a,b){var c=this.options.vertical?"clientY":"clientX";if(void 0!==a[c])return a[c];var d=this.getEventAttr(a,"touches");if(void 0!==b)for(var e=0;ec?this.minH:c>d?this.maxH:this.options.rightToLeft?b>this.minH.rzsp?this.minH:this.maxH:b=i?h=k:i>=this.maxPos?h=j:(h=this.positionToValue(i),h=d&&a.isNumber(this.options.showTicks)?this.roundStep(h,this.options.showTicks):this.roundStep(h)),this.positionTrackingHandle(h)}},onEnd:function(a,b){this.moving=!1,this.options.disableAnimation||this.sliderElem.removeClass("noanimate");var d=this.getEventAttr(b,"changedTouches");if(!d||d[0].identifier===this.touchId){this.isDragging=!1,this.touchId=null,this.options.keyboardSupport||(this.minH.removeClass("rz-active"),this.maxH.removeClass("rz-active"),this.tracking=""),this.dragging.active=!1;var e=this.getEventNames(b);c.off(e.moveEvent,a),c.off(e.endEvent,this.endHandlerToBeRemovedOnEnd),this.endHandlerToBeRemovedOnEnd=null,this.callOnEnd()}},onTickClick:function(a,b){this.onMove(a,b,!0)},onPointerFocus:function(b,c){this.tracking=c,b.one("blur",a.bind(this,this.onPointerBlur,b)),b.on("keydown",a.bind(this,this.onKeyboardEvent)),b.on("keyup",a.bind(this,this.onKeyUp)),this.firstKeyDown=!0,b.addClass("rz-active"),this.currentFocusElement={pointer:b,ref:c}},onKeyUp:function(){this.firstKeyDown=!0,this.callOnEnd()},onPointerBlur:function(a){a.off("keydown"),a.off("keyup"),a.removeClass("rz-active"),this.isDragging||(this.tracking="",this.currentFocusElement=null)},skipRestrictedRanges:function(a,b){if(this.options.restrictedRange&&Array.isArray(this.options.restrictedRange))for(var c in this.options.restrictedRange){var d=this.options.restrictedRange[c];if(0===d.from&&0===b&&[37,40].includes(a)||d.to>=this.options.restrictedRange[this.options.restrictedRange.length-1].to&&b>=this.options.restrictedRange[this.options.restrictedRange.length-1].to&&[38,39].includes(a))return b;d.to>b&&b>d.from&&(b=Math.abs(d.to-b)>Math.abs(d.from-b)?d.to:d.from)}return b},getKeyActions:function(a){var b=a+this.step,c=a-this.step,d=a+this.valueRange/10,e=a-this.valueRange/10;this.options.reversedControls&&(b=a-this.step,c=a+this.step,d=a-this.valueRange/10,e=a+this.valueRange/10);var f={UP:b,DOWN:c,LEFT:c,RIGHT:b,PAGEUP:d,PAGEDOWN:e,HOME:this.options.reversedControls?this.maxValue:this.minValue,END:this.options.reversedControls?this.minValue:this.maxValue};return this.options.rightToLeft&&(f.LEFT=b,f.RIGHT=c,this.options.vertical&&(f.UP=c,f.DOWN=b)),f},onKeyboardEvent:function(a){var c=a.keyCode||a.which,d=this[this.tracking],e={38:"UP",40:"DOWN",37:"LEFT",39:"RIGHT",33:"PAGEUP",34:"PAGEDOWN",36:"HOME",35:"END"},f=this.getKeyActions(d),g=e[c],h=f[g];if(null!=h&&""!==this.tracking){a.preventDefault(),this.firstKeyDown&&(this.firstKeyDown=!1,this.callOnStart());var i=this;b(function(){var a=i.roundStep(i.sanitizeValue(h));if(a=i.options.skipRestrictedRangesWithArrowKeys?i.skipRestrictedRanges(c,a):a,i.options.draggableRangeOnly){var b,d,e=i.highValue-i.lowValue;"lowValue"===i.tracking?(b=a,d=a+e,d>i.maxValue&&(d=i.maxValue,b=d-e)):(d=a,b=a-e,b=k,h=k>=this.maxPos-e,g){if(0===i.rzsp)return;c=this.getValue("min",k,!0,!1),d=this.getValue("max",k,!0,!1)}else if(h){if(j.rzsp===this.maxPos)return;d=this.getValue("max",k,!0,!0),c=this.getValue("min",k,!0,!0)}else c=this.getValue("min",k,!1),d=this.getValue("max",k,!1);this.positionTrackingBar(c,d)},positionTrackingBar:function(a,b){null!=this.options.minLimit&&athis.options.maxLimit&&(b=this.options.maxLimit,a=b-this.dragging.difference),this.lowValue=a,this.highValue=b,this.applyLowValue(),this.range&&this.applyHighValue(),this.applyModel(!0),this.updateHandles("lowValue",this.valueToPosition(a)),this.updateHandles("highValue",this.valueToPosition(b))},positionTrackingHandle:function(a){var b=!1;a=this.applyMinMaxLimit(a),a=this.applyRestrictedRange(a),this.range&&(this.options.pushRange?(a=this.applyPushRange(a),b=!0):(this.options.noSwitching&&("lowValue"===this.tracking&&a>this.highValue?a=this.applyMinMaxRange(this.highValue):"highValue"===this.tracking&&athis.highValue?(this.lowValue=this.highValue,this.applyLowValue(),this.applyModel(),this.updateHandles(this.tracking,this.maxH.rzsp),this.updateAriaAttributes(),this.tracking="highValue",this.minH.removeClass("rz-active"),this.maxH.addClass("rz-active"),this.options.keyboardSupport&&this.focusElement(this.maxH),b=!0):"highValue"===this.tracking&&athis.options.maxLimit?this.options.maxLimit:a},applyMinMaxRange:function(a){var b="lowValue"===this.tracking?this.highValue:this.lowValue,c=Math.abs(a-b);return null!=this.options.minRange&&cthis.options.maxRange?"lowValue"===this.tracking?this.highValue-this.options.maxRange:this.lowValue+this.options.maxRange:a},applyRestrictedRange:function(a){for(var b in this.options.restrictedRange)if(null!=this.options.restrictedRange[b]&&a>this.options.restrictedRange[b].from&&athis.options.restrictedRange[b].from+c?this.options.restrictedRange[b].to:this.options.restrictedRange[b].from;if("highValue"===this.tracking)return ab?("lowValue"===this.tracking?(this.highValue=Math.min(a+c,this.maxValue),a=this.highValue-c,this.applyHighValue(),this.updateHandles("highValue",this.valueToPosition(this.highValue))):(this.lowValue=Math.max(a-c,this.minValue),a=this.lowValue+c,this.applyLowValue(),this.updateHandles("lowValue",this.valueToPosition(this.lowValue))),this.updateAriaAttributes()):null!==d&&b>d&&("lowValue"===this.tracking?(this.highValue=a+d,this.applyHighValue(),this.updateHandles("highValue",this.valueToPosition(this.highValue))):(this.lowValue=a-d,this.applyLowValue(),this.updateHandles("lowValue",this.valueToPosition(this.lowValue))),this.updateAriaAttributes()),a},applyModel:function(a){this.internalChange=!0,this.scope.$apply(),a&&this.callOnChange(),this.internalChange=!1},callOnStart:function(){if(this.options.onStart){var a=this,b="lowValue"===this.tracking?"min":"max";this.scope.$evalAsync(function(){a.options.onStart(a.options.id,a.scope.rzSliderModel,a.scope.rzSliderHigh,b)})}},callOnChange:function(){if(this.options.onChange){var a=this,b="lowValue"===this.tracking?"min":"max";this.scope.$evalAsync(function(){a.options.onChange(a.options.id,a.scope.rzSliderModel,a.scope.rzSliderHigh,b)})}},callOnEnd:function(){if(this.options.onEnd){var a=this,b="lowValue"===this.tracking?"min":"max";this.scope.$evalAsync(function(){a.options.onEnd(a.options.id,a.scope.rzSliderModel,a.scope.rzSliderHigh,b)})}this.scope.$emit("slideEnded")}},h}]).directive("rzslider",["RzSlider",function(a){return{restrict:"AE",replace:!0,scope:{rzSliderModel:"=?",rzSliderHigh:"=?",rzSliderOptions:"&?",rzSliderTplUrl:"@"},templateUrl:function(a,b){return b.rzSliderTplUrl||"rzSliderTpl.html"},link:function(b,c){b.slider=new a(b,c)}}}]);return b.run(["$templateCache",function(a){a.put("rzSliderTpl.html",'
  • {{ t.value }} {{ t.legend }}
')}]),b.name}); \ No newline at end of file diff --git a/dist/rzslider.scss b/dist/rzslider.scss new file mode 100644 index 0000000..5f60607 --- /dev/null +++ b/dist/rzslider.scss @@ -0,0 +1,284 @@ +/*! angularjs-slider - v7.1.0 - + (c) Rafal Zajac , Valentin Hervieu , Jussi Saarivirta , Angelin Sirbu - + https://github.com/angular-slider/angularjs-slider - + 2022-05-26 */ +.rzslider { + position: relative; + display: inline-block; + width: 100%; + height: 4px; + margin: 35px 0 15px 0; + vertical-align: middle; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.rzslider.noanimate * { + transition: none !important; +} + +.rzslider.with-legend { + margin-bottom: 40px; +} + +.rzslider[disabled] { + cursor: not-allowed; +} + +.rzslider[disabled] .rz-pointer { + cursor: not-allowed; + background-color: #d8e0f3; +} + +.rzslider[disabled] .rz-draggable { + cursor: not-allowed; +} + +.rzslider[disabled] .rz-selection { + background: #8b91a2; +} + +.rzslider[disabled] .rz-tick { + cursor: not-allowed; +} + +.rzslider[disabled] .rz-tick.rz-selected { + background: #8b91a2; +} + +.rzslider span { + position: absolute; + display: inline-block; + white-space: nowrap; +} + +.rzslider .rz-base { + width: 100%; + height: 100%; + padding: 0; +} + +.rzslider .rz-bar-wrapper { + left: 0; + z-index: 1; + width: 100%; + height: 32px; + padding-top: 16px; + margin-top: -16px; + box-sizing: border-box; + transition: all linear 0.3s; +} + +.rzslider .rz-draggable { + cursor: move; +} + +.rzslider .rz-bar { + left: 0; + z-index: 1; + width: 100%; + height: 4px; + background: #d8e0f3; + border-radius: 2px; +} + +.rzslider .rz-bar-wrapper.rz-transparent .rz-bar { + background: transparent; +} + +.rzslider .rz-bar-wrapper.rz-left-out-selection .rz-bar { + background: #df002d; +} + +.rzslider .rz-bar-wrapper.rz-right-out-selection .rz-bar { + background: #03a688; +} + +.rzslider .rz-selection { + z-index: 2; + background: #0db9f0; + border-radius: 2px; + transition: background-color linear 0.3s; +} + +.rzslider .rz-restricted { + z-index: 3; + background: #ff0000; + border-radius: 2px; +} + +.rzslider .rz-pointer { + top: -14px; + z-index: 3; + width: 32px; + height: 32px; + cursor: pointer; + background-color: #0db9f0; + border-radius: 16px; + transition: all linear 0.3s; +} + +.rzslider .rz-pointer:after { + position: absolute; + top: 12px; + left: 12px; + width: 8px; + height: 8px; + background: #ffffff; + border-radius: 4px; + content: ''; +} + +.rzslider .rz-pointer:hover:after { + background-color: #ffffff; +} + +.rzslider .rz-pointer.rz-active { + z-index: 4; +} + +.rzslider .rz-pointer.rz-active:after { + background-color: #451aff; +} + +.rzslider .rz-bubble { + bottom: 16px; + padding: 1px 3px; + color: #55637d; + cursor: default; + transition: all linear 0.3s; +} + +.rzslider .rz-bubble.rz-limit { + color: #55637d; + transition: none; +} + +.rzslider .rz-ticks { + position: absolute; + top: -3px; + left: 0; + z-index: 1; + width: 100%; + height: 0; + margin: 0; + list-style: none; + box-sizing: border-box; +} + +.rzslider .rz-ticks-values-under .rz-tick-value { + top: auto; + bottom: -32px; +} + +.rzslider .rz-tick { + position: absolute; + top: 0; + left: 0; + width: 10px; + height: 10px; + margin-left: 11px; + text-align: center; + cursor: pointer; + background: #d8e0f3; + border-radius: 50%; + transition: background-color linear 0.3s; +} + +.rzslider .rz-tick.rz-selected { + background: #0db9f0; +} + +.rzslider .rz-tick-value { + position: absolute; + top: -30px; + transform: translate(-50%, 0); +} + +.rzslider .rz-tick-legend { + position: absolute; + top: 24px; + max-width: 50px; + white-space: normal; + transform: translate(-50%, 0); +} + +.rzslider.rz-vertical { + position: relative; + width: 4px; + height: 100%; + padding: 0; + margin: 0 20px; + vertical-align: baseline; +} + +.rzslider.rz-vertical .rz-base { + width: 100%; + height: 100%; + padding: 0; +} + +.rzslider.rz-vertical .rz-bar-wrapper { + top: auto; + left: 0; + width: 32px; + height: 100%; + padding: 0 0 0 16px; + margin: 0 0 0 -16px; +} + +.rzslider.rz-vertical .rz-bar { + bottom: 0; + left: auto; + width: 4px; + height: 100%; +} + +.rzslider.rz-vertical .rz-pointer { + top: auto; + bottom: 0; + left: -14px !important; +} + +.rzslider.rz-vertical .rz-bubble { + bottom: 0; + left: 16px !important; + margin-left: 3px; +} + +.rzslider.rz-vertical .rz-ticks { + top: 0; + left: -3px; + z-index: 1; + width: 0; + height: 100%; +} + +.rzslider.rz-vertical .rz-tick { + margin-top: 11px; + margin-left: auto; + vertical-align: middle; +} + +.rzslider.rz-vertical .rz-tick-value { + top: auto; + left: 24px; + transform: translate(0, -28%); +} + +.rzslider.rz-vertical .rz-tick-legend { + top: auto; + right: 24px; + max-width: none; + white-space: nowrap; + transform: translate(0, -28%); +} + +.rzslider.rz-vertical .rz-ticks-values-under .rz-tick-value { + right: 24px; + bottom: auto; + left: auto; +} +/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInJ6c2xpZGVyLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O2NBR2M7QUFDZDtFQUNFLG1CQUFtQjtFQUNuQixzQkFBc0I7RUFDdEIsWUFBWTtFQUNaLFlBQVk7RUFDWixzQkFBc0I7RUFDdEIsdUJBQXVCO0VBQ3ZCLDBCQUFrQjtLQUFsQix1QkFBa0I7TUFBbEIsc0JBQWtCO1VBQWxCLGtCQUFrQjtDQUNuQjs7QUFFRDtFQUNFLDRCQUE0QjtDQUM3Qjs7QUFFRDtFQUNFLG9CQUFvQjtDQUNyQjs7QUFFRDtFQUNFLG9CQUFvQjtDQUNyQjs7QUFFRDtFQUNFLG9CQUFvQjtFQUNwQiwwQkFBMEI7Q0FDM0I7O0FBRUQ7RUFDRSxvQkFBb0I7Q0FDckI7O0FBRUQ7RUFDRSxvQkFBb0I7Q0FDckI7O0FBRUQ7RUFDRSxvQkFBb0I7Q0FDckI7O0FBRUQ7RUFDRSxvQkFBb0I7Q0FDckI7O0FBRUQ7RUFDRSxtQkFBbUI7RUFDbkIsc0JBQXNCO0VBQ3RCLG9CQUFvQjtDQUNyQjs7QUFFRDtFQUNFLFlBQVk7RUFDWixhQUFhO0VBQ2IsV0FBVztDQUNaOztBQUVEO0VBQ0UsUUFBUTtFQUNSLFdBQVc7RUFDWCxZQUFZO0VBQ1osYUFBYTtFQUNiLGtCQUFrQjtFQUNsQixrQkFBa0I7RUFDbEIsdUJBQXVCO0VBQ3ZCLDRCQUE0QjtDQUM3Qjs7QUFFRDtFQUNFLGFBQWE7Q0FDZDs7QUFFRDtFQUNFLFFBQVE7RUFDUixXQUFXO0VBQ1gsWUFBWTtFQUNaLFlBQVk7RUFDWixvQkFBb0I7RUFHWixtQkFBbUI7Q0FDNUI7O0FBRUQ7RUFDRSx3QkFBd0I7Q0FDekI7O0FBRUQ7RUFDRSxvQkFBb0I7Q0FDckI7O0FBRUQ7RUFDRSxvQkFBb0I7Q0FDckI7O0FBRUQ7RUFDRSxXQUFXO0VBQ1gsb0JBQW9CO0VBR1osbUJBQW1CO0VBQzNCLHlDQUF5QztDQUMxQzs7QUFFRDtFQUNFLFdBQVc7RUFDWCxvQkFBb0I7RUFHWixtQkFBbUI7Q0FDNUI7O0FBRUQ7RUFDRSxXQUFXO0VBQ1gsV0FBVztFQUNYLFlBQVk7RUFDWixhQUFhO0VBQ2IsZ0JBQWdCO0VBQ2hCLDBCQUEwQjtFQUdsQixvQkFBb0I7RUFDNUIsNEJBQTRCO0NBQzdCOztBQUVEO0VBQ0UsbUJBQW1CO0VBQ25CLFVBQVU7RUFDVixXQUFXO0VBQ1gsV0FBVztFQUNYLFlBQVk7RUFDWixvQkFBb0I7RUFHWixtQkFBbUI7RUFDM0IsWUFBWTtDQUNiOztBQUVEO0VBQ0UsMEJBQTBCO0NBQzNCOztBQUVEO0VBQ0UsV0FBVztDQUNaOztBQUVEO0VBQ0UsMEJBQTBCO0NBQzNCOztBQUVEO0VBQ0UsYUFBYTtFQUNiLGlCQUFpQjtFQUNqQixlQUFlO0VBQ2YsZ0JBQWdCO0VBQ2hCLDRCQUE0QjtDQUM3Qjs7QUFFRDtFQUNFLGVBQWU7RUFDZixpQkFBaUI7Q0FDbEI7O0FBRUQ7RUFDRSxtQkFBbUI7RUFDbkIsVUFBVTtFQUNWLFFBQVE7RUFDUixXQUFXO0VBQ1gsWUFBWTtFQUNaLFVBQVU7RUFDVixVQUFVO0VBQ1YsaUJBQWlCO0VBQ2pCLHVCQUF1QjtDQUN4Qjs7QUFFRDtFQUNFLFVBQVU7RUFDVixjQUFjO0NBQ2Y7O0FBRUQ7RUFDRSxtQkFBbUI7RUFDbkIsT0FBTztFQUNQLFFBQVE7RUFDUixZQUFZO0VBQ1osYUFBYTtFQUNiLGtCQUFrQjtFQUNsQixtQkFBbUI7RUFDbkIsZ0JBQWdCO0VBQ2hCLG9CQUFvQjtFQUNwQixtQkFBbUI7RUFDbkIseUNBQXlDO0NBQzFDOztBQUVEO0VBQ0Usb0JBQW9CO0NBQ3JCOztBQUVEO0VBQ0UsbUJBQW1CO0VBQ25CLFdBQVc7RUFDWCw4QkFBOEI7Q0FDL0I7O0FBRUQ7RUFDRSxtQkFBbUI7RUFDbkIsVUFBVTtFQUNWLGdCQUFnQjtFQUNoQixvQkFBb0I7RUFDcEIsOEJBQThCO0NBQy9COztBQUVEO0VBQ0UsbUJBQW1CO0VBQ25CLFdBQVc7RUFDWCxhQUFhO0VBQ2IsV0FBVztFQUNYLGVBQWU7RUFDZix5QkFBeUI7Q0FDMUI7O0FBRUQ7RUFDRSxZQUFZO0VBQ1osYUFBYTtFQUNiLFdBQVc7Q0FDWjs7QUFFRDtFQUNFLFVBQVU7RUFDVixRQUFRO0VBQ1IsWUFBWTtFQUNaLGFBQWE7RUFDYixvQkFBb0I7RUFDcEIsb0JBQW9CO0NBQ3JCOztBQUVEO0VBQ0UsVUFBVTtFQUNWLFdBQVc7RUFDWCxXQUFXO0VBQ1gsYUFBYTtDQUNkOztBQUVEO0VBQ0UsVUFBVTtFQUNWLFVBQVU7RUFDVix1QkFBdUI7Q0FDeEI7O0FBRUQ7RUFDRSxVQUFVO0VBQ1Ysc0JBQXNCO0VBQ3RCLGlCQUFpQjtDQUNsQjs7QUFFRDtFQUNFLE9BQU87RUFDUCxXQUFXO0VBQ1gsV0FBVztFQUNYLFNBQVM7RUFDVCxhQUFhO0NBQ2Q7O0FBRUQ7RUFDRSxpQkFBaUI7RUFDakIsa0JBQWtCO0VBQ2xCLHVCQUF1QjtDQUN4Qjs7QUFFRDtFQUNFLFVBQVU7RUFDVixXQUFXO0VBQ1gsOEJBQThCO0NBQy9COztBQUVEO0VBQ0UsVUFBVTtFQUNWLFlBQVk7RUFDWixnQkFBZ0I7RUFDaEIsb0JBQW9CO0VBQ3BCLDhCQUE4QjtDQUMvQjs7QUFFRDtFQUNFLFlBQVk7RUFDWixhQUFhO0VBQ2IsV0FBVztDQUNaIiwiZmlsZSI6InJ6c2xpZGVyLmNzcyIsInNvdXJjZXNDb250ZW50IjpbIi8qISBhbmd1bGFyanMtc2xpZGVyIC0gdjcuMS4wIC0gXG4gKGMpIFJhZmFsIFphamFjIDxyemFqYWNAZ21haWwuY29tPiwgVmFsZW50aW4gSGVydmlldSA8dmFsZW50aW5AaGVydmkuZXU+LCBKdXNzaSBTYWFyaXZpcnRhIDxqdXNhc2lAZ21haWwuY29tPiwgQW5nZWxpbiBTaXJidSA8YW5nZWxpbi5zaXJidUBnbWFpbC5jb20+IC0gXG4gaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXItc2xpZGVyL2FuZ3VsYXJqcy1zbGlkZXIgLSBcbiAyMDIyLTA1LTI2ICovXG4ucnpzbGlkZXIge1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogNHB4O1xuICBtYXJnaW46IDM1cHggMCAxNXB4IDA7XG4gIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG4gIHVzZXItc2VsZWN0OiBub25lO1xufVxuXG4ucnpzbGlkZXIubm9hbmltYXRlICoge1xuICB0cmFuc2l0aW9uOiBub25lICFpbXBvcnRhbnQ7XG59XG5cbi5yenNsaWRlci53aXRoLWxlZ2VuZCB7XG4gIG1hcmdpbi1ib3R0b206IDQwcHg7XG59XG5cbi5yenNsaWRlcltkaXNhYmxlZF0ge1xuICBjdXJzb3I6IG5vdC1hbGxvd2VkO1xufVxuXG4ucnpzbGlkZXJbZGlzYWJsZWRdIC5yei1wb2ludGVyIHtcbiAgY3Vyc29yOiBub3QtYWxsb3dlZDtcbiAgYmFja2dyb3VuZC1jb2xvcjogI2Q4ZTBmMztcbn1cblxuLnJ6c2xpZGVyW2Rpc2FibGVkXSAucnotZHJhZ2dhYmxlIHtcbiAgY3Vyc29yOiBub3QtYWxsb3dlZDtcbn1cblxuLnJ6c2xpZGVyW2Rpc2FibGVkXSAucnotc2VsZWN0aW9uIHtcbiAgYmFja2dyb3VuZDogIzhiOTFhMjtcbn1cblxuLnJ6c2xpZGVyW2Rpc2FibGVkXSAucnotdGljayB7XG4gIGN1cnNvcjogbm90LWFsbG93ZWQ7XG59XG5cbi5yenNsaWRlcltkaXNhYmxlZF0gLnJ6LXRpY2sucnotc2VsZWN0ZWQge1xuICBiYWNrZ3JvdW5kOiAjOGI5MWEyO1xufVxuXG4ucnpzbGlkZXIgc3BhbiB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xufVxuXG4ucnpzbGlkZXIgLnJ6LWJhc2Uge1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAxMDAlO1xuICBwYWRkaW5nOiAwO1xufVxuXG4ucnpzbGlkZXIgLnJ6LWJhci13cmFwcGVyIHtcbiAgbGVmdDogMDtcbiAgei1pbmRleDogMTtcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogMzJweDtcbiAgcGFkZGluZy10b3A6IDE2cHg7XG4gIG1hcmdpbi10b3A6IC0xNnB4O1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICB0cmFuc2l0aW9uOiBhbGwgbGluZWFyIDAuM3M7XG59XG5cbi5yenNsaWRlciAucnotZHJhZ2dhYmxlIHtcbiAgY3Vyc29yOiBtb3ZlO1xufVxuXG4ucnpzbGlkZXIgLnJ6LWJhciB7XG4gIGxlZnQ6IDA7XG4gIHotaW5kZXg6IDE7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDRweDtcbiAgYmFja2dyb3VuZDogI2Q4ZTBmMztcbiAgLXdlYmtpdC1ib3JkZXItcmFkaXVzOiAycHg7XG4gICAgIC1tb3otYm9yZGVyLXJhZGl1czogMnB4O1xuICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDJweDtcbn1cblxuLnJ6c2xpZGVyIC5yei1iYXItd3JhcHBlci5yei10cmFuc3BhcmVudCAucnotYmFyIHtcbiAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG59XG5cbi5yenNsaWRlciAucnotYmFyLXdyYXBwZXIucnotbGVmdC1vdXQtc2VsZWN0aW9uIC5yei1iYXIge1xuICBiYWNrZ3JvdW5kOiAjZGYwMDJkO1xufVxuXG4ucnpzbGlkZXIgLnJ6LWJhci13cmFwcGVyLnJ6LXJpZ2h0LW91dC1zZWxlY3Rpb24gLnJ6LWJhciB7XG4gIGJhY2tncm91bmQ6ICMwM2E2ODg7XG59XG5cbi5yenNsaWRlciAucnotc2VsZWN0aW9uIHtcbiAgei1pbmRleDogMjtcbiAgYmFja2dyb3VuZDogIzBkYjlmMDtcbiAgLXdlYmtpdC1ib3JkZXItcmFkaXVzOiAycHg7XG4gICAgIC1tb3otYm9yZGVyLXJhZGl1czogMnB4O1xuICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgdHJhbnNpdGlvbjogYmFja2dyb3VuZC1jb2xvciBsaW5lYXIgMC4zcztcbn1cblxuLnJ6c2xpZGVyIC5yei1yZXN0cmljdGVkIHtcbiAgei1pbmRleDogMztcbiAgYmFja2dyb3VuZDogI2ZmMDAwMDtcbiAgLXdlYmtpdC1ib3JkZXItcmFkaXVzOiAycHg7XG4gICAgIC1tb3otYm9yZGVyLXJhZGl1czogMnB4O1xuICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDJweDtcbn1cblxuLnJ6c2xpZGVyIC5yei1wb2ludGVyIHtcbiAgdG9wOiAtMTRweDtcbiAgei1pbmRleDogMztcbiAgd2lkdGg6IDMycHg7XG4gIGhlaWdodDogMzJweDtcbiAgY3Vyc29yOiBwb2ludGVyO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjMGRiOWYwO1xuICAtd2Via2l0LWJvcmRlci1yYWRpdXM6IDE2cHg7XG4gICAgIC1tb3otYm9yZGVyLXJhZGl1czogMTZweDtcbiAgICAgICAgICBib3JkZXItcmFkaXVzOiAxNnB4O1xuICB0cmFuc2l0aW9uOiBhbGwgbGluZWFyIDAuM3M7XG59XG5cbi5yenNsaWRlciAucnotcG9pbnRlcjphZnRlciB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgdG9wOiAxMnB4O1xuICBsZWZ0OiAxMnB4O1xuICB3aWR0aDogOHB4O1xuICBoZWlnaHQ6IDhweDtcbiAgYmFja2dyb3VuZDogI2ZmZmZmZjtcbiAgLXdlYmtpdC1ib3JkZXItcmFkaXVzOiA0cHg7XG4gICAgIC1tb3otYm9yZGVyLXJhZGl1czogNHB4O1xuICAgICAgICAgIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgY29udGVudDogJyc7XG59XG5cbi5yenNsaWRlciAucnotcG9pbnRlcjpob3ZlcjphZnRlciB7XG4gIGJhY2tncm91bmQtY29sb3I6ICNmZmZmZmY7XG59XG5cbi5yenNsaWRlciAucnotcG9pbnRlci5yei1hY3RpdmUge1xuICB6LWluZGV4OiA0O1xufVxuXG4ucnpzbGlkZXIgLnJ6LXBvaW50ZXIucnotYWN0aXZlOmFmdGVyIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogIzQ1MWFmZjtcbn1cblxuLnJ6c2xpZGVyIC5yei1idWJibGUge1xuICBib3R0b206IDE2cHg7XG4gIHBhZGRpbmc6IDFweCAzcHg7XG4gIGNvbG9yOiAjNTU2MzdkO1xuICBjdXJzb3I6IGRlZmF1bHQ7XG4gIHRyYW5zaXRpb246IGFsbCBsaW5lYXIgMC4zcztcbn1cblxuLnJ6c2xpZGVyIC5yei1idWJibGUucnotbGltaXQge1xuICBjb2xvcjogIzU1NjM3ZDtcbiAgdHJhbnNpdGlvbjogbm9uZTtcbn1cblxuLnJ6c2xpZGVyIC5yei10aWNrcyB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgdG9wOiAtM3B4O1xuICBsZWZ0OiAwO1xuICB6LWluZGV4OiAxO1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAwO1xuICBtYXJnaW46IDA7XG4gIGxpc3Qtc3R5bGU6IG5vbmU7XG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG59XG5cbi5yenNsaWRlciAucnotdGlja3MtdmFsdWVzLXVuZGVyIC5yei10aWNrLXZhbHVlIHtcbiAgdG9wOiBhdXRvO1xuICBib3R0b206IC0zMnB4O1xufVxuXG4ucnpzbGlkZXIgLnJ6LXRpY2sge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogMDtcbiAgbGVmdDogMDtcbiAgd2lkdGg6IDEwcHg7XG4gIGhlaWdodDogMTBweDtcbiAgbWFyZ2luLWxlZnQ6IDExcHg7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgY3Vyc29yOiBwb2ludGVyO1xuICBiYWNrZ3JvdW5kOiAjZDhlMGYzO1xuICBib3JkZXItcmFkaXVzOiA1MCU7XG4gIHRyYW5zaXRpb246IGJhY2tncm91bmQtY29sb3IgbGluZWFyIDAuM3M7XG59XG5cbi5yenNsaWRlciAucnotdGljay5yei1zZWxlY3RlZCB7XG4gIGJhY2tncm91bmQ6ICMwZGI5ZjA7XG59XG5cbi5yenNsaWRlciAucnotdGljay12YWx1ZSB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgdG9wOiAtMzBweDtcbiAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgMCk7XG59XG5cbi5yenNsaWRlciAucnotdGljay1sZWdlbmQge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogMjRweDtcbiAgbWF4LXdpZHRoOiA1MHB4O1xuICB3aGl0ZS1zcGFjZTogbm9ybWFsO1xuICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSgtNTAlLCAwKTtcbn1cblxuLnJ6c2xpZGVyLnJ6LXZlcnRpY2FsIHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICB3aWR0aDogNHB4O1xuICBoZWlnaHQ6IDEwMCU7XG4gIHBhZGRpbmc6IDA7XG4gIG1hcmdpbjogMCAyMHB4O1xuICB2ZXJ0aWNhbC1hbGlnbjogYmFzZWxpbmU7XG59XG5cbi5yenNsaWRlci5yei12ZXJ0aWNhbCAucnotYmFzZSB7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDEwMCU7XG4gIHBhZGRpbmc6IDA7XG59XG5cbi5yenNsaWRlci5yei12ZXJ0aWNhbCAucnotYmFyLXdyYXBwZXIge1xuICB0b3A6IGF1dG87XG4gIGxlZnQ6IDA7XG4gIHdpZHRoOiAzMnB4O1xuICBoZWlnaHQ6IDEwMCU7XG4gIHBhZGRpbmc6IDAgMCAwIDE2cHg7XG4gIG1hcmdpbjogMCAwIDAgLTE2cHg7XG59XG5cbi5yenNsaWRlci5yei12ZXJ0aWNhbCAucnotYmFyIHtcbiAgYm90dG9tOiAwO1xuICBsZWZ0OiBhdXRvO1xuICB3aWR0aDogNHB4O1xuICBoZWlnaHQ6IDEwMCU7XG59XG5cbi5yenNsaWRlci5yei12ZXJ0aWNhbCAucnotcG9pbnRlciB7XG4gIHRvcDogYXV0bztcbiAgYm90dG9tOiAwO1xuICBsZWZ0OiAtMTRweCAhaW1wb3J0YW50O1xufVxuXG4ucnpzbGlkZXIucnotdmVydGljYWwgLnJ6LWJ1YmJsZSB7XG4gIGJvdHRvbTogMDtcbiAgbGVmdDogMTZweCAhaW1wb3J0YW50O1xuICBtYXJnaW4tbGVmdDogM3B4O1xufVxuXG4ucnpzbGlkZXIucnotdmVydGljYWwgLnJ6LXRpY2tzIHtcbiAgdG9wOiAwO1xuICBsZWZ0OiAtM3B4O1xuICB6LWluZGV4OiAxO1xuICB3aWR0aDogMDtcbiAgaGVpZ2h0OiAxMDAlO1xufVxuXG4ucnpzbGlkZXIucnotdmVydGljYWwgLnJ6LXRpY2sge1xuICBtYXJnaW4tdG9wOiAxMXB4O1xuICBtYXJnaW4tbGVmdDogYXV0bztcbiAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcbn1cblxuLnJ6c2xpZGVyLnJ6LXZlcnRpY2FsIC5yei10aWNrLXZhbHVlIHtcbiAgdG9wOiBhdXRvO1xuICBsZWZ0OiAyNHB4O1xuICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSgwLCAtMjglKTtcbn1cblxuLnJ6c2xpZGVyLnJ6LXZlcnRpY2FsIC5yei10aWNrLWxlZ2VuZCB7XG4gIHRvcDogYXV0bztcbiAgcmlnaHQ6IDI0cHg7XG4gIG1heC13aWR0aDogbm9uZTtcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoMCwgLTI4JSk7XG59XG5cbi5yenNsaWRlci5yei12ZXJ0aWNhbCAucnotdGlja3MtdmFsdWVzLXVuZGVyIC5yei10aWNrLXZhbHVlIHtcbiAgcmlnaHQ6IDI0cHg7XG4gIGJvdHRvbTogYXV0bztcbiAgbGVmdDogYXV0bztcbn0iXX0= */ \ No newline at end of file diff --git a/issue_template.md b/issue_template.md deleted file mode 100644 index b99c3b9..0000000 --- a/issue_template.md +++ /dev/null @@ -1,12 +0,0 @@ -### Steps to reproduce -1. -2. -3. - -Demo: http://jsfiddle.net/cwhgLcjv/ (fork this example and update the link) - -### Expected behaviour -Tell us what should happen - -### Actual behaviour -Tell us what happens instead diff --git a/karma.conf.js b/karma.conf.js index f89ca40..952482e 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -8,7 +8,11 @@ module.exports = function (config) { // testing framework to use (jasmine/mocha/qunit/...) frameworks: ['mocha', 'sinon', 'chai'], - reporters: ['dots', 'coverage'], + reporters: ['mocha', 'coverage'], + + mochaReporter: { + showDiff: true + }, // list of files / patterns to load in the browser files: [ diff --git a/package.json b/package.json index 5698535..104e3ba 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,9 @@ { "name": "angularjs-slider", - "version": "5.5.1", + "version": "7.1.0", "description": "AngularJS slider directive with no external dependencies. Mobile friendly!.", "main": "dist/rzslider.js", + "types": "dist/rzslider.d.ts", "repository": { "type": "git", "url": "https://github.com/angular-slider/angularjs-slider" @@ -11,11 +12,25 @@ "angular", "slider" ], + "publishConfig": { + "registry": "https://registry.npmjs.org/" + }, "scripts": { + "start": "http-server ./ -c-1", "commit": "git-cz", "build": "grunt", "test": "grunt test", - "report-coverage": "cat ./tests/coverage/lcov.info | codecov" + "report-coverage": "cat ./tests/coverage/lcov.info | codecov", + "format": "prettier --write \"{src,tests,demo}/{,!(lib)/**}/*.{js,less,css}\"", + "precommit": "npm run build && git add dist && lint-staged", + "e2e": "npm start & cypress run", + "cypress:open": "cypress open" + }, + "lint-staged": { + "{src,tests,demo}/{,!(lib)/**}/*.{js,less,css}": [ + "prettier --write", + "git add" + ] }, "peerDependencies": { "angular": "^1.2.x" @@ -23,38 +38,50 @@ "devDependencies": { "angular": "1.4.7", "angular-mocks": "1.4.8", - "chai": "^3.4.1", + "autoprefixer": "^6.5.3", + "chai": "^3.5.0", "codecov.io": "^0.1.6", "commitizen": "^2.4.6", + "cypress": "^0.20.3", "cz-conventional-changelog": "^1.1.5", "grunt": "~0.4.2", "grunt-angular-templates": "^0.5.7", + "grunt-cli": "^1.2.0", "grunt-contrib-concat": "^0.5.1", + "grunt-contrib-copy": "^1.0.0", "grunt-contrib-mincss": "~0.3.2", "grunt-contrib-uglify": "~0.2.2", "grunt-contrib-watch": "^0.6.1", "grunt-karma": "^0.12.1", "grunt-ng-annotate": "^1.0.1", + "grunt-postcss": "^0.8.0", "grunt-recess": "~0.4.0", "grunt-replace": "^0.11.0", "grunt-serve": "^0.1.6", - "karma": "^0.13.15", + "http-server": "^0.10.0", + "husky": "^0.14.3", + "karma": "^1.3.0", "karma-chai": "^0.1.0", "karma-chrome-launcher": "^0.2.2", "karma-coverage": "^0.5.3", "karma-mocha": "^0.2.1", + "karma-mocha-reporter": "^2.2.0", "karma-ng-html2js-preprocessor": "^0.2.0", - "karma-phantomjs-launcher": "^0.2.1", + "karma-phantomjs-launcher": "^1.0.2", "karma-sinon": "^1.0.4", - "mocha": "^2.3.4", + "lint-staged": "^4.0.3", + "mocha": "^3.1.2", "phantomjs": "^1.9.19", + "prettier": "^1.13.7", "recess": "~1.1.9", "sinon": "^1.17.2" }, - "author": "Rafal Zajac , Valentin Hervieu , Jussi Saarivirta , Angelin Sirbu ", + "author": "Rafal Zajac , Valentin Hervieu , Jussi Saarivirta , Angelin Sirbu ", "license": "MIT", "readmeFilename": "README.md", - "czConfig": { - "path": "node_modules/cz-conventional-changelog" + "config": { + "commitizen": { + "path": "node_modules/cz-conventional-changelog" + } } } diff --git a/rzslider.d.ts b/rzslider.d.ts new file mode 100644 index 0000000..e9ec697 --- /dev/null +++ b/rzslider.d.ts @@ -0,0 +1,217 @@ +/** + * Typescript type definition file. + */ + +import * as angular from "angular"; + +declare module "angular" { + export namespace RzSlider { + type RzLabelType = "model"|"high"|"floor"|"ceil"|"tick-value"; + type RzPointerType = "min"|"max"; + type RzCallback = (id: string, modelValue: number, highValue: number, pointerType: "min"|"max") => void; + type RzTranslate = (value: number, sliderId: string, label: RzLabelType) => string; + + /** RZ slider options typing */ + interface RzOptions { + /** Number (defaults to 0): Minimum value for a slider. */ + floor?: number; + /** Number (defaults to rz-slider-modelvalue): Maximum value for a slider. */ + ceil?: number; + /** Number (defaults to 1): Step between each value. */ + step?: number; + /** Number (defaults to 0): The precision to display values with. The toFixed() is used internally for this. */ + precision?: number; + /** Number (defaults to null): The minimum value authorized on the slider. */ + minLimit?: number; + /** Number (defaults to null): The maximum value authorized on the slider. */ + maxLimit?: number; + /** + * Object(defaults to null): Has two _Number_ properties, _from_ and _to_ that determine + * the bounds of an area that is not authorized for values. _Applies to range slider only._ + */ + restrictedRange?: { from: number, to: number } | Array<{from: number, to: number}>; + /** Number (defaults to null): The minimum range authorized on the slider. Applies to range slider only. Can also use an array.*/ + skipRestrictedRangesWithArrowKeys?: boolean + /** Set to true to skip restricted ranges with arrow keys. */ + minRange?: number; + /** Number (defaults to null): The maximum range authorized on the slider. Applies to range slider only. */ + maxRange?: number; + /** + * Boolean (defaults to false): Set to true to have a push behavior. When the min handle goes above the max, + * the max is moved as well (and vice-versa). The range between min and max is defined by the step option + * (defaults to 1) and can also be override by the minRange option. Applies to range slider only. + */ + pushRange?: boolean; + /** + * Custom translate function. Use this if you want to translate values displayed on the slider. + * sliderId can be used to determine the slider for which we are translating the value. + * label is a string that can take the following values: + * 'model': the model label + * 'high': the high label + * 'floor': the floor label + * 'ceil': the ceil label + * 'tick-value': the ticks labels + */ + translate?: RzTranslate; + /** + * Function(value, sliderId): Use to display legend under ticks. The function will be called with each tick + * value and returned content will be displayed under the tick as a legend. If the returned value is null, + * then no legend is displayed under the corresponding tick. + */ + getLegend?: (value: number, sliderId: string) => string; + /** + * Any (defaults to null): If you want to use the same translate function for several sliders, + * just set the id to anything you want, and it will be passed to the translate(value, sliderId) + * function as a second argument. + */ + id?: string; + /** + * Array: If you want to display a slider with non linear/number steps. Just pass an array with each slider + * value and that's it; the floor, ceil and step settings of the slider will be computed automatically. + * By default, the rz-slider-model and rz-slider-high values will be the value of the selected item in the stepsArray. + * They can also be bound to the index of the selected item by setting the bindIndexForStepsArray option to true. + * + * stepsArray can also be an array of objects like: + * [ + * {value: 'A'}, // the display value will be *A* + * {value: 10, legend: 'Legend for 10'} // the display value will be 10 and a legend will be displayed under the corresponding tick. + * ] + */ + stepsArray?: number[] | Array<{value: number; legend?: string}>; + /** + * Boolean (defaults to false): Set to true to bind the index of the selected item to rz-slider-model and rz-slider-high. + * (This was the default behavior prior to 4.0). + */ + bindIndexForStepsArray?: boolean; + /** Boolean (defaults to false): When set to true and using a range slider, the range can be dragged by the selection bar. Applies to range slider only. */ + draggableRange?: boolean; + /** Boolean (defaults to false): Same as draggableRange but the slider range can't be changed. Applies to range slider only. */ + draggableRangeOnly?: boolean; + /** Boolean (defaults to false): Set to true to always show the selection bar before the slider handle. */ + showSelectionBar?: boolean; + /** Boolean (defaults to false): Set to true to always show the selection bar after the slider handle. */ + showSelectionBarEnd?: boolean; + /** Boolean (defaults to false): Only for range slider. Set to true to visualize in different colour the areas on the left/right (top/bottom for vertical range slider) of selection bar between the handles. */ + showOuterSelectionBars?: boolean; + /** Number (defaults to null): Set a number to draw the selection bar between this value and the slider handle. */ + showSelectionBarFromValue?: number; + /** + * Function(value) or Function(minVal, maxVal) (defaults to null): Function that returns the current color of the + * selection bar. If your color won't changed, don't use this option but set it through CSS. If the returned color + * depends on a model value (either rzScopeModelor 'rzSliderHigh), you should use the argument passed to the function. + * Indeed, when the function is called, there is no certainty that the model has already been updated. + */ + getSelectionBarColor?: (minVal: number, maxVal?: number) => string; + /** Function(value) (defaults to null): Function that returns the color of a tick. showTicks must be enabled. */ + getTickColor?: (value: number) => string; + /** + * Function(value, pointerType) (defaults to null): Function that returns the current color of a pointer. + * If your color won't changed, don't use this option but set it through CSS. If the returned color depends + * on a model value (either rzScopeModelor 'rzSliderHigh), you should use the argument passed to the function. + * Indeed, when the function is called, there is no certainty that the model has already been updated. + * To handle range slider pointers independently, you should evaluate pointerType within the given function + * where "min" stands for rzScopeModel and "max" for rzScopeHigh values. + */ + getPointerColor?: (value: number, pointerType: RzPointerType) => string; + /** Boolean (defaults to false): Set to true to hide pointer labels */ + hidePointerLabels?: boolean; + /** Boolean (defaults to false): Set to true to hide min / max labels */ + hideLimitLabels?: boolean; + /** Boolean (defaults to true): Set to false to disable the auto- hiding behavior of the limit labels. */ + autoHideLimitLabels?: boolean; + /** Boolean (defaults to false): Set to true to make the slider read-only. */ + readOnly?: boolean; + /** Boolean (defaults to false): Set to true to disable the slider. */ + disabled?: boolean; + /** + * Number in ms (defaults to 350): Internally, a throttle function (See http://underscorejs.org/#throttle) is used + * when the model or high values of the slider are changed from outside the slider. This is to prevent from re-rendering + * the slider too many times in a row. interval is the number of milliseconds to wait between two updates of the slider. + */ + interval?: number; + /** Boolean or Number (defaults to false): Set to true to display a tick for each step of the slider. Set an integer to display ticks at intermediate positions. */ + showTicks?: boolean | number; + /** Boolean or Number (defaults to false): Set to true to display a tick and the step value for each step of the slider. Set an integer to display ticks and the step value at intermediate positions. */ + showTicksValues?: boolean | number; + /** Array (defaults to null): Use to display ticks at specific positions. The array contains the index of the ticks that should be displayed. For example, [0, 1, 5] will display a tick for the first, second and sixth values. It also supports the { value: 0, legend: 'Bad' } format to display a legend for each tick. */ + ticksArray?: number[] | Array<{value: number; legend?: string}>; + /** Function(value) (defaults to null): (requires angular-ui bootstrap) Used to display a tooltip when a tick is hovered. Set to a function that returns the tooltip content for a given value. */ + ticksTooltip?: (value: number) => string; + /** Function(value) (defaults to null): Same as ticksTooltip but for ticks values. */ + ticksValuesTooltip?: (value: number) => string; + /** Number (defaults to 1): If you display the slider in an element that uses transform: scale(0.5), set the scale value to 2 so that the slider is rendered properly and the events are handled correctly. */ + scale?: number; + /** Boolean (defaults to true): Set to true to force the value to be rounded to the step, even when modified from the outside.. When set to false, if the model values are modified from outside the slider, they are not rounded and can be between two steps. */ + enforceStep?: boolean; + /** Boolean (defaults to false): Set to true to round the rzSliderModel and rzSliderHigh to the slider range even when modified from outside the slider. When set to false, if the model values are modified from outside the slider, they are not rounded but they are still rendered properly on the slider. */ + enforceRange?: boolean; + /** Boolean (defaults to false): Set to true to prevent to user from switching the min and max handles. Applies to range slider only. */ + noSwitching?: boolean; + /** Boolean (defaults to false): Set to true to only bind events on slider handles. */ + onlyBindHandles?: boolean; + /** Boolean (defaults to true): Set to true to keep the slider labels inside the slider bounds. */ + boundPointerLabels?: boolean; + /** Boolean (defaults to false): Set to true to merge the range labels if they are the same. For instance, if min and max are 50, the label will be "50 - 50" if mergeRangeLabelsIfSame: false, else "50". */ + mergeRangeLabelsIfSame?: boolean; + /** String (defaults to ' - '): Separator to use when the labels overlap. For instance, if min and max are -1 and 1, the label will be "-1 .. 1" if `labelOverlapSeparator: ' .. '`. */ + labelOverlapSeparator?: string; + /** Function(sliderId, modelValue, highValue, pointerType): Function to be called when a slider update is started. If an id was set in the options, then it's passed to this callback. This callback is called before any update on the model. pointerType is either 'min' or 'max' depending on which handle is used. */ + onStart?: RzCallback; + /** + * Function to be called when rz-slider-model or rz-slider-high change. If an id was set in the options, + * then it's passed to this callback. pointerType is either 'min' or 'max' depending + * on which handle is used. + */ + onChange?: RzCallback; + /** Function(sliderId, modelValue, highValue, pointerType): Function to be called when a slider update is ended. If an id was set in the options, then it's passed to this callback. pointerType is either 'min' or 'max' depending on which handle is used. */ + onEnd?: RzCallback; + /** Boolean (defaults to false): Set to true to show graphs right to left. If vertical is true it will be from top to bottom and left / right arrow functions reversed. */ + rightToLeft?: boolean; + /** + * Boolean (defaults to false): Set to true to display the slider vertically. The slider will take the full height of its parent. + * Changing this value at runtime is not currently supported. + */ + vertical?: boolean; + /** + * Boolean (defaults to true): Handles are focusable (on click or with tab) and can be modified using the following keyboard controls: + * - Left/bottom arrows: -1 + * - Right/top arrows: +1 + * - Page-down: -10% + * - Page-up: +10% + * - Home: minimum value + * - End: maximum value + */ + keyboardSupport?: boolean; + /** + * Boolean (defaults to false): Set to true to reverse keyboard navigation: + * - Right/top arrows: -1 + * - Left/bottom arrows: +1 + * - Page-up: -10% + * - Page-down: +10% + * - End: minimum value + * - Home: maximum value + */ + reversedControls?: boolean; + /** Object (default to null): The properties defined in this object will be exposed in the slider template under custom.X. */ + customTemplateScope?: any; + /** Boolean (defaults to false): Set to true to use a logarithmic scale to display the slider. */ + logScale?: boolean; + /** Function(val, minVal, maxVal): percent: Function that returns the position on the slider for a given value.The position must be a percentage between 0 and 1. */ + customValueToPosition?: (val: number, minVal: number, maxVal: number) => number; + /** Function(percent, minVal, maxVal): value: Function that returns the value for a given position on the slider. The position is a percentage between 0 and 1. */ + customPositionToValue?: (percent: number, minVal: number, maxVal: number) => number; + /** Object(default to null): Use to display the selection bar as a gradient. The given object must contain from and to properties which are colors. */ + selectionBarGradient?: {from: string, to: string}; + /** String(default to null): Use to add a label directly to the slider(s) for accessibility. Adds the aria-label attribute. */ + ariaLabel?: string; + /** String(default to null): Use to add a label directly to the slider(s) for accessibility. Adds the aria-label attribute. */ + ariaLabelHigh?: string; + /** String(default to null): Use instead of ariaLabel and ariaLabelHigh to reference the id of an element which will be used to label the slider(s). Adds the aria-labelledby attribute. */ + ariaLabelledBy?: string; + /** String(default to null): Use instead of ariaLabel and ariaLabelHigh to reference the id of an element which will be used to label the slider(s). Adds the aria-labelledby attribute. */ + ariaLabelledByHigh?: string; + /** Boolean (defaults to false): Set to true to disable slider animation. */ + disableAnimation?: boolean; + } + } +} diff --git a/src/rzSliderTpl.html b/src/rzSliderTpl.html index b522de0..2431f3e 100644 --- a/src/rzSliderTpl.html +++ b/src/rzSliderTpl.html @@ -1,24 +1,44 @@
- - - - - - - - - - - -
    -
  • - {{ t.value }} - {{ t.legend }} -
  • -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
  • + {{ t.value }} + {{ t.legend }} +
  • +
diff --git a/src/rzslider.js b/src/rzslider.js index 6c2754f..8b10560 100644 --- a/src/rzslider.js +++ b/src/rzslider.js @@ -8,2172 +8,2842 @@ */ /*jslint unparam: true */ /*global angular: false, console: false, define, module */ -(function(root, factory) { - 'use strict'; +;(function(root, factory) { + 'use strict' /* istanbul ignore next */ if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. - define(['angular'], factory); + define(['angular'], factory) } else if (typeof module === 'object' && module.exports) { // Node. Does not work with strict CommonJS, but // only CommonJS-like environments that support module.exports, // like Node. // to support bundler like browserify - module.exports = factory(require('angular')); + var angularObj = angular || require('angular') + if ((!angularObj || !angularObj.module) && typeof angular != 'undefined') { + angularObj = angular + } + module.exports = factory(angularObj) } else { // Browser globals (root is window) - factory(root.angular); + factory(root.angular) } +})(this, function(angular) { + 'use strict' + var module = angular + .module('rzSlider', []) + .factory('RzSliderOptions', function() { + var defaultOptions = { + floor: 0, + ceil: null, //defaults to rz-slider-model + step: 1, + precision: 0, + minRange: null, + maxRange: null, + restrictedRange: null, + skipRestrictedRangesWithArrowKeys: null, + pushRange: false, + minLimit: null, + maxLimit: null, + id: null, + translate: null, + getLegend: null, + stepsArray: null, + bindIndexForStepsArray: false, + draggableRange: false, + draggableRangeOnly: false, + showSelectionBar: false, + showSelectionBarEnd: false, + showSelectionBarFromValue: null, + showOuterSelectionBars: false, + hidePointerLabels: false, + hideLimitLabels: false, + autoHideLimitLabels: true, + readOnly: false, + disabled: false, + interval: 350, + showTicks: false, + showTicksValues: false, + ticksArray: null, + ticksTooltip: null, + ticksValuesTooltip: null, + vertical: false, + getSelectionBarColor: null, + getTickColor: null, + getPointerColor: null, + keyboardSupport: true, + scale: 1, + enforceStep: true, + enforceRange: false, + noSwitching: false, + onlyBindHandles: false, + disableAnimation: false, + onStart: null, + onChange: null, + onEnd: null, + rightToLeft: false, + reversedControls: false, + boundPointerLabels: true, + mergeRangeLabelsIfSame: false, + labelOverlapSeparator: ' - ', + customTemplateScope: null, + logScale: false, + customValueToPosition: null, + customPositionToValue: null, + selectionBarGradient: null, + ariaLabel: null, + ariaLabelledBy: null, + ariaLabelHigh: null, + ariaLabelledByHigh: null, + } + var globalOptions = {} -}(this, function(angular) { - 'use strict'; - var module = angular.module('rzModule', []) - - .factory('RzSliderOptions', function() { - var defaultOptions = { - floor: 0, - ceil: null, //defaults to rz-slider-model - step: 1, - precision: 0, - minRange: null, - maxRange: null, - pushRange: false, - minLimit: null, - maxLimit: null, - id: null, - translate: null, - getLegend: null, - stepsArray: null, - bindIndexForStepsArray: false, - draggableRange: false, - draggableRangeOnly: false, - showSelectionBar: false, - showSelectionBarEnd: false, - showSelectionBarFromValue: null, - hidePointerLabels: false, - hideLimitLabels: false, - autoHideLimitLabels: true, - readOnly: false, - disabled: false, - interval: 350, - showTicks: false, - showTicksValues: false, - ticksTooltip: null, - ticksValuesTooltip: null, - vertical: false, - getSelectionBarColor: null, - getTickColor: null, - getPointerColor: null, - keyboardSupport: true, - scale: 1, - enforceStep: true, - enforceRange: false, - noSwitching: false, - onlyBindHandles: false, - onStart: null, - onChange: null, - onEnd: null, - rightToLeft: false, - boundPointerLabels: true, - mergeRangeLabelsIfSame: false, - customTemplateScope: null - }; - var globalOptions = {}; - - var factory = {}; - /** - * `options({})` allows global configuration of all sliders in the - * application. - * - * var app = angular.module( 'App', ['rzModule'], function( RzSliderOptions ) { - * // show ticks for all sliders - * RzSliderOptions.options( { showTicks: true } ); - * }); - */ - factory.options = function(value) { - angular.extend(globalOptions, value); - }; - - factory.getOptions = function(options) { - return angular.extend({}, defaultOptions, globalOptions, options); - }; - - return factory; - }) - - .factory('rzThrottle', function($timeout) { - /** - * rzThrottle - * - * Taken from underscore project - * - * @param {Function} func - * @param {number} wait - * @param {ThrottleOptions} options - * @returns {Function} - */ - return function(func, wait, options) { - 'use strict'; - /* istanbul ignore next */ - var getTime = (Date.now || function() { - return new Date().getTime(); - }); - var context, args, result; - var timeout = null; - var previous = 0; - options = options || {}; - var later = function() { - previous = getTime(); - timeout = null; - result = func.apply(context, args); - context = args = null; - }; - return function() { - var now = getTime(); - var remaining = wait - (now - previous); - context = this; - args = arguments; - if (remaining <= 0) { - $timeout.cancel(timeout); - timeout = null; - previous = now; - result = func.apply(context, args); - context = args = null; - } else if (!timeout && options.trailing !== false) { - timeout = $timeout(later, remaining); - } - return result; - }; - } - }) - - .factory('RzSlider', function($timeout, $document, $window, $compile, RzSliderOptions, rzThrottle) { - 'use strict'; - - /** - * Slider - * - * @param {ngScope} scope The AngularJS scope - * @param {Element} sliderElem The slider directive element wrapped in jqLite - * @constructor - */ - var Slider = function(scope, sliderElem) { + var factory = {} /** - * The slider's scope + * `options({})` allows global configuration of all sliders in the + * application. * - * @type {ngScope} - */ - this.scope = scope; - - /** - * The slider inner low value (linked to rzSliderModel) - * @type {number} - */ - this.lowValue = 0; - - /** - * The slider inner high value (linked to rzSliderHigh) - * @type {number} + * var app = angular.module( 'App', ['rzSlider'], function( RzSliderOptions ) { + * // show ticks for all sliders + * RzSliderOptions.options( { showTicks: true } ); + * }); */ - this.highValue = 0; + factory.options = function(value) { + angular.extend(globalOptions, value) + } - /** - * Slider element wrapped in jqLite - * - * @type {jqLite} - */ - this.sliderElem = sliderElem; + factory.getOptions = function(options) { + return angular.extend({}, defaultOptions, globalOptions, options) + } + return factory + }) + .factory('rzThrottle', function($timeout) { /** - * Slider type + * rzThrottle * - * @type {boolean} Set to true for range slider - */ - this.range = this.scope.rzSliderModel !== undefined && this.scope.rzSliderHigh !== undefined; - - /** - * Values recorded when first dragging the bar + * Taken from underscore project * - * @type {Object} - */ - this.dragging = { - active: false, - value: 0, - difference: 0, - offset: 0, - lowLimit: 0, - highLimit: 0 - }; - - /** - * property that handle position (defaults to left for horizontal) - * @type {string} + * @param {Function} func + * @param {number} wait + * @param {ThrottleOptions} options + * @returns {Function} */ - this.positionProperty = 'left'; + return function(func, wait, options) { + 'use strict' + /* istanbul ignore next */ + var getTime = + Date.now || + function() { + return new Date().getTime() + } + var context, args, result + var timeout = null + var previous = 0 + options = options || {} + var later = function() { + previous = getTime() + timeout = null + result = func.apply(context, args) + context = args = null + } + return function() { + var now = getTime() + var remaining = wait - (now - previous) + context = this + args = arguments + if (remaining <= 0) { + $timeout.cancel(timeout) + timeout = null + previous = now + result = func.apply(context, args) + context = args = null + } else if (!timeout && options.trailing !== false) { + timeout = $timeout(later, remaining) + } + return result + } + } + }) + .factory('RzSlider', function( + $timeout, + $document, + $window, + $compile, + RzSliderOptions, + rzThrottle + ) { + 'use strict' + + /** + * Slider + * + * @param {ngScope} scope The AngularJS scope + * @param {Element} sliderElem The slider directive element wrapped in jqLite + * @constructor + */ + var Slider = function(scope, sliderElem) { + /** + * The slider's scope + * + * @type {ngScope} + */ + this.scope = scope - /** - * property that handle dimension (defaults to width for horizontal) - * @type {string} - */ - this.dimensionProperty = 'width'; + /** + * The slider inner low value (linked to rzSliderModel) + * @type {number} + */ + this.lowValue = 0 - /** - * Half of the width or height of the slider handles - * - * @type {number} - */ - this.handleHalfDim = 0; + /** + * The slider inner high value (linked to rzSliderHigh) + * @type {number} + */ + this.highValue = 0 - /** - * Maximum position the slider handle can have - * - * @type {number} - */ - this.maxPos = 0; + /** + * Slider element wrapped in jqLite + * + * @type {jqLite} + */ + this.sliderElem = sliderElem - /** - * Precision - * - * @type {number} - */ - this.precision = 0; + /** + * Slider type + * + * @type {boolean} Set to true for range slider + */ + this.range = + this.scope.rzSliderModel !== undefined && + this.scope.rzSliderHigh !== undefined + + /** + * Values recorded when first dragging the bar + * + * @type {Object} + */ + this.dragging = { + active: false, + value: 0, + difference: 0, + position: 0, + lowLimit: 0, + highLimit: 0, + } - /** - * Step - * - * @type {number} - */ - this.step = 1; + /** + * property that handle position (defaults to left for horizontal) + * @type {string} + */ + this.positionProperty = 'left' - /** - * The name of the handle we are currently tracking - * - * @type {string} - */ - this.tracking = ''; + /** + * property that handle dimension (defaults to width for horizontal) + * @type {string} + */ + this.dimensionProperty = 'width' - /** - * Minimum value (floor) of the model - * - * @type {number} - */ - this.minValue = 0; + /** + * Half of the width or height of the slider handles + * + * @type {number} + */ + this.handleHalfDim = 0 - /** - * Maximum value (ceiling) of the model - * - * @type {number} - */ - this.maxValue = 0; + /** + * Maximum position the slider handle can have + * + * @type {number} + */ + this.maxPos = 0 + /** + * Precision + * + * @type {number} + */ + this.precision = 0 - /** - * The delta between min and max value - * - * @type {number} - */ - this.valueRange = 0; + /** + * Step + * + * @type {number} + */ + this.step = 1 + /** + * The name of the handle we are currently tracking + * + * @type {string} + */ + this.tracking = '' - /** - * If showTicks/showTicksValues options are number. - * In this case, ticks values should be displayed below the slider. - * @type {boolean} - */ - this.intermediateTicks = false; + /** + * Minimum value (floor) of the model + * + * @type {number} + */ + this.minValue = 0 - /** - * Set to true if init method already executed - * - * @type {boolean} - */ - this.initHasRun = false; + /** + * Maximum value (ceiling) of the model + * + * @type {number} + */ + this.maxValue = 0 - /** - * Used to call onStart on the first keydown event - * - * @type {boolean} - */ - this.firstKeyDown = false; + /** + * The delta between min and max value + * + * @type {number} + */ + this.valueRange = 0 - /** - * Internal flag to prevent watchers to be called when the sliders value are modified internally. - * @type {boolean} - */ - this.internalChange = false; + /** + * If showTicks/showTicksValues options are number. + * In this case, ticks values should be displayed below the slider. + * @type {boolean} + */ + this.intermediateTicks = false - /** - * Internal flag to keep track of the visibility of combo label - * @type {boolean} - */ - this.cmbLabelShown = false; + /** + * Set to true if init method already executed + * + * @type {boolean} + */ + this.initHasRun = false - /** - * Internal variable to keep track of the focus element - */ - this.currentFocusElement = null; - - // Slider DOM elements wrapped in jqLite - this.fullBar = null; // The whole slider bar - this.selBar = null; // Highlight between two handles - this.minH = null; // Left slider handle - this.maxH = null; // Right slider handle - this.flrLab = null; // Floor label - this.ceilLab = null; // Ceiling label - this.minLab = null; // Label above the low value - this.maxLab = null; // Label above the high value - this.cmbLab = null; // Combined label - this.ticks = null; // The ticks - - // Initialize slider - this.init(); - }; - - // Add instance methods - Slider.prototype = { + /** + * Used to call onStart on the first keydown event + * + * @type {boolean} + */ + this.firstKeyDown = false - /** - * Initialize slider - * - * @returns {undefined} - */ - init: function() { - var thrLow, thrHigh, - self = this; - - var calcDimFn = function() { - self.calcViewDimensions(); - }; - - this.applyOptions(); - this.syncLowValue(); - if (this.range) - this.syncHighValue(); - this.initElemHandles(); - this.manageElementsStyle(); - this.setDisabledState(); - this.calcViewDimensions(); - this.setMinAndMax(); - this.addAccessibility(); - this.updateCeilLab(); - this.updateFloorLab(); - this.initHandles(); - this.manageEventsBindings(); - - // Recalculate slider view dimensions - this.scope.$on('reCalcViewDimensions', calcDimFn); - - // Recalculate stuff if view port dimensions have changed - angular.element($window).on('resize', calcDimFn); - - this.initHasRun = true; - - // Watch for changes to the model - thrLow = rzThrottle(function() { - self.onLowHandleChange(); - }, self.options.interval); - - thrHigh = rzThrottle(function() { - self.onHighHandleChange(); - }, self.options.interval); - - this.scope.$on('rzSliderForceRender', function() { - self.resetLabelsValue(); - thrLow(); - if (self.range) { - thrHigh(); - } - self.resetSlider(); - }); - - // Watchers (order is important because in case of simultaneous change, - // watchers will be called in the same order) - this.scope.$watch('rzSliderOptions()', function(newValue, oldValue) { - if (newValue === oldValue) - return; - self.applyOptions(); // need to be called before synchronizing the values - self.syncLowValue(); - if (self.range) - self.syncHighValue(); - self.resetSlider(); - }, true); - - this.scope.$watch('rzSliderModel', function(newValue, oldValue) { - if (self.internalChange) - return; - if (newValue === oldValue) - return; - thrLow(); - }); - - this.scope.$watch('rzSliderHigh', function(newValue, oldValue) { - if (self.internalChange) - return; - if (newValue === oldValue) - return; - if (newValue != null) - thrHigh(); - if (self.range && newValue == null || !self.range && newValue != null) { - self.applyOptions(); - self.resetSlider(); - } - }); - - this.scope.$on('$destroy', function() { - self.unbindEvents(); - angular.element($window).off('resize', calcDimFn); - self.currentFocusElement = null; - }); - }, - - findStepIndex: function(modelValue) { - var index = 0; - for (var i = 0; i < this.options.stepsArray.length; i++) { - var step = this.options.stepsArray[i]; - if (step === modelValue) { - index = i; - break; - } - else if (angular.isObject(step) && step.value === modelValue) { - index = i; - break; - } - } - return index; - }, + /** + * Internal flag to prevent watchers to be called when the sliders value are modified internally. + * @type {boolean} + */ + this.internalChange = false - syncLowValue: function() { - if (this.options.stepsArray) { - if (!this.options.bindIndexForStepsArray) - this.lowValue = this.findStepIndex(this.scope.rzSliderModel); - else - this.lowValue = this.scope.rzSliderModel - } - else - this.lowValue = this.scope.rzSliderModel; - }, - - syncHighValue: function() { - if (this.options.stepsArray) { - if (!this.options.bindIndexForStepsArray) - this.highValue = this.findStepIndex(this.scope.rzSliderHigh); - else - this.highValue = this.scope.rzSliderHigh - } - else - this.highValue = this.scope.rzSliderHigh; - }, - - getStepValue: function(sliderValue) { - var step = this.options.stepsArray[sliderValue]; - if (angular.isObject(step)) - return step.value; - return step; - }, - - applyLowValue: function() { - if (this.options.stepsArray) { - if (!this.options.bindIndexForStepsArray) - this.scope.rzSliderModel = this.getStepValue(this.lowValue); - else - this.scope.rzSliderModel = this.lowValue - } - else - this.scope.rzSliderModel = this.lowValue; - }, - - applyHighValue: function() { - if (this.options.stepsArray) { - if (!this.options.bindIndexForStepsArray) - this.scope.rzSliderHigh = this.getStepValue(this.highValue); - else - this.scope.rzSliderHigh = this.highValue - } - else - this.scope.rzSliderHigh = this.highValue; - }, + /** + * Internal flag to keep track of the visibility of combo label + * @type {boolean} + */ + this.cmbLabelShown = false - /* - * Reflow the slider when the low handle changes (called with throttle) - */ - onLowHandleChange: function() { - this.syncLowValue(); - if (this.range) - this.syncHighValue(); - this.setMinAndMax(); - this.updateLowHandle(this.valueToOffset(this.lowValue)); - this.updateSelectionBar(); - this.updateTicksScale(); - this.updateAriaAttributes(); - if (this.range) { - this.updateCmbLabel(); - } - }, + /** + * Internal variable to keep track of the focus element + */ + this.currentFocusElement = null - /* - * Reflow the slider when the high handle changes (called with throttle) - */ - onHighHandleChange: function() { - this.syncLowValue(); - this.syncHighValue(); - this.setMinAndMax(); - this.updateHighHandle(this.valueToOffset(this.highValue)); - this.updateSelectionBar(); - this.updateTicksScale(); - this.updateCmbLabel(); - this.updateAriaAttributes(); - }, + /** + * Internal variable to know if we are already moving + */ + this.moving = false + + // Slider DOM elements wrapped in jqLite + this.fullBar = null // The whole slider bar + this.selBar = null // Highlight between two handles + this.minH = null // Left slider handle + this.maxH = null // Right slider handle + this.flrLab = null // Floor label + this.ceilLab = null // Ceiling label + this.minLab = null // Label above the low value + this.maxLab = null // Label above the high value + this.cmbLab = null // Combined label + this.ticks = null // The ticks + + // Initialize slider + this.init() + } - /** - * Read the user options and apply them to the slider model - */ - applyOptions: function() { - var sliderOptions; - if (this.scope.rzSliderOptions) - sliderOptions = this.scope.rzSliderOptions(); - else - sliderOptions = {}; - - this.options = RzSliderOptions.getOptions(sliderOptions); - - if (this.options.step <= 0) - this.options.step = 1; - - this.range = this.scope.rzSliderModel !== undefined && this.scope.rzSliderHigh !== undefined; - this.options.draggableRange = this.range && this.options.draggableRange; - this.options.draggableRangeOnly = this.range && this.options.draggableRangeOnly; - if (this.options.draggableRangeOnly) { - this.options.draggableRange = true; - } + // Add instance methods + Slider.prototype = { + /** + * Initialize slider + * + * @returns {undefined} + */ + init: function() { + var thrLow, + thrHigh, + self = this - this.options.showTicks = this.options.showTicks || this.options.showTicksValues; - this.scope.showTicks = this.options.showTicks; //scope is used in the template - if (angular.isNumber(this.options.showTicks)) - this.intermediateTicks = true; + var calcDimFn = function() { + self.calcViewDimensions() + } - this.options.showSelectionBar = this.options.showSelectionBar || this.options.showSelectionBarEnd - || this.options.showSelectionBarFromValue !== null; + this.applyOptions() + this.syncLowValue() + if (this.range) this.syncHighValue() + this.initElemHandles() + this.manageElementsStyle() + this.setDisabledState() + this.calcViewDimensions() + this.setMinAndMax() + this.updateRestrictionBar() + this.addAccessibility() + this.updateCeilLab() + this.updateFloorLab() + this.initHandles() + this.manageEventsBindings() + + // Recalculate slider view dimensions + this.scope.$on('reCalcViewDimensions', calcDimFn) + + // Recalculate stuff if view port dimensions have changed + angular.element($window).on('resize', calcDimFn) + + this.initHasRun = true + + if (this.options.disableAnimation) { + this.sliderElem.addClass('noanimate') + } - if (this.options.stepsArray) { - this.parseStepsArray(); - } else { - if (this.options.translate) - this.customTrFn = this.options.translate; - else - this.customTrFn = function(value) { - return String(value); - }; + // Watch for changes to the model + thrLow = rzThrottle(function() { + self.onLowHandleChange() + }, self.options.interval) - this.getLegend = this.options.getLegend; - } + thrHigh = rzThrottle(function() { + self.onHighHandleChange() + }, self.options.interval) - if (this.options.vertical) { - this.positionProperty = 'bottom'; - this.dimensionProperty = 'height'; - } + this.scope.$on('rzSliderForceRender', function() { + self.resetLabelsValue() + thrLow() + if (self.range) { + thrHigh() + } + self.resetSlider() + }) + + // Watchers (order is important because in case of simultaneous change, + // watchers will be called in the same order) + this.scope.$watchCollection('rzSliderOptions()', function( + newValue, + oldValue + ) { + if (newValue === oldValue) return + self.applyOptions() // need to be called before synchronizing the values + self.syncLowValue() + if (self.range) self.syncHighValue() + self.resetSlider() + }) + + this.scope.$watch('rzSliderModel', function(newValue, oldValue) { + if (self.internalChange) return + if (newValue === oldValue) return + thrLow() + }) + + this.scope.$watch('rzSliderHigh', function(newValue, oldValue) { + if (self.internalChange) return + if (newValue === oldValue) return + if (newValue != null) thrHigh() + if ( + (self.range && newValue == null) || + (!self.range && newValue != null) + ) { + self.applyOptions() + self.resetSlider() + } + }) + + this.scope.$on('$destroy', function() { + self.unbindEvents() + angular.element($window).off('resize', calcDimFn) + self.currentFocusElement = null + }) + }, + + findStepIndex: function(modelValue) { + var index = 0 + for (var i = 0; i < this.options.stepsArray.length; i++) { + var step = this.options.stepsArray[i] + if (step === modelValue) { + index = i + break + } else if (angular.isDate(step)) { + if (step.getTime() === modelValue.getTime()) { + index = i + break + } + } else if (angular.isObject(step)) { + if ( + (angular.isDate(step.value) && + step.value.getTime() === modelValue.getTime()) || + step.value === modelValue + ) { + index = i + break + } + } + } + return index + }, + + syncLowValue: function() { + if (this.options.stepsArray) { + if (!this.options.bindIndexForStepsArray) + this.lowValue = this.findStepIndex(this.scope.rzSliderModel) + else this.lowValue = this.scope.rzSliderModel + } else this.lowValue = this.scope.rzSliderModel + }, + + syncHighValue: function() { + if (this.options.stepsArray) { + if (!this.options.bindIndexForStepsArray) + this.highValue = this.findStepIndex(this.scope.rzSliderHigh) + else this.highValue = this.scope.rzSliderHigh + } else this.highValue = this.scope.rzSliderHigh + }, + + getStepValue: function(sliderValue) { + var step = this.options.stepsArray[sliderValue] + if (angular.isDate(step)) return step + if (angular.isObject(step)) return step.value + return step + }, + + applyLowValue: function() { + if (this.options.stepsArray) { + if (!this.options.bindIndexForStepsArray) + this.scope.rzSliderModel = this.getStepValue(this.lowValue) + else this.scope.rzSliderModel = this.lowValue + } else this.scope.rzSliderModel = this.lowValue + }, + + applyHighValue: function() { + if (this.options.stepsArray) { + if (!this.options.bindIndexForStepsArray) + this.scope.rzSliderHigh = this.getStepValue(this.highValue) + else this.scope.rzSliderHigh = this.highValue + } else this.scope.rzSliderHigh = this.highValue + }, - if (this.options.customTemplateScope) - this.scope.custom = this.options.customTemplateScope; - }, + /* + * Reflow the slider when the low handle changes (called with throttle) + */ + onLowHandleChange: function() { + this.syncLowValue() + if (this.range) this.syncHighValue() + this.setMinAndMax() + this.updateLowHandle(this.valueToPosition(this.lowValue)) + this.updateSelectionBar() + this.updateTicksScale() + this.updateAriaAttributes() + if (this.range) { + this.updateCmbLabel() + } + }, - parseStepsArray: function() { - this.options.floor = 0; - this.options.ceil = this.options.stepsArray.length - 1; - this.options.step = 1; + /* + * Reflow the slider when the high handle changes (called with throttle) + */ + onHighHandleChange: function() { + this.syncLowValue() + this.syncHighValue() + this.setMinAndMax() + this.updateHighHandle(this.valueToPosition(this.highValue)) + this.updateSelectionBar() + this.updateTicksScale() + this.updateCmbLabel() + this.updateAriaAttributes() + }, + + /** + * Read the user options and apply them to the slider model + */ + applyOptions: function() { + var sliderOptions + if (this.scope.rzSliderOptions) + sliderOptions = this.scope.rzSliderOptions() + else sliderOptions = {} + + this.options = RzSliderOptions.getOptions(sliderOptions) + + if (this.options.step <= 0) this.options.step = 1 + + this.range = + this.scope.rzSliderModel !== undefined && + this.scope.rzSliderHigh !== undefined + this.options.draggableRange = + this.range && this.options.draggableRange + this.options.draggableRangeOnly = + this.range && this.options.draggableRangeOnly + if (this.options.draggableRangeOnly) { + this.options.draggableRange = true + } - if (this.options.translate) { - this.customTrFn = this.options.translate; - } - else { - this.customTrFn = function(modelValue) { - if (this.options.bindIndexForStepsArray) - return this.getStepValue(modelValue); - return modelValue; - }; - } + this.options.showTicks = + this.options.showTicks || + this.options.showTicksValues || + !!this.options.ticksArray + this.scope.showTicks = this.options.showTicks //scope is used in the template + if ( + angular.isNumber(this.options.showTicks) || + this.options.ticksArray + ) + this.intermediateTicks = true + + this.options.showSelectionBar = + this.options.showSelectionBar || + this.options.showSelectionBarEnd || + this.options.showSelectionBarFromValue !== null + + if (this.options.stepsArray) { + this.parseStepsArray() + } else { + if (this.options.translate) this.customTrFn = this.options.translate + else + this.customTrFn = function(value) { + return String(value) + } - this.getLegend = function(index) { - var step = this.options.stepsArray[index]; - if (angular.isObject(step)) - return step.legend; - return null; - }; - }, + this.getLegend = this.options.getLegend + } - /** - * Resets slider - * - * @returns {undefined} - */ - resetSlider: function() { - this.manageElementsStyle(); - this.addAccessibility(); - this.setMinAndMax(); - this.updateCeilLab(); - this.updateFloorLab(); - this.unbindEvents(); - this.manageEventsBindings(); - this.setDisabledState(); - this.calcViewDimensions(); - this.refocusPointerIfNeeded(); - }, - - refocusPointerIfNeeded: function() { - if (this.currentFocusElement) { - this.onPointerFocus(this.currentFocusElement.pointer, this.currentFocusElement.ref); - this.focusElement(this.currentFocusElement.pointer) - } - }, + if (this.options.vertical) { + this.positionProperty = 'bottom' + this.dimensionProperty = 'height' + } else { + this.positionProperty = 'left' + this.dimensionProperty = 'width' + } - /** - * Set the slider children to variables for easy access - * - * Run only once during initialization - * - * @returns {undefined} - */ - initElemHandles: function() { - // Assign all slider elements to object properties for easy access - angular.forEach(this.sliderElem.children(), function(elem, index) { - var jElem = angular.element(elem); - - switch (index) { - case 0: - this.fullBar = jElem; - break; - case 1: - this.selBar = jElem; - break; - case 2: - this.minH = jElem; - break; - case 3: - this.maxH = jElem; - break; - case 4: - this.flrLab = jElem; - break; - case 5: - this.ceilLab = jElem; - break; - case 6: - this.minLab = jElem; - break; - case 7: - this.maxLab = jElem; - break; - case 8: - this.cmbLab = jElem; - break; - case 9: - this.ticks = jElem; - break; - } - - }, this); - - // Initialize offset cache properties - this.selBar.rzsp = 0; - this.minH.rzsp = 0; - this.maxH.rzsp = 0; - this.flrLab.rzsp = 0; - this.ceilLab.rzsp = 0; - this.minLab.rzsp = 0; - this.maxLab.rzsp = 0; - this.cmbLab.rzsp = 0; - }, + if (this.options.customTemplateScope) + this.scope.custom = this.options.customTemplateScope + }, - /** - * Update each elements style based on options - */ - manageElementsStyle: function() { + parseStepsArray: function() { + this.options.floor = 0 + this.options.ceil = this.options.stepsArray.length - 1 + this.options.step = 1 - if (!this.range) - this.maxH.css('display', 'none'); - else - this.maxH.css('display', ''); + if (this.options.translate) { + this.customTrFn = this.options.translate + } else { + this.customTrFn = function(modelValue) { + if (this.options.bindIndexForStepsArray) + return this.getStepValue(modelValue) + return modelValue + } + } + this.getLegend = function(index) { + var step = this.options.stepsArray[index] + if (angular.isObject(step)) return step.legend + return null + } + }, - this.alwaysHide(this.flrLab, this.options.showTicksValues || this.options.hideLimitLabels); - this.alwaysHide(this.ceilLab, this.options.showTicksValues || this.options.hideLimitLabels); + /** + * Resets slider + * + * @returns {undefined} + */ + resetSlider: function() { + this.resetLabelsValue() + this.manageElementsStyle() + this.addAccessibility() + this.setMinAndMax() + this.updateCeilLab() + this.updateFloorLab() + this.unbindEvents() + this.manageEventsBindings() + this.setDisabledState() + this.calcViewDimensions() + this.updateRestrictionBar() + this.refocusPointerIfNeeded() + }, + + refocusPointerIfNeeded: function() { + if (this.currentFocusElement) { + this.onPointerFocus( + this.currentFocusElement.pointer, + this.currentFocusElement.ref + ) + this.focusElement(this.currentFocusElement.pointer) + } + }, + + /** + * Check if the restrictedRange option using multiple or not + * + * Run only once during initialization and only in case 4 + * + * @returns {undefined} + */ - var hideLabelsForTicks = this.options.showTicksValues && !this.intermediateTicks; - this.alwaysHide(this.minLab, hideLabelsForTicks || this.options.hidePointerLabels); - this.alwaysHide(this.maxLab, hideLabelsForTicks || !this.range || this.options.hidePointerLabels); - this.alwaysHide(this.cmbLab, hideLabelsForTicks || !this.range || this.options.hidePointerLabels); - this.alwaysHide(this.selBar, !this.range && !this.options.showSelectionBar); + ensureRestrictedBarIsArray: function(elem) { + var jElem = angular.element(elem) + this.restrictedBar = [] + if (this.options.restrictedRange) { + // this.options.restrictedRange converting to an array even if it's not entered as array. + this.options.restrictedRange = !Array.isArray( + this.options.restrictedRange + ) + ? [this.options.restrictedRange] + : this.options.restrictedRange + this.restrictedBar[0] = jElem + var mainDiv = elem.parentElement + for (var i = 1; i < this.options.restrictedRange.length; i++) { + var sp = document.createElement('span') + sp.setAttribute('class', 'rz-bar-wrapper') + sp.innerHTML = + '' + mainDiv.appendChild(sp) + this.restrictedBar[i] = angular.element(sp) + } + } else { + elem.style.visibility = 'hidden' + this.restrictedBar = null + } + }, + + /** + * Set the slider children to variables for easy access + * + * Run only once during initialization + * + * @returns {undefined} + */ + initElemHandles: function() { + // Assign all slider elements to object properties for easy access + angular.forEach( + this.sliderElem.children(), + function(elem, index) { + var jElem = angular.element(elem) + + switch (index) { + case 0: + this.leftOutSelBar = jElem + break + case 1: + this.rightOutSelBar = jElem + break + case 2: + this.fullBar = jElem + break + case 3: + this.selBar = jElem + break + case 4: + this.ensureRestrictedBarIsArray(elem) + break + case 5: + this.minH = jElem + break + case 6: + this.maxH = jElem + break + case 7: + this.flrLab = jElem + break + case 8: + this.ceilLab = jElem + break + case 9: + this.minLab = jElem + break + case 10: + this.maxLab = jElem + break + case 11: + this.cmbLab = jElem + break + case 12: + this.ticks = jElem + break + } + }, + this + ) + + // Initialize position cache properties + this.selBar.rzsp = 0 + this.minH.rzsp = 0 + this.maxH.rzsp = 0 + this.flrLab.rzsp = 0 + this.ceilLab.rzsp = 0 + this.minLab.rzsp = 0 + this.maxLab.rzsp = 0 + this.cmbLab.rzsp = 0 + }, + + /** + * Update each elements style based on options + */ + manageElementsStyle: function() { + if (!this.range) this.maxH.css('display', 'none') + else this.maxH.css('display', '') + + this.alwaysHide( + this.flrLab, + this.options.showTicksValues || this.options.hideLimitLabels + ) + this.alwaysHide( + this.ceilLab, + this.options.showTicksValues || this.options.hideLimitLabels + ) + + var hideLabelsForTicks = + this.options.showTicksValues && !this.intermediateTicks + this.alwaysHide( + this.minLab, + hideLabelsForTicks || this.options.hidePointerLabels + ) + this.alwaysHide( + this.maxLab, + hideLabelsForTicks || !this.range || this.options.hidePointerLabels + ) + this.alwaysHide( + this.cmbLab, + hideLabelsForTicks || !this.range || this.options.hidePointerLabels + ) + this.alwaysHide( + this.selBar, + !this.range && !this.options.showSelectionBar + ) + this.alwaysHide( + this.leftOutSelBar, + !this.range || !this.options.showOuterSelectionBars + ) + + // this.restrictedBar is everytime an array + for (var r in this.restrictedBar) { + if (this.restrictedBar[r]) + this.alwaysHide( + this.restrictedBar[r], + !this.options.restrictedRange[r] + ) + } - if (this.options.vertical) - this.sliderElem.addClass('rz-vertical'); + this.alwaysHide( + this.rightOutSelBar, + !this.range || !this.options.showOuterSelectionBars + ) - if (this.options.draggableRange) - this.selBar.addClass('rz-draggable'); - else - this.selBar.removeClass('rz-draggable'); + if (this.range && this.options.showOuterSelectionBars) { + this.fullBar.addClass('rz-transparent') + } - if (this.intermediateTicks && this.options.showTicksValues) - this.ticks.addClass('rz-ticks-values-under'); - }, + if (this.options.vertical) { + this.sliderElem.addClass('rz-vertical') + } else { + this.sliderElem.removeClass('rz-vertical') + } - alwaysHide: function(el, hide) { - el.rzAlwaysHide = hide; - if (hide) - this.hideEl(el); - else - this.showEl(el) - }, + if (this.options.draggableRange) this.selBar.addClass('rz-draggable') + else this.selBar.removeClass('rz-draggable') - /** - * Manage the events bindings based on readOnly and disabled options - * - * @returns {undefined} - */ - manageEventsBindings: function() { - if (this.options.disabled || this.options.readOnly) - this.unbindEvents(); - else - this.bindEvents(); - }, + if (this.intermediateTicks && this.options.showTicksValues) + this.ticks.addClass('rz-ticks-values-under') + }, - /** - * Set the disabled state based on rzSliderDisabled - * - * @returns {undefined} - */ - setDisabledState: function() { - if (this.options.disabled) { - this.sliderElem.attr('disabled', 'disabled'); - } else { - this.sliderElem.attr('disabled', null); - } - }, + alwaysHide: function(el, hide) { + el.rzAlwaysHide = hide + if (hide) this.hideEl(el) + else this.showEl(el) + }, - /** - * Reset label values - * - * @return {undefined} - */ - resetLabelsValue: function() { - this.minLab.rzsv = undefined; - this.maxLab.rzsv = undefined; - }, + /** + * Manage the events bindings based on readOnly and disabled options + * + * @returns {undefined} + */ + manageEventsBindings: function() { + if (this.options.disabled || this.options.readOnly) + this.unbindEvents() + else this.bindEvents() + }, + + /** + * Set the disabled state based on rzSliderDisabled + * + * @returns {undefined} + */ + setDisabledState: function() { + if (this.options.disabled) { + this.sliderElem.attr('disabled', 'disabled') + } else { + this.sliderElem.attr('disabled', null) + } + }, - /** - * Initialize slider handles positions and labels - * - * Run only once during initialization and every time view port changes size - * - * @returns {undefined} - */ - initHandles: function() { - this.updateLowHandle(this.valueToOffset(this.lowValue)); + /** + * Reset label values + * + * @return {undefined} + */ + resetLabelsValue: function() { + this.minLab.rzsv = undefined + this.maxLab.rzsv = undefined + this.flrLab.rzsv = undefined + this.ceilLab.rzsv = undefined + this.cmbLab.rzsv = undefined + this.resetPosition(this.flrLab) + this.resetPosition(this.ceilLab) + this.resetPosition(this.cmbLab) + this.resetPosition(this.minLab) + this.resetPosition(this.maxLab) + }, + + /** + * Initialize slider handles positions and labels + * + * Run only once during initialization and every time view port changes size + * + * @returns {undefined} + */ + initHandles: function() { + this.updateLowHandle(this.valueToPosition(this.lowValue)) - /* + /* the order here is important since the selection bar should be updated after the high handle but before the combined label */ - if (this.range) - this.updateHighHandle(this.valueToOffset(this.highValue)); - this.updateSelectionBar(); - if (this.range) - this.updateCmbLabel(); - - this.updateTicksScale(); - }, - - /** - * Translate value to human readable format - * - * @param {number|string} value - * @param {jqLite} label - * @param {String} which - * @param {boolean} [useCustomTr] - * @returns {undefined} - */ - translateFn: function(value, label, which, useCustomTr) { - useCustomTr = useCustomTr === undefined ? true : useCustomTr; - - var valStr = '', - getDimension = false, - noLabelInjection = label.hasClass('no-label-injection'); + if (this.range) + this.updateHighHandle(this.valueToPosition(this.highValue)) + this.updateSelectionBar() + if (this.range) this.updateCmbLabel() + + this.updateTicksScale() + }, + + /** + * Translate value to human readable format + * + * @param {number|string} value + * @param {jqLite} label + * @param {String} which + * @param {boolean} [useCustomTr] + * @returns {undefined} + */ + translateFn: function(value, label, which, useCustomTr) { + useCustomTr = useCustomTr === undefined ? true : useCustomTr - if (useCustomTr) { - if (this.options.stepsArray && !this.options.bindIndexForStepsArray) - value = this.getStepValue(value); - valStr = String(this.customTrFn(value, this.options.id, which)); - } - else { - valStr = String(value) - } + var valStr = '', + getDimension = false, + noLabelInjection = label.hasClass('no-label-injection') - if (label.rzsv === undefined || label.rzsv.length !== valStr.length || (label.rzsv.length > 0 && label.rzsd === 0)) { - getDimension = true; - label.rzsv = valStr; - } + if (useCustomTr) { + if (this.options.stepsArray && !this.options.bindIndexForStepsArray) + value = this.getStepValue(value) + valStr = String(this.customTrFn(value, this.options.id, which)) + } else { + valStr = String(value) + } - if (!noLabelInjection) { - label.html(valStr); - } - ; + if ( + label.rzsv === undefined || + label.rzsv.length !== valStr.length || + (label.rzsv.length > 0 && label.rzsd === 0) + ) { + getDimension = true + label.rzsv = valStr + } - this.scope[which + 'Label'] = valStr; + if (!noLabelInjection) { + label.html(valStr) + } + this.scope[which + 'Label'] = valStr - // Update width only when length of the label have changed - if (getDimension) { - this.getDimension(label); - } - }, + // Update width only when length of the label have changed + if (getDimension) { + this.getDimension(label) + } + }, - /** - * Set maximum and minimum values for the slider and ensure the model and high - * value match these limits - * @returns {undefined} - */ - setMinAndMax: function() { + /** + * Set maximum and minimum values for the slider and ensure the model and high + * value match these limits + * @returns {undefined} + */ + setMinAndMax: function() { + this.step = +this.options.step + this.precision = +this.options.precision - this.step = +this.options.step; - this.precision = +this.options.precision; + this.minValue = this.options.floor + if (this.options.logScale && this.minValue === 0) + throw Error("Can't use floor=0 with logarithmic scale") - this.minValue = this.options.floor; + if (this.options.enforceStep) { + this.lowValue = this.roundStep(this.lowValue) + if (this.range) this.highValue = this.roundStep(this.highValue) + } - if (this.options.enforceStep) { - this.lowValue = this.roundStep(this.lowValue); - if (this.range) - this.highValue = this.roundStep(this.highValue); - } + if (this.options.ceil != null) this.maxValue = this.options.ceil + else + this.maxValue = this.options.ceil = this.range + ? this.highValue + : this.lowValue - if (this.options.ceil != null) - this.maxValue = this.options.ceil; - else - this.maxValue = this.options.ceil = this.range ? this.highValue : this.lowValue; + if (this.options.enforceRange) { + this.lowValue = this.sanitizeValue(this.lowValue) + if (this.range) this.highValue = this.sanitizeValue(this.highValue) + } - if (this.options.enforceRange) { - this.lowValue = this.sanitizeValue(this.lowValue); - if (this.range) - this.highValue = this.sanitizeValue(this.highValue); - } + this.applyLowValue() + if (this.range) this.applyHighValue() - this.applyLowValue(); - if (this.range) - this.applyHighValue(); + this.valueRange = this.maxValue - this.minValue + }, - this.valueRange = this.maxValue - this.minValue; - }, + /** + * Adds accessibility attributes + * + * Run only once during initialization + * + * @returns {undefined} + */ + addAccessibility: function() { + this.minH.attr('role', 'slider') + this.updateAriaAttributes() + if ( + this.options.keyboardSupport && + !(this.options.readOnly || this.options.disabled) + ) + this.minH.attr('tabindex', '0') + else this.minH.attr('tabindex', '') + if (this.options.vertical) { + this.minH.attr('aria-orientation', 'vertical') + } else { + this.minH.attr('aria-orientation', 'horizontal') + } + if (this.options.ariaLabel) + this.minH.attr('aria-label', this.options.ariaLabel) + else if (this.options.ariaLabelledBy) + this.minH.attr('aria-labelledby', this.options.ariaLabelledBy) - /** - * Adds accessibility attributes - * - * Run only once during initialization - * - * @returns {undefined} - */ - addAccessibility: function() { - this.minH.attr('role', 'slider'); - this.updateAriaAttributes(); - if (this.options.keyboardSupport && !(this.options.readOnly || this.options.disabled)) - this.minH.attr('tabindex', '0'); - else - this.minH.attr('tabindex', ''); - if (this.options.vertical) - this.minH.attr('aria-orientation', 'vertical'); - - if (this.range) { - this.maxH.attr('role', 'slider'); - if (this.options.keyboardSupport && !(this.options.readOnly || this.options.disabled)) - this.maxH.attr('tabindex', '0'); - else - this.maxH.attr('tabindex', ''); - if (this.options.vertical) - this.maxH.attr('aria-orientation', 'vertical'); - } - }, + if (this.range) { + this.maxH.attr('role', 'slider') + if ( + this.options.keyboardSupport && + !(this.options.readOnly || this.options.disabled) + ) + this.maxH.attr('tabindex', '0') + else this.maxH.attr('tabindex', '') + if (this.options.vertical) + this.maxH.attr('aria-orientation', 'vertical') + else this.maxH.attr('aria-orientation', 'horizontal') + if (this.options.ariaLabelHigh) + this.maxH.attr('aria-label', this.options.ariaLabelHigh) + else if (this.options.ariaLabelledByHigh) + this.maxH.attr('aria-labelledby', this.options.ariaLabelledByHigh) + } + }, - /** - * Updates aria attributes according to current values - */ - updateAriaAttributes: function() { - this.minH.attr({ - 'aria-valuenow': this.scope.rzSliderModel, - 'aria-valuetext': this.customTrFn(this.scope.rzSliderModel, this.options.id, 'model'), - 'aria-valuemin': this.minValue, - 'aria-valuemax': this.maxValue - }); - if (this.range) { - this.maxH.attr({ - 'aria-valuenow': this.scope.rzSliderHigh, - 'aria-valuetext': this.customTrFn(this.scope.rzSliderHigh, this.options.id, 'high'), + /** + * Updates aria attributes according to current values + */ + updateAriaAttributes: function() { + this.minH.attr({ + 'aria-valuenow': this.scope.rzSliderModel, + 'aria-valuetext': this.customTrFn( + this.scope.rzSliderModel, + this.options.id, + 'model' + ), 'aria-valuemin': this.minValue, - 'aria-valuemax': this.maxValue - }); - } - }, - - /** - * Calculate dimensions that are dependent on view port size - * - * Run once during initialization and every time view port changes size. - * - * @returns {undefined} - */ - calcViewDimensions: function() { - var handleWidth = this.getDimension(this.minH); + 'aria-valuemax': this.maxValue, + }) + if (this.range) { + this.maxH.attr({ + 'aria-valuenow': this.scope.rzSliderHigh, + 'aria-valuetext': this.customTrFn( + this.scope.rzSliderHigh, + this.options.id, + 'high' + ), + 'aria-valuemin': this.minValue, + 'aria-valuemax': this.maxValue, + }) + } + }, + + /** + * Calculate dimensions that are dependent on view port size + * + * Run once during initialization and every time view port changes size. + * + * @returns {undefined} + */ + calcViewDimensions: function() { + var handleWidth = this.getDimension(this.minH) + + this.handleHalfDim = handleWidth / 2 + this.barDimension = this.getDimension(this.fullBar) + + this.maxPos = this.barDimension - handleWidth + + this.getDimension(this.sliderElem) + this.sliderElem.rzsp = this.sliderElem[0].getBoundingClientRect()[ + this.positionProperty + ] + + if (this.initHasRun) { + this.updateFloorLab() + this.updateCeilLab() + this.initHandles() + var self = this + $timeout(function() { + self.updateTicksScale() + }) + } + }, - this.handleHalfDim = handleWidth / 2; - this.barDimension = this.getDimension(this.fullBar); + /** + * Update the ticks position + * + * @returns {undefined} + */ + updateTicksScale: function() { + if (!this.options.showTicks) return - this.maxPos = this.barDimension - handleWidth; + var ticksArray = this.options.ticksArray || this.getTicksArray(), + translate = this.options.vertical ? 'translateY' : 'translateX', + self = this - this.getDimension(this.sliderElem); - this.sliderElem.rzsp = this.sliderElem[0].getBoundingClientRect()[this.positionProperty]; + if (this.options.rightToLeft) ticksArray.reverse() - if (this.initHasRun) { - this.updateFloorLab(); - this.updateCeilLab(); - this.initHandles(); - } - }, + this.scope.ticks = ticksArray.map(function(value) { + var legend = null + if (angular.isObject(value)) { + legend = value.legend + value = value.value + } - /** - * Update the ticks position - * - * @returns {undefined} - */ - updateTicksScale: function() { - if (!this.options.showTicks) return; - var step = this.step; - if (this.intermediateTicks) - step = this.options.showTicks; - var ticksCount = Math.round((this.maxValue - this.minValue) / step) + 1; - this.scope.ticks = []; - for (var i = 0; i < ticksCount; i++) { - var value = this.roundStep(this.minValue + i * step); - var tick = { - selected: this.isTickSelected(value) - }; - if (tick.selected && this.options.getSelectionBarColor) { - tick.style = { - 'background-color': this.getSelectionBarColor() - }; - } - if (!tick.selected && this.options.getTickColor) { - tick.style = { - 'background-color': this.getTickColor(value) + var position = self.valueToPosition(value) + + if (self.options.vertical) position = self.maxPos - position + + var translation = translate + '(' + Math.round(position) + 'px)' + var tick = { + legend: legend, + selected: self.isTickSelected(value), + style: { + '-webkit-transform': translation, + '-moz-transform': translation, + '-o-transform': translation, + '-ms-transform': translation, + transform: translation, + }, + } + if (tick.selected && self.options.getSelectionBarColor) { + tick.style['background-color'] = self.getSelectionBarColor() + } + if (!tick.selected && self.options.getTickColor) { + tick.style['background-color'] = self.getTickColor(value) + } + if (self.options.ticksTooltip) { + tick.tooltip = self.options.ticksTooltip(value) + tick.tooltipPlacement = self.options.vertical ? 'right' : 'top' + } + if ( + self.options.showTicksValues === true || + value % self.options.showTicksValues === 0 + ) { + tick.value = self.getDisplayValue(value, 'tick-value') + if (self.options.ticksValuesTooltip) { + tick.valueTooltip = self.options.ticksValuesTooltip(value) + tick.valueTooltipPlacement = self.options.vertical + ? 'right' + : 'top' + } + } + if (self.getLegend) { + legend = self.getLegend(value, self.options.id) + if (legend) tick.legend = legend } + return tick + }) + }, + + getTicksArray: function() { + var step = this.step, + ticksArray = [] + if (this.intermediateTicks) step = this.options.showTicks + for ( + var value = this.minValue; + value <= this.maxValue; + value += step + ) { + ticksArray.push(value) } - if (this.options.ticksTooltip) { - tick.tooltip = this.options.ticksTooltip(value); - tick.tooltipPlacement = this.options.vertical ? 'right' : 'top'; + return ticksArray + }, + + isTickSelected: function(value) { + if (!this.range) { + if (this.options.showSelectionBarFromValue !== null) { + var center = this.options.showSelectionBarFromValue + if ( + this.lowValue > center && + value >= center && + value <= this.lowValue + ) + return true + else if ( + this.lowValue < center && + value <= center && + value >= this.lowValue + ) + return true + } else if (this.options.showSelectionBarEnd) { + if (value >= this.lowValue) return true + } else if (this.options.showSelectionBar && value <= this.lowValue) + return true } - if (this.options.showTicksValues) { - tick.value = this.getDisplayValue(value, 'tick-value'); - if (this.options.ticksValuesTooltip) { - tick.valueTooltip = this.options.ticksValuesTooltip(value); - tick.valueTooltipPlacement = this.options.vertical ? 'right' : 'top'; - } - } - if (this.getLegend) { - var legend = this.getLegend(value, this.options.id); - if (legend) - tick.legend = legend; - } - if (!this.options.rightToLeft) { - this.scope.ticks.push(tick); + if (this.range && value >= this.lowValue && value <= this.highValue) + return true + return false + }, + + /** + * Update position of the floor label + * + * @returns {undefined} + */ + updateFloorLab: function() { + this.translateFn(this.minValue, this.flrLab, 'floor') + this.getDimension(this.flrLab) + var position = this.options.rightToLeft + ? this.barDimension - this.flrLab.rzsd + : 0 + this.setPosition(this.flrLab, position) + }, + + /** + * Update position of the ceiling label + * + * @returns {undefined} + */ + updateCeilLab: function() { + this.translateFn(this.maxValue, this.ceilLab, 'ceil') + this.getDimension(this.ceilLab) + var position = this.options.rightToLeft + ? 0 + : this.barDimension - this.ceilLab.rzsd + this.setPosition(this.ceilLab, position) + }, + + /** + * Update slider handles and label positions + * + * @param {string} which + * @param {number} newPos + */ + updateHandles: function(which, newPos) { + if (which === 'lowValue') this.updateLowHandle(newPos) + else this.updateHighHandle(newPos) + + this.updateSelectionBar() + this.updateTicksScale() + if (this.range) this.updateCmbLabel() + }, + + /** + * Helper function to work out the position for handle labels depending on RTL or not + * + * @param {string} labelName maxLab or minLab + * @param newPos + * + * @returns {number} + */ + getHandleLabelPos: function(labelName, newPos) { + var labelRzsd = this[labelName].rzsd, + nearHandlePos = newPos - labelRzsd / 2 + this.handleHalfDim, + endOfBarPos = this.barDimension - labelRzsd + + if (!this.options.boundPointerLabels) return nearHandlePos + + if ( + (this.options.rightToLeft && labelName === 'minLab') || + (!this.options.rightToLeft && labelName === 'maxLab') + ) { + return Math.min(nearHandlePos, endOfBarPos) } else { - this.scope.ticks.unshift(tick); + return Math.min(Math.max(nearHandlePos, 0), endOfBarPos) } - } - }, - - isTickSelected: function(value) { - if (!this.range) { - if (this.options.showSelectionBarFromValue !== null) { - var center = this.options.showSelectionBarFromValue; - if (this.lowValue > center && value >= center && value <= this.lowValue) - return true; - else if (this.lowValue < center && value <= center && value >= this.lowValue) - return true; - } - else if (this.options.showSelectionBarEnd) { - if (value >= this.lowValue) - return true; - } - else if (this.options.showSelectionBar && value <= this.lowValue) - return true; - } - if (this.range && value >= this.lowValue && value <= this.highValue) - return true; - return false; - }, - - /** - * Update position of the floor label - * - * @returns {undefined} - */ - updateFloorLab: function() { - this.translateFn(this.minValue, this.flrLab, 'floor'); - this.getDimension(this.flrLab); - var position = this.options.rightToLeft ? this.barDimension - this.flrLab.rzsd : 0; - this.setPosition(this.flrLab, position); - }, - - /** - * Update position of the ceiling label - * - * @returns {undefined} - */ - updateCeilLab: function() { - this.translateFn(this.maxValue, this.ceilLab, 'ceil'); - this.getDimension(this.ceilLab); - var position = this.options.rightToLeft ? 0 : this.barDimension - this.ceilLab.rzsd; - this.setPosition(this.ceilLab, position); - }, - - /** - * Update slider handles and label positions - * - * @param {string} which - * @param {number} newOffset - */ - updateHandles: function(which, newOffset) { - if (which === 'lowValue') - this.updateLowHandle(newOffset); - else - this.updateHighHandle(newOffset); - - this.updateSelectionBar(); - this.updateTicksScale(); - if (this.range) - this.updateCmbLabel(); - }, + }, - /** - * Helper function to work out the position for handle labels depending on RTL or not - * - * @param {string} labelName maxLab or minLab - * @param newOffset - * - * @returns {number} - */ - getHandleLabelPos: function(labelName, newOffset) { - var labelRzsd = this[labelName].rzsd, - nearHandlePos = newOffset - labelRzsd / 2 + this.handleHalfDim, - endOfBarPos = this.barDimension - labelRzsd; - - if (!this.options.boundPointerLabels) - return nearHandlePos; - - if (this.options.rightToLeft && labelName === 'minLab' || !this.options.rightToLeft && labelName === 'maxLab') { - return Math.min(nearHandlePos, endOfBarPos); - } else { - return Math.min(Math.max(nearHandlePos, 0), endOfBarPos); - } - }, + /** + * Update low slider handle position and label + * + * @param {number} newPos + * @returns {undefined} + */ + updateLowHandle: function(newPos) { + this.setPosition(this.minH, newPos) + this.translateFn(this.lowValue, this.minLab, 'model') + this.setPosition( + this.minLab, + this.getHandleLabelPos('minLab', newPos) + ) + + if (this.options.getPointerColor) { + var pointercolor = this.getPointerColor('min') + this.scope.minPointerStyle = { + backgroundColor: pointercolor, + } + } - /** - * Update low slider handle position and label - * - * @param {number} newOffset - * @returns {undefined} - */ - updateLowHandle: function(newOffset) { - this.setPosition(this.minH, newOffset); - this.translateFn(this.lowValue, this.minLab, 'model'); - this.setPosition(this.minLab, this.getHandleLabelPos('minLab', newOffset)); - - if (this.options.getPointerColor) { - var pointercolor = this.getPointerColor('min'); - this.scope.minPointerStyle = { - backgroundColor: pointercolor - }; - } + if (this.options.autoHideLimitLabels) { + this.shFloorCeil() + } + }, - if (this.options.autoHideLimitLabels) { - this.shFloorCeil(); - } - }, + /** + * Update high slider handle position and label + * + * @param {number} newPos + * @returns {undefined} + */ + updateHighHandle: function(newPos) { + this.setPosition(this.maxH, newPos) + this.translateFn(this.highValue, this.maxLab, 'high') + this.setPosition( + this.maxLab, + this.getHandleLabelPos('maxLab', newPos) + ) + + if (this.options.getPointerColor) { + var pointercolor = this.getPointerColor('max') + this.scope.maxPointerStyle = { + backgroundColor: pointercolor, + } + } + if (this.options.autoHideLimitLabels) { + this.shFloorCeil() + } + }, - /** - * Update high slider handle position and label - * - * @param {number} newOffset - * @returns {undefined} - */ - updateHighHandle: function(newOffset) { - this.setPosition(this.maxH, newOffset); - this.translateFn(this.highValue, this.maxLab, 'high'); - this.setPosition(this.maxLab, this.getHandleLabelPos('maxLab', newOffset)); - - if (this.options.getPointerColor) { - var pointercolor = this.getPointerColor('max'); - this.scope.maxPointerStyle = { - backgroundColor: pointercolor - }; - } - if (this.options.autoHideLimitLabels) { - this.shFloorCeil(); - } + /** + * Show/hide floor/ceiling label + * + * @returns {undefined} + */ + shFloorCeil: function() { + // Show based only on hideLimitLabels if pointer labels are hidden + if (this.options.hidePointerLabels) { + return + } + var flHidden = false, + clHidden = false, + isMinLabAtFloor = this.isLabelBelowFloorLab(this.minLab), + isMinLabAtCeil = this.isLabelAboveCeilLab(this.minLab), + isMaxLabAtCeil = this.isLabelAboveCeilLab(this.maxLab), + isCmbLabAtFloor = this.isLabelBelowFloorLab(this.cmbLab), + isCmbLabAtCeil = this.isLabelAboveCeilLab(this.cmbLab) + + if (isMinLabAtFloor) { + flHidden = true + this.hideEl(this.flrLab) + } else { + flHidden = false + this.showEl(this.flrLab) + } - }, + if (isMinLabAtCeil) { + clHidden = true + this.hideEl(this.ceilLab) + } else { + clHidden = false + this.showEl(this.ceilLab) + } - /** - * Show/hide floor/ceiling label - * - * @returns {undefined} - */ - shFloorCeil: function() { - // Show based only on hideLimitLabels if pointer labels are hidden - if (this.options.hidePointerLabels) { - return; - } - var flHidden = false, - clHidden = false, - isRTL = this.options.rightToLeft, - flrLabPos = this.flrLab.rzsp, - flrLabDim = this.flrLab.rzsd, - minLabPos = this.minLab.rzsp, - minLabDim = this.minLab.rzsd, - maxLabPos = this.maxLab.rzsp, - maxLabDim = this.maxLab.rzsd, - cmbLabPos = this.cmbLab.rzsp, - cmbLabDim = this.cmbLab.rzsd, - ceilLabPos = this.ceilLab.rzsp, - halfHandle = this.handleHalfDim, - isMinLabAtFloor = isRTL ? minLabPos + minLabDim >= flrLabPos - flrLabDim - 5 : minLabPos <= flrLabPos + flrLabDim + 5, - isMinLabAtCeil = isRTL ? minLabPos - minLabDim <= ceilLabPos + halfHandle + 10 : minLabPos + minLabDim >= ceilLabPos - halfHandle - 10, - isMaxLabAtFloor = isRTL ? maxLabPos >= flrLabPos - flrLabDim - halfHandle : maxLabPos <= flrLabPos + flrLabDim + halfHandle, - isMaxLabAtCeil = isRTL ? maxLabPos - maxLabDim <= ceilLabPos + 10 : maxLabPos + maxLabDim >= ceilLabPos - 10, - isCmbLabAtFloor = isRTL ? cmbLabPos >= flrLabPos - flrLabDim - halfHandle : cmbLabPos <= flrLabPos + flrLabDim + halfHandle, - isCmbLabAtCeil = isRTL ? cmbLabPos - cmbLabDim <= ceilLabPos + 10 : cmbLabPos + cmbLabDim >= ceilLabPos - 10 - - - if (isMinLabAtFloor) { - flHidden = true; - this.hideEl(this.flrLab); - } else { - flHidden = false; - this.showEl(this.flrLab); - } + if (this.range) { + var hideCeil = this.cmbLabelShown ? isCmbLabAtCeil : isMaxLabAtCeil + var hideFloor = this.cmbLabelShown + ? isCmbLabAtFloor + : isMinLabAtFloor + + if (hideCeil) { + this.hideEl(this.ceilLab) + } else if (!clHidden) { + this.showEl(this.ceilLab) + } - if (isMinLabAtCeil) { - clHidden = true; - this.hideEl(this.ceilLab); - } else { - clHidden = false; - this.showEl(this.ceilLab); - } + // Hide or show floor label + if (hideFloor) { + this.hideEl(this.flrLab) + } else if (!flHidden) { + this.showEl(this.flrLab) + } + } + }, + + isLabelBelowFloorLab: function(label) { + var isRTL = this.options.rightToLeft, + pos = label.rzsp, + dim = label.rzsd, + floorPos = this.flrLab.rzsp, + floorDim = this.flrLab.rzsd + return isRTL + ? pos + dim >= floorPos - 2 + : pos <= floorPos + floorDim + 2 + }, + + isLabelAboveCeilLab: function(label) { + var isRTL = this.options.rightToLeft, + pos = label.rzsp, + dim = label.rzsd, + ceilPos = this.ceilLab.rzsp, + ceilDim = this.ceilLab.rzsd + return isRTL ? pos <= ceilPos + ceilDim + 2 : pos + dim >= ceilPos - 2 + }, + + /** + * Update restricted area bar + * + * @returns {undefined} + */ + updateRestrictionBar: function() { + var position = 0, + dimension = 0 + if (this.options.restrictedRange) { + this.options.restrictedRange = !Array.isArray( + this.options.restrictedRange + ) + ? [this.options.restrictedRange] + : this.options.restrictedRange + for (var i in this.options.restrictedRange) { + var from = this.valueToPosition( + this.options.restrictedRange[i].from + ), + to = this.valueToPosition(this.options.restrictedRange[i].to) + dimension = Math.abs(to - from) + position = this.options.rightToLeft + ? to + this.handleHalfDim + : from + this.handleHalfDim + this.setDimension(this.restrictedBar[i], dimension) + this.setPosition(this.restrictedBar[i], position) + } + } + }, - if (this.range) { - var hideCeil = this.cmbLabelShown ? isCmbLabAtCeil : isMaxLabAtCeil; - var hideFloor = this.cmbLabelShown ? isCmbLabAtFloor : isMinLabAtFloor; + /** + * Update slider selection bar, combined label and range label + * + * @returns {undefined} + */ + updateSelectionBar: function() { + var position = 0, + dimension = 0, + isSelectionBarFromRight = this.options.rightToLeft + ? !this.options.showSelectionBarEnd + : this.options.showSelectionBarEnd, + positionForRange = this.options.rightToLeft + ? this.maxH.rzsp + this.handleHalfDim + : this.minH.rzsp + this.handleHalfDim - if (hideCeil) { - this.hideEl(this.ceilLab); - } else if (!clHidden) { - this.showEl(this.ceilLab); + if (this.range) { + dimension = Math.abs(this.maxH.rzsp - this.minH.rzsp) + position = positionForRange + } else { + if (this.options.showSelectionBarFromValue !== null) { + var center = this.options.showSelectionBarFromValue, + centerPosition = this.valueToPosition(center), + isModelGreaterThanCenter = this.options.rightToLeft + ? this.lowValue <= center + : this.lowValue > center + if (isModelGreaterThanCenter) { + dimension = this.minH.rzsp - centerPosition + position = centerPosition + this.handleHalfDim + } else { + dimension = centerPosition - this.minH.rzsp + position = this.minH.rzsp + this.handleHalfDim + } + } else if (isSelectionBarFromRight) { + dimension = + Math.abs(this.maxPos - this.minH.rzsp) + this.handleHalfDim + position = this.minH.rzsp + this.handleHalfDim + } else { + dimension = this.minH.rzsp + this.handleHalfDim + position = 0 + } } - - // Hide or show floor label - if (hideFloor) { - this.hideEl(this.flrLab); - } else if (!flHidden) { - this.showEl(this.flrLab); + this.setDimension(this.selBar, dimension) + this.setPosition(this.selBar, position) + if (this.range && this.options.showOuterSelectionBars) { + if (this.options.rightToLeft) { + this.setDimension(this.rightOutSelBar, position) + this.setPosition(this.rightOutSelBar, 0) + this.setDimension( + this.leftOutSelBar, + this.getDimension(this.fullBar) - (position + dimension) + ) + this.setPosition(this.leftOutSelBar, position + dimension) + } else { + this.setDimension(this.leftOutSelBar, position) + this.setPosition(this.leftOutSelBar, 0) + this.setDimension( + this.rightOutSelBar, + this.getDimension(this.fullBar) - (position + dimension) + ) + this.setPosition(this.rightOutSelBar, position + dimension) + } } - } - }, - - /** - * Update slider selection bar, combined label and range label - * - * @returns {undefined} - */ - updateSelectionBar: function() { - var position = 0, - dimension = 0, - isSelectionBarFromRight = this.options.rightToLeft ? !this.options.showSelectionBarEnd : this.options.showSelectionBarEnd, - positionForRange = this.options.rightToLeft ? this.maxH.rzsp + this.handleHalfDim : this.minH.rzsp + this.handleHalfDim; - - if (this.range) { - dimension = Math.abs(this.maxH.rzsp - this.minH.rzsp); - position = positionForRange; - } - else { - if (this.options.showSelectionBarFromValue !== null) { - var center = this.options.showSelectionBarFromValue, - centerPosition = this.valueToOffset(center), - isModelGreaterThanCenter = this.options.rightToLeft ? this.lowValue <= center : this.lowValue > center; - if (isModelGreaterThanCenter) { - dimension = this.minH.rzsp - centerPosition; - position = centerPosition + this.handleHalfDim; + if (this.options.getSelectionBarColor) { + var color = this.getSelectionBarColor() + this.scope.barStyle = { + backgroundColor: color, } - else { - dimension = centerPosition - this.minH.rzsp; - position = this.minH.rzsp + this.handleHalfDim; + } else if (this.options.selectionBarGradient) { + var offset = + this.options.showSelectionBarFromValue !== null + ? this.valueToPosition(this.options.showSelectionBarFromValue) + : 0, + reversed = (offset - position > 0) ^ isSelectionBarFromRight, + direction = this.options.vertical + ? reversed + ? 'bottom' + : 'top' + : reversed + ? 'left' + : 'right' + this.scope.barStyle = { + backgroundImage: + 'linear-gradient(to ' + + direction + + ', ' + + this.options.selectionBarGradient.from + + ' 0%,' + + this.options.selectionBarGradient.to + + ' 100%)', + } + if (this.options.vertical) { + this.scope.barStyle.backgroundPosition = + 'center ' + + (offset + + dimension + + position + + (reversed ? -this.handleHalfDim : 0)) + + 'px' + this.scope.barStyle.backgroundSize = + '100% ' + (this.barDimension - this.handleHalfDim) + 'px' + } else { + this.scope.barStyle.backgroundPosition = + offset - + position + + (reversed ? this.handleHalfDim : 0) + + 'px center' + this.scope.barStyle.backgroundSize = + this.barDimension - this.handleHalfDim + 'px 100%' } } - else if (isSelectionBarFromRight) { - dimension = Math.abs(this.maxPos - this.minH.rzsp) + this.handleHalfDim; - position = this.minH.rzsp + this.handleHalfDim; + }, + + /** + * Wrapper around the getSelectionBarColor of the user to pass to + * correct parameters + */ + getSelectionBarColor: function() { + if (this.range) + return this.options.getSelectionBarColor( + this.scope.rzSliderModel, + this.scope.rzSliderHigh + ) + return this.options.getSelectionBarColor(this.scope.rzSliderModel) + }, + + /** + * Wrapper around the getPointerColor of the user to pass to + * correct parameters + */ + getPointerColor: function(pointerType) { + if (pointerType === 'max') { + return this.options.getPointerColor( + this.scope.rzSliderHigh, + pointerType + ) + } + return this.options.getPointerColor( + this.scope.rzSliderModel, + pointerType + ) + }, + + /** + * Wrapper around the getTickColor of the user to pass to + * correct parameters + */ + getTickColor: function(value) { + return this.options.getTickColor(value) + }, + + /** + * Update combined label position and value + * + * @returns {undefined} + */ + updateCmbLabel: function() { + var isLabelOverlap = null + if (this.options.rightToLeft) { + isLabelOverlap = + this.minLab.rzsp - this.minLab.rzsd - 10 <= this.maxLab.rzsp } else { - dimension = Math.abs(this.maxH.rzsp - this.minH.rzsp) + this.handleHalfDim; - position = 0; + isLabelOverlap = + this.minLab.rzsp + this.minLab.rzsd + 10 >= this.maxLab.rzsp } - } - this.setDimension(this.selBar, dimension); - this.setPosition(this.selBar, position); - if (this.options.getSelectionBarColor) { - var color = this.getSelectionBarColor(); - this.scope.barStyle = { - backgroundColor: color - }; - } - }, - /** - * Wrapper around the getSelectionBarColor of the user to pass to - * correct parameters - */ - getSelectionBarColor: function() { - if (this.range) - return this.options.getSelectionBarColor(this.scope.rzSliderModel, this.scope.rzSliderHigh); - return this.options.getSelectionBarColor(this.scope.rzSliderModel); - }, - - /** - * Wrapper around the getPointerColor of the user to pass to - * correct parameters - */ - getPointerColor: function(pointerType) { - if (pointerType === 'max') { - return this.options.getPointerColor(this.scope.rzSliderHigh, pointerType); - } - return this.options.getPointerColor(this.scope.rzSliderModel, pointerType); - }, - - /** - * Wrapper around the getTickColor of the user to pass to - * correct parameters - */ - getTickColor: function(value) { - return this.options.getTickColor(value); - }, - - /** - * Update combined label position and value - * - * @returns {undefined} - */ - updateCmbLabel: function() { - var isLabelOverlap = null; - if (this.options.rightToLeft) { - isLabelOverlap = this.minLab.rzsp - this.minLab.rzsd - 10 <= this.maxLab.rzsp; - } else { - isLabelOverlap = this.minLab.rzsp + this.minLab.rzsd + 10 >= this.maxLab.rzsp; - } + if (isLabelOverlap) { + var lowTr = this.getDisplayValue(this.lowValue, 'model'), + highTr = this.getDisplayValue(this.highValue, 'high'), + labelVal = '' + if (this.options.mergeRangeLabelsIfSame && lowTr === highTr) { + labelVal = lowTr + } else { + labelVal = this.options.rightToLeft + ? highTr + this.options.labelOverlapSeparator + lowTr + : lowTr + this.options.labelOverlapSeparator + highTr + } - if (isLabelOverlap) { - var lowTr = this.getDisplayValue(this.lowValue, 'model'), - highTr = this.getDisplayValue(this.highValue, 'high'), - labelVal = ''; - if (this.options.mergeRangeLabelsIfSame && lowTr === highTr) { - labelVal = lowTr; + this.translateFn(labelVal, this.cmbLab, 'cmb', false) + var pos = this.options.boundPointerLabels + ? Math.min( + Math.max( + this.selBar.rzsp + + this.selBar.rzsd / 2 - + this.cmbLab.rzsd / 2, + 0 + ), + this.barDimension - this.cmbLab.rzsd + ) + : this.selBar.rzsp + this.selBar.rzsd / 2 - this.cmbLab.rzsd / 2 + + this.setPosition(this.cmbLab, pos) + this.cmbLabelShown = true + this.hideEl(this.minLab) + this.hideEl(this.maxLab) + this.showEl(this.cmbLab) } else { - labelVal = this.options.rightToLeft ? highTr + ' - ' + lowTr : lowTr + ' - ' + highTr; + this.cmbLabelShown = false + this.updateHighHandle(this.valueToPosition(this.highValue)) + this.updateLowHandle(this.valueToPosition(this.lowValue)) + this.showEl(this.maxLab) + this.showEl(this.minLab) + this.hideEl(this.cmbLab) + } + if (this.options.autoHideLimitLabels) { + this.shFloorCeil() } + }, - this.translateFn(labelVal, this.cmbLab, 'cmb', false); - var pos = this.options.boundPointerLabels ? Math.min( - Math.max( - this.selBar.rzsp + this.selBar.rzsd / 2 - this.cmbLab.rzsd / 2, - 0 - ), - this.barDimension - this.cmbLab.rzsd - ) : this.selBar.rzsp + this.selBar.rzsd / 2 - this.cmbLab.rzsd / 2; - - this.setPosition(this.cmbLab, pos); - this.cmbLabelShown = true; - this.hideEl(this.minLab); - this.hideEl(this.maxLab); - this.showEl(this.cmbLab); - } else { - this.cmbLabelShown = false; - this.showEl(this.maxLab); - this.showEl(this.minLab); - this.hideEl(this.cmbLab); - } - }, + /** + * Return the translated value if a translate function is provided else the original value + * @param value + * @param which if it's min or max handle + * @returns {*} + */ + getDisplayValue: function(value, which) { + if (this.options.stepsArray && !this.options.bindIndexForStepsArray) { + value = this.getStepValue(value) + } + return this.customTrFn(value, this.options.id, which) + }, + + /** + * Round value to step and precision based on minValue + * + * @param {number} value + * @param {number} customStep a custom step to override the defined step + * @returns {number} + */ + roundStep: function(value, customStep) { + var step = customStep ? customStep : this.step, + steppedDifference = parseFloat( + (value - this.minValue) / step + ).toPrecision(12) + steppedDifference = Math.round(+steppedDifference) * step + var newValue = (this.minValue + steppedDifference).toFixed( + this.precision + ) + return +newValue + }, + + /** + * Hide element + * + * @param element + * @returns {jqLite} The jqLite wrapped DOM element + */ + hideEl: function(element) { + return element.css({ + visibility: 'hidden', + }) + }, + + /** + * Show element + * + * @param element The jqLite wrapped DOM element + * @returns {jqLite} The jqLite + */ + showEl: function(element) { + if (!!element.rzAlwaysHide) { + return element + } - /** - * Return the translated value if a translate function is provided else the original value - * @param value - * @param which if it's min or max handle - * @returns {*} - */ - getDisplayValue: function(value, which) { - if (this.options.stepsArray && !this.options.bindIndexForStepsArray) { - value = this.getStepValue(value); - } - return this.customTrFn(value, this.options.id, which); - }, + return element.css({ + visibility: 'visible', + }) + }, + + /** + * Set element left/top position depending on whether slider is horizontal or vertical + * + * @param {jqLite} elem The jqLite wrapped DOM element + * @param {number} pos + * @returns {number} + */ + setPosition: function(elem, pos) { + elem.rzsp = pos + var css = {} + css[this.positionProperty] = Math.round(pos) + 'px' + elem.css(css) + return pos + }, + + resetPosition: function(elem) { + elem.css({ + left: null, + bottom: null, + }) + }, + + /** + * Get element width/height depending on whether slider is horizontal or vertical + * + * @param {jqLite} elem The jqLite wrapped DOM element + * @returns {number} + */ + getDimension: function(elem) { + var val = elem[0].getBoundingClientRect() + if (this.options.vertical) + elem.rzsd = (val.bottom - val.top) * this.options.scale + else elem.rzsd = (val.right - val.left) * this.options.scale + return elem.rzsd + }, + + /** + * Set element width/height depending on whether slider is horizontal or vertical + * + * @param {jqLite} elem The jqLite wrapped DOM element + * @param {number} dim + * @returns {number} + */ + setDimension: function(elem, dim) { + elem.rzsd = dim + var css = {} + css[this.dimensionProperty] = Math.round(dim) + 'px' + elem.css(css) + return dim + }, + + /** + * Returns a value that is within slider range + * + * @param {number} val + * @returns {number} + */ + sanitizeValue: function(val) { + return Math.min(Math.max(val, this.minValue), this.maxValue) + }, + + /** + * Translate value to pixel position + * + * @param {number} val + * @returns {number} + */ + valueToPosition: function(val) { + var fn = this.linearValueToPosition + if (this.options.customValueToPosition) + fn = this.options.customValueToPosition + else if (this.options.logScale) fn = this.logValueToPosition + + val = this.sanitizeValue(val) + var percent = fn(val, this.minValue, this.maxValue) || 0 + if (this.options.rightToLeft) percent = 1 - percent + return percent * this.maxPos + }, + + linearValueToPosition: function(val, minVal, maxVal) { + var range = maxVal - minVal + return (val - minVal) / range + }, + + logValueToPosition: function(val, minVal, maxVal) { + val = Math.log(val) + minVal = Math.log(minVal) + maxVal = Math.log(maxVal) + var range = maxVal - minVal + return (val - minVal) / range + }, + + /** + * Translate position to model value + * + * @param {number} position + * @returns {number} + */ + positionToValue: function(position) { + var percent = position / this.maxPos + if (this.options.rightToLeft) percent = 1 - percent + var fn = this.linearPositionToValue + if (this.options.customPositionToValue) + fn = this.options.customPositionToValue + else if (this.options.logScale) fn = this.logPositionToValue + return fn(percent, this.minValue, this.maxValue) || 0 + }, + + linearPositionToValue: function(percent, minVal, maxVal) { + return percent * (maxVal - minVal) + minVal + }, + + logPositionToValue: function(percent, minVal, maxVal) { + minVal = Math.log(minVal) + maxVal = Math.log(maxVal) + var value = percent * (maxVal - minVal) + minVal + return Math.exp(value) + }, + + getEventAttr: function(event, attr) { + return event.originalEvent === undefined + ? event[attr] + : event.originalEvent[attr] + }, + + // Events + /** + * Get the X-coordinate or Y-coordinate of an event + * + * @param {Object} event The event + * @param targetTouchId The identifier of the touch with the X/Y coordinates + * @returns {number} + */ + getEventXY: function(event, targetTouchId) { + /* http://stackoverflow.com/a/12336075/282882 */ + //noinspection JSLint + var clientXY = this.options.vertical ? 'clientY' : 'clientX' + if (event[clientXY] !== undefined) { + return event[clientXY] + } - /** - * Round value to step and precision based on minValue - * - * @param {number} value - * @param {number} customStep a custom step to override the defined step - * @returns {number} - */ - roundStep: function(value, customStep) { - var step = customStep ? customStep : this.step, - steppedDifference = parseFloat((value - this.minValue) / step).toPrecision(12); - steppedDifference = Math.round(+steppedDifference) * step; - var newValue = (this.minValue + steppedDifference).toFixed(this.precision); - return +newValue; - }, + var touches = this.getEventAttr(event, 'touches') - /** - * Hide element - * - * @param element - * @returns {jqLite} The jqLite wrapped DOM element - */ - hideEl: function(element) { - return element.css({ - visibility: 'hidden' - }); - }, + if (targetTouchId !== undefined) { + for (var i = 0; i < touches.length; i++) { + if (touches[i].identifier === targetTouchId) { + return touches[i][clientXY] + } + } + } - /** - * Show element - * - * @param element The jqLite wrapped DOM element - * @returns {jqLite} The jqLite - */ - showEl: function(element) { - if (!!element.rzAlwaysHide) { - return element; - } + // If no target touch or the target touch was not found in the event + // returns the coordinates of the first touch + return touches[0][clientXY] + }, - return element.css({ - visibility: 'visible' - }); - }, + /** + * Compute the event position depending on whether the slider is horizontal or vertical + * @param event + * @param targetTouchId If targetTouchId is provided it will be considered the position of that + * @returns {number} + */ + getEventPosition: function(event, targetTouchId) { + var sliderPos = this.sliderElem.rzsp, + eventPos = 0 + if (this.options.vertical) + eventPos = -this.getEventXY(event, targetTouchId) + sliderPos + else eventPos = this.getEventXY(event, targetTouchId) - sliderPos + return eventPos * this.options.scale - this.handleHalfDim // #346 handleHalfDim is already scaled + }, + + /** + * Get event names for move and event end + * + * @param {Event} event The event + * + * @return {{moveEvent: string, endEvent: string}} + */ + getEventNames: function(event) { + var eventNames = { + moveEvent: '', + endEvent: '', + } - /** - * Set element left/top offset depending on whether slider is horizontal or vertical - * - * @param {jqLite} elem The jqLite wrapped DOM element - * @param {number} pos - * @returns {number} - */ - setPosition: function(elem, pos) { - elem.rzsp = pos; - var css = {}; - css[this.positionProperty] = pos + 'px'; - elem.css(css); - return pos; - }, + if (this.getEventAttr(event, 'touches')) { + eventNames.moveEvent = 'touchmove' + eventNames.endEvent = 'touchend' + } else { + eventNames.moveEvent = 'mousemove' + eventNames.endEvent = 'mouseup' + } - /** - * Get element width/height depending on whether slider is horizontal or vertical - * - * @param {jqLite} elem The jqLite wrapped DOM element - * @returns {number} - */ - getDimension: function(elem) { - var val = elem[0].getBoundingClientRect(); - if (this.options.vertical) - elem.rzsd = (val.bottom - val.top) * this.options.scale; - else - elem.rzsd = (val.right - val.left) * this.options.scale; - return elem.rzsd; - }, + return eventNames + }, - /** - * Set element width/height depending on whether slider is horizontal or vertical - * - * @param {jqLite} elem The jqLite wrapped DOM element - * @param {number} dim - * @returns {number} - */ - setDimension: function(elem, dim) { - elem.rzsd = dim; - var css = {}; - css[this.dimensionProperty] = dim + 'px'; - elem.css(css); - return dim; - }, + /** + * Get the handle closest to an event. + * + * @param event {Event} The event + * @returns {jqLite} The handle closest to the event. + */ + getNearestHandle: function(event) { + if (!this.range) { + return this.minH + } + var position = this.getEventPosition(event), + distanceMin = Math.abs(position - this.minH.rzsp), + distanceMax = Math.abs(position - this.maxH.rzsp) + if (distanceMin < distanceMax) return this.minH + else if (distanceMin > distanceMax) return this.maxH + else if (!this.options.rightToLeft) + //if event is at the same distance from min/max then if it's at left of minH, we return minH else maxH + return position < this.minH.rzsp ? this.minH : this.maxH + //reverse in rtl + else return position > this.minH.rzsp ? this.minH : this.maxH + }, + + /** + * Wrapper function to focus an angular element + * + * @param el {AngularElement} the element to focus + */ + focusElement: function(el) { + var DOM_ELEMENT = 0 + el[DOM_ELEMENT].focus() + }, + + /** + * Bind mouse and touch events to slider handles + * + * @returns {undefined} + */ + bindEvents: function() { + var barTracking, barStart, barMove - /** - * Translate value to pixel offset - * - * @param {number} val - * @returns {number} - */ - valueToOffset: function(val) { - if (this.options.rightToLeft) { - return (this.maxValue - this.sanitizeValue(val)) * this.maxPos / this.valueRange || 0; - } - return (this.sanitizeValue(val) - this.minValue) * this.maxPos / this.valueRange || 0; - }, + if (this.options.draggableRange) { + barTracking = 'rzSliderDrag' + barStart = this.onDragStart + barMove = this.onDragMove + } else { + barTracking = 'lowValue' + barStart = this.onStart + barMove = this.onMove + } - /** - * Returns a value that is within slider range - * - * @param {number} val - * @returns {number} - */ - sanitizeValue: function(val) { - return Math.min(Math.max(val, this.minValue), this.maxValue); - }, + if (!this.options.onlyBindHandles) { + this.selBar.on( + 'mousedown', + angular.bind(this, barStart, null, barTracking) + ) + this.selBar.on( + 'mousedown', + angular.bind(this, barMove, this.selBar) + ) + } - /** - * Translate offset to model value - * - * @param {number} offset - * @returns {number} - */ - offsetToValue: function(offset) { - if (this.options.rightToLeft) { - return (1 - (offset / this.maxPos)) * this.valueRange + this.minValue; - } - return (offset / this.maxPos) * this.valueRange + this.minValue; - }, + if (this.options.draggableRangeOnly) { + this.minH.on( + 'mousedown', + angular.bind(this, barStart, null, barTracking) + ) + this.maxH.on( + 'mousedown', + angular.bind(this, barStart, null, barTracking) + ) + } else { + this.minH.on( + 'mousedown', + angular.bind(this, this.onStart, this.minH, 'lowValue') + ) + if (this.range) { + this.maxH.on( + 'mousedown', + angular.bind(this, this.onStart, this.maxH, 'highValue') + ) + } + if (!this.options.onlyBindHandles) { + this.fullBar.on( + 'mousedown', + angular.bind(this, this.onStart, null, null) + ) + this.fullBar.on( + 'mousedown', + angular.bind(this, this.onMove, this.fullBar) + ) + this.ticks.on( + 'mousedown', + angular.bind(this, this.onStart, null, null) + ) + this.ticks.on( + 'mousedown', + angular.bind(this, this.onTickClick, this.ticks) + ) + } + } - // Events + if (!this.options.onlyBindHandles) { + this.selBar.on( + 'touchstart', + angular.bind(this, barStart, null, barTracking) + ) + this.selBar.on( + 'touchstart', + angular.bind(this, barMove, this.selBar) + ) + } + if (this.options.draggableRangeOnly) { + this.minH.on( + 'touchstart', + angular.bind(this, barStart, null, barTracking) + ) + this.maxH.on( + 'touchstart', + angular.bind(this, barStart, null, barTracking) + ) + } else { + this.minH.on( + 'touchstart', + angular.bind(this, this.onStart, this.minH, 'lowValue') + ) + if (this.range) { + this.maxH.on( + 'touchstart', + angular.bind(this, this.onStart, this.maxH, 'highValue') + ) + } + if (!this.options.onlyBindHandles) { + this.fullBar.on( + 'touchstart', + angular.bind(this, this.onStart, null, null) + ) + this.fullBar.on( + 'touchstart', + angular.bind(this, this.onMove, this.fullBar) + ) + this.ticks.on( + 'touchstart', + angular.bind(this, this.onStart, null, null) + ) + this.ticks.on( + 'touchstart', + angular.bind(this, this.onTickClick, this.ticks) + ) + } + } - /** - * Get the X-coordinate or Y-coordinate of an event - * - * @param {Object} event The event - * @returns {number} - */ - getEventXY: function(event) { - /* http://stackoverflow.com/a/12336075/282882 */ - //noinspection JSLint - var clientXY = this.options.vertical ? 'clientY' : 'clientX'; - if (event[clientXY] !== undefined) { - return event[clientXY]; - } + if (this.options.keyboardSupport) { + this.minH.on( + 'focus', + angular.bind(this, this.onPointerFocus, this.minH, 'lowValue') + ) + if (this.range) { + this.maxH.on( + 'focus', + angular.bind(this, this.onPointerFocus, this.maxH, 'highValue') + ) + } + } + }, - return event.originalEvent === undefined ? - event.touches[0][clientXY] : event.originalEvent.touches[0][clientXY]; - }, + /** + * Unbind mouse and touch events to slider handles + * + * @returns {undefined} + */ + unbindEvents: function() { + this.minH.off() + this.maxH.off() + this.fullBar.off() + this.selBar.off() + this.ticks.off() + }, + + /** + * onStart event handler + * + * @param {?Object} pointer The jqLite wrapped DOM element; if null, the closest handle is used + * @param {?string} ref The name of the handle being changed; if null, the closest handle's value is modified + * @param {Event} event The event + * @returns {undefined} + */ + onStart: function(pointer, ref, event) { + var ehMove, + ehEnd, + eventNames = this.getEventNames(event) - /** - * Compute the event position depending on whether the slider is horizontal or vertical - * @param event - * @returns {number} - */ - getEventPosition: function(event) { - var sliderPos = this.sliderElem.rzsp, - eventPos = 0; - if (this.options.vertical) - eventPos = -this.getEventXY(event) + sliderPos; - else - eventPos = this.getEventXY(event) - sliderPos; - return (eventPos - this.handleHalfDim) * this.options.scale; - }, + event.stopPropagation() + event.preventDefault() - /** - * Get event names for move and event end - * - * @param {Event} event The event - * - * @return {{moveEvent: string, endEvent: string}} - */ - getEventNames: function(event) { - var eventNames = { - moveEvent: '', - endEvent: '' - }; - - if (event.touches || (event.originalEvent !== undefined && event.originalEvent.touches)) { - eventNames.moveEvent = 'touchmove'; - eventNames.endEvent = 'touchend'; - } else { - eventNames.moveEvent = 'mousemove'; - eventNames.endEvent = 'mouseup'; - } + // We have to do this in case the HTML where the sliders are on + // have been animated into view. + this.calcViewDimensions() - return eventNames; - }, + if (pointer) { + this.tracking = ref + } else { + pointer = this.getNearestHandle(event) + this.tracking = pointer === this.minH ? 'lowValue' : 'highValue' + } - /** - * Get the handle closest to an event. - * - * @param event {Event} The event - * @returns {jqLite} The handle closest to the event. - */ - getNearestHandle: function(event) { - if (!this.range) { - return this.minH; - } - var offset = this.getEventPosition(event), - distanceMin = Math.abs(offset - this.minH.rzsp), - distanceMax = Math.abs(offset - this.maxH.rzsp); - if (distanceMin < distanceMax) - return this.minH; - else if (distanceMin > distanceMax) - return this.maxH; - else if (!this.options.rightToLeft) - //if event is at the same distance from min/max then if it's at left of minH, we return minH else maxH - return offset < this.minH.rzsp ? this.minH : this.maxH; - else - //reverse in rtl - return offset > this.minH.rzsp ? this.minH : this.maxH; - }, + pointer.addClass('rz-active') - /** - * Wrapper function to focus an angular element - * - * @param el {AngularElement} the element to focus - */ - focusElement: function(el) { - var DOM_ELEMENT = 0; - el[DOM_ELEMENT].focus(); - }, + if (this.options.keyboardSupport) this.focusElement(pointer) - /** - * Bind mouse and touch events to slider handles - * - * @returns {undefined} - */ - bindEvents: function() { - var barTracking, barStart, barMove; - - if (this.options.draggableRange) { - barTracking = 'rzSliderDrag'; - barStart = this.onDragStart; - barMove = this.onDragMove; - } else { - barTracking = 'lowValue'; - barStart = this.onStart; - barMove = this.onMove; - } + ehMove = angular.bind( + this, + this.dragging.active ? this.onDragMove : this.onMove, + pointer + ) + ehEnd = angular.bind(this, this.onEnd, ehMove) - if (!this.options.onlyBindHandles) { - this.selBar.on('mousedown', angular.bind(this, barStart, null, barTracking)); - this.selBar.on('mousedown', angular.bind(this, barMove, this.selBar)); - } + $document.on(eventNames.moveEvent, ehMove) + $document.on(eventNames.endEvent, ehEnd) + this.endHandlerToBeRemovedOnEnd = ehEnd - if (this.options.draggableRangeOnly) { - this.minH.on('mousedown', angular.bind(this, barStart, null, barTracking)); - this.maxH.on('mousedown', angular.bind(this, barStart, null, barTracking)); - } else { - this.minH.on('mousedown', angular.bind(this, this.onStart, this.minH, 'lowValue')); - if (this.range) { - this.maxH.on('mousedown', angular.bind(this, this.onStart, this.maxH, 'highValue')); - } - if (!this.options.onlyBindHandles) { - this.fullBar.on('mousedown', angular.bind(this, this.onStart, null, null)); - this.fullBar.on('mousedown', angular.bind(this, this.onMove, this.fullBar)); - this.ticks.on('mousedown', angular.bind(this, this.onStart, null, null)); - this.ticks.on('mousedown', angular.bind(this, this.onTickClick, this.ticks)); - } - } + this.callOnStart() - if (!this.options.onlyBindHandles) { - this.selBar.on('touchstart', angular.bind(this, barStart, null, barTracking)); - this.selBar.on('touchstart', angular.bind(this, barMove, this.selBar)); - } - if (this.options.draggableRangeOnly) { - this.minH.on('touchstart', angular.bind(this, barStart, null, barTracking)); - this.maxH.on('touchstart', angular.bind(this, barStart, null, barTracking)); - } else { - this.minH.on('touchstart', angular.bind(this, this.onStart, this.minH, 'lowValue')); - if (this.range) { - this.maxH.on('touchstart', angular.bind(this, this.onStart, this.maxH, 'highValue')); + var changedTouches = this.getEventAttr(event, 'changedTouches') + if (changedTouches) { + // Store the touch identifier + if (!this.touchId) { + this.isDragging = true + this.touchId = changedTouches[0].identifier + } } - if (!this.options.onlyBindHandles) { - this.fullBar.on('touchstart', angular.bind(this, this.onStart, null, null)); - this.fullBar.on('touchstart', angular.bind(this, this.onMove, this.fullBar)); - this.ticks.on('touchstart', angular.bind(this, this.onStart, null, null)); - this.ticks.on('touchstart', angular.bind(this, this.onTickClick, this.ticks)); + }, + + /** + * onMove event handler + * + * @param {jqLite} pointer + * @param {Event} event The event + * @param {boolean} fromTick if the event occured on a tick or not + * @returns {undefined} + */ + onMove: function(pointer, event, fromTick) { + if (!this.options.disableAnimation) { + if (this.moving) { + this.sliderElem.addClass('noanimate') + } } - } - - if (this.options.keyboardSupport) { - this.minH.on('focus', angular.bind(this, this.onPointerFocus, this.minH, 'lowValue')); - if (this.range) { - this.maxH.on('focus', angular.bind(this, this.onPointerFocus, this.maxH, 'highValue')); + this.moving = true + var changedTouches = this.getEventAttr(event, 'changedTouches') + var touchForThisSlider + if (changedTouches) { + for (var i = 0; i < changedTouches.length; i++) { + if (changedTouches[i].identifier === this.touchId) { + touchForThisSlider = changedTouches[i] + break + } + } } - } - }, - - /** - * Unbind mouse and touch events to slider handles - * - * @returns {undefined} - */ - unbindEvents: function() { - this.minH.off(); - this.maxH.off(); - this.fullBar.off(); - this.selBar.off(); - this.ticks.off(); - }, - - /** - * onStart event handler - * - * @param {?Object} pointer The jqLite wrapped DOM element; if null, the closest handle is used - * @param {?string} ref The name of the handle being changed; if null, the closest handle's value is modified - * @param {Event} event The event - * @returns {undefined} - */ - onStart: function(pointer, ref, event) { - var ehMove, ehEnd, - eventNames = this.getEventNames(event); - - event.stopPropagation(); - event.preventDefault(); - - // We have to do this in case the HTML where the sliders are on - // have been animated into view. - this.calcViewDimensions(); - - if (pointer) { - this.tracking = ref; - } else { - pointer = this.getNearestHandle(event); - this.tracking = pointer === this.minH ? 'lowValue' : 'highValue'; - } - pointer.addClass('rz-active'); + if (changedTouches && !touchForThisSlider) { + return + } - if (this.options.keyboardSupport) - this.focusElement(pointer); + var newPos = this.getEventPosition( + event, + touchForThisSlider ? touchForThisSlider.identifier : undefined + ), + newValue, + ceilValue = this.options.rightToLeft + ? this.minValue + : this.maxValue, + flrValue = this.options.rightToLeft ? this.maxValue : this.minValue + + if (newPos <= 0) { + newValue = flrValue + } else if (newPos >= this.maxPos) { + newValue = ceilValue + } else { + newValue = this.positionToValue(newPos) + if (fromTick && angular.isNumber(this.options.showTicks)) + newValue = this.roundStep(newValue, this.options.showTicks) + else newValue = this.roundStep(newValue) + } + this.positionTrackingHandle(newValue) + }, + + /** + * onEnd event handler + * + * @param {Event} event The event + * @param {Function} ehMove The bound move event handler + * @returns {undefined} + */ + onEnd: function(ehMove, event) { + this.moving = false + if (!this.options.disableAnimation) { + this.sliderElem.removeClass('noanimate') + } + var changedTouches = this.getEventAttr(event, 'changedTouches') + if (changedTouches && changedTouches[0].identifier !== this.touchId) { + return + } + this.isDragging = false + this.touchId = null - ehMove = angular.bind(this, this.dragging.active ? this.onDragMove : this.onMove, pointer); - ehEnd = angular.bind(this, this.onEnd, ehMove); + if (!this.options.keyboardSupport) { + this.minH.removeClass('rz-active') + this.maxH.removeClass('rz-active') + this.tracking = '' + } + this.dragging.active = false + + var eventName = this.getEventNames(event) + $document.off(eventName.moveEvent, ehMove) + $document.off(eventName.endEvent, this.endHandlerToBeRemovedOnEnd) + this.endHandlerToBeRemovedOnEnd = null + this.callOnEnd() + }, + + onTickClick: function(pointer, event) { + this.onMove(pointer, event, true) + }, + + onPointerFocus: function(pointer, ref) { + this.tracking = ref + pointer.one('blur', angular.bind(this, this.onPointerBlur, pointer)) + pointer.on('keydown', angular.bind(this, this.onKeyboardEvent)) + pointer.on('keyup', angular.bind(this, this.onKeyUp)) + this.firstKeyDown = true + pointer.addClass('rz-active') + + this.currentFocusElement = { + pointer: pointer, + ref: ref, + } + }, + + onKeyUp: function() { + this.firstKeyDown = true + this.callOnEnd() + }, + + onPointerBlur: function(pointer) { + pointer.off('keydown') + pointer.off('keyup') + pointer.removeClass('rz-active') + if (!this.isDragging) { + this.tracking = '' + this.currentFocusElement = null + } + }, + + /** + * Skip restricted range function when arrow keys use + * + * @param {number} currentValue value of the slider + * @param {number} key arrow key used + * + * @returns {number} currentValue value of the slider + */ - $document.on(eventNames.moveEvent, ehMove); - $document.one(eventNames.endEvent, ehEnd); - this.callOnStart(); - }, + skipRestrictedRanges: function(key, currentValue) { + if ( + this.options.restrictedRange && + Array.isArray(this.options.restrictedRange) + ) { + for (var i in this.options.restrictedRange) { + var range = this.options.restrictedRange[i] + // if it first or last value + if ( + (range.from === 0 && + currentValue === 0 && + [37, 40].includes(key)) || // LEFT or DOWN + (range.to >= + this.options.restrictedRange[ + this.options.restrictedRange.length - 1 + ].to && + currentValue >= + this.options.restrictedRange[ + this.options.restrictedRange.length - 1 + ].to && + [38, 39].includes(key)) // UP or RIGHT + ) { + return currentValue + } + if (range.to > currentValue && currentValue > range.from) { + if ( + Math.abs(range.to - currentValue) > + Math.abs(range.from - currentValue) + ) { + currentValue = range.to + } else { + currentValue = range.from + } + } + } + } - /** - * onMove event handler - * - * @param {jqLite} pointer - * @param {Event} event The event - * @param {boolean} fromTick if the event occured on a tick or not - * @returns {undefined} - */ - onMove: function(pointer, event, fromTick) { - var newOffset = this.getEventPosition(event), - newValue, - ceilValue = this.options.rightToLeft ? this.minValue : this.maxValue, - flrValue = this.options.rightToLeft ? this.maxValue : this.minValue; - - if (newOffset <= 0) { - newValue = flrValue; - } else if (newOffset >= this.maxPos) { - newValue = ceilValue; - } else { - newValue = this.offsetToValue(newOffset); - if (fromTick && angular.isNumber(this.options.showTicks)) - newValue = this.roundStep(newValue, this.options.showTicks); - else - newValue = this.roundStep(newValue); - } - this.positionTrackingHandle(newValue); - }, + return currentValue + }, - /** - * onEnd event handler - * - * @param {Event} event The event - * @param {Function} ehMove The the bound move event handler - * @returns {undefined} - */ - onEnd: function(ehMove, event) { - var moveEventName = this.getEventNames(event).moveEvent; - - if (!this.options.keyboardSupport) { - this.minH.removeClass('rz-active'); - this.maxH.removeClass('rz-active'); - this.tracking = ''; - } - this.dragging.active = false; - - $document.off(moveEventName, ehMove); - this.callOnEnd(); - }, - - onTickClick: function(pointer, event) { - this.onMove(pointer, event, true); - }, - - onPointerFocus: function(pointer, ref) { - this.tracking = ref; - pointer.one('blur', angular.bind(this, this.onPointerBlur, pointer)); - pointer.on('keydown', angular.bind(this, this.onKeyboardEvent)); - pointer.on('keyup', angular.bind(this, this.onKeyUp)); - this.firstKeyDown = true; - pointer.addClass('rz-active'); - - this.currentFocusElement = { - pointer: pointer, - ref: ref - }; - }, - - onKeyUp: function() { - this.firstKeyDown = true; - this.callOnEnd(); - }, - - onPointerBlur: function(pointer) { - pointer.off('keydown'); - pointer.off('keyup'); - this.tracking = ''; - pointer.removeClass('rz-active'); - this.currentFocusElement = null - }, + /** + * Key actions helper function + * + * @param {number} currentValue value of the slider + * + * @returns {?Object} action value mappings + */ + getKeyActions: function(currentValue) { + var increaseStep = currentValue + this.step, + decreaseStep = currentValue - this.step, + increasePage = currentValue + this.valueRange / 10, + decreasePage = currentValue - this.valueRange / 10 + + if (this.options.reversedControls) { + increaseStep = currentValue - this.step + decreaseStep = currentValue + this.step + increasePage = currentValue - this.valueRange / 10 + decreasePage = currentValue + this.valueRange / 10 + } - /** - * Key actions helper function - * - * @param {number} currentValue value of the slider - * - * @returns {?Object} action value mappings - */ - getKeyActions: function(currentValue) { - var increaseStep = currentValue + this.step, - decreaseStep = currentValue - this.step, - increasePage = currentValue + this.valueRange / 10, - decreasePage = currentValue - this.valueRange / 10; - - //Left to right default actions - var actions = { - 'UP': increaseStep, - 'DOWN': decreaseStep, - 'LEFT': decreaseStep, - 'RIGHT': increaseStep, - 'PAGEUP': increasePage, - 'PAGEDOWN': decreasePage, - 'HOME': this.minValue, - 'END': this.maxValue - }; - //right to left means swapping right and left arrows - if (this.options.rightToLeft) { - actions.LEFT = increaseStep; - actions.RIGHT = decreaseStep; - // right to left and vertical means we also swap up and down - if (this.options.vertical) { - actions.UP = decreaseStep; - actions.DOWN = increaseStep; + //Left to right default actions + var actions = { + UP: increaseStep, + DOWN: decreaseStep, + LEFT: decreaseStep, + RIGHT: increaseStep, + PAGEUP: increasePage, + PAGEDOWN: decreasePage, + HOME: this.options.reversedControls ? this.maxValue : this.minValue, + END: this.options.reversedControls ? this.minValue : this.maxValue, + } + //right to left means swapping right and left arrows + if (this.options.rightToLeft) { + actions.LEFT = increaseStep + actions.RIGHT = decreaseStep + // right to left and vertical means we also swap up and down + if (this.options.vertical) { + actions.UP = decreaseStep + actions.DOWN = increaseStep + } + } + return actions + }, + + onKeyboardEvent: function(event) { + var keyCode = event.keyCode || event.which + var currentValue = this[this.tracking] + var keys = { + 38: 'UP', + 40: 'DOWN', + 37: 'LEFT', + 39: 'RIGHT', + 33: 'PAGEUP', + 34: 'PAGEDOWN', + 36: 'HOME', + 35: 'END', + }, + actions = this.getKeyActions(currentValue), + key = keys[keyCode], + action = actions[key] + if (action == null || this.tracking === '') return + event.preventDefault() + + if (this.firstKeyDown) { + this.firstKeyDown = false + this.callOnStart() } - } - return actions; - }, - - onKeyboardEvent: function(event) { - var currentValue = this[this.tracking], - keyCode = event.keyCode || event.which, - keys = { - 38: 'UP', - 40: 'DOWN', - 37: 'LEFT', - 39: 'RIGHT', - 33: 'PAGEUP', - 34: 'PAGEDOWN', - 36: 'HOME', - 35: 'END' - }, - actions = this.getKeyActions(currentValue), - key = keys[keyCode], - action = actions[key]; - if (action == null || this.tracking === '') return; - event.preventDefault(); - - if (this.firstKeyDown) { - this.firstKeyDown = false; - this.callOnStart(); - } - var self = this; - $timeout(function() { - var newValue = self.roundStep(self.sanitizeValue(action)); - if (!self.options.draggableRangeOnly) { - self.positionTrackingHandle(newValue); - } - else { - var difference = self.highValue - self.lowValue, - newMinValue, newMaxValue; - if (self.tracking === 'lowValue') { - newMinValue = newValue; - newMaxValue = newValue + difference; - if (newMaxValue > self.maxValue) { - newMaxValue = self.maxValue; - newMinValue = newMaxValue - difference; - } + var self = this + $timeout(function() { + var newValue = self.roundStep(self.sanitizeValue(action)) + newValue = self.options.skipRestrictedRangesWithArrowKeys + ? self.skipRestrictedRanges(keyCode, newValue) + : newValue + if (!self.options.draggableRangeOnly) { + self.positionTrackingHandle(newValue) } else { - newMaxValue = newValue; - newMinValue = newValue - difference; - if (newMinValue < self.minValue) { - newMinValue = self.minValue; - newMaxValue = newMinValue + difference; + var difference = self.highValue - self.lowValue, + newMinValue, + newMaxValue + if (self.tracking === 'lowValue') { + newMinValue = newValue + newMaxValue = newValue + difference + if (newMaxValue > self.maxValue) { + newMaxValue = self.maxValue + newMinValue = newMaxValue - difference + } + } else { + newMaxValue = newValue + newMinValue = newValue - difference + if (newMinValue < self.minValue) { + newMinValue = self.minValue + newMaxValue = newMinValue + difference + } } + self.positionTrackingBar(newMinValue, newMaxValue) } - self.positionTrackingBar(newMinValue, newMaxValue); + }) + }, + + /** + * onDragStart event handler + * + * Handles dragging of the middle bar. + * + * @param {Object} pointer The jqLite wrapped DOM element + * @param {string} ref One of the refLow, refHigh values + * @param {Event} event The event + * @returns {undefined} + */ + onDragStart: function(pointer, ref, event) { + var position = this.getEventPosition(event) + this.dragging = { + active: true, + value: this.positionToValue(position), + difference: this.highValue - this.lowValue, + lowLimit: this.options.rightToLeft + ? this.minH.rzsp - position + : position - this.minH.rzsp, + highLimit: this.options.rightToLeft + ? position - this.maxH.rzsp + : this.maxH.rzsp - position, } - }); - }, - - /** - * onDragStart event handler - * - * Handles dragging of the middle bar. - * - * @param {Object} pointer The jqLite wrapped DOM element - * @param {string} ref One of the refLow, refHigh values - * @param {Event} event The event - * @returns {undefined} - */ - onDragStart: function(pointer, ref, event) { - var offset = this.getEventPosition(event); - this.dragging = { - active: true, - value: this.offsetToValue(offset), - difference: this.highValue - this.lowValue, - lowLimit: this.options.rightToLeft ? this.minH.rzsp - offset : offset - this.minH.rzsp, - highLimit: this.options.rightToLeft ? offset - this.maxH.rzsp : this.maxH.rzsp - offset - }; - - this.onStart(pointer, ref, event); - }, - /** - * getValue helper function - * - * gets max or min value depending on whether the newOffset is outOfBounds above or below the bar and rightToLeft - * - * @param {string} type 'max' || 'min' The value we are calculating - * @param {number} newOffset The new offset - * @param {boolean} outOfBounds Is the new offset above or below the max/min? - * @param {boolean} isAbove Is the new offset above the bar if out of bounds? - * - * @returns {number} - */ - getValue: function(type, newOffset, outOfBounds, isAbove) { - var isRTL = this.options.rightToLeft, - value = null; - - if (type === 'min') { - if (outOfBounds) { - if (isAbove) { - value = isRTL ? this.minValue : this.maxValue - this.dragging.difference; + this.onStart(pointer, ref, event) + }, + + /** + * getValue helper function + * + * gets max or min value depending on whether the newPos is outOfBounds above or below the bar and rightToLeft + * + * @param {string} type 'max' || 'min' The value we are calculating + * @param {number} newPos The new position + * @param {boolean} outOfBounds Is the new position above or below the max/min? + * @param {boolean} isAbove Is the new position above the bar if out of bounds? + * + * @returns {number} + */ + getValue: function(type, newPos, outOfBounds, isAbove) { + var isRTL = this.options.rightToLeft, + value = null + + if (type === 'min') { + if (outOfBounds) { + if (isAbove) { + value = isRTL + ? this.minValue + : this.maxValue - this.dragging.difference + } else { + value = isRTL + ? this.maxValue - this.dragging.difference + : this.minValue + } } else { - value = isRTL ? this.maxValue - this.dragging.difference : this.minValue; + value = isRTL + ? this.positionToValue(newPos + this.dragging.lowLimit) + : this.positionToValue(newPos - this.dragging.lowLimit) } } else { - value = isRTL ? this.offsetToValue(newOffset + this.dragging.lowLimit) : this.offsetToValue(newOffset - this.dragging.lowLimit) - } - } else { - if (outOfBounds) { - if (isAbove) { - value = isRTL ? this.minValue + this.dragging.difference : this.maxValue; + if (outOfBounds) { + if (isAbove) { + value = isRTL + ? this.minValue + this.dragging.difference + : this.maxValue + } else { + value = isRTL + ? this.maxValue + : this.minValue + this.dragging.difference + } } else { - value = isRTL ? this.maxValue : this.minValue + this.dragging.difference; + if (isRTL) { + value = + this.positionToValue(newPos + this.dragging.lowLimit) + + this.dragging.difference + } else { + value = + this.positionToValue(newPos - this.dragging.lowLimit) + + this.dragging.difference + } } + } + return this.roundStep(value) + }, + + /** + * onDragMove event handler + * + * Handles dragging of the middle bar. + * + * @param {jqLite} pointer + * @param {Event} event The event + * @returns {undefined} + */ + onDragMove: function(pointer, event) { + if (!this.options.disableAnimation) { + if (this.moving) { + this.sliderElem.addClass('noanimate') + } + } + this.moving = true + var newPos = this.getEventPosition(event), + newMinValue, + newMaxValue, + ceilLimit, + flrLimit, + isUnderFlrLimit, + isOverCeilLimit, + flrH, + ceilH + + if (this.options.rightToLeft) { + ceilLimit = this.dragging.lowLimit + flrLimit = this.dragging.highLimit + flrH = this.maxH + ceilH = this.minH + } else { + ceilLimit = this.dragging.highLimit + flrLimit = this.dragging.lowLimit + flrH = this.minH + ceilH = this.maxH + } + isUnderFlrLimit = newPos <= flrLimit + isOverCeilLimit = newPos >= this.maxPos - ceilLimit + + if (isUnderFlrLimit) { + if (flrH.rzsp === 0) return + newMinValue = this.getValue('min', newPos, true, false) + newMaxValue = this.getValue('max', newPos, true, false) + } else if (isOverCeilLimit) { + if (ceilH.rzsp === this.maxPos) return + newMaxValue = this.getValue('max', newPos, true, true) + newMinValue = this.getValue('min', newPos, true, true) } else { - if (isRTL) { - value = this.offsetToValue(newOffset + this.dragging.lowLimit) + this.dragging.difference + newMinValue = this.getValue('min', newPos, false) + newMaxValue = this.getValue('max', newPos, false) + } + this.positionTrackingBar(newMinValue, newMaxValue) + }, + + /** + * Set the new value and position for the entire bar + * + * @param {number} newMinValue the new minimum value + * @param {number} newMaxValue the new maximum value + */ + positionTrackingBar: function(newMinValue, newMaxValue) { + if ( + this.options.minLimit != null && + newMinValue < this.options.minLimit + ) { + newMinValue = this.options.minLimit + newMaxValue = newMinValue + this.dragging.difference + } + if ( + this.options.maxLimit != null && + newMaxValue > this.options.maxLimit + ) { + newMaxValue = this.options.maxLimit + newMinValue = newMaxValue - this.dragging.difference + } + + this.lowValue = newMinValue + this.highValue = newMaxValue + this.applyLowValue() + if (this.range) this.applyHighValue() + this.applyModel(true) + this.updateHandles('lowValue', this.valueToPosition(newMinValue)) + this.updateHandles('highValue', this.valueToPosition(newMaxValue)) + }, + + /** + * Set the new value and position to the current tracking handle + * + * @param {number} newValue new model value + */ + positionTrackingHandle: function(newValue) { + var valueChanged = false + newValue = this.applyMinMaxLimit(newValue) + newValue = this.applyRestrictedRange(newValue) + if (this.range) { + if (this.options.pushRange) { + newValue = this.applyPushRange(newValue) + valueChanged = true } else { - value = this.offsetToValue(newOffset - this.dragging.lowLimit) + this.dragging.difference; + if (this.options.noSwitching) { + if (this.tracking === 'lowValue' && newValue > this.highValue) + newValue = this.applyMinMaxRange(this.highValue) + else if ( + this.tracking === 'highValue' && + newValue < this.lowValue + ) + newValue = this.applyMinMaxRange(this.lowValue) + } + newValue = this.applyMinMaxRange(newValue) + /* This is to check if we need to switch the min and max handles */ + if (this.tracking === 'lowValue' && newValue > this.highValue) { + this.lowValue = this.highValue + this.applyLowValue() + this.applyModel() + this.updateHandles(this.tracking, this.maxH.rzsp) + this.updateAriaAttributes() + this.tracking = 'highValue' + this.minH.removeClass('rz-active') + this.maxH.addClass('rz-active') + if (this.options.keyboardSupport) this.focusElement(this.maxH) + valueChanged = true + } else if ( + this.tracking === 'highValue' && + newValue < this.lowValue + ) { + this.highValue = this.lowValue + this.applyHighValue() + this.applyModel() + this.updateHandles(this.tracking, this.minH.rzsp) + this.updateAriaAttributes() + this.tracking = 'lowValue' + this.maxH.removeClass('rz-active') + this.minH.addClass('rz-active') + if (this.options.keyboardSupport) this.focusElement(this.minH) + valueChanged = true + } } } - } - return this.roundStep(value); - }, - - /** - * onDragMove event handler - * - * Handles dragging of the middle bar. - * - * @param {jqLite} pointer - * @param {Event} event The event - * @returns {undefined} - */ - onDragMove: function(pointer, event) { - var newOffset = this.getEventPosition(event), - newMinValue, newMaxValue, - ceilLimit, flrLimit, - isUnderFlrLimit, isOverCeilLimit, - flrH, ceilH; - - if (this.options.rightToLeft) { - ceilLimit = this.dragging.lowLimit; - flrLimit = this.dragging.highLimit; - flrH = this.maxH; - ceilH = this.minH; - } else { - ceilLimit = this.dragging.highLimit; - flrLimit = this.dragging.lowLimit; - flrH = this.minH; - ceilH = this.maxH; - } - isUnderFlrLimit = newOffset <= flrLimit; - isOverCeilLimit = newOffset >= this.maxPos - ceilLimit; - - if (isUnderFlrLimit) { - if (flrH.rzsp === 0) - return; - newMinValue = this.getValue('min', newOffset, true, false); - newMaxValue = this.getValue('max', newOffset, true, false); - } else if (isOverCeilLimit) { - if (ceilH.rzsp === this.maxPos) - return; - newMaxValue = this.getValue('max', newOffset, true, true); - newMinValue = this.getValue('min', newOffset, true, true); - } else { - newMinValue = this.getValue('min', newOffset, false); - newMaxValue = this.getValue('max', newOffset, false); - } - this.positionTrackingBar(newMinValue, newMaxValue); - }, - /** - * Set the new value and offset for the entire bar - * - * @param {number} newMinValue the new minimum value - * @param {number} newMaxValue the new maximum value - */ - positionTrackingBar: function(newMinValue, newMaxValue) { - - if (this.options.minLimit != null && newMinValue < this.options.minLimit) { - newMinValue = this.options.minLimit; - newMaxValue = newMinValue + this.dragging.difference; - } - if (this.options.maxLimit != null && newMaxValue > this.options.maxLimit) { - newMaxValue = this.options.maxLimit; - newMinValue = newMaxValue - this.dragging.difference; - } - - this.lowValue = newMinValue; - this.highValue = newMaxValue; - this.applyLowValue(); - if (this.range) - this.applyHighValue(); - this.applyModel(); - this.updateHandles('lowValue', this.valueToOffset(newMinValue)); - this.updateHandles('highValue', this.valueToOffset(newMaxValue)); - }, + if (this[this.tracking] !== newValue) { + this[this.tracking] = newValue + if (this.tracking === 'lowValue') this.applyLowValue() + else this.applyHighValue() + this.applyModel() + this.updateHandles(this.tracking, this.valueToPosition(newValue)) + this.updateAriaAttributes() + valueChanged = true + } - /** - * Set the new value and offset to the current tracking handle - * - * @param {number} newValue new model value - */ - positionTrackingHandle: function(newValue) { - var valueChanged = false; - - newValue = this.applyMinMaxLimit(newValue); - if (this.range) { - if (this.options.pushRange) { - newValue = this.applyPushRange(newValue); - valueChanged = true; - } - else { - if (this.options.noSwitching) { - if (this.tracking === 'lowValue' && newValue > this.highValue) - newValue = this.applyMinMaxRange(this.highValue); - else if (this.tracking === 'highValue' && newValue < this.lowValue) - newValue = this.applyMinMaxRange(this.lowValue); + if (valueChanged) this.applyModel(true) + }, + + applyMinMaxLimit: function(newValue) { + if (this.options.minLimit != null && newValue < this.options.minLimit) + return this.options.minLimit + if (this.options.maxLimit != null && newValue > this.options.maxLimit) + return this.options.maxLimit + return newValue + }, + + applyMinMaxRange: function(newValue) { + var oppositeValue = + this.tracking === 'lowValue' ? this.highValue : this.lowValue, + difference = Math.abs(newValue - oppositeValue) + if (this.options.minRange != null) { + if (difference < this.options.minRange) { + if (this.tracking === 'lowValue') + return this.highValue - this.options.minRange + else return this.lowValue + this.options.minRange } - newValue = this.applyMinMaxRange(newValue); - /* This is to check if we need to switch the min and max handles */ - if (this.tracking === 'lowValue' && newValue > this.highValue) { - this.lowValue = this.highValue; - this.applyLowValue(); - this.updateHandles(this.tracking, this.maxH.rzsp); - this.updateAriaAttributes(); - this.tracking = 'highValue'; - this.minH.removeClass('rz-active'); - this.maxH.addClass('rz-active'); - if (this.options.keyboardSupport) - this.focusElement(this.maxH); - valueChanged = true; + } + if (this.options.maxRange != null) { + if (difference > this.options.maxRange) { + if (this.tracking === 'lowValue') + return this.highValue - this.options.maxRange + else return this.lowValue + this.options.maxRange } - else if (this.tracking === 'highValue' && newValue < this.lowValue) { - this.highValue = this.lowValue; - this.applyHighValue(); - this.updateHandles(this.tracking, this.minH.rzsp); - this.updateAriaAttributes(); - this.tracking = 'lowValue'; - this.maxH.removeClass('rz-active'); - this.minH.addClass('rz-active'); - if (this.options.keyboardSupport) - this.focusElement(this.minH); - valueChanged = true; + } + return newValue + }, + + applyRestrictedRange: function(newValue) { + for (var i in this.options.restrictedRange) { + if ( + this.options.restrictedRange[i] != null && + newValue > this.options.restrictedRange[i].from && + newValue < this.options.restrictedRange[i].to + ) { + var halfWidth = + (this.options.restrictedRange[i].to - + this.options.restrictedRange[i].from) / + 2 + if (this.tracking === 'lowValue') { + return newValue > + this.options.restrictedRange[i].from + halfWidth + ? this.options.restrictedRange[i].to + : this.options.restrictedRange[i].from + } + if (this.tracking === 'highValue') { + return newValue < this.options.restrictedRange[i].to - halfWidth + ? this.options.restrictedRange[i].from + : this.options.restrictedRange[i].to + } } } - } - - if (this[this.tracking] !== newValue) { - this[this.tracking] = newValue; - if (this.tracking === 'lowValue') - this.applyLowValue(); - else - this.applyHighValue(); - this.updateHandles(this.tracking, this.valueToOffset(newValue)); - this.updateAriaAttributes(); - valueChanged = true; - } - if (valueChanged) - this.applyModel(); - }, - - applyMinMaxLimit: function(newValue) { - if (this.options.minLimit != null && newValue < this.options.minLimit) - return this.options.minLimit; - if (this.options.maxLimit != null && newValue > this.options.maxLimit) - return this.options.maxLimit; - return newValue; - }, - - applyMinMaxRange: function(newValue) { - var oppositeValue = this.tracking === 'lowValue' ? this.highValue : this.lowValue, - difference = Math.abs(newValue - oppositeValue); - if (this.options.minRange != null) { - if (difference < this.options.minRange) { - if (this.tracking === 'lowValue') - return this.highValue - this.options.minRange; - else - return this.lowValue + this.options.minRange; - } - } - if (this.options.maxRange != null) { - if (difference > this.options.maxRange) { - if (this.tracking === 'lowValue') - return this.highValue - this.options.maxRange; - else - return this.lowValue + this.options.maxRange; + return newValue + }, + + applyPushRange: function(newValue) { + var difference = + this.tracking === 'lowValue' + ? this.highValue - newValue + : newValue - this.lowValue, + minRange = + this.options.minRange !== null + ? this.options.minRange + : this.options.step, + maxRange = this.options.maxRange + // if smaller than minRange + if (difference < minRange) { + if (this.tracking === 'lowValue') { + this.highValue = Math.min(newValue + minRange, this.maxValue) + newValue = this.highValue - minRange + this.applyHighValue() + this.updateHandles( + 'highValue', + this.valueToPosition(this.highValue) + ) + } else { + this.lowValue = Math.max(newValue - minRange, this.minValue) + newValue = this.lowValue + minRange + this.applyLowValue() + this.updateHandles( + 'lowValue', + this.valueToPosition(this.lowValue) + ) + } + this.updateAriaAttributes() + } else if (maxRange !== null && difference > maxRange) { + // if greater than maxRange + if (this.tracking === 'lowValue') { + this.highValue = newValue + maxRange + this.applyHighValue() + this.updateHandles( + 'highValue', + this.valueToPosition(this.highValue) + ) + } else { + this.lowValue = newValue - maxRange + this.applyLowValue() + this.updateHandles( + 'lowValue', + this.valueToPosition(this.lowValue) + ) + } + this.updateAriaAttributes() } - } - return newValue; - }, - - applyPushRange: function(newValue) { - var difference = this.tracking === 'lowValue' ? this.highValue - newValue : newValue - this.lowValue, - range = this.options.minRange !== null ? this.options.minRange : this.options.step; - if (difference < range) { - if (this.tracking === 'lowValue') { - this.highValue = Math.min(newValue + range, this.maxValue); - newValue = this.highValue - range; - this.applyHighValue(); - this.updateHandles('highValue', this.valueToOffset(this.highValue)); - } - else { - this.lowValue = Math.max(newValue - range, this.minValue); - newValue = this.lowValue + range; - this.applyLowValue(); - this.updateHandles('lowValue', this.valueToOffset(this.lowValue)); - } - this.updateAriaAttributes(); - } - return newValue; - }, - - /** - * Apply the model values using scope.$apply. - * We wrap it with the internalChange flag to avoid the watchers to be called - */ - applyModel: function() { - this.internalChange = true; - this.scope.$apply(); - this.callOnChange(); - this.internalChange = false; - }, + return newValue + }, - /** - * Call the onStart callback if defined - * The callback call is wrapped in a $evalAsync to ensure that its result will be applied to the scope. - * - * @returns {undefined} - */ - callOnStart: function() { - if (this.options.onStart) { - var self = this, - pointerType = this.tracking === 'lowValue' ? 'min' : 'max'; - this.scope.$evalAsync(function() { - self.options.onStart(self.options.id, self.scope.rzSliderModel, self.scope.rzSliderHigh, pointerType); - }); - } - }, + /** + * Apply the model values using scope.$apply. + * We wrap it with the internalChange flag to avoid the watchers to be called + */ + applyModel: function(callOnChange) { + this.internalChange = true + this.scope.$apply() + callOnChange && this.callOnChange() + this.internalChange = false + }, + + /** + * Call the onStart callback if defined + * The callback call is wrapped in a $evalAsync to ensure that its result will be applied to the scope. + * + * @returns {undefined} + */ + callOnStart: function() { + if (this.options.onStart) { + var self = this, + pointerType = this.tracking === 'lowValue' ? 'min' : 'max' + this.scope.$evalAsync(function() { + self.options.onStart( + self.options.id, + self.scope.rzSliderModel, + self.scope.rzSliderHigh, + pointerType + ) + }) + } + }, - /** - * Call the onChange callback if defined - * The callback call is wrapped in a $evalAsync to ensure that its result will be applied to the scope. - * - * @returns {undefined} - */ - callOnChange: function() { - if (this.options.onChange) { - var self = this, - pointerType = this.tracking === 'lowValue' ? 'min' : 'max'; - this.scope.$evalAsync(function() { - self.options.onChange(self.options.id, self.scope.rzSliderModel, self.scope.rzSliderHigh, pointerType); - }); - } - }, + /** + * Call the onChange callback if defined + * The callback call is wrapped in a $evalAsync to ensure that its result will be applied to the scope. + * + * @returns {undefined} + */ + callOnChange: function() { + if (this.options.onChange) { + var self = this, + pointerType = this.tracking === 'lowValue' ? 'min' : 'max' + this.scope.$evalAsync(function() { + self.options.onChange( + self.options.id, + self.scope.rzSliderModel, + self.scope.rzSliderHigh, + pointerType + ) + }) + } + }, - /** - * Call the onEnd callback if defined - * The callback call is wrapped in a $evalAsync to ensure that its result will be applied to the scope. - * - * @returns {undefined} - */ - callOnEnd: function() { - if (this.options.onEnd) { - var self = this, - pointerType = this.tracking === 'lowValue' ? 'min' : 'max'; - this.scope.$evalAsync(function() { - self.options.onEnd(self.options.id, self.scope.rzSliderModel, self.scope.rzSliderHigh, pointerType); - }); - } - this.scope.$emit('slideEnded'); + /** + * Call the onEnd callback if defined + * The callback call is wrapped in a $evalAsync to ensure that its result will be applied to the scope. + * + * @returns {undefined} + */ + callOnEnd: function() { + if (this.options.onEnd) { + var self = this, + pointerType = this.tracking === 'lowValue' ? 'min' : 'max' + this.scope.$evalAsync(function() { + self.options.onEnd( + self.options.id, + self.scope.rzSliderModel, + self.scope.rzSliderHigh, + pointerType + ) + }) + } + this.scope.$emit('slideEnded') + }, } - }; - - return Slider; - }) - - .directive('rzslider', function(RzSlider) { - 'use strict'; - - return { - restrict: 'AE', - replace: true, - scope: { - rzSliderModel: '=?', - rzSliderHigh: '=?', - rzSliderOptions: '&?', - rzSliderTplUrl: '@' - }, - /** - * Return template URL - * - * @param {jqLite} elem - * @param {Object} attrs - * @return {string} - */ - templateUrl: function(elem, attrs) { - //noinspection JSUnresolvedVariable - return attrs.rzSliderTplUrl || 'rzSliderTpl.html'; - }, - - link: function(scope, elem) { - scope.slider = new RzSlider(scope, elem); //attach on scope so we can test it + return Slider + }) + .directive('rzslider', function(RzSlider) { + 'use strict' + + return { + restrict: 'AE', + replace: true, + scope: { + rzSliderModel: '=?', + rzSliderHigh: '=?', + rzSliderOptions: '&?', + rzSliderTplUrl: '@', + }, + + /** + * Return template URL + * + * @param {jqLite} elem + * @param {Object} attrs + * @return {string} + */ + templateUrl: function(elem, attrs) { + //noinspection JSUnresolvedVariable + return attrs.rzSliderTplUrl || 'rzSliderTpl.html' + }, + + link: function(scope, elem) { + scope.slider = new RzSlider(scope, elem) //attach on scope so we can test it + }, } - }; - }); + }) // IDE assist @@ -2188,7 +2858,7 @@ /** * @name jqLite * - * @property {number|undefined} rzsp rzslider label position offset + * @property {number|undefined} rzsp rzslider label position position * @property {number|undefined} rzsd rzslider element dimension * @property {string|undefined} rzsv rzslider label value/text * @property {Function} css @@ -2211,4 +2881,4 @@ /*templateReplacement*/ return module.name -})); +}) diff --git a/src/rzslider.less b/src/rzslider.less index 7c4217d..171bdfa 100644 --- a/src/rzslider.less +++ b/src/rzslider.less @@ -2,7 +2,8 @@ * Angular JS slider directive * * (c) Rafal Zajac - * http://github.com/rzajac/angularjs-slider + * (c) Valentin Hervieu + * http://github.com/angular-slider/angularjs-slider * * Licensed under the MIT license */ @@ -15,11 +16,12 @@ width: 100%; margin: 35px 0 15px 0; vertical-align: middle; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; user-select: none; + &.noanimate * { + transition: none !important; + } + &.with-legend { margin-bottom: @withLegendMargin; } @@ -30,6 +32,18 @@ cursor: not-allowed; background-color: @handleDisabledColor; } + .rz-draggable { + cursor: not-allowed; + } + .rz-selection { + background: @barDisabledFillColor; + } + .rz-tick { + cursor: not-allowed; + &.rz-selected { + background: @barDisabledFillColor; + } + } } span { @@ -47,14 +61,16 @@ .rz-bar-wrapper { left: 0; box-sizing: border-box; - margin-top: -@handleSize / 2; - padding-top: @handleSize / 2; + margin-top: (-@handleSize / 2); + padding-top: (@handleSize / 2); width: 100%; height: @handleSize; z-index: 1; - &.rz-draggable { - cursor: move; - } + transition: all linear @animationDuration; + } + + .rz-draggable { + cursor: move; } .rz-bar { @@ -63,42 +79,56 @@ height: @barDimension; z-index: 1; background: @barNormalColor; - .rounded(@barDimension/2); + .rounded((@barDimension / 2)); + } - &.rz-selection { - z-index: 2; - background: @barFillColor; - .rounded(@barDimension/2); - } + .rz-bar-wrapper.rz-transparent .rz-bar { + background: transparent; + } + .rz-bar-wrapper.rz-left-out-selection .rz-bar { + background: @barLeftOutSelectionColor; + } + .rz-bar-wrapper.rz-right-out-selection .rz-bar { + background: @barRightOutSelectionColor; + } + + .rz-selection { + z-index: 2; + background: @barFillColor; + .rounded((@barDimension / 2)); + transition: background-color linear @animationDuration; + } + + .rz-restricted { + z-index: 3; + background: @restrictedBarColor; + .rounded((@barDimension / 2)); } .rz-pointer { cursor: pointer; width: @handleSize; height: @handleSize; - top: -@handleSize/2 + @barDimension/2; + top: (-@handleSize / 2 + @barDimension / 2); background-color: @handleBgColor; z-index: 3; - .rounded(@handleSize/2); - // -webkit-transition:all linear 0.15s; - // -moz-transition:all linear 0.15s; - // -o-transition:all linear 0.15s; - // transition:all linear 0.15s; + .rounded((@handleSize / 2)); + transition: all linear @animationDuration; &:after { content: ''; width: @handlePointerSize; height: @handlePointerSize; position: absolute; - top: @handleSize/2 - @handlePointerSize/2; - left: @handleSize/2 - @handlePointerSize/2; - .rounded(@handlePointerSize/2); + top: (@handleSize / 2 - @handlePointerSize / 2); + left: (@handleSize / 2 - @handlePointerSize / 2); + .rounded((@handlePointerSize / 2)); background: @handleInnerColor; } &:hover:after { background-color: @handleHoverColor; } - &.rz-active{ + &.rz-active { z-index: 4; &:after { background-color: @handleActiveColor; @@ -108,14 +138,13 @@ .rz-bubble { cursor: default; - bottom: @handleSize/2; + bottom: (@handleSize / 2); padding: @bubblePadding; color: @labelTextColor; - &.rz-selection { - top: @handleSize/2; - } + transition: all linear @animationDuration; &.rz-limit { color: @limitLabelTextColor; + transition: none; } } @@ -125,50 +154,50 @@ height: 0; position: absolute; left: 0; - top: -(@ticksHeight - @barDimension) / 2; + top: (-(@ticksHeight - @barDimension) / 2); margin: 0; - padding: 0 (@handleSize - @ticksWidth) / 2; z-index: 1; list-style: none; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; + } - .rz-tick { - text-align: center; - cursor: pointer; - width: @ticksWidth; - height: @ticksHeight; - background: @ticksColor; - border-radius: 50%; - &.rz-selected { - background: @selectedTicksColor; - } - .rz-tick-value { - position: absolute; - top: @ticksValuePosition; - transform: translate(-50%, 0); - } - .rz-tick-legend { - position: absolute; - top: @ticksLegendPosition; - transform: translate(-50%, 0); - max-width: 50px; - white-space: normal; - } + .rz-ticks-values-under { + .rz-tick-value { + top: auto; + bottom: (@ticksValuePosition - 2); } + } - &.rz-ticks-values-under { - .rz-tick-value { - top: initial; - bottom: @ticksValuePosition - 10; - } + .rz-tick { + text-align: center; + cursor: pointer; + width: @ticksWidth; + height: @ticksHeight; + background: @ticksColor; + border-radius: 50%; + position: absolute; + top: 0; + left: 0; + margin-left: (@handleSize / 2 - @ticksWidth / 2); // for centering + transition: background-color linear @animationDuration; + &.rz-selected { + background: @selectedTicksColor; } } + .rz-tick-value { + position: absolute; + top: @ticksValuePosition; + transform: translate(-50%, 0); + } + + .rz-tick-legend { + position: absolute; + top: @ticksLegendPosition; + transform: translate(-50%, 0); + max-width: 50px; + white-space: normal; + } + &.rz-vertical { position: relative; width: @barDimension; @@ -186,8 +215,8 @@ .rz-bar-wrapper { top: auto; left: 0; - margin: 0 0 0 -@handleSize / 2; - padding: 0 0 0 @handleSize / 2; + margin: 0 0 0 (-@handleSize / 2); + padding: 0 0 0 (@handleSize / 2); height: 100%; width: @handleSize; } @@ -200,54 +229,46 @@ } .rz-pointer { - left: -@handleSize/2 + @barDimension/2 !important; + left: (-@handleSize / 2 + @barDimension / 2) !important; top: auto; bottom: 0; } .rz-bubble { - left: @handleSize/2 !important; + left: (@handleSize / 2) !important; margin-left: 3px; bottom: 0; - &.rz-selection { - left: @handleSize/2 !important; - top: auto; - } } .rz-ticks { height: 100%; width: 0; - left: -(@ticksHeight - @barDimension) / 2; + left: (-(@ticksHeight - @barDimension) / 2); top: 0; - padding: (@handleSize - @ticksWidth) / 2 0; z-index: 1; - -webkit-flex-direction: column-reverse; - -ms-flex-direction: column-reverse; - flex-direction: column-reverse; - - .rz-tick { - vertical-align: middle; - .rz-tick-value { - left: @ticksValuePositionOnVertical; - top: initial; - transform: translate(0, -28%); - } - .rz-tick-legend { - top: initial; - right: @ticksLegendPosition; - transform: translate(0, -28%); - max-width: none; - white-space: nowrap; - } - } - - &.rz-ticks-values-under { - .rz-tick-value { - bottom: initial; - left: initial; - right: @ticksValuePositionOnVertical - 10; - } + } + .rz-tick { + vertical-align: middle; + margin-left: auto; + margin-top: (@handleSize / 2 - @ticksWidth / 2); // for centering + } + .rz-tick-value { + left: @ticksValuePositionOnVertical; + top: auto; + transform: translate(0, -28%); + } + .rz-tick-legend { + top: auto; + right: @ticksLegendPosition; + transform: translate(0, -28%); + max-width: none; + white-space: nowrap; + } + .rz-ticks-values-under { + .rz-tick-value { + bottom: auto; + left: auto; + right: @ticksValuePositionOnVertical; } } } diff --git a/src/variables.less b/src/variables.less index 0deab44..a8422a9 100644 --- a/src/variables.less +++ b/src/variables.less @@ -12,7 +12,11 @@ @handleDisabledColor: #d8e0f3; @limitLabelTextColor: @labelTextColor; @barFillColor: @handleBgColor; +@barDisabledFillColor: #8b91a2; @barNormalColor: #d8e0f3; +@barLeftOutSelectionColor: #df002d; +@barRightOutSelectionColor: #03a688; +@restrictedBarColor: red; @ticksColor: @barNormalColor; @selectedTicksColor: @barFillColor; @@ -20,7 +24,7 @@ @ticksHeight: 10px; @ticksValuePosition: -30px; @ticksLegendPosition: 24px; -@ticksValuePositionOnVertical: 22px; +@ticksValuePositionOnVertical: 24px; @handleSize: 32px; @handlePointerSize: 8px; @@ -28,3 +32,5 @@ @barDimension: 4px; @withLegendMargin: 40px; + +@animationDuration: 0.3s; diff --git a/tests/specs/accessibility-test.js b/tests/specs/accessibility-test.js index 87b492d..ee0c0e0 100644 --- a/tests/specs/accessibility-test.js +++ b/tests/specs/accessibility-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Accessibility - ', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; + var helper, RzSliderOptions, $rootScope, $timeout - beforeEach(module('test-helper')); + beforeEach(module('test-helper')) - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) it('should have accessible horizontal single slider', function() { var sliderConf = { @@ -26,22 +28,22 @@ options: { floor: 0, ceil: 100, - step: 10 - } - }; - helper.createSlider(sliderConf); - expect(helper.slider.minH.attr('role')).to.equal('slider'); - expect(helper.slider.minH.attr('tabindex')).to.equal('0'); - expect(helper.slider.minH.attr('aria-valuenow')).to.equal('10'); - expect(helper.slider.minH.attr('aria-valuetext')).to.equal('10'); - expect(helper.slider.minH.attr('aria-valuemin')).to.equal('0'); - expect(helper.slider.minH.attr('aria-valuemax')).to.equal('100'); - - helper.scope.slider.value = 20; - helper.scope.$digest(); - expect(helper.slider.minH.attr('aria-valuenow')).to.equal('20'); - expect(helper.slider.minH.attr('aria-valuetext')).to.equal('20'); - }); + step: 10, + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.minH.attr('role')).to.equal('slider') + expect(helper.slider.minH.attr('tabindex')).to.equal('0') + expect(helper.slider.minH.attr('aria-valuenow')).to.equal('10') + expect(helper.slider.minH.attr('aria-valuetext')).to.equal('10') + expect(helper.slider.minH.attr('aria-valuemin')).to.equal('0') + expect(helper.slider.minH.attr('aria-valuemax')).to.equal('100') + + helper.scope.slider.value = 20 + helper.scope.$digest() + expect(helper.slider.minH.attr('aria-valuenow')).to.equal('20') + expect(helper.slider.minH.attr('aria-valuetext')).to.equal('20') + }) it('should have accessible vertical single slider', function() { var sliderConf = { @@ -50,23 +52,23 @@ floor: 0, ceil: 100, step: 10, - vertical: true - } - }; - helper.createSlider(sliderConf); - expect(helper.slider.minH.attr('role')).to.equal('slider'); - expect(helper.slider.minH.attr('tabindex')).to.equal('0'); - expect(helper.slider.minH.attr('aria-orientation')).to.equal('vertical'); - expect(helper.slider.minH.attr('aria-valuenow')).to.equal('10'); - expect(helper.slider.minH.attr('aria-valuetext')).to.equal('10'); - expect(helper.slider.minH.attr('aria-valuemin')).to.equal('0'); - expect(helper.slider.minH.attr('aria-valuemax')).to.equal('100'); - - helper.scope.slider.value = 20; - helper.scope.$digest(); - expect(helper.slider.minH.attr('aria-valuenow')).to.equal('20'); - expect(helper.slider.minH.attr('aria-valuetext')).to.equal('20'); - }); + vertical: true, + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.minH.attr('role')).to.equal('slider') + expect(helper.slider.minH.attr('tabindex')).to.equal('0') + expect(helper.slider.minH.attr('aria-orientation')).to.equal('vertical') + expect(helper.slider.minH.attr('aria-valuenow')).to.equal('10') + expect(helper.slider.minH.attr('aria-valuetext')).to.equal('10') + expect(helper.slider.minH.attr('aria-valuemin')).to.equal('0') + expect(helper.slider.minH.attr('aria-valuemax')).to.equal('100') + + helper.scope.slider.value = 20 + helper.scope.$digest() + expect(helper.slider.minH.attr('aria-valuenow')).to.equal('20') + expect(helper.slider.minH.attr('aria-valuetext')).to.equal('20') + }) it('should have accessible horizontal range slider', function() { var sliderConf = { @@ -75,33 +77,33 @@ options: { floor: 0, ceil: 100, - step: 10 - } - }; - helper.createRangeSlider(sliderConf); - expect(helper.slider.minH.attr('role')).to.equal('slider'); - expect(helper.slider.minH.attr('tabindex')).to.equal('0'); - expect(helper.slider.minH.attr('aria-valuenow')).to.equal('10'); - expect(helper.slider.minH.attr('aria-valuetext')).to.equal('10'); - expect(helper.slider.minH.attr('aria-valuemin')).to.equal('0'); - expect(helper.slider.minH.attr('aria-valuemax')).to.equal('100'); - expect(helper.slider.maxH.attr('role')).to.equal('slider'); - expect(helper.slider.maxH.attr('tabindex')).to.equal('0'); - expect(helper.slider.maxH.attr('aria-valuenow')).to.equal('90'); - expect(helper.slider.maxH.attr('aria-valuetext')).to.equal('90'); - expect(helper.slider.maxH.attr('aria-valuemin')).to.equal('0'); - expect(helper.slider.maxH.attr('aria-valuemax')).to.equal('100'); - - helper.scope.slider.min = 20; - helper.scope.$digest(); - expect(helper.slider.minH.attr('aria-valuenow')).to.equal('20'); - expect(helper.slider.minH.attr('aria-valuetext')).to.equal('20'); - - helper.scope.slider.max = 80; - helper.scope.$digest(); - expect(helper.slider.maxH.attr('aria-valuenow')).to.equal('80'); - expect(helper.slider.maxH.attr('aria-valuetext')).to.equal('80'); - }); + step: 10, + }, + } + helper.createRangeSlider(sliderConf) + expect(helper.slider.minH.attr('role')).to.equal('slider') + expect(helper.slider.minH.attr('tabindex')).to.equal('0') + expect(helper.slider.minH.attr('aria-valuenow')).to.equal('10') + expect(helper.slider.minH.attr('aria-valuetext')).to.equal('10') + expect(helper.slider.minH.attr('aria-valuemin')).to.equal('0') + expect(helper.slider.minH.attr('aria-valuemax')).to.equal('100') + expect(helper.slider.maxH.attr('role')).to.equal('slider') + expect(helper.slider.maxH.attr('tabindex')).to.equal('0') + expect(helper.slider.maxH.attr('aria-valuenow')).to.equal('90') + expect(helper.slider.maxH.attr('aria-valuetext')).to.equal('90') + expect(helper.slider.maxH.attr('aria-valuemin')).to.equal('0') + expect(helper.slider.maxH.attr('aria-valuemax')).to.equal('100') + + helper.scope.slider.min = 20 + helper.scope.$digest() + expect(helper.slider.minH.attr('aria-valuenow')).to.equal('20') + expect(helper.slider.minH.attr('aria-valuetext')).to.equal('20') + + helper.scope.slider.max = 80 + helper.scope.$digest() + expect(helper.slider.maxH.attr('aria-valuenow')).to.equal('80') + expect(helper.slider.maxH.attr('aria-valuetext')).to.equal('80') + }) it('should have accessible vertical range slider', function() { var sliderConf = { @@ -111,35 +113,35 @@ floor: 0, ceil: 100, step: 10, - vertical: true - } - }; - helper.createRangeSlider(sliderConf); - expect(helper.slider.minH.attr('role')).to.equal('slider'); - expect(helper.slider.minH.attr('tabindex')).to.equal('0'); - expect(helper.slider.minH.attr('aria-orientation')).to.equal('vertical'); - expect(helper.slider.minH.attr('aria-valuenow')).to.equal('10'); - expect(helper.slider.minH.attr('aria-valuetext')).to.equal('10'); - expect(helper.slider.minH.attr('aria-valuemin')).to.equal('0'); - expect(helper.slider.minH.attr('aria-valuemax')).to.equal('100'); - expect(helper.slider.maxH.attr('role')).to.equal('slider'); - expect(helper.slider.maxH.attr('tabindex')).to.equal('0'); - expect(helper.slider.maxH.attr('aria-orientation')).to.equal('vertical'); - expect(helper.slider.maxH.attr('aria-valuenow')).to.equal('90'); - expect(helper.slider.maxH.attr('aria-valuetext')).to.equal('90'); - expect(helper.slider.maxH.attr('aria-valuemin')).to.equal('0'); - expect(helper.slider.maxH.attr('aria-valuemax')).to.equal('100'); - - helper.scope.slider.min = 20; - helper.scope.$digest(); - expect(helper.slider.minH.attr('aria-valuenow')).to.equal('20'); - expect(helper.slider.minH.attr('aria-valuetext')).to.equal('20'); - - helper.scope.slider.max = 80; - helper.scope.$digest(); - expect(helper.slider.maxH.attr('aria-valuenow')).to.equal('80'); - expect(helper.slider.maxH.attr('aria-valuetext')).to.equal('80'); - }); + vertical: true, + }, + } + helper.createRangeSlider(sliderConf) + expect(helper.slider.minH.attr('role')).to.equal('slider') + expect(helper.slider.minH.attr('tabindex')).to.equal('0') + expect(helper.slider.minH.attr('aria-orientation')).to.equal('vertical') + expect(helper.slider.minH.attr('aria-valuenow')).to.equal('10') + expect(helper.slider.minH.attr('aria-valuetext')).to.equal('10') + expect(helper.slider.minH.attr('aria-valuemin')).to.equal('0') + expect(helper.slider.minH.attr('aria-valuemax')).to.equal('100') + expect(helper.slider.maxH.attr('role')).to.equal('slider') + expect(helper.slider.maxH.attr('tabindex')).to.equal('0') + expect(helper.slider.maxH.attr('aria-orientation')).to.equal('vertical') + expect(helper.slider.maxH.attr('aria-valuenow')).to.equal('90') + expect(helper.slider.maxH.attr('aria-valuetext')).to.equal('90') + expect(helper.slider.maxH.attr('aria-valuemin')).to.equal('0') + expect(helper.slider.maxH.attr('aria-valuemax')).to.equal('100') + + helper.scope.slider.min = 20 + helper.scope.$digest() + expect(helper.slider.minH.attr('aria-valuenow')).to.equal('20') + expect(helper.slider.minH.attr('aria-valuetext')).to.equal('20') + + helper.scope.slider.max = 80 + helper.scope.$digest() + expect(helper.slider.maxH.attr('aria-valuenow')).to.equal('80') + expect(helper.slider.maxH.attr('aria-valuetext')).to.equal('80') + }) it('should have accessible horizontal single slider when keyboardSupport is false', function() { var sliderConf = { @@ -148,22 +150,22 @@ floor: 0, ceil: 100, step: 10, - keyboardSupport: false - } - }; - helper.createSlider(sliderConf); - expect(helper.slider.minH.attr('role')).to.equal('slider'); - expect(helper.slider.minH.attr('tabindex')).to.equal(''); - expect(helper.slider.minH.attr('aria-valuenow')).to.equal('10'); - expect(helper.slider.minH.attr('aria-valuetext')).to.equal('10'); - expect(helper.slider.minH.attr('aria-valuemin')).to.equal('0'); - expect(helper.slider.minH.attr('aria-valuemax')).to.equal('100'); - - helper.scope.slider.value = 20; - helper.scope.$digest(); - expect(helper.slider.minH.attr('aria-valuenow')).to.equal('20'); - expect(helper.slider.minH.attr('aria-valuetext')).to.equal('20'); - }); + keyboardSupport: false, + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.minH.attr('role')).to.equal('slider') + expect(helper.slider.minH.attr('tabindex')).to.equal('') + expect(helper.slider.minH.attr('aria-valuenow')).to.equal('10') + expect(helper.slider.minH.attr('aria-valuetext')).to.equal('10') + expect(helper.slider.minH.attr('aria-valuemin')).to.equal('0') + expect(helper.slider.minH.attr('aria-valuemax')).to.equal('100') + + helper.scope.slider.value = 20 + helper.scope.$digest() + expect(helper.slider.minH.attr('aria-valuenow')).to.equal('20') + expect(helper.slider.minH.attr('aria-valuetext')).to.equal('20') + }) it('should have accessible horizontal range slider when keyboardSupport is false', function() { var sliderConf = { @@ -173,76 +175,174 @@ floor: 0, ceil: 100, step: 10, - keyboardSupport: false - } - }; - helper.createRangeSlider(sliderConf); - expect(helper.slider.minH.attr('role')).to.equal('slider'); - expect(helper.slider.minH.attr('tabindex')).to.equal(''); - expect(helper.slider.minH.attr('aria-valuenow')).to.equal('10'); - expect(helper.slider.minH.attr('aria-valuetext')).to.equal('10'); - expect(helper.slider.minH.attr('aria-valuemin')).to.equal('0'); - expect(helper.slider.minH.attr('aria-valuemax')).to.equal('100'); - expect(helper.slider.maxH.attr('role')).to.equal('slider'); - expect(helper.slider.maxH.attr('tabindex')).to.equal(''); - expect(helper.slider.maxH.attr('aria-valuenow')).to.equal('90'); - expect(helper.slider.maxH.attr('aria-valuetext')).to.equal('90'); - expect(helper.slider.maxH.attr('aria-valuemin')).to.equal('0'); - expect(helper.slider.maxH.attr('aria-valuemax')).to.equal('100'); - - helper.scope.slider.min = 20; - helper.scope.$digest(); - expect(helper.slider.minH.attr('aria-valuenow')).to.equal('20'); - expect(helper.slider.minH.attr('aria-valuetext')).to.equal('20'); - - helper.scope.slider.max = 80; - helper.scope.$digest(); - expect(helper.slider.maxH.attr('aria-valuenow')).to.equal('80'); - expect(helper.slider.maxH.attr('aria-valuetext')).to.equal('80'); - }); + keyboardSupport: false, + }, + } + helper.createRangeSlider(sliderConf) + expect(helper.slider.minH.attr('role')).to.equal('slider') + expect(helper.slider.minH.attr('tabindex')).to.equal('') + expect(helper.slider.minH.attr('aria-valuenow')).to.equal('10') + expect(helper.slider.minH.attr('aria-valuetext')).to.equal('10') + expect(helper.slider.minH.attr('aria-valuemin')).to.equal('0') + expect(helper.slider.minH.attr('aria-valuemax')).to.equal('100') + expect(helper.slider.maxH.attr('role')).to.equal('slider') + expect(helper.slider.maxH.attr('tabindex')).to.equal('') + expect(helper.slider.maxH.attr('aria-valuenow')).to.equal('90') + expect(helper.slider.maxH.attr('aria-valuetext')).to.equal('90') + expect(helper.slider.maxH.attr('aria-valuemin')).to.equal('0') + expect(helper.slider.maxH.attr('aria-valuemax')).to.equal('100') + + helper.scope.slider.min = 20 + helper.scope.$digest() + expect(helper.slider.minH.attr('aria-valuenow')).to.equal('20') + expect(helper.slider.minH.attr('aria-valuetext')).to.equal('20') + + helper.scope.slider.max = 80 + helper.scope.$digest() + expect(helper.slider.maxH.attr('aria-valuenow')).to.equal('80') + expect(helper.slider.maxH.attr('aria-valuetext')).to.equal('80') + }) it('should have accessible slider when values are text', function() { var sliderConf = { value: 'B', options: { - stepsArray: ['A', 'B', 'C'] - } - }; - helper.createSlider(sliderConf); - expect(helper.slider.minH.attr('role')).to.equal('slider'); - expect(helper.slider.minH.attr('tabindex')).to.equal('0'); - expect(helper.slider.minH.attr('aria-valuenow')).to.equal('B'); - expect(helper.slider.minH.attr('aria-valuetext')).to.equal('B'); - expect(helper.slider.minH.attr('aria-valuemin')).to.equal('0'); - expect(helper.slider.minH.attr('aria-valuemax')).to.equal('2'); - - helper.scope.slider.value = 'C'; - helper.scope.$digest(); - expect(helper.slider.minH.attr('aria-valuenow')).to.equal('C'); - expect(helper.slider.minH.attr('aria-valuetext')).to.equal('C'); - }); + stepsArray: ['A', 'B', 'C'], + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.minH.attr('role')).to.equal('slider') + expect(helper.slider.minH.attr('tabindex')).to.equal('0') + expect(helper.slider.minH.attr('aria-valuenow')).to.equal('B') + expect(helper.slider.minH.attr('aria-valuetext')).to.equal('B') + expect(helper.slider.minH.attr('aria-valuemin')).to.equal('0') + expect(helper.slider.minH.attr('aria-valuemax')).to.equal('2') + + helper.scope.slider.value = 'C' + helper.scope.$digest() + expect(helper.slider.minH.attr('aria-valuenow')).to.equal('C') + expect(helper.slider.minH.attr('aria-valuetext')).to.equal('C') + }) it('should have accessible slider when values are text but bindIndexForStepsArray is true', function() { var sliderConf = { value: 1, options: { stepsArray: ['A', 'B', 'C'], - bindIndexForStepsArray: true - } - }; - helper.createSlider(sliderConf); - expect(helper.slider.minH.attr('role')).to.equal('slider'); - expect(helper.slider.minH.attr('tabindex')).to.equal('0'); - expect(helper.slider.minH.attr('aria-valuenow')).to.equal('1'); - expect(helper.slider.minH.attr('aria-valuetext')).to.equal('B'); - expect(helper.slider.minH.attr('aria-valuemin')).to.equal('0'); - expect(helper.slider.minH.attr('aria-valuemax')).to.equal('2'); - - helper.scope.slider.value = 2; - helper.scope.$digest(); - expect(helper.slider.minH.attr('aria-valuenow')).to.equal('2'); - expect(helper.slider.minH.attr('aria-valuetext')).to.equal('C'); - }); - }); -}()); + bindIndexForStepsArray: true, + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.minH.attr('role')).to.equal('slider') + expect(helper.slider.minH.attr('tabindex')).to.equal('0') + expect(helper.slider.minH.attr('aria-valuenow')).to.equal('1') + expect(helper.slider.minH.attr('aria-valuetext')).to.equal('B') + expect(helper.slider.minH.attr('aria-valuemin')).to.equal('0') + expect(helper.slider.minH.attr('aria-valuemax')).to.equal('2') + + helper.scope.slider.value = 2 + helper.scope.$digest() + expect(helper.slider.minH.attr('aria-valuenow')).to.equal('2') + expect(helper.slider.minH.attr('aria-valuetext')).to.equal('C') + }) + + it('should have labelled single slider when option is set', function() { + var sliderConf = { + value: 10, + options: { + floor: 0, + ceil: 100, + step: 10, + ariaLabel: 'test label', + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.minH.attr('aria-label')).to.equal('test label') + }) + + it('should have labelled range slider when option is set', function() { + var sliderConf = { + min: 10, + max: 90, + options: { + floor: 0, + ceil: 100, + step: 10, + ariaLabel: 'test label', + ariaLabelHigh: 'test label high', + }, + } + helper.createRangeSlider(sliderConf) + expect(helper.slider.minH.attr('aria-label')).to.equal('test label') + expect(helper.slider.maxH.attr('aria-label')).to.equal('test label high') + }) + it('should have labelled by id on single slider when option is set', function() { + var sliderConf = { + value: 10, + options: { + floor: 0, + ceil: 100, + step: 10, + ariaLabelledBy: 'testId', + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.minH.attr('aria-labelledby')).to.equal('testId') + }) + + it('should have labelled by id on range slider when option is set', function() { + var sliderConf = { + min: 10, + max: 90, + options: { + floor: 0, + ceil: 100, + step: 10, + ariaLabelledBy: 'testId', + ariaLabelledByHigh: 'testIdHigh', + }, + } + helper.createRangeSlider(sliderConf) + expect(helper.slider.minH.attr('aria-labelledby')).to.equal('testId') + expect(helper.slider.maxH.attr('aria-labelledby')).to.equal('testIdHigh') + }) + + it('should not have labelled by id on single slider when both options set', function() { + var sliderConf = { + value: 10, + options: { + floor: 0, + ceil: 100, + step: 10, + ariaLabel: 'test label', + ariaLabelledBy: 'testId', + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.minH.attr('aria-label')).to.equal('test label') + expect(helper.slider.minH.attr('aria-labelledby')).to.equal(undefined) + }) + + it('should not have labelled by id on range slider when both options set', function() { + var sliderConf = { + min: 10, + max: 90, + options: { + floor: 0, + ceil: 100, + step: 10, + ariaLabel: 'test label', + ariaLabelHigh: 'test label high', + ariaLabelledBy: 'testId', + ariaLabelledByHigh: 'testIdHigh', + }, + } + helper.createRangeSlider(sliderConf) + expect(helper.slider.minH.attr('aria-label')).to.equal('test label') + expect(helper.slider.maxH.attr('aria-label')).to.equal('test label high') + expect(helper.slider.minH.attr('aria-labelledby')).to.equal(undefined) + expect(helper.slider.maxH.attr('aria-labelledby')).to.equal(undefined) + }) + }) +})() diff --git a/tests/specs/custom-template-test.js b/tests/specs/custom-template-test.js index 54570d5..060e655 100644 --- a/tests/specs/custom-template-test.js +++ b/tests/specs/custom-template-test.js @@ -1,26 +1,28 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Custom templates - ', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; + var helper, RzSliderOptions, $rootScope, $timeout - beforeEach(module('test-helper')); + beforeEach(module('test-helper')) - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) - var url = 'tests/specs/custom-tpl.html'; + var url = 'tests/specs/custom-tpl.html' it('should render ceil/floor labels', function() { var sliderConf = { @@ -29,13 +31,13 @@ options: { floor: 0, ceil: 100, - step: 10 - } - }; - helper.createRangeSliderWithCustomTemplate(sliderConf, url); - expect(helper.slider.flrLab.text()).to.equal('test- 0'); - expect(helper.slider.ceilLab.text()).to.equal('test- 100'); - }); + step: 10, + }, + } + helper.createRangeSliderWithCustomTemplate(sliderConf, url) + expect(helper.slider.flrLab.text()).to.equal('test- 0') + expect(helper.slider.ceilLab.text()).to.equal('test- 100') + }) it('should render min/max labels', function() { var sliderConf = { @@ -44,13 +46,13 @@ options: { floor: 0, ceil: 100, - step: 10 - } - }; - helper.createRangeSliderWithCustomTemplate(sliderConf, url); - expect(helper.slider.minLab.text()).to.equal('test- 10'); - expect(helper.slider.maxLab.text()).to.equal('test- 50'); - }); + step: 10, + }, + } + helper.createRangeSliderWithCustomTemplate(sliderConf, url) + expect(helper.slider.minLab.text()).to.equal('test- 10') + expect(helper.slider.maxLab.text()).to.equal('test- 50') + }) it('should render min/max labels', function() { var sliderConf = { @@ -59,12 +61,11 @@ options: { floor: 0, ceil: 100, - step: 10 - } - }; - helper.createRangeSliderWithCustomTemplate(sliderConf, url); - expect(helper.slider.cmbLab.text()).to.equal('test- 50 - 50'); - }); - - }); -}()); + step: 10, + }, + } + helper.createRangeSliderWithCustomTemplate(sliderConf, url) + expect(helper.slider.cmbLab.text()).to.equal('test- 50 - 50') + }) + }) +})() diff --git a/tests/specs/custom-tpl.html b/tests/specs/custom-tpl.html index 93ec02d..c9e921c 100644 --- a/tests/specs/custom-tpl.html +++ b/tests/specs/custom-tpl.html @@ -1,8 +1,13 @@
+ + - - - + + + + + + test- {{floorLabel}} diff --git a/tests/specs/helper-functions-test.js b/tests/specs/helper-functions-test.js index 353b325..307a15f 100644 --- a/tests/specs/helper-functions-test.js +++ b/tests/specs/helper-functions-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Helper functions - ', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) describe('tests with same config', function() { beforeEach(function() { @@ -27,393 +29,417 @@ options: { floor: 0, ceil: 100, - step: 10 - } - }; - helper.createSlider(sliderConf); - }); + step: 10, + }, + } + helper.createSlider(sliderConf) + }) it('should have a valid roundStep for integer values when floor is 0', function() { - expect(helper.slider.roundStep(10)).to.equal(10); - expect(helper.slider.roundStep(9)).to.equal(10); - expect(helper.slider.roundStep(11)).to.equal(10); - expect(helper.slider.roundStep(15)).to.equal(20); - expect(helper.slider.roundStep(14)).to.equal(10); - expect(helper.slider.roundStep(-10)).to.equal(-10); - expect(helper.slider.roundStep(-9)).to.equal(-10); - expect(helper.slider.roundStep(-11)).to.equal(-10); - expect(helper.slider.roundStep(-16)).to.equal(-20); - expect(helper.slider.roundStep(-15)).to.equal(-10); - expect(helper.slider.roundStep(-14)).to.equal(-10); - }); + expect(helper.slider.roundStep(10)).to.equal(10) + expect(helper.slider.roundStep(9)).to.equal(10) + expect(helper.slider.roundStep(11)).to.equal(10) + expect(helper.slider.roundStep(15)).to.equal(20) + expect(helper.slider.roundStep(14)).to.equal(10) + expect(helper.slider.roundStep(-10)).to.equal(-10) + expect(helper.slider.roundStep(-9)).to.equal(-10) + expect(helper.slider.roundStep(-11)).to.equal(-10) + expect(helper.slider.roundStep(-16)).to.equal(-20) + expect(helper.slider.roundStep(-15)).to.equal(-10) + expect(helper.slider.roundStep(-14)).to.equal(-10) + }) it('should have a valid roundStep for integer values when floor is above 0', function() { - helper.scope.slider.options.floor = 3; - helper.scope.slider.options.ceil = 103; - helper.scope.$digest(); - - expect(helper.slider.roundStep(3)).to.equal(3); - expect(helper.slider.roundStep(13)).to.equal(13); - expect(helper.slider.roundStep(12)).to.equal(13); - expect(helper.slider.roundStep(14)).to.equal(13); - expect(helper.slider.roundStep(18)).to.equal(23); - expect(helper.slider.roundStep(17)).to.equal(13); - }); + helper.scope.slider.options.floor = 3 + helper.scope.slider.options.ceil = 103 + helper.scope.$digest() + + expect(helper.slider.roundStep(3)).to.equal(3) + expect(helper.slider.roundStep(13)).to.equal(13) + expect(helper.slider.roundStep(12)).to.equal(13) + expect(helper.slider.roundStep(14)).to.equal(13) + expect(helper.slider.roundStep(18)).to.equal(23) + expect(helper.slider.roundStep(17)).to.equal(13) + }) it('should have a valid roundStep for integer values when floor is below 0', function() { - helper.scope.slider.options.floor = -25; - helper.scope.$digest(); - - expect(helper.slider.roundStep(-5)).to.equal(-5); - expect(helper.slider.roundStep(-15)).to.equal(-15); - expect(helper.slider.roundStep(-16)).to.equal(-15); - expect(helper.slider.roundStep(-14)).to.equal(-15); - expect(helper.slider.roundStep(-21)).to.equal(-25); - expect(helper.slider.roundStep(-20)).to.equal(-15); - expect(helper.slider.roundStep(-19)).to.equal(-15); - }); + helper.scope.slider.options.floor = -25 + helper.scope.$digest() + + expect(helper.slider.roundStep(-5)).to.equal(-5) + expect(helper.slider.roundStep(-15)).to.equal(-15) + expect(helper.slider.roundStep(-16)).to.equal(-15) + expect(helper.slider.roundStep(-14)).to.equal(-15) + expect(helper.slider.roundStep(-21)).to.equal(-25) + expect(helper.slider.roundStep(-20)).to.equal(-15) + expect(helper.slider.roundStep(-19)).to.equal(-15) + }) it('should have a valid roundStep for floating values when floor is 0', function() { - helper.scope.slider.options.precision = 1; - helper.scope.slider.options.step = 0.1; - helper.scope.$digest(); - - expect(helper.slider.roundStep(10)).to.equal(10); - expect(helper.slider.roundStep(1.1)).to.equal(1.1); - expect(helper.slider.roundStep(1.09)).to.equal(1.1); - expect(helper.slider.roundStep(1.11)).to.equal(1.1); - expect(helper.slider.roundStep(1.15)).to.equal(1.2); - expect(helper.slider.roundStep(1.14)).to.equal(1.1); - - expect(helper.slider.roundStep(-10)).to.equal(-10); - expect(helper.slider.roundStep(-1.1)).to.equal(-1.1); - expect(helper.slider.roundStep(-1.09)).to.equal(-1.1); - expect(helper.slider.roundStep(-1.11)).to.equal(-1.1); - expect(helper.slider.roundStep(-1.16)).to.equal(-1.2); - expect(helper.slider.roundStep(-1.15)).to.equal(-1.1); - expect(helper.slider.roundStep(-1.14)).to.equal(-1.1); - }); + helper.scope.slider.options.precision = 1 + helper.scope.slider.options.step = 0.1 + helper.scope.$digest() + + expect(helper.slider.roundStep(10)).to.equal(10) + expect(helper.slider.roundStep(1.1)).to.equal(1.1) + expect(helper.slider.roundStep(1.09)).to.equal(1.1) + expect(helper.slider.roundStep(1.11)).to.equal(1.1) + expect(helper.slider.roundStep(1.15)).to.equal(1.2) + expect(helper.slider.roundStep(1.14)).to.equal(1.1) + + expect(helper.slider.roundStep(-10)).to.equal(-10) + expect(helper.slider.roundStep(-1.1)).to.equal(-1.1) + expect(helper.slider.roundStep(-1.09)).to.equal(-1.1) + expect(helper.slider.roundStep(-1.11)).to.equal(-1.1) + expect(helper.slider.roundStep(-1.16)).to.equal(-1.2) + expect(helper.slider.roundStep(-1.15)).to.equal(-1.1) + expect(helper.slider.roundStep(-1.14)).to.equal(-1.1) + }) it('should have a valid roundStep for floating values when floor is above 0', function() { - helper.scope.slider.options.floor = 3; - helper.scope.slider.options.ceil = 103; - helper.scope.slider.options.precision = 1; - helper.scope.slider.options.step = 0.1; - helper.scope.$digest(); - - expect(helper.slider.roundStep(3)).to.equal(3); - expect(helper.slider.roundStep(13)).to.equal(13); - expect(helper.slider.roundStep(1.1)).to.equal(1.1); - expect(helper.slider.roundStep(1.09)).to.equal(1.1); - expect(helper.slider.roundStep(1.11)).to.equal(1.1); - expect(helper.slider.roundStep(1.15)).to.equal(1.2); - expect(helper.slider.roundStep(1.14)).to.equal(1.1); - }); + helper.scope.slider.options.floor = 3 + helper.scope.slider.options.ceil = 103 + helper.scope.slider.options.precision = 1 + helper.scope.slider.options.step = 0.1 + helper.scope.$digest() + + expect(helper.slider.roundStep(3)).to.equal(3) + expect(helper.slider.roundStep(13)).to.equal(13) + expect(helper.slider.roundStep(1.1)).to.equal(1.1) + expect(helper.slider.roundStep(1.09)).to.equal(1.1) + expect(helper.slider.roundStep(1.11)).to.equal(1.1) + expect(helper.slider.roundStep(1.15)).to.equal(1.2) + expect(helper.slider.roundStep(1.14)).to.equal(1.1) + }) it('should have a valid roundStep for floating values when floor is below 0', function() { - helper.scope.slider.options.floor = -25; - helper.scope.slider.options.ceil = 75; - helper.scope.slider.options.precision = 1; - helper.scope.slider.options.step = 0.1; - helper.scope.$digest(); - - expect(helper.slider.roundStep(-25)).to.equal(-25); - expect(helper.slider.roundStep(-5)).to.equal(-5); - expect(helper.slider.roundStep(-1.1)).to.equal(-1.1); - expect(helper.slider.roundStep(-1.09)).to.equal(-1.1); - expect(helper.slider.roundStep(-1.11)).to.equal(-1.1); - expect(helper.slider.roundStep(-1.16)).to.equal(-1.2); - expect(helper.slider.roundStep(-1.15)).to.equal(-1.1); - expect(helper.slider.roundStep(-1.14)).to.equal(-1.1); - }); + helper.scope.slider.options.floor = -25 + helper.scope.slider.options.ceil = 75 + helper.scope.slider.options.precision = 1 + helper.scope.slider.options.step = 0.1 + helper.scope.$digest() + + expect(helper.slider.roundStep(-25)).to.equal(-25) + expect(helper.slider.roundStep(-5)).to.equal(-5) + expect(helper.slider.roundStep(-1.1)).to.equal(-1.1) + expect(helper.slider.roundStep(-1.09)).to.equal(-1.1) + expect(helper.slider.roundStep(-1.11)).to.equal(-1.1) + expect(helper.slider.roundStep(-1.16)).to.equal(-1.2) + expect(helper.slider.roundStep(-1.15)).to.equal(-1.1) + expect(helper.slider.roundStep(-1.14)).to.equal(-1.1) + }) it('should have a valid hideEl', function() { - var el = angular.element('
'); - helper.slider.hideEl(el); - expect(el.css('visibility')).to.equal('hidden'); - }); + var el = angular.element('
') + helper.slider.hideEl(el) + expect(el.css('visibility')).to.equal('hidden') + }) it('should have a valid showEl when not rzAlwaysHide', function() { - var el = angular.element('
'); - helper.slider.showEl(el); - expect(el.css('visibility')).to.equal('visible'); - }); + var el = angular.element('
') + helper.slider.showEl(el) + expect(el.css('visibility')).to.equal('visible') + }) it('should have a valid showEl when rzAlwaysHide', function() { - var el = angular.element('
'); - el.css('visibility', 'hidden'); - el.rzAlwaysHide = true; + var el = angular.element('
') + el.css('visibility', 'hidden') + el.rzAlwaysHide = true - helper.slider.showEl(el); - expect(el.css('visibility')).to.equal('hidden'); - }); + helper.slider.showEl(el) + expect(el.css('visibility')).to.equal('hidden') + }) it('should have a valid setPosition for horizontal sliders', function() { - var el = angular.element('
'); - helper.slider.setPosition(el, 12); - expect(el.css('left')).to.equal('12px'); - }); + var el = angular.element('
') + helper.slider.setPosition(el, 12) + expect(el.css('left')).to.equal('12px') + }) it('should have a valid setPosition for vertical sliders', function() { - helper.scope.slider.options.vertical = true; - helper.scope.$digest(); - var el = angular.element('
'); - helper.slider.setPosition(el, 12); - expect(el.css('bottom')).to.equal('12px'); - }); + helper.scope.slider.options.vertical = true + helper.scope.$digest() + var el = angular.element('
') + helper.slider.setPosition(el, 12) + expect(el.css('bottom')).to.equal('12px') + }) it('should have a valid getDimension for horizontal sliders', function() { - expect(helper.slider.getDimension(helper.slider.sliderElem)).to.equal(1000); - }); + expect(helper.slider.getDimension(helper.slider.sliderElem)).to.equal( + 1000 + ) + }) it('should have a valid getDimension for horizontal sliders with custom scale', function() { - helper.scope.slider.options.scale = 2; - helper.scope.$digest(); - expect(helper.slider.getDimension(helper.slider.sliderElem)).to.equal(2000); - }); + helper.scope.slider.options.scale = 2 + helper.scope.$digest() + expect(helper.slider.getDimension(helper.slider.sliderElem)).to.equal( + 2000 + ) + }) it('should have a valid getDimension for vertical sliders', function() { - helper.scope.slider.options.vertical = true; - helper.scope.$digest(); - expect(helper.slider.getDimension(helper.slider.sliderElem)).to.equal(1000); - }); + helper.scope.slider.options.vertical = true + helper.scope.$digest() + expect(helper.slider.getDimension(helper.slider.sliderElem)).to.equal( + 1000 + ) + }) it('should have a valid getDimension for vertical sliders with custom scale', function() { - helper.scope.slider.options.scale = 2; - helper.scope.slider.options.vertical = true; - helper.scope.$digest(); - expect(helper.slider.getDimension(helper.slider.sliderElem)).to.equal(2000); - }); + helper.scope.slider.options.scale = 2 + helper.scope.slider.options.vertical = true + helper.scope.$digest() + expect(helper.slider.getDimension(helper.slider.sliderElem)).to.equal( + 2000 + ) + }) it('should have a valid setDimension for horizontal sliders', function() { - var el = angular.element('
'); - helper.slider.setDimension(el, 12); - expect(el.css('width')).to.equal('12px'); - }); + var el = angular.element('
') + helper.slider.setDimension(el, 12) + expect(el.css('width')).to.equal('12px') + }) it('should have a valid setDimension for vertical sliders', function() { - helper.scope.slider.options.vertical = true; - helper.scope.$digest(); - var el = angular.element('
'); - helper.slider.setDimension(el, 12); - expect(el.css('height')).to.equal('12px'); - }); - - it('should have a valid valueToOffset for positive sliders', function() { - helper.slider.maxPos = 1000; - expect(helper.slider.valueToOffset(0)).to.equal(0); - expect(helper.slider.valueToOffset(50)).to.equal(500); - expect(helper.slider.valueToOffset(100)).to.equal(1000); - }); - - it('should have a valid valueToOffset for negative sliders', function() { - helper.scope.slider.options.floor = -100; - helper.scope.slider.options.ceil = 0; - helper.scope.slider.value = -50; - helper.scope.$digest(); - - helper.slider.maxPos = 1000; - expect(helper.slider.valueToOffset(0)).to.equal(1000); - expect(helper.slider.valueToOffset(-50)).to.equal(500); - expect(helper.slider.valueToOffset(-100)).to.equal(0); - }); + helper.scope.slider.options.vertical = true + helper.scope.$digest() + var el = angular.element('
') + helper.slider.setDimension(el, 12) + expect(el.css('height')).to.equal('12px') + }) + + it('should have a valid valueToPosition for positive sliders', function() { + helper.slider.maxPos = 1000 + expect(helper.slider.valueToPosition(0)).to.equal(0) + expect(helper.slider.valueToPosition(50)).to.equal(500) + expect(helper.slider.valueToPosition(100)).to.equal(1000) + }) + + it('should have a valid valueToPosition for negative sliders', function() { + helper.scope.slider.options.floor = -100 + helper.scope.slider.options.ceil = 0 + helper.scope.slider.value = -50 + helper.scope.$digest() + + helper.slider.maxPos = 1000 + expect(helper.slider.valueToPosition(0)).to.equal(1000) + expect(helper.slider.valueToPosition(-50)).to.equal(500) + expect(helper.slider.valueToPosition(-100)).to.equal(0) + }) it('should have a valid sanitizeValue', function() { - expect(helper.slider.sanitizeValue(0)).to.equal(0); - expect(helper.slider.sanitizeValue(50)).to.equal(50); - expect(helper.slider.sanitizeValue(100)).to.equal(100); - expect(helper.slider.sanitizeValue(-1)).to.equal(0); - expect(helper.slider.sanitizeValue(-10)).to.equal(0); - expect(helper.slider.sanitizeValue(101)).to.equal(100); - expect(helper.slider.sanitizeValue(110)).to.equal(100); - }); - - it('should have a valid offsetToValue for positive sliders', function() { - helper.slider.maxPos = 1000; - expect(helper.slider.offsetToValue(0)).to.equal(0); - expect(helper.slider.offsetToValue(1000)).to.equal(100); - expect(helper.slider.offsetToValue(500)).to.equal(50); - }); - - it('should have a valid offsetToValue for for negative sliders', function() { - helper.scope.slider.options.floor = -100; - helper.scope.slider.options.ceil = 0; - helper.scope.slider.value = -50; - helper.scope.$digest(); - helper.slider.maxPos = 1000; - - expect(helper.slider.offsetToValue(0)).to.equal(-100); - expect(helper.slider.offsetToValue(1000)).to.equal(0); - expect(helper.slider.offsetToValue(500)).to.equal(-50); - }); + expect(helper.slider.sanitizeValue(0)).to.equal(0) + expect(helper.slider.sanitizeValue(50)).to.equal(50) + expect(helper.slider.sanitizeValue(100)).to.equal(100) + expect(helper.slider.sanitizeValue(-1)).to.equal(0) + expect(helper.slider.sanitizeValue(-10)).to.equal(0) + expect(helper.slider.sanitizeValue(101)).to.equal(100) + expect(helper.slider.sanitizeValue(110)).to.equal(100) + }) + + it('should have a valid positionToValue for positive sliders', function() { + helper.slider.maxPos = 1000 + expect(helper.slider.positionToValue(0)).to.equal(0) + expect(helper.slider.positionToValue(1000)).to.equal(100) + expect(helper.slider.positionToValue(500)).to.equal(50) + }) + + it('should have a valid positionToValue for for negative sliders', function() { + helper.scope.slider.options.floor = -100 + helper.scope.slider.options.ceil = 0 + helper.scope.slider.value = -50 + helper.scope.$digest() + helper.slider.maxPos = 1000 + + expect(helper.slider.positionToValue(0)).to.equal(-100) + expect(helper.slider.positionToValue(1000)).to.equal(0) + expect(helper.slider.positionToValue(500)).to.equal(-50) + }) it('should have a valid getEventXY for horizontal sliders on desktop browsers', function() { var event = { - clientX: 12 - }; - expect(helper.slider.getEventXY(event)).to.equal(12); - }); + clientX: 12, + } + expect(helper.slider.getEventXY(event)).to.equal(12) + }) it('should have a valid getEventXY for vertical sliders on desktop browsers', function() { - helper.scope.slider.options.vertical = true; - helper.scope.$digest(); + helper.scope.slider.options.vertical = true + helper.scope.$digest() var event = { - clientY: 12 - }; - expect(helper.slider.getEventXY(event)).to.equal(12); - }); + clientY: 12, + } + expect(helper.slider.getEventXY(event)).to.equal(12) + }) it('should have a valid getEventXY for horizontal sliders on mobile browsers with no originalEvent', function() { var event = { - touches: [{ - clientX: 12 - }] - }; - expect(helper.slider.getEventXY(event)).to.equal(12); - }); + touches: [ + { + clientX: 12, + }, + ], + } + expect(helper.slider.getEventXY(event)).to.equal(12) + }) it('should have a valid getEventXY for horizontal sliders on mobile browsers with originalEvent', function() { var event = { originalEvent: { - touches: [{ - clientX: 12 - }] - } - }; - expect(helper.slider.getEventXY(event)).to.equal(12); - }); + touches: [ + { + clientX: 12, + }, + ], + }, + } + expect(helper.slider.getEventXY(event)).to.equal(12) + }) it('should have a valid getEventXY for vertical sliders on mobile browsers with no originalEvent', function() { - helper.scope.slider.options.vertical = true; - helper.scope.$digest(); + helper.scope.slider.options.vertical = true + helper.scope.$digest() var event = { - touches: [{ - clientY: 12 - }] - }; - expect(helper.slider.getEventXY(event)).to.equal(12); - }); + touches: [ + { + clientY: 12, + }, + ], + } + expect(helper.slider.getEventXY(event)).to.equal(12) + }) it('should have a valid getEventXY for vertical sliders on mobile browsers with originalEvent', function() { - helper.scope.slider.options.vertical = true; - helper.scope.$digest(); + helper.scope.slider.options.vertical = true + helper.scope.$digest() var event = { originalEvent: { - touches: [{ - clientY: 12 - }] - } - }; - expect(helper.slider.getEventXY(event)).to.equal(12); - }); + touches: [ + { + clientY: 12, + }, + ], + }, + } + expect(helper.slider.getEventXY(event)).to.equal(12) + }) it('should have a valid getEventPosition for horizontal sliders', function() { - sinon.stub(helper.slider, 'getEventXY').returns(46); - var event = {}; + sinon.stub(helper.slider, 'getEventXY').returns(46) + var event = {} //fake slider's dimension - helper.slider.sliderElem.rzsp = 10; - helper.slider.handleHalfDim = 16; + helper.slider.sliderElem.rzsp = 10 + helper.slider.handleHalfDim = 16 - expect(helper.slider.getEventPosition(event)).to.equal(20); - }); + expect(helper.slider.getEventPosition(event)).to.equal(20) + }) it('should have a valid getEventPosition for vertical sliders', function() { - helper.scope.slider.options.vertical = true; - helper.scope.$digest(); - sinon.stub(helper.slider, 'getEventXY').returns(46); - var event = {}; + helper.scope.slider.options.vertical = true + helper.scope.$digest() + sinon.stub(helper.slider, 'getEventXY').returns(46) + var event = {} //fake slider's dimension - helper.slider.sliderElem.rzsp = 10; - helper.slider.handleHalfDim = 16; + helper.slider.sliderElem.rzsp = 10 + helper.slider.handleHalfDim = 16 - expect(helper.slider.getEventPosition(event)).to.equal(-52); - }); + expect(helper.slider.getEventPosition(event)).to.equal(-52) + }) it('should have a valid getEventPosition for horizontal sliders with scale option', function() { - helper.scope.slider.options.scale = 0.5; - helper.scope.$digest(); - sinon.stub(helper.slider, 'getEventXY').returns(46); - var event = {}; + helper.scope.slider.options.scale = 0.5 + helper.scope.$digest() + sinon.stub(helper.slider, 'getEventXY').returns(46) + var event = {} //fake slider's dimension - helper.slider.sliderElem.rzsp = 10; - helper.slider.handleHalfDim = 16; + helper.slider.sliderElem.rzsp = 10 + helper.slider.handleHalfDim = 16 - expect(helper.slider.getEventPosition(event)).to.equal(10); - }); + expect(helper.slider.getEventPosition(event)).to.equal(2) + }) it('should have a valid getEventPosition for vertical sliders with scale option', function() { - helper.scope.slider.options.scale = 0.5; - helper.scope.slider.options.vertical = true; - helper.scope.$digest(); - sinon.stub(helper.slider, 'getEventXY').returns(46); - var event = {}; + helper.scope.slider.options.scale = 0.5 + helper.scope.slider.options.vertical = true + helper.scope.$digest() + sinon.stub(helper.slider, 'getEventXY').returns(46) + var event = {} //fake slider's dimension - helper.slider.sliderElem.rzsp = 10; - helper.slider.handleHalfDim = 16; + helper.slider.sliderElem.rzsp = 10 + helper.slider.handleHalfDim = 16 - expect(helper.slider.getEventPosition(event)).to.equal(-26); - }); + expect(helper.slider.getEventPosition(event)).to.equal(-34) + }) it('should have a valid getEventNames for desktop', function() { var event = { clientX: 10, - clientY: 100 - }; - var eventNames = helper.slider.getEventNames(event); + clientY: 100, + } + var eventNames = helper.slider.getEventNames(event) expect(eventNames).to.deep.equal({ moveEvent: 'mousemove', - endEvent: 'mouseup' - }); - }); + endEvent: 'mouseup', + }) + }) it('should have a valid getEventNames for mobile with new API', function() { var event = { - touches: [{ - clientX: 10, - clientY: 100 - }] - }; - var eventNames = helper.slider.getEventNames(event); + touches: [ + { + clientX: 10, + clientY: 100, + }, + ], + } + var eventNames = helper.slider.getEventNames(event) expect(eventNames).to.deep.equal({ moveEvent: 'touchmove', - endEvent: 'touchend' - }); - }); + endEvent: 'touchend', + }) + }) it('should have a valid getEventNames for mobile with old API', function() { var event = { originalEvent: { - touches: [{ - clientX: 10, - clientY: 100 - }] - } - }; - var eventNames = helper.slider.getEventNames(event); + touches: [ + { + clientX: 10, + clientY: 100, + }, + ], + }, + } + var eventNames = helper.slider.getEventNames(event) expect(eventNames).to.deep.equal({ moveEvent: 'touchmove', - endEvent: 'touchend' - }); - }); + endEvent: 'touchend', + }) + }) it('should have a valid getNearestHandle for single sliders', function() { - sinon.stub(helper.slider, 'getEventPosition').returns(46); - var event = {}; - expect(helper.slider.getNearestHandle(event)).to.equal(helper.slider.minH); - }); + sinon.stub(helper.slider, 'getEventPosition').returns(46) + var event = {} + expect(helper.slider.getNearestHandle(event)).to.equal( + helper.slider.minH + ) + }) it('should have a valid focusElement', function() { - var el = [{ - focus: sinon.spy() - }]; - helper.slider.focusElement(el); - el[0].focus.called.should.be.true; - }); - }); + var el = [ + { + focus: sinon.spy(), + }, + ] + helper.slider.focusElement(el) + el[0].focus.called.should.be.true + }) + }) describe('Tests with specific config', function() { it('should have a valid getNearestHandle for range sliders when click is near minH', function() { @@ -423,19 +449,21 @@ options: { floor: 0, ceil: 100, - step: 10 - } - }; - helper.createRangeSlider(sliderConf); - sinon.stub(helper.slider, 'getEventPosition').returns(46); + step: 10, + }, + } + helper.createRangeSlider(sliderConf) + sinon.stub(helper.slider, 'getEventPosition').returns(46) //fake slider's dimension - helper.slider.minH.rzsp = 0; - helper.slider.maxH.rzsp = 100; + helper.slider.minH.rzsp = 0 + helper.slider.maxH.rzsp = 100 - var event = {}; - expect(helper.slider.getNearestHandle(event)).to.equal(helper.slider.minH); - }); + var event = {} + expect(helper.slider.getNearestHandle(event)).to.equal( + helper.slider.minH + ) + }) it('should have a valid getNearestHandle for range sliders when click is near maxH', function() { var sliderConf = { @@ -444,19 +472,21 @@ options: { floor: 0, ceil: 100, - step: 10 - } - }; - helper.createRangeSlider(sliderConf); - sinon.stub(helper.slider, 'getEventPosition').returns(66); + step: 10, + }, + } + helper.createRangeSlider(sliderConf) + sinon.stub(helper.slider, 'getEventPosition').returns(66) //fake slider's dimension - helper.slider.minH.rzsp = 0; - helper.slider.maxH.rzsp = 100; + helper.slider.minH.rzsp = 0 + helper.slider.maxH.rzsp = 100 - var event = {}; - expect(helper.slider.getNearestHandle(event)).to.equal(helper.slider.maxH); - }); + var event = {} + expect(helper.slider.getNearestHandle(event)).to.equal( + helper.slider.maxH + ) + }) it('should have a bindEvents that bind correct events for single sliders on desktop', function() { var sliderConf = { @@ -464,42 +494,42 @@ options: { floor: 0, ceil: 100, - step: 10 - } - }; - helper.createSlider(sliderConf); - helper.slider.onStart = sinon.spy(); - helper.slider.onMove = sinon.spy(); - helper.slider.onPointerFocus = sinon.spy(); - - helper.slider.unbindEvents(); //remove previously bound events - helper.slider.bindEvents(); - - helper.slider.selBar.triggerHandler('mousedown'); - expect(helper.slider.onStart.callCount).to.equal(1); - expect(helper.slider.onMove.callCount).to.equal(1); - - helper.slider.minH.triggerHandler('mousedown'); - expect(helper.slider.onStart.callCount).to.equal(2); - expect(helper.slider.onMove.callCount).to.equal(1); - - helper.slider.maxH.triggerHandler('mousedown'); - expect(helper.slider.onStart.callCount).to.equal(2); - expect(helper.slider.onMove.callCount).to.equal(1); - - helper.slider.fullBar.triggerHandler('mousedown'); - expect(helper.slider.onStart.callCount).to.equal(3); - expect(helper.slider.onMove.callCount).to.equal(2); - - helper.slider.ticks.triggerHandler('mousedown'); - expect(helper.slider.onStart.callCount).to.equal(4); - expect(helper.slider.onMove.callCount).to.equal(3); - - helper.slider.minH.triggerHandler('focus'); - expect(helper.slider.onPointerFocus.callCount).to.equal(1); - helper.slider.maxH.triggerHandler('focus'); - expect(helper.slider.onPointerFocus.callCount).to.equal(1); - }); + step: 10, + }, + } + helper.createSlider(sliderConf) + helper.slider.onStart = sinon.spy() + helper.slider.onMove = sinon.spy() + helper.slider.onPointerFocus = sinon.spy() + + helper.slider.unbindEvents() //remove previously bound events + helper.slider.bindEvents() + + helper.slider.selBar.triggerHandler('mousedown') + expect(helper.slider.onStart.callCount).to.equal(1) + expect(helper.slider.onMove.callCount).to.equal(1) + + helper.slider.minH.triggerHandler('mousedown') + expect(helper.slider.onStart.callCount).to.equal(2) + expect(helper.slider.onMove.callCount).to.equal(1) + + helper.slider.maxH.triggerHandler('mousedown') + expect(helper.slider.onStart.callCount).to.equal(2) + expect(helper.slider.onMove.callCount).to.equal(1) + + helper.slider.fullBar.triggerHandler('mousedown') + expect(helper.slider.onStart.callCount).to.equal(3) + expect(helper.slider.onMove.callCount).to.equal(2) + + helper.slider.ticks.triggerHandler('mousedown') + expect(helper.slider.onStart.callCount).to.equal(4) + expect(helper.slider.onMove.callCount).to.equal(3) + + helper.slider.minH.triggerHandler('focus') + expect(helper.slider.onPointerFocus.callCount).to.equal(1) + helper.slider.maxH.triggerHandler('focus') + expect(helper.slider.onPointerFocus.callCount).to.equal(1) + }) it('should have a bindEvents that bind correct events for single sliders on mobile', function() { var sliderConf = { @@ -507,37 +537,37 @@ options: { floor: 0, ceil: 100, - step: 10 - } - }; - helper.createSlider(sliderConf); - helper.slider.onStart = sinon.spy(); - helper.slider.onMove = sinon.spy(); - helper.slider.onPointerFocus = sinon.spy(); - - helper.slider.unbindEvents(); //remove previously bound events - helper.slider.bindEvents(); - - helper.slider.selBar.triggerHandler('touchstart'); - expect(helper.slider.onStart.callCount).to.equal(1); - expect(helper.slider.onMove.callCount).to.equal(1); - - helper.slider.minH.triggerHandler('touchstart'); - expect(helper.slider.onStart.callCount).to.equal(2); - expect(helper.slider.onMove.callCount).to.equal(1); - - helper.slider.maxH.triggerHandler('touchstart'); - expect(helper.slider.onStart.callCount).to.equal(2); - expect(helper.slider.onMove.callCount).to.equal(1); - - helper.slider.fullBar.triggerHandler('touchstart'); - expect(helper.slider.onStart.callCount).to.equal(3); - expect(helper.slider.onMove.callCount).to.equal(2); - - helper.slider.ticks.triggerHandler('touchstart'); - expect(helper.slider.onStart.callCount).to.equal(4); - expect(helper.slider.onMove.callCount).to.equal(3); - }); + step: 10, + }, + } + helper.createSlider(sliderConf) + helper.slider.onStart = sinon.spy() + helper.slider.onMove = sinon.spy() + helper.slider.onPointerFocus = sinon.spy() + + helper.slider.unbindEvents() //remove previously bound events + helper.slider.bindEvents() + + helper.slider.selBar.triggerHandler('touchstart') + expect(helper.slider.onStart.callCount).to.equal(1) + expect(helper.slider.onMove.callCount).to.equal(1) + + helper.slider.minH.triggerHandler('touchstart') + expect(helper.slider.onStart.callCount).to.equal(2) + expect(helper.slider.onMove.callCount).to.equal(1) + + helper.slider.maxH.triggerHandler('touchstart') + expect(helper.slider.onStart.callCount).to.equal(2) + expect(helper.slider.onMove.callCount).to.equal(1) + + helper.slider.fullBar.triggerHandler('touchstart') + expect(helper.slider.onStart.callCount).to.equal(3) + expect(helper.slider.onMove.callCount).to.equal(2) + + helper.slider.ticks.triggerHandler('touchstart') + expect(helper.slider.onStart.callCount).to.equal(4) + expect(helper.slider.onMove.callCount).to.equal(3) + }) it('should have a bindEvents that bind correct events for range sliders on desktop', function() { var sliderConf = { @@ -546,42 +576,42 @@ options: { floor: 0, ceil: 100, - step: 10 - } - }; - helper.createRangeSlider(sliderConf); - helper.slider.onStart = sinon.spy(); - helper.slider.onMove = sinon.spy(); - helper.slider.onPointerFocus = sinon.spy(); - - helper.slider.unbindEvents(); //remove previously bound events - helper.slider.bindEvents(); - - helper.slider.selBar.triggerHandler('mousedown'); - expect(helper.slider.onStart.callCount).to.equal(1); - expect(helper.slider.onMove.callCount).to.equal(1); - - helper.slider.minH.triggerHandler('mousedown'); - expect(helper.slider.onStart.callCount).to.equal(2); - expect(helper.slider.onMove.callCount).to.equal(1); - - helper.slider.maxH.triggerHandler('mousedown'); - expect(helper.slider.onStart.callCount).to.equal(3); - expect(helper.slider.onMove.callCount).to.equal(1); - - helper.slider.fullBar.triggerHandler('mousedown'); - expect(helper.slider.onStart.callCount).to.equal(4); - expect(helper.slider.onMove.callCount).to.equal(2); - - helper.slider.ticks.triggerHandler('mousedown'); - expect(helper.slider.onStart.callCount).to.equal(5); - expect(helper.slider.onMove.callCount).to.equal(3); - - helper.slider.minH.triggerHandler('focus'); - expect(helper.slider.onPointerFocus.callCount).to.equal(1); - helper.slider.maxH.triggerHandler('focus'); - expect(helper.slider.onPointerFocus.callCount).to.equal(2); - }); + step: 10, + }, + } + helper.createRangeSlider(sliderConf) + helper.slider.onStart = sinon.spy() + helper.slider.onMove = sinon.spy() + helper.slider.onPointerFocus = sinon.spy() + + helper.slider.unbindEvents() //remove previously bound events + helper.slider.bindEvents() + + helper.slider.selBar.triggerHandler('mousedown') + expect(helper.slider.onStart.callCount).to.equal(1) + expect(helper.slider.onMove.callCount).to.equal(1) + + helper.slider.minH.triggerHandler('mousedown') + expect(helper.slider.onStart.callCount).to.equal(2) + expect(helper.slider.onMove.callCount).to.equal(1) + + helper.slider.maxH.triggerHandler('mousedown') + expect(helper.slider.onStart.callCount).to.equal(3) + expect(helper.slider.onMove.callCount).to.equal(1) + + helper.slider.fullBar.triggerHandler('mousedown') + expect(helper.slider.onStart.callCount).to.equal(4) + expect(helper.slider.onMove.callCount).to.equal(2) + + helper.slider.ticks.triggerHandler('mousedown') + expect(helper.slider.onStart.callCount).to.equal(5) + expect(helper.slider.onMove.callCount).to.equal(3) + + helper.slider.minH.triggerHandler('focus') + expect(helper.slider.onPointerFocus.callCount).to.equal(1) + helper.slider.maxH.triggerHandler('focus') + expect(helper.slider.onPointerFocus.callCount).to.equal(2) + }) it('should have a bindEvents that bind correct events for range sliders on mobile', function() { var sliderConf = { @@ -590,37 +620,37 @@ options: { floor: 0, ceil: 100, - step: 10 - } - }; - helper.createRangeSlider(sliderConf); - helper.slider.onStart = sinon.spy(); - helper.slider.onMove = sinon.spy(); - helper.slider.onPointerFocus = sinon.spy(); - - helper.slider.unbindEvents(); //remove previously bound events - helper.slider.bindEvents(); - - helper.slider.selBar.triggerHandler('touchstart'); - expect(helper.slider.onStart.callCount).to.equal(1); - expect(helper.slider.onMove.callCount).to.equal(1); - - helper.slider.minH.triggerHandler('touchstart'); - expect(helper.slider.onStart.callCount).to.equal(2); - expect(helper.slider.onMove.callCount).to.equal(1); - - helper.slider.maxH.triggerHandler('touchstart'); - expect(helper.slider.onStart.callCount).to.equal(3); - expect(helper.slider.onMove.callCount).to.equal(1); - - helper.slider.fullBar.triggerHandler('touchstart'); - expect(helper.slider.onStart.callCount).to.equal(4); - expect(helper.slider.onMove.callCount).to.equal(2); - - helper.slider.ticks.triggerHandler('touchstart'); - expect(helper.slider.onStart.callCount).to.equal(5); - expect(helper.slider.onMove.callCount).to.equal(3); - }); + step: 10, + }, + } + helper.createRangeSlider(sliderConf) + helper.slider.onStart = sinon.spy() + helper.slider.onMove = sinon.spy() + helper.slider.onPointerFocus = sinon.spy() + + helper.slider.unbindEvents() //remove previously bound events + helper.slider.bindEvents() + + helper.slider.selBar.triggerHandler('touchstart') + expect(helper.slider.onStart.callCount).to.equal(1) + expect(helper.slider.onMove.callCount).to.equal(1) + + helper.slider.minH.triggerHandler('touchstart') + expect(helper.slider.onStart.callCount).to.equal(2) + expect(helper.slider.onMove.callCount).to.equal(1) + + helper.slider.maxH.triggerHandler('touchstart') + expect(helper.slider.onStart.callCount).to.equal(3) + expect(helper.slider.onMove.callCount).to.equal(1) + + helper.slider.fullBar.triggerHandler('touchstart') + expect(helper.slider.onStart.callCount).to.equal(4) + expect(helper.slider.onMove.callCount).to.equal(2) + + helper.slider.ticks.triggerHandler('touchstart') + expect(helper.slider.onStart.callCount).to.equal(5) + expect(helper.slider.onMove.callCount).to.equal(3) + }) it('should have a unbindEvents that unbind all events', function() { var sliderConf = { @@ -629,83 +659,90 @@ options: { floor: 0, ceil: 100, - step: 10 - } - }; - helper.createRangeSlider(sliderConf); - helper.slider.onStart = sinon.spy(); - helper.slider.onMove = sinon.spy(); - helper.slider.onPointerFocus = sinon.spy(); - - helper.slider.unbindEvents(); //remove previously bound events - helper.slider.bindEvents(); - helper.slider.unbindEvents(); - - helper.slider.selBar.triggerHandler('mousedown'); - helper.slider.minH.triggerHandler('mousedown'); - helper.slider.maxH.triggerHandler('mousedown'); - helper.slider.fullBar.triggerHandler('mousedown'); - helper.slider.ticks.triggerHandler('mousedown'); - helper.slider.minH.triggerHandler('focus'); - expect(helper.slider.onStart.callCount).to.equal(0); - expect(helper.slider.onMove.callCount).to.equal(0); - expect(helper.slider.onPointerFocus.callCount).to.equal(0); - }); - }); + step: 10, + }, + } + helper.createRangeSlider(sliderConf) + helper.slider.onStart = sinon.spy() + helper.slider.onMove = sinon.spy() + helper.slider.onPointerFocus = sinon.spy() + + helper.slider.unbindEvents() //remove previously bound events + helper.slider.bindEvents() + helper.slider.unbindEvents() + + helper.slider.selBar.triggerHandler('mousedown') + helper.slider.minH.triggerHandler('mousedown') + helper.slider.maxH.triggerHandler('mousedown') + helper.slider.fullBar.triggerHandler('mousedown') + helper.slider.ticks.triggerHandler('mousedown') + helper.slider.minH.triggerHandler('focus') + expect(helper.slider.onStart.callCount).to.equal(0) + expect(helper.slider.onMove.callCount).to.equal(0) + expect(helper.slider.onPointerFocus.callCount).to.equal(0) + }) + }) describe('RTL tests with same config', function() { - beforeEach(function () { + beforeEach(function() { var sliderConf = { value: 50, options: { floor: 0, ceil: 100, step: 10, - rightToLeft: true - } - - }; - helper.createSlider(sliderConf); - }); - - it('should have a valid valueToOffset for positive sliders', function() { - helper.slider.maxPos = 1000; - expect(helper.slider.valueToOffset(0)).to.equal(1000); - expect(helper.slider.valueToOffset(50)).to.equal(500); - expect(helper.slider.valueToOffset(100)).to.equal(0); - }); - - it('should have a valid valueToOffset for negative sliders', function() { - helper.scope.slider.options.floor = -100; - helper.scope.slider.options.ceil = 0; - helper.scope.slider.value = -50; - helper.scope.$digest(); - - helper.slider.maxPos = 1000; - expect(helper.slider.valueToOffset(0)).to.equal(0); - expect(helper.slider.valueToOffset(-50)).to.equal(500); - expect(helper.slider.valueToOffset(-100)).to.equal(1000); - }); - - it('should have a valid offsetToValue for positive sliders', function() { - helper.slider.maxPos = 1000; - expect(helper.slider.offsetToValue(0)).to.equal(100); - expect(helper.slider.offsetToValue(1000)).to.equal(0); - expect(helper.slider.offsetToValue(500)).to.equal(50); - }); - - it('should have a valid offsetToValue for for negative sliders', function() { - helper.scope.slider.options.floor = -100; - helper.scope.slider.options.ceil = 0; - helper.scope.slider.value = -50; - helper.scope.$digest(); - helper.slider.maxPos = 1000; - - expect(helper.slider.offsetToValue(0)).to.equal(0); - expect(helper.slider.offsetToValue(1000)).to.equal(-100); - expect(helper.slider.offsetToValue(500)).to.equal(-50); - }); - }); - }); -}()); - + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + }) + + it('should have a valid valueToPosition for positive sliders', function() { + helper.slider.maxPos = 1000 + expect(helper.slider.valueToPosition(0)).to.equal(1000) + expect(helper.slider.valueToPosition(50)).to.equal(500) + expect(helper.slider.valueToPosition(100)).to.equal(0) + }) + + it('should have a valid valueToPosition for negative sliders', function() { + helper.scope.slider.options.floor = -100 + helper.scope.slider.options.ceil = 0 + helper.scope.slider.value = -50 + helper.scope.$digest() + + helper.slider.maxPos = 1000 + expect(helper.slider.valueToPosition(0)).to.equal(0) + expect(helper.slider.valueToPosition(-50)).to.equal(500) + expect(helper.slider.valueToPosition(-100)).to.equal(1000) + }) + + it('should have a valid positionToValue for positive sliders', function() { + helper.slider.maxPos = 1000 + expect(helper.slider.positionToValue(0)).to.equal(100) + expect(helper.slider.positionToValue(1000)).to.equal(0) + expect(helper.slider.positionToValue(500)).to.equal(50) + }) + + it('should have a valid positionToValue for for negative sliders', function() { + helper.scope.slider.options.floor = -100 + helper.scope.slider.options.ceil = 0 + helper.scope.slider.value = -50 + helper.scope.$digest() + helper.slider.maxPos = 1000 + + expect(helper.slider.positionToValue(0)).to.equal(0) + expect(helper.slider.positionToValue(1000)).to.equal(-100) + expect(helper.slider.positionToValue(500)).to.equal(-50) + }) + it('should conditionally call callOnChange in applyModel', function() { + sinon.spy(helper.slider, 'callOnChange') + + helper.slider.applyModel(false) + helper.slider.callOnChange.called.should.be.false + + helper.slider.applyModel(true) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) + }) + }) +})() diff --git a/tests/specs/helper.js b/tests/specs/helper.js index cb1f9cf..505d058 100644 --- a/tests/specs/helper.js +++ b/tests/specs/helper.js @@ -1,135 +1,307 @@ -(function() { - "use strict"; - var helperModule = angular.module('test-helper', ['rzModule', 'appTemplates']); +;(function() { + 'use strict' + var helperModule = angular.module('test-helper', ['rzSlider', 'appTemplates']) - helperModule.factory('TestHelper', function(RzSlider, RzSliderOptions, $rootScope, $compile, $timeout, $window, $document) { + helperModule.factory('TestHelper', function( + RzSlider, + RzSliderOptions, + $rootScope, + $compile, + $timeout, + $window, + $document + ) { var h = { element: null, scope: null, - parent: null - }; + parent: null, + } h.createSlider = function(sliderObj) { - var template = ''; - var optionsExpression = sliderObj.optionsExpression || 'slider.options'; + var template = '' + var optionsExpression = sliderObj.optionsExpression || 'slider.options' if (sliderObj.options || sliderObj.optionsExpression) - template = ''; - else - template = ''; - h.initSlider(sliderObj, template); - }; + template = + '' + else template = '' + h.initSlider(sliderObj, template) + } h.createRangeSlider = function(sliderObj) { - var template = ''; - var optionsExpression = sliderObj.optionsExpression || 'slider.options'; + var template = '' + var optionsExpression = sliderObj.optionsExpression || 'slider.options' if (sliderObj.options || sliderObj.optionsExpression) - template = ''; + template = + '' else - template = ''; - h.initSlider(sliderObj, template); - }; + template = + '' + h.initSlider(sliderObj, template) + } h.createRangeSliderWithCustomTemplate = function(sliderObj, templateUrl) { - var template = ''; - var optionsExpression = sliderObj.optionsExpression || 'slider.options'; + var template = '' + var optionsExpression = sliderObj.optionsExpression || 'slider.options' if (sliderObj.options || sliderObj.optionsExpression) - template = ''; + ' rz-slider-options="' + + optionsExpression + + '" rz-slider-tpl-url="' + + templateUrl + + '">' else - template = ''; - h.initSlider(sliderObj, template); - }; + template = + '' + h.initSlider(sliderObj, template) + } h.initSlider = function(sliderObj, template) { - h.scope = $rootScope.$new(); - h.scope.slider = sliderObj; - h.parent = angular.element('
'); - h.element = $compile(template)(h.scope); - h.parent.append(h.element); - angular.element(document).find('body').append(h.parent); - h.scope.$digest(); - h.slider = h.element.isolateScope().slider; - }; + h.scope = $rootScope.$new() + h.scope.slider = sliderObj + h.parent = angular.element( + '
' + ) + h.element = $compile(template)(h.scope) + h.parent.append(h.element) + angular + .element(document) + .find('body') + .append(h.parent) + h.scope.$digest() + h.slider = h.element.isolateScope().slider + } h.clean = function() { //simulate to $destroy event to clean everything - if (h.scope) - h.scope.$broadcast('$destroy'); + if (h.scope) h.scope.$broadcast('$destroy') //clean the element we append at each test - if (h.parent) - h.parent.remove(); - }; - + if (h.parent) h.parent.remove() + } h.fireMousedown = function(element, position, vertical) { - var positionProp = vertical ? 'clientY' : 'clientX'; + var positionProp = vertical ? 'clientY' : 'clientX' var event = { type: 'mousedown', preventDefault: sinon.stub(), - stopPropagation: sinon.stub() - }; - event[positionProp] = position; + stopPropagation: sinon.stub(), + } + event[positionProp] = position - element.triggerHandler(event); - return event; - }; + element.triggerHandler(event) + return event + } h.fireMousemove = function(position, vertical) { - var positionProp = vertical ? 'clientY' : 'clientX'; + var positionProp = vertical ? 'clientY' : 'clientX' var event = { - type: 'mousemove' - }; - event[positionProp] = position; + type: 'mousemove', + } + event[positionProp] = position - $document.triggerHandler(event); - }; + $document.triggerHandler(event) + } h.fireMouseup = function() { var event = { - type: 'mouseup' - }; - $document.triggerHandler(event); - }; + type: 'mouseup', + } + $document.triggerHandler(event) + } + + h.fireTouchstartWithOriginalEvent = function( + element, + position, + touchIdentifier, + touchesIds, + vertical + ) { + var event = { + type: 'touchstart', + originalEvent: this.getTouchEvent( + 'touchstart', + position, + vertical, + touchIdentifier, + touchesIds, + sinon.stub() + ), + } + + element.triggerHandler(event) + return event + } + + h.fireTouchstartWithoutOriginalEvent = function( + element, + position, + touchIdentifier, + touchesIds, + vertical + ) { + var event = this.getTouchEvent( + 'touchstart', + position, + vertical, + touchIdentifier, + touchesIds, + sinon.stub() + ) + + element.triggerHandler(event) + return event + } + + h.fireTouchmoveWithOriginalEvent = function( + position, + touchIdentifier, + touchesIds, + vertical + ) { + var event = { + type: 'touchmove', + originalEvent: this.getTouchEvent( + 'touchmove', + position, + vertical, + touchIdentifier, + touchesIds + ), + } + + $document.triggerHandler(event) + return event + } + + h.fireTouchmoveWithoutOriginalEvent = function( + position, + touchIdentifier, + touchesIds, + vertical + ) { + var event = this.getTouchEvent( + 'touchmove', + position, + vertical, + touchIdentifier, + touchesIds + ) + + $document.triggerHandler(event) + return event + } + + h.fireTouchendWithOriginalEvent = function( + touchIdentifier, + touchesIds, + vertical + ) { + var event = { + type: 'touchend', + originalEvent: this.getTouchEvent( + 'touchend', + 0, + vertical, + touchIdentifier, + touchesIds + ), + } + + $document.triggerHandler(event) + return event + } + + h.fireTouchendWithoutOriginalEvent = function( + touchIdentifier, + touchesIds, + vertical + ) { + var event = this.getTouchEvent( + 'touchend', + 0, + vertical, + touchIdentifier, + touchesIds + ) + + $document.triggerHandler(event) + return event + } + + h.getTouchEvent = function( + type, + position, + vertical, + changedTouchId, + touchesIds, + preventDefaultAndStopPropagation + ) { + var positionProp = vertical ? 'clientY' : 'clientX' + + var changedTouches = [{ identifier: changedTouchId }] + changedTouches[0][positionProp] = position + + var touches = [] + for (var i = 0; i < touchesIds.length; i++) { + var touch = { identifier: touchesIds[i] } + if (touch.identifier == changedTouchId) { + touch[positionProp] = position + } + touches.push(touch) + } + + var originalEvent = { + type: type, + preventDefault: preventDefaultAndStopPropagation, + stopPropagation: preventDefaultAndStopPropagation, + changedTouches: changedTouches, + touches: touches, + } + return originalEvent + } h.pressKeydown = function(element, key, options) { - options = options || {}; - key = key.toUpperCase(); + options = options || {} + key = key.toUpperCase() var event = { - type: 'keydown' - }; + type: 'keydown', + } var keys = { - 'UP': 38, - 'DOWN': 40, - 'LEFT': 37, - 'RIGHT': 39, - 'PAGEUP': 33, - 'PAGEDOWN': 34, - 'HOME': 36, - 'END': 35, - 'SPACE': 32 - }; - var keyCode = keys[key]; - if (options.oldAPI) - event.which = keyCode; - else event.keyCode = keyCode; - element.triggerHandler(event); - if (options.timeout !== false) - $timeout.flush(); - }; + UP: 38, + DOWN: 40, + LEFT: 37, + RIGHT: 39, + PAGEUP: 33, + PAGEDOWN: 34, + HOME: 36, + END: 35, + SPACE: 32, + } + var keyCode = keys[key] + if (options.oldAPI) event.which = keyCode + else event.keyCode = keyCode + element.triggerHandler(event) + if (options.timeout !== false) $timeout.flush() + } h.getMousePosition = function(value) { - return h.slider.valueToOffset(value) + h.slider.handleHalfDim + h.slider.sliderElem.rzsp; - }; + return ( + h.slider.valueToPosition(value) + + h.slider.handleHalfDim + + h.slider.sliderElem.rzsp + ) + } h.moveMouseToValue = function(value) { - h.fireMousemove(h.getMousePosition(value)); - }; + h.fireMousemove(h.getMousePosition(value)) + } - return h; - }); -}()); + return h + }) +})() diff --git a/tests/specs/keyboard-controls/draggableRangeOnly-range-slider-test.js b/tests/specs/keyboard-controls/draggableRangeOnly-range-slider-test.js index f973310..a439f06 100644 --- a/tests/specs/keyboard-controls/draggableRangeOnly-range-slider-test.js +++ b/tests/specs/keyboard-controls/draggableRangeOnly-range-slider-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Keyboard controls - draggableRangeOnly range slider', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -27,117 +29,119 @@ options: { floor: 0, ceil: 200, - draggableRangeOnly: true - } - }; - helper.createRangeSlider(sliderConf); - }); + draggableRangeOnly: true, + }, + } + helper.createRangeSlider(sliderConf) + }) it('should increment minH/maxH by 1 when RIGHT is pressed on minH', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - expect(helper.scope.slider.min).to.equal(91); - expect(helper.scope.slider.max).to.equal(111); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.min).to.equal(91) + expect(helper.scope.slider.max).to.equal(111) + }) it('should increment minH/maxH by 1 when RIGHT is pressed on maxH', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'RIGHT'); - expect(helper.scope.slider.min).to.equal(91); - expect(helper.scope.slider.max).to.equal(111); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'RIGHT') + expect(helper.scope.slider.min).to.equal(91) + expect(helper.scope.slider.max).to.equal(111) + }) it('should increment minH/maxH by 1 when LEFT is pressed on minH', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'LEFT'); - expect(helper.scope.slider.min).to.equal(89); - expect(helper.scope.slider.max).to.equal(109); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.min).to.equal(89) + expect(helper.scope.slider.max).to.equal(109) + }) it('should increment minH/maxH by 1 when LEFT is pressed on maxH', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'LEFT'); - expect(helper.scope.slider.min).to.equal(89); - expect(helper.scope.slider.max).to.equal(109); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'LEFT') + expect(helper.scope.slider.min).to.equal(89) + expect(helper.scope.slider.max).to.equal(109) + }) it('should increment minH/maxH by 10% when PAGEUP is pressed on minH', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'PAGEUP'); - expect(helper.scope.slider.min).to.equal(110); - expect(helper.scope.slider.max).to.equal(130); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'PAGEUP') + expect(helper.scope.slider.min).to.equal(110) + expect(helper.scope.slider.max).to.equal(130) + }) it('should increment minH/maxH by 10% when PAGEUP is pressed on maxH', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'PAGEUP'); - expect(helper.scope.slider.min).to.equal(110); - expect(helper.scope.slider.max).to.equal(130); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'PAGEUP') + expect(helper.scope.slider.min).to.equal(110) + expect(helper.scope.slider.max).to.equal(130) + }) it('should decrement minH/maxH by 10% when PAGEDOWN is pressed on minH', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'PAGEDOWN'); - expect(helper.scope.slider.min).to.equal(70); - expect(helper.scope.slider.max).to.equal(90); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'PAGEDOWN') + expect(helper.scope.slider.min).to.equal(70) + expect(helper.scope.slider.max).to.equal(90) + }) it('should decrement minH/maxH by 10% when PAGEDOWN is pressed on maxH', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'PAGEDOWN'); - expect(helper.scope.slider.min).to.equal(70); - expect(helper.scope.slider.max).to.equal(90); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'PAGEDOWN') + expect(helper.scope.slider.min).to.equal(70) + expect(helper.scope.slider.max).to.equal(90) + }) it('should set minH to min when HOME is pressed on minH', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'HOME'); - expect(helper.scope.slider.min).to.equal(0); - expect(helper.scope.slider.max).to.equal(20); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'HOME') + expect(helper.scope.slider.min).to.equal(0) + expect(helper.scope.slider.max).to.equal(20) + }) it('should set minH to min when HOME is pressed on maxH', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'HOME'); - expect(helper.scope.slider.min).to.equal(0); - expect(helper.scope.slider.max).to.equal(20); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'HOME') + expect(helper.scope.slider.min).to.equal(0) + expect(helper.scope.slider.max).to.equal(20) + }) it('should set minH to min when END is pressed on minH', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'END'); - expect(helper.scope.slider.min).to.equal(180); - expect(helper.scope.slider.max).to.equal(200); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'END') + expect(helper.scope.slider.min).to.equal(180) + expect(helper.scope.slider.max).to.equal(200) + }) it('should set minH to min when END is pressed on maxH', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'END'); - expect(helper.scope.slider.min).to.equal(180); - expect(helper.scope.slider.max).to.equal(200); - }); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'END') + expect(helper.scope.slider.min).to.equal(180) + expect(helper.scope.slider.max).to.equal(200) + }) + }) describe('Right to left Keyboard controls - draggableRangeOnly range slider', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) - beforeEach(inject(function (TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); - - afterEach(function () { - helper.clean(); - }); + afterEach(function() { + helper.clean() + }) - beforeEach(function () { + beforeEach(function() { var sliderConf = { min: 90, max: 110, @@ -145,95 +149,94 @@ floor: 0, ceil: 200, draggableRangeOnly: true, - rightToLeft: true - } - }; - helper.createRangeSlider(sliderConf); - }); + rightToLeft: true, + }, + } + helper.createRangeSlider(sliderConf) + }) it('should decrement minH/maxH by 1 when RIGHT is pressed on minH', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - expect(helper.scope.slider.min).to.equal(89); - expect(helper.scope.slider.max).to.equal(109); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.min).to.equal(89) + expect(helper.scope.slider.max).to.equal(109) + }) it('should decrement minH/maxH by 1 when RIGHT is pressed on maxH', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'RIGHT'); - expect(helper.scope.slider.min).to.equal(89); - expect(helper.scope.slider.max).to.equal(109); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'RIGHT') + expect(helper.scope.slider.min).to.equal(89) + expect(helper.scope.slider.max).to.equal(109) + }) it('should increment minH/maxH by 1 when LEFT is pressed on minH', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'LEFT'); - expect(helper.scope.slider.min).to.equal(91); - expect(helper.scope.slider.max).to.equal(111); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.min).to.equal(91) + expect(helper.scope.slider.max).to.equal(111) + }) it('should increment minH/maxH by 1 when LEFT is pressed on maxH', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'LEFT'); - expect(helper.scope.slider.min).to.equal(91); - expect(helper.scope.slider.max).to.equal(111); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'LEFT') + expect(helper.scope.slider.min).to.equal(91) + expect(helper.scope.slider.max).to.equal(111) + }) it('should increment minH/maxH by 10% when PAGEUP is pressed on minH', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'PAGEUP'); - expect(helper.scope.slider.min).to.equal(110); - expect(helper.scope.slider.max).to.equal(130); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'PAGEUP') + expect(helper.scope.slider.min).to.equal(110) + expect(helper.scope.slider.max).to.equal(130) + }) it('should increment minH/maxH by 10% when PAGEUP is pressed on maxH', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'PAGEUP'); - expect(helper.scope.slider.min).to.equal(110); - expect(helper.scope.slider.max).to.equal(130); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'PAGEUP') + expect(helper.scope.slider.min).to.equal(110) + expect(helper.scope.slider.max).to.equal(130) + }) it('should decrement minH/maxH by 10% when PAGEDOWN is pressed on minH', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'PAGEDOWN'); - expect(helper.scope.slider.min).to.equal(70); - expect(helper.scope.slider.max).to.equal(90); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'PAGEDOWN') + expect(helper.scope.slider.min).to.equal(70) + expect(helper.scope.slider.max).to.equal(90) + }) it('should decrement minH/maxH by 10% when PAGEDOWN is pressed on maxH', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'PAGEDOWN'); - expect(helper.scope.slider.min).to.equal(70); - expect(helper.scope.slider.max).to.equal(90); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'PAGEDOWN') + expect(helper.scope.slider.min).to.equal(70) + expect(helper.scope.slider.max).to.equal(90) + }) it('should set minH to min when HOME is pressed on minH', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'HOME'); - expect(helper.scope.slider.min).to.equal(0); - expect(helper.scope.slider.max).to.equal(20); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'HOME') + expect(helper.scope.slider.min).to.equal(0) + expect(helper.scope.slider.max).to.equal(20) + }) it('should set minH to min when HOME is pressed on maxH', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'HOME'); - expect(helper.scope.slider.min).to.equal(0); - expect(helper.scope.slider.max).to.equal(20); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'HOME') + expect(helper.scope.slider.min).to.equal(0) + expect(helper.scope.slider.max).to.equal(20) + }) it('should set minH to min when END is pressed on minH', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'END'); - expect(helper.scope.slider.min).to.equal(180); - expect(helper.scope.slider.max).to.equal(200); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'END') + expect(helper.scope.slider.min).to.equal(180) + expect(helper.scope.slider.max).to.equal(200) + }) it('should set minH to min when END is pressed on maxH', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'END'); - expect(helper.scope.slider.min).to.equal(180); - expect(helper.scope.slider.max).to.equal(200); - }); - }); -}()); - + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'END') + expect(helper.scope.slider.min).to.equal(180) + expect(helper.scope.slider.max).to.equal(200) + }) + }) +})() diff --git a/tests/specs/keyboard-controls/range-slider-test.js b/tests/specs/keyboard-controls/range-slider-test.js index 1780f7f..4ec4315 100644 --- a/tests/specs/keyboard-controls/range-slider-test.js +++ b/tests/specs/keyboard-controls/range-slider-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Keyboard controls - range slider', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -26,266 +28,266 @@ max: 100, options: { floor: 0, - ceil: 200 - } - }; - helper.createRangeSlider(sliderConf); - }); + ceil: 200, + }, + } + helper.createRangeSlider(sliderConf) + }) it('should toggle active style when handle focused/blured', function() { - helper.slider.minH.triggerHandler('focus'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - expect(helper.slider.maxH.hasClass('rz-active')).to.be.false; - helper.slider.minH.triggerHandler('blur'); - helper.slider.maxH.triggerHandler('focus'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.false; - expect(helper.slider.maxH.hasClass('rz-active')).to.be.true; - helper.slider.maxH.triggerHandler('blur'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.false; - expect(helper.slider.maxH.hasClass('rz-active')).to.be.false; - }); + helper.slider.minH.triggerHandler('focus') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + expect(helper.slider.maxH.hasClass('rz-active')).to.be.false + helper.slider.minH.triggerHandler('blur') + helper.slider.maxH.triggerHandler('focus') + expect(helper.slider.minH.hasClass('rz-active')).to.be.false + expect(helper.slider.maxH.hasClass('rz-active')).to.be.true + helper.slider.maxH.triggerHandler('blur') + expect(helper.slider.minH.hasClass('rz-active')).to.be.false + expect(helper.slider.maxH.hasClass('rz-active')).to.be.false + }) it('should increment minH by 1 when RIGHT is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - expect(helper.scope.slider.min).to.equal(51); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.min).to.equal(51) + }) it('should increment maxH by 1 when RIGHT is pressed', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'RIGHT'); - expect(helper.scope.slider.max).to.equal(101); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'RIGHT') + expect(helper.scope.slider.max).to.equal(101) + }) it('should decrement minH by 1 when LEFT is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'LEFT'); - expect(helper.scope.slider.min).to.equal(49); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.min).to.equal(49) + }) it('should decrement maxH by 1 when LEFT is pressed', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'LEFT'); - expect(helper.scope.slider.max).to.equal(99); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'LEFT') + expect(helper.scope.slider.max).to.equal(99) + }) it('should increment minH by 10% when PAGEUP is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'PAGEUP'); - expect(helper.scope.slider.min).to.equal(70); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'PAGEUP') + expect(helper.scope.slider.min).to.equal(70) + }) it('should increment maxH by 10% when PAGEUP is pressed', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'PAGEUP'); - expect(helper.scope.slider.max).to.equal(120); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'PAGEUP') + expect(helper.scope.slider.max).to.equal(120) + }) it('should decrement minH by 10% when PAGEDOWN is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'PAGEDOWN'); - expect(helper.scope.slider.min).to.equal(30); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'PAGEDOWN') + expect(helper.scope.slider.min).to.equal(30) + }) it('should decrement maxH by 10% when PAGEDOWN is pressed', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'PAGEDOWN'); - expect(helper.scope.slider.max).to.equal(80); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'PAGEDOWN') + expect(helper.scope.slider.max).to.equal(80) + }) it('should set minH to min when HOME is pressed on minH', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'HOME'); - expect(helper.scope.slider.min).to.equal(0); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'HOME') + expect(helper.scope.slider.min).to.equal(0) + }) it('should set minH value to previous min and switch min/max when HOME is pressed on maxH', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'HOME'); - expect(helper.scope.slider.min).to.equal(0); - expect(helper.scope.slider.max).to.equal(50); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'HOME') + expect(helper.scope.slider.min).to.equal(0) + expect(helper.scope.slider.max).to.equal(50) + }) it('should set minH value to previous max and switch min/max when END is pressed on minH', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'END'); - expect(helper.scope.slider.min).to.equal(100); - expect(helper.scope.slider.max).to.equal(200); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'END') + expect(helper.scope.slider.min).to.equal(100) + expect(helper.scope.slider.max).to.equal(200) + }) it('should set maxH value to max when END is pressed on maxH', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'END'); - expect(helper.scope.slider.max).to.equal(200); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'END') + expect(helper.scope.slider.max).to.equal(200) + }) it('should do nothing when SPACE is pressed on minH', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'SPACE'); - expect(helper.scope.slider.min).to.equal(50); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'SPACE') + expect(helper.scope.slider.min).to.equal(50) + }) it('should do nothing when SPACE is pressed on maxH', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'SPACE'); - expect(helper.scope.slider.max).to.equal(100); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'SPACE') + expect(helper.scope.slider.max).to.equal(100) + }) it('should not modify minH when keypress but not focused', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - expect(helper.scope.slider.min).to.equal(51); - helper.slider.minH.triggerHandler('blur'); - helper.pressKeydown(helper.slider.minH, 'RIGHT', {timeout: false}); - expect(helper.scope.slider.min).to.equal(51); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.min).to.equal(51) + helper.slider.minH.triggerHandler('blur') + helper.pressKeydown(helper.slider.minH, 'RIGHT', { timeout: false }) + expect(helper.scope.slider.min).to.equal(51) + }) it('should not modify maxH when keypress but not focused', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'RIGHT'); - expect(helper.scope.slider.max).to.equal(101); - helper.slider.maxH.triggerHandler('blur'); - helper.pressKeydown(helper.slider.maxH, 'RIGHT', {timeout: false}); - expect(helper.scope.slider.max).to.equal(101); - }); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'RIGHT') + expect(helper.scope.slider.max).to.equal(101) + helper.slider.maxH.triggerHandler('blur') + helper.pressKeydown(helper.slider.maxH, 'RIGHT', { timeout: false }) + expect(helper.scope.slider.max).to.equal(101) + }) + }) describe('Right to left Keyboard controls - range slider', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function (TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) - afterEach(function () { - helper.clean(); - }); + afterEach(function() { + helper.clean() + }) - beforeEach(function () { + beforeEach(function() { var sliderConf = { min: 50, max: 100, options: { floor: 0, ceil: 200, - rightToLeft: true - } - }; - helper.createRangeSlider(sliderConf); - }); + rightToLeft: true, + }, + } + helper.createRangeSlider(sliderConf) + }) it('should decrement minH by 1 when RIGHT is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - expect(helper.scope.slider.min).to.equal(49); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.min).to.equal(49) + }) it('should decrement maxH by 1 when RIGHT is pressed', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'RIGHT'); - expect(helper.scope.slider.max).to.equal(99); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'RIGHT') + expect(helper.scope.slider.max).to.equal(99) + }) it('should increment minH by 1 when LEFT is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'LEFT'); - expect(helper.scope.slider.min).to.equal(51); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.min).to.equal(51) + }) it('should increment maxH by 1 when LEFT is pressed', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'LEFT'); - expect(helper.scope.slider.max).to.equal(101); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'LEFT') + expect(helper.scope.slider.max).to.equal(101) + }) it('should increment minH by 10% when PAGEUP is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'PAGEUP'); - expect(helper.scope.slider.min).to.equal(70); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'PAGEUP') + expect(helper.scope.slider.min).to.equal(70) + }) it('should increment maxH by 10% when PAGEUP is pressed', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'PAGEUP'); - expect(helper.scope.slider.max).to.equal(120); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'PAGEUP') + expect(helper.scope.slider.max).to.equal(120) + }) it('should decrement minH by 10% when PAGEDOWN is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'PAGEDOWN'); - expect(helper.scope.slider.min).to.equal(30); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'PAGEDOWN') + expect(helper.scope.slider.min).to.equal(30) + }) it('should decrement maxH by 10% when PAGEDOWN is pressed', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'PAGEDOWN'); - expect(helper.scope.slider.max).to.equal(80); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'PAGEDOWN') + expect(helper.scope.slider.max).to.equal(80) + }) it('should set minH to min when HOME is pressed on minH', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'HOME'); - expect(helper.scope.slider.min).to.equal(0); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'HOME') + expect(helper.scope.slider.min).to.equal(0) + }) it('should set minH value to previous min and switch min/max when HOME is pressed on maxH', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'HOME'); - expect(helper.scope.slider.min).to.equal(0); - expect(helper.scope.slider.max).to.equal(50); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'HOME') + expect(helper.scope.slider.min).to.equal(0) + expect(helper.scope.slider.max).to.equal(50) + }) it('should set minH value to previous max and switch min/max when END is pressed on minH', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'END'); - expect(helper.scope.slider.min).to.equal(100); - expect(helper.scope.slider.max).to.equal(200); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'END') + expect(helper.scope.slider.min).to.equal(100) + expect(helper.scope.slider.max).to.equal(200) + }) it('should set maxH value to max when END is pressed on maxH', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'END'); - expect(helper.scope.slider.max).to.equal(200); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'END') + expect(helper.scope.slider.max).to.equal(200) + }) it('should do nothing when SPACE is pressed on minH', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'SPACE'); - expect(helper.scope.slider.min).to.equal(50); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'SPACE') + expect(helper.scope.slider.min).to.equal(50) + }) it('should do nothing when SPACE is pressed on maxH', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'SPACE'); - expect(helper.scope.slider.max).to.equal(100); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'SPACE') + expect(helper.scope.slider.max).to.equal(100) + }) it('should not modify minH when keypress but not focused', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - expect(helper.scope.slider.min).to.equal(49); - helper.slider.minH.triggerHandler('blur'); - helper.pressKeydown(helper.slider.minH, 'RIGHT', {timeout: false}); - expect(helper.scope.slider.min).to.equal(49); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.min).to.equal(49) + helper.slider.minH.triggerHandler('blur') + helper.pressKeydown(helper.slider.minH, 'RIGHT', { timeout: false }) + expect(helper.scope.slider.min).to.equal(49) + }) it('should not modify maxH when keypress but not focused', function() { - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'RIGHT'); - expect(helper.scope.slider.max).to.equal(99); - helper.slider.maxH.triggerHandler('blur'); - helper.pressKeydown(helper.slider.maxH, 'RIGHT', {timeout: false}); - expect(helper.scope.slider.max).to.equal(99); - }); - - }); -}()); - + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'RIGHT') + expect(helper.scope.slider.max).to.equal(99) + helper.slider.maxH.triggerHandler('blur') + helper.pressKeydown(helper.slider.maxH, 'RIGHT', { timeout: false }) + expect(helper.scope.slider.max).to.equal(99) + }) + }) +})() diff --git a/tests/specs/keyboard-controls/single-slider-test.js b/tests/specs/keyboard-controls/single-slider-test.js index 898fa70..e977f9d 100644 --- a/tests/specs/keyboard-controls/single-slider-test.js +++ b/tests/specs/keyboard-controls/single-slider-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Keyboard controls - single slider', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -28,226 +30,482 @@ ceil: 200, onStart: sinon.spy(), onChange: sinon.spy(), - onEnd: sinon.spy() - } - }; - helper.createSlider(sliderConf); - }); + onEnd: sinon.spy(), + }, + } + helper.createSlider(sliderConf) + }) it('should call onStart on the first keydown but not after', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - helper.scope.slider.options.onStart.callCount === 1; - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - helper.scope.slider.options.onStart.callCount === 1; - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + helper.scope.slider.options.onStart.callCount === 1 + helper.pressKeydown(helper.slider.minH, 'RIGHT') + helper.scope.slider.options.onStart.callCount === 1 + }) it('should call onChange on each keydown but after a timeout', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT', {timeout: false}); - $timeout.flush(); - helper.scope.slider.options.onChange.callCount === 1; - helper.pressKeydown(helper.slider.minH, 'RIGHT', {timeout: false}); - $timeout.flush(); - helper.scope.slider.options.onChange.callCount === 1; - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT', { timeout: false }) + $timeout.flush() + helper.scope.slider.options.onChange.callCount === 1 + helper.pressKeydown(helper.slider.minH, 'RIGHT', { timeout: false }) + $timeout.flush() + helper.scope.slider.options.onChange.callCount === 1 + }) it('should call onEnd on keyup and recall onStart if key is down again', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - helper.slider.minH.triggerHandler({type: 'keyup'}); - helper.scope.slider.options.onStart.callCount === 1; - helper.scope.slider.options.onEnd.callCount === 1; - - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - helper.slider.minH.triggerHandler({type: 'keyup'}); - helper.scope.slider.options.onStart.callCount === 2; - helper.scope.slider.options.onEnd.callCount === 2; - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + helper.slider.minH.triggerHandler({ type: 'keyup' }) + helper.scope.slider.options.onStart.callCount === 1 + helper.scope.slider.options.onEnd.callCount === 1 + + helper.pressKeydown(helper.slider.minH, 'RIGHT') + helper.slider.minH.triggerHandler({ type: 'keyup' }) + helper.scope.slider.options.onStart.callCount === 2 + helper.scope.slider.options.onEnd.callCount === 2 + }) it('should toggle active style when handle focused/blured', function() { - helper.slider.minH.triggerHandler('focus'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - helper.slider.minH.triggerHandler('blur'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.false; - }); + helper.slider.minH.triggerHandler('focus') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + helper.slider.minH.triggerHandler('blur') + expect(helper.slider.minH.hasClass('rz-active')).to.be.false + }) it('should increment by 1 when RIGHT is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - expect(helper.scope.slider.value).to.equal(101); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.value).to.equal(101) + }) it('should increment by 1 when RIGHT is pressed with oldAPI', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT', {oldAPI: true}); - expect(helper.scope.slider.value).to.equal(101); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT', { oldAPI: true }) + expect(helper.scope.slider.value).to.equal(101) + }) it('should decrement by 1 when LEFT is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'LEFT'); - expect(helper.scope.slider.value).to.equal(99); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.value).to.equal(99) + }) it('should increment by 1 when UP is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'UP'); - expect(helper.scope.slider.value).to.equal(101); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'UP') + expect(helper.scope.slider.value).to.equal(101) + }) it('should decrement by 1 when DOWN is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'DOWN'); - expect(helper.scope.slider.value).to.equal(99); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'DOWN') + expect(helper.scope.slider.value).to.equal(99) + }) it('should increment by 10% when PAGEUP is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'PAGEUP'); - expect(helper.scope.slider.value).to.equal(120); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'PAGEUP') + expect(helper.scope.slider.value).to.equal(120) + }) it('should decrement by 10% when PAGEDOWN is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'PAGEDOWN'); - expect(helper.scope.slider.value).to.equal(80); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'PAGEDOWN') + expect(helper.scope.slider.value).to.equal(80) + }) it('should set value to min when HOME is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'HOME'); - expect(helper.scope.slider.value).to.equal(0); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'HOME') + expect(helper.scope.slider.value).to.equal(0) + }) it('should set value to max when END is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'END'); - expect(helper.scope.slider.value).to.equal(200); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'END') + expect(helper.scope.slider.value).to.equal(200) + }) it('should do nothing when SPACE is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'SPACE'); - expect(helper.scope.slider.value).to.equal(100); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'SPACE') + expect(helper.scope.slider.value).to.equal(100) + }) it('should not modify when keypress but not focused', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - expect(helper.scope.slider.value).to.equal(101); - helper.slider.minH.triggerHandler('blur'); - helper.pressKeydown(helper.slider.minH, 'RIGHT', {timeout: false}); - expect(helper.scope.slider.value).to.equal(101); - }); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.value).to.equal(101) + helper.slider.minH.triggerHandler('blur') + helper.pressKeydown(helper.slider.minH, 'RIGHT', { timeout: false }) + expect(helper.scope.slider.value).to.equal(101) + }) + }) describe('Right to left Keyboard controls - single slider', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function (TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) - afterEach(function () { - helper.clean(); - }); + afterEach(function() { + helper.clean() + }) - beforeEach(function () { + beforeEach(function() { var sliderConf = { value: 100, options: { floor: 0, ceil: 200, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + }) it('should toggle active style when handle focused/blured', function() { - helper.slider.minH.triggerHandler('focus'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - helper.slider.minH.triggerHandler('blur'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.false; - }); + helper.slider.minH.triggerHandler('focus') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + helper.slider.minH.triggerHandler('blur') + expect(helper.slider.minH.hasClass('rz-active')).to.be.false + }) it('should decrement by 1 when RIGHT is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - expect(helper.scope.slider.value).to.equal(99); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.value).to.equal(99) + }) it('should decrement by 1 when RIGHT is pressed with oldAPI', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT', true); - expect(helper.scope.slider.value).to.equal(99); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT', true) + expect(helper.scope.slider.value).to.equal(99) + }) it('should increment by 1 when LEFT is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'LEFT'); - expect(helper.scope.slider.value).to.equal(101); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.value).to.equal(101) + }) it('should increment by 1 when UP is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'UP'); - expect(helper.scope.slider.value).to.equal(101); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'UP') + expect(helper.scope.slider.value).to.equal(101) + }) it('should decrement by 1 when DOWN is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'DOWN'); - expect(helper.scope.slider.value).to.equal(99); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'DOWN') + expect(helper.scope.slider.value).to.equal(99) + }) it('should increment by 10% when PAGEUP is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'PAGEUP'); - expect(helper.scope.slider.value).to.equal(120); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'PAGEUP') + expect(helper.scope.slider.value).to.equal(120) + }) it('should decrement by 10% when PAGEDOWN is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'PAGEDOWN'); - expect(helper.scope.slider.value).to.equal(80); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'PAGEDOWN') + expect(helper.scope.slider.value).to.equal(80) + }) it('should set value to min when HOME is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'HOME'); - expect(helper.scope.slider.value).to.equal(0); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'HOME') + expect(helper.scope.slider.value).to.equal(0) + }) it('should set value to max when END is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'END'); - expect(helper.scope.slider.value).to.equal(200); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'END') + expect(helper.scope.slider.value).to.equal(200) + }) it('should do nothing when SPACE is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'SPACE'); - expect(helper.scope.slider.value).to.equal(100); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'SPACE') + expect(helper.scope.slider.value).to.equal(100) + }) it('should not modify when keypress but not focused', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - expect(helper.scope.slider.value).to.equal(99); - helper.slider.minH.triggerHandler('blur'); - helper.pressKeydown(helper.slider.minH, 'RIGHT', {timeout: false}); - expect(helper.scope.slider.value).to.equal(99); - }); - }); -}()); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.value).to.equal(99) + helper.slider.minH.triggerHandler('blur') + helper.pressKeydown(helper.slider.minH, 'RIGHT', { timeout: false }) + expect(helper.scope.slider.value).to.equal(99) + }) + }) + + describe('Keyboard controls - single slider with reversed controls flag', function() { + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) + + afterEach(function() { + helper.clean() + }) + + beforeEach(function() { + var sliderConf = { + value: 100, + options: { + floor: 0, + ceil: 200, + onStart: sinon.spy(), + onChange: sinon.spy(), + onEnd: sinon.spy(), + reversedControls: true, + }, + } + helper.createSlider(sliderConf) + }) + + it('should call onStart on the first keydown but not after', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + helper.scope.slider.options.onStart.callCount === 1 + helper.pressKeydown(helper.slider.minH, 'LEFT') + helper.scope.slider.options.onStart.callCount === 1 + }) + + it('should call onChange on each keydown but after a timeout', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT', { timeout: false }) + $timeout.flush() + helper.scope.slider.options.onChange.callCount === 1 + helper.pressKeydown(helper.slider.minH, 'LEFT', { timeout: false }) + $timeout.flush() + helper.scope.slider.options.onChange.callCount === 1 + }) + + it('should call onEnd on keyup and recall onStart if key is down again', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + helper.slider.minH.triggerHandler({ type: 'keyup' }) + helper.scope.slider.options.onStart.callCount === 1 + helper.scope.slider.options.onEnd.callCount === 1 + + helper.pressKeydown(helper.slider.minH, 'LEFT') + helper.slider.minH.triggerHandler({ type: 'keyup' }) + helper.scope.slider.options.onStart.callCount === 2 + helper.scope.slider.options.onEnd.callCount === 2 + }) + + it('should toggle active style when handle focused/blured', function() { + helper.slider.minH.triggerHandler('focus') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + helper.slider.minH.triggerHandler('blur') + expect(helper.slider.minH.hasClass('rz-active')).to.be.false + }) + + it('should increment by 1 when RIGHT is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.value).to.equal(101) + }) + it('should increment by 1 when LEFT is pressed with oldAPI', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT', { oldAPI: true }) + expect(helper.scope.slider.value).to.equal(101) + }) + + it('should decrement by 1 when RIGHT is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.value).to.equal(99) + }) + + it('should increment by 1 when DOWN is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'DOWN') + expect(helper.scope.slider.value).to.equal(101) + }) + + it('should decrement by 1 when UP is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'UP') + expect(helper.scope.slider.value).to.equal(99) + }) + + it('should increment by 10% when PAGEDOWN is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'PAGEDOWN') + expect(helper.scope.slider.value).to.equal(120) + }) + + it('should decrement by 10% when PAGEUP is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'PAGEUP') + expect(helper.scope.slider.value).to.equal(80) + }) + + it('should set value to min when END is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'END') + expect(helper.scope.slider.value).to.equal(0) + }) + + it('should set value to max when HOME is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'HOME') + expect(helper.scope.slider.value).to.equal(200) + }) + + it('should do nothing when SPACE is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'SPACE') + expect(helper.scope.slider.value).to.equal(100) + }) + + it('should not modify when keypress but not focused', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.value).to.equal(101) + helper.slider.minH.triggerHandler('blur') + helper.pressKeydown(helper.slider.minH, 'LEFT', { timeout: false }) + expect(helper.scope.slider.value).to.equal(101) + }) + }) + + describe('Right to left Keyboard controls - single slider with reversed controls flag', function() { + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) + + afterEach(function() { + helper.clean() + }) + + beforeEach(function() { + var sliderConf = { + value: 100, + options: { + floor: 0, + ceil: 200, + rightToLeft: true, + reversedControls: true, + }, + } + helper.createSlider(sliderConf) + }) + + it('should toggle active style when handle focused/blured', function() { + helper.slider.minH.triggerHandler('focus') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + helper.slider.minH.triggerHandler('blur') + expect(helper.slider.minH.hasClass('rz-active')).to.be.false + }) + + it('should decrement by 1 when LEFT is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.value).to.equal(99) + }) + + it('should decrement by 1 when LEFT is pressed with oldAPI', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT', true) + expect(helper.scope.slider.value).to.equal(99) + }) + + it('should increment by 1 when RIGHT is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.value).to.equal(101) + }) + + it('should increment by 1 when DOWN is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'DOWN') + expect(helper.scope.slider.value).to.equal(101) + }) + + it('should decrement by 1 when UP is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'UP') + expect(helper.scope.slider.value).to.equal(99) + }) + + it('should increment by 10% when PAGEDOWN is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'PAGEDOWN') + expect(helper.scope.slider.value).to.equal(120) + }) + + it('should decrement by 10% when PAGEUP is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'PAGEUP') + expect(helper.scope.slider.value).to.equal(80) + }) + + it('should set value to min when END is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'END') + expect(helper.scope.slider.value).to.equal(0) + }) + + it('should set value to max when HOME is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'HOME') + expect(helper.scope.slider.value).to.equal(200) + }) + + it('should do nothing when SPACE is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'SPACE') + expect(helper.scope.slider.value).to.equal(100) + }) + + it('should not modify when keypress but not focused', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.value).to.equal(99) + helper.slider.minH.triggerHandler('blur') + helper.pressKeydown(helper.slider.minH, 'LEFT', { timeout: false }) + expect(helper.scope.slider.value).to.equal(99) + }) + }) +})() diff --git a/tests/specs/keyboard-controls/specific-test.js b/tests/specs/keyboard-controls/specific-test.js index ada0386..89d87dd 100644 --- a/tests/specs/keyboard-controls/specific-test.js +++ b/tests/specs/keyboard-controls/specific-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Keyboard controls - specific tests', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) it('should not go below floor', function() { var sliderConf = { @@ -26,14 +28,14 @@ options: { floor: 0, ceil: 1000, - step: 10 - } - }; - helper.createSlider(sliderConf); - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'PAGEDOWN'); - expect(helper.scope.slider.value).to.equal(0); - }); + step: 10, + }, + } + helper.createSlider(sliderConf) + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'PAGEDOWN') + expect(helper.scope.slider.value).to.equal(0) + }) it('should not go above ceil', function() { var sliderConf = { @@ -41,14 +43,14 @@ options: { floor: 0, ceil: 1000, - step: 10 - } - }; - helper.createSlider(sliderConf); - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'PAGEUP'); - expect(helper.scope.slider.value).to.equal(1000); - }); + step: 10, + }, + } + helper.createSlider(sliderConf) + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'PAGEUP') + expect(helper.scope.slider.value).to.equal(1000) + }) it('should not be modified by keyboard if disabled=true', function() { var sliderConf = { @@ -56,14 +58,14 @@ options: { floor: 0, ceil: 100, - disabled: true - } - }; - helper.createSlider(sliderConf); - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'LEFT'); - expect(helper.scope.slider.value).to.equal(10); - }); + disabled: true, + }, + } + helper.createSlider(sliderConf) + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.value).to.equal(10) + }) it('should not be modified by keyboard if readOnly=true', function() { var sliderConf = { @@ -71,14 +73,14 @@ options: { floor: 0, ceil: 100, - readOnly: true - } - }; - helper.createSlider(sliderConf); - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'LEFT'); - expect(helper.scope.slider.value).to.equal(10); - }); + readOnly: true, + }, + } + helper.createSlider(sliderConf) + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.value).to.equal(10) + }) it('should not be modified by keyboard if new range is below minRange', function() { var sliderConf = { @@ -88,20 +90,20 @@ floor: 0, ceil: 100, step: 1, - minRange: 10 - } - }; - helper.createRangeSlider(sliderConf); + minRange: 10, + }, + } + helper.createRangeSlider(sliderConf) //try to move minH right - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - expect(helper.scope.slider.min).to.equal(45); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.min).to.equal(45) //try to move maxH left - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'LEFT'); - expect(helper.scope.slider.max).to.equal(55); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'LEFT') + expect(helper.scope.slider.max).to.equal(55) + }) it('should be modified by keyboard if new range is above minRange', function() { var sliderConf = { @@ -111,21 +113,21 @@ floor: 0, ceil: 100, step: 1, - minRange: 10 - } - }; - helper.createRangeSlider(sliderConf); + minRange: 10, + }, + } + helper.createRangeSlider(sliderConf) //try to move minH left - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'LEFT'); - expect(helper.scope.slider.min).to.equal(44); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.min).to.equal(44) //try to move maxH right - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'RIGHT'); - expect(helper.scope.slider.max).to.equal(56); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'RIGHT') + expect(helper.scope.slider.max).to.equal(56) + }) it('should not be modified by keyboard if new range is above maxRange', function() { var sliderConf = { @@ -135,20 +137,20 @@ floor: 0, ceil: 100, step: 1, - maxRange: 10 - } - }; - helper.createRangeSlider(sliderConf); + maxRange: 10, + }, + } + helper.createRangeSlider(sliderConf) //try to move minH left - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'LEFT'); - expect(helper.scope.slider.min).to.equal(45); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.min).to.equal(45) //try to move maxH right - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'RIGHT'); - expect(helper.scope.slider.max).to.equal(55); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'RIGHT') + expect(helper.scope.slider.max).to.equal(55) + }) it('should be modified by keyboard if new range is below maxRange', function() { var sliderConf = { @@ -158,21 +160,21 @@ floor: 0, ceil: 100, step: 1, - maxRange: 10 - } - }; - helper.createRangeSlider(sliderConf); + maxRange: 10, + }, + } + helper.createRangeSlider(sliderConf) //try to move minH right - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - expect(helper.scope.slider.min).to.equal(46); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.min).to.equal(46) //try to move maxH left - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'LEFT'); - expect(helper.scope.slider.max).to.equal(54); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'LEFT') + expect(helper.scope.slider.max).to.equal(54) + }) it('should be modified by keyboard if new value is above minLimit', function() { var sliderConf = { @@ -181,15 +183,15 @@ floor: 0, ceil: 100, step: 1, - minLimit: 10 - } - }; - helper.createSlider(sliderConf); + minLimit: 10, + }, + } + helper.createSlider(sliderConf) //try to move minH right - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - expect(helper.scope.slider.value).to.equal(11); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.value).to.equal(11) + }) it('should not be modified by keyboard if new value is below minLimit', function() { var sliderConf = { @@ -198,15 +200,15 @@ floor: 0, ceil: 100, step: 1, - minLimit: 10 - } - }; - helper.createSlider(sliderConf); + minLimit: 10, + }, + } + helper.createSlider(sliderConf) //try to move minH left - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'LEFT'); - expect(helper.scope.slider.value).to.equal(10); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.value).to.equal(10) + }) it('should be modified by keyboard if new value is below maxLimit', function() { var sliderConf = { @@ -215,15 +217,15 @@ floor: 0, ceil: 100, step: 1, - maxLimit: 90 - } - }; - helper.createSlider(sliderConf); + maxLimit: 90, + }, + } + helper.createSlider(sliderConf) //try to move minH left - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'LEFT'); - expect(helper.scope.slider.value).to.equal(89); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.value).to.equal(89) + }) it('should not be modified by keyboard if new value is above maxLimit', function() { var sliderConf = { @@ -232,15 +234,15 @@ floor: 0, ceil: 100, step: 1, - maxLimit: 90 - } - }; - helper.createSlider(sliderConf); + maxLimit: 90, + }, + } + helper.createSlider(sliderConf) //try to move minH right - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - expect(helper.scope.slider.value).to.equal(90); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.value).to.equal(90) + }) it('should refocus the slider after a reset if needed and still handle keyboard', function() { var sliderConf = { @@ -248,39 +250,41 @@ options: { floor: 0, ceil: 100, - step: 1 - } - }; - helper.createSlider(sliderConf); + step: 1, + }, + } + helper.createSlider(sliderConf) //try to move minH right - helper.slider.minH.triggerHandler('focus'); + helper.slider.minH.triggerHandler('focus') - helper.slider.resetSlider(); + helper.slider.resetSlider() - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - expect(document.activeElement).to.equal(helper.slider.minH[0]); - expect(helper.scope.slider.value).to.equal(91); - }); - }); + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(document.activeElement).to.equal(helper.slider.minH[0]) + expect(helper.scope.slider.value).to.equal(91) + }) + }) describe('Right to left Keyboard controls - specific tests', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) - beforeEach(inject(function (TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); - - afterEach(function () { - helper.clean(); - }); + afterEach(function() { + helper.clean() + }) it('should not go below floor', function() { var sliderConf = { @@ -289,14 +293,14 @@ floor: 0, ceil: 1000, step: 10, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'PAGEDOWN'); - expect(helper.scope.slider.value).to.equal(0); - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'PAGEDOWN') + expect(helper.scope.slider.value).to.equal(0) + }) it('should not go above ceil', function() { var sliderConf = { @@ -305,14 +309,14 @@ floor: 0, ceil: 1000, step: 10, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'PAGEUP'); - expect(helper.scope.slider.value).to.equal(1000); - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'PAGEUP') + expect(helper.scope.slider.value).to.equal(1000) + }) it('should not be modified by keyboard if disabled=true', function() { var sliderConf = { @@ -321,14 +325,14 @@ floor: 0, ceil: 100, disabled: true, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'LEFT'); - expect(helper.scope.slider.value).to.equal(10); - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.value).to.equal(10) + }) it('should not be modified by keyboard if readOnly=true', function() { var sliderConf = { @@ -337,14 +341,14 @@ floor: 0, ceil: 100, readOnly: true, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'LEFT'); - expect(helper.scope.slider.value).to.equal(10); - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.value).to.equal(10) + }) it('should not be modified by keyboard if new range is below minRange', function() { var sliderConf = { @@ -355,20 +359,20 @@ ceil: 100, step: 1, minRange: 10, - rightToLeft: true - } - }; - helper.createRangeSlider(sliderConf); + rightToLeft: true, + }, + } + helper.createRangeSlider(sliderConf) //try to move minH left ( increase in rtl ) - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'LEFT'); - expect(helper.scope.slider.min).to.equal(45); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.min).to.equal(45) //try to move maxH right (decrease in rtl ) - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'RIGHT'); - expect(helper.scope.slider.max).to.equal(55); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'RIGHT') + expect(helper.scope.slider.max).to.equal(55) + }) it('should be modified by keyboard if new range is above minRange', function() { var sliderConf = { @@ -379,21 +383,21 @@ ceil: 100, step: 1, minRange: 10, - rightToLeft: true - } - }; - helper.createRangeSlider(sliderConf); + rightToLeft: true, + }, + } + helper.createRangeSlider(sliderConf) //try to move minH RIGHT - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - expect(helper.scope.slider.min).to.equal(44); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.min).to.equal(44) //try to move maxH LEFT - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'LEFT'); - expect(helper.scope.slider.max).to.equal(56); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'LEFT') + expect(helper.scope.slider.max).to.equal(56) + }) it('should not be modified by keyboard if new range is above maxRange', function() { var sliderConf = { @@ -404,20 +408,20 @@ ceil: 100, step: 1, maxRange: 10, - rightToLeft: true - } - }; - helper.createRangeSlider(sliderConf); + rightToLeft: true, + }, + } + helper.createRangeSlider(sliderConf) //try to move minH right ( increase in rtl ) - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - expect(helper.scope.slider.min).to.equal(45); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.min).to.equal(45) //try to move maxH left (decrease in rtl ) - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'LEFT'); - expect(helper.scope.slider.max).to.equal(55); - }); + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'LEFT') + expect(helper.scope.slider.max).to.equal(55) + }) it('should be modified by keyboard if new range is below maxRange', function() { var sliderConf = { @@ -428,21 +432,20 @@ ceil: 100, step: 1, maxRange: 10, - rightToLeft: true - } - }; - helper.createRangeSlider(sliderConf); + rightToLeft: true, + }, + } + helper.createRangeSlider(sliderConf) //try to move minH LEFT - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'LEFT'); - expect(helper.scope.slider.min).to.equal(46); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.min).to.equal(46) //try to move maxH RIGHT - helper.slider.maxH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.maxH, 'RIGHT'); - expect(helper.scope.slider.max).to.equal(54); - }); - }); -}()); - + helper.slider.maxH.triggerHandler('focus') + helper.pressKeydown(helper.slider.maxH, 'RIGHT') + expect(helper.scope.slider.max).to.equal(54) + }) + }) +})() diff --git a/tests/specs/keyboard-controls/vertical-slider-test.js b/tests/specs/keyboard-controls/vertical-slider-test.js index 6fe7b84..0a4a0bf 100644 --- a/tests/specs/keyboard-controls/vertical-slider-test.js +++ b/tests/specs/keyboard-controls/vertical-slider-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Keyboard controls - vertical slider', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -26,55 +28,116 @@ options: { floor: 0, ceil: 200, - vertical: true - } - }; - helper.createSlider(sliderConf); - }); + vertical: true, + }, + } + helper.createSlider(sliderConf) + }) it('should increment by 1 when RIGHT is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - expect(helper.scope.slider.value).to.equal(101); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.value).to.equal(101) + }) it('should increment by 1 when UP is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'UP'); - expect(helper.scope.slider.value).to.equal(101); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'UP') + expect(helper.scope.slider.value).to.equal(101) + }) it('should decrement by 1 when DOWN is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'DOWN'); - expect(helper.scope.slider.value).to.equal(99); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'DOWN') + expect(helper.scope.slider.value).to.equal(99) + }) it('should decrement by 1 when LEFT is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'LEFT'); - expect(helper.scope.slider.value).to.equal(99); - }); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.value).to.equal(99) + }) + }) + + describe('Keyboard controls - vertical slider with reverserControls', function() { + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) - describe('Right to left Keyboard controls - vertical slider', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; + afterEach(function() { + helper.clean() + }) + + beforeEach(function() { + var sliderConf = { + value: 100, + options: { + floor: 0, + ceil: 200, + vertical: true, + reversedControls: true, + }, + } + helper.createSlider(sliderConf) + }) + + it('should increment by 1 when LEFT is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.value).to.equal(101) + }) - beforeEach(module('test-helper')); + it('should increment by 1 when DOWN is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'DOWN') + expect(helper.scope.slider.value).to.equal(101) + }) + + it('should decrement by 1 when UP is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'UP') + expect(helper.scope.slider.value).to.equal(99) + }) + + it('should decrement by 1 when RIGHT is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.value).to.equal(99) + }) + }) - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + describe('Right to left Keyboard controls - vertical slider', function() { + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -83,37 +146,96 @@ floor: 0, ceil: 200, vertical: true, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + }) it('should decrement by 1 when RIGHT is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'RIGHT'); - expect(helper.scope.slider.value).to.equal(99); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.value).to.equal(99) + }) it('should decrement by 1 when UP is pressed', function() { //while not strictly left to right this does allow also reversing vertical bars - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'UP'); - expect(helper.scope.slider.value).to.equal(99); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'UP') + expect(helper.scope.slider.value).to.equal(99) + }) it('should increment by 1 when DOWN is pressed', function() { //while not strictly left to right this does allow also reversing vertical bars - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'DOWN'); - expect(helper.scope.slider.value).to.equal(101); - }); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'DOWN') + expect(helper.scope.slider.value).to.equal(101) + }) it('should increment by 1 when LEFT is pressed', function() { - helper.slider.minH.triggerHandler('focus'); - helper.pressKeydown(helper.slider.minH, 'LEFT'); - expect(helper.scope.slider.value).to.equal(101); - }); - }); -}()); + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.value).to.equal(101) + }) + }) + + describe('Right to left Keyboard controls - vertical slider', function() { + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) + + afterEach(function() { + helper.clean() + }) + + beforeEach(function() { + var sliderConf = { + value: 100, + options: { + floor: 0, + ceil: 200, + vertical: true, + rightToLeft: true, + reversedControls: true, + }, + } + helper.createSlider(sliderConf) + }) + + it('should decrement by 1 when LEFT is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'LEFT') + expect(helper.scope.slider.value).to.equal(99) + }) + it('should decrement by 1 when DOWN is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'DOWN') + expect(helper.scope.slider.value).to.equal(99) + }) + + it('should increment by 1 when UP is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'UP') + expect(helper.scope.slider.value).to.equal(101) + }) + + it('should increment by 1 when RIGHT is pressed', function() { + helper.slider.minH.triggerHandler('focus') + helper.pressKeydown(helper.slider.minH, 'RIGHT') + expect(helper.scope.slider.value).to.equal(101) + }) + }) +})() diff --git a/tests/specs/labels-test.js b/tests/specs/labels-test.js index 241d7a3..30c3dcc 100644 --- a/tests/specs/labels-test.js +++ b/tests/specs/labels-test.js @@ -1,63 +1,65 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Single slider initialisation - ', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) it('should display floor and ceil labels when handle is at the middle', function() { var sliderConf = { value: 50, options: { floor: 0, - ceil: 100 - } - }; - helper.createSlider(sliderConf); - expect(helper.slider.flrLab.css('visibility')).to.equal('visible'); - expect(helper.slider.ceilLab.css('visibility')).to.equal('visible'); - }); + ceil: 100, + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.flrLab.css('visibility')).to.equal('visible') + expect(helper.slider.ceilLab.css('visibility')).to.equal('visible') + }) it('should hide floor and display ceil labels when handle is at min', function() { var sliderConf = { value: 0, options: { floor: 0, - ceil: 100 - } - }; - helper.createSlider(sliderConf); - expect(helper.slider.flrLab.css('visibility')).to.equal('hidden'); - expect(helper.slider.ceilLab.css('visibility')).to.equal('visible'); - }); + ceil: 100, + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.flrLab.css('visibility')).to.equal('hidden') + expect(helper.slider.ceilLab.css('visibility')).to.equal('visible') + }) it('should show floor and hide ceil labels when handle is at max', function() { var sliderConf = { value: 100, options: { floor: 0, - ceil: 100 - } - }; - helper.createSlider(sliderConf); - expect(helper.slider.flrLab.css('visibility')).to.equal('visible'); - expect(helper.slider.ceilLab.css('visibility')).to.equal('hidden'); - }); + ceil: 100, + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.flrLab.css('visibility')).to.equal('visible') + expect(helper.slider.ceilLab.css('visibility')).to.equal('hidden') + }) it('should display floor and ceil labels when handle is at the middle for RTL slider', function() { var sliderConf = { @@ -65,13 +67,13 @@ options: { floor: 0, ceil: 100, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - expect(helper.slider.flrLab.css('visibility')).to.equal('visible'); - expect(helper.slider.ceilLab.css('visibility')).to.equal('visible'); - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.flrLab.css('visibility')).to.equal('visible') + expect(helper.slider.ceilLab.css('visibility')).to.equal('visible') + }) it('should hide floor and display ceil labels when handle is at min for RTL slider', function() { var sliderConf = { @@ -79,13 +81,13 @@ options: { floor: 0, ceil: 100, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - expect(helper.slider.flrLab.css('visibility')).to.equal('hidden'); - expect(helper.slider.ceilLab.css('visibility')).to.equal('visible'); - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.flrLab.css('visibility')).to.equal('hidden') + expect(helper.slider.ceilLab.css('visibility')).to.equal('visible') + }) it('should show floor and hide ceil labels when handle is at max for RTL slider', function() { var sliderConf = { @@ -93,13 +95,13 @@ options: { floor: 0, ceil: 100, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - expect(helper.slider.flrLab.css('visibility')).to.equal('visible'); - expect(helper.slider.ceilLab.css('visibility')).to.equal('hidden'); - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.flrLab.css('visibility')).to.equal('visible') + expect(helper.slider.ceilLab.css('visibility')).to.equal('hidden') + }) it('should hide floor and ceil labels when minHandle is at min and maxHandle at max for range slider', function() { var sliderConf = { @@ -107,13 +109,13 @@ max: 100, options: { floor: 0, - ceil: 100 - } - }; - helper.createRangeSlider(sliderConf); - expect(helper.slider.flrLab.css('visibility')).to.equal('hidden'); - expect(helper.slider.ceilLab.css('visibility')).to.equal('hidden'); - }); + ceil: 100, + }, + } + helper.createRangeSlider(sliderConf) + expect(helper.slider.flrLab.css('visibility')).to.equal('hidden') + expect(helper.slider.ceilLab.css('visibility')).to.equal('hidden') + }) it('should hide floor and ceil labels when minHandle is at min and maxHandle at max for range RTL slider', function() { var sliderConf = { @@ -122,13 +124,13 @@ options: { floor: 0, ceil: 100, - rightToLeft: true - } - }; - helper.createRangeSlider(sliderConf); - expect(helper.slider.flrLab.css('visibility')).to.equal('hidden'); - expect(helper.slider.ceilLab.css('visibility')).to.equal('hidden'); - }); + rightToLeft: true, + }, + } + helper.createRangeSlider(sliderConf) + expect(helper.slider.flrLab.css('visibility')).to.equal('hidden') + expect(helper.slider.ceilLab.css('visibility')).to.equal('hidden') + }) it('should hide floor and ceil labels when cmb label is overlapping, for range slider', function() { var sliderConf = { @@ -137,17 +139,17 @@ options: { floor: 0, ceil: 100, - translate: function(v, _, which){ - if(which != 'model' && which != 'high') return v; + translate: function(v, _, which) { + if (which != 'model' && which != 'high') return v return "I'm whatever long text ===============================================================================================================================================================" - } - } - }; + }, + }, + } - helper.createRangeSlider(sliderConf); - expect(helper.slider.flrLab.css('visibility')).to.equal('hidden'); - expect(helper.slider.ceilLab.css('visibility')).to.equal('hidden'); - }); + helper.createRangeSlider(sliderConf) + expect(helper.slider.flrLab.css('visibility')).to.equal('hidden') + expect(helper.slider.ceilLab.css('visibility')).to.equal('hidden') + }) it('should hide floor and ceil labels when cmb label is overlapping, for range RTL slider', function() { var sliderConf = { @@ -156,19 +158,16 @@ options: { floor: 0, ceil: 100, - translate: function(v, _, which){ - if(which != 'model' && which != 'high') return v; + translate: function(v, _, which) { + if (which != 'model' && which != 'high') return v return "I'm whatever long text ===============================================================================================================================================================" - } + }, }, - rightToLeft: true - }; - helper.createRangeSlider(sliderConf); - expect(helper.slider.flrLab.css('visibility')).to.equal('hidden'); - expect(helper.slider.ceilLab.css('visibility')).to.equal('hidden'); - }); - - - }); -}()); - + rightToLeft: true, + } + helper.createRangeSlider(sliderConf) + expect(helper.slider.flrLab.css('visibility')).to.equal('hidden') + expect(helper.slider.ceilLab.css('visibility')).to.equal('hidden') + }) + }) +})() diff --git a/tests/specs/mouse-controls/draggable-range-slider-horizontal-test.js b/tests/specs/mouse-controls/draggable-range-slider-horizontal-test.js index 6747417..ae7630d 100644 --- a/tests/specs/mouse-controls/draggable-range-slider-horizontal-test.js +++ b/tests/specs/mouse-controls/draggable-range-slider-horizontal-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Mouse controls - draggableRange Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -27,217 +29,224 @@ options: { floor: 0, ceil: 100, - draggableRange: true - } - }; - helper.createRangeSlider(sliderConf); - }); + draggableRange: true, + }, + } + helper.createRangeSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should handle click and drag on minH correctly when mouse is on the middle', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnChange'); - var event = helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 50; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(expectedValue); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + var event = helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 50 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click and drag on maxH correctly when mouse is on the middle', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnChange'); - var event = helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 50; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.max).to.equal(expectedValue); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + var event = helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 50 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.max).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click and drag on minH and switch min/max if needed', function() { - var event = helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 80; - helper.moveMouseToValue(expectedValue); + var event = helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 80 + helper.moveMouseToValue(expectedValue) - expect(helper.scope.slider.min).to.equal(60); - expect(helper.scope.slider.max).to.equal(80); - }); + expect(helper.scope.slider.min).to.equal(60) + expect(helper.scope.slider.max).to.equal(80) + }) it('should handle click and drag on maxH and switch min/max if needed', function() { - var event = helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 20; - helper.moveMouseToValue(expectedValue); + var event = helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 20 + helper.moveMouseToValue(expectedValue) - expect(helper.scope.slider.min).to.equal(20); - expect(helper.scope.slider.max).to.equal(40); - }); + expect(helper.scope.slider.min).to.equal(20) + expect(helper.scope.slider.max).to.equal(40) + }) it('should handle click on fullbar and move minH when click pos is nearer to minH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') var expectedValue = 10, - offset = helper.getMousePosition(expectedValue); + position = helper.getMousePosition(expectedValue) - var event = helper.fireMousedown(helper.slider.fullBar, offset); + var event = helper.fireMousedown(helper.slider.fullBar, position) - expect(helper.scope.slider.min).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.min).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on fullbar and move maxH when click pos is nearer to maxH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') var expectedValue = 90, - offset = helper.getMousePosition(expectedValue); + position = helper.getMousePosition(expectedValue) - var event = helper.fireMousedown(helper.slider.fullBar, offset); + var event = helper.fireMousedown(helper.slider.fullBar, position) - expect(helper.scope.slider.max).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('highValue'); - helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true; - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.max).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('highValue') + helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on selbar and move whole range when moved within slider range', function() { - sinon.spy(helper.slider, 'positionTrackingBar'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingBar') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') - helper.fireMousedown(helper.slider.selBar, 0); + helper.fireMousedown(helper.slider.selBar, 0) var moveValue = 10, - offset = helper.slider.valueToOffset(moveValue); - helper.fireMousemove(offset); - - expect(helper.scope.slider.min).to.equal(50); - expect(helper.scope.slider.max).to.equal(70); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - helper.slider.positionTrackingBar.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + position = helper.slider.valueToPosition(moveValue) + helper.fireMousemove(position) + + expect(helper.scope.slider.min).to.equal(50) + expect(helper.scope.slider.max).to.equal(70) + expect(helper.slider.tracking).to.equal('lowValue') + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + expect(helper.slider.positionTrackingBar.callCount).to.equal(2) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(2) + }) it('should handle click on selbar and move move range when near 0 and moved left', function() { - helper.scope.slider.min = 10; - helper.scope.$digest(); + helper.scope.slider.min = 10 + helper.scope.$digest() - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousemove(-1000); + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousemove(-1000) - expect(helper.scope.slider.min).to.equal(0); - expect(helper.scope.slider.max).to.equal(50); - expect(helper.slider.tracking).to.equal('lowValue'); - }); + expect(helper.scope.slider.min).to.equal(0) + expect(helper.scope.slider.max).to.equal(50) + expect(helper.slider.tracking).to.equal('lowValue') + }) - it('should handle click on selbar and don\'t move range when already at 0 and moved left', function() { - helper.scope.slider.min = 0; - helper.scope.$digest(); + it("should handle click on selbar and don't move range when already at 0 and moved left", function() { + helper.scope.slider.min = 0 + helper.scope.$digest() - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousemove(-100); + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousemove(-100) - expect(helper.scope.slider.min).to.equal(0); - expect(helper.scope.slider.max).to.equal(60); - expect(helper.slider.tracking).to.equal('lowValue'); - }); + expect(helper.scope.slider.min).to.equal(0) + expect(helper.scope.slider.max).to.equal(60) + expect(helper.slider.tracking).to.equal('lowValue') + }) it('should handle click on selbar and move move range when near max and moved right', function() { - helper.scope.slider.max = 90; - helper.scope.$digest(); + helper.scope.slider.max = 90 + helper.scope.$digest() - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousemove(helper.slider.maxPos); + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousemove(helper.slider.maxPos) - expect(helper.scope.slider.min).to.equal(50); - expect(helper.scope.slider.max).to.equal(100); - expect(helper.slider.tracking).to.equal('lowValue'); - }); + expect(helper.scope.slider.min).to.equal(50) + expect(helper.scope.slider.max).to.equal(100) + expect(helper.slider.tracking).to.equal('lowValue') + }) - it('should handle click on selbar and don\'t move range when already at max and moved right', function() { - helper.scope.slider.max = 100; - helper.scope.$digest(); + it("should handle click on selbar and don't move range when already at max and moved right", function() { + helper.scope.slider.max = 100 + helper.scope.$digest() - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousemove(helper.slider.maxPos); + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousemove(helper.slider.maxPos) - expect(helper.scope.slider.min).to.equal(40); - expect(helper.scope.slider.max).to.equal(100); - expect(helper.slider.tracking).to.equal('lowValue'); - }); + expect(helper.scope.slider.min).to.equal(40) + expect(helper.scope.slider.max).to.equal(100) + expect(helper.slider.tracking).to.equal('lowValue') + }) it('should a working positionTrackingBar', function() { var newMin = 50, newMax = 90, - minOffset = helper.slider.valueToOffset(newMin), - maxOffset = helper.slider.valueToOffset(newMax); - helper.slider.positionTrackingBar(newMin, newMax, minOffset, maxOffset); - - expect(helper.scope.slider.min).to.equal(50); - expect(helper.scope.slider.max).to.equal(90); - expect(helper.slider.minH.css('left')).to.equal(minOffset + 'px'); - expect(helper.slider.maxH.css('left')).to.equal(maxOffset + 'px'); - }); + minposition = Math.round(helper.slider.valueToPosition(newMin)), + maxposition = Math.round(helper.slider.valueToPosition(newMax)) + helper.slider.positionTrackingBar( + newMin, + newMax, + minposition, + maxposition + ) + + expect(helper.scope.slider.min).to.equal(50) + expect(helper.scope.slider.max).to.equal(90) + expect(helper.slider.minH.css('left')).to.equal(minposition + 'px') + expect(helper.slider.maxH.css('left')).to.equal(maxposition + 'px') + }) it('should respect minLimit option', function() { - helper.scope.slider.options.minLimit = 20; - helper.scope.$digest(); + helper.scope.slider.options.minLimit = 20 + helper.scope.$digest() - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousemove(-1000); + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousemove(-1000) - expect(helper.scope.slider.min).to.equal(20); - expect(helper.scope.slider.max).to.equal(40); - }); + expect(helper.scope.slider.min).to.equal(20) + expect(helper.scope.slider.max).to.equal(40) + }) it('should respect maxLimit option', function() { - helper.scope.slider.options.maxLimit = 80; - helper.scope.$digest(); + helper.scope.slider.options.maxLimit = 80 + helper.scope.$digest() - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousemove(helper.slider.maxPos); + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousemove(helper.slider.maxPos) - expect(helper.scope.slider.min).to.equal(60); - expect(helper.scope.slider.max).to.equal(80); - }); - }); + expect(helper.scope.slider.min).to.equal(60) + expect(helper.scope.slider.max).to.equal(80) + }) + }) describe('Right to left Mouse controls - draggableRange Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -247,179 +256,184 @@ floor: 0, ceil: 100, draggableRange: true, - rightToLeft: true - } - }; - helper.createRangeSlider(sliderConf); - }); + rightToLeft: true, + }, + } + helper.createRangeSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should handle click and drag on minH correctly when mouse is on the middle', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnChange'); - var event = helper.fireMousedown(helper.slider.minH, 0); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + var event = helper.fireMousedown(helper.slider.minH, 0) var expectedValue = 50, - offset = helper.getMousePosition(expectedValue); - helper.fireMousemove(offset); - expect(helper.scope.slider.min).to.equal(expectedValue); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + position = helper.getMousePosition(expectedValue) + helper.fireMousemove(position) + expect(helper.scope.slider.min).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click and drag on maxH correctly when mouse is on the middle', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnChange'); - var event = helper.fireMousedown(helper.slider.maxH, 0); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + var event = helper.fireMousedown(helper.slider.maxH, 0) var expectedValue = 50, - offset = helper.getMousePosition(expectedValue); - helper.fireMousemove(offset); - expect(helper.scope.slider.max).to.equal(expectedValue); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + position = helper.getMousePosition(expectedValue) + helper.fireMousemove(position) + expect(helper.scope.slider.max).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click and drag on minH and switch min/max if needed', function() { - var event = helper.fireMousedown(helper.slider.minH, 0); + var event = helper.fireMousedown(helper.slider.minH, 0) var expectedValue = 80, - offset = helper.getMousePosition(expectedValue); - helper.fireMousemove(offset); + position = helper.getMousePosition(expectedValue) + helper.fireMousemove(position) - expect(helper.scope.slider.min).to.equal(60); - expect(helper.scope.slider.max).to.equal(80); - }); + expect(helper.scope.slider.min).to.equal(60) + expect(helper.scope.slider.max).to.equal(80) + }) it('should handle click and drag on maxH and switch min/max if needed', function() { - var event = helper.fireMousedown(helper.slider.maxH, 0); + var event = helper.fireMousedown(helper.slider.maxH, 0) var expectedValue = 20, - offset = helper.getMousePosition(expectedValue); - helper.fireMousemove(offset); + position = helper.getMousePosition(expectedValue) + helper.fireMousemove(position) - expect(helper.scope.slider.min).to.equal(20); - expect(helper.scope.slider.max).to.equal(40); - }); + expect(helper.scope.slider.min).to.equal(20) + expect(helper.scope.slider.max).to.equal(40) + }) it('should handle click on fullbar and move minH when click pos is nearer to minH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') var expectedValue = 10, - offset = helper.getMousePosition(expectedValue); + position = helper.getMousePosition(expectedValue) - var event = helper.fireMousedown(helper.slider.fullBar, offset); + var event = helper.fireMousedown(helper.slider.fullBar, position) - expect(helper.scope.slider.min).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.min).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on fullbar and move maxH when click pos is nearer to maxH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') var expectedValue = 90, - offset = helper.getMousePosition(expectedValue); + position = helper.getMousePosition(expectedValue) - var event = helper.fireMousedown(helper.slider.fullBar, offset); + var event = helper.fireMousedown(helper.slider.fullBar, position) - expect(helper.scope.slider.max).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('highValue'); - helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true; - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.max).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('highValue') + helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on selbar and move whole range when moved within slider range', function() { - sinon.spy(helper.slider, 'positionTrackingBar'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingBar') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') - helper.fireMousedown(helper.slider.selBar, 0); + helper.fireMousedown(helper.slider.selBar, 0) var moveValue = 10, - offset = helper.slider.maxPos - helper.slider.valueToOffset(moveValue); - helper.fireMousemove(offset); - - expect(helper.scope.slider.min).to.equal(30); - expect(helper.scope.slider.max).to.equal(50); - expect(helper.slider.tracking).to.equal('highValue'); - helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true; - helper.slider.positionTrackingBar.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + position = + helper.slider.maxPos - helper.slider.valueToPosition(moveValue) + helper.fireMousemove(position) + + expect(helper.scope.slider.min).to.equal(30) + expect(helper.scope.slider.max).to.equal(50) + expect(helper.slider.tracking).to.equal('highValue') + helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true + expect(helper.slider.positionTrackingBar.callCount).to.equal(2) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(2) + }) it('should handle click on selbar and move move range when near 0 and moved right', function() { - helper.scope.slider.min = 10; - helper.scope.$digest(); + helper.scope.slider.min = 10 + helper.scope.$digest() - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousemove(1000); + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousemove(1000) - expect(helper.scope.slider.min).to.equal(0); - expect(helper.scope.slider.max).to.equal(50); - expect(helper.slider.tracking).to.equal('highValue'); - }); + expect(helper.scope.slider.min).to.equal(0) + expect(helper.scope.slider.max).to.equal(50) + expect(helper.slider.tracking).to.equal('highValue') + }) - it('should handle click on selbar and don\'t move range when already at 0 and moved right', function() { - helper.scope.slider.min = 0; - helper.scope.$digest(); + it("should handle click on selbar and don't move range when already at 0 and moved right", function() { + helper.scope.slider.min = 0 + helper.scope.$digest() - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousemove(100); + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousemove(100) - expect(helper.scope.slider.min).to.equal(0); - expect(helper.scope.slider.max).to.equal(60); - expect(helper.slider.tracking).to.equal('highValue'); - }); + expect(helper.scope.slider.min).to.equal(0) + expect(helper.scope.slider.max).to.equal(60) + expect(helper.slider.tracking).to.equal('highValue') + }) it('should handle click on selbar and move range when near max and moved left', function() { - helper.scope.slider.max = 90; - helper.scope.$digest(); + helper.scope.slider.max = 90 + helper.scope.$digest() - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousemove(-1000); + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousemove(-1000) - expect(helper.scope.slider.min).to.equal(50); - expect(helper.scope.slider.max).to.equal(100); - expect(helper.slider.tracking).to.equal('highValue'); - }); + expect(helper.scope.slider.min).to.equal(50) + expect(helper.scope.slider.max).to.equal(100) + expect(helper.slider.tracking).to.equal('highValue') + }) - it('should handle click on selbar and don\'t move range when already at max and moved left', function() { - helper.scope.slider.max = 100; - helper.scope.$digest(); + it("should handle click on selbar and don't move range when already at max and moved left", function() { + helper.scope.slider.max = 100 + helper.scope.$digest() - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousemove(-1000); + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousemove(-1000) - expect(helper.scope.slider.min).to.equal(40); - expect(helper.scope.slider.max).to.equal(100); - expect(helper.slider.tracking).to.equal('highValue'); - }); + expect(helper.scope.slider.min).to.equal(40) + expect(helper.scope.slider.max).to.equal(100) + expect(helper.slider.tracking).to.equal('highValue') + }) it('should a working positionTrackingBar', function() { var newMin = 50, - newMax = 90, - minOffset = helper.slider.valueToOffset(newMin), - maxOffset = helper.slider.valueToOffset(newMax); - helper.slider.positionTrackingBar(newMin, newMax, minOffset, maxOffset); - - expect(helper.scope.slider.min).to.equal(50); - expect(helper.scope.slider.max).to.equal(90); - expect(helper.slider.minH.css('left')).to.equal(minOffset + 'px'); - expect(helper.slider.maxH.css('left')).to.equal(maxOffset + 'px'); - }); - }); -}()); - + newMax = 90, + minposition = Math.round(helper.slider.valueToPosition(newMin)), + maxposition = Math.round(helper.slider.valueToPosition(newMax)) + helper.slider.positionTrackingBar( + newMin, + newMax, + minposition, + maxposition + ) + + expect(helper.scope.slider.min).to.equal(50) + expect(helper.scope.slider.max).to.equal(90) + expect(helper.slider.minH.css('left')).to.equal(minposition + 'px') + expect(helper.slider.maxH.css('left')).to.equal(maxposition + 'px') + }) + }) +})() diff --git a/tests/specs/mouse-controls/draggableOnly-range-slider-horizontal-test.js b/tests/specs/mouse-controls/draggableOnly-range-slider-horizontal-test.js index 846827a..70d78b3 100644 --- a/tests/specs/mouse-controls/draggableOnly-range-slider-horizontal-test.js +++ b/tests/specs/mouse-controls/draggableOnly-range-slider-horizontal-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Mouse controls - draggableRangeOnly Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -27,161 +29,163 @@ options: { floor: 0, ceil: 100, - draggableRangeOnly: true - } - }; - helper.createRangeSlider(sliderConf); - }); + draggableRangeOnly: true, + }, + } + helper.createRangeSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should handle click and drag on minH correctly', function() { - sinon.spy(helper.slider, 'positionTrackingBar'); - sinon.spy(helper.slider, 'callOnChange'); + sinon.spy(helper.slider, 'positionTrackingBar') + sinon.spy(helper.slider, 'callOnChange') - var event = helper.fireMousedown(helper.slider.minH, 0); + var event = helper.fireMousedown(helper.slider.minH, 0) var moveValue = 10, - offset = helper.slider.valueToOffset(moveValue); - helper.fireMousemove(offset); + position = helper.slider.valueToPosition(moveValue) + helper.fireMousemove(position) - expect(helper.scope.slider.min).to.equal(50); - expect(helper.scope.slider.max).to.equal(70); - helper.slider.positionTrackingBar.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.min).to.equal(50) + expect(helper.scope.slider.max).to.equal(70) + expect(helper.slider.positionTrackingBar.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click and drag on maxH correctly', function() { - sinon.spy(helper.slider, 'positionTrackingBar'); - sinon.spy(helper.slider, 'callOnChange'); - var event = helper.fireMousedown(helper.slider.maxH, 0); + sinon.spy(helper.slider, 'positionTrackingBar') + sinon.spy(helper.slider, 'callOnChange') + var event = helper.fireMousedown(helper.slider.maxH, 0) var moveValue = 10, - offset = helper.slider.valueToOffset(moveValue); - helper.fireMousemove(offset); - expect(helper.scope.slider.min).to.equal(50); - expect(helper.scope.slider.max).to.equal(70); - helper.slider.positionTrackingBar.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + position = helper.slider.valueToPosition(moveValue) + helper.fireMousemove(position) + expect(helper.scope.slider.min).to.equal(50) + expect(helper.scope.slider.max).to.equal(70) + expect(helper.slider.positionTrackingBar.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should not handle click on fullbar', function() { - sinon.spy(helper.slider, 'callOnStart'); + sinon.spy(helper.slider, 'callOnStart') var moveValue = 10, - offset = helper.slider.valueToOffset(moveValue); + position = helper.slider.valueToPosition(moveValue) - var event = helper.fireMousedown(helper.slider.fullBar, offset); + var event = helper.fireMousedown(helper.slider.fullBar, position) - expect(helper.scope.slider.min).to.equal(40); - expect(helper.scope.slider.max).to.equal(60); - expect(helper.slider.tracking).to.equal(''); - helper.slider.callOnStart.called.should.be.false; - }); + expect(helper.scope.slider.min).to.equal(40) + expect(helper.scope.slider.max).to.equal(60) + expect(helper.slider.tracking).to.equal('') + helper.slider.callOnStart.called.should.be.false + }) it('should handle click on selbar and move whole range when moved within slider range', function() { - sinon.spy(helper.slider, 'positionTrackingBar'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingBar') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') - helper.fireMousedown(helper.slider.selBar, 0); + helper.fireMousedown(helper.slider.selBar, 0) var moveValue = 10, - offset = helper.slider.valueToOffset(moveValue); - helper.fireMousemove(offset); - - expect(helper.scope.slider.min).to.equal(50); - expect(helper.scope.slider.max).to.equal(70); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - helper.slider.positionTrackingBar.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + position = helper.slider.valueToPosition(moveValue) + helper.fireMousemove(position) + + expect(helper.scope.slider.min).to.equal(50) + expect(helper.scope.slider.max).to.equal(70) + expect(helper.slider.tracking).to.equal('lowValue') + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + expect(helper.slider.positionTrackingBar.callCount).to.equal(2) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(2) + }) it('should handle click on selbar and move range when near 0 and moved left', function() { - helper.scope.slider.min = 10; - helper.scope.$digest(); + helper.scope.slider.min = 10 + helper.scope.$digest() - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousemove(-1000); + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousemove(-1000) - expect(helper.scope.slider.min).to.equal(0); - expect(helper.scope.slider.max).to.equal(50); - expect(helper.slider.tracking).to.equal('lowValue'); - }); + expect(helper.scope.slider.min).to.equal(0) + expect(helper.scope.slider.max).to.equal(50) + expect(helper.slider.tracking).to.equal('lowValue') + }) - it('should handle click on selbar and don\'t move range when already at 0 and moved left', function() { - helper.scope.slider.min = 0; - helper.scope.$digest(); + it("should handle click on selbar and don't move range when already at 0 and moved left", function() { + helper.scope.slider.min = 0 + helper.scope.$digest() - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousemove(-100); + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousemove(-100) - expect(helper.scope.slider.min).to.equal(0); - expect(helper.scope.slider.max).to.equal(60); - expect(helper.slider.tracking).to.equal('lowValue'); - }); + expect(helper.scope.slider.min).to.equal(0) + expect(helper.scope.slider.max).to.equal(60) + expect(helper.slider.tracking).to.equal('lowValue') + }) it('should handle click on selbar and move range when near max and moved right', function() { - helper.scope.slider.max = 90; - helper.scope.$digest(); + helper.scope.slider.max = 90 + helper.scope.$digest() - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousemove(helper.slider.maxPos); + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousemove(helper.slider.maxPos) - expect(helper.scope.slider.min).to.equal(50); - expect(helper.scope.slider.max).to.equal(100); - expect(helper.slider.tracking).to.equal('lowValue'); - }); + expect(helper.scope.slider.min).to.equal(50) + expect(helper.scope.slider.max).to.equal(100) + expect(helper.slider.tracking).to.equal('lowValue') + }) - it('should handle click on selbar and don\'t move range when already at max and moved right', function() { - helper.scope.slider.max = 100; - helper.scope.$digest(); + it("should handle click on selbar and don't move range when already at max and moved right", function() { + helper.scope.slider.max = 100 + helper.scope.$digest() - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousemove(helper.slider.maxPos); + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousemove(helper.slider.maxPos) - expect(helper.scope.slider.min).to.equal(40); - expect(helper.scope.slider.max).to.equal(100); - expect(helper.slider.tracking).to.equal('lowValue'); - }); + expect(helper.scope.slider.min).to.equal(40) + expect(helper.scope.slider.max).to.equal(100) + expect(helper.slider.tracking).to.equal('lowValue') + }) it('should handle click on selbar and move range when floor is not 0 and handle is dragged below limit', function() { - helper.scope.slider.min = 1050; - helper.scope.slider.max = 1550; - helper.scope.slider.options.floor = 1000; - helper.scope.slider.options.ceil = 5000; - helper.scope.$digest(); + helper.scope.slider.min = 1050 + helper.scope.slider.max = 1550 + helper.scope.slider.options.floor = 1000 + helper.scope.slider.options.ceil = 5000 + helper.scope.$digest() - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousemove(-1000); + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousemove(-1000) - expect(helper.scope.slider.min).to.equal(1000); - expect(helper.scope.slider.max).to.equal(1500); - expect(helper.slider.tracking).to.equal('lowValue'); - }); - }); + expect(helper.scope.slider.min).to.equal(1000) + expect(helper.scope.slider.max).to.equal(1500) + expect(helper.slider.tracking).to.equal('lowValue') + }) + }) describe('Right to left Mouse controls - draggableRangeOnly Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -191,141 +195,140 @@ floor: 0, ceil: 100, draggableRangeOnly: true, - leftToRight: true - } - }; - helper.createRangeSlider(sliderConf); - }); + leftToRight: true, + }, + } + helper.createRangeSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should handle click and drag on minH correctly', function() { - sinon.spy(helper.slider, 'positionTrackingBar'); - sinon.spy(helper.slider, 'callOnChange'); + sinon.spy(helper.slider, 'positionTrackingBar') + sinon.spy(helper.slider, 'callOnChange') - var event = helper.fireMousedown(helper.slider.minH, 0); + var event = helper.fireMousedown(helper.slider.minH, 0) var moveValue = 10, - offset = helper.slider.valueToOffset(moveValue); - helper.fireMousemove(offset); + position = helper.slider.valueToPosition(moveValue) + helper.fireMousemove(position) - expect(helper.scope.slider.min).to.equal(50); - expect(helper.scope.slider.max).to.equal(70); - helper.slider.positionTrackingBar.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.min).to.equal(50) + expect(helper.scope.slider.max).to.equal(70) + expect(helper.slider.positionTrackingBar.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click and drag on maxH correctly', function() { - sinon.spy(helper.slider, 'positionTrackingBar'); - sinon.spy(helper.slider, 'callOnChange'); - var event = helper.fireMousedown(helper.slider.maxH, 0); + sinon.spy(helper.slider, 'positionTrackingBar') + sinon.spy(helper.slider, 'callOnChange') + var event = helper.fireMousedown(helper.slider.maxH, 0) var moveValue = 10, - offset = helper.slider.valueToOffset(moveValue); - helper.fireMousemove(offset); - expect(helper.scope.slider.min).to.equal(50); - expect(helper.scope.slider.max).to.equal(70); - helper.slider.positionTrackingBar.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + position = helper.slider.valueToPosition(moveValue) + helper.fireMousemove(position) + expect(helper.scope.slider.min).to.equal(50) + expect(helper.scope.slider.max).to.equal(70) + expect(helper.slider.positionTrackingBar.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should not handle click on fullbar', function() { - sinon.spy(helper.slider, 'callOnStart'); + sinon.spy(helper.slider, 'callOnStart') var moveValue = 10, - offset = helper.slider.valueToOffset(moveValue); + position = helper.slider.valueToPosition(moveValue) - var event = helper.fireMousedown(helper.slider.fullBar, offset); + var event = helper.fireMousedown(helper.slider.fullBar, position) - expect(helper.scope.slider.min).to.equal(40); - expect(helper.scope.slider.max).to.equal(60); - expect(helper.slider.tracking).to.equal(''); - helper.slider.callOnStart.called.should.be.false; - }); + expect(helper.scope.slider.min).to.equal(40) + expect(helper.scope.slider.max).to.equal(60) + expect(helper.slider.tracking).to.equal('') + helper.slider.callOnStart.called.should.be.false + }) it('should handle click on selbar and move whole range when moved within slider range', function() { - sinon.spy(helper.slider, 'positionTrackingBar'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingBar') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') - helper.fireMousedown(helper.slider.selBar, 0); + helper.fireMousedown(helper.slider.selBar, 0) var moveValue = 10, - offset = helper.slider.valueToOffset(moveValue); - helper.fireMousemove(offset); - - expect(helper.scope.slider.min).to.equal(50); - expect(helper.scope.slider.max).to.equal(70); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - helper.slider.positionTrackingBar.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + position = helper.slider.valueToPosition(moveValue) + helper.fireMousemove(position) + + expect(helper.scope.slider.min).to.equal(50) + expect(helper.scope.slider.max).to.equal(70) + expect(helper.slider.tracking).to.equal('lowValue') + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + expect(helper.slider.positionTrackingBar.callCount).to.equal(2) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(2) + }) it('should handle click on selbar and move range when near 0 and moved left', function() { - helper.scope.slider.min = 10; - helper.scope.$digest(); + helper.scope.slider.min = 10 + helper.scope.$digest() - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousemove(-1000); + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousemove(-1000) - expect(helper.scope.slider.min).to.equal(0); - expect(helper.scope.slider.max).to.equal(50); - expect(helper.slider.tracking).to.equal('lowValue'); - }); + expect(helper.scope.slider.min).to.equal(0) + expect(helper.scope.slider.max).to.equal(50) + expect(helper.slider.tracking).to.equal('lowValue') + }) - it('should handle click on selbar and don\'t move range when already at 0 and moved left', function() { - helper.scope.slider.min = 0; - helper.scope.$digest(); + it("should handle click on selbar and don't move range when already at 0 and moved left", function() { + helper.scope.slider.min = 0 + helper.scope.$digest() - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousemove(-100); + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousemove(-100) - expect(helper.scope.slider.min).to.equal(0); - expect(helper.scope.slider.max).to.equal(60); - expect(helper.slider.tracking).to.equal('lowValue'); - }); + expect(helper.scope.slider.min).to.equal(0) + expect(helper.scope.slider.max).to.equal(60) + expect(helper.slider.tracking).to.equal('lowValue') + }) it('should handle click on selbar and move range when near max and moved right', function() { - helper.scope.slider.max = 90; - helper.scope.$digest(); + helper.scope.slider.max = 90 + helper.scope.$digest() - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousemove(helper.slider.maxPos); + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousemove(helper.slider.maxPos) - expect(helper.scope.slider.min).to.equal(50); - expect(helper.scope.slider.max).to.equal(100); - expect(helper.slider.tracking).to.equal('lowValue'); - }); + expect(helper.scope.slider.min).to.equal(50) + expect(helper.scope.slider.max).to.equal(100) + expect(helper.slider.tracking).to.equal('lowValue') + }) - it('should handle click on selbar and don\'t move range when already at max and moved right', function() { - helper.scope.slider.max = 100; - helper.scope.$digest(); + it("should handle click on selbar and don't move range when already at max and moved right", function() { + helper.scope.slider.max = 100 + helper.scope.$digest() - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousemove(helper.slider.maxPos); + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousemove(helper.slider.maxPos) - expect(helper.scope.slider.min).to.equal(40); - expect(helper.scope.slider.max).to.equal(100); - expect(helper.slider.tracking).to.equal('lowValue'); - }); + expect(helper.scope.slider.min).to.equal(40) + expect(helper.scope.slider.max).to.equal(100) + expect(helper.slider.tracking).to.equal('lowValue') + }) it('should handle click on selbar and move range when floor is not 0 and handle is dragged below limit', function() { - helper.scope.slider.min = 1050; - helper.scope.slider.max = 1550; - helper.scope.slider.options.floor = 1000; - helper.scope.slider.options.ceil = 5000; - helper.scope.$digest(); - - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousemove(-1000); - - expect(helper.scope.slider.min).to.equal(1000); - expect(helper.scope.slider.max).to.equal(1500); - expect(helper.slider.tracking).to.equal('lowValue'); - }); - }); -}()); - + helper.scope.slider.min = 1050 + helper.scope.slider.max = 1550 + helper.scope.slider.options.floor = 1000 + helper.scope.slider.options.ceil = 5000 + helper.scope.$digest() + + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousemove(-1000) + + expect(helper.scope.slider.min).to.equal(1000) + expect(helper.scope.slider.max).to.equal(1500) + expect(helper.slider.tracking).to.equal('lowValue') + }) + }) +})() diff --git a/tests/specs/mouse-controls/minMaxLimit-range-slider-horizontal-test.js b/tests/specs/mouse-controls/minMaxLimit-range-slider-horizontal-test.js index 091ca65..6376be2 100644 --- a/tests/specs/mouse-controls/minMaxLimit-range-slider-horizontal-test.js +++ b/tests/specs/mouse-controls/minMaxLimit-range-slider-horizontal-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Mouse controls - minLimit!=null && maxLimit!=null Range Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -28,63 +30,65 @@ floor: 0, ceil: 100, minLimit: 40, - maxLimit: 60 - } - }; - helper.createRangeSlider(sliderConf); - }); + maxLimit: 60, + }, + } + helper.createRangeSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should be able to modify minH above minLimit', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 42; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(42); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 42 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(42) + }) it('should not be able to modify minH below minLimit', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 30; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(40); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 30 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(40) + }) it('should be able to modify maxH below maxLimit', function() { - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 58; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.max).to.equal(58); - }); + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 58 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.max).to.equal(58) + }) it('should not be able to modify maxH above maxLimit', function() { - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 70; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.max).to.equal(60); - }); - }); + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 70 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.max).to.equal(60) + }) + }) describe('Right to left Mouse controls - minLimit!=null && maxLimit!=null Range Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -95,43 +99,42 @@ ceil: 100, minLimit: 40, maxLimit: 60, - rightToLeft: true - } - }; - helper.createRangeSlider(sliderConf); - }); + rightToLeft: true, + }, + } + helper.createRangeSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should be able to modify minH above minLimit', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 42; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(42); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 42 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(42) + }) it('should not be able to modify minH below minLimit', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 30; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(40); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 30 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(40) + }) it('should be able to modify maxH below maxLimit', function() { - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 58; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.max).to.equal(58); - }); + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 58 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.max).to.equal(58) + }) it('should not be able to modify maxH above maxLimit', function() { - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 70; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.max).to.equal(60); - }); - }); -}()); - + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 70 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.max).to.equal(60) + }) + }) +})() diff --git a/tests/specs/mouse-controls/minMaxLimit-single-slider-horizontal-test.js b/tests/specs/mouse-controls/minMaxLimit-single-slider-horizontal-test.js index 5e99aa2..f5654a6 100644 --- a/tests/specs/mouse-controls/minMaxLimit-single-slider-horizontal-test.js +++ b/tests/specs/mouse-controls/minMaxLimit-single-slider-horizontal-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Mouse controls - minLimit!=null && maxLimit!=null Single Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -27,63 +29,65 @@ floor: 0, ceil: 100, minLimit: 40, - maxLimit: 60 - } - }; - helper.createSlider(sliderConf); - }); + maxLimit: 60, + }, + } + helper.createSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should be able to modify minH above minLimit', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 42; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.value).to.equal(42); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 42 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.value).to.equal(42) + }) it('should not be able to modify minH below minLimit', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 30; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.value).to.equal(40); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 30 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.value).to.equal(40) + }) it('should be able to modify minH below maxLimit', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 58; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.value).to.equal(58); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 58 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.value).to.equal(58) + }) it('should not be able to modify minH above maxLimit', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 70; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.value).to.equal(60); - }); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 70 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.value).to.equal(60) + }) + }) describe('Right to left Mouse controls - minLimit!=null && maxLimit!=null Single Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -93,43 +97,42 @@ ceil: 100, minLimit: 40, maxLimit: 60, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should be able to modify minH above minLimit', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 42; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.value).to.equal(42); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 42 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.value).to.equal(42) + }) it('should not be able to modify minH below minLimit', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 30; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.value).to.equal(40); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 30 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.value).to.equal(40) + }) it('should be able to modify minH below maxLimit', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 58; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.value).to.equal(58); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 58 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.value).to.equal(58) + }) it('should not be able to modify minH above maxLimit', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 70; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.value).to.equal(60); - }); - }); -}()); - + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 70 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.value).to.equal(60) + }) + }) +})() diff --git a/tests/specs/mouse-controls/minMaxRange-noSwitching-range-slider-horizontal-test.js b/tests/specs/mouse-controls/minMaxRange-noSwitching-range-slider-horizontal-test.js index db7cd5f..5f8184b 100644 --- a/tests/specs/mouse-controls/minMaxRange-noSwitching-range-slider-horizontal-test.js +++ b/tests/specs/mouse-controls/minMaxRange-noSwitching-range-slider-horizontal-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Mouse controls - minRange and noSwitching Range Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -29,117 +31,119 @@ ceil: 100, minRange: 10, maxRange: 50, - noSwitching: true - } - }; - helper.createRangeSlider(sliderConf); - }); + noSwitching: true, + }, + } + helper.createRangeSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should not modify any value if new range would be smaller than minRange when moving minH', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 50; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(45); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 50 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(45) + }) it('should not modify any value if new range would be smaller than minRange when moving maxH', function() { - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 50; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.max).to.equal(55); - }); + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 50 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.max).to.equal(55) + }) it('should modify the min value if new range is larger than minRange when moving minH', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 30; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(expectedValue); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 30 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(expectedValue) + }) it('should modify the max value if new range is larger than than minRange when moving maxH', function() { - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 70; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.max).to.equal(expectedValue); - }); + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 70 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.max).to.equal(expectedValue) + }) it('should not switch min/max when moving minH even if the range is large enough', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 80; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(45); - expect(helper.scope.slider.max).to.equal(55); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 80 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(45) + expect(helper.scope.slider.max).to.equal(55) + }) it('should not switch min/max when moving maxH even if the range is large enough', function() { - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 20; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(45); - expect(helper.scope.slider.max).to.equal(55); - }); + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 20 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(45) + expect(helper.scope.slider.max).to.equal(55) + }) it('should not modify any value if new range would be larger than maxRange when moving minH', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 0; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(5); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 0 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(5) + }) it('should not modify any value if new range would be larger than maxRange when moving maxH', function() { - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 100; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.max).to.equal(95); - }); + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 100 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.max).to.equal(95) + }) it('should not switch min/max when moving minH far higher than maxH (issue #377)', function() { - helper.scope.slider.min = 0; - helper.scope.slider.max = 10; - helper.scope.$digest(); + helper.scope.slider.min = 0 + helper.scope.slider.max = 10 + helper.scope.$digest() - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 100; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(0); - expect(helper.scope.slider.max).to.equal(10); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 100 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(0) + expect(helper.scope.slider.max).to.equal(10) + }) it('should not switch min/max when moving maxH far lower than minH (issue #377)', function() { - helper.scope.slider.min = 90; - helper.scope.slider.max = 100; - helper.scope.$digest(); - - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 0; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(90); - expect(helper.scope.slider.max).to.equal(100); - }); - }); + helper.scope.slider.min = 90 + helper.scope.slider.max = 100 + helper.scope.$digest() + + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 0 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(90) + expect(helper.scope.slider.max).to.equal(100) + }) + }) describe('Right to left Mouse controls - minRange and noSwitching Range Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -150,63 +154,61 @@ ceil: 100, minRange: 10, noSwitching: true, - rightToLeft: true - } - }; - helper.createRangeSlider(sliderConf); - }); + rightToLeft: true, + }, + } + helper.createRangeSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should not modify any value if new range would be smaller than minRange when moving minH', function() { - helper.fireMousedown(helper.slider.minH, 0); + helper.fireMousedown(helper.slider.minH, 0) var expectedValue = 50, - offset = helper.getMousePosition(expectedValue); - helper.fireMousemove(-offset); - expect(helper.scope.slider.min).to.equal(45); - }); + position = helper.getMousePosition(expectedValue) + helper.fireMousemove(-position) + expect(helper.scope.slider.min).to.equal(45) + }) it('should not modify any value if new range would be smaller than minRange when moving maxH', function() { - helper.fireMousedown(helper.slider.maxH, 0); + helper.fireMousedown(helper.slider.maxH, 0) var expectedValue = 50, - offset = helper.slider.maxPos - helper.getMousePosition(expectedValue); - helper.fireMousemove(offset); - expect(helper.scope.slider.max).to.equal(55); - }); + position = helper.slider.maxPos - helper.getMousePosition(expectedValue) + helper.fireMousemove(position) + expect(helper.scope.slider.max).to.equal(55) + }) it('should modify the min value if new range is larger than minRange when moving minH', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 30; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(expectedValue); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 30 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(expectedValue) + }) it('should modify the max value if new range is larger than than minRange when moving maxH', function() { - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 70; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.max).to.equal(expectedValue); - }); + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 70 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.max).to.equal(expectedValue) + }) it('should not switch min/max when moving minH even if the range is large enough', function() { - helper.fireMousedown(helper.slider.minH, 0); + helper.fireMousedown(helper.slider.minH, 0) var expectedValue = 80, - offset = helper.getMousePosition(expectedValue); - helper.fireMousemove(-offset); - expect(helper.scope.slider.min).to.equal(45); - expect(helper.scope.slider.max).to.equal(55); - }); + position = helper.getMousePosition(expectedValue) + helper.fireMousemove(-position) + expect(helper.scope.slider.min).to.equal(45) + expect(helper.scope.slider.max).to.equal(55) + }) it('should not switch min/max when moving maxH even if the range is large enough', function() { - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 20; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(45); - expect(helper.scope.slider.max).to.equal(55); - }); - }); - -}()); - + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 20 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(45) + expect(helper.scope.slider.max).to.equal(55) + }) + }) +})() diff --git a/tests/specs/mouse-controls/minMaxRange-range-slider-horizontal-test.js b/tests/specs/mouse-controls/minMaxRange-range-slider-horizontal-test.js index b318ffe..88789ed 100644 --- a/tests/specs/mouse-controls/minMaxRange-range-slider-horizontal-test.js +++ b/tests/specs/mouse-controls/minMaxRange-range-slider-horizontal-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Mouse controls - minRange!=0 Range Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -27,79 +29,81 @@ options: { floor: 0, ceil: 100, - minRange: 10 - } - }; - helper.createRangeSlider(sliderConf); - }); + minRange: 10, + }, + } + helper.createRangeSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should not modify any value if new range would be smaller than minRange when moving minH', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 50; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(45); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 50 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(45) + }) it('should not modify any value if new range would be smaller than minRange when moving maxH', function() { - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 50; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.max).to.equal(55); - }); + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 50 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.max).to.equal(55) + }) it('should modify the min value if new range is larger than minRange when moving minH', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 30; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(expectedValue); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 30 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(expectedValue) + }) it('should modify the max value if new range is larger than than minRange when moving maxH', function() { - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 70; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.max).to.equal(expectedValue); - }); + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 70 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.max).to.equal(expectedValue) + }) it('should modify the min value if switch min/max with a value large enough', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 80; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(55); - expect(helper.scope.slider.max).to.equal(expectedValue); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 80 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(55) + expect(helper.scope.slider.max).to.equal(expectedValue) + }) it('should modify the max value if switch min/max with a value large enough', function() { - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 20; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(expectedValue); - expect(helper.scope.slider.max).to.equal(45); - }); - }); + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 20 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(expectedValue) + expect(helper.scope.slider.max).to.equal(45) + }) + }) describe('Mouse controls - maxRange!=0 Range Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -108,63 +112,65 @@ options: { floor: 0, ceil: 100, - maxRange: 10 - } - }; - helper.createRangeSlider(sliderConf); - }); + maxRange: 10, + }, + } + helper.createRangeSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should not modify any value if new range would be larger than maxRange when moving minH', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 30; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(45); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 30 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(45) + }) it('should not modify any value if new range would be larger than maxRange when moving maxH', function() { - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 70; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.max).to.equal(55); - }); + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 70 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.max).to.equal(55) + }) it('should modify the min value if new range is smaller than maxRange when moving minH', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 50; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(expectedValue); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 50 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(expectedValue) + }) it('should modify the max value if new range is smaller than than maxRange when moving maxH', function() { - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 50; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.max).to.equal(expectedValue); - }); - }); + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 50 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.max).to.equal(expectedValue) + }) + }) describe('Right to left Mouse controls - minRange!=0 Range Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -174,60 +180,58 @@ floor: 0, ceil: 100, minRange: 10, - rightToLeft: true - } - - }; - helper.createRangeSlider(sliderConf); - }); + rightToLeft: true, + }, + } + helper.createRangeSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should not modify any value if new range would be smaller than minRange when moving minH', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 50; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(45); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 50 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(45) + }) it('should not modify any value if new range would be smaller than minRange when moving maxH', function() { - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 50; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.max).to.equal(55); - }); + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 50 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.max).to.equal(55) + }) it('should modify the min value if new range is larger than minRange when moving minH', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 30; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(expectedValue); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 30 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(expectedValue) + }) it('should modify the max value if new range is larger than than minRange when moving maxH', function() { - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 70; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.max).to.equal(expectedValue); - }); + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 70 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.max).to.equal(expectedValue) + }) it('should modify the min value if switch min/max with a value large enough', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 80; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(55); - expect(helper.scope.slider.max).to.equal(expectedValue); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 80 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(55) + expect(helper.scope.slider.max).to.equal(expectedValue) + }) it('should modify the max value if switch min/max with a value large enough', function() { - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 20; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(expectedValue); - expect(helper.scope.slider.max).to.equal(45); - }); - }); -}()); - + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 20 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(expectedValue) + expect(helper.scope.slider.max).to.equal(45) + }) + }) +})() diff --git a/tests/specs/mouse-controls/noSwitching-range-slider-horizontal-test.js b/tests/specs/mouse-controls/noSwitching-range-slider-horizontal-test.js index 76c7f58..528f260 100644 --- a/tests/specs/mouse-controls/noSwitching-range-slider-horizontal-test.js +++ b/tests/specs/mouse-controls/noSwitching-range-slider-horizontal-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Mouse controls - noSwitching Range Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -27,75 +29,77 @@ options: { floor: 0, ceil: 100, - noSwitching: true - } - }; - helper.createRangeSlider(sliderConf); - }); + noSwitching: true, + }, + } + helper.createRangeSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should not switch min and max handles if minH is dragged after maxH', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 60; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(55); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 60 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(55) + }) it('should not switch min and max handles if maxH is dragged before minH', function() { - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 20; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.max).to.equal(45); - }); + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 20 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.max).to.equal(45) + }) it('should move minH if minH==maxH and click is on the left side of the bar', function() { - helper.scope.slider.min = helper.scope.slider.max = 50; - helper.scope.$digest(); + helper.scope.slider.min = helper.scope.slider.max = 50 + helper.scope.$digest() var expectedValue = 30, - offset = helper.getMousePosition(expectedValue); + position = helper.getMousePosition(expectedValue) - helper.fireMousedown(helper.slider.fullBar, offset); + helper.fireMousedown(helper.slider.fullBar, position) - expect(helper.scope.slider.min).to.equal(30); - expect(helper.scope.slider.max).to.equal(50); - }); + expect(helper.scope.slider.min).to.equal(30) + expect(helper.scope.slider.max).to.equal(50) + }) it('should move maxH if minH==maxH and click is on the right side of the bar', function() { - helper.scope.slider.min = helper.scope.slider.max = 50; - helper.scope.$digest(); + helper.scope.slider.min = helper.scope.slider.max = 50 + helper.scope.$digest() var expectedValue = 70, - offset = helper.getMousePosition(expectedValue); + position = helper.getMousePosition(expectedValue) - helper.fireMousedown(helper.slider.fullBar, offset); + helper.fireMousedown(helper.slider.fullBar, position) - expect(helper.scope.slider.min).to.equal(50); - expect(helper.scope.slider.max).to.equal(70); - }); - }); + expect(helper.scope.slider.min).to.equal(50) + expect(helper.scope.slider.max).to.equal(70) + }) + }) describe('Right to left Mouse controls - noSwitching Range Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -105,55 +109,54 @@ floor: 0, ceil: 100, noSwitching: true, - rightToLeft: true - } - }; - helper.createRangeSlider(sliderConf); - }); + rightToLeft: true, + }, + } + helper.createRangeSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should not switch min and max handles if minH is dragged after maxH', function() { - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 60; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(55); - }); + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 60 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(55) + }) it('should not switch min and max handles if maxH is dragged before minH', function() { - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 20; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.max).to.equal(45); - }); + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 20 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.max).to.equal(45) + }) it('should move minH if minH==maxH and click is on the left side of the bar', function() { - helper.scope.slider.min = helper.scope.slider.max = 50; - helper.scope.$digest(); + helper.scope.slider.min = helper.scope.slider.max = 50 + helper.scope.$digest() var expectedValue = 30, - offset = helper.getMousePosition(expectedValue); + position = helper.getMousePosition(expectedValue) - helper.fireMousedown(helper.slider.fullBar, offset); + helper.fireMousedown(helper.slider.fullBar, position) - expect(helper.scope.slider.min).to.equal(30); - expect(helper.scope.slider.max).to.equal(50); - }); + expect(helper.scope.slider.min).to.equal(30) + expect(helper.scope.slider.max).to.equal(50) + }) it('should move maxH if minH==maxH and click is on the right side of the bar', function() { - helper.scope.slider.min = helper.scope.slider.max = 50; - helper.scope.$digest(); + helper.scope.slider.min = helper.scope.slider.max = 50 + helper.scope.$digest() var expectedValue = 70, - offset = helper.getMousePosition(expectedValue); - - helper.fireMousedown(helper.slider.fullBar, offset); + position = helper.getMousePosition(expectedValue) - expect(helper.scope.slider.min).to.equal(50); - expect(helper.scope.slider.max).to.equal(70); - }); - }); -}()); + helper.fireMousedown(helper.slider.fullBar, position) + expect(helper.scope.slider.min).to.equal(50) + expect(helper.scope.slider.max).to.equal(70) + }) + }) +})() diff --git a/tests/specs/mouse-controls/onlyBindHandles-single-slider-horizontal-test.js b/tests/specs/mouse-controls/onlyBindHandles-single-slider-horizontal-test.js index 7b6fdc8..1db382a 100644 --- a/tests/specs/mouse-controls/onlyBindHandles-single-slider-horizontal-test.js +++ b/tests/specs/mouse-controls/onlyBindHandles-single-slider-horizontal-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Mouse controls - onlyBindHandles Single Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -27,59 +29,61 @@ floor: 0, ceil: 100, showTicks: true, - onlyBindHandles: true - } - }; - helper.createSlider(sliderConf); - }); + onlyBindHandles: true, + }, + } + helper.createSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should handle click and drag on minH correctly when mouse is on the middle', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnChange'); - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 50; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.value).to.equal(expectedValue); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 50 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should do nothing when a click happen on another element than the handle', function() { - helper.scope.slider.value = 100; - helper.scope.$digest(); + helper.scope.slider.value = 100 + helper.scope.$digest() - sinon.spy(helper.slider, 'positionTrackingHandle'); - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousedown(helper.slider.fullBar, 0); - helper.fireMousedown(helper.slider.ticks, 0); + sinon.spy(helper.slider, 'positionTrackingHandle') + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousedown(helper.slider.fullBar, 0) + helper.fireMousedown(helper.slider.ticks, 0) - expect(helper.scope.slider.value).to.equal(100); - helper.slider.positionTrackingHandle.called.should.be.false; - }); - }); + expect(helper.scope.slider.value).to.equal(100) + helper.slider.positionTrackingHandle.called.should.be.false + }) + }) describe('Right to left Mouse controls - onlyBindHandles Single Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -89,39 +93,38 @@ ceil: 100, showTicks: true, onlyBindHandles: true, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should handle click and drag on minH correctly when mouse is on the middle', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnChange'); - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 50; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.value).to.equal(expectedValue); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 50 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should do nothing when a click happen on another element than the handle', function() { - helper.scope.slider.value = 100; - helper.scope.$digest(); - - sinon.spy(helper.slider, 'positionTrackingHandle'); - helper.fireMousedown(helper.slider.selBar, 0); - helper.fireMousedown(helper.slider.fullBar, 0); - helper.fireMousedown(helper.slider.ticks, 0); - - expect(helper.scope.slider.value).to.equal(100); - helper.slider.positionTrackingHandle.called.should.be.false; - }); - }); -}()); - + helper.scope.slider.value = 100 + helper.scope.$digest() + + sinon.spy(helper.slider, 'positionTrackingHandle') + helper.fireMousedown(helper.slider.selBar, 0) + helper.fireMousedown(helper.slider.fullBar, 0) + helper.fireMousedown(helper.slider.ticks, 0) + + expect(helper.scope.slider.value).to.equal(100) + helper.slider.positionTrackingHandle.called.should.be.false + }) + }) +})() diff --git a/tests/specs/mouse-controls/pushRange-range-slider-horizontal-test.js b/tests/specs/mouse-controls/pushRange-range-slider-horizontal-test.js index 3de2012..d182637 100644 --- a/tests/specs/mouse-controls/pushRange-range-slider-horizontal-test.js +++ b/tests/specs/mouse-controls/pushRange-range-slider-horizontal-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Mouse controls - pushRange Range Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -27,108 +29,126 @@ options: { floor: 0, ceil: 100, - pushRange: true - } - }; - helper.createRangeSlider(sliderConf); - }); + pushRange: true, + }, + } + helper.createRangeSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should push maxH when moving minH above it', function() { - helper.fireMousedown(helper.slider.minH, 0); - helper.moveMouseToValue(60); - expect(helper.scope.slider.min).to.equal(60); - expect(helper.scope.slider.max).to.equal(61); - }); + helper.fireMousedown(helper.slider.minH, 0) + helper.moveMouseToValue(60) + expect(helper.scope.slider.min).to.equal(60) + expect(helper.scope.slider.max).to.equal(61) + }) it('should push minH when moving maxH below it', function() { - helper.fireMousedown(helper.slider.maxH, 0); - helper.moveMouseToValue(40); - expect(helper.scope.slider.min).to.equal(39); - expect(helper.scope.slider.max).to.equal(40); - }); + helper.fireMousedown(helper.slider.maxH, 0) + helper.moveMouseToValue(40) + expect(helper.scope.slider.min).to.equal(39) + expect(helper.scope.slider.max).to.equal(40) + }) it('should not move maxH above ceil when moving minH to ceil', function() { - helper.fireMousedown(helper.slider.minH, 0); - helper.moveMouseToValue(100); - expect(helper.scope.slider.min).to.equal(99); - expect(helper.scope.slider.max).to.equal(100); - }); + helper.fireMousedown(helper.slider.minH, 0) + helper.moveMouseToValue(100) + expect(helper.scope.slider.min).to.equal(99) + expect(helper.scope.slider.max).to.equal(100) + }) it('should not move minH below floor when moving maxH to floor', function() { - helper.fireMousedown(helper.slider.maxH, 0); - helper.moveMouseToValue(0); - expect(helper.scope.slider.min).to.equal(0); - expect(helper.scope.slider.max).to.equal(1); - }); + helper.fireMousedown(helper.slider.maxH, 0) + helper.moveMouseToValue(0) + expect(helper.scope.slider.min).to.equal(0) + expect(helper.scope.slider.max).to.equal(1) + }) it('should push maxH according to step', function() { - helper.scope.slider.options.step = 5; - helper.scope.$digest(); + helper.scope.slider.options.step = 5 + helper.scope.$digest() - helper.fireMousedown(helper.slider.minH, 0); - helper.moveMouseToValue(60); - expect(helper.scope.slider.min).to.equal(60); - expect(helper.scope.slider.max).to.equal(65); - }); + helper.fireMousedown(helper.slider.minH, 0) + helper.moveMouseToValue(60) + expect(helper.scope.slider.min).to.equal(60) + expect(helper.scope.slider.max).to.equal(65) + }) it('should push minH according to step', function() { - helper.scope.slider.options.step = 5; - helper.scope.$digest(); + helper.scope.slider.options.step = 5 + helper.scope.$digest() - helper.fireMousedown(helper.slider.maxH, 0); - helper.moveMouseToValue(40); - expect(helper.scope.slider.min).to.equal(35); - expect(helper.scope.slider.max).to.equal(40); - }); + helper.fireMousedown(helper.slider.maxH, 0) + helper.moveMouseToValue(40) + expect(helper.scope.slider.min).to.equal(35) + expect(helper.scope.slider.max).to.equal(40) + }) it('should push maxH according to minRange when both step and minRange are defined', function() { - helper.scope.slider.options.step = 5; - helper.scope.slider.options.minRange = 10; - helper.scope.$digest(); + helper.scope.slider.options.step = 5 + helper.scope.slider.options.minRange = 10 + helper.scope.$digest() - helper.fireMousedown(helper.slider.minH, 0); - helper.moveMouseToValue(60); - expect(helper.scope.slider.min).to.equal(60); - expect(helper.scope.slider.max).to.equal(70); - }); + helper.fireMousedown(helper.slider.minH, 0) + helper.moveMouseToValue(60) + expect(helper.scope.slider.min).to.equal(60) + expect(helper.scope.slider.max).to.equal(70) + }) it('should push minH according to minRange when both step and minRange are defined', function() { - helper.scope.slider.options.step = 5; - helper.scope.slider.options.minRange = 10; - helper.scope.$digest(); + helper.scope.slider.options.step = 5 + helper.scope.slider.options.minRange = 10 + helper.scope.$digest() - helper.fireMousedown(helper.slider.maxH, 0); - helper.moveMouseToValue(40); - expect(helper.scope.slider.min).to.equal(30); - expect(helper.scope.slider.max).to.equal(40); - }); + helper.fireMousedown(helper.slider.maxH, 0) + helper.moveMouseToValue(40) + expect(helper.scope.slider.min).to.equal(30) + expect(helper.scope.slider.max).to.equal(40) + }) it('should push maxH according to minRange when minRange is 0', function() { - helper.scope.slider.options.step = 5; - helper.scope.slider.options.minRange = 0; - helper.scope.$digest(); + helper.scope.slider.options.step = 5 + helper.scope.slider.options.minRange = 0 + helper.scope.$digest() - helper.fireMousedown(helper.slider.minH, 0); - helper.moveMouseToValue(60); - expect(helper.scope.slider.min).to.equal(60); - expect(helper.scope.slider.max).to.equal(60); - }); + helper.fireMousedown(helper.slider.minH, 0) + helper.moveMouseToValue(60) + expect(helper.scope.slider.min).to.equal(60) + expect(helper.scope.slider.max).to.equal(60) + }) it('should push minH according to minRange when minRange is 0', function() { - helper.scope.slider.options.step = 5; - helper.scope.slider.options.minRange = 0; - helper.scope.$digest(); - - helper.fireMousedown(helper.slider.maxH, 0); - helper.moveMouseToValue(40); - expect(helper.scope.slider.min).to.equal(40); - expect(helper.scope.slider.max).to.equal(40); - }); - }); - -}()); - + helper.scope.slider.options.step = 5 + helper.scope.slider.options.minRange = 0 + helper.scope.$digest() + + helper.fireMousedown(helper.slider.maxH, 0) + helper.moveMouseToValue(40) + expect(helper.scope.slider.min).to.equal(40) + expect(helper.scope.slider.max).to.equal(40) + }) + + it('should pull minH when moving maxH above maxRange', function() { + helper.scope.slider.options.maxRange = 15 + helper.scope.$digest() + + helper.fireMousedown(helper.slider.maxH, 0) + helper.moveMouseToValue(80) + expect(helper.scope.slider.min).to.equal(65) + expect(helper.scope.slider.max).to.equal(80) + }) + + it('should pull maxH when moving minH above maxRange', function() { + helper.scope.slider.options.maxRange = 15 + helper.scope.$digest() + + helper.fireMousedown(helper.slider.minH, 0) + helper.moveMouseToValue(20) + expect(helper.scope.slider.min).to.equal(20) + expect(helper.scope.slider.max).to.equal(35) + }) + }) +})() diff --git a/tests/specs/mouse-controls/range-slider-horizontal-test.js b/tests/specs/mouse-controls/range-slider-horizontal-test.js index e5918b4..bf8a05e 100644 --- a/tests/specs/mouse-controls/range-slider-horizontal-test.js +++ b/tests/specs/mouse-controls/range-slider-horizontal-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Mouse controls - Range Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -26,265 +28,267 @@ max: 100, options: { floor: 0, - ceil: 100 - } - }; - helper.createRangeSlider(sliderConf); - }); + ceil: 100, + }, + } + helper.createRangeSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should handle mousedown on minH correctly when keyboardSupport is true', function() { - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') - var event = helper.fireMousedown(helper.slider.minH, 0); + var event = helper.fireMousedown(helper.slider.minH, 0) - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('lowValue'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - }); + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + }) it('should handle mousedown on minH correctly when keyboardSupport is false', function() { - helper.scope.slider.options.keyboardSupport = false; - helper.scope.$digest(); + helper.scope.slider.options.keyboardSupport = false + helper.scope.$digest() - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') - var event = helper.fireMousedown(helper.slider.minH, 0); + var event = helper.fireMousedown(helper.slider.minH, 0) - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.called.should.be.false; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('lowValue'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - }); + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.called.should.be.false + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + }) it('should handle mousedown on maxH correctly when keyboardSupport is true', function() { - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') - var event = helper.fireMousedown(helper.slider.maxH, 0); + var event = helper.fireMousedown(helper.slider.maxH, 0) - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('highValue'); - expect(helper.slider.maxH.hasClass('rz-active')).to.be.true; - }); + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('highValue') + expect(helper.slider.maxH.hasClass('rz-active')).to.be.true + }) it('should handle mousedown on maxH correctly when keyboardSupport is false', function() { - helper.scope.slider.options.keyboardSupport = false; - helper.scope.$digest(); + helper.scope.slider.options.keyboardSupport = false + helper.scope.$digest() - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') - var event = helper.fireMousedown(helper.slider.maxH, 0); + var event = helper.fireMousedown(helper.slider.maxH, 0) - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.called.should.be.false; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('highValue'); - expect(helper.slider.maxH.hasClass('rz-active')).to.be.true; - }); + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.called.should.be.false + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('highValue') + expect(helper.slider.maxH.hasClass('rz-active')).to.be.true + }) it('should handle click and drag on minH correctly when mouse is on the middle', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnChange'); - var event = helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 50; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(expectedValue); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + var event = helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 50 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click and drag on maxH correctly when mouse is on the middle', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnChange'); - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 50; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.max).to.equal(expectedValue); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 50 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.max).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click and drag on minH and switch min/max if needed', function() { - helper.scope.slider.min = 40; - helper.scope.slider.max = 60; - helper.scope.$digest(); + helper.scope.slider.min = 40 + helper.scope.slider.max = 60 + helper.scope.$digest() - sinon.spy(helper.slider, 'focusElement'); - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 80; - helper.moveMouseToValue(expectedValue); + sinon.spy(helper.slider, 'focusElement') + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 80 + helper.moveMouseToValue(expectedValue) - expect(helper.scope.slider.min).to.equal(60); - expect(helper.scope.slider.max).to.equal(80); - helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true; - }); + expect(helper.scope.slider.min).to.equal(60) + expect(helper.scope.slider.max).to.equal(80) + helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true + }) it('should handle click and drag on minH and switch min/max if needed when keyboardSupport is false', function() { - helper.scope.slider.options.keyboardSupport = false; - helper.scope.slider.min = 40; - helper.scope.slider.max = 60; - helper.scope.$digest(); + helper.scope.slider.options.keyboardSupport = false + helper.scope.slider.min = 40 + helper.scope.slider.max = 60 + helper.scope.$digest() - sinon.spy(helper.slider, 'focusElement'); - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 80; - helper.moveMouseToValue(expectedValue); + sinon.spy(helper.slider, 'focusElement') + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 80 + helper.moveMouseToValue(expectedValue) - expect(helper.scope.slider.min).to.equal(60); - expect(helper.scope.slider.max).to.equal(80); - helper.slider.focusElement.called.should.be.false; - }); + expect(helper.scope.slider.min).to.equal(60) + expect(helper.scope.slider.max).to.equal(80) + helper.slider.focusElement.called.should.be.false + }) it('should handle click and drag on maxH and switch min/max if needed', function() { - helper.scope.slider.min = 40; - helper.scope.slider.max = 60; - helper.scope.$digest(); + helper.scope.slider.min = 40 + helper.scope.slider.max = 60 + helper.scope.$digest() - sinon.spy(helper.slider, 'focusElement'); - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 20; - helper.moveMouseToValue(expectedValue); + sinon.spy(helper.slider, 'focusElement') + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 20 + helper.moveMouseToValue(expectedValue) - expect(helper.scope.slider.min).to.equal(20); - expect(helper.scope.slider.max).to.equal(40); - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - }); + expect(helper.scope.slider.min).to.equal(20) + expect(helper.scope.slider.max).to.equal(40) + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + }) it('should handle click and drag on maxH and switch min/max if needed when keyboardSupport is false', function() { - helper.scope.slider.options.keyboardSupport = false; - helper.scope.slider.min = 40; - helper.scope.slider.max = 60; - helper.scope.$digest(); + helper.scope.slider.options.keyboardSupport = false + helper.scope.slider.min = 40 + helper.scope.slider.max = 60 + helper.scope.$digest() - sinon.spy(helper.slider, 'focusElement'); - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 20; - helper.moveMouseToValue(expectedValue); + sinon.spy(helper.slider, 'focusElement') + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 20 + helper.moveMouseToValue(expectedValue) - expect(helper.scope.slider.min).to.equal(20); - expect(helper.scope.slider.max).to.equal(40); - helper.slider.focusElement.called.should.be.false; - }); + expect(helper.scope.slider.min).to.equal(20) + expect(helper.scope.slider.max).to.equal(40) + helper.slider.focusElement.called.should.be.false + }) it('should handle click on fullbar and move minH when click pos is nearer to minH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') var expectedValue = 10, - offset = helper.getMousePosition(expectedValue); + position = helper.getMousePosition(expectedValue) - var event = helper.fireMousedown(helper.slider.fullBar, offset); + var event = helper.fireMousedown(helper.slider.fullBar, position) - expect(helper.scope.slider.min).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.min).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on fullbar and move maxH when click pos is nearer to maxH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') var expectedValue = 90, - offset = helper.getMousePosition(expectedValue); + position = helper.getMousePosition(expectedValue) - var event = helper.fireMousedown(helper.slider.fullBar, offset); + var event = helper.fireMousedown(helper.slider.fullBar, position) - expect(helper.scope.slider.max).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('highValue'); - helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true; - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.max).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('highValue') + helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on selbar and move minH when click pos is nearer to minH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') var expectedValue = 10, - offset = helper.getMousePosition(expectedValue); + position = helper.getMousePosition(expectedValue) - var event = helper.fireMousedown(helper.slider.selBar, offset); + var event = helper.fireMousedown(helper.slider.selBar, position) - expect(helper.scope.slider.min).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.min).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on selbar and move maxH when click pos is nearer to maxH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') var expectedValue = 90, - offset = helper.getMousePosition(expectedValue); + position = helper.getMousePosition(expectedValue) - var event = helper.fireMousedown(helper.slider.selBar, offset); + var event = helper.fireMousedown(helper.slider.selBar, position) - expect(helper.scope.slider.max).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('highValue'); - helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true; - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); - }); + expect(helper.scope.slider.max).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('highValue') + helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) + }) describe('Right to left Mouse controls - Range Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -293,245 +297,244 @@ options: { floor: 0, ceil: 100, - rightToLeft: true - } - }; - helper.createRangeSlider(sliderConf); - }); + rightToLeft: true, + }, + } + helper.createRangeSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should handle mousedown on minH correctly when keyboardSupport is true', function() { - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') - var event = helper.fireMousedown(helper.slider.minH, 0); + var event = helper.fireMousedown(helper.slider.minH, 0) - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('lowValue'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - }); + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + }) it('should handle mousedown on minH correctly when keyboardSupport is false', function() { - helper.scope.slider.options.keyboardSupport = false; - helper.scope.$digest(); + helper.scope.slider.options.keyboardSupport = false + helper.scope.$digest() - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') - var event = helper.fireMousedown(helper.slider.minH, 0); + var event = helper.fireMousedown(helper.slider.minH, 0) - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.called.should.be.false; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('lowValue'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - }); + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.called.should.be.false + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + }) it('should handle mousedown on maxH correctly when keyboardSupport is true', function() { - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') - var event = helper.fireMousedown(helper.slider.maxH, 0); + var event = helper.fireMousedown(helper.slider.maxH, 0) - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('highValue'); - expect(helper.slider.maxH.hasClass('rz-active')).to.be.true; - }); + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('highValue') + expect(helper.slider.maxH.hasClass('rz-active')).to.be.true + }) it('should handle mousedown on maxH correctly when keyboardSupport is false', function() { - helper.scope.slider.options.keyboardSupport = false; - helper.scope.$digest(); + helper.scope.slider.options.keyboardSupport = false + helper.scope.$digest() - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') - var event = helper.fireMousedown(helper.slider.maxH, 0); + var event = helper.fireMousedown(helper.slider.maxH, 0) - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.called.should.be.false; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('highValue'); - expect(helper.slider.maxH.hasClass('rz-active')).to.be.true; - }); + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.called.should.be.false + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('highValue') + expect(helper.slider.maxH.hasClass('rz-active')).to.be.true + }) it('should handle click and drag on minH correctly when mouse is on the middle', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnChange'); - var event = helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 50; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.min).to.equal(expectedValue); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + var event = helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 50 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.min).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click and drag on maxH correctly when mouse is on the middle', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnChange'); - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 50; - helper.moveMouseToValue(expectedValue); - expect(helper.scope.slider.max).to.equal(expectedValue); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 50 + helper.moveMouseToValue(expectedValue) + expect(helper.scope.slider.max).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click and drag on minH and switch min/max if needed', function() { - helper.scope.slider.min = 40; - helper.scope.slider.max = 60; - helper.scope.$digest(); + helper.scope.slider.min = 40 + helper.scope.slider.max = 60 + helper.scope.$digest() - sinon.spy(helper.slider, 'focusElement'); - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 80; - helper.moveMouseToValue(expectedValue); + sinon.spy(helper.slider, 'focusElement') + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 80 + helper.moveMouseToValue(expectedValue) - expect(helper.scope.slider.min).to.equal(60); - expect(helper.scope.slider.max).to.equal(80); - helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true; - }); + expect(helper.scope.slider.min).to.equal(60) + expect(helper.scope.slider.max).to.equal(80) + helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true + }) it('should handle click and drag on minH and switch min/max if needed when keyboardSupport is false', function() { - helper.scope.slider.options.keyboardSupport = false; - helper.scope.slider.min = 40; - helper.scope.slider.max = 60; - helper.scope.$digest(); + helper.scope.slider.options.keyboardSupport = false + helper.scope.slider.min = 40 + helper.scope.slider.max = 60 + helper.scope.$digest() - sinon.spy(helper.slider, 'focusElement'); - helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 80; - helper.moveMouseToValue(expectedValue); + sinon.spy(helper.slider, 'focusElement') + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 80 + helper.moveMouseToValue(expectedValue) - expect(helper.scope.slider.min).to.equal(60); - expect(helper.scope.slider.max).to.equal(80); - helper.slider.focusElement.called.should.be.false; - }); + expect(helper.scope.slider.min).to.equal(60) + expect(helper.scope.slider.max).to.equal(80) + helper.slider.focusElement.called.should.be.false + }) it('should handle click and drag on maxH and switch min/max if needed', function() { - helper.scope.slider.min = 40; - helper.scope.slider.max = 60; - helper.scope.$digest(); + helper.scope.slider.min = 40 + helper.scope.slider.max = 60 + helper.scope.$digest() - sinon.spy(helper.slider, 'focusElement'); - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 20; - helper.moveMouseToValue(expectedValue); + sinon.spy(helper.slider, 'focusElement') + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 20 + helper.moveMouseToValue(expectedValue) - expect(helper.scope.slider.min).to.equal(20); - expect(helper.scope.slider.max).to.equal(40); - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - }); + expect(helper.scope.slider.min).to.equal(20) + expect(helper.scope.slider.max).to.equal(40) + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + }) it('should handle click and drag on maxH and switch min/max if needed when keyboardSupport is false', function() { - helper.scope.slider.options.keyboardSupport = false; - helper.scope.slider.min = 40; - helper.scope.slider.max = 60; - helper.scope.$digest(); + helper.scope.slider.options.keyboardSupport = false + helper.scope.slider.min = 40 + helper.scope.slider.max = 60 + helper.scope.$digest() - sinon.spy(helper.slider, 'focusElement'); - helper.fireMousedown(helper.slider.maxH, 0); - var expectedValue = 20; - helper.moveMouseToValue(expectedValue); + sinon.spy(helper.slider, 'focusElement') + helper.fireMousedown(helper.slider.maxH, 0) + var expectedValue = 20 + helper.moveMouseToValue(expectedValue) - expect(helper.scope.slider.min).to.equal(20); - expect(helper.scope.slider.max).to.equal(40); - helper.slider.focusElement.called.should.be.false; - }); + expect(helper.scope.slider.min).to.equal(20) + expect(helper.scope.slider.max).to.equal(40) + helper.slider.focusElement.called.should.be.false + }) it('should handle click on fullbar and move minH when click pos is nearer to minH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') var expectedValue = 10, - offset = helper.getMousePosition(expectedValue); + position = helper.getMousePosition(expectedValue) - var event = helper.fireMousedown(helper.slider.fullBar, offset); + var event = helper.fireMousedown(helper.slider.fullBar, position) - expect(helper.scope.slider.min).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.min).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on fullbar and move maxH when click pos is nearer to maxH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') var expectedValue = 90, - offset = helper.getMousePosition(expectedValue); + position = helper.getMousePosition(expectedValue) - var event = helper.fireMousedown(helper.slider.fullBar, offset); + var event = helper.fireMousedown(helper.slider.fullBar, position) - expect(helper.scope.slider.max).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('highValue'); - helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true; - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.max).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('highValue') + helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on selbar and move minH when click pos is nearer to minH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') var expectedValue = 10, - offset = helper.getMousePosition(expectedValue); + position = helper.getMousePosition(expectedValue) - var event = helper.fireMousedown(helper.slider.selBar, offset); + var event = helper.fireMousedown(helper.slider.selBar, position) - expect(helper.scope.slider.min).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.min).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on selbar and move maxH when click pos is nearer to maxH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') var expectedValue = 90, - offset = helper.getMousePosition(expectedValue); - - var event = helper.fireMousedown(helper.slider.selBar, offset); - - expect(helper.scope.slider.max).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('highValue'); - helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true; - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); - }); -}()); - + position = helper.getMousePosition(expectedValue) + + var event = helper.fireMousedown(helper.slider.selBar, position) + + expect(helper.scope.slider.max).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('highValue') + helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) + }) +})() diff --git a/tests/specs/mouse-controls/range-slider-vertical-test.js b/tests/specs/mouse-controls/range-slider-vertical-test.js index 2560662..b22f9ed 100644 --- a/tests/specs/mouse-controls/range-slider-vertical-test.js +++ b/tests/specs/mouse-controls/range-slider-vertical-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Mouse controls - Range Vertical', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -27,233 +29,259 @@ options: { floor: 0, ceil: 100, - vertical: true - } - }; - helper.createRangeSlider(sliderConf); - }); + vertical: true, + }, + } + helper.createRangeSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should handle mousedown on minH correctly when keyboardSupport is true', function() { - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') - var event = helper.fireMousedown(helper.slider.minH, 0, true); + var event = helper.fireMousedown(helper.slider.minH, 0, true) - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('lowValue'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - }); + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + }) it('should handle mousedown on minH correctly when keyboardSupport is false', function() { - helper.scope.slider.options.keyboardSupport = false; - helper.scope.$digest(); + helper.scope.slider.options.keyboardSupport = false + helper.scope.$digest() - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') - var event = helper.fireMousedown(helper.slider.minH, 0, true); + var event = helper.fireMousedown(helper.slider.minH, 0, true) - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.called.should.be.false; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('lowValue'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - }); + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.called.should.be.false + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + }) it('should handle mousedown on maxH correctly when keyboardSupport is true', function() { - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') - var event = helper.fireMousedown(helper.slider.maxH, 0, true); + var event = helper.fireMousedown(helper.slider.maxH, 0, true) - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('highValue'); - expect(helper.slider.maxH.hasClass('rz-active')).to.be.true; - }); + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('highValue') + expect(helper.slider.maxH.hasClass('rz-active')).to.be.true + }) it('should handle mousedown on maxH correctly when keyboardSupport is false', function() { - helper.scope.slider.options.keyboardSupport = false; - helper.scope.$digest(); + helper.scope.slider.options.keyboardSupport = false + helper.scope.$digest() - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') - var event = helper.fireMousedown(helper.slider.maxH, 0, true); + var event = helper.fireMousedown(helper.slider.maxH, 0, true) - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.called.should.be.false; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('highValue'); - expect(helper.slider.maxH.hasClass('rz-active')).to.be.true; - }); + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.called.should.be.false + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('highValue') + expect(helper.slider.maxH.hasClass('rz-active')).to.be.true + }) it('should handle click and drag on minH correctly when mouse is on the middle', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnChange'); - var event = helper.fireMousedown(helper.slider.minH, 0, true); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + var event = helper.fireMousedown(helper.slider.minH, 0, true) var expectedValue = 50, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; - helper.fireMousemove(offset, true); - expect(helper.scope.slider.min).to.equal(expectedValue); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim + helper.fireMousemove(position, true) + expect(helper.scope.slider.min).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click and drag on maxH correctly when mouse is on the middle', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnChange'); - var event = helper.fireMousedown(helper.slider.maxH, 0, true); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + var event = helper.fireMousedown(helper.slider.maxH, 0, true) var expectedValue = 50, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; - helper.fireMousemove(offset, true); - expect(helper.scope.slider.max).to.equal(expectedValue); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim + helper.fireMousemove(position, true) + expect(helper.scope.slider.max).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click and drag on minH and switch min/max if needed', function() { - helper.scope.slider.min = 40; - helper.scope.slider.max = 60; - helper.scope.$digest(); + helper.scope.slider.min = 40 + helper.scope.slider.max = 60 + helper.scope.$digest() - var event = helper.fireMousedown(helper.slider.minH, 0, true); + var event = helper.fireMousedown(helper.slider.minH, 0, true) var expectedValue = 80, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; - helper.fireMousemove(offset, true); + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim + helper.fireMousemove(position, true) - expect(helper.scope.slider.min).to.equal(60); - expect(helper.scope.slider.max).to.equal(80); - }); + expect(helper.scope.slider.min).to.equal(60) + expect(helper.scope.slider.max).to.equal(80) + }) it('should handle click and drag on maxH and switch min/max if needed', function() { - helper.scope.slider.min = 40; - helper.scope.slider.max = 60; - helper.scope.$digest(); + helper.scope.slider.min = 40 + helper.scope.slider.max = 60 + helper.scope.$digest() - var event = helper.fireMousedown(helper.slider.maxH, 0, true); + var event = helper.fireMousedown(helper.slider.maxH, 0, true) var expectedValue = 20, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; - helper.fireMousemove(offset, true); + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim + helper.fireMousemove(position, true) - expect(helper.scope.slider.min).to.equal(20); - expect(helper.scope.slider.max).to.equal(40); - }); + expect(helper.scope.slider.min).to.equal(20) + expect(helper.scope.slider.max).to.equal(40) + }) it('should handle click on fullbar and move minH when click pos is nearer to minH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') var expectedValue = 10, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim - var event = helper.fireMousedown(helper.slider.fullBar, offset, true); + var event = helper.fireMousedown(helper.slider.fullBar, position, true) - expect(helper.scope.slider.min).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.min).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on fullbar and move maxH when click pos is nearer to maxH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') var expectedValue = 90, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim - var event = helper.fireMousedown(helper.slider.fullBar, offset, true); + var event = helper.fireMousedown(helper.slider.fullBar, position, true) - expect(helper.scope.slider.max).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('highValue'); - helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true; - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.max).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('highValue') + helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on selbar and move minH when click pos is nearer to minH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') var expectedValue = 10, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim - var event = helper.fireMousedown(helper.slider.selBar, offset, true); + var event = helper.fireMousedown(helper.slider.selBar, position, true) - expect(helper.scope.slider.min).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.min).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on selbar and move maxH when click pos is nearer to maxH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') var expectedValue = 90, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; - - var event = helper.fireMousedown(helper.slider.selBar, offset, true); - - expect(helper.scope.slider.max).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('highValue'); - helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true; - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); - }); + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim + + var event = helper.fireMousedown(helper.slider.selBar, position, true) + + expect(helper.scope.slider.max).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('highValue') + helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) + }) describe('Right to left Mouse controls - Range Vertical', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -263,213 +291,236 @@ floor: 0, ceil: 100, vertical: true, - rightToLeft: true - } - }; - helper.createRangeSlider(sliderConf); - }); + rightToLeft: true, + }, + } + helper.createRangeSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should handle mousedown on minH correctly when keyboardSupport is true', function() { - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') - var event = helper.fireMousedown(helper.slider.minH, 0, true); + var event = helper.fireMousedown(helper.slider.minH, 0, true) - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('lowValue'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - }); + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + }) it('should handle mousedown on minH correctly when keyboardSupport is false', function() { - helper.scope.slider.options.keyboardSupport = false; - helper.scope.$digest(); + helper.scope.slider.options.keyboardSupport = false + helper.scope.$digest() - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') - var event = helper.fireMousedown(helper.slider.minH, 0, true); + var event = helper.fireMousedown(helper.slider.minH, 0, true) - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.called.should.be.false; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('lowValue'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - }); + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.called.should.be.false + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + }) it('should handle mousedown on maxH correctly when keyboardSupport is true', function() { - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') - var event = helper.fireMousedown(helper.slider.maxH, 0, true); + var event = helper.fireMousedown(helper.slider.maxH, 0, true) - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('highValue'); - expect(helper.slider.maxH.hasClass('rz-active')).to.be.true; - }); + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('highValue') + expect(helper.slider.maxH.hasClass('rz-active')).to.be.true + }) it('should handle mousedown on maxH correctly when keyboardSupport is false', function() { - helper.scope.slider.options.keyboardSupport = false; - helper.scope.$digest(); + helper.scope.slider.options.keyboardSupport = false + helper.scope.$digest() - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') - var event = helper.fireMousedown(helper.slider.maxH, 0, true); + var event = helper.fireMousedown(helper.slider.maxH, 0, true) - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.called.should.be.false; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('highValue'); - expect(helper.slider.maxH.hasClass('rz-active')).to.be.true; - }); + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.called.should.be.false + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('highValue') + expect(helper.slider.maxH.hasClass('rz-active')).to.be.true + }) it('should handle click and drag on minH correctly when mouse is on the middle', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnChange'); - var event = helper.fireMousedown(helper.slider.minH, 0, true); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + var event = helper.fireMousedown(helper.slider.minH, 0, true) var expectedValue = 50, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; - helper.fireMousemove(offset, true); - expect(helper.scope.slider.min).to.equal(expectedValue); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim + helper.fireMousemove(position, true) + expect(helper.scope.slider.min).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click and drag on maxH correctly when mouse is on the middle', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnChange'); - var event = helper.fireMousedown(helper.slider.maxH, 0, true); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + var event = helper.fireMousedown(helper.slider.maxH, 0, true) var expectedValue = 50, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; - helper.fireMousemove(offset, true); - expect(helper.scope.slider.max).to.equal(expectedValue); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim + helper.fireMousemove(position, true) + expect(helper.scope.slider.max).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click and drag on minH and switch min/max if needed', function() { - helper.scope.slider.min = 40; - helper.scope.slider.max = 60; - helper.scope.$digest(); + helper.scope.slider.min = 40 + helper.scope.slider.max = 60 + helper.scope.$digest() - var event = helper.fireMousedown(helper.slider.minH, 0, true); + var event = helper.fireMousedown(helper.slider.minH, 0, true) var expectedValue = 80, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; - helper.fireMousemove(offset, true); + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim + helper.fireMousemove(position, true) - expect(helper.scope.slider.min).to.equal(60); - expect(helper.scope.slider.max).to.equal(80); - }); + expect(helper.scope.slider.min).to.equal(60) + expect(helper.scope.slider.max).to.equal(80) + }) it('should handle click and drag on maxH and switch min/max if needed', function() { - helper.scope.slider.min = 40; - helper.scope.slider.max = 60; - helper.scope.$digest(); + helper.scope.slider.min = 40 + helper.scope.slider.max = 60 + helper.scope.$digest() - var event = helper.fireMousedown(helper.slider.maxH, 0, true); + var event = helper.fireMousedown(helper.slider.maxH, 0, true) var expectedValue = 20, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; - helper.fireMousemove(offset, true); + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim + helper.fireMousemove(position, true) - expect(helper.scope.slider.min).to.equal(20); - expect(helper.scope.slider.max).to.equal(40); - }); + expect(helper.scope.slider.min).to.equal(20) + expect(helper.scope.slider.max).to.equal(40) + }) it('should handle click on fullbar and move minH when click pos is nearer to minH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') var expectedValue = 10, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim - var event = helper.fireMousedown(helper.slider.fullBar, offset, true); + var event = helper.fireMousedown(helper.slider.fullBar, position, true) - expect(helper.scope.slider.min).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.min).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on fullbar and move maxH when click pos is nearer to maxH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') var expectedValue = 90, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim - var event = helper.fireMousedown(helper.slider.fullBar, offset, true); + var event = helper.fireMousedown(helper.slider.fullBar, position, true) - expect(helper.scope.slider.max).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('highValue'); - helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true; - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.max).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('highValue') + helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on selbar and move minH when click pos is nearer to minH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') var expectedValue = 10, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim - var event = helper.fireMousedown(helper.slider.selBar, offset, true); + var event = helper.fireMousedown(helper.slider.selBar, position, true) - expect(helper.scope.slider.min).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.min).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on selbar and move maxH when click pos is nearer to maxH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + sinon.spy(helper.slider, 'focusElement') var expectedValue = 90, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; - - var event = helper.fireMousedown(helper.slider.selBar, offset, true); - - expect(helper.scope.slider.max).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('highValue'); - helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true; - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); - }); -}()); - + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim + + var event = helper.fireMousedown(helper.slider.selBar, position, true) + + expect(helper.scope.slider.max).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('highValue') + helper.slider.focusElement.calledWith(helper.slider.maxH).should.be.true + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) + }) +})() diff --git a/tests/specs/mouse-controls/restricted-range-slider-test.js b/tests/specs/mouse-controls/restricted-range-slider-test.js new file mode 100644 index 0000000..13e2b68 --- /dev/null +++ b/tests/specs/mouse-controls/restricted-range-slider-test.js @@ -0,0 +1,145 @@ +;(function() { + 'use strict' + + describe('Mouse controls - Restricted Range', function() { + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) + + afterEach(function() { + helper.clean() + }) + + beforeEach(function() { + var sliderConf = { + min: 25, + max: 85, + options: { + floor: 0, + ceil: 100, + restrictedRange: { + from: 30, + to: 70, + }, + }, + } + helper.createRangeSlider(sliderConf) + }) + + afterEach(function() { + // to clean document listener + helper.fireMouseup() + }) + + it('should be able to modify minH below restrictedRange.from', function() { + helper.fireMousedown(helper.slider.minH, 0) + var attemptedValue = 25 + helper.moveMouseToValue(attemptedValue) + expect(helper.scope.slider.min).to.equal(25) + }) + + it('should not be able to modify minH above restrictedRange.from', function() { + helper.fireMousedown(helper.slider.minH, 0) + var attemptedValue = 40 + helper.moveMouseToValue(attemptedValue) + expect(helper.scope.slider.min).to.equal(30) + }) + + it('should be able to modify maxH above restrictedRange.to', function() { + helper.fireMousedown(helper.slider.maxH, 0) + var attemptedValue = 78 + helper.moveMouseToValue(attemptedValue) + expect(helper.scope.slider.max).to.equal(78) + }) + + it('should not be able to modify maxH below restrictedRange.to', function() { + helper.fireMousedown(helper.slider.maxH, 0) + var attemptedValue = 50 + helper.moveMouseToValue(attemptedValue) + expect(helper.scope.slider.max).to.equal(70) + }) + }) + + describe('Right to left Mouse controls - minLimit!=null && maxLimit!=null Range Horizontal', function() { + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) + + afterEach(function() { + helper.clean() + }) + + beforeEach(function() { + var sliderConf = { + min: 45, + max: 55, + options: { + floor: 0, + ceil: 100, + restrictedRange: { + from: 30, + to: 70, + }, + rightToLeft: true, + }, + } + helper.createRangeSlider(sliderConf) + }) + afterEach(function() { + // to clean document listener + helper.fireMouseup() + }) + + it('should be able to modify minH below restrictedRange.from', function() { + helper.fireMousedown(helper.slider.minH, 0) + var attemptedValue = 25 + helper.moveMouseToValue(attemptedValue) + expect(helper.scope.slider.min).to.equal(25) + }) + + it('should not be able to modify minH above restrictedRange.from', function() { + helper.fireMousedown(helper.slider.minH, 0) + var attemptedValue = 40 + helper.moveMouseToValue(attemptedValue) + expect(helper.scope.slider.min).to.equal(30) + }) + + it('should be able to modify maxH above restrictedRange.to', function() { + helper.fireMousedown(helper.slider.maxH, 0) + var attemptedValue = 78 + helper.moveMouseToValue(attemptedValue) + expect(helper.scope.slider.max).to.equal(78) + }) + + it('should not be able to modify maxH below restrictedRange.to', function() { + helper.fireMousedown(helper.slider.maxH, 0) + var attemptedValue = 50 + helper.moveMouseToValue(attemptedValue) + expect(helper.scope.slider.max).to.equal(70) + }) + }) +})() diff --git a/tests/specs/mouse-controls/single-slider-horizontal-test.js b/tests/specs/mouse-controls/single-slider-horizontal-test.js index db774a8..501cb28 100644 --- a/tests/specs/mouse-controls/single-slider-horizontal-test.js +++ b/tests/specs/mouse-controls/single-slider-horizontal-test.js @@ -1,412 +1,523 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Mouse controls - Single Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) + + afterEach(function() { + helper.clean() + }) + + beforeEach(function() { + var sliderConf = { + value: 0, + options: { + floor: 0, + ceil: 100, + }, + } + helper.createSlider(sliderConf) + }) + afterEach(function() { + // to clean document listener + helper.fireMouseup() + }) + + it('should handle mousedown on minH correctly when keyboardSupport is true', function() { + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') + + var event = helper.fireMousedown(helper.slider.minH, 0) + + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + }) + + it('should handle mousedown on minH correctly when keyboardSupport is false', function() { + helper.scope.slider.options.keyboardSupport = false + helper.scope.$digest() + + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') + + var event = helper.fireMousedown(helper.slider.minH, 0) + + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.called.should.be.false + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + }) + + it('should handle click and drag on minH correctly when mouse is on the middle', function() { + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + var event = helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 50, + position = helper.getMousePosition(expectedValue) + helper.fireMousemove(position) + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) + + it('should handle click and drag on minH correctly when mouse is before the slider and previous value was different than 0', function() { + helper.scope.slider.value = 50 + helper.scope.$digest() + + sinon.spy(helper.slider, 'positionTrackingHandle') + var event = helper.fireMousedown(helper.slider.minH, 0) + helper.fireMousemove(-100) + expect(helper.scope.slider.value).to.equal(0) + helper.slider.positionTrackingHandle.called.should.be.true + }) + + it('should handle click and drag on minH correctly when mouse is after the slider and previous value was different than 100', function() { + sinon.spy(helper.slider, 'positionTrackingHandle') + var event = helper.fireMousedown(helper.slider.minH, 0) + helper.fireMousemove(helper.slider.maxPos + 100) + expect(helper.scope.slider.value).to.equal(100) + helper.slider.positionTrackingHandle.called.should.be.true + }) + + it('should call correct callbacks on slider end and keep handle focused when keyboardSupport is true', function() { + var event = helper.fireMousedown(helper.slider.minH, 0) + + sinon.spy(helper.slider, 'callOnEnd') + sinon.spy(helper.slider.scope, '$emit') + helper.fireMouseup() + + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + helper.slider.callOnEnd.called.should.be.true + helper.slider.scope.$emit.calledWith('slideEnded').should.be.true + }) + + it('should call correct callbacks on slider end and not keep handle focused when keyboardSupport is false', function() { + helper.scope.slider.options.keyboardSupport = false + helper.scope.$digest() + var event = helper.fireMousedown(helper.slider.minH, 0) + + sinon.spy(helper.slider, 'callOnEnd') + sinon.spy(helper.slider.scope, '$emit') + + helper.fireMouseup() + + expect(helper.slider.tracking).to.equal('') + expect(helper.slider.minH.hasClass('rz-active')).to.be.false + helper.slider.callOnEnd.called.should.be.true + helper.slider.scope.$emit.calledWith('slideEnded').should.be.true + }) + + it('should handle click on fullbar and move minH', function() { + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + + var expectedValue = 12, + position = helper.getMousePosition(expectedValue) + + helper.fireMousedown(helper.slider.fullBar, position) + + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) - beforeEach(module('test-helper')); + it('should handle click on selbar and move minH', function() { + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') - beforeEach(inject(function (TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var expectedValue = 12, + position = helper.getMousePosition(expectedValue) + + var event = helper.fireMousedown(helper.slider.selBar, position) + + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) + + it('should handle click on ticks and move minH', function() { + helper.scope.slider.options.step = 10 + helper.scope.slider.options.showTicks = true + helper.scope.$digest() + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') + + var expectedValue = 10, + position = helper.getMousePosition(expectedValue) + + helper.fireMousedown(helper.slider.ticks, position) + + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) - afterEach(function () { - helper.clean(); - }); + it('should handle click on ticks when showTicks is an integer and move minH', function() { + helper.scope.slider.options.step = 1 + helper.scope.slider.options.showTicks = 10 + helper.scope.$digest() + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') - beforeEach(function () { + var expectedValue = 10, + position = helper.getMousePosition(expectedValue) + + helper.fireMousedown(helper.slider.ticks, position) + + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) + }) + + describe('Right to left Mouse controls - Single Horizontal', function() { + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) + + afterEach(function() { + helper.clean() + }) + + beforeEach(function() { var sliderConf = { value: 0, options: { floor: 0, - ceil: 100 - } - }; - helper.createSlider(sliderConf); - }); - afterEach(function () { + ceil: 100, + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + }) + afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); - - it('should handle mousedown on minH correctly when keyboardSupport is true', function () { - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); - - var event = helper.fireMousedown(helper.slider.minH, 0); - - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('lowValue'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - }); - - it('should handle mousedown on minH correctly when keyboardSupport is false', function () { - helper.scope.slider.options.keyboardSupport = false; - helper.scope.$digest(); - - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); - - var event = helper.fireMousedown(helper.slider.minH, 0); - - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.called.should.be.false; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('lowValue'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - }); - - it('should handle click and drag on minH correctly when mouse is on the middle', function () { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnChange'); - var event = helper.fireMousedown(helper.slider.minH, 0); + helper.fireMouseup() + }) + + it('should handle mousedown on minH correctly when keyboardSupport is true', function() { + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') + + var event = helper.fireMousedown(helper.slider.minH, 0) + + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + }) + + it('should handle mousedown on minH correctly when keyboardSupport is false', function() { + helper.scope.slider.options.keyboardSupport = false + helper.scope.$digest() + + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') + + var event = helper.fireMousedown(helper.slider.minH, 0) + + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.called.should.be.false + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + }) + + it('should handle click and drag on minH correctly when mouse is on the middle', function() { + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + var event = helper.fireMousedown(helper.slider.minH, 0) var expectedValue = 50, - offset = helper.getMousePosition(expectedValue); - helper.fireMousemove(offset); - expect(helper.scope.slider.value).to.equal(expectedValue); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); - - it('should handle click and drag on minH correctly when mouse is before the slider and previous value was different than 0', function () { - helper.scope.slider.value = 50; - helper.scope.$digest(); - - sinon.spy(helper.slider, 'positionTrackingHandle'); - var event = helper.fireMousedown(helper.slider.minH, 0); - helper.fireMousemove(-100); - expect(helper.scope.slider.value).to.equal(0); - helper.slider.positionTrackingHandle.called.should.be.true; - }); - - it('should handle click and drag on minH correctly when mouse is after the slider and previous value was different than 100', function () { - sinon.spy(helper.slider, 'positionTrackingHandle'); - var event = helper.fireMousedown(helper.slider.minH, 0); - helper.fireMousemove(helper.slider.maxPos + 100); - expect(helper.scope.slider.value).to.equal(100); - helper.slider.positionTrackingHandle.called.should.be.true; - }); - - it('should call correct callbacks on slider end and keep handle focused when keyboardSupport is true', function () { - var event = helper.fireMousedown(helper.slider.minH, 0); - - sinon.spy(helper.slider, 'callOnEnd'); - sinon.spy(helper.slider.scope, '$emit'); - helper.fireMouseup(); - - expect(helper.slider.tracking).to.equal('lowValue'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - helper.slider.callOnEnd.called.should.be.true; - helper.slider.scope.$emit.calledWith('slideEnded').should.be.true; - }); - - it('should call correct callbacks on slider end and not keep handle focused when keyboardSupport is false', function () { - helper.scope.slider.options.keyboardSupport = false; - helper.scope.$digest(); - var event = helper.fireMousedown(helper.slider.minH, 0); - - sinon.spy(helper.slider, 'callOnEnd'); - sinon.spy(helper.slider.scope, '$emit'); - - helper.fireMouseup(); - - expect(helper.slider.tracking).to.equal(''); - expect(helper.slider.minH.hasClass('rz-active')).to.be.false; - helper.slider.callOnEnd.called.should.be.true; - helper.slider.scope.$emit.calledWith('slideEnded').should.be.true; - }); - - it('should handle click on fullbar and move minH', function () { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); + position = helper.getMousePosition(expectedValue) + helper.fireMousemove(position) + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) + + it('should handle click and drag on minH correctly when mouse is before the slider and previous value was different than 0', function() { + helper.scope.slider.value = 50 + helper.scope.$digest() + sinon.spy(helper.slider, 'positionTrackingHandle') + var event = helper.fireMousedown(helper.slider.minH, 0) + helper.fireMousemove(helper.slider.maxPos + 100) + expect(helper.scope.slider.value).to.equal(0) + helper.slider.positionTrackingHandle.called.should.be.true + }) + + it('should handle click and drag on minH correctly when mouse is after the slider and previous value was different than 100', function() { + sinon.spy(helper.slider, 'positionTrackingHandle') + var event = helper.fireMousedown(helper.slider.minH, 0) + helper.fireMousemove(-100) + expect(helper.scope.slider.value).to.equal(100) + helper.slider.positionTrackingHandle.called.should.be.true + }) + + it('should call correct callbacks on slider end and keep handle focused when keyboardSupport is true', function() { + var event = helper.fireMousedown(helper.slider.minH, 0) + + sinon.spy(helper.slider, 'callOnEnd') + sinon.spy(helper.slider.scope, '$emit') + helper.fireMouseup() + + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + helper.slider.callOnEnd.called.should.be.true + helper.slider.scope.$emit.calledWith('slideEnded').should.be.true + }) + + it('should call correct callbacks on slider end and not keep handle focused when keyboardSupport is false', function() { + helper.scope.slider.options.keyboardSupport = false + helper.scope.$digest() + var event = helper.fireMousedown(helper.slider.minH, 0) + + sinon.spy(helper.slider, 'callOnEnd') + sinon.spy(helper.slider.scope, '$emit') + + helper.fireMouseup() + + expect(helper.slider.tracking).to.equal('') + expect(helper.slider.minH.hasClass('rz-active')).to.be.false + helper.slider.callOnEnd.called.should.be.true + helper.slider.scope.$emit.calledWith('slideEnded').should.be.true + }) + + it('should handle click on fullbar and move minH', function() { + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') var expectedValue = 12, - offset = helper.getMousePosition(expectedValue); + position = helper.getMousePosition(expectedValue) - helper.fireMousedown(helper.slider.fullBar, offset); + helper.fireMousedown(helper.slider.fullBar, position) - expect(helper.scope.slider.value).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) - it('should handle click on selbar and move minH', function () { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); + it('should handle click on selbar and move minH', function() { + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') var expectedValue = 12, - offset = helper.getMousePosition(expectedValue); + position = helper.getMousePosition(expectedValue) - var event = helper.fireMousedown(helper.slider.selBar, offset); + var event = helper.fireMousedown(helper.slider.selBar, position) - expect(helper.scope.slider.value).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) - it('should handle click on ticks and move minH', function () { - helper.scope.slider.options.step = 10; - helper.scope.slider.options.showTicks = true; - helper.scope.$digest(); - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); + it('should handle click on ticks and move minH', function() { + helper.scope.slider.options.step = 10 + helper.scope.slider.options.showTicks = true + helper.scope.$digest() + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') var expectedValue = 10, - offset = helper.getMousePosition(expectedValue); + position = helper.getMousePosition(expectedValue) - helper.fireMousedown(helper.slider.ticks, offset); + helper.fireMousedown(helper.slider.ticks, position) - expect(helper.scope.slider.value).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) - it('should handle click on ticks when showTicks is an integer and move minH', function () { - helper.scope.slider.options.step = 1; - helper.scope.slider.options.showTicks = 10; - helper.scope.$digest(); - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); + it('should handle click on ticks when showTicks is an integer and move minH', function() { + helper.scope.slider.options.step = 1 + helper.scope.slider.options.showTicks = 10 + helper.scope.$digest() + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') var expectedValue = 10, - offset = helper.getMousePosition(expectedValue); - - helper.fireMousedown(helper.slider.ticks, offset); - - expect(helper.scope.slider.value).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); - }); - - describe('Right to left Mouse controls - Single Horizontal', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); - - afterEach(function() { - helper.clean(); - }); - - beforeEach(function() { - var sliderConf = { - value: 0, - options: { - floor: 0, - ceil: 100, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - }); - afterEach(function() { - // to clean document listener - helper.fireMouseup(); - }); - - it('should handle mousedown on minH correctly when keyboardSupport is true', function() { - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); - - var event = helper.fireMousedown(helper.slider.minH, 0); - - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('lowValue'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - }); - - it('should handle mousedown on minH correctly when keyboardSupport is false', function() { - helper.scope.slider.options.keyboardSupport = false; - helper.scope.$digest(); - - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); - - var event = helper.fireMousedown(helper.slider.minH, 0); - - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.called.should.be.false; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('lowValue'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - }); - - it('should handle click and drag on minH correctly when mouse is on the middle', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnChange'); - var event = helper.fireMousedown(helper.slider.minH, 0); - var expectedValue = 50, - offset = helper.getMousePosition(expectedValue); - helper.fireMousemove(offset); - expect(helper.scope.slider.value).to.equal(expectedValue); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); - - it('should handle click and drag on minH correctly when mouse is before the slider and previous value was different than 0', function() { - helper.scope.slider.value = 50; - helper.scope.$digest(); - sinon.spy(helper.slider, 'positionTrackingHandle'); - var event = helper.fireMousedown(helper.slider.minH, 0); - helper.fireMousemove(helper.slider.maxPos + 100); - expect(helper.scope.slider.value).to.equal(0); - helper.slider.positionTrackingHandle.called.should.be.true; - }); - - it('should handle click and drag on minH correctly when mouse is after the slider and previous value was different than 100', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - var event = helper.fireMousedown(helper.slider.minH, 0); - helper.fireMousemove(-100); - expect(helper.scope.slider.value).to.equal(100); - helper.slider.positionTrackingHandle.called.should.be.true; - }); - - it('should call correct callbacks on slider end and keep handle focused when keyboardSupport is true', function() { - var event = helper.fireMousedown(helper.slider.minH, 0); - - sinon.spy(helper.slider, 'callOnEnd'); - sinon.spy(helper.slider.scope, '$emit'); - helper.fireMouseup(); - - expect(helper.slider.tracking).to.equal('lowValue'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - helper.slider.callOnEnd.called.should.be.true; - helper.slider.scope.$emit.calledWith('slideEnded').should.be.true; - }); - - it('should call correct callbacks on slider end and not keep handle focused when keyboardSupport is false', function() { - helper.scope.slider.options.keyboardSupport = false; - helper.scope.$digest(); - var event = helper.fireMousedown(helper.slider.minH, 0); - - sinon.spy(helper.slider, 'callOnEnd'); - sinon.spy(helper.slider.scope, '$emit'); - - helper.fireMouseup(); - - expect(helper.slider.tracking).to.equal(''); - expect(helper.slider.minH.hasClass('rz-active')).to.be.false; - helper.slider.callOnEnd.called.should.be.true; - helper.slider.scope.$emit.calledWith('slideEnded').should.be.true; - }); - - it('should handle click on fullbar and move minH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - - var expectedValue = 12, - offset = helper.getMousePosition(expectedValue); - - helper.fireMousedown(helper.slider.fullBar, offset); - - expect(helper.scope.slider.value).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); - - it('should handle click on selbar and move minH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - - var expectedValue = 12, - offset = helper.getMousePosition(expectedValue); - - var event = helper.fireMousedown(helper.slider.selBar, offset); - - expect(helper.scope.slider.value).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); - - it('should handle click on ticks and move minH', function() { - helper.scope.slider.options.step = 10; - helper.scope.slider.options.showTicks = true; - helper.scope.$digest(); - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - - var expectedValue = 10, - offset = helper.getMousePosition(expectedValue); - - helper.fireMousedown(helper.slider.ticks, offset); - - expect(helper.scope.slider.value).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); - - it('should handle click on ticks when showTicks is an integer and move minH', function() { - helper.scope.slider.options.step = 1; - helper.scope.slider.options.showTicks = 10; - helper.scope.$digest(); - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); - - var expectedValue = 10, - offset = helper.getMousePosition(expectedValue); - - helper.fireMousedown(helper.slider.ticks, offset); - - expect(helper.scope.slider.value).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); - }); -}()); - + position = helper.getMousePosition(expectedValue) + + helper.fireMousedown(helper.slider.ticks, position) + + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) + + it('should handle touch start, touch move and touch end correctly when multitouch with originalEvent', function() { + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + + // Touch start for the slider + helper.fireTouchstartWithOriginalEvent(helper.slider.minH, 0, 0, [0]) + + var expectedValue = 50 + var touchPositionForSlider = helper.getMousePosition(expectedValue) + // Touch move for the slider + helper.fireTouchmoveWithOriginalEvent(touchPositionForSlider, 0, [0, 1]) + + // Simultaneous touch move but not on slider + var otherTouchPosition = touchPositionForSlider + 100 + helper.fireTouchmoveWithOriginalEvent(otherTouchPosition, 1, [0, 1]) + + // The slider does not react + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + + // The other simultaneous touch ends + helper.fireTouchendWithOriginalEvent(1, [0, 1]) + + var expectedValue = 60 + var touchPositionForSlider = helper.getMousePosition(expectedValue) + // Touch move for the slider + helper.fireTouchmoveWithOriginalEvent(touchPositionForSlider, 0, [0, 1]) + + // Can still drag the slider + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(2) + expect(helper.slider.callOnChange.callCount).to.equal(2) + + // Slider touch ends + helper.fireTouchendWithOriginalEvent(0, [0, 1]) + + // Touch move for the slider + var touchPositionForSlider = helper.getMousePosition(70) + helper.fireTouchmoveWithOriginalEvent(touchPositionForSlider, 0, [0, 1]) + + // Can not drag the slider anymore + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(2) + expect(helper.slider.callOnChange.callCount).to.equal(2) + }) + + it('should handle touch start, touch move and touch end correctly when multitouch without originalEvent', function() { + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + + // Touch start for the slider + var eventOnSlider = helper.fireTouchstartWithoutOriginalEvent( + helper.slider.minH, + 0, + 0, + [0] + ) + + var expectedValue = 50 + var touchPositionForSlider = helper.getMousePosition(expectedValue) + // Touch move for the slider + helper.fireTouchmoveWithoutOriginalEvent(touchPositionForSlider, 0, [ + 0, + 1, + ]) + + // Simultaneous touch move but not on slider + var otherTouchPosition = touchPositionForSlider + 100 + helper.fireTouchmoveWithoutOriginalEvent(otherTouchPosition, 1, [0, 1]) + + // The slider does not react + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + + // The other simultaneous touch ends + helper.fireTouchendWithoutOriginalEvent(1, [0, 1]) + + var expectedValue = 60 + var touchPositionForSlider = helper.getMousePosition(expectedValue) + // Touch move for slider + helper.fireTouchmoveWithoutOriginalEvent(touchPositionForSlider, 0, [ + 0, + 1, + ]) + + // Can still drag the slider + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(2) + expect(helper.slider.callOnChange.callCount).to.equal(2) + + // Slider touch ends + helper.fireTouchendWithoutOriginalEvent(0, [0, 1]) + + // Touch move for the slider + var touchPositionForSlider = helper.getMousePosition(70) + helper.fireTouchmoveWithoutOriginalEvent(touchPositionForSlider, 0, [ + 0, + 1, + ]) + + // Can not drag the slider anymore + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(2) + expect(helper.slider.callOnChange.callCount).to.equal(2) + }) + }) +})() diff --git a/tests/specs/mouse-controls/single-slider-vertical-test.js b/tests/specs/mouse-controls/single-slider-vertical-test.js index a7c132c..897711a 100644 --- a/tests/specs/mouse-controls/single-slider-vertical-test.js +++ b/tests/specs/mouse-controls/single-slider-vertical-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Mouse controls - Single Vertical', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -26,206 +28,223 @@ options: { floor: 0, ceil: 100, - vertical: true - } - }; - helper.createSlider(sliderConf); - }); + vertical: true, + }, + } + helper.createSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should handle mousedown on minH correctly when keyboardSupport is true', function() { - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') - var event = helper.fireMousedown(helper.slider.minH, 0, true); + var event = helper.fireMousedown(helper.slider.minH, 0, true) - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('lowValue'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - }); + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + }) it('should handle mousedown on minH correctly when keyboardSupport is false', function() { - helper.scope.slider.options.keyboardSupport = false; - helper.scope.$digest(); + helper.scope.slider.options.keyboardSupport = false + helper.scope.$digest() - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') - var event = helper.fireMousedown(helper.slider.minH, 0, true); + var event = helper.fireMousedown(helper.slider.minH, 0, true) - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.called.should.be.false; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('lowValue'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - }); + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.called.should.be.false + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + }) it('should handle click and drag on minH correctly when mouse is on the middle', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnChange'); - helper.fireMousedown(helper.slider.minH, 0, true); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + helper.fireMousedown(helper.slider.minH, 0, true) var expectedValue = 50, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim - helper.fireMousemove(offset, true); - expect(helper.scope.slider.value).to.equal(expectedValue); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + helper.fireMousemove(position, true) + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click and drag on minH correctly when mouse is before the slider and previous value was different than 0', function() { - helper.scope.slider.value = 50; - helper.scope.$digest(); + helper.scope.slider.value = 50 + helper.scope.$digest() - sinon.spy(helper.slider, 'positionTrackingHandle'); - var event = helper.fireMousedown(helper.slider.minH, 0, true); - helper.fireMousemove(helper.slider.maxPos + 100, true); - expect(helper.scope.slider.value).to.equal(0); - helper.slider.positionTrackingHandle.called.should.be.true; - }); + sinon.spy(helper.slider, 'positionTrackingHandle') + var event = helper.fireMousedown(helper.slider.minH, 0, true) + helper.fireMousemove(helper.slider.maxPos + 100, true) + expect(helper.scope.slider.value).to.equal(0) + helper.slider.positionTrackingHandle.called.should.be.true + }) it('should handle click and drag on minH correctly when mouse is after the slider and previous value was different than 100', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - var event = helper.fireMousedown(helper.slider.minH, 0, true); - helper.fireMousemove(-100, true); - expect(helper.scope.slider.value).to.equal(100); - helper.slider.positionTrackingHandle.called.should.be.true; - }); + sinon.spy(helper.slider, 'positionTrackingHandle') + var event = helper.fireMousedown(helper.slider.minH, 0, true) + helper.fireMousemove(-100, true) + expect(helper.scope.slider.value).to.equal(100) + helper.slider.positionTrackingHandle.called.should.be.true + }) it('should call correct callbacks on slider end and keep handle focused when keyboardSupport is true', function() { - var event = helper.fireMousedown(helper.slider.minH, 0, true); + var event = helper.fireMousedown(helper.slider.minH, 0, true) - sinon.spy(helper.slider, 'callOnEnd'); - sinon.spy(helper.slider.scope, '$emit'); - helper.fireMouseup(); + sinon.spy(helper.slider, 'callOnEnd') + sinon.spy(helper.slider.scope, '$emit') + helper.fireMouseup() - expect(helper.slider.tracking).to.equal('lowValue'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - helper.slider.callOnEnd.called.should.be.true; - helper.slider.scope.$emit.calledWith('slideEnded').should.be.true; - }); + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + helper.slider.callOnEnd.called.should.be.true + helper.slider.scope.$emit.calledWith('slideEnded').should.be.true + }) it('should call correct callbacks on slider end and not keep handle focused when keyboardSupport is false', function() { - helper.scope.slider.options.keyboardSupport = false; - helper.scope.$digest(); - var event = helper.fireMousedown(helper.slider.minH, 0, true); + helper.scope.slider.options.keyboardSupport = false + helper.scope.$digest() + var event = helper.fireMousedown(helper.slider.minH, 0, true) - sinon.spy(helper.slider, 'callOnEnd'); - sinon.spy(helper.slider.scope, '$emit'); + sinon.spy(helper.slider, 'callOnEnd') + sinon.spy(helper.slider.scope, '$emit') - helper.fireMouseup(); + helper.fireMouseup() - expect(helper.slider.tracking).to.equal(''); - expect(helper.slider.minH.hasClass('rz-active')).to.be.false; - helper.slider.callOnEnd.called.should.be.true; - helper.slider.scope.$emit.calledWith('slideEnded').should.be.true; - }); + expect(helper.slider.tracking).to.equal('') + expect(helper.slider.minH.hasClass('rz-active')).to.be.false + helper.slider.callOnEnd.called.should.be.true + helper.slider.scope.$emit.calledWith('slideEnded').should.be.true + }) it('should handle click on fullbar and move minH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') var expectedValue = 50, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim - var event = helper.fireMousedown(helper.slider.fullBar, offset, true); + var event = helper.fireMousedown(helper.slider.fullBar, position, true) - expect(helper.scope.slider.value).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on selbar and move minH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') var expectedValue = 12, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim - helper.fireMousedown(helper.slider.selBar, offset, true); + helper.fireMousedown(helper.slider.selBar, position, true) - expect(helper.scope.slider.value).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on ticks and move minH', function() { - helper.scope.slider.options.step = 10; - helper.scope.slider.options.showTicks = true; - helper.scope.$digest(); - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); + helper.scope.slider.options.step = 10 + helper.scope.slider.options.showTicks = true + helper.scope.$digest() + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') var expectedValue = 10, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim - helper.fireMousedown(helper.slider.ticks, offset, true); + helper.fireMousedown(helper.slider.ticks, position, true) - expect(helper.scope.slider.value).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on ticks when showTicks is an integer and move minH', function() { - helper.scope.slider.options.step = 1; - helper.scope.slider.options.showTicks = 10; - helper.scope.$digest(); - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); + helper.scope.slider.options.step = 1 + helper.scope.slider.options.showTicks = 10 + helper.scope.$digest() + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') var expectedValue = 10, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim - helper.fireMousedown(helper.slider.ticks, offset, true); + helper.fireMousedown(helper.slider.ticks, position, true) - expect(helper.scope.slider.value).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); - }); + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) + }) describe('Right to left Mouse controls - Single Vertical', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -234,187 +253,360 @@ floor: 0, ceil: 100, vertical: true, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + }) afterEach(function() { // to clean document listener - helper.fireMouseup(); - }); + helper.fireMouseup() + }) it('should handle mousedown on minH correctly when keyboardSupport is true', function() { - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') - var event = helper.fireMousedown(helper.slider.minH, 0, true); + var event = helper.fireMousedown(helper.slider.minH, 0, true) - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('lowValue'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - }); + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.calledWith(helper.slider.minH).should.be.true + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + }) it('should handle mousedown on minH correctly when keyboardSupport is false', function() { - helper.scope.slider.options.keyboardSupport = false; - helper.scope.$digest(); + helper.scope.slider.options.keyboardSupport = false + helper.scope.$digest() - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'focusElement'); + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'focusElement') - var event = helper.fireMousedown(helper.slider.minH, 0, true); + var event = helper.fireMousedown(helper.slider.minH, 0, true) - helper.slider.calcViewDimensions.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.focusElement.called.should.be.false; - event.preventDefault.called.should.be.true; - event.stopPropagation.called.should.be.true; - expect(helper.slider.tracking).to.equal('lowValue'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - }); + helper.slider.calcViewDimensions.called.should.be.true + helper.slider.callOnStart.called.should.be.true + helper.slider.focusElement.called.should.be.false + event.preventDefault.called.should.be.true + event.stopPropagation.called.should.be.true + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + }) it('should handle click and drag on minH correctly when mouse is on the middle', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnChange'); - helper.fireMousedown(helper.slider.minH, 0, true); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + helper.fireMousedown(helper.slider.minH, 0, true) var expectedValue = 50, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim - helper.fireMousemove(offset, true); - expect(helper.scope.slider.value).to.equal(expectedValue); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + helper.fireMousemove(position, true) + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click and drag on minH correctly when mouse is before the slider and previous value was different than 0', function() { - helper.scope.slider.value = 50; - helper.scope.$digest(); + helper.scope.slider.value = 50 + helper.scope.$digest() - sinon.spy(helper.slider, 'positionTrackingHandle'); - var event = helper.fireMousedown(helper.slider.minH, 0, true); - helper.fireMousemove(-100, true); - expect(helper.scope.slider.value).to.equal(0); - helper.slider.positionTrackingHandle.called.should.be.true; - }); + sinon.spy(helper.slider, 'positionTrackingHandle') + var event = helper.fireMousedown(helper.slider.minH, 0, true) + helper.fireMousemove(-100, true) + expect(helper.scope.slider.value).to.equal(0) + helper.slider.positionTrackingHandle.called.should.be.true + }) it('should handle click and drag on minH correctly when mouse is after the slider and previous value was different than 100', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - var event = helper.fireMousedown(helper.slider.minH, 0, true); - helper.fireMousemove(helper.slider.maxPos + 100, true); - expect(helper.scope.slider.value).to.equal(100); - helper.slider.positionTrackingHandle.called.should.be.true; - }); + sinon.spy(helper.slider, 'positionTrackingHandle') + var event = helper.fireMousedown(helper.slider.minH, 0, true) + helper.fireMousemove(helper.slider.maxPos + 100, true) + expect(helper.scope.slider.value).to.equal(100) + helper.slider.positionTrackingHandle.called.should.be.true + }) it('should call correct callbacks on slider end and keep handle focused when keyboardSupport is true', function() { - var event = helper.fireMousedown(helper.slider.minH, 0, true); + var event = helper.fireMousedown(helper.slider.minH, 0, true) - sinon.spy(helper.slider, 'callOnEnd'); - sinon.spy(helper.slider.scope, '$emit'); - helper.fireMouseup(); + sinon.spy(helper.slider, 'callOnEnd') + sinon.spy(helper.slider.scope, '$emit') + helper.fireMouseup() - expect(helper.slider.tracking).to.equal('lowValue'); - expect(helper.slider.minH.hasClass('rz-active')).to.be.true; - helper.slider.callOnEnd.called.should.be.true; - helper.slider.scope.$emit.calledWith('slideEnded').should.be.true; - }); + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.minH.hasClass('rz-active')).to.be.true + helper.slider.callOnEnd.called.should.be.true + helper.slider.scope.$emit.calledWith('slideEnded').should.be.true + }) it('should call correct callbacks on slider end and not keep handle focused when keyboardSupport is false', function() { - helper.scope.slider.options.keyboardSupport = false; - helper.scope.$digest(); - var event = helper.fireMousedown(helper.slider.minH, 0, true); + helper.scope.slider.options.keyboardSupport = false + helper.scope.$digest() + var event = helper.fireMousedown(helper.slider.minH, 0, true) - sinon.spy(helper.slider, 'callOnEnd'); - sinon.spy(helper.slider.scope, '$emit'); + sinon.spy(helper.slider, 'callOnEnd') + sinon.spy(helper.slider.scope, '$emit') - helper.fireMouseup(); + helper.fireMouseup() - expect(helper.slider.tracking).to.equal(''); - expect(helper.slider.minH.hasClass('rz-active')).to.be.false; - helper.slider.callOnEnd.called.should.be.true; - helper.slider.scope.$emit.calledWith('slideEnded').should.be.true; - }); + expect(helper.slider.tracking).to.equal('') + expect(helper.slider.minH.hasClass('rz-active')).to.be.false + helper.slider.callOnEnd.called.should.be.true + helper.slider.scope.$emit.calledWith('slideEnded').should.be.true + }) it('should handle click on fullbar and move minH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') var expectedValue = 50, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim - var event = helper.fireMousedown(helper.slider.fullBar, offset, true); + var event = helper.fireMousedown(helper.slider.fullBar, position, true) - expect(helper.scope.slider.value).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on selbar and move minH', function() { - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') var expectedValue = 12, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim - helper.fireMousedown(helper.slider.selBar, offset, true); + helper.fireMousedown(helper.slider.selBar, position, true) - expect(helper.scope.slider.value).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on ticks and move minH', function() { - helper.scope.slider.options.step = 10; - helper.scope.slider.options.showTicks = true; - helper.scope.$digest(); - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); + helper.scope.slider.options.step = 10 + helper.scope.slider.options.showTicks = true + helper.scope.$digest() + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') var expectedValue = 10, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim - helper.fireMousedown(helper.slider.ticks, offset, true); + helper.fireMousedown(helper.slider.ticks, position, true) - expect(helper.scope.slider.value).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) it('should handle click on ticks when showTicks is an integer and move minH', function() { - helper.scope.slider.options.step = 1; - helper.scope.slider.options.showTicks = 10; - helper.scope.$digest(); - sinon.spy(helper.slider, 'positionTrackingHandle'); - sinon.spy(helper.slider, 'callOnStart'); - sinon.spy(helper.slider, 'callOnChange'); + helper.scope.slider.options.step = 1 + helper.scope.slider.options.showTicks = 10 + helper.scope.$digest() + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnStart') + sinon.spy(helper.slider, 'callOnChange') var expectedValue = 10, - offset = helper.slider.sliderElem.rzsp - helper.slider.valueToOffset(expectedValue) - helper.slider.handleHalfDim; - - helper.fireMousedown(helper.slider.ticks, offset, true); - - expect(helper.scope.slider.value).to.equal(expectedValue); - expect(helper.slider.tracking).to.equal('lowValue'); - helper.slider.positionTrackingHandle.called.should.be.true; - helper.slider.callOnStart.called.should.be.true; - helper.slider.callOnChange.called.should.be.true; - }); - }); - -}()); - + position = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim + + helper.fireMousedown(helper.slider.ticks, position, true) + + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.tracking).to.equal('lowValue') + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnStart.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + }) + + it('should handle touch start, touch move and touch end correctly when multitouch with originalEvent', function() { + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + // Touch start for the slider + var eventOnSlider = helper.fireTouchstartWithOriginalEvent( + helper.slider.minH, + 0, + 0, + [0], + true + ) + + var expectedValue = 50 + var touchPositionForSlider = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim + + // Touch move for the slider + helper.fireTouchmoveWithOriginalEvent( + touchPositionForSlider, + 0, + [0, 1], + true + ) + + // Simultaneous touch move but not on slider + var otherTouchPosition = touchPositionForSlider + 100 + helper.fireTouchmoveWithOriginalEvent(otherTouchPosition, 1, [0, 1], true) + + // The slider does not react + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + + // The other simultaneous touch ends + helper.fireTouchendWithOriginalEvent(1, [0, 1], true) + + var expectedValue = 60 + var touchPositionForSlider = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim + // Touch move for the slider + helper.fireTouchmoveWithOriginalEvent( + touchPositionForSlider, + 0, + [0, 1], + true + ) + + // Can still drag the slider + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(2) + expect(helper.slider.callOnChange.callCount).to.equal(2) + + // Slider touch ends + helper.fireTouchendWithOriginalEvent(0, [0, 1], true) + + // Touch move for the slider + var touchPositionForSlider = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(70) - + helper.slider.handleHalfDim + helper.fireTouchmoveWithOriginalEvent( + touchPositionForSlider, + 0, + [0, 1], + true + ) + + //Can not drag the slider anymore + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(2) + expect(helper.slider.callOnChange.callCount).to.equal(2) + }) + + it('should handle touch start, touch move and touch end correctly when multitouch without originalEvent', function() { + sinon.spy(helper.slider, 'positionTrackingHandle') + sinon.spy(helper.slider, 'callOnChange') + + // Touch start for the slider + var eventOnSlider = helper.fireTouchstartWithoutOriginalEvent( + helper.slider.minH, + 0, + 0, + [0], + true + ) + var expectedValue = 50 + var touchPositionForSlider = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim + + // Touch move for slider + helper.fireTouchmoveWithoutOriginalEvent( + touchPositionForSlider, + 0, + [0, 1], + true + ) + + // Simultaneous touch move but not on slider + var otherTouchPosition = touchPositionForSlider + 100 + helper.fireTouchmoveWithoutOriginalEvent( + otherTouchPosition, + 1, + [0, 1], + true + ) + + // The slider does not react + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(1) + expect(helper.slider.callOnChange.callCount).to.equal(1) + + // The other simultaneous touch ends + helper.fireTouchendWithoutOriginalEvent(1, [0, 1], true) + + var expectedValue = 60 + var touchPositionForSlider = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(expectedValue) - + helper.slider.handleHalfDim + // Touch move for slider + helper.fireTouchmoveWithoutOriginalEvent( + touchPositionForSlider, + 0, + [0, 1], + true + ) + + // Can still drag the slider + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(2) + expect(helper.slider.callOnChange.callCount).to.equal(2) + + // Slider touch ends + helper.fireTouchendWithoutOriginalEvent(0, [0, 1], true) + + // Touch move for the slider + var touchPositionForSlider = + helper.slider.sliderElem.rzsp - + helper.slider.valueToPosition(70) - + helper.slider.handleHalfDim + + // Can not drag the slider anymore + helper.fireTouchmoveWithoutOriginalEvent( + touchPositionForSlider, + 0, + [0, 1], + true + ) + + expect(helper.scope.slider.value).to.equal(expectedValue) + expect(helper.slider.positionTrackingHandle.callCount).to.equal(2) + expect(helper.slider.callOnChange.callCount).to.equal(2) + }) + }) +})() diff --git a/tests/specs/options-handling-test.js b/tests/specs/options-handling-test.js index 18adf04..e64bc4d 100644 --- a/tests/specs/options-handling-test.js +++ b/tests/specs/options-handling-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Options handling - ', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) describe('tests with same config', function() { beforeEach(function() { @@ -27,245 +29,307 @@ options: { floor: 0, ceil: 100, - step: 10 - } - }; - helper.createSlider(sliderConf); - }); + step: 10, + }, + } + helper.createSlider(sliderConf) + }) it('horizontal slider should take the full width and get correct position/dimension properties', function() { - helper.scope.$digest(); - expect(helper.element[0].getBoundingClientRect().width).to.equal(1000); - expect(helper.slider.positionProperty).to.equal('left'); - expect(helper.slider.dimensionProperty).to.equal('width'); - expect(helper.slider.sliderElem.hasClass('rz-vertical')).to.be.false; - }); + helper.scope.$digest() + expect(helper.element[0].getBoundingClientRect().width).to.equal(1000) + expect(helper.slider.positionProperty).to.equal('left') + expect(helper.slider.dimensionProperty).to.equal('width') + expect(helper.slider.sliderElem.hasClass('rz-vertical')).to.be.false + }) it('vertical slider should take the full height and get correct position/dimension properties', function() { - helper.scope.$digest(); - helper.scope.slider.options.vertical = true; - helper.scope.$digest(); - expect(helper.element[0].getBoundingClientRect().height).to.equal(1000); - expect(helper.slider.positionProperty).to.equal('bottom'); - expect(helper.slider.dimensionProperty).to.equal('height'); - expect(helper.slider.sliderElem.hasClass('rz-vertical')).to.be.true; - }); + helper.scope.$digest() + helper.scope.slider.options.vertical = true + helper.scope.$digest() + expect(helper.element[0].getBoundingClientRect().height).to.equal(1000) + expect(helper.slider.positionProperty).to.equal('bottom') + expect(helper.slider.dimensionProperty).to.equal('height') + expect(helper.slider.sliderElem.hasClass('rz-vertical')).to.be.true + }) it('should prevent invalid step', function() { - helper.scope.slider.options.step = 0; - helper.scope.$digest(); - expect(helper.slider.options.step).to.equal(1); + helper.scope.slider.options.step = 0 + helper.scope.$digest() + expect(helper.slider.options.step).to.equal(1) - helper.scope.slider.options.step = -1; - helper.scope.$digest(); - expect(helper.slider.options.step).to.equal(1); - }); + helper.scope.slider.options.step = -1 + helper.scope.$digest() + expect(helper.slider.options.step).to.equal(1) + }) it('should not round value to step if enforceStep is false', function() { - helper.scope.slider.options.enforceStep = false; - helper.scope.$digest(); + helper.scope.slider.options.enforceStep = false + helper.scope.$digest() - helper.scope.slider.value = 14; - helper.scope.$digest(); - expect(helper.scope.slider.value).to.equal(14); - }); + helper.scope.slider.value = 14 + helper.scope.$digest() + expect(helper.scope.slider.value).to.equal(14) + }) it('should round value to step if enforceStep is true', function() { - helper.scope.slider.options.enforceStep = true; - helper.scope.$digest(); + helper.scope.slider.options.enforceStep = true + helper.scope.$digest() - helper.scope.slider.value = 14; - helper.scope.$digest(); - expect(helper.scope.slider.value).to.equal(10); - }); + helper.scope.slider.value = 14 + helper.scope.$digest() + expect(helper.scope.slider.value).to.equal(10) + }) it('should set the showTicks scope flag to true when showTicks is true', function() { - helper.scope.slider.options.showTicks = true; - helper.scope.$digest(); - expect(helper.slider.scope.showTicks).to.be.true; - }); + helper.scope.slider.options.showTicks = true + helper.scope.$digest() + expect(helper.slider.scope.showTicks).to.be.true + }) it('should set the showTicks scope flag to true when showTicksValues is true', function() { - helper.scope.slider.options.showTicksValues = true; - helper.scope.$digest(); - expect(helper.slider.scope.showTicks).to.be.true; - }); + helper.scope.slider.options.showTicksValues = true + helper.scope.$digest() + expect(helper.slider.scope.showTicks).to.be.true + }) it('should set not accept draggableRange to true when slider is a single one', function() { - helper.scope.slider.options.draggableRange = true; - helper.scope.$digest(); - expect(helper.slider.options.draggableRange).to.be.false; - }); + helper.scope.slider.options.draggableRange = true + helper.scope.$digest() + expect(helper.slider.options.draggableRange).to.be.false + }) it('should set not accept draggableRangeOnly to true when slider is a single one', function() { - helper.scope.slider.options.draggableRangeOnly = true; - helper.scope.$digest(); - expect(helper.slider.options.draggableRange).to.be.false; - expect(helper.slider.options.draggableRangeOnly).to.be.false; - }); + helper.scope.slider.options.draggableRangeOnly = true + helper.scope.$digest() + expect(helper.slider.options.draggableRange).to.be.false + expect(helper.slider.options.draggableRangeOnly).to.be.false + }) it('should set correct step/floor/ceil and translate function when stepsArray is used with values', function() { - helper.scope.slider.value = 'C'; - helper.scope.slider.options.stepsArray = ['A', 'B', 'C', 'D', 'E']; - helper.scope.$digest(); - expect(helper.slider.options.step).to.equal(1); - expect(helper.slider.options.floor).to.equal(0); - expect(helper.slider.options.ceil).to.equal(4); - expect(helper.slider.lowValue).to.equal(2); - }); + helper.scope.slider.value = 'C' + helper.scope.slider.options.stepsArray = ['A', 'B', 'C', 'D', 'E'] + helper.scope.$digest() + expect(helper.slider.options.step).to.equal(1) + expect(helper.slider.options.floor).to.equal(0) + expect(helper.slider.options.ceil).to.equal(4) + expect(helper.slider.lowValue).to.equal(2) + }) it('should set correct step/floor/ceil and translate function when stepsArray is used with values and bindIndexForStepsArray is true', function() { - helper.scope.slider.value = 2; - helper.scope.slider.options.stepsArray = ['A', 'B', 'C', 'D', 'E']; - helper.scope.slider.options.bindIndexForStepsArray = true; - helper.scope.$digest(); - expect(helper.slider.options.step).to.equal(1); - expect(helper.slider.options.floor).to.equal(0); - expect(helper.slider.options.ceil).to.equal(4); - expect(helper.slider.lowValue).to.equal(2); - }); + helper.scope.slider.value = 2 + helper.scope.slider.options.stepsArray = ['A', 'B', 'C', 'D', 'E'] + helper.scope.slider.options.bindIndexForStepsArray = true + helper.scope.$digest() + expect(helper.slider.options.step).to.equal(1) + expect(helper.slider.options.floor).to.equal(0) + expect(helper.slider.options.ceil).to.equal(4) + expect(helper.slider.lowValue).to.equal(2) + }) it('should set correct step/floor/ceil when stepsArray is used with values and ticks', function() { - helper.scope.slider.value = 'C'; - helper.scope.slider.options.stepsArray = ['A', 'B', 'C', 'D', 'E']; - helper.scope.slider.options.showTicks = true; - helper.scope.$digest(); - expect(helper.slider.options.step).to.equal(1); - expect(helper.slider.options.floor).to.equal(0); - expect(helper.slider.options.ceil).to.equal(4); - expect(helper.slider.lowValue).to.equal(2); - }); + helper.scope.slider.value = 'C' + helper.scope.slider.options.stepsArray = ['A', 'B', 'C', 'D', 'E'] + helper.scope.slider.options.showTicks = true + helper.scope.$digest() + expect(helper.slider.options.step).to.equal(1) + expect(helper.slider.options.floor).to.equal(0) + expect(helper.slider.options.ceil).to.equal(4) + expect(helper.slider.lowValue).to.equal(2) + }) it('should set correct step/floor/ceil when stepsArray is used with objects', function() { - helper.scope.slider.value = 'D'; + helper.scope.slider.value = 'D' helper.scope.slider.options.stepsArray = [ - {value: 'A'}, - {value: 'B'}, - {value: 'C'}, - {value: 'D'}, - {value: 'E'} - ]; - helper.scope.$digest(); - expect(helper.slider.options.step).to.equal(1); - expect(helper.slider.options.floor).to.equal(0); - expect(helper.slider.options.ceil).to.equal(4); - expect(helper.slider.lowValue).to.equal(3); - }); + { value: 'A' }, + { value: 'B' }, + { value: 'C' }, + { value: 'D' }, + { value: 'E' }, + ] + helper.scope.$digest() + expect(helper.slider.options.step).to.equal(1) + expect(helper.slider.options.floor).to.equal(0) + expect(helper.slider.options.ceil).to.equal(4) + expect(helper.slider.lowValue).to.equal(3) + }) it('should set correct step/floor/ceil when stepsArray is used with objects and bindIndexForStepsArray is true', function() { - helper.scope.slider.value = 3; + helper.scope.slider.value = 3 helper.scope.slider.options.stepsArray = [ - {value: 'A'}, - {value: 'B'}, - {value: 'C'}, - {value: 'D'}, - {value: 'E'} - ]; - helper.scope.slider.options.bindIndexForStepsArray = true; - helper.scope.$digest(); - expect(helper.slider.options.step).to.equal(1); - expect(helper.slider.options.floor).to.equal(0); - expect(helper.slider.options.ceil).to.equal(4); - expect(helper.slider.lowValue).to.equal(3); - }); + { value: 'A' }, + { value: 'B' }, + { value: 'C' }, + { value: 'D' }, + { value: 'E' }, + ] + helper.scope.slider.options.bindIndexForStepsArray = true + helper.scope.$digest() + expect(helper.slider.options.step).to.equal(1) + expect(helper.slider.options.floor).to.equal(0) + expect(helper.slider.options.ceil).to.equal(4) + expect(helper.slider.lowValue).to.equal(3) + }) it('should set correct step/floor/ceil function when stepsArray is used with objects containing legends', function() { - helper.scope.slider.value = 'D'; + helper.scope.slider.value = 'D' helper.scope.slider.options.stepsArray = [ - {value: 'A'}, - {value: 'B', legend: 'Legend B'}, - {value: 'C'}, - {value: 'D', legend: 'Legend D'}, - {value: 'E'} - ]; - helper.scope.slider.options.showTicks = true; - helper.scope.$digest(); - - expect(helper.slider.options.step).to.equal(1); - expect(helper.slider.options.floor).to.equal(0); - expect(helper.slider.options.ceil).to.equal(4); - expect(helper.slider.lowValue).to.equal(3); - - expect(helper.slider.getLegend(1)).to.equal('Legend B'); - expect(helper.slider.getLegend(3)).to.equal('Legend D'); - - expect(helper.element[0].querySelectorAll('.rz-tick-legend')).to.have.length(2); - }); + { value: 'A' }, + { value: 'B', legend: 'Legend B' }, + { value: 'C' }, + { value: 'D', legend: 'Legend D' }, + { value: 'E' }, + ] + helper.scope.slider.options.showTicks = true + helper.scope.$digest() + + expect(helper.slider.options.step).to.equal(1) + expect(helper.slider.options.floor).to.equal(0) + expect(helper.slider.options.ceil).to.equal(4) + expect(helper.slider.lowValue).to.equal(3) + + expect(helper.slider.getLegend(1)).to.equal('Legend B') + expect(helper.slider.getLegend(3)).to.equal('Legend D') + + expect( + helper.element[0].querySelectorAll('.rz-tick-legend') + ).to.have.length(2) + }) it('should set correct step/floor/ceil function when stepsArray is used with objects containing legends and bindIndexForStepsArray is true', function() { - helper.scope.slider.value = 3; + helper.scope.slider.value = 3 helper.scope.slider.options.stepsArray = [ - {value: 'A'}, - {value: 'B', legend: 'Legend B'}, - {value: 'C'}, - {value: 'D', legend: 'Legend D'}, - {value: 'E'} - ]; - helper.scope.slider.options.bindIndexForStepsArray = true; - helper.scope.slider.options.showTicks = true; - helper.scope.$digest(); - - expect(helper.slider.options.step).to.equal(1); - expect(helper.slider.options.floor).to.equal(0); - expect(helper.slider.options.ceil).to.equal(4); - expect(helper.slider.lowValue).to.equal(3); - - expect(helper.slider.getLegend(1)).to.equal('Legend B'); - expect(helper.slider.getLegend(3)).to.equal('Legend D'); - - expect(helper.element[0].querySelectorAll('.rz-tick-legend')).to.have.length(2); - }); + { value: 'A' }, + { value: 'B', legend: 'Legend B' }, + { value: 'C' }, + { value: 'D', legend: 'Legend D' }, + { value: 'E' }, + ] + helper.scope.slider.options.bindIndexForStepsArray = true + helper.scope.slider.options.showTicks = true + helper.scope.$digest() + + expect(helper.slider.options.step).to.equal(1) + expect(helper.slider.options.floor).to.equal(0) + expect(helper.slider.options.ceil).to.equal(4) + expect(helper.slider.lowValue).to.equal(3) + + expect(helper.slider.getLegend(1)).to.equal('Legend B') + expect(helper.slider.getLegend(3)).to.equal('Legend D') + + expect( + helper.element[0].querySelectorAll('.rz-tick-legend') + ).to.have.length(2) + }) + + it('should set correct step/floor/ceil when stepsArray is used with Date using same instances', function() { + var dates = [] + for (var i = 1; i <= 7; i++) { + dates.push(new Date(2016, 7, i)) + } + helper.scope.slider.value = dates[3] + helper.scope.slider.options.stepsArray = dates + helper.scope.$digest() + expect(helper.slider.options.step).to.equal(1) + expect(helper.slider.options.floor).to.equal(0) + expect(helper.slider.options.ceil).to.equal(6) + expect(helper.slider.lowValue).to.equal(3) + }) + + it('should set correct step/floor/ceil when stepsArray is used with Date using different instances', function() { + var dates = [] + for (var i = 1; i <= 7; i++) { + dates.push(new Date(2016, 7, i)) + } + helper.scope.slider.value = new Date(2016, 7, 4) + helper.scope.slider.options.stepsArray = dates + helper.scope.$digest() + expect(helper.slider.options.step).to.equal(1) + expect(helper.slider.options.floor).to.equal(0) + expect(helper.slider.options.ceil).to.equal(6) + expect(helper.slider.lowValue).to.equal(3) + }) + + it('should set correct step/floor/ceil when stepsArray is used with Object with Date values using different instances', function() { + var dates = [] + for (var i = 1; i <= 7; i++) { + dates.push(new Date(2016, 7, i)) + } + helper.scope.slider.value = new Date(2016, 7, 4) + helper.scope.slider.options.stepsArray = dates.map(function(val) { + return { value: val } + }) + helper.scope.$digest() + expect(helper.slider.options.step).to.equal(1) + expect(helper.slider.options.floor).to.equal(0) + expect(helper.slider.options.ceil).to.equal(6) + expect(helper.slider.lowValue).to.equal(3) + }) it('should allow a custom translate function when stepsArray is used', function() { helper.scope.slider.options.stepsArray = [ - {value: 'A', 'foo': 'barA'}, - {value: 'B', 'foo': 'barB'}, - {value: 'C', 'foo': 'barC'} - ]; - helper.scope.slider.options.translate = function(value, sliderId, label) { - return 'value: '+ value - }; - helper.scope.$digest(); - expect(helper.slider.options.step).to.equal(1); - expect(helper.slider.options.floor).to.equal(0); - expect(helper.slider.options.ceil).to.equal(2); - - expect(helper.slider.customTrFn('A')).to.equal('value: A'); - expect(helper.slider.customTrFn('C')).to.equal('value: C'); - }); + { value: 'A', foo: 'barA' }, + { value: 'B', foo: 'barB' }, + { value: 'C', foo: 'barC' }, + ] + helper.scope.slider.options.translate = function( + value, + sliderId, + label + ) { + return 'value: ' + value + } + helper.scope.$digest() + expect(helper.slider.options.step).to.equal(1) + expect(helper.slider.options.floor).to.equal(0) + expect(helper.slider.options.ceil).to.equal(2) + + expect(helper.slider.customTrFn('A')).to.equal('value: A') + expect(helper.slider.customTrFn('C')).to.equal('value: C') + }) it('should allow a custom translate function when stepsArray is used and bindIndexForStepsArray is true', function() { - helper.scope.slider.options.stepsArray = [{'foo': 'barA'}, {'foo': 'barB'}, {'foo': 'barC'}]; - helper.scope.slider.options.bindIndexForStepsArray = true; - helper.scope.slider.options.translate = function(value, sliderId, label) { - if (value >= 0 && value < helper.scope.slider.options.stepsArray.length) { - return helper.scope.slider.options.stepsArray[value]['foo']; - } - else { + helper.scope.slider.options.stepsArray = [ + { foo: 'barA' }, + { foo: 'barB' }, + { foo: 'barC' }, + ] + helper.scope.slider.options.bindIndexForStepsArray = true + helper.scope.slider.options.translate = function( + value, + sliderId, + label + ) { + if ( + value >= 0 && + value < helper.scope.slider.options.stepsArray.length + ) { + return helper.scope.slider.options.stepsArray[value]['foo'] + } else { return '' } - }; - helper.scope.$digest(); - expect(helper.slider.options.step).to.equal(1); - expect(helper.slider.options.floor).to.equal(0); - expect(helper.slider.options.ceil).to.equal(2); + } + helper.scope.$digest() + expect(helper.slider.options.step).to.equal(1) + expect(helper.slider.options.floor).to.equal(0) + expect(helper.slider.options.ceil).to.equal(2) - expect(helper.slider.customTrFn(0)).to.equal('barA'); - expect(helper.slider.customTrFn(2)).to.equal('barC'); - }); + expect(helper.slider.customTrFn(0)).to.equal('barA') + expect(helper.slider.customTrFn(2)).to.equal('barC') + }) it('should sanitize rzSliderModel between floor and ceil', function() { - helper.scope.slider.options.enforceRange = true; - helper.scope.slider.value = 1000; - helper.scope.$digest(); - expect(helper.scope.slider.value).to.equal(100); - - helper.scope.slider.value = -1000; - helper.scope.$digest(); - $timeout.flush(); //to flush the throttle function - expect(helper.scope.slider.value).to.equal(0); - }); - }); + helper.scope.slider.options.enforceRange = true + helper.scope.slider.value = 1000 + helper.scope.$digest() + expect(helper.scope.slider.value).to.equal(100) + + helper.scope.slider.value = -1000 + helper.scope.$digest() + $timeout.flush() //to flush the throttle function + expect(helper.scope.slider.value).to.equal(0) + }) + }) describe('tests with specific config', function() { it('should accept custom translate function', function() { @@ -276,31 +340,31 @@ ceil: 100, step: 10, translate: function(v) { - return 'custom value'; - } - } - }; - helper.createSlider(sliderConf); - expect(helper.slider.customTrFn(0)).to.equal('custom value'); - expect(helper.slider.customTrFn(100)).to.equal('custom value'); - }); + return 'custom value' + }, + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.customTrFn(0)).to.equal('custom value') + expect(helper.slider.customTrFn(100)).to.equal('custom value') + }) it('should set maxValue to rzSliderModel if no ceil is set for a single slider', function() { var sliderConf = { - value: 10 - }; - helper.createSlider(sliderConf); - expect(helper.slider.maxValue).to.equal(10); - }); + value: 10, + } + helper.createSlider(sliderConf) + expect(helper.slider.maxValue).to.equal(10) + }) it('should set maxValue to rzSliderHigh if no ceil is set for a range slider', function() { var sliderConf = { min: 10, - max: 100 - }; - helper.createRangeSlider(sliderConf); - expect(helper.slider.maxValue).to.equal(100); - }); + max: 100, + } + helper.createRangeSlider(sliderConf) + expect(helper.slider.maxValue).to.equal(100) + }) it('should set the correct dimension/position for selection bar for single slider with showSelectionBar=true', function() { var sliderConf = { @@ -308,14 +372,19 @@ options: { floor: 0, ceil: 10, - showSelectionBar: true - } - }; - helper.createSlider(sliderConf); - var expectedDimension = helper.slider.valueToOffset(2) + helper.slider.handleHalfDim; - expect(helper.slider.selBar.css('width')).to.equal(expectedDimension + 'px'); - expect(helper.slider.selBar.css('left')).to.equal('0px'); - }); + showSelectionBar: true, + disableAnimation: true, + }, + } + helper.createSlider(sliderConf) + var expectedDimension = + Math.round(helper.slider.valueToPosition(2)) + + helper.slider.handleHalfDim + expect(helper.slider.selBar.css('width')).to.equal( + expectedDimension + 'px' + ) + expect(helper.slider.selBar.css('left')).to.equal('0px') + }) it('should set the correct dimension/position for selection bar for single slider with showSelectionBarEnd=true', function() { var sliderConf = { @@ -323,15 +392,26 @@ options: { floor: 0, ceil: 10, - showSelectionBarEnd: true - } - }; - helper.createSlider(sliderConf); - var expectedDimension = helper.slider.valueToOffset(8) + helper.slider.handleHalfDim, - expectedPosition = helper.slider.valueToOffset(2) + helper.slider.handleHalfDim; - expect(helper.slider.selBar.css('width')).to.equal(expectedDimension + 'px'); - expect(helper.slider.selBar.css('left')).to.equal(expectedPosition + 'px'); - }); + showSelectionBarEnd: true, + disableAnimation: true, + }, + } + helper.createSlider(sliderConf) + var expectedDimension = Math.floor( + helper.slider.valueToPosition(8) + helper.slider.handleHalfDim + ), + actualDimension = Math.floor( + helper.slider.selBar[0].getBoundingClientRect().width + ) + expect(actualDimension).to.equal(expectedDimension) + + var expectedPosition = + Math.round(helper.slider.valueToPosition(2)) + + helper.slider.handleHalfDim + expect(helper.slider.selBar.css('left')).to.equal( + expectedPosition + 'px' + ) + }) it('should set the correct dimension/position for selection bar for single slider with showSelectionBarFromValue is used with a value on the right', function() { var sliderConf = { @@ -339,15 +419,22 @@ options: { floor: 0, ceil: 20, - showSelectionBarFromValue: 10 - } - }; - helper.createSlider(sliderConf); - var expectedDimension = helper.slider.valueToOffset(5), - expectedPosition = helper.slider.valueToOffset(10) + helper.slider.handleHalfDim; - expect(helper.slider.selBar.css('width')).to.equal(expectedDimension + 'px'); - expect(helper.slider.selBar.css('left')).to.equal(expectedPosition + 'px'); - }); + showSelectionBarFromValue: 10, + disableAnimation: true, + }, + } + helper.createSlider(sliderConf) + var expectedDimension = Math.round(helper.slider.valueToPosition(5)), + expectedPosition = + Math.round(helper.slider.valueToPosition(10)) + + helper.slider.handleHalfDim + expect(helper.slider.selBar.css('width')).to.equal( + expectedDimension + 'px' + ) + expect(helper.slider.selBar.css('left')).to.equal( + expectedPosition + 'px' + ) + }) it('should set the correct dimension/position for selection bar for single slider with showSelectionBarFromValue is used with a value on the left', function() { var sliderConf = { @@ -355,52 +442,108 @@ options: { floor: 0, ceil: 20, - showSelectionBarFromValue: 10 - } - }; - helper.createSlider(sliderConf); - var expectedDimension = helper.slider.valueToOffset(7), - expectedPosition = helper.slider.valueToOffset(3) + helper.slider.handleHalfDim; - expect(helper.slider.selBar.css('width')).to.equal(expectedDimension + 'px'); - expect(helper.slider.selBar.css('left')).to.equal(expectedPosition + 'px'); - }); + showSelectionBarFromValue: 10, + disableAnimation: true, + }, + } + helper.createSlider(sliderConf) + var expectedDimension = Math.round(helper.slider.valueToPosition(7)), + actualDimension = Math.round( + helper.slider.selBar[0].getBoundingClientRect().width + ) + expect(actualDimension).to.equal(expectedDimension) + + var expectedPosition = + Math.round(helper.slider.valueToPosition(3)) + + helper.slider.handleHalfDim + expect(helper.slider.selBar.css('left')).to.equal( + expectedPosition + 'px' + ) + }) + + it('should set the correct background position for selection bar for range slider when selectionBarGradient is used with a value {from: "white"; to:"blue"}', function() { + var sliderConf = { + min: 5, + max: 10, + options: { + floor: 0, + ceil: 20, + selectionBarGradient: { + from: 'white', + to: 'blue', + }, + }, + } + + helper.createRangeSlider(sliderConf) + + var expectedPosition = + -( + Math.round(helper.slider.valueToPosition(5)) + + helper.slider.handleHalfDim + ) + 'px center', + actualPosition = helper.slider.scope.barStyle.backgroundPosition + expect(actualPosition).to.equal(expectedPosition) + }) + + it('should set the correct gradient for selection bar for slider when selectionBarGradient is used with a value {from: "white"; to:"blue"} and vertical is used with a value true', function() { + var sliderConf = { + value: 5, + options: { + floor: 0, + ceil: 20, + vertical: true, + showSelectionBar: true, + selectionBarGradient: { + from: 'white', + to: 'blue', + }, + }, + } + + helper.createSlider(sliderConf) + + var expectedGradient = 'linear-gradient(to top, white 0%,blue 100%)', + actualGradient = helper.slider.scope.barStyle.backgroundImage + expect(actualGradient).to.equal(expectedGradient) + }) it('should set alwaysHide on floor/ceil when hideLimitLabels is set to true', function() { var sliderConf = { value: 10, options: { - hideLimitLabels: true - } - }; - helper.createSlider(sliderConf); - expect(helper.slider.flrLab.rzAlwaysHide).to.be.true; - expect(helper.slider.ceilLab.rzAlwaysHide).to.be.true; - }); + hideLimitLabels: true, + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.flrLab.rzAlwaysHide).to.be.true + expect(helper.slider.ceilLab.rzAlwaysHide).to.be.true + }) it('should set alwaysHide on minLab when hidePointerLabels is set to true on a single slider', function() { var sliderConf = { value: 10, options: { - hidePointerLabels: true - } - }; - helper.createSlider(sliderConf); - expect(helper.slider.minLab.rzAlwaysHide).to.be.true; - }); + hidePointerLabels: true, + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.minLab.rzAlwaysHide).to.be.true + }) it('should set alwaysHide on minLab when hidePointerLabels is set to true on a single slider', function() { var sliderConf = { min: 10, max: 100, options: { - hidePointerLabels: true - } - }; - helper.createRangeSlider(sliderConf); - expect(helper.slider.minLab.rzAlwaysHide).to.be.true; - expect(helper.slider.maxLab.rzAlwaysHide).to.be.true; - expect(helper.slider.cmbLab.rzAlwaysHide).to.be.true; - }); + hidePointerLabels: true, + }, + } + helper.createRangeSlider(sliderConf) + expect(helper.slider.minLab.rzAlwaysHide).to.be.true + expect(helper.slider.maxLab.rzAlwaysHide).to.be.true + expect(helper.slider.cmbLab.rzAlwaysHide).to.be.true + }) it('should show floor and ceil labels when hidePointerLabels is true', function() { var sliderConf = { @@ -408,13 +551,13 @@ options: { floor: 0, ceil: 100, - hidePointerLabels: true - } - }; - helper.createSlider(sliderConf); - expect(helper.slider.flrLab.css('visibility')).to.equal('visible'); - expect(helper.slider.ceilLab.css('visibility')).to.equal('visible'); - }); + hidePointerLabels: true, + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.flrLab.css('visibility')).to.equal('visible') + expect(helper.slider.ceilLab.css('visibility')).to.equal('visible') + }) it('should show floor and ceil labels when hidePointerLabels is true, for range slider', function() { var sliderConf = { @@ -423,13 +566,13 @@ options: { floor: 0, ceil: 100, - hidePointerLabels: true - } - }; - helper.createRangeSlider(sliderConf); - expect(helper.slider.flrLab.css('visibility')).to.equal('visible'); - expect(helper.slider.ceilLab.css('visibility')).to.equal('visible'); - }); + hidePointerLabels: true, + }, + } + helper.createRangeSlider(sliderConf) + expect(helper.slider.flrLab.css('visibility')).to.equal('visible') + expect(helper.slider.ceilLab.css('visibility')).to.equal('visible') + }) it('should set the correct background-color on selection bar for single slider', function() { var sliderConf = { @@ -439,19 +582,21 @@ ceil: 10, showSelectionBar: true, getSelectionBarColor: function(v) { - if (v < 5) return 'red'; - return 'green'; - } - } - }; - helper.createSlider(sliderConf); - var selBarChild = angular.element(helper.slider.selBar[0].querySelector('.rz-selection')); - expect(selBarChild.css('background-color')).to.equal('green'); - - helper.scope.slider.value = 2; - helper.scope.$digest(); - expect(selBarChild.css('background-color')).to.equal('red'); - }); + if (v < 5) return 'red' + return 'green' + }, + }, + } + helper.createSlider(sliderConf) + var selBarChild = angular.element( + helper.slider.selBar[0].querySelector('.rz-selection') + ) + expect(selBarChild.css('background-color')).to.equal('green') + + helper.scope.slider.value = 2 + helper.scope.$digest() + expect(selBarChild.css('background-color')).to.equal('red') + }) it('should set the correct dimension/position for selection bar for range slider', function() { var sliderConf = { @@ -459,15 +604,24 @@ max: 8, options: { floor: 0, - ceil: 10 - } - }; - helper.createRangeSlider(sliderConf); - var expectedDimension = helper.slider.valueToOffset(6), - expectedPosition = helper.slider.valueToOffset(2) + helper.slider.handleHalfDim; - expect(helper.slider.selBar.css('width')).to.equal(expectedDimension + 'px'); - expect(helper.slider.selBar.css('left')).to.equal(expectedPosition + 'px'); - }); + ceil: 10, + disableAnimation: true, + }, + } + helper.createRangeSlider(sliderConf) + + var expectedDimension = Math.round(helper.slider.valueToPosition(6)), + actualDimension = helper.slider.selBar[0].getBoundingClientRect() + .width + expect(actualDimension).to.equal(expectedDimension) + + var expectedPosition = + Math.round(helper.slider.valueToPosition(2)) + + helper.slider.handleHalfDim + expect(helper.slider.selBar.css('left')).to.equal( + expectedPosition + 'px' + ) + }) it('should set the correct background-color on selection bar for range slider', function() { var sliderConf = { @@ -477,84 +631,90 @@ floor: 0, ceil: 10, getSelectionBarColor: function(min, max) { - if (max - min < 5) return 'red'; - return 'green'; - } - } - }; - helper.createRangeSlider(sliderConf); - var selBarChild = angular.element(helper.slider.selBar[0].querySelector('.rz-selection')); - expect(selBarChild.css('background-color')).to.equal('green'); - - helper.scope.slider.min = 4; - helper.scope.slider.max = 6; - helper.scope.$digest(); - expect(selBarChild.css('background-color')).to.equal('red'); - }); + if (max - min < 5) return 'red' + return 'green' + }, + }, + } + helper.createRangeSlider(sliderConf) + var selBarChild = angular.element( + helper.slider.selBar[0].querySelector('.rz-selection') + ) + expect(selBarChild.css('background-color')).to.equal('green') + + helper.scope.slider.min = 4 + helper.scope.slider.max = 6 + helper.scope.$digest() + expect(selBarChild.css('background-color')).to.equal('red') + }) it('should call the correct callback for onStart', function() { var sliderConf = { value: 10, options: { id: 'test', - onStart: sinon.spy() - } - }; - helper.createSlider(sliderConf); + onStart: sinon.spy(), + }, + } + helper.createSlider(sliderConf) - helper.slider.tracking = 'lowValue'; - helper.slider.callOnStart(); - $timeout.flush(); - sliderConf.options.onStart.calledWith('test', 10, undefined, 'min').should.be.true; - }); + helper.slider.tracking = 'lowValue' + helper.slider.callOnStart() + $timeout.flush() + sliderConf.options.onStart.calledWith('test', 10, undefined, 'min') + .should.be.true + }) it('should call the correct callback for onStart called on high handle', function() { var sliderConf = { value: 10, options: { id: 'test', - onStart: sinon.spy() - } - }; - helper.createSlider(sliderConf); + onStart: sinon.spy(), + }, + } + helper.createSlider(sliderConf) - helper.slider.tracking = 'highValue'; - helper.slider.callOnStart(); - $timeout.flush(); - sliderConf.options.onStart.calledWith('test', 10, undefined, 'max').should.be.true; - }); + helper.slider.tracking = 'highValue' + helper.slider.callOnStart() + $timeout.flush() + sliderConf.options.onStart.calledWith('test', 10, undefined, 'max') + .should.be.true + }) it('should call the correct callback for onChange', function() { var sliderConf = { value: 10, options: { id: 'test', - onChange: sinon.spy() - } - }; - helper.createSlider(sliderConf); + onChange: sinon.spy(), + }, + } + helper.createSlider(sliderConf) - helper.slider.tracking = 'lowValue'; - helper.slider.callOnChange(); - $timeout.flush(); - sliderConf.options.onChange.calledWith('test', 10, undefined, 'min').should.be.true; - }); + helper.slider.tracking = 'lowValue' + helper.slider.callOnChange() + $timeout.flush() + sliderConf.options.onChange.calledWith('test', 10, undefined, 'min') + .should.be.true + }) it('should call the correct callback for onEnd', function() { var sliderConf = { value: 10, options: { id: 'test', - onEnd: sinon.spy() - } - }; - helper.createSlider(sliderConf); + onEnd: sinon.spy(), + }, + } + helper.createSlider(sliderConf) - helper.slider.tracking = 'lowValue'; - helper.slider.callOnEnd(); - $timeout.flush(); - sliderConf.options.onEnd.calledWith('test', 10, undefined, 'min').should.be.true; - }); + helper.slider.tracking = 'lowValue' + helper.slider.callOnEnd() + $timeout.flush() + sliderConf.options.onEnd.calledWith('test', 10, undefined, 'min').should + .be.true + }) it('should set the correct background-color on pointer for single slider', function() { var sliderConf = { @@ -564,19 +724,19 @@ ceil: 10, showSelectionBar: true, getPointerColor: function(v) { - if (v < 5) return 'red'; - return 'green'; - } - } - }; - helper.createSlider(sliderConf); - var minHChild = angular.element(helper.slider.minH[0]); - expect(minHChild.css('background-color')).to.equal('green'); + if (v < 5) return 'red' + return 'green' + }, + }, + } + helper.createSlider(sliderConf) + var minHChild = angular.element(helper.slider.minH[0]) + expect(minHChild.css('background-color')).to.equal('green') - helper.scope.slider.value = 2; - helper.scope.$digest(); - expect(minHChild.css('background-color')).to.equal('red'); - }); + helper.scope.slider.value = 2 + helper.scope.$digest() + expect(minHChild.css('background-color')).to.equal('red') + }) it('should set the correct background-color on pointer for range slider (simple rule)', function() { var sliderConf = { @@ -586,23 +746,23 @@ floor: 0, ceil: 10, getPointerColor: function(v) { - if (v < 5) return 'red'; - return 'green'; - } - } - }; - helper.createRangeSlider(sliderConf); + if (v < 5) return 'red' + return 'green' + }, + }, + } + helper.createRangeSlider(sliderConf) var minHChild = angular.element(helper.slider.minH[0]), - maxHChild = angular.element(helper.slider.maxH[0]); - expect(minHChild.css('background-color')).to.equal('red'); - expect(maxHChild.css('background-color')).to.equal('green'); + maxHChild = angular.element(helper.slider.maxH[0]) + expect(minHChild.css('background-color')).to.equal('red') + expect(maxHChild.css('background-color')).to.equal('green') - helper.scope.slider.min = 6; - helper.scope.slider.max = 7; - helper.scope.$digest(); - expect(minHChild.css('background-color')).to.equal('green'); - expect(maxHChild.css('background-color')).to.equal('green'); - }); + helper.scope.slider.min = 6 + helper.scope.slider.max = 7 + helper.scope.$digest() + expect(minHChild.css('background-color')).to.equal('green') + expect(maxHChild.css('background-color')).to.equal('green') + }) it('should set the correct background-color on pointer for range slider (min/high independent rule 1)', function() { var sliderConf = { @@ -613,27 +773,27 @@ ceil: 10, getPointerColor: function(v, type) { if (type === 'min') { - if (v < 5) return 'red'; - return 'green'; + if (v < 5) return 'red' + return 'green' } if (type === 'max') { - if (v < 5) return 'blue'; - return 'orange'; + if (v < 5) return 'blue' + return 'orange' } - } - } - }; - helper.createRangeSlider(sliderConf); + }, + }, + } + helper.createRangeSlider(sliderConf) var minHChild = angular.element(helper.slider.minH[0]), - maxHChild = angular.element(helper.slider.maxH[0]); - expect(minHChild.css('background-color')).to.equal('red'); - expect(maxHChild.css('background-color')).to.equal('orange'); + maxHChild = angular.element(helper.slider.maxH[0]) + expect(minHChild.css('background-color')).to.equal('red') + expect(maxHChild.css('background-color')).to.equal('orange') - helper.scope.slider.min = 6; - helper.scope.$digest(); - expect(minHChild.css('background-color')).to.equal('green'); - }); + helper.scope.slider.min = 6 + helper.scope.$digest() + expect(minHChild.css('background-color')).to.equal('green') + }) it('should set the correct background-color on pointer for range slider (min/high independent rule 2)', function() { var sliderConf = { @@ -644,29 +804,28 @@ ceil: 10, getPointerColor: function(v, type) { if (type === 'min') { - if (v < 5) return 'red'; - return 'green'; + if (v < 5) return 'red' + return 'green' } if (type === 'max') { - if (v < 5) return 'blue'; - return 'orange'; + if (v < 5) return 'blue' + return 'orange' } - } - } - }; - helper.createRangeSlider(sliderConf); + }, + }, + } + helper.createRangeSlider(sliderConf) var minHChild = angular.element(helper.slider.minH[0]), - maxHChild = angular.element(helper.slider.maxH[0]); - expect(minHChild.css('background-color')).to.equal('red'); - expect(maxHChild.css('background-color')).to.equal('orange'); - - helper.scope.slider.max = 3; - helper.scope.$digest(); - expect(minHChild.css('background-color')).to.equal('red'); - expect(maxHChild.css('background-color')).to.equal('blue'); + maxHChild = angular.element(helper.slider.maxH[0]) + expect(minHChild.css('background-color')).to.equal('red') + expect(maxHChild.css('background-color')).to.equal('orange') - }); + helper.scope.slider.max = 3 + helper.scope.$digest() + expect(minHChild.css('background-color')).to.equal('red') + expect(maxHChild.css('background-color')).to.equal('blue') + }) it('should set the correct background-color on tick', function() { var sliderConf = { @@ -676,18 +835,24 @@ ceil: 10, showTicks: true, getTickColor: function(v) { - if (v < 5) return 'red'; - return 'green'; - } - } - }; - helper.createRangeSlider(sliderConf); - expect(helper.element[0].querySelectorAll('.rz-tick')).to.have.length(11); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[0]); - var lastTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[10]); - expect(firstTick[0].style['background-color']).to.equal('red'); - expect(lastTick[0].style['background-color']).to.equal('green'); - }); + if (v < 5) return 'red' + return 'green' + }, + }, + } + helper.createRangeSlider(sliderConf) + expect(helper.element[0].querySelectorAll('.rz-tick')).to.have.length( + 11 + ) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[0] + ) + var lastTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[10] + ) + expect(firstTick[0].style['background-color']).to.equal('red') + expect(lastTick[0].style['background-color']).to.equal('green') + }) it('should set the correct position for labels for single slider with boundPointerLabels=false', function() { var sliderConf = { @@ -696,20 +861,31 @@ options: { floor: 100000000, ceil: 100001000, - boundPointerLabels: false - } - }; - - helper.createRangeSlider(sliderConf); - expect(helper.slider.minLab.css('left')).to.equal('-' + (helper.slider.minLab.rzsd / 2 - helper.slider.handleHalfDim) + 'px'); - expect(helper.slider.maxLab.css('left')).to.equal((helper.slider.barDimension - (helper.slider.maxLab.rzsd / 2 + helper.slider.handleHalfDim)) + 'px'); - - sliderConf.max = 100000001; - helper.createRangeSlider(sliderConf); - - expect(parseInt(helper.slider.cmbLab.css('left'))).to.be.below(0); - }); - }); + boundPointerLabels: false, + }, + } + + helper.createRangeSlider(sliderConf) + expect(helper.slider.minLab.css('left')).to.equal( + '-' + + Math.round( + helper.slider.minLab.rzsd / 2 - helper.slider.handleHalfDim + ) + + 'px' + ) + expect(helper.slider.maxLab.css('left')).to.equal( + Math.round( + helper.slider.barDimension - + (helper.slider.maxLab.rzsd / 2 + helper.slider.handleHalfDim) + ) + 'px' + ) + + sliderConf.max = 100000001 + helper.createRangeSlider(sliderConf) + + expect(parseInt(helper.slider.cmbLab.css('left'))).to.be.below(0) + }) + }) describe('range slider specific - ', function() { beforeEach(function() { @@ -719,151 +895,151 @@ options: { floor: 0, ceil: 100, - step: 10 - } - }; - helper.createRangeSlider(sliderConf); - }); + step: 10, + }, + } + helper.createRangeSlider(sliderConf) + }) it('should set the correct class to true when draggableRange is true', function() { - helper.scope.slider.options.draggableRange = true; - helper.scope.$digest(); - expect(helper.slider.selBar.hasClass('rz-draggable')).to.be.true; - }); + helper.scope.slider.options.draggableRange = true + helper.scope.$digest() + expect(helper.slider.selBar.hasClass('rz-draggable')).to.be.true + }) it('should set draggableRange to true when draggableRangeOnly is true', function() { - helper.scope.slider.options.draggableRangeOnly = true; - helper.scope.$digest(); - expect(helper.slider.options.draggableRange).to.be.true; - expect(helper.slider.selBar.hasClass('rz-draggable')).to.be.true; - }); + helper.scope.slider.options.draggableRangeOnly = true + helper.scope.$digest() + expect(helper.slider.options.draggableRange).to.be.true + expect(helper.slider.selBar.hasClass('rz-draggable')).to.be.true + }) it('should sanitize rzSliderModel and rzSliderHigh between floor and ceil', function() { - helper.scope.slider.options.enforceRange = true; - helper.scope.slider.min = -1000; - helper.scope.slider.max = 1000; - helper.scope.$digest(); - expect(helper.scope.slider.min).to.equal(0); - expect(helper.scope.slider.max).to.equal(100); - }); + helper.scope.slider.options.enforceRange = true + helper.scope.slider.min = -1000 + helper.scope.slider.max = 1000 + helper.scope.$digest() + expect(helper.scope.slider.min).to.equal(0) + expect(helper.scope.slider.max).to.equal(100) + }) it('should set correct step/floor/ceil and translate function when stepsArray is used with values', function() { - helper.scope.slider.min = 'B'; - helper.scope.slider.max = 'D'; - helper.scope.slider.options.stepsArray = ['A', 'B', 'C', 'D', 'E']; - helper.scope.$digest(); - expect(helper.slider.options.step).to.equal(1); - expect(helper.slider.options.floor).to.equal(0); - expect(helper.slider.options.ceil).to.equal(4); - expect(helper.slider.lowValue).to.equal(1); - expect(helper.slider.highValue).to.equal(3); - }); + helper.scope.slider.min = 'B' + helper.scope.slider.max = 'D' + helper.scope.slider.options.stepsArray = ['A', 'B', 'C', 'D', 'E'] + helper.scope.$digest() + expect(helper.slider.options.step).to.equal(1) + expect(helper.slider.options.floor).to.equal(0) + expect(helper.slider.options.ceil).to.equal(4) + expect(helper.slider.lowValue).to.equal(1) + expect(helper.slider.highValue).to.equal(3) + }) it('should set correct step/floor/ceil and translate function when stepsArray is used with values and bindIndexForStepsArray is true', function() { - helper.scope.slider.min = 1; - helper.scope.slider.max = 3; - helper.scope.slider.options.stepsArray = ['A', 'B', 'C', 'D', 'E']; - helper.scope.slider.options.bindIndexForStepsArray = true; - helper.scope.$digest(); - expect(helper.slider.options.step).to.equal(1); - expect(helper.slider.options.floor).to.equal(0); - expect(helper.slider.options.ceil).to.equal(4); - expect(helper.slider.lowValue).to.equal(1); - expect(helper.slider.highValue).to.equal(3); - }); + helper.scope.slider.min = 1 + helper.scope.slider.max = 3 + helper.scope.slider.options.stepsArray = ['A', 'B', 'C', 'D', 'E'] + helper.scope.slider.options.bindIndexForStepsArray = true + helper.scope.$digest() + expect(helper.slider.options.step).to.equal(1) + expect(helper.slider.options.floor).to.equal(0) + expect(helper.slider.options.ceil).to.equal(4) + expect(helper.slider.lowValue).to.equal(1) + expect(helper.slider.highValue).to.equal(3) + }) it('should set correct step/floor/ceil when stepsArray is used with values and ticks', function() { - helper.scope.slider.min = 'B'; - helper.scope.slider.max = 'D'; - helper.scope.slider.options.stepsArray = ['A', 'B', 'C', 'D', 'E']; - helper.scope.slider.options.showTicks = true; - helper.scope.$digest(); - expect(helper.slider.options.step).to.equal(1); - expect(helper.slider.options.floor).to.equal(0); - expect(helper.slider.options.ceil).to.equal(4); - expect(helper.slider.lowValue).to.equal(1); - expect(helper.slider.highValue).to.equal(3); - }); + helper.scope.slider.min = 'B' + helper.scope.slider.max = 'D' + helper.scope.slider.options.stepsArray = ['A', 'B', 'C', 'D', 'E'] + helper.scope.slider.options.showTicks = true + helper.scope.$digest() + expect(helper.slider.options.step).to.equal(1) + expect(helper.slider.options.floor).to.equal(0) + expect(helper.slider.options.ceil).to.equal(4) + expect(helper.slider.lowValue).to.equal(1) + expect(helper.slider.highValue).to.equal(3) + }) it('should set correct step/floor/ceil when stepsArray is used with values and ticks and bindIndexForStepsArray is true', function() { - helper.scope.slider.min = 1; - helper.scope.slider.max = 3; - helper.scope.slider.options.stepsArray = ['A', 'B', 'C', 'D', 'E']; - helper.scope.slider.options.bindIndexForStepsArray = true; - helper.scope.slider.options.showTicks = true; - helper.scope.$digest(); - expect(helper.slider.options.step).to.equal(1); - expect(helper.slider.options.floor).to.equal(0); - expect(helper.slider.options.ceil).to.equal(4); - expect(helper.slider.lowValue).to.equal(1); - expect(helper.slider.highValue).to.equal(3); - }); + helper.scope.slider.min = 1 + helper.scope.slider.max = 3 + helper.scope.slider.options.stepsArray = ['A', 'B', 'C', 'D', 'E'] + helper.scope.slider.options.bindIndexForStepsArray = true + helper.scope.slider.options.showTicks = true + helper.scope.$digest() + expect(helper.slider.options.step).to.equal(1) + expect(helper.slider.options.floor).to.equal(0) + expect(helper.slider.options.ceil).to.equal(4) + expect(helper.slider.lowValue).to.equal(1) + expect(helper.slider.highValue).to.equal(3) + }) it('should set correct step/floor/ceil when stepsArray is used with objects', function() { - helper.scope.slider.min = 'B'; - helper.scope.slider.max = 'D'; + helper.scope.slider.min = 'B' + helper.scope.slider.max = 'D' helper.scope.slider.options.stepsArray = [ - {value: 'A'}, - {value: 'B'}, - {value: 'C'}, - {value: 'D'}, - {value: 'E'} - ]; - helper.scope.$digest(); - expect(helper.slider.options.step).to.equal(1); - expect(helper.slider.options.floor).to.equal(0); - expect(helper.slider.options.ceil).to.equal(4); - expect(helper.slider.lowValue).to.equal(1); - expect(helper.slider.highValue).to.equal(3); - }); + { value: 'A' }, + { value: 'B' }, + { value: 'C' }, + { value: 'D' }, + { value: 'E' }, + ] + helper.scope.$digest() + expect(helper.slider.options.step).to.equal(1) + expect(helper.slider.options.floor).to.equal(0) + expect(helper.slider.options.ceil).to.equal(4) + expect(helper.slider.lowValue).to.equal(1) + expect(helper.slider.highValue).to.equal(3) + }) it('should set correct step/floor/ceil when stepsArray is used with objects and bindIndexForStepsArray is true', function() { - helper.scope.slider.min = 1; - helper.scope.slider.max = 3; + helper.scope.slider.min = 1 + helper.scope.slider.max = 3 helper.scope.slider.options.stepsArray = [ - {value: 'A'}, - {value: 'B'}, - {value: 'C'}, - {value: 'D'}, - {value: 'E'} - ]; - helper.scope.slider.options.bindIndexForStepsArray = true; - helper.scope.$digest(); - expect(helper.slider.options.step).to.equal(1); - expect(helper.slider.options.floor).to.equal(0); - expect(helper.slider.options.ceil).to.equal(4); - expect(helper.slider.lowValue).to.equal(1); - expect(helper.slider.highValue).to.equal(3); - }); + { value: 'A' }, + { value: 'B' }, + { value: 'C' }, + { value: 'D' }, + { value: 'E' }, + ] + helper.scope.slider.options.bindIndexForStepsArray = true + helper.scope.$digest() + expect(helper.slider.options.step).to.equal(1) + expect(helper.slider.options.floor).to.equal(0) + expect(helper.slider.options.ceil).to.equal(4) + expect(helper.slider.lowValue).to.equal(1) + expect(helper.slider.highValue).to.equal(3) + }) it('should set the correct combined label when range values are the same and mergeRangeLabelsIfSame option is false', function() { - helper.scope.slider.options.mergeRangeLabelsIfSame = false; - helper.scope.slider.min = 50; - helper.scope.slider.max = 50; - helper.scope.$digest(); - expect(helper.slider.cmbLab.text()).to.equal('50 - 50'); - }); + helper.scope.slider.options.mergeRangeLabelsIfSame = false + helper.scope.slider.min = 50 + helper.scope.slider.max = 50 + helper.scope.$digest() + expect(helper.slider.cmbLab.text()).to.equal('50 - 50') + }) it('should set the correct combined label when range values are the same and mergeRangeLabelsIfSame option is true', function() { - helper.scope.slider.options.mergeRangeLabelsIfSame = true; - helper.scope.slider.min = 50; - helper.scope.slider.max = 50; - helper.scope.$digest(); - expect(helper.slider.cmbLab.text()).to.equal('50'); - }); - }); + helper.scope.slider.options.mergeRangeLabelsIfSame = true + helper.scope.slider.min = 50 + helper.scope.slider.max = 50 + helper.scope.$digest() + expect(helper.slider.cmbLab.text()).to.equal('50') + }) + }) describe('options expression specific - ', function() { it('should safely handle null expressions', function() { var sliderConf = { value: 10, - optionsExpression: 'thisDoesntExist' - }; + optionsExpression: 'thisDoesntExist', + } - helper.createSlider(sliderConf); - helper.scope.$digest(); - expect(helper.slider.step).to.equal(1); - }); + helper.createSlider(sliderConf) + helper.scope.$digest() + expect(helper.slider.step).to.equal(1) + }) it('should not cause an infinite $digest loop with an expression that always returns a new object', function() { var sliderConf = { @@ -871,38 +1047,40 @@ options: function() { return { floor: 1, - ceil: 1000 - }; + ceil: 1000, + } }, - optionsExpression: 'slider.options()' - }; + optionsExpression: 'slider.options()', + } - helper.createSlider(sliderConf); - helper.scope.$digest(); - expect(helper.slider.minValue).to.equal(1); - expect(helper.slider.maxValue).to.equal(1000); - }); - }); - }); + helper.createSlider(sliderConf) + helper.scope.$digest() + expect(helper.slider.minValue).to.equal(1) + expect(helper.slider.maxValue).to.equal(1000) + }) + }) + }) describe('Right to left Options handling - ', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) describe('tests with same config', function() { beforeEach(function() { @@ -912,117 +1090,117 @@ floor: 0, ceil: 100, step: 10, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + }) it('horizontal slider should take the full width and get correct position/dimension properties', function() { - helper.scope.$digest(); - expect(helper.element[0].getBoundingClientRect().width).to.equal(1000); - expect(helper.slider.positionProperty).to.equal('left'); - expect(helper.slider.dimensionProperty).to.equal('width'); - expect(helper.slider.sliderElem.hasClass('rz-vertical')).to.be.false; - }); + helper.scope.$digest() + expect(helper.element[0].getBoundingClientRect().width).to.equal(1000) + expect(helper.slider.positionProperty).to.equal('left') + expect(helper.slider.dimensionProperty).to.equal('width') + expect(helper.slider.sliderElem.hasClass('rz-vertical')).to.be.false + }) it('vertical slider should take the full height and get correct position/dimension properties', function() { - helper.scope.$digest(); - helper.scope.slider.options.vertical = true; - helper.scope.$digest(); - expect(helper.element[0].getBoundingClientRect().height).to.equal(1000); - expect(helper.slider.positionProperty).to.equal('bottom'); - expect(helper.slider.dimensionProperty).to.equal('height'); - expect(helper.slider.sliderElem.hasClass('rz-vertical')).to.be.true; - }); + helper.scope.$digest() + helper.scope.slider.options.vertical = true + helper.scope.$digest() + expect(helper.element[0].getBoundingClientRect().height).to.equal(1000) + expect(helper.slider.positionProperty).to.equal('bottom') + expect(helper.slider.dimensionProperty).to.equal('height') + expect(helper.slider.sliderElem.hasClass('rz-vertical')).to.be.true + }) it('should prevent invalid step', function() { - helper.scope.slider.options.step = 0; - helper.scope.$digest(); - expect(helper.slider.options.step).to.equal(1); + helper.scope.slider.options.step = 0 + helper.scope.$digest() + expect(helper.slider.options.step).to.equal(1) - helper.scope.slider.options.step = -1; - helper.scope.$digest(); - expect(helper.slider.options.step).to.equal(1); - }); + helper.scope.slider.options.step = -1 + helper.scope.$digest() + expect(helper.slider.options.step).to.equal(1) + }) it('should not round value to step if enforceStep is false', function() { - helper.scope.slider.options.enforceStep = false; - helper.scope.$digest(); + helper.scope.slider.options.enforceStep = false + helper.scope.$digest() - helper.scope.slider.value = 14; - helper.scope.$digest(); - expect(helper.scope.slider.value).to.equal(14); - }); + helper.scope.slider.value = 14 + helper.scope.$digest() + expect(helper.scope.slider.value).to.equal(14) + }) it('should round value to step if enforceStep is true', function() { - helper.scope.slider.options.enforceStep = true; - helper.scope.$digest(); + helper.scope.slider.options.enforceStep = true + helper.scope.$digest() - helper.scope.slider.value = 14; - helper.scope.$digest(); - expect(helper.scope.slider.value).to.equal(10); - }); + helper.scope.slider.value = 14 + helper.scope.$digest() + expect(helper.scope.slider.value).to.equal(10) + }) it('should set the showTicks scope flag to true when showTicks is true', function() { - helper.scope.slider.options.showTicks = true; - helper.scope.$digest(); - expect(helper.slider.scope.showTicks).to.be.true; - }); + helper.scope.slider.options.showTicks = true + helper.scope.$digest() + expect(helper.slider.scope.showTicks).to.be.true + }) it('should set the showTicks scope flag to true when showTicksValues is true', function() { - helper.scope.slider.options.showTicksValues = true; - helper.scope.$digest(); - expect(helper.slider.scope.showTicks).to.be.true; - }); + helper.scope.slider.options.showTicksValues = true + helper.scope.$digest() + expect(helper.slider.scope.showTicks).to.be.true + }) it('should set the intermediateTicks flag to true when showTicks is an integer', function() { - helper.scope.slider.options.showTicks = 10; - helper.scope.$digest(); - expect(helper.slider.intermediateTicks).to.be.true; - }); + helper.scope.slider.options.showTicks = 10 + helper.scope.$digest() + expect(helper.slider.intermediateTicks).to.be.true + }) it('should set the intermediateTicks flag to true when showTicksValues is an integer', function() { - helper.scope.slider.options.showTicksValues = 10; - helper.scope.$digest(); - expect(helper.slider.intermediateTicks).to.be.true; - }); + helper.scope.slider.options.showTicksValues = 10 + helper.scope.$digest() + expect(helper.slider.intermediateTicks).to.be.true + }) it('should set not accept draggableRange to true when slider is a single one', function() { - helper.scope.slider.options.draggableRange = true; - helper.scope.$digest(); - expect(helper.slider.options.draggableRange).to.be.false; - }); + helper.scope.slider.options.draggableRange = true + helper.scope.$digest() + expect(helper.slider.options.draggableRange).to.be.false + }) it('should set not accept draggableRangeOnly to true when slider is a single one', function() { - helper.scope.slider.options.draggableRangeOnly = true; - helper.scope.$digest(); - expect(helper.slider.options.draggableRange).to.be.false; - expect(helper.slider.options.draggableRangeOnly).to.be.false; - }); + helper.scope.slider.options.draggableRangeOnly = true + helper.scope.$digest() + expect(helper.slider.options.draggableRange).to.be.false + expect(helper.slider.options.draggableRangeOnly).to.be.false + }) it('should set correct step/floor/ceil and translate function when stepsArray is used', function() { - helper.scope.slider.value = 'C'; - helper.scope.slider.options.stepsArray = ['A', 'B', 'C', 'D', 'E']; - helper.scope.$digest(); - expect(helper.slider.options.step).to.equal(1); - expect(helper.slider.options.floor).to.equal(0); - expect(helper.slider.options.ceil).to.equal(4); - expect(helper.slider.lowValue).to.equal(2); - }); + helper.scope.slider.value = 'C' + helper.scope.slider.options.stepsArray = ['A', 'B', 'C', 'D', 'E'] + helper.scope.$digest() + expect(helper.slider.options.step).to.equal(1) + expect(helper.slider.options.floor).to.equal(0) + expect(helper.slider.options.ceil).to.equal(4) + expect(helper.slider.lowValue).to.equal(2) + }) it('should sanitize rzSliderModel between floor and ceil', function() { - helper.scope.slider.options.enforceRange = true; - helper.scope.slider.value = 1000; - helper.scope.$digest(); - expect(helper.scope.slider.value).to.equal(100); - - helper.scope.slider.value = -1000; - helper.scope.$digest(); - $timeout.flush(); //to flush the throttle function - expect(helper.scope.slider.value).to.equal(0); - }); - }); + helper.scope.slider.options.enforceRange = true + helper.scope.slider.value = 1000 + helper.scope.$digest() + expect(helper.scope.slider.value).to.equal(100) + + helper.scope.slider.value = -1000 + helper.scope.$digest() + $timeout.flush() //to flush the throttle function + expect(helper.scope.slider.value).to.equal(0) + }) + }) describe('tests with specific config', function() { it('should accept custom translate function', function() { @@ -1033,34 +1211,34 @@ ceil: 100, step: 10, translate: function(v) { - return 'custom value'; + return 'custom value' }, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - expect(helper.slider.customTrFn(0)).to.equal('custom value'); - expect(helper.slider.customTrFn(100)).to.equal('custom value'); - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.customTrFn(0)).to.equal('custom value') + expect(helper.slider.customTrFn(100)).to.equal('custom value') + }) it('should set maxValue to rzSliderModel if no ceil is set for a single slider', function() { var sliderConf = { value: 10, - rightToLeft: true - }; - helper.createSlider(sliderConf); - expect(helper.slider.maxValue).to.equal(10); - }); + rightToLeft: true, + } + helper.createSlider(sliderConf) + expect(helper.slider.maxValue).to.equal(10) + }) it('should set maxValue to rzSliderHigh if no ceil is set for a range slider', function() { var sliderConf = { min: 10, max: 100, - rightToLeft: true - }; - helper.createRangeSlider(sliderConf); - expect(helper.slider.maxValue).to.equal(100); - }); + rightToLeft: true, + } + helper.createRangeSlider(sliderConf) + expect(helper.slider.maxValue).to.equal(100) + }) it('should set the correct dimension/position for selection bar for single slider with showSelectionBar=true', function() { var sliderConf = { @@ -1069,15 +1247,24 @@ floor: 0, ceil: 10, showSelectionBar: true, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - var expectedDimension = Math.floor(helper.slider.valueToOffset(8) + helper.slider.handleHalfDim), - actualDimension = Math.floor(helper.slider.selBar[0].getBoundingClientRect().width); - expect(actualDimension).to.equal(expectedDimension); - expect(helper.slider.selBar.css('left')).to.equal(helper.slider.valueToOffset(2) + helper.slider.handleHalfDim + 'px'); - }); + rightToLeft: true, + disableAnimation: true, + }, + } + helper.createSlider(sliderConf) + var expectedDimension = Math.round( + helper.slider.valueToPosition(8) + helper.slider.handleHalfDim + ), + actualDimension = Math.round( + helper.slider.selBar[0].getBoundingClientRect().width + ) + expect(actualDimension).to.equal(expectedDimension) + expect(helper.slider.selBar.css('left')).to.equal( + Math.round(helper.slider.valueToPosition(2)) + + helper.slider.handleHalfDim + + 'px' + ) + }) it('should set the correct dimension/position for selection bar for single slider with showSelectionBarEnd=true', function() { var sliderConf = { @@ -1086,14 +1273,20 @@ floor: 0, ceil: 10, showSelectionBarEnd: true, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - var expectedDimension = helper.slider.valueToOffset(2) + helper.slider.handleHalfDim; - expect(helper.slider.selBar.css('width')).to.equal(expectedDimension + 'px'); - expect(helper.slider.selBar.css('left')).to.equal('0px'); - }); + rightToLeft: true, + disableAnimation: true, + }, + } + helper.createSlider(sliderConf) + var expectedDimension = Math.floor( + helper.slider.valueToPosition(2) + helper.slider.handleHalfDim + ), + actualDimension = Math.floor( + helper.slider.selBar[0].getBoundingClientRect().width + ) + expect(actualDimension).to.equal(expectedDimension) + expect(helper.slider.selBar.css('left')).to.equal('0px') + }) it('should set the correct dimension/position for selection bar for single slider with showSelectionBarFromValue is used with a value on the left', function() { var sliderConf = { @@ -1102,15 +1295,21 @@ floor: 0, ceil: 20, showSelectionBarFromValue: 10, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - var expectedDimension = helper.slider.valueToOffset(15), - expectedPosition = helper.slider.valueToOffset(15) + helper.slider.handleHalfDim; - expect(helper.slider.selBar.css('width')).to.equal(expectedDimension + 'px'); - expect(helper.slider.selBar.css('left')).to.equal(expectedPosition + 'px'); - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + var expectedDimension = Math.round(helper.slider.valueToPosition(15)), + expectedPosition = + Math.round(helper.slider.valueToPosition(15)) + + helper.slider.handleHalfDim + expect(helper.slider.selBar.css('width')).to.equal( + expectedDimension + 'px' + ) + expect(helper.slider.selBar.css('left')).to.equal( + expectedPosition + 'px' + ) + }) it('should set the correct dimension/position for selection bar for single slider with showSelectionBarFromValue is used with a value on the right', function() { var sliderConf = { @@ -1119,16 +1318,22 @@ floor: 0, ceil: 20, showSelectionBarFromValue: 10, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - var expectedDimension = Math.floor(helper.slider.valueToOffset(13)), - actualDimension = Math.floor(helper.slider.selBar[0].getBoundingClientRect().width), - expectedPosition = helper.slider.valueToOffset(10) + helper.slider.handleHalfDim; - expect(actualDimension).to.equal(expectedDimension); - expect(helper.slider.selBar.css('left')).to.equal(expectedPosition + 'px'); - }); + rightToLeft: true, + disableAnimation: true, + }, + } + helper.createSlider(sliderConf) + var expectedDimension = Math.round(helper.slider.valueToPosition(13)), + actualDimension = helper.slider.selBar[0].getBoundingClientRect() + .width, + expectedPosition = + Math.round(helper.slider.valueToPosition(10)) + + helper.slider.handleHalfDim + expect(actualDimension).to.equal(expectedDimension) + expect(helper.slider.selBar.css('left')).to.equal( + expectedPosition + 'px' + ) + }) it('should set the correct background-color on selection bar for single slider', function() { var sliderConf = { @@ -1138,20 +1343,22 @@ ceil: 10, showSelectionBar: true, getSelectionBarColor: function(v) { - if (v < 5) return 'red'; - return 'green'; + if (v < 5) return 'red' + return 'green' }, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - var selBarChild = angular.element(helper.slider.selBar[0].querySelector('.rz-selection')); - expect(selBarChild.css('background-color')).to.equal('green'); - - helper.scope.slider.value = 2; - helper.scope.$digest(); - expect(selBarChild.css('background-color')).to.equal('red'); - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + var selBarChild = angular.element( + helper.slider.selBar[0].querySelector('.rz-selection') + ) + expect(selBarChild.css('background-color')).to.equal('green') + + helper.scope.slider.value = 2 + helper.scope.$digest() + expect(selBarChild.css('background-color')).to.equal('red') + }) it('should set the correct dimension/position for selection bar for range slider', function() { var sliderConf = { @@ -1159,16 +1366,25 @@ max: 8, options: { floor: 0, - ceil: 10 + ceil: 10, + disableAnimation: true, }, - rightToLeft: true - }; - helper.createRangeSlider(sliderConf); - var expectedDimension = helper.slider.valueToOffset(6), - expectedPosition = helper.slider.valueToOffset(2) + helper.slider.handleHalfDim; - expect(helper.slider.selBar.css('width')).to.equal(expectedDimension + 'px'); - expect(helper.slider.selBar.css('left')).to.equal(expectedPosition + 'px'); - }); + rightToLeft: true, + } + helper.createRangeSlider(sliderConf) + + var expectedDimension = Math.round(helper.slider.valueToPosition(6)), + actualDimension = helper.slider.selBar[0].getBoundingClientRect() + .width + expect(actualDimension).to.equal(expectedDimension) + + var expectedPosition = + Math.round(helper.slider.valueToPosition(2)) + + helper.slider.handleHalfDim + expect(helper.slider.selBar.css('left')).to.equal( + expectedPosition + 'px' + ) + }) it('should set the correct background-color on selection bar for range slider', function() { var sliderConf = { @@ -1178,21 +1394,23 @@ floor: 0, ceil: 10, getSelectionBarColor: function(min, max) { - if (max - min < 5) return 'red'; - return 'green'; + if (max - min < 5) return 'red' + return 'green' }, - rightToLeft: true - } - }; - helper.createRangeSlider(sliderConf); - var selBarChild = angular.element(helper.slider.selBar[0].querySelector('.rz-selection')); - expect(selBarChild.css('background-color')).to.equal('green'); - - helper.scope.slider.min = 4; - helper.scope.slider.max = 6; - helper.scope.$digest(); - expect(selBarChild.css('background-color')).to.equal('red'); - }); + rightToLeft: true, + }, + } + helper.createRangeSlider(sliderConf) + var selBarChild = angular.element( + helper.slider.selBar[0].querySelector('.rz-selection') + ) + expect(selBarChild.css('background-color')).to.equal('green') + + helper.scope.slider.min = 4 + helper.scope.slider.max = 6 + helper.scope.$digest() + expect(selBarChild.css('background-color')).to.equal('red') + }) it('should call the correct callback for onStart', function() { var sliderConf = { @@ -1200,15 +1418,15 @@ options: { id: 'test', onStart: sinon.spy(), - rightToLeft: true - } - }; - helper.createSlider(sliderConf); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) - helper.slider.callOnStart(); - $timeout.flush(); - sliderConf.options.onStart.calledWith('test').should.be.true; - }); + helper.slider.callOnStart() + $timeout.flush() + sliderConf.options.onStart.calledWith('test').should.be.true + }) it('should call the correct callback for onChange', function() { var sliderConf = { @@ -1216,15 +1434,15 @@ options: { id: 'test', onChange: sinon.spy(), - rightToLeft: true - } - }; - helper.createSlider(sliderConf); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) - helper.slider.callOnChange(); - $timeout.flush(); - sliderConf.options.onChange.calledWith('test').should.be.true; - }); + helper.slider.callOnChange() + $timeout.flush() + sliderConf.options.onChange.calledWith('test').should.be.true + }) it('should call the correct callback for onEnd', function() { var sliderConf = { @@ -1232,15 +1450,15 @@ options: { id: 'test', onEnd: sinon.spy(), - rightToLeft: true - } - }; - helper.createSlider(sliderConf); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) - helper.slider.callOnEnd(); - $timeout.flush(); - sliderConf.options.onEnd.calledWith('test').should.be.true; - }); + helper.slider.callOnEnd() + $timeout.flush() + sliderConf.options.onEnd.calledWith('test').should.be.true + }) it('should set the correct background-color on pointer for single slider', function() { var sliderConf = { @@ -1250,20 +1468,20 @@ ceil: 10, showSelectionBar: true, getPointerColor: function(v) { - if (v < 5) return 'red'; - return 'green'; + if (v < 5) return 'red' + return 'green' }, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - var minHChild = angular.element(helper.slider.minH[0]); - expect(minHChild.css('background-color')).to.equal('green'); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + var minHChild = angular.element(helper.slider.minH[0]) + expect(minHChild.css('background-color')).to.equal('green') - helper.scope.slider.value = 2; - helper.scope.$digest(); - expect(minHChild.css('background-color')).to.equal('red'); - }); + helper.scope.slider.value = 2 + helper.scope.$digest() + expect(minHChild.css('background-color')).to.equal('red') + }) it('should set the correct background-color on pointer for range slider (simple rule)', function() { var sliderConf = { @@ -1273,24 +1491,24 @@ floor: 0, ceil: 10, getPointerColor: function(v) { - if (v < 5) return 'red'; - return 'green'; + if (v < 5) return 'red' + return 'green' }, - rightToLeft: true - } - }; - helper.createRangeSlider(sliderConf); + rightToLeft: true, + }, + } + helper.createRangeSlider(sliderConf) var minHChild = angular.element(helper.slider.minH[0]), - maxHChild = angular.element(helper.slider.maxH[0]); - expect(minHChild.css('background-color')).to.equal('red'); - expect(maxHChild.css('background-color')).to.equal('green'); + maxHChild = angular.element(helper.slider.maxH[0]) + expect(minHChild.css('background-color')).to.equal('red') + expect(maxHChild.css('background-color')).to.equal('green') - helper.scope.slider.min = 6; - helper.scope.slider.max = 7; - helper.scope.$digest(); - expect(minHChild.css('background-color')).to.equal('green'); - expect(maxHChild.css('background-color')).to.equal('green'); - }); + helper.scope.slider.min = 6 + helper.scope.slider.max = 7 + helper.scope.$digest() + expect(minHChild.css('background-color')).to.equal('green') + expect(maxHChild.css('background-color')).to.equal('green') + }) it('should set the correct background-color on pointer for range slider (min/high independent rule 1)', function() { var sliderConf = { @@ -1301,28 +1519,28 @@ ceil: 10, getPointerColor: function(v, type) { if (type === 'min') { - if (v < 5) return 'red'; - return 'green'; + if (v < 5) return 'red' + return 'green' } if (type === 'max') { - if (v < 5) return 'blue'; - return 'orange'; + if (v < 5) return 'blue' + return 'orange' } }, - rightToLeft: true - } - }; - helper.createRangeSlider(sliderConf); + rightToLeft: true, + }, + } + helper.createRangeSlider(sliderConf) var minHChild = angular.element(helper.slider.minH[0]), - maxHChild = angular.element(helper.slider.maxH[0]); - expect(minHChild.css('background-color')).to.equal('red'); - expect(maxHChild.css('background-color')).to.equal('orange'); + maxHChild = angular.element(helper.slider.maxH[0]) + expect(minHChild.css('background-color')).to.equal('red') + expect(maxHChild.css('background-color')).to.equal('orange') - helper.scope.slider.min = 6; - helper.scope.$digest(); - expect(minHChild.css('background-color')).to.equal('green'); - }); + helper.scope.slider.min = 6 + helper.scope.$digest() + expect(minHChild.css('background-color')).to.equal('green') + }) it('should set the correct background-color on pointer for range slider (min/high independent rule 2)', function() { var sliderConf = { @@ -1333,30 +1551,29 @@ ceil: 10, getPointerColor: function(v, type) { if (type === 'min') { - if (v < 5) return 'red'; - return 'green'; + if (v < 5) return 'red' + return 'green' } if (type === 'max') { - if (v < 5) return 'blue'; - return 'orange'; + if (v < 5) return 'blue' + return 'orange' } }, - rightToLeft: true - } - }; - helper.createRangeSlider(sliderConf); + rightToLeft: true, + }, + } + helper.createRangeSlider(sliderConf) var minHChild = angular.element(helper.slider.minH[0]), - maxHChild = angular.element(helper.slider.maxH[0]); - expect(minHChild.css('background-color')).to.equal('red'); - expect(maxHChild.css('background-color')).to.equal('orange'); - - helper.scope.slider.max = 3; - helper.scope.$digest(); - expect(minHChild.css('background-color')).to.equal('red'); - expect(maxHChild.css('background-color')).to.equal('blue'); + maxHChild = angular.element(helper.slider.maxH[0]) + expect(minHChild.css('background-color')).to.equal('red') + expect(maxHChild.css('background-color')).to.equal('orange') - }); + helper.scope.slider.max = 3 + helper.scope.$digest() + expect(minHChild.css('background-color')).to.equal('red') + expect(maxHChild.css('background-color')).to.equal('blue') + }) it('should correctly link the customTemplateScope properties on slider scope', function() { var sliderConf = { @@ -1364,15 +1581,15 @@ options: { customTemplateScope: { a: 1, - b: 'test' - } - } - }; - helper.createSlider(sliderConf); + b: 'test', + }, + }, + } + helper.createSlider(sliderConf) expect(helper.slider.scope.custom.a).to.equal(1) expect(helper.slider.scope.custom.b).to.equal('test') - }); - }); + }) + }) describe('range slider specific - ', function() { beforeEach(function() { @@ -1383,46 +1600,113 @@ floor: 0, ceil: 100, step: 10, - rightToLeft: true - } - }; - helper.createRangeSlider(sliderConf); - }); + rightToLeft: true, + }, + } + helper.createRangeSlider(sliderConf) + }) it('should set the correct class to true when draggableRange is true', function() { - helper.scope.slider.options.draggableRange = true; - helper.scope.$digest(); - expect(helper.slider.selBar.hasClass('rz-draggable')).to.be.true; - }); + helper.scope.slider.options.draggableRange = true + helper.scope.$digest() + expect(helper.slider.selBar.hasClass('rz-draggable')).to.be.true + }) it('should set draggableRange to true when draggableRangeOnly is true', function() { - helper.scope.slider.options.draggableRangeOnly = true; - helper.scope.$digest(); - expect(helper.slider.options.draggableRange).to.be.true; - expect(helper.slider.selBar.hasClass('rz-draggable')).to.be.true; - }); + helper.scope.slider.options.draggableRangeOnly = true + helper.scope.$digest() + expect(helper.slider.options.draggableRange).to.be.true + expect(helper.slider.selBar.hasClass('rz-draggable')).to.be.true + }) it('should sanitize rzSliderModel and rzSliderHigh between floor and ceil', function() { - helper.scope.slider.options.enforceRange = true; - helper.scope.slider.min = -1000; - helper.scope.slider.max = 1000; - helper.scope.$digest(); - expect(helper.scope.slider.min).to.equal(0); - expect(helper.scope.slider.max).to.equal(100); - }); - }); + helper.scope.slider.options.enforceRange = true + helper.scope.slider.min = -1000 + helper.scope.slider.max = 1000 + helper.scope.$digest() + expect(helper.scope.slider.min).to.equal(0) + expect(helper.scope.slider.max).to.equal(100) + }) + + it('should visualize left/right outer selection', function() { + helper.scope.slider.min = 30 + helper.scope.slider.max = 70 + helper.scope.slider.options.showOuterSelectionBars = true + helper.scope.slider.options.rightToLeft = false + helper.scope.$digest() + expect(helper.slider.leftOutSelBar.css('visibility')).to.equal( + 'visible' + ) + expect(helper.slider.rightOutSelBar.css('visibility')).to.equal( + 'visible' + ) + expect(helper.slider.fullBar.hasClass('rz-transparent')).to.be.true + }) + + it('should swap left/right outer selection in rightToLeft mode', function() { + helper.scope.slider.min = 30 + helper.scope.slider.max = 70 + helper.scope.slider.options.showOuterSelectionBars = true + helper.scope.slider.options.rightToLeft = true + helper.scope.$digest() + expect(helper.slider.leftOutSelBar.css('visibility')).to.equal( + 'visible' + ) + expect(helper.slider.rightOutSelBar.css('visibility')).to.equal( + 'visible' + ) + expect(helper.slider.fullBar.hasClass('rz-transparent')).to.be.true + // rightToLeft checking + expect(parseInt(helper.slider.rightOutSelBar.css('left'))).to.be.below( + parseInt(helper.slider.leftOutSelBar.css('left')) + ) + }) + + it('should use the default separator when labels overlap', function() { + helper.scope.slider.min = -1 + helper.scope.slider.max = 1 + helper.scope.slider.options.floor = -100 + helper.scope.slider.options.ceil = +100 + helper.scope.slider.options.step = 1 + helper.scope.slider.options.rightToLeft = false + helper.scope.$digest() + expect(helper.slider.cmbLab.text()).to.equal('-1 - 1') + }) + + it('should use the custom separator when labels overlap, and labelOverlapSeparator is set', function() { + helper.scope.slider.min = -1 + helper.scope.slider.max = 1 + helper.scope.slider.options.floor = -100 + helper.scope.slider.options.ceil = +100 + helper.scope.slider.options.step = 1 + helper.scope.slider.options.rightToLeft = false + helper.scope.slider.options.labelOverlapSeparator = ' .. ' + helper.scope.$digest() + expect(helper.slider.cmbLab.text()).to.equal('-1 .. 1') + }) + it('should use the custom separator when labels overlap, and labelOverlapSeparator is set, in RTL mode', function() { + helper.scope.slider.min = -1 + helper.scope.slider.max = 1 + helper.scope.slider.options.floor = -100 + helper.scope.slider.options.ceil = +100 + helper.scope.slider.options.step = 1 + helper.scope.slider.options.labelOverlapSeparator = ' .. ' + helper.scope.$digest() + expect(helper.slider.cmbLab.text()).to.equal('1 .. -1') + }) + }) describe('options expression specific - ', function() { it('should safely handle null expressions', function() { var sliderConf = { value: 10, - optionsExpression: 'thisDoesntExist' - }; + optionsExpression: 'thisDoesntExist', + } - helper.createSlider(sliderConf); - helper.scope.$digest(); - expect(helper.slider.step).to.equal(1); - }); + helper.createSlider(sliderConf) + helper.scope.$digest() + expect(helper.slider.step).to.equal(1) + }) it('should not cause an infinite $digest loop with an expression that always returns a new object', function() { var sliderConf = { @@ -1430,18 +1714,42 @@ options: function() { return { floor: 1, - ceil: 1000 - }; + ceil: 1000, + } + }, + optionsExpression: 'slider.options()', + } + + helper.createSlider(sliderConf) + helper.scope.$digest() + expect(helper.slider.minValue).to.equal(1) + expect(helper.slider.maxValue).to.equal(1000) + }) + }) + + describe('reacting to changes - ', function() { + beforeEach(function() { + var sliderConf = { + value: 10, + options: { + floor: 0, + ceil: 100, + step: 10, + translate: function(val) { + return val + '%' + }, }, - optionsExpression: 'slider.options()' - }; - - helper.createSlider(sliderConf); - helper.scope.$digest(); - expect(helper.slider.minValue).to.equal(1); - expect(helper.slider.maxValue).to.equal(1000); - }); - }); - }); - -}()); + } + helper.createSlider(sliderConf) + }) + + it('should react to changes of options which are functions', function() { + helper.scope.slider.options.translate = function(val) { + return val + '$' + } + helper.scope.$digest() + expect(helper.slider.customTrFn(100)).to.equal('100$') + }) + }) + }) +})() diff --git a/tests/specs/range-slider-init-test.js b/tests/specs/range-slider-init-test.js index 5ddee72..1d201dd 100644 --- a/tests/specs/range-slider-init-test.js +++ b/tests/specs/range-slider-init-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Range slider initialisation - ', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; + var helper, RzSliderOptions, $rootScope, $timeout - beforeEach(module('test-helper')); + beforeEach(module('test-helper')) - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -27,78 +29,77 @@ options: { floor: 0, ceil: 100, - step: 10 - } - }; - helper.createRangeSlider(sliderConf); - }); + step: 10, + }, + } + helper.createRangeSlider(sliderConf) + }) it('should exist compiled and with correct config', function() { - expect(helper.element.find('span')).to.have.length(11); - expect(helper.slider.range).to.be.true; - expect(helper.slider.valueRange).to.equal(100); - expect(helper.slider.maxH.css('display')).to.equal(''); - }); + expect(helper.element.find('span')).to.have.length(17) + expect(helper.slider.range).to.be.true + expect(helper.slider.valueRange).to.equal(100) + expect(helper.slider.maxH.css('display')).to.equal('') + }) it('should watch rzSliderHigh and reflow the slider accordingly', function() { - sinon.spy(helper.slider, 'onHighHandleChange'); - helper.scope.slider.max = 95; - helper.scope.$digest(); - helper.slider.onHighHandleChange.called.should.be.true; - }); + sinon.spy(helper.slider, 'onHighHandleChange') + helper.scope.slider.max = 95 + helper.scope.$digest() + helper.slider.onHighHandleChange.called.should.be.true + }) it('should switch to a single slider when rzSliderHigh is unset after init', function() { - sinon.spy(helper.slider, 'onHighHandleChange'); - sinon.spy(helper.slider, 'applyOptions'); - sinon.spy(helper.slider, 'resetSlider'); - helper.scope.slider.max = undefined; - helper.scope.$digest(); - helper.slider.onHighHandleChange.called.should.be.false; - helper.slider.applyOptions.called.should.be.true; - helper.slider.resetSlider.called.should.be.true; - }); + sinon.spy(helper.slider, 'onHighHandleChange') + sinon.spy(helper.slider, 'applyOptions') + sinon.spy(helper.slider, 'resetSlider') + helper.scope.slider.max = undefined + helper.scope.$digest() + helper.slider.onHighHandleChange.called.should.be.false + helper.slider.applyOptions.called.should.be.true + helper.slider.resetSlider.called.should.be.true + }) it('should switch to a range slider when rzSliderHigh is set after init', function() { - helper.scope.slider.max = undefined; - helper.scope.$digest(); - sinon.spy(helper.slider, 'onHighHandleChange'); - sinon.spy(helper.slider, 'applyOptions'); - sinon.spy(helper.slider, 'resetSlider'); - helper.scope.slider.max = 100; - helper.scope.$digest(); - helper.slider.onHighHandleChange.called.should.be.true; - helper.slider.applyOptions.called.should.be.true; - helper.slider.resetSlider.called.should.be.true; - }); + helper.scope.slider.max = undefined + helper.scope.$digest() + sinon.spy(helper.slider, 'onHighHandleChange') + sinon.spy(helper.slider, 'applyOptions') + sinon.spy(helper.slider, 'resetSlider') + helper.scope.slider.max = 100 + helper.scope.$digest() + helper.slider.onHighHandleChange.called.should.be.true + helper.slider.applyOptions.called.should.be.true + helper.slider.resetSlider.called.should.be.true + }) it('should round the model value to the step', function() { - helper.scope.slider.min = 23; - helper.scope.slider.max = 84; - helper.scope.$digest(); - expect(helper.scope.slider.min).to.equal(20); - expect(helper.scope.slider.max).to.equal(80); + helper.scope.slider.min = 23 + helper.scope.slider.max = 84 + helper.scope.$digest() + expect(helper.scope.slider.min).to.equal(20) + expect(helper.scope.slider.max).to.equal(80) - helper.scope.slider.min = 25; - helper.scope.slider.max = 95; - helper.scope.$digest(); - $timeout.flush(); //to flush the throttle function - expect(helper.scope.slider.min).to.equal(30); - expect(helper.scope.slider.max).to.equal(100); - }); + helper.scope.slider.min = 25 + helper.scope.slider.max = 95 + helper.scope.$digest() + $timeout.flush() //to flush the throttle function + expect(helper.scope.slider.min).to.equal(30) + expect(helper.scope.slider.max).to.equal(100) + }) it('should reset everything on rzSliderForceRender', function() { - sinon.spy(helper.slider, 'resetLabelsValue'); - sinon.spy(helper.slider, 'resetSlider'); - sinon.spy(helper.slider, 'onLowHandleChange'); - sinon.spy(helper.slider, 'onHighHandleChange'); + sinon.spy(helper.slider, 'resetLabelsValue') + sinon.spy(helper.slider, 'resetSlider') + sinon.spy(helper.slider, 'onLowHandleChange') + sinon.spy(helper.slider, 'onHighHandleChange') - helper.scope.$broadcast('rzSliderForceRender'); - - helper.slider.resetLabelsValue.called.should.be.true; - helper.slider.resetSlider.called.should.be.true; - helper.slider.onLowHandleChange.called.should.be.true; - helper.slider.onHighHandleChange.called.should.be.true; - }); - }); -}()); + helper.scope.$broadcast('rzSliderForceRender') + helper.slider.resetLabelsValue.called.should.be.true + helper.slider.resetSlider.called.should.be.true + helper.slider.onLowHandleChange.called.should.be.true + helper.slider.onHighHandleChange.called.should.be.true + }) + }) +})() diff --git a/tests/specs/rz-slider-options-test.js b/tests/specs/rz-slider-options-test.js index f90d2f1..03dafb4 100644 --- a/tests/specs/rz-slider-options-test.js +++ b/tests/specs/rz-slider-options-test.js @@ -1,48 +1,48 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('RzSliderOptions - ', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) it('should have a correct getOptions method that apply custom options', function() { - var defaultOpts = RzSliderOptions.getOptions(); + var defaultOpts = RzSliderOptions.getOptions() var customOpts = { - showTicks: true - }; + showTicks: true, + } - var expectedOpts = angular.extend({}, defaultOpts, customOpts); - var options = RzSliderOptions.getOptions(customOpts); - expect(options).to.deep.equal(expectedOpts); - }); + var expectedOpts = angular.extend({}, defaultOpts, customOpts) + var options = RzSliderOptions.getOptions(customOpts) + expect(options).to.deep.equal(expectedOpts) + }) it('should have a correct options method to update the global options', function() { - - var defaultOpts = RzSliderOptions.getOptions(); + var defaultOpts = RzSliderOptions.getOptions() var globalOpts = { - showTicks: true - }; - RzSliderOptions.options(globalOpts); - - var expectedOpts = angular.extend({}, defaultOpts, globalOpts); - var options = RzSliderOptions.getOptions(); - expect(options).to.deep.equal(expectedOpts); - }); - }); -}()); - + showTicks: true, + } + RzSliderOptions.options(globalOpts) + + var expectedOpts = angular.extend({}, defaultOpts, globalOpts) + var options = RzSliderOptions.getOptions() + expect(options).to.deep.equal(expectedOpts) + }) + }) +})() diff --git a/tests/specs/scale-test.js b/tests/specs/scale-test.js new file mode 100644 index 0000000..e1824de --- /dev/null +++ b/tests/specs/scale-test.js @@ -0,0 +1,158 @@ +;(function() { + 'use strict' + + describe('Scale test - ', function() { + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) + + afterEach(function() { + helper.clean() + }) + + describe('Linear scale - ', function() { + beforeEach(function() { + var sliderConf = { + value: 10, + options: { + floor: 0, + ceil: 100, + step: 10, + }, + } + helper.createSlider(sliderConf) + }) + + it('should have a correct linearValueToPosition', function() { + var actual = helper.slider.linearValueToPosition(0, 0, 50) + expect(actual).to.equal(0) + actual = helper.slider.linearValueToPosition(25, 0, 50) + expect(actual.toFixed(2)).to.equal('0.50') + actual = helper.slider.linearValueToPosition(50, 0, 50) + expect(actual).to.equal(1) + }) + + it('should have a correct linearPositionToValue', function() { + var actual = helper.slider.linearPositionToValue(0, 0, 50) + expect(actual).to.equal(0) + actual = helper.slider.linearPositionToValue(0.5, 0, 50) + expect(actual).to.equal(25) + actual = Math.round(helper.slider.linearPositionToValue(1, 0, 50)) + expect(actual).to.equal(50) + }) + }) + + describe('Logarithm scale - ', function() { + beforeEach(function() { + var sliderConf = { + value: 10, + options: { + floor: 1, + ceil: 100, + step: 10, + logScale: true, + }, + } + helper.createSlider(sliderConf) + }) + + it('should throw an error if floor is 0', function() { + var testFn = function() { + helper.scope.slider.options.floor = 0 + helper.scope.$digest() + } + expect(testFn).to.throw("Can't use floor=0 with logarithmic scale") + }) + + it('should have a correct logValueToPosition', function() { + var actual = helper.slider.logValueToPosition(1, 1, 50) + expect(actual).to.equal(0) + actual = helper.slider.logValueToPosition(25, 1, 50) + expect(actual.toFixed(2)).to.equal('0.82') + actual = helper.slider.logValueToPosition(50, 1, 50) + expect(actual).to.equal(1) + }) + + it('should have a correct logPositionToValue', function() { + var actual = helper.slider.logPositionToValue(0, 1, 50) + expect(actual).to.equal(1) + actual = helper.slider.logPositionToValue(0.5, 1, 50) + expect(actual.toFixed(2)).to.equal('7.07') + actual = Math.round(helper.slider.logPositionToValue(1, 1, 50)) + expect(actual).to.equal(50) + }) + + it('should handle click and drag on minH correctly', function() { + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 50, + position = helper.getMousePosition(expectedValue) + helper.fireMousemove(position) + expect(helper.scope.slider.value).to.equal(expectedValue + 1) // + 1 because we start at 1 + }) + }) + + describe('Custom scale (here a x^2 scale)- ', function() { + beforeEach(function() { + var sliderConf = { + value: 50, + options: { + floor: 0, + ceil: 100, + step: 10, + customValueToPosition: function(val, minVal, maxVal) { + val = Math.sqrt(val) + minVal = Math.sqrt(minVal) + maxVal = Math.sqrt(maxVal) + var range = maxVal - minVal + return (val - minVal) / range + }, + customPositionToValue: function(percent, minVal, maxVal) { + minVal = Math.sqrt(minVal) + maxVal = Math.sqrt(maxVal) + var value = percent * (maxVal - minVal) + minVal + return Math.pow(value, 2) + }, + }, + } + helper.createSlider(sliderConf) + }) + ;-it('should have a correct valueToPosition', function() { + var actual = helper.slider.valueToPosition(0) + expect(actual).to.equal(0) + actual = helper.slider.valueToPosition(25) + expect(actual).to.equal(helper.slider.maxPos / 2) + actual = helper.slider.valueToPosition(100) + expect(actual).to.equal(helper.slider.maxPos) + }) + + it('should have a correct positionToValue', function() { + var actual = helper.slider.positionToValue(0) + expect(actual).to.equal(0) + actual = helper.slider.positionToValue(helper.slider.maxPos / 2) + expect(actual).to.equal(25) + actual = Math.round(helper.slider.positionToValue(helper.slider.maxPos)) + expect(actual).to.equal(100) + }) + + it('should handle click and drag on minH correctly', function() { + helper.fireMousedown(helper.slider.minH, 0) + var expectedValue = 50, + position = helper.getMousePosition(expectedValue) + helper.fireMousemove(position) + expect(helper.scope.slider.value).to.equal(expectedValue) + }) + }) + }) +})() diff --git a/tests/specs/single-slider-init-test.js b/tests/specs/single-slider-init-test.js index e416cce..35f6147 100644 --- a/tests/specs/single-slider-init-test.js +++ b/tests/specs/single-slider-init-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Single slider initialisation - ', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) beforeEach(function() { var sliderConf = { @@ -26,80 +28,83 @@ options: { floor: 0, ceil: 100, - step: 10 - } - }; - helper.createSlider(sliderConf); - }); + step: 10, + }, + } + helper.createSlider(sliderConf) + }) it('should exist compiled and with correct config', function() { - expect(helper.element.find('span')).to.have.length(11); - expect(helper.slider.range).to.be.false; - expect(helper.slider.valueRange).to.equal(100); - expect(helper.slider.maxH.css('display')).to.equal('none'); - }); + expect(helper.element.find('span')).to.have.length(17) + expect(helper.slider.range).to.be.false + expect(helper.slider.valueRange).to.equal(100) + expect(helper.slider.maxH.css('display')).to.equal('none') + }) it('should watch rzSliderModel and reflow the slider accordingly', function() { - sinon.spy(helper.slider, 'onLowHandleChange'); - helper.scope.slider.value = 54; - helper.scope.$digest(); - helper.slider.onLowHandleChange.called.should.be.true; - }); + sinon.spy(helper.slider, 'onLowHandleChange') + helper.scope.slider.value = 54 + helper.scope.$digest() + helper.slider.onLowHandleChange.called.should.be.true + }) it('should watch rzSliderOptions and reset the slider accordingly', function() { - sinon.spy(helper.slider, 'applyOptions'); - sinon.spy(helper.slider, 'resetSlider'); - helper.scope.slider.options.showTicks = true; - helper.scope.$digest(); - helper.slider.applyOptions.called.should.be.true; - helper.slider.resetSlider.called.should.be.true; - }); + sinon.spy(helper.slider, 'applyOptions') + sinon.spy(helper.slider, 'resetSlider') + helper.scope.slider.options.showTicks = true + helper.scope.$digest() + helper.slider.applyOptions.called.should.be.true + helper.slider.resetSlider.called.should.be.true + }) it('should round the model value to the step by default', function() { - helper.scope.slider.value = 54; - helper.scope.$digest(); - expect(helper.scope.slider.value).to.equal(50); + helper.scope.slider.value = 54 + helper.scope.$digest() + expect(helper.scope.slider.value).to.equal(50) - helper.scope.slider.value = 55; - helper.scope.$digest(); - $timeout.flush(); //to flush the throttle function since we modify twice in a row - expect(helper.scope.slider.value).to.equal(60); - }); + helper.scope.slider.value = 55 + helper.scope.$digest() + $timeout.flush() //to flush the throttle function since we modify twice in a row + expect(helper.scope.slider.value).to.equal(60) + }) it('should call calcViewDimensions() on reCalcViewDimensions', function() { - sinon.spy(helper.slider, 'calcViewDimensions'); - helper.scope.$broadcast('reCalcViewDimensions'); - helper.slider.calcViewDimensions.called.should.be.true; - }); + sinon.spy(helper.slider, 'calcViewDimensions') + helper.scope.$broadcast('reCalcViewDimensions') + helper.slider.calcViewDimensions.called.should.be.true + }) it('should reset everything on rzSliderForceRender', function() { - sinon.spy(helper.slider, 'resetLabelsValue'); - sinon.spy(helper.slider, 'resetSlider'); - sinon.spy(helper.slider, 'onLowHandleChange'); - - helper.scope.$broadcast('rzSliderForceRender'); - - helper.slider.resetLabelsValue.called.should.be.true; - helper.slider.resetSlider.called.should.be.true; - helper.slider.onLowHandleChange.called.should.be.true; - }); - - it('should call calcViewDimensions() on window resize event', inject(function($window) { - sinon.spy(helper.slider, 'calcViewDimensions'); - angular.element($window).triggerHandler('resize'); - helper.slider.calcViewDimensions.called.should.be.true; - })); - - it('should unregister all dom events on $destroy', inject(function($window) { - sinon.spy(helper.slider, 'calcViewDimensions'); - sinon.spy(helper.slider, 'unbindEvents'); - - helper.scope.$broadcast('$destroy'); - angular.element($window).triggerHandler('resize'); - - helper.slider.calcViewDimensions.called.should.be.false; - helper.slider.unbindEvents.called.should.be.true; - })); - }); -}()); - + sinon.spy(helper.slider, 'resetLabelsValue') + sinon.spy(helper.slider, 'resetSlider') + sinon.spy(helper.slider, 'onLowHandleChange') + + helper.scope.$broadcast('rzSliderForceRender') + + helper.slider.resetLabelsValue.called.should.be.true + helper.slider.resetSlider.called.should.be.true + helper.slider.onLowHandleChange.called.should.be.true + }) + + it('should call calcViewDimensions() on window resize event', inject(function( + $window + ) { + sinon.spy(helper.slider, 'calcViewDimensions') + angular.element($window).triggerHandler('resize') + helper.slider.calcViewDimensions.called.should.be.true + })) + + it('should unregister all dom events on $destroy', inject(function( + $window + ) { + sinon.spy(helper.slider, 'calcViewDimensions') + sinon.spy(helper.slider, 'unbindEvents') + + helper.scope.$broadcast('$destroy') + angular.element($window).triggerHandler('resize') + + helper.slider.calcViewDimensions.called.should.be.false + helper.slider.unbindEvents.called.should.be.true + })) + }) +})() diff --git a/tests/specs/test-template.js b/tests/specs/test-template.js index b6651d2..69f487b 100644 --- a/tests/specs/test-template.js +++ b/tests/specs/test-template.js @@ -1,5 +1,5 @@ -(function() { - "use strict"; +;(function() { + 'use strict' /** * Your test file should end with "-test.js" to be executed. @@ -7,23 +7,25 @@ */ describe('Test group description - ', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) /* The slider that will be used for each test. @@ -35,15 +37,12 @@ options: { floor: 0, ceil: 100, - step: 10 - } - }; - helper.createSlider(sliderConf); - }); - - it('should be true', function() { - - }); - }); -}()); - + step: 10, + }, + } + helper.createSlider(sliderConf) + }) + + it('should be true', function() {}) + }) +})() diff --git a/tests/specs/ticks-test.js b/tests/specs/ticks-test.js index b60db28..4379fd1 100644 --- a/tests/specs/ticks-test.js +++ b/tests/specs/ticks-test.js @@ -1,24 +1,26 @@ -(function() { - "use strict"; +;(function() { + 'use strict' describe('Ticks - ', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) it('should not create any tick if showTicks is false (default)', function() { var sliderConf = { @@ -26,12 +28,12 @@ options: { floor: 0, ceil: 100, - step: 10 - } - }; - helper.createSlider(sliderConf); - expect(helper.element[0].querySelectorAll('.rz-tick')).to.have.length(0); - }); + step: 10, + }, + } + helper.createSlider(sliderConf) + expect(helper.element[0].querySelectorAll('.rz-tick')).to.have.length(0) + }) it('should create the correct number of ticks when showTicks is true', function() { var sliderConf = { @@ -40,12 +42,12 @@ floor: 0, ceil: 100, step: 10, - showTicks: true - } - }; - helper.createSlider(sliderConf); - expect(helper.element[0].querySelectorAll('.rz-tick')).to.have.length(11); - }); + showTicks: true, + }, + } + helper.createSlider(sliderConf) + expect(helper.element[0].querySelectorAll('.rz-tick')).to.have.length(11) + }) it('should create the correct number of ticks when showTicks is an integer', function() { var sliderConf = { @@ -54,12 +56,12 @@ floor: 0, ceil: 100, step: 10, - showTicks: 20 - } - }; - helper.createSlider(sliderConf); - expect(helper.element[0].querySelectorAll('.rz-tick')).to.have.length(6); - }); + showTicks: 20, + }, + } + helper.createSlider(sliderConf) + expect(helper.element[0].querySelectorAll('.rz-tick')).to.have.length(6) + }) it('should create the correct number of ticks when showTicksValues is true', function() { var sliderConf = { @@ -68,36 +70,50 @@ floor: 0, ceil: 100, step: 10, - showTicksValues: true - } - }; - helper.createSlider(sliderConf); - expect(helper.element[0].querySelectorAll('.rz-tick')).to.have.length(11); - expect(helper.element[0].querySelectorAll('.rz-tick-value')).to.have.length(11); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick-value')[0]); - expect(firstTick.text()).to.equal('0'); - var secondTick = angular.element(helper.element[0].querySelectorAll('.rz-tick-value')[1]); - expect(secondTick.text()).to.equal('10'); - }); + showTicksValues: true, + }, + } + helper.createSlider(sliderConf) + expect(helper.element[0].querySelectorAll('.rz-tick')).to.have.length(11) + expect( + helper.element[0].querySelectorAll('.rz-tick-value') + ).to.have.length(11) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[0] + ) + expect(firstTick.text()).to.equal('0') + var secondTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[1] + ) + expect(secondTick.text()).to.equal('10') + }) it('should create the correct number of ticks when showTicksValues is true and used with stepsArray', function() { var sliderConf = { value: 'C', options: { stepsArray: ['A', 'B', 'C', 'D', 'E'], - showTicksValues: true - } - }; - helper.createSlider(sliderConf); - expect(helper.element[0].querySelectorAll('.rz-tick')).to.have.length(5); - expect(helper.element[0].querySelectorAll('.rz-tick-value')).to.have.length(5); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick-value')[0]); - expect(firstTick.text()).to.equal('A'); - var secondTick = angular.element(helper.element[0].querySelectorAll('.rz-tick-value')[1]); - expect(secondTick.text()).to.equal('B'); - var lasTick = angular.element(helper.element[0].querySelectorAll('.rz-tick-value')[4]); - expect(lasTick.text()).to.equal('E'); - }); + showTicksValues: true, + }, + } + helper.createSlider(sliderConf) + expect(helper.element[0].querySelectorAll('.rz-tick')).to.have.length(5) + expect( + helper.element[0].querySelectorAll('.rz-tick-value') + ).to.have.length(5) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[0] + ) + expect(firstTick.text()).to.equal('A') + var secondTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[1] + ) + expect(secondTick.text()).to.equal('B') + var lasTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[4] + ) + expect(lasTick.text()).to.equal('E') + }) it('should create the correct number of ticks when showTicksValues is true and used with stepsArray and bindIndexForStepsArray is true', function() { var sliderConf = { @@ -105,19 +121,27 @@ options: { stepsArray: ['A', 'B', 'C', 'D', 'E'], bindIndexForStepsArray: true, - showTicksValues: true - } - }; - helper.createSlider(sliderConf); - expect(helper.element[0].querySelectorAll('.rz-tick')).to.have.length(5); - expect(helper.element[0].querySelectorAll('.rz-tick-value')).to.have.length(5); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick-value')[0]); - expect(firstTick.text()).to.equal('A'); - var secondTick = angular.element(helper.element[0].querySelectorAll('.rz-tick-value')[1]); - expect(secondTick.text()).to.equal('B'); - var lasTick = angular.element(helper.element[0].querySelectorAll('.rz-tick-value')[4]); - expect(lasTick.text()).to.equal('E'); - }); + showTicksValues: true, + }, + } + helper.createSlider(sliderConf) + expect(helper.element[0].querySelectorAll('.rz-tick')).to.have.length(5) + expect( + helper.element[0].querySelectorAll('.rz-tick-value') + ).to.have.length(5) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[0] + ) + expect(firstTick.text()).to.equal('A') + var secondTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[1] + ) + expect(secondTick.text()).to.equal('B') + var lasTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[4] + ) + expect(lasTick.text()).to.equal('E') + }) it('should create the correct number of ticks when showTicksValues is an integer', function() { var sliderConf = { @@ -126,20 +150,151 @@ floor: 0, ceil: 100, step: 10, - showTicksValues: 20 + showTicksValues: 20, + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.ticks.hasClass('rz-ticks-values-under')).to.be.true + expect(helper.element[0].querySelectorAll('.rz-tick')).to.have.length(6) + expect( + helper.element[0].querySelectorAll('.rz-tick-value') + ).to.have.length(6) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[0] + ) + expect(firstTick.text()).to.equal('0') + var secondTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[1] + ) + expect(secondTick.text()).to.equal('20') + var lastTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[5] + ) + expect(lastTick.text()).to.equal('100') + }) + + it( + 'should create the correct number of ticks/values when showTick and showTicksValues' + + ' are integers with different values', + function() { + var sliderConf = { + value: 50, + options: { + floor: 0, + ceil: 100, + step: 10, + showTicksValues: 20, + showTicks: 10, + }, } - }; - helper.createSlider(sliderConf); - expect(helper.slider.ticks.hasClass('rz-ticks-values-under')).to.be.true; - expect(helper.element[0].querySelectorAll('.rz-tick')).to.have.length(6); - expect(helper.element[0].querySelectorAll('.rz-tick-value')).to.have.length(6); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick-value')[0]); - expect(firstTick.text()).to.equal('0'); - var secondTick = angular.element(helper.element[0].querySelectorAll('.rz-tick-value')[1]); - expect(secondTick.text()).to.equal('20'); - var lastTick = angular.element(helper.element[0].querySelectorAll('.rz-tick-value')[5]); - expect(lastTick.text()).to.equal('100'); - }); + helper.createSlider(sliderConf) + expect(helper.slider.ticks.hasClass('rz-ticks-values-under')).to.be.true + expect(helper.element[0].querySelectorAll('.rz-tick')).to.have.length( + 11 + ) + expect( + helper.element[0].querySelectorAll('.rz-tick-value') + ).to.have.length(6) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[0] + ) + expect(firstTick.text()).to.equal('0') + var secondTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[1] + ) + expect(secondTick.text()).to.equal('20') + var lastTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[5] + ) + expect(lastTick.text()).to.equal('100') + } + ) + + it('should create the correct number of ticks when ticksArray is used', function() { + var sliderConf = { + value: 50, + options: { + floor: 0, + ceil: 100, + step: 10, + ticksArray: [0, 25, 50, 100], + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.ticks.hasClass('rz-ticks-values-under')).to.be.false + expect(helper.element[0].querySelectorAll('.rz-tick')).to.have.length(4) + expect( + helper.element[0].querySelectorAll('.rz-tick-value') + ).to.have.length(0) + }) + + it('should create the correct number of ticks when ticksArray is used along with showTicksValues', function() { + var sliderConf = { + value: 50, + options: { + floor: 0, + ceil: 100, + step: 10, + ticksArray: [0, 25, 50, 100], + showTicksValues: true, + }, + } + helper.createSlider(sliderConf) + expect(helper.slider.ticks.hasClass('rz-ticks-values-under')).to.be.true + expect(helper.element[0].querySelectorAll('.rz-tick')).to.have.length(4) + expect( + helper.element[0].querySelectorAll('.rz-tick-value') + ).to.have.length(4) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[0] + ) + expect(firstTick.text()).to.equal('0') + var secondTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[1] + ) + expect(secondTick.text()).to.equal('25') + var thirdTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[2] + ) + expect(thirdTick.text()).to.equal('50') + var lastTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[3] + ) + expect(lastTick.text()).to.equal('100') + }) + + it('should create the correct number of ticks when ticksArray is used as array of objects', function() { + var sliderConf = { + value: 50, + options: { + floor: 0, + ceil: 100, + step: 10, + ticksArray: [ + { value: 0, legend: 'Bad' }, + { value: 50, legend: 'Average' }, + { value: 100, legend: 'Excellent' }, + ], + }, + } + helper.createSlider(sliderConf) + expect(helper.element[0].querySelectorAll('.rz-tick')).to.have.length(3) + expect( + helper.element[0].querySelectorAll('.rz-tick-value') + ).to.have.length(0) + + expect( + helper.element[0].querySelectorAll('.rz-tick-legend') + ).to.have.length(3) + var firstLegend = angular.element( + helper.element[0].querySelectorAll('.rz-tick-legend')[0] + ) + expect(firstLegend.text()).to.equal('Bad') + var lastLegend = angular.element( + helper.element[0].querySelectorAll('.rz-tick-legend')[2] + ) + expect(lastLegend.text()).to.equal('Excellent') + }) it('should create the correct number of legend items when getLegend is defined', function() { var sliderConf = { @@ -150,17 +305,23 @@ step: 10, showTicks: true, getLegend: function(value) { - return 'Legend for ' + value; - } - } - }; - helper.createSlider(sliderConf); - expect(helper.element[0].querySelectorAll('.rz-tick-legend')).to.have.length(11); - var firstLegend = angular.element(helper.element[0].querySelectorAll('.rz-tick-legend')[0]); - expect(firstLegend.text()).to.equal('Legend for 0'); - var lastLegend = angular.element(helper.element[0].querySelectorAll('.rz-tick-legend')[10]); - expect(lastLegend.text()).to.equal('Legend for 100'); - }); + return 'Legend for ' + value + }, + }, + } + helper.createSlider(sliderConf) + expect( + helper.element[0].querySelectorAll('.rz-tick-legend') + ).to.have.length(11) + var firstLegend = angular.element( + helper.element[0].querySelectorAll('.rz-tick-legend')[0] + ) + expect(firstLegend.text()).to.equal('Legend for 0') + var lastLegend = angular.element( + helper.element[0].querySelectorAll('.rz-tick-legend')[10] + ) + expect(lastLegend.text()).to.equal('Legend for 100') + }) it('should create the correct number of legend items when getLegend is defined and only some legend are displayed', function() { var sliderConf = { @@ -171,19 +332,24 @@ step: 10, showTicks: true, getLegend: function(value) { - if(value % 20 === 0) - return 'Legend for ' + value; - return null; - } - } - }; - helper.createSlider(sliderConf); - expect(helper.element[0].querySelectorAll('.rz-tick-legend')).to.have.length(6); - var firstLegend = angular.element(helper.element[0].querySelectorAll('.rz-tick-legend')[0]); - expect(firstLegend.text()).to.equal('Legend for 0'); - var lastLegend = angular.element(helper.element[0].querySelectorAll('.rz-tick-legend')[5]); - expect(lastLegend.text()).to.equal('Legend for 100'); - }); + if (value % 20 === 0) return 'Legend for ' + value + return null + }, + }, + } + helper.createSlider(sliderConf) + expect( + helper.element[0].querySelectorAll('.rz-tick-legend') + ).to.have.length(6) + var firstLegend = angular.element( + helper.element[0].querySelectorAll('.rz-tick-legend')[0] + ) + expect(firstLegend.text()).to.equal('Legend for 0') + var lastLegend = angular.element( + helper.element[0].querySelectorAll('.rz-tick-legend')[5] + ) + expect(lastLegend.text()).to.equal('Legend for 100') + }) it('should set rz-selected class to ticks below the model value if showSelectionBar is true', function() { var sliderConf = { @@ -193,19 +359,27 @@ ceil: 100, step: 10, showTicks: true, - showSelectionBar: true - } - }; - helper.createSlider(sliderConf); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[0]); - expect(firstTick.hasClass('rz-selected')).to.be.true; - var sixthTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[5]); - expect(sixthTick.hasClass('rz-selected')).to.be.true; - var seventhTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[6]); - expect(seventhTick.hasClass('rz-selected')).to.be.false; - var lastTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[10]); - expect(lastTick.hasClass('rz-selected')).to.be.false; - }); + showSelectionBar: true, + }, + } + helper.createSlider(sliderConf) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[0] + ) + expect(firstTick.hasClass('rz-selected')).to.be.true + var sixthTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[5] + ) + expect(sixthTick.hasClass('rz-selected')).to.be.true + var seventhTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[6] + ) + expect(seventhTick.hasClass('rz-selected')).to.be.false + var lastTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[10] + ) + expect(lastTick.hasClass('rz-selected')).to.be.false + }) it('should set rz-selected class to ticks above the model value if showSelectionBarEnd is true', function() { var sliderConf = { @@ -215,21 +389,31 @@ ceil: 100, step: 10, showTicks: true, - showSelectionBarEnd: true - } - }; - helper.createSlider(sliderConf); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[0]); - expect(firstTick.hasClass('rz-selected')).to.be.false; - var fifthTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[4]); - expect(fifthTick.hasClass('rz-selected')).to.be.false; - var sixthTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[5]); - expect(sixthTick.hasClass('rz-selected')).to.be.true; - var seventhTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[6]); - expect(seventhTick.hasClass('rz-selected')).to.be.true; - var lastTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[10]); - expect(lastTick.hasClass('rz-selected')).to.be.true; - }); + showSelectionBarEnd: true, + }, + } + helper.createSlider(sliderConf) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[0] + ) + expect(firstTick.hasClass('rz-selected')).to.be.false + var fifthTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[4] + ) + expect(fifthTick.hasClass('rz-selected')).to.be.false + var sixthTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[5] + ) + expect(sixthTick.hasClass('rz-selected')).to.be.true + var seventhTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[6] + ) + expect(seventhTick.hasClass('rz-selected')).to.be.true + var lastTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[10] + ) + expect(lastTick.hasClass('rz-selected')).to.be.true + }) it('should set rz-selected class to correct ticks if showSelectionBarFromValue is used and the model is on the right', function() { var sliderConf = { @@ -239,25 +423,39 @@ ceil: 100, step: 10, showTicks: true, - showSelectionBarFromValue: 30 - } - }; - helper.createSlider(sliderConf); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[0]); - expect(firstTick.hasClass('rz-selected')).to.be.false; - var thirdTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[2]); - expect(thirdTick.hasClass('rz-selected')).to.be.false; - var fourthTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[3]); - expect(fourthTick.hasClass('rz-selected')).to.be.true; - var fifthTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[4]); - expect(fifthTick.hasClass('rz-selected')).to.be.true; - var sixthTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[5]); - expect(sixthTick.hasClass('rz-selected')).to.be.true; - var seventhTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[6]); - expect(seventhTick.hasClass('rz-selected')).to.be.false; - var lastTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[10]); - expect(lastTick.hasClass('rz-selected')).to.be.false; - }); + showSelectionBarFromValue: 30, + }, + } + helper.createSlider(sliderConf) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[0] + ) + expect(firstTick.hasClass('rz-selected')).to.be.false + var thirdTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[2] + ) + expect(thirdTick.hasClass('rz-selected')).to.be.false + var fourthTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[3] + ) + expect(fourthTick.hasClass('rz-selected')).to.be.true + var fifthTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[4] + ) + expect(fifthTick.hasClass('rz-selected')).to.be.true + var sixthTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[5] + ) + expect(sixthTick.hasClass('rz-selected')).to.be.true + var seventhTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[6] + ) + expect(seventhTick.hasClass('rz-selected')).to.be.false + var lastTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[10] + ) + expect(lastTick.hasClass('rz-selected')).to.be.false + }) it('should set rz-selected class to correct ticks if showSelectionBarFromValue is used and the model is on the left', function() { var sliderConf = { value: 50, @@ -266,25 +464,39 @@ ceil: 100, step: 10, showTicks: true, - showSelectionBarFromValue: 70 - } - }; - helper.createSlider(sliderConf); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[0]); - expect(firstTick.hasClass('rz-selected')).to.be.false; - var fifthTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[4]); - expect(fifthTick.hasClass('rz-selected')).to.be.false; - var sixthTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[5]); - expect(sixthTick.hasClass('rz-selected')).to.be.true; - var seventhTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[6]); - expect(seventhTick.hasClass('rz-selected')).to.be.true; - var eighthTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[7]); - expect(eighthTick.hasClass('rz-selected')).to.be.true; - var ninthTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[8]); - expect(ninthTick.hasClass('rz-selected')).to.be.false; - var lastTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[10]); - expect(lastTick.hasClass('rz-selected')).to.be.false; - }); + showSelectionBarFromValue: 70, + }, + } + helper.createSlider(sliderConf) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[0] + ) + expect(firstTick.hasClass('rz-selected')).to.be.false + var fifthTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[4] + ) + expect(fifthTick.hasClass('rz-selected')).to.be.false + var sixthTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[5] + ) + expect(sixthTick.hasClass('rz-selected')).to.be.true + var seventhTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[6] + ) + expect(seventhTick.hasClass('rz-selected')).to.be.true + var eighthTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[7] + ) + expect(eighthTick.hasClass('rz-selected')).to.be.true + var ninthTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[8] + ) + expect(ninthTick.hasClass('rz-selected')).to.be.false + var lastTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[10] + ) + expect(lastTick.hasClass('rz-selected')).to.be.false + }) it('should set rz-selected class to ticks between min/max if showSelectionBar is true on range slider', function() { var sliderConf = { @@ -294,19 +506,27 @@ floor: 0, ceil: 100, step: 10, - showTicks: true - } - }; - helper.createRangeSlider(sliderConf); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[0]); - expect(firstTick.hasClass('rz-selected')).to.be.false; - var sixthTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[5]); - expect(sixthTick.hasClass('rz-selected')).to.be.true; - var seventhTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[6]); - expect(seventhTick.hasClass('rz-selected')).to.be.true; - var lastTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[10]); - expect(lastTick.hasClass('rz-selected')).to.be.false; - }); + showTicks: true, + }, + } + helper.createRangeSlider(sliderConf) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[0] + ) + expect(firstTick.hasClass('rz-selected')).to.be.false + var sixthTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[5] + ) + expect(sixthTick.hasClass('rz-selected')).to.be.true + var seventhTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[6] + ) + expect(seventhTick.hasClass('rz-selected')).to.be.true + var lastTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[10] + ) + expect(lastTick.hasClass('rz-selected')).to.be.false + }) it('should set the correct color to ticks when getSelectionBarColor is defined', function() { var sliderConf = { @@ -318,21 +538,21 @@ showTicks: true, showSelectionBar: true, getSelectionBarColor: function(value) { - if (value <= 50) - return 'red'; - else - return 'green'; - } - } - }; - helper.createSlider(sliderConf); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[0]); - expect(firstTick.css('background-color')).to.equal('red'); - - helper.scope.slider.value = 100; - helper.scope.$digest(); - expect(firstTick.css('background-color')).to.equal('green'); - }); + if (value <= 50) return 'red' + else return 'green' + }, + }, + } + helper.createSlider(sliderConf) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[0] + ) + expect(firstTick.css('background-color')).to.equal('red') + + helper.scope.slider.value = 100 + helper.scope.$digest() + expect(firstTick.css('background-color')).to.equal('green') + }) it('should set correct tooltip attributes if ticksTooltip is defined for a horizontal slider', function() { var sliderConf = { @@ -343,17 +563,21 @@ step: 10, showTicks: true, ticksTooltip: function(value) { - return 'tooltip for ' + value; - } - } - }; - helper.createSlider(sliderConf); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[0]); - expect(firstTick.attr('uib-tooltip')).to.equal('tooltip for 0'); - expect(firstTick.attr('tooltip-placement')).to.equal('top'); - var secondTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[1]); - expect(secondTick.attr('uib-tooltip')).to.equal('tooltip for 10'); - }); + return 'tooltip for ' + value + }, + }, + } + helper.createSlider(sliderConf) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[0] + ) + expect(firstTick.attr('uib-tooltip')).to.equal('tooltip for 0') + expect(firstTick.attr('tooltip-placement')).to.equal('top') + var secondTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[1] + ) + expect(secondTick.attr('uib-tooltip')).to.equal('tooltip for 10') + }) it('should set correct tooltip attributes if ticksTooltip is defined for a vertical slider', function() { var sliderConf = { @@ -365,17 +589,21 @@ vertical: true, showTicks: true, ticksTooltip: function(value) { - return 'tooltip for ' + value; - } - } - }; - helper.createSlider(sliderConf); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[0]); - expect(firstTick.attr('uib-tooltip')).to.equal('tooltip for 0'); - expect(firstTick.attr('tooltip-placement')).to.equal('right'); - var secondTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[1]); - expect(secondTick.attr('uib-tooltip')).to.equal('tooltip for 10'); - }); + return 'tooltip for ' + value + }, + }, + } + helper.createSlider(sliderConf) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[0] + ) + expect(firstTick.attr('uib-tooltip')).to.equal('tooltip for 0') + expect(firstTick.attr('tooltip-placement')).to.equal('right') + var secondTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[1] + ) + expect(secondTick.attr('uib-tooltip')).to.equal('tooltip for 10') + }) it('should set correct tooltip attributes on rz-tick-value if ticksValuesTooltip is defined for a horizontal slider', function() { var sliderConf = { @@ -386,17 +614,21 @@ step: 10, showTicksValues: true, ticksValuesTooltip: function(value) { - return 'tooltip for ' + value; - } - } - }; - helper.createSlider(sliderConf); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick-value')[0]); - expect(firstTick.attr('uib-tooltip')).to.equal('tooltip for 0'); - expect(firstTick.attr('tooltip-placement')).to.equal('top'); - var secondTick = angular.element(helper.element[0].querySelectorAll('.rz-tick-value')[1]); - expect(secondTick.attr('uib-tooltip')).to.equal('tooltip for 10'); - }); + return 'tooltip for ' + value + }, + }, + } + helper.createSlider(sliderConf) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[0] + ) + expect(firstTick.attr('uib-tooltip')).to.equal('tooltip for 0') + expect(firstTick.attr('tooltip-placement')).to.equal('top') + var secondTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[1] + ) + expect(secondTick.attr('uib-tooltip')).to.equal('tooltip for 10') + }) it('should set correct tooltip attributes on rz-tick-value if ticksValuesTooltip is defined for a vertical slider', function() { var sliderConf = { @@ -408,37 +640,43 @@ vertical: true, showTicksValues: true, ticksValuesTooltip: function(value) { - return 'tooltip for ' + value; - } - } - }; - helper.createSlider(sliderConf); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick-value')[0]); - expect(firstTick.attr('uib-tooltip')).to.equal('tooltip for 0'); - expect(firstTick.attr('tooltip-placement')).to.equal('right'); - var secondTick = angular.element(helper.element[0].querySelectorAll('.rz-tick-value')[1]); - expect(secondTick.attr('uib-tooltip')).to.equal('tooltip for 10'); - }); - }); + return 'tooltip for ' + value + }, + }, + } + helper.createSlider(sliderConf) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[0] + ) + expect(firstTick.attr('uib-tooltip')).to.equal('tooltip for 0') + expect(firstTick.attr('tooltip-placement')).to.equal('right') + var secondTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[1] + ) + expect(secondTick.attr('uib-tooltip')).to.equal('tooltip for 10') + }) + }) describe('Right to left Ticks - ', function() { - var helper, - RzSliderOptions, - $rootScope, - $timeout; - - beforeEach(module('test-helper')); - - beforeEach(inject(function(TestHelper, _RzSliderOptions_, _$rootScope_, _$timeout_) { - helper = TestHelper; - RzSliderOptions = _RzSliderOptions_; - $rootScope = _$rootScope_; - $timeout = _$timeout_; - })); + var helper, RzSliderOptions, $rootScope, $timeout + + beforeEach(module('test-helper')) + + beforeEach(inject(function( + TestHelper, + _RzSliderOptions_, + _$rootScope_, + _$timeout_ + ) { + helper = TestHelper + RzSliderOptions = _RzSliderOptions_ + $rootScope = _$rootScope_ + $timeout = _$timeout_ + })) afterEach(function() { - helper.clean(); - }); + helper.clean() + }) it('should set rz-selected class to ticks below the model value if showSelectionBar is true', function() { var sliderConf = { @@ -449,19 +687,27 @@ step: 10, showTicks: true, showSelectionBar: true, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[0]); - expect(firstTick.hasClass('rz-selected')).to.be.false; - var sixthTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[5]); - expect(sixthTick.hasClass('rz-selected')).to.be.true; - var seventhTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[6]); - expect(seventhTick.hasClass('rz-selected')).to.be.true; - var lastTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[10]); - expect(lastTick.hasClass('rz-selected')).to.be.true; - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[0] + ) + expect(firstTick.hasClass('rz-selected')).to.be.false + var sixthTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[5] + ) + expect(sixthTick.hasClass('rz-selected')).to.be.true + var seventhTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[6] + ) + expect(seventhTick.hasClass('rz-selected')).to.be.true + var lastTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[10] + ) + expect(lastTick.hasClass('rz-selected')).to.be.true + }) it('should set rz-selected class to ticks above the model value if showSelectionBarEnd is true', function() { var sliderConf = { @@ -472,21 +718,31 @@ step: 10, showTicks: true, showSelectionBarEnd: true, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[0]); - expect(firstTick.hasClass('rz-selected')).to.be.true; - var fifthTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[4]); - expect(fifthTick.hasClass('rz-selected')).to.be.true; - var sixthTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[5]); - expect(sixthTick.hasClass('rz-selected')).to.be.true; - var seventhTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[6]); - expect(seventhTick.hasClass('rz-selected')).to.be.false; - var lastTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[10]); - expect(lastTick.hasClass('rz-selected')).to.be.false; - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[0] + ) + expect(firstTick.hasClass('rz-selected')).to.be.true + var fifthTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[4] + ) + expect(fifthTick.hasClass('rz-selected')).to.be.true + var sixthTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[5] + ) + expect(sixthTick.hasClass('rz-selected')).to.be.true + var seventhTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[6] + ) + expect(seventhTick.hasClass('rz-selected')).to.be.false + var lastTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[10] + ) + expect(lastTick.hasClass('rz-selected')).to.be.false + }) it('should set rz-selected class to correct ticks if showSelectionBarFromValue is used and the model is on the right', function() { var sliderConf = { @@ -497,25 +753,39 @@ step: 10, showTicks: true, showSelectionBarFromValue: 30, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[0]); - expect(firstTick.hasClass('rz-selected')).to.be.false; - var thirdTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[2]); - expect(thirdTick.hasClass('rz-selected')).to.be.false; - var fourthTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[3]); - expect(fourthTick.hasClass('rz-selected')).to.be.false; - var fifthTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[4]); - expect(fifthTick.hasClass('rz-selected')).to.be.false; - var sixthTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[5]); - expect(sixthTick.hasClass('rz-selected')).to.be.true; - var seventhTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[6]); - expect(seventhTick.hasClass('rz-selected')).to.be.true; - var lastTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[10]); - expect(lastTick.hasClass('rz-selected')).to.be.false; - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[0] + ) + expect(firstTick.hasClass('rz-selected')).to.be.false + var thirdTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[2] + ) + expect(thirdTick.hasClass('rz-selected')).to.be.false + var fourthTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[3] + ) + expect(fourthTick.hasClass('rz-selected')).to.be.false + var fifthTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[4] + ) + expect(fifthTick.hasClass('rz-selected')).to.be.false + var sixthTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[5] + ) + expect(sixthTick.hasClass('rz-selected')).to.be.true + var seventhTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[6] + ) + expect(seventhTick.hasClass('rz-selected')).to.be.true + var lastTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[10] + ) + expect(lastTick.hasClass('rz-selected')).to.be.false + }) it('should set rz-selected class to correct ticks if showSelectionBarFromValue is used and the model is on the left', function() { var sliderConf = { value: 50, @@ -525,25 +795,39 @@ step: 10, showTicks: true, showSelectionBarFromValue: 70, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[0]); - expect(firstTick.hasClass('rz-selected')).to.be.false; - var fifthTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[4]); - expect(fifthTick.hasClass('rz-selected')).to.be.true; - var sixthTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[5]); - expect(sixthTick.hasClass('rz-selected')).to.be.true; - var seventhTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[6]); - expect(seventhTick.hasClass('rz-selected')).to.be.false; - var eighthTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[7]); - expect(eighthTick.hasClass('rz-selected')).to.be.false; - var ninthTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[8]); - expect(ninthTick.hasClass('rz-selected')).to.be.false; - var lastTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[10]); - expect(lastTick.hasClass('rz-selected')).to.be.false; - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[0] + ) + expect(firstTick.hasClass('rz-selected')).to.be.false + var fifthTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[4] + ) + expect(fifthTick.hasClass('rz-selected')).to.be.true + var sixthTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[5] + ) + expect(sixthTick.hasClass('rz-selected')).to.be.true + var seventhTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[6] + ) + expect(seventhTick.hasClass('rz-selected')).to.be.false + var eighthTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[7] + ) + expect(eighthTick.hasClass('rz-selected')).to.be.false + var ninthTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[8] + ) + expect(ninthTick.hasClass('rz-selected')).to.be.false + var lastTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[10] + ) + expect(lastTick.hasClass('rz-selected')).to.be.false + }) it('should set the correct color to ticks when getSelectionBarColor is defined', function() { var sliderConf = { @@ -555,22 +839,22 @@ showTicks: true, showSelectionBar: true, getSelectionBarColor: function(value) { - if (value <= 50) - return 'red'; - else - return 'green'; + if (value <= 50) return 'red' + else return 'green' }, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[9]); - expect(firstTick.css('background-color')).to.equal('red'); - - helper.scope.slider.value = 100; - helper.scope.$digest(); - expect(firstTick.css('background-color')).to.equal('green'); - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[9] + ) + expect(firstTick.css('background-color')).to.equal('red') + + helper.scope.slider.value = 100 + helper.scope.$digest() + expect(firstTick.css('background-color')).to.equal('green') + }) it('should set correct tooltip attributes if ticksTooltip is defined for a horizontal slider', function() { var sliderConf = { @@ -581,18 +865,22 @@ step: 10, showTicks: true, ticksTooltip: function(value) { - return 'tooltip for ' + value; + return 'tooltip for ' + value }, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[0]); - expect(firstTick.attr('uib-tooltip')).to.equal('tooltip for 100'); - expect(firstTick.attr('tooltip-placement')).to.equal('top'); - var secondTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[1]); - expect(secondTick.attr('uib-tooltip')).to.equal('tooltip for 90'); - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[0] + ) + expect(firstTick.attr('uib-tooltip')).to.equal('tooltip for 100') + expect(firstTick.attr('tooltip-placement')).to.equal('top') + var secondTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[1] + ) + expect(secondTick.attr('uib-tooltip')).to.equal('tooltip for 90') + }) it('should set correct tooltip attributes if ticksTooltip is defined for a vertical slider', function() { var sliderConf = { @@ -604,18 +892,22 @@ vertical: true, showTicks: true, ticksTooltip: function(value) { - return 'tooltip for ' + value; + return 'tooltip for ' + value }, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[0]); - expect(firstTick.attr('uib-tooltip')).to.equal('tooltip for 100'); - expect(firstTick.attr('tooltip-placement')).to.equal('right'); - var secondTick = angular.element(helper.element[0].querySelectorAll('.rz-tick')[1]); - expect(secondTick.attr('uib-tooltip')).to.equal('tooltip for 90'); - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[0] + ) + expect(firstTick.attr('uib-tooltip')).to.equal('tooltip for 100') + expect(firstTick.attr('tooltip-placement')).to.equal('right') + var secondTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick')[1] + ) + expect(secondTick.attr('uib-tooltip')).to.equal('tooltip for 90') + }) it('should set correct tooltip attributes on rz-tick-value if ticksValuesTooltip is defined for a horizontal slider', function() { var sliderConf = { @@ -626,18 +918,22 @@ step: 10, showTicksValues: true, ticksValuesTooltip: function(value) { - return 'tooltip for ' + value; + return 'tooltip for ' + value }, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick-value')[0]); - expect(firstTick.attr('uib-tooltip')).to.equal('tooltip for 100'); - expect(firstTick.attr('tooltip-placement')).to.equal('top'); - var secondTick = angular.element(helper.element[0].querySelectorAll('.rz-tick-value')[1]); - expect(secondTick.attr('uib-tooltip')).to.equal('tooltip for 90'); - }); + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[0] + ) + expect(firstTick.attr('uib-tooltip')).to.equal('tooltip for 100') + expect(firstTick.attr('tooltip-placement')).to.equal('top') + var secondTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[1] + ) + expect(secondTick.attr('uib-tooltip')).to.equal('tooltip for 90') + }) it('should set correct tooltip attributes on rz-tick-value if ticksValuesTooltip is defined for a vertical slider', function() { var sliderConf = { @@ -649,19 +945,21 @@ vertical: true, showTicksValues: true, ticksValuesTooltip: function(value) { - return 'tooltip for ' + value; + return 'tooltip for ' + value }, - rightToLeft: true - } - }; - helper.createSlider(sliderConf); - var firstTick = angular.element(helper.element[0].querySelectorAll('.rz-tick-value')[0]); - expect(firstTick.attr('uib-tooltip')).to.equal('tooltip for 100'); - expect(firstTick.attr('tooltip-placement')).to.equal('right'); - var secondTick = angular.element(helper.element[0].querySelectorAll('.rz-tick-value')[1]); - expect(secondTick.attr('uib-tooltip')).to.equal('tooltip for 90'); - }); - }); - -}()); - + rightToLeft: true, + }, + } + helper.createSlider(sliderConf) + var firstTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[0] + ) + expect(firstTick.attr('uib-tooltip')).to.equal('tooltip for 100') + expect(firstTick.attr('tooltip-placement')).to.equal('right') + var secondTick = angular.element( + helper.element[0].querySelectorAll('.rz-tick-value')[1] + ) + expect(secondTick.attr('uib-tooltip')).to.equal('tooltip for 90') + }) + }) +})()