Commit b2f8ebbb authored by Mike Greiling's avatar Mike Greiling

refactor sidebar logic into singleton class

parent 6690fc70
......@@ -13,6 +13,7 @@ v 8.12.0 (unreleased)
- Instructions for enabling Git packfile bitmaps !6104
- Fix pagination on user snippets page
- Escape search term before passing it to Regexp.new !6241 (winniehell)
- Fix pinned sidebar behavior in smaller viewports !6169
- Change merge_error column from string to text type
- Reduce contributions calendar data payload (ClemMakesApps)
- Add `web_url` field to issue, merge request, and snippet API objects (Ben Boeckel)
......
......@@ -174,9 +174,7 @@
$body.tooltip({
selector: '.has-tooltip, [data-toggle="tooltip"]',
placement: function(_, el) {
var $el;
$el = $(el);
return $el.data('placement') || 'bottom';
return $(el).data('placement') || 'bottom';
}
});
$('.trigger-submit').on('change', function() {
......@@ -286,42 +284,9 @@
gl.awardsHandler = new AwardsHandler();
checkInitialSidebarSize();
new Aside();
if ($window.width() < 1024 && $.cookie('pin_nav') === 'true') {
$.cookie('pin_nav', 'false', {
path: gon.relative_url_root || '/',
expires: 365 * 10
});
$('.page-with-sidebar').toggleClass('page-sidebar-collapsed page-sidebar-expanded').removeClass('page-sidebar-pinned');
$('.navbar-fixed-top').removeClass('header-pinned-nav');
}
$document.off('click', '.js-nav-pin').on('click', '.js-nav-pin', function(e) {
var $page, $pinBtn, $tooltip, $topNav, doPinNav, tooltipText;
e.preventDefault();
$pinBtn = $(e.currentTarget);
$page = $('.page-with-sidebar');
$topNav = $('.navbar-fixed-top');
$tooltip = $("#" + ($pinBtn.attr('aria-describedby')));
doPinNav = !$page.is('.page-sidebar-pinned');
tooltipText = 'Pin navigation';
$(this).toggleClass('is-active');
if (doPinNav) {
$page.addClass('page-sidebar-pinned');
$topNav.addClass('header-pinned-nav');
} else {
$tooltip.remove();
$page.removeClass('page-sidebar-pinned').toggleClass('page-sidebar-collapsed page-sidebar-expanded');
$topNav.removeClass('header-pinned-nav').toggleClass('header-collapsed header-expanded');
}
$.cookie('pin_nav', doPinNav, {
path: gon.relative_url_root || '/',
expires: 365 * 10
});
if ($.cookie('pin_nav') === 'true' || doPinNav) {
tooltipText = 'Unpin navigation';
}
$tooltip.find('.tooltip-inner').text(tooltipText);
return $pinBtn.attr('title', tooltipText).tooltip('fixTitle');
});
// bind sidebar events
new gl.Sidebar();
// Custom time ago
gl.utils.shortTimeAgo($('.js-short-timeago'));
......
(function() {
var collapsed, expanded, toggleSidebar;
collapsed = 'page-sidebar-collapsed';
expanded = 'page-sidebar-expanded';
toggleSidebar = function() {
$('.page-with-sidebar').toggleClass(collapsed + " " + expanded);
$('.navbar-fixed-top').toggleClass("header-collapsed header-expanded");
if ($.cookie('pin_nav') === 'true') {
$('.navbar-fixed-top').toggleClass('header-pinned-nav');
$('.page-with-sidebar').toggleClass('page-sidebar-pinned');
}
return setTimeout((function() {
var niceScrollBars;
niceScrollBars = $('.nav-sidebar').niceScroll();
return niceScrollBars.updateScrollBar();
}), 300);
};
$(document).off('click', 'body').on('click', 'body', function(e) {
var $nav, $target, $toggle, pageExpanded;
if ($.cookie('pin_nav') !== 'true') {
$target = $(e.target);
$nav = $target.closest('.sidebar-wrapper');
pageExpanded = $('.page-with-sidebar').hasClass('page-sidebar-expanded');
$toggle = $target.closest('.toggle-nav-collapse, .side-nav-toggle');
if ($nav.length === 0 && pageExpanded && $toggle.length === 0) {
$('.page-with-sidebar').toggleClass('page-sidebar-collapsed page-sidebar-expanded');
return $('.navbar-fixed-top').toggleClass('header-collapsed header-expanded');
}
}
});
$(document).on("click", '.toggle-nav-collapse, .side-nav-toggle', function(e) {
e.preventDefault();
return toggleSidebar();
});
}).call(this);
((global) => {
let singleton;
const pinnedStateCookie = 'pin_nav';
const sidebarBreakpoint = 1024;
const pageSelector = '.page-with-sidebar';
const navbarSelector = '.navbar-fixed-top';
const sidebarWrapperSelector = '.sidebar-wrapper';
const sidebarContentSelector = '.nav-sidebar';
const pinnedToggleSelector = '.js-nav-pin';
const sidebarToggleSelector = '.toggle-nav-collapse, .side-nav-toggle';
const pinnedPageClass = 'page-sidebar-pinned';
const expandedPageClass = 'page-sidebar-expanded';
const collapsedPageClass = 'page-sidebar-collapsed';
const pinnedNavbarClass = 'header-pinned-nav';
const expandedNavbarClass = 'header-expanded';
const collapsedNavbarClass = 'header-collapsed';
class Sidebar {
constructor() {
if (!singleton) {
singleton = this;
singleton.init();
} else {
singleton.renderState();
}
return singleton;
}
init() {
this.isPinned = $.cookie(pinnedStateCookie) === 'true';
this.isExpanded = (
window.innerWidth >= sidebarBreakpoint &&
$(pageSelector).hasClass(expandedPageClass)
);
$(document)
.on('click', sidebarToggleSelector, () => this.toggleSidebar())
.on('click', pinnedToggleSelector, () => this.togglePinnedState())
.on('click', 'html, body', (e) => this.handleClickEvent(e));
this.renderState();
}
handleClickEvent(e) {
if (this.isExpanded && (!this.isPinned || window.innerWidth < sidebarBreakpoint)) {
const $target = $(e.target);
const targetIsToggle = $target.closest(sidebarToggleSelector).length > 0;
const targetIsSidebar = $target.closest(sidebarWrapperSelector).length > 0;
if (!targetIsToggle && (!targetIsSidebar || $target.closest('a'))) {
this.toggleSidebar();
}
}
}
toggleSidebar() {
this.isExpanded = !this.isExpanded;
this.renderState();
}
togglePinnedState() {
this.isPinned = !this.isPinned;
if (!this.isPinned) {
this.isExpanded = false;
}
$.cookie(pinnedStateCookie, this.isPinned ? 'true' : 'false', {
path: gon.relative_url_root || '/',
expires: 3650
});
this.renderState();
}
renderState() {
$(pageSelector)
.toggleClass(pinnedPageClass, this.isPinned && this.isExpanded)
.toggleClass(expandedPageClass, this.isExpanded)
.toggleClass(collapsedPageClass, !this.isExpanded);
$(navbarSelector)
.toggleClass(pinnedNavbarClass, this.isPinned && this.isExpanded)
.toggleClass(expandedNavbarClass, this.isExpanded)
.toggleClass(collapsedNavbarClass, !this.isExpanded);
const $pinnedToggle = $(pinnedToggleSelector);
const tooltipText = this.isPinned ? 'Unpin navigation' : 'Pin navigation';
const tooltipState = $pinnedToggle.attr('aria-describedby') && this.isExpanded ? 'show' : 'hide';
$pinnedToggle.attr('title', tooltipText).tooltip('fixTitle').tooltip(tooltipState);
if (this.isExpanded) {
setTimeout(() => $(sidebarContentSelector).niceScroll().updateScrollBar(), 200);
}
}
}
global.Sidebar = Sidebar;
})(window.gl || (window.gl = {}));
......@@ -128,10 +128,8 @@
.fa {
transition: transform .15s;
}
&.is-active {
.fa {
.page-sidebar-pinned & {
transform: rotate(90deg);
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment