mirror of
https://github.com/WebStackPage/WebStackPage.github.io.git
synced 2026-02-11 06:15:25 +08:00
274 lines
7.7 KiB
JavaScript
Executable File
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); |