diff --git a/lib/atom/gutter.js b/lib/atom/gutter.js index f36b477a80..6d181a263f 100644 --- a/lib/atom/gutter.js +++ b/lib/atom/gutter.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import {Disposable} from 'event-kit'; -import {autobind, extractProps} from '../helpers'; +import {extractProps} from '../helpers'; import {RefHolderPropType} from '../prop-types'; import {TextEditorContext} from './atom-text-editor'; import RefHolder from '../models/ref-holder'; @@ -32,7 +32,7 @@ class BareGutter extends React.Component { constructor(props) { super(props); - autobind(this, 'observeEditor', 'forceUpdate'); + this.forceUpdate = this.forceUpdate.bind(this); this.state = { gutter: null, @@ -67,7 +67,7 @@ class BareGutter extends React.Component { return null; } - observeEditor(editor) { + observeEditor = editor => { this.setState((prevState, props) => { if (prevState.gutter !== null) { prevState.gutter.destroy(); diff --git a/lib/atom/keystroke.js b/lib/atom/keystroke.js index d61d8d2e3a..984e2bf2d5 100644 --- a/lib/atom/keystroke.js +++ b/lib/atom/keystroke.js @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import {humanizeKeystroke} from 'underscore-plus'; import {Disposable} from 'event-kit'; -import {autobind} from '../helpers'; import {RefHolderPropType} from '../prop-types'; export default class Keystroke extends React.Component { @@ -17,7 +16,6 @@ export default class Keystroke extends React.Component { constructor(props) { super(props); - autobind(this, 'didChangeTarget'); this.sub = new Disposable(); this.state = {keybinding: null}; @@ -56,7 +54,7 @@ export default class Keystroke extends React.Component { } } - didChangeTarget(target) { + didChangeTarget = target => { const [keybinding] = this.props.keymaps.findKeyBindings({ command: this.props.command, target, diff --git a/lib/atom/marker-layer.js b/lib/atom/marker-layer.js index b4bc3f6f83..d1cdd6c54d 100644 --- a/lib/atom/marker-layer.js +++ b/lib/atom/marker-layer.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import {CompositeDisposable, Disposable} from 'event-kit'; -import {autobind, extractProps} from '../helpers'; +import {extractProps} from '../helpers'; import RefHolder from '../models/ref-holder'; import {TextEditorContext} from './atom-text-editor'; import {DecorableContext} from './marker'; @@ -34,8 +34,6 @@ class BareMarkerLayer extends React.Component { constructor(props) { super(props); - autobind(this, 'createLayer'); - this.subs = new CompositeDisposable(); this.layerSub = new Disposable(); @@ -90,7 +88,7 @@ class BareMarkerLayer extends React.Component { this.subs.add(this.state.editorHolder.observe(this.createLayer)); } - createLayer() { + createLayer = () => { this.subs.remove(this.layerSub); this.layerSub.dispose(); diff --git a/lib/atom/marker.js b/lib/atom/marker.js index 859ee74dd7..617649ee7c 100644 --- a/lib/atom/marker.js +++ b/lib/atom/marker.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import {CompositeDisposable, Disposable} from 'event-kit'; -import {autobind, extractProps} from '../helpers'; +import {extractProps} from '../helpers'; import {RefHolderPropType, RangePropType} from '../prop-types'; import RefHolder from '../models/ref-holder'; import {TextEditorContext} from './atom-text-editor'; @@ -42,8 +42,6 @@ class BareMarker extends React.Component { constructor(props) { super(props); - autobind(this, 'createMarker', 'didChange'); - this.markerSubs = new CompositeDisposable(); this.subs = new CompositeDisposable(); @@ -94,7 +92,7 @@ class BareMarker extends React.Component { this.subs.add(this.props.markableHolder.observe(this.createMarker)); } - createMarker() { + createMarker = () => { this.markerSubs.dispose(); this.markerSubs = new CompositeDisposable(); this.subs.add(this.markerSubs); @@ -126,7 +124,7 @@ class BareMarker extends React.Component { this.markerHolder.map(marker => marker.setBufferRange(this.props.bufferRange)); } - didChange(event) { + didChange = event => { const reversed = this.markerHolder.map(marker => marker.isReversed()).getOr(false); const oldBufferStartPosition = reversed ? event.oldHeadBufferPosition : event.oldTailBufferPosition; diff --git a/lib/atom/pane-item.js b/lib/atom/pane-item.js index f564d021d0..a50e61d9d8 100644 --- a/lib/atom/pane-item.js +++ b/lib/atom/pane-item.js @@ -6,7 +6,7 @@ import {CompositeDisposable} from 'event-kit'; import URIPattern, {nonURIMatch} from './uri-pattern'; import RefHolder from '../models/ref-holder'; import StubItem from '../items/stub-item'; -import {createItem, autobind} from '../helpers'; +import {createItem} from '../helpers'; /** * PaneItem registers an opener with the current Atom workspace as long as this component is mounted. The opener will @@ -39,7 +39,6 @@ export default class PaneItem extends React.Component { constructor(props) { super(props); - autobind(this, 'opener'); const uriPattern = new URIPattern(this.props.uriPattern); const currentlyOpen = this.props.workspace.getPaneItems() @@ -99,7 +98,7 @@ export default class PaneItem extends React.Component { this.subs.dispose(); } - opener(uri) { + opener = uri => { const m = this.state.uriPattern.matches(uri); if (!m.ok()) { return undefined; diff --git a/lib/containers/changed-file-container.js b/lib/containers/changed-file-container.js index fc9a83ee4c..9748dbd263 100644 --- a/lib/containers/changed-file-container.js +++ b/lib/containers/changed-file-container.js @@ -2,7 +2,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import yubikiri from 'yubikiri'; -import {autobind} from '../helpers'; import ObserveModel from '../views/observe-model'; import LoadingView from '../views/loading-view'; import ChangedFileController from '../controllers/changed-file-controller'; @@ -24,12 +23,7 @@ export default class ChangedFileContainer extends React.Component { surfaceFileAtPath: PropTypes.func.isRequired, } - constructor(props) { - super(props); - autobind(this, 'fetchData', 'renderWithData'); - } - - fetchData(repository) { + fetchData = repository => { const staged = this.props.stagingStatus === 'staged'; return yubikiri({ @@ -47,7 +41,7 @@ export default class ChangedFileContainer extends React.Component { ); } - renderWithData(data) { + renderWithData = data => { if (this.props.repository.isLoading() || data === null) { return ; } diff --git a/lib/containers/current-pull-request-container.js b/lib/containers/current-pull-request-container.js index 1f012df810..216498eef2 100644 --- a/lib/containers/current-pull-request-container.js +++ b/lib/containers/current-pull-request-container.js @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import {QueryRenderer, graphql} from 'react-relay'; import {Disposable} from 'event-kit'; -import {autobind} from '../helpers'; import {RemotePropType, RemoteSetPropType, BranchSetPropType, OperationStateObserverPropType} from '../prop-types'; import IssueishListController, {BareIssueishListController} from '../controllers/issueish-list-controller'; import CreatePullRequestTile from '../views/create-pull-request-tile'; @@ -39,7 +38,6 @@ export default class CurrentPullRequestContainer extends React.Component { constructor(props) { super(props); - autobind(this, 'renderQueryResult', 'renderEmptyTile'); this.sub = new Disposable(); } @@ -98,7 +96,7 @@ export default class CurrentPullRequestContainer extends React.Component { return ; } - renderQueryResult({error, props, retry}) { + renderQueryResult = ({error, props, retry}) => { if (retry) { this.sub.dispose(); this.sub = this.props.remoteOperationObserver.onDidComplete(retry); @@ -140,7 +138,7 @@ export default class CurrentPullRequestContainer extends React.Component { ); } - renderEmptyTile() { + renderEmptyTile = () => { return ( { return yubikiri({ lastCommit: repository.getLastCommit(), recentCommits: repository.getRecentCommits({max: 10}), diff --git a/lib/containers/github-tab-container.js b/lib/containers/github-tab-container.js index 75ddad0b14..f27f4106d8 100644 --- a/lib/containers/github-tab-container.js +++ b/lib/containers/github-tab-container.js @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import yubikiri from 'yubikiri'; import {GithubLoginModelPropType, RefHolderPropType} from '../prop-types'; -import {autobind} from '../helpers'; import OperationStateObserver, {PUSH, PULL, FETCH} from '../models/operation-state-observer'; import GitHubTabController from '../controllers/github-tab-controller'; import ObserveModel from '../views/observe-model'; @@ -20,7 +19,6 @@ export default class GitHubTabContainer extends React.Component { constructor(props) { super(props); - autobind(this, 'fetchRepositoryData', 'renderRepositoryData'); this.state = {}; } @@ -36,7 +34,7 @@ export default class GitHubTabContainer extends React.Component { return null; } - fetchRepositoryData(repository) { + fetchRepositoryData = repository => { return yubikiri({ workingDirectory: repository.getWorkingDirectoryPath(), allRemotes: repository.getRemotes(), @@ -59,7 +57,7 @@ export default class GitHubTabContainer extends React.Component { ); } - renderRepositoryData(data) { + renderRepositoryData = data => { if (!data || this.props.repository.isLoading()) { return ( { return yubikiri({ token: loginModel.getToken(this.props.host), }); @@ -54,7 +43,7 @@ export default class IssueishDetailContainer extends React.Component { ); } - fetchRepositoryData(repository) { + fetchRepositoryData = repository => { return yubikiri({ branches: repository.getBranches(), remotes: repository.getRemotes(), @@ -66,7 +55,7 @@ export default class IssueishDetailContainer extends React.Component { }); } - renderWithToken(tokenData) { + renderWithToken = tokenData => { if (!tokenData) { return ; } @@ -92,7 +81,7 @@ export default class IssueishDetailContainer extends React.Component { ); } - renderWithRepositoryData(repoData, token) { + renderWithRepositoryData = (repoData, token) => { if (!repoData) { return ; } @@ -142,7 +131,7 @@ export default class IssueishDetailContainer extends React.Component { ); } - renderWithResult({error, props, retry}, repoData) { + renderWithResult = ({error, props, retry}, repoData) => { if (error) { return ( this.props.loginModel.setToken(this.props.host, token) - handleLogout() { - return this.props.loginModel.removeToken(this.props.host); - } + handleLogout = () => this.props.loginModel.removeToken(this.props.host) } diff --git a/lib/containers/issueish-search-container.js b/lib/containers/issueish-search-container.js index a937113658..3c86158a6f 100644 --- a/lib/containers/issueish-search-container.js +++ b/lib/containers/issueish-search-container.js @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import {QueryRenderer, graphql} from 'react-relay'; import {Disposable} from 'event-kit'; -import {autobind} from '../helpers'; import {SearchPropType, OperationStateObserverPropType} from '../prop-types'; import IssueishListController, {BareIssueishListController} from '../controllers/issueish-list-controller'; import RelayNetworkLayerManager from '../relay-network-layer-manager'; @@ -26,7 +25,6 @@ export default class IssueishSearchContainer extends React.Component { constructor(props) { super(props); - autobind(this, 'renderQueryResult'); this.sub = new Disposable(); } @@ -68,7 +66,7 @@ export default class IssueishSearchContainer extends React.Component { ); } - renderQueryResult({error, props, retry}) { + renderQueryResult = ({error, props, retry}) => { if (retry) { this.sub.dispose(); this.sub = this.props.remoteOperationObserver.onDidComplete(retry); diff --git a/lib/containers/remote-container.js b/lib/containers/remote-container.js index fc68447a1f..75a7166adc 100644 --- a/lib/containers/remote-container.js +++ b/lib/containers/remote-container.js @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import {QueryRenderer, graphql} from 'react-relay'; import {incrementCounter} from '../reporter-proxy'; -import {autobind} from '../helpers'; import {RemotePropType, RemoteSetPropType, BranchSetPropType, OperationStateObserverPropType} from '../prop-types'; import RelayNetworkLayerManager from '../relay-network-layer-manager'; import {UNAUTHENTICATED, INSUFFICIENT} from '../shared/keytar-strategy'; @@ -32,15 +31,7 @@ export default class RemoteContainer extends React.Component { onPushBranch: PropTypes.func.isRequired, } - constructor(props) { - super(props); - - autobind(this, 'fetchToken', 'renderWithToken', 'renderWithResult', 'handleLogin', 'handleLogout'); - } - - fetchToken(loginModel) { - return loginModel.getToken(this.props.host); - } + fetchToken = loginModel => loginModel.getToken(this.props.host) render() { return ( @@ -50,7 +41,7 @@ export default class RemoteContainer extends React.Component { ); } - renderWithToken(token) { + renderWithToken = token => { if (token === null) { return ; } @@ -96,7 +87,7 @@ export default class RemoteContainer extends React.Component { ); } - renderWithResult({error, props, retry}, token) { + renderWithResult = ({error, props, retry}, token) => { if (error) { return ( { incrementCounter('github-login'); this.props.loginModel.setToken(this.props.host, token); } - handleLogout() { + handleLogout = () => { incrementCounter('github-logout'); this.props.loginModel.removeToken(this.props.host); } diff --git a/lib/controllers/commit-controller.js b/lib/controllers/commit-controller.js index 7183eeb31a..9f225ef680 100644 --- a/lib/controllers/commit-controller.js +++ b/lib/controllers/commit-controller.js @@ -11,7 +11,6 @@ import RefHolder from '../models/ref-holder'; import CommitPreviewItem from '../items/commit-preview-item'; import {AuthorPropType, UserStorePropType} from '../prop-types'; import {watchWorkspaceItem} from '../watch-workspace-item'; -import {autobind} from '../helpers'; import {addEvent} from '../reporter-proxy'; export const COMMIT_GRAMMAR_SCOPE = 'text.git-commit'; @@ -44,8 +43,6 @@ export default class CommitController extends React.Component { constructor(props, context) { super(props, context); - autobind(this, 'commit', 'handleMessageChange', 'toggleExpandedCommitMessageEditor', 'grammarAdded', - 'toggleCommitPreview'); this.subscriptions = new CompositeDisposable(); this.refCommitView = new RefHolder(); @@ -137,7 +134,7 @@ export default class CommitController extends React.Component { this.subscriptions.dispose(); } - commit(message, coAuthors = [], amend = false) { + commit = (message, coAuthors = [], amend = false) => { let msg, verbatim; if (this.isCommitMessageEditorExpanded()) { msg = this.getCommitMessageEditors()[0].getText(); @@ -164,7 +161,7 @@ export default class CommitController extends React.Component { return path.join(this.props.repository.getGitDirectoryPath(), 'ATOM_COMMIT_EDITMSG'); } - handleMessageChange() { + handleMessageChange = () => { if (!this.props.repository.isPresent()) { return; } @@ -178,7 +175,7 @@ export default class CommitController extends React.Component { return this.props.workspace.getTextEditors().filter(editor => editor.getPath() === this.getCommitMessagePath()); } - async toggleExpandedCommitMessageEditor(messageFromBox) { + toggleExpandedCommitMessageEditor = async messageFromBox => { if (this.isCommitMessageEditorExpanded()) { if (this.commitMessageEditorIsInForeground()) { await this.closeAllOpenCommitMessageEditors(); @@ -245,7 +242,7 @@ export default class CommitController extends React.Component { } } - grammarAdded(grammar) { + grammarAdded = grammar => { if (grammar.scopeName !== COMMIT_GRAMMAR_SCOPE) { return; } this.getCommitMessageEditors().forEach(editor => editor.setGrammar(grammar)); @@ -268,7 +265,7 @@ export default class CommitController extends React.Component { return this.refCommitView.map(view => view.retreatFocusFrom(...args)).getOr(false); } - toggleCommitPreview() { + toggleCommitPreview = () => { addEvent('toggle-commit-preview', {package: 'github'}); const uri = CommitPreviewItem.buildURI(this.props.repository.getWorkingDirectoryPath()); if (this.props.workspace.hide(uri)) { diff --git a/lib/controllers/conflict-controller.js b/lib/controllers/conflict-controller.js index f51e1236f2..737790f4b1 100644 --- a/lib/controllers/conflict-controller.js +++ b/lib/controllers/conflict-controller.js @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import {remote} from 'electron'; const {Menu, MenuItem} = remote; -import {autobind} from '../helpers'; import {OURS, BASE, THEIRS} from '../models/conflicts/source'; import Decoration from '../atom/decoration'; import Octicon from '../atom/octicon'; @@ -23,7 +22,6 @@ export default class ConflictController extends React.Component { constructor(props, context) { super(props, context); - autobind(this, 'showResolveMenu'); this.state = { chosenSide: this.props.conflict.getChosenSide(), @@ -43,7 +41,7 @@ export default class ConflictController extends React.Component { side.isBannerModified() && side.revertBanner(); } - showResolveMenu(event) { + showResolveMenu = event => { event.preventDefault(); const menu = new Menu(); diff --git a/lib/controllers/editor-conflict-controller.js b/lib/controllers/editor-conflict-controller.js index 728cfc5021..d67bdffa4e 100644 --- a/lib/controllers/editor-conflict-controller.js +++ b/lib/controllers/editor-conflict-controller.js @@ -7,7 +7,6 @@ import Commands, {Command} from '../atom/commands'; import Conflict from '../models/conflicts/conflict'; import ConflictController from './conflict-controller'; import {OURS, THEIRS, BASE} from '../models/conflicts/source'; -import {autobind} from '../helpers'; /** * Render a `ConflictController` for each conflict marker within an open TextEditor. @@ -27,7 +26,6 @@ export default class EditorConflictController extends React.Component { constructor(props, context) { super(props, context); - autobind(this, 'resolveAsCurrent', 'revertConflictModifications', 'dismissCurrent'); // this.layer = props.editor.addMarkerLayer({ // maintainHistory: true, @@ -148,7 +146,7 @@ export default class EditorConflictController extends React.Component { }; } - resolveAsCurrent() { + resolveAsCurrent = () => { this.getCurrentConflicts().forEach(match => { if (match.sides.size === 1) { const side = match.sides.keys().next().value; @@ -157,7 +155,7 @@ export default class EditorConflictController extends React.Component { }); } - revertConflictModifications() { + revertConflictModifications = () => { this.getCurrentConflicts().forEach(match => { match.sides.forEach(side => { side.isModified() && side.revert(); @@ -166,7 +164,7 @@ export default class EditorConflictController extends React.Component { }); } - dismissCurrent() { + dismissCurrent = () => { this.dismissConflicts(this.getCurrentConflicts().map(match => match.conflict)); } diff --git a/lib/controllers/git-tab-controller.js b/lib/controllers/git-tab-controller.js index 647f8f9535..78343c09ab 100644 --- a/lib/controllers/git-tab-controller.js +++ b/lib/controllers/git-tab-controller.js @@ -10,7 +10,6 @@ import RefHolder from '../models/ref-holder'; import { CommitPropType, BranchPropType, FilePatchItemPropType, MergeConflictItemPropType, RefHolderPropType, } from '../prop-types'; -import {autobind} from '../helpers'; export default class GitTabController extends React.Component { static focus = { @@ -55,12 +54,6 @@ export default class GitTabController extends React.Component { constructor(props, context) { super(props, context); - autobind( - this, - 'attemptStageAllOperation', 'attemptFileStageOperation', 'unstageFiles', 'prepareToCommit', - 'commit', 'updateSelectedCoAuthors', 'undoLastCommit', 'abortMerge', 'resolveAsOurs', 'resolveAsTheirs', - 'checkout', 'rememberLastFocus', 'quietlySelectItem', - ); this.stagingOperationInProgress = false; this.lastFocus = GitTabView.focus.STAGING; @@ -189,11 +182,11 @@ export default class GitTabController extends React.Component { } } - attemptStageAllOperation(stageStatus) { + attemptStageAllOperation = stageStatus => { return this.attemptFileStageOperation(['.'], stageStatus); } - attemptFileStageOperation(filePaths, stageStatus) { + attemptFileStageOperation = (filePaths, stageStatus) => { if (this.stagingOperationInProgress) { return { stageOperationPromise: Promise.resolve(), @@ -245,19 +238,13 @@ export default class GitTabController extends React.Component { return this.props.repository.stageFiles(Array.from(pathsToStage)); } - unstageFiles(filePaths) { - return this.props.repository.unstageFiles(filePaths); - } + unstageFiles = filePaths => this.props.repository.unstageFiles(filePaths) - async prepareToCommit() { - return !await this.props.ensureGitTab(); - } + prepareToCommit = async () => !await this.props.ensureGitTab() - commit(message, options) { - return this.props.repository.commit(message, options); - } + commit = (message, options) => this.props.repository.commit(message, options) - updateSelectedCoAuthors(selectedCoAuthors, newAuthor) { + updateSelectedCoAuthors = (selectedCoAuthors, newAuthor) => { if (newAuthor) { this.userStore.addUsers([newAuthor]); selectedCoAuthors = selectedCoAuthors.concat([newAuthor]); @@ -265,7 +252,7 @@ export default class GitTabController extends React.Component { this.setState({selectedCoAuthors}); } - async undoLastCommit() { + undoLastCommit = async () => { const repo = this.props.repository; const lastCommit = await repo.getLastCommit(); if (lastCommit.isUnbornRef()) { return null; } @@ -281,7 +268,7 @@ export default class GitTabController extends React.Component { return null; } - async abortMerge() { + abortMerge = async () => { const choice = this.props.confirm({ message: 'Abort merge', detailedMessage: 'Are you sure?', @@ -303,7 +290,7 @@ export default class GitTabController extends React.Component { } } - async resolveAsOurs(paths) { + resolveAsOurs = async paths => { if (this.props.fetchInProgress) { return; } @@ -313,7 +300,7 @@ export default class GitTabController extends React.Component { this.refreshResolutionProgress(false, true); } - async resolveAsTheirs(paths) { + resolveAsTheirs = async paths => { if (this.props.fetchInProgress) { return; } @@ -323,11 +310,9 @@ export default class GitTabController extends React.Component { this.refreshResolutionProgress(false, true); } - checkout(branchName, options) { - return this.props.repository.checkout(branchName, options); - } + checkout = (branchName, options) => this.props.repository.checkout(branchName, options) - rememberLastFocus(event) { + rememberLastFocus = event => { this.lastFocus = this.refView.map(view => view.getFocus(event.target)).getOr(null) || GitTabView.focus.STAGING; } @@ -357,7 +342,7 @@ export default class GitTabController extends React.Component { return this.refView.map(view => view.focusAndSelectRecentCommit()); } - quietlySelectItem(filePath, stagingStatus) { + quietlySelectItem = (filePath, stagingStatus) => { return this.refView.map(view => view.quietlySelectItem(filePath, stagingStatus)).getOr(null); } } diff --git a/lib/controllers/github-tab-controller.js b/lib/controllers/github-tab-controller.js index 153b723d28..8e69c82251 100644 --- a/lib/controllers/github-tab-controller.js +++ b/lib/controllers/github-tab-controller.js @@ -4,7 +4,6 @@ import PropTypes from 'prop-types'; import { GithubLoginModelPropType, RefHolderPropType, RemoteSetPropType, BranchSetPropType, OperationStateObserverPropType, } from '../prop-types'; -import {autobind} from '../helpers'; import GitHubTabView from '../views/github-tab-view'; export default class GitHubTabController extends React.Component { @@ -24,11 +23,6 @@ export default class GitHubTabController extends React.Component { isLoading: PropTypes.bool.isRequired, } - constructor(props) { - super(props); - autobind(this, 'handlePushBranch', 'handleRemoteSelect'); - } - render() { const gitHubRemotes = this.props.allRemotes.filter(remote => remote.isGithubRepo()); const currentBranch = this.props.branches.getHeadBranch(); @@ -64,14 +58,14 @@ export default class GitHubTabController extends React.Component { ); } - handlePushBranch(currentBranch, targetRemote) { + handlePushBranch = (currentBranch, targetRemote) => { return this.props.repository.push(currentBranch.getName(), { remote: targetRemote, setUpstream: true, }); } - handleRemoteSelect(e, remote) { + handleRemoteSelect = (e, remote) => { e.preventDefault(); return this.props.repository.setConfig('atomGithub.currentRemote', remote.getName()); } diff --git a/lib/controllers/issueish-searches-controller.js b/lib/controllers/issueish-searches-controller.js index 02ea32e5a4..3973bc0f79 100644 --- a/lib/controllers/issueish-searches-controller.js +++ b/lib/controllers/issueish-searches-controller.js @@ -2,7 +2,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import {shell} from 'electron'; -import {autobind} from '../helpers'; import {RemotePropType, RemoteSetPropType, BranchSetPropType, OperationStateObserverPropType} from '../prop-types'; import Search from '../models/search'; import IssueishSearchContainer from '../containers/issueish-search-container'; @@ -37,7 +36,6 @@ export default class IssueishSearchesController extends React.Component { constructor(props) { super(props); - autobind(this, 'onOpenIssueish', 'onOpenSearch'); this.state = {}; } @@ -84,7 +82,7 @@ export default class IssueishSearchesController extends React.Component { ); } - onOpenIssueish(issueish) { + onOpenIssueish = issueish => { return this.props.workspace.open( IssueishDetailItem.buildURI( this.props.host, @@ -99,7 +97,7 @@ export default class IssueishSearchesController extends React.Component { }); } - onOpenSearch(search) { + onOpenSearch = search => { const searchURL = search.getWebURL(this.props.remote); return new Promise((resolve, reject) => { diff --git a/lib/controllers/multi-file-patch-controller.js b/lib/controllers/multi-file-patch-controller.js index cdba88def6..c63bfd3c31 100644 --- a/lib/controllers/multi-file-patch-controller.js +++ b/lib/controllers/multi-file-patch-controller.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import path from 'path'; -import {autobind, equalSets} from '../helpers'; +import {equalSets} from '../helpers'; import {addEvent} from '../reporter-proxy'; import {MultiFilePatchPropType} from '../prop-types'; import ChangedFileItem from '../items/changed-file-item'; @@ -29,12 +29,6 @@ export default class MultiFilePatchController extends React.Component { constructor(props) { super(props); - autobind( - this, - 'selectedRowsChanged', - 'undoLastDiscard', 'diveIntoMirrorPatch', 'openFile', - 'toggleFile', 'toggleRows', 'toggleModeChange', 'toggleSymlinkChange', 'discardRows', - ); this.state = { selectionMode: 'hunk', @@ -51,7 +45,7 @@ export default class MultiFilePatchController extends React.Component { }); } - componentDidUpdate(prevProps) { + componentDidUpdate() { if ( this.lastPatchString !== null && this.lastPatchString !== this.props.multiFilePatch.toString() @@ -87,7 +81,7 @@ export default class MultiFilePatchController extends React.Component { ); } - undoLastDiscard(filePatch, {eventSource} = {}) { + undoLastDiscard = (filePatch, {eventSource} = {}) => { addEvent('undo-last-discard', { package: 'github', component: this.constructor.name, @@ -97,7 +91,7 @@ export default class MultiFilePatchController extends React.Component { return this.props.undoLastDiscard(filePatch.getPath(), this.props.repository); } - diveIntoMirrorPatch(filePatch) { + diveIntoMirrorPatch = filePatch => { const mirrorStatus = this.withStagingStatus({staged: 'unstaged', unstaged: 'staged'}); const workingDirectory = this.props.repository.getWorkingDirectoryPath(); const uri = ChangedFileItem.buildURI(filePatch.getPath(), workingDirectory, mirrorStatus); @@ -106,7 +100,7 @@ export default class MultiFilePatchController extends React.Component { return this.props.workspace.open(uri); } - async openFile(filePatch, positions, pending) { + openFile = async (filePatch, positions, pending) => { const absolutePath = path.join(this.props.repository.getWorkingDirectoryPath(), filePatch.getPath()); const editor = await this.props.workspace.open(absolutePath, {pending}); if (positions.length > 0) { @@ -119,14 +113,14 @@ export default class MultiFilePatchController extends React.Component { return editor; } - toggleFile(filePatch) { + toggleFile = filePatch => { return this.stagingOperation(() => { const methodName = this.withStagingStatus({staged: 'unstageFiles', unstaged: 'stageFiles'}); return this.props.repository[methodName]([filePatch.getPath()]); }); } - async toggleRows(rowSet, nextSelectionMode) { + toggleRows = async (rowSet, nextSelectionMode) => { let chosenRows = rowSet; if (chosenRows) { const nextMultipleFileSelections = this.props.multiFilePatch.spansMultipleFiles(chosenRows); @@ -148,7 +142,7 @@ export default class MultiFilePatchController extends React.Component { }); } - toggleModeChange(filePatch) { + toggleModeChange = filePatch => { return this.stagingOperation(() => { const targetMode = this.withStagingStatus({ unstaged: filePatch.getNewMode(), @@ -158,7 +152,7 @@ export default class MultiFilePatchController extends React.Component { }); } - toggleSymlinkChange(filePatch) { + toggleSymlinkChange = filePatch => { return this.stagingOperation(() => { const relPath = filePatch.getPath(); const repository = this.props.repository; @@ -181,7 +175,7 @@ export default class MultiFilePatchController extends React.Component { }); } - async discardRows(rowSet, nextSelectionMode, {eventSource} = {}) { + discardRows = async (rowSet, nextSelectionMode, {eventSource} = {}) => { // (kuychaco) For now we only support discarding rows for MultiFilePatches that contain a single file patch // The only way to access this method from the UI is to be in a ChangedFileItem, which only has a single file patch // This check is duplicated in RootController#discardLines. We also want it here to prevent us from sending metrics @@ -208,7 +202,7 @@ export default class MultiFilePatchController extends React.Component { return this.props.discardLines(this.props.multiFilePatch, chosenRows, this.props.repository); } - selectedRowsChanged(rows, nextSelectionMode, nextMultipleFileSelections) { + selectedRowsChanged = (rows, nextSelectionMode, nextMultipleFileSelections) => { if ( equalSets(this.state.selectedRows, rows) && this.state.selectionMode === nextSelectionMode && diff --git a/lib/controllers/remote-controller.js b/lib/controllers/remote-controller.js index f97f64e16c..da9197d3d1 100644 --- a/lib/controllers/remote-controller.js +++ b/lib/controllers/remote-controller.js @@ -2,7 +2,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import {shell} from 'electron'; -import {autobind} from '../helpers'; import {incrementCounter} from '../reporter-proxy'; import {RemotePropType, RemoteSetPropType, BranchSetPropType, OperationStateObserverPropType} from '../prop-types'; import IssueishSearchesController from './issueish-searches-controller'; @@ -33,11 +32,6 @@ export default class RemoteController extends React.Component { onPushBranch: PropTypes.func.isRequired, } - constructor(props) { - super(props); - autobind(this, 'onCreatePr'); - } - render() { return ( { const currentBranch = this.props.branches.getHeadBranch(); const upstream = currentBranch.getUpstream(); if (!upstream.isPresent() || this.props.aheadCount > 0) { diff --git a/lib/controllers/root-controller.js b/lib/controllers/root-controller.js index d3431a2321..e25b6f2e2d 100644 --- a/lib/controllers/root-controller.js +++ b/lib/controllers/root-controller.js @@ -28,7 +28,7 @@ import GitCacheView from '../views/git-cache-view'; import Conflict from '../models/conflicts/conflict'; import Switchboard from '../switchboard'; import {WorkdirContextPoolPropType} from '../prop-types'; -import {destroyFilePatchPaneItems, destroyEmptyFilePatchPaneItems, autobind} from '../helpers'; +import {destroyFilePatchPaneItems, destroyEmptyFilePatchPaneItems} from '../helpers'; import {GitError} from '../git-shell-out-strategy'; import {incrementCounter, addEvent} from '../reporter-proxy'; @@ -65,15 +65,6 @@ export default class RootController extends React.Component { constructor(props, context) { super(props, context); - autobind( - this, - 'installReactDevTools', 'clearGithubToken', 'initializeRepo', 'showOpenIssueishDialog', - 'showWaterfallDiagnostics', 'showCacheDiagnostics', 'acceptClone', 'cancelClone', 'acceptInit', 'cancelInit', - 'acceptOpenIssueish', 'cancelOpenIssueish', 'destroyFilePatchPaneItems', - 'destroyEmptyFilePatchPaneItems', 'openCloneDialog', 'quietlySelectItem', 'viewUnstagedChangesForCurrentFile', - 'viewStagedChangesForCurrentFile', 'openFiles', 'getUnsavedFiles', 'ensureNoUnsavedFiles', - 'discardWorkDirChangesForPaths', 'discardLines', 'undoLastDiscard', 'refreshResolutionProgress', - ); this.state = { cloneDialogActive: false, @@ -452,7 +443,7 @@ export default class RootController extends React.Component { } } - async installReactDevTools() { + installReactDevTools = async () => { // Prevent electron-link from attempting to descend into electron-devtools-installer, which is not available // when we're bundled in Atom. const devToolsName = 'electron-devtools-installer'; @@ -506,11 +497,9 @@ export default class RootController extends React.Component { } } - clearGithubToken() { - return this.props.loginModel.removeToken('https://api.github.com'); - } + clearGithubToken = () => this.props.loginModel.removeToken('https://api.github.com') - initializeRepo(initDialogPath) { + initializeRepo = initDialogPath => { if (this.state.initDialogActive) { return null; } @@ -529,23 +518,15 @@ export default class RootController extends React.Component { return this.props.workspace.toggle(CommitPreviewItem.buildURI(workdir)); } - showOpenIssueishDialog() { - this.setState({openIssueishDialogActive: true}); - } + showOpenIssueishDialog = () => new Promise(resolve => this.setState({openIssueishDialogActive: true}, resolve)) - showOpenCommitDialog = () => { - this.setState({openCommitDialogActive: true}); - } + showOpenCommitDialog = () => new Promise(resolve => this.setState({openCommitDialogActive: true}, resolve)) - showWaterfallDiagnostics() { - this.props.workspace.open(GitTimingsView.buildURI()); - } + showWaterfallDiagnostics = () => this.props.workspace.open(GitTimingsView.buildURI()) - showCacheDiagnostics() { - this.props.workspace.open(GitCacheView.buildURI()); - } + showCacheDiagnostics = () => this.props.workspace.open(GitCacheView.buildURI()) - async acceptClone(remoteUrl, projectPath) { + acceptClone = async (remoteUrl, projectPath) => { this.setState({cloneDialogInProgress: true}); try { await this.props.cloneRepositoryForProjectPath(remoteUrl, projectPath); @@ -560,11 +541,9 @@ export default class RootController extends React.Component { } } - cancelClone() { - this.setState({cloneDialogActive: false}); - } + cancelClone = () => new Promise(resolve => this.setState({cloneDialogActive: false}, resolve)) - async acceptInit(projectPath) { + acceptInit = async projectPath => { try { await this.props.createRepositoryForProjectPath(projectPath); if (this.state.initDialogResolve) { this.state.initDialogResolve(projectPath); } @@ -578,12 +557,14 @@ export default class RootController extends React.Component { } } - cancelInit() { + cancelInit = () => { if (this.state.initDialogResolve) { this.state.initDialogResolve(false); } - this.setState({initDialogActive: false, initDialogPath: null, initDialogResolve: null}); + return new Promise(resolve => { + this.setState({initDialogActive: false, initDialogPath: null, initDialogResolve: null}, resolve); + }); } - acceptOpenIssueish({repoOwner, repoName, issueishNumber}) { + acceptOpenIssueish = ({repoOwner, repoName, issueishNumber}) => { const uri = IssueishDetailItem.buildURI('https://api.github.com', repoOwner, repoName, issueishNumber); this.setState({openIssueishDialogActive: false}); this.props.workspace.open(uri).then(() => { @@ -591,9 +572,7 @@ export default class RootController extends React.Component { }); } - cancelOpenIssueish() { - this.setState({openIssueishDialogActive: false}); - } + cancelOpenIssueish = () => new Promise(resolve => this.setState({openIssueishDialogActive: false}, resolve)) isValidCommit = async ref => { try { @@ -636,19 +615,13 @@ export default class RootController extends React.Component { return gitTab && gitTab.focusAndSelectRecentCommit(); } - destroyFilePatchPaneItems() { - destroyFilePatchPaneItems({onlyStaged: false}, this.props.workspace); - } + destroyFilePatchPaneItems = () => destroyFilePatchPaneItems({onlyStaged: false}, this.props.workspace) - destroyEmptyFilePatchPaneItems() { - destroyEmptyFilePatchPaneItems(this.props.workspace); - } + destroyEmptyFilePatchPaneItems = () => destroyEmptyFilePatchPaneItems(this.props.workspace) - openCloneDialog() { - this.setState({cloneDialogActive: true}); - } + openCloneDialog = () => new Promise(resolve => this.setState({cloneDialogActive: true}, resolve)) - quietlySelectItem(filePath, stagingStatus) { + quietlySelectItem = (filePath, stagingStatus) => { const gitTab = this.gitTabTracker.getComponent(); return gitTab && gitTab.quietlySelectItem(filePath, stagingStatus); } @@ -705,22 +678,18 @@ export default class RootController extends React.Component { } } - viewUnstagedChangesForCurrentFile() { - return this.viewChangesForCurrentFile('unstaged'); - } + viewUnstagedChangesForCurrentFile = () => this.viewChangesForCurrentFile('unstaged') - viewStagedChangesForCurrentFile() { - return this.viewChangesForCurrentFile('staged'); - } + viewStagedChangesForCurrentFile = () => this.viewChangesForCurrentFile('staged') - openFiles(filePaths, repository = this.props.repository) { + openFiles = (filePaths, repository = this.props.repository) => { return Promise.all(filePaths.map(filePath => { const absolutePath = path.join(repository.getWorkingDirectoryPath(), filePath); return this.props.workspace.open(absolutePath, {pending: filePaths.length === 1}); })); } - getUnsavedFiles(filePaths, workdirPath) { + getUnsavedFiles = (filePaths, workdirPath) => { const isModifiedByPath = new Map(); this.props.workspace.getTextEditors().forEach(editor => { isModifiedByPath.set(editor.getPath(), editor.isModified()); @@ -731,7 +700,7 @@ export default class RootController extends React.Component { }); } - ensureNoUnsavedFiles(filePaths, message, workdirPath = this.props.repository.getWorkingDirectoryPath()) { + ensureNoUnsavedFiles = (filePaths, message, workdirPath = this.props.repository.getWorkingDirectoryPath()) => { const unsavedFiles = this.getUnsavedFiles(filePaths, workdirPath).map(filePath => `\`${filePath}\``).join('
'); if (unsavedFiles.length) { this.props.notificationManager.addError( @@ -747,7 +716,7 @@ export default class RootController extends React.Component { } } - async discardWorkDirChangesForPaths(filePaths) { + discardWorkDirChangesForPaths = async filePaths => { const destructiveAction = () => { return this.props.repository.discardWorkDirChangesForPaths(filePaths); }; @@ -758,7 +727,7 @@ export default class RootController extends React.Component { ); } - async discardLines(multiFilePatch, lines, repository = this.props.repository) { + discardLines = async (multiFilePatch, lines, repository = this.props.repository) => { // (kuychaco) For now we only support discarding rows for MultiFilePatches that contain a single file patch // The only way to access this method from the UI is to be in a ChangedFileItem, which only has a single file patch if (multiFilePatch.getFilePatches().length !== 1) { @@ -786,7 +755,7 @@ export default class RootController extends React.Component { return lastSnapshots.map(snapshot => snapshot.filePath); } - async undoLastDiscard(partialDiscardFilePath = null, repository = this.props.repository) { + undoLastDiscard = async (partialDiscardFilePath = null, repository = this.props.repository) => { const filePaths = this.getFilePathsForLastDiscard(partialDiscardFilePath); try { const results = await repository.restoreLastDiscardInTempFiles( @@ -869,12 +838,10 @@ export default class RootController extends React.Component { /* * Asynchronously count the conflict markers present in a file specified by full path. */ - refreshResolutionProgress(fullPath) { + refreshResolutionProgress = fullPath => { const readStream = fs.createReadStream(fullPath, {encoding: 'utf8'}); - return new Promise(resolve => { - Conflict.countFromStream(readStream).then(count => { - this.props.resolutionProgress.reportMarkerCount(fullPath, count); - }); + return Conflict.countFromStream(readStream).then(count => { + this.props.resolutionProgress.reportMarkerCount(fullPath, count); }); } @@ -897,14 +864,13 @@ export default class RootController extends React.Component { class TabTracker { constructor(name, {getWorkspace, uri}) { - autobind(this, 'toggle', 'toggleFocus', 'ensureVisible'); this.name = name; this.getWorkspace = getWorkspace; this.uri = uri; } - async toggle() { + toggle = async () => { const focusToRestore = document.activeElement; let shouldRestoreFocus = false; @@ -929,7 +895,7 @@ class TabTracker { } } - async toggleFocus() { + toggleFocus = async () => { const hadFocus = this.hasFocus(); await this.ensureVisible(); @@ -944,7 +910,7 @@ class TabTracker { } } - async ensureVisible() { + ensureVisible = async () => { if (!this.isVisible()) { await this.reveal(); return true; diff --git a/lib/github-package.js b/lib/github-package.js index a0ed479710..e3d22f6788 100644 --- a/lib/github-package.js +++ b/lib/github-package.js @@ -6,7 +6,7 @@ import fs from 'fs-extra'; import React from 'react'; import ReactDom from 'react-dom'; -import {fileExists, autobind} from './helpers'; +import {fileExists} from './helpers'; import WorkdirCache from './models/workdir-cache'; import WorkdirContext from './models/workdir-context'; import WorkdirContextPool from './models/workdir-context-pool'; @@ -36,13 +36,6 @@ export default class GithubPackage { configDirPath, renderFn, loginModel, }) { - autobind( - this, - 'consumeStatusBar', 'createGitTimingsView', 'createIssueishPaneItemStub', 'createDockItemStub', - 'createFilePatchControllerStub', 'destroyGitTabItem', 'destroyGithubTabItem', 'createRepositoryForProjectPath', - 'cloneRepositoryForProjectPath', 'getRepositoryForWorkdir', 'scheduleActiveContextUpdate', - ); - this.workspace = workspace; this.project = project; this.commandRegistry = commandRegistry; @@ -312,7 +305,7 @@ export default class GithubPackage { await yardstick.flush(); } - consumeStatusBar(statusBar) { + consumeStatusBar = statusBar => { this.statusBar = statusBar; this.rerender(); } @@ -321,19 +314,19 @@ export default class GithubPackage { reporterProxy.setReporter(reporter); } - createGitTimingsView() { + createGitTimingsView = () => { return StubItem.create('git-timings-view', { title: 'GitHub Package Timings View', }, GitTimingsView.buildURI()); } - createIssueishPaneItemStub({uri}) { + createIssueishPaneItemStub = ({uri}) => { return StubItem.create('issueish-detail-item', { title: 'Issueish', }, uri); } - createDockItemStub({uri}) { + createDockItemStub = ({uri}) => { let item; switch (uri) { // always return an empty stub @@ -369,7 +362,7 @@ export default class GithubPackage { }, uri); } - createFilePatchControllerStub({uri} = {}) { + createFilePatchControllerStub = ({uri} = {}) => { const item = StubItem.create('git-file-patch-controller', { title: 'Diff', }, uri); @@ -399,7 +392,7 @@ export default class GithubPackage { return item; } - destroyGitTabItem() { + destroyGitTabItem = () => { if (this.gitTabStubItem) { this.gitTabStubItem.destroy(); this.gitTabStubItem = null; @@ -409,7 +402,7 @@ export default class GithubPackage { } } - destroyGithubTabItem() { + destroyGithubTabItem = () => { if (this.githubTabStubItem) { this.githubTabStubItem.destroy(); this.githubTabStubItem = null; @@ -419,7 +412,7 @@ export default class GithubPackage { } } - async createRepositoryForProjectPath(projectPath) { + createRepositoryForProjectPath = async projectPath => { await fs.mkdirs(projectPath); const repository = this.contextPool.add(projectPath).getRepository(); @@ -433,7 +426,7 @@ export default class GithubPackage { await this.scheduleActiveContextUpdate(); } - async cloneRepositoryForProjectPath(remoteUrl, projectPath) { + cloneRepositoryForProjectPath = async (remoteUrl, projectPath) => { const context = this.contextPool.getContext(projectPath); let repository; if (context.isPresent()) { @@ -452,7 +445,7 @@ export default class GithubPackage { await this.scheduleActiveContextUpdate(); } - getRepositoryForWorkdir(projectPath) { + getRepositoryForWorkdir = projectPath => { const loadingGuessRepo = Repository.loadingGuess({pipelineManager: this.pipelineManager}); return this.guessedContext ? loadingGuessRepo : this.contextPool.getContext(projectPath).getRepository(); } @@ -477,7 +470,7 @@ export default class GithubPackage { return this.switchboard; } - async scheduleActiveContextUpdate(savedState = {}) { + scheduleActiveContextUpdate = async (savedState = {}) => { this.switchboard.didScheduleActiveContextUpdate(); await this.activeContextQueue.push(this.updateActiveContext.bind(this, savedState), {parallel: false}); } diff --git a/lib/helpers.js b/lib/helpers.js index 74a77f9460..9fb1b7741f 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -9,15 +9,6 @@ import RefHolder from './models/ref-holder'; export const LINE_ENDING_REGEX = /\r?\n/; export const CO_AUTHOR_REGEX = /^co-authored-by. (.+?) <(.+?)>$/i; -export function autobind(self, ...methods) { - for (const method of methods) { - if (typeof self[method] !== 'function') { - throw new Error(`Unable to autobind method ${method}`); - } - self[method] = self[method].bind(self); - } -} - // Extract a subset of props chosen from a propTypes object from a component's props to pass to a different API. // // Usage: diff --git a/lib/items/changed-file-item.js b/lib/items/changed-file-item.js index bff241401c..5395beeb74 100644 --- a/lib/items/changed-file-item.js +++ b/lib/items/changed-file-item.js @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import {Emitter} from 'event-kit'; import {WorkdirContextPoolPropType} from '../prop-types'; -import {autobind} from '../helpers'; import ChangedFileContainer from '../containers/changed-file-container'; export default class ChangedFileItem extends React.Component { @@ -36,7 +35,6 @@ export default class ChangedFileItem extends React.Component { constructor(props) { super(props); - autobind(this, 'destroy'); this.emitter = new Emitter(); this.isDestroyed = false; @@ -61,7 +59,7 @@ export default class ChangedFileItem extends React.Component { return this.emitter.on('did-terminate-pending-state', callback); } - destroy() { + destroy = () => { /* istanbul ignore else */ if (!this.isDestroyed) { this.emitter.emit('did-destroy'); diff --git a/lib/items/issueish-detail-item.js b/lib/items/issueish-detail-item.js index 88c0bd78d3..06a3c084e8 100644 --- a/lib/items/issueish-detail-item.js +++ b/lib/items/issueish-detail-item.js @@ -2,7 +2,6 @@ import React, {Component} from 'react'; import PropTypes from 'prop-types'; import {Emitter} from 'event-kit'; -import {autobind} from '../helpers'; import {GithubLoginModelPropType, WorkdirContextPoolPropType} from '../prop-types'; import Repository from '../models/repository'; import IssueishDetailContainer from '../containers/issueish-detail-container'; @@ -36,7 +35,6 @@ export default class IssueishDetailItem extends Component { constructor(props) { super(props); - autobind(this, 'switchToIssueish', 'handleTitleChanged'); this.emitter = new Emitter(); this.title = `${this.props.owner}/${this.props.repo}#${this.props.issueishNumber}`; @@ -77,7 +75,7 @@ export default class IssueishDetailItem extends Component { ); } - async switchToIssueish(owner, repo, issueishNumber) { + switchToIssueish = async (owner, repo, issueishNumber) => { const pool = this.props.workdirContextPool; const prev = { owner: this.state.owner, @@ -116,7 +114,7 @@ export default class IssueishDetailItem extends Component { }); } - handleTitleChanged(title) { + handleTitleChanged = title => { if (this.title !== title) { this.title = title; this.emitter.emit('did-change-title', title); diff --git a/lib/models/list-selection.js b/lib/models/list-selection.js index 28bd87b9aa..d3eee6d815 100644 --- a/lib/models/list-selection.js +++ b/lib/models/list-selection.js @@ -1,11 +1,7 @@ -import {autobind} from '../helpers'; - const COPY = Symbol('copy'); export default class ListSelection { constructor(options = {}) { - autobind(this, 'isItemSelectable'); - if (options._copy !== COPY) { this.options = { isItemSelectable: options.isItemSelectable || (item => !!item), @@ -31,9 +27,7 @@ export default class ListSelection { }); } - isItemSelectable(item) { - return this.options.isItemSelectable(item); - } + isItemSelectable = item => this.options.isItemSelectable(item) setItems(items) { let newSelectionIndex; diff --git a/lib/models/style-calculator.js b/lib/models/style-calculator.js index 33a849dbcc..91ec7f6a99 100644 --- a/lib/models/style-calculator.js +++ b/lib/models/style-calculator.js @@ -1,11 +1,7 @@ import {CompositeDisposable} from 'event-kit'; -import {autobind} from '../helpers'; - export default class StyleCalculator { constructor(styles, config) { - autobind(this, 'updateStyles'); - this.styles = styles; this.config = config; } @@ -24,7 +20,7 @@ export default class StyleCalculator { return subscriptions; } - updateStyles(sourcePath, getStylesheetFn) { + updateStyles = (sourcePath, getStylesheetFn) => { const stylesheet = getStylesheetFn(this.config); this.styles.addStyleSheet(stylesheet, {sourcePath, priority: 0}); } diff --git a/lib/models/workdir-context.js b/lib/models/workdir-context.js index 3c29a405ee..f08a71ac99 100644 --- a/lib/models/workdir-context.js +++ b/lib/models/workdir-context.js @@ -4,7 +4,6 @@ import Repository from './repository'; import ResolutionProgress from './conflicts/resolution-progress'; import FileSystemChangeObserver from './file-system-change-observer'; import WorkspaceChangeObserver from './workspace-change-observer'; -import {autobind} from '../helpers'; const createRepoSym = Symbol('createRepo'); @@ -27,8 +26,6 @@ export default class WorkdirContext { * - `options.promptCallback`: Callback used to collect information interactively through Atom. */ constructor(directory, options = {}) { - autobind(this, 'repositoryChangedState'); - this.directory = directory; const {window: theWindow, workspace, promptCallback, pipelineManager} = options; @@ -91,7 +88,7 @@ export default class WorkdirContext { * The ResolutionProgress will be loaded before the change event is re-broadcast, but change observer modifications * will not be complete. */ - repositoryChangedState(payload) { + repositoryChangedState = payload => { if (this.destroyed) { return; } diff --git a/lib/models/workspace-change-observer.js b/lib/models/workspace-change-observer.js index 00546f8d65..13334b78a2 100644 --- a/lib/models/workspace-change-observer.js +++ b/lib/models/workspace-change-observer.js @@ -3,14 +3,11 @@ import {CompositeDisposable, Disposable, Emitter} from 'event-kit'; import {watchPath} from 'atom'; import EventLogger from './event-logger'; -import {autobind} from '../helpers'; export const FOCUS = Symbol('focus'); export default class WorkspaceChangeObserver { constructor(window, workspace, repository) { - autobind(this, 'observeTextEditor'); - this.window = window; this.repository = repository; this.workspace = workspace; @@ -135,7 +132,7 @@ export default class WorkspaceChangeObserver { } } - observeTextEditor(editor) { + observeTextEditor = editor => { const buffer = editor.getBuffer(); if (!this.observedBuffers.has(buffer)) { let lastPath = buffer.getPath(); diff --git a/lib/periodic-refresher.js b/lib/periodic-refresher.js index 806bd0def4..838d690e38 100644 --- a/lib/periodic-refresher.js +++ b/lib/periodic-refresher.js @@ -1,5 +1,3 @@ -import {autobind} from './helpers'; - const refreshMapPerUniqueId = new WeakMap(); export default class PeriodicRefresher { @@ -14,8 +12,6 @@ export default class PeriodicRefresher { } constructor(uniqueId, options) { - autobind(this, 'refreshNow'); - this.options = options; this._refreshesPerId = PeriodicRefresher.getRefreshMap(uniqueId); } @@ -37,7 +33,7 @@ export default class PeriodicRefresher { this._timer = setTimeout(this.refreshNow, this.options.interval()); } - refreshNow(force = false) { + refreshNow = (force = false) => { const currentId = this.options.getCurrentId(); const lastRefreshForId = this._refreshesPerId.get(currentId) || 0; const delta = performance.now() - lastRefreshForId; diff --git a/lib/views/accordion.js b/lib/views/accordion.js index dc35729400..790ff17301 100644 --- a/lib/views/accordion.js +++ b/lib/views/accordion.js @@ -1,8 +1,6 @@ import React, {Fragment} from 'react'; import PropTypes from 'prop-types'; -import {autobind} from '../helpers'; - export default class Accordion extends React.Component { static propTypes = { leftTitle: PropTypes.string.isRequired, @@ -26,7 +24,6 @@ export default class Accordion extends React.Component { constructor(props) { super(props); - autobind(this, 'toggle'); this.state = { expanded: true, @@ -95,7 +92,7 @@ export default class Accordion extends React.Component { ); } - toggle(e) { + toggle = e => { e.preventDefault(); return new Promise(resolve => { this.setState(prevState => ({expanded: !prevState.expanded}), resolve); diff --git a/lib/views/branch-menu-view.js b/lib/views/branch-menu-view.js index e81adf7254..1840453566 100644 --- a/lib/views/branch-menu-view.js +++ b/lib/views/branch-menu-view.js @@ -5,7 +5,6 @@ import cx from 'classnames'; import Commands, {Command} from '../atom/commands'; import {BranchPropType, BranchSetPropType} from '../prop-types'; import {GitError} from '../git-shell-out-strategy'; -import {autobind} from '../helpers'; export default class BranchMenuView extends React.Component { static propTypes = { @@ -24,7 +23,6 @@ export default class BranchMenuView extends React.Component { constructor(props, context) { super(props, context); - autobind(this, 'didSelectItem', 'createBranch', 'checkout', 'cancelCreateNewBranch'); this.state = { createNew: false, @@ -101,12 +99,12 @@ export default class BranchMenuView extends React.Component { ); } - async didSelectItem(event) { + didSelectItem = async event => { const branchName = event.target.value; await this.checkout(branchName); } - async createBranch() { + createBranch = async () => { if (this.state.createNew) { const branchName = this.editorElement.getModel().getText().trim(); await this.checkout(branchName, {createNew: true}); @@ -120,7 +118,7 @@ export default class BranchMenuView extends React.Component { } } - async checkout(branchName, options) { + checkout = async (branchName, options) => { this.editorElement.classList.remove('is-focused'); await new Promise(resolve => { this.setState({checkedOutBranch: branchName}, resolve); @@ -142,7 +140,5 @@ export default class BranchMenuView extends React.Component { } } - cancelCreateNewBranch() { - this.setState({createNew: false}); - } + cancelCreateNewBranch = () => new Promise(resolve => this.setState({createNew: false}, resolve)); } diff --git a/lib/views/changed-files-count-view.js b/lib/views/changed-files-count-view.js index be7b5ed2d5..247811d0aa 100644 --- a/lib/views/changed-files-count-view.js +++ b/lib/views/changed-files-count-view.js @@ -2,7 +2,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import Octicon from '../atom/octicon'; import {addEvent} from '../reporter-proxy'; -import {autobind} from '../helpers'; export default class ChangedFilesCountView extends React.Component { static propTypes = { @@ -17,12 +16,7 @@ export default class ChangedFilesCountView extends React.Component { didClick: () => {}, } - constructor(props) { - super(props); - autobind(this, 'handleClick'); - } - - handleClick() { + handleClick = () => { addEvent('click', {package: 'github', component: 'ChangedFileCountView'}); this.props.didClick(); } diff --git a/lib/views/clone-dialog.js b/lib/views/clone-dialog.js index 68d41854be..609899e00a 100644 --- a/lib/views/clone-dialog.js +++ b/lib/views/clone-dialog.js @@ -5,7 +5,6 @@ import url from 'url'; import path from 'path'; import Commands, {Command} from '../atom/commands'; -import {autobind} from '../helpers'; export default class CloneDialog extends React.Component { static propTypes = { @@ -24,7 +23,6 @@ export default class CloneDialog extends React.Component { constructor(props, context) { super(props, context); - autobind(this, 'clone', 'cancel', 'didChangeRemoteUrl', 'didChangeProjectPath', 'editorRefs'); this.state = { cloneDisabled: false, @@ -99,7 +97,7 @@ export default class CloneDialog extends React.Component { ); } - clone() { + clone = () => { if (this.getRemoteUrl().length === 0 || this.getProjectPath().length === 0) { return; } @@ -107,11 +105,9 @@ export default class CloneDialog extends React.Component { this.props.didAccept(this.getRemoteUrl(), this.getProjectPath()); } - cancel() { - this.props.didCancel(); - } + cancel = () => this.props.didCancel() - didChangeRemoteUrl() { + didChangeRemoteUrl = () => { if (!this.projectPathModified) { const name = path.basename(url.parse(this.getRemoteUrl()).pathname, '.git') || ''; @@ -125,12 +121,12 @@ export default class CloneDialog extends React.Component { this.setCloneEnablement(); } - didChangeProjectPath() { + didChangeProjectPath = () => { this.projectPathModified = true; this.setCloneEnablement(); } - editorRefs(baseName) { + editorRefs = baseName => { const elementName = `${baseName}Element`; const modelName = `${baseName}Editor`; const subName = `${baseName}Subs`; diff --git a/lib/views/co-author-form.js b/lib/views/co-author-form.js index 23d5f9f1ba..ccb8d4526d 100644 --- a/lib/views/co-author-form.js +++ b/lib/views/co-author-form.js @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import Author from '../models/author'; import Commands, {Command} from '../atom/commands'; -import {autobind} from '../helpers'; export default class CoAuthorForm extends React.Component { static propTypes = { @@ -20,7 +19,6 @@ export default class CoAuthorForm extends React.Component { constructor(props, context) { super(props, context); - autobind(this, 'confirm', 'cancel', 'onNameChange', 'onEmailChange', 'validate', 'focusFirstInput'); this.state = { name: this.props.name, @@ -74,25 +72,21 @@ export default class CoAuthorForm extends React.Component { ); } - confirm() { + confirm = () => { if (this.isInputValid()) { this.props.onSubmit(new Author(this.state.email, this.state.name)); } } - cancel() { + cancel = () => { this.props.onCancel(); } - onNameChange(e) { - this.setState({name: e.target.value}, this.validate); - } + onNameChange = e => this.setState({name: e.target.value}, this.validate) - onEmailChange(e) { - this.setState({email: e.target.value}, this.validate); - } + onEmailChange = e => this.setState({email: e.target.value}, this.validate) - validate() { + validate = () => { if (this.isInputValid()) { this.setState({submitDisabled: false}); } @@ -106,7 +100,5 @@ export default class CoAuthorForm extends React.Component { return this.state.name && this.state.email.includes('@'); } - focusFirstInput() { - this.nameInput.focus(); - } + focusFirstInput = () => this.nameInput.focus() } diff --git a/lib/views/commit-view.js b/lib/views/commit-view.js index a12b50f0c9..b4c87b9993 100644 --- a/lib/views/commit-view.js +++ b/lib/views/commit-view.js @@ -13,7 +13,7 @@ import Commands, {Command} from '../atom/commands'; import RefHolder from '../models/ref-holder'; import Author from '../models/author'; import ObserveModel from './observe-model'; -import {LINE_ENDING_REGEX, autobind} from '../helpers'; +import {LINE_ENDING_REGEX} from '../helpers'; import {AuthorPropType, UserStorePropType} from '../prop-types'; import {incrementCounter} from '../reporter-proxy'; @@ -65,12 +65,6 @@ export default class CommitView extends React.Component { constructor(props, context) { super(props, context); - autobind( - this, - 'submitNewCoAuthor', 'cancelNewCoAuthor', 'didMoveCursor', 'toggleHardWrap', - 'toggleCoAuthorInput', 'abortMerge', 'commit', 'amendLastCommit', 'toggleExpandedCommitMessageEditor', - 'renderCoAuthorListItem', 'onSelectedCoAuthorsChanged', 'excludeCoAuthor', - ); this.state = { showWorking: false, @@ -366,14 +360,12 @@ export default class CommitView extends React.Component { ); } - submitNewCoAuthor(newAuthor) { + submitNewCoAuthor = newAuthor => { this.props.updateSelectedCoAuthors(this.props.selectedCoAuthors, newAuthor); this.hideNewAuthorForm(); } - cancelNewCoAuthor() { - this.hideNewAuthorForm(); - } + cancelNewCoAuthor = () => this.hideNewAuthorForm() hideNewAuthorForm() { this.setState({showCoAuthorForm: false}, () => { @@ -390,16 +382,14 @@ export default class CommitView extends React.Component { this.subs.dispose(); } - didMoveCursor() { - this.forceUpdate(); - } + didMoveCursor = () => this.forceUpdate() - toggleHardWrap() { + toggleHardWrap = () => { const currentSetting = this.props.config.get('github.automaticCommitMessageWrapping'); this.props.config.set('github.automaticCommitMessageWrapping', !currentSetting); } - toggleCoAuthorInput() { + toggleCoAuthorInput = () => { this.setState({ showCoAuthorInput: !this.state.showCoAuthorInput, }, () => { @@ -414,7 +404,7 @@ export default class CommitView extends React.Component { }); } - excludeCoAuthor() { + excludeCoAuthor = () => { const author = this.refCoAuthorSelect.map(c => c.getFocusedOption()).getOr(null); if (!author || author.isNew()) { return; @@ -428,11 +418,11 @@ export default class CommitView extends React.Component { this.props.config.set('github.excludedUsers', excluded); } - abortMerge() { + abortMerge = () => { this.props.abortMerge(); } - async commit(event, amend) { + commit = async (_event, amend) => { if (await this.props.prepareToCommit() && this.commitIsEnabled(amend)) { try { await this.props.commit(this.props.messageBuffer.getText(), this.props.selectedCoAuthors, amend); @@ -447,7 +437,7 @@ export default class CommitView extends React.Component { } } - amendLastCommit() { + amendLastCommit = () => { incrementCounter('amend'); this.commit(null, true); } @@ -509,7 +499,7 @@ export default class CommitView extends React.Component { } } - toggleExpandedCommitMessageEditor() { + toggleExpandedCommitMessageEditor = () => { return this.props.toggleExpandedCommitMessageEditor(this.props.messageBuffer.getText()); } @@ -538,7 +528,7 @@ export default class CommitView extends React.Component { ); } - renderCoAuthorListItem(author) { + renderCoAuthorListItem = author => { return (
{this.renderCoAuthorListItemField('name', author.getFullName())} @@ -560,7 +550,7 @@ export default class CommitView extends React.Component { return {author.getEmail()}; } - onSelectedCoAuthorsChanged(selectedCoAuthors) { + onSelectedCoAuthorsChanged = selectedCoAuthors => { incrementCounter('selected-co-authors-changed'); const newAuthor = selectedCoAuthors.find(author => author.isNew()); diff --git a/lib/views/credential-dialog.js b/lib/views/credential-dialog.js index f363021991..68d8e2a5c2 100644 --- a/lib/views/credential-dialog.js +++ b/lib/views/credential-dialog.js @@ -2,7 +2,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import Commands, {Command} from '../atom/commands'; -import {autobind} from '../helpers'; export default class CredentialDialog extends React.Component { static propTypes = { @@ -23,8 +22,6 @@ export default class CredentialDialog extends React.Component { constructor(props, context) { super(props, context); - autobind(this, 'confirm', 'cancel', 'onUsernameChange', 'onPasswordChange', 'onRememberChange', - 'focusFirstInput', 'toggleShowPassword'); this.state = { username: '', @@ -94,7 +91,7 @@ export default class CredentialDialog extends React.Component { ); } - confirm() { + confirm = () => { const payload = {password: this.state.password}; if (this.props.includeUsername) { @@ -108,27 +105,15 @@ export default class CredentialDialog extends React.Component { this.props.onSubmit(payload); } - cancel() { - this.props.onCancel(); - } + cancel = () => this.props.onCancel() - onUsernameChange(e) { - this.setState({username: e.target.value}); - } + onUsernameChange = e => this.setState({username: e.target.value}) - onPasswordChange(e) { - this.setState({password: e.target.value}); - } + onPasswordChange = e => this.setState({password: e.target.value}) - onRememberChange(e) { - this.setState({remember: e.target.checked}); - } + onRememberChange = e => this.setState({remember: e.target.checked}) - focusFirstInput() { - (this.usernameInput || this.passwordInput).focus(); - } + focusFirstInput = () => (this.usernameInput || this.passwordInput).focus() - toggleShowPassword() { - this.setState({showPassword: !this.state.showPassword}); - } + toggleShowPassword = () => this.setState({showPassword: !this.state.showPassword}) } diff --git a/lib/views/donut-chart.js b/lib/views/donut-chart.js index a92b8f2a71..f6e3bce2bb 100644 --- a/lib/views/donut-chart.js +++ b/lib/views/donut-chart.js @@ -1,8 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import {autobind} from '../helpers'; - export default class DonutChart extends React.Component { static propTypes = { baseOffset: PropTypes.number, @@ -19,11 +17,6 @@ export default class DonutChart extends React.Component { baseOffset: 25, } - constructor(props) { - super(props); - autobind(this, 'renderArc'); - } - render() { const {slices, baseOffset, ...others} = this.props; // eslint-disable-line no-unused-vars const arcs = this.calculateArcs(slices); @@ -50,7 +43,7 @@ export default class DonutChart extends React.Component { }); } - renderArc({length, position, type, className}) { + renderArc = ({length, position, type, className}) => { return ( @@ -42,7 +34,7 @@ export default class ErrorView extends React.Component { ); } - renderDescription(description, key) { + renderDescription = (description, key) => { if (this.props.preformatted) { return (
diff --git a/lib/views/git-cache-view.js b/lib/views/git-cache-view.js
index e99925c857..f1062c3a6d 100644
--- a/lib/views/git-cache-view.js
+++ b/lib/views/git-cache-view.js
@@ -3,7 +3,6 @@ import PropTypes from 'prop-types';
 import {inspect} from 'util';
 
 import ObserveModel from './observe-model';
-import {autobind} from '../helpers';
 
 const sortOrders = {
   'by key': (a, b) => a.key.localeCompare(b.key),
@@ -26,7 +25,6 @@ export default class GitCacheView extends React.Component {
 
   constructor(props, context) {
     super(props, context);
-    autobind(this, 'fetchRepositoryData', 'fetchCacheData', 'renderCache', 'didSelectItem', 'clearCache');
 
     this.state = {
       order: 'by key',
@@ -45,11 +43,11 @@ export default class GitCacheView extends React.Component {
     return null;
   }
 
-  fetchRepositoryData(repository) {
+  fetchRepositoryData = repository => {
     return repository.getCache();
   }
 
-  fetchCacheData(cache) {
+  fetchCacheData = cache => {
     const cached = {};
     const promises = [];
     const now = performance.now();
@@ -85,7 +83,7 @@ export default class GitCacheView extends React.Component {
     );
   }
 
-  renderCache(contents) {
+  renderCache = contents => {
     const rows = Object.keys(contents || {}).map(key => {
       return {
         key,
@@ -188,7 +186,7 @@ export default class GitCacheView extends React.Component {
     return parts.slice(parts.length - 2).join(' ');
   }
 
-  didSelectItem(event) {
+  didSelectItem = event => {
     this.setState({order: event.target.value});
   }
 
@@ -201,7 +199,7 @@ export default class GitCacheView extends React.Component {
     cache.removePrimary(key);
   }
 
-  clearCache() {
+  clearCache = () => {
     const cache = this.props.repository.getCache();
     if (!cache) {
       return;
diff --git a/lib/views/git-tab-view.js b/lib/views/git-tab-view.js
index 4ec74fde66..24981575c0 100644
--- a/lib/views/git-tab-view.js
+++ b/lib/views/git-tab-view.js
@@ -8,7 +8,7 @@ import GitLogo from './git-logo';
 import CommitController from '../controllers/commit-controller';
 import RecentCommitsController from '../controllers/recent-commits-controller';
 import RefHolder from '../models/ref-holder';
-import {isValidWorkdir, autobind} from '../helpers';
+import {isValidWorkdir} from '../helpers';
 import {AuthorPropType, UserStorePropType, RefHolderPropType} from '../prop-types';
 
 export default class GitTabView extends React.Component {
@@ -65,7 +65,6 @@ export default class GitTabView extends React.Component {
 
   constructor(props, context) {
     super(props, context);
-    autobind(this, 'initializeRepo', 'blur', 'advanceFocus', 'retreatFocus', 'quietlySelectItem');
 
     this.subscriptions = new CompositeDisposable();
 
@@ -211,7 +210,7 @@ export default class GitTabView extends React.Component {
     this.subscriptions.dispose();
   }
 
-  initializeRepo(event) {
+  initializeRepo = event => {
     event.preventDefault();
     let initPath = null;
     const activeEditor = this.props.workspace.getActiveTextEditor();
@@ -243,11 +242,9 @@ export default class GitTabView extends React.Component {
     return false;
   }
 
-  blur() {
-    this.props.workspace.getCenter().activate();
-  }
+  blur = () => this.props.workspace.getCenter().activate()
 
-  async advanceFocus(evt) {
+  advanceFocus = async evt => {
     const currentFocus = this.getFocus(document.activeElement);
     let nextSeen = false;
 
@@ -263,7 +260,7 @@ export default class GitTabView extends React.Component {
     }
   }
 
-  async retreatFocus(evt) {
+  retreatFocus = async evt => {
     const currentFocus = this.getFocus(document.activeElement);
     let previousSeen = false;
 
@@ -292,7 +289,7 @@ export default class GitTabView extends React.Component {
     this.setFocus(GitTabView.focus.COMMIT_PREVIEW_BUTTON);
   }
 
-  quietlySelectItem(filePath, stagingStatus) {
+  quietlySelectItem = (filePath, stagingStatus) => {
     return this.props.refStagingView.map(view => view.quietlySelectItem(filePath, stagingStatus)).getOr(false);
   }
 
diff --git a/lib/views/git-timings-view.js b/lib/views/git-timings-view.js
index 6f1b6b88ce..bac6359a00 100644
--- a/lib/views/git-timings-view.js
+++ b/lib/views/git-timings-view.js
@@ -9,7 +9,6 @@ import memoize from 'lodash.memoize';
 import fs from 'fs-extra';
 
 import Octicon from '../atom/octicon';
-import {autobind} from '../helpers';
 
 const genArray = memoize(function genArray(interval, count) {
   const arr = [];
@@ -104,11 +103,6 @@ class MarkerSpan extends React.Component {
     marker: PropTypes.instanceOf(Marker).isRequired,
   }
 
-  constructor(props) {
-    super(props);
-    autobind(this, 'handleMouseOver', 'handleMouseOut');
-  }
-
   render() {
     const {marker, ...others} = this.props;
     const timings = marker.getTimings();
@@ -134,7 +128,7 @@ class MarkerSpan extends React.Component {
     );
   }
 
-  handleMouseOver(e) {
+  handleMouseOver = e => {
     const elem = document.createElement('div');
     ReactDom.render(, elem);
     this.tooltipDisposable = atom.tooltips.add(this.element, {
@@ -149,7 +143,7 @@ class MarkerSpan extends React.Component {
     this.tooltipDisposable = null;
   }
 
-  handleMouseOut(e) {
+  handleMouseOut = e => {
     this.closeTooltip();
   }
 
@@ -167,7 +161,6 @@ class Waterfall extends React.Component {
 
   constructor(props, context) {
     super(props, context);
-    autobind(this, 'renderMarker');
     this.state = this.getNextState(props);
   }
 
@@ -239,7 +232,7 @@ class Waterfall extends React.Component {
     );
   }
 
-  renderMarker(marker, i) {
+  renderMarker = (marker, i) => {
     if (marker.getStart() === null || marker.getEnd() === null) { return 
; } const startOffset = marker.getStart() - this.state.startTime; @@ -268,7 +261,6 @@ class WaterfallWidget extends React.Component { constructor(props, context) { super(props, context); - autobind(this, 'handleZoomFactorChange', 'handleCollapseClick', 'handleExportClick'); this.state = { zoomFactor: 0.3, collapsed: false, @@ -314,15 +306,11 @@ class WaterfallWidget extends React.Component { ); } - handleZoomFactorChange(e) { - this.setState({zoomFactor: parseFloat(e.target.value)}); - } + handleZoomFactorChange = e => this.setState({zoomFactor: parseFloat(e.target.value)}) - handleCollapseClick(e) { - this.setState(s => ({collapsed: !s.collapsed})); - } + handleCollapseClick = () => this.setState(s => ({collapsed: !s.collapsed})) - handleExportClick(e) { + handleExportClick = e => { e.preventDefault(); const json = JSON.stringify(this.props.markers.map(m => m.serialize()), null, ' '); const buffer = new TextBuffer({text: json}); @@ -391,11 +379,6 @@ export default class GitTimingsView extends React.Component { return GitTimingsView.emitter.on('did-update', callback); } - constructor(props) { - super(props); - autobind(this, 'handleImportClick'); - } - componentDidMount() { this.subscriptions = new CompositeDisposable( GitTimingsView.onDidUpdate(() => this.forceUpdate()), @@ -419,7 +402,7 @@ export default class GitTimingsView extends React.Component { ); } - handleImportClick(e) { + handleImportClick = e => { e.preventDefault(); dialog.showOpenDialog({ properties: ['openFile'], diff --git a/lib/views/github-dotcom-markdown.js b/lib/views/github-dotcom-markdown.js index 5af7dfb7bd..4a5b1bb14a 100644 --- a/lib/views/github-dotcom-markdown.js +++ b/lib/views/github-dotcom-markdown.js @@ -8,7 +8,6 @@ import {handleClickEvent, openIssueishLinkInNewTab, openLinkInBrowser, getDataFr import UserMentionTooltipItem from '../items/user-mention-tooltip-item'; import IssueishTooltipItem from '../items/issueish-tooltip-item'; import RelayEnvironment from './relay-environment'; -import {autobind} from '../helpers'; export class BareGithubDotcomMarkdown extends React.Component { static propTypes = { @@ -26,11 +25,6 @@ export class BareGithubDotcomMarkdown extends React.Component { openLinkInBrowser, } - constructor(props) { - super(props); - autobind(this, 'handleClick', 'openLinkInNewTab', 'openLinkInThisTab', 'openLinkInBrowser'); - } - componentDidMount() { this.commandSubscriptions = atom.commands.add(ReactDom.findDOMNode(this), { 'github:open-link-in-new-tab': this.openLinkInNewTab, @@ -96,7 +90,7 @@ export class BareGithubDotcomMarkdown extends React.Component { ); } - handleClick(event) { + handleClick = event => { if (event.target.dataset.url) { return this.props.handleClickEvent(event, event.target.dataset.url); } else { @@ -104,18 +98,14 @@ export class BareGithubDotcomMarkdown extends React.Component { } } - openLinkInNewTab(event) { - return this.props.openIssueishLinkInNewTab(event.target.dataset.url); - } + openLinkInNewTab = event => this.props.openIssueishLinkInNewTab(event.target.dataset.url) - openLinkInThisTab(event) { + openLinkInThisTab = event => { const {repoOwner, repoName, issueishNumber} = getDataFromGithubUrl(event.target.dataset.url); this.props.switchToIssueish(repoOwner, repoName, issueishNumber); } - openLinkInBrowser(event) { - return this.props.openLinkInBrowser(event.target.getAttribute('href')); - } + openLinkInBrowser = event => this.props.openLinkInBrowser(event.target.getAttribute('href')) } export default class GithubDotcomMarkdown extends React.Component { diff --git a/lib/views/github-login-view.js b/lib/views/github-login-view.js index e959d06576..0017cead30 100644 --- a/lib/views/github-login-view.js +++ b/lib/views/github-login-view.js @@ -1,8 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import {autobind} from '../helpers'; - export default class GithubLoginView extends React.Component { static propTypes = { children: PropTypes.node, @@ -11,15 +9,11 @@ export default class GithubLoginView extends React.Component { static defaultProps = { children:

Log in to GitHub to access PR information and more!

, - onLogin: token => {}, + onLogin: () => {}, } constructor(props, context) { super(props, context); - autobind( - this, - 'handleLoginClick', 'handleCancelTokenClick', 'handleSubmitTokenClick', 'handleSubmitToken', 'handleTokenChange', - ); this.state = { loggingIn: false, token: '', @@ -83,25 +77,19 @@ export default class GithubLoginView extends React.Component { ); } - handleLoginClick() { - this.setState({loggingIn: true}); - } + handleLoginClick = () => new Promise(resolve => this.setState({loggingIn: true}, resolve)) - handleCancelTokenClick(e) { + handleCancelTokenClick = e => { e.preventDefault(); - this.setState({loggingIn: false}); + return new Promise(resolve => this.setState({loggingIn: false}, resolve)); } - handleSubmitTokenClick(e) { + handleSubmitTokenClick = e => { e.preventDefault(); this.handleSubmitToken(); } - handleSubmitToken() { - this.props.onLogin(this.state.token); - } + handleSubmitToken = () => this.props.onLogin(this.state.token) - handleTokenChange(e) { - this.setState({token: e.target.value}); - } + handleTokenChange = e => new Promise(resolve => this.setState({token: e.target.value}, resolve)) } diff --git a/lib/views/github-tile-view.js b/lib/views/github-tile-view.js index 64a5185105..0c6c29ee6d 100644 --- a/lib/views/github-tile-view.js +++ b/lib/views/github-tile-view.js @@ -3,19 +3,13 @@ import PropTypes from 'prop-types'; import Octicon from '../atom/octicon'; import {addEvent} from '../reporter-proxy'; -import {autobind} from '../helpers'; export default class GithubTileView extends React.Component { static propTypes = { didClick: PropTypes.func.isRequired, } - constructor(props) { - super(props); - autobind(this, 'handleClick'); - } - - handleClick() { + handleClick = () => { addEvent('click', {package: 'github', component: 'GithubTileView'}); this.props.didClick(); } diff --git a/lib/views/hunk-header-view.js b/lib/views/hunk-header-view.js index a2ed357015..72307bbb3b 100644 --- a/lib/views/hunk-header-view.js +++ b/lib/views/hunk-header-view.js @@ -2,7 +2,6 @@ import React, {Fragment} from 'react'; import PropTypes from 'prop-types'; import cx from 'classnames'; -import {autobind} from '../helpers'; import {RefHolderPropType} from '../prop-types'; import RefHolder from '../models/ref-holder'; import Tooltip from '../atom/tooltip'; @@ -36,7 +35,6 @@ export default class HunkHeaderView extends React.Component { constructor(props) { super(props); - autobind(this, 'didMouseDown', 'renderButtons'); this.refDiscardButton = new RefHolder(); } @@ -57,7 +55,7 @@ export default class HunkHeaderView extends React.Component { ); } - renderButtons() { + renderButtons = () => { if (this.props.itemType === CommitDetailItem) { return null; } else { @@ -90,7 +88,7 @@ export default class HunkHeaderView extends React.Component { } } - didMouseDown(event) { + didMouseDown = event => { return this.props.mouseDown(event, this.props.hunk); } } diff --git a/lib/views/init-dialog.js b/lib/views/init-dialog.js index 43985985e8..b80ae4a23b 100644 --- a/lib/views/init-dialog.js +++ b/lib/views/init-dialog.js @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import {CompositeDisposable} from 'event-kit'; import Commands, {Command} from '../atom/commands'; -import {autobind} from '../helpers'; export default class InitDialog extends React.Component { static propTypes = { @@ -21,7 +20,6 @@ export default class InitDialog extends React.Component { constructor(props, context) { super(props, context); - autobind(this, 'init', 'cancel', 'editorRef', 'setInitEnablement'); this.state = { initDisabled: false, @@ -70,7 +68,7 @@ export default class InitDialog extends React.Component { ); } - init() { + init = () => { if (this.getProjectPath().length === 0) { return; } @@ -78,11 +76,9 @@ export default class InitDialog extends React.Component { this.props.didAccept(this.getProjectPath()); } - cancel() { - this.props.didCancel(); - } + cancel = () => this.props.didCancel() - editorRef() { + editorRef = () => { return element => { if (!element) { return; @@ -112,7 +108,5 @@ export default class InitDialog extends React.Component { return this.remoteUrlEditor ? this.remoteUrlEditor.getText() : ''; } - setInitEnablement() { - this.setState({initDisabled: this.getProjectPath().length === 0}); - } + setInitEnablement = () => this.setState({initDisabled: this.getProjectPath().length === 0}) } diff --git a/lib/views/issueish-list-view.js b/lib/views/issueish-list-view.js index 8b9ba5e917..c26f9d2a4f 100644 --- a/lib/views/issueish-list-view.js +++ b/lib/views/issueish-list-view.js @@ -1,7 +1,6 @@ import React, {Fragment} from 'react'; import PropTypes from 'prop-types'; -import {autobind} from '../helpers'; import {IssueishPropType} from '../prop-types'; import Accordion from './accordion'; import Timeago from './timeago'; @@ -30,12 +29,6 @@ export default class IssueishListView extends React.Component { error: PropTypes.object, } - constructor(props) { - super(props); - - autobind(this, 'renderIssueish', 'renderLoadingTile', 'renderEmptyTile', 'renderMoreTile'); - } - render() { return ( { return ( ; } - renderLoadingTile() { + renderLoadingTile = () => { return (
Loading @@ -101,7 +94,7 @@ export default class IssueishListView extends React.Component { ); } - renderEmptyTile() { + renderEmptyTile = () => { if (this.props.error) { return ; } @@ -114,7 +107,7 @@ export default class IssueishListView extends React.Component { return null; } - renderMoreTile() { + renderMoreTile = () => { /* eslint-disable jsx-a11y/anchor-is-valid */ if (this.props.onMoreClick) { return ( diff --git a/lib/views/issueish-timeline-view.js b/lib/views/issueish-timeline-view.js index 6523173807..cbef881a6f 100644 --- a/lib/views/issueish-timeline-view.js +++ b/lib/views/issueish-timeline-view.js @@ -2,7 +2,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import {RelayConnectionPropType} from '../prop-types'; -import {autobind} from '../helpers'; import Octicon from '../atom/octicon'; import CommitsView from './timeline-items/commits-view.js'; import IssueCommentView from './timeline-items/issue-comment-view.js'; @@ -26,16 +25,11 @@ export function collectionRenderer(Component, styleAsTimelineItem = true) { return Component.getFragment(frag, ...args); } - constructor(props) { - super(props); - autobind(this, 'renderNode'); - } - render() { return
{this.props.nodes.map(this.renderNode)}
; } - renderNode(node, i) { + renderNode = (node, i) => { return ( { this.props.relay.loadMore(10, () => { this.forceUpdate(); }); diff --git a/lib/views/multi-file-patch-view.js b/lib/views/multi-file-patch-view.js index 5d1407e496..be2c0e5aa5 100644 --- a/lib/views/multi-file-patch-view.js +++ b/lib/views/multi-file-patch-view.js @@ -4,7 +4,6 @@ import cx from 'classnames'; import {Range} from 'atom'; import {CompositeDisposable} from 'event-kit'; -import {autobind} from '../helpers'; import {RefHolderPropType, MultiFilePatchPropType} from '../prop-types'; import AtomTextEditor from '../atom/atom-text-editor'; import Marker from '../atom/marker'; @@ -64,13 +63,6 @@ export default class MultiFilePatchView extends React.Component { constructor(props) { super(props); - autobind( - this, - 'didMouseDownOnHeader', 'didMouseDownOnLineNumber', 'didMouseMoveOnLineNumber', 'didMouseUp', - 'didConfirm', 'didToggleSelectionMode', 'selectNextHunk', 'selectPreviousHunk', - 'didOpenFile', 'didAddSelection', 'didChangeSelectionRange', 'didDestroySelection', - 'oldLineNumberLabel', 'newLineNumberLabel', - ); this.mouseSelectionInProgress = false; this.lastMouseMoveLine = null; @@ -108,7 +100,7 @@ export default class MultiFilePatchView extends React.Component { }); this.subs.add( - this.props.config.onDidChange('github.showDiffIconGutter', ({newValue}) => this.forceUpdate()), + this.props.config.onDidChange('github.showDiffIconGutter', () => this.forceUpdate()), ); } @@ -129,7 +121,7 @@ export default class MultiFilePatchView extends React.Component { return newSelectionRange; } - componentDidUpdate(prevProps, prevState, newSelectionRange) { + componentDidUpdate(prevProps, _prevState, newSelectionRange) { if (prevProps.refInitialFocus !== this.props.refInitialFocus) { prevProps.refInitialFocus && prevProps.refInitialFocus.setter(null); this.props.refInitialFocus && this.refEditorElement.map(this.props.refInitialFocus.setter); @@ -650,12 +642,12 @@ export default class MultiFilePatchView extends React.Component { } } - didMouseDownOnHeader(event, hunk) { + didMouseDownOnHeader = (event, hunk) => { this.nextSelectionMode = 'hunk'; this.handleSelectionEvent(event, hunk.getRange()); } - didMouseDownOnLineNumber(event) { + didMouseDownOnLineNumber = event => { const line = event.bufferRow; if (line === undefined || isNaN(line)) { return; @@ -667,7 +659,7 @@ export default class MultiFilePatchView extends React.Component { } } - didMouseMoveOnLineNumber(event) { + didMouseMoveOnLineNumber = event => { if (!this.mouseSelectionInProgress) { return; } @@ -682,7 +674,7 @@ export default class MultiFilePatchView extends React.Component { this.handleSelectionEvent(event.domEvent, [[line, 0], [line, Infinity]], {add: true}); } - didMouseUp() { + didMouseUp = () => { this.mouseSelectionInProgress = false; } @@ -790,11 +782,11 @@ export default class MultiFilePatchView extends React.Component { return true; } - didConfirm() { + didConfirm = () => { return this.props.toggleRows(this.props.selectedRows, this.props.selectionMode); } - didToggleSelectionMode() { + didToggleSelectionMode = () => { const selectedHunks = this.getSelectedHunks(); this.withSelectionMode({ line: () => { @@ -836,7 +828,7 @@ export default class MultiFilePatchView extends React.Component { ); } - selectNextHunk() { + selectNextHunk = () => { this.refEditor.map(editor => { const nextHunks = new Set( this.withSelectedHunks(hunk => this.getHunkAfter(hunk) || hunk), @@ -848,7 +840,7 @@ export default class MultiFilePatchView extends React.Component { }); } - selectPreviousHunk() { + selectPreviousHunk = () => { this.refEditor.map(editor => { const nextHunks = new Set( this.withSelectedHunks(hunk => this.getHunkBefore(hunk) || hunk), @@ -860,7 +852,7 @@ export default class MultiFilePatchView extends React.Component { }); } - didOpenFile({selectedFilePatch} = {}) { + didOpenFile = ({selectedFilePatch} = {}) => { const cursorsByFilePatch = new Map(); this.refEditor.map(editor => { @@ -949,11 +941,9 @@ export default class MultiFilePatchView extends React.Component { }).getOr(new Set()); } - didAddSelection() { - this.didChangeSelectedRows(); - } + didAddSelection = () => this.didChangeSelectedRows() - didChangeSelectionRange(event) { + didChangeSelectionRange = event => { if ( !event || event.oldBufferRange.start.row !== event.newBufferRange.start.row || @@ -963,9 +953,7 @@ export default class MultiFilePatchView extends React.Component { } } - didDestroySelection() { - this.didChangeSelectedRows(); - } + didDestroySelection = () => this.didChangeSelectedRows() didChangeSelectedRows() { if (this.suppressChanges) { @@ -984,7 +972,7 @@ export default class MultiFilePatchView extends React.Component { ); } - oldLineNumberLabel({bufferRow, softWrapped}) { + oldLineNumberLabel = ({bufferRow, softWrapped}) => { const hunk = this.props.multiFilePatch.getHunkAt(bufferRow); if (hunk === undefined) { return this.pad(''); @@ -998,7 +986,7 @@ export default class MultiFilePatchView extends React.Component { return this.pad(oldRow); } - newLineNumberLabel({bufferRow, softWrapped}) { + newLineNumberLabel = ({bufferRow, softWrapped}) => { const hunk = this.props.multiFilePatch.getHunkAt(bufferRow); if (hunk === undefined) { return this.pad(''); diff --git a/lib/views/observe-model.js b/lib/views/observe-model.js index 5bd8eb5e21..040862e220 100644 --- a/lib/views/observe-model.js +++ b/lib/views/observe-model.js @@ -2,7 +2,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import ModelObserver from '../models/model-observer'; -import {autobind} from '../helpers'; export default class ObserveModel extends React.Component { static propTypes = { @@ -15,7 +14,6 @@ export default class ObserveModel extends React.Component { constructor(props, context) { super(props, context); - autobind(this, 'fetchData', 'didUpdate'); this.state = {data: null}; this.modelObserver = new ModelObserver({fetchData: this.fetchData, didUpdate: this.didUpdate}); } @@ -29,11 +27,9 @@ export default class ObserveModel extends React.Component { this.modelObserver.setActiveModel(nextProps.model); } - fetchData(model) { - return this.props.fetchData(model); - } + fetchData = model => this.props.fetchData(model) - didUpdate(model) { + didUpdate = () => { if (this.mounted) { const data = this.modelObserver.getActiveModelData(); this.setState({data}); diff --git a/lib/views/open-issueish-dialog.js b/lib/views/open-issueish-dialog.js index dbd21ff04d..6098fb3ba1 100644 --- a/lib/views/open-issueish-dialog.js +++ b/lib/views/open-issueish-dialog.js @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import {CompositeDisposable} from 'event-kit'; import Commands, {Command} from '../atom/commands'; -import {autobind} from '../helpers'; const ISSUEISH_URL_REGEX = /^(?:https?:\/\/)?github.com\/([^/]+)\/([^/]+)\/(?:issues|pull)\/(\d+)/; @@ -21,7 +20,6 @@ export default class OpenIssueishDialog extends React.Component { constructor(props, context) { super(props, context); - autobind(this, 'accept', 'cancel', 'editorRefs', 'didChangeIssueishUrl'); this.state = { cloneDisabled: false, @@ -70,7 +68,7 @@ export default class OpenIssueishDialog extends React.Component { ); } - accept() { + accept = () => { if (this.getIssueishUrl().length === 0) { return; } @@ -87,11 +85,11 @@ export default class OpenIssueishDialog extends React.Component { this.props.didAccept({repoOwner, repoName, issueishNumber}); } - cancel() { + cancel = () => { this.props.didCancel(); } - editorRefs(baseName) { + editorRefs = baseName => { const elementName = `${baseName}Element`; const modelName = `${baseName}Editor`; const subName = `${baseName}Subs`; @@ -118,7 +116,7 @@ export default class OpenIssueishDialog extends React.Component { }; } - didChangeIssueishUrl() { + didChangeIssueishUrl = () => { this.setState({error: null}); } diff --git a/lib/views/pr-commit-view.js b/lib/views/pr-commit-view.js index 3ec3afc578..74b27d4f99 100644 --- a/lib/views/pr-commit-view.js +++ b/lib/views/pr-commit-view.js @@ -4,8 +4,6 @@ import {emojify} from 'node-emoji'; import moment from 'moment'; import {graphql, createFragmentContainer} from 'react-relay'; -import {autobind} from '../helpers'; - const avatarAltText = 'committer avatar'; export class PrCommitView extends React.Component { @@ -29,16 +27,11 @@ export class PrCommitView extends React.Component { constructor(props) { super(props); this.state = {showMessageBody: false}; - autobind(this, 'toggleShowCommitMessageBody', 'humanizeTimeSince'); } - toggleShowCommitMessageBody() { - this.setState({showMessageBody: !this.state.showMessageBody}); - } + toggleShowCommitMessageBody = () => this.setState({showMessageBody: !this.state.showMessageBody}) - humanizeTimeSince(date) { - return moment(date).fromNow(); - } + humanizeTimeSince = date => moment(date).fromNow() openCommitDetailItem = () => this.props.openCommit({sha: this.props.item.sha}) diff --git a/lib/views/pr-commits-view.js b/lib/views/pr-commits-view.js index 5398c58ad1..af8036f8cb 100644 --- a/lib/views/pr-commits-view.js +++ b/lib/views/pr-commits-view.js @@ -4,8 +4,6 @@ import {graphql, createPaginationContainer} from 'react-relay'; import {RelayConnectionPropType} from '../prop-types'; import PrCommitView from './pr-commit-view'; -import {autobind} from '../helpers'; - const PAGE_SIZE = 50; export class PrCommitsView extends React.Component { @@ -28,12 +26,7 @@ export class PrCommitsView extends React.Component { openCommit: PropTypes.func.isRequired, } - constructor(props) { - super(props); - autobind(this, 'loadMore'); - } - - loadMore() { + loadMore = () => { this.props.relay.loadMore(PAGE_SIZE, () => { this.forceUpdate(); }); diff --git a/lib/views/pr-statuses-view.js b/lib/views/pr-statuses-view.js index 96c68db617..200b758148 100644 --- a/lib/views/pr-statuses-view.js +++ b/lib/views/pr-statuses-view.js @@ -2,7 +2,7 @@ import React from 'react'; import {createRefetchContainer, graphql} from 'react-relay'; import PropTypes from 'prop-types'; -import {toSentence, autobind} from '../helpers'; +import {toSentence} from '../helpers'; import PrStatusContextView from './pr-status-context-view'; import Octicon from '../atom/octicon'; import StatusDonutChart from './status-donut-chart'; @@ -61,11 +61,6 @@ export class BarePrStatusesView extends React.Component { static PENDING_REFRESH_TIMEOUT = 30 * 1000 static MINIMUM_REFRESH_INTERVAL = 15 * 1000 - constructor(props) { - super(props); - autobind(this, 'refresh'); - } - componentDidMount() { this.refresher = new PeriodicRefresher(this.constructor, { interval: () => { @@ -86,7 +81,7 @@ export class BarePrStatusesView extends React.Component { this.refresher.destroy(); } - refresh() { + refresh = () => { this.props.relay.refetch({ id: this.props.pullRequest.id, }, null, null, {force: true}); diff --git a/lib/views/staging-view.js b/lib/views/staging-view.js index 474db1aaa0..6941f12aad 100644 --- a/lib/views/staging-view.js +++ b/lib/views/staging-view.js @@ -16,7 +16,6 @@ import CommitView from './commit-view'; import RefHolder from '../models/ref-holder'; import ChangedFileItem from '../items/changed-file-item'; import Commands, {Command} from '../atom/commands'; -import {autobind} from '../helpers'; import {addEvent} from '../reporter-proxy'; const debounce = (fn, wait) => { @@ -83,14 +82,6 @@ export default class StagingView extends React.Component { constructor(props) { super(props); - autobind( - this, - 'dblclickOnItem', 'contextMenuOnItem', 'mousedownOnItem', 'mousemoveOnItem', 'mouseup', 'registerItemElement', - 'renderBody', 'openFile', 'discardChanges', 'activateNextList', 'activatePreviousList', 'activateLastList', - 'stageAll', 'unstageAll', 'stageAllMergeConflicts', 'discardAll', 'confirmSelectedItems', 'selectAll', - 'selectFirst', 'selectLast', 'diveIntoSelection', 'showDiffView', 'showBulkResolveMenu', 'showActionsMenu', - 'resolveCurrentAsOurs', 'resolveCurrentAsTheirs', 'quietlySelectItem', 'didChangeSelectedItems', - ); this.subs = new CompositeDisposable( atom.config.observe('github.keyboardNavigationDelay', value => { @@ -194,7 +185,7 @@ export default class StagingView extends React.Component { ); } - renderBody() { + renderBody = () => { const selectedItems = this.state.selection.getSelectedItems(); return ( @@ -430,12 +421,12 @@ export default class StagingView extends React.Component { return this.getSelectedItemFilePaths(); } - openFile() { + openFile = () => { const filePaths = this.getSelectedItemFilePaths(); return this.props.openFiles(filePaths); } - discardChanges({eventSource} = {}) { + discardChanges = ({eventSource} = {}) => { const filePaths = this.getSelectedItemFilePaths(); addEvent('discard-unstaged-changes', { package: 'github', @@ -447,7 +438,7 @@ export default class StagingView extends React.Component { return this.props.discardWorkDirChangesForPaths(filePaths); } - activateNextList() { + activateNextList = () => { return new Promise(resolve => { let advanced = false; @@ -463,7 +454,7 @@ export default class StagingView extends React.Component { }); } - activatePreviousList() { + activatePreviousList = () => { return new Promise(resolve => { let retreated = false; this.setState(prevState => { @@ -478,7 +469,7 @@ export default class StagingView extends React.Component { }); } - activateLastList() { + activateLastList = () => { return new Promise(resolve => { let emptySelection = false; this.setState(prevState => { @@ -494,23 +485,23 @@ export default class StagingView extends React.Component { }); } - stageAll() { + stageAll = () => { if (this.props.unstagedChanges.length === 0) { return null; } return this.props.attemptStageAllOperation('unstaged'); } - unstageAll() { + unstageAll = () => { if (this.props.stagedChanges.length === 0) { return null; } return this.props.attemptStageAllOperation('staged'); } - stageAllMergeConflicts() { + stageAllMergeConflicts = () => { if (this.props.mergeConflicts.length === 0) { return null; } const filePaths = this.props.mergeConflicts.map(conflict => conflict.filePath); return this.props.attemptFileStageOperation(filePaths, 'unstaged'); } - discardAll({eventSource} = {}) { + discardAll = ({eventSource} = {}) => { if (this.props.unstagedChanges.length === 0) { return null; } const filePaths = this.props.unstagedChanges.map(filePatch => filePatch.filePath); addEvent('discard-unstaged-changes', { @@ -551,7 +542,7 @@ export default class StagingView extends React.Component { }); } - selectAll() { + selectAll = () => { return new Promise(resolve => { this.setState(prevState => ({ selection: prevState.selection.selectAllItems().coalesce(), @@ -559,7 +550,7 @@ export default class StagingView extends React.Component { }); } - selectFirst(preserveTail = false) { + selectFirst = (preserveTail = false) => { return new Promise(resolve => { this.setState(prevState => ({ selection: prevState.selection.selectFirstItem(preserveTail).coalesce(), @@ -567,7 +558,7 @@ export default class StagingView extends React.Component { }); } - selectLast(preserveTail = false) { + selectLast = (preserveTail = false) => { return new Promise(resolve => { this.setState(prevState => ({ selection: prevState.selection.selectLastItem(preserveTail).coalesce(), @@ -575,7 +566,7 @@ export default class StagingView extends React.Component { }); } - async diveIntoSelection() { + diveIntoSelection = async () => { const selectedItems = this.state.selection.getSelectedItems(); if (selectedItems.size !== 1) { return; @@ -611,7 +602,7 @@ export default class StagingView extends React.Component { } } - async showDiffView() { + showDiffView = async () => { const selectedItems = this.state.selection.getSelectedItems(); if (selectedItems.size !== 1) { return; @@ -627,7 +618,7 @@ export default class StagingView extends React.Component { } } - showBulkResolveMenu(event) { + showBulkResolveMenu = event => { const conflictPaths = this.props.mergeConflicts.map(c => c.filePath); event.preventDefault(); @@ -647,7 +638,7 @@ export default class StagingView extends React.Component { menu.popup(remote.getCurrentWindow()); } - showActionsMenu(event) { + showActionsMenu = event => { event.preventDefault(); const menu = new Menu(); @@ -676,18 +667,14 @@ export default class StagingView extends React.Component { menu.popup(remote.getCurrentWindow()); } - resolveCurrentAsOurs() { - this.props.resolveAsOurs(this.getSelectedConflictPaths()); - } + resolveCurrentAsOurs = () => this.props.resolveAsOurs(this.getSelectedConflictPaths()) - resolveCurrentAsTheirs() { - this.props.resolveAsTheirs(this.getSelectedConflictPaths()); - } + resolveCurrentAsTheirs = () => this.props.resolveAsTheirs(this.getSelectedConflictPaths()) // Directly modify the selection to include only the item identified by the file path and stagingStatus tuple. // Re-render the component, but don't notify didSelectSingleItem() or other callback functions. This is useful to // avoid circular callback loops for actions originating in FilePatchView or TextEditors with merge conflicts. - quietlySelectItem(filePath, stagingStatus) { + quietlySelectItem = (filePath, stagingStatus) => { return new Promise(resolve => { this.setState(prevState => { const item = prevState.selection.findItem((each, key) => each.filePath === filePath && key === stagingStatus); @@ -713,7 +700,7 @@ export default class StagingView extends React.Component { }); } - didChangeSelectedItems(openNew) { + didChangeSelectedItems = openNew => { const selectedItems = Array.from(this.state.selection.getSelectedItems()); if (selectedItems.length === 1) { this.didSelectSingleItem(selectedItems[0], openNew); @@ -814,11 +801,11 @@ export default class StagingView extends React.Component { return new File(absolutePath).exists(); } - dblclickOnItem(event, item) { + dblclickOnItem = (_event, item) => { return this.props.attemptFileStageOperation([item.filePath], this.state.selection.listKeyForItem(item)); } - async contextMenuOnItem(event, item) { + contextMenuOnItem = async (event, item) => { if (!this.state.selection.getSelectedItems().has(item)) { event.stopPropagation(); @@ -839,7 +826,7 @@ export default class StagingView extends React.Component { } } - async mousedownOnItem(event, item) { + mousedownOnItem = async (event, item) => { const windows = process.platform === 'win32'; if (event.ctrlKey && !windows) { return; } // simply open context menu if (event.button === 0) { @@ -860,7 +847,7 @@ export default class StagingView extends React.Component { } } - async mousemoveOnItem(event, item) { + mousemoveOnItem = async (_event, item) => { if (this.mouseSelectionInProgress) { await new Promise(resolve => { this.setState(prevState => ({ @@ -870,7 +857,7 @@ export default class StagingView extends React.Component { } } - async mouseup() { + mouseup = async () => { const hadSelectionInProgress = this.mouseSelectionInProgress; this.mouseSelectionInProgress = false; @@ -902,9 +889,7 @@ export default class StagingView extends React.Component { return this.state.selection.getActiveListKey() === listKey ? 'is-focused' : ''; } - registerItemElement(item, element) { - this.listElementsByItem.set(item, element); - } + registerItemElement = (item, element) => this.listElementsByItem.set(item, element) getFocus(element) { return this.refRoot.map(root => root.contains(element)).getOr(false) ? StagingView.focus.STAGING : null; diff --git a/lib/worker-manager.js b/lib/worker-manager.js index e6811314c4..b4c2d7426d 100644 --- a/lib/worker-manager.js +++ b/lib/worker-manager.js @@ -5,7 +5,7 @@ import {remote, ipcRenderer as ipc} from 'electron'; const {BrowserWindow} = remote; import {Emitter, Disposable, CompositeDisposable} from 'event-kit'; -import {getPackageRoot, autobind} from './helpers'; +import {getPackageRoot} from './helpers'; export default class WorkerManager { static instance = null; @@ -23,8 +23,6 @@ export default class WorkerManager { } constructor() { - autobind(this, 'onDestroyed', 'onCrashed', 'onSick'); - this.workers = new Set(); this.activeWorker = null; this.createNewWorker(); @@ -59,18 +57,18 @@ export default class WorkerManager { this.workers.add(this.activeWorker); } - onDestroyed(destroyedWorker) { + onDestroyed = destroyedWorker => { this.workers.delete(destroyedWorker); } - onCrashed(crashedWorker) { + onCrashed = crashedWorker => { if (crashedWorker === this.getActiveWorker()) { this.createNewWorker({operationCountLimit: crashedWorker.getOperationCountLimit()}); } crashedWorker.getRemainingOperations().forEach(operation => this.activeWorker.executeOperation(operation)); } - onSick(sickWorker) { + onSick = sickWorker => { if (!atom.inSpecMode()) { // eslint-disable-next-line no-console console.warn(`Sick worker detected. @@ -108,12 +106,6 @@ export class Worker { static channelName = 'github:renderer-ipc'; constructor({operationCountLimit, onSick, onCrashed, onDestroyed}) { - autobind( - this, - 'handleDataReceived', 'onOperationComplete', 'handleCancelled', 'handleExecStarted', 'handleSpawnError', - 'handleStdinError', 'handleSick', 'handleCrashed', - ); - this.operationCountLimit = operationCountLimit; this.onSick = onSick; this.onCrashed = onCrashed; @@ -166,7 +158,7 @@ export class Worker { return this.rendererProcess.cancelOperation(operation); } - handleDataReceived({id, results}) { + handleDataReceived = ({id, results}) => { const operation = this.operationsById.get(id); operation.complete(results, data => { const {timing} = data; @@ -177,7 +169,7 @@ export class Worker { }); } - onOperationComplete(operation) { + onOperationComplete = operation => { this.completedOperationCount++; this.operationsById.delete(operation.id); @@ -186,7 +178,7 @@ export class Worker { } } - handleCancelled({id}) { + handleCancelled = ({id}) => { const operation = this.operationsById.get(id); if (operation) { // handleDataReceived() can be received before handleCancelled() @@ -194,27 +186,27 @@ export class Worker { } } - handleExecStarted({id}) { + handleExecStarted = ({id}) => { const operation = this.operationsById.get(id); operation.setInProgress(); } - handleSpawnError({id, err}) { + handleSpawnError = ({id, err}) => { const operation = this.operationsById.get(id); operation.error(err); } - handleStdinError({id, stdin, err}) { + handleStdinError = ({id, err}) => { const operation = this.operationsById.get(id); operation.error(err); } - handleSick() { + handleSick = () => { this.sick = true; this.onSick(this); } - handleCrashed() { + handleCrashed = () => { this.onCrashed(this); this.destroy(); } @@ -257,7 +249,6 @@ Sends operations to renderer processes export class RendererProcess { constructor({loadUrl, onDestroyed, onCrashed, onSick, onData, onCancelled, onSpawnError, onStdinError, onExecStarted}) { - autobind(this, 'handleDestroy'); this.onDestroyed = onDestroyed; this.onCrashed = onCrashed; this.onSick = onSick; @@ -297,7 +288,7 @@ export class RendererProcess { return this.ready; } - handleDestroy(...args) { + handleDestroy = (...args) => { this.destroy(); this.onCrashed(...args); } diff --git a/test/async-queue.test.js b/test/async-queue.test.js index 7178673bc4..782be8f9c3 100644 --- a/test/async-queue.test.js +++ b/test/async-queue.test.js @@ -1,17 +1,14 @@ -import {autobind} from '../lib/helpers'; import AsyncQueue from '../lib/async-queue'; class Task { constructor(name, error) { - autobind(this, 'run', 'finish'); - this.name = name; this.error = error; this.started = false; this.finished = false; } - run() { + run = () => { this.started = true; this.finished = false; return new Promise((resolve, reject) => { @@ -20,7 +17,7 @@ class Task { }); } - finish() { + finish = () => { this.finished = true; if (this.error) { this.reject(new Error(this.name)); diff --git a/test/views/pr-commits-view.test.js b/test/views/pr-commits-view.test.js index 5b0cbf705e..ca107034e9 100644 --- a/test/views/pr-commits-view.test.js +++ b/test/views/pr-commits-view.test.js @@ -82,8 +82,8 @@ describe('PrCommitsView', function() { it('calls relay.loadMore when load more button is clicked', function() { const commitSpecs = [commitSpec, commitSpec]; - const loadMoreStub = sinon.stub(PrCommitsView.prototype, 'loadMore'); - const wrapper = shallow(buildApp({relayHasMore: () => true, commitSpecs})); + const loadMoreStub = sinon.stub().returns(true); + const wrapper = shallow(buildApp({relayHasMore: () => true, relayLoadMore: loadMoreStub, commitSpecs})); assert.strictEqual(loadMoreStub.callCount, 0); wrapper.find('.github-PrCommitsView-load-more-button').simulate('click'); assert.strictEqual(loadMoreStub.callCount, 1);