/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ /* global Emitter:readable */ const JavascriptEmitter = function () { Emitter.call(this, 'js', ' '); }; function toValueJavascript(value) { if (value.match(/^[0-9.e+-]+px$/i)) return parseFloat(value); if (value.match(/^[0-9.e+-]+%/i)) return JSON.stringify(value); if (value == 'Yoga.AUTO') return '"auto"'; return value; } JavascriptEmitter.prototype = Object.create(Emitter.prototype, { constructor: {value: JavascriptEmitter}, emitPrologue: { value: function () { this.push( "import { instrinsicSizeMeasureFunc } from '../tools/utils.ts'", ); this.push("import Yoga from 'yoga-layout';"); this.push('import {'); this.pushIndent(); this.push('Align,'); this.push('BoxSizing,'); this.push('Direction,'); this.push('Display,'); this.push('Edge,'); this.push('Errata,'); this.push('ExperimentalFeature,'); this.push('FlexDirection,'); this.push('Gutter,'); this.push('Justify,'); this.push('MeasureMode,'); this.push('Overflow,'); this.push('PositionType,'); this.push('Unit,'); this.push('Wrap,'); this.popIndent(); this.push("} from 'yoga-layout';"); this.push(''); }, }, emitTestPrologue: { value: function (name, experiments, ignore) { const testFn = ignore ? `test.skip` : 'test'; this.push(`${testFn}('${name}', () => {`); this.pushIndent(); this.push('const config = Yoga.Config.create();'); this.push('let root;'); this.push(''); if (experiments.length > 0) { for (const experiment of experiments) { this.push( `config.setExperimentalFeatureEnabled(ExperimentalFeature.${experiment}, true);`, ); } this.push(''); } this.push('try {'); this.pushIndent(); }, }, emitTestTreePrologue: { value: function (nodeName) { if (nodeName === 'root') { this.push(`root = Yoga.Node.create(config);`); } else { this.push(`const ${nodeName} = Yoga.Node.create(config);`); } }, }, emitTestEpilogue: { value: function (_experiments) { this.popIndent(); this.push('} finally {'); this.pushIndent(); this.push("if (typeof root !== 'undefined') {"); this.pushIndent(); this.push('root.freeRecursive();'); this.popIndent(); this.push('}'); this.push(''); this.push('config.free();'); this.popIndent(); this.push('}'); this.popIndent(); this.push('});'); }, }, emitEpilogue: { value: function () { this.push(''); }, }, AssertEQ: { value: function (v0, v1) { this.push(`expect(${v1}).toBe(${v0});`); }, }, YGAlignAuto: {value: 'Align.Auto'}, YGAlignCenter: {value: 'Align.Center'}, YGAlignFlexEnd: {value: 'Align.FlexEnd'}, YGAlignFlexStart: {value: 'Align.FlexStart'}, YGAlignStretch: {value: 'Align.Stretch'}, YGAlignSpaceBetween: {value: 'Align.SpaceBetween'}, YGAlignSpaceAround: {value: 'Align.SpaceAround'}, YGAlignSpaceEvenly: {value: 'Align.SpaceEvenly'}, YGAlignBaseline: {value: 'Align.Baseline'}, YGDirectionInherit: {value: 'Direction.Inherit'}, YGDirectionLTR: {value: 'Direction.LTR'}, YGDirectionRTL: {value: 'Direction.RTL'}, YGEdgeBottom: {value: 'Edge.Bottom'}, YGEdgeEnd: {value: 'Edge.End'}, YGEdgeLeft: {value: 'Edge.Left'}, YGEdgeRight: {value: 'Edge.Right'}, YGEdgeStart: {value: 'Edge.Start'}, YGEdgeTop: {value: 'Edge.Top'}, YGGutterAll: {value: 'Gutter.All'}, YGGutterColumn: {value: 'Gutter.Column'}, YGGutterRow: {value: 'Gutter.Row'}, YGFlexDirectionColumn: {value: 'FlexDirection.Column'}, YGFlexDirectionColumnReverse: {value: 'FlexDirection.ColumnReverse'}, YGFlexDirectionRow: {value: 'FlexDirection.Row'}, YGFlexDirectionRowReverse: {value: 'FlexDirection.RowReverse'}, YGJustifyCenter: {value: 'Justify.Center'}, YGJustifyFlexEnd: {value: 'Justify.FlexEnd'}, YGJustifyFlexStart: {value: 'Justify.FlexStart'}, YGJustifySpaceAround: {value: 'Justify.SpaceAround'}, YGJustifySpaceBetween: {value: 'Justify.SpaceBetween'}, YGJustifySpaceEvenly: {value: 'Justify.SpaceEvenly'}, YGOverflowHidden: {value: 'Overflow.Hidden'}, YGOverflowVisible: {value: 'Overflow.Visible'}, YGOverflowScroll: {value: 'Overflow.Scroll'}, YGPositionTypeAbsolute: {value: 'PositionType.Absolute'}, YGPositionTypeRelative: {value: 'PositionType.Relative'}, YGPositionTypeStatic: {value: 'PositionType.Static'}, YGAuto: {value: "'auto'"}, YGUndefined: {value: 'undefined'}, YGWrapNoWrap: {value: 'Wrap.NoWrap'}, YGWrapWrap: {value: 'Wrap.Wrap'}, YGWrapWrapReverse: {value: 'Wrap.WrapReverse'}, YGDisplayFlex: {value: 'Display.Flex'}, YGDisplayNone: {value: 'Display.None'}, YGDisplayContents: {value: 'Display.Contents'}, YGBoxSizingBorderBox: {value: 'BoxSizing.BorderBox'}, YGBoxSizingContentBox: {value: 'BoxSizing.ContentBox'}, YGNodeCalculateLayout: { value: function (node, dir, _experiments) { this.push(node + '.calculateLayout(undefined, undefined, ' + dir + ');'); }, }, YGNodeInsertChild: { value: function (parentName, nodeName, index) { this.push(parentName + '.insertChild(' + nodeName + ', ' + index + ');'); }, }, YGNodeLayoutGetLeft: { value: function (nodeName) { return nodeName + '.getComputedLeft()'; }, }, YGNodeLayoutGetTop: { value: function (nodeName) { return nodeName + '.getComputedTop()'; }, }, YGNodeLayoutGetWidth: { value: function (nodeName) { return nodeName + '.getComputedWidth()'; }, }, YGNodeLayoutGetHeight: { value: function (nodeName) { return nodeName + '.getComputedHeight()'; }, }, YGNodeStyleSetAlignContent: { value: function (nodeName, value) { this.push( nodeName + '.setAlignContent(' + toValueJavascript(value) + ');', ); }, }, YGNodeStyleSetAlignItems: { value: function (nodeName, value) { this.push(nodeName + '.setAlignItems(' + toValueJavascript(value) + ');'); }, }, YGNodeStyleSetAlignSelf: { value: function (nodeName, value) { this.push(nodeName + '.setAlignSelf(' + toValueJavascript(value) + ');'); }, }, YGNodeStyleSetAspectRatio: { value: function (nodeName, value) { this.push( nodeName + '.setAspectRatio(' + toValueJavascript(value) + ');', ); }, }, YGNodeStyleSetBorder: { value: function (nodeName, edge, value) { this.push( nodeName + '.setBorder(' + toValueJavascript(edge) + ', ' + toValueJavascript(value) + ');', ); }, }, YGNodeStyleSetDirection: { value: function (nodeName, value) { this.push(nodeName + '.setDirection(' + toValueJavascript(value) + ');'); }, }, YGNodeStyleSetDisplay: { value: function (nodeName, value) { this.push(nodeName + '.setDisplay(' + toValueJavascript(value) + ');'); }, }, YGNodeStyleSetFlexBasis: { value: function (nodeName, value) { this.push(nodeName + '.setFlexBasis(' + toValueJavascript(value) + ');'); }, }, YGNodeStyleSetFlexDirection: { value: function (nodeName, value) { this.push( nodeName + '.setFlexDirection(' + toValueJavascript(value) + ');', ); }, }, YGNodeStyleSetFlexGrow: { value: function (nodeName, value) { this.push(nodeName + '.setFlexGrow(' + toValueJavascript(value) + ');'); }, }, YGNodeStyleSetFlexShrink: { value: function (nodeName, value) { this.push(nodeName + '.setFlexShrink(' + toValueJavascript(value) + ');'); }, }, YGNodeStyleSetFlexWrap: { value: function (nodeName, value) { this.push(nodeName + '.setFlexWrap(' + toValueJavascript(value) + ');'); }, }, YGNodeStyleSetHeight: { value: function (nodeName, value) { this.push(nodeName + '.setHeight(' + toValueJavascript(value) + ');'); }, }, YGNodeStyleSetJustifyContent: { value: function (nodeName, value) { this.push( nodeName + '.setJustifyContent(' + toValueJavascript(value) + ');', ); }, }, YGNodeStyleSetMargin: { value: function (nodeName, edge, value) { this.push( nodeName + '.setMargin(' + toValueJavascript(edge) + ', ' + toValueJavascript(value) + ');', ); }, }, YGNodeStyleSetMaxHeight: { value: function (nodeName, value) { this.push(nodeName + '.setMaxHeight(' + toValueJavascript(value) + ');'); }, }, YGNodeStyleSetMaxWidth: { value: function (nodeName, value) { this.push(nodeName + '.setMaxWidth(' + toValueJavascript(value) + ');'); }, }, YGNodeStyleSetMinHeight: { value: function (nodeName, value) { this.push(nodeName + '.setMinHeight(' + toValueJavascript(value) + ');'); }, }, YGNodeStyleSetMinWidth: { value: function (nodeName, value) { this.push(nodeName + '.setMinWidth(' + toValueJavascript(value) + ');'); }, }, YGNodeStyleSetOverflow: { value: function (nodeName, value) { this.push(nodeName + '.setOverflow(' + toValueJavascript(value) + ');'); }, }, YGNodeStyleSetPadding: { value: function (nodeName, edge, value) { this.push( nodeName + '.setPadding(' + toValueJavascript(edge) + ', ' + toValueJavascript(value) + ');', ); }, }, YGNodeStyleSetPosition: { value: function (nodeName, edge, value) { const valueStr = toValueJavascript(value); if (valueStr == "'auto'") { this.push( nodeName + '.setPositionAuto(' + toValueJavascript(edge) + ');', ); } else { this.push( nodeName + '.setPosition(' + toValueJavascript(edge) + ', ' + valueStr + ');', ); } }, }, YGNodeStyleSetPositionType: { value: function (nodeName, value) { this.push( nodeName + '.setPositionType(' + toValueJavascript(value) + ');', ); }, }, YGNodeStyleSetWidth: { value: function (nodeName, value) { this.push(nodeName + '.setWidth(' + toValueJavascript(value) + ');'); }, }, YGNodeStyleSetGap: { value: function (nodeName, gap, value) { this.push( nodeName + '.setGap(' + toValueJavascript(gap) + ', ' + toValueJavascript(value) + ');', ); }, }, YGNodeStyleSetBoxSizing: { value: function (nodeName, value) { this.push(nodeName + '.setBoxSizing(' + toValueJavascript(value) + ');'); }, }, YGNodeSetMeasureFunc: { value: function (nodeName, innerText) { this.push( `${nodeName}.setMeasureFunc(instrinsicSizeMeasureFunc.bind("${innerText}"));`, ); }, }, });