weex-nuke
Version:
基于 Rax 、Weex 的高性能组件体系 ~~
180 lines (150 loc) • 3.79 kB
JSX
import { Component, createElement, PropTypes } from 'rax';
const isWeex = typeof callNative === 'function';
class Text extends Component {
static propTypes = {};
static contextTypes = {
isInAParentText: PropTypes.bool,
};
static childContextTypes = {
isInAParentText: PropTypes.bool,
};
getChildContext() {
return {
isInAParentText: true,
};
}
render() {
const props = this.props;
let { children } = props;
if (!Array.isArray(children)) {
children = [children];
}
let nested = false;
for (let i = 0; i < children.length; i++) {
const child = children[i];
if (child && typeof child === 'object') {
nested = true;
break;
}
}
return nested ? this.renderRichText() : this.renderText();
}
renderText = () => {
const props = this.props;
const nativeProps = {
...props,
...{
style: props.style || {},
},
};
let textString = '';
if (props.children != null) {
if (!Array.isArray(props.children)) {
textString = props.children.toString();
} else {
textString = props.children.join('');
}
}
if (this.context.isInAParentText) {
return <span {...nativeProps}>{textString}</span>;
}
if (props.onPress) {
nativeProps.onClick = props.onPress;
}
if (isWeex) {
if (props.numberOfLines) {
nativeProps.style.lines = props.numberOfLines;
}
nativeProps.value = textString;
return <text {...nativeProps} />;
}
const styleProps = {
...styles.text,
...nativeProps.style,
};
const numberOfLines = props.numberOfLines;
if (numberOfLines) {
if (parseInt(numberOfLines) === 1) {
styleProps.whiteSpace = 'nowrap';
} else {
styleProps.display = '-webkit-box';
styleProps.webkitBoxOrient = 'vertical';
styleProps.webkitLineClamp = String(numberOfLines);
}
styleProps.overflow = 'hidden';
}
return (
<span {...nativeProps} style={styleProps}>
{textString}
</span>
);
};
renderRichText = () => {
const props = this.props;
let { children } = props;
const nativeProps = {
...props,
...{
style: props.style || {},
},
};
const styleProps = {
...styles.richtext,
...nativeProps.style,
};
if (isWeex) {
children = transformChildren(children, this);
}
return (
<p {...nativeProps} style={styleProps}>
{children}
</p>
);
};
}
function transformChild(child, instance) {
const { type: ChildComponent, props } = child;
const { children } = props;
if (typeof ChildComponent === 'function') {
const childInstance = new ChildComponent();
childInstance.props = props;
if (children) {
childInstance.props.children = transformChildren(children, instance);
}
childInstance.context = instance.getChildContext();
return childInstance.render();
}
return child;
}
function transformChildren(children, instance) {
const elements = [];
if (!Array.isArray(children)) {
children = [children];
}
for (let i = 0; i < children.length; i++) {
const child = children[i];
if (typeof child === 'string') {
elements.push(child);
} else if (typeof child === 'object') {
elements.push(transformChild(child, instance));
}
}
return elements;
}
const styles = {
text: {
border: '0 solid black',
position: 'relative',
boxSizing: 'border-box',
display: 'block',
flexDirection: 'column',
alignContent: 'flex-start',
flexShrink: 0,
fontSize: 32,
},
richtext: {
marginTop: 0,
marginBottom: 0,
},
};
export default Text;