]> _ Git - fluidbook-html5.git/commitdiff
fix #2411 @0.5
authorVincent Vanwaelscappel <vincent@cubedesigners.com>
Fri, 7 Dec 2018 12:56:36 +0000 (13:56 +0100)
committerVincent Vanwaelscappel <vincent@cubedesigners.com>
Fri, 7 Dec 2018 12:56:36 +0000 (13:56 +0100)
js/libs/fluidbook/fluidbook.help.js
style/fluidbook.less
style/help.less [new file with mode: 0644]

index 4274d8cf2b32c9e1720591693ee4c61aef65576d..e88c131cbd7c1cff40bfae6a842878ec1641bf12 100644 (file)
-function FluidbookHelp(fluidbook) {\r
-    this.autoTimeout;\r
-    this.fluidbook = fluidbook;\r
-    this.view = $("#helpView");\r
-    this.overlay = $("#helpViewOverlay");\r
-    this.initEvents();\r
-    this.interfaceTop;\r
-}\r
-\r
-FluidbookHelp.prototype = {\r
-    init: function () {\r
-        var $this = this;\r
-        var help = '';\r
-\r
-        // Image centrale\r
-        var ext = '';\r
-        if (this.fluidbook.support.SVG) {\r
-            ext = 'svg';\r
-        } else {\r
-            ext = 'png';\r
-        }\r
-\r
-        var name = '';\r
-        var width = 100;\r
-        var height = 200;\r
-        var text;\r
-        var zoom = 1;\r
-        if (this.fluidbook.support.isMobile) {\r
-            width = 400;\r
-            height = 200;\r
-            zoom = 2;\r
-            name = 'fingers';\r
-            text = this.fluidbook.l10n.__("tap twice or spread your fingers to zoom in");\r
-        } else {\r
-            name = 'mouse';\r
-            text = this.fluidbook.l10n.__('click once to zoom in, click again to zoom out') + '<br />' + this.fluidbook.l10n.__('roll the mouse wheel to zoom in/out');\r
-        }\r
-\r
-        help += '<div class="illustration">' + this.fluidbook.loader.getImage('data/images/help-' + name + '.' + ext, width * zoom, height * zoom);\r
-        help += '<p>' + text + '</p>';\r
-        help += '</div>';\r
-\r
-\r
-        // Icons\r
-        help += '<div id="icons">';\r
-\r
-        var tooltipSelector = '#horizontalNav li > a[data-tooltip]:visible';\r
-\r
-        // When the menu position is inverted, the icon help lines need\r
-        // to be drawn in the reverse order to avoid text/line overlaps\r
-        var tooltips = this.fluidbook.datas.invertMenuPosition ? $(tooltipSelector).get().reverse() : $(tooltipSelector);\r
-        var navScale = this.fluidbook.resize.navScale;\r
-        var initialHeight = 20 * navScale; // Buffer in line height away from icons\r
-        var hStep = 25 * navScale; // The step height - the difference in height between the icon label lines\r
-        var h = initialHeight + ($(tooltipSelector).length - 1) * hStep;\r
-        var ww = $(window).width();\r
-\r
-        $(tooltips).each(function () {\r
-            var text = $(this).data('tooltip');\r
-            if (text == null || text == undefined || text == '' || $(this).hasClass('hidden')) {\r
-                return;\r
-            }\r
-\r
-            var icon = $(this).find('.nav-icon:visible:first'); // Must get first visible icon so "toggle" icons work\r
-            if (icon.length > 0) {\r
-                var offset = icon.offset(),\r
-                    iconWidth = icon.outerWidth() * navScale,\r
-                    left;\r
-\r
-                if ($this.fluidbook.l10n.dir == 'ltr') {\r
-                    left = offset.left + (iconWidth / 2);\r
-                } else {\r
-                    left = (ww - offset.left - (iconWidth / 2)) * -1;\r
-                }\r
-\r
-                // Since the outer container has been scaled, we need to factor that in\r
-                // for the left position so the lines still meet with the icons\r
-                left = left / navScale;\r
-\r
-                var c = 'nav';\r
-                if ($(this).parents("#afterSearch").length > 0) {\r
-                    c = 'afterSearch';\r
-                }\r
-                help += '<div class="icon ' + c + '" style="padding-top:' + h + 'px;left:' + left + 'px;"><span>' + text + '</span></div>';\r
-                h -= hStep;\r
-            }\r
-        });\r
-\r
-        help += '</div>';\r
-\r
-        // Interface\r
-\r
-        var next = this.fluidbook.l10n.__('next double page');\r
-        var previous = this.fluidbook.l10n.__('previous double page');\r
-        if (this.fluidbook.pad.enabled) {\r
-            next = this.fluidbook.l10n.__('next chapter');\r
-            previous = this.fluidbook.l10n.__('previous chapter');\r
-        }\r
-\r
-        help += '<div class="interface">';\r
-        help += '<div class="next">' + next + '</div>';\r
-        help += '<div class="last">' + this.fluidbook.l10n.__('last page') + '</div>';\r
-        help += '<div class="previous">' + previous + '</div>';\r
-        help += '<div class="first">' + this.fluidbook.l10n.__('frontpage') + '</div>';\r
-        help += '<div class="slider"><span>' + this.fluidbook.l10n.__('drag handle to switch page') + '</span></div>';\r
-        help += this.bookmarkLabel();\r
-        help += '</div>';\r
-\r
-        if (this.fluidbook.pad.enabled) {\r
-            help += '<div class="down">' + this.fluidbook.l10n.__('read more') + '<hr /></div>';\r
-        }\r
-\r
-        this.view.html(help);\r
-        //resize();\r
-    },\r
-    initEvents: function () {\r
-        var $this = this;\r
-\r
-        $(document).on('click', '.icon-help', function (e) {\r
-            $this.show();\r
-            if (fluidbook.nav.menuIsOpen) {\r
-                fluidbook.nav.menuAPI.close();\r
-            }\r
-            e.preventDefault();\r
-        });\r
-\r
-        // Click handler on main helpView div to hide it\r
-        $this.overlay.click(function (e) {\r
-            e.stopImmediatePropagation();\r
-            e.stopPropagation();\r
-            e.preventDefault();\r
-\r
-            $this.hide();\r
-            return false;\r
-        });\r
-    },\r
-    isVisible: function () {\r
-        return this.view.is(":visible");\r
-    },\r
-    show: function (time) {\r
-        this.clearTimeout();\r
-        if (time == undefined) {\r
-            time = 0;\r
-        }\r
-\r
-        this.fluidbook.interface.displayInterface();\r
-\r
-        if (this.isVisible()) {\r
-            return false;\r
-        }\r
-\r
-        var $this = this;\r
-\r
-        this.init(); // Re-run init because layout and options might have changed since last run\r
-        resize();\r
-        this.overlay.show();\r
-        this.view.show();\r
-\r
-        $("body,#previous,#next").addClass('help');\r
-        this.fluidbook.showAllButtons();\r
-\r
-        if (time != 0) {\r
-            this.autoTimeout = setTimeout(function () {\r
-                $this.hide();\r
-            }, time * 1000);\r
-        }\r
-\r
-        return false;\r
-    },\r
-    hide: function () {\r
-        this.clearTimeout();\r
-        this.fluidbook.interface.checkHidden();\r
-        var $this = this;\r
-        if (this.isVisible()) {\r
-            this.overlay.hide();\r
-            this.view.hide();\r
-            $("body,#previous,#next").removeClass('help');\r
-            this.fluidbook.hideUnnecessaryButtons();\r
-            if (this.fluidbook.support.isMobile) {\r
-                $("*").unbind('click', function () {\r
-                    $this.hide();\r
-                });\r
-            }\r
-        }\r
-        return false;\r
-    },\r
-    toggle: function () {\r
-        if (this.isVisible()) {\r
-            this.hide();\r
-        } else {\r
-            this.show();\r
-        }\r
-    },\r
-    resize: function (ww, hh, interfaceScale, navScale) {\r
-\r
-        // Repopulate and reposition help overlay elements.\r
-        // Mostly important for the RTL languages where icon label position must be recalculated/\r
-        // ToDo: Replace this sledgehammer approach with something more elegant\r
-        this.init();\r
-\r
-        // ToDo: access variables from fluidbook.resize.* if they're not passed to the function. So resize function can be called directly...\r
-\r
-        var $this = this,\r
-            dir = this.fluidbook.l10n.dir,\r
-            menuHeightScaled = (this.fluidbook.datas.menuHeight) * navScale,\r
-            arrow = $('#interface #next').get(0).getBoundingClientRect(), // Used for calculating offsets for both #next & #previous\r
-            nextTop,\r
-            firstTop;\r
-\r
-        // The arrow element contains both arrows in a single image\r
-        // so we calculate the top position of the labels by percentage\r
-        nextTop = Math.round(arrow.top + arrow.height * 0.35);\r
-        firstTop = Math.round(arrow.top + arrow.height * 0.71);\r
-\r
-        // Navigation arrow labels\r
-        this.view.find('.previous, .next').css({\r
-            top: nextTop\r
-        });\r
-        this.view.find('.first, .last').css({\r
-            top: firstTop\r
-        });\r
-\r
-        // Labels are swapped for RTL documents\r
-        var prevPosition = (dir == 'ltr') ? {left: Math.round(arrow.width)} : {right: Math.round(arrow.width)},\r
-            nextPosition = (dir == 'ltr') ? {right: Math.round(arrow.width)} : {left: Math.round(arrow.width)};\r
-\r
-        this.view.find('.previous, .first').css(prevPosition);\r
-        this.view.find('.next, .last').css(nextPosition);\r
-\r
-\r
-        // Slider label\r
-        var positionSliderLabel = function () {\r
-            var sliderHelp = $this.view.find('.slider');\r
-            var sliderCursor = $('#slidercursor .visible');\r
-            sliderHelp.css({\r
-                bottom: Math.round(hh - sliderCursor.offset().top),\r
-                left: Math.round(sliderCursor.offset().left + (sliderCursor.width() / 2)),\r
-                transformOrigin: 'left bottom'\r
-            });\r
-        };\r
-        positionSliderLabel(); // Run immediately\r
-        setTimeout(positionSliderLabel, 250); // delay slightly to make sure co-ordinates are correct\r
-\r
-        this.view.find('#icons').css({\r
-            top: menuHeightScaled,\r
-            transform: 'scale(' + navScale + ')'\r
-        });\r
-\r
-        $("#helpView #icons").css({\r
-            fontSize: (14 / navScale) * interfaceScale\r
-        });\r
-\r
-        this.view.find('.illustration').css({\r
-            transform: 'translate(-50%, -50%) scale(' + interfaceScale + ')'\r
-        });\r
-\r
-        $("#helpView .interface").find('> div').transform({\r
-            scale: [interfaceScale, interfaceScale]\r
-        })\r
-\r
-    },\r
-    clearTimeout: function () {\r
-        clearTimeout(this.autoTimeout);\r
-    },\r
-    displayAtStartup: function () {\r
-        if (this.fluidbook.datas.helpStartup) {\r
-            this.show(parseInt(this.fluidbook.datas.helpStartupTime));\r
-            if (this.fluidbook.pad.enabled) {\r
-                this.fluidbook.pad.displayInterface();\r
-            }\r
-        } else {\r
-            this.fluidbook.hideUnnecessaryButtons();\r
-        }\r
-    },\r
-\r
-    bookmarkLabel: function () {\r
-\r
-        // The bookmark help element is a bit complex because it must be placed in a section of the help overlay that is\r
-        // not already used by the icon labels. Since the menu can be either on the left or right, this needs to be taken\r
-        // into account. On the first and last pages of the Fluidbook we don't have a left or right page so it might not\r
-        // be possible to always display the bookmark icon in this case...\r
-\r
-        var dir = this.fluidbook.l10n.dir,\r
-            inverted = this.fluidbook.datas.invertMenuPosition,\r
-            side = ((dir == 'ltr' && inverted) || (dir == 'rtl' && !inverted)) ? 'left' : 'right',\r
-            baseElement = $('#links .bookmark.' + side), // Original element used to provide position and sizing for overlay\r
-            html = '';\r
-\r
-        // If bookmark icon isn't present on the side we want, it means that we're on\r
-        // the first/last page and that side is missing so we can't display the help\r
-        if (baseElement.length == 0) {\r
-            return '';\r
-        }\r
-\r
-        // Get the offset and dimensions of the element, taking into account the scaling\r
-        var box = baseElement[0].getBoundingClientRect(),\r
-            circleExtra = 20 * this.fluidbook.resize.interfaceScale, // How much bigger the circle should be around the bookmark icon\r
-            lineLength = 30; // Length of the line to the label text\r
-\r
-        // The bookmark icon sits inside a circle that is slightly bigger so in order to make the icon sit exactly\r
-        // on the corner of the page, we must offset the difference added by the larger wrapping circle.\r
-        var circleOffset = circleExtra / 2;\r
-\r
-        // Build a HTML string via jQuery with all the styling\r
-        // Bookmark icon:\r
-        var icon = $('<div/>').css({\r
-            width: Math.round(box.width),\r
-            height: Math.round(box.height),\r
-            margin: Math.round(circleOffset), // Centre inside circle\r
-            backgroundSize: 'contain',\r
-            backgroundPosition: 'center',\r
-            backgroundRepeat: 'no-repeat',\r
-            backgroundImage: baseElement.css('backgroundImage').replace('off.svg', 'on.svg') // Show the "on" state if not already set\r
-        })[0].outerHTML;\r
-\r
-        // Circle around the icon - slightly bigger\r
-        html += $('<div>' + icon + '</div>').css({\r
-            width: Math.round(box.width + circleExtra),\r
-            height: Math.round(box.height + circleExtra),\r
-            borderRadius: '50%',\r
-            border: '1px solid'\r
-        })[0].outerHTML;\r
-\r
-        // Line to text\r
-        html += $('<div/>').css({\r
-            width: lineLength,\r
-            height: 0,\r
-            borderBottom: '1px solid',\r
-        })[0].outerHTML;\r
-\r
-        // Help text label\r
-        html += $('<div>' + this.fluidbook.l10n.__('add / remove bookmark') + '</div>').css({\r
-            whiteSpace: 'nowrap',\r
-            padding: '0 0.5em' // Ensure spacing around text regardless which side the line is on\r
-        })[0].outerHTML;\r
-\r
-\r
-        // Wrapper with positioning and layout switched depending on the side\r
-        var wrapperCSS = { // Shared properties\r
-                display: 'flex',\r
-                alignItems: 'center',\r
-                position: 'absolute',\r
-                top: Math.round(box.top - circleOffset)\r
-            },\r
-            wrapperLayout;\r
-\r
-        if (side == 'left') {\r
-            wrapperLayout = {\r
-                left: Math.round(box.left - circleOffset),\r
-                transformOrigin: 'left top',\r
-                flexDirection: 'row' // Flexbox direction controls order of elements (icon, line, label)\r
-            };\r
-        } else {\r
-            wrapperLayout = {\r
-                right: Math.round(this.fluidbook.resize.ww - box.left - box.width - circleOffset),\r
-                transformOrigin: 'right top',\r
-                flexDirection: 'row-reverse' // Reverse order of elements for right hand page\r
-            }\r
-        }\r
-\r
-        var wrapper = $('<div class="bookmark-help">' + html + '</div>')\r
-            .css(\r
-                $.extend(wrapperCSS, wrapperLayout) // Merge all properties\r
-            )[0].outerHTML\r
-\r
-        return wrapper;\r
-    }\r
-};\r
-\r
+function FluidbookHelp(fluidbook) {
+    this.autoTimeout;
+    this.fluidbook = fluidbook;
+    this.view = $("#helpView");
+    this.overlay = $("#helpViewOverlay");
+    this.initEvents();
+    this.interfaceTop;
+}
+
+FluidbookHelp.prototype = {
+    init: function () {
+        var $this = this;
+        var help = '';
+
+        // Image centrale
+        var ext = '';
+        if (this.fluidbook.support.SVG) {
+            ext = 'svg';
+        } else {
+            ext = 'png';
+        }
+
+        var name = '';
+        var width = 100;
+        var height = 200;
+        var text;
+        var zoom = 1;
+        if (this.fluidbook.support.isMobile) {
+            width = 400;
+            height = 200;
+            zoom = 2;
+            name = 'fingers';
+            text = this.fluidbook.l10n.__("tap twice or spread your fingers to zoom in");
+        } else {
+            name = 'mouse';
+            text = this.fluidbook.l10n.__('click once to zoom in, click again to zoom out') + '<br />' + this.fluidbook.l10n.__('roll the mouse wheel to zoom in/out');
+        }
+
+        help += '<div class="illustration">' + this.fluidbook.loader.getImage('data/images/help-' + name + '.' + ext, width * zoom, height * zoom);
+        help += '<p>' + text + '</p>';
+        help += '</div>';
+
+
+        // Icons
+        help += '<div id="icons">';
+
+        var tooltipSelector = '#horizontalNav li > a[data-tooltip]:visible';
+
+        // When the menu position is inverted, the icon help lines need
+        // to be drawn in the reverse order to avoid text/line overlaps
+        var tooltips = this.fluidbook.datas.invertMenuPosition ? $(tooltipSelector).get().reverse() : $(tooltipSelector);
+        var navScale = this.fluidbook.resize.navScale;
+        var initialHeight = 20 * navScale; // Buffer in line height away from icons
+        var hStep = 25 * navScale; // The step height - the difference in height between the icon label lines
+        var h = initialHeight + ($(tooltipSelector).length - 1) * hStep;
+        var ww = $(window).width();
+
+        $(tooltips).each(function () {
+            var text = $(this).data('tooltip');
+            if (text == null || text == undefined || text == '' || $(this).hasClass('hidden')) {
+                return;
+            }
+
+            var icon = $(this).find('.nav-icon:visible:first'); // Must get first visible icon so "toggle" icons work
+            if (icon.length > 0) {
+                var offset = icon.offset();
+                var iconWidth = parseFloat($(icon).width()) * navScale;
+                var left;
+
+                if ($this.fluidbook.l10n.dir === 'ltr') {
+                    left = offset.left + (iconWidth / 2);
+                } else {
+                    left = (ww - offset.left - (iconWidth / 2)) * -1;
+                }
+
+                // Since the outer container has been scaled, we need to factor that in
+                // for the left position so the lines still meet with the icons
+                left = left / navScale;
+
+                var c = 'nav';
+                if ($(this).parents("#afterSearch").length > 0) {
+                    c = 'afterSearch';
+                }
+                help += '<div class="icon ' + c + '" style="padding-top:' + h + 'px;left:' + left + 'px;"><span>' + text + '</span></div>';
+                h -= hStep;
+            }
+        });
+
+        help += '</div>';
+
+        // Interface
+
+        var next = this.fluidbook.l10n.__('next double page');
+        var previous = this.fluidbook.l10n.__('previous double page');
+        if (this.fluidbook.pad.enabled) {
+            next = this.fluidbook.l10n.__('next chapter');
+            previous = this.fluidbook.l10n.__('previous chapter');
+        }
+
+        help += '<div class="interface">';
+        help += '<div class="next">' + next + '</div>';
+        help += '<div class="last">' + this.fluidbook.l10n.__('last page') + '</div>';
+        help += '<div class="previous">' + previous + '</div>';
+        help += '<div class="first">' + this.fluidbook.l10n.__('frontpage') + '</div>';
+        help += '<div class="slider"><span>' + this.fluidbook.l10n.__('drag handle to switch page') + '</span></div>';
+        help += this.bookmarkLabel();
+        help += '</div>';
+
+        if (this.fluidbook.pad.enabled) {
+            help += '<div class="down">' + this.fluidbook.l10n.__('read more') + '<hr /></div>';
+        }
+
+        this.view.html(help);
+        //resize();
+    },
+    initEvents: function () {
+        var $this = this;
+
+        $(document).on('click', '.icon-help', function (e) {
+            $this.show();
+            if (fluidbook.nav.menuIsOpen) {
+                fluidbook.nav.menuAPI.close();
+            }
+            e.preventDefault();
+        });
+
+        // Click handler on main helpView div to hide it
+        $this.overlay.click(function (e) {
+            e.stopImmediatePropagation();
+            e.stopPropagation();
+            e.preventDefault();
+
+            $this.hide();
+            return false;
+        });
+    },
+    isVisible: function () {
+        return this.view.is(":visible");
+    },
+    show: function (time) {
+        this.clearTimeout();
+        if (time == undefined) {
+            time = 0;
+        }
+
+        this.fluidbook.interface.displayInterface();
+
+        if (this.isVisible()) {
+            return false;
+        }
+
+        var $this = this;
+
+        this.init(); // Re-run init because layout and options might have changed since last run
+        resize();
+        this.overlay.show();
+        this.view.show();
+
+        $("body,#previous,#next").addClass('help');
+        this.fluidbook.showAllButtons();
+
+        if (time != 0) {
+            this.autoTimeout = setTimeout(function () {
+                $this.hide();
+            }, time * 1000);
+        }
+
+        return false;
+    },
+    hide: function () {
+        this.clearTimeout();
+        this.fluidbook.interface.checkHidden();
+        var $this = this;
+        if (this.isVisible()) {
+            this.overlay.hide();
+            this.view.hide();
+            $("body,#previous,#next").removeClass('help');
+            this.fluidbook.hideUnnecessaryButtons();
+            if (this.fluidbook.support.isMobile) {
+                $("*").unbind('click', function () {
+                    $this.hide();
+                });
+            }
+        }
+        return false;
+    },
+    toggle: function () {
+        if (this.isVisible()) {
+            this.hide();
+        } else {
+            this.show();
+        }
+    },
+    resize: function (ww, hh, interfaceScale, navScale) {
+
+        // Repopulate and reposition help overlay elements.
+        // Mostly important for the RTL languages where icon label position must be recalculated/
+        // ToDo: Replace this sledgehammer approach with something more elegant
+        this.init();
+
+        // ToDo: access variables from fluidbook.resize.* if they're not passed to the function. So resize function can be called directly...
+
+        var $this = this,
+            dir = this.fluidbook.l10n.dir,
+            menuHeightScaled = (this.fluidbook.datas.menuHeight) * navScale,
+            arrow = $('#interface #next').get(0).getBoundingClientRect(), // Used for calculating offsets for both #next & #previous
+            nextTop,
+            firstTop;
+
+        // The arrow element contains both arrows in a single image
+        // so we calculate the top position of the labels by percentage
+        nextTop = Math.round(arrow.top + arrow.height * 0.35);
+        firstTop = Math.round(arrow.top + arrow.height * 0.71);
+
+        // Navigation arrow labels
+        this.view.find('.previous, .next').css({
+            top: nextTop
+        });
+        this.view.find('.first, .last').css({
+            top: firstTop
+        });
+
+        // Labels are swapped for RTL documents
+        var prevPosition = (dir == 'ltr') ? {left: Math.round(arrow.width)} : {right: Math.round(arrow.width)},
+            nextPosition = (dir == 'ltr') ? {right: Math.round(arrow.width)} : {left: Math.round(arrow.width)};
+
+        this.view.find('.previous, .first').css(prevPosition);
+        this.view.find('.next, .last').css(nextPosition);
+
+
+        // Slider label
+        var positionSliderLabel = function () {
+            var sliderHelp = $this.view.find('.slider');
+            var sliderCursor = $('#slidercursor .visible');
+            sliderHelp.css({
+                bottom: Math.round(hh - sliderCursor.offset().top),
+                left: Math.round(sliderCursor.offset().left + (sliderCursor.width() / 2)),
+                transformOrigin: 'left bottom'
+            });
+        };
+        positionSliderLabel(); // Run immediately
+        setTimeout(positionSliderLabel, 250); // delay slightly to make sure co-ordinates are correct
+
+        this.view.find('#icons').css({
+            top: menuHeightScaled,
+            transform: 'scale(' + navScale + ')'
+        });
+
+        $("#helpView #icons").css({
+            fontSize: (14 / navScale) * interfaceScale
+        });
+
+        this.view.find('.illustration').css({
+            transform: 'translate(-50%, -50%) scale(' + interfaceScale + ')'
+        });
+
+        $("#helpView .interface").find('> div').transform({
+            scale: [interfaceScale, interfaceScale]
+        })
+
+    },
+    clearTimeout: function () {
+        clearTimeout(this.autoTimeout);
+    },
+    displayAtStartup: function () {
+        if (this.fluidbook.datas.helpStartup) {
+            this.show(parseInt(this.fluidbook.datas.helpStartupTime));
+            if (this.fluidbook.pad.enabled) {
+                this.fluidbook.pad.displayInterface();
+            }
+        } else {
+            this.fluidbook.hideUnnecessaryButtons();
+        }
+    },
+
+    bookmarkLabel: function () {
+
+        // The bookmark help element is a bit complex because it must be placed in a section of the help overlay that is
+        // not already used by the icon labels. Since the menu can be either on the left or right, this needs to be taken
+        // into account. On the first and last pages of the Fluidbook we don't have a left or right page so it might not
+        // be possible to always display the bookmark icon in this case...
+
+        var dir = this.fluidbook.l10n.dir,
+            inverted = this.fluidbook.datas.invertMenuPosition,
+            side = ((dir == 'ltr' && inverted) || (dir == 'rtl' && !inverted)) ? 'left' : 'right',
+            baseElement = $('#links .bookmark.' + side), // Original element used to provide position and sizing for overlay
+            html = '';
+
+        // If bookmark icon isn't present on the side we want, it means that we're on
+        // the first/last page and that side is missing so we can't display the help
+        if (baseElement.length == 0) {
+            return '';
+        }
+
+        // Get the offset and dimensions of the element, taking into account the scaling
+        var box = baseElement[0].getBoundingClientRect(),
+            circleExtra = 20 * this.fluidbook.resize.interfaceScale, // How much bigger the circle should be around the bookmark icon
+            lineLength = 30; // Length of the line to the label text
+
+        // The bookmark icon sits inside a circle that is slightly bigger so in order to make the icon sit exactly
+        // on the corner of the page, we must offset the difference added by the larger wrapping circle.
+        var circleOffset = circleExtra / 2;
+
+        // Build a HTML string via jQuery with all the styling
+        // Bookmark icon:
+        var icon = $('<div/>').css({
+            width: Math.round(box.width),
+            height: Math.round(box.height),
+            margin: Math.round(circleOffset), // Centre inside circle
+            backgroundSize: 'contain',
+            backgroundPosition: 'center',
+            backgroundRepeat: 'no-repeat',
+            backgroundImage: baseElement.css('backgroundImage').replace('off.svg', 'on.svg') // Show the "on" state if not already set
+        })[0].outerHTML;
+
+        // Circle around the icon - slightly bigger
+        html += $('<div>' + icon + '</div>').css({
+            width: Math.round(box.width + circleExtra),
+            height: Math.round(box.height + circleExtra),
+            borderRadius: '50%',
+            border: '1px solid'
+        })[0].outerHTML;
+
+        // Line to text
+        html += $('<div/>').css({
+            width: lineLength,
+            height: 0,
+            borderBottom: '1px solid',
+        })[0].outerHTML;
+
+        // Help text label
+        html += $('<div>' + this.fluidbook.l10n.__('add / remove bookmark') + '</div>').css({
+            whiteSpace: 'nowrap',
+            padding: '0 0.5em' // Ensure spacing around text regardless which side the line is on
+        })[0].outerHTML;
+
+
+        // Wrapper with positioning and layout switched depending on the side
+        var wrapperCSS = { // Shared properties
+                display: 'flex',
+                alignItems: 'center',
+                position: 'absolute',
+                top: Math.round(box.top - circleOffset)
+            },
+            wrapperLayout;
+
+        if (side == 'left') {
+            wrapperLayout = {
+                left: Math.round(box.left - circleOffset),
+                transformOrigin: 'left top',
+                flexDirection: 'row' // Flexbox direction controls order of elements (icon, line, label)
+            };
+        } else {
+            wrapperLayout = {
+                right: Math.round(this.fluidbook.resize.ww - box.left - box.width - circleOffset),
+                transformOrigin: 'right top',
+                flexDirection: 'row-reverse' // Reverse order of elements for right hand page
+            }
+        }
+
+        var wrapper = $('<div class="bookmark-help">' + html + '</div>')
+            .css(
+                $.extend(wrapperCSS, wrapperLayout) // Merge all properties
+            )[0].outerHTML
+
+        return wrapper;
+    }
+};
+
index 25429ac07d645002892d6c0bdc69e13a13fd022c..879744d3e08bdb9ae9d8740adfcbd7c90aaf81da 100644 (file)
@@ -1870,194 +1870,7 @@ ul.chapters.shareList a.level0 .svg-icon {
        }
 }
 
-/* Help */
-#helpViewOverlay {
-       display: none;
-       z-index: 30;
-       position: absolute;
-       top: 0;
-       right: 0;
-       bottom: 0;
-       left: 0;
-       background-color: transparent;
-}
-
-#helpView {
-       background-color: rgba(0, 0, 0, 0.7);
-       position: absolute;
-       top: 0;
-       height: 100%;
-       width: 100%;
-       z-index: 20;
-       display: none;
-       color: #ffffff;
-       overflow: hidden;
-
-       .illustration {
-               position: absolute;
-               top: 50%;
-               left: 50%;
-               //transform: translate(-50%, -50%); // Transform handled via fluidbook.help.js so dynamic scaling can be done
-               text-align: center;
-               font-size: 20px;
-
-               img {
-                       max-width: 100%;
-                       height: auto;
-               }
-
-               p {
-                       position: static;
-               }
-
-       }
-
-       #icons {
-               position: absolute;
-
-               @media all and (max-width: @menu-breakpoint) {
-                       display: none;
-               }
-       }
-
-       .portrait & .icon.afterSearch {
-               display: none;
-       }
-
-       .icon {
-               position: absolute;
-               top: 0px;
-               display: inline-block;
-               white-space: nowrap;
-               padding: 0 0.5em;
-               border-color: #fff;
-               border-style: solid;
-               border-width: 0 0 0 1px; // Left border
-
-               // When in RTL default or LTR with menu inverted, the labels need to be on the other side of the line
-               .rtl.menu-default &, .ltr.menu-inverted & {
-                       border-width: 0 1px 0 0; // Right border
-                       transform: translateX(-100%); // Flip position back to where it would be if it was based on a left border line
-               }
-       }
-
-       .icon span {
-               position: relative;
-               bottom: -0.5em;
-
-               & .rtl {
-                       position: absolute;
-                       right: 1em;
-                       margin-top: -1em;
-               }
-       }
-
-}
-
-#helpView .interface hr {
-       width: 30px;
-       height: 0px;
-       border: 0;
-       border-top: 1px solid #ffffff;
-       display: inline-block;
-       margin: 0 10px;
-       vertical-align: middle;
-}
-
-#helpView .down {
-       position: absolute;
-       right: 62px;
-       bottom: 20px;
-}
-
-#helpView .down hr {
-       width: 30px;
-       height: 0px;
-       border: 0;
-       border-top: 1px solid #ffffff;
-       display: inline-block;
-       margin: 0 10px;
-       vertical-align: middle;
-}
-
-#helpView .interface .slider {
-       position: absolute;
-       display: inline-block;
-       border-left: 1px solid #fff;
-       padding: 0 0 20px 0.5em;
-       white-space: nowrap;
-
-       span {
-               position: relative;
-               top: -0.5em;
-       }
-}
-
-#helpView {
-       .next, .last, .previous, .first {
-               margin-top: -0.5em;
-               line-height: 1;
-       }
-
-       .next, .last {
-               transform-origin: right;
-
-               .rtl & {
-                       transform-origin: left;
-               }
-       }
-
-       .previous, .first {
-               transform-origin: left;
-
-               .rtl & {
-                       transform-origin: right;
-               }
-       }
-}
-
-.ltr #helpView .interface .next:after,
-.ltr #helpView .interface .last:after,
-.rtl #helpView .interface .first:after,
-.rtl #helpView .interface .previous:after {
-       content: '------------';
-       width: 100px;
-       border-bottom: 1px solid #fff;
-       margin-left: 10px;
-       position: relative;
-       top: -0.5em;
-       color: transparent;
-}
-
-.rtl #helpView .interface .next:before,
-.rtl #helpView .interface .last:before,
-.ltr #helpView .interface .first:before,
-.ltr #helpView .interface .previous:before {
-       content: '------------';
-       width: 100px;
-       border-bottom: 1px solid #fff;
-       margin-right: 10px;
-       position: relative;
-       top: -0.5em;
-       color: transparent;
-}
-
-#helpView .interface > div {
-       position: absolute;
-       direction: ltr;
-}
-
-.portrait #helpView .interface {
-       display: none;
-}
-
-.pad.portrait #helpView .interface {
-       display: block;
-}
-
-.pad #helpView .illustration {
-       display: none;
-}
+@import "help";
 
 /* Archives */
 #archivesview {
diff --git a/style/help.less b/style/help.less
new file mode 100644 (file)
index 0000000..c46d032
--- /dev/null
@@ -0,0 +1,188 @@
+/* Help */
+#helpViewOverlay {
+       display: none;
+       z-index: 30;
+       position: absolute;
+       top: 0;
+       right: 0;
+       bottom: 0;
+       left: 0;
+       background-color: transparent;
+}
+
+#helpView {
+       background-color: rgba(0, 0, 0, 0.7);
+       position: absolute;
+       top: 0;
+       height: 100%;
+       width: 100%;
+       z-index: 20;
+       display: none;
+       color: #ffffff;
+       overflow: hidden;
+
+       .illustration {
+               position: absolute;
+               top: 50%;
+               left: 50%;
+               //transform: translate(-50%, -50%); // Transform handled via fluidbook.help.js so dynamic scaling can be done
+               text-align: center;
+               font-size: 20px;
+
+               img {
+                       max-width: 100%;
+                       height: auto;
+               }
+
+               p {
+                       position: static;
+               }
+
+       }
+
+       #icons {
+               position: absolute;
+
+               @media all and (max-width: @menu-breakpoint) {
+                       display: none;
+               }
+       }
+
+       .portrait & .icon.afterSearch {
+               display: none;
+       }
+
+       .icon {
+               position: absolute;
+               top: 0px;
+               display: inline-block;
+               white-space: nowrap;
+               padding: 0 0.5em;
+               border-color: #fff;
+               border-style: solid;
+               border-width: 0 0 0 1px; // Left border
+
+               // When in RTL default or LTR with menu inverted, the labels need to be on the other side of the line
+               .rtl.menu-default &, .ltr.menu-inverted & {
+                       border-width: 0 1px 0 0; // Right border
+                       transform: translateX(-100%); // Flip position back to where it would be if it was based on a left border line
+               }
+       }
+
+       .icon span {
+               position: relative;
+               bottom: -0.25em;
+
+               & .rtl {
+                       position: absolute;
+                       right: 1em;
+                       margin-top: -1em;
+               }
+       }
+
+}
+
+#helpView .interface hr {
+       width: 30px;
+       height: 0px;
+       border: 0;
+       border-top: 1px solid #ffffff;
+       display: inline-block;
+       margin: 0 10px;
+       vertical-align: middle;
+}
+
+#helpView .down {
+       position: absolute;
+       right: 62px;
+       bottom: 20px;
+}
+
+#helpView .down hr {
+       width: 30px;
+       height: 0px;
+       border: 0;
+       border-top: 1px solid #ffffff;
+       display: inline-block;
+       margin: 0 10px;
+       vertical-align: middle;
+}
+
+#helpView .interface .slider {
+       position: absolute;
+       display: inline-block;
+       border-left: 1px solid #fff;
+       padding: 0 0 20px 0.5em;
+       white-space: nowrap;
+
+       span {
+               position: relative;
+               top: -0.5em;
+       }
+}
+
+#helpView {
+       .next, .last, .previous, .first {
+               margin-top: -0.5em;
+               line-height: 1;
+       }
+
+       .next, .last {
+               transform-origin: right;
+
+               .rtl & {
+                       transform-origin: left;
+               }
+       }
+
+       .previous, .first {
+               transform-origin: left;
+
+               .rtl & {
+                       transform-origin: right;
+               }
+       }
+}
+
+.ltr #helpView .interface .next:after,
+.ltr #helpView .interface .last:after,
+.rtl #helpView .interface .first:after,
+.rtl #helpView .interface .previous:after {
+       content: '------------';
+       width: 100px;
+       border-bottom: 1px solid #fff;
+       margin-left: 10px;
+       position: relative;
+       top: -0.5em;
+       color: transparent;
+}
+
+.rtl #helpView .interface .next:before,
+.rtl #helpView .interface .last:before,
+.ltr #helpView .interface .first:before,
+.ltr #helpView .interface .previous:before {
+       content: '------------';
+       width: 100px;
+       border-bottom: 1px solid #fff;
+       margin-right: 10px;
+       position: relative;
+       top: -0.5em;
+       color: transparent;
+}
+
+#helpView .interface > div {
+       position: absolute;
+       direction: ltr;
+}
+
+.portrait #helpView .interface {
+       display: none;
+}
+
+.pad.portrait #helpView .interface {
+       display: block;
+}
+
+.pad #helpView .illustration {
+       display: none;
+}
\ No newline at end of file