Skip to content

Instantly share code, notes, and snippets.

@FokkeZB
Last active April 13, 2016 14:28
Show Gist options
  • Save FokkeZB/2176a050569e4f354166 to your computer and use it in GitHub Desktop.
Save FokkeZB/2176a050569e4f354166 to your computer and use it in GitHub Desktop.
Facebook's css-layout for Titanium

Facebook's css-layout for Titanium

Exploring how it could be used to have a more iOS-autolayout-like layout system on Titanium.

Getting the script to work

  1. Put Layout.js in app/lib.
  2. Put the below computeLayout.js in app/lib to fix this.
  3. Use the below alloy.js and confirm it to work.

Using it meaningful

  • The Alloy view compiler could run the TSS/inline properties of a full view hierarchy through computeLayout before using them in the create*() statements.
  • If Titanium would allow to batch-create views like Carbon promised it could use the Obj-C/JAVA versions of CSS-layout on the native side, for both new and updated views.
  • Even without the above the flexbox properties could be added as supported layout properties and on each change the Obj-C/JAVA versions of CSS-layout could be used to re-layout.
var computeLayout = require('computeLayout');
console.debug(computeLayout({
style: {
padding: 50
},
children: [{
style: {
padding: 10,
alignSelf: 'stretch'
}
}]
}));
var computeLayout = require('Layout');
function roundLayout(layout) {
// Chrome rounds all the numbers with a precision of 1/64
// Reproduce the same behavior
function round(number) {
var floored = Math.floor(number);
var decimal = number - floored;
if (decimal === 0) {
return number;
}
var minDifference = Infinity;
var minDecimal = Infinity;
for (var i = 1; i < 64; ++i) {
var roundedDecimal = i / 64;
var difference = Math.abs(roundedDecimal - decimal);
if (difference < minDifference) {
minDifference = difference;
minDecimal = roundedDecimal;
}
}
return floored + minDecimal;
}
function rec(layout) {
layout.top = round(layout.top);
layout.left = round(layout.left);
layout.width = round(layout.width);
layout.height = round(layout.height);
if (layout.children) {
for (var i = 0; i < layout.children.length; ++i) {
rec(layout.children[i]);
}
}
}
rec(layout);
return layout;
}
function computeCSSLayout(rootNode) {
function fillNodes(node) {
node.layout = {
width: undefined,
height: undefined,
top: 0,
left: 0
};
if (!node.style) {
node.style = {};
}
if (!node.children || node.style.measure) {
node.children = [];
}
node.children.forEach(fillNodes);
}
function extractNodes(node) {
var layout = node.layout;
delete node.layout;
if (node.children.length > 0) {
layout.children = node.children.map(extractNodes);
} else {
delete node.children;
}
return layout;
}
fillNodes(rootNode);
computeLayout(rootNode);
return roundLayout(extractNodes(rootNode));
}
module.exports = computeCSSLayout;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment