Last active
March 5, 2024 12:08
-
-
Save dataserver/7baa96ce14c170e66720c3ec7d57bfdf to your computer and use it in GitHub Desktop.
tampermonkey userscript boilerplate
This file contains 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 userscript boilerplate | |
// @namespace userscriptnamespace | |
// @version 1 | |
// @description Script description | |
// @author Author | |
// @match http://asdf.com/* | |
// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js | |
// @require https://cdnjs.cloudflare.com/ajax/libs/jquery-popup-overlay/2.1.1/jquery.popupoverlay.min.js | |
// @require https://cdnjs.cloudflare.com/ajax/libs/jquery.serializeJSON/2.9.0/jquery.serializejson.min.js | |
// @require https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/jquery.mark.min.js | |
// @require https://cdnjs.cloudflare.com/ajax/libs/alasql/0.4.11/alasql.min.js | |
// @require https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.4/toastr.min.js | |
// @require https://cdnjs.cloudflare.com/ajax/libs/jscolor/2.0.4/jscolor.min.js | |
// @require https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.23.0/moment.min.js | |
// @require https://cdnjs.cloudflare.com/ajax/libs/lz-string/1.4.4/lz-string.min.js | |
// @require https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js | |
// @grant GM_setValue | |
// @grant GM_getValue | |
// @grant GM_deleteValue | |
// @grant GM_listValues | |
// ==/UserScript== | |
// #################################################################################################################################### | |
// ABOUT: | |
// SOURCE CODE: https://greasyfork.org/en/scripts/372121- | |
// REF: | |
// - js style guide https://github.com/airbnb/javascript | |
// - reserved words http://www.javascripter.net/faq/reserved.htm | |
// - template strings https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Template_literals | |
// - icons https://fontawesome.com/v4.7.0/cheatsheet/ | |
// - alasql https://github.com/agershun/alasql/wiki/Getting-started | |
// - moment https://momentjs.com/docs/ | |
// - lz-string http://pieroxy.net/blog/pages/lz-string/ | |
// - underscore https://underscorejs.org/ | |
/* global $:false, jQuery:false, debug:false, alasql:false, toastr:false, jscolor:false, moment:false, LZString:false, _:false */ | |
((() => { // avoid conflicts | |
const DEBUG_MODE = true; | |
const SCRIPT_VERSION = 1; | |
const DEFAULT_CONFIG = { | |
font: 'Roboto', | |
color: '00cc00', | |
param_one: `1 Something here`, | |
param_text: `2 Text Another thing`, | |
param_three: `3 Three Third thing\nOhhhh`, | |
}; | |
const MARKJS_OPTIONS = { | |
element: "mark", | |
className: "uscr-text-highlight", | |
separateWordSearch: true | |
}; | |
const cssFiles = [ | |
"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/fontawesome.min.css", | |
"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/solid.min.css", | |
"https://fonts.googleapis.com/icon?family=Material+Icons", | |
"https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.4/toastr.min.css" | |
]; | |
// #################################################################################################################################### | |
let dbase; | |
let highlight_strings = []; | |
let storage = { | |
version: 1, | |
// compress: false, | |
options: { | |
prefix: '' | |
}, | |
// Greasemonkey storage API | |
read: function (key, defaultValue) { | |
const raw = GM_getValue(this._prefix(key), defaultValue); | |
// let str = (this.compress) ? LZString.decompressFromUTF16(raw) : raw; | |
return this._parse(raw); | |
}, | |
write: function (key, value) { | |
const raw = this._stringify(value); | |
// let str = (this.compress) ? LZString.compressToUTF16(raw) : raw; | |
return GM_setValue(this._prefix(key), raw); | |
}, | |
delete: function (key) { | |
return GM_deleteValue(this._prefix(key)); | |
}, | |
readKeys: function () { | |
return GM_listValues(); | |
}, | |
// browser localstorage | |
// read: function (key, defaultValue) { | |
// const raw = localStorage.getItem(this._prefix(key), defaultValue); | |
// const val = raw || defaultValue; | |
// // const str = (this.compress) ? LZString.decompressFromUTF16(val) : val; | |
// // return this._parse(str); | |
// return this._parse(val); | |
// }, | |
// write: function (key, value) { | |
// const raw = this._stringify(value); | |
// // let str = (this.compress) ? LZString.compressToUTF16(raw) : raw; | |
// localStorage.setItem(this._prefix(key), raw); | |
// return; | |
// }, | |
// delete: function (key) { | |
// return localStorage.removeItem(this._prefix(key)); | |
// }, | |
// readKeys: function () { | |
// let keys = []; | |
// for(let i=0, l=localStorage.length; i < l; i++){ | |
// keys.push( localStorage.getItem(localStorage.key(i)) ); | |
// } | |
// return keys; | |
// }, | |
// “Set” means “add if absent, replace if present.” | |
set: function (key, value) { | |
let savedVal = this.read(key); | |
if (typeof savedVal === 'undefined' || !savedVal) { | |
// add if absent | |
return this.add(key, value); | |
} else { | |
// replace if present | |
this.write(key, value); | |
return true; | |
} | |
}, | |
// “Add” means “add if absent, do nothing if present” (if a uniquing collection). | |
add: function (key, value) { | |
let savedVal = this.read(key, false); | |
if (typeof savedVal === 'undefined' || !savedVal) { | |
this.write(key, value); | |
return true; | |
} else { | |
if (this._isArray(savedVal)) { // is array | |
let index = savedVal.indexOf(value); | |
if (index !== -1) { | |
// do nothing if present | |
return false; | |
} else { | |
// add if absent | |
savedVal.push(value); | |
this.write(key, savedVal); | |
return true; | |
} | |
} else if (this._isObject(savedVal)) { // is object | |
// merge obj value on obj | |
let result, objToMerge = value; | |
result = Object.assign(savedVal, objToMerge); | |
this.write(key, result); | |
return false; | |
} | |
return false; | |
} | |
}, | |
// “Replace” means “replace if present, do nothing if absent.” | |
replace: function (key, itemFind, itemReplacement) { | |
let savedVal = this.read(key, false); | |
if (typeof savedVal === 'undefined' || !savedVal) { | |
// do nothing if absent | |
return false; | |
} else { | |
if (this._isArray(savedVal)) { // is Array | |
let index = savedVal.indexOf(itemFind); | |
if (index !== -1) { | |
// replace if present | |
savedVal[index] = itemReplacement; | |
this.write(key, savedVal); | |
return true; | |
} else { | |
// do nothing if absent | |
return false; | |
} | |
} else if (this._isObject(savedVal)) { | |
// is Object | |
// replace property's value | |
savedVal[itemFind] = itemReplacement; | |
this.write(key, savedVal); | |
return true; | |
} | |
return false; | |
} | |
}, | |
// “Remove” means “remove if present, do nothing if absent.” | |
remove: function (key, value) { | |
if (typeof value === 'undefined') { // remove key | |
this.delete(key); | |
return true; | |
} else { // value present | |
let savedVal = this.read(key); | |
if (typeof savedVal === 'undefined' || !savedVal) { | |
return true; | |
} else { | |
if (this._isArray(savedVal)) { // is Array | |
let index = savedVal.indexOf(value); | |
if (index !== -1) { | |
// remove if present | |
savedVal.splice(index, 1); | |
this.write(key, savedVal); | |
return true; | |
} else { | |
// do nothing if absent | |
return false; | |
} | |
} else if (this._isObject(savedVal)) { // is Object | |
let property = value; | |
delete savedVal[property]; | |
this.write(key, savedVal); | |
return true; | |
} | |
return false; | |
} | |
} | |
}, | |
get: function (key, defaultValue) { | |
return this.read(key, defaultValue); | |
}, | |
getAll: function () { | |
const keys = this._listKeys(); | |
let obj = {}; | |
for (let i = 0, len = keys.length; i < len; i++) { | |
obj[keys[i]] = this.read(keys[i]); | |
} | |
return obj; | |
}, | |
getKeys: function () { | |
return this._listKeys(); | |
}, | |
getPrefix: function () { | |
return this.options.prefix; | |
}, | |
empty: function () { | |
const keys = this._listKeys(); | |
for (let i = 0, len = keys.lenght; i < len; i++) { | |
this.delete(keys[i]); | |
} | |
}, | |
has: function (key) { | |
return this.get(key) !== null; | |
}, | |
forEach: function (callbackFunc) { | |
const allContent = this.getAll(); | |
for (let prop in allContent) { | |
callbackFunc(prop, allContent[prop]); | |
} | |
}, | |
_parse: function (value) { | |
if (this._isJson(value)) { | |
return JSON.parse(value); | |
} | |
return value; | |
}, | |
_stringify: function (value) { | |
if (this._isJson(value)) { | |
return value; | |
} | |
return JSON.stringify(value); | |
}, | |
_listKeys: function (usePrefix = false) { | |
const prefixed = this.readKeys(); | |
let unprefixed = []; | |
if (usePrefix) { | |
return prefixed; | |
} else { | |
for (let i = 0, len = prefixed.length; i < len; i++) { | |
unprefixed[i] = this._unprefix(prefixed[i]); | |
} | |
return unprefixed; | |
} | |
}, | |
_prefix: function (key) { | |
return this.options.prefix + key; | |
}, | |
_unprefix: function (key) { | |
return key.substring(this.options.prefix.length); | |
}, | |
_isJson: function (item) { | |
try { | |
JSON.parse(item); | |
} catch (e) { | |
return false; | |
} | |
return true; | |
}, | |
_isObject: function (a) { | |
return (!!a) && (a.constructor === Object); | |
}, | |
_isArray: function (a) { | |
return (!!a) && (a.constructor === Array); | |
} | |
}; | |
// https://stackoverflow.com/questions/7298364/using-jquery-and-json-to-populate-forms | |
function populateForm($form, data) { | |
$.each(data, (key, value) => { // all json fields ordered by name | |
let $ctrls, $ctrl; | |
if (value instanceof Array) { | |
$ctrls = $form.find("[name='" + key + "[]']"); //all form elements for a name. Multiple checkboxes can have the same name, but different values | |
} else { | |
$ctrls = $form.find("[name='" + key + "']"); | |
} | |
if ($ctrls.is("select")) { //special form types | |
$("option", $ctrls).each(function () { | |
if (this.value == value) { | |
this.selected = true; | |
} | |
}); | |
} else if ($ctrls.is("textarea")) { | |
$ctrls.val(value); | |
} else { | |
switch ($ctrls.attr("type")) { //input type | |
case "text": | |
case "range": | |
case "hidden": | |
$ctrls.val(value); | |
break; | |
case "radio": | |
if ($ctrls.length >= 1) { | |
$.each($ctrls, function (index) { // every individual element | |
let elemValue = $(this).attr("value"); | |
let singleVal = value; | |
let elemValueInData = singleVal; | |
if (elemValue == value) { | |
$(this).prop("checked", true); | |
} else { | |
$(this).prop("checked", false); | |
} | |
}); | |
} | |
break; | |
case "checkbox": | |
if ($ctrls.length > 1) { | |
$.each($ctrls, function (index) { // every individual element | |
let elemValue = $(this).attr("value"); | |
let elemValueInData; | |
let singleVal; | |
for (let i = 0; i < value.length; i++) { | |
singleVal = value[i]; | |
debug("singleVal", singleVal, "/value[i][1]", value[i][1]); | |
if (singleVal == elemValue) { | |
elemValueInData = singleVal; | |
} | |
} | |
if (elemValueInData) { | |
$(this).prop("checked", true); | |
} else { | |
$(this).prop("checked", false); | |
} | |
}); | |
} else if ($ctrls.length == 1) { | |
$ctrl = $ctrls; | |
if (value) { | |
$ctrl.prop("checked", true); | |
} else { | |
$ctrl.prop("checked", false); | |
} | |
} | |
break; | |
} | |
} | |
}); | |
} | |
function db_check_version() { | |
const stored_ver = parseInt(storage.get('version', 0), 10); | |
let upgrade = false; | |
if (stored_ver === 0) { // first run | |
setup_storage(); | |
} else if (stored_ver === 111) { | |
upgrade_v2(); | |
debug('set new version', SCRIPT_VERSION); | |
} | |
} | |
function setup_storage() { | |
// storage.set('configs', DEFAULT_CONFIG); | |
// storage.set('version', SCRIPT_VERSION); | |
} | |
function db_init() { | |
// let users_db = storage.get("users", []); | |
// let favorites_db = storage.get("favorites", []); | |
dbase = new alasql.Database("mybase"); | |
// dbase.exec("CREATE TABLE users (id INT, name STRING, highlight INT, icon STRING, icon_color STRING, note STRING)"); | |
// dbase.exec("CREATE TABLE favorites (postid INT, username STRING, note STRING)"); | |
// if (users_db.length >= 1) { | |
// alasql.databases.mybase.tables.users.data = users_db; | |
// } | |
// if (favorites_db.length >= 1) { | |
// alasql.databases.mybase.tables.favorites.data = favorites_db; | |
// } | |
// setup_storage(); | |
// db_clean(); | |
} | |
function db_clean() { | |
// dbase.exec("DELETE FROM users"); | |
// dbase.exec("DELETE FROM favorites"); | |
db_save(); | |
} | |
function db_save() { | |
// debug( alasql.databases.mybase.tables.users.data); | |
// storage.set("users", alasql.databases.mybase.tables.users.data); | |
// debug( alasql.databases.mybase.tables.favorites.data); | |
// storage.set("favorites", alasql.databases.mybase.tables.favorites.data); | |
} | |
function upgrade_v2() { | |
// storage.set('version', 2); | |
// do stuff | |
} | |
// CONFIG | |
function get_config() { | |
let cfg = storage.get('configs', DEFAULT_CONFIG); | |
debug('cfg', cfg); | |
return Object.assign({}, DEFAULT_CONFIG, cfg); | |
} | |
function set_config(configs) { | |
debug('props', Object.getOwnPropertyNames(configs).sort()); | |
storage.set('configs', configs); | |
return configs; | |
} | |
// USER | |
function create_User(user) { | |
return { | |
id: parseInt(user.id), | |
name: (typeof user.name !== 'undefined') ? user.name : "", | |
flagged: (typeof user.flagged !== 'undefined') ? parseInt(user.flagged) : 0, | |
note: (typeof user.note !== 'undefined') ? user.note : "" | |
}; | |
} | |
function get_user(id = 0) { | |
id = parseInt(id); | |
// let result = dbase.exec("SELECT * FROM users WHERE id = ? LIMIT 1", [id]); | |
// if (result.length > 0) { | |
// return result[0]; | |
// } else { | |
// return null; | |
// } | |
} | |
function set_user(user = {}) { | |
// user.id = parseInt(user.id); | |
// user.highlight = parseInt(user.highlight); | |
// dbase.exec("DELETE FROM users WHERE id = ? ", [user.id]); | |
// dbase.exec("INSERT INTO users (?,?,?,?,?,?)", [user.id, user.name, user.highlight, user.icon, user.icon_color, user.note]); | |
db_save(); | |
} | |
function delete_user(id = 0) { | |
id = parseInt(id); | |
// dbase.exec("DELETE FROM users WHERE id = ? ", [id]); | |
db_save(); | |
} | |
// DEBUG | |
function set_debug(isDebug = false) { | |
if (isDebug) { | |
window.debug = window.console.log.bind(window.console); | |
} else { | |
window.debug = function () {}; | |
} | |
} | |
function appendFilesToHead(arr = [], forceExt = false) { | |
for (let i = 0; i < arr.length; i++) { | |
let urlStr = arr[i]; | |
let ext = (forceExt) ? forceExt : urlStr.slice((Math.max(0, urlStr.lastIndexOf(".")) || Infinity) + 1); | |
let ele = null; | |
switch (ext) { | |
case "js": | |
ele = document.createElement("script"); | |
ele.type = "text/javascript"; | |
ele.src = urlStr; | |
break; | |
case "css": | |
ele = document.createElement("link"); | |
ele.rel = "stylesheet"; | |
ele.type = "text/css"; | |
ele.href = urlStr; | |
break; | |
default: | |
ele = document.createElement("script"); | |
ele.type = "text/javascript"; | |
ele.src = urlStr; | |
} | |
document.getElementsByTagName("head")[0].appendChild(ele); | |
} | |
} | |
function append_styles() { | |
let styles = ``; | |
let arrCss = cssFiles; | |
if (configs.forum_font != "") { | |
arrCss.push(`https://fonts.googleapis.com/css?family=${configs.font}`); | |
} | |
appendFilesToHead(arrCss, 'css'); | |
// http://dev.vast.com/jquery-popup-overlay/ | |
styles += ` | |
<style data-style-id="js-uscr-fixed-style" type="text/css"> | |
/* .mil {font-family: 'Lato', sans-serif;} */ | |
.mil { color: #000000; line-height: 1.5; } | |
/* TYPOGRAPHY */ | |
.mil h1 {font-size: 2.5rem;} | |
.mil h2 {font-size: 2rem;} | |
.mil h3 {font-size: 1.375rem;} | |
.mil h4 {font-size: 1.125rem;} | |
.mil h5 {font-size: 1rem;} | |
.mil h6 {font-size: 0.875rem;} | |
/* .mil p { font-size: 1.125rem; font-weight: 200; line-height: 1.8;} */ | |
.mil .left {text-align: left;} | |
.mil .right {text-align: right;} | |
.mil .center {text-align: center; margin-left: auto; margin-right: auto;} | |
.mil .justify {text-align: justify;} | |
/* GRID */ | |
.mil .container { width: 90%; margin-left: auto; margin-right: auto;} | |
.mil .row { position: relative; width: 100%; } | |
.mil .row [class^="col"] { float: left; margin: 0.5rem 2%; min-height: 0.125rem; } | |
.mil .col-1,.mil .col-2,.mil .col-3,.mil .col-4,.mil .col-5,.mil .col-6,.mil .col-7,.mil .col-8,.mil .col-9,.mil .col-10,.mil .col-11,.mil .col-12 { width: 96%; } | |
.mil .col-1-sm { width: 4.33%; } | |
.mil .col-2-sm { width: 12.66%; } | |
.mil .col-3-sm { width: 21%; } | |
.mil .col-4-sm { width: 29.33%; } | |
.mil .col-5-sm { width: 37.66%; } | |
.mil .col-6-sm { width: 46%; } | |
.mil .col-7-sm { width: 54.33%; } | |
.mil .col-8-sm { width: 62.66%; } | |
.mil .col-9-sm { width: 71%; } | |
.mil .col-10-sm { width: 79.33%; } | |
.mil .col-11-sm { width: 87.66%; } | |
.mil .col-12-sm { width: 96%; } | |
.mil .row::after { content: ""; display: table; clear: both;} | |
.mil .hidden-sm { display: none;} | |
@media only screen and (min-width: 33.75em) {/* 540px */ | |
.mil .container { width: 80%; } | |
} | |
@media only screen and (min-width: 45em) {/* 720px */ | |
.mil .col-1 { width: 4.33%; } | |
.mil .col-2 { width: 12.66%; } | |
.mil .col-3 { width: 21%; } | |
.mil .col-4 { width: 29.33%; } | |
.mil .col-5 { width: 37.66%; } | |
.mil .col-6 { width: 46%; } | |
.mil .col-7 { width: 54.33%; } | |
.mil .col-8 { width: 62.66%; } | |
.mil .col-9 { width: 71%; } | |
.mil .col-10-sm { width: 79.33%; } | |
.mil .col-11-sm { width: 87.66%; } | |
.mil .col-12-sm { width: 96%; } | |
.mil .hidden-sm { display: block; } | |
} | |
@media only screen and (min-width: 60em) {/* 960px */ | |
.mil .container {width: 75%;max-width: 60rem;} | |
} | |
/* userscript css */ | |
.css-uscr {color:#000000;} | |
.css-uscr a:link { color: #0000EE; } | |
.css-uscr a:visited { color: #551A8B; } | |
.css-uscr-cursor-pointer { cursor: pointer;} | |
.css-uscr-cursor-move { cursor: move;} | |
.css-uscr-hidden { display:none; } | |
.css-uscr-modal-resizable { overflow: auto; resize: both; } | |
.css-uscr-modal-draggable { position: absolute;} | |
.popup_visible .css-uscr-card { | |
-webkit-transform: scale(1); | |
-moz-transform: scale(1); | |
-ms-transform: scale(1); | |
transform: scale(1); | |
} | |
.css-uscr-full-overlay { | |
position: fixed; | |
background: #fff; | |
bottom: 0; | |
right: 0; | |
width: 0%; | |
height: 0%; | |
opacity: 0.9; | |
visibility: hidden; | |
overflow: auto; | |
z-index: 99998; | |
} | |
.css-uscr-card { | |
-webkit-transform: scale(0.8); | |
-moz-transform: scale(0.8); | |
-ms-transform: scale(0.8); | |
transform: scale(0.8); | |
z-index: 10000; | |
min-height:20px; | |
padding:19px; | |
margin-bottom:20px; | |
background-color:#FFFFFF; | |
border:1px solid #e3e3e3; | |
border-radius:4px; | |
-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05); | |
box-shadow:inset 0 1px 1px rgba(0,0,0,.05) | |
} | |
.css-uscr-card FIELDSET { | |
border: 1px solid #000000; | |
padding: 5px; | |
margin-top: 10px; | |
} | |
.css-uscr-card FIELDSET LEGEND { | |
color: #000000; | |
padding: 2px 5px ; | |
margin-left: 10px; | |
} | |
.css-uscr-card BUTTON { | |
padding: 5px 10px; | |
text-align: center; | |
font-weight: bold; | |
display: inline-block; | |
border-radius: .5rem; | |
border: 3px solid transparent; | |
} | |
.css-uscr-button-row { text-align:center; margin-top: 20px;} | |
.css-uscr-card TABLE BUTTON { padding: 0px 10px;} | |
.css-uscr-card TEXTAREA { min-height: 250px; } | |
.css-uscr-card TEXTAREA, | |
.css-uscr-card INPUT[type="text"] { width: 95%; } | |
.css-uscr-slider {-webkit-appearance: none; appearance: none; width: 100%; background: #e3e3e3; outline: none; opacity: 0.7; -webkit-transition: .2s; transition: opacity .2s; } | |
.css-uscr-slider:hover { opacity: 1; } | |
.css-uscr-slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 25px; height: 25px; background: #4CAF50; cursor: pointer;} | |
.css-uscr-slider::-moz-range-thumb { width: 25px; height: 25px; background: #4CAF50; cursor: pointer;} | |
.css-btn-primary {background-color: blue; cursor:pointer; color:white;} | |
.css-btn-danger {background-color: red; cursor:pointer; color:white;} | |
.css-btn-neutral {background-color: grey; cursor:pointer; color:white;} | |
.css-uscr-help-icon { text-align: right;cursor: pointer;} | |
.mil dl { | |
display: block; | |
margin-block-start: 1em; | |
margin-block-end: 1em; | |
margin-inline-start: 0px; | |
margin-inline-end: 0px; | |
} | |
.mil dt { | |
display: block; | |
} | |
.mil dd { | |
display: block; | |
margin-inline-start: 40px; | |
} | |
.tables-row-hover tr:hover td{ | |
background-color:#CFFFFD; | |
} | |
</style> | |
<style data-style-id="js-uscr-dynamic-style" type="text/css"></style> | |
`; | |
$('head').append(styles); | |
} | |
function append_modals() { | |
let cpButton, modals; | |
modals = ` | |
<!-- USERSCRIPT --> | |
<!-- TEMPLATE --> | |
<div id="js-uscr-card-template" class="js-uscr-modal-draggable css-uscr css-uscr-card css-uscr-modal-resizable" style="display:none;"> | |
<div class="mil"> | |
<h2 class="js-uscr-modal-draggable-handler css-uscr-cursor-move"> | |
Help | |
</h2> | |
<div class="row"> | |
<div class="col-12"> | |
<h2>Icons</h2> | |
<dl> | |
<dt>Top of Page</dt> | |
<dd><i class="fas fa-cog fa-lg"></i> - Open userscript options</dd> | |
<dd><i class="fas fa-bookmark fa-lg"></i> - Your Favorites</dd> | |
<dt>Under User Posts</dt> | |
<dd><i class="fas fa-sticky-note fa-lg"></i> - Write note about this user</dd> | |
<dd><i class="fas fa-paint-brush fa-lg"></i> - Highlight the username everywhere</dd> | |
<dd><i class="fas fa-bookmark fa-lg"></i> - Favorite this post</dd> | |
</dl> | |
<p></p> | |
<p>version: ${SCRIPT_VERSION}</p> | |
</div> | |
</div> | |
<p class="button-row"> | |
<button type="button" class="js-uscr-card-button-close css-btn-neutral">Close</button> | |
</p> | |
</div> | |
</div> | |
<!-- /TEMPLATE --> | |
<!-- HELP --> | |
<div id="js-uscr-card-help" class="js-uscr-modal-draggable css-uscr css-uscr-card css-uscr-modal-resizable" style="min-width:50vh; min-height:40vh; display:none;"> | |
<div class="mil"> | |
<h2 class="js-uscr-modal-draggable-handler css-uscr-cursor-move"> | |
Help | |
</h2> | |
<div class="row"> | |
<div class="col-12"> | |
<h2>Icons</h2> | |
<dl> | |
<dt>Top of Page</dt> | |
<dd><i class="fas fa-cog fa-lg"></i> - Open userscript options</dd> | |
<dd><i class="fas fa-bookmark fa-lg"></i> - Your Favorites</dd> | |
<dt>Under User Posts</dt> | |
<dd><i class="fas fa-sticky-note fa-lg"></i> - Write note about this user</dd> | |
<dd><i class="fas fa-paint-brush fa-lg"></i> - Highlight the username everywhere</dd> | |
<dd><i class="fas fa-bookmark fa-lg"></i> - Favorite this post</dd> | |
</dl> | |
<p></p> | |
<p>version: ${SCRIPT_VERSION}</p> | |
</div> | |
</div> | |
<p class="button-row"> | |
<button type="button" class="js-uscr-card-button-close css-btn-neutral">Close</button> | |
</p> | |
</div> | |
</div> | |
<!-- /HELP --> | |
<!-- CPANEL --> | |
<div id="js-uscr-card-cpanel" class="js-uscr-modal-draggable css-uscr css-uscr-card css-uscr-modal-resizable" style="min-width:50vh; min-height:40vh; display:none;"> | |
<div class="mil"> | |
<form id="js-uscr-form-cpanel"> | |
<h2 class="js-uscr-modal-draggable-handler css-uscr-cursor-move">Settings</h2> | |
<fieldset> | |
<legend>Field Set</legend> | |
<P> | |
<label> | |
<span>Param 1</span> | |
<br> | |
<input type="text" name="param_one" value=""> | |
</label> | |
</p> | |
<P> | |
<label> | |
<span>Param 2</span> | |
<br> | |
<input type="text" name="param_text" value=""> | |
</label> | |
</p> | |
<p> | |
<label> | |
<span>Color</span> | |
<br> | |
<input type="text" class="js-uscr-color" data-jscolor="{position:'top', zIndex:100002, width:101, padding:20, borderWidth:3}" data-bind="updateSampleText" name="color" value="" size="6"> | |
</label> | |
</p> | |
<p> | |
<span class="js-uscr-color-sample">Lorem ipsum dolor sit amet, consectetur</span> | |
</p> | |
<p> | |
<label> | |
<span>Font</span> | |
<br> | |
<select name="font"> | |
<option value="">- Use theme default -</option> | |
<option value="IBM+Plex+Mono">IBM Plex Mono</option> | |
<option value="Lato">Lato</option> | |
<option value="Merriweather">Merriweather</option> | |
<option value="Open+Sans">Opens Sans</option> | |
<option value="Questrial">Questrial</option> | |
<option value="Raleway">Raleway</option> | |
<option value="Roboto">Roboto</option> | |
<option value="Roboto+Mono">Roboto Mono</option> | |
<option value="Ubuntu">Ubuntu</option> | |
</select> | |
</label> | |
</p> | |
<p> | |
<label> | |
<span>Note</span> | |
<br> | |
<textarea name="param_three" row="3"></textarea> | |
</label> | |
</p> | |
</fieldset> | |
<!-- | |
<fieldset> | |
<legend></legend> | |
<p> | |
<label> | |
<span></span> | |
<br> | |
</label> | |
</p> | |
</fieldset> | |
--> | |
<p class="button-row"> | |
<button type="button" class="js-uscr-card-button-close css-btn-neutral">Close</button> | |
<button type="button" class="js-uscr-card-button-save css-btn-primary">Save</button> | |
</p> | |
</form> | |
<div align="right"> | |
<span class="js-uscr-card-button-help css-uscr-help-icon"><i class="fas fa-question-circle fa-2x"></i></span> | |
</div> | |
</div> | |
</div> | |
<!-- /CPANEL --> | |
<!-- /USERSCRIPT --> | |
`; | |
cpButton = ` | |
<!-- USERSCRIPT --> | |
<div> | |
<span class="js-uscr-card-cpanel-button-open" style="cursor: pointer;"><i class="fas fa-cogs fa-lg"></i> </span> | |
</div> | |
<!-- /USERSCRIPT --> | |
`; | |
$("BODY").append(modals); | |
$("BODY").append(cpButton); | |
} | |
function do_config_css() { | |
let css; | |
css = `.uscr-text-highlight {color:#${configs.hightlight_color}; background-color:#${configs.hightlight_bgcolor};}`; | |
// if (configs.banned_users_highlight) { | |
// css += `.uscr-title-banner-member {color:#${configs.banned_users_highlight_color};}`; | |
// } | |
if (configs.font != "") { | |
css += `body { font-family: "${configs.font}"; }`; | |
} | |
$("#uscr-dynamic-style").html(css); | |
$("#navigation.pageWidth").css({ "width": configs.forum_width + "vw" }); | |
$("#content .pageWidth").css({ "width": configs.forum_width + "vw" }); | |
} | |
// HIGHLIGHT | |
function do_highlight(arr = []) { | |
let db_strings; | |
let result; | |
let strings_comma = configs.highlight_strings; | |
let oldArray = strings_comma.split(","); | |
let trimedArr = oldArray.map(str => str.trim()); | |
debug("do_highlight", result); | |
// result = mybase.exec("SELECT * FROM configs"); | |
// if (result.length > 0) { | |
// db_strings = result.map(item => item.name); | |
// debug("db_strings", db_strings); | |
// } | |
// $("elementName").mark(strs, MARKJS_OPTIONS); | |
$("BODY").mark(trimedArr, MARKJS_OPTIONS); | |
} | |
function undo_highlight() { | |
$("BODY").unmark(MARKJS_OPTIONS); | |
} | |
function main() { | |
debug('main()', ''); | |
// CARD > DRAG | |
$(document).on('mousedown', '.js-uscr-modal-draggable-handler', function (event) { | |
let move = $(this).closest('.js-uscr-modal-draggable'); | |
let lastOffset = move.data('lastTransform'); | |
let lastOffsetX = lastOffset ? lastOffset.dx : 0; | |
let lastOffsetY = lastOffset ? lastOffset.dy : 0; | |
let startX = event.pageX - lastOffsetX; | |
let startY = event.pageY - lastOffsetY; | |
$(document).on('mousemove', function (event) { | |
let newDx = event.pageX - startX; | |
let newDy = event.pageY - startY; | |
move.css('transform', 'translate(' + newDx + 'px, ' + newDy + 'px)'); | |
move.data('lastTransform', { | |
dx: newDx, | |
dy: newDy | |
}); | |
window.getSelection().removeAllRanges(); | |
}); | |
}); | |
$(document).on('mouseup', function () { | |
$(this).off('mousemove'); | |
}); | |
// CARD > CPANEL > OPEN | |
$(document).on('click', '.js-uscr-card-cpanel-button-open', function (event) { | |
event.preventDefault(); | |
$("BODY").addClass("css-uscr-noscroll"); | |
$("#js-uscr-card-cpanel").popup({ blur: false, autoopen: true }); | |
populateForm($("#js-uscr-card-cpanel FORM"), configs); | |
jscolor.installByClassName('js-uscr-color'); | |
return false; | |
}); | |
// CARD > BUTTON CLOSE | |
$(".js-uscr-card-button-close").click(function () { | |
event.preventDefault(); | |
let card_id = $(this).closest('.css-uscr-card').attr("id"); | |
$("BODY").removeClass("css-uscr-noscroll"); | |
$(`#${card_id}`).popup('hide'); | |
return false; | |
}); | |
// CARD > BUTTON SAVE | |
$(".js-uscr-card-button-save").click(function () { | |
event.preventDefault(); | |
let card_id = $(this).closest(".css-uscr-card").attr("id"); | |
let formData = $(this).closest("form").serializeJSON(); | |
console.log(formData); | |
switch (card_id) { //input type | |
case "js-uscr-card-": | |
break; | |
case "js-uscr-card-cpanel": | |
set_config(formData); | |
configs = get_config(); | |
do_config_css(); | |
break; | |
default: | |
} | |
$("BODY").removeClass("css-uscr-noscroll"); | |
$(`#${card_id}`).popup('hide'); | |
toastr.success('Saved'); | |
return false; | |
}); | |
// CARD > BUTTON DELETE | |
$(".js-uscr-card-button-delete").click(function () { | |
event.preventDefault(); | |
let id; | |
let card_id = $(this).closest(".css-uscr-card").attr("id"); | |
switch (card_id) { | |
case "js-uscr-card-": | |
id = $(this).closest("form[data-id]").attr("data-id"); | |
break; | |
case "js-uscr-card-cpanel": | |
//id = '2'; | |
//delete_xyz(card_id); | |
break; | |
default: | |
//something | |
} | |
$("BODY").removeClass("css-uscr-noscroll"); | |
$(`#${card_id}`).popup('hide'); | |
toastr.success('Deleted'); | |
return false; | |
}); | |
// CARD > BUTTON HELP | |
$('.js-uscr-card-button-help').click(function () { | |
event.preventDefault(); | |
let card_id = $(this).closest(".css-uscr-card").attr("id"); | |
$("BODY").addClass("css-uscr-noscroll"); | |
$(`#${card_id}`).popup('hide'); | |
$("#js-uscr-card-help").popup({ blur: false, autoopen: true }); | |
return false; | |
}); | |
// ==================================================================== | |
$("#js-uscr-card-cpanel INPUT[data-bind='updateSampleText']").on('change', function () { | |
let color = $(this).val(); | |
$(this).css("background-color", '#' + color); | |
$(".js-uscr-color-sample").css({ color: "#" + color }); | |
return false; | |
}); | |
} //main | |
// ======================================================================== | |
set_debug(DEBUG_MODE); | |
db_check_version(); | |
let configs = get_config(); | |
toastr.options = { | |
toastClass: 'toastr', | |
positionClass: 'toast-top-full-width', | |
showDuration: 300, | |
hideDuration: 1000, | |
timeOut: 3000 | |
}; | |
$(document).ready(function () { | |
db_init(); | |
append_styles(); | |
append_modals(); | |
main(); | |
do_config_css(); | |
}); | |
}))(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment