Trying to use a document fragment for the roster view
This commit is contained in:
parent
a9f9328682
commit
cfa55896a5
54
converse.js
54
converse.js
@ -3266,7 +3266,8 @@
|
|||||||
toggle_state: toggle_state
|
toggle_state: toggle_state
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.$el.hide().html(roster_markup);
|
this.$fragment = $('<span>');
|
||||||
|
this.$fragment.append($(roster_markup));
|
||||||
},
|
},
|
||||||
|
|
||||||
onAdd: function (item) {
|
onAdd: function (item) {
|
||||||
@ -3281,6 +3282,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
showRoster: function () {
|
||||||
|
if (this.$fragment) {
|
||||||
|
this.$el.html(this.$fragment)
|
||||||
|
delete this.$fragment;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
onChange: function (item) {
|
onChange: function (item) {
|
||||||
if ((_.size(item.changed) === 1) && _.contains(_.keys(item.changed), 'sorted')) {
|
if ((_.size(item.changed) === 1) && _.contains(_.keys(item.changed), 'sorted')) {
|
||||||
return;
|
return;
|
||||||
@ -3342,6 +3351,17 @@
|
|||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getRosterElement: function () {
|
||||||
|
// TODO: see is _ensureElement can be used.
|
||||||
|
// Return the document fragment if it exists.
|
||||||
|
var $el;
|
||||||
|
if (this.$fragment) {
|
||||||
|
return this.$fragment;
|
||||||
|
} else {
|
||||||
|
return this.$el;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
addRosterItem: function (item) {
|
addRosterItem: function (item) {
|
||||||
if ((converse.show_only_online_users) && (item.get('chat_status') !== 'online')) {
|
if ((converse.show_only_online_users) && (item.get('chat_status') !== 'online')) {
|
||||||
return this;
|
return this;
|
||||||
@ -3352,13 +3372,14 @@
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
view.render()
|
view.render()
|
||||||
|
var $el = this.getRosterElement();
|
||||||
if (view.$el.hasClass('current-xmpp-contact')) {
|
if (view.$el.hasClass('current-xmpp-contact')) {
|
||||||
// TODO: need to add group support
|
// TODO: need to add group support
|
||||||
this.$('.roster-group').after(view.el);
|
$el.find('.roster-group').after(view.el);
|
||||||
} else if (view.$el.hasClass('pending-xmpp-contact')) {
|
} else if (view.$el.hasClass('pending-xmpp-contact')) {
|
||||||
this.$('#pending-xmpp-contacts').after(view.el);
|
$el.find('#pending-xmpp-contacts').after(view.el);
|
||||||
} else if (view.$el.hasClass('requesting-xmpp-contact')) {
|
} else if (view.$el.hasClass('requesting-xmpp-contact')) {
|
||||||
this.$('#xmpp-contact-requests').after(view.render().el);
|
$el.find('#xmpp-contact-requests').after(view.render().el);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
@ -3379,9 +3400,10 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
toggleHeaders: function () {
|
toggleHeaders: function () {
|
||||||
var $contact_requests = this.$('#xmpp-contact-requests'),
|
var $el = this.getRosterElement();
|
||||||
$pending_contacts = this.$('#pending-xmpp-contacts');
|
var $contact_requests = $el.find('#xmpp-contact-requests'),
|
||||||
var $groups = this.$el.find('.roster-group');
|
$pending_contacts = $el.find('#pending-xmpp-contacts');
|
||||||
|
var $groups = $el.find('.roster-group');
|
||||||
// Hide the headers if there are no contacts under them
|
// Hide the headers if there are no contacts under them
|
||||||
_.each([$groups, $contact_requests, $pending_contacts], function (h) {
|
_.each([$groups, $contact_requests, $pending_contacts], function (h) {
|
||||||
var show_or_hide = function (h) {
|
var show_or_hide = function (h) {
|
||||||
@ -3431,29 +3453,19 @@
|
|||||||
* 1). See if the jquery detach method can be somehow used to avoid DOM reflows.
|
* 1). See if the jquery detach method can be somehow used to avoid DOM reflows.
|
||||||
* 2). Likewise see if documentFragment can be used.
|
* 2). Likewise see if documentFragment can be used.
|
||||||
*/
|
*/
|
||||||
this.$el.find('.roster-group').each($.proxy(function (idx, group) {
|
var $el = this.getRosterElement();
|
||||||
|
$el.find('.roster-group').each($.proxy(function (idx, group) {
|
||||||
var $group = $(group);
|
var $group = $(group);
|
||||||
var $contacts = $group.nextUntil('dt', 'dd.current-xmpp-contact');
|
var $contacts = $group.nextUntil('dt', 'dd.current-xmpp-contact');
|
||||||
$group.after($contacts.tsort({sortFunction: this.sortFunction, data: 'status'}, 'a'));
|
$group.after($contacts.tsort({sortFunction: this.sortFunction, data: 'status'}, 'a'));
|
||||||
},this));
|
},this));
|
||||||
// Also sort pending and requesting contacts
|
// Also sort pending and requesting contacts
|
||||||
var crit = {order:'asc'},
|
var crit = {order:'asc'},
|
||||||
$contact_requests = this.$('#xmpp-contact-requests'),
|
$contact_requests = $el.find('#xmpp-contact-requests'),
|
||||||
$pending_contacts = this.$('#pending-xmpp-contacts');
|
$pending_contacts = $el.find('#pending-xmpp-contacts');
|
||||||
$pending_contacts.after($pending_contacts.siblings('dd.pending-xmpp-contact').tsort(crit));
|
$pending_contacts.after($pending_contacts.siblings('dd.pending-xmpp-contact').tsort(crit));
|
||||||
$contact_requests.after($contact_requests.siblings('dd.requesting-xmpp-contact').tsort(crit));
|
$contact_requests.after($contact_requests.siblings('dd.requesting-xmpp-contact').tsort(crit));
|
||||||
return this;
|
return this;
|
||||||
},
|
|
||||||
|
|
||||||
showRoster: function () {
|
|
||||||
if (!this.$el.is(':visible')) {
|
|
||||||
// Once all initial roster items have been added, we
|
|
||||||
// can show the roster.
|
|
||||||
// TODO: It would be more efficient to use a
|
|
||||||
// documentFragment and then put that in the DOM
|
|
||||||
this.$el.show();
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -129,28 +129,32 @@
|
|||||||
describe("The Contacts Roster", $.proxy(function (mock, utils) {
|
describe("The Contacts Roster", $.proxy(function (mock, utils) {
|
||||||
|
|
||||||
describe("Pending Contacts", $.proxy(function () {
|
describe("Pending Contacts", $.proxy(function () {
|
||||||
beforeEach($.proxy(function () {
|
function _clearContacts () {
|
||||||
runs(function () {
|
utils.clearBrowserStorage();
|
||||||
converse.rosterview.model.reset();
|
converse.rosterview.model.reset();
|
||||||
utils.createContacts('pending').openControlBox();
|
converse.rosterview.initialize();
|
||||||
});
|
};
|
||||||
waits(50);
|
|
||||||
runs(function () {
|
function _addContacts () {
|
||||||
utils.openContactsPanel();
|
_clearContacts();
|
||||||
});
|
// Must be initialized, so that render is called and documentFragment set up.
|
||||||
}, converse));
|
utils.createContacts('pending').openControlBox();
|
||||||
|
utils.openContactsPanel();
|
||||||
|
};
|
||||||
|
|
||||||
it("do not have a header if there aren't any", $.proxy(function () {
|
it("do not have a header if there aren't any", $.proxy(function () {
|
||||||
converse.rosterview.model.reset();
|
_addContacts();
|
||||||
|
this.rosterview.model.reset();
|
||||||
expect(this.rosterview.$el.find('dt#pending-xmpp-contacts').css('display')).toEqual('none');
|
expect(this.rosterview.$el.find('dt#pending-xmpp-contacts').css('display')).toEqual('none');
|
||||||
}, converse));
|
}, converse));
|
||||||
|
|
||||||
it("can be collapsed under their own header", $.proxy(function () {
|
it("can be collapsed under their own header", $.proxy(function () {
|
||||||
|
_addContacts();
|
||||||
checkHeaderToggling.apply(this, [this.rosterview.$el.find('dt#pending-xmpp-contacts')]);
|
checkHeaderToggling.apply(this, [this.rosterview.$el.find('dt#pending-xmpp-contacts')]);
|
||||||
}, converse));
|
}, converse));
|
||||||
|
|
||||||
it("can be added to the roster", $.proxy(function () {
|
it("can be added to the roster", $.proxy(function () {
|
||||||
converse.rosterview.model.reset(); // We want to manually create users so that we can spy
|
_clearContacts();
|
||||||
spyOn(converse, 'emit');
|
spyOn(converse, 'emit');
|
||||||
spyOn(this.rosterview, 'updateRoster').andCallThrough();
|
spyOn(this.rosterview, 'updateRoster').andCallThrough();
|
||||||
runs($.proxy(function () {
|
runs($.proxy(function () {
|
||||||
@ -171,6 +175,7 @@
|
|||||||
}, converse));
|
}, converse));
|
||||||
|
|
||||||
it("can be removed by the user", $.proxy(function () {
|
it("can be removed by the user", $.proxy(function () {
|
||||||
|
_addContacts();
|
||||||
var jid = mock.pend_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
var jid = mock.pend_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||||
var view = this.rosterview.get(jid);
|
var view = this.rosterview.get(jid);
|
||||||
spyOn(window, 'confirm').andReturn(true);
|
spyOn(window, 'confirm').andReturn(true);
|
||||||
@ -190,6 +195,7 @@
|
|||||||
}, converse));
|
}, converse));
|
||||||
|
|
||||||
it("will lose their own header once the last one has been removed", $.proxy(function () {
|
it("will lose their own header once the last one has been removed", $.proxy(function () {
|
||||||
|
_addContacts();
|
||||||
var view;
|
var view;
|
||||||
spyOn(window, 'confirm').andReturn(true);
|
spyOn(window, 'confirm').andReturn(true);
|
||||||
for (i=0; i<mock.pend_names.length; i++) {
|
for (i=0; i<mock.pend_names.length; i++) {
|
||||||
@ -200,7 +206,7 @@
|
|||||||
}, converse));
|
}, converse));
|
||||||
|
|
||||||
it("can be added to the roster and they will be sorted alphabetically", $.proxy(function () {
|
it("can be added to the roster and they will be sorted alphabetically", $.proxy(function () {
|
||||||
converse.rosterview.model.reset(); // We want to manually create users so that we can spy
|
_clearContacts();
|
||||||
var i, t, is_last;
|
var i, t, is_last;
|
||||||
spyOn(converse, 'emit');
|
spyOn(converse, 'emit');
|
||||||
spyOn(this.rosterview, 'updateRoster').andCallThrough();
|
spyOn(this.rosterview, 'updateRoster').andCallThrough();
|
||||||
|
Loading…
Reference in New Issue
Block a user