diff --git a/distribute/nouislider.css b/distribute/nouislider.css index cb9d5ff3..55ef90af 100644 --- a/distribute/nouislider.css +++ b/distribute/nouislider.css @@ -1,4 +1,4 @@ -/*! nouislider - 12.1.0 - 10/25/2018 */ +/*! nouislider - 12.1.0 - 2/6/2019 */ /* Functional styling; * These styles are required for noUiSlider to function. * You don't need to change these rules to apply your design. @@ -64,6 +64,10 @@ html:not([dir="rtl"]) .noUi-horizontal .noUi-origin { .noUi-handle { position: absolute; } +.noUi-touch-area { + height: 100%; + width: 100%; +} .noUi-state-tap .noUi-connect, .noUi-state-tap .noUi-origin { -webkit-transition: transform 0.3s; @@ -242,7 +246,7 @@ html:not([dir="rtl"]) .noUi-horizontal .noUi-handle { } .noUi-value-vertical { -webkit-transform: translate(0, -50%); - transform: translate(0, -50%, 0); + transform: translate(0, -50%); padding-left: 25px; } .noUi-rtl .noUi-value-vertical { diff --git a/distribute/nouislider.js b/distribute/nouislider.js index 3bf6352d..58ed5eb3 100644 --- a/distribute/nouislider.js +++ b/distribute/nouislider.js @@ -1,4 +1,4 @@ -/*! nouislider - 12.1.0 - 10/25/2018 */ +/*! nouislider - 12.1.0 - 2/6/2019 */ (function(factory) { if (typeof define === "function" && define.amd) { // AMD. Register as an anonymous module. @@ -423,6 +423,17 @@ return value; }; + Spectrum.prototype.getDefaultStep = function(value, isDown, size) { + var j = getJ(value, this.xPct); + + // When at the top or stepping down, look at the previous sub-range + if (value === 100 || (isDown && value === this.xPct[j - 1])) { + j = Math.max(j - 1, 1); + } + + return (this.xVal[j] - this.xVal[j - 1]) / size; + }; + Spectrum.prototype.getNearbySteps = function(value) { var j = getJ(value, this.xPct); @@ -861,6 +872,7 @@ handle: "handle", handleLower: "handle-lower", handleUpper: "handle-upper", + touchArea: "touch-area", horizontal: "horizontal", vertical: "vertical", background: "background", @@ -939,18 +951,29 @@ var supportsPassive = supportsTouchActionNone && getSupportsPassive(); // All variables local to 'scope' are prefixed with 'scope_' + + // Slider DOM Nodes var scope_Target = target; - var scope_Locations = []; var scope_Base; var scope_Handles; - var scope_HandleNumbers = []; - var scope_ActiveHandlesCount = 0; var scope_Connects; + var scope_Pips; + + // Override for the 'animate' option + var scope_ShouldAnimate = true; + + // Slider state values var scope_Spectrum = options.spectrum; var scope_Values = []; + var scope_Locations = []; + var scope_HandleNumbers = []; + var scope_ActiveHandlesCount = 0; var scope_Events = {}; + + // Exposed API var scope_Self; - var scope_Pips; + + // Document Nodes var scope_Document = target.ownerDocument; var scope_DocumentElement = options.documentElement || scope_Document.documentElement; var scope_Body = scope_Document.body; @@ -983,12 +1006,17 @@ var origin = addNodeTo(base, options.cssClasses.origin); var handle = addNodeTo(origin, options.cssClasses.handle); + addNodeTo(handle, options.cssClasses.touchArea); + handle.setAttribute("data-handle", handleNumber); if (options.keyboardSupport) { // https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex // 0 = focusable and reachable handle.setAttribute("tabindex", "0"); + handle.addEventListener("keydown", function(event) { + return eventKeydown(event, handleNumber); + }); } handle.setAttribute("role", "slider"); @@ -1060,6 +1088,12 @@ return addNodeTo(handle.firstChild, options.cssClasses.tooltip); } + // Disable the slider dragging if any handle is disabled + function isHandleDisabled(handleNumber) { + var handleOrigin = scope_Handles[handleNumber]; + return handleOrigin.hasAttribute("disabled"); + } + // The tooltips option is a shorthand for using the 'update' event. function tooltips() { // Tooltips are added with options.tooltips in original order. @@ -1508,7 +1542,7 @@ scope_Handles.forEach(function(handle, index) { // Disabled handles are ignored - if (handle.hasAttribute("disabled")) { + if (isHandleDisabled(index)) { return; } @@ -1584,15 +1618,16 @@ // Bind move events on document. function eventStart(event, data) { + // Ignore event if any handle is disabled + if (data.handleNumbers.some(isHandleDisabled)) { + return false; + } + var handle; + if (data.handleNumbers.length === 1) { var handleOrigin = scope_Handles[data.handleNumbers[0]]; - // Ignore 'disabled' handles - if (handleOrigin.hasAttribute("disabled")) { - return false; - } - handle = handleOrigin.children[0]; scope_ActiveHandlesCount += 1; @@ -1715,6 +1750,61 @@ }); } + // Handles keydown on focused handles + // Don't move the document when pressing arrow keys on focused handles + function eventKeydown(event, handleNumber) { + if (isHandleDisabled(handleNumber)) { + return false; + } + + var horizontalKeys = ["Left", "Right"]; + var verticalKeys = ["Down", "Up"]; + + if (options.dir && !options.ort) { + // On an right-to-left slider, the left and right keys act inverted + horizontalKeys.reverse(); + } else if (options.ort && !options.dir) { + // On a top-to-bottom slider, the up and down keys act inverted + verticalKeys.reverse(); + } + + // Strip "Arrow" for IE compatibility. https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key + var key = event.key.replace("Arrow", ""); + var isDown = key === verticalKeys[0] || key === horizontalKeys[0]; + var isUp = key === verticalKeys[1] || key === horizontalKeys[1]; + + if (!isDown && !isUp) { + return true; + } + + event.preventDefault(); + + var direction = isDown ? 0 : 1; + var steps = getNextStepsForHandle(handleNumber); + var step = steps[direction]; + + // At the edge of a slider, do nothing + if (step === null) { + return false; + } + + // No step set, use the default of 10% of the sub-range + if (step === false) { + step = scope_Spectrum.getDefaultStep(scope_Locations[handleNumber], isDown, 10); + } + + // Decrement for down steps + step = (isDown ? -1 : 1) * step; + + scope_ShouldAnimate = false; + + valueSetHandle(handleNumber, scope_Values[handleNumber] + step, true); + + scope_ShouldAnimate = true; + + return false; + } + // Attach events to several slider parts. function bindSliderEvents(behaviour) { // Attach the standard drag event to the handles. @@ -1826,10 +1916,6 @@ }); } - function toPct(pct) { - return pct + "%"; - } - // Split out the handle positioning logic so the Move event can use it, too function checkHandlePosition(reference, handleNumber, to, lookBackward, lookForward, getValue) { // For sliders with multiple handles, limit movement to the other handle. @@ -1964,7 +2050,7 @@ // Convert the value to the slider stepping/range. scope_Values[handleNumber] = scope_Spectrum.fromStepping(to); - var rule = "translate(" + inRuleOrder(toPct(transformDirection(to, 0) - scope_DirOffset), "0") + ")"; + var rule = "translate(" + inRuleOrder(transformDirection(to, 0) - scope_DirOffset + "%", "0") + ")"; scope_Handles[handleNumber].style[options.transformRule] = rule; updateConnect(handleNumber); @@ -2018,7 +2104,7 @@ // 'scale' to change the width of the element; // As the element has a width of 100%, a translation of 100% is equal to 100% of the parent (.noUi-base) var connectWidth = h - l; - var translateRule = "translate(" + inRuleOrder(toPct(transformDirection(l, connectWidth)), "0") + ")"; + var translateRule = "translate(" + inRuleOrder(transformDirection(l, connectWidth) + "%", "0") + ")"; var scaleRule = "scale(" + inRuleOrder(connectWidth / 100, "1") + ")"; scope_Connects[index].style[options.transformRule] = translateRule + " " + scaleRule; @@ -2058,7 +2144,7 @@ // Animation is optional. // Make sure the initial values were set before using animated placement. - if (options.animate && !isInit) { + if (options.animate && !isInit && scope_ShouldAnimate) { addClassFor(scope_Target, options.cssClasses.tap, options.animationDuration); } @@ -2137,57 +2223,58 @@ delete scope_Target.noUiSlider; } - // Get the current step size for the slider. - function getCurrentStep() { - // Check all locations, map them to their stepping point. - // Get the step point, then find it in the input list. - return scope_Locations.map(function(location, index) { - var nearbySteps = scope_Spectrum.getNearbySteps(location); - var value = scope_Values[index]; - var increment = nearbySteps.thisStep.step; - var decrement = null; - - // If the next value in this step moves into the next step, - // the increment is the start of the next step - the current value - if (increment !== false) { - if (value + increment > nearbySteps.stepAfter.startValue) { - increment = nearbySteps.stepAfter.startValue - value; - } - } + function getNextStepsForHandle(handleNumber) { + var location = scope_Locations[handleNumber]; + var nearbySteps = scope_Spectrum.getNearbySteps(location); + var value = scope_Values[handleNumber]; + var increment = nearbySteps.thisStep.step; + var decrement = null; - // If the value is beyond the starting point - if (value > nearbySteps.thisStep.startValue) { - decrement = nearbySteps.thisStep.step; - } else if (nearbySteps.stepBefore.step === false) { - decrement = false; + // If the next value in this step moves into the next step, + // the increment is the start of the next step - the current value + if (increment !== false) { + if (value + increment > nearbySteps.stepAfter.startValue) { + increment = nearbySteps.stepAfter.startValue - value; } + } - // If a handle is at the start of a step, it always steps back into the previous step first - else { - decrement = value - nearbySteps.stepBefore.highestStep; - } + // If the value is beyond the starting point + if (value > nearbySteps.thisStep.startValue) { + decrement = nearbySteps.thisStep.step; + } else if (nearbySteps.stepBefore.step === false) { + decrement = false; + } - // Now, if at the slider edges, there is not in/decrement - if (location === 100) { - increment = null; - } else if (location === 0) { - decrement = null; - } + // If a handle is at the start of a step, it always steps back into the previous step first + else { + decrement = value - nearbySteps.stepBefore.highestStep; + } - // As per #391, the comparison for the decrement step can have some rounding issues. - var stepDecimals = scope_Spectrum.countStepDecimals(); + // Now, if at the slider edges, there is no in/decrement + if (location === 100) { + increment = null; + } else if (location === 0) { + decrement = null; + } - // Round per #391 - if (increment !== null && increment !== false) { - increment = Number(increment.toFixed(stepDecimals)); - } + // As per #391, the comparison for the decrement step can have some rounding issues. + var stepDecimals = scope_Spectrum.countStepDecimals(); - if (decrement !== null && decrement !== false) { - decrement = Number(decrement.toFixed(stepDecimals)); - } + // Round per #391 + if (increment !== null && increment !== false) { + increment = Number(increment.toFixed(stepDecimals)); + } - return [decrement, increment]; - }); + if (decrement !== null && decrement !== false) { + decrement = Number(decrement.toFixed(stepDecimals)); + } + + return [decrement, increment]; + } + + // Get the current step size for the slider. + function getNextSteps() { + return scope_HandleNumbers.map(getNextStepsForHandle); } // Updateable: margin, limit, padding, step, range, animate, snap @@ -2232,21 +2319,37 @@ valueSet(optionsToUpdate.start || v, fireSetEvent); } - // Create the base element, initialize HTML and set classes. - // Add handles and connect elements. - scope_Base = addSlider(scope_Target); - addElements(options.connect, scope_Base); + // Initialization steps + function setupSlider() { + // Create the base element, initialize HTML and set classes. + // Add handles and connect elements. + scope_Base = addSlider(scope_Target); + + addElements(options.connect, scope_Base); + + // Attach user events. + bindSliderEvents(options.events); + + // Use the public value method to set the start values. + valueSet(options.start); + + if (options.pips) { + pips(options.pips); + } - // Attach user events. - bindSliderEvents(options.events); + if (options.tooltips) { + tooltips(); + } + + aria(); + } - // Use the public value method to set the start values. - valueSet(options.start); + setupSlider(); // noinspection JSUnusedGlobalSymbols scope_Self = { destroy: destroy, - steps: getCurrentStep, + steps: getNextSteps, on: bindEvent, off: removeEvent, get: valueGet, @@ -2264,16 +2367,6 @@ pips: pips // Issue #594 }; - if (options.pips) { - pips(options.pips); - } - - if (options.tooltips) { - tooltips(); - } - - aria(); - return scope_Self; } diff --git a/distribute/nouislider.min.css b/distribute/nouislider.min.css index ea1d6dd7..a53678d8 100644 --- a/distribute/nouislider.min.css +++ b/distribute/nouislider.min.css @@ -1,2 +1,2 @@ -/*! nouislider - 12.1.0 - 10/25/2018 */ -.noUi-target,.noUi-target *{-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent;-webkit-user-select:none;-ms-touch-action:none;touch-action:none;-ms-user-select:none;-moz-user-select:none;user-select:none;-moz-box-sizing:border-box;box-sizing:border-box}.noUi-target{position:relative;direction:ltr}.noUi-base,.noUi-connects{width:100%;height:100%;position:relative;z-index:1}.noUi-connects{overflow:hidden;z-index:0}.noUi-connect,.noUi-origin{will-change:transform;position:absolute;z-index:1;top:0;left:0;height:100%;width:100%;-ms-transform-origin:0 0;-webkit-transform-origin:0 0;transform-origin:0 0}html:not([dir=rtl]) .noUi-horizontal .noUi-origin{left:auto;right:0}.noUi-vertical .noUi-origin{width:0}.noUi-horizontal .noUi-origin{height:0}.noUi-handle{position:absolute}.noUi-state-tap .noUi-connect,.noUi-state-tap .noUi-origin{-webkit-transition:transform .3s;transition:transform .3s}.noUi-state-drag *{cursor:inherit!important}.noUi-horizontal{height:18px}.noUi-horizontal .noUi-handle{width:34px;height:28px;left:-17px;top:-6px}.noUi-vertical{width:18px}.noUi-vertical .noUi-handle{width:28px;height:34px;left:-6px;top:-17px}html:not([dir=rtl]) .noUi-horizontal .noUi-handle{right:-17px;left:auto}.noUi-target{background:#FAFAFA;border-radius:4px;border:1px solid #D3D3D3;box-shadow:inset 0 1px 1px #F0F0F0,0 3px 6px -5px #BBB}.noUi-connects{border-radius:3px}.noUi-connect{background:#3FB8AF}.noUi-draggable{cursor:ew-resize}.noUi-vertical .noUi-draggable{cursor:ns-resize}.noUi-handle{border:1px solid #D9D9D9;border-radius:3px;background:#FFF;cursor:default;box-shadow:inset 0 0 1px #FFF,inset 0 1px 7px #EBEBEB,0 3px 6px -3px #BBB}.noUi-active{box-shadow:inset 0 0 1px #FFF,inset 0 1px 7px #DDD,0 3px 6px -3px #BBB}.noUi-handle:after,.noUi-handle:before{content:"";display:block;position:absolute;height:14px;width:1px;background:#E8E7E6;left:14px;top:6px}.noUi-handle:after{left:17px}.noUi-vertical .noUi-handle:after,.noUi-vertical .noUi-handle:before{width:14px;height:1px;left:6px;top:14px}.noUi-vertical .noUi-handle:after{top:17px}[disabled] .noUi-connect{background:#B8B8B8}[disabled] .noUi-handle,[disabled].noUi-handle,[disabled].noUi-target{cursor:not-allowed}.noUi-pips,.noUi-pips *{-moz-box-sizing:border-box;box-sizing:border-box}.noUi-pips{position:absolute;color:#999}.noUi-value{position:absolute;white-space:nowrap;text-align:center}.noUi-value-sub{color:#ccc;font-size:10px}.noUi-marker{position:absolute;background:#CCC}.noUi-marker-sub{background:#AAA}.noUi-marker-large{background:#AAA}.noUi-pips-horizontal{padding:10px 0;height:80px;top:100%;left:0;width:100%}.noUi-value-horizontal{-webkit-transform:translate(-50%,50%);transform:translate(-50%,50%)}.noUi-rtl .noUi-value-horizontal{-webkit-transform:translate(50%,50%);transform:translate(50%,50%)}.noUi-marker-horizontal.noUi-marker{margin-left:-1px;width:2px;height:5px}.noUi-marker-horizontal.noUi-marker-sub{height:10px}.noUi-marker-horizontal.noUi-marker-large{height:15px}.noUi-pips-vertical{padding:0 10px;height:100%;top:0;left:100%}.noUi-value-vertical{-webkit-transform:translate(0,-50%);transform:translate(0,-50%,0);padding-left:25px}.noUi-rtl .noUi-value-vertical{-webkit-transform:translate(0,50%);transform:translate(0,50%)}.noUi-marker-vertical.noUi-marker{width:5px;height:2px;margin-top:-1px}.noUi-marker-vertical.noUi-marker-sub{width:10px}.noUi-marker-vertical.noUi-marker-large{width:15px}.noUi-tooltip{display:block;position:absolute;border:1px solid #D9D9D9;border-radius:3px;background:#fff;color:#000;padding:5px;text-align:center;white-space:nowrap}.noUi-horizontal .noUi-tooltip{-webkit-transform:translate(-50%,0);transform:translate(-50%,0);left:50%;bottom:120%}.noUi-vertical .noUi-tooltip{-webkit-transform:translate(0,-50%);transform:translate(0,-50%);top:50%;right:120%} \ No newline at end of file +/*! nouislider - 12.1.0 - 2/6/2019 */ +.noUi-target,.noUi-target *{-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent;-webkit-user-select:none;-ms-touch-action:none;touch-action:none;-ms-user-select:none;-moz-user-select:none;user-select:none;-moz-box-sizing:border-box;box-sizing:border-box}.noUi-target{position:relative;direction:ltr}.noUi-base,.noUi-connects{width:100%;height:100%;position:relative;z-index:1}.noUi-connects{overflow:hidden;z-index:0}.noUi-connect,.noUi-origin{will-change:transform;position:absolute;z-index:1;top:0;left:0;height:100%;width:100%;-ms-transform-origin:0 0;-webkit-transform-origin:0 0;transform-origin:0 0}html:not([dir=rtl]) .noUi-horizontal .noUi-origin{left:auto;right:0}.noUi-vertical .noUi-origin{width:0}.noUi-horizontal .noUi-origin{height:0}.noUi-handle{position:absolute}.noUi-touch-area{height:100%;width:100%}.noUi-state-tap .noUi-connect,.noUi-state-tap .noUi-origin{-webkit-transition:transform .3s;transition:transform .3s}.noUi-state-drag *{cursor:inherit!important}.noUi-horizontal{height:18px}.noUi-horizontal .noUi-handle{width:34px;height:28px;left:-17px;top:-6px}.noUi-vertical{width:18px}.noUi-vertical .noUi-handle{width:28px;height:34px;left:-6px;top:-17px}html:not([dir=rtl]) .noUi-horizontal .noUi-handle{right:-17px;left:auto}.noUi-target{background:#FAFAFA;border-radius:4px;border:1px solid #D3D3D3;box-shadow:inset 0 1px 1px #F0F0F0,0 3px 6px -5px #BBB}.noUi-connects{border-radius:3px}.noUi-connect{background:#3FB8AF}.noUi-draggable{cursor:ew-resize}.noUi-vertical .noUi-draggable{cursor:ns-resize}.noUi-handle{border:1px solid #D9D9D9;border-radius:3px;background:#FFF;cursor:default;box-shadow:inset 0 0 1px #FFF,inset 0 1px 7px #EBEBEB,0 3px 6px -3px #BBB}.noUi-active{box-shadow:inset 0 0 1px #FFF,inset 0 1px 7px #DDD,0 3px 6px -3px #BBB}.noUi-handle:after,.noUi-handle:before{content:"";display:block;position:absolute;height:14px;width:1px;background:#E8E7E6;left:14px;top:6px}.noUi-handle:after{left:17px}.noUi-vertical .noUi-handle:after,.noUi-vertical .noUi-handle:before{width:14px;height:1px;left:6px;top:14px}.noUi-vertical .noUi-handle:after{top:17px}[disabled] .noUi-connect{background:#B8B8B8}[disabled] .noUi-handle,[disabled].noUi-handle,[disabled].noUi-target{cursor:not-allowed}.noUi-pips,.noUi-pips *{-moz-box-sizing:border-box;box-sizing:border-box}.noUi-pips{position:absolute;color:#999}.noUi-value{position:absolute;white-space:nowrap;text-align:center}.noUi-value-sub{color:#ccc;font-size:10px}.noUi-marker{position:absolute;background:#CCC}.noUi-marker-sub{background:#AAA}.noUi-marker-large{background:#AAA}.noUi-pips-horizontal{padding:10px 0;height:80px;top:100%;left:0;width:100%}.noUi-value-horizontal{-webkit-transform:translate(-50%,50%);transform:translate(-50%,50%)}.noUi-rtl .noUi-value-horizontal{-webkit-transform:translate(50%,50%);transform:translate(50%,50%)}.noUi-marker-horizontal.noUi-marker{margin-left:-1px;width:2px;height:5px}.noUi-marker-horizontal.noUi-marker-sub{height:10px}.noUi-marker-horizontal.noUi-marker-large{height:15px}.noUi-pips-vertical{padding:0 10px;height:100%;top:0;left:100%}.noUi-value-vertical{-webkit-transform:translate(0,-50%);transform:translate(0,-50%);padding-left:25px}.noUi-rtl .noUi-value-vertical{-webkit-transform:translate(0,50%);transform:translate(0,50%)}.noUi-marker-vertical.noUi-marker{width:5px;height:2px;margin-top:-1px}.noUi-marker-vertical.noUi-marker-sub{width:10px}.noUi-marker-vertical.noUi-marker-large{width:15px}.noUi-tooltip{display:block;position:absolute;border:1px solid #D9D9D9;border-radius:3px;background:#fff;color:#000;padding:5px;text-align:center;white-space:nowrap}.noUi-horizontal .noUi-tooltip{-webkit-transform:translate(-50%,0);transform:translate(-50%,0);left:50%;bottom:120%}.noUi-vertical .noUi-tooltip{-webkit-transform:translate(0,-50%);transform:translate(0,-50%);top:50%;right:120%} \ No newline at end of file diff --git a/distribute/nouislider.min.js b/distribute/nouislider.min.js index 6e3307c2..640826ef 100644 --- a/distribute/nouislider.min.js +++ b/distribute/nouislider.min.js @@ -1,2 +1,2 @@ -/*! nouislider - 12.1.0 - 10/25/2018 */ -!function(t){"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?module.exports=t():window.noUiSlider=t()}(function(){"use strict";var et="12.1.0";function s(t){return null!=t}function rt(t){t.preventDefault()}function i(t){return"number"==typeof t&&!isNaN(t)&&isFinite(t)}function nt(t,e,r){0=e[r];)r+=1;return r}function r(t,e,r){if(r>=t.slice(-1)[0])return 100;var n,i,o=f(r,t),a=t[o-1],s=t[o],l=e[o-1],u=e[o];return l+(i=r,p(n=[a,s],n[0]<0?i+Math.abs(n[0]):i-n[0])/c(l,u))}function n(t,e,r,n){if(100===n)return n;var i,o,a=f(n,t),s=t[a-1],l=t[a];return r?(l-s)/2= 2) required for mode 'count'.");var n=e-1,i=100/n;for(e=[];n--;)e[n]=n*i;e.push(100),t="positions"}return"positions"===t?e.map(function(t){return E.fromStepping(r?E.getStep(t):t)}):"values"===t?r?e.map(function(t){return E.fromStepping(E.getStep(E.toStepping(t)))}):e:void 0}(n,t.values||!1,t.stepped||!1),s=(m=i,g=n,v=a,b={},e=E.xVal[0],r=E.xVal[E.xVal.length-1],w=S=!1,x=0,(v=v.slice().sort(function(t,e){return t-e}).filter(function(t){return!this[t]&&(this[t]=!0)},{}))[0]!==e&&(v.unshift(e),S=!0),v[v.length-1]!==r&&(v.push(r),w=!0),v.forEach(function(t,e){var r,n,i,o,a,s,l,u,c,p,f=t,d=v[e+1],h="steps"===g;if(h&&(r=E.xNumSteps[e]),r||(r=d-f),!1!==f&&void 0!==d)for(r=Math.max(r,1e-7),n=f;n<=d;n=(n+r).toFixed(7)/1){for(u=(a=(o=E.toStepping(n))-x)/m,p=a/(c=Math.round(u)),i=1;i<=c;i+=1)b[(s=x+i*p).toFixed(5)]=[E.fromStepping(s),0];l=-1r.stepAfter.startValue&&(i=r.stepAfter.startValue-n),o=n>r.thisStep.startValue?r.thisStep.step:!1!==r.stepBefore.step&&n-r.stepBefore.highestStep,100===t?i=null:0===t&&(o=null);var a=E.countStepDecimals();return null!==i&&!1!==i&&(i=Number(i.toFixed(a))),null!==o&&!1!==o&&(o=Number(o.toFixed(a))),[o,i]})},on:X,off:function(t){var n=t&&t.split(".")[0],i=n&&t.substring(n.length);Object.keys(S).forEach(function(t){var e=t.split(".")[0],r=t.substring(e.length);n&&n!==e||i&&i!==r||delete S[t]})},get:tt,set:Z,setHandle:function(t,e,r){var n=[];if(!(0<=(t=Number(t))&&t=e[r];)r+=1;return r}function r(t,e,r){if(r>=t.slice(-1)[0])return 100;var n,i,o=f(r,t),a=t[o-1],s=t[o],l=e[o-1],u=e[o];return l+(i=r,p(n=[a,s],n[0]<0?i+Math.abs(n[0]):i-n[0])/c(l,u))}function n(t,e,r,n){if(100===n)return n;var i,o,a=f(n,t),s=t[a-1],l=t[a];return r?(l-s)/2= 2) required for mode 'count'.");var n=e-1,i=100/n;for(e=[];n--;)e[n]=n*i;e.push(100),t="positions"}return"positions"===t?e.map(function(t){return E.fromStepping(r?E.getStep(t):t)}):"values"===t?r?e.map(function(t){return E.fromStepping(E.getStep(E.toStepping(t)))}):e:void 0}(n,t.values||!1,t.stepped||!1),s=(m=i,g=n,v=a,b={},e=E.xVal[0],r=E.xVal[E.xVal.length-1],w=S=!1,x=0,(v=v.slice().sort(function(t,e){return t-e}).filter(function(t){return!this[t]&&(this[t]=!0)},{}))[0]!==e&&(v.unshift(e),S=!0),v[v.length-1]!==r&&(v.push(r),w=!0),v.forEach(function(t,e){var r,n,i,o,a,s,l,u,c,p,f=t,d=v[e+1],h="steps"===g;if(h&&(r=E.xNumSteps[e]),r||(r=d-f),!1!==f&&void 0!==d)for(r=Math.max(r,1e-7),n=f;n<=d;n=(n+r).toFixed(7)/1){for(u=(a=(o=E.toStepping(n))-x)/m,p=a/(c=Math.round(u)),i=1;i<=c;i+=1)b[(s=x+i*p).toFixed(5)]=[E.fromStepping(s),0];l=-1r.stepAfter.startValue&&(i=r.stepAfter.startValue-n),o=n>r.thisStep.startValue?r.thisStep.step:!1!==r.stepBefore.step&&n-r.stepBefore.highestStep,100===e?i=null:0===e&&(o=null);var a=E.countStepDecimals();return null!==i&&!1!==i&&(i=Number(i.toFixed(a))),null!==o&&!1!==o&&(o=Number(o.toFixed(a))),[o,i]}return ct(e=y,f.cssClasses.target),0===f.dir?ct(e,f.cssClasses.ltr):ct(e,f.cssClasses.rtl),0===f.ort?ct(e,f.cssClasses.horizontal):ct(e,f.cssClasses.vertical),l=V(e,f.cssClasses.base),function(t,e){var r=V(e,f.cssClasses.connects);u=[],(a=[]).push(L(r,t[0]));for(var n=0;n + +

Horizontal - LTR

diff --git a/documentation/index.php b/documentation/index.php index d5472734..ebcbcca6 100644 --- a/documentation/index.php +++ b/documentation/index.php @@ -1,6 +1,6 @@
@@ -14,7 +14,7 @@
  • Accessible with ARIA and keyboard support
  • Responsive design friendly
  • No dependencies
  • -
  • Tested in IE9 - IE11, Edge, Chrome, Opera, Firefox & Safari
  • +
  • Tested in IE9 - IE11, Edge, Chrome, Firefox & Safari
  • Download noUiSlider diff --git a/src/nouislider.js b/src/nouislider.js index 047c4b26..7b9e3689 100644 --- a/src/nouislider.js +++ b/src/nouislider.js @@ -1756,8 +1756,8 @@ return false; } - var horizontalKeys = ["ArrowLeft", "ArrowRight"]; - var verticalKeys = ["ArrowDown", "ArrowUp"]; + var horizontalKeys = ["Left", "Right"]; + var verticalKeys = ["Down", "Up"]; if (options.dir && !options.ort) { // On an right-to-left slider, the left and right keys act inverted @@ -1767,8 +1767,10 @@ verticalKeys.reverse(); } - var isDown = event.key === verticalKeys[0] || event.key === horizontalKeys[0]; - var isUp = event.key === verticalKeys[1] || event.key === horizontalKeys[1]; + // Strip "Arrow" for IE compatibility. https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key + var key = event.key.replace("Arrow", ""); + var isDown = key === verticalKeys[0] || key === horizontalKeys[0]; + var isUp = key === verticalKeys[1] || key === horizontalKeys[1]; if (!isDown && !isUp) { return true; diff --git a/tests/slider.html b/tests/slider.html index 2f6d825c..eae97830 100644 --- a/tests/slider.html +++ b/tests/slider.html @@ -23,7 +23,18 @@ - + diff --git a/tests/slider_binding.js b/tests/slider_binding.js index 586a5b2f..4704571b 100644 --- a/tests/slider_binding.js +++ b/tests/slider_binding.js @@ -70,11 +70,7 @@ QUnit.test("Binding", function (assert) { // Do this async, because we can't click the slider before it paints. setTimeout(function () { - simulant.fire(slider.querySelectorAll('.noUi-origin')[1], 'mousedown', { - button: 1, // middle-click - clientX: offset(slider).left + 100, - clientY: offset(slider).top + 8 - }); + simulateMousedown(slider.querySelectorAll('.noUi-origin')[1], offset(slider).left + 100, offset(slider).top + 8); slider.noUiSlider.off('.namespace'); diff --git a/tests/slider_contained_handles.js b/tests/slider_contained_handles.js index b2e3751e..68c2cfdd 100644 --- a/tests/slider_contained_handles.js +++ b/tests/slider_contained_handles.js @@ -1,14 +1,3 @@ -function simulateMousedown(clickTarget, x, y) { - // Based on https://stackoverflow.com/a/19570419/1367431 - var clickEvent = document.createEvent('MouseEvents'); - clickEvent.initMouseEvent( - 'mousedown', true, true, window, 0, - 0, 0, x, y, false, false, - false, false, 0, null - ); - clickTarget.dispatchEvent(clickEvent); -} - QUnit.test("Slider with contained handles", function (assert) { document.getElementById('qunit-fixture').innerHTML = '\ diff --git a/tests/slider_three_or_more_handles.js b/tests/slider_three_or_more_handles.js index bc5a26a9..fb27ef09 100644 --- a/tests/slider_three_or_more_handles.js +++ b/tests/slider_three_or_more_handles.js @@ -1,14 +1,3 @@ -function simulateMousedown(clickTarget, x, y) { - // Based on https://stackoverflow.com/a/19570419/1367431 - var clickEvent = document.createEvent('MouseEvents'); - clickEvent.initMouseEvent( - 'mousedown', true, true, window, 0, - 0, 0, x, y, false, false, - false, false, 0, null - ); - clickTarget.dispatchEvent(clickEvent); -} - QUnit.test("Slider with three or more handles", function (assert) { document.getElementById('qunit-fixture').innerHTML = '\ @@ -64,8 +53,8 @@ QUnit.test("Slider with three or more handles", function (assert) { var middleHandleX = (middleHandlePos.right + middleHandlePos.left) / 2; var middleHandleY = (middleHandlePos.top + middleHandlePos.bottom) / 2; - var selectedByClick = document.elementFromPoint(middleHandleX, middleHandleY); - assert.strictEqual(selectedByClick, middleHandle, "Middle handle should be selected by click as rightmost handle is unmovable move") + var selectedByClick = document.elementFromPoint(middleHandleX, middleHandleY).parentElement; + assert.strictEqual(selectedByClick, middleHandle, "Middle handle should be selected by click as rightmost handle is unmovable move"); // xnakos also spotted a bug where clicking