@dualbox/editor 1.0.32 → 1.0.33
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/js/dist/GraphEditor.js +252 -232
- package/js/dist/GraphEditor.min.js +251 -231
- package/js/src/GraphEditor.js +230 -231
- package/package.json +2 -2
package/js/src/GraphEditor.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import _ from
|
|
1
|
+
import _ from "lodash";
|
|
2
2
|
|
|
3
|
-
import GraphModel from
|
|
4
|
-
import GraphView from
|
|
5
|
-
import GraphController from
|
|
6
|
-
import AppParser from
|
|
7
|
-
import jsplumbjs from
|
|
3
|
+
import GraphModel from "./m/GraphModel";
|
|
4
|
+
import GraphView from "./v/GraphView";
|
|
5
|
+
import GraphController from "./c/GraphController";
|
|
6
|
+
import AppParser from "@dualbox/dualbox-lib-appparser";
|
|
7
|
+
import jsplumbjs from "jsplumb";
|
|
8
8
|
|
|
9
9
|
//import fa from '@dualbox/dualbox-lib-font-awesome';
|
|
10
10
|
//console.log('FontAwesome loaded: ' + fa);
|
|
@@ -15,241 +15,241 @@ import jsplumbjs from 'jsplumb';
|
|
|
15
15
|
* Main class of the Graph Editor
|
|
16
16
|
*/
|
|
17
17
|
class DualboxEditor {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
if (type) {
|
|
61
|
-
packages = _.filter(packages, o => {
|
|
62
|
-
return o.name.startsWith('@dualbox/dualbox-' + type)
|
|
63
|
-
|| (type == "module" && o.name.startsWith('dualbox-core'))
|
|
64
|
-
})
|
|
65
|
-
}
|
|
66
|
-
resolve(packages);
|
|
67
|
-
}
|
|
68
|
-
});
|
|
18
|
+
// div: selector or jquery div
|
|
19
|
+
constructor(div, attrs) {
|
|
20
|
+
this.div = $(div);
|
|
21
|
+
this.div.addClass("main-editor-div");
|
|
22
|
+
this.attrs = attrs;
|
|
23
|
+
|
|
24
|
+
// export itself top window
|
|
25
|
+
window.dualboxEditor = this;
|
|
26
|
+
|
|
27
|
+
this.rootAppName = attrs.name ? attrs.name : "Application";
|
|
28
|
+
|
|
29
|
+
// MVC model
|
|
30
|
+
this.m = new GraphModel(this);
|
|
31
|
+
this.v = new GraphView(this, div, attrs);
|
|
32
|
+
this.c = new GraphController(this);
|
|
33
|
+
|
|
34
|
+
// bind links
|
|
35
|
+
this.v.m = this.c.m = this.m;
|
|
36
|
+
this.v.c = this.m.c = this.c;
|
|
37
|
+
this.c.v = this.m.v = this.v;
|
|
38
|
+
|
|
39
|
+
// cache for packages
|
|
40
|
+
this.packages = {};
|
|
41
|
+
this.DualBox = null; // local dualbox, for editor use
|
|
42
|
+
|
|
43
|
+
// the function to search for modules
|
|
44
|
+
// attr.search signature: search( text, cb )
|
|
45
|
+
// callback signature: cb( err, packages ), packages is an array of package.json
|
|
46
|
+
this.search = (text, type) => {
|
|
47
|
+
return new Promise((resolve, reject) => {
|
|
48
|
+
attrs.search(text, (err, packages) => {
|
|
49
|
+
if (err) {
|
|
50
|
+
reject(err);
|
|
51
|
+
} else {
|
|
52
|
+
// cache packages in this.packages
|
|
53
|
+
_.each(packages, r => {
|
|
54
|
+
if (!this.packages[r.name]) {
|
|
55
|
+
this.packages[r.name] = r;
|
|
56
|
+
}
|
|
69
57
|
});
|
|
70
|
-
}
|
|
71
58
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
var hasTypeDef = _.get(p, "dualbox.type");
|
|
80
|
-
|
|
81
|
-
if (isType && !hasTypeDef) {
|
|
82
|
-
console.error('Type package ' + p.name + ' has no dualbox Type description.\n'
|
|
83
|
-
+ 'Type was not imported');
|
|
84
|
-
}
|
|
85
|
-
return isType && hasTypeDef;
|
|
86
|
-
});
|
|
87
|
-
resolve(this.types);
|
|
88
|
-
}).catch((e) => {
|
|
89
|
-
reject(e);
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
return Promise.resolve(this.types);
|
|
59
|
+
if (type) {
|
|
60
|
+
packages = _.filter(packages, o => {
|
|
61
|
+
return (
|
|
62
|
+
o.name.startsWith("@dualbox/dualbox-" + type) ||
|
|
63
|
+
(type == "module" && o.name.startsWith("dualbox-core"))
|
|
64
|
+
);
|
|
65
|
+
});
|
|
95
66
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
// the function to find module by name and version (with cache)
|
|
105
|
-
// signature: find( name, version ), return a Promise which, when resolved, is a package.json
|
|
106
|
-
this.loadPackage = (name, version) => {
|
|
107
|
-
version = version || "*";
|
|
108
|
-
|
|
109
|
-
return new Promise((resolve, reject) => {
|
|
110
|
-
if (name.startsWith('dualbox-core')) {
|
|
111
|
-
var pkg = null;
|
|
112
|
-
_.each(this.DualBox.core, (corePackage) => {
|
|
113
|
-
if (corePackage.name == name) {
|
|
114
|
-
pkg = corePackage;
|
|
115
|
-
return false;
|
|
116
|
-
}
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
if (pkg) {
|
|
120
|
-
this.packages[name] = pkg;
|
|
121
|
-
resolve(pkg);
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
reject("Couldn't resolve core package: " + name);
|
|
125
|
-
}
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
var loadScript = (pkg, cb) => {
|
|
130
|
-
if (attrs.load) {
|
|
131
|
-
attrs.load(pkg.name, pkg.version, cb);
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
// Local editor. Bind the callback on the local script load
|
|
135
|
-
var script = $('script[data-pkg="' + pkg.name + '"]');
|
|
136
|
-
if (!script) {
|
|
137
|
-
throw "Couldn't find script in the current document: " + pkg.name + ". Did you forget gulp link-editor ?";
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (script.attr('data-loaded') === "true") {
|
|
141
|
-
cb();
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
else {
|
|
145
|
-
script[0].addEventListener("error", function () {
|
|
146
|
-
throw "Failed to load script " + pkg.name;
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
var timeout = setTimeout(function () {
|
|
150
|
-
cb("Failed to load " + pkg.name + " after 5 seconds");
|
|
151
|
-
}, 5000)
|
|
152
|
-
script[0].addEventListener("load", () => {
|
|
153
|
-
clearTimeout(timeout);
|
|
154
|
-
cb()
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
67
|
+
resolve(packages);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
};
|
|
159
72
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
178
|
-
else {
|
|
179
|
-
this.packages[name] = result; // cache result
|
|
180
|
-
loadScript(this.packages[name], (err) => {
|
|
181
|
-
if (err) reject(err)
|
|
182
|
-
else resolve(result);
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
});
|
|
73
|
+
this.types = [];
|
|
74
|
+
this.getRootTypes = function() {
|
|
75
|
+
if (_.isEmpty(this.types)) {
|
|
76
|
+
return new Promise((resolve, reject) => {
|
|
77
|
+
this.search("dualbox-type-")
|
|
78
|
+
.then(packages => {
|
|
79
|
+
this.types = _.filter(packages, p => {
|
|
80
|
+
var isType = p.name.startsWith("@dualbox/dualbox-type");
|
|
81
|
+
var hasTypeDef = _.get(p, "dualbox.type");
|
|
82
|
+
|
|
83
|
+
if (isType && !hasTypeDef) {
|
|
84
|
+
console.error(
|
|
85
|
+
"Type package " +
|
|
86
|
+
p.name +
|
|
87
|
+
" has no dualbox Type description.\n" +
|
|
88
|
+
"Type was not imported"
|
|
89
|
+
);
|
|
186
90
|
}
|
|
91
|
+
return isType && hasTypeDef;
|
|
92
|
+
});
|
|
93
|
+
resolve(this.types);
|
|
187
94
|
})
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
95
|
+
.catch(e => {
|
|
96
|
+
reject(e);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
} else {
|
|
100
|
+
return Promise.resolve(this.types);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
194
103
|
|
|
104
|
+
this.getAvailableTypes = async function() {
|
|
105
|
+
var types = await this.getRootTypes();
|
|
106
|
+
return _.map(types, t => _.get(t, "dualbox.type.name"));
|
|
107
|
+
};
|
|
195
108
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
109
|
+
// the function to find module by name and version (with cache)
|
|
110
|
+
// signature: find( name, version ), return a Promise which, when resolved, is a package.json
|
|
111
|
+
this.loadPackage = (name, version) => {
|
|
112
|
+
version = version || "*";
|
|
113
|
+
|
|
114
|
+
return new Promise((resolve, reject) => {
|
|
115
|
+
if (name.startsWith("dualbox-core")) {
|
|
116
|
+
var pkg = null;
|
|
117
|
+
_.each(this.DualBox.core, corePackage => {
|
|
118
|
+
if (corePackage.name == name) {
|
|
119
|
+
pkg = corePackage;
|
|
120
|
+
return false;
|
|
201
121
|
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
if (pkg) {
|
|
125
|
+
this.packages[name] = pkg;
|
|
126
|
+
resolve(pkg);
|
|
127
|
+
} else {
|
|
128
|
+
reject("Couldn't resolve core package: " + name);
|
|
129
|
+
}
|
|
130
|
+
return;
|
|
202
131
|
}
|
|
203
132
|
|
|
204
|
-
|
|
133
|
+
var loadScript = (pkg, cb) => {
|
|
134
|
+
if (attrs.load) {
|
|
135
|
+
attrs.load(pkg.name, pkg.version, cb);
|
|
136
|
+
} else {
|
|
137
|
+
// Local editor. Bind the callback on the local script load
|
|
138
|
+
var script = $('script[data-pkg="' + pkg.name + '"]');
|
|
139
|
+
if (!script) {
|
|
140
|
+
throw "Couldn't find script in the current document: " +
|
|
141
|
+
pkg.name +
|
|
142
|
+
". Did you forget gulp link-editor ?";
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (script.attr("data-loaded") === "true") {
|
|
146
|
+
cb();
|
|
147
|
+
return;
|
|
148
|
+
} else {
|
|
149
|
+
script[0].addEventListener("error", function() {
|
|
150
|
+
throw "Failed to load script " + pkg.name;
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
var timeout = setTimeout(function() {
|
|
154
|
+
cb("Failed to load " + pkg.name + " after 5 seconds");
|
|
155
|
+
}, 5000);
|
|
156
|
+
script[0].addEventListener("load", () => {
|
|
157
|
+
clearTimeout(timeout);
|
|
158
|
+
cb();
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
};
|
|
205
163
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
164
|
+
// we need to find the package.json and make sure the script is loaded
|
|
165
|
+
if (this.packages[name]) {
|
|
166
|
+
try {
|
|
167
|
+
loadScript(this.packages[name], err => {
|
|
168
|
+
if (err) reject(err);
|
|
169
|
+
else resolve(this.packages[name]);
|
|
212
170
|
});
|
|
171
|
+
} catch (e) {
|
|
172
|
+
reject(e);
|
|
173
|
+
}
|
|
174
|
+
} else {
|
|
175
|
+
// mark the package as beeing resolved
|
|
176
|
+
attrs.find(name, version, (err, result) => {
|
|
177
|
+
if (err) {
|
|
178
|
+
reject(err);
|
|
179
|
+
} else {
|
|
180
|
+
this.packages[name] = result; // cache result
|
|
181
|
+
loadScript(this.packages[name], err => {
|
|
182
|
+
if (err) reject(err);
|
|
183
|
+
else resolve(result);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
});
|
|
213
187
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
// call cb when the editor is initialized
|
|
217
|
-
onReady(cb) {
|
|
218
|
-
this.v.onReady(cb);
|
|
219
|
-
}
|
|
188
|
+
});
|
|
189
|
+
};
|
|
220
190
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
191
|
+
// the function to require a dualbox module
|
|
192
|
+
this.require = (name, version, cb) => {
|
|
193
|
+
return require(name); // TODO: local only for now
|
|
194
|
+
};
|
|
225
195
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
196
|
+
// Safety when the user leave the page,
|
|
197
|
+
// if not already defined externally
|
|
198
|
+
if (!window.onbeforeunload) {
|
|
199
|
+
window.onbeforeunload = function() {
|
|
200
|
+
return "Unsaved changes will be lost, are you sure you want to leave the editor?";
|
|
201
|
+
};
|
|
231
202
|
}
|
|
232
203
|
|
|
233
|
-
|
|
234
|
-
return this.c.load(json);
|
|
235
|
-
}
|
|
204
|
+
this.loadCorePackages();
|
|
236
205
|
|
|
237
|
-
|
|
238
|
-
|
|
206
|
+
if (attrs.json) {
|
|
207
|
+
this.onReady(() => {
|
|
208
|
+
var p = this.setApp(attrs.json);
|
|
209
|
+
if (attrs.onLoaded) {
|
|
210
|
+
p.then(attrs.onLoaded);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
239
213
|
}
|
|
214
|
+
}
|
|
240
215
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
this.promises = promises;
|
|
216
|
+
// call cb when the editor is initialized
|
|
217
|
+
onReady(cb) {
|
|
218
|
+
this.v.onReady(cb);
|
|
219
|
+
}
|
|
246
220
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
221
|
+
async loadCorePackages() {
|
|
222
|
+
var onError = function(err) {
|
|
223
|
+
console.error(err);
|
|
224
|
+
};
|
|
251
225
|
|
|
252
|
-
|
|
226
|
+
await this.loadPackage("@dualbox/dualbox");
|
|
227
|
+
this.DualBox = window.DualBox = this.require("@dualbox/dualbox");
|
|
228
|
+
_.each(this.DualBox.core, async corePackage => {
|
|
229
|
+
await this.loadPackage(corePackage.name);
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
setApp(json) {
|
|
234
|
+
return this.c.load(json);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
getApp() {
|
|
238
|
+
this.m.get();
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// load all packages needed in the json
|
|
242
|
+
// return a Promise
|
|
243
|
+
loadPackages(json) {
|
|
244
|
+
var promises = []; // array of promises
|
|
245
|
+
this.promises = promises;
|
|
246
|
+
|
|
247
|
+
var parser = new AppParser(json);
|
|
248
|
+
parser.eachComponent((name, version) => {
|
|
249
|
+
promises.push(this.loadPackage(name, version));
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
/*
|
|
253
253
|
// also load core nodes
|
|
254
254
|
promises.push(this.loadPackage('dualbox-core-if', '*'));
|
|
255
255
|
promises.push(this.loadPackage('dualbox-core-value', '*'));
|
|
@@ -259,24 +259,23 @@ class DualboxEditor {
|
|
|
259
259
|
promises.push(this.loadPackage('dualbox-core-switch', '*'));
|
|
260
260
|
*/
|
|
261
261
|
|
|
262
|
-
|
|
263
|
-
|
|
262
|
+
return Promise.all(promises);
|
|
263
|
+
}
|
|
264
264
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
265
|
+
// sync version of this.loadPackage. Will crash if the package has not been loaded yet
|
|
266
|
+
getPackage(name, version) {
|
|
267
|
+
if (this.packages[name] === undefined) {
|
|
268
|
+
throw "Package " + name + " has not been loaded yet.";
|
|
269
|
+
}
|
|
270
|
+
return this.packages[name];
|
|
271
|
+
}
|
|
272
272
|
}
|
|
273
273
|
|
|
274
274
|
// try to export in window if in browser context
|
|
275
275
|
try {
|
|
276
|
-
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
console.log('Could not export to window: ' + e);
|
|
276
|
+
window.DualboxEditor = DualboxEditor;
|
|
277
|
+
} catch (e) {
|
|
278
|
+
console.log("Could not export to window: " + e);
|
|
280
279
|
}
|
|
281
280
|
|
|
282
281
|
//export default DualboxEditor;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dualbox/editor",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.33",
|
|
4
4
|
"description": "Editor of Dualbox apps",
|
|
5
5
|
"browser": "js/dist/GraphEditor.js",
|
|
6
6
|
"main": "js/dist/GraphEditor.js",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@babel/cli": "^7.2.3",
|
|
32
32
|
"@babel/core": "^7.2.2",
|
|
33
33
|
"@babel/preset-env": "^7.0.0-beta.46",
|
|
34
|
-
"@dualbox/dualbox-lib-appparser": "1.0.
|
|
34
|
+
"@dualbox/dualbox-lib-appparser": "1.0.10",
|
|
35
35
|
"@dualbox/dualbox-lib-bootstrap": "^1.0.14",
|
|
36
36
|
"@dualbox/dualbox-lib-font-awesome": "5.6.3",
|
|
37
37
|
"@fortawesome/fontawesome-free": "^5.4.1",
|