Thành viên:Mifield/x.js

Bách khoa toàn thư mở Wikipedia

Chú ý: Sau khi lưu thay đổi trang, bạn phải xóa bộ nhớ đệm của trình duyệt để nhìn thấy các thay đổi. Google Chrome, Firefox, Internet ExplorerSafari: Giữ phím ⇧ Shift và nhấn nút Reload/Tải lại trên thanh công cụ của trình duyệt. Để biết chi tiết và hướng dẫn cho các trình duyệt khác, xem Trợ giúp:Xóa bộ nhớ đệm.

mw.loader.using( [], function ( require ) {

	if ( mw.libs.x === undefined ) {
		mw.libs.x = {};
	}



	// standalone utilities that don't depend on anything else
	const ident             = function ident    ( value )  { return value; };

	const eqeqeq            = function eqeqeq    ( a, b )  { return a === b; };
	const stringEq          = function stringEq  ( a, b )  { return String( a ) === String( b ); };

	const stringToSpliced   = function toSpliced ( string, start, deleteCount ) {
		string = String( string );
		const front  = string.substring( 0, start );
		const back   = string.substring( start + deleteCount );
		const items  = Array.prototype.toSpliced.call( arguments, 0, 3 );
		const middle = items.join( "" );
		return front + middle + back;
	};

	const arrayFlatten      = function flatten   ( array, flattenIterables, depth ) {
		const flattened = Array.prototype.flat.call(
			array,
			depth === undefined ? +Infinity : depth
		).map( flattenIterables ? function ( item ) {
			if ( item[ Symbol.iterator ] ) {
				return Array.from( item );
			}
		} : ident );
		
		if ( flattened.some( Array.isArray ) )
			return arrayFlatten( flattened );
		return flattened;
	};



	const subtract          = function subtract  ( a, b )  { return Number( a ) - Number( b ); };
	const stringCompare     = function compare   ( a, b )  {
		a = String( a );
		b = String( b );
		return a > b ? 1 : a === b ? 0 : -1;
	};
	const stringCompare_    = function compare_  ( a, b )  {
		a = String( a );
		b = String( b );
		return stringCompare( a.toLowerCase(), b.toLowerCase() );
	};
	const stringCompare__   = function compare__ ( a, b )  {
		a = String( a );
		b = String( b );
		return stringCompare_( a.replace( regexUnderscore, " " ), b.replace( regexUnderscore, " " ) );
	};

	const sortNumeric       = function sort     ( array ) { return array.sort( subtract ); };
	const sortLexical       = function sort     ( array ) { return array.sort(); };
	const sortLexical_      = function sort_    ( array ) { return array.sort( stringCompare_ ); };
	const sortLexical__     = function sort__   ( array ) { return array.sort( stringCompare__ ); };
	const _sort             = function _sort    ( compareFunction, array ) {
		if ( array === undefined ) {
			return function ( array ) {
				return array.sort( compareFunction );
			};
		}
		return array.sort( compareFunction );
	};

	const toSortedNumeric           = function toSorted   ( array ) { return array.toSorted( subtract ); };
	const toSortedLexical           = function toSorted   ( array ) { return array.toSorted(); };
	const toSortedLexical_          = function toSorted_  ( array ) { return array.toSorted( stringCompare_ ); };
	const toSortedLexical__         = function toSorted__ ( array ) { return array.toSorted( stringCompare__ ); };
	const _toSorted                 = function _toSorted  ( compareFunction, array ) {
		if ( array === undefined ) {
			return function ( array ) {
				return array.toSorted( compareFunction );
			};
		}

		return array.toSorted( compareFunction );
	};

	const _sortUniqueWorkerFunction = function ( sortFunction, array, compareFunction ) {
		if ( array.length === 0 || array.length === 1 ) return array;
		sortFunction( array );
		array.reduceRight( function ( previous, current, index, array /* should be sorted already at this stage */ ) {
			if ( compareFunction === undefined ?
				previous === current :
				compareFunction( previous, current ) === 0
			) {
				array.splice( index, 1 );
			}
			return current;
		} );
		return array;
	};

	const sortUniqueNumeric         = function sortUnique   ( array ) {
		return _sortUniqueWorkerFunction( sortNumeric,   array );
	};
	const sortUniqueLexical         = function sortUnique   ( array ) {
		return _sortUniqueWorkerFunction( sortLexical,   array );
	};
	const sortUniqueLexical_        = function sortUnique_  ( array ) {
		return _sortUniqueWorkerFunction( sortLexical_,  array, stringCompare_ );
	};
	const sortUniqueLexical__       = function sortUnique__ ( array ) {
		return _sortUniqueWorkerFunction( sortLexical__, array, stringCompare__ );
	};
	const _sortUnique               = function _sortUnique  ( compareFunction, array ) {
		if ( array === undefined ) {
			return function ( array ) {
				return _sortUniqueWorkerFunction(
					_sort( compareFunction ),
					array, compareFunction
				);
			};
		}
		return _sortUniqueWorkerFunction(
			_sort( compareFunction ),
			array, compareFunction
		);
	};

	const _toSortedUniqueWorkerFunction = function ( toSortedFunction, array, compareFunction ) {
		if ( array.length === 0 ) return [];

		const sorted = toSortedFunction( array );
		const unique = [ sorted[ 0 ] ];
		if ( array.length === 1 ) return unique;
		/* Array.prototype.reduce() starts with the element at index 1
		** as the value for <current> when no <initialValue> is given */
		sorted.reduce( function ( previous, current, index ) {
			if ( compareFunction === undefined ?
				previous !== current :
				compareFunction( previous, current ) !== 0
			) {
				unique.push( current );
			}
			return current;
		} );
		return unique;
	};

	const toSortedUniqueNumeric     = function toSortedUnique   ( array ) {
		return _toSortedUniqueWorkerFunction( toSortedNumeric,   array );
	};
	const toSortedUniqueLexical     = function toSortedUnique   ( array ) {
		return _toSortedUniqueWorkerFunction( toSortedLexical,   array );
	};
	const toSortedUniqueLexical_    = function toSortedUnique_  ( array ) {
		return _toSortedUniqueWorkerFunction( toSortedLexical_,  array, stringCompare_ );
	};
	const toSortedUniqueLexical__   = function toSortedUnique__ ( array ) {
		return _toSortedUniqueWorkerFunction( toSortedLexical__, array, stringCompare__ );
	};
	const _toSortedUnique           = function _toSortedUnique  ( compareFunction, array ) {
		if ( array === undefined ) {
			return function ( array ) {
				return _toSortedUniqueWorkerFunction(
					_toSorted( compareFunction ),
					array, compareFunction
				);
			};
		}

		return _toSortedUniqueWorkerFunction(
			_toSorted( compareFunction ),
			array, compareFunction
		);
	};

	const _intersectWorkerFunction  = function ( compareFunction, toSortedUniqueFunction, array, other, areSortedUnique, prefer, intersection ) {
		if ( !( Array.isArray( intersection ) ) ) intersection = [];
		if ( array.length * other.length === 0 ) return intersection;

		if ( !areSortedUnique ) {
			array = toSortedUniqueFunction( array );
			other = toSortedUniqueFunction( other );
		}

		if (array.length < other.length )
			return _intersectWorkerFunction ( compareFunction, toSortedUniqueFunction, other, array, true, 1 - prefer, intersection );

		const comparator = other[ 0 ];
		const location = array.findIndex( function ( item, index ) {
			return compareFunction( comparator, item ) <= 0;
		} );
		if ( location >= 0 ) {
			if ( compareFunction( array[ location ], comparator ) === 0 ) {
				array.splice( 0, location + 1 );

				if ( prefer ) intersection.push( comparator );
				else intersection.push( array[ location ] );
			} else {
				array.splice( 0, location );
			}
			other.splice( 0, 1 );
		} else return intersection; // this the (current) smallest value of <other> is greater than all of <array>

		return _intersectWorkerFunction( compareFunction, toSortedUniqueFunction, array, other, true, prefer, intersection );
	};

	const intersectNumeric          = function intersect   ( array, other ) {
		return _intersectWorkerFunction( subtract,        toSortedUniqueNumeric,   array, other, false );
	};
	const intersectLexical          = function intersect   ( array, other ) {
		return _intersectWorkerFunction( stringCompare,   toSortedUniqueLexical,   array, other, false );
	};
	const intersectLexical_         = function intersect_  ( array, other, prefer ) {
		return _intersectWorkerFunction( stringCompare_,  toSortedUniqueLexical_,  array, other, false, prefer );
	};
	const intersectLexical__        = function intersect__ ( array, other, prefer ) {
		return _intersectWorkerFunction( stringCompare__, toSortedUniqueLexical__, array, other, false, prefer );
	};
	const _intersect                = function _intersect  ( compareFunction, array, other, prefer ) {
		if ( array === undefined && other === undefined ) {
			return function ( array, other, _prefer ) {
				return _intersectWorkerFunction(
					compareFunction,
					_toSortedUnique( compareFunction ),
					array, other, false,
					_prefer === undefined ? prefer : _prefer
				);
			};
		}

		if ( other === undefined ) {
			return function ( other, _prefer ) {
				return _intersectWorkerFunction(
					compareFunction,
					_toSortedUnique( compareFunction ),
					array, other, false,
					_prefer === undefined ? prefer : _prefer
				);
			};
		}

		if ( array === undefined ) {
			return function ( array, _prefer ) {
				return _intersectWorkerFunction(
					compareFunction,
					_toSortedUnique( compareFunction ),
					array, other, false,
					_prefer === undefined ? prefer : _prefer
				);
			};
		}

		return _intersectWorkerFunction(
			compareFunction,
			_toSortedUnique( compareFunction ),
			array, other, false, prefer
		);
	};



	Object.assign( mw.libs.x, {

		ident:                       ident,

		eqeqeq:                      eqeqeq,

		math: {
			subtract:                subtract,
		},

		string: {
			compare:                 Object.assign( stringCompare, {
				i:                   Object.assign( stringCompare_, {
					_:               stringCompare__,
				} ),
			} ),
			eq:                      stringEq,
			to:                      {
				spliced:             stringToSpliced,
			},
		},

		array: {
			sort:                    Object.assign( _sort, {
				numeric:             sortNumeric,
				lexical:             Object.assign( sortLexical, {
					i:               Object.assign( sortLexical_, {
						_:           sortLexical__,
					} ),
				} ),
				unique:              Object.assign( _sortUnique, {
					numeric:         sortUniqueNumeric,
					lexical:         Object.assign( sortUniqueLexical, {
						i:           Object.assign( sortUniqueLexical_, {
							_:       sortUniqueLexical__,
						} ),
					} ),
					_worker:         _sortUniqueWorkerFunction,
				} ),
			} ),
			to: {
				sorted:              Object.assign( _toSorted, {
					numeric:         toSortedNumeric,
					lexical:         Object.assign( toSortedLexical, {
						i:           Object.assign( toSortedLexical_, {
							_:       toSortedLexical__,
						} ),
					} ),
					unique:          Object.assign( _toSortedUnique, {
						numeric:     toSortedUniqueNumeric,
						lexical:     Object.assign( toSortedUniqueLexical, {
							i:       Object.assign( toSortedUniqueLexical_, {
								_:   toSortedUniqueLexical__,
							} ),
						} ),
						_worker:     _toSortedUniqueWorkerFunction,
					} ),
				} ),
			},
			flatten:                 arrayFlatten,
			intersect:               Object.assign( _intersect, {
				numeric:             intersectNumeric,
				lexical:             Object.assign( intersectLexical, {
					i:               Object.assign( intersectLexical_, {
						_:           intersectLexical__,
					} ),
				} ),
			} ),
		},

	} );

	alert( "x.js loaded" );
} );