core-decorators
Advanced tools
Comparing version 0.12.2 to 0.12.3
@@ -51,9 +51,30 @@ 'use strict'; | ||
for (var key in descs) { | ||
var desc = descs[key]; | ||
if (typeof desc.value !== 'function' || key === 'constructor') { | ||
continue; | ||
var _iteratorNormalCompletion = true; | ||
var _didIteratorError = false; | ||
var _iteratorError = undefined; | ||
try { | ||
for (var _iterator = (0, _privateUtils.getOwnKeys)(descs)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
var key = _step.value; | ||
var desc = descs[key]; | ||
if (typeof desc.value !== 'function' || key === 'constructor') { | ||
continue; | ||
} | ||
defineProperty(klass.prototype, key, autobindMethod(klass.prototype, key, desc)); | ||
} | ||
defineProperty(klass.prototype, key, autobindMethod(klass.prototype, key, desc)); | ||
} catch (err) { | ||
_didIteratorError = true; | ||
_iteratorError = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion && _iterator['return']) { | ||
_iterator['return'](); | ||
} | ||
} finally { | ||
if (_didIteratorError) { | ||
throw _iteratorError; | ||
} | ||
} | ||
} | ||
@@ -93,3 +114,3 @@ } | ||
// Autobound method calling calling super.sameMethod() which is also autobound and so on. | ||
// Autobound method calling super.sameMethod() which is also autobound and so on. | ||
if (this.constructor !== constructor && key in this.constructor.prototype) { | ||
@@ -96,0 +117,0 @@ return getBoundSuper(this, fn); |
@@ -21,3 +21,2 @@ 'use strict'; | ||
var fn = descriptor.value; | ||
var configurable = descriptor.configurable; | ||
@@ -27,2 +26,7 @@ var enumerable = descriptor.enumerable; | ||
var originalGet = descriptor.get; | ||
var originalSet = descriptor.set; | ||
var originalValue = descriptor.value; | ||
var isGetter = !!originalGet; | ||
return { | ||
@@ -32,14 +36,22 @@ configurable: configurable, | ||
get: function get() { | ||
var value = decorator.apply(undefined, [fn].concat(_toConsumableArray(args))); | ||
var fn = isGetter ? originalGet.call(this) : originalValue; | ||
var value = decorator.call.apply(decorator, [this, fn].concat(_toConsumableArray(args))); | ||
Object.defineProperty(this, key, { | ||
configurable: configurable, | ||
enumerable: enumerable, | ||
writable: writable, | ||
value: value | ||
}); | ||
if (isGetter) { | ||
return value; | ||
} else { | ||
var desc = { | ||
configurable: configurable, | ||
enumerable: enumerable | ||
}; | ||
return value; | ||
desc.value = value; | ||
desc.writable = writable; | ||
Object.defineProperty(this, key, desc); | ||
return value; | ||
} | ||
}, | ||
set: (0, _privateUtils.createDefaultSetter)() | ||
set: isGetter ? originalSet : (0, _privateUtils.createDefaultSetter)() | ||
}; | ||
@@ -46,0 +58,0 @@ } |
@@ -11,3 +11,31 @@ 'use strict'; | ||
var defineProperty = Object.defineProperty; | ||
var getPrototypeOf = Object.getPrototypeOf; | ||
function buggySymbol(symbol) { | ||
return Object.prototype.toString.call(symbol) === '[object Symbol]' && typeof symbol === 'object'; | ||
} | ||
function hasProperty(prop, obj) { | ||
// We have to traverse manually prototypes' chain for polyfilled ES6 Symbols | ||
// like "in" operator does. | ||
// I.e.: Babel 5 Symbol polyfill stores every created symbol in Object.prototype. | ||
// That's why we cannot use construction like "prop in obj" to check, if needed | ||
// prop actually exists in given object/prototypes' chain. | ||
if (buggySymbol(prop)) { | ||
do { | ||
if (obj === Object.prototype) { | ||
// Polyfill assigns undefined as value for stored symbol key. | ||
// We can assume in this special case if there is nothing assigned it doesn't exist. | ||
return typeof obj[prop] !== 'undefined'; | ||
} | ||
if (obj.hasOwnProperty(prop)) { | ||
return true; | ||
} | ||
} while (obj = getPrototypeOf(obj)); | ||
return false; | ||
} else { | ||
return prop in obj; | ||
} | ||
} | ||
function handleClass(target, mixins) { | ||
@@ -21,6 +49,27 @@ if (!mixins.length) { | ||
for (var key in descs) { | ||
if (!(key in target.prototype)) { | ||
defineProperty(target.prototype, key, descs[key]); | ||
var _iteratorNormalCompletion = true; | ||
var _didIteratorError = false; | ||
var _iteratorError = undefined; | ||
try { | ||
for (var _iterator = (0, _privateUtils.getOwnKeys)(descs)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
var key = _step.value; | ||
if (!hasProperty(key, target.prototype)) { | ||
defineProperty(target.prototype, key, descs[key]); | ||
} | ||
} | ||
} catch (err) { | ||
_didIteratorError = true; | ||
_iteratorError = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion && _iterator['return']) { | ||
_iterator['return'](); | ||
} | ||
} finally { | ||
if (_didIteratorError) { | ||
throw _iteratorError; | ||
} | ||
} | ||
} | ||
@@ -27,0 +76,0 @@ } |
@@ -115,2 +115,4 @@ 'use strict'; | ||
exports.getOwnKeys = getOwnKeys; | ||
function getOwnPropertyDescriptors(obj) { | ||
@@ -117,0 +119,0 @@ var descs = {}; |
{ | ||
"name": "core-decorators", | ||
"version": "0.12.2", | ||
"version": "0.12.3", | ||
"description": "Library of ES2016 (ES7) JavaScript decorators inspired by languages that come with built-ins like @override, @deprecate, @autobind, @mixin and more! Works great with React/Angular/more!", | ||
@@ -5,0 +5,0 @@ "main": "lib/core-decorators.js", |
@@ -13,3 +13,3 @@ # core-decorators.js [![Build Status](https://travis-ci.org/jayphelps/core-decorators.js.svg?branch=master)](https://travis-ci.org/jayphelps/core-decorators.js) | ||
This can be consumed by any transpiler that supports stage-0 of the decorators spec, like [babel.js](https://babeljs.io/) version 5 or using the recent iterations of TypeScript. *Babel 6 [does not yet support decorators](https://phabricator.babeljs.io/T2645), use Babel 5 or the [`applyDecorators()` helper](#applyDecorators) until that is fixed.* | ||
This can be consumed by any transpiler that supports stage-0 of the decorators spec, like [babel.js](https://babeljs.io/) version 5 or using the recent iterations of TypeScript. *Babel 6 [does not yet support decorators](https://phabricator.babeljs.io/T2645), use Babel 5 or the [`applyDecorators()` helper](#applydecorators-helper) until that is fixed.* | ||
@@ -496,1 +496,10 @@ ##### Bower/globals | ||
Since most people can't keep up to date with specs, it's important to note that the spec is in-flux and subject to breaking changes. In fact, the [biggest change is coming shortly](https://github.com/wycats/javascript-decorators/pull/36) but I am active in the appropriate communities and will be keeping this project up to date as things progress. For the most part, these changes will usually be transparent to consumers of this project--that said, core-decorators has not yet reached 1.0 and may in fact introduce breaking changes. If you'd prefer not to receive these changes, be sure to lock your dependency to [PATCH](http://semver.org/). You can track the progress of core-decorators@1.0.0 in the [The Road to 1.0](https://github.com/jayphelps/core-decorators.js/issues/15) ticket. | ||
# Decorator Order Sometimes Matters | ||
When using multiple decorators on a class, method, or property the order of the decorators sometimes matters. This is a neccesary caveat of decorators because otherwise certain cool features wouldn't be possible. The most common example of this is using `@autobind` and any [Higher-Order Component (HOC)](https://medium.com/@dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750) decorator, e.g. Redux's `@connect`. You must `@autobind` your class first before applying the `@connect` HOC. | ||
```js | ||
@connect() | ||
@autobind | ||
class Foo extends Component {} | ||
``` |
@@ -1,2 +0,2 @@ | ||
import { decorate, createDefaultSetter, getOwnPropertyDescriptors } from './private/utils'; | ||
import { decorate, createDefaultSetter, getOwnPropertyDescriptors, getOwnKeys } from './private/utils'; | ||
const { defineProperty } = Object; | ||
@@ -44,3 +44,3 @@ | ||
for (const key in descs) { | ||
for (const key of getOwnKeys(descs)) { | ||
const desc = descs[key]; | ||
@@ -82,3 +82,3 @@ if (typeof desc.value !== 'function' || key === 'constructor') { | ||
// Autobound method calling calling super.sameMethod() which is also autobound and so on. | ||
// Autobound method calling super.sameMethod() which is also autobound and so on. | ||
if (this.constructor !== constructor && key in this.constructor.prototype) { | ||
@@ -85,0 +85,0 @@ return getBoundSuper(this, fn); |
import { decorate as _decorate, createDefaultSetter } from './private/utils'; | ||
function handleDescriptor(target, key, descriptor, [decorator, ...args]) { | ||
const { value: fn, configurable, enumerable, writable } = descriptor; | ||
const { configurable, enumerable, writable } = descriptor; | ||
const originalGet = descriptor.get; | ||
const originalSet = descriptor.set; | ||
const originalValue = descriptor.value; | ||
const isGetter = !!originalGet; | ||
@@ -10,14 +14,22 @@ return { | ||
get() { | ||
const value = decorator(fn, ...args); | ||
const fn = isGetter ? originalGet.call(this) : originalValue; | ||
const value = decorator.call(this, fn, ...args); | ||
Object.defineProperty(this, key, { | ||
configurable, | ||
enumerable, | ||
writable, | ||
value | ||
}); | ||
if (isGetter) { | ||
return value; | ||
} else { | ||
const desc = { | ||
configurable, | ||
enumerable | ||
}; | ||
return value; | ||
desc.value = value; | ||
desc.writable = writable; | ||
Object.defineProperty(this, key, desc); | ||
return value; | ||
} | ||
}, | ||
set: createDefaultSetter() | ||
set: isGetter ? originalSet : createDefaultSetter() | ||
}; | ||
@@ -24,0 +36,0 @@ } |
@@ -1,5 +0,32 @@ | ||
import { getOwnPropertyDescriptors } from './private/utils'; | ||
import { getOwnPropertyDescriptors, getOwnKeys } from './private/utils'; | ||
const { defineProperty } = Object; | ||
const { defineProperty, getPrototypeOf } = Object; | ||
function buggySymbol(symbol) { | ||
return Object.prototype.toString.call(symbol) === '[object Symbol]' && typeof(symbol) === 'object'; | ||
} | ||
function hasProperty(prop, obj) { | ||
// We have to traverse manually prototypes' chain for polyfilled ES6 Symbols | ||
// like "in" operator does. | ||
// I.e.: Babel 5 Symbol polyfill stores every created symbol in Object.prototype. | ||
// That's why we cannot use construction like "prop in obj" to check, if needed | ||
// prop actually exists in given object/prototypes' chain. | ||
if (buggySymbol(prop)) { | ||
do { | ||
if (obj === Object.prototype) { | ||
// Polyfill assigns undefined as value for stored symbol key. | ||
// We can assume in this special case if there is nothing assigned it doesn't exist. | ||
return typeof(obj[prop]) !== 'undefined'; | ||
} | ||
if (obj.hasOwnProperty(prop)) { | ||
return true; | ||
} | ||
} while (obj = getPrototypeOf(obj)); | ||
return false; | ||
} else { | ||
return prop in obj; | ||
} | ||
} | ||
function handleClass(target, mixins) { | ||
@@ -13,4 +40,4 @@ if (!mixins.length) { | ||
for (const key in descs) { | ||
if (!(key in target.prototype)) { | ||
for (const key of getOwnKeys(descs)) { | ||
if (!(hasProperty(key, target.prototype))) { | ||
defineProperty(target.prototype, key, descs[key]); | ||
@@ -17,0 +44,0 @@ } |
@@ -56,3 +56,3 @@ import lazyInitialize from '../lazy-initialize'; | ||
const getOwnKeys = getOwnPropertySymbols | ||
export const getOwnKeys = getOwnPropertySymbols | ||
? function (object) { | ||
@@ -59,0 +59,0 @@ return getOwnPropertyNames(object) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
88005
1886
504