Skip to content

Instantly share code, notes, and snippets.

@jaydson
Created May 31, 2012 15:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaydson/2844011 to your computer and use it in GitHub Desktop.
Save jaydson/2844011 to your computer and use it in GitHub Desktop.
package manager prototype
/*global window, console, document,XMLHttpRequest, setTimeout, location, navigator*/
(function () {
'use strict';
// private methods and properties are stored in this object
var core = {
// Constructor
init : function () {
core.parsePackages();
},
// Add new scripts and stylesheets into head
// @resource - path of file
// @type - JS or CSS
// @callback - function to be executed when file is loaded(not sure if it works in IE)
inject : function (resource, type, callback) {
var fileref = null;
if (resource && type === "js") {
fileref = document.createElement('script');
fileref.setAttribute("type", "text/javascript");
fileref.setAttribute("src", resource);
fileref.onreadystatechange = function () {
if (typeof callback === 'function') {
callback();
}
};
fileref.onload = function () {
if (typeof callback === 'function') {
callback();
}
};
} else if (resource && type === "css") {
fileref = document.createElement("link");
fileref.setAttribute("rel", "stylesheet");
fileref.setAttribute("type", "text/css");
fileref.setAttribute("href", resource);
}
if (typeof fileref !== "undefined") {
document.getElementsByTagName("head")[0].appendChild(fileref);
}
},
// Ajax stuff, based on John Resig script
ajax : function (opt) {
var options = {
type: opt.type || "POST",
url: opt.url || "",
timeout: opt.timeout || 5000,
onComplete: opt.onComplete || function () {},
onError: opt.onError || function () {},
onSuccess: opt.onSuccess || function () {},
data: opt.data || ""
},
timeoutLength = 5000,
requestDone = false,
xml = new XMLHttpRequest();
function httpSuccess(r) {
try {
return (!r.status && location.protocol === "file:") ||
(r.status >= 200 && r.status < 300) ||
r.status === 304 ||
(navigator.userAgent.indexOf("Safari") >= 0 && typeof r.status === "undefined");
} catch (e) {}
return false;
}
function httpData(r, type) {
var ct = r.getResponseHeader("content-type"),
data = !type && ct && ct.indexOf("xml") >= 0;
data = type === "xml" || data ? r.responseXML : r.responseText;
return data;
}
xml.open(options.type, options.url, true);
setTimeout(function () {
requestDone = true;
}, timeoutLength);
xml.onreadystatechange = function () {
if (xml.readyState === 4 && !requestDone) {
if (httpSuccess(xml)) {
options.onSuccess(httpData(xml, options.type));
} else {
options.onError();
}
options.onComplete();
xml = null;
}
};
xml.send();
},
// Just a namespace to store logs
LOG : {
critical : [],
message : []
},
// Some default properties
DEFAULTS : {
path_manifest : 'packman-manifest.json',
packages : null
},
// Load the manifest file, parse and store it in DEFAULTS.packages property
parsePackages : function () {
core.ajax({
type: "GET",
url: core.DEFAULTS.path_manifest,
onSuccess: function (pack) {
core.DEFAULTS.packages = (function () {
try {
return JSON.parse(pack);
} catch (ex) {
core.LOG.critical.push({
'time' : new Date(),
'message' : 'JSON Parse Error - Check your manifest file'
});
}
}());
},
onError: function () {
core.LOG.critical.push({
'time' : new Date(),
'message' : 'Manifest Error - Loading manifest file failed'
});
}
});
}
},
packman = function (settings) {
core.init();
};
// Change path of manifest file
packman.prototype.setPathManifest = function (path) {
if (path !== '' && path !== undefined) {
core.DEFAULTS.path_manifest = path;
} else {
core.LOG.critical.push({
'time' : new Date(),
'message' : 'Manifest Path Error - You need to specify the manifest path'
});
}
};
// Just return the stored, parsed packages
packman.prototype.getPackges = function () {
return core.DEFAULTS.packages.packages;
};
// Return one package, based on his name, or his properties
// @pack - String with package name
// @pack - Object literal with package properties
packman.prototype.getPackge = function (pack) {
var packs = core.DEFAULTS.packages.packages,
packsLen = packs.length,
i = 0,
curpack = null;
if (typeof pack === 'object') {
return "Not implemented";
} else if (typeof pack === 'string') {
for (i; i < packsLen; i = i + 1) {
if (packs[i].name === pack) {
curpack = packs[i];
}
}
if (curpack !== null) {
return curpack;
} else {
core.LOG.critical.push({
'time' : new Date(),
'message' : 'Package ' + pack + ' was not found'
});
}
} else {
core.LOG.critical.push({
'time' : new Date(),
'message' : 'Invalid package'
});
}
};
// Log messages or errors
packman.prototype.log = function (type, message) {
if (type !== 'critical' && type !== 'message' && message !== '') {
core.LOG.critical.push({
'time' : new Date(),
'message' : 'Inception Error - You need to specify an message and a correct type of log'
});
} else {
core.LOG[type].push({
'time' : new Date(),
'message' : message
});
}
};
// Return all errors
packman.prototype.debug = function () {
return core.LOG;
};
//
packman.prototype.use = function (pack, callback) {
var curPack = null,
deps = null,
i = 0,
loadDependencies = function (dependencies) {
var deps = dependencies.length;
for (i; i < deps; i = i + 1) {
packman.prototype.use(dependencies[i]);
}
};
if (typeof pack === 'object') {
if (pack.dependencies) {
loadDependencies(pack.dependencies);
}
core.inject(pack.path, pack.type || 'js', function () {
packman.prototype[pack.global] = window[pack.global];
try {
delete window[pack.global];
} catch (er) {
core.LOG.message.push({
'time' : new Date(),
'message' : 'Inject Error - Cannot delete global object ' + pack.global
});
}
if (typeof callback === 'function') {
callback(packman.prototype[pack.global]);
}
});
} else if (typeof pack === 'string') {
curPack = this.getPackge(pack);
deps = null;
i = 0;
if (curPack) {
if (curPack.dependencies) {
loadDependencies(curPack.dependencies);
}
core.inject(curPack.path, curPack.type || 'js', function () {
packman.prototype[curPack.global] = window[curPack.global];
try {
delete window[curPack.global];
} catch (er) {
core.LOG.message.push({
'time' : new Date(),
'message' : 'Inject Error - Cannot delete global object ' + pack.global
});
}
if (typeof callback === 'function') {
callback(packman.prototype[curPack.global]);
}
});
}
} else {
console.log('x');
}
};
window.packman = packman;
}());
//Sample manifest
{
"packages" : [{
"name" : "jquery",
"type" : "js",
"path" : "js/jquery.min.js",
"version" : "1.7",
"global" : "jQuery"
},
{
"name" : "jqueryui-style",
"type" : "css",
"path" : "css/jqueryui.min.js",
"version" : "1.7"
},
{
"name" : "jqueryui",
"type" : "js",
"path" : "js/jqueryui.min.js",
"version" : "1.7",
"global" : "jQueryUI",
"dependencies" : [{
"name" : "core3",
"type" : "js",
"path" : "js/core3.js",
"version" : "1.0",
"global" : "Core3",
"dependencies" : [{
"name" : "core2",
"type" : "js",
"path" : "js/core2.js",
"version" : "1.0",
"global" : "Core2",
"dependencies" : [{
"name" : "core1",
"type" : "js",
"path" : "js/core1.js",
"version" : "1.0",
"global" : "Core1",
"dependencies" : [{
"name" : "core",
"type" : "js",
"path" : "js/core.js",
"version" : "1.0",
"global" : "Core"
}]
}]
}]
},
{
"name" : "base",
"type" : "js",
"path" : "js/base.js",
"version" : "1.0",
"global" : "Base"
},
{
"name" : "nucleo",
"type" : "js",
"path" : "js/nucleo.js",
"version" : "1.0",
"global" : "Nucleo"
}
]
},
{
"name" : "yui",
"type" : "js",
"path" : "js/yui.min.js",
"version" : "2",
"global" : "YUI"
}]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment