diff --git a/extensions/json.anubis b/extensions/json.anubis new file mode 100644 index 0000000..eff455b --- /dev/null +++ b/extensions/json.anubis @@ -0,0 +1,59 @@ +/* + * Created by PyramIDE. + * User: フランスのトトロ + * Date: 12/12/2015 + * Time: 21:48 + * © Calexium + */ + +read tools/basis.anubis + +public define String + lib_error_to_string + ( + LibraryError err + )= + if err is + { + cant_load_library then "Can't load library.", + symbol_not_found then "Symbol not found.", + external_call_failed then "External call failed.", + unknown_error then "Unknown error." + }. + +public define String + to_JS_String + ( + Library json_lib, + String unescaped_string + )= + if unescaped_string = "" then + "''" + else + if extension_library_call(json_lib, "to_JS_String", serialize(unescaped_string), length(unescaped_string)+30) is + { + error(err) then + println("Can't call to_JS_String"); + println(" --> " + lib_error_to_string(err)); + "''", + ok(ba) then to_string(ba) + }. + +public define String + to_JSON_String + ( + Library json_lib, + String unescaped_string + )= + if unescaped_string = "" then + "\"\"" + else + if extension_library_call(json_lib, "to_JSON_String", serialize(unescaped_string), length(unescaped_string)+30) is + { + error(err) then + println("Can't call to_JSON_String"); + println(" --> " + lib_error_to_string(err)); + "\"\"", + ok(ba) then to_string(ba) + }. + diff --git a/web/CXM_json.anubis b/web/CXM_json.anubis index e9a8cec..f5f4d08 100644 --- a/web/CXM_json.anubis +++ b/web/CXM_json.anubis @@ -11,6 +11,8 @@ read tools/basis.anubis read tools/printable_tree.anubis transmit web/mime.anubis +transmit calexium_lib/extensions/json.anubis + public type JsonMember:... @@ -28,6 +30,18 @@ public type JsonMember: json_member(String name, JsonValue value). +public define Printable_tree + _format_json + ( + JsonValue json + ). + +public define Printable_tree + _format_json + ( + Library json_lib, + JsonValue json + ). //------------------------------- // helpers @@ -99,7 +113,7 @@ define List(Word8) ) = if original is { - [] then new_string, + [] then ['\"' . new_string], //add trailing double quotes [h . t] then if (h >=+ 32 & h +=< 33) | (h >=+ 35 & h +=< 91) | h >=+ 93 then // Allowed characters for JSON see RFC4627 + " ' " Why ' ??? _format_json_esc(t, [h . new_string]) @@ -115,7 +129,7 @@ public define String ( String original, ) = - implode(reverse(_format_json_esc(explode(original), [],))). + implode(reverse(_format_json_esc(explode(original), ['\"'],))). public define Printable_tree @@ -136,9 +150,18 @@ public define Printable_tree JsonMember member ) = if member is json_member(name, value) then - [ "\"", name, "\":" . format_json(value) ]. + [ "\"", name, "\":" . _format_json(value) ]. public define Printable_tree + format_json_member + ( + Library json_lib, + JsonMember member + ) = + if member is json_member(name, value) then + [ "\"", name, "\":" . _format_json(json_lib, value) ]. + +public define Printable_tree json_member_to_js ( JsonMember member @@ -149,13 +172,25 @@ public define Printable_tree define Printable_tree format_json_object ( - List(JsonMember) members + List(JsonMember) members ) = if members is { [] then [], [h . t] then [ format_json_member(h), (if t is [] then "" else ",") . format_json_object(t) ] }. + +define Printable_tree + format_json_object + ( + Library json_lib, + List(JsonMember) members + ) = + if members is + { + [] then [], + [h . t] then [ format_json_member(json_lib, h), (if t is [] then "" else ",") . format_json_object(json_lib, t) ] + }. define Printable_tree json_object_to_js @@ -171,70 +206,101 @@ define Printable_tree define Printable_tree format_json_array ( + Library json_lib, List(JsonValue) values ) = if values is { - [] then [], - [h . t] then [ format_json(h), (if t is [] then "" else ",") . format_json_array(t) ] + [] then [], + [h . t] then [ _format_json(json_lib, h), (if t is [] then "" else ",") . format_json_array(json_lib, t) ] }. define Printable_tree - json_array_to_js + format_json_array ( List(JsonValue) values ) = if values is { [] then [], - [h . t] then [ to_javascript(h), (if t is [] then "" else ",") . format_json_array(t) ] + [h . t] then [ _format_json(h), (if t is [] then "" else ",") . format_json_array(t) ] }. public define Printable_tree - format_json + _format_json ( + Library json_lib, JsonValue json ) = if json is { - json_object(members) then [ "{", format_json_object(members), "}" . [] ], - json_array(values) then [ "[", format_json_array(values), "]" . [] ], + json_object(members) then [ "{", format_json_object(json_lib, members), "}" . [] ], + json_array(values) then [ "[", format_json_array(json_lib, values), "]" . [] ], json_int(i) then int_pt(i, []), json_float(f, p) then str_pt(float_to_string(f, p), []), - json_string(s) then str_pt("\"" + format_json_esc(s) + "\"", []), + json_string(s) then if s ="" then str_pt("\"\"", []) else str_pt(to_JSON_String(json_lib, s), []), json_bool(b) then str_pt(if b then "true" else "false", []), json_null then str_pt("null", []) }. public define Printable_tree - to_javascript + _format_json ( JsonValue json ) = if json is { - json_object(members) then [ "{", json_object_to_js(members), "}" . [] ], - json_array(values) then [ "[", json_array_to_js(values), "]" . [] ], + json_object(members) then [ "{", format_json_object(members), "}" . [] ], + json_array(values) then [ "[", format_json_array(values), "]" . [] ], json_int(i) then int_pt(i, []), json_float(f, p) then str_pt(float_to_string(f, p), []), - json_string(s) then str_pt("\"" + format_json_esc(s) + "\"", []), + json_string(s) then str_pt(format_json_esc(s), []), json_bool(b) then str_pt(if b then "true" else "false", []), json_null then str_pt("null", []) }. - -public define String + +public define Printable_tree format_json ( - JsonValue json + JsonValue json ) = - to_String(format_json(json)). + //try to use adl version of json escape string + if load_library("json") is + { + error(err) then + println("load lib error:"); + println("--> can't load extension lib. Hence use anubis version"); + _format_json(json) + ok(json_lib) then + with start = unow, + result = _format_json(json_lib, json), + println(show_duration_string("format_json with extension ",start)); + result + }. + +public define String + to_JSON_String + ( + String str + ) = + //try to use adl version of json escape string + if load_library("json") is + { + error(err) then + println("load lib error:"); + println("--> can't load extension lib. Hence use anubis version"); + format_json_esc(str) + ok(json_lib) then + to_JSON_String(json_lib, str) + }. public define String - to_javascript + format_json ( - JsonValue json + JsonValue json ) = - to_String(to_javascript(json)). + to_String(format_json(json)). + public define WriteFileResult write_to_file diff --git a/web/CXM_making_a_web_site.anubis b/web/CXM_making_a_web_site.anubis index 7597b3c..485b918 100644 --- a/web/CXM_making_a_web_site.anubis +++ b/web/CXM_making_a_web_site.anubis @@ -57,7 +57,7 @@ read CXM_common.anubis read CXM_multihost_http_server.anubis read web/mime.anubis read CXM_cookies.anubis - +read CXM_json.anubis * (1) Structure of a web site. @@ -1675,6 +1675,8 @@ public type HTTP_Answer: custom_tree (HTTP_Status /*http_status*/, MIME /*mime_type*/, Printable_tree /*content*/), + json (HTTP_Status, /*http_status*/ + JsonValue), /*json value*/ http_raw (Printable_tree), html_content (HTTP_Status /*http_status*/, HTML_Off_Form), @@ -4915,7 +4917,19 @@ public define Printable_tree crlf . content ], - + json(HTTP_Status status, JsonValue json_content) then + with start = unow, + with content = (Printable_tree)format_json(json_content), + println(show_duration_string("HTTP json format json object ", start)); + if format(status) is (status_string, status_headers) then + [ "HTTP/1.1 " + status_string, crlf, + format_headers(standard_headers), + format_headers(standard_headers_for(to_String(mime_json), length(content), success(charset))), + format_headers(status_headers), + format_headers(additional_headers), + crlf . + content + ], http_raw(Printable_tree content) then content, html_content(HTTP_Status status, HTML_Off_Form content_HTML) then diff --git a/web/jQuery/CXM_jquery_animate.anubis b/web/jQuery/CXM_jquery_animate.anubis index 96766e3..e5e101b 100644 --- a/web/jQuery/CXM_jquery_animate.anubis +++ b/web/jQuery/CXM_jquery_animate.anubis @@ -381,7 +381,7 @@ public define List(HTML_Head_Tag) js_anim_function_name, [ format_jquery_selector(jq_selector), - to_javascript( + format_json( json_array( generate_js( format_animations([ ], anims), diff --git a/web/jQuery/CXM_jquery_button.anubis b/web/jQuery/CXM_jquery_button.anubis index c31afd5..437eea1 100644 --- a/web/jQuery/CXM_jquery_button.anubis +++ b/web/jQuery/CXM_jquery_button.anubis @@ -11,6 +11,7 @@ transmit calexium_lib/web/CXM_jquery.anubis transmit calexium_lib/web/jQuery/CXM_jquery_icons.anubis transmit calexium_lib/web/widgets/button.anubis transmit calexium_lib/web/js_tools.anubis +transmit calexium_lib/web/CXM_json.anubis transmit tools/basis.anubis transmit system/string.anubis transmit tools/random.anubis @@ -272,15 +273,15 @@ public define HTML_Partial_Content )= with uid = generate_random_string(10), - js_confirm_dialog_data_obj = "CalexiumToolBox.data.confirm_dialog[" + to_js_string(uid) + "]", + js_confirm_dialog_data_obj = "CalexiumToolBox.data.confirm_dialog['" + uid + "']", js_data = js_confirm_dialog_data_obj + " = { - title: " + to_js_string(dlg_title) + ", - text: " + to_js_string(dlg_text) + ", - ok : " + to_js_string(dlg_ok) + ", - cancel: " + to_js_string(dlg_cancel) + "};", + title: " + to_JS_String(dlg_title) + ", + text: " + to_JS_String(dlg_text) + ", + ok : " + to_JS_String(dlg_ok) + ", + cancel: " + to_JS_String(dlg_cancel) + "};", button_name = uid, - actioner = jQuery_actioner(same, jqscript, "CalexiumToolBox.make_confirm_dialog(this, " /*+ to_js_string("/?a=" + url + format_extra_operands(extra_ops))+*/ + to_js_string(jquery_button_get_onclick_action(actioner)) + ");"), + actioner = jQuery_actioner(same, jqscript, "CalexiumToolBox.make_confirm_dialog(this, " /*+ to_js_string("/?a=" + url + format_extra_operands(extra_ops))+*/ + to_JS_String(jquery_button_get_onclick_action(actioner)) + ");"), partial_content([js(js_file("js/cxm/cxm.js")), js_inline(jquery_ready(js_data))],sequence([ partial(jquery_button(jQuery_button(button, uid, button_name, button_label, actioner, jq_icon_none, jq_icon_none))) @@ -301,15 +302,15 @@ public define HTML_Partial_Content since button is jquery_img_button(img_url, button_label, button_name, actioner, orientation), with uid = generate_random_string(10), - js_confirm_dialog_data_obj = "CalexiumToolBox.data.confirm_dialog[" + to_js_string(uid) + "]", + js_confirm_dialog_data_obj = "CalexiumToolBox.data.confirm_dialog['" + uid + "']", js_data = js_confirm_dialog_data_obj + " = { - title: " + to_js_string(dlg_title) + ", - text: " + to_js_string(dlg_text) + ", - ok : " + to_js_string(dlg_ok) + ", - cancel: " + to_js_string(dlg_cancel) + "};", + title: " + to_JS_String(dlg_title) + ", + text: " + to_JS_String(dlg_text) + ", + ok : " + to_JS_String(dlg_ok) + ", + cancel: " + to_JS_String(dlg_cancel) + "};", button_name = uid, - actioner = jQuery_actioner(same, jqscript, "CalexiumToolBox.make_confirm_dialog(this, " + to_js_string(jquery_button_get_onclick_action(actioner)) +");"), + actioner = jQuery_actioner(same, jqscript, "CalexiumToolBox.make_confirm_dialog(this, " + to_JS_String(jquery_button_get_onclick_action(actioner)) +");"), partial_content([js(js_file("js/cxm/cxm.js")), js_inline(jquery_ready(js_data))],sequence([ partial(jquery_button(jquery_img_button(img_url, button_label, button_name, actioner, orientation))) diff --git a/web/js_tools.anubis b/web/js_tools.anubis index c0e1446..54b7cfd 100644 --- a/web/js_tools.anubis +++ b/web/js_tools.anubis @@ -7,9 +7,11 @@ */ read tools/basis.anubis +read calexium_lib/web/CXM_json.anubis +transmit calexium_lib/extensions/json.anubis define List(Word8) - make_js_string + make_JS_String ( List(Word8) current, List(Word8) so_far @@ -19,7 +21,7 @@ define List(Word8) { [ ] then reverse(so_far), [h . t] then - make_js_string(t, + make_JS_String(t, if h = '\'' then [ h, '\\' . so_far] //single quote else if h = '\"' then [ h, '\\' . so_far] else if h = '\r' then ['r', '\\' . so_far] //CR @@ -35,20 +37,28 @@ define List(Word8) * Convert a string into certified javascript string (I hope) */ public define String - make_js_string + make_JS_String ( String str ) = - implode(make_js_string(explode(str), [])). + implode(make_JS_String(explode(str), [])). + public define String - to_js_string + to_JS_String ( String str ) = - "'" + make_js_string(str) + "'". + //try to use adl version of json escape string + if load_library("json") is + { + error(err) then + "'" + make_JS_String(str) + "'" + ok(json_lib) then + to_JS_String(json_lib, str) + }. public define String format_js_function_call diff --git a/web/widgets/button.anubis b/web/widgets/button.anubis index 2ba007a..9fdf3a0 100644 --- a/web/widgets/button.anubis +++ b/web/widgets/button.anubis @@ -8,6 +8,7 @@ read calexium_lib/web/CXM_making_a_web_site.anubis read calexium_lib/web/CXM_jquery.anubis +read calexium_lib/web/CXM_json.anubis read calexium_lib/web/js_tools.anubis transmit calexium_lib/web/widgets/icons_set.anubis read tools/basis.anubis @@ -88,11 +89,11 @@ define inline String String dlg_ok, String dlg_cancel ) = - "CalexiumToolBox.data.confirm_dialog[" + to_js_string(uid) + "] = " + - "{ title: " + to_js_string(dlg_title) + - ", text: " + to_js_string(dlg_text) + - ", ok : " + to_js_string(dlg_ok) + - ", cancel: " + to_js_string(dlg_cancel) + + "CalexiumToolBox.data.confirm_dialog['" +(uid) + "'] = " + + "{ title: " + to_JS_String(dlg_title) + + ", text: " + to_JS_String(dlg_text) + + ", ok : " + to_JS_String(dlg_ok) + + ", cancel: " + to_JS_String(dlg_cancel) + "};". define List(CoreAttrs) @@ -102,7 +103,7 @@ define List(CoreAttrs) String uid, JQuery_Actioner actioner ) = - core_attrs + [id(uid), style("cursor: pointer"), event(onclick, "CalexiumToolBox.make_confirm_dialog(this, "/* + to_js_string("/?a=" + url + format_extra_operands(extra_ops))+*/+ to_js_string(jquery_button_get_onclick_action(actioner)) +");")]. + core_attrs + [id(uid), style("cursor: pointer"), event(onclick, "CalexiumToolBox.make_confirm_dialog(this, "/* + to_js_string("/?a=" + url + format_extra_operands(extra_ops))+*/+ to_JS_String(jquery_button_get_onclick_action(actioner)) +");")]. public define HTML_Partial_Content img_button_confirm -- libgit2 0.21.4