diff --git a/Examples/UIExplorer/PanResponderExample.js b/Examples/UIExplorer/PanResponderExample.js index b41b56f3e..c2e6a667c 100644 --- a/Examples/UIExplorer/PanResponderExample.js +++ b/Examples/UIExplorer/PanResponderExample.js @@ -52,8 +52,10 @@ var PanResponderExample = React.createClass({ this._previousLeft = 20; this._previousTop = 84; this._circleStyles = { - left: this._previousLeft, - top: this._previousTop, + style: { + left: this._previousLeft, + top: this._previousTop + } }; }, @@ -78,13 +80,17 @@ var PanResponderExample = React.createClass({ _highlight: function() { this.circle && this.circle.setNativeProps({ - backgroundColor: processColor(CIRCLE_HIGHLIGHT_COLOR) + style: { + backgroundColor: processColor(CIRCLE_HIGHLIGHT_COLOR) + } }); }, _unHighlight: function() { this.circle && this.circle.setNativeProps({ - backgroundColor: processColor(CIRCLE_COLOR) + style: { + backgroundColor: processColor(CIRCLE_COLOR) + } }); }, @@ -106,8 +112,8 @@ var PanResponderExample = React.createClass({ this._highlight(); }, _handlePanResponderMove: function(e: Object, gestureState: Object) { - this._circleStyles.left = this._previousLeft + gestureState.dx; - this._circleStyles.top = this._previousTop + gestureState.dy; + this._circleStyles.style.left = this._previousLeft + gestureState.dx; + this._circleStyles.style.top = this._previousTop + gestureState.dy; this._updatePosition(); }, _handlePanResponderEnd: function(e: Object, gestureState: Object) { diff --git a/Libraries/Components/Navigator/NavigatorBreadcrumbNavigationBarStyles.android.js b/Libraries/Components/Navigator/NavigatorBreadcrumbNavigationBarStyles.android.js index 359e63c32..3ae86f0e7 100644 --- a/Libraries/Components/Navigator/NavigatorBreadcrumbNavigationBarStyles.android.js +++ b/Libraries/Components/Navigator/NavigatorBreadcrumbNavigationBarStyles.android.js @@ -125,18 +125,14 @@ RIGHT[0].Title = merge(FIRST_TITLE_BASE, {opacity: 0}); var buildIndexSceneInterpolator = function(startStyles, endStyles) { return { Crumb: buildStyleInterpolator({ - translateX: { + left: { type: 'linear', - from: 0, - to: endStyles.Crumb.left - startStyles.Crumb.left, + from: startStyles.Crumb.left, + to: endStyles.Crumb.left, min: 0, max: 1, extrapolate: true, }, - left: { - value: startStyles.Crumb.left, - type: 'constant' - }, }), Icon: buildStyleInterpolator({ opacity: { @@ -164,18 +160,14 @@ var buildIndexSceneInterpolator = function(startStyles, endStyles) { min: 0, max: 1, }, - translateX: { + left: { type: 'linear', - from: 0, - to: endStyles.Title.left - startStyles.Title.left, + from: startStyles.Title.left, + to: endStyles.Title.left, min: 0, max: 1, extrapolate: true, }, - left: { - value: startStyles.Title.left, - type: 'constant' - }, }), RightItem: buildStyleInterpolator({ opacity: { diff --git a/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js b/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js index fcd695abd..5a1015758 100644 --- a/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js +++ b/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js @@ -44,6 +44,31 @@ function handleError(e, isFatal) { } } +/** + * Assigns a new global property, replacing the existing one if there is one. + * + * Existing properties are preserved as `originalPropertyName`. Both properties + * will maintain the same enumerability & configurability. + * + * This allows you to undo the more aggressive polyfills, should you need to. + * For example, if you want to route network requests through DevTools (to trace + * them): + * + * GLOBAL.XMLHTTPRequest = GLOBAL.originalXMLHTTPRequest; + * + * For more info on that particular case, see: + * https://github.com/facebook/react-native/issues/934 + */ +function polyfillGlobal(name, newValue, scope=GLOBAL) { + var descriptor = Object.getOwnPropertyDescriptor(scope, name); + + if (scope[name] !== undefined) { + var backupName = `original${name[0].toUpperCase()}${name.substr(1)}`; + Object.defineProperty(scope, backupName, {...descriptor, value: scope[name]}); + } + Object.defineProperty(scope, name, {...descriptor, value: newValue}); +} + function setUpRedBoxErrorHandler() { var ErrorUtils = require('ErrorUtils'); ErrorUtils.setGlobalHandler(handleError); @@ -111,23 +136,23 @@ function setUpPromise() { function setUpXHR() { // The native XMLHttpRequest in Chrome dev tools is CORS aware and won't // let you fetch anything from the internet - GLOBAL.XMLHttpRequest = require('XMLHttpRequest'); - GLOBAL.FormData = require('FormData'); + polyfillGlobal('XMLHttpRequest', require('XMLHttpRequest')); + polyfillGlobal('FormData', require('FormData')); var fetchPolyfill = require('fetch'); - GLOBAL.fetch = fetchPolyfill.fetch; - GLOBAL.Headers = fetchPolyfill.Headers; - GLOBAL.Request = fetchPolyfill.Request; - GLOBAL.Response = fetchPolyfill.Response; + polyfillGlobal('fetch', fetchPolyfill.fetch); + polyfillGlobal('Headers', fetchPolyfill.Headers); + polyfillGlobal('Request', fetchPolyfill.Request); + polyfillGlobal('Response', fetchPolyfill.Response); } function setUpGeolocation() { GLOBAL.navigator = GLOBAL.navigator || {}; - GLOBAL.navigator.geolocation = require('Geolocation'); + polyfillGlobal('geolocation', require('Geolocation'), GLOBAL.navigator); } function setUpWebSockets() { - GLOBAL.WebSocket = require('WebSocket'); + polyfillGlobal('WebSocket', require('WebSocket')); } function setUpProfile() { diff --git a/React.podspec b/React.podspec index 4b762c858..523020ae9 100644 --- a/React.podspec +++ b/React.podspec @@ -24,7 +24,6 @@ Pod::Spec.new do |s| s.platform = :ios, "7.0" s.prepare_command = 'npm install --production' s.preserve_paths = "cli.js", "Libraries/**/*.js", "lint", "linter.js", "node_modules", "package.json", "packager", "PATENTS", "react-native-cli" - s.header_mappings_dir = "." s.subspec 'Core' do |ss| ss.source_files = "React/**/*.{c,h,m}" diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java index 21540b59c..a841e2c9a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java @@ -73,7 +73,13 @@ public class ReactTextShadowNode extends ReactShadowNode { this.what = what; } public void execute(SpannableStringBuilder sb) { - sb.setSpan(what, start, end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); + // All spans will automatically extend to the right of the text, but not the left - except + // for spans that start at the beginning of the text. + int spanFlags = Spannable.SPAN_EXCLUSIVE_INCLUSIVE; + if (start == 0) { + spanFlags = Spannable.SPAN_INCLUSIVE_INCLUSIVE; + } + sb.setSpan(what, start, end, spanFlags); } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java index 8a4833225..713209423 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java @@ -56,6 +56,8 @@ public class ReactTextInputManager extends public static final String PROP_TEXT_INPUT_TEXT = "text"; @UIProp(UIProp.Type.NUMBER) public static final String PROP_TEXT_INPUT_MOST_RECENT_EVENT_COUNT = "mostRecentEventCount"; + @UIProp(UIProp.Type.COLOR) + public static final String PROP_TEXT_INPUT_COLOR = ViewProps.COLOR; private static final String KEYBOARD_TYPE_EMAIL_ADDRESS = "email-address"; private static final String KEYBOARD_TYPE_NUMERIC = "numeric"; @@ -157,16 +159,6 @@ public class ReactTextInputManager extends (int) Math.ceil(PixelUtil.toPixelFromSP(fontSize))); } - // Prevents flickering color while waiting for JS update. - @ReactProp(name = ViewProps.COLOR, customType = "Color") - public void setColor(ReactEditText view, @Nullable Integer color) { - if (color == null) { - view.setTextColor(DefaultStyleValuesUtil.getDefaultTextColor(view.getContext())); - } else { - view.setTextColor(color); - } - } - @ReactProp(name = "placeholder") public void setPlaceholder(ReactEditText view, @Nullable String placeholder) { view.setHint(placeholder); diff --git a/package.json b/package.json index 5e6118d3f..2f3870188 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,9 @@ "type": "git", "url": "git@github.com:facebook/react-native.git" }, + "engines": { + "node": ">=4" + }, "jest": { "scriptPreprocessor": "jestSupport/preprocessor.js", "setupEnvScriptFile": "jestSupport/env.js", diff --git a/packager/package.json b/packager/package.json index f9927a87c..61f733d64 100644 --- a/packager/package.json +++ b/packager/package.json @@ -6,6 +6,9 @@ "type": "git", "url": "git@github.com:facebook/react-native.git" }, + "engines": { + "node": ">=4" + }, "jest": { "setupEnvScriptFile": "jestSupport/env.js", "testPathIgnorePatterns": [ diff --git a/website/server/extractDocs.js b/website/server/extractDocs.js index 7ce11d5f2..800718273 100644 --- a/website/server/extractDocs.js +++ b/website/server/extractDocs.js @@ -225,6 +225,7 @@ var apis = [ '../Libraries/Storage/AsyncStorage.ios.js', '../Libraries/Utilities/BackAndroid.android.js', '../Libraries/CameraRoll/CameraRoll.js', + '../Libraries/Utilities/Dimensions.js', '../Libraries/Interaction/InteractionManager.js', '../Libraries/LayoutAnimation/LayoutAnimation.js', '../Libraries/LinkingIOS/LinkingIOS.js',