mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49f47cd7bd | ||
|
|
94cbf206d6 | ||
|
|
6bfc1187a8 | ||
|
|
29704b1f02 |
@@ -10,6 +10,8 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
// This is a test change. @nocommit
|
||||
|
||||
const passthroughSyntaxPlugins = require('../passthrough-syntax-plugins');
|
||||
const lazyImports = require('./lazy-imports');
|
||||
|
||||
|
||||
@@ -3315,6 +3315,7 @@ public abstract class com/facebook/react/uimanager/BaseViewManager : com/faceboo
|
||||
public fun getExportedCustomBubblingEventTypeConstants ()Ljava/util/Map;
|
||||
public fun getExportedCustomDirectEventTypeConstants ()Ljava/util/Map;
|
||||
protected fun onAfterUpdateTransaction (Landroid/view/View;)V
|
||||
public fun onDropViewInstance (Landroid/view/View;)V
|
||||
public fun onLayoutChange (Landroid/view/View;IIIIIIII)V
|
||||
protected fun prepareToRecycleView (Lcom/facebook/react/uimanager/ThemedReactContext;Landroid/view/View;)Landroid/view/View;
|
||||
public fun setAccessibilityActions (Landroid/view/View;Lcom/facebook/react/bridge/ReadableArray;)V
|
||||
|
||||
+58
-24
@@ -173,30 +173,19 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
|
||||
protected void addEventEmitters(@NonNull ThemedReactContext reactContext, @NonNull T view) {
|
||||
super.addEventEmitters(reactContext, view);
|
||||
|
||||
@Nullable OnFocusChangeListener originalFocusChangeListener = view.getOnFocusChangeListener();
|
||||
view.setOnFocusChangeListener(
|
||||
(v, hasFocus) -> {
|
||||
if (originalFocusChangeListener != null) {
|
||||
originalFocusChangeListener.onFocusChange(v, hasFocus);
|
||||
}
|
||||
int surfaceId = UIManagerHelper.getSurfaceId(v.getContext());
|
||||
if (surfaceId == View.NO_ID) {
|
||||
return;
|
||||
}
|
||||
if (view.getContext() instanceof ThemedReactContext) {
|
||||
ThemedReactContext themedReactContext = (ThemedReactContext) v.getContext();
|
||||
@Nullable
|
||||
EventDispatcher eventDispatcher =
|
||||
UIManagerHelper.getEventDispatcherForReactTag(themedReactContext, view.getId());
|
||||
if (eventDispatcher != null) {
|
||||
if (hasFocus) {
|
||||
eventDispatcher.dispatchEvent(new FocusEvent(surfaceId, view.getId()));
|
||||
} else {
|
||||
eventDispatcher.dispatchEvent(new BlurEvent(surfaceId, view.getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
BaseVMFocusChangeListener focusChangeListener =
|
||||
new BaseVMFocusChangeListener(view.getOnFocusChangeListener());
|
||||
focusChangeListener.attach(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDropViewInstance(@NonNull T view) {
|
||||
super.onDropViewInstance(view);
|
||||
|
||||
@Nullable OnFocusChangeListener focusChangeListener = view.getOnFocusChangeListener();
|
||||
if (focusChangeListener instanceof BaseVMFocusChangeListener) {
|
||||
((BaseVMFocusChangeListener) focusChangeListener).detach(view);
|
||||
}
|
||||
}
|
||||
|
||||
// Currently, layout listener is only attached when transform or transformOrigin is set.
|
||||
@@ -1052,4 +1041,49 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
|
||||
}
|
||||
|
||||
// Please add new props to BaseViewManagerDelegate as well!
|
||||
|
||||
/**
|
||||
* A helper class to keep track of the original focus change listener if one is set. This is
|
||||
* especially helpful for views that are recycled so we can retain and restore the original
|
||||
* listener upon recycling (onDropViewInstance).
|
||||
*/
|
||||
private class BaseVMFocusChangeListener<V extends View> implements OnFocusChangeListener {
|
||||
private @Nullable OnFocusChangeListener mOriginalFocusChangeListener;
|
||||
|
||||
public BaseVMFocusChangeListener(@Nullable OnFocusChangeListener originalFocusChangeListener) {
|
||||
mOriginalFocusChangeListener = originalFocusChangeListener;
|
||||
}
|
||||
|
||||
public void attach(T view) {
|
||||
view.setOnFocusChangeListener(this);
|
||||
}
|
||||
|
||||
public void detach(T view) {
|
||||
view.setOnFocusChangeListener(mOriginalFocusChangeListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFocusChange(View view, boolean hasFocus) {
|
||||
if (mOriginalFocusChangeListener != null) {
|
||||
mOriginalFocusChangeListener.onFocusChange(view, hasFocus);
|
||||
}
|
||||
int surfaceId = UIManagerHelper.getSurfaceId(view.getContext());
|
||||
if (surfaceId == View.NO_ID) {
|
||||
return;
|
||||
}
|
||||
if (view.getContext() instanceof ThemedReactContext) {
|
||||
ThemedReactContext themedReactContext = (ThemedReactContext) view.getContext();
|
||||
@Nullable
|
||||
EventDispatcher eventDispatcher =
|
||||
UIManagerHelper.getEventDispatcherForReactTag(themedReactContext, view.getId());
|
||||
if (eventDispatcher != null) {
|
||||
if (hasFocus) {
|
||||
eventDispatcher.dispatchEvent(new FocusEvent(surfaceId, view.getId()));
|
||||
} else {
|
||||
eventDispatcher.dispatchEvent(new BlurEvent(surfaceId, view.getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+17
@@ -93,4 +93,21 @@ class BaseViewManagerTest {
|
||||
view.onFocusChangeListener.onFocusChange(view, true)
|
||||
verify(originalFocusListener, times(1)).onFocusChange(view, true)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDroppingViewInstanceRestoresFocusChangeListener() {
|
||||
val originalFocusListener = mock<OnFocusChangeListener>()
|
||||
view.onFocusChangeListener = originalFocusListener
|
||||
viewManager.addEventEmitters(themedReactContext, view)
|
||||
Assertions.assertThat(view.onFocusChangeListener).isNotEqualTo(originalFocusListener)
|
||||
|
||||
view.onFocusChangeListener.onFocusChange(view, true)
|
||||
verify(originalFocusListener, times(1)).onFocusChange(view, true)
|
||||
Assertions.assertThat(originalFocusListener).isNotEqualTo(view.onFocusChangeListener)
|
||||
|
||||
viewManager.onDropViewInstance(view)
|
||||
view.onFocusChangeListener.onFocusChange(view, true)
|
||||
verify(originalFocusListener, times(2)).onFocusChange(view, true)
|
||||
Assertions.assertThat(originalFocusListener).isEqualTo(view.onFocusChangeListener)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,10 +35,12 @@ function formatFantomHermesVariant(hermesVariant: HermesVariant): string {
|
||||
switch (hermesVariant) {
|
||||
case FantomTestConfigHermesVariant.Hermes:
|
||||
return 'hermes';
|
||||
case FantomTestConfigHermesVariant.StaticHermes:
|
||||
return 'hermes 🆕';
|
||||
case FantomTestConfigHermesVariant.StaticHermesStable:
|
||||
return 'shermes 🆕';
|
||||
case FantomTestConfigHermesVariant.StaticHermesStaging:
|
||||
return 'shermes ⏭️';
|
||||
case FantomTestConfigHermesVariant.StaticHermesExperimental:
|
||||
return 'hermes 🧪';
|
||||
return 'shermes 🧪';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-6
@@ -90,7 +90,7 @@ const MAX_FANTOM_CONFIGURATION_VARIATIONS = 12;
|
||||
* /**
|
||||
* * @flow strict-local
|
||||
* * @fantom_mode opt
|
||||
* * @fantom_hermes_variant static_hermes
|
||||
* * @fantom_hermes_variant static_hermes_stable
|
||||
* * @fantom_flags commonTestFlag:true
|
||||
* * @fantom_flags jsOnlyTestFlag:true
|
||||
* * @fantom_react_fb_flags reactInternalFlag:true
|
||||
@@ -101,8 +101,8 @@ const MAX_FANTOM_CONFIGURATION_VARIATIONS = 12;
|
||||
* - `fantom_mode`: specifies the level of optimization to compile the test
|
||||
* with. Valid values are `dev`, `dev-bytecode` and `opt`.
|
||||
* - `fantom_hermes_variant`: specifies the Hermes variant to use to run the
|
||||
* test. Valid values are `hermes`, `static_hermes` and
|
||||
* `static_hermes_experimental`.
|
||||
* test. Valid values are `hermes`, `static_hermes_stable`,
|
||||
* `static_hermes_staging` and `static_hermes_experimental`.
|
||||
* - `fantom_flags`: specifies the configuration for common and JS-only feature
|
||||
* flags. They can be specified in the same pragma or in different ones, and
|
||||
* the format is `<flag_name>:<value>`.
|
||||
@@ -187,8 +187,11 @@ export default function getFantomTestConfigs(
|
||||
case 'hermes':
|
||||
config.hermesVariant = HermesVariant.Hermes;
|
||||
break;
|
||||
case 'static_hermes':
|
||||
config.hermesVariant = HermesVariant.StaticHermes;
|
||||
case 'static_hermes_stable':
|
||||
config.hermesVariant = HermesVariant.StaticHermesStable;
|
||||
break;
|
||||
case 'static_hermes_staging':
|
||||
config.hermesVariant = HermesVariant.StaticHermesStaging;
|
||||
break;
|
||||
case 'static_hermes_experimental':
|
||||
config.hermesVariant = HermesVariant.StaticHermesExperimental;
|
||||
@@ -196,7 +199,8 @@ export default function getFantomTestConfigs(
|
||||
case '*':
|
||||
configVariations.push([
|
||||
{hermesVariant: HermesVariant.Hermes},
|
||||
{hermesVariant: HermesVariant.StaticHermes},
|
||||
{hermesVariant: HermesVariant.StaticHermesStable},
|
||||
{hermesVariant: HermesVariant.StaticHermesStaging},
|
||||
{hermesVariant: HermesVariant.StaticHermesExperimental},
|
||||
]);
|
||||
break;
|
||||
|
||||
+8
-3
@@ -20,7 +20,8 @@ const BUCK_ISOLATION_DIR = 'react-native-fantom-buck-out';
|
||||
|
||||
export enum HermesVariant {
|
||||
Hermes,
|
||||
StaticHermes, // Static Hermes Stable
|
||||
StaticHermesStable, // Static Hermes Stable
|
||||
StaticHermesStaging, // Static Hermes Staging
|
||||
StaticHermesExperimental, // Static Hermes Trunk
|
||||
}
|
||||
|
||||
@@ -30,8 +31,10 @@ export function getBuckOptionsForHermes(
|
||||
switch (variant) {
|
||||
case HermesVariant.Hermes:
|
||||
return [];
|
||||
case HermesVariant.StaticHermes:
|
||||
case HermesVariant.StaticHermesStable:
|
||||
return ['-c hermes.static_hermes=stable'];
|
||||
case HermesVariant.StaticHermesStaging:
|
||||
return ['-c hermes.static_hermes=staging'];
|
||||
case HermesVariant.StaticHermesExperimental:
|
||||
return ['-c hermes.static_hermes=trunk'];
|
||||
}
|
||||
@@ -41,8 +44,10 @@ export function getHermesCompilerTarget(variant: HermesVariant): string {
|
||||
switch (variant) {
|
||||
case HermesVariant.Hermes:
|
||||
return '//xplat/hermes/tools/hermesc:hermesc';
|
||||
case HermesVariant.StaticHermes:
|
||||
case HermesVariant.StaticHermesStable:
|
||||
return '//xplat/shermes/stable:hermesc';
|
||||
case HermesVariant.StaticHermesStaging:
|
||||
return '//xplat/shermes/staging:hermesc';
|
||||
case HermesVariant.StaticHermesExperimental:
|
||||
return '//xplat/static_h:hermesc';
|
||||
}
|
||||
|
||||
+3
-11
@@ -172,20 +172,12 @@ export function suite(
|
||||
|
||||
function printBenchmarkResults(bench: Bench) {
|
||||
const {fantomConfigSummary} = getConstants();
|
||||
const longestTaskNameLength = bench.tasks.reduce(
|
||||
(maxLength, task) => Math.max(maxLength, task.name.length),
|
||||
0,
|
||||
);
|
||||
const separatorWidth = 137 + longestTaskNameLength - 'Task name'.length;
|
||||
const benchmarkName =
|
||||
(bench.name ?? 'Benchmark') +
|
||||
(fantomConfigSummary ? ` (${fantomConfigSummary})` : '');
|
||||
|
||||
console.log('-'.repeat(separatorWidth));
|
||||
console.log(
|
||||
`| ${benchmarkName}${' '.repeat(separatorWidth - (4 + benchmarkName.length))} |`,
|
||||
);
|
||||
console.log('-'.repeat(separatorWidth));
|
||||
console.log('');
|
||||
console.log(`### ${benchmarkName} ###`);
|
||||
console.table(nullthrows(bench.table()));
|
||||
console.log('-'.repeat(separatorWidth) + '\n');
|
||||
console.log('');
|
||||
}
|
||||
|
||||
+2
-2
@@ -6,12 +6,12 @@
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
* @fantom_hermes_variant static_hermes
|
||||
* @fantom_hermes_variant static_hermes_stable
|
||||
*/
|
||||
|
||||
declare var HermesInternal: $HermesInternalType;
|
||||
|
||||
describe('"@fantom_hermes_variant static_hermes" in docblock', () => {
|
||||
describe('"@fantom_hermes_variant static_hermes_stable" in docblock', () => {
|
||||
it('should use Static Hermes', () => {
|
||||
expect(HermesInternal.getRuntimeProperties?.()['Static Hermes']).toBe(true);
|
||||
});
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
* @fantom_hermes_variant static_hermes_staging
|
||||
*/
|
||||
|
||||
declare var HermesInternal: $HermesInternalType;
|
||||
|
||||
describe('"@fantom_hermes_variant static_hermes_staging" in docblock', () => {
|
||||
it('should use Static Hermes', () => {
|
||||
expect(HermesInternal.getRuntimeProperties?.()['Static Hermes']).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user