@wxn0brp/db 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CollectionManager.js +119 -0
- package/LICENSE +21 -0
- package/README.md +194 -0
- package/action.js +250 -0
- package/cacheManager.js +83 -0
- package/database.js +208 -0
- package/executor.js +54 -0
- package/file/find.js +88 -0
- package/file/index.js +3 -0
- package/file/remove.js +75 -0
- package/file/update.js +83 -0
- package/file/utils.js +27 -0
- package/format.js +29 -0
- package/gen.js +97 -0
- package/graph.js +130 -0
- package/more.js +103 -0
- package/package.json +32 -0
- package/remote/client/database.js +229 -0
- package/remote/client/graph.js +139 -0
- package/remote/client/index.js +10 -0
- package/remote/server/auth.js +100 -0
- package/remote/server/db.js +197 -0
- package/remote/server/function.js +43 -0
- package/remote/server/graph.js +121 -0
- package/remote/server/gui/css/main.css +130 -0
- package/remote/server/gui/css/scrool.css +81 -0
- package/remote/server/gui/css/style.css +61 -0
- package/remote/server/gui/favicon.svg +12 -0
- package/remote/server/gui/html/data.html +15 -0
- package/remote/server/gui/html/main.html +46 -0
- package/remote/server/gui/html/nav.html +25 -0
- package/remote/server/gui/html/popup.html +51 -0
- package/remote/server/gui/index.html +49 -0
- package/remote/server/gui/js/api.js +166 -0
- package/remote/server/gui/js/index.js +17 -0
- package/remote/server/gui/js/loadHTML.js +16 -0
- package/remote/server/gui/js/popUp.js +72 -0
- package/remote/server/gui/js/queryApi.js +51 -0
- package/remote/server/gui/js/queryDb.js +79 -0
- package/remote/server/gui/js/queryGraph.js +144 -0
- package/remote/server/gui/js/render.js +64 -0
- package/remote/server/gui/js/templates.js +31 -0
- package/remote/server/gui/js/utils.js +36 -0
- package/remote/server/gui/js/vars.js +9 -0
- package/remote/server/gui/libs/core.js +176 -0
- package/remote/server/gui/libs/d3.v7.min.js +2 -0
- package/remote/server/gui/libs/handlebars.min.js +29 -0
- package/remote/server/gui/libs/json5.min.js +1 -0
- package/remote/server/index.js +63 -0
- package/remote/server/initDataBases.js +20 -0
- package/remote/server/pathUtils.js +7 -0
- package/remote/server/secret.js +23 -0
- package/remote/serverMgmt/index.js +86 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const dbActionUtils = {
|
|
2
|
+
async query(data, path){
|
|
3
|
+
if(!vars.selectedServer) return false;
|
|
4
|
+
if(!vars.selectedDb) return false;
|
|
5
|
+
if(!vars.selectedTable) return false;
|
|
6
|
+
|
|
7
|
+
const body = {
|
|
8
|
+
db: vars.selectedDb,
|
|
9
|
+
collection: vars.selectedTable,
|
|
10
|
+
...data
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const server = serversMeta[vars.selectedServer];
|
|
14
|
+
const res = await fetch(server.url + "db/" + path, {
|
|
15
|
+
method: "POST",
|
|
16
|
+
headers: {
|
|
17
|
+
"Content-Type": "application/json",
|
|
18
|
+
"Authorization": server.token
|
|
19
|
+
},
|
|
20
|
+
body: JSON.stringify(body)
|
|
21
|
+
}).then(res => res.json());
|
|
22
|
+
if(res.err){
|
|
23
|
+
alert(res.msg);
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return res.result;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const dbActions = {
|
|
32
|
+
async find(query, context=undefined, opts=undefined){
|
|
33
|
+
const body = {
|
|
34
|
+
search: query,
|
|
35
|
+
context,
|
|
36
|
+
opts
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return await dbActionUtils.query(body, "database/find");
|
|
40
|
+
},
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const graphActions = {
|
|
44
|
+
async find(node){
|
|
45
|
+
return await dbActionUtils.query({ node }, "graph/find");
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
async getAll(){
|
|
49
|
+
return await dbActionUtils.query({}, "graph/getAll");
|
|
50
|
+
},
|
|
51
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const queryDbFunc = {
|
|
2
|
+
queryInput: document.querySelector("#query"),
|
|
3
|
+
queryTypeSelect: document.querySelector("#query-type"),
|
|
4
|
+
queryContextInput: document.querySelector("#query-context"),
|
|
5
|
+
queryContextLabel: document.querySelector("#query-context-label"),
|
|
6
|
+
queryOptsInput: document.querySelector("#query-opts"),
|
|
7
|
+
|
|
8
|
+
renderData(){
|
|
9
|
+
if(!db_data || db_data.length == 0){
|
|
10
|
+
data_output.innerHTML = "<p>No data</p>";
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
data_output.innerHTML = templates.tableData({ data: db_data });
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
init(){
|
|
17
|
+
document.querySelector("#query-db-btn").addEventListener("click", async () => {
|
|
18
|
+
let query = queryDbFunc.queryInput.value.trim();
|
|
19
|
+
let type = queryDbFunc.queryTypeSelect.value.trim();
|
|
20
|
+
let context = queryDbFunc.queryContextInput.value.trim();
|
|
21
|
+
let opts = queryDbFunc.queryOptsInput.value.trim();
|
|
22
|
+
|
|
23
|
+
if(!query) query = "{}";
|
|
24
|
+
if(!type) type = "json";
|
|
25
|
+
if(!context) context = "{}";
|
|
26
|
+
if(!opts) opts = "{}";
|
|
27
|
+
|
|
28
|
+
switch(type){
|
|
29
|
+
case "js-function":
|
|
30
|
+
try{
|
|
31
|
+
(new Function("return " + query))();
|
|
32
|
+
}catch{
|
|
33
|
+
return alert("Invalid query context");
|
|
34
|
+
}
|
|
35
|
+
break;
|
|
36
|
+
case "json5":
|
|
37
|
+
if(!query.startsWith("{")) query = "{" + query + "}";
|
|
38
|
+
query = JSON5.parse(query);
|
|
39
|
+
break;
|
|
40
|
+
case "json":
|
|
41
|
+
query = JSON.parse(query);
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
context = JSON5.parse(context);
|
|
46
|
+
opts = JSON5.parse(opts);
|
|
47
|
+
if(!context) context = {};
|
|
48
|
+
if(!opts) opts = {};
|
|
49
|
+
|
|
50
|
+
const data = await dbActions.find(query, context, opts);
|
|
51
|
+
if(!data) return;
|
|
52
|
+
db_data = data;
|
|
53
|
+
queryDbFunc.renderData();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
queryDbFunc.queryTypeSelect.addEventListener("change", () => {
|
|
57
|
+
queryDbFunc.queryContextLabel.style.display = queryTypeSelect.value == "js-function" ? "block" : "none";
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
document.querySelector("#sortData").addEventListener("click", () => {
|
|
61
|
+
const sortKey = prompt("Enter key to sort by:");
|
|
62
|
+
if(!sortKey) return;
|
|
63
|
+
queryDbFunc.sortData(sortKey);
|
|
64
|
+
});
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
sortData(key){
|
|
68
|
+
db_data.sort((a, b) => {
|
|
69
|
+
const aValue = a[key] !== undefined ? a[key] : "";
|
|
70
|
+
const bValue = b[key] !== undefined ? b[key] : "";
|
|
71
|
+
if(aValue > bValue) return 1;
|
|
72
|
+
if(aValue < bValue) return -1;
|
|
73
|
+
return 0;
|
|
74
|
+
});
|
|
75
|
+
this.renderData();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
queryDbFunc.init();
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
const queryGraphFunc = {
|
|
2
|
+
queryInput: document.querySelector("#query-graph-node"),
|
|
3
|
+
outputMethodSelect: document.querySelector("#query-graph-output-method"),
|
|
4
|
+
|
|
5
|
+
init(){
|
|
6
|
+
document.querySelector("#query-graph-btn").addEventListener("click", async () => {
|
|
7
|
+
const node = queryGraphFunc.queryInput.value.trim();
|
|
8
|
+
const edges = await graphActions.find(node);
|
|
9
|
+
db_data = edges;
|
|
10
|
+
queryGraphFunc.displayEdges();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
document.querySelector("#query-graph-all-btn").addEventListener("click", async () => {
|
|
14
|
+
const edges = await graphActions.getAll();
|
|
15
|
+
db_data = edges;
|
|
16
|
+
queryGraphFunc.displayEdges();
|
|
17
|
+
});
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
displayEdges(){
|
|
21
|
+
const method = queryGraphFunc.outputMethodSelect.value;
|
|
22
|
+
|
|
23
|
+
switch(method){
|
|
24
|
+
case "table":
|
|
25
|
+
if(!db_data || db_data.length == 0){
|
|
26
|
+
data_output.innerHTML = "<p>No data</p>";
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
data_output.innerHTML = templates.tableData({ data: db_data });
|
|
30
|
+
break;
|
|
31
|
+
case "graph":
|
|
32
|
+
queryGraphFunc.displayEdgesGraph();
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
displayEdgesGraph(){
|
|
38
|
+
if(!db_data || db_data.length == 0){
|
|
39
|
+
data_output.innerHTML = "<p>No data</p>";
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
data_output.innerHTML = "";
|
|
43
|
+
const { nodes, links } = queryGraphFunc.transformData(db_data);
|
|
44
|
+
|
|
45
|
+
const div = document.createElement("div");
|
|
46
|
+
div.style.height = "500px";
|
|
47
|
+
div.style.width = "99%";
|
|
48
|
+
data_output.appendChild(div);
|
|
49
|
+
|
|
50
|
+
const width = div.clientWidth;
|
|
51
|
+
const height = div.clientHeight;
|
|
52
|
+
|
|
53
|
+
const zoom = d3.zoom()
|
|
54
|
+
.scaleExtent([0.1, 4])
|
|
55
|
+
.on("zoom", (event) => {
|
|
56
|
+
g.attr("transform", event.transform);
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
const svg = d3.create("svg")
|
|
60
|
+
.attr("width", width)
|
|
61
|
+
.attr("height", height)
|
|
62
|
+
.call(zoom);
|
|
63
|
+
|
|
64
|
+
const g = svg.append("g");
|
|
65
|
+
|
|
66
|
+
const simulation = d3.forceSimulation(nodes)
|
|
67
|
+
.force("link", d3.forceLink().id(d => d.id).distance(90))
|
|
68
|
+
.force("charge", d3.forceManyBody().strength(-90))
|
|
69
|
+
.force("center", d3.forceCenter(width / 2, height / 2))
|
|
70
|
+
.force("collision", d3.forceCollide().radius(50))
|
|
71
|
+
.force("gravity", d3.forceManyBody().strength(20));
|
|
72
|
+
|
|
73
|
+
const link = g.append("g")
|
|
74
|
+
.attr("class", "links")
|
|
75
|
+
.selectAll("line")
|
|
76
|
+
.data(links)
|
|
77
|
+
.enter().append("line")
|
|
78
|
+
.attr("stroke-width", 2)
|
|
79
|
+
.style("stroke", "var(--accent)");
|
|
80
|
+
|
|
81
|
+
const node = g.append("g")
|
|
82
|
+
.attr("class", "nodes")
|
|
83
|
+
.selectAll("g")
|
|
84
|
+
.data(nodes)
|
|
85
|
+
.enter().append("g");
|
|
86
|
+
|
|
87
|
+
node.append("circle")
|
|
88
|
+
.attr("r", 8)
|
|
89
|
+
.attr("fill", "var(--accent)");
|
|
90
|
+
|
|
91
|
+
node.append("text")
|
|
92
|
+
.attr("dx", 12)
|
|
93
|
+
.attr("dy", ".35em")
|
|
94
|
+
.attr("fill", "var(--txt)")
|
|
95
|
+
.text(d => d.id)
|
|
96
|
+
.style("cursor", "pointer")
|
|
97
|
+
.on("click", function(event, d) {
|
|
98
|
+
queryGraphFunc.copyToClipboard(d.id);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
simulation
|
|
102
|
+
.nodes(nodes)
|
|
103
|
+
.on("tick", () => {
|
|
104
|
+
link.attr("x1", d => d.source.x)
|
|
105
|
+
.attr("y1", d => d.source.y)
|
|
106
|
+
.attr("x2", d => d.target.x)
|
|
107
|
+
.attr("y2", d => d.target.y);
|
|
108
|
+
|
|
109
|
+
node.attr("transform", d => `translate(${d.x},${d.y})`);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
simulation.force("link").links(links);
|
|
113
|
+
div.appendChild(svg.node());
|
|
114
|
+
|
|
115
|
+
const resetView = document.createElement("button");
|
|
116
|
+
resetView.innerText = "Reset view";
|
|
117
|
+
resetView.addEventListener("click", () => {
|
|
118
|
+
svg.transition().duration(750)
|
|
119
|
+
.call(zoom.transform, d3.zoomIdentity);
|
|
120
|
+
});
|
|
121
|
+
data_output.appendChild(resetView);
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
transformData(inputData){
|
|
125
|
+
const nodesSet = new Set();
|
|
126
|
+
|
|
127
|
+
const links = inputData.map(({ a, b }) => {
|
|
128
|
+
nodesSet.add(a);
|
|
129
|
+
nodesSet.add(b);
|
|
130
|
+
return { source: a, target: b };
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const nodes = Array.from(nodesSet).map(id => ({ id }));
|
|
134
|
+
return { nodes, links };
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
copyToClipboard(text){
|
|
138
|
+
navigator.clipboard.writeText(text).then(() => alert("Copied in clipboard!")).catch(() => {
|
|
139
|
+
alert("Failed to copy in clipboard. Manually select and copy it:\n" + text);
|
|
140
|
+
});
|
|
141
|
+
},
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
queryGraphFunc.init();
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
const databaseServerList = document.querySelector("#database-server-list");
|
|
2
|
+
const data_output = document.querySelector("#data-output");
|
|
3
|
+
const queryDivDb = document.querySelector("#query-div-db");
|
|
4
|
+
const queryDivGraph = document.querySelector("#query-div-graph");
|
|
5
|
+
|
|
6
|
+
const renderFunc = {
|
|
7
|
+
renderServerList(){
|
|
8
|
+
const serversList = [];
|
|
9
|
+
Object.keys(serversMeta).forEach(id => {
|
|
10
|
+
serversList.push({
|
|
11
|
+
id,
|
|
12
|
+
name: serversMeta[id].name,
|
|
13
|
+
saved: serversMeta[id].saved || false
|
|
14
|
+
});
|
|
15
|
+
})
|
|
16
|
+
databaseServerList.innerHTML = templates.databasesList({ serversList });
|
|
17
|
+
|
|
18
|
+
Object.keys(serversMeta).forEach(id => {
|
|
19
|
+
renderFunc.rednerServer(id);
|
|
20
|
+
})
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
async rednerServer(id){
|
|
24
|
+
const server = serversMeta[id];
|
|
25
|
+
if(!server) return;
|
|
26
|
+
const nav = document.querySelector("#database-nav-"+id);
|
|
27
|
+
nav.innerHTML = "";
|
|
28
|
+
|
|
29
|
+
const dbsObj = await databaseGetMetaFunc.loadDbList(id);
|
|
30
|
+
const dbsArray = [];
|
|
31
|
+
Object.keys(dbsObj).forEach(db => {
|
|
32
|
+
dbsArray.push({
|
|
33
|
+
serverId: id,
|
|
34
|
+
name: db
|
|
35
|
+
});
|
|
36
|
+
})
|
|
37
|
+
nav.innerHTML = templates.databaseNav({ dbs: dbsArray });
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
async renderTables(serverId, dbName){
|
|
41
|
+
const nav = document.querySelector("#database-nav-"+serverId+"-"+dbName);
|
|
42
|
+
nav.innerHTML = "";
|
|
43
|
+
vars.selectedServer = serverId;
|
|
44
|
+
vars.selectedDb = dbName;
|
|
45
|
+
vars.selectedTable = null;
|
|
46
|
+
renderFunc.updateQueryStyle();
|
|
47
|
+
const tables = await databaseGetMetaFunc.getDbTables(serverId, dbName);
|
|
48
|
+
nav.innerHTML = templates.databasesTables({ tables, server: serverId, db: dbName });
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
updateQueryStyle(){
|
|
52
|
+
const dbType = getSelectedDatabase().type;
|
|
53
|
+
switch(dbType){
|
|
54
|
+
case "database":
|
|
55
|
+
queryDivDb.style.display = "block";
|
|
56
|
+
queryDivGraph.style.display = "none";
|
|
57
|
+
break;
|
|
58
|
+
case "graph":
|
|
59
|
+
queryDivDb.style.display = "none";
|
|
60
|
+
queryDivGraph.style.display = "block";
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const templatesUtils = {
|
|
2
|
+
load(id){
|
|
3
|
+
const templateEle = document.querySelector("#"+id);
|
|
4
|
+
const html = templateEle.innerHTML;
|
|
5
|
+
const template = Handlebars.compile(html);
|
|
6
|
+
templateEle.remove();
|
|
7
|
+
return template;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
Handlebars.registerHelper("isObject", function (value){
|
|
12
|
+
return typeof value === "object" && value !== null;
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
Handlebars.registerHelper("json5", function (context){
|
|
16
|
+
const json5 = JSON5.stringify(context, null, 4);
|
|
17
|
+
return json5.substring(1, json5.length - 1);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
Handlebars.registerHelper("br", function(height){
|
|
21
|
+
return new Handlebars.SafeString(`<div style="height: ${height}px;"></div>`);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const templates = {
|
|
25
|
+
databasesList: templatesUtils.load("databases-list-template"),
|
|
26
|
+
databaseNav: templatesUtils.load("database-nav-template"),
|
|
27
|
+
databasesTables: templatesUtils.load("databases-tables-template"),
|
|
28
|
+
tableData: templatesUtils.load("table-data-template"),
|
|
29
|
+
addServer: templatesUtils.load("addServer-template"),
|
|
30
|
+
menageServers: templatesUtils.load("menageServers-template"),
|
|
31
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
class AutoUpdater{
|
|
2
|
+
constructor(obj, key, selector, updateCB){
|
|
3
|
+
this.obj = obj;
|
|
4
|
+
this.key = key;
|
|
5
|
+
this.element = document.querySelector(selector);
|
|
6
|
+
this.updateCB = updateCB;
|
|
7
|
+
this.init();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
init(){
|
|
11
|
+
this.updateElement();
|
|
12
|
+
this.watch();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
updateElement(){
|
|
16
|
+
let value = this.obj[this.key];
|
|
17
|
+
const formattedValue = this.updateCB ? this.updateCB(value) : value;
|
|
18
|
+
this.element.innerHTML = formattedValue;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
watch(){
|
|
22
|
+
let currentValue = this.obj[this.key];
|
|
23
|
+
|
|
24
|
+
Object.defineProperty(this.obj, this.key, {
|
|
25
|
+
set: (newValue) => {
|
|
26
|
+
currentValue = newValue;
|
|
27
|
+
this.updateElement();
|
|
28
|
+
},
|
|
29
|
+
get: () => currentValue
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function getSelectedDatabase(){
|
|
35
|
+
return serversData[vars.selectedServer][vars.selectedDb];
|
|
36
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
var lo = console.log;
|
|
2
|
+
const delay = ms => new Promise(res => setTimeout(res, ms));
|
|
3
|
+
|
|
4
|
+
const cw = {};
|
|
5
|
+
|
|
6
|
+
cw.proto = {
|
|
7
|
+
html(v){
|
|
8
|
+
if(this.innerHTML != undefined){
|
|
9
|
+
this.innerHTML = v;
|
|
10
|
+
return this;
|
|
11
|
+
}else{
|
|
12
|
+
return this.innerHTML;
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
v(v){
|
|
17
|
+
if(this.value != undefined){
|
|
18
|
+
this.value = v;
|
|
19
|
+
return this;
|
|
20
|
+
}else{
|
|
21
|
+
return this.value;
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
on(event, fn){
|
|
26
|
+
this.addEventListener(event, fn);
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
css(style, val=null){
|
|
30
|
+
const ele = this;
|
|
31
|
+
if(typeof style == "string"){
|
|
32
|
+
if(val != null){
|
|
33
|
+
ele.style[style] = val;
|
|
34
|
+
}else{
|
|
35
|
+
ele.style = style;
|
|
36
|
+
}
|
|
37
|
+
}else if(typeof style == "object"){
|
|
38
|
+
Object.assign(ele.style, style);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
atrib(att, arg=null){
|
|
43
|
+
if(arg){
|
|
44
|
+
this.setAttribute(att, arg);
|
|
45
|
+
}else{
|
|
46
|
+
return this.getAttribute(att);
|
|
47
|
+
}
|
|
48
|
+
return this;
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
clA(arg){
|
|
52
|
+
this.classList.add(arg);
|
|
53
|
+
return this;
|
|
54
|
+
},
|
|
55
|
+
|
|
56
|
+
clR(arg){
|
|
57
|
+
this.classList.remove(arg);
|
|
58
|
+
return this;
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
clT(className){
|
|
62
|
+
this.classList.toggle(className);
|
|
63
|
+
return this;
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
animateFade(from, { time=200, cb=null }){
|
|
67
|
+
const style = this.style;
|
|
68
|
+
const steps = 50;
|
|
69
|
+
const timeToStep = time / steps;
|
|
70
|
+
const d = (from == 0 ? 1 : -1)/steps;
|
|
71
|
+
let index = 0;
|
|
72
|
+
style.opacity = from;
|
|
73
|
+
|
|
74
|
+
const interval = setInterval(() => {
|
|
75
|
+
if(index >= steps){
|
|
76
|
+
clearInterval(interval);
|
|
77
|
+
if(cb && typeof cb == "function") cb();
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
style.opacity = parseFloat(style.opacity) + d;
|
|
81
|
+
index++;
|
|
82
|
+
}, timeToStep);
|
|
83
|
+
return this;
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
fadeIn(display="block", cb=null){
|
|
87
|
+
if(typeof display == "function"){
|
|
88
|
+
cb = display;
|
|
89
|
+
display = "block";
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
this.css("display", display);
|
|
93
|
+
this.animateFade(0, { cb });
|
|
94
|
+
this.fade = true;
|
|
95
|
+
return this;
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
fadeOut(cb=null){
|
|
99
|
+
this.animateFade(1, { time: 300, cb });
|
|
100
|
+
setTimeout(() => this.css("display", "none"), 300);
|
|
101
|
+
this.fade = false;
|
|
102
|
+
return this;
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
fade: true,
|
|
106
|
+
fadeToogle(){
|
|
107
|
+
if(this.fade){
|
|
108
|
+
this.fadeOut();
|
|
109
|
+
}else{
|
|
110
|
+
this.fadeIn();
|
|
111
|
+
}
|
|
112
|
+
return this;
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
add(child){
|
|
116
|
+
this.appendChild(child);
|
|
117
|
+
return this;
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
addUp(child){
|
|
121
|
+
this.insertBefore(child, this.firstChild);
|
|
122
|
+
return this;
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
cw.init = function(){
|
|
127
|
+
Object.assign(HTMLElement.prototype, this.proto);
|
|
128
|
+
}
|
|
129
|
+
cw.init();
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
cw.grid = function(doc=document.body){
|
|
133
|
+
function getSize(className, size){
|
|
134
|
+
const match = className.match(new RegExp(`${size}_(\\d+)`));
|
|
135
|
+
return match ? parseInt(match[0].replace(size+"_","")) : 12;
|
|
136
|
+
}
|
|
137
|
+
function add(ele, start, size){
|
|
138
|
+
for(let i=start; i<prefixes.length; i++){
|
|
139
|
+
ele.classList.add(prefixes[i] + "_" + size);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const prefixes = "smlu";
|
|
143
|
+
const elementy = doc.querySelectorAll(".s, [class^='s_']");
|
|
144
|
+
elementy.forEach(ele => {
|
|
145
|
+
const cm = ele.className;
|
|
146
|
+
let foundPrefix = 0;
|
|
147
|
+
for(let i=0; i<prefixes.length; i++){
|
|
148
|
+
if(!cm.includes(prefixes[i] + "_")) continue;
|
|
149
|
+
foundPrefix = i;
|
|
150
|
+
}
|
|
151
|
+
const size = getSize(cm, prefixes[foundPrefix])
|
|
152
|
+
add(ele, foundPrefix, size);
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
cw.rand = function(min, max){
|
|
157
|
+
return Math.round(Math.random() * (max-min) + min);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
cw.round = function(a, b){
|
|
161
|
+
const factor = Math.pow(10, b);
|
|
162
|
+
return Math.round(a*factor)/factor;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
cw.get = function(url){
|
|
166
|
+
if(!url) return false;
|
|
167
|
+
const xhr = new XMLHttpRequest();
|
|
168
|
+
xhr.open("GET", url, false);
|
|
169
|
+
xhr.send();
|
|
170
|
+
|
|
171
|
+
if(xhr.status == 200){
|
|
172
|
+
return xhr.responseText;
|
|
173
|
+
}else if(xhr.status == 404){
|
|
174
|
+
return false;
|
|
175
|
+
}else return null;
|
|
176
|
+
}
|