Fix setting js responder for null react view for tag

Reviewed By: kmagiera

Differential Revision: D2637015

fb-gh-sync-id: 03af870cee82519ed34a4bbbcbd2c72146fcf00f
This commit is contained in:
Andrei Coman 2015-11-18 03:18:29 -08:00 committed by facebook-github-bot-4
parent d5daef08ef
commit 32c19c1994
3 changed files with 39 additions and 12 deletions

View File

@ -442,13 +442,26 @@ import com.facebook.react.touch.JSResponderHandler;
return TouchTargetHelper.findTargetTagForTouch(touchY, touchX, (ViewGroup) view);
}
public void setJSResponder(int reactTag, boolean blockNativeResponder) {
public void setJSResponder(int reactTag, int initialReactTag, boolean blockNativeResponder) {
if (!blockNativeResponder) {
mJSResponderHandler.setJSResponder(initialReactTag, null);
return;
}
View view = mTagsToViews.get(reactTag);
if (initialReactTag != reactTag && view instanceof ViewParent) {
// In this case, initialReactTag corresponds to a virtual/layout-only View, and we already
// have a parent of that View in reactTag, so we can use it.
mJSResponderHandler.setJSResponder(initialReactTag, (ViewParent) view);
return;
}
if (mRootTags.get(reactTag)) {
SoftAssertions.assertUnreachable(
"Cannot block native responder on " + reactTag + " that is a root view");
}
ViewParent viewParent = blockNativeResponder ? mTagsToViews.get(reactTag).getParent() : null;
mJSResponderHandler.setJSResponder(reactTag, viewParent);
mJSResponderHandler
.setJSResponder(initialReactTag, view.getParent());
}
public void clearJSResponder() {

View File

@ -20,16 +20,14 @@ import java.util.concurrent.TimeUnit;
import android.util.DisplayMetrics;
import com.facebook.csslayout.CSSLayoutContext;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.animation.Animation;
import com.facebook.react.animation.AnimationRegistry;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.debug.NotThreadSafeUiManagerDebugListener;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.OnBatchCompleteListener;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
@ -37,6 +35,8 @@ import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.SoftAssertions;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.uimanager.debug.NotThreadSafeUiManagerDebugListener;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.systrace.Systrace;
import com.facebook.systrace.SystraceMessage;
@ -664,7 +664,11 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
@ReactMethod
public void setJSResponder(int reactTag, boolean blockNativeResponder) {
assertViewExists(reactTag, "setJSResponder");
mOperationsQueue.enqueueSetJSResponder(reactTag, blockNativeResponder);
ReactShadowNode node = mShadowNodeRegistry.getNode(reactTag);
while (node.isVirtual() || node.isLayoutOnly()) {
node = node.getParent();
}
mOperationsQueue.enqueueSetJSResponder(node.getReactTag(), reactTag, blockNativeResponder);
}
@ReactMethod

View File

@ -186,14 +186,17 @@ public class UIViewOperationQueue {
private final class ChangeJSResponderOperation extends ViewOperation {
private final int mInitialTag;
private final boolean mBlockNativeResponder;
private final boolean mClearResponder;
public ChangeJSResponderOperation(
int tag,
int initialTag,
boolean clearResponder,
boolean blockNativeResponder) {
super(tag);
mInitialTag = initialTag;
mClearResponder = clearResponder;
mBlockNativeResponder = blockNativeResponder;
}
@ -201,7 +204,7 @@ public class UIViewOperationQueue {
@Override
public void execute() {
if (!mClearResponder) {
mNativeViewHierarchyManager.setJSResponder(mTag, mBlockNativeResponder);
mNativeViewHierarchyManager.setJSResponder(mTag, mInitialTag, mBlockNativeResponder);
} else {
mNativeViewHierarchyManager.clearJSResponder();
}
@ -450,14 +453,21 @@ public class UIViewOperationQueue {
mOperations.add(new RemoveRootViewOperation(rootViewTag));
}
public void enqueueSetJSResponder(int reactTag, boolean blockNativeResponder) {
public void enqueueSetJSResponder(
int tag,
int initialTag,
boolean blockNativeResponder) {
mOperations.add(
new ChangeJSResponderOperation(reactTag, false /*clearResponder*/, blockNativeResponder));
new ChangeJSResponderOperation(
tag,
initialTag,
false /*clearResponder*/,
blockNativeResponder));
}
public void enqueueClearJSResponder() {
// Tag is 0 because JSResponderHandler doesn't need one in order to clear the responder.
mOperations.add(new ChangeJSResponderOperation(0, true /*clearResponder*/, false));
mOperations.add(new ChangeJSResponderOperation(0, 0, true /*clearResponder*/, false));
}
public void enqueueDispatchCommand(