Last active
May 2, 2024 02:45
-
-
Save jr-codes/4088609 to your computer and use it in GitHub Desktop.
u.js userscript
This file contains hidden or 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
| // ==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