// ==UserScript==
// @name Page Positioning Buttons
// @author Ziyu
// @namespace http://userscripts.org/users/ziyu
// @description Add links to go to top, bottom or a user specified position of each page.
// @include *
// @grant none
// @version End
// ==/UserScript==
// "Forked" from http://userscripts.org/scripts/show/105473
(function (document, window) {
'use strict';
// USER VARIABLES
var numberOfPositions = 3, // Sets the number of recording positions
bottomEdge = '40%', // Sets the bottom edge position in % of the page height
color = '#a8a8a8';
// Extend object a with object b's properties.
var extend = function (a, b) {
for (var key in b) {
if (b.hasOwnProperty(key)) {
a[key] = b[key];
}
}
return a;
};
var cssPropsCommon = {
cursor : 'pointer',
zIndex : '1000'
};
var cssPropsContainer = extend({
borderTop : '2px solid' + color,
borderBottom: '2px solid' + color,
width : '24px',
position : 'fixed',
right : '10px',
bottom : bottomEdge
}, cssPropsCommon);
var cssPropsTopButton = extend({
width : '0',
height : '0',
borderBottom: '12px solid' + color,
borderLeft : '12px solid transparent',
borderRight : '12px solid transparent'
}, cssPropsCommon);
var cssPropsBtmButton = extend({
transform : 'rotate(180deg)',
marginTop : '4px'
}, cssPropsTopButton);
var cssPropsRecButton = extend({
width : '12px',
height : '12px',
borderRadius: '50%',
background : color,
marginLeft : '6px',
marginTop : '4px'
}, cssPropsCommon);
var cssPropsRwdButton = extend({
width : '0',
height : '0',
borderRight : '12px solid' + color,
borderTop : '6px solid transparent',
borderBottom: '6px solid transparent',
marginLeft : '5px',
marginTop : '4px'
}, cssPropsCommon);
// HELPER FUNCTIONS
// pfx is a function that takes a standard CSS property name as a parameter
// and returns it's prefixed version valid for current browser it runs in.
// The code is heavily inspired by Modernizr http://www.modernizr.com/
var pfx = (function () {
var style = document.createElement('dummy').style,
prefixes = 'Webkit Moz O ms Khtml'.split(' '),
memory = {};
return function ( prop ) {
if ( typeof memory[ prop ] === "undefined" ) {
var ucProp = prop.charAt(0).toUpperCase() + prop.substr(1),
props = (prop + ' ' + prefixes.join(ucProp + ' ') + ucProp).split(' ');
memory[ prop ] = null;
for ( var i in props ) {
if ( style[ props[i] ] !== undefined ) {
memory[ prop ] = props[i];
break;
}
}
}
return memory[ prop ];
};
})();
// css function applies the styles given in `props` object to the element
// given as `el`. It runs all property names through `pfx` function to make
// sure proper prefixed version of the property is used.
// If rm is set to true, it removes the properties from the element.
var css = function ( el, props, rm ) {
var key, pkey;
for ( key in props ) {
if ( props.hasOwnProperty(key) ) {
pkey = pfx(key);
if ( pkey !== null ) {
el.style[pkey] = rm ? null : props[key];
}
}
}
return el;
};
// PAGE POSITIONING BUTTONS API
var createPositionButton = function () {
var position = 0,
isset = 0,
button = document.createElement('div');
var setPosition = function (yOffset) {
position = yOffset;
isset = 1;
return position;
};
var getPosition = function () {
return position;
};
var rewind = function () {
if(isset) {
window.scrollTo(0, position);
}
};
var record = function () {
setPosition(window.pageYOffset);
css(button, cssPropsRecButton, true);
css(button, cssPropsRwdButton);
button.removeEventListener('click', record, false);
button.addEventListener('click', rewind, false);
};
css(button, cssPropsRecButton);
button.addEventListener('click', record, false);
return {
button : button,
isset : isset,
getPosition : getPosition
};
};
var buttons = function () {
var intervalHandle = null,
container = document.createElement('div'),
positionButtonContainer = document.createElement('div');
var pageGoToTop = function () {
window.scrollTo(0, 0);
};
var pageGoToBottom = function () {
window.scrollTo(0, 999999);
};
var pageScrollUp = function () {
if (intervalHandle === null) {
intervalHandle = setInterval(function(){window.scrollBy(0,-3);}, 60);
}
};
var pageScrollDown = function () {
if (intervalHandle === null) {
intervalHandle = setInterval(function(){window.scrollBy(0,3);}, 60);
}
};
var stopScroll = function () {
clearInterval(intervalHandle);
intervalHandle = null;
};
var addPos = function () {
while (numberOfPositions--) {
positionButtonContainer.appendChild(createPositionButton().button);
}
};
var init = function () {
var topButton = document.createElement('div'),
btmButton = document.createElement('div');
css(container, cssPropsContainer);
css(topButton, cssPropsTopButton);
css(btmButton, cssPropsBtmButton);
topButton.addEventListener('click', pageGoToTop, false);
topButton.addEventListener('mouseover', pageScrollUp, false);
topButton.addEventListener('mouseout', stopScroll, false);
btmButton.addEventListener('click', pageGoToBottom, false);
btmButton.addEventListener('mouseover', pageScrollDown, false);
btmButton.addEventListener('mouseout', stopScroll, false);
container.appendChild(topButton);
container.appendChild(positionButtonContainer);
container.appendChild(btmButton);
document.body.appendChild(container);
addPos();
};
return {
container : container,
init : init
};
};
// START PAGE POSITIONING BUTTONS
if (window.top == window.self) { // if not iframe
var de = document.documentElement;
if(de.scrollHeight > de.clientHeight && document.body) {
buttons().init();
}
}
})(document, window);