summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Speller <crspeller@gmail.com>2016-03-17 12:09:04 -0400
committerChristopher Speller <crspeller@gmail.com>2016-03-17 12:09:04 -0400
commitd383ed2f8dfc320c090b67d9f2e2d111710ca3cf (patch)
tree4051092e6838f0564af8a7e2116aefbceb1409d1
parent2cd006474ec8a808b2ea2b0502a842f44cb0b127 (diff)
parent529513606b74fce60cbb066b381b27fbb6ea9d52 (diff)
downloadchat-d383ed2f8dfc320c090b67d9f2e2d111710ca3cf.tar.gz
chat-d383ed2f8dfc320c090b67d9f2e2d111710ca3cf.tar.bz2
chat-d383ed2f8dfc320c090b67d9f2e2d111710ca3cf.zip
Merge pull request #2380 from rodrigocorsi2/code_preview
Created component CodePreview
-rw-r--r--webapp/components/code_preview.jsx101
-rw-r--r--webapp/components/view_image.jsx11
-rw-r--r--webapp/sass/components/_files.scss1
-rw-r--r--webapp/sass/components/_modal.scss16
-rw-r--r--webapp/sass/layout/_markdown.scss48
-rw-r--r--webapp/utils/constants.jsx82
-rw-r--r--webapp/utils/markdown.jsx87
-rw-r--r--webapp/utils/syntax_hightlighting.jsx197
-rw-r--r--webapp/utils/utils.jsx2
9 files changed, 434 insertions, 111 deletions
diff --git a/webapp/components/code_preview.jsx b/webapp/components/code_preview.jsx
new file mode 100644
index 000000000..8d2bc6269
--- /dev/null
+++ b/webapp/components/code_preview.jsx
@@ -0,0 +1,101 @@
+// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+import $ from 'jquery';
+import * as syntaxHightlighting from 'utils/syntax_hightlighting.jsx';
+import Constants from 'utils/constants.jsx';
+import FileInfoPreview from './file_info_preview.jsx';
+
+import React from 'react';
+
+export default class CodePreview extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.updateStateFromProps = this.updateStateFromProps.bind(this);
+ this.handleReceivedError = this.handleReceivedError.bind(this);
+ this.handleReceivedCode = this.handleReceivedCode.bind(this);
+
+ this.state = {
+ code: '',
+ lang: '',
+ loading: true,
+ success: true
+ };
+ }
+
+ componentDidMount() {
+ this.updateStateFromProps(this.props);
+ }
+
+ componentWillReceiveProps(nextProps) {
+ if (this.props.fileUrl !== nextProps.fileUrl) {
+ this.updateStateFromProps(nextProps);
+ }
+ }
+
+ updateStateFromProps(props) {
+ var usedLanguage = syntaxHightlighting.getLang(props.filename);
+
+ if (!usedLanguage || props.fileInfo.size > Constants.CODE_PREVIEW_MAX_FILE_SIZE) {
+ this.setState({code: '', lang: '', loading: false, success: false});
+ return;
+ }
+
+ this.setState({code: '', lang: usedLanguage, loading: true});
+
+ $.ajax({
+ async: true,
+ url: props.fileUrl,
+ type: 'GET',
+ error: this.handleReceivedError,
+ success: this.handleReceivedCode
+ });
+ }
+
+ handleReceivedCode(data) {
+ const parsed = syntaxHightlighting.formatCode(this.state.lang, data, this.props.filename)
+ this.setState({code: parsed, loading: false, success: true});
+ }
+
+ handleReceivedError() {
+ this.setState({loading: false, success: false});
+ }
+
+ static support(filename) {
+ return typeof syntaxHightlighting.getLang(filename) !== 'undefined';
+ }
+
+ render() {
+ if (this.state.loading) {
+ return (
+ <div className='view-image__loading'>
+ <img
+ className='loader-image'
+ src='/static/images/load.gif'
+ />
+ </div>
+ );
+ }
+
+ if (!this.state.success) {
+ return (
+ <FileInfoPreview
+ filename={this.props.filename}
+ fileUrl={this.props.fileUrl}
+ fileInfo={this.props.fileInfo}
+ formatMessage={this.props.formatMessage}
+ />
+ );
+ }
+
+ return <div dangerouslySetInnerHTML={{__html: this.state.code}}/>;
+ }
+}
+
+CodePreview.propTypes = {
+ filename: React.PropTypes.string.isRequired,
+ fileUrl: React.PropTypes.string.isRequired,
+ fileInfo: React.PropTypes.object.isRequired,
+ formatMessage: React.PropTypes.func.isRequired
+};
diff --git a/webapp/components/view_image.jsx b/webapp/components/view_image.jsx
index 2b7e03382..7572f88ae 100644
--- a/webapp/components/view_image.jsx
+++ b/webapp/components/view_image.jsx
@@ -7,6 +7,7 @@ import * as Client from 'utils/client.jsx';
import * as Utils from 'utils/utils.jsx';
import AudioVideoPreview from './audio_video_preview.jsx';
import Constants from 'utils/constants.jsx';
+import CodePreview from './code_preview.jsx';
import FileInfoPreview from './file_info_preview.jsx';
import FileStore from 'stores/file_store.jsx';
import ViewImagePopoverBar from './view_image_popover_bar.jsx';
@@ -254,6 +255,15 @@ class ViewImageModal extends React.Component {
formatMessage={this.props.intl.formatMessage}
/>
);
+ } else if (CodePreview.support(filename)) {
+ content = (
+ <CodePreview
+ filename={filename}
+ fileUrl={fileUrl}
+ fileInfo={fileInfo}
+ formatMessage={this.props.intl.formatMessage}
+ />
+ );
} else {
content = (
<FileInfoPreview
@@ -323,6 +333,7 @@ class ViewImageModal extends React.Component {
onClick={this.props.onModalDismissed}
>
<div
+ className='modal-back'
onMouseEnter={this.onMouseEnterImage}
onMouseLeave={this.onMouseLeaveImage}
onClick={(e) => e.stopPropagation()}
diff --git a/webapp/sass/components/_files.scss b/webapp/sass/components/_files.scss
index b854312c1..5522c6db8 100644
--- a/webapp/sass/components/_files.scss
+++ b/webapp/sass/components/_files.scss
@@ -234,6 +234,7 @@
.file-details__container {
@include display-flex;
+ background: $white;
.file-details {
height: 270px;
diff --git a/webapp/sass/components/_modal.scss b/webapp/sass/components/_modal.scss
index 601aa33ab..94378aabe 100644
--- a/webapp/sass/components/_modal.scss
+++ b/webapp/sass/components/_modal.scss
@@ -256,13 +256,27 @@
}
> div {
- background: $white;
display: inline-block;
min-height: 100px;
min-width: 320px;
position: relative;
}
+ code {
+ min-height: 130px;
+ min-width: 330px;
+ }
+
+ pre, code {
+ display: inline-block;
+ }
+
+ .post-body--code {
+ max-height: calc(100vh - 80px);
+ max-width: calc(100vw - 80px);
+ overflow: auto;
+ }
+
img {
max-height: 100%;
max-width: 100%;
diff --git a/webapp/sass/layout/_markdown.scss b/webapp/sass/layout/_markdown.scss
index e2180c64d..b9acd8b5b 100644
--- a/webapp/sass/layout/_markdown.scss
+++ b/webapp/sass/layout/_markdown.scss
@@ -22,29 +22,63 @@
}
.post-body--code {
+ overflow-x: auto;
+ overflow-y: hidden;
position: relative;
pre {
- margin-bottom: 0;
- overflow: auto;
- word-break: normal;
- word-wrap: normal;
+ border: 1px solid rgba(221,221,221,0.2);
+ border-radius: .25em;
+ margin: 0;
+ padding: 0px;
+ text-align: left;
+ white-space: nowrap;
+ }
+
+ code {
+ border: none;
+ white-space: pre;
+ }
+
+ td {
+ padding: 0 .5em;
+ vertical-align: top;
+ }
+
+ &:hover .post-body--code__language {
+ @include opacity(1);
}
}
.post-body--code__language {
+ @include opacity(0);
@include translate3d(0, 0, 0);
background: #21586d;
+ border-radius: 0 .25em;
color: $white;
- font-size: 13px;
- opacity: .7;
padding: 4px 10px 5px;
position: absolute;
right: 0;
top: 0;
+ -webkit-transition: opacity 0.6s;
+ -moz-transition: opacity 0.6s;
+ -o-transition: opacity 0.6s;
+ transition: opacity 0.6s;
z-index: 5;
}
+.post-body--code__lineno {
+ border-right: 1px solid #aaa;
+ color: #aaa;
+ margin-right: .5em;
+ text-align: right;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ -o-user-select: none;
+ user-select: none;
+}
+
.post__body {
hr {
@include opacity(.2);
@@ -108,9 +142,9 @@ blockquote {
}
pre {
- border: none;
color: inherit;
margin: 5px 0;
+ padding: 0;
}
code {
diff --git a/webapp/utils/constants.jsx b/webapp/utils/constants.jsx
index c1e527702..29178aca6 100644
--- a/webapp/utils/constants.jsx
+++ b/webapp/utils/constants.jsx
@@ -144,7 +144,7 @@ export default {
PRESENTATION_TYPES: ['ppt', 'pptx'],
SPREADSHEET_TYPES: ['xlsx', 'csv'],
WORD_TYPES: ['doc', 'docx'],
- CODE_TYPES: ['css', 'html', 'js', 'php', 'rb'],
+ CODE_TYPES: ['as', 'applescript', 'osascript', 'scpt', 'bash', 'sh', 'zsh', 'clj', 'boot', 'cl2', 'cljc', 'cljs', 'cljs.hl', 'cljscm', 'cljx', 'hic', 'coffee', '_coffee', 'cake', 'cjsx', 'cson', 'iced', 'cpp', 'c', 'cc', 'h', 'c++', 'h++', 'hpp', 'cs', 'csharp', 'css', 'd', 'di', 'dart', 'delphi', 'dpr', 'dfm', 'pas', 'pascal', 'freepascal', 'lazarus', 'lpr', 'lfm', 'diff', 'django', 'jinja', 'dockerfile', 'docker', 'erl', 'f90', 'f95', 'fsharp', 'fs', 'gcode', 'nc', 'go', 'groovy', 'handlebars', 'hbs', 'html.hbs', 'html.handlebars', 'hs', 'hx', 'java', 'jsp', 'js', 'jsx', 'json', 'jl', 'kt', 'ktm', 'kts', 'less', 'lisp', 'lua', 'mk', 'mak', 'md', 'mkdown', 'mkd', 'matlab', 'm', 'mm', 'objc', 'obj-c', 'ml', 'perl', 'pl', 'php', 'php3', 'php4', 'php5', 'php6', 'ps', 'ps1', 'pp', 'py', 'gyp', 'r', 'ruby', 'rb', 'gemspec', 'podspec', 'thor', 'irb', 'rs', 'scala', 'scm', 'sld', 'scss', 'st', 'sql', 'swift', 'tex', 'vbnet', 'vb', 'bas', 'vbs', 'v', 'veo', 'xml', 'html', 'xhtml', 'rss', 'atom', 'xsl', 'plist', 'yaml'],
PDF_TYPES: ['pdf'],
PATCH_TYPES: ['patch'],
ICON_FROM_TYPE: {
@@ -514,30 +514,64 @@ export default {
SPACE: 32,
TAB: 9
},
+ CODE_PREVIEW_MAX_FILE_SIZE: 500000, // 500 KB
HighlightedLanguages: {
- diff: 'Diff',
- apache: 'Apache',
- makefile: 'Makefile',
- http: 'HTTP',
- json: 'JSON',
- markdown: 'Markdown',
- javascript: 'JavaScript',
- css: 'CSS',
- nginx: 'nginx',
- objectivec: 'Objective-C',
- python: 'Python',
- xml: 'XML',
- perl: 'Perl',
- bash: 'Bash',
- php: 'PHP',
- coffeescript: 'CoffeeScript',
- cs: 'C#',
- cpp: 'C++',
- sql: 'SQL',
- go: 'Go',
- ruby: 'Ruby',
- java: 'Java',
- ini: 'ini'
+ actionscript: {name: 'ActionScript', extensions: ['as']},
+ applescript: {name: 'AppleScript', extensions: ['applescript', 'osascript', 'scpt']},
+ bash: {name: 'Bash', extensions: ['bash', 'sh', 'zsh']},
+ clojure: {name: 'Clojure', extensions: ['clj', 'boot', 'cl2', 'cljc', 'cljs', 'cljs.hl', 'cljscm', 'cljx', 'hic']},
+ coffeescript: {name: 'CoffeeScript', extensions: ['coffee', '_coffee', 'cake', 'cjsx', 'cson', 'iced']},
+ cpp: {name: 'C/C++', extensions: ['cpp', 'c', 'cc', 'h', 'c++', 'h++', 'hpp']},
+ cs: {name: 'C#', extensions: ['cs', 'csharp']},
+ css: {name: 'CSS', extensions: ['css']},
+ d: {name: 'D', extensions: ['d', 'di']},
+ dart: {name: 'Dart', extensions: ['dart']},
+ delphi: {name: 'Delphi', extensions: ['delphi', 'dpr', 'dfm', 'pas', 'pascal', 'freepascal', 'lazarus', 'lpr', 'lfm']},
+ diff: {name: 'Diff', extensions: ['diff', 'patch']},
+ django: {name: 'Django', extensions: ['django', 'jinja']},
+ dockerfile: {name: 'Dockerfile', extensions: ['dockerfile', 'docker']},
+ erlang: {name: 'Erlang', extensions: ['erl']},
+ fortran: {name: 'Fortran', extensions: ['f90', 'f95']},
+ fsharp: {name: 'F#', extensions: ['fsharp', 'fs']},
+ gcode: {name: 'G-Code', extensions: ['gcode', 'nc']},
+ go: {name: 'Go', extensions: ['go']},
+ groovy: {name: 'Groovy', extensions: ['groovy']},
+ handlebars: {name: 'Handlebars', extensions: ['handlebars', 'hbs', 'html.hbs', 'html.handlebars']},
+ haskell: {name: 'Haskell', extensions: ['hs']},
+ haxe: {name: 'Haxe', extensions: ['hx']},
+ java: {name: 'Java', extensions: ['java', 'jsp']},
+ javascript: {name: 'JavaScript', extensions: ['js', 'jsx']},
+ json: {name: 'JSON', extensions: ['json']},
+ julia: {name: 'Julia', extensions: ['jl']},
+ kotlin: {name: 'Kotlin', extensions: ['kt', 'ktm', 'kts']},
+ less: {name: 'Less', extensions: ['less']},
+ lisp: {name: 'Lisp', extensions: ['lisp']},
+ lua: {name: 'Lua', extensions: ['lua']},
+ makefile: {name: 'Makefile', extensions: ['mk', 'mak']},
+ markdown: {name: 'Markdown', extensions: ['md', 'mkdown', 'mkd']},
+ matlab: {name: 'Matlab', extensions: ['matlab', 'm']},
+ objectivec: {name: 'Objective C', extensions: ['mm', 'objc', 'obj-c']},
+ ocaml: {name: 'OCaml', extensions: ['ml']},
+ perl: {name: 'Perl', extensions: ['perl', 'pl']},
+ php: {name: 'PHP', extensions: ['php', 'php3', 'php4', 'php5', 'php6']},
+ powershell: {name: 'PowerShell', extensions: ['ps', 'ps1']},
+ puppet: {name: 'Puppet', extensions: ['pp']},
+ python: {name: 'Python', extensions: ['py', 'gyp']},
+ r: {name: 'R', extensions: ['r']},
+ ruby: {name: 'Ruby', extensions: ['ruby', 'rb', 'gemspec', 'podspec', 'thor', 'irb']},
+ rust: {name: 'Rust', extensions: ['rs']},
+ scala: {name: 'Scala', extensions: ['scala']},
+ scheme: {name: 'Scheme', extensions: ['scm', 'sld']},
+ scss: {name: 'SCSS', extensions: ['scss']},
+ smalltalk: {name: 'Smalltalk', extensions: ['st']},
+ sql: {name: 'SQL', extensions: ['sql']},
+ swift: {name: 'Swift', extensions: ['swift']},
+ tex: {name: 'TeX', extensions: ['tex']},
+ vbnet: {name: 'VB.Net', extensions: ['vbnet', 'vb', 'bas']},
+ vbscript: {name: 'VBScript', extensions: ['vbs']},
+ verilog: {name: 'Verilog', extensions: ['v', 'veo']},
+ xml: {name: 'HTML, XML', extensions: ['xml', 'html', 'xhtml', 'rss', 'atom', 'xsl', 'plist']},
+ yaml: {name: 'YAML', extensions: ['yaml']}
},
PostsViewJumpTypes: {
BOTTOM: 1,
diff --git a/webapp/utils/markdown.jsx b/webapp/utils/markdown.jsx
index 635a39290..ee63e6a19 100644
--- a/webapp/utils/markdown.jsx
+++ b/webapp/utils/markdown.jsx
@@ -1,57 +1,9 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
-import highlightJs from 'highlight.js/lib/highlight.js';
-import highlightJsDiff from 'highlight.js/lib/languages/diff.js';
-import highlightJsApache from 'highlight.js/lib/languages/apache.js';
-import highlightJsMakefile from 'highlight.js/lib/languages/makefile.js';
-import highlightJsHttp from 'highlight.js/lib/languages/http.js';
-import highlightJsJson from 'highlight.js/lib/languages/json.js';
-import highlightJsMarkdown from 'highlight.js/lib/languages/markdown.js';
-import highlightJsJavascript from 'highlight.js/lib/languages/javascript.js';
-import highlightJsCss from 'highlight.js/lib/languages/css.js';
-import highlightJsNginx from 'highlight.js/lib/languages/nginx.js';
-import highlightJsObjectivec from 'highlight.js/lib/languages/objectivec.js';
-import highlightJsPython from 'highlight.js/lib/languages/python.js';
-import highlightJsXml from 'highlight.js/lib/languages/xml.js';
-import highlightJsPerl from 'highlight.js/lib/languages/perl.js';
-import highlightJsBash from 'highlight.js/lib/languages/bash.js';
-import highlightJsPhp from 'highlight.js/lib/languages/php.js';
-import highlightJsCoffeescript from 'highlight.js/lib/languages/coffeescript.js';
-import highlightJsCs from 'highlight.js/lib/languages/cs.js';
-import highlightJsCpp from 'highlight.js/lib/languages/cpp.js';
-import highlightJsSql from 'highlight.js/lib/languages/sql.js';
-import highlightJsGo from 'highlight.js/lib/languages/go.js';
-import highlightJsRuby from 'highlight.js/lib/languages/ruby.js';
-import highlightJsJava from 'highlight.js/lib/languages/java.js';
-import highlightJsIni from 'highlight.js/lib/languages/ini.js';
-
-highlightJs.registerLanguage('diff', highlightJsDiff);
-highlightJs.registerLanguage('apache', highlightJsApache);
-highlightJs.registerLanguage('makefile', highlightJsMakefile);
-highlightJs.registerLanguage('http', highlightJsHttp);
-highlightJs.registerLanguage('json', highlightJsJson);
-highlightJs.registerLanguage('markdown', highlightJsMarkdown);
-highlightJs.registerLanguage('javascript', highlightJsJavascript);
-highlightJs.registerLanguage('css', highlightJsCss);
-highlightJs.registerLanguage('nginx', highlightJsNginx);
-highlightJs.registerLanguage('objectivec', highlightJsObjectivec);
-highlightJs.registerLanguage('python', highlightJsPython);
-highlightJs.registerLanguage('xml', highlightJsXml);
-highlightJs.registerLanguage('perl', highlightJsPerl);
-highlightJs.registerLanguage('bash', highlightJsBash);
-highlightJs.registerLanguage('php', highlightJsPhp);
-highlightJs.registerLanguage('coffeescript', highlightJsCoffeescript);
-highlightJs.registerLanguage('cs', highlightJsCs);
-highlightJs.registerLanguage('cpp', highlightJsCpp);
-highlightJs.registerLanguage('sql', highlightJsSql);
-highlightJs.registerLanguage('go', highlightJsGo);
-highlightJs.registerLanguage('ruby', highlightJsRuby);
-highlightJs.registerLanguage('java', highlightJsJava);
-highlightJs.registerLanguage('ini', highlightJsIni);
-
import * as TextFormatting from './text_formatting.jsx';
import * as Utils from './utils.jsx';
+import * as syntaxHightlighting from './syntax_hightlighting.jsx';
import marked from 'marked';
import katex from 'katex';
@@ -110,31 +62,11 @@ class MattermostMarkdownRenderer extends marked.Renderer {
this.formattingOptions = formattingOptions;
}
- code(code, language, escaped) {
+ code(code, language) {
let usedLanguage = language || '';
usedLanguage = usedLanguage.toLowerCase();
- // treat html as xml to prevent injection attacks
- if (usedLanguage === 'html') {
- usedLanguage = 'xml';
- }
-
- if (HighlightedLanguages[usedLanguage]) {
- const parsed = highlightJs.highlight(usedLanguage, code);
-
- return (
- '<div class="post-body--code">' +
- '<span class="post-body--code__language">' +
- HighlightedLanguages[usedLanguage] +
- '</span>' +
- '<pre>' +
- '<code class="hljs">' +
- parsed.value +
- '</code>' +
- '</pre>' +
- '</div>'
- );
- } else if (usedLanguage === 'tex' || usedLanguage === 'latex') {
+ if (usedLanguage === 'tex' || usedLanguage === 'latex') {
try {
const html = katex.renderToString(code, {throwOnError: false, displayMode: true});
@@ -144,13 +76,12 @@ class MattermostMarkdownRenderer extends marked.Renderer {
}
}
- return (
- '<pre>' +
- '<code class="hljs">' +
- (escaped ? code : TextFormatting.sanitizeHtml(code)) + '\n' +
- '</code>' +
- '</pre>'
- );
+ // treat html as xml to prevent injection attacks
+ if (usedLanguage === 'html') {
+ usedLanguage = 'xml';
+ }
+
+ return syntaxHightlighting.formatCode(usedLanguage, code);
}
codespan(text) {
diff --git a/webapp/utils/syntax_hightlighting.jsx b/webapp/utils/syntax_hightlighting.jsx
new file mode 100644
index 000000000..981ce6b35
--- /dev/null
+++ b/webapp/utils/syntax_hightlighting.jsx
@@ -0,0 +1,197 @@
+// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
+// See License.txt for license information.
+
+import * as Utils from './utils.jsx';
+import * as TextFormatting from './text_formatting.jsx';
+import Constants from './constants.jsx';
+
+import hlJS from 'highlight.js/lib/highlight.js';
+
+import hljsActionscript from 'highlight.js/lib/languages/actionscript.js';
+import hljsApplescript from 'highlight.js/lib/languages/applescript.js';
+import hljsBash from 'highlight.js/lib/languages/bash.js';
+import hljsClojure from 'highlight.js/lib/languages/clojure.js';
+import hljsCoffeescript from 'highlight.js/lib/languages/coffeescript.js';
+import hljsCpp from 'highlight.js/lib/languages/cpp.js';
+import hljsCs from 'highlight.js/lib/languages/cs.js';
+import hljsCss from 'highlight.js/lib/languages/css.js';
+import hljsD from 'highlight.js/lib/languages/d.js';
+import hljsDart from 'highlight.js/lib/languages/dart.js';
+import hljsDelphi from 'highlight.js/lib/languages/delphi.js';
+import hljsDiff from 'highlight.js/lib/languages/diff.js';
+import hljsDjango from 'highlight.js/lib/languages/django.js';
+import hljsDockerfile from 'highlight.js/lib/languages/dockerfile.js';
+import hljsErlang from 'highlight.js/lib/languages/erlang.js';
+import hljsFortran from 'highlight.js/lib/languages/fortran.js';
+import hljsFsharp from 'highlight.js/lib/languages/fsharp.js';
+import hljsGcode from 'highlight.js/lib/languages/gcode.js';
+import hljsGo from 'highlight.js/lib/languages/go.js';
+import hljsGroovy from 'highlight.js/lib/languages/groovy.js';
+import hljsHandlebars from 'highlight.js/lib/languages/handlebars.js';
+import hljsHaskell from 'highlight.js/lib/languages/haskell.js';
+import hljsHaxe from 'highlight.js/lib/languages/haxe.js';
+import hljsJava from 'highlight.js/lib/languages/java.js';
+import hljsJavascript from 'highlight.js/lib/languages/javascript.js';
+import hljsJson from 'highlight.js/lib/languages/json.js';
+import hljsJulia from 'highlight.js/lib/languages/julia.js';
+import hljsKotlin from 'highlight.js/lib/languages/kotlin.js';
+import hljsLess from 'highlight.js/lib/languages/less.js';
+import hljsLisp from 'highlight.js/lib/languages/lisp.js';
+import hljsLua from 'highlight.js/lib/languages/lua.js';
+import hljsMakefile from 'highlight.js/lib/languages/makefile.js';
+import hljsMarkdown from 'highlight.js/lib/languages/markdown.js';
+import hljsMatlab from 'highlight.js/lib/languages/matlab.js';
+import hljsObjectivec from 'highlight.js/lib/languages/objectivec.js';
+import hljsOcaml from 'highlight.js/lib/languages/ocaml.js';
+import hljsPerl from 'highlight.js/lib/languages/perl.js';
+import hljsPhp from 'highlight.js/lib/languages/php.js';
+import hljsPowershell from 'highlight.js/lib/languages/powershell.js';
+import hljsPuppet from 'highlight.js/lib/languages/puppet.js';
+import hljsPython from 'highlight.js/lib/languages/python.js';
+import hljsR from 'highlight.js/lib/languages/r.js';
+import hljsRuby from 'highlight.js/lib/languages/ruby.js';
+import hljsRust from 'highlight.js/lib/languages/rust.js';
+import hljsScala from 'highlight.js/lib/languages/scala.js';
+import hljsScheme from 'highlight.js/lib/languages/scheme.js';
+import hljsScss from 'highlight.js/lib/languages/scss.js';
+import hljsSmalltalk from 'highlight.js/lib/languages/smalltalk.js';
+import hljsSql from 'highlight.js/lib/languages/sql.js';
+import hljsSwift from 'highlight.js/lib/languages/swift.js';
+import hljsTex from 'highlight.js/lib/languages/tex.js';
+import hljsVbnet from 'highlight.js/lib/languages/vbnet.js';
+import hljsVbscript from 'highlight.js/lib/languages/vbscript.js';
+import hljsVerilog from 'highlight.js/lib/languages/verilog.js';
+import hljsXml from 'highlight.js/lib/languages/xml.js';
+import hljsYaml from 'highlight.js/lib/languages/yaml.js';
+
+hlJS.registerLanguage('actionscript', hljsActionscript);
+hlJS.registerLanguage('applescript', hljsApplescript);
+hlJS.registerLanguage('bash', hljsBash);
+hlJS.registerLanguage('clojure', hljsClojure);
+hlJS.registerLanguage('coffeescript', hljsCoffeescript);
+hlJS.registerLanguage('cpp', hljsCpp);
+hlJS.registerLanguage('cs', hljsCs);
+hlJS.registerLanguage('css', hljsCss);
+hlJS.registerLanguage('d', hljsD);
+hlJS.registerLanguage('dart', hljsDart);
+hlJS.registerLanguage('delphi', hljsDelphi);
+hlJS.registerLanguage('diff', hljsDiff);
+hlJS.registerLanguage('django', hljsDjango);
+hlJS.registerLanguage('dockerfile', hljsDockerfile);
+hlJS.registerLanguage('erlang', hljsErlang);
+hlJS.registerLanguage('fortran', hljsFortran);
+hlJS.registerLanguage('fsharp', hljsFsharp);
+hlJS.registerLanguage('gcode', hljsGcode);
+hlJS.registerLanguage('go', hljsGo);
+hlJS.registerLanguage('groovy', hljsGroovy);
+hlJS.registerLanguage('handlebars', hljsHandlebars);
+hlJS.registerLanguage('haskell', hljsHaskell);
+hlJS.registerLanguage('haxe', hljsHaxe);
+hlJS.registerLanguage('java', hljsJava);
+hlJS.registerLanguage('javascript', hljsJavascript);
+hlJS.registerLanguage('json', hljsJson);
+hlJS.registerLanguage('julia', hljsJulia);
+hlJS.registerLanguage('kotlin', hljsKotlin);
+hlJS.registerLanguage('less', hljsLess);
+hlJS.registerLanguage('lisp', hljsLisp);
+hlJS.registerLanguage('lua', hljsLua);
+hlJS.registerLanguage('makefile', hljsMakefile);
+hlJS.registerLanguage('markdown', hljsMarkdown);
+hlJS.registerLanguage('matlab', hljsMatlab);
+hlJS.registerLanguage('objectivec', hljsObjectivec);
+hlJS.registerLanguage('ocaml', hljsOcaml);
+hlJS.registerLanguage('perl', hljsPerl);
+hlJS.registerLanguage('php', hljsPhp);
+hlJS.registerLanguage('powershell', hljsPowershell);
+hlJS.registerLanguage('puppet', hljsPuppet);
+hlJS.registerLanguage('python', hljsPython);
+hlJS.registerLanguage('r', hljsR);
+hlJS.registerLanguage('ruby', hljsRuby);
+hlJS.registerLanguage('rust', hljsRust);
+hlJS.registerLanguage('scala', hljsScala);
+hlJS.registerLanguage('scheme', hljsScheme);
+hlJS.registerLanguage('scss', hljsScss);
+hlJS.registerLanguage('smalltalk', hljsSmalltalk);
+hlJS.registerLanguage('sql', hljsSql);
+hlJS.registerLanguage('swift', hljsSwift);
+hlJS.registerLanguage('tex', hljsTex);
+hlJS.registerLanguage('vbnet', hljsVbnet);
+hlJS.registerLanguage('vbscript', hljsVbscript);
+hlJS.registerLanguage('verilog', hljsVerilog);
+hlJS.registerLanguage('xml', hljsXml);
+hlJS.registerLanguage('yaml', hljsYaml);
+
+const HighlightedLanguages = Constants.HighlightedLanguages;
+
+export function formatCode(lang, data, filename) {
+ var language = lang || '';
+ var parsed;
+ var header = '';
+
+ language = language.toLowerCase();
+
+ if (HighlightedLanguages[language]) {
+ var name = HighlightedLanguages[language].name;
+
+ if (filename) {
+ const fname = decodeURIComponent(Utils.getFileName(filename));
+ name = fname + ' - ' + name;
+ }
+
+ header = '<span class="post-body--code__language">' + name + '</span>';
+
+ try {
+ parsed = hlJS.highlight(language, data).value;
+ } catch (e) {
+ parsed = TextFormatting.sanitizeHtml(data);
+ }
+ } else {
+ parsed = TextFormatting.sanitizeHtml(data);
+ }
+
+ const lines = data.match(/\r\n|\r|\n|$/g).length;
+ var strlines = '';
+ for (var i = 1; i <= lines; i++) {
+ if (strlines) {
+ strlines += '\n' + i;
+ } else {
+ strlines += i;
+ }
+ }
+
+ return (
+ '<div class="post-body--code">' +
+ header +
+ '<pre>' +
+ '<code class="hljs">' +
+ '<table>' +
+ '<tbody>' +
+ '<tr>' +
+ '<td class="post-body--code__lineno">' + strlines + '</td>' +
+ '<td>' +
+ parsed +
+ '</td>' +
+ '</tr>' +
+ '</tbody>' +
+ '</table>' +
+ '</code>' +
+ '</pre>' +
+ '</div>'
+ );
+}
+
+export function getLang(filename) {
+ const fileInfo = Utils.splitFileLocation(filename);
+ var ext = fileInfo.ext;
+ if (!ext) {
+ return null;
+ }
+
+ ext = ext.toLowerCase();
+ for (var key in HighlightedLanguages) {
+ if (HighlightedLanguages[key].extensions.find((x) => x === ext)) {
+ return key;
+ }
+ }
+ return null;
+}
diff --git a/webapp/utils/utils.jsx b/webapp/utils/utils.jsx
index fbed9a082..12a7ff50e 100644
--- a/webapp/utils/utils.jsx
+++ b/webapp/utils/utils.jsx
@@ -680,7 +680,7 @@ export function applyTheme(theme) {
}
if (theme.centerChannelBg) {
- changeCss('.app__content, .markdown__table, .markdown__table tbody tr, .suggestion-list__content, .modal .modal-content', 'background:' + theme.centerChannelBg, 1);
+ changeCss('.app__content, .markdown__table, .markdown__table tbody tr, .suggestion-list__content, .modal .modal-content, .modal .modal-back', 'background:' + theme.centerChannelBg, 1);
changeCss('#post-list .post-list-holder-by-time', 'background:' + theme.centerChannelBg, 1);
changeCss('#post-create', 'background:' + theme.centerChannelBg, 1);
changeCss('.date-separator .separator__text, .new-separator .separator__text', 'background:' + theme.centerChannelBg, 1);