diff --git a/src/actions/creators.js b/src/actions/creators.js index bd58824..a64a0be 100644 --- a/src/actions/creators.js +++ b/src/actions/creators.js @@ -1,8 +1,9 @@ import * as types from './types.js'; -export const traceActivated = (trace) => { +export const traceActivated = (lang, trace) => { return { type: types.TRACE_ACTIVATED, + lang, trace, }; } diff --git a/src/components/structuredlang/StructuredExpWrapper.js b/src/components/structuredlang/StructuredExpWrapper.js index 942a543..28a2a96 100644 --- a/src/components/structuredlang/StructuredExpWrapper.js +++ b/src/components/structuredlang/StructuredExpWrapper.js @@ -3,16 +3,17 @@ import PropTypes from 'prop-types'; import StructuredExp from './recursive/StructuredExp.js'; -const StructuredExpWrapper = ({ lang, sExp }) => ( +const StructuredExpWrapper = ({ lang, sExp, createOnClick }) => (
         {lang}
- +
) StructuredExpWrapper.propTypes = { lang: PropTypes.string.isRequired, sExp: PropTypes.object.isRequired, + createOnClick: PropTypes.func.isRequired, }; export default StructuredExpWrapper; diff --git a/src/components/structuredlang/StructuredLangTrees.js b/src/components/structuredlang/StructuredLangTrees.js index 70b51f8..2252f28 100644 --- a/src/components/structuredlang/StructuredLangTrees.js +++ b/src/components/structuredlang/StructuredLangTrees.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import StructuredExpWrapper from './StructuredExpWrapper.js'; -const StructuredLangTrees = ({ trees }) => { +const StructuredLangTrees = ({ trees, createOnClick }) => { if (!trees) { return null; } @@ -13,6 +13,7 @@ const StructuredLangTrees = ({ trees }) => { key={tree.lang} lang={tree.lang} sExp={tree.prog} + createOnClick={createOnClick(tree.lang)} /> )); @@ -24,6 +25,7 @@ StructuredLangTrees.propTypes = { lang: PropTypes.string.isRequired, prog: PropTypes.object.isRequired, })), -} + createOnClick: PropTypes.func.isRequired, +}; export default StructuredLangTrees; diff --git a/src/components/structuredlang/recursive/Item.js b/src/components/structuredlang/recursive/Item.js index 2beb37c..d62ec7f 100644 --- a/src/components/structuredlang/recursive/Item.js +++ b/src/components/structuredlang/recursive/Item.js @@ -10,11 +10,11 @@ const shouldSurround = (item) => item.args && item.args.length > 0; // This function is intended to be used as the `callback` argument in a call to // `Array.prototype.map`, hence the index argument. -const renderAndMaybeSurround = (sExp, index) => { - const rendered = ; +const renderAndMaybeSurround = (props) => { + const rendered = ; let arr = []; - if (shouldSurround(sExp)) { + if (shouldSurround(props.sExp)) { arr = ['(', rendered, ')']; } else { arr = [rendered]; @@ -23,19 +23,27 @@ const renderAndMaybeSurround = (sExp, index) => { return arr; } -const Item = ({ name, args, trace }) => { - const nestedRenderedArgs = args.map(renderAndMaybeSurround); +const Item = ({ name, args, trace, createOnClick }) => { + const decorated = args.map((arg, index) => ({ + sExp: arg, + key: index, + createOnClick, + })); + const nestedRenderedArgs = decorated.map(renderAndMaybeSurround); const nestedNameAndArgs = [name].concat(nestedRenderedArgs); const nestedWithSpaces = intersperse(' ', nestedNameAndArgs); const withSpaces = _.flatten(nestedWithSpaces); - return {withSpaces}; + const onClick = createOnClick(trace); + + return {withSpaces}; } Item.propTypes = { name: PropTypes.string.isRequired, args: PropTypes.array.isRequired, trace: PropTypes.object, + createOnClick: PropTypes.func.isRequired, }; export default Item; diff --git a/src/components/structuredlang/recursive/List.js b/src/components/structuredlang/recursive/List.js index ef8d7ff..5439282 100644 --- a/src/components/structuredlang/recursive/List.js +++ b/src/components/structuredlang/recursive/List.js @@ -3,16 +3,18 @@ import PropTypes from 'prop-types'; import SurroundAndSeparate from './SurroundAndSeparate.js'; -const List = ({ elements }) => +const List = ({ elements, createOnClick }) => ; List.propTypes = { elements: PropTypes.array.isRequired, + createOnClick: PropTypes.func.isRequired, }; export default List; diff --git a/src/components/structuredlang/recursive/StructuredExp.js b/src/components/structuredlang/recursive/StructuredExp.js index 976e832..cbdf603 100644 --- a/src/components/structuredlang/recursive/StructuredExp.js +++ b/src/components/structuredlang/recursive/StructuredExp.js @@ -5,14 +5,14 @@ import Item from './Item.js'; import List from './List.js'; import Tuple from './Tuple.js'; -const StructuredExp = ({ sExp }) => { +const StructuredExp = ({ sExp, createOnClick }) => { let rendered; if (Array.isArray(sExp)) { - rendered = ; + rendered = ; } else if (sExp.isTuple) { - rendered = ; + rendered = ; } else { - rendered = ; + rendered = ; } return rendered; @@ -24,6 +24,7 @@ StructuredExp.propTypes = { PropTypes.object, PropTypes.array, ]).isRequired, + createOnClick: PropTypes.func.isRequired, }; export default StructuredExp; diff --git a/src/components/structuredlang/recursive/SurroundAndSeparate.js b/src/components/structuredlang/recursive/SurroundAndSeparate.js index 859ce0e..0ac5a5c 100644 --- a/src/components/structuredlang/recursive/SurroundAndSeparate.js +++ b/src/components/structuredlang/recursive/SurroundAndSeparate.js @@ -5,8 +5,14 @@ import { intersperse } from '../../../utils/ArrayUtils.js'; import StructuredExp from './StructuredExp.js'; -const SurroundAndSeparate = ({ left, right, separator, elements }) => { - const renderedElements = elements.map((element, index) => ); +const SurroundAndSeparate = ({ left, right, separator, elements, createOnClick }) => { + const renderedElements = elements.map((element, index) => ( + + )); const withSeparator = intersperse(separator, renderedElements); return {left}{withSeparator}{right}; } @@ -16,6 +22,7 @@ SurroundAndSeparate.propTypes = { right: PropTypes.string.isRequired, separator: PropTypes.string.isRequired, elements: PropTypes.array.isRequired, + createOnClick: PropTypes.func.isRequired, }; export default SurroundAndSeparate; diff --git a/src/components/structuredlang/recursive/Tuple.js b/src/components/structuredlang/recursive/Tuple.js index d869558..c0dc337 100644 --- a/src/components/structuredlang/recursive/Tuple.js +++ b/src/components/structuredlang/recursive/Tuple.js @@ -3,16 +3,18 @@ import PropTypes from 'prop-types'; import SurroundAndSeparate from './SurroundAndSeparate.js'; -const Tuple = ({ elements }) => +const Tuple = ({ elements, createOnClick }) => ; Tuple.propTypes = { elements: PropTypes.array.isRequired, + createOnClick: PropTypes.func.isRequired, }; export default Tuple; diff --git a/src/containers/LangTreesContainer.js b/src/containers/LangTreesContainer.js index 9f759ea..c13a832 100644 --- a/src/containers/LangTreesContainer.js +++ b/src/containers/LangTreesContainer.js @@ -1,12 +1,23 @@ import { connect } from 'react-redux'; +import { traceActivated, traceDeactivated } from '../actions/creators.js'; + import StructuredLangTrees from '../components/structuredlang/StructuredLangTrees.js'; const mapStateToProps = (state) => ({ trees: state.trees.trees, }) -const mapDispatchToProps = (dispatch) => ({}) +const mapDispatchToProps = (dispatch) => ({ + createOnClick: (lang) => (trace) => (event) => { + event.stopPropagation(); + if (trace) { + dispatch(traceActivated(lang, trace)); + } else { + dispatch(traceDeactivated()); + } + }, +}) const LangTreesContainer = connect( mapStateToProps, diff --git a/src/reducers/highlightedTrace.js b/src/reducers/highlightedTrace.js index e8c9150..f67ed18 100644 --- a/src/reducers/highlightedTrace.js +++ b/src/reducers/highlightedTrace.js @@ -3,7 +3,10 @@ import { TRACE_ACTIVATED, TRACE_DEACTIVATED } from '../actions/types.js'; const highlightedTrace = (state = null, action) => { switch (action.type) { case TRACE_ACTIVATED: - return action.trace; + return { + lang: action.lang, + trace: action.trace, + }; case TRACE_DEACTIVATED: return null; default: