1+ /*!
2+ * ReactFire is an open-source JavaScript library that allows you to add a
3+ * realtime data source to your React apps by providing and easy way to let
4+ * Firebase populate the state of React components.
5+ *
6+ * ReactFire 0.2.0
7+ * https://github.com/firebase/reactfire/
8+ * License: MIT
9+ */
10+
11+ var ReactFireMixin = ( function ( ) {
12+ "use strict" ;
13+ var ReactFireMixin = {
14+ /********************/
15+ /* MIXIN LIFETIME */
16+ /********************/
17+ /* Initializes the Firebase binding refs array */
18+ componentWillMount : function ( ) {
19+ this . firebaseRefs = { } ;
20+ this . firebaseListeners = { } ;
21+ } ,
22+
23+ /* Removes any remaining Firebase bindings */
24+ componentWillUnmount : function ( ) {
25+ for ( var key in this . firebaseRefs ) {
26+ if ( this . firebaseRefs . hasOwnProperty ( key ) ) {
27+ this . unbind ( key ) ;
28+ }
29+ }
30+ } ,
31+
32+
33+ /*************/
34+ /* BINDING */
35+ /*************/
36+ /* Creates a binding between Firebase and the inputted bind variable as an array */
37+ bindAsArray : function ( firebaseRef , bindVar ) {
38+ this . _bind ( firebaseRef , bindVar , true ) ;
39+ } ,
40+
41+ /* Creates a binding between Firebase and the inputted bind variable as an object */
42+ bindAsObject : function ( firebaseRef , bindVar ) {
43+ this . _bind ( firebaseRef , bindVar , false ) ;
44+ } ,
45+
46+ /* Creates a binding between Firebase and the inputted bind variable as either an array or object */
47+ _bind : function ( firebaseRef , bindVar , bindAsArray ) {
48+ this . _validateBindVar ( bindVar ) ;
49+
50+ var error ;
51+ if ( typeof firebaseRef . ref === "undefined" || firebaseRef . ref ( ) instanceof Firebase === false ) {
52+ error = "firebaseRef must be an instance of Firebase" ;
53+ }
54+ else if ( typeof bindAsArray !== "boolean" ) {
55+ error = "bindAsArray must be a boolean. Got: " + bindAsArray ;
56+ }
57+
58+ if ( typeof error !== "undefined" ) {
59+ throw new Error ( "ReactFire: " + error ) ;
60+ }
61+
62+ this . firebaseRefs [ bindVar ] = firebaseRef . ref ( ) ;
63+ this . firebaseListeners [ bindVar ] = firebaseRef . on ( "value" , function ( dataSnapshot ) {
64+ var newState = { } ;
65+ if ( bindAsArray ) {
66+ newState [ bindVar ] = this . _toArray ( dataSnapshot . val ( ) ) ;
67+ }
68+ else {
69+ newState [ bindVar ] = dataSnapshot . val ( ) ;
70+ }
71+ this . setState ( newState ) ;
72+ } . bind ( this ) ) ;
73+ } ,
74+
75+ /* Removes the binding between Firebase and the inputted bind variable */
76+ unbind : function ( bindVar ) {
77+ this . _validateBindVar ( bindVar ) ;
78+
79+ if ( typeof this . firebaseRefs [ bindVar ] === "undefined" ) {
80+ throw new Error ( "unexpected value for bindVar. \"" + bindVar + "\" was either never bound or has already been unbound" ) ;
81+ }
82+
83+ this . firebaseRefs [ bindVar ] . off ( "value" , this . firebaseListeners [ bindVar ] ) ;
84+ delete this . firebaseRefs [ bindVar ] ;
85+ delete this . firebaseListeners [ bindVar ] ;
86+ } ,
87+
88+
89+ /*************/
90+ /* HELPERS */
91+ /*************/
92+ /* Validates the name of the variable which is being bound */
93+ _validateBindVar : function ( bindVar ) {
94+ var error ;
95+
96+ if ( typeof bindVar !== "string" ) {
97+ error = "bindVar must be a string. Got: " + bindVar ;
98+ }
99+ else if ( bindVar . length === 0 ) {
100+ error = "bindVar must be a non-empty string. Got: \"\"" ;
101+ }
102+ else if ( bindVar . length > 768 ) {
103+ // Firebase can only stored child paths up to 768 characters
104+ error = "bindVar is too long to be stored in Firebase. Got: " + bindVar ;
105+ }
106+ else if ( / [ \[ \] . # $ \/ \u0000 - \u001F \u007F ] / . test ( bindVar ) ) {
107+ // Firebase does not allow node keys to contain the following characters
108+ error = "bindVar cannot contain any of the following characters: . # $ ] [ /. Got: " + bindVar ;
109+ }
110+
111+ if ( typeof error !== "undefined" ) {
112+ throw new Error ( "ReactFire: " + error ) ;
113+ }
114+ } ,
115+
116+
117+ /* Returns true if the inputted object is a JavaScript array */
118+ _isArray : function ( obj ) {
119+ return ( Object . prototype . toString . call ( obj ) === "[object Array]" ) ;
120+ } ,
121+
122+ /* Converts a Firebase object to a JavaScript array */
123+ _toArray : function ( obj ) {
124+ var out = [ ] ;
125+ if ( obj ) {
126+ if ( this . _isArray ( obj ) ) {
127+ out = obj ;
128+ }
129+ else if ( typeof ( obj ) === "object" ) {
130+ for ( var key in obj ) {
131+ if ( obj . hasOwnProperty ( key ) ) {
132+ out . push ( obj [ key ] ) ;
133+ }
134+ }
135+ }
136+ }
137+ return out ;
138+ }
139+ } ;
140+
141+ return ReactFireMixin ;
142+ } ) ( ) ;
143+
144+ // Export ReactFireMixin if this is being run in node
145+ if ( typeof module !== "undefined" && typeof process !== "undefined" ) {
146+ module . exports = ReactFireMixin ;
147+ }
0 commit comments