From bdd7d004c1f972963c1cbb6a463bc2822d464692 Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Thu, 22 Oct 2015 16:59:30 -0400 Subject: [PATCH 01/31] version 2.0 --- package.json | 35 +---- react-backbone.js | 251 ------------------------------- react-backbone.min.js | 6 - react-nested.js | 251 ------------------------------- react-nested.min.js | 6 - reactbone.js | 336 ++++++++++++++++++++++++++++++++++++++++++ reactbone.js.map | 1 + src/component-view.js | 69 +++++++++ src/createClass.js | 96 ++++++++++++ src/glue.js | 236 ----------------------------- src/main.js | 22 +++ src/view-element.js | 39 +++++ umd/backbone-head.js | 11 -- umd/copyright.js | 5 - umd/nested-head.js | 11 -- umd/tail.js | 1 - webpack.config.js | 29 ++++ 17 files changed, 600 insertions(+), 805 deletions(-) delete mode 100644 react-backbone.js delete mode 100644 react-backbone.min.js delete mode 100644 react-nested.js delete mode 100644 react-nested.min.js create mode 100644 reactbone.js create mode 100644 reactbone.js.map create mode 100644 src/component-view.js create mode 100644 src/createClass.js delete mode 100644 src/glue.js create mode 100644 src/main.js create mode 100644 src/view-element.js delete mode 100644 umd/backbone-head.js delete mode 100644 umd/copyright.js delete mode 100644 umd/nested-head.js delete mode 100644 umd/tail.js create mode 100644 webpack.config.js diff --git a/package.json b/package.json index b7ea2c6..f72af21 100644 --- a/package.json +++ b/package.json @@ -7,47 +7,28 @@ "backbone", "react" ], - "repository": { "type": "git", "url": "https://github.com/Volicon/react-backbone.glue.git" }, - "author": "Vlad Balin ", "contributors": "", - "dependencies": { "backbone": ">=1.1.2", - "react" : ">=0.13.0" + "react": "^0.14.0", + "react-dom": "^0.14.0" }, - "devDependencies": { - "uglify-js": "*" + "uglify-js": "*", + "webpack": "^1.12.2" }, - "files": [ - "react-backbone.js", - "react-nested.js", - "react-backbone.min.js", - "react-nested.min.js" + "reactbone.js" ], - "license": "MIT", - "version": "0.1.1", + "version": "0.2.0", "scripts": { - "make:backbone:win" : "type .\\umd\\copyright.js .\\umd\\backbone-head.js .\\src\\glue.js .\\umd\\tail.js > .\\react-backbone.js", - "make:nested:win" : "type .\\umd\\copyright.js .\\umd\\nested-head.js .\\src\\glue.js .\\umd\\tail.js > .\\react-nested.js", - "make:win": "npm run make:backbone:win & npm run make:nested:win", - - "minify:win": ".\\node_modules\\.bin\\uglifyjs react-nested.js --comments --compress --mangle --screw-ie8 > react-nested.min.js & .\\node_modules\\.bin\\uglifyjs .\\react-backbone.js --comments --compress --mangle --screw-ie8 > .\\react-backbone.min.js", - "build:win": "npm run make:win && npm run minify:win", - - "make:backbone" : "cat ./umd/copyright.js ./umd/backbone-head.js ./src/glue.js ./umd/tail.js > ./react-backbone.js", - "make:nested" : "cat ./umd/copyright.js ./umd/nested-head.js ./src/glue.js ./umd/tail.js > ./react-nested.js", - "make": "npm run make:backbone & npm run make:nested", - - "minify": "./node_modules/.bin/uglifyjs react-nested.js --comments --compress --mangle --screw-ie8 > react-nested.min.js & ./node_modules/.bin/uglifyjs ./react-backbone.js --comments --compress --mangle --screw-ie8 > ./react-backbone.min.js", - "build": "npm run make && npm run minify" + "build": "./node_modules/.bin/webpack" } -} \ No newline at end of file +} diff --git a/react-backbone.js b/react-backbone.js deleted file mode 100644 index ef54c84..0000000 --- a/react-backbone.js +++ /dev/null @@ -1,251 +0,0 @@ -/** - * React-Backbone.Glue 0.1.1 - * (c) 2015 Vlad Balin & Volicon - * Released under MIT @license - */ -(function( root, factory ){ - if( typeof exports === 'object' ){ - module.exports = factory( require( 'backbone' ), require( 'react' ) ); - } - else if( typeof define === 'function' && define.amd ){ - define( [ 'backbone', 'react' ], factory ); - } - else{ - root.React = factory( root.Backbone, root.React ); - } -}( this, function reactBackboneGlue( Backbone, React ){ - // Object.assign polyfill - - Object.assign || ( Object.assign = function( target, firstSource ){ - if( target == null ){ - throw new TypeError( 'Cannot convert first argument to object' ); - } - - var to = Object( target ); - for( var i = 1; i < arguments.length; i++ ){ - var nextSource = arguments[ i ]; - if( nextSource == null ){ - continue; - } - - var keysArray = Object.keys( Object( nextSource ) ); - for( var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++ ){ - var nextKey = keysArray[ nextIndex ]; - var desc = Object.getOwnPropertyDescriptor( nextSource, nextKey ); - if( desc !== void 0 && desc.enumerable ){ - to[ nextKey ] = nextSource[ nextKey ]; - } - } - } - return to; - }); - - // Wrapper for forceUpdate to be used in backbone events handlers - function forceUpdate(){ - this.forceUpdate(); - } - - var ListenToProps = { - componentDidMount : function(){ - var props = this.props, - updateOn = this.listenToProps; - - for( var prop in updateOn ){ - var emitter = props[ prop ]; - emitter && this.listenTo( emitter, updateOn[ prop ], forceUpdate ); - } - }, - - componentWillUnmount : function(){ - var props = this.props, - updateOn = this.listenToProps; - - for( var prop in updateOn ){ - var emitter = props[ prop ]; - emitter && this.stopListening( emitter ); - } - } - }; - - var ModelState = { - listenToState : 'change', - - getInitialState : function(){ - return new this.Model(); - }, - - componentDidMount : function(){ - var events = this.listenToState; - events && this.listenTo( this.state, events, forceUpdate ); - }, - - componentWillUnmount : function(){ - this.stopListening( this.state ); - this.state = null; - } - }; - - function getModelAttributes( spec ){ - var attributes = null; - - for( var i = spec.mixins.length - 1; i >= 0; i-- ){ - var mixin = spec.mixins[ i ]; - if( mixin.attributes ){ - attributes || ( attributes = {} ); - Object.assign( attributes, mixin.attributes ); - } - } - - if( spec.attributes ){ - if( attributes ){ - Object.assign( attributes, spec.attributes ); - } - else{ - attributes = spec.attributes; - } - } - - return attributes; - } - - var createClass = React.createClass; - - React.createClass = function( spec ){ - spec.mixins || ( spec.mixins = [] ); - - var attributes = getModelAttributes( spec ); - if( attributes ){ - var BaseModel = spec.Model || Backbone.Model; - spec.Model = BaseModel.extend({ defaults : attributes }); - } - - if( spec.Model ){ - spec.mixins.unshift( ModelState ); - } - - if( spec.listenToProps ){ - spec.mixins.unshift( ListenToProps ); - } - - if( spec.Model || spec.listenToProps ){ - spec.mixins.push( Backbone.Events ); - } - - var component = createClass.call( React, spec ); - component.createView = createView; - return component; - }; - - var slice = Array.prototype.slice; - - function createView(){ - var args = slice.call( arguments ); - args.unshift( this ); - return new ReactView( args ); - } - - /** - * React Backbone View Wrapper. Same as React.createElement - * but returns Backbone.View - * - * Usage: - * var View = React.createView( MyReactClass, { - * prop1 : value1, - * prop2 : value2, - * ... - * }); - */ - React.createView = function(){ - return new ReactView( arguments ); - }; - - var ReactView = Backbone.View.extend({ - initialize : function( args ){ - // memorise arguments to pass to React - this._args = args; - }, - - // cached react element... - element : null, - - setElement : function(){ - // new element instance needs to be created on next render... - if( this.element ){ - this.element = null; - this.unmountComponent(); - } - - return Backbone.View.prototype.setElement.apply( this, arguments ); - }, - - // cached instance of react component... - component : null, - - unmountComponent : function(){ - if( this.component ){ - if( this.component.trigger ){ - this.stopListening( this.component ); - } - - React.unmountComponentAtNode( this.el ); - this.component = null; - } - }, - - render : function(){ - if( !this.element ){ - this.element = React.createElement.apply( React, this._args ); - } - - var firstCall = !this.component; - this.component = React.render( this.element, this.el ); - - if( firstCall ){ - this.component.trigger && this.listenTo( this.component, 'all', function(){ - this.trigger.apply( this, arguments ); - }); - } - }, - - dispose : function(){ - this.unmountComponent(); - Backbone.View.prototype.dispose.apply( this, arguments ); - } - }); - - React.subview = React.createClass({ - displayName : 'BackboneView', - - propTypes : { - View : React.PropTypes.func.isRequired, - options : React.PropTypes.object - }, - - render : function(){ - return React.DOM.div({ - ref : 'subview', - className : this.props.className - }); - }, - - componentDidMount : function(){ - var el = this.refs.subview.getDOMNode(), - p = this.props; - - var view = this.view = p.options ? new p.View( p.options ) : new p.View(); - view.setElement( el ); - view.render(); - }, - - componentDidUpdate : function(){ - this.view.render(); - }, - - componentWillUnmount : function(){ - var view = this.view; - if( view.dispose ) view.dispose(); - } - }); - - return React; -} )); \ No newline at end of file diff --git a/react-backbone.min.js b/react-backbone.min.js deleted file mode 100644 index 3174b76..0000000 --- a/react-backbone.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * React-Backbone.Glue 0.1.1 - * (c) 2015 Vlad Balin & Volicon - * Released under MIT @license - */ -!function(t,e){"object"==typeof exports?module.exports=e(require("backbone"),require("react")):"function"==typeof define&&define.amd?define(["backbone","react"],e):t.React=e(t.Backbone,t.React)}(this,function(t,e){function n(){this.forceUpdate()}function i(t){for(var e=null,n=t.mixins.length-1;n>=0;n--){var i=t.mixins[n];i.attributes&&(e||(e={}),Object.assign(e,i.attributes))}return t.attributes&&(e?Object.assign(e,t.attributes):e=t.attributes),e}function o(){var t=u.call(arguments);return t.unshift(this),new c(t)}Object.assign||(Object.assign=function(t,e){if(null==t)throw new TypeError("Cannot convert first argument to object");for(var n=Object(t),i=1;ir;r++){var u=s[r],c=Object.getOwnPropertyDescriptor(o,u);void 0!==c&&c.enumerable&&(n[u]=o[u])}}return n});var s={componentDidMount:function(){var t=this.props,e=this.listenToProps;for(var i in e){var o=t[i];o&&this.listenTo(o,e[i],n)}},componentWillUnmount:function(){var t=this.props,e=this.listenToProps;for(var n in e){var i=t[n];i&&this.stopListening(i)}}},r={listenToState:"change",getInitialState:function(){return new this.Model},componentDidMount:function(){var t=this.listenToState;t&&this.listenTo(this.state,t,n)},componentWillUnmount:function(){this.stopListening(this.state),this.state=null}},a=e.createClass;e.createClass=function(n){n.mixins||(n.mixins=[]);var u=i(n);if(u){var c=n.Model||t.Model;n.Model=c.extend({defaults:u})}n.Model&&n.mixins.unshift(r),n.listenToProps&&n.mixins.unshift(s),(n.Model||n.listenToProps)&&n.mixins.push(t.Events);var l=a.call(e,n);return l.createView=o,l};var u=Array.prototype.slice;e.createView=function(){return new c(arguments)};var c=t.View.extend({initialize:function(t){this._args=t},element:null,setElement:function(){return this.element&&(this.element=null,this.unmountComponent()),t.View.prototype.setElement.apply(this,arguments)},component:null,unmountComponent:function(){this.component&&(this.component.trigger&&this.stopListening(this.component),e.unmountComponentAtNode(this.el),this.component=null)},render:function(){this.element||(this.element=e.createElement.apply(e,this._args));var t=!this.component;this.component=e.render(this.element,this.el),t&&this.component.trigger&&this.listenTo(this.component,"all",function(){this.trigger.apply(this,arguments)})},dispose:function(){this.unmountComponent(),t.View.prototype.dispose.apply(this,arguments)}});return e.subview=e.createClass({displayName:"BackboneView",propTypes:{View:e.PropTypes.func.isRequired,options:e.PropTypes.object},render:function(){return e.DOM.div({ref:"subview",className:this.props.className})},componentDidMount:function(){var t=this.refs.subview.getDOMNode(),e=this.props,n=this.view=e.options?new e.View(e.options):new e.View;n.setElement(t),n.render()},componentDidUpdate:function(){this.view.render()},componentWillUnmount:function(){var t=this.view;t.dispose&&t.dispose()}}),e}); diff --git a/react-nested.js b/react-nested.js deleted file mode 100644 index 393dc3f..0000000 --- a/react-nested.js +++ /dev/null @@ -1,251 +0,0 @@ -/** - * React-Backbone.Glue 0.1.1 - * (c) 2015 Vlad Balin & Volicon - * Released under MIT @license - */ -(function( root, factory ){ - if( typeof exports === 'object' ){ - module.exports = factory( require( 'nestedtypes' ), require( 'react' ) ); - } - else if( typeof define === 'function' && define.amd ){ - define( [ 'nestedtypes', 'react' ], factory ); - } - else{ - root.React = factory( root.Nested, root.React ); - } -}( this, function reactBackboneGlue( Backbone, React ){ - // Object.assign polyfill - - Object.assign || ( Object.assign = function( target, firstSource ){ - if( target == null ){ - throw new TypeError( 'Cannot convert first argument to object' ); - } - - var to = Object( target ); - for( var i = 1; i < arguments.length; i++ ){ - var nextSource = arguments[ i ]; - if( nextSource == null ){ - continue; - } - - var keysArray = Object.keys( Object( nextSource ) ); - for( var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++ ){ - var nextKey = keysArray[ nextIndex ]; - var desc = Object.getOwnPropertyDescriptor( nextSource, nextKey ); - if( desc !== void 0 && desc.enumerable ){ - to[ nextKey ] = nextSource[ nextKey ]; - } - } - } - return to; - }); - - // Wrapper for forceUpdate to be used in backbone events handlers - function forceUpdate(){ - this.forceUpdate(); - } - - var ListenToProps = { - componentDidMount : function(){ - var props = this.props, - updateOn = this.listenToProps; - - for( var prop in updateOn ){ - var emitter = props[ prop ]; - emitter && this.listenTo( emitter, updateOn[ prop ], forceUpdate ); - } - }, - - componentWillUnmount : function(){ - var props = this.props, - updateOn = this.listenToProps; - - for( var prop in updateOn ){ - var emitter = props[ prop ]; - emitter && this.stopListening( emitter ); - } - } - }; - - var ModelState = { - listenToState : 'change', - - getInitialState : function(){ - return new this.Model(); - }, - - componentDidMount : function(){ - var events = this.listenToState; - events && this.listenTo( this.state, events, forceUpdate ); - }, - - componentWillUnmount : function(){ - this.stopListening( this.state ); - this.state = null; - } - }; - - function getModelAttributes( spec ){ - var attributes = null; - - for( var i = spec.mixins.length - 1; i >= 0; i-- ){ - var mixin = spec.mixins[ i ]; - if( mixin.attributes ){ - attributes || ( attributes = {} ); - Object.assign( attributes, mixin.attributes ); - } - } - - if( spec.attributes ){ - if( attributes ){ - Object.assign( attributes, spec.attributes ); - } - else{ - attributes = spec.attributes; - } - } - - return attributes; - } - - var createClass = React.createClass; - - React.createClass = function( spec ){ - spec.mixins || ( spec.mixins = [] ); - - var attributes = getModelAttributes( spec ); - if( attributes ){ - var BaseModel = spec.Model || Backbone.Model; - spec.Model = BaseModel.extend({ defaults : attributes }); - } - - if( spec.Model ){ - spec.mixins.unshift( ModelState ); - } - - if( spec.listenToProps ){ - spec.mixins.unshift( ListenToProps ); - } - - if( spec.Model || spec.listenToProps ){ - spec.mixins.push( Backbone.Events ); - } - - var component = createClass.call( React, spec ); - component.createView = createView; - return component; - }; - - var slice = Array.prototype.slice; - - function createView(){ - var args = slice.call( arguments ); - args.unshift( this ); - return new ReactView( args ); - } - - /** - * React Backbone View Wrapper. Same as React.createElement - * but returns Backbone.View - * - * Usage: - * var View = React.createView( MyReactClass, { - * prop1 : value1, - * prop2 : value2, - * ... - * }); - */ - React.createView = function(){ - return new ReactView( arguments ); - }; - - var ReactView = Backbone.View.extend({ - initialize : function( args ){ - // memorise arguments to pass to React - this._args = args; - }, - - // cached react element... - element : null, - - setElement : function(){ - // new element instance needs to be created on next render... - if( this.element ){ - this.element = null; - this.unmountComponent(); - } - - return Backbone.View.prototype.setElement.apply( this, arguments ); - }, - - // cached instance of react component... - component : null, - - unmountComponent : function(){ - if( this.component ){ - if( this.component.trigger ){ - this.stopListening( this.component ); - } - - React.unmountComponentAtNode( this.el ); - this.component = null; - } - }, - - render : function(){ - if( !this.element ){ - this.element = React.createElement.apply( React, this._args ); - } - - var firstCall = !this.component; - this.component = React.render( this.element, this.el ); - - if( firstCall ){ - this.component.trigger && this.listenTo( this.component, 'all', function(){ - this.trigger.apply( this, arguments ); - }); - } - }, - - dispose : function(){ - this.unmountComponent(); - Backbone.View.prototype.dispose.apply( this, arguments ); - } - }); - - React.subview = React.createClass({ - displayName : 'BackboneView', - - propTypes : { - View : React.PropTypes.func.isRequired, - options : React.PropTypes.object - }, - - render : function(){ - return React.DOM.div({ - ref : 'subview', - className : this.props.className - }); - }, - - componentDidMount : function(){ - var el = this.refs.subview.getDOMNode(), - p = this.props; - - var view = this.view = p.options ? new p.View( p.options ) : new p.View(); - view.setElement( el ); - view.render(); - }, - - componentDidUpdate : function(){ - this.view.render(); - }, - - componentWillUnmount : function(){ - var view = this.view; - if( view.dispose ) view.dispose(); - } - }); - - return React; -} )); \ No newline at end of file diff --git a/react-nested.min.js b/react-nested.min.js deleted file mode 100644 index 1dabf74..0000000 --- a/react-nested.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * React-Backbone.Glue 0.1.1 - * (c) 2015 Vlad Balin & Volicon - * Released under MIT @license - */ -!function(t,e){"object"==typeof exports?module.exports=e(require("nestedtypes"),require("react")):"function"==typeof define&&define.amd?define(["nestedtypes","react"],e):t.React=e(t.Nested,t.React)}(this,function(t,e){function n(){this.forceUpdate()}function i(t){for(var e=null,n=t.mixins.length-1;n>=0;n--){var i=t.mixins[n];i.attributes&&(e||(e={}),Object.assign(e,i.attributes))}return t.attributes&&(e?Object.assign(e,t.attributes):e=t.attributes),e}function s(){var t=u.call(arguments);return t.unshift(this),new p(t)}Object.assign||(Object.assign=function(t,e){if(null==t)throw new TypeError("Cannot convert first argument to object");for(var n=Object(t),i=1;ir;r++){var u=o[r],p=Object.getOwnPropertyDescriptor(s,u);void 0!==p&&p.enumerable&&(n[u]=s[u])}}return n});var o={componentDidMount:function(){var t=this.props,e=this.listenToProps;for(var i in e){var s=t[i];s&&this.listenTo(s,e[i],n)}},componentWillUnmount:function(){var t=this.props,e=this.listenToProps;for(var n in e){var i=t[n];i&&this.stopListening(i)}}},r={listenToState:"change",getInitialState:function(){return new this.Model},componentDidMount:function(){var t=this.listenToState;t&&this.listenTo(this.state,t,n)},componentWillUnmount:function(){this.stopListening(this.state),this.state=null}},a=e.createClass;e.createClass=function(n){n.mixins||(n.mixins=[]);var u=i(n);if(u){var p=n.Model||t.Model;n.Model=p.extend({defaults:u})}n.Model&&n.mixins.unshift(r),n.listenToProps&&n.mixins.unshift(o),(n.Model||n.listenToProps)&&n.mixins.push(t.Events);var l=a.call(e,n);return l.createView=s,l};var u=Array.prototype.slice;e.createView=function(){return new p(arguments)};var p=t.View.extend({initialize:function(t){this._args=t},element:null,setElement:function(){return this.element&&(this.element=null,this.unmountComponent()),t.View.prototype.setElement.apply(this,arguments)},component:null,unmountComponent:function(){this.component&&(this.component.trigger&&this.stopListening(this.component),e.unmountComponentAtNode(this.el),this.component=null)},render:function(){this.element||(this.element=e.createElement.apply(e,this._args));var t=!this.component;this.component=e.render(this.element,this.el),t&&this.component.trigger&&this.listenTo(this.component,"all",function(){this.trigger.apply(this,arguments)})},dispose:function(){this.unmountComponent(),t.View.prototype.dispose.apply(this,arguments)}});return e.subview=e.createClass({displayName:"BackboneView",propTypes:{View:e.PropTypes.func.isRequired,options:e.PropTypes.object},render:function(){return e.DOM.div({ref:"subview",className:this.props.className})},componentDidMount:function(){var t=this.refs.subview.getDOMNode(),e=this.props,n=this.view=e.options?new e.View(e.options):new e.View;n.setElement(t),n.render()},componentDidUpdate:function(){this.view.render()},componentWillUnmount:function(){var t=this.view;t.dispose&&t.dispose()}}),e}); diff --git a/reactbone.js b/reactbone.js new file mode 100644 index 0000000..4664984 --- /dev/null +++ b/reactbone.js @@ -0,0 +1,336 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(require("react"), require("react-dom")); + else if(typeof define === 'function' && define.amd) + define(["react", "react-dom"], factory); + else if(typeof exports === 'object') + exports["React"] = factory(require("react"), require("react-dom")); + else + root["React"] = factory(root["React"], root["ReactDOM"]); +})(this, function(__WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_3__) { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; +/******/ +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.loaded = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(module) {var React = __webpack_require__( 2 ), + ReactDOM = __webpack_require__( 3 ); + + var NestedReact = module.export = Object.create( React ); + + NestedReact.use = function( Backbone ){ + // listenToProps, listenToState, model, attributes, Model + NestedReact.createClass = __webpack_require__( 4 ).use( Backbone ); + + // React component for attaching views + NestedReact.subview = __webpack_require__( 6 ).use( Backbone ); + + // Extend react components to have jquery accessors + var BaseComponent = React.createClass({ render : function(){} }).type, + $ = Backbone.$; + + Object.defineProperties( BaseComponent.prototype, { + el : { get : function(){ return ReactDOM.findDOMNode( this ); } }, + $el : { get : function(){ return $( this.el ); } }, + $ : { value : function( sel ){ return this.$el.find( sel ); } } + }); + } + + /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1)(module))) + +/***/ }, +/* 1 */ +/***/ function(module, exports) { + + module.exports = function(module) { + if(!module.webpackPolyfill) { + module.deprecate = function() {}; + module.paths = []; + // module.parent = undefined by default + module.children = []; + module.webpackPolyfill = 1; + } + return module; + } + + +/***/ }, +/* 2 */ +/***/ function(module, exports) { + + module.exports = __WEBPACK_EXTERNAL_MODULE_2__; + +/***/ }, +/* 3 */ +/***/ function(module, exports) { + + module.exports = __WEBPACK_EXTERNAL_MODULE_3__; + +/***/ }, +/* 4 */ +/***/ function(module, exports, __webpack_require__) { + + var React = __webpack_require__( 2 ), + ReactDOM = __webpack_require__( 3 ); + + function assign( dest, source ){ + for( var i in source ) dest[ i ] = source[ i ]; + } + + exports.use = function( Backbone ){ + var ComponentView = __webpack_require__( 5 ).use( Backbone ); + + function forceUpdate(){ + this.forceUpdate(); + } + + var Events = _.extend({ + componentWillUnmount : function(){ + this.stopListening(); + } + }, Backbone.Events ); + + var ListenToProps = { + componentDidMount : function(){ + var props = this.props, + updateOn = this.listenToProps; + + for( var prop in updateOn ){ + var emitter = props[ prop ]; + emitter && this.listenTo( emitter, updateOn[ prop ], forceUpdate ); + } + } + }; + + var ModelState = { + listenToState : 'change', + model : null, + + getInitialState : function(){ + return this.model = new this.Model(); + }, + + componentDidMount : function(){ + var events = this.listenToState; + events && this.listenTo( this.state, events, forceUpdate ); + }, + + componentWillUnmount : function(){ + this.state.stopListening(); + } + }; + + function createClass( spec ){ + var mixins = spec.mixins || ( spec.mixins = [] ); + + var attributes = getModelAttributes( spec ); + if( attributes ){ + var BaseModel = spec.Model || Backbone.Model; + spec.Model = BaseModel.extend({ defaults : attributes }); + } + + if( spec.Model ) mixins.push( ModelState ); + + if( spec.listenToProps ) mixins.unshift( ListenToProps ); + + mixins.push( Events ); + + var component = React.createClass( spec ); + component.View = ComponentView.extend({ component : component }); + + return component; + }; + + function getModelAttributes( spec ){ + var attributes = null; + + for( var i = spec.mixins.length - 1; i >= 0; i-- ){ + var mixin = spec.mixins[ i ]; + if( mixin.attributes ){ + attributes || ( attributes = {} ); + assign( attributes, mixin.attributes ); + } + } + + if( spec.attributes ){ + if( attributes ){ + assign( attributes, spec.attributes ); + } + else{ + attributes = spec.attributes; + } + } + + return attributes; + } + + return createClass; + } + + +/***/ }, +/* 5 */ +/***/ function(module, exports, __webpack_require__) { + + var React = __webpack_require__( 2 ), + ReactDOM = __webpack_require__( 3 ); + + module.exports.use = function( Backbone ){ + var View = Backbone.View, + dispose = View.prototype.dispose || function(){}, + setElement = View.prototype.setElement; + + var ComponentView = View.extend({ + reactClass : null, + props : {}, + element : null, + + initialize : function( props ){ + // memorise arguments to pass to React + this.options = props || {}; + this.element = React.createElement( this.reactClass, this.options ); + }, + + setElement : function(){ + var $content = this.$el.children().detach(), + res = setElement.apply( this, arguments ); + + this.$el.append( $content ); + return res; + }, + + // cached instance of react component... + component : null, + + render : function(){ + var component = ReactDOM.render( this.element, this.el ); + + if( !this.component ){ + if( component && component.trigger ){ + // bubble up backbone events, if any + this.listenTo( component, 'all', function(){ + this.trigger.apply( this, arguments ); + }); + } + + this.component = component; + } + }, + + unmountComponent : function(){ + if( this.component && this.component.trigger ){ + this.stopListening( this.component ); + } + + ReactDOM.unmountComponentAtNode( this.el ); + this.component = null; + }, + + dispose : function(){ + this.unmountComponent(); + return dispose.apply( this, arguments ); + } + }); + + Object.defineProperty( ComponentView.prototype, 'model', { + get : function(){ + this.component || this.render(); + return this.component && this.component.model; + } + }); + + return ComponentView; + }; + + +/***/ }, +/* 6 */ +/***/ function(module, exports, __webpack_require__) { + + var React = __webpack_require__( 2 ), + ReactDOM = __webpack_require__( 3 ); + + module.exports = React.createClass({ + displayName : 'BackboneView', + + propTypes : { + View : React.PropTypes.func.isRequired, + options : React.PropTypes.object + }, + + render : function(){ + return ReactDOM.div({ + ref : 'subview', + className : this.props.className + }); + }, + + componentDidMount : function(){ + var el = this.refs.subview, + p = this.props; + + var view = this.view = p.options ? new p.View( p.options ) : new p.View(); + + if( el.getDOMNode ) el = el.getDOMNode(); + + el.appendChild( view.el ); + view.render(); + }, + + componentDidUpdate : function(){ + this.view.render(); + }, + + componentWillUnmount : function(){ + var view = this.view; + if( view.dispose ) view.dispose(); + } + }); + + +/***/ } +/******/ ]) +}); +; +//# sourceMappingURL=reactbone.js.map \ No newline at end of file diff --git a/reactbone.js.map b/reactbone.js.map new file mode 100644 index 0000000..6009253 --- /dev/null +++ b/reactbone.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap 60364c2c7a6755999b38","webpack:///./src/main.js","webpack:///(webpack)/buildin/module.js","webpack:///external {\"commonjs\":\"react\",\"commonjs2\":\"react\",\"amd\":\"react\",\"root\":\"React\"}","webpack:///external {\"commonjs\":\"react-dom\",\"commonjs2\":\"react-dom\",\"amd\":\"react-dom\",\"root\":\"ReactDOM\"}","webpack:///./src/createClass.js","webpack:///./src/component-view.js","webpack:///./src/view-element.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,4CAA2C,sBAAsB,EAAE;AACnE;;AAEA;AACA,eAAc,kBAAkB,qCAAqC,EAAE,EAAE;AACzE,gBAAe,kBAAkB,qBAAqB,EAAE,EAAE;AAC1D,cAAa,yBAAyB,6BAA6B,EAAE;AACrE,MAAK;AACL;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACTA,gD;;;;;;ACAA,gD;;;;;;ACAA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,4CAA2C,wBAAwB;AACnE;;AAEA;;AAEA;;AAEA;;AAEA;AACA,gDAA+C,wBAAwB;;AAEvE;AACA;;AAEA;AACA;;AAEA,6CAA4C,QAAQ;AACpD;AACA;AACA,gDAA+C;AAC/C;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;AC/FA;AACA;;AAEA;AACA;AACA,uDAAsD;AACtD;;AAEA;AACA;AACA,sBAAqB;AACrB;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,oBAAmB;AACnB;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;;;;;;ACpEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,UAAS;AACT,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,EAAC","file":"./reactbone.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"react\"), require(\"react-dom\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"react\", \"react-dom\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"React\"] = factory(require(\"react\"), require(\"react-dom\"));\n\telse\n\t\troot[\"React\"] = factory(root[\"React\"], root[\"ReactDOM\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_3__) {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 60364c2c7a6755999b38\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nvar NestedReact = module.export = Object.create( React );\r\n\r\nNestedReact.use = function( Backbone ){\r\n // listenToProps, listenToState, model, attributes, Model\r\n NestedReact.createClass = require( './createClass' ).use( Backbone );\r\n\r\n // React component for attaching views\r\n NestedReact.subview = require( './view-element' ).use( Backbone );\r\n\r\n // Extend react components to have jquery accessors\r\n var BaseComponent = React.createClass({ render : function(){} }).type,\r\n $ = Backbone.$;\r\n\r\n Object.defineProperties( BaseComponent.prototype, {\r\n el : { get : function(){ return ReactDOM.findDOMNode( this ); } },\r\n $el : { get : function(){ return $( this.el ); } },\r\n $ : { value : function( sel ){ return this.$el.find( sel ); } }\r\n });\r\n}\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/main.js\n ** module id = 0\n ** module chunks = 0\n **/","module.exports = function(module) {\r\n\tif(!module.webpackPolyfill) {\r\n\t\tmodule.deprecate = function() {};\r\n\t\tmodule.paths = [];\r\n\t\t// module.parent = undefined by default\r\n\t\tmodule.children = [];\r\n\t\tmodule.webpackPolyfill = 1;\r\n\t}\r\n\treturn module;\r\n}\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** (webpack)/buildin/module.js\n ** module id = 1\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_2__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external {\"commonjs\":\"react\",\"commonjs2\":\"react\",\"amd\":\"react\",\"root\":\"React\"}\n ** module id = 2\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_3__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external {\"commonjs\":\"react-dom\",\"commonjs2\":\"react-dom\",\"amd\":\"react-dom\",\"root\":\"ReactDOM\"}\n ** module id = 3\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nfunction assign( dest, source ){\r\n for( var i in source ) dest[ i ] = source[ i ];\r\n}\r\n\r\nexports.use = function( Backbone ){\r\n var ComponentView = require( './component-view' ).use( Backbone );\r\n\r\n function forceUpdate(){\r\n this.forceUpdate();\r\n }\r\n\r\n var Events = _.extend({\r\n componentWillUnmount : function(){\r\n this.stopListening();\r\n }\r\n }, Backbone.Events );\r\n\r\n var ListenToProps = {\r\n componentDidMount : function(){\r\n var props = this.props,\r\n updateOn = this.listenToProps;\r\n\r\n for( var prop in updateOn ){\r\n var emitter = props[ prop ];\r\n emitter && this.listenTo( emitter, updateOn[ prop ], forceUpdate );\r\n }\r\n }\r\n };\r\n\r\n var ModelState = {\r\n listenToState : 'change',\r\n model : null,\r\n\r\n getInitialState : function(){\r\n return this.model = new this.Model();\r\n },\r\n\r\n componentDidMount : function(){\r\n var events = this.listenToState;\r\n events && this.listenTo( this.state, events, forceUpdate );\r\n },\r\n\r\n componentWillUnmount : function(){\r\n this.state.stopListening();\r\n }\r\n };\r\n\r\n function createClass( spec ){\r\n var mixins = spec.mixins || ( spec.mixins = [] );\r\n\r\n var attributes = getModelAttributes( spec );\r\n if( attributes ){\r\n var BaseModel = spec.Model || Backbone.Model;\r\n spec.Model = BaseModel.extend({ defaults : attributes });\r\n }\r\n\r\n if( spec.Model ) mixins.push( ModelState );\r\n\r\n if( spec.listenToProps ) mixins.unshift( ListenToProps );\r\n\r\n mixins.push( Events );\r\n\r\n var component = React.createClass( spec );\r\n component.View = ComponentView.extend({ component : component });\r\n\r\n return component;\r\n };\r\n\r\n function getModelAttributes( spec ){\r\n var attributes = null;\r\n\r\n for( var i = spec.mixins.length - 1; i >= 0; i-- ){\r\n var mixin = spec.mixins[ i ];\r\n if( mixin.attributes ){\r\n attributes || ( attributes = {} );\r\n assign( attributes, mixin.attributes );\r\n }\r\n }\r\n\r\n if( spec.attributes ){\r\n if( attributes ){\r\n assign( attributes, spec.attributes );\r\n }\r\n else{\r\n attributes = spec.attributes;\r\n }\r\n }\r\n\r\n return attributes;\r\n }\r\n\r\n return createClass;\r\n}\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/createClass.js\n ** module id = 4\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nmodule.exports.use = function( Backbone ){\r\n var View = Backbone.View,\r\n dispose = View.prototype.dispose || function(){},\r\n setElement = View.prototype.setElement;\r\n\r\n var ComponentView = View.extend({\r\n reactClass : null,\r\n props : {},\r\n element : null,\r\n\r\n initialize : function( props ){\r\n // memorise arguments to pass to React\r\n this.options = props || {};\r\n this.element = React.createElement( this.reactClass, this.options );\r\n },\r\n\r\n setElement : function(){\r\n var $content = this.$el.children().detach(),\r\n res = setElement.apply( this, arguments );\r\n\r\n this.$el.append( $content );\r\n return res;\r\n },\r\n\r\n // cached instance of react component...\r\n component : null,\r\n\r\n render : function(){\r\n var component = ReactDOM.render( this.element, this.el );\r\n\r\n if( !this.component ){\r\n if( component && component.trigger ){\r\n // bubble up backbone events, if any\r\n this.listenTo( component, 'all', function(){\r\n this.trigger.apply( this, arguments );\r\n });\r\n }\r\n\r\n this.component = component;\r\n }\r\n },\r\n\r\n unmountComponent : function(){\r\n if( this.component && this.component.trigger ){\r\n this.stopListening( this.component );\r\n }\r\n\r\n ReactDOM.unmountComponentAtNode( this.el );\r\n this.component = null;\r\n },\r\n\r\n dispose : function(){\r\n this.unmountComponent();\r\n return dispose.apply( this, arguments );\r\n }\r\n });\r\n\r\n Object.defineProperty( ComponentView.prototype, 'model', {\r\n get : function(){\r\n this.component || this.render();\r\n return this.component && this.component.model;\r\n }\r\n });\r\n\r\n return ComponentView;\r\n};\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/component-view.js\n ** module id = 5\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nmodule.exports = React.createClass({\r\n displayName : 'BackboneView',\r\n\r\n propTypes : {\r\n View : React.PropTypes.func.isRequired,\r\n options : React.PropTypes.object\r\n },\r\n\r\n render : function(){\r\n return ReactDOM.div({\r\n ref : 'subview',\r\n className : this.props.className\r\n });\r\n },\r\n\r\n componentDidMount : function(){\r\n var el = this.refs.subview,\r\n p = this.props;\r\n\r\n var view = this.view = p.options ? new p.View( p.options ) : new p.View();\r\n\r\n if( el.getDOMNode ) el = el.getDOMNode();\r\n\r\n el.appendChild( view.el );\r\n view.render();\r\n },\r\n\r\n componentDidUpdate : function(){\r\n this.view.render();\r\n },\r\n\r\n componentWillUnmount : function(){\r\n var view = this.view;\r\n if( view.dispose ) view.dispose();\r\n }\r\n});\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/view-element.js\n ** module id = 6\n ** module chunks = 0\n **/"],"sourceRoot":""} \ No newline at end of file diff --git a/src/component-view.js b/src/component-view.js new file mode 100644 index 0000000..9c5d22d --- /dev/null +++ b/src/component-view.js @@ -0,0 +1,69 @@ +var React = require( 'react' ), + ReactDOM = require( 'react-dom' ); + +module.exports.use = function( Backbone ){ + var View = Backbone.View, + dispose = View.prototype.dispose || function(){}, + setElement = View.prototype.setElement; + + var ComponentView = View.extend({ + reactClass : null, + props : {}, + element : null, + + initialize : function( props ){ + // memorise arguments to pass to React + this.options = props || {}; + this.element = React.createElement( this.reactClass, this.options ); + }, + + setElement : function(){ + var $content = this.$el.children().detach(), + res = setElement.apply( this, arguments ); + + this.$el.append( $content ); + return res; + }, + + // cached instance of react component... + component : null, + + render : function(){ + var component = ReactDOM.render( this.element, this.el ); + + if( !this.component ){ + if( component && component.trigger ){ + // bubble up backbone events, if any + this.listenTo( component, 'all', function(){ + this.trigger.apply( this, arguments ); + }); + } + + this.component = component; + } + }, + + unmountComponent : function(){ + if( this.component && this.component.trigger ){ + this.stopListening( this.component ); + } + + ReactDOM.unmountComponentAtNode( this.el ); + this.component = null; + }, + + dispose : function(){ + this.unmountComponent(); + return dispose.apply( this, arguments ); + } + }); + + Object.defineProperty( ComponentView.prototype, 'model', { + get : function(){ + this.component || this.render(); + return this.component && this.component.model; + } + }); + + return ComponentView; +}; diff --git a/src/createClass.js b/src/createClass.js new file mode 100644 index 0000000..5b53f3c --- /dev/null +++ b/src/createClass.js @@ -0,0 +1,96 @@ +var React = require( 'react' ), + ReactDOM = require( 'react-dom' ); + +function assign( dest, source ){ + for( var i in source ) dest[ i ] = source[ i ]; +} + +exports.use = function( Backbone ){ + var ComponentView = require( './component-view' ).use( Backbone ); + + function forceUpdate(){ + this.forceUpdate(); + } + + var Events = _.extend({ + componentWillUnmount : function(){ + this.stopListening(); + } + }, Backbone.Events ); + + var ListenToProps = { + componentDidMount : function(){ + var props = this.props, + updateOn = this.listenToProps; + + for( var prop in updateOn ){ + var emitter = props[ prop ]; + emitter && this.listenTo( emitter, updateOn[ prop ], forceUpdate ); + } + } + }; + + var ModelState = { + listenToState : 'change', + model : null, + + getInitialState : function(){ + return this.model = new this.Model(); + }, + + componentDidMount : function(){ + var events = this.listenToState; + events && this.listenTo( this.state, events, forceUpdate ); + }, + + componentWillUnmount : function(){ + this.state.stopListening(); + } + }; + + function createClass( spec ){ + var mixins = spec.mixins || ( spec.mixins = [] ); + + var attributes = getModelAttributes( spec ); + if( attributes ){ + var BaseModel = spec.Model || Backbone.Model; + spec.Model = BaseModel.extend({ defaults : attributes }); + } + + if( spec.Model ) mixins.push( ModelState ); + + if( spec.listenToProps ) mixins.unshift( ListenToProps ); + + mixins.push( Events ); + + var component = React.createClass( spec ); + component.View = ComponentView.extend({ component : component }); + + return component; + }; + + function getModelAttributes( spec ){ + var attributes = null; + + for( var i = spec.mixins.length - 1; i >= 0; i-- ){ + var mixin = spec.mixins[ i ]; + if( mixin.attributes ){ + attributes || ( attributes = {} ); + assign( attributes, mixin.attributes ); + } + } + + if( spec.attributes ){ + if( attributes ){ + assign( attributes, spec.attributes ); + } + else{ + attributes = spec.attributes; + } + } + + return attributes; + } + + return createClass; +} diff --git a/src/glue.js b/src/glue.js deleted file mode 100644 index b0fb62c..0000000 --- a/src/glue.js +++ /dev/null @@ -1,236 +0,0 @@ -function reactBackboneGlue( Backbone, React ){ - // Object.assign polyfill - - Object.assign || ( Object.assign = function( target, firstSource ){ - if( target == null ){ - throw new TypeError( 'Cannot convert first argument to object' ); - } - - var to = Object( target ); - for( var i = 1; i < arguments.length; i++ ){ - var nextSource = arguments[ i ]; - if( nextSource == null ){ - continue; - } - - var keysArray = Object.keys( Object( nextSource ) ); - for( var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++ ){ - var nextKey = keysArray[ nextIndex ]; - var desc = Object.getOwnPropertyDescriptor( nextSource, nextKey ); - if( desc !== void 0 && desc.enumerable ){ - to[ nextKey ] = nextSource[ nextKey ]; - } - } - } - return to; - }); - - // Wrapper for forceUpdate to be used in backbone events handlers - function forceUpdate(){ - this.forceUpdate(); - } - - var ListenToProps = { - componentDidMount : function(){ - var props = this.props, - updateOn = this.listenToProps; - - for( var prop in updateOn ){ - var emitter = props[ prop ]; - emitter && this.listenTo( emitter, updateOn[ prop ], forceUpdate ); - } - }, - - componentWillUnmount : function(){ - var props = this.props, - updateOn = this.listenToProps; - - for( var prop in updateOn ){ - var emitter = props[ prop ]; - emitter && this.stopListening( emitter ); - } - } - }; - - var ModelState = { - listenToState : 'change', - - getInitialState : function(){ - return new this.Model(); - }, - - componentDidMount : function(){ - var events = this.listenToState; - events && this.listenTo( this.state, events, forceUpdate ); - }, - - componentWillUnmount : function(){ - this.stopListening( this.state ); - this.state = null; - } - }; - - function getModelAttributes( spec ){ - var attributes = null; - - for( var i = spec.mixins.length - 1; i >= 0; i-- ){ - var mixin = spec.mixins[ i ]; - if( mixin.attributes ){ - attributes || ( attributes = {} ); - Object.assign( attributes, mixin.attributes ); - } - } - - if( spec.attributes ){ - if( attributes ){ - Object.assign( attributes, spec.attributes ); - } - else{ - attributes = spec.attributes; - } - } - - return attributes; - } - - var createClass = React.createClass; - - React.createClass = function( spec ){ - spec.mixins || ( spec.mixins = [] ); - - var attributes = getModelAttributes( spec ); - if( attributes ){ - var BaseModel = spec.Model || Backbone.Model; - spec.Model = BaseModel.extend({ defaults : attributes }); - } - - if( spec.Model ){ - spec.mixins.unshift( ModelState ); - } - - if( spec.listenToProps ){ - spec.mixins.unshift( ListenToProps ); - } - - if( spec.Model || spec.listenToProps ){ - spec.mixins.push( Backbone.Events ); - } - - var component = createClass.call( React, spec ); - component.createView = createView; - return component; - }; - - var slice = Array.prototype.slice; - - function createView(){ - var args = slice.call( arguments ); - args.unshift( this ); - return new ReactView( args ); - } - - /** - * React Backbone View Wrapper. Same as React.createElement - * but returns Backbone.View - * - * Usage: - * var View = React.createView( MyReactClass, { - * prop1 : value1, - * prop2 : value2, - * ... - * }); - */ - React.createView = function(){ - return new ReactView( arguments ); - }; - - var ReactView = Backbone.View.extend({ - initialize : function( args ){ - // memorise arguments to pass to React - this._args = args; - }, - - // cached react element... - element : null, - - setElement : function(){ - // new element instance needs to be created on next render... - if( this.element ){ - this.element = null; - this.unmountComponent(); - } - - return Backbone.View.prototype.setElement.apply( this, arguments ); - }, - - // cached instance of react component... - component : null, - - unmountComponent : function(){ - if( this.component ){ - if( this.component.trigger ){ - this.stopListening( this.component ); - } - - React.unmountComponentAtNode( this.el ); - this.component = null; - } - }, - - render : function(){ - if( !this.element ){ - this.element = React.createElement.apply( React, this._args ); - } - - var firstCall = !this.component; - this.component = React.render( this.element, this.el ); - - if( firstCall ){ - this.component.trigger && this.listenTo( this.component, 'all', function(){ - this.trigger.apply( this, arguments ); - }); - } - }, - - dispose : function(){ - this.unmountComponent(); - Backbone.View.prototype.dispose.apply( this, arguments ); - } - }); - - React.subview = React.createClass({ - displayName : 'BackboneView', - - propTypes : { - View : React.PropTypes.func.isRequired, - options : React.PropTypes.object - }, - - render : function(){ - return React.DOM.div({ - ref : 'subview', - className : this.props.className - }); - }, - - componentDidMount : function(){ - var el = this.refs.subview.getDOMNode(), - p = this.props; - - var view = this.view = p.options ? new p.View( p.options ) : new p.View(); - view.setElement( el ); - view.render(); - }, - - componentDidUpdate : function(){ - this.view.render(); - }, - - componentWillUnmount : function(){ - var view = this.view; - if( view.dispose ) view.dispose(); - } - }); - - return React; -} \ No newline at end of file diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..1450f8a --- /dev/null +++ b/src/main.js @@ -0,0 +1,22 @@ +var React = require( 'react' ), + ReactDOM = require( 'react-dom' ); + +var NestedReact = module.export = Object.create( React ); + +NestedReact.use = function( Backbone ){ + // listenToProps, listenToState, model, attributes, Model + NestedReact.createClass = require( './createClass' ).use( Backbone ); + + // React component for attaching views + NestedReact.subview = require( './view-element' ).use( Backbone ); + + // Extend react components to have jquery accessors + var BaseComponent = React.createClass({ render : function(){} }).type, + $ = Backbone.$; + + Object.defineProperties( BaseComponent.prototype, { + el : { get : function(){ return ReactDOM.findDOMNode( this ); } }, + $el : { get : function(){ return $( this.el ); } }, + $ : { value : function( sel ){ return this.$el.find( sel ); } } + }); +} diff --git a/src/view-element.js b/src/view-element.js new file mode 100644 index 0000000..5eda71f --- /dev/null +++ b/src/view-element.js @@ -0,0 +1,39 @@ +var React = require( 'react' ), + ReactDOM = require( 'react-dom' ); + +module.exports = React.createClass({ + displayName : 'BackboneView', + + propTypes : { + View : React.PropTypes.func.isRequired, + options : React.PropTypes.object + }, + + render : function(){ + return ReactDOM.div({ + ref : 'subview', + className : this.props.className + }); + }, + + componentDidMount : function(){ + var el = this.refs.subview, + p = this.props; + + var view = this.view = p.options ? new p.View( p.options ) : new p.View(); + + if( el.getDOMNode ) el = el.getDOMNode(); + + el.appendChild( view.el ); + view.render(); + }, + + componentDidUpdate : function(){ + this.view.render(); + }, + + componentWillUnmount : function(){ + var view = this.view; + if( view.dispose ) view.dispose(); + } +}); diff --git a/umd/backbone-head.js b/umd/backbone-head.js deleted file mode 100644 index 2e606e5..0000000 --- a/umd/backbone-head.js +++ /dev/null @@ -1,11 +0,0 @@ -(function( root, factory ){ - if( typeof exports === 'object' ){ - module.exports = factory( require( 'backbone' ), require( 'react' ) ); - } - else if( typeof define === 'function' && define.amd ){ - define( [ 'backbone', 'react' ], factory ); - } - else{ - root.React = factory( root.Backbone, root.React ); - } -}( this, \ No newline at end of file diff --git a/umd/copyright.js b/umd/copyright.js deleted file mode 100644 index ea7273c..0000000 --- a/umd/copyright.js +++ /dev/null @@ -1,5 +0,0 @@ -/** - * React-Backbone.Glue 0.1.1 - * (c) 2015 Vlad Balin & Volicon - * Released under MIT @license - */ diff --git a/umd/nested-head.js b/umd/nested-head.js deleted file mode 100644 index 416f351..0000000 --- a/umd/nested-head.js +++ /dev/null @@ -1,11 +0,0 @@ -(function( root, factory ){ - if( typeof exports === 'object' ){ - module.exports = factory( require( 'nestedtypes' ), require( 'react' ) ); - } - else if( typeof define === 'function' && define.amd ){ - define( [ 'nestedtypes', 'react' ], factory ); - } - else{ - root.React = factory( root.Nested, root.React ); - } -}( this, \ No newline at end of file diff --git a/umd/tail.js b/umd/tail.js deleted file mode 100644 index e0f7d5d..0000000 --- a/umd/tail.js +++ /dev/null @@ -1 +0,0 @@ - )); \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..2402de7 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,29 @@ +module.exports = { + entry: "./src/main", + + output : { + filename : './reactbone.js', + library : "React", + libraryTarget : 'umd' + }, + + devtool : 'source-map', + + externals : [ + { + 'react' : { + commonjs : 'react', + commonjs2 : 'react', + amd : 'react', + root : 'React' + }, + + 'react-dom' : { + commonjs : 'react-dom', + commonjs2 : 'react-dom', + amd : 'react-dom', + root : 'ReactDOM' + } + } + ] +}; From ebf9dfb89218eefac981e49cb65d4460c98a13fa Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Thu, 22 Oct 2015 17:02:55 -0400 Subject: [PATCH 02/31] changed naming --- package.json | 13 ++++++------- reactbone.js => react-bone.js | 2 +- react-bone.js.map | 1 + reactbone.js.map | 1 - webpack.config.js | 2 +- 5 files changed, 9 insertions(+), 10 deletions(-) rename reactbone.js => react-bone.js (99%) create mode 100644 react-bone.js.map delete mode 100644 reactbone.js.map diff --git a/package.json b/package.json index f72af21..b8aa881 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "react-backbone.glue", - "main": "react-backbone.js", + "name": "react-bone", + "main": "react-bone.js", "description": "Essential tool for migration to React in large Backbone application", "homepage": "https://github.com/Volicon/react-backbone.glue", "keywords": [ @@ -13,18 +13,17 @@ }, "author": "Vlad Balin ", "contributors": "", + "dependencies": { - "backbone": ">=1.1.2", "react": "^0.14.0", "react-dom": "^0.14.0" }, + "devDependencies": { - "uglify-js": "*", "webpack": "^1.12.2" }, - "files": [ - "reactbone.js" - ], + + "files": [ "react-bone.js" ], "license": "MIT", "version": "0.2.0", diff --git a/reactbone.js b/react-bone.js similarity index 99% rename from reactbone.js rename to react-bone.js index 4664984..b42b585 100644 --- a/reactbone.js +++ b/react-bone.js @@ -333,4 +333,4 @@ return /******/ (function(modules) { // webpackBootstrap /******/ ]) }); ; -//# sourceMappingURL=reactbone.js.map \ No newline at end of file +//# sourceMappingURL=react-bone.js.map \ No newline at end of file diff --git a/react-bone.js.map b/react-bone.js.map new file mode 100644 index 0000000..18a63c1 --- /dev/null +++ b/react-bone.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap 4b7b1008733b88d02c92","webpack:///./src/main.js","webpack:///(webpack)/buildin/module.js","webpack:///external {\"commonjs\":\"react\",\"commonjs2\":\"react\",\"amd\":\"react\",\"root\":\"React\"}","webpack:///external {\"commonjs\":\"react-dom\",\"commonjs2\":\"react-dom\",\"amd\":\"react-dom\",\"root\":\"ReactDOM\"}","webpack:///./src/createClass.js","webpack:///./src/component-view.js","webpack:///./src/view-element.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,4CAA2C,sBAAsB,EAAE;AACnE;;AAEA;AACA,eAAc,kBAAkB,qCAAqC,EAAE,EAAE;AACzE,gBAAe,kBAAkB,qBAAqB,EAAE,EAAE;AAC1D,cAAa,yBAAyB,6BAA6B,EAAE;AACrE,MAAK;AACL;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACTA,gD;;;;;;ACAA,gD;;;;;;ACAA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,4CAA2C,wBAAwB;AACnE;;AAEA;;AAEA;;AAEA;;AAEA;AACA,gDAA+C,wBAAwB;;AAEvE;AACA;;AAEA;AACA;;AAEA,6CAA4C,QAAQ;AACpD;AACA;AACA,gDAA+C;AAC/C;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;AC/FA;AACA;;AAEA;AACA;AACA,uDAAsD;AACtD;;AAEA;AACA;AACA,sBAAqB;AACrB;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,oBAAmB;AACnB;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;;;;;;ACpEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,UAAS;AACT,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,EAAC","file":"./react-bone.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"react\"), require(\"react-dom\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"react\", \"react-dom\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"React\"] = factory(require(\"react\"), require(\"react-dom\"));\n\telse\n\t\troot[\"React\"] = factory(root[\"React\"], root[\"ReactDOM\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_3__) {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 4b7b1008733b88d02c92\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nvar NestedReact = module.export = Object.create( React );\r\n\r\nNestedReact.use = function( Backbone ){\r\n // listenToProps, listenToState, model, attributes, Model\r\n NestedReact.createClass = require( './createClass' ).use( Backbone );\r\n\r\n // React component for attaching views\r\n NestedReact.subview = require( './view-element' ).use( Backbone );\r\n\r\n // Extend react components to have jquery accessors\r\n var BaseComponent = React.createClass({ render : function(){} }).type,\r\n $ = Backbone.$;\r\n\r\n Object.defineProperties( BaseComponent.prototype, {\r\n el : { get : function(){ return ReactDOM.findDOMNode( this ); } },\r\n $el : { get : function(){ return $( this.el ); } },\r\n $ : { value : function( sel ){ return this.$el.find( sel ); } }\r\n });\r\n}\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/main.js\n ** module id = 0\n ** module chunks = 0\n **/","module.exports = function(module) {\r\n\tif(!module.webpackPolyfill) {\r\n\t\tmodule.deprecate = function() {};\r\n\t\tmodule.paths = [];\r\n\t\t// module.parent = undefined by default\r\n\t\tmodule.children = [];\r\n\t\tmodule.webpackPolyfill = 1;\r\n\t}\r\n\treturn module;\r\n}\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** (webpack)/buildin/module.js\n ** module id = 1\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_2__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external {\"commonjs\":\"react\",\"commonjs2\":\"react\",\"amd\":\"react\",\"root\":\"React\"}\n ** module id = 2\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_3__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external {\"commonjs\":\"react-dom\",\"commonjs2\":\"react-dom\",\"amd\":\"react-dom\",\"root\":\"ReactDOM\"}\n ** module id = 3\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nfunction assign( dest, source ){\r\n for( var i in source ) dest[ i ] = source[ i ];\r\n}\r\n\r\nexports.use = function( Backbone ){\r\n var ComponentView = require( './component-view' ).use( Backbone );\r\n\r\n function forceUpdate(){\r\n this.forceUpdate();\r\n }\r\n\r\n var Events = _.extend({\r\n componentWillUnmount : function(){\r\n this.stopListening();\r\n }\r\n }, Backbone.Events );\r\n\r\n var ListenToProps = {\r\n componentDidMount : function(){\r\n var props = this.props,\r\n updateOn = this.listenToProps;\r\n\r\n for( var prop in updateOn ){\r\n var emitter = props[ prop ];\r\n emitter && this.listenTo( emitter, updateOn[ prop ], forceUpdate );\r\n }\r\n }\r\n };\r\n\r\n var ModelState = {\r\n listenToState : 'change',\r\n model : null,\r\n\r\n getInitialState : function(){\r\n return this.model = new this.Model();\r\n },\r\n\r\n componentDidMount : function(){\r\n var events = this.listenToState;\r\n events && this.listenTo( this.state, events, forceUpdate );\r\n },\r\n\r\n componentWillUnmount : function(){\r\n this.state.stopListening();\r\n }\r\n };\r\n\r\n function createClass( spec ){\r\n var mixins = spec.mixins || ( spec.mixins = [] );\r\n\r\n var attributes = getModelAttributes( spec );\r\n if( attributes ){\r\n var BaseModel = spec.Model || Backbone.Model;\r\n spec.Model = BaseModel.extend({ defaults : attributes });\r\n }\r\n\r\n if( spec.Model ) mixins.push( ModelState );\r\n\r\n if( spec.listenToProps ) mixins.unshift( ListenToProps );\r\n\r\n mixins.push( Events );\r\n\r\n var component = React.createClass( spec );\r\n component.View = ComponentView.extend({ component : component });\r\n\r\n return component;\r\n };\r\n\r\n function getModelAttributes( spec ){\r\n var attributes = null;\r\n\r\n for( var i = spec.mixins.length - 1; i >= 0; i-- ){\r\n var mixin = spec.mixins[ i ];\r\n if( mixin.attributes ){\r\n attributes || ( attributes = {} );\r\n assign( attributes, mixin.attributes );\r\n }\r\n }\r\n\r\n if( spec.attributes ){\r\n if( attributes ){\r\n assign( attributes, spec.attributes );\r\n }\r\n else{\r\n attributes = spec.attributes;\r\n }\r\n }\r\n\r\n return attributes;\r\n }\r\n\r\n return createClass;\r\n}\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/createClass.js\n ** module id = 4\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nmodule.exports.use = function( Backbone ){\r\n var View = Backbone.View,\r\n dispose = View.prototype.dispose || function(){},\r\n setElement = View.prototype.setElement;\r\n\r\n var ComponentView = View.extend({\r\n reactClass : null,\r\n props : {},\r\n element : null,\r\n\r\n initialize : function( props ){\r\n // memorise arguments to pass to React\r\n this.options = props || {};\r\n this.element = React.createElement( this.reactClass, this.options );\r\n },\r\n\r\n setElement : function(){\r\n var $content = this.$el.children().detach(),\r\n res = setElement.apply( this, arguments );\r\n\r\n this.$el.append( $content );\r\n return res;\r\n },\r\n\r\n // cached instance of react component...\r\n component : null,\r\n\r\n render : function(){\r\n var component = ReactDOM.render( this.element, this.el );\r\n\r\n if( !this.component ){\r\n if( component && component.trigger ){\r\n // bubble up backbone events, if any\r\n this.listenTo( component, 'all', function(){\r\n this.trigger.apply( this, arguments );\r\n });\r\n }\r\n\r\n this.component = component;\r\n }\r\n },\r\n\r\n unmountComponent : function(){\r\n if( this.component && this.component.trigger ){\r\n this.stopListening( this.component );\r\n }\r\n\r\n ReactDOM.unmountComponentAtNode( this.el );\r\n this.component = null;\r\n },\r\n\r\n dispose : function(){\r\n this.unmountComponent();\r\n return dispose.apply( this, arguments );\r\n }\r\n });\r\n\r\n Object.defineProperty( ComponentView.prototype, 'model', {\r\n get : function(){\r\n this.component || this.render();\r\n return this.component && this.component.model;\r\n }\r\n });\r\n\r\n return ComponentView;\r\n};\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/component-view.js\n ** module id = 5\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nmodule.exports = React.createClass({\r\n displayName : 'BackboneView',\r\n\r\n propTypes : {\r\n View : React.PropTypes.func.isRequired,\r\n options : React.PropTypes.object\r\n },\r\n\r\n render : function(){\r\n return ReactDOM.div({\r\n ref : 'subview',\r\n className : this.props.className\r\n });\r\n },\r\n\r\n componentDidMount : function(){\r\n var el = this.refs.subview,\r\n p = this.props;\r\n\r\n var view = this.view = p.options ? new p.View( p.options ) : new p.View();\r\n\r\n if( el.getDOMNode ) el = el.getDOMNode();\r\n\r\n el.appendChild( view.el );\r\n view.render();\r\n },\r\n\r\n componentDidUpdate : function(){\r\n this.view.render();\r\n },\r\n\r\n componentWillUnmount : function(){\r\n var view = this.view;\r\n if( view.dispose ) view.dispose();\r\n }\r\n});\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/view-element.js\n ** module id = 6\n ** module chunks = 0\n **/"],"sourceRoot":""} \ No newline at end of file diff --git a/reactbone.js.map b/reactbone.js.map deleted file mode 100644 index 6009253..0000000 --- a/reactbone.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap 60364c2c7a6755999b38","webpack:///./src/main.js","webpack:///(webpack)/buildin/module.js","webpack:///external {\"commonjs\":\"react\",\"commonjs2\":\"react\",\"amd\":\"react\",\"root\":\"React\"}","webpack:///external {\"commonjs\":\"react-dom\",\"commonjs2\":\"react-dom\",\"amd\":\"react-dom\",\"root\":\"ReactDOM\"}","webpack:///./src/createClass.js","webpack:///./src/component-view.js","webpack:///./src/view-element.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,4CAA2C,sBAAsB,EAAE;AACnE;;AAEA;AACA,eAAc,kBAAkB,qCAAqC,EAAE,EAAE;AACzE,gBAAe,kBAAkB,qBAAqB,EAAE,EAAE;AAC1D,cAAa,yBAAyB,6BAA6B,EAAE;AACrE,MAAK;AACL;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACTA,gD;;;;;;ACAA,gD;;;;;;ACAA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,4CAA2C,wBAAwB;AACnE;;AAEA;;AAEA;;AAEA;;AAEA;AACA,gDAA+C,wBAAwB;;AAEvE;AACA;;AAEA;AACA;;AAEA,6CAA4C,QAAQ;AACpD;AACA;AACA,gDAA+C;AAC/C;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;AC/FA;AACA;;AAEA;AACA;AACA,uDAAsD;AACtD;;AAEA;AACA;AACA,sBAAqB;AACrB;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,oBAAmB;AACnB;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;;;;;;ACpEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,UAAS;AACT,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,EAAC","file":"./reactbone.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"react\"), require(\"react-dom\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"react\", \"react-dom\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"React\"] = factory(require(\"react\"), require(\"react-dom\"));\n\telse\n\t\troot[\"React\"] = factory(root[\"React\"], root[\"ReactDOM\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_3__) {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 60364c2c7a6755999b38\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nvar NestedReact = module.export = Object.create( React );\r\n\r\nNestedReact.use = function( Backbone ){\r\n // listenToProps, listenToState, model, attributes, Model\r\n NestedReact.createClass = require( './createClass' ).use( Backbone );\r\n\r\n // React component for attaching views\r\n NestedReact.subview = require( './view-element' ).use( Backbone );\r\n\r\n // Extend react components to have jquery accessors\r\n var BaseComponent = React.createClass({ render : function(){} }).type,\r\n $ = Backbone.$;\r\n\r\n Object.defineProperties( BaseComponent.prototype, {\r\n el : { get : function(){ return ReactDOM.findDOMNode( this ); } },\r\n $el : { get : function(){ return $( this.el ); } },\r\n $ : { value : function( sel ){ return this.$el.find( sel ); } }\r\n });\r\n}\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/main.js\n ** module id = 0\n ** module chunks = 0\n **/","module.exports = function(module) {\r\n\tif(!module.webpackPolyfill) {\r\n\t\tmodule.deprecate = function() {};\r\n\t\tmodule.paths = [];\r\n\t\t// module.parent = undefined by default\r\n\t\tmodule.children = [];\r\n\t\tmodule.webpackPolyfill = 1;\r\n\t}\r\n\treturn module;\r\n}\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** (webpack)/buildin/module.js\n ** module id = 1\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_2__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external {\"commonjs\":\"react\",\"commonjs2\":\"react\",\"amd\":\"react\",\"root\":\"React\"}\n ** module id = 2\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_3__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external {\"commonjs\":\"react-dom\",\"commonjs2\":\"react-dom\",\"amd\":\"react-dom\",\"root\":\"ReactDOM\"}\n ** module id = 3\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nfunction assign( dest, source ){\r\n for( var i in source ) dest[ i ] = source[ i ];\r\n}\r\n\r\nexports.use = function( Backbone ){\r\n var ComponentView = require( './component-view' ).use( Backbone );\r\n\r\n function forceUpdate(){\r\n this.forceUpdate();\r\n }\r\n\r\n var Events = _.extend({\r\n componentWillUnmount : function(){\r\n this.stopListening();\r\n }\r\n }, Backbone.Events );\r\n\r\n var ListenToProps = {\r\n componentDidMount : function(){\r\n var props = this.props,\r\n updateOn = this.listenToProps;\r\n\r\n for( var prop in updateOn ){\r\n var emitter = props[ prop ];\r\n emitter && this.listenTo( emitter, updateOn[ prop ], forceUpdate );\r\n }\r\n }\r\n };\r\n\r\n var ModelState = {\r\n listenToState : 'change',\r\n model : null,\r\n\r\n getInitialState : function(){\r\n return this.model = new this.Model();\r\n },\r\n\r\n componentDidMount : function(){\r\n var events = this.listenToState;\r\n events && this.listenTo( this.state, events, forceUpdate );\r\n },\r\n\r\n componentWillUnmount : function(){\r\n this.state.stopListening();\r\n }\r\n };\r\n\r\n function createClass( spec ){\r\n var mixins = spec.mixins || ( spec.mixins = [] );\r\n\r\n var attributes = getModelAttributes( spec );\r\n if( attributes ){\r\n var BaseModel = spec.Model || Backbone.Model;\r\n spec.Model = BaseModel.extend({ defaults : attributes });\r\n }\r\n\r\n if( spec.Model ) mixins.push( ModelState );\r\n\r\n if( spec.listenToProps ) mixins.unshift( ListenToProps );\r\n\r\n mixins.push( Events );\r\n\r\n var component = React.createClass( spec );\r\n component.View = ComponentView.extend({ component : component });\r\n\r\n return component;\r\n };\r\n\r\n function getModelAttributes( spec ){\r\n var attributes = null;\r\n\r\n for( var i = spec.mixins.length - 1; i >= 0; i-- ){\r\n var mixin = spec.mixins[ i ];\r\n if( mixin.attributes ){\r\n attributes || ( attributes = {} );\r\n assign( attributes, mixin.attributes );\r\n }\r\n }\r\n\r\n if( spec.attributes ){\r\n if( attributes ){\r\n assign( attributes, spec.attributes );\r\n }\r\n else{\r\n attributes = spec.attributes;\r\n }\r\n }\r\n\r\n return attributes;\r\n }\r\n\r\n return createClass;\r\n}\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/createClass.js\n ** module id = 4\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nmodule.exports.use = function( Backbone ){\r\n var View = Backbone.View,\r\n dispose = View.prototype.dispose || function(){},\r\n setElement = View.prototype.setElement;\r\n\r\n var ComponentView = View.extend({\r\n reactClass : null,\r\n props : {},\r\n element : null,\r\n\r\n initialize : function( props ){\r\n // memorise arguments to pass to React\r\n this.options = props || {};\r\n this.element = React.createElement( this.reactClass, this.options );\r\n },\r\n\r\n setElement : function(){\r\n var $content = this.$el.children().detach(),\r\n res = setElement.apply( this, arguments );\r\n\r\n this.$el.append( $content );\r\n return res;\r\n },\r\n\r\n // cached instance of react component...\r\n component : null,\r\n\r\n render : function(){\r\n var component = ReactDOM.render( this.element, this.el );\r\n\r\n if( !this.component ){\r\n if( component && component.trigger ){\r\n // bubble up backbone events, if any\r\n this.listenTo( component, 'all', function(){\r\n this.trigger.apply( this, arguments );\r\n });\r\n }\r\n\r\n this.component = component;\r\n }\r\n },\r\n\r\n unmountComponent : function(){\r\n if( this.component && this.component.trigger ){\r\n this.stopListening( this.component );\r\n }\r\n\r\n ReactDOM.unmountComponentAtNode( this.el );\r\n this.component = null;\r\n },\r\n\r\n dispose : function(){\r\n this.unmountComponent();\r\n return dispose.apply( this, arguments );\r\n }\r\n });\r\n\r\n Object.defineProperty( ComponentView.prototype, 'model', {\r\n get : function(){\r\n this.component || this.render();\r\n return this.component && this.component.model;\r\n }\r\n });\r\n\r\n return ComponentView;\r\n};\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/component-view.js\n ** module id = 5\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nmodule.exports = React.createClass({\r\n displayName : 'BackboneView',\r\n\r\n propTypes : {\r\n View : React.PropTypes.func.isRequired,\r\n options : React.PropTypes.object\r\n },\r\n\r\n render : function(){\r\n return ReactDOM.div({\r\n ref : 'subview',\r\n className : this.props.className\r\n });\r\n },\r\n\r\n componentDidMount : function(){\r\n var el = this.refs.subview,\r\n p = this.props;\r\n\r\n var view = this.view = p.options ? new p.View( p.options ) : new p.View();\r\n\r\n if( el.getDOMNode ) el = el.getDOMNode();\r\n\r\n el.appendChild( view.el );\r\n view.render();\r\n },\r\n\r\n componentDidUpdate : function(){\r\n this.view.render();\r\n },\r\n\r\n componentWillUnmount : function(){\r\n var view = this.view;\r\n if( view.dispose ) view.dispose();\r\n }\r\n});\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/view-element.js\n ** module id = 6\n ** module chunks = 0\n **/"],"sourceRoot":""} \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js index 2402de7..7874e3c 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,7 +2,7 @@ module.exports = { entry: "./src/main", output : { - filename : './reactbone.js', + filename : './react-bone.js', library : "React", libraryTarget : 'umd' }, From 1d8306ea7b7ff0ef4c872529bc855f231f1a8e24 Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Thu, 22 Oct 2015 17:39:43 -0400 Subject: [PATCH 03/31] added simple test, fixed bugs --- package.json | 15 +++++++------ react-bone.js | 55 ++++++++++++++++------------------------------- react-bone.js.map | 2 +- src/main.js | 8 +++---- test.html | 41 +++++++++++++++++++++++++++++++++++ 5 files changed, 74 insertions(+), 47 deletions(-) create mode 100644 test.html diff --git a/package.json b/package.json index b8aa881..440c4af 100644 --- a/package.json +++ b/package.json @@ -13,21 +13,24 @@ }, "author": "Vlad Balin ", "contributors": "", - "dependencies": { "react": "^0.14.0", "react-dom": "^0.14.0" }, - "devDependencies": { + "backbone": "*", + "jquery": "^2.1.4", + "underscore": "^1.8.3", "webpack": "^1.12.2" }, - - "files": [ "react-bone.js" ], + "files": [ + "react-bone.js", + "react-bone.js.map" + ], "license": "MIT", "version": "0.2.0", - "scripts": { - "build": "./node_modules/.bin/webpack" + "build": "./node_modules/.bin/webpack", + "watch": "./node_modules/.bin/webpack --watch" } } diff --git a/react-bone.js b/react-bone.js index b42b585..bb08820 100644 --- a/react-bone.js +++ b/react-bone.js @@ -7,7 +7,7 @@ exports["React"] = factory(require("react"), require("react-dom")); else root["React"] = factory(root["React"], root["ReactDOM"]); -})(this, function(__WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_3__) { +})(this, function(__WEBPACK_EXTERNAL_MODULE_1__, __WEBPACK_EXTERNAL_MODULE_2__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; @@ -54,46 +54,35 @@ return /******/ (function(modules) { // webpackBootstrap /* 0 */ /***/ function(module, exports, __webpack_require__) { - /* WEBPACK VAR INJECTION */(function(module) {var React = __webpack_require__( 2 ), - ReactDOM = __webpack_require__( 3 ); + var React = __webpack_require__( 1 ), + ReactDOM = __webpack_require__( 2 ); - var NestedReact = module.export = Object.create( React ); + var NestedReact = module.exports = Object.create( React ); NestedReact.use = function( Backbone ){ // listenToProps, listenToState, model, attributes, Model - NestedReact.createClass = __webpack_require__( 4 ).use( Backbone ); + NestedReact.createClass = __webpack_require__( 3 ).use( Backbone ); // React component for attaching views - NestedReact.subview = __webpack_require__( 6 ).use( Backbone ); + NestedReact.subview = __webpack_require__( 5 ); // Extend react components to have jquery accessors - var BaseComponent = React.createClass({ render : function(){} }).type, + var BaseComponent = Object.getPrototypeOf( React.createClass({ render : function(){} }).prototype ), $ = Backbone.$; - Object.defineProperties( BaseComponent.prototype, { + Object.defineProperties( BaseComponent, { el : { get : function(){ return ReactDOM.findDOMNode( this ); } }, $el : { get : function(){ return $( this.el ); } }, $ : { value : function( sel ){ return this.$el.find( sel ); } } }); } - - /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1)(module))) + /***/ }, /* 1 */ /***/ function(module, exports) { - module.exports = function(module) { - if(!module.webpackPolyfill) { - module.deprecate = function() {}; - module.paths = []; - // module.parent = undefined by default - module.children = []; - module.webpackPolyfill = 1; - } - return module; - } - + module.exports = __WEBPACK_EXTERNAL_MODULE_1__; /***/ }, /* 2 */ @@ -103,23 +92,17 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, /* 3 */ -/***/ function(module, exports) { - - module.exports = __WEBPACK_EXTERNAL_MODULE_3__; - -/***/ }, -/* 4 */ /***/ function(module, exports, __webpack_require__) { - var React = __webpack_require__( 2 ), - ReactDOM = __webpack_require__( 3 ); + var React = __webpack_require__( 1 ), + ReactDOM = __webpack_require__( 2 ); function assign( dest, source ){ for( var i in source ) dest[ i ] = source[ i ]; } exports.use = function( Backbone ){ - var ComponentView = __webpack_require__( 5 ).use( Backbone ); + var ComponentView = __webpack_require__( 4 ).use( Backbone ); function forceUpdate(){ this.forceUpdate(); @@ -210,11 +193,11 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, -/* 5 */ +/* 4 */ /***/ function(module, exports, __webpack_require__) { - var React = __webpack_require__( 2 ), - ReactDOM = __webpack_require__( 3 ); + var React = __webpack_require__( 1 ), + ReactDOM = __webpack_require__( 2 ); module.exports.use = function( Backbone ){ var View = Backbone.View, @@ -285,11 +268,11 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, -/* 6 */ +/* 5 */ /***/ function(module, exports, __webpack_require__) { - var React = __webpack_require__( 2 ), - ReactDOM = __webpack_require__( 3 ); + var React = __webpack_require__( 1 ), + ReactDOM = __webpack_require__( 2 ); module.exports = React.createClass({ displayName : 'BackboneView', diff --git a/react-bone.js.map b/react-bone.js.map index 18a63c1..4626266 100644 --- a/react-bone.js.map +++ b/react-bone.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap 4b7b1008733b88d02c92","webpack:///./src/main.js","webpack:///(webpack)/buildin/module.js","webpack:///external {\"commonjs\":\"react\",\"commonjs2\":\"react\",\"amd\":\"react\",\"root\":\"React\"}","webpack:///external {\"commonjs\":\"react-dom\",\"commonjs2\":\"react-dom\",\"amd\":\"react-dom\",\"root\":\"ReactDOM\"}","webpack:///./src/createClass.js","webpack:///./src/component-view.js","webpack:///./src/view-element.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,4CAA2C,sBAAsB,EAAE;AACnE;;AAEA;AACA,eAAc,kBAAkB,qCAAqC,EAAE,EAAE;AACzE,gBAAe,kBAAkB,qBAAqB,EAAE,EAAE;AAC1D,cAAa,yBAAyB,6BAA6B,EAAE;AACrE,MAAK;AACL;;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACTA,gD;;;;;;ACAA,gD;;;;;;ACAA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,4CAA2C,wBAAwB;AACnE;;AAEA;;AAEA;;AAEA;;AAEA;AACA,gDAA+C,wBAAwB;;AAEvE;AACA;;AAEA;AACA;;AAEA,6CAA4C,QAAQ;AACpD;AACA;AACA,gDAA+C;AAC/C;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;AC/FA;AACA;;AAEA;AACA;AACA,uDAAsD;AACtD;;AAEA;AACA;AACA,sBAAqB;AACrB;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,oBAAmB;AACnB;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;;;;;;ACpEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,UAAS;AACT,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,EAAC","file":"./react-bone.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"react\"), require(\"react-dom\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"react\", \"react-dom\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"React\"] = factory(require(\"react\"), require(\"react-dom\"));\n\telse\n\t\troot[\"React\"] = factory(root[\"React\"], root[\"ReactDOM\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_3__) {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 4b7b1008733b88d02c92\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nvar NestedReact = module.export = Object.create( React );\r\n\r\nNestedReact.use = function( Backbone ){\r\n // listenToProps, listenToState, model, attributes, Model\r\n NestedReact.createClass = require( './createClass' ).use( Backbone );\r\n\r\n // React component for attaching views\r\n NestedReact.subview = require( './view-element' ).use( Backbone );\r\n\r\n // Extend react components to have jquery accessors\r\n var BaseComponent = React.createClass({ render : function(){} }).type,\r\n $ = Backbone.$;\r\n\r\n Object.defineProperties( BaseComponent.prototype, {\r\n el : { get : function(){ return ReactDOM.findDOMNode( this ); } },\r\n $el : { get : function(){ return $( this.el ); } },\r\n $ : { value : function( sel ){ return this.$el.find( sel ); } }\r\n });\r\n}\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/main.js\n ** module id = 0\n ** module chunks = 0\n **/","module.exports = function(module) {\r\n\tif(!module.webpackPolyfill) {\r\n\t\tmodule.deprecate = function() {};\r\n\t\tmodule.paths = [];\r\n\t\t// module.parent = undefined by default\r\n\t\tmodule.children = [];\r\n\t\tmodule.webpackPolyfill = 1;\r\n\t}\r\n\treturn module;\r\n}\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** (webpack)/buildin/module.js\n ** module id = 1\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_2__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external {\"commonjs\":\"react\",\"commonjs2\":\"react\",\"amd\":\"react\",\"root\":\"React\"}\n ** module id = 2\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_3__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external {\"commonjs\":\"react-dom\",\"commonjs2\":\"react-dom\",\"amd\":\"react-dom\",\"root\":\"ReactDOM\"}\n ** module id = 3\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nfunction assign( dest, source ){\r\n for( var i in source ) dest[ i ] = source[ i ];\r\n}\r\n\r\nexports.use = function( Backbone ){\r\n var ComponentView = require( './component-view' ).use( Backbone );\r\n\r\n function forceUpdate(){\r\n this.forceUpdate();\r\n }\r\n\r\n var Events = _.extend({\r\n componentWillUnmount : function(){\r\n this.stopListening();\r\n }\r\n }, Backbone.Events );\r\n\r\n var ListenToProps = {\r\n componentDidMount : function(){\r\n var props = this.props,\r\n updateOn = this.listenToProps;\r\n\r\n for( var prop in updateOn ){\r\n var emitter = props[ prop ];\r\n emitter && this.listenTo( emitter, updateOn[ prop ], forceUpdate );\r\n }\r\n }\r\n };\r\n\r\n var ModelState = {\r\n listenToState : 'change',\r\n model : null,\r\n\r\n getInitialState : function(){\r\n return this.model = new this.Model();\r\n },\r\n\r\n componentDidMount : function(){\r\n var events = this.listenToState;\r\n events && this.listenTo( this.state, events, forceUpdate );\r\n },\r\n\r\n componentWillUnmount : function(){\r\n this.state.stopListening();\r\n }\r\n };\r\n\r\n function createClass( spec ){\r\n var mixins = spec.mixins || ( spec.mixins = [] );\r\n\r\n var attributes = getModelAttributes( spec );\r\n if( attributes ){\r\n var BaseModel = spec.Model || Backbone.Model;\r\n spec.Model = BaseModel.extend({ defaults : attributes });\r\n }\r\n\r\n if( spec.Model ) mixins.push( ModelState );\r\n\r\n if( spec.listenToProps ) mixins.unshift( ListenToProps );\r\n\r\n mixins.push( Events );\r\n\r\n var component = React.createClass( spec );\r\n component.View = ComponentView.extend({ component : component });\r\n\r\n return component;\r\n };\r\n\r\n function getModelAttributes( spec ){\r\n var attributes = null;\r\n\r\n for( var i = spec.mixins.length - 1; i >= 0; i-- ){\r\n var mixin = spec.mixins[ i ];\r\n if( mixin.attributes ){\r\n attributes || ( attributes = {} );\r\n assign( attributes, mixin.attributes );\r\n }\r\n }\r\n\r\n if( spec.attributes ){\r\n if( attributes ){\r\n assign( attributes, spec.attributes );\r\n }\r\n else{\r\n attributes = spec.attributes;\r\n }\r\n }\r\n\r\n return attributes;\r\n }\r\n\r\n return createClass;\r\n}\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/createClass.js\n ** module id = 4\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nmodule.exports.use = function( Backbone ){\r\n var View = Backbone.View,\r\n dispose = View.prototype.dispose || function(){},\r\n setElement = View.prototype.setElement;\r\n\r\n var ComponentView = View.extend({\r\n reactClass : null,\r\n props : {},\r\n element : null,\r\n\r\n initialize : function( props ){\r\n // memorise arguments to pass to React\r\n this.options = props || {};\r\n this.element = React.createElement( this.reactClass, this.options );\r\n },\r\n\r\n setElement : function(){\r\n var $content = this.$el.children().detach(),\r\n res = setElement.apply( this, arguments );\r\n\r\n this.$el.append( $content );\r\n return res;\r\n },\r\n\r\n // cached instance of react component...\r\n component : null,\r\n\r\n render : function(){\r\n var component = ReactDOM.render( this.element, this.el );\r\n\r\n if( !this.component ){\r\n if( component && component.trigger ){\r\n // bubble up backbone events, if any\r\n this.listenTo( component, 'all', function(){\r\n this.trigger.apply( this, arguments );\r\n });\r\n }\r\n\r\n this.component = component;\r\n }\r\n },\r\n\r\n unmountComponent : function(){\r\n if( this.component && this.component.trigger ){\r\n this.stopListening( this.component );\r\n }\r\n\r\n ReactDOM.unmountComponentAtNode( this.el );\r\n this.component = null;\r\n },\r\n\r\n dispose : function(){\r\n this.unmountComponent();\r\n return dispose.apply( this, arguments );\r\n }\r\n });\r\n\r\n Object.defineProperty( ComponentView.prototype, 'model', {\r\n get : function(){\r\n this.component || this.render();\r\n return this.component && this.component.model;\r\n }\r\n });\r\n\r\n return ComponentView;\r\n};\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/component-view.js\n ** module id = 5\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nmodule.exports = React.createClass({\r\n displayName : 'BackboneView',\r\n\r\n propTypes : {\r\n View : React.PropTypes.func.isRequired,\r\n options : React.PropTypes.object\r\n },\r\n\r\n render : function(){\r\n return ReactDOM.div({\r\n ref : 'subview',\r\n className : this.props.className\r\n });\r\n },\r\n\r\n componentDidMount : function(){\r\n var el = this.refs.subview,\r\n p = this.props;\r\n\r\n var view = this.view = p.options ? new p.View( p.options ) : new p.View();\r\n\r\n if( el.getDOMNode ) el = el.getDOMNode();\r\n\r\n el.appendChild( view.el );\r\n view.render();\r\n },\r\n\r\n componentDidUpdate : function(){\r\n this.view.render();\r\n },\r\n\r\n componentWillUnmount : function(){\r\n var view = this.view;\r\n if( view.dispose ) view.dispose();\r\n }\r\n});\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/view-element.js\n ** module id = 6\n ** module chunks = 0\n **/"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap 7f4286f9a4f4e7b48c0a","webpack:///./src/main.js","webpack:///external {\"commonjs\":\"react\",\"commonjs2\":\"react\",\"amd\":\"react\",\"root\":\"React\"}","webpack:///external {\"commonjs\":\"react-dom\",\"commonjs2\":\"react-dom\",\"amd\":\"react-dom\",\"root\":\"ReactDOM\"}","webpack:///./src/createClass.js","webpack:///./src/component-view.js","webpack:///./src/view-element.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,mEAAkE,sBAAsB,EAAE;AAC1F;;AAEA;AACA,eAAc,kBAAkB,qCAAqC,EAAE,EAAE;AACzE,gBAAe,kBAAkB,qBAAqB,EAAE,EAAE;AAC1D,cAAa,yBAAyB,6BAA6B,EAAE;AACrE,MAAK;AACL;;;;;;;ACrBA,gD;;;;;;ACAA,gD;;;;;;ACAA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,4CAA2C,wBAAwB;AACnE;;AAEA;;AAEA;;AAEA;;AAEA;AACA,gDAA+C,wBAAwB;;AAEvE;AACA;;AAEA;AACA;;AAEA,6CAA4C,QAAQ;AACpD;AACA;AACA,gDAA+C;AAC/C;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;AC/FA;AACA;;AAEA;AACA;AACA,uDAAsD;AACtD;;AAEA;AACA;AACA,sBAAqB;AACrB;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,oBAAmB;AACnB;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;;;;;;ACpEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,UAAS;AACT,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,EAAC","file":"./react-bone.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"react\"), require(\"react-dom\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"react\", \"react-dom\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"React\"] = factory(require(\"react\"), require(\"react-dom\"));\n\telse\n\t\troot[\"React\"] = factory(root[\"React\"], root[\"ReactDOM\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_1__, __WEBPACK_EXTERNAL_MODULE_2__) {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 7f4286f9a4f4e7b48c0a\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nvar NestedReact = module.exports = Object.create( React );\r\n\r\nNestedReact.use = function( Backbone ){\r\n // listenToProps, listenToState, model, attributes, Model\r\n NestedReact.createClass = require( './createClass' ).use( Backbone );\r\n\r\n // React component for attaching views\r\n NestedReact.subview = require( './view-element' );\r\n\r\n // Extend react components to have jquery accessors\r\n var BaseComponent = Object.getPrototypeOf( React.createClass({ render : function(){} }).prototype ),\r\n $ = Backbone.$;\r\n\r\n Object.defineProperties( BaseComponent, {\r\n el : { get : function(){ return ReactDOM.findDOMNode( this ); } },\r\n $el : { get : function(){ return $( this.el ); } },\r\n $ : { value : function( sel ){ return this.$el.find( sel ); } }\r\n });\r\n}\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/main.js\n ** module id = 0\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_1__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external {\"commonjs\":\"react\",\"commonjs2\":\"react\",\"amd\":\"react\",\"root\":\"React\"}\n ** module id = 1\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_2__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external {\"commonjs\":\"react-dom\",\"commonjs2\":\"react-dom\",\"amd\":\"react-dom\",\"root\":\"ReactDOM\"}\n ** module id = 2\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nfunction assign( dest, source ){\r\n for( var i in source ) dest[ i ] = source[ i ];\r\n}\r\n\r\nexports.use = function( Backbone ){\r\n var ComponentView = require( './component-view' ).use( Backbone );\r\n\r\n function forceUpdate(){\r\n this.forceUpdate();\r\n }\r\n\r\n var Events = _.extend({\r\n componentWillUnmount : function(){\r\n this.stopListening();\r\n }\r\n }, Backbone.Events );\r\n\r\n var ListenToProps = {\r\n componentDidMount : function(){\r\n var props = this.props,\r\n updateOn = this.listenToProps;\r\n\r\n for( var prop in updateOn ){\r\n var emitter = props[ prop ];\r\n emitter && this.listenTo( emitter, updateOn[ prop ], forceUpdate );\r\n }\r\n }\r\n };\r\n\r\n var ModelState = {\r\n listenToState : 'change',\r\n model : null,\r\n\r\n getInitialState : function(){\r\n return this.model = new this.Model();\r\n },\r\n\r\n componentDidMount : function(){\r\n var events = this.listenToState;\r\n events && this.listenTo( this.state, events, forceUpdate );\r\n },\r\n\r\n componentWillUnmount : function(){\r\n this.state.stopListening();\r\n }\r\n };\r\n\r\n function createClass( spec ){\r\n var mixins = spec.mixins || ( spec.mixins = [] );\r\n\r\n var attributes = getModelAttributes( spec );\r\n if( attributes ){\r\n var BaseModel = spec.Model || Backbone.Model;\r\n spec.Model = BaseModel.extend({ defaults : attributes });\r\n }\r\n\r\n if( spec.Model ) mixins.push( ModelState );\r\n\r\n if( spec.listenToProps ) mixins.unshift( ListenToProps );\r\n\r\n mixins.push( Events );\r\n\r\n var component = React.createClass( spec );\r\n component.View = ComponentView.extend({ component : component });\r\n\r\n return component;\r\n };\r\n\r\n function getModelAttributes( spec ){\r\n var attributes = null;\r\n\r\n for( var i = spec.mixins.length - 1; i >= 0; i-- ){\r\n var mixin = spec.mixins[ i ];\r\n if( mixin.attributes ){\r\n attributes || ( attributes = {} );\r\n assign( attributes, mixin.attributes );\r\n }\r\n }\r\n\r\n if( spec.attributes ){\r\n if( attributes ){\r\n assign( attributes, spec.attributes );\r\n }\r\n else{\r\n attributes = spec.attributes;\r\n }\r\n }\r\n\r\n return attributes;\r\n }\r\n\r\n return createClass;\r\n}\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/createClass.js\n ** module id = 3\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nmodule.exports.use = function( Backbone ){\r\n var View = Backbone.View,\r\n dispose = View.prototype.dispose || function(){},\r\n setElement = View.prototype.setElement;\r\n\r\n var ComponentView = View.extend({\r\n reactClass : null,\r\n props : {},\r\n element : null,\r\n\r\n initialize : function( props ){\r\n // memorise arguments to pass to React\r\n this.options = props || {};\r\n this.element = React.createElement( this.reactClass, this.options );\r\n },\r\n\r\n setElement : function(){\r\n var $content = this.$el.children().detach(),\r\n res = setElement.apply( this, arguments );\r\n\r\n this.$el.append( $content );\r\n return res;\r\n },\r\n\r\n // cached instance of react component...\r\n component : null,\r\n\r\n render : function(){\r\n var component = ReactDOM.render( this.element, this.el );\r\n\r\n if( !this.component ){\r\n if( component && component.trigger ){\r\n // bubble up backbone events, if any\r\n this.listenTo( component, 'all', function(){\r\n this.trigger.apply( this, arguments );\r\n });\r\n }\r\n\r\n this.component = component;\r\n }\r\n },\r\n\r\n unmountComponent : function(){\r\n if( this.component && this.component.trigger ){\r\n this.stopListening( this.component );\r\n }\r\n\r\n ReactDOM.unmountComponentAtNode( this.el );\r\n this.component = null;\r\n },\r\n\r\n dispose : function(){\r\n this.unmountComponent();\r\n return dispose.apply( this, arguments );\r\n }\r\n });\r\n\r\n Object.defineProperty( ComponentView.prototype, 'model', {\r\n get : function(){\r\n this.component || this.render();\r\n return this.component && this.component.model;\r\n }\r\n });\r\n\r\n return ComponentView;\r\n};\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/component-view.js\n ** module id = 4\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nmodule.exports = React.createClass({\r\n displayName : 'BackboneView',\r\n\r\n propTypes : {\r\n View : React.PropTypes.func.isRequired,\r\n options : React.PropTypes.object\r\n },\r\n\r\n render : function(){\r\n return ReactDOM.div({\r\n ref : 'subview',\r\n className : this.props.className\r\n });\r\n },\r\n\r\n componentDidMount : function(){\r\n var el = this.refs.subview,\r\n p = this.props;\r\n\r\n var view = this.view = p.options ? new p.View( p.options ) : new p.View();\r\n\r\n if( el.getDOMNode ) el = el.getDOMNode();\r\n\r\n el.appendChild( view.el );\r\n view.render();\r\n },\r\n\r\n componentDidUpdate : function(){\r\n this.view.render();\r\n },\r\n\r\n componentWillUnmount : function(){\r\n var view = this.view;\r\n if( view.dispose ) view.dispose();\r\n }\r\n});\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/view-element.js\n ** module id = 5\n ** module chunks = 0\n **/"],"sourceRoot":""} \ No newline at end of file diff --git a/src/main.js b/src/main.js index 1450f8a..bf40ecd 100644 --- a/src/main.js +++ b/src/main.js @@ -1,20 +1,20 @@ var React = require( 'react' ), ReactDOM = require( 'react-dom' ); -var NestedReact = module.export = Object.create( React ); +var NestedReact = module.exports = Object.create( React ); NestedReact.use = function( Backbone ){ // listenToProps, listenToState, model, attributes, Model NestedReact.createClass = require( './createClass' ).use( Backbone ); // React component for attaching views - NestedReact.subview = require( './view-element' ).use( Backbone ); + NestedReact.subview = require( './view-element' ); // Extend react components to have jquery accessors - var BaseComponent = React.createClass({ render : function(){} }).type, + var BaseComponent = Object.getPrototypeOf( React.createClass({ render : function(){} }).prototype ), $ = Backbone.$; - Object.defineProperties( BaseComponent.prototype, { + Object.defineProperties( BaseComponent, { el : { get : function(){ return ReactDOM.findDOMNode( this ); } }, $el : { get : function(){ return $( this.el ); } }, $ : { value : function( sel ){ return this.$el.find( sel ); } } diff --git a/test.html b/test.html new file mode 100644 index 0000000..bcc6857 --- /dev/null +++ b/test.html @@ -0,0 +1,41 @@ + + + + + + + + + + + + + From dae3e79c17322ec08533e47a8110b5b82b505a05 Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Thu, 22 Oct 2015 18:10:57 -0400 Subject: [PATCH 04/31] updated readme --- README.md | 83 +++++++++++++++++++++++++++++++++++++++-------- react-bone.js | 2 ++ react-bone.js.map | 2 +- src/main.js | 2 ++ 4 files changed, 75 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 073e426..ec1882f 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,22 @@ -# react-backbone.glue -This is React add-on designed to replace Backbone views with React in existing Backbone application. +# react-bone +This is React add-on designed to simplify migration to React views in large Backbone applications. It allows you: -- To use React component in place of every Backbone View in your application. -- To use your existing Backbone Views as subviews in React components. +- To use React component in place of every Backbone View. +- To use your existing Backbone Views from React components. - To use your existing Backbone Models as React component state. - Update React components on Backbone events. Thus, no refactoring of your application is required. You can start writing UI with React immediately replacing your Backbone Views one-by-one, while keeping your existing models. This extension works with raw Backbone. However, in order to take full advantage of React/Backbone -architecture you are encouraged to upgrade to `Backbone.NestedTypes`. It will give you following +architecture you are encouraged to upgrade to `Backbone.NestedTypes`. It will give you following features to help managing complex application state: - Proper nested models and collections implementation with deep changes detection. React components will update UI on nested attribute changes. -- Dramatic improvement in model update performance compared to Backbone. Up to 40x faster in Chrome. Imprortant for mobile devices. +- Dramatic improvement in model update performance compared to Backbone. Up to 40x faster in Chrome. Important for mobile devices. - Type safety. Attributes are guaranteed to hold values of declared types all the time. For more information, visit @@ -25,28 +25,35 @@ and https://github.com/Volicon/backbone.nestedTypes # Usage -It's packed as single UMD, thus grab the module which is appropriate for you. So far, there are two of them, one for raw backbone, and one for `backbone.nestedTypes`. +It's packed as single UMD, thus grab the module or use `npm` to install. + `npm install --save react-bone` -First one depends on `react` and `backbone`, so if you're using Chaplin or Marionette you will -probably need to pass appropriate module instead of `backbone`. Don't hesitate to replace module name in the beginning of the file, or use raw factory function from `src/glue.js`. +Module export's modified React namespace, and must be used as a replacement for `react`. It must be initialized before use. If you're using backbone-based frameworks, such as `ChaplinJS`, `Marionette`, or `NestedTypes`, pass it instead of Backbone. -If you're using `NestedTypes`, you need `NestedTypes` to require appropriate framework. Report a bug if something goes wrong, we like when someone share our passion for technology and quite fast in response. +```javascript + var Backbone = require( 'backbone' ), + React = require( 'react-bone' ).use( Backbone ); +``` + +Note, that if you're using `NestedTypes`, it needs to be used in place of backbone in all places where Backbone is required. # Features ## Use React components as Backbone View ```javscript -var backboneView = MyReactComponent.createView( props ); +var backboneView = new MyReactComponent.View( props ); ``` ## Use Backbone View in React component ```javscript +var React = require( 'react-bone' ); + var MyComponent = React.createClass({ render : function(){ return (
- + { this.state.count } +
+ ); + }, + + onClick : function(){ + this.state.count = this.state.count + 1; + } +}); +``` + ## Passing Backbone objects as React components props ```javscript var MyComponent = React.createClass({ diff --git a/react-bone.js b/react-bone.js index bb08820..7f99056 100644 --- a/react-bone.js +++ b/react-bone.js @@ -75,6 +75,8 @@ return /******/ (function(modules) { // webpackBootstrap $el : { get : function(){ return $( this.el ); } }, $ : { value : function( sel ){ return this.$el.find( sel ); } } }); + + NestedReact.use = function(){}; } diff --git a/react-bone.js.map b/react-bone.js.map index 4626266..56a60e9 100644 --- a/react-bone.js.map +++ b/react-bone.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap 7f4286f9a4f4e7b48c0a","webpack:///./src/main.js","webpack:///external {\"commonjs\":\"react\",\"commonjs2\":\"react\",\"amd\":\"react\",\"root\":\"React\"}","webpack:///external {\"commonjs\":\"react-dom\",\"commonjs2\":\"react-dom\",\"amd\":\"react-dom\",\"root\":\"ReactDOM\"}","webpack:///./src/createClass.js","webpack:///./src/component-view.js","webpack:///./src/view-element.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,mEAAkE,sBAAsB,EAAE;AAC1F;;AAEA;AACA,eAAc,kBAAkB,qCAAqC,EAAE,EAAE;AACzE,gBAAe,kBAAkB,qBAAqB,EAAE,EAAE;AAC1D,cAAa,yBAAyB,6BAA6B,EAAE;AACrE,MAAK;AACL;;;;;;;ACrBA,gD;;;;;;ACAA,gD;;;;;;ACAA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,4CAA2C,wBAAwB;AACnE;;AAEA;;AAEA;;AAEA;;AAEA;AACA,gDAA+C,wBAAwB;;AAEvE;AACA;;AAEA;AACA;;AAEA,6CAA4C,QAAQ;AACpD;AACA;AACA,gDAA+C;AAC/C;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;AC/FA;AACA;;AAEA;AACA;AACA,uDAAsD;AACtD;;AAEA;AACA;AACA,sBAAqB;AACrB;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,oBAAmB;AACnB;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;;;;;;ACpEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,UAAS;AACT,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,EAAC","file":"./react-bone.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"react\"), require(\"react-dom\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"react\", \"react-dom\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"React\"] = factory(require(\"react\"), require(\"react-dom\"));\n\telse\n\t\troot[\"React\"] = factory(root[\"React\"], root[\"ReactDOM\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_1__, __WEBPACK_EXTERNAL_MODULE_2__) {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 7f4286f9a4f4e7b48c0a\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nvar NestedReact = module.exports = Object.create( React );\r\n\r\nNestedReact.use = function( Backbone ){\r\n // listenToProps, listenToState, model, attributes, Model\r\n NestedReact.createClass = require( './createClass' ).use( Backbone );\r\n\r\n // React component for attaching views\r\n NestedReact.subview = require( './view-element' );\r\n\r\n // Extend react components to have jquery accessors\r\n var BaseComponent = Object.getPrototypeOf( React.createClass({ render : function(){} }).prototype ),\r\n $ = Backbone.$;\r\n\r\n Object.defineProperties( BaseComponent, {\r\n el : { get : function(){ return ReactDOM.findDOMNode( this ); } },\r\n $el : { get : function(){ return $( this.el ); } },\r\n $ : { value : function( sel ){ return this.$el.find( sel ); } }\r\n });\r\n}\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/main.js\n ** module id = 0\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_1__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external {\"commonjs\":\"react\",\"commonjs2\":\"react\",\"amd\":\"react\",\"root\":\"React\"}\n ** module id = 1\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_2__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external {\"commonjs\":\"react-dom\",\"commonjs2\":\"react-dom\",\"amd\":\"react-dom\",\"root\":\"ReactDOM\"}\n ** module id = 2\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nfunction assign( dest, source ){\r\n for( var i in source ) dest[ i ] = source[ i ];\r\n}\r\n\r\nexports.use = function( Backbone ){\r\n var ComponentView = require( './component-view' ).use( Backbone );\r\n\r\n function forceUpdate(){\r\n this.forceUpdate();\r\n }\r\n\r\n var Events = _.extend({\r\n componentWillUnmount : function(){\r\n this.stopListening();\r\n }\r\n }, Backbone.Events );\r\n\r\n var ListenToProps = {\r\n componentDidMount : function(){\r\n var props = this.props,\r\n updateOn = this.listenToProps;\r\n\r\n for( var prop in updateOn ){\r\n var emitter = props[ prop ];\r\n emitter && this.listenTo( emitter, updateOn[ prop ], forceUpdate );\r\n }\r\n }\r\n };\r\n\r\n var ModelState = {\r\n listenToState : 'change',\r\n model : null,\r\n\r\n getInitialState : function(){\r\n return this.model = new this.Model();\r\n },\r\n\r\n componentDidMount : function(){\r\n var events = this.listenToState;\r\n events && this.listenTo( this.state, events, forceUpdate );\r\n },\r\n\r\n componentWillUnmount : function(){\r\n this.state.stopListening();\r\n }\r\n };\r\n\r\n function createClass( spec ){\r\n var mixins = spec.mixins || ( spec.mixins = [] );\r\n\r\n var attributes = getModelAttributes( spec );\r\n if( attributes ){\r\n var BaseModel = spec.Model || Backbone.Model;\r\n spec.Model = BaseModel.extend({ defaults : attributes });\r\n }\r\n\r\n if( spec.Model ) mixins.push( ModelState );\r\n\r\n if( spec.listenToProps ) mixins.unshift( ListenToProps );\r\n\r\n mixins.push( Events );\r\n\r\n var component = React.createClass( spec );\r\n component.View = ComponentView.extend({ component : component });\r\n\r\n return component;\r\n };\r\n\r\n function getModelAttributes( spec ){\r\n var attributes = null;\r\n\r\n for( var i = spec.mixins.length - 1; i >= 0; i-- ){\r\n var mixin = spec.mixins[ i ];\r\n if( mixin.attributes ){\r\n attributes || ( attributes = {} );\r\n assign( attributes, mixin.attributes );\r\n }\r\n }\r\n\r\n if( spec.attributes ){\r\n if( attributes ){\r\n assign( attributes, spec.attributes );\r\n }\r\n else{\r\n attributes = spec.attributes;\r\n }\r\n }\r\n\r\n return attributes;\r\n }\r\n\r\n return createClass;\r\n}\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/createClass.js\n ** module id = 3\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nmodule.exports.use = function( Backbone ){\r\n var View = Backbone.View,\r\n dispose = View.prototype.dispose || function(){},\r\n setElement = View.prototype.setElement;\r\n\r\n var ComponentView = View.extend({\r\n reactClass : null,\r\n props : {},\r\n element : null,\r\n\r\n initialize : function( props ){\r\n // memorise arguments to pass to React\r\n this.options = props || {};\r\n this.element = React.createElement( this.reactClass, this.options );\r\n },\r\n\r\n setElement : function(){\r\n var $content = this.$el.children().detach(),\r\n res = setElement.apply( this, arguments );\r\n\r\n this.$el.append( $content );\r\n return res;\r\n },\r\n\r\n // cached instance of react component...\r\n component : null,\r\n\r\n render : function(){\r\n var component = ReactDOM.render( this.element, this.el );\r\n\r\n if( !this.component ){\r\n if( component && component.trigger ){\r\n // bubble up backbone events, if any\r\n this.listenTo( component, 'all', function(){\r\n this.trigger.apply( this, arguments );\r\n });\r\n }\r\n\r\n this.component = component;\r\n }\r\n },\r\n\r\n unmountComponent : function(){\r\n if( this.component && this.component.trigger ){\r\n this.stopListening( this.component );\r\n }\r\n\r\n ReactDOM.unmountComponentAtNode( this.el );\r\n this.component = null;\r\n },\r\n\r\n dispose : function(){\r\n this.unmountComponent();\r\n return dispose.apply( this, arguments );\r\n }\r\n });\r\n\r\n Object.defineProperty( ComponentView.prototype, 'model', {\r\n get : function(){\r\n this.component || this.render();\r\n return this.component && this.component.model;\r\n }\r\n });\r\n\r\n return ComponentView;\r\n};\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/component-view.js\n ** module id = 4\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nmodule.exports = React.createClass({\r\n displayName : 'BackboneView',\r\n\r\n propTypes : {\r\n View : React.PropTypes.func.isRequired,\r\n options : React.PropTypes.object\r\n },\r\n\r\n render : function(){\r\n return ReactDOM.div({\r\n ref : 'subview',\r\n className : this.props.className\r\n });\r\n },\r\n\r\n componentDidMount : function(){\r\n var el = this.refs.subview,\r\n p = this.props;\r\n\r\n var view = this.view = p.options ? new p.View( p.options ) : new p.View();\r\n\r\n if( el.getDOMNode ) el = el.getDOMNode();\r\n\r\n el.appendChild( view.el );\r\n view.render();\r\n },\r\n\r\n componentDidUpdate : function(){\r\n this.view.render();\r\n },\r\n\r\n componentWillUnmount : function(){\r\n var view = this.view;\r\n if( view.dispose ) view.dispose();\r\n }\r\n});\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/view-element.js\n ** module id = 5\n ** module chunks = 0\n **/"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap 30cc45000bca9f6814ea","webpack:///./src/main.js","webpack:///external {\"commonjs\":\"react\",\"commonjs2\":\"react\",\"amd\":\"react\",\"root\":\"React\"}","webpack:///external {\"commonjs\":\"react-dom\",\"commonjs2\":\"react-dom\",\"amd\":\"react-dom\",\"root\":\"ReactDOM\"}","webpack:///./src/createClass.js","webpack:///./src/component-view.js","webpack:///./src/view-element.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,mEAAkE,sBAAsB,EAAE;AAC1F;;AAEA;AACA,eAAc,kBAAkB,qCAAqC,EAAE,EAAE;AACzE,gBAAe,kBAAkB,qBAAqB,EAAE,EAAE;AAC1D,cAAa,yBAAyB,6BAA6B,EAAE;AACrE,MAAK;;AAEL;AACA;;;;;;;ACvBA,gD;;;;;;ACAA,gD;;;;;;ACAA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,4CAA2C,wBAAwB;AACnE;;AAEA;;AAEA;;AAEA;;AAEA;AACA,gDAA+C,wBAAwB;;AAEvE;AACA;;AAEA;AACA;;AAEA,6CAA4C,QAAQ;AACpD;AACA;AACA,gDAA+C;AAC/C;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;AC/FA;AACA;;AAEA;AACA;AACA,uDAAsD;AACtD;;AAEA;AACA;AACA,sBAAqB;AACrB;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,oBAAmB;AACnB;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;;;;;;ACpEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,UAAS;AACT,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,EAAC","file":"./react-bone.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"react\"), require(\"react-dom\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"react\", \"react-dom\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"React\"] = factory(require(\"react\"), require(\"react-dom\"));\n\telse\n\t\troot[\"React\"] = factory(root[\"React\"], root[\"ReactDOM\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_1__, __WEBPACK_EXTERNAL_MODULE_2__) {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 30cc45000bca9f6814ea\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nvar NestedReact = module.exports = Object.create( React );\r\n\r\nNestedReact.use = function( Backbone ){\r\n // listenToProps, listenToState, model, attributes, Model\r\n NestedReact.createClass = require( './createClass' ).use( Backbone );\r\n\r\n // React component for attaching views\r\n NestedReact.subview = require( './view-element' );\r\n\r\n // Extend react components to have jquery accessors\r\n var BaseComponent = Object.getPrototypeOf( React.createClass({ render : function(){} }).prototype ),\r\n $ = Backbone.$;\r\n\r\n Object.defineProperties( BaseComponent, {\r\n el : { get : function(){ return ReactDOM.findDOMNode( this ); } },\r\n $el : { get : function(){ return $( this.el ); } },\r\n $ : { value : function( sel ){ return this.$el.find( sel ); } }\r\n });\r\n\r\n NestedReact.use = function(){};\r\n}\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/main.js\n ** module id = 0\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_1__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external {\"commonjs\":\"react\",\"commonjs2\":\"react\",\"amd\":\"react\",\"root\":\"React\"}\n ** module id = 1\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_2__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external {\"commonjs\":\"react-dom\",\"commonjs2\":\"react-dom\",\"amd\":\"react-dom\",\"root\":\"ReactDOM\"}\n ** module id = 2\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nfunction assign( dest, source ){\r\n for( var i in source ) dest[ i ] = source[ i ];\r\n}\r\n\r\nexports.use = function( Backbone ){\r\n var ComponentView = require( './component-view' ).use( Backbone );\r\n\r\n function forceUpdate(){\r\n this.forceUpdate();\r\n }\r\n\r\n var Events = _.extend({\r\n componentWillUnmount : function(){\r\n this.stopListening();\r\n }\r\n }, Backbone.Events );\r\n\r\n var ListenToProps = {\r\n componentDidMount : function(){\r\n var props = this.props,\r\n updateOn = this.listenToProps;\r\n\r\n for( var prop in updateOn ){\r\n var emitter = props[ prop ];\r\n emitter && this.listenTo( emitter, updateOn[ prop ], forceUpdate );\r\n }\r\n }\r\n };\r\n\r\n var ModelState = {\r\n listenToState : 'change',\r\n model : null,\r\n\r\n getInitialState : function(){\r\n return this.model = new this.Model();\r\n },\r\n\r\n componentDidMount : function(){\r\n var events = this.listenToState;\r\n events && this.listenTo( this.state, events, forceUpdate );\r\n },\r\n\r\n componentWillUnmount : function(){\r\n this.state.stopListening();\r\n }\r\n };\r\n\r\n function createClass( spec ){\r\n var mixins = spec.mixins || ( spec.mixins = [] );\r\n\r\n var attributes = getModelAttributes( spec );\r\n if( attributes ){\r\n var BaseModel = spec.Model || Backbone.Model;\r\n spec.Model = BaseModel.extend({ defaults : attributes });\r\n }\r\n\r\n if( spec.Model ) mixins.push( ModelState );\r\n\r\n if( spec.listenToProps ) mixins.unshift( ListenToProps );\r\n\r\n mixins.push( Events );\r\n\r\n var component = React.createClass( spec );\r\n component.View = ComponentView.extend({ component : component });\r\n\r\n return component;\r\n };\r\n\r\n function getModelAttributes( spec ){\r\n var attributes = null;\r\n\r\n for( var i = spec.mixins.length - 1; i >= 0; i-- ){\r\n var mixin = spec.mixins[ i ];\r\n if( mixin.attributes ){\r\n attributes || ( attributes = {} );\r\n assign( attributes, mixin.attributes );\r\n }\r\n }\r\n\r\n if( spec.attributes ){\r\n if( attributes ){\r\n assign( attributes, spec.attributes );\r\n }\r\n else{\r\n attributes = spec.attributes;\r\n }\r\n }\r\n\r\n return attributes;\r\n }\r\n\r\n return createClass;\r\n}\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/createClass.js\n ** module id = 3\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nmodule.exports.use = function( Backbone ){\r\n var View = Backbone.View,\r\n dispose = View.prototype.dispose || function(){},\r\n setElement = View.prototype.setElement;\r\n\r\n var ComponentView = View.extend({\r\n reactClass : null,\r\n props : {},\r\n element : null,\r\n\r\n initialize : function( props ){\r\n // memorise arguments to pass to React\r\n this.options = props || {};\r\n this.element = React.createElement( this.reactClass, this.options );\r\n },\r\n\r\n setElement : function(){\r\n var $content = this.$el.children().detach(),\r\n res = setElement.apply( this, arguments );\r\n\r\n this.$el.append( $content );\r\n return res;\r\n },\r\n\r\n // cached instance of react component...\r\n component : null,\r\n\r\n render : function(){\r\n var component = ReactDOM.render( this.element, this.el );\r\n\r\n if( !this.component ){\r\n if( component && component.trigger ){\r\n // bubble up backbone events, if any\r\n this.listenTo( component, 'all', function(){\r\n this.trigger.apply( this, arguments );\r\n });\r\n }\r\n\r\n this.component = component;\r\n }\r\n },\r\n\r\n unmountComponent : function(){\r\n if( this.component && this.component.trigger ){\r\n this.stopListening( this.component );\r\n }\r\n\r\n ReactDOM.unmountComponentAtNode( this.el );\r\n this.component = null;\r\n },\r\n\r\n dispose : function(){\r\n this.unmountComponent();\r\n return dispose.apply( this, arguments );\r\n }\r\n });\r\n\r\n Object.defineProperty( ComponentView.prototype, 'model', {\r\n get : function(){\r\n this.component || this.render();\r\n return this.component && this.component.model;\r\n }\r\n });\r\n\r\n return ComponentView;\r\n};\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/component-view.js\n ** module id = 4\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nmodule.exports = React.createClass({\r\n displayName : 'BackboneView',\r\n\r\n propTypes : {\r\n View : React.PropTypes.func.isRequired,\r\n options : React.PropTypes.object\r\n },\r\n\r\n render : function(){\r\n return ReactDOM.div({\r\n ref : 'subview',\r\n className : this.props.className\r\n });\r\n },\r\n\r\n componentDidMount : function(){\r\n var el = this.refs.subview,\r\n p = this.props;\r\n\r\n var view = this.view = p.options ? new p.View( p.options ) : new p.View();\r\n\r\n if( el.getDOMNode ) el = el.getDOMNode();\r\n\r\n el.appendChild( view.el );\r\n view.render();\r\n },\r\n\r\n componentDidUpdate : function(){\r\n this.view.render();\r\n },\r\n\r\n componentWillUnmount : function(){\r\n var view = this.view;\r\n if( view.dispose ) view.dispose();\r\n }\r\n});\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/view-element.js\n ** module id = 5\n ** module chunks = 0\n **/"],"sourceRoot":""} \ No newline at end of file diff --git a/src/main.js b/src/main.js index bf40ecd..880dc9e 100644 --- a/src/main.js +++ b/src/main.js @@ -19,4 +19,6 @@ NestedReact.use = function( Backbone ){ $el : { get : function(){ return $( this.el ); } }, $ : { value : function( sel ){ return this.$el.find( sel ); } } }); + + NestedReact.use = function(){}; } From 9049a8ee5002ccc6e465a5791cfc4b7f9b274053 Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Thu, 22 Oct 2015 18:14:56 -0400 Subject: [PATCH 05/31] updated readme --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index ec1882f..94a7494 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,11 @@ http://volicon.github.io/backbone.nestedTypes/ and https://github.com/Volicon/backbone.nestedTypes +# Breaking changes introduced in 0.2 +- `component.createView( props )` doesn't work any more, use `new component.View( props )` instead. +- Library must be initialized with `.use` after load. +- module and npm package name is now `react-bone` + # Usage It's packed as single UMD, thus grab the module or use `npm` to install. `npm install --save react-bone` From 526f92b58da6dcf9156829b2363c855e3df1aa19 Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Thu, 5 Nov 2015 14:01:25 -0500 Subject: [PATCH 06/31] Changed to nestedreact --- nestedreact.js | 343 ++++++++++++++++++++++++++++++++++++++++++ nestedreact.js.map | 1 + package.json | 15 +- react-bone.js | 321 --------------------------------------- react-bone.js.map | 1 - src/component-view.js | 105 +++++++------ src/createClass.js | 139 +++++++++-------- src/main.js | 42 +++--- src/view-element.js | 26 +++- webpack.config.js | 53 ++++--- 10 files changed, 546 insertions(+), 500 deletions(-) create mode 100644 nestedreact.js create mode 100644 nestedreact.js.map delete mode 100644 react-bone.js delete mode 100644 react-bone.js.map diff --git a/nestedreact.js b/nestedreact.js new file mode 100644 index 0000000..26b9c33 --- /dev/null +++ b/nestedreact.js @@ -0,0 +1,343 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(require("react"), require("react-dom"), require("nestedtypes")); + else if(typeof define === 'function' && define.amd) + define(["react", "react-dom", "nestedtypes"], factory); + else if(typeof exports === 'object') + exports["React"] = factory(require("react"), require("react-dom"), require("nestedtypes")); + else + root["React"] = factory(root["React"], root["ReactDOM"], root["Nested"]); +})(this, function(__WEBPACK_EXTERNAL_MODULE_1__, __WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_3__) { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; +/******/ +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.loaded = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + var React = __webpack_require__( 1 ), + ReactDOM = __webpack_require__( 2 ), + Nested = __webpack_require__( 3 ), + $ = Nested.$; + + // extend React namespace + var NestedReact = module.exports = Object.create( React ); + + // listenToProps, listenToState, model, attributes, Model + NestedReact.createClass = __webpack_require__( 4 ); + + var ComponentView = __webpack_require__( 5 ); + + // export hook to override base View class used... + NestedReact.useView = function( View ){ + NestedReact._BaseView = ComponentView.use( View ); + }; + + NestedReact.useView( Nested.View ); + + // React component for attaching views + NestedReact.subview = __webpack_require__( 6 ); + + // Extend react components to have backbone-style jquery accessors + var Component = React.createClass( { render : function(){} } ), + BaseComponent = Object.getPrototypeOf( Component.prototype ); + + Object.defineProperties( BaseComponent, { + el : { get : function(){ return ReactDOM.findDOMNode( this ); } }, + $el : { get : function(){ return $( this.el ); } }, + $ : { value : function( sel ){ return this.$el.find( sel ); } } + } ); + + +/***/ }, +/* 1 */ +/***/ function(module, exports) { + + module.exports = __WEBPACK_EXTERNAL_MODULE_1__; + +/***/ }, +/* 2 */ +/***/ function(module, exports) { + + module.exports = __WEBPACK_EXTERNAL_MODULE_2__; + +/***/ }, +/* 3 */ +/***/ function(module, exports) { + + module.exports = __WEBPACK_EXTERNAL_MODULE_3__; + +/***/ }, +/* 4 */ +/***/ function(module, exports, __webpack_require__) { + + var React = __webpack_require__( 1 ), + ReactDOM = __webpack_require__( 2 ), + Nested = __webpack_require__( 3 ); + + function forceUpdate(){ this.forceUpdate(); } + + var Events = Object.assign( { + componentWillUnmount : function(){ + this.stopListening(); + } + }, Nested.Events ); + + var ListenToProps = { + componentDidMount : function(){ + var props = this.props, + updateOn = this.listenToProps; + + for( var prop in updateOn ){ + var emitter = props[ prop ]; + emitter && this.listenTo( emitter, updateOn[ prop ], forceUpdate ); + } + } + }; + + var ModelState = { + listenToState : 'change', + model : null, + + getInitialState : function(){ + return this.model = new this.Model(); + }, + + componentDidMount : function(){ + var events = this.listenToState; + events && this.listenTo( this.model, events, forceUpdate ); + }, + + componentWillUnmount : function(){ + this.model.stopListening(); + } + }; + + function createClass( spec ){ + var mixins = spec.mixins || ( spec.mixins = [] ); + + var attributes = getModelAttributes( spec ); + if( attributes ){ + var BaseModel = spec.Model || Nested.Model; + spec.Model = BaseModel.extend( { defaults : attributes } ); + } + + if( spec.Model ) mixins.push( ModelState ); + + if( spec.listenToProps ) mixins.unshift( ListenToProps ); + + mixins.push( Events ); + + var component = React.createClass( spec ); + + // attach lazily evaluated backbone View class + var NestedReact = this; + + Object.defineProperty( component, 'View', { + get : function(){ + return this._View || ( this._View = NestedReact._BaseView.extend( { component : component } ) ); + } + }); + + return component; + } + + function getModelAttributes( spec ){ + var attributes = null; + + for( var i = spec.mixins.length - 1; i >= 0; i-- ){ + var mixin = spec.mixins[ i ]; + if( mixin.attributes ){ + attributes || ( attributes = {} ); + Object.assign( attributes, mixin.attributes ); + } + } + + if( spec.attributes ){ + if( attributes ){ + Object.assign( attributes, spec.attributes ); + } + else{ + attributes = spec.attributes; + } + } + + return attributes; + } + + module.exports = createClass; + + +/***/ }, +/* 5 */ +/***/ function(module, exports, __webpack_require__) { + + var React = __webpack_require__( 1 ), + ReactDOM = __webpack_require__( 2 ); + + module.exports.use = function( View ){ + var dispose = View.prototype.dispose || function(){}, + setElement = View.prototype.setElement; + + var ComponentView = View.extend( { + reactClass : null, + props : {}, + element : null, + + initialize : function( props ){ + // memorise arguments to pass to React + this.options = props || {}; + this.element = React.createElement( this.reactClass, this.options ); + }, + + setElement : function(){ + var $content = this.$el.children().detach(), + res = setElement.apply( this, arguments ); + + this.$el.append( $content ); + return res; + }, + + // cached instance of react component... + component : null, + + render : function(){ + var component = ReactDOM.render( this.element, this.el ); + + if( !this.component ){ + if( component && component.trigger ){ + // bubble up backbone events, if any + this.listenTo( component, 'all', function(){ + this.trigger.apply( this, arguments ); + } ); + } + + this.component = component; + } + }, + + unmountComponent : function(){ + if( this.component && this.component.trigger ){ + this.stopListening( this.component ); + } + + ReactDOM.unmountComponentAtNode( this.el ); + this.component = null; + }, + + dispose : function(){ + this.unmountComponent(); + return dispose.apply( this, arguments ); + } + } ); + + Object.defineProperty( ComponentView.prototype, 'model', { + get : function(){ + this.component || this.render(); + return this.component && this.component.model; + } + } ); + + return ComponentView; + }; + + +/***/ }, +/* 6 */ +/***/ function(module, exports, __webpack_require__) { + + var React = __webpack_require__( 1 ), + ReactDOM = __webpack_require__( 2 ); + + module.exports = React.createClass({ + displayName : 'BackboneView', + + propTypes : { + View : React.PropTypes.func.isRequired, + options : React.PropTypes.object + }, + + render : function(){ + return ReactDOM.div({ + ref : 'subview', + className : this.props.className + }); + }, + + componentDidMount : function(){ + this._mountView(); + }, + componentDidUpdate : function(){ + this._dispose(); + this._mountView(); + }, + componentWillUnmount : function(){ + this._dispose(); + }, + + _mountView: function () { + var el = this.refs.subview, + p = this.props; + + var view = this.view = p.options ? new p.View( p.options ) : new p.View(); + + el.appendChild( view.el ); + view.render(); + }, + + _dispose : function(){ + var view = this.view; + if( view ){ + view.stopListening(); + if( view.dispose ) view.dispose(); + this.refs.subview.innerHTML = ""; + this.view = null; + } + } + }); + + +/***/ } +/******/ ]) +}); +; +//# sourceMappingURL=nestedreact.js.map \ No newline at end of file diff --git a/nestedreact.js.map b/nestedreact.js.map new file mode 100644 index 0000000..0c97af3 --- /dev/null +++ b/nestedreact.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap 2d874ff238fc1352e739","webpack:///./src/main.js","webpack:///external {\"commonjs\":\"react\",\"commonjs2\":\"react\",\"amd\":\"react\",\"root\":\"React\"}","webpack:///external {\"commonjs\":\"react-dom\",\"commonjs2\":\"react-dom\",\"amd\":\"react-dom\",\"root\":\"ReactDOM\"}","webpack:///external {\"commonjs\":\"nestedtypes\",\"commonjs2\":\"nestedtypes\",\"amd\":\"nestedtypes\",\"root\":\"Nested\"}","webpack:///./src/createClass.js","webpack:///./src/component-view.js","webpack:///./src/view-element.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,yCAAwC,sBAAsB,EAAE;AAChE;;AAEA;AACA,YAAW,kBAAkB,qCAAqC,EAAE,EAAE;AACtE,YAAW,kBAAkB,qBAAqB,EAAE,EAAE;AACtD,YAAW,yBAAyB,6BAA6B,EAAE;AACnE,EAAC;;;;;;;AC/BD,gD;;;;;;ACAA,gD;;;;;;ACAA,gD;;;;;;ACAA;AACA;AACA;;AAEA,wBAAuB,oBAAoB;;AAE3C;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,4CAA2C,wBAAwB;AACnE;;AAEA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA,gFAA+E,wBAAwB;AACvG;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;;AAEA,yCAAwC,QAAQ;AAChD;AACA;AACA,4CAA2C;AAC3C;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;;;;;;AC9FA;AACA;;AAEA;AACA,4DAA2D;AAC3D;;AAEA;AACA;AACA,wBAAuB;AACvB;;AAEA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;;AAEA;AACA;AACA,UAAS;;AAET;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,sBAAqB;AACrB;;AAEA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;;;;;;ACnEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,UAAS;AACT,MAAK;;AAEL;AACA;AACA,MAAK;AACL;AACA;AACA;AACA,MAAK;AACL;AACA;AACA,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC","file":"./nestedreact.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"react\"), require(\"react-dom\"), require(\"nestedtypes\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"react\", \"react-dom\", \"nestedtypes\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"React\"] = factory(require(\"react\"), require(\"react-dom\"), require(\"nestedtypes\"));\n\telse\n\t\troot[\"React\"] = factory(root[\"React\"], root[\"ReactDOM\"], root[\"Nested\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_1__, __WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_3__) {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 2d874ff238fc1352e739\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' ),\r\n Nested = require( 'nestedtypes' ),\r\n $ = Nested.$;\r\n\r\n// extend React namespace\r\nvar NestedReact = module.exports = Object.create( React );\r\n\r\n// listenToProps, listenToState, model, attributes, Model\r\nNestedReact.createClass = require( './createClass' );\r\n\r\nvar ComponentView = require( './component-view' );\r\n\r\n// export hook to override base View class used...\r\nNestedReact.useView = function( View ){\r\n NestedReact._BaseView = ComponentView.use( View );\r\n};\r\n\r\nNestedReact.useView( Nested.View );\r\n\r\n// React component for attaching views\r\nNestedReact.subview = require( './view-element' );\r\n\r\n// Extend react components to have backbone-style jquery accessors\r\nvar Component = React.createClass( { render : function(){} } ),\r\n BaseComponent = Object.getPrototypeOf( Component.prototype );\r\n\r\nObject.defineProperties( BaseComponent, {\r\n el : { get : function(){ return ReactDOM.findDOMNode( this ); } },\r\n $el : { get : function(){ return $( this.el ); } },\r\n $ : { value : function( sel ){ return this.$el.find( sel ); } }\r\n} );\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/main.js\n ** module id = 0\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_1__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external {\"commonjs\":\"react\",\"commonjs2\":\"react\",\"amd\":\"react\",\"root\":\"React\"}\n ** module id = 1\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_2__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external {\"commonjs\":\"react-dom\",\"commonjs2\":\"react-dom\",\"amd\":\"react-dom\",\"root\":\"ReactDOM\"}\n ** module id = 2\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_3__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external {\"commonjs\":\"nestedtypes\",\"commonjs2\":\"nestedtypes\",\"amd\":\"nestedtypes\",\"root\":\"Nested\"}\n ** module id = 3\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' ),\r\n Nested = require( 'nestedtypes' );\r\n\r\nfunction forceUpdate(){ this.forceUpdate(); }\r\n\r\nvar Events = Object.assign( {\r\n componentWillUnmount : function(){\r\n this.stopListening();\r\n }\r\n}, Nested.Events );\r\n\r\nvar ListenToProps = {\r\n componentDidMount : function(){\r\n var props = this.props,\r\n updateOn = this.listenToProps;\r\n\r\n for( var prop in updateOn ){\r\n var emitter = props[ prop ];\r\n emitter && this.listenTo( emitter, updateOn[ prop ], forceUpdate );\r\n }\r\n }\r\n};\r\n\r\nvar ModelState = {\r\n listenToState : 'change',\r\n model : null,\r\n\r\n getInitialState : function(){\r\n return this.model = new this.Model();\r\n },\r\n\r\n componentDidMount : function(){\r\n var events = this.listenToState;\r\n events && this.listenTo( this.model, events, forceUpdate );\r\n },\r\n\r\n componentWillUnmount : function(){\r\n this.model.stopListening();\r\n }\r\n};\r\n\r\nfunction createClass( spec ){\r\n var mixins = spec.mixins || ( spec.mixins = [] );\r\n\r\n var attributes = getModelAttributes( spec );\r\n if( attributes ){\r\n var BaseModel = spec.Model || Nested.Model;\r\n spec.Model = BaseModel.extend( { defaults : attributes } );\r\n }\r\n\r\n if( spec.Model ) mixins.push( ModelState );\r\n\r\n if( spec.listenToProps ) mixins.unshift( ListenToProps );\r\n\r\n mixins.push( Events );\r\n\r\n var component = React.createClass( spec );\r\n\r\n // attach lazily evaluated backbone View class\r\n var NestedReact = this;\r\n\r\n Object.defineProperty( component, 'View', {\r\n get : function(){\r\n return this._View || ( this._View = NestedReact._BaseView.extend( { component : component } ) );\r\n }\r\n });\r\n\r\n return component;\r\n}\r\n\r\nfunction getModelAttributes( spec ){\r\n var attributes = null;\r\n\r\n for( var i = spec.mixins.length - 1; i >= 0; i-- ){\r\n var mixin = spec.mixins[ i ];\r\n if( mixin.attributes ){\r\n attributes || ( attributes = {} );\r\n Object.assign( attributes, mixin.attributes );\r\n }\r\n }\r\n\r\n if( spec.attributes ){\r\n if( attributes ){\r\n Object.assign( attributes, spec.attributes );\r\n }\r\n else{\r\n attributes = spec.attributes;\r\n }\r\n }\r\n\r\n return attributes;\r\n}\r\n\r\nmodule.exports = createClass;\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/createClass.js\n ** module id = 4\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nmodule.exports.use = function( View ){\r\n var dispose = View.prototype.dispose || function(){},\r\n setElement = View.prototype.setElement;\r\n\r\n var ComponentView = View.extend( {\r\n reactClass : null,\r\n props : {},\r\n element : null,\r\n\r\n initialize : function( props ){\r\n // memorise arguments to pass to React\r\n this.options = props || {};\r\n this.element = React.createElement( this.reactClass, this.options );\r\n },\r\n\r\n setElement : function(){\r\n var $content = this.$el.children().detach(),\r\n res = setElement.apply( this, arguments );\r\n\r\n this.$el.append( $content );\r\n return res;\r\n },\r\n\r\n // cached instance of react component...\r\n component : null,\r\n\r\n render : function(){\r\n var component = ReactDOM.render( this.element, this.el );\r\n\r\n if( !this.component ){\r\n if( component && component.trigger ){\r\n // bubble up backbone events, if any\r\n this.listenTo( component, 'all', function(){\r\n this.trigger.apply( this, arguments );\r\n } );\r\n }\r\n\r\n this.component = component;\r\n }\r\n },\r\n\r\n unmountComponent : function(){\r\n if( this.component && this.component.trigger ){\r\n this.stopListening( this.component );\r\n }\r\n\r\n ReactDOM.unmountComponentAtNode( this.el );\r\n this.component = null;\r\n },\r\n\r\n dispose : function(){\r\n this.unmountComponent();\r\n return dispose.apply( this, arguments );\r\n }\r\n } );\r\n\r\n Object.defineProperty( ComponentView.prototype, 'model', {\r\n get : function(){\r\n this.component || this.render();\r\n return this.component && this.component.model;\r\n }\r\n } );\r\n\r\n return ComponentView;\r\n};\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/component-view.js\n ** module id = 5\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nmodule.exports = React.createClass({\r\n displayName : 'BackboneView',\r\n\r\n propTypes : {\r\n View : React.PropTypes.func.isRequired,\r\n options : React.PropTypes.object\r\n },\r\n\r\n render : function(){\r\n return ReactDOM.div({\r\n ref : 'subview',\r\n className : this.props.className\r\n });\r\n },\r\n\r\n componentDidMount : function(){\r\n this._mountView();\r\n },\r\n componentDidUpdate : function(){\r\n this._dispose();\r\n this._mountView();\r\n },\r\n componentWillUnmount : function(){\r\n this._dispose();\r\n },\r\n\r\n _mountView: function () {\r\n var el = this.refs.subview,\r\n p = this.props;\r\n\r\n var view = this.view = p.options ? new p.View( p.options ) : new p.View();\r\n\r\n el.appendChild( view.el );\r\n view.render();\r\n },\r\n\r\n _dispose : function(){\r\n var view = this.view;\r\n if( view ){\r\n view.stopListening();\r\n if( view.dispose ) view.dispose();\r\n this.refs.subview.innerHTML = \"\";\r\n this.view = null;\r\n }\r\n }\r\n});\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/view-element.js\n ** module id = 6\n ** module chunks = 0\n **/"],"sourceRoot":""} \ No newline at end of file diff --git a/package.json b/package.json index 440c4af..f716c1f 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,11 @@ { - "name": "react-bone", - "main": "react-bone.js", + "name": "nestedreact", + "main": "nestedreact.js", "description": "Essential tool for migration to React in large Backbone application", "homepage": "https://github.com/Volicon/react-backbone.glue", "keywords": [ "backbone", + "nestedtypes", "react" ], "repository": { @@ -15,20 +16,20 @@ "contributors": "", "dependencies": { "react": "^0.14.0", - "react-dom": "^0.14.0" + "react-dom": "^0.14.0", + "nestedtypes" : "^1.1.5" }, "devDependencies": { - "backbone": "*", "jquery": "^2.1.4", "underscore": "^1.8.3", "webpack": "^1.12.2" }, "files": [ - "react-bone.js", - "react-bone.js.map" + "nestedreact.js", + "nestedreact.js.map" ], "license": "MIT", - "version": "0.2.0", + "version": "0.3.0", "scripts": { "build": "./node_modules/.bin/webpack", "watch": "./node_modules/.bin/webpack --watch" diff --git a/react-bone.js b/react-bone.js deleted file mode 100644 index 7f99056..0000000 --- a/react-bone.js +++ /dev/null @@ -1,321 +0,0 @@ -(function webpackUniversalModuleDefinition(root, factory) { - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(require("react"), require("react-dom")); - else if(typeof define === 'function' && define.amd) - define(["react", "react-dom"], factory); - else if(typeof exports === 'object') - exports["React"] = factory(require("react"), require("react-dom")); - else - root["React"] = factory(root["React"], root["ReactDOM"]); -})(this, function(__WEBPACK_EXTERNAL_MODULE_1__, __WEBPACK_EXTERNAL_MODULE_2__) { -return /******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) -/******/ return installedModules[moduleId].exports; -/******/ -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ exports: {}, -/******/ id: moduleId, -/******/ loaded: false -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.loaded = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ function(module, exports, __webpack_require__) { - - var React = __webpack_require__( 1 ), - ReactDOM = __webpack_require__( 2 ); - - var NestedReact = module.exports = Object.create( React ); - - NestedReact.use = function( Backbone ){ - // listenToProps, listenToState, model, attributes, Model - NestedReact.createClass = __webpack_require__( 3 ).use( Backbone ); - - // React component for attaching views - NestedReact.subview = __webpack_require__( 5 ); - - // Extend react components to have jquery accessors - var BaseComponent = Object.getPrototypeOf( React.createClass({ render : function(){} }).prototype ), - $ = Backbone.$; - - Object.defineProperties( BaseComponent, { - el : { get : function(){ return ReactDOM.findDOMNode( this ); } }, - $el : { get : function(){ return $( this.el ); } }, - $ : { value : function( sel ){ return this.$el.find( sel ); } } - }); - - NestedReact.use = function(){}; - } - - -/***/ }, -/* 1 */ -/***/ function(module, exports) { - - module.exports = __WEBPACK_EXTERNAL_MODULE_1__; - -/***/ }, -/* 2 */ -/***/ function(module, exports) { - - module.exports = __WEBPACK_EXTERNAL_MODULE_2__; - -/***/ }, -/* 3 */ -/***/ function(module, exports, __webpack_require__) { - - var React = __webpack_require__( 1 ), - ReactDOM = __webpack_require__( 2 ); - - function assign( dest, source ){ - for( var i in source ) dest[ i ] = source[ i ]; - } - - exports.use = function( Backbone ){ - var ComponentView = __webpack_require__( 4 ).use( Backbone ); - - function forceUpdate(){ - this.forceUpdate(); - } - - var Events = _.extend({ - componentWillUnmount : function(){ - this.stopListening(); - } - }, Backbone.Events ); - - var ListenToProps = { - componentDidMount : function(){ - var props = this.props, - updateOn = this.listenToProps; - - for( var prop in updateOn ){ - var emitter = props[ prop ]; - emitter && this.listenTo( emitter, updateOn[ prop ], forceUpdate ); - } - } - }; - - var ModelState = { - listenToState : 'change', - model : null, - - getInitialState : function(){ - return this.model = new this.Model(); - }, - - componentDidMount : function(){ - var events = this.listenToState; - events && this.listenTo( this.state, events, forceUpdate ); - }, - - componentWillUnmount : function(){ - this.state.stopListening(); - } - }; - - function createClass( spec ){ - var mixins = spec.mixins || ( spec.mixins = [] ); - - var attributes = getModelAttributes( spec ); - if( attributes ){ - var BaseModel = spec.Model || Backbone.Model; - spec.Model = BaseModel.extend({ defaults : attributes }); - } - - if( spec.Model ) mixins.push( ModelState ); - - if( spec.listenToProps ) mixins.unshift( ListenToProps ); - - mixins.push( Events ); - - var component = React.createClass( spec ); - component.View = ComponentView.extend({ component : component }); - - return component; - }; - - function getModelAttributes( spec ){ - var attributes = null; - - for( var i = spec.mixins.length - 1; i >= 0; i-- ){ - var mixin = spec.mixins[ i ]; - if( mixin.attributes ){ - attributes || ( attributes = {} ); - assign( attributes, mixin.attributes ); - } - } - - if( spec.attributes ){ - if( attributes ){ - assign( attributes, spec.attributes ); - } - else{ - attributes = spec.attributes; - } - } - - return attributes; - } - - return createClass; - } - - -/***/ }, -/* 4 */ -/***/ function(module, exports, __webpack_require__) { - - var React = __webpack_require__( 1 ), - ReactDOM = __webpack_require__( 2 ); - - module.exports.use = function( Backbone ){ - var View = Backbone.View, - dispose = View.prototype.dispose || function(){}, - setElement = View.prototype.setElement; - - var ComponentView = View.extend({ - reactClass : null, - props : {}, - element : null, - - initialize : function( props ){ - // memorise arguments to pass to React - this.options = props || {}; - this.element = React.createElement( this.reactClass, this.options ); - }, - - setElement : function(){ - var $content = this.$el.children().detach(), - res = setElement.apply( this, arguments ); - - this.$el.append( $content ); - return res; - }, - - // cached instance of react component... - component : null, - - render : function(){ - var component = ReactDOM.render( this.element, this.el ); - - if( !this.component ){ - if( component && component.trigger ){ - // bubble up backbone events, if any - this.listenTo( component, 'all', function(){ - this.trigger.apply( this, arguments ); - }); - } - - this.component = component; - } - }, - - unmountComponent : function(){ - if( this.component && this.component.trigger ){ - this.stopListening( this.component ); - } - - ReactDOM.unmountComponentAtNode( this.el ); - this.component = null; - }, - - dispose : function(){ - this.unmountComponent(); - return dispose.apply( this, arguments ); - } - }); - - Object.defineProperty( ComponentView.prototype, 'model', { - get : function(){ - this.component || this.render(); - return this.component && this.component.model; - } - }); - - return ComponentView; - }; - - -/***/ }, -/* 5 */ -/***/ function(module, exports, __webpack_require__) { - - var React = __webpack_require__( 1 ), - ReactDOM = __webpack_require__( 2 ); - - module.exports = React.createClass({ - displayName : 'BackboneView', - - propTypes : { - View : React.PropTypes.func.isRequired, - options : React.PropTypes.object - }, - - render : function(){ - return ReactDOM.div({ - ref : 'subview', - className : this.props.className - }); - }, - - componentDidMount : function(){ - var el = this.refs.subview, - p = this.props; - - var view = this.view = p.options ? new p.View( p.options ) : new p.View(); - - if( el.getDOMNode ) el = el.getDOMNode(); - - el.appendChild( view.el ); - view.render(); - }, - - componentDidUpdate : function(){ - this.view.render(); - }, - - componentWillUnmount : function(){ - var view = this.view; - if( view.dispose ) view.dispose(); - } - }); - - -/***/ } -/******/ ]) -}); -; -//# sourceMappingURL=react-bone.js.map \ No newline at end of file diff --git a/react-bone.js.map b/react-bone.js.map deleted file mode 100644 index 56a60e9..0000000 --- a/react-bone.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap 30cc45000bca9f6814ea","webpack:///./src/main.js","webpack:///external {\"commonjs\":\"react\",\"commonjs2\":\"react\",\"amd\":\"react\",\"root\":\"React\"}","webpack:///external {\"commonjs\":\"react-dom\",\"commonjs2\":\"react-dom\",\"amd\":\"react-dom\",\"root\":\"ReactDOM\"}","webpack:///./src/createClass.js","webpack:///./src/component-view.js","webpack:///./src/view-element.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,mEAAkE,sBAAsB,EAAE;AAC1F;;AAEA;AACA,eAAc,kBAAkB,qCAAqC,EAAE,EAAE;AACzE,gBAAe,kBAAkB,qBAAqB,EAAE,EAAE;AAC1D,cAAa,yBAAyB,6BAA6B,EAAE;AACrE,MAAK;;AAEL;AACA;;;;;;;ACvBA,gD;;;;;;ACAA,gD;;;;;;ACAA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,4CAA2C,wBAAwB;AACnE;;AAEA;;AAEA;;AAEA;;AAEA;AACA,gDAA+C,wBAAwB;;AAEvE;AACA;;AAEA;AACA;;AAEA,6CAA4C,QAAQ;AACpD;AACA;AACA,gDAA+C;AAC/C;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;AC/FA;AACA;;AAEA;AACA;AACA,uDAAsD;AACtD;;AAEA;AACA;AACA,sBAAqB;AACrB;;AAEA;AACA;AACA;AACA;AACA,QAAO;;AAEP;AACA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,oBAAmB;AACnB;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAO;;AAEP;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;;;;;;ACpEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,UAAS;AACT,MAAK;;AAEL;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,MAAK;;AAEL;AACA;AACA,MAAK;;AAEL;AACA;AACA;AACA;AACA,EAAC","file":"./react-bone.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"react\"), require(\"react-dom\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"react\", \"react-dom\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"React\"] = factory(require(\"react\"), require(\"react-dom\"));\n\telse\n\t\troot[\"React\"] = factory(root[\"React\"], root[\"ReactDOM\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_1__, __WEBPACK_EXTERNAL_MODULE_2__) {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 30cc45000bca9f6814ea\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nvar NestedReact = module.exports = Object.create( React );\r\n\r\nNestedReact.use = function( Backbone ){\r\n // listenToProps, listenToState, model, attributes, Model\r\n NestedReact.createClass = require( './createClass' ).use( Backbone );\r\n\r\n // React component for attaching views\r\n NestedReact.subview = require( './view-element' );\r\n\r\n // Extend react components to have jquery accessors\r\n var BaseComponent = Object.getPrototypeOf( React.createClass({ render : function(){} }).prototype ),\r\n $ = Backbone.$;\r\n\r\n Object.defineProperties( BaseComponent, {\r\n el : { get : function(){ return ReactDOM.findDOMNode( this ); } },\r\n $el : { get : function(){ return $( this.el ); } },\r\n $ : { value : function( sel ){ return this.$el.find( sel ); } }\r\n });\r\n\r\n NestedReact.use = function(){};\r\n}\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/main.js\n ** module id = 0\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_1__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external {\"commonjs\":\"react\",\"commonjs2\":\"react\",\"amd\":\"react\",\"root\":\"React\"}\n ** module id = 1\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_2__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external {\"commonjs\":\"react-dom\",\"commonjs2\":\"react-dom\",\"amd\":\"react-dom\",\"root\":\"ReactDOM\"}\n ** module id = 2\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nfunction assign( dest, source ){\r\n for( var i in source ) dest[ i ] = source[ i ];\r\n}\r\n\r\nexports.use = function( Backbone ){\r\n var ComponentView = require( './component-view' ).use( Backbone );\r\n\r\n function forceUpdate(){\r\n this.forceUpdate();\r\n }\r\n\r\n var Events = _.extend({\r\n componentWillUnmount : function(){\r\n this.stopListening();\r\n }\r\n }, Backbone.Events );\r\n\r\n var ListenToProps = {\r\n componentDidMount : function(){\r\n var props = this.props,\r\n updateOn = this.listenToProps;\r\n\r\n for( var prop in updateOn ){\r\n var emitter = props[ prop ];\r\n emitter && this.listenTo( emitter, updateOn[ prop ], forceUpdate );\r\n }\r\n }\r\n };\r\n\r\n var ModelState = {\r\n listenToState : 'change',\r\n model : null,\r\n\r\n getInitialState : function(){\r\n return this.model = new this.Model();\r\n },\r\n\r\n componentDidMount : function(){\r\n var events = this.listenToState;\r\n events && this.listenTo( this.state, events, forceUpdate );\r\n },\r\n\r\n componentWillUnmount : function(){\r\n this.state.stopListening();\r\n }\r\n };\r\n\r\n function createClass( spec ){\r\n var mixins = spec.mixins || ( spec.mixins = [] );\r\n\r\n var attributes = getModelAttributes( spec );\r\n if( attributes ){\r\n var BaseModel = spec.Model || Backbone.Model;\r\n spec.Model = BaseModel.extend({ defaults : attributes });\r\n }\r\n\r\n if( spec.Model ) mixins.push( ModelState );\r\n\r\n if( spec.listenToProps ) mixins.unshift( ListenToProps );\r\n\r\n mixins.push( Events );\r\n\r\n var component = React.createClass( spec );\r\n component.View = ComponentView.extend({ component : component });\r\n\r\n return component;\r\n };\r\n\r\n function getModelAttributes( spec ){\r\n var attributes = null;\r\n\r\n for( var i = spec.mixins.length - 1; i >= 0; i-- ){\r\n var mixin = spec.mixins[ i ];\r\n if( mixin.attributes ){\r\n attributes || ( attributes = {} );\r\n assign( attributes, mixin.attributes );\r\n }\r\n }\r\n\r\n if( spec.attributes ){\r\n if( attributes ){\r\n assign( attributes, spec.attributes );\r\n }\r\n else{\r\n attributes = spec.attributes;\r\n }\r\n }\r\n\r\n return attributes;\r\n }\r\n\r\n return createClass;\r\n}\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/createClass.js\n ** module id = 3\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nmodule.exports.use = function( Backbone ){\r\n var View = Backbone.View,\r\n dispose = View.prototype.dispose || function(){},\r\n setElement = View.prototype.setElement;\r\n\r\n var ComponentView = View.extend({\r\n reactClass : null,\r\n props : {},\r\n element : null,\r\n\r\n initialize : function( props ){\r\n // memorise arguments to pass to React\r\n this.options = props || {};\r\n this.element = React.createElement( this.reactClass, this.options );\r\n },\r\n\r\n setElement : function(){\r\n var $content = this.$el.children().detach(),\r\n res = setElement.apply( this, arguments );\r\n\r\n this.$el.append( $content );\r\n return res;\r\n },\r\n\r\n // cached instance of react component...\r\n component : null,\r\n\r\n render : function(){\r\n var component = ReactDOM.render( this.element, this.el );\r\n\r\n if( !this.component ){\r\n if( component && component.trigger ){\r\n // bubble up backbone events, if any\r\n this.listenTo( component, 'all', function(){\r\n this.trigger.apply( this, arguments );\r\n });\r\n }\r\n\r\n this.component = component;\r\n }\r\n },\r\n\r\n unmountComponent : function(){\r\n if( this.component && this.component.trigger ){\r\n this.stopListening( this.component );\r\n }\r\n\r\n ReactDOM.unmountComponentAtNode( this.el );\r\n this.component = null;\r\n },\r\n\r\n dispose : function(){\r\n this.unmountComponent();\r\n return dispose.apply( this, arguments );\r\n }\r\n });\r\n\r\n Object.defineProperty( ComponentView.prototype, 'model', {\r\n get : function(){\r\n this.component || this.render();\r\n return this.component && this.component.model;\r\n }\r\n });\r\n\r\n return ComponentView;\r\n};\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/component-view.js\n ** module id = 4\n ** module chunks = 0\n **/","var React = require( 'react' ),\r\n ReactDOM = require( 'react-dom' );\r\n\r\nmodule.exports = React.createClass({\r\n displayName : 'BackboneView',\r\n\r\n propTypes : {\r\n View : React.PropTypes.func.isRequired,\r\n options : React.PropTypes.object\r\n },\r\n\r\n render : function(){\r\n return ReactDOM.div({\r\n ref : 'subview',\r\n className : this.props.className\r\n });\r\n },\r\n\r\n componentDidMount : function(){\r\n var el = this.refs.subview,\r\n p = this.props;\r\n\r\n var view = this.view = p.options ? new p.View( p.options ) : new p.View();\r\n\r\n if( el.getDOMNode ) el = el.getDOMNode();\r\n\r\n el.appendChild( view.el );\r\n view.render();\r\n },\r\n\r\n componentDidUpdate : function(){\r\n this.view.render();\r\n },\r\n\r\n componentWillUnmount : function(){\r\n var view = this.view;\r\n if( view.dispose ) view.dispose();\r\n }\r\n});\r\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./src/view-element.js\n ** module id = 5\n ** module chunks = 0\n **/"],"sourceRoot":""} \ No newline at end of file diff --git a/src/component-view.js b/src/component-view.js index 9c5d22d..2405816 100644 --- a/src/component-view.js +++ b/src/component-view.js @@ -1,69 +1,68 @@ -var React = require( 'react' ), +var React = require( 'react' ), ReactDOM = require( 'react-dom' ); -module.exports.use = function( Backbone ){ - var View = Backbone.View, - dispose = View.prototype.dispose || function(){}, - setElement = View.prototype.setElement; +module.exports.use = function( View ){ + var dispose = View.prototype.dispose || function(){}, + setElement = View.prototype.setElement; - var ComponentView = View.extend({ - reactClass : null, - props : {}, - element : null, + var ComponentView = View.extend( { + reactClass : null, + props : {}, + element : null, - initialize : function( props ){ - // memorise arguments to pass to React - this.options = props || {}; - this.element = React.createElement( this.reactClass, this.options ); - }, + initialize : function( props ){ + // memorise arguments to pass to React + this.options = props || {}; + this.element = React.createElement( this.reactClass, this.options ); + }, - setElement : function(){ - var $content = this.$el.children().detach(), - res = setElement.apply( this, arguments ); + setElement : function(){ + var $content = this.$el.children().detach(), + res = setElement.apply( this, arguments ); - this.$el.append( $content ); - return res; - }, + this.$el.append( $content ); + return res; + }, - // cached instance of react component... - component : null, + // cached instance of react component... + component : null, - render : function(){ - var component = ReactDOM.render( this.element, this.el ); + render : function(){ + var component = ReactDOM.render( this.element, this.el ); - if( !this.component ){ - if( component && component.trigger ){ - // bubble up backbone events, if any - this.listenTo( component, 'all', function(){ - this.trigger.apply( this, arguments ); - }); - } + if( !this.component ){ + if( component && component.trigger ){ + // bubble up backbone events, if any + this.listenTo( component, 'all', function(){ + this.trigger.apply( this, arguments ); + } ); + } - this.component = component; - } - }, + this.component = component; + } + }, - unmountComponent : function(){ - if( this.component && this.component.trigger ){ - this.stopListening( this.component ); - } + unmountComponent : function(){ + if( this.component && this.component.trigger ){ + this.stopListening( this.component ); + } - ReactDOM.unmountComponentAtNode( this.el ); - this.component = null; - }, + ReactDOM.unmountComponentAtNode( this.el ); + this.component = null; + }, - dispose : function(){ - this.unmountComponent(); - return dispose.apply( this, arguments ); - } - }); + dispose : function(){ + this.unmountComponent(); + return dispose.apply( this, arguments ); + } + } ); - Object.defineProperty( ComponentView.prototype, 'model', { - get : function(){ - this.component || this.render(); - return this.component && this.component.model; - } - }); + Object.defineProperty( ComponentView.prototype, 'model', { + get : function(){ + this.component || this.render(); + return this.component && this.component.model; + } + } ); - return ComponentView; + return ComponentView; }; diff --git a/src/createClass.js b/src/createClass.js index 5b53f3c..f2b13e0 100644 --- a/src/createClass.js +++ b/src/createClass.js @@ -1,96 +1,95 @@ -var React = require( 'react' ), - ReactDOM = require( 'react-dom' ); +var React = require( 'react' ), + ReactDOM = require( 'react-dom' ), + Nested = require( 'nestedtypes' ); -function assign( dest, source ){ - for( var i in source ) dest[ i ] = source[ i ]; -} - -exports.use = function( Backbone ){ - var ComponentView = require( './component-view' ).use( Backbone ); +function forceUpdate(){ this.forceUpdate(); } - function forceUpdate(){ - this.forceUpdate(); +var Events = Object.assign( { + componentWillUnmount : function(){ + this.stopListening(); } +}, Nested.Events ); - var Events = _.extend({ - componentWillUnmount : function(){ - this.stopListening(); - } - }, Backbone.Events ); - - var ListenToProps = { - componentDidMount : function(){ - var props = this.props, +var ListenToProps = { + componentDidMount : function(){ + var props = this.props, updateOn = this.listenToProps; - for( var prop in updateOn ){ - var emitter = props[ prop ]; - emitter && this.listenTo( emitter, updateOn[ prop ], forceUpdate ); - } + for( var prop in updateOn ){ + var emitter = props[ prop ]; + emitter && this.listenTo( emitter, updateOn[ prop ], forceUpdate ); } - }; - - var ModelState = { - listenToState : 'change', - model : null, + } +}; - getInitialState : function(){ - return this.model = new this.Model(); - }, +var ModelState = { + listenToState : 'change', + model : null, - componentDidMount : function(){ - var events = this.listenToState; - events && this.listenTo( this.state, events, forceUpdate ); - }, + getInitialState : function(){ + return this.model = new this.Model(); + }, - componentWillUnmount : function(){ - this.state.stopListening(); - } - }; + componentDidMount : function(){ + var events = this.listenToState; + events && this.listenTo( this.model, events, forceUpdate ); + }, - function createClass( spec ){ - var mixins = spec.mixins || ( spec.mixins = [] ); + componentWillUnmount : function(){ + this.model.stopListening(); + } +}; - var attributes = getModelAttributes( spec ); - if( attributes ){ - var BaseModel = spec.Model || Backbone.Model; - spec.Model = BaseModel.extend({ defaults : attributes }); - } +function createClass( spec ){ + var mixins = spec.mixins || ( spec.mixins = [] ); - if( spec.Model ) mixins.push( ModelState ); + var attributes = getModelAttributes( spec ); + if( attributes ){ + var BaseModel = spec.Model || Nested.Model; + spec.Model = BaseModel.extend( { defaults : attributes } ); + } - if( spec.listenToProps ) mixins.unshift( ListenToProps ); + if( spec.Model ) mixins.push( ModelState ); - mixins.push( Events ); + if( spec.listenToProps ) mixins.unshift( ListenToProps ); - var component = React.createClass( spec ); - component.View = ComponentView.extend({ component : component }); + mixins.push( Events ); - return component; - }; + var component = React.createClass( spec ); - function getModelAttributes( spec ){ - var attributes = null; + // attach lazily evaluated backbone View class + var NestedReact = this; - for( var i = spec.mixins.length - 1; i >= 0; i-- ){ - var mixin = spec.mixins[ i ]; - if( mixin.attributes ){ - attributes || ( attributes = {} ); - assign( attributes, mixin.attributes ); - } + Object.defineProperty( component, 'View', { + get : function(){ + return this._View || ( this._View = NestedReact._BaseView.extend( { component : component } ) ); } + }); + + return component; +} - if( spec.attributes ){ - if( attributes ){ - assign( attributes, spec.attributes ); - } - else{ - attributes = spec.attributes; - } +function getModelAttributes( spec ){ + var attributes = null; + + for( var i = spec.mixins.length - 1; i >= 0; i-- ){ + var mixin = spec.mixins[ i ]; + if( mixin.attributes ){ + attributes || ( attributes = {} ); + Object.assign( attributes, mixin.attributes ); } + } - return attributes; + if( spec.attributes ){ + if( attributes ){ + Object.assign( attributes, spec.attributes ); + } + else{ + attributes = spec.attributes; + } } - return createClass; + return attributes; } + +module.exports = createClass; diff --git a/src/main.js b/src/main.js index 880dc9e..068a0c0 100644 --- a/src/main.js +++ b/src/main.js @@ -1,24 +1,32 @@ -var React = require( 'react' ), - ReactDOM = require( 'react-dom' ); +var React = require( 'react' ), + ReactDOM = require( 'react-dom' ), + Nested = require( 'nestedtypes' ), + $ = Nested.$; +// extend React namespace var NestedReact = module.exports = Object.create( React ); -NestedReact.use = function( Backbone ){ - // listenToProps, listenToState, model, attributes, Model - NestedReact.createClass = require( './createClass' ).use( Backbone ); +// listenToProps, listenToState, model, attributes, Model +NestedReact.createClass = require( './createClass' ); - // React component for attaching views - NestedReact.subview = require( './view-element' ); +var ComponentView = require( './component-view' ); - // Extend react components to have jquery accessors - var BaseComponent = Object.getPrototypeOf( React.createClass({ render : function(){} }).prototype ), - $ = Backbone.$; +// export hook to override base View class used... +NestedReact.useView = function( View ){ + NestedReact._BaseView = ComponentView.use( View ); +}; - Object.defineProperties( BaseComponent, { - el : { get : function(){ return ReactDOM.findDOMNode( this ); } }, - $el : { get : function(){ return $( this.el ); } }, - $ : { value : function( sel ){ return this.$el.find( sel ); } } - }); +NestedReact.useView( Nested.View ); - NestedReact.use = function(){}; -} +// React component for attaching views +NestedReact.subview = require( './view-element' ); + +// Extend react components to have backbone-style jquery accessors +var Component = React.createClass( { render : function(){} } ), + BaseComponent = Object.getPrototypeOf( Component.prototype ); + +Object.defineProperties( BaseComponent, { + el : { get : function(){ return ReactDOM.findDOMNode( this ); } }, + $el : { get : function(){ return $( this.el ); } }, + $ : { value : function( sel ){ return this.$el.find( sel ); } } +} ); diff --git a/src/view-element.js b/src/view-element.js index 5eda71f..f7d43f1 100644 --- a/src/view-element.js +++ b/src/view-element.js @@ -17,23 +17,33 @@ module.exports = React.createClass({ }, componentDidMount : function(){ + this._mountView(); + }, + componentDidUpdate : function(){ + this._dispose(); + this._mountView(); + }, + componentWillUnmount : function(){ + this._dispose(); + }, + + _mountView: function () { var el = this.refs.subview, p = this.props; var view = this.view = p.options ? new p.View( p.options ) : new p.View(); - if( el.getDOMNode ) el = el.getDOMNode(); - el.appendChild( view.el ); view.render(); }, - componentDidUpdate : function(){ - this.view.render(); - }, - - componentWillUnmount : function(){ + _dispose : function(){ var view = this.view; - if( view.dispose ) view.dispose(); + if( view ){ + view.stopListening(); + if( view.dispose ) view.dispose(); + this.refs.subview.innerHTML = ""; + this.view = null; + } } }); diff --git a/webpack.config.js b/webpack.config.js index 7874e3c..9aed0e6 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,29 +1,36 @@ module.exports = { - entry: "./src/main", + entry : "./src/main", - output : { - filename : './react-bone.js', - library : "React", - libraryTarget : 'umd' - }, + output : { + filename : './nestedreact.js', + library : "React", + libraryTarget : 'umd' + }, - devtool : 'source-map', + devtool : 'source-map', - externals : [ - { - 'react' : { - commonjs : 'react', - commonjs2 : 'react', - amd : 'react', - root : 'React' - }, + externals : [ + { + 'nestedtypes' : { + commonjs : 'nestedtypes', + commonjs2 : 'nestedtypes', + amd : 'nestedtypes', + root : 'Nested' + }, - 'react-dom' : { - commonjs : 'react-dom', - commonjs2 : 'react-dom', - amd : 'react-dom', - root : 'ReactDOM' - } - } - ] + 'react' : { + commonjs : 'react', + commonjs2 : 'react', + amd : 'react', + root : 'React' + }, + + 'react-dom' : { + commonjs : 'react-dom', + commonjs2 : 'react-dom', + amd : 'react-dom', + root : 'ReactDOM' + } + } + ] }; From 5e1aeeab279824bea5c39166860bdb1fad3403cd Mon Sep 17 00:00:00 2001 From: Vlad Balin Date: Thu, 5 Nov 2015 14:13:06 -0500 Subject: [PATCH 07/31] moved test to example folder --- test.html => example/test.html | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) rename test.html => example/test.html (55%) diff --git a/test.html b/example/test.html similarity index 55% rename from test.html rename to example/test.html index bcc6857..4fe67bb 100644 --- a/test.html +++ b/example/test.html @@ -1,18 +1,16 @@ - - - - - - + + + + + +