From 2940df501e8c6c0deaef4159ac4ad1b25db01933 Mon Sep 17 00:00:00 2001 From: Nick Laffey Date: Mon, 19 Jun 2017 15:41:53 -0400 Subject: [PATCH 1/2] Moving _componentMap property inside the ReactJsonSchema class so that its not shared between instances. --- dist/react-json-schema.js | 20 ++++++++++---------- dist/react-json-schema.min.js | 2 +- lib/ReactJsonSchema.js | 11 +++++++---- spec/ReactJsonSchemaSpec.js | 12 ++++++++++++ 4 files changed, 30 insertions(+), 15 deletions(-) diff --git a/dist/react-json-schema.js b/dist/react-json-schema.js index 556247c..c6f8099 100644 --- a/dist/react-json-schema.js +++ b/dist/react-json-schema.js @@ -12,11 +12,11 @@ function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in ob function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -var _componentMap = null; - var ReactJsonSchema = function () { function ReactJsonSchema() { _classCallCheck(this, ReactJsonSchema); + + this._componentMap = null; } _createClass(ReactJsonSchema, [{ @@ -34,7 +34,7 @@ var ReactJsonSchema = function () { }, { key: 'parseSubSchemas', value: function parseSubSchemas() { - var subSchemas = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; + var subSchemas = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; var Components = []; var index = 0; @@ -70,11 +70,10 @@ var ReactJsonSchema = function () { }, { key: 'createComponent', value: function createComponent(schema) { - var component = schema.component; - var children = schema.children; - var text = schema.text; - - var rest = _objectWithoutProperties(schema, ['component', 'children', 'text']); + var component = schema.component, + children = schema.children, + text = schema.text, + rest = _objectWithoutProperties(schema, ['component', 'children', 'text']); var Component = this.resolveComponent(schema); var Children = typeof text !== 'undefined' ? text : this.resolveComponentChildren(schema); @@ -83,6 +82,7 @@ var ReactJsonSchema = function () { }, { key: 'resolveComponent', value: function resolveComponent(schema) { + var _componentMap = this._componentMap; var Component = null; if (schema.hasOwnProperty('component')) { if (schema.component === Object(schema.component)) { @@ -105,12 +105,12 @@ var ReactJsonSchema = function () { }, { key: 'getComponentMap', value: function getComponentMap() { - return _componentMap; + return this._componentMap; } }, { key: 'setComponentMap', value: function setComponentMap(componentMap) { - _componentMap = componentMap; + this._componentMap = componentMap; } }]); diff --git a/dist/react-json-schema.min.js b/dist/react-json-schema.min.js index 3e8e1f2..2520767 100644 --- a/dist/react-json-schema.min.js +++ b/dist/react-json-schema.min.js @@ -1 +1 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:true});var _createClass=function(){function e(e,n){for(var t=0;t=0)continue;if(!Object.prototype.hasOwnProperty.call(e,r))continue;t[r]=e[r]}return t}function _classCallCheck(e,n){if(!(e instanceof n)){throw new TypeError("Cannot call a class as a function")}}var _componentMap=null;var ReactJsonSchema=function(){function e(){_classCallCheck(this,e)}_createClass(e,[{key:"parseSchema",value:function e(n){var t=null;var r=null;if(Array.isArray(n)){r=this.parseSubSchemas(n)}else{t=this.createComponent(n)}return t||r}},{key:"parseSubSchemas",value:function e(){var n=arguments.length<=0||arguments[0]===undefined?[]:arguments[0];var t=[];var r=0;var o=true;var a=false;var c=undefined;try{for(var i=n[Symbol.iterator](),u;!(o=(u=i.next()).done);o=true){var l=u.value;l.key=typeof l.key!=="undefined"?l.key:r;t.push(this.parseSchema(l));r++}}catch(e){a=true;c=e}finally{try{if(!o&&i.return){i.return()}}finally{if(a){throw c}}}return t}},{key:"createComponent",value:function e(n){var t=n.component;var r=n.children;var o=n.text;var a=_objectWithoutProperties(n,["component","children","text"]);var c=this.resolveComponent(n);var i=typeof o!=="undefined"?o:this.resolveComponentChildren(n);return(0,_react.createElement)(c,a,i)}},{key:"resolveComponent",value:function e(n){var t=null;if(n.hasOwnProperty("component")){if(n.component===Object(n.component)){t=n.component}else if(_componentMap&&_componentMap[n.component]){t=_componentMap[n.component]}else if(_react.DOM.hasOwnProperty(n.component)){t=n.component}}else{throw new Error("ReactJsonSchema could not resolve a component due to a missing component attribute in the schema.")}return t}},{key:"resolveComponentChildren",value:function e(n){return n.hasOwnProperty("children")?this.parseSchema(n.children):[]}},{key:"getComponentMap",value:function e(){return _componentMap}},{key:"setComponentMap",value:function e(n){_componentMap=n}}]);return e}();exports.default=ReactJsonSchema; \ No newline at end of file +"use strict";Object.defineProperty(exports,"__esModule",{value:true});var _createClass=function(){function e(e,n){for(var t=0;t=0)continue;if(!Object.prototype.hasOwnProperty.call(e,r))continue;t[r]=e[r]}return t}function _classCallCheck(e,n){if(!(e instanceof n)){throw new TypeError("Cannot call a class as a function")}}var ReactJsonSchema=function(){function e(){_classCallCheck(this,e);this._componentMap=null}_createClass(e,[{key:"parseSchema",value:function e(n){var t=null;var r=null;if(Array.isArray(n)){r=this.parseSubSchemas(n)}else{t=this.createComponent(n)}return t||r}},{key:"parseSubSchemas",value:function e(){var n=arguments.length>0&&arguments[0]!==undefined?arguments[0]:[];var t=[];var r=0;var o=true;var a=false;var c=undefined;try{for(var i=n[Symbol.iterator](),u;!(o=(u=i.next()).done);o=true){var l=u.value;l.key=typeof l.key!=="undefined"?l.key:r;t.push(this.parseSchema(l));r++}}catch(e){a=true;c=e}finally{try{if(!o&&i.return){i.return()}}finally{if(a){throw c}}}return t}},{key:"createComponent",value:function e(n){var t=n.component,r=n.children,o=n.text,a=_objectWithoutProperties(n,["component","children","text"]);var c=this.resolveComponent(n);var i=typeof o!=="undefined"?o:this.resolveComponentChildren(n);return(0,_react.createElement)(c,a,i)}},{key:"resolveComponent",value:function e(n){var t=this._componentMap;var r=null;if(n.hasOwnProperty("component")){if(n.component===Object(n.component)){r=n.component}else if(t&&t[n.component]){r=t[n.component]}else if(_react.DOM.hasOwnProperty(n.component)){r=n.component}}else{throw new Error("ReactJsonSchema could not resolve a component due to a missing component attribute in the schema.")}return r}},{key:"resolveComponentChildren",value:function e(n){return n.hasOwnProperty("children")?this.parseSchema(n.children):[]}},{key:"getComponentMap",value:function e(){return this._componentMap}},{key:"setComponentMap",value:function e(n){this._componentMap=n}}]);return e}();exports.default=ReactJsonSchema; \ No newline at end of file diff --git a/lib/ReactJsonSchema.js b/lib/ReactJsonSchema.js index f411ae2..d0977f5 100644 --- a/lib/ReactJsonSchema.js +++ b/lib/ReactJsonSchema.js @@ -1,9 +1,11 @@ import { DOM, createElement } from 'react'; -let _componentMap = null; - export default class ReactJsonSchema { + constructor(){ + this._componentMap = null; + } + parseSchema(schema) { let element = null; let elements = null; @@ -34,6 +36,7 @@ export default class ReactJsonSchema { } resolveComponent(schema) { + const _componentMap = this._componentMap; let Component = null; if (schema.hasOwnProperty('component')) { if (schema.component === Object(schema.component)) { @@ -55,10 +58,10 @@ export default class ReactJsonSchema { } getComponentMap() { - return _componentMap; + return this._componentMap; } setComponentMap(componentMap) { - _componentMap = componentMap; + this._componentMap = componentMap; } } diff --git a/spec/ReactJsonSchemaSpec.js b/spec/ReactJsonSchemaSpec.js index ab0d405..6f649d1 100644 --- a/spec/ReactJsonSchemaSpec.js +++ b/spec/ReactJsonSchemaSpec.js @@ -131,4 +131,16 @@ export default describe('ReactJsonSchema', () => { expect(!!actual.length).toBe(true); }); }); + describe('when multiple instances of ReactJsonSchema are created with different componentMaps', () => { + it('getComponentMap() should return the appropriate value for each instance', () => { + const reactJsonSchema1 = new ReactJsonSchema(); + const componentMap1 = { component1: Tester }; + reactJsonSchema1.setComponentMap(componentMap1); + const reactJsonSchema2 = new ReactJsonSchema(); + const componentMap2 = { component2: Tester }; + reactJsonSchema2.setComponentMap(componentMap2); + expect(reactJsonSchema1.getComponentMap()).toEqual(componentMap1); + expect(reactJsonSchema2.getComponentMap()).toEqual(componentMap2); + }); + }); }); From 3d56c4555232a40102c3b65a1b45ce402d4755d5 Mon Sep 17 00:00:00 2001 From: Nick Laffey Date: Mon, 19 Jun 2017 16:38:59 -0400 Subject: [PATCH 2/2] Using WeakMap to make componentMap field private. --- dist/react-json-schema.js | 10 +++++----- dist/react-json-schema.min.js | 2 +- lib/ReactJsonSchema.js | 18 ++++++++---------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/dist/react-json-schema.js b/dist/react-json-schema.js index c6f8099..d21a2a9 100644 --- a/dist/react-json-schema.js +++ b/dist/react-json-schema.js @@ -12,11 +12,11 @@ function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in ob function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } +var _componentMap = new WeakMap(); + var ReactJsonSchema = function () { function ReactJsonSchema() { _classCallCheck(this, ReactJsonSchema); - - this._componentMap = null; } _createClass(ReactJsonSchema, [{ @@ -82,7 +82,7 @@ var ReactJsonSchema = function () { }, { key: 'resolveComponent', value: function resolveComponent(schema) { - var _componentMap = this._componentMap; + var _componentMap = this.getComponentMap(); var Component = null; if (schema.hasOwnProperty('component')) { if (schema.component === Object(schema.component)) { @@ -105,12 +105,12 @@ var ReactJsonSchema = function () { }, { key: 'getComponentMap', value: function getComponentMap() { - return this._componentMap; + return _componentMap.get(this); } }, { key: 'setComponentMap', value: function setComponentMap(componentMap) { - this._componentMap = componentMap; + _componentMap.set(this, componentMap); } }]); diff --git a/dist/react-json-schema.min.js b/dist/react-json-schema.min.js index 2520767..38705a8 100644 --- a/dist/react-json-schema.min.js +++ b/dist/react-json-schema.min.js @@ -1 +1 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:true});var _createClass=function(){function e(e,n){for(var t=0;t=0)continue;if(!Object.prototype.hasOwnProperty.call(e,r))continue;t[r]=e[r]}return t}function _classCallCheck(e,n){if(!(e instanceof n)){throw new TypeError("Cannot call a class as a function")}}var ReactJsonSchema=function(){function e(){_classCallCheck(this,e);this._componentMap=null}_createClass(e,[{key:"parseSchema",value:function e(n){var t=null;var r=null;if(Array.isArray(n)){r=this.parseSubSchemas(n)}else{t=this.createComponent(n)}return t||r}},{key:"parseSubSchemas",value:function e(){var n=arguments.length>0&&arguments[0]!==undefined?arguments[0]:[];var t=[];var r=0;var o=true;var a=false;var c=undefined;try{for(var i=n[Symbol.iterator](),u;!(o=(u=i.next()).done);o=true){var l=u.value;l.key=typeof l.key!=="undefined"?l.key:r;t.push(this.parseSchema(l));r++}}catch(e){a=true;c=e}finally{try{if(!o&&i.return){i.return()}}finally{if(a){throw c}}}return t}},{key:"createComponent",value:function e(n){var t=n.component,r=n.children,o=n.text,a=_objectWithoutProperties(n,["component","children","text"]);var c=this.resolveComponent(n);var i=typeof o!=="undefined"?o:this.resolveComponentChildren(n);return(0,_react.createElement)(c,a,i)}},{key:"resolveComponent",value:function e(n){var t=this._componentMap;var r=null;if(n.hasOwnProperty("component")){if(n.component===Object(n.component)){r=n.component}else if(t&&t[n.component]){r=t[n.component]}else if(_react.DOM.hasOwnProperty(n.component)){r=n.component}}else{throw new Error("ReactJsonSchema could not resolve a component due to a missing component attribute in the schema.")}return r}},{key:"resolveComponentChildren",value:function e(n){return n.hasOwnProperty("children")?this.parseSchema(n.children):[]}},{key:"getComponentMap",value:function e(){return this._componentMap}},{key:"setComponentMap",value:function e(n){this._componentMap=n}}]);return e}();exports.default=ReactJsonSchema; \ No newline at end of file +"use strict";Object.defineProperty(exports,"__esModule",{value:true});var _createClass=function(){function e(e,n){for(var t=0;t=0)continue;if(!Object.prototype.hasOwnProperty.call(e,r))continue;t[r]=e[r]}return t}function _classCallCheck(e,n){if(!(e instanceof n)){throw new TypeError("Cannot call a class as a function")}}var _componentMap=new WeakMap;var ReactJsonSchema=function(){function e(){_classCallCheck(this,e)}_createClass(e,[{key:"parseSchema",value:function e(n){var t=null;var r=null;if(Array.isArray(n)){r=this.parseSubSchemas(n)}else{t=this.createComponent(n)}return t||r}},{key:"parseSubSchemas",value:function e(){var n=arguments.length>0&&arguments[0]!==undefined?arguments[0]:[];var t=[];var r=0;var o=true;var a=false;var c=undefined;try{for(var i=n[Symbol.iterator](),u;!(o=(u=i.next()).done);o=true){var l=u.value;l.key=typeof l.key!=="undefined"?l.key:r;t.push(this.parseSchema(l));r++}}catch(e){a=true;c=e}finally{try{if(!o&&i.return){i.return()}}finally{if(a){throw c}}}return t}},{key:"createComponent",value:function e(n){var t=n.component,r=n.children,o=n.text,a=_objectWithoutProperties(n,["component","children","text"]);var c=this.resolveComponent(n);var i=typeof o!=="undefined"?o:this.resolveComponentChildren(n);return(0,_react.createElement)(c,a,i)}},{key:"resolveComponent",value:function e(n){var t=this.getComponentMap();var r=null;if(n.hasOwnProperty("component")){if(n.component===Object(n.component)){r=n.component}else if(t&&t[n.component]){r=t[n.component]}else if(_react.DOM.hasOwnProperty(n.component)){r=n.component}}else{throw new Error("ReactJsonSchema could not resolve a component due to a missing component attribute in the schema.")}return r}},{key:"resolveComponentChildren",value:function e(n){return n.hasOwnProperty("children")?this.parseSchema(n.children):[]}},{key:"getComponentMap",value:function e(){return _componentMap.get(this)}},{key:"setComponentMap",value:function e(n){_componentMap.set(this,n)}}]);return e}();exports.default=ReactJsonSchema; \ No newline at end of file diff --git a/lib/ReactJsonSchema.js b/lib/ReactJsonSchema.js index d0977f5..ede98b1 100644 --- a/lib/ReactJsonSchema.js +++ b/lib/ReactJsonSchema.js @@ -1,10 +1,8 @@ import { DOM, createElement } from 'react'; -export default class ReactJsonSchema { +const _componentMap = new WeakMap(); - constructor(){ - this._componentMap = null; - } +export default class ReactJsonSchema { parseSchema(schema) { let element = null; @@ -29,20 +27,20 @@ export default class ReactJsonSchema { } createComponent(schema) { - const { component, children, text, ...rest} = schema; + const { component, children, text, ...rest } = schema; const Component = this.resolveComponent(schema); const Children = typeof text !== 'undefined' ? text : this.resolveComponentChildren(schema); return createElement(Component, rest, Children); } resolveComponent(schema) { - const _componentMap = this._componentMap; + const componentMap = this.getComponentMap(); let Component = null; if (schema.hasOwnProperty('component')) { if (schema.component === Object(schema.component)) { Component = schema.component; - } else if (_componentMap && _componentMap[schema.component]) { - Component = _componentMap[schema.component]; + } else if (componentMap && componentMap[schema.component]) { + Component = componentMap[schema.component]; } else if (DOM.hasOwnProperty(schema.component)) { Component = schema.component; } @@ -58,10 +56,10 @@ export default class ReactJsonSchema { } getComponentMap() { - return this._componentMap; + return _componentMap.get(this); } setComponentMap(componentMap) { - this._componentMap = componentMap; + _componentMap.set(this, componentMap); } }