diff --git a/README.md b/README.md index 200efeb..c27de8a 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,55 @@ function createPage(html, scriptTag) { ## API +### setCustomCreateScriptTagMethod + +You can use custom `createScriptTag(json)` function to escape html symbols json for example. +By default, AsyncProps use: + +```js +function createScriptTag(json){ + return `` +} +``` + +You can specify your own function: + +```js +import { setCreateScriptTagMethod } from 'async-props' + +setCreateScriptTagMethod(function(json){ + return `` +}) +``` + +As you see, you function should return `''` + + +### setCustomStringifyPropsMethod + +You can use custom `stringifyProp(propsArray)` function to minify json on production for example. +By default, AsyncProps use: + +```js +function (propsArray){ + return JSON.stringify(propsArray, null, 2) +} +``` + +You can specify your own function: + +```js +import { setStringifyPropsMethod } from 'async-props' + +setStringifyPropsMethod(function(propsArray){ + return JSON.stringify(propsArray) +}) +``` + +As you see, you function should String, that you can parse on client. + +--------- + Please refer to the example, as it exercises the entire API. Docs will come eventually :) diff --git a/modules/AsyncProps.js b/modules/AsyncProps.js index 4dc7880..c354f91 100644 --- a/modules/AsyncProps.js +++ b/modules/AsyncProps.js @@ -26,7 +26,7 @@ function filterAndFlattenComponents(components) { return flattened } -function loadAsyncProps({ components, params, loadContext }, cb) { +function loadAsyncProps({ components, params, location, loadContext }, cb) { let componentsArray = [] let propsArray = [] let needToLoadCounter = components.length @@ -44,7 +44,7 @@ function loadAsyncProps({ components, params, loadContext }, cb) { maybeFinish() } else { components.forEach((Component, index) => { - Component.loadProps({ params, loadContext }, (error, props) => { + Component.loadProps({ params, location, loadContext }, (error, props) => { const isDeferredCallback = hasCalledBack[index] if (isDeferredCallback && needToLoadCounter === 0) { cb(error, { @@ -93,18 +93,35 @@ function createElement(Component, props) { return } -export function loadPropsOnServer({ components, params }, loadContext, cb) { +function stringifyProps(propsArray){ + return JSON.stringify(propsArray, null, 2) +} + +export function setStringifyPropsMethod(newStringifyPropsMethod){ + stringifyProps = newStringifyPropsMethod; +} + +function createScriptTag(json){ + return `` +} + +export function setCreateScriptTagMethod(newCreateScriptTagMethod){ + createScriptTag = newCreateScriptTagMethod; +} + +export function loadPropsOnServer({ components, params, location }, loadContext, cb) { loadAsyncProps({ components: filterAndFlattenComponents(components), params, + location, loadContext }, (err, propsAndComponents) => { if (err) { cb(err) } else { - const json = JSON.stringify(propsAndComponents.propsArray, null, 2) - const scriptString = `` + const json = stringifyProps(propsAndComponents.propsArray) + const scriptString = createScriptTag(json) cb(null, propsAndComponents, scriptString) } }) @@ -222,14 +239,15 @@ const AsyncProps = React.createClass({ if (nextProps.location === this.props.location) return - const { enterRoutes } = computeChangedRoutes( + const { enterRoutes, changeRoutes } = computeChangedRoutes( { routes: this.props.routes, params: this.props.params }, { routes: nextProps.routes, params: nextProps.params } ) - const indexDiff = nextProps.components.length - enterRoutes.length + const checkRoutes = enterRoutes.concat(changeRoutes.filter((route)=>(route.component && route.component.isQueryDepend))) + const indexDiff = nextProps.components.length - checkRoutes.length const components = [] - for (let i = 0, l = enterRoutes.length; i < l; i++) + for (let i = 0, l = checkRoutes.length; i < l; i++) components.push(nextProps.components[indexDiff + i]) this.loadAsyncProps( @@ -261,6 +279,7 @@ const AsyncProps = React.createClass({ loadAsyncProps({ components: filterAndFlattenComponents(components), params, + location, loadContext }, this.handleError((err, propsAndComponents) => { const reloading = options && options.reload diff --git a/modules/__tests__/AsyncProps-test.js b/modules/__tests__/AsyncProps-test.js index 49456b2..0c4a8b9 100644 --- a/modules/__tests__/AsyncProps-test.js +++ b/modules/__tests__/AsyncProps-test.js @@ -3,7 +3,7 @@ import expect, { spyOn, restoreSpies } from 'expect' import createHistory from 'react-router/lib/createMemoryHistory' import { render } from 'react-dom' import { Router, Route, match } from 'react-router' -import AsyncProps, { loadPropsOnServer } from '../AsyncProps' +import AsyncProps, { loadPropsOnServer, setCreateScriptTagMethod, setStringifyPropsMethod } from '../AsyncProps' const createRunner = (routes, extraProps) => { return ({ startPath, steps }) => { @@ -146,6 +146,44 @@ describe('server rendering', () => { }) }) }) + + describe('customise script tag by user', function(){ + afterEach(function(){ + setStringifyPropsMethod(function(json){ + return JSON.stringify(json, null, 2) //default + }); + setCreateScriptTagMethod(function (json){ + return `` + }) + }); + it('allow to replace default JSON#stringify() by user stringify method', () => { + match({ routes, location: '/' }, (err, redirect, renderProps) => { + function someStringifyMethod(props){ + return JSON.stringify(props); + } + setStringifyPropsMethod(someStringifyMethod); + loadPropsOnServer(renderProps, {}, (err, data, scriptString) => { + expect(scriptString).toEqual( + `` + ) + }) + }) + }) + + it('allow to change script tag with user createScriptTagMethod', () => { + match({ routes, location: '/' }, (err, redirect, renderProps) => { + function createSomeTag(json){ + return `` + } + setCreateScriptTagMethod(createSomeTag); + loadPropsOnServer(renderProps, {}, (err, data, scriptString) => { + expect(scriptString).toEqual( + `` + ) + }) + }) + }) + }) }) // These tests are probably overkill for the implementation, could diff --git a/package.json b/package.json index 5c8b2d6..7ef9d1e 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { - "name": "async-props", - "version": "0.3.2", + "name": "async-props-nfs", + "version": "0.4.4", "description": "Co-located component data fetching for React Router", "main": "lib/AsyncProps", "repository": { "type": "git", - "url": "https://github.com/rackt/async-props.git" + "url": "https://github.com/NumminorihSF/async-props-nfs.git" }, - "bugs": "https://github.com/rackt/async-props/issues", + "bugs": "https://github.com/NumminorihSF/async-props-nfs/issues", "scripts": { "build": "babel ./modules -d lib --ignore '__tests__'", "build-umd": "NODE_ENV=production webpack modules/AsyncProps.js umd/AsyncProps.js", @@ -18,7 +18,8 @@ "postinstall": "node ./npm-scripts/postinstall.js" }, "authors": [ - "Ryan Florence" + "Ryan Florence", + "Konstantin Petryaev" ], "license": "MIT", "peerDependencies": {