// Crayon Syntax Highlighter Theme Editor JavaScript (function ($) { CrayonSyntaxThemeEditor = new function () { var base = this; var crayonSettings = CrayonSyntaxSettings; var adminSettings = CrayonAdminSettings; var settings = CrayonThemeEditorSettings; var strings = CrayonThemeEditorStrings; var adminStrings = CrayonAdminStrings; var admin = CrayonSyntaxAdmin; var preview, previewCrayon, previewCSS, status, title, info; var colorPickerPos; var changed, loaded; var themeID, themeJSON, themeCSS, themeStr, themeInfo; var reImportant = /\s+!important$/gmi; var reSize = /^[0-9-]+px$/; var reCopy = /-copy(-\d+)?$/; var changedAttr = 'data-value'; var borderCSS = {'border': true, 'border-left': true, 'border-right': true, 'border-top': true, 'border-bottom': true}; base.init = function (callback) { // Called only once CrayonUtil.log('editor init'); base.initUI(); if (callback) { callback(); } }; base.show = function (callback, crayon) { // Called each time editor is shown previewCrayon = crayon.find('.crayon-syntax'); preview.append(crayon) base.load(); if (callback) { callback(); } }; base.load = function () { loaded = false; themeStr = adminSettings.currThemeCSS; themeID = adminSettings.currTheme; changed = false; themeJSON = CSSJSON.toJSON(themeStr, { stripComments: true, split: true }); themeJSON = base.filterCSS(themeJSON); CrayonUtil.log(themeJSON); themeInfo = base.readCSSInfo(themeStr); base.removeExistingCSS(); base.initInfoUI(); base.updateTitle(); base.updateInfo(); base.setFieldValues(themeInfo); base.populateAttributes(); base.updateLiveCSS(); base.updateUI(); loaded = true; }; base.save = function () { // Update info from form fields themeInfo = base.getFieldValues($.keys(themeInfo)); // Get the names of the fields and map them to their values var names = base.getFieldNames(themeInfo); var info = {}; for (var id in themeInfo) { info[names[id]] = themeInfo[id]; } // Update attributes base.persistAttributes(); // Save themeCSS = CSSJSON.toCSS(themeJSON); var newThemeStr = base.writeCSSInfo(info) + themeCSS; CrayonUtil.postAJAX({ action: 'crayon-theme-editor-save', id: themeID, name: base.getName(), css: newThemeStr }, function (result) { status.show(); result = parseInt(result); if (result > 0) { status.html(strings.success); if (result === 2) { window.GET['theme-editor'] = 1; CrayonUtil.reload(); } } else { status.html(strings.fail); } changed = false; setTimeout(function () { status.fadeOut(); }, 1000); }); }; base.del = function (id, name) { admin.createDialog({ title: strings.del, html: strings.deleteThemeConfirm.replace('%s', name), yes: function () { CrayonUtil.postAJAX({ action: 'crayon-theme-editor-delete', id: id }, function (result) { if (result > 0) { CrayonUtil.reload(); } else { admin.createAlert({ html: strings.deleteFail + ' ' + strings.checkLog }); } }); }, options: { selectedButtonIndex: 2 } }); }; base.duplicate = function (id, name) { base.createPrompt({ //html: "Are you sure you want to duplicate the '" + name + "' theme?", title: strings.duplicate, text: strings.newName, value: base.getNextAvailableName(id), ok: function (val) { CrayonUtil.postAJAX({ action: 'crayon-theme-editor-duplicate', id: id, name: val }, function (result) { if (result > 0) { CrayonUtil.reload(); } else { admin.createAlert({ html: strings.duplicateFail + ' ' + strings.checkLog }); } }); } }); }; base.submit = function (id, name) { base.createPrompt({ title: strings.submit, desc: strings.submitText, text: strings.message, value: strings.submitMessage, ok: function (val) { CrayonUtil.postAJAX({ action: 'crayon-theme-editor-submit', id: id, message: val }, function (result) { var msg = result > 0 ? strings.submitSucceed : strings.submitFail + ' ' + strings.checkLog; admin.createAlert({ html: msg }); }); } }); }; base.getNextAvailableName = function (id) { var next = base.getNextAvailableID(id); return base.idToName(next[1]); }; base.getNextAvailableID = function (id) { var themes = adminSettings.themes; var count = 0; if (reCopy.test(id)) { // Remove the "copy" if it already exists var newID = id.replace(reCopy, ''); if (newID.length > 0) { id = newID; } } var nextID = id; while (nextID in themes) { count++; if (count == 1) { nextID = id + '-copy'; } else { nextID = id + '-copy-' + count.toString(); } } return [count, nextID]; }; base.readCSSInfo = function (cssStr) { var infoStr = /^\s*\/\*[\s\S]*?\*\//gmi.exec(cssStr); var themeInfo = {}; var match = null; var infoRegex = /([^\r\n:]*[^\r\n\s:])\s*:\s*([^\r\n]+)/gmi; while ((match = infoRegex.exec(infoStr)) != null) { themeInfo[base.nameToID(match[1])] = CrayonUtil.encode_html(match[2]); } // Force title case on the name if (themeInfo.name) { themeInfo.name = base.idToName(themeInfo.name); } return themeInfo; }; base.getFieldName = function (id) { var name = ''; if (id in settings.fields) { name = settings.fields[id]; } else { name = base.idToName(id); } return name; }; base.getFieldNames = function (fields) { var names = {}; for (var id in fields) { names[id] = base.getFieldName(id); } return names; }; base.removeExistingCSS = function () { // Remove the old '); }; base.removeStyle = function () { previewCSS.html(''); }; base.writeCSSInfo = function (info) { var infoStr = '/*\n'; for (var field in info) { infoStr += field + ': ' + info[field] + '\n'; } return infoStr + '*/\n'; }; base.filterCSS = function (css) { // Split all border CSS attributes into individual attributes for (var child in css.children) { var atts = css.children[child].attributes; for (var att in atts) { if (att in borderCSS) { var rules = base.getBorderCSS(atts[att]); for (var rule in rules) { atts[att + '-' + rule] = rules[rule]; } delete atts[att]; } } } return css; }, base.getBorderCSS = function (css) { var result = {}; var important = base.isImportant(css); $.each(strings.borderStyles, function (i, style) { if (css.indexOf(style) >= 0) { result.style = style; } }); var width = /\d+\s*(px|%|em|rem)/gi.exec(css); if (width) { result.width = width[0]; } var color = /#\w+/gi.exec(css); if (color) { result.color = color[0]; } if (important) { for (var rule in result) { result[rule] = base.addImportant(result[rule]); } } return result; }, base.createPrompt = function (args) { args = $.extend({ title: adminStrings.prompt, text: adminStrings.value, desc: null, value: '', options: { buttons: { "OK": function () { if (args.ok) { args.ok(base.getFieldValue('prompt-text')); } $(this).crayonDialog('close'); }, "Cancel": function () { $(this).crayonDialog('close'); } }, open: function () { base.getField('prompt-text').val(args.value).focus(); } } }, args); args.html = '
' + args.desc + ' | |
' + args.text + ': | ' + base.createInput('prompt-text') + ' |