You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
4.5 KiB
102 lines
4.5 KiB
'use strict'; |
|
var global = require('../internals/global'); |
|
var apply = require('../internals/function-apply'); |
|
var uncurryThis = require('../internals/function-uncurry-this'); |
|
var isCallable = require('../internals/is-callable'); |
|
var getOwnPropertyDescriptor = require('../internals/object-get-own-property-descriptor').f; |
|
var isForced = require('../internals/is-forced'); |
|
var path = require('../internals/path'); |
|
var bind = require('../internals/function-bind-context'); |
|
var createNonEnumerableProperty = require('../internals/create-non-enumerable-property'); |
|
var hasOwn = require('../internals/has-own-property'); |
|
|
|
var wrapConstructor = function (NativeConstructor) { |
|
var Wrapper = function (a, b, c) { |
|
if (this instanceof Wrapper) { |
|
switch (arguments.length) { |
|
case 0: return new NativeConstructor(); |
|
case 1: return new NativeConstructor(a); |
|
case 2: return new NativeConstructor(a, b); |
|
} return new NativeConstructor(a, b, c); |
|
} return apply(NativeConstructor, this, arguments); |
|
}; |
|
Wrapper.prototype = NativeConstructor.prototype; |
|
return Wrapper; |
|
}; |
|
|
|
/* |
|
options.target - name of the target object |
|
options.global - target is the global object |
|
options.stat - export as static methods of target |
|
options.proto - export as prototype methods of target |
|
options.real - real prototype method for the `pure` version |
|
options.forced - export even if the native feature is available |
|
options.bind - bind methods to the target, required for the `pure` version |
|
options.wrap - wrap constructors to preventing global pollution, required for the `pure` version |
|
options.unsafe - use the simple assignment of property instead of delete + defineProperty |
|
options.sham - add a flag to not completely full polyfills |
|
options.enumerable - export as enumerable property |
|
options.dontCallGetSet - prevent calling a getter on target |
|
options.name - the .name of the function if it does not match the key |
|
*/ |
|
module.exports = function (options, source) { |
|
var TARGET = options.target; |
|
var GLOBAL = options.global; |
|
var STATIC = options.stat; |
|
var PROTO = options.proto; |
|
|
|
var nativeSource = GLOBAL ? global : STATIC ? global[TARGET] : (global[TARGET] || {}).prototype; |
|
|
|
var target = GLOBAL ? path : path[TARGET] || createNonEnumerableProperty(path, TARGET, {})[TARGET]; |
|
var targetPrototype = target.prototype; |
|
|
|
var FORCED, USE_NATIVE, VIRTUAL_PROTOTYPE; |
|
var key, sourceProperty, targetProperty, nativeProperty, resultProperty, descriptor; |
|
|
|
for (key in source) { |
|
FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced); |
|
// contains in native |
|
USE_NATIVE = !FORCED && nativeSource && hasOwn(nativeSource, key); |
|
|
|
targetProperty = target[key]; |
|
|
|
if (USE_NATIVE) if (options.dontCallGetSet) { |
|
descriptor = getOwnPropertyDescriptor(nativeSource, key); |
|
nativeProperty = descriptor && descriptor.value; |
|
} else nativeProperty = nativeSource[key]; |
|
|
|
// export native or implementation |
|
sourceProperty = (USE_NATIVE && nativeProperty) ? nativeProperty : source[key]; |
|
|
|
if (USE_NATIVE && typeof targetProperty == typeof sourceProperty) continue; |
|
|
|
// bind timers to global for call from export context |
|
if (options.bind && USE_NATIVE) resultProperty = bind(sourceProperty, global); |
|
// wrap global constructors for prevent changs in this version |
|
else if (options.wrap && USE_NATIVE) resultProperty = wrapConstructor(sourceProperty); |
|
// make static versions for prototype methods |
|
else if (PROTO && isCallable(sourceProperty)) resultProperty = uncurryThis(sourceProperty); |
|
// default case |
|
else resultProperty = sourceProperty; |
|
|
|
// add a flag to not completely full polyfills |
|
if (options.sham || (sourceProperty && sourceProperty.sham) || (targetProperty && targetProperty.sham)) { |
|
createNonEnumerableProperty(resultProperty, 'sham', true); |
|
} |
|
|
|
createNonEnumerableProperty(target, key, resultProperty); |
|
|
|
if (PROTO) { |
|
VIRTUAL_PROTOTYPE = TARGET + 'Prototype'; |
|
if (!hasOwn(path, VIRTUAL_PROTOTYPE)) { |
|
createNonEnumerableProperty(path, VIRTUAL_PROTOTYPE, {}); |
|
} |
|
// export virtual prototype methods |
|
createNonEnumerableProperty(path[VIRTUAL_PROTOTYPE], key, sourceProperty); |
|
// export real prototype methods |
|
if (options.real && targetPrototype && !targetPrototype[key]) { |
|
createNonEnumerableProperty(targetPrototype, key, sourceProperty); |
|
} |
|
} |
|
} |
|
};
|
|
|