您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Modules for UI constructing
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/384232/704113/UIModules.js
- // ==UserScript==
- // @name UIModules
- // @name:en UIModules
- // @description Modules for UI constructing
- // @description:en Modules for UI constructing
- // @namespace https://gf.qytechs.cn/users/174399
- // @version 0.1.0
- // @include *://*.mozilla.org/*
- // @run-at document-start
- // @grant none
- // ==/UserScript==
- (function(window) {
- 'use strict';
- const listSymbol = Symbol('list');
- const modeSymbol = Symbol('mode');
- const valueSymbol = Symbol('value');
- const fn = {};
- fn.toJSON = function() {
- return {
- __function_body__: this.toString().replace(/\s+/g, ' '),
- __function_name__: this.name,
- __function_length__: this.length,
- };
- };
- function reviver(key, value) {
- if (key === '__function_body__') {
- return new Function('return ' + value)();
- }
- if (typeof value === 'object' && typeof value.__function_body__ === 'function') {
- return value.__function_body__;
- }
- return value;
- }
- /*
- const interfaceTemplate = {
- title: 'template interface',
- version: '0.1.0',
- mode: 'normal',
- tabs: {
- data: {
- 'general': {},
- },
- order: ['general'],
- },
- };
- const tabDataTemplate = {
- name: 'general',
- label: 'General',
- options: {
- data: {
- 'option-name': {},
- },
- order: ['option-name'],
- },
- };
- const optionDataTemplate = {
- name: 'option-name',
- label: 'Option name',
- value: 'option-value',
- description: 'description text (optional)',
- type: 'string',
- mode: 'normal',
- tab: 'general',
- };
- */
- /*
- <div class="interface-ui">
- <div class="tabs-ui tabs-ui-active">
- <div class="tab-ui tab-ui-active" data-name="{tabUI.name}">
- <div class="tab-ui-label">
- <span>{tabUI.label}</span>
- </div>
- <div class="tab-ui-data">
- <input type="radio" name="file-size" data-key="10G" value="10G" />
- <input type="radio" name="file-size" data-key="1G" value="1G" />
- <input type="radio" name="file-size" data-key="1M" value="1M" />
- <input type="radio" name="file-size" data-key="1Kb" value="1024" />
- <input type="text" name="file-name" value="foo.txt" />
- </div>
- </div>
- <div class="tab-ui"/>
- </div>
- </div>
- */
- function dummy() {}
- function Mode(name = 'normal', label = '', onChange = dummy) {
- let nam;
- Object.defineProperty(this, 'name', {
- get: function() { return nam; },
- set: function(n) {
- try {
- Mode.validateName(n);
- nam = n;
- onChange(null, n);
- } catch (err) {
- onChange(err);
- }
- },
- enumerable: true,
- });
- this.name = name;
- this.label = label || name;
- }
- Object.defineProperties(Mode, {
- 'NORMAL': {
- value: 'normal',
- enumerable: true,
- },
- 'ADVANCED': {
- value: 'advanced',
- enumerable: true,
- },
- 'NAMES': {
- get: function(){
- return [Mode.NORMAL, Mode.ADVANCED];
- },
- enumerable: true,
- },
- });
- Mode.validateName = function(name) {
- switch (name) {
- case Mode.NORMAL:
- case Mode.ADVANCED:
- return true;
- default:
- throw new Error('invalid mode name (' + name + '), valid names = [' + Mode.NAMES.join(', ') + ']');
- }
- };
- Mode.descriptor = {
- get: function() { return this[modeSymbol]; },
- set: function(mode) {
- try {
- Mode.validateName(mode);
- this[modeSymbol] = mode;
- } catch (error) {
- if (typeof this.onChange === 'function') {
- this.onChange(error);
- } else {
- console.error('mode validation: ', error);
- }
- }
- },
- enumerable: true,
- };
- function Datum({
- mode = Mode.NORMAL,
- label,
- key,
- name,
- description,
- onChange = dummy,
- validate = dummy,
- setter = function(v) { return v; },
- } = {}) {
- console.log('new Datum() -> args: ', JSON.stringify(arguments[0], null, 2));
- this.onChange = onChange;
- this.validate = validate;
- this.setter = setter;
- this.label = label;
- this.description = description;
- this.mode = mode;
- Object.defineProperty(this, 'name', { value: name });
- Object.defineProperty(this, 'key', { value: (key || name) });
- }
- Datum.descriptor = {
- get: function(){ return this[valueSymbol]; },
- set: function(val) {
- try {
- this.validate(val);
- this[valueSymbol] = this.setter(val);
- this.onChange(null, this[valueSymbol], val);
- } catch (error) {
- this.onChange(error);
- }
- },
- enumerable: true,
- };
- Object.defineProperty(Datum.prototype, 'mode', extend({}, Mode.descriptor));
- Datum.prototype.toJSON = function() {
- const { mode, name, label, description, key } = this;
- return { mode, name, label, description, key };
- };
- Datum.prototype.assign = function(item, checkName = false) {
- if (!item || item === this) {
- return this;
- }
- const {
- key,
- name,
- validate = this.validate,
- onChange = this.onChange,
- label = this.label,
- description = this.description,
- } = item;
- if (name !== this.name && checkName) {
- throw new Error('In assign (' + this.TYPE + ', name does not match, expected "' + this.name + '", but got "' + name + '"');
- }
- this.validate = validate;
- this.onChange = onChange;
- this.label = label;
- this.description = description;
- return this;
- };
- function Input({
- mode = Mode.NORMAL,
- label,
- name,
- key,
- value,
- description,
- type,
- onChange,
- validate,
- setter,
- } = {}) {
- this.index = Input.index++;
- console.log('new Input() -> args: ', JSON.stringify(arguments[0], null, 2));
- Datum.call(this, { mode, label, name, key, description, onChange, validate, setter });
- Object.defineProperty(this, 'value', extend({}, Datum.descriptor));
- Object.defineProperty(this, 'tag', { value: 'input' });
- let _type;
- Object.defineProperty(this, 'type', {
- get: function(){ return _type; },
- set: function(t) {
- if (Input.TYPES.indexOf(t) === -1) {
- throw new TypeError('invalid input type, expected one of ' + JSON.stringify(Input.TYPES) + ', but got ' + t);
- }
- _type = t;
- },
- enumerable: true,
- });
- this.type = type;
- this.value = value;
- }
- Input.index = 0;
- Input.TYPES = ['number', 'text', 'checkbox', 'date', 'email', 'radio', 'tel', 'time'];
- Object.defineProperty(Input.prototype, 'mode', extend({}, Mode.descriptor));
- Input.parse = function(item){
- if (item instanceof Input) {
- return item;
- }
- if (typeof item === 'object') {
- return new Input(item);
- }
- return new Input();
- };
- Input.prototype.toJSON = function() {
- const { value, type } = this;
- return extend({ value, type }, Datum.prototype.toJSON.call(this));
- };
- Input.prototype.toHTML = function() {
- const div = document.createElement('div');
- const elem = document.createElement('input');
- elem.setAttribute('type', this.type);
- elem.setAttribute('value', this.value);
- elem.setAttribute('name', this.name);
- elem.setAttribute('data-key', this.key);
- const id = this.name + '-' + (this.key === this.name ? this.globalIndex : this.key);
- elem.setAttribute('id', id);
- elem.setAttribute('title', this.description);
- div.appendChild(elem);
- return div.firstElementChild;
- };
- Input.prototype.assign = function(item, checkName = false) {
- if (!item || item === this) {
- return this;
- }
- Datum.prototype.assign.call(this, item, checkName);
- const { value = this.value } = item;
- this.value = value;
- return this;
- };
- function Option({
- label,
- name,
- key,
- value,
- description,
- onChange,
- validate,
- setter,
- } = {}) {
- this.globalIndex = Option.index++;
- console.log('new Option() -> args: ', JSON.stringify(arguments[0], null, 2));
- Datum.call(this, { label, name, key, description, onChange, validate, setter });
- Object.defineProperty(this, 'value', extend({}, Datum.descriptor));
- Object.defineProperty(this, 'tag', { value: 'option' });
- this.value = value;
- }
- Object.defineProperty(Option.prototype, 'mode', extend({}, Mode.descriptor));
- Option.parse = function(item){
- if (item instanceof Option) {
- return item;
- }
- if (typeof item === 'object') {
- return new Option(item);
- }
- return new Option();
- };
- Option.prototype.toJSON = function() {
- const { value, type } = this;
- return extend({ value, type }, Datum.prototype.toJSON.call(this));
- };
- Option.index = 0;
- Option.prototype.toHTML = function() {
- const div = document.createElement('div');
- const elem = document.createElement('option');
- elem.setAttribute('value', this.value);
- elem.setAttribute('name', this.name);
- elem.setAttribute('data-key', this.key);
- const id = this.name + '-' + (this.key === this.name ? this.globalIndex : this.key);
- elem.setAttribute('id', id);
- elem.setAttribute('title', this.description);
- div.appendChild(elem);
- return div.firstElementChild;
- };
- Option.prototype.assign = function(item, checkName = false) {
- if (!item || item === this) {
- return this;
- }
- Datum.prototype.assign.call(this, item, checkName);
- const { value = this.value } = item;
- this.value = value;
- return this;
- };
- function List(Item = Input, itemKey = 'name', itemDefaults = {}) {
- Object.defineProperty(this, 'Item', { value: Item });
- this.data = {};
- this.order = [];
- this.itemDefaults = itemDefaults;
- List.validateItemKey(itemKey);
- Object.defineProperty(this, 'itemKey', { value: itemKey });
- }
- List.ITEM_KEYS = ['key', 'name'];
- List.validateItemKey = function(key) {
- if (List.ITEM_KEYS.indexOf(key) === -1) {
- throw new Error('Invalid key property name, expected ' + JSON.stringify(List.ITEM_KEYS) + ', but got ' + key + ' (typeof = ' + typeof key + ')');
- }
- };
- List.prototype.add = function(...data) {
- const { Item, itemKey, itemDefaults } = this;
- for (const datum of data) {
- const item = datum instanceof Item ? datum : new Item(extend({}, itemDefaults, datum));
- const { [itemKey]: name } = item;
- if (this.data[name] || this.order.indexOf(name) !== -1) {
- throw new Error('data already exists, type = "' + Item.name + '", name = "' + name + '"');
- }
- this.data[name] = item;
- this.order.push(name);
- }
- };
- List.prototype.update = function(datum) {
- if (!datum || typeof datum !== 'object') {
- return;
- }
- const { Item, itemKey } = this;
- const { [itemKey]: name } = datum;
- const item = this.data[name];
- if (item instanceof Item) {
- item.assign(datum);
- }
- };
- List.prototype.remove = function(name = '') {
- if (!name) {
- return;
- }
- const { Item } = this;
- const item = this.data[name];
- const index = this.order.indexOf(name);
- if (item) {
- delete this.data[name];
- }
- if (index !== -1) {
- this.order.splice(index, 1);
- }
- };
- List.prototype.setValue = function(name = '', value) {
- const { Item } = this;
- const item = this.data[name];
- if (item instanceof Item) {
- item.value = value;
- }
- };
- List.prototype.getValue = function(name = '') {
- const { Item } = this;
- const item = this.data[name];
- if (item instanceof Item) {
- return item.value;
- }
- return null;
- };
- List.prototype.assign = function(_list) {
- if (!_list || _list === this) {
- return this;
- }
- if (!(_list instanceof List) && typeof _list !== 'object') {
- return this;
- }
- const {
- data = this.data,
- order = this.order,
- itemKey = this.itemKey,
- itemDefaults = this.itemDefaults,
- } = _list;
- if (order !== this.order && itemKey !== 'key') {
- this.order = [...order];
- }
- if (itemKey !== this.itemKey) {
- this.itemKey = itemKey;
- }
- if (itemDefaults !== this.itemDefaults) {
- this.itemDefaults = itemDefaults;
- }
- if (data !== this.data) {
- this.data = extend({}, data);
- }
- return this;
- };
- List.parse = function(elem) {
- if (elem instanceof List) {
- return elem;
- }
- if (typeof elem === 'object') {
- let Item;
- switch (elem.itemType) {
- case 'Datum':
- Item = Datum;
- break;
- case 'Input':
- Item = Input;
- break;
- case 'Radio':
- Item = Radio;
- break;
- case 'Option':
- Item = Option;
- break;
- case 'Tab':
- Item = Tab;
- break;
- case 'TabItem':
- Item = TabItem;
- break;
- case 'List':
- Item = List;
- break;
- case 'Mode':
- Item = Mode;
- break;
- case 'Select':
- Item = Select;
- break;
- default:
- throw new TypeError('Invalid itemType (' + itemType + ', ' + typeof itemType + ')');
- }
- const { itemKey, itemDefaults, data = {}, order = [] } = elem;
- const list = new List(Item, itemKey, itemDefaults);
- for (const key of order) {
- list.add(data[key]);
- }
- return list;
- }
- return new List();
- };
- List.prototype.toJSON = function() {
- const { data, order, itemKey, itemDefaults, Item } = this;
- return { data, order, itemKey, itemDefaults, itemType: Item.name };
- };
- function Radio({ mode, label, description, name, value, onChange, validate, setter } = {}) {
- Datum.call(this, { mode, label, description, name, onChange, validate, setter });
- Object.defineProperty(this, 'value', Datum.descriptor);
- List.call(this, Input, 'key', {
- type: 'radio',
- name: this.name,
- mode: this.mode,
- validate: this.validate,
- setter: this.setter,
- });
- }
- Object.defineProperty(Radio.prototype, 'mode', Mode.descriptor);
- for (const fn of ['add', 'update', 'remove', 'setValue', 'getValue']) {
- Radio.prototype[fn] = function(...args) {
- return List.prototype[fn].apply(this, args);
- };
- }
- Radio.prototype.changeItem = function(itemValue) {
- const { Item, itemDefaults } = this;
- console.log('------ itemDefaults: ', JSON.stringify(itemDefaults, null, 2));
- console.log('changeItem: ', itemValue);
- let error;
- const elem = new Item(extend({}, itemDefaults, {
- value: itemValue,
- onChange: function(err){
- error = err;
- },
- }));
- console.log('changeItem -> elem: ', JSON.stringify(elem, null, 2));
- if (error) {
- console.log('In changeItem, ', error);
- return;
- }
- console.log('changeItem -> item: ', JSON.stringify(elem, null, 2));
- for (const key of this.order) {
- const item = this.data[key];
- console.log('[' + key + ']: ', JSON.stringify(item, null, 2));
- if (item.value === elem.value) {
- this.value = itemValue;
- console.log('-------------------- found');
- break;
- }
- }
- };
- Radio.prototype.assign = function(radio) {
- if (!radio || radio === this) {
- return this;
- }
- if (radio instanceof Radio || typeof radio === 'object') {
- const { value = this.value } = radio;
- this.value = value;
- }
- Datum.prototype.assign.call(this, radio);
- List.prototype.assign.call(this, radio);
- return this;
- };
- Radio.parse = function(elem) {
- if (elem instanceof Radio) {
- return elem;
- }
- if (typeof elem === 'object') {
- const radio = new Radio(elem);
- const { data = {}, order = [] } = elem;
- for (const key of order) {
- radio.add(data[key]);
- }
- return radio;
- }
- return new Radio();
- };
- Radio.prototype.toJSON = function() {
- const { value } = this;
- return extend(
- { value, type: 'radio' },
- Datum.prototype.toJSON.call(this),
- List.prototype.toJSON.call(this),
- );
- };
- function Select({ mode, label, description, name, value, onChange, validate, setter } = {}) {
- Datum.call(this, { mode, label, description, name, onChange, validate, setter });
- Object.defineProperty(this, 'value', Datum.descriptor);
- List.call(this, Option, 'key', {
- name: this.name,
- mode: this.mode,
- validate: this.validate,
- setter: this.setter,
- });
- }
- Object.defineProperty(Select.prototype, 'mode', Mode.descriptor);
- for (const fn of ['add', 'update', 'remove', 'setValue', 'getValue']) {
- Radio.prototype[fn] = function(...args) {
- return List.prototype[fn].apply(this, args);
- };
- }
- Select.prototype.changeItem = function(itemValue) {
- const { Item, itemDefaults } = this;
- console.log('------ itemDefaults: ', JSON.stringify(itemDefaults, null, 2));
- console.log('changeItem: ', itemValue);
- let error;
- const elem = new Item(extend({}, itemDefaults, {
- value: itemValue,
- onChange: function(err){
- error = err;
- },
- }));
- console.log('changeItem -> elem: ', JSON.stringify(elem, null, 2));
- if (error) {
- console.log('changeItem -> elem: ', JSON.stringify(elem, null, 2));
- return;
- }
- console.log('changeItem -> item: ', JSON.stringify(elem, null, 2));
- for (const key of this.order) {
- const item = this.data[key];
- console.log('[' + key + ']: ', JSON.stringify(item, null, 2));
- if (item.value === elem.value) {
- this.value = itemValue;
- console.log('-------------------- found');
- break;
- }
- }
- };
- Select.prototype.assign = function(elem) {
- if (!elem || elem === this) {
- return this;
- }
- if (elem instanceof Select || typeof elem === 'object') {
- const { value = this.value } = elem;
- this.value = value;
- }
- Datum.prototype.assign.call(this, elem);
- List.prototype.assign.call(this, elem);
- return this;
- };
- Select.parse = function(elem) {
- if (elem instanceof Select) {
- return elem;
- }
- if (typeof elem === 'object') {
- const select = new Select(elem);
- const { data = {}, order = [] } = elem;
- for (const key of order) {
- select.add(data[key]);
- }
- return select;
- }
- return new Select();
- };
- Select.prototype.toJSON = function() {
- const { value } = this;
- return extend(
- { value, type: 'select' },
- Datum.prototype.toJSON.call(this),
- List.prototype.toJSON.call(this),
- );
- };
- const list = new List();
- const onChange = function(error, value) {
- if (error) {
- console.log('error occured while setting value, ', error);
- return;
- }
- console.log('next value: ', value);
- };
- onChange.toJSON = fn.toJSON;
- const validate = function(value) {
- let match;
- switch (typeof value) {
- case 'undefined':
- case 'number':
- break;
- case 'string':
- match = value.trim().match(/^(\d+(?:\.\d+)?)\s?(k|m|g|t)?b?/i);
- if (match && match[1]) break;
- default:
- throw new TypeError('invalid value');
- }
- };
- validate.toJSON = fn.toJSON;
- const setter = function(value) {
- let match;
- switch (typeof value) {
- case 'string':
- match = value.trim().match(/^(\d+(?:\.\d+)?)\s?(k|m|g|t)?b?/i);
- return +match[1] * Math.pow(1024, match[2] ? ['', 'k', 'm', 'g', 't'].indexOf(match[2].toLowerCase()) : undefined);
- case 'number':
- return value;
- default:
- throw new TypeError('invalid value');
- }
- };
- setter.toJSON = fn.toJSON;
- const input = new Input({
- name: 'file-size',
- label: 'File size (bytes)',
- description: 'Here is size of uploaded file in bytes',
- value: 1023,
- key: '1G',
- type: 'radio',
- onChange,
- validate,
- setter,
- });
- list.add(input);
- console.log('item: ', JSON.stringify(input, null, 2));
- console.log('list: ', JSON.stringify(list, null, 2));
- list.setValue('file-size', '1 GB');
- console.log('item.value: ', input.value);
- const radio = new Radio({ name: 'file-size', value: '1G', onChange, validate, setter });
- radio.add(input);
- radio.add(new Input({
- name: 'file-size',
- key: '10MB',
- label: 'File size (bytes)',
- value: '10 MB',
- type: 'radio',
- onChange,
- validate,
- setter,
- }));
- radio.changeItem('10MB');
- radio.value;
- console.log('radio: ', JSON.stringify(radio, null, 2));
- function TabItem({
- mode, type, name, label, description, value, onChange, validate, setter,
- } = {}) {
- let Item;
- switch (type) {
- case 'radio':
- Item = Radio;
- break;
- case 'select':
- Item = Select;
- break;
- default:
- Item = Input;
- }
- Object.defineProperty(this, 'Class', { value: Item });
- this.Class.call(this, arguments[0]);
- }
- Object.defineProperty(TabItem.prototype, 'mode', Mode.descriptor);
- TabItem.prototype.assign = function() {
- return this.Class.prototype.assign.apply(this, arguments);
- };
- TabItem.parse = function(elem) {
- if (elem instanceof Option) {
- return elem;
- }
- if (typeof elem !== 'object') {
- return new Option();
- }
- const { type } = elem;
- if (type === 'radio') {
- const opt = new TabItem(elem);
- const { data = {}, order = [] } = elem;
- for (const key of order) {
- opt.add(data[key]);
- }
- return opt;
- }
- return new TabItem(elem);
- };
- TabItem.prototype.toJSON = function() {
- return this.Class.prototype.toJSON.apply(this, arguments);
- };
- for (const fn of ['add', 'update', 'remove', 'setValue', 'getValue', 'changeItem']) {
- TabItem.prototype[fn] = function() {
- if (this.Class === Radio) {
- return Radio.prototype[fn].apply(this, arguments);
- }
- };
- }
- const opt = new TabItem({ mode: Mode.ADVANCED, type: 'radio', name: 'file-size', value: '10.5 MB', onChange, validate, setter });
- opt.add({
- key: '1MB', value: '1MB',
- }, {
- key: '2MB', value: '2MB',
- }, {
- key: '1Gb', value: '1GB',
- }, {
- key: '2KB', value: '2K',
- });
- opt.changeItem('2kb');
- console.log('================== value: ', opt.value);
- const opt2 = new TabItem({ mode: Mode.ADVANCED, type: 'text', name: 'file-name', value: 'my_file.txt', onChange });
- console.log('================== opt2: ', JSON.stringify(opt2, null, 2));
- console.log('================== opt: ', JSON.stringify(opt, null, 2));
- opt2.value = 'my_file_xxx.out';
- console.log('================== opt2: ', JSON.stringify(opt2, null, 2));
- const json = JSON.stringify({ setter }, null, 2);
- console.log('{ setter }: ', json);
- const parsed = JSON.parse(json, reviver);
- console.log('parsed.setter: ', parsed.setter);
- try {
- if (1024 === parsed.setter('1Kb')) {
- console.log('PASSED');
- } else {
- console.log('FAILED');
- }
- } catch (err) {
- console.log('setter error: ', err);
- }
- const optJson = JSON.stringify(opt2, null, 2);
- const parsedOpt = JSON.parse(optJson, reviver);
- const opt3 = TabItem.parse(parsedOpt);
- console.log('opt3: ', opt3);
- function Tab({ name, key, label, description } = {}) {
- this.name = name;
- this.key = key || name;
- this.label = label;
- this.description = description;
- List.call(this, TabItem);
- }
- for (const fn of ['add', 'update', 'remove', 'setValue', 'getValue']) {
- Tab.prototype[fn] = function() {
- return List.prototype[fn].apply(this, arguments);
- };
- }
- Tab.prototype.assign = function(elem) {
- throw new Error('TODO');
- }; // TODO
- Tab.prototype.toJSON = function() {
- const { name, key, label, description } = this;
- return extend({
- name, key, label, description,
- }, List.prototype.toJSON.call(this));
- };
- Tab.parse = function(elem) {
- if (elem instanceof Tab) {
- return elem;
- }
- if (typeof elem !== 'object') {
- return new Tab();
- }
- const tb = new Tab(elem);
- const { data = {}, order = [] } = elem;
- for (const key of order) {
- tb.add(data[key]);
- }
- return tb;
- };
- const tab = new Tab({ name: 'general', label: 'General', description: 'Here are general options' });
- tab.add({ name: 'file-owner', type: 'text', value: 'Enakin Skywalker' });
- tab.add({ name: 'file-size', type: 'radio', value: '1Mb', validate, setter });
- tab.data['file-size'].add({
- key: '1Mb', value: '1M',
- }, {
- key: '10Mb', value: '10M',
- }, {
- key: '1Gb', value: '1GB',
- });
- const tabJson = JSON.stringify(tab, null, 2);
- console.log('tab: ', tabJson);
- const tab2 = Tab.parse(JSON.parse(tabJson, reviver));
- console.log('tab2: ', tab2);
- function Interface({
- mode: modeName = Mode.NORMAL, title = 'Interface', version = '0.1.0', onChangeMode = function(){},
- } = {}) {
- const mode = new Mode(modeName, null, onChangeMode);
- Object.defineProperty(this, 'mode', {
- get: function() { return mode.name; },
- set: function(n) { mode.name = n; },
- enumerable: true,
- });
- this.title = title;
- this.version = version;
- this.onChangeMode = onChangeMode;
- List.call(this, Tab);
- }
- for (const fn of ['add', 'update', 'remove']) {
- Interface.prototype[fn] = function() {
- return List.prototype[fn].apply(this, arguments);
- };
- }
- Interface.prototype.toJSON = function() {
- const { mode, title, version } = this;
- return extend({
- mode, title, version,
- }, List.prototype.toJSON.call(this));
- };
- Interface.parse = function(elem) {
- if (elem instanceof Interface) {
- return elem;
- }
- if (typeof elem !== 'object') {
- return new Interface();
- }
- const intf = new Interface(elem);
- const { data = {}, order = [] } = elem;
- for (const key of order) {
- intf.add(data[key]);
- }
- return intf;
- };
- const iface = new Interface({
- onChangeMode: function(error, mode) {
- if (error) {
- console.log('onChangeMode: ', error);
- return;
- }
- console.log('new mode: ', mode);
- },
- });
- iface.add(tab);
- tab2.name = 'advanced';
- iface.add(tab2);
- const ifaceJson = JSON.stringify(iface, null, 2);
- console.log('interface: ', ifaceJson);
- const iface2 = Interface.parse(JSON.parse(ifaceJson));
- console.log('interface2: ', iface2);
- function extend(target) {
- target = target || {};
- const args = Array.prototype.slice.call(arguments, 1);
- for (const arg of args) {
- for (const key of Object.keys(arg)) {
- target[key] = arg[key];
- }
- }
- return target;
- }
- const { ESModules = {} } = window;
- ESModules.UIModules = {
- Mode,
- Datum,
- Input,
- Option,
- List,
- Radio,
- Select,
- Tab,
- TabItem,
- Interface,
- functionToJSON: fn.toJSON,
- functionReviver: reviver,
- memoryValidator: validate,
- memorySetter: setter,
- };
- window.ESModules = ESModules;
- })(window)
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址