3 var identityDecoder = function (src) {
7 var identityEncoder = function (src) {
11 var mapDecoder = function (src) {
13 var lines = src.split(/\n/);
15 $.each(lines, function () {
16 var m = this.match(/^(\S+)\s+(\S+)$/);
24 var mapEncoder = function (map) {
27 $.each(map, function (key) {
28 lines.push(key + " " + this);
31 return lines.join("\n");
34 var boolDecoder = function (src) {
38 var boolEncoder = function (bool) {
39 return bool ? "*" : "";
43 siteName : identityDecoder,
44 baseURI : identityDecoder,
45 defaultPage: identityDecoder,
46 styleSheet : identityDecoder,
47 languages : mapDecoder,
48 globalLock : boolDecoder
52 siteName : identityEncoder,
53 baseURI : identityEncoder,
54 defaultPage: identityEncoder,
55 styleSheet : identityEncoder,
56 languages : mapEncoder,
57 globalLock : boolEncoder
60 var cachedConf = null;
62 var isValidBaseURI = function (str) {
63 parseUri.options.strictMode = true;
64 var uri = parseUri(str);
66 return (uri.protocol != "" &&
67 uri.authority != "" &&
69 uri.path.match(/\/$/) &&
74 // FIXME: Don't let user to manipulate directly this structure.
75 // FIXME: Values may include spaces.
76 var isValidMap = function (src) {
77 return src.match(/^(?:\S+\s+\S+(?:\n\S+\s+\S+)*\n?)?$/) != null;
80 Rakka.getUserList = function () {
85 url: Rakka.baseURI + "users",
87 beforeSend: function (req) {
88 Rakka.setAuthorization(req);
90 success: function (xml) {
91 $(xml).find("user").each(function () {
92 users.push(this.getAttribute("id"));
95 error: function (req) {
96 throw new Error(req.status + " " + req.statusText);
103 Rakka.getSystemConfig = function () {
104 if (cachedConf != null) {
113 url : Rakka.baseURI + "systemConfig",
115 success: function (xml) {
116 $(xml).find("value").each(function () {
117 var path = this.getAttribute("path");
118 var decoder = decoder_of[path];
120 if (decoder == null) {
121 throw new Error("unknown config path: " + path);
124 conf[path] = decoder($(this).text());
128 error : function (req) {
129 throw new Error(req.status + " " + req.statusText);
136 var appendConfigPanel = function ($area) {
137 var conf = Rakka.getSystemConfig();
138 $area.append($.H1({}, "Configuration"));
141 = $.INPUT({type: "text", value: conf.siteName});
144 = $.INPUT({type: "text", value: conf.baseURI});
147 = $.INPUT({type: "text", value: conf.defaultPage});
150 = $.INPUT({type: "text", value: conf.styleSheet});
153 = $.TEXTAREA({value: encoder_of.languages(conf.languages)});
156 = $.INPUT({type: "checkbox", checked: conf.globalLock});
159 = $.INPUT({type: "button", value: "Save changes", disabled: "disabled"});
161 $(btnSave).click(function () {
162 var NS = "http://cielonegro.org/schema/Rakka/Config/1.0";
163 var doc = document.implementation.createDocument(NS, "systemConfig", null);
164 var sc = doc.documentElement;
166 var mkValue = function (path, value) {
167 var elem = doc.createElementNS(NS, "value");
168 elem.setAttribute("path", path);
169 elem.appendChild(doc.createTextNode(value));
173 sc.appendChild(mkValue("siteName" , fldSiteName.value));
174 sc.appendChild(mkValue("baseURI" , fldBaseURI.value));
175 sc.appendChild(mkValue("defaultPage", fldDefaultPage.value));
176 sc.appendChild(mkValue("styleSheet" , fldStyleSheet.value));
177 sc.appendChild(mkValue("languages" , fldLanguages.value));
178 sc.appendChild(mkValue("globalLock" , encoder_of["globalLock"](chkGlobalLock.checked)));
180 Rakka.displayWaitingMessage("Submitting... please wait.");
182 var url = Rakka.baseURI + "systemConfig";
183 $.ajax({ type : "PUT",
185 contentType: "text/xml",
188 beforeSend : function (req) {
189 Rakka.setAuthorization(req);
191 success : function () {
193 Rakka.hideWaitingMessage();
194 Rakka.restoreScreen();
196 error : function (req) {
197 Rakka.hideWaitingMessage();
199 var $area = Rakka.switchScreen();
200 $area.text("Error: " + req.status + " " + req.statusText);
206 = $.INPUT({type: "button", value: "Revert changes", disabled: "disabled"});
208 $(btnRevert).click(function () {
209 if (window.confirm("Do you really want to discard changes?")) {
210 // FIXME: implement this
215 = $.TABLE({className: "pageEditor"},
218 $.TH({}, "Site name"),
219 $.TD({}, fldSiteName)),
221 $.TH({}, "Base URI"),
222 $.TD({}, fldBaseURI)),
224 $.TH({}, "Default page"),
225 $.TD({}, fldDefaultPage)),
227 $.TH({}, "Style sheet"),
228 $.TD({}, fldStyleSheet)),
230 $.TH({}, "Languages"),
231 $.TD({}, fldLanguages)),
233 $.TH({}, "Global lock"),
237 "Disallow guest users to edit pages."))),
240 $.TD({}, btnSave, btnRevert))));
242 var validate = function () {
243 var isValid = (function () {
244 if (!isValidBaseURI(fldBaseURI.value)) {
248 if (fldDefaultPage.value.match(Rakka.rePageName) == null) {
252 if (fldStyleSheet.value.match(Rakka.rePageName) == null) {
256 if (!isValidMap(fldLanguages.value)) {
263 $(btnSave).attr({disabled: (isValid ? "" : "disabled")});
267 var makeDirty = function () {
269 $(btnRevert).attr({disabled: ""});
283 $area.append(configPanel);
286 var appendUsersPanel = function ($area) {
287 $area.append($.H2({}, "Users"));
288 $area.append($.H3({}, "Existing Users"));
290 var tbody = $.TBODY();
293 = $.TABLE({className: "pageEditor"},
297 $.TH({}, "Change Password"),
298 $.TH({}, "Delete User"))),
301 var updateUserList = function () {
302 var users = Rakka.getUserList();
306 for (var i = 0; i < users.length; i++) {
307 var pass1 = $.INPUT({type: "password"});
308 var pass2 = $.INPUT({type: "password"});
309 var change = $.INPUT({type: "button", value: "Change"});
311 var chpass = $.TABLE({className: "pageEditor"},
314 $.TD({rowSpan: 2}, change)),
318 var delUser = $.INPUT({type: "button", value: "Delete"});
320 var validatePassword = function () {
321 var isValid = (function () {
322 if (pass1.value == "") {
326 if (pass1.value != pass2.value) {
332 $(change).attr({disabled: (isValid ? "" : "disabled")});
337 .change(validatePassword)
338 .keyup(validatePassword);
340 $.each(users, function () {
347 tbody.appendChild(tr);
353 $area.append(usersPanel);
355 $area.append($.H3({}, "Add new user"));
357 var userID = $.INPUT({type: "text"});
358 var pass1 = $.INPUT({type: "password"});
359 var pass2 = $.INPUT({type: "password"});
360 var addUser = $.INPUT({type: "button", value: "Add"});
361 var addUserPanel = $.TABLE({className: "pageEditor"},
366 $.TH({}, "Password"),
369 $.TH({}, "Password (retype)"),
375 $area.append(addUserPanel);
378 Rakka.showConfigPanel = function () {
379 var $area = Rakka.switchScreen();
381 appendConfigPanel($area);
382 appendUsersPanel($area);
385 $(document).ready(function () {
386 $("input.configButton")
388 Rakka.showConfigPanel();