Skip to content

Instantly share code, notes, and snippets.

@jr-codes
Last active May 2, 2024 02:45
Show Gist options
  • Select an option

  • Save jr-codes/4088609 to your computer and use it in GitHub Desktop.

Select an option

Save jr-codes/4088609 to your computer and use it in GitHub Desktop.
u.js userscript
// ==UserScript==
// @name u.js (embedded)
// @namespace http://zarjay.net/
// @description Utility functions for browser console ninjas
// @include *
// @version 0.14
// ==/UserScript==
function exec(fn) {
var script = document.createElement('script');
script.textContent = '(' + fn + ')();';
document.head.appendChild(script);
}
exec(function() {
// Key used for localStorage
var GLOBAL_KEY = '_u.js',
DOMAIN_KEY = GLOBAL_KEY + ':' + location.hostname;
PAGE_KEY = DOMAIN_KEY + location.pathname,
QUERY_KEY = PAGE_KEY + location.search,
HASH_KEY = QUERY_KEY + location.hash,
USER_KEY = GLOBAL_KEY + ':user:';
var scopeKeys = {
global: GLOBAL_KEY,
domain: DOMAIN_KEY,
page: PAGE_KEY,
query: QUERY_KEY,
hash: HASH_KEY
};
// Libraries for easy including with u.lib();
var LIBS = {
datejs: {
css: [],
js: ['//cdnjs.cloudflare.com/ajax/libs/datejs/1.0/date.min.js']
},
design: {
css: [],
js: ['http://www.sprymedia.co.uk/design/design/media/js/design-loader.js']
},
'dom-monster': {
css: [],
js: ['//mir.aculo.us/dom-monster/dommonster.js']
},
jquery: {
css: [],
js: ['//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js']
},
'jquery-ui': {
css: ['//ajax.googleapis.com/ajax/libs/jqueryui/1/themes/base/jquery-ui.css'],
js: ['//ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js']
},
kickass: {
css: [],
js: ['//hi.kickassapp.com/kickass.js']
},
raphael: {
css: [],
js: ['//cdnjs.cloudflare.com/ajax/libs/raphael/2.0.1/raphael-min.js']
},
underscore: {
css: [],
js: ['//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.2/underscore-min.js']
}
};
var u = {};
u._namespace = 'zarjay.net';
function loadu(u, names) {
var loaded = false;
for (var i = 0; !loaded && i < names.length; ++i) {
var name = names[i];
if (window[name] && window[name]._namespace !== u._namespace) {
console.warn('u: "' + name + '" is taken.');
} else {
window[name] = u;
console.log('u.js is loaded: ' + name);
loaded = true;
}
}
if (!loaded) console.warn('u: u.js not loaded due to naming collisions.');
}
loadu(u, ['u', 'ujs', 'ujslib', 'zarjay_u']);
// u.uload(fn) - Sets a function to run when u.js loads
// u.uload() - Runs the function previously set
// u.uload(null) - Clears the function previously set
u.uload = function(scope, fn) {
var scopeKey = scopeKeys[scope];
if (typeof fn === 'function') {
localStorage[scopeKey] = JSON.stringify(fn.toString());
} else if (fn === null) {
localStorage.removeItem(scopeKey);
} else if (arguments.length === 0) {
this.uload('domain');
this.uload('page');
this.uload('query');
this.uload('hash');
} else if (arguments.length === 1) {
fn = localStorage[scopeKey];
if (fn) fn = JSON.parse(fn);
this.exec(fn);
}
};
// Sets an item in localStorage
u.set = function(key, value) {
if (typeof value === 'function') value = value.toString();
localStorage[USER_KEY + key] = JSON.stringify(value);
};
// Gets an item in localStorage
u.get = function(key) {
var value = localStorage[USER_KEY + key];
// Return immediately if undefined
if (typeof value === 'undefined' || value === 'undefined') return value;
value = JSON.parse(value);
// Check for function string and convert to function
if (value.indexOf && value.indexOf('function') === 0) value = eval('(' + value + ')');
return value;
};
// Clears localStorage items that were set with u.js
u.clear = function() {
Object.keys(localStorage).forEach(function(key) {
if (key.indexOf(USER_KEY) === 0) localStorage.removeItem(key);
});
};
// Code utilities
// Executes a function
u.exec = function(fn) {
if (!fn) return;
var script = document.createElement('script');
script.textContent = '(' + fn + ')();';
document.head.appendChild(script);
};
// Includes a JS or CSS file onto the page
u.include = function(url, type) {
if (!url) return;
// If type is empty, determine type via file extension
type = (type || url.split('.').pop()).toLowerCase();
if (type === 'css') {
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = url;
// Add <link> to <head>
document.head.appendChild(link);
console.log('Loaded ' + url);
} else if (type === 'js') {
var script = document.createElement('script');
script.src = url;
// Make sure scripts run in the order in which they're included.
script.async = false;
// Add <script> to <head>
document.head.appendChild(script);
console.log('Loaded ' + url);
} else {
throw new Error('u: Failed to include ' + url + ' due to unknown file type.');
}
};
// Includes one or more libraries onto the page
u.lib = function(/* libs */) {
var numArgs = arguments.length;
// If no params, return list of available libraries
if (numArgs === 0) return Object.keys(LIBS);
// Import CSS/JS files from each lib parameter
for (var i = 0; i < numArgs; ++i) {
var lib = LIBS[arguments[i]];
if (lib) {
for (var j = 0; j < lib.css.length; ++j) this.include(lib.css[j], 'css');
for (var k = 0; k < lib.js.length; ++k) this.include(lib.js[k], 'js');
}
}
},
u.slice = Function.prototype.call.bind(Array.prototype.slice);
// DOM queries
// Shortcut for document.querySelector()
u.query = function(selector) {
return document.querySelector(selector);
},
// Shortcut for document.querySelectorAll() + converts result to an array
u.queryAll = function(selector) {
return u.slice(document.querySelectorAll(selector));
},
// Shortcut for u.queryAll(selector).forEach(fn)
u.each = function(selector, fn) {
this.queryAll(selector).forEach(fn);
};
// Calculations
u.accumulate = function(selector, filter, map, reduce) {
return this.queryAll(selector).filter(filter).map(map).reduce(reduce);
},
// Adds together numbers from given selector.
// Optionally massage the data by passing in filter and map functions.
u.sum = function(selector, filter, map) {
filter = filter || function() { return true; };
map = map || function(elem) { return +elem.textContent.replace(/[$,%]/g, ''); };
var sum = function(a, b) { return a + b; };
return this.accumulate(selector, filter, map, sum);
},
u.start = function(name) {
console.time(name || 'u');
};
u.stop = function(name) {
console.timeEnd(name || 'u');
};
// Modifications
// Makes everything editable.
u.edit = function() {
document.body.contentEditable = 'true';
document.designMode = 'on';
},
// string.replace() on selector (or body if no selector is given)
u.replace = function(/* [selector], regex, newStr */) {
if (arguments.length === 2) return this.replace('body', arguments[0], arguments[1]);
if (arguments.length !== 3) return console.log('u: replace([selector], regex, newStr');
var selector = arguments[0],
regex = arguments[1],
newStr = arguments[2];
if (!(regex instanceof RegExp)) regex = new RegExp(regex,'g');
u.each(selector, function(elem) {
elem.innerHTML = elem.innerHTML.replace(regex, newStr);
});
};
function insertAdjacentHTML(args, position, message) {
if (args.length === 1) {
args.unshift('body');
return insertAdjacentHTML(args, position, message);
}
if (args.length !== 2 || typeof args[1] === 'undefined') {
return console.log(message);
}
var selector = args[0],
html = args[1];
u.each(selector, function(elem) {
elem.insertAdjacentHTML(position, html);
});
}
// Add HTML as a last child of node
u.append = function(/* [selector], html */) {
return insertAdjacentHTML(u.slice(arguments), 'beforeend', 'u: append([selector], html)');
};
// Add HTML as a first child of node
u.prepend = function(/* [selector], html */) {
return insertAdjacentHTML(u.slice(arguments), 'afterbegin', 'u: prepend([selector], html)');
};
// Add HTML before node
u.before = function(selector, html) {
return insertAdjacentHTML([selector, html], 'beforebegin', 'u: before(selector, html)');
};
// Add HTML after node
u.after = function(selector, html) {
return insertAdjacentHTML([selector, html], 'afterend', 'u: after(selector, html');
};
/* Style */
function rotate(args, property, message) {
if (args.length === 1 || args.length === 2 && typeof args[0] === 'number') {
args.unshift('body');
return rotate(args, property, message);
}
if (args.length === 2 && typeof args[0] !== 'number') {
args.push(3);
return rotate(args, property, message);
}
if (args.length !== 3) {
return console.log(message);
}
var selector = args[0],
angle = args[1],
speed = args[2];
u.each(selector, function(elem) {
elem.style.webkitTransition = speed + 's' + ' -webkit-transform ease';
elem.style.transition = speed + 's' + ' transform ease';
var rotateString = property + '(' + angle + 'deg' + ')';
elem.style.webkitTransform = rotateString;
elem.style.transform = rotateString;
});
}
// 2D rotation
// selector - optional CSS selector
// angle - angle in degrees
// speed in seconds
u.rotate = function() {
return rotate(u.slice(arguments), 'rotate', 'u: rotate([selector], angle, [speed])');
};
// 3D rotation on x-axis
// selector - optional CSS selector
// angle - angle in degrees
// speed in seconds
u.rotateX = function() {
return rotate(u.slice(arguments), 'rotateX', 'u: rotateX([selector], angle, [speed])');
};
// 3D rotation on y-axis
// selector - optional CSS selector
// angle - angle in degrees
// speed in seconds
u.rotateY = function() {
return rotate(u.slice(arguments), 'rotateY', 'u: rotateY([selector], angle, [speed])');
};
// 3D rotation on z-axis
// selector - optional CSS selector
// angle - angle in degrees
// speed in seconds
u.rotateZ = function() {
return rotate(u.slice(arguments), 'rotateZ', 'u: rotateZ([selector], angle, [speed])');
};
// // Rotates the selected element
// // angle - angle in degrees
// // speed - speed in seconds
// u.rotateY = function(/* [selector], angle, [speed] */) {
// if (arguments.length === 1) return this.rotateY('body', arguments[0]);
// if (arguments.length === 2 && typeof arguments[0] === 'number') return this.rotateY('body', arguments[0], arguments[1]);
// if (arguments.length === 2 && typeof arguments[0] !== 'number') return this.rotateY(arguments[0], arguments[1], 3);
// if (arguments.length !== 3) return console.log('u: rotateY([selector], angle, speed)');
// var selector = arguments[0],
// angle = arguments[1],
// speed = arguments[2];
// u.each(selector, function(elem) {
// elem.style.webkitTransition = speed + 's' + ' -webkit-transform ease';
// elem.style.transition = speed + 's' + ' transform ease';
// var rotateString = 'rotateY(' + angle + 'deg)';
// elem.style.webkitTransform = rotateString;
// elem.style.transform = rotateString;
// });
// };
// // Rotates the selected element
// // angle - angle in degrees
// // speed - speed in seconds
// u.rotateZ = function(/* [selector], angle, [speed] */) {
// if (arguments.length === 1) return this.rotateZ('body', arguments[0]);
// if (arguments.length === 2 && typeof arguments[0] === 'number') return this.rotateZ('body', arguments[0], arguments[1]);
// if (arguments.length === 2 && typeof arguments[0] !== 'number') return this.rotateZ(arguments[0], arguments[1], 3);
// if (arguments.length !== 3) return console.log('u: rotateZ([selector], angle, speed)');
// var selector = arguments[0],
// angle = arguments[1],
// speed = arguments[2];
// u.each(selector, function(elem) {
// elem.style.webkitTransition = speed + 's' + ' -webkit-transform ease';
// elem.style.transition = speed + 's' + ' transform ease';
// var rotateString = 'rotateZ(' + angle + 'deg)';
// elem.style.webkitTransform = rotateString;
// elem.style.transform = rotateString;
// });
// };
// // Rotates the selected element
// // angle - angle in degrees
// // speed - speed in seconds
// u.rotate = function(/* [selector], angle, [speed] */) {
// if (arguments.length === 1) return this.rotate('body', arguments[0]);
// if (arguments.length === 2 && typeof arguments[0] === 'number') return this.rotate('body', arguments[0], arguments[1]);
// if (arguments.length === 2 && typeof arguments[0] !== 'number') return this.rotate(arguments[0], arguments[1], 3);
// if (arguments.length !== 3) return console.log('u: rotate([selector], angle, speed)');
// var selector = arguments[0],
// angle = arguments[1],
// speed = arguments[2];
// u.each(selector, function(elem) {
// elem.style.webkitTransition = speed + 's' + ' -webkit-transform ease';
// elem.style.transition = speed + 's' + ' transform ease';
// var rotateString = 'rotate(' + angle + 'deg)';
// elem.style.webkitTransform = rotateString;
// elem.style.transform = rotateString;
// });
// };
// Adds display:none
u.hide = function(selector) {
selector = selector || 'body';
u.each(selector, function(elem) {
elem.style.display = 'none';
});
};
// Removes display property
u.show = function(selector) {
selector = selector || 'body';
u.each(selector, function(elem) {
elem.style.display = '';
});
};
// Adds visibility:hidden;
u.disappear = function(selector) {
selector = selector || 'body';
u.each(selector, function(elem) {
elem.style.visibility = 'hidden';
});
};
// Removes visbility property
u.appear = function(selector) {
selector = selector || 'body';
u.each(selector, function(elem) {
elem.style.visibility = '';
});
};
u.uload();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment