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