Merge pull request #2380 from rodrigocorsi2/code_preview
Created component CodePreview
Этот коммит содержится в:
101
webapp/components/code_preview.jsx
Обычный файл
101
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
|
||||||
|
};
|
||||||
@@ -7,6 +7,7 @@ import * as Client from 'utils/client.jsx';
|
|||||||
import * as Utils from 'utils/utils.jsx';
|
import * as Utils from 'utils/utils.jsx';
|
||||||
import AudioVideoPreview from './audio_video_preview.jsx';
|
import AudioVideoPreview from './audio_video_preview.jsx';
|
||||||
import Constants from 'utils/constants.jsx';
|
import Constants from 'utils/constants.jsx';
|
||||||
|
import CodePreview from './code_preview.jsx';
|
||||||
import FileInfoPreview from './file_info_preview.jsx';
|
import FileInfoPreview from './file_info_preview.jsx';
|
||||||
import FileStore from 'stores/file_store.jsx';
|
import FileStore from 'stores/file_store.jsx';
|
||||||
import ViewImagePopoverBar from './view_image_popover_bar.jsx';
|
import ViewImagePopoverBar from './view_image_popover_bar.jsx';
|
||||||
@@ -254,6 +255,15 @@ class ViewImageModal extends React.Component {
|
|||||||
formatMessage={this.props.intl.formatMessage}
|
formatMessage={this.props.intl.formatMessage}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
} else if (CodePreview.support(filename)) {
|
||||||
|
content = (
|
||||||
|
<CodePreview
|
||||||
|
filename={filename}
|
||||||
|
fileUrl={fileUrl}
|
||||||
|
fileInfo={fileInfo}
|
||||||
|
formatMessage={this.props.intl.formatMessage}
|
||||||
|
/>
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
content = (
|
content = (
|
||||||
<FileInfoPreview
|
<FileInfoPreview
|
||||||
@@ -323,6 +333,7 @@ class ViewImageModal extends React.Component {
|
|||||||
onClick={this.props.onModalDismissed}
|
onClick={this.props.onModalDismissed}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
className='modal-back'
|
||||||
onMouseEnter={this.onMouseEnterImage}
|
onMouseEnter={this.onMouseEnterImage}
|
||||||
onMouseLeave={this.onMouseLeaveImage}
|
onMouseLeave={this.onMouseLeaveImage}
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
|||||||
@@ -234,6 +234,7 @@
|
|||||||
|
|
||||||
.file-details__container {
|
.file-details__container {
|
||||||
@include display-flex;
|
@include display-flex;
|
||||||
|
background: $white;
|
||||||
|
|
||||||
.file-details {
|
.file-details {
|
||||||
height: 270px;
|
height: 270px;
|
||||||
|
|||||||
@@ -256,13 +256,27 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
background: $white;
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
min-height: 100px;
|
min-height: 100px;
|
||||||
min-width: 320px;
|
min-width: 320px;
|
||||||
position: relative;
|
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 {
|
img {
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
|||||||
@@ -22,29 +22,63 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.post-body--code {
|
.post-body--code {
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
margin-bottom: 0;
|
border: 1px solid rgba(221,221,221,0.2);
|
||||||
overflow: auto;
|
border-radius: .25em;
|
||||||
word-break: normal;
|
margin: 0;
|
||||||
word-wrap: normal;
|
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 {
|
.post-body--code__language {
|
||||||
|
@include opacity(0);
|
||||||
@include translate3d(0, 0, 0);
|
@include translate3d(0, 0, 0);
|
||||||
background: #21586d;
|
background: #21586d;
|
||||||
|
border-radius: 0 .25em;
|
||||||
color: $white;
|
color: $white;
|
||||||
font-size: 13px;
|
|
||||||
opacity: .7;
|
|
||||||
padding: 4px 10px 5px;
|
padding: 4px 10px 5px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 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;
|
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 {
|
.post__body {
|
||||||
hr {
|
hr {
|
||||||
@include opacity(.2);
|
@include opacity(.2);
|
||||||
@@ -108,9 +142,9 @@ blockquote {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
border: none;
|
|
||||||
color: inherit;
|
color: inherit;
|
||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ export default {
|
|||||||
PRESENTATION_TYPES: ['ppt', 'pptx'],
|
PRESENTATION_TYPES: ['ppt', 'pptx'],
|
||||||
SPREADSHEET_TYPES: ['xlsx', 'csv'],
|
SPREADSHEET_TYPES: ['xlsx', 'csv'],
|
||||||
WORD_TYPES: ['doc', 'docx'],
|
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'],
|
PDF_TYPES: ['pdf'],
|
||||||
PATCH_TYPES: ['patch'],
|
PATCH_TYPES: ['patch'],
|
||||||
ICON_FROM_TYPE: {
|
ICON_FROM_TYPE: {
|
||||||
@@ -514,30 +514,64 @@ export default {
|
|||||||
SPACE: 32,
|
SPACE: 32,
|
||||||
TAB: 9
|
TAB: 9
|
||||||
},
|
},
|
||||||
|
CODE_PREVIEW_MAX_FILE_SIZE: 500000, // 500 KB
|
||||||
HighlightedLanguages: {
|
HighlightedLanguages: {
|
||||||
diff: 'Diff',
|
actionscript: {name: 'ActionScript', extensions: ['as']},
|
||||||
apache: 'Apache',
|
applescript: {name: 'AppleScript', extensions: ['applescript', 'osascript', 'scpt']},
|
||||||
makefile: 'Makefile',
|
bash: {name: 'Bash', extensions: ['bash', 'sh', 'zsh']},
|
||||||
http: 'HTTP',
|
clojure: {name: 'Clojure', extensions: ['clj', 'boot', 'cl2', 'cljc', 'cljs', 'cljs.hl', 'cljscm', 'cljx', 'hic']},
|
||||||
json: 'JSON',
|
coffeescript: {name: 'CoffeeScript', extensions: ['coffee', '_coffee', 'cake', 'cjsx', 'cson', 'iced']},
|
||||||
markdown: 'Markdown',
|
cpp: {name: 'C/C++', extensions: ['cpp', 'c', 'cc', 'h', 'c++', 'h++', 'hpp']},
|
||||||
javascript: 'JavaScript',
|
cs: {name: 'C#', extensions: ['cs', 'csharp']},
|
||||||
css: 'CSS',
|
css: {name: 'CSS', extensions: ['css']},
|
||||||
nginx: 'nginx',
|
d: {name: 'D', extensions: ['d', 'di']},
|
||||||
objectivec: 'Objective-C',
|
dart: {name: 'Dart', extensions: ['dart']},
|
||||||
python: 'Python',
|
delphi: {name: 'Delphi', extensions: ['delphi', 'dpr', 'dfm', 'pas', 'pascal', 'freepascal', 'lazarus', 'lpr', 'lfm']},
|
||||||
xml: 'XML',
|
diff: {name: 'Diff', extensions: ['diff', 'patch']},
|
||||||
perl: 'Perl',
|
django: {name: 'Django', extensions: ['django', 'jinja']},
|
||||||
bash: 'Bash',
|
dockerfile: {name: 'Dockerfile', extensions: ['dockerfile', 'docker']},
|
||||||
php: 'PHP',
|
erlang: {name: 'Erlang', extensions: ['erl']},
|
||||||
coffeescript: 'CoffeeScript',
|
fortran: {name: 'Fortran', extensions: ['f90', 'f95']},
|
||||||
cs: 'C#',
|
fsharp: {name: 'F#', extensions: ['fsharp', 'fs']},
|
||||||
cpp: 'C++',
|
gcode: {name: 'G-Code', extensions: ['gcode', 'nc']},
|
||||||
sql: 'SQL',
|
go: {name: 'Go', extensions: ['go']},
|
||||||
go: 'Go',
|
groovy: {name: 'Groovy', extensions: ['groovy']},
|
||||||
ruby: 'Ruby',
|
handlebars: {name: 'Handlebars', extensions: ['handlebars', 'hbs', 'html.hbs', 'html.handlebars']},
|
||||||
java: 'Java',
|
haskell: {name: 'Haskell', extensions: ['hs']},
|
||||||
ini: 'ini'
|
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: {
|
PostsViewJumpTypes: {
|
||||||
BOTTOM: 1,
|
BOTTOM: 1,
|
||||||
|
|||||||
@@ -1,57 +1,9 @@
|
|||||||
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
||||||
// See License.txt for license information.
|
// 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 TextFormatting from './text_formatting.jsx';
|
||||||
import * as Utils from './utils.jsx';
|
import * as Utils from './utils.jsx';
|
||||||
|
import * as syntaxHightlighting from './syntax_hightlighting.jsx';
|
||||||
|
|
||||||
import marked from 'marked';
|
import marked from 'marked';
|
||||||
import katex from 'katex';
|
import katex from 'katex';
|
||||||
@@ -110,31 +62,11 @@ class MattermostMarkdownRenderer extends marked.Renderer {
|
|||||||
this.formattingOptions = formattingOptions;
|
this.formattingOptions = formattingOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
code(code, language, escaped) {
|
code(code, language) {
|
||||||
let usedLanguage = language || '';
|
let usedLanguage = language || '';
|
||||||
usedLanguage = usedLanguage.toLowerCase();
|
usedLanguage = usedLanguage.toLowerCase();
|
||||||
|
|
||||||
// treat html as xml to prevent injection attacks
|
if (usedLanguage === 'tex' || usedLanguage === 'latex') {
|
||||||
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') {
|
|
||||||
try {
|
try {
|
||||||
const html = katex.renderToString(code, {throwOnError: false, displayMode: true});
|
const html = katex.renderToString(code, {throwOnError: false, displayMode: true});
|
||||||
|
|
||||||
@@ -144,13 +76,12 @@ class MattermostMarkdownRenderer extends marked.Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
// treat html as xml to prevent injection attacks
|
||||||
'<pre>' +
|
if (usedLanguage === 'html') {
|
||||||
'<code class="hljs">' +
|
usedLanguage = 'xml';
|
||||||
(escaped ? code : TextFormatting.sanitizeHtml(code)) + '\n' +
|
}
|
||||||
'</code>' +
|
|
||||||
'</pre>'
|
return syntaxHightlighting.formatCode(usedLanguage, code);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
codespan(text) {
|
codespan(text) {
|
||||||
|
|||||||
197
webapp/utils/syntax_hightlighting.jsx
Обычный файл
197
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;
|
||||||
|
}
|
||||||
@@ -680,7 +680,7 @@ export function applyTheme(theme) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (theme.centerChannelBg) {
|
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-list .post-list-holder-by-time', 'background:' + theme.centerChannelBg, 1);
|
||||||
changeCss('#post-create', 'background:' + theme.centerChannelBg, 1);
|
changeCss('#post-create', 'background:' + theme.centerChannelBg, 1);
|
||||||
changeCss('.date-separator .separator__text, .new-separator .separator__text', 'background:' + theme.centerChannelBg, 1);
|
changeCss('.date-separator .separator__text, .new-separator .separator__text', 'background:' + theme.centerChannelBg, 1);
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user