From 59fbc3dced404ef6d8f11ff2bd94598c366c7ee8 Mon Sep 17 00:00:00 2001 From: Dave Bailey Date: Mon, 11 Sep 2017 11:08:08 -0700 Subject: [PATCH] Revert "React: Remove uses of React.createClass in publicKeyCryptography" --- apps/src/publicKeyCryptography/Alice.jsx | 51 ++++--- apps/src/publicKeyCryptography/Bob.jsx | 50 ++++--- .../publicKeyCryptography/EqualColumns.jsx | 18 ++- apps/src/publicKeyCryptography/Eve.jsx | 62 ++++---- .../publicKeyCryptography/IntegerDropdown.jsx | 16 +- .../publicKeyCryptography/IntegerTextbox.jsx | 13 +- .../src/publicKeyCryptography/ModuloClock.jsx | 27 ++-- .../ModuloClockWidget.jsx | 35 +++-- .../NumberedSteps.story.jsx | 141 ++++++++++-------- .../PublicKeyCryptographyWidget.jsx | 56 +++---- .../publicKeyCryptography/StartOverButton.jsx | 28 ++-- 11 files changed, 274 insertions(+), 223 deletions(-) diff --git a/apps/src/publicKeyCryptography/Alice.jsx b/apps/src/publicKeyCryptography/Alice.jsx index 180a6efec9d5a..a39e52f3697df 100644 --- a/apps/src/publicKeyCryptography/Alice.jsx +++ b/apps/src/publicKeyCryptography/Alice.jsx @@ -17,55 +17,59 @@ import { import {computePublicKey} from './cryptographyMath'; import {COLORS} from './style'; -export default class Alice extends React.Component { - static propTypes = { +const Alice = React.createClass({ + propTypes: { disabled: PropTypes.bool, setPublicModulus: PropTypes.func.isRequired, setPublicKey: PropTypes.func.isRequired, runModuloClock: PropTypes.func.isRequired - }; + }, - state = { - publicModulus: null, - privateKey: null, - publicNumber: null, - secretNumber: null - }; + getInitialState() { + return { + publicModulus: null, + privateKey: null, + publicNumber: null, + secretNumber: null + }; + }, - startOver = () => this.setState(this.getInitialState()); + startOver() { + this.setState(this.getInitialState()); + }, setPublicModulus(publicModulus) { this.setState({publicModulus}); this.setPrivateKey(null); this.clearSecretNumber(); - } + }, - onPublicModulusChange = (publicModulus) => { + onPublicModulusChange(publicModulus) { this.setPublicModulus(publicModulus); this.props.setPublicModulus(publicModulus); - }; + }, setPrivateKey(privateKey) { this.setState({privateKey}); this.clearSecretNumber(); - } + }, - onPrivateKeyChange = (privateKey) => { + onPrivateKeyChange(privateKey) { const {publicModulus} = this.state; this.setPrivateKey(privateKey); this.props.setPublicKey(this.getPublicKey({privateKey, publicModulus})); - }; + }, - setPublicNumber = (publicNumber) => { + setPublicNumber(publicNumber) { this.setState({publicNumber}); this.clearSecretNumber(); - }; + }, getPublicKey({privateKey, publicModulus}) { return privateKey && publicModulus ? computePublicKey(privateKey, publicModulus) : null; - } + }, - computeSecretNumber = () => { + computeSecretNumber() { const {runModuloClock} = this.props; const {publicModulus, privateKey, publicNumber} = this.state; if ([publicModulus, privateKey, publicNumber].every(Number.isInteger)) { @@ -79,11 +83,11 @@ export default class Alice extends React.Component { } else { this.clearSecretNumber(); } - }; + }, clearSecretNumber() { this.setState({secretNumber: null}); - } + }, render() { const {disabled} = this.props; @@ -156,4 +160,5 @@ export default class Alice extends React.Component { ); } -} +}); +export default Alice; diff --git a/apps/src/publicKeyCryptography/Bob.jsx b/apps/src/publicKeyCryptography/Bob.jsx index 5bf9f47bec7e5..4d3b6537c95ee 100644 --- a/apps/src/publicKeyCryptography/Bob.jsx +++ b/apps/src/publicKeyCryptography/Bob.jsx @@ -15,45 +15,49 @@ import { } from './cryptographyFields'; import {COLORS} from './style'; -export default class Bob extends React.Component { - static propTypes = { +const Bob = React.createClass({ + propTypes: { disabled: PropTypes.bool, setPublicModulus: PropTypes.func.isRequired, setPublicNumber: PropTypes.func.isRequired, runModuloClock: PropTypes.func.isRequired - }; + }, - state = { - publicModulus: null, - publicKey: null, - secretNumber: null, - publicNumber: null - }; + getInitialState() { + return { + publicModulus: null, + publicKey: null, + secretNumber: null, + publicNumber: null + }; + }, - startOver = () => this.setState(this.getInitialState()); + startOver() { + this.setState(this.getInitialState()); + }, setPublicModulus(publicModulus) { this.setState({publicModulus}); this.setSecretNumber(null); this.clearPublicNumber(); - } + }, - onPublicModulusChange = (publicModulus) => { + onPublicModulusChange(publicModulus) { this.setPublicModulus(publicModulus); this.props.setPublicModulus(publicModulus); - }; + }, - setPublicKey = (publicKey) => { + setPublicKey(publicKey) { this.setState({publicKey}); this.clearPublicNumber(); - }; + }, - setSecretNumber = (secretNumber) => { + setSecretNumber(secretNumber) { this.setState({secretNumber}); this.clearPublicNumber(); - }; + }, - computePublicNumber = () => { + computePublicNumber() { const {runModuloClock} = this.props; const {publicKey, secretNumber, publicModulus} = this.state; if ([publicKey, secretNumber, publicModulus].every(Number.isInteger)) { @@ -68,11 +72,11 @@ export default class Bob extends React.Component { } else { this.clearPublicNumber(); } - }; + }, clearPublicNumber() { this.setState({publicNumber: null}); - } + }, render() { const {disabled} = this.props; @@ -136,7 +140,7 @@ export default class Bob extends React.Component { - - ); + ); } -} +}); +export default Bob; diff --git a/apps/src/publicKeyCryptography/EqualColumns.jsx b/apps/src/publicKeyCryptography/EqualColumns.jsx index 7bbf20ad7b38c..f7f8471c333b3 100644 --- a/apps/src/publicKeyCryptography/EqualColumns.jsx +++ b/apps/src/publicKeyCryptography/EqualColumns.jsx @@ -3,14 +3,18 @@ import React, {PropTypes} from 'react'; import Radium from 'radium'; import {AnyChildren} from './types'; -export default Radium(class EqualColumns extends React.Component { - static propTypes = { +const EqualColumns = Radium(React.createClass({ + propTypes: { // Space between columns, in pixels intercolumnarDistance: PropTypes.number, children: AnyChildren - }; + }, - static defaultProps = {intercolumnarDistance: 0}; + getDefaultProps() { + return { + intercolumnarDistance: 0 + }; + }, render() { const {children, intercolumnarDistance} = this.props; @@ -34,7 +38,7 @@ export default Radium(class EqualColumns extends React.Component { ); })}
-
- ); + ); } -}); +})); +export default EqualColumns; diff --git a/apps/src/publicKeyCryptography/Eve.jsx b/apps/src/publicKeyCryptography/Eve.jsx index 97949be6f25e6..15ed0c699ff4e 100644 --- a/apps/src/publicKeyCryptography/Eve.jsx +++ b/apps/src/publicKeyCryptography/Eve.jsx @@ -26,41 +26,45 @@ const tdEquationStyleLHS = Object.assign({}, tdEquationStyleRHS, { whiteSpace: 'nowrap' }); -export default class Eve extends React.Component { - static propTypes = { +const Eve = React.createClass({ + propTypes: { disabled: PropTypes.bool, setPublicModulus: PropTypes.func.isRequired, runModuloClock: PropTypes.func.isRequired - }; + }, - state = { - publicModulus: null, - publicKey: null, - privateKey: null, - publicNumber: null, - secretNumber: null, - checkingPrivateKey: false, - privateKeyEquationResult: null, - checkingSecretNumber: false, - secretNumberEquationResult: null - }; + getInitialState() { + return { + publicModulus: null, + publicKey: null, + privateKey: null, + publicNumber: null, + secretNumber: null, + checkingPrivateKey: false, + privateKeyEquationResult: null, + checkingSecretNumber: false, + secretNumberEquationResult: null + }; + }, - startOver = () => this.setState(this.getInitialState()); + startOver() { + this.setState(this.getInitialState()); + }, setPublicModulus(publicModulus) { this.setState({publicModulus}); - } + }, - onPublicModulusChange = (publicModulus) => { + onPublicModulusChange(publicModulus) { this.setPublicModulus(publicModulus); this.props.setPublicModulus(publicModulus); - }; + }, - setPublicKey = (publicKey) => { + setPublicKey(publicKey) { this.setState({publicKey}); - }; + }, - setPrivateKey = (privateKey) => { + setPrivateKey(privateKey) { const {runModuloClock} = this.props; const {publicKey, publicModulus} = this.state; this.setState({privateKey}); @@ -81,13 +85,13 @@ export default class Eve extends React.Component { } else { this.setState({privateKey: null, privateKeyEquationResult: null}); } - }; + }, - setPublicNumber = (publicNumber) => { + setPublicNumber(publicNumber) { this.setState({publicNumber}); - }; + }, - setSecretNumber = (secretNumber) => { + setSecretNumber(secretNumber) { this.setState({secretNumber}); const {runModuloClock} = this.props; const {publicKey, publicModulus} = this.state; @@ -109,7 +113,7 @@ export default class Eve extends React.Component { } else { this.setState({secretNumber: null, secretNumberEquationResult: null}); } - }; + }, render() { const {disabled} = this.props; @@ -224,7 +228,7 @@ export default class Eve extends React.Component { - - ); + ); } -} +}); +export default Eve; diff --git a/apps/src/publicKeyCryptography/IntegerDropdown.jsx b/apps/src/publicKeyCryptography/IntegerDropdown.jsx index d6f710ac85ecf..0cf4850f4e55e 100644 --- a/apps/src/publicKeyCryptography/IntegerDropdown.jsx +++ b/apps/src/publicKeyCryptography/IntegerDropdown.jsx @@ -7,17 +7,19 @@ import 'react-virtualized/styles.css'; import 'react-select/dist/react-select.css'; import 'react-virtualized-select/styles.css'; -export default class IntegerDropdown extends React.Component { - static propTypes = { +const IntegerDropdown = React.createClass({ + propTypes: { className: PropTypes.string, value: PropTypes.number, options: PropTypes.arrayOf(PropTypes.number).isRequired, style: PropTypes.object, disabled: PropTypes.bool, onChange: PropTypes.func.isRequired - }; + }, - onChange = (selected) => this.props.onChange(selected ? selected.value : null); + onChange(selected) { + this.props.onChange(selected ? selected.value : null); + }, render() { let {className, value, options, style, disabled} = this.props; @@ -32,7 +34,7 @@ export default class IntegerDropdown extends React.Component { style={style} disabled={disabled} onChange={this.onChange} - /> - ); + />); } -} +}); +export default IntegerDropdown; diff --git a/apps/src/publicKeyCryptography/IntegerTextbox.jsx b/apps/src/publicKeyCryptography/IntegerTextbox.jsx index 9eda958ea9307..6c934c6ad9c29 100644 --- a/apps/src/publicKeyCryptography/IntegerTextbox.jsx +++ b/apps/src/publicKeyCryptography/IntegerTextbox.jsx @@ -2,19 +2,19 @@ import React, {PropTypes} from 'react'; import color from "../util/color"; -export default class IntegerTextbox extends React.Component { - static propTypes = { +const IntegerTextbox = React.createClass({ + propTypes: { className: PropTypes.string, value: PropTypes.number, disabled: PropTypes.bool, color: PropTypes.string, onChange: PropTypes.func.isRequired - }; + }, - onChange = (event) => { + onChange(event) { const value = parseInt(event.target.value, 10); this.props.onChange(Number.isInteger(value) ? value : null); - }; + }, render() { let {className, value, disabled, color: backgroundColor} = this.props; @@ -41,4 +41,5 @@ export default class IntegerTextbox extends React.Component { onChange={this.onChange} />); } -} +}); +export default IntegerTextbox; diff --git a/apps/src/publicKeyCryptography/ModuloClock.jsx b/apps/src/publicKeyCryptography/ModuloClock.jsx index 45d058cc7e3b7..b9966070ac88a 100644 --- a/apps/src/publicKeyCryptography/ModuloClock.jsx +++ b/apps/src/publicKeyCryptography/ModuloClock.jsx @@ -42,15 +42,17 @@ const style = { } }; -export default class ModuloClock extends React.Component { - static propTypes = { +const ModuloClock = React.createClass({ + propTypes: { modulus: PropTypes.number - }; + }, - state = { - startTime: null, - currentDividend: 0 - }; + getInitialState() { + return { + startTime: null, + currentDividend: 0 + }; + }, /** * @param {number} dividend - The left-hand-side of the modulus operation @@ -72,9 +74,9 @@ export default class ModuloClock extends React.Component { this.onComplete = onComplete || function () {}; this.duration = Math.min(maximumDuration, dividend * maximumTimePerSegment); this.setState({startTime: Date.now(), currentDividend: 0}); - } + }, - tick = () => { + tick() { const elapsedTime = Date.now() - this.state.startTime; if (elapsedTime < this.duration - FINALIZATION_DELAY) { // What dividend should we render on this frame? Ask the easing function. @@ -93,7 +95,7 @@ export default class ModuloClock extends React.Component { this.onComplete = null; this.setState({startTime: null}); } - }; + }, renderSegments(dividend, modulus, isRunning) { const segmentGapInDegrees = modulus > SMALL_GAPS_OVER_MODULUS ? 0.5 : 1; @@ -141,7 +143,7 @@ export default class ModuloClock extends React.Component { ); }); } - } + }, render() { const modulus = Math.max(1, this.props.modulus); @@ -177,7 +179,8 @@ export default class ModuloClock extends React.Component { ); } -} +}); +export default ModuloClock; /** * Produces SVG Path string for a clock segment sweeping the given number of diff --git a/apps/src/publicKeyCryptography/ModuloClockWidget.jsx b/apps/src/publicKeyCryptography/ModuloClockWidget.jsx index 6afca0fee75d0..ccf0083a19474 100644 --- a/apps/src/publicKeyCryptography/ModuloClockWidget.jsx +++ b/apps/src/publicKeyCryptography/ModuloClockWidget.jsx @@ -38,27 +38,35 @@ const style = { }; /** Root component for Public Key Cryptography widget */ -export default class ModuloClockWidget extends React.Component { - state = { - dividend: 247, - modulus: 37, - speed: 1, - animating: false - }; +const ModuloClockWidget = React.createClass({ + getInitialState() { + return { + dividend: 247, + modulus: 37, + speed: 1, + animating: false + }; + }, - onDividendChange = dividend => this.setState({dividend}); + onDividendChange(dividend) { + this.setState({dividend}); + }, - onModulusChange = modulus => this.setState({modulus}); + onModulusChange(modulus) { + this.setState({modulus}); + }, - onGoClick = () => { + onGoClick() { this.setState({animating: true}); const maximumDuration = 8000 / this.state.speed + 2000; this.moduloClock.animateTo(this.state.dividend, maximumDuration, null, () => { this.setState({animating: false}); }); - }; + }, - onSpeedChange = speed => this.setState({speed}); + onSpeedChange(speed) { + this.setState({speed}); + }, render() { const {dividend, modulus, speed, animating} = this.state; @@ -110,7 +118,8 @@ export default class ModuloClockWidget extends React.Component { ); } -} +}); +export default ModuloClockWidget; function LabelBelow(props) { return ( diff --git a/apps/src/publicKeyCryptography/NumberedSteps.story.jsx b/apps/src/publicKeyCryptography/NumberedSteps.story.jsx index 7104c3381b5e5..9b0138ff7c763 100644 --- a/apps/src/publicKeyCryptography/NumberedSteps.story.jsx +++ b/apps/src/publicKeyCryptography/NumberedSteps.story.jsx @@ -1,75 +1,84 @@ import React from 'react'; import NumberedSteps, {Step} from './NumberedSteps'; -export default storybook => storybook - .storiesOf('NumberedSteps', module) - .addStoryTable([ - { - name: 'Steps with prerequisites', - description: `You can pass requirements to each step. Steps with - unmet requirements (null or undefined) will be displayed at 20% - opacity.`, - story: () => ( - - typeof s === 'string')}> - Step with all requirements met. - - x)}> - Step with an unmet requirement - - ) - }, - { - name: 'Fade effect', - description: `Steps fade in and out as their requirements are met/unmet`, - story: () => { - class FadeEffectExample extends React.Component { - state = {}; +export default storybook => { + return storybook + .storiesOf('NumberedSteps', module) + .addStoryTable([ + { + name: 'Steps with prerequisites', + description: `You can pass requirements to each step. Steps with + unmet requirements (null or undefined) will be displayed at 20% + opacity.`, + story: () => ( + + typeof s === 'string')}> + Step with all requirements met. + + x)}> + Step with an unmet requirement + + ) + }, + { + name: 'Fade effect', + description: `Steps fade in and out as their requirements are met/unmet`, + story: () => { + const FadeEffectExample = React.createClass({ + getInitialState() { + return {}; + }, - onToggleStep1 = () => this.setState({step1Done: !this.state.step1Done}); + onToggleStep1() { + this.setState({step1Done: !this.state.step1Done}); + }, - onToggleStep2 = () => this.setState({step2Done: !this.state.step2Done}); + onToggleStep2() { + this.setState({step2Done: !this.state.step2Done}); + }, - onToggleStep3 = () => this.setState({step3Done: !this.state.step3Done}); + onToggleStep3() { + this.setState({step3Done: !this.state.step3Done}); + }, - render() { - const {step1Done, step2Done, step3Done} = this.state; - return ( - - - Click to complete this step: {step1Done ? '' : 'Not'} Done - - - This step depends only on step one. -
Click to complete this step: {step2Done ? '' : 'Not'} Done -
- - This step depends only on step two. -
Click to complete this step: {step3Done ? '' : 'Not'} Done -
- - This step depends on all preceding steps. - -
- ); - } + render() { + const {step1Done, step2Done, step3Done} = this.state; + return ( + + + Click to complete this step: {step1Done ? '' : 'Not'} Done + + + This step depends only on step one. +
Click to complete this step: {step2Done ? '' : 'Not'} Done +
+ + This step depends only on step two. +
Click to complete this step: {step3Done ? '' : 'Not'} Done +
+ + This step depends on all preceding steps. + +
); + } + }); + return ; } - return ; + }, + { + name: 'Holds any content', + description: `By default, NumberedSteps just works like an
    element + with particular spacing and styling.`, + story: () => ( + + + Arbitrary content here. +

    With multiple lines.

    +
    + + More arbitrary content here. + +
    ) } - }, - { - name: 'Holds any content', - description: `By default, NumberedSteps just works like an
      element - with particular spacing and styling.`, - story: () => ( - - - Arbitrary content here. -

      With multiple lines.

      -
      - - More arbitrary content here. - -
      ) - } - ]); + ]); +}; diff --git a/apps/src/publicKeyCryptography/PublicKeyCryptographyWidget.jsx b/apps/src/publicKeyCryptography/PublicKeyCryptographyWidget.jsx index 6e259b8c3722e..f7a20769283ad 100644 --- a/apps/src/publicKeyCryptography/PublicKeyCryptographyWidget.jsx +++ b/apps/src/publicKeyCryptography/PublicKeyCryptographyWidget.jsx @@ -38,50 +38,54 @@ const style = { }; /** Root component for Public Key Cryptography widget */ -export default class PublicKeyCryptographyWidget extends React.Component { - state = { - animating: false, - publicModulus: null, - selectedCharacter: null - }; +const PublicKeyCryptographyWidget = React.createClass({ + getInitialState() { + return { + animating: false, + publicModulus: null, + selectedCharacter: null + }; + }, - setSelectedCharacter = selectedCharacter => this.setState({selectedCharacter}); + setSelectedCharacter(selectedCharacter) { + this.setState({selectedCharacter}); + }, - setPublicModulus = (publicModulus) => { + setPublicModulus(publicModulus) { // Anyone can set the public modulus. Inform everyone. this.alice && this.alice.setPublicModulus(publicModulus); this.bob && this.bob.setPublicModulus(publicModulus); this.eve && this.eve.setPublicModulus(publicModulus); this.setState({publicModulus}); - }; + }, - setPublicKey = (publicKey) => { + setPublicKey(publicKey) { // Only Alice can set the public key. Inform Bob and Eve. this.bob && this.bob.setPublicKey(publicKey); this.eve && this.eve.setPublicKey(publicKey); - }; + }, - setPublicNumber = (publicNumber) => { + setPublicNumber(publicNumber) { // Only Bob can set the public number. Inform Alice and Eve. this.alice && this.alice.setPublicNumber(publicNumber); this.eve && this.eve.setPublicNumber(publicNumber); - }; + }, - runModuloClock = (dividend, onStep, onComplete) => { + runModuloClock(dividend, onStep, onComplete) { const duration = 1000; this.setState({animating: true}); this.moduloClock.animateTo(dividend, duration, onStep, (finalValue) => { this.setState({animating: false}); onComplete(finalValue); }); - }; + }, - onStartOverClick = () => { + onStartOverClick() { this.alice && this.alice.startOver(); this.bob && this.bob.startOver(); this.eve && this.eve.startOver(); this.setState({publicModulus: null}); - }; + }, renderCharacterView(selectedCharacter) { if (ALICE_VIEW === selectedCharacter) { @@ -125,7 +129,7 @@ export default class PublicKeyCryptographyWidget extends React.Component { Please pick a character first. ); - } + }, renderAliceControls() { return ( @@ -137,7 +141,7 @@ export default class PublicKeyCryptographyWidget extends React.Component { runModuloClock={this.runModuloClock} /> ); - } + }, renderEveControls() { return ( @@ -148,7 +152,7 @@ export default class PublicKeyCryptographyWidget extends React.Component { runModuloClock={this.runModuloClock} /> ); - } + }, renderBobControls() { return ( @@ -160,7 +164,7 @@ export default class PublicKeyCryptographyWidget extends React.Component { runModuloClock={this.runModuloClock} /> ); - } + }, renderModuloClockPanel() { return ( @@ -168,7 +172,7 @@ export default class PublicKeyCryptographyWidget extends React.Component { {this.renderModuloClock()} ); - } + }, renderModuloClock() { return ( @@ -177,7 +181,7 @@ export default class PublicKeyCryptographyWidget extends React.Component { modulus={this.state.publicModulus || 1} /> ); - } + }, render() { const {selectedCharacter} = this.state; @@ -192,10 +196,10 @@ export default class PublicKeyCryptographyWidget extends React.Component {
      {this.renderCharacterView(selectedCharacter)}
      - - ); + ); } -} +}); +export default PublicKeyCryptographyWidget; /** * Toggle group of character view options: Alice|Eve|Bob|All diff --git a/apps/src/publicKeyCryptography/StartOverButton.jsx b/apps/src/publicKeyCryptography/StartOverButton.jsx index a2a09cc47c454..0e4e620ded611 100644 --- a/apps/src/publicKeyCryptography/StartOverButton.jsx +++ b/apps/src/publicKeyCryptography/StartOverButton.jsx @@ -3,21 +3,27 @@ import React, {PropTypes} from 'react'; import i18n from '@cdo/locale'; import Dialog from '../templates/Dialog'; -export default class StartOverButton extends React.Component { - static propTypes = { +const StartOverButton = React.createClass({ + propTypes: { onClick: PropTypes.func.isRequired - }; + }, - state = {confirming: false}; + getInitialState() { + return {confirming: false}; + }, - confirm = () => this.setState({confirming: true}); + confirm() { + this.setState({confirming: true}); + }, - onConfirm = () => { + onConfirm() { this.props.onClick(); this.setState({confirming: false}); - }; + }, - onCancel = () => this.setState({confirming: false}); + onCancel() { + this.setState({confirming: false}); + }, render() { return ( @@ -36,7 +42,7 @@ export default class StartOverButton extends React.Component { onConfirm={this.onConfirm} onCancel={this.onCancel} /> - - ); + ); } -} +}); +export default StartOverButton;