--- /dev/null
+(function ($) {
+ function JQAriaRadio(element) {
+ this.element = element;
+ this.optionSelector = '[role="radio"]';
+ this.options = $(element).find(this.optionSelector);
+ this.init();
+ }
+
+ JQAriaRadio.prototype = {
+ init: function () {
+ var $this = this;
+
+ $(this.element).on('click', this.optionSelector, function () {
+ var r = $(this).find('input[type=radio]');
+ r.prop('checked', true);
+ $this.update();
+ return false;
+ });
+
+ $(this.element).on('keydown', function (e) {
+ var active = $(document.activeElement);
+ if (!active.is($this.optionSelector)) {
+ return true;
+ }
+ if (e.keyCode >= 37 && e.keyCode <= 40) {
+ fluidbook.keyboard._navigate($this.optionSelector, e.keyCode === 37 || e.keyCode === 38 ? -1 : 1, ['focus', 'click']);
+ e.preventDefault();
+ return false;
+ }
+ return true;
+ });
+
+ $(this.options).each(function () {
+ $(this).addClass('ignore-tab-children');
+ });
+
+ this.update();
+ },
+
+ update: function () {
+ $(this.options).each(function () {
+ var r = $(this).find('input[type="radio"]');
+ if ($(r).prop('checked')) {
+ $(this).attr('tabindex', 0).attr('aria-checked', true);
+ } else {
+ $(this).attr('tabindex', -1).attr('aria-checked', false);
+ }
+ });
+ },
+ };
+
+ jQuery.fn.AriaRadio = function () {
+ return this.each(function () {
+ var $this = $(this);
+ if ($(this).data('AriaRadio') === undefined) {
+ $(this).data('AriaRadio', new JQAriaRadio($this));
+ }
+ })
+ };
+})(jQuery);
+
}
},
- _navigate: function (list, dir) {
+ _navigate: function (list, dir, actions) {
+ if (actions === undefined) {
+ actions = ['focus'];
+ }
if (dir === undefined) {
dir = 1;
}
}
console.log(next);
var ne = $(items).eq(next);
- $(ne).focus();
+ $.each(actions, function (k, action) {
+ if (action === 'focus') {
+ $(ne).focus();
+ } else if (action === 'click') {
+ $(ne).click();
+ }
+ });
+
},
tabNavigation: function (selector, dir) {
var focusableElementsString = 'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex="0"]:not(.ps__thumb-x):not(.ps__thumb-y), [contenteditable]';
- this._navigate($(selector).find(focusableElementsString), dir);
+ var elements = $(selector).find(focusableElementsString);
+ var list = [];
+ $(elements).each(function () {
+ if ($(this).parents('[tabindex="-1"],.ignore-tab-children').length === 0) {
+ list.push(this);
+ }
+ });
+ this._navigate(list, dir);
},
initBookmarksShortcuts: function () {
// Auto select first option (the options are dynamic so we can't do it until now)
$('.print-dialogue .print-option:first-of-type input[type="radio"]').prop('checked', true);
+ $('[role="radiogroup"]').AriaRadio();
if (callback != undefined) {
callback();
var view = '';
view += '<div class="content">';
- view += '<div class="print-dialogue' + (this.compact ? ' compact' : '') + '">';
+ view += '<div role="radiogroup" class="print-dialogue' + (this.compact ? ' compact' : '') + '">';
// NOTE: Each option has two labels so thumbnails are also clickable and so it works with the custom radio inputs
// Double Page
if (!this.isFirstPage && !this.isLastPage && !this.isSinglePageMode) {
- view += '<div class="print-option">';
+ view += '<div class="print-option" role="radio">';
if (!this.compact) {
view += '<label for="doublePage">';
view += '<div class="doubleThumb">';
// Full Brochure
if (this.fluidbook.settings.printFullBrochure) {
- view += '<div class="print-option">';
+ view += '<div class="print-option" role="radio">';
if (!this.compact) {
view += '<label for="allPages">';
view += '<div class="doubleThumb">';
var hasBookmarks = this.fluidbook.bookmarks.hasBookmarkedPages(),
bookmarksDisabled = hasBookmarks ? '' : 'disabled';
- view += '<div class="print-option bookmarks-option ' + bookmarksDisabled + '">';
+ view += '<div class="print-option bookmarks-option ' + bookmarksDisabled + '" role="radio">';
if (!this.compact) {
view += '<label for="bookmarkedPages">';
view += '<div class="doubleThumb bookmarks">';
view += '</div>'; // .print-option
}
- view += '<div class="print-option blank"></div>'; // Extra empty div to ensure flexbox space-between works as expected
+ view += '<div class="print-option blank" aria-hidden="true"></div>'; // Extra empty div to ensure flexbox space-between works as expected
// Page range inputs
if (this.fluidbook.settings.printPageRange) {
// It has to be calculated this way because sometimes there is no this.rightPageNumber
var rangeEnd = Math.min(rangeStart + 1, this.fluidbook.settings.pages);
- view += '<div class="print-option page-range-option">';
+ view += '<div class="print-option page-range-option" role="radio">';
view += '<input type="radio" name="pageChoice" value="range" id="pageRange">';
view += '<label for="pageRange">';
view += __('From page');
sideMask = side === 'left' ? 'right' : 'left';
}
var view = '';
- view += '<div class="print-option">';
+ view += '<div class="print-option" role="radio">';
if (!this.compact) {
view += '<label for="' + side + 'Page">';
view += '<div class="doubleThumb">';