changeset 1956:ac1be85e91ad

Add 'html5' .urp directive
author Adam Chlipala <adam@chlipala.net>
date Thu, 09 Jan 2014 17:27:24 -0500
parents 469e02eea43a
children ef9fdbb05c73
files doc/manual.tex include/urweb/types_cpp.h include/urweb/urweb_cpp.h src/c/urweb.c src/cjr_print.sml src/compiler.sml src/settings.sig src/settings.sml
diffstat 8 files changed, 28 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/doc/manual.tex	Tue Jan 07 08:36:18 2014 -0500
+++ b/doc/manual.tex	Thu Jan 09 17:27:24 2014 -0500
@@ -146,6 +146,7 @@
 \item \texttt{effectful Module.ident} registers an FFI function or transaction as having side effects.  The optimizer avoids removing, moving, or duplicating calls to such functions.  This is the default behavior for \texttt{transaction}-based types.
 \item \texttt{exe FILENAME} sets the filename to which to write the output executable.  The default for file \texttt{P.urp} is \texttt{P.exe}.  
 \item \texttt{ffi FILENAME} reads the file \texttt{FILENAME.urs} to determine the interface to a new FFI module.  The name of the module is calculated from \texttt{FILENAME} in the same way as for normal source files.  See the files \texttt{include/urweb/urweb\_cpp.h} and \texttt{src/c/urweb.c} for examples of C headers and implementations for FFI modules.  In general, every type or value \texttt{Module.ident} becomes \texttt{uw\_Module\_ident} in C.
+\item \texttt{html5} activates work-in-progress support for generating HTML5 instead of XHTML.  For now, this option only affects the first few tokens on any page, which are always the same.
 \item \texttt{include FILENAME} adds \texttt{FILENAME} to the list of files to be \texttt{\#include}d in C sources.  This is most useful for interfacing with new FFI modules.
 \item \texttt{jsFunc Module.ident=name} gives the JavaScript name of an FFI value.
 \item \texttt{library FILENAME} parses \texttt{FILENAME.urp} and merges its contents with the rest of the current file's contents.  If \texttt{FILENAME.urp} doesn't exist, the compiler also tries \texttt{FILENAME/lib.urp}.
--- a/include/urweb/types_cpp.h	Tue Jan 07 08:36:18 2014 -0500
+++ b/include/urweb/types_cpp.h	Thu Jan 09 17:27:24 2014 -0500
@@ -102,6 +102,8 @@
   uw_periodic *periodics; // 0-terminated array
 
   uw_Basis_string time_format;
+
+  int is_html5;
 } uw_app;
 
 #define ERROR_BUF_LEN 1024
--- a/include/urweb/urweb_cpp.h	Tue Jan 07 08:36:18 2014 -0500
+++ b/include/urweb/urweb_cpp.h	Thu Jan 09 17:27:24 2014 -0500
@@ -377,4 +377,6 @@
 uw_Basis_string uw_Basis_remainingFields(struct uw_context *, uw_Basis_postField);
 uw_Basis_postField *uw_Basis_firstFormField(struct uw_context *, uw_Basis_string);
 
+extern const char uw_begin_xhtml[], uw_begin_html5[];
+
 #endif
--- a/src/c/urweb.c	Tue Jan 07 08:36:18 2014 -0500
+++ b/src/c/urweb.c	Thu Jan 09 17:27:24 2014 -0500
@@ -3241,7 +3241,8 @@
     return 0;
 }
 
-static const char begin_xhtml[] = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">";
+const char uw_begin_xhtml[] = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">";
+const char uw_begin_html5[] = "<!DOCTYPE html><html>";
 
 extern int uw_hash_blocksize;
 
@@ -3331,11 +3332,14 @@
   uw_check(ctx, 1);
   *ctx->page.front = 0;
 
-  if (!ctx->returning_indirectly && !strncmp(ctx->page.start, begin_xhtml, sizeof begin_xhtml - 1)) {
+  if (!ctx->returning_indirectly
+      && (ctx->app->is_html5
+          ? !strncmp(ctx->page.start, uw_begin_html5, sizeof uw_begin_html5 - 1)
+          : !strncmp(ctx->page.start, uw_begin_xhtml, sizeof uw_begin_xhtml - 1))) {
     char *s;
 
     // Splice script data into appropriate part of page, also adding <head> if needed.
-    s = ctx->page.start + sizeof begin_xhtml - 1;
+    s = ctx->page.start + (ctx->app->is_html5 ? sizeof uw_begin_html5 - 1 : sizeof uw_begin_xhtml - 1);
     s = strchr(s, '<');
     if (s == NULL) {
       // Weird.  Document has no tags!
@@ -4170,7 +4174,7 @@
         uw_write_header(ctx, "Status: ");
       uw_write_header(ctx, "500 Internal Server Error\r\n");
       uw_write_header(ctx, "Content-type: text/html\r\n");
-      uw_write(ctx, begin_xhtml);
+      uw_write(ctx, ctx->app->is_html5 ? uw_begin_html5 : uw_begin_xhtml);
       ctx->app->on_error(ctx, msg);
       uw_write(ctx, "</html>");
     }
--- a/src/cjr_print.sml	Tue Jan 07 08:36:18 2014 -0500
+++ b/src/cjr_print.sml	Thu Jan 09 17:27:24 2014 -0500
@@ -3083,7 +3083,11 @@
                                         ServerOnly => box []
                                       | _ => box [string "uw_write_header(ctx, \"Content-script-type: text/javascript\\r\\n\");",
                                                   newline],
-                                    string "uw_write(ctx, begin_xhtml);",
+                                    string ("uw_write(ctx, uw_begin_" ^
+                                            (if Settings.getIsHtml5 () then
+                                                 "html5"
+                                             else
+                                                 "xhtml") ^ ");"),
                                     newline,
                                     string "uw_mayReturnIndirectly(ctx);",
                                     newline,
@@ -3374,9 +3378,6 @@
              newline,
              newline,
 
-             string "static const char begin_xhtml[] = \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\" ?>\\n<!DOCTYPE html PUBLIC \\\"-//W3C//DTD XHTML 1.0 Transitional//EN\\\" \\\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\\\">\\n<html xmlns=\\\"http://www.w3.org/1999/xhtml\\\" xml:lang=\\\"en\\\" lang=\\\"en\\\">\";",
-             newline,
-             newline,
 
              p_list_sep newline (fn x => x) pds,
              newline,
@@ -3588,7 +3589,8 @@
                          "uw_handle",
                          "uw_input_num", "uw_cookie_sig", "uw_check_url", "uw_check_mime", "uw_check_requestHeader", "uw_check_responseHeader", "uw_check_envVar",
                          case onError of NONE => "NULL" | SOME _ => "uw_onError", "my_periodics",
-                         "\"" ^ Prim.toCString (Settings.getTimeFormat ()) ^ "\""],
+                         "\"" ^ Prim.toCString (Settings.getTimeFormat ()) ^ "\"",
+                         if Settings.getIsHtml5 () then "1" else "0"],
              string "};",
              newline]
     end
--- a/src/compiler.sml	Tue Jan 07 08:36:18 2014 -0500
+++ b/src/compiler.sml	Thu Jan 09 17:27:24 2014 -0500
@@ -865,6 +865,7 @@
                                    | "noXsrfProtection" => Settings.addNoXsrfProtection arg
                                    | "timeFormat" => Settings.setTimeFormat arg
                                    | "noMangleSql" => Settings.setMangleSql false
+                                   | "html5" => Settings.setIsHtml5 true
 
                                    | _ => ErrorMsg.error ("Unrecognized command '" ^ cmd ^ "'");
                                  read ()
--- a/src/settings.sig	Tue Jan 07 08:36:18 2014 -0500
+++ b/src/settings.sig	Thu Jan 09 17:27:24 2014 -0500
@@ -265,4 +265,7 @@
     val mangleSql : string -> string
     val mangleSqlCatalog : string -> string
     val mangleSqlTable : string -> string
+
+    val setIsHtml5 : bool -> unit
+    val getIsHtml5 : unit -> bool
 end
--- a/src/settings.sml	Tue Jan 07 08:36:18 2014 -0500
+++ b/src/settings.sml	Thu Jan 09 17:27:24 2014 -0500
@@ -716,4 +716,8 @@
                   else "\"" ^ lowercase s ^ "\""
 fun mangleSqlCatalog s = if !mangle then "uw_" ^ s else lowercase s
 
+val html5 = ref false
+fun setIsHtml5 b = html5 := b
+fun getIsHtml5 () = !html5
+
 end