Skip to content

Commit

Permalink
handle snake-case and camel-case data attributes more consistently
Browse files Browse the repository at this point in the history
  • Loading branch information
cemerick committed Mar 16, 2022
1 parent c893294 commit 905fd4e
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 11 deletions.
26 changes: 16 additions & 10 deletions jsx/tyxml_jsx.ml
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,22 @@ let lowercase_lead s =
String.mapi (fun i c -> if i = 0 then Char.lowercase_ascii c else c) s

let to_kebab_case name =
let length = String.length name in
if length > 5 then
let first = String.sub name 0 4 in
match first with
| "aria"
| "data" ->
first ^ "-" ^ lowercase_lead (String.sub name 4 (length - 4))
| _ -> name
else
name
let open Re in
let kebab string =
replace (Posix.compile_pat "[A-Z]") ~f:(fun g -> "-" ^ Group.get g 0) string
|> String.lowercase_ascii
|> replace_string (compile @@ char '_') ~by:"-" in
match exec_opt (Perl.compile_pat {|^(data_?|aria_?)(.+)|}) name with
| None ->
if name.[0] == '_'
(* need to keep the leading underscore, as that's what the syntax support keys
off of to know to use Unsafe.string_attrib *)
then "_" ^ kebab @@ String.sub name 1 (String.length name - 1)
else name
| Some g ->
let prefix = String.sub name 0 4 in
let suffix = kebab @@ Group.get g 2 in
prefix ^ (if suffix.[0] == '-' then "" else "-") ^ suffix

let make_attr_name name =
let name =
Expand Down
17 changes: 16 additions & 1 deletion test/test_jsx.re
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,22 @@ let attribs = (
[<script type_="text/javascript" />],
[script(~a=[a_script_type(`Mime("text/javascript"))], txt(""))],
),
],
( "camel-case data attribs",
[<div dataFooBar="baz"/>],
// the Xml.W.nil is here to satisfy the internal structure of what the jsx ppx produces
[div(~a=[a_user_data("foo-bar", "baz")], Xml.W.nil ())],
),
( "kebab-case data attribs",
[<div data_foo_bar="baz"/>],
// the Xml.W.nil is here to satisfy the internal structure of what the jsx ppx produces
[div(~a=[a_user_data("foo-bar", "baz")], Xml.W.nil ())],
),
( "kebab-case data attribs, again",
[<div datafoo_bar="baz"/>],
// the Xml.W.nil is here to satisfy the internal structure of what the jsx ppx produces
[div(~a=[a_user_data("foo-bar", "baz")], Xml.W.nil ())],
),
]
),
);

Expand Down

0 comments on commit 905fd4e

Please sign in to comment.