Skip to content
This repository
Browse code

Refactors View rendering into Ember.States

  • Loading branch information...
commit df7fa6fc5a51d0cd6f20750ec759ef167f3d8f2b 1 parent fd2e1bd
Trek Glowacki authored krisselden committed
2  Assetfile
@@ -65,7 +65,7 @@ end
65 65
 
66 66
 distros = {
67 67
   :runtime => %w(ember-metal ember-runtime),
68  
-  :full    => %w(handlebars ember-metal ember-runtime ember-application ember-views ember-states ember-viewstates metamorph ember-handlebars)
  68
+  :full    => %w(handlebars ember-metal ember-runtime ember-application ember-states ember-views ember-viewstates metamorph ember-handlebars)
69 69
 }
70 70
 
71 71
 output "dist"
2  packages/ember-handlebars/lib/views/metamorph_view.js
@@ -42,7 +42,7 @@ var DOMManager = {
42 42
       view.invalidateRecursively('element');
43 43
       view._notifyWillInsertElement();
44 44
       morph.replaceWith(buffer.string());
45  
-      view.transitionTo('inDOM');
  45
+      view.transitionTo('hasElement.inDOM');
46 46
       view._notifyDidInsertElement();
47 47
     });
48 48
   },
1  packages/ember-views/lib/main.js
@@ -10,4 +10,5 @@
10 10
 require("ember-runtime");
11 11
 require("ember-views/core");
12 12
 require("ember-views/system");
  13
+require("ember-states");
13 14
 require("ember-views/views");
146  packages/ember-views/lib/views/container_view.js
@@ -287,7 +287,7 @@ Ember.ContainerView = Ember.View.extend({
287 287
     var changedViews = views.slice(start, start+removed);
288 288
     this.initializeViews(changedViews, null, null);
289 289
 
290  
-    this.invokeForState('childViewsWillChange', views, start, removed);
  290
+    this.invokeForState('childViewsWillChange', {views: views, start: start, removed: removed});
291 291
   },
292 292
 
293 293
   /**
@@ -315,7 +315,7 @@ Ember.ContainerView = Ember.View.extend({
315 315
     this.initializeViews(changedViews, this, get(this, 'templateData'));
316 316
 
317 317
     // Let the current state handle the changes
318  
-    this.invokeForState('childViewsDidChange', views, start, added);
  318
+    this.invokeForState('childViewsDidChange', {views: views, start: start, added: added});
319 319
   },
320 320
 
321 321
   initializeViews: function(views, parentView, templateData) {
@@ -363,70 +363,90 @@ Ember.ContainerView = Ember.View.extend({
363 363
     if (currentView) {
364 364
       childViews.pushObject(currentView);
365 365
     }
366  
-  }, 'currentView')
  366
+  }, 'currentView'),
  367
+
  368
+  renderStates: Ember.computed(function(){
  369
+    return Ember.ContainerView.RenderStateManager.create({
  370
+      view: this
  371
+    });
  372
+  }).property().cacheable()
367 373
 });
368 374
 
  375
+
369 376
 // Ember.ContainerView extends the default view states to provide different
370 377
 // behavior for childViewsWillChange and childViewsDidChange.
371  
-Ember.ContainerView.states = {
372  
-  parent: Ember.View.states,
373  
-
374  
-  inBuffer: {
375  
-    childViewsDidChange: function(parentView, views, start, added) {
376  
-      var buffer = parentView.buffer,
377  
-          startWith, prev, prevBuffer, view;
378  
-
379  
-      // Determine where to begin inserting the child view(s) in the
380  
-      // render buffer.
381  
-      if (start === 0) {
382  
-        // If views were inserted at the beginning, prepend the first
383  
-        // view to the render buffer, then begin inserting any
384  
-        // additional views at the beginning.
385  
-        view = views[start];
386  
-        startWith = start + 1;
387  
-        view.renderToBuffer(buffer, 'prepend');
388  
-      } else {
389  
-        // Otherwise, just insert them at the same place as the child
390  
-        // views mutation.
391  
-        view = views[start - 1];
392  
-        startWith = start;
393  
-      }
394  
-
395  
-      for (var i=startWith; i<start+added; i++) {
396  
-        prev = view;
397  
-        view = views[i];
398  
-        prevBuffer = prev.buffer;
399  
-        view.renderToBuffer(prevBuffer, 'insertAfter');
400  
-      }
401  
-    }
402  
-  },
403  
-
404  
-  hasElement: {
405  
-    childViewsWillChange: function(view, views, start, removed) {
406  
-      for (var i=start; i<start+removed; i++) {
407  
-        views[i].remove();
408  
-      }
409  
-    },
410  
-
411  
-    childViewsDidChange: function(view, views, start, added) {
412  
-      // If the DOM element for this container view already exists,
413  
-      // schedule each child view to insert its DOM representation after
414  
-      // bindings have finished syncing.
415  
-      var prev = start === 0 ? null : views[start-1];
416  
-
417  
-      for (var i=start; i<start+added; i++) {
418  
-        view = views[i];
419  
-        this._scheduleInsertion(view, prev);
420  
-        prev = view;
421  
-      }
422  
-    }
  378
+/** @private */
  379
+Ember.ContainerView.RenderStateManager = Ember.View.RenderStateManager.extend({
  380
+  initialState: '_default.preRender',
  381
+
  382
+  states: {
  383
+    '_default': Ember.View.states.DefaultState.create({
  384
+      preRender: Ember.View.states.PreRenderState.create(),
  385
+      destroyed: Ember.View.states.DestroyedState.create(),
  386
+
  387
+      hasElement: Ember.View.states.HasElementState.create({
  388
+        inDOM: Ember.View.states.InDomState.create(),
  389
+        childViewsWillChange: function(manager, options) {
  390
+          var view = get(manager, 'view'),
  391
+              views = options.views,
  392
+              start = options.start,
  393
+              removed = options.removed;
  394
+
  395
+          for (var i=start; i<start+removed; i++) {
  396
+            views[i].remove();
  397
+          }
  398
+        },
  399
+
  400
+        childViewsDidChange: function(manager, options) {
  401
+          var view = get(manager, 'view'),
  402
+              views = options.views,
  403
+              start = options.start,
  404
+              added = options.added;
  405
+
  406
+          // If the DOM element for this container view already exists,
  407
+          // schedule each child view to insert its DOM representation after
  408
+          // bindings have finished syncing.
  409
+          var insertedview;
  410
+          var prev = start === 0 ? null : views[start-1];
  411
+
  412
+          for (var i=start; i<start+added; i++) {
  413
+            insertedview = views[i];
  414
+            view._scheduleInsertion(insertedview, prev);
  415
+            prev = insertedview;
  416
+          }
  417
+        }
  418
+      }),
  419
+      inBuffer: Ember.View.states.InBufferState.create({
  420
+        childViewsDidChange: function(manager, views, start, added) {
  421
+          var parentView = get(manager, 'view'),
  422
+              buffer = parentView.buffer,
  423
+              startWith, prev, prevBuffer, view;
  424
+
  425
+          // Determine where to begin inserting the child view(s) in the
  426
+          // render buffer.
  427
+          if (start === 0) {
  428
+            // If views were inserted at the beginning, prepend the first
  429
+            // view to the render buffer, then begin inserting any
  430
+            // additional views at the beginning.
  431
+            view = views[start];
  432
+            startWith = start + 1;
  433
+            view.renderToBuffer(buffer, 'prepend');
  434
+          } else {
  435
+            // Otherwise, just insert them at the same place as the child
  436
+            // views mutation.
  437
+            view = views[start - 1];
  438
+            startWith = start;
  439
+          }
  440
+
  441
+          for (var i=startWith; i<start+added; i++) {
  442
+            prev = view;
  443
+            view = views[i];
  444
+            prevBuffer = prev.buffer;
  445
+            view.renderToBuffer(prevBuffer, 'insertAfter');
  446
+          }
  447
+        }
  448
+      })
  449
+    })
423 450
   }
424  
-};
425  
-
426  
-Ember.ContainerView.states.inDOM = {
427  
-  parentState: Ember.ContainerView.states.hasElement
428  
-};
429  
-
430  
-Ember.ContainerView.reopen({
431  
-  states: Ember.ContainerView.states
432 451
 });
  452
+
18  packages/ember-views/lib/views/states.js
@@ -10,3 +10,21 @@ require("ember-views/views/states/pre_render");
10 10
 require("ember-views/views/states/in_buffer");
11 11
 require("ember-views/views/states/in_dom");
12 12
 require("ember-views/views/states/destroyed");
  13
+
  14
+var get = Ember.get, set = Ember.set, getPath = Ember.getPath, fmt = Ember.String.fmt;
  15
+
  16
+/** @private */
  17
+Ember.View.RenderStateManager = Ember.StateManager.extend({
  18
+  initialState: '_default.preRender',
  19
+
  20
+  states: {
  21
+    '_default': Ember.View.states.DefaultState.create({
  22
+      preRender: Ember.View.states.PreRenderState.create(),
  23
+      hasElement: Ember.View.states.HasElementState.create({
  24
+        inDOM: Ember.View.states.InDomState.create()
  25
+      }),
  26
+      inBuffer: Ember.View.states.InBufferState.create(),
  27
+      destroyed: Ember.View.states.DestroyedState.create()
  28
+    })
  29
+  }
  30
+});
57  packages/ember-views/lib/views/states/default.js
@@ -8,35 +8,32 @@
8 8
 require('ember-views/views/view');
9 9
 
10 10
 var get = Ember.get, set = Ember.set;
11  
-
12  
-Ember.View.states = {
13  
-  _default: {
14  
-    // appendChild is only legal while rendering the buffer.
15  
-    appendChild: function() {
16  
-      throw "You can't use appendChild outside of the rendering process";
17  
-    },
18  
-
19  
-    $: function() {
20  
-      return Ember.$();
21  
-    },
22  
-
23  
-    getElement: function() {
24  
-      return null;
25  
-    },
26  
-
27  
-    // Handle events from `Ember.EventDispatcher`
28  
-    handleEvent: function() {
29  
-      return true; // continue event propagation
30  
-    },
31  
-
32  
-    destroyElement: function(view) {
33  
-      set(view, 'element', null);
34  
-      view._lastInsert = null;
35  
-      return view;
36  
-    }
  11
+Ember.View.states = {};
  12
+
  13
+/** @private */
  14
+Ember.View.states.DefaultState = Ember.State.extend({
  15
+  handleEvent: function() {
  16
+    return true; // continue event propagation
  17
+  },
  18
+  appendChild: function() {
  19
+    throw "You can't use appendChild outside of the rendering process";
  20
+  },
  21
+  destroyElement: function(manager) {
  22
+    var view = get(manager, 'view');
  23
+    set(view, 'element', null);
  24
+    view._lastInsert = null;
  25
+    return view;
  26
+  },
  27
+  getElement: function(){
  28
+    return null;
  29
+  },
  30
+  childViewsDidChange: Ember.K,
  31
+  insertElement: Ember.K,
  32
+  
  33
+  // default behavior is to complain of missing actions:
  34
+  rerender: Ember.K,
  35
+  childViewsWillChange: Ember.K,
  36
+  $: function(){
  37
+    return Ember.$();
37 38
   }
38  
-};
39  
-
40  
-Ember.View.reopen({
41  
-  states: Ember.View.states
42 39
 });
49  packages/ember-views/lib/views/states/destroyed.js
@@ -6,31 +6,28 @@
6 6
 // ==========================================================================
7 7
 
8 8
 require('ember-views/views/states/default');
9  
-
10 9
 var destroyedError = "You can't call %@ on a destroyed view", fmt = Ember.String.fmt;
11 10
 
12  
-Ember.View.states.destroyed = {
13  
-  parentState: Ember.View.states._default,
14  
-
15  
-  appendChild: function() {
16  
-    throw fmt(destroyedError, ['appendChild']);
17  
-  },
18  
-  rerender: function() {
19  
-    throw fmt(destroyedError, ['rerender']);
20  
-  },
21  
-  destroyElement: function() {
22  
-    throw fmt(destroyedError, ['destroyElement']);
23  
-  },
24  
-  empty: function() {
25  
-    throw fmt(destroyedError, ['empty']);
26  
-  },
27  
-
28  
-  setElement: function() {
29  
-    throw fmt(destroyedError, ["set('element', ...)"]);
30  
-  },
31  
-
32  
-  // Since element insertion is scheduled, don't do anything if
33  
-  // the view has been destroyed between scheduling and execution
34  
-  insertElement: Ember.K
35  
-};
36  
-
  11
+/** @private */
  12
+Ember.View.states.DestroyedState = Ember.State.extend({
  13
+    appendChild: function() {
  14
+      throw fmt(destroyedError, ['appendChild']);
  15
+    },
  16
+    rerender: function() {
  17
+      throw fmt(destroyedError, ['rerender']);
  18
+    },
  19
+    destroyElement: function() {
  20
+      throw fmt(destroyedError, ['destroyElement']);
  21
+    },
  22
+    empty: function() {
  23
+      throw fmt(destroyedError, ['empty']);
  24
+    },
  25
+  
  26
+    setElement: function() {
  27
+      throw fmt(destroyedError, ["set('element', ...)"]);
  28
+    },
  29
+  
  30
+    // Since element insertion is scheduled, don't do anything if
  31
+    // the view has been destroyed between scheduling and execution
  32
+    insertElement: Ember.K
  33
+});
151  packages/ember-views/lib/views/states/in_buffer.js
@@ -9,77 +9,84 @@ require('ember-views/views/states/default');
9 9
 
10 10
 var get = Ember.get, set = Ember.set, meta = Ember.meta;
11 11
 
12  
-Ember.View.states.inBuffer = {
13  
-  parentState: Ember.View.states._default,
14  
-
15  
-  $: function(view, sel) {
16  
-    // if we don't have an element yet, someone calling this.$() is
17  
-    // trying to update an element that isn't in the DOM. Instead,
18  
-    // rerender the view to allow the render method to reflect the
19  
-    // changes.
20  
-    view.rerender();
21  
-    return Ember.$();
22  
-  },
23  
-
24  
-  // when a view is rendered in a buffer, rerendering it simply
25  
-  // replaces the existing buffer with a new one
26  
-  rerender: function(view) {
27  
-    Ember.deprecate("Something you did caused a view to re-render after it rendered but before it was inserted into the DOM. Because this is avoidable and the cause of significant performance issues in applications, this behavior is deprecated. If you want to use the debugger to find out what caused this, you can set ENV.RAISE_ON_DEPRECATION to true.");
28  
-
29  
-    view._notifyWillRerender();
30  
-
31  
-    view.clearRenderedChildren();
32  
-    view.renderToBuffer(view.buffer, 'replaceWith');
33  
-  },
34  
-
35  
-  // when a view is rendered in a buffer, appending a child
36  
-  // view will render that view and append the resulting
37  
-  // buffer into its buffer.
38  
-  appendChild: function(view, childView, options) {
39  
-    var buffer = view.buffer;
40  
-
41  
-    childView = this.createChildView(childView, options);
42  
-    get(view, '_childViews').push(childView);
43  
-
44  
-    childView.renderToBuffer(buffer);
45  
-
46  
-    view.propertyDidChange('childViews');
47  
-
48  
-    return childView;
49  
-  },
50  
-
51  
-  // when a view is rendered in a buffer, destroying the
52  
-  // element will simply destroy the buffer and put the
53  
-  // state back into the preRender state.
54  
-  destroyElement: function(view) {
55  
-    view.clearBuffer();
56  
-    view._notifyWillDestroyElement();
57  
-    view.transitionTo('preRender');
58  
-
59  
-    return view;
60  
-  },
61  
-
62  
-  empty: function() {
63  
-    Ember.assert("Emptying a view in the inBuffer state is not allowed and should not happen under normal circumstances. Most likely there is a bug in your application. This may be due to excessive property change notifications.");
64  
-  },
65  
-
66  
-  // It should be impossible for a rendered view to be scheduled for
67  
-  // insertion.
68  
-  insertElement: function() {
69  
-    throw "You can't insert an element that has already been rendered";
70  
-  },
71  
-
72  
-  setElement: function(view, value) {
73  
-    view.invalidateRecursively('element');
74  
-
75  
-    if (value === null) {
76  
-      view.transitionTo('preRender');
77  
-    } else {
  12
+/** @private */
  13
+Ember.View.states.InBufferState = Ember.State.extend({
  14
+    $: function(manager) {
  15
+      var view = get(manager, 'view');
  16
+      // if we don't have an element yet, someone calling this.$() is
  17
+      // trying to update an element that isn't in the DOM. Instead,
  18
+      // rerender the view to allow the render method to reflect the
  19
+      // changes.
  20
+      view.rerender();
  21
+      return Ember.$();
  22
+    },
  23
+  
  24
+    // when a view is rendered in a buffer, rerendering it simply
  25
+    // replaces the existing buffer with a new one
  26
+    rerender: function(manager) {
  27
+      Ember.deprecate("Something you did caused a view to re-render after it rendered but before it was inserted into the DOM. Because this is avoidable and the cause of significant performance issues in applications, this behavior is deprecated. If you want to use the debugger to find out what caused this, you can set ENV.RAISE_ON_DEPRECATION to true.");
  28
+      
  29
+      var view = get(manager, 'view');
  30
+      view._notifyWillRerender();
  31
+  
  32
+      view.clearRenderedChildren();
  33
+      view.renderToBuffer(view.buffer, 'replaceWith');
  34
+    },
  35
+  
  36
+    // when a view is rendered in a buffer, appending a child
  37
+    // view will render that view and append the resulting
  38
+    // buffer into its buffer.
  39
+    appendChild: function(manager, context) {
  40
+      var view = get(manager, 'view'),
  41
+          buffer = view.buffer,
  42
+          childView = context.childView,
  43
+          options = context.options;
  44
+  
  45
+      childView = view.createChildView(childView, options);
  46
+      get(view, '_childViews').push(childView);
  47
+  
  48
+      childView.renderToBuffer(buffer);
  49
+  
  50
+      view.propertyDidChange('childViews');
  51
+  
  52
+      return childView;
  53
+    },
  54
+  
  55
+    // when a view is rendered in a buffer, destroying the
  56
+    // element will simply destroy the buffer and put the
  57
+    // state back into the preRender state.
  58
+    destroyElement: function(manager) {
  59
+      var view = get(manager, 'view');
  60
+      
78 61
       view.clearBuffer();
79  
-      view.transitionTo('hasElement');
  62
+      view._notifyWillDestroyElement();
  63
+      view.transitionTo('preRender');
  64
+  
  65
+      return view;
  66
+    },
  67
+  
  68
+    empty: function() {
  69
+       Ember.assert("Emptying a view in the inBuffer state is not allowed and should not happen under normal circumstances. Most likely there is a bug in your application. This may be due to excessive property change notifications.");
  70
+    },
  71
+  
  72
+    // It should be impossible for a rendered view to be scheduled for
  73
+    // insertion.
  74
+    insertElement: function() {
  75
+      throw "You can't insert an element that has already been rendered";
  76
+    },
  77
+  
  78
+    setElement: function(manager, value) {
  79
+      var view = get(manager, 'view');
  80
+  
  81
+      view.invalidateRecursively('element');
  82
+  
  83
+      if (value === null) {
  84
+        view.transitionTo('preRender');
  85
+      } else {
  86
+        view.clearBuffer();
  87
+        view.transitionTo('hasElement');
  88
+      }
  89
+  
  90
+      return value;
80 91
     }
81  
-
82  
-    return value;
83  
-  }
84  
-};
85  
-
  92
+});
50  packages/ember-views/lib/views/states/in_dom.js
@@ -9,22 +9,25 @@ require('ember-views/views/states/default');
9 9
 
10 10
 var get = Ember.get, set = Ember.set, meta = Ember.meta;
11 11
 
12  
-Ember.View.states.hasElement = {
13  
-  parentState: Ember.View.states._default,
14  
-
15  
-  $: function(view, sel) {
16  
-    var elem = get(view, 'element');
  12
+/** @private */
  13
+Ember.View.states.HasElementState = Ember.State.extend({
  14
+  $: function(manager, sel) {
  15
+    var view = get(manager, 'view'),
  16
+        elem = get(view, 'element');
17 17
     return sel ? Ember.$(sel, elem) : Ember.$(elem);
18 18
   },
19 19
 
20  
-  getElement: function(view) {
21  
-    var parent = get(view, 'parentView');
  20
+  getElement: function(manager) {
  21
+    var view = get(manager, 'view'),
  22
+        parent = get(view, 'parentView');
22 23
     if (parent) { parent = get(parent, 'element'); }
23 24
     if (parent) { return view.findElementInParentElement(parent); }
24 25
     return Ember.$("#" + get(view, 'elementId'))[0];
25 26
   },
26 27
 
27  
-  setElement: function(view, value) {
  28
+  setElement: function(manager, value) {
  29
+    var view = get(manager, 'view');
  30
+
28 31
     if (value === null) {
29 32
       view.invalidateRecursively('element');
30 33
 
@@ -38,7 +41,9 @@ Ember.View.states.hasElement = {
38 41
 
39 42
   // once the view has been inserted into the DOM, rerendering is
40 43
   // deferred to allow bindings to synchronize.
41  
-  rerender: function(view) {
  44
+  rerender: function(manager) {
  45
+    var view = get(manager, 'view');
  46
+    
42 47
     view._notifyWillRerender();
43 48
 
44 49
     view.clearRenderedChildren();
@@ -51,13 +56,17 @@ Ember.View.states.hasElement = {
51 56
   // from the DOM, nukes its element, and puts it back into the
52 57
   // preRender state if inDOM.
53 58
 
54  
-  destroyElement: function(view) {
  59
+  destroyElement: function(manager) {
  60
+    var view = get(manager, 'view');
  61
+    
55 62
     view._notifyWillDestroyElement();
56 63
     view.domManager.remove(view);
57 64
     return view;
58 65
   },
59 66
 
60  
-  empty: function(view) {
  67
+  empty: function(manager) {
  68
+    var view = get(manager, 'view');
  69
+    
61 70
     var _childViews = get(view, '_childViews'), len, idx;
62 71
     if (_childViews) {
63 72
       len = get(_childViews, 'length');
@@ -69,22 +78,27 @@ Ember.View.states.hasElement = {
69 78
   },
70 79
 
71 80
   // Handle events from `Ember.EventDispatcher`
72  
-  handleEvent: function(view, eventName, evt) {
  81
+  handleEvent: function(manager, options) {
  82
+    var view = get(manager, 'view'),
  83
+        eventName = options.eventName,
  84
+        evt = options.event;
  85
+    
73 86
     if (view.has(eventName)) {
74 87
       return view.fire(eventName, evt);
75 88
     } else {
76 89
       return true; // continue event propagation
77 90
     }
78 91
   }
79  
-};
  92
+});
80 93
 
81  
-Ember.View.states.inDOM = {
82  
-  parentState: Ember.View.states.hasElement,
83  
-
84  
-  insertElement: function(view, fn) {
  94
+Ember.View.states.InDomState = Ember.State.extend({
  95
+  insertElement: function(manager, fn) {
  96
+    var view = get(manager, 'view');
  97
+    
85 98
     if (view._lastInsert !== Ember.guidFor(fn)){
86 99
       return;
87 100
     }
88 101
     throw "You can't insert an element into the DOM that has already been inserted";
89 102
   }
90  
-};
  103
+});
  104
+
17  packages/ember-views/lib/views/states/pre_render.js
@@ -5,14 +5,15 @@
5 5
 // License:   Licensed under MIT license (see license.js)
6 6
 // ==========================================================================
7 7
 
8  
-require('ember-views/views/states/default');
9  
-
10  
-Ember.View.states.preRender = {
11  
-  parentState: Ember.View.states._default,
  8
+var get = Ember.get;
12 9
 
  10
+/** @private */
  11
+Ember.View.states.PreRenderState = Ember.State.extend({
13 12
   // a view leaves the preRender state once its element has been
14 13
   // created (createElement).
15  
-  insertElement: function(view, fn) {
  14
+  insertElement: function(manager, fn) {
  15
+    var view = get(manager, 'view');
  16
+    
16 17
     if (view._lastInsert !== Ember.guidFor(fn)){
17 18
       return;
18 19
     }
@@ -26,7 +27,9 @@ Ember.View.states.preRender = {
26 27
 
27 28
   empty: Ember.K,
28 29
 
29  
-  setElement: function(view, value) {
  30
+  setElement: function(manager, value) {
  31
+    var view = get(manager, 'view');
  32
+
30 33
     view.beginPropertyChanges();
31 34
     view.invalidateRecursively('element');
32 35
 
@@ -38,4 +41,4 @@ Ember.View.states.preRender = {
38 41
 
39 42
     return value;
40 43
   }
41  
-};
  44
+});
67  packages/ember-views/lib/views/view.js
@@ -41,14 +41,6 @@ Ember.warn("The way that the {{view}} helper affects templates is about to chang
41 41
 */
42 42
 Ember.TEMPLATES = {};
43 43
 
44  
-var invokeForState = {
45  
-  preRender: {},
46  
-  inBuffer: {},
47  
-  hasElement: {},
48  
-  inDOM: {},
49  
-  destroyed: {}
50  
-};
51  
-
52 44
 /**
53 45
   @class
54 46
 
@@ -821,41 +813,10 @@ Ember.View = Ember.Object.extend(Ember.Evented,
821 813
       if (output !== undefined) { buffer.push(output); }
822 814
     }
823 815
   },
824  
-
825  
-  invokeForState: function(name) {
826  
-    var stateName = this.state, args, fn;
827  
-
828  
-    // try to find the function for the state in the cache
829  
-    if (fn = invokeForState[stateName][name]) {
830  
-      args = a_slice.call(arguments);
831  
-      args[0] = this;
832  
-
833  
-      return fn.apply(this, args);
834  
-    }
835  
-
836  
-    // otherwise, find and cache the function for this state
837  
-    var parent = this, states = parent.states, state;
838  
-
839  
-    while (states) {
840  
-      state = states[stateName];
841  
-
842  
-      while (state) {
843  
-        fn = state[name];
844  
-
845  
-        if (fn) {
846  
-          invokeForState[stateName][name] = fn;
847  
-
848  
-          args = a_slice.call(arguments, 1);
849  
-          args.unshift(this);
850  
-
851  
-          return fn.apply(this, args);
852  
-        }
853  
-
854  
-        state = state.parentState;
855  
-      }
856  
-
857  
-      states = states.parent;
858  
-    }
  816
+  
  817
+  invokeForState: function(methodName, options) {
  818
+    var states = this.get('renderStates');
  819
+    return states.send(methodName, options);
859 820
   },
860 821
 
861 822
   /**
@@ -1630,8 +1591,6 @@ Ember.View = Ember.Object.extend(Ember.Evented,
1630 1591
   */
1631 1592
   attributeBindings: [],
1632 1593
 
1633  
-  state: 'preRender',
1634  
-
1635 1594
   // .......................................................
1636 1595
   // CORE DISPLAY METHODS
1637 1596
   //
@@ -1671,8 +1630,14 @@ Ember.View = Ember.Object.extend(Ember.Evented,
1671 1630
     }
1672 1631
   },
1673 1632
 
  1633
+  renderStates: Ember.computed(function(){
  1634
+    return Ember.View.RenderStateManager.create({
  1635
+      view: this
  1636
+    });
  1637
+  }).property().cacheable(),
  1638
+  
1674 1639
   appendChild: function(view, options) {
1675  
-    return this.invokeForState('appendChild', view, options);
  1640
+    return this.invokeForState('appendChild', {childView: view, options: options});
1676 1641
   },
1677 1642
 
1678 1643
   /**
@@ -1763,7 +1728,7 @@ Ember.View = Ember.Object.extend(Ember.Evented,
1763 1728
     // the DOM again.
1764 1729
     if (parent) { parent.removeChild(this); }
1765 1730
 
1766  
-    this.state = 'destroyed';
  1731
+    this.get('renderStates').transitionTo('destroyed');
1767 1732
 
1768 1733
     childLen = get(childViews, 'length');
1769 1734
     for (var i=childLen-1; i>=0; i--) {
@@ -1875,9 +1840,9 @@ Ember.View = Ember.Object.extend(Ember.Evented,
1875 1840
       this.buffer = null;
1876 1841
     });
1877 1842
   },
1878  
-
1879  
-  transitionTo: function(state, children) {
1880  
-    this.state = state;
  1843
+  
  1844
+  transitionTo: function(state, children){
  1845
+    this.get('renderStates').transitionTo(state);
1881 1846
 
1882 1847
     if (children !== false) {
1883 1848
       this.forEachChildView(function(view) {
@@ -1913,7 +1878,7 @@ Ember.View = Ember.Object.extend(Ember.Evented,
1913 1878
     Handle events from `Ember.EventDispatcher`
1914 1879
   */
1915 1880
   handleEvent: function(eventName, evt) {
1916  
-    return this.invokeForState('handleEvent', eventName, evt);
  1881
+    return this.invokeForState('handleEvent', {eventName: eventName, event: evt});
1917 1882
   }
1918 1883
 
1919 1884
 });

0 notes on commit df7fa6f

Please sign in to comment.
Something went wrong with that request. Please try again.