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.9 | |
| // ==/UserScript== | |
| function exec(fn) { | |
| var script = document.createElement('script'); | |
| script.textContent = '(' + fn + ')();'; | |
| document.head.appendChild(script); | |
| } | |
| exec(function() { | |
| // Key used for localStorage | |
| var KEY = '_u.js' + location.pathname; | |
| var USER_KEY = KEY + ':user:'; | |
| // 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(fn) { | |
| if (typeof fn === 'function') { | |
| localStorage[KEY] = JSON.stringify(fn.toString()); | |
| } | |
| if (typeof fn === 'undefined') { | |
| fn = localStorage[KEY]; | |
| if (fn) fn = JSON.parse(fn); | |
| this.exec(fn); | |
| } | |
| if (fn === null) { | |
| localStorage.removeItem(KEY); | |
| } | |
| }; | |
| // 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; | |
| }; | |
| // 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'); | |
| } | |
| } | |
| }, | |
| // 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 Array.prototype.slice.call(document.querySelectorAll(selector)); | |
| }, | |
| // 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 */) { | |
| var numArgs = arguments.length, | |
| selector = 'body', | |
| regex, | |
| newStr; | |
| switch(numArgs) { | |
| case 3: | |
| selector = arguments[0]; | |
| regex = arguments[1]; | |
| newStr = arguments[2]; | |
| break; | |
| case 2: | |
| regex = arguments[0]; | |
| newStr = arguments[1]; | |
| break; | |
| default: | |
| console.log('u: Use 2 parameters (regex, newStr) or 3 (selector, regex, newStr)'); | |
| return; | |
| } | |
| if (!(regex instanceof RegExp)) regex = new RegExp(regex,'g'); | |
| var elems = this.queryAll(selector); | |
| elems.forEach(function(elem) { | |
| elem.innerHTML = elem.innerHTML.replace(regex, newStr); | |
| }); | |
| }; | |
| // TODO: Consider converting numArg stuff into an extends() method. | |
| // TODO: Let append() and replace() share the same queryAll/forEach code. | |
| // TODO: Consider adding prepend(); look at insertAdjacentHTML's options | |
| u.append = function(/* [selector], html */) { | |
| var numArgs = arguments.length, | |
| selector = 'body', | |
| html; | |
| switch(numArgs) { | |
| case 2: | |
| selector = arguments[0]; | |
| html = arguments[1]; | |
| break; | |
| case 1: | |
| html = arguments[0]; | |
| break; | |
| default: | |
| console.log('u: Use 2 parameters (selector, html) or 1 (html)'); | |
| return; | |
| } | |
| var elems = this.queryAll(selector); | |
| elems.forEach(function(elem) { | |
| elem.insertAdjacentHTML('beforeend', html); | |
| }); | |
| }; | |
| u.uload(); | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment