返回首頁 

GM_config RU

RU версия библиотеки GM_config

This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @require https://update.greasyfork.org/scripts/389678/826683/GM_config%20RU.js

// ==UserScript==// @name        GM_config RU// @namespace   https://github.com/ywzhaiqi/// @description RU версия библиотеки GM_config// @source      https://github.com/ywzhaiqi/GM_config// @version     1.1// @copyright   sizzlemctwizzle, RX-3200// @grant       GM_getValue// @grant       GM_setValue// @grant       GM_deleteValue// @license     LGPL 3// ==/UserScript==/*Modify the description1. Change to the Chinese "OK" and "Cancel" buttons.2. Select has added an array of textContents.3. Added a lot of features, see the example*//*Copyright 2009+, GM_config Contributors (https://github.com/sizzlemctwizzle/GM_config)GM_config Contributors:Mike Medley <[email protected]>Joe SimmonsIzzy SoftMarti MartzGM_config is distributed under the terms of the GNU Lesser General Public License.GM_config is free software: you can redistribute it and/or modifyit under the terms of the GNU Lesser General Public License as published bythe Free Software Foundation, either version 3 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU Lesser General Public License for more details.You should have received a copy of the GNU Lesser General Public Licensealong with this program.  If not, see <http://www.gnu.org/licenses/>;.*/// The GM_config constructorfunction GM_configStruct() {// call init() if settings were passed to constructorif (arguments.length) {GM_configInit(this, arguments);this.onInit();}}// This is the initializer functionfunction GM_configInit(config, args) {// Initialize instance variablesif (typeof config.fields == "undefined") {config.fields = {};config.onInit = config.onInit || function() {};config.onOpen = config.onOpen || function() {};config.onSave = config.onSave || function() {};config.onClose = config.onClose || function() {};config.onReset = config.onReset || function() {};config.isOpen = false;config.title = 'Настройки пользовательского скрипта';config.css = {basic: ["#GM_config * { font-family: arial,tahoma,myriad pro,sans-serif; }","#GM_config { background: #FFF; }","#GM_config input[type='radio'] { margin-right: 8px; }","#GM_config .indent40 { margin-left: 40%; }","#GM_config .field_label { font-size: 12px; font-weight: bold; margin-right: 6px; }","#GM_config .radio_label { font-size: 12px; }","#GM_config .block { display: block; }","#GM_config .saveclose_buttons { margin: 16px 10px 10px; padding: 2px 12px; }","#GM_config .reset, #GM_config .reset a," +" #GM_config_buttons_holder { color: #000; text-align: right; }","#GM_config .config_header { font-size: 20pt; margin: 0; }","#GM_config .config_desc, #GM_config .section_desc, #GM_config .reset { font-size: 9pt; }","#GM_config .center { text-align: center; }","#GM_config .section_header_holder { margin-top: 8px; }","#GM_config .config_var { margin: 0 0 4px; }","#GM_config .section_header { background: #414141; border: 1px solid #000; color: #FFF;"," font-size: 13pt; margin: 0; }","#GM_config .section_desc { background: #EFEFEF; border: 1px solid #CCC; color: #575757;" +" font-size: 9pt; margin: 0 0 6px; }",// newer"#GM_config input[type='number'] { width: 60px; }","#GM_config .nav-tabs { margin: 10 0}","#GM_config .nav-tabs > div { display: inline; padding: 3px 10px; }","#pv-prefs .section_header_holder { padding-left: 10px; }",].join('\n') + '\n',skin_tab: ["#GM_config { background: #EEE; }","#GM_config textarea { width: 98%; height: 45px; margin-top: 5px; }","#GM_config .field_label { display: inline-block; font-weight: normal; }",// Настройки в одной строке"#GM_config .inline input[type='checkbox'] { margin-left: 0; }","#GM_config .inline .config_var { margin-left: 15px; }",// Стиль контента"#GM_config .config_var { font-size: 12px; padding: 5px; margin: 0; }","#GM_config .config_header a { text-decoration: none; color: #000; }","#GM_config .nav-tabs { margin: 20 0}","#GM_config .nav-tabs > div { font-size: 14px; color: #999; cursor: pointer; padding: 10px 20px; }","#GM_config .nav-tabs > .active { cursor: default; color: #FFF; }","#GM_config .nav-tabs > div:hover { color: #FFF; }",].join('\n') + '\n',skin_1: [  // копия стиля Mouseover Popup Image Viewer"#GM_config { background: #EEE; }","#GM_config textarea { width: 98%; height: 45px; margin-top: 5px; }","#GM_config .config_var { font-size: 12px; }","#GM_config .inline .config_var { margin-left: 15px; }","#GM_config .field_label { display: inline-block; font-weight: normal; }","#GM_config { padding: 20px 30px; margin: 0; }","#GM_config .config_header { margin-bottom: 10px; }","#GM_config div.config_var { padding: 7px 0; }",].join('\n') + '\n',basicPrefix: "GM_config",stylish: ""};}if (args.length == 1 &&typeof args[0].id == "string" &&typeof args[0].appendChild != "function") var settings = args[0];else {// Provide backwards-compatibility with argument style intializationvar settings = {};// loop through GM_config.init() argumentsfor (var i = 0, l = args.length, arg; i < l; ++i) {arg = args[i];// An element to use as the config windowif (typeof arg.appendChild == "function") {settings.frame = arg;continue;}switch (typeof arg) {case 'object':for (var j in arg) { // could be a callback functions or settings objectif (typeof arg[j] != "function") { // we are in the settings objectif (typeof arg[j] == 'string') {settings.frameStyle = arg;} else {settings.fields = arg; // store settings object}break; // leave the loop} // otherwise it must be a callback functionif (!settings.events) settings.events = {};settings.events[j] = arg[j];}break;case 'function': // passing a bare function is set to open callbacksettings.events = {open: arg};break;case 'string': // could be custom CSS or the title string// if (/[\w\.]+\s*\{\s*[\w-]+\s*:\s*\w+[\s|\S]*\}/.test(arg))if (/[\w\.]+\s*\{\s*[\w-]+\s*:[\s|\S]*\}/.test(arg))settings.css = arg;else if (arg)settings.title = arg;break;}}}/* Initialize everything using the new settings object */// Set the idif (settings.id) config.id = settings.id;else if (typeof config.id == "undefined") config.id = 'GM_config';// Set the titleif (settings.title) config.title = settings.title;// Set the custom cssif (settings.css) config.css.stylish = settings.css;if (settings.skin) {var skin = config.css['skin_' + settings.skin];if (skin) {config.css.basic += skin;}}// Set the frameif (settings.frame) config.frame = settings.frame;if (settings.frameStyle) config.frameStyle = settings.frameStyle;config.isTabs = settings.isTabs;// Set the event callbacksif (settings.events) {var events = settings.events;for (var e in events)config["on" + e.charAt(0).toUpperCase() + e.slice(1)] = events[e];}// Create the fieldsif (settings.fields) {var stored = config.read(), // read the stored settingsfields = settings.fields,customTypes = settings.types || {};for (var id in fields) {var field = fields[id];// for each field definition create a field objectif (field)config.fields[id] = new GM_configField(field, stored[id], id,customTypes[field.type]);else if (config.fields[id]) delete config.fields[id];}}// If the id has changed we must modify the default styleif (config.id != config.css.basicPrefix) {config.css.basic = config.css.basic.replace(new RegExp('#' + config.css.basicPrefix, 'gm'), '#' + config.id);config.css.basicPrefix = config.id;}}GM_configStruct.prototype = {// Support old method of initalizinginit: function() {GM_configInit(this, arguments);this.onInit();},// call GM_config.open() from your script to open the menuopen: function () {// Die if the menu is already open on this page// You can have multiple instances but you can't open the same instance twicevar match = document.getElementById(this.id);if (match && (match.tagName == "IFRAME" || match.childNodes.length > 0)) return;// Sometimes "this" gets overwritten so create an aliasvar config = this;// Function to build the mighty config window :)function buildConfigWin (body, head) {var create = config.create,fields = config.fields,configId = config.id,bodyWrapper = create('div', {id: configId + '_wrapper'});// Append the style which is our default style plus the user stylehead.appendChild(create('style', {type: 'text/css',textContent: config.css.basic + config.css.stylish}));// Add header and titlebodyWrapper.appendChild(create('div', {id: configId + '_header',className: 'config_header block center'}, config.title));// Append elementsvar section = bodyWrapper,secNum = 0; // Section countvar lastParentNode = null;// loop through fieldsfor (var id in fields) {var field = fields[id],settings = field.settings;if (settings.section) { // the start of a new sectionsection = bodyWrapper.appendChild(create('div', {className: 'section_header_holder',id: configId + '_section_' + secNum}));if (Object.prototype.toString.call(settings.section) !== '[object Array]')settings.section = [settings.section];if (settings.section[0])section.appendChild(create('div', {className: 'section_header center',id: configId + '_section_header_' + secNum}, settings.section[0]));if (settings.section[1])section.appendChild(create('p', {className: 'section_desc center',id: configId + '_section_desc_' + secNum}, settings.section[1]));++secNum;}if (settings.line == 'start' && lastParentNode) {  // Переключиться на следующую строкуlastParentNode = null;}// Create field elements and append to current section(lastParentNode || section).appendChild((field.wrapper = field.toNode(configId, lastParentNode)));if (settings.line == 'start') {lastParentNode = field.wrapper;lastParentNode.classList.add('inline')} else if (settings.line == 'end') {lastParentNode = null;}}// Add save and close buttonsbodyWrapper.appendChild(create('div',{id: configId + '_buttons_holder'},create('button', {id: configId + '_saveBtn',textContent: 'Применить',title: 'Some options need to be refreshed to take effect',className: 'saveclose_buttons',onclick: function () {config.save();config.close();}}),create('button', {id: configId + '_closeBtn',textContent: 'Отмена',title: 'Отмена этих настроек, все параметры будут восстановлены',className: 'saveclose_buttons',onclick: function () {config.close()}}),create('div',{className: 'reset_holder block'},// Reset linkcreate('a', {id: configId + '_resetLink',textContent: 'По умолчанию',href: '#',title: 'Восстановить все настройки по умолчанию',className: 'reset',onclick: function (e) {e.preventDefault();config.reset()}}))));body.appendChild(bodyWrapper); // Paint everything to window at onceconfig.center(); // Show and center iframewindow.addEventListener('resize', config.center, false); // Center frame on resize// Call the open() callback functionconfig.onOpen(config.frame.contentDocument || config.frame.ownerDocument,config.frame.contentWindow || window,config.frame);if (config.isTabs) {config.toTabs();}// Close frame on window closewindow.addEventListener('beforeunload', function () {config.close();}, false);// Now that everything is loaded, make it visibleconfig.frame.style.display = "block";config.isOpen = true;}// Change this in the onOpen callback using this.frame.setAttribute('style', '')var defaultStyle = 'bottom: auto; border: 1px solid #000; display: none; height: 75%;'+ ' left: 0; margin: 0; max-height: 95%; max-width: 95%; opacity: 0;'+ ' overflow: auto; padding: 0; position: fixed; right: auto; top: 0;'+ ' width: 75%; z-index: 999999999;';// Either use the element passed to init() or create an iframeif (this.frame) {this.frame.id = this.id; // Allows for prefixing styles with the config idthis.frame.setAttribute('style', defaultStyle);buildConfigWin(this.frame, this.frame.ownerDocument.getElementsByTagName('head')[0]);} else {// Create framedocument.body.appendChild((this.frame = this.create('iframe', {id: this.id,style: defaultStyle})));if (this.frameStyle) {Object.keys(this.frameStyle).forEach(function(key) {config.frame.style[key] = config.frameStyle[key];})}// In WebKit src can't be set until it is added to the pagethis.frame.src = 'about:blank';// we wait for the iframe to load before we can modify itthis.frame.addEventListener('load', function(e) {var frame = config.frame;var body = frame.contentDocument.getElementsByTagName('body')[0];body.id = config.id; // Allows for prefixing styles with the config idbuildConfigWin(body, frame.contentDocument.getElementsByTagName('head')[0]);}, false);}},save: function () {var forgotten = this.write();this.onSave(forgotten); // Call the save() callback function},close: function() {if (!this.frame) return;// If frame is an iframe then remove itif (this.frame.contentDocument) {this.remove(this.frame);this.frame = null;} else { // else wipe its contentthis.frame.innerHTML = "";this.frame.style.display = "none";}// Null out all the fields so we don't leak memoryvar fields = this.fields;for (var id in fields) {var field = fields[id];field.wrapper = null;field.node = null;}this.onClose(); //  Call the close() callback functionthis.isOpen = false;},set: function (name, val) {this.fields[name].value = val;},get: function (name) {return this.fields[name].value;},write: function (store, obj) {if (!obj) {var values = {},forgotten = {},fields = this.fields;for (var id in fields) {var field = fields[id];var value = field.toValue();if (field.save) {if (value != null) {values[id] = value;field.value = value;} elsevalues[id] = field.value;} elseforgotten[id] = value;}}try {this.setValue(store || this.id, this.stringify(obj || values));} catch(e) {this.log("GM_config failed to save settings!");}return forgotten;},read: function (store) {try {var rval = this.parser(this.getValue(store || this.id, '{}'));} catch(e) {this.log("GM_config failed to read saved settings!");var rval = {};}return rval;},reset: function () {var fields = this.fields;// Reset all the fieldsfor (var id in fields) fields[id].reset();this.onReset(); // Call the reset() callback function},create: function () {switch(arguments.length) {case 1:var A = document.createTextNode(arguments[0]);break;default:var A = document.createElement(arguments[0]),B = arguments[1];for (var b in B) {if (b.indexOf("on") == 0)A.addEventListener(b.substring(2), B[b], false);else if (",style,accesskey,id,name,src,href,which,for".indexOf("," +b.toLowerCase()) != -1)A.setAttribute(b, B[b]);else if (typeof B[b] != 'undefined')A[b] = B[b];}if (typeof arguments[2] == "string")A.innerHTML = arguments[2];elsefor (var i = 2, len = arguments.length; i < len; ++i)A.appendChild(arguments[i]);}return A;},center: function () {var node = this.frame;if (!node) return;var style = node.style,beforeOpacity = style.opacity;if (style.display == 'none') style.opacity = '0';style.display = '';style.top = Math.floor((window.innerHeight / 2) - (node.offsetHeight / 2)) + 'px';style.left = Math.floor((window.innerWidth / 2) - (node.offsetWidth / 2)) + 'px';style.opacity = '1';},remove: function (el) {if (el && el.parentNode) el.parentNode.removeChild(el);},toTabs: function() {  // Convert to tab formvar body = this.frame.tagName == 'IFRAME' ? this.frame.contentWindow.document : this.frame,configId = this.id;var $ = function(id) {return body.getElementById(configId + '_' + id);};var headers = body.querySelectorAll('.section_header');if (!headers.length) return;var anch = this.create('div', {// id: configId + '_tab_holder',className: 'nav-tabs',});for (var i = 0, header; i < headers.length; i++) {header = headers[i];if (i == 0) {header.classList.add('active');}anch.appendChild(header);}anch.addEventListener('click', this.toggleTab.bind(this), false);$('section_0').parentNode.insertBefore(anch, $('section_0'));var curTab = localStorage.getItem(configId + '.config.curTab') || 0;this.toggleTab(parseInt(curTab, 10));},toggleTab: function(e) {var body = this.frame.tagName == 'IFRAME' ? this.frame.contentWindow.document : this.frame,configId = this.id;var curTab = typeof e == 'number' ? e : /\_(\d+)/.exec(e.target.id)[1];[].forEach.call(body.querySelectorAll('.section_header'), function(header, i) {if (i == curTab) {header.classList.add('active');} else {header.classList.remove('active');}});[].forEach.call(body.querySelectorAll('.section_header_holder'), function(holder, i) {holder.style.display = (i == curTab) ? 'block' : 'none';});localStorage.setItem(configId + '.config.curTab', curTab)}};// Define a bunch of API stuff(function() {var isGM = typeof GM_getValue != 'undefined' &&typeof GM_getValue('a', 'b') != 'undefined',setValue, getValue, stringify, parser;// Define value storing and reading APIif (!isGM) {setValue = function (name, value) {return localStorage.setItem(name, value);};getValue = function(name, def){var s = localStorage.getItem(name);return s == null ? def : s};// We only support JSON parser outside GMstringify = JSON.stringify;parser = JSON.parse;} else {setValue = GM_setValue;getValue = GM_getValue;stringify = typeof JSON == "undefined" ?function(obj) {return obj.toSource();} : JSON.stringify;parser = typeof JSON == "undefined" ?function(jsonData) {return (new Function('return ' + jsonData + ';'))();} : JSON.parse;}GM_configStruct.prototype.isGM = isGM;GM_configStruct.prototype.setValue = setValue;GM_configStruct.prototype.getValue = getValue;GM_configStruct.prototype.stringify = stringify;GM_configStruct.prototype.parser = parser;GM_configStruct.prototype.log =  window.console ?console.log : (isGM && typeof GM_log != 'undefined' ?GM_log : (window.opera ?opera.postError : function(){ /* no logging */ }));})();function GM_configDefaultValue(type, options) {var value;if (type && type.indexOf('unsigned ') == 0)type = type.substring(9);switch (type) {case 'radio': case 'select':value = options[0];break;case 'checkbox':value = false;break;case 'int': case 'integer':case 'float': case 'number':value = 0;break;default:value = '';}return value;}function GM_configField(settings, stored, id, customType) {// Store the field's settingsthis.settings = settings;this.id = id;this.node = null;this.wrapper = null;this.save = typeof settings.save == "undefined" ? true : settings.save;// Buttons are static and don't have a stored valueif (settings.type == "button") this.save = false;if (settings.type == "span") this.save = false;// if a default value wasn't passed through init() then//   if the type is custom use its default value//   else use default value for type// else use the default value passed through init()this['default'] = typeof settings['default'] == "undefined" ?customType ?customType['default']: GM_configDefaultValue(settings.type, settings.options): settings['default'];// Store the field's valuethis.value = typeof stored == "undefined" ? this['default'] : stored;// Setup methods for a custom typeif (customType) {this.toNode = customType.toNode;this.toValue = customType.toValue;this.reset = customType.reset;}}GM_configField.prototype = {create: GM_configStruct.prototype.create,toNode: function(configId, lastParentNode) {var field = this.settings,value = this.value,options = field.options,type = field.type,id = this.id,labelPos = field.labelPos,create = this.create;function addLabel(pos, labelEl, parentNode, beforeEl) {if (!beforeEl) {beforeEl = lastParentNode ? parentNode.lastChild : parentNode.firstChild;  // oneLine коррекция}switch (pos) {case 'right': case 'below':if (pos == 'below')parentNode.appendChild(create('br', {}));parentNode.appendChild(labelEl);break;default:if (pos == 'above')parentNode.insertBefore(create('br', {}), beforeEl);parentNode.insertBefore(labelEl, beforeEl);}}var retNode = create(lastParentNode ? 'span' : 'div', { className: 'config_var',id: configId + '_' + id + '_var',title: field.title }),firstProp;if (lastParentNode && field.className) retNode.classList.add(field.className);// Retrieve the first propfor (var i in field) { firstProp = i; break; }var label = field.label && type != "button" ?create('label', {id: configId + '_' + id + '_field_label',for: configId + '_field_' + id,className: 'field_label'}, field.label) : null;switch (type) {case 'span':label = null;this.node = create('span', {innerHTML: field.label,className: 'field_label',title: field.title,style: field.style});retNode = this.node;break;case 'textarea':retNode.appendChild((this.node = create('textarea', {innerHTML: value,id: configId + '_field_' + id,className: 'block' + (field.className ? (" " + field.className) : ''),cols: (field.cols ? field.cols : 20),rows: (field.rows ? field.rows : 2),placeholder: field.placeholder})));break;case 'radio':var wrap = create('div', {id: configId + '_field_' + id,className: field.className});this.node = wrap;for (var i = 0, len = options.length; i < len; ++i) {var radLabel = create('label', {className: 'radio_label'}, options[i]);var rad = wrap.appendChild(create('input', {value: options[i],type: 'radio',name: id,checked: options[i] == value}));var radLabelPos = labelPos &&(labelPos == 'left' || labelPos == 'right') ?labelPos : firstProp == 'options' ? 'left' : 'right';addLabel(radLabelPos, radLabel, wrap, rad);}retNode.appendChild(wrap);break;case 'select':var wrap = create('select', {id: configId + '_field_' + id,className: field.className});this.node = wrap;if (Array.isArray(options)) {  // Изменить на object форматvar newOptions = {};options.forEach(function(option) {newOptions[option] = option;});options = newOptions;}Object.keys(options).forEach(function(option) {wrap.appendChild(create('option', {value: option,selected: option == value,}, options[option]));});retNode.appendChild(wrap);break;default: // fields using input elementsvar props = {id: configId + '_field_' + id,type: type,value: type == 'button' ? field.label : value,className: field.className};switch (type) {case 'checkbox':props.checked = value;break;case 'button':props.size = field.size ? field.size : 25;if (field.script) field.click = field.script;if (field.click) props.onclick = field.click;break;case 'hidden':break;case 'number':break;default:// type = text, int, or floatprops.type = 'text';props.size = field.size ? field.size : 25;props.placeholder = field.placeholder;}retNode.appendChild((this.node = create('input', props)));}if (label) {// If the label is passed first, insert it before the field// else insert it afterif (!labelPos)labelPos = firstProp == "label" || type == "radio" ?"left" : "right";if ('className' in field) {label.className += ' ' + field.className;}if (field.style && field.style.label) {label.style.cssText = field.style.label;}addLabel(labelPos, label, retNode);}if (field.after) {retNode.appendChild(document.createTextNode(field.after));}if (field.attr) {var self = this;Object.keys(field.attr).forEach(function(key) {self.node.setAttribute(key, field.attr[key]);});}return retNode;},toValue: function() {var node = this.node,field = this.settings,type = field.type,unsigned = false,rval = null;if (!node) return rval;if (type && type.indexOf('unsigned ') == 0) {type = type.substring(9);unsigned = true;}switch (type) {case 'checkbox':rval = node.checked;break;case 'select':rval = node[node.selectedIndex].value;break;case 'radio':var radios = node.getElementsByTagName('input');for (var i = 0, len = radios.length; i < len; ++i)if (radios[i].checked)rval = radios[i].value;break;case 'button':break;case 'int': case 'integer':case 'float': case 'number':var num = Number(node.value);var warn = 'Field labeled "' + field.label + '" expects a' +(unsigned ? ' positive ' : 'n ') + 'integer value';if (isNaN(num) || (type.substr(0, 3) == 'int' &&Math.ceil(num) != Math.floor(num)) ||(unsigned && num < 0)) {alert(warn + '.');return null;}if (!this._checkNumberRange(num, warn))return null;rval = num;break;default:rval = node.value;break;}return rval; // value read successfully},reset: function() {var node = this.node,field = this.settings,type = field.type;if (!node) return;switch (type) {case 'checkbox':node.checked = this['default'];break;case 'select':for (var i = 0, len = node.options.length; i < len; ++i)if (node.options[i].value == this['default'])node.selectedIndex = i;break;case 'radio':var radios = node.getElementsByTagName('input');for (var i = 0, len = radios.length; i < len; ++i)if (radios[i].value == this['default'])radios[i].checked = true;break;case 'button' :break;default:node.value = this['default'];break;}},remove: function(el) {GM_configStruct.prototype.remove(el || this.wrapper);this.wrapper = null;this.node = null;},reload: function() {var wrapper = this.wrapper;if (wrapper) {var fieldParent = wrapper.parentNode;fieldParent.insertBefore((this.wrapper = this.toNode()), wrapper);this.remove(wrapper);}},_checkNumberRange: function(num, warn) {var field = this.settings;if (typeof field.min == "number" && num < field.min) {alert(warn + ' greater than or equal to ' + field.min + '.');return null;}if (typeof field.max == "number" && num > field.max) {alert(warn + ' less than or equal to ' + field.max + '.');return null;}return true;}};// Create default instance of GM_configvar GM_config = new GM_configStruct();