nsCSSValue.cpp 102 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238
  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. /* representation of simple property values within CSS declarations */
  6. #include "mozilla/ArrayUtils.h"
  7. #include "nsCSSValue.h"
  8. #include "mozilla/StyleSheetInlines.h"
  9. #include "mozilla/Likely.h"
  10. #include "mozilla/Move.h"
  11. #include "mozilla/css/ImageLoader.h"
  12. #include "CSSCalc.h"
  13. #include "gfxFontConstants.h"
  14. #include "imgIRequest.h"
  15. #include "imgRequestProxy.h"
  16. #include "nsIDocument.h"
  17. #include "nsNetUtil.h"
  18. #include "nsPresContext.h"
  19. #include "nsStyleUtil.h"
  20. #include "nsDeviceContext.h"
  21. #include "nsStyleSet.h"
  22. #include "nsContentUtils.h"
  23. using namespace mozilla;
  24. using namespace mozilla::css;
  25. static bool
  26. IsLocalRefURL(nsStringBuffer* aString)
  27. {
  28. // Find the first non-"C0 controls + space" character.
  29. char16_t* current = static_cast<char16_t*>(aString->Data());
  30. for (; *current != '\0'; current++) {
  31. if (*current > 0x20) {
  32. // if the first non-"C0 controls + space" character is '#', this is a
  33. // local-ref URL.
  34. return *current == '#';
  35. }
  36. }
  37. return false;
  38. }
  39. nsCSSValue::nsCSSValue(int32_t aValue, nsCSSUnit aUnit)
  40. : mUnit(aUnit)
  41. {
  42. MOZ_ASSERT(aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated ||
  43. aUnit == eCSSUnit_EnumColor,
  44. "not an int value");
  45. if (aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated ||
  46. aUnit == eCSSUnit_EnumColor) {
  47. mValue.mInt = aValue;
  48. }
  49. else {
  50. mUnit = eCSSUnit_Null;
  51. mValue.mInt = 0;
  52. }
  53. }
  54. nsCSSValue::nsCSSValue(float aValue, nsCSSUnit aUnit)
  55. : mUnit(aUnit)
  56. {
  57. MOZ_ASSERT(eCSSUnit_Percent <= aUnit, "not a float value");
  58. if (eCSSUnit_Percent <= aUnit) {
  59. mValue.mFloat = aValue;
  60. MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
  61. }
  62. else {
  63. mUnit = eCSSUnit_Null;
  64. mValue.mInt = 0;
  65. }
  66. }
  67. nsCSSValue::nsCSSValue(const nsString& aValue, nsCSSUnit aUnit)
  68. : mUnit(aUnit)
  69. {
  70. MOZ_ASSERT(UnitHasStringValue(), "not a string value");
  71. if (UnitHasStringValue()) {
  72. mValue.mString = BufferFromString(aValue).take();
  73. }
  74. else {
  75. mUnit = eCSSUnit_Null;
  76. mValue.mInt = 0;
  77. }
  78. }
  79. nsCSSValue::nsCSSValue(nsCSSValue::Array* aValue, nsCSSUnit aUnit)
  80. : mUnit(aUnit)
  81. {
  82. MOZ_ASSERT(UnitHasArrayValue(), "bad unit");
  83. mValue.mArray = aValue;
  84. mValue.mArray->AddRef();
  85. }
  86. nsCSSValue::nsCSSValue(mozilla::css::URLValue* aValue)
  87. : mUnit(eCSSUnit_URL)
  88. {
  89. mValue.mURL = aValue;
  90. mValue.mURL->AddRef();
  91. }
  92. nsCSSValue::nsCSSValue(mozilla::css::ImageValue* aValue)
  93. : mUnit(eCSSUnit_Image)
  94. {
  95. mValue.mImage = aValue;
  96. mValue.mImage->AddRef();
  97. }
  98. nsCSSValue::nsCSSValue(nsCSSValueGradient* aValue)
  99. : mUnit(eCSSUnit_Gradient)
  100. {
  101. mValue.mGradient = aValue;
  102. mValue.mGradient->AddRef();
  103. }
  104. nsCSSValue::nsCSSValue(nsCSSValueTokenStream* aValue)
  105. : mUnit(eCSSUnit_TokenStream)
  106. {
  107. mValue.mTokenStream = aValue;
  108. mValue.mTokenStream->AddRef();
  109. }
  110. nsCSSValue::nsCSSValue(mozilla::css::GridTemplateAreasValue* aValue)
  111. : mUnit(eCSSUnit_GridTemplateAreas)
  112. {
  113. mValue.mGridTemplateAreas = aValue;
  114. mValue.mGridTemplateAreas->AddRef();
  115. }
  116. nsCSSValue::nsCSSValue(css::FontFamilyListRefCnt* aValue)
  117. : mUnit(eCSSUnit_FontFamilyList)
  118. {
  119. mValue.mFontFamilyList = aValue;
  120. mValue.mFontFamilyList->AddRef();
  121. }
  122. nsCSSValue::nsCSSValue(const nsCSSValue& aCopy)
  123. : mUnit(aCopy.mUnit)
  124. {
  125. if (mUnit <= eCSSUnit_DummyInherit) {
  126. // nothing to do, but put this important case first
  127. }
  128. else if (eCSSUnit_Percent <= mUnit) {
  129. mValue.mFloat = aCopy.mValue.mFloat;
  130. MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
  131. }
  132. else if (UnitHasStringValue()) {
  133. mValue.mString = aCopy.mValue.mString;
  134. mValue.mString->AddRef();
  135. }
  136. else if (eCSSUnit_Integer <= mUnit && mUnit <= eCSSUnit_EnumColor) {
  137. mValue.mInt = aCopy.mValue.mInt;
  138. }
  139. else if (IsIntegerColorUnit()) {
  140. mValue.mColor = aCopy.mValue.mColor;
  141. }
  142. else if (IsFloatColorUnit()) {
  143. mValue.mFloatColor = aCopy.mValue.mFloatColor;
  144. mValue.mFloatColor->AddRef();
  145. }
  146. else if (eCSSUnit_ComplexColor == mUnit) {
  147. mValue.mComplexColor = aCopy.mValue.mComplexColor;
  148. mValue.mComplexColor->AddRef();
  149. }
  150. else if (UnitHasArrayValue()) {
  151. mValue.mArray = aCopy.mValue.mArray;
  152. mValue.mArray->AddRef();
  153. }
  154. else if (eCSSUnit_URL == mUnit) {
  155. mValue.mURL = aCopy.mValue.mURL;
  156. mValue.mURL->AddRef();
  157. }
  158. else if (eCSSUnit_Image == mUnit) {
  159. mValue.mImage = aCopy.mValue.mImage;
  160. mValue.mImage->AddRef();
  161. }
  162. else if (eCSSUnit_Gradient == mUnit) {
  163. mValue.mGradient = aCopy.mValue.mGradient;
  164. mValue.mGradient->AddRef();
  165. }
  166. else if (eCSSUnit_TokenStream == mUnit) {
  167. mValue.mTokenStream = aCopy.mValue.mTokenStream;
  168. mValue.mTokenStream->AddRef();
  169. }
  170. else if (eCSSUnit_Pair == mUnit) {
  171. mValue.mPair = aCopy.mValue.mPair;
  172. mValue.mPair->AddRef();
  173. }
  174. else if (eCSSUnit_Triplet == mUnit) {
  175. mValue.mTriplet = aCopy.mValue.mTriplet;
  176. mValue.mTriplet->AddRef();
  177. }
  178. else if (eCSSUnit_Rect == mUnit) {
  179. mValue.mRect = aCopy.mValue.mRect;
  180. mValue.mRect->AddRef();
  181. }
  182. else if (eCSSUnit_List == mUnit) {
  183. mValue.mList = aCopy.mValue.mList;
  184. mValue.mList->AddRef();
  185. }
  186. else if (eCSSUnit_ListDep == mUnit) {
  187. mValue.mListDependent = aCopy.mValue.mListDependent;
  188. }
  189. else if (eCSSUnit_SharedList == mUnit) {
  190. mValue.mSharedList = aCopy.mValue.mSharedList;
  191. mValue.mSharedList->AddRef();
  192. }
  193. else if (eCSSUnit_PairList == mUnit) {
  194. mValue.mPairList = aCopy.mValue.mPairList;
  195. mValue.mPairList->AddRef();
  196. }
  197. else if (eCSSUnit_PairListDep == mUnit) {
  198. mValue.mPairListDependent = aCopy.mValue.mPairListDependent;
  199. }
  200. else if (eCSSUnit_GridTemplateAreas == mUnit) {
  201. mValue.mGridTemplateAreas = aCopy.mValue.mGridTemplateAreas;
  202. mValue.mGridTemplateAreas->AddRef();
  203. }
  204. else if (eCSSUnit_FontFamilyList == mUnit) {
  205. mValue.mFontFamilyList = aCopy.mValue.mFontFamilyList;
  206. mValue.mFontFamilyList->AddRef();
  207. }
  208. else {
  209. MOZ_ASSERT(false, "unknown unit");
  210. }
  211. }
  212. nsCSSValue& nsCSSValue::operator=(const nsCSSValue& aCopy)
  213. {
  214. if (this != &aCopy) {
  215. Reset();
  216. new (this) nsCSSValue(aCopy);
  217. }
  218. return *this;
  219. }
  220. nsCSSValue&
  221. nsCSSValue::operator=(nsCSSValue&& aOther)
  222. {
  223. MOZ_ASSERT(this != &aOther, "Self assigment with rvalue reference");
  224. Reset();
  225. mUnit = aOther.mUnit;
  226. mValue = aOther.mValue;
  227. aOther.mUnit = eCSSUnit_Null;
  228. return *this;
  229. }
  230. bool nsCSSValue::operator==(const nsCSSValue& aOther) const
  231. {
  232. MOZ_ASSERT(mUnit != eCSSUnit_ListDep &&
  233. aOther.mUnit != eCSSUnit_ListDep &&
  234. mUnit != eCSSUnit_PairListDep &&
  235. aOther.mUnit != eCSSUnit_PairListDep,
  236. "don't use operator== with dependent lists");
  237. if (mUnit == aOther.mUnit) {
  238. if (mUnit <= eCSSUnit_DummyInherit) {
  239. return true;
  240. }
  241. else if (UnitHasStringValue()) {
  242. return (NS_strcmp(GetBufferValue(mValue.mString),
  243. GetBufferValue(aOther.mValue.mString)) == 0);
  244. }
  245. else if ((eCSSUnit_Integer <= mUnit) && (mUnit <= eCSSUnit_EnumColor)) {
  246. return mValue.mInt == aOther.mValue.mInt;
  247. }
  248. else if (IsIntegerColorUnit()) {
  249. return mValue.mColor == aOther.mValue.mColor;
  250. }
  251. else if (IsFloatColorUnit()) {
  252. return *mValue.mFloatColor == *aOther.mValue.mFloatColor;
  253. }
  254. else if (eCSSUnit_ComplexColor == mUnit) {
  255. return *mValue.mComplexColor == *aOther.mValue.mComplexColor;
  256. }
  257. else if (UnitHasArrayValue()) {
  258. return *mValue.mArray == *aOther.mValue.mArray;
  259. }
  260. else if (eCSSUnit_URL == mUnit) {
  261. return mValue.mURL->Equals(*aOther.mValue.mURL);
  262. }
  263. else if (eCSSUnit_Image == mUnit) {
  264. return mValue.mImage->Equals(*aOther.mValue.mImage);
  265. }
  266. else if (eCSSUnit_Gradient == mUnit) {
  267. return *mValue.mGradient == *aOther.mValue.mGradient;
  268. }
  269. else if (eCSSUnit_TokenStream == mUnit) {
  270. return *mValue.mTokenStream == *aOther.mValue.mTokenStream;
  271. }
  272. else if (eCSSUnit_Pair == mUnit) {
  273. return *mValue.mPair == *aOther.mValue.mPair;
  274. }
  275. else if (eCSSUnit_Triplet == mUnit) {
  276. return *mValue.mTriplet == *aOther.mValue.mTriplet;
  277. }
  278. else if (eCSSUnit_Rect == mUnit) {
  279. return *mValue.mRect == *aOther.mValue.mRect;
  280. }
  281. else if (eCSSUnit_List == mUnit) {
  282. return nsCSSValueList::Equal(mValue.mList, aOther.mValue.mList);
  283. }
  284. else if (eCSSUnit_SharedList == mUnit) {
  285. return *mValue.mSharedList == *aOther.mValue.mSharedList;
  286. }
  287. else if (eCSSUnit_PairList == mUnit) {
  288. return nsCSSValuePairList::Equal(mValue.mPairList,
  289. aOther.mValue.mPairList);
  290. }
  291. else if (eCSSUnit_GridTemplateAreas == mUnit) {
  292. return *mValue.mGridTemplateAreas == *aOther.mValue.mGridTemplateAreas;
  293. }
  294. else if (eCSSUnit_FontFamilyList == mUnit) {
  295. return *mValue.mFontFamilyList == *aOther.mValue.mFontFamilyList;
  296. }
  297. else {
  298. return mValue.mFloat == aOther.mValue.mFloat;
  299. }
  300. }
  301. return false;
  302. }
  303. double
  304. nsCSSValue::GetAngleValueInRadians() const
  305. {
  306. double angle = GetFloatValue();
  307. switch (GetUnit()) {
  308. case eCSSUnit_Radian: return angle;
  309. case eCSSUnit_Turn: return angle * 2 * M_PI;
  310. case eCSSUnit_Degree: return angle * M_PI / 180.0;
  311. case eCSSUnit_Grad: return angle * M_PI / 200.0;
  312. default:
  313. MOZ_ASSERT(false, "unrecognized angular unit");
  314. return 0.0;
  315. }
  316. }
  317. double
  318. nsCSSValue::GetAngleValueInDegrees() const
  319. {
  320. double angle = GetFloatValue();
  321. switch (GetUnit()) {
  322. case eCSSUnit_Degree: return angle;
  323. case eCSSUnit_Grad: return angle * 0.9; // grad / 400 * 360
  324. case eCSSUnit_Radian: return angle * 180.0 / M_PI; // rad / 2pi * 360
  325. case eCSSUnit_Turn: return angle * 360.0;
  326. default:
  327. MOZ_ASSERT(false, "unrecognized angular unit");
  328. return 0.0;
  329. }
  330. }
  331. imgRequestProxy* nsCSSValue::GetImageValue(nsIDocument* aDocument) const
  332. {
  333. MOZ_ASSERT(mUnit == eCSSUnit_Image, "not an Image value");
  334. return mValue.mImage->mRequests.GetWeak(aDocument);
  335. }
  336. already_AddRefed<imgRequestProxy>
  337. nsCSSValue::GetPossiblyStaticImageValue(nsIDocument* aDocument,
  338. nsPresContext* aPresContext) const
  339. {
  340. imgRequestProxy* req = GetImageValue(aDocument);
  341. if (aPresContext->IsDynamic()) {
  342. return do_AddRef(req);
  343. }
  344. return nsContentUtils::GetStaticRequest(req);
  345. }
  346. nscoord nsCSSValue::GetFixedLength(nsPresContext* aPresContext) const
  347. {
  348. MOZ_ASSERT(mUnit == eCSSUnit_PhysicalMillimeter,
  349. "not a fixed length unit");
  350. float inches = mValue.mFloat / MM_PER_INCH_FLOAT;
  351. return NSToCoordFloorClamped(inches *
  352. float(aPresContext->DeviceContext()->AppUnitsPerPhysicalInch()));
  353. }
  354. nscoord nsCSSValue::GetPixelLength() const
  355. {
  356. MOZ_ASSERT(IsPixelLengthUnit(), "not a fixed length unit");
  357. double scaleFactor;
  358. switch (mUnit) {
  359. case eCSSUnit_Pixel: return nsPresContext::CSSPixelsToAppUnits(mValue.mFloat);
  360. case eCSSUnit_Pica: scaleFactor = 16.0; break;
  361. case eCSSUnit_Point: scaleFactor = 4/3.0; break;
  362. case eCSSUnit_Inch: scaleFactor = 96.0; break;
  363. case eCSSUnit_Millimeter: scaleFactor = 96/25.4; break;
  364. case eCSSUnit_Centimeter: scaleFactor = 96/2.54; break;
  365. case eCSSUnit_Quarter: scaleFactor = 96/101.6; break;
  366. default:
  367. NS_ERROR("should never get here");
  368. return 0;
  369. }
  370. return nsPresContext::CSSPixelsToAppUnits(float(mValue.mFloat*scaleFactor));
  371. }
  372. void nsCSSValue::DoReset()
  373. {
  374. if (UnitHasStringValue()) {
  375. mValue.mString->Release();
  376. } else if (IsFloatColorUnit()) {
  377. mValue.mFloatColor->Release();
  378. } else if (eCSSUnit_ComplexColor == mUnit) {
  379. mValue.mComplexColor->Release();
  380. } else if (UnitHasArrayValue()) {
  381. mValue.mArray->Release();
  382. } else if (eCSSUnit_URL == mUnit) {
  383. mValue.mURL->Release();
  384. } else if (eCSSUnit_Image == mUnit) {
  385. mValue.mImage->Release();
  386. } else if (eCSSUnit_Gradient == mUnit) {
  387. mValue.mGradient->Release();
  388. } else if (eCSSUnit_TokenStream == mUnit) {
  389. mValue.mTokenStream->Release();
  390. } else if (eCSSUnit_Pair == mUnit) {
  391. mValue.mPair->Release();
  392. } else if (eCSSUnit_Triplet == mUnit) {
  393. mValue.mTriplet->Release();
  394. } else if (eCSSUnit_Rect == mUnit) {
  395. mValue.mRect->Release();
  396. } else if (eCSSUnit_List == mUnit) {
  397. mValue.mList->Release();
  398. } else if (eCSSUnit_SharedList == mUnit) {
  399. mValue.mSharedList->Release();
  400. } else if (eCSSUnit_PairList == mUnit) {
  401. mValue.mPairList->Release();
  402. } else if (eCSSUnit_GridTemplateAreas == mUnit) {
  403. mValue.mGridTemplateAreas->Release();
  404. } else if (eCSSUnit_FontFamilyList == mUnit) {
  405. mValue.mFontFamilyList->Release();
  406. }
  407. mUnit = eCSSUnit_Null;
  408. }
  409. void nsCSSValue::SetIntValue(int32_t aValue, nsCSSUnit aUnit)
  410. {
  411. MOZ_ASSERT(aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated ||
  412. aUnit == eCSSUnit_EnumColor,
  413. "not an int value");
  414. Reset();
  415. if (aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated ||
  416. aUnit == eCSSUnit_EnumColor) {
  417. mUnit = aUnit;
  418. mValue.mInt = aValue;
  419. }
  420. }
  421. void nsCSSValue::SetPercentValue(float aValue)
  422. {
  423. Reset();
  424. mUnit = eCSSUnit_Percent;
  425. mValue.mFloat = aValue;
  426. MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
  427. }
  428. void nsCSSValue::SetFloatValue(float aValue, nsCSSUnit aUnit)
  429. {
  430. MOZ_ASSERT(IsFloatUnit(aUnit), "not a float value");
  431. Reset();
  432. if (IsFloatUnit(aUnit)) {
  433. mUnit = aUnit;
  434. mValue.mFloat = aValue;
  435. MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
  436. }
  437. }
  438. void nsCSSValue::SetStringValue(const nsString& aValue,
  439. nsCSSUnit aUnit)
  440. {
  441. Reset();
  442. mUnit = aUnit;
  443. MOZ_ASSERT(UnitHasStringValue(), "not a string unit");
  444. if (UnitHasStringValue()) {
  445. mValue.mString = BufferFromString(aValue).take();
  446. } else
  447. mUnit = eCSSUnit_Null;
  448. }
  449. void nsCSSValue::SetColorValue(nscolor aValue)
  450. {
  451. SetIntegerColorValue(aValue, eCSSUnit_RGBAColor);
  452. }
  453. void nsCSSValue::SetIntegerColorValue(nscolor aValue, nsCSSUnit aUnit)
  454. {
  455. Reset();
  456. mUnit = aUnit;
  457. MOZ_ASSERT(IsIntegerColorUnit(), "bad unit");
  458. mValue.mColor = aValue;
  459. }
  460. void nsCSSValue::SetIntegerCoordValue(nscoord aValue)
  461. {
  462. SetFloatValue(nsPresContext::AppUnitsToFloatCSSPixels(aValue),
  463. eCSSUnit_Pixel);
  464. }
  465. void nsCSSValue::SetFloatColorValue(float aComponent1,
  466. float aComponent2,
  467. float aComponent3,
  468. float aAlpha,
  469. nsCSSUnit aUnit)
  470. {
  471. Reset();
  472. mUnit = aUnit;
  473. MOZ_ASSERT(IsFloatColorUnit(), "bad unit");
  474. mValue.mFloatColor =
  475. new nsCSSValueFloatColor(aComponent1, aComponent2, aComponent3, aAlpha);
  476. mValue.mFloatColor->AddRef();
  477. }
  478. void
  479. nsCSSValue::SetRGBAColorValue(const RGBAColorData& aValue)
  480. {
  481. SetFloatColorValue(aValue.mR, aValue.mG, aValue.mB,
  482. aValue.mA, eCSSUnit_PercentageRGBAColor);
  483. }
  484. void
  485. nsCSSValue::SetComplexColorValue(already_AddRefed<ComplexColorValue> aValue)
  486. {
  487. Reset();
  488. mUnit = eCSSUnit_ComplexColor;
  489. mValue.mComplexColor = aValue.take();
  490. }
  491. void nsCSSValue::SetArrayValue(nsCSSValue::Array* aValue, nsCSSUnit aUnit)
  492. {
  493. Reset();
  494. mUnit = aUnit;
  495. MOZ_ASSERT(UnitHasArrayValue(), "bad unit");
  496. mValue.mArray = aValue;
  497. mValue.mArray->AddRef();
  498. }
  499. void nsCSSValue::SetURLValue(mozilla::css::URLValue* aValue)
  500. {
  501. Reset();
  502. mUnit = eCSSUnit_URL;
  503. mValue.mURL = aValue;
  504. mValue.mURL->AddRef();
  505. }
  506. void nsCSSValue::SetImageValue(mozilla::css::ImageValue* aValue)
  507. {
  508. Reset();
  509. mUnit = eCSSUnit_Image;
  510. mValue.mImage = aValue;
  511. mValue.mImage->AddRef();
  512. }
  513. void nsCSSValue::SetGradientValue(nsCSSValueGradient* aValue)
  514. {
  515. Reset();
  516. mUnit = eCSSUnit_Gradient;
  517. mValue.mGradient = aValue;
  518. mValue.mGradient->AddRef();
  519. }
  520. void nsCSSValue::SetTokenStreamValue(nsCSSValueTokenStream* aValue)
  521. {
  522. Reset();
  523. mUnit = eCSSUnit_TokenStream;
  524. mValue.mTokenStream = aValue;
  525. mValue.mTokenStream->AddRef();
  526. }
  527. void nsCSSValue::SetGridTemplateAreas(mozilla::css::GridTemplateAreasValue* aValue)
  528. {
  529. Reset();
  530. mUnit = eCSSUnit_GridTemplateAreas;
  531. mValue.mGridTemplateAreas = aValue;
  532. mValue.mGridTemplateAreas->AddRef();
  533. }
  534. void nsCSSValue::SetFontFamilyListValue(css::FontFamilyListRefCnt* aValue)
  535. {
  536. Reset();
  537. mUnit = eCSSUnit_FontFamilyList;
  538. mValue.mFontFamilyList = aValue;
  539. mValue.mFontFamilyList->AddRef();
  540. }
  541. void nsCSSValue::SetPairValue(const nsCSSValuePair* aValue)
  542. {
  543. // pairs should not be used for null/inherit/initial values
  544. MOZ_ASSERT(aValue &&
  545. aValue->mXValue.GetUnit() != eCSSUnit_Null &&
  546. aValue->mYValue.GetUnit() != eCSSUnit_Null &&
  547. aValue->mXValue.GetUnit() != eCSSUnit_Inherit &&
  548. aValue->mYValue.GetUnit() != eCSSUnit_Inherit &&
  549. aValue->mXValue.GetUnit() != eCSSUnit_Initial &&
  550. aValue->mYValue.GetUnit() != eCSSUnit_Initial &&
  551. aValue->mXValue.GetUnit() != eCSSUnit_Unset &&
  552. aValue->mYValue.GetUnit() != eCSSUnit_Unset,
  553. "missing or inappropriate pair value");
  554. Reset();
  555. mUnit = eCSSUnit_Pair;
  556. mValue.mPair = new nsCSSValuePair_heap(aValue->mXValue, aValue->mYValue);
  557. mValue.mPair->AddRef();
  558. }
  559. void nsCSSValue::SetPairValue(const nsCSSValue& xValue,
  560. const nsCSSValue& yValue)
  561. {
  562. MOZ_ASSERT(xValue.GetUnit() != eCSSUnit_Null &&
  563. yValue.GetUnit() != eCSSUnit_Null &&
  564. xValue.GetUnit() != eCSSUnit_Inherit &&
  565. yValue.GetUnit() != eCSSUnit_Inherit &&
  566. xValue.GetUnit() != eCSSUnit_Initial &&
  567. yValue.GetUnit() != eCSSUnit_Initial &&
  568. xValue.GetUnit() != eCSSUnit_Unset &&
  569. yValue.GetUnit() != eCSSUnit_Unset,
  570. "inappropriate pair value");
  571. Reset();
  572. mUnit = eCSSUnit_Pair;
  573. mValue.mPair = new nsCSSValuePair_heap(xValue, yValue);
  574. mValue.mPair->AddRef();
  575. }
  576. void nsCSSValue::SetTripletValue(const nsCSSValueTriplet* aValue)
  577. {
  578. // triplet should not be used for null/inherit/initial values
  579. MOZ_ASSERT(aValue &&
  580. aValue->mXValue.GetUnit() != eCSSUnit_Null &&
  581. aValue->mYValue.GetUnit() != eCSSUnit_Null &&
  582. aValue->mZValue.GetUnit() != eCSSUnit_Null &&
  583. aValue->mXValue.GetUnit() != eCSSUnit_Inherit &&
  584. aValue->mYValue.GetUnit() != eCSSUnit_Inherit &&
  585. aValue->mZValue.GetUnit() != eCSSUnit_Inherit &&
  586. aValue->mXValue.GetUnit() != eCSSUnit_Initial &&
  587. aValue->mYValue.GetUnit() != eCSSUnit_Initial &&
  588. aValue->mZValue.GetUnit() != eCSSUnit_Initial &&
  589. aValue->mXValue.GetUnit() != eCSSUnit_Unset &&
  590. aValue->mYValue.GetUnit() != eCSSUnit_Unset &&
  591. aValue->mZValue.GetUnit() != eCSSUnit_Unset,
  592. "missing or inappropriate triplet value");
  593. Reset();
  594. mUnit = eCSSUnit_Triplet;
  595. mValue.mTriplet = new nsCSSValueTriplet_heap(aValue->mXValue, aValue->mYValue, aValue->mZValue);
  596. mValue.mTriplet->AddRef();
  597. }
  598. void nsCSSValue::SetTripletValue(const nsCSSValue& xValue,
  599. const nsCSSValue& yValue,
  600. const nsCSSValue& zValue)
  601. {
  602. // Only allow Null for the z component
  603. MOZ_ASSERT(xValue.GetUnit() != eCSSUnit_Null &&
  604. yValue.GetUnit() != eCSSUnit_Null &&
  605. xValue.GetUnit() != eCSSUnit_Inherit &&
  606. yValue.GetUnit() != eCSSUnit_Inherit &&
  607. zValue.GetUnit() != eCSSUnit_Inherit &&
  608. xValue.GetUnit() != eCSSUnit_Initial &&
  609. yValue.GetUnit() != eCSSUnit_Initial &&
  610. zValue.GetUnit() != eCSSUnit_Initial &&
  611. xValue.GetUnit() != eCSSUnit_Unset &&
  612. yValue.GetUnit() != eCSSUnit_Unset &&
  613. zValue.GetUnit() != eCSSUnit_Unset,
  614. "inappropriate triplet value");
  615. Reset();
  616. mUnit = eCSSUnit_Triplet;
  617. mValue.mTriplet = new nsCSSValueTriplet_heap(xValue, yValue, zValue);
  618. mValue.mTriplet->AddRef();
  619. }
  620. nsCSSRect& nsCSSValue::SetRectValue()
  621. {
  622. Reset();
  623. mUnit = eCSSUnit_Rect;
  624. mValue.mRect = new nsCSSRect_heap;
  625. mValue.mRect->AddRef();
  626. return *mValue.mRect;
  627. }
  628. nsCSSValueList* nsCSSValue::SetListValue()
  629. {
  630. Reset();
  631. mUnit = eCSSUnit_List;
  632. mValue.mList = new nsCSSValueList_heap;
  633. mValue.mList->AddRef();
  634. return mValue.mList;
  635. }
  636. void nsCSSValue::SetSharedListValue(nsCSSValueSharedList* aList)
  637. {
  638. Reset();
  639. mUnit = eCSSUnit_SharedList;
  640. mValue.mSharedList = aList;
  641. mValue.mSharedList->AddRef();
  642. }
  643. void nsCSSValue::SetDependentListValue(nsCSSValueList* aList)
  644. {
  645. Reset();
  646. if (aList) {
  647. mUnit = eCSSUnit_ListDep;
  648. mValue.mListDependent = aList;
  649. }
  650. }
  651. void
  652. nsCSSValue::AdoptListValue(UniquePtr<nsCSSValueList> aValue)
  653. {
  654. // We have to copy the first element since for owned lists the first
  655. // element should be an nsCSSValueList_heap object.
  656. SetListValue();
  657. mValue.mList->mValue = Move(aValue->mValue);
  658. mValue.mList->mNext = aValue->mNext;
  659. aValue->mNext = nullptr;
  660. aValue.reset();
  661. }
  662. nsCSSValuePairList* nsCSSValue::SetPairListValue()
  663. {
  664. Reset();
  665. mUnit = eCSSUnit_PairList;
  666. mValue.mPairList = new nsCSSValuePairList_heap;
  667. mValue.mPairList->AddRef();
  668. return mValue.mPairList;
  669. }
  670. void nsCSSValue::SetDependentPairListValue(nsCSSValuePairList* aList)
  671. {
  672. Reset();
  673. if (aList) {
  674. mUnit = eCSSUnit_PairListDep;
  675. mValue.mPairListDependent = aList;
  676. }
  677. }
  678. void
  679. nsCSSValue::AdoptPairListValue(UniquePtr<nsCSSValuePairList> aValue)
  680. {
  681. // We have to copy the first element, since for owned pair lists, the first
  682. // element should be an nsCSSValuePairList_heap object.
  683. SetPairListValue();
  684. mValue.mPairList->mXValue = Move(aValue->mXValue);
  685. mValue.mPairList->mYValue = Move(aValue->mYValue);
  686. mValue.mPairList->mNext = aValue->mNext;
  687. aValue->mNext = nullptr;
  688. aValue.reset();
  689. }
  690. void nsCSSValue::SetAutoValue()
  691. {
  692. Reset();
  693. mUnit = eCSSUnit_Auto;
  694. }
  695. void nsCSSValue::SetInheritValue()
  696. {
  697. Reset();
  698. mUnit = eCSSUnit_Inherit;
  699. }
  700. void nsCSSValue::SetInitialValue()
  701. {
  702. Reset();
  703. mUnit = eCSSUnit_Initial;
  704. }
  705. void nsCSSValue::SetUnsetValue()
  706. {
  707. Reset();
  708. mUnit = eCSSUnit_Unset;
  709. }
  710. void nsCSSValue::SetNoneValue()
  711. {
  712. Reset();
  713. mUnit = eCSSUnit_None;
  714. }
  715. void nsCSSValue::SetAllValue()
  716. {
  717. Reset();
  718. mUnit = eCSSUnit_All;
  719. }
  720. void nsCSSValue::SetNormalValue()
  721. {
  722. Reset();
  723. mUnit = eCSSUnit_Normal;
  724. }
  725. void nsCSSValue::SetSystemFontValue()
  726. {
  727. Reset();
  728. mUnit = eCSSUnit_System_Font;
  729. }
  730. void nsCSSValue::SetDummyValue()
  731. {
  732. Reset();
  733. mUnit = eCSSUnit_Dummy;
  734. }
  735. void nsCSSValue::SetDummyInheritValue()
  736. {
  737. Reset();
  738. mUnit = eCSSUnit_DummyInherit;
  739. }
  740. void nsCSSValue::SetCalcValue(const nsStyleCoord::CalcValue* aCalc)
  741. {
  742. RefPtr<nsCSSValue::Array> arr = nsCSSValue::Array::Create(1);
  743. if (!aCalc->mHasPercent) {
  744. arr->Item(0).SetIntegerCoordValue(aCalc->mLength);
  745. } else {
  746. nsCSSValue::Array *arr2 = nsCSSValue::Array::Create(2);
  747. arr->Item(0).SetArrayValue(arr2, eCSSUnit_Calc_Plus);
  748. arr2->Item(0).SetIntegerCoordValue(aCalc->mLength);
  749. arr2->Item(1).SetPercentValue(aCalc->mPercent);
  750. }
  751. SetArrayValue(arr, eCSSUnit_Calc);
  752. }
  753. void nsCSSValue::StartImageLoad(nsIDocument* aDocument) const
  754. {
  755. MOZ_ASSERT(eCSSUnit_URL == mUnit, "Not a URL value!");
  756. mozilla::css::ImageValue* image =
  757. new mozilla::css::ImageValue(mValue.mURL->GetURI(),
  758. mValue.mURL->mString,
  759. mValue.mURL->mBaseURI,
  760. mValue.mURL->mReferrer,
  761. mValue.mURL->mOriginPrincipal,
  762. aDocument);
  763. nsCSSValue* writable = const_cast<nsCSSValue*>(this);
  764. writable->SetImageValue(image);
  765. }
  766. nscolor nsCSSValue::GetColorValue() const
  767. {
  768. MOZ_ASSERT(IsNumericColorUnit(), "not a color value");
  769. if (IsFloatColorUnit()) {
  770. return mValue.mFloatColor->GetColorValue(mUnit);
  771. }
  772. return mValue.mColor;
  773. }
  774. bool nsCSSValue::IsNonTransparentColor() const
  775. {
  776. // We have the value in the form it was specified in at this point, so we
  777. // have to look for both the keyword 'transparent' and its equivalent in
  778. // rgba notation.
  779. nsDependentString buf;
  780. return
  781. (IsIntegerColorUnit() && NS_GET_A(GetColorValue()) > 0) ||
  782. (IsFloatColorUnit() && mValue.mFloatColor->IsNonTransparentColor()) ||
  783. (mUnit == eCSSUnit_Ident &&
  784. !nsGkAtoms::transparent->Equals(GetStringValue(buf))) ||
  785. (mUnit == eCSSUnit_EnumColor);
  786. }
  787. nsCSSValue::Array*
  788. nsCSSValue::InitFunction(nsCSSKeyword aFunctionId, uint32_t aNumArgs)
  789. {
  790. RefPtr<nsCSSValue::Array> func = Array::Create(aNumArgs + 1);
  791. func->Item(0).SetIntValue(aFunctionId, eCSSUnit_Enumerated);
  792. SetArrayValue(func, eCSSUnit_Function);
  793. return func;
  794. }
  795. bool
  796. nsCSSValue::EqualsFunction(nsCSSKeyword aFunctionId) const
  797. {
  798. if (mUnit != eCSSUnit_Function) {
  799. return false;
  800. }
  801. nsCSSValue::Array* func = mValue.mArray;
  802. MOZ_ASSERT(func && func->Count() >= 1 &&
  803. func->Item(0).GetUnit() == eCSSUnit_Enumerated,
  804. "illegally structured function value");
  805. nsCSSKeyword thisFunctionId = func->Item(0).GetKeywordValue();
  806. return thisFunctionId == aFunctionId;
  807. }
  808. // static
  809. already_AddRefed<nsStringBuffer>
  810. nsCSSValue::BufferFromString(const nsString& aValue)
  811. {
  812. RefPtr<nsStringBuffer> buffer = nsStringBuffer::FromString(aValue);
  813. if (buffer) {
  814. return buffer.forget();
  815. }
  816. nsString::size_type length = aValue.Length();
  817. // NOTE: Alloc prouduces a new, already-addref'd (refcnt = 1) buffer.
  818. // NOTE: String buffer allocation is currently fallible.
  819. size_t sz = (length + 1) * sizeof(char16_t);
  820. buffer = nsStringBuffer::Alloc(sz);
  821. if (MOZ_UNLIKELY(!buffer)) {
  822. NS_ABORT_OOM(sz);
  823. }
  824. char16_t* data = static_cast<char16_t*>(buffer->Data());
  825. nsCharTraits<char16_t>::copy(data, aValue.get(), length);
  826. // Null-terminate.
  827. data[length] = 0;
  828. return buffer.forget();
  829. }
  830. namespace {
  831. struct CSSValueSerializeCalcOps {
  832. CSSValueSerializeCalcOps(nsCSSPropertyID aProperty, nsAString& aResult,
  833. nsCSSValue::Serialization aSerialization)
  834. : mProperty(aProperty),
  835. mResult(aResult),
  836. mValueSerialization(aSerialization)
  837. {
  838. }
  839. typedef nsCSSValue input_type;
  840. typedef nsCSSValue::Array input_array_type;
  841. static nsCSSUnit GetUnit(const input_type& aValue) {
  842. return aValue.GetUnit();
  843. }
  844. void Append(const char* aString)
  845. {
  846. mResult.AppendASCII(aString);
  847. }
  848. void AppendLeafValue(const input_type& aValue)
  849. {
  850. MOZ_ASSERT(aValue.GetUnit() == eCSSUnit_Percent ||
  851. aValue.IsLengthUnit() ||
  852. aValue.GetUnit() == eCSSUnit_Number,
  853. "unexpected unit");
  854. aValue.AppendToString(mProperty, mResult, mValueSerialization);
  855. }
  856. void AppendNumber(const input_type& aValue)
  857. {
  858. MOZ_ASSERT(aValue.GetUnit() == eCSSUnit_Number, "unexpected unit");
  859. aValue.AppendToString(mProperty, mResult, mValueSerialization);
  860. }
  861. private:
  862. nsCSSPropertyID mProperty;
  863. nsAString &mResult;
  864. nsCSSValue::Serialization mValueSerialization;
  865. };
  866. } // namespace
  867. void
  868. nsCSSValue::AppendPolygonToString(nsCSSPropertyID aProperty, nsAString& aResult,
  869. Serialization aSerialization) const
  870. {
  871. const nsCSSValue::Array* array = GetArrayValue();
  872. MOZ_ASSERT(array->Count() > 1 && array->Count() <= 3,
  873. "Polygons must have name and at least one more value.");
  874. // When the array has 2 elements, the item on index 1 is the coordinate
  875. // pair list.
  876. // When the array has 3 elements, the item on index 1 is a fill-rule
  877. // and item on index 2 is the coordinate pair list.
  878. size_t index = 1;
  879. if (array->Count() == 3) {
  880. const nsCSSValue& fillRuleValue = array->Item(index);
  881. MOZ_ASSERT(fillRuleValue.GetUnit() == eCSSUnit_Enumerated,
  882. "Expected polygon fill rule.");
  883. int32_t fillRule = fillRuleValue.GetIntValue();
  884. AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(fillRule,
  885. nsCSSProps::kFillRuleKTable),
  886. aResult);
  887. aResult.AppendLiteral(", ");
  888. ++index;
  889. }
  890. array->Item(index).AppendToString(aProperty, aResult, aSerialization);
  891. }
  892. inline void
  893. nsCSSValue::AppendPositionCoordinateToString(
  894. const nsCSSValue& aValue, nsCSSPropertyID aProperty,
  895. nsAString& aResult, Serialization aSerialization) const
  896. {
  897. if (aValue.GetUnit() == eCSSUnit_Enumerated) {
  898. int32_t intValue = aValue.GetIntValue();
  899. AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
  900. nsCSSProps::kShapeRadiusKTable), aResult);
  901. } else {
  902. aValue.AppendToString(aProperty, aResult, aSerialization);
  903. }
  904. }
  905. void
  906. nsCSSValue::AppendCircleOrEllipseToString(nsCSSKeyword aFunctionId,
  907. nsCSSPropertyID aProperty,
  908. nsAString& aResult,
  909. Serialization aSerialization) const
  910. {
  911. const nsCSSValue::Array* array = GetArrayValue();
  912. size_t count = aFunctionId == eCSSKeyword_circle ? 2 : 3;
  913. MOZ_ASSERT(array->Count() == count + 1, "wrong number of arguments");
  914. bool hasRadii = array->Item(1).GetUnit() != eCSSUnit_Null;
  915. // closest-side is the default, so we don't need to
  916. // output it if all values are closest-side.
  917. if (array->Item(1).GetUnit() == eCSSUnit_Enumerated &&
  918. array->Item(1).GetIntValue() == NS_RADIUS_CLOSEST_SIDE &&
  919. (aFunctionId == eCSSKeyword_circle ||
  920. (array->Item(2).GetUnit() == eCSSUnit_Enumerated &&
  921. array->Item(2).GetIntValue() == NS_RADIUS_CLOSEST_SIDE))) {
  922. hasRadii = false;
  923. } else {
  924. AppendPositionCoordinateToString(array->Item(1), aProperty,
  925. aResult, aSerialization);
  926. if (hasRadii && aFunctionId == eCSSKeyword_ellipse) {
  927. aResult.Append(' ');
  928. AppendPositionCoordinateToString(array->Item(2), aProperty,
  929. aResult, aSerialization);
  930. }
  931. }
  932. if (hasRadii) {
  933. aResult.Append(' ');
  934. }
  935. // Any position specified?
  936. if (array->Item(count).GetUnit() != eCSSUnit_Array) {
  937. MOZ_ASSERT(array->Item(count).GetUnit() == eCSSUnit_Null,
  938. "unexpected value");
  939. // We only serialize to the 2 or 4 value form
  940. // |circle()| is valid, but should be expanded
  941. // to |circle(at 50% 50%)|
  942. aResult.AppendLiteral("at 50% 50%");
  943. return;
  944. }
  945. aResult.AppendLiteral("at ");
  946. array->Item(count).AppendBasicShapePositionToString(aResult, aSerialization);
  947. }
  948. // https://drafts.csswg.org/css-shapes/#basic-shape-serialization
  949. // basic-shape asks us to omit a lot of redundant things whilst serializing
  950. // position values. Other specs are not clear about this
  951. // (https://github.com/w3c/csswg-drafts/issues/368), so for now we special-case
  952. // basic shapes only
  953. void
  954. nsCSSValue::AppendBasicShapePositionToString(nsAString& aResult,
  955. Serialization aSerialization) const
  956. {
  957. const nsCSSValue::Array* array = GetArrayValue();
  958. // We always parse these into an array of four elements
  959. MOZ_ASSERT(array->Count() == 4,
  960. "basic-shape position value doesn't have enough elements");
  961. const nsCSSValue &xEdge = array->Item(0);
  962. const nsCSSValue &xOffset = array->Item(1);
  963. const nsCSSValue &yEdge = array->Item(2);
  964. const nsCSSValue &yOffset = array->Item(3);
  965. MOZ_ASSERT(xEdge.GetUnit() == eCSSUnit_Enumerated &&
  966. yEdge.GetUnit() == eCSSUnit_Enumerated &&
  967. xOffset.IsLengthPercentCalcUnit() &&
  968. yOffset.IsLengthPercentCalcUnit() &&
  969. xEdge.GetIntValue() != NS_STYLE_IMAGELAYER_POSITION_CENTER &&
  970. yEdge.GetIntValue() != NS_STYLE_IMAGELAYER_POSITION_CENTER,
  971. "Ensure invariants from ParsePositionValueBasicShape "
  972. "haven't been modified");
  973. if (xEdge.GetIntValue() == NS_STYLE_IMAGELAYER_POSITION_LEFT &&
  974. yEdge.GetIntValue() == NS_STYLE_IMAGELAYER_POSITION_TOP) {
  975. // We can omit these defaults
  976. xOffset.AppendToString(eCSSProperty_UNKNOWN, aResult, aSerialization);
  977. aResult.Append(' ');
  978. yOffset.AppendToString(eCSSProperty_UNKNOWN, aResult, aSerialization);
  979. } else {
  980. // We only serialize to the two or four valued form
  981. xEdge.AppendToString(eCSSProperty_object_position, aResult, aSerialization);
  982. aResult.Append(' ');
  983. xOffset.AppendToString(eCSSProperty_UNKNOWN, aResult, aSerialization);
  984. aResult.Append(' ');
  985. yEdge.AppendToString(eCSSProperty_object_position, aResult, aSerialization);
  986. aResult.Append(' ');
  987. yOffset.AppendToString(eCSSProperty_UNKNOWN, aResult, aSerialization);
  988. }
  989. }
  990. // Helper to append |aString| with the shorthand sides notation used in e.g.
  991. // 'padding'. |aProperties| and |aValues| are expected to have 4 elements.
  992. /*static*/ void
  993. nsCSSValue::AppendSidesShorthandToString(const nsCSSPropertyID aProperties[],
  994. const nsCSSValue* aValues[],
  995. nsAString& aString,
  996. nsCSSValue::Serialization
  997. aSerialization)
  998. {
  999. const nsCSSValue& value1 = *aValues[0];
  1000. const nsCSSValue& value2 = *aValues[1];
  1001. const nsCSSValue& value3 = *aValues[2];
  1002. const nsCSSValue& value4 = *aValues[3];
  1003. MOZ_ASSERT(value1.GetUnit() != eCSSUnit_Null, "null value 1");
  1004. value1.AppendToString(aProperties[0], aString, aSerialization);
  1005. if (value1 != value2 || value1 != value3 || value1 != value4) {
  1006. aString.Append(char16_t(' '));
  1007. MOZ_ASSERT(value2.GetUnit() != eCSSUnit_Null, "null value 2");
  1008. value2.AppendToString(aProperties[1], aString, aSerialization);
  1009. if (value1 != value3 || value2 != value4) {
  1010. aString.Append(char16_t(' '));
  1011. MOZ_ASSERT(value3.GetUnit() != eCSSUnit_Null, "null value 3");
  1012. value3.AppendToString(aProperties[2], aString, aSerialization);
  1013. if (value2 != value4) {
  1014. aString.Append(char16_t(' '));
  1015. MOZ_ASSERT(value4.GetUnit() != eCSSUnit_Null, "null value 4");
  1016. value4.AppendToString(aProperties[3], aString, aSerialization);
  1017. }
  1018. }
  1019. }
  1020. }
  1021. /*static*/ void
  1022. nsCSSValue::AppendBasicShapeRadiusToString(const nsCSSPropertyID aProperties[],
  1023. const nsCSSValue* aValues[],
  1024. nsAString& aResult,
  1025. Serialization aSerialization)
  1026. {
  1027. bool needY = false;
  1028. const nsCSSValue* xVals[4];
  1029. const nsCSSValue* yVals[4];
  1030. for (int i = 0; i < 4; i++) {
  1031. if (aValues[i]->GetUnit() == eCSSUnit_Pair) {
  1032. needY = true;
  1033. xVals[i] = &aValues[i]->GetPairValue().mXValue;
  1034. yVals[i] = &aValues[i]->GetPairValue().mYValue;
  1035. } else {
  1036. xVals[i] = yVals[i] = aValues[i];
  1037. }
  1038. }
  1039. AppendSidesShorthandToString(aProperties, xVals, aResult, aSerialization);
  1040. if (needY) {
  1041. aResult.AppendLiteral(" / ");
  1042. AppendSidesShorthandToString(aProperties, yVals, aResult, aSerialization);
  1043. }
  1044. }
  1045. void
  1046. nsCSSValue::AppendInsetToString(nsCSSPropertyID aProperty, nsAString& aResult,
  1047. Serialization aSerialization) const
  1048. {
  1049. const nsCSSValue::Array* array = GetArrayValue();
  1050. MOZ_ASSERT(array->Count() == 6,
  1051. "inset function has wrong number of arguments");
  1052. if (array->Item(1).GetUnit() != eCSSUnit_Null) {
  1053. array->Item(1).AppendToString(aProperty, aResult, aSerialization);
  1054. if (array->Item(2).GetUnit() != eCSSUnit_Null) {
  1055. aResult.Append(' ');
  1056. array->Item(2).AppendToString(aProperty, aResult, aSerialization);
  1057. if (array->Item(3).GetUnit() != eCSSUnit_Null) {
  1058. aResult.Append(' ');
  1059. array->Item(3).AppendToString(aProperty, aResult, aSerialization);
  1060. if (array->Item(4).GetUnit() != eCSSUnit_Null) {
  1061. aResult.Append(' ');
  1062. array->Item(4).AppendToString(aProperty, aResult, aSerialization);
  1063. }
  1064. }
  1065. }
  1066. }
  1067. if (array->Item(5).GetUnit() == eCSSUnit_Array) {
  1068. const nsCSSPropertyID* subprops =
  1069. nsCSSProps::SubpropertyEntryFor(eCSSProperty_border_radius);
  1070. const nsCSSValue::Array* radius = array->Item(5).GetArrayValue();
  1071. MOZ_ASSERT(radius->Count() == 4, "expected 4 radii values");
  1072. const nsCSSValue* vals[4] = {
  1073. &(radius->Item(0)),
  1074. &(radius->Item(1)),
  1075. &(radius->Item(2)),
  1076. &(radius->Item(3))
  1077. };
  1078. aResult.AppendLiteral(" round ");
  1079. AppendBasicShapeRadiusToString(subprops, vals, aResult,
  1080. aSerialization);
  1081. } else {
  1082. MOZ_ASSERT(array->Item(5).GetUnit() == eCSSUnit_Null,
  1083. "unexpected value");
  1084. }
  1085. }
  1086. /* static */ void
  1087. nsCSSValue::AppendAlignJustifyValueToString(int32_t aValue, nsAString& aResult)
  1088. {
  1089. auto legacy = aValue & NS_STYLE_ALIGN_LEGACY;
  1090. if (legacy) {
  1091. aValue &= ~legacy;
  1092. aResult.AppendLiteral("legacy ");
  1093. }
  1094. auto overflowPos = aValue & (NS_STYLE_ALIGN_SAFE | NS_STYLE_ALIGN_UNSAFE);
  1095. aValue &= ~overflowPos;
  1096. MOZ_ASSERT(!(aValue & NS_STYLE_ALIGN_FLAG_BITS),
  1097. "unknown bits in align/justify value");
  1098. MOZ_ASSERT((aValue != NS_STYLE_ALIGN_AUTO &&
  1099. aValue != NS_STYLE_ALIGN_NORMAL &&
  1100. aValue != NS_STYLE_ALIGN_BASELINE &&
  1101. aValue != NS_STYLE_ALIGN_LAST_BASELINE) ||
  1102. (!legacy && !overflowPos),
  1103. "auto/normal/baseline/'last baseline' never have any flags");
  1104. MOZ_ASSERT(legacy == 0 || overflowPos == 0,
  1105. "'legacy' together with <overflow-position>");
  1106. if (aValue == NS_STYLE_ALIGN_LAST_BASELINE) {
  1107. aResult.AppendLiteral("last ");
  1108. aValue = NS_STYLE_ALIGN_BASELINE;
  1109. }
  1110. const auto& kwtable(nsCSSProps::kAlignAllKeywords);
  1111. AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(aValue, kwtable), aResult);
  1112. // Don't serialize the 'unsafe' keyword; it's the default.
  1113. if (MOZ_UNLIKELY(overflowPos == NS_STYLE_ALIGN_SAFE)) {
  1114. aResult.Append(' ');
  1115. AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(overflowPos, kwtable),
  1116. aResult);
  1117. }
  1118. }
  1119. void
  1120. nsCSSValue::AppendToString(nsCSSPropertyID aProperty, nsAString& aResult,
  1121. Serialization aSerialization) const
  1122. {
  1123. // eCSSProperty_UNKNOWN gets used for some recursive calls below.
  1124. MOZ_ASSERT((0 <= aProperty &&
  1125. aProperty <= eCSSProperty_COUNT_no_shorthands) ||
  1126. aProperty == eCSSProperty_UNKNOWN ||
  1127. aProperty == eCSSProperty_DOM,
  1128. "property ID out of range");
  1129. nsCSSUnit unit = GetUnit();
  1130. if (unit == eCSSUnit_Null) {
  1131. return;
  1132. }
  1133. if (eCSSUnit_String <= unit && unit <= eCSSUnit_Attr) {
  1134. if (unit == eCSSUnit_Attr) {
  1135. aResult.AppendLiteral("attr(");
  1136. }
  1137. nsAutoString buffer;
  1138. GetStringValue(buffer);
  1139. if (unit == eCSSUnit_String) {
  1140. nsStyleUtil::AppendEscapedCSSString(buffer, aResult);
  1141. } else {
  1142. nsStyleUtil::AppendEscapedCSSIdent(buffer, aResult);
  1143. }
  1144. }
  1145. else if (eCSSUnit_Array <= unit && unit <= eCSSUnit_Symbols) {
  1146. switch (unit) {
  1147. case eCSSUnit_Counter: aResult.AppendLiteral("counter("); break;
  1148. case eCSSUnit_Counters: aResult.AppendLiteral("counters("); break;
  1149. case eCSSUnit_Cubic_Bezier: aResult.AppendLiteral("cubic-bezier("); break;
  1150. case eCSSUnit_Steps: aResult.AppendLiteral("steps("); break;
  1151. case eCSSUnit_Symbols: aResult.AppendLiteral("symbols("); break;
  1152. default: break;
  1153. }
  1154. nsCSSValue::Array *array = GetArrayValue();
  1155. bool mark = false;
  1156. for (size_t i = 0, i_end = array->Count(); i < i_end; ++i) {
  1157. if (mark && array->Item(i).GetUnit() != eCSSUnit_Null) {
  1158. if ((unit == eCSSUnit_Array &&
  1159. eCSSProperty_transition_timing_function != aProperty) ||
  1160. unit == eCSSUnit_Symbols)
  1161. aResult.Append(' ');
  1162. else if (unit != eCSSUnit_Steps)
  1163. aResult.AppendLiteral(", ");
  1164. }
  1165. if (unit == eCSSUnit_Steps && i == 1) {
  1166. MOZ_ASSERT(array->Item(i).GetUnit() == eCSSUnit_Enumerated,
  1167. "unexpected value");
  1168. int32_t side = array->Item(i).GetIntValue();
  1169. MOZ_ASSERT(side == NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START ||
  1170. side == NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END ||
  1171. side == -1,
  1172. "unexpected value");
  1173. if (side == NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START) {
  1174. aResult.AppendLiteral(", start");
  1175. } else if (side == NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END) {
  1176. aResult.AppendLiteral(", end");
  1177. }
  1178. continue;
  1179. }
  1180. if (unit == eCSSUnit_Symbols && i == 0) {
  1181. MOZ_ASSERT(array->Item(i).GetUnit() == eCSSUnit_Enumerated,
  1182. "unexpected value");
  1183. int32_t system = array->Item(i).GetIntValue();
  1184. if (system != NS_STYLE_COUNTER_SYSTEM_SYMBOLIC) {
  1185. AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(
  1186. system, nsCSSProps::kCounterSystemKTable), aResult);
  1187. mark = true;
  1188. }
  1189. continue;
  1190. }
  1191. nsCSSPropertyID prop =
  1192. ((eCSSUnit_Counter <= unit && unit <= eCSSUnit_Counters) &&
  1193. i == array->Count() - 1)
  1194. ? eCSSProperty_list_style_type : aProperty;
  1195. if (array->Item(i).GetUnit() != eCSSUnit_Null) {
  1196. array->Item(i).AppendToString(prop, aResult, aSerialization);
  1197. mark = true;
  1198. }
  1199. }
  1200. if (eCSSUnit_Array == unit &&
  1201. aProperty == eCSSProperty_transition_timing_function) {
  1202. aResult.Append(')');
  1203. }
  1204. }
  1205. /* Although Function is backed by an Array, we'll handle it separately
  1206. * because it's a bit quirky.
  1207. */
  1208. else if (eCSSUnit_Function == unit) {
  1209. const nsCSSValue::Array* array = GetArrayValue();
  1210. MOZ_ASSERT(array->Count() >= 1,
  1211. "Functions must have at least one element for the name.");
  1212. const nsCSSValue& functionName = array->Item(0);
  1213. MOZ_ASSERT(functionName.GetUnit() == eCSSUnit_Enumerated,
  1214. "Functions must have an enumerated name.");
  1215. // The first argument is always of nsCSSKeyword type.
  1216. const nsCSSKeyword functionId = functionName.GetKeywordValue();
  1217. // minmax(auto, <flex>) is equivalent to (and is our internal representation
  1218. // of) <flex>, and both are serialized as <flex>
  1219. if (functionId == eCSSKeyword_minmax &&
  1220. array->Count() == 3 &&
  1221. array->Item(1).GetUnit() == eCSSUnit_Auto &&
  1222. array->Item(2).GetUnit() == eCSSUnit_FlexFraction) {
  1223. array->Item(2).AppendToString(aProperty, aResult, aSerialization);
  1224. MOZ_ASSERT(aProperty == eCSSProperty_grid_template_columns ||
  1225. aProperty == eCSSProperty_grid_template_rows ||
  1226. aProperty == eCSSProperty_grid_auto_columns ||
  1227. aProperty == eCSSProperty_grid_auto_rows);
  1228. return;
  1229. }
  1230. /* Append the function name. */
  1231. NS_ConvertASCIItoUTF16 ident(nsCSSKeywords::GetStringValue(functionId));
  1232. // Bug 721136: Normalize the identifier to lowercase, except that things
  1233. // like scaleX should have the last character capitalized. This matches
  1234. // what other browsers do.
  1235. switch (functionId) {
  1236. case eCSSKeyword_rotatex:
  1237. case eCSSKeyword_scalex:
  1238. case eCSSKeyword_skewx:
  1239. case eCSSKeyword_translatex:
  1240. ident.Replace(ident.Length() - 1, 1, char16_t('X'));
  1241. break;
  1242. case eCSSKeyword_rotatey:
  1243. case eCSSKeyword_scaley:
  1244. case eCSSKeyword_skewy:
  1245. case eCSSKeyword_translatey:
  1246. ident.Replace(ident.Length() - 1, 1, char16_t('Y'));
  1247. break;
  1248. case eCSSKeyword_rotatez:
  1249. case eCSSKeyword_scalez:
  1250. case eCSSKeyword_translatez:
  1251. ident.Replace(ident.Length() - 1, 1, char16_t('Z'));
  1252. break;
  1253. default:
  1254. break;
  1255. }
  1256. nsStyleUtil::AppendEscapedCSSIdent(ident, aResult);
  1257. aResult.Append('(');
  1258. switch (functionId) {
  1259. case eCSSKeyword_polygon:
  1260. AppendPolygonToString(aProperty, aResult, aSerialization);
  1261. break;
  1262. case eCSSKeyword_circle:
  1263. case eCSSKeyword_ellipse:
  1264. AppendCircleOrEllipseToString(functionId, aProperty, aResult,
  1265. aSerialization);
  1266. break;
  1267. case eCSSKeyword_inset:
  1268. AppendInsetToString(aProperty, aResult, aSerialization);
  1269. break;
  1270. default: {
  1271. // Now, step through the function contents, writing each of
  1272. // them as we go.
  1273. for (size_t index = 1; index < array->Count(); ++index) {
  1274. array->Item(index).AppendToString(aProperty, aResult,
  1275. aSerialization);
  1276. /* If we're not at the final element, append a comma. */
  1277. if (index + 1 != array->Count())
  1278. aResult.AppendLiteral(", ");
  1279. }
  1280. }
  1281. }
  1282. /* Finally, append the closing parenthesis. */
  1283. aResult.Append(')');
  1284. }
  1285. else if (IsCalcUnit()) {
  1286. MOZ_ASSERT(GetUnit() == eCSSUnit_Calc, "unexpected unit");
  1287. CSSValueSerializeCalcOps ops(aProperty, aResult, aSerialization);
  1288. css::SerializeCalc(*this, ops);
  1289. }
  1290. else if (eCSSUnit_Integer == unit) {
  1291. aResult.AppendInt(GetIntValue(), 10);
  1292. }
  1293. else if (eCSSUnit_Enumerated == unit) {
  1294. int32_t intValue = GetIntValue();
  1295. switch(aProperty) {
  1296. case eCSSProperty_text_combine_upright:
  1297. if (intValue <= NS_STYLE_TEXT_COMBINE_UPRIGHT_ALL) {
  1298. AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue),
  1299. aResult);
  1300. } else if (intValue == NS_STYLE_TEXT_COMBINE_UPRIGHT_DIGITS_2) {
  1301. aResult.AppendLiteral("digits 2");
  1302. } else if (intValue == NS_STYLE_TEXT_COMBINE_UPRIGHT_DIGITS_3) {
  1303. aResult.AppendLiteral("digits 3");
  1304. } else {
  1305. aResult.AppendLiteral("digits 4");
  1306. }
  1307. break;
  1308. case eCSSProperty_text_decoration_line:
  1309. if (NS_STYLE_TEXT_DECORATION_LINE_NONE == intValue) {
  1310. AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue),
  1311. aResult);
  1312. } else {
  1313. // Ignore the "override all" internal value.
  1314. // (It doesn't have a string representation.)
  1315. intValue &= ~NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL;
  1316. nsStyleUtil::AppendBitmaskCSSValue(
  1317. aProperty, intValue,
  1318. NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE,
  1319. NS_STYLE_TEXT_DECORATION_LINE_PREF_ANCHORS,
  1320. aResult);
  1321. }
  1322. break;
  1323. case eCSSProperty_paint_order:
  1324. static_assert
  1325. (NS_STYLE_PAINT_ORDER_BITWIDTH * NS_STYLE_PAINT_ORDER_LAST_VALUE <= 8,
  1326. "SVGStyleStruct::mPaintOrder and the following cast not big enough");
  1327. nsStyleUtil::AppendPaintOrderValue(static_cast<uint8_t>(GetIntValue()),
  1328. aResult);
  1329. break;
  1330. case eCSSProperty_font_synthesis:
  1331. nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
  1332. NS_FONT_SYNTHESIS_WEIGHT,
  1333. NS_FONT_SYNTHESIS_STYLE,
  1334. aResult);
  1335. break;
  1336. case eCSSProperty_font_variant_east_asian:
  1337. nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
  1338. NS_FONT_VARIANT_EAST_ASIAN_JIS78,
  1339. NS_FONT_VARIANT_EAST_ASIAN_RUBY,
  1340. aResult);
  1341. break;
  1342. case eCSSProperty_font_variant_ligatures:
  1343. nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
  1344. NS_FONT_VARIANT_LIGATURES_NONE,
  1345. NS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL,
  1346. aResult);
  1347. break;
  1348. case eCSSProperty_font_variant_numeric:
  1349. nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
  1350. NS_FONT_VARIANT_NUMERIC_LINING,
  1351. NS_FONT_VARIANT_NUMERIC_ORDINAL,
  1352. aResult);
  1353. break;
  1354. case eCSSProperty_grid_auto_flow:
  1355. nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
  1356. NS_STYLE_GRID_AUTO_FLOW_ROW,
  1357. NS_STYLE_GRID_AUTO_FLOW_DENSE,
  1358. aResult);
  1359. break;
  1360. case eCSSProperty_grid_column_start:
  1361. case eCSSProperty_grid_column_end:
  1362. case eCSSProperty_grid_row_start:
  1363. case eCSSProperty_grid_row_end:
  1364. // "span" is the only enumerated-unit value for these properties
  1365. aResult.AppendLiteral("span");
  1366. break;
  1367. case eCSSProperty_touch_action:
  1368. nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
  1369. NS_STYLE_TOUCH_ACTION_NONE,
  1370. NS_STYLE_TOUCH_ACTION_MANIPULATION,
  1371. aResult);
  1372. break;
  1373. case eCSSProperty_clip_path:
  1374. AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
  1375. nsCSSProps::kClipPathGeometryBoxKTable),
  1376. aResult);
  1377. break;
  1378. case eCSSProperty_shape_outside:
  1379. AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
  1380. nsCSSProps::kShapeOutsideShapeBoxKTable),
  1381. aResult);
  1382. break;
  1383. case eCSSProperty_contain:
  1384. if (intValue & NS_STYLE_CONTAIN_STRICT) {
  1385. NS_ASSERTION(intValue == (NS_STYLE_CONTAIN_STRICT | NS_STYLE_CONTAIN_ALL_BITS),
  1386. "contain: strict should imply contain: layout style paint");
  1387. // Only output strict.
  1388. intValue = NS_STYLE_CONTAIN_STRICT;
  1389. }
  1390. nsStyleUtil::AppendBitmaskCSSValue(aProperty,
  1391. intValue,
  1392. NS_STYLE_CONTAIN_STRICT,
  1393. NS_STYLE_CONTAIN_PAINT,
  1394. aResult);
  1395. break;
  1396. case eCSSProperty_align_content:
  1397. case eCSSProperty_justify_content: {
  1398. AppendAlignJustifyValueToString(intValue & NS_STYLE_ALIGN_ALL_BITS, aResult);
  1399. auto fallback = intValue >> NS_STYLE_ALIGN_ALL_SHIFT;
  1400. if (fallback) {
  1401. MOZ_ASSERT(nsCSSProps::ValueToKeywordEnum(fallback & ~NS_STYLE_ALIGN_FLAG_BITS,
  1402. nsCSSProps::kAlignSelfPosition)
  1403. != eCSSKeyword_UNKNOWN, "unknown fallback value");
  1404. aResult.Append(' ');
  1405. AppendAlignJustifyValueToString(fallback, aResult);
  1406. }
  1407. break;
  1408. }
  1409. case eCSSProperty_align_items:
  1410. case eCSSProperty_align_self:
  1411. case eCSSProperty_justify_items:
  1412. case eCSSProperty_justify_self:
  1413. AppendAlignJustifyValueToString(intValue, aResult);
  1414. break;
  1415. case eCSSProperty_text_emphasis_position: {
  1416. nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
  1417. NS_STYLE_TEXT_EMPHASIS_POSITION_OVER,
  1418. NS_STYLE_TEXT_EMPHASIS_POSITION_RIGHT,
  1419. aResult);
  1420. break;
  1421. }
  1422. case eCSSProperty_text_emphasis_style: {
  1423. auto fill = intValue & NS_STYLE_TEXT_EMPHASIS_STYLE_FILL_MASK;
  1424. AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(
  1425. fill, nsCSSProps::kTextEmphasisStyleFillKTable), aResult);
  1426. aResult.Append(' ');
  1427. auto shape = intValue & NS_STYLE_TEXT_EMPHASIS_STYLE_SHAPE_MASK;
  1428. AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(
  1429. shape, nsCSSProps::kTextEmphasisStyleShapeKTable), aResult);
  1430. break;
  1431. }
  1432. default:
  1433. const nsAFlatCString& name = nsCSSProps::LookupPropertyValue(aProperty, intValue);
  1434. AppendASCIItoUTF16(name, aResult);
  1435. break;
  1436. }
  1437. }
  1438. else if (eCSSUnit_EnumColor == unit) {
  1439. // we can lookup the property in the ColorTable and then
  1440. // get a string mapping the name
  1441. nsAutoCString str;
  1442. if (nsCSSProps::GetColorName(GetIntValue(), str)){
  1443. AppendASCIItoUTF16(str, aResult);
  1444. } else {
  1445. MOZ_ASSERT(false, "bad color value");
  1446. }
  1447. }
  1448. else if (IsNumericColorUnit(unit)) {
  1449. if (aSerialization == eNormalized ||
  1450. unit == eCSSUnit_RGBColor ||
  1451. unit == eCSSUnit_RGBAColor) {
  1452. nscolor color = GetColorValue();
  1453. if (aSerialization == eNormalized &&
  1454. color == NS_RGBA(0, 0, 0, 0)) {
  1455. // Use the strictest match for 'transparent' so we do correct
  1456. // round-tripping of all other rgba() values.
  1457. aResult.AppendLiteral("transparent");
  1458. } else {
  1459. // For brevity, we omit the alpha component if it's equal to 255 (full
  1460. // opaque). Also, we use "rgba" rather than "rgb" when the color includes
  1461. // the non-opaque alpha value, for backwards-compat (even though they're
  1462. // aliases as of css-color-4).
  1463. // e.g.:
  1464. // rgba(1, 2, 3, 1.0) => rgb(1, 2, 3)
  1465. // rgba(1, 2, 3, 0.5) => rgba(1, 2, 3, 0.5)
  1466. uint8_t a = NS_GET_A(color);
  1467. bool showAlpha = (a != 255);
  1468. if (showAlpha) {
  1469. aResult.AppendLiteral("rgba(");
  1470. } else {
  1471. aResult.AppendLiteral("rgb(");
  1472. }
  1473. NS_NAMED_LITERAL_STRING(comma, ", ");
  1474. aResult.AppendInt(NS_GET_R(color), 10);
  1475. aResult.Append(comma);
  1476. aResult.AppendInt(NS_GET_G(color), 10);
  1477. aResult.Append(comma);
  1478. aResult.AppendInt(NS_GET_B(color), 10);
  1479. if (showAlpha) {
  1480. aResult.Append(comma);
  1481. aResult.AppendFloat(nsStyleUtil::ColorComponentToFloat(a));
  1482. }
  1483. aResult.Append(char16_t(')'));
  1484. }
  1485. } else if (eCSSUnit_HexColor == unit ||
  1486. eCSSUnit_HexColorAlpha == unit) {
  1487. nscolor color = GetColorValue();
  1488. aResult.Append('#');
  1489. aResult.AppendPrintf("%02x", NS_GET_R(color));
  1490. aResult.AppendPrintf("%02x", NS_GET_G(color));
  1491. aResult.AppendPrintf("%02x", NS_GET_B(color));
  1492. if (eCSSUnit_HexColorAlpha == unit) {
  1493. aResult.AppendPrintf("%02x", NS_GET_A(color));
  1494. }
  1495. } else if (eCSSUnit_ShortHexColor == unit ||
  1496. eCSSUnit_ShortHexColorAlpha == unit) {
  1497. nscolor color = GetColorValue();
  1498. aResult.Append('#');
  1499. aResult.AppendInt(NS_GET_R(color) / 0x11, 16);
  1500. aResult.AppendInt(NS_GET_G(color) / 0x11, 16);
  1501. aResult.AppendInt(NS_GET_B(color) / 0x11, 16);
  1502. if (eCSSUnit_ShortHexColorAlpha == unit) {
  1503. aResult.AppendInt(NS_GET_A(color) / 0x11, 16);
  1504. }
  1505. } else {
  1506. MOZ_ASSERT(IsFloatColorUnit());
  1507. mValue.mFloatColor->AppendToString(unit, aResult);
  1508. }
  1509. }
  1510. else if (eCSSUnit_ComplexColor == unit) {
  1511. StyleComplexColor color = GetStyleComplexColorValue();
  1512. nsCSSValue serializable;
  1513. if (color.IsCurrentColor()) {
  1514. serializable.SetIntValue(NS_COLOR_CURRENTCOLOR, eCSSUnit_EnumColor);
  1515. } else if (color.IsNumericColor()) {
  1516. serializable.SetColorValue(color.mColor);
  1517. } else {
  1518. MOZ_ASSERT_UNREACHABLE("Cannot serialize a complex color");
  1519. }
  1520. serializable.AppendToString(aProperty, aResult, aSerialization);
  1521. }
  1522. else if (eCSSUnit_URL == unit || eCSSUnit_Image == unit) {
  1523. aResult.AppendLiteral("url(");
  1524. nsStyleUtil::AppendEscapedCSSString(
  1525. nsDependentString(GetOriginalURLValue()), aResult);
  1526. aResult.Append(')');
  1527. }
  1528. else if (eCSSUnit_Element == unit) {
  1529. aResult.AppendLiteral("-moz-element(#");
  1530. nsAutoString tmpStr;
  1531. GetStringValue(tmpStr);
  1532. nsStyleUtil::AppendEscapedCSSIdent(tmpStr, aResult);
  1533. aResult.Append(')');
  1534. }
  1535. else if (eCSSUnit_Percent == unit) {
  1536. aResult.AppendFloat(GetPercentValue() * 100.0f);
  1537. }
  1538. else if (eCSSUnit_Percent < unit) { // length unit
  1539. aResult.AppendFloat(GetFloatValue());
  1540. }
  1541. else if (eCSSUnit_Gradient == unit) {
  1542. nsCSSValueGradient* gradient = GetGradientValue();
  1543. if (gradient->mIsLegacySyntax) {
  1544. aResult.AppendLiteral("-moz-");
  1545. }
  1546. if (gradient->mIsRepeating) {
  1547. aResult.AppendLiteral("repeating-");
  1548. }
  1549. if (gradient->mIsRadial) {
  1550. aResult.AppendLiteral("radial-gradient(");
  1551. } else {
  1552. aResult.AppendLiteral("linear-gradient(");
  1553. }
  1554. bool needSep = false;
  1555. if (gradient->mIsRadial && !gradient->mIsLegacySyntax) {
  1556. if (!gradient->mIsExplicitSize) {
  1557. if (gradient->GetRadialShape().GetUnit() != eCSSUnit_None) {
  1558. MOZ_ASSERT(gradient->GetRadialShape().GetUnit() ==
  1559. eCSSUnit_Enumerated,
  1560. "bad unit for radial gradient shape");
  1561. int32_t intValue = gradient->GetRadialShape().GetIntValue();
  1562. MOZ_ASSERT(intValue != NS_STYLE_GRADIENT_SHAPE_LINEAR,
  1563. "radial gradient with linear shape?!");
  1564. AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
  1565. nsCSSProps::kRadialGradientShapeKTable),
  1566. aResult);
  1567. needSep = true;
  1568. }
  1569. if (gradient->GetRadialSize().GetUnit() != eCSSUnit_None) {
  1570. if (needSep) {
  1571. aResult.Append(' ');
  1572. }
  1573. MOZ_ASSERT(gradient->GetRadialSize().GetUnit() == eCSSUnit_Enumerated,
  1574. "bad unit for radial gradient size");
  1575. int32_t intValue = gradient->GetRadialSize().GetIntValue();
  1576. AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
  1577. nsCSSProps::kRadialGradientSizeKTable),
  1578. aResult);
  1579. needSep = true;
  1580. }
  1581. } else {
  1582. MOZ_ASSERT(gradient->GetRadiusX().GetUnit() != eCSSUnit_None,
  1583. "bad unit for radial gradient explicit size");
  1584. gradient->GetRadiusX().AppendToString(aProperty, aResult,
  1585. aSerialization);
  1586. if (gradient->GetRadiusY().GetUnit() != eCSSUnit_None) {
  1587. aResult.Append(' ');
  1588. gradient->GetRadiusY().AppendToString(aProperty, aResult,
  1589. aSerialization);
  1590. }
  1591. needSep = true;
  1592. }
  1593. }
  1594. if (!gradient->mIsRadial && !gradient->mIsLegacySyntax) {
  1595. if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None ||
  1596. gradient->mBgPos.mYValue.GetUnit() != eCSSUnit_None) {
  1597. MOZ_ASSERT(gradient->mAngle.GetUnit() == eCSSUnit_None);
  1598. MOZ_ASSERT(gradient->mBgPos.mXValue.GetUnit() == eCSSUnit_Enumerated &&
  1599. gradient->mBgPos.mYValue.GetUnit() == eCSSUnit_Enumerated,
  1600. "unexpected unit");
  1601. aResult.AppendLiteral("to");
  1602. if (!(gradient->mBgPos.mXValue.GetIntValue() & NS_STYLE_IMAGELAYER_POSITION_CENTER)) {
  1603. aResult.Append(' ');
  1604. gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position_x,
  1605. aResult, aSerialization);
  1606. }
  1607. if (!(gradient->mBgPos.mYValue.GetIntValue() & NS_STYLE_IMAGELAYER_POSITION_CENTER)) {
  1608. aResult.Append(' ');
  1609. gradient->mBgPos.mYValue.AppendToString(eCSSProperty_background_position_y,
  1610. aResult, aSerialization);
  1611. }
  1612. needSep = true;
  1613. } else if (gradient->mAngle.GetUnit() != eCSSUnit_None) {
  1614. gradient->mAngle.AppendToString(aProperty, aResult, aSerialization);
  1615. needSep = true;
  1616. }
  1617. } else if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None ||
  1618. gradient->mBgPos.mYValue.GetUnit() != eCSSUnit_None ||
  1619. gradient->mAngle.GetUnit() != eCSSUnit_None) {
  1620. if (needSep) {
  1621. aResult.Append(' ');
  1622. }
  1623. if (gradient->mIsRadial && !gradient->mIsLegacySyntax) {
  1624. aResult.AppendLiteral("at ");
  1625. }
  1626. if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None) {
  1627. gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position_x,
  1628. aResult, aSerialization);
  1629. aResult.Append(' ');
  1630. }
  1631. if (gradient->mBgPos.mYValue.GetUnit() != eCSSUnit_None) {
  1632. gradient->mBgPos.mYValue.AppendToString(eCSSProperty_background_position_y,
  1633. aResult, aSerialization);
  1634. aResult.Append(' ');
  1635. }
  1636. if (gradient->mAngle.GetUnit() != eCSSUnit_None) {
  1637. MOZ_ASSERT(gradient->mIsLegacySyntax,
  1638. "angle is allowed only for legacy syntax");
  1639. gradient->mAngle.AppendToString(aProperty, aResult, aSerialization);
  1640. }
  1641. needSep = true;
  1642. }
  1643. if (gradient->mIsRadial && gradient->mIsLegacySyntax &&
  1644. (gradient->GetRadialShape().GetUnit() != eCSSUnit_None ||
  1645. gradient->GetRadialSize().GetUnit() != eCSSUnit_None)) {
  1646. MOZ_ASSERT(!gradient->mIsExplicitSize);
  1647. if (needSep) {
  1648. aResult.AppendLiteral(", ");
  1649. }
  1650. if (gradient->GetRadialShape().GetUnit() != eCSSUnit_None) {
  1651. MOZ_ASSERT(gradient->GetRadialShape().GetUnit() == eCSSUnit_Enumerated,
  1652. "bad unit for radial gradient shape");
  1653. int32_t intValue = gradient->GetRadialShape().GetIntValue();
  1654. MOZ_ASSERT(intValue != NS_STYLE_GRADIENT_SHAPE_LINEAR,
  1655. "radial gradient with linear shape?!");
  1656. AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
  1657. nsCSSProps::kRadialGradientShapeKTable),
  1658. aResult);
  1659. aResult.Append(' ');
  1660. }
  1661. if (gradient->GetRadialSize().GetUnit() != eCSSUnit_None) {
  1662. MOZ_ASSERT(gradient->GetRadialSize().GetUnit() == eCSSUnit_Enumerated,
  1663. "bad unit for radial gradient size");
  1664. int32_t intValue = gradient->GetRadialSize().GetIntValue();
  1665. AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
  1666. nsCSSProps::kRadialGradientSizeKTable),
  1667. aResult);
  1668. }
  1669. needSep = true;
  1670. }
  1671. if (needSep) {
  1672. aResult.AppendLiteral(", ");
  1673. }
  1674. for (uint32_t i = 0 ;;) {
  1675. bool isInterpolationHint = gradient->mStops[i].mIsInterpolationHint;
  1676. if (!isInterpolationHint) {
  1677. gradient->mStops[i].mColor.AppendToString(aProperty, aResult,
  1678. aSerialization);
  1679. }
  1680. if (gradient->mStops[i].mLocation.GetUnit() != eCSSUnit_None) {
  1681. if (!isInterpolationHint) {
  1682. aResult.Append(' ');
  1683. }
  1684. gradient->mStops[i].mLocation.AppendToString(aProperty, aResult,
  1685. aSerialization);
  1686. }
  1687. if (++i == gradient->mStops.Length()) {
  1688. break;
  1689. }
  1690. aResult.AppendLiteral(", ");
  1691. }
  1692. aResult.Append(')');
  1693. } else if (eCSSUnit_TokenStream == unit) {
  1694. nsCSSPropertyID shorthand = mValue.mTokenStream->mShorthandPropertyID;
  1695. if (shorthand == eCSSProperty_UNKNOWN ||
  1696. nsCSSProps::PropHasFlags(shorthand, CSS_PROPERTY_IS_ALIAS) ||
  1697. aProperty == eCSSProperty__x_system_font) {
  1698. // We treat serialization of aliases like '-moz-transform' as a special
  1699. // case, since it really wants to be serialized as if it were a longhand
  1700. // even though it is implemented as a shorthand. We also need to
  1701. // serialize -x-system-font's token stream value, even though the
  1702. // value is set through the font shorthand. This serialization
  1703. // of -x-system-font is needed when we need to output the
  1704. // 'font' shorthand followed by a number of overriding font
  1705. // longhand components.
  1706. aResult.Append(mValue.mTokenStream->mTokenStream);
  1707. }
  1708. } else if (eCSSUnit_Pair == unit) {
  1709. if (eCSSProperty_font_variant_alternates == aProperty) {
  1710. int32_t intValue = GetPairValue().mXValue.GetIntValue();
  1711. nsAutoString out;
  1712. // simple, enumerated values
  1713. nsStyleUtil::AppendBitmaskCSSValue(aProperty,
  1714. intValue & NS_FONT_VARIANT_ALTERNATES_ENUMERATED_MASK,
  1715. NS_FONT_VARIANT_ALTERNATES_HISTORICAL,
  1716. NS_FONT_VARIANT_ALTERNATES_HISTORICAL,
  1717. out);
  1718. // functional values
  1719. const nsCSSValueList *list = GetPairValue().mYValue.GetListValue();
  1720. AutoTArray<gfxAlternateValue,8> altValues;
  1721. nsStyleUtil::ComputeFunctionalAlternates(list, altValues);
  1722. nsStyleUtil::SerializeFunctionalAlternates(altValues, out);
  1723. aResult.Append(out);
  1724. } else {
  1725. GetPairValue().AppendToString(aProperty, aResult, aSerialization);
  1726. }
  1727. } else if (eCSSUnit_Triplet == unit) {
  1728. GetTripletValue().AppendToString(aProperty, aResult, aSerialization);
  1729. } else if (eCSSUnit_Rect == unit) {
  1730. GetRectValue().AppendToString(aProperty, aResult, aSerialization);
  1731. } else if (eCSSUnit_List == unit || eCSSUnit_ListDep == unit) {
  1732. GetListValue()->AppendToString(aProperty, aResult, aSerialization);
  1733. } else if (eCSSUnit_SharedList == unit) {
  1734. GetSharedListValue()->AppendToString(aProperty, aResult, aSerialization);
  1735. } else if (eCSSUnit_PairList == unit || eCSSUnit_PairListDep == unit) {
  1736. switch (aProperty) {
  1737. case eCSSProperty_font_feature_settings:
  1738. nsStyleUtil::AppendFontFeatureSettings(*this, aResult);
  1739. break;
  1740. default:
  1741. GetPairListValue()->AppendToString(aProperty, aResult, aSerialization);
  1742. break;
  1743. }
  1744. } else if (eCSSUnit_GridTemplateAreas == unit) {
  1745. const mozilla::css::GridTemplateAreasValue* areas = GetGridTemplateAreas();
  1746. MOZ_ASSERT(!areas->mTemplates.IsEmpty(),
  1747. "Unexpected empty array in GridTemplateAreasValue");
  1748. nsStyleUtil::AppendEscapedCSSString(areas->mTemplates[0], aResult);
  1749. for (uint32_t i = 1; i < areas->mTemplates.Length(); i++) {
  1750. aResult.Append(char16_t(' '));
  1751. nsStyleUtil::AppendEscapedCSSString(areas->mTemplates[i], aResult);
  1752. }
  1753. } else if (eCSSUnit_FontFamilyList == unit) {
  1754. nsStyleUtil::AppendEscapedCSSFontFamilyList(*mValue.mFontFamilyList,
  1755. aResult);
  1756. }
  1757. switch (unit) {
  1758. case eCSSUnit_Null: break;
  1759. case eCSSUnit_Auto: aResult.AppendLiteral("auto"); break;
  1760. case eCSSUnit_Inherit: aResult.AppendLiteral("inherit"); break;
  1761. case eCSSUnit_Initial: aResult.AppendLiteral("initial"); break;
  1762. case eCSSUnit_Unset: aResult.AppendLiteral("unset"); break;
  1763. case eCSSUnit_None: aResult.AppendLiteral("none"); break;
  1764. case eCSSUnit_Normal: aResult.AppendLiteral("normal"); break;
  1765. case eCSSUnit_System_Font: aResult.AppendLiteral("-moz-use-system-font"); break;
  1766. case eCSSUnit_All: aResult.AppendLiteral("all"); break;
  1767. case eCSSUnit_Dummy:
  1768. case eCSSUnit_DummyInherit:
  1769. MOZ_ASSERT(false, "should never serialize");
  1770. break;
  1771. case eCSSUnit_FontFamilyList: break;
  1772. case eCSSUnit_String: break;
  1773. case eCSSUnit_Ident: break;
  1774. case eCSSUnit_URL: break;
  1775. case eCSSUnit_Image: break;
  1776. case eCSSUnit_Element: break;
  1777. case eCSSUnit_Array: break;
  1778. case eCSSUnit_Attr:
  1779. case eCSSUnit_Cubic_Bezier:
  1780. case eCSSUnit_Steps:
  1781. case eCSSUnit_Symbols:
  1782. case eCSSUnit_Counter:
  1783. case eCSSUnit_Counters: aResult.Append(char16_t(')')); break;
  1784. case eCSSUnit_Local_Font: break;
  1785. case eCSSUnit_Font_Format: break;
  1786. case eCSSUnit_Function: break;
  1787. case eCSSUnit_Calc: break;
  1788. case eCSSUnit_Calc_Plus: break;
  1789. case eCSSUnit_Calc_Minus: break;
  1790. case eCSSUnit_Calc_Times_L: break;
  1791. case eCSSUnit_Calc_Times_R: break;
  1792. case eCSSUnit_Calc_Divided: break;
  1793. case eCSSUnit_Integer: break;
  1794. case eCSSUnit_Enumerated: break;
  1795. case eCSSUnit_EnumColor: break;
  1796. case eCSSUnit_RGBColor: break;
  1797. case eCSSUnit_RGBAColor: break;
  1798. case eCSSUnit_HexColor: break;
  1799. case eCSSUnit_ShortHexColor: break;
  1800. case eCSSUnit_HexColorAlpha: break;
  1801. case eCSSUnit_ShortHexColorAlpha: break;
  1802. case eCSSUnit_PercentageRGBColor: break;
  1803. case eCSSUnit_PercentageRGBAColor: break;
  1804. case eCSSUnit_HSLColor: break;
  1805. case eCSSUnit_HSLAColor: break;
  1806. case eCSSUnit_ComplexColor: break;
  1807. case eCSSUnit_Percent: aResult.Append(char16_t('%')); break;
  1808. case eCSSUnit_Number: break;
  1809. case eCSSUnit_Gradient: break;
  1810. case eCSSUnit_TokenStream: break;
  1811. case eCSSUnit_Pair: break;
  1812. case eCSSUnit_Triplet: break;
  1813. case eCSSUnit_Rect: break;
  1814. case eCSSUnit_List: break;
  1815. case eCSSUnit_ListDep: break;
  1816. case eCSSUnit_SharedList: break;
  1817. case eCSSUnit_PairList: break;
  1818. case eCSSUnit_PairListDep: break;
  1819. case eCSSUnit_GridTemplateAreas: break;
  1820. case eCSSUnit_Inch: aResult.AppendLiteral("in"); break;
  1821. case eCSSUnit_Millimeter: aResult.AppendLiteral("mm"); break;
  1822. case eCSSUnit_PhysicalMillimeter: aResult.AppendLiteral("mozmm"); break;
  1823. case eCSSUnit_Centimeter: aResult.AppendLiteral("cm"); break;
  1824. case eCSSUnit_Point: aResult.AppendLiteral("pt"); break;
  1825. case eCSSUnit_Pica: aResult.AppendLiteral("pc"); break;
  1826. case eCSSUnit_Quarter: aResult.AppendLiteral("q"); break;
  1827. case eCSSUnit_ViewportWidth: aResult.AppendLiteral("vw"); break;
  1828. case eCSSUnit_ViewportHeight: aResult.AppendLiteral("vh"); break;
  1829. case eCSSUnit_ViewportMin: aResult.AppendLiteral("vmin"); break;
  1830. case eCSSUnit_ViewportMax: aResult.AppendLiteral("vmax"); break;
  1831. case eCSSUnit_EM: aResult.AppendLiteral("em"); break;
  1832. case eCSSUnit_XHeight: aResult.AppendLiteral("ex"); break;
  1833. case eCSSUnit_Char: aResult.AppendLiteral("ch"); break;
  1834. case eCSSUnit_RootEM: aResult.AppendLiteral("rem"); break;
  1835. case eCSSUnit_Pixel: aResult.AppendLiteral("px"); break;
  1836. case eCSSUnit_Degree: aResult.AppendLiteral("deg"); break;
  1837. case eCSSUnit_Grad: aResult.AppendLiteral("grad"); break;
  1838. case eCSSUnit_Radian: aResult.AppendLiteral("rad"); break;
  1839. case eCSSUnit_Turn: aResult.AppendLiteral("turn"); break;
  1840. case eCSSUnit_Hertz: aResult.AppendLiteral("Hz"); break;
  1841. case eCSSUnit_Kilohertz: aResult.AppendLiteral("kHz"); break;
  1842. case eCSSUnit_Seconds: aResult.Append(char16_t('s')); break;
  1843. case eCSSUnit_Milliseconds: aResult.AppendLiteral("ms"); break;
  1844. case eCSSUnit_FlexFraction: aResult.AppendLiteral("fr"); break;
  1845. }
  1846. }
  1847. size_t
  1848. nsCSSValue::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  1849. {
  1850. size_t n = 0;
  1851. switch (GetUnit()) {
  1852. // No value: nothing extra to measure.
  1853. case eCSSUnit_Null:
  1854. case eCSSUnit_Auto:
  1855. case eCSSUnit_Inherit:
  1856. case eCSSUnit_Initial:
  1857. case eCSSUnit_Unset:
  1858. case eCSSUnit_None:
  1859. case eCSSUnit_Normal:
  1860. case eCSSUnit_System_Font:
  1861. case eCSSUnit_All:
  1862. case eCSSUnit_Dummy:
  1863. case eCSSUnit_DummyInherit:
  1864. break;
  1865. // String
  1866. case eCSSUnit_String:
  1867. case eCSSUnit_Ident:
  1868. case eCSSUnit_Attr:
  1869. case eCSSUnit_Local_Font:
  1870. case eCSSUnit_Font_Format:
  1871. case eCSSUnit_Element:
  1872. n += mValue.mString->SizeOfIncludingThisIfUnshared(aMallocSizeOf);
  1873. break;
  1874. // Array
  1875. case eCSSUnit_Array:
  1876. case eCSSUnit_Counter:
  1877. case eCSSUnit_Counters:
  1878. case eCSSUnit_Cubic_Bezier:
  1879. case eCSSUnit_Steps:
  1880. case eCSSUnit_Symbols:
  1881. case eCSSUnit_Function:
  1882. case eCSSUnit_Calc:
  1883. case eCSSUnit_Calc_Plus:
  1884. case eCSSUnit_Calc_Minus:
  1885. case eCSSUnit_Calc_Times_L:
  1886. case eCSSUnit_Calc_Times_R:
  1887. case eCSSUnit_Calc_Divided:
  1888. break;
  1889. // URL
  1890. case eCSSUnit_URL:
  1891. n += mValue.mURL->SizeOfIncludingThis(aMallocSizeOf);
  1892. break;
  1893. // Image
  1894. case eCSSUnit_Image:
  1895. // Not yet measured. Measurement may be added later if DMD finds it
  1896. // worthwhile.
  1897. break;
  1898. // Gradient
  1899. case eCSSUnit_Gradient:
  1900. n += mValue.mGradient->SizeOfIncludingThis(aMallocSizeOf);
  1901. break;
  1902. // TokenStream
  1903. case eCSSUnit_TokenStream:
  1904. n += mValue.mTokenStream->SizeOfIncludingThis(aMallocSizeOf);
  1905. break;
  1906. // Pair
  1907. case eCSSUnit_Pair:
  1908. n += mValue.mPair->SizeOfIncludingThis(aMallocSizeOf);
  1909. break;
  1910. // Triplet
  1911. case eCSSUnit_Triplet:
  1912. n += mValue.mTriplet->SizeOfIncludingThis(aMallocSizeOf);
  1913. break;
  1914. // Rect
  1915. case eCSSUnit_Rect:
  1916. n += mValue.mRect->SizeOfIncludingThis(aMallocSizeOf);
  1917. break;
  1918. // List
  1919. case eCSSUnit_List:
  1920. n += mValue.mList->SizeOfIncludingThis(aMallocSizeOf);
  1921. break;
  1922. // ListDep: not measured because it's non-owning.
  1923. case eCSSUnit_ListDep:
  1924. break;
  1925. // SharedList
  1926. case eCSSUnit_SharedList:
  1927. // Makes more sense not to measure, since it most cases the list
  1928. // will be shared.
  1929. break;
  1930. // PairList
  1931. case eCSSUnit_PairList:
  1932. n += mValue.mPairList->SizeOfIncludingThis(aMallocSizeOf);
  1933. break;
  1934. // PairListDep: not measured because it's non-owning.
  1935. case eCSSUnit_PairListDep:
  1936. break;
  1937. // GridTemplateAreas
  1938. case eCSSUnit_GridTemplateAreas:
  1939. n += mValue.mGridTemplateAreas->SizeOfIncludingThis(aMallocSizeOf);
  1940. break;
  1941. case eCSSUnit_FontFamilyList:
  1942. n += mValue.mFontFamilyList->SizeOfIncludingThis(aMallocSizeOf);
  1943. break;
  1944. // Int: nothing extra to measure.
  1945. case eCSSUnit_Integer:
  1946. case eCSSUnit_Enumerated:
  1947. case eCSSUnit_EnumColor:
  1948. break;
  1949. // Integer Color: nothing extra to measure.
  1950. case eCSSUnit_RGBColor:
  1951. case eCSSUnit_RGBAColor:
  1952. case eCSSUnit_HexColor:
  1953. case eCSSUnit_ShortHexColor:
  1954. case eCSSUnit_HexColorAlpha:
  1955. case eCSSUnit_ShortHexColorAlpha:
  1956. break;
  1957. // Float Color
  1958. case eCSSUnit_PercentageRGBColor:
  1959. case eCSSUnit_PercentageRGBAColor:
  1960. case eCSSUnit_HSLColor:
  1961. case eCSSUnit_HSLAColor:
  1962. n += mValue.mFloatColor->SizeOfIncludingThis(aMallocSizeOf);
  1963. break;
  1964. // Complex Color
  1965. case eCSSUnit_ComplexColor:
  1966. n += mValue.mComplexColor->SizeOfIncludingThis(aMallocSizeOf);
  1967. break;
  1968. // Float: nothing extra to measure.
  1969. case eCSSUnit_Percent:
  1970. case eCSSUnit_Number:
  1971. case eCSSUnit_PhysicalMillimeter:
  1972. case eCSSUnit_ViewportWidth:
  1973. case eCSSUnit_ViewportHeight:
  1974. case eCSSUnit_ViewportMin:
  1975. case eCSSUnit_ViewportMax:
  1976. case eCSSUnit_EM:
  1977. case eCSSUnit_XHeight:
  1978. case eCSSUnit_Char:
  1979. case eCSSUnit_RootEM:
  1980. case eCSSUnit_Point:
  1981. case eCSSUnit_Inch:
  1982. case eCSSUnit_Millimeter:
  1983. case eCSSUnit_Centimeter:
  1984. case eCSSUnit_Pica:
  1985. case eCSSUnit_Pixel:
  1986. case eCSSUnit_Quarter:
  1987. case eCSSUnit_Degree:
  1988. case eCSSUnit_Grad:
  1989. case eCSSUnit_Turn:
  1990. case eCSSUnit_Radian:
  1991. case eCSSUnit_Hertz:
  1992. case eCSSUnit_Kilohertz:
  1993. case eCSSUnit_Seconds:
  1994. case eCSSUnit_Milliseconds:
  1995. case eCSSUnit_FlexFraction:
  1996. break;
  1997. default:
  1998. MOZ_ASSERT(false, "bad nsCSSUnit");
  1999. break;
  2000. }
  2001. return n;
  2002. }
  2003. // --- nsCSSValueList -----------------
  2004. nsCSSValueList::~nsCSSValueList()
  2005. {
  2006. MOZ_COUNT_DTOR(nsCSSValueList);
  2007. NS_CSS_DELETE_LIST_MEMBER(nsCSSValueList, this, mNext);
  2008. }
  2009. nsCSSValueList*
  2010. nsCSSValueList::Clone() const
  2011. {
  2012. nsCSSValueList* result = new nsCSSValueList(*this);
  2013. nsCSSValueList* dest = result;
  2014. const nsCSSValueList* src = this->mNext;
  2015. while (src) {
  2016. dest->mNext = new nsCSSValueList(*src);
  2017. dest = dest->mNext;
  2018. src = src->mNext;
  2019. }
  2020. MOZ_ASSERT(result, "shouldn't return null; supposed to be infallible");
  2021. return result;
  2022. }
  2023. void
  2024. nsCSSValueList::CloneInto(nsCSSValueList* aList) const
  2025. {
  2026. NS_ASSERTION(!aList->mNext, "Must be an empty list!");
  2027. aList->mValue = mValue;
  2028. aList->mNext = mNext ? mNext->Clone() : nullptr;
  2029. }
  2030. static void
  2031. AppendValueListToString(const nsCSSValueList* val,
  2032. nsCSSPropertyID aProperty, nsAString& aResult,
  2033. nsCSSValue::Serialization aSerialization)
  2034. {
  2035. for (;;) {
  2036. val->mValue.AppendToString(aProperty, aResult, aSerialization);
  2037. val = val->mNext;
  2038. if (!val)
  2039. break;
  2040. if (nsCSSProps::PropHasFlags(aProperty,
  2041. CSS_PROPERTY_VALUE_LIST_USES_COMMAS))
  2042. aResult.Append(char16_t(','));
  2043. aResult.Append(char16_t(' '));
  2044. }
  2045. }
  2046. static void
  2047. AppendGridTemplateToString(const nsCSSValueList* val,
  2048. nsCSSPropertyID aProperty, nsAString& aResult,
  2049. nsCSSValue::Serialization aSerialization)
  2050. {
  2051. // This is called for the "list" that's the top-level value of the property.
  2052. bool isSubgrid = false;
  2053. for (;;) {
  2054. bool addSpaceSeparator = true;
  2055. nsCSSUnit unit = val->mValue.GetUnit();
  2056. if (unit == eCSSUnit_Enumerated &&
  2057. val->mValue.GetIntValue() == NS_STYLE_GRID_TEMPLATE_SUBGRID) {
  2058. MOZ_ASSERT(!isSubgrid, "saw subgrid once already");
  2059. isSubgrid = true;
  2060. aResult.AppendLiteral("subgrid");
  2061. } else if (unit == eCSSUnit_Pair) {
  2062. // This is a repeat 'auto-fill' / 'auto-fit'.
  2063. const nsCSSValuePair& pair = val->mValue.GetPairValue();
  2064. switch (pair.mXValue.GetIntValue()) {
  2065. case NS_STYLE_GRID_REPEAT_AUTO_FILL:
  2066. aResult.AppendLiteral("repeat(auto-fill, ");
  2067. break;
  2068. case NS_STYLE_GRID_REPEAT_AUTO_FIT:
  2069. aResult.AppendLiteral("repeat(auto-fit, ");
  2070. break;
  2071. default:
  2072. MOZ_ASSERT_UNREACHABLE("unexpected enum value");
  2073. }
  2074. const nsCSSValueList* repeatList = pair.mYValue.GetListValue();
  2075. if (repeatList->mValue.GetUnit() != eCSSUnit_Null) {
  2076. aResult.Append('[');
  2077. AppendValueListToString(repeatList->mValue.GetListValue(), aProperty,
  2078. aResult, aSerialization);
  2079. aResult.Append(']');
  2080. if (!isSubgrid) {
  2081. aResult.Append(' ');
  2082. }
  2083. } else if (isSubgrid) {
  2084. aResult.AppendLiteral("[]");
  2085. }
  2086. if (!isSubgrid) {
  2087. repeatList = repeatList->mNext;
  2088. repeatList->mValue.AppendToString(aProperty, aResult, aSerialization);
  2089. repeatList = repeatList->mNext;
  2090. if (repeatList->mValue.GetUnit() != eCSSUnit_Null) {
  2091. aResult.AppendLiteral(" [");
  2092. AppendValueListToString(repeatList->mValue.GetListValue(), aProperty,
  2093. aResult, aSerialization);
  2094. aResult.Append(']');
  2095. }
  2096. }
  2097. aResult.Append(')');
  2098. } else if (unit == eCSSUnit_Null) {
  2099. // Empty or omitted <line-names>.
  2100. if (isSubgrid) {
  2101. aResult.AppendLiteral("[]");
  2102. } else {
  2103. // Serializes to nothing.
  2104. addSpaceSeparator = false; // Avoid a double space.
  2105. }
  2106. } else if (unit == eCSSUnit_List || unit == eCSSUnit_ListDep) {
  2107. // Non-empty <line-names>
  2108. aResult.Append('[');
  2109. AppendValueListToString(val->mValue.GetListValue(), aProperty,
  2110. aResult, aSerialization);
  2111. aResult.Append(']');
  2112. } else {
  2113. // <track-size>
  2114. val->mValue.AppendToString(aProperty, aResult, aSerialization);
  2115. if (!isSubgrid &&
  2116. val->mNext &&
  2117. val->mNext->mValue.GetUnit() == eCSSUnit_Null &&
  2118. !val->mNext->mNext) {
  2119. // Break out of the loop early to avoid a trailing space.
  2120. break;
  2121. }
  2122. }
  2123. val = val->mNext;
  2124. if (!val) {
  2125. break;
  2126. }
  2127. if (addSpaceSeparator) {
  2128. aResult.Append(char16_t(' '));
  2129. }
  2130. }
  2131. }
  2132. void
  2133. nsCSSValueList::AppendToString(nsCSSPropertyID aProperty, nsAString& aResult,
  2134. nsCSSValue::Serialization aSerialization) const
  2135. {
  2136. if (aProperty == eCSSProperty_grid_template_columns ||
  2137. aProperty == eCSSProperty_grid_template_rows) {
  2138. AppendGridTemplateToString(this, aProperty, aResult, aSerialization);
  2139. } else {
  2140. AppendValueListToString(this, aProperty, aResult, aSerialization);
  2141. }
  2142. }
  2143. /* static */ bool
  2144. nsCSSValueList::Equal(const nsCSSValueList* aList1,
  2145. const nsCSSValueList* aList2)
  2146. {
  2147. if (aList1 == aList2) {
  2148. return true;
  2149. }
  2150. const nsCSSValueList *p1 = aList1, *p2 = aList2;
  2151. for ( ; p1 && p2; p1 = p1->mNext, p2 = p2->mNext) {
  2152. if (p1->mValue != p2->mValue)
  2153. return false;
  2154. }
  2155. return !p1 && !p2; // true if same length, false otherwise
  2156. }
  2157. size_t
  2158. nsCSSValueList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2159. {
  2160. size_t n = 0;
  2161. const nsCSSValueList* v = this;
  2162. while (v) {
  2163. n += aMallocSizeOf(v);
  2164. n += v->mValue.SizeOfExcludingThis(aMallocSizeOf);
  2165. v = v->mNext;
  2166. }
  2167. return n;
  2168. }
  2169. size_t
  2170. nsCSSValueList_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2171. {
  2172. // Only measure it if it's unshared, to avoid double-counting.
  2173. size_t n = 0;
  2174. if (mRefCnt <= 1) {
  2175. n += aMallocSizeOf(this);
  2176. n += mValue.SizeOfExcludingThis(aMallocSizeOf);
  2177. n += mNext ? mNext->SizeOfIncludingThis(aMallocSizeOf) : 0;
  2178. }
  2179. return n;
  2180. }
  2181. // --- nsCSSValueSharedList -----------------
  2182. nsCSSValueSharedList::~nsCSSValueSharedList()
  2183. {
  2184. MOZ_COUNT_DTOR(nsCSSValueSharedList);
  2185. if (mHead) {
  2186. NS_CSS_DELETE_LIST_MEMBER(nsCSSValueList, mHead, mNext);
  2187. delete mHead;
  2188. }
  2189. }
  2190. void
  2191. nsCSSValueSharedList::AppendToString(nsCSSPropertyID aProperty, nsAString& aResult,
  2192. nsCSSValue::Serialization aSerialization) const
  2193. {
  2194. if (mHead) {
  2195. mHead->AppendToString(aProperty, aResult, aSerialization);
  2196. }
  2197. }
  2198. bool
  2199. nsCSSValueSharedList::operator==(const nsCSSValueSharedList& aOther) const
  2200. {
  2201. return nsCSSValueList::Equal(mHead, aOther.mHead);
  2202. }
  2203. size_t
  2204. nsCSSValueSharedList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2205. {
  2206. // Only measure it if it's unshared, to avoid double-counting.
  2207. size_t n = 0;
  2208. if (mRefCnt <= 1) {
  2209. n += aMallocSizeOf(this);
  2210. n += mHead->SizeOfIncludingThis(aMallocSizeOf);
  2211. }
  2212. return n;
  2213. }
  2214. // --- nsCSSRect -----------------
  2215. nsCSSRect::nsCSSRect(void)
  2216. {
  2217. MOZ_COUNT_CTOR(nsCSSRect);
  2218. }
  2219. nsCSSRect::nsCSSRect(const nsCSSRect& aCopy)
  2220. : mTop(aCopy.mTop),
  2221. mRight(aCopy.mRight),
  2222. mBottom(aCopy.mBottom),
  2223. mLeft(aCopy.mLeft)
  2224. {
  2225. MOZ_COUNT_CTOR(nsCSSRect);
  2226. }
  2227. nsCSSRect::~nsCSSRect()
  2228. {
  2229. MOZ_COUNT_DTOR(nsCSSRect);
  2230. }
  2231. void
  2232. nsCSSRect::AppendToString(nsCSSPropertyID aProperty, nsAString& aResult,
  2233. nsCSSValue::Serialization aSerialization) const
  2234. {
  2235. MOZ_ASSERT(mTop.GetUnit() != eCSSUnit_Null &&
  2236. mTop.GetUnit() != eCSSUnit_Inherit &&
  2237. mTop.GetUnit() != eCSSUnit_Initial &&
  2238. mTop.GetUnit() != eCSSUnit_Unset,
  2239. "parser should have used a bare value");
  2240. if (eCSSProperty_border_image_slice == aProperty ||
  2241. eCSSProperty_border_image_width == aProperty ||
  2242. eCSSProperty_border_image_outset == aProperty ||
  2243. eCSSProperty_DOM == aProperty) {
  2244. NS_NAMED_LITERAL_STRING(space, " ");
  2245. mTop.AppendToString(aProperty, aResult, aSerialization);
  2246. aResult.Append(space);
  2247. mRight.AppendToString(aProperty, aResult, aSerialization);
  2248. aResult.Append(space);
  2249. mBottom.AppendToString(aProperty, aResult, aSerialization);
  2250. aResult.Append(space);
  2251. mLeft.AppendToString(aProperty, aResult, aSerialization);
  2252. } else {
  2253. NS_NAMED_LITERAL_STRING(comma, ", ");
  2254. aResult.AppendLiteral("rect(");
  2255. mTop.AppendToString(aProperty, aResult, aSerialization);
  2256. aResult.Append(comma);
  2257. mRight.AppendToString(aProperty, aResult, aSerialization);
  2258. aResult.Append(comma);
  2259. mBottom.AppendToString(aProperty, aResult, aSerialization);
  2260. aResult.Append(comma);
  2261. mLeft.AppendToString(aProperty, aResult, aSerialization);
  2262. aResult.Append(char16_t(')'));
  2263. }
  2264. }
  2265. void nsCSSRect::SetAllSidesTo(const nsCSSValue& aValue)
  2266. {
  2267. mTop = aValue;
  2268. mRight = aValue;
  2269. mBottom = aValue;
  2270. mLeft = aValue;
  2271. }
  2272. size_t
  2273. nsCSSRect_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2274. {
  2275. // Only measure it if it's unshared, to avoid double-counting.
  2276. size_t n = 0;
  2277. if (mRefCnt <= 1) {
  2278. n += aMallocSizeOf(this);
  2279. n += mTop .SizeOfExcludingThis(aMallocSizeOf);
  2280. n += mRight .SizeOfExcludingThis(aMallocSizeOf);
  2281. n += mBottom.SizeOfExcludingThis(aMallocSizeOf);
  2282. n += mLeft .SizeOfExcludingThis(aMallocSizeOf);
  2283. }
  2284. return n;
  2285. }
  2286. static_assert(NS_SIDE_TOP == 0 && NS_SIDE_RIGHT == 1 &&
  2287. NS_SIDE_BOTTOM == 2 && NS_SIDE_LEFT == 3,
  2288. "box side constants not top/right/bottom/left == 0/1/2/3");
  2289. /* static */ const nsCSSRect::side_type nsCSSRect::sides[4] = {
  2290. &nsCSSRect::mTop,
  2291. &nsCSSRect::mRight,
  2292. &nsCSSRect::mBottom,
  2293. &nsCSSRect::mLeft,
  2294. };
  2295. // --- nsCSSValuePair -----------------
  2296. void
  2297. nsCSSValuePair::AppendToString(nsCSSPropertyID aProperty,
  2298. nsAString& aResult,
  2299. nsCSSValue::Serialization aSerialization) const
  2300. {
  2301. mXValue.AppendToString(aProperty, aResult, aSerialization);
  2302. if (mYValue.GetUnit() != eCSSUnit_Null) {
  2303. aResult.Append(char16_t(' '));
  2304. mYValue.AppendToString(aProperty, aResult, aSerialization);
  2305. }
  2306. }
  2307. size_t
  2308. nsCSSValuePair::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2309. {
  2310. size_t n = 0;
  2311. n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
  2312. n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
  2313. return n;
  2314. }
  2315. size_t
  2316. nsCSSValuePair_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2317. {
  2318. // Only measure it if it's unshared, to avoid double-counting.
  2319. size_t n = 0;
  2320. if (mRefCnt <= 1) {
  2321. n += aMallocSizeOf(this);
  2322. n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
  2323. n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
  2324. }
  2325. return n;
  2326. }
  2327. // --- nsCSSValueTriplet -----------------
  2328. void
  2329. nsCSSValueTriplet::AppendToString(nsCSSPropertyID aProperty,
  2330. nsAString& aResult,
  2331. nsCSSValue::Serialization aSerialization) const
  2332. {
  2333. mXValue.AppendToString(aProperty, aResult, aSerialization);
  2334. if (mYValue.GetUnit() != eCSSUnit_Null) {
  2335. aResult.Append(char16_t(' '));
  2336. mYValue.AppendToString(aProperty, aResult, aSerialization);
  2337. if (mZValue.GetUnit() != eCSSUnit_Null) {
  2338. aResult.Append(char16_t(' '));
  2339. mZValue.AppendToString(aProperty, aResult, aSerialization);
  2340. }
  2341. }
  2342. }
  2343. size_t
  2344. nsCSSValueTriplet_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2345. {
  2346. // Only measure it if it's unshared, to avoid double-counting.
  2347. size_t n = 0;
  2348. if (mRefCnt <= 1) {
  2349. n += aMallocSizeOf(this);
  2350. n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
  2351. n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
  2352. n += mZValue.SizeOfExcludingThis(aMallocSizeOf);
  2353. }
  2354. return n;
  2355. }
  2356. // --- nsCSSValuePairList -----------------
  2357. nsCSSValuePairList::~nsCSSValuePairList()
  2358. {
  2359. MOZ_COUNT_DTOR(nsCSSValuePairList);
  2360. NS_CSS_DELETE_LIST_MEMBER(nsCSSValuePairList, this, mNext);
  2361. }
  2362. nsCSSValuePairList*
  2363. nsCSSValuePairList::Clone() const
  2364. {
  2365. nsCSSValuePairList* result = new nsCSSValuePairList(*this);
  2366. nsCSSValuePairList* dest = result;
  2367. const nsCSSValuePairList* src = this->mNext;
  2368. while (src) {
  2369. dest->mNext = new nsCSSValuePairList(*src);
  2370. dest = dest->mNext;
  2371. src = src->mNext;
  2372. }
  2373. MOZ_ASSERT(result, "shouldn't return null; supposed to be infallible");
  2374. return result;
  2375. }
  2376. void
  2377. nsCSSValuePairList::AppendToString(nsCSSPropertyID aProperty,
  2378. nsAString& aResult,
  2379. nsCSSValue::Serialization aSerialization) const
  2380. {
  2381. const nsCSSValuePairList* item = this;
  2382. for (;;) {
  2383. MOZ_ASSERT(item->mXValue.GetUnit() != eCSSUnit_Null,
  2384. "unexpected null unit");
  2385. item->mXValue.AppendToString(aProperty, aResult, aSerialization);
  2386. if (item->mXValue.GetUnit() != eCSSUnit_Inherit &&
  2387. item->mXValue.GetUnit() != eCSSUnit_Initial &&
  2388. item->mXValue.GetUnit() != eCSSUnit_Unset &&
  2389. item->mYValue.GetUnit() != eCSSUnit_Null) {
  2390. aResult.Append(char16_t(' '));
  2391. item->mYValue.AppendToString(aProperty, aResult, aSerialization);
  2392. }
  2393. item = item->mNext;
  2394. if (!item)
  2395. break;
  2396. if (nsCSSProps::PropHasFlags(aProperty,
  2397. CSS_PROPERTY_VALUE_LIST_USES_COMMAS) ||
  2398. aProperty == eCSSProperty_clip_path ||
  2399. aProperty == eCSSProperty_shape_outside)
  2400. aResult.Append(char16_t(','));
  2401. aResult.Append(char16_t(' '));
  2402. }
  2403. }
  2404. /* static */ bool
  2405. nsCSSValuePairList::Equal(const nsCSSValuePairList* aList1,
  2406. const nsCSSValuePairList* aList2)
  2407. {
  2408. if (aList1 == aList2) {
  2409. return true;
  2410. }
  2411. const nsCSSValuePairList *p1 = aList1, *p2 = aList2;
  2412. for ( ; p1 && p2; p1 = p1->mNext, p2 = p2->mNext) {
  2413. if (p1->mXValue != p2->mXValue ||
  2414. p1->mYValue != p2->mYValue)
  2415. return false;
  2416. }
  2417. return !p1 && !p2; // true if same length, false otherwise
  2418. }
  2419. size_t
  2420. nsCSSValuePairList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2421. {
  2422. size_t n = 0;
  2423. const nsCSSValuePairList* v = this;
  2424. while (v) {
  2425. n += aMallocSizeOf(v);
  2426. n += v->mXValue.SizeOfExcludingThis(aMallocSizeOf);
  2427. n += v->mYValue.SizeOfExcludingThis(aMallocSizeOf);
  2428. v = v->mNext;
  2429. }
  2430. return n;
  2431. }
  2432. size_t
  2433. nsCSSValuePairList_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2434. {
  2435. // Only measure it if it's unshared, to avoid double-counting.
  2436. size_t n = 0;
  2437. if (mRefCnt <= 1) {
  2438. n += aMallocSizeOf(this);
  2439. n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
  2440. n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
  2441. n += mNext ? mNext->SizeOfIncludingThis(aMallocSizeOf) : 0;
  2442. }
  2443. return n;
  2444. }
  2445. size_t
  2446. nsCSSValue::Array::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2447. {
  2448. size_t n = aMallocSizeOf(this);
  2449. for (size_t i = 0; i < mCount; i++) {
  2450. n += mArray[i].SizeOfExcludingThis(aMallocSizeOf);
  2451. }
  2452. return n;
  2453. }
  2454. css::URLValueData::URLValueData(already_AddRefed<PtrHolder<nsIURI>> aURI,
  2455. nsStringBuffer* aString,
  2456. already_AddRefed<PtrHolder<nsIURI>> aBaseURI,
  2457. already_AddRefed<PtrHolder<nsIURI>> aReferrer,
  2458. already_AddRefed<PtrHolder<nsIPrincipal>>
  2459. aOriginPrincipal)
  2460. : mURI(Move(aURI))
  2461. , mBaseURI(Move(aBaseURI))
  2462. , mString(aString)
  2463. , mReferrer(Move(aReferrer))
  2464. , mOriginPrincipal(Move(aOriginPrincipal))
  2465. , mURIResolved(true)
  2466. , mIsLocalRef(IsLocalRefURL(aString))
  2467. {
  2468. MOZ_ASSERT(mString);
  2469. MOZ_ASSERT(mBaseURI);
  2470. MOZ_ASSERT(mOriginPrincipal);
  2471. }
  2472. css::URLValueData::URLValueData(nsStringBuffer* aString,
  2473. already_AddRefed<PtrHolder<nsIURI>> aBaseURI,
  2474. already_AddRefed<PtrHolder<nsIURI>> aReferrer,
  2475. already_AddRefed<PtrHolder<nsIPrincipal>>
  2476. aOriginPrincipal)
  2477. : mBaseURI(Move(aBaseURI))
  2478. , mString(aString)
  2479. , mReferrer(Move(aReferrer))
  2480. , mOriginPrincipal(Move(aOriginPrincipal))
  2481. , mURIResolved(false)
  2482. , mIsLocalRef(IsLocalRefURL(aString))
  2483. {
  2484. MOZ_ASSERT(aString);
  2485. MOZ_ASSERT(mBaseURI);
  2486. MOZ_ASSERT(mOriginPrincipal);
  2487. }
  2488. bool
  2489. css::URLValueData::Equals(const URLValueData& aOther) const
  2490. {
  2491. MOZ_ASSERT(NS_IsMainThread());
  2492. bool eq;
  2493. // Cast away const so we can call nsIPrincipal::Equals.
  2494. auto& self = *const_cast<URLValueData*>(this);
  2495. auto& other = const_cast<URLValueData&>(aOther);
  2496. return NS_strcmp(nsCSSValue::GetBufferValue(mString),
  2497. nsCSSValue::GetBufferValue(aOther.mString)) == 0 &&
  2498. (GetURI() == aOther.GetURI() || // handles null == null
  2499. (mURI && aOther.mURI &&
  2500. NS_SUCCEEDED(mURI->Equals(aOther.mURI, &eq)) &&
  2501. eq)) &&
  2502. (mBaseURI == aOther.mBaseURI ||
  2503. (NS_SUCCEEDED(self.mBaseURI.get()->Equals(other.mBaseURI.get(), &eq)) &&
  2504. eq)) &&
  2505. (mOriginPrincipal == aOther.mOriginPrincipal ||
  2506. self.mOriginPrincipal.get()->Equals(other.mOriginPrincipal.get())) &&
  2507. mIsLocalRef == aOther.mIsLocalRef;
  2508. }
  2509. bool
  2510. css::URLValueData::DefinitelyEqualURIs(const URLValueData& aOther) const
  2511. {
  2512. return mBaseURI == aOther.mBaseURI &&
  2513. (mString == aOther.mString ||
  2514. NS_strcmp(nsCSSValue::GetBufferValue(mString),
  2515. nsCSSValue::GetBufferValue(aOther.mString)) == 0);
  2516. }
  2517. bool
  2518. css::URLValueData::DefinitelyEqualURIsAndPrincipal(
  2519. const URLValueData& aOther) const
  2520. {
  2521. return mOriginPrincipal == aOther.mOriginPrincipal &&
  2522. DefinitelyEqualURIs(aOther);
  2523. }
  2524. nsIURI*
  2525. css::URLValueData::GetURI() const
  2526. {
  2527. MOZ_ASSERT(NS_IsMainThread());
  2528. if (!mURIResolved) {
  2529. MOZ_ASSERT(!mURI);
  2530. nsCOMPtr<nsIURI> newURI;
  2531. NS_NewURI(getter_AddRefs(newURI),
  2532. NS_ConvertUTF16toUTF8(nsCSSValue::GetBufferValue(mString)),
  2533. nullptr, const_cast<nsIURI*>(mBaseURI.get()));
  2534. mURI = new PtrHolder<nsIURI>(newURI.forget());
  2535. mURIResolved = true;
  2536. }
  2537. return mURI;
  2538. }
  2539. already_AddRefed<nsIURI>
  2540. css::URLValueData::ResolveLocalRef(nsIURI* aURI) const
  2541. {
  2542. nsCOMPtr<nsIURI> result = GetURI();
  2543. if (result && mIsLocalRef) {
  2544. nsCString ref;
  2545. mURI->GetRef(ref);
  2546. aURI->Clone(getter_AddRefs(result));
  2547. result->SetRef(ref);
  2548. }
  2549. return result.forget();
  2550. }
  2551. already_AddRefed<nsIURI>
  2552. css::URLValueData::ResolveLocalRef(nsIContent* aContent) const
  2553. {
  2554. nsCOMPtr<nsIURI> url = aContent->GetBaseURI();
  2555. return ResolveLocalRef(url);
  2556. }
  2557. void
  2558. css::URLValueData::GetSourceString(nsString& aRef) const
  2559. {
  2560. nsIURI* uri = GetURI();
  2561. if (!uri) {
  2562. aRef.Truncate();
  2563. return;
  2564. }
  2565. nsCString cref;
  2566. if (mIsLocalRef) {
  2567. // XXXheycam It's possible we can just return mString in this case, since
  2568. // it should be the "#fragment" string the URLValueData was created with.
  2569. uri->GetRef(cref);
  2570. cref.Insert('#', 0);
  2571. } else {
  2572. // It's not entirely clear how to best handle failure here. Ensuring the
  2573. // string is empty seems safest.
  2574. nsresult rv = uri->GetSpec(cref);
  2575. if (NS_FAILED(rv)) {
  2576. cref.Truncate();
  2577. }
  2578. }
  2579. aRef = NS_ConvertUTF8toUTF16(cref);
  2580. }
  2581. bool
  2582. css::URLValueData::EqualsExceptRef(nsIURI* aURI) const
  2583. {
  2584. nsIURI* uri = GetURI();
  2585. if (!uri) {
  2586. return false;
  2587. }
  2588. bool ret = false;
  2589. uri->EqualsExceptRef(aURI, &ret);
  2590. return ret;
  2591. }
  2592. size_t
  2593. css::URLValueData::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2594. {
  2595. size_t n = 0;
  2596. n += mString->SizeOfIncludingThisIfUnshared(aMallocSizeOf);
  2597. // Measurement of the following members may be added later if DMD finds it
  2598. // is worthwhile:
  2599. // - mURI
  2600. // - mReferrer
  2601. // - mOriginPrincipal
  2602. return n;
  2603. }
  2604. URLValue::URLValue(nsStringBuffer* aString, nsIURI* aBaseURI, nsIURI* aReferrer,
  2605. nsIPrincipal* aOriginPrincipal)
  2606. : URLValueData(aString,
  2607. do_AddRef(new PtrHolder<nsIURI>(aBaseURI)),
  2608. do_AddRef(new PtrHolder<nsIURI>(aReferrer)),
  2609. do_AddRef(new PtrHolder<nsIPrincipal>(aOriginPrincipal)))
  2610. {
  2611. MOZ_ASSERT(NS_IsMainThread());
  2612. }
  2613. URLValue::URLValue(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aBaseURI,
  2614. nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal)
  2615. : URLValueData(do_AddRef(new PtrHolder<nsIURI>(aURI)),
  2616. aString,
  2617. do_AddRef(new PtrHolder<nsIURI>(aBaseURI)),
  2618. do_AddRef(new PtrHolder<nsIURI>(aReferrer)),
  2619. do_AddRef(new PtrHolder<nsIPrincipal>(aOriginPrincipal)))
  2620. {
  2621. MOZ_ASSERT(NS_IsMainThread());
  2622. }
  2623. size_t
  2624. css::URLValue::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2625. {
  2626. // Only measure it if it's unshared, to avoid double-counting.
  2627. size_t n = 0;
  2628. if (mRefCnt <= 1) {
  2629. n += aMallocSizeOf(this);
  2630. n += URLValueData::SizeOfExcludingThis(aMallocSizeOf);
  2631. }
  2632. return n;
  2633. }
  2634. css::ImageValue::ImageValue(nsIURI* aURI, nsStringBuffer* aString,
  2635. nsIURI* aBaseURI, nsIURI* aReferrer,
  2636. nsIPrincipal* aOriginPrincipal,
  2637. nsIDocument* aDocument)
  2638. : URLValueData(do_AddRef(new PtrHolder<nsIURI>(aURI)),
  2639. aString,
  2640. do_AddRef(new PtrHolder<nsIURI>(aBaseURI, false)),
  2641. do_AddRef(new PtrHolder<nsIURI>(aReferrer)),
  2642. do_AddRef(new PtrHolder<nsIPrincipal>(aOriginPrincipal)))
  2643. {
  2644. Initialize(aDocument);
  2645. }
  2646. css::ImageValue::ImageValue(
  2647. nsStringBuffer* aString,
  2648. already_AddRefed<PtrHolder<nsIURI>> aBaseURI,
  2649. already_AddRefed<PtrHolder<nsIURI>> aReferrer,
  2650. already_AddRefed<PtrHolder<nsIPrincipal>> aOriginPrincipal)
  2651. : URLValueData(aString, Move(aBaseURI), Move(aReferrer),
  2652. Move(aOriginPrincipal))
  2653. {
  2654. }
  2655. void
  2656. css::ImageValue::Initialize(nsIDocument* aDocument)
  2657. {
  2658. MOZ_ASSERT(NS_IsMainThread());
  2659. MOZ_ASSERT(!mInitialized);
  2660. // NB: If aDocument is not the original document, we may not be able to load
  2661. // images from aDocument. Instead we do the image load from the original doc
  2662. // and clone it to aDocument.
  2663. nsIDocument* loadingDoc = aDocument->GetOriginalDocument();
  2664. if (!loadingDoc) {
  2665. loadingDoc = aDocument;
  2666. }
  2667. loadingDoc->StyleImageLoader()->LoadImage(GetURI(), mOriginPrincipal,
  2668. mReferrer, this);
  2669. if (loadingDoc != aDocument) {
  2670. aDocument->StyleImageLoader()->MaybeRegisterCSSImage(this);
  2671. }
  2672. #ifdef DEBUG
  2673. mInitialized = true;
  2674. #endif
  2675. }
  2676. css::ImageValue::~ImageValue()
  2677. {
  2678. MOZ_ASSERT(NS_IsMainThread());
  2679. for (auto iter = mRequests.Iter(); !iter.Done(); iter.Next()) {
  2680. nsIDocument* doc = iter.Key();
  2681. RefPtr<imgRequestProxy>& proxy = iter.Data();
  2682. if (doc) {
  2683. doc->StyleImageLoader()->DeregisterCSSImage(this);
  2684. }
  2685. if (proxy) {
  2686. proxy->CancelAndForgetObserver(NS_BINDING_ABORTED);
  2687. }
  2688. iter.Remove();
  2689. }
  2690. }
  2691. size_t
  2692. css::ComplexColorValue::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
  2693. {
  2694. // Only measure it if it's unshared, to avoid double-counting.
  2695. size_t n = 0;
  2696. if (mRefCnt <= 1) {
  2697. n += aMallocSizeOf(this);
  2698. }
  2699. return n;
  2700. }
  2701. nsCSSValueGradientStop::nsCSSValueGradientStop()
  2702. : mLocation(eCSSUnit_None),
  2703. mColor(eCSSUnit_Null),
  2704. mIsInterpolationHint(false)
  2705. {
  2706. MOZ_COUNT_CTOR(nsCSSValueGradientStop);
  2707. }
  2708. nsCSSValueGradientStop::nsCSSValueGradientStop(const nsCSSValueGradientStop& aOther)
  2709. : mLocation(aOther.mLocation),
  2710. mColor(aOther.mColor),
  2711. mIsInterpolationHint(aOther.mIsInterpolationHint)
  2712. {
  2713. MOZ_COUNT_CTOR(nsCSSValueGradientStop);
  2714. }
  2715. nsCSSValueGradientStop::~nsCSSValueGradientStop()
  2716. {
  2717. MOZ_COUNT_DTOR(nsCSSValueGradientStop);
  2718. }
  2719. size_t
  2720. nsCSSValueGradientStop::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2721. {
  2722. size_t n = 0;
  2723. n += mLocation.SizeOfExcludingThis(aMallocSizeOf);
  2724. n += mColor .SizeOfExcludingThis(aMallocSizeOf);
  2725. return n;
  2726. }
  2727. nsCSSValueGradient::nsCSSValueGradient(bool aIsRadial,
  2728. bool aIsRepeating)
  2729. : mIsRadial(aIsRadial),
  2730. mIsRepeating(aIsRepeating),
  2731. mIsLegacySyntax(false),
  2732. mIsExplicitSize(false),
  2733. mBgPos(eCSSUnit_None),
  2734. mAngle(eCSSUnit_None)
  2735. {
  2736. mRadialValues[0].SetNoneValue();
  2737. mRadialValues[1].SetNoneValue();
  2738. }
  2739. size_t
  2740. nsCSSValueGradient::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2741. {
  2742. // Only measure it if it's unshared, to avoid double-counting.
  2743. size_t n = 0;
  2744. if (mRefCnt <= 1) {
  2745. n += aMallocSizeOf(this);
  2746. n += mBgPos.SizeOfExcludingThis(aMallocSizeOf);
  2747. n += mAngle.SizeOfExcludingThis(aMallocSizeOf);
  2748. n += mRadialValues[0].SizeOfExcludingThis(aMallocSizeOf);
  2749. n += mRadialValues[1].SizeOfExcludingThis(aMallocSizeOf);
  2750. n += mStops.ShallowSizeOfExcludingThis(aMallocSizeOf);
  2751. for (uint32_t i = 0; i < mStops.Length(); i++) {
  2752. n += mStops[i].SizeOfExcludingThis(aMallocSizeOf);
  2753. }
  2754. }
  2755. return n;
  2756. }
  2757. // --- nsCSSValueTokenStream ------------
  2758. nsCSSValueTokenStream::nsCSSValueTokenStream()
  2759. : mPropertyID(eCSSProperty_UNKNOWN)
  2760. , mShorthandPropertyID(eCSSProperty_UNKNOWN)
  2761. , mLevel(SheetType::Count)
  2762. {
  2763. MOZ_COUNT_CTOR(nsCSSValueTokenStream);
  2764. }
  2765. nsCSSValueTokenStream::~nsCSSValueTokenStream()
  2766. {
  2767. MOZ_COUNT_DTOR(nsCSSValueTokenStream);
  2768. }
  2769. size_t
  2770. nsCSSValueTokenStream::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2771. {
  2772. // Only measure it if it's unshared, to avoid double-counting.
  2773. size_t n = 0;
  2774. if (mRefCnt <= 1) {
  2775. n += aMallocSizeOf(this);
  2776. n += mTokenStream.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
  2777. }
  2778. return n;
  2779. }
  2780. // --- nsCSSValueFloatColor -------------
  2781. bool
  2782. nsCSSValueFloatColor::operator==(nsCSSValueFloatColor& aOther) const
  2783. {
  2784. return mComponent1 == aOther.mComponent1 &&
  2785. mComponent2 == aOther.mComponent2 &&
  2786. mComponent3 == aOther.mComponent3 &&
  2787. mAlpha == aOther.mAlpha;
  2788. }
  2789. nscolor
  2790. nsCSSValueFloatColor::GetColorValue(nsCSSUnit aUnit) const
  2791. {
  2792. MOZ_ASSERT(nsCSSValue::IsFloatColorUnit(aUnit), "unexpected unit");
  2793. // We should clamp each component value since eCSSUnit_PercentageRGBColor
  2794. // and eCSSUnit_PercentageRGBAColor may store values greater than 1.0.
  2795. if (aUnit == eCSSUnit_PercentageRGBColor ||
  2796. aUnit == eCSSUnit_PercentageRGBAColor) {
  2797. return NS_RGBA(
  2798. // We need to clamp before multiplying by 255.0f to avoid overflow.
  2799. NSToIntRound(mozilla::clamped(mComponent1, 0.0f, 1.0f) * 255.0f),
  2800. NSToIntRound(mozilla::clamped(mComponent2, 0.0f, 1.0f) * 255.0f),
  2801. NSToIntRound(mozilla::clamped(mComponent3, 0.0f, 1.0f) * 255.0f),
  2802. NSToIntRound(mozilla::clamped(mAlpha, 0.0f, 1.0f) * 255.0f));
  2803. }
  2804. // HSL color
  2805. MOZ_ASSERT(aUnit == eCSSUnit_HSLColor ||
  2806. aUnit == eCSSUnit_HSLAColor);
  2807. nscolor hsl = NS_HSL2RGB(mComponent1, mComponent2, mComponent3);
  2808. return NS_RGBA(NS_GET_R(hsl),
  2809. NS_GET_G(hsl),
  2810. NS_GET_B(hsl),
  2811. NSToIntRound(mAlpha * 255.0f));
  2812. }
  2813. bool
  2814. nsCSSValueFloatColor::IsNonTransparentColor() const
  2815. {
  2816. return mAlpha > 0.0f;
  2817. }
  2818. void
  2819. nsCSSValueFloatColor::AppendToString(nsCSSUnit aUnit, nsAString& aResult) const
  2820. {
  2821. // Similar to the rgb()/rgba() case in nsCSSValue::AppendToString. We omit the
  2822. // alpha component if it's equal to 1.0f (full opaque). Also, we try to
  2823. // preserve the author-specified function name, unless it's rgba()/hsla() and
  2824. // we're omitting the alpha component - then we use rgb()/hsl().
  2825. MOZ_ASSERT(nsCSSValue::IsFloatColorUnit(aUnit), "unexpected unit");
  2826. bool showAlpha = (mAlpha != 1.0f);
  2827. bool isHSL = (aUnit == eCSSUnit_HSLColor ||
  2828. aUnit == eCSSUnit_HSLAColor);
  2829. if (isHSL) {
  2830. aResult.AppendLiteral("hsl");
  2831. } else {
  2832. aResult.AppendLiteral("rgb");
  2833. }
  2834. if (showAlpha && (aUnit == eCSSUnit_HSLAColor || aUnit == eCSSUnit_PercentageRGBAColor)) {
  2835. aResult.AppendLiteral("a(");
  2836. } else {
  2837. aResult.Append('(');
  2838. }
  2839. if (isHSL) {
  2840. aResult.AppendFloat(mComponent1 * 360.0f);
  2841. aResult.AppendLiteral(", ");
  2842. } else {
  2843. aResult.AppendFloat(mComponent1 * 100.0f);
  2844. aResult.AppendLiteral("%, ");
  2845. }
  2846. aResult.AppendFloat(mComponent2 * 100.0f);
  2847. aResult.AppendLiteral("%, ");
  2848. aResult.AppendFloat(mComponent3 * 100.0f);
  2849. if (showAlpha) {
  2850. aResult.AppendLiteral("%, ");
  2851. aResult.AppendFloat(mAlpha);
  2852. aResult.Append(')');
  2853. } else {
  2854. aResult.AppendLiteral("%)");
  2855. }
  2856. }
  2857. size_t
  2858. nsCSSValueFloatColor::SizeOfIncludingThis(
  2859. mozilla::MallocSizeOf aMallocSizeOf) const
  2860. {
  2861. // Only measure it if it's unshared, to avoid double-counting.
  2862. size_t n = 0;
  2863. if (mRefCnt <= 1) {
  2864. n += aMallocSizeOf(this);
  2865. }
  2866. return n;
  2867. }
  2868. // --- nsCSSCornerSizes -----------------
  2869. nsCSSCornerSizes::nsCSSCornerSizes(void)
  2870. {
  2871. MOZ_COUNT_CTOR(nsCSSCornerSizes);
  2872. }
  2873. nsCSSCornerSizes::nsCSSCornerSizes(const nsCSSCornerSizes& aCopy)
  2874. : mTopLeft(aCopy.mTopLeft),
  2875. mTopRight(aCopy.mTopRight),
  2876. mBottomRight(aCopy.mBottomRight),
  2877. mBottomLeft(aCopy.mBottomLeft)
  2878. {
  2879. MOZ_COUNT_CTOR(nsCSSCornerSizes);
  2880. }
  2881. nsCSSCornerSizes::~nsCSSCornerSizes()
  2882. {
  2883. MOZ_COUNT_DTOR(nsCSSCornerSizes);
  2884. }
  2885. void
  2886. nsCSSCornerSizes::Reset()
  2887. {
  2888. NS_FOR_CSS_FULL_CORNERS(corner) {
  2889. this->GetCorner(corner).Reset();
  2890. }
  2891. }
  2892. static_assert(NS_CORNER_TOP_LEFT == 0 && NS_CORNER_TOP_RIGHT == 1 &&
  2893. NS_CORNER_BOTTOM_RIGHT == 2 && NS_CORNER_BOTTOM_LEFT == 3,
  2894. "box corner constants not tl/tr/br/bl == 0/1/2/3");
  2895. /* static */ const nsCSSCornerSizes::corner_type
  2896. nsCSSCornerSizes::corners[4] = {
  2897. &nsCSSCornerSizes::mTopLeft,
  2898. &nsCSSCornerSizes::mTopRight,
  2899. &nsCSSCornerSizes::mBottomRight,
  2900. &nsCSSCornerSizes::mBottomLeft,
  2901. };
  2902. size_t
  2903. mozilla::css::GridTemplateAreasValue::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
  2904. {
  2905. // Only measure it if it's unshared, to avoid double-counting.
  2906. size_t n = 0;
  2907. if (mRefCnt <= 1) {
  2908. n += aMallocSizeOf(this);
  2909. n += mNamedAreas.ShallowSizeOfExcludingThis(aMallocSizeOf);
  2910. n += mTemplates.ShallowSizeOfExcludingThis(aMallocSizeOf);
  2911. }
  2912. return n;
  2913. }