Files
yoga/javascript/sources/entry-common.js
Maël Nison 36f6fa9861 Fix tests of splitted config feature
Summary:
The following PR fixes the tests used in the javascript port (it modifies gentest.rb).

These changes don't yet pass, it seems something is segfaulting somewhere. I have to check if it comes from nbind, the yoga library, or the node bridge itself. There's also some fails on the browser build, but it might be the same issue.
Closes https://github.com/facebook/yoga/pull/487

Reviewed By: emilsjolander

Differential Revision: D4778870

Pulled By: astreet

fbshipit-source-id: 936fbca564ec89738c78e50c4402c53eb6867dec
2017-03-28 10:49:46 -07:00

250 lines
5.8 KiB
JavaScript

/**
* 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.
*/
function patch(prototype, name, fn) {
let original = prototype[name];
prototype[name] = function (... args) {
return fn.call(this, original, ... args);
};
}
module.exports = function (bind, lib) {
let constants = Object.assign({
UNDEFINED: NaN
}, require(`./YGEnums`));
class Layout {
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}>`;
}
}
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 (!Object.prototype.hasOwnProperty.call(methods, unit))
throw new Error(`Failed to execute "${fnName}": Unsupported unit.`);
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);
};