// // Theme Customizer v2.0.0 - from sg-app.js and sg-web.js // var changed = Array(); var TC = function() { this.lessVars = {}; this.nestedLoopText = ''; this.nestedIdentation = ''; this.data = ''; this.cssValidator = true; this.cssLineError = 0; this.cssCustomText = ''; }; TC.prototype = { constructor: TC, // check the attributes that contains what we are looking for checkAttribs: function(node, key) { if ($.isArray(node.attributes)) { for (var i = 0; i < node.attributes.length; i++) { this.checkForDupes(node.attributes[i], key); } } else { for (i in node.attributes) { this.checkForDupes(node.attributes[i], key); } } if (node.nested) this.checkAttribs(node.nested, key); }, // check for duplicates checkForDupes: function(node, key) { // colors var reg = node.match(/(#[A-Fa-f0-9]+)/); if (reg && node.indexOf('\9') === -1) { if (! this.lessVars.colors[reg[0]]) this.lessVars.colors[reg[0]] = []; this.lessVars.colors[reg[0]].push(key); } // fonts reg = node.match(/font-family:\s(.+)/); if (reg && node.indexOf('inherit') === -1) { if (! this.lessVars.fonts[reg[1]]) this.lessVars.fonts[reg[1]] = []; this.lessVars.fonts[reg[1]].push(key); } // size reg = node.match(/.*\s(-?[0-9]+px)$/); if (reg) { if (! this.lessVars.size[' ' + reg[1]]) this.lessVars.size[' ' + reg[1]] = []; this.lessVars.size[' ' + reg[1]].push(key); } }, // check the results after compiling duplicates checkResults: function(node, json, name, min) { var var_count = 0; var var_name = '', j; for (var k in json) { if (json.hasOwnProperty(k) && json[k].length >= min) { var_count++; var_name = name + var_count; this.data += var_name + ': ' + k + ';\n'; for (var i = 0; i < json[k].length; i++) { if ($.isArray(node[json[k][i]].attributes)) { for (j = 0; j < node[json[k][i]].attributes.length; j++) { node[json[k][i]].attributes[j] = node[json[k][i]].attributes[j].replace(k, var_name); } } else { for (j in node[json[k][i]].attributes) { node[json[k][i]].attributes[j] = node[json[k][i]].attributes[j].replace(k, var_name); } } } } } }, // main checking function that uses the 3 above checkForVars: function(node, log) { if (typeof log === "undefined") log = false; this.lessVars.colors = {}; this.lessVars.fonts = {}; this.lessVars.size = {}; this.lessVars.named = {}; for (var k in node) { if ($.inArray(node[k].selector,changed) != -1) { if (node.hasOwnProperty(k) && node[k].selector && node[k].attributes) { if (node[k].var) { // names vars take first attribute value this.lessVars.named[node[k].var] = node[k].attributes[Object.keys(node[k].attributes)[0]]; this.data += node[k].var + ': ' + node[k].attributes[Object.keys(node[k].attributes)[0]] + ';\n'; } else { this.checkAttribs(node[k], k); } } } } this.checkResults(node, this.lessVars.colors, '@color', 5); this.checkResults(node, this.lessVars.fonts, '@font', 3); this.checkResults(node, this.lessVars.size, '@size', 10); if (log) console.log(JSON.stringify(this.lessVars, null, 2)); }, // loop through the nested nodes nestLoop: function(node, tab) { if (typeof tab === "undefined") tab = true; for (var k in node.nested) { if (tab) this.nestedIdentation += ' '; if (node.nested.hasOwnProperty(k)) { this.nestedLoopText += this.nestedIdentation + ' ' + node.nested[k].selector + ' {\n'; if ($.isArray(node.nested[k].attributes)) { for (var i = 0; i < node.nested[k].attributes.length; i++) { this.nestedLoopText += this.nestedIdentation + ' ' + node.nested[k].attributes[i] + ';\n'; } } else { for (i in node.nested[k].attributes) { this.nestedLoopText += this.nestedIdentation + ' ' + i + ': ' + node.nested[k].attributes[i] + ';\n'; } } if (node.nested[k].nested) this.nestLoop(node.nested[k]); this.nestedLoopText += this.nestedIdentation + ' }\n'; this.nestedIdentation = this.nestedIdentation.slice(0, -2); } } }, // looking for duplicate selectors in nested nodes DSnestLoop: function(node, source, undef) { if (typeof undef === "undefined") undef = true; var match = false; for (var k in node) { if (node.hasOwnProperty(k)) { if (undef) { for (var key in source) { match = false; if (source.hasOwnProperty(key) && node[k].selector !== source[key].selector) { match = true; } else { if (node[k].nested) { source[key].nested ? this.DSnestLoop(node[k].nested, source[key].nested) : this.DSnestLoop(node[k].nested, source[key], false); } } } } else { match = true; } if (match) { if (!undef) { source.nested = {}; source.nested = node; } else { $.extend(source, node); } delete(node); } } } }, // pass 1: separate multiple selectors separateMultipleSelectors: function(node, log) { if (typeof log === "undefined") log = false; for (var k in node) { if (node.hasOwnProperty(k) && node[k].selector) { if (node[k].selector.indexOf(',') === -1 && node[k].selector.indexOf('@') === -1) { var selectors = []; var char = node[k].selector[0]; var sel_count = 0; var wildcard = false; for (var i = 1; i < node[k].selector.length; i++) { switch(node[k].selector[i]) { case ' ': if (! wildcard) { selectors[sel_count++] = char; char = ''; } else { wildcard = false; char += ' '; } break; case '(': case '>': case '+': case '~': wildcard = true; case '.': case '#': case ':': if (! wildcard && node[k].selector[i - 1] !== ' ') { if (node[k].selector[i] !== ':' || node[k].selector[i - 1] !== ':') { selectors[sel_count++] = char; char = '&'; } } default: char += node[k].selector[i]; } } selectors[sel_count++] = char; var less = {}; if (sel_count > 1) { node[k].selector = selectors[0]; for (i = sel_count - 1; i > 0; i--) { less[k + '-' + i] = {}; less[k + '-' + i].selector = selectors[i]; less[k + '-' + i].attributes = []; if (i + 1 === sel_count) { less[k + '-' + i].attributes = node[k].attributes; } else if (i + 1 < sel_count) { less[k + '-' + i].nested = {}; less[k + '-' + i].nested[k + '-' + (i + 1)] = less[k + '-' + (i + 1)]; delete less[k + '-' + (i + 1)]; } } node[k].nested = less; node[k].attributes = []; } if (log) console.log(JSON.stringify(node[k], null, 2)); } } } }, // pass 2: combine duplicate selectors combineDuplicateSelectors: function(node, log) { if (typeof log === "undefined") log = false; for (var k in node) { if (node.hasOwnProperty(k) && node[k].selector && node[k].nested) { var down = 1; while (node[k - down] === undefined || node[k].selector === node[k - down].selector) { if (node[k - down] !== undefined) { if (! node[k - down].nested) { node[k - down].nested = node[k].nested; } else { for (var key in node[k].nested) { if (node[k].nested.hasOwnProperty(key)) { for (var kkey in node[k - down].nested) { if (node[k - down].nested.hasOwnProperty(kkey)) { var match = false; if (node[k].nested[key].selector !== node[k - down].nested[kkey].selector) { match = true; } else { if (!node[k - down].nested[kkey].nested) { if (!node[k].nested[key].nested) { node[k - down].nested[kkey].attributes = node[k - down].nested[kkey].attributes.concat(node[k].nested[key].attributes); } else { node[k - down].nested[kkey].nested = node[k].nested[key].nested; } } else { this.DSnestLoop(node[k].nested, node[k - down].nested); } break; } } } if (match) { node[k - down].nested[key] = {}; node[k - down].nested[key] = node[k].nested[key]; } } } } delete node[k]; break; } down++; } } if (log) console.log(JSON.stringify(node[k], null, 2)); } }, // pass 3: add it to the file constructFile: function(node, log) { if (typeof log === "undefined") log = false; for (var k in node) { if (node.hasOwnProperty(k)) { if ($.inArray(node[k].selector, changed) != -1) { if (node[k].selector) { this.data += node[k].selector + ' {\n'; if (node[k].attributes) { if ($.isArray(node[k].attributes)) { for (var i = 0; i < node[k].attributes.length; i++) { this.data += ' ' + node[k].attributes[i] + ';\n'; } } else { for (i in node[k].attributes) { if (node[k].attributes.hasOwnProperty(i)) { this.data += ' ' + i + ': ' + node[k].attributes[i] + ';\n'; } } } } this.nestedLoopText = ''; this.nestedIdentation = ''; if (node[k].nested) { this.nestLoop(node[k], false); this.data += this.nestedLoopText; } } if (node[k].comment) { if ($.isArray(node[k].comment)) { for (i = 0; i < node[k].comment.length; i++) { if (node[k].selector) this.data += ' '; this.data += node[k].comment[i] + '\n'; } } else { if (node[k].selector) this.data += ' '; this.data += node[k].comment + '\n'; } if (node[k].attributes && !node[k].selector) this.data += node[k].attributes + ';\n'; } if (node[k].selector) this.data += '}\n'; if (log) console.log(JSON.stringify(node[k], null, 2)); } } } }, // generate less file from all json sources and save it locally generateLessFile: function(sources) { // add generated variables based on # of times same color, font, size appears if (sources.constructor !== Array) sources = [sources]; this.data = "/*\n"; this.data += "==========================================================================\n"; this.data += "Theme Customizer Generated LESS Variables\n"; this.data += "==========================================================================\n"; this.data += "*/\n"; var node = $.extend(true, {}, sources[0]); this.checkForVars(node); // next up the CSS from all sources for (var i = 0; i < sources.length; i++) { this.data += "/*\n"; this.data += "==========================================================================\n"; this.data += "Theme Customizer Generated LESS\n"; this.data += "==========================================================================\n"; this.data += "*/\n"; if (i !== 0) node = $.extend(true, {}, sources[i]); this.separateMultipleSelectors(node); this.combineDuplicateSelectors(node); this.constructFile(node); } // and finally lets save and download file var properties = {type: 'plain/text'}; try { file = new File([this.data], 'themecustomizer.less', properties); } catch (e) { file = new Blob([this.data], properties); } url = URL.createObjectURL(file); document.getElementById('generate-var').href = url; }, generateLessVariables: function(sources) { // add generated variables based on # of times same color, font, size appears if (sources.constructor !== Array) sources = [sources]; this.data = "/*\n"; this.data += "==========================================================================\n"; this.data += "Theme Customizer Generated LESS Variables\n"; this.data += "==========================================================================\n"; this.data += "*/\n"; var node = $.extend(true, {}, sources[0]); this.checkForVars(node); return this.data; }, // generate custom css file from all json sources generateCSS: function(sources) { if (sources.constructor !== Array) sources = [sources]; this.data = ''; for (var i = 0; i < sources.length; i++) { this.data += "/*\n"; this.data += "=================================================\n"; this.data += "Theme Customizer Generated CSS\n"; this.data += "=================================================\n"; this.data += "*/\n"; var node = $.extend(true, {}, sources[i]); this.constructFile(node); } return this.data; }, // css file to json conversion, easier to manipulate json data compare to a css 'text' file toJSON: function(data, base) { if (typeof base === "undefined") base = false; var comment = /(\/\*[\s\S]*?\*\/)/g; var selector = /([^\s\;\{\}][^\;\{\}]+)\{|(\})/g; var attributes = /([^\s\;\{\}][^\;\{\}]+\;)/g; var json = {}; var obj = {}; var count = 0; var sel = false; var match = null; var nested_json = {}; var nested_count = 0; var nested = false; var all = /(\/\*[\s\S]*?\*\/)|([^\s\;\{\}][^\;\{\}]+)\{|(\})|([^\s\;\{\}][^\;\{\}]+)/g; if (base) all = /(\/\*[\s\S]*?\*\/)|([^\s\;\{\}][^\;\{\}]+)\{|(\})|([^\s\;\{\}][^\;\{\}]+\;)/g; // var all = /(\/\*[\s\S]*?\*\/)|([^\s\;\{\}][^\;\{\}]*(?=\{))|(\})|([^\;\{\}]+\;(?!\s*\*\/))/gmi; while ((match = all.exec(data)) != null) { if (typeof match[1] !== "undefined") { if (sel) { if (obj['comment'] === undefined) { obj['comment'] = [match[1]]; } else { obj['comment'].push(match[1]); } } else { obj = {}; obj['comment'] = match[1]; json[count++] = obj; } } else if (typeof match[2] !== "undefined") { if (obj['selector'] && (obj['selector'].indexOf('@media') > -1 || obj['selector'].indexOf('@keyframes') > -1 || obj['selector'].indexOf('@-webkit-keyframes') > -1)) { nested_json = {}; nested_count = 0; nested_json['selector'] = obj['selector']; nested = true; } obj = {}; obj['selector'] = match[2].replace('}', ' ').trim(); base ? obj['attributes'] = [] : obj['attributes'] = {}; sel = true; } else if (typeof match[3] !== "undefined") { if (nested) { if ((nested_count > 0) && (nested_json.nested[(count) + '-' + (nested_count - 1)] === obj)) { json[count++] = nested_json; nested = false; } else { if (nested_count === 0) nested_json['nested'] = {}; nested_json.nested[(count) + '-' + (nested_count++)] = obj; } } else { json[count++] = obj; } sel = false; } else if (typeof match[4] !== "undefined") { if (base) { attr = match[4].replace(';', ''); if (obj['attributes'] === undefined) { obj['attributes'] = attr; } else if (match[4].indexOf('base64') > -1) { var pop = obj['attributes'].pop(); obj['attributes'].push(pop + ';' + attr); } else { obj['attributes'].push(attr); } } else { match[4] = match[4].trim(); if (match[4].slice(-1) === ';') match[4] = match[4].slice(0, -1); attr = match[4].split(':'); if (typeof attr[1] !== "undefined") { obj['attributes'][attr[0]] = attr[1].trim(); } else { obj['attributes'][attr[0]] = ''; } } } } return json; }, // update css from json values, more stuff to do here toCSS: function(node) { var text = ''; var lines = 1; this.cssValidator = true; for (var key in node) { if (node.hasOwnProperty(key)) { text += node[key].selector + ' {\n'; lines++; for (var k in node[key].nested) { if (node[key].nested.hasOwnProperty(k)) { text += ' ' + node[key].nested[k].selector + ' {\n'; lines++; for (var i in node[key].nested[k].attributes) { if (node[key].nested[k].attributes.hasOwnProperty(i)) { var old = $(node[key].nested[k].selector).css(k); $(node[key].nested[k].selector).css(i, node[key].nested[k].attributes[i]); var newer = $(node[key].nested[k].selector).css(k); if (old === newer) { if (newer !== node[key].nested[k].attributes[k]) { this.cssValidator = false; this.cssLineError = lines; } } text += ' ' + i + ': ' + node[key].nested[k].attributes[i] + ';\n'; lines++; // console.log('nested selector: ' + node[key].nested[k].selector); // console.log('nested attribute: ' + i); // console.log('nested value: ' + node[key].nested[k].attributes[i]); } } text += ' }\n'; lines++; } } for (k in node[key].attributes) { if (node[key].attributes.hasOwnProperty(k)) { if (node[key].selector.indexOf('@') === -1) { old = $(node[key].selector).css(k); $(node[key].selector).css(k, node[key].attributes[k]); newer = $(node[key].selector).css(k); if (old === newer) { if (newer !== node[key].attributes[k]) { this.cssValidator = false; this.cssLineError = lines; // console.log(old); // console.log(newer); // console.log(node[key].attributes[k]); } } } text += ' ' + k + ': ' + node[key].attributes[k] + ';\n'; lines++; // console.log('selector: ' + node[key].selector); // console.log('attribute: ' + k); // console.log('value: ' + node[key].attributes[k]); } } text += '}\n\n'; lines = lines + 2; } } } }; /* * from sg-web.js */ // // Theme Customizer - Web page stuff // var tc = new TC(); var baseJSON = {}; var inputJSON = {}; // change text color for input fields depending on background color function getContrast(color) { if (color === 'transparent') return 'black'; color = color.replace('#', ''); if (color.length === 3) color = color.charAt(0) + color.charAt(0) + color.charAt(1) + color.charAt(1) + color.charAt(2) + color.charAt(2); var r = parseInt(color.substr(0, 2), 16); var g = parseInt(color.substr(2, 2), 16); var b = parseInt(color.substr(4, 2), 16); var yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000; return (yiq >= 128) ? 'black' : 'white'; } // return a jquery selector function getSelector(el) { return el.attr('data-selector') ? el.attr('data-selector') : ""; } // takes a 3 char color value and returns a 6 char color value function longColorValue(color){ color = color.replace('#', ''); if (color.length === 3) { color = color.charAt(0) + color.charAt(0) + color.charAt(1) + color.charAt(1) + color.charAt(2) + color.charAt(2); } return '#' + color; } // convert rgb value to hex function toHex(rgb) { if (rgb === 'transparent') return rgb; var regex = /([0-9]+)/g; var matches = rgb.match(regex); var hex = matches.map(function(x) { return parseInt(x, 10); }); if (hex.length > 3) { if ((hex[0] === 0) && (hex[1] === 0) && (hex[2] === 0) && (hex[3] === 0)) return 'transparent'; } return "#" + ((1 << 24) + (hex[0] << 16) + (hex[1] << 8) + hex[2]).toString(16).slice(1); } // equivalent of darken/lighten in css which is unusable in jquery function lightenDarkenColor(color, amount) { var isColor = false; if (color[0] === "#") { color = color.slice(1); isColor = true; if (getContrast(color) === 'black') { amount = -Math.abs(amount); } } var num = parseInt(color, 16); var r = (num >> 16) + amount; if (r > 255) r = 255; else if (r < 0) r = 0; var b = ((num >> 8) & 0x00FF) + amount; if (b > 255) b = 255; else if (b < 0) b = 0; var g = (num & 0x0000FF) + amount; if (g > 255) g = 255; else if (g < 0) g = 0; return (isColor ? "#" : "") + String("000000" + (g | (b << 8) | (r << 16)).toString(16)).slice(-6); } // stuff repeated in next 2 functions function checkInputValues(el, selector) { var bfa = el.attr('data-element'); // browser friendly attribute if (bfa === 'border-color') bfa = 'border-top-color'; // get all the relevant example elements for this control var $selected = $(el).parents(".row:first").find("> div:first").find(selector); if ($selected.length === 0) $selected = $(selector); if ($selected.css(bfa).indexOf('rgb(') > -1) { css = $selected.css(bfa); part1 = css.slice(0, css.indexOf('rgb(')); part2 = css.slice(css.indexOf('rgb(')); el.val( part1 + toHex(part2) ); } else if (bfa === 'padding') { if ($selected.css('padding-top') === $selected.css('padding-left') && $selected.css('padding-top') === $selected.css('padding-bottom') && $selected.css('padding-top') === $selected.css('padding-right')) { el.val( $selected.css('padding-top') ); } else { el.val( $selected.css('padding-top') + ' ' + $selected.css('padding-right') + ' ' + $selected.css('padding-bottom') + ' ' + $selected.css('padding-left') ); } } else if (bfa === 'border-radius') { if ($selected.css('border-top-left-radius') === $selected.css('border-top-right-radius') && $selected.css('border-top-left-radius') === $selected.css('border-bottom-right-radius') && $selected.css('border-top-left-radius') === $selected.css('border-bottom-left-radius')) { el.val( $selected.css('border-top-left-radius') ); } else { el.val( $selected.css('border-top-left-radius') + ' ' + $selected.css('border-top-right-radius') + ' ' + $selected.css('border-bottom-right-radius') + ' ' + $selected.css('border-bottom-left-radius') ); } } else if (bfa === 'border') { el.val( $selected.css('border-top-width') + ' ' + $selected.css('border-top-style') + ' ' + toHex($selected.css('border-top-color')) ); } else { el.val( $selected.css(bfa) ); } if ( selector === '.customizer .icons .sample span' ) { var width = 0; $selected.css('width', ''); $selected.each(function() { if ($(this).width() > width) width = $(this).width(); }); $selected.each(function() { $(this).width(width); $(this).height(width); }); } } // change default values of all input fields on pageload function defaultInputValues(pageload) { if (typeof pageload === "undefined") pageload = true; var count = 0; $('.input input').each(function() { var obj = {}; var selector = getSelector($(this)); var bfa = $(this).attr('data-element'); // browser friendly attribute if (bfa === 'border-color') bfa = 'border-top-color'; if (! $(this).hasClass('nocolor')) { $(this).val( toHex($(selector).css(bfa)) ); if ($(this).val() === 'transparent') { $(this).css('background-color', 'rgba(0, 0, 0, 0)'); } else { $(this).css('background-color', '#' + $(this).val()); } $(this).css('color', getContrast($(this).val())); if (!pageload) $(this).closest('.picker').colorpicker('setValue', $(this).val()); } else { checkInputValues($(this), selector); if ( $(this).hasClass('check') ) { if ($(this).val() === $(this).attr('data-check')) $(this).prop('checked', true); } } obj['selector'] = selector; obj['attributes'] = {}; obj['attributes'][$(this).attr("data-element")] = $(this).val(); obj['var'] = $(this).data("var"); sel = false; for (var k in inputJSON) { if (inputJSON.hasOwnProperty(k) && inputJSON[k].selector === obj.selector) { sel = true; for (var key in obj.attributes) { if (obj.attributes.hasOwnProperty(key)) { inputJSON[k].attributes[key] = obj.attributes[key]; } } inputJSON[k].var = obj.var; break; } } if (!sel) inputJSON[count++] = obj; }); } // update value of an input field (and json equivalent) function updateInputValue(el) { var selector = getSelector(el); var bfa = el.attr('data-element'); // browser friendly attribute if (bfa === 'border-color') bfa = 'border-top-color'; if (! el.hasClass('nocolor')) { el.val( toHex($(selector).css(bfa)) ); el.css('background-color', '#' + el.val()); el.css('color', getContrast(el.val())); } else { checkInputValues(el, selector); } for (var k in inputJSON) { if (inputJSON[k].selector === selector) { inputJSON[k].attributes[el.attr("data-element")] = el.val(); break; } } if ($.inArray(selector, changed) == -1) changed.push(selector); saveCustomizerCSS(); } // save custom CSS to localStorage function saveCustomizerCSS() { if ( $('.keep-changes').prop('checked') ) { localStorage.setItem('customizerData', JSON.stringify(inputJSON)); localStorage.setItem('changedData', JSON.stringify(changed)); } } // load custom CSS from localStorage function loadCustomizerCSS() { inputJSON = JSON.parse(localStorage.getItem('customizerData')); changed = JSON.parse(localStorage.getItem('changedData')); } // delete stored data function deleteData() { localStorage.removeItem('customizerData'); localStorage.removeItem('changedData'); } // stuff to fix for TC to work with all themes / browsers function themeFix() { var $body = $('body'); $('.header_outer, footer').css('background', $body.css('background')); $('.header_outer, footer').css('background-color', $body.css('background-color')); $('.customizer .tables .table-bordered .tb').css('border', '1px solid ' + $('.table-bordered > tbody > tr > td').css('border-top-color')); $('.customizer h1, .customizer h2').css('border-bottom-color', $('h1').css('color')); $('.customizer .btn-primary').css('border-color', $('.customizer .btn-primary').css('border-bottom-color')); if ($('table').css('background-color') === 'rgba(0, 0, 0, 0)') { if ($('#middle.container').css('background-color') !== 'rgba(0, 0, 0, 0)') { $('tbody > tr:nth-of-type(even), .table-bordered tr').css('background-color', $('#middle.container').css('background-color')); } else { $('tbody > tr:nth-of-type(even), .table-bordered tr').css('background-color', $body.css('background-color')); } } else { $('tbody > tr:nth-of-type(even), .table-bordered tr').css('background-color', $('table').css('background-color')); } if ($('.customizer .navbar-dark .navbar-nav .nav-link').css('background-color') === 'rgba(0, 0, 0, 0)') { $('.customizer .navbar-dark .navbar-nav .nav-link').css('background-color', $('.customizer .navbar-dark').css('background-color')); } var border = ['btn-primary', 'btn-secondary', 'btn-success', 'btn-danger', 'btn-warning', 'btn-info', 'btn-light', 'btn-dark', 'alert-primary', 'alert-secondary', 'alert-success', 'alert-info', 'alert-warning', 'alert-danger']; for (var i = 0; i < border.length; i++) { var sel = $('.customizer .' + border[i]); if (sel.css('border-top-color').indexOf('rgba') > -1) sel.css('border-color', sel.css('background-color')); } var font = $body.css('font-family').split(','); for (i = 0; i < 3; i++) { if (i >= font.length) { $('.fonts .font' + (i + 1)).css('font-family', 'Arial'); $('.fonts .ff' + (i + 1)).append('Arial'); } else { $('.fonts .font' + (i + 1)).css('font-family', font[i]); $('.fonts .ff' + (i + 1)).append(font[i]); } } } (function($) { // parse original css to json var base_css = ''; var customizer_css = ''; $.when( $.get('./themes/default/css/default.css', function(data) { base_css = data; }), $.get('./themes/base_files/css/theme-customizer.css', function(data) { customizer_css = data; }) ).then(function() { baseJSON = tc.toJSON(base_css + customizer_css, true); // console.log(JSON.stringify(baseJSON, null, 2)); }); var $themeCustomizer = $('.customizer'); if ($themeCustomizer.length) themeFix(); $('.customizer .tc-form').submit(false); // theme customizer's footer autotoc $themeCustomizer.find('h2').each(function () { var text = $(this).text(); $(this).attr('id', text); $('.tc-footer .dropdown-menu').append('' + $(this).text() + ''); }); // set some values if stored data exist if (localStorage.getItem('customizerData') !== null) { $('.keep-changes').prop('checked', true); loadCustomizerCSS(); tc.toCSS(inputJSON); $('textarea[name=header_custom_css]').val(tc.generateCSS([inputJSON])); } defaultInputValues(); // update css when out of focus $('.input input').on('focusout', function() { var check = $(this).val(); if (!$(this).hasClass('nocolor')) check = longColorValue(check); $(getSelector($(this))).css($(this).attr('data-element'), $(this).val()); updateInputValue($(this)); check !== $(this).val() ? $(this).parent().addClass('error') : $(this).parent().removeClass('error'); }); // update css on change for checkbox $('.input .check').on('change', function() { $(this).prop('checked') ? $(this).val($(this).attr('data-check')) : $(this).val($(this).attr('data-default')); $(getSelector($(this))).css($(this).attr('data-element'), $(this).val()); updateInputValue($(this)); }); // generate custom css when clicked $('.generate-custom-css').click(function() { $('textarea[name=header_custom_css]').val(tc.generateCSS([inputJSON])); $('html, body').animate({ scrollTop: $('textarea[name=header_custom_css]').offset().top }, 200); return false; }); // TODO generate SCSS variables when clicked // apply lighter color on hover for links $('.customizer p > a').hover( function() { $(this).css('color', lightenDarkenColor($('#tc-link-color').val(), 50)); }, function() { $(this).css('color', $('#tc-link-color').val()); } ); // apply lighter color on hover for buttons $('.customizer .btn, .customizer .icons span').each(function() { var id = '#tc-btn-primary-bg-color'; if ( $(this).hasClass('btn-secondary') ) id = '#tc-btn-secondary-bg-color'; if ( $(this).hasClass('btn-success') ) id = '#tc-btn-success-bg-color'; if ( $(this).hasClass('btn-info') ) id = '#tc-btn-info-bg-color'; if ( $(this).hasClass('btn-warning') ) id = '#tc-btn-warning-bg-color'; if ( $(this).hasClass('btn-danger') ) id = '#tc-btn-danger-bg-color'; if ( $(this).hasClass('btn-light') ) id = '#tc-btn-light-bg-color'; if ( $(this).hasClass('btn-dark') ) id = '#tc-btn-dark-bg-color'; if ( $(this).hasClass('fas') ) id = '#tc-icon-bg-color'; if ( $(this).hasClass('fab') ) id = '#tc-icon-bg-color'; $(this).hover( function() { $(this).css('background-color', lightenDarkenColor($(id).val(), 50)); }, function() { $(this).css('background-color', $(id).val()); } ); }); // storage behaviour when checking/unchecking $('.keep-changes').on('change', function() { $(this).prop('checked') ? saveCustomizerCSS() : deleteData(); }); // update css when using colorpicker $('.picker').colorpicker().on('changeColor', function(e) { var selector = getSelector( $(e.target) ); $(selector).css(e.target.dataset.element, e.color.toHex()); $(this).find('input').css('background-color', e.color.toHex()); $(this).find('input').css('color', getContrast(e.color.toHex())); for (var key in inputJSON) { if (inputJSON[key].selector === selector) { inputJSON[key].attributes[e.target.dataset.element] = e.color.toHex(); if ($.inArray(selector, changed) == -1) changed.push(selector); saveCustomizerCSS(); break; } } }); })(jQuery);