This commit is contained in:
Sam 2014-12-04 09:35:11 +11:00
parent 665ff94ff7
commit 8977d5917b
15 changed files with 10667 additions and 13458 deletions

View file

@ -1,5 +1,12 @@
<%
if Rails.env.development?
require_asset ("development/list-view.js")
else
require_asset ("production/list-view.js")
end
require_asset("main_include_admin.js")
DiscoursePluginRegistry.admin_javascripts.each { |js| require_asset(js) }
%>

View file

@ -8,7 +8,7 @@
**/
Discourse.CategoryList = Ember.ArrayProxy.extend({
init: function() {
this.set('content', []);
this.content = [];
this._super();
}
});

View file

@ -527,7 +527,7 @@ Discourse.PostStream = Em.Object.extend({
this.get('stream').removeObjects(postIds);
this.get('posts').removeObjects(posts);
postIds.forEach(function(id){
identityMap.delete(id);
identityMap.remove(id);
});
},

View file

@ -73,7 +73,7 @@
{{loading-spinner condition=postStream.loadingAbove}}
{{#unless postStream.loadingFilter}}
{{cloaked-collection itemViewClass="post"
{{cloaked-collection cloakView="post"
idProperty="post_number"
defaultHeight="200"
content=postStream.posts

View file

@ -1,3 +1,10 @@
/**
Lists previous posts in the history of a post.
@class ReplyHistory
@namespace Discourse
@module Discourse
**/
export default Em.CollectionView.extend({
tagName: 'section',
classNameBindings: [':embedded-posts', ':top', ':topic-body', ':offset2', 'hidden'],
@ -5,3 +12,5 @@ export default Em.CollectionView.extend({
hidden: Em.computed.equal('content.length', 0),
previousPost: true
});

View file

@ -1,4 +1,3 @@
//= require list-view
//= require admin/models/user-field
//= require admin/controllers/admin-email-skipped
//= require admin/controllers/change-site-customization-details

View file

@ -92,6 +92,3 @@ pre code {
.row:after {clear: both;}
#offscreen-content {
display: none;
}

View file

@ -61,9 +61,6 @@
<section id='main'>
</section>
<div id='offscreen-content'>
</div>
<% unless current_user %>
<form id='hidden-login-form' method="post" action="<%=login_path%>" style="display: none;">
<input name="username" type="text" id="signin_username">

View file

@ -49,6 +49,12 @@ var Poll = Discourse.Model.extend({
var PollView = Ember.View.extend({
templateName: "poll",
classNames: ['poll-ui'],
replaceElement: function(target) {
this._insertElementLater(function() {
target.replaceWith(this.$());
});
}
});
function initializePollView(self) {
@ -64,9 +70,13 @@ function initializePollView(self) {
postController: self.get('controller')
});
return self.createChildView(PollView, { controller: pollController });
var pollView = self.createChildView(PollView, {
controller: pollController
});
return pollView;
}
export default {
name: 'poll',
@ -80,14 +90,13 @@ export default {
}
var view = initializePollView(this);
var pollContainer = $post.find(".poll-ui:first");
if (pollContainer.length === 0) {
pollContainer = $post.find("ul:first");
}
var $div = $('<div>');
pollContainer.replaceWith($div);
view.constructor.renderer.appendTo(view, $div[0]);
view.replaceElement(pollContainer);
this.set('pollView', view);
}.on('postViewInserted'),
@ -99,4 +108,4 @@ export default {
}.on('willClearRender')
});
}
};
}

View file

@ -233,7 +233,7 @@ test("storePost", function() {
var postWithoutId = Discourse.Post.create({raw: 'hello world'});
stored = postStream.storePost(postWithoutId);
equal(stored, postWithoutId, "it returns the same post back");
equal(postStream.get('postIdentityMap.size'), 1, "it does not add a new entry into the identity map");
equal(postStream.get('postIdentityMap.length'), 1, "it does not add a new entry into the identity map");
});

File diff suppressed because it is too large Load diff

View file

@ -159,6 +159,79 @@ define("list-view/list_item_view",
var get = Ember.get, set = Ember.set;
function backportedInnerString(buffer) {
var content = [], childBuffers = buffer.childBuffers;
Ember.ArrayPolyfills.forEach.call(childBuffers, function(buffer) {
var stringy = typeof buffer === 'string';
if (stringy) {
content.push(buffer);
} else {
buffer.array(content);
}
});
return content.join('');
}
function willInsertElementIfNeeded(view) {
if (view.willInsertElement) {
view.willInsertElement();
}
}
function didInsertElementIfNeeded(view) {
if (view.didInsertElement) {
view.didInsertElement();
}
}
function rerender() {
var element, buffer, context, hasChildViews;
element = get(this, 'element');
if (!element) { return; }
context = get(this, 'context');
// releases action helpers in contents
// this means though that the ListItemView itself can't use classBindings or attributeBindings
// need support for rerender contents in ember
this.triggerRecursively('willClearRender');
if (this.lengthAfterRender > this.lengthBeforeRender) {
this.clearRenderedChildren();
this._childViews.length = this.lengthBeforeRender; // triage bug in ember
}
if (context) {
buffer = Ember.RenderBuffer();
buffer = this.renderToBuffer(buffer);
// check again for childViews, since rendering may have added some
hasChildViews = this._childViews.length > 0;
if (hasChildViews) {
this.invokeRecursively(willInsertElementIfNeeded, false);
}
element.innerHTML = buffer.innerString ? buffer.innerString() : backportedInnerString(buffer);
set(this, 'element', element);
var transitionTo = this._transitionTo ? this._transitionTo : this.transitionTo;
transitionTo.call(this, 'inDOM');
if (hasChildViews) {
this.invokeRecursively(didInsertElementIfNeeded, false);
}
} else {
element.innerHTML = ''; // when there is no context, this view should be completely empty
}
}
/**
The `Ember.ListItemView` view class renders a
[div](https://developer.mozilla.org/en/HTML/Element/div) HTML element
@ -188,7 +261,6 @@ define("list-view/list_item_view",
__exports__["default"] = Ember.View.extend(ListItemViewMixin, {
updateContext: function(newContext){
var context = get(this, 'context');
Ember.instrument('view.updateContext.render', this, function() {
if (context !== newContext) {
set(this, 'context', newContext);
@ -198,19 +270,10 @@ define("list-view/list_item_view",
}
}, this);
},
rerender: function () {
// todo: work around for tests. investigate a real fix.
if(get(this, 'isDestroying') || get(this, 'isDestroyed')) {
return;
}
return this._super.apply(this, arguments);
Ember.run.scheduleOnce('render', this, rerender);
},
_contextDidChange: Ember.observer(function () {
Ember.run.once(this, this.rerender);
}, 'context', 'controller')
_contextDidChange: Ember.observer(rerender, 'context', 'controller')
});
});
define("list-view/list_item_view_mixin",
@ -219,7 +282,7 @@ define("list-view/list_item_view_mixin",
"use strict";
// jshint validthis: true
var get = Ember.get;
var get = Ember.get, set = Ember.set;
function samePosition(a, b) {
return a && b && a.x === b.x && a.y === b.y;
@ -233,41 +296,28 @@ define("list-view/list_item_view_mixin",
position = this.position;
_position = this._position;
if (!position || !element) {
return;
}
if (!position || !element) { return; }
// // TODO: avoid needing this by avoiding unnecessary
// // calls to this method in the first place
if (samePosition(position, _position)) {
return;
}
Ember.run.schedule('render', this, this._parentView.applyTransform, this, position.x, position.y);
// TODO: avoid needing this by avoiding unnecessary
// calls to this method in the first place
if (samePosition(position, _position)) { return; }
Ember.run.schedule('render', this, this._parentView.applyTransform, element, position.x, position.y);
this._position = position;
}, this);
}
var TransformMixin = Ember.Mixin.create({
style: '',
attributeBindings: ['style'],
});
__exports__.TransformMixin = TransformMixin;
__exports__["default"] = Ember.Mixin.create(TransformMixin, {
_position: null,
classNames: ['ember-list-item-view'],
_positionElement: positionElement,
__exports__["default"] = Ember.Mixin.create({
init: function(){
this._super();
this.one('didInsertElement', positionElement);
},
classNames: ['ember-list-item-view'],
_position: null,
updatePosition: function(position) {
this.position = position;
this._positionElement();
}
},
_positionElement: positionElement
});
});
define("list-view/list_view",
@ -450,45 +500,24 @@ define("list-view/list_view_helper",
"use strict";
// TODO - remove this!
var el = document.createElement('div'), style = el.style;
var set = Ember.set;
function testProp (prop) {
var propPrefixes = ['Webkit', 'Moz', 'O', 'ms'];
function testProp(prop) {
if (prop in style) return prop;
var uppercaseProp = prop.charAt(0).toUpperCase() + prop.slice(1);
var dic = {
webkit: '-webkit-' + prop,
moz: '-moz-' + prop,
ms: 'ms' + uppercaseProp
};
var props = [
prop,
'webkit' + prop,
'webkit' + uppercaseProp,
'Moz' + uppercaseProp,
'moz' + uppercaseProp,
'ms' + uppercaseProp,
'ms' + prop
];
for (var i=0; i < props.length; i++) {
var property = props[i];
var prefix;
if (property in style) {
prefix = property.toLowerCase().replace(prop, '');
if (prefix && dic[prefix]) {
return dic[prefix];
}
return property;
for (var i=0; i<propPrefixes.length; i++) {
var prefixedProp = propPrefixes[i] + uppercaseProp;
if (prefixedProp in style) {
return prefixedProp;
}
}
return null;
}
var transformProp = testProp('transform');
var perspectiveProp = testProp('perspective');
var supports2D = transformProp !== null;
var supports3D = perspectiveProp !== null;
@ -496,27 +525,29 @@ define("list-view/list_view_helper",
transformProp: transformProp,
applyTransform: (function(){
if (supports2D) {
return function(childView, x, y){
set(childView, 'style', transformProp + ': translate(' + x + 'px, ' + y + 'px);');
return function(element, x, y){
element.style[transformProp] = 'translate(' + x + 'px, ' + y + 'px)';
};
} else {
return function(childView, x, y){
set(childView, 'style', 'top: ' + y + 'px; left: ' + x + 'px;');
return function(element, x, y){
element.style.top = y + 'px';
element.style.left = x + 'px';
};
}
})(),
apply3DTransform: (function(){
if (supports3D) {
return function(childView, x, y){
set(childView, 'style', transformProp + ': translate3d(' + x + 'px, ' + y + 'px, 0);');
return function(element, x, y){
element.style[transformProp] = 'translate3d(' + x + 'px, ' + y + 'px, 0)';
};
} else if (supports2D) {
return function(childView, x, y){
set(childView, 'style', transformProp + ': translate(' + x + 'px, ' + y + 'px);');
return function(element, x, y){
element.style[transformProp] = 'translate(' + x + 'px, ' + y + 'px)';
};
} else {
return function(childView, x, y){
set(childView, 'style', 'top: ' + y + 'px; left: ' + x + 'px;');
return function(element, x, y){
element.style.top = y + 'px';
element.style.left = x + 'px';
};
}
})()
@ -593,6 +624,13 @@ define("list-view/list_view_mixin",
this.unshiftObject(emptyView);
}
var domManager = Ember.create(Ember.ContainerView.proto().domManager);
domManager.prepend = function(view, html) {
view.$('.ember-list-container').prepend(html);
notifyMutationListeners();
};
function enableProfilingOutput() {
function before(name, time, payload) {
console.time(name);
@ -624,6 +662,7 @@ define("list-view/list_view_mixin",
classNames: ['ember-list-view'],
attributeBindings: ['style'],
classNameBindings: ['_isGrid:ember-list-view-grid:ember-list-view-list'],
domManager: domManager,
scrollTop: 0,
bottomPadding: 0, // TODO: maybe this can go away
_lastEndingIndex: 0,
@ -667,15 +706,9 @@ define("list-view/list_view_mixin",
@param {Ember.RenderBuffer} buffer The render buffer
*/
render: function(buffer) {
buffer.push('<div class="ember-list-container"></div>');
buffer.push('<div class="ember-list-container">');
this._super(buffer);
},
createChildViewsMorph: function (element) {
var children = element.children;
element = children[0];
this._childViewsMorph = this._renderer._dom.createMorph(element, children[children.length - 1], null);
return element;
buffer.push('</div>');
},
willInsertElement: function() {
@ -1402,9 +1435,7 @@ define("list-view/list_view_mixin",
},
destroy: function () {
if (!this._super()) {
return;
}
if (!this._super()) { return; }
if (this._createdEmptyView) {
this._createdEmptyView.destroy();
@ -1517,9 +1548,7 @@ define("list-view/virtual_list_scroller_events",
} else {
startEvent = 'mousedown';
handleStart = function (e) {
if (e.which !== 1) {
return;
}
if (e.which !== 1) return;
var target = e.target;
// avoid e.preventDefault() on fields
if (target && fieldRegex.test(target.tagName)) {
@ -1540,9 +1569,7 @@ define("list-view/virtual_list_scroller_events",
};
cancelEvent = 'mouseout';
handleCancel = function (e) {
if (e.relatedTarget) {
return;
}
if (e.relatedTarget) return;
unbindWindow(this.scrollerEventHandlers);
this.endScroll(e.timeStamp);
};
@ -1620,17 +1647,16 @@ define("list-view/virtual_list_scroller_events",
}
});
define("list-view/virtual_list_view",
["list-view/list_view_mixin","list-view/list_item_view_mixin","list-view/list_view_helper","list-view/virtual_list_scroller_events","exports"],
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
["list-view/list_view_mixin","list-view/list_view_helper","list-view/virtual_list_scroller_events","exports"],
function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
"use strict";
/*
global Scroller
*/
var ListViewMixin = __dependency1__["default"];
var TransformMixin = __dependency2__.TransformMixin;
var ListViewHelper = __dependency3__["default"];
var VirtualListScrollerEvents = __dependency4__["default"];
var ListViewHelper = __dependency2__["default"];
var VirtualListScrollerEvents = __dependency3__["default"];
var max = Math.max, get = Ember.get, set = Ember.set;
@ -1678,9 +1704,7 @@ define("list-view/virtual_list_view",
// Support old and new Ember versions
var state = view._state || view.state;
if (state !== 'inDOM') {
return;
}
if (state !== 'inDOM') { return; }
if (view.listContainerElement) {
view._scrollerTop = top;
@ -1698,23 +1722,17 @@ define("list-view/virtual_list_view",
updateScrollerDimensions(view);
},
setupPullToRefresh: function() {
if (!this.pullToRefreshViewClass) {
return;
}
if (!this.pullToRefreshViewClass) { return; }
this._insertPullToRefreshView();
this._activateScrollerPullToRefresh();
},
_insertPullToRefreshView: function(){
var pulldownClass = this.pullToRefreshViewClass.extend(TransformMixin);
this.pullToRefreshView = this.createChildView(pulldownClass);
this.pullToRefreshView = this.createChildView(this.pullToRefreshViewClass);
this.insertAt(0, this.pullToRefreshView);
var view = this;
this.pullToRefreshView.on('didInsertElement', function(){
Ember.run.schedule('afterRender', this, function(){
view.applyTransform(this, 0, -1 * view.pullToRefreshViewHeight);
view.applyTransform(this.get('element'), 0, -1 * view.pullToRefreshViewHeight);
});
});
},

View file

@ -8,13 +8,10 @@
@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'),
@ -28,7 +25,7 @@
this.set('itemViewClass', Ember.CloakedView.extend({
classNames: [cloakView + '-cloak'],
cloaks: cloakView,
preservesContext: this.get('preservesContext') === 'true',
preservesContext: this.get('preservesContext') === "true",
cloaksController: this.get('itemController'),
defaultHeight: this.get('defaultHeight'),
@ -202,11 +199,12 @@
var checkView = childViews[j];
if (!checkView._containedView) {
if (!checkView.get('loading')) {
checkView.$().html(this.get('loadingHTML'));
checkView.$().html(this.get('loadingHTML') || "Loading...");
}
return;
}
}
},
uncloakQueue: function(){
@ -250,9 +248,8 @@
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);
Ember.run.debounce(self, 'scrollTriggered', 10);
};
if (offsetFixedTop) {
@ -392,7 +389,8 @@
loading: false
});
this.setContainedView(this.createChildView(this.get('cloaks'), createArgs));
this._containedView = this.createChildView(this.get('cloaks'), createArgs);
this.rerender();
}
},
@ -409,15 +407,25 @@
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);
if(self._containedView){
self._containedView.remove();
self._containedView = null;
}
});
}
},
_removeContainedView: function(){
if(this._containedView){
this._containedView.remove();
this._containedView = null;
}
this._super();
}.on('willDestroyElement'),
_setHeights: function(){
if (!this._containedView) {
// setting default height
@ -431,8 +439,36 @@
this.$().css('height', defaultHeight);
}
}
}.on('didInsertElement')
}.on('didInsertElement'),
/**
Render the cloaked view if applicable.
@method render
*/
render: function(buffer) {
var containedView = this._containedView, self = this;
if (containedView && (containedView._state || containedView.state) !== 'inDOM') {
containedView.triggerRecursively('willInsertElement');
containedView.renderToBuffer(buffer);
if (Ember.View.prototype._transitionTo) {
containedView._transitionTo('inDOM');
} else {
containedView.transitionTo('inDOM');
}
Em.run.schedule('afterRender', function() {
if(self._containedView) {
self._containedView.triggerRecursively('didInsertElement');
}
});
}
}
});
Ember.Handlebars.registerHelper('cloaked-collection', function(options) {
var hash = options.hash,

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long