From: Vincent Vanwaelscappel Date: Thu, 2 Jul 2020 18:07:11 +0000 (+0200) Subject: wip #3758 @2 X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=d021fe8eb183bbea7097b1b85289d90dd72dd777;p=fluidbook-html5.git wip #3758 @2 --- diff --git a/js/libs/fluidbook/fluidbook.interface.js b/js/libs/fluidbook/fluidbook.interface.js index 50cb13ef..6ac393e1 100644 --- a/js/libs/fluidbook/fluidbook.interface.js +++ b/js/libs/fluidbook/fluidbook.interface.js @@ -14,30 +14,29 @@ function FluidbookInterface(fluidbook) { FluidbookInterface.prototype = { - init: function () { var $this = this; if (this.arrowsEnabled()) { - var labels=this.getLabels(); + var labels = this.getLabels(); var res = ''; if ($('html').hasClass('ltr')) { res += '
'; - res += this.fluidbook.nav.getLink('interface-next', '#', 'next', '', labels.next, 'arrow-top', true); - res += this.fluidbook.nav.getLink('interface-last', '#', 'last', '', labels.last, 'arrow-bottom', true); + res += this.fluidbook.nav.getLink('interface-next', '#', 'next', '', labels.next, 'arrow-top', true, '', 'Right'); + res += this.fluidbook.nav.getLink('interface-last', '#', 'last', '', labels.last, 'arrow-bottom', true ,'','End'); res += '
'; res += '
'; - res += this.fluidbook.nav.getLink('interface-prev', '#', 'previous', '', labels.previous, 'arrow-top', true); - res += this.fluidbook.nav.getLink('interface-first', '#', 'first', '', labels.first, 'arrow-bottom', true); + res += this.fluidbook.nav.getLink('interface-prev', '#', 'previous', '', labels.previous, 'arrow-top', true, '', 'Left'); + res += this.fluidbook.nav.getLink('interface-first', '#', 'first', '', labels.first, 'arrow-bottom', true, '', 'Home'); res += '
'; } else { res += '
'; - res += this.fluidbook.nav.getLink('interface-next', '#', 'previous', '', labels.previous, 'arrow-top', true); - res += this.fluidbook.nav.getLink('interface-last', '#', 'first', '', labels.first, 'arrow-bottom', true); + res += this.fluidbook.nav.getLink('interface-next', '#', 'previous', '', labels.previous, 'arrow-top', true, '', 'Right'); + res += this.fluidbook.nav.getLink('interface-last', '#', 'first', '', labels.first, 'arrow-bottom', true, 'Home'); res += '
'; res += '
'; - res += this.fluidbook.nav.getLink('interface-prev', '#', 'next', '', labels.next, 'arrow-top', true); - res += this.fluidbook.nav.getLink('interface-first', '#', 'last', '', labels.last, 'arrow-bottom', true); + res += this.fluidbook.nav.getLink('interface-prev', '#', 'next', '', labels.next, 'arrow-top', true, 'Left'); + res += this.fluidbook.nav.getLink('interface-first', '#', 'last', '', labels.last, 'arrow-bottom', true, 'End'); res += '
'; } diff --git a/js/libs/fluidbook/fluidbook.js b/js/libs/fluidbook/fluidbook.js index 50313f60..4de1cdc2 100644 --- a/js/libs/fluidbook/fluidbook.js +++ b/js/libs/fluidbook/fluidbook.js @@ -37,10 +37,10 @@ Fluidbook.prototype = { this.junk = this.settings.cacheDate; this.networkControl = new FluidbookNetworkControl(this); this.input = new FluidbookInput(this); + this.keyboard = new FluidbookKeyboard(this); if (this.settings.landingPage != undefined && this.settings.landingPage != '') { this.landingpage = new FluidbookLandingPage(this); } - this.splash = new FluidbookSplash(this); this.contentlock = new FluidbookContentLock(this); this.menu = new FluidbookMenu(this); @@ -74,7 +74,6 @@ Fluidbook.prototype = { this.slideshow = new FluidbookSlideshow(this); this.printing = new FluidbookPrint(this); - if (this.settings.basket) { this.cart = new FluidbookCart(this); } @@ -126,7 +125,6 @@ Fluidbook.prototype = { this.articles = new FluidbookArticles(this); this.initTheme(); - this.initKeyboardShortcuts(); this.initLoading(); }, @@ -188,32 +186,6 @@ Fluidbook.prototype = { }); }, - initKeyboardShortcuts: function () { - var $this = this; - // General keyboard shortcuts - key('home', function () { - $this.goFirstPage(); - }); - key('end', function () { - $this.goLastPage(); - }); - key('left', function () { - if ($this.l10n.dir === 'ltr') { - $this.goPreviousPage(); - } else { - $this.goNextPage(); - } - }); - key('right', function () { - if ($this.l10n.dir === 'ltr') { - $this.goNextPage(); - } else { - $this.goPreviousPage(); - } - }); - // See fluidbook.audiodescription.js for specific shortcuts - }, - allowChangePage: function () { var $this = this; setTimeout(function () { diff --git a/js/libs/fluidbook/fluidbook.keyboard.js b/js/libs/fluidbook/fluidbook.keyboard.js new file mode 100644 index 00000000..de10da57 --- /dev/null +++ b/js/libs/fluidbook/fluidbook.keyboard.js @@ -0,0 +1,80 @@ +function FluidbookKeyboard(fluidbook) { + this.fluidbook = fluidbook; + this.shortcuts = []; + this.initKeyboardShortcuts(); +} + +FluidbookKeyboard.prototype = { + initKeyboardShortcuts: function () { + var $this = this; + key('escape', function () { + $this.fluidbook.help.hide(); + $this.fluidbook.menu.closeView(function () { + + }, true, true); + }); + }, + + keyShortcut: function (shortcuts, func) { + if (shortcuts === '') { + return; + } + key(this.checkShortcuts(shortcuts), function () { + console.log('triggered ' + shortcuts) + func(); + if(shortcuts==='f11'){ + return true; + } + return false; + }); + }, + + + checkShortcuts: function (shortcuts) { + console.log(shortcuts); + var $this = this; + var s = shortcuts.split(','); + var res = []; + $.each(s, function (k, shortcut) { + shortcut = shortcut.trim(); + if ($this.shortcuts.indexOf(shortcut) === -1) { + $this.shortcuts.push(shortcut); + res.push(shortcut); + } + }); + console.log(res); + return res.join(', '); + }, + + ariaShortcut: function (shortcuts, func) { + if (shortcuts === '') { + return; + } + this.keyShortcut(this.ariaToKey(shortcuts), func); + }, + + ariaToKey: function (shortcuts) { + var $this = this; + shortcuts = shortcuts.split(' '); + var res = []; + var map = {control: 'ctrl'}; + $.each(shortcuts, function (k, shortcut) { + if (shortcut === '') { + return; + } + var keys = shortcut.split('+'); + var ok = []; + $.each(keys, function (kk, key) { + key = key.toLowerCase(); + if (map[key]) { + ok.push(map[key]); + } else { + ok.push(key); + } + }); + res.push(ok.join('+')); + }); + + return res.join(','); + } +} \ No newline at end of file diff --git a/js/libs/fluidbook/fluidbook.nav.js b/js/libs/fluidbook/fluidbook.nav.js index e19c0c3e..187e20fe 100644 --- a/js/libs/fluidbook/fluidbook.nav.js +++ b/js/libs/fluidbook/fluidbook.nav.js @@ -140,14 +140,14 @@ FluidbookNav.prototype = { // } // return this.fluidbook.loader.getImage(src, this._dimensions[name][0], this._dimensions[name][1]); // }, - addLink: function (navType, name, href, id, title, help, before, className, showIcon) { + addLink: function (navType, name, href, id, title, help, keyboardShortcut, before, className, showIcon) { var $nav = this.getNavFromType(navType), elementID = navType + '_' + id; if ($nav.find('#' + elementID).length > 0) { return; } - var l = $(this.getLink(name, href, id, title, help, className, showIcon, navType)), + var l = $(this.getLink(name, href, id, title, help, className, showIcon, navType, keyboardShortcut)), li = '
  • ' + l[0].outerHTML + '
  • '; if (before === undefined) { $nav.find('ul').append(li); @@ -156,25 +156,34 @@ FluidbookNav.prototype = { } return $("#" + elementID).get(0); }, - getLink: function (name, href, id, title, help, className, showIcon, navType) { + getLink: function (name, href, id, title, help, className, showIcon, navType, keyboardShortcut) { if (showIcon === undefined) { showIcon = true; } + if (keyboardShortcut === undefined) { + keyboardShortcut = ''; + } var res = ''; - if (id !== undefined) { + if (id === undefined) { + var id = name; + if (navType !== undefined) { + id += '_' + navType; + } + } - // Make sure that the link gets a unique ID when it is used in both menus - var elementID = (navType === undefined) ? id : navType + '_' + id; - res += ' id="' + elementID + '"'; + // Make sure that the link gets a unique ID when it is used in both menus + var elementID = (navType === undefined || navType===null || navType==='') ? id : navType + '_' + id; + + res += ' id="' + elementID + '"'; + + // Links may exist more than once so add a class name based on the ID + // This class name can be used by event handlers to handle all instances + // For more specific behaviour, the ID can be targeted + className = (className === undefined) ? 'icon-' + id : className + ' icon-' + id; - // Links may exist more than once so add a class name based on the ID - // This class name can be used by event handlers to handle all instances - // For more specific behaviour, the ID can be targeted - className = (className === undefined) ? 'icon-' + id : className + ' icon-' + id; - } if (className !== undefined) { res += ' class="' + className + '"'; } @@ -186,8 +195,16 @@ FluidbookNav.prototype = { } res += ' aria-label="' + this.fluidbook.l10n.__(help) + '"'; } + if (keyboardShortcut !== '') { + res += ' aria-keyshortcuts="' + keyboardShortcut + '"'; + this.fluidbook.keyboard.ariaShortcut(keyboardShortcut, function () { + console.log('triggers ' + elementID + ' click'); + $("#" + elementID).get(0).click(); + }); + } res += '>'; + if (showIcon) { res += getSpriteIcon(name); @@ -367,7 +384,7 @@ FluidbookNav.prototype = { } try { if (homeURL !== '') { - link = this.addLink(navType, 'nav-home', homeURL, 'home', 'home', 'home'); + link = this.addLink(navType, 'nav-home', homeURL, 'home', 'home', 'home', 'Control+H'); } } catch (err) { @@ -388,26 +405,26 @@ FluidbookNav.prototype = { }); } else if (icon === 'index') { - link = this.addLink(navType, 'nav-index', '#/index', 'index', 'overview', 'overview'); + link = this.addLink(navType, 'nav-index', '#/index', 'index', 'overview', 'overview', 'Control+O'); } else if (icon === 'chapters') { if (!this.fluidbook.settings.displayChaptersIcon) { continue; } if (this.fluidbook.settings.externalChaptersHTML) { - link = this.addLink(navType, 'nav-chapters', '#/chapters', 'chapters', 'chapters', 'chapters'); + link = this.addLink(navType, 'nav-chapters', '#/chapters', 'chapters', 'chapters', 'chapters', 'F2'); } else if (this.fluidbook.settings.chaptersPage !== '') { - link = this.addLink(navType, 'nav-chapters', '#/page/' + this.fluidbook.settings.chaptersPage, 'chapters', 'chapters', 'chapters'); + link = this.addLink(navType, 'nav-chapters', '#/page/' + this.fluidbook.settings.chaptersPage, 'chapters', 'chapters', 'chapters', 'F2'); } else if (this.fluidbook.settings.chapters.length > 0) { // NOTE: Currently the MMenu breaks when the non-cascading chapter UL HTML is inserted so it will // be opened in a popup for now. Todo: fix this so it works as a sub panel of it's own if (navType === 'menu' && this.fluidbook.settings.chaptersCascade && !this.fluidbook.settings.displayChaptersPopup) { - link = this.addLink(navType, 'nav-chapters', '', 'chapters', 'chapters', 'chapters'); + link = this.addLink(navType, 'nav-chapters', '', 'chapters', 'chapters', 'chapters', 'F2'); // Get HTML for submenus (appended later) this.chaptersMenuHTML = this.makeChapterLists(this.fluidbook.settings.chapters); } else { - link = this.addLink(navType, 'nav-chapters', '#/chapters', 'chapters', 'chapters', 'chapters'); + link = this.addLink(navType, 'nav-chapters', '#/chapters', 'chapters', 'chapters', 'chapters', 'F2'); } } // Sharing icons - this may contain many different icons @@ -415,7 +432,7 @@ FluidbookNav.prototype = { if (this.fluidbook.share.isEnabled()) { if (navType === 'horizontalNav') { if (this.fluidbook.settings.share) { - link = this.addLink(navType, 'nav-share', '#/share', 'share', 'share', 'share'); + link = this.addLink(navType, 'nav-share', '#/share', 'share', 'share', 'share', 'Control+S'); } } else if (navType === 'menu') { // Save HTML so it can be added to menu once MMenu is initialised @@ -424,13 +441,13 @@ FluidbookNav.prototype = { } } else if (icon === 'bookmark' && this.fluidbook.settings.bookmark) { - link = this.addLink(navType, 'nav-bookmarks', '#/bookmark', 'bookmarks', 'bookmarks', 'bookmarks'); + link = this.addLink(navType, 'nav-bookmarks', '#/bookmark', 'bookmarks', 'bookmarks', 'bookmarks', 'Control+B'); } else if (icon === 'pdf' && this.fluidbook.settings.pdf) { - link = this.addLink(navType, 'nav-download', '#', 'download', 'download', 'download'); + link = this.addLink(navType, 'nav-download', '#', 'download', 'download', 'download', 'Control+Alt+D'); } else if (icon === 'print' && this.fluidbook.settings.print) { - link = this.addLink(navType, 'nav-print', '#', 'print', 'print', 'print'); + link = this.addLink(navType, 'nav-print', '#', 'print', 'print', 'print', 'Control+P'); } else if (icon === 'basket' && this.fluidbook.cart !== undefined && this.fluidbook.cart.enabled) { - link = this.addLink(navType, 'nav-basket', '#/cart', 'cart', 'basket', 'basket'); + link = this.addLink(navType, 'nav-basket', '#/cart', 'cart', 'basket', 'basket', 'Control+Alt+C'); $(this.fluidbook).on('fluidbook.cart.updateIcon', {link: $(link).attr('id')}, function (e, data) { var n = data.number; var l = $("#" + e.data.link); @@ -451,31 +468,31 @@ FluidbookNav.prototype = { } } else if (icon === 'lang' && this.fluidbook.l10n.multilangEnabled) { // Note: the "!" at the beginning of the title/help parameters means that we don't want these strings translated - link = this.addLink(navType, 'nav-locales', '#/locales', 'locales', '!' + this.fluidbook.l10n.getCurrentLanguageName(), '!Select Language'); + link = this.addLink(navType, 'nav-locales', '#/locales', 'locales', '!' + this.fluidbook.l10n.getCurrentLanguageName(), '!Select Language', 'Control+L'); } else if (icon === 'archives') { if (this.fluidbook.settings.archivesLink !== '') { - link = this.addLink(navType, 'nav-archives', this.fluidbook.settings.archivesLink, 'archives', '!' + this.fluidbook.settings.archivesLabel, '!' + this.fluidbook.settings.archivesLabel); + link = this.addLink(navType, 'nav-archives', this.fluidbook.settings.archivesLink, 'archives', '!' + this.fluidbook.settings.archivesLabel, '!' + this.fluidbook.settings.archivesLabel, ''); } else if (this.fluidbook.settings.externalArchives !== '') { - link = this.addLink(navType, 'nav-archives', '#/archives', 'archives', '!' + this.fluidbook.settings.archivesLabel, '!' + this.fluidbook.settings.archivesLabel); + link = this.addLink(navType, 'nav-archives', '#/archives', 'archives', '!' + this.fluidbook.settings.archivesLabel, '!' + this.fluidbook.settings.archivesLabel, ''); } } else if (icon === 'help') { - link = this.addLink(navType, 'nav-help', '#', 'help', 'help', 'help'); + link = this.addLink(navType, 'nav-help', '#', 'help', 'help', 'help', 'F1'); } else if (icon === 'zoom' && !this.fluidbook.support.isMobile) { link = this.addLink(navType, 'nav-zoomin', '#', 'zoomin', 'zoom in', 'zoom in'); link = this.addLink(navType, 'nav-zoomout', '#', 'zoomout', 'zoom out', 'zoom out'); } else if (icon === 'fullscreen' && this.fluidbook.support.fullscreen && !this.fluidbook.settings.phonegap) { - link = this.addLink(navType, 'nav-' + icon, '#', icon, 'full screen', 'switch between fullscreen and normal'); + link = this.addLink(navType, 'nav-' + icon, '#', icon, 'full screen', 'switch between fullscreen and normal', 'F11'); } else if (icon === 'sound' && this.fluidbook.sound.enabled) { - link = this.addLink(navType, 'nav-sound-on', '#', 'sound-on', 'switch off the sound', 'switch on / switch off the sound'); - link2 = this.addLink(navType, 'nav-sound-off', '#', 'sound-off', 'switch on the sound', 'switch on / switch off the sound'); + link = this.addLink(navType, 'nav-sound-on', '#', 'sound-on', 'switch off the sound', 'switch on / switch off the sound', 'F10'); + link2 = this.addLink(navType, 'nav-sound-off', '#', 'sound-off', 'switch on the sound', 'switch on / switch off the sound', 'Alt+A'); } else if (icon === 'search') { // Only the horizontal icon menu has the search icon, which opens the main menu if (this.fluidbook.settings.search && navType === 'horizontalNav') { - link = this.addLink(navType, 'nav-search', '#', 'searchIcon', 'search', 'search'); + link = this.addLink(navType, 'nav-search', '#', 'searchIcon', 'search', 'search', 'Control+F'); } } else if (icon === 'extra') { @@ -525,7 +542,7 @@ FluidbookNav.prototype = { if (extraIcon.indexOf('.') === -1) { linkIcon = getSpriteIcon(extraIcon); } else { - if ((extraIcon.indexOf('.svg') >= 0) && (extraType === 'icon')) { + if ((extraIcon.indexOf('.addLink') >= 0) && (extraType === 'icon')) { if (getSpriteIcon('extra-extra' + n) === '') { var url = 'data/images/' + extraIcon; extraNPerURL[url] = n;