Skip to content

Commit

Permalink
Re-implementing source code viewer component (using prism-based synta…
Browse files Browse the repository at this point in the history
…x highlighter instead of ACE editor).
  • Loading branch information
krulis-martin committed Sep 12, 2022
1 parent 6768475 commit add9c9a
Show file tree
Hide file tree
Showing 12 changed files with 402 additions and 66 deletions.
31 changes: 30 additions & 1 deletion .babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,36 @@
"transform-object-assign",
"transform-flow-strip-types",
"@babel/plugin-proposal-class-properties",
"@babel/plugin-transform-runtime"
"@babel/plugin-transform-runtime",
["prismjs", {
"languages": [
"csharp",
"css",
"go",
"groovy",
"java",
"javascript",
"kotlin",
"markdown",
"pascal",
"php",
"python",
"rust",
"scala",
"typescript",
"bash",
"cpp",
"haskell",
"cshtml",
"arduino",
"prolog",
"bash",
"sql",
"bison"
],
"theme": "default",
"css": true
}]
],
"env": {
"production": {
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"markdown-it": "^13.0.1",
"moment": "^2.29.4",
"pretty-ms": "^8.0.0",
"prismjs": "^1.29.0",
"prop-types": "^15.8.1",
"react": "^17.0.2",
"react-ace": "^10.1.0",
Expand All @@ -79,6 +80,7 @@
"react-redux": "^8.0.2",
"react-router": "^5.3.3",
"react-router-dom": "^5.3.3",
"react-syntax-highlighter": "^15.5.0",
"react-toggle": "4.1.3",
"redux": "^4.2.0",
"redux-actions": "^2.6.5",
Expand Down Expand Up @@ -107,6 +109,7 @@
"@formatjs/cli-lib": "^5.0.5",
"async": "^3.2.4",
"babel-loader": "^8.2.5",
"babel-plugin-prismjs": "^2.1.0",
"babel-plugin-transform-flow-strip-types": "^6.22.0",
"babel-plugin-transform-object-assign": "^6.22.0",
"babel-preset-es2015": "^6.24.1",
Expand Down
4 changes: 4 additions & 0 deletions src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ Object.keys(KNOWN_ACE_WORKERS).forEach(key => {
ace.config.setModuleUrl(`ace/mode/${key}`, `${ACE_CDN_PREFIX}${KNOWN_ACE_WORKERS[key]}.js`);
});

// set Prismjs to manual mode (if present)
window.Prism = window.Prism || {};
window.Prism.manual = true;

// load the initial state form the server - if any
let state;
const ini = window.__INITIAL_STATE__;
Expand Down
1 change: 1 addition & 0 deletions src/components/Solutions/SolutionDetail/SolutionDetail.js
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ class SolutionDetail extends Component {
</Col>
)}
</Row>

<SourceCodeViewerContainer
solutionId={id}
show={openFileId !== null}
Expand Down
2 changes: 1 addition & 1 deletion src/components/forms/Fields/SourceCodeField.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { canUseDOM } from 'exenv';
import { UserUIDataContext } from '../../../helpers/contexts';

// load the ACE editor only when rendering in the browser
import { getAceModeFromExtension } from '../../helpers/ace';
import { getAceModeFromExtension } from '../../helpers/syntaxHighlighting';
const AceEditor = canUseDOM ? require('react-ace').default : null;

const SourceCodeField = ({
Expand Down
35 changes: 35 additions & 0 deletions src/components/helpers/SourceCodeViewer/SourceCodeViewer.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
.sourceCodeViewer {
margin: 0;
padding: 0;

}

.sourceCodeViewer span[data-line] {
display: block;
line-height: 25px;
}

.sourceCodeViewer span[data-line] .linenumber {
margin-right: 0.25rem;
background-color: #e0e0e0;
text-align: right;
min-width: 5em!important;
text-shadow: none;
color: #666;
}

.sourceCodeViewer span[data-line]:hover, .sourceCodeViewer span[data-line]:hover * {
background-color: #f3f3f3;
}

.sourceCodeViewer span[data-line]:hover .linenumber {
background-color: #d0d0d0;
}

.sourceCodeViewer span[data-line-style="selected"] {
background-color: #ff9;
}

.sourceCodeViewer span[data-line-style="selected"] .linenumber {
background-color: yellow;
}
54 changes: 36 additions & 18 deletions src/components/helpers/SourceCodeViewer/SourceCodeViewer.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,46 @@
import React from 'react';
import PropTypes from 'prop-types';
import { canUseDOM } from 'exenv';
import { UserUIDataContext } from '../../../helpers/contexts';
import { getAceModeFromExtension } from '../../helpers/ace';
import { Prism as SyntaxHighlighter, createElement } from 'react-syntax-highlighter';
import { vs } from 'react-syntax-highlighter/dist/esm/styles/prism';
import 'prismjs/themes/prism.css';

const AceEditor = canUseDOM ? require('react-ace').default : null;
import { getPrismModeFromExtension } from '../../helpers/syntaxHighlighting';

import './SourceCodeViewer.css';

const linesRenderer = ({ rows, stylesheet, useInlineStyles }) => {
return rows.map((node, i) => (
<React.Fragment key={`fragment-${i}`}>
{createElement({
node,
stylesheet,
useInlineStyles,
key: `code-segement${i}`,
})}
</React.Fragment>
));
};

const linePropsGenerator = lineNumber => ({
'data-line': lineNumber,
});

const SourceCodeViewer = ({ name, content = '' }) =>
canUseDOM ? (
<UserUIDataContext.Consumer>
{({ vimMode = false, darkTheme = true, editorFontSize = 16 }) => (
<AceEditor
value={content}
mode={getAceModeFromExtension(name.split('.').pop())}
keyboardHandler={vimMode ? 'vim' : undefined}
theme={darkTheme ? 'monokai' : 'github'}
name="source-code-viewer"
width="100%"
height="100%"
fontSize={editorFontSize}
editorProps={{ $blockScrolling: true, $autoScrollEditorIntoView: true }}
/>
)}
</UserUIDataContext.Consumer>
<SyntaxHighlighter
language={getPrismModeFromExtension(name.split('.').pop())}
style={vs}
className="sourceCodeViewer"
showLineNumbers={true}
showInlineLineNumbers={true}
wrapLines={true}
wrapLongLines={false}
useInlineStyles={false}
lineProps={linePropsGenerator}
renderer={linesRenderer}>
{content}
</SyntaxHighlighter>
) : (
<></>
);
Expand Down
37 changes: 0 additions & 37 deletions src/components/helpers/ace.js

This file was deleted.

63 changes: 63 additions & 0 deletions src/components/helpers/syntaxHighlighting.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const commonMapping = {
cs: 'csharp',
css: 'css',
groovy: 'groovy',
java: 'java',
js: 'javascript',
kt: 'kotlin',
kts: 'kotlin',
ktm: 'kotlin',
lpr: 'pascal',
makefile: 'makefile',
md: 'markdown',
markdown: 'markdown',
pas: 'pascal',
php: 'php',
py: 'python',
rs: 'rust',
sc: 'scala',
scala: 'scala',
ts: 'typescript',
};

const aceMapping = {
...commonMapping,
c: 'c_cpp',
cpp: 'c_cpp',
h: 'c_cpp',
hpp: 'c_cpp',
ino: 'c_cpp',
html: 'html',
};

export const createExtensionTranslator = mapping => ext => {
ext = ext.trim().toLowerCase();
if (ext === '') {
return mapping.makefile; // makefile has no extension
} else if (mapping[ext]) {
return mapping[ext]; // mapping found
} else {
return mapping.cpp; // C/C++ is default
}
};

const prismMapping = {
...commonMapping,
bash: 'bash',
c: 'cpp',
cpp: 'cpp',
cu: 'cpp', // CUDA
go: 'go',
h: 'cpp',
hpp: 'cpp',
hs: 'haskell',
html: 'cshtml',
ino: 'arduino',
pl: 'prolog',
sh: 'bash',
sql: 'sql',
y: 'bison',
};

export const getAceModeFromExtension = createExtensionTranslator(aceMapping);
export const getPrismModeFromExtension = createExtensionTranslator(prismMapping);
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class SourceCodeViewerContainer extends Component {
isReference = false,
submittedBy = null,
} = this.props;

return (
<ResourceRenderer
loading={
Expand Down Expand Up @@ -139,7 +140,7 @@ class SourceCodeViewerContainer extends Component {

<Modal.Body className={styles.modalBody}>
{(content.malformedCharacters || content.tooLarge) && (
<Callout variant="warning">
<Callout variant="warning" className="m-2">
{content.malformedCharacters && (
<p>
<FormattedMessage
Expand All @@ -158,9 +159,13 @@ class SourceCodeViewerContainer extends Component {
)}
</Callout>
)}
<div>

{content.malformedCharacters ? (
<pre className="border-top">{content.content}</pre>
) : (
<SourceCodeViewer content={content.content} name={fileName} />
</div>
)}
<div className="border-top pt-1 bg-light rounded-bottom"></div>
</Modal.Body>
</Modal>
)}
Expand Down
8 changes: 3 additions & 5 deletions src/containers/SourceCodeViewerContainer/sourceCode.less
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
min-height: 100%;
display: flex;
flex-direction: column;
margin-bottom: 1vmax;

& > div:nth-child(2) {
flex-grow: 1;
Expand All @@ -26,14 +27,11 @@
flex-grow: 1;
display: flex;
flex-direction: column;
padding: 0!important;

& > *:last-child {
flex-grow: 1;
display: flex;
flex-direction: column;

& > * {
flex-grow: 1;
}
flex-grow: 1;
}
}
Loading

0 comments on commit add9c9a

Please sign in to comment.