From 0996f6d2a6efe5a3afff6e82b99bcf897903b640 Mon Sep 17 00:00:00 2001 From: jedrzejchalubek Date: Tue, 24 Apr 2018 20:37:09 +0200 Subject: [PATCH] Create special function for merging instance options that can handle nesteded settings (#205) --- dist/glide.esm.js | 55 +++++++++++++----------------- dist/glide.js | 55 +++++++++++++----------------- dist/glide.min.js | 2 +- dist/glide.modular.esm.js | 55 +++++++++++++----------------- src/components/breakpoints.js | 6 ++-- src/index.js | 3 +- src/utils/object.js | 26 ++++++++++++++ tests/integration/instance.test.js | 3 +- tests/unit/object.test.js | 4 +-- 9 files changed, 105 insertions(+), 104 deletions(-) diff --git a/dist/glide.esm.js b/dist/glide.esm.js index fd9ed1bf..423b3ab7 100644 --- a/dist/glide.esm.js +++ b/dist/glide.esm.js @@ -244,20 +244,7 @@ var createClass = function () { -var defineProperty = function (obj, key, value) { - if (key in obj) { - Object.defineProperty(obj, key, { - value: value, - enumerable: true, - configurable: true, - writable: true - }); - } else { - obj[key] = value; - } - return obj; -}; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { @@ -463,25 +450,29 @@ function sortKeys(obj) { } /** - * Deeply merges two objects. + * Merges passed settings object with default options. * - * @param {Object} target - * @param {Object} source + * @param {Object} defaults + * @param {Object} settings * @return {Object} */ -function merge(target, source) { - if (isObject(target) && isObject(source)) { - Object.keys(source).forEach(function (key) { - if (isObject(source[key])) { - if (!target[key]) _extends(target, defineProperty({}, key, {})); - merge(target[key], source[key]); - } else { - _extends(target, defineProperty({}, key, source[key])); - } - }); +function mergeOptions(defaults, settings) { + var options = _extends({}, defaults, settings); + + // `Object.assign` do not deeply merge objects, so we + // have to do it manually for every nested object + // in options. Although it does not look smart, + // it's smaller and faster than some fancy + // merging deep-merge algorithm script. + if (settings.hasOwnProperty('classes')) { + options.classes = _extends({}, defaults.classes, settings.classes); + + if (settings.classes.hasOwnProperty('direction')) { + options.classes.direction = _extends({}, defaults.classes.direction, settings.classes.direction); + } } - return _extends({}, target); + return options; } var EventsBus = function () { @@ -562,7 +553,8 @@ var EventsBus = function () { }(); var Glide$2 = function () { - /** * Construct glide. + /** + * Construct glide. * * @param {String} selector * @param {Object} options @@ -575,9 +567,8 @@ var Glide$2 = function () { this._e = new EventsBus(); this.disabled = false; - this.selector = selector; - this.settings = merge(defaults, options); + this.settings = mergeOptions(defaults, options); this.index = this.settings.startAt; } @@ -3525,14 +3516,14 @@ var Breakpoints = function (Glide, Components, Events) { * Overwrite instance settings with currently matching breakpoint settings. * This happens right after component initialization. */ - settings = _extends(settings, Breakpoints.match(points)); + _extends(settings, Breakpoints.match(points)); /** * Update glide with settings of matched brekpoint: * - window resize to update slider */ Binder.on('resize', window, throttle(function () { - settings = _extends(settings, Breakpoints.match(points)); + _extends(settings, Breakpoints.match(points)); }, Glide.settings.throttle)); /** diff --git a/dist/glide.js b/dist/glide.js index 88123bd7..207916e0 100644 --- a/dist/glide.js +++ b/dist/glide.js @@ -250,20 +250,7 @@ var createClass = function () { -var defineProperty = function (obj, key, value) { - if (key in obj) { - Object.defineProperty(obj, key, { - value: value, - enumerable: true, - configurable: true, - writable: true - }); - } else { - obj[key] = value; - } - return obj; -}; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { @@ -469,25 +456,29 @@ function sortKeys(obj) { } /** - * Deeply merges two objects. + * Merges passed settings object with default options. * - * @param {Object} target - * @param {Object} source + * @param {Object} defaults + * @param {Object} settings * @return {Object} */ -function merge(target, source) { - if (isObject(target) && isObject(source)) { - Object.keys(source).forEach(function (key) { - if (isObject(source[key])) { - if (!target[key]) _extends(target, defineProperty({}, key, {})); - merge(target[key], source[key]); - } else { - _extends(target, defineProperty({}, key, source[key])); - } - }); +function mergeOptions(defaults, settings) { + var options = _extends({}, defaults, settings); + + // `Object.assign` do not deeply merge objects, so we + // have to do it manually for every nested object + // in options. Although it does not look smart, + // it's smaller and faster than some fancy + // merging deep-merge algorithm script. + if (settings.hasOwnProperty('classes')) { + options.classes = _extends({}, defaults.classes, settings.classes); + + if (settings.classes.hasOwnProperty('direction')) { + options.classes.direction = _extends({}, defaults.classes.direction, settings.classes.direction); + } } - return _extends({}, target); + return options; } var EventsBus = function () { @@ -568,7 +559,8 @@ var EventsBus = function () { }(); var Glide$2 = function () { - /** * Construct glide. + /** + * Construct glide. * * @param {String} selector * @param {Object} options @@ -581,9 +573,8 @@ var Glide$2 = function () { this._e = new EventsBus(); this.disabled = false; - this.selector = selector; - this.settings = merge(defaults, options); + this.settings = mergeOptions(defaults, options); this.index = this.settings.startAt; } @@ -3531,14 +3522,14 @@ var Breakpoints = function (Glide, Components, Events) { * Overwrite instance settings with currently matching breakpoint settings. * This happens right after component initialization. */ - settings = _extends(settings, Breakpoints.match(points)); + _extends(settings, Breakpoints.match(points)); /** * Update glide with settings of matched brekpoint: * - window resize to update slider */ Binder.on('resize', window, throttle(function () { - settings = _extends(settings, Breakpoints.match(points)); + _extends(settings, Breakpoints.match(points)); }, Glide.settings.throttle)); /** diff --git a/dist/glide.min.js b/dist/glide.min.js index 9f572103..757a3d06 100644 --- a/dist/glide.min.js +++ b/dist/glide.min.js @@ -3,4 +3,4 @@ * (c) 2013-2018 Jędrzej Chałubek (http://jedrzejchalubek.com/) * Released under the MIT License. */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Glide=e()}(this,function(){"use strict";var i={type:"slider",startAt:0,perView:1,focusAt:0,gap:10,autoplay:!1,hoverpause:!0,keyboard:!0,swipeThreshold:80,dragThreshold:120,perTouch:!1,touchRatio:.5,touchAngle:45,animationDuration:400,rewindDuration:800,animationTimingFunc:"cubic-bezier(0.165, 0.840, 0.440, 1.000)",throttle:10,direction:"ltr",peek:0,breakpoints:{},classes:{direction:{ltr:"glide--ltr",rtl:"glide--rtl"},slider:"glide--slider",carousel:"glide--carousel",swipeable:"glide--swipeable",dragging:"glide--dragging",cloneSlide:"glide__slide--clone",activeNav:"glide__bullet--active",activeSlide:"glide__slide--active",disabledArrow:"glide__arrow--disabled"}};var n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},o=function(){function i(t,e){for(var n=0;n":"<","<":">","=":"="},A=[function(e,n){return{modify:function(t){return t+n.Gaps.value*e.index}}},function(t,e){return{modify:function(t){return t+e.Clones.grow/2}}},function(n,i){return{modify:function(t){if(0<=n.settings.focusAt){var e=i.Peek.value;return l(e)?t-e.before:t-e}return t}}},function(o,s){return{modify:function(t){var e=s.Gaps.value,n=s.Sizes.width,i=o.settings.focusAt,r=s.Sizes.slideWidth;return"center"===i?t-(n/2-r/2):t-r*i-e*i}}},function(t,e){return{modify:function(t){return e.Direction.is("rtl")?-t:t}}}],M=["touchstart","mousedown"],C=["touchmove","mousemove"],z=["touchend","touchcancel","mouseup","mouseleave"],D=["mousedown","mousemove","mouseup","mouseleave"];function j(t){return l(t)?(n=t,Object.keys(n).sort().reduce(function(t,e){return t[e]=n[e],t[e],t},{})):{};var n}var L={Html:function(e,t){var n={mount:function(){this.root=e.selector,this.track=this.root.querySelector(H),this.slides=Array.from(this.wrapper.children).filter(function(t){return!t.classList.contains(e.settings.classes.cloneSlide)})}};return m(n,"root",{get:function(){return n._r},set:function(t){c(t)&&(t=document.querySelector(t)),S(t)&&(n._r=t)}}),m(n,"track",{get:function(){return n._t},set:function(t){S(t)&&(n._t=t)}}),m(n,"wrapper",{get:function(){return n.track.children[0]}}),n},Translate:function(r,o,s){var u={set:function(t){var n,i,e=(n=r,i=o,{mutate:function(t){for(var e=0;e")?(o.Transition.after(function(){s.emit("translate.jump"),u.set(0)}),u.set(i*n+e*n)):u.set(t.movement)}),s.on("destroy",function(){u.remove()}),u},Transition:function(n,e,t){var i=!1,r={compose:function(t){var e=n.settings;return i?t+" 0ms "+e.animationTimingFunc:t+" "+this.duration+"ms "+e.animationTimingFunc},set:function(){var t=0"))&&(e._o=!1,s.emit("run.offset",e.move)),s.emit("run.after",e.move),o.enable()}))},calculate:function(){var t=this.move,e=this.length,n=t.steps,i=t.direction,r=f(p(n))&&0!==p(n);switch(i){case">":">"===n?o.index=e:this.isEnd()?(this._o=!0,o.index=0,s.emit("run.end",t)):r?o.index+=Math.min(e-o.index,-p(n)):o.index++;break;case"<":"<"===n?o.index=0:this.isStart()?(this._o=!0,o.index=e,s.emit("run.start",t)):r?o.index-=Math.min(o.index,p(n)):o.index--;break;case"=":o.index=n}},isStart:function(){return 0===o.index},isEnd:function(){return o.index===this.length},isOffset:function(t){return this._o&&this.move.direction===t}};return m(t,"move",{get:function(){return this._m},set:function(t){this._m={direction:t.substr(0,1),steps:t.substr(1)?t.substr(1):0}}}),m(t,"length",{get:function(){return n.Html.slides.length-1}}),m(t,"offset",{get:function(){return this._o}}),t},Swipe:function(c,l,f){var e=new T,d=0,h=0,v=0,n=!1,t={mount:function(){this.bindSwipeStart()},start:function(t){if(!n&&!c.disabled){this.disable();var e=this.touches(t);d=null,h=p(e.pageX),v=p(e.pageY),this.bindSwipeMove(),this.bindSwipeEnd(),f.emit("swipe.start")}},move:function(t){if(!c.disabled){var e=c.settings,n=this.touches(t),i=p(n.pageX)-h,r=p(n.pageY)-v,o=Math.abs(i<<2),s=Math.abs(r<<2),u=Math.sqrt(o+s),a=Math.sqrt(s);if(180*(d=Math.asin(a/u))/Math.PI"+s))):l.Move.make(),l.Html.root.classList.remove(e.classes.dragging),this.unbindSwipeMove(),this.unbindSwipeEnd(),f.emit("swipe.end")}},bindSwipeStart:function(){var t=c.settings;t.swipeThreshold&&e.on(M[0],l.Html.wrapper,this.start.bind(this)),t.dragThreshold&&e.on(M[1],l.Html.wrapper,this.start.bind(this))},unbindSwipeStart:function(){e.off(M[0],l.Html.wrapper),e.off(M[1],l.Html.wrapper)},bindSwipeMove:function(){e.on(C,l.Html.wrapper,w(this.move.bind(this),c.settings.throttle))},unbindSwipeMove:function(){e.off(C,l.Html.wrapper)},bindSwipeEnd:function(){e.on(z,l.Html.wrapper,this.end.bind(this))},unbindSwipeEnd:function(){e.off(z,l.Html.wrapper)},touches:function(t){return D.includes(t.type)?t:t.touches[0]||t.changedTouches[0]},threshold:function(t){var e=c.settings;return D.includes(t.type)?e.dragThreshold:e.swipeThreshold},enable:function(){return n=!1,l.Transition.enable(),this},disable:function(){return n=!0,l.Transition.disable(),this}};return f.on("build.after",function(){l.Html.root.classList.add(c.settings.classes.swipeable)}),f.on("destroy",function(){t.unbindSwipeStart(),t.unbindSwipeMove(),t.unbindSwipeEnd(),e.destroy()}),t},Images:function(t,e,n){var i=new T,r={mount:function(){this.bind()},bind:function(){i.on("dragstart",e.Html.wrapper,this.dragstart)},unbind:function(){i.off("dragstart",e.Html.wrapper)},dragstart:function(t){t.preventDefault()}};return n.on("destroy",function(){r.unbind(),i.destroy()}),r},Anchors:function(t,e,n){var i=new T,r=!1,o=!1,s={mount:function(){this._a=e.Html.wrapper.querySelectorAll("a"),this.bind()},bind:function(){i.on("click",e.Html.wrapper,this.click)},unbind:function(){i.off("click",e.Html.wrapper)},click:function(t){t.stopPropagation(),o&&t.preventDefault()},detach:function(){if(o=!0,!r){for(var t=0;t")),37===t.keyCode&&e.Run.make(e.Direction.resolve("<"))}};return n.on(["destroy","update"],function(){r.unbind()}),n.on("update",function(){r.mount()}),n.on("destroy",function(){i.destroy()}),r},Autoplay:function(e,n,t){var i=new T,r={mount:function(){this.start(),e.settings.hoverpause&&this.bind()},start:function(){var t=this;e.settings.autoplay&&h(this._i)&&(this._i=setInterval(function(){t.stop(),n.Run.make(">"),t.start()},this.time))},stop:function(){this._i=clearInterval(this._i)},bind:function(){var t=this;i.on("mouseover",n.Html.root,function(){t.stop()}),i.on("mouseout",n.Html.root,function(){t.start()})},unbind:function(){i.off(["mouseover","mouseout"],n.Html.root)}};return m(r,"time",{get:function(){var t=n.Html.slides[e.index].getAttribute("data-glide-autoplay");return p(t||e.settings.autoplay)}}),t.on(["destroy","update"],function(){r.unbind()}),t.on(["run.before","pause","destroy","swipe.start","update"],function(){r.stop()}),t.on(["run.after","play","swipe.end"],function(){r.start()}),t.on("update",function(){r.mount()}),t.on("destroy",function(){i.destroy()}),r},Breakpoints:function(t,e,n){var i=new T,r=t.settings,o=r.breakpoints;o=j(o);var s=a({},r),u={match:function(t){if(void 0!==window.matchMedia)for(var e in t)if(t.hasOwnProperty(e)&&window.matchMedia("(max-width: "+e+"px)").matches)return t[e];return s}};return r=a(r,u.match(o)),i.on("resize",window,w(function(){r=a(r,u.match(o))},t.settings.throttle)),n.on("update",function(){o=j(o),s=a({},r)}),n.on("destroy",function(){i.off("resize",window)}),u}};return function(t){function e(){return r(this,e),u(this,(e.__proto__||Object.getPrototypeOf(e)).apply(this,arguments))}return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}(e,y),o(e,[{key:"mount",value:function(){var t=0":"<","<":">","=":"="},S=[function(e,n){return{modify:function(t){return t+n.Gaps.value*e.index}}},function(t,e){return{modify:function(t){return t+e.Clones.grow/2}}},function(n,i){return{modify:function(t){if(0<=n.settings.focusAt){var e=i.Peek.value;return c(e)?t-e.before:t-e}return t}}},function(r,s){return{modify:function(t){var e=s.Gaps.value,n=s.Sizes.width,i=r.settings.focusAt,o=s.Sizes.slideWidth;return"center"===i?t-(n/2-o/2):t-o*i-e*i}}},function(t,e){return{modify:function(t){return e.Direction.is("rtl")?-t:t}}}],H=["touchstart","mousedown"],T=["touchmove","mousemove"],x=["touchend","touchcancel","mouseup","mouseleave"],O=["mousedown","mousemove","mouseup","mouseleave"];function A(t){return c(t)?(n=t,Object.keys(n).sort().reduce(function(t,e){return t[e]=n[e],t[e],t},{})):{};var n}var M={Html:function(e,t){var n={mount:function(){this.root=e.selector,this.track=this.root.querySelector(w),this.slides=Array.from(this.wrapper.children).filter(function(t){return!t.classList.contains(e.settings.classes.cloneSlide)})}};return n},Translate:function(o,r,s){var u={set:function(t){var n,i,e=(n=o,i=r,{mutate:function(t){for(var e=0;e")?(r.Transition.after(function(){s.emit("translate.jump"),u.set(0)}),u.set(i*n+e*n)):u.set(t.movement)}),s.on("destroy",function(){u.remove()}),u},Transition:function(n,e,t){var i=!1,o={compose:function(t){var e=n.settings;return i?t+" 0ms "+e.animationTimingFunc:t+" "+this.duration+"ms "+e.animationTimingFunc},set:function(){var t=0"))&&(e._o=!1,s.emit("run.offset",e.move)),s.emit("run.after",e.move),r.enable()}))},calculate:function(){var t=this.move,e=this.length,n=t.steps,i=t.direction,o="number"==typeof v(n)&&0!==v(n);switch(i){case">":">"===n?r.index=e:this.isEnd()?(this._o=!0,r.index=0,s.emit("run.end",t)):o?r.index+=Math.min(e-r.index,-v(n)):r.index++;break;case"<":"<"===n?r.index=0:this.isStart()?(this._o=!0,r.index=e,s.emit("run.start",t)):o?r.index-=Math.min(r.index,v(n)):r.index--;break;case"=":r.index=n}},isStart:function(){return 0===r.index},isEnd:function(){return r.index===this.length},isOffset:function(t){return this._o&&this.move.direction===t}};return t},Swipe:function(c,l,f){var e=new k,d=0,h=0,p=0,n=!1,t={mount:function(){this.bindSwipeStart()},start:function(t){if(!n&&!c.disabled){this.disable();var e=this.touches(t);d=null,h=v(e.pageX),p=v(e.pageY),this.bindSwipeMove(),this.bindSwipeEnd(),f.emit("swipe.start")}},move:function(t){if(!c.disabled){var e=c.settings,n=this.touches(t),i=v(n.pageX)-h,o=v(n.pageY)-p,r=Math.abs(i<<2),s=Math.abs(o<<2),u=Math.sqrt(r+s),a=Math.sqrt(s);if(180*(d=Math.asin(a/u))/Math.PI"+s))):l.Move.make(),l.Html.root.classList.remove(e.classes.dragging),this.unbindSwipeMove(),this.unbindSwipeEnd(),f.emit("swipe.end")}},bindSwipeStart:function(){var t=c.settings;t.swipeThreshold&&e.on(H[0],l.Html.wrapper,this.start.bind(this)),t.dragThreshold&&e.on(H[1],l.Html.wrapper,this.start.bind(this))},unbindSwipeStart:function(){e.off(H[0],l.Html.wrapper),e.off(H[1],l.Html.wrapper)},bindSwipeMove:function(){e.on(T,l.Html.wrapper,g(this.move.bind(this),c.settings.throttle))},unbindSwipeMove:function(){e.off(T,l.Html.wrapper)},bindSwipeEnd:function(){e.on(x,l.Html.wrapper,this.end.bind(this))},unbindSwipeEnd:function(){e.off(x,l.Html.wrapper)},touches:function(t){return O.includes(t.type)?t:t.touches[0]||t.changedTouches[0]},threshold:function(t){var e=c.settings;return O.includes(t.type)?e.dragThreshold:e.swipeThreshold},enable:function(){return n=!1,l.Transition.enable(),this},disable:function(){return n=!0,l.Transition.disable(),this}};return f.on("build.after",function(){l.Html.root.classList.add(c.settings.classes.swipeable)}),f.on("destroy",function(){t.unbindSwipeStart(),t.unbindSwipeMove(),t.unbindSwipeEnd(),e.destroy()}),t},Images:function(t,e,n){var i=new k,o={mount:function(){this.bind()},bind:function(){i.on("dragstart",e.Html.wrapper,this.dragstart)},unbind:function(){i.off("dragstart",e.Html.wrapper)},dragstart:function(t){t.preventDefault()}};return n.on("destroy",function(){o.unbind(),i.destroy()}),o},Anchors:function(t,e,n){var i=new k,o=!1,r=!1,s={mount:function(){this._a=e.Html.wrapper.querySelectorAll("a"),this.bind()},bind:function(){i.on("click",e.Html.wrapper,this.click)},unbind:function(){i.off("click",e.Html.wrapper)},click:function(t){t.stopPropagation(),r&&t.preventDefault()},detach:function(){if(r=!0,!o){for(var t=0;t")),37===t.keyCode&&e.Run.make(e.Direction.resolve("<"))}};return n.on(["destroy","update"],function(){o.unbind()}),n.on("update",function(){o.mount()}),n.on("destroy",function(){i.destroy()}),o},Autoplay:function(e,n,t){var i=new k,o={mount:function(){this.start(),e.settings.hoverpause&&this.bind()},start:function(){var t=this;e.settings.autoplay&&f(this._i)&&(this._i=setInterval(function(){t.stop(),n.Run.make(">"),t.start()},this.time))},stop:function(){this._i=clearInterval(this._i)},bind:function(){var t=this;i.on("mouseover",n.Html.root,function(){t.stop()}),i.on("mouseout",n.Html.root,function(){t.start()})},unbind:function(){i.off(["mouseover","mouseout"],n.Html.root)}};return t.on(["destroy","update"],function(){o.unbind()}),t.on(["run.before","pause","destroy","swipe.start","update"],function(){o.stop()}),t.on(["run.after","play","swipe.end"],function(){o.start()}),t.on("update",function(){o.mount()}),t.on("destroy",function(){i.destroy()}),o},Breakpoints:function(t,e,n){var i=new k,o=t.settings,r=o.breakpoints;r=A(r);var s=a({},o),u={match:function(t){if(void 0!==window.matchMedia)for(var e in t)if(t.hasOwnProperty(e)&&window.matchMedia("(max-width: "+e+"px)").matches)return t[e];return s}};return a(o,u.match(r)),i.on("resize",window,g(function(){a(o,u.match(r))},t.settings.throttle)),n.on("update",function(){r=A(r),s=a({},o)}),n.on("destroy",function(){i.off("resize",window)}),u}};return function(t){function e(){return u(this,e),o(this,(e.__proto__||Object.getPrototypeOf(e)).apply(this,arguments))}return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}(e,p),i(e,[{key:"mount",value:function(){var t=0 { - settings = Object.assign(settings, Breakpoints.match(points)) + Object.assign(settings, Breakpoints.match(points)) }, Glide.settings.throttle)) /** diff --git a/src/index.js b/src/index.js index bbd0d092..975e8a9a 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,7 @@ import defaults from './defaults' import { warn } from './utils/log' import { mount } from './core/index' +import { mergeOptions } from './utils/object' import { toInt, isObject } from './utils/unit' import EventsBus from './core/event/events-bus' @@ -18,7 +19,7 @@ export default class Glide { this.disabled = false this.selector = selector - this.settings = Object.assign({}, defaults, options) + this.settings = mergeOptions(defaults, options) this.index = this.settings.startAt } diff --git a/src/utils/object.js b/src/utils/object.js index 7550c1dc..dce08918 100644 --- a/src/utils/object.js +++ b/src/utils/object.js @@ -23,3 +23,29 @@ export function sortKeys (obj) { return (r[k], r) }, {}) } + +/** + * Merges passed settings object with default options. + * + * @param {Object} defaults + * @param {Object} settings + * @return {Object} + */ +export function mergeOptions (defaults, settings) { + let options = Object.assign({}, defaults, settings) + + // `Object.assign` do not deeply merge objects, so we + // have to do it manually for every nested object + // in options. Although it does not look smart, + // it's smaller and faster than some fancy + // merging deep-merge algorithm script. + if (settings.hasOwnProperty('classes')) { + options.classes = Object.assign({}, defaults.classes, settings.classes) + + if (settings.classes.hasOwnProperty('direction')) { + options.classes.direction = Object.assign({}, defaults.classes.direction, settings.classes.direction) + } + } + + return options +} diff --git a/tests/integration/instance.test.js b/tests/integration/instance.test.js index 297d42b3..ebfee3b3 100644 --- a/tests/integration/instance.test.js +++ b/tests/integration/instance.test.js @@ -1,5 +1,6 @@ import html from '../fixtures/html' import defaults from '../../src/defaults' +import { mergeOptions } from '../../src/utils/object' import Glide from '../../entry/entry-complete' @@ -37,7 +38,7 @@ describe('Glide', () => { } }).mount() - expect(glide.settings).toEqual(Object.assign(defaults, { + expect(glide.settings).toEqual(mergeOptions(defaults, { startAt: 2, classes: { direction: { diff --git a/tests/unit/object.test.js b/tests/unit/object.test.js index 53e4685a..1822c22e 100644 --- a/tests/unit/object.test.js +++ b/tests/unit/object.test.js @@ -1,4 +1,4 @@ -import { define, options } from '../../src/utils/object' +import { define, mergeOptions } from '../../src/utils/object' describe('Function', () => { test('`define` should create object getters and setters', () => { @@ -22,7 +22,7 @@ describe('Function', () => { }) test('`merge` should deep merge defaults and options object', () => { - let obj = options( + let obj = mergeOptions( { a: 1, b: 2,