]> _ Git - fluidbook-html5.git/commitdiff
wip #3758 @2
authorVincent Vanwaelscappel <vincent@cubedesigners.com>
Thu, 2 Jul 2020 18:07:11 +0000 (20:07 +0200)
committerVincent Vanwaelscappel <vincent@cubedesigners.com>
Thu, 2 Jul 2020 18:07:11 +0000 (20:07 +0200)
js/libs/fluidbook/fluidbook.interface.js
js/libs/fluidbook/fluidbook.js
js/libs/fluidbook/fluidbook.keyboard.js [new file with mode: 0644]
js/libs/fluidbook/fluidbook.nav.js

index 50cb13ef96668c22a26a96a7aa940be60d541ca4..6ac393e1fb659a0c3e244ff4651aa3160963a444 100644 (file)
@@ -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 += '<div id="next-arrows">';
-                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 += '</div>';
                 res += '<div id="prev-arrows">';
-                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 += '</div>';
             } else {
                 res += '<div id="next-arrows">';
-                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 += '</div>';
                 res += '<div id="prev-arrows">';
-                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 += '</div>';
             }
 
index 50313f600767dbd2f04cb2ea34807de7ecd8b30e..4de1cdc23096214e4c67b0d25774de90e8799e1c 100644 (file)
@@ -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 (file)
index 0000000..de10da5
--- /dev/null
@@ -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
index e19c0c3e94ced903a4a4933ba4515571a0c4e991..187e20fe4697fac0ef34faf4de896a4975071fa7 100644 (file)
@@ -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 = '<li>' + l[0].outerHTML + '</li>';
         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;