From: Jakub Pawlowicz Date: Mon, 17 Aug 2015 06:31:53 +0000 (+0100) Subject: Fixes #607 - adds better rule reordering. X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=085835daf114629c8dcc420889b0cd27197f33f7;p=clean-css.git Fixes #607 - adds better rule reordering. Apparently IDs coupled with tag selectors are safe for reordering too. --- diff --git a/History.md b/History.md index fff1111b..61c53e61 100644 --- a/History.md +++ b/History.md @@ -5,6 +5,7 @@ * Adds inferring proxy settings from HTTP_PROXY environment variable. * Unifies wrappers for simple & advanced optimizations. * Fixed issue [#599](https://github.com/jakubpawlowicz/clean-css/issues/599) - support for inlined source maps. +* Fixed issue [#607](https://github.com/jakubpawlowicz/clean-css/issues/607) - adds better rule reordering. * Fixed issue [#612](https://github.com/jakubpawlowicz/clean-css/issues/612) - adds HTTP proxy support. * Fixed issue [#618](https://github.com/jakubpawlowicz/clean-css/issues/618) - adds safer function validation. * Fixed issue [#625](https://github.com/jakubpawlowicz/clean-css/issues/625) - adds length unit optimizations. diff --git a/lib/selectors/extractor.js b/lib/selectors/extractor.js index 72cafca5..df62e0ea 100644 --- a/lib/selectors/extractor.js +++ b/lib/selectors/extractor.js @@ -11,7 +11,7 @@ function extract(token) { var properties = []; if (token[0] == 'selector') { - var inSimpleSelector = !/[\.\+#>~\s]/.test(stringifySelectors(token[1])); + var inSpecificSelector = !/[\.\+>~]/.test(stringifySelectors(token[1])); for (var i = 0, l = token[2].length; i < l; i++) { var property = token[2][i]; @@ -34,7 +34,7 @@ function extract(token) { token[2][i], name + ':' + value, token[1], - inSimpleSelector + inSpecificSelector ]); } } else if (token[0] == 'block') { diff --git a/lib/selectors/reorderable.js b/lib/selectors/reorderable.js index bae11437..2f44eb75 100644 --- a/lib/selectors/reorderable.js +++ b/lib/selectors/reorderable.js @@ -19,12 +19,12 @@ function canReorderSingle(left, right) { var leftValue = left[1]; var leftNameRoot = left[2]; var leftSelector = left[5]; - var leftInSimpleSelector = left[6]; + var leftInSpecificSelector = left[6]; var rightName = right[0]; var rightValue = right[1]; var rightNameRoot = right[2]; var rightSelector = right[5]; - var rightInSimpleSelector = right[6]; + var rightInSpecificSelector = right[6]; if (leftName == 'font' && rightName == 'line-height' || rightName == 'font' && leftName == 'line-height') return false; @@ -44,7 +44,7 @@ function canReorderSingle(left, right) { return true; if (leftName != rightName && leftNameRoot == rightNameRoot && leftValue == rightValue) return true; - if (rightInSimpleSelector && leftInSimpleSelector && selectorsDoNotOverlap(rightSelector, leftSelector)) + if (rightInSpecificSelector && leftInSpecificSelector && selectorsDoNotOverlap(rightSelector, leftSelector)) return true; return false; diff --git a/test/fixtures/big-min.css b/test/fixtures/big-min.css index 26a13412..6f6dd1e3 100644 --- a/test/fixtures/big-min.css +++ b/test/fixtures/big-min.css @@ -2274,6 +2274,7 @@ form .btn-rounded-degraded input[type=button],form .btn-rounded-degraded input[t #core-liberation .toolbox li.spacer span{display:block;width:1px;height:20px;margin-top:5px} #core-liberation .toolbox .txt-min,#core-liberation .toolbox .txt-plus{display:block;font-size:15px;padding-top:4px} #core-liberation .toolbox .txt-reset{display:block;font-family:"Times New Roman",Times,Georgia,serif;font-size:19px;padding:4px 0 0 3px} +#page-mailfriend,#page-paywall{font-family:Verdana,sans-serif} .site-liberation .toolbox li a span{display:block} .site-liberation .toolbox li a.print span{margin-top:7px;width:1pc;height:1pc} .site-liberation .toolbox li a.favorite span{margin-top:5px;width:20px;height:18px} @@ -2300,7 +2301,6 @@ form .btn-rounded-degraded input[type=button],form .btn-rounded-degraded input[t #core-liberation .sb-podcasts ul li a.itunes{background-position:-267px 0;width:50px} #core-liberation .sb-podcasts ul li a.xml{background-position:-322px 0;width:41px} #bar-liberation{display:block;position:fixed;top:0;left:0;z-index:10000;width:100%;height:40px;border-bottom:1px solid;font-family:Arial,Verdana,sans-serif;font-size:9pt;line-height:14px} -#page-mailfriend,#page-paywall{font-family:Verdana,sans-serif} body.init-bar-is-closed #bar-liberation{height:15px} #bar-liberation a,#bar-liberation a p{text-decoration:none;outline:0} #bar-liberation .content{position:relative;margin:auto;height:40px;width:801pt} @@ -2868,13 +2868,13 @@ body.slideshow .ad-top .megaban{background:#333} #bar-liberation{background-color:#fff;box-shadow:0 1px 2px 0 #E2E2E2;-webkit-box-shadow:0 1px 2px 0 #E2E2E2;-moz-box-shadow:0 1px 2px 0 #E2E2E2} #bar-liberation,#bar-liberation a{color:#3c3c3c} #bar-liberation .content .activities-stream,#bar-liberation .content .close,#bar-liberation .content .login,#bar-liberation .content .mail-box,#bar-liberation .content .open,#bar-liberation .content .other,#bar-liberation .content .personal-options{background:#fff;border-left-color:#dadada;border-right-color:#dadada;border-bottom-color:#dadada} +#bar-liberation #personal-options-content,#bar-liberation .content .open a .arrow{border-left-color:1px solid #dadada;border-right-color:1px solid #dadada} #bar-liberation .content ul.list li,#bar-liberation .content ul.list li a,#core-liberation .block-activities .block-content ul li,#core-liberation .block-activities .block-content ul li a{color:#222} #bar-liberation .content ul.list li span,#core-liberation .block-activities .block-content ul li span{color:#878787} -#bar-liberation .content .open a .arrow{border-left-color:1px solid #dadada;border-right-color:1px solid #dadada} #bar-liberation .content .login a.subscribe{background-color:#656565;color:#fff} #bar-liberation .content .login a.subscribe:hover{background-color:#3c3c3c} #bar-liberation #login-box-content{background-color:#fff;border-left-color:#dadada;border-right-color:#dadada;box-shadow:0 1px 1px 0 #E2E2E2;-webkit-box-shadow:0 1px 1px 0 #E2E2E2;-moz-box-shadow:0 1px 1px 0 #E2E2E2} -#bar-liberation #personal-options-content{background-color:#fff;border-left-color:1px solid #dadada;border-right-color:1px solid #dadada;border-bottom-color:1px solid #dadada;box-shadow:0 1px 1px 0 #E2E2E2;-webkit-box-shadow:0 1px 1px 0 #E2E2E2;-moz-box-shadow:0 1px 1px 0 #E2E2E2} +#bar-liberation #personal-options-content{background-color:#fff;border-bottom-color:1px solid #dadada;box-shadow:0 1px 1px 0 #E2E2E2;-webkit-box-shadow:0 1px 1px 0 #E2E2E2;-moz-box-shadow:0 1px 1px 0 #E2E2E2} #bar-liberation #personal-options-content ul.subscription li.subscribe,#bar-liberation #personal-options-content ul.subscription li.subscribe a,#bar-liberation #personal-options-content ul.subscription strong{color:#a40000} #bar-liberation #personal-options-content ul li{color:#878787} #bar-liberation #personal-options-content ul li a,#bar-liberation #personal-options-content ul li strong{color:#3c3c3c} diff --git a/test/fixtures/blueprint-min.css b/test/fixtures/blueprint-min.css index 2768bd72..1d4d082b 100644 --- a/test/fixtures/blueprint-min.css +++ b/test/fixtures/blueprint-min.css @@ -1,6 +1,6 @@ -h1,h3{line-height:1} +h1 img,h2 img,h3 img,h4 img,h5 img,h6 img,html{margin:0} .clear,hr{clear:both} -html{margin:0;padding:0;border:0;font-size:100.01%} +html{padding:0;border:0;font-size:100.01%} a,abbr,acronym,address,article,aside,blockquote,body,caption,code,dd,del,dfn,dialog,div,dl,dt,em,fieldset,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,iframe,img,label,legend,li,nav,object,ol,p,pre,q,section,span,table,tbody,td,tfoot,th,thead,tr,ul{margin:0;padding:0;border:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline} address,blockquote,dfn,em,tfoot{font-style:italic} h5,h6{font-size:1em;font-weight:700} @@ -13,17 +13,17 @@ blockquote,q{quotes:"" ""} a img{border:none} :focus{outline:0} h1,h2,h3,h4,h5,h6{font-weight:400;color:#111} -h1{font-size:3em;margin-bottom:.5em} +h1{font-size:3em;line-height:1;margin-bottom:.5em} h2{font-size:2em;margin-bottom:.75em} -h3{font-size:1.5em;margin-bottom:1em} +h3{font-size:1.5em;line-height:1;margin-bottom:1em} h4{font-size:1.2em;line-height:1.25;margin-bottom:1.25em} h5{margin-bottom:1.5em} -h1 img,h2 img,h3 img,h4 img,h5 img,h6 img{margin:0} p{margin:0 0 1.5em} .left{float:left!important} p .left{margin:1.5em 1.5em 1.5em 0;padding:0} .right{float:right!important} p .right{margin:1.5em 0 1.5em 1.5em;padding:0} +address,dl{margin:0 0 1.5em} a:focus,a:hover{color:#09f} a{color:#06c;text-decoration:underline} .quiet,blockquote,del{color:#666} @@ -31,14 +31,12 @@ blockquote{margin:1.5em} dfn,dl dt,strong,th{font-weight:700} sub,sup{line-height:0} abbr,acronym{border-bottom:1px dotted #666} -address{margin:0 0 1.5em} pre{margin:1.5em 0;white-space:pre} code,pre,tt{font:1em 'andale mono','lucida console',monospace;line-height:1.5} li ol,li ul{margin:0} ol,ul{margin:0 1.5em 1.5em 0;padding-left:1.5em} ul{list-style-type:disc} ol{list-style-type:decimal} -dl{margin:0 0 1.5em} dd{margin-left:1.5em} table{border-collapse:separate;border-spacing:0;margin-bottom:1.4em;width:100%} thead th{background:#c3d9ff} diff --git a/test/fixtures/bootstrap-min.css b/test/fixtures/bootstrap-min.css index 1de385f4..5b914711 100644 --- a/test/fixtures/bootstrap-min.css +++ b/test/fixtures/bootstrap-min.css @@ -22,6 +22,7 @@ hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizin pre,textarea{overflow:auto} code,kbd,pre,samp{font-size:1em} button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit} +.glyphicon,address{font-style:normal} button{overflow:visible} button,select{text-transform:none} button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer} @@ -54,7 +55,7 @@ select{background:#fff!important} .btn,.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-warning.active,.btn-warning:active,.btn.active,.btn:active,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover,.form-control,.navbar-toggle,.open>.dropdown-toggle.btn-danger,.open>.dropdown-toggle.btn-default,.open>.dropdown-toggle.btn-info,.open>.dropdown-toggle.btn-primary,.open>.dropdown-toggle.btn-warning{background-image:none} .img-thumbnail,body{background-color:#fff} @font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')} -.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale} +.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale} .glyphicon-asterisk:before{content:"\2a"} .glyphicon-plus:before{content:"\2b"} .glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"} @@ -379,11 +380,11 @@ a.bg-danger:hover{background-color:#e4b9b9} pre code,table{background-color:transparent} .page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee} dl,ol,ul{margin-top:0} +blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child,ol ol,ol ul,ul ol,ul ul{margin-bottom:0} +address,dl{margin-bottom:20px} ol,ul{margin-bottom:10px} -ol ol,ol ul,ul ol,ul ul{margin-bottom:0} .list-inline{margin-left:-5px} .list-inline>li{display:inline-block;padding-right:5px;padding-left:5px} -dl{margin-bottom:20px} dd{margin-left:0} @media (min-width:768px){.dl-horizontal dt{float:left;width:10pc;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap} .dl-horizontal dd{margin-left:180px} @@ -392,21 +393,20 @@ dd{margin-left:0} abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777} .initialism{font-size:90%;text-transform:uppercase} blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee} -blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0} blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;color:#777} +legend,pre{display:block;color:#333} blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'} .blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0} code,kbd{padding:2px 4px;font-size:90%} caption,th{text-align:left} .blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''} .blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'} -address{margin-bottom:20px;font-style:normal} code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace} .popover,.tooltip{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif} code{color:#c7254e;background-color:#f9f2f4;border-radius:4px} kbd{color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)} kbd kbd{padding:0;font-size:100%;-webkit-box-shadow:none;box-shadow:none} -pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px} +pre{padding:9.5px;margin:0 0 10px;font-size:13px;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px} .container,.container-fluid{margin-right:auto;margin-left:auto} pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;border-radius:0} .container,.container-fluid{padding-right:15px;padding-left:15px} @@ -661,7 +661,7 @@ table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;f } fieldset,legend{padding:0;border:0} fieldset{min-width:0;margin:0} -legend{display:block;width:100%;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border-bottom:1px solid #e5e5e5} +legend{width:100%;margin-bottom:20px;font-size:21px;line-height:inherit;border-bottom:1px solid #e5e5e5} label{display:inline-block;max-width:100%;margin-bottom:5px} input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none} input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal} @@ -1419,4 +1419,4 @@ td.visible-print,th.visible-print{display:table-cell!important} .visible-print-inline-block{display:none!important} @media print{.visible-print-inline-block{display:inline-block!important} .hidden-print{display:none!important} -} +} \ No newline at end of file diff --git a/test/selectors/extractor-test.js b/test/selectors/extractor-test.js index 23484525..09e74593 100644 --- a/test/selectors/extractor-test.js +++ b/test/selectors/extractor-test.js @@ -33,6 +33,12 @@ vows.describe(extractor) assert.deepEqual(tokens, [['color', 'red!important', 'color', [['color'], ['red!important']], 'color:red!important', [['a']], true]]); } }, + 'one property - simple selector': { + 'topic': extractor(buildToken('#one span{color:red}')), + 'has no properties': function (tokens) { + assert.deepEqual(tokens, [['color', 'red', 'color', [['color'], ['red']], 'color:red', [['#one span']], true]]); + } + }, 'one property - complex selector': { 'topic': extractor(buildToken('.one{color:red}')), 'has no properties': function (tokens) { diff --git a/test/selectors/merge-media-queries-test.js b/test/selectors/merge-media-queries-test.js index 6b92626d..734baaad 100644 --- a/test/selectors/merge-media-queries-test.js +++ b/test/selectors/merge-media-queries-test.js @@ -72,6 +72,10 @@ vows.describe('merge media queries') '@media screen{a{color:red}}/*! a comment */@media screen{a{display:block}}', '/*! a comment */@media screen{a{color:red;display:block}}' ], + 'with IDs mixed with type selectors': [ + '@media (max-width:768px){#id img{display:none}}#id span{display:inline-block;width:50%}@media (max-width:768px){#id span{width:100%}}', + '#id span{display:inline-block;width:50%}@media (max-width:768px){#id img{display:none}#id span{width:100%}}' + ], 'backwards': [ '@media (max-width:768px){.one{padding-right:0}}.one{padding:10px}@media (max-width:768px){.one{margin:0}}', '@media (max-width:768px){.one{padding-right:0;margin:0}}.one{padding:10px}'