Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/webroot/rsrc/js/application/pholio/behavior-pholio-mock-edit.js
12241 views
1
/**
2
* @provides javelin-behavior-pholio-mock-edit
3
* @requires javelin-behavior
4
* javelin-stratcom
5
* javelin-dom
6
* javelin-workflow
7
* javelin-quicksand
8
* phabricator-phtize
9
* phabricator-drag-and-drop-file-upload
10
* phabricator-draggable-list
11
*/
12
JX.behavior('pholio-mock-edit', function(config, statics) {
13
var pht = JX.phtize(config.pht);
14
var uploading = [];
15
16
17
/* -( Deleting Images )---------------------------------------------------- */
18
19
20
// When the user clicks the "X" on an image, we replace it with a "click to
21
// undo" element. If they click to undo, we put the original node back in the
22
// DOM.
23
var pholio_drop_remove = function(e) {
24
e.kill();
25
26
var node = e.getNode('pholio-drop-image');
27
var undo = render_undo();
28
29
JX.DOM.listen(undo, 'click', 'pholio-drop-undo', function(e) {
30
e.kill();
31
JX.DOM.replace(undo, node);
32
synchronize_order();
33
});
34
35
JX.DOM.replace(node, undo);
36
synchronize_order();
37
};
38
39
40
/* -( Reordering Images )-------------------------------------------------- */
41
42
43
// Reflect the display order in a hidden input.
44
var synchronize_order = function() {
45
var items = statics.draglist.findItems();
46
var order = [];
47
for (var ii = 0; ii < items.length; ii++) {
48
order.push(JX.Stratcom.getData(items[ii]).filePHID);
49
}
50
statics.nodes.order.value = order.join(',');
51
};
52
53
54
var build_draglist = function(node) {
55
var draglist = new JX.DraggableList('pholio-drop-image', node)
56
.setGhostNode(JX.$N('div', {className: 'drag-ghost'}))
57
.setFindItemsHandler(function() {
58
return JX.DOM.scry(node, 'div', 'pholio-drop-image');
59
});
60
61
// Only let the user drag images by the handle, not the whole entry.
62
draglist.listen('shouldBeginDrag', function(e) {
63
if (!e.getNode('pholio-drag-handle')) {
64
JX.Stratcom.context().prevent();
65
}
66
});
67
draglist.listen('didDrop', synchronize_order);
68
return draglist;
69
};
70
71
72
/* -( Build )-------------------------------------------------------------- */
73
74
75
var build_drop_upload = function(node) {
76
var drop = new JX.PhabricatorDragAndDropFileUpload(node)
77
.setURI(config.uploadURI);
78
79
drop.listen('didBeginDrag', function() {
80
JX.DOM.alterClass(node, 'pholio-drop-active', true);
81
});
82
83
drop.listen('didEndDrag', function() {
84
JX.DOM.alterClass(node, 'pholio-drop-active', false);
85
});
86
87
return drop;
88
};
89
90
var build_add_control = function(add_node) {
91
var drop = build_drop_upload(add_node);
92
93
drop.listen('willUpload', function(file) {
94
var node = render_uploading();
95
uploading.push({node: node, file: file});
96
statics.nodes.list.appendChild(node);
97
});
98
99
drop.listen('didUpload', function(file) {
100
var node;
101
for (var ii = 0; ii < uploading.length; ii++) {
102
if (uploading[ii].file === file) {
103
node = uploading[ii].node;
104
uploading.splice(ii, 1);
105
break;
106
}
107
}
108
109
render_upload(node, file);
110
});
111
112
drop.start();
113
114
JX.DOM.listen(add_node, 'click', null, function(e) {
115
e.kill();
116
117
new JX.Workflow('/file/uploaddialog/')
118
.setHandler(function(response) {
119
var files = response.files;
120
for (var ii = 0; ii < files.length; ii++) {
121
var file = files[ii];
122
123
var upload = new JX.PhabricatorFileUpload()
124
.setID(file.id)
125
.setPHID(file.phid)
126
.setURI(file.uri);
127
128
var node = render_uploading();
129
statics.nodes.list.appendChild(node);
130
131
render_upload(node, upload);
132
}
133
})
134
.start();
135
});
136
};
137
138
var render_upload = function(node, file) {
139
JX.DOM.setContent(node, pht('uploaded'));
140
141
new JX.Workflow(config.renderURI, {filePHID: file.getPHID()})
142
.setHandler(function(response) {
143
var new_node = JX.$H(response.markup).getFragment().firstChild;
144
build_update_control(new_node);
145
146
JX.DOM.replace(node, new_node);
147
synchronize_order();
148
})
149
.start();
150
};
151
152
var build_list_controls = function(list_node) {
153
var nodes = JX.DOM.scry(list_node, 'div', 'pholio-drop-image');
154
for (var ii = 0; ii < nodes.length; ii++) {
155
build_update_control(nodes[ii]);
156
}
157
};
158
159
var build_update_control = function(node) {
160
var did_upload = function(node, file) {
161
var node_data = JX.Stratcom.getData(node);
162
163
var data = {
164
filePHID: file.getPHID(),
165
replacesPHID: node_data.replacesPHID || node_data.filePHID || null,
166
title: JX.DOM.find(node, 'input', 'image-title').value,
167
description: JX.DOM.find(node, 'textarea', 'image-description').value
168
};
169
170
new JX.Workflow(config.renderURI, data)
171
.setHandler(function(response) {
172
var new_node = JX.$H(response.markup).getFragment().firstChild;
173
build_update_control(new_node);
174
175
JX.DOM.replace(node, new_node);
176
JX.DOM.alterClass(node, 'pholio-replacing', false);
177
synchronize_order();
178
})
179
.start();
180
};
181
182
var drop = build_drop_upload(node);
183
184
drop.listen('willUpload', function() {
185
JX.DOM.alterClass(node, 'pholio-replacing', true);
186
});
187
188
drop.listen('didUpload', function(file) {
189
did_upload(node, file);
190
});
191
192
drop.start();
193
194
JX.DOM.listen(node, 'click', 'pholio-uploaded-thumb', function(e) {
195
e.kill();
196
197
new JX.Workflow('/file/uploaddialog/single/')
198
.setHandler(function(response) {
199
var files = response.files;
200
for (var ii = 0; ii < files.length; ii++) {
201
var file = files[ii];
202
203
var upload = new JX.PhabricatorFileUpload()
204
.setID(file.id)
205
.setPHID(file.phid)
206
.setURI(file.uri);
207
208
did_upload(node, upload);
209
}
210
})
211
.start();
212
});
213
};
214
215
216
/* -( Rendering )---------------------------------------------------------- */
217
218
219
var render_uploading = function() {
220
return JX.$N(
221
'div',
222
{className: 'pholio-drop-uploading'},
223
pht('uploading'));
224
};
225
226
var render_undo = function() {
227
var link = JX.$N(
228
'a',
229
{href: '#', sigil: 'pholio-drop-undo'},
230
pht('undo'));
231
232
return JX.$N(
233
'div',
234
{className: 'pholio-drop-undo'},
235
[pht('removed'), ' ', link]);
236
};
237
238
239
/* -( Init )--------------------------------------------------------------- */
240
241
242
function update_statics(data, page_id, no_build) {
243
statics.nodes = {
244
list: JX.$(data.listID),
245
drop: JX.$(data.dropID),
246
order: JX.$(data.orderID)
247
};
248
249
if (!statics.mockEditCache[page_id]) {
250
statics.mockEditCache[page_id] = {};
251
}
252
statics.mockEditCache[page_id].config = config;
253
statics.mockEditCache[page_id].nodes = statics.nodes;
254
255
if (no_build !== true) {
256
build_add_control(statics.nodes.drop);
257
build_list_controls(statics.nodes.list);
258
statics.draglist = build_draglist(statics.nodes.list);
259
statics.mockEditCache[page_id].draglist = statics.draglist;
260
} else {
261
statics.draglist = statics.mockEditCache[page_id].draglist;
262
}
263
synchronize_order();
264
}
265
266
function install() {
267
statics.mockEditCache = {};
268
JX.Stratcom.listen('click', 'pholio-drop-remove', pholio_drop_remove);
269
JX.Stratcom.listen(
270
'quicksand-redraw',
271
null,
272
function (e) {
273
e.kill();
274
275
var data = e.getData();
276
if (!data.newResponse.mockEditConfig) {
277
return;
278
}
279
if (data.fromServer) {
280
// we ran update_statics(config) below already
281
} else {
282
var page_id = data.newResponseID;
283
var new_config = statics.mockEditCache[page_id].config;
284
update_statics(new_config, page_id, true);
285
}
286
});
287
return true;
288
}
289
290
statics.installed = statics.installed || install();
291
update_statics(config, JX.Quicksand.getCurrentPageID(), false);
292
});
293
294