Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
mincss
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Taddeüs Kroes
mincss
Commits
660009a0
Commit
660009a0
authored
Aug 10, 2015
by
Taddeüs Kroes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Changed the way shorthand generation works so that the result is closer to the source
parent
0ca0aa97
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
107 additions
and
100 deletions
+107
-100
README.md
README.md
+0
-2
shorthand.ml
shorthand.ml
+98
-86
util.ml
util.ml
+9
-12
No files found.
README.md
View file @
660009a0
...
...
@@ -120,5 +120,3 @@ TODO / bugs
generating the shortest possible representation of the resulting box model.
-
`border:none`
could be
`border:0`
, or in general any shorthand that has both
a
`style`
and
`width`
property should be transformed from
`none`
into
`0`
.
-
`padding: 0 !important`
is expanded to 4 directions because of the
`!important`
shorthand.ml
View file @
660009a0
...
...
@@ -4,10 +4,16 @@
open
Types
open
Util
module
SS
=
Set
.
Make
(
String
)
let
pattern
=
Str
.
regexp
(
"^
\\
(background
\\
|border
\\
|font
\\
|list-style"
^
"
\\
|outline
\\
|padding
\\
|margin
\\
)-
\\
(.*
\\
)$"
)
module
KM
=
Map
.
Make
(
struct
type
t
=
string
*
bool
let
compare
a
b
=
match
a
,
b
with
|
(
_
,
false
)
,
(
_
,
true
)
->
-
1
|
(
_
,
true
)
,
(
_
,
false
)
->
1
|
(
base_a
,
_
)
,
(
base_b
,
_
)
->
String
.
compare
base_a
base_b
end
)
let
order
=
function
|
"background"
->
[
"color"
;
"image"
;
"repeat"
;
"attachment"
;
"position-x"
;
...
...
@@ -20,74 +26,68 @@ let order = function
|
"padding"
->
[
"top"
;
"right"
;
"bottom"
;
"left"
]
|
_
->
failwith
"not a shorthand property"
let
rec
decls_mem
name
=
function
|
[]
->
false
|
(
nm
,
_
,
_
)
::
_
when
nm
=
name
->
true
|
_
::
tl
->
decls_mem
name
tl
(* find the value of the last declaration of some property (since the earlier
* values are overridden), unless an earlier !important value was found *)
let
decls_find
name
decls
=
let
rec
wrap
known
must_be_imp
=
function
|
[]
->
known
|
(
nm
,
value
,
false
)
::
tl
when
nm
=
name
&&
not
must_be_imp
->
wrap
(
Some
value
)
false
tl
|
(
nm
,
value
,
true
)
::
tl
when
nm
=
name
->
wrap
(
Some
value
)
true
tl
|
_
::
tl
->
wrap
known
must_be_imp
tl
in
match
wrap
None
false
decls
with
|
None
->
raise
Not_found
|
Some
value
->
value
let
fold_box_dims
=
function
|
[
top
;
right
;
bottom
;
left
]
when
top
=
bottom
&&
right
=
left
&&
top
=
right
->
[
top
]
|
[
top
;
right
;
bottom
;
left
]
when
top
=
bottom
&&
right
=
left
->
[
top
;
right
]
|
[
top
;
right
;
bottom
;
left
]
when
right
=
left
->
[
top
;
right
;
bottom
]
|
dims
->
dims
let
fold
base
decls
=
let
rec
filter
=
function
|
[]
->
[]
let
fold
group
base
=
let
group_mem
name
=
let
rec
mem
=
function
|
[]
->
false
|
(
nm
,
_
,
_
)
::
_
when
nm
=
name
->
true
|
_
::
tl
->
mem
tl
in
mem
group
in
(* `font-size` and `line-height` are slash-separated in `font` *)
|
"size"
::
tl
when
base
=
"font"
&&
decls_mem
"line-height"
decls
->
let
font_size
=
decls_find
"font-size"
decls
in
let
line_height
=
decls_find
"line-height"
decls
in
Nary
(
"/"
,
[
font_size
;
line_height
])
::
filter
tl
let
group_find
name
=
let
rec
wrap
known
=
function
|
[]
->
(
match
known
with
Some
value
->
value
|
None
->
raise
Not_found
)
|
(
nm
,
value
,
_
)
::
tl
when
nm
=
name
->
wrap
(
Some
value
)
tl
|
_
::
tl
->
wrap
known
tl
in
wrap
None
group
in
|
name
::
tl
when
decls_mem
(
base
^
"-"
^
name
)
decls
->
decls_find
(
base
^
"-"
^
name
)
decls
::
filter
tl
let
exists
sub
=
group_mem
(
base
^
"-"
^
sub
)
in
let
find
sub
=
group_find
(
base
^
"-"
^
sub
)
in
|
_
::
tl
->
filter
tl
let
rec
lookup
=
function
|
[]
->
[]
(* `font-size` and `line-height` are slash-separated in `font` *)
|
"size"
::
tl
when
base
=
"font"
&&
group_mem
"line-height"
->
Nary
(
"/"
,
[
find
"size"
;
group_find
"line-height"
])
::
lookup
tl
|
name
::
tl
when
exists
name
->
find
name
::
lookup
tl
|
_
::
tl
->
lookup
tl
in
filter
(
order
base
)
let
shorten_box_dims
=
function
|
[
top
;
right
;
bottom
;
left
]
when
top
=
bottom
&&
right
=
left
&&
top
=
right
->
[
top
]
|
[
top
;
right
;
bottom
;
left
]
when
top
=
bottom
&&
right
=
left
->
[
top
;
right
]
|
[
top
;
right
;
bottom
;
left
]
when
right
=
left
->
[
top
;
right
;
bottom
]
|
dims
->
dims
match
base
with
let
shorten
decls
=
function
(* `font-size` and `font-family` are required for `font` *)
|
"font"
when
decls_mem
"font-size"
decls
&&
decls_mem
"font-family"
decls
->
Some
(
Concat
(
fold
"font"
decls
))
|
"font"
when
exists
"size"
&&
exists
"family"
->
Some
(
Concat
(
lookup
(
order
"font"
)
))
(* `border-style` is required for `border` *)
|
"border"
when
decls_mem
"border-style"
decls
->
Some
(
Concat
(
fold
"border"
decls
))
|
"border"
when
exists
"style"
->
Some
(
Concat
(
lookup
(
order
"border"
)
))
(* others require at least one property, which is
the case when this function
* is called *)
(* others require at least one property, which is
already the case when this
*
function
is called *)
|
(
"background"
|
"list-style"
|
"outline"
)
as
base
->
Some
(
Concat
(
fold
base
decls
))
Some
(
Concat
(
lookup
(
order
base
)
))
(* margin and padding can only be shorthanded when all directions are known,
* merging into even shorter shorthands is done by `shorten_box_dims` *)
|
(
"margin"
|
"padding"
)
as
base
when
let
has
dir
=
decls_mem
(
base
^
"-"
^
dir
)
decls
in
has
"top"
&&
has
"right"
&&
has
"bottom"
&&
has
"left"
->
let
get
dir
=
decls_find
(
base
^
"-"
^
dir
)
decls
in
Some
(
Concat
(
shorten_box_dims
[
get
"top"
;
get
"right"
;
get
"bottom"
;
get
"left"
]))
* merging into even shorter shorthands is done by `fold_box_dims` *)
|
"margin"
|
"padding"
when
exists
"top"
&&
exists
"right"
&&
exists
"bottom"
&&
exists
"left"
->
let
dirs
=
[
find
"top"
;
find
"right"
;
find
"bottom"
;
find
"left"
]
in
Some
(
Concat
(
fold_box_dims
dirs
))
|
_
->
None
...
...
@@ -234,45 +234,57 @@ let rec unfold = function
|
hd
::
tl
->
hd
::
unfold
tl
let
make_shorthands
decls
=
let
pattern
=
Str
.
regexp
(
"^
\\
(background
\\
|border
\\
|font
\\
|list-style"
^
"
\\
|outline
\\
|padding
\\
|margin
\\
)-
\\
(.*
\\
)$"
)
let
rec
make_shorthands
decls
=
(* unfold currently existing shorthands into separate properties for merging
* with override properties that are defined later on *)
(*let decls = unfold decls in
XXX: done by main function for correct pruning of duplicate declarations*)
(* find shorthand names for which properties are present *)
let
rec
find_props
=
function
|
[]
->
SS
.
empty
|
(
name
,
value
,
false
)
::
tl
when
Str
.
string_match
pattern
name
0
->
let
rec
extract_groups
decl_skipped
groups
rest
=
let
rec
find_in_group
name
=
function
|
[]
->
false
|
(
nm
,
_
,
_
)
::
_
when
nm
=
name
->
true
|
_
::
tl
->
find_in_group
name
tl
in
let
should_skip
base
name
imp
=
try
find_in_group
name
(
KM
.
find
(
base
,
imp
)
groups
)
with
Not_found
->
false
in
let
add
base
imp
value
=
let
key
=
base
,
imp
in
let
group
=
try
KM
.
find
key
groups
with
Not_found
->
[]
in
KM
.
add
key
(
value
::
group
)
groups
in
function
|
[]
->
decl_skipped
,
groups
,
rest
|
((
"line-height"
,
_
,
imp
)
as
hd
)
::
tl
when
should_skip
"font"
"line_height"
imp
->
extract_groups
true
groups
(
hd
::
rest
)
tl
|
((
"line-height"
,
_
,
imp
)
as
hd
)
::
tl
->
extract_groups
decl_skipped
(
add
"font"
imp
hd
)
rest
tl
|
((
name
,
_
,
imp
)
as
hd
)
::
tl
when
Str
.
string_match
pattern
name
0
->
let
base
=
Str
.
matched_group
1
name
in
let
sub
=
Str
.
matched_group
2
name
in
if
List
.
mem
sub
(
order
base
)
then
SS
.
add
base
(
find_props
tl
)
else
find_props
tl
|
_
::
tl
->
find_props
tl
let
skip_this
=
should_skip
base
name
imp
in
if
not
skip_this
&&
List
.
mem
sub
(
order
base
)
then
extract_groups
decl_skipped
(
add
base
imp
hd
)
rest
tl
else
extract_groups
(
decl_skipped
||
skip_this
)
groups
(
hd
::
rest
)
tl
|
hd
::
tl
->
extract_groups
decl_skipped
groups
(
hd
::
rest
)
tl
in
let
try_shorthands
=
find_props
decls
in
let
decl_skipped
,
groups
,
rest
=
extract_groups
false
KM
.
empty
[]
decls
in
(* try to generate shorthands for the matched base properties *)
let
rec
replace
base
tl
=
match
shorten
decls
base
with
|
None
->
tl
|
Some
short_value
->
(
base
,
short_value
,
false
)
::
tl
let
replace
(
base
,
important
)
group
tl
=
match
fold
(
List
.
rev
group
)
base
with
|
Some
short_value
->
(
base
,
short_value
,
important
)
::
tl
|
None
->
group
@
tl
in
let
shorthands
=
SS
.
fold
replace
try_shorthands
[]
in
(* filter out the original, partial properties, and append the shorthands *)
let
keep_prop
=
function
|
(
"line-height"
,
_
,
_
)
->
not
(
decls_mem
"font"
shorthands
)
|
(
name
,
_
,
important
)
->
important
||
not
(
Str
.
string_match
pattern
name
0
)
||
let
base
=
Str
.
matched_group
1
name
in
let
sub
=
Str
.
matched_group
2
name
in
not
(
List
.
mem
sub
(
order
base
))
||
not
(
decls_mem
base
shorthands
)
in
List
.
filter
keep_prop
decls
@
shorthands
let
shorthands
=
KM
.
fold
replace
groups
[]
in
let
decls
=
List
.
rev_append
rest
shorthands
in
if
decl_skipped
then
make_shorthands
decls
else
decls
let
compress
=
Util
.
transform_stylesheet
begin
function
...
...
util.ml
View file @
660009a0
...
...
@@ -254,18 +254,15 @@ let sort_stylesheet =
in
let
rec
cmp
a
b
=
match
split
a
,
split
b
with
|
Some
(
stem_a
,
tail_a
)
,
Some
(
stem_b
,
tail_b
)
->
begin
match
String
.
compare
stem_a
stem_b
with
|
0
->
cmp
tail_a
tail_b
|
n
->
n
end
|
Some
(
stem_a
,
tail_a
)
,
None
->
String
.
compare
stem_a
b
|
None
,
Some
(
stem_b
,
tail_b
)
->
String
.
compare
a
stem_b
|
None
,
None
->
String
.
compare
a
b
|
Some
(
base_a
,
sub_a
)
,
Some
(
base_b
,
sub_b
)
when
base_a
=
base_b
->
cmp
sub_a
sub_b
|
Some
(
base_a
,
_
)
,
Some
(
base_b
,
_
)
->
String
.
compare
base_a
base_b
|
Some
(
base_a
,
_
)
,
None
when
base_a
=
b
->
1
|
Some
(
base_a
,
_
)
,
None
->
String
.
compare
base_a
b
|
None
,
Some
(
base_b
,
_
)
when
a
=
base_b
->
-
1
|
None
,
Some
(
base_b
,
_
)
->
String
.
compare
a
base_b
|
None
,
None
->
String
.
compare
a
b
in
let
cmp_decls
(
a
,
_
,
_
)
(
b
,
_
,
_
)
=
cmp
a
b
in
Statement
(
Ruleset
(
selectors
,
List
.
stable_sort
cmp_decls
decls
))
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment