Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2121 from tfennelly/JENKINS-33495
[JENKINS-33495 and JENKINS-33496] Separate scrollspy widget code out from tab widget code
- Loading branch information
Showing
24 changed files
with
1,041 additions
and
460 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
var $ = require('jquery-detached').getJQuery(); | ||
var page = require('./util/page.js'); | ||
var windowHandle = require('window-handle'); | ||
var isScrolling = false; | ||
var ignoreNextScrollEvent = false; | ||
var pageHeaderHeight = page.pageHeaderHeight(); | ||
var breadcrumbBarHeight = page.breadcrumbBarHeight(); | ||
|
||
// Some stuff useful for testing. | ||
exports.tabbars = []; | ||
exports.scrollspeed = 500; | ||
var eventListeners = []; | ||
exports.on = function(listener) { | ||
eventListeners.push(listener); | ||
}; | ||
function notify(event) { | ||
for (var i = 0; i < eventListeners.length; i++) { | ||
eventListeners[i](event); | ||
} | ||
} | ||
|
||
$(function() { | ||
var tabBarWidget = require('./widgets/config/tabbar.js'); | ||
|
||
tabBarWidget.addPageTabs('.config-table.scrollspy', function(tabBar) { | ||
exports.tabbars.push(tabBar); | ||
|
||
tabBarWidget.addFinderToggle(tabBar); | ||
tabBar.onShowSection(function() { | ||
// Scroll to the section. | ||
scrollTo(this, tabBar); | ||
// Hook back into hudson-behavior.js | ||
page.fireBottomStickerAdjustEvent(); | ||
}); | ||
|
||
autoActivateTabs(tabBar); | ||
page.onWinScroll(function () { | ||
autoActivateTabs(tabBar); | ||
}); | ||
page.onWinScroll(function () { | ||
stickTabbar(tabBar); | ||
}); | ||
}, {trackSectionVisibility: true}); | ||
}); | ||
|
||
function scrollTo(section, tabBar) { | ||
var $header = section.headerRow; | ||
var scrollTop = $header.offset().top - ($('#main-panel .jenkins-config-widgets').outerHeight() + 15); | ||
|
||
isScrolling = true; | ||
$('html,body').animate({ | ||
scrollTop: scrollTop | ||
}, exports.scrollspeed, function() { | ||
if (isScrolling) { | ||
notify({ | ||
type: 'click_scrollto', | ||
section: section | ||
}); | ||
isScrolling = false; | ||
ignoreNextScrollEvent = stickTabbar(tabBar); | ||
} | ||
}); | ||
} | ||
|
||
/** | ||
* Watch page scrolling, changing the active tab as needed. | ||
* @param tabBar The tabbar. | ||
*/ | ||
function autoActivateTabs(tabBar) { | ||
if (isScrolling === true) { | ||
// Ignore window scroll events while we are doing a scroll. | ||
// See scrollTo function. | ||
return; | ||
} | ||
if (ignoreNextScrollEvent === true) { | ||
// Things like repositioning of the tabbar (see stickTabbar) | ||
// can trigger scroll events that we want to ignore. | ||
ignoreNextScrollEvent = false; | ||
return; | ||
} | ||
|
||
var winScrollTop = page.winScrollTop(); | ||
var sections = tabBar.sections; | ||
|
||
// calculate the top and height of each section to know where to switch the tabs... | ||
$.each(sections, function (i, section) { | ||
if (!section.isVisible()) { | ||
return; | ||
} | ||
|
||
// each section enters the viewport at its distance down the page, less the height of | ||
// the toolbar, which hangs down the page. Or it is zero if the section doesn't | ||
// match or was removed... | ||
var viewportEntryOffset = section.getViewportEntryOffset(); | ||
// height of this one is the top of the next, less the top of this one. | ||
var sectionHeight = 0; | ||
var nextSection = nextVisibleSection(section); | ||
if (nextSection) { | ||
sectionHeight = nextSection.getViewportEntryOffset() - viewportEntryOffset; | ||
} | ||
|
||
// the trigger point to change the tab happens when the scroll position passes below the height of the section... | ||
// ...but we want to wait to advance the tab until the existing section is 75% off the top... | ||
// ### < 75% ADVANCED | ||
if (winScrollTop < (viewportEntryOffset + (0.75 * sectionHeight))) { | ||
section.markAsActive(); | ||
notify({ | ||
type: 'manual_scrollto', | ||
section: section | ||
}); | ||
return false; | ||
} | ||
}); | ||
} | ||
|
||
/** | ||
* Stick the scrollspy tabbar to the top of the visible area as the user | ||
* scrolls down the page. | ||
* @param tabBar The tabbar. | ||
*/ | ||
function stickTabbar(tabBar) { | ||
var win = $(windowHandle.getWindow()); | ||
var winScrollTop = page.winScrollTop(); | ||
var widgetBox = tabBar.configWidgets; | ||
var configTable = tabBar.configTable; | ||
var configForm = tabBar.configForm; | ||
var setWidth = function() { | ||
widgetBox.width(configForm.outerWidth() - 2); | ||
}; | ||
|
||
if (winScrollTop > pageHeaderHeight - 5) { | ||
setWidth(); | ||
widgetBox.css({ | ||
'position': 'fixed', | ||
'top': (breadcrumbBarHeight - 5 ) + 'px', | ||
'margin': '0 auto !important' | ||
}); | ||
configTable.css({'margin-top': widgetBox.outerHeight() + 'px'}); | ||
win.resize(setWidth); | ||
return true; | ||
} else { | ||
widgetBox.removeAttr('style'); | ||
configTable.removeAttr('style'); | ||
win.unbind('resize', setWidth); | ||
return false; | ||
} | ||
} | ||
|
||
function nextVisibleSection(section) { | ||
var next = section.getSibling(+1); | ||
while (next && !next.isVisible()) { | ||
next = next.getSibling(+1); | ||
} | ||
return next; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
@import "widgets/variables"; | ||
|
||
/* | ||
* Mixins | ||
* http://lesscss.org/features/#mixins-feature | ||
*/ | ||
@import "widgets/layout-mixins"; | ||
@import "widgets/form/form-mixins"; | ||
|
||
/* | ||
* Widget styles | ||
*/ | ||
@import "widgets/config/tabbar"; | ||
|
||
|
||
/* | ||
* ---------------------------------------------------------------------------------------- | ||
* Scrollspy specific styles. | ||
* ---------------------------------------------------------------------------------------- | ||
*/ | ||
|
||
.jenkins-config { | ||
// The Section header for the General section was manufactured, | ||
// so the default is to not display it. | ||
.section-header-row.config_general .section-header { | ||
display: none; | ||
} | ||
} | ||
|
||
.jenkins-config-widgets { | ||
.find-container { | ||
.find { | ||
display: none; | ||
} | ||
} | ||
} |
Oops, something went wrong.