From 9fde7d2828956372aadd64c760cdfb66a3acde0a Mon Sep 17 00:00:00 2001 From: Amjad Masad Date: Wed, 13 May 2015 17:45:36 -0700 Subject: [PATCH] [react-native] Make document.js into a polyfill. Fixes #1149 Summary: @public document shimming must run before anything else. However, we don't currently guarantee that. This moves the document shimming into `document.js` which is used as a polyfill. Test Plan: * start server * go to playground app * require `NativeModules` as the first thing * open chrome debugger * no error --- .../InitializeJavaScriptAppEngine.js | 34 ------------------- .../JavaScriptAppEngine/polyfills/document.js | 34 +++++++++++++++++++ packager/packager.js | 7 +++- 3 files changed, 40 insertions(+), 35 deletions(-) create mode 100644 Libraries/JavaScriptAppEngine/polyfills/document.js diff --git a/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js b/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js index 217fd93e7..b810c5bc3 100644 --- a/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js +++ b/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js @@ -33,39 +33,6 @@ if (typeof window === 'undefined') { window = GLOBAL; } -/** - * The document must be shimmed before anything else that might define the - * `ExecutionEnvironment` module (which checks for `document.createElement`). - */ -function setupDocumentShim() { - // The browser defines Text and Image globals by default. If you forget to - // require them, then the error message is very confusing. - function getInvalidGlobalUseError(name) { - return new Error( - 'You are trying to render the global ' + name + ' variable as a ' + - 'React element. You probably forgot to require ' + name + '.' - ); - } - GLOBAL.Text = { - get defaultProps() { - throw getInvalidGlobalUseError('Text'); - } - }; - GLOBAL.Image = { - get defaultProps() { - throw getInvalidGlobalUseError('Image'); - } - }; - // Force `ExecutionEnvironment.canUseDOM` to be false. - if (GLOBAL.document) { - GLOBAL.document.createElement = null; - } - - // There is no DOM so MutationObserver doesn't make sense. It is used - // as feature detection in Bluebird Promise implementation - GLOBAL.MutationObserver = undefined; -} - function handleErrorWithRedBox(e, isFatal) { try { require('ExceptionsManager').handleException(e, isFatal); @@ -148,7 +115,6 @@ function setupGeolocation() { GLOBAL.navigator.geolocation = require('Geolocation'); } -setupDocumentShim(); setupRedBoxErrorHandler(); setupTimers(); setupAlert(); diff --git a/Libraries/JavaScriptAppEngine/polyfills/document.js b/Libraries/JavaScriptAppEngine/polyfills/document.js new file mode 100644 index 000000000..4e76db957 --- /dev/null +++ b/Libraries/JavaScriptAppEngine/polyfills/document.js @@ -0,0 +1,34 @@ +/* eslint global-strict: 0 */ +(function(GLOBAL) { + /** + * The document must be shimmed before anything else that might define the + * `ExecutionEnvironment` module (which checks for `document.createElement`). + */ + + // The browser defines Text and Image globals by default. If you forget to + // require them, then the error message is very confusing. + function getInvalidGlobalUseError(name) { + return new Error( + 'You are trying to render the global ' + name + ' variable as a ' + + 'React element. You probably forgot to require ' + name + '.' + ); + } + GLOBAL.Text = { + get defaultProps() { + throw getInvalidGlobalUseError('Text'); + } + }; + GLOBAL.Image = { + get defaultProps() { + throw getInvalidGlobalUseError('Image'); + } + }; + // Force `ExecutionEnvironment.canUseDOM` to be false. + if (GLOBAL.document) { + GLOBAL.document.createElement = null; + } + + // There is no DOM so MutationObserver doesn't make sense. It is used + // as feature detection in Bluebird Promise implementation + GLOBAL.MutationObserver = undefined; +})(this); diff --git a/packager/packager.js b/packager/packager.js index 48552d93e..eb90b04e0 100644 --- a/packager/packager.js +++ b/packager/packager.js @@ -200,7 +200,12 @@ function getAppMiddleware(options) { cacheVersion: '2', transformModulePath: require.resolve('./transformer.js'), assetRoots: options.assetRoots, - assetExts: ['png', 'jpeg', 'jpg'] + assetExts: ['png', 'jpeg', 'jpg'], + polyfillModuleNames: [ + require.resolve( + '../Libraries/JavaScriptAppEngine/polyfills/document.js' + ), + ], }); }