Designed for user scripts
jMod was constructed with the sandbox’s security in mind. It will handle permission and scope errors for you without any additional headaches.
jMod is a new javascript library designed around the needs of user script authors. Lightweight and versatile, it comes packaged with tools that will cut your coding time in half!
jMod was constructed with the sandbox’s security in mind. It will handle permission and scope errors for you without any additional headaches.
Settings Modal, Notification Popups, and Loading Events are just a few of the features built into jMod that will boost your productivity and cut your time coding.
jMod uses a custom Bootstrap stylesheet fully namespaced with the class .jmod-na. Trimmed to its bare bones, loading is lightning fast and won’t cause any unintentional changes to the page.
jMod loads a namespaced version of Font Awesome.
Loading jMod is as simple as requiring it in your script. That’s it! Once loaded, jMod takes care of everything else.
jMod is 100% open source and freely accepts edits and feature updates.
To add jMod to any project, use the following example as a guide:
// ==UserScript==
// @name jMod Example Script
// @description Example script
// @author jgjake2
// @include http://test.com/change/me
// @require http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// @require http://code.jmod.info/0.0.19/jMod.min.js
// @version 0.1
// @grant unsafeWindow
// @grant GM_info
// @grant GM_log
// @grant GM_addStyle
// @grant GM_getMetadata
// @grant GM_xmlhttpRequest
// @grant GM_registerMenuCommand
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_listValues
// @grant GM_deleteValue
// @grant GM_getResourceText
// @grant GM_getResourceURL
// @unwrap
// @noframes
// @run-at document-start
// @jMod {"debug": true, "API": {"log": {"debug": true}}}
// ==/UserScript==
Only the @require line is necessary. However, the @jMod allows you to configure jMod as it initializes (rather than configuring it when your script begins) with a JSON string.
Additionally, it is recommended you include the following grants:
// @grant unsafeWindow
// @grant GM_info
// @grant GM_getMetadata
// @grant GM_xmlhttpRequest
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_listValues
// @grant GM_deleteValue
Without GM_info and GM_getMetadata, jMod wont be able to access your meta block and cant properly initialize.
jMod handles loading events for you. This is key when writing a script that executes at document-start since your script will execute before the DOM exists.
// Start DOM interactions
function onDOMReadyCB(){
console.log('onDOMReadyCB');
}
jMod.onDOMReady = onDOMReadyCB;
// jMod fully initialized
function onReadyCB(){
console.log('onReadyCB');
}
jMod.onReady = onReadyCB;
// Page is ready
function onPageReadyCB(){
console.log('onPageReadyCB');
}
jMod.onPageReady = onPageReadyCB;
// Page is loaded
function loadCB(){
console.log('loadCB');
}
jMod.load = loadCB;
/**
* The following four methods are all functionally equivalent:
*/
// Execute function when jMod is fully loaded and CSS is added
jMod.onReady = function(){
console.log('onReady');
}
jMod(function(){
console.log('onReady');
});
jMod('onReady', function(){
console.log('onReady');
});
jMod.Events.addListener('onReady', function(){
console.log('onReady');
}, true);
Adding CSS is simpler than ever with jMod. You dont have to worry about if the DOM exists or not; jMod takes care of that for you. Just use the following example:
// Import a style sheet
jMod.CSS = "@import url(//example.com/custom.css);"
// add custom css
jMod.CSS = ".class-name {color: #000000;}";
// add custom stylesheet link (does not wait for DOM to exist)
jMod.API.addStylesheet("http://example.com/custom2.css");
// add custom css (does not wait for DOM to exist)
jMod.API.addStyle(".class-name {color: #000000;}");
jMod.CSS will add your style to the current document immediately if the DOM exists. Otherwise it is added to the jMod CSS stack, which is added one the DOM is available.
jMod can generate a settings dialog for you! No need to write your own settings engine.
var SettingsTest = function(){
console.log('jMod.Settings Example');
var SettingOptions = {
title: 'Example Title',
settings: [
{
name: 'Setting 1',
description: 'Setting 1 description',
tooltip: {
innerHTML: 'Text input Top-Right Tooltip',
placement: 'top-right'
},
icon: {
name: 'fa-microphone',
tooltip: {
innerHTML: 'icon tooltip',
placement: 'right'
}
},
tab: 'Tab Name 1',
section: 'Other',
type: 'input',
'default': 'foo bar'
},
{
name: 'element example',
tab: 'Tab Name 1',
section: 'Other',
type: 'element',
innerHTML: [
'Element Example: ',
{
type: 'img',
attributes: {
src: "https://assets-cdn.github.com/images/modules/logos_page/GitHub-Logo.png",
height: "10px"
}
}
]
},
{
name: 'Toggle',
description: 'Toggle Test',
options: {
'val1': {
label: 'Toggle 1',
on: 'ON',
off: 'OFF',
tooltip: {
innerHTML: 'Toggle Tooltip 1',
placement: 'right'
}
},
'val2': {
label: 'Toggle 2',
on: 'ON',
off: 'OFF',
tooltip: {
innerHTML: 'Toggle Tooltip 2',
placement: 'right'
}
},
'val3': {
label: 'Toggle 3',
on: 'WIDE ON',
off: 'WIDE OFF',
className: 'wide',
tooltip: {
innerHTML: 'Toggle Tooltip 3',
placement: 'right'
}
},
'val4': {
label: 'Toggle 4',
on: 'EX WIDE ON',
off: 'EX WIDE OFF',
className: 'ex-wide',
tooltip: {
innerHTML: 'Toggle Tooltip 4',
placement: 'right'
}
}
},
tab: 'Tab Name 1',
section: 'Other',
type: 'toggle',
'default': 'val3,val4'
},
{
name: 'Setting 2',
tooltip: {
innerHTML: 'Select Left Tooltip',
placement: 'left'
},
tab: 'Tab Name 1',
section: 'Other',
type: 'select',
options: {
'val1': 'Option 1',
'val2': 'Option 2',
'val3': 'Option 3',
'val4': 'Option 4',
},
'default': 'val3'
},
{
name: 'Setting 3',
tooltip: {
innerHTML: 'Textarea Top Left Tooltip',
placement: 'left-top'
},
icon: {
name: 'fa-question-circle',
tooltip: {
innerHTML: 'Icon Tooltip for Textarea',
placement: 'right'
}
},
style: {
minHeight: '100px'
},
tab: 'Tab Name 1',
section: 'Other',
type: 'textarea',
'default': 'taco'
},
{
name: 'Checkboxes',
tab: 'Tab Name 1',
tooltip: {
innerHTML: 'Top Label Tooltip',
placement: 'top-left',
margin: {
//left: '5px'
}
},
section: 'Other2',
options: {
'val1': {
label: 'Checkbox 1',
tooltip: {
innerHTML: 'Checkbox Tooltip 1',
placement: 'top'
}
},
'val2': {
label: 'Checkbox 2',
tooltip: {
innerHTML: 'Checkbox Tooltip 2',
placement: 'top'
}
},
'val3': {
label: 'Checkbox 3',
className: 'wide',
tooltip: {
innerHTML: 'Checkbox Tooltip 3',
placement: 'top'
}
},
'val4': {
label: 'Checkbox 4',
className: 'ex-wide',
tooltip: {
innerHTML: 'Checkbox Tooltip 4',
placement: 'top'
}
}
},
type: 'checkbox',
'default': 'val1,val3'
},
{
name: 'Depend Checkbox',
description: 'Depend on Value of Checkboxes',
tab: 'Tab Name 1',
section: 'Other2',
type: 'input',
'default': 'Depend Checkbox',
depend: {
'Checkboxes': ['val1', 'val4']
}
},
{
name: 'Radio',
tab: 'Tab Name 1',
tooltip: {
innerHTML: 'Bottom Label Tooltip',
placement: 'bottom-left'
},
section: 'Other2',
options: {
'val1': {
label: 'Radio 1',
tooltip: {
innerHTML: 'Radio Tooltip 1',
placement: 'bottom'
}
},
'val2': {
label: 'Radio 2',
tooltip: {
innerHTML: 'Radio Tooltip 2',
placement: 'bottom'
}
},
'val3': {
label: 'Radio 3',
className: 'wide',
tooltip: {
innerHTML: 'Radio Tooltip 3',
placement: 'bottom'
}
},
'val4': {
label: 'Radio 4',
className: 'ex-wide',
tooltip: {
innerHTML: 'Radio Tooltip 4',
placement: 'bottom'
}
}
},
type: 'radio',
'default': 'val1'
},
{
name: 'Depend 1',
description: 'Depend on Value of Radio',
tab: 'Tab Name 1',
section: 'Other2',
type: 'input',
'default': 'Depend 1',
depend: {
'Radio': ['val2', 'val4']
}
},
{
name: 'Depend 2',
description: 'Depend on Value of Radio',
tab: 'Tab Name 1',
section: 'Other2',
type: 'input',
'default': 'Depend 2',
depend: {
'Radio': function(prefEl, data, radioValue){
if(radioValue == 'val1')
return true;
return false;
}
}
},
{
name: 'Range',
min: 20,
max: 567,
tooltip: {
innerHTML: 'Slider tooltip',
placement: 'top',
},
tab: 'Tab Name 1',
section: 'Other',
type: 'range',
'default': '50'
},
{
name: 'Setting 6',
tab: 'Tab Name 2',
section: 'Other',
type: 'input'
},
{
name: 'Setting 7',
tab: 'Tab Name 2',
section: 'Other',
type: 'input'
},
],
tabs: [
// (optional) Additional Custom tab
{
name: 'About',
innerHTML: [
{
type: 'h1',
innerHTML: 'About'
},
{
type: 'p',
innerHTML: 'about example'
}
]
},
// (optional) Adding information about a tab referenced by a setting
{
name: 'Tab Name 1',
displayName: 'Tab 1 displayName',
content: {
footer: {
type: 'div',
innerHTML: 'Tab 1 Footer foo bar'
}
}
}
],
// (optional) Change the order of the tabs. Tabs left out will be added after in the order they are referenced by your settings
tabOrder: ['About', 'Tab Name 1'],
// (optional) Set the active tab
activeTab: 'Tab Name 1',
// (optional) callback that fires before the settings dialog closes
onBeforeHide: function(e){
console.log('Settings on before hide');
}
};
jMod.Settings(SettingOptions);
setTimeout(function(){
// Show the settings dialog
console.log('Show jMod Settings');
jMod.Settings.show();
console.log('Setting 1 Value: ', jMod.Settings.get('Setting 1'));
console.log('Setting 1 Default: ', jMod.Settings.getDefault('Setting 1'));
},100);
};
jMod.onReady = SettingsTest;
This User Script Library is made by jgjake2 and is 100% FREE under the GNU General Public License Version 3 (GNU GPL v3)
If you want to show your support for jMod, you can buy me a beer or coffee via the PayPal donate button below. :)
Feel free to get in touch if you have any questions or suggestions.