Merge pull request #429 from thelounge/xpaw/scrollbar

Remove javascript scrollbar library, use hover appearing scrollbar instead
This commit is contained in:
Jérémie Astori 2016-07-02 20:46:49 -04:00 committed by GitHub
commit f21f901a69
5 changed files with 24 additions and 441 deletions

View File

@ -243,7 +243,8 @@ button {
#sidebar {
bottom: 52px;
left: 0;
overflow: hidden;
overflow: auto;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;
position: absolute;
top: 0;
@ -267,7 +268,6 @@ button {
}
#sidebar .networks {
min-height: 100%;
padding: 20px 30px 0;
}
@ -544,6 +544,10 @@ button {
width: 100%;
}
#user-specified-css-input {
resize: vertical;
}
#windows .input:hover,
#windows .input:focus {
border-color: #79838c;
@ -1014,10 +1018,6 @@ button {
padding: 0 16px;
}
#chat .names .inner {
width: 300px;
}
#chat .user-mode:before {
content: "";
border-bottom: 1px solid #eee;
@ -1552,64 +1552,6 @@ button {
font-style: italic;
}
/**
* TrackpadScrollEmulator
* Version: 1.0.6
* Author: Jonathan Nicol @f6design
* https://github.com/jnicol/trackpad-scroll-emulator
*/
.tse-scrollable {
position: relative;
overflow: hidden;
}
.tse-scrollable .tse-scroll-content {
overflow: hidden;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
.tse-scrollable .tse-scroll-content::-webkit-scrollbar {
width: 0;
height: 0;
}
.tse-scrollbar {
z-index: 99;
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 11px;
}
.tse-scrollbar .drag-handle {
position: absolute;
right: 2px;
border-radius: 2px;
min-height: 10px;
width: 6px;
opacity: .1;
transition: opacity .2s linear;
background: #000;
-webkit-background-clip: padding-box;
-moz-background-clip: padding;
}
.tse-scrollbar:hover .drag-handle {
opacity: .25;
transition: opacity 0 linear;
}
.tse-scrollbar .drag-handle.visible {
opacity: .2;
}
.scrollbar-width-tester::-webkit-scrollbar {
width: 0;
height: 0;
}
@media (max-width: 768px) {
.container {
margin-top: 60px !important;
@ -1714,3 +1656,7 @@ button {
background: rgba(0, 0, 0, .5);
border-radius: 100px;
}
::-webkit-scrollbar-thumb:vertical:active {
background: rgba(0, 0, 0, .6);
}

View File

@ -27,12 +27,10 @@
<div id="wrap">
<div id="viewport">
<aside id="sidebar" class="tse-scrollable">
<div class="tse-content">
<div class="networks"></div>
<div class="empty">
You're not connected to any networks yet.
</div>
<aside id="sidebar">
<div class="networks"></div>
<div class="empty">
You're not connected to any networks yet.
</div>
</aside>
<footer id="footer">

View File

@ -1,357 +0,0 @@
/**
* TrackpadScrollEmulator
* Version: 1.0.6
* Author: Jonathan Nicol @f6design
* https://github.com/jnicol/trackpad-scroll-emulator
*
* The MIT License
*
* Copyright (c) 2012-2014 Jonathan Nicol
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
;(function($) {
var pluginName = 'TrackpadScrollEmulator';
function Plugin(element, options) {
var el = element;
var $el = $(element);
var $scrollContentEl;
var $contentEl = $el.find('.tse-content');
var $scrollbarEl;
var $dragHandleEl;
var dragOffset;
var flashTimeout;
var pageJumpMultp = 7/8;
var scrollDirection = 'vert';
var scrollOffsetAttr = 'scrollTop';
var sizeAttr = 'height';
var offsetAttr = 'top';
options = $.extend({}, $.fn[pluginName].defaults, options);
/**
* Initialize plugin
*/
function init() {
if ($el.hasClass('horizontal')){
scrollDirection = 'horiz';
scrollOffsetAttr = 'scrollLeft';
sizeAttr = 'width';
offsetAttr = 'left';
}
$el.prepend('<div class="tse-scrollbar"><div class="drag-handle"></div></div>');
$scrollbarEl = $el.find('.tse-scrollbar');
$dragHandleEl = $el.find('.drag-handle');
if (options.wrapContent) {
$contentEl.wrap('<div class="tse-scroll-content" />');
}
$scrollContentEl = $el.find('.tse-scroll-content');
resizeScrollContent();
if (options.autoHide) {
$el.on('mouseenter', flashScrollbar);
}
$dragHandleEl.on('mousedown', startDrag);
$scrollbarEl.on('mousedown', jumpScroll);
$scrollContentEl.on('scroll', onScrolled);
resizeScrollbar();
$(window).on('resize', function() {
recalculate();
});
if (!options.autoHide) {
showScrollbar();
}
}
/**
* Start scrollbar handle drag
*/
function startDrag(e) {
// Preventing the event's default action stops text being
// selectable during the drag.
e.preventDefault();
var self = $(this);
self.trigger('startDrag');
// Measure how far the user's mouse is from the top of the scrollbar drag handle.
var eventOffset = e.pageY;
if (scrollDirection === 'horiz') {
eventOffset = e.pageX;
}
dragOffset = eventOffset - $dragHandleEl.offset()[offsetAttr];
$(document).on('mousemove', drag);
$(document).on('mouseup', function() {
endDrag.call(self);
});
}
/**
* Drag scrollbar handle
*/
function drag(e) {
e.preventDefault();
// Calculate how far the user's mouse is from the top/left of the scrollbar (minus the dragOffset).
var eventOffset = e.pageY;
if (scrollDirection === 'horiz') {
eventOffset = e.pageX;
}
var dragPos = eventOffset - $scrollbarEl.offset()[offsetAttr] - dragOffset;
// Convert the mouse position into a percentage of the scrollbar height/width.
var dragPerc = dragPos / $scrollbarEl[sizeAttr]();
// Scroll the content by the same percentage.
var scrollPos = dragPerc * $contentEl[sizeAttr]();
$scrollContentEl[scrollOffsetAttr](scrollPos);
}
/**
* End scroll handle drag
*/
function endDrag() {
$(this).trigger('endDrag');
$(document).off('mousemove', drag);
$(document).off('mouseup', endDrag);
}
/**
* Scroll in the same manner as the PAGE UP/DOWN keys
*/
function jumpScroll(e) {
// If the drag handle element was pressed, don't do anything here.
if (e.target === $dragHandleEl[0]) {
return;
}
// The content will scroll by 7/8 of a page.
var jumpAmt = pageJumpMultp * $scrollContentEl[sizeAttr]();
// Calculate where along the scrollbar the user clicked.
var eventOffset = (scrollDirection === 'vert') ? e.originalEvent.layerY : e.originalEvent.layerX;
// Get the position of the top (or left) of the drag handle.
var dragHandleOffset = $dragHandleEl.position()[offsetAttr];
// Determine which direction to scroll.
var scrollPos = (eventOffset < dragHandleOffset) ? $scrollContentEl[scrollOffsetAttr]() - jumpAmt : $scrollContentEl[scrollOffsetAttr]() + jumpAmt;
$scrollContentEl[scrollOffsetAttr](scrollPos);
}
/**
* Scroll callback
*/
function onScrolled(e) {
flashScrollbar();
}
/**
* Resize scrollbar
*/
function resizeScrollbar() {
var contentSize = $contentEl[sizeAttr]();
var scrollOffset = $scrollContentEl[scrollOffsetAttr](); // Either scrollTop() or scrollLeft().
var scrollbarSize = $scrollbarEl[sizeAttr]();
var scrollbarRatio = scrollbarSize / contentSize;
// Calculate new height/position of drag handle.
// Offset of 2px allows for a small top/bottom or left/right margin around handle.
var handleOffset = Math.round(scrollbarRatio * scrollOffset) + 2;
var handleSize = Math.floor(scrollbarRatio * (scrollbarSize - 2)) - 2;
if (scrollbarSize < contentSize) {
if (scrollDirection === 'vert'){
$dragHandleEl.css({'top': handleOffset, 'height': handleSize});
} else {
$dragHandleEl.css({'left': handleOffset, 'width': handleSize});
}
$scrollbarEl.show();
} else {
$scrollbarEl.hide();
}
}
/**
* Flash scrollbar visibility
*/
function flashScrollbar() {
resizeScrollbar();
showScrollbar();
}
/**
* Show scrollbar
*/
function showScrollbar() {
$dragHandleEl.addClass('visible');
if (!options.autoHide) {
return;
}
if(typeof flashTimeout === 'number') {
window.clearTimeout(flashTimeout);
}
flashTimeout = window.setTimeout(function() {
hideScrollbar();
}, 1000);
}
/**
* Hide Scrollbar
*/
function hideScrollbar() {
$dragHandleEl.removeClass('visible');
if(typeof flashTimeout === 'number') {
window.clearTimeout(flashTimeout);
}
}
/**
* Resize content element
*/
function resizeScrollContent() {
if (scrollDirection === 'vert'){
$scrollContentEl.width($el.width()+scrollbarWidth());
$scrollContentEl.height($el.height());
} else {
$scrollContentEl.width($el.width());
$scrollContentEl.height($el.height()+scrollbarWidth());
$contentEl.height($el.height());
}
}
/**
* Calculate scrollbar width
*
* Original function by Jonathan Sharp:
* http://jdsharp.us/jQuery/minute/calculate-scrollbar-width.php
* Updated to work in Chrome v25.
*/
function scrollbarWidth() {
// Append a temporary scrolling element to the DOM, then measure
// the difference between between its outer and inner elements.
var tempEl = $('<div class="scrollbar-width-tester" style="width:50px;height:50px;overflow-y:scroll;position:absolute;top:-200px;left:-200px;"><div style="height:100px;"></div>');
$('body').append(tempEl);
var width = $(tempEl).innerWidth();
var widthMinusScrollbars = $('div', tempEl).innerWidth();
tempEl.remove();
// On OS X if the scrollbar is set to auto hide it will have zero width. On webkit we can still
// hide it using ::-webkit-scrollbar { width:0; height:0; } but there is no moz equivalent. So we're
// forced to sniff Firefox and return a hard-coded scrollbar width. I know, I know...
if (width === widthMinusScrollbars && navigator.userAgent.toLowerCase().indexOf('firefox') > -1) {
return 17;
}
return (width - widthMinusScrollbars);
}
/**
* Recalculate scrollbar
*/
function recalculate() {
resizeScrollContent();
resizeScrollbar();
}
/**
* Get/Set plugin option.
*/
function option (key, val) {
if (val) {
options[key] = val;
} else {
return options[key];
}
}
/**
* Destroy plugin.
*/
function destroy() {
// Restore the element to its original state.
$contentEl.insertBefore($scrollbarEl);
$scrollbarEl.remove();
$scrollContentEl.remove();
$contentEl.css({'height': $el.height()+'px', 'overflow-y': 'scroll'});
hook('onDestroy');
$el.removeData('plugin_' + pluginName);
}
/**
* Plugin callback hook.
*/
function hook(hookName) {
if (options[hookName] !== undefined) {
options[hookName].call(el);
}
}
init();
return {
option: option,
destroy: destroy,
recalculate: recalculate
};
}
$.fn[pluginName] = function(options) {
if (typeof arguments[0] === 'string') {
var methodName = arguments[0];
var args = Array.prototype.slice.call(arguments, 1);
var returnVal;
this.each(function() {
if ($.data(this, 'plugin_' + pluginName) && typeof $.data(this, 'plugin_' + pluginName)[methodName] === 'function') {
returnVal = $.data(this, 'plugin_' + pluginName)[methodName].apply(this, args);
} else {
throw new Error('Method ' + methodName + ' does not exist on jQuery.' + pluginName);
}
});
if (returnVal !== undefined){
return returnVal;
} else {
return this;
}
} else if (typeof options === "object" || !options) {
return this.each(function() {
if (!$.data(this, 'plugin_' + pluginName)) {
$.data(this, 'plugin_' + pluginName, new Plugin(this, options));
}
});
}
};
$.fn[pluginName].defaults = {
onInit: function() {},
onDestroy: function() {},
wrapContent: true,
autoHide: true
};
})(jQuery);

View File

@ -48,8 +48,6 @@ $(function() {
pop.play();
});
$(".tse-scrollable").TrackpadScrollEmulator();
var favicon = $("#favicon");
function render(name, data) {

View File

@ -4,17 +4,15 @@
</div>
{{/if}}
<div class="names">
<div class="inner">
{{#diff "reset"}}{{/diff}}
{{#each users}}
{{#diff mode}}
{{#unless @first}}
</div>
{{/unless}}
<div class="user-mode {{modes mode}}">
{{/diff}}
<span role="button" class="user {{colorClass name}}" data-name="{{name}}">{{mode}}{{name}}</span>
{{/each}}
</div>
{{#diff "reset"}}{{/diff}}
{{#each users}}
{{#diff mode}}
{{#unless @first}}
</div>
{{/unless}}
<div class="user-mode {{modes mode}}">
{{/diff}}
<span role="button" class="user {{colorClass name}}" data-name="{{name}}">{{mode}}{{name}}</span>
{{/each}}
</div>
</div>