mirror of
https://github.com/quine-global/hyper.git
synced 2026-01-12 20:18: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 Component from '../component';
|
||||
import {PureComponent} from '../base-components';
|
||||
import {decorate, getTabsProps} from '../utils/plugins';
|
||||
|
||||
import Tabs_ from './tabs';
|
||||
|
||||
const Tabs = decorate(Tabs_, 'Tabs');
|
||||
|
||||
export default class Header extends Component {
|
||||
export default class Header extends PureComponent {
|
||||
constructor() {
|
||||
super();
|
||||
this.onChangeIntent = this.onChangeIntent.bind(this);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
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() {
|
||||
super();
|
||||
this.state = {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
import React from 'react';
|
||||
|
||||
import Component from '../component';
|
||||
import {PureComponent} from '../base-components';
|
||||
import {decorate} from '../utils/plugins';
|
||||
|
||||
import Notification_ from './notification';
|
||||
|
||||
const Notification = decorate(Notification_);
|
||||
|
||||
export default class Notifications extends Component {
|
||||
export default class Notifications extends PureComponent {
|
||||
template(css) {
|
||||
return (
|
||||
<div className={css('view')}>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
/* eslint-disable quote-props */
|
||||
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) {
|
||||
super(props);
|
||||
this.handleDragStart = this.handleDragStart.bind(this);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
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() {
|
||||
super();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
|
||||
import Component from '../component';
|
||||
import {PureComponent} from '../base-components';
|
||||
import {decorate, getTabProps} from '../utils/plugins';
|
||||
|
||||
import Tab_ from './tab';
|
||||
|
|
@ -8,7 +8,7 @@ import Tab_ from './tab';
|
|||
const Tab = decorate(Tab_, 'Tab');
|
||||
const isMac = /Mac/.test(navigator.userAgent);
|
||||
|
||||
export default class Tabs extends Component {
|
||||
export default class Tabs extends PureComponent {
|
||||
template(css) {
|
||||
const {tabs = [], borderColor, onChange, onClose} = this.props;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import Component from '../component';
|
||||
import {PureComponent} from '../base-components';
|
||||
import {decorate, getTermProps, getTermGroupProps} from '../utils/plugins';
|
||||
import {resizeTermGroup} from '../actions/term-groups';
|
||||
import Term_ from './term';
|
||||
|
|
@ -9,7 +9,7 @@ import SplitPane_ from './split-pane';
|
|||
const Term = decorate(Term_, 'Term');
|
||||
const SplitPane = decorate(SplitPane_, 'SplitPane');
|
||||
|
||||
class TermGroup_ extends Component {
|
||||
class TermGroup_ extends PureComponent {
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
this.bound = new WeakMap();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* global Blob,URL,requestAnimationFrame */
|
||||
import React from 'react';
|
||||
import Terminal from 'xterm';
|
||||
import Component from '../component';
|
||||
import {PureComponent} from '../base-components';
|
||||
import terms from '../terms';
|
||||
import returnKey from '../utils/keymaps';
|
||||
import CommandRegistry from '../command-registry';
|
||||
|
|
@ -13,7 +13,7 @@ const CURSOR_STYLES = {
|
|||
BLOCK: 'block'
|
||||
};
|
||||
|
||||
export default class Term extends Component {
|
||||
export default class Term extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
props.ref_(props.uid, this);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import Component from '../component';
|
||||
import {Component} from '../base-components';
|
||||
import {decorate, getTermGroupProps} from '../utils/plugins';
|
||||
import CommandRegistry from '../command-registry';
|
||||
import TermGroup_ from './term-group';
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import React from 'react';
|
||||
|
||||
import Component from '../component';
|
||||
import {PureComponent} from '../base-components';
|
||||
import {connect} from '../utils/plugins';
|
||||
import * as uiActions from '../actions/ui';
|
||||
|
||||
|
|
@ -12,7 +12,7 @@ import NotificationsContainer from './notifications';
|
|||
|
||||
const isMac = /Mac/.test(navigator.userAgent);
|
||||
|
||||
class Hyper extends Component {
|
||||
class Hyper extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleFocusActive = this.handleFocusActive.bind(this);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {connect as reduxConnect} from 'react-redux';
|
|||
// https://github.com/zeit/hyper/issues/619
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import Component from '../component';
|
||||
import {PureComponent} from '../base-components';
|
||||
import Notification from '../components/notification';
|
||||
import notify from './notify';
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ Module._load = function _load(path) {
|
|||
case 'react-dom':
|
||||
return ReactDOM;
|
||||
case 'hyper/component':
|
||||
return Component;
|
||||
return PureComponent;
|
||||
case 'hyper/notify':
|
||||
return notify;
|
||||
case 'hyper/Notification':
|
||||
|
|
@ -457,7 +457,7 @@ function getDecorated(parent, name) {
|
|||
let class__;
|
||||
|
||||
try {
|
||||
class__ = fn(class_, {React, Component, Notification, notify});
|
||||
class__ = fn(class_, {React, PureComponent, Notification, notify});
|
||||
class__.displayName = `${fn._pluginName}(${name})`;
|
||||
} catch (err) {
|
||||
//eslint-disable-next-line no-console
|
||||
|
|
|
|||
|
|
@ -150,9 +150,9 @@
|
|||
"mousetrap": "1.6.1",
|
||||
"ms": "2.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-dom": "15.6.1",
|
||||
"react-dom": "16.0.0-rc.3",
|
||||
"react-redux": "5.0.6",
|
||||
"redux": "3.7.2",
|
||||
"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"
|
||||
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:
|
||||
version "5.0.5"
|
||||
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"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
|
||||
|
|
@ -4814,7 +4806,7 @@ promise@^7.1.1:
|
|||
dependencies:
|
||||
asap "~2.0.3"
|
||||
|
||||
prop-types@^15.5.10:
|
||||
prop-types@^15.5.10, prop-types@^15.5.6:
|
||||
version "15.5.10"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154"
|
||||
dependencies:
|
||||
|
|
@ -4896,14 +4888,14 @@ react-deep-force-update@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"
|
||||
|
||||
react-dom@15.6.1:
|
||||
version "15.6.1"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.6.1.tgz#2cb0ed4191038e53c209eb3a79a23e2a4cf99470"
|
||||
react-dom@16.0.0-rc.3:
|
||||
version "16.0.0-rc.3"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.0.0-rc.3.tgz#bd4e4d2abd464df5149a062b45fe796bbb804c2c"
|
||||
dependencies:
|
||||
fbjs "^0.8.9"
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.0"
|
||||
prop-types "^15.5.10"
|
||||
prop-types "^15.5.6"
|
||||
|
||||
react-redux@5.0.6:
|
||||
version "5.0.6"
|
||||
|
|
@ -4916,15 +4908,14 @@ react-redux@5.0.6:
|
|||
loose-envify "^1.1.0"
|
||||
prop-types "^15.5.10"
|
||||
|
||||
react@15.6.1:
|
||||
version "15.6.1"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-15.6.1.tgz#baa8434ec6780bde997cdc380b79cd33b96393df"
|
||||
react@16.0.0-rc.3:
|
||||
version "16.0.0-rc.3"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-16.0.0-rc.3.tgz#4a9df996326ba7185903d9fbed3149765e237e26"
|
||||
dependencies:
|
||||
create-react-class "^15.6.0"
|
||||
fbjs "^0.8.9"
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.0"
|
||||
prop-types "^15.5.10"
|
||||
prop-types "^15.5.6"
|
||||
|
||||
read-config-file@1.1.0:
|
||||
version "1.1.0"
|
||||
|
|
|
|||
Loading…
Reference in a new issue