Files
WebStackPage.github.io/assets/js/uikit/vendor/customizer.js
2017-12-20 13:23:22 +08:00

291 lines
12 KiB
JavaScript
Executable File

(function($) {
var Customizer = function($element, $options) {
var $select = $($options.select, $element),
$sidebar = $($options.sidebar, $element),
$advanced = $($options.advanced, $element),
$style, memory = window.sessionStorage || {};
this.$options = $options;
this.$select = $select;
$element.on({
"update": function(e, value, force) {
if ($("option", $select).length != $options.styles.length) {
$select.html($.mustache($options.template.select, $options));
if(memory["uikit-customizer-last-theme"]) {
$select.val(memory["uikit-customizer-last-theme"]);
}
}
if (value) {
$select.val(value);
}
var name = $select.val(), current = $style;
$.each($options.styles, function(i, style) {
if (name == style.name) {
$style = style;
}
});
if ($style !== current || force) {
$element.trigger("updating", $style);
loadStyle($style).done(function() {
renderSidebar($style);
$element.trigger("updated", $style);
});
}
},
"updating": $options.updating,
"updated": $options.updated
});
$select.on("change", function(e) {
memory["uikit-customizer-last-theme"] = $select.val();
setTimeout(function() {
$element.trigger("update");
}, 1);
});
$advanced.on("change", function(e) {
$sidebar[$(this).prop("checked") ? "addClass" : "removeClass"]("cm-show-advanced");
}).trigger("change");
$element.on("click", "a.cm-more-link", function(e) {
e.preventDefault();
$(this).parents("fieldset:first").toggleClass("cm-show-more");
});
$element.on("change", "input[name=vars], select[name=vars]", function(e) {
e.preventDefault();
var name = $(this).attr('data-name'), value = $(this).val();
if (value === "") {
delete $style.variables[name];
} else {
$style.variables[name] = value;
}
$element.trigger("updated", $style);
});
function loadStyle(style) {
var deferred = $.Deferred(),
imports = "";
if (style.less) {
return deferred.resolve();
}
if($.isArray(style.url)) {
for (var i = 0; i < style.url.length; i++) {
imports += "@import url(" + style.url[i] + ");";
}
} else {
imports = "@import url(" + style.url + ");";
}
$.less.resolveImports(imports).done(function(less) {
$.ajax({"url": style.config, "cache": false, "dataType": "json"}).done(function(config) {
var vars = $.less.getVars(less);
style.less = less;
style.config = config;
style.groups = [];
style.variables = style.variables || {};
style.matchName = matchName;
$.each(style.config.groups, function(i, grp) {
var variable, group = {label: grp.label, variables: [], advanced: grp.advanced || false, more: false};
$.each(grp.vars, function(i, opt) {
$.each(vars, function(name, value) {
if (matchName(opt, name)) {
delete vars[name];
variable = {
"name": name,
"default": value,
"placeholder": value,
"label": name.replace(/^@/, "").replace(/^\w+\-/, "").replace(/\-/g, " "),
"more": value.indexOf("@") !== -1,
"value": function() {
return style.variables[name] ? style.variables[name] : "";
}
};
if (variable.more) {
group.more = true;
variable.placeholder = "@";
}
group.variables.push(variable);
}
});
});
if (group.variables.length) {
style.groups.push(group);
}
});
deferred.resolve();
});
});
return deferred.promise();
}
function renderSidebar(style) {
$sidebar.html($.mustache($options.template.sidebar, style));
$sidebar.find("input[data-name]").each(function() {
var input = $(this), value = input.val() || input.data("default"), select, groups;
if (input.attr("data-default").indexOf('@') !== -1) {
return;
}
$.each(style.config.controls, function(i, control) {
$.each(control.vars, function(i, pattern) {
if (matchName(pattern, input.attr("data-name"))) {
switch (control.type) {
case "color":
var placeholder = $('<div class="sp-placeholder"><div class="sp-placeholder-color"></div></div>').find("div").css("background-color", value).end().on("click", function() {
var spectrum;
input.spectrum({
"showInput": true,
"showAlpha": true,
"preferredFormat": "hex6",
"color": (value=='inherit' ? '':value),
"change": function(color) {
if (color.toRgb().a < 1) {
input.val(color.toRgbString()).trigger("change");
}
},
"show": function(){
if (!spectrum) {
spectrum = $.fn.spectrum.get(input.data("spectrum.id"));
spectrum.container.find('.sp-cancel').after($('<a href="#" class="sp-reset">reset</a>').on("click", function(e) {
e.preventDefault();
spectrum.set(input.data("default")=="inherit" ? "rgba(0,0,0,0)":input.data("default"));
spectrum.hide();
input.val("");
}));
}
}
});
placeholder.remove();
setTimeout(function(){
input.spectrum("show");
}, 50);
});
input.hide().after(placeholder);
break;
case "font":
groups = [];
if ($.isArray(control.options)) {
groups.push({"group": "", "options": control.options});
} else {
$.each(control.options, function(group, options) {
groups.push({"group": group, "options": options});
});
}
select = $($.mustache('<select>{{#groups}}{{#group}}<optgroup label="{{group}}">{{/group}}{{#options}}<option value="{{value}}"{{#url}} data-url="{{url}}"{{/url}}>{{name}}</option>{{/options}}{{#group}}</optgroup>{{/group}}{{/groups}}</select>', {groups: groups}));
input.replaceWith(select.val(value).attr("class", input.attr("class")).attr("name", input.attr("name")).attr("data-name", input.attr("data-name")));
break;
case "select":
select = $($.mustache('<select>{{#options}}<option value="{{value}}">{{name}}</option>{{/options}}</select>', {options: control.options}));
input.replaceWith(select.val(value).attr("class", input.attr("class")).attr("name", input.attr("name")).attr("data-name", input.attr("data-name")));
break;
}
}
});
});
});
}
function matchName(pattern, path) {
var parsedPattern = '^' + pattern.replace(/\//g, '\\/').
replace(/\*\*/g, '(\\/[^\\/]+)*').
replace(/\*/g, '[^\\/]+').
replace(/((?!\\))\?/g, '$1.') + '$';
parsedPattern = '^' + parsedPattern + '$';
return (path.match(new RegExp(parsedPattern)) !== null);
}
};
$.fn.customizer = function(options) {
return this.each(function() {
var defaults = {
"updating": $.noop(),
"updated": $.noop(),
"select": "select[name=style]",
"advanced": "input[name=advanced]",
"sidebar": "section.cm-sidebar-content",
"template": {
"select":
'{{#styles}}<option value="{{name}}">{{name}}</option>{{/styles}}',
"sidebar":
'<div class="cm-vars cm-form uk-form"> \
{{#groups}} \
<fieldset{{#advanced}} class="cm-advanced"{{/advanced}}> \
<h2 class="cm-form-title">{{label}}{{#more}} <a href="#" class="cm-more-link"></a>{{/more}}</h2> \
{{#variables}} \
<div class="uk-form-row{{#more}} cm-more{{/more}}"> \
<label class="uk-form-label" title="{{name}}">{{label}}</label> \
<div class="uk-form-controls"> \
<input class="uk-form-small" name="vars" type="text"{{#value}} value="{{value}}"{{/value}} placeholder="{{placeholder}}" data-name="{{name}}" data-default="{{default}}"> \
</div> \
</div> \
{{/variables}} \
</fieldset> \
{{/groups}} \
</div>'
}
},
$this = $(this);
$this.data("customizer", new Customizer($this, $.extend({}, defaults, options)));
});
};
})(jQuery);