Setup
-
Setup Meta Block
-
When loading jMod via "
@require
", your meta block should look something like this:// ==UserScript== // @name script_name // @namespace http://downloadurl.com/user/user_name // @description script description // @author user_name // @downloadURL http://downloadurl.com/script/script_name.user.js // @updateURL http://downloadurl.com/script/script_name.meta.js // @homepage http://downloadurl.com/script/script_name // @include http://includeurl.com/* // @require http://myuserjs.org/API/0.0.16/jMod.js // @version 0.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 // @unwrap // @noframes // @run-at document-start // @jMod {"API": {"log": {"debug": true}}} // ==/UserScript==
The only line required is:
However, it is highly encouraged that you consider following:// @require http://myuserjs.org/API/0.0.16/jMod.js
Grants
Name Description GM_info
GM_getMetadata
(for scriptish)Allows jMod to access your script info, which automates its initialization. unsafeWindow
Allows jMod to access the unsafeWindow. Without this, jMod can run into some scope and permission issues. GM_xmlhttpRequest
Allows jMod.SendMessage to access remote information from any domain. Very helpful when checking for updates. GM_addStyle
Allows jMod.API.addStyle to add CSS far faster than any other method. GM_getValue
GM_setValue
GM_listValues
GM_deleteValue
Allows jMod to use GM storage options instead of localStorage. This is important if your userscript runs on multiple domains since localStorage settings are specific to a single domain. Script Information
Name Description downloadURL
jModdownloadURL
Allows jMod to find out your true myUserJS script name and username. If you are using a site like greasyfork.org that rewrites your downloadURL, add jModdownloadURLto your meta block to ensure jMod can properly parse your download URL. updateURL
jModupdateURL
Similar to downloadURL except the URL is also parsed for the update type via its extension (meta.js, metajs.js or data.js). jModscriptname
(orjMod_script_name
)jModusername
(orjMod_username
)You can also set your myUserJS script name and username by using these keys in your meta block. You can manually set these values later when your script executes, but using your meta block is the preferred method. Other
Name Description run-at
jMod is designed to run at any time, even at start. This can be an issue for some scripts considering it will then execute before the DOM exists. However, jMod has several features to assist script authors with this problem.
see Standard Events below.jMod
This can be set to a valid JSON string, to be parsed as soon as jMod initializes. The value is processed before any changes are made to the document. Thus, if notifications or tooltips were disabled, their initializers would not execute and no document changes would be made. -
Setup Script Tag
-
When loading jMod by adding a script tag to the document, you can use the following methods to initialize your configuration:
<script> jMOD_CONFIGURATION = { API: { Storage: { engine: 'localStorage' } }, }; </script> <script src="http://myuserjs.org/API/0.0.16/jMod.js" data-username="myUserName" data-script_name="myScriptName" Update.DOMTiming="true" data-jmod-config='{"API": {"log": {"debug": true}}}'></script>
Once again, not all of this is necessary; only the following is required to load jMod:
<script src="http://myuserjs.org/API/0.0.16/jMod.js"></script>
Attributes
You can set individual configuration values via attributes using the following format:
Update.DOMTiming="true"
,Update-DOMTiming="true"
,data-Update-DOMTiming="true"
Additionally, you can pass a JSON formatted string to the attribute
data-jmod-config
. If valid, it will be merged with thejMod.Config
object.Configuration Variable
Alternatively, you can initialize your configuration with a global variable named
jMOD_CONFIGURATION
. If valid, it will be merged with thejMod.Config
object. -
Usage Standard Events
-
jMod is, by design, meant to be used by userscripts without the need for additional resources (like jQuery). So jMod handles several events for you, like waiting for the DOM to be available
Any function can be added to the event stack using the following syntax:// 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;
orjMod.EVENT_NAME = function(e){};
fireRecorded - Some events (like onDOMReady) record the most recent firing. If fireRecorded is true then, if there is a recorded event when adding to the stack, the callback is fired immediately with the recorded arguments. This is useful if you need the DOM but don't know if it is loaded yet.jMod.Events.addListener('EVENT_NAME', function(e){}, fireRecorded);
Events Table
Order Name Arguments Description 1 onDOMReady
none Fires as soon as the DOM is available. 2 onReady
none Fires as soon as all the jMod resources are added and initialized. This includes anything added using jMod.CSS = 'custom css';
which stores values until the DOM is available.3 onPageReady
none Fires when document.readyState is complete. 4* onPerformanceReady
none Fires when ALL the window's performance values are available. This is when you should make your update requests, and report stats to the server. 4* load
event Fires when the window's load event fires. * DOMContentLoaded
event Fires when the window's DOMContentLoaded event fires. * onreadystatechange
event Fires when the window's onreadystatechange event fires. * afterscriptexecute
event Fires when the window's afterscriptexecute event fires. * beforescriptexecute
event Fires when the window's beforescriptexecute event fires. -
Usage Settings
-
jMod has a powerful settings dialog generator built in, no need to write one yourself anymore!
Preference Types
Name Preference Features Description input
tooltip, icon textarea
tooltip, icon select
tooltip range
tooltip checkbox
label tooltip, checkbox tooltips radio
label tooltip, radio tooltips toggle
label tooltip, toggle tooltips Settings Example
The following example utilizes most of the features jMod Settings has to offer:
var SettingsTest = function(){ console.log('jMod.Settings Test'); 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); //setTimeout(function(){ //var settingsNav = document.querySelector('.jMod-settings .nav-tabs'); // Switch to Tab #1 in the settings dialog //jMod.Tabs.show(settingsNav, 1); //},2000); }; jMod.onReady = SettingsTest;