export.js 4.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. 'use strict';
  2. var global = require('../internals/global');
  3. var getOwnPropertyDescriptor = require('../internals/object-get-own-property-descriptor').f;
  4. var isForced = require('../internals/is-forced');
  5. var path = require('../internals/path');
  6. var bind = require('../internals/function-bind-context');
  7. var createNonEnumerableProperty = require('../internals/create-non-enumerable-property');
  8. var has = require('../internals/has');
  9. var wrapConstructor = function (NativeConstructor) {
  10. var Wrapper = function (a, b, c) {
  11. if (this instanceof NativeConstructor) {
  12. switch (arguments.length) {
  13. case 0: return new NativeConstructor();
  14. case 1: return new NativeConstructor(a);
  15. case 2: return new NativeConstructor(a, b);
  16. } return new NativeConstructor(a, b, c);
  17. } return NativeConstructor.apply(this, arguments);
  18. };
  19. Wrapper.prototype = NativeConstructor.prototype;
  20. return Wrapper;
  21. };
  22. /*
  23. options.target - name of the target object
  24. options.global - target is the global object
  25. options.stat - export as static methods of target
  26. options.proto - export as prototype methods of target
  27. options.real - real prototype method for the `pure` version
  28. options.forced - export even if the native feature is available
  29. options.bind - bind methods to the target, required for the `pure` version
  30. options.wrap - wrap constructors to preventing global pollution, required for the `pure` version
  31. options.unsafe - use the simple assignment of property instead of delete + defineProperty
  32. options.sham - add a flag to not completely full polyfills
  33. options.enumerable - export as enumerable property
  34. options.noTargetGet - prevent calling a getter on target
  35. */
  36. module.exports = function (options, source) {
  37. var TARGET = options.target;
  38. var GLOBAL = options.global;
  39. var STATIC = options.stat;
  40. var PROTO = options.proto;
  41. var nativeSource = GLOBAL ? global : STATIC ? global[TARGET] : (global[TARGET] || {}).prototype;
  42. var target = GLOBAL ? path : path[TARGET] || (path[TARGET] = {});
  43. var targetPrototype = target.prototype;
  44. var FORCED, USE_NATIVE, VIRTUAL_PROTOTYPE;
  45. var key, sourceProperty, targetProperty, nativeProperty, resultProperty, descriptor;
  46. for (key in source) {
  47. FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);
  48. // contains in native
  49. USE_NATIVE = !FORCED && nativeSource && has(nativeSource, key);
  50. targetProperty = target[key];
  51. if (USE_NATIVE) if (options.noTargetGet) {
  52. descriptor = getOwnPropertyDescriptor(nativeSource, key);
  53. nativeProperty = descriptor && descriptor.value;
  54. } else nativeProperty = nativeSource[key];
  55. // export native or implementation
  56. sourceProperty = (USE_NATIVE && nativeProperty) ? nativeProperty : source[key];
  57. if (USE_NATIVE && typeof targetProperty === typeof sourceProperty) continue;
  58. // bind timers to global for call from export context
  59. if (options.bind && USE_NATIVE) resultProperty = bind(sourceProperty, global);
  60. // wrap global constructors for prevent changs in this version
  61. else if (options.wrap && USE_NATIVE) resultProperty = wrapConstructor(sourceProperty);
  62. // make static versions for prototype methods
  63. else if (PROTO && typeof sourceProperty == 'function') resultProperty = bind(Function.call, sourceProperty);
  64. // default case
  65. else resultProperty = sourceProperty;
  66. // add a flag to not completely full polyfills
  67. if (options.sham || (sourceProperty && sourceProperty.sham) || (targetProperty && targetProperty.sham)) {
  68. createNonEnumerableProperty(resultProperty, 'sham', true);
  69. }
  70. target[key] = resultProperty;
  71. if (PROTO) {
  72. VIRTUAL_PROTOTYPE = TARGET + 'Prototype';
  73. if (!has(path, VIRTUAL_PROTOTYPE)) {
  74. createNonEnumerableProperty(path, VIRTUAL_PROTOTYPE, {});
  75. }
  76. // export virtual prototype methods
  77. path[VIRTUAL_PROTOTYPE][key] = sourceProperty;
  78. // export real prototype methods
  79. if (options.real && targetPrototype && !targetPrototype[key]) {
  80. createNonEnumerableProperty(targetPrototype, key, sourceProperty);
  81. }
  82. }
  83. }
  84. };