066bfc02f35cef63ba7bb435b36581140fb45815
[Plinn.git] / skins / ajax_scripts / folder_contents_script.js
1 // (c) BenoƮt PIN 2006-2007
2 // http://plinn.org
3 // Licence GPL
4 //
5 //
6
7 var FolderDDropControler;
8 var DropTarget;
9 var loadListing;
10 var DDFolderUploader;
11
12 (function(){
13
14 function getTargetRow(evt){
15 var target = getTargetedObject(evt);
16 while (target.nodeName !== "TR") {
17 target = target.parentNode; }
18 return target;
19 }
20
21 FolderDDropControler = function(listing, orderable, firstItemPos) {
22 this.folderUrl = document.getElementById("FolderUrl").innerHTML;
23 this.targetRow = null;
24 this.lastOverPosition = null;
25 this.prevDirUp = null;
26 this.noOver = true;
27 this.listing = listing;
28 this.firstItemPos = firstItemPos;
29 this._updatePositions();
30 this.lastCBChecked = undefined;
31 var thisControler = this;
32 if (orderable) {
33 this.listing.onmousedown = function(evt) {thisControler.drag(evt);};
34 this.listing.onmouseover = function(evt) {thisControler.moveRow(evt);};
35 this.listing.onmouseup = function(evt) {thisControler.drop(evt);};
36 addListener(this.listing, 'click', function(evt) {thisControler.disableClickAfterDrop(evt);});
37 }
38 addListener(this.listing, 'click', function(evt) {thisControler.selectCBRange(evt);});
39
40 if (browser.isIE10max) {
41 this.listing.ondragstart = function() { window.event.returnValue = false;};
42 }
43 };
44
45 FolderDDropControler.prototype._updatePositions = function() {
46 var rows = this.listing.getElementsByTagName("TR");
47 var i, row;
48 for (i=0 ; i < rows.length ; i++ ) {
49 row = rows[i];
50 row.pos = i + this.firstItemPos;
51 if (i % 2 === 0) {
52 row.className = "even"; }
53 else {
54 row.className = "odd"; }
55 }
56 };
57
58 FolderDDropControler.prototype.drag = function(evt){
59 var target = getTargetedObject(evt);
60 if (target.nodeName === "INPUT") { return true; }
61 disableDefault(evt);
62 var targetRow = getTargetRow(evt);
63 targetRow.style.backgroundColor = base_properties.highLightColor;
64 this.listing.style.cursor = "move";
65 this.targetRow = targetRow;
66 this.lastOverPosition = targetRow.pos;
67 };
68
69 FolderDDropControler.prototype.moveRow = function(evt){
70 var targetRow = this.targetRow;
71 if (targetRow !== null) {
72 this.noOver = false;
73 if (browser.isIE10max) {document.selection.clear();}
74 var overRow = getTargetRow(evt);
75
76 if (overRow.pos === targetRow.pos) {return;}
77
78 if (this.lastOverPosition < overRow.pos) { // move up
79 this.listing.insertBefore(targetRow, overRow.nextSibling);
80 this.prevDirUp = true;
81 this.lastOverPosition = overRow.pos;
82 }
83 else if (this.lastOverPosition > overRow.pos) { // move down
84 this.listing.insertBefore(targetRow, overRow);
85 this.prevDirUp = false;
86 this.lastOverPosition = overRow.pos;
87 }
88 else {
89 if (this.prevDirUp) {
90 this.prevDirUp = false;
91 this.listing.insertBefore(targetRow, overRow);
92 }
93 else {
94 this.prevDirUp = true;
95 this.listing.insertBefore(targetRow, overRow.nextSibling);
96 }
97 }
98 }
99 };
100
101 FolderDDropControler.prototype.drop = function(evt){
102 var targetRow = this.targetRow;
103 if (targetRow !== null) {
104 targetRow.style.backgroundColor="";
105 this.listing.style.cursor = "";
106 var thisControler = this;
107 if (this.noOver) {
108 setTimeout(function(){thisControler.reset();}, 50);
109 return;
110 }
111 if (this.lastOverPosition !== null) {
112 // get new object position.
113 var trim = 0;
114 if (targetRow.pos < this.lastOverPosition && !this.prevDirUp) {
115 trim = -1; }
116 else if (targetRow.pos > this.lastOverPosition && this.prevDirUp) {
117 trim = 1; }
118
119 // construct url
120 var object_id = targetRow.getElementsByTagName("INPUT")[0].getAttribute("value");
121 var url = this.folderUrl + "/moveObjectIdToPosition";
122 var form ="object_id=" + object_id + "&position:int=" +
123 String(this.lastOverPosition - 1 + trim);
124
125 // reinitialize positions
126 this._updatePositions();
127
128 // send request
129 var req = new XMLHttpRequest();
130 req.open("POST", url, true);
131 req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
132 req.send(form);
133 setTimeout(function(){thisControler.reset();}, 50);
134 }
135 }
136 };
137
138 FolderDDropControler.prototype.disableClickAfterDrop = function(evt) {
139 var target = getTargetedObject(evt);
140 if (!this.noOver) {
141 disablePropagation(evt);
142 disableDefault(evt);
143 }
144 this.reset();
145 };
146
147 FolderDDropControler.prototype.selectCBRange = function(evt) {
148 var target = getTargetedObject(evt);
149 if (target.tagName === 'INPUT' && target.type === 'checkbox') {
150 evt = getEventObject(evt);
151 var shift = evt.shiftKey;
152 if (shift && this.lastCBChecked) {
153 var from = this.getCBIndex(this.lastCBChecked);
154 var to = this.getCBIndex(target);
155 var rows = this.listing.getElementsByTagName('TR');
156 var start = Math.min(from, to);
157 var stop = Math.max(from, to);
158 var i;
159 for (i=start ; i<stop ; i++ ) {
160 rows[i].getElementsByTagName('INPUT')[0].checked = true;
161 }
162 }
163 else if (target.checked) {
164 this.lastCBChecked = target;
165 }
166 else {
167 this.lastCBChecked = undefined;
168 }
169 }
170 };
171
172 FolderDDropControler.prototype.getCBIndex = function(cb) {
173 var row = cb.parentNode;
174 while(row.tagName !== 'TR') {
175 row = row.parentNode;
176 }
177 return row.pos - this.firstItemPos;
178 };
179
180 FolderDDropControler.prototype.reset = function() {
181 this.targetRow = null;
182 this.lastOverPosition = null;
183 this.prevDirUp = null;
184 this.noOver = true;
185 };
186
187
188
189 DropTarget = function(node, folderDDControler) {
190 this.folderDDControler = folderDDControler;
191 this.batchSize = parseInt(document.getElementById("BatchNavigationSize").innerHTML, 10);
192 var thisControler = this;
193 node.onmouseup = function(evt){thisControler.drop(evt);};
194 node.onmouseover = function(evt) {thisControler.highlightTarget(evt);};
195 node.onmouseout = function(evt) {
196 var target = getTargetedObject(evt);
197 if (target.nodeName === "A" && target.className === "dropPageTarget"){
198 target.className = "";}
199 };
200 };
201
202 DropTarget.prototype.drop = function(evt) {
203 var target = getTargetedObject(evt);
204 if (target.nodeName === "A" &&
205 target.className !== "previous" &&
206 target.className !== "next") {
207 var pageNumber = parseInt(target.innerHTML, 10);
208 var targetRow = this.folderDDControler.targetRow;
209 if ( !isNaN(pageNumber) && targetRow) {
210 this.folderDDControler.reset();
211 var object_id = targetRow.getElementsByTagName("INPUT")[0].getAttribute("value");
212 var url = this.folderDDControler.folderUrl + "/moveObjectIdToPosition";
213 var form ="object_id=" + object_id + "&position:int=" + String(this.batchSize * (pageNumber-1));
214 // send request
215 var req = new XMLHttpRequest();
216 req.open("POST", url, true);
217 req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
218 req.send(form);
219 req.onreadystatechange = function() {
220 if (req.readyState === 4) {
221 switch (req.status) {
222 case 200:
223 case 204:
224 case 1223:
225 raiseMouseEvent(target, "click");
226 break;
227 default:
228 alert('Error: ' + req.status);
229 }
230 }
231 };
232 }
233 }
234 };
235
236 DropTarget.prototype.highlightTarget = function(evt){
237 if (browser.isIE10max) {document.selection.clear();}
238 var target = getTargetedObject(evt);
239 if (this.folderDDControler.targetRow &&
240 target.nodeName === "A" &&
241 target.className !== "previous" &&
242 target.className !== "next"){
243 target.className = "dropPageTarget";}
244 };
245
246
247
248
249 loadListing = function(evt) {
250 var target = getTargetedObject(evt);
251 disableDefault(evt);
252 disablePropagation(evt);
253 var url;
254 switch (target.nodeName) {
255 case "A" :
256 var parts = target.href.split('?');
257 url = parts[0];
258 var query = '';
259 if (parts.length === 2){
260 query = parts[1];}
261
262 var urlParts = url.split("/");
263 url = urlParts.slice(0,urlParts.length-1).join("/");
264 if (query.search("template") === -1){
265 query += "&template=folder_contents_macros&macro=FolderListing&fragmentId=FolderListing";}
266 url = url + "/folder_contents?" + query;
267
268 var fi = new FragmentImporter(url);
269 fi.load();
270 break;
271
272 case "IMG" :
273 if (target.id === 'SetSortingAsDefault') {
274 var parent = target.parentNode;
275 url = parent.href;
276 url = url.replace("folder_contents", "folder_sort_control");
277 parent.parentNode.removeChild(parent);
278
279 var req = new XMLHttpRequest();
280 req.open("GET", url, true);
281 req.send(null);
282 }
283 break;
284 }
285 return false;
286 };
287
288 DDFolderUploader = function(dropbox, uploadUrl, listing) {
289 DDFileUploaderBase.apply(this, [dropbox, uploadUrl]);
290 this.listing = listing;
291 this.progressBarMaxSize = listing.clientWidth;
292 var thead = listing;
293 do {
294 thead = thead.previousSibling;
295 } while (thead.tagName !== 'THEAD');
296
297 var cells = thead.getElementsByTagName('th');
298 var cell, i;
299 this.tableSpan = 0;
300 for (i=0 ; i < cells.length ; i++) {
301 cell = cells[i];
302 this.tableSpan += cell.getAttribute('colspan') ? Number(cell.getAttribute('colspan')) : 1;
303 }
304 var lastRow = listing.lastChild;
305 while(lastRow && lastRow.tagName !== 'TR') {
306 lastRow = lastRow.previousSibling;
307 }
308 this.lastRowClassName = lastRow ? lastRow.className : 'even';
309 };
310
311 copyPrototype(DDFolderUploader, DDFileUploaderBase);
312
313
314 DDFolderUploader.prototype.createRow = function(file) {
315 var row = document.createElement('tr');
316 row.file = file;
317 row.className = this.lastRowClassName === 'even' ? 'odd' : 'even';
318 this.lastRowClassName = row.className;
319 var td = document.createElement('td');
320 td.setAttribute('colspan', this.tableSpan);
321 var relSpan = document.createElement('span');
322 relSpan.style.position = 'relative';
323 td.appendChild(relSpan);
324 var progressBar = document.createElement('span');
325 progressBar.className = 'upload-progress';
326 row.progressBar = progressBar;
327 relSpan.appendChild(progressBar);
328 var fileNameSpan = document.createElement('span');
329 fileNameSpan.innerHTML = file.name;
330 td.appendChild(fileNameSpan);
331 row.appendChild(td);
332 this.listing.appendChild(row);
333 this.progressBarMaxSize = row.clientWidth;
334 return row;
335 };
336
337 // Methods about upload
338 DDFolderUploader.prototype.handleFiles = function(files) {
339 var file, i, row;
340 for (i = 0; i < files.length; i++) {
341 file = files[i];
342 row = this.createRow(file);
343 this.uploadQueuePush(row);
344 }
345 };
346
347 DDFolderUploader.prototype.beforeUpload = function(item) {
348 this.uploadedItem = item;
349 this.progressBar = item.progressBar;
350 };
351
352 DDFolderUploader.prototype.uploadCompleteHandlerCB = function(req) {
353 var item = this.uploadedItem;
354 var row = getCopyOfNode(req.responseXML.documentElement.firstChild);
355
356 if (req.status === 200) {
357 // update
358 this.listing.removeChild(item);
359 var itemUrl = row.getElementsByTagName('a')[0].href;
360 var links = this.listing.getElementsByTagName('a');
361 var i, existingRow;
362 for (i=0 ; i < links.length ; i++) {
363 if (links[i].href === itemUrl) {
364 existingRow = links[i].parentNode.parentNode;
365 row.className = existingRow.className;
366 this.listing.replaceChild(row, existingRow);
367 break;
368 }
369 }
370 }
371 else if(req.status === 201) {
372 // creation
373 row.className = item.className;
374 this.listing.replaceChild(row, item);
375 this.progressBarMaxSize = row.clientWidth;
376 }
377 };
378
379 DDFolderUploader.prototype.progressHandlerCB = function(progress) {
380 // 0 <= progress <= 1
381 var size = this.progressBarMaxSize * progress;
382 size = Math.round(size);
383 this.progressBar.style.width = size + 'px';
384 };
385
386 }());