feeles-ide
Version:
The hackable and serializable IDE to make learning material
287 lines (264 loc) • 8.19 kB
JavaScript
import _getIterator from 'babel-runtime/core-js/get-iterator';
import _Object$getPrototypeOf from 'babel-runtime/core-js/object/get-prototype-of';
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
import _createClass from 'babel-runtime/helpers/createClass';
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
import _inherits from 'babel-runtime/helpers/inherits';
import _extends from 'babel-runtime/helpers/extends';
/* eslint-disable react/prop-types */
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import RaisedButton from 'material-ui/RaisedButton';
import { emphasize } from 'material-ui/utils/colorManipulator';
import ActionOpenInNew from 'material-ui/svg-icons/action/open-in-new';
import EditorModeEdit from 'material-ui/svg-icons/editor/mode-edit';
import CodeMirrorComponent from '../../utils/CodeMirrorComponent';
import MDReactComponent from '../../jsx/MDReactComponent';
import { Tab } from '../../ChromeTab/';
var mdComponents = [{
// 外部リンク
validate: function validate(tag, props) {
return tag === 'a' && isValidURL(props.href);
},
render: function render(tag, props, children, component, mdStyles) {
return React.createElement(RaisedButton, {
primary: true,
key: props.key,
label: children,
href: props.href,
labelPosition: 'before',
target: '_blank',
style: mdStyles.raisedButton,
labelStyle: mdStyles.raisedButtonLabel,
icon: React.createElement(ActionOpenInNew, null)
});
}
}, {
// Feeles 内リンク
validate: function validate(tag) {
return tag === 'a';
},
render: function render(tag, props, children, component, mdStyles) {
var onClick = function onClick() {
component.props.setLocation(decodeURIComponent(props.href));
};
return React.createElement(RaisedButton, {
primary: true,
key: props.key,
label: children,
style: mdStyles.raisedButton,
labelStyle: mdStyles.raisedButtonLabel,
onClick: onClick
});
}
}, {
// 外部リンク画像
validate: function validate(tag, props) {
return tag === 'img' && isValidURL(props.src);
},
render: function render(tag, props, children, component, mdStyles) {
return React.createElement('img', _extends({}, props, { style: mdStyles.img }));
}
}, {
// Feeles 内画像
validate: function validate(tag) {
return tag === 'img';
},
render: function render(tag, props, children, component, mdStyles) {
var file = component.props.findFile(decodeURIComponent(props.src));
if (!file) {
return React.createElement(
'span',
props,
props.alt
);
}
if (file.is('blob')) {
return React.createElement('img', _extends({}, props, { style: mdStyles.img, src: file.blobURL }));
}
// Edit file
var onClick = function onClick() {
var getFile = function getFile() {
return component.props.findFile(function (item) {
return item.key === file.key;
});
};
component.props.selectTab(new Tab({ getFile: getFile }));
};
return React.createElement(RaisedButton, {
primary: true,
key: props.key,
label: props.alt,
icon: React.createElement(EditorModeEdit, null),
style: mdStyles.raisedButton,
labelStyle: mdStyles.raisedButtonLabel,
onClick: onClick
});
}
}, {
// インタプリタ
validate: function validate(tag) {
return tag === 'pre';
},
render: function render(tag, props, children) {
var code = children[0].props.children[0] || '';
var containerStyle = {
position: 'relative',
height: Math.min(20, code.split('\n').length) + 'rem',
paddingBottom: 8
};
return React.createElement(
'div',
{ key: props.key + code, style: containerStyle },
React.createElement(CodeMirrorComponent, {
id: 'Readme',
value: code,
mode: 'javascript',
keyMap: 'sublime',
readOnly: true
})
);
}
}];
var mdStyle = function mdStyle(props, state, context) {
var _context$muiTheme = context.muiTheme,
palette = _context$muiTheme.palette,
spacing = _context$muiTheme.spacing;
var tableBorder = '1px solid ' + palette.disabledColor;
return {
blockquote: {
color: palette.secondaryTextColor,
marginLeft: '1rem',
paddingLeft: '1rem',
borderLeft: '5px solid ' + palette.disabledColor
},
img: {
maxWidth: '100%'
},
table: {
margin: '1rem 0',
borderLeft: tableBorder,
borderSpacing: 0
},
th: {
padding: spacing.desktopGutterMini,
borderTop: tableBorder,
borderRight: tableBorder,
borderBottom: tableBorder
},
td: {
padding: spacing.desktopGutterMini,
borderRight: tableBorder,
borderBottom: tableBorder
},
code: {
backgroundColor: emphasize(palette.canvasColor, 0.07),
padding: '.2em',
borderRadius: 2
},
iconStyle: {
transform: 'scale(0.6)',
verticalAlign: 'middle'
},
iconColor: palette.alternateTextColor,
raisedButton: {
margin: 4
},
raisedButtonLabel: {
textTransform: 'none'
}
};
};
var Readme = function (_PureComponent) {
_inherits(Readme, _PureComponent);
function Readme() {
_classCallCheck(this, Readme);
return _possibleConstructorReturn(this, (Readme.__proto__ || _Object$getPrototypeOf(Readme)).apply(this, arguments));
}
_createClass(Readme, [{
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps, nextContext) {
if (this.context.muiTheme !== nextContext.muiTheme) {
this.forceUpdate();
}
}
}, {
key: 'render',
value: function render() {
var _this2 = this;
var mdStyles = mdStyle(this.props, this.state, this.context);
var onIterate = function onIterate(tag, props, children) {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = _getIterator(mdComponents), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var _ref2 = _step.value;
var validate = _ref2.validate,
render = _ref2.render;
if (validate(tag, props)) {
return render(tag, props, children, _this2, mdStyles);
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
if (tag in mdStyles) {
props = _extends({}, props, { style: mdStyles[tag] });
}
if (children.length < 1) {
children = null;
}
if (tag === 'p') {
tag = 'div';
props = _extends({}, props, { style: _extends({}, props.style, { margin: '14px 0' }) });
}
return React.createElement(tag, props, children);
};
var styles = {
root: {
boxSizing: 'border-box',
overflow: 'scroll'
}
};
return React.createElement(MDReactComponent, {
text: this.props.file.text,
style: styles.root,
onIterate: onIterate
});
}
}]);
return Readme;
}(PureComponent);
Readme.propTypes = {
file: PropTypes.object.isRequired,
findFile: PropTypes.func.isRequired,
selectTab: PropTypes.func.isRequired,
getConfig: PropTypes.func.isRequired,
localization: PropTypes.object.isRequired,
completes: PropTypes.array.isRequired,
setLocation: PropTypes.func.isRequired
};
Readme.contextTypes = {
muiTheme: PropTypes.object.isRequired
};
export default Readme;
function isValidURL(url) {
try {
new URL(url);
return true;
} catch (e) {
return false;
}
}