<commit_before>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 * @format
 */

'use strict';

const View = require('../../Components/View/View');
const Platform = require('../../Utilities/Platform');
const {AnimatedEvent} = require('./AnimatedEvent');
const AnimatedProps = require('./nodes/AnimatedProps');
const React = require('react');
const NativeAnimatedHelper = require('./NativeAnimatedHelper');

const invariant = require('invariant');
const setAndForwardRef = require('../../Utilities/setAndForwardRef');

let animatedComponentNextId = 1;

export type AnimatedComponentType<
  Props: {+[string]: mixed, ...},
  Instance,
> = React.AbstractComponent<
  $ObjMap<
    Props &
      $ReadOnly<{
        passthroughAnimatedPropExplicitValues?: React.ElementConfig<
          typeof View,
        >,
      }>,
    () => any,
  >,
  Instance,
>;

function createAnimatedComponent<Props: {+[string]: mixed, ...}, Instance>(
  Component: React.AbstractComponent<Props, Instance>,
): AnimatedComponentType<Props, Instance> {
  invariant(
    typeof Component !== 'function' ||
      (Component.prototype && Component.prototype.isReactComponent),
    '`createAnimatedComponent` does not support stateless functional components; ' +
      'use a class component instead.',
  );

  class AnimatedComponent extends React.Component<Object> {
    _component: any; // TODO T53738161: flow type this, and the whole file
    _invokeAnimatedPropsCallbackOnMount: boolean = false;
    _prevComponent: any;
    _propsAnimated: AnimatedProps;
    _eventDetachers: Array<Function> = [];

    // Only to be used in this file, and only in Fabric.
    _animatedComponentId: number = -1;

    _attachNativeEvents() {
      // Make sure to get the scrollable node for components that implement
      // `ScrollResponder.Mixin`.
      const scrollableNode = this._component?.getScrollableNode
        ? this._component.getScrollableNode()
        : this._component;

      for (const key in this.props) {
        const prop = this.props[key];
        if (prop instanceof AnimatedEvent && prop.__isNative) {
          prop.__attach(scrollableNode, key);
          this._eventDetachers.push(() => prop.__detach(scrollableNode, key));
        }
      }
    }

    _detachNativeEvents() {
      this._eventDetachers.forEach(remove => remove());
      this._eventDetachers = [];
    }

    _isFabric = (): boolean => {
      if (this._component == null) {
        return false;
      }
      return (
        // eslint-disable-next-line dot-notation
        this._component['_internalInstanceHandle']?.stateNode?.canonical !=
          null ||
        // Some components have a setNativeProps function but aren't a host component
        // such as lists like FlatList and SectionList. These should also use
        // forceUpdate in Fabric since setNativeProps doesn't exist on the underlying
        // host component. This crazy hack is essentially special casing those lists and
        // ScrollView itself to use forceUpdate in Fabric.
        // If these components end up using forwardRef then these hacks can go away
        // as this._component would actually be the underlying host component and the above check
        // would be sufficient.
        (this._component.getNativeScrollRef != null &&
          this._component.getNativeScrollRef() != null &&
          // eslint-disable-next-line dot-notation
          this._component.getNativeScrollRef()['_internalInstanceHandle']
            ?.stateNode?.canonical != null) ||
        (this._component.getScrollResponder != null &&
          this._component.getScrollResponder() != null &&
          this._component.getScrollResponder().getNativeScrollRef != null &&
          this._component.getScrollResponder().getNativeScrollRef() != null &&
          this._component.getScrollResponder().getNativeScrollRef()[
            // eslint-disable-next-line dot-notation
            '_internalInstanceHandle'
          ]?.stateNode?.canonical != null)
      );
    };

    _waitForUpdate = (): void => {
      // If this works well on iOS, we should remove this check
      if (Platform.OS === 'android') {
        if (this._isFabric()) {
          if (this._animatedComponentId === -1) {
            this._animatedComponentId = animatedComponentNextId++;
          }
          NativeAnimatedHelper.API.setWaitingForIdentifier(
            this._animatedComponentId,
          );
        }
      }
    };

    _markUpdateComplete = (): void => {
      // If this works well on iOS, we should remove this check
      if (Platform.OS === 'android') {
        if (this._isFabric()) {
          NativeAnimatedHelper.API.unsetWaitingForIdentifier(
            this._animatedComponentId,
          );
        }
      }
    };

    // The system is best designed when setNativeProps is implemented. It is
    // able to avoid re-rendering and directly set the attributes that changed.
    // However, setNativeProps can only be implemented on leaf native<commit_msg>Animated: queue all NativeAnimated operations until mounting effects are finished on iOS<commit_after>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 * @format
 */

'use strict';

const View = require('../../Components/View/View');
const Platform = require('../../Utilities/Platform');
const {AnimatedEvent} = require('./AnimatedEvent');
const AnimatedProps = require('./nodes/AnimatedProps');
const React = require('react');
const NativeAnimatedHelper = require('./NativeAnimatedHelper');

const invariant = require('invariant');
const setAndForwardRef = require('../../Utilities/setAndForwardRef');

let animatedComponentNextId = 1;

export type AnimatedComponentType<
  Props: {+[string]: mixed, ...},
  Instance,
> = React.AbstractComponent<
  $ObjMap<
    Props &
      $ReadOnly<{
        passthroughAnimatedPropExplicitValues?: React.ElementConfig<
          typeof View,
        >,
      }>,
    () => any,
  >,
  Instance,
>;

function createAnimatedComponent<Props: {+[string]: mixed, ...}, Instance>(
  Component: React.AbstractComponent<Props, Instance>,
): AnimatedComponentType<Props, Instance> {
  invariant(
    typeof Component !== 'function' ||
      (Component.prototype && Component.prototype.isReactComponent),
    '`createAnimatedComponent` does not support stateless functional components; ' +
      'use a class component instead.',
  );

  class AnimatedComponent extends React.Component<Object> {
    _component: any; // TODO T53738161: flow type this, and the whole file
    _invokeAnimatedPropsCallbackOnMount: boolean = false;
    _prevComponent: any;
    _propsAnimated: AnimatedProps;
    _eventDetachers: Array<Function> = [];

    // Only to be used in this file, and only in Fabric.
    _animatedComponentId: number = -1;

    _attachNativeEvents() {
      // Make sure to get the scrollable node for components that implement
      // `ScrollResponder.Mixin`.
      const scrollableNode = this._component?.getScrollableNode
        ? this._component.getScrollableNode()
        : this._component;

      for (const key in this.props) {
        const prop = this.props[key];
        if (prop instanceof AnimatedEvent && prop.__isNative) {
          prop.__attach(scrollableNode, key);
          this._eventDetachers.push(() => prop.__detach(scrollableNode, key));
        }
      }
    }

    _detachNativeEvents() {
      this._eventDetachers.forEach(remove => remove());
      this._eventDetachers = [];
    }

    _isFabric = (): boolean => {
      if (this._component == null) {
        return false;
      }
      return (
        // eslint-disable-next-line dot-notation
        this._component['_internalInstanceHandle']?.stateNode?.canonical !=
          null ||
        // Some components have a setNativeProps function but aren't a host component
        // such as lists like FlatList and SectionList. These should also use
        // forceUpdate in Fabric since setNativeProps doesn't exist on the underlying
        // host component. This crazy hack is essentially special casing those lists and
        // ScrollView itself to use forceUpdate in Fabric.
        // If these components end up using forwardRef then these hacks can go away
        // as this._component would actually be the underlying host component and the above check
        // would be sufficient.
        (this._component.getNativeScrollRef != null &&
          this._component.getNativeScrollRef() != null &&
          // eslint-disable-next-line dot-notation
          this._component.getNativeScrollRef()['_internalInstanceHandle']
            ?.stateNode?.canonical != null) ||
        (this._component.getScrollResponder != null &&
          this._component.getScrollResponder() != null &&
          this._component.getScrollResponder().getNativeScrollRef != null &&
          this._component.getScrollResponder().getNativeScrollRef() != null &&
          this._component.getScrollResponder().getNativeScrollRef()[
            // eslint-disable-next-line dot-notation
            '_internalInstanceHandle'
          ]?.stateNode?.canonical != null)
      );
    };

    _waitForUpdate = (): void => {
      // If this works well on iOS, we should remove this check
      if (this._isFabric()) {
        if (this._animatedComponentId === -1) {
          this._animatedComponentId = animatedComponentNextId++;
        }
        NativeAnimatedHelper.API.setWaitingForIdentifier(
          this._animatedComponentId,
        );
      }
    };

    _markUpdateComplete = (): void => {
      // If this works well on iOS, we should remove this check
      if (this._isFabric()) {
        NativeAnimatedHelper.API.unsetWaitingForIdentifier(
          this._animatedComponentId,
        );
      }
    };

    // The system is best designed when setNativeProps is implemented. It is
    // able to avoid re-rendering and directly set the attributes that changed.
    // However, setNativeProps can only be implemented on leaf native
{'fraction_non_alphanumeric': 0.10944059357610075, 'fraction_numerical': 0.0021478082592990334, 'mean_word_length': 2.785661492978566, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3742239', 'n_tokens_mistral': 2699, 'n_tokens_neox': 2635, 'n_words': 754}