X-Git-Url: http://git.cielonegro.org/gitweb.cgi?a=blobdiff_plain;f=js%2FeditPage.js;h=1843be911ae682ce4b3347c1d10a9509c878c9c4;hb=c21f22c897782e6d49ce1e8cd06e2cb27d02d2f6;hp=d50e5b40c6003c32d2029285366c2e72dd23886a;hpb=443af4d3304139bb2187a0c726327b9c05829810;p=Rakka.git diff --git a/js/editPage.js b/js/editPage.js index d50e5b4..1843be9 100644 --- a/js/editPage.js +++ b/js/editPage.js @@ -3,41 +3,55 @@ var $previewHeader = null; var $previewArea = null; - var isDirty = null; - Rakka.editPage = function (pageName) { var $area = Rakka.switchScreen(); Rakka.displayWaitingMessage("Loading... please wait."); - + // XML 版のページを取得する。 $.ajax({ url : Rakka.baseURI + pageName + ".xml", success: function (pageXml) { Rakka.hideWaitingMessage(); - - var $page = $(pageXml).find("page"); - var oldRevision = $page.attr("revision"); - var defaultType - = $page.attr("isBinary") == "yes" ? "binary" - : $page.attr("type") == "text/x-rakka" ? "rakka" - : $page.attr("type") == "text/css" ? "css" - : $page.attr("redirect") != null ? "redirect" - : "unknown" - ; - var source - = $page.attr("redirect") != null ? $page.attr("redirect") - : $page.find("textData").text() - ; - var summary = $page.find("summary").text(); - - displayPageEditor(pageName, oldRevision, defaultType, source, summary); + + if (pageXml.documentElement.tagName == "page") { + var $page = $(pageXml).find("page"); + var oldRevision = $page.attr("revision"); + var defaultType + = $page.attr("isBinary") == "yes" ? "binary" + : $page.attr("type") == "text/x-rakka" ? "rakka" + : $page.attr("type") == "text/css" ? "css" + : $page.attr("type") == "text/javascript" ? "js" + : $page.attr("redirect") != null ? "redirect" + : "unknown" + ; + var lang = $page.attr("lang"); + var isLocked = $page.attr("isLocked") == "yes"; + var otherLangs = (function () { + var obj = {}; + $page.find("otherLang > link").each(function () { + obj[this.getAttribute("lang")] = this.getAttribute("page"); + }); + return obj; + })(); + var source + = $page.attr("redirect") != null ? $page.attr("redirect") + : $page.attr("isBinary") == "yes" ? Rakka.decodeBase64($page.find("binaryData").text()) + : $page.find("textData").text() + ; + var summary = $page.find("summary").text(); + + displayPageEditor(pageName, oldRevision, defaultType, lang, isLocked, otherLangs, source, summary); + } + else { + displayPageEditor(pageName, null, "rakka", null, false, {}, null, ""); + } }, error : function (req) { Rakka.hideWaitingMessage(); - + if (req.status == 404) { - displayPageEditor(pageName, null, "rakka", null, ""); + displayPageEditor(pageName, null, "rakka", null, false, {}, null, ""); } else { $area.text("Error: " + req.status + " " + req.statusText); @@ -47,10 +61,10 @@ }; Rakka.newPage = function () { - displayPageEditor("", null, "rakka", null, ""); + displayPageEditor("", null, "rakka", null, false, {}, null, ""); }; - var displayPageEditor = function (pageName, oldRevision, defaultType, source, summary) { + var displayPageEditor = function (pageName, oldRevision, defaultType, lang, isLocked, otherLangs, source, summary) { var $area = Rakka.switchScreen(); $previewHeader = $( $.H1({}, "Preview") ); @@ -63,15 +77,30 @@ $area.append($.H1({}, pageName == "" ? "Create page" : "Edit page")); + var isDirty = null; var makeDirty = function () { isDirty = true; }; - + var fldPageName = $.INPUT({type : "text", value: pageName}); $(fldPageName).change(makeDirty); + var chkIsLocked + = $.INPUT({type : "checkbox", + checked : (isLocked ? "checked" : "")}); + + $(chkIsLocked).change(makeDirty); + + var trIsLocked + = $.TR({}, + $.TH({}, "Page lock"), + $.TD({}, + $.LABEL({}, + chkIsLocked, + "Disallow anonymous users to edit or delete this page"))); + var btnTypeRakka = $.INPUT({type : "radio", name : "type", @@ -86,6 +115,12 @@ $(btnTypeCSS).change(makeDirty); + var btnTypeJS + = $.INPUT({type : "radio", + name : "type", + checked: (defaultType == "js" ? "checked" : "")}); + $(btnTypeJS).change(makeDirty); + var btnTypeBinary = $.INPUT({type : "radio", name : "type", @@ -100,6 +135,72 @@ $(btnTypeRedirect).change(makeDirty); + var selPageLang + = $.SELECT({}, + $.OPTION({value: ""}, "(unspecified)"), + (function () { + var options = []; + + $.each(Rakka.getSystemConfig().languages, function (tag, name) { + options.push( + $.OPTION({value: tag}, name)); + }); + + return options; + })()); + + $(selPageLang).change(makeDirty); + + if (lang == null || lang == "") { + $(selPageLang).val($("html").attr("xml:lang")); + } + else { + $(selPageLang).val(lang); + } + + var trPageLang + = $.TR({}, + $.TH({}, "Page language"), + $.TD({}, selPageLang)); + + var trOtherLangs = (function () { + var options = []; + + $.each(Rakka.getSystemConfig().languages, function (tag, name) { + options.push( + $.OPTION({value: tag}, name)); + }); + + var selLang = $.SELECT({}, options); + var fldLink = $.INPUT({type: "text", className: "smallField"}); + + $(selLang).change(function () { + var pageName = otherLangs[$(selLang).val()]; + $(fldLink).val( + pageName == null ? "" : pageName + ); + }).trigger("change"); + + var onLinkChanged = function () { + isDirty = true; + + var lang = $(selLang).val(); + var pageName = $(this).val(); + + if (pageName == "") { + delete otherLangs[lang]; + } + else { + otherLangs[lang] = pageName; + } + }; + $(fldLink).change(onLinkChanged).keyup(onLinkChanged); + + return $.TR({}, + $.TH({}, "Language links"), + $.TD({}, selLang, fldLink)); + })(); + var fldSummary = $.TEXTAREA({className: "summary"}, summary); @@ -122,10 +223,27 @@ $(fldCSSSource).change(makeDirty); - var fldUploadFile - = $.INPUT({type: "file"}); + var fldJSSource + = $.TEXTAREA({className: "source"}, + (defaultType == "js" && source != null ? source : "")); + + $(fldJSSource).change(makeDirty); - $(fldUploadFile).change(makeDirty); + var uploadFileBin + = (defaultType == "binary" && source != null ? source : ""); + var fldUploadFile + = $.TEXTAREA({className: "hexDump", disabled: true}, Rakka.hexDump(uploadFileBin, 128)); + var btnSelectFile + = $.INPUT({type: "button", value: "Select file..."}); + + $(btnSelectFile).click(function () { + var file = Rakka.selectFile("Select a binary file to upload", "open"); + if (file != null) { + uploadFileBin = Rakka.loadLocalBinaryFile(file); + fldUploadFile.value = Rakka.hexDump(uploadFileBin, 128); + makeDirty(); + } + }); var fldRedirect = $.INPUT({type: "text", value: (defaultType == "redirect" ? source : "")}); @@ -133,35 +251,40 @@ $(fldRedirect).change(makeDirty); var trContent - = $.TR({}, + = $.TR({}, $.TH({}), $.TD({}) ); var btnPreview = $.INPUT({type: "button", value: "Preview page"}); - + $(btnPreview).click(function () { if (btnTypeRakka.checked) { previewRakkaPage( fldPageName.value, fldRakkaSource.value); } else if (btnTypeBinary.checked) { - previewBinaryPage( - fldPageName.value, fldUploadFile.value); + if (uploadFileBin != "") { + previewBinaryPage( + fldPageName.value, uploadFileBin); + } } }); var btnSubmit = $.INPUT({type: "button", value: "Submit page"}); - + $(btnSubmit).click(function () { if (btnTypeRakka.checked) { submitTextPage( pageName, oldRevision, fldPageName.value, + chkIsLocked.checked, "text/x-rakka", + $(selPageLang).val(), + otherLangs, fldSummary.value, fldRakkaSource.value); } @@ -170,70 +293,93 @@ pageName, oldRevision, fldPageName.value, + chkIsLocked.checked, "text/css", + $(selPageLang).val(), + otherLangs, fldSummary.value, fldCSSSource.value); } - else if (btnTypeBinary.checked) { - submitBinaryPage( + else if (btnTypeJS.checked) { + submitTextPage( pageName, oldRevision, fldPageName.value, + chkIsLocked.checked, + "text/javascript", + $(selPageLang).val(), + otherLangs, fldSummary.value, - fldUploadFile.value); + fldJSSource.value); + } + else if (btnTypeBinary.checked) { + if (fldUploadFile.value != "") { + submitBinaryPage( + pageName, + oldRevision, + fldPageName.value, + chkIsLocked.checked, + $(selPageLang).val(), + otherLangs, + fldSummary.value, + uploadFileBin); + } } else if (btnTypeRedirect.checked) { submitRedirection( pageName, oldRevision, fldPageName.value, + chkIsLocked.checked, fldRedirect.value); } }); var btnDelete = $.INPUT({type: "button", value: "Delete this page"}); - + $(btnDelete).click(function () { if (window.confirm("Do you really want to delete this page?")) { deletePage(pageName); } }); - var btnCancel - = $.INPUT({type: "button", value: "Cancel editing"}); - - $(btnCancel).click(function () { - if (isDirty) { - if (window.confirm("Do you really want to discard changes?")) { - Rakka.restoreScreen(); - } - } - else { - Rakka.restoreScreen(); - } - }); - var updateTRContent = function () { if (btnTypeRakka.checked) { + $(trPageLang).show(); + $(trOtherLangs).show(); $(trSummary).show(); $(trContent).find("th").text("Wiki source"); $(trContent).find("td").empty().append(fldRakkaSource); $(btnPreview).show(); } else if (btnTypeCSS.checked) { + $(trPageLang).show(); + $(trOtherLangs).show(); $(trSummary).show(); $(trContent).find("th").text("CSS source"); $(trContent).find("td").empty().append(fldCSSSource); $(btnPreview).hide(); } + else if (btnTypeJS.checked) { + $(trPageLang).show(); + $(trOtherLangs).show(); + $(trSummary).show(); + $(trContent).find("th").text("JavaScript source"); + $(trContent).find("td").empty().append(fldJSSource); + $(btnPreview).hide(); + } else if (btnTypeBinary.checked) { + $(trPageLang).show(); + $(trOtherLangs).show(); $(trSummary).show(); $(trContent).find("th").text("File"); - $(trContent).find("td").empty().append(fldUploadFile); + $(trContent).find("td").empty().append(fldUploadFile).append(btnSelectFile); $(btnPreview).show(); } else if (btnTypeRedirect.checked) { + $(trPageLang).hide(); + $(trOtherLangs).hide(); $(trSummary).hide(); $(trContent).find("th").text("Destination Page"); $(trContent).find("td").empty().append(fldRedirect); @@ -242,6 +388,7 @@ }; $(btnTypeRakka ).change(updateTRContent); $(btnTypeCSS ).change(updateTRContent); + $(btnTypeJS ).change(updateTRContent); $(btnTypeBinary ).change(updateTRContent); $(btnTypeRedirect).change(updateTRContent); updateTRContent(); @@ -253,6 +400,7 @@ $.TH({}, "Page name"), $.TD({}, fldPageName) ), + trIsLocked, $.TR({}, $.TH({}, "Page type"), $.TD({}, @@ -269,6 +417,12 @@ "Style sheet" ) ), + $.LI({}, + $.LABEL({}, + btnTypeJS, + "JavaScript" + ) + ), $.LI({}, $.LABEL({}, btnTypeBinary, @@ -284,15 +438,61 @@ ) ) ), + trPageLang, + trOtherLangs, trSummary, trContent, $.TR({}, $.TH({}), - $.TD({}, btnPreview, btnSubmit, btnDelete, btnCancel) + $.TD({}, btnPreview, btnSubmit, btnDelete) ) ) ); + var validate = function () { + var isValid = (function () { + if (fldPageName.value.match(Rakka.rePageName) == null) { + return false; + } + + if (btnTypeRedirect.checked) { + if (fldRedirect.value.match(Rakka.rePageName) == null) { + return false; + } + } + else { + for (var tag in otherLangs) { + if (otherLangs[tag].match(Rakka.rePageName) == null) { + return false; + } + } + + if (btnTypeBinary.checked) { + if (uploadFileBin == "") { + return false; + } + } + } + + return true; + })(); + + $(btnSubmit).attr({disabled: (isValid ? "" : "disabled")}); + }; + $(fldPageName) + .add(btnTypeRakka) + .add(btnTypeCSS) + .add(btnTypeJS) + .add(btnTypeBinary) + .add(btnTypeRedirect) + .add($(trOtherLangs).find("input")) + .add(fldUploadFile) + .add(fldRedirect) + .change(validate) + .keyup(validate); + $(btnSelectFile).click(validate); + validate(); + if (oldRevision == null || oldRevision == 0) { // 削除不可 $(btnDelete).hide(); @@ -300,12 +500,14 @@ $area.append(pageEditor); - isDirty = false; + if (!Rakka.isLoggedIn() || Rakka.isGlobalLocked) { + $(trIsLocked).hide(); + } }; var previewRakkaPage = function (pageName, source) { Rakka.displayWaitingMessage("Loading... please wait."); - + var url = Rakka.baseURI + "render/" + encodeURI(pageName); $.ajax({ type : "POST", @@ -324,17 +526,16 @@ }); }; - var previewBinaryPage = function (pageName, path) { + var previewBinaryPage = function (pageName, data) { Rakka.displayWaitingMessage("Loading... please wait."); /* Firefox でバイナリを送らうとすると 0x00 の位置で切れてしまふ。*/ - var bin = Rakka.loadLocalBinaryFile(path); var url = Rakka.baseURI + "render/" + encodeURI(pageName); $.ajax({ type : "POST", url : url, contentType: "application/x-rakka-base64-stream", - data : Rakka.encodeBase64(bin), + data : Rakka.encodeBase64(data), processData: false, success : function (resultDoc) { Rakka.hideWaitingMessage(); @@ -349,10 +550,10 @@ var showPreview = function (doc) { $previewArea.empty(); - + $previewHeader.show(); $previewArea.show(); - + var root = doc.documentElement; var child = root.firstChild; do { @@ -365,19 +566,19 @@ Rakka.scrollToTopLeft(); }; - var submitTextPage = function (pageName, oldRevision, givenPageName, mimeType, summary, text) { - var doc = document.implementation.createDocument( - "http://cielonegro.org/schema/Rakka/Page/1.0", "page", null); - - var page = doc.documentElement; + var submitTextPage + = function (pageName, oldRevision, givenPageName, isLocked, mimeType, lang, otherLangs, summary, text) { + var NS = "http://cielonegro.org/schema/Rakka/Page/1.0"; + var doc = document.implementation.createDocument(NS, "page", null); + var page = doc.documentElement; if (oldRevision != null) { // ページ書換時 - var updateInfo = doc.createElement("updateInfo"); + var updateInfo = doc.createElementNS(NS, "updateInfo"); updateInfo.setAttribute("oldRevision", oldRevision); if (pageName != givenPageName) { - var move = doc.createElement("move"); + var move = doc.createElementNS(NS, "move"); move.setAttribute("from", pageName); updateInfo.appendChild(move); } @@ -385,16 +586,30 @@ page.appendChild(updateInfo); } + page.setAttribute("isLocked", isLocked ? "yes" : "no"); page.setAttribute("type", mimeType); - if (summary != null) { - var s = doc.createElement("summary"); + if (lang != null && lang != "") { + page.setAttribute("lang", lang); + } + + if (summary != null && summary != "") { + var s = doc.createElementNS(NS, "summary"); s.appendChild( doc.createTextNode(summary)); page.appendChild(s); } - var textData = doc.createElement("textData"); + var oLang = doc.createElementNS(NS, "otherLang"); + for (var tag in otherLangs) { + var link = doc.createElementNS(NS, "link"); + link.setAttribute("lang", tag); + link.setAttribute("page", otherLangs[tag]); + oLang.appendChild(link); + } + page.appendChild(oLang); + + var textData = doc.createElementNS(NS, "textData"); textData.appendChild( doc.createTextNode(text)); @@ -417,26 +632,25 @@ }, error : function (req) { Rakka.hideWaitingMessage(); - + var $area = Rakka.switchScreen(); $area.text("Error: " + req.status + " " + req.statusText); } }); }; - var submitBinaryPage = function (pageName, oldRevision, givenPageName, summary, path) { - var doc = document.implementation.createDocument( - "http://cielonegro.org/schema/Rakka/Page/1.0", "page", null); - + var submitBinaryPage = function (pageName, oldRevision, givenPageName, isLocked, lang, otherLangs, summary, data) { + var NS = "http://cielonegro.org/schema/Rakka/Page/1.0"; + var doc = document.implementation.createDocument(NS, "page", null); var page = doc.documentElement; if (oldRevision != null) { // ページ書換時 - var updateInfo = doc.createElement("updateInfo"); + var updateInfo = doc.createElementNS(NS, "updateInfo"); updateInfo.setAttribute("oldRevision", oldRevision); if (pageName != givenPageName) { - var move = doc.createElement("move"); + var move = doc.createElementNS(NS, "move"); move.setAttribute("from", pageName); updateInfo.appendChild(move); } @@ -444,19 +658,31 @@ page.appendChild(updateInfo); } + page.setAttribute("isLocked", isLocked ? "yes" : "no"); page.setAttribute("type", ""); + if (lang != null && lang != "") { + page.setAttribute("lang", lang); + } + if (summary != null) { - var s = doc.createElement("summary"); + var s = doc.createElementNS(NS, "summary"); s.appendChild( doc.createTextNode(summary)); page.appendChild(s); } - var bin = Rakka.loadLocalBinaryFile(path); - var b64 = Rakka.encodeBase64(bin); + var oLang = doc.createElementNS(NS, "otherLang"); + for (var tag in otherLangs) { + var link = doc.createElementNS(NS, "link"); + link.setAttribute("lang", tag); + link.setAttribute("page", otherLangs[tag]); + oLang.appendChild(link); + } + page.appendChild(oLang); - var binaryData = doc.createElement("binaryData"); + var b64 = Rakka.encodeBase64(data); + var binaryData = doc.createElementNS(NS, "binaryData"); binaryData.appendChild( doc.createTextNode(b64)); @@ -479,26 +705,25 @@ }, error : function (req) { Rakka.hideWaitingMessage(); - + var $area = Rakka.switchScreen(); $area.text("Error: " + req.status + " " + req.statusText); } }); }; - var submitRedirection = function (pageName, oldRevision, givenPageName, destination) { - var doc = document.implementation.createDocument( - "http://cielonegro.org/schema/Rakka/Page/1.0", "page", null); - + var submitRedirection = function (pageName, oldRevision, givenPageName, isLocked, destination) { + var NS = "http://cielonegro.org/schema/Rakka/Page/1.0"; + var doc = document.implementation.createDocument(NS, "page", null); var page = doc.documentElement; if (oldRevision != null) { // ページ書換時 - var updateInfo = doc.createElement("updateInfo"); + var updateInfo = doc.createElementNS(NS, "updateInfo"); updateInfo.setAttribute("oldRevision", oldRevision); if (pageName != givenPageName) { - var move = doc.createElement("move"); + var move = doc.createElementNS(NS, "move"); move.setAttribute("from", pageName); updateInfo.appendChild(move); } @@ -506,6 +731,7 @@ page.appendChild(updateInfo); } + page.setAttribute("isLocked", isLocked ? "yes" : "no"); page.setAttribute("redirect", destination); Rakka.displayWaitingMessage("Submitting... please wait."); @@ -525,7 +751,7 @@ }, error : function (req) { Rakka.hideWaitingMessage(); - + var $area = Rakka.switchScreen(); $area.text("Error: " + req.status + " " + req.statusText); } @@ -545,7 +771,7 @@ }, error : function (req) { Rakka.hideWaitingMessage(); - + var $area = Rakka.switchScreen(); $area.text("Error: " + req.status + " " + req.statusText); }