]> gitweb @ CieloNegro.org - Rakka.git/blob - js/editPage.js
implemented page listing
[Rakka.git] / js / editPage.js
1 (function () {
2
3     var $previewHeader = null;
4     var $previewArea   = null;
5
6     var isDirty = null;
7
8     Rakka.editPage = function (pageName) {
9         var $area = Rakka.switchScreen();
10
11         Rakka.displayWaitingMessage("Loading... please wait.");
12     
13         // XML 版のページを取得する。
14         $.ajax({
15             url    : Rakka.baseURI + pageName + ".xml",
16             success: function (pageXml) {
17                 Rakka.hideWaitingMessage();
18
19                 if (pageXml.documentElement.tagName == "page") {
20                     var $page       = $(pageXml).find("page");
21                     var oldRevision = $page.attr("revision");
22                     var defaultType
23                         = $page.attr("isBinary") == "yes"          ? "binary"
24                         : $page.attr("type")     == "text/x-rakka" ? "rakka"
25                         : $page.attr("type")     == "text/css"     ? "css"
26                         : $page.attr("redirect") != null           ? "redirect"
27                         :                                            "unknown"
28                         ;
29                     var isLocked    = $page.attr("isLocked") == "yes";
30                     var source
31                         = $page.attr("redirect") != null ? $page.attr("redirect")
32                         : $page.find("textData").text()
33                         ;
34                     var summary     = $page.find("summary").text();
35                 
36                     displayPageEditor(pageName, oldRevision, defaultType, isLocked, source, summary);
37                 }
38                 else {
39                     displayPageEditor(pageName, null, "rakka", false, null, "");
40                 }
41             },
42             error  : function (req) {
43                 Rakka.hideWaitingMessage();
44                 
45                 if (req.status == 404) {
46                     displayPageEditor(pageName, null, "rakka", false, null, "");
47                 }
48                 else {
49                     $area.text("Error: " + req.status + " " + req.statusText);
50                 }
51             }
52         });
53     };
54
55     Rakka.newPage = function () {
56         displayPageEditor("", null, "rakka", false, null, "");
57     };
58
59     var displayPageEditor = function (pageName, oldRevision, defaultType, isLocked, source, summary) {
60         var $area = Rakka.switchScreen();
61
62         $previewHeader = $( $.H1({}, "Preview") );
63         $area.append($previewHeader);
64         $previewHeader.hide();
65
66         $previewArea = $( $.DIV({className: "preview"}) );
67         $area.append($previewArea);
68         $previewArea.hide();
69
70         $area.append($.H1({}, pageName == "" ? "Create page" : "Edit page"));
71
72         var makeDirty = function () {
73             isDirty = true;
74         };
75     
76         var fldPageName
77             = $.INPUT({type : "text", value: pageName});
78
79         $(fldPageName).change(makeDirty);
80
81         var chkIsLocked
82             = $.INPUT({type    : "checkbox",
83                        checked : (isLocked ? "checked" : "")});
84
85         $(chkIsLocked).change(makeDirty);
86
87         var trIsLocked
88             = $.TR({},
89                    $.TH({}, "Page lock"),
90                    $.TD({},
91                         $.LABEL({},
92                                 chkIsLocked,
93                                 "Disallow anonymous users to edit or delete this page")));
94         
95         var btnTypeRakka
96             = $.INPUT({type   : "radio",
97                        name   : "type",
98                        checked: (defaultType == "rakka"    ? "checked" : "")});
99
100         $(btnTypeRakka).change(makeDirty);
101
102         var btnTypeCSS
103             = $.INPUT({type   : "radio",
104                        name   : "type",
105                        checked: (defaultType == "css"      ? "checked" : "")});
106
107         $(btnTypeCSS).change(makeDirty);
108
109         var btnTypeBinary
110             = $.INPUT({type   : "radio",
111                        name   : "type",
112                        checked: (defaultType == "binary"   ? "checked" : "")});
113
114         $(btnTypeBinary).change(makeDirty);
115
116         var btnTypeRedirect
117             = $.INPUT({type   : "radio",
118                        name   : "type",
119                        checked: (defaultType == "redirect" ? "checked" : "")});
120
121         $(btnTypeRedirect).change(makeDirty);
122
123         var fldSummary
124             = $.TEXTAREA({className: "summary"}, summary);
125
126         $(fldSummary).change(makeDirty);
127
128         var trSummary
129             = $.TR({},
130                    $.TH({}, "Summary"),
131                    $.TD({}, fldSummary));
132
133         var fldRakkaSource
134             = $.TEXTAREA({className: "source"},
135                          (defaultType == "rakka" && source != null ? source : ""));
136
137         $(fldRakkaSource).change(makeDirty);
138
139         var fldCSSSource
140             = $.TEXTAREA({className: "source"},
141                          (defaultType == "css"   && source != null ? source : ""));
142
143         $(fldCSSSource).change(makeDirty);
144
145         var fldUploadFile
146             = $.INPUT({type: "file"});
147
148         $(fldUploadFile).change(makeDirty);
149
150         var fldRedirect
151             = $.INPUT({type: "text", value: (defaultType == "redirect" ? source : "")});
152
153         $(fldRedirect).change(makeDirty);
154
155         var trContent
156             = $.TR({}, 
157                    $.TH({}),
158                    $.TD({})
159                   );
160
161         var btnPreview
162             = $.INPUT({type: "button", value: "Preview page"});
163         
164         $(btnPreview).click(function () {
165             if (btnTypeRakka.checked) {
166                 previewRakkaPage(
167                     fldPageName.value, fldRakkaSource.value);
168             }
169             else if (btnTypeBinary.checked) {
170                 previewBinaryPage(
171                     fldPageName.value, fldUploadFile.value);
172             }
173         });
174
175         var btnSubmit
176             = $.INPUT({type: "button", value: "Submit page"});
177         
178         $(btnSubmit).click(function () {
179             if (btnTypeRakka.checked) {
180                 submitTextPage(
181                     pageName,
182                     oldRevision,
183                     fldPageName.value,
184                     chkIsLocked.checked,
185                     "text/x-rakka",
186                     fldSummary.value,
187                     fldRakkaSource.value);
188             }
189             else if (btnTypeCSS.checked) {
190                 submitTextPage(
191                     pageName,
192                     oldRevision,
193                     fldPageName.value,
194                     chkIsLocked.checked,
195                     "text/css",
196                     fldSummary.value,
197                     fldCSSSource.value);
198             }
199             else if (btnTypeBinary.checked) {
200                 submitBinaryPage(
201                     pageName,
202                     oldRevision,
203                     fldPageName.value,
204                     chkIsLocked.checked,
205                     fldSummary.value,
206                     fldUploadFile.value);
207             }
208             else if (btnTypeRedirect.checked) {
209                 submitRedirection(
210                     pageName,
211                     oldRevision,
212                     fldPageName.value,
213                     chkIsLocked.checked,
214                     fldRedirect.value);
215             }
216         });
217
218         var btnDelete
219             = $.INPUT({type: "button", value: "Delete this page"});
220         
221         $(btnDelete).click(function () {
222             if (window.confirm("Do you really want to delete this page?")) {
223                 deletePage(pageName);
224             }
225         });
226
227         var btnCancel
228             = $.INPUT({type: "button", value: "Cancel editing"});
229
230         $(btnCancel).click(function () {
231             if (isDirty) {
232                 if (window.confirm("Do you really want to discard changes?")) {
233                     Rakka.restoreScreen();
234                 }
235             }
236             else {
237                 Rakka.restoreScreen();
238             }
239         });
240
241         var updateTRContent = function () {
242             if (btnTypeRakka.checked) {
243                 $(trSummary).show();
244                 $(trContent).find("th").text("Wiki source");
245                 $(trContent).find("td").empty().append(fldRakkaSource);
246                 $(btnPreview).show();
247             }
248             else if (btnTypeCSS.checked) {
249                 $(trSummary).show();
250                 $(trContent).find("th").text("CSS source");
251                 $(trContent).find("td").empty().append(fldCSSSource);
252                 $(btnPreview).hide();
253             }
254             else if (btnTypeBinary.checked) {
255                 $(trSummary).show();
256                 $(trContent).find("th").text("File");
257                 $(trContent).find("td").empty().append(fldUploadFile);
258                 $(btnPreview).show();
259             }
260             else if (btnTypeRedirect.checked) {
261                 $(trSummary).hide();
262                 $(trContent).find("th").text("Destination Page");
263                 $(trContent).find("td").empty().append(fldRedirect);
264                 $(btnPreview).hide();
265             }
266         };
267         $(btnTypeRakka   ).change(updateTRContent);
268         $(btnTypeCSS     ).change(updateTRContent);
269         $(btnTypeBinary  ).change(updateTRContent);
270         $(btnTypeRedirect).change(updateTRContent);
271         updateTRContent();
272
273         var pageEditor
274             = $.TABLE({className: "pageEditor"},
275                       $.TBODY({},
276                               $.TR({},
277                                    $.TH({}, "Page name"),
278                                    $.TD({}, fldPageName)
279                                   ),
280                               trIsLocked,
281                               $.TR({},
282                                    $.TH({}, "Page type"),
283                                    $.TD({},
284                                         $.UL({},
285                                              $.LI({},
286                                                   $.LABEL({},
287                                                           btnTypeRakka,
288                                                           "Wiki page"
289                                                          )
290                                                  ),
291                                              $.LI({},
292                                                   $.LABEL({},
293                                                           btnTypeCSS,
294                                                           "Style sheet"
295                                                          )
296                                                  ),
297                                              $.LI({},
298                                                   $.LABEL({},
299                                                           btnTypeBinary,
300                                                           "Binary file"
301                                                          )
302                                                  ),
303                                              $.LI({},
304                                                   $.LABEL({},
305                                                           btnTypeRedirect,
306                                                           "Redirection"
307                                                          )
308                                                  )
309                                             )
310                                        )
311                                   ),
312                               trSummary,
313                               trContent,
314                               $.TR({},
315                                    $.TH({}),
316                                    $.TD({}, btnPreview, btnSubmit, btnDelete, btnCancel)
317                                   )
318                              )
319                      );
320
321         if (oldRevision == null || oldRevision == 0) {
322             // 削除不可
323             $(btnDelete).hide();
324         }
325
326         $area.append(pageEditor);
327
328         if (!Rakka.isLoggedIn() || Rakka.isGlobalLocked) {
329             $(trIsLocked).hide();
330         }
331
332         isDirty = false;
333     };
334
335     var previewRakkaPage = function (pageName, source) {
336         Rakka.displayWaitingMessage("Loading... please wait.");
337         
338         var url = Rakka.baseURI + "render/" + encodeURI(pageName);
339         $.ajax({
340             type       : "POST",
341             url        : url,
342             contentType: "text/x-rakka",
343             data       : source,
344             processData: false,
345             success    : function (resultDoc) {
346                 Rakka.hideWaitingMessage();
347                 showPreview(resultDoc);
348             },
349             error      : function (req) {
350                 Rakka.hideWaitingMessage();
351                 alert("Error: " + req.status + " " + req.statusText);
352             }
353         });
354     };
355
356     var previewBinaryPage = function (pageName, path) {
357         Rakka.displayWaitingMessage("Loading... please wait.");
358
359         /* Firefox でバイナリを送らうとすると 0x00 の位置で切れてしまふ。*/
360         var bin = Rakka.loadLocalBinaryFile(path);
361         var url = Rakka.baseURI + "render/" + encodeURI(pageName);
362         $.ajax({
363             type       : "POST",
364             url        : url,
365             contentType: "application/x-rakka-base64-stream",
366             data       : Rakka.encodeBase64(bin),
367             processData: false,
368             success    : function (resultDoc) {
369                 Rakka.hideWaitingMessage();
370                 showPreview(resultDoc);
371             },
372             error      : function (req) {
373                 Rakka.hideWaitingMessage();
374                 alert("Error: " + req.status + " " + req.statusText);
375             }
376         });
377     };
378
379     var showPreview = function (doc) {
380         $previewArea.empty();
381         
382         $previewHeader.show();
383         $previewArea.show();
384         
385         var root  = doc.documentElement;
386         var child = root.firstChild;
387         do {
388             if (child.nodeType == 1) {
389                 // 要素だったので複製
390                 $previewArea.append(child.cloneNode(true));
391             }
392         } while (child = child.nextSibling);
393
394         Rakka.scrollToTopLeft();
395     };
396
397     var submitTextPage = function (pageName, oldRevision, givenPageName, isLocked, mimeType, summary, text) {
398         var doc = document.implementation.createDocument(
399             "http://cielonegro.org/schema/Rakka/Page/1.0", "page", null);
400
401         var page = doc.documentElement;
402
403         if (oldRevision != null) {
404             // ページ書換時
405             var updateInfo = doc.createElement("updateInfo");
406             updateInfo.setAttribute("oldRevision", oldRevision);
407
408             if (pageName != givenPageName) {
409                 var move = doc.createElement("move");
410                 move.setAttribute("from", pageName);
411                 updateInfo.appendChild(move);
412             }
413
414             page.appendChild(updateInfo);
415         }
416
417         page.setAttribute("isLocked", isLocked ? "yes" : "no");
418         page.setAttribute("type", mimeType);
419
420         if (summary != null) {
421             var s = doc.createElement("summary");
422             s.appendChild(
423                 doc.createTextNode(summary));
424             page.appendChild(s);
425         }
426
427         var textData = doc.createElement("textData");
428         textData.appendChild(
429             doc.createTextNode(text));
430
431         page.appendChild(textData);
432
433         Rakka.displayWaitingMessage("Submitting... please wait.");
434
435         var url = Rakka.baseURI + encodeURI(givenPageName);
436         $.ajax({
437             type       : "PUT",
438             url        : url,
439             contentType: "text/xml",
440             data       : doc,
441             processData: false,
442             beforeSend : function (req) {
443                 Rakka.setAuthorization(req);
444             },
445             success    : function () {
446                 window.location.replace(url);
447             },
448             error      : function (req) {
449                 Rakka.hideWaitingMessage();
450                 
451                 var $area = Rakka.switchScreen();
452                 $area.text("Error: " + req.status + " " + req.statusText);
453             }
454         });
455     };
456
457     var submitBinaryPage = function (pageName, oldRevision, givenPageName, isLocked, summary, path) {
458         var doc = document.implementation.createDocument(
459             "http://cielonegro.org/schema/Rakka/Page/1.0", "page", null);
460
461         var page = doc.documentElement;
462
463         if (oldRevision != null) {
464             // ページ書換時
465             var updateInfo = doc.createElement("updateInfo");
466             updateInfo.setAttribute("oldRevision", oldRevision);
467
468             if (pageName != givenPageName) {
469                 var move = doc.createElement("move");
470                 move.setAttribute("from", pageName);
471                 updateInfo.appendChild(move);
472             }
473
474             page.appendChild(updateInfo);
475         }
476
477         page.setAttribute("isLocked", isLocked ? "yes" : "no");
478         page.setAttribute("type", "");
479
480         if (summary != null) {
481             var s = doc.createElement("summary");
482             s.appendChild(
483                 doc.createTextNode(summary));
484             page.appendChild(s);
485         }
486
487         var bin = Rakka.loadLocalBinaryFile(path);
488         var b64 = Rakka.encodeBase64(bin);
489
490         var binaryData = doc.createElement("binaryData");
491         binaryData.appendChild(
492             doc.createTextNode(b64));
493
494         page.appendChild(binaryData);
495
496         Rakka.displayWaitingMessage("Submitting... please wait.");
497
498         var url = Rakka.baseURI + encodeURI(givenPageName);
499         $.ajax({
500             type       : "PUT",
501             url        : url,
502             contentType: "text/xml",
503             data       : doc,
504             processData: false,
505             beforeSend : function (req) {
506                 Rakka.setAuthorization(req);
507             },
508             success    : function () {
509                 window.location.replace(url);
510             },
511             error      : function (req) {
512                 Rakka.hideWaitingMessage();
513                 
514                 var $area = Rakka.switchScreen();
515                 $area.text("Error: " + req.status + " " + req.statusText);
516             }
517         });
518     };
519
520     var submitRedirection = function (pageName, oldRevision, givenPageName, isLocked, destination) {
521         var doc = document.implementation.createDocument(
522             "http://cielonegro.org/schema/Rakka/Page/1.0", "page", null);
523
524         var page = doc.documentElement;
525
526         if (oldRevision != null) {
527             // ページ書換時
528             var updateInfo = doc.createElement("updateInfo");
529             updateInfo.setAttribute("oldRevision", oldRevision);
530
531             if (pageName != givenPageName) {
532                 var move = doc.createElement("move");
533                 move.setAttribute("from", pageName);
534                 updateInfo.appendChild(move);
535             }
536
537             page.appendChild(updateInfo);
538         }
539
540         page.setAttribute("isLocked", isLocked ? "yes" : "no");
541         page.setAttribute("redirect", destination);
542
543         Rakka.displayWaitingMessage("Submitting... please wait.");
544
545         var url = Rakka.baseURI + encodeURI(givenPageName);
546         $.ajax({
547             type       : "PUT",
548             url        : url,
549             contentType: "text/xml",
550             data       : doc,
551             processData: false,
552             beforeSend : function (req) {
553                 Rakka.setAuthorization(req);
554             },
555             success    : function () {
556                 window.location.replace(url);
557             },
558             error      : function (req) {
559                 Rakka.hideWaitingMessage();
560                 
561                 var $area = Rakka.switchScreen();
562                 $area.text("Error: " + req.status + " " + req.statusText);
563             }
564         });
565     };
566
567     var deletePage = function (pageName) {
568         var url = Rakka.baseURI + encodeURI(pageName);
569         $.ajax({
570             type       : "DELETE",
571             url        : url,
572             beforeSend : function (req) {
573                 Rakka.setAuthorization(req);
574             },
575             success    : function () {
576                 window.location.replace(url);
577             },
578             error      : function (req) {
579                 Rakka.hideWaitingMessage();
580                 
581                 var $area = Rakka.switchScreen();
582                 $area.text("Error: " + req.status + " " + req.statusText);
583             }
584         });
585     };
586
587 })();