Comparing version 2.4.6 to 2.5.0
@@ -74,2 +74,3 @@ 'use strict'; | ||
}); | ||
this._options = {}; | ||
} | ||
@@ -116,2 +117,17 @@ }, { | ||
}, { | ||
key: 'configureLog', | ||
value: function configureLog(name, spy) { | ||
if (spy) { | ||
if (typeof spy !== 'function') { | ||
throw new Error('The spy must be a function'); | ||
} | ||
if (!this._options.log) { | ||
this._options.log = {}; | ||
} | ||
this._options.log[name] = spy; | ||
} else { | ||
delete this._options.log[name]; | ||
} | ||
} | ||
}, { | ||
key: 'wrap', | ||
@@ -123,3 +139,3 @@ value: function wrap(name, component, more) { | ||
return (0, _wrap3.default)(this._connectors, (0, _extend2.default)(name, component, styles)); | ||
return (0, _wrap3.default)(this._connectors, (0, _extend2.default)(name, component, styles, this._options)); | ||
} | ||
@@ -126,0 +142,0 @@ }, { |
@@ -30,3 +30,3 @@ 'use strict'; | ||
function extendComponent(component, stylesDef) { | ||
function extendComponent(component, stylesDef, options) { | ||
var stylesResolver = _electrumTheme.Styles.build(stylesDef); | ||
@@ -48,3 +48,7 @@ return (function (_component) { | ||
value: function shouldComponentUpdate(nextProps, nextState) { | ||
return (0, _reactAddonsShallowCompare2.default)(this, nextProps, nextState); | ||
var dirty = (0, _reactAddonsShallowCompare2.default)(this, nextProps, nextState); | ||
if (options && options.log && options.log.shouldComponentUpdate) { | ||
options.log.shouldComponentUpdate(this, nextProps, nextState, dirty); | ||
} | ||
return dirty; | ||
} | ||
@@ -51,0 +55,0 @@ }, { |
@@ -28,3 +28,3 @@ 'use strict'; | ||
function extend(name, component, stylesDef) { | ||
function extend(name, component, stylesDef, options) { | ||
if (typeof component !== 'function') { | ||
@@ -39,3 +39,3 @@ throw new Error('Component ' + name + ' is not defined as a function/class'); | ||
} | ||
component = (0, _extendComponent2.default)(component, stylesDef); | ||
component = (0, _extendComponent2.default)(component, stylesDef, options); | ||
component = (0, _extendComponentDisplayName2.default)(component, name); | ||
@@ -42,0 +42,0 @@ return component; |
{ | ||
"name": "electrum", | ||
"version": "2.4.6", | ||
"version": "2.5.0", | ||
"description": "Electrum simplifies framework-agnostic declaration of React components.", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -206,1 +206,24 @@ # Electrum | ||
``` | ||
# Tracing | ||
Electrum includes basic tracing functionality, which might come in handy when | ||
live debugging wrapped components. | ||
## shouldComponentUpdate() | ||
Whenever React calls a wrapped component's `shouldComponentUpdate()`, Electrum | ||
will call the corresponding logging function: | ||
```javascript | ||
import E from 'electrum'; | ||
E.configureLog ('shouldComponentUpdate', (component, nextProps, nextState, result) => { /* ... */ }); | ||
``` | ||
The arguments are: | ||
* `component` → component instance. | ||
* `nextProps` → next properties, as provided to `shouldComponentUpdate`. | ||
* `nextState` → next state, as provided to `shouldComponentUpdate`. | ||
* `result` → result of the call to `shouldComponentUpdate`, where `true` | ||
means that the component should be rendered. |
@@ -38,2 +38,3 @@ 'use strict'; | ||
this._wrappers.forEach (x => this.use (x)); | ||
this._options = {}; | ||
} | ||
@@ -86,5 +87,19 @@ | ||
configureLog (name, spy) { | ||
if (spy) { | ||
if (typeof spy !== 'function') { | ||
throw new Error ('The spy must be a function'); | ||
} | ||
if (!this._options.log) { | ||
this._options.log = {}; | ||
} | ||
this._options.log[name] = spy; | ||
} else { | ||
delete this._options.log[name]; | ||
} | ||
} | ||
wrap (name, component, more) { | ||
const {styles} = more || {}; | ||
return wrap (this._connectors, extend (name, component, styles)); | ||
return wrap (this._connectors, extend (name, component, styles, this._options)); | ||
} | ||
@@ -91,0 +106,0 @@ } |
@@ -21,6 +21,8 @@ 'use strict'; | ||
log = log + '/Author'; | ||
return <div> | ||
<img src={this.read ('imageUrl')} /> | ||
<span>{this.read ('displayName')}</span> | ||
</div>; | ||
return ( | ||
<div> | ||
<img src={this.read ('imageUrl')} /> | ||
<span>{this.read ('displayName')}</span> | ||
</div> | ||
); | ||
} | ||
@@ -34,6 +36,8 @@ }); | ||
log = log + '/Post'; | ||
return <div> | ||
<Content {...this.link ('content')} /> | ||
<Author {...this.link ('author')} /> | ||
</div>; | ||
return ( | ||
<div> | ||
<Content {...this.link ('content')} /> | ||
<Author {...this.link ('author')} /> | ||
</div> | ||
); | ||
} | ||
@@ -71,10 +75,18 @@ }); | ||
const mountNode = document.getElementById ('root'); | ||
let spy; | ||
E.configureLog ('shouldComponentUpdate', (o, p, s, dirty) => { | ||
spy += `/${o.constructor.displayName}: ${dirty}`; | ||
}); | ||
spy = ''; | ||
log = ''; | ||
ReactDOM.render (<Post state={store.select ('blog.post-1')} />, mountNode); | ||
expect (log).to.equal ('/Post/Author'); | ||
expect (spy).to.equal (''); | ||
spy = ''; | ||
log = ''; | ||
ReactDOM.render (<Post state={store.select ('blog.post-1')} />, mountNode); | ||
expect (log).to.equal (''); | ||
expect (spy).to.equal ('/Post: false'); | ||
@@ -84,5 +96,7 @@ // Mutate the store; this will re-render <Content>, but not <Author> | ||
spy = ''; | ||
log = ''; | ||
ReactDOM.render (<Post state={store.select ('blog.post-1')} />, mountNode); | ||
expect (log).to.equal ('/Post'); | ||
expect (spy).to.equal ('/Post: true/Content: true/Author: false'); | ||
}); | ||
@@ -89,0 +103,0 @@ }); |
@@ -10,3 +10,3 @@ 'use strict'; | ||
export default function extendComponent (component, stylesDef) { | ||
export default function extendComponent (component, stylesDef, options) { | ||
const stylesResolver = Styles.build (stylesDef); | ||
@@ -19,3 +19,7 @@ return class extends component { | ||
shouldComponentUpdate (nextProps, nextState) { | ||
return shallowCompare (this, nextProps, nextState); | ||
const dirty = shallowCompare (this, nextProps, nextState); | ||
if (options && options.log && options.log.shouldComponentUpdate) { | ||
options.log.shouldComponentUpdate (this, nextProps, nextState, dirty); | ||
} | ||
return dirty; | ||
} | ||
@@ -22,0 +26,0 @@ link (id) { |
@@ -10,3 +10,3 @@ 'use strict'; | ||
export default function extend (name, component, stylesDef) { | ||
export default function extend (name, component, stylesDef, options) { | ||
if (typeof component !== 'function') { | ||
@@ -21,3 +21,3 @@ throw new Error (`Component ${name} is not defined as a function/class`); | ||
} | ||
component = extendComponent (component, stylesDef); | ||
component = extendComponent (component, stylesDef, options); | ||
component = extendComponentDisplayName (component, name); | ||
@@ -24,0 +24,0 @@ return component; |
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
121175
2267
229