Этот коммит содержится в:
=Corey Hulen
2016-03-17 09:51:45 -07:00
родитель 074f15f761 128204b47a
Коммит 5273559ca1
90 изменённых файлов: 2766 добавлений и 1650 удалений

Просмотреть файл

@@ -781,12 +781,12 @@ export function savePreferences(preferences, success, error) {
);
}
export function getSuggestedCommands(command, suggestionId, component) {
client.listCommands(
export function getSuggestedCommands(command, channelId, suggestionId, component) {
client.listCommands({command: command, channelId: channelId},
(data) => {
var matches = [];
data.forEach((cmd) => {
if (('/' + cmd.trigger).indexOf(command) === 0) {
if (('/' + cmd.trigger).indexOf(command) === 0 || cmd.external_management) {
let s = '/' + cmd.trigger;
let hint = '';
if (cmd.auto_complete_hint && cmd.auto_complete_hint.length !== 0) {

Просмотреть файл

@@ -1031,12 +1031,13 @@ export function regenCommandToken(data, success, error) {
});
}
export function listCommands(success, error) {
export function listCommands(data, success, error) {
$.ajax({
url: '/api/v1/commands/list',
dataType: 'json',
contentType: 'application/json',
type: 'GET',
type: 'POST',
data: JSON.stringify(data),
success,
error: function onError(xhr, status, err) {
var e = handleError('listCommands', xhr, status, err);

Просмотреть файл

@@ -145,7 +145,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: {
@@ -515,30 +515,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,
@@ -561,6 +595,10 @@ export default {
EMBED_TOGGLE: {
label: 'embed_toggle',
description: 'Show toggle for all embed previews'
},
SLASHCMD_AUTOCMP: {
label: 'slashCmd_autocmp',
description: 'Enable external application to offer slash command autocomplete'
}
},
OVERLAY_TIME_DELAY: 400,

Просмотреть файл

@@ -1,65 +1,14 @@
// 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';
import 'katex/dist/katex.min.css';
import Constants from 'utils/constants.jsx';
const HighlightedLanguages = Constants.HighlightedLanguages;
function markdownImageLoaded(image) {
image.style.height = 'auto';
}
@@ -110,31 +59,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 +73,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) {

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;
}

Просмотреть файл

@@ -213,6 +213,11 @@ function highlightCurrentMentions(text, tokens) {
}
for (const mention of UserStore.getCurrentMentionKeys()) {
// occasionally we get an empty mention which matches a bunch of empty strings
if (!mention) {
continue;
}
output = output.replace(new RegExp(`(^|\\W)(${escapeRegex(mention)})\\b`, 'gi'), replaceCurrentMentionWithToken);
}

Просмотреть файл

@@ -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);
@@ -763,7 +763,6 @@ export function applyTheme(theme) {
if (theme.buttonBg) {
changeCss('.btn.btn-primary, .tutorial__circles .circle.active', 'background:' + theme.buttonBg, 1);
changeCss('.btn.btn-primary:hover, .btn.btn-primary:active, .btn.btn-primary:focus', 'background:' + changeColor(theme.buttonBg, -0.25), 1);
changeCss('.file-playback__controls', 'color:' + changeColor(theme.buttonBg, -0.25), 1);
}
if (theme.buttonColor) {