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

274 lines
7.7 KiB
JavaScript
Executable File

(function($) {
var cache = {};
function getCSS(source, options) {
var deferred = $.Deferred(), opts = options || {};
(opts.imports ? resolveImports(source) : $.Deferred().resolve(source)).done(function(source) {
if (opts.id && cache[opts.id]) {
createCSS(cache[opts.id]);
} else {
new(less.Parser)().parse(source, function(error, tree) {
if (error) {
return deferred.reject(error);
}
if (opts.id) {
cache[opts.id] = tree;
}
createCSS(tree);
});
}
});
function createCSS(tree) {
var variables = "";
if (opts.variables) {
$.each(opts.variables, function(name, value) {
variables += ((name.slice(0,1) === "@") ? "" : "@") + name + ": " + ((value.slice(-1) === ";") ? value : value + ";");
});
}
if (variables) {
new(less.Parser)().parse(variables, function(error, vars) {
if (error) {
return deferred.reject(error);
}
var rules = tree.rules;
tree.rules = tree.rules.concat(vars.rules);
toCSS(tree);
tree.rules = rules;
});
} else {
toCSS(tree);
}
}
function toCSS(tree) {
try {
deferred.resolve(tree.toCSS(opts));
} catch (e) {
if (opts.id && cache[opts.id]) {
delete cache[opts.id];
}
deferred.reject(e);
}
}
return deferred.promise();
}
function resolveImports(source) {
var deferred = $.Deferred(), imports = {}, host = extractUrlParts(window.location.href).host, importRegex = /@import\s+url\s*\(['"]?(.+?)['"]?\)\s*;/g, urlRegex = /url\s*\(['"]?(.+?)['"]?\)/g;
function queuedWhen(queue) {
var deferreds = [], prev = null;
$.each(queue, function(i, fn) {
deferreds.push(prev = prev ? prev.then(fn) : fn.call());
});
return $.when.apply($, deferreds);
}
function rewrite(source, baseUrl) {
source = source.replace(/@import\s['"]?(.+?)['"]?\s*;/g, function(match, url) {
return match.indexOf("url(")!=-1 ? match:'@import url("'+url+'");';
});
return source.replace(urlRegex, function(match, url) {
return match.match(/data\:image\//) ? match : match.replace(url, extractUrlParts(url, baseUrl).url);
});
}
(function resolve(source) {
var queue = [];
source = source.replace(/@import\s['"]?(.+?)['"]?\s*;/g, function(match, url) {
return match.indexOf("url(")!=-1 ? match:'@import url("'+url+'");';
});
source.replace(importRegex, function(match, url) {
if (!imports[url] && host == extractUrlParts(url).host) {
queue.push(
function() {
return $.ajax({url: url, cache: false}).done(function(data) {
imports[url] = rewrite(data.replace(/\/\*(?:[^*]|\*+[^\/*])*\*+\/|^((?!:).)?\/\/.*/g, ''), url);
}).fail(function(xhr, status, error) {
imports[url] = "/* Can't resolve import '" + url + "' (" + status + ", " + error + ") */";
});
}
);
}
return match;
});
queuedWhen(queue).always(function() {
source = source.replace(importRegex, function(match, url) {
return imports[url] ? imports[url] : match;
});
if (queue.length) {
source = resolve(source);
} else {
deferred.resolve(source);
}
});
return source;
})(rewrite(source.replace(/\/\*(?:[^*]|\*+[^\/*])*\*+\/|^((?!:).)?\/\/.*/g, '')));
return deferred.promise();
}
function getVars(source) {
var i, vars = {}, lines = source.split("\n");
for (i = 0, max = lines.length; i < max; i++) {
var line = $.trim(lines[i]);
if (!line.length) continue;
if (!/@[\w\-]+\s*:.[^;]*;/.test(line)) continue;
var keyval = $.trim(line.replace(";", "").replace(/\s+/, "")).split(":");
keyval[1] = $.trim(keyval[1].replace(";","").split('//')[0]);
vars[keyval[0]] = keyval[1];
}
return vars;
}
function rewriteUrls(source, baseUrl) {
return source.replace(/url\s*\(['"]?(.+?)['"]?\)/g, function(match, url) {
return (url.match(/^(http|\/\/)/) || match.match(/data\:image\//)) ? match : match.replace(url, pathDiff(extractUrlParts(url, baseUrl).url, baseUrl));
});
}
function pathDiff(url, baseUrl) {
var urlParts = extractUrlParts(url), urlDirs,
baseUrlParts = extractUrlParts(baseUrl), baseUrlDirs,
diff = "", max, i;
if (urlParts.host !== baseUrlParts.host) {
return "";
}
max = Math.max(baseUrlParts.dirs.length, urlParts.dirs.length);
for (i = 0; i < max; i++) {
if (baseUrlParts.dirs[i] !== urlParts.dirs[i]) { break; }
}
urlDirs = urlParts.dirs.slice(i);
baseUrlDirs = baseUrlParts.dirs.slice(i);
for (i = 0; i < baseUrlDirs.length - 1; i++) {
diff += "../";
}
for (i = 0; i < urlDirs.length - 1; i++) {
diff += urlDirs[i] + "/";
}
return diff + urlParts.file + urlParts.query;
}
function extractUrlParts(url, baseUrl) {
var urlPartsRegex = /^((?:[a-z-]+:)?\/\/(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/,
urlParts = url.match(urlPartsRegex), baseUrlParts,
parts = {}, dirs = [], i;
if (!urlParts) {
throw new Exception("Could not parse url - '" + url + "'");
}
if (!urlParts[1] || urlParts[2]) {
if (!baseUrl) {
baseUrl = window.location.href;
}
baseUrlParts = baseUrl.match(urlPartsRegex);
if (!baseUrlParts) {
throw new Exception("Could not parse url - '" + baseUrl + "'");
}
urlParts[1] = baseUrlParts[1];
if (!urlParts[2]) {
urlParts[3] = baseUrlParts[3] + urlParts[3];
}
}
if (urlParts[3]) {
dirs = urlParts[3].replace("\\", "/").split("/");
for (i = 0; i < dirs.length; i++) {
if (dirs[i] === ".." && i > 0) {
dirs.splice(i-1, 2);
i -= 2;
}
}
}
parts.host = urlParts[1];
parts.path = urlParts[1] + dirs.join("/");
parts.file = urlParts[4] || "";
parts.query = urlParts[5] || "";
parts.url = parts.path + parts.file + parts.query;
parts.dirs = dirs;
return parts;
}
$.less = $.less || (function() {
return {
'getCSS': getCSS,
'getVars': getVars,
'resolveImports': resolveImports,
'rewriteUrls': rewriteUrls,
'pathDiff': pathDiff,
'extractUrlParts': extractUrlParts
};
})();
})(jQuery);