/* Flexbox Layout Tests
* --------------------
* This mochitest exercises our implementation of the flexbox layout algorithm
* by creating a flex container, inserting some flexible children, and then
* verifying that the computed width of those children is what we expect.
*
* See flexbox_layout_testcases.js for the actual testcases & testcase format.
*/
function getComputedStyleWrapper(elem, prop)
{
return window.getComputedStyle(elem).getPropertyValue(prop);
}
function setPossiblyAliasedProperty(aElem, aPropertyName, aPropertyValue,
aPropertyMapping)
{
let actualPropertyName = (aPropertyName in aPropertyMapping ?
aPropertyMapping[aPropertyName] : aPropertyName);
if (!gCSSProperties[actualPropertyName]) {
ok(false, "Bug in test: property '" + actualPropertyName + "' doesn't exist in gCSSProperties");
} else {
let domPropertyName = gCSSProperties[actualPropertyName].domProp;
aElem.style[domPropertyName] = aPropertyValue;
}
}
// Helper function to strip "px" off the end of a string
// (so that we can compare two lengths using "isfuzzy()" with an epsilon)
function stripPx(aLengthInPx)
{
let pxOffset = aLengthInPx.length - 2; // subtract off length of "px"
// Sanity-check the arg:
ok(pxOffset > 0 && aLengthInPx.substr(pxOffset) == "px", "expecting value with 'px' units");
return aLengthInPx.substr(0, pxOffset);
}
// The main test function.
// aFlexboxTestcase is an entry from the list in flexbox_layout_testcases.js
function testFlexboxTestcase(aFlexboxTestcase, aFlexDirection, aPropertyMapping)
{
let content = document.getElementById("content");
// Apply testcase's customizations for flex container (if any).
if (aFlexboxTestcase.container_properties) {
for (let propName in aFlexboxTestcase.container_properties) {
let propValue = aFlexboxTestcase.container_properties[propName];
setPossiblyAliasedProperty(flexContainer, propName, propValue,
aPropertyMapping);
}
}
// Create & append flex items
aFlexboxTestcase.items.forEach(function(aChildSpec) {
// Create an element for our item
let child = document.createElement("div");
// Set all the specified properties on our item
for (let propName in aChildSpec) {
// aChildSpec[propName] is either a specified value,
// or an array of [specifiedValue, computedValue]
let specifiedValue = Array.isArray(aChildSpec[propName]) ?
aChildSpec[propName][0] :
aChildSpec[propName];
// SANITY CHECK:
if (Array.isArray(aChildSpec[propName])) {
ok(aChildSpec[propName].length >= 2 &&
aChildSpec[propName].length <= 3, "unexpected number of elements in array within child spec");
}
// Append the item to the flex container
flexContainer.appendChild(child);
});
// Append the flex container
content.appendChild(flexContainer);
// NOW: Test the computed style on the flex items
let child = flexContainer.firstChild;
for (let i = 0; i < aFlexboxTestcase.items.length; i++) {
if (!child) { // sanity
ok(false, "should have created a child for each child-spec");
}
let childSpec = aFlexboxTestcase.items[i];
for (let propName in childSpec) {
if (Array.isArray(childSpec[propName])) {
let expectedVal = childSpec[propName][1];
let actualPropName = (propName in aPropertyMapping ?
aPropertyMapping[propName] : propName);
let actualVal = getComputedStyleWrapper(child, actualPropName);
let message = "computed value of '" + actualPropName + "' should match expected";
if (childSpec[propName].length > 2) {
// 3rd entry in array is epsilon
// Need to strip off "px" units in order to use epsilon:
let actualValNoPx = stripPx(actualVal);
let expectedValNoPx = stripPx(expectedVal);
isfuzzy(actualValNoPx, expectedValNoPx,
childSpec[propName][2], message);
} else {
is(actualVal, expectedVal, message);
}
}
}
child = child.nextSibling;
}
// Clean up: drop the flex container.
content.removeChild(flexContainer);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.