From 5024cca7d9ab9cd1a27287c46cedb7ad3c2cb48b Mon Sep 17 00:00:00 2001 From: Antonio Laguna Date: Thu, 20 Apr 2017 12:25:51 +0200 Subject: [PATCH 1/5] 1.3.0 --- package.json | 2 +- static/js/webslides.js | 8 ++------ static/js/webslides.min.js | 4 ++-- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 7f417fc..da1a8c9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "webslides", - "version": "1.2.1", + "version": "1.3.0", "description": "Making HTML presentations easy", "main": "index.js", "repository": { diff --git a/static/js/webslides.js b/static/js/webslides.js index ed43690..4d97c37 100644 --- a/static/js/webslides.js +++ b/static/js/webslides.js @@ -1,7 +1,7 @@ /*! * Name: WebSlides - * Version: 1.2.1 - * Date: 2017-04-19 + * Version: 1.3.0 + * Date: 2017-04-20 * Description: Making HTML presentations easy * URL: https://github.com/webslides/webslides#readme * Credits: @jlantunez, @LuisSacristan, @Belelros @@ -1102,10 +1102,6 @@ var WebSlides = function () { /** * Registers a plugin to be loaded when the instance is created. It allows * (on purpose) to replace default plugins. - * Those being: - * - Navigation - * - Hash - * - Keyboard * @param {!string} key They key under which it'll be stored inside of the * instance, inside the plugins dict. * @param {!Function} cto Plugin constructor. diff --git a/static/js/webslides.min.js b/static/js/webslides.min.js index 0ff696b..271a54f 100644 --- a/static/js/webslides.min.js +++ b/static/js/webslides.min.js @@ -1,7 +1,7 @@ /*! * Name: WebSlides - * Version: 1.2.1 - * Date: 2017-04-19 + * Version: 1.3.0 + * Date: 2017-04-20 * Description: Making HTML presentations easy * URL: https://github.com/webslides/webslides#readme * Credits: @jlantunez, @LuisSacristan, @Belelros From d592006bfa04ff676382ab8fad4ede770b92614a Mon Sep 17 00:00:00 2001 From: Antonio Laguna Date: Wed, 26 Apr 2017 20:07:15 +0200 Subject: [PATCH 2/5] Ensuring the navigation works on any iOS device Fixes #79 --- src/js/utils/mobile-detector.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/utils/mobile-detector.js b/src/js/utils/mobile-detector.js index 9beb94d..558e2a4 100644 --- a/src/js/utils/mobile-detector.js +++ b/src/js/utils/mobile-detector.js @@ -26,7 +26,7 @@ export default class MobileDetector { * @return {Boolean} */ static isiOS() { - return !!UA.match(/iPhone/i); + return !!UA.match(/iPad|iPhone|iPod/i); } /** From f6ac24007a15af0922f1117281e0b9c29763d0e3 Mon Sep 17 00:00:00 2001 From: Antonio Laguna Date: Wed, 26 Apr 2017 20:08:04 +0200 Subject: [PATCH 3/5] 1.3.1 --- package.json | 2 +- static/js/webslides.js | 6 +++--- static/js/webslides.min.js | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index da1a8c9..6248335 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "webslides", - "version": "1.3.0", + "version": "1.3.1", "description": "Making HTML presentations easy", "main": "index.js", "repository": { diff --git a/static/js/webslides.js b/static/js/webslides.js index 4d97c37..35da68e 100644 --- a/static/js/webslides.js +++ b/static/js/webslides.js @@ -1,7 +1,7 @@ /*! * Name: WebSlides - * Version: 1.3.0 - * Date: 2017-04-20 + * Version: 1.3.1 + * Date: 2017-04-26 * Description: Making HTML presentations easy * URL: https://github.com/webslides/webslides#readme * Credits: @jlantunez, @LuisSacristan, @Belelros @@ -587,7 +587,7 @@ var MobileDetector = function () { }, { key: "isiOS", value: function isiOS() { - return !!UA.match(/iPhone/i); + return !!UA.match(/iPad|iPhone|iPod/i); } /** diff --git a/static/js/webslides.min.js b/static/js/webslides.min.js index 271a54f..b331365 100644 --- a/static/js/webslides.min.js +++ b/static/js/webslides.min.js @@ -1,9 +1,9 @@ /*! * Name: WebSlides - * Version: 1.3.0 - * Date: 2017-04-20 + * Version: 1.3.1 + * Date: 2017-04-26 * Description: Making HTML presentations easy * URL: https://github.com/webslides/webslides#readme * Credits: @jlantunez, @LuisSacristan, @Belelros */ -!function(e){function t(i){if(n[i])return n[i].exports;var r=n[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,t),r.l=!0,r.exports}var n={};t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,i){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:i})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="/static/js/",t(t.s=5)}([function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",i=document.createElement(e);return i.id=t,n&&(i.textContent=n),i}},{key:"once",value:function(e,t,n){var i=function i(r){r.target===e&&(e.removeEventListener(t,i),n(r))};e.addEventListener(t,i,!1)}},{key:"getTransitionEvent",value:function(){if(s)return s;for(var e=document.createElement("ws"),t={transition:"transitionend",OTransition:"oTransitionEnd",MozTransition:"transitionend",WebkitTransition:"webkitTransitionEnd"},n=Object.keys(t),i=0,r=n.length;i2&&void 0!==arguments[2]?arguments[2]:{},i=new o.default(t,{detail:n});e.dispatchEvent(i)}},{key:"toArray",value:function(e){return[].slice.call(e)}},{key:"isFocusableElement",value:function(){var e=!1;if(document.activeElement){var t="inherit"!==document.activeElement.contentEditable;e=["INPUT","SELECT","OPTION","TEXTAREA"].indexOf(document.activeElement.tagName)>-1||t}return e}}]),e}();t.default=u},function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0}),t.Events=t.default=void 0;var r=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{},n=t.autoslide,i=void 0!==n&&n,a=t.changeOnClick,o=void 0!==a&&a,s=t.loop,l=void 0===s||s,u=t.minWheelDelta,d=void 0===u?40:u,c=t.scrollWait,f=void 0===c?450:c,h=t.slideOffset,y=void 0===h?50:h;if(r(this,e),this.el=document.getElementById("webslides"),!this.el)throw new Error("Couldn't find the webslides container!");this.isMoving=!1,this.slides=null,this.currentSlideI_=-1,this.currentSlide_=null,this.maxSlide_=0,this.isVertical=this.el.classList.contains(v.VERTICAL),this.plugins={},this.options={autoslide:i,changeOnClick:o,loop:l,minWheelDelta:d,scrollWait:f,slideOffset:y},this.initialised=!1,this.removeChildren_(),this.grabSlides_(),this.createPlugins_(),this.initSlides_(),this.onInit_()}return a(e,[{key:"removeChildren_",value:function(){for(var e=this.el.childNodes,t=e.length;t--;){var n=e[t];u.default.isCandidate(n)||this.el.removeChild(n)}}},{key:"createPlugins_",value:function(){var e=this;Object.keys(y).forEach(function(t){var n=y[t];e.plugins[t]=new n(e)})}},{key:"onInit_",value:function(){this.initialised=!0,c.default.fireEvent(this.el,"ws:init"),document.documentElement.classList.add(v.READY)}},{key:"grabSlides_",value:function(){this.slides=c.default.toArray(this.el.childNodes).map(function(e,t){return new u.default(e,t)}),this.maxSlide_=this.slides.length}},{key:"goToSlide",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;if(this.isValidIndexSlide_(e)&&!this.isMoving&&this.currentSlideI_!==e){this.isMoving=!0;var n=!1;null!==t?n=t:this.currentSlideI_>=0&&(n=e>this.currentSlideI_);var i=this.slides[e];null===this.currentSlide_||!this.isVertical||this.plugins.touch&&this.plugins.touch.isEnabled?this.transitionToSlide_(n,i,this.onSlideChange_):this.scrollTransitionToSlide_(n,i,this.onSlideChange_)}}},{key:"scrollTransitionToSlide_",value:function(e,t,n){var i=this;this.el.style.overflow="hidden",e?t.show():(t.moveBeforeFirst(),t.show(),(0,h.default)(this.currentSlide_.el.offsetTop,0)),(0,h.default)(t.el.offsetTop,500,function(){i.currentSlide_.hide(),e&&i.currentSlide_.moveAfterLast(),i.el.style.overflow="auto",setTimeout(function(){n.call(i,t)},150)})}},{key:"transitionToSlide_",value:function(e,t,n){var i=this;(0,h.default)(0,0);var r="slideInRight";e||(t.moveBeforeFirst(),r="slideInLeft"),this.currentSlide_&&(e&&this.currentSlide_.moveAfterLast(),this.currentSlide_.hide()),t.show(),this.initialised&&this.plugins.touch&&this.plugins.touch.isEnabled?(c.default.once(t.el,c.default.getAnimationEvent(),function(){t.el.classList.remove(r),n.call(i,t)}),t.el.classList.add(r)):n.call(this,t)}},{key:"onSlideChange_",value:function(e){this.currentSlide_&&this.currentSlide_.disable(),this.currentSlide_=e,this.currentSlideI_=e.i,this.currentSlide_.enable(),this.isMoving=!1,c.default.fireEvent(this.el,"ws:slide-change",{slides:this.maxSlide_,currentSlide0:this.currentSlideI_,currentSlide:this.currentSlideI_+1})}},{key:"goNext",value:function(){var e=this.currentSlideI_+1;if(e>=this.maxSlide_){if(!this.options.loop)return;e=0}this.goToSlide(e,!0)}},{key:"goPrev",value:function(){var e=this.currentSlideI_-1;if(e<0){if(!this.options.loop)return;e=this.maxSlide_-1}this.goToSlide(e,!1)}},{key:"isValidIndexSlide_",value:function(e){return e>=0&&e=this.maxSlide_)&&(e=0),0!==e)for(var t=0;t0&&(this.interval_=setInterval(this.ws_.goNext.bind(this.ws_),e))}},{key:"stop",value:function(){this.interval_&&(clearInterval(this.interval_),this.interval_=null)}}]),e}();t.default=s},function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;nMath.abs(t);if(this.isGoingUp_=t<0,this.isGoingLeft_=n<0,r){if(i)return;e.preventDefault()}(Math.abs(t)>=this.ws_.options.minWheelDelta||Math.abs(n)>=this.ws_.options.minWheelDelta)&&(r&&this.isGoingLeft_||!r&&this.isGoingUp_?this.ws_.goPrev():this.ws_.goNext(),e.preventDefault())}}]),e}();t.default=s},function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;nMath.abs(t)&&(e<-this.ws_.options.slideOffset?this.ws_.goPrev():e>this.ws_.options.slideOffset&&this.ws_.goNext())}}],[{key:"normalizeEventInfo",value:function(e){var t={pageX:0,pageY:0};return void 0!==e.changedTouches?t=e.changedTouches[0]:void 0!==e.originalEvent&&void 0!==e.originalEvent.changedTouches&&(t=e.originalEvent.changedTouches[0]),{x:e.offsetX||e.layerX||t.pageX,y:e.offsetY||e.layerY||t.pageY}}}]),e}();t.default=l},function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:500,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){},i=e-o.scrollTop,r=o.scrollTop;if(!t)return o.scrollTop=e,void n();!function s(l){l+=16;var u=Math.min(1,l/t),d=a.default.swing(u,l*u,e,i,t);o.scrollTop=Math.floor(r+d*i),l1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"",i=document.createElement(e);return i.id=t,n&&(i.textContent=n),i}},{key:"once",value:function(e,t,n){var i=function i(a){a.target===e&&(e.removeEventListener(t,i),n(a))};e.addEventListener(t,i,!1)}},{key:"getTransitionEvent",value:function(){if(s)return s;for(var e=document.createElement("ws"),t={transition:"transitionend",OTransition:"oTransitionEnd",MozTransition:"transitionend",WebkitTransition:"webkitTransitionEnd"},n=Object.keys(t),i=0,a=n.length;i2&&void 0!==arguments[2]?arguments[2]:{},i=new o.default(t,{detail:n});e.dispatchEvent(i)}},{key:"toArray",value:function(e){return[].slice.call(e)}},{key:"isFocusableElement",value:function(){var e=!1;if(document.activeElement){var t="inherit"!==document.activeElement.contentEditable;e=["INPUT","SELECT","OPTION","TEXTAREA"].indexOf(document.activeElement.tagName)>-1||t}return e}}]),e}();t.default=u},function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0}),t.Events=t.default=void 0;var a=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{},n=t.autoslide,i=void 0!==n&&n,r=t.changeOnClick,o=void 0!==r&&r,s=t.loop,l=void 0===s||s,u=t.minWheelDelta,d=void 0===u?40:u,c=t.scrollWait,f=void 0===c?450:c,h=t.slideOffset,y=void 0===h?50:h;if(a(this,e),this.el=document.getElementById("webslides"),!this.el)throw new Error("Couldn't find the webslides container!");this.isMoving=!1,this.slides=null,this.currentSlideI_=-1,this.currentSlide_=null,this.maxSlide_=0,this.isVertical=this.el.classList.contains(v.VERTICAL),this.plugins={},this.options={autoslide:i,changeOnClick:o,loop:l,minWheelDelta:d,scrollWait:f,slideOffset:y},this.initialised=!1,this.removeChildren_(),this.grabSlides_(),this.createPlugins_(),this.initSlides_(),this.onInit_()}return r(e,[{key:"removeChildren_",value:function(){for(var e=this.el.childNodes,t=e.length;t--;){var n=e[t];u.default.isCandidate(n)||this.el.removeChild(n)}}},{key:"createPlugins_",value:function(){var e=this;Object.keys(y).forEach(function(t){var n=y[t];e.plugins[t]=new n(e)})}},{key:"onInit_",value:function(){this.initialised=!0,c.default.fireEvent(this.el,"ws:init"),document.documentElement.classList.add(v.READY)}},{key:"grabSlides_",value:function(){this.slides=c.default.toArray(this.el.childNodes).map(function(e,t){return new u.default(e,t)}),this.maxSlide_=this.slides.length}},{key:"goToSlide",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;if(this.isValidIndexSlide_(e)&&!this.isMoving&&this.currentSlideI_!==e){this.isMoving=!0;var n=!1;null!==t?n=t:this.currentSlideI_>=0&&(n=e>this.currentSlideI_);var i=this.slides[e];null===this.currentSlide_||!this.isVertical||this.plugins.touch&&this.plugins.touch.isEnabled?this.transitionToSlide_(n,i,this.onSlideChange_):this.scrollTransitionToSlide_(n,i,this.onSlideChange_)}}},{key:"scrollTransitionToSlide_",value:function(e,t,n){var i=this;this.el.style.overflow="hidden",e?t.show():(t.moveBeforeFirst(),t.show(),(0,h.default)(this.currentSlide_.el.offsetTop,0)),(0,h.default)(t.el.offsetTop,500,function(){i.currentSlide_.hide(),e&&i.currentSlide_.moveAfterLast(),i.el.style.overflow="auto",setTimeout(function(){n.call(i,t)},150)})}},{key:"transitionToSlide_",value:function(e,t,n){var i=this;(0,h.default)(0,0);var a="slideInRight";e||(t.moveBeforeFirst(),a="slideInLeft"),this.currentSlide_&&(e&&this.currentSlide_.moveAfterLast(),this.currentSlide_.hide()),t.show(),this.initialised&&this.plugins.touch&&this.plugins.touch.isEnabled?(c.default.once(t.el,c.default.getAnimationEvent(),function(){t.el.classList.remove(a),n.call(i,t)}),t.el.classList.add(a)):n.call(this,t)}},{key:"onSlideChange_",value:function(e){this.currentSlide_&&this.currentSlide_.disable(),this.currentSlide_=e,this.currentSlideI_=e.i,this.currentSlide_.enable(),this.isMoving=!1,c.default.fireEvent(this.el,"ws:slide-change",{slides:this.maxSlide_,currentSlide0:this.currentSlideI_,currentSlide:this.currentSlideI_+1})}},{key:"goNext",value:function(){var e=this.currentSlideI_+1;if(e>=this.maxSlide_){if(!this.options.loop)return;e=0}this.goToSlide(e,!0)}},{key:"goPrev",value:function(){var e=this.currentSlideI_-1;if(e<0){if(!this.options.loop)return;e=this.maxSlide_-1}this.goToSlide(e,!1)}},{key:"isValidIndexSlide_",value:function(e){return e>=0&&e=this.maxSlide_)&&(e=0),0!==e)for(var t=0;t0&&(this.interval_=setInterval(this.ws_.goNext.bind(this.ws_),e))}},{key:"stop",value:function(){this.interval_&&(clearInterval(this.interval_),this.interval_=null)}}]),e}();t.default=s},function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;nMath.abs(t);if(this.isGoingUp_=t<0,this.isGoingLeft_=n<0,a){if(i)return;e.preventDefault()}(Math.abs(t)>=this.ws_.options.minWheelDelta||Math.abs(n)>=this.ws_.options.minWheelDelta)&&(a&&this.isGoingLeft_||!a&&this.isGoingUp_?this.ws_.goPrev():this.ws_.goNext(),e.preventDefault())}}]),e}();t.default=s},function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;nMath.abs(t)&&(e<-this.ws_.options.slideOffset?this.ws_.goPrev():e>this.ws_.options.slideOffset&&this.ws_.goNext())}}],[{key:"normalizeEventInfo",value:function(e){var t={pageX:0,pageY:0};return void 0!==e.changedTouches?t=e.changedTouches[0]:void 0!==e.originalEvent&&void 0!==e.originalEvent.changedTouches&&(t=e.originalEvent.changedTouches[0]),{x:e.offsetX||e.layerX||t.pageX,y:e.offsetY||e.layerY||t.pageY}}}]),e}();t.default=l},function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:500,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){},i=e-o.scrollTop,a=o.scrollTop;if(!t)return o.scrollTop=e,void n();!function s(l){l+=16;var u=Math.min(1,l/t),d=r.default.swing(u,l*u,e,i,t);o.scrollTop=Math.floor(a+d*i),l Date: Wed, 26 Apr 2017 23:11:56 +0200 Subject: [PATCH 4/5] Adding tests with jest --- .babelrc | 10 +- .eslintrc | 4 + package.json | 31 +---- src/js/utils/dom.js | 21 ++-- test/utils/dom.test.js | 270 ++++++++++++++++++++++++++++++++++++++++ test/utils/keys.test.js | 14 +++ 6 files changed, 315 insertions(+), 35 deletions(-) create mode 100644 test/utils/dom.test.js create mode 100644 test/utils/keys.test.js diff --git a/.babelrc b/.babelrc index c13c5f6..05dcf49 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,11 @@ { - "presets": ["es2015"] + "presets": [ + ["es2015", {"modules": false}] + ], + + "env": { + "test": { + "plugins": ["transform-es2015-modules-commonjs"] + } + } } diff --git a/.eslintrc b/.eslintrc index 1343963..3763bfd 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,11 +1,15 @@ { "env": { + "jest/globals": true, "browser": true }, "parserOptions": { "ecmaVersion": 6, "sourceType": "module" }, + "plugins": [ + "jest" + ], "rules": { "no-cond-assign": 0, "no-console": 2, diff --git a/package.json b/package.json index 6248335..c75ab80 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "ava": "^0.19.1", "babel-cli": "^6.24.1", "babel-core": "^6.24.1", + "babel-jest": "^19.0.0", "babel-loader": "^6.4.1", "babel-preset-env": "^1.4.0", "babel-preset-es2015": "^6.24.1", @@ -38,8 +39,11 @@ "browser-env": "^2.0.30", "eslint": "^3.19.0", "eslint-loader": "^1.7.1", + "eslint-plugin-jest": "^19.0.1", + "jest": "^19.0.2", "npm-run-all": "^4.0.2", "rimraf": "^2.6.1", + "simulant": "^0.2.2", "smart-banner-webpack-plugin": "^3.0.1", "webpack": "^2.4.1", "webpack-dev-server": "^2.4.2" @@ -50,31 +54,6 @@ "build:main": "webpack", "build:main.min": "webpack --output-filename [name].min.js -p", "dev": "webpack-dev-server", - "test": "ava test/*.js" - }, - "babel": { - "presets": [ - [ - "es2015", - { - "modules": false - }, - "@ava/stage-4", - "@ava/transform-test-files" - ] - ] - }, - "ava": { - "babel": { - "presets": [ - "es2015", - "stage-0", - "react" - ] - }, - "require": [ - "babel-register", - "./test/helpers/setup-browser-env.js" - ] + "test": "jest" } } diff --git a/src/js/utils/dom.js b/src/js/utils/dom.js index 181ddf3..ff1ee77 100644 --- a/src/js/utils/dom.js +++ b/src/js/utils/dom.js @@ -46,14 +46,17 @@ export default class DOM { /** * Gets the prefixed transitionend event. + * @param {?Element} optEl Element to check * @return {string} */ - static getTransitionEvent() { - if (transitionEvent) { + static getTransitionEvent(optEl) { + if (transitionEvent && !optEl) { return transitionEvent; } - const el = document.createElement('ws'); + transitionEvent = ''; + + const el = optEl || document.createElement('ws'); const transitions = { 'transition': 'transitionend', 'OTransition': 'oTransitionEnd', @@ -76,14 +79,17 @@ export default class DOM { /** * Gets the prefixed animation end event. + * @param {?Element} optEl Element to check * @return {string} */ - static getAnimationEvent() { - if (animationEvent) { + static getAnimationEvent(optEl) { + if (animationEvent && !optEl) { return animationEvent; } - const el = document.createElement('ws'); + animationEvent = ''; + + const el = optEl || document.createElement('ws'); const animations = { 'animation': 'animationend', 'OAnimation': 'oAnimationEnd', @@ -156,10 +162,9 @@ export default class DOM { if (document.activeElement) { const isContentEditable = document.activeElement - .contentEditable !== 'inherit'; + .contentEditable !== 'inherit' && document.activeElement.contentEditable !== undefined; const isInput = ['INPUT', 'SELECT', 'OPTION', 'TEXTAREA'] .indexOf(document.activeElement.tagName) > -1; - result = isInput || isContentEditable; } diff --git a/test/utils/dom.test.js b/test/utils/dom.test.js new file mode 100644 index 0000000..53bf72d --- /dev/null +++ b/test/utils/dom.test.js @@ -0,0 +1,270 @@ +import DOM from '../../src/js/utils/dom'; +import simulant from 'simulant'; + +describe('Node creation', () => { + test('Creates a node', () => { + const node = DOM.createNode('p'); + + expect(node).toBeInstanceOf(Element); + expect(node.tagName).toBe('P'); + expect(node.id).toBe(''); + }); + + test('Should be possible to pass an id', () => { + const node = DOM.createNode('p', 'myId'); + + expect(node.id).toBe('myId'); + }); + + test('Should be possible to pass text', () => { + const node = DOM.createNode('p', 'id', 'foo'); + + expect(node.textContent).toBe('foo'); + }); +}); + +describe('Once', () => { + let parent; + let inner; + + beforeEach(() => { + document.body.innerHTML = ` +
+
+
+ `; + parent = document.getElementById('parent'); + inner = document.getElementById('inner'); + }); + + afterEach(() => { + document.body.innerHTML = ''; + }); + + test('Only once called once', () => { + const cb = jest.fn(); + DOM.once(parent, 'click', cb); + simulant.fire(parent, 'click'); + simulant.fire(parent, 'click'); + simulant.fire(parent, 'click'); + + expect(cb).toHaveBeenCalledTimes(1); + }); + + test('Callback doesn\'t run on bubbled event', () => { + const cb = jest.fn(); + DOM.once(parent, 'click', cb); + simulant.fire(inner, 'click'); + + expect(cb).not.toHaveBeenCalled(); + }); +}); + +describe('Transition', () => { + test('Returns unprefixed first if available', () => { + const fakeEl = { + style: { + transition: 'foo', + OTransition: 'foo', + MozTransition: 'foo', + WebkitTransition: 'foo' + } + }; + + expect(DOM.getTransitionEvent(fakeEl)).toBe('transitionend'); + }); + + test('Prefixed Opera', () => { + const fakeEl = { + style: { + OTransition: 'foo' + } + }; + + expect(DOM.getTransitionEvent(fakeEl)).toBe('oTransitionEnd'); + }); + + + test('Prefixed Gecko', () => { + const fakeEl = { + style: { + MozTransition: 'foo' + } + }; + + expect(DOM.getTransitionEvent(fakeEl)).toBe('transitionend'); + }); + + + test('Prefixed Webkit', () => { + const fakeEl = { + style: { + WebkitTransition: 'foo' + } + }; + + expect(DOM.getTransitionEvent(fakeEl)).toBe('webkitTransitionEnd'); + }); + + test('Retains value', () => { + const fakeEl = { + style: { + WebkitTransition: 'foo' + } + }; + + expect(DOM.getTransitionEvent(fakeEl)).toBe('webkitTransitionEnd'); + expect(DOM.getTransitionEvent()).toBe('webkitTransitionEnd'); + }); +}); + +describe('Animation', () => { + test('Returns unprefixed first if available', () => { + const fakeEl = { + style: { + animation: 'foo', + OAnimation: 'foo', + MozAnimation: 'foo', + WebkitAnimation: 'foo' + } + }; + + expect(DOM.getAnimationEvent(fakeEl)).toBe('animationend'); + }); + + test('Prefixed Opera', () => { + const fakeEl = { + style: { + OAnimation: 'foo' + } + }; + + expect(DOM.getAnimationEvent(fakeEl)).toBe('oAnimationEnd'); + }); + + + test('Prefixed Gecko', () => { + const fakeEl = { + style: { + MozAnimation: 'foo' + } + }; + + expect(DOM.getAnimationEvent(fakeEl)).toBe('animationend'); + }); + + + test('Prefixed Webkit', () => { + const fakeEl = { + style: { + WebkitAnimation: 'foo' + } + }; + + expect(DOM.getAnimationEvent(fakeEl)).toBe('webkitAnimationEnd'); + }); + + test('Retains value', () => { + const fakeEl = { + style: { + WebkitAnimation: 'foo' + } + }; + + expect(DOM.getAnimationEvent(fakeEl)).toBe('webkitAnimationEnd'); + expect(DOM.getAnimationEvent()).toBe('webkitAnimationEnd'); + }); +}); + +describe('Show/hide', () => { + test('Show removes the display property', () => { + const el = DOM.createNode('div'); + el.style.display = 'flex'; + + expect(el.style.display).toBe('flex'); + DOM.show(el); + expect(el.style.display).toBe(''); + }); + + test('Hide adds display none', () => { + const el = DOM.createNode('div'); + + expect(el.style.display).toBe(''); + DOM.hide(el); + expect(el.style.display).toBe('none'); + }); +}); + +describe('Custom Event', () => { + test('Event gets fired', () => { + const cb = jest.fn(); + const el = DOM.createNode('div'); + + el.addEventListener('foo', cb); + DOM.fireEvent(el, 'foo'); + expect(cb).toHaveBeenCalled(); + }); + + test('Event can pass data', () => { + const cb = jest.fn(); + const el = DOM.createNode('div'); + + el.addEventListener('foo', cb); + DOM.fireEvent(el, 'foo', { + foo: 'bar' + }); + expect(cb.mock.calls[0][0].detail.foo).toBe('bar'); + }); +}); + +describe('To Array', () => { + test('Converts to array', () => { + document.body.innerHTML = '

'; + const paragraphs = document.querySelectorAll('p'); + + expect(paragraphs.length).toBe(5); + expect(paragraphs).not.toBeInstanceOf(Array); + expect(DOM.toArray(paragraphs)).toBeInstanceOf(Array); + expect(DOM.toArray(paragraphs).length).toBe(5); + + document.body.innerHTML = ''; + }); +}); + +describe('Focusble Element', () => { + beforeEach(() => { + document.body.innerHTML = ` +

+ + + + `; + }); + + afterEach(() => { + document.body.innerHTML = ''; + }); + + test('Returns false if not focusable', () => { + document.getElementById('noContent').focus(); + expect(DOM.isFocusableElement()).toBe(false); + }); + + test('Returns true if focusable', () => { + document.getElementById('noContent').focus(); + expect(DOM.isFocusableElement()).toBe(false); + document.getElementById('input').focus(); + expect(DOM.isFocusableElement()).toBe(true); + document.getElementById('noContent').focus(); + expect(DOM.isFocusableElement()).toBe(false); + document.getElementById('select').focus(); + expect(DOM.isFocusableElement()).toBe(true); + document.getElementById('noContent').focus(); + expect(DOM.isFocusableElement()).toBe(false); + document.getElementById('textarea').focus(); + expect(DOM.isFocusableElement()).toBe(true); + }); +}); diff --git a/test/utils/keys.test.js b/test/utils/keys.test.js new file mode 100644 index 0000000..9482ced --- /dev/null +++ b/test/utils/keys.test.js @@ -0,0 +1,14 @@ +import Keys from '../../src/js/utils/keys'; + +test('Keys are present', () => { + expect(Keys.ENTER).toBe(13); + expect(Keys.SPACE).toBe(32); + expect(Keys.RE_PAGE).toBe(33); + expect(Keys.AV_PAGE).toBe(34); + expect(Keys.END).toBe(35); + expect(Keys.HOME).toBe(36); + expect(Keys.LEFT).toBe(37); + expect(Keys.UP).toBe(38); + expect(Keys.RIGHT).toBe(39); + expect(Keys.DOWN).toBe(40); +}); From eb458892667788365c321457a87b2ff62c72853c Mon Sep 17 00:00:00 2001 From: Antonio Laguna Date: Thu, 27 Apr 2017 07:42:06 +0200 Subject: [PATCH 5/5] Adding travis --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..b278bdb --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - "6" + - "7"