<commit_before>'use strict';

import * as React from 'react';
import * as Rx from 'rx';
import * as wx from 'webrx';

import logManager from '../Common/App/Logging';
import { IBaseViewModel } from './BaseViewModel';

export interface IBaseViewProps {
  children?: React.ReactNode;
  key?: React.Key;
  viewModel: IBaseViewModel;
}

export interface IBaseHTMLDivViewProps extends IBaseViewProps, React.HTMLProps<HTMLDivElement> {
}

export abstract class BaseView<TViewProps extends IBaseViewProps, TViewModel extends IBaseViewModel> extends React.Component<TViewProps, TViewModel> {
  public static displayName = 'BaseView';

  private updateSubscription: Rx.IDisposable;

  protected logger = logManager.getLogger(this.getDisplayName());

  constructor(props?: TViewProps, context?: any) {
    super(props, context);

    this.state = props.viewModel as TViewModel;
  }

  protected updateOn(): Rx.Observable<any>[] { return []; }

  protected getDisplayName() { return Object.getName(this); }
  protected getRateLimit() { return 100; }

  protected renderView() { this.forceUpdate(); }

  protected initialize() {}
  protected cleanup() {}

  public bindObservable<TResult>(commandSelector: (viewModel: TViewModel) => wx.ICommand<TResult>, observable: Rx.Observable<TResult>) {
    return this.state.bind(observable, commandSelector(this.state));
  }

  public bindCallback<TEvent, TParameter>(
    targetSelector: (viewModel: TViewModel) => wx.IObservableProperty<TParameter>,
    paramSelector: (event: TEvent, ...args: any[]) => TParameter): (event: TEvent) => void {
    return (event: TEvent, ...args: any[]) => targetSelector(this.state)(paramSelector(event, args));
  }

  public bindEvent<TEvent, TParameter>(
    commandSelector: (viewModel: TViewModel) => wx.ICommand<any>,
    eventArgsSelector?: (e: TEvent, args: any[]) => TParameter,
    conditionSelector?: (e: TEvent, x: TParameter) => boolean): (event: TEvent) => void {
    return (e: TEvent, ...args: any[]) => {
      let parameter = eventArgsSelector ? eventArgsSelector(e, args) : null;
      if (conditionSelector == null || conditionSelector(e, parameter) === true) {
        let cmd = commandSelector(this.state);
        if (cmd.canExecute(parameter)) {
          cmd.execute(parameter);
        }
      }
    };
  }

  private logRender(initial: boolean) {
    this.logger.debug(`${initial ? '' : 're-'}rendering`);
  }

  private subscribeToUpdates() {
    let updateProps = this.updateOn();
    updateProps.push(this.state.stateChanged.results);

    this.updateSubscription = Rx.Observable
      .fromArray(updateProps)
      .selectMany(x => x)
      .debounce(this.getRateLimit())
      .subscribe(x => {
        this.renderView();<commit_msg>adding jsdocs to bind helpers to improve intellisense<commit_after>'use strict';

import * as React from 'react';
import * as Rx from 'rx';
import * as wx from 'webrx';

import logManager from '../Common/App/Logging';
import { IBaseViewModel } from './BaseViewModel';

export interface IBaseViewProps {
  children?: React.ReactNode;
  key?: React.Key;
  viewModel: IBaseViewModel;
}

export interface IBaseHTMLDivViewProps extends IBaseViewProps, React.HTMLProps<HTMLDivElement> {
}

export abstract class BaseView<TViewProps extends IBaseViewProps, TViewModel extends IBaseViewModel> extends React.Component<TViewProps, TViewModel> {
  public static displayName = 'BaseView';

  private updateSubscription: Rx.IDisposable;

  protected logger = logManager.getLogger(this.getDisplayName());

  constructor(props?: TViewProps, context?: any) {
    super(props, context);

    this.state = props.viewModel as TViewModel;
  }

  protected updateOn(): Rx.Observable<any>[] { return []; }

  protected getDisplayName() { return Object.getName(this); }
  protected getRateLimit() { return 100; }

  protected renderView() { this.forceUpdate(); }

  protected initialize() {}
  protected cleanup() {}

  /**
   * Binds an observable to a command on the view model
   */
  public bindObservable<TResult>(commandSelector: (viewModel: TViewModel) => wx.ICommand<TResult>, observable: Rx.Observable<TResult>) {
    return this.state.bind(observable, commandSelector(this.state));
  }

  /**
   * Binds a DOM event to an observable property on the view model
   */
  public bindCallback<TEvent, TParameter>(
    targetSelector: (viewModel: TViewModel) => wx.IObservableProperty<TParameter>,
    paramSelector: (event: TEvent, ...args: any[]) => TParameter): (event: TEvent) => void {
    return (event: TEvent, ...args: any[]) => targetSelector(this.state)(paramSelector(event, args));
  }

  /**
   * Binds a DOM event to an observable command on the view model
   */
  public bindEvent<TEvent, TParameter>(
    commandSelector: (viewModel: TViewModel) => wx.ICommand<any>,
    eventArgsSelector?: (e: TEvent, args: any[]) => TParameter,
    conditionSelector?: (e: TEvent, x: TParameter) => boolean): (event: TEvent) => void {
    return (e: TEvent, ...args: any[]) => {
      let parameter = eventArgsSelector ? eventArgsSelector(e, args) : null;
      if (conditionSelector == null || conditionSelector(e, parameter) === true) {
        let cmd = commandSelector(this.state);
        if (cmd.canExecute(parameter)) {
          cmd.execute(parameter);
        }
      }
    };
  }

  private logRender(initial: boolean) {
    this.logger.debug(`${initial ? '' : 're-'}rendering`);
  }

  private subscribeToUpdates() {
    let updateProps = this.updateOn();
    updateProps.push(this.state.stateChanged.results);

    this.updateSubscription = Rx.Observable
      .fromArray(updateProps)
      .selectMany(x => x)
      .debounce(this.getRateLimit())
      .subscribe(x => {
        this.renderView();
{'fraction_non_alphanumeric': 0.13533834586466165, 'fraction_numerical': 0.0010491344640671447, 'mean_word_length': 4.130044843049327, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3377738', 'n_tokens_mistral': 1725, 'n_tokens_neox': 1663, 'n_words': 416}