// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information. // // module WinJSTests.Less { "use strict"; // For use with standard attributes (doesn't support attribute names with vendor prefixes) function getDashedStandardAttribute(attribute) { return attribute.replace(/[A-Z]/g, function (x) { return "-" + x[0].toLowerCase(); }); } // Returns a dashed CSS class name which is a combination of *attribute* (camel case) // and *values* (dashed case). // Example: toCssTestClass("flexFlow", "column", "wrap-reverse") => flex-flow-column-wrap-reverse // Designed to be used with the rules in FlexboxMixins.less. function toCssTestClass(attribute, ...values) { return getDashedStandardAttribute(attribute) + "-" + values.join("-"); } // Synonyms map from standard CSS attribute/values to alternatives implemented by browsers. // CSS attribute synonyms // Camel case var attributeSynonyms = { "alignContent": ["msFlexLinePack", "webkitAlignContent"], "alignItems": ["msFlexAlign", "webkitAlignItems"], "alignSelf": ["msFlexItemAlign", "webkitAlignSelf"], "justifyContent": ["msFlexPack", "webkitJustifyContent"], "flexWrap": ["msFlexWrap", "webkitFlexWrap"], "flexDirection": ["msFlexDirection", "webkitFlexDirection"], "order": ["flex-order", "msFlexOrder", "webkitOrder"], "flexGrow": ["msFlexPositive", "webkitFlexGrow"], "flexShrink": ["msFlexNegative", "webkitFlexShrink"], "flexBasis": ["msFlexPreferredSize", "webkitFlexBasis"] }; // CSS value synonyms // Dashed case var valueSynonyms = { "flex": ["-ms-flexbox", "-webkit-flex"], "inline-flex": ["-ms-inline-flexbox", "-webkit-inline-flex"], "flex-start": ["start"], "flex-end": ["end"], "space-between": ["justify"], "space-around": ["distribute"], "nowrap": ["none"] }; function allAlternatives(synonymMap, standard) { var synonyms = synonymMap[standard]; return synonyms ? [standard].concat(synonyms) : [standard]; } function testAttribute(element, standardAttribute, standardValue) { var foundMatch = false; var attributes = allAlternatives(attributeSynonyms, standardAttribute); var values = allAlternatives(valueSynonyms, standardValue); for (var i = 0; i < attributes.length && !foundMatch; i++) { var attr = attributes[i]; for (var j = 0; j < values.length && !foundMatch; j++) { var val = values[j]; try { if ("" + val === "" + getComputedStyle(element)[attr]) { foundMatch = true; } } catch (e) { // Eat any exceptions that may arise from trying to read // an unsupported style } } } LiveUnit.Assert.isTrue(foundMatch, "LESS flexbox mixins don't properly support '" + standardAttribute + ": " + standardValue + "' in this environment"); } // Verifies the CSS style of an element with class name *className* matches // *attributesAndValues*. *attributesAndValues* is a map between CSS attributes and values. function testRule(className, attributesAndValues) { var root = document.getElementById("flexbox-mixin-tests"); var element = document.createElement("div"); element.className = className; root.appendChild(element); Object.keys(attributesAndValues).forEach(function (attribute) { testAttribute(element, attribute, attributesAndValues[attribute]); }); root.removeChild(element); } // Returns a function which verifies that *attribute* works with each of *values*. Applies a CSS // class to an element which is a combination of the *attribute* and value and verifies that this // causes the element to have a particular value for its CSS *attribute*. // // Example: // // makeTestAttributeWithValues("align-items", ["stretch", "flex-start"]) // Tests that an element: // - with class .align-items-stretch has attribute "align-items" equal to "stretch" // - with class .align-items-flex-start has attribute "align-items" equal to "flex-start" // function makeTestAttributeWithValues(attribute, values) { return function () { values.forEach(function (v) { var attributeAndValue = {}; attributeAndValue[attribute] = v; testRule(toCssTestClass(attribute, v), attributeAndValue); }); }; } var flexWrapValues = ["nowrap", "wrap", "wrap-reverse"]; var flexDirectionValues = ["row", "row-reverse", "column", "column-reverse"]; export class FlexboxMixinTests { setUp() { var newNode = document.createElement("div"); newNode.id = "flexbox-mixin-tests"; document.body.appendChild(newNode); } tearDown() { var element = document.getElementById("flexbox-mixin-tests"); document.body.removeChild(element); } testDisplay = function () { testRule("display-flex", { display: "flex" }); testRule("display-inline-flex", { display: "inline-flex" }); }; testAlignContent = makeTestAttributeWithValues( "alignContent", ["stretch", "flex-start", "flex-end", "center", "space-between", "space-around"] ); testAlignItems = makeTestAttributeWithValues( "alignItems", ["stretch", "flex-start", "flex-end", "center", "baseline"] ); testAlignSelf = makeTestAttributeWithValues( "alignSelf", ["flex-start", "flex-end", "center", "baseline", "stretch"] ); testJustifyContent = makeTestAttributeWithValues( "justifyContent", ["flex-start", "flex-end", "center", "space-between", "space-around"] ); testFlexWrap = makeTestAttributeWithValues( "flexWrap", flexWrapValues ); testFlexDirection = makeTestAttributeWithValues( "flexDirection", flexDirectionValues ); testFlexFlow = function () { flexDirectionValues.forEach(function (direction) { var className = toCssTestClass("flexFlow", direction, "nowrap"); testRule(className, { flexDirection: direction, flexWrap: "nowrap" }); }); flexWrapValues.forEach(function (wrap) { var className = toCssTestClass("flexFlow", "row", wrap); testRule(className, { flexDirection: "row", flexWrap: wrap }); }); }; testOrder = function () { testRule("order-8", { order: "8" }); }; testFlex = function () { testRule("flex-grow-8", { flexGrow: "8", flexShrink: "1", flexBasis: "auto" }); testRule("flex-shrink-4", { flexGrow: "0", flexShrink: "4", flexBasis: "auto" }); testRule("flex-basis-2px", { flexGrow: "0", flexShrink: "1", flexBasis: "2px" }); testRule("flex-2-3-4px", { flexGrow: "2", flexShrink: "3", flexBasis: "4px" }); testRule("flex-none", { flexGrow: "0", flexShrink: "0", flexBasis: "auto" }); }; }; } LiveUnit.registerTestClass("WinJSTests.Less.FlexboxMixinTests");