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