Skip to content

Commit

Permalink
Resolve relative size rendering error in inspector (#23804)
Browse files Browse the repository at this point in the history
Summary:
Currently, when relative sizes are given in margin or padding stylings (be it a percentage or an auto measure), the inspector crashes, due to frame rendering not properly handling those kinds of measurements. This PR adds a resolution step for them:

* Percentages are evaluated relative to the window size.
* I decided to simply not render `auto` margins/paddings, due to the complexities involved (e.g. when the margin is between multiple elements with relative sizes).

Since the inspector does not crash anymore on relative sizes on paddings or margins, I believe that this addresses #17496.

Fixes #17496

[General] [Fixed] - Fix inspector rendering of relative margins and paddings
Pull Request resolved: #23804

Differential Revision: D14437273

Pulled By: cpojer

fbshipit-source-id: c9f0f71a2e1b2399a2b2148cef2124787703ead3
  • Loading branch information
Georgios Andreadis authored and facebook-github-bot committed Mar 13, 2019
1 parent fc3225d commit 972ee2e
Showing 1 changed file with 54 additions and 2 deletions.
56 changes: 54 additions & 2 deletions Libraries/Inspector/ElementBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,16 @@ const BorderBox = require('BorderBox');
const React = require('React');
const StyleSheet = require('StyleSheet');
const View = require('View');
const Dimensions = require('Dimensions');

const flattenStyle = require('flattenStyle');
const resolveBoxStyle = require('resolveBoxStyle');

class ElementBox extends React.Component<$FlowFixMeProps> {
render() {
const style = flattenStyle(this.props.style) || {};
const margin = resolveBoxStyle('margin', style);
const padding = resolveBoxStyle('padding', style);
let margin = resolveBoxStyle('margin', style);
let padding = resolveBoxStyle('padding', style);

const frameStyle = {...this.props.frame};
const contentStyle = {
Expand All @@ -31,6 +32,8 @@ class ElementBox extends React.Component<$FlowFixMeProps> {
};

if (margin != null) {
margin = resolveRelativeSizes(margin);

frameStyle.top -= margin.top;
frameStyle.left -= margin.left;
frameStyle.height += margin.top + margin.bottom;
Expand All @@ -51,6 +54,8 @@ class ElementBox extends React.Component<$FlowFixMeProps> {
}

if (padding != null) {
padding = resolveRelativeSizes(padding);

contentStyle.width -= padding.left + padding.right;
contentStyle.height -= padding.top + padding.bottom;
}
Expand Down Expand Up @@ -82,4 +87,51 @@ const styles = StyleSheet.create({
},
});

type Style = {
top: number,
right: number,
bottom: number,
left: number,
};

/**
* Resolves relative sizes (percentages and auto) in a style object.
*
* @param style the style to resolve
* @return a modified copy
*/
function resolveRelativeSizes(style: $ReadOnly<Style>): Style {
let resolvedStyle = Object.assign({}, style);
resolveSizeInPlace(resolvedStyle, 'top', 'height');
resolveSizeInPlace(resolvedStyle, 'right', 'width');
resolveSizeInPlace(resolvedStyle, 'bottom', 'height');
resolveSizeInPlace(resolvedStyle, 'left', 'width');
return resolvedStyle;
}

/**
* Resolves the given size of a style object in place.
*
* @param style the style object to modify
* @param direction the direction to resolve (e.g. 'top')
* @param dimension the window dimension that this direction belongs to (e.g. 'height')
*/
function resolveSizeInPlace(
style: Style,
direction: string,
dimension: string,
) {
if (style[direction] !== null && typeof style[direction] === 'string') {
if (style[direction].indexOf('%') !== -1) {
style[direction] =
(parseFloat(style[direction]) / 100.0) *
Dimensions.get('window')[dimension];
}
if (style[direction] === 'auto') {
// Ignore auto sizing in frame drawing due to complexity of correctly rendering this
style[direction] = 0;
}
}
}

module.exports = ElementBox;

0 comments on commit 972ee2e

Please sign in to comment.