summaryrefslogtreecommitdiffstats
path: root/webapp/utils
diff options
context:
space:
mode:
authorHarrison Healey <harrisonmhealey@gmail.com>2016-06-01 08:28:54 -0400
committerChristopher Speller <crspeller@gmail.com>2016-06-01 08:28:54 -0400
commitf5ccfb362e724508e1a29e7f7d8cb30ffd49c2c1 (patch)
tree8b6fff1a46a2720a65079bade15ce9d79ffbaa02 /webapp/utils
parent85ccd6759361099d2bfd069d144fd8f234549c52 (diff)
downloadchat-f5ccfb362e724508e1a29e7f7d8cb30ffd49c2c1.tar.gz
chat-f5ccfb362e724508e1a29e7f7d8cb30ffd49c2c1.tar.bz2
chat-f5ccfb362e724508e1a29e7f7d8cb30ffd49c2c1.zip
Reorganized syntax highlighting code and added search term highlighting for code blocks with syntax highlighting (#3191)
Diffstat (limited to 'webapp/utils')
-rw-r--r--webapp/utils/markdown.jsx49
-rw-r--r--webapp/utils/syntax_hightlighting.jsx83
2 files changed, 65 insertions, 67 deletions
diff --git a/webapp/utils/markdown.jsx b/webapp/utils/markdown.jsx
index 7fd165134..6691b57b2 100644
--- a/webapp/utils/markdown.jsx
+++ b/webapp/utils/markdown.jsx
@@ -2,7 +2,7 @@
// See License.txt for license information.
import * as TextFormatting from './text_formatting.jsx';
-import * as syntaxHightlighting from './syntax_hightlighting.jsx';
+import * as SyntaxHighlighting from './syntax_hightlighting.jsx';
import marked from 'marked';
import katex from 'katex';
@@ -43,7 +43,52 @@ class MattermostMarkdownRenderer extends marked.Renderer {
usedLanguage = 'xml';
}
- return syntaxHightlighting.formatCode(usedLanguage, code, null, this.formattingOptions.searchTerm);
+ let className = 'post-code';
+ if (!usedLanguage) {
+ className += ' post-code--wrap';
+ }
+
+ let header = '';
+ if (SyntaxHighlighting.canHighlight(usedLanguage)) {
+ header = (
+ '<span class="post-code__language">' +
+ SyntaxHighlighting.getLanguageName(language) +
+ '</span>'
+ );
+ }
+
+ // if we have to apply syntax highlighting AND highlighting of search terms, create two copies
+ // of the code block, one with syntax highlighting applied and another with invisible text, but
+ // search term highlighting and overlap them
+ const content = SyntaxHighlighting.highlight(usedLanguage, code);
+ let searchedContent = '';
+
+ if (this.formattingOptions.searchTerm) {
+ const tokens = new Map();
+
+ let searched = TextFormatting.sanitizeHtml(code);
+ searched = TextFormatting.highlightSearchTerms(searched, tokens, this.formattingOptions.searchTerm);
+
+ if (tokens.size > 0) {
+ searched = TextFormatting.replaceTokens(searched, tokens);
+
+ searchedContent = (
+ '<div class="post-code__search-highlighting">' +
+ searched +
+ '</div>'
+ );
+ }
+ }
+
+ return (
+ '<div class="' + className + '">' +
+ header +
+ '<code class="hljs">' +
+ searchedContent +
+ content +
+ '</code>' +
+ '</div>'
+ );
}
codespan(text) {
diff --git a/webapp/utils/syntax_hightlighting.jsx b/webapp/utils/syntax_hightlighting.jsx
index 33b3e2d3d..ce904c41f 100644
--- a/webapp/utils/syntax_hightlighting.jsx
+++ b/webapp/utils/syntax_hightlighting.jsx
@@ -123,80 +123,21 @@ hlJS.registerLanguage('yaml', hljsYaml);
const HighlightedLanguages = Constants.HighlightedLanguages;
-export function formatCode(lang, data, filename, searchTerm) {
- const language = lang.toLowerCase() || '';
-
- let contents;
- let header = '';
- let className = 'post-code';
+export function highlight(lang, code) {
+ const language = lang.toLowerCase();
if (HighlightedLanguages[language]) {
- let name = HighlightedLanguages[language].name;
-
- if (filename) {
- const fname = decodeURIComponent(Utils.getFileName(filename));
- name = fname + ' - ' + name;
- }
-
- header = '<span class="post-code__language">' + name + '</span>';
-
try {
- contents = hlJS.highlight(language, data).value;
+ return hlJS.highlight(language, code).value;
} catch (e) {
- contents = TextFormatting.sanitizeHtml(data);
+ // fall through if highlighting fails and handle below
}
- } else {
- contents = TextFormatting.sanitizeHtml(data);
}
- if (!language) {
- // wrap when no language is specified
- className += ' post-code--wrap';
-
- const tokens = new Map();
- contents = TextFormatting.highlightSearchTerms(contents, tokens, searchTerm);
- contents = TextFormatting.replaceTokens(contents, tokens);
- }
-
- if (filename) {
- // add line numbers when viewing a code file preview
- const lines = data.match(/\r\n|\r|\n|$/g).length;
- let strlines = '';
- for (let i = 1; i <= lines; i++) {
- if (strlines) {
- strlines += '\n' + i;
- } else {
- strlines += i;
- }
- }
-
- contents = (
- '<table>' +
- '<tbody>' +
- '<tr>' +
- '<td class="post-code__lineno">' + strlines + '</td>' +
- '<td>' +
- contents +
- '</td>' +
- '</tr>' +
- '</tbody>' +
- '</table>'
- );
- }
-
- return (
- '<div class="' + className + '">' +
- header +
- '<pre>' +
- '<code class="hljs">' +
- contents +
- '</code>' +
- '</pre>' +
- '</div>'
- );
+ return TextFormatting.sanitizeHtml(code);
}
-export function getLang(filename) {
+export function getLanguageFromFilename(filename) {
const fileInfo = Utils.splitFileLocation(filename);
var ext = fileInfo.ext;
if (!ext) {
@@ -211,3 +152,15 @@ export function getLang(filename) {
}
return null;
}
+
+export function canHighlight(language) {
+ return !!HighlightedLanguages[language.toLowerCase()];
+}
+
+export function getLanguageName(language) {
+ if (canHighlight(language)) {
+ return HighlightedLanguages[language.toLowerCase()].name;
+ }
+
+ return '';
+} \ No newline at end of file