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