|
/* App |
|
=============================*/ |
|
var App = Ember.Application.create({ |
|
LOG_TRANSITIONS: true |
|
}); |
|
|
|
App.Store = DS.Store.extend({ |
|
adapter: DS.FixtureAdapter.create() |
|
}); |
|
|
|
/* Router |
|
=============================*/ |
|
|
|
App.Router.map(function() { |
|
this.route("about", { path: "/about" }); |
|
this.route("inview", { path: "/inview" }); |
|
this.route("calendar", { path: "/calendar" }); |
|
this.route("infinite", { path: "/infinite" }); |
|
this.route("scroll", { path: "/scroll" }); |
|
}); |
|
|
|
/* Routes |
|
=============================*/ |
|
App.IndexRoute = Ember.Route.extend({ |
|
model: function() { |
|
return Ember.Object.create({ name: 'My name' }); |
|
} |
|
}); |
|
|
|
App.ApplicationRoute = Ember.Route.extend({ |
|
actions: { |
|
showModal: function(name, model) { |
|
this.render(name, { |
|
into: 'application', |
|
outlet: 'modal', |
|
model: model |
|
}); |
|
}, |
|
removeModal: function() { |
|
this.disconnectOutlet({ |
|
outlet: 'modal', |
|
parentView: 'application' |
|
}); |
|
} |
|
} |
|
}); |
|
|
|
App.InviewRoute = Ember.Route.extend({ |
|
model: function() { |
|
return ['Shiba Inu', 'Siberian Husky', 'Labrador', 'Golden Retriever', 'Malamute', 'Pomeranian', 'Doberman']; |
|
} |
|
}); |
|
|
|
App.CalendarRoute = Em.Route.extend({ |
|
setupController: function(controller) { |
|
controller.set('emberConfDates', [ |
|
/*moment('2014-03-25'), |
|
moment('2014-03-26')*/ |
|
]); |
|
}, |
|
actions: { |
|
dateSelected: function(date) { |
|
/* console.log(this.get('dates'), 'dateSelected'); |
|
$('input[name="dateSelected]').val('date')*/ |
|
} |
|
} |
|
}); |
|
|
|
App.InfiniteRoute = Ember.Route.extend({ |
|
model: function(){ |
|
var items = Em.A([]); |
|
for (var i = 0; i < 10; i++) { |
|
items.pushObject({name: ''+i}); |
|
} |
|
return items; |
|
}, |
|
actions: { |
|
getMore: function() { |
|
var controller = this.get('controller'), |
|
nextPage = controller.get('page') + 1, |
|
perPage = controller.get('perPage'), |
|
items; |
|
|
|
items = this.send('fetchPage', nextPage, perPage); |
|
|
|
console.log(items, 'items') |
|
|
|
// add delay to simulate API latency |
|
Ember.run.later(function(){ |
|
// alert the controller to the new data |
|
controller.gotMore(items, nextPage); |
|
}, 1000); |
|
}, |
|
// load another page's worth of fake widgets |
|
fetchPage: function(page, perPage) { |
|
var items = Em.A([]); |
|
console.log(items, 'fetchPage') |
|
var firstIndex = (page-1) * perPage; |
|
var lastIndex = page * perPage; |
|
for (var i = firstIndex; i < lastIndex; i++) { |
|
items.pushObject({name:''+i}); |
|
} |
|
return items; |
|
} |
|
} |
|
}); |
|
|
|
|
|
/* Models |
|
=============================*/ |
|
|
|
/* Views |
|
=============================*/ |
|
|
|
App.InfiniteView = Ember.View.extend({ |
|
didInsertElement: function(){ |
|
// we want to make sure 'this' inside `didScroll` refers |
|
// to the IndexView, so we use jquery's `proxy` method to bind it |
|
$(window).on('scroll', $.proxy(this.didScroll, this)); |
|
}, |
|
|
|
willDestroyElement: function(){ |
|
// have to use the same argument to `off` that we did to `on` |
|
$(window).off('scroll', $.proxy(this.didScroll, this)); |
|
}, |
|
|
|
// this is called every time we scroll |
|
didScroll: function(){ |
|
if (this.isScrolledToBottom()) { |
|
this.get('controller').send('getMore'); |
|
} |
|
}, |
|
|
|
// we check if we are at the bottom of the page |
|
isScrolledToBottom: function(){ |
|
var distanceToViewportTop = ( |
|
$(document).height() - $(window).height()); |
|
var viewPortTop = $(document).scrollTop(); |
|
|
|
if (viewPortTop === 0) { |
|
// if we are at the top of the page, don't do |
|
// the infinite scroll thing |
|
return false; |
|
} |
|
|
|
return (viewPortTop - distanceToViewportTop === 0); |
|
} |
|
}); |
|
|
|
/*rerenderObserver:function(){ |
|
this.rerender(); |
|
}.observes('controller.content')*/ |
|
|
|
/* Controllers =============================*/ |
|
App.SettingsModalController = Ember.ObjectController.extend({ |
|
actions: { |
|
save: function() { |
|
// save to server |
|
console.log('settings saved'); |
|
} |
|
} |
|
}); |
|
|
|
App.LogoutModalController = Ember.Controller.extend({ |
|
actions: { |
|
logout: function() { |
|
// logout |
|
console.log('logout triggered'); |
|
} |
|
} |
|
}); |
|
|
|
App.InfiniteController = Ember.ArrayController.extend({ |
|
// add properties |
|
page: 1, |
|
perPage: 10, |
|
|
|
getMore: function() { |
|
// don't load new data if we already are |
|
if (this.get('loadingMore')) return; |
|
|
|
this.set('loadingMore', true); |
|
|
|
// pass this action up the chain to the events hash on the route |
|
this.get('target').send('getMore'); |
|
}, |
|
|
|
// Also add a method `gotMore` that the route can call back to |
|
// notify the controller that the new data is in and it can stop |
|
// showing its loading indicator |
|
gotMore: function(items, page) { |
|
this.set('loadingMore', false); |
|
this.set('page', page); |
|
|
|
this.pushObjects(items); |
|
} |
|
}); |
|
|
|
|
|
/* Components =============================*/ |
|
App.MyModalComponent = Ember.Component.extend({ |
|
actions: { |
|
ok: function() { |
|
this.$('.modal').modal('hide'); |
|
this.sendAction('ok'); |
|
} |
|
}, |
|
show: function() { |
|
this.$('.modal').modal().on('hidden.bs.modal', function() { |
|
this.sendAction('close'); |
|
}.bind(this)); |
|
}.on('didInsertElement') |
|
}); |
|
|
|
App.ThisIsDogComponent = Ember.Component.extend(App.InViewportMixin, { |
|
classNames: ['dog-card'], |
|
classNameBindings: ['enteredViewport:entered-viewport'] |
|
}); |
|
|
|
App.FormatDateComponent = Em.Component.extend({ |
|
layout: Em.Handlebars.compile('{{formatted}}'), |
|
date: null, |
|
format: null, |
|
|
|
formatted: function() { |
|
var date = this.get('date'); |
|
var format = this.get('format'); |
|
|
|
return date ? date.format(format) : null; |
|
}.property('date', 'format') |
|
}); |
|
|
|
/* Mixins =============================*/ |
|
App.InViewportMixin = Ember.Mixin.create({ |
|
scrollTimeout: 100, |
|
boundingClientRect: 0, |
|
windowHeight: 0, |
|
windowWidth: 0, |
|
enteredViewport: Em.computed('boundingClientRect', 'windowHeight', 'windowWidth', function() { |
|
var rect, windowHeight, windowWidth; |
|
rect = this.get('boundingClientRect'); |
|
windowHeight = this.get('windowHeight'); |
|
windowWidth = this.get('windowWidth'); |
|
console.log(rect, 'rect') |
|
return ( |
|
rect.top >= 0 && |
|
rect.left >= 0 && |
|
rect.bottom <= windowHeight && |
|
rect.right <= windowWidth |
|
); |
|
}), |
|
exitedViewport: Em.computed.not('enteredViewport'), |
|
_updateBoundingClientRect: function() { |
|
var el; |
|
el = this.$()[0]; |
|
this.set('boundingClientRect', el.getBoundingClientRect()); |
|
}, |
|
_setup: (function() { |
|
console.log('setup') |
|
return Em.run.scheduleOnce('afterRender', this, function() { |
|
this._updateBoundingClientRect(); |
|
this.set('windowHeight', window.innerHeight || document.documentElement.clientHeight); |
|
this.set('windowWidth', window.innerWidth || document.documentElement.clientWidth); |
|
}); |
|
}).on('didInsertElement'), |
|
_scrollHandler: function() { |
|
return Em.run.debounce(this, '_updateBoundingClientRect', this.get('scrollTimeout')); |
|
}, |
|
_bindScroll: (function() { |
|
console.log('scroll') |
|
var scrollHandler; |
|
scrollHandler = this._scrollHandler.bind(this); |
|
Ember.$(document).on('touchmove.scrollable', scrollHandler); |
|
Ember.$(window).on('scroll.scrollable', scrollHandler); |
|
}).on('didInsertElement'), |
|
_unbindScroll: (function() { |
|
Ember.$(window).off('.scrollable'); |
|
Ember.$(document).off('.scrollable'); |
|
}).on('willDestroyElement') |
|
}); |
|
|
|
|
|
$(function() { |
|
// Check to see if the window is running in app mode. |
|
if (("standalone" in window.navigator) && window.navigator.standalone) { |
|
$('.navbar-fixed-top').css({ |
|
paddingTop:'12px' |
|
}); |
|
} |
|
}) |
|
|
|
|
|
// Cloaked Collection |
|
|
|
random_height = function() { |
|
return Math.round(Math.random() * 100 + 20); |
|
}; |
|
|
|
model = (function() { |
|
var _i, _results; |
|
_results = []; |
|
for (i = _i = 0; _i <= 500; i = ++_i) { |
|
_results.push({ |
|
id: i, |
|
height: random_height() |
|
}); |
|
} |
|
return _results; |
|
})(); |
|
|
|
App.ScrollRoute = Ember.Route.extend({ |
|
model: function() { |
|
return model; |
|
}, |
|
actions: { |
|
greeting: function() { |
|
return alert('greeting from route'); |
|
} |
|
} |
|
}); |
|
|
|
App.ScrollView = Em.View.extend({ |
|
templateName: 'scroll' |
|
}); |
|
|
|
App.ItemView = Em.View.extend({ |
|
templateName: 'item', |
|
didInsertElement: function() { |
|
return this.$().css('height', this.get('context.height')); |
|
} |
|
}); |
|
|
|
|
|
/** |
|
Display a list of cloaked items |
|
@class CloakedCollectionView |
|
@extends Ember.CollectionView |
|
@namespace Ember |
|
**/ |
|
Ember.CloakedCollectionView = Ember.CollectionView.extend({ |
|
cloakView: Ember.computed.alias('itemViewClass'), |
|
topVisible: null, |
|
bottomVisible: null, |
|
offsetFixedTopElement: null, |
|
offsetFixedBottomElement: null, |
|
loadingHTML: 'Loading...', |
|
scrollDebounce: 10, |
|
|
|
init: function() { |
|
var cloakView = this.get('cloakView'), |
|
idProperty = this.get('idProperty'), |
|
uncloakDefault = !!this.get('uncloakDefault'); |
|
|
|
// Set the slack ratio differently to allow for more or less slack in preloading |
|
var slackRatio = parseFloat(this.get('slackRatio')); |
|
if (!slackRatio) { this.set('slackRatio', 1.0); } |
|
|
|
this.set('itemViewClass', Ember.CloakedView.extend({ |
|
classNames: [cloakView + '-cloak'], |
|
cloaks: cloakView, |
|
preservesContext: this.get('preservesContext') === 'true', |
|
cloaksController: this.get('itemController'), |
|
defaultHeight: this.get('defaultHeight'), |
|
|
|
init: function() { |
|
this._super(); |
|
|
|
if (idProperty) { |
|
this.set('elementId', cloakView + '-cloak-' + this.get('content.' + idProperty)); |
|
} |
|
if (uncloakDefault) { |
|
this.uncloak(); |
|
} else { |
|
this.cloak(); |
|
} |
|
} |
|
})); |
|
|
|
this._super(); |
|
Ember.run.next(this, 'scrolled'); |
|
}, |
|
|
|
|
|
/** |
|
If the topmost visible view changed, we will notify the controller if it has an appropriate hook. |
|
@method _topVisibleChanged |
|
@observes topVisible |
|
**/ |
|
_topVisibleChanged: function() { |
|
var controller = this.get('controller'); |
|
if (controller.topVisibleChanged) { controller.topVisibleChanged(this.get('topVisible')); } |
|
}.observes('topVisible'), |
|
|
|
/** |
|
If the bottommost visible view changed, we will notify the controller if it has an appropriate hook. |
|
@method _bottomVisible |
|
@observes bottomVisible |
|
**/ |
|
_bottomVisible: function() { |
|
var controller = this.get('controller'); |
|
if (controller.bottomVisibleChanged) { controller.bottomVisibleChanged(this.get('bottomVisible')); } |
|
}.observes('bottomVisible'), |
|
|
|
/** |
|
Binary search for finding the topmost view on screen. |
|
@method findTopView |
|
@param {Array} childViews the childViews to search through |
|
@param {Number} windowTop The top of the viewport to search against |
|
@param {Number} min The minimum index to search through of the child views |
|
@param {Number} max The max index to search through of the child views |
|
@returns {Number} the index into childViews of the topmost view |
|
**/ |
|
findTopView: function(childViews, viewportTop, min, max) { |
|
if (max < min) { return min; } |
|
|
|
var wrapperTop = this.get('wrapperTop')>>0; |
|
|
|
while(max>min){ |
|
var mid = Math.floor((min + max) / 2), |
|
// in case of not full-window scrolling |
|
$view = childViews[mid].$(), |
|
viewBottom = $view.position().top + wrapperTop + $view.height(); |
|
|
|
if (viewBottom > viewportTop) { |
|
max = mid-1; |
|
} else { |
|
min = mid+1; |
|
} |
|
} |
|
|
|
return min; |
|
}, |
|
|
|
|
|
/** |
|
Determine what views are onscreen and cloak/uncloak them as necessary. |
|
@method scrolled |
|
**/ |
|
scrolled: function() { |
|
if (!this.get('scrollingEnabled')) { return; } |
|
|
|
var childViews = this.get('childViews'); |
|
if ((!childViews) || (childViews.length === 0)) { return; } |
|
|
|
var self = this, |
|
toUncloak = [], |
|
onscreen = [], |
|
onscreenCloaks = [], |
|
// calculating viewport edges |
|
$w = Ember.$(window), |
|
windowHeight = this.get('wrapperHeight') || ( window.innerHeight ? window.innerHeight : $w.height() ), |
|
windowTop = this.get('wrapperTop') || $w.scrollTop(), |
|
slack = Math.round(windowHeight * this.get('slackRatio')), |
|
viewportTop = windowTop - slack, |
|
windowBottom = windowTop + windowHeight, |
|
viewportBottom = windowBottom + slack, |
|
topView = this.findTopView(childViews, viewportTop, 0, childViews.length-1), |
|
bodyHeight = this.get('wrapperHeight') ? this.$().height() : $('body').height(), |
|
bottomView = topView, |
|
offsetFixedTopElement = this.get('offsetFixedTopElement'), |
|
offsetFixedBottomElement = this.get('offsetFixedBottomElement'); |
|
|
|
if (windowBottom > bodyHeight) { windowBottom = bodyHeight; } |
|
if (viewportBottom > bodyHeight) { viewportBottom = bodyHeight; } |
|
|
|
if (offsetFixedTopElement) { |
|
windowTop += (offsetFixedTopElement.outerHeight(true) || 0); |
|
} |
|
|
|
if (offsetFixedBottomElement) { |
|
windowBottom -= (offsetFixedBottomElement.outerHeight(true) || 0); |
|
} |
|
|
|
// Find the bottom view and what's onscreen |
|
while (bottomView < childViews.length) { |
|
var view = childViews[bottomView], |
|
$view = view.$(), |
|
// in case of not full-window scrolling |
|
scrollOffset = this.get('wrapperTop') || 0, |
|
viewTop = $view.offset().top + scrollOffset, |
|
viewBottom = viewTop + $view.height(); |
|
|
|
if (viewTop > viewportBottom) { break; } |
|
toUncloak.push(view); |
|
|
|
if (viewBottom > windowTop && viewTop <= windowBottom) { |
|
onscreen.push(view.get('content')); |
|
onscreenCloaks.push(view); |
|
} |
|
|
|
bottomView++; |
|
} |
|
if (bottomView >= childViews.length) { bottomView = childViews.length - 1; } |
|
|
|
// If our controller has a `sawObjects` method, pass the on screen objects to it. |
|
var controller = this.get('controller'); |
|
if (onscreen.length) { |
|
this.setProperties({topVisible: onscreen[0], bottomVisible: onscreen[onscreen.length-1]}); |
|
if (controller && controller.sawObjects) { |
|
Em.run.schedule('afterRender', function() { |
|
controller.sawObjects(onscreen); |
|
}); |
|
} |
|
} else { |
|
this.setProperties({topVisible: null, bottomVisible: null}); |
|
} |
|
|
|
var toCloak = childViews.slice(0, topView).concat(childViews.slice(bottomView+1)); |
|
|
|
this._uncloak = toUncloak; |
|
if(this._nextUncloak){ |
|
Em.run.cancel(this._nextUncloak); |
|
this._nextUncloak = null; |
|
} |
|
|
|
Em.run.schedule('afterRender', this, function() { |
|
onscreenCloaks.forEach(function (v) { |
|
if(v && v.uncloak) { |
|
v.uncloak(); |
|
} |
|
}); |
|
toCloak.forEach(function (v) { v.cloak(); }); |
|
if (self._nextUncloak) { Em.run.cancel(self._nextUncloak); } |
|
self._nextUncloak = Em.run.later(self, self.uncloakQueue,50); |
|
}); |
|
|
|
for (var j=bottomView; j<childViews.length; j++) { |
|
var checkView = childViews[j]; |
|
if (!checkView._containedView) { |
|
if (!checkView.get('loading')) { |
|
checkView.$().html(this.get('loadingHTML')); |
|
} |
|
return; |
|
} |
|
} |
|
}, |
|
|
|
uncloakQueue: function(){ |
|
var maxPerRun = 3, delay = 50, processed = 0, self = this; |
|
|
|
if(this._uncloak){ |
|
while(processed < maxPerRun && this._uncloak.length>0){ |
|
var view = this._uncloak.shift(); |
|
if(view && view.uncloak && !view._containedView){ |
|
Em.run.schedule('afterRender', view, view.uncloak); |
|
processed++; |
|
} |
|
} |
|
if(this._uncloak.length === 0){ |
|
this._uncloak = null; |
|
} else { |
|
Em.run.schedule('afterRender', self, function(){ |
|
if(self._nextUncloak){ |
|
Em.run.cancel(self._nextUncloak); |
|
} |
|
self._nextUncloak = Em.run.next(self, function(){ |
|
if(self._nextUncloak){ |
|
Em.run.cancel(self._nextUncloak); |
|
} |
|
self._nextUncloak = Em.run.later(self,self.uncloakQueue,delay); |
|
}); |
|
}); |
|
} |
|
} |
|
}, |
|
|
|
scrollTriggered: function() { |
|
Em.run.scheduleOnce('afterRender', this, 'scrolled'); |
|
}, |
|
|
|
_startEvents: function() { |
|
if (this.get('offsetFixed')) { |
|
Em.warn("Cloaked-collection's `offsetFixed` is deprecated. Use `offsetFixedTop` instead."); |
|
} |
|
|
|
var self = this, |
|
offsetFixedTop = this.get('offsetFixedTop') || this.get('offsetFixed'), |
|
offsetFixedBottom = this.get('offsetFixedBottom'), |
|
scrollDebounce = this.get('scrollDebounce'), |
|
onScrollMethod = function() { |
|
Ember.run.debounce(self, 'scrollTriggered', scrollDebounce); |
|
}; |
|
|
|
if (offsetFixedTop) { |
|
this.set('offsetFixedTopElement', Ember.$(offsetFixedTop)); |
|
} |
|
|
|
if (offsetFixedBottom) { |
|
this.set('offsetFixedBottomElement', Ember.$(offsetFixedBottom)); |
|
} |
|
|
|
Ember.$(document).bind('touchmove.ember-cloak', onScrollMethod); |
|
Ember.$(window).bind('scroll.ember-cloak', onScrollMethod); |
|
this.addObserver('wrapperTop', self, onScrollMethod); |
|
this.addObserver('wrapperHeight', self, onScrollMethod); |
|
this.addObserver('content.@each', self, onScrollMethod); |
|
this.scrollTriggered(); |
|
|
|
this.set('scrollingEnabled', true); |
|
}.on('didInsertElement'), |
|
|
|
cleanUp: function() { |
|
Ember.$(document).unbind('touchmove.ember-cloak'); |
|
Ember.$(window).unbind('scroll.ember-cloak'); |
|
this.set('scrollingEnabled', false); |
|
}, |
|
|
|
_endEvents: function() { |
|
this.cleanUp(); |
|
}.on('willDestroyElement') |
|
}); |
|
|
|
|
|
/** |
|
A cloaked view is one that removes its content when scrolled off the screen |
|
@class CloakedView |
|
@extends Ember.View |
|
@namespace Ember |
|
**/ |
|
Ember.CloakedView = Ember.View.extend({ |
|
attributeBindings: ['style'], |
|
_containedView: null, |
|
_scheduled: null, |
|
|
|
init: function() { |
|
this._super(); |
|
this._scheduled = false; |
|
this._childViews = []; |
|
}, |
|
|
|
setContainedView: function(cv) { |
|
if (this._childViews[0]) { |
|
this._childViews[0].destroy(); |
|
this._childViews[0] = cv; |
|
} |
|
|
|
if (cv) { |
|
cv.set('_parentView', this); |
|
cv.set('templateData', this.get('templateData')); |
|
this._childViews[0] = cv; |
|
} else { |
|
this._childViews.clear(); |
|
} |
|
|
|
if (this._scheduled) return; |
|
this._scheduled = true; |
|
this.set('_containedView', cv); |
|
Ember.run.schedule('render', this, this.updateChildView); |
|
}, |
|
|
|
render: function (buffer) { |
|
var el = buffer.element(); |
|
this._childViewsMorph = buffer.dom.createMorph(el, null, null, el); |
|
}, |
|
|
|
updateChildView: function () { |
|
this._scheduled = false; |
|
if (!this._elementCreated || this.isDestroying || this.isDestroyed) { return; } |
|
|
|
var childView = this._containedView; |
|
if (childView && !childView._elementCreated) { |
|
this._renderer.renderTree(childView, this, 0); |
|
} |
|
}, |
|
|
|
/** |
|
Triggers the set up for rendering a view that is cloaked. |
|
@method uncloak |
|
*/ |
|
uncloak: function() { |
|
var state = this._state || this.state; |
|
if (state !== 'inDOM' && state !== 'preRender') { return; } |
|
|
|
if (!this._containedView) { |
|
var model = this.get('content'), |
|
controller = null, |
|
container = this.get('container'); |
|
|
|
// Wire up the itemController if necessary |
|
var controllerName = this.get('cloaksController'); |
|
if (controllerName) { |
|
var controllerFullName = 'controller:' + controllerName, |
|
factory = container.lookupFactory(controllerFullName), |
|
parentController = this.get('controller'); |
|
|
|
// let ember generate controller if needed |
|
if (factory === undefined) { |
|
factory = Ember.generateControllerFactory(container, controllerName, model); |
|
|
|
// inform developer about typo |
|
Ember.Logger.warn('ember-cloaking: can\'t lookup controller by name "' + controllerFullName + '".'); |
|
Ember.Logger.warn('ember-cloaking: using ' + factory.toString() + '.'); |
|
} |
|
|
|
controller = factory.create({ |
|
model: model, |
|
parentController: parentController, |
|
target: parentController |
|
}); |
|
} |
|
|
|
var createArgs = {}, |
|
target = controller || model; |
|
|
|
if (this.get('preservesContext')) { |
|
createArgs.content = target; |
|
} else { |
|
createArgs.context = target; |
|
} |
|
if (controller) { createArgs.controller = controller; } |
|
this.setProperties({ |
|
style: null, |
|
loading: false |
|
}); |
|
|
|
this.setContainedView(this.createChildView(this.get('cloaks'), createArgs)); |
|
} |
|
}, |
|
|
|
/** |
|
Removes the view from the DOM and tears down all observers. |
|
@method cloak |
|
*/ |
|
cloak: function() { |
|
var self = this; |
|
|
|
if (this._containedView && (this._state || this.state) === 'inDOM') { |
|
var style = 'height: ' + this.$().height() + 'px;'; |
|
this.set('style', style); |
|
this.$().prop('style', style); |
|
|
|
|
|
// We need to remove the container after the height of the element has taken |
|
// effect. |
|
Ember.run.schedule('afterRender', function() { |
|
self.setContainedView(null); |
|
}); |
|
} |
|
}, |
|
|
|
_setHeights: function(){ |
|
if (!this._containedView) { |
|
// setting default height |
|
// but do not touch if height already defined |
|
if(!this.$().height()){ |
|
var defaultHeight = 100; |
|
if(this.get('defaultHeight')) { |
|
defaultHeight = this.get('defaultHeight'); |
|
} |
|
|
|
this.$().css('height', defaultHeight); |
|
} |
|
} |
|
}.on('didInsertElement') |
|
}); |
|
|
|
Ember.Handlebars.registerHelper('cloaked-collection', function(options) { |
|
var hash = options.hash, |
|
types = options.hashTypes; |
|
|
|
for (var prop in hash) { |
|
if (types[prop] === 'ID') { |
|
hash[prop + 'Binding'] = hash[prop]; |
|
delete hash[prop]; |
|
} |
|
} |
|
return Ember.Handlebars.helpers.view.call(this, Ember.CloakedCollectionView, options); |
|
}); |