Summary: Fixes ComponentKit code generation to outpput valid code. Reviewed By: emilsjolander Differential Revision: D6902924 fbshipit-source-id: f03a69268d22084f30aea46297b59aec28ba68d2
185 lines
5.1 KiB
JavaScript
185 lines
5.1 KiB
JavaScript
// @flow
|
|
import yoga from 'yoga-layout';
|
|
import LayoutRecord from './LayoutRecord';
|
|
import PositionRecord from './PositionRecord';
|
|
import type {LayoutRecordT} from './LayoutRecord';
|
|
import type {Yoga$Direction /* Yoga$Node */} from 'yoga-layout';
|
|
|
|
type Yoga$Node = any;
|
|
|
|
const enumLookup = {
|
|
flexDirection: {
|
|
[yoga.FLEX_DIRECTION_COLUMN]: 'CKFlexboxDirectionVertical',
|
|
[yoga.FLEX_DIRECTION_ROW]: 'CKFlexboxDirectionHorizontal',
|
|
[yoga.FLEX_DIRECTION_COLUMN_REVERSE]: 'CKFlexboxDirectionVerticalReverse',
|
|
[yoga.FLEX_DIRECTION_ROW_REVERSE]: 'CKFlexboxDirectionHorizontalReverse',
|
|
},
|
|
alignItems: {
|
|
[yoga.ALIGN_FLEX_START]: 'CKFlexboxAlignItemsStart',
|
|
[yoga.ALIGN_FLEX_END]: 'CKFlexboxAlignItemsEnd',
|
|
[yoga.ALIGN_CENTER]: 'CKFlexboxAlignItemsCenter',
|
|
[yoga.ALIGN_BASELINE]: 'CKFlexboxAlignItemsBaseline',
|
|
[yoga.ALIGN_STRETCH]: 'CKFlexboxAlignItemsStretch',
|
|
},
|
|
alignSelf: {
|
|
[yoga.ALIGN_AUTO]: 'CKFlexboxAlignSelfAuto',
|
|
[yoga.ALIGN_FLEX_START]: 'CKFlexboxAlignSelfStart',
|
|
[yoga.ALIGN_FLEX_END]: 'CKFlexboxAlignSelfEnd',
|
|
[yoga.ALIGN_CENTER]: 'CKFlexboxAlignSelfCenter',
|
|
[yoga.ALIGN_BASELINE]: 'CKFlexboxAlignSelfBaseline',
|
|
[yoga.ALIGN_STRETCH]: 'CKFlexboxAlignSelfStretch',
|
|
},
|
|
alignContent: {
|
|
[yoga.ALIGN_FLEX_START]: 'CKFlexboxAlignContentStart',
|
|
[yoga.ALIGN_FLEX_END]: 'CKFlexboxAlignContentEnd',
|
|
[yoga.ALIGN_CENTER]: 'CKFlexboxAlignContentCenter',
|
|
[yoga.ALIGN_SPACE_BETWEEN]: 'CKFlexboxAlignContentSpaceBetween',
|
|
[yoga.ALIGN_SPACE_AROUND]: 'CKFlexboxAlignContentSpaceAround',
|
|
[yoga.ALIGN_STRETCH]: 'CKFlexboxAlignContentStretch',
|
|
},
|
|
justifyContent: {
|
|
[yoga.JUSTIFY_FLEX_START]: 'CKFlexboxJustifyContentStart',
|
|
[yoga.JUSTIFY_CENTER]: 'CKFlexboxJustifyContentCenter',
|
|
[yoga.JUSTIFY_FLEX_END]: 'CKFlexboxJustifyContentEnd',
|
|
[yoga.JUSTIFY_SPACE_BETWEEN]: 'CKFlexboxJustifyContentSpaceBetween',
|
|
[yoga.JUSTIFY_SPACE_AROUND]: 'CKFlexboxJustifyContentSpaceAround',
|
|
},
|
|
flexWrap: {
|
|
[yoga.WRAP_NO_WRAP]: 'CKFlexboxWrapNoWrap',
|
|
[yoga.WRAP_WRAP]: 'CKFlexboxWrapWrap',
|
|
[yoga.WRAP_WRAP_REVERSE]: 'CKFlexboxWrapWrapReverse',
|
|
},
|
|
positionType: {
|
|
[yoga.POSITION_TYPE_RELATIVE]: 'CKFlexboxPositionTypeRelative',
|
|
[yoga.POSITION_TYPE_ABSOLUTE]: 'CKFlexboxPositionTypeAbsolute',
|
|
},
|
|
};
|
|
|
|
const untouchedLayout = LayoutRecord({});
|
|
const untouchedPosition = PositionRecord({});
|
|
|
|
function keyLookup(key: string): string {
|
|
const keyLookup = {
|
|
flexWrap: 'wrap',
|
|
flexDirection: 'direction',
|
|
};
|
|
return keyLookup[key] || key;
|
|
}
|
|
|
|
function getLayoutCode(
|
|
node: LayoutRecordT,
|
|
indent: string = '',
|
|
isRoot?: boolean,
|
|
): string {
|
|
const lines = [];
|
|
const isFlexbox = node.children.size > 0;
|
|
|
|
lines.push(
|
|
indent +
|
|
`${isRoot ? '' : `.component = \n${indent}`}[${
|
|
isFlexbox ? 'CKFlexboxComponent' : 'CKComponent'
|
|
}`,
|
|
);
|
|
lines.push(indent + ` newWithView:{}`);
|
|
lines.push(indent + ` size:{${node.width},${node.height}}`);
|
|
|
|
const CKFlexboxComponentStyle = [
|
|
'direction',
|
|
'margin',
|
|
'justifyContent',
|
|
'alignItems',
|
|
'alignContent',
|
|
'wrap',
|
|
'padding',
|
|
'border',
|
|
];
|
|
const CKFlexboxComponentChild = [
|
|
'margin',
|
|
'padding',
|
|
'flexGrow',
|
|
'flexShrink',
|
|
'flexBasis',
|
|
'alignSelf',
|
|
'position',
|
|
];
|
|
|
|
if (isFlexbox) {
|
|
// render styles
|
|
lines.push(indent + ` style:{`);
|
|
indent += '\t';
|
|
CKFlexboxComponentStyle.forEach(key => {
|
|
let line = renderKey(node, key, indent);
|
|
if (line) {
|
|
lines.push(line);
|
|
}
|
|
});
|
|
indent = indent.substr(-1);
|
|
lines.push(indent + ` }`);
|
|
|
|
// render children
|
|
lines.push(indent + ' children:{');
|
|
lines.push(
|
|
...node.children
|
|
.toJSON()
|
|
.map(
|
|
child =>
|
|
`${indent}\t{\n${getLayoutCode(
|
|
child,
|
|
indent + '\t\t',
|
|
)}\n${indent}\t},`,
|
|
),
|
|
);
|
|
lines.push(indent + `}]${isRoot ? ';' : ''}`);
|
|
} else {
|
|
lines[lines.length - 1] += ']';
|
|
CKFlexboxComponentChild.forEach(key => {
|
|
let line = renderKey(node, key, indent);
|
|
if (line) {
|
|
lines.push(line);
|
|
}
|
|
});
|
|
}
|
|
|
|
return lines.join('\n');
|
|
}
|
|
|
|
function renderKey(node: Yoga$Node, key: string, indent: string): ?string {
|
|
if (
|
|
node[key] instanceof PositionRecord &&
|
|
!node[key].equals(untouchedPosition)
|
|
) {
|
|
const lines = [];
|
|
lines.push(indent + `.${key} = {`);
|
|
|
|
if (key === 'position') {
|
|
lines.push(
|
|
indent + `\t.type = ${enumLookup.positionType[node.positionType]},`,
|
|
);
|
|
}
|
|
|
|
['top', 'left', 'right', 'bottom'].forEach(pKey => {
|
|
if (node[key][pKey]) {
|
|
lines.push(indent + `\t.${pKey} = ${node[key][pKey]},`);
|
|
}
|
|
});
|
|
|
|
lines.push(indent + `},`);
|
|
return lines.join('\n');
|
|
} else if (node[key] !== untouchedLayout[key]) {
|
|
if (enumLookup[key]) {
|
|
return indent + `.${keyLookup(key)} = ${enumLookup[key][node[key]]},`;
|
|
} else {
|
|
console.error(`Unknown property ${key}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
export default function generateCode(
|
|
root: LayoutRecordT,
|
|
direction: Yoga$Direction,
|
|
): string {
|
|
return ['CKFlexboxComponent *c =', getLayoutCode(root, '\t', true)].join(
|
|
'\n',
|
|
);
|
|
}
|