This repository has been archived by the owner on Aug 21, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
130 lines (111 loc) · 4.08 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* jshint node:true */
var _ = require('lodash');
module.exports = function(options, callback) {
return new Construct(options, callback);
};
module.exports.Construct = Construct;
function Construct(options, callback) {
var apos = options.apos;
var app = options.app;
var schemas = options.schemas;
var self = this;
self.widgets = {};
self.toggleUi = options.toggleUi || false;
self._apos = apos;
self._app = app;
self._schemas = schemas;
self._options = options;
self._pages = options.pages;
self._apos.mixinModuleAssets(self, 'schema-widgets', __dirname, options);
self._action = '/apos-schema-widgets';
self._apos.pushGlobalData({
schemaWidgetsUi: {
toggleUi: self.toggleUi
}
});
self.pushAsset('script', 'editor', { when: 'user' });
self.pushAsset('stylesheet', 'editor', { when: 'user' });
self.registerWidget = function(options) {
var widget = {};
apos.defaultControls.push(options.name);
widget.name = options.name;
widget.widget = true;
widget.label = options.label || options.name;
widget.css = options.css || apos.cssName(options.name);
widget.icon = options.icon;
if (options.afterLoad) {
widget.afterLoad = options.afterLoad;
}
if (_.find(options.schema, function(field) {
return (field.name === 'content');
})) {
console.error('\n\nERROR: apostrophe-schema-widgets schema fields must not be named "content". Fix your \"' + widget.name + '\" widget definition.\n\n');
}
widget.sanitize = function(req, item, callback) {
var object = {};
return schemas.convertFields(req, options.schema, 'form', item, object, function(err) {
if (err) {
return callback(err, object);
}
return widget.afterConvertFields(req, object, function(e) {
return callback(e, object);
});
});
};
widget.renderWidget = options.renderWidget || function(data) {
return self.render(widget.name, data);
};
widget.empty = function(data) {
return self._schemas.empty(options.schema, data);
};
widget.afterConvertFields = function(req, object, callback) {
return callback(null);
};
widget.load = function(req, item, callback) {
if (req.aposSchemaWidgetLoading) {
// Refuse to do perform joins through two levels of schema widgets.
// This prevents a number of infinite loop scenarios. For this to
// work properly page loaders should continue to run in series
// rather than in parallel. -Tom
return setImmediate(callback);
}
if (req.deferredLoads) {
if (!req.deferredLoads[options.name]) {
req.deferredLoads[options.name] = [];
req.deferredLoaders[options.name] = widget.loadNow;
}
req.deferredLoads[options.name].push(item);
return setImmediate(callback);
}
return widget.loadNow(req, [ item ], callback);
};
widget.loadNow = function(req, items, callback) {
req.aposSchemaWidgetLoading = true;
return self._schemas.join(req, options.schema, items, undefined, function(err) {
if (err || typeof widget.afterLoad !== 'function'){
req.aposSchemaWidgetLoading = false;
return setImmediate(_.partial(callback, err));
}
return widget.afterLoad(req, items[0], function(err) {
req.aposSchemaWidgetLoading = false;
return setImmediate(_.partial(callback, err));
});
});
};
apos.addWidgetType(widget.name, widget);
self.widgets[widget.name] = widget;
var data = {
schemaWidgets: {}
};
options.css = options.css || apos.cssName(options.name);
data.schemaWidgets[widget.name] = options;
self._apos.pushGlobalData(data);
// originally designed to output templates for many widgets at once, this template
// can be repurposed to push them one at a time
self.pushAsset('template', 'widgetEditors', { when: 'user', data: { widgets: [ options ] } });
};
_.each(options.widgets, self.registerWidget);
if (callback) {
process.nextTick(function() { return callback(null); });
}
}