make main menu collapsible, just like the top menu, fixes #9

- rename TopMenuCollapse.js to MenuCollapse.js
- refactor MenuCollapse to handle two menus
- add dark image icons for arrow up and down
This commit is contained in:
mrliptontea
2015-04-17 15:39:25 +02:00
parent 7f518e0ff7
commit aebbfbaf17
9 changed files with 257 additions and 117 deletions

View File

@@ -61,6 +61,7 @@ Latest (master):
* Fixed #8: Setting `$top-menu-collapse` to `true` will enable script allowing to toggle if top menu should be collapsed (no wrapping) or expanded (wrapped, with auto height)
+ Header matching current URL fragment will have `#` prepended
+ Introduced `$font-weight-normal` and `$font-weight-bold` variables to give better control on the appearance of text with custom fonts
* Fixed #9: Added `$main-menu-collapse` and applied the same logic as in #8
v1.5.0 (2015-04-15):

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,142 @@
var PurpleMine = PurpleMine || {};
PurpleMine.MenuCollapse = (function()
{
"use strict";
var self; // Make it work for browsers without Function.prototype.bind
var translations = {
en: {
topMenuToggler : "Expand/collapse top menu",
mainMenuToggler: "Expand/collapse main menu"
},
pl: {
topMenuToggler : "Zwiń/rozwiń górne menu",
mainMenuToggler: "Zwiń/rozwiń główne menu"
}
};
function MenuCollapse()
{
if (self)
{
return self;
}
self = this;
this.lang = document.documentElement.lang;
if (typeof translations[this.lang] === "undefined")
{
this.lang = "en";
}
this._ = translations[this.lang];
this.menus = {
top: {
$el: $("#top-menu")
},
main: {
$el: $("#main-menu")
}
};
for (var menu in this.menus)
{
if (this.menus.hasOwnProperty(menu) &&
this.menus[menu].$el.length > 0)
{
handleMenu(menu);
}
}
}
function handleMenu(menu)
{
if ("none" === self.menus[menu].$el.css("maxHeight"))
{
return false;
}
self.menus[menu].collapsed = true;
if (window.localStorage)
{
self.menus[menu].collapsed =
null === localStorage.getItem(getMenuStorageKey(menu));
}
buildToggleButton(menu);
if (false === self.isCollapsed(menu))
{
self.expandMenu(menu);
}
}
function getMenuStorageKey(menu)
{
return "PurpleMine:" + menu + "MenuExpanded";
}
function buildToggleButton(menu)
{
var togglerClass = menu + "-menu-toggler",
togglerLabel = self._[menu + "MenuToggler"],
togglerHtml;
togglerHtml = "<a href=\"javascript:;\" class=\"" + togglerClass +
"\" title=\"" + togglerLabel + "\"></a>";
self.menus[menu].$toggler = $(togglerHtml);
self.menus[menu].$el.prepend(self.menus[menu].$toggler);
self.menus[menu].$toggler.on("click", { menu: menu }, self.toggleMenu);
}
MenuCollapse.prototype.toggleMenu = function(event)
{
var menu = event.data.menu || "";
if (self.isCollapsed(menu))
{
self.expandMenu(menu);
}
else
{
self.collapseMenu(menu);
}
};
MenuCollapse.prototype.isCollapsed = function(menu)
{
return this.menus[menu].collapsed;
};
MenuCollapse.prototype.expandMenu = function(menu)
{
this.menus[menu].$el.addClass("expanded");
this.menus[menu].$toggler.addClass("expanded");
this.menus[menu].collapsed = false;
if (window.localStorage)
{
localStorage.setItem(getMenuStorageKey(menu), "x");
}
};
MenuCollapse.prototype.collapseMenu = function(menu)
{
this.menus[menu].$el.removeClass("expanded");
this.menus[menu].$toggler.removeClass("expanded");
this.menus[menu].collapsed = true;
if (window.localStorage)
{
localStorage.removeItem(getMenuStorageKey(menu));
}
};
return MenuCollapse;
}());

View File

@@ -1,100 +0,0 @@
var PurpleMine = PurpleMine || {};
PurpleMine.TopMenuCollapse = (function()
{
"use strict";
var self; // Make it work for browsers without Function.prototype.bind
var translations = {
en: {
toggler: "Expand/collapse top menu"
},
pl: {
toggler: "Zwiń/rozwiń górne menu"
}
};
function TopMenuCollapse()
{
self = this;
this.topMenuCollapsed = true;
this.$toggler = null;
this.$topMenu = $("#top-menu");
this.lang = document.documentElement.lang;
if (typeof translations[this.lang] === "undefined")
{
this.lang = "en";
}
this._ = translations[this.lang];
if ("none" !== this.$topMenu.css("maxHeight"))
{
if (window.localStorage)
{
this.topMenuCollapsed =
null === localStorage.getItem("PurpleMine:topMenuExpanded");
}
this.buildToggleButton();
if (false === this.topMenuCollapsed)
{
this.expandTopMenu(true);
}
}
}
TopMenuCollapse.prototype.buildToggleButton = function()
{
var togglerClass = "top-menu-toggler",
togglerHtml;
togglerHtml = "<a href=\"javascript:;\" class=\"" + togglerClass +
"\" title=\"" + this._.toggler + "\"></a>";
this.$toggler = $(togglerHtml);
this.$topMenu.prepend(this.$toggler);
this.$toggler.on("click", this.toggleTopMenu);
};
TopMenuCollapse.prototype.toggleTopMenu = function()
{
if (self.topMenuCollapsed)
{
self.expandTopMenu();
}
else
{
self.collapseTopMenu();
}
};
TopMenuCollapse.prototype.expandTopMenu = function()
{
this.$topMenu.addClass("expanded");
this.$toggler.addClass("expanded");
this.topMenuCollapsed = false;
if (window.localStorage)
{
localStorage.setItem("PurpleMine:topMenuExpanded", "x");
}
};
TopMenuCollapse.prototype.collapseTopMenu = function()
{
this.$topMenu.removeClass("expanded");
this.$toggler.removeClass("expanded");
this.topMenuCollapsed = true;
if (window.localStorage)
{
localStorage.removeItem("PurpleMine:topMenuExpanded");
}
};
return TopMenuCollapse;
}());

View File

@@ -5,5 +5,5 @@ $(function()
new PurpleMine.SidebarToggler();
new PurpleMine.HistoryTabs();
new PurpleMine.TopMenuCollapse();
new PurpleMine.MenuCollapse();
});

View File

@@ -18,6 +18,7 @@ $issue-subject-large: true !default;
$enable-sidebar-toggler: true !default;
$wiki-page-more-vertical-space: true !default;
$top-menu-collapse: false !default;
$main-menu-collapse: false !default;
//== Colors
@@ -473,6 +474,7 @@ $screen-sm-max: ($screen-md-min - 1) !default;
$screen-md-max: ($screen-lg-min - 1) !default;
$top-menu-collapse-breakpoint: $screen-lg-min !default;
$main-menu-collapse-breakpoint: $screen-lg-min !default;
//== Content widths

View File

@@ -8,7 +8,7 @@
}
%image-arrow-up {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAYUlEQVR4Xu2SMQqAMAxFVUxOID2FQ+9R3cRjesX4A5lCoaUFB2nhkeQPLxQyi8jU8xbwYwGBC1CrIIFda4sgKq6vFgS/1eZQI2BwZ/5NlnNJcIAtt8ny04ermx/l4zsYgheccgigTIfmMAAAAABJRU5ErkJggg==);
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAGFBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWNxwqAAAACHRSTlMAgFIFe2wwFmA2CKQAAAArSURBVAjXYyASGBlAGYoKEJpNUAzCKBEUKQDRzIGCgsEgBpOgoKAQA5kAAOOzAuqv1pGxAAAAAElFTkSuQmCC);
}
%image-arrow-right {
@@ -16,13 +16,21 @@
}
%image-arrow-down {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAG1BMVEUAAAD////////////////////////////////rTT7CAAAACXRSTlMAgFIFbBZWMTBl3YBFAAAALElEQVQI12MgDTAJCgoKgRjMjoKCzmChQEHBADCDQ1AcqkpRAcowM2AgEQAAvM4CiwrixCQAAAAASUVORK5CYII=);
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAGFBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWNxwqAAAACHRSTlMAgFIFbDAWVn1ccuIAAAAsSURBVAjXYyANMAkKCgqBGMyOgoLOYKFEQcEEMINVUBSqSlEByjA3YCARAADFOwKnW3vw7AAAAABJRU5ErkJggg==);
}
%image-arrow-left {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAGFBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWNxwqAAAACHRSTlMAgF1mUUUMBtml7EIAAAAjSURBVAjXYyAAWGEMRyhdJAih2QyhDCZBhAhcDVwXwhziAACuywJHmKAVPgAAAABJRU5ErkJggg==);
}
%image-arrow-up-white {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAYUlEQVR4Xu2SMQqAMAxFVUxOID2FQ+9R3cRjesX4A5lCoaUFB2nhkeQPLxQyi8jU8xbwYwGBC1CrIIFda4sgKq6vFgS/1eZQI2BwZ/5NlnNJcIAtt8ny04ermx/l4zsYgheccgigTIfmMAAAAABJRU5ErkJggg==);
}
%image-arrow-down-white {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAG1BMVEUAAAD////////////////////////////////rTT7CAAAACXRSTlMAgFIFbBZWMTBl3YBFAAAALElEQVQI12MgDTAJCgoKgRjMjoKCzmChQEHBADCDQ1AcqkpRAcowM2AgEQAAvM4CiwrixCQAAAAASUVORK5CYII=);
}
%image-calendar {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOBAMAAADtZjDiAAAAIVBMVEUAAABVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUMftYpAAAACnRSTlMArIDn/dahwzIKIC4f+wAAADxJREFUCNdjYEhJACEGBk8HEGIQXrDYeMFiAYZVK1YB0QKGVSAApBcwMQgwMSDohaKChqKCxItXgc0pAADUBx5bh1ZBCgAAAABJRU5ErkJggg==);
}

View File

@@ -3,6 +3,7 @@
// --------------------------------------------------
#top-menu {
position: relative;
padding: $padding-small-vertical $padding-side;
background: $top-menu-bg;
color: $top-menu-text;
@@ -11,7 +12,7 @@
@if $top-menu-collapse {
$toggler-position-v: $padding-small-vertical + 1px;
$toggler-position-h: $padding-small-vertical - 1px;
$toggler-position-h: 1px;
max-height: floor($font-size-base * $font-size-small-unitless * $line-height-base) + $padding-small-vertical;
padding-bottom: 0;
@@ -31,7 +32,11 @@
display: block;
position: absolute;
top: $toggler-position-v;
left: $toggler-position-h;
@if $sidebar-position == "left" {
left: $toggler-position-h;
} @else {
right: $toggler-position-h;
}
@include user-select(none);
@if $use-font-awesome {
@@ -41,7 +46,7 @@
content: $fa-var-caret-square-o-down;
}
} @else {
@extend %image-arrow-down;
@extend %image-arrow-down-white;
}
@if $use-font-awesome {
@@ -78,7 +83,7 @@
content: $fa-var-caret-square-o-up;
}
} @else {
@extend %image-arrow-up;
@extend %image-arrow-up-white;
}
}
@@ -198,11 +203,88 @@
}
#main-menu {
border-bottom: 1px solid $main-menu-border;
background-color: $main-menu-bg;
box-shadow: inset 0 -1px $main-menu-border;
@media screen and (max-width: $screen-sm-max) {
font-size: $font-size-small-px;
@if $main-menu-collapse {
$toggler-position-v: $main-menu-padding-vertical + 3px;
$toggler-position-h: 1px;
position: relative;
max-height: $line-height-computed + $main-menu-padding-vertical * 2;
overflow: hidden;
&.expanded {
max-height: none;
}
.main-menu-toggler {
display: block;
position: absolute;
top: $toggler-position-v;
@if $sidebar-position == "left" {
left: $toggler-position-h;
} @else {
right: $toggler-position-h;
}
@include user-select(none);
@if $use-font-awesome {
font-size: 14px;
&:before {
content: $fa-var-caret-square-o-down;
}
} @else {
@extend %image-arrow-down;
}
@if $use-font-awesome {
@extend %fa-icon;
color: mix($main-menu-link, $main-menu-bg, 33%);
line-height: 1;
&:before {
margin-right: 0;
}
&:hover,
&:focus,
&:active {
color: mix($main-menu-link, $main-menu-bg, 50%);
}
} @else {
width: 15px;
height: 15px;
border-radius: $border-radius-base;
background-repeat: no-repeat;
background-position: center center;
&:hover,
&:focus,
&:active {
background-color: darken($main-menu-bg, 15%);
}
}
&.expanded {
@if $use-font-awesome {
&:before {
content: $fa-var-caret-square-o-up;
}
} @else {
@extend %image-arrow-up;
}
}
@media screen and (min-width: $main-menu-collapse-breakpoint) {
display: none;
}
}
} @else {
@media screen and (max-width: $screen-sm-max) {
font-size: $font-size-small-px;
}
}
ul {
@@ -214,17 +296,22 @@
> li {
margin-right: .5em;
margin-bottom: -1px;
float: left;
> a {
display: block;
padding: $main-menu-padding-vertical 0;
white-space: nowrap;
@include transition(box-shadow .2s);
@media screen and (min-width: $screen-md-min) {
padding-right: $main-menu-padding-horizontal;
padding-left: $main-menu-padding-horizontal;
@if $main-menu-collapse {
padding: $main-menu-padding-vertical $main-menu-padding-horizontal;
} @else {
padding: $main-menu-padding-vertical 0;
@media screen and (min-width: $screen-md-min) {
padding-right: $main-menu-padding-horizontal;
padding-left: $main-menu-padding-horizontal;
}
}
@media screen and (min-width: $screen-lg-min) {

File diff suppressed because one or more lines are too long