Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file css_gen.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598moduleStable=structopenCore_kernel.Core_kernel_stablemoduleV1=struct(** (field * value) list. Where value should be escaped / quoted
as necessary as per https://www.w3.org/TR/CSS21/syndata.html#rule-sets. *)typet=(string*string)list[@@derivingsexp,compare,bin_io]endendopenCore_kernelincludeStable.V1letsanitize_sexps=Sexp.to_strings|>String.lowercase|>String.substr_replace_all~pattern:"_"~with_:"-";;typecss_global_values=[`Inherit|`Initial][@@derivingsexp,bin_io,compare]moduleColor=structmoduleT=structmoduleRGBA=structtypet={r:int;g:int;b:int;a:Percent.toption}[@@derivingsexp,bin_io,compare,fields]letcreate~r~g~b?a()={r;g;b;a}endtypet=[`RGBAofRGBA.t|`Nameofstring|css_global_values][@@derivingsexp,bin_io,compare]endincludeTincludeSexpable.To_stringable(T)letto_string_css=function|#css_global_valuesasc->sexp_of_tc|>sanitize_sexp|`RGBA{RGBA.r;g;b;a}->(matchawith|None->sprintf"rgb(%i,%i,%i)"rgb|Somep->sprintf"rgba(%i,%i,%i,%.2f)"rgb(Percent.to_multp))|`Namename->name;;endmoduleAlignment=structtypet=[`Left|`Right|`Center(* horizontal *)|`Top|`Bottom|`Middle(* vertical *)|`Justify(* text-align (in addition to [horizontal]) *)|css_global_values][@@derivingsexp,bin_io,compare]includeSexpable.To_stringable(structtypenonrect=t[@@derivingsexp]end)letto_string_css=Fn.composesanitize_sexpsexp_of_tendmoduleLength=structtypet=[`Choffloat|`Remoffloat|`Emofint|`PercentofPercent.t|`Ptoffloat|`Pxofint|`VhofPercent.t|`VwofPercent.t|css_global_values][@@derivingsexp,bin_io,compare]letto_string_css=function|`Chc->sprintf"%.2fch"c|`Remf->sprintf"%.2frem"f|`Emi->sprintf"%iem"i|`Percentp->sprintf"%.2f%%"(Percent.to_percentagep)|`Ptp->sprintf"%.2fpt"p|`Pxi->sprintf"%ipx"i|`Vhp->sprintf"%.2fvh"(Percent.to_percentagep)|`Vwp->sprintf"%.2fvw"(Percent.to_percentagep)|#css_global_valuesasl->sexp_of_css_global_valuesl|>sanitize_sexp;;letpercent100=`Percent(Percent.of_percentage100.)endmoduleAuto_or_length=structtypet=[`Auto|Length.t][@@derivingbin_io,compare,sexp]letto_string_css=function|`Auto->"auto"|#Length.tasl->Length.to_string_cssl;;endletvalue_mapo~f=Option.value_mapo~default:""~fletcombinet1t2=t1@t2let(@>)=combineletconcatl=List.concatlletto_string_list=Fn.idletto_string_csst=List.mapt~f:(fun(field,value)->sprintf"%s: %s"fieldvalue)|>String.concat~sep:";";;letof_string_css_exns=Css_parser.parse_declaration_lists|>Or_error.ok_exn(** create_raw creates a single field, value pair. It assumes that the value is a valid
css value. As such it is unsafe to use with arbitrary value strings. But for the
vast majority of combinators in this module it is the right thing to use, as we know
by construction that the values do not need quoting / escaping. *)letcreate_raw~field~value=[field,value]letcreate~field~value=Css_parser.validate_valuevalue|>Or_error.ok_exn;create_raw~field~value;;letempty=[]letis_empty=List.is_emptyletcreate_placementnamelength=create~field:name~value:(Length.to_string_csslength);;letleft=create_placement"left"lettop=create_placement"top"letbottom=create_placement"bottom"letright=create_placement"right"letposition?top:tp?bottom:bt?left:lt?right:rtpos=letpos=letvalue=matchposwith|`Static->"static"|`Absolute->"absolute"|`Sticky->"sticky"|`Relative->"relative"|`Fixed->"fixed"increate~field:"position"~valueinletconvertopt_lf=Option.value_mapopt_l~default:empty~finconcat[pos;converttptop;convertltleft;convertrtright;convertbtbottom];;letbox_sizingv=letvalue=[%sexp_of:[`Content_box|`Border_box|css_global_values]]v|>sanitize_sexpincreate_raw~field:"box-sizing"~value;;letdisplayv=letvalue=[%sexp_of:[`Inline|`Block|`Inline_block|`List_item|`Table|`Inline_table|`None|(* [ `Flex | `Inline_flex ] are intentionally left out of the mli to force the user
to use [flex_container] below *)`Flex|`Inline_flex|css_global_values]]v|>sanitize_sexpincreate_raw~field:"display"~value;;letvisibilityv=letvalue=[%sexp_of:[`Visible|`Hidden|`Collapse|css_global_values]]v|>sanitize_sexpincreate_raw~field:"visibility"~value;;typeoverflow=[`Visible|`Hidden|`Scroll|`Auto|css_global_values]letmake_overflowfieldv=letvalue=[%sexp_of:[`Visible|`Hidden|`Scroll|`Auto|css_global_values]]v|>sanitize_sexpincreate_raw~field~value;;letoverflow=make_overflow"overflow"letoverflow_x=make_overflow"overflow-x"letoverflow_y=make_overflow"overflow-y"letz_indexi=create_raw~field:"z-index"~value:(Int.to_stringi)letopacityi=create_raw~field:"opacity"~value:(Float.to_stringi)letcreate_length_fieldfieldl=create_raw~field~value:(Auto_or_length.to_string_cssl);;letwhite_spacev=letvalue=matchvwith|`Normal->"normal"|`Nowrap->"nowrap"|`Pre->"pre"|`Pre_line->"pre-line"|`Pre_wrap->"pre-wrap"|`Initial->"initial"|`Inherit->"inherit"increate~field:"white-space"~value;;typefont_style=[`Normal|`Italic|`Oblique|css_global_values]typefont_weight=[`Normal|`Bold|`Bolder|`Lighter|`Numberofint|css_global_values]typefont_variant=[`Normal|`Small_caps|css_global_values]letfont_size=create_length_field"font-size"letfont_familyl=create_raw~field:"font-family"~value:(String.concatl~sep:",")letfont_styles=letvalue=[%sexp_of:[`Normal|`Italic|`Oblique|css_global_values]]s|>sanitize_sexpincreate_raw~field:"font-style"~value;;letfont_weight=letmoduleStatic_weight=structtypet=[`Normal|`Bold|`Bolder|`Lighter|css_global_values][@@derivingsexp]endinfuns->letvalue=matchswith|`Numberi->Int.to_stringi|#Static_weight.tasx->Static_weight.sexp_of_tx|>sanitize_sexpincreate_raw~field:"font-weight"~value;;letbold=font_weight`Boldletfont_variants=letvalue=[%sexp_of:[`Normal|`Small_caps|css_global_values]]s|>sanitize_sexpincreate_raw~field:"font-variant"~value;;letfont~size~family?style?weight?variant()=[Some(font_sizesize);Some(font_familyfamily);Option.mapstyle~f:font_style;Option.mapweight~f:font_weight;Option.mapvariant~f:font_variant]|>List.filter_opt|>concat;;letcolorc=create_raw~field:"color"~value:(Color.to_string_cssc)letbackground_colorc=create_raw~field:"background-color"~value:(Color.to_string_cssc);;letcreate_alignmentfielda=create_raw~field~value:(Alignment.to_string_css(a:>Alignment.t));;lettext_align=create_alignment"text-align"lethorizontal_align=create_alignment"horizontal-align"letvertical_align=create_alignment"vertical-align"letfloatf=create_raw~field:"float"~value:([%sexp_of:[`None|`Left|`Right|css_global_values]]f|>sanitize_sexp);;letwidth=create_length_field"width"letmin_width=create_length_field"min-width"letmax_width=create_length_field"max-width"letheight=create_length_field"height"letmin_height=create_length_field"min-height"letmax_height=create_length_field"max-height"letpadding_top=create_length_field"padding-top"letpadding_bottom=create_length_field"padding-bottom"letpadding_left=create_length_field"padding-left"letpadding_right=create_length_field"padding-right"letpadding?top?bottom?left?right()=letm=Option.mapin[mtop~f:padding_top;mbottom~f:padding_bottom;mleft~f:padding_left;mright~f:padding_right]|>List.filter_opt|>concat;;letuniform_paddingl=padding~top:l~bottom:l~left:l~right:l()letmargin_top=create_length_field"margin-top"letmargin_bottom=create_length_field"margin-bottom"letmargin_left=create_length_field"margin-left"letmargin_right=create_length_field"margin-right"letmargin?top?bottom?left?right()=letm=Option.mapin[mtop~f:margin_top;mbottom~f:margin_bottom;mleft~f:margin_left;mright~f:margin_right]|>List.filter_opt|>concat;;letuniform_marginl=margin~top:l~bottom:l~left:l~right:l()typeborder_style=[`None|`Hidden|`Dotted|`Dashed|`Solid|`Double|`Groove|`Ridge|`Inset|`Outset|css_global_values][@@derivingsexp](** Concat 2 values with a space in between. If either is the empty string
don't put in unnecessary whitespace. *)letconcat2vv1v2=matchv1,v2with|"",x->x|x,""->x|x,y->x^" "^y;;(** Concat up to 3 values with spaces in between. *)letconcat3vv1v2v3=concat2v(concat2vv1v2)v3letborder_value?width?color~style()=letstyle=[%sexp_of:border_style]style|>sanitize_sexpinletwidth=value_mapwidth~f:Length.to_string_cssinletcolor=value_mapcolor~f:Color.to_string_cssinconcat3vwidthstylecolor;;letcreate_border?side()=letfield=matchsidewith|Some`Top->"border-top"|Some`Bottom->"border-bottom"|Some`Right->"border-right"|Some`Left->"border-left"|None->"border"infun?width?color~style()->create_raw~field~value:(border_value?width?color~style());;letborder_top=create_border~side:`Top()letborder_bottom=create_border~side:`Bottom()letborder_left=create_border~side:`Left()letborder_right=create_border~side:`Right()letborder=create_border()letoutline?width?color~style()=create_raw~field:"outline"~value:(border_value?width?color~style());;letborder_collapsev=letvalue=[%sexp_of:[`Separate|`Collapse|css_global_values]]v|>sanitize_sexpincreate_raw~field:"border-collapse"~value;;letborder_spacing=create_length_field"border-spacing"letborder_radiusl=create~field:"border-radius"~value:(Length.to_string_cssl)typetext_decoration_line=[`None|`Underline|`Overline|`Line_through|css_global_values][@@derivingsexp]typetext_decoration_style=[`Solid|`Double|`Dotted|`Dashed|`Wavy|css_global_values][@@derivingsexp]lettext_decoration?style?color~line()=letvalue=letline=List.mapline~f:(funl->[%sexp_of:text_decoration_line]l|>sanitize_sexp)|>String.concat~sep:" "inletstyle=value_mapstyle~f:(funs->[%sexp_of:text_decoration_style]s|>sanitize_sexp)inletcolor=value_mapcolor~f:Color.to_string_cssinconcat3vlinestylecolorincreate_raw~field:"text-decoration"~value;;typeitem_alignment=[`Auto|`Flex_start|`Flex_end|`Center|`Baseline|`Stretch]letitem_alignment_to_string_css=function|`Auto->"auto"|`Flex_start->"flex-start"|`Flex_end->"flex-end"|`Center->"center"|`Baseline->"baseline"|`Stretch->"stretch";;letflex_container?(inline=false)?(direction=`Row)?(wrap=`Nowrap)?align_items()=letdirection=[%sexp_of:[`Row|`Row_reverse|`Column|`Column_reverse]]direction|>sanitize_sexpinletwrap=[%sexp_of:[`Nowrap|`Wrap|`Wrap_reverse]]wrap|>sanitize_sexpinletalign_items=matchalign_itemswith|None->empty|Somea->create_raw~field:"align-items"~value:(item_alignment_to_string_cssa)inconcat[display(ifinlinethen`Inline_flexelse`Flex);create_raw~field:"flex-direction"~value:direction;create_raw~field:"flex-wrap"~value:wrap;align_items];;letflex_item?order?(basis=`Auto)?(shrink=1.)~grow()=letorder=Option.maporder~f:(funi->create_raw~field:"order"~value:(Int.to_stringi))|>Option.to_list|>List.joininletflex=letbasis=Auto_or_length.to_string_cssbasisincreate_raw~field:"flex"~value:(sprintf"%f %f %s"growshrinkbasis)inconcat[flex;order];;letalign_selfa=letvalue=item_alignment_to_string_cssaincreate_raw~field:"align-self"~value;;letanimation~name~duration?delay?direction?fill_mode?iter_count?timing_function()=letm=Option.mapinletspan_to_strings=sprintf"%.2fs"(Time_ns.Span.to_secs)inletdirection=mdirection~f:(fund->letvalue=d|>[%sexp_of:[`Normal|`Reverse|`Alternate|`Alternate_reverse|css_global_values]]|>sanitize_sexpincreate_raw~field:"animation-direction"~value)inletfill_mode=mfill_mode~f:(funf->letvalue=[%sexp_of:[`None|`Forwards|`Backwards|`Both|css_global_values]]f|>sanitize_sexpincreate_raw~field:"animation-fill-mode"~value)in[Some(create_raw~field:"animation-name"~value:name);Some(create_raw~field:"animation-duration"~value:(span_to_stringduration));mdelay~f:(funs->create_raw~field:"animation-delay"~value:(span_to_strings));miter_count~f:(funi->create_raw~field:"animation-iteration-count"~value:(Int.to_stringi));mtiming_function~f:(funvalue->create_raw~field:"animation-timing-function"~value);direction;fill_mode]|>List.filter_opt|>concat;;let%expect_test"to_string_css -> of_string_css_exn -> to_string_css"=lettcss=lets=to_string_csscssinlets2=to_string_css(of_string_css_exns)inprint_endlines;print_endlines2int(flex_item~grow:1.0()@>overflow`Scroll);t(flex_container~inline:true~direction:`Column()@>border~style:`Dashed());t(color(`RGBA(Color.RGBA.create~r:100~g:100~b:100())));t(create~field:"content"~value:{|";"|});[%expect{|
flex: 1.000000 1.000000 auto;overflow: scroll
flex: 1.000000 1.000000 auto;overflow: scroll
display: inline-flex;flex-direction: column;flex-wrap: nowrap;border: dashed
display: inline-flex;flex-direction: column;flex-wrap: nowrap;border: dashed
color: rgb(100,100,100)
color: rgb(100,100,100)
content: ";"
content: ";" |}];;