mirror of
https://github.com/quine-global/hyper.git
synced 2026-01-15 05:08:41 -09:00
Upgrade React to v16
* Introduce 2 base components: Component and PureComponent. Before, we have only PureComponent but it was impossible to add a shoulComponentUpdate method (used for Terms).
This commit is contained in:
parent
507fc28200
commit
f8366d010d
15 changed files with 103 additions and 107 deletions
69
lib/base-components.js
Normal file
69
lib/base-components.js
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
import React from 'react';
|
||||||
|
import {StyleSheet, css} from 'aphrodite-simple';
|
||||||
|
|
||||||
|
const decorateBaseComponent = Component => {
|
||||||
|
return class BaseComponent extends Component {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.styles_ = this.createStyleSheet();
|
||||||
|
this.cssHelper = this.cssHelper.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
createStyleSheet() {
|
||||||
|
if (!this.styles) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = this.styles();
|
||||||
|
|
||||||
|
if (typeof styles !== 'object') {
|
||||||
|
throw new TypeError('Component `styles` returns a non-object');
|
||||||
|
}
|
||||||
|
|
||||||
|
return StyleSheet.create(this.styles());
|
||||||
|
}
|
||||||
|
|
||||||
|
// wrap aphrodite's css helper for two reasons:
|
||||||
|
// - we can give the element an unaltered global classname
|
||||||
|
// that can be used to introduce global css side effects
|
||||||
|
// for example, through the configuration, web inspector
|
||||||
|
// or user agent extensions
|
||||||
|
// - the user doesn't need to keep track of both `css`
|
||||||
|
// and `style`, and we make that whole ordeal easier
|
||||||
|
cssHelper(...args) {
|
||||||
|
const classes = args
|
||||||
|
.map(c => {
|
||||||
|
if (c) {
|
||||||
|
// we compute the global name from the given
|
||||||
|
// css class and we prepend the component name
|
||||||
|
//
|
||||||
|
// it's important classes never get mangled by
|
||||||
|
// uglifiers so that we can avoid collisions
|
||||||
|
const component = this.constructor.name.toString().toLowerCase();
|
||||||
|
const globalName = `${component}_${c}`;
|
||||||
|
return [globalName, css(this.styles_[c])];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
// skip nulls
|
||||||
|
.filter(v => Boolean(v))
|
||||||
|
// flatten
|
||||||
|
.reduce((a, b) => a.concat(b));
|
||||||
|
return classes.length ? classes.join(' ') : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
// convert static objects from `babel-plugin-transform-jsx`
|
||||||
|
// to `React.Element`.
|
||||||
|
if (!this.template) {
|
||||||
|
throw new TypeError("Component doesn't define `template`");
|
||||||
|
}
|
||||||
|
|
||||||
|
// invoke the template creator passing our css helper
|
||||||
|
return this.template(this.cssHelper);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const PureComponent = decorateBaseComponent(React.PureComponent);
|
||||||
|
export const Component = decorateBaseComponent(React.Component);
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import {StyleSheet, css} from 'aphrodite-simple';
|
|
||||||
|
|
||||||
export default class Component extends React.PureComponent {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.styles_ = this.createStyleSheet();
|
|
||||||
this.cssHelper = this.cssHelper.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
createStyleSheet() {
|
|
||||||
if (!this.styles) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = this.styles();
|
|
||||||
|
|
||||||
if (typeof styles !== 'object') {
|
|
||||||
throw new TypeError('Component `styles` returns a non-object');
|
|
||||||
}
|
|
||||||
|
|
||||||
return StyleSheet.create(this.styles());
|
|
||||||
}
|
|
||||||
|
|
||||||
// wrap aphrodite's css helper for two reasons:
|
|
||||||
// - we can give the element an unaltered global classname
|
|
||||||
// that can be used to introduce global css side effects
|
|
||||||
// for example, through the configuration, web inspector
|
|
||||||
// or user agent extensions
|
|
||||||
// - the user doesn't need to keep track of both `css`
|
|
||||||
// and `style`, and we make that whole ordeal easier
|
|
||||||
cssHelper(...args) {
|
|
||||||
const classes = args
|
|
||||||
.map(c => {
|
|
||||||
if (c) {
|
|
||||||
// we compute the global name from the given
|
|
||||||
// css class and we prepend the component name
|
|
||||||
//
|
|
||||||
// it's important classes never get mangled by
|
|
||||||
// uglifiers so that we can avoid collisions
|
|
||||||
const component = this.constructor.name.toString().toLowerCase();
|
|
||||||
const globalName = `${component}_${c}`;
|
|
||||||
return [globalName, css(this.styles_[c])];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
})
|
|
||||||
// skip nulls
|
|
||||||
.filter(v => Boolean(v))
|
|
||||||
// flatten
|
|
||||||
.reduce((a, b) => a.concat(b));
|
|
||||||
return classes.length ? classes.join(' ') : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
// convert static objects from `babel-plugin-transform-jsx`
|
|
||||||
// to `React.Element`.
|
|
||||||
if (!this.template) {
|
|
||||||
throw new TypeError("Component doesn't define `template`");
|
|
||||||
}
|
|
||||||
|
|
||||||
// invoke the template creator passing our css helper
|
|
||||||
return this.template(this.cssHelper);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import Component from '../component';
|
import {PureComponent} from '../base-components';
|
||||||
import {decorate, getTabsProps} from '../utils/plugins';
|
import {decorate, getTabsProps} from '../utils/plugins';
|
||||||
|
|
||||||
import Tabs_ from './tabs';
|
import Tabs_ from './tabs';
|
||||||
|
|
||||||
const Tabs = decorate(Tabs_, 'Tabs');
|
const Tabs = decorate(Tabs_, 'Tabs');
|
||||||
|
|
||||||
export default class Header extends Component {
|
export default class Header extends PureComponent {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.onChangeIntent = this.onChangeIntent.bind(this);
|
this.onChangeIntent = this.onChangeIntent.bind(this);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Component from '../component';
|
import {PureComponent} from '../base-components';
|
||||||
|
|
||||||
export default class Notification extends Component {
|
export default class Notification extends PureComponent {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.state = {
|
this.state = {
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import Component from '../component';
|
import {PureComponent} from '../base-components';
|
||||||
import {decorate} from '../utils/plugins';
|
import {decorate} from '../utils/plugins';
|
||||||
|
|
||||||
import Notification_ from './notification';
|
import Notification_ from './notification';
|
||||||
|
|
||||||
const Notification = decorate(Notification_);
|
const Notification = decorate(Notification_);
|
||||||
|
|
||||||
export default class Notifications extends Component {
|
export default class Notifications extends PureComponent {
|
||||||
template(css) {
|
template(css) {
|
||||||
return (
|
return (
|
||||||
<div className={css('view')}>
|
<div className={css('view')}>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
/* eslint-disable quote-props */
|
/* eslint-disable quote-props */
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Component from '../component';
|
import {PureComponent} from '../base-components';
|
||||||
|
|
||||||
export default class SplitPane extends Component {
|
export default class SplitPane extends PureComponent {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.handleDragStart = this.handleDragStart.bind(this);
|
this.handleDragStart = this.handleDragStart.bind(this);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Component from '../component';
|
import {PureComponent} from '../base-components';
|
||||||
|
|
||||||
export default class Tab extends Component {
|
export default class Tab extends PureComponent {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import Component from '../component';
|
import {PureComponent} from '../base-components';
|
||||||
import {decorate, getTabProps} from '../utils/plugins';
|
import {decorate, getTabProps} from '../utils/plugins';
|
||||||
|
|
||||||
import Tab_ from './tab';
|
import Tab_ from './tab';
|
||||||
|
|
@ -8,7 +8,7 @@ import Tab_ from './tab';
|
||||||
const Tab = decorate(Tab_, 'Tab');
|
const Tab = decorate(Tab_, 'Tab');
|
||||||
const isMac = /Mac/.test(navigator.userAgent);
|
const isMac = /Mac/.test(navigator.userAgent);
|
||||||
|
|
||||||
export default class Tabs extends Component {
|
export default class Tabs extends PureComponent {
|
||||||
template(css) {
|
template(css) {
|
||||||
const {tabs = [], borderColor, onChange, onClose} = this.props;
|
const {tabs = [], borderColor, onChange, onClose} = this.props;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import Component from '../component';
|
import {PureComponent} from '../base-components';
|
||||||
import {decorate, getTermProps, getTermGroupProps} from '../utils/plugins';
|
import {decorate, getTermProps, getTermGroupProps} from '../utils/plugins';
|
||||||
import {resizeTermGroup} from '../actions/term-groups';
|
import {resizeTermGroup} from '../actions/term-groups';
|
||||||
import Term_ from './term';
|
import Term_ from './term';
|
||||||
|
|
@ -9,7 +9,7 @@ import SplitPane_ from './split-pane';
|
||||||
const Term = decorate(Term_, 'Term');
|
const Term = decorate(Term_, 'Term');
|
||||||
const SplitPane = decorate(SplitPane_, 'SplitPane');
|
const SplitPane = decorate(SplitPane_, 'SplitPane');
|
||||||
|
|
||||||
class TermGroup_ extends Component {
|
class TermGroup_ extends PureComponent {
|
||||||
constructor(props, context) {
|
constructor(props, context) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
this.bound = new WeakMap();
|
this.bound = new WeakMap();
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/* global Blob,URL,requestAnimationFrame */
|
/* global Blob,URL,requestAnimationFrame */
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Terminal from 'xterm';
|
import Terminal from 'xterm';
|
||||||
import Component from '../component';
|
import {PureComponent} from '../base-components';
|
||||||
import terms from '../terms';
|
import terms from '../terms';
|
||||||
import returnKey from '../utils/keymaps';
|
import returnKey from '../utils/keymaps';
|
||||||
import CommandRegistry from '../command-registry';
|
import CommandRegistry from '../command-registry';
|
||||||
|
|
@ -13,7 +13,7 @@ const CURSOR_STYLES = {
|
||||||
BLOCK: 'block'
|
BLOCK: 'block'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class Term extends Component {
|
export default class Term extends PureComponent {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
props.ref_(props.uid, this);
|
props.ref_(props.uid, this);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Component from '../component';
|
import {Component} from '../base-components';
|
||||||
import {decorate, getTermGroupProps} from '../utils/plugins';
|
import {decorate, getTermGroupProps} from '../utils/plugins';
|
||||||
import CommandRegistry from '../command-registry';
|
import CommandRegistry from '../command-registry';
|
||||||
import TermGroup_ from './term-group';
|
import TermGroup_ from './term-group';
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import Component from '../component';
|
import {PureComponent} from '../base-components';
|
||||||
import {connect} from '../utils/plugins';
|
import {connect} from '../utils/plugins';
|
||||||
import * as uiActions from '../actions/ui';
|
import * as uiActions from '../actions/ui';
|
||||||
|
|
||||||
|
|
@ -12,7 +12,7 @@ import NotificationsContainer from './notifications';
|
||||||
|
|
||||||
const isMac = /Mac/.test(navigator.userAgent);
|
const isMac = /Mac/.test(navigator.userAgent);
|
||||||
|
|
||||||
class Hyper extends Component {
|
class Hyper extends PureComponent {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.handleFocusActive = this.handleFocusActive.bind(this);
|
this.handleFocusActive = this.handleFocusActive.bind(this);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import {connect as reduxConnect} from 'react-redux';
|
||||||
// https://github.com/zeit/hyper/issues/619
|
// https://github.com/zeit/hyper/issues/619
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import Component from '../component';
|
import {PureComponent} from '../base-components';
|
||||||
import Notification from '../components/notification';
|
import Notification from '../components/notification';
|
||||||
import notify from './notify';
|
import notify from './notify';
|
||||||
|
|
||||||
|
|
@ -20,7 +20,7 @@ Module._load = function _load(path) {
|
||||||
case 'react-dom':
|
case 'react-dom':
|
||||||
return ReactDOM;
|
return ReactDOM;
|
||||||
case 'hyper/component':
|
case 'hyper/component':
|
||||||
return Component;
|
return PureComponent;
|
||||||
case 'hyper/notify':
|
case 'hyper/notify':
|
||||||
return notify;
|
return notify;
|
||||||
case 'hyper/Notification':
|
case 'hyper/Notification':
|
||||||
|
|
@ -457,7 +457,7 @@ function getDecorated(parent, name) {
|
||||||
let class__;
|
let class__;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
class__ = fn(class_, {React, Component, Notification, notify});
|
class__ = fn(class_, {React, PureComponent, Notification, notify});
|
||||||
class__.displayName = `${fn._pluginName}(${name})`;
|
class__.displayName = `${fn._pluginName}(${name})`;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
//eslint-disable-next-line no-console
|
//eslint-disable-next-line no-console
|
||||||
|
|
|
||||||
|
|
@ -150,9 +150,9 @@
|
||||||
"mousetrap": "1.6.1",
|
"mousetrap": "1.6.1",
|
||||||
"ms": "2.0.0",
|
"ms": "2.0.0",
|
||||||
"php-escape-shell": "1.0.0",
|
"php-escape-shell": "1.0.0",
|
||||||
"react": "15.6.1",
|
"react": "16.0.0-rc.3",
|
||||||
"react-deep-force-update": "2.0.1",
|
"react-deep-force-update": "2.0.1",
|
||||||
"react-dom": "15.6.1",
|
"react-dom": "16.0.0-rc.3",
|
||||||
"react-redux": "5.0.6",
|
"react-redux": "5.0.6",
|
||||||
"redux": "3.7.2",
|
"redux": "3.7.2",
|
||||||
"redux-thunk": "2.2.0",
|
"redux-thunk": "2.2.0",
|
||||||
|
|
|
||||||
29
yarn.lock
29
yarn.lock
|
|
@ -1725,14 +1725,6 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
|
||||||
safe-buffer "^5.0.1"
|
safe-buffer "^5.0.1"
|
||||||
sha.js "^2.4.8"
|
sha.js "^2.4.8"
|
||||||
|
|
||||||
create-react-class@^15.6.0:
|
|
||||||
version "15.6.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.0.tgz#ab448497c26566e1e29413e883207d57cfe7bed4"
|
|
||||||
dependencies:
|
|
||||||
fbjs "^0.8.9"
|
|
||||||
loose-envify "^1.3.1"
|
|
||||||
object-assign "^4.1.1"
|
|
||||||
|
|
||||||
cross-env@5.0.5:
|
cross-env@5.0.5:
|
||||||
version "5.0.5"
|
version "5.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.0.5.tgz#4383d364d9660873dd185b398af3bfef5efffef3"
|
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.0.5.tgz#4383d364d9660873dd185b398af3bfef5efffef3"
|
||||||
|
|
@ -4178,7 +4170,7 @@ oauth-sign@~0.8.1:
|
||||||
version "0.8.2"
|
version "0.8.2"
|
||||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
|
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
|
||||||
|
|
||||||
object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
|
object-assign@^4.0.1, object-assign@^4.1.0:
|
||||||
version "4.1.1"
|
version "4.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||||
|
|
||||||
|
|
@ -4814,7 +4806,7 @@ promise@^7.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
asap "~2.0.3"
|
asap "~2.0.3"
|
||||||
|
|
||||||
prop-types@^15.5.10:
|
prop-types@^15.5.10, prop-types@^15.5.6:
|
||||||
version "15.5.10"
|
version "15.5.10"
|
||||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154"
|
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -4896,14 +4888,14 @@ react-deep-force-update@2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-2.0.1.tgz#4f7f6c12c3e7de42f345992a3c518236fa1ecad3"
|
resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-2.0.1.tgz#4f7f6c12c3e7de42f345992a3c518236fa1ecad3"
|
||||||
|
|
||||||
react-dom@15.6.1:
|
react-dom@16.0.0-rc.3:
|
||||||
version "15.6.1"
|
version "16.0.0-rc.3"
|
||||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.6.1.tgz#2cb0ed4191038e53c209eb3a79a23e2a4cf99470"
|
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.0.0-rc.3.tgz#bd4e4d2abd464df5149a062b45fe796bbb804c2c"
|
||||||
dependencies:
|
dependencies:
|
||||||
fbjs "^0.8.9"
|
fbjs "^0.8.9"
|
||||||
loose-envify "^1.1.0"
|
loose-envify "^1.1.0"
|
||||||
object-assign "^4.1.0"
|
object-assign "^4.1.0"
|
||||||
prop-types "^15.5.10"
|
prop-types "^15.5.6"
|
||||||
|
|
||||||
react-redux@5.0.6:
|
react-redux@5.0.6:
|
||||||
version "5.0.6"
|
version "5.0.6"
|
||||||
|
|
@ -4916,15 +4908,14 @@ react-redux@5.0.6:
|
||||||
loose-envify "^1.1.0"
|
loose-envify "^1.1.0"
|
||||||
prop-types "^15.5.10"
|
prop-types "^15.5.10"
|
||||||
|
|
||||||
react@15.6.1:
|
react@16.0.0-rc.3:
|
||||||
version "15.6.1"
|
version "16.0.0-rc.3"
|
||||||
resolved "https://registry.yarnpkg.com/react/-/react-15.6.1.tgz#baa8434ec6780bde997cdc380b79cd33b96393df"
|
resolved "https://registry.yarnpkg.com/react/-/react-16.0.0-rc.3.tgz#4a9df996326ba7185903d9fbed3149765e237e26"
|
||||||
dependencies:
|
dependencies:
|
||||||
create-react-class "^15.6.0"
|
|
||||||
fbjs "^0.8.9"
|
fbjs "^0.8.9"
|
||||||
loose-envify "^1.1.0"
|
loose-envify "^1.1.0"
|
||||||
object-assign "^4.1.0"
|
object-assign "^4.1.0"
|
||||||
prop-types "^15.5.10"
|
prop-types "^15.5.6"
|
||||||
|
|
||||||
read-config-file@1.1.0:
|
read-config-file@1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue