use leading and trailing instead of hardcoded ygedge correctly apply margin auto on crossAxis enum.py and reformat reformat delete formating file revert unrelated changes add spaces apply justifycontent only if there aren't any auto margins fix enum definition rerun format apply auto as default values to width, height and flexBasis to conform with spec code review and additional tests added missing language bindings for c# and java regen tests added initial margin auto support use leading and trailing instead of hardcoded ygedge correctly apply margin auto on crossAxis enum.py and reformat delete formating file revert unrelated changes add spaces apply justifycontent only if there aren't any auto margins fix enum definition rerun format apply auto as default values to width, height and flexBasis to conform with spec code review and additional tests added missing language bindings for c# and java fix up rebase add javascript test another fix up
523 lines
16 KiB
JavaScript
Executable File
523 lines
16 KiB
JavaScript
Executable File
/**
|
|
* Copyright (c) 2014-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
|
|
window.onload = function() {
|
|
checkDefaultValues();
|
|
|
|
printTest(
|
|
new CPPEmitter(),
|
|
document.body.children[0],
|
|
document.body.children[1],
|
|
document.body.children[2]);
|
|
|
|
printTest(
|
|
new JavaEmitter(),
|
|
document.body.children[0],
|
|
document.body.children[1],
|
|
document.body.children[2]);
|
|
|
|
printTest(
|
|
new CSEmitter(),
|
|
document.body.children[0],
|
|
document.body.children[1],
|
|
document.body.children[2]);
|
|
|
|
printTest(
|
|
new JavascriptEmitter(),
|
|
document.body.children[0],
|
|
document.body.children[1],
|
|
document.body.children[2]);
|
|
}
|
|
|
|
function assert(condition, message) {
|
|
if (!condition) {
|
|
throw new Error(message);
|
|
}
|
|
}
|
|
|
|
function printTest(e, LTRContainer, RTLContainer, genericContainer) {
|
|
e.push([
|
|
'/**',
|
|
' * Copyright (c) 2014-present, Facebook, Inc.',
|
|
' * All rights reserved.',
|
|
' *',
|
|
' * This source code is licensed under the BSD-style license found in the',
|
|
' * LICENSE file in the root directory of this source tree. An additional grant',
|
|
' * of patent rights can be found in the PATENTS file in the same directory.',
|
|
' */',
|
|
'',
|
|
'// @Generated by gentest/gentest.rb from gentest/fixtures/' + document.title + '.html',
|
|
'',
|
|
]);
|
|
e.emitPrologue();
|
|
|
|
var LTRLayoutTree = calculateTree(LTRContainer);
|
|
var RTLLayoutTree = calculateTree(RTLContainer);
|
|
var genericLayoutTree = calculateTree(genericContainer);
|
|
|
|
|
|
for (var i = 0; i < genericLayoutTree.length; i++) {
|
|
e.emitTestPrologue(genericLayoutTree[i].name, genericLayoutTree[i].experiments);
|
|
|
|
if (genericLayoutTree[i].name == 'wrap_column') {
|
|
// Modify width and left values due to both safari and chrome not abiding by the
|
|
// specification. The undefined dimension of a parent should be defined by the total size
|
|
// of their children in that dimension.
|
|
// See diagram under flex-wrap header https://www.w3.org/TR/css-flexbox-1/
|
|
assert(LTRLayoutTree[0].width == 30, 'wrap_column LTR root.width should be 30');
|
|
LTRLayoutTree[0].width = 60;
|
|
assert(RTLLayoutTree[0].width == 30, 'wrap_column RTL root.width should be 30');
|
|
RTLLayoutTree[0].width = 60;
|
|
var children = RTLLayoutTree[0].children;
|
|
assert(children[0].left == 0, 'wrap_column RTL root_child0.left should be 0');
|
|
children[0].left = 30;
|
|
assert(children[1].left == 0, 'wrap_column RTL root_child0.left should be 0');
|
|
children[1].left = 30;
|
|
assert(children[2].left == 0, 'wrap_column RTL root_child2.left should be 0');
|
|
children[2].left = 30;
|
|
assert(children[3].left == -30, 'wrap_column RTL root_child3.left should be -30');
|
|
children[3].left = 0;
|
|
}
|
|
|
|
setupTestTree(
|
|
e,
|
|
undefined,
|
|
LTRLayoutTree[i],
|
|
genericLayoutTree[i],
|
|
'root',
|
|
null);
|
|
|
|
e.YGNodeCalculateLayout('root', e.YGDirectionLTR);
|
|
e.push('');
|
|
|
|
assertTestTree(e, LTRLayoutTree[i], 'root', null);
|
|
e.push('');
|
|
|
|
e.YGNodeCalculateLayout('root', e.YGDirectionRTL);
|
|
e.push('');
|
|
|
|
assertTestTree(e, RTLLayoutTree[i], 'root', null);
|
|
|
|
e.emitTestEpilogue(genericLayoutTree[i].experiments);
|
|
}
|
|
e.emitEpilogue();
|
|
|
|
e.print();
|
|
}
|
|
|
|
function assertTestTree(e, node, nodeName, parentName) {
|
|
e.AssertEQ(node.left, e.YGNodeLayoutGetLeft(nodeName));
|
|
e.AssertEQ(node.top, e.YGNodeLayoutGetTop(nodeName));
|
|
e.AssertEQ(node.width, e.YGNodeLayoutGetWidth(nodeName));
|
|
e.AssertEQ(node.height, e.YGNodeLayoutGetHeight(nodeName));
|
|
|
|
for (var i = 0; i < node.children.length; i++) {
|
|
e.push('');
|
|
var childName = nodeName + '_child' + i;
|
|
assertTestTree(e, node.children[i], childName, nodeName);
|
|
}
|
|
}
|
|
|
|
function checkDefaultValues() {
|
|
// Sanity check of the Yoga default values by test-template.html
|
|
[
|
|
{style:'flex-direction', value:'column'},
|
|
{style:'justify-content', value:'flex-start'},
|
|
{style:'align-content', value:'flex-start'},
|
|
{style:'align-items', value:'stretch'},
|
|
{style:'position', value:'relative'},
|
|
{style:'flex-wrap', value:'nowrap'},
|
|
{style:'overflow', value:'visible'},
|
|
{style:'flex-grow', value:'0'},
|
|
{style:'flex-shrink', value:'0'},
|
|
{style:'left', value:'undefined'},
|
|
{style:'top', value:'undefined'},
|
|
{style:'right', value:'undefined'},
|
|
{style:'bottom', value:'undefined'},
|
|
{style:'display', value:'flex'},
|
|
].forEach(function(item) {
|
|
assert(item.value === getDefaultStyleValue(item.style),
|
|
item.style + ' should be ' + item.value);
|
|
});
|
|
}
|
|
|
|
function setupTestTree(e, parent, node, genericNode, nodeName, parentName, index) {
|
|
e.emitTestTreePrologue(nodeName);
|
|
|
|
for (var style in node.style) {
|
|
// Skip position info for root as it messes up tests
|
|
if (node.declaredStyle[style] === "" &&
|
|
(style == 'position' ||
|
|
style == 'left' ||
|
|
style == 'top' ||
|
|
style == 'right' ||
|
|
style == 'bottom' ||
|
|
style == 'width' ||
|
|
style == 'height')) {
|
|
continue;
|
|
}
|
|
|
|
if (node.style[style] !== getDefaultStyleValue(style)) {
|
|
switch (style) {
|
|
case 'direction':
|
|
e.YGNodeStyleSetDirection(nodeName, directionValue(e, node.style[style]));
|
|
break;
|
|
case 'flex-direction':
|
|
e.YGNodeStyleSetFlexDirection(nodeName, flexDirectionValue(e, node.style[style]));
|
|
break;
|
|
case 'justify-content':
|
|
e.YGNodeStyleSetJustifyContent(nodeName, justifyValue(e, node.style[style]));
|
|
break;
|
|
case 'align-content':
|
|
e.YGNodeStyleSetAlignContent(nodeName, alignValue(e, node.style[style]));
|
|
break;
|
|
case 'align-items':
|
|
e.YGNodeStyleSetAlignItems(nodeName, alignValue(e, node.style[style]));
|
|
break;
|
|
case 'align-self':
|
|
if (!parent || node.style[style] !== parent.style['align-items']) {
|
|
e.YGNodeStyleSetAlignSelf(nodeName, alignValue(e, node.style[style]));
|
|
}
|
|
break;
|
|
case 'position':
|
|
e.YGNodeStyleSetPositionType(nodeName, positionValue(e, node.style[style]));
|
|
break;
|
|
case 'flex-wrap':
|
|
e.YGNodeStyleSetFlexWrap(nodeName, wrapValue(e, node.style[style]));
|
|
break;
|
|
case 'overflow':
|
|
e.YGNodeStyleSetOverflow(nodeName, overflowValue(e, node.style[style]));
|
|
break;
|
|
case 'flex-grow':
|
|
e.YGNodeStyleSetFlexGrow(nodeName, node.style[style]);
|
|
break;
|
|
case 'flex-shrink':
|
|
e.YGNodeStyleSetFlexShrink(nodeName, node.style[style]);
|
|
break;
|
|
case 'flex-basis':
|
|
e.YGNodeStyleSetFlexBasis(nodeName, pixelValue(e, node.style[style]));
|
|
break;
|
|
case 'left':
|
|
if (genericNode.rawStyle.indexOf('start:') >= 0) {
|
|
e.YGNodeStyleSetPosition(nodeName, e.YGEdgeStart, pixelValue(e, node.style[style]));
|
|
} else {
|
|
e.YGNodeStyleSetPosition(nodeName, e.YGEdgeLeft, pixelValue(e, node.style[style]));
|
|
}
|
|
break;
|
|
case 'top':
|
|
e.YGNodeStyleSetPosition(nodeName, e.YGEdgeTop, pixelValue(e, node.style[style]));
|
|
break;
|
|
case 'right':
|
|
if (genericNode.rawStyle.indexOf('end:') >= 0) {
|
|
e.YGNodeStyleSetPosition(nodeName, e.YGEdgeEnd, pixelValue(e, node.style[style]));
|
|
} else {
|
|
e.YGNodeStyleSetPosition(nodeName, e.YGEdgeRight, pixelValue(e, node.style[style]));
|
|
}
|
|
break;
|
|
case 'bottom':
|
|
e.YGNodeStyleSetPosition(nodeName, e.YGEdgeBottom, pixelValue(e, node.style[style]));
|
|
break;
|
|
case 'margin-left':
|
|
if (genericNode.rawStyle.indexOf('margin-start:') >= 0) {
|
|
e.YGNodeStyleSetMargin(nodeName, e.YGEdgeStart, pixelValue(e, node.style[style]));
|
|
} else {
|
|
e.YGNodeStyleSetMargin(nodeName, e.YGEdgeLeft, pixelValue(e, node.style[style]));
|
|
}
|
|
break;
|
|
case 'margin-top':
|
|
e.YGNodeStyleSetMargin(nodeName, e.YGEdgeTop, pixelValue(e, node.style[style]));
|
|
break;
|
|
case 'margin-right':
|
|
if (genericNode.rawStyle.indexOf('margin-end:') >= 0) {
|
|
e.YGNodeStyleSetMargin(nodeName, e.YGEdgeEnd, pixelValue(e, node.style[style]));
|
|
} else {
|
|
e.YGNodeStyleSetMargin(nodeName, e.YGEdgeRight, pixelValue(e, node.style[style]));
|
|
}
|
|
break;
|
|
case 'margin-bottom':
|
|
e.YGNodeStyleSetMargin(nodeName, e.YGEdgeBottom, pixelValue(e, node.style[style]));
|
|
break;
|
|
case 'padding-left':
|
|
if (genericNode.rawStyle.indexOf('padding-start:') >= 0) {
|
|
e.YGNodeStyleSetPadding(nodeName, e.YGEdgeStart, pixelValue(e, node.style[style]));
|
|
} else {
|
|
e.YGNodeStyleSetPadding(nodeName, e.YGEdgeLeft, pixelValue(e, node.style[style]));
|
|
}
|
|
break;
|
|
case 'padding-top':
|
|
e.YGNodeStyleSetPadding(nodeName, e.YGEdgeTop, pixelValue(e, node.style[style]));
|
|
break;
|
|
case 'padding-right':
|
|
if (genericNode.rawStyle.indexOf('padding-end:') >= 0) {
|
|
e.YGNodeStyleSetPadding(nodeName, e.YGEdgeEnd, pixelValue(e, node.style[style]));
|
|
} else {
|
|
e.YGNodeStyleSetPadding(nodeName, e.YGEdgeRight, pixelValue(e, node.style[style]));
|
|
}
|
|
break;
|
|
case 'padding-bottom':
|
|
e.YGNodeStyleSetPadding(nodeName, e.YGEdgeBottom, pixelValue(e, node.style[style]));
|
|
break;
|
|
case 'border-left-width':
|
|
if (genericNode.rawStyle.indexOf('border-start-width:') >= 0) {
|
|
e.YGNodeStyleSetBorder(nodeName, e.YGEdgeStart, pixelValue(e, node.style[style]));
|
|
} else {
|
|
e.YGNodeStyleSetBorder(nodeName, e.YGEdgeLeft, pixelValue(e, node.style[style]));
|
|
}
|
|
break;
|
|
case 'border-top-width':
|
|
e.YGNodeStyleSetBorder(nodeName, e.YGEdgeTop, pixelValue(e, node.style[style]));
|
|
break;
|
|
case 'border-right-width':
|
|
if (genericNode.rawStyle.indexOf('border-end-width:') >= 0) {
|
|
e.YGNodeStyleSetBorder(nodeName, e.YGEdgeEnd, pixelValue(e, node.style[style]));
|
|
} else {
|
|
e.YGNodeStyleSetBorder(nodeName, e.YGEdgeRight, pixelValue(e, node.style[style]));
|
|
}
|
|
break;
|
|
case 'border-bottom-width':
|
|
e.YGNodeStyleSetBorder(nodeName, e.YGEdgeBottom, pixelValue(e, node.style[style]));
|
|
break;
|
|
case 'width':
|
|
e.YGNodeStyleSetWidth(nodeName, pixelValue(e, node.style[style]));
|
|
break;
|
|
case 'min-width':
|
|
e.YGNodeStyleSetMinWidth(nodeName, pixelValue(e, node.style[style]));
|
|
break;
|
|
case 'max-width':
|
|
e.YGNodeStyleSetMaxWidth(nodeName, pixelValue(e, node.style[style]));
|
|
break;
|
|
case 'height':
|
|
e.YGNodeStyleSetHeight(nodeName, pixelValue(e, node.style[style]));
|
|
break;
|
|
case 'min-height':
|
|
e.YGNodeStyleSetMinHeight(nodeName, pixelValue(e, node.style[style]));
|
|
break;
|
|
case 'max-height':
|
|
e.YGNodeStyleSetMaxHeight(nodeName, pixelValue(e, node.style[style]));
|
|
break;
|
|
case 'display':
|
|
e.YGNodeStyleSetDisplay(nodeName, displayValue(e, node.style[style]))
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (parentName) {
|
|
e.YGNodeInsertChild(parentName, nodeName, index);
|
|
}
|
|
|
|
for (var i = 0; i < node.children.length; i++) {
|
|
e.push('');
|
|
var childName = nodeName + '_child' + i;
|
|
setupTestTree(
|
|
e,
|
|
node,
|
|
node.children[i],
|
|
genericNode.children[i],
|
|
childName,
|
|
nodeName,
|
|
i);
|
|
}
|
|
}
|
|
|
|
function overflowValue(e, value) {
|
|
switch (value) {
|
|
case 'visible': return e.YGOverflowVisible;
|
|
case 'hidden': return e.YGOverflowHidden;
|
|
}
|
|
}
|
|
|
|
function wrapValue(e, value) {
|
|
switch (value) {
|
|
case 'wrap': return e.YGWrapWrap;
|
|
case 'nowrap': return e.YGWrapNoWrap;
|
|
}
|
|
}
|
|
|
|
function flexDirectionValue(e, value) {
|
|
switch (value) {
|
|
case 'row': return e.YGFlexDirectionRow;
|
|
case 'row-reverse': return e.YGFlexDirectionRowReverse;
|
|
case 'column': return e.YGFlexDirectionColumn;
|
|
case 'column-reverse': return e.YGFlexDirectionColumnReverse;
|
|
}
|
|
}
|
|
|
|
function justifyValue(e, value) {
|
|
switch (value) {
|
|
case 'center': return e.YGJustifyCenter;
|
|
case 'space-around': return e.YGJustifySpaceAround;
|
|
case 'space-between': return e.YGJustifySpaceBetween;
|
|
case 'flex-start': return e.YGJustifyFlexStart;
|
|
case 'flex-end': return e.YGJustifyFlexEnd;
|
|
}
|
|
}
|
|
|
|
function positionValue(e, value) {
|
|
switch (value) {
|
|
case 'absolute': return e.YGPositionTypeAbsolute;
|
|
default: return e.YGPositionTypeRelative
|
|
}
|
|
}
|
|
|
|
function directionValue(e, value) {
|
|
switch (value) {
|
|
case 'ltr': return e.YGDirectionLTR;
|
|
case 'rtl': return e.YGDirectionRTL;
|
|
case 'inherit': return e.YGDirectionInherit;
|
|
}
|
|
}
|
|
|
|
function alignValue(e, value) {
|
|
switch (value) {
|
|
case 'auto': return e.YGAlignAuto;
|
|
case 'center': return e.YGAlignCenter;
|
|
case 'stretch': return e.YGAlignStretch;
|
|
case 'flex-start': return e.YGAlignFlexStart;
|
|
case 'flex-end': return e.YGAlignFlexEnd;
|
|
case 'space-between': return e.YGAlignSpaceBetween;
|
|
case 'space-around': return e.YGAlignSpaceAround;
|
|
case 'baseline': return e.YGAlignBaseline;
|
|
}
|
|
}
|
|
|
|
function pixelValue(e, value) {
|
|
switch (value) {
|
|
case 'auto': return e.YGAuto;
|
|
case 'undefined': return e.YGUndefined;
|
|
default: return value;
|
|
}
|
|
}
|
|
|
|
function displayValue(e, value){
|
|
switch(value){
|
|
case 'flex': return e.YGDisplayFlex;
|
|
case 'none': return e.YGDisplayNone;
|
|
}
|
|
}
|
|
|
|
function getDefaultStyleValue(style) {
|
|
if (style == 'position') {
|
|
return 'relative';
|
|
}
|
|
switch (style) {
|
|
case 'left':
|
|
case 'top':
|
|
case 'right':
|
|
case 'bottom':
|
|
case 'start':
|
|
case 'end':
|
|
return 'undefined';
|
|
}
|
|
var node = document.getElementById('default');
|
|
return getComputedStyle(node, null).getPropertyValue(style);
|
|
}
|
|
|
|
function calculateTree(root) {
|
|
var rootLayout = [];
|
|
|
|
for (var i = 0; i < root.children.length; i++) {
|
|
var child = root.children[i];
|
|
rootLayout.push({
|
|
name: child.id !== '' ? child.id : 'INSERT_NAME_HERE',
|
|
left: child.offsetLeft + child.parentNode.clientLeft,
|
|
top: child.offsetTop + child.parentNode.clientTop,
|
|
width: child.offsetWidth,
|
|
height: child.offsetHeight,
|
|
children: calculateTree(child),
|
|
style: getYogaStyle(child),
|
|
declaredStyle: child.style,
|
|
rawStyle: child.getAttribute('style'),
|
|
experiments: child.getAttribute('experiments')
|
|
? child.getAttribute('experiments').split(' ')
|
|
: [],
|
|
});
|
|
}
|
|
|
|
return rootLayout;
|
|
}
|
|
|
|
function getYogaStyle(node) {
|
|
return [
|
|
'direction',
|
|
'flex-direction',
|
|
'justify-content',
|
|
'align-content',
|
|
'align-items',
|
|
'align-self',
|
|
'position',
|
|
'flex-wrap',
|
|
'overflow',
|
|
'flex-grow',
|
|
'flex-shrink',
|
|
'flex-basis',
|
|
'left',
|
|
'top',
|
|
'right',
|
|
'bottom',
|
|
'margin-left',
|
|
'margin-top',
|
|
'margin-right',
|
|
'margin-bottom',
|
|
'padding-left',
|
|
'padding-top',
|
|
'padding-right',
|
|
'padding-bottom',
|
|
'border-left-width',
|
|
'border-top-width',
|
|
'border-right-width',
|
|
'border-bottom-width',
|
|
'width',
|
|
'min-width',
|
|
'max-width',
|
|
'height',
|
|
'min-height',
|
|
'max-height',
|
|
'display',
|
|
].reduce(function(map, key) {
|
|
map[key] = node.style[key] || getComputedStyle(node, null).getPropertyValue(key);
|
|
return map;
|
|
}, {});
|
|
}
|
|
|
|
var Emitter = function(lang, indent) {
|
|
this.lang = lang;
|
|
this.indent = indent;
|
|
this.indents = [];
|
|
this.lines = [];
|
|
};
|
|
|
|
Emitter.prototype = Object.create(Object.prototype, {
|
|
constructor:{value:Emitter},
|
|
|
|
pushIndent:{value:function() {
|
|
this.indents.push(this.indent);
|
|
}},
|
|
|
|
popIndent:{value:function() {
|
|
this.indents.pop();
|
|
}},
|
|
|
|
push:{value:function(line) {
|
|
if (line instanceof Array) {
|
|
line.forEach(function(element) {
|
|
this.push(element);
|
|
}, this);
|
|
return;
|
|
} else if (line.length > 0) {
|
|
line = this.indents.join('') + line;
|
|
}
|
|
this.lines.push(line);
|
|
}},
|
|
|
|
print:{value:function() {
|
|
console.log(this.lines.join('\n'));
|
|
}},
|
|
});
|