Commit 102790d53d5c0d09fb3b2b1f7a4583eb3ab90995
1 parent
0fa08cdc
add some CoreAttrs according to HTML5 and Anubis specific tooltip
Showing
4 changed files
with
649 additions
and
427 deletions
Show diff stats
| 1 | +/* | |
| 2 | + * Created by 伝作 (Densaku). | |
| 3 | + * Types & Messages generator written by フランスのトトロ aka (David RENÉ) | |
| 4 | + * Date: 2018-12-07 | |
| 5 | + * Time: 00:57:44 | |
| 6 | + * | |
| 7 | + */ | |
| 8 | + | |
| 9 | +transmit system/muscle.anubis | |
| 10 | +transmit system/convert.anubis | |
| 11 | +transmit tools/basis.anubis | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | +public type Email_Address: | |
| 17 | + email_address( | |
| 18 | + String name, | |
| 19 | + String address | |
| 20 | + ) | |
| 21 | +. | |
| 22 | + | |
| 23 | + Email_Address message format | |
| 24 | + ============================ | |
| 25 | + | |
| 26 | + | |
| 27 | +public define Message | |
| 28 | + to_Message | |
| 29 | + ( | |
| 30 | + Email_Address _email_address | |
| 31 | + )= | |
| 32 | + with _email_address_message = message((Word32)0), // | |
| 33 | + forget(add_string(_email_address_message, "__TYPE__", "Email_Address")); | |
| 34 | + if _email_address is | |
| 35 | + { | |
| 36 | + //Alternative email_address | |
| 37 | + email_address(_name, _address) then | |
| 38 | + forget(add_string(_email_address_message, "__TYPE_ALT__", "email_address")); | |
| 39 | + // [type = String] email_address.name | |
| 40 | + forget(add_string(_email_address_message, "name", _name)); | |
| 41 | + // [type = String] email_address.address | |
| 42 | + forget(add_string(_email_address_message, "address", _address)), | |
| 43 | + | |
| 44 | + }; | |
| 45 | + _email_address_message | |
| 46 | +. | |
| 47 | + | |
| 48 | +public define Maybe(Email_Address) | |
| 49 | + from_Message | |
| 50 | + ( | |
| 51 | + Message _email_address_message | |
| 52 | + )= | |
| 53 | + if find_string(_email_address_message, "__TYPE__") is {failure then failure, success(__type__) then | |
| 54 | + if find_string(_email_address_message, "__TYPE_ALT__") is {failure then failure, success(__type_alt__) then | |
| 55 | + if __type__ = "Email_Address" then | |
| 56 | + //Alternative email_address | |
| 57 | + if __type_alt__ = "email_address" then //Alternative email_address | |
| 58 | + // [type = String] email_address.name | |
| 59 | + if find_string(_email_address_message, "name") is {failure then failure, success(_name_) then | |
| 60 | + // [type = String] email_address.address | |
| 61 | + if find_string(_email_address_message, "address") is {failure then failure, success(_address_) then | |
| 62 | + | |
| 63 | + success(email_address(_name_, _address_)) | |
| 64 | + }} | |
| 65 | + else | |
| 66 | + failure //No valid Alternative found ! | |
| 67 | + else | |
| 68 | + failure //Type not found in message ! | |
| 69 | + }} | |
| 70 | +. | |
| 71 | + | ... | ... |
| 1 | +/* | |
| 2 | + * Created by 伝作 (Densaku). | |
| 3 | + * Types & Messages generator written by フランスのトトロ aka (David RENÉ) | |
| 4 | + * Date: 2018-12-07 | |
| 5 | + * Time: 01:14:06 | |
| 6 | + * | |
| 7 | + */ | |
| 8 | + | |
| 9 | +transmit system/muscle.anubis | |
| 10 | +transmit system/convert.anubis | |
| 11 | +transmit tools/basis.anubis | |
| 12 | + | |
| 13 | +transmit calexium_lib/mail/types/generated/email_address.anubis | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | +public type Email_to_send: | |
| 18 | + data_to_send( | |
| 19 | + Email_Address from, //email sent from that sender | |
| 20 | + List(Email_Address) to, //email sent to that list of recipients | |
| 21 | + List(Email_Address) cc, //email sent as copy to that list of recipients | |
| 22 | + List(Email_Address) bcc, //email sent as blank carbon copy to that list of recipients | |
| 23 | + String subject, //subject of email. Supposed to be UTF8 | |
| 24 | + String content, //content of the email | |
| 25 | + List(String) files, //list of files | |
| 26 | + Bool send_copy, //send copy to sender by bcc (useful when the email is sent by an automat) | |
| 27 | + String reply_to //reply to !! | |
| 28 | + ) | |
| 29 | +. | |
| 30 | + | |
| 31 | + Email_to_send message format | |
| 32 | + ============================ | |
| 33 | + | |
| 34 | + | |
| 35 | +public define Message | |
| 36 | + to_Message | |
| 37 | + ( | |
| 38 | + Email_to_send _email_to_send | |
| 39 | + )= | |
| 40 | + with _email_to_send_message = message((Word32)0), // | |
| 41 | + forget(add_string(_email_to_send_message, "__TYPE__", "Email_to_send")); | |
| 42 | + if _email_to_send is | |
| 43 | + { | |
| 44 | + //Alternative data_to_send | |
| 45 | + data_to_send(_from, __to, __cc, __bcc, _subject, _content, __files, _send_copy, _reply_to) then | |
| 46 | + forget(add_string(_email_to_send_message, "__TYPE_ALT__", "data_to_send")); | |
| 47 | + // [type = Email_Address] data_to_send.from | |
| 48 | + forget(add_message(_email_to_send_message, "from", to_Message(_from))); | |
| 49 | + // [type = List(Email_Address)] data_to_send.to | |
| 50 | + map_forget((Email_Address _to) |-> add_message(_email_to_send_message, "to", to_Message(_to)), __to); | |
| 51 | + // [type = List(Email_Address)] data_to_send.cc | |
| 52 | + map_forget((Email_Address _cc) |-> add_message(_email_to_send_message, "cc", to_Message(_cc)), __cc); | |
| 53 | + // [type = List(Email_Address)] data_to_send.bcc | |
| 54 | + map_forget((Email_Address _bcc) |-> add_message(_email_to_send_message, "bcc", to_Message(_bcc)), __bcc); | |
| 55 | + // [type = String] data_to_send.subject | |
| 56 | + forget(add_string(_email_to_send_message, "subject", _subject)); | |
| 57 | + // [type = String] data_to_send.content | |
| 58 | + forget(add_string(_email_to_send_message, "content", _content)); | |
| 59 | + // [type = List(String)] data_to_send.files | |
| 60 | + map_forget((String _files) |-> add_string(_email_to_send_message, "files", _files), __files); | |
| 61 | + // [type = Bool] data_to_send.send_copy | |
| 62 | + forget(add_bool(_email_to_send_message, "send_copy", _send_copy)); | |
| 63 | + // [type = String] data_to_send.reply_to | |
| 64 | + forget(add_string(_email_to_send_message, "reply_to", _reply_to)), | |
| 65 | + | |
| 66 | + }; | |
| 67 | + _email_to_send_message | |
| 68 | +. | |
| 69 | + | |
| 70 | +public define Maybe(Email_to_send) | |
| 71 | + from_Message | |
| 72 | + ( | |
| 73 | + Message _email_to_send_message | |
| 74 | + )= | |
| 75 | + if find_string(_email_to_send_message, "__TYPE__") is {failure then failure, success(__type__) then | |
| 76 | + if find_string(_email_to_send_message, "__TYPE_ALT__") is {failure then failure, success(__type_alt__) then | |
| 77 | + if __type__ = "Email_to_send" then | |
| 78 | + //Alternative data_to_send | |
| 79 | + if __type_alt__ = "data_to_send" then //Alternative data_to_send | |
| 80 | + // [type = Email_Address] data_to_send.from | |
| 81 | + if find_message(_email_to_send_message, "from") is {failure then failure, success(_from__msg) then | |
| 82 | + if (Maybe(Email_Address))from_Message(_from__msg) is {failure then failure, success(_from_) then | |
| 83 | + // [type = List(Email_Address)] data_to_send.to | |
| 84 | + with mb__to_ = map_escape(( Message msg ) |-> (Maybe(Email_Address)) from_Message(msg), find_messages(_email_to_send_message, "to")), | |
| 85 | + if mb__to_ is {failure then failure, success(_to_) then | |
| 86 | + // [type = List(Email_Address)] data_to_send.cc | |
| 87 | + with mb__cc_ = map_escape(( Message msg ) |-> (Maybe(Email_Address)) from_Message(msg), find_messages(_email_to_send_message, "cc")), | |
| 88 | + if mb__cc_ is {failure then failure, success(_cc_) then | |
| 89 | + // [type = List(Email_Address)] data_to_send.bcc | |
| 90 | + with mb__bcc_ = map_escape(( Message msg ) |-> (Maybe(Email_Address)) from_Message(msg), find_messages(_email_to_send_message, "bcc")), | |
| 91 | + if mb__bcc_ is {failure then failure, success(_bcc_) then | |
| 92 | + // [type = String] data_to_send.subject | |
| 93 | + if find_string(_email_to_send_message, "subject") is {failure then failure, success(_subject_) then | |
| 94 | + // [type = String] data_to_send.content | |
| 95 | + if find_string(_email_to_send_message, "content") is {failure then failure, success(_content_) then | |
| 96 | + // [type = List(String)] data_to_send.files | |
| 97 | + with _files_ = find_string_list(_email_to_send_message, "files"), | |
| 98 | + // [type = Bool] data_to_send.send_copy | |
| 99 | + if find_bool(_email_to_send_message, "send_copy") is {failure then failure, success(_send_copy_) then | |
| 100 | + // [type = String] data_to_send.reply_to | |
| 101 | + if find_string(_email_to_send_message, "reply_to") is {failure then failure, success(_reply_to_) then | |
| 102 | + | |
| 103 | + success(data_to_send(_from_, _to_, _cc_, _bcc_, _subject_, _content_, _files_, _send_copy_, _reply_to_)) | |
| 104 | + }}}}}}}}} | |
| 105 | + else | |
| 106 | + failure //No valid Alternative found ! | |
| 107 | + else | |
| 108 | + failure //Type not found in message ! | |
| 109 | + }} | |
| 110 | +. | |
| 111 | + | ... | ... |
web/CXM_http_get.anubis
| 1 | - *Project* The Anubis Project | |
| 2 | - | |
| 3 | - *Title* Getting a document from the Web. | |
| 4 | - | |
| 5 | - *Copyright* Copyright (c) Alain Prouté 2001. | |
| 6 | - | |
| 7 | - | |
| 8 | - *Author* Alain Prouté | |
| 9 | - | |
| 10 | - | |
| 11 | - | |
| 12 | - *Overview* | |
| 13 | - This file defines the function 'http_get' which retrieves a document from the world | |
| 14 | - wide web (a similar function 'https_get' for secured documents is defined in | |
| 15 | - 'https_get.anubis'). The function simulates the behavior of a browser, at least just | |
| 16 | - what is needed to retrieve the document. It does not display the document, but returns | |
| 17 | - it (if found) in the form of a string. It also returns the response line from the | |
| 18 | - server, and the list af all HTTP headers. | |
| 19 | - | |
| 20 | - The function 'http_get' takes the following arguments: | |
| 21 | - | |
| 22 | - - the name of the server to which the request is to be sent, | |
| 23 | - - the name (including the path) of the document on this server, | |
| 24 | - - a list of headers to be added to mandatory standard headers, | |
| 25 | - - a list of 'arguments' in the form of pairs of strings '(name,value)' to be sent as | |
| 26 | - the body of the request. | |
| 27 | - | |
| 28 | - | |
| 29 | - The result returned by 'http_get' has the following type, which defines the problems | |
| 30 | - which may happen: | |
| 31 | - | |
| 32 | - | |
| 33 | -read tools/basis.anubis | |
| 34 | -read system/string.anubis | |
| 35 | -read web/CXM_common.anubis | |
| 36 | -read web/CXM_http_get_common.anubis | |
| 37 | - | |
| 38 | - | |
| 39 | -public type HTTP_GET_Result: | |
| 40 | - cannot_resolve_server_name(DNS_Result), | |
| 41 | - cannot_connect_to_server(NetworkConnectError), | |
| 42 | - transmission_problem, | |
| 43 | - request_refused_by_server, | |
| 44 | - ok(String response, // HTTP response line from the server | |
| 45 | - List(HTTP_header) headers, // HTTP headers received from the server | |
| 46 | - String document). // The HTML document itself | |
| 47 | - | |
| 48 | - | |
| 49 | -public define HTTP_GET_Result | |
| 50 | - http_get | |
| 51 | - ( //-------- example: ----------------------- | |
| 52 | - String server_name, // "www.machin.com" | |
| 53 | - String document_name, // "/truc/bidule.html" | |
| 54 | - List(HTTP_header) headers, // [http_header("Cookie","..."),...] | |
| 55 | - List(HTTP_argument) arguments // [http_argument("ga","bu"),...] | |
| 56 | - ). | |
| 57 | - | |
| 58 | - The same one without the 'headers' argument: | |
| 59 | - | |
| 60 | -public define HTTP_GET_Result | |
| 61 | - http_get | |
| 62 | - ( //-------- example: ----------------------- | |
| 63 | - String server_name, // "www.machin.com" | |
| 64 | - String document_name, // "/truc/bidule.html" | |
| 65 | - List(HTTP_argument) arguments // [http_argument("ga","bu"),...] | |
| 66 | - ) = http_get(server_name,document_name,[],arguments). | |
| 67 | - | |
| 68 | - | |
| 69 | - | |
| 70 | - This file also defines the command 'http_get' to be used directly from the system | |
| 71 | - prompt. To learn about the syntax, just type 'http_get' at the system prompt, or have | |
| 72 | - a look at the end of this file | |
| 73 | - | |
| 74 | - --- That's all for public definitions. ------------------------------------------------ | |
| 75 | - | |
| 76 | - | |
| 77 | - | |
| 78 | - We need two functions for sending and receiving bytes. | |
| 79 | - | |
| 80 | -define Maybe(One) | |
| 81 | - send | |
| 82 | - ( | |
| 83 | - RWStream conn, // where to send the text | |
| 84 | - String text, // the text to be sent | |
| 85 | - Word32 n // start sending at character number 'n' in 'text' | |
| 86 | - ) = | |
| 87 | - if nth(to_Int(n),text) is | |
| 88 | - { | |
| 89 | - failure then success(unique), | |
| 90 | - success(c) then | |
| 91 | - if conn <- c is | |
| 92 | - { | |
| 93 | - failure then failure, | |
| 94 | - success(_) then send(conn,text,n+1) | |
| 95 | - } | |
| 96 | - }. | |
| 97 | - | |
| 98 | -define Maybe(String) | |
| 99 | - receive_text_chunk | |
| 100 | - ( | |
| 101 | - RWStream conn, | |
| 102 | - List(Word8) so_far, | |
| 103 | - Word32 count | |
| 104 | - ) = | |
| 105 | - if count = 100 | |
| 106 | - then success(implode(reverse(so_far))) | |
| 107 | - else if *conn is // *conn waits for data to be readable from connection | |
| 108 | - { | |
| 109 | - failure then success(implode(reverse(so_far))), // means 'connection closed by peer' | |
| 110 | - success(c) then receive_text_chunk(conn,[c . so_far],count+1) | |
| 111 | - }. | |
| 112 | - | |
| 113 | - | |
| 114 | -define HTTP_GET_Result | |
| 115 | - receive | |
| 116 | - ( | |
| 117 | - RWStream conn, | |
| 118 | - String headers, | |
| 119 | - String text_so_far, | |
| 120 | - Bool double_crlf_seen | |
| 121 | - ) = | |
| 122 | - if receive_text_chunk(conn,[],0) is | |
| 123 | - { | |
| 124 | - failure then if separate_headers(headers) is | |
| 125 | - { | |
| 126 | - [ ] then ok("",[],text_so_far), | |
| 127 | - [h . t] then if h is http_header(a,b) then ok(a,t,text_so_far) | |
| 128 | - }, | |
| 129 | - | |
| 130 | - success(s) then | |
| 131 | - if s = "" | |
| 132 | - then if separate_headers(headers) is | |
| 133 | - { | |
| 134 | - [ ] then ok("",[],text_so_far), | |
| 135 | - [h . t] then if h is http_header(a,b) then ok(a,t,text_so_far) | |
| 136 | - } | |
| 137 | - else with new_s = text_so_far+s, | |
| 138 | - if double_crlf_seen | |
| 139 | - then receive(conn,headers,new_s,true) | |
| 140 | - else if has_double_crlf(new_s) is | |
| 141 | - { | |
| 142 | - failure then receive(conn,headers,new_s,false), | |
| 143 | - success(n) then | |
| 144 | - if sub_string(new_s,n+4,length(new_s)-n-4) is | |
| 145 | - { | |
| 146 | - failure then alert, | |
| 147 | - success(s1) then | |
| 148 | - if sub_string(new_s,0,n) is | |
| 149 | - { | |
| 150 | - failure then alert, | |
| 151 | - success(h) then receive(conn,h,s1,true) | |
| 152 | - } | |
| 153 | - } | |
| 154 | - } | |
| 155 | - }. | |
| 156 | - | |
| 157 | - | |
| 158 | - | |
| 159 | - The next function has a valid TCP/IP connection to the server, and tries to retrieve | |
| 160 | - the document. | |
| 161 | - | |
| 162 | - | |
| 163 | -define HTTP_GET_Result | |
| 164 | - http_get | |
| 165 | - ( | |
| 166 | - Bool print_all, | |
| 167 | - RWStream conn, | |
| 168 | - String server_name, | |
| 169 | - String document_name, | |
| 170 | - List(HTTP_header) headers, | |
| 171 | - List(HTTP_argument) arguments, | |
| 172 | - ) = | |
| 173 | - // | |
| 174 | - // Send the HTTP request, and receive the answer: | |
| 175 | - // | |
| 176 | - with body = format_http_args(arguments), | |
| 177 | - with request = (if arguments = [] then "GET " else "POST ") | |
| 178 | - + document_name + " HTTP/1.0" + crlf + | |
| 179 | - "Host: " + server_name + crlf + | |
| 180 | - "Accept-Charset: iso-8859-1,*,utf-8" + crlf + | |
| 181 | - (if arguments = [] then "" | |
| 182 | - else "Content-type: application/x-www-form-urlencoded" + crlf + | |
| 183 | - "Content-length: " + to_decimal(length(body))+ crlf) + | |
| 184 | - format_headers(headers) + | |
| 185 | - crlf + | |
| 186 | - body, | |
| 187 | - (if print_all then | |
| 188 | - ( | |
| 189 | - print("----- request ----\n"); | |
| 190 | - print(request); | |
| 191 | - print("\n") | |
| 192 | - ) else unique); | |
| 193 | - if send(conn,request,0) is | |
| 194 | - { | |
| 195 | - failure then transmission_problem, | |
| 196 | - success(_) then receive(conn,"","",false) | |
| 197 | - }. | |
| 198 | - | |
| 199 | - | |
| 200 | - The next function retrieves the document using the numerical (resolved) server address. | |
| 201 | - | |
| 202 | -define HTTP_GET_Result | |
| 203 | - http_get | |
| 204 | - ( | |
| 205 | - Bool print_all, | |
| 206 | - Word32 server_addr, | |
| 207 | - Word32 server_port, | |
| 208 | - String server_name, | |
| 209 | - String document_name, | |
| 210 | - List(HTTP_header) headers, | |
| 211 | - List(HTTP_argument) arguments, | |
| 212 | - ) = | |
| 213 | - // | |
| 214 | - // try to connect to the server before sending the request | |
| 215 | - // | |
| 216 | - if (Result(NetworkConnectError,RWStream))connect(server_addr,server_port) is | |
| 217 | - { | |
| 218 | - error(e) then cannot_connect_to_server(e), | |
| 219 | - ok(conn) then http_get(print_all,conn,server_name,document_name,headers,arguments) | |
| 220 | - }. | |
| 221 | - | |
| 222 | - | |
| 223 | -define HTTP_GET_Result | |
| 224 | - http_get | |
| 225 | - ( | |
| 226 | - Bool print_all, | |
| 227 | - String server_name, | |
| 228 | - String document_name, | |
| 229 | - List(HTTP_header) headers, | |
| 230 | - List(HTTP_argument) arguments, | |
| 231 | - ) = | |
| 232 | - if separate_name_port(server_name,80) is (name,port) then | |
| 233 | - // | |
| 234 | - // resolve server name and call 'http_get' with numeric server address: | |
| 235 | - // | |
| 236 | - with a = dns(name), | |
| 237 | - if a is ok(addr) | |
| 238 | - then http_get(print_all,addr,port,name,document_name,headers,arguments) | |
| 239 | - else cannot_resolve_server_name(a). | |
| 240 | - | |
| 241 | - | |
| 242 | - Now, here is our public tool: | |
| 243 | - | |
| 244 | -define HTTP_GET_Result | |
| 245 | - http_get | |
| 246 | - ( | |
| 247 | - String server_name, | |
| 248 | - String document_name, | |
| 249 | - List(HTTP_header) headers, | |
| 250 | - List(HTTP_argument) arguments, | |
| 251 | - ) = http_get(false,server_name,document_name,headers,arguments). | |
| 252 | - | |
| 253 | - | |
| 254 | - | |
| 255 | - Finally, we construct the executable module 'http_get': | |
| 256 | - | |
| 257 | -define One | |
| 258 | - recall_syntax = | |
| 259 | - print("\nUsage: http_get <server> <document> [options] =<header> <value> ... -<arg> <value> ...\n"); | |
| 260 | - print(" Options are:\n"); | |
| 261 | - print(" -print_all print request, response line, headers and document\n"); | |
| 262 | - print(" (default is to print only the document)\n"). | |
| 263 | - | |
| 264 | - | |
| 265 | - | |
| 266 | - | |
| 267 | -global define One | |
| 268 | - http_get | |
| 269 | - ( | |
| 270 | - List(String) args | |
| 271 | - ) = | |
| 272 | - if args is | |
| 273 | - { | |
| 274 | - [ ] then recall_syntax, | |
| 275 | - [server . t] then if t is | |
| 276 | - { | |
| 277 | - [ ] then recall_syntax, | |
| 278 | - [document . rest] then | |
| 279 | - with print_all = member(rest,"-print_all"), | |
| 280 | - headers = get_headers(rest), | |
| 281 | - arguments = get_arguments(rest), | |
| 282 | - if http_get(print_all,server,document,headers,arguments) is | |
| 283 | - { | |
| 284 | - cannot_resolve_server_name(dns_error) then | |
| 285 | - print("Cannot resolve server name: " + format(dns_error) + ".\n"), | |
| 286 | - | |
| 287 | - cannot_connect_to_server(connect_error) then | |
| 288 | - print("Cannot connect to server: " + format(connect_error) + ".\n"), | |
| 289 | - | |
| 290 | - transmission_problem then | |
| 291 | - print("Transmission problem.\n"), | |
| 292 | - | |
| 293 | - request_refused_by_server then | |
| 294 | - print("The request has been refused by server: " + server + ".\n"), | |
| 295 | - | |
| 296 | - ok(response,headers1,document1) then | |
| 297 | - ( | |
| 298 | - if print_all | |
| 299 | - then ( | |
| 300 | - print("\n----- response ----\n"); | |
| 301 | - print(response); | |
| 302 | - print("\n----- headers -----\n"); | |
| 303 | - print_headers(headers1); | |
| 304 | - print("----- document ----\n") | |
| 305 | - ) else unique | |
| 306 | - ); | |
| 307 | - print(document1) // on the screen (use a redirection to get it in a file) | |
| 308 | - } | |
| 309 | - } | |
| 310 | - }. | |
| 311 | - | |
| 1 | + *Project* The Anubis Project | |
| 2 | + | |
| 3 | + *Title* Getting a document from the Web. | |
| 4 | + | |
| 5 | + *Copyright* Copyright (c) Alain Prouté 2001. | |
| 6 | + | |
| 7 | + | |
| 8 | + *Author* Alain Prouté | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + *Overview* | |
| 13 | + This file defines the function 'http_get' which retrieves a document from the world | |
| 14 | + wide web (a similar function 'https_get' for secured documents is defined in | |
| 15 | + 'https_get.anubis'). The function simulates the behavior of a browser, at least just | |
| 16 | + what is needed to retrieve the document. It does not display the document, but returns | |
| 17 | + it (if found) in the form of a string. It also returns the response line from the | |
| 18 | + server, and the list af all HTTP headers. | |
| 19 | + | |
| 20 | + The function 'http_get' takes the following arguments: | |
| 21 | + | |
| 22 | + - the name of the server to which the request is to be sent, | |
| 23 | + - the name (including the path) of the document on this server, | |
| 24 | + - a list of headers to be added to mandatory standard headers, | |
| 25 | + - a list of 'arguments' in the form of pairs of strings '(name,value)' to be sent as | |
| 26 | + the body of the request. | |
| 27 | + | |
| 28 | + | |
| 29 | + The result returned by 'http_get' has the following type, which defines the problems | |
| 30 | + which may happen: | |
| 31 | + | |
| 32 | + | |
| 33 | +read tools/basis.anubis | |
| 34 | +read system/string.anubis | |
| 35 | +transmit calexium_lib/web/CXM_common.anubis | |
| 36 | +transmit calexium_lib/web/CXM_http_get_common.anubis | |
| 37 | + | |
| 38 | + | |
| 39 | +public type HTTP_GET_Result: | |
| 40 | + cannot_resolve_server_name(DNS_Result), | |
| 41 | + cannot_connect_to_server(NetworkConnectError), | |
| 42 | + transmission_problem, | |
| 43 | + request_refused_by_server, | |
| 44 | + ok(String response, // HTTP response line from the server | |
| 45 | + List(HTTP_header) headers, // HTTP headers received from the server | |
| 46 | + String document). // The HTML document itself | |
| 47 | + | |
| 48 | + | |
| 49 | +public define HTTP_GET_Result | |
| 50 | + http_get | |
| 51 | + ( //-------- example: ----------------------- | |
| 52 | + String server_name, // "www.machin.com" | |
| 53 | + String document_name, // "/truc/bidule.html" | |
| 54 | + List(HTTP_header) headers, // [http_header("Cookie","..."),...] | |
| 55 | + List(HTTP_argument) arguments // [http_argument("ga","bu"),...] | |
| 56 | + ). | |
| 57 | + | |
| 58 | + The same one without the 'headers' argument: | |
| 59 | + | |
| 60 | +public define HTTP_GET_Result | |
| 61 | + http_get | |
| 62 | + ( //-------- example: ----------------------- | |
| 63 | + String server_name, // "www.machin.com" | |
| 64 | + String document_name, // "/truc/bidule.html" | |
| 65 | + List(HTTP_argument) arguments // [http_argument("ga","bu"),...] | |
| 66 | + ) = http_get(server_name,document_name,[],arguments). | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + This file also defines the command 'http_get' to be used directly from the system | |
| 71 | + prompt. To learn about the syntax, just type 'http_get' at the system prompt, or have | |
| 72 | + a look at the end of this file | |
| 73 | + | |
| 74 | + --- That's all for public definitions. ------------------------------------------------ | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + We need two functions for sending and receiving bytes. | |
| 79 | + | |
| 80 | +define Maybe(One) | |
| 81 | + send | |
| 82 | + ( | |
| 83 | + RWStream conn, // where to send the text | |
| 84 | + String text, // the text to be sent | |
| 85 | + Word32 n // start sending at character number 'n' in 'text' | |
| 86 | + ) = | |
| 87 | + if nth(to_Int(n),text) is | |
| 88 | + { | |
| 89 | + failure then success(unique), | |
| 90 | + success(c) then | |
| 91 | + if conn <- c is | |
| 92 | + { | |
| 93 | + failure then failure, | |
| 94 | + success(_) then send(conn,text,n+1) | |
| 95 | + } | |
| 96 | + }. | |
| 97 | + | |
| 98 | +define Maybe(String) | |
| 99 | + receive_text_chunk | |
| 100 | + ( | |
| 101 | + RWStream conn, | |
| 102 | + List(Word8) so_far, | |
| 103 | + Word32 count | |
| 104 | + ) = | |
| 105 | + if count = 1000 then | |
| 106 | + success(implode(reverse(so_far))) | |
| 107 | + else if *conn is // *conn waits for data to be readable from connection | |
| 108 | + { | |
| 109 | + failure then success(implode(reverse(so_far))), // means 'connection closed by peer' | |
| 110 | + success(c) then | |
| 111 | + receive_text_chunk(conn, [c . so_far], count+1) | |
| 112 | + }. | |
| 113 | + | |
| 114 | + | |
| 115 | +define HTTP_GET_Result | |
| 116 | + receive | |
| 117 | + ( | |
| 118 | + RWStream conn, | |
| 119 | + String headers, | |
| 120 | + String text_so_far, | |
| 121 | + Bool double_crlf_seen | |
| 122 | + ) = | |
| 123 | + if receive_text_chunk(conn,[],0) is | |
| 124 | + { | |
| 125 | + failure then if separate_headers(headers) is | |
| 126 | + { | |
| 127 | + [ ] then ok("",[],text_so_far), | |
| 128 | + [h . t] then if h is http_header(a,b) then ok(a,t,text_so_far) | |
| 129 | + }, | |
| 130 | + | |
| 131 | + success(s) then | |
| 132 | + if s = "" then | |
| 133 | + if separate_headers(headers) is | |
| 134 | + { | |
| 135 | + [ ] then ok("",[],text_so_far), | |
| 136 | + [h . t] then if h is http_header(a,b) then ok(a,t,text_so_far) | |
| 137 | + } | |
| 138 | + else | |
| 139 | + with new_s = text_so_far+s, | |
| 140 | + if double_crlf_seen then | |
| 141 | + with len = length(s), | |
| 142 | + println("content received : "+len+" bytes"); | |
| 143 | + receive(conn, headers, new_s, true) | |
| 144 | + else if has_double_crlf(new_s) is | |
| 145 | + { | |
| 146 | + failure then | |
| 147 | + receive(conn, headers, new_s, false), | |
| 148 | + success(n) then | |
| 149 | + //extract the begin of data | |
| 150 | + if sub_string(new_s,n+4,length(new_s)-n-4) is | |
| 151 | + { | |
| 152 | + failure then alert, | |
| 153 | + success(s1) then | |
| 154 | + //extract end of the header | |
| 155 | + if sub_string(new_s, 0, n) is | |
| 156 | + { | |
| 157 | + failure then alert, | |
| 158 | + success(h) then receive(conn, h, s1, true) | |
| 159 | + } | |
| 160 | + } | |
| 161 | + } | |
| 162 | + }. | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + The next function has a valid TCP/IP connection to the server, and tries to retrieve | |
| 167 | + the document. | |
| 168 | + | |
| 169 | + | |
| 170 | +define HTTP_GET_Result | |
| 171 | + http_get | |
| 172 | + ( | |
| 173 | + Bool print_all, | |
| 174 | + RWStream conn, | |
| 175 | + String server_name, | |
| 176 | + String document_name, | |
| 177 | + List(HTTP_header) headers, | |
| 178 | + List(HTTP_argument) arguments, | |
| 179 | + ) = | |
| 180 | + // | |
| 181 | + // Send the HTTP request, and receive the answer: | |
| 182 | + // | |
| 183 | + with body = format_http_args(arguments), | |
| 184 | + with request = (if arguments = [] then "GET " else "POST ") | |
| 185 | + + document_name + " HTTP/1.1" + crlf + | |
| 186 | + "Host: " + server_name + crlf + | |
| 187 | + "Accept-Charset: iso-8859-1,*,utf-8" + crlf + | |
| 188 | + (if arguments = [] then "" | |
| 189 | + else "Content-type: application/x-www-form-urlencoded" + crlf + | |
| 190 | + "Content-length: " + to_decimal(length(body))+ crlf) + | |
| 191 | + format_headers(headers) + | |
| 192 | + crlf + | |
| 193 | + body, | |
| 194 | + (if print_all then | |
| 195 | + ( | |
| 196 | + print("----- request ----\n"); | |
| 197 | + print(request); | |
| 198 | + print("\n") | |
| 199 | + ) else unique); | |
| 200 | + if send(conn,request,0) is | |
| 201 | + { | |
| 202 | + failure then transmission_problem, | |
| 203 | + success(_) then receive(conn,"","",false) | |
| 204 | + }. | |
| 205 | + | |
| 206 | + | |
| 207 | + The next function retrieves the document using the numerical (resolved) server address. | |
| 208 | + | |
| 209 | +define HTTP_GET_Result | |
| 210 | + http_get | |
| 211 | + ( | |
| 212 | + Bool print_all, | |
| 213 | + Word32 server_addr, | |
| 214 | + Word32 server_port, | |
| 215 | + String server_name, | |
| 216 | + String document_name, | |
| 217 | + List(HTTP_header) headers, | |
| 218 | + List(HTTP_argument) arguments, | |
| 219 | + ) = | |
| 220 | + // | |
| 221 | + // try to connect to the server before sending the request | |
| 222 | + // | |
| 223 | + if (Result(NetworkConnectError,RWStream))connect(server_addr,server_port) is | |
| 224 | + { | |
| 225 | + error(e) then cannot_connect_to_server(e), | |
| 226 | + ok(conn) then http_get(print_all,conn,server_name,document_name,headers,arguments) | |
| 227 | + }. | |
| 228 | + | |
| 229 | + | |
| 230 | +public define HTTP_GET_Result | |
| 231 | + http_get | |
| 232 | + ( | |
| 233 | + Bool print_all, | |
| 234 | + String server_name, | |
| 235 | + String document_name, | |
| 236 | + List(HTTP_header) headers, | |
| 237 | + List(HTTP_argument) arguments, | |
| 238 | + ) = | |
| 239 | + if separate_name_port(server_name,80) is (name,port) then | |
| 240 | + // | |
| 241 | + // resolve server name and call 'http_get' with numeric server address: | |
| 242 | + // | |
| 243 | + with a = dns(name), | |
| 244 | + if a is ok(addr) | |
| 245 | + then http_get(print_all,addr,port,name,document_name,headers,arguments) | |
| 246 | + else cannot_resolve_server_name(a). | |
| 247 | + | |
| 248 | + | |
| 249 | + Now, here is our public tool: | |
| 250 | + | |
| 251 | +public define HTTP_GET_Result | |
| 252 | + http_get | |
| 253 | + ( | |
| 254 | + String server_name, | |
| 255 | + String document_name, | |
| 256 | + List(HTTP_header) headers, | |
| 257 | + List(HTTP_argument) arguments, | |
| 258 | + ) = http_get(false,server_name,document_name,headers,arguments). | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + Finally, we construct the executable module 'http_get': | |
| 263 | + | |
| 264 | +define One | |
| 265 | + recall_syntax = | |
| 266 | + print("\nUsage: http_get <server> <document> [options] =<header> <value> ... -<arg> <value> ...\n"); | |
| 267 | + print(" Options are:\n"); | |
| 268 | + print(" -print_all print request, response line, headers and document\n"); | |
| 269 | + print(" (default is to print only the document)\n"). | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + global define One | |
| 275 | + http_get | |
| 276 | + ( | |
| 277 | + List(String) args | |
| 278 | + ) = | |
| 279 | + if args is | |
| 280 | + { | |
| 281 | + [ ] then recall_syntax, | |
| 282 | + [server . t] then if t is | |
| 283 | + { | |
| 284 | + [ ] then recall_syntax, | |
| 285 | + [document . rest] then | |
| 286 | + with print_all = member(rest,"-print_all"), | |
| 287 | + headers = get_headers(rest), | |
| 288 | + arguments = get_arguments(rest), | |
| 289 | + if http_get(print_all,server,document,headers,arguments) is | |
| 290 | + { | |
| 291 | + cannot_resolve_server_name(dns_error) then | |
| 292 | + print("Cannot resolve server name: " + format(dns_error) + ".\n"), | |
| 293 | + | |
| 294 | + cannot_connect_to_server(connect_error) then | |
| 295 | + print("Cannot connect to server: " + format(connect_error) + ".\n"), | |
| 296 | + | |
| 297 | + transmission_problem then | |
| 298 | + print("Transmission problem.\n"), | |
| 299 | + | |
| 300 | + request_refused_by_server then | |
| 301 | + print("The request has been refused by server: " + server + ".\n"), | |
| 302 | + | |
| 303 | + ok(response,headers1,document1) then | |
| 304 | + ( | |
| 305 | + if print_all | |
| 306 | + then ( | |
| 307 | + print("\n----- response ----\n"); | |
| 308 | + print(response); | |
| 309 | + print("\n----- headers -----\n"); | |
| 310 | + print_headers(headers1); | |
| 311 | + print("----- document ----\n") | |
| 312 | + ) else unique | |
| 313 | + ); | |
| 314 | + print(document1) // on the screen (use a redirection to get it in a file) | |
| 315 | + } | |
| 316 | + } | |
| 317 | + }. | |
| 318 | + | ... | ... |
web/CXM_making_a_web_site.anubis
| ... | ... | @@ -1002,6 +1002,33 @@ public define Printable_tree [WebArgName x . Printable_tree y] = str_pt(x.name |
| 1002 | 1002 | public define Printable_tree [WebArgValue x . Printable_tree y] = str_pt(x.value, y). |
| 1003 | 1003 | public define Printable_tree [InitialValue x . Printable_tree y] = str_pt(x.value, y). |
| 1004 | 1004 | |
| 1005 | +public type HTML_tooltip: | |
| 1006 | + html_tooltip | |
| 1007 | + ( | |
| 1008 | + String title, | |
| 1009 | + String keyword, | |
| 1010 | + Int width, | |
| 1011 | + ), | |
| 1012 | + html_tooltip_ext | |
| 1013 | + ( | |
| 1014 | + String title, | |
| 1015 | + String extend_type, | |
| 1016 | + String class_suffix, | |
| 1017 | + List((String, String)) ext_args | |
| 1018 | + ), | |
| 1019 | + html_tooltip_ext //same without class suffix. This means we use awesome font | |
| 1020 | + ( | |
| 1021 | + String title, | |
| 1022 | + String extend_type, | |
| 1023 | + List((String, String)) ext_args | |
| 1024 | + ), | |
| 1025 | + html_tooltip | |
| 1026 | + ( | |
| 1027 | + String title, | |
| 1028 | + WEB_Action_Name wan, | |
| 1029 | + List((String, String)) ext_args | |
| 1030 | + ). | |
| 1031 | + | |
| 1005 | 1032 | |
| 1006 | 1033 | public type HtmlEvents: |
| 1007 | 1034 | // Window Event Attributes |
| ... | ... | @@ -1087,18 +1114,31 @@ public type HtmlEvents: |
| 1087 | 1114 | |
| 1088 | 1115 | public type CoreAttrs: |
| 1089 | 1116 | empty, |
| 1090 | - id (String), | |
| 1091 | - class (String), | |
| 1092 | - style (String), | |
| 1093 | - title (String), | |
| 1094 | - lang (String), | |
| 1095 | - dir (Reading_Way), | |
| 1096 | - accesskey (Word8), | |
| 1097 | - tabindex (Int), | |
| 1098 | - attr (String, String), | |
| 1099 | - event (HtmlEvents, String), | |
| 1117 | + id (String), //A unique identifier for the element. | |
| 1118 | + //There must not be multiple elements in a document that have the same id value. | |
| 1119 | + class (String), //A name of a classification, or list of names of classifications, to which the element belongs | |
| 1120 | + style (String), //Specifies zero or more CSS declarations that apply to the element [CSS]. | |
| 1121 | + title (String), //Advisory information associated with the element. | |
| 1122 | + lang (String), //Specifies the primary language for the contents of the element and for any of the element’s attributes that contain text. | |
| 1123 | + dir (Reading_Way), //Specifies the element’s text directionality. | |
| 1124 | + accesskey (Word8), //A key label or list of key labels with which to associate the element; each key label represents | |
| 1125 | + //a keyboard shortcut which UAs can use to activate the element or give focus to the element. | |
| 1126 | + tabindex (Int), //Specifies whether the element represents an element that is is focusable (that is, an element which is part of the | |
| 1127 | + //sequence of focusable elements in the document), and the relative order of the element in the sequence of focusable | |
| 1128 | + //elements in the document. | |
| 1129 | + //Anubis specific | |
| 1130 | + attr (String, String), //intended to provide unknown attritute | |
| 1131 | + event (HtmlEvents, String), | |
| 1132 | + tooltip (HTML_tooltip), | |
| 1133 | + | |
| 1100 | 1134 | //HTML5 |
| 1101 | - data (String name, String value). | |
| 1135 | + data (String name, String value), | |
| 1136 | + contenteditable(Bool), //Specifies whether the contents of the element are editable | |
| 1137 | + contextmenu(String), //Identifies a menu with which to associate the element as a context menu. | |
| 1138 | + draggable(Bool), //Specifies whether the element is draggable. | |
| 1139 | + hidden(Bool), //Specifies that the element represents an element that is not yet, or is no longer, relevant. | |
| 1140 | + spellcheck(Bool) //Specifies whether the element represents an element whose contents are subject to spell checking and grammar checking. | |
| 1141 | +. | |
| 1102 | 1142 | |
| 1103 | 1143 | public define CoreAttrs attr(String name, Bool value) = attr(name, if value then "true" else "false"). |
| 1104 | 1144 | |
| ... | ... | @@ -1577,32 +1617,6 @@ public define HTML_Head_Tag |
| 1577 | 1617 | |
| 1578 | 1618 | |
| 1579 | 1619 | |
| 1580 | -public type HTML_tooltip: | |
| 1581 | - html_tooltip | |
| 1582 | - ( | |
| 1583 | - String title, | |
| 1584 | - String keyword, | |
| 1585 | - Int width, | |
| 1586 | - ), | |
| 1587 | - html_tooltip_ext | |
| 1588 | - ( | |
| 1589 | - String title, | |
| 1590 | - String extend_type, | |
| 1591 | - String class_suffix, | |
| 1592 | - List((String, String)) ext_args | |
| 1593 | - ), | |
| 1594 | - html_tooltip_ext //same without class suffix. This means we use awesome font | |
| 1595 | - ( | |
| 1596 | - String title, | |
| 1597 | - String extend_type, | |
| 1598 | - List((String, String)) ext_args | |
| 1599 | - ), | |
| 1600 | - html_tooltip | |
| 1601 | - ( | |
| 1602 | - String title, | |
| 1603 | - WEB_Action_Name wan, | |
| 1604 | - List((String, String)) ext_args | |
| 1605 | - ). | |
| 1606 | 1620 | |
| 1607 | 1621 | |
| 1608 | 1622 | public define HTML_tooltip |
| ... | ... | @@ -4801,6 +4815,8 @@ define String |
| 4801 | 4815 | current + format_attrs(t, classes, styles) |
| 4802 | 4816 | }. |
| 4803 | 4817 | |
| 4818 | +public define List(CoreAttrs) extract_attributes(HTML_tooltip htt). | |
| 4819 | + | |
| 4804 | 4820 | define String |
| 4805 | 4821 | format_attrs |
| 4806 | 4822 | ( |
| ... | ... | @@ -4814,41 +4830,60 @@ define String |
| 4814 | 4830 | (if length(classes) = 0 then "" else " class=\""+join(" ",classes)+"\"")+ |
| 4815 | 4831 | if length(styles) = 0 then "" else " style=\""+join(";",styles)+"\"", |
| 4816 | 4832 | [h . t] then |
| 4817 | - with new_classes = if h is class(class_name) then [class_name. classes] else classes, | |
| 4818 | - new_styles = if h is style(style_string) then [style_string . styles] else styles, | |
| 4819 | - current = if h is | |
| 4820 | - { | |
| 4821 | - empty then "", | |
| 4822 | - id(id_name) then | |
| 4823 | - " id=\"" + id_name + "\"", | |
| 4824 | - class(class_name) then "", //do nothing here, because we accumulate the class until we have some other attributes | |
| 4825 | - style(style_string) then "", //do nothing here, because we accumulate the style until we have some other attributes | |
| 4826 | - title(title_string) then | |
| 4827 | - " title=\"" + title_string + "\"", | |
| 4828 | - | |
| 4829 | - lang(lang) then | |
| 4830 | - " xml:lang=" + lang, | |
| 4831 | - dir(reading_Way) then | |
| 4832 | - if reading_Way is | |
| 4833 | - { | |
| 4834 | - ltr then " dir=ltr", | |
| 4835 | - rtl then " dir=rtl" | |
| 4836 | - }, | |
| 4837 | - | |
| 4838 | - accesskey(key) then | |
| 4839 | - " accesskey=\"" + key + "\"", | |
| 4840 | - tabindex(index) then | |
| 4841 | - " tabindex=\"" + index + "\"", | |
| 4842 | - | |
| 4843 | - attr(name, value) then | |
| 4844 | - " " + name + "=\"" + value + "\"", | |
| 4845 | - | |
| 4846 | - event(e, value) then | |
| 4847 | - " " + event_name(e) + "=\"" + value + "\"", | |
| 4848 | - data(name, value) then | |
| 4849 | - " data-" + to_lower(name) + "=\"" + value + "\"", | |
| 4850 | - }, | |
| 4851 | - current + format_attrs(t, new_classes, new_styles) | |
| 4833 | + with new_classes = if h is class(class_name) then [class_name. classes] else classes, | |
| 4834 | + new_styles = if h is style(style_string) then [style_string . styles] else styles, | |
| 4835 | + new_attrs = if h is tooltip(tt) then extract_attributes(tt) else [], | |
| 4836 | + | |
| 4837 | + current = if h is | |
| 4838 | + { | |
| 4839 | + empty then "", | |
| 4840 | + id(id_name) then | |
| 4841 | + " id=\"" + id_name + "\"", | |
| 4842 | + class(class_name) then "", //do nothing here, because we accumulate the class until we have some other attributes | |
| 4843 | + style(style_string) then "", //do nothing here, because we accumulate the style until we have some other attributes | |
| 4844 | + title(title_string) then | |
| 4845 | + " title=\"" + title_string + "\"", | |
| 4846 | + | |
| 4847 | + lang(lang) then | |
| 4848 | + " xml:lang=" + lang, | |
| 4849 | + dir(reading_Way) then | |
| 4850 | + if reading_Way is | |
| 4851 | + { | |
| 4852 | + ltr then " dir=ltr", | |
| 4853 | + rtl then " dir=rtl" | |
| 4854 | + }, | |
| 4855 | + | |
| 4856 | + accesskey(key) then | |
| 4857 | + " accesskey=\"" + key + "\"", | |
| 4858 | + tabindex(index) then | |
| 4859 | + " tabindex=\"" + index + "\"", | |
| 4860 | + | |
| 4861 | + attr(name, value) then | |
| 4862 | + " " + name + "=\"" + value + "\"", | |
| 4863 | + | |
| 4864 | + event(e, value) then | |
| 4865 | + " " + event_name(e) + "=\"" + value + "\"", | |
| 4866 | + tooltip(_) then "", //do nothing here, because we extract attributes at first in new_attrs | |
| 4867 | + data(name, value) then | |
| 4868 | + " data-" + to_lower(name) + "=\"" + value + "\"", | |
| 4869 | + | |
| 4870 | + contenteditable(value)then //boolean value | |
| 4871 | + " contenteditable=\""+ to_String(value)+ "\"" | |
| 4872 | + | |
| 4873 | + contextmenu(id_name) then //ID value | |
| 4874 | + " contextmenu=\"" + id_name + "\"", | |
| 4875 | + | |
| 4876 | + draggable(value) then //boolean value | |
| 4877 | + " draggable=\""+ to_String(value)+ "\"" | |
| 4878 | + | |
| 4879 | + hidden(value) then //boolean value | |
| 4880 | + " hidden=\""+ (if value then "hidden" else "") + "\"" | |
| 4881 | + | |
| 4882 | + spellcheck(value) then //boolean value | |
| 4883 | + " spellcheck=\""+ to_String(value)+ "\"" | |
| 4884 | + | |
| 4885 | + }, | |
| 4886 | + current + format_attrs(t + new_attrs, new_classes, new_styles) | |
| 4852 | 4887 | }. |
| 4853 | 4888 | |
| 4854 | 4889 | define String |
| ... | ... | @@ -4878,50 +4913,13 @@ define String |
| 4878 | 4913 | (if length(core_attrs) = 0 then "" else format_attrs(core_attrs)) |
| 4879 | 4914 | . |
| 4880 | 4915 | |
| 4881 | -//define String | |
| 4882 | -// _format | |
| 4883 | -// ( | |
| 4884 | -// List(CoreAttrs) opt | |
| 4885 | -// )= | |
| 4886 | -// if opt is | |
| 4887 | -// { | |
| 4888 | -// [] then "", | |
| 4889 | -// [h .t] then | |
| 4890 | -// with current = if h is | |
| 4891 | -// { | |
| 4892 | -// id(id_name) then | |
| 4893 | -// " id=\"" + id_name + "\"", | |
| 4894 | -// class(class_name) then | |
| 4895 | -// " class=\"" + class_name + "\"", | |
| 4896 | -// style(style_string) then | |
| 4897 | -// " style=\"" + style_string + "\"", | |
| 4898 | -// | |
| 4899 | -// title(title_string) then | |
| 4900 | -// " title=\"" + title_string + "\"", | |
| 4901 | -// lang(lang) then | |
| 4902 | -// " xml:lang=" + lang, | |
| 4903 | -// dir(reading_Way) then | |
| 4904 | -// if reading_Way is | |
| 4905 | -// { | |
| 4906 | -// ltr then " dir=ltr", | |
| 4907 | -// rtl then " dir=rtl" | |
| 4908 | -// }, | |
| 4909 | -// attr(name, value) then | |
| 4910 | -// " " + name + "=\"" + value + "\"", | |
| 4911 | -// event(e, value) then | |
| 4912 | -// " " + event_name(e) + "=\"" + value + "\"" | |
| 4913 | -// }, | |
| 4914 | -// current + _format(t) | |
| 4915 | -// } | |
| 4916 | -// . | |
| 4917 | - | |
| 4918 | 4916 | define Printable_tree |
| 4919 | 4917 | format_div_option |
| 4920 | 4918 | ( |
| 4921 | 4919 | List(CoreAttrs) options |
| 4922 | 4920 | )= |
| 4923 | - ["<div" + format_attrs(options) + ">"] . | |
| 4924 | - | |
| 4921 | + ["<div" + format_attrs(options) + ">"] | |
| 4922 | +. | |
| 4925 | 4923 | |
| 4926 | 4924 | define Maybe(String) |
| 4927 | 4925 | extract_id |
| ... | ... | @@ -4930,11 +4928,12 @@ define Maybe(String) |
| 4930 | 4928 | ) = |
| 4931 | 4929 | if attrbs is |
| 4932 | 4930 | { |
| 4933 | - [] then failure, | |
| 4931 | + [] then failure, | |
| 4934 | 4932 | [h . t] then |
| 4935 | 4933 | if h is id(value) then success(value) |
| 4936 | 4934 | else extract_id(t) |
| 4937 | - }. | |
| 4935 | + } | |
| 4936 | +. | |
| 4938 | 4937 | |
| 4939 | 4938 | define Maybe(String) |
| 4940 | 4939 | extract_id |
| ... | ... | @@ -5774,6 +5773,39 @@ define Printable_tree |
| 5774 | 5773 | // ["<a id=\"jTip\" class=\"jTipu jTip_",class_suffix,"\" name=\"",title,"\" href=\"/?a=ajax_show_tooltip&tooltip_ext=",extend_type+extra_args,"\"></a>"] |
| 5775 | 5774 | // }. |
| 5776 | 5775 | |
| 5776 | +public define List(CoreAttrs) | |
| 5777 | + extract_attributes | |
| 5778 | + ( | |
| 5779 | + HTML_tooltip tooltip | |
| 5780 | + )= | |
| 5781 | + if tooltip is | |
| 5782 | + { | |
| 5783 | + html_tooltip(title, keyword, width) then //TODO | |
| 5784 | + [] | |
| 5785 | + //["<a id=\"help_",keyword,"\" class=\"jTipu \" name=\"",title,"\" href=\"/?a=ajax_show_tooltip&tooltip_id=",keyword,(if width > 0 then ["&width=",width,"\""] else ["\""]), "><i class=\"fa fa-info\" aria-hidden=\"true\" style=\"color:#2e6da4\"></i></a>"], | |
| 5786 | + | |
| 5787 | + html_tooltip_ext(title, extend_type, class_suffix, ext_args) then //TODO | |
| 5788 | + [] | |
| 5789 | + //with extra_args = format_extra_operands(ext_args), | |
| 5790 | + //["<a id=\"jTip\" class=\"jTipu jTip_",class_suffix,"\" name=\"",title,"\" href=\"/?a=ajax_show_tooltip&tooltip_ext=",extend_type+extra_args,"\"></a>"] | |
| 5791 | + | |
| 5792 | + html_tooltip_ext(title, extend_type, ext_args) then //TODO | |
| 5793 | + [] | |
| 5794 | + //with extra_args = format_extra_operands(ext_args), | |
| 5795 | + //["<a id=\"jTip\" class=\"jTipu \" name=\"",title,"\" href=\"/?a=ajax_show_tooltip&tooltip_ext=",extend_type+extra_args,"\"><i class=\"fa fa-info\" aria-hidden=\"true\" style=\"color:#2e6da4\"></i></a>"], | |
| 5796 | + | |
| 5797 | + html_tooltip(title, web_action, extra_args) then | |
| 5798 | + [ id("jTip"), class("jTipu"), data("name", title), data("href", "/"+format_web_action_name(web_action, extra_args)) | |
| 5799 | + ] | |
| 5800 | + | |
| 5801 | + //["<a id=\"jTip\" class=\"jTipu \" name=\"",title,"\" href=\"/", format_web_action_name(web_action, extra_args) ,"\"><i class=\"fa fa-info\" aria-hidden=\"true\" style=\"color:#2e6da4\"></i></a>"], | |
| 5802 | + | |
| 5803 | + } | |
| 5804 | +. | |
| 5805 | + | |
| 5806 | + literal_pt(["<span id=\"jTip\" class=\"jTipu\" data-name=\"",title,"\" data-href=\"/", format_web_action_name(web_action, extra_args) ,"\">"]), | |
| 5807 | + | |
| 5808 | + | |
| 5777 | 5809 | public define Printable_tree |
| 5778 | 5810 | format |
| 5779 | 5811 | ( |
| ... | ... | @@ -5794,7 +5826,8 @@ public define Printable_tree |
| 5794 | 5826 | html_tooltip(title, web_action, extra_args) then |
| 5795 | 5827 | ["<a id=\"jTip\" class=\"jTipu \" name=\"",title,"\" href=\"/", format_web_action_name(web_action, extra_args) ,"\"><i class=\"fa fa-info\" aria-hidden=\"true\" style=\"color:#2e6da4\"></i></a>"], |
| 5796 | 5828 | |
| 5797 | - }. | |
| 5829 | + } | |
| 5830 | +. | |
| 5798 | 5831 | |
| 5799 | 5832 | public define HTML_Off_Form |
| 5800 | 5833 | html_tooltip |
| ... | ... | @@ -5805,9 +5838,9 @@ public define HTML_Off_Form |
| 5805 | 5838 | HTML_Off_Form html_element, |
| 5806 | 5839 | )= |
| 5807 | 5840 | sequence([ |
| 5808 | - literal_pt(["<a id=\"jTip\" class=\"jTipu \" name=\"",title,"\" href=\"/", format_web_action_name(web_action, extra_args) ,"\">"]), | |
| 5841 | + literal_pt(["<span id=\"jTip\" class=\"jTipu\" data-name=\"",title,"\" data-href=\"/", format_web_action_name(web_action, extra_args) ,"\">"]), | |
| 5809 | 5842 | html_element, |
| 5810 | - literal_pt(["</a>"]) | |
| 5843 | + literal_pt(["</span>"]) | |
| 5811 | 5844 | ]) |
| 5812 | 5845 | . |
| 5813 | 5846 | ... | ... |