UNPKG

nuke-link

Version:

链接

196 lines (186 loc) 4.9 kB
/** @jsx createElement */ 'use strict'; import { createElement, Component, PropTypes, render } from 'rax'; import Text from 'nuke-text'; import Touchable from 'nuke-touchable'; import { isWeex, isWeb, isQNWeb } from 'nuke-env'; import { urlHelper } from 'nuke-util'; import Bridge from './bridge'; import StyledA from './styleda'; const defaultLineHeightOptimizer = fontSize => Math.ceil( 9.24 * Math.pow(10, -5) * Math.pow(fontSize, 2) + 1.492 * fontSize + 2.174 ); class Link extends Component { constructor(props, context) { super(props); this.fixedFont = context.commonConfigs && context.commonConfigs.fixedFont; this.optimizeLineHeight = context.commonConfigs && context.commonConfigs.optimizeLineHeight; if ('fixedFont' in props) { this.fixedFont = props.fixedFont; } if ('optimizeLineHeight' in props) { this.optimizeLineHeight = props.optimizeLineHeight; } } pushNext = () => { if (isWeex) { var navigator = require('@weex-module/navigator'); try { navigator.push( { url: this.props.href }, function(e) {} ); } catch (e) {} } }; onTextPress = e => { // 由于 native 端事件绑了2遍,因此 web 端需要去重 if (isWeb) { e.stopPropagation(); } this.pushNext(); }; convertURL(url) { if (url.indexOf('qap://') > -1) { let options = { refer: window.location.href }; if ( typeof window.__QAP__ !== 'undefined' && __QAP__.package && __QAP__.package.config && __QAP__.package.config.WebRootPath ) { options.webRootPath = __QAP__.package.config.WebRootPath; } if (!options.webRootPath.endsWith('/')) { options.webRootPath += '/'; } // qap降级情况下,根据webrootPath计算获得qap协议对应的实际降级页面地址 url = options.webRootPath + url.replace(/qap:\/{2,3}/, ''); const WxParam = ['_wx_tpl', '_h5_tpl', 'dd_wx_tpl']; WxParam.map(param => { if (options.refer.indexOf(param) > -1) { options[param] = url; } }); url = urlHelper.setSearchParameter(url.replace('.js', '.html'), options, { keepOrigin: true, addQueryPrefix: false, encode: false }); } return url; } pushto = url => { Bridge(url); }; render() { const TextAttrArr = [ 'color', 'fontSize', 'fontStyle', 'fontWeight', 'textAlign', 'textDecoration' ]; const { children, href, target = '_self', webUrl, activeStyle } = this.props; let style = { ...styles.initial, ...this.props.style }; let textStyle = {}; let content; let activeObj = {}; for (let k in activeStyle) { activeObj[k + ':active'] = activeStyle[k]; } style = Object.assign(style, activeObj); if (isWeex) { if (typeof children === 'string') { TextAttrArr.forEach(item => { if (style[item]) { textStyle[item] = style[item]; } if (style[item + ':active']) { textStyle[item + ':active'] = style[item + ':active']; } }); content = ( <Text fixedFont={this.fixedFont} optimizeLineHeight={this.optimizeLineHeight} onPress={this.onTextPress} style={textStyle} > {children} </Text> ); } return ( <Touchable {...this.props} activeStyle={activeStyle} style={style} onPress={this.pushNext} > {typeof children !== 'string' ? children : content} </Touchable> ); } else { let linkURL = webUrl || (href ? this.convertURL(href) : ''); if (isQNWeb && linkURL && target === '_blank') { return ( <Touchable {...this.props} style={style} onPress={this.pushto(linkURL)} > {children || content} </Touchable> ); } else { return ( <StyledA {...this.props} lineHeightOptimizer={defaultLineHeightOptimizer} target={target} style={[{ display: 'flex' }, style]} href={linkURL} > {this.props.children} </StyledA> ); } } } } const styles = { initial: { textDecoration: 'none' } }; Link.contextTypes = { androidConfigs: PropTypes.any, commonConfigs: PropTypes.any }; Link.propTypes = { optimizeLineHeight: PropTypes.boolean, fixedFont: PropTypes.boolean, lineHeightOptimizer: PropTypes.func }; Link.defaultProps = { style: {}, lineHeightOptimizer: defaultLineHeightOptimizer }; export default Link;