package cascade
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
CSS generation and manipulation library for OCaml
Install
dune-project
Dependency
Authors
Maintainers
Sources
cascade-1.2.0.tbz
sha256=3315f94068943b3655bf530c1d82b68655524ff3601efedfbaf0a7f886fbf5a1
sha512=0f187c8e17fcbddaa0ad2760930956451062e476b678e1e60daf6ad9e7414fad99a2d70534dfdf8bca0a1092e374d009051f06b0ce9da33f2742cdde0187e75c
doc/src/cascade.browser/browser.ml.html
Source file browser.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 170let ( // ) = Filename.concat let getenv name = match Sys.getenv_opt name with Some "" | None -> None | Some v -> Some v let executable path = (try Sys.file_exists path && not (Sys.is_directory path) with Sys_error _ -> false) && try Unix.access path [ Unix.X_OK ]; true with Unix.Unix_error _ | Sys_error _ -> false let on_path name = let dirs = String.split_on_char ':' (Option.value ~default:"" (getenv "PATH")) in List.find_map (fun d -> if d = "" then None else let p = d // name in if executable p then Some p else None) dirs (* The browser caches keep one directory per version, so the largest path is the newest build. *) let rec search_tree root names depth acc = if depth <= 0 then acc else match Sys.readdir root with | exception Sys_error _ -> acc | entries -> Array.fold_left (fun acc entry -> let p = root // entry in if try Sys.is_directory p with Sys_error _ -> false then search_tree p names (depth - 1) acc else if List.mem entry names && executable p then p :: acc else acc) acc entries let chrome_binary () = match getenv "CHROME" with | Some c when executable c -> Some c | Some _ | None -> ( let names = [ "chromium"; "chromium-browser"; "google-chrome"; "google-chrome-stable"; ] in match List.find_map on_path names with | Some c -> Some c | None -> ( let home = Option.value ~default:"" (getenv "HOME") in let caches = [ home // ".cache" // "puppeteer"; home // "Library" // "Caches" // "ms-playwright"; home // ".cache" // "ms-playwright"; ] in let binaries = [ "chrome-headless-shell"; "headless_shell"; "Chromium"; "Google Chrome for Testing"; ] in let found = List.concat_map (fun c -> search_tree c binaries 6 []) caches in match List.sort compare found with | [] -> let app = "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" in if executable app then Some app else None | l -> Some (List.nth l (List.length l - 1)))) let node_binary () = match getenv "NODE" with | Some n when executable n -> Some n | Some _ | None -> on_path "node" let chrome_version chrome = let read_lines ic = let rec loop acc = match input_line ic with | line -> loop (line :: acc) | exception End_of_file -> List.rev acc in loop [] in let ic = Unix.open_process_in (String.concat " " [ Filename.quote chrome; "--version"; "2>/dev/null" ]) in let lines = read_lines ic in ignore (Unix.close_process_in ic); let leading_int s = let n = String.length s in let rec upto i = if i < n && s.[i] >= '0' && s.[i] <= '9' then upto (i + 1) else i in let stop = upto 0 in if stop = 0 then None else int_of_string_opt (String.sub s 0 stop) in let of_word w = match String.split_on_char '.' w with | major :: minor :: _ -> ( match (leading_int major, leading_int minor) with | Some a, Some b -> Some (a, b) | _ -> None) | _ -> None in List.fold_left (fun found line -> match found with | Some _ -> found | None -> List.fold_left (fun found word -> match found with Some _ -> found | None -> of_word word) None (String.split_on_char ' ' line)) None lines let skip harness reason = print_endline (String.concat "" [ "SKIP: "; harness; " ("; reason; ")" ]); exit 0 (* Setting CASCADE_NO_BROWSER silences a gate, and a gate that did not run is not a pass: only the value below, which names the run for what it is, exits 0. A machine with no browser still skips, because there is nothing there to silence. *) let acknowledged = "unchecked" let suppressed harness = match getenv "CASCADE_NO_BROWSER" with | None -> () | Some v when String.equal v acknowledged -> print_endline (String.concat "" [ "SKIP: "; harness; " (CASCADE_NO_BROWSER="; acknowledged; ", so this run checks nothing)"; ]); exit 0 | Some v -> prerr_endline (String.concat "" [ "FAIL: "; harness; " is suppressed by CASCADE_NO_BROWSER="; v; "; a gate that did not run is not a pass. Set CASCADE_NO_BROWSER="; acknowledged; " to exit 0 and say so."; ]); exit 1
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>