1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/style/test/flexbox_layout_testcases.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,838 @@ 1.4 +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=2 sw=2 sts=2 et: */ 1.6 + 1.7 +/* 1.8 + * This Source Code is subject to the terms of the Mozilla Public License 1.9 + * version 2.0 (the "License"). You can obtain a copy of the License at 1.10 + * http://mozilla.org/MPL/2.0/. 1.11 + */ 1.12 + 1.13 +/** 1.14 + * For the purposes of this test, flex items are specified as a hash with a 1.15 + * hash-entry for each CSS property that is to be set. In these per-property 1.16 + * entries, the key is the property-name, and the value can be either of the 1.17 + * following: 1.18 + * (a) the property's specified value (which indicates that we don't need to 1.19 + * bother checking the computed value of this particular property) 1.20 + * ...OR... 1.21 + * (b) an array with 2-3 entries... 1.22 + * [specifiedValue, expectedComputedValue (, epsilon) ] 1.23 + * ...which indicates that the property's computed value should be 1.24 + * checked. The array's first entry (for the specified value) may be 1.25 + * null; this means that no value should be explicitly specified for this 1.26 + * property. The second entry is the property's expected computed 1.27 + * value. The third (optional) entry is an epsilon value, which allows for 1.28 + * fuzzy equality when testing the computed value. 1.29 + * 1.30 + * To allow these testcases to be re-used in both horizontal and vertical 1.31 + * flex containers, we specify "width"/"min-width"/etc. using the aliases 1.32 + * "_main-size", "_min-main-size", etc. The test code can map these 1.33 + * placeholder names to their corresponding property-names using the maps 1.34 + * defined below -- gRowPropertyMapping, gColumnPropertyMapping, etc. 1.35 + * 1.36 + * If the testcase needs to customize its flex container at all (e.g. by 1.37 + * specifying a custom container-size), it can do so by including a hash 1.38 + * called "container_properties", with propertyName:propertyValue mappings. 1.39 + * (This hash can use aliased property-names like "_main-size" as well.) 1.40 + */ 1.41 + 1.42 +// The standard main-size we'll use for our flex container when setting up 1.43 +// the testcases defined below: 1.44 +var gDefaultFlexContainerSize = "200px"; 1.45 + 1.46 +// Left-to-right versions of placeholder property-names used in 1.47 +// testcases below: 1.48 +var gRowPropertyMapping = 1.49 +{ 1.50 + "_main-size": "width", 1.51 + "_min-main-size": "min-width", 1.52 + "_max-main-size": "max-width", 1.53 + "_border-main-start-width": "border-left-width", 1.54 + "_border-main-end-width": "border-right-width", 1.55 + "_padding-main-start": "padding-left", 1.56 + "_padding-main-end": "padding-right", 1.57 + "_margin-main-start": "margin-left", 1.58 + "_margin-main-end": "margin-right" 1.59 +}; 1.60 + 1.61 +// Right-to-left versions of placeholder property-names used in 1.62 +// testcases below: 1.63 +var gRowReversePropertyMapping = 1.64 +{ 1.65 + "_main-size": "width", 1.66 + "_min-main-size": "min-width", 1.67 + "_max-main-size": "max-width", 1.68 + "_border-main-start-width": "border-right-width", 1.69 + "_border-main-end-width": "border-left-width", 1.70 + "_padding-main-start": "padding-right", 1.71 + "_padding-main-end": "padding-left", 1.72 + "_margin-main-start": "margin-right", 1.73 + "_margin-main-end": "margin-left" 1.74 +}; 1.75 + 1.76 +// Top-to-bottom versions of placeholder property-names used in 1.77 +// testcases below: 1.78 +var gColumnPropertyMapping = 1.79 +{ 1.80 + "_main-size": "height", 1.81 + "_min-main-size": "min-height", 1.82 + "_max-main-size": "max-height", 1.83 + "_border-main-start-width": "border-top-width", 1.84 + "_border-main-end-width": "border-bottom-width", 1.85 + "_padding-main-start": "padding-top", 1.86 + "_padding-main-end": "padding-bottom", 1.87 + "_margin-main-start": "margin-top", 1.88 + "_margin-main-end": "margin-bottom" 1.89 +}; 1.90 + 1.91 +// Bottom-to-top versions of placeholder property-names used in 1.92 +// testcases below: 1.93 +var gColumnReversePropertyMapping = 1.94 +{ 1.95 + "_main-size": "height", 1.96 + "_min-main-size": "min-height", 1.97 + "_max-main-size": "max-height", 1.98 + "_border-main-start-width": "border-bottom-width", 1.99 + "_border-main-end-width": "border-top-width", 1.100 + "_padding-main-start": "padding-bottom", 1.101 + "_padding-main-end": "padding-top", 1.102 + "_margin-main-start": "margin-bottom", 1.103 + "_margin-main-end": "margin-top" 1.104 +}; 1.105 + 1.106 +// The list of actual testcase definitions: 1.107 +var gFlexboxTestcases = 1.108 +[ 1.109 + // No flex properties specified --> should just use 'width' for sizing 1.110 + { 1.111 + items: 1.112 + [ 1.113 + { "_main-size": [ "40px", "40px" ] }, 1.114 + { "_main-size": [ "65px", "65px" ] }, 1.115 + ] 1.116 + }, 1.117 + // flex-basis is specified: 1.118 + { 1.119 + items: 1.120 + [ 1.121 + { "flex-basis": "50px", 1.122 + "_main-size": [ null, "50px" ] 1.123 + }, 1.124 + { 1.125 + "flex-basis": "20px", 1.126 + "_main-size": [ null, "20px" ] 1.127 + }, 1.128 + ] 1.129 + }, 1.130 + // flex-basis is *large* -- sum of flex-basis values is > flex container size: 1.131 + // (w/ 0 flex-shrink so we don't shrink): 1.132 + { 1.133 + items: 1.134 + [ 1.135 + { 1.136 + "flex": "0 0 150px", 1.137 + "_main-size": [ null, "150px" ] 1.138 + }, 1.139 + { 1.140 + "flex": "0 0 90px", 1.141 + "_main-size": [ null, "90px" ] 1.142 + }, 1.143 + ] 1.144 + }, 1.145 + // flex-basis is *large* -- each flex-basis value is > flex container size: 1.146 + // (w/ 0 flex-shrink so we don't shrink): 1.147 + { 1.148 + items: 1.149 + [ 1.150 + { 1.151 + "flex": "0 0 250px", 1.152 + "_main-size": [ null, "250px" ] 1.153 + }, 1.154 + { 1.155 + "flex": "0 0 400px", 1.156 + "_main-size": [ null, "400px" ] 1.157 + }, 1.158 + ] 1.159 + }, 1.160 + // flex-basis has percentage value: 1.161 + { 1.162 + items: 1.163 + [ 1.164 + { 1.165 + "flex-basis": "30%", 1.166 + "_main-size": [ null, "60px" ] 1.167 + }, 1.168 + { 1.169 + "flex-basis": "45%", 1.170 + "_main-size": [ null, "90px" ] 1.171 + }, 1.172 + ] 1.173 + }, 1.174 + // flex-basis has calc(percentage) value: 1.175 + { 1.176 + items: 1.177 + [ 1.178 + { 1.179 + "flex-basis": "calc(20%)", 1.180 + "_main-size": [ null, "40px" ] 1.181 + }, 1.182 + { 1.183 + "flex-basis": "calc(80%)", 1.184 + "_main-size": [ null, "160px" ] 1.185 + }, 1.186 + ] 1.187 + }, 1.188 + // flex-basis has calc(percentage +/- length) value: 1.189 + { 1.190 + items: 1.191 + [ 1.192 + { 1.193 + "flex-basis": "calc(10px + 20%)", 1.194 + "_main-size": [ null, "50px" ] 1.195 + }, 1.196 + { 1.197 + "flex-basis": "calc(60% - 1px)", 1.198 + "_main-size": [ null, "119px" ] 1.199 + }, 1.200 + ] 1.201 + }, 1.202 + // flex-grow is specified: 1.203 + { 1.204 + items: 1.205 + [ 1.206 + { 1.207 + "flex": "1", 1.208 + "_main-size": [ null, "60px" ] 1.209 + }, 1.210 + { 1.211 + "flex": "2", 1.212 + "_main-size": [ null, "120px" ] 1.213 + }, 1.214 + { 1.215 + "flex": "0 20px", 1.216 + "_main-size": [ null, "20px" ] 1.217 + } 1.218 + ] 1.219 + }, 1.220 + // Same ratio as prev. testcase; making sure we handle float inaccuracy 1.221 + { 1.222 + items: 1.223 + [ 1.224 + { 1.225 + "flex": "100000", 1.226 + "_main-size": [ null, "60px" ] 1.227 + }, 1.228 + { 1.229 + "flex": "200000", 1.230 + "_main-size": [ null, "120px" ] 1.231 + }, 1.232 + { 1.233 + "flex": "0.000001 20px", 1.234 + "_main-size": [ null, "20px" ] 1.235 + } 1.236 + ] 1.237 + }, 1.238 + // Same ratio as prev. testcase, but with items cycled and w/ 1.239 + // "flex: none" & explicit size instead of "flex: 0 20px" 1.240 + { 1.241 + items: 1.242 + [ 1.243 + { 1.244 + "flex": "none", 1.245 + "_main-size": [ "20px", "20px" ] 1.246 + }, 1.247 + { 1.248 + "flex": "1", 1.249 + "_main-size": [ null, "60px" ] 1.250 + }, 1.251 + { 1.252 + "flex": "2", 1.253 + "_main-size": [ null, "120px" ] 1.254 + } 1.255 + ] 1.256 + }, 1.257 + 1.258 + // ...and now with flex-grow:[huge] to be sure we handle infinite float values 1.259 + // gracefully. 1.260 + { 1.261 + items: 1.262 + [ 1.263 + { 1.264 + "flex": "9999999999999999999999999999999999999999999999999999999", 1.265 + "_main-size": [ null, "200px" ] 1.266 + }, 1.267 + ] 1.268 + }, 1.269 + { 1.270 + items: 1.271 + [ 1.272 + { 1.273 + "flex": "9999999999999999999999999999999999999999999999999999999", 1.274 + "_main-size": [ null, "50px" ] 1.275 + }, 1.276 + { 1.277 + "flex": "9999999999999999999999999999999999999999999999999999999", 1.278 + "_main-size": [ null, "50px" ] 1.279 + }, 1.280 + { 1.281 + "flex": "9999999999999999999999999999999999999999999999999999999", 1.282 + "_main-size": [ null, "50px" ] 1.283 + }, 1.284 + { 1.285 + "flex": "9999999999999999999999999999999999999999999999999999999", 1.286 + "_main-size": [ null, "50px" ] 1.287 + }, 1.288 + ] 1.289 + }, 1.290 + { 1.291 + items: 1.292 + [ 1.293 + { 1.294 + "flex": "99999999999999999999999999999999999", 1.295 + "_main-size": [ null, "50px" ] 1.296 + }, 1.297 + { 1.298 + "flex": "99999999999999999999999999999999999", 1.299 + "_main-size": [ null, "50px" ] 1.300 + }, 1.301 + { 1.302 + "flex": "99999999999999999999999999999999999", 1.303 + "_main-size": [ null, "50px" ] 1.304 + }, 1.305 + { 1.306 + "flex": "99999999999999999999999999999999999", 1.307 + "_main-size": [ null, "50px" ] 1.308 + }, 1.309 + ] 1.310 + }, 1.311 + 1.312 + // And now, some testcases to check that we handle float accumulation error 1.313 + // gracefully. 1.314 + 1.315 + // First, a testcase with just a custom-sized huge container, to be sure we'll 1.316 + // be able to handle content on that scale, in the subsequent more-complex 1.317 + // testcases: 1.318 + { 1.319 + container_properties: 1.320 + { 1.321 + "_main-size": "9000000px" 1.322 + }, 1.323 + items: 1.324 + [ 1.325 + { 1.326 + "flex": "1", 1.327 + "_main-size": [ null, "9000000px" ] 1.328 + }, 1.329 + ] 1.330 + }, 1.331 + // ...and now with two flex items dividing up that container's huge size: 1.332 + { 1.333 + container_properties: 1.334 + { 1.335 + "_main-size": "9000000px" 1.336 + }, 1.337 + items: 1.338 + [ 1.339 + { 1.340 + "flex": "2", 1.341 + "_main-size": [ null, "6000000px" ] 1.342 + }, 1.343 + { 1.344 + "flex": "1", 1.345 + "_main-size": [ null, "3000000px" ] 1.346 + }, 1.347 + ] 1.348 + }, 1.349 + 1.350 + // OK, now to actually test accumulation error. Below, we have six flex items 1.351 + // splitting up the container's size, with huge differences between flex 1.352 + // weights. For simplicity, I've set up the weights so that they sum exactly 1.353 + // to the container's size in px. So 1 unit of flex *should* get you 1px. 1.354 + // 1.355 + // NOTE: The expected computed "_main-size" values for the flex items below 1.356 + // appear to add up to more than their container's size, which would suggest 1.357 + // that they overflow their container unnecessarily. But they don't actually 1.358 + // overflow -- this discrepancy is simply because Gecko's code for reporting 1.359 + // computed-sizes rounds to 6 significant figures (in particular, the method 1.360 + // (nsTSubstring_CharT::AppendFloat() does this). Internally, in app-units, 1.361 + // the child frames' main-sizes add up exactly to the container's main-size, 1.362 + // as you'd hope & expect. 1.363 + { 1.364 + container_properties: 1.365 + { 1.366 + "_main-size": "9000000px" 1.367 + }, 1.368 + items: 1.369 + [ 1.370 + { 1.371 + "flex": "3000000", 1.372 + "_main-size": [ null, "3000000px" ] 1.373 + }, 1.374 + { 1.375 + "flex": "1", 1.376 + "_main-size": [ null, "1px" ] 1.377 + }, 1.378 + { 1.379 + "flex": "1", 1.380 + "_main-size": [ null, "1px" ] 1.381 + }, 1.382 + { 1.383 + "flex": "2999999", 1.384 + // NOTE: Expected value is off slightly, from float error when 1.385 + // resolving flexible lengths & when generating computed value string: 1.386 + "_main-size": [ null, "3000000px" ] 1.387 + }, 1.388 + { 1.389 + "flex": "2999998", 1.390 + // NOTE: Expected value is off slightly, from float error when 1.391 + // resolving flexible lengths & when generating computed value string: 1.392 + "_main-size": [ null, "3000000px" ] 1.393 + }, 1.394 + { 1.395 + "flex": "1", 1.396 + "_main-size": [ null, "1px", 0.2 ] 1.397 + }, 1.398 + ] 1.399 + }, 1.400 + // Same flex items as previous testcase, but now reordered such that the items 1.401 + // with tiny flex weights are all listed last: 1.402 + { 1.403 + container_properties: 1.404 + { 1.405 + "_main-size": "9000000px" 1.406 + }, 1.407 + items: 1.408 + [ 1.409 + { 1.410 + "flex": "3000000", 1.411 + "_main-size": [ null, "3000000px" ] 1.412 + }, 1.413 + { 1.414 + "flex": "2999999", 1.415 + // NOTE: Expected value is off slightly, from float error when 1.416 + // resolving flexible lengths & when generating computed value string: 1.417 + "_main-size": [ null, "3000000px" ] 1.418 + }, 1.419 + { 1.420 + "flex": "2999998", 1.421 + // NOTE: Expected value is off slightly, from float error when 1.422 + // resolving flexible lengths & when generating computed value string: 1.423 + "_main-size": [ null, "3000000px" ] 1.424 + }, 1.425 + { 1.426 + "flex": "1", 1.427 + "_main-size": [ null, "1px", 0.2 ] 1.428 + }, 1.429 + { 1.430 + "flex": "1", 1.431 + "_main-size": [ null, "1px", 0.2 ] 1.432 + }, 1.433 + { 1.434 + "flex": "1", 1.435 + "_main-size": [ null, "1px", 0.2 ] 1.436 + }, 1.437 + ] 1.438 + }, 1.439 + // Same flex items as previous testcase, but now reordered such that the items 1.440 + // with tiny flex weights are all listed first: 1.441 + { 1.442 + container_properties: 1.443 + { 1.444 + "_main-size": "9000000px" 1.445 + }, 1.446 + items: 1.447 + [ 1.448 + { 1.449 + "flex": "1", 1.450 + // NOTE: Expected value is off slightly, from float error when 1.451 + // resolving flexible lengths: 1.452 + "_main-size": [ null, "1px", 0.2 ] 1.453 + }, 1.454 + { 1.455 + "flex": "1", 1.456 + // NOTE: Expected value is off slightly, from float error when 1.457 + // resolving flexible lengths: 1.458 + "_main-size": [ null, "1px", 0.2 ] 1.459 + }, 1.460 + { 1.461 + "flex": "1", 1.462 + // NOTE: Expected value is off slightly, from float error when 1.463 + // resolving flexible lengths: 1.464 + "_main-size": [ null, "1px", 0.2 ] 1.465 + }, 1.466 + { 1.467 + "flex": "3000000", 1.468 + "_main-size": [ null, "3000000px" ] 1.469 + }, 1.470 + { 1.471 + "flex": "2999999", 1.472 + // NOTE: Expected value is off slightly, from float error when 1.473 + // resolving flexible lengths & when generating computed value string: 1.474 + "_main-size": [ null, "3000000px" ] 1.475 + }, 1.476 + { 1.477 + "flex": "2999998", 1.478 + // NOTE: Expected value is off slightly, from float error when 1.479 + // resolving flexible lengths & when generating computed value string: 1.480 + "_main-size": [ null, "3000000px" ] 1.481 + }, 1.482 + ] 1.483 + }, 1.484 + 1.485 + // Trying "flex: auto" (== "1 1 auto") w/ a mix of flex-grow/flex-basis values 1.486 + { 1.487 + items: 1.488 + [ 1.489 + { 1.490 + "flex": "auto", 1.491 + "_main-size": [ null, "45px" ] 1.492 + }, 1.493 + { 1.494 + "flex": "2", 1.495 + "_main-size": [ null, "90px" ] 1.496 + }, 1.497 + { 1.498 + "flex": "20px 1 0", 1.499 + "_main-size": [ null, "65px" ] 1.500 + } 1.501 + ] 1.502 + }, 1.503 + // Same as previous, but with items cycled & different syntax 1.504 + { 1.505 + items: 1.506 + [ 1.507 + { 1.508 + "flex": "20px", 1.509 + "_main-size": [ null, "65px" ] 1.510 + }, 1.511 + { 1.512 + "flex": "1", 1.513 + "_main-size": [ null, "45px" ] 1.514 + }, 1.515 + { 1.516 + "flex": "2", 1.517 + "_main-size": [ null, "90px" ] 1.518 + } 1.519 + ] 1.520 + }, 1.521 + { 1.522 + items: 1.523 + [ 1.524 + { 1.525 + "flex": "2", 1.526 + "_main-size": [ null, "100px" ], 1.527 + "border": "0px dashed", 1.528 + "_border-main-start-width": [ "5px", "5px" ], 1.529 + "_border-main-end-width": [ "15px", "15px" ], 1.530 + "_margin-main-start": [ "22px", "22px" ], 1.531 + "_margin-main-end": [ "8px", "8px" ] 1.532 + }, 1.533 + { 1.534 + "flex": "1", 1.535 + "_main-size": [ null, "50px" ], 1.536 + "_margin-main-start": [ "auto", "0px" ], 1.537 + "_padding-main-end": [ "auto", "0px" ], 1.538 + } 1.539 + ] 1.540 + }, 1.541 + // Test negative flexibility: 1.542 + 1.543 + // Basic testcase: just 1 item (relying on initial "flex-shrink: 1") -- 1.544 + // should shrink to container size. 1.545 + { 1.546 + items: 1.547 + [ 1.548 + { "_main-size": [ "400px", "200px" ] }, 1.549 + ], 1.550 + }, 1.551 + // ...and now with a "flex" specification and a different flex-shrink value: 1.552 + { 1.553 + items: 1.554 + [ 1.555 + { 1.556 + "flex": "4 2 250px", 1.557 + "_main-size": [ null, "200px" ] 1.558 + }, 1.559 + ], 1.560 + }, 1.561 + // ...and now with multiple items, which all shrink proportionally (by 50%) 1.562 + // to fit to the container, since they have the same (initial) flex-shrink val 1.563 + { 1.564 + items: 1.565 + [ 1.566 + { "_main-size": [ "80px", "40px" ] }, 1.567 + { "_main-size": [ "40px", "20px" ] }, 1.568 + { "_main-size": [ "30px", "15px" ] }, 1.569 + { "_main-size": [ "250px", "125px" ] }, 1.570 + ] 1.571 + }, 1.572 + // ...and now with positive flexibility specified. (should have no effect, so 1.573 + // everything still shrinks by the same proportion, since the flex-shrink 1.574 + // values are all the same). 1.575 + { 1.576 + items: 1.577 + [ 1.578 + { 1.579 + "flex": "4 3 100px", 1.580 + "_main-size": [ null, "80px" ] 1.581 + }, 1.582 + { 1.583 + "flex": "5 3 50px", 1.584 + "_main-size": [ null, "40px" ] 1.585 + }, 1.586 + { 1.587 + "flex": "0 3 100px", 1.588 + "_main-size": [ null, "80px" ] 1.589 + } 1.590 + ] 1.591 + }, 1.592 + // ...and now with *different* flex-shrink values: 1.593 + { 1.594 + items: 1.595 + [ 1.596 + { 1.597 + "flex": "4 2 50px", 1.598 + "_main-size": [ null, "30px" ] 1.599 + }, 1.600 + { 1.601 + "flex": "5 3 50px", 1.602 + "_main-size": [ null, "20px" ] 1.603 + }, 1.604 + { 1.605 + "flex": "0 0 150px", 1.606 + "_main-size": [ null, "150px" ] 1.607 + } 1.608 + ] 1.609 + }, 1.610 + // Same ratio as prev. testcase; making sure we handle float inaccuracy 1.611 + { 1.612 + items: 1.613 + [ 1.614 + { 1.615 + "flex": "4 20000000 50px", 1.616 + "_main-size": [ null, "30px" ] 1.617 + }, 1.618 + { 1.619 + "flex": "5 30000000 50px", 1.620 + "_main-size": [ null, "20px" ] 1.621 + }, 1.622 + { 1.623 + "flex": "0 0.0000001 150px", 1.624 + "_main-size": [ null, "150px" ] 1.625 + } 1.626 + ] 1.627 + }, 1.628 + // Another "different flex-shrink values" testcase: 1.629 + { 1.630 + items: 1.631 + [ 1.632 + { 1.633 + "flex": "4 2 115px", 1.634 + "_main-size": [ null, "69px" ] 1.635 + }, 1.636 + { 1.637 + "flex": "5 1 150px", 1.638 + "_main-size": [ null, "120px" ] 1.639 + }, 1.640 + { 1.641 + "flex": "1 4 30px", 1.642 + "_main-size": [ null, "6px" ] 1.643 + }, 1.644 + { 1.645 + "flex": "1 0 5px", 1.646 + "_main-size": [ null, "5px" ] 1.647 + }, 1.648 + ] 1.649 + }, 1.650 + 1.651 + // ...and now with min-size (clamping the effects of flex-shrink on one item): 1.652 + { 1.653 + items: 1.654 + [ 1.655 + { 1.656 + "flex": "4 5 75px", 1.657 + "_min-main-size": "50px", 1.658 + "_main-size": [ null, "50px" ], 1.659 + }, 1.660 + { 1.661 + "flex": "5 5 100px", 1.662 + "_main-size": [ null, "62.5px" ] 1.663 + }, 1.664 + { 1.665 + "flex": "0 4 125px", 1.666 + "_main-size": [ null, "87.5px" ] 1.667 + } 1.668 + ] 1.669 + }, 1.670 + 1.671 + // Test a min-size that's much larger than initial preferred size, but small 1.672 + // enough that our flexed size pushes us over it: 1.673 + { 1.674 + items: 1.675 + [ 1.676 + { 1.677 + "flex": "auto", 1.678 + "_min-main-size": "110px", 1.679 + "_main-size": [ "50px", "125px" ] 1.680 + }, 1.681 + { 1.682 + "flex": "auto", 1.683 + "_main-size": [ null, "75px" ] 1.684 + } 1.685 + ] 1.686 + }, 1.687 + 1.688 + // Test a min-size that's much larger than initial preferred size, and is 1.689 + // even larger than our positively-flexed size, so that we have to increase it 1.690 + // (as a 'min violation') after we've flexed. 1.691 + { 1.692 + items: 1.693 + [ 1.694 + { 1.695 + "flex": "auto", 1.696 + "_min-main-size": "150px", 1.697 + "_main-size": [ "50px", "150px" ] 1.698 + }, 1.699 + { 1.700 + "flex": "auto", 1.701 + "_main-size": [ null, "50px" ] 1.702 + } 1.703 + ] 1.704 + }, 1.705 + 1.706 + // Test min-size on multiple items simultaneously: 1.707 + { 1.708 + items: 1.709 + [ 1.710 + { 1.711 + "flex": "auto", 1.712 + "_min-main-size": "20px", 1.713 + "_main-size": [ null, "20px" ] 1.714 + }, 1.715 + { 1.716 + "flex": "9 auto", 1.717 + "_min-main-size": "150px", 1.718 + "_main-size": [ "50px", "180px" ] 1.719 + }, 1.720 + ] 1.721 + }, 1.722 + { 1.723 + items: 1.724 + [ 1.725 + { 1.726 + "flex": "1 1 0px", 1.727 + "_min-main-size": "90px", 1.728 + "_main-size": [ null, "90px" ] 1.729 + }, 1.730 + { 1.731 + "flex": "1 1 0px", 1.732 + "_min-main-size": "80px", 1.733 + "_main-size": [ null, "80px" ] 1.734 + }, 1.735 + { 1.736 + "flex": "1 1 40px", 1.737 + "_main-size": [ null, "30px" ] 1.738 + } 1.739 + ] 1.740 + }, 1.741 + 1.742 + // Test a case where _min-main-size will be violated on different items in 1.743 + // successive iterations of the "resolve the flexible lengths" loop 1.744 + { 1.745 + items: 1.746 + [ 1.747 + { 1.748 + "flex": "1 2 100px", 1.749 + "_min-main-size": "90px", 1.750 + "_main-size": [ null, "90px" ] 1.751 + }, 1.752 + { 1.753 + "flex": "1 1 100px", 1.754 + "_min-main-size": "70px", 1.755 + "_main-size": [ null, "70px" ] 1.756 + }, 1.757 + { 1.758 + "flex": "1 1 100px", 1.759 + "_main-size": [ null, "40px" ] 1.760 + } 1.761 + ] 1.762 + }, 1.763 + 1.764 + // Test some cases that have a min-size violation on one item and a 1.765 + // max-size violation on another: 1.766 + 1.767 + // Here, both items initially grow to 100px. That violates both 1.768 + // items' sizing constraints (it's smaller than the min-size and larger than 1.769 + // the max-size), so we clamp both of them and sum the clamping-differences: 1.770 + // 1.771 + // (130px - 100px) + (50px - 100px) = (30px) + (-50px) = -20px 1.772 + // 1.773 + // This sum is negative, so (per spec) we freeze the item that had its 1.774 + // max-size violated (the second one) and restart the algorithm. This time, 1.775 + // all the available space (200px - 50px = 150px) goes to the not-yet-frozen 1.776 + // first item, and that puts it above its min-size, so all is well. 1.777 + { 1.778 + items: 1.779 + [ 1.780 + { 1.781 + "flex": "auto", 1.782 + "_min-main-size": "130px", 1.783 + "_main-size": [ null, "150px" ] 1.784 + }, 1.785 + { 1.786 + "flex": "auto", 1.787 + "_max-main-size": "50px", 1.788 + "_main-size": [ null, "50px" ] 1.789 + }, 1.790 + ] 1.791 + }, 1.792 + 1.793 + // As above, both items initially grow to 100px, and that violates both items' 1.794 + // constraints. However, now the sum of the clamping differences is: 1.795 + // 1.796 + // (130px - 100px) + (80px - 100px) = (30px) + (-20px) = 10px 1.797 + // 1.798 + // This sum is positive, so (per spec) we freeze the item that had its 1.799 + // min-size violated (the first one) and restart the algorithm. This time, 1.800 + // all the available space (200px - 130px = 70px) goes to the not-yet-frozen 1.801 + // second item, and that puts it below its max-size, so all is well. 1.802 + { 1.803 + items: 1.804 + [ 1.805 + { 1.806 + "flex": "auto", 1.807 + "_min-main-size": "130px", 1.808 + "_main-size": [ null, "130px" ] 1.809 + }, 1.810 + { 1.811 + "flex": "auto", 1.812 + "_max-main-size": "80px", 1.813 + "_main-size": [ null, "70px" ] 1.814 + }, 1.815 + ] 1.816 + }, 1.817 + 1.818 + // As above, both items initially grow to 100px, and that violates both items' 1.819 + // constraints. So we clamp both items and sum the clamping differences to 1.820 + // see what to do next. The sum is: 1.821 + // 1.822 + // (80px - 100px) + (120px - 100px) = (-20px) + (20px) = 0px 1.823 + // 1.824 + // Per spec, if the sum is 0, we're done -- we leave both items at their 1.825 + // clamped sizes. 1.826 + { 1.827 + items: 1.828 + [ 1.829 + { 1.830 + "flex": "auto", 1.831 + "_max-main-size": "80px", 1.832 + "_main-size": [ null, "80px" ] 1.833 + }, 1.834 + { 1.835 + "flex": "auto", 1.836 + "_min-main-size": "120px", 1.837 + "_main-size": [ null, "120px" ] 1.838 + }, 1.839 + ] 1.840 + }, 1.841 +];