# HG changeset patch # User jbe/bsw # Date 1265996422 -3600 # Node ID d76a8857ba629e716ee61194af3e4ed807214542 # Parent e017c47d43b5bd576859b50bfd202add708f94c8 Added ui.partial and other functions, which allow partial content replacement using XMLHttpRequests; Image support for ui.link Also includes following changes: - Fix for rocketcgi library to accept POST data content-types, which contain additional charset information. - Support arrays passed as params to encode.url (only for keys ending with "[]") - Version information changed to "1.0.7" Documentation for added functions is not yet complete. diff -r e017c47d43b5 -r d76a8857ba62 doc/autodoc-header.htmlpart --- a/doc/autodoc-header.htmlpart Wed Feb 03 00:57:18 2010 +0100 +++ b/doc/autodoc-header.htmlpart Fri Feb 12 18:40:22 2010 +0100 @@ -55,10 +55,10 @@ color: #505050; } -
WebMCP is a completely new web development framework, and has not been extensively tested yet. The API might change at any time, but in future releases there will be a list of all changes, which break downward compatibility.
diff -r e017c47d43b5 -r d76a8857ba62 framework/cgi-bin/webmcp.lua --- a/framework/cgi-bin/webmcp.lua Wed Feb 03 00:57:18 2010 +0100 +++ b/framework/cgi-bin/webmcp.lua Fri Feb 12 18:40:22 2010 +0100 @@ -1,6 +1,6 @@ #!/usr/bin/env lua -_WEBMCP_VERSION = "1.0.6" +_WEBMCP_VERSION = "1.0.7" -- include "../lib/" in search path for libraries do @@ -388,7 +388,7 @@ if not success then local errobj = error_info.errobj local stacktrace = error_info.stacktrace - if not request.get_status() then + if not request.get_status() and not request.get_json_request_slots() then request.set_status("500 Internal Server Error") end slot.set_layout('system_error') @@ -417,6 +417,10 @@ if slot_dump ~= "" then redirect_params.tempstore = tempstore.save(slot_dump) end + local json_request_slots = request.get_json_request_slots() + if json_request_slots then + redirect_params["_webmcp_json_slots[]"] = json_request_slots + end cgi.redirect( encode.url{ base = request.get_absolute_baseurl(), diff -r e017c47d43b5 -r d76a8857ba62 framework/env/encode/url.lua --- a/framework/env/encode/url.lua Wed Feb 03 00:57:18 2010 +0100 +++ b/framework/env/encode/url.lua Fri Feb 12 18:40:22 2010 +0100 @@ -81,7 +81,14 @@ add("_webmcp_id=", encode.url_part(id), "&") end for key, value in pairs(params) do - add(encode.url_part(key), "=", encode.url_part(value), "&") + -- TODO: better way to detect arrays? + if string.match(key, "%[%]$") then + for idx, entry in ipairs(value) do + add(encode.url_part(key), "=", encode.url_part(entry), "&") + end + else + add(encode.url_part(key), "=", encode.url_part(value), "&") + end end result[#result] = nil -- remove last '&' or '?' end diff -r e017c47d43b5 -r d76a8857ba62 framework/env/ui/__init.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/framework/env/ui/__init.lua Fri Feb 12 18:40:22 2010 +0100 @@ -0,0 +1,2 @@ +ui._partial_loading_enabled = false +ui._partial_state = nil diff -r e017c47d43b5 -r d76a8857ba62 framework/env/ui/_partial_load_js.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/framework/env/ui/_partial_load_js.lua Fri Feb 12 18:40:22 2010 +0100 @@ -0,0 +1,93 @@ +--[[-- +ui._partial_load_js{ +} + +TODO: documentation + +NOTE: may return nil + +--]]-- + +function ui._partial_load_js(args, mode) + local args = args or {} + local module + local view + local id + local params = {} + local target + if args.view and args.target then + module = args.module + view = args.view + id = args.id + target = args.target + elseif not args.view and not args.target then + if not ui._partial_state then + return nil + end + module = ui._partial_state.module + view = ui._partial_state.view + id = ui._partial_state.id + target = ui._partial_state.target + else + error("Unexpected arguments passed to ui._partial_load_js{...}") + end + + if ui._partial_state then + if ui._partial_state.params then + for key, value in pairs(ui._partial_state.params) do + params[key] = value + end + end + for param_name, dummy in pairs(ui._partial_state.param_name_hash) do + params[param_name] = cgi.params[param_name] + end + end + if args.params then + for key, value in pairs(args.params) do + params[key] = value + end + end + local encoded_url = encode.json( + encode.url{ + module = module, + view = view, + id = id, + params = params + } + ) + + if mode == "form_normal" then + -- NOTE: action in "action_mode" refers to WebMCP actions, while action + -- in "this.action" refers to the action attribute of HTML forms + slot.put('this.action = ', encoded_url, '; ') + end + + return slot.use_temporary(function() + slot.put( + 'partialMultiLoad({', + -- mapping: + '"trace": "trace", "system_error": "system_error", ', + encode.json(target), ': "default" }, ', + -- tempLoadingContents: + '{}, ', + -- failureContents: + '"error", ', + -- url: + (mode == "form_normal" or mode == "form_action") and ( + 'this' + ) or ( + encoded_url + ), ', ', + -- urlParams: + '"_webmcp_json_slots[]=default&_webmcp_json_slots[]=trace&_webmcp_json_slots[]=system_error", ', + -- postParams: + '{}, ', + -- successHandler: + 'function() {}, ', + -- failureHandler: + 'function() {} ', + '); ', + 'return false;' + ) + end) +end diff -r e017c47d43b5 -r d76a8857ba62 framework/env/ui/add_partial_param_names.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/framework/env/ui/add_partial_param_names.lua Fri Feb 12 18:40:22 2010 +0100 @@ -0,0 +1,16 @@ +--[[-- +ui.add_partial_param_names( + name_list +) + +TODO: documentation + +--]]-- + +function ui.add_partial_param_names(name_list) + if ui._partial_state then + for idx, param_name in ipairs(name_list) do + ui._partial_state.param_name_hash[param_name] = true + end + end +end diff -r e017c47d43b5 -r d76a8857ba62 framework/env/ui/enable_partial_loading.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/framework/env/ui/enable_partial_loading.lua Fri Feb 12 18:40:22 2010 +0100 @@ -0,0 +1,11 @@ +--[[-- +ui.enable_partial_loading() + +TODO: documentation + +--]]-- + +function ui.enable_partial_loading() + ui._partial_loading_enabled = true + request.force_absolute_baseurl() +end diff -r e017c47d43b5 -r d76a8857ba62 framework/env/ui/form.lua --- a/framework/env/ui/form.lua Wed Feb 03 00:57:18 2010 +0100 +++ b/framework/env/ui/form.lua Fri Feb 12 18:40:22 2010 +0100 @@ -27,6 +27,35 @@ --]]-- +local function prepare_routing_params(params, routing, default_module) + local routing_default_given = false + if routing then + for status, settings in pairs(routing) do + if status == "default" then + routing_default_given = true + end + local module = settings.module or default_module or request.get_module() + assert(settings.mode, "No mode specified in routing entry.") + assert(settings.view, "No view specified in routing entry.") + params["_webmcp_routing." .. status .. ".mode"] = settings.mode + params["_webmcp_routing." .. status .. ".module"] = module + params["_webmcp_routing." .. status .. ".view"] = settings.view + params["_webmcp_routing." .. status .. ".id"] = settings.id + if settings.params then + for key, value in pairs(settings.params) do + params["_webmcp_routing." .. status .. ".params." .. key] = value + end + end + end + end + if not routing_default_given then + params["_webmcp_routing.default.mode"] = "forward" + params["_webmcp_routing.default.module"] = request.get_module() + params["_webmcp_routing.default.view"] = request.get_view() + end + return params +end + function ui.form(args) local args = args or {} local slot_state = slot.get_state_table() @@ -39,31 +68,7 @@ else slot_state.form_readonly = false local params = table.new(args.params) - local routing_default_given = false - if args.routing then - for status, settings in pairs(args.routing) do - if status == "default" then - routing_default_given = true - end - local module = settings.module or args.module or request.get_module() - assert(settings.mode, "No mode specified in routing entry.") - assert(settings.view, "No view specified in routing entry.") - params["_webmcp_routing." .. status .. ".mode"] = settings.mode - params["_webmcp_routing." .. status .. ".module"] = module - params["_webmcp_routing." .. status .. ".view"] = settings.view - params["_webmcp_routing." .. status .. ".id"] = settings.id - if settings.params then - for key, value in pairs(settings.params) do - params["_webmcp_routing." .. status .. ".params." .. key] = value - end - end - end - end - if not routing_default_given then - params["_webmcp_routing.default.mode"] = "forward" - params["_webmcp_routing.default.module"] = request.get_module() - params["_webmcp_routing.default.view"] = request.get_view() - end + prepare_routing_params(params, args.routing, args.module) params._webmcp_csrf_secret = request.get_csrf_secret() local attr = table.new(args.attr) attr.action = encode.url{ @@ -73,6 +78,45 @@ action = args.action, } attr.method = args.method and string.upper(args.method) or "POST" + if ui.is_partial_loading_enabled() and args.partial then + attr.onsubmit = slot.use_temporary(function() + local partial_mode = "form_normal" + if args.action then + partial_mode = "form_action" + slot.put( + 'var element; ', + 'var formElements = []; ', + 'for (var i=0; i