/*!
- * OOjs v1.1.3 optimised for jQuery
+ * OOjs v1.1.6 optimised for jQuery
* https://www.mediawiki.org/wiki/OOjs
*
- * Copyright 2011-2014 OOjs Team and other contributors.
+ * Copyright 2011-2015 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2014-11-17T19:17:29Z
+ * Date: 2015-03-19T00:42:55Z
*/
( function ( global ) {
*
* @param {Object} obj
* @param {Mixed...} [keys]
- * @returns obj[arguments[1]][arguments[2]].... or undefined
+ * @return obj[arguments[1]][arguments[2]].... or undefined
*/
oo.getProp = function ( obj ) {
var i,
a = a || {};
b = b || {};
+ if ( typeof a.nodeType === 'number' && typeof a.isEqualNode === 'function' ) {
+ return a.isEqualNode( b );
+ }
+
for ( k in a ) {
- if ( !hasOwn.call( a, k ) || a[k] === undefined ) {
+ if ( !hasOwn.call( a, k ) || a[k] === undefined || a[k] === b[k] ) {
// Support es3-shim: Without the hasOwn filter, comparing [] to {} will be false in ES3
// because the shimmed "forEach" is enumerable and shows up in Array but not Object.
// Also ignore undefined values, because there is no conceptual difference between
( aType === 'string' || aType === 'number' || aType === 'boolean' ) &&
aValue !== bValue
) ||
- ( aValue === Object( aValue ) && !oo.compare( aValue, bValue, asymmetrical ) ) ) {
+ ( aValue === Object( aValue ) && !oo.compare( aValue, bValue, true ) ) ) {
return false;
}
}
}
};
+/**
+ * Get the unique values of an array, removing duplicates
+ *
+ * @param {Array} arr Array
+ * @return {Array} Unique values in array
+ */
+oo.unique = function ( arr ) {
+ return arr.reduce( function ( result, current ) {
+ if ( result.indexOf( current ) === -1 ) {
+ result.push( current );
+ }
+ return result;
+ }, [] );
+};
+
/**
* Compute the union (duplicate-free merge) of a set of arrays.
*
*/
oo.EventEmitter.prototype.once = function ( event, listener ) {
var eventEmitter = this,
- listenerWrapper = function () {
- eventEmitter.off( event, listenerWrapper );
- listener.apply( eventEmitter, Array.prototype.slice.call( arguments, 0 ) );
+ wrapper = function () {
+ eventEmitter.off( event, wrapper );
+ return listener.apply( this, arguments );
};
- return this.on( event, listenerWrapper );
+ return this.on( event, wrapper );
};
/**
* @return {boolean} If event was handled by at least one listener
*/
oo.EventEmitter.prototype.emit = function ( event ) {
- var i, len, binding, bindings, args, method;
+ var args = [],
+ i, len, binding, bindings, method;
if ( hasOwn.call( this.bindings, event ) ) {
// Slicing ensures that we don't get tripped up by event handlers that add/remove bindings
bindings = this.bindings[event].slice();
- args = Array.prototype.slice.call( arguments, 1 );
+ for ( i = 1, len = arguments.length; i < len; i++ ) {
+ args.push( arguments[i] );
+ }
for ( i = 0, len = bindings.length; i < len; i++ ) {
binding = bindings[i];
if ( typeof binding.method === 'string' ) {
* @throws {Error} Unknown object name
*/
oo.Factory.prototype.create = function ( name ) {
- var args, obj,
+ var obj, i,
+ args = [],
constructor = this.lookup( name );
if ( !constructor ) {
}
// Convert arguments to array and shift the first argument (name) off
- args = Array.prototype.slice.call( arguments, 1 );
+ for ( i = 1; i < arguments.length; i++ ) {
+ args.push( arguments[i] );
+ }
// We can't use the "new" operator with .apply directly because apply needs a
// context. So instead just do what "new" does: create an object that inherits from