* Merges properties inside merged selectors too.
* Adds merging two adjacent properties when merging selectors.
* Adds CSS tokenizer which will make it possible to optimize content by reordering and/or merging selectors.
* Adds basic optimizer removing duplicate selectors from a list.
* Adds merging duplicate properties within a single selector's body.
+* Adds merging adjacent selectors within a scope (single and multiple ones).
1.1.7 / 2013-10-28
==================
return plain.join(',');
};
- var mergeProperties = function(body) {
+ var mergeProperties = function(body, allowAdjacent) {
var merged = [];
var properties = [];
var flat = [];
// comment is necessary - we assume that if two keys are one after another
// then it is intentional way of redefining property which may not be widely supported
- if (alreadyIn > -1 && lastKey != key) {
+ // however if `allowAdjacent` is set then the rule does not apply (see merging two adjacent selectors)
+ if (alreadyIn > -1 && (allowAdjacent || lastKey != key)) {
merged.splice(alreadyIn, 1);
properties.splice(alreadyIn, 1);
}
}
};
+ var mergeAdjacent = function(tokens) {
+ var forMerging = [];
+ var lastSelector = null;
+
+ for (var i = 0, l = tokens.length; i < l; i++) {
+ if (typeof(tokens[i]) == 'string' || tokens[i].block)
+ continue;
+
+ var selector = tokens[i].selector;
+ if (lastSelector == selector)
+ forMerging.push(i);
+
+ lastSelector = selector;
+ }
+
+ for (var j = 0, m = forMerging.length; j < m; j++) {
+ var position = forMerging[j] - j;
+ tokens[position - 1].body = mergeProperties(tokens[position - 1].body + ';' + tokens[position].body, true);
+ tokens.splice(position, 1);
+ }
+ };
+
var optimize = function(tokens) {
tokens = (Array.isArray(tokens) ? tokens : [tokens]);
for (var i = 0, l = tokens.length; i < l; i++) {
if (token.selector) {
token.selector = stripRepeats(token.selector);
- token.body = mergeProperties(token.body);
+ token.body = mergeProperties(token.body, false);
} else if (token.block) {
optimize(token.body);
}
}
removeDuplicates(tokens);
+ mergeAdjacent(tokens);
};
var rebuild = function(tokens) {
.fleuve .urgent .grid_1 .tt13_capital{padding:0 0 10px;border-bottom:1px solid #cb2626}
.fleuve .conteneur_fleuve{background:#fff;margin-left:0;padding:0;width:605px}
.fleuve .urgent .conteneur_fleuve{padding-top:10px}
-.fleuve .jour_parution{background:#fff}
-.fleuve .jour_parution{display:block;padding:0 0 20px;color:#2e3942;text-transform:uppercase;font-weight:700}
+.fleuve .jour_parution{background:#fff;display:block;padding:0 0 20px;color:#2e3942;text-transform:uppercase;font-weight:700}
.fleuve .atome{margin:0 0 10px}
.fleuve .liens{margin:16px 0 0;color:#a2a9ae}
.fleuve .liens>span:first-child{float:left}
#header .acces_compte .avatar_nom{height:26px;margin:3px 0 0;background-color:#fafafa;background-image:-webkit-gradient(linear,0 0,0 100%,from(#fefefe),color-stop(25%,#fefefe),to(#e4e6e9));background-image:-webkit-linear-gradient(#fefefe,#fefefe 25%,#e4e6e9);background-image:-moz-linear-gradient(top,#fefefe,#fefefe 25%,#e4e6e9);background-image:-ms-linear-gradient(#fefefe,#fefefe 25%,#e4e6e9);background-image:-o-linear-gradient(#fefefe,#fefefe 25%,#e4e6e9);background-image:linear-gradient(#fefefe,#fefefe 25%,#e4e6e9);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e4e6e9', GradientType=0);border:1px solid #d2d6db;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}
#header .acces_compte .avatar_nom span{display:block;height:26px;line-height:26px;float:left}
#header .acces_compte .avatar{width:28px;border-right:1px solid #d2d6db}
-#header .acces_compte .avatar img{display:block;margin:4px auto 0}
-#header .acces_compte .avatar img{vertical-align:middle}
+#header .acces_compte .avatar img{display:block;margin:4px auto 0;vertical-align:middle}
#header .acces_compte .nom{padding:0 16px;border-right:1px solid #d2d6db;border-left:1px solid #fff}
#header .acces_compte .fle{width:28px;background:url(/medias/web/img/pictos/fle_bas_noir7x4.png) no-repeat 50% 50%}
#header .acces_compte ul{position:absolute;right:0;top:29px;width:98%;background:#fff;list-style-type:none;text-align:left;display:none;border:1px solid #d2d6db;border-radius:0 0 3px 3px}
.col_droite .bloc_element .ligne_titre{display:block;overflow:hidden;position:relative;border-top:3px solid #16212c;border-bottom:1px solid #eef1f5;border-left:1px solid #eef1f5;background:#e9ecf0}
.col_droite .bloc_element .titre{float:left;width:238px;padding:8px 16px 6px;border-right:1px solid #fff;background:#fafbfc}
.col_droite .bloc_element .element:hover .titre{background:#e9ecf0}
-.col_droite .bloc_element .fleche{display:block;float:right;width:42px;border-left:1px solid #e4e6e9}
-.col_droite .bloc_element .fleche{position:absolute;right:13px;top:33%;background:url(/medias/web/img/sprites/icos_petites.png) no-repeat -1px -108px;width:13px;height:22px}
+.col_droite .bloc_element .fleche{display:block;float:right;border-left:1px solid #e4e6e9;position:absolute;right:13px;top:33%;background:url(/medias/web/img/sprites/icos_petites.png) no-repeat -1px -108px;width:13px;height:22px}
.col_droite .bloc_element .element:hover .fleche{background-position:-15px -108px}
.contenu_bloc_droit{padding:7px 16px 10px;overflow:hidden}
.contenu_bloc_droit .liste_chevron li{padding:8px 0 6px}
#core-liberation ul.list-items li.arround h5,#core-liberation ul.list-items li.arround h4,#core-liberation ul.list-items li.arround p{margin-left:0}
#core-liberation ul.list-items li.chat p{display:block;clear:both;margin-left:0}
#core-liberation ul.list-items li.chat h5{margin-bottom:5px}
-#core-liberation ul.list-items-mosts li{margin-bottom:5px}
-#core-liberation ul.list-items-mosts li{font-family:Georgia,"Times New Roman",Times,serif}
+#core-liberation ul.list-items-mosts li{margin-bottom:5px;font-family:Georgia,"Times New Roman",Times,serif}
#core-liberation ul.list-rss-stream{list-style:none}
#core-liberation ul.list-rss-stream li{list-style:none;margin-bottom:20px}
#core-liberation ul.list-rss-stream li h5{margin-bottom:7px;font-weight:400;text-decoration:underline}
#core-liberation .bg-sprites-icons .arrow-grey-l,#core-liberation .bg-sprites-icons .arrow-grey-b{display:block;background-image:url(http://s0.libe.com/libe/img/common/_sprites_icons/icons.png?9914d0d70a49);background-repeat:no-repeat}
#core-liberation .bg-sprites-icons .arrow-grey-l{background-position:0 -66px;width:6px;height:8px}
#core-liberation .bg-sprites-icons .arrow-grey-b{background-position:0 -75px;width:8px;height:7px}
-#core-liberation .bg-sprites-icons .community-bubble{display:block;background-image:url(http://s0.libe.com/libe/img/common/_sprites_icons/icons.png?9914d0d70a49);background-repeat:no-repeat}
-#core-liberation .bg-sprites-icons .community-bubble{background-position:0 -36px;width:21px;height:18px}
+#core-liberation .bg-sprites-icons .community-bubble{display:block;background-image:url(http://s0.libe.com/libe/img/common/_sprites_icons/icons.png?9914d0d70a49);background-repeat:no-repeat;background-position:0 -36px;width:21px;height:18px}
.site-liberation .toolbox{border-top:1px solid;border-bottom:1px solid;display:block;height:30px;letter-spacing:-1px}
.site-liberation .toolbox li{float:left;display:block;margin:0 4px;height:30px}
#core-liberation .toolbox>li:first-child{margin-left:0}
#bar-liberation .content .login a.subscribe{position:absolute;display:block;top:10px;right:230px;padding:3px 10px;border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px}
#bar-liberation .content .login a.subscribe:hover{text-decoration:none}
#bar-liberation .content .login span{position:absolute;display:block;top:13px;right:205px}
-#bar-liberation .content .login a.connect{position:absolute;display:block;top:13px;right:120px}
-#bar-liberation .content .login a.connect{font-weight:700}
+#bar-liberation .content .login a.connect{position:absolute;display:block;top:13px;right:120px;font-weight:700}
#bar-liberation #login-box-content{display:none;position:absolute;border-left:1px solid;border-right:1px solid;border-bottom:1px solid;top:40px;right:0;z-index:10025;width:184px;padding:10px}
#bar-liberation #login-box-content form ul li{margin-bottom:10px;clear:both}
#bar-liberation #login-box-content form label{display:block;float:left;width:150px;margin-bottom:3px}
'a{background:url(/images/blank.png) 0 0 no-repeat}'
],
'strip more': [
- 'a{background:url("/images/blank.png") 0 0 no-repeat}a{display:block}a{background:url("/images/blank2.png") 0 0 no-repeat}',
- 'a{background:url(/images/blank.png) 0 0 no-repeat}a{display:block}a{background:url(/images/blank2.png) 0 0 no-repeat}'
+ 'a{background:url("/images/blank.png") 0 0 no-repeat}b{display:block}a{background:url("/images/blank2.png") 0 0 no-repeat}',
+ 'a{background:url(/images/blank.png) 0 0 no-repeat}b{display:block}a{background:url(/images/blank2.png) 0 0 no-repeat}'
],
'not strip comments if spaces inside': [
- 'a{background:url("/images/long image name.png") 0 0 no-repeat}a{display:block}a{background:url("/images/no-spaces.png") 0 0 no-repeat}',
- 'a{background:url("/images/long image name.png") 0 0 no-repeat}a{display:block}a{background:url(/images/no-spaces.png) 0 0 no-repeat}'
+ 'a{background:url("/images/long image name.png") 0 0 no-repeat}b{display:block}a{background:url("/images/no-spaces.png") 0 0 no-repeat}',
+ 'a{background:url("/images/long image name.png") 0 0 no-repeat}b{display:block}a{background:url(/images/no-spaces.png) 0 0 no-repeat}'
],
'not add a space before url\'s hash': "a{background:url(/fonts/d90b3358-e1e2-4abb-ba96-356983a54c22.svg#d90b3358-e1e2-4abb-ba96-356983a54c22)}",
'keep urls from being stripped down #1': 'a{background:url(/image-1.0.png)}',
],
'of two successive selectors with different body': [
'a{color:red}a{display:block}',
- 'a{color:red}a{display:block}'
+ 'a{color:red;display:block}'
],
'of many successive selectors': [
'a{color:red}a{color:red}a{color:red}a{color:red}',
'a{display:inline-block;color:red;font-weight:bolder;font-weight:700;display:block!important;color:#fff}',
'a{font-weight:bolder;font-weight:700;display:block!important;color:#fff}'
]
+ }),
+ 'same selectors': cssContext({
+ 'of two non-adjacent selectors': '.one{color:red}.two{color:#00f}.one{font-weight:700}',
+ 'of two adjacent single selectors': [
+ '.one{color:red}.one{font-weight:700}',
+ '.one{color:red;font-weight:700}'
+ ],
+ 'of three adjacent single selectors': [
+ '.one{color:red}.one{font-weight:700}.one{font-size:12px}',
+ '.one{color:red;font-weight:700;font-size:12px}'
+ ],
+ 'of two adjacent single, complex selectors': [
+ '#box>.one{color:red}#box>.one{font-weight:700}',
+ '#box>.one{color:red;font-weight:700}'
+ ],
+ 'of two adjacent multiple, complex selectors': [
+ '.zero,#box>.one{color:red}.zero,#box>.one{font-weight:700}',
+ '.zero,#box>.one{color:red;font-weight:700}'
+ ],
+ 'of two adjacent selectors with duplicate properties #1': [
+ '.one{color:red}.one{color:#fff}',
+ '.one{color:#fff}'
+ ],
+ 'of two adjacent selectors with duplicate properties #2': [
+ '.one{color:red;font-weight:bold}.one{color:#fff;font-weight:400}',
+ '.one{color:#fff;font-weight:400}'
+ ]
})
}).export(module);