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