]> _ Git - fluidbook-html5.git/commitdiff
wip #1388 @10
authorVincent Vanwaelscappel <vincent@cubedesigners.com>
Tue, 30 May 2017 17:12:52 +0000 (19:12 +0200)
committerVincent Vanwaelscappel <vincent@cubedesigners.com>
Tue, 30 May 2017 17:12:52 +0000 (19:12 +0200)
.htaccess
_index.html
images/interface.svg
js/libs/fluidbook/fluidbook.bookmarks.js
js/libs/fluidbook/fluidbook.js
js/libs/fluidbook/fluidbook.links.js
js/libs/fluidbook/fluidbook.menu.js
js/libs/fluidbook/fluidbook.resize.js
js/libs/fluidbook/fluidbook.utils.js
js/libs/jquery/perfect-scrollbar.jquery.js [new file with mode: 0644]
style/fluidbook.less

index f99e52e4a47c074f08eecd3ab58741777cdf0783..bb66b465bb81b70c9ad5649e3351d68da2f8e08e 100644 (file)
--- a/.htaccess
+++ b/.htaccess
@@ -11,6 +11,7 @@
        AddType application/octet-stream .otf\r
        AddType application/octet-stream .ttf\r
        AddType application/x-font-woff .woff\r
+       AddType font/woff2 .woff2\r
        AddType text/cache-manifest .appcache\r
 \r
        AddEncoding gzip svgz\r
index 02bd7dfd56a80df2e251860a46a9d7e919b22288..39cd025e81f978f11de7a65237cd829b7f4a7f0c 100644 (file)
@@ -20,7 +20,7 @@
 </head>
 <body style="background-color:#<!-- $bgcolor -->;" data-branch="menus">
 <!--googleoff: all-->
-<!-- $svg -->
+<div style="display:none;" id="svg-container"><!-- $svg --></div>
 <div id="message"><!-- $message --></div>
 <!--googleon: all-->
 <div id="main">
index 70bf1ad61b5557a587f274e5223912282392502a..1386df0c712ba8b0aebd410c534eb44526fbce89 100644 (file)
@@ -1,5 +1,5 @@
-<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
-    <symbol viewBox="0 0 17 17" id="close">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <symbol viewBox="0 0 17 17" id="interface-close">
         <path id="p1" class="fill-c-menu-text" d="M0.01472 2.13604L2.13604 0.014720000000000066L16.98528 14.86396L14.863959999999999 16.98528Z" fill-opacity="1" transform="matrix(1,0,0,1,0,0)"></path>
         <path id="p2" class="fill-c-menu-text" d="M2.13604 16.98528L0.014720000000000066 14.863959999999999L14.86396 0.014719999999998734L16.98528 2.1360399999999986Z" fill-opacity="1" transform="matrix(1,0,0,1,0,0)"></path>
     </symbol>
index f4a7b23aa4260a4d2b530152045f79410c06909c..13753a4ed51a5d0e0dd7f3fd8bd433e75b9d6f47 100644 (file)
 function FluidbookBookmarks(fluidbook) {
-       this.fluidbook = fluidbook;
-       this.enabled = false;
-       this.bookmarks = [];
+    this.fluidbook = fluidbook;
+    this.enabled = false;
+    this.bookmarks = [];
 
-       this._pagesToGroup = [];
-       this._groupNames = [];
-       this._groups = 0;
-       this._groupOrder = [];
+    this._pagesToGroup = [];
+    this._groupNames = [];
+    this._groups = 0;
+    this._groupOrder = [];
 
-       this._cornersIndex = [];
-       this._cornersPages = [];
+    this._cornersIndex = [];
+    this._cornersPages = [];
 
-       this.enabled = this.fluidbook.datas.bookmark;
-       this.init();
+    this.enabled = this.fluidbook.datas.bookmark;
+    this.init();
 }
 
 FluidbookBookmarks.prototype = {
-       init: function() {
-               var $this = this;
-               $(document).on('click', '.bookmark', function() {
-                       $this.toggleBookmark(parseInt($(this).attr('data-page')));
-                       return false;
-               });
-
-               $(document).on('click', '.bookmarkssub a.send', function() {
-                       var subject = '%title%';
-                       if ($this.fluidbook.datas.bookmark_email_title != '') {
-                               subject = $this.fluidbook.datas.bookmark_email_title;
-                       }
-
-
-                       var body = $this.fluidbook.l10n.__('Please see the attached files from "%title%".');
-                       if ($this.fluidbook.datas.bookmark_email_body != '') {
-                               body = $this.fluidbook.datas.bookmark_email_body;
-                       }
-
-                       subject = subject.replace(/\%title\%/gi, $this.fluidbook.datas.title);
-                       body = trim(body.replace(/\%title\%/gi, $this.fluidbook.datas.title), ' .');
-                       body += " : " + $this.getPDF();
-
-                       $this.fluidbook.intentShare(subject, body);
-                       return false;
-               });
-
-               $(document).on('click', '.bookmarkssub a.print', function() {
-                       $this.fluidbook._openFile($this.getPDF(), $(this), 'pdf', $this.getBookmarksCompacted() + '.pdf');
-                       return false;
-               });
-
-               for (var g in this.fluidbook.datas.bookmarkGroups) {
-
-                       var group = this.fluidbook.datas.bookmarkGroups[g];
-                       this.addGroup(group.page, group.nb, group.name);
-               }
-               this.completeGroups();
-               this._groupOrder.sort($.proxy(this.sortGroup, this));
-
-               this.bookmarks = this.getSavedBookmarks();
-               for (var i in this.bookmarks) {
-                       this.addBookmark(this.bookmarks[i], true);
-               }
-       },
-       sortGroup: function(a, b) {
-               var p_a = this.getPagesOfGroup(a)[0];
-               var p_b = this.getPagesOfGroup(b)[0];
-               return p_a - p_b;
-       },
-       sortnumeric: function(a, b) {
-               return a - b;
-       },
-       getPDF: function() {
-               return  'https://workshop.fluidbook.com/s/e/' + this.fluidbook.datas.cid + '/' + this.getBookmarksCompacted();
-       },
-       getBookmarksCompacted: function() {
-               this.bookmarks.sort(this.sortnumeric);
-
-               var g = [];
-               var rs = 0;
-               var re = 0;
-               for (var i = 0; i < this.bookmarks.length; i++) {
-                       var b = this.bookmarks[i];
-                       if (rs == 0) {
-                               rs = re = b;
-                               continue;
-                       }
-                       if (re + 1 == b) {
-                               re = b;
-                               continue;
-                       }
-                       if (rs == re) {
-                               g.push('' + rs);
-                       } else {
-                               g.push(rs + '-' + re);
-                       }
-
-                       rs = re = b;
-               }
-
-               if (rs != 0) {
-                       if (rs == re) {
-                               g.push('' + rs);
-                       } else {
-                               g.push(rs + '-' + re);
-                       }
-               }
-
-               return g.join(',');
-       },
-       addGroup: function(from, nb, name) {
-               var to = Math.min(from + (nb - 1), this.fluidbook.datas.pages);
-               for (var i = from; i <= to; i++)
-               {
-                       this._pagesToGroup[i] = this._groups;
-               }
-               this._groupNames[this._groups] = name;
-               this._groupOrder.push(this._groups);
-               this._groups++;
-       },
-       completeGroups: function() {
-               for (var i = 1; i <= this.fluidbook.datas.pages; i++) {
-                       if (this._pagesToGroup[i] == undefined || this._pagesToGroup[i] == null) {
-                               this._pagesToGroup[i] = this._groups;
-                               this._groupOrder.push(this._groups);
-                               this._groups++;
-                       }
-               }
-       },
-       getPreviousGroup: function(group) {
-               var o = this.getOrderGroup(group);
-               if (o == -1) {
-                       return false;
-               }
-               o--;
-               return this._groupOrder[o];
-       },
-       getNextGroup: function(group) {
-               var o = this.getOrderGroup(group);
-               if (o == -1) {
-                       return false;
-               }
-               o++;
-               return this._groupOrder[o];
-       },
-       getOrderGroup: function(group) {
-               return this._groupOrder.indexOf(group);
-       },
-       getGroupName: function(groupId)
-       {
-               var res = '';
-               if (this._groupNames[groupId] != undefined) {
-                       res = this._groupNames[groupId];
-               }
-               if (res == '') {
-                       var pages = this.getPagesOfGroup(groupId);
-                       res = this.fluidbook.physicalToVirtual(pages[0]);
-                       if (pages.length == 1) {
-                               return res;
-                       }
-                       res += " - " + this.fluidbook.physicalToVirtual(pages[pages.length - 1]);
-               }
-               return res;
-       },
-       getPagesOfGroup: function(groupId)
-       {
-               var res = [];
-               for (var i = 1; i <= this.fluidbook.datas.pages; i++) {
-                       if (this._pagesToGroup[i] == groupId) {
-                               res.push(i);
-                       }
-               }
-               return res;
-       },
-       getPagesNumberInGroup: function(groupId) {
-               return this.getPagesOfGroup(groupId).length;
-       },
-       getBookmarkedGroups: function(onlyBookmarked)
-       {
-               if (onlyBookmarked == undefined) {
-                       onlyBookmarked = true;
-               }
-
-               var res = [];
-               var nb;
-               var groupId;
-               for (var i = 1; i <= this.fluidbook.datas.pages; ) {
-                       if (this.isBookmarked(i) || !onlyBookmarked) {
-                               groupId = this.getGroupOfPage(i);
-                               nb = this.getPagesNumberInGroup(groupId);
-                               res.push({page: i, nb: nb, name: this.getGroupName(groupId)});
-                               i += nb;
-                               continue;
-                       }
-                       i++;
-               }
-               return res;
-       },
-       getOrderedGroups: function() {
-               return this.getBookmarkedGroups(false);
-       },
-       getGroupOfPage: function(page) {
-               return this._pagesToGroup[page];
-       },
-       getNextPageInGroupOfPage: function(page) {
-               var group = this.getLinkedPages(page);
-               var index = group.indexOf(page);
-               if (index == group.length - 1) {
-                       return false;
-               }
-               return group[index + 1];
-       },
-       getPreviousPageInGroupOfPage: function(page) {
-               var group = this.getLinkedPages(page);
-               var index = group.indexOf(page);
-               if (index == 0) {
-                       return false;
-               }
-               return group[index - 1];
-       },
-       getNextGroupCover: function(page) {
-               var group = this.getGroupOfPage(page);
-               group = this.getNextGroup(group);
-               if (group === false) {
-                       return false;
-               }
-               return this.getCoverOfGroup(group);
-       },
-       getPreviousGroupCover: function(page) {
-               var group = this.getGroupOfPage(page);
-               group = this.getPreviousGroup(group);
-               if (group === false) {
-                       return false;
-               }
-               return this.getCoverOfGroup(group);
-       },
-       getCoverOfGroup: function(group) {
-               var pages = this.getPagesOfGroup(group);
-               if (pages.length) {
-                       return pages[0];
-               }
-               return false;
-       },
-       hasNextPageInGroup: function(page) {
-               var group = this.getGroupOfPage(page);
-               var pages = this.getPagesOfGroup(group);
-               var i = pages.indexOf(page);
-               if (i == pages.length - 1) {
-                       return false;
-               }
-               return true;
-       },
-       getLinkedPages: function(page) {
-               var group = this.getGroupOfPage(page);
-               if (group == -1 || isNaN(group)) {
-                       return [];
-               }
-               return this.getPagesOfGroup(group);
-       },
-       addBookmark: function(page, cornersOnly)
-       {
-               if (cornersOnly == undefined) {
-                       cornersOnly = false;
-               }
-               var pages = this.getLinkedPages(page);
-               for (i in pages)
-               {
-                       var page = pages[i];
-                       if (!cornersOnly) {
-                               this.bookmarks.push(page);
-                       }
-               }
-               if (!cornersOnly) {
-                       this.updateBookmarks();
-                       // TODO add stats call
-               }
-       },
-       setCornersEnabled: function(page, enabled) {
-               var bookmarks = $('.bookmark[data-page="' + page + '"]');
-               if (enabled) {
-                       $(bookmarks).attr('data-enabled', 'enabled');
-               } else {
-                       $(bookmarks).attr('data-enabled', null);
-               }
-       },
-       disableCorners: function() {
-               $(".bookmark").attr('data-enabled', null);
-       },
-       toggleBookmark: function(page) {
-
-               var pages = this.getLinkedPages(page);
-               var add = false;
-               for (var i in pages) {
-                       var p = pages[i];
-                       if (this.bookmarks.indexOf(p) > -1) {
-                               add = true;
-                               break;
-                       }
-               }
-               if (add) {
-                       this.removeBookmark(page);
-               } else {
-                       this.addBookmark(page);
-               }
-       },
-       removeBookmark: function(page) {
-               var pages = this.getLinkedPages(page);
-               for (var i in pages) {
-                       this.bookmarks = arrayRemove(this.bookmarks, pages[i]);
-               }
-               this.updateBookmarks();
-       },
-       updateBookmarks: function() {
-               this.saveBookmarks();
-               var $this = this;
-
-               this.disableCorners();
-               $.each(this.bookmarks, function(k, v) {
-                       $this.setCornersEnabled(v, true);
-               });
-       },
-       saveBookmarks: function() {
-               this.fluidbook.cache.set('bookmarks', this.bookmarks);
-       },
-       getSavedBookmarks: function() {
-               if (this.fluidbook.cache.isset('bookmarks')) {
-                       return this.fluidbook.cache.get('bookmarks');
-               }
-               return [];
-       },
-       isBookmarked: function(page) {
-               return this.bookmarks.indexOf(page) > -1;
-       },
-       getBookmarkForPage: function(pageNr, onlyOne, allwaysAtRight) {
-               if (onlyOne == undefined) {
-                       onlyOne = false;
-               }
-               if (allwaysAtRight == undefined) {
-                       allwaysAtRight = false;
-               }
-
-               var to = pageNr;
-               if (!onlyOne) {
-                       to++;
-               }
-
-               var bookmarks = "";
-               for (var i = pageNr; i <= to; i++) {
-                       if (i > 0 && i <= this.fluidbook.datas.pages) {
-                               var side;
-                               if (allwaysAtRight) {
-                                       side = 'right';
-                               } else {
-                                       side = (i % 2 == 0) ? 'left' : 'right';
-                                       if (this.fluidbook.l10n.dir == 'rtl') {
-                                               side = side == 'left' ? 'right' : 'left';
-                                       }
-                               }
-
-                               bookmarks += "<a href=\"#\" class=\"bookmark " + side + "\" data-page=\"" + i + "\"";
-                               if (this.isBookmarked(i)) {
-                                       bookmarks += " data-enabled=\"enabled\"";
-                               }
-                               bookmarks += '></a>';
-                       }
-               }
-               return bookmarks;
-       },
-       getView: function() {
-               var c = this.getIndex(false);
-               if (c === false) {
-                       return c;
-               }
-               var index = '<div class="bookmarkssub"><div class="caption"><a href="#" class="back miniOnPortrait"><span class="hideOnPortrait">' + this.fluidbook.l10n.__('back') + '</span></a><h2>' + this.fluidbook.l10n.__('bookmarks') + '</h2>';
-               index += '<div class="fonctions">';
-               if (this.fluidbook.datas.friend) {
-                       index += '<a class="send miniOnPortrait" href="#"><span class="hideOnPortrait">' + this.fluidbook.l10n.__('send') + '</span></a>';
-
-               }
-               if (this.fluidbook.datas.print || this.fluidbook.datas.pdf) {
-                       index += '<a class="print miniOnPortrait" href="#"><span class="hideOnPortrait">' + this.fluidbook.l10n.__('download') + '</span></a>';
-               }
-               index += '</div>';
-               index += '</div>';
-               index += '' + c + '</div>';
-               return index;
-       },
-       hasBookmarkedPages: function(all) {
-               if (all == undefined) {
-                       all = false;
-               }
-
-               if (all == false) {
-                       groups = this.getBookmarkedGroups();
-               } else {
-                       groups = this.getOrderedGroups();
-               }
-
-               if (groups.length == 0) {
-                       return false;
-               }
-               return true;
-       },
-       getIndex: function(all, onlyGroup) {
-               if (all == undefined) {
-                       all = false;
-               }
-               var groups;
-
-               if (all == false) {
-                       groups = this.getBookmarkedGroups();
-               } else {
-                       groups = this.getOrderedGroups();
-               }
-
-               if (groups.length == 0) {
-                       return false;
-               }
-
-               var index = '<div class="content"><div id="indexView" class="bookmarkView">';
-
-               if (onlyGroup == undefined) {
-                       for (var g = 0; g < groups.length; g++) {
-                               var group = groups[g];
-                               var pages = [];
-                               for (var i = 0; i < group.nb; i++) {
-                                       pages.push(group.page + i);
-                               }
-
-                               index += '<div class="doubleThumb simple left" page="' + group.page + '" data-pages="' + pages.join(',') + '">';
-                               index += '<div class="thumb left"><a href="#/page/' + group.page + '">' + this.fluidbook.loader.getImage('data/thumbnails/p' + group.page + '.jpg') + '</a><span class="number">' + group.name + '</span>';
-                               if (this.fluidbook.bookmarks.enabled) {
-                                       index += this.fluidbook.bookmarks.getBookmarkForPage(group.page, true, true);
-                               }
-                               index += '</div>';
-                               index += '</div>';
-                       }
-               } else {
-                       var group = groups[this.getGroupOfPage(onlyGroup)];
-
-                       var pages = [];
-                       for (var i = 0; i < group.nb; i++) {
-                               pages.push(group.page + i);
-                       }
-
-                       for (i in pages) {
-                               var p = pages[i];
-                               index += '<div class="doubleThumb simple left" page="' + p + '" data-pages="' + p + '">';
-                               index += '<div class="thumb left"><a href="#/page/' + p + '">' + this.fluidbook.loader.getImage('data/thumbnails/p' + p + '.jpg') + '</a><span class="number">' + this.fluidbook.physicalToVirtual(p) + '</span>';
-                               if (this.fluidbook.bookmarks.enabled) {
-                                       index += this.fluidbook.bookmarks.getBookmarkForPage(p, true, true);
-                               }
-                               index += '</div>';
-                               index += '</div>';
-                       }
-               }
-               index += '</div></div>';
-               return index;
-       }
+    init: function () {
+        var $this = this;
+        $(document).on('click', '.bookmark', function () {
+            $this.toggleBookmark(parseInt($(this).attr('data-page')));
+            return false;
+        });
+
+        $(document).on('click', '.bookmarkssub a.send', function () {
+            var subject = '%title%';
+            if ($this.fluidbook.datas.bookmark_email_title != '') {
+                subject = $this.fluidbook.datas.bookmark_email_title;
+            }
+
+
+            var body = $this.fluidbook.l10n.__('Please see the attached files from "%title%".');
+            if ($this.fluidbook.datas.bookmark_email_body != '') {
+                body = $this.fluidbook.datas.bookmark_email_body;
+            }
+
+            subject = subject.replace(/\%title\%/gi, $this.fluidbook.datas.title);
+            body = trim(body.replace(/\%title\%/gi, $this.fluidbook.datas.title), ' .');
+            body += " : " + $this.getPDF();
+
+            $this.fluidbook.intentShare(subject, body);
+            return false;
+        });
+
+        $(document).on('click', '.bookmarkssub a.print', function () {
+            $this.fluidbook._openFile($this.getPDF(), $(this), 'pdf', $this.getBookmarksCompacted() + '.pdf');
+            return false;
+        });
+
+        for (var g in this.fluidbook.datas.bookmarkGroups) {
+
+            var group = this.fluidbook.datas.bookmarkGroups[g];
+            this.addGroup(group.page, group.nb, group.name);
+        }
+        this.completeGroups();
+        this._groupOrder.sort($.proxy(this.sortGroup, this));
+
+        this.bookmarks = this.getSavedBookmarks();
+        for (var i in this.bookmarks) {
+            this.addBookmark(this.bookmarks[i], true);
+        }
+    },
+    sortGroup: function (a, b) {
+        var p_a = this.getPagesOfGroup(a)[0];
+        var p_b = this.getPagesOfGroup(b)[0];
+        return p_a - p_b;
+    },
+    sortnumeric: function (a, b) {
+        return a - b;
+    },
+    getPDF: function () {
+        return 'https://workshop.fluidbook.com/s/e/' + this.fluidbook.datas.cid + '/' + this.getBookmarksCompacted();
+    },
+    getBookmarksCompacted: function () {
+        this.bookmarks.sort(this.sortnumeric);
+
+        var g = [];
+        var rs = 0;
+        var re = 0;
+        for (var i = 0; i < this.bookmarks.length; i++) {
+            var b = this.bookmarks[i];
+            if (rs == 0) {
+                rs = re = b;
+                continue;
+            }
+            if (re + 1 == b) {
+                re = b;
+                continue;
+            }
+            if (rs == re) {
+                g.push('' + rs);
+            } else {
+                g.push(rs + '-' + re);
+            }
+
+            rs = re = b;
+        }
+
+        if (rs != 0) {
+            if (rs == re) {
+                g.push('' + rs);
+            } else {
+                g.push(rs + '-' + re);
+            }
+        }
+
+        return g.join(',');
+    },
+    addGroup: function (from, nb, name) {
+        var to = Math.min(from + (nb - 1), this.fluidbook.datas.pages);
+        for (var i = from; i <= to; i++) {
+            this._pagesToGroup[i] = this._groups;
+        }
+        this._groupNames[this._groups] = name;
+        this._groupOrder.push(this._groups);
+        this._groups++;
+    },
+    completeGroups: function () {
+        for (var i = 1; i <= this.fluidbook.datas.pages; i++) {
+            if (this._pagesToGroup[i] == undefined || this._pagesToGroup[i] == null) {
+                this._pagesToGroup[i] = this._groups;
+                this._groupOrder.push(this._groups);
+                this._groups++;
+            }
+        }
+    },
+    getPreviousGroup: function (group) {
+        var o = this.getOrderGroup(group);
+        if (o == -1) {
+            return false;
+        }
+        o--;
+        return this._groupOrder[o];
+    },
+    getNextGroup: function (group) {
+        var o = this.getOrderGroup(group);
+        if (o == -1) {
+            return false;
+        }
+        o++;
+        return this._groupOrder[o];
+    },
+    getOrderGroup: function (group) {
+        return this._groupOrder.indexOf(group);
+    },
+    getGroupName: function (groupId) {
+        var res = '';
+        if (this._groupNames[groupId] != undefined) {
+            res = this._groupNames[groupId];
+        }
+        if (res == '') {
+            var pages = this.getPagesOfGroup(groupId);
+            res = this.fluidbook.physicalToVirtual(pages[0]);
+            if (pages.length == 1) {
+                return res;
+            }
+            res += " - " + this.fluidbook.physicalToVirtual(pages[pages.length - 1]);
+        }
+        return res;
+    },
+    getPagesOfGroup: function (groupId) {
+        var res = [];
+        for (var i = 1; i <= this.fluidbook.datas.pages; i++) {
+            if (this._pagesToGroup[i] == groupId) {
+                res.push(i);
+            }
+        }
+        return res;
+    },
+    getPagesNumberInGroup: function (groupId) {
+        return this.getPagesOfGroup(groupId).length;
+    },
+    getBookmarkedGroups: function (onlyBookmarked) {
+        if (onlyBookmarked == undefined) {
+            onlyBookmarked = true;
+        }
+
+        var res = [];
+        var nb;
+        var groupId;
+        for (var i = 1; i <= this.fluidbook.datas.pages;) {
+            if (this.isBookmarked(i) || !onlyBookmarked) {
+                groupId = this.getGroupOfPage(i);
+                nb = this.getPagesNumberInGroup(groupId);
+                res.push({page: i, nb: nb, name: this.getGroupName(groupId)});
+                i += nb;
+                continue;
+            }
+            i++;
+        }
+        return res;
+    },
+    getOrderedGroups: function () {
+        return this.getBookmarkedGroups(false);
+    },
+    getGroupOfPage: function (page) {
+        return this._pagesToGroup[page];
+    },
+    getNextPageInGroupOfPage: function (page) {
+        var group = this.getLinkedPages(page);
+        var index = group.indexOf(page);
+        if (index == group.length - 1) {
+            return false;
+        }
+        return group[index + 1];
+    },
+    getPreviousPageInGroupOfPage: function (page) {
+        var group = this.getLinkedPages(page);
+        var index = group.indexOf(page);
+        if (index == 0) {
+            return false;
+        }
+        return group[index - 1];
+    },
+    getNextGroupCover: function (page) {
+        var group = this.getGroupOfPage(page);
+        group = this.getNextGroup(group);
+        if (group === false) {
+            return false;
+        }
+        return this.getCoverOfGroup(group);
+    },
+    getPreviousGroupCover: function (page) {
+        var group = this.getGroupOfPage(page);
+        group = this.getPreviousGroup(group);
+        if (group === false) {
+            return false;
+        }
+        return this.getCoverOfGroup(group);
+    },
+    getCoverOfGroup: function (group) {
+        var pages = this.getPagesOfGroup(group);
+        if (pages.length) {
+            return pages[0];
+        }
+        return false;
+    },
+    hasNextPageInGroup: function (page) {
+        var group = this.getGroupOfPage(page);
+        var pages = this.getPagesOfGroup(group);
+        var i = pages.indexOf(page);
+        if (i == pages.length - 1) {
+            return false;
+        }
+        return true;
+    },
+    getLinkedPages: function (page) {
+        var group = this.getGroupOfPage(page);
+        if (group == -1 || isNaN(group)) {
+            return [];
+        }
+        return this.getPagesOfGroup(group);
+    },
+    addBookmark: function (page, cornersOnly) {
+        if (cornersOnly == undefined) {
+            cornersOnly = false;
+        }
+        var pages = this.getLinkedPages(page);
+        for (i in pages) {
+            var page = pages[i];
+            if (!cornersOnly) {
+                this.bookmarks.push(page);
+            }
+        }
+        if (!cornersOnly) {
+            this.updateBookmarks();
+            // TODO add stats call
+        }
+    },
+    setCornersEnabled: function (page, enabled) {
+        var bookmarks = $('.bookmark[data-page="' + page + '"]');
+        if (enabled) {
+            $(bookmarks).attr('data-enabled', 'enabled');
+        } else {
+            $(bookmarks).attr('data-enabled', null);
+        }
+    },
+    disableCorners: function () {
+        $(".bookmark").attr('data-enabled', null);
+    },
+    toggleBookmark: function (page) {
+
+        var pages = this.getLinkedPages(page);
+        var add = false;
+        for (var i in pages) {
+            var p = pages[i];
+            if (this.bookmarks.indexOf(p) > -1) {
+                add = true;
+                break;
+            }
+        }
+        if (add) {
+            this.removeBookmark(page);
+        } else {
+            this.addBookmark(page);
+        }
+    },
+    removeBookmark: function (page) {
+        var pages = this.getLinkedPages(page);
+        for (var i in pages) {
+            this.bookmarks = arrayRemove(this.bookmarks, pages[i]);
+        }
+        this.updateBookmarks();
+    },
+    updateBookmarks: function () {
+        this.saveBookmarks();
+        var $this = this;
+
+        this.disableCorners();
+        $.each(this.bookmarks, function (k, v) {
+            $this.setCornersEnabled(v, true);
+        });
+    },
+    saveBookmarks: function () {
+        this.fluidbook.cache.set('bookmarks', this.bookmarks);
+    },
+    getSavedBookmarks: function () {
+        if (this.fluidbook.cache.isset('bookmarks')) {
+            return this.fluidbook.cache.get('bookmarks');
+        }
+        return [];
+    },
+    isBookmarked: function (page) {
+        return this.bookmarks.indexOf(page) > -1;
+    },
+    getBookmarkForPage: function (pageNr, onlyOne, allwaysAtRight) {
+        if (onlyOne == undefined) {
+            onlyOne = false;
+        }
+        if (allwaysAtRight == undefined) {
+            allwaysAtRight = false;
+        }
+
+        var to = pageNr;
+        if (!onlyOne) {
+            to++;
+        }
+
+        var bookmarks = "";
+        for (var i = pageNr; i <= to; i++) {
+            if (i > 0 && i <= this.fluidbook.datas.pages) {
+                var side;
+                if (allwaysAtRight) {
+                    side = 'right';
+                } else {
+                    side = (i % 2 == 0) ? 'left' : 'right';
+                    if (this.fluidbook.l10n.dir == 'rtl') {
+                        side = side == 'left' ? 'right' : 'left';
+                    }
+                }
+
+                bookmarks += "<a href=\"#\" class=\"bookmark " + side + "\" data-page=\"" + i + "\"";
+                if (this.isBookmarked(i)) {
+                    bookmarks += " data-enabled=\"enabled\"";
+                }
+                bookmarks += '></a>';
+            }
+        }
+        return bookmarks;
+    },
+    getView: function () {
+        var c = this.getIndex(false);
+        if (c === false) {
+            return c;
+        }
+        var index = '<div class="bookmarkssub"><div class="caption">' + this.fluidbook.menu.closeButton() + '<h2>' + this.fluidbook.l10n.__('bookmarks') + '</h2>';
+        index += '</div>';
+        index += c;
+        index += '</div>';
+        return index;
+    },
+    hasBookmarkedPages: function (all) {
+        if (all == undefined) {
+            all = false;
+        }
+
+        if (all == false) {
+            groups = this.getBookmarkedGroups();
+        } else {
+            groups = this.getOrderedGroups();
+        }
+
+        if (groups.length == 0) {
+            return false;
+        }
+        return true;
+    },
+    getIndex: function (all, onlyGroup) {
+        if (all == undefined) {
+            all = false;
+        }
+        var groups;
+
+        if (all == false) {
+            groups = this.getBookmarkedGroups();
+        } else {
+            groups = this.getOrderedGroups();
+        }
+
+        if (groups.length == 0) {
+            return false;
+        }
+
+        var index = '<div class="content"><div id="indexView" class="bookmarkView">';
+
+        if (onlyGroup == undefined) {
+            for (var g = 0; g < groups.length; g++) {
+                var group = groups[g];
+                var pages = [];
+                for (var i = 0; i < group.nb; i++) {
+                    pages.push(group.page + i);
+                }
+
+                index += '<div class="doubleThumb simple left" page="' + group.page + '" data-pages="' + pages.join(',') + '">';
+                index += '<div class="thumb left"><a href="#/page/' + group.page + '">' + this.fluidbook.loader.getImage('data/thumbnails/p' + group.page + '.jpg') + '</a><span class="number">' + group.name + '</span>';
+                if (this.fluidbook.bookmarks.enabled) {
+                    index += this.fluidbook.bookmarks.getBookmarkForPage(group.page, true, true);
+                }
+                index += '</div>';
+                index += '</div>';
+            }
+        } else {
+            var group = groups[this.getGroupOfPage(onlyGroup)];
+
+            var pages = [];
+            for (var i = 0; i < group.nb; i++) {
+                pages.push(group.page + i);
+            }
+
+            for (i in pages) {
+                var p = pages[i];
+                index += '<div class="doubleThumb simple left" page="' + p + '" data-pages="' + p + '">';
+                index += '<div class="thumb left"><a href="#/page/' + p + '">' + this.fluidbook.loader.getImage('data/thumbnails/p' + p + '.jpg') + '</a><span class="number">' + this.fluidbook.physicalToVirtual(p) + '</span>';
+                if (this.fluidbook.bookmarks.enabled) {
+                    index += this.fluidbook.bookmarks.getBookmarkForPage(p, true, true);
+                }
+                index += '</div>';
+                index += '</div>';
+            }
+        }
+        index += '</div>';
+        index += '<div class="fonctions">';
+        if (this.fluidbook.datas.friend) {
+            index += '<a class="send miniOnPortrait" href="#"><span class="hideOnPortrait">' + this.fluidbook.l10n.__('send') + '</span></a>';
+
+        }
+        if (this.fluidbook.datas.print || this.fluidbook.datas.pdf) {
+            index += '<a class="print miniOnPortrait" href="#"><span class="hideOnPortrait">' + this.fluidbook.l10n.__('download') + '</span></a>';
+        }
+        index += '</div>';
+        index += '</div>';
+        return index;
+    }
 };
\ No newline at end of file
index 8aba2646d7366df80e6267af039e2455dfb19991..839327a1756765b96902754b381a2311d439c6ec 100644 (file)
@@ -45,7 +45,6 @@ Fluidbook.prototype = {
         this.l10n = new FluidbookL10N(this, $_GET['lang']);
         this.video = new FluidbookVideo(this);
         this.bookmarks = new FluidbookBookmarks(this);
-        this.index = new FluidbookIndex(this);
         this.tooltip = new FluidbookTooltip(this);
         this.audiodescription = new FluidbookAudioDescription(this);
 
index 17efc1a01e82d1b1f1666a5d460c3b74fcc7c16f..0613a3005b95f8b0e498feaab4d87335a91c140f 100644 (file)
@@ -14,7 +14,7 @@ FluidbookLinks.prototype = {
         });
 
         // ToDo: consider re-using existing popinOverlay div?
-        $('body').append('<div id="zoomPopupOverlay"></div><div id="zoomPopupWrapper"><a href="#" class="zoomPopupClose"><svg viewBox="0 0 20 20"><use xlink:href="#close"></use></svg></a></div>');
+        $('body').append('<div id="zoomPopupOverlay"></div><div id="zoomPopupWrapper"><a href="#" class="zoomPopupClose">' + getSpriteIcon('interface-close') + '</a></div>');
 
 
         $(document).on('click touchend', '.zoomPopup', function (e) {
index 7bbe122c0ea0bdc32f4bb822cbbc6dcc55959a7d..dc2d9e517e8b3fbe48fbe1ee4a0acd7c20fc8509 100644 (file)
@@ -5,7 +5,7 @@ function FluidbookMenu(fluidbook) {
 
 FluidbookMenu.prototype = {
     init: function () {
-
+        this.index = new FluidbookIndex(this.fluidbook);
     },
 
     viewMode: function () {
@@ -13,11 +13,10 @@ FluidbookMenu.prototype = {
     },
     openView: function (view, param1, param2, callback) {
         var $this = this;
-        this.fluidbook.displayLoader();
-        this.fluidbook.resetWaiters();
+
         setTimeout(function () {
             $this._openView(view, param1, param2, callback);
-        }, 20);
+        }, 10);
     },
 
     _openView: function (view, param1, param2, callback) {
@@ -29,6 +28,8 @@ FluidbookMenu.prototype = {
             video: 'extras'
         };
         if (!OFFLINEAPP && this.fluidbook.gal != null && preload[view] != undefined) {
+            this.fluidbook.displayLoader();
+            this.fluidbook.resetWaiters();
             var w = this.fluidbook.addWaiter(true);
             this.fluidbook.gal.downloadAndCall(preload[view], function () {
                 if ($this.fluidbook.waiterActive(w)) {
@@ -40,6 +41,8 @@ FluidbookMenu.prototype = {
         }
     },
     __openView: function (view, param1, param2, callback) {
+        console.log('__openView(' + view + ',' + param1 + ',' + param2 + ')');
+
         var $this = this;
         var camelView = view.charAt(0).toUpperCase() + view.substr(1);
         var cb = function () {
@@ -74,19 +77,33 @@ FluidbookMenu.prototype = {
         }
     },
     openingView: function (callback) {
+        console.log('openingView');
         var $this = this;
         this.fluidbook.resize.resizeView();
         this.fluidbook.tooltip.hideTooltip();
         var mview = $('#view .mview:last');
 
         $(mview).show();
-        TweenMax.from($(mview), 0.5, {autoAlpha: 0}, {
-            autoAlpha: 1, onComplete: function () {
+        if (!Modernizr.ftouch) {
+            $(mview).find('.content').perfectScrollbar();
+        } else {
+            $(mview).find('.content').css({overflowY: 'auto'});
+        }
+
+        var from = {y: -200, opacity: 0};
+        var to = {
+            y: 0, opacity: 1, onComplete: function () {
+                console.log('end opening view');
                 callback();
                 $this.fluidbook.hideLoader();
                 resize();
             }
-        });
+        };
+        if (mview.hasClass('fs')) {
+            from.y = 0;
+        }
+        TweenMax.fromTo($(mview), 0.5, from, to);
+
     },
 
     displayResults: function (data, group, callback) {
@@ -151,27 +168,29 @@ FluidbookMenu.prototype = {
                 callback();
             }
         });
-    },
+    }
+    ,
     openMultimedia: function (multimedia, callback) {
         var a = $('a[href="#/multimedia/' + multimedia + '"]');
         var markup = decodeURIComponent($(a).attr('data-multimedia'));
-        var view = '<div class="caption"><a href="#" class="back">' + this.fluidbook.l10n.__('back') + '</a></div>';
+        var view = '<div class="caption">' + this.closeButton() + '</div>';
         view += '<div class="content"><div class="multimediaScale">';
         view += markup;
         view += '</div></div>';
-        $("#view").append('<div class="mview" dir="ltr">' + view + '</div>');
+        $("#view").append('<div class="mview" dir="ltr" data-menu="multimedia">' + view + '</div>');
         if (callback != undefined) {
             callback();
         }
-    },
+    }
+    ,
     openVideo: function (video, callback) {
         var a = $('a[href="#/video/' + video + '"]');
         var markup = decodeURIComponent($(a).attr('data-video'));
-        var view = '<div class="caption"><a href="#" class="back">' + this.fluidbook.l10n.__('back') + '</a></div>';
+        var view = '<div class="caption">' + this.closeButton() + '</div>';
         view += '<div class="content">';
         view += markup;
         view += '</div>';
-        $("#view").append('<div class="mview">' + view + '</div>');
+        $("#view").append('<div class="mview" data-menu="video">' + view + '</div>');
         this.fluidbook.stats.track(11);
         this.fluidbook.initVideos();
         var $this = this;
@@ -185,15 +204,25 @@ FluidbookMenu.prototype = {
             callback();
         }
         this.fluidbook.hideLoader(5);
-    },
+    }
+    ,
+    closeButton: function (c) {
+        if (c == undefined) {
+            c = '';
+        } else {
+            c = ' ' + c;
+        }
+        return '<a href="#" class="back' + c + '">' + getSpriteIcon('interface-close') + '</a>';
+    }
+    ,
     openAudio: function (audio, callback) {
         var a = $('a[href="#/audio/' + audio + '"]');
         var markup = decodeURIComponent($(a).attr('data-audio'));
-        var view = '<div class="caption"><a href="#" class="back">' + this.fluidbook.l10n.__('back') + '</a></div>';
+        var view = '<div class="caption">' + this.closeButton() + '</div>';
         view += '<div class="content">';
         view += markup;
         view += '</div>';
-        $("#view").append('<div class="mview">' + view + '</div>');
+        $("#view").append('<div class="mview" data-menu="audio">' + view + '</div>');
         this.fluidbook.stats.track(11);
         var $this = this;
         var times = [250, 500, 750, 1000, 1250];
@@ -205,10 +234,11 @@ FluidbookMenu.prototype = {
         if (callback != undefined) {
             callback();
         }
-    },
+    }
+    ,
     openWebVideo: function (service, video, callback) {
 
-        var view = '<div class="caption"><a href="#" class="back">' + this.fluidbook.l10n.__('back') + '</a></div>';
+        var view = '<div class="caption">' + this.closeButton() + '</div>';
         view += '<div class="content">';
 
         var h = this.fluidbook.resize.getPopupWebVideoHeight();
@@ -221,7 +251,7 @@ FluidbookMenu.prototype = {
             view += '<iframe class="webvideo" type="text/html" width="100%" height="' + h + '" src="./video/brightcove.html?pid=' + DATAS.brightcovePlayerId + '&pk=' + encodeURIComponent(DATAS.brightcovePlayerSecret) + '&vid=' + video + '" width="100%" frameborder="0"></iframe>'
         }
         view += '</div>';
-        $("#view").append('<div class="mview">' + view + '</div>');
+        $("#view").append('<div class="mview" data-menu="video">' + view + '</div>');
         $("#view .mview:last iframe").each(function () {
             $(this).attr('height', h);
             $(this).css('height', h);
@@ -230,9 +260,10 @@ FluidbookMenu.prototype = {
         if (callback != undefined) {
             callback();
         }
-    },
+    }
+    ,
     openLocales: function (p1, p2, callback) {
-        var view = '<div class="caption"><a href="#" class="back">' + this.fluidbook.l10n.__('back') + '</a><h2>Select language</h2></div>';
+        var view = '<div class="caption">' + this.closeButton() + '<h2>Select language</h2></div>';
         view += '<div class="content">';
         view += '<ul class="chapters localesList">';
         var $this = this;
@@ -263,13 +294,14 @@ FluidbookMenu.prototype = {
         });
         view += '</ul>';
         view += '</div>';
-        $("#view").append('<div class="mview">' + view + '</div>');
+        $("#view").append('<div class="mview" data-menu="locales">' + view + '</div>');
         if (callback != undefined) {
             callback();
         }
-    },
+    }
+    ,
     openShare: function (p1, p2, callback) {
-        var view = '<div class="caption"><a href="#" class="back">' + this.fluidbook.l10n.__('back') + '</a><h2>' + this.fluidbook.l10n.__('share') + '</h2></div>';
+        var view = '<div class="caption">' + this.closeButton() + '<h2>' + this.fluidbook.l10n.__('share') + '</h2></div>';
         view += '<div class="content">';
         view += '<ul class="chapters shareList">';
         var $this = this;
@@ -293,15 +325,16 @@ FluidbookMenu.prototype = {
         }
         view += '</ul>';
         view += '</div>';
-        $("#view").append('<div class="mview">' + view + '</div>');
+        $("#view").append('<div class="mview" data-menu="share">' + view + '</div>');
         if (callback != undefined) {
             callback();
         }
-    },
+    }
+    ,
     openBookmark: function (p1, p2, callback) {
         var view = this.fluidbook.bookmarks.getView();
         if (view !== false) {
-            $("#view").append('<div class="mview">' + view + '</div>');
+            $("#view").append('<div class="mview" data-menu="bookmarks">' + view + '</div>');
             if (callback != undefined) {
                 callback();
             }
@@ -317,39 +350,43 @@ FluidbookMenu.prototype = {
             }
             this.fluidbook.hideLoader();
         }
-    },
+    }
+    ,
     openChapters: function (callback) {
         if (this.fluidbook.chapters == undefined) {
             this.fluidbook.chapters = new FluidbookChapters(this.fluidbook, this.fluidbook.datas.chapters);
         }
 
-        var view = '<div class="caption"><a href="#" class="back">' + this.fluidbook.l10n.__('back') + '</a><h2>' + this.fluidbook.l10n.__('chapters') + '</h2></div>';
+        var view = '<div class="caption">' + this.closeButton() + '<h2>' + this.fluidbook.l10n.__('chapters') + '</h2></div>';
         view += '<div class="content">';
         view += this.fluidbook.chapters.getView();
         view += '</div>';
-        $("#view").append('<div class="mview">' + view + '</div>');
+        $("#view").append('<div class="mview" data-menu="chapters">' + view + '</div>');
         if (callback != undefined) {
             callback();
         }
-    },
+    }
+    ,
     openIndex: function (title, group, closeAll, callback) {
         var c = !closeAll ? ' one' : '';
-        var index = '<div class="caption"><a href="#" class="back' + c + '">' + this.fluidbook.l10n.__('back') + '</a><h2>' + title + '</h2></div>';
-        index += this.fluidbook.index.getView(group);
-        $("#view").append('<div class="mview">' + index + '</div>');
+        var index = '<div class="caption">' + this.closeButton(c) + '<h2>' + title + '</h2></div>';
+        index += this.index.getView(group);
+        $("#view").append('<div class="mview" data-menu="index">' + index + '</div>');
         this.fluidbook.bookmarks.updateBookmarks();
         if (callback != undefined) {
             callback();
         }
-    },
+    }
+    ,
     openArchives: function (title, callback) {
-        var archives = '<div class="caption"><a href="#" class="back">' + this.fluidbook.l10n.__('back') + '</a><h2>' + title + '</h2></div>';
+        var archives = '<div class="caption">' + this.closeButton() + '<h2>' + title + '</h2></div>';
         archives += '<div class="image" id="archivesview"><img src="data/images/' + this.fluidbook.datas.externalArchives + '" /><div class="links">' + this.fluidbook.datas.links.archives + '</div></div>';
-        $("#view").append('<div class="mview archives">' + archives + '</div>');
+        $("#view").append('<div class="mview archives" data-menu="archives">' + archives + '</div>');
         if (callback != undefined) {
             callback();
         }
-    },
+    }
+    ,
     closeView: function (callback, all, animate) {
         var $this = this;
         if (all == undefined) {
@@ -363,13 +400,6 @@ FluidbookMenu.prototype = {
             this.pause();
         });
 
-        if ($('.mview').scrollTop() > 0) {
-            $('.mview').scrollTo(0, 500, function () {
-                $this.closeView(callback, all, animate);
-            });
-            return;
-        }
-
         all = all || ($("#view .mview").length <= 1);
         if (!this.viewMode()) {
             callback();
@@ -393,23 +423,87 @@ FluidbookMenu.prototype = {
             to = {translateX: $(window).width() + 'px'}
         }
 
-        if (animate && this.fluidbook.support.transitions2d) {
-            setTimeout(function () {
-                $(mview).one($this.fluidbook.support.getTransitionEndEvent(), function () {
-                    $this.fluidbook.video.killVideosIn(this);
-                    $(this).remove();
-                    callback();
-                }).addClass('animate').transform(to);
-            }, 50);
-        } else {
-            this.fluidbook.video.killVideosIn(mview);
-            $(mview).remove()
-            callback();
-        }
+        TweenMax.to(mview, 0.25, {
+            autoAlpha: 0, onComplete: function () {
+                $this.fluidbook.video.killVideosIn(mview);
+                mview.remove();
+
+            }
+        });
+        callback();
+
         if (all) {
             $("#main").show();
             $('body').removeClass('view');
         }
         resize();
-    },
+    }
+    ,
+
+    resize: function (ww, hh) {
+
+        var m = $(".mview");
+        var w = ww * 0.6;
+        var h = hh * 0.8;
+        var forceHeight = false;
+        var fullscreen = false;
+
+        switch (m.data('menu')) {
+            case 'chapters':
+                w = this.fluidbook.datas.chaptersColMaxWidth * 1.5;
+                fullscreen = (w >= ww * 0.9);
+                break;
+            case 'index':
+                fullscreen = true;
+                break;
+            case 'share':
+                w = 200;
+                break;
+            case 'bookmarks':
+                var max = Math.floor((ww * 0.8) / 120) * 120 + 40;
+                w = Math.min(max, Math.max(m.find('.doubleThumb').length, 4) * 120 + 40);
+                break;
+            default:
+                break;
+        }
+
+
+        var captionHeight = m.find('.caption').outerHeight();
+        css = {};
+        ccss = {};
+        if (fullscreen) {
+            w = ww;
+            h = hh;
+            forceHeight = true;
+            css.top = 0;
+            css.left = 0;
+            m.addClass('fs');
+        } else {
+            m.removeClass('fs');
+        }
+        css.maxWidth = css.minWidth = css.width = w;
+        css.maxHeight = h;
+        ccss.maxHeight = h - captionHeight;
+        if (forceHeight) {
+            css.minHeight = css.height = h;
+            ccss.minHeight = ccss.height = h - captionHeight;
+        } else {
+            ccss.minHeight = ccss.height = css.minHeight = css.height = '';
+        }
+        m.css(css);
+        m.find(".content").css(ccss);
+        if (!fullscreen) {
+            m.css({top: (hh - m.outerHeight()) / 2, left: (ww - m.outerWidth()) / 2});
+        }
+
+        if (!Modernizr.ftouch) {
+            m.find('.content').perfectScrollbar('update');
+        }
+
+        if ($("#archivesview").length == 1) {
+            var w = this.fluidbook.datas.filesInfos.archives.width;
+            var ratio = $("#archivesview img").width() / w;
+            $("#archivesview .links").transform({scale: [ratio]});
+        }
+    }
 };
\ No newline at end of file
index 64ef6852c300ed5182a83e78a3f312d528673dba..f0fa937c5ab092b64ba239156f6801333de3da98 100644 (file)
@@ -334,44 +334,7 @@ FluidbookResize.prototype = {
     resizeView: function () {
         var $this = this;
         this.updateWindow();
-
-        $(".mview").css({
-            width: this.ww,
-            minHeight: this.hh,
-            maxHeight: this.hh,
-            height: this.hh
-        });
-
-        $(".mview").find('.caption,.content').css({
-            width: this.ww
-        });
-
-
-        $(".mview .caption h2").each(function () {
-            var wavailable = $this.ww;
-            $(this).parent().find('a.back').each(function () {
-                wavailable -= ($(this).outerWidth() + 10) * 2;
-            });
-            $(this).css('max-width', wavailable);
-        });
-
-        if ($("#archivesview").length == 1) {
-            var w = this.fluidbook.datas.filesInfos.archives.width;
-            var ratio = $("#archivesview img").width() / w;
-            $("#archivesview .links").transform({scale: [ratio]});
-        }
-
-        $(".bookmarkView").each(function () {
-            var w = $(this).parent().width();
-            var perCol = Math.floor(w / 120);
-
-            var uw = perCol * 120;
-            var m = (w - uw) / 2;
-            $(this).css({
-                width: uw,
-                margin: '0 auto'
-            })
-        });
+        this.fluidbook.menu.resize(this.ww, this.hh);
     },
     handleOrientation: function () {
         var $this = this;
index 841a353af9a43c888ef5c955696acff383b59732..252996f45825be54b854fad649f07bdca92d4bbe 100644 (file)
@@ -46,4 +46,18 @@ function getBaseURL(removeQuery) {
         l = e.join('/');
     }
     return l;
+}
+
+function getSpriteIcon(icon, attrs) {
+    var a = [];
+    if (attrs == undefined) {
+        attrs = {};
+    }
+    if (attrs.viewBox == null) {
+        attrs.viewBox = $('svg symbol#'+icon).get(0).attributes.viewBox.value;
+    }
+    $.each(attrs, function (k, v) {
+        a.push(k + '="' + v + '"');
+    });
+    return '<svg ' + a.join(' ') + '><use xlink:href="#' + icon + '" /></svg>';
 }
\ No newline at end of file
diff --git a/js/libs/jquery/perfect-scrollbar.jquery.js b/js/libs/jquery/perfect-scrollbar.jquery.js
new file mode 100644 (file)
index 0000000..fa1f79a
--- /dev/null
@@ -0,0 +1,1580 @@
+/* perfect-scrollbar v0.7.1 */
+(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+'use strict';
+
+var ps = require('../main');
+var psInstances = require('../plugin/instances');
+
+function mountJQuery(jQuery) {
+  jQuery.fn.perfectScrollbar = function (settingOrCommand) {
+    return this.each(function () {
+      if (typeof settingOrCommand === 'object' ||
+          typeof settingOrCommand === 'undefined') {
+        // If it's an object or none, initialize.
+        var settings = settingOrCommand;
+
+        if (!psInstances.get(this)) {
+          ps.initialize(this, settings);
+        }
+      } else {
+        // Unless, it may be a command.
+        var command = settingOrCommand;
+
+        if (command === 'update') {
+          ps.update(this);
+        } else if (command === 'destroy') {
+          ps.destroy(this);
+        }
+      }
+    });
+  };
+}
+
+if (typeof define === 'function' && define.amd) {
+  // AMD. Register as an anonymous module.
+  define(['jquery'], mountJQuery);
+} else {
+  var jq = window.jQuery ? window.jQuery : window.$;
+  if (typeof jq !== 'undefined') {
+    mountJQuery(jq);
+  }
+}
+
+module.exports = mountJQuery;
+
+},{"../main":7,"../plugin/instances":18}],2:[function(require,module,exports){
+'use strict';
+
+function oldAdd(element, className) {
+  var classes = element.className.split(' ');
+  if (classes.indexOf(className) < 0) {
+    classes.push(className);
+  }
+  element.className = classes.join(' ');
+}
+
+function oldRemove(element, className) {
+  var classes = element.className.split(' ');
+  var idx = classes.indexOf(className);
+  if (idx >= 0) {
+    classes.splice(idx, 1);
+  }
+  element.className = classes.join(' ');
+}
+
+exports.add = function (element, className) {
+  if (element.classList) {
+    element.classList.add(className);
+  } else {
+    oldAdd(element, className);
+  }
+};
+
+exports.remove = function (element, className) {
+  if (element.classList) {
+    element.classList.remove(className);
+  } else {
+    oldRemove(element, className);
+  }
+};
+
+exports.list = function (element) {
+  if (element.classList) {
+    return Array.prototype.slice.apply(element.classList);
+  } else {
+    return element.className.split(' ');
+  }
+};
+
+},{}],3:[function(require,module,exports){
+'use strict';
+
+var DOM = {};
+
+DOM.e = function (tagName, className) {
+  var element = document.createElement(tagName);
+  element.className = className;
+  return element;
+};
+
+DOM.appendTo = function (child, parent) {
+  parent.appendChild(child);
+  return child;
+};
+
+function cssGet(element, styleName) {
+  return window.getComputedStyle(element)[styleName];
+}
+
+function cssSet(element, styleName, styleValue) {
+  if (typeof styleValue === 'number') {
+    styleValue = styleValue.toString() + 'px';
+  }
+  element.style[styleName] = styleValue;
+  return element;
+}
+
+function cssMultiSet(element, obj) {
+  for (var key in obj) {
+    var val = obj[key];
+    if (typeof val === 'number') {
+      val = val.toString() + 'px';
+    }
+    element.style[key] = val;
+  }
+  return element;
+}
+
+DOM.css = function (element, styleNameOrObject, styleValue) {
+  if (typeof styleNameOrObject === 'object') {
+    // multiple set with object
+    return cssMultiSet(element, styleNameOrObject);
+  } else {
+    if (typeof styleValue === 'undefined') {
+      return cssGet(element, styleNameOrObject);
+    } else {
+      return cssSet(element, styleNameOrObject, styleValue);
+    }
+  }
+};
+
+DOM.matches = function (element, query) {
+  if (typeof element.matches !== 'undefined') {
+    return element.matches(query);
+  } else {
+    if (typeof element.matchesSelector !== 'undefined') {
+      return element.matchesSelector(query);
+    } else if (typeof element.webkitMatchesSelector !== 'undefined') {
+      return element.webkitMatchesSelector(query);
+    } else if (typeof element.mozMatchesSelector !== 'undefined') {
+      return element.mozMatchesSelector(query);
+    } else if (typeof element.msMatchesSelector !== 'undefined') {
+      return element.msMatchesSelector(query);
+    }
+  }
+};
+
+DOM.remove = function (element) {
+  if (typeof element.remove !== 'undefined') {
+    element.remove();
+  } else {
+    if (element.parentNode) {
+      element.parentNode.removeChild(element);
+    }
+  }
+};
+
+DOM.queryChildren = function (element, selector) {
+  return Array.prototype.filter.call(element.childNodes, function (child) {
+    return DOM.matches(child, selector);
+  });
+};
+
+module.exports = DOM;
+
+},{}],4:[function(require,module,exports){
+'use strict';
+
+var EventElement = function (element) {
+  this.element = element;
+  this.events = {};
+};
+
+EventElement.prototype.bind = function (eventName, handler) {
+  if (typeof this.events[eventName] === 'undefined') {
+    this.events[eventName] = [];
+  }
+  this.events[eventName].push(handler);
+  this.element.addEventListener(eventName, handler, false);
+};
+
+EventElement.prototype.unbind = function (eventName, handler) {
+  var isHandlerProvided = (typeof handler !== 'undefined');
+  this.events[eventName] = this.events[eventName].filter(function (hdlr) {
+    if (isHandlerProvided && hdlr !== handler) {
+      return true;
+    }
+    this.element.removeEventListener(eventName, hdlr, false);
+    return false;
+  }, this);
+};
+
+EventElement.prototype.unbindAll = function () {
+  for (var name in this.events) {
+    this.unbind(name);
+  }
+};
+
+var EventManager = function () {
+  this.eventElements = [];
+};
+
+EventManager.prototype.eventElement = function (element) {
+  var ee = this.eventElements.filter(function (eventElement) {
+    return eventElement.element === element;
+  })[0];
+  if (typeof ee === 'undefined') {
+    ee = new EventElement(element);
+    this.eventElements.push(ee);
+  }
+  return ee;
+};
+
+EventManager.prototype.bind = function (element, eventName, handler) {
+  this.eventElement(element).bind(eventName, handler);
+};
+
+EventManager.prototype.unbind = function (element, eventName, handler) {
+  this.eventElement(element).unbind(eventName, handler);
+};
+
+EventManager.prototype.unbindAll = function () {
+  for (var i = 0; i < this.eventElements.length; i++) {
+    this.eventElements[i].unbindAll();
+  }
+};
+
+EventManager.prototype.once = function (element, eventName, handler) {
+  var ee = this.eventElement(element);
+  var onceHandler = function (e) {
+    ee.unbind(eventName, onceHandler);
+    handler(e);
+  };
+  ee.bind(eventName, onceHandler);
+};
+
+module.exports = EventManager;
+
+},{}],5:[function(require,module,exports){
+'use strict';
+
+module.exports = (function () {
+  function s4() {
+    return Math.floor((1 + Math.random()) * 0x10000)
+               .toString(16)
+               .substring(1);
+  }
+  return function () {
+    return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
+           s4() + '-' + s4() + s4() + s4();
+  };
+})();
+
+},{}],6:[function(require,module,exports){
+'use strict';
+
+var cls = require('./class');
+var dom = require('./dom');
+
+var toInt = exports.toInt = function (x) {
+  return parseInt(x, 10) || 0;
+};
+
+var clone = exports.clone = function (obj) {
+  if (!obj) {
+    return null;
+  } else if (Array.isArray(obj)) {
+    return obj.map(clone);
+  } else if (typeof obj === 'object') {
+    var result = {};
+    for (var key in obj) {
+      result[key] = clone(obj[key]);
+    }
+    return result;
+  } else {
+    return obj;
+  }
+};
+
+exports.extend = function (original, source) {
+  var result = clone(original);
+  for (var key in source) {
+    result[key] = clone(source[key]);
+  }
+  return result;
+};
+
+exports.isEditable = function (el) {
+  return dom.matches(el, "input,[contenteditable]") ||
+         dom.matches(el, "select,[contenteditable]") ||
+         dom.matches(el, "textarea,[contenteditable]") ||
+         dom.matches(el, "button,[contenteditable]");
+};
+
+exports.removePsClasses = function (element) {
+  var clsList = cls.list(element);
+  for (var i = 0; i < clsList.length; i++) {
+    var className = clsList[i];
+    if (className.indexOf('ps-') === 0) {
+      cls.remove(element, className);
+    }
+  }
+};
+
+exports.outerWidth = function (element) {
+  return toInt(dom.css(element, 'width')) +
+         toInt(dom.css(element, 'paddingLeft')) +
+         toInt(dom.css(element, 'paddingRight')) +
+         toInt(dom.css(element, 'borderLeftWidth')) +
+         toInt(dom.css(element, 'borderRightWidth'));
+};
+
+function toggleScrolling(handler) {
+  return function (element, axis) {
+    handler(element, 'ps--in-scrolling');
+    if (typeof axis !== 'undefined') {
+      handler(element, 'ps--' + axis);
+    } else {
+      handler(element, 'ps--x');
+      handler(element, 'ps--y');
+    }
+  };
+}
+
+exports.startScrolling = toggleScrolling(cls.add);
+
+exports.stopScrolling = toggleScrolling(cls.remove);
+
+exports.env = {
+  isWebKit: typeof document !== 'undefined' && 'WebkitAppearance' in document.documentElement.style,
+  supportsTouch: typeof window !== 'undefined' && (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch),
+  supportsIePointer: typeof window !== 'undefined' && window.navigator.msMaxTouchPoints !== null
+};
+
+},{"./class":2,"./dom":3}],7:[function(require,module,exports){
+'use strict';
+
+var destroy = require('./plugin/destroy');
+var initialize = require('./plugin/initialize');
+var update = require('./plugin/update');
+
+module.exports = {
+  initialize: initialize,
+  update: update,
+  destroy: destroy
+};
+
+},{"./plugin/destroy":9,"./plugin/initialize":17,"./plugin/update":21}],8:[function(require,module,exports){
+'use strict';
+
+module.exports = {
+  handlers: ['click-rail', 'drag-scrollbar', 'keyboard', 'wheel', 'touch'],
+  maxScrollbarLength: null,
+  minScrollbarLength: null,
+  scrollXMarginOffset: 0,
+  scrollYMarginOffset: 0,
+  suppressScrollX: false,
+  suppressScrollY: false,
+  swipePropagation: true,
+  swipeEasing: true,
+  useBothWheelAxes: false,
+  wheelPropagation: false,
+  wheelSpeed: 1,
+  theme: 'default'
+};
+
+},{}],9:[function(require,module,exports){
+'use strict';
+
+var _ = require('../lib/helper');
+var dom = require('../lib/dom');
+var instances = require('./instances');
+
+module.exports = function (element) {
+  var i = instances.get(element);
+
+  if (!i) {
+    return;
+  }
+
+  i.event.unbindAll();
+  dom.remove(i.scrollbarX);
+  dom.remove(i.scrollbarY);
+  dom.remove(i.scrollbarXRail);
+  dom.remove(i.scrollbarYRail);
+  _.removePsClasses(element);
+
+  instances.remove(element);
+};
+
+},{"../lib/dom":3,"../lib/helper":6,"./instances":18}],10:[function(require,module,exports){
+'use strict';
+
+var instances = require('../instances');
+var updateGeometry = require('../update-geometry');
+var updateScroll = require('../update-scroll');
+
+function bindClickRailHandler(element, i) {
+  function pageOffset(el) {
+    return el.getBoundingClientRect();
+  }
+  var stopPropagation = function (e) { e.stopPropagation(); };
+
+  i.event.bind(i.scrollbarY, 'click', stopPropagation);
+  i.event.bind(i.scrollbarYRail, 'click', function (e) {
+    var positionTop = e.pageY - window.pageYOffset - pageOffset(i.scrollbarYRail).top;
+    var direction = positionTop > i.scrollbarYTop ? 1 : -1;
+
+    updateScroll(element, 'top', element.scrollTop + direction * i.containerHeight);
+    updateGeometry(element);
+
+    e.stopPropagation();
+  });
+
+  i.event.bind(i.scrollbarX, 'click', stopPropagation);
+  i.event.bind(i.scrollbarXRail, 'click', function (e) {
+    var positionLeft = e.pageX - window.pageXOffset - pageOffset(i.scrollbarXRail).left;
+    var direction = positionLeft > i.scrollbarXLeft ? 1 : -1;
+
+    updateScroll(element, 'left', element.scrollLeft + direction * i.containerWidth);
+    updateGeometry(element);
+
+    e.stopPropagation();
+  });
+}
+
+module.exports = function (element) {
+  var i = instances.get(element);
+  bindClickRailHandler(element, i);
+};
+
+},{"../instances":18,"../update-geometry":19,"../update-scroll":20}],11:[function(require,module,exports){
+'use strict';
+
+var _ = require('../../lib/helper');
+var dom = require('../../lib/dom');
+var instances = require('../instances');
+var updateGeometry = require('../update-geometry');
+var updateScroll = require('../update-scroll');
+
+function bindMouseScrollXHandler(element, i) {
+  var currentLeft = null;
+  var currentPageX = null;
+
+  function updateScrollLeft(deltaX) {
+    var newLeft = currentLeft + (deltaX * i.railXRatio);
+    var maxLeft = Math.max(0, i.scrollbarXRail.getBoundingClientRect().left) + (i.railXRatio * (i.railXWidth - i.scrollbarXWidth));
+
+    if (newLeft < 0) {
+      i.scrollbarXLeft = 0;
+    } else if (newLeft > maxLeft) {
+      i.scrollbarXLeft = maxLeft;
+    } else {
+      i.scrollbarXLeft = newLeft;
+    }
+
+    var scrollLeft = _.toInt(i.scrollbarXLeft * (i.contentWidth - i.containerWidth) / (i.containerWidth - (i.railXRatio * i.scrollbarXWidth))) - i.negativeScrollAdjustment;
+    updateScroll(element, 'left', scrollLeft);
+  }
+
+  var mouseMoveHandler = function (e) {
+    updateScrollLeft(e.pageX - currentPageX);
+    updateGeometry(element);
+    e.stopPropagation();
+    e.preventDefault();
+  };
+
+  var mouseUpHandler = function () {
+    _.stopScrolling(element, 'x');
+    i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler);
+  };
+
+  i.event.bind(i.scrollbarX, 'mousedown', function (e) {
+    currentPageX = e.pageX;
+    currentLeft = _.toInt(dom.css(i.scrollbarX, 'left')) * i.railXRatio;
+    _.startScrolling(element, 'x');
+
+    i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);
+    i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler);
+
+    e.stopPropagation();
+    e.preventDefault();
+  });
+}
+
+function bindMouseScrollYHandler(element, i) {
+  var currentTop = null;
+  var currentPageY = null;
+
+  function updateScrollTop(deltaY) {
+    var newTop = currentTop + (deltaY * i.railYRatio);
+    var maxTop = Math.max(0, i.scrollbarYRail.getBoundingClientRect().top) + (i.railYRatio * (i.railYHeight - i.scrollbarYHeight));
+
+    if (newTop < 0) {
+      i.scrollbarYTop = 0;
+    } else if (newTop > maxTop) {
+      i.scrollbarYTop = maxTop;
+    } else {
+      i.scrollbarYTop = newTop;
+    }
+
+    var scrollTop = _.toInt(i.scrollbarYTop * (i.contentHeight - i.containerHeight) / (i.containerHeight - (i.railYRatio * i.scrollbarYHeight)));
+    updateScroll(element, 'top', scrollTop);
+  }
+
+  var mouseMoveHandler = function (e) {
+    updateScrollTop(e.pageY - currentPageY);
+    updateGeometry(element);
+    e.stopPropagation();
+    e.preventDefault();
+  };
+
+  var mouseUpHandler = function () {
+    _.stopScrolling(element, 'y');
+    i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler);
+  };
+
+  i.event.bind(i.scrollbarY, 'mousedown', function (e) {
+    currentPageY = e.pageY;
+    currentTop = _.toInt(dom.css(i.scrollbarY, 'top')) * i.railYRatio;
+    _.startScrolling(element, 'y');
+
+    i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);
+    i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler);
+
+    e.stopPropagation();
+    e.preventDefault();
+  });
+}
+
+module.exports = function (element) {
+  var i = instances.get(element);
+  bindMouseScrollXHandler(element, i);
+  bindMouseScrollYHandler(element, i);
+};
+
+},{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],12:[function(require,module,exports){
+'use strict';
+
+var _ = require('../../lib/helper');
+var dom = require('../../lib/dom');
+var instances = require('../instances');
+var updateGeometry = require('../update-geometry');
+var updateScroll = require('../update-scroll');
+
+function bindKeyboardHandler(element, i) {
+  var hovered = false;
+  i.event.bind(element, 'mouseenter', function () {
+    hovered = true;
+  });
+  i.event.bind(element, 'mouseleave', function () {
+    hovered = false;
+  });
+
+  var shouldPrevent = false;
+  function shouldPreventDefault(deltaX, deltaY) {
+    var scrollTop = element.scrollTop;
+    if (deltaX === 0) {
+      if (!i.scrollbarYActive) {
+        return false;
+      }
+      if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)) {
+        return !i.settings.wheelPropagation;
+      }
+    }
+
+    var scrollLeft = element.scrollLeft;
+    if (deltaY === 0) {
+      if (!i.scrollbarXActive) {
+        return false;
+      }
+      if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)) {
+        return !i.settings.wheelPropagation;
+      }
+    }
+    return true;
+  }
+
+  i.event.bind(i.ownerDocument, 'keydown', function (e) {
+    if ((e.isDefaultPrevented && e.isDefaultPrevented()) || e.defaultPrevented) {
+      return;
+    }
+
+    var focused = dom.matches(i.scrollbarX, ':focus') ||
+                  dom.matches(i.scrollbarY, ':focus');
+
+    if (!hovered && !focused) {
+      return;
+    }
+
+    var activeElement = document.activeElement ? document.activeElement : i.ownerDocument.activeElement;
+    if (activeElement) {
+      if (activeElement.tagName === 'IFRAME') {
+        activeElement = activeElement.contentDocument.activeElement;
+      } else {
+        // go deeper if element is a webcomponent
+        while (activeElement.shadowRoot) {
+          activeElement = activeElement.shadowRoot.activeElement;
+        }
+      }
+      if (_.isEditable(activeElement)) {
+        return;
+      }
+    }
+
+    var deltaX = 0;
+    var deltaY = 0;
+
+    switch (e.which) {
+    case 37: // left
+      if (e.metaKey) {
+        deltaX = -i.contentWidth;
+      } else if (e.altKey) {
+        deltaX = -i.containerWidth;
+      } else {
+        deltaX = -30;
+      }
+      break;
+    case 38: // up
+      if (e.metaKey) {
+        deltaY = i.contentHeight;
+      } else if (e.altKey) {
+        deltaY = i.containerHeight;
+      } else {
+        deltaY = 30;
+      }
+      break;
+    case 39: // right
+      if (e.metaKey) {
+        deltaX = i.contentWidth;
+      } else if (e.altKey) {
+        deltaX = i.containerWidth;
+      } else {
+        deltaX = 30;
+      }
+      break;
+    case 40: // down
+      if (e.metaKey) {
+        deltaY = -i.contentHeight;
+      } else if (e.altKey) {
+        deltaY = -i.containerHeight;
+      } else {
+        deltaY = -30;
+      }
+      break;
+    case 33: // page up
+      deltaY = 90;
+      break;
+    case 32: // space bar
+      if (e.shiftKey) {
+        deltaY = 90;
+      } else {
+        deltaY = -90;
+      }
+      break;
+    case 34: // page down
+      deltaY = -90;
+      break;
+    case 35: // end
+      if (e.ctrlKey) {
+        deltaY = -i.contentHeight;
+      } else {
+        deltaY = -i.containerHeight;
+      }
+      break;
+    case 36: // home
+      if (e.ctrlKey) {
+        deltaY = element.scrollTop;
+      } else {
+        deltaY = i.containerHeight;
+      }
+      break;
+    default:
+      return;
+    }
+
+    updateScroll(element, 'top', element.scrollTop - deltaY);
+    updateScroll(element, 'left', element.scrollLeft + deltaX);
+    updateGeometry(element);
+
+    shouldPrevent = shouldPreventDefault(deltaX, deltaY);
+    if (shouldPrevent) {
+      e.preventDefault();
+    }
+  });
+}
+
+module.exports = function (element) {
+  var i = instances.get(element);
+  bindKeyboardHandler(element, i);
+};
+
+},{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],13:[function(require,module,exports){
+'use strict';
+
+var instances = require('../instances');
+var updateGeometry = require('../update-geometry');
+var updateScroll = require('../update-scroll');
+
+function bindMouseWheelHandler(element, i) {
+  var shouldPrevent = false;
+
+  function shouldPreventDefault(deltaX, deltaY) {
+    var scrollTop = element.scrollTop;
+    if (deltaX === 0) {
+      if (!i.scrollbarYActive) {
+        return false;
+      }
+      if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)) {
+        return !i.settings.wheelPropagation;
+      }
+    }
+
+    var scrollLeft = element.scrollLeft;
+    if (deltaY === 0) {
+      if (!i.scrollbarXActive) {
+        return false;
+      }
+      if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)) {
+        return !i.settings.wheelPropagation;
+      }
+    }
+    return true;
+  }
+
+  function getDeltaFromEvent(e) {
+    var deltaX = e.deltaX;
+    var deltaY = -1 * e.deltaY;
+
+    if (typeof deltaX === "undefined" || typeof deltaY === "undefined") {
+      // OS X Safari
+      deltaX = -1 * e.wheelDeltaX / 6;
+      deltaY = e.wheelDeltaY / 6;
+    }
+
+    if (e.deltaMode && e.deltaMode === 1) {
+      // Firefox in deltaMode 1: Line scrolling
+      deltaX *= 10;
+      deltaY *= 10;
+    }
+
+    if (deltaX !== deltaX && deltaY !== deltaY/* NaN checks */) {
+      // IE in some mouse drivers
+      deltaX = 0;
+      deltaY = e.wheelDelta;
+    }
+
+    if (e.shiftKey) {
+      // reverse axis with shift key
+      return [-deltaY, -deltaX];
+    }
+    return [deltaX, deltaY];
+  }
+
+  function shouldBeConsumedByChild(deltaX, deltaY) {
+    var child = element.querySelector('textarea:hover, select[multiple]:hover, .ps-child:hover');
+    if (child) {
+      var style = window.getComputedStyle(child);
+      var overflow = [
+        style.overflow,
+        style.overflowX,
+        style.overflowY
+      ].join('');
+
+      if (!overflow.match(/(scroll|auto)/)) {
+        // if not scrollable
+        return false;
+      }
+
+      var maxScrollTop = child.scrollHeight - child.clientHeight;
+      if (maxScrollTop > 0) {
+        if (!(child.scrollTop === 0 && deltaY > 0) && !(child.scrollTop === maxScrollTop && deltaY < 0)) {
+          return true;
+        }
+      }
+      var maxScrollLeft = child.scrollLeft - child.clientWidth;
+      if (maxScrollLeft > 0) {
+        if (!(child.scrollLeft === 0 && deltaX < 0) && !(child.scrollLeft === maxScrollLeft && deltaX > 0)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  function mousewheelHandler(e) {
+    var delta = getDeltaFromEvent(e);
+
+    var deltaX = delta[0];
+    var deltaY = delta[1];
+
+    if (shouldBeConsumedByChild(deltaX, deltaY)) {
+      return;
+    }
+
+    shouldPrevent = false;
+    if (!i.settings.useBothWheelAxes) {
+      // deltaX will only be used for horizontal scrolling and deltaY will
+      // only be used for vertical scrolling - this is the default
+      updateScroll(element, 'top', element.scrollTop - (deltaY * i.settings.wheelSpeed));
+      updateScroll(element, 'left', element.scrollLeft + (deltaX * i.settings.wheelSpeed));
+    } else if (i.scrollbarYActive && !i.scrollbarXActive) {
+      // only vertical scrollbar is active and useBothWheelAxes option is
+      // active, so let's scroll vertical bar using both mouse wheel axes
+      if (deltaY) {
+        updateScroll(element, 'top', element.scrollTop - (deltaY * i.settings.wheelSpeed));
+      } else {
+        updateScroll(element, 'top', element.scrollTop + (deltaX * i.settings.wheelSpeed));
+      }
+      shouldPrevent = true;
+    } else if (i.scrollbarXActive && !i.scrollbarYActive) {
+      // useBothWheelAxes and only horizontal bar is active, so use both
+      // wheel axes for horizontal bar
+      if (deltaX) {
+        updateScroll(element, 'left', element.scrollLeft + (deltaX * i.settings.wheelSpeed));
+      } else {
+        updateScroll(element, 'left', element.scrollLeft - (deltaY * i.settings.wheelSpeed));
+      }
+      shouldPrevent = true;
+    }
+
+    updateGeometry(element);
+
+    shouldPrevent = (shouldPrevent || shouldPreventDefault(deltaX, deltaY));
+    if (shouldPrevent) {
+      e.stopPropagation();
+      e.preventDefault();
+    }
+  }
+
+  if (typeof window.onwheel !== "undefined") {
+    i.event.bind(element, 'wheel', mousewheelHandler);
+  } else if (typeof window.onmousewheel !== "undefined") {
+    i.event.bind(element, 'mousewheel', mousewheelHandler);
+  }
+}
+
+module.exports = function (element) {
+  var i = instances.get(element);
+  bindMouseWheelHandler(element, i);
+};
+
+},{"../instances":18,"../update-geometry":19,"../update-scroll":20}],14:[function(require,module,exports){
+'use strict';
+
+var instances = require('../instances');
+var updateGeometry = require('../update-geometry');
+
+function bindNativeScrollHandler(element, i) {
+  i.event.bind(element, 'scroll', function () {
+    updateGeometry(element);
+  });
+}
+
+module.exports = function (element) {
+  var i = instances.get(element);
+  bindNativeScrollHandler(element, i);
+};
+
+},{"../instances":18,"../update-geometry":19}],15:[function(require,module,exports){
+'use strict';
+
+var _ = require('../../lib/helper');
+var instances = require('../instances');
+var updateGeometry = require('../update-geometry');
+var updateScroll = require('../update-scroll');
+
+function bindSelectionHandler(element, i) {
+  function getRangeNode() {
+    var selection = window.getSelection ? window.getSelection() :
+                    document.getSelection ? document.getSelection() : '';
+    if (selection.toString().length === 0) {
+      return null;
+    } else {
+      return selection.getRangeAt(0).commonAncestorContainer;
+    }
+  }
+
+  var scrollingLoop = null;
+  var scrollDiff = {top: 0, left: 0};
+  function startScrolling() {
+    if (!scrollingLoop) {
+      scrollingLoop = setInterval(function () {
+        if (!instances.get(element)) {
+          clearInterval(scrollingLoop);
+          return;
+        }
+
+        updateScroll(element, 'top', element.scrollTop + scrollDiff.top);
+        updateScroll(element, 'left', element.scrollLeft + scrollDiff.left);
+        updateGeometry(element);
+      }, 50); // every .1 sec
+    }
+  }
+  function stopScrolling() {
+    if (scrollingLoop) {
+      clearInterval(scrollingLoop);
+      scrollingLoop = null;
+    }
+    _.stopScrolling(element);
+  }
+
+  var isSelected = false;
+  i.event.bind(i.ownerDocument, 'selectionchange', function () {
+    if (element.contains(getRangeNode())) {
+      isSelected = true;
+    } else {
+      isSelected = false;
+      stopScrolling();
+    }
+  });
+  i.event.bind(window, 'mouseup', function () {
+    if (isSelected) {
+      isSelected = false;
+      stopScrolling();
+    }
+  });
+  i.event.bind(window, 'keyup', function () {
+    if (isSelected) {
+      isSelected = false;
+      stopScrolling();
+    }
+  });
+
+  i.event.bind(window, 'mousemove', function (e) {
+    if (isSelected) {
+      var mousePosition = {x: e.pageX, y: e.pageY};
+      var containerGeometry = {
+        left: element.offsetLeft,
+        right: element.offsetLeft + element.offsetWidth,
+        top: element.offsetTop,
+        bottom: element.offsetTop + element.offsetHeight
+      };
+
+      if (mousePosition.x < containerGeometry.left + 3) {
+        scrollDiff.left = -5;
+        _.startScrolling(element, 'x');
+      } else if (mousePosition.x > containerGeometry.right - 3) {
+        scrollDiff.left = 5;
+        _.startScrolling(element, 'x');
+      } else {
+        scrollDiff.left = 0;
+      }
+
+      if (mousePosition.y < containerGeometry.top + 3) {
+        if (containerGeometry.top + 3 - mousePosition.y < 5) {
+          scrollDiff.top = -5;
+        } else {
+          scrollDiff.top = -20;
+        }
+        _.startScrolling(element, 'y');
+      } else if (mousePosition.y > containerGeometry.bottom - 3) {
+        if (mousePosition.y - containerGeometry.bottom + 3 < 5) {
+          scrollDiff.top = 5;
+        } else {
+          scrollDiff.top = 20;
+        }
+        _.startScrolling(element, 'y');
+      } else {
+        scrollDiff.top = 0;
+      }
+
+      if (scrollDiff.top === 0 && scrollDiff.left === 0) {
+        stopScrolling();
+      } else {
+        startScrolling();
+      }
+    }
+  });
+}
+
+module.exports = function (element) {
+  var i = instances.get(element);
+  bindSelectionHandler(element, i);
+};
+
+},{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],16:[function(require,module,exports){
+'use strict';
+
+var _ = require('../../lib/helper');
+var instances = require('../instances');
+var updateGeometry = require('../update-geometry');
+var updateScroll = require('../update-scroll');
+
+function bindTouchHandler(element, i, supportsTouch, supportsIePointer) {
+  function shouldPreventDefault(deltaX, deltaY) {
+    var scrollTop = element.scrollTop;
+    var scrollLeft = element.scrollLeft;
+    var magnitudeX = Math.abs(deltaX);
+    var magnitudeY = Math.abs(deltaY);
+
+    if (magnitudeY > magnitudeX) {
+      // user is perhaps trying to swipe up/down the page
+
+      if (((deltaY < 0) && (scrollTop === i.contentHeight - i.containerHeight)) ||
+          ((deltaY > 0) && (scrollTop === 0))) {
+        return !i.settings.swipePropagation;
+      }
+    } else if (magnitudeX > magnitudeY) {
+      // user is perhaps trying to swipe left/right across the page
+
+      if (((deltaX < 0) && (scrollLeft === i.contentWidth - i.containerWidth)) ||
+          ((deltaX > 0) && (scrollLeft === 0))) {
+        return !i.settings.swipePropagation;
+      }
+    }
+
+    return true;
+  }
+
+  function applyTouchMove(differenceX, differenceY) {
+    updateScroll(element, 'top', element.scrollTop - differenceY);
+    updateScroll(element, 'left', element.scrollLeft - differenceX);
+
+    updateGeometry(element);
+  }
+
+  var startOffset = {};
+  var startTime = 0;
+  var speed = {};
+  var easingLoop = null;
+  var inGlobalTouch = false;
+  var inLocalTouch = false;
+
+  function globalTouchStart() {
+    inGlobalTouch = true;
+  }
+  function globalTouchEnd() {
+    inGlobalTouch = false;
+  }
+
+  function getTouch(e) {
+    if (e.targetTouches) {
+      return e.targetTouches[0];
+    } else {
+      // Maybe IE pointer
+      return e;
+    }
+  }
+  function shouldHandle(e) {
+    if (e.targetTouches && e.targetTouches.length === 1) {
+      return true;
+    }
+    if (e.pointerType && e.pointerType !== 'mouse' && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) {
+      return true;
+    }
+    return false;
+  }
+  function touchStart(e) {
+    if (shouldHandle(e)) {
+      inLocalTouch = true;
+
+      var touch = getTouch(e);
+
+      startOffset.pageX = touch.pageX;
+      startOffset.pageY = touch.pageY;
+
+      startTime = (new Date()).getTime();
+
+      if (easingLoop !== null) {
+        clearInterval(easingLoop);
+      }
+
+      e.stopPropagation();
+    }
+  }
+  function touchMove(e) {
+    if (!inLocalTouch && i.settings.swipePropagation) {
+      touchStart(e);
+    }
+    if (!inGlobalTouch && inLocalTouch && shouldHandle(e)) {
+      var touch = getTouch(e);
+
+      var currentOffset = {pageX: touch.pageX, pageY: touch.pageY};
+
+      var differenceX = currentOffset.pageX - startOffset.pageX;
+      var differenceY = currentOffset.pageY - startOffset.pageY;
+
+      applyTouchMove(differenceX, differenceY);
+      startOffset = currentOffset;
+
+      var currentTime = (new Date()).getTime();
+
+      var timeGap = currentTime - startTime;
+      if (timeGap > 0) {
+        speed.x = differenceX / timeGap;
+        speed.y = differenceY / timeGap;
+        startTime = currentTime;
+      }
+
+      if (shouldPreventDefault(differenceX, differenceY)) {
+        e.stopPropagation();
+        e.preventDefault();
+      }
+    }
+  }
+  function touchEnd() {
+    if (!inGlobalTouch && inLocalTouch) {
+      inLocalTouch = false;
+
+      if (i.settings.swipeEasing) {
+        clearInterval(easingLoop);
+        easingLoop = setInterval(function () {
+          if (!instances.get(element)) {
+            clearInterval(easingLoop);
+            return;
+          }
+
+          if (!speed.x && !speed.y) {
+            clearInterval(easingLoop);
+            return;
+          }
+
+          if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {
+            clearInterval(easingLoop);
+            return;
+          }
+
+          applyTouchMove(speed.x * 30, speed.y * 30);
+
+          speed.x *= 0.8;
+          speed.y *= 0.8;
+        }, 10);
+      }
+    }
+  }
+
+  if (supportsTouch) {
+    i.event.bind(window, 'touchstart', globalTouchStart);
+    i.event.bind(window, 'touchend', globalTouchEnd);
+    i.event.bind(element, 'touchstart', touchStart);
+    i.event.bind(element, 'touchmove', touchMove);
+    i.event.bind(element, 'touchend', touchEnd);
+  } else if (supportsIePointer) {
+    if (window.PointerEvent) {
+      i.event.bind(window, 'pointerdown', globalTouchStart);
+      i.event.bind(window, 'pointerup', globalTouchEnd);
+      i.event.bind(element, 'pointerdown', touchStart);
+      i.event.bind(element, 'pointermove', touchMove);
+      i.event.bind(element, 'pointerup', touchEnd);
+    } else if (window.MSPointerEvent) {
+      i.event.bind(window, 'MSPointerDown', globalTouchStart);
+      i.event.bind(window, 'MSPointerUp', globalTouchEnd);
+      i.event.bind(element, 'MSPointerDown', touchStart);
+      i.event.bind(element, 'MSPointerMove', touchMove);
+      i.event.bind(element, 'MSPointerUp', touchEnd);
+    }
+  }
+}
+
+module.exports = function (element) {
+  if (!_.env.supportsTouch && !_.env.supportsIePointer) {
+    return;
+  }
+
+  var i = instances.get(element);
+  bindTouchHandler(element, i, _.env.supportsTouch, _.env.supportsIePointer);
+};
+
+},{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],17:[function(require,module,exports){
+'use strict';
+
+var _ = require('../lib/helper');
+var cls = require('../lib/class');
+var instances = require('./instances');
+var updateGeometry = require('./update-geometry');
+
+// Handlers
+var handlers = {
+  'click-rail': require('./handler/click-rail'),
+  'drag-scrollbar': require('./handler/drag-scrollbar'),
+  'keyboard': require('./handler/keyboard'),
+  'wheel': require('./handler/mouse-wheel'),
+  'touch': require('./handler/touch'),
+  'selection': require('./handler/selection')
+};
+var nativeScrollHandler = require('./handler/native-scroll');
+
+module.exports = function (element, userSettings) {
+  userSettings = typeof userSettings === 'object' ? userSettings : {};
+
+  cls.add(element, 'ps');
+
+  // Create a plugin instance.
+  var i = instances.add(element);
+
+  i.settings = _.extend(i.settings, userSettings);
+  cls.add(element, 'ps--theme_' + i.settings.theme);
+
+  i.settings.handlers.forEach(function (handlerName) {
+    handlers[handlerName](element);
+  });
+
+  nativeScrollHandler(element);
+
+  updateGeometry(element);
+};
+
+},{"../lib/class":2,"../lib/helper":6,"./handler/click-rail":10,"./handler/drag-scrollbar":11,"./handler/keyboard":12,"./handler/mouse-wheel":13,"./handler/native-scroll":14,"./handler/selection":15,"./handler/touch":16,"./instances":18,"./update-geometry":19}],18:[function(require,module,exports){
+'use strict';
+
+var _ = require('../lib/helper');
+var cls = require('../lib/class');
+var defaultSettings = require('./default-setting');
+var dom = require('../lib/dom');
+var EventManager = require('../lib/event-manager');
+var guid = require('../lib/guid');
+
+var instances = {};
+
+function Instance(element) {
+  var i = this;
+
+  i.settings = _.clone(defaultSettings);
+  i.containerWidth = null;
+  i.containerHeight = null;
+  i.contentWidth = null;
+  i.contentHeight = null;
+
+  i.isRtl = dom.css(element, 'direction') === "rtl";
+  i.isNegativeScroll = (function () {
+    var originalScrollLeft = element.scrollLeft;
+    var result = null;
+    element.scrollLeft = -1;
+    result = element.scrollLeft < 0;
+    element.scrollLeft = originalScrollLeft;
+    return result;
+  })();
+  i.negativeScrollAdjustment = i.isNegativeScroll ? element.scrollWidth - element.clientWidth : 0;
+  i.event = new EventManager();
+  i.ownerDocument = element.ownerDocument || document;
+
+  function focus() {
+    cls.add(element, 'ps--focus');
+  }
+
+  function blur() {
+    cls.remove(element, 'ps--focus');
+  }
+
+  i.scrollbarXRail = dom.appendTo(dom.e('div', 'ps__scrollbar-x-rail'), element);
+  i.scrollbarX = dom.appendTo(dom.e('div', 'ps__scrollbar-x'), i.scrollbarXRail);
+  i.scrollbarX.setAttribute('tabindex', 0);
+  i.event.bind(i.scrollbarX, 'focus', focus);
+  i.event.bind(i.scrollbarX, 'blur', blur);
+  i.scrollbarXActive = null;
+  i.scrollbarXWidth = null;
+  i.scrollbarXLeft = null;
+  i.scrollbarXBottom = _.toInt(dom.css(i.scrollbarXRail, 'bottom'));
+  i.isScrollbarXUsingBottom = i.scrollbarXBottom === i.scrollbarXBottom; // !isNaN
+  i.scrollbarXTop = i.isScrollbarXUsingBottom ? null : _.toInt(dom.css(i.scrollbarXRail, 'top'));
+  i.railBorderXWidth = _.toInt(dom.css(i.scrollbarXRail, 'borderLeftWidth')) + _.toInt(dom.css(i.scrollbarXRail, 'borderRightWidth'));
+  // Set rail to display:block to calculate margins
+  dom.css(i.scrollbarXRail, 'display', 'block');
+  i.railXMarginWidth = _.toInt(dom.css(i.scrollbarXRail, 'marginLeft')) + _.toInt(dom.css(i.scrollbarXRail, 'marginRight'));
+  dom.css(i.scrollbarXRail, 'display', '');
+  i.railXWidth = null;
+  i.railXRatio = null;
+
+  i.scrollbarYRail = dom.appendTo(dom.e('div', 'ps__scrollbar-y-rail'), element);
+  i.scrollbarY = dom.appendTo(dom.e('div', 'ps__scrollbar-y'), i.scrollbarYRail);
+  i.scrollbarY.setAttribute('tabindex', 0);
+  i.event.bind(i.scrollbarY, 'focus', focus);
+  i.event.bind(i.scrollbarY, 'blur', blur);
+  i.scrollbarYActive = null;
+  i.scrollbarYHeight = null;
+  i.scrollbarYTop = null;
+  i.scrollbarYRight = _.toInt(dom.css(i.scrollbarYRail, 'right'));
+  i.isScrollbarYUsingRight = i.scrollbarYRight === i.scrollbarYRight; // !isNaN
+  i.scrollbarYLeft = i.isScrollbarYUsingRight ? null : _.toInt(dom.css(i.scrollbarYRail, 'left'));
+  i.scrollbarYOuterWidth = i.isRtl ? _.outerWidth(i.scrollbarY) : null;
+  i.railBorderYWidth = _.toInt(dom.css(i.scrollbarYRail, 'borderTopWidth')) + _.toInt(dom.css(i.scrollbarYRail, 'borderBottomWidth'));
+  dom.css(i.scrollbarYRail, 'display', 'block');
+  i.railYMarginHeight = _.toInt(dom.css(i.scrollbarYRail, 'marginTop')) + _.toInt(dom.css(i.scrollbarYRail, 'marginBottom'));
+  dom.css(i.scrollbarYRail, 'display', '');
+  i.railYHeight = null;
+  i.railYRatio = null;
+}
+
+function getId(element) {
+  return element.getAttribute('data-ps-id');
+}
+
+function setId(element, id) {
+  element.setAttribute('data-ps-id', id);
+}
+
+function removeId(element) {
+  element.removeAttribute('data-ps-id');
+}
+
+exports.add = function (element) {
+  var newId = guid();
+  setId(element, newId);
+  instances[newId] = new Instance(element);
+  return instances[newId];
+};
+
+exports.remove = function (element) {
+  delete instances[getId(element)];
+  removeId(element);
+};
+
+exports.get = function (element) {
+  return instances[getId(element)];
+};
+
+},{"../lib/class":2,"../lib/dom":3,"../lib/event-manager":4,"../lib/guid":5,"../lib/helper":6,"./default-setting":8}],19:[function(require,module,exports){
+'use strict';
+
+var _ = require('../lib/helper');
+var cls = require('../lib/class');
+var dom = require('../lib/dom');
+var instances = require('./instances');
+var updateScroll = require('./update-scroll');
+
+function getThumbSize(i, thumbSize) {
+  if (i.settings.minScrollbarLength) {
+    thumbSize = Math.max(thumbSize, i.settings.minScrollbarLength);
+  }
+  if (i.settings.maxScrollbarLength) {
+    thumbSize = Math.min(thumbSize, i.settings.maxScrollbarLength);
+  }
+  return thumbSize;
+}
+
+function updateCss(element, i) {
+  var xRailOffset = {width: i.railXWidth};
+  if (i.isRtl) {
+    xRailOffset.left = i.negativeScrollAdjustment + element.scrollLeft + i.containerWidth - i.contentWidth;
+  } else {
+    xRailOffset.left = element.scrollLeft;
+  }
+  if (i.isScrollbarXUsingBottom) {
+    xRailOffset.bottom = i.scrollbarXBottom - element.scrollTop;
+  } else {
+    xRailOffset.top = i.scrollbarXTop + element.scrollTop;
+  }
+  dom.css(i.scrollbarXRail, xRailOffset);
+
+  var yRailOffset = {top: element.scrollTop, height: i.railYHeight};
+  if (i.isScrollbarYUsingRight) {
+    if (i.isRtl) {
+      yRailOffset.right = i.contentWidth - (i.negativeScrollAdjustment + element.scrollLeft) - i.scrollbarYRight - i.scrollbarYOuterWidth;
+    } else {
+      yRailOffset.right = i.scrollbarYRight - element.scrollLeft;
+    }
+  } else {
+    if (i.isRtl) {
+      yRailOffset.left = i.negativeScrollAdjustment + element.scrollLeft + i.containerWidth * 2 - i.contentWidth - i.scrollbarYLeft - i.scrollbarYOuterWidth;
+    } else {
+      yRailOffset.left = i.scrollbarYLeft + element.scrollLeft;
+    }
+  }
+  dom.css(i.scrollbarYRail, yRailOffset);
+
+  dom.css(i.scrollbarX, {left: i.scrollbarXLeft, width: i.scrollbarXWidth - i.railBorderXWidth});
+  dom.css(i.scrollbarY, {top: i.scrollbarYTop, height: i.scrollbarYHeight - i.railBorderYWidth});
+}
+
+module.exports = function (element) {
+  var i = instances.get(element);
+
+  i.containerWidth = element.clientWidth;
+  i.containerHeight = element.clientHeight;
+  i.contentWidth = element.scrollWidth;
+  i.contentHeight = element.scrollHeight;
+
+  var existingRails;
+  if (!element.contains(i.scrollbarXRail)) {
+    existingRails = dom.queryChildren(element, '.ps__scrollbar-x-rail');
+    if (existingRails.length > 0) {
+      existingRails.forEach(function (rail) {
+        dom.remove(rail);
+      });
+    }
+    dom.appendTo(i.scrollbarXRail, element);
+  }
+  if (!element.contains(i.scrollbarYRail)) {
+    existingRails = dom.queryChildren(element, '.ps__scrollbar-y-rail');
+    if (existingRails.length > 0) {
+      existingRails.forEach(function (rail) {
+        dom.remove(rail);
+      });
+    }
+    dom.appendTo(i.scrollbarYRail, element);
+  }
+
+  if (!i.settings.suppressScrollX && i.containerWidth + i.settings.scrollXMarginOffset < i.contentWidth) {
+    i.scrollbarXActive = true;
+    i.railXWidth = i.containerWidth - i.railXMarginWidth;
+    i.railXRatio = i.containerWidth / i.railXWidth;
+    i.scrollbarXWidth = getThumbSize(i, _.toInt(i.railXWidth * i.containerWidth / i.contentWidth));
+    i.scrollbarXLeft = _.toInt((i.negativeScrollAdjustment + element.scrollLeft) * (i.railXWidth - i.scrollbarXWidth) / (i.contentWidth - i.containerWidth));
+  } else {
+    i.scrollbarXActive = false;
+  }
+
+  if (!i.settings.suppressScrollY && i.containerHeight + i.settings.scrollYMarginOffset < i.contentHeight) {
+    i.scrollbarYActive = true;
+    i.railYHeight = i.containerHeight - i.railYMarginHeight;
+    i.railYRatio = i.containerHeight / i.railYHeight;
+    i.scrollbarYHeight = getThumbSize(i, _.toInt(i.railYHeight * i.containerHeight / i.contentHeight));
+    i.scrollbarYTop = _.toInt(element.scrollTop * (i.railYHeight - i.scrollbarYHeight) / (i.contentHeight - i.containerHeight));
+  } else {
+    i.scrollbarYActive = false;
+  }
+
+  if (i.scrollbarXLeft >= i.railXWidth - i.scrollbarXWidth) {
+    i.scrollbarXLeft = i.railXWidth - i.scrollbarXWidth;
+  }
+  if (i.scrollbarYTop >= i.railYHeight - i.scrollbarYHeight) {
+    i.scrollbarYTop = i.railYHeight - i.scrollbarYHeight;
+  }
+
+  updateCss(element, i);
+
+  if (i.scrollbarXActive) {
+    cls.add(element, 'ps--active-x');
+  } else {
+    cls.remove(element, 'ps--active-x');
+    i.scrollbarXWidth = 0;
+    i.scrollbarXLeft = 0;
+    updateScroll(element, 'left', 0);
+  }
+  if (i.scrollbarYActive) {
+    cls.add(element, 'ps--active-y');
+  } else {
+    cls.remove(element, 'ps--active-y');
+    i.scrollbarYHeight = 0;
+    i.scrollbarYTop = 0;
+    updateScroll(element, 'top', 0);
+  }
+};
+
+},{"../lib/class":2,"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-scroll":20}],20:[function(require,module,exports){
+'use strict';
+
+var instances = require('./instances');
+
+var createDOMEvent = function (name) {
+  var event = document.createEvent("Event");
+  event.initEvent(name, true, true);
+  return event;
+};
+
+module.exports = function (element, axis, value) {
+  if (typeof element === 'undefined') {
+    throw 'You must provide an element to the update-scroll function';
+  }
+
+  if (typeof axis === 'undefined') {
+    throw 'You must provide an axis to the update-scroll function';
+  }
+
+  if (typeof value === 'undefined') {
+    throw 'You must provide a value to the update-scroll function';
+  }
+
+  if (axis === 'top' && value <= 0) {
+    element.scrollTop = value = 0; // don't allow negative scroll
+    element.dispatchEvent(createDOMEvent('ps-y-reach-start'));
+  }
+
+  if (axis === 'left' && value <= 0) {
+    element.scrollLeft = value = 0; // don't allow negative scroll
+    element.dispatchEvent(createDOMEvent('ps-x-reach-start'));
+  }
+
+  var i = instances.get(element);
+
+  if (axis === 'top' && value >= i.contentHeight - i.containerHeight) {
+    // don't allow scroll past container
+    value = i.contentHeight - i.containerHeight;
+    if (value - element.scrollTop <= 1) {
+      // mitigates rounding errors on non-subpixel scroll values
+      value = element.scrollTop;
+    } else {
+      element.scrollTop = value;
+    }
+    element.dispatchEvent(createDOMEvent('ps-y-reach-end'));
+  }
+
+  if (axis === 'left' && value >= i.contentWidth - i.containerWidth) {
+    // don't allow scroll past container
+    value = i.contentWidth - i.containerWidth;
+    if (value - element.scrollLeft <= 1) {
+      // mitigates rounding errors on non-subpixel scroll values
+      value = element.scrollLeft;
+    } else {
+      element.scrollLeft = value;
+    }
+    element.dispatchEvent(createDOMEvent('ps-x-reach-end'));
+  }
+
+  if (i.lastTop === undefined) {
+    i.lastTop = element.scrollTop;
+  }
+
+  if (i.lastLeft === undefined) {
+    i.lastLeft = element.scrollLeft;
+  }
+
+  if (axis === 'top' && value < i.lastTop) {
+    element.dispatchEvent(createDOMEvent('ps-scroll-up'));
+  }
+
+  if (axis === 'top' && value > i.lastTop) {
+    element.dispatchEvent(createDOMEvent('ps-scroll-down'));
+  }
+
+  if (axis === 'left' && value < i.lastLeft) {
+    element.dispatchEvent(createDOMEvent('ps-scroll-left'));
+  }
+
+  if (axis === 'left' && value > i.lastLeft) {
+    element.dispatchEvent(createDOMEvent('ps-scroll-right'));
+  }
+
+  if (axis === 'top' && value !== i.lastTop) {
+    element.scrollTop = i.lastTop = value;
+    element.dispatchEvent(createDOMEvent('ps-scroll-y'));
+  }
+
+  if (axis === 'left' && value !== i.lastLeft) {
+    element.scrollLeft = i.lastLeft = value;
+    element.dispatchEvent(createDOMEvent('ps-scroll-x'));
+  }
+
+};
+
+},{"./instances":18}],21:[function(require,module,exports){
+'use strict';
+
+var _ = require('../lib/helper');
+var dom = require('../lib/dom');
+var instances = require('./instances');
+var updateGeometry = require('./update-geometry');
+var updateScroll = require('./update-scroll');
+
+module.exports = function (element) {
+  var i = instances.get(element);
+
+  if (!i) {
+    return;
+  }
+
+  // Recalcuate negative scrollLeft adjustment
+  i.negativeScrollAdjustment = i.isNegativeScroll ? element.scrollWidth - element.clientWidth : 0;
+
+  // Recalculate rail margins
+  dom.css(i.scrollbarXRail, 'display', 'block');
+  dom.css(i.scrollbarYRail, 'display', 'block');
+  i.railXMarginWidth = _.toInt(dom.css(i.scrollbarXRail, 'marginLeft')) + _.toInt(dom.css(i.scrollbarXRail, 'marginRight'));
+  i.railYMarginHeight = _.toInt(dom.css(i.scrollbarYRail, 'marginTop')) + _.toInt(dom.css(i.scrollbarYRail, 'marginBottom'));
+
+  // Hide scrollbars not to affect scrollWidth and scrollHeight
+  dom.css(i.scrollbarXRail, 'display', 'none');
+  dom.css(i.scrollbarYRail, 'display', 'none');
+
+  updateGeometry(element);
+
+  // Update top/left scroll to trigger events
+  updateScroll(element, 'top', element.scrollTop);
+  updateScroll(element, 'left', element.scrollLeft);
+
+  dom.css(i.scrollbarXRail, 'display', '');
+  dom.css(i.scrollbarYRail, 'display', '');
+};
+
+},{"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-geometry":19,"./update-scroll":20}]},{},[1]);
index 1bde3d84647d324905c5329843db0c46a6bef16b..a88da8de1d2f9c36abb58ccd21a3bbad4f95d425 100644 (file)
@@ -1,6 +1,5 @@
 @import "variables";
 
-
 /* Screenshot */
 .screenshot .mview {
        overflow-y: hidden;
@@ -123,7 +122,6 @@ body, html {
        display: none;
        overflow-x: hidden;
        overflow-y: hidden;
-       overflow: hidden;
        visibility: hidden;
        opacity: 1;
        z-index: 0;
@@ -826,19 +824,42 @@ footer.hidden, header.hidden, #interface.hidden {
        right: 0px;
 }
 
-/* View */
+@menu-padding: 30px;
 
+/* View */
 .mview {
+       background-color: @menu-background;
+       color: @menu-text;
        position: absolute;
+       top: 0;
+       left: 0;
        z-index: 22;
        display: none;
-       overflow-x: hidden;
-       overflow-y: auto;
-       -webkit-overflow-scrolling: touch;
-       text-shadow: 0px -1px 0px rgba(0, 0, 0, 0.15);
+       overflow: hidden;
        background-repeat: no-repeat;
        background-size: 100% 100%;
+       max-width: 600px;
+       width: 100%;
 
+       .fonctions {
+               padding: 0 @menu-padding @menu-padding 0;
+               text-align: right;
+               a {
+                       line-height: 12px;
+                       background-color: @menu-button-background;
+                       border-radius: 2px;
+                       text-transform: uppercase;
+                       margin: 0 0 0 10px;
+                       padding: 16px 25px;
+                       display: inline-block;
+                       height: 45px;
+                       text-align: center;
+               }
+       }
+
+       &[data-chapters] {
+               max-width: 320px;
+       }
        &.animate {
                -moz-transition: -moz-transform 600ms ease-out, transform 600ms ease-out;
                -webkit-transition: -webkit-transform 600ms ease-out;
@@ -847,174 +868,134 @@ footer.hidden, header.hidden, #interface.hidden {
                transition: transform 600ms ease-out;
        }
        .caption {
-               padding: 20px 32px;
-
+               padding: 20px @menu-padding;
+               width: 100%;
                height: 60px;
-               position: absolute;
-               z-index: 1;
+
                h2 {
-                       font-size: 20px;
+                       font-size: 16px;
                        line-height: 16px;
-                       text-align: center;
-                       font-weight: 600;
+                       font-weight: 400;
                        margin: 0 auto;
-                       overflow: hidden;
-                       text-overflow: ellipsis;
                        white-space: nowrap;
                }
 
-               .fonctions {
-                       position: absolute;
-                       top: 9px;
-                       right: 12px;
-                       a {
-                               float: right;
-                               margin: 0 0 0 10px;
-                       }
-               }
-
                a {
                        height: 27px;
                        font-weight: 600;
                        font-size: 14px;
                        line-height: 25px;
                        display: block;
-
-                       box-shadow: inset 1px 1px 0px rgba(255, 255, 255, 0.3);
-                       -moz-box-shadow: inset 1px 1px 0px rgba(255, 255, 255, 0.3);
-                       -webkit-box-shadow: inset 1px 1px 0px rgba(255, 255, 255, 0.3);
-                       -ms-box-shadow: inset 1px 1px 0px rgba(255, 255, 255, 0.3);
-                       -o-box-shadow: inset 1px 1px 0px rgba(255, 255, 255, 0.3);
-
-                       background-repeat: no-repeat;
-                       background-position: 10px 4px;
-
-                       padding: 0 13px 0 33px;
-                       background-size: auto 17px;
                        &.back {
                                position: absolute;
-                               top: 9px;
-                               left: 12px;
-
-                               background-image: url("../data/images/interface-back-arrow.svg");
-                               background-size: auto 17px;
-                               padding: 0 13px 0 27px;
+                               top: 0;
+                               right: 0;
+                               width: 60px;
+                               height: 60px;
+                               padding: 22px;
+                               background-color: @menu-button-background;
                        }
-                       &.send {
-                               background-image: url("../data/images/share-email.svg");
-                       }
-                       &.print {
-                               background-image: url("../data/images/interface-print.svg");
-                       }
-                       &.miniOnPortrait {
-                               background-position: 50% 50%;
-                               padding: 0 15px;
-                       }
-
                }
-
        }
 
        .content {
                text-align: center;
-               position: absolute;
-               top: 44px;
+               width: 100%;
+               overflow: hidden;
+               position: relative;
+               -webkit-overflow-scrolling: touch;
        }
 }
 
-#indexView {
-       margin: auto;
-}
-
-#indexView .doubleThumb, #indexView .padding {
-       display: inline-block;
-       margin: 10px 10px 40px 10px;
-       position: relative;
-       width: 200px;
-       cursor: pointer;
-       text-align: center;
-}
-
-#indexView.bookmarkView .doubleThumb {
-       width: 100px;
-
-}
-
-#indexView.bookmarkView .doubleThumb.left {
-       margin-right: 10px;
-}
-
-#indexView.bookmarkView {
-       text-align: left;
-}
-
-#indexView .padding {
-       height: 1px;
-}
-
-#indexView .doubleThumb .overlay {
-       background-color: rgba(0, 0, 0, 0.5);
-       position: absolute;
-       top: 0px;
-       left: 0px;
-       width: 200px;
-       z-index: 4;
-}
-
-#indexView .doubleThumb.simple .overlay {
-       width: 100px;
-}
-
-#indexView .doubleThumb .hits {
-       position: relative;
-       display: inline;
-       top: 30px;
-       z-index: 5;
-       font-size: 12px;
-}
-
-#indexView .doubleThumb .hits.yes {
-       padding: 5px;
-       border-radius: 5px;
-}
-
-#indexView .thumb {
-       position: absolute;
-       top: 0px;
-       left: 0px;
-       font-size: 12px;
-}
-
-#indexView .thumb img {
-       background: #fff;
+form input[type="text"], form input[type="email"] {
+       background-color: @menu-field-background;
+       color: @menu-field-text;
 }
 
-#indexView .thumb .number {
-       text-align: center;
-       display: block;
-       font-family: Arial, Helvetica, sans-serif;
-       margin: 1px 0 0 0;
-       max-width: 100px;
-}
-
-#indexView .thumb.right {
-       left: 100px;
-}
+#indexView {
+       margin: auto;
+       .doubleThumb, .padding {
+               display: inline-block;
+               margin: 10px 10px 40px 10px;
+               position: relative;
+               width: 200px;
+               cursor: pointer;
+               text-align: center;
+       }
 
-#indexView .doubleThumb.simple {
-       width: 100px;
-}
+       &.bookmarkView {
+               @padding: @menu-padding - 10px;
+               text-align: left;
+               width: 100%;
+               padding: 20px @padding 0;
+               .doubleThumb {
+                       width: 100px;
+                       &.left {
+                               margin-right: 10px;
+                       }
+                       &.simple {
+                               overlay {
+                                       .overlay {
+                                               width: 100px;
+                                       }
+                               }
+                       }
+                       .overlay {
+                               background-color: rgba(0, 0, 0, 0.5);
+                               position: absolute;
+                               top: 0px;
+                               left: 0px;
+                               width: 200px;
+                               z-index: 4;
+                       }
 
-#indexView .doubleThumb.simple.right {
-       margin-left: 110px;
-}
+                       .hits {
+                               position: relative;
+                               display: inline;
+                               top: 30px;
+                               z-index: 5;
+                               font-size: 12px;
+                               &.yes {
+                                       padding: 5px;
+                                       border-radius: 5px;
+                               }
+                       }
+               }
 
-#indexView .doubleThumb.left {
-       margin-right: 110px;
-}
+               .padding {
+                       height: 1px;
+               }
+       }
+       .thumb {
+               position: absolute;
+               top: 0px;
+               left: 0px;
+               font-size: 12px;
+               img {
+                       background: #fff;
+               }
+               .number {
+                       text-align: center;
+                       display: block;
+                       font-family: Arial, Helvetica, sans-serif;
+                       margin: 1px 0 0 0;
+                       max-width: 100px;
+               }
+               &.right {
+                       left: 100px;
+                       left: 0;
+               }
+               &.simple {
+                       width: 100px;
+                       &.right {
+                               margin-left: 110px;
+                       }
+               }
+               &.left {
+                       margin-right: 110px;
+               }
 
-#indexView .right .thumb.right {
-       left: 0px;
+       }
 }
 
 /* Search */
@@ -1059,40 +1040,42 @@ ul.chapters.shareList a.level0 img {
        display: none;
        color: #ffffff;
        overflow: hidden;
-}
 
-#helpView .illustration {
-       text-align: center;
-       font-size: 20px;
-}
+       .illustration {
+               text-align: center;
+               font-size: 20px;
+               p {
+                       position: static;
+               }
 
-#helpView .illustration p {
-       position: static;
-}
+       }
 
-#helpView #icons {
-       position: absolute;
-       top: 0px;
-}
+       #icons {
+               position: absolute;
+               top: 0px;
+       }
 
-.portrait #helpView .icon.afterSearch {
-       display: none;
-}
+       .portrait & .icon.afterSearch {
+               display: none;
+       }
+       .icon {
+               position: absolute;
+               top: 0px;
+               display: inline-block;
+               border-left: 1px solid #ffffff;
+               padding-left: 5px;
+               white-space: nowrap;
+       }
 
-#helpView .icon {
-       position: absolute;
-       top: 0px;
-       display: inline-block;
-       border-left: 1px solid #ffffff;
-       padding-left: 5px;
-       white-space: nowrap;
-}
+       .icon span {
+               & .rtl {
+                       position: absolute;
+                       right: 1em;
+                       display: block;
+                       margin-top: -1em;
+               }
+       }
 
-.rtl #helpView .icon span {
-       position: absolute;
-       right: 1em;
-       display: block;
-       margin-top: -1em;
 }
 
 #helpView .interface hr {
@@ -1228,7 +1211,6 @@ ul.chapters.shareList a.level0 img {
 
 #archivesview .links .link {
        position: absolute;
-
 }
 
 /* Inner view */
@@ -1239,59 +1221,61 @@ ul.chapters.shareList a.level0 img {
        left: 0px;
        z-index: 30;
        display: none;
-}
-
-#innerView > div {
-       position: absolute;
-       border-radius: 10px;
-       padding: 20px;
-       font-size: 0.8rem;
-}
-
-#innerView > div p {
-       margin: 0 0 20px 0;
-}
+       > div {
+               position: absolute;
+               border-radius: 10px;
+               padding: 20px;
+               font-size: 0.8rem;
+               background-color: @menu-background;
+               color: @menu-text;
+               p {
+                       margin: 0 0 20px 0;
+               }
+       }
 
-/* Form elements */
-#innerView form input[type="text"],
-#innerView form input[type="email"] {
-       font-family: @font;
-       padding: 5px;
-       border-radius: 5px;
-       border: 0;
-       width: 100%;
-       margin: 7px 0;
-}
+       form {
+               input {
+                       &[type="text"], &[type="email"] {
+                               font-family: @font;
+                               padding: 5px;
+                               border-radius: 5px;
+                               border: 0;
+                               width: 100%;
+                               margin: 7px 0;
+                       }
+               }
+       }
 
-#innerView .close {
-       position: absolute;
-       top: 0px;
-       right: 0px;
-       width: 34px;
-       height: 34px;
-       display: block;
-       background-image: url("../data/images/interface-close.svg");
-       background-size: 14px 14px;
-       background-position: 50% 50%;
-       background-repeat: no-repeat;
-}
+       .close {
+               position: absolute;
+               top: 0px;
+               right: 0px;
+               width: 34px;
+               height: 34px;
+               display: block;
+               background-image: url("../data/images/interface-close.svg");
+               background-size: 14px 14px;
+               background-position: 50% 50%;
+               background-repeat: no-repeat;
+       }
 
-#innerView form input[type="submit"] {
-       background-image: -moz-linear-gradient(top, #ffffff 0%, #a2a2a2 100%); /* FF3.6+ */
-       background-image: -webkit-linear-gradient(top, #ffffff 0%, #a2a2a2 100%); /* Chrome10+,Safari5.1+ */
-       background-image: -o-linear-gradient(top, #ffffff 0%, #a2a2a2 100%); /* Opera 11.10+ */
-       background-image: -ms-linear-gradient(top, #ffffff 0%, #a2a2a2 100%); /* IE10+ */
-       background-image: linear-gradient(to bottom, #ffffff 0%, #a2a2a2 100%); /* W3C */
-       border: 0;
-       color: #000;
-       font-weight: bold;
-       position: absolute;
-       right: 20px;
-       bottom: 20px;
-       padding: 4px 10px 6px;
-       border-radius: 5px;
-       display: inline-block;
-       cursor: pointer;
+       input[type="submit"] {
+               background-image: -moz-linear-gradient(top, #ffffff 0%, #a2a2a2 100%); /* FF3.6+ */
+               background-image: -webkit-linear-gradient(top, #ffffff 0%, #a2a2a2 100%); /* Chrome10+,Safari5.1+ */
+               background-image: -o-linear-gradient(top, #ffffff 0%, #a2a2a2 100%); /* Opera 11.10+ */
+               background-image: -ms-linear-gradient(top, #ffffff 0%, #a2a2a2 100%); /* IE10+ */
+               background-image: linear-gradient(to bottom, #ffffff 0%, #a2a2a2 100%); /* W3C */
+               border: 0;
+               color: #000;
+               font-weight: bold;
+               position: absolute;
+               right: 20px;
+               bottom: 20px;
+               padding: 4px 10px 6px;
+               border-radius: 5px;
+               display: inline-block;
+               cursor: pointer;
+       }
 }
 
 /* Videos */
@@ -1329,117 +1313,110 @@ ul.chapters.shareList a.level0 img {
 }
 
 /* Chapters */
-ul.chapters > li {
-       clear: both;
-}
 
-ul.chapters a {
-       display: block;
-       text-align: left;
-       padding: 10px 20px;
-}
-
-.rtl ul.chapters a {
-       text-align: right;
-}
-
-ul.chapters a.level-1 {
-       font-size: 200%;
-       font-family: @font;
-       font-weight: 600;
-       text-align: center;
-}
-
-ul.chapters a.level-1 .right {
-       display: none;
-}
-
-ul.chapters a.level0, ul.chapters a.level1, ul.chapters a.level2, ul.chapters a.level3 {
-       border-top: 1px solid rgba(255, 255, 255, 0.3);
-}
-
-ul.chapters a.level0 {
-       font-size: 150%;
-       font-family: @font;
-       font-weight: 600;
-}
-
-ul.chapters a.level1 {
-       padding: 10px 20px 10px 50px;
-       font-size: 120%;
-}
-
-ul.chapters a.level2 {
-       padding: 10px 20px 10px 80px;
-       font-size: 100%;
-}
-
-ul.chapters a.level3 {
-       padding: 10px 20px 10px 110px;
-       font-size: 80%;
-}
-
-ul.chapters, ul.chapters ul {
+ul.chapters {
        list-style: none;
-}
-
-ul.chapters .right {
-       float: right;
-       display: inline-block;
-}
-
-ul.chapters .right .puce.noshadow {
-       border-radius: 0px;
-       -moz-border-radius: 0px;
-       -webkit-border-radius: 0px;
-       -ms-border-radius: 0px;
-       -o-border-radius: 0px;
-
-       box-shadow: 2px 2px 4px rgba(0, 0, 0, 0);
-       -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0);
-       -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0);
-       -ms-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0);
-       -o-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0);
-
-       margin: 0 0 0 15px;
-       float: right;
-}
+       padding: 20px 0;
+       ul {
+               list-style: none;
+       }
+       > li {
+               clear: both;
+       }
 
-ul.chapters .right .puce {
-       width: 25px;
-       height: 25px;
+       li {
+               &[data-level="1"] + [data-level="0"] {
+                       margin-top: 15px;
+               }
+               &[data-level="2"] + [data-level="1"] {
+                       margin-top: 10px;
+               }
+               &[data-level="3"] + [data-level="2"] {
+                       margin-top: 5px;
+               }
+       }
+       a {
+               font-size: 16px;
+               display: block;
+               text-align: left;
+               padding: 5px 32px;
+               .rtl & {
+                       text-align: right;
+               }
+               &.level-1 {
+                       font-family: @font;
+                       font-weight: 400;
+                       text-align: center;
+                       .right {
+                               display: none;
+                       }
+               }
+               &.level0 {
+                       font-family: @font;
+                       font-weight: 400;
+                       .right .puce {
+                               margin: 2px 0 0 0;
+                       }
 
-       border-radius: 5px;
-       -moz-border-radius: 5px;
-       -webkit-border-radius: 5px;
-       -ms-border-radius: 5px;
-       -o-border-radius: 5px;
-
-       box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25);
-       -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25);
-       -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25);
-       -ms-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25);
-       -o-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25);
-
-       background-image: url("../images/chapters-arrow.png");
-       background-repeat: no-repeat;
-}
+               }
+               &.level1 {
+                       padding-left: 50px;
 
-ul.chapters a.nodark {
-       background-image: none !important;
-       border-top: 1px solid rgba(255, 255, 255, 0.25);
-}
+               }
+               &.level2 {
+                       padding-left: 80px;
+                       .right .puce {
+                               margin: -2px 0 0 0;
+                       }
+               }
+               .level3 {
+                       padding-left: 110px;
+               }
+               > nav {
+                       display: none;
+               }
+       }
+       .right {
+               float: right;
+               display: inline-block;
+
+               .puce {
+                       width: 25px;
+                       height: 25px;
+
+                       border-radius: 5px;
+                       -moz-border-radius: 5px;
+                       -webkit-border-radius: 5px;
+                       -ms-border-radius: 5px;
+                       -o-border-radius: 5px;
+
+                       box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25);
+                       -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25);
+                       -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25);
+                       -ms-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25);
+                       -o-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.25);
+
+                       background-image: url("../images/chapters-arrow.png");
+                       background-repeat: no-repeat;
 
-ul.chapters a.level0 .right .puce {
-       margin: 2px 0 0 0;
-}
+                       &.noshadow {
+                               border-radius: 0px;
+                               -moz-border-radius: 0px;
+                               -webkit-border-radius: 0px;
+                               -ms-border-radius: 0px;
+                               -o-border-radius: 0px;
 
-ul.chapters a.level2 .right .puce {
-       margin: -2px 0 0 0;
-}
+                               box-shadow: 2px 2px 4px rgba(0, 0, 0, 0);
+                               -moz-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0);
+                               -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0);
+                               -ms-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0);
+                               -o-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0);
 
-ul.chapters a > nav {
-       display: none;
+                               margin: 0 0 0 15px;
+                               float: right;
+                       }
+               }
+       }
 }
 
 /* ipad mag */
@@ -1816,6 +1793,173 @@ a.button {
        }
 }
 
+@rail-background: @menu-button-background;
+@rail-opacity: 1;
+@handle: @menu-button-background;
+@handle-hover: @menu-text;
+
+// Scrollbars
+/* perfect-scrollbar v0.7.1 */
+.ps {
+       -ms-touch-action: auto;
+       touch-action: auto;
+       overflow: hidden !important;
+       -ms-overflow-style: none;
+}
+
+@supports (-ms-overflow-style: none) {
+       .ps {
+               overflow: auto !important;
+       }
+}
+
+@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
+       .ps {
+               overflow: auto !important;
+       }
+}
+
+.ps.ps--active-x > .ps__scrollbar-x-rail,
+.ps.ps--active-y > .ps__scrollbar-y-rail {
+       display: block;
+       background-color: transparent;
+}
+
+.ps.ps--in-scrolling.ps--x > .ps__scrollbar-x-rail {
+       background-color: @rail-background;
+       opacity: @rail-opacity;
+}
+
+.ps.ps--in-scrolling.ps--x > .ps__scrollbar-x-rail > .ps__scrollbar-x {
+       background-color: @handle-hover;
+       height: 11px;
+}
+
+.ps.ps--in-scrolling.ps--y > .ps__scrollbar-y-rail {
+       background-color: @rail-background;
+       opacity: @rail-opacity;
+}
+
+.ps.ps--in-scrolling.ps--y > .ps__scrollbar-y-rail > .ps__scrollbar-y {
+       background-color: @handle-hover;
+       width: 11px;
+}
+
+.ps > .ps__scrollbar-x-rail {
+       display: none;
+       position: absolute;
+       /* please don't change 'position' */
+       opacity: 0;
+       -webkit-transition: background-color .2s linear, opacity .2s linear;
+       -o-transition: background-color .2s linear, opacity .2s linear;
+       -moz-transition: background-color .2s linear, opacity .2s linear;
+       transition: background-color .2s linear, opacity .2s linear;
+       bottom: 0px;
+       /* there must be 'bottom' for ps__scrollbar-x-rail */
+       height: 15px;
+}
+
+.ps > .ps__scrollbar-x-rail > .ps__scrollbar-x {
+       position: absolute;
+       /* please don't change 'position' */
+       background-color: @handle;
+       -webkit-border-radius: 6px;
+       -moz-border-radius: 6px;
+       border-radius: 6px;
+       -webkit-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
+       transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
+       -o-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
+       -moz-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
+       transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
+       transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
+       bottom: 2px;
+       /* there must be 'bottom' for ps__scrollbar-x */
+       height: 6px;
+}
+
+.ps > .ps__scrollbar-x-rail:hover > .ps__scrollbar-x, .ps > .ps__scrollbar-x-rail:active > .ps__scrollbar-x {
+       height: 11px;
+}
+
+.ps > .ps__scrollbar-y-rail {
+       display: none;
+       position: absolute;
+       /* please don't change 'position' */
+       opacity: 0;
+       -webkit-transition: background-color .2s linear, opacity .2s linear;
+       -o-transition: background-color .2s linear, opacity .2s linear;
+       -moz-transition: background-color .2s linear, opacity .2s linear;
+       transition: background-color .2s linear, opacity .2s linear;
+       right: 0;
+       /* there must be 'right' for ps__scrollbar-y-rail */
+       width: 15px;
+}
+
+.ps > .ps__scrollbar-y-rail > .ps__scrollbar-y {
+       position: absolute;
+       /* please don't change 'position' */
+       background-color: @handle;
+       -webkit-border-radius: 6px;
+       -moz-border-radius: 6px;
+       border-radius: 6px;
+       -webkit-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
+       transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
+       -o-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
+       -moz-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
+       transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
+       transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
+       right: 2px;
+       /* there must be 'right' for ps__scrollbar-y */
+       width: 6px;
+}
+
+.ps > .ps__scrollbar-y-rail:hover > .ps__scrollbar-y, .ps > .ps__scrollbar-y-rail:active > .ps__scrollbar-y {
+       width: 11px;
+}
+
+.ps:hover.ps--in-scrolling.ps--x > .ps__scrollbar-x-rail {
+       background-color: @rail-background;
+       opacity: @rail-opacity;
+}
+
+.ps:hover.ps--in-scrolling.ps--x > .ps__scrollbar-x-rail > .ps__scrollbar-x {
+       background-color: @handle-hover;
+       height: 11px;
+}
+
+.ps:hover.ps--in-scrolling.ps--y > .ps__scrollbar-y-rail {
+       background-color: @rail-background;
+       opacity: @rail-opacity;
+}
+
+.ps:hover.ps--in-scrolling.ps--y > .ps__scrollbar-y-rail > .ps__scrollbar-y {
+       background-color: @handle-hover;
+       width: 11px;
+}
+
+.ps:hover > .ps__scrollbar-x-rail,
+.ps:hover > .ps__scrollbar-y-rail {
+       opacity: 0.6;
+}
+
+.ps:hover > .ps__scrollbar-x-rail:hover {
+       background-color: @rail-background;
+       opacity: @rail-opacity;
+}
+
+.ps:hover > .ps__scrollbar-x-rail:hover > .ps__scrollbar-x {
+       background-color: @handle-hover;
+}
+
+.ps:hover > .ps__scrollbar-y-rail:hover {
+       background-color: @rail-background;
+       opacity: @rail-opacity;
+}
+
+.ps:hover > .ps__scrollbar-y-rail:hover > .ps__scrollbar-y {
+       background-color: @handle-hover;
+}
+
 @media handled and (orientation: portrait) {
        #ol {
                display: none;