From f9da6156aedd2ab6d94acf186eec3fbab67ca9af Mon Sep 17 00:00:00 2001 From: Stephen Cameron Date: Wed, 21 Jun 2017 18:11:35 +0200 Subject: [PATCH] WIP #807 @6 --- images/interface.svg | 36 ++++++++ js/libs/fluidbook/fluidbook.js | 22 ++++- js/libs/fluidbook/fluidbook.menu.js | 2 - js/libs/fluidbook/fluidbook.nav.js | 91 +++++++++++++------- js/libs/fluidbook/fluidbook.search.js | 2 +- js/libs/fluidbook/fluidbook.utils.js | 14 ++- js/main.js | 2 +- style/fluidbook.less | 29 ------- style/mmenu/mmenu.less | 119 +++++++++++++++++++++++--- 9 files changed, 235 insertions(+), 82 deletions(-) diff --git a/images/interface.svg b/images/interface.svg index b55c7f56..5586dbcf 100644 --- a/images/interface.svg +++ b/images/interface.svg @@ -8,4 +8,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/js/libs/fluidbook/fluidbook.js b/js/libs/fluidbook/fluidbook.js index fed53a29..59d982ea 100644 --- a/js/libs/fluidbook/fluidbook.js +++ b/js/libs/fluidbook/fluidbook.js @@ -713,13 +713,26 @@ Fluidbook.prototype = { return this.datas.numerotation.indexOf(page) + 1; }, + hideMenuItems: function (exception) { + exception = exception || ''; + $('#menuList > ul > li').not(exception).fadeOut(100); + }, + + showMenuItems: function (exception) { + exception = exception || ''; + $('#menuList > ul > li').not(exception).fadeIn(300); + }, + + initSearchHints: function () { this.menuSearchHints = $('#menuSearchHints'); + this.hideMenuItems('#menuSearch'); // Hide everything except the search form so we can have space for the hints - if (this.menuSearchHints.hasClass('mm-hidden')) { - this.nav.menuAPI.openPanel(this.menuSearchHints, false); - } + this.menuSearchHints.fadeIn(300); + // if (this.menuSearchHints.hasClass('mm-hidden')) { + // this.nav.menuAPI.openPanel(this.menuSearchHints, false); + // } }, getSearchHints: function (q) { @@ -756,7 +769,8 @@ Fluidbook.prototype = { // this.killLastSearchHint(); // $("#searchHints").html(''); // $("#searchHints").hide(); - this.nav.menuAPI.closeAllPanels(); // Todo: see if we can just close the hints panel. Doesn't seem to work using .closePanel(...). See how built-in search plugin works + this.menuSearchHints.html('').hide(); // Clear and hide all hints + this.showMenuItems('#menuSearch'); // Show menu items that were hidden previously }, getLocationToShare: function () { if (this.datas.phonegap) { diff --git a/js/libs/fluidbook/fluidbook.menu.js b/js/libs/fluidbook/fluidbook.menu.js index 9241e264..53fde9b4 100644 --- a/js/libs/fluidbook/fluidbook.menu.js +++ b/js/libs/fluidbook/fluidbook.menu.js @@ -115,8 +115,6 @@ FluidbookMenu.prototype = { displayResults: function (data, group, callback) { - // ToDo: investigate MMenu dynamic content for displaying in menu: http://mmenu.frebsite.nl/tutorials/dynamic-content.html - var $this = this; var results = data.results; var hideNoResults = !this.fluidbook.datas.searchShowNoResultsPages; diff --git a/js/libs/fluidbook/fluidbook.nav.js b/js/libs/fluidbook/fluidbook.nav.js index 1f67d803..88c5c460 100644 --- a/js/libs/fluidbook/fluidbook.nav.js +++ b/js/libs/fluidbook/fluidbook.nav.js @@ -11,22 +11,22 @@ function FluidbookNav(fluidbook) { FluidbookNav.prototype = { initMenu: function () { - var $this = this, - navbars = [ - { - "position": "bottom", - "content": [ - '[Sharing links]' - ] - } - ]; - - if (this.fluidbook.datas.search) { - navbars.push({ - "position": "top", - "content": [ this.getSearch() ] - }); - } + var $this = this; + // navbars = [ + // { + // "position": "bottom", + // "content": [ + // '[Sharing links]' + // ] + // } + // ]; + // + // if (this.fluidbook.datas.search) { + // navbars.push({ + // "position": "top", + // "content": [ this.getSearch() ] + // }); + // } this.menu.mmenu({ @@ -49,7 +49,7 @@ FluidbookNav.prototype = { //add: false // Removes main title bars completely title: "" // Hides the default "Menu" text }, - "navbars": navbars + //"navbars": navbars }); this.menuAPI = this.menu.data('mmenu'); @@ -111,7 +111,7 @@ FluidbookNav.prototype = { } res += '>'; if (icon) { - res += this.getIcon(name); + res += getSpriteIcon(name); } // Temporary: use the help text as the link text - we probably need a dedicated string for these @@ -148,6 +148,9 @@ FluidbookNav.prototype = { // Add holder list element for menu items this.menu.append(''); + // Add Search form + $('#menuList').prepend(''); + try { var skipHome = (window.localStorage.getItem('home') === '0'); var forceHome = (window.localStorage.getItem('home') === '1'); @@ -189,14 +192,14 @@ FluidbookNav.prototype = { return false; }) } else if (icon == 'index') { - this.addLink('nav-index', '#/index', 'index', 'overview'); + this.addLink('interface-index', '#/index', 'index', 'overview'); } else if (icon == 'chapters') { if (this.fluidbook.datas.displayChaptersIcon) { if (this.fluidbook.datas.chaptersPage != '') { - this.addLink('nav-sommaire', '#/page/' + this.fluidbook.datas.chaptersPage, 'chapters', 'chapters'); + this.addLink('interface-chapters', '#/page/' + this.fluidbook.datas.chaptersPage, 'chapters', 'chapters'); } else if (this.fluidbook.datas.chapters.length > 0) { // this.addLink('nav-sommaire', '#/chapters', 'chapters', 'chapters'); - this.addLink('nav-sommaire', '', 'chapters', 'chapters'); + this.addLink('interface-chapters', '', 'chapters', 'chapters'); // Get HTML for submenus (appended later) this.chaptersMenuHTML = this.makeChapterLists(this.fluidbook.datas.chapters); @@ -215,7 +218,7 @@ FluidbookNav.prototype = { } } else if (icon == 'bookmark') { if (this.fluidbook.datas.bookmark) { - this.addLink('nav-bookmark', '#/bookmark', 'bookmarks', 'bookmarks'); + this.addLink('interface-bookmarks', '#/bookmark', 'bookmarks', 'bookmarks'); $("#bookmarks").click(function () { if (!$this.fluidbook.bookmarks.hasBookmarkedPages()) { var message = $this.fluidbook.l10n.__("you don't have any bookmarks"); @@ -231,7 +234,7 @@ FluidbookNav.prototype = { } } else if (icon == 'pdf' || icon == 'print') { if ($("#print").length == 0 && (this.fluidbook.datas.print || this.fluidbook.datas.pdf)) { - this.addLink('nav-print', '#', 'print', '!' + this.fluidbook.l10n.__('print') + ' | ' + this.fluidbook.l10n.__('download pdf')); + this.addLink('interface-print', '#', 'print', '!' + this.fluidbook.l10n.__('print') + ' | ' + this.fluidbook.l10n.__('download pdf')); $("#print").on('click', function () { $this.fluidbook.print(); return false; @@ -248,7 +251,7 @@ FluidbookNav.prototype = { this.addLink('nav-archives', '#/archives', 'archives', '!' + this.fluidbook.datas.archivesLabel); } } else if (icon == 'help') { - this.addLink('nav-help', '#', 'help', 'help'); + this.addLink('interface-help', '#', 'help', 'help'); } else if (icon == 'zoom' && !this.fluidbook.support.isMobile) { this.addLink('nav-zoomin', '#', 'zoomin', 'zoom in'); this.addLink('nav-zoomout', '#', 'zoomout', 'zoom out'); @@ -263,7 +266,7 @@ FluidbookNav.prototype = { return false; }); } else if (icon == 'fullscreen' && Modernizr.fullscreen && !DATAS.phonegap) { - this.addLink('nav-fullscreen', '#', 'fullscreen', 'switch between fullscreen and normal'); + this.addLink('interface-fullscreen', '#', 'fullscreen', 'switch between fullscreen and normal'); $("#fullscreen").click(function () { screenfull.toggle(); return false; @@ -295,8 +298,6 @@ FluidbookNav.prototype = { } }); - $('#menu').append(''); - $('#menu').append(''); // If the chapters menu is not cascading, wrap submenu lists in
s so that MMenu will show them in the same panel if (!this.fluidbook.datas.chaptersCascade) { @@ -312,6 +313,9 @@ FluidbookNav.prototype = { //console.log($('#menuList').parent().html()); } + // Add close button to menu + this.menu.append(this.getMenuCloseButton()); + this.initMenu(); $(this.fluidbook).trigger('fluidbooknavready'); @@ -326,12 +330,28 @@ FluidbookNav.prototype = { this.menu.append(l); this.menu.find("#locales").css('background-image', 'url("images/flags/' + flag + '.png")'); }, + + getMenuCloseButton: function () { + var $this = this, + buttonID = 'menuClose'; + + // Click handler to close menu + $(document).on('click', '#' + buttonID, function(e) { + e.preventDefault(); + $this.menuAPI.close(); + }); + + return ''+ getSpriteIcon('interface-close') +''; + }, + getSearch: function () { var $this = this; var res = '
'; res += ''; res += this.getLink('interface-search', '#', 'submitSearch'); res += '
'; + res += ''; + res += ''; $("#search").append(res); // Search submit button @@ -341,18 +361,25 @@ FluidbookNav.prototype = { return false; }) - // Search form + // Search form handler $(document).on('submit', '#searchForm', function () { var q = $("#q").val(); if (q == '') { return false; } - window.location.hash = '/search/' + q; + $this.fluidbook.search.find(q, function (results) { + // Todo: see FluidbookMenu displayResults function... + //$this.displayResults(r, group, cb); + console.log('Search results...'); + console.log(results); + }); - if ($this.menuIsOpen) { - $this.menuAPI.close(); - } + // window.location.hash = '/search/' + q; + // + // if ($this.menuIsOpen) { + // $this.menuAPI.close(); + // } return false; }); diff --git a/js/libs/fluidbook/fluidbook.search.js b/js/libs/fluidbook/fluidbook.search.js index 672d284c..e5f3c681 100644 --- a/js/libs/fluidbook/fluidbook.search.js +++ b/js/libs/fluidbook/fluidbook.search.js @@ -32,7 +32,7 @@ FluidbookSearch.prototype = { var words = this.normalizeQuery(q); q = words.pop(); var res = []; - if (q.length < 3) { + if (q.length < 2) { return res; } diff --git a/js/libs/fluidbook/fluidbook.utils.js b/js/libs/fluidbook/fluidbook.utils.js index f02f3bf5..ab2f0eed 100644 --- a/js/libs/fluidbook/fluidbook.utils.js +++ b/js/libs/fluidbook/fluidbook.utils.js @@ -49,18 +49,28 @@ function getBaseURL(removeQuery) { } function getSpriteIcon(icon, attrs) { - var a = []; + var a = [], + iconSymbol = $('svg symbol#' + icon); + + if (iconSymbol.length == 0) { + console.warn('Unable to find sprite icon: ' + icon); + return ''; // Bail out because symbol doesn't exist + } + if (attrs == undefined) { attrs = {}; } if (attrs.viewBox == null) { - attrs.viewBox = $('svg symbol#' + icon).get(0).attributes.viewBox.value; + attrs.viewBox = iconSymbol.get(0).attributes.viewBox.value; } if (attrs.class == null) { attrs.class = icon; } else { attrs.class += ' ' + icon; } + + attrs.class += ' svg-icon'; // Common class for all icons + $.each(attrs, function (k, v) { a.push(k + '="' + v + '"'); }); diff --git a/js/main.js b/js/main.js index 31711d70..592a9769 100644 --- a/js/main.js +++ b/js/main.js @@ -499,7 +499,7 @@ function setBackground(page, resolution) { } function searchHints() { - if ($("#q").val().length >= 3) { + if ($("#q").val().length >= 2) { fluidbook.initSearchHints(); fluidbook.getSearchHints($("#q").val()); } else { diff --git a/style/fluidbook.less b/style/fluidbook.less index 7cdd5b8d..9f565ed4 100644 --- a/style/fluidbook.less +++ b/style/fluidbook.less @@ -534,35 +534,6 @@ header { margin: 0 5px 0 0; } -#menu { - //position: relative; - //white-space: nowrap; - background-color: @menu-background; - color: @menu-text; - - a, span { - padding: 10px; - - img { - display: inline-block; - vertical-align: middle; - margin-right: 0.7em; - } - } - - //> a { - // vertical-align: top; - // display: inline-block; - //} -} - -#menuOpener { - position: absolute; - right: 10px; - top: 10px; - color: @menu-text; -} - #afterSearch { display: inline-block; position: relative; diff --git a/style/mmenu/mmenu.less b/style/mmenu/mmenu.less index 8207c052..64a601a0 100644 --- a/style/mmenu/mmenu.less +++ b/style/mmenu/mmenu.less @@ -6,6 +6,10 @@ // MMenu overrides .mm-menu { + &.mm-offcanvas { + max-width: 320px; + } + .mm-navbar { height: auto; @@ -15,14 +19,30 @@ } } +// Menu title bar +.mm-navbar .mm-title { + line-height: 60px; + padding: 0 !important; +} + +// < Title bar back arrow +.mm-btn.mm-prev { + height: 60px; +} + +// Make menu items sit properly under title bar +.mm-panels>.mm-panel>.mm-listview:first-child, .mm-panels>.mm-panel>.mm-navbar+.mm-listview { + margin-top: 0; +} + // Submenu arrows < > .mm-menu .mm-btn:after, .mm-menu .mm-btn:before, .mm-menu .mm-listview>li .mm-next:after { border-color: @menu-text; } -.mm-hasnavbar-top-1 .mm-panels { - top: 60px; -} +//.mm-hasnavbar-top-1 .mm-panels { +// top: 60px; +//} // Page overlay opacity html.mm-opening .mm-menu.mm-opened[class*=mm-pagedim]~#mm-blocker { @@ -32,17 +52,94 @@ html.mm-opening .mm-menu.mm-opened[class*=mm-pagedim]~#mm-blocker { // Fluidbook menu styles +#menu { + //position: relative; + //white-space: nowrap; + background-color: @menu-background; + color: @menu-text; + + a, span { + padding: 10px; + + img { + display: inline-block; + vertical-align: middle; + margin-right: 0.7em; + } + } + + //> a { + // vertical-align: top; + // display: inline-block; + //} +} + +#menuOpener { + position: absolute; + right: 10px; + top: 10px; + color: @menu-text; +} + +#menuSearch { + &:after { + border: none; + } +} + +// Main menu with icons +#menuList { + &:before { + height: 0; // Fix spacing with search box + } + + .svg-icon { + width: 25px; + height: 25px; + vertical-align: middle; + margin-right: 10px; + } +} + + +#menuClose { + position: absolute; + top: 0; + right: 0; + width: 60px; + height: 60px; + padding: 22px !important; // Controls size of icon and position within the element + color: @menu-text; + background-color: overlay(@menu-background, #c0c0c0); +} + + #searchForm { + position: relative; padding: 0; text-align: left; +} - #q { - background-color: @menu-field-background; - color: @menu-field-text; - -webkit-appearance: none; - border: none; - height: 60px; - font-size: 16px; - padding: 0 2em; +#q { + background-color: @menu-field-background; + color: @menu-field-text; + -webkit-appearance: none; + border: none; + height: 60px; + font-size: 16px; + padding: 0 1em 0 2.8em; + width: 260px; +} + +#submitSearch { + position: absolute; + left: 0; + top: 50%; + transform: translateY(-50%); + color: @menu-background; + + .svg-icon { + width: 20px; + height: 20px; } } \ No newline at end of file -- 2.39.5