Created
May 16, 2015 12:01
-
-
Save satya164/ab80f54e6592129f17c0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
function Lace(selector) { | |
var nodes, el; | |
// Handle situation where called without "new" keyword | |
if (false === (this instanceof Lace)) { | |
return new Lace(selector); | |
} | |
if (typeof selector === "undefined") { | |
// No selectors passed, create an empty node | |
nodes = null; | |
} else if (typeof selector !== "string") { | |
if (typeof selector === "object" && selector.nodeType > 0) { | |
// A DOM node passed, add it to the nodes array | |
nodes = [ selector ]; | |
} else if (typeof selector === "object" && selector.length) { | |
// An HTMLCollection is passed, set it to the nodes | |
nodes = selector; | |
} else { | |
throw new TypeError("Invalid selector: " + selector); | |
} | |
} else { | |
if (/^<[a-z]+>$/.test(selector)) { | |
// Create a new DOM node | |
el = selector.replace(/((^<)|(>$))/g, ""); | |
nodes = [ document.createElement(el) ]; | |
} else { | |
if (/^#/.test(selector)) { | |
// An ID was passed | |
nodes = [ document.getElementById(selector.replace(/^#/, "")) ]; | |
} else if (/^\./.test(selector)) { | |
// A class name was passed | |
nodes = document.getElementsByClassName(selector.replace(/^\./, "")); | |
} else if (/^[a-z]+$/.test(selector)) { | |
// A tagname was passed | |
nodes = document.getElementsByTagName(selector); | |
} else { | |
nodes = document.querySelectorAll(selector); | |
} | |
} | |
} | |
// Add elements | |
for (var i = nodes.length - 1; i >= 0; i--) { | |
if (nodes[i] && nodes[i].nodeType > 0) { | |
this[i] = nodes[i]; | |
} | |
} | |
// Add the length property | |
Object.defineProperty(this, "length", { | |
get: function() { | |
return nodes.length; | |
} | |
}); | |
// An HTMLCollection is immutable | |
Object.freeze(this); | |
} | |
// Add all array methods | |
Lace.prototype = Object.create(Array.prototype); | |
// Helper methods | |
Lace.prototype.item = function(index) { | |
if (typeof index !== "number") { | |
throw new TypeError("Invalid index: " + index); | |
} | |
return this.length > index ? this[index] : null; | |
}; | |
Lace.prototype.each = function(callback) { | |
if (typeof callback !== "function") { | |
throw new TypeError("Invalid callback: " + callback); | |
} | |
for (var i = this.length - 1; i >= 0; i--) { | |
callback.call(this.item(i), i); | |
} | |
return this; | |
}; | |
// Add a method to get the first item from a collection | |
Lace._ = function(selector) { | |
if (selector instanceof Lace) { | |
return selector.item(0); | |
} else if (selector.nodeType > 0) { | |
return selector; | |
} else { | |
return (new Lace(selector)).item(0); | |
} | |
}; | |
// Let's add a DOM ready listener | |
Lace.ready = function(callback) { | |
if (typeof callback !== "function") { | |
throw new TypeError("Invalid listener: " + callback); | |
} | |
if (document.readyState === "complete") { | |
// document is already ready | |
callback(); | |
} else { | |
// document is not ready, wait till it's ready | |
document.addEventListener("readystatechange", function() { | |
if (document.readyState === "complete") { | |
callback(); | |
} | |
}, false); | |
} | |
}; | |
// We need a object extend functionality | |
Lace.extend = function() { | |
var objs = Array.prototype.slice.call(arguments, 0), | |
orig = objs[0]; | |
if (typeof orig !== "object" || orig === null) { | |
return orig; | |
} | |
for (var i = 1, l = objs.length; i < l; i++) { | |
if (typeof objs[i] !== "object" || objs[i] === null) { | |
return orig; | |
} | |
for (var o in objs[i]) { | |
if (objs[i].hasOwnProperty(o)) { | |
if (typeof orig[o] === "object") { | |
this.extend(orig[o], objs[i][o]); | |
} else { | |
orig[o] = objs[i][o]; | |
} | |
} | |
} | |
} | |
return orig; | |
}; | |
// Add a plugin system | |
Lace.plugin = function(name, defaults, methods) { | |
var extend = this.extend; | |
this.prototype[name] = function(method, options) { | |
if (typeof method === "object") { | |
options = method; | |
method = "init"; | |
} | |
if (typeof method === "undefined") { | |
method = "init"; | |
} | |
if (typeof method === "string" && typeof methods[method] === "function") { | |
methods[method].call(this, extend({}, defaults, options)); | |
} | |
}; | |
}; | |
// Export modules | |
if (typeof define === "function" && define.amd) { | |
// Define as AMD module | |
define(function() { | |
return Lace; | |
}); | |
} else if (typeof module !== "undefined" && module.exports) { | |
// Export to CommonJS | |
module.exports = Lace; | |
} else { | |
// Export to global object | |
window.Lace = Lace; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment