diff options
author | Harrison Healey <harrisonmhealey@gmail.com> | 2015-10-30 09:21:53 -0400 |
---|---|---|
committer | Harrison Healey <harrisonmhealey@gmail.com> | 2015-10-30 09:21:53 -0400 |
commit | c2cd58a33f52c6567e39d8ba563425dc06916d41 (patch) | |
tree | 492f80236bf30aa05514f1428296cf6b0432f435 /web/react/utils | |
parent | b686e51cfde4c50fba8e2797a532c8813ee8aade (diff) | |
parent | d630567c91d01d5b78be84ac1a5e638e4e72516c (diff) | |
download | chat-c2cd58a33f52c6567e39d8ba563425dc06916d41.tar.gz chat-c2cd58a33f52c6567e39d8ba563425dc06916d41.tar.bz2 chat-c2cd58a33f52c6567e39d8ba563425dc06916d41.zip |
Merge pull request #1220 from florianorben/PLT-395
PLT-395: Add syntax highlighting to Markdown code blocks
Diffstat (limited to 'web/react/utils')
-rw-r--r-- | web/react/utils/constants.jsx | 32 | ||||
-rw-r--r-- | web/react/utils/markdown.jsx | 71 | ||||
-rw-r--r-- | web/react/utils/utils.jsx | 26 |
3 files changed, 129 insertions, 0 deletions
diff --git a/web/react/utils/constants.jsx b/web/react/utils/constants.jsx index 43d81d322..1593f6706 100644 --- a/web/react/utils/constants.jsx +++ b/web/react/utils/constants.jsx @@ -304,6 +304,13 @@ module.exports = { uiName: 'Mention Highlight Link' } ], + CODE_THEMES: { + github: 'GitHub', + solarized_light: 'Solarized light', + monokai: 'Monokai', + solarized_dark: 'Solarized Dark' + }, + DEFAULT_CODE_THEME: 'github', Preferences: { CATEGORY_DIRECT_CHANNEL_SHOW: 'direct_channel_show', CATEGORY_DISPLAY_SETTINGS: 'display_settings', @@ -318,5 +325,30 @@ module.exports = { ENTER: 13, ESCAPE: 27, SPACE: 32 + }, + 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' } }; diff --git a/web/react/utils/markdown.jsx b/web/react/utils/markdown.jsx index e34f3d00a..179416ea0 100644 --- a/web/react/utils/markdown.jsx +++ b/web/react/utils/markdown.jsx @@ -6,6 +6,34 @@ const Utils = require('./utils.jsx'); const marked = require('marked'); +const highlightJs = require('highlight.js/lib/highlight.js'); +const highlightJsDiff = require('highlight.js/lib/languages/diff.js'); +const highlightJsApache = require('highlight.js/lib/languages/apache.js'); +const highlightJsMakefile = require('highlight.js/lib/languages/makefile.js'); +const highlightJsHttp = require('highlight.js/lib/languages/http.js'); +const highlightJsJson = require('highlight.js/lib/languages/json.js'); +const highlightJsMarkdown = require('highlight.js/lib/languages/markdown.js'); +const highlightJsJavascript = require('highlight.js/lib/languages/javascript.js'); +const highlightJsCss = require('highlight.js/lib/languages/css.js'); +const highlightJsNginx = require('highlight.js/lib/languages/nginx.js'); +const highlightJsObjectivec = require('highlight.js/lib/languages/objectivec.js'); +const highlightJsPython = require('highlight.js/lib/languages/python.js'); +const highlightJsXml = require('highlight.js/lib/languages/xml.js'); +const highlightJsPerl = require('highlight.js/lib/languages/perl.js'); +const highlightJsBash = require('highlight.js/lib/languages/bash.js'); +const highlightJsPhp = require('highlight.js/lib/languages/php.js'); +const highlightJsCoffeescript = require('highlight.js/lib/languages/coffeescript.js'); +const highlightJsCs = require('highlight.js/lib/languages/cs.js'); +const highlightJsCpp = require('highlight.js/lib/languages/cpp.js'); +const highlightJsSql = require('highlight.js/lib/languages/sql.js'); +const highlightJsGo = require('highlight.js/lib/languages/go.js'); +const highlightJsRuby = require('highlight.js/lib/languages/ruby.js'); +const highlightJsJava = require('highlight.js/lib/languages/java.js'); +const highlightJsIni = require('highlight.js/lib/languages/ini.js'); + +const Constants = require('../utils/constants.jsx'); +const HighlightedLanguages = Constants.HighlightedLanguages; + class MattermostInlineLexer extends marked.InlineLexer { constructor(links, options) { super(links, options); @@ -51,6 +79,49 @@ class MattermostMarkdownRenderer extends marked.Renderer { this.text = this.text.bind(this); this.formattingOptions = formattingOptions; + + 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); + } + + code(code, language) { + let usedLanguage = language; + + if (String(usedLanguage).toLocaleLowerCase() === 'html') { + usedLanguage = 'xml'; + } + + if (!usedLanguage || highlightJs.listLanguages().indexOf(usedLanguage) < 0) { + let parsed = super.code(code, usedLanguage); + return '<div class="post-body--code"><code class="hljs">' + TextFormatting.sanitizeHtml($(parsed).text()) + '</code></div>'; + } + + let parsed = highlightJs.highlight(usedLanguage, code); + return '<div class="post-body--code">' + + '<span class="post-body--code__language">' + HighlightedLanguages[usedLanguage] + '</span>' + + '<code class="hljs">' + parsed.value + '</code>' + + '</div>'; } br() { diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx index 35ce49ae2..c7c8549b9 100644 --- a/web/react/utils/utils.jsx +++ b/web/react/utils/utils.jsx @@ -424,6 +424,11 @@ export function toTitleCase(str) { } export function applyTheme(theme) { + if (!theme.codeTheme) { + theme.codeTheme = Constants.DEFAULT_CODE_THEME; + } + updateCodeTheme(theme.codeTheme); + if (theme.sidebarBg) { changeCss('.sidebar--left, .settings-modal .settings-table .settings-links, .sidebar--menu', 'background:' + theme.sidebarBg, 1); } @@ -612,6 +617,27 @@ export function rgb2hex(rgbIn) { return '#' + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]); } +export function updateCodeTheme(theme) { + const path = '/static/css/highlight/' + theme + '.css'; + const $link = $('link.code_theme'); + if (path !== $link.attr('href')) { + changeCss('code.hljs', 'visibility: hidden'); + var xmlHTTP = new XMLHttpRequest(); + xmlHTTP.open('GET', path, true); + xmlHTTP.onload = function onLoad() { + $link.attr('href', path); + if (isBrowserFirefox()) { + $link.one('load', () => { + changeCss('code.hljs', 'visibility: visible'); + }); + } else { + changeCss('code.hljs', 'visibility: visible'); + } + }; + xmlHTTP.send(); + } +} + export function placeCaretAtEnd(el) { el.focus(); if (typeof window.getSelection != 'undefined' && typeof document.createRange != 'undefined') { |