implement syntax highlighter

This commit is contained in:
btzr-io 2018-07-27 19:42:35 -06:00
parent 1642672c8d
commit 842fbcc668
9 changed files with 748 additions and 106 deletions

View file

@ -18,8 +18,8 @@ type Props = {
class FileRender extends React.PureComponent<Props> { class FileRender extends React.PureComponent<Props> {
renderViewer() { renderViewer() {
const { source, mediaType, currentTheme } = this.props; const { source, mediaType, currentTheme: theme } = this.props;
const viewerProps = { source, theme: currentTheme }; const viewerProps = { source, theme };
// Supported mediaTypes // Supported mediaTypes
const mediaTypes = { const mediaTypes = {

View file

@ -195,8 +195,10 @@ class VideoPlayer extends React.PureComponent {
this.setState({ unsupported: true }); this.setState({ unsupported: true });
return false; return false;
} }
console.info(filename);
// File to render // File to render
const fileSource = { const fileSource = {
contentType,
downloadPath, downloadPath,
filePath: url, filePath: url,
fileType: path.extname(filename).substring(1), fileType: path.extname(filename).substring(1),

View file

@ -1,10 +1,16 @@
// @flow // @flow
import React from 'react'; import React from 'react';
import CodeMirror from 'codemirror'; import CodeMirror from 'codemirror/lib/codemirror';
// Syntax mode
import 'codemirror/mode/javascript/javascript';
import 'codemirror/mode/markdown/markdown';
import 'codemirror/mode/xml/xml';
type Props = { type Props = {
theme: string,
value: string, value: string,
contentType: string,
}; };
class CodeViewer extends React.PureComponent<Props> { class CodeViewer extends React.PureComponent<Props> {
@ -15,9 +21,11 @@ class CodeViewer extends React.PureComponent<Props> {
} }
componentDidMount() { componentDidMount() {
const { theme, contentType } = this.props;
this.codeMirror = CodeMirror.fromTextArea(this.textarea.current, { this.codeMirror = CodeMirror.fromTextArea(this.textarea.current, {
mode: 'markdown', mode: contentType,
readOnly: true, theme: theme === 'dark' ? 'dark' : 'default',
readOnly: 'nocursor',
dragDrop: false, dragDrop: false,
lineNumbers: true, lineNumbers: true,
lineWrapping: true, lineWrapping: true,
@ -26,10 +34,9 @@ class CodeViewer extends React.PureComponent<Props> {
render() { render() {
const { value } = this.props; const { value } = this.props;
return ( return (
<div className="document-viewer__content"> <div className="code-viewer">
<textarea ref={this.textarea} disabled="true" value={value} /> <textarea ref={this.textarea} disabled value={value} />
</div> </div>
); );
} }

View file

@ -7,6 +7,7 @@ import CodeViewer from 'component/viewers/codeViewer';
import MarkdownPreview from 'component/common/markdown-preview'; import MarkdownPreview from 'component/common/markdown-preview';
type Props = { type Props = {
theme: string,
source: { source: {
fileType: string, fileType: string,
filePath: string, filePath: string,
@ -45,17 +46,19 @@ class DocumentViewer extends React.PureComponent<Props> {
renderDocument() { renderDocument() {
let viewer = null; let viewer = null;
const { source } = this.props; const { source, theme } = this.props;
const { fileType, contentType } = source;
const { content, error } = this.state; const { content, error } = this.state;
const isReady = content && !error; const isReady = content && !error;
const markdownType = ['md', 'markdown']; const markdownType = ['md', 'markdown'];
if (isReady && markdownType.includes(source.fileType)) { if (isReady && markdownType.includes(fileType)) {
// Render markdown // Render markdown
viewer = <MarkdownPreview content={content} promptLinks />; viewer = <MarkdownPreview content={content} promptLinks />;
} else if (isReady) { } else if (isReady) {
// Render plain text // Render plain text
viewer = <CodeViewer value={content} />; viewer = <CodeViewer value={content} contentType={contentType} theme={theme} />;
} }
return viewer; return viewer;

View file

@ -2,6 +2,7 @@
@import '_reset.scss'; @import '_reset.scss';
@import '_vars.scss'; @import '_vars.scss';
@import '_gui.scss'; @import '_gui.scss';
@import 'component/_syntax-highlighter.scss';
@import 'component/_table.scss'; @import 'component/_table.scss';
@import 'component/_button.scss'; @import 'component/_button.scss';
@import 'component/_card.scss'; @import 'component/_card.scss';
@ -26,3 +27,4 @@
@import 'component/_file-render.scss'; @import 'component/_file-render.scss';
@import 'component/_search.scss'; @import 'component/_search.scss';
@import 'component/_toggle.scss'; @import 'component/_toggle.scss';
@import 'component/_search.scss';

View file

@ -36,8 +36,15 @@
padding: 32px 16px; padding: 32px 16px;
} }
.code-viewer,
.document-viewer__content {
overflow: auto;
width: 100%;
height: 100%;
}
/* Code-viewer */ /* Code-viewer */
.document-viewer .CodeMirror { .code-viewer .CodeMirror {
margin: 0; margin: 0;
padding: 0; padding: 0;
width: 100%; width: 100%;
@ -45,13 +52,21 @@
min-height: 100px; min-height: 100px;
.CodeMirror-code { .CodeMirror-code {
font-family: monospace; font-size: 1em;
line-height: 1.5em;
font-family: inconsolata, monospace;
letter-spacing: 0.3px;
word-spacing: 1px;
} }
.CodeMirror-linenumber { .CodeMirror-linenumber {
color: var(--card-text-color); color: var(--card-text-color);
} }
.CodeMirror .CodeMirror-lines {
padding: 4px 0;
}
.CodeMirror-line { .CodeMirror-line {
padding-left: 16px; padding-left: 16px;
} }
@ -59,21 +74,11 @@
.CodeMirror-gutters { .CodeMirror-gutters {
border-right: 1px solid var(--color-divider); border-right: 1px solid var(--color-divider);
background: var(--color-bg-alt); background: var(--color-bg-alt);
padding-right: 8px;
z-index: 3;
} }
.cm-invalidchar { .cm-invalidchar {
display: none; display: none;
} }
} }
/* Markdown-viewer */
.document-viewer__content {
overflow: auto;
width: 100%;
height: 100%;
textarea {
display: none;
}
}

View file

@ -1,8 +1,8 @@
.CodeMirror { .CodeMirror {
background: var(--color-canvas) !important; background: var(--color-canvas);
border: 0px !important; border: 0px;
border-radius: 0px !important; border-radius: 0px;
color: var(--text-color) !important; color: var(--text-color);
box-shadow: var(--box-shadow-layer); box-shadow: var(--box-shadow-layer);
} }
@ -55,18 +55,6 @@ div.editor-toolbar a {
border: 1px solid var(--input-border-color) !important; border: 1px solid var(--input-border-color) !important;
} }
.CodeMirror .CodeMirror-code .cm-tag {
color: #63a35c;
}
.CodeMirror .CodeMirror-code .cm-attribute {
color: #795da3;
}
.CodeMirror .CodeMirror-code .cm-string {
color: #183691;
}
.CodeMirror .CodeMirror-selected { .CodeMirror .CodeMirror-selected {
background: var(--text-selection-bg) !important; background: var(--text-selection-bg) !important;
color: var(--text-selection-color) !important; color: var(--text-selection-color) !important;
@ -76,18 +64,6 @@ div.editor-toolbar a {
border-color: var(--color-primary) !important; border-color: var(--color-primary) !important;
} }
.CodeMirror .CodeMirror-code .cm-comment {
background: rgba(0, 0, 0, 0.05);
}
.CodeMirror .CodeMirror-code .cm-link {
color: #7f8c8d;
}
.CodeMirror .CodeMirror-code .cm-url {
color: #aab2b3;
}
.CodeMirror .CodeMirror-placeholder { .CodeMirror .CodeMirror-placeholder {
opacity: 0.5; opacity: 0.5;
} }

View file

@ -0,0 +1,40 @@
/*
Dark-theme
https://github.com/FarhadG/code-mirror-themes/blob/master/themes/made-of-code.css
*/
.CodeMirror .cm-s-dark {
--color-property: #7ed6df;
--color-string: #ff7979;
--color-keyword: #ff7979;
}
.CodeMirror.cm-s-dark .CodeMirror-selected {
background: #007dff80;
}
.CodeMirror.cm-s-dark .cm-comment {
color: #54576b;
background: #00000000;
}
.CodeMirror.cm-s-dark .cm-keyword {
color: var(--color-keyword);
}
.CodeMirror.cm-s-dark .cm-string {
color: #f6e58d;
background: #102622fa;
}
.CodeMirror.cm-s-dark .cm-property {
color: var(--color-property);
}
.CodeMirror.cm-s-dark .cm-atom {
color: #f1d950;
}
.CodeMirror.cm-s-dark .cm-number {
color: #f1d950;
}
.CodeMirror.cm-s-dark .cm-operator {
color: var(--color-keyword);
}
.CodeMirror.cm-s-dark .CodeMirror-linenumber {
color: #54576b;
}

713
yarn.lock

File diff suppressed because it is too large Load diff