<commit_before>var React = require('react');
var ReactDOM = require('react-dom');

var Renderer = require("./renderer.jsx");
var QuestionParagraph = require("./question-paragraph.jsx");
var WidgetContainer = require("./widget-container.jsx");
var Widgets = require("./widgets.js");

var Util = require("./util.js");
var EnabledFeatures = require("./enabled-features.jsx");
var ApiOptions = require("./perseus-api.jsx").Options;

var SINGLE_ITEM_WIDGET_ID = "answer-area";
var PT = React.PropTypes;

var AnswerAreaRenderer = React.createClass({
    propTypes: {
        type: PT.string,
        options: PT.object,
        calculator: PT.bool,
        problemNum: PT.number,
        onInteractWithWidget: PT.func.isRequired,
        enabledFeatures: EnabledFeatures.propTypes,
        highlightedWidgets: PT.array.isRequired,
        apiOptions: ApiOptions.propTypes
    },

    getInitialState: function() {
        // TODO(alpert): Move up to parent props?
        return {
            widget: {},
            cls: this.getClass(this.props.type)
        };
    },

    componentWillReceiveProps: function(nextProps) {
        this.setState({cls: this.getClass(nextProps.type)});
    },

    getClass: function(type) {
        if (type === "multiple") {
            return Renderer;
        } else {
            return Widgets.getWidget(type, this.props.enabledFeatures);
        }
    },

    render: function() {
        if (this.props.type === "multiple") {
            return this.renderMultiple();
        } else {
            return this.renderSingle();
        }
    },

    emptyWidgets: function() {
        if (this.props.type === "multiple") {
            return this.refs.widget.emptyWidgets();
        } else {
            return Util.scoreIsEmpty(
                this.refs.widget.simpleValidate(this.props.options)) ?
                [SINGLE_ITEM_WIDGET_ID] : [];
        }
    },

    // Gets a focus object fixed up with an "answer-" prefix for
    // onFocusChange when type === "multiple"
    _getAnswerAreaFocusObj: function(rendererFocusObj) {
        if (rendererFocusObj.path == null) {
            return rendererFocusObj;
        }
        // TODO(jack): make "answer" the first element of the prefix
        // array, rather than modifying the widgetId, once we have
        // expunged widgetIds from the rest of the api calls in
        // favor of focus paths
        var answerPath = ["answer-" + rendererFocusObj.path[0]];
        answerPath = answerPath.concat(_.rest(rendererFocusObj.path));
        return {
            path: answerPath,
            element: rendererFocusObj.element
        };
    },

    renderMultiple: function() {
        var parentInterceptInputFocus =
                this.props.apiOptions.interceptInputFocus;
        var parentOnFocusChange = this.props.apiOptions.onFocusChange;

        var apiOptions = _.extend(
            {},
            ApiOptions.defaults,
            this.props.apiOptions,
            parentInterceptInputFocus && {
                // Rewrite widgetIds sent to interceptInputFocus on the way
                // up to include an "answer-" prefix
                interceptInputFocus: (widgetId) => {
                    var args = _.toArray(arguments);
                    var fullWidgetId = "answer-" + widgetId;
                    args[0] = fullWidgetId;
                    return parentInterceptInputFocus.apply(null, args);
                }
            },
            parentOnFocusChange && {
                onFocusChange: (newFocus, oldFocus) => {
                    // If we have an apiOptions.onFocusChange, call
                    // it with an "answer-" prefix on our widget id
                    parentOnFocusChange(
                        this._getAnswerAreaFocusObj(newFocus),
                        this._getAnswerAreaFocusObj(oldFocus)
                    );
                }
            }
        );

        return <this.state.cls
            ref="widget"
            problemNum={this.props.problemNum}
            onChange={this.handleChangeRenderer}
            onInteractWithWidget={this.props.onInteractWithWidget}
            highlightedWidgets={this.props.highlightedWidgets}
            enabledFeatures={{...this.props.enabledFeatures,
                // Hide answer area tooltip formats,
                // the "Acceptable formats" box already works
                toolTipFormats: false
            }}
            apiOptions={apiOptions}
            {...this.props.options}
            {...this.state.widget}
        />
    },

    renderSingle: function() {
        var shouldHighlight = _.contains(this.props.highlightedWidgets,
                                    SINGLE_ITEM_WIDGET_ID);
        return <QuestionParagraph>
            <WidgetContainer
                ref="container"
                key={this.props.type}
                type={this.state.cls}
                initialProps={this.getSingleWidgetProps()}
                shouldHighlight={shouldHighlight} />
        </QuestionParagraph>;
    },

    getSingleWidgetProps: function() {
        var editorProps = this.props.options;
        var transform = Widgets.getTransform(this.props.type);
        var apiOptions = _.extend(<commit_msg>fix ref name<commit_after>var React = require('react');
var ReactDOM = require('react-dom');

var Renderer = require("./renderer.jsx");
var QuestionParagraph = require("./question-paragraph.jsx");
var WidgetContainer = require("./widget-container.jsx");
var Widgets = require("./widgets.js");

var Util = require("./util.js");
var EnabledFeatures = require("./enabled-features.jsx");
var ApiOptions = require("./perseus-api.jsx").Options;

var SINGLE_ITEM_WIDGET_ID = "answer-area";
var PT = React.PropTypes;

var AnswerAreaRenderer = React.createClass({
    propTypes: {
        type: PT.string,
        options: PT.object,
        calculator: PT.bool,
        problemNum: PT.number,
        onInteractWithWidget: PT.func.isRequired,
        enabledFeatures: EnabledFeatures.propTypes,
        highlightedWidgets: PT.array.isRequired,
        apiOptions: ApiOptions.propTypes
    },

    getInitialState: function() {
        // TODO(alpert): Move up to parent props?
        return {
            widget: {},
            cls: this.getClass(this.props.type)
        };
    },

    componentWillReceiveProps: function(nextProps) {
        this.setState({cls: this.getClass(nextProps.type)});
    },

    getClass: function(type) {
        if (type === "multiple") {
            return Renderer;
        } else {
            return Widgets.getWidget(type, this.props.enabledFeatures);
        }
    },

    render: function() {
        if (this.props.type === "multiple") {
            return this.renderMultiple();
        } else {
            return this.renderSingle();
        }
    },

    emptyWidgets: function() {
        if (this.props.type === "multiple") {
            return this.refs.widget.emptyWidgets();
        } else {
            return Util.scoreIsEmpty(
                this.refs.widget.simpleValidate(this.props.options)) ?
                [SINGLE_ITEM_WIDGET_ID] : [];
        }
    },

    // Gets a focus object fixed up with an "answer-" prefix for
    // onFocusChange when type === "multiple"
    _getAnswerAreaFocusObj: function(rendererFocusObj) {
        if (rendererFocusObj.path == null) {
            return rendererFocusObj;
        }
        // TODO(jack): make "answer" the first element of the prefix
        // array, rather than modifying the widgetId, once we have
        // expunged widgetIds from the rest of the api calls in
        // favor of focus paths
        var answerPath = ["answer-" + rendererFocusObj.path[0]];
        answerPath = answerPath.concat(_.rest(rendererFocusObj.path));
        return {
            path: answerPath,
            element: rendererFocusObj.element
        };
    },

    renderMultiple: function() {
        var parentInterceptInputFocus =
                this.props.apiOptions.interceptInputFocus;
        var parentOnFocusChange = this.props.apiOptions.onFocusChange;

        var apiOptions = _.extend(
            {},
            ApiOptions.defaults,
            this.props.apiOptions,
            parentInterceptInputFocus && {
                // Rewrite widgetIds sent to interceptInputFocus on the way
                // up to include an "answer-" prefix
                interceptInputFocus: (widgetId) => {
                    var args = _.toArray(arguments);
                    var fullWidgetId = "answer-" + widgetId;
                    args[0] = fullWidgetId;
                    return parentInterceptInputFocus.apply(null, args);
                }
            },
            parentOnFocusChange && {
                onFocusChange: (newFocus, oldFocus) => {
                    // If we have an apiOptions.onFocusChange, call
                    // it with an "answer-" prefix on our widget id
                    parentOnFocusChange(
                        this._getAnswerAreaFocusObj(newFocus),
                        this._getAnswerAreaFocusObj(oldFocus)
                    );
                }
            }
        );

        return <this.state.cls
            ref="widget"
            problemNum={this.props.problemNum}
            onChange={this.handleChangeRenderer}
            onInteractWithWidget={this.props.onInteractWithWidget}
            highlightedWidgets={this.props.highlightedWidgets}
            enabledFeatures={{...this.props.enabledFeatures,
                // Hide answer area tooltip formats,
                // the "Acceptable formats" box already works
                toolTipFormats: false
            }}
            apiOptions={apiOptions}
            {...this.props.options}
            {...this.state.widget}
        />
    },

    renderSingle: function() {
        var shouldHighlight = _.contains(this.props.highlightedWidgets,
                                    SINGLE_ITEM_WIDGET_ID);
        return <QuestionParagraph>
            <WidgetContainer
                ref="widget"
                key={this.props.type}
                type={this.state.cls}
                initialProps={this.getSingleWidgetProps()}
                shouldHighlight={shouldHighlight} />
        </QuestionParagraph>;
    },

    getSingleWidgetProps: function() {
        var editorProps = this.props.options;
        var transform = Widgets.getTransform(this.props.type);
        var apiOptions = _.extend(
{'fraction_non_alphanumeric': 0.10602870813397129, 'fraction_numerical': 0.0003827751196172249, 'mean_word_length': 1.8268866648634028, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 15, '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': '1335060', 'n_tokens_mistral': 2759, 'n_tokens_neox': 2675, 'n_words': 563}