From dd9534d1f52275af256e8ee31c95242d4a784a01 Mon Sep 17 00:00:00 2001 From: Andreas Lind Date: Thu, 18 Dec 2014 23:57:07 +0100 Subject: [PATCH 1/9] Added test case with a retina image. Does not actually assert anything yet. --- test/spriteBackgroundImages.js | 18 ++++++++++++++ .../spriteBackgroundImages/retina/index.html | 23 ++++++++++++++++++ .../retina/settings.png | Bin 0 -> 9023 bytes .../retina/settings@2x.png | Bin 0 -> 28026 bytes 4 files changed, 41 insertions(+) create mode 100644 testdata/spriteBackgroundImages/retina/index.html create mode 100644 testdata/spriteBackgroundImages/retina/settings.png create mode 100644 testdata/spriteBackgroundImages/retina/settings@2x.png diff --git a/test/spriteBackgroundImages.js b/test/spriteBackgroundImages.js index a590d74..8289f3b 100644 --- a/test/spriteBackgroundImages.js +++ b/test/spriteBackgroundImages.js @@ -257,4 +257,22 @@ describe('spriteBackgroundImages', function () { }) .run(done); }); + + it('should get the background-position right when spriting a @2x image', function (done) { + new AssetGraph({root: __dirname + '/../testdata/spriteBackgroundImages/retina/'}) + .loadAssets('index.html') + .populate() + .queue(function (assetGraph) { + expect(assetGraph, 'to contain assets', 'Css', 1); + expect(assetGraph, 'to contain assets', 'Png', 2); + }) + .queue(spriteBackgroundImages()) + .writeAssetsToDisc({url: /file:/}, "file:///tmp/foo/") + .queue(function (assetGraph) { + var cssAssets = assetGraph.findAssets({ type: 'Css'}); + + expect(assetGraph, 'to contain asset', 'Png'); + }) + .run(done); + }); }); diff --git a/testdata/spriteBackgroundImages/retina/index.html b/testdata/spriteBackgroundImages/retina/index.html new file mode 100644 index 0000000..29a45f7 --- /dev/null +++ b/testdata/spriteBackgroundImages/retina/index.html @@ -0,0 +1,23 @@ + + + + + + + +
+
+ + \ No newline at end of file diff --git a/testdata/spriteBackgroundImages/retina/settings.png b/testdata/spriteBackgroundImages/retina/settings.png new file mode 100644 index 0000000000000000000000000000000000000000..188a6483a70dec96fca5a03bc194bb1312066751 GIT binary patch literal 9023 zcmaKSWmFv7)-41*Sb*T#Sdc*D5D4z>ZjCh(0u9}by9akCxC9Rtf+sjM+E~!w1PBsb z!{glVp8LHY@4gzlYRg!2uC-^aHEPtTiqg_h#K)n+K|w*mS5}hKdFtQ%ePUxiUHe&1 z8=pE#xV#Zu7h(tZw1R?Bq-`PAV1Tl-l|5JoY-Q{1HVhU+K|#}W)H8w`sjG?FK%9YA zf7<}PoL!&LC@5l*UanR)PGC5|8f@?ABF=c+-pvSbv=wJG6jbL?ca;S@I4b!-!MZ*g zdNw{zHX^o+k`e$hFVQCgXE59f;N|?z1t#hx&iF50(Wmj>%iN5Bf0@9Y#2No5C?j<( zfGh+G1_%QAxomiNc>zK~KwbesAt7E)03Q!8A2-ia6XN0(5ET>>suH#~KFL0sn8j|4(9=p0_KQTL%n-xI=B8Zk!#{->zImWuagzI0UK(fxP=iMJ)#i z90GHIxB_H#g#c{4{6L<6iO0jwBM5W`3h)a4TT6a!9zjt)UQr&Nr^XHdu&GWR`|bS|IQm{*C)?%V5p-9*j51waR&TLA5q8u9*e+# z<@-0*_P@s>_+PQyPr-2iody3_R{XQ{lxlwu|C8fSlmAo+*yX7-piebm`aw@e{q!!HC9lRMveby54v$2}p)&0E)bFWDzAe7hZ~E+B)$Cs3QQUEPvzV~B z-#81r-Jk24zkS>6KO5cbLV|(eW`%o43x<87oKfZWWh_pRg-md;} zCcb+`?KEGza(X5Cf;FJW=keickcHz_U9^HVE*FB1{I3P~4U^!a!>Gf2`k!pZ@7LyaU&X~T0=-@%(gC&Z&ZZMBhm0CHKcjqV53=sg zO0NXwjq_@{`-ukKRtN^qOrQ(DR3G;8%I)&}_5*k`0)GwO`hr2e7qeS8VHnDw!{OROLD-*|G^|nN^GtAK7c&^z2mew-;uH=3wXV zdsU;gmWdxG1Y7EzGs?di@nC`yg9m8^-zsyhVhxbCWU80bn>N3lJ*9?p)L+qaw7VmA zh#Kw21K4SB)at!pF&0JWB$Gm(`nbM3k{NkHk_GQ$Hc1vj+~0{u<_R1Xo+!Nih`2)< zopaO_E1aJ5caCp2%Zr=$87>wT4HSH))#`ndstR$uJNL+;uY9igaCH_ zI(gK-ER3Y9?l>E->!gg5v;UIUs*Do-Yq8VR!r#C7{QLsh*EMK4YmEw7cYL!pm{T9V zNy1Esoptpm!E|(Uxu7*qQbSvI5eHpT^m(CLc(vun`&i_Io^+0dAiYRDQ&T=E&qQr) zZ8FB$F2lpiRCT$ehJ{~ciUGe*I^=Gqv3Bu;QdPI^Oo}~kox)RTNhjfB_l0I(1MErKHcSv%nNz2!ih%h%=*Nx;b zM!>LuCctQ@Reh-RFc@=GK0rvW$c@b~)f#wAJurR8TYvf`4-;x`^MSWG0^ym?ozd22 zG6um-nx9^IxSrY5g$x9T3@kAv+(Sn;NlBI-z2e(zG8TcL;8t}TFZ!B zn#m%2ddFV2KqMfY^rUbpC3+;xr^(1QcH8F5OHe8b$;rr?qcRw*b8H&K$5DS!fs~gc znjpnc;W*$CCSoV0I$BpU(&_Ak{&=`TJY20rI?;|0W%7CNUwrvV@KT$TNOSZBBc0e( zhkM4am39#Ea7iD>#wS~fRnCp|JUJV;irSh`a9r~qB@PjuqLsPNfK^CkM$zvuy_Z$9 zDZmbzue%HsT-Z#=pjuF6)V6+$y+J=iN4us?b%%6wrLd}N zp(hM%7Q3mW=HZ7Ie|xK{8vAO&50$Ql5P@aZgDsZ{tiJfVWlaG$m;Gh<&kEmbI27gGhym~yZ)|=OJBH@|ocH8}My8Gy@&~=-}%`~fPTCB zDK}Ua+teZ#>%LsKGg}qy;i1I*y1gKeg;wpVyriX3mbBEB^T^+v7KK~YrSnjz^?0>C zjkk178oDSaA6_=J2ixsAaJ;x@=Pyg?Rw1d7dhS7Yr}a`@Liwok4y(a+ol!jU;{@Ca zE~28q85ImC^oy>1r{Kh!Bu=KuroIgmqaWka8QuVZ(^jWaY9qdw@R8uF%Il}makHI% zQ+X||jCxx5o{eqIpX{ePgQPbrMoh#*(QA3Hg5_qH&iBzwX&hSJs_&r4)Ia%8;XVxwSXFReQX`0&3lRY2)9K zJUdH_`V4fNg|KxvBs9xUe=g*r2R}MK3JXT#vp?EPv_eU;zZL=87+2evd&UZ9so?!U zmx|fydBqb(TXPH!f-bN&=z6?s4mn_mHMXbaCuJih)sDXQhCuS40i{d$h%)lUuY&}H zW)QuErwiqerm(m3dE$IGeNi7HQE$fT=&=ao^x3Hrn_PbPoLwA?$>a}~e-JRvdsu<2 zFXVEJ{Kyf81Vbq+Gz>7>v{7=wTPl= zFZ*8Kp$R#WcMH7Q?CH-qvZduxSI_kMo{?_3{n@!2)-6*q1etWX57uzZN74td-CZ5( zo)fHjbF!*21#T2W&mwI@;u)tokX7S~(^&;cbT>PTqErmr;P03+a=QVku_}A-oP>Y< z)tdgS*yK{EVZ3}hUVV((wVnS&CpwzNekP8%xonN;^v!+kw!d%iJDBPB+nRf*2` zbRJsLtiS39i{mtJkQ<1nD-GehV*7P_aj<Lsr=^Y)aK+Glm# zq1??20S$BW4}H=WKetfrB2HIv^;G|7F=^v#a)cJ2cx<+ah|D5Ye&WcPK0K<{F2 zVq@w3QoCoJ*wr!&IXlbZOuK@_{lwTBC1*{nNV!f8b;LB>_i8t5{l%f5%>Cznr$y5- zAdkl?L``ImSwGWx2U)5L-rTWkwH;=xkgu`Z8qJZ^%=SFgm73*cLM4M5GMN|&DkY0e z@a1-vRPV`JWfav6t94}|cGC8zbU3eh!;}d`PG@vAhpoNR(?K04V*b4MKeOg7eDT-Y z)IE-uxK|!1xz2@7yHSpPtTZuoBBmQyMnhFzP9*>{J=1r@(>Aa_dJh6Ak*f@7O68wz z2DegmHG&&3D23mK zlENVyaeNe%5FPxJ;i;VXkBSFWR3&#_So=;|e@>Qh3HjI??LTll5GDh9HNqH{LOK>_ zksSVe9hW(rw49gtOoJhG9(SvaskpnMNa$+o?%TNXqVpL@xhiPIQmJWeQ&WOHMMI2;>^a9GG1xRAfX!*u$5afPst)}SQ8KDD5Z9x1 zIMN2qvf%edSz&4mgsz8!rHUGy=DJGPHJx2~bqRgLIFVULWYx}wD^|6zfA7?Qbu(U;P)?jV7QM)8o0lW3G zTaFVi*tpK^#OQRLUT9}k<(qnx#!~Vdf4#wJXBrRnr613J0V4L*^AE2BVw>nhnFZNS zGA#U(a0ZjLtbt8JAXReiWRXVuVH}>4-bjLwb>_rl$1Gt;p4nZ$6Z|uEXb+wuRrHPF z>91_TgP?IrK@I;+Z1rH0*TSq6?U(dn42sGuRK)yVp5Sj;u#4kRC0YqzxlLD*xs`H< ziQ#AsIok2zDTxN$e>t`Jvl8D83OIxyB@=ZO}pS$;Azq+~!Bp^Cn`MPAIS(2fjDYf2U`3z;P8 z9U)Lf4i4vb4*6&cO|9)~6yrxmGAtCLV%ZbJf4`|V>Q(qUo2*MW7uZ)I#ydMW)sPb0 z+-f#8?WRXRbQyz5G{=ptTBkL+;(Mt=Fm$Tu~9_8%ZV0YmpKaU90KtsupkDs}MKm0`PqB9x$Wr=Ua)uchZyidct}O zE9uiI4pp8w-=jfIQ<#sCc9Z$q%sX+$u%uhY>%ItYeO&d`I^*LIt67>}DGiy{#rjsj z__2kEZF(Uii8b&61Qn9`U~5SsCR6&6jr7$64D=u36Xy6Rq2KR9_2iXDlnPL z^fO0Kn?;(2f){thO;WL9X+=HJZn-Vq+v63X@fm>R1p%#vSqdk8V*^iLv?D?l`7_ zq1qK+@b$_1zWGQ`_7AM_F(@SghM>JjLOknh&J*}o0~1YtE4;o9wprZPwhe`*&BZZa zYGGx`YLS3@FSgaK=Nn?FK@1I8oMm+_APx@g$f-e{Tu!C0xeNTwM?_LM0WkG`iR(2q z5$M)?fu2`3g!}igR_$N}8OpLU)hVZ=p8^C@r*_+iewg+qo<{4JWu}MjjGj2fvJ6j0 z^{OcoK~jtVpvFQ+v+;+%&%m5lnOQ=HX;>L_F*T?zYQSM-hCylqERc(o(DCvs>XyS) zFAC>n^4i}pAc}N*iQBmstrK6}mzQrb#3Y3HlQ;z?)r;M@!J5v~UaHc~eT0`d8#w z?ib9`$Y?%z1sg1tL5*c$d@NrQlxE#D*^aj&4j?&ytr~4#w&*jyP(HyGYP$D2Zj5A4 zhI-J~P(MdrP>4KNadt-deTuG$gIx?W+hqY#*Ol`(IqIxWo1FIOa7FoeYE^BUNp^(b z&tH);dz`G6m+G$lxd*ZgY$L1bXY@tx6`|~?#NzMLnYjefG3;IV;Eqx|v>*X3N0+f5 zY8Vmly>fwp!k!NDIFWX~rW{gZ17>H7h ztS!8^NiWDG-=JK|8pz2n^dfUgJ?hSdNndS49sepRadixnMLWG+WSEWcRpbIg^k&rN zFvEF?VqRroU`rC*oYQ?}&hae0SVJ|&h5l#=%-}=lqG7;$ z!)pfA4D?5?4Ez+22mN+$mMJH{zg8n?`ZW(Gi+3JOpmQvmq3mc^bQfehXv6qmsaIfL z#O1>$BC;O#7vFAED>6F!J6cm|IQ!a9?P50z=p+G+#zmzqmR8bg(b_phTB$u5mq`f@ z(#U2oem1%H3cYGt@@CIHI@EE6Xm%XM{41w&jxYoEYImBs`Z1f zN;s)=JojYwL=dTB!}y=+ zmQD#c{6qyPaSg`N7RyYt-P01}IAb;wo}T4DipAE;CS}gQDEVn##9JIRlJW6p4EKY+ zVriVsKq2j@DoC@u_C*3_()$fqo~p6K_ov5WRjhr!cUiT+?}u6iWYw=J5%!B`p;MVA zGG7v3XuZ_e9g|t%G6Z>JKx^>x>TP#xS1dW1q_GsMPSC3;PFu?*<1|V^cO#~dcJrNa z3Hh}3=V@RYsR^W(pQO`VHIyLRpU|h>twFK254!{^o zW!}~2zv_Q1Uf|VEjO}52FjprluXIa2!nql+~uNT5Q1_ADo>A@u&| z+-bf2mCFsu_3_Pae%&+io2?fO)K>5fW!>$AmLCz3dK@D<_Z*20aJqI1a*2< z$x@z|w@-dLts`v!#8xZA3Nx(abk9&sI<6TV9X@6h7sUB(Pck>P(9hFlvHUK7{KEvd zIc%ug4vKf`YaDSBmyoK@*#$NPxr`QA%ZVgo0kwI8H7SHO#zhbC4%I0=&gr7006Glw zob5C!mwWG8W@bB1_nr2~a=QI=7ht8QMA#H|8k*@l!vb=qzU|8agCCI4>yOMy<;&?` zCt1o|8$|p@mE_$y`WHyz=;ZVP#hX0A#d-vEn3%}6g6#z*-rvH7sp6^zede4Dbz*he z0a4T^o;EfqVwVU-J+1L@hwa&_$Ct&y<1yS~hC(j)QW+Oc4`TpGN2`Lw_nB%00Xor< zI%7EJ>>?6J6eJx;>u^C084>P&a2^g_bR$T^Bz13Ef|4pK#JxivO1v`c0?dN~(MU#y z(hSWQ5VajTInR=56&Mnx-^2q?GuzBeh_P=?*@y;qLWQJm^Faan^R_#Mp;z~r}!hf6I^QI=?dmkag?m#}M>t=~tTT*=a={TD{7-iX=eSe1 z9=|D7P##Gcx~*Owm^;)btJ+D&m6@9Hr#f1H2XT|z;H6y+q7NrsIGz86|A50U8&d+> zq*CZ`+{GHTxS={jCUtR;yO(4E`7WlY6J@9%mRjWS}nhc1wsl+ z0gVL0wru8pzx(%T(-Y6Q&6uMW3l}f9iBy(r6+N~^8NBZvxEgS-HgEB%VaV32Revlx z>cXo|LVr%fOWfAj?unk%7~i8m5`A-q<59&ZSM;f^Fgs;r zT_G+xFqPe5TV>Qv&|%R{PF``z?JxNao%zX<>J zFMnpI9ezJuJ`22!sx{k&-B=(w=gOE#rY0(3HFx7Mc9w zTC-Li?dygKKa-tYpN0~jc-6Z|#S-#n?cn#Os7gj(f(GJ1UQ?emB_EnrV?y|uHS>L` zMvUstJ=ZCdGZ5VEYT`F{KOR@#NuJC@y~lU~M>Ri;7>->QD>ump>n_?hw1yl*3&v3H z_N>#Vy^q>RgmcE5q9l=-yf)brT71~MO$=0j1`wB*1g#G_KT>*w?voW4D#Y%7H6oG7 zA_p%DOY_tixs9;Q6#5Nn-k&0WUgBiB~RXQ^<+=9-DhMZeHLpVMg-|`jrd2 zgWQS#Sd~tl=`1&rE&y-si!^3~qu{a>sLn-UUB`(kkTv+lGOD6aSu1_eM6M6OvC45=dguV`}~OHh`fcj(K(ULZfy^UdBhM= zFT$CeYeJrN{5=&R!&aSM(BNL{=HQzW$yv~9CzUL1oviaqNno6Tve8himn6_T^)1X1 ze!JG2kWTGQfIF(zJLR9AqLB;mT)xz2VH6jC7{MZFZo1#j^F40GFQ;v~H}{!688|<# zHTo^rQ2Ex3aD+L9ln-5;F>(^p-6+kT6@r#=O1)YdiMKDIt9=`7Zb_xIAnBxToE<%P{la{jw{(Sz0^%qwXU=TWVsuEY_@L9DXm!SBHBGipmLA!M2^ZuzvBE z%~Ch5jhbnU;sl=HkhM zb&OO7F4P2t3j|p15Aq9X-8JUB`^)+}i*`$yhY(}d{rxU4Q<0X#Gt0A5OpqyJ`tIjy zz!D)f|LOTCnW^u|mFnn`!I?kW5s~FYy4qO+q|PCa zpL_kGN-lOT*6za_RRL{Jnkdf6E;zfOolJ+eThd0n8+O=PqVqfcIquWmp=^4^Y%)NR ze&oy7u8C{+n6d<2`}!l`q6+lT)L3luN<(yn{nKJgNp&3$P8A-QK=XsB^P;hRZhe7U z-_X-%&vy<2G%8={aL_!1O`cf)7^3+>vL9CBox46W#xE?d-_RlHQf^$R|2Svl(A5rS z)`c6Da@SpBmKH5HZKvNn_q;gCVUVtWC^l=CaXgr?Z5T9tPP^E&Q`2G~2w7Mer!8wTi@yop|*gu>L)cWxe r=O)_Zv1FvJ%i8!+|NgP7{-Rr|CeE%i-G}1uUs{yqHRNh#EJOYev0nXi literal 0 HcmV?d00001 diff --git a/testdata/spriteBackgroundImages/retina/settings@2x.png b/testdata/spriteBackgroundImages/retina/settings@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d6f33ea1c37cf21a1abb19e4bccf2f9362ac0969 GIT binary patch literal 28026 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 Date: Fri, 19 Dec 2014 00:04:35 +0100 Subject: [PATCH 2/9] jshint --- test/spriteBackgroundImages.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/spriteBackgroundImages.js b/test/spriteBackgroundImages.js index 8289f3b..64a0b57 100644 --- a/test/spriteBackgroundImages.js +++ b/test/spriteBackgroundImages.js @@ -267,10 +267,8 @@ describe('spriteBackgroundImages', function () { expect(assetGraph, 'to contain assets', 'Png', 2); }) .queue(spriteBackgroundImages()) - .writeAssetsToDisc({url: /file:/}, "file:///tmp/foo/") + .writeAssetsToDisc({url: /file:/}, 'file:///tmp/foo/') .queue(function (assetGraph) { - var cssAssets = assetGraph.findAssets({ type: 'Css'}); - expect(assetGraph, 'to contain asset', 'Png'); }) .run(done); From a75a8fc0e6d1d991913db590edaf91876cacbf66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20M=C3=BCller?= Date: Fri, 26 Dec 2014 00:32:55 +0100 Subject: [PATCH 3/9] Make packingData available later in the spriting chain --- lib/spriteBackgroundImages.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/spriteBackgroundImages.js b/lib/spriteBackgroundImages.js index 190dd38..80b8c38 100644 --- a/lib/spriteBackgroundImages.js +++ b/lib/spriteBackgroundImages.js @@ -190,7 +190,8 @@ module.exports = function () { var callback = this, spriteGroup = spriteGroups[spriteGroupName], imageInfos = _.values(spriteGroup.imageInfosById), - spriteInfo = spriteGroup.placeHolders && spriteGroup.placeHolders[0] || {}; + spriteInfo = spriteGroup.placeHolders && spriteGroup.placeHolders[0] || {}, + packingData; seq(imageInfos) .parMap(function (imageInfo) { @@ -210,9 +211,12 @@ module.exports = function () { horizontal: 'horizontal', vertical: 'vertical' }[spriteInfo.packer] || 'tryAll'; - var packingData = packers[packerName].pack(imageInfos), - canvas = new Canvas(packingData.width, packingData.height), + + packingData = packers[packerName].pack(imageInfos); + + var canvas = new Canvas(packingData.width, packingData.height), ctx = canvas.getContext('2d'); + imageInfos = packingData.imageInfos; if ('backgroundColor' in spriteInfo) { ctx.fillStyle = spriteInfo.backgroundColor; From c9f9a33241af6b7c83da4ff3080fadcbc4310ec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20M=C3=BCller?= Date: Fri, 26 Dec 2014 00:40:13 +0100 Subject: [PATCH 4/9] Update -sprite-selector-for-group background-size property if it exists. When switching to a sprite sheet it changes --- lib/spriteBackgroundImages.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/spriteBackgroundImages.js b/lib/spriteBackgroundImages.js index 80b8c38..c211fd1 100644 --- a/lib/spriteBackgroundImages.js +++ b/lib/spriteBackgroundImages.js @@ -285,6 +285,11 @@ module.exports = function () { ['selector-for-group', 'packer', 'image-format', 'background-color', 'important'].forEach(function (propertyName) { spriteInfo.cssRule.style.removeProperty('-sprite-' + propertyName); }); + + // If background-size is set, we should update it, The correct size is now the sprites size + if (spriteInfo.cssRule.style.getPropertyValue('background-size')) { + spriteInfo.cssRule.style.setPropertyValue('background-size', packingData.width + 'px ' + packingData.height + 'px'); + } }); } imageInfos.forEach(function (imageInfo) { From d36ae118ac9864f6fa53bf00fed46bb99c226244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20M=C3=BCller?= Date: Fri, 26 Dec 2014 00:41:45 +0100 Subject: [PATCH 5/9] Handle background-size css property in each of the cssRules that point to a sprite. Apply device pixel ratio if needed --- lib/spriteBackgroundImages.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/spriteBackgroundImages.js b/lib/spriteBackgroundImages.js index c211fd1..90b55ec 100644 --- a/lib/spriteBackgroundImages.js +++ b/lib/spriteBackgroundImages.js @@ -360,6 +360,21 @@ module.exports = function () { ['group', 'padding', 'no-group-selector', 'important'].forEach(function (propertyName) { style.removeProperty('-sprite-' + propertyName); }); + + // Background-sizes change when spriting, upadte appropriately + if (imageInfo.asset.devicePixelRatio === 1) { + // Device pixel ratio is default. Remove property and let the defaults rule + incomingRelation.cssRule.style.removeProperty('background-size'); + } else { + // Device pixel ratio is non-default, Set it explicitly with the ratio applied + var dpr = incomingRelation.to.devicePixelRatio; + + // TODO: Figure out if rounding might become a problem + var width = packingData.width / dpr; + var height = packingData.height / dpr; + incomingRelation.cssRule.style.setProperty('background-size', width + 'px ' + height + 'px'); + } + if (relationSpriteInfo.noGroup || !spriteGroup.placeHolders) { // The user specified that this selector needs its own background-image/background // property pointing at the sprite rather than relying on the Html elements also being From c8ff224268da418adb10445b27c24b3b66926621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20M=C3=BCller?= Date: Fri, 26 Dec 2014 00:43:11 +0100 Subject: [PATCH 6/9] Upgrade assetgraph to 1.15.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0524b4c..23fec01 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "canvas": "=1.1.2" }, "devDependencies": { - "assetgraph": "1.14.4", + "assetgraph": "1.15.0", "coveralls": "^2.11.1", "istanbul": "^0.3.0", "jshint": "=2.5.1", From 796dbd916a5ef97e909ef7d2a961eb9d7f3de17b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20M=C3=BCller?= Date: Sat, 27 Dec 2014 18:23:05 +0100 Subject: [PATCH 7/9] Try to improve transform readability --- lib/spriteBackgroundImages.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/spriteBackgroundImages.js b/lib/spriteBackgroundImages.js index 90b55ec..14a7eab 100644 --- a/lib/spriteBackgroundImages.js +++ b/lib/spriteBackgroundImages.js @@ -110,6 +110,8 @@ module.exports = function () { } var spriteGroups = {}; + + // Find sprite annotated images and create a data structure with their information assetGraph.findRelations({type: 'CssImage', to: {isImage: true}, href: /\?(?:|[^#]*&)sprite(?:[=&#]|$)/}).forEach(function (relation) { var relationSpriteInfo = getRelationSpriteInfoFromIncomingRelation(relation), spriteGroup = (spriteGroups[relationSpriteInfo.groupName] = spriteGroups[relationSpriteInfo.groupName] || { @@ -127,6 +129,7 @@ module.exports = function () { } }); + // Extract sprite grouping information va -sprite- prefixed properties in stylesheets assetGraph.findAssets({type: 'Css'}).forEach(function (cssAsset) { cssAsset.eachRuleInParseTree(function (cssRule) { if (cssRule.type !== 1) { // cssom.CSSRule.STYLE_RULE From fb71b6a424315aa26dcf8b3cf7df5dffa9737dc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20M=C3=BCller?= Date: Sat, 27 Dec 2014 18:23:27 +0100 Subject: [PATCH 8/9] Fix invalid function call --- lib/spriteBackgroundImages.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/spriteBackgroundImages.js b/lib/spriteBackgroundImages.js index 14a7eab..3813601 100644 --- a/lib/spriteBackgroundImages.js +++ b/lib/spriteBackgroundImages.js @@ -291,7 +291,7 @@ module.exports = function () { // If background-size is set, we should update it, The correct size is now the sprites size if (spriteInfo.cssRule.style.getPropertyValue('background-size')) { - spriteInfo.cssRule.style.setPropertyValue('background-size', packingData.width + 'px ' + packingData.height + 'px'); + spriteInfo.cssRule.style.setProperty('background-size', packingData.width + 'px ' + packingData.height + 'px'); } }); } From e8b156f68a05b59e21d7be2219d114235dbaa290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20M=C3=BCller?= Date: Sat, 27 Dec 2014 18:24:17 +0100 Subject: [PATCH 9/9] Improve retina sprite test case to actually test something --- test/spriteBackgroundImages.js | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/test/spriteBackgroundImages.js b/test/spriteBackgroundImages.js index 64a0b57..e38c1ba 100644 --- a/test/spriteBackgroundImages.js +++ b/test/spriteBackgroundImages.js @@ -265,11 +265,34 @@ describe('spriteBackgroundImages', function () { .queue(function (assetGraph) { expect(assetGraph, 'to contain assets', 'Css', 1); expect(assetGraph, 'to contain assets', 'Png', 2); + expect(assetGraph, 'to contain assets', { type: 'Png', devicePixelRatio: 1 }, 1); + expect(assetGraph, 'to contain assets', { type: 'Png', devicePixelRatio: 2 }, 1); + + assetGraph.findRelations({ type: 'CssImage', cssRule: { selectorText: '.regular' } }).forEach(function (relation) { + expect(relation.to.devicePixelRatio, 'to be', 1); + expect(relation.cssRule.style, 'not to have property', 'background-size'); + }); + + assetGraph.findRelations({ type: 'CssImage', cssRule: { selectorText: '.retina' } }).forEach(function (relation) { + expect(relation.to.devicePixelRatio, 'to be', 2); + expect(relation.cssRule.style, 'not to have property', 'background-size'); + }); }) .queue(spriteBackgroundImages()) - .writeAssetsToDisc({url: /file:/}, 'file:///tmp/foo/') .queue(function (assetGraph) { - expect(assetGraph, 'to contain asset', 'Png'); + expect(assetGraph, 'to contain asset', 'Png', 1); + expect(assetGraph, 'to contain relations', 'CssImage', 2); + expect(assetGraph, 'to contain relations', { type: 'CssImage', cssRule: { selectorText: '.regular' } }, 1); + expect(assetGraph, 'to contain relations', { type: 'CssImage', cssRule: { selectorText: '.retina' } }, 1); + + assetGraph.findRelations({ type: 'CssImage', cssRule: { selectorText: '.regular' } }).forEach(function (relation) { + expect(relation.cssRule.style, 'not to have property', 'background-size'); + }); + + assetGraph.findRelations({ type: 'CssImage', cssRule: { selectorText: '.retina' } }).forEach(function (relation) { + expect(relation.cssRule.style, 'to have property', 'background-size'); + expect(relation.cssRule.style.getPropertyValue('background-size'), 'to be', '88.5px 59px'); + }); }) .run(done); });