diff --git a/package.json b/package.json index f64841ba..6c55cefb 100644 --- a/package.json +++ b/package.json @@ -76,12 +76,14 @@ "react": "^0.14.0", "react-dom": "^0.14.0", "rimraf": "^2.4.3", + "scriptjs": "^2.5.8", "tomchentw-npm-dev": "^3.1.0" }, "dependencies": { "can-use-dom": "^0.1.0", "google-maps-infobox": "^1.1.13", - "invariant": "^2.1.1" + "invariant": "^2.1.1", + "warning": "^2.1.0" }, "peerDependencies": { "react": "^0.14.0", diff --git a/src/async/ScriptjsGoogleMap.js b/src/async/ScriptjsGoogleMap.js new file mode 100644 index 00000000..e2ad4b4c --- /dev/null +++ b/src/async/ScriptjsGoogleMap.js @@ -0,0 +1,68 @@ +import { + default as React, + Component, + PropTypes, +} from "react"; + +import { + default as canUseDOM, +} from "can-use-dom"; + +import { + default as warning, +} from "warning"; + +import { + GoogleMap, +} from "../index"; + +import { + default as makeUrl, +} from "../utils/makeUrl"; + +export default class ScriptjsGoogleMap extends Component { + static propTypes = { + // PropTypes for URL generation + // https://nodejs.org/api/url.html#url_url_format_urlobj + protocol: PropTypes.string, + hostname: PropTypes.string.isRequired, + port: PropTypes.number, + pathname: PropTypes.string.isRequired, + query: PropTypes.object.isRequired, + // PropTypes for ScriptjsGoogleMap + loadingElement: PropTypes.node, + } + + state = { + isLoaded: false, + } + + componentWillMount () { + if (!canUseDOM) { + return; + } + const scriptjs = require("scriptjs"); + const {protocol, hostname, port, pathname, query, ...restProps} = this.props; + const urlObj = {protocol, hostname, port, pathname, query}; + const url = makeUrl(urlObj); + scriptjs(url, () => this.setState({ isLoaded: true })); + } + + componentWillReceiveProps (nextProps) { + const changedKeys = Object.keys(ScriptjsGoogleMap.propTypes) + .filter(key => this.props[key] !== nextProps[key]); + + warning(0 === changedKeys.length, `ScriptjsGoogleMap doesn't support mutating props after initial render. Changed props: %s`, `[${ changedKeys.join(", ") }]`); + } + + render () { + if (this.state.isLoaded) { + const {protocol, hostname, port, pathname, query, ...restProps} = this.props; + return ( + + ); + } else { + return this.props.loadingElement; + } + } +} diff --git a/src/utils/makeUrl.js b/src/utils/makeUrl.js new file mode 100644 index 00000000..9261647b --- /dev/null +++ b/src/utils/makeUrl.js @@ -0,0 +1,13 @@ +import { + format as formatUrlObj, +} from "url"; + +export default function makeUrl (urlObj) { + return formatUrlObj({ + protocol: urlObj.protocol, + hostname: urlObj.hostname, + port: urlObj.port, + pathname: urlObj.pathname, + query: urlObj.query, + }); +}