diff --git a/vendor/backbone/backbone.js b/vendor/backbone/backbone.js
index cfa836155..9796cc04f 100644
--- a/vendor/backbone/backbone.js
+++ b/vendor/backbone/backbone.js
@@ -18,8 +18,10 @@
// restored later on, if `noConflict` is used.
var previousBackbone = root.Backbone;
- // Create a local reference to splice.
- var splice = Array.prototype.splice;
+ // Create a local reference to array methods.
+ var ArrayProto = Array.prototype;
+ var slice = ArrayProto.slice;
+ var splice = ArrayProto.splice;
// The top-level namespace. All public Backbone classes and modules will
// be attached to this. Exported for both CommonJS and the browser.
@@ -866,7 +868,9 @@
// Mix in each Underscore method as a proxy to `Collection#models`.
_.each(methods, function(method) {
Collection.prototype[method] = function() {
- return _[method].apply(_, [this.models].concat(_.toArray(arguments)));
+ var args = slice.call(arguments);
+ args.unshift(this.models);
+ return _[method].apply(_, args);
};
});
@@ -961,9 +965,12 @@
this.history = options && options.history || root.history;
};
- // Cached regex for cleaning leading hashes and slashes .
+ // Cached regex for cleaning leading hashes and slashes.
var routeStripper = /^[#\/]/;
+ // Cached regex for stripping leading and trailing slashes.
+ var rootStripper = /^\/+|\/+$/g;
+
// Cached regex for detecting MSIE.
var isExplorer = /msie [\w.]+/;
@@ -993,7 +1000,7 @@
if (fragment == null) {
if (this._hasPushState || !this._wantsHashChange || forcePushState) {
fragment = this.location.pathname;
- var root = this.options.root.replace(trailingSlash, '');
+ var root = this.root.replace(trailingSlash, '');
if (!fragment.indexOf(root)) fragment = fragment.substr(root.length);
} else {
fragment = this.getHash();
@@ -1011,6 +1018,7 @@
// Figure out the initial configuration. Do we need an iframe?
// Is pushState desired ... is it available?
this.options = _.extend({}, {root: '/'}, this.options, options);
+ this.root = this.options.root;
this._wantsHashChange = this.options.hashChange !== false;
this._wantsPushState = !!this.options.pushState;
this._hasPushState = !!(this.options.pushState && this.history && this.history.pushState);
@@ -1018,8 +1026,8 @@
var docMode = document.documentMode;
var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7));
- // Normalize root to always include trailing slash
- if (!trailingSlash.test(this.options.root)) this.options.root += '/';
+ // Normalize root to always include a leading and trailing slash.
+ this.root = ('/' + this.root + '/').replace(rootStripper, '/');
if (oldIE && this._wantsHashChange) {
this.iframe = Backbone.$('').hide().appendTo('body')[0].contentWindow;
@@ -1040,13 +1048,13 @@
// opened by a non-pushState browser.
this.fragment = fragment;
var loc = this.location;
- var atRoot = (loc.pathname.replace(/[^/]$/, '$&/') === this.options.root) && !loc.search;
+ var atRoot = (loc.pathname.replace(/[^/]$/, '$&/') === this.root) && !loc.search;
// If we've started off with a route from a `pushState`-enabled browser,
// but we're currently in a browser that doesn't support it...
if (this._wantsHashChange && this._wantsPushState && !this._hasPushState && !atRoot) {
this.fragment = this.getFragment(null, true);
- this.location.replace(this.options.root + this.location.search + '#' + this.fragment);
+ this.location.replace(this.root + this.location.search + '#' + this.fragment);
// Return immediately as browser will do redirect to new url
return true;
@@ -1054,7 +1062,7 @@
// in a browser where it could be `pushState`-based instead...
} else if (this._wantsPushState && this._hasPushState && atRoot && loc.hash) {
this.fragment = this.getHash().replace(routeStripper, '');
- this.history.replaceState({}, document.title, loc.protocol + '//' + loc.host + this.options.root + this.fragment);
+ this.history.replaceState({}, document.title, this.root + this.fragment);
}
if (!this.options.silent) return this.loadUrl();
@@ -1113,7 +1121,7 @@
var frag = (fragment || '').replace(routeStripper, '');
if (this.fragment === frag) return;
this.fragment = frag;
- var url = (frag.indexOf(this.options.root) !== 0 ? this.options.root : '') + frag;
+ var url = (frag.indexOf(this.root) !== 0 ? this.root : '') + frag;
// If pushState is available, we use it to set the fragment as a real URL.
if (this._hasPushState) {
@@ -1434,7 +1442,7 @@
return child;
};
- // Set up inheritance for the model, collection, and view.
+ // Set up inheritance for the model, collection, router, and view.
Model.extend = Collection.extend = Router.extend = View.extend = extend;
// Throw an error when a URL is needed, and none is supplied.
diff --git a/vendor/backbone/test/router.js b/vendor/backbone/test/router.js
index 56d8a10d4..95ebe49bb 100644
--- a/vendor/backbone/test/router.js
+++ b/vendor/backbone/test/router.js
@@ -344,7 +344,7 @@ $(document).ready(function() {
history: {
pushState: function(state, title, url) {},
replaceState: function(state, title, url) {
- strictEqual(url, 'http://example.com/root/fragment');
+ strictEqual(url, '/root/fragment');
}
}
});
@@ -365,4 +365,88 @@ $(document).ready(function() {
});
});
+ test("Normalize root - leading slash.", 1, function() {
+ Backbone.history.stop();
+ location.replace('http://example.com/root');
+ Backbone.history = new Backbone.History({
+ location: location,
+ history: {
+ pushState: function(){},
+ replaceState: function(){}
+ }
+ });
+ Backbone.history.start({root: 'root'});
+ strictEqual(Backbone.history.root, '/root/');
+ });
+
+ test("Transition from hashChange to pushState.", 1, function() {
+ Backbone.history.stop();
+ location.replace('http://example.com/root#x/y');
+ Backbone.history = new Backbone.History({
+ location: location,
+ history: {
+ pushState: function(){},
+ replaceState: function(state, title, url){
+ strictEqual(url, '/root/x/y');
+ }
+ }
+ });
+ Backbone.history.start({
+ root: 'root',
+ pushState: true
+ });
+ });
+
+ test("#1619: Router: Normalize empty root", 1, function() {
+ Backbone.history.stop();
+ location.replace('http://example.com/');
+ Backbone.history = new Backbone.History({
+ location: location,
+ history: {
+ pushState: function(){},
+ replaceState: function(){}
+ }
+ });
+ Backbone.history.start({root: ''});
+ strictEqual(Backbone.history.root, '/');
+ });
+
+ test("#1619: Router: nagivate with empty root", 1, function() {
+ Backbone.history.stop();
+ location.replace('http://example.com/');
+ Backbone.history = new Backbone.History({
+ location: location,
+ history: {
+ pushState: function(state, title, url) {
+ strictEqual(url, '/fragment');
+ }
+ }
+ });
+ Backbone.history.start({
+ pushState: true,
+ root: '',
+ hashChange: false
+ });
+ Backbone.history.navigate('fragment');
+ });
+
+ test("Transition from pushState to hashChange.", 1, function() {
+ Backbone.history.stop();
+ location.replace('http://example.com/root/x/y?a=b');
+ location.replace = function(url) {
+ strictEqual(url, '/root/?a=b#x/y');
+ };
+ Backbone.history = new Backbone.History({
+ location: location,
+ history: {
+ pushState: null,
+ replaceState: null
+ }
+ });
+ Backbone.history.start({
+ root: 'root',
+ pushState: true
+ });
+ });
+
});
diff --git a/vendor/docdown/src/DocDown/Alias.php b/vendor/docdown/src/DocDown/Alias.php
new file mode 100644
index 000000000..1f9521e1b
--- /dev/null
+++ b/vendor/docdown/src/DocDown/Alias.php
@@ -0,0 +1,204 @@
+owner = $owner;
+ $this->_name = $name;
+ $this->_call = $owner->getCall();
+ $this->_desc = $owner->getDesc();
+ $this->_example = $owner->getExample();
+ $this->_lineNumber = $owner->getLineNumber();
+ $this->_members = $owner->getMembers();
+ $this->_params = $owner->getParams();
+ $this->_returns = $owner->getReturns();
+ $this->_type = $owner->getType();
+ $this->_isCtor = $owner->isCtor();
+ $this->_isPlugin = $owner->isPlugin();
+ $this->_isPrivate = $owner->isPrivate();
+ $this->_isStatic = $owner->isStatic();
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * Extracts the entry's `alias` objects.
+ *
+ * @memberOf Alias
+ * @param {Number} $index The index of the array value to return.
+ * @returns {Array|String} The entry's `alias` objects.
+ */
+ public function getAliases( $index = null ) {
+ $result = array();
+ return $index !== null
+ ? @$result[$index]
+ : $result;
+ }
+
+ /**
+ * Extracts the function call from the owner entry.
+ *
+ * @memberOf Alias
+ * @returns {String} The function call.
+ */
+ public function getCall() {
+ return $this->_call;
+ }
+
+ /**
+ * Extracts the owner entry's description.
+ *
+ * @memberOf Alias
+ * @returns {String} The owner entry's description.
+ */
+ public function getDesc() {
+ return $this->_desc;
+ }
+
+ /**
+ * Extracts the owner entry's `example` data.
+ *
+ * @memberOf Alias
+ * @returns {String} The owner entry's `example` data.
+ */
+ public function getExample() {
+ return $this->_example;
+ }
+
+ /**
+ * Resolves the owner entry's line number.
+ *
+ * @memberOf Alias
+ * @returns {Number} The owner entry's line number.
+ */
+ public function getLineNumber() {
+ return $this->_lineNumber;
+ }
+
+ /**
+ * Extracts the owner entry's `member` data.
+ *
+ * @memberOf Alias
+ * @param {Number} $index The index of the array value to return.
+ * @returns {Array|String} The owner entry's `member` data.
+ */
+ public function getMembers( $index = null ) {
+ return $index !== null
+ ? @$this->_members[$index]
+ : $this->_members;
+ }
+
+ /**
+ * Extracts the owner entry's `name` data.
+ *
+ * @memberOf Alias
+ * @returns {String} The owner entry's `name` data.
+ */
+ public function getName() {
+ return $this->_name;
+ }
+
+ /**
+ * Extracts the owner entry's `param` data.
+ *
+ * @memberOf Alias
+ * @param {Number} $index The index of the array value to return.
+ * @returns {Array} The owner entry's `param` data.
+ */
+ public function getParams( $index = null ) {
+ return $index !== null
+ ? @$this->_params[$index]
+ : $this->_params;
+ }
+
+ /**
+ * Extracts the owner entry's `returns` data.
+ *
+ * @memberOf Alias
+ * @returns {String} The owner entry's `returns` data.
+ */
+ public function getReturns() {
+ return $this->_returns;
+ }
+
+ /**
+ * Extracts the owner entry's `type` data.
+ *
+ * @memberOf Alias
+ * @returns {String} The owner entry's `type` data.
+ */
+ public function getType() {
+ return $this->_type;
+ }
+
+ /**
+ * Checks if the entry is an alias.
+ *
+ * @memberOf Alias
+ * @returns {Boolean} Returns `true`.
+ */
+ public function isAlias() {
+ return true;
+ }
+
+ /**
+ * Checks if the owner entry is a constructor.
+ *
+ * @memberOf Alias
+ * @returns {Boolean} Returns `true` if a constructor, else `false`.
+ */
+ public function isCtor() {
+ return $this->_isCtor;
+ }
+
+ /**
+ * Checks if the owner entry *is* assigned to a prototype.
+ *
+ * @memberOf Alias
+ * @returns {Boolean} Returns `true` if assigned to a prototype, else `false`.
+ */
+ public function isPlugin() {
+ return $this->_isPlugin;
+ }
+
+ /**
+ * Checks if the owner entry is private.
+ *
+ * @memberOf Alias
+ * @returns {Boolean} Returns `true` if private, else `false`.
+ */
+ public function isPrivate() {
+ return $this->_isPrivate;
+ }
+
+ /**
+ * Checks if the owner entry is *not* assigned to a prototype.
+ *
+ * @memberOf Alias
+ * @returns {Boolean} Returns `true` if not assigned to a prototype, else `false`.
+ */
+ public function isStatic() {
+ return $this->_isStatic;
+ }
+}
+?>
\ No newline at end of file
diff --git a/vendor/docdown/src/DocDown/Entry.php b/vendor/docdown/src/DocDown/Entry.php
index d312dd16a..6cd78d713 100644
--- a/vendor/docdown/src/DocDown/Entry.php
+++ b/vendor/docdown/src/DocDown/Entry.php
@@ -1,5 +1,7 @@
entry = $entry;
@@ -70,16 +72,45 @@ class Entry {
* @returns {Boolean} Returns `true` if the entry is a function reference, else `false`.
*/
private function isFunction() {
- return !!(
- $this->isCtor() ||
- count($this->getParams()) ||
- count($this->getReturns()) ||
- preg_match('/\*\s*@function\b/', $this->entry)
- );
+ if (!isset($this->_isFunction)) {
+ $this->_isFunction = !!(
+ $this->isCtor() ||
+ count($this->getParams()) ||
+ count($this->getReturns()) ||
+ preg_match('/\*\s*@function\b/', $this->entry)
+ );
+ }
+ return $this->_isFunction;
}
/*--------------------------------------------------------------------------*/
+ /**
+ * Extracts the entry's `alias` objects.
+ *
+ * @memberOf Entry
+ * @param {Number} $index The index of the array value to return.
+ * @returns {Array|String} The entry's `alias` objects.
+ */
+ public function getAliases( $index = null ) {
+ if (!isset($this->_aliases)) {
+ preg_match('#\*\s*@alias\s+([^\n]+)#', $this->entry, $result);
+
+ if (count($result)) {
+ $result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]));
+ $result = preg_split('/,\s*/', $result);
+
+ foreach ($result as $resultIndex => $value) {
+ $result[$resultIndex] = new Alias($value, $this);
+ }
+ }
+ $this->_aliases = $result;
+ }
+ return $index !== null
+ ? @$this->_aliases[$index]
+ : $this->_aliases;
+ }
+
/**
* Extracts the function call from the entry.
*
@@ -87,6 +118,10 @@ class Entry {
* @returns {String} The function call.
*/
public function getCall() {
+ if (isset($this->_call)) {
+ return $this->_call;
+ }
+
preg_match('#\*/\s*(?:function ([^(]*)|(.*?)(?=[:=,]|return\b))#', $this->entry, $result);
if ($result = array_pop($result)) {
$result = array_pop(explode('var ', trim(trim(array_pop(explode('.', $result))), "'")));
@@ -111,176 +146,239 @@ class Entry {
$result = $name .'('. implode(array_slice($result, 1), ', ') .')';
$result = str_replace(', [', ' [, ', str_replace('], [', ', ', $result));
}
- return $result ? $result : $name;
+
+ $this->_call = $result ? $result : $name;
+ return $this->_call;
}
/**
- * Extracts the entry description.
+ * Extracts the entry's description.
*
* @memberOf Entry
- * @returns {String} The entry description.
+ * @returns {String} The entry's description.
*/
public function getDesc() {
+ if (isset($this->_desc)) {
+ return $this->_desc;
+ }
+
preg_match('#/\*\*(?:\s*\*)?([\s\S]*?)(?=\*\s\@[a-z]|\*/)#', $this->entry, $result);
if (count($result)) {
$type = $this->getType();
$result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]));
$result = ($type == 'Function' ? '' : '(' . str_replace('|', ', ', trim($type, '{}')) . '): ') . $result;
}
+ $this->_desc = $result;
return $result;
}
/**
- * Extracts the entry `example` data.
+ * Extracts the entry's `example` data.
*
* @memberOf Entry
- * @returns {String} The entry `example` data.
+ * @returns {String} The entry's `example` data.
*/
public function getExample() {
+ if (isset($this->_example)) {
+ return $this->_example;
+ }
+
preg_match('#\*\s*@example\s+([\s\S]*?)(?=\*\s\@[a-z]|\*/)#', $this->entry, $result);
if (count($result)) {
$result = trim(preg_replace('/(?:^|\n)\s*\* ?/', "\n", $result[1]));
$result = '```' . $this->lang . "\n" . $result . "\n```";
}
+ $this->_example = $result;
return $result;
}
/**
- * Resolves the line number of the entry.
+ * Resolves the entry's line number.
*
* @memberOf Entry
- * @returns {Number} The line number.
+ * @returns {Number} The entry's line number.
*/
public function getLineNumber() {
- preg_match_all('/\n/', substr($this->source, 0, strrpos($this->source, $this->entry) + strlen($this->entry)), $lines);
- return count(array_pop($lines)) + 1;
+ if (!isset($this->_lineNumber)) {
+ preg_match_all('/\n/', substr($this->source, 0, strrpos($this->source, $this->entry) + strlen($this->entry)), $lines);
+ $this->_lineNumber = count(array_pop($lines)) + 1;
+ }
+ return $this->_lineNumber;
}
/**
- * Extracts the entry `member` data.
+ * Extracts the entry's `member` data.
*
* @memberOf Entry
* @param {Number} $index The index of the array value to return.
- * @returns {Array|String} The entry `member` data.
+ * @returns {Array|String} The entry's `member` data.
*/
public function getMembers( $index = null ) {
- preg_match('#\*\s*@member(?:Of)?\s+([^\n]+)#', $this->entry, $result);
- if (count($result)) {
- $result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]));
- $result = preg_split('/,\s*/', $result);
+ if (!isset($this->_members)) {
+ preg_match('#\*\s*@member(?:Of)?\s+([^\n]+)#', $this->entry, $result);
+ if (count($result)) {
+ $result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]));
+ $result = preg_split('/,\s*/', $result);
+ }
+ $this->_members = $result;
}
- return $index !== null ? @$result[$index] : $result;
+ return $index !== null
+ ? @$this->_members[$index]
+ : $this->_members;
}
/**
- * Extracts the entry `name` data.
+ * Extracts the entry's `name` data.
*
* @memberOf Entry
- * @returns {String} The entry `name` data.
+ * @returns {String} The entry's `name` data.
*/
public function getName() {
+ if (isset($this->_name)) {
+ return $this->_name;
+ }
+
preg_match('#\*\s*@name\s+([^\n]+)#', $this->entry, $result);
if (count($result)) {
$result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]));
} else {
$result = array_shift(explode('(', $this->getCall()));
}
+ $this->_name = $result;
return $result;
}
/**
- * Extracts the entry `param` data.
+ * Extracts the entry's `param` data.
*
* @memberOf Entry
* @param {Number} $index The index of the array value to return.
- * @returns {Array} The entry `param` data.
+ * @returns {Array} The entry's `param` data.
*/
public function getParams( $index = null ) {
- preg_match_all('#\*\s*@param\s+\{([^}]+)\}\s+(\[.+\]|[$\w|]+(?:\[.+\])?)\s+([\s\S]*?)(?=\*\s\@[a-z]|\*/)#i', $this->entry, $result);
- if (count($result = array_filter(array_slice($result, 1)))) {
- // repurpose array
- foreach ($result as $param) {
- foreach ($param as $key => $value) {
- if (!is_array($result[0][$key])) {
- $result[0][$key] = array();
+ if (!isset($this->_params)) {
+ preg_match_all('#\*\s*@param\s+\{([^}]+)\}\s+(\[.+\]|[$\w|]+(?:\[.+\])?)\s+([\s\S]*?)(?=\*\s\@[a-z]|\*/)#i', $this->entry, $result);
+ if (count($result = array_filter(array_slice($result, 1)))) {
+ // repurpose array
+ foreach ($result as $param) {
+ foreach ($param as $key => $value) {
+ if (!is_array($result[0][$key])) {
+ $result[0][$key] = array();
+ }
+ $result[0][$key][] = trim(preg_replace('/(?:^|\n)\s*\* */', ' ', $value));
}
- $result[0][$key][] = trim(preg_replace('/(?:^|\n)\s*\* */', ' ', $value));
}
+ $result = $result[0];
}
- $result = $result[0];
+ $this->_params = $result;
}
- return $index !== null ? @$result[$index] : $result;
+ return $index !== null
+ ? @$this->_params[$index]
+ : $this->_params;
}
/**
- * Extracts the entry `returns` data.
+ * Extracts the entry's `returns` data.
*
* @memberOf Entry
- * @returns {String} The entry `returns` data.
+ * @returns {String} The entry's `returns` data.
*/
public function getReturns() {
+ if (isset($this->_returns)) {
+ return $this->_returns;
+ }
+
preg_match('#\*\s*@returns\s+\{([^}]+)\}\s+([\s\S]*?)(?=\*\s\@[a-z]|\*/)#', $this->entry, $result);
if (count($result)) {
$result = array_map('trim', array_slice($result, 1));
$result[0] = str_replace('|', ', ', $result[0]);
$result[1] = preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]);
}
+ $this->_returns = $result;
return $result;
}
/**
- * Extracts the entry `type` data.
+ * Extracts the entry's `type` data.
*
* @memberOf Entry
- * @returns {String} The entry `type` data.
+ * @returns {String} The entry's `type` data.
*/
public function getType() {
+ if (isset($this->_type)) {
+ return $this->_type;
+ }
+
preg_match('#\*\s*@type\s+([^\n]+)#', $this->entry, $result);
if (count($result)) {
$result = trim(preg_replace('/(?:^|\n)\s*\* ?/', ' ', $result[1]));
} else {
$result = $this->isFunction() ? 'Function' : 'Unknown';
}
+ $this->_type = $result;
return $result;
}
/**
- * Checks if an entry is a constructor.
+ * Checks if the entry is an alias.
*
* @memberOf Entry
- * @returns {Boolean} Returns true if a constructor, else false.
+ * @returns {Boolean} Returns `false`.
+ */
+ public function isAlias() {
+ return false;
+ }
+
+ /**
+ * Checks if the entry is a constructor.
+ *
+ * @memberOf Entry
+ * @returns {Boolean} Returns `true` if a constructor, else `false`.
*/
public function isCtor() {
- return !!preg_match('/\*\s*@constructor\b/', $this->entry);
+ if (!isset($this->_isCtor)) {
+ $this->_isCtor = !!preg_match('/\*\s*@constructor\b/', $this->entry);
+ }
+ return $this->_isCtor;
}
/**
- * Checks if an entry *is* assigned to a prototype.
+ * Checks if the entry *is* assigned to a prototype.
*
* @memberOf Entry
- * @returns {Boolean} Returns true if assigned to a prototype, else false.
+ * @returns {Boolean} Returns `true` if assigned to a prototype, else `false`.
*/
public function isPlugin() {
- return !$this->isCtor() && !$this->isPrivate() && !$this->isStatic();
+ if (!isset($this->_isPlugin)) {
+ $this->_isPlugin = !$this->isCtor() && !$this->isPrivate() && !$this->isStatic();
+ }
+ return $this->_isPlugin;
}
/**
- * Checks if an entry is private.
+ * Checks if the entry is private.
*
* @memberOf Entry
- * @returns {Boolean} Returns true if private, else false.
+ * @returns {Boolean} Returns `true` if private, else `false`.
*/
public function isPrivate() {
- return !!preg_match('/\*\s*@private\b/', $this->entry) || strrpos($this->entry, '@') === false;
+ if (!isset($this->_isPrivate)) {
+ $this->_isPrivate = !!preg_match('/\*\s*@private\b/', $this->entry) || strrpos($this->entry, '@') === false;
+ }
+ return $this->_isPrivate;
}
/**
- * Checks if an entry is *not* assigned to a prototype.
+ * Checks if the entry is *not* assigned to a prototype.
*
* @memberOf Entry
- * @returns {Boolean} Returns true if not assigned to a prototype, else false.
+ * @returns {Boolean} Returns `true` if not assigned to a prototype, else `false`.
*/
public function isStatic() {
+ if (isset($this->_isStatic)) {
+ return $this->_isStatic;
+ }
+
$public = !$this->isPrivate();
$result = $public && !!preg_match('/\*\s*@static\b/', $this->entry);
@@ -298,6 +396,7 @@ class Entry {
$result = true;
}
}
+ $this->_isStatic = $result;
return $result;
}
}
diff --git a/vendor/docdown/src/DocDown/Generator.php b/vendor/docdown/src/DocDown/Generator.php
index ebf4aa18d..fd28478f8 100644
--- a/vendor/docdown/src/DocDown/Generator.php
+++ b/vendor/docdown/src/DocDown/Generator.php
@@ -221,22 +221,39 @@ class Generator {
foreach ($members as $member) {
// create api category arrays
if (!isset($api[$member]) && $member) {
+ // create temporary entry to be replaced later
$api[$member] = new Entry('', '', $entry->lang);
$api[$member]->static = array();
$api[$member]->plugin = array();
}
+
// append entry to api category
if (!$member || $entry->isCtor() || ($entry->getType() == 'Object' &&
!preg_match('/[=:]\s*null\s*[,;]?$/', $entry->entry))) {
+
+ // assign the real entry, replacing the temporary entry if it exist
$member = ($member ? $member . ($entry->isPlugin() ? '#' : '.') : '') . $name;
$entry->static = @$api[$member] ? $api[$member]->static : array();
$entry->plugin = @$api[$member] ? $api[$member]->plugin : array();
- $api[$member] = $entry;
+
+ $api[$member] = $entry;
+ foreach ($entry->getAliases() as $alias) {
+ $api[$member] = $alias;
+ $alias->static = array();
+ $alias->plugin = array();
+ }
}
else if ($entry->isStatic()) {
$api[$member]->static[] = $entry;
- } else if (!$entry->isCtor()) {
+ foreach ($entry->getAliases() as $alias) {
+ $api[$member]->static[] = $alias;
+ }
+ }
+ else if (!$entry->isCtor()) {
$api[$member]->plugin[] = $entry;
+ foreach ($entry->getAliases() as $alias) {
+ $api[$member]->plugin[] = $alias;
+ }
}
}
}
@@ -346,6 +363,11 @@ class Generator {
$result[] = $openTag;
foreach ($api as $entry) {
+ // skip aliases
+ if ($entry->isAlias()) {
+ continue;
+ }
+
// add root entry
$member = $entry->member . $entry->getName();
$compiling = $compiling ? ($result[] = $closeTag) : true;
@@ -370,6 +392,11 @@ class Generator {
// body
foreach ($subentries as $subentry) {
+ // skip aliases
+ if ($subentry->isAlias()) {
+ continue;
+ }
+
// description
array_push(
$result,
@@ -377,6 +404,14 @@ class Generator {
Generator::interpolate("### `#{member}#{separator}#{call}`\n# [Ⓢ](#{href} \"View in source\") [Ⓣ][1]\n\n#{desc}", $subentry)
);
+ // @alias
+ if (count($aliases = $subentry->getAliases())) {
+ array_push($result, '', '#### Aliases');
+ foreach ($aliases as $index => $alias) {
+ $aliases[$index] = $alias->getName();
+ }
+ $result[] = implode(', ', $aliases);
+ }
// @param
if (count($params = $subentry->getParams())) {
array_push($result, '', '#### Arguments');
diff --git a/vendor/qunit/README.md b/vendor/qunit/README.md
index 3778a27b4..57ff29e1f 100644
--- a/vendor/qunit/README.md
+++ b/vendor/qunit/README.md
@@ -1,4 +1,4 @@
-[QUnit](http://docs.jquery.com/QUnit) - A JavaScript Unit Testing framework.
+[QUnit](http://qunitjs.com) - A JavaScript Unit Testing framework.
================================
QUnit is a powerful, easy-to-use, JavaScript test suite. It's used by the jQuery
@@ -35,7 +35,8 @@ the change, run `grunt` to lint and test it, then commit, push and create a pull
Include some background for the change in the commit message and `Fixes #nnn`, referring
to the issue number you're addressing.
-To run `grunt`, you need `node` and `npm`, then `npm install grunt -g`.
+To run `grunt`, you need `node` and `npm`, then `npm install grunt -g`. That gives you a global
+grunt binary. For additional grunt tasks, also run `npm install`.
Releases
--------
@@ -47,3 +48,12 @@ tag, update them again to the next version, commit and push commits and tags
Put the 'v' in front of the tag, e.g. `v1.8.0`. Clean up the changelog, removing merge commits
or whitespace cleanups.
+
+To upload to code.jquery.com (replace $version accordingly):
+
+ scp -q qunit/qunit.js jqadmin@code.origin.jquery.com:/var/www/html/code.jquery.com/qunit/qunit-$version.js
+ scp -q qunit/qunit.css jqadmin@code.origin.jquery.com:/var/www/html/code.jquery.com/qunit/qunit-$version.css
+
+Then update /var/www/html/code.jquery.com/index.html and purge it with:
+
+ curl -s http://code.origin.jquery.com/?reload
\ No newline at end of file
diff --git a/vendor/qunit/qunit/qunit.css b/vendor/qunit/qunit/qunit.css
index 257b224ff..55970e006 100644
--- a/vendor/qunit/qunit/qunit.css
+++ b/vendor/qunit/qunit/qunit.css
@@ -1,11 +1,11 @@
/**
- * QUnit v1.9.0 - A JavaScript Unit Testing Framework
+ * QUnit v1.10.0 - A JavaScript Unit Testing Framework
*
- * http://docs.jquery.com/QUnit
+ * http://qunitjs.com
*
- * Copyright (c) 2012 John Resig, Jörn Zaefferer
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * or GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
*/
/** Font Family and Sizes */
@@ -20,7 +20,7 @@
/** Resets */
-#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
+#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
margin: 0;
padding: 0;
}
@@ -67,6 +67,7 @@
padding: 0.5em 0 0.5em 2em;
color: #5E740B;
background-color: #eee;
+ overflow: hidden;
}
#qunit-userAgent {
@@ -76,6 +77,9 @@
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
}
+#qunit-modulefilter-container {
+ float: right;
+}
/** Tests: Pass/Fail */
diff --git a/vendor/qunit/qunit/qunit.js b/vendor/qunit/qunit/qunit.js
index 9efedcb44..d4f17b5ae 100644
--- a/vendor/qunit/qunit/qunit.js
+++ b/vendor/qunit/qunit/qunit.js
@@ -1,11 +1,11 @@
/**
- * QUnit v1.9.0 - A JavaScript Unit Testing Framework
+ * QUnit v1.10.0 - A JavaScript Unit Testing Framework
*
- * http://docs.jquery.com/QUnit
+ * http://qunitjs.com
*
- * Copyright (c) 2012 John Resig, Jörn Zaefferer
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * or GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
*/
(function( window ) {
@@ -17,6 +17,8 @@ var QUnit,
fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""),
toString = Object.prototype.toString,
hasOwn = Object.prototype.hasOwnProperty,
+ // Keep a local reference to Date (GH-283)
+ Date = window.Date,
defined = {
setTimeout: typeof window.setTimeout !== "undefined",
sessionStorage: (function() {
@@ -304,7 +306,8 @@ QUnit = {
// call on start of module test to prepend name to all tests
module: function( name, testEnvironment ) {
config.currentModule = name;
- config.currentModuleTestEnviroment = testEnvironment;
+ config.currentModuleTestEnvironment = testEnvironment;
+ config.modules[name] = true;
},
asyncTest: function( testName, expected, callback ) {
@@ -336,7 +339,7 @@ QUnit = {
async: async,
callback: callback,
module: config.currentModule,
- moduleTestEnvironment: config.currentModuleTestEnviroment,
+ moduleTestEnvironment: config.currentModuleTestEnvironment,
stack: sourceFromStacktrace( 2 )
});
@@ -349,7 +352,11 @@ QUnit = {
// Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
expect: function( asserts ) {
- config.current.expected = asserts;
+ if (arguments.length === 1) {
+ config.current.expected = asserts;
+ } else {
+ return config.current.expected;
+ }
},
start: function( count ) {
@@ -415,6 +422,8 @@ QUnit.assert = {
var source,
details = {
+ module: config.current.module,
+ name: config.current.testName,
result: result,
message: msg
};
@@ -600,6 +609,9 @@ config = {
}
],
+ // Set of all modules.
+ modules: {},
+
// logging callback queues
begin: [],
done: [],
@@ -710,17 +722,10 @@ extend( QUnit, {
},
// Resets the test setup. Useful for tests that modify the DOM.
- // If jQuery is available, uses jQuery's html(), otherwise just innerHTML.
reset: function() {
- var fixture;
-
- if ( window.jQuery ) {
- jQuery( "#qunit-fixture" ).html( config.fixture );
- } else {
- fixture = id( "qunit-fixture" );
- if ( fixture ) {
- fixture.innerHTML = config.fixture;
- }
+ var fixture = id( "qunit-fixture" );
+ if ( fixture ) {
+ fixture.innerHTML = config.fixture;
}
},
@@ -781,6 +786,8 @@ extend( QUnit, {
var output, source,
details = {
+ module: config.current.module,
+ name: config.current.testName,
result: result,
message: message,
actual: actual,
@@ -826,6 +833,8 @@ extend( QUnit, {
var output,
details = {
+ module: config.current.module,
+ name: config.current.testName,
result: false,
message: message
};
@@ -916,7 +925,9 @@ QUnit.load = function() {
runLoggingCallbacks( "begin", QUnit, {} );
// Initialize the config, saving the execution queue
- var banner, filter, i, label, len, main, ol, toolbar, userAgent, val, urlConfigCheckboxes,
+ var banner, filter, i, label, len, main, ol, toolbar, userAgent, val, urlConfigCheckboxes, moduleFilter,
+ numModules = 0,
+ moduleFilterHtml = "",
urlConfigHtml = "",
oldconfig = extend( {}, config );
@@ -940,6 +951,15 @@ QUnit.load = function() {
urlConfigHtml += "";
}
+ moduleFilterHtml += "";
+
// `userAgent` initialized at top of scope
userAgent = id( "qunit-userAgent" );
if ( userAgent ) {
@@ -1002,6 +1022,19 @@ QUnit.load = function() {
window.location = QUnit.url( params );
});
toolbar.appendChild( urlConfigCheckboxes );
+
+ if (numModules > 1) {
+ moduleFilter = document.createElement( 'span' );
+ moduleFilter.setAttribute( 'id', 'qunit-modulefilter-container' );
+ moduleFilter.innerHTML = moduleFilterHtml;
+ addEvent( moduleFilter, "change", function() {
+ var selectBox = moduleFilter.getElementsByTagName("select")[0],
+ selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
+
+ window.location = QUnit.url( { module: ( selectedModule === "" ) ? undefined : selectedModule } );
+ });
+ toolbar.appendChild(moduleFilter);
+ }
}
// `main` initialized at top of scope
@@ -1039,9 +1072,9 @@ window.onerror = function ( error, filePath, linerNr ) {
}
QUnit.pushFailure( error, filePath + ":" + linerNr );
} else {
- QUnit.test( "global failure", function() {
+ QUnit.test( "global failure", extend( function() {
QUnit.pushFailure( error, filePath + ":" + linerNr );
- });
+ }, { validTest: validTest } ) );
}
return false;
}
@@ -1108,6 +1141,11 @@ function done() {
}
}
+ // scroll back to top to show results
+ if ( window.scrollTo ) {
+ window.scrollTo(0, 0);
+ }
+
runLoggingCallbacks( "done", QUnit, {
failed: config.stats.bad,
passed: passed,
@@ -1123,6 +1161,12 @@ function validTest( test ) {
module = config.module && config.module.toLowerCase(),
fullName = (test.module + ": " + test.testName).toLowerCase();
+ // Internally-generated tests are always valid
+ if ( test.callback && test.callback.validTest === validTest ) {
+ delete test.callback.validTest;
+ return true;
+ }
+
if ( config.testNumber ) {
return test.testNumber === config.testNumber;
}
@@ -1404,7 +1448,8 @@ QUnit.equiv = (function() {
a.global === b.global &&
// (gmi) ...
a.ignoreCase === b.ignoreCase &&
- a.multiline === b.multiline;
+ a.multiline === b.multiline &&
+ a.sticky === b.sticky;
},
// - skip when the property is a method of an instance (OOP)
diff --git a/vendor/underscore/test/utility.js b/vendor/underscore/test/utility.js
index c8ebc889b..f1a3a7d91 100644
--- a/vendor/underscore/test/utility.js
+++ b/vendor/underscore/test/utility.js
@@ -14,6 +14,12 @@ $(document).ready(function() {
});
+ test("#750 - Return _ instance.", 2, function() {
+ var instance = _([]);
+ ok(_(instance) === instance);
+ ok(new _(instance) === instance);
+ });
+
test("utility: identity", function() {
var moe = {name : 'moe'};
equal(_.identity(moe), moe, 'moe is the same as his identity');
@@ -229,4 +235,10 @@ $(document).ready(function() {
templateEscaped({f: function(){ ok(!(countEscaped++)); }});
});
+ test('#746 - _.template settings are not modified.', 1, function() {
+ var settings = {};
+ _.template('', null, settings);
+ deepEqual(settings, {});
+ });
+
});
diff --git a/vendor/underscore/test/vendor/qunit.css b/vendor/underscore/test/vendor/qunit.css
index 5684a4485..55970e006 100644
--- a/vendor/underscore/test/vendor/qunit.css
+++ b/vendor/underscore/test/vendor/qunit.css
@@ -1,11 +1,11 @@
/**
- * QUnit v1.8.0 - A JavaScript Unit Testing Framework
+ * QUnit v1.10.0 - A JavaScript Unit Testing Framework
*
- * http://docs.jquery.com/QUnit
+ * http://qunitjs.com
*
- * Copyright (c) 2012 John Resig, Jörn Zaefferer
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * or GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
*/
/** Font Family and Sizes */
@@ -20,7 +20,7 @@
/** Resets */
-#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
+#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
margin: 0;
padding: 0;
}
@@ -38,10 +38,10 @@
line-height: 1em;
font-weight: normal;
- border-radius: 15px 15px 0 0;
- -moz-border-radius: 15px 15px 0 0;
- -webkit-border-top-right-radius: 15px;
- -webkit-border-top-left-radius: 15px;
+ border-radius: 5px 5px 0 0;
+ -moz-border-radius: 5px 5px 0 0;
+ -webkit-border-top-right-radius: 5px;
+ -webkit-border-top-left-radius: 5px;
}
#qunit-header a {
@@ -54,9 +54,9 @@
color: #fff;
}
-#qunit-header label {
+#qunit-testrunner-toolbar label {
display: inline-block;
- padding-left: 0.5em;
+ padding: 0 .5em 0 .1em;
}
#qunit-banner {
@@ -67,6 +67,7 @@
padding: 0.5em 0 0.5em 2em;
color: #5E740B;
background-color: #eee;
+ overflow: hidden;
}
#qunit-userAgent {
@@ -76,6 +77,9 @@
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
}
+#qunit-modulefilter-container {
+ float: right;
+}
/** Tests: Pass/Fail */
@@ -113,13 +117,9 @@
background-color: #fff;
- border-radius: 15px;
- -moz-border-radius: 15px;
- -webkit-border-radius: 15px;
-
- box-shadow: inset 0px 2px 13px #999;
- -moz-box-shadow: inset 0px 2px 13px #999;
- -webkit-box-shadow: inset 0px 2px 13px #999;
+ border-radius: 5px;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
}
#qunit-tests table {
@@ -162,8 +162,7 @@
#qunit-tests b.failed { color: #710909; }
#qunit-tests li li {
- margin: 0.5em;
- padding: 0.4em 0.5em 0.4em 0.5em;
+ padding: 5px;
background-color: #fff;
border-bottom: none;
list-style-position: inside;
@@ -172,9 +171,9 @@
/*** Passing Styles */
#qunit-tests li li.pass {
- color: #5E740B;
+ color: #3c510c;
background-color: #fff;
- border-left: 26px solid #C6E746;
+ border-left: 10px solid #C6E746;
}
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
@@ -190,15 +189,15 @@
#qunit-tests li li.fail {
color: #710909;
background-color: #fff;
- border-left: 26px solid #EE5757;
+ border-left: 10px solid #EE5757;
white-space: pre;
}
#qunit-tests > li:last-child {
- border-radius: 0 0 15px 15px;
- -moz-border-radius: 0 0 15px 15px;
- -webkit-border-bottom-right-radius: 15px;
- -webkit-border-bottom-left-radius: 15px;
+ border-radius: 0 0 5px 5px;
+ -moz-border-radius: 0 0 5px 5px;
+ -webkit-border-bottom-right-radius: 5px;
+ -webkit-border-bottom-left-radius: 5px;
}
#qunit-tests .fail { color: #000000; background-color: #EE5757; }
diff --git a/vendor/underscore/test/vendor/qunit.js b/vendor/underscore/test/vendor/qunit.js
index c1570c252..d4f17b5ae 100644
--- a/vendor/underscore/test/vendor/qunit.js
+++ b/vendor/underscore/test/vendor/qunit.js
@@ -1,11 +1,11 @@
/**
- * QUnit v1.8.0 - A JavaScript Unit Testing Framework
+ * QUnit v1.10.0 - A JavaScript Unit Testing Framework
*
- * http://docs.jquery.com/QUnit
+ * http://qunitjs.com
*
- * Copyright (c) 2012 John Resig, Jörn Zaefferer
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * or GPL (GPL-LICENSE.txt) licenses.
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license.
+ * http://jquery.org/license
*/
(function( window ) {
@@ -17,6 +17,8 @@ var QUnit,
fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""),
toString = Object.prototype.toString,
hasOwn = Object.prototype.hasOwnProperty,
+ // Keep a local reference to Date (GH-283)
+ Date = window.Date,
defined = {
setTimeout: typeof window.setTimeout !== "undefined",
sessionStorage: (function() {
@@ -304,7 +306,8 @@ QUnit = {
// call on start of module test to prepend name to all tests
module: function( name, testEnvironment ) {
config.currentModule = name;
- config.currentModuleTestEnviroment = testEnvironment;
+ config.currentModuleTestEnvironment = testEnvironment;
+ config.modules[name] = true;
},
asyncTest: function( testName, expected, callback ) {
@@ -336,7 +339,7 @@ QUnit = {
async: async,
callback: callback,
module: config.currentModule,
- moduleTestEnvironment: config.currentModuleTestEnviroment,
+ moduleTestEnvironment: config.currentModuleTestEnvironment,
stack: sourceFromStacktrace( 2 )
});
@@ -349,7 +352,11 @@ QUnit = {
// Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
expect: function( asserts ) {
- config.current.expected = asserts;
+ if (arguments.length === 1) {
+ config.current.expected = asserts;
+ } else {
+ return config.current.expected;
+ }
},
start: function( count ) {
@@ -403,6 +410,8 @@ QUnit = {
QUnit.assert = {
/**
* Asserts rough true-ish result.
+ * @name ok
+ * @function
* @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
*/
ok: function( result, msg ) {
@@ -413,6 +422,8 @@ QUnit.assert = {
var source,
details = {
+ module: config.current.module,
+ name: config.current.testName,
result: result,
message: msg
};
@@ -437,36 +448,59 @@ QUnit.assert = {
/**
* Assert that the first two arguments are equal, with an optional message.
* Prints out both actual and expected values.
+ * @name equal
+ * @function
* @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" );
*/
equal: function( actual, expected, message ) {
QUnit.push( expected == actual, actual, expected, message );
},
+ /**
+ * @name notEqual
+ * @function
+ */
notEqual: function( actual, expected, message ) {
QUnit.push( expected != actual, actual, expected, message );
},
+ /**
+ * @name deepEqual
+ * @function
+ */
deepEqual: function( actual, expected, message ) {
QUnit.push( QUnit.equiv(actual, expected), actual, expected, message );
},
+ /**
+ * @name notDeepEqual
+ * @function
+ */
notDeepEqual: function( actual, expected, message ) {
QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message );
},
+ /**
+ * @name strictEqual
+ * @function
+ */
strictEqual: function( actual, expected, message ) {
QUnit.push( expected === actual, actual, expected, message );
},
+ /**
+ * @name notStrictEqual
+ * @function
+ */
notStrictEqual: function( actual, expected, message ) {
QUnit.push( expected !== actual, actual, expected, message );
},
- raises: function( block, expected, message ) {
+ throws: function( block, expected, message ) {
var actual,
ok = false;
+ // 'expected' is optional
if ( typeof expected === "string" ) {
message = expected;
expected = null;
@@ -494,18 +528,29 @@ QUnit.assert = {
} else if ( expected.call( {}, actual ) === true ) {
ok = true;
}
- }
- QUnit.push( ok, actual, null, message );
+ QUnit.push( ok, actual, null, message );
+ } else {
+ QUnit.pushFailure( message, null, 'No exception was thrown.' );
+ }
}
};
-// @deprecated: Kept assertion helpers in root for backwards compatibility
+/**
+ * @deprecate since 1.8.0
+ * Kept assertion helpers in root for backwards compatibility
+ */
extend( QUnit, QUnit.assert );
/**
- * @deprecated: Kept for backwards compatibility
- * next step: remove entirely
+ * @deprecated since 1.9.0
+ * Kept global "raises()" for backwards compatibility
+ */
+QUnit.raises = QUnit.assert.throws;
+
+/**
+ * @deprecated since 1.0.0, replaced with error pushes since 1.3.0
+ * Kept to avoid TypeErrors for undefined methods.
*/
QUnit.equals = function() {
QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" );
@@ -549,7 +594,23 @@ config = {
// when enabled, all tests must call expect()
requireExpects: false,
- urlConfig: [ "noglobals", "notrycatch" ],
+ // add checkboxes that are persisted in the query-string
+ // when enabled, the id is set to `true` as a `QUnit.config` property
+ urlConfig: [
+ {
+ id: "noglobals",
+ label: "Check for Globals",
+ tooltip: "Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings."
+ },
+ {
+ id: "notrycatch",
+ label: "No try-catch",
+ tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings."
+ }
+ ],
+
+ // Set of all modules.
+ modules: {},
// logging callback queues
begin: [],
@@ -661,17 +722,10 @@ extend( QUnit, {
},
// Resets the test setup. Useful for tests that modify the DOM.
- // If jQuery is available, uses jQuery's html(), otherwise just innerHTML.
reset: function() {
- var fixture;
-
- if ( window.jQuery ) {
- jQuery( "#qunit-fixture" ).html( config.fixture );
- } else {
- fixture = id( "qunit-fixture" );
- if ( fixture ) {
- fixture.innerHTML = config.fixture;
- }
+ var fixture = id( "qunit-fixture" );
+ if ( fixture ) {
+ fixture.innerHTML = config.fixture;
}
},
@@ -732,6 +786,8 @@ extend( QUnit, {
var output, source,
details = {
+ module: config.current.module,
+ name: config.current.testName,
result: result,
message: message,
actual: actual,
@@ -770,26 +826,36 @@ extend( QUnit, {
});
},
- pushFailure: function( message, source ) {
+ pushFailure: function( message, source, actual ) {
if ( !config.current ) {
throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) );
}
var output,
details = {
+ module: config.current.module,
+ name: config.current.testName,
result: false,
message: message
};
- message = escapeInnerText(message ) || "error";
+ message = escapeInnerText( message ) || "error";
message = "" + message + "";
output = message;
+ output += "
";
+
+ if ( actual ) {
+ output += "| Result: | " + escapeInnerText( actual ) + " |
";
+ }
+
if ( source ) {
details.source = source;
- output += "| Source: | " + escapeInnerText( source ) + " |
|---|
";
+ output += "| Source: | " + escapeInnerText( source ) + " |
";
}
+ output += "
";
+
runLoggingCallbacks( "log", QUnit, details );
config.current.assertions.push({
@@ -859,7 +925,9 @@ QUnit.load = function() {
runLoggingCallbacks( "begin", QUnit, {} );
// Initialize the config, saving the execution queue
- var banner, filter, i, label, len, main, ol, toolbar, userAgent, val,
+ var banner, filter, i, label, len, main, ol, toolbar, userAgent, val, urlConfigCheckboxes, moduleFilter,
+ numModules = 0,
+ moduleFilterHtml = "",
urlConfigHtml = "",
oldconfig = extend( {}, config );
@@ -872,10 +940,26 @@ QUnit.load = function() {
for ( i = 0; i < len; i++ ) {
val = config.urlConfig[i];
- config[val] = QUnit.urlParams[val];
- urlConfigHtml += "";
+ if ( typeof val === "string" ) {
+ val = {
+ id: val,
+ label: val,
+ tooltip: "[no tooltip available]"
+ };
+ }
+ config[ val.id ] = QUnit.urlParams[ val.id ];
+ urlConfigHtml += "";
}
+ moduleFilterHtml += "";
+
// `userAgent` initialized at top of scope
userAgent = id( "qunit-userAgent" );
if ( userAgent ) {
@@ -885,12 +969,7 @@ QUnit.load = function() {
// `banner` initialized at top of scope
banner = id( "qunit-header" );
if ( banner ) {
- banner.innerHTML = "" + banner.innerHTML + " " + urlConfigHtml;
- addEvent( banner, "change", function( event ) {
- var params = {};
- params[ event.target.name ] = event.target.checked ? true : undefined;
- window.location = QUnit.url( params );
- });
+ banner.innerHTML = "" + banner.innerHTML + " ";
}
// `toolbar` initialized at top of scope
@@ -931,8 +1010,31 @@ QUnit.load = function() {
// `label` initialized at top of scope
label = document.createElement( "label" );
label.setAttribute( "for", "qunit-filter-pass" );
+ label.setAttribute( "title", "Only show tests and assertons that fail. Stored in sessionStorage." );
label.innerHTML = "Hide passed tests";
toolbar.appendChild( label );
+
+ urlConfigCheckboxes = document.createElement( 'span' );
+ urlConfigCheckboxes.innerHTML = urlConfigHtml;
+ addEvent( urlConfigCheckboxes, "change", function( event ) {
+ var params = {};
+ params[ event.target.name ] = event.target.checked ? true : undefined;
+ window.location = QUnit.url( params );
+ });
+ toolbar.appendChild( urlConfigCheckboxes );
+
+ if (numModules > 1) {
+ moduleFilter = document.createElement( 'span' );
+ moduleFilter.setAttribute( 'id', 'qunit-modulefilter-container' );
+ moduleFilter.innerHTML = moduleFilterHtml;
+ addEvent( moduleFilter, "change", function() {
+ var selectBox = moduleFilter.getElementsByTagName("select")[0],
+ selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
+
+ window.location = QUnit.url( { module: ( selectedModule === "" ) ? undefined : selectedModule } );
+ });
+ toolbar.appendChild(moduleFilter);
+ }
}
// `main` initialized at top of scope
@@ -970,9 +1072,9 @@ window.onerror = function ( error, filePath, linerNr ) {
}
QUnit.pushFailure( error, filePath + ":" + linerNr );
} else {
- QUnit.test( "global failure", function() {
+ QUnit.test( "global failure", extend( function() {
QUnit.pushFailure( error, filePath + ":" + linerNr );
- });
+ }, { validTest: validTest } ) );
}
return false;
}
@@ -1039,6 +1141,11 @@ function done() {
}
}
+ // scroll back to top to show results
+ if ( window.scrollTo ) {
+ window.scrollTo(0, 0);
+ }
+
runLoggingCallbacks( "done", QUnit, {
failed: config.stats.bad,
passed: passed,
@@ -1051,14 +1158,20 @@ function done() {
function validTest( test ) {
var include,
filter = config.filter && config.filter.toLowerCase(),
- module = config.module,
+ module = config.module && config.module.toLowerCase(),
fullName = (test.module + ": " + test.testName).toLowerCase();
+ // Internally-generated tests are always valid
+ if ( test.callback && test.callback.validTest === validTest ) {
+ delete test.callback.validTest;
+ return true;
+ }
+
if ( config.testNumber ) {
return test.testNumber === config.testNumber;
}
- if ( module && test.module !== module ) {
+ if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) {
return false;
}
@@ -1335,7 +1448,8 @@ QUnit.equiv = (function() {
a.global === b.global &&
// (gmi) ...
a.ignoreCase === b.ignoreCase &&
- a.multiline === b.multiline;
+ a.multiline === b.multiline &&
+ a.sticky === b.sticky;
},
// - skip when the property is a method of an instance (OOP)
diff --git a/vendor/underscore/underscore-min.js b/vendor/underscore/underscore-min.js
index 15530c637..29232ee4c 100644
--- a/vendor/underscore/underscore-min.js
+++ b/vendor/underscore/underscore-min.js
@@ -5,29 +5,29 @@
// Oliver Steele's Functional, and John Resig's Micro-Templating.
// For all details and documentation:
// http://documentcloud.github.com/underscore
-(function(){var t=this,M=t._,p={},k=Array.prototype,q=Object.prototype,N=k.push,h=k.slice,O=k.unshift,m=q.toString,P=q.hasOwnProperty,A=k.forEach,B=k.map,C=k.reduce,D=k.reduceRight,E=k.filter,F=k.every,G=k.some,r=k.indexOf,H=k.lastIndexOf,q=Array.isArray,Q=Object.keys,u=Function.prototype.bind,b=function(a){return new l(a)};"undefined"!==typeof exports?("undefined"!==typeof module&&module.exports&&(exports=module.exports=b),exports._=b):t._=b;b.VERSION="1.3.3";var j=b.each=b.forEach=function(a,c,
-d){if(a!=null)if(A&&a.forEach===A)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e2;a==null&&(a=[]);if(C&&a.reduce===C){e&&(c=b.bind(c,e));return f?a.reduce(c,
-d):a.reduce(c)}j(a,function(a,b,h){if(f)d=c.call(e,d,a,b,h);else{d=a;f=true}});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(D&&a.reduceRight===D){e&&(c=b.bind(c,e));return f?a.reduceRight(c,d):a.reduceRight(c)}var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=function(a,c,b){var e;I(a,function(a,g,i){if(c.call(b,a,g,i)){e=
-a;return true}});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(E&&a.filter===E)return a.filter(c,b);j(a,function(a,g,i){c.call(b,a,g,i)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,i){c.call(b,a,g,i)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,d){c||(c=b.identity);var e=true;if(a==null)return e;if(F&&a.every===F)return a.every(c,d);j(a,function(a,b,i){if(!(e=e&&c.call(d,a,b,i)))return p});return!!e};var I=
-b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(G&&a.some===G)return a.some(c,d);j(a,function(a,b,i){if(e||(e=c.call(d,a,b,i)))return p});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;if(r&&a.indexOf===r)return a.indexOf(c)!=-1;return b=I(a,function(a){return a===c})};b.invoke=function(a,c){var d=h.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c:a[c]).apply(a,d)})};b.pluck=function(a,c){return b.map(a,function(a){return a[c]})};
-b.max=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0]&&a.length<65535)return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,i){b=c?c.call(d,a,b,i):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0]&&a.length<65535)return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,i){b=c?c.call(d,a,b,i):a;bd?1:0}),"value")};var J=function(a,c){return b.isFunction(c)?c:function(a){return a[c]}},K=function(a,c,b){var e={},f=J(a,c);j(a,function(a,c){var h=f(a,c);b(e,
-h,a)});return e};b.groupBy=function(a,c){return K(a,c,function(a,c,b){(a[c]||(a[c]=[])).push(b)})};b.countBy=function(a,c){return K(a,c,function(a,c){a[c]||(a[c]=0);a[c]++})};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var c=d(c),e=0,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a){var c=s(h.call(arguments,
-1),true,[]);return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=h.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=Q||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=
-[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.pairs=function(a){return b.map(a,function(a,b){return[b,a]})};b.invert=function(a){return b.reduce(a,function(a,b,e){a[b]=e;return a},{})};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(h.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.pick=function(a){var c={},d=b.flatten(h.call(arguments,1));j(d,
-function(b){b in a&&(c[b]=a[b])});return c};b.omit=function(a){var c={},d=b.flatten(h.call(arguments,1)),e;for(e in a)b.include(d,e)||(c[e]=a[e]);return c};b.defaults=function(a){j(h.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};var v=function(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=
-c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=m.call(a);if(e!=m.call(c))return false;switch(e){case "[object String]":return a==""+c;case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;
-for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){f=a.length;if(g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&v(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var i in a)if(b.has(a,i)){f++;if(!(g=b.has(c,i)&&v(a[i],c[i],d)))break}if(g){for(i in c)if(b.has(c,i)&&!f--)break;g=!f}}d.pop();return g};b.isEqual=function(a,b){return v(a,b,[])};b.isEmpty=function(a){if(a==null)return true;if(b.isArray(a)||
-b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=q||function(a){return m.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};j("Arguments,Function,String,Number,Date,RegExp".split(","),function(a){b["is"+a]=function(b){return m.call(b)=="[object "+a+"]"}});b.isArguments(arguments)||(b.isArguments=function(a){return!(!a||!b.has(a,"callee"))});b.isFinite=function(a){return b.isNumber(a)&&
-isFinite(a)};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||m.call(a)=="[object Boolean]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return P.call(a,b)};b.noConflict=function(){t._=M;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e":">",'"':""",
-"'":"'","/":"/"}};n.unescape=b.invert(n.escape);var R={escape:RegExp("["+b.keys(n.escape).join("")+"]","g"),unescape:RegExp("("+b.keys(n.unescape).join("|")+")","g")};b.each(["escape","unescape"],function(a){b[a]=function(b){return b==null?"":(""+b).replace(R[a],function(b){return n[a][b]})}});b.result=function(a,c){if(a==null)return null;var d=a[c];return b.isFunction(d)?d.call(a):d};b.mixin=function(a){j(b.functions(a),function(c){S(c,b[c]=a[c])})};var T=0;b.uniqueId=function(a){var b=
-T++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var w=/.^/,o={"\\":"\\","'":"'",r:"\r",n:"\n",t:"\t",u2028:"\u2028",u2029:"\u2029"},x;for(x in o)o[o[x]]=x;var U=/\\|'|\r|\n|\t|\u2028|\u2029/g,V=/\\(\\|'|r|n|t|u2028|u2029)/g,y=function(a){return a.replace(V,function(a,b){return o[b]})};b.template=function(a,c,d){d=b.defaults(d||{},b.templateSettings);a="__p+='"+a.replace(U,function(a){return"\\"+o[a]}).replace(d.escape||w,
-function(a,b){return"'+\n((__t=("+y(b)+"))==null?'':_.escape(__t))+\n'"}).replace(d.interpolate||w,function(a,b){return"'+\n((__t=("+y(b)+"))==null?'':__t)+\n'"}).replace(d.evaluate||w,function(a,b){return"';\n"+y(b)+"\n__p+='"})+"';\n";d.variable||(a="with(obj||{}){\n"+a+"}\n");a="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{var e=new Function(d.variable||"obj","_",a)}catch(f){f.source=a;throw f;}if(c)return e(c,b);c=function(a){return e.call(this,
-a,b)};c.source="function("+(d.variable||"obj")+"){\n"+a+"}";return c};b.chain=function(a){return b(a).chain()};var l=function(a){this._wrapped=a};b.prototype=l.prototype;var z=function(a,c){return c?b(a).chain():a},S=function(a,c){l.prototype[a]=function(){var a=h.call(arguments);O.call(a,this._wrapped);return z(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];l.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);
-(a=="shift"||a=="splice")&&d.length===0&&delete d[0];return z(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];l.prototype[a]=function(){return z(b.apply(this._wrapped,arguments),this._chain)}});l.prototype.chain=function(){this._chain=true;return this};l.prototype.value=function(){return this._wrapped}}).call(this);
+(function(){var s=this,K=s._,o={},k=Array.prototype,p=Object.prototype,L=k.push,h=k.slice,l=p.toString,M=p.hasOwnProperty,y=k.forEach,z=k.map,A=k.reduce,B=k.reduceRight,C=k.filter,D=k.every,E=k.some,q=k.indexOf,F=k.lastIndexOf,p=Array.isArray,N=Object.keys,t=Function.prototype.bind,b=function(a){if(a instanceof b)return a;if(!(this instanceof b))return new b(a);this._wrapped=a};"undefined"!==typeof exports?("undefined"!==typeof module&&module.exports&&(exports=module.exports=b),exports._=b):s._=b;
+b.VERSION="1.3.3";var j=b.each=b.forEach=function(a,c,d){if(a!=null)if(y&&a.forEach===y)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e2;a==null&&(a=[]);if(A&&
+a.reduce===A){e&&(c=b.bind(c,e));return f?a.reduce(c,d):a.reduce(c)}j(a,function(a,b,h){if(f)d=c.call(e,d,a,b,h);else{d=a;f=true}});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(B&&a.reduceRight===B){e&&(c=b.bind(c,e));return f?a.reduceRight(c,d):a.reduceRight(c)}var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=function(a,
+c,b){var e;G(a,function(a,g,i){if(c.call(b,a,g,i)){e=a;return true}});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(C&&a.filter===C)return a.filter(c,b);j(a,function(a,g,i){c.call(b,a,g,i)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,i){c.call(b,a,g,i)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,d){c||(c=b.identity);var e=true;if(a==null)return e;if(D&&a.every===D)return a.every(c,d);j(a,function(a,b,
+i){if(!(e=e&&c.call(d,a,b,i)))return o});return!!e};var G=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(E&&a.some===E)return a.some(c,d);j(a,function(a,b,i){if(e||(e=c.call(d,a,b,i)))return o});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;if(q&&a.indexOf===q)return a.indexOf(c)!=-1;return b=G(a,function(a){return a===c})};b.invoke=function(a,c){var d=h.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c:a[c]).apply(a,
+d)})};b.pluck=function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0]&&a.length<65535)return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,i){b=c?c.call(d,a,b,i):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a)&&a[0]===+a[0]&&a.length<65535)return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,
+function(a,b,i){b=c?c.call(d,a,b,i):a;bd?1:0}),"value")};var H=function(a,c){return b.isFunction(c)?c:function(a){return a[c]}},
+I=function(a,c,b){var e={},f=H(a,c);j(a,function(a,c){var h=f(a,c);b(e,h,a)});return e};b.groupBy=function(a,c){return I(a,c,function(a,c,b){(a[c]||(a[c]=[])).push(b)})};b.countBy=function(a,c){return I(a,c,function(a,c){a[c]||(a[c]=0);a[c]++})};b.sortedIndex=function(a,c,d){d||(d=b.identity);for(var c=d(c),e=0,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a){var c=r(h.call(arguments,1),true,[]);return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=h.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};
+b.keys=N||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.pairs=function(a){return b.map(a,function(a,b){return[b,a]})};b.invert=function(a){return b.reduce(a,function(a,b,e){a[b]=e;return a},{})};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(h.call(arguments,1),function(b){for(var d in b)a[d]=
+b[d]});return a};b.pick=function(a){var c={},d=b.flatten(h.call(arguments,1));j(d,function(b){b in a&&(c[b]=a[b])});return c};b.omit=function(a){var c={},d=b.flatten(h.call(arguments,1)),e;for(e in a)b.include(d,e)||(c[e]=a[e]);return c};b.defaults=function(a){j(h.call(arguments,1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};var u=function(a,c,d){if(a===c)return a!==
+0||1/a==1/c;if(a==null||c==null)return a===c;if(a instanceof b)a=a._wrapped;if(c instanceof b)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==""+c;case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==c.source&&a.global==c.global&&
+a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){f=a.length;if(g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&u(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var i in a)if(b.has(a,i)){f++;if(!(g=b.has(c,i)&&u(a[i],c[i],d)))break}if(g){for(i in c)if(b.has(c,i)&&!f--)break;g=!f}}d.pop();
+return g};b.isEqual=function(a,b){return u(a,b,[])};b.isEmpty=function(a){if(a==null)return true;if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=p||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};j("Arguments,Function,String,Number,Date,RegExp".split(","),function(a){b["is"+a]=function(b){return l.call(b)=="[object "+a+"]"}});b.isArguments(arguments)||
+(b.isArguments=function(a){return!(!a||!b.has(a,"callee"))});b.isFinite=function(a){return b.isNumber(a)&&isFinite(a)};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return M.call(a,b)};b.noConflict=function(){s._=K;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e":">",'"':""","'":"'","/":"/"}};m.unescape=b.invert(m.escape);var O={escape:RegExp("["+b.keys(m.escape).join("")+"]","g"),unescape:RegExp("("+b.keys(m.unescape).join("|")+")","g")};b.each(["escape","unescape"],function(a){b[a]=function(b){return b==null?"":(""+b).replace(O[a],function(b){return m[a][b]})}});b.result=function(a,c){if(a==null)return null;var d=a[c];return b.isFunction(d)?d.call(a):
+d};b.mixin=function(a){j(b.functions(a),function(c){var d=b[c]=a[c];b.prototype[c]=function(){var a=h.call(arguments);a.unshift(this._wrapped);a=d.apply(b,a);return this._chain?b(a).chain():a}})};var P=0;b.uniqueId=function(a){var b=P++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var v=/.^/,n={"\\":"\\","'":"'",r:"\r",n:"\n",t:"\t",u2028:"\u2028",u2029:"\u2029"},w;for(w in n)n[n[w]]=w;var Q=/\\|'|\r|\n|\t|\u2028|\u2029/g,
+R=/\\(\\|'|r|n|t|u2028|u2029)/g,x=function(a){return a.replace(R,function(a,b){return n[b]})};b.template=function(a,c,d){d=b.defaults({},d,b.templateSettings);a="__p+='"+a.replace(Q,function(a){return"\\"+n[a]}).replace(d.escape||v,function(a,b){return"'+\n((__t=("+x(b)+"))==null?'':_.escape(__t))+\n'"}).replace(d.interpolate||v,function(a,b){return"'+\n((__t=("+x(b)+"))==null?'':__t)+\n'"}).replace(d.evaluate||v,function(a,b){return"';\n"+x(b)+"\n__p+='"})+"';\n";d.variable||(a="with(obj||{}){\n"+
+a+"}\n");a="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{var e=new Function(d.variable||"obj","_",a)}catch(f){f.source=a;throw f;}if(c)return e(c,b);c=function(a){return e.call(this,a,b)};c.source="function("+(d.variable||"obj")+"){\n"+a+"}";return c};b.chain=function(a){return b(a).chain()};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var c=k[a];b.prototype[a]=function(){var d=this._wrapped;c.apply(d,
+arguments);(a=="shift"||a=="splice")&&d.length===0&&delete d[0];return this._chain?b(d).chain():d}});j(["concat","join","slice"],function(a){var c=k[a];b.prototype[a]=function(){var a=c.apply(this._wrapped,arguments);return this._chain?b(a).chain():a}});b.extend(b.prototype,{chain:function(){this._chain=true;return this},value:function(){return this._wrapped}})}).call(this);
diff --git a/vendor/underscore/underscore.js b/vendor/underscore/underscore.js
index 4b6e76167..563df8bf9 100644
--- a/vendor/underscore/underscore.js
+++ b/vendor/underscore/underscore.js
@@ -47,7 +47,11 @@
nativeBind = FuncProto.bind;
// Create a safe reference to the Underscore object for use below.
- var _ = function(obj) { return new wrapper(obj); };
+ var _ = function(obj) {
+ if (obj instanceof _) return obj;
+ if (!(this instanceof _)) return new _(obj);
+ this._wrapped = obj;
+ };
// Export the Underscore object for **Node.js**, with
// backwards-compatibility for the old `require()` API. If we're in
@@ -771,8 +775,8 @@
// A strict comparison is necessary because `null == undefined`.
if (a == null || b == null) return a === b;
// Unwrap any wrapped objects.
- if (a._chain) a = a._wrapped;
- if (b._chain) b = b._wrapped;
+ if (a instanceof _) a = a._wrapped;
+ if (b instanceof _) b = b._wrapped;
// Invoke a custom `isEqual` method if one is provided.
if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b);
if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a);
@@ -990,11 +994,15 @@
return _.isFunction(value) ? value.call(object) : value;
};
- // Add your own custom functions to the Underscore object, ensuring that
- // they're correctly added to the OOP wrapper as well.
+ // Add your own custom functions to the Underscore object.
_.mixin = function(obj) {
each(_.functions(obj), function(name){
- addToWrapper(name, _[name] = obj[name]);
+ var func = _[name] = obj[name];
+ _.prototype[name] = function() {
+ var args = slice.call(arguments);
+ args.unshift(this._wrapped);
+ return result.call(this, func.apply(_, args));
+ };
});
};
@@ -1047,7 +1055,7 @@
// Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code.
_.template = function(text, data, settings) {
- settings = _.defaults(settings || {}, _.templateSettings);
+ settings = _.defaults({}, settings, _.templateSettings);
// Compile the template source, taking care to escape characters that
// cannot be included in a string literal and then unescape them in code
@@ -1096,29 +1104,15 @@
return _(obj).chain();
};
- // The OOP Wrapper
+ // OOP
// ---------------
-
// If Underscore is called as a function, it returns a wrapped object that
// can be used OO-style. This wrapper holds altered versions of all the
// underscore functions. Wrapped objects may be chained.
- var wrapper = function(obj) { this._wrapped = obj; };
-
- // Expose `wrapper.prototype` as `_.prototype`
- _.prototype = wrapper.prototype;
// Helper function to continue chaining intermediate results.
- var result = function(obj, chain) {
- return chain ? _(obj).chain() : obj;
- };
-
- // A method to easily add functions to the OOP wrapper.
- var addToWrapper = function(name, func) {
- wrapper.prototype[name] = function() {
- var args = slice.call(arguments);
- unshift.call(args, this._wrapped);
- return result(func.apply(_, args), this._chain);
- };
+ var result = function(obj) {
+ return this._chain ? _(obj).chain() : obj;
};
// Add all of the Underscore functions to the wrapper object.
@@ -1127,31 +1121,35 @@
// Add all mutator Array functions to the wrapper.
each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
var method = ArrayProto[name];
- wrapper.prototype[name] = function() {
+ _.prototype[name] = function() {
var obj = this._wrapped;
method.apply(obj, arguments);
if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
- return result(obj, this._chain);
+ return result.call(this, obj);
};
});
// Add all accessor Array functions to the wrapper.
each(['concat', 'join', 'slice'], function(name) {
var method = ArrayProto[name];
- wrapper.prototype[name] = function() {
- return result(method.apply(this._wrapped, arguments), this._chain);
+ _.prototype[name] = function() {
+ return result.call(this, method.apply(this._wrapped, arguments));
};
});
- // Start chaining a wrapped Underscore object.
- wrapper.prototype.chain = function() {
- this._chain = true;
- return this;
- };
+ _.extend(_.prototype, {
- // Extracts the result from a wrapped and chained object.
- wrapper.prototype.value = function() {
- return this._wrapped;
- };
+ // Start chaining a wrapped Underscore object.
+ chain: function() {
+ this._chain = true;
+ return this;
+ },
+
+ // Extracts the result from a wrapped and chained object.
+ value: function() {
+ return this._wrapped;
+ }
+
+ });
}).call(this);