reorganizing file structures;
This commit is contained in:
306
src/lib/autoComplete.js
Normal file
306
src/lib/autoComplete.js
Normal file
@@ -0,0 +1,306 @@
|
||||
class autoComplete {
|
||||
options;
|
||||
static UP = 38;
|
||||
static DOWN = 40;
|
||||
static ENTER = 13;
|
||||
static ESC = 27;
|
||||
static entryClass = ".suggestion-item";
|
||||
static entryClassContainer = ".suggestion-container";
|
||||
constructor(options) {
|
||||
this.options = {
|
||||
selector: 0,
|
||||
source: 0,
|
||||
minChars: 3,
|
||||
delay: 150,
|
||||
offsetLeft: 0,
|
||||
offsetTop: 1,
|
||||
cache: 1,
|
||||
menuClass: '',
|
||||
renderItem: function (item, search) {
|
||||
search = search.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
||||
var re = new RegExp(`(${search.split(' ').join('|')})`, "gi");
|
||||
return `<div class="suggestion-item" data-val="${item}">${item.replace(re, "<b>$1</b>")}</div>`;
|
||||
},
|
||||
onSelect: function (e, term, item) { }
|
||||
};
|
||||
for (let k in this.options) {
|
||||
if (options.hasOwnProperty(k)) this.options[k] = options[k];
|
||||
}
|
||||
if (typeof this.options.selector !== 'string' && !(this.options.selector instanceof NodeList))
|
||||
throw ("invalid selecor!");
|
||||
this.elements = typeof this.options.selector == 'object' ? this.options.selector : document.querySelectorAll(this.options.selector);
|
||||
}
|
||||
static getInstance(options) {
|
||||
return new autoComplete(options);
|
||||
}
|
||||
attachData(element) {
|
||||
element.rect = element.getBoundingClientRect();
|
||||
element.sgBox = this.createSuggestionBox();
|
||||
element.options = this.options;
|
||||
}
|
||||
run() {
|
||||
for (const element of this.elements) {
|
||||
this.init(element);
|
||||
}
|
||||
}
|
||||
|
||||
init(element) {
|
||||
element.autocompleteAttr = element.getAttribute('autocomplete');
|
||||
element.setAttribute('autocomplete', 'off');
|
||||
element.cache = {};
|
||||
element.lastValue = '';
|
||||
this.attachData(element);
|
||||
this.attach('resize', window, function (e) {
|
||||
autoComplete.updateSuggestionBox(element);
|
||||
});
|
||||
document.body.appendChild(element.sgBox);
|
||||
this.live('suggestion-item', 'mouseleave', function (e) {
|
||||
var sel = element.sgBox.querySelector('.suggestion-item.selected');
|
||||
if (sel)
|
||||
setTimeout(function () { sel.className = sel.className.replace('selected', ''); }, 20);
|
||||
}, element.sgBox);
|
||||
|
||||
this.live('suggestion-item', 'mouseover', function (e) {
|
||||
var sel = element.sgBox.querySelector('.suggestion-item.selected');
|
||||
if (sel) {
|
||||
sel.classList.remove("selected");
|
||||
}
|
||||
this.className += ' selected';
|
||||
}, element.sgBox);
|
||||
const selectHandler = function (selected, element, e) {
|
||||
if (autoComplete.hasClass(selected, 'suggestion-item')) {
|
||||
let v = selected.getAttribute('data-val');
|
||||
element.value = v;
|
||||
element.options.onSelect(e, v, selected);
|
||||
element.sgBox.style.display = 'none';
|
||||
}
|
||||
}
|
||||
this.live('suggestion-item', 'mousedown,pointerdown', function (e) {
|
||||
e.stopPropagation();
|
||||
//this refers to the found element within;
|
||||
let selected = this;
|
||||
selectHandler(selected, element, e);
|
||||
}, element.sgBox);
|
||||
|
||||
this.attach('blur', element, autoComplete.blurCallback);
|
||||
this.attach('keydown', element, autoComplete.keyDownCallback);
|
||||
this.attach('keyup', element, autoComplete.keyUpCallback);
|
||||
if (!this.options.minChars)
|
||||
this.attach('focus', element, autoComplete.focusCallback);
|
||||
}
|
||||
static suggest(element, data) {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
let sgBox = element.sgBox, options = element.options;
|
||||
var val = element.value;
|
||||
element.cache[val] = data;
|
||||
if (data.length && val.length >= options.minChars) {
|
||||
var s = '';
|
||||
for (var i = 0; i < data.length; i++) s += options.renderItem(data[i], val);
|
||||
sgBox.innerHTML = s;
|
||||
autoComplete.updateSuggestionBox(element, 0);
|
||||
}
|
||||
else {
|
||||
sgBox.style.display = 'none';
|
||||
}
|
||||
}
|
||||
static hasClass(el, className) {
|
||||
return el.classList ? el.classList.contains(className) : new RegExp('\\b' + className + '\\b').test(el.className);
|
||||
}
|
||||
attach(eventType, target, selector, callback) {
|
||||
if (typeof selector === 'function' && !callback) {
|
||||
callback = selector;
|
||||
selector = target;
|
||||
}
|
||||
if (typeof target === 'object') {
|
||||
if (target.attachEvent) {
|
||||
target.attachEvent('on' + eventType, function (e) {
|
||||
callback.call(target, e);
|
||||
});
|
||||
}
|
||||
else {
|
||||
target.addEventListener(eventType, function (e) {
|
||||
callback.call(target, e);
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
let el = document.querySelector(target);
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
el.addEventListener(eventType, function (e) {
|
||||
let element = e.target;
|
||||
if (element === this) {
|
||||
callback.call(element, e);
|
||||
return;
|
||||
}
|
||||
for (; element && element != this; element = element.parentNode) {
|
||||
if (element.matches(selector)) {
|
||||
callback.call(element, e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
live(elClass, event, cb, context) {
|
||||
if (typeof event === 'string' && event.indexOf(',')) {
|
||||
var events = event.split(',');
|
||||
}
|
||||
for (const event of events) {
|
||||
this.attach(event, context || document, function (e) {
|
||||
var found, el = e.target || e.srcElement;
|
||||
while (el && !(found = autoComplete.hasClass(el, elClass)))
|
||||
el = el.parentElement;
|
||||
if (found) cb.call(el, e);
|
||||
});
|
||||
}
|
||||
}
|
||||
static blurCallback(e) {
|
||||
let element = this
|
||||
let sgBox = element.sgBox;
|
||||
let hoverActive;
|
||||
try {
|
||||
hoverActive = document.querySelector('.suggestion-container:hover');
|
||||
} catch (e) {
|
||||
hoverActive = 0;
|
||||
}
|
||||
if (!hoverActive) {
|
||||
element.lastValue = element.value;
|
||||
sgBox.style.display = 'none';
|
||||
setTimeout(function () { sgBox.style.display = 'none'; }, 350);
|
||||
} else if (element !== document.activeElement) {
|
||||
setTimeout(function () {
|
||||
element.focus();
|
||||
}, 20);
|
||||
}
|
||||
}
|
||||
static keyUpCallback(e) {
|
||||
let element = this;
|
||||
let sgBox = element.sgBox, options = element.options;
|
||||
var key = window.event ? e.keyCode : e.which;
|
||||
if (!key || (key < 35 || key > 40) && ![autoComplete.ENTER, autoComplete.ESC].includes(key)) {
|
||||
var val = element.value;
|
||||
if (val.length >= options.minChars) {
|
||||
if (val != element.lastValue) {
|
||||
element.lastValue = val;
|
||||
clearTimeout(element.timer);
|
||||
if (options.cache) {
|
||||
if (val in element.cache) {
|
||||
autoComplete.suggest(element, element.cache[val]); return;
|
||||
}
|
||||
for (var i = 1; i < val.length - options.minChars; i++) {
|
||||
var part = val.slice(0, val.length - i);
|
||||
if (part in element.cache && !element.cache[part].length) {
|
||||
autoComplete.suggest([]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
const msuggest = function (data) {
|
||||
autoComplete.suggest(element, data);
|
||||
}
|
||||
element.timer = setTimeout(function () { options.source(val, msuggest) }, options.delay);
|
||||
}
|
||||
} else {
|
||||
element.lastValue = val;
|
||||
sgBox.style.display = 'none';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static keyDownCallback(e) {
|
||||
let element = this;
|
||||
let sgBox = element.sgBox, options = element.options;
|
||||
var key = window.event ? e.keyCode : e.which;
|
||||
// down =40, up =38
|
||||
if ((key == 40 || key == 38) && sgBox.innerHTML) {
|
||||
var next, sel = sgBox.querySelector('.suggestion-item.selected');
|
||||
if (!sel) {
|
||||
next = (key == 40) ? sgBox.querySelector('.suggestion-item') : sgBox.childNodes[scBox.childNodes.length - 1]; // first : last
|
||||
next.className += ' selected';
|
||||
element.value = next.getAttribute('data-val');
|
||||
} else {
|
||||
next = (key == 40) ? sel.nextSibling : sel.previousSibling;
|
||||
if (next) {
|
||||
sel.className = sel.className.replace('selected', '');
|
||||
next.className += ' selected';
|
||||
element.value = next.getAttribute('data-val');
|
||||
}
|
||||
else {
|
||||
sel.className = sel.className.replace('selected', '');
|
||||
element.value = element.lastValue; next = 0;
|
||||
}
|
||||
}
|
||||
autoComplete.updateSuggestionBox(element, 0, next);
|
||||
return false;
|
||||
//ESC = 27
|
||||
} else if (key == 27) {
|
||||
element.value = element.lastValue;
|
||||
sgBox.style.display = 'none';
|
||||
//enter = 13,tab = 9
|
||||
} else if (key == 13 || key == 9) {
|
||||
var sel = sgBox.querySelector('.suggestion-item.selected');
|
||||
if (sel && sgBox.style.display != 'none') {
|
||||
options.onSelect(e, sel.getAttribute('data-val'), sel);
|
||||
setTimeout(function () { sgBox.style.display = 'none'; }, 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static focusCallback(e) {
|
||||
let element = this;
|
||||
element.lastValue = '\n';
|
||||
autoComplete.keyUpCallback(e)
|
||||
}
|
||||
|
||||
static getMaxHeight(element) {
|
||||
let style = window.getComputedStyle ? getComputedStyle(element, null) : element.currentStyle;
|
||||
return parseInt(style.maxHeight);
|
||||
}
|
||||
|
||||
static updatePosition(element, rect, options) {
|
||||
element.style.left = Math.round(rect.left + (window.pageXOffset || document.documentElement.scrollLeft) + options.offsetLeft) + 'px';
|
||||
element.style.top = Math.round(rect.bottom + (window.pageYOffset || document.documentElement.scrollTop) + options.offsetTop) + 'px';
|
||||
element.style.width = Math.round(rect.right - rect.left) + 'px';
|
||||
}
|
||||
|
||||
static updateSuggestionBox(element, resize, next) {
|
||||
let sgBox = element.sgBox, rect = element.getBoundingClientRect(), options = element.options;
|
||||
autoComplete.updatePosition(sgBox, rect, options);
|
||||
if (resize && !next) {
|
||||
return;
|
||||
}
|
||||
sgBox.style.display = 'block';
|
||||
if (!sgBox.maxHeight) {
|
||||
sgBox.maxHeight = autoComplete.getMaxHeight(sgBox);
|
||||
}
|
||||
if (!sgBox.suggestionHeight) {
|
||||
sgBox.suggestionHeight = sgBox.querySelector('.suggestion-item').offsetHeight;
|
||||
}
|
||||
|
||||
if (!sgBox.suggestionHeight) {
|
||||
return;
|
||||
}
|
||||
if (!next) {
|
||||
sgBox.scrollTop = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
let scrTop = sgBox.scrollTop
|
||||
let selTop = next.getBoundingClientRect().top - sgBox.getBoundingClientRect().top;
|
||||
if (selTop + sgBox.suggestionHeight - sgBox.maxHeight > 0) {
|
||||
sgBox.scrollTop = selTop + sgBox.suggestionHeight + scrTop - sgBox.maxHeight;
|
||||
} else if (selTop < 0) {
|
||||
sgBox.scrollTop = selTop + scrTop;
|
||||
}
|
||||
}
|
||||
createSuggestionBox() {
|
||||
let sgBox = document.createElement('div');
|
||||
sgBox.classList.add('suggestion-container');
|
||||
//suggestionBox.classList.add(options.menuClass);
|
||||
return sgBox;
|
||||
}
|
||||
}
|
||||
export default autoComplete;
|
||||
42
src/lib/eventHandler.js
Normal file
42
src/lib/eventHandler.js
Normal file
@@ -0,0 +1,42 @@
|
||||
const eventHandler = {
|
||||
add: function (eventType, target, selector, callback) {
|
||||
if (typeof selector === 'function' && !callback) {
|
||||
callback = selector;
|
||||
selector = target;
|
||||
}
|
||||
if (typeof target === 'object') {
|
||||
if (target.attachEvent) {
|
||||
target.attachEvent('on' + eventType, function (e) {
|
||||
callback.call(target, e);
|
||||
});
|
||||
}
|
||||
else {
|
||||
target.addEventListener(eventType, function (e) {
|
||||
callback.call(target, e);
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
let el = document.querySelector(target);
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
el.addEventListener(eventType, function (e) {
|
||||
let element = e.target;
|
||||
if (element === this && selector === target) {
|
||||
callback.call(element, e);
|
||||
return;
|
||||
}
|
||||
for (; element && element != this; element = element.parentNode) {
|
||||
if (element.matches(selector)) {
|
||||
callback.call(element, e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
off: function (element, eventType, callback) {
|
||||
element.removeEventListener(eventType, callback);
|
||||
}
|
||||
}
|
||||
export default eventHandler;
|
||||
67
src/lib/http.js
Normal file
67
src/lib/http.js
Normal file
@@ -0,0 +1,67 @@
|
||||
const Http = class {
|
||||
data;
|
||||
constructor(url) {
|
||||
this.url = url;
|
||||
this.method = 'POST';
|
||||
this.data = null;
|
||||
this.dataType = 'application/json';
|
||||
this.xhr = new XMLHttpRequest();
|
||||
}
|
||||
static getInstance(url) {
|
||||
return new Http(url);
|
||||
}
|
||||
setData(data) {
|
||||
this.data = data
|
||||
return this
|
||||
}
|
||||
setDataType($value) {
|
||||
this.dataType = $value;
|
||||
}
|
||||
send() {
|
||||
let token = this.getToken();
|
||||
this.xhr.open(this.method, this.url);
|
||||
this.xhr.setRequestHeader('requesttoken', token)
|
||||
this.xhr.setRequestHeader('OCS-APIREQUEST', 'true')
|
||||
if (this.dataType)
|
||||
this.xhr.setRequestHeader('Content-Type', this.dataType);
|
||||
let callback = this.handler;
|
||||
this.xhr.onload = () => {
|
||||
if (typeof callback === 'function')
|
||||
callback(JSON.parse(this.xhr.response));
|
||||
}
|
||||
this.xhr.onerror = this.errorHandler;
|
||||
this.xhr.send(JSON.stringify(this.data));
|
||||
}
|
||||
getToken() {
|
||||
return document.getElementsByTagName('head')[0].getAttribute('data-requesttoken')
|
||||
}
|
||||
setUrl(url) {
|
||||
this.url = url
|
||||
return this
|
||||
}
|
||||
setMethod(method) {
|
||||
this.method = method
|
||||
return this
|
||||
}
|
||||
setHandler(handler) {
|
||||
this.handler = handler || function (data) { };
|
||||
return this;
|
||||
}
|
||||
setErrorHandler(handler) {
|
||||
this.errorHandler = handler
|
||||
return this;
|
||||
}
|
||||
upload(file) {
|
||||
const fd = new FormData();
|
||||
this.xhr.open(this.method, this.url, true);
|
||||
let callback = this.handler;
|
||||
this.xhr.onload = () => {
|
||||
if (typeof callback === 'function')
|
||||
callback(JSON.parse(this.xhr.response));
|
||||
}
|
||||
fd.append('torrentfile', file);
|
||||
return this.xhr.send(fd);
|
||||
}
|
||||
}
|
||||
|
||||
export default Http
|
||||
120
src/lib/msg.js
Normal file
120
src/lib/msg.js
Normal file
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* A little class to manage a status field for a "saving" process.
|
||||
* It can be used to display a starting message (e.g. "Saving...") and then
|
||||
* replace it with a green success message or a red error message.
|
||||
*
|
||||
*
|
||||
*/
|
||||
export default {
|
||||
/**
|
||||
* Displayes a "Saving..." message in the given message placeholder
|
||||
*
|
||||
* @param {Object} selector Placeholder to display the message in
|
||||
*/
|
||||
startSaving(selector) {
|
||||
this.startAction(selector, t('core', 'Saving …'))
|
||||
},
|
||||
|
||||
/**
|
||||
* Displayes a custom message in the given message placeholder
|
||||
*
|
||||
* @param {Object} selector Placeholder to display the message in
|
||||
* @param {string} message Plain text message to display (no HTML allowed)
|
||||
*/
|
||||
startAction(selector, message) {
|
||||
let el = document.querySelector(selector);
|
||||
el.textContent = message;
|
||||
el.style.removeProperty("display")
|
||||
},
|
||||
|
||||
/**
|
||||
* Displayes an success/error message in the given selector
|
||||
*
|
||||
* @param {Object} selector Placeholder to display the message in
|
||||
* @param {Object} response Response of the server
|
||||
* @param {Object} response.data Data of the servers response
|
||||
* @param {string} response.data.message Plain text message to display (no HTML allowed)
|
||||
* @param {string} response.status is being used to decide whether the message
|
||||
* is displayed as an error/success
|
||||
*/
|
||||
finishedSaving(selector, response) {
|
||||
this.finishedAction(selector, response)
|
||||
},
|
||||
|
||||
/**
|
||||
* Displayes an success/error message in the given selector
|
||||
*
|
||||
* @param {Object} selector Placeholder to display the message in
|
||||
* @param {Object} response Response of the server
|
||||
* @param {Object} response.data Data of the servers response
|
||||
* @param {string} response.data.message Plain text message to display (no HTML allowed)
|
||||
* @param {string} response.status is being used to decide whether the message
|
||||
* is displayed as an error/success
|
||||
*/
|
||||
finishedAction(selector, response) {
|
||||
if (response.status === 'success') {
|
||||
this.finishedSuccess(selector, response.data.message)
|
||||
} else {
|
||||
this.finishedError(selector, response.data.message)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Displayes an success message in the given selector
|
||||
*
|
||||
* @param {Object} selector Placeholder to display the message in
|
||||
* @param {string} message Plain text success message to display (no HTML allowed)
|
||||
*/
|
||||
finishedSuccess(selector, message) {
|
||||
let el = document.querySelector(selector);
|
||||
el.textContent = message;
|
||||
if (el.classList.contains("error")) el.classList.remove("error");
|
||||
el.classList.add("success");
|
||||
this.fadeOut(el);
|
||||
},
|
||||
|
||||
/**
|
||||
* Displayes an error message in the given selector
|
||||
*
|
||||
* @param {Object} selector Placeholder to display the message in
|
||||
* @param {string} message Plain text error message to display (no HTML allowed)
|
||||
*/
|
||||
finishedError(selector, message) {
|
||||
let el = document.querySelector(selector);
|
||||
el.textContent = message;
|
||||
if (el.classList.contains("success")) el.classList.remove("success");
|
||||
el.classList.add("error");
|
||||
},
|
||||
fadeIn(element, duration = 1000) {
|
||||
(function increment() {
|
||||
element.style.opacity = String(0);
|
||||
element.style.removeProperty("display")
|
||||
let opacity = parseFloat(element.style.opacity);
|
||||
if (opacity !== 1) {
|
||||
setTimeout(() => {
|
||||
increment(opacity + 0.1);
|
||||
}, duration / 10);
|
||||
}
|
||||
})();
|
||||
},
|
||||
|
||||
fadeOut(element, duration = 1000) {
|
||||
let opacity = parseFloat(element.style.opacity) || 1;
|
||||
(function decrement() {
|
||||
if ((opacity -= 0.1) < 0) {
|
||||
element.style.display = 'none'
|
||||
element.style.removeProperty('opacity');
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
decrement();
|
||||
}, duration / 10);
|
||||
}
|
||||
})();
|
||||
},
|
||||
show(el) {
|
||||
el.style.display = '';
|
||||
},
|
||||
hide(el) {
|
||||
el.style.display = 'none';
|
||||
}
|
||||
}
|
||||
154
src/lib/ncTable.js
Normal file
154
src/lib/ncTable.js
Normal file
@@ -0,0 +1,154 @@
|
||||
import helper from '../utils/helper'
|
||||
import { translate as t, translatePlural as n } from '@nextcloud/l10n'
|
||||
|
||||
class ncTable {
|
||||
actionLink = true;
|
||||
bodyClass = "ncdownloader-table-data";
|
||||
rowClass = "table-row";
|
||||
headingClass = "table-heading";
|
||||
cellClass = "table-cell";
|
||||
//this is the parent element the table is going to append to
|
||||
tableContainer = 'ncdownloader-table-wrapper';
|
||||
numRow;
|
||||
table;
|
||||
|
||||
constructor(heading, rows) {
|
||||
this.table = document.getElementById(this.tableContainer);
|
||||
if (heading && rows) {
|
||||
this.table.innerHTML = '';
|
||||
this.rows = rows;
|
||||
this.heading = heading;
|
||||
this.actionButtons = [];
|
||||
}
|
||||
}
|
||||
static getInstance(heading, row) {
|
||||
return new ncTable(heading, row);
|
||||
}
|
||||
create() {
|
||||
let thead = this.createHeading()
|
||||
let tbody = this.createRow();
|
||||
this.table.appendChild(thead);
|
||||
this.table.appendChild(tbody);
|
||||
return this;
|
||||
}
|
||||
clear() {
|
||||
this.table.innerHTML = '';
|
||||
}
|
||||
loading() {
|
||||
let htmlStr = '<div class="text-center"><div class="spinner-border" role="status"> <span class="visually-hidden">Loading...</span></div></div>'
|
||||
this.table.innerHTML = htmlStr;
|
||||
return this;
|
||||
}
|
||||
noData() {
|
||||
this.clear();
|
||||
let div = document.createElement('div');
|
||||
div.classList.add("no-items");
|
||||
div.appendChild(document.createTextNode(t("ncdownloader", 'No items')));
|
||||
this.table.appendChild(div);
|
||||
}
|
||||
createHeading(prefix = "table-heading") {
|
||||
let thead = document.createElement("section");
|
||||
thead.classList.add(this.headingClass);
|
||||
let headRow = document.createElement("header");
|
||||
headRow.classList.add(this.rowClass);
|
||||
thead.classList.add(this.headingClass);
|
||||
this.heading.forEach(name => {
|
||||
let rowItem = document.createElement("div");
|
||||
rowItem.classList.add(prefix + "-" + name.toLowerCase());
|
||||
rowItem.classList.add(this.cellClass);
|
||||
let text = document.createTextNode(t("ncdownloader", helper.ucfirst(name)));
|
||||
rowItem.appendChild(text);
|
||||
headRow.appendChild(rowItem);
|
||||
})
|
||||
thead.appendChild(headRow);
|
||||
return thead;
|
||||
}
|
||||
createRow() {
|
||||
let tbody = document.createElement("section");
|
||||
tbody.classList.add(this.bodyClass);
|
||||
tbody.classList.add("table-body");
|
||||
let row;
|
||||
for (const element of this.rows) {
|
||||
if (element === null) {
|
||||
continue;
|
||||
}
|
||||
row = document.createElement("div");
|
||||
row.classList.add(this.rowClass);
|
||||
let text;
|
||||
for (let key in element) {
|
||||
if (key.substring(0, 4) == 'data') {
|
||||
let name = key.replace("_", "-");
|
||||
row.setAttribute(name, element[key]);
|
||||
row.setAttribute("id", element[key]);
|
||||
continue;
|
||||
}
|
||||
let rowItem = document.createElement("div");
|
||||
rowItem.classList.add(this.cellClass);
|
||||
if (key === 'actions') {
|
||||
rowItem.classList.add([this.cellClass, "action-item"].join("-"));
|
||||
let container = document.createElement("div");
|
||||
container.classList.add("button-container");
|
||||
element[key].forEach(value => {
|
||||
if (!value.name) {
|
||||
return;
|
||||
}
|
||||
let data = value.data || '';
|
||||
container.appendChild(this.createActionButton(value.name, value.path, data));
|
||||
})
|
||||
rowItem.appendChild(container);
|
||||
row.appendChild(rowItem);
|
||||
continue;
|
||||
}
|
||||
if (typeof element[key] === 'object') {
|
||||
let child = element[key];
|
||||
let div;
|
||||
child.forEach(ele => {
|
||||
div = document.createElement('div');
|
||||
if (helper.isHtml(ele)) {
|
||||
div.innerHTML = ele;
|
||||
} else {
|
||||
text = document.createTextNode(ele);
|
||||
div.appendChild(text);
|
||||
}
|
||||
rowItem.appendChild(div);
|
||||
})
|
||||
rowItem.setAttribute("id", [this.cellClass, key].join("-"));
|
||||
row.appendChild(rowItem);
|
||||
continue;
|
||||
}
|
||||
text = document.createTextNode(element[key]);
|
||||
rowItem.appendChild(text);
|
||||
rowItem.setAttribute("id", [this.cellClass, key].join("-"));
|
||||
row.appendChild(rowItem);
|
||||
}
|
||||
tbody.appendChild(row);
|
||||
}
|
||||
return tbody;
|
||||
|
||||
}
|
||||
|
||||
createActionButton(name, path, data) {
|
||||
let button = document.createElement("button");
|
||||
button.classList.add("icon-" + name);
|
||||
button.setAttribute("path", path);
|
||||
button.setAttribute("data", data);
|
||||
if (name == 'refresh') {
|
||||
name = 'Redownload';
|
||||
}
|
||||
button.setAttribute("title", helper.ucfirst(name));
|
||||
return button;
|
||||
}
|
||||
|
||||
createActionCell(cell) {
|
||||
let div = document.createElement("div");
|
||||
let button = document.createElement("button");
|
||||
button.classList.add("icon-more", "action-button");
|
||||
button.setAttribute("id", "action-links-button");
|
||||
div.classList.add("action-item");
|
||||
div.appendChild(button);
|
||||
//div.appendChild(actionLinks);
|
||||
cell.appendChild(div);
|
||||
}
|
||||
}
|
||||
|
||||
export default ncTable;
|
||||
110
src/lib/settingsForm.js
Normal file
110
src/lib/settingsForm.js
Normal file
@@ -0,0 +1,110 @@
|
||||
class settingsForm {
|
||||
parent = "custom-aria2-settings-container";
|
||||
constructor() {
|
||||
|
||||
}
|
||||
static getInstance() {
|
||||
return new this();
|
||||
}
|
||||
create(parent, element) {
|
||||
let label = this._createLabel(element.name, element.id)
|
||||
let input = this._createInput(element);
|
||||
//let saveBtn = this._createSaveBtn(element.id);
|
||||
let cancelBtn = this._createCancelBtn("has-content");
|
||||
let container = this._createContainer(element.id);
|
||||
[label, input, cancelBtn].forEach(ele => {
|
||||
container.appendChild(ele);
|
||||
})
|
||||
let button;
|
||||
if (button = parent.querySelector('button.add-custom-aria2-settings')) {
|
||||
return parent.insertBefore(container, button);
|
||||
}
|
||||
return parent.appendChild(container);
|
||||
}
|
||||
|
||||
createCustomInput(keyId, valueId) {
|
||||
let div = this._createContainer(keyId + "-container")
|
||||
div.appendChild(this._createInput({ id: keyId }));
|
||||
div.appendChild(this._createInput({ id: valueId }));
|
||||
div.appendChild(this._createCancelBtn());
|
||||
return div;
|
||||
}
|
||||
|
||||
createInput(element) {
|
||||
let div = document.createElement("div");
|
||||
div.classList.add(this.parent);
|
||||
/* element.forEach(element => {
|
||||
let label = document.createElement('label');
|
||||
label.setAttribute("for", element.id);
|
||||
let text = document.createTextNode(element.name);
|
||||
label.appendChild(text);
|
||||
div.appendChild(label);
|
||||
// div.appendChild(this._createInput(element));
|
||||
});*/
|
||||
div.appendChild(this._createInput(element));
|
||||
let button = document.createElement("button");
|
||||
//button.setAttribute("type",'button')
|
||||
button.classList.add("icon-close");
|
||||
div.appendChild(button);
|
||||
button = document.createElement("input");
|
||||
button.setAttribute('type', 'button');
|
||||
button.setAttribute('value', 'save');
|
||||
button.setAttribute("data-rel", this.parent);
|
||||
div.appendChild(button);
|
||||
return div;
|
||||
|
||||
}
|
||||
_createContainer(id) {
|
||||
let div = document.createElement("div");
|
||||
div.classList.add(id);
|
||||
return div;
|
||||
}
|
||||
_createCancelBtn(className = '') {
|
||||
let button = document.createElement("button");
|
||||
if (className)
|
||||
button.classList.add(className);
|
||||
//button.setAttribute("type",'button')
|
||||
button.classList.add("icon-close");
|
||||
return button;
|
||||
}
|
||||
_createSaveBtn(id) {
|
||||
let button = document.createElement("input");
|
||||
button.setAttribute('type', 'button');
|
||||
button.setAttribute('value', 'save');
|
||||
button.setAttribute("data-rel", id + "-container");
|
||||
return button;
|
||||
}
|
||||
_createLabel(name, id) {
|
||||
name = name.replace('_', '-');
|
||||
let label = document.createElement("lable");
|
||||
label.setAttribute("for", id);
|
||||
let text = document.createTextNode(name);
|
||||
label.appendChild(text);
|
||||
return label;
|
||||
}
|
||||
_createInput(data) {
|
||||
let input = document.createElement('input');
|
||||
let type = data.type || "text";
|
||||
let placeholder = data.placeholder || '';
|
||||
let value = data.value || placeholder;
|
||||
input.setAttribute('type', type);
|
||||
input.setAttribute('id', data.id);
|
||||
input.setAttribute("name", data.name || data.id);
|
||||
if (type === 'text') {
|
||||
input.setAttribute('value', value);
|
||||
input.setAttribute('placeholder', value);
|
||||
}
|
||||
input.classList.add('form-input-' + type);
|
||||
return input;
|
||||
}
|
||||
|
||||
render(data) {
|
||||
let parent = document.getElementById(this.parent)
|
||||
for (const element of data) {
|
||||
this.create(parent, element)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default settingsForm
|
||||
Reference in New Issue
Block a user