Created
June 29, 2012 21:44
-
-
Save stefanpenner/3020853 to your computer and use it in GitHub Desktop.
A web page created at CodePen.io
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ -> | |
window.App = Ember.Application.create() | |
$(document).bind('resize orientationChanged scroll', => $(window).trigger('viewportDidChange') ) | |
App.BufferedView = Ember.View.extend | |
collection: [] | |
offset: 0 | |
limit: 4 | |
bufferStateBinding: 'manager.currentState.name' | |
init: -> | |
@set('manager', App.BufferedView.Manager.create({delegate: @})) | |
window.manager = @get('manager') | |
@_super() | |
getNextSegment: -> @get('manager').send('getNextSegment') | |
doesHaveMore: -> | |
Ember.run.next( -> $(document).trigger('scroll') ) | |
isInFlight: -> | |
didInsertElement: -> | |
viewportDidChange = => | |
element = @.$() | |
height = element.height() | |
elementYOffset = element.offset().top + height | |
pageYOffset = $(window).height() + window.pageYOffset | |
doesHaveMore = @getPath('manager.currentState.name') is 'hasMore' | |
if (pageYOffset + 10) > elementYOffset and doesHaveMore | |
@getNextSegment() | |
$(window).bind('viewportDidChange', viewportDidChange).trigger('viewportDidChange') | |
shouldConsumeMore: -> | |
source = @getPath('source') | |
collectionLength = @getPath('collection.length') | |
state = @getPath('manager.currentState.name') | |
manager = @get('manager') | |
source.consumerIsWaitingForMore(manager, collectionLength) | |
doesNotHaveMore: -> @shouldConsumeMore() | |
isIdle: -> @shouldConsumeMore() | |
appendNextSegment: -> | |
collection = @get('collection') | |
source = @get('source') | |
limit = @get('limit') | |
offset = @get('offset') | |
manager = @get('manager') | |
nextSegment = source.slice(offset, offset + limit) | |
collection.pushObjects(nextSegment) | |
@set('offset', collection.get('length')) | |
manager.send('didGetNextSegment') | |
App.BufferedView = Ember.View.extend | |
collection: [] | |
offset: 0 | |
limit: 4 | |
bufferStateBinding: 'manager.currentState.name' | |
init: -> | |
@set('manager', App.BufferedView.Manager.create({delegate: @})) | |
window.manager = @get('manager') | |
@_super() | |
getNextSegment: -> @get('manager').send('getNextSegment') | |
doesHaveMore: -> | |
Ember.run.next( -> $(document).trigger('scroll') ) | |
isInFlight: -> | |
didInsertElement: -> | |
viewportDidChange = => | |
element = @.$() | |
height = element.height() | |
elementYOffset = element.offset().top + height | |
pageYOffset = $(window).height() + window.pageYOffset | |
doesHaveMore = @getPath('manager.currentState.name') is 'hasMore' | |
if (pageYOffset + 10) > elementYOffset and doesHaveMore | |
@getNextSegment() | |
$(window).bind('viewportDidChange', viewportDidChange).trigger('viewportDidChange') | |
shouldConsumeMore: -> | |
source = @getPath('source') | |
collectionLength = @getPath('collection.length') | |
state = @getPath('manager.currentState.name') | |
manager = @get('manager') | |
source.consumerIsWaitingForMore(manager, collectionLength) | |
doesNotHaveMore: -> @shouldConsumeMore() | |
isIdle: -> @shouldConsumeMore() | |
appendNextSegment: -> | |
collection = @get('collection') | |
source = @get('source') | |
limit = @get('limit') | |
offset = @get('offset') | |
manager = @get('manager') | |
nextSegment = source.slice(offset, offset + limit) | |
collection.pushObjects(nextSegment) | |
@set('offset', collection.get('length')) | |
manager.send('didGetNextSegment') | |
App.BufferedView.Manager = Ember.StateManager.extend | |
initialState: 'idle' | |
apple: 'stefan' | |
hasMore: Ember.State.create | |
enter: (manager) -> | |
Ember.run.next => manager.delegate.doesHaveMore() | |
getNextSegment: (manager) -> manager.goToState('inFlight') | |
inFlight: Ember.State.create | |
enter: (manager) -> | |
Ember.run.next => manager.delegate.isInFlight() | |
didGetNextSegment: (manager) -> manager.goToState('idle') | |
idle: Ember.State.create | |
enter: (manager) -> | |
Ember.run.next => manager.delegate.isIdle() | |
doesHaveMore: (manager) -> manager.goToState('hasMore') | |
doesNotHaveMore: (manager) -> manager.goToState('hasNoMore') | |
hasNoMore: Ember.State.create | |
enter: -> | |
Ember.run.next => manager.delegate.doesNotHaveMore() | |
# re-awaken | |
doesHaveMore: (manager) -> manager.goToState('hasMore') | |
doesNotHaveMore: (manager) -> manager.goToState('hasNoMore') | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<title>CodePen · A Pen by stefanpenner</title> | |
<style> | |
#codepen-footer, #codepen-footer * { | |
-webkit-box-sizing: border-box !important; | |
-moz-box-sizing: border-box !important; | |
box-sizing: border-box !important; | |
} | |
#codepen-footer { | |
display: block !important; | |
position: fixed !important; | |
bottom: 0 !important; | |
left: 0 !important; | |
width: 100% !important; | |
padding: 0 10px !important; | |
margin: 0 !important; | |
height: 30px !important; | |
line-height: 30px !important; | |
font-size: 12px !important; | |
color: #eeeeee !important; | |
background-color: #505050 !important; | |
text-align: left !important; | |
background: -webkit-linear-gradient(top, #505050, #383838) !important; | |
background: -moz-linear-gradient(top, #505050, #383838) !important; | |
background: -ms-linear-gradient(top, #505050, #383838) !important; | |
background: -o-linear-gradient(top, #505050, #383838) !important; | |
border-top: 1px solid black !important; | |
border-bottom: 1px solid black !important; | |
border-radius: 0 !important; | |
border-image: none !important; | |
box-shadow: inset 0 1px 0 #6e6e6e, 0 2px 2px rgba(0, 0, 0, 0.4) !important; | |
z-index: 300 !important; | |
font-family: "Lucida Grande", "Lucida Sans Unicode", Tahoma, sans-serif !important; | |
letter-spacing: 0 !important; | |
word-spacing: 0 !important; | |
} | |
#codepen-footer a { | |
color: #a7a7a7 !important; | |
text-decoration: none !important; | |
} | |
#codepen-footer a:hover { | |
color: white !important; | |
} | |
</style> | |
<script> | |
// Kill alerts, confirmations and prompts | |
window.alert = function(){}; | |
window.confirm = function(){}; | |
window.prompt = function(){}; | |
window.open = function(){}; | |
window.print = function(){}; | |
</script> | |
<script src="http://codepen.io/javascripts/libs/prefixfree.min.js"></script> | |
</head> | |
<body> | |
<script src="https://raw.github.com/qlabs/when/master/app/assets/javascripts/ember/lib/ember.js?login=stefanpenner&token=dd36bd239833661c6c6e3e1f8702b07a"></script> | |
<script type="text/x-handlebars"> | |
<h1>Buffered View Example:</h1> | |
{{#view App.BufferedView sourceBinding="App.sourceController"}} | |
<div style="position: fixed; top: 0; right: 0"> | |
Limit: {{limit}} Offset: {{offset}} BufferState: {{bufferState}} | |
<br/> | |
Visible Collection Length: {{collection.length}} | |
<br/> | |
Total Collection Length: {{source.length}} | |
(<a href="#" {{action "appendMore" target="App.sourceController"}}>Append More</a>) | |
<br/> | |
</div> | |
{{#each collection}} | |
{{this}} | |
<br/> | |
{{/each}} | |
{{/view}} | |
</script> | |
<script src="http://codepen.io/javascripts/libs/modernizr.js"></script> | |
<!-- invalid external javascript file: https://raw.github.com/qlabs/when/master/app/assets/javascripts/ember/lib/ember.js?login=stefanpenner&token=dd36bd239833661c6c6e3e1f8702b07a --> | |
<script> | |
(function() { | |
(function() { | |
$(function() { | |
var _this = this; | |
window.App = Ember.Application.create(); | |
$(document).bind('resize orientationChanged scroll', function() { | |
return $(window).trigger('viewportDidChange'); | |
}); | |
return App.BufferedView = Ember.View.extend({ | |
collection: [], | |
offset: 0, | |
limit: 4, | |
bufferStateBinding: 'manager.currentState.name', | |
init: function() { | |
this.set('manager', App.BufferedView.Manager.create({ | |
delegate: this | |
})); | |
window.manager = this.get('manager'); | |
return this._super(); | |
}, | |
getNextSegment: function() { | |
return this.get('manager').send('getNextSegment'); | |
}, | |
doesHaveMore: function() { | |
return Ember.run.next(function() { | |
return $(document).trigger('scroll'); | |
}); | |
}, | |
isInFlight: function() {}, | |
didInsertElement: function() { | |
var viewportDidChange, | |
_this = this; | |
viewportDidChange = function() { | |
var doesHaveMore, element, elementYOffset, height, pageYOffset; | |
element = _this.$(); | |
height = element.height(); | |
elementYOffset = element.offset().top + height; | |
pageYOffset = $(window).height() + window.pageYOffset; | |
doesHaveMore = _this.getPath('manager.currentState.name') === 'hasMore'; | |
if ((pageYOffset + 10) > elementYOffset && doesHaveMore) { | |
return _this.getNextSegment(); | |
} | |
}; | |
return $(window).bind('viewportDidChange', viewportDidChange).trigger('viewportDidChange'); | |
}, | |
shouldConsumeMore: function() { | |
var collectionLength, manager, source, state; | |
source = this.getPath('source'); | |
collectionLength = this.getPath('collection.length'); | |
state = this.getPath('manager.currentState.name'); | |
manager = this.get('manager'); | |
return source.consumerIsWaitingForMore(manager, collectionLength); | |
}, | |
doesNotHaveMore: function() { | |
return this.shouldConsumeMore(); | |
}, | |
isIdle: function() { | |
return this.shouldConsumeMore(); | |
}, | |
appendNextSegment: function() { | |
var collection, limit, manager, nextSegment, offset, source; | |
collection = this.get('collection'); | |
source = this.get('source'); | |
limit = this.get('limit'); | |
offset = this.get('offset'); | |
manager = this.get('manager'); | |
nextSegment = source.slice(offset, offset + limit); | |
collection.pushObjects(nextSegment); | |
this.set('offset', collection.get('length')); | |
return manager.send('didGetNextSegment'); | |
} | |
}); | |
}); | |
App.BufferedView = Ember.View.extend({ | |
collection: [], | |
offset: 0, | |
limit: 4, | |
bufferStateBinding: 'manager.currentState.name', | |
init: function() { | |
this.set('manager', App.BufferedView.Manager.create({ | |
delegate: this | |
})); | |
window.manager = this.get('manager'); | |
return this._super(); | |
}, | |
getNextSegment: function() { | |
return this.get('manager').send('getNextSegment'); | |
}, | |
doesHaveMore: function() { | |
return Ember.run.next(function() { | |
return $(document).trigger('scroll'); | |
}); | |
}, | |
isInFlight: function() {}, | |
didInsertElement: function() { | |
var viewportDidChange, | |
_this = this; | |
viewportDidChange = function() { | |
var doesHaveMore, element, elementYOffset, height, pageYOffset; | |
element = _this.$(); | |
height = element.height(); | |
elementYOffset = element.offset().top + height; | |
pageYOffset = $(window).height() + window.pageYOffset; | |
doesHaveMore = _this.getPath('manager.currentState.name') === 'hasMore'; | |
if ((pageYOffset + 10) > elementYOffset && doesHaveMore) { | |
return _this.getNextSegment(); | |
} | |
}; | |
return $(window).bind('viewportDidChange', viewportDidChange).trigger('viewportDidChange'); | |
}, | |
shouldConsumeMore: function() { | |
var collectionLength, manager, source, state; | |
source = this.getPath('source'); | |
collectionLength = this.getPath('collection.length'); | |
state = this.getPath('manager.currentState.name'); | |
manager = this.get('manager'); | |
return source.consumerIsWaitingForMore(manager, collectionLength); | |
}, | |
doesNotHaveMore: function() { | |
return this.shouldConsumeMore(); | |
}, | |
isIdle: function() { | |
return this.shouldConsumeMore(); | |
}, | |
appendNextSegment: function() { | |
var collection, limit, manager, nextSegment, offset, source; | |
collection = this.get('collection'); | |
source = this.get('source'); | |
limit = this.get('limit'); | |
offset = this.get('offset'); | |
manager = this.get('manager'); | |
nextSegment = source.slice(offset, offset + limit); | |
collection.pushObjects(nextSegment); | |
this.set('offset', collection.get('length')); | |
return manager.send('didGetNextSegment'); | |
} | |
}); | |
App.BufferedView.Manager = Ember.StateManager.extend({ | |
initialState: 'idle', | |
apple: 'stefan', | |
hasMore: Ember.State.create({ | |
enter: function(manager) { | |
var _this = this; | |
return Ember.run.next(function() { | |
return manager.delegate.doesHaveMore(); | |
}); | |
} | |
}), | |
getNextSegment: function(manager) { | |
return manager.goToState('inFlight'); | |
} | |
}); | |
({ | |
inFlight: Ember.State.create({ | |
enter: function(manager) { | |
var _this = this; | |
return Ember.run.next(function() { | |
return manager.delegate.isInFlight(); | |
}); | |
}, | |
didGetNextSegment: function(manager) { | |
return manager.goToState('idle'); | |
} | |
}), | |
idle: Ember.State.create({ | |
enter: function(manager) { | |
var _this = this; | |
return Ember.run.next(function() { | |
return manager.delegate.isIdle(); | |
}); | |
}, | |
doesHaveMore: function(manager) { | |
return manager.goToState('hasMore'); | |
}, | |
doesNotHaveMore: function(manager) { | |
return manager.goToState('hasNoMore'); | |
} | |
}), | |
hasNoMore: Ember.State.create({ | |
enter: function() { | |
var _this = this; | |
return Ember.run.next(function() { | |
return manager.delegate.doesNotHaveMore(); | |
}); | |
}, | |
doesHaveMore: function(manager) { | |
return manager.goToState('hasMore'); | |
}, | |
doesNotHaveMore: function(manager) { | |
return manager.goToState('hasNoMore'); | |
} | |
}) | |
}); | |
}).call(this); | |
})(); | |
</script> | |
<div id="codepen-footer"> | |
<a style="color: #f73535 !important;" href="https://codepen.wufoo.com/forms/m7x3r3/def/field14=" onclick="window.open(this.href, null, 'height=517, width=680, toolbar=0, location=0, status=1, scrollbars=1, resizable=1'); return false">Report Abuse</a> | |
| |
<a href="/stefanpenner/pen/1/5">Edit this Pen</a> | |
</div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://raw.github.com/qlabs/when/master/app/assets/javascripts/ember/lib/ember.js?login=stefanpenner&token=dd36bd239833661c6c6e3e1f8702b07a"></script> | |
<script type="text/x-handlebars"> | |
<h1>Buffered View Example:</h1> | |
{{#view App.BufferedView sourceBinding="App.sourceController"}} | |
<div style="position: fixed; top: 0; right: 0"> | |
Limit: {{limit}} Offset: {{offset}} BufferState: {{bufferState}} | |
<br/> | |
Visible Collection Length: {{collection.length}} | |
<br/> | |
Total Collection Length: {{source.length}} | |
(<a href="#" {{action "appendMore" target="App.sourceController"}}>Append More</a>) | |
<br/> | |
</div> | |
{{#each collection}} | |
{{this}} | |
<br/> | |
{{/each}} | |
{{/view}} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment