diff --git a/README.md b/README.md index 41f8dd3..d7ed5e4 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,10 @@ # owl-aria An Owl Carousel v2 accessibility layer + + + +## License + +### Commercial license + +If you want to use owl-arai to develop commercial sites, themes, projects, and applications, the Commercial license is the appropriate license. diff --git a/dist/js/owl.carousel.aria.js b/dist/js/owl.carousel.aria.js new file mode 100644 index 0000000..343eabf --- /dev/null +++ b/dist/js/owl.carousel.aria.js @@ -0,0 +1,196 @@ +"use strict"; + +/** + * Aria Plugin + * Author: Stephan Fischer + * @since 2.0.0 + */ + +;(function ($, window, document, undefined) { + var Aria = function Aria(scope) { + var _this = this; + + this._core = scope; + this.options = $.extend({}, Aria.Defaults, this._core.options); + + if (!this.options.aria) { + return false; + } + + this.$element = this._core.$element; + + this._init = false; + + this.$element.on({ + 'initialized.owl.carousel': function initializedOwlCarousel(e) { + if (e.namespace && !_this._init) { + _this.$stage = _this._core.$stage; + + _this.$nav = $('.' + _this.options.navContainerClass + ', .' + _this.options.dotsClass, _this.$element); + + _this.bind(); + _this.setAria(); + _this._init = true; + } + }, + 'changed.owl.carousel': function changedOwlCarousel(e) { + return _this.setAria(); + }, + 'translated.owl.carousel': function translatedOwlCarousel(e) { + return _this.setAria(); + }, + 'refreshed.owl.carousel': function refreshedOwlCarousel(e) { + return _this.setAria(); + }, + 'resized.owl.carousel': function resizedOwlCarousel(e) { + return _this.setAria(); + } + }); + }; + + Aria.Defaults = { + aria: true + }; + + Aria.prototype.bind = function () { + var _this2 = this; + + this.$element.attr('tabindex', '0'); + this.$element.on('to.owl.carousel', function (e) { + return e.stopPropagation(); + }); + this.$element.on('next.owl.carousel', function (e) { + return e.stopPropagation(); + }); + this.$element.on('prev.owl.carousel', function (e) { + return e.stopPropagation(); + }); + this.$element.on('destroy.owl.carousel', function (e) { + return e.stopPropagation(); + }); + this.$element.on('focusin', function (e) { + return _this2.focus(e); + }).on('focusout', function (e) { + return _this2.blur(e); + }).on('keyup', function (e) { + return _this2.keyUp(e); + }); + }; + + Aria.prototype.focus = function () { + this.$element.attr({ 'aria-live': 'polite' }); + }; + + Aria.prototype.blur = function () { + this.$element.attr({ 'aria-live': 'off' }); + }; + + Aria.prototype.keyUp = function (e) { + var action = null; + + if (e.keyCode == 37 || e.keyCode == 38) { + action = 'prev.owl.carousel'; + } else if (e.keyCode == 39 || e.keyCode == 40) { + action = 'next.owl.carousel'; + } + + if (action !== null) { + this.$element.trigger(action); + } + + return false; // important! + }; + + Aria.prototype.setAria = function () { + var _this3 = this; + + if (!this.$stage || !this.$stage.length) { + return false; + } + + setTimeout(function () { + _this3.$nav.children().each(function (i, el) { + var $item = $(el); + var isDisabled = $item.hasClass('disabled'); + var isActive = $item.hasClass('active'); + + $item.attr('aria-disabled', isDisabled || isActive ? "true" : "false"); + }); + + _this3.$stage.children().each(function (i, el) { + var $item = $(el); + var isActive = $item.hasClass('active'); + + $item.attr('aria-hidden', !isActive ? "true" : "false"); + $item.find('*').each(function (i, e) { + var $el = $(e); + + if (isActive === false) { + $el.storeTabindex(); + $el.attr("tabindex", "-1"); + } else { + if ($el.is('[data-tabindex]')) { + $el.restoreTabindex(); + } else { + $el.removeAttr("tabindex"); + } + } + }); + }); + }); + }; + + Aria.prototype.destroy = function () { + var _this4 = this; + + this.$element.removeAttr('aria-live'); + this.$element.removeAttr('tabindex'); + this.$element.children().removeAttr('aria-hidden'); + this.$element.find('[data-store-tabindex]').clearTabindex(); + this.$element.off('focusin', function (e) { + return _this4.focus(e); + }).off('focusout', function (e) { + return _this4.blur(e); + }).off('keyup', function (e) { + return _this4.keyUp(e); + }); + }; + + $.fn.extend({ + clearTabindex: function clearTabindex() { + return this.each(function () { + var $el = $(this); + + if (!$el.is('[data-tabindex]')) { + $el.removeAttr("tabindex"); + } + + $el.restoreTabindex(); + }); + }, + restoreTabindex: function restoreTabindex() { + return this.each(function () { + var $el = $(this); + + if ($el.is('[data-tabindex]')) { + $el.attr("tabindex", $el.attr('data-tabindex')); + $el.removeAttr('data-tabindex'); + } + + $el.removeAttr('data-store-tabindex'); + }); + }, + storeTabindex: function storeTabindex() { + return this.each(function () { + var $el = $(this); + if ($el.is('[tabindex]')) { + $el.attr("data-tabindex", $el.attr('tabindex')); + } + + $el.attr('data-store-tabindex', true); + }); + } + }); + + $.fn.owlCarousel.Constructor.Plugins['Aria'] = Aria; +})(window.Zepto || window.jQuery, window, document); \ No newline at end of file diff --git a/dist/js/owl.carousel.aria.min.js b/dist/js/owl.carousel.aria.min.js new file mode 100644 index 0000000..586670a --- /dev/null +++ b/dist/js/owl.carousel.aria.min.js @@ -0,0 +1 @@ +"use strict";!function(t,e,n,i){var r=function e(n){var i=this;if(this._core=n,this.options=t.extend({},e.Defaults,this._core.options),!this.options.aria)return!1;this.$element=this._core.$element,this._init=!1,this.$element.on({"initialized.owl.carousel":function(e){e.namespace&&!i._init&&(i.$stage=i._core.$stage,i.$nav=t("."+i.options.navContainerClass+", ."+i.options.dotsClass,i.$element),i.bind(),i.setAria(),i._init=!0)},"changed.owl.carousel":function(t){return i.setAria()},"translated.owl.carousel":function(t){return i.setAria()},"refreshed.owl.carousel":function(t){return i.setAria()},"resized.owl.carousel":function(t){return i.setAria()}})};r.Defaults={aria:!0},r.prototype.bind=function(){var t=this;this.$element.attr("tabindex","0"),this.$element.on("to.owl.carousel",function(t){return t.stopPropagation()}),this.$element.on("next.owl.carousel",function(t){return t.stopPropagation()}),this.$element.on("prev.owl.carousel",function(t){return t.stopPropagation()}),this.$element.on("destroy.owl.carousel",function(t){return t.stopPropagation()}),this.$element.on("focusin",function(e){return t.focus(e)}).on("focusout",function(e){return t.blur(e)}).on("keyup",function(e){return t.keyUp(e)})},r.prototype.focus=function(){this.$element.attr({"aria-live":"polite"})},r.prototype.blur=function(){this.$element.attr({"aria-live":"off"})},r.prototype.keyUp=function(t){var e=null;return 37==t.keyCode||38==t.keyCode?e="prev.owl.carousel":39!=t.keyCode&&40!=t.keyCode||(e="next.owl.carousel"),null!==e&&this.$element.trigger(e),!1},r.prototype.setAria=function(){var e=this;if(!this.$stage||!this.$stage.length)return!1;setTimeout(function(){e.$nav.children().each(function(e,n){var i=t(n),r=i.hasClass("disabled"),o=i.hasClass("active");i.attr("aria-disabled",r||o?"true":"false")}),e.$stage.children().each(function(e,n){var i=t(n),r=i.hasClass("active");i.attr("aria-hidden",r?"false":"true"),i.find("*").each(function(e,n){var i=t(n);!1===r?(i.storeTabindex(),i.attr("tabindex","-1")):i.is("[data-tabindex]")?i.restoreTabindex():i.removeAttr("tabindex")})})})},r.prototype.destroy=function(){var t=this;this.$element.removeAttr("aria-live"),this.$element.removeAttr("tabindex"),this.$element.children().removeAttr("aria-hidden"),this.$element.find("[data-store-tabindex]").clearTabindex(),this.$element.off("focusin",function(e){return t.focus(e)}).off("focusout",function(e){return t.blur(e)}).off("keyup",function(e){return t.keyUp(e)})},t.fn.extend({clearTabindex:function(){return this.each(function(){var e=t(this);e.is("[data-tabindex]")||e.removeAttr("tabindex"),e.restoreTabindex()})},restoreTabindex:function(){return this.each(function(){var e=t(this);e.is("[data-tabindex]")&&(e.attr("tabindex",e.attr("data-tabindex")),e.removeAttr("data-tabindex")),e.removeAttr("data-store-tabindex")})},storeTabindex:function(){return this.each(function(){var e=t(this);e.is("[tabindex]")&&e.attr("data-tabindex",e.attr("tabindex")),e.attr("data-store-tabindex",!0)})}}),t.fn.owlCarousel.Constructor.Plugins.Aria=r}(window.Zepto||window.jQuery,window,document); \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..36576d4 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,38 @@ +'use strict'; + +const gulp = require('gulp'); +const concat = require('gulp-concat'); +const babel = require('gulp-babel'); +const sourcemaps = require('gulp-sourcemaps'); +const rename = require('gulp-rename'); +const minify = require('gulp-minifier'); +const source = 'src/js/**'; +const dist = 'dist/js/'; + +gulp.task('dist', () => +{ + return gulp.src(source) + .pipe(sourcemaps.init()) + .pipe(concat('owl.carousel.aria.js'), { + newLine: '\n;' + }) + .pipe(babel({ + presets: ['es2015'] + })) + .pipe(gulp.dest(dist)) + .pipe(rename('owl.carousel.aria.min.js')) + .pipe(minify({ + minify: true, + minifyJS: { + sourceMap: false + } + })) + .pipe(gulp.dest(dist)); +}); + + + + + + +gulp.task('default', ['dist']); \ No newline at end of file diff --git a/index.html b/index.html index 7a82fbc..deb2391 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,7 @@ - +