update JavaScript bindings

Summary:
- adds flow types
- transpiles bundle using babel
- cleans and formats code

Reviewed By: emilsjolander

Differential Revision: D6748362

fbshipit-source-id: fcb5fdde73df6e0062eff1e5038bb5fe0532f997
This commit is contained in:
Daniel Büchele
2018-01-18 07:55:50 -08:00
committed by Facebook Github Bot
parent 9ecdff14fa
commit a40ba9d350
9 changed files with 1218 additions and 1030 deletions

View File

@@ -5,10 +5,12 @@
* 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.
*
* @flow
* @format
*/
module.exports = {
const CONSTANTS = {
ALIGN_COUNT: 8,
ALIGN_AUTO: 0,
ALIGN_FLEX_START: 1,
@@ -101,5 +103,73 @@ module.exports = {
WRAP_NO_WRAP: 0,
WRAP_WRAP: 1,
WRAP_WRAP_REVERSE: 2,
};
export type Yoga$JustifyContent =
| typeof CONSTANTS.JUSTIFY_CENTER
| typeof CONSTANTS.JUSTIFY_FLEX_END
| typeof CONSTANTS.JUSTIFY_FLEX_START
| typeof CONSTANTS.JUSTIFY_SPACE_AROUND
| typeof CONSTANTS.JUSTIFY_SPACE_BETWEEN
| typeof CONSTANTS.JUSTIFY_SPACE_EVENLY;
export type Yoga$Align =
| typeof CONSTANTS.ALIGN_AUTO
| typeof CONSTANTS.ALIGN_BASELINE
| typeof CONSTANTS.ALIGN_CENTER
| typeof CONSTANTS.ALIGN_FLEX_END
| typeof CONSTANTS.ALIGN_FLEX_START
| typeof CONSTANTS.ALIGN_SPACE_AROUND
| typeof CONSTANTS.ALIGN_SPACE_BETWEEN
| typeof CONSTANTS.ALIGN_STRETCH;
export type Yoga$FlexDirection =
| typeof CONSTANTS.FLEX_DIRECTION_COLUMN
| typeof CONSTANTS.FLEX_DIRECTION_COLUMN_REVERSE
| typeof CONSTANTS.FLEX_DIRECTION_COUNT
| typeof CONSTANTS.FLEX_DIRECTION_ROW
| typeof CONSTANTS.FLEX_DIRECTION_ROW_REVERSE;
export type Yoga$Direction =
| typeof CONSTANTS.DIRECTION_INHERIT
| typeof CONSTANTS.DIRECTION_LTR
| typeof CONSTANTS.DIRECTION_RTL;
export type Yoga$FlexWrap =
| typeof CONSTANTS.WRAP_NO_WRAP
| typeof CONSTANTS.WRAP_WRAP
| typeof CONSTANTS.WRAP_WRAP_REVERSE;
export type Yoga$Edge =
| typeof CONSTANTS.EDGE_LEFT
| typeof CONSTANTS.EDGE_TOP
| typeof CONSTANTS.EDGE_RIGHT
| typeof CONSTANTS.EDGE_BOTTOM
| typeof CONSTANTS.EDGE_START
| typeof CONSTANTS.EDGE_END
| typeof CONSTANTS.EDGE_HORIZONTAL
| typeof CONSTANTS.EDGE_VERTICAL
| typeof CONSTANTS.EDGE_ALL;
export type Yoga$Display =
| typeof CONSTANTS.DISPLAY_FLEX
| typeof CONSTANTS.DISPLAY_NONE;
export type Yoga$Unit =
| typeof CONSTANTS.UNIT_AUTO
| typeof CONSTANTS.UNIT_PERCENT
| typeof CONSTANTS.UNIT_POINT
| typeof CONSTANTS.UNIT_UNDEFINED;
export type Yoga$Overflow =
| typeof CONSTANTS.OVERFLOW_HIDDEN
| typeof CONSTANTS.OVERFLOW_SCROLL
| typeof CONSTANTS.OVERFLOW_VISIBLE;
export type Yoga$PositionType =
| typeof CONSTANTS.POSITION_TYPE_ABSOLUTE
| typeof CONSTANTS.POSITION_TYPE_RELATIVE;
export type Yoga$ExperimentalFeature = typeof CONSTANTS.EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS;
export default CONSTANTS;

View File

@@ -5,28 +5,51 @@
* 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.
*
* @flow
* @format
*/
var nbind = require('../build/Release/nbind.js');
import Yoga from './entry-common';
var ran = false;
var ret = null;
const nbind = require('../build/Release/nbind.js');
nbind({}, function (err, result) {
let ran = false;
let ret = null;
if (ran)
return;
nbind({}, function(err, result) {
if (ran) {
return;
}
ran = true;
ran = true;
if (err)
throw err;
ret = result;
if (err) {
throw err;
}
ret = result;
});
if (!ran)
throw new Error('Failed to load the yoga module - it needed to be loaded synchronously, but didn\'t');
if (!ran) {
throw new Error(
"Failed to load the yoga module - it needed to be loaded synchronously, but didn't",
);
}
module.exports = require('./entry-common')(ret.bind, ret.lib);
// $FlowFixMe ret will not be null here
module.exports = Yoga(ret.bind, ret.lib);
export type {
Yoga$JustifyContent,
Yoga$Align,
Yoga$FlexDirection,
Yoga$Direction,
Yoga$FlexWrap,
Yoga$Edge,
Yoga$Display,
Yoga$Unit,
Yoga$Overflow,
Yoga$PositionType,
Yoga$ExperimentalFeature,
} from './YGEnums.js';

View File

@@ -5,245 +5,352 @@
* 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.
*
* @flow
* @format
*/
function patch(prototype, name, fn) {
import CONSTANTS from './YGEnums';
import type {
Yoga$Edge,
Yoga$FlexWrap,
Yoga$Align,
Yoga$FlexDirection,
Yoga$Direction,
Yoga$PositionType,
Yoga$Overflow,
Yoga$JustifyContent,
Yoga$Display,
Yoga$ExperimentalFeature,
} from './YGEnums';
let original = prototype[name];
class Layout {
left: number;
right: number;
top: number;
bottom: number;
width: number;
height: number;
prototype[name] = function (... args) {
return fn.call(this, original, ... args);
};
constructor(left, right, top, bottom, width, height) {
this.left = left;
this.right = right;
this.top = top;
this.bottom = bottom;
this.width = width;
this.height = height;
}
fromJS(expose) {
expose(
this.left,
this.right,
this.top,
this.bottom,
this.width,
this.height,
);
}
toString() {
return `<Layout#${this.left}:${this.right};${this.top}:${this.bottom};${
this.width
}:${this.height}>`;
}
}
module.exports = function (bind, lib) {
class Size {
static fromJS({width, height}) {
return new Size(width, height);
}
let constants = Object.assign({
width: number;
height: number;
UNDEFINED: NaN
constructor(width, height) {
this.width = width;
this.height = height;
}
}, require('./YGEnums'));
fromJS(expose) {
expose(this.width, this.height);
}
class Layout {
toString() {
return `<Size#${this.width}x${this.height}>`;
}
}
constructor(left, right, top, bottom, width, height) {
class Value {
unit: number;
value: number;
this.left = left;
this.right = right;
constructor(unit, value) {
this.unit = unit;
this.value = value;
}
this.top = top;
this.bottom = bottom;
this.width = width;
this.height = height;
}
fromJS(expose) {
expose(this.left, this.right, this.top, this.bottom, this.width, this.height);
}
toString() {
return `<Layout#${this.left}:${this.right};${this.top}:${this.bottom};${this.width}:${this.height}>`;
}
fromJS(expose) {
expose(this.unit, this.value);
}
toString() {
switch (this.unit) {
case CONSTANTS.UNIT_POINT:
return String(this.value);
case CONSTANTS.UNIT_PERCENT:
return `${this.value}%`;
case CONSTANTS.UNIT_AUTO:
return 'auto';
default: {
return `${this.value}?`;
}
}
class Size {
static fromJS({ width, height }) {
return new Size(width, height);
}
constructor(width, height) {
this.width = width;
this.height = height;
}
fromJS(expose) {
expose(this.width, this.height);
}
toString() {
return `<Size#${this.width}x${this.height}>`;
}
}
class Value {
constructor(unit, value) {
this.unit = unit;
this.value = value;
}
fromJS(expose) {
expose(this.unit, this.value);
}
toString() {
switch (this.unit) {
case constants.UNIT_POINT:
return `${this.value}`;
case constants.UNIT_PERCENT:
return `${this.value}%`;
case constants.UNIT_AUTO:
return `auto`;
default: {
return `${this.value}?`;
}
}
}
valueOf() {
return this.value;
}
}
for (let fnName of [ `setPosition`, `setMargin`, `setFlexBasis`, `setWidth`, `setHeight`, `setMinWidth`, `setMinHeight`, `setMaxWidth`, `setMaxHeight`, `setPadding` ]) {
let methods = { [constants.UNIT_POINT]: lib.Node.prototype[fnName], [constants.UNIT_PERCENT]: lib.Node.prototype[`${fnName}Percent`], [constants.UNIT_AUTO]: lib.Node.prototype[`${fnName}Auto`] };
patch(lib.Node.prototype, fnName, function (original, ... args) {
// We patch all these functions to add support for the following calls:
// .setWidth(100) / .setWidth("100%") / .setWidth(.getWidth()) / .setWidth("auto")
let value = args.pop();
let unit, asNumber;
if (value === `auto`) {
unit = constants.UNIT_AUTO;
asNumber = undefined;
} else if (value instanceof Value) {
unit = value.unit;
asNumber = value.valueOf();
} else {
unit = typeof value === `string` && value.endsWith(`%`) ? constants.UNIT_PERCENT : constants.UNIT_POINT;
asNumber = parseFloat(value);
}
if (!methods[unit])
throw new Error(`Failed to execute "${fnName}": Unsupported unit '${value}'`);
if (asNumber !== undefined) {
return methods[unit].call(this, ... args, asNumber);
} else {
return methods[unit].call(this, ... args);
}
});
}
patch(lib.Config.prototype, `free`, function () {
// Since we handle the memory allocation ourselves (via lib.Config.create), we also need to handle the deallocation
lib.Config.destroy(this);
});
patch(lib.Node, `create`, function (_, config) {
// We decide the constructor we want to call depending on the parameters
return config ? lib.Node.createWithConfig(config) : lib.Node.createDefault();
});
patch(lib.Node.prototype, `free`, function () {
// Since we handle the memory allocation ourselves (via lib.Node.create), we also need to handle the deallocation
lib.Node.destroy(this);
});
patch(lib.Node.prototype, `freeRecursive`, function () {
for (let t = 0, T = this.getChildCount(); t < T; ++t)
this.getChild(0).freeRecursive();
this.free();
});
patch(lib.Node.prototype, `setMeasureFunc`, function (original, measureFunc) {
// This patch is just a convenience patch, since it helps write more idiomatic source code (such as .setMeasureFunc(null))
// We also automatically convert the return value of the measureFunc to a Size object, so that we can return anything that has .width and .height properties
if (measureFunc) {
return original.call(this, (... args) => Size.fromJS(measureFunc(... args)));
} else {
return this.unsetMeasureFunc();
}
});
patch(lib.Node.prototype, `calculateLayout`, function (original, width = constants.UNDEFINED, height = constants.UNDEFINED, direction = constants.DIRECTION_LTR) {
// Just a small patch to add support for the function default parameters
return original.call(this, width, height, direction);
});
function getInstanceCount(... args) {
return lib.getInstanceCount(... args);
}
bind(`Layout`, Layout);
bind(`Size`, Size);
bind(`Value`, Value);
return Object.assign({
Config: lib.Config,
Node: lib.Node,
Layout,
Size,
Value,
getInstanceCount
}, constants);
}
valueOf() {
return this.value;
}
}
declare class Yoga$Config {
isExperimentalFeatureEnabled(feature: Yoga$ExperimentalFeature): boolean;
setExperimentalFeatureEnabled(
feature: Yoga$ExperimentalFeature,
enabled: boolean,
): void;
setPointScaleFactor(factor: number): void;
}
declare class Yoga$Node {
calculateLayout(
width?: number,
height?: number,
direction?: Yoga$Direction,
): void;
copyStyle(node: Yoga$Node): void;
free(): void;
freeRecursive(): void;
getAlignContent(): Yoga$Align;
getAlignItems(): Yoga$Align;
getAlignSelf(): Yoga$Align;
getAspectRatio(): number;
getBorder(edge: Yoga$Edge): number;
getChild(index: number): Yoga$Node;
getChildCount(): number;
getComputedBorder(edge: Yoga$Edge): number;
getComputedBottom(): number;
getComputedHeight(): number;
getComputedLayout(): Layout;
getComputedLeft(): number;
getComputedMargin(edge: Yoga$Edge): number;
getComputedPadding(edge: Yoga$Edge): number;
getComputedRight(): number;
getComputedTop(): number;
getComputedWidth(): number;
getDisplay(): Yoga$Display;
getFlexBasis(): number;
getFlexDirection(): Yoga$FlexDirection;
getFlexGrow(): number;
getFlexShrink(): number;
getFlexWrap(): Yoga$FlexWrap;
getHeight(): Value;
getJustifyContent(): Yoga$JustifyContent;
getMargin(edge: Yoga$Edge): Value;
getMaxHeight(): Value;
getMaxWidth(): Value;
getMinHeight(): Value;
getMinWidth(): Value;
getOverflow(): Yoga$Overflow;
getPadding(edge: Yoga$Edge): Value;
getParent(): ?Yoga$Node;
getPosition(edge: Yoga$Edge): Value;
getPositionType(): Yoga$PositionType;
getWidth(): Value;
insertChild(child: Yoga$Node, index: number): void;
isDirty(): boolean;
markDirty(): void;
removeChild(child: Yoga$Node): void;
reset(): void;
setAlignContent(alignContent: Yoga$Align): void;
setAlignItems(alignItems: Yoga$Align): void;
setAlignSelf(alignSelf: Yoga$Align): void;
setAspectRatio(aspectRatio: number): void;
setBorder(edge: Yoga$Edge, borderWidth: number): void;
setDisplay(display: Yoga$Display): void;
setFlex(flex: number): void;
setFlexBasis(flexBasis: number | string): void;
setFlexBasisPercent(flexBasis: number): void;
setFlexDirection(flexDirection: Yoga$FlexDirection): void;
setFlexGrow(flexGrow: number): void;
setFlexShrink(flexShrink: number): void;
setFlexWrap(flexWrap: Yoga$FlexWrap): void;
setHeight(height: number | string): void;
setHeightAuto(): void;
setHeightPercent(height: number): void;
setJustifyContent(justifyContent: Yoga$JustifyContent): void;
setMargin(edge: Yoga$Edge, margin: number): void;
setMarginAuto(edge: Yoga$Edge): void;
setMarginPercent(edge: Yoga$Edge, margin: number): void;
setMaxHeight(maxHeight: number | string): void;
setMaxHeightPercent(maxHeight: number): void;
setMaxWidth(maxWidth: number | string): void;
setMaxWidthPercent(maxWidth: number): void;
setMeasureFunc(measureFunc: ?Function): void;
setMinHeight(minHeight: number | string): void;
setMinHeightPercent(minHeight: number): void;
setMinWidth(minWidth: number | string): void;
setMinWidthPercent(minWidth: number): void;
setOverflow(overflow: Yoga$Overflow): void;
setPadding(edge: Yoga$Edge, padding: number | string): void;
setPaddingPercent(edge: Yoga$Edge, padding: number): void;
setPosition(edge: Yoga$Edge, position: number | string): void;
setPositionPercent(edge: Yoga$Edge, position: number): void;
setPositionType(positionType: Yoga$PositionType): void;
setWidth(width: number | string): void;
setWidthAuto(): void;
setWidthPercent(width: number): void;
unsetMeasureFun(): void;
}
type Yoga = {
Config: {
create(): Yoga$Config,
destroy(config: Yoga$Config): any,
},
Node: {
create(): Yoga$Node,
createDefault(): Yoga$Node,
createWithConfig(config: Yoga$Config): Yoga$Node,
destroy(node: Yoga$Node): any,
},
Layout: Layout,
Size: Size,
Value: Value,
getInstanceCount(): number,
...typeof CONSTANTS,
};
export default (bind: any, lib: any): Yoga => {
function patch(prototype, name, fn) {
let original = prototype[name];
prototype[name] = function(...args) {
return fn.call(this, original, ...args);
};
}
for (let fnName of [
'setPosition',
'setMargin',
'setFlexBasis',
'setWidth',
'setHeight',
'setMinWidth',
'setMinHeight',
'setMaxWidth',
'setMaxHeight',
'setPadding',
]) {
let methods = {
[CONSTANTS.UNIT_POINT]: lib.Node.prototype[fnName],
[CONSTANTS.UNIT_PERCENT]: lib.Node.prototype[`${fnName}Percent`],
[CONSTANTS.UNIT_AUTO]: lib.Node.prototype[`${fnName}Auto`],
};
patch(lib.Node.prototype, fnName, function(original, ...args) {
// We patch all these functions to add support for the following calls:
// .setWidth(100) / .setWidth("100%") / .setWidth(.getWidth()) / .setWidth("auto")
let value = args.pop();
let unit, asNumber;
if (value === 'auto') {
unit = CONSTANTS.UNIT_AUTO;
asNumber = undefined;
} else if (value instanceof Value) {
unit = value.unit;
asNumber = value.valueOf();
} else {
unit =
typeof value === 'string' && value.endsWith('%')
? CONSTANTS.UNIT_PERCENT
: CONSTANTS.UNIT_POINT;
asNumber = parseFloat(value);
}
if (!methods[unit])
throw new Error(
`Failed to execute "${fnName}": Unsupported unit '${value}'`,
);
if (asNumber !== undefined) {
return methods[unit].call(this, ...args, asNumber);
} else {
return methods[unit].call(this, ...args);
}
});
}
patch(lib.Config.prototype, 'free', function() {
// Since we handle the memory allocation ourselves (via lib.Config.create),
// we also need to handle the deallocation
lib.Config.destroy(this);
});
patch(lib.Node, 'create', function(_, config) {
// We decide the constructor we want to call depending on the parameters
return config
? lib.Node.createWithConfig(config)
: lib.Node.createDefault();
});
patch(lib.Node.prototype, 'free', function() {
// Since we handle the memory allocation ourselves (via lib.Node.create),
// we also need to handle the deallocation
lib.Node.destroy(this);
});
patch(lib.Node.prototype, 'freeRecursive', function() {
for (let t = 0, T = this.getChildCount(); t < T; ++t) {
this.getChild(0).freeRecursive();
}
this.free();
});
patch(lib.Node.prototype, 'setMeasureFunc', function(original, measureFunc) {
// This patch is just a convenience patch, since it helps write more
// idiomatic source code (such as .setMeasureFunc(null))
// We also automatically convert the return value of the measureFunc
// to a Size object, so that we can return anything that has .width and
// .height properties
if (measureFunc) {
return original.call(this, (...args) =>
Size.fromJS(measureFunc(...args)),
);
} else {
return this.unsetMeasureFunc();
}
});
patch(lib.Node.prototype, 'calculateLayout', function(
original,
width = NaN,
height = NaN,
direction = CONSTANTS.DIRECTION_LTR,
) {
// Just a small patch to add support for the function default parameters
return original.call(this, width, height, direction);
});
return {
Config: lib.Config,
Node: lib.Node,
Layout: bind('Layout', Layout),
Size: bind('Size', Size),
Value: bind('Value', Value),
getInstanceCount(...args) {
return lib.getInstanceCount(...args);
},
...CONSTANTS,
};
};

View File

@@ -5,9 +5,25 @@
* 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.
*
* @flow
* @format
*/
var nbind = require('nbind');
var ret = nbind.init(__dirname + '/../');
module.exports = require('./entry-common')(ret.bind, ret.lib);
import Yoga from './entry-common';
const nbind = require('nbind');
const {bind, lib} = nbind.init(__dirname + '/../');
module.exports = Yoga(bind, lib);
export type {
Yoga$JustifyContent,
Yoga$Align,
Yoga$FlexDirection,
Yoga$Direction,
Yoga$FlexWrap,
Yoga$Edge,
Yoga$Display,
Yoga$Unit,
Yoga$Overflow,
Yoga$PositionType,
Yoga$ExperimentalFeature,
} from './YGEnums.js';