Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve relative size rendering error in inspector #23804

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;