Created
April 7, 2011 12:48
-
-
Save Olical/907707 to your computer and use it in GitHub Desktop.
A pre release of Spark. This is for testing the selector speed.
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
/** | |
* @preserve Spark JavaScript Library v3.0.0 | |
* http://sparkjs.co.uk/ | |
* | |
* Copyright 2011, Oliver Caldwell | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://sparkjs.co.uk/licence.html | |
*/ | |
(function() { | |
// Create the object | |
function Spark(){} | |
/** | |
* Adds a variable to Spark's prototype | |
* | |
* @param {String} name Name you wish to add your variable under | |
* @param toAdd Variable you wish to add | |
*/ | |
Spark.prototype.extend = function(name, toAdd) { | |
// Add the object | |
Spark.prototype[name] = toAdd; | |
}; | |
/** | |
* Create a clone of the object. This should be done when anything is being stored in it for chaining. | |
* Otherwise added variables will be there for ever. | |
* This way they only exist within that chain | |
* | |
* @returns {Object} The copy of the object | |
*/ | |
Spark.prototype.clone = function() { | |
return new Spark(); | |
}; | |
// Expose the object | |
window.Spark = new Spark(); | |
// Set up the alias for the find function | |
window.$ = function(parameters, context) { | |
return window.Spark.find(parameters, context); | |
}; | |
}()); | |
/** | |
* Runs the specified function when the DOM is ready | |
* | |
* @param {Function} fn Function to be run when the DOM is ready | |
*/ | |
Spark.extend('ready', function(fn) { | |
// Check if we can use addEventListener | |
if(window.addEventListener) { | |
// For all browsers except IE | |
document.addEventListener('DOMContentLoaded', fn, false); | |
} | |
else { | |
// For IE | |
(function(){ | |
// Create the custom tag | |
var tempNode = document.createElement('document:ready'); | |
try { | |
// See if it throws errors until after it is ready | |
tempNode.doScroll('left'); | |
// Call the function | |
fn(); | |
} | |
catch(err) { | |
setTimeout(arguments.callee, 0); | |
} | |
})(); | |
} | |
}); | |
Spark.extend('ajax', { | |
/** | |
* Selects what AJAX object to use | |
* | |
* @returns {Object} The correct AJAX object for this browser | |
*/ | |
initialise: function() { | |
// Pass back the correct object | |
return (typeof XMLHttpRequest === 'undefined') ? | |
new ActiveXObject('Microsoft.XMLHTTP') : | |
new XMLHttpRequest(); | |
}, | |
/** | |
* Turns an object of parameters into a string | |
* | |
* @param {Object} parameters An object of parameters | |
* @returns {String} The combined string, ready to be appended to a filename | |
*/ | |
buildParameterString: function(parameters) { | |
// Initialise any required variables | |
var p = null, | |
built = ''; | |
// Loop through the parameters appending them to the filename | |
for(p in parameters) { | |
// Make sure it is not a prototype | |
if(parameters.hasOwnProperty(p) === true) { | |
// Add the parameter | |
built += escape(p) + '=' + escape(parameters[p]) + '&'; | |
} | |
} | |
// Remove the trailing ampersand and return the escaped string | |
return built.slice(0, built.length - 1); | |
}, | |
/** | |
* Pass the data to the callback when the request is complete | |
* | |
* @param {Object} req The AJAX request object | |
* @param {Function} callback The callback function that the data should be passed to | |
*/ | |
handleCallback: function(req, callback) { | |
// Listen for the change in state | |
req.onreadystatechange = function() { | |
// Check if it is finished | |
if(req.readyState === 4) { | |
// Check the status | |
if(req.status === 200) { | |
// It's all good, Pass the data to the callback | |
callback(req.responseText); | |
} | |
else { | |
// There was an error so pass false to the callback | |
callback(false); | |
} | |
} | |
}; | |
}, | |
/** | |
* Perform a get request with optional parameters either syncronously or asyncronously | |
* | |
* @param {String} file Path of the target file | |
* @param {Object} parameters The arguments you wish to pass to the file | |
* @param {Function} callback If set, the call become asyncronous and the data is passed to it on completion, it will pass false if it failed | |
* @returns {String|Boolean} The data retrived from the file if it is a syncronous call, returns false if it failed | |
*/ | |
get: function(file, parameters, callback) { | |
// Set up the AJAX object | |
var req = this.initialise(); | |
// Make sure parameters is an object | |
if(typeof parameters === 'object') { | |
// Add the parameters to the file name | |
file += '?' + this.buildParameterString(parameters); | |
} | |
// Check for the callback | |
if(typeof callback === 'function') { | |
// It exists, so pass it to the callback handling function | |
this.handleCallback(req, callback); | |
} | |
// Open the request, if the callback is set then make it asyncronous | |
req.open('GET', file, (typeof callback === 'function') ? true : false); | |
// Send the request | |
req.send(); | |
// Check if the callback has not been passed | |
if(typeof callback === 'undefined') { | |
if(req.status === 200) { | |
// Just return the content because it was a syncronous request | |
return req.responseText; | |
} | |
else { | |
// There was an error so return false | |
return false; | |
} | |
} | |
}, | |
/** | |
* Perform a post request with optional parameters either syncronously or asyncronously | |
* | |
* @param {String} file Path of the target file | |
* @param {Object} parameters The arguments you wish to pass to the file | |
* @param {Function} callback If set, the call become asyncronous and the data is passed to it on completion, it will pass false if it failed | |
* @returns {String|Boolean} The data retrived from the file if it is a syncronous call, returns false if it failed | |
*/ | |
post: function(file, parameters, callback) { | |
// Set up the AJAX object | |
var req = this.initialise(); | |
// Check for the callback | |
if(typeof callback === 'function') { | |
// It exists, so pass it to the callback handling function | |
this.handleCallback(req, callback); | |
} | |
// Open the request, if the callback is set then make it asyncronous | |
req.open('POST', file, (typeof callback === 'function') ? true : false); | |
// Set the headers | |
req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); | |
// Only send the data if it is set | |
if(typeof parameters === 'object') { | |
req.send(this.buildParameterString(parameters)); | |
} | |
else { | |
req.send(); | |
} | |
// Check if the callback has not been passed | |
if(typeof callback === 'undefined') { | |
if(req.status === 200) { | |
// Just return the content because it was a syncronous request | |
return req.responseText; | |
} | |
else { | |
// There was an error so return false | |
return false; | |
} | |
} | |
} | |
}); | |
/** | |
* Gets or sets cookies | |
* | |
* @param {String} name The name of the cookie you wish to get or set | |
* @param {String} content If passed the cookie will be set with this as it's content | |
* @param {Number} duration The amount of miliseconds you wish the cookie to last for, if not set then it will last for the session | |
* @returns {String} The content of the cookie whos name you specified | |
*/ | |
Spark.extend('cookie', function(name, content, duration) { | |
// Initialise any required variables | |
var cookies = document.cookie.split(';'), | |
i = null, | |
cookie = null, | |
date = new Date(); | |
// Check if we need to get or set | |
if(typeof content === 'undefined') { | |
// Get the cookie | |
// Loop through all the cookies | |
for(i = 0; i < cookies.length; i++) { | |
// Grab the current cookie and trim any whitespace | |
cookie = cookies[i].replace(/^\s+/g, ''); | |
// Check if the cookie contains the name | |
if(cookie.indexOf(name + '=') === 0) { | |
return cookie.substring(name.length + 1, cookie.length); | |
} | |
} | |
// Return false if we did not find it | |
return false; | |
} | |
else { | |
// Set the cookie | |
// Check for a passed duration | |
if(typeof duration !== 'undefined') { | |
// Add on the duration | |
date.setTime(date.getTime() + duration); | |
expires = '; expires=' + date.toGMTString(); | |
} | |
else { | |
// Otherwise set the expires to nothing | |
expires = ''; | |
} | |
// Set the cookie | |
document.cookie = name + '=' + escape(content) + expires + '; path=/'; | |
} | |
}); | |
/** | |
* Find elements that match the specified parameters | |
* | |
* @param {Object} parameters The criteria the element must meet to be selected | |
* @param {Element} context The place you wish to start the search from, defaults to document | |
* @returns {Object} Returns the Spark object to allow chaining | |
*/ | |
Spark.extend('find', function(parameters, context) { | |
// Initialise any required variables | |
var found = [], | |
filtered = [], | |
ctx = (typeof context !== 'undefined') ? context : document, | |
i = null, | |
e = null, | |
tempFound = null, | |
classes = null, | |
built = this.clone(); | |
// Check if parameters is not an actual search object | |
if(typeof parameters === 'object') { | |
if(typeof parameters.nodeName === 'string') { | |
// They passed an element, this needs to be adopted into the chain | |
built[0] = parameters; | |
built.elements = [parameters]; | |
built.length = 1; | |
// Return the object with the adopted value | |
return built; | |
} | |
else if(parameters instanceof Array) { | |
// They passed an array, this needs to be adopted into the chain | |
for(i = 0; i < parameters.length; i++) { | |
built[i] = parameters[i]; | |
} | |
built.length = parameters.length; | |
// Return the object with the adopted values | |
return built; | |
} | |
} | |
/** | |
* Removes duplicate values from an array | |
* | |
* @param {Array} target The target array to have duplicates remove from | |
* @returns {Array} The cleaned array with no duplicate values | |
*/ | |
function unique(target) { | |
var a = [], | |
l = target.length, | |
j = null, | |
i = null; | |
for(i = 0; i < l; i++) { | |
for(j = i + 1; j < l; j++) { | |
if(target[i] === target[j]) { | |
j = ++i; | |
} | |
} | |
a.push(target[i]); | |
} | |
return a; | |
} | |
/** | |
* Takes a string, breaks it down into its components and uses them to run the find function | |
* | |
* @param {String} selector The selector string | |
* @param {Object} offset The instance of Spark already containing elements | |
* @returns {Object} An instance of Spark containing all of the found elements | |
*/ | |
function parseSelector(selector, offset) { | |
// Initialise any required variables | |
var selectors = selector.split(/\s*,\s*/g), | |
paths = null, | |
built = Spark.clone(), | |
i = null, | |
p = null, | |
path = null, | |
found = [], | |
parameters = null, | |
tempFound = null, | |
regexs = [ | |
'^\\[([a-z_][\\-a-z0-9_]+)=[\'"](.*)[\'"]\\]', // Attribute comparison | |
'^\\[([a-z_][\\-a-z0-9_]+)\\]', // Has attribute | |
'^([a-z0-9*]+)', // Tag name comparison | |
'^#([a-z][a-z0-9-_]*)', // ID comparison | |
'^\\.(-?[_a-z]+[_a-z0-9\\-]*)', // Class comparison | |
'^\\[([a-z_][\\-a-z0-9_]+)~=[\'"](.*)[\'"]\\]', // Whitespace seperated attribute | |
'^\\[([a-z_][\\-a-z0-9_]+)\\|=[\'"](.*)[\'"]\\]', // Beginning of attribute with optional hyphen after | |
'^:first-child' // Element must be the first child of it's parent | |
], | |
finders = []; | |
// Set up all the RegExps | |
for(i = 0; i < regexs.length; i++) { | |
finders.push({ | |
search: new RegExp(regexs[i], 'i'), | |
remove: new RegExp(regexs[i] + '.*', 'i') | |
}); | |
} | |
// Loop through the selectors | |
for(i = 0; i < selectors.length; i++) { | |
// Grab the paths | |
paths = selectors[i].replace(/(>|\+)/g, " $1 ").replace(/\s+(>|\+)\s+/g, " $1").split(/\s+/g); | |
// Reset the parameters | |
parameters = []; | |
// Loop through all the paths | |
for(p = 0; p < paths.length; p++) { | |
// Grab the path | |
path = paths[p]; | |
// Add the new object | |
parameters.push({}); | |
// Keep looping until the string is gone | |
while(path.length > 0) { | |
// Check if it is a direct child selector or direct sibling | |
if(path.indexOf('>') === 0) { | |
parameters[p].child = true; | |
path = path.substr(1); | |
} | |
else if(path.indexOf('+') === 0) { | |
parameters[p].sibling = true; | |
path = path.substr(1); | |
} | |
// Do the checks | |
if(path.match(finders[5].search)) { | |
// Check if element has whitespace seperated attribute | |
// Make sure the object exists | |
if(typeof parameters[p].whiteSpaceAttribute === 'undefined') { | |
parameters[p].whiteSpaceAttribute = {}; | |
} | |
// Add the check | |
parameters[p].whiteSpaceAttribute[path.replace(finders[5].remove, "$1")] = path.replace(finders[5].remove, "$2"); | |
// Remove the selection | |
path = path.replace(finders[5].search, ''); | |
} | |
else if(path.match(finders[6].search)) { | |
// Check if element attribute begins with a string, potentially followed by a hyphen | |
// Make sure the object exists | |
if(typeof parameters[p].hyphenAttribute === 'undefined') { | |
parameters[p].hyphenAttribute = {}; | |
} | |
// Add the check | |
parameters[p].hyphenAttribute[path.replace(finders[6].remove, "$1")] = path.replace(finders[6].remove, "$2"); | |
// Remove the selection | |
path = path.replace(finders[6].search, ''); | |
} | |
else if(path.match(finders[0].search)) { | |
// Check if element has attribute | |
// Make sure the object exists | |
if(typeof parameters[p].attribute === 'undefined') { | |
parameters[p].attribute = {}; | |
} | |
// Add the check | |
parameters[p].attribute[path.replace(finders[0].remove, "$1")] = path.replace(finders[0].remove, "$2"); | |
// Remove the selection | |
path = path.replace(finders[0].search, ''); | |
} | |
else if(path.match(finders[1].search)) { | |
// Check if element has attribute | |
// Make sure the object exists | |
if(typeof parameters[p].attribute === 'undefined') { | |
parameters[p].attribute = {}; | |
} | |
// Add the check | |
parameters[p].attribute[path.replace(finders[1].remove, "$1")] = true; | |
// Remove the selection | |
path = path.replace(finders[1].search, ''); | |
} | |
else if(path.match(finders[2].search)) { | |
// Element | |
if(typeof parameters[p].tag === 'undefined') { | |
parameters[p].tag = path.replace(finders[2].remove, "$1"); | |
} | |
else { | |
if(typeof parameters[p].tag === 'string') { | |
parameters[p].tag = [parameters[p].tag]; | |
} | |
parameters[p].tag.push(path.replace(finders[2].remove, "$1")); | |
} | |
// Remove the selection | |
path = path.replace(finders[2].search, ''); | |
} | |
else if(path.match(finders[3].search)) { | |
// ID | |
if(typeof parameters[p].id === 'undefined') { | |
parameters[p].id = path.replace(finders[3].remove, "$1"); | |
} | |
else { | |
if(typeof parameters[p].id === 'string') { | |
parameters[p].id = [parameters[p].id]; | |
} | |
parameters[p].id.push(path.replace(finders[3].remove, "$1")); | |
} | |
// Remove the selection | |
path = path.replace(finders[3].search, ''); | |
} | |
else if(path.match(finders[4].search)) { | |
// Class | |
if(typeof parameters[p].classes === 'undefined') { | |
parameters[p].classes = path.replace(finders[4].remove, "$1"); | |
} | |
else { | |
if(typeof parameters[p].classes === 'string') { | |
parameters[p].classes = [parameters[p].classes]; | |
} | |
parameters[p].classes.push(path.replace(finders[4].remove, "$1")); | |
} | |
// Remove the selection | |
path = path.replace(finders[4].search, ''); | |
} | |
else if(path.match(finders[7].search)) { | |
// First child | |
parameters[p].first = true; | |
// Remove the selection | |
path = path.replace(finders[7].search, ''); | |
} | |
else { | |
// If it does not match anything return false to stop endless loops | |
return false; | |
} | |
} | |
} | |
// So now we have an array of parameter objects | |
// Set up temp found to search with | |
tempFound = offset; | |
// Loop through all of the parameter objects | |
for(p = 0; p < parameters.length; p++) { | |
// Now do the search into tempFound | |
tempFound = tempFound.find(parameters[p]); | |
} | |
// When done concat these results to the found array | |
found = found.concat(tempFound.elements); | |
} | |
// Clean the array | |
found = unique(found); | |
// Loop through the found adding them to the object | |
for(i = 0; i < found.length; i++) { | |
built[i] = found[i]; | |
} | |
// Add the array version | |
built.elements = found; | |
// Add the length | |
built.length = found.length; | |
// Return the built object | |
return built; | |
} | |
/** | |
* Compare the value of a tag or ID to an array or string of comparisons | |
* | |
* @param {String|Array} value Either an ID, an array of classes or a tag name to compare | |
* @param {String|Array} compare The string or array of values to check against | |
* @param {Boolean} tag If true, the values are converted to uppercase on comparison | |
* @param {Boolean} space If true, the values are whitespace seperated before comparison | |
* @param {Boolean} hyphen If true, the value must exactly match or start with followed by a hyphen | |
* @returns {Boolean} Returns true if it can not be compared or if they match | |
*/ | |
function compareValue(value, compare, tag, space, hyphen) { | |
// Initialise any required variables | |
var i = null, | |
e = null, | |
classes = ((value instanceof Array) ? value.join(' ') : false); | |
// Check what type of search we need to do | |
if(typeof compare === 'string') { | |
// Compare the two strings | |
if(classes) { | |
if(classes.match(new RegExp('(^| )' + compare + '($| )', 'g'))) { | |
return true; | |
} | |
else { | |
return false; | |
} | |
} | |
else { | |
if(value === ((tag) ? compare.toUpperCase() : compare)) { | |
return true; | |
} | |
else { | |
if(tag && compare === '*') { | |
return true; | |
} | |
return false; | |
} | |
} | |
} | |
else if(compare instanceof Array) { | |
// Loop through and compare | |
for(i = 0; i < compare.length; i++) { | |
if(classes) { | |
if(classes.match(new RegExp('(^| )' + compare[i] + '($| )', 'g'))) { | |
return true; | |
} | |
} | |
else { | |
if(value === ((tag) ? compare[i].toUpperCase() : compare[i])) { | |
return true; | |
} | |
} | |
} | |
// Default to returning false | |
return false; | |
} | |
else if(typeof compare === 'object') { | |
// It is an object of attributes, loop through and compare | |
// If any do not match, return false | |
for(i in compare) { | |
// Make sure it has the property and so does the object | |
if(compare.hasOwnProperty(i)) { | |
// If it is true then all we have to do is see if it exists | |
if(compare[i] === true) { | |
// So now if it has the attribute then continue | |
if(value.getAttribute(i) === null) { | |
// It doesnt | |
return false; | |
} | |
} | |
else { | |
// So now we check if it has the value again, if it does we compare | |
if(value.getAttribute(i) !== null) { | |
// It does, check what it is | |
if(typeof compare[i] === 'string') { | |
if(hyphen) { | |
if(value.getAttribute(i) !== compare[i] && value.getAttribute(i).indexOf(compare[i] + '-') !== 0) { | |
return false; | |
} | |
} | |
else { | |
if(((space) ? value.getAttribute(i).replace(/\s+/g, '').split('').join(' ') : value.getAttribute(i)) !== ((space) ? compare[i].replace(/\s+/g, '').split('').join(' ') : compare[i])) { | |
return false; | |
} | |
} | |
} | |
else if(compare[i] instanceof Array) { | |
// It is an or statement, so we need do a special check | |
for(e = 0; e < compare[i].length; e++) { | |
if(hyphen) { | |
if(value.getAttribute(i) !== compare[i][e] && value.getAttribute(i).indexOf(compare[i][e] + '-') !== 0) { | |
return false; | |
} | |
} | |
else { | |
if(((space) ? value.getAttribute(i).replace(/\s+/g, '').split('').join(' ') : value.getAttribute(i))!==((space) ? compare[i][e].replace(/\s+/g, '').split('').join(' ') : compare[i][e])) { | |
return false; | |
} | |
} | |
} | |
} | |
} | |
else { | |
// It doesnt | |
return false; | |
} | |
} | |
} | |
} | |
// Default to returning true | |
return true; | |
} | |
else { | |
// Default to returning true | |
return true; | |
} | |
} | |
/** | |
* Find elements from a context | |
* | |
* @param {String} tag The name of the tag you wish to find | |
* @param {Object} ctx The context you wish to search in | |
* @param {Boolean} child Only find direct children | |
* @param {Boolean} sibling Only find the next sibling element | |
* @param {Boolean} first Only find elements that are the first child | |
* @returns {Array} Returns an array of the found elements | |
*/ | |
function findElements(tag, ctx, child, sibling, first) { | |
// Initialise any required variables | |
var tempFound = null, | |
found = []; | |
// Check what the tag filter is | |
if(typeof tag === 'string') { | |
// Perform a basic tag search | |
tempFound = (sibling === true) ? ctx.parentNode.getElementsByTagName(tag) : ctx.getElementsByTagName(tag); | |
// Loop through the elements | |
for(e = 0; e < tempFound.length; e++) { | |
// Push the found element to found | |
// Check if it needs to be the first child | |
if(first === true && tempFound[e] === (tempFound[e].parentNode.firstElementChild || tempFound[e].parentNode.firstChild)) { | |
// And check if it is a direct child if we need to | |
if(child === true && tempFound[e].parentNode === ctx) { | |
found.push(tempFound[e]); | |
} | |
else if(sibling === true && (tempFound[e] === ctx.nextElementSibling || tempFound[e] === ctx.nextSibling)) { | |
found.push(tempFound[e]); | |
} | |
else if(!child && !sibling) { | |
found.push(tempFound[e]); | |
} | |
} | |
else if(!first) { | |
// And check if it is a direct child if we need to | |
if(child === true && tempFound[e].parentNode === ctx) { | |
found.push(tempFound[e]); | |
} | |
else if(sibling === true && (tempFound[e] === ctx.nextElementSibling || tempFound[e] === ctx.nextSibling)) { | |
found.push(tempFound[e]); | |
} | |
else if(!child && !sibling) { | |
found.push(tempFound[e]); | |
} | |
} | |
} | |
// Return the filtered array | |
return found; | |
} | |
else if(tag instanceof Array) { | |
// Perform a looping tag search | |
for(i = 0; i < tag.length; i++) { | |
// Search into the temporary location | |
tempFound = (sibling === true) ? ctx.parentNode.getElementsByTagName(tag[i]) : ctx.getElementsByTagName(tag[i]); | |
// Loop through the elements | |
for(e = 0; e < tempFound.length; e++) { | |
// Push the found element to found | |
// And check if it is a direct child if we need to | |
if(child === true && tempFound[e].parentNode === ctx) { | |
found.push(tempFound[e]); | |
} | |
else if(sibling === true && (tempFound[e] === ctx.nextElementSibling || tempFound[e] === ctx.nextSibling)) { | |
found.push(tempFound[e]); | |
} | |
else if(!child && !sibling) { | |
found.push(tempFound[e]); | |
} | |
} | |
} | |
// Return the found ones | |
return found; | |
} | |
else { | |
// Default to grabbing all tags | |
tempFound = (sibling === true) ? ctx.parentNode.getElementsByTagName('*') : ctx.getElementsByTagName('*'); | |
// Loop through the elements | |
for(e = 0; e < tempFound.length; e++) { | |
// Push the found element to found | |
// And check if it is a direct child if we need to | |
if(child === true && tempFound[e].parentNode === ctx) { | |
found.push(tempFound[e]); | |
} | |
else if(sibling === true && (tempFound[e] === ctx.nextElementSibling || tempFound[e] === ctx.nextSibling)) { | |
found.push(tempFound[e]); | |
} | |
else if(!child && !sibling) { | |
found.push(tempFound[e]); | |
} | |
} | |
// Return the filtered array | |
return found; | |
} | |
} | |
// Check if this is part of the chain | |
if(this.elements instanceof Array) { | |
// Find from the previously found | |
// Loop through the elements | |
for(i = 0; i < this.length; i++) { | |
tempFound = findElements(parameters.tag, this.elements[i], parameters.child, parameters.sibling, parameters.first); | |
// Loop through the elements | |
for(e = 0; e < tempFound.length; e++) { | |
// Push the found element to found | |
found.push(tempFound[e]); | |
} | |
} | |
} | |
else { | |
// Find from scratch | |
found = findElements(parameters.tag, ctx, parameters.child, parameters.sibling, parameters.first); | |
} | |
// Check if parameters is a string | |
if(typeof parameters === 'string') { | |
// If so, then return what is found by the parse selector function | |
return parseSelector(parameters, this); | |
} | |
// Loop through all elements | |
for(i = 0; i < found.length; i++) { | |
// Grab the current element | |
e = found[i]; | |
// Get the classes of the element | |
classes = e.className.split(/\s+/g); | |
// Check if the element matches | |
if( | |
compareValue(e.nodeName, parameters.tag, true) === true && | |
compareValue(classes, parameters.classes) === true && | |
compareValue(e.id, parameters.id) === true && | |
compareValue(e, parameters.attribute) === true && | |
compareValue(e, parameters.whiteSpaceAttribute, false, true) && | |
compareValue(e, parameters.hyphenAttribute, false, false, true) | |
) { | |
// Add the found element to the filtered array | |
filtered.push(e); | |
} | |
} | |
// Clean the array | |
filtered = unique(filtered); | |
// Loop through the filtered adding them to the object | |
for(i = 0; i < filtered.length; i++) { | |
built[i] = filtered[i]; | |
} | |
// Add the array version | |
built.elements = filtered; | |
// Add the length | |
built.length = filtered.length; | |
// Check if there is a find parameter | |
if(typeof parameters.find === 'object') { | |
// Refind with the passed parameters | |
built = built.find(parameters.find); | |
} | |
// Return the object with all the elements within it | |
return built; | |
}); | |
/** | |
* Loops through all of the elmenets contained in the Spark object passing the to a function | |
* | |
* @param {Function} fn Function for the current element to be passed to | |
* @returns {Object} Returns the Spark object for chaining | |
*/ | |
Spark.extend('each', function(fn) { | |
// Initialise any required variables | |
var i = null; | |
// Loop through all elements | |
for(i = 0; i < this.length; i++) { | |
// Pass the element to the function | |
fn(this[i]); | |
} | |
// Return the Spark object for chaining | |
return this; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment