package server-reason-react
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
Rendering React components on the server natively
Install
dune-project
Dependency
Authors
Maintainers
Sources
server-reason-react-0.4.1.tbz
sha256=2d27cb4656208dde8d5eb0c452c590186d092618ac0a04f1ab0a095a3ca58498
sha512=26e16daf87f6b80eff86ccf7df29153527b24e3f4dbc7f13820d1507b0a2e7d6db40fd774bcaad6e6cccff0bf19d4a411b95a10a071f9ce92d52bf07eb08f75f
doc/src/server-reason-react.html/Html.ml.html
Source file Html.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202let is_self_closing_tag = function (* Take the list from https://github.com/facebook/react/blob/97d75c9c8bcddb0daed1ed062101c7f5e9b825f4/packages/react-dom-bindings/src/shared/omittedCloseTags.js but found https://github.com/wooorm/html-void-elements to be more complete. *) | "area" | "base" | "basefont" | "bgsound" | "br" | "col" | "command" | "embed" | "frame" | "hr" | "image" | "img" | "input" | "keygen" | "link" (* | "menuitem" *) | "meta" | "param" | "source" | "track" | "wbr" -> true | _ -> false let escape buf s = let length = String.length s in let exception First_char_to_escape of int in match for i = 0 to length - 1 do match String.unsafe_get s i with | '&' | '<' | '>' | '\'' | '"' -> raise_notrace (First_char_to_escape i) | _ -> () done with | exception First_char_to_escape first -> if first > 0 then Buffer.add_substring buf s 0 first; for i = first to length - 1 do match String.unsafe_get s i with | '&' -> Buffer.add_string buf "&" | '<' -> Buffer.add_string buf "<" | '>' -> Buffer.add_string buf ">" | '\'' -> Buffer.add_string buf "'" | '"' -> Buffer.add_string buf """ | c -> Buffer.add_char buf c done | () -> Buffer.add_string buf s type attribute = [ `Present of string | `Value of string * string | `Omitted ] type attribute_list = attribute list let attribute name value = `Value (name, value) let present name = `Present name let omitted () = `Omitted let write_attribute buf (attr : attribute) = match attr with | `Omitted -> () | `Present name -> Buffer.add_char buf ' '; Buffer.add_string buf name | `Value (name, value) -> Buffer.add_char buf ' '; Buffer.add_string buf name; Buffer.add_string buf "=\""; escape buf value; Buffer.add_char buf '"' type element = | Null | String of string | Raw of string (* text without encoding *) | Node of node | Int of int | Float of float | List of (string * element list) | Array of element array and node = { tag : string; attributes : attribute_list; children : element list } let string txt = String txt let raw txt = Raw txt let null = Null let int i = Int i let float f = Float f let list ?(separator = "") list = List (separator, list) let array arr = Array arr let fragment arr = List arr let node tag attributes children = Node { tag; attributes; children } let to_string ?(add_separator_between_text_nodes = true) element = let out = Buffer.create 1024 in (* This ref is used to enable rendering comments <!-- --> between text nodes and can be disabled by `add_separator_between_text_nodes` *) let previous_was_text_node = ref false in let should_add_doctype_to_html = ref true in let rec write element = match element with | Null -> should_add_doctype_to_html.contents <- false | Int i -> Buffer.add_string out (Int.to_string i) | Float f -> Buffer.add_string out (Float.to_string f) | String text -> let is_previous_text_node = previous_was_text_node.contents in previous_was_text_node.contents <- true; if is_previous_text_node && add_separator_between_text_nodes then Buffer.add_string out "<!-- -->"; escape out text; should_add_doctype_to_html.contents <- false | Raw text -> Buffer.add_string out text; should_add_doctype_to_html.contents <- false | Node { tag; attributes; _ } when is_self_closing_tag tag -> Buffer.add_char out '<'; Buffer.add_string out tag; List.iter (write_attribute out) attributes; Buffer.add_string out " />"; should_add_doctype_to_html.contents <- false | Node { tag; attributes; children } -> (* capturing the value of should_add_doctype_to_html before setting it to false, so the first thing is set to false and use the captured value *) let should_add_doctype = should_add_doctype_to_html.contents in should_add_doctype_to_html.contents <- false; (* If the previous node was text, but from another parent node, then the comment shouldn't be added. Check `separated_text_nodes_by_other_nodes` in test_renderToString.ml *) if add_separator_between_text_nodes then previous_was_text_node.contents <- false; if tag = "html" && should_add_doctype then Buffer.add_string out "<!DOCTYPE html>"; Buffer.add_char out '<'; Buffer.add_string out tag; List.iter (write_attribute out) attributes; Buffer.add_char out '>'; List.iter write children; Buffer.add_string out "</"; Buffer.add_string out tag; Buffer.add_char out '>' | List ("", list) -> List.iter write list | List (separator, list) -> let rec iter = function | [] -> () | [ one ] -> write one | [ first; second ] -> write first; Buffer.add_string out separator; write second | first :: rest -> write first; Buffer.add_string out separator; iter rest in iter list | Array elements -> Array.iter write elements in write element; Buffer.contents out (* The pretty print is used for debugging purposes *) let pp element = let out = Buffer.create 1024 in let rec write element = match element with | Null -> () | Int i -> Buffer.add_string out (Int.to_string i) | Float f -> Buffer.add_string out (Float.to_string f) | String text -> escape out text | Raw text -> Buffer.add_string out text | Node { tag; attributes; _ } when is_self_closing_tag tag -> Buffer.add_char out '<'; Buffer.add_string out tag; List.iter (write_attribute out) attributes; Buffer.add_string out " />" | Node { tag; attributes; children } -> Buffer.add_char out '<'; Buffer.add_string out tag; List.iter (write_attribute out) attributes; Buffer.add_char out '>'; List.iter write children; Buffer.add_string out "</"; Buffer.add_string out tag; Buffer.add_char out '>' | List ("", list) -> List.iter write list | List (separator, list) -> let rec iter = function | [] -> () | [ one ] -> write one | [ first; second ] -> write first; Buffer.add_string out separator; write second | first :: rest -> write first; Buffer.add_string out separator; iter rest in iter list | Array elements -> Array.iter write elements in write element; Buffer.contents out let add_single_quote_escaped b s = let getc = String.unsafe_get s in let adds = Buffer.add_string in let len = String.length s in let max_idx = len - 1 in let flush b start i = if start < len then Buffer.add_substring b s start (i - start) in let rec loop start i = if i > max_idx then flush b start i else let next = i + 1 in match getc i with | '\'' -> flush b start i; adds b "'"; loop next next | _ -> loop start next in loop 0 0 let single_quote_escape data = let buf = Buffer.create (String.length data) in add_single_quote_escaped buf data; Buffer.contents buf
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>