summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Calviño Sánchez <danxuliu@gmail.com>2018-11-27 11:40:12 +0100
committerJoas Schilling <coding@schilljs.com>2018-11-28 12:48:51 +0100
commit252c53e780a3557f073981cea78c8982f39745e5 (patch)
tree5c8910b73c6b9318bac7e99a06c7f5690ada3e08
parentda13fd1d8f493e231aa348d60124bb22baf69a3d (diff)
Move ChatView to precompiled Handlebars templates
In Nextcloud 15 the default Content Security Policy disallows unsafe eval expressions, so Handlebars templates can no longer be compiled at runtime. For the time being that default Content Security Policy was lifted for Talk so "Handlebars.compile" could still be used. However, this only applies to Talk itself; when using Talk components in other apps they must abide to the Content Security Policy of those apps. As ChatView is going to be used in the Files app it has been moved to precompiled Handlebars templates (which are still compatible with the regular Talk UI). Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
-rwxr-xr-xcompile-handlebars-templates.sh2
-rw-r--r--js/views/chatview.js57
-rw-r--r--js/views/templates.js89
-rw-r--r--js/views/templates/chatview.handlebars6
-rw-r--r--js/views/templates/chatview_add_comment.handlebars19
-rw-r--r--js/views/templates/chatview_comment.handlebars10
-rw-r--r--lib/PublicShareAuth/TemplateLoader.php1
-rw-r--r--templates/index-public.php1
-rw-r--r--templates/index.php1
9 files changed, 140 insertions, 46 deletions
diff --git a/compile-handlebars-templates.sh b/compile-handlebars-templates.sh
index 663a5bd83..632488aff 100755
--- a/compile-handlebars-templates.sh
+++ b/compile-handlebars-templates.sh
@@ -4,3 +4,5 @@
export PATH=./node_modules/.bin/:$PATH
handlebars -n OCA.VideoCalls.Admin.Templates js/admin/templates/ -f js/admin/templates.js
+
+handlebars -n OCA.SpreedMe.Views.Templates js/views/templates/ -f js/views/templates.js
diff --git a/js/views/chatview.js b/js/views/chatview.js
index eccf5f858..2a7106337 100644
--- a/js/views/chatview.js
+++ b/js/views/chatview.js
@@ -1,4 +1,4 @@
-/* global autosize, Handlebars, Marionette, moment, OC, OCA, OCP */
+/* global autosize, Marionette, moment, OC, OCA, OCP */
/**
*
@@ -21,52 +21,12 @@
*
*/
-(function(OCA, OC, OCP, Marionette, Handlebars, autosize, moment) {
+(function(OCA, OC, OCP, Marionette, autosize, moment) {
'use strict';
OCA.SpreedMe = OCA.SpreedMe || {};
OCA.SpreedMe.Views = OCA.SpreedMe.Views || {};
- var TEMPLATE =
- '<ul class="comments">' +
- '</ul>' +
- '<div class="emptycontent"><div class="icon-comment"></div>' +
- '<p>{{emptyResultLabel}}</p></div>' +
- '<div class="loading hidden" style="height: 50px"></div>';
-
- var ADD_COMMENT_TEMPLATE =
- '<div class="newCommentRow comment">' +
- ' <div class="authorRow currentUser">' +
- ' <div class="avatar" data-user-id="{{actorId}}"></div>' +
- ' {{#if actorId}}' +
- ' <div class="author">{{actorDisplayName}}</div>' +
- ' {{else}}' +
- ' <div class="guest-name"></div>' +
- ' {{/if}}' +
- ' </div>' +
- ' <form class="newCommentForm">' +
- ' <div contentEditable="true" class="message" data-placeholder="{{newMessagePlaceholder}}">{{message}}</div>' +
- ' <input class="submit icon-confirm has-tooltip" type="submit" value="" title="{{submitText}}"/>' +
- ' <div class="submitLoading icon-loading-small hidden"></div>'+
- ' {{#if actorId}}' +
- ' <button class="share icon-add has-tooltip" title="{{shareText}}"></button>' +
- ' <div class="shareLoading icon-loading-small hidden"></div>'+
- ' {{/if}}' +
- ' </form>' +
- '</div>';
-
- var COMMENT_TEMPLATE =
- '<li class="comment{{#if isNotSystemMessage}}{{else}} systemMessage{{/if}}" data-id="{{id}}">' +
- ' <div class="authorRow{{#if isUserAuthor}} currentUser{{/if}}{{#if isGuest}} guestUser{{/if}}">' +
- ' {{#if isNotSystemMessage}}' +
- ' <div class="avatar" data-user-id="{{#if isGuest}}{{else}}{{actorId}}{{/if}}" data-user-display-name="{{actorDisplayName}}"> </div>' +
- ' <div class="author">{{actorDisplayName}}</div>' +
- ' {{/if}}' +
- ' <div class="date has-tooltip{{#if relativeDate}} live-relative-timestamp{{/if}}" data-timestamp="{{timestamp}}" title="{{altDate}}">{{date}}</div>' +
- ' </div>' +
- ' <div class="message">{{{formattedMessage}}}</div>' +
- '</li>';
-
var ChatView = Marionette.View.extend({
groupedMessages: 0,
@@ -201,14 +161,19 @@
document.execCommand('insertText', false, text);
},
- template: Handlebars.compile(TEMPLATE),
+ template: function(context) {
+ // OCA.SpreedMe.Views.Templates may not have been initialized when
+ // this view is initialized, so the template can not be directly
+ // assigned.
+ return OCA.SpreedMe.Views.Templates['chatview'](context);
+ },
templateContext: {
emptyResultLabel: t('spreed', 'No messages yet, start the conversation!')
},
addCommentTemplate: function(params) {
if (!this._addCommentTemplate) {
- this._addCommentTemplate = Handlebars.compile(ADD_COMMENT_TEMPLATE);
+ this._addCommentTemplate = OCA.SpreedMe.Views.Templates['chatview_add_comment'];
}
return this._addCommentTemplate(_.extend({
@@ -222,7 +187,7 @@
commentTemplate: function(params) {
if (!this._commentTemplate) {
- this._commentTemplate = Handlebars.compile(COMMENT_TEMPLATE);
+ this._commentTemplate = OCA.SpreedMe.Views.Templates['chatview_comment'];
}
params = _.extend({
@@ -756,4 +721,4 @@
OCA.SpreedMe.Views.ChatView = ChatView;
-})(OCA, OC, OCP, Marionette, Handlebars, autosize, moment);
+})(OCA, OC, OCP, Marionette, autosize, moment);
diff --git a/js/views/templates.js b/js/views/templates.js
new file mode 100644
index 000000000..ee6175bc1
--- /dev/null
+++ b/js/views/templates.js
@@ -0,0 +1,89 @@
+(function() {
+ var template = Handlebars.template, templates = OCA.SpreedMe.Views.Templates = OCA.SpreedMe.Views.Templates || {};
+templates['chatview'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+ var helper;
+
+ return "<ul class=\"comments\"></ul>\n<div class=\"emptycontent\">\n <div class=\"icon-comment\"></div>\n <p>"
+ + container.escapeExpression(((helper = (helper = helpers.emptyResultLabel || (depth0 != null ? depth0.emptyResultLabel : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"emptyResultLabel","hash":{},"data":data}) : helper)))
+ + "</p>\n</div>\n<div class=\"loading hidden\" style=\"height: 50px\"></div>\n";
+},"useData":true});
+templates['chatview_add_comment'] = template({"1":function(container,depth0,helpers,partials,data) {
+ var helper;
+
+ return " <div class=\"author\">"
+ + container.escapeExpression(((helper = (helper = helpers.actorDisplayName || (depth0 != null ? depth0.actorDisplayName : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"actorDisplayName","hash":{},"data":data}) : helper)))
+ + "</div>\n";
+},"3":function(container,depth0,helpers,partials,data) {
+ return " <div class=\"guest-name\"></div>\n";
+},"5":function(container,depth0,helpers,partials,data) {
+ var helper;
+
+ return " <button class=\"share icon-add has-tooltip\" title=\""
+ + container.escapeExpression(((helper = (helper = helpers.shareText || (depth0 != null ? depth0.shareText : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"shareText","hash":{},"data":data}) : helper)))
+ + "\"></button>\n <div class=\"shareLoading icon-loading-small hidden\"></div>\n";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+ var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+
+ return "<div class=\"newCommentRow comment\">\n <div class=\"authorRow currentUser\">\n <div class=\"avatar\" data-user-id=\""
+ + alias4(((helper = (helper = helpers.actorId || (depth0 != null ? depth0.actorId : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"actorId","hash":{},"data":data}) : helper)))
+ + "\"></div>\n"
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.actorId : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(3, data, 0),"data":data})) != null ? stack1 : "")
+ + " </div>\n <form class=\"newCommentForm\">\n <div contentEditable=\"true\" class=\"message\" data-placeholder=\""
+ + alias4(((helper = (helper = helpers.newMessagePlaceholder || (depth0 != null ? depth0.newMessagePlaceholder : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"newMessagePlaceholder","hash":{},"data":data}) : helper)))
+ + "\">"
+ + alias4(((helper = (helper = helpers.message || (depth0 != null ? depth0.message : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"message","hash":{},"data":data}) : helper)))
+ + "</div>\n <input class=\"submit icon-confirm has-tooltip\" type=\"submit\" value=\"\" title=\""
+ + alias4(((helper = (helper = helpers.submitText || (depth0 != null ? depth0.submitText : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"submitText","hash":{},"data":data}) : helper)))
+ + "\"/>\n <div class=\"submitLoading icon-loading-small hidden\"></div>\n"
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.actorId : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + " </form>\n</div>\n";
+},"useData":true});
+templates['chatview_comment'] = template({"1":function(container,depth0,helpers,partials,data) {
+ return "";
+},"3":function(container,depth0,helpers,partials,data) {
+ return " systemMessage";
+},"5":function(container,depth0,helpers,partials,data) {
+ return " currentUser";
+},"7":function(container,depth0,helpers,partials,data) {
+ return " guestUser";
+},"9":function(container,depth0,helpers,partials,data) {
+ var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+
+ return " <div class=\"avatar\" data-user-id=\""
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isGuest : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(10, data, 0),"data":data})) != null ? stack1 : "")
+ + "\" data-user-display-name=\""
+ + alias4(((helper = (helper = helpers.actorDisplayName || (depth0 != null ? depth0.actorDisplayName : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"actorDisplayName","hash":{},"data":data}) : helper)))
+ + "\"></div>\n <div class=\"author\">"
+ + alias4(((helper = (helper = helpers.actorDisplayName || (depth0 != null ? depth0.actorDisplayName : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"actorDisplayName","hash":{},"data":data}) : helper)))
+ + "</div>\n";
+},"10":function(container,depth0,helpers,partials,data) {
+ var helper;
+
+ return container.escapeExpression(((helper = (helper = helpers.actorId || (depth0 != null ? depth0.actorId : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"actorId","hash":{},"data":data}) : helper)));
+},"12":function(container,depth0,helpers,partials,data) {
+ return " live-relative-timestamp";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+ var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+
+ return "<li class=\"comment"
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isNotSystemMessage : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(3, data, 0),"data":data})) != null ? stack1 : "")
+ + "\" data-id=\""
+ + alias4(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"id","hash":{},"data":data}) : helper)))
+ + "\">\n <div class=\"authorRow"
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isUserAuthor : depth0),{"name":"if","hash":{},"fn":container.program(5, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isGuest : depth0),{"name":"if","hash":{},"fn":container.program(7, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + "\">\n"
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.isNotSystemMessage : depth0),{"name":"if","hash":{},"fn":container.program(9, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + " <div class=\"date has-tooltip"
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.relativeDate : depth0),{"name":"if","hash":{},"fn":container.program(12, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + "\" data-timestamp=\""
+ + alias4(((helper = (helper = helpers.timestamp || (depth0 != null ? depth0.timestamp : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"timestamp","hash":{},"data":data}) : helper)))
+ + "\" title=\""
+ + alias4(((helper = (helper = helpers.altDate || (depth0 != null ? depth0.altDate : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"altDate","hash":{},"data":data}) : helper)))
+ + "\">"
+ + alias4(((helper = (helper = helpers.date || (depth0 != null ? depth0.date : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"date","hash":{},"data":data}) : helper)))
+ + "</div>\n </div>\n <div class=\"message\">"
+ + ((stack1 = ((helper = (helper = helpers.formattedMessage || (depth0 != null ? depth0.formattedMessage : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"formattedMessage","hash":{},"data":data}) : helper))) != null ? stack1 : "")
+ + "</div>\n</li>\n";
+},"useData":true});
+})(); \ No newline at end of file
diff --git a/js/views/templates/chatview.handlebars b/js/views/templates/chatview.handlebars
new file mode 100644
index 000000000..a21321214
--- /dev/null
+++ b/js/views/templates/chatview.handlebars
@@ -0,0 +1,6 @@
+<ul class="comments"></ul>
+<div class="emptycontent">
+ <div class="icon-comment"></div>
+ <p>{{emptyResultLabel}}</p>
+</div>
+<div class="loading hidden" style="height: 50px"></div>
diff --git a/js/views/templates/chatview_add_comment.handlebars b/js/views/templates/chatview_add_comment.handlebars
new file mode 100644
index 000000000..4af7ad0a8
--- /dev/null
+++ b/js/views/templates/chatview_add_comment.handlebars
@@ -0,0 +1,19 @@
+<div class="newCommentRow comment">
+ <div class="authorRow currentUser">
+ <div class="avatar" data-user-id="{{actorId}}"></div>
+ {{#if actorId}}
+ <div class="author">{{actorDisplayName}}</div>
+ {{else}}
+ <div class="guest-name"></div>
+ {{/if}}
+ </div>
+ <form class="newCommentForm">
+ <div contentEditable="true" class="message" data-placeholder="{{newMessagePlaceholder}}">{{message}}</div>
+ <input class="submit icon-confirm has-tooltip" type="submit" value="" title="{{submitText}}"/>
+ <div class="submitLoading icon-loading-small hidden"></div>
+ {{#if actorId}}
+ <button class="share icon-add has-tooltip" title="{{shareText}}"></button>
+ <div class="shareLoading icon-loading-small hidden"></div>
+ {{/if}}
+ </form>
+</div>
diff --git a/js/views/templates/chatview_comment.handlebars b/js/views/templates/chatview_comment.handlebars
new file mode 100644
index 000000000..ef9d345b9
--- /dev/null
+++ b/js/views/templates/chatview_comment.handlebars
@@ -0,0 +1,10 @@
+<li class="comment{{#if isNotSystemMessage}}{{else}} systemMessage{{/if}}" data-id="{{id}}">
+ <div class="authorRow{{#if isUserAuthor}} currentUser{{/if}}{{#if isGuest}} guestUser{{/if}}">
+ {{#if isNotSystemMessage}}
+ <div class="avatar" data-user-id="{{#if isGuest}}{{else}}{{actorId}}{{/if}}" data-user-display-name="{{actorDisplayName}}"></div>
+ <div class="author">{{actorDisplayName}}</div>
+ {{/if}}
+ <div class="date has-tooltip{{#if relativeDate}} live-relative-timestamp{{/if}}" data-timestamp="{{timestamp}}" title="{{altDate}}">{{date}}</div>
+ </div>
+ <div class="message">{{{formattedMessage}}}</div>
+</li>
diff --git a/lib/PublicShareAuth/TemplateLoader.php b/lib/PublicShareAuth/TemplateLoader.php
index 52f4d0ddd..2052f3195 100644
--- a/lib/PublicShareAuth/TemplateLoader.php
+++ b/lib/PublicShareAuth/TemplateLoader.php
@@ -97,6 +97,7 @@ class TemplateLoader {
Util::addScript('spreed', 'views/roomlistview');
Util::addScript('spreed', 'views/sidebarview');
Util::addScript('spreed', 'views/tabview');
+ Util::addScript('spreed', 'views/templates');
Util::addScript('spreed', 'views/virtuallist');
Util::addScript('spreed', 'richobjectstringparser');
Util::addScript('spreed', 'simplewebrtc');
diff --git a/templates/index-public.php b/templates/index-public.php
index f85a7326f..799b54bd8 100644
--- a/templates/index-public.php
+++ b/templates/index-public.php
@@ -32,6 +32,7 @@ script(
'views/roomlistview',
'views/sidebarview',
'views/tabview',
+ 'views/templates',
'views/virtuallist',
'richobjectstringparser',
'simplewebrtc',
diff --git a/templates/index.php b/templates/index.php
index 0263073cd..a3dbb5290 100644
--- a/templates/index.php
+++ b/templates/index.php
@@ -31,6 +31,7 @@ script(
'views/roomlistview',
'views/sidebarview',
'views/tabview',
+ 'views/templates',
'views/virtuallist',
'richobjectstringparser',
'simplewebrtc',