From deb0a85440e9735f44616b5752538252943d881d Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Sun, 11 Jun 2017 14:07:57 -0700 Subject: [PATCH] [change] AppRegistry.getApplication returns React elements This changes the return value of 'getApplication' so that the application element and stylesheets are all available as React elements. Also changes StyleSheet's 'renderToString' to 'getStyleSheets'. Fix #504 --- docs/apis/AppRegistry.md | 3 +- docs/apis/StyleSheet.md | 5 +- docs/guides/getting-started.md | 5 +- .../renderApplication-test.js.snap | 124 +++++++++--------- .../__tests__/renderApplication-test.js | 4 +- src/apis/AppRegistry/renderApplication.js | 6 +- src/apis/StyleSheet/StyleManager.js | 22 +++- src/apis/StyleSheet/StyleRegistry.js | 4 +- .../__snapshots__/index-test.js.snap | 22 ++-- src/apis/StyleSheet/__tests__/index-test.js | 4 +- src/apis/StyleSheet/index.js | 8 +- 11 files changed, 118 insertions(+), 89 deletions(-) diff --git a/docs/apis/AppRegistry.md b/docs/apis/AppRegistry.md index 98ba5b83..af66e87d 100644 --- a/docs/apis/AppRegistry.md +++ b/docs/apis/AppRegistry.md @@ -14,8 +14,7 @@ into `runApplication`. These should always be used as a pair. (web) static **getApplication**(appKey:string, appParameters: object) Returns the given application element. Use this for server-side rendering. -Return object is of type `{ element: ReactElement; stylesheet: ReactElement }`. -It's recommended that you use `sheetsheet` to render the style sheet in an app +Return object is of type `{ element: ReactElement; stylesheets: [ ReactElement ] }`. static **registerConfig**(config: Array) diff --git a/docs/apis/StyleSheet.md b/docs/apis/StyleSheet.md index bf79a0bc..c5104a3d 100644 --- a/docs/apis/StyleSheet.md +++ b/docs/apis/StyleSheet.md @@ -16,9 +16,10 @@ Each key of the object passed to `create` must define a style object. Flattens an array of styles into a single style object. -(web) **renderToString**: function +(web) **getStyleSheets**: function -Returns a string of the stylesheet for use in server-side rendering. +Returns an array of stylesheets (`{ id, textContent }`). Useful for +compile-time or server-side rendering. ## Properties diff --git a/docs/guides/getting-started.md b/docs/guides/getting-started.md index 1e803e6d..f17f5afb 100644 --- a/docs/guides/getting-started.md +++ b/docs/guides/getting-started.md @@ -187,15 +187,16 @@ const AppContainer = (props) => { /* ... */ } AppRegistry.registerComponent('App', () => AppContainer) // prerender the app -const { element, stylesheet } = AppRegistry.getApplication('App', { initialProps }); +const { element, stylesheets } = AppRegistry.getApplication('App', { initialProps }); const initialHTML = ReactDOMServer.renderToString(element); +const initialStyles = stylesheets.map((sheet) => ReactDOMServer.renderToString(sheet)).join('\n'); // construct HTML document const document = ` -${stylesheet} +${initialStyles} ${initialHTML} diff --git a/src/apis/AppRegistry/__tests__/__snapshots__/renderApplication-test.js.snap b/src/apis/AppRegistry/__tests__/__snapshots__/renderApplication-test.js.snap index f3724bf9..a8a9deda 100644 --- a/src/apis/AppRegistry/__tests__/__snapshots__/renderApplication-test.js.snap +++ b/src/apis/AppRegistry/__tests__/__snapshots__/renderApplication-test.js.snap @@ -9,63 +9,69 @@ exports[`apis/AppRegistry/renderApplication getApplication 1`] = ` `; exports[`apis/AppRegistry/renderApplication getApplication 2`] = ` -" -" +Array [ + , + , +] `; diff --git a/src/apis/AppRegistry/__tests__/renderApplication-test.js b/src/apis/AppRegistry/__tests__/renderApplication-test.js index 186d8512..06c4bc92 100644 --- a/src/apis/AppRegistry/__tests__/renderApplication-test.js +++ b/src/apis/AppRegistry/__tests__/renderApplication-test.js @@ -7,9 +7,9 @@ const RootComponent = () =>
; describe('apis/AppRegistry/renderApplication', () => { test('getApplication', () => { - const { element, stylesheet } = getApplication(RootComponent, {}); + const { element, stylesheets } = getApplication(RootComponent, {}); expect(element).toMatchSnapshot(); - expect(stylesheet).toMatchSnapshot(); + expect(stylesheets).toMatchSnapshot(); }); }); diff --git a/src/apis/AppRegistry/renderApplication.js b/src/apis/AppRegistry/renderApplication.js index f5f257ac..c1cc38ce 100644 --- a/src/apis/AppRegistry/renderApplication.js +++ b/src/apis/AppRegistry/renderApplication.js @@ -33,6 +33,8 @@ export function getApplication(RootComponent: ReactClass, initialProps: ); - const stylesheet = StyleSheet.renderToString(); - return { element, stylesheet }; + const stylesheets = StyleSheet.getStyleSheets().map(sheet => + + ); + return { element, stylesheets }; } diff --git a/src/apis/StyleSheet/StyleManager.js b/src/apis/StyleSheet/StyleManager.js index 1c059e11..50ffbca7 100644 --- a/src/apis/StyleSheet/StyleManager.js +++ b/src/apis/StyleSheet/StyleManager.js @@ -85,6 +85,15 @@ export default class StyleManager { } getStyleSheetHtml() { + const styleSheets = this.getStyleSheets(); + return styleSheets + .map(sheet => { + return ``; + }) + .join('\n'); + } + + getStyleSheets() { const cache = this.cache.byProp; const mainSheetTextContext = Object.keys(cache) @@ -99,9 +108,16 @@ export default class StyleManager { }, []) .join('\n'); - const staticSheet = ``; - const mainSheet = ``; - return `${staticSheet}\n${mainSheet}`; + return [ + { + id: 'react-native-stylesheet-static', + textContent: `${staticCss}\n${pointerEventsCss}` + }, + { + id: STYLE_ELEMENT_ID, + textContent: `${mainSheetTextContext}` + } + ]; } setDeclaration(prop, value) { diff --git a/src/apis/StyleSheet/StyleRegistry.js b/src/apis/StyleSheet/StyleRegistry.js index 61b61a13..95fb1dc3 100644 --- a/src/apis/StyleSheet/StyleRegistry.js +++ b/src/apis/StyleSheet/StyleRegistry.js @@ -26,8 +26,8 @@ export default class StyleRegistry { this.styleManager = new StyleManager(); } - getStyleSheetHtml() { - return this.styleManager.getStyleSheetHtml(); + getStyleSheets() { + return this.styleManager.getStyleSheets(); } /** diff --git a/src/apis/StyleSheet/__tests__/__snapshots__/index-test.js.snap b/src/apis/StyleSheet/__tests__/__snapshots__/index-test.js.snap index 1d4d83b3..62b31407 100644 --- a/src/apis/StyleSheet/__tests__/__snapshots__/index-test.js.snap +++ b/src/apis/StyleSheet/__tests__/__snapshots__/index-test.js.snap @@ -1,8 +1,10 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`apis/StyleSheet renderToString 1`] = ` -" -" +.rn-top-ipm5af{top:0px}", + }, +] `; diff --git a/src/apis/StyleSheet/__tests__/index-test.js b/src/apis/StyleSheet/__tests__/index-test.js index b1ed53b6..f361b7de 100644 --- a/src/apis/StyleSheet/__tests__/index-test.js +++ b/src/apis/StyleSheet/__tests__/index-test.js @@ -37,7 +37,7 @@ describe('apis/StyleSheet', () => { expect(Number.isInteger(StyleSheet.hairlineWidth) === true).toBeTruthy(); }); - test('renderToString', () => { - expect(StyleSheet.renderToString()).toMatchSnapshot(); + test('getStyleSheets', () => { + expect(StyleSheet.getStyleSheets()).toMatchSnapshot(); }); }); diff --git a/src/apis/StyleSheet/index.js b/src/apis/StyleSheet/index.js index 8af41ebd..ad92aa2a 100644 --- a/src/apis/StyleSheet/index.js +++ b/src/apis/StyleSheet/index.js @@ -24,11 +24,11 @@ const StyleSheet = { }); return result; }, - hairlineWidth: 1, flatten: flattenStyle, - renderToString() { - return StyleRegistry.getStyleSheetHtml(); - } + getStyleSheets() { + return StyleRegistry.getStyleSheets(); + }, + hairlineWidth: 1 }; export default StyleSheet;