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:
@@ -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
142
src/javascripts/modules/MenuCollapse.js
Normal file
142
src/javascripts/modules/MenuCollapse.js
Normal 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;
|
||||
}());
|
||||
@@ -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;
|
||||
}());
|
||||
@@ -5,5 +5,5 @@ $(function()
|
||||
|
||||
new PurpleMine.SidebarToggler();
|
||||
new PurpleMine.HistoryTabs();
|
||||
new PurpleMine.TopMenuCollapse();
|
||||
new PurpleMine.MenuCollapse();
|
||||
});
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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==);
|
||||
}
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user