New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

agave

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

agave - npm Package Compare versions

Comparing version 0.1.4 to 0.2.0

.jshintrc

427

index.js

@@ -0,1 +1,2 @@

// Agave.JS
// I'm a UMD module (works in RequireJS and CommonJS-like environments)

@@ -18,185 +19,250 @@ // See https://github.com/umdjs

// Agave.JS
// Extend objects with Agave methods, using
var enable = function(prefix){
var global = this;
// object.getKeys() returns an array of keys
var getKeys = function(){
return Object.keys(this);
};
var SECONDS = 1000;
var MINUTES = 60 * SECONDS;
var HOURS = 60 * MINUTES;
var DAYS = 24 * HOURS;
var WEEKS = 7 * DAYS;
// object.getSize() returns the number of properties in the object
var getSize = function() {
return Object.keys(this).length;
};
// object.getKeys() returns an array of keys
var getKeys = function(){
return Object.keys(this);
};
// string.reverse()
var reverse = function() {
return this.split("").reverse().join("");
};
// object.getSize() returns the number of properties in the object
var getSize = function() {
return Object.keys(this).length;
};
// string.leftStrip(stripChars) returns the string with the leading chars removed
var leftStrip = function(stripChars) {
var result = this;
while ( true ) {
if ( ! stripChars.contains(result.charAt(0)) ) {
return result;
} else {
result = result.slice(1);
// string.reverse()
var reverse = function() {
return this.split("").reverse().join("");
};
// string.leftStrip(stripChars) returns the string with the leading chars removed
var leftStrip = function(stripChars) {
var result = this;
while ( true ) {
// Note result could be zero characters
if ( ! stripChars[prefix+'contains'](result.charAt(0)) || ! result) {
return result;
} else {
result = result.slice(1);
}
}
}
};
};
// string.rightStrip(stripChars) returns the string with the trailing chars removed
var rightStrip = function(stripChars) {
return this.reverse().leftStrip(stripChars).reverse();
};
// string.rightStrip(stripChars) returns the string with the trailing chars removed
var rightStrip = function(stripChars) {
return this[prefix+'reverse']()[prefix+'leftStrip'](stripChars)[prefix+'reverse']();
};
// string.strip(stripChars) returns the string with the leading and trailing chars removed
var strip = function(stripChars) {
return this.leftStrip(stripChars).rightStrip(stripChars);
};
// object.getPath - get the value of the nested keys provided in the object.
// If any are missing, return undefined. Used for checking JSON results.
var getPath = function(pathItems) {
var obj = this;
var delim = '/';
var result;
var still_checking = true;
// Handle Unix style paths
if ( typeof(pathItems) === 'string' ) {
pathItems = pathItems.strip(delim).split(delim);
}
pathItems.forEach( function(pathItem) {
if ( still_checking ) {
if ( ! obj.hasOwnProperty(pathItem) ) {
result = undefined;
still_checking = false;
} else {
result = obj[pathItem];
// string.strip(stripChars) returns the string with the leading and trailing chars removed
var strip = function(stripChars) {
return this[prefix+'leftStrip'](stripChars)[prefix+'rightStrip'](stripChars);
};
// object.getPath - get the value of the nested keys provided in the object.
// If any are missing, return undefined. Used for checking JSON results.
var getPath = function(pathItems) {
var obj = this;
var delim = '/';
var result;
var still_checking = true;
// Handle Unix style paths
if ( typeof(pathItems) === 'string' ) {
pathItems = pathItems[prefix+'strip'](delim).split(delim);
}
pathItems.forEach( function(pathItem) {
if ( still_checking ) {
if ( ! obj.hasOwnProperty(pathItem) ) {
result = undefined;
still_checking = false;
} else {
result = obj[pathItem];
}
obj = obj[pathItem];
}
obj = obj[pathItem];
}
});
return result;
};
// array.findItem(test_function) returns the first item that matches the test_function
var findItem = function(test_function){
var arr = this;
var last_index;
var found = arr.some(function(item, index) {
last_index = index;
return test_function(item);
});
if ( found ) {
return arr[last_index];
} else {
return null;
}
};
// string.endsWith(suffix) returns true if string ends with the suffix
var endsWith = function(suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
// string.endsWith(prefix) returns true if string ends with the prefix
var startsWith = function(prefix){
return this.slice(0, prefix.length) === prefix;
};
// array.contains(item) returns true if an array contains an item
// string.contains(substring) returns true if a string contains a substring
var contains = function(item){
return ( this.indexOf(item) !== -1);
};
// Extend an array with another array.
// Cleverness alert: since .apply() accepts an array of args, we use the new_array as all the args to push()
var extend = function(new_array) {
Array.prototype.push.apply(this, new_array);
return this;
};
// string.repeat() repeat a string 'times' times. Borrowed from ES6 shim at https://github.com/paulmillr/es6-shim
var repeat = function(times) {
if (times < 1) return '';
if (times % 2) return this.repeat(times - 1) + this;
var half = this.repeat(times / 2);
return half + half;
};
});
return result;
};
// Clone an object recursively
var clone = function() {
var newObj = (this instanceof Array) ? [] : {};
for (var key in this) {
if (this[key] && typeof this[key] == "object") {
newObj[key] = this[key].clone();
// array.findItem(test_function) returns the first item that matches the test_function
var findItem = function(test_function){
var arr = this;
var last_index;
var found = arr.some(function(item, index) {
last_index = index;
return test_function(item);
});
if ( found ) {
return arr[last_index];
} else {
newObj[key] = this[key];
return null;
}
}
return newObj;
};
};
var arrayClone = function(){return this.slice();};
// string.endsWith(suffix) returns true if string ends with the suffix
var endsWith = function(suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
// Add a new element as a child of this element
var createChild = function(name, attributes, text) {
var newElement = document.createElement(name);
if ( attributes ) {
for (var attribute in attributes) {
newElement.setAttribute(attribute, attributes[attribute]);
}
}
if ( text ) {
newElement.textContent = text;
}
return this.appendChild(newElement);
};
// string.endsWith(prefix) returns true if string ends with the prefix
var startsWith = function(prefix){
return this.slice(0, prefix.length) === prefix;
};
// Apply the CSS styles
var applyStyles = function(styles) {
for ( var style in styles ) {
this.style[style] = styles[style];
}
return this;
};
// array.contains(item) returns true if an array contains an item
// string.contains(substring) returns true if a string contains a substring
var contains = function(item){
return ( this.indexOf(item) !== -1);
};
// Return array of an elements parent elements from closest to farthest
var getParents = function(selector) {
var parents = [];
var parent = this.parentNode;
// While parents are 'element' type nodes
// See https://developer.mozilla.org/en-US/docs/DOM/Node.nodeType
while ( parent && parent.nodeType && parent.nodeType === 1 ) {
if ( selector ) {
if ( parent.matches(selector) ) {
parents.push(parent);
}
// Extend an array with another array.
// Cleverness alert: since .apply() accepts an array of args, we use the new_array as all the args to push()
var extend = function(new_array) {
Array.prototype.push.apply(this, new_array);
return this;
};
// string.repeat() repeat a string 'times' times. Borrowed from ES6 shim at https://github.com/paulmillr/es6-shim
var repeat = function(times) {
if (times < 1) return '';
if (times % 2) return this[prefix+'repeat'](times - 1) + this;
var half = this[prefix+'repeat'](times / 2);
return half + half;
};
// Clone an object recursively
var clone = function() {
var newObj = (this instanceof Array) ? [] : {};
for (var key in this) {
if (this[key] && typeof this[key] == "object") {
newObj[key] = this[key][prefix+'clone']();
} else {
newObj[key] = this[key];
}
}
return newObj;
};
var arrayClone = function(){return this.slice();};
// Array toNodeList converts arrays to NodeLists
var toNodeList = function(){
var fragment = document.createDocumentFragment();
this.forEach(function(item){
fragment.appendChild(item);
});
return fragment.childNodes;
};
// Convert Number to (function name). +ensures type returned is still Number
var seconds = function() {
return +this * SECONDS;
};
var minutes = function() {
return +this * MINUTES;
};
var hours = function() {
return +this * HOURS;
};
var days = function() {
return +this * DAYS;
};
var weeks = function() {
return +this * WEEKS;
};
// Helper function for before() and after()
var getTimeOrNow = function(date) {
return (date || new Date()).getTime();
};
// Return Number of seconds to time delta from date (or now if not specified)
var before = function(date) {
var time = getTimeOrNow(date);
return new Date(time-(+this));
};
// Return Number of seconds to time delta after date (or now if not specified)
var after = function(date) {
var time = getTimeOrNow(date);
return new Date(time+(+this));
};
// Add a new element as a child of this element
var createChild = function(name, attributes, text) {
var newElement = document.createElement(name);
if ( attributes ) {
for (var attribute in attributes) {
newElement.setAttribute(attribute, attributes[attribute]);
}
}
if ( text ) {
newElement.textContent = text;
}
return this.appendChild(newElement);
};
// Apply the CSS styles
var applyStyles = function(styles) {
for ( var style in styles ) {
this.style[style] = styles[style];
}
return this;
};
// Toggle a class
var toggleClass = function(className) {
if ( this.classList.contains(className) ) {
this.classList.remove(className);
} else {
parents.push(parent);
}
parent = parent.parentNode;
}
return parents;
};
this.classList.add(className);
}
return this;
};
// Polyfill if Element.prototype.matches doesn't exist.
var prefixedMatchesMethod = ( !this.Element || Element.prototype.msMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.oMatchesSelector);
// Return nodeList of an elements parent elements from closest to farthest
var ancestorNodes = function(selector) {
var ancestors = [];
var parent = this.parentNode;
// While parents are 'element' type nodes
// See https://developer.mozilla.org/en-US/docs/DOM/Node.nodeType
while ( parent && parent.nodeType && parent.nodeType === 1 ) {
if ( selector ) {
if ( parent.matches(selector) ) {
ancestors.append(parent);
}
} else {
ancestors.append(parent);
}
parent = parent.parentNode;
}
// Return a NodeList to be consistent with childNodes
return ancestors.toNodeList();
};
// Add method as a non-enumerable property on obj with the name methodName
var addMethod = function( obj, methodName, method) {
// Check - NodeLists and Elements don't always exist on all JS implementations
if ( obj ) {
// Don't add if the method already exists
if ( ! obj.method ) {
Object.defineProperty( obj.prototype, methodName, {value: method, enumerable: false});
}
}
};
// Polyfill if Element.prototype.matches doesn't exist.
var prefixedMatchesMethod = ( !this.Element || Element.prototype.msMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.webkitMatchesSelector || Element.prototype.oMatchesSelector);
// Extend objects with Agave methods, using
var enable = function(prefix){
var global = this;
// Add method as a non-enumerable property on obj with the name methodName
var addMethod = function( global, objectName, prefix, methodName, method) {
var objectToExtend = global[objectName];
methodName = prefix ? prefix+methodName: methodName;
// Check - NodeLists and Elements don't always exist on all JS implementations
if ( objectToExtend ) {
// Don't add if the method already exists
if ( ! objectToExtend.prototype.hasOwnProperty(methodName) ) {
Object.defineProperty( objectToExtend.prototype, methodName, {
value: method,
enumerable: false
});
}
}
};
var newMethods = {

@@ -207,3 +273,4 @@ 'Array':{

'contains':contains,
'clone':arrayClone
'clone':arrayClone,
'toNodeList':toNodeList
},

@@ -215,3 +282,4 @@ 'Object':{

'getPath':getPath,
'contains':contains
'contains':contains,
'clone':clone
},

@@ -229,7 +297,17 @@ 'String':{

},
'Number':{
'seconds':seconds,
'minutes':minutes,
'hours':hours,
'days':days,
'weeks':weeks,
'before':before,
'after':after
},
'Element':{
'createChild':createChild,
'getParents':getParents,
'ancestorNodes':ancestorNodes,
'matches':prefixedMatchesMethod,
'applyStyles':applyStyles
'applyStyles':applyStyles,
'toggleClass':toggleClass
},

@@ -241,11 +319,6 @@ 'NodeList':{

};
for ( var obj in newMethods ) {
for ( var method in newMethods[obj] ) {
if ( prefix ) {
methodName = prefix+method;
} else {
methodName = method;
}
addMethod(global[obj], methodName, newMethods[obj][method]);
}
for ( var objectName in newMethods ) {
for ( var methodName in newMethods[objectName] ) {
addMethod(global, objectName, prefix, methodName, newMethods[objectName][methodName]);
}
}

@@ -252,0 +325,0 @@ }.bind();

{
"name": "agave",
"version": "0.1.4",
"version": "0.2.0",
"author": "Mike MacCana <mike.maccana@gmail.com>",

@@ -15,2 +15,3 @@ "description": "Safely extends native JS objects with helpful, intuitive methods.",

"agave",
"agavejs",
"methods",

@@ -21,10 +22,11 @@ "native"

"devDependencies": {
"jsdom":"0.2.19",
"requirejs":"2.0.6"
"jsdom":"0.6.5",
"requirejs":"2.1.6",
"mocha":"1.10.0"
},
"license": "MIT",
"engines": {
"node": ">=0.8"
"node": ">=0.10"
}
}

@@ -1,16 +0,23 @@

# Agave.JS [![Build Status](https://secure.travis-ci.org/mikemaccana/agave.png?branch=master)](https://travis-ci.org/mikemaccana/agave)
# Agave.JS
## Cleaner, simpler Javascript for ES5 environments
## Cleaner, simpler JavaScript for ES5 environments
Agave.js safely extends native Javascript objects with helpful, intuitive methods that make your code shorter and more readable.
[![Build Status](https://secure.travis-ci.org/mikemaccana/agave.png?branch=master)](https://travis-ci.org/mikemaccana/agave)
- Adds things you use every day. See 'What does Agave provide?' below.
- Built only for ES5 enviroments like Chrome, Firefox, Safari, IE9, IE10 and node.js. Agave uses ES5 specific features to safely extend inbuilt objects.
- Is tiny. <300 lines of code. Agave also uses ES5 to stay small.
- Is loadable both as a regular node module and via RequireJS as an AMD module.
Agave.js **safely** extends native JavaScript objects with helpful, intuitive methods that **make your code shorter and more readable**.
- Adds useful things you'll use every day.
- Actual methods, ie, on the objects you expect them to be on. No underscores or other punctuation.
- Is less than 320 lines of code. Agave doesn't include things that are already in ES5, so it stays small.
- Uses [prefixing](#prefixing) and ES5 [defineProperty()](#defineProperty) to safely extend inbuilt objects.
- Available both as a regular node module and via RequireJS as an AMD module.
Agave works on [current versions of Chrome, Firefox, Safari, IE9, IE10 and node.js](#support).
### What does Agave provide?
#### Object methods
#### <a name="object"></a>Object methods
The following examples are based on this sample object:
var mockObject = {

@@ -26,12 +33,14 @@ foo: 'bar',

##### .getKeys()
##### <a name="objectgetKeys"></a>.getKeys()
Returns an array of the object’s keys.
mockObject.getKeys()
Returns:
[‘foo’,’bar’]
##### .getSize()
##### <a name="objectgetSize"></a>.getSize()
Returns the number of properties in the object.

@@ -45,8 +54,8 @@

##### .getPath(path)
##### <a name="objectgetPath"></a>.getPath(*path*)
Provided with either a '/' separated path, or an array of keys, get the value of the nested keys in the object.
If any of the keys are missing, return undefined. This is very useful for useful for checking JSON API responses where something useful is buried deep inside an object. Eg, the following code:
Provided with either a '/' separated path, or an array of keys, get the value of the nested keys in the object.
If any of the keys are missing, return *undefined*. This is very useful for useful for checking JSON API responses where something useful is buried deep inside an object. Eg, the following code:
mockObject.getPath('/baz/zar/zog')
mockObject.getPath('/baz/zar/zog')

@@ -60,11 +69,11 @@ or, alternatively:

'something useful'
Keys, of course, could be strings, array indices, or anything else.
#### Array methods
#### <a name="array"></a>Array methods
##### .clone()
##### <a name="arrayclone"></a>.clone()
Returns a shallow clone of the object.
##### .contains(_item_)
##### <a name="arraycontains"></a>.contains(*item*)

@@ -79,11 +88,14 @@ returns true if the array contains the item.

##### .findItem(_testfunction_)
##### <a name="arrayfindItem"></a>.findItem(*testfunction*)
When provided with a function to test each item against, returns the first item that where testfunction returns true.
##### .extend(_newarray_)
Adds the items from _newarray_ to the end of this array.
##### <a name="arrayextend"></a>.extend(*newarray*)
Adds the items from *newarray* to the end of this array.
#### String methods
##### <a name="arraytoNodeList"></a>.toNodeList()
Turns an array of Elements into a NodeList.
##### .contains(_substring_)
#### <a name="string"></a>String methods
##### <a name="stringcontains"></a>.contains(*substring*)
returns true if a string contains the substring

@@ -93,10 +105,10 @@

Returns:
Returns:
true
##### .startsWith(_substring_)
##### <a name="stringstartsWith"></a>.startsWith(*substring*)
returns true if a string starts with the substring
##### .endsWith(_substring_)
##### <a name="stringendsWith"></a>.endsWith(*substring*)
returns true if a string ends with the substring

@@ -106,7 +118,7 @@

Returns:
Returns:
true
##### .strip(_chars_)
##### <a name="stringstrip"></a>.strip(*chars*)
returns the string, with the specified chars removed from the beginning and end.

@@ -116,22 +128,63 @@

Returns:
Returns:
'ello wor'
##### .leftStrip(_chars_)
##### <a name="stringleftStrip"></a>.leftStrip(*chars*)
returns the string, with the specified chars removed from the beginning.
##### .rightStrip(_chars_)
##### <a name="stringrightStrip"></a>.rightStrip(*chars*)
returns the string, with the specified chars removed from the end.
##### .forEach(_iterationfunction_)
Runs _iterationfunction_ over each character in the String. Just like ES5’s inbuilt Array.forEach().
##### <a name="stringforEach"></a>.forEach(*iterationfunction*)
##### .repeat(_times_)
Repeat the string _times_ times.
Runs *iterationfunction* over each character in the String. Just like ES5’s inbuilt Array.forEach().
#### NodeList methods
##### <a name="stringrepeat"></a>.repeat(*times*)
NodeLists are what's returned when you use the document.querySelectorAll, or
Repeat the string *times* times.
#### <a name="number"></a>Number methods
**Note:** numbers in JavaScript have to be wrapped in brackets to use methods on them, otherwise the '.' is interpreted as the decimal point in a Float.
##### <a name="numberseconds"></a>.seconds, .hours(), .days(), and .weeks()
Converts a number into the amount of milliseconds for a timespan. For example:
(5).days()
Returns:
432000000
Since 5 days is 432000000 milliseconds.
##### <a name="numberbefore"></a>.before(), .after()
Turns a number (assumed to be an amount of milliseconds) into the Date in the past (using .before) or the future (using .after). You'd typically combine this with .seconds, .hours, .days, and .weeks to easily get a date a certain amount of units in the past or the future. For example:
(2).days().before()
Returns a Date for 2 days ago, eg:
Tue Jun 04 2013 22:16:50 GMT+0100 (BST)
You can also specify a date to be before/after. For example:
var joinedCompanyDate = new Date('Tue Jun 04 2013 1:00:00 GMT+0100 (BST)')
(3).weeks().after(joinedCompanyDate)
Returns a Date for 3 weeks after that date, eg:
Thu Jun 27 2013 22:44:05 GMT+0100 (BST)
#### <a name="nodelist"></a>NodeList methods
NodeLists are what's returned when you use the document.querySelectorAll(), or similar methods.
For example, given the following document:
<html>

@@ -149,3 +202,3 @@ <body>

For example, to fetch a list of all paragraphs:
We can fetch a list of all paragraphs:

@@ -156,10 +209,10 @@ var paragraphs = document.getElementsByTagName('p');

##### .reverse()
##### <a name="nodelistreverse"></a>.reverse()
Returns a reversed version of the nodeList.
##### .forEach(_iterationfunction_)
Runs _iterationfunction_ over each node in the NodeList. Just like ES5’s inbuilt Array.forEach().
##### <a name="nodelistforEach"></a>.forEach(*iterationfunction*)
Runs *iterationfunction* over each node in the NodeList. Just like ES5’s inbuilt Array.forEach().
Here’s an example of changing every paragraph in a document to say ‘Hello’ (look ma, No JQuery!).
paragraphs.forEach(function(paragraph){

@@ -169,7 +222,7 @@ paragraph.innerText = 'Hello.';

#### Element methods
#### <a name="element"></a>Element methods
Agave also provides useful methods for Elements.
##### .createChild(name, attributes, innerText)
##### <a name="elementcreateChild"></a>.createChild(name, attributes, innerText)

@@ -181,5 +234,5 @@ Make a new child element, with the tag name, any attributes, and inner text specified.

Would create a new
Would create a new
<p id="testpara">hey there</p>
<p id="testpara">hey there</p>

@@ -190,13 +243,13 @@ element beneath

##### .matches(_selector_)
##### <a name="elementmatches"></a>.matches(*selector*)
Returns true if the element matches the selector provided.
##### .applyStyles(_styles_)
##### <a name="elementapplyStyles"></a>.applyStyles(*styles*)
Apply the styles mentioned to the element.
##### .getParents(_selector_)
##### <a name="elementancestorNodes"></a>.ancestorNodes(*selector*)
Returns a list of an element’s parents, from closest to farthest ancestor. If selector is provided, only the parents which match the selector will be returned.
Returns a NodeList of an element’s parents, from closest to farthest ancestor. If selector is provided, only the parents which match the selector will be returned.

@@ -210,4 +263,6 @@ ## Why would I want to use Agave?

[Sugar.js](http://sugarjs.com/) is an excellent project and was the inspiration for Agave. Like Sugar, Agave provides useful additional methods on native objects.
- Agave focuses only on things JS programmers do every day, and is much smaller than Sugar.js. Sugar.js has String.prototype.humanize() and String.prototype.hankaku(). Agave won’t ever have those.
- Agave does not attempt to support IE8 and other ES3 browsers, resulting in a much smaller code base that is free of ES3 shims.
- Sugar extends String, Array etc but avoids extending Object specifically. Agave extends all prototypes using a user-specified prefix to avoid collisions.
- Agave focuses only on things JS programmers do every day, and is much smaller than Sugar.js. Sugar.js has String.prototype.humanize() and String.prototype.hankaku(). Agave won’t ever have those.
- Agave has a more explicit method naming style that’s consistent with the ES5 specification.

@@ -217,5 +272,6 @@

- Agave.js provides additional methods to complement those provided by ES5, rather than functions attached to punctuation.
- Agave.js provides additional methods to complement those provided by ES5, rather than functions attached to punctuation.
- Agave doesn’t require a separate string library.
- Agave does not attempt to support IE8 and other ES3 browsers, resulting in a much smaller code base that is free of ES3->ES5 shims.
- Agave is probably not as fast as lodash - it deliberately chooses simple, more obvious code over faster but more obscure options. This shouldn’t make much different to most people, but if it does, you can easily patch Agave to use any preferred techniques.

@@ -226,10 +282,10 @@ ### I read that adding methods to prototypes is bad

### Q. Will Agave methods appear when iterating over objects?
### <a name="defineProperty"></a>Q. Will Agave methods appear when iterating over objects?
### A. No. Methods will never appear when iterating over objects.
Adding methods to inbuilt objects _was_ bad, back on ES3 browsers like IE8 and Firefox 3 and older. ES3 didn’t provide a way for developers to add their own non-enumerable properties to inbuilt objects.
Adding methods to inbuilt objects _was_ bad, back on ES3 browsers like IE8 and Firefox 3 and older. ES3 didn’t provide a way for developers to add their own non-enumerable properties to inbuilt objects.
Let's see the problem: open your browser console right now and add a method, the traditional way:
Object.prototype.oldStyleMethod = function oldStyleMethod (){}
Object.prototype.oldStyleMethod = function oldStyleMethod (){}

@@ -256,5 +312,5 @@ And make an object:

The answer is that inbuilt methods in Javascript have always been non-enumerable. But __in ES3, you never had the ability to make your own non-enumerable methods__.
The answer is that inbuilt methods in JavaScript have always been non-enumerable. But __in ES3, you never had the ability to make your own non-enumerable methods__.
ES5 - the current version of Javascript created in 2009 that Chrome, Firefox, and IE9/10, as well as node.js use - specifically allows for the [addition of new non-enumerable properties via Object.defineProperty()](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty).
ES5 - the current version of JavaScript created in 2009 that Chrome, Firefox, and IE9/10, as well as node.js use - specifically allows for the [addition of new non-enumerable properties via Object.defineProperty()](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty).

@@ -267,14 +323,14 @@ So open a new tab. Let’s try again, ES5-style:

Hrm, it seems newStyleMethod(), just like toString(), doesn’t interfere with our loops.
Hrm, it seems newStyleMethod(), just like toString(), doesn’t interfere with our loops.
This is exactly what Agave uses. As a result, Agave’s methods will **never** show up in for loops.
This is exactly what Agave uses. As a result, Agave’s methods will **never** show up in for loops.
So if you’re OK with Agave’s requirements - ie, you support only ES5 environments like current generation browsers and node - you can use Agave.
So if you’re OK with Agave’s requirements - ie, you support only ES5 environments like current generation browsers and node - you can use Agave.
### Q. Future ES versions or other libraries might use the same method names to do different stuff
### A. That’s why we let you prefix all method names
### <a name="prefixing"></a>Q. Future ES versions or other libraries might use the same method names to do different stuff
### A. That’s why Agave makes you prefix all method names
Another concern may be naming or implementation conflicts - ie, another library or perhaps a new version of ES includes some code that uses the same method name to do something differently. This is why __Agave allows you to prefix every method it provides__. Just start it with:
Another concern may be naming or implementation conflicts - ie, another library or perhaps a new version of ES includes some code that uses the same method name to do something differently. This is why __Agave makes you to prefix every method it provides__. Just start it with:
agave.enable(‘av’);
agave.enable('av');

@@ -285,19 +341,18 @@ or the prefix of your choice to have all the methods prefixed with whatever string you like.

You may still prefer unprefixed, for the following reasons:
The prefix can be as short or as long as you like. PeIn my oen experience I've found two letters has been enough to avoid conflicts in the last year I've been using Agave, prior to its public release. If you're think this might not be enough to satisfy the need for uniqueness, use a longer prefix. If you're feeling adventurous (and you strongly control the libraries used in your projects) you can use no prefix at all.
- You may find the benefits of shorter code ourweigh the rish of a possible future conflict.
- Agave's developers track ES6 updates and specifically try to avoid conflicts with what’s proposed.
### Q. There are new methods on my window object!
### A. Yes, window is an object. This is how JS works.
Everything’s an object in JS, so eveerything has has object methods. We mentioned object.toString() earlier - there’s a window.toSting() in your browser, and a global.toString() in Node that JS provides because window and global are objects.
Everything’s an object in JS, so eveerything has has object methods. We mentioned object.toString() earlier - there’s a window.toSting() in your browser, and a global.toString() in Node that JS provides because window and global are objects.
When running agave, the additional methods added to Object.prototype will appear on window and global just like the inbuilt ones. You might find this odd, but it’s expected behavior.
You may find this useful - for example, if you wanted to find out whether some deeply nested set of keys exists underneath window, then .getKeys() or it’s equivalent.
You may find this useful - for example, if you wanted to find out whether some deeply nested set of keys exists underneath window, then .getKeys() is awfully handy.
It would make things *nicer* if a future version of JS allowed us to isolate prototypes between modules. But it certainly won’t kill us in the meantime if we’re using prefixed, non-enumerable methods.
### Using Agave
#### On the server (node.js)
##### <a name="node"></a>On the server (node.js)

@@ -312,12 +367,12 @@ Just run:

#### In the browser, on the server using RequireJS, or shared between the browser and server.
#### <a name="browser"></a>In the browser, on the server using RequireJS, or shared between the browser and server.
Agave is provided as an AMD module. You’d normally load it as a dependency for your own module, either in the browser or on node.js, using [RequireJS](http://requirejs.org/):
define('yourmodulename', ['agave'], function (agave) {
define('yourmodulename', ['agave'], function (agave) {
// Start Agave, optionally you can also provide a prefix of your choice.
agave.enable(_optionalprefix_);
agave.enable(*optionalprefix*);
// Your code here...
})

@@ -329,3 +384,3 @@

Awesome. Fork the repo, add your code, add your tests to tests.js and send me a pull request.
Awesome. Fork the repo, add your code, add your tests to tests.js and send me a pull request.

@@ -341,6 +396,10 @@ ### Tests

### What About IE8 and Firefox 3 support?
### <a name="support"></a>What browsers does Agave support?
Sorry, but this isn’t possible. ES3 browsers don’t support Object.defineProperty() and it cannot be emulated via shims.
Any ES5 compatible environment. This includes current Chrome, current Firefox, current Safari, IE9/10 and node.js.
#### What about IE8 and Firefox 3 support?
Sorry, but this isn’t possible. ES3 browsers like IE8 and Firefox 3 don’t support Object.defineProperty() and it cannot be emulated via shims.
### License

@@ -347,0 +406,0 @@

/*jshint multistr:true */
// Tests. Mocha/assert style. See
// http://visionmedia.github.com/mocha/
// Tests. Mocha/assert style. See
// http://visionmedia.github.com/mocha/
// http://nodejs.org/docs/latest/api/assert.html
var assert = require('assert');
var assert = require('assert');
var jsdom = require('jsdom');

@@ -23,3 +23,3 @@ var agave = require('../index.js');

}
};
};

@@ -33,3 +33,3 @@ // Set up a global.document with a DOM in the same way a browser has

});
window = document.createWindow();
var window = document.createWindow();
['Element','NodeList','document'].forEach(function(obj){

@@ -55,12 +55,12 @@ global[obj] = window[obj];

setupDOM(mockHTML);
agave.enable();
agave.enable('av');
describe('Array.contains', function(){
it('fetches the item accurately', function(){
assert(['one','two','three'].contains('two') );
assert(['one','two','three'].avcontains('two') );
});
it('handles missing items accurately', function(){
assert( ! ['one','two','three'].contains('notthere') );
});
assert( ! ['one','two','three'].avcontains('notthere') );
});
});

@@ -70,3 +70,3 @@

it('extends the array accurately', function(){
assert.deepEqual([1,2,3].extend([4,5]), [1,2,3,4,5] );
assert.deepEqual([1,2,3].avextend([4,5]), [1,2,3,4,5] );
});

@@ -77,7 +77,7 @@ });

it('checks for the substring accurately', function(){
assert('elephantine'.contains('tin') );
});
assert('elephantine'.avcontains('tin') );
});
it('handles missing substrings accurately', function(){
assert( ! 'elephantine'.contains('zam') );
});
assert( ! 'elephantine'.avcontains('zam') );
});
});

@@ -87,12 +87,12 @@

it('works if the string actually ends with the suffix', function(){
assert('Hello world'.endsWith('world'));
assert('Hello world'.avendsWith('world'));
});
it('handles trying to check if something ends in something larger than itself', function(){
assert.equal('world'.endsWith('Hello world'), false);
assert.equal('world'.avendsWith('Hello world'), false);
});
});
});
describe('String.startsWith', function(){
it('works if the string actually starts with the prefix', function(){
assert('Hello world'.startsWith('Hello'));
assert('Hello world'.avstartsWith('Hello'));
});

@@ -103,3 +103,3 @@ });

it('repeats strings accurately', function(){
assert.equal('Hello world'.repeat(3), 'Hello worldHello worldHello world');
assert.equal('Hello world'.avrepeat(3), 'Hello worldHello worldHello world');
});

@@ -110,3 +110,3 @@ });

it('reverses strings accurately', function(){
assert.equal('Hello world'.reverse(), 'dlrow olleH');
assert.equal('Hello world'.avreverse(), 'dlrow olleH');
});

@@ -117,3 +117,3 @@ });

it('strips from the left accurately', function(){
assert.equal('Hello world'.leftStrip('Hle'), 'o world');
assert.equal('Hello world'.avleftStrip('Hle'), 'o world');
});

@@ -124,9 +124,15 @@ });

it('strips from the right accurately', function(){
assert.equal('Hello world'.rightStrip('ldr'), 'Hello wo');
assert.equal('Hello world'.avrightStrip('ldr'), 'Hello wo');
});
});
describe('String.rightStrip', function(){
it('strips from the left accurately with a single character', function(){
assert.equal('a'.avleftStrip('a'), '');
});
});
describe('String.strip', function(){
it('strips from the both sides accurately', function(){
assert.equal('Hello world'.strip('Hld'), 'ello wor');
assert.equal('Hello world'.avstrip('Hld'), 'ello wor');
});

@@ -137,3 +143,3 @@ });

it('fetches keys accurately', function(){
assert.deepEqual(mockObject.getKeys(), ["foo","baz","null"] );
assert.deepEqual(mockObject.avgetKeys(), ["foo","baz","null"] );
});

@@ -144,4 +150,4 @@ });

it('counts keys accurately', function(){
assert.equal(mockObject.getSize(), 3);
});
assert.equal(mockObject.avgetSize(), 3);
});
});

@@ -151,6 +157,6 @@

it('correctly finds items that match the function', function(){
assert.equal(['one','two','three'].findItem(function(item){
assert.equal(['one','two','three'].avfindItem(function(item){
return (item === 'three');
}), 'three');
});
});
});

@@ -160,51 +166,55 @@

it('returns undefined when a value is missing', function(){
assert.equal(mockObject.getPath(['foo','pineapple']), undefined);
});
assert.equal(mockObject.avgetPath(['foo','pineapple']), undefined);
});
it('returns the value when the provided keys exist', function(){
assert.equal(mockObject.getPath(['baz','zar','zog']), 'victory');
assert.equal(mockObject.avgetPath(['baz','zar','zog']), 'victory');
});
it('returns the value when the provided keys exist, even if null is on the path', function(){
assert.equal(mockObject.getPath([null,'yarr','parrot']), 'ahoy');
assert.equal(mockObject.avgetPath([null,'yarr','parrot']), 'ahoy');
});
it('works using Unix-style paths', function(){
assert.equal(mockObject.getPath('/baz/zar/zog'), 'victory');
assert.equal(mockObject.avgetPath('/baz/zar/zog'), 'victory');
});
});
describe('Agave really doesn\'t affect for loops', function(){
it ('doesn\'t. really', function(){
for ( var key in mockObject ) {
assert( ! ['getKeys','getSize','getPath'].contains(key) );
}
describe('Object.clone', function(){
var copyObject = mockObject.avclone()
it('clones objects so that modification to the new object will not affect the original', function(){
copyObject.baz.bam = 'newvalue'
assert.equal(copyObject.avgetPath(['baz','bam']), 'newvalue');
assert.equal(mockObject.avgetPath(['baz','bam']), 'boo');
});
});
describe('Prefixing', function(){
agave.enable('av');
it('allows methods to be found under the prefix', function(){
assert('hamparty'.avcontains('art') );
describe('Number.days', function(){
it('correctly converts a number to days in seconds', function(){
assert.equal((5).avdays(), 432000000);
});
});
describe('NodeList.forEach', function(){
it('iterates over nodes properly', function(){
var results = [];
var paras = document.querySelectorAll('p');
paras.forEach(function(para){
results.push(para.textContent)
})
var correctResults = [
'Carles portland banh mi lomo twee.',
'Narwhal bicycle rights keffiyeh beard.',
'Pork belly beard pop-up kale chips.'
]
// Just check the first 3 results as other tests may add paragraphs
assert.deepEqual(results.slice(0,3),correctResults);
describe('Number.weeks.before and .after', function(){
it('correctly converts a number to a period in weeks before a set date', function(){
var someDate = new Date('Thu Jun 06 2013 22:44:05 GMT+0100 (UTC)')
var timezoneOffset = someDate.getTimezoneOffset()
assert.equal((3).avweeks().avbefore(someDate).toLocaleDateString("en-GB", {timeZone:'UTC'}), 'Thursday, May 16, 2013');
});
it('correctly converts a number to a period in weeks after a set date', function(){
var someDate = new Date('Thu Jun 06 2013 22:44:05 GMT+0100 (UTC)')
var timezoneOffset = someDate.getTimezoneOffset()
assert.equal((3).avweeks().avafter(someDate).toLocaleDateString("en-GB", {timeZone:'UTC'}), 'Thursday, June 27, 2013');
});
});
describe('Agave really doesn\'t affect for loops', function(){
it ('doesn\'t. really', function(){
for ( var key in mockObject ) {
assert( ! ['avgetKeys','avgetSize','avgetPath'].avcontains(key) );
}
});
});
describe('Element.createChild', function(){
var sillyText = 'ethical messenger bag';
var article = document.querySelector('article');
article.createChild('p',{'id':'testpara'},sillyText);
article.avcreateChild('p',{'id':'testpara'},sillyText);
it('creates children with the specified attributes', function(){

@@ -219,20 +229,8 @@ var paraCount = document.querySelector('#testpara');

describe('Element.getParents', function(){
it('returns all parent nodes', function(){
var ancestors = document.querySelector('heading').getParents();
var results = [];
ancestors.forEach(function(ancestor){
results.push(ancestor.tagName)
})
var correctResults = ["ARTICLE","BODY","HTML"];
assert.deepEqual(results, correctResults);
});
});
describe('Element.applyStyles', function(){
it('styles elements', function(){
var heading = document.querySelector('heading');
heading.applyStyles({'font-size':'18em'})
heading.avapplyStyles({'font-size':'18em'})
assert.equal(heading.style['font-size'], '18em');
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc