apeman-react-head
Version:
apeman react package for head component.
215 lines (202 loc) • 5.43 kB
JSX
/**
* apeman react package for head component.
* @class ApHead
*/
import React, { PropTypes as types } from 'react'
import stringcase from 'stringcase'
/** @lends ApHead */
const ApHead = React.createClass({
// --------------------
// Specs
// --------------------
propTypes: {
/** CharSet */
charSet: types.string,
/** Document Title */
title: types.string,
/** Favicon */
icon: types.string,
/** Meta data */
meta: types.oneOfType([
types.arrayOf(types.object),
types.object
]),
/** Micro data settings */
itemProps: types.oneOfType([
types.arrayOf(types.object),
types.object
]),
/** CSS file urls */
css: types.array,
/** JS file urls */
js: types.array,
/** Version string */
version: types.string,
/** Query string key for version */
versionKey: types.string,
/** Global variables */
globals: types.object,
/** View port settings */
viewPort: types.object,
/** Base url */
base: types.string,
/** Target of base url. '_blank', '_parent', '_self', '_top' or frame name */
baseTarget: types.string,
/** Path of manifest.json */
manifest: types.string,
/** Theme color */
color: types.string
},
mixins: [],
statics: {
renderBase (base, target) {
if (!base) {
return null
}
return (
<base href={ base } target={ target }/>
)
},
renderCharset (charSet) {
if (!charSet) {
return null
}
return (
<meta className='ap-head-meta' charSet={ charSet }/>
)
},
renderTitle (title) {
if (!title) {
return null
}
return (
<title className='ap-head-title'>{ title }</title>
)
},
renderIcon (url, query) {
if (!url) {
return null
}
return (
<link rel='icon' href={ ApHead._addQuery(url, query) }/>
)
},
renderMetaValues (values) {
if (!values) {
return null
}
return [].concat(values).map((values, i) =>
Object.keys(values).map((name, j) =>
<meta name={ name }
content={ values[ name ] }
key={ `meta-${i}-${j}` }/>
)
).reduce((a, b) => [].concat(a, b), [])
},
renderItemProps (values) {
if (!values) {
return null
}
return [].concat(values).map((values, i) =>
Object.keys(values).map((name, j) =>
<meta itemProp={ name }
content={ values[ name ] }
key={ `item-prop${i}-${j}` }/>
)
).reduce((a, b) => [].concat(a, b), [])
},
renderCss (urls, query) {
if (!urls) {
return null
}
return [].concat(urls).map((url, i) =>
<link rel='stylesheet'
type='text/css'
key={ `css-${i}-${url}` }
href={ ApHead._addQuery(url, query) }/>
)
},
renderJs (urls, query) {
if (!urls) {
return null
}
return [].concat(urls).map((url, i) =>
<script type='text/javascript'
key={ `js-${i}-${url}` }
src={ ApHead._addQuery(url, query)}></script>
)
},
renderGlobals (values) {
let _stringify = (data) => data ? JSON.stringify(data || {}) : 'null'
return Object.keys(values || {}).map((key, i) =>
<script type='text/javascript'
key={ `global-${i}-${key}` }
dangerouslySetInnerHTML={
{ __html: `window.${key}=${_stringify(values[ key ])}` }
}></script>
)
},
renderViewPort (values) {
let content = Object.keys(values || {}).map((key) =>
[ stringcase.spinalcase(key), values[ key ] ].join('=')
).join(',')
return <meta name='viewport' content={ content }/>
},
renderManifest (value) {
if (!value) {
return null
}
return <link rel='manifest' href={ value }/>
},
renderThemeColor (value) {
if (!value) {
return null
}
return <meta name='theme-color' content={ value }/>
},
_addQuery (url, query) {
let joiner = /\?/.test(url) ? '&' : '?'
return [ url, query ].join(joiner)
}
},
getInitialState () {
return {}
},
getDefaultProps () {
return {
charSet: 'utf-8',
version: 'unknown',
versionKey: 'v',
viewPort: {
width: 'device-width',
initialScale: '1.0'
},
base: null,
baseTarget: undefined
}
},
render () {
const s = this
let { props } = s
let query = [ props.versionKey, props.version ].join('=')
return (
<head className='ap-head'>
{ ApHead.renderBase(props.base, props.baseTarget) }
{ ApHead.renderCharset(props.charSet) }
{ ApHead.renderTitle(props.title) }
{ ApHead.renderMetaValues(props.meta) }
{ ApHead.renderItemProps(props.itemProps) }
{ ApHead.renderIcon(props.icon, query) }
{ ApHead.renderGlobals(props.globals) }
{ ApHead.renderCss(props.css, query) }
{ ApHead.renderViewPort(props.viewPort) }
{ ApHead.renderManifest(props.manifest) }
{ ApHead.renderThemeColor(props.color) }
{ ApHead.renderJs(props.js, query) }
{ props.children }
</head>
)
}
})
export default ApHead