diff --git a/conversation.html b/conversation.html index 390e9747e..d15220689 100644 --- a/conversation.html +++ b/conversation.html @@ -134,6 +134,7 @@ + diff --git a/index.html b/index.html index b54bae4db..8d57e41c6 100644 --- a/index.html +++ b/index.html @@ -88,6 +88,7 @@ + diff --git a/js/views/attachment_preview_view.js b/js/views/attachment_preview_view.js index bfbd98626..21511d427 100644 --- a/js/views/attachment_preview_view.js +++ b/js/views/attachment_preview_view.js @@ -17,15 +17,11 @@ var Whisper = Whisper || {}; (function () { 'use strict'; - Whisper.AttachmentPreviewView = Backbone.View.extend({ + Whisper.AttachmentPreviewView = Whisper.View.extend({ className: 'attachment-preview', - initialize: function() { - this.template = $('#attachment-preview').html(); - Mustache.parse(this.template); - }, - render: function() { - this.$el.html(Mustache.render(this.template, {source: this.src})); - return this; + template: $('#attachment-preview').html(), + attributes: function() { + return {source: this.src}; } }); })(); diff --git a/js/views/conversation_list_item_view.js b/js/views/conversation_list_item_view.js index b3130a1c5..b49497709 100644 --- a/js/views/conversation_list_item_view.js +++ b/js/views/conversation_list_item_view.js @@ -20,17 +20,15 @@ var Whisper = Whisper || {}; 'use strict'; // list of conversations, showing user/group and last message sent - Whisper.ConversationListItemView = Backbone.View.extend({ + Whisper.ConversationListItemView = Whisper.View.extend({ tagName: 'div', className: 'contact', events: { 'click': 'select' }, + template: $('#contact').html(), initialize: function() { - this.template = $('#contact').html(); - Mustache.parse(this.template); - this.listenTo(this.model, 'change', this.render); // auto update this.listenTo(this.model, 'destroy', this.remove); // auto update }, diff --git a/js/views/conversation_view.js b/js/views/conversation_view.js index 33ffd9efb..ea1cf4b2e 100644 --- a/js/views/conversation_view.js +++ b/js/views/conversation_view.js @@ -17,18 +17,18 @@ 'use strict'; window.Whisper = window.Whisper || {}; - Whisper.ConversationView = Backbone.View.extend({ + Whisper.ConversationView = Whisper.View.extend({ className: function() { return [ 'conversation', this.model.get('type') ].join(' '); }, + template: $('#conversation').html(), + attributes: function() { + return { group: this.model.get('type') === 'group' }; + }, initialize: function() { - this.listenTo(this.model, 'destroy', this.stopListening); // auto update - this.template = $('#conversation').html(); - Mustache.parse(this.template); + this.listenTo(this.model, 'destroy', this.stopListening); - this.$el.html(Mustache.render(this.template, - { group: this.model.get('type') === 'group' } - )); + this.render(); this.fileInput = new Whisper.FileInputView({ el: this.$el.find('.attachments') diff --git a/js/views/key_verification_view.js b/js/views/key_verification_view.js index c500eae64..fd98a7df2 100644 --- a/js/views/key_verification_view.js +++ b/js/views/key_verification_view.js @@ -18,12 +18,9 @@ window.Whisper = window.Whisper || {}; - Whisper.KeyVerificationView = Backbone.View.extend({ + Whisper.KeyVerificationView = Whisper.View.extend({ className: 'key-verification', - initialize: function(options) { - this.template = $('#key-verification').html(); - Mustache.parse(this.template); - }, + template: $('#key-verification').html(), events: { 'click .back': 'goBack' }, @@ -37,12 +34,11 @@ }); }, - render: function() { - this.$el.html(Mustache.render(this.template, { + attributes: function() { + return { your_key: this.splitKey(this.model.your_key), their_key: this.splitKey(this.model.their_key) - })); - return this; + }; } }); })(); diff --git a/js/views/message_detail_view.js b/js/views/message_detail_view.js index d52fee1f3..457c5f632 100644 --- a/js/views/message_detail_view.js +++ b/js/views/message_detail_view.js @@ -18,11 +18,10 @@ window.Whisper = window.Whisper || {}; - Whisper.MessageDetailView = Backbone.View.extend({ + Whisper.MessageDetailView = Whisper.View.extend({ className: 'message-detail', + template: $('#message-detail').html(), initialize: function(options) { - this.template = $('#message-detail').html(); - Mustache.parse(this.template); this.view = new Whisper.MessageView({model: this.model}); this.conversation = options.conversation; }, diff --git a/js/views/message_view.js b/js/views/message_view.js index 5a170281b..95bd0d0dc 100644 --- a/js/views/message_view.js +++ b/js/views/message_view.js @@ -33,12 +33,9 @@ }); - var ContentMessageView = Backbone.View.extend({ + var ContentMessageView = Whisper.View.extend({ tagName: 'div', - initialize: function() { - this.template = $('#message').html(); - Mustache.parse(this.template); - }, + template: $('#message').html(), className: function() { if (this.model.get('delivered')) { return 'delivered'; } }, diff --git a/js/views/new_conversation_view.js b/js/views/new_conversation_view.js index 1add78a57..45b126880 100644 --- a/js/views/new_conversation_view.js +++ b/js/views/new_conversation_view.js @@ -30,16 +30,14 @@ var Whisper = Whisper || {}; model: Whisper.Conversation }); - Whisper.ContactPillView = Backbone.View.extend({ + Whisper.ContactPillView = Whisper.View.extend({ tagName: 'span', className: 'recipient', events: { 'click .remove': 'removeModel' }, + template: $('#contact_pill').html(), initialize: function() { - this.template = $('#contact_pill').html(); - Mustache.parse(this.template); - var error = this.model.validate(this.model.attributes); if (error) { this.$el.addClass('error'); @@ -49,11 +47,8 @@ var Whisper = Whisper || {}; this.$el.trigger('remove', {modelId: this.model.id}); this.remove(); }, - render: function() { - this.$el.html( - Mustache.render(this.template, { name: this.model.getTitle() }) - ); - return this; + attributes: function() { + return { name: this.model.getTitle() }; } }); @@ -61,12 +56,11 @@ var Whisper = Whisper || {}; itemView: Whisper.ContactPillView }); - Whisper.NewConversationView = Backbone.View.extend({ + Whisper.NewConversationView = Whisper.View.extend({ className: 'new-conversation', + template: $('#new-conversation').html(), initialize: function() { - this.template = $('#new-conversation').html(); - Mustache.parse(this.template); - this.$el.html($(Mustache.render(this.template))); + this.render(); this.$group_update = this.$el.find('.new-group-update-form'); this.$buttons = this.$el.find('.buttons'); this.$input = this.$el.find('input.new-message'); diff --git a/js/views/new_group_update_view.js b/js/views/new_group_update_view.js index 40720c8df..2440c631b 100644 --- a/js/views/new_group_update_view.js +++ b/js/views/new_group_update_view.js @@ -18,16 +18,13 @@ window.Whisper = window.Whisper || {}; - Whisper.NewGroupUpdateView = Backbone.View.extend({ + Whisper.NewGroupUpdateView = Whisper.View.extend({ tagName: "div", className: "new-group-update-form", + template: $('#new-group-update-form').html(), initialize: function(options) { if (this.$el.html().length === 0) { - this.template = $('#new-group-update-form').html(); - Mustache.parse(this.template); - this.$el.html( - Mustache.render(this.template, this.model.attributes) - ); + this.render(); } this.avatarInput = new Whisper.FileInputView({ el: this.$el.find('.group-avatar') diff --git a/js/views/phone-input-view.js b/js/views/phone-input-view.js index 867ae4853..46b9fa773 100644 --- a/js/views/phone-input-view.js +++ b/js/views/phone-input-view.js @@ -17,12 +17,11 @@ var Whisper = Whisper || {}; (function () { 'use strict'; - Whisper.PhoneInputView = Backbone.View.extend({ + Whisper.PhoneInputView = Whisper.View.extend({ tagName: 'div', className: 'phone-input', + template: $('#phone-number').html(), initialize: function() { - this.template = $('#phone-number').html(); - Mustache.parse(this.template); this.render(); }, diff --git a/js/views/toast_view.js b/js/views/toast_view.js index cc842c1a5..eb2098824 100644 --- a/js/views/toast_view.js +++ b/js/views/toast_view.js @@ -17,10 +17,9 @@ var Whisper = Whisper || {}; (function () { 'use strict'; - Whisper.ToastView = Backbone.View.extend({ + Whisper.ToastView = Whisper.View.extend({ className: 'toast', initialize: function() { - Mustache.parse(this.template); this.$el.hide(); }, diff --git a/js/views/whisper_view.js b/js/views/whisper_view.js new file mode 100644 index 000000000..9f49a1dc8 --- /dev/null +++ b/js/views/whisper_view.js @@ -0,0 +1,35 @@ +/* vim: ts=4:sw=4:expandtab + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +(function () { + 'use strict'; + window.Whisper = window.Whisper || {}; + + Whisper.View = Backbone.View.extend({ + constructor: function() { + Backbone.View.apply(this, arguments); + Mustache.parse(_.result(this, 'template')); + }, + attributes: function() { + return _.result(this.model, 'attributes', {}); + }, + render: function() { + var attrs = _.result(this, 'attributes', {}); + var template = _.result(this, 'template', ''); + this.$el.html(Mustache.render(template, attrs)); + return this; + } + }); +})(); diff --git a/options.html b/options.html index 672ab6508..d394801de 100644 --- a/options.html +++ b/options.html @@ -102,6 +102,7 @@ + diff --git a/test/index.html b/test/index.html index 3137d847f..a0da11954 100644 --- a/test/index.html +++ b/test/index.html @@ -129,6 +129,7 @@ + @@ -139,6 +140,7 @@ + diff --git a/test/views/whisper_view_test.js b/test/views/whisper_view_test.js new file mode 100644 index 000000000..0676a0b9c --- /dev/null +++ b/test/views/whisper_view_test.js @@ -0,0 +1,34 @@ +describe('Whisper.View', function() { + it('renders a template with attributes', function() { + var viewClass = Whisper.View.extend({ + template: '
{{ variable }}
', + attributes: { + variable: 'value' + } + }); + + var view = new viewClass(); + view.render(); + assert.strictEqual(view.$el.html(), '
value
'); + }); + it('renders a template with no attributes', function() { + var viewClass = Whisper.View.extend({ + template: '
static text
' + }); + + var view = new viewClass(); + view.render(); + assert.strictEqual(view.$el.html(), '
static text
'); + }); + it('renders a template function with attributes function', function() { + var viewClass = Whisper.View.extend({ + template: function() { return '
{{ variable }}
'; }, + attributes: function() { + return { variable: 'value' }; + } + }); + var view = new viewClass(); + view.render(); + assert.strictEqual(view.$el.html(), '
value
'); + }); +});