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+)$/);
26 var mapEncoder = function (map) {
29 $.each(map, function (key) {
30 lines.push(key + " " + this);
33 return lines.join("\n");
36 var boolDecoder = function (src) {
40 var boolEncoder = function (bool) {
41 return bool ? "*" : "";
45 siteName : identityDecoder,
46 baseURI : identityDecoder,
47 defaultPage: identityDecoder,
48 styleSheet : identityDecoder,
49 languages : mapDecoder,
50 globalLock : boolDecoder
54 siteName : identityEncoder,
55 baseURI : identityEncoder,
56 defaultPage: identityEncoder,
57 styleSheet : identityEncoder,
58 languages : mapEncoder,
59 globalLock : boolEncoder
62 var cachedConf = null;
64 var isValidBaseURI = function (str) {
65 parseUri.options.strictMode = true;
66 var uri = parseUri(str);
68 return (uri.protocol != "" &&
69 uri.authority != "" &&
71 uri.path.match(/\/$/) &&
76 // FIXME: Don't let user to manipulate directly this structure.
77 // FIXME: Values may include spaces.
78 var isValidMap = function (src) {
79 return src.match(/^(?:\S+\s+\S+(?:\n\S+\s+\S+)*\n?)?$/) != null;
82 Rakka.getUserList = function () {
87 url: Rakka.baseURI + "users",
89 beforeSend: function (req) {
90 Rakka.setAuthorization(req);
92 success: function (xml) {
93 $(xml).find("user").each(function () {
94 users.push(this.getAttribute("id"));
97 error: function (req) {
98 throw new Error(req.status + " " + req.statusText);
105 Rakka.getSystemConfig = function () {
106 if (cachedConf != null) {
115 url : Rakka.baseURI + "systemConfig",
117 success: function (xml) {
118 $(xml).find("value").each(function () {
119 var path = this.getAttribute("path");
120 var decoder = decoder_of[path];
122 if (decoder == null) {
123 throw new Error("unknown config path: " + path);
126 conf[path] = decoder($(this).text());
130 error : function (req) {
131 throw new Error(req.status + " " + req.statusText);
138 var appendConfigPanel = function ($area) {
139 $area.append($.H1({}, "Configuration"));
142 = $.INPUT({type: "text"});
145 = $.INPUT({type: "text"});
148 = $.INPUT({type: "text"});
151 = $.INPUT({type: "text"});
157 = $.INPUT({type: "checkbox"});
160 = $.INPUT({type: "button", value: "Save changes"});
163 = $.INPUT({type: "button", value: "Revert changes"});
165 var makeClean = function () {
166 $(btnSave).attr({disabled: "disabled"});
167 $(btnRevert).attr({disabled: "disabled"});
170 var updateConfig = function () {
171 var conf = Rakka.getSystemConfig();
173 fldSiteName.value = conf.siteName;
174 fldBaseURI.value = conf.baseURI;
175 fldDefaultPage.value = conf.defaultPage;
176 fldStyleSheet.value = conf.styleSheet;
177 fldLanguages.value = encoder_of.languages(conf.languages);
178 chkGlobalLock.checked = conf.globalLock;
184 var validate = function () {
185 var isValid = (function () {
186 if (!isValidBaseURI(fldBaseURI.value)) {
190 if (fldDefaultPage.value.match(Rakka.rePageName) == null) {
194 if (fldStyleSheet.value.match(Rakka.rePageName) == null) {
198 if (!isValidMap(fldLanguages.value)) {
205 $(btnSave).attr({disabled: (isValid ? "" : "disabled")});
208 var makeDirty = function () {
209 $(btnRevert).attr({disabled: ""});
213 $(btnSave).click(function () {
214 var NS = "http://cielonegro.org/schema/Rakka/Config/1.0";
215 var doc = document.implementation.createDocument(NS, "systemConfig", null);
216 var sc = doc.documentElement;
218 var mkValue = function (path, value) {
219 var elem = doc.createElementNS(NS, "value");
220 elem.setAttribute("path", path);
221 elem.appendChild(doc.createTextNode(value));
225 sc.appendChild(mkValue("siteName" , fldSiteName.value));
226 sc.appendChild(mkValue("baseURI" , fldBaseURI.value));
227 sc.appendChild(mkValue("defaultPage", fldDefaultPage.value));
228 sc.appendChild(mkValue("styleSheet" , fldStyleSheet.value));
229 sc.appendChild(mkValue("languages" , fldLanguages.value));
230 sc.appendChild(mkValue("globalLock" , encoder_of["globalLock"](chkGlobalLock.checked)));
232 Rakka.displayWaitingMessage("Submitting... please wait.");
234 var url = Rakka.baseURI + "systemConfig";
235 $.ajax({ type : "PUT",
237 contentType: "text/xml",
240 beforeSend : function (req) {
241 Rakka.setAuthorization(req);
243 success : function () {
245 Rakka.hideWaitingMessage();
248 error : function (req) {
249 Rakka.hideWaitingMessage();
251 // FIXME: better error handling
252 var $area = Rakka.switchScreen();
253 $area.text("Error: " + req.status + " " + req.statusText);
258 $(btnRevert).click(function () {
259 if (window.confirm("Do you really want to discard changes?")) {
265 = $.TABLE({className: "pageEditor"},
268 $.TH({}, "Site name"),
269 $.TD({}, fldSiteName)),
271 $.TH({}, "Base URI"),
272 $.TD({}, fldBaseURI)),
274 $.TH({}, "Default page"),
275 $.TD({}, fldDefaultPage)),
277 $.TH({}, "Style sheet"),
278 $.TD({}, fldStyleSheet)),
280 $.TH({}, "Languages"),
281 $.TD({}, fldLanguages)),
283 $.TH({}, "Global lock"),
287 "Disallow guest users to edit pages."))),
290 $.TD({}, btnSave, btnRevert))));
300 $area.append(configPanel);
303 var appendUsersPanel = function ($area) {
304 $area.append($.H2({}, "Users"));
305 $area.append($.H3({}, "Existing Users"));
307 var tbody = $.TBODY();
310 = $.TABLE({className: "pageEditor vertical"},
314 $.TH({}, "Change Password"),
315 $.TH({}, "Delete User"))),
318 var updateUserList = function () {
319 var users = Rakka.getUserList();
323 for (var i = 0; i < users.length; i++) {
324 var pass1 = $.INPUT({type: "password"});
325 var pass2 = $.INPUT({type: "password"});
326 var change = $.INPUT({type: "button", value: "Change"});
328 var chpass = $.TABLE({className: "pageEditor"},
331 $.TD({rowSpan: 2}, change)),
335 var delUser = $.INPUT({type: "button", value: "Delete"});
337 var validatePassword = function () {
338 var isValid = (function () {
339 if (pass1.value == "") {
343 if (pass1.value != pass2.value) {
349 $(change).attr({disabled: (isValid ? "" : "disabled")});
354 .change(validatePassword)
355 .keyup(validatePassword);
357 $.each(users, function () {
364 tbody.appendChild(tr);
370 $area.append(usersPanel);
372 $area.append($.H3({}, "Add new user"));
374 var userID = $.INPUT({type: "text"});
375 var pass1 = $.INPUT({type: "password"});
376 var pass2 = $.INPUT({type: "password"});
377 var addUser = $.INPUT({type: "button", value: "Add"});
378 var addUserPanel = $.TABLE({className: "pageEditor"},
383 $.TH({}, "Password"),
386 $.TH({}, "Password (retype)"),
392 $area.append(addUserPanel);
395 Rakka.showConfigPanel = function () {
396 var $area = Rakka.switchScreen();
398 appendConfigPanel($area);
399 appendUsersPanel($area);
402 $(document).ready(function () {
403 $("input.configButton")
405 Rakka.showConfigPanel();