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,6 +1002,33 @@ public define Printable_tree [WebArgName x . Printable_tree y] = str_pt(x.name | ||
| 1002 | public define Printable_tree [WebArgValue x . Printable_tree y] = str_pt(x.value, y). | 1002 | public define Printable_tree [WebArgValue x . Printable_tree y] = str_pt(x.value, y). |
| 1003 | public define Printable_tree [InitialValue x . Printable_tree y] = str_pt(x.value, y). | 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 | public type HtmlEvents: | 1033 | public type HtmlEvents: |
| 1007 | // Window Event Attributes | 1034 | // Window Event Attributes |
| @@ -1087,18 +1114,31 @@ public type HtmlEvents: | @@ -1087,18 +1114,31 @@ public type HtmlEvents: | ||
| 1087 | 1114 | ||
| 1088 | public type CoreAttrs: | 1115 | public type CoreAttrs: |
| 1089 | empty, | 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 | //HTML5 | 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 | public define CoreAttrs attr(String name, Bool value) = attr(name, if value then "true" else "false"). | 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,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 | public define HTML_tooltip | 1622 | public define HTML_tooltip |
| @@ -4801,6 +4815,8 @@ define String | @@ -4801,6 +4815,8 @@ define String | ||
| 4801 | current + format_attrs(t, classes, styles) | 4815 | current + format_attrs(t, classes, styles) |
| 4802 | }. | 4816 | }. |
| 4803 | 4817 | ||
| 4818 | +public define List(CoreAttrs) extract_attributes(HTML_tooltip htt). | ||
| 4819 | + | ||
| 4804 | define String | 4820 | define String |
| 4805 | format_attrs | 4821 | format_attrs |
| 4806 | ( | 4822 | ( |
| @@ -4814,41 +4830,60 @@ define String | @@ -4814,41 +4830,60 @@ define String | ||
| 4814 | (if length(classes) = 0 then "" else " class=\""+join(" ",classes)+"\"")+ | 4830 | (if length(classes) = 0 then "" else " class=\""+join(" ",classes)+"\"")+ |
| 4815 | if length(styles) = 0 then "" else " style=\""+join(";",styles)+"\"", | 4831 | if length(styles) = 0 then "" else " style=\""+join(";",styles)+"\"", |
| 4816 | [h . t] then | 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 | define String | 4889 | define String |
| @@ -4878,50 +4913,13 @@ define String | @@ -4878,50 +4913,13 @@ define String | ||
| 4878 | (if length(core_attrs) = 0 then "" else format_attrs(core_attrs)) | 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 | define Printable_tree | 4916 | define Printable_tree |
| 4919 | format_div_option | 4917 | format_div_option |
| 4920 | ( | 4918 | ( |
| 4921 | List(CoreAttrs) options | 4919 | List(CoreAttrs) options |
| 4922 | )= | 4920 | )= |
| 4923 | - ["<div" + format_attrs(options) + ">"] . | ||
| 4924 | - | 4921 | + ["<div" + format_attrs(options) + ">"] |
| 4922 | +. | ||
| 4925 | 4923 | ||
| 4926 | define Maybe(String) | 4924 | define Maybe(String) |
| 4927 | extract_id | 4925 | extract_id |
| @@ -4930,11 +4928,12 @@ define Maybe(String) | @@ -4930,11 +4928,12 @@ define Maybe(String) | ||
| 4930 | ) = | 4928 | ) = |
| 4931 | if attrbs is | 4929 | if attrbs is |
| 4932 | { | 4930 | { |
| 4933 | - [] then failure, | 4931 | + [] then failure, |
| 4934 | [h . t] then | 4932 | [h . t] then |
| 4935 | if h is id(value) then success(value) | 4933 | if h is id(value) then success(value) |
| 4936 | else extract_id(t) | 4934 | else extract_id(t) |
| 4937 | - }. | 4935 | + } |
| 4936 | +. | ||
| 4938 | 4937 | ||
| 4939 | define Maybe(String) | 4938 | define Maybe(String) |
| 4940 | extract_id | 4939 | extract_id |
| @@ -5774,6 +5773,39 @@ define Printable_tree | @@ -5774,6 +5773,39 @@ define Printable_tree | ||
| 5774 | // ["<a id=\"jTip\" class=\"jTipu jTip_",class_suffix,"\" name=\"",title,"\" href=\"/?a=ajax_show_tooltip&tooltip_ext=",extend_type+extra_args,"\"></a>"] | 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 | public define Printable_tree | 5809 | public define Printable_tree |
| 5778 | format | 5810 | format |
| 5779 | ( | 5811 | ( |
| @@ -5794,7 +5826,8 @@ public define Printable_tree | @@ -5794,7 +5826,8 @@ public define Printable_tree | ||
| 5794 | html_tooltip(title, web_action, extra_args) then | 5826 | html_tooltip(title, web_action, extra_args) then |
| 5795 | ["<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>"], | 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 | public define HTML_Off_Form | 5832 | public define HTML_Off_Form |
| 5800 | html_tooltip | 5833 | html_tooltip |
| @@ -5805,9 +5838,9 @@ public define HTML_Off_Form | @@ -5805,9 +5838,9 @@ public define HTML_Off_Form | ||
| 5805 | HTML_Off_Form html_element, | 5838 | HTML_Off_Form html_element, |
| 5806 | )= | 5839 | )= |
| 5807 | sequence([ | 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 | html_element, | 5842 | html_element, |
| 5810 | - literal_pt(["</a>"]) | 5843 | + literal_pt(["</span>"]) |
| 5811 | ]) | 5844 | ]) |
| 5812 | . | 5845 | . |
| 5813 | 5846 |