Source file merge_style.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
open StdLabels
open Css_parser.Types
let delim_coma = ( Component_value.Delim ","
, Common.location_none )
module MapRule = Map.Make(struct
type t = Component_value.t list
let compare =
Comparator.compare_list (fun l1 l2 ->
Comparator.component_value
(l1, Common.location_none)
(l2, Common.location_none)
)
end)
(** The type of the map contains both :
- The declaration inside the selector
- The selector Location
*)
type t = (Declaration_list.t * Location.t) list MapRule.t
type acc = Component_value.t list * Component_value.t list list
(** Group all the selectors together, using a given delimiter *)
let group_selector
: string -> Component_value.t with_loc list with_loc -> Component_value.t list list
= fun delim elems ->
let add_element
: acc -> Component_value.t with_loc -> acc
= fun (acc, prev) elem ->
match (fst elem) with
| Delim s when String.equal s delim -> [], (List.rev acc)::prev
| other -> other::acc, prev
in
let last, prev = List.fold_left
(fst elems)
~init:([], [])
~f:add_element in
(List.rev last)::prev
(** Add a new style in the map. *)
let add_style
: Style_rule.t -> t -> t
= fun {prelude; block; loc} map ->
List.fold_left (group_selector "," prelude)
~init:map
~f:(fun map group ->
MapRule.update group
(function
| None ->
Some [(block, loc)]
| Some tl ->
Some (Common.update_declarations (block, loc) tl))
map)
module ReversedMapRule = Map.Make(struct
type t = Declaration_list.t * Location.t
let compare l1 l2 =
Comparator.declaration_list
(fst l1)
(fst l2)
end)
type splitted_rules' = (Component_value.t list list) ReversedMapRule.t
(** Extract all the styles, and return them as a Rule.t sequence *)
let extract_style
: t -> Rule.t Seq.t
= fun map ->
let table:splitted_rules' =
MapRule.fold
(fun k values map' ->
List.fold_left values
~init:map'
~f:(fun map' (v, loc) ->
ReversedMapRule.update (v, loc)
(function
| None -> Some [k]
| Some tl -> Some (k::tl))
map' ))
map
ReversedMapRule.empty in
ReversedMapRule.to_seq table
|> Seq.map (fun ((block, loc), k) ->
let selectors =
List.fold_left k
~init:[]
~f:(fun acc v ->
let selectors = List.map
v
~f:(fun x -> x , Common.location_none) in
let tail = List.append selectors acc in
delim_coma::tail) in
let prelude =
match selectors with
| (Component_value.Delim ",", _)::tl ->
( tl
, Common.location_none)
| _->
( selectors
, Common.location_none )
in
Rule.Style_rule (Style_rule.{prelude; block; loc}))
let empty = MapRule.empty