<commit_before>open Js
open Dom_html

class type formData = object
  method append : js_string t -> js_string t -> unit meth
  method append_blob : js_string t -> File.blob t -> unit meth
end

let formData : formData t constr =
  Js.Unsafe.variable "window.FormData"

let formData_form : (formElement t -> formData t) constr =
  Js.Unsafe.variable "window.FormData"

type form_elt =
  [ `String of js_string t
  | `File of File.file t ]

type form_contents =
  [ `Fields of (string * form_elt) list ref
  | `FormData of formData t ]

let rec filter_map f = function
  | [] -> []
  | v::q ->
    match f v with
      | None -> filter_map f q
      | Some v' -> v' :: (filter_map f q)

let get_select_val (elt:selectElement t) =
  let name = to_string (elt##name) in
  if to_bool (elt##multiple)
  then
    let options = Array.init ( elt##options##length )
      (fun i -> Optdef.to_option elt##options##item(i)) in
    filter_map (function
      | None -> None
      | Some e ->
	if e##selected
	then Some (name,`String (e##value))
	else None)
      (Array.to_list options)
  else [name,`String (elt##value)]

class type file_input = object
  inherit inputElement
  method files : File.fileList t optdef readonly_prop
  method multiple : bool optdef readonly_prop
end

let get_input_val ?(get=false) (elt:inputElement t) =
  let name = to_string (elt##name) in
  match name with
    | "" -> []
    | _ ->
      let value = elt##value in
      match String.lowercase (to_string (elt##_type)) with
	| "checkbox"
	| "radio" ->
	  if to_bool (elt##checked)
	  then [name,`String value]
	  else []
	| "submit"
	| "reset" -> []
	| "text"
	| "password" -> [name,`String value]
	| "file" ->
	  if get
	  then [name,`String value]
	  else
	    let elt = (Unsafe.coerce elt:file_input t) in
	    (match Optdef.to_option (elt##files) with
	      | None -> []
	      | Some list ->
		if list##length = 0
		then [name,`String (Js.string "")]
		else
		  match Optdef.to_option (elt##multiple) with
		    | None
		    | Some false ->
		      (match Optdef.to_option (list##item(0)) with
			| None -> []
			| Some file -> [name,`File file])
		    | Some true ->
		      filter_map (fun f ->
			match Optdef.to_option f with
			  | None -> None
			  | Some file -> Some (name,`File file))
			(Array.to_list (Array.init (list##length) (fun i -> list##item(i)))))
	| _ -> [name,`String value]

let form_contents ?get (form:formElement t) =
  let length = form##elements##length in
  let elements = Array.to_list
    (Array.init length
       (fun i -> Optdef.to_option (form##elements##item(i)))) in
  let contents =
    List.flatten
      (List.map
	 (function
	   | None -> [] (* shouldn't happen *)
	   | Some v ->
	     match tagged v with
	       | Select v -> get_select_val v
	       | Input v -> get_input_val ?get v
	       | _ -> [] (* shouldn't happen *) )
	 elements)
  in
  contents

let append (form_contents:form_contents) (form_elt:string * form_elt) =
  match form_contents with
    | `Fields list -> list := form_elt::!list
    | `FormData f ->
      match form_elt with
	| name, `String s -> f##append(string name, s)<commit_msg>add textarea elements content retrieval to Form module<commit_after>open Js
open Dom_html

class type formData = object
  method append : js_string t -> js_string t -> unit meth
  method append_blob : js_string t -> File.blob t -> unit meth
end

let formData : formData t constr =
  Js.Unsafe.variable "window.FormData"

let formData_form : (formElement t -> formData t) constr =
  Js.Unsafe.variable "window.FormData"

type form_elt =
  [ `String of js_string t
  | `File of File.file t ]

type form_contents =
  [ `Fields of (string * form_elt) list ref
  | `FormData of formData t ]

let rec filter_map f = function
  | [] -> []
  | v::q ->
    match f v with
      | None -> filter_map f q
      | Some v' -> v' :: (filter_map f q)

class type submittableElement = object
  method disabled : bool t prop
  method name : js_string t readonly_prop
  method value : js_string t prop
end

let have_content (elt:submittableElement t) =
  let name = to_string (elt##name) in
  match name with
    | "" -> false
    | _ -> not (Js.to_bool (elt##disabled))

let get_textarea_val ?(get=false) (elt:textAreaElement t) =
  if have_content (elt:>submittableElement t)
  then
    let name = to_string (elt##name) in
    [name,`String (elt##value)]
  else []

let get_select_val (elt:selectElement t) =
  if have_content (elt:>submittableElement t)
  then
    let name = to_string (elt##name) in
    if to_bool (elt##multiple)
    then
      let options = Array.init ( elt##options##length )
	(fun i -> Optdef.to_option elt##options##item(i)) in
      filter_map (function
	| None -> None
	| Some e ->
	  if e##selected
	  then Some (name,`String (e##value))
	  else None)
	(Array.to_list options)
    else [name,`String (elt##value)]
  else []

class type file_input = object
  inherit inputElement
  method files : File.fileList t optdef readonly_prop
  method multiple : bool optdef readonly_prop
end

let get_input_val ?(get=false) (elt:inputElement t) =
  if have_content (elt:>submittableElement t)
  then
    let name = to_string (elt##name) in
    let value = elt##value in
    match String.lowercase (to_string (elt##_type)) with
      | "checkbox"
      | "radio" ->
	if to_bool (elt##checked)
	then [name,`String value]
	else []
      | "submit"
      | "reset" -> []
      | "text"
      | "password" -> [name,`String value]
      | "file" ->
	if get
	then [name,`String value]
	else
	  let elt = (Unsafe.coerce elt:file_input t) in
	  (match Optdef.to_option (elt##files) with
	    | None -> []
	    | Some list ->
	      if list##length = 0
	      then [name,`String (Js.string "")]
	      else
		match Optdef.to_option (elt##multiple) with
		  | None
		  | Some false ->
		    (match Optdef.to_option (list##item(0)) with
		      | None -> []
		      | Some file -> [name,`File file])
		  | Some true ->
		    filter_map (fun f ->
		      match Optdef.to_option f with
			| None -> None
			| Some file -> Some (name,`File file))
		      (Array.to_list (Array.init (list##length)
					(fun i -> list##item(i)))))
      | _ -> [name,`String value]
  else []

let form_contents ?get (form:formElement t) =
  let length = form##elements##length in
  let elements = Array.to_list
    (Array.init length
       (fun i -> Optdef.to_option (form##elements##item(i)))) in
  let contents =
    List.flatten
      (List.map
	 (function
	   | None -> [] (* shouldn't happen *)
	   | Some v ->
	     match tagged v with
	       | Select v -> get_select_val v
	       | Input v -> get_input_val ?get v
	       | Textarea v -> get_textarea_val v
	       | _ -> [] )
	 elements)
  in
  contents

let append (form_contents:form_contents) (form_elt:string * form_elt) =
  match form_contents with
    | `Fields list -> list := form_elt::!list
    | `FormData f ->
      match form_elt with
	| name, `String s -> f##append(string name, s)
{'fraction_non_alphanumeric': 0.12931530494821633, 'fraction_numerical': 0.0005753739930955121, 'mean_word_length': 2.787037037037037, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 83, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '854497', 'n_tokens_mistral': 2454, 'n_tokens_neox': 2347, 'n_words': 703}