diff --git a/lms/static/js/edxnotes/models/note.js b/lms/static/js/edxnotes/models/note.js
index 001f20c43d..e9748dafec 100644
--- a/lms/static/js/edxnotes/models/note.js
+++ b/lms/static/js/edxnotes/models/note.js
@@ -1,6 +1,6 @@
;(function (define) {
'use strict';
-define(['backbone', 'underscore.string'], function (Backbone) {
+define(['backbone', 'js/edxnotes/utils/utils', 'underscore.string'], function (Backbone, Utils) {
var NoteModel = Backbone.Model.extend({
defaults: {
'id': null,
@@ -42,7 +42,7 @@ define(['backbone', 'underscore.string'], function (Backbone) {
}
},
- getNoteText: function () {
+ getQuote: function () {
var message = this.get('quote');
if (!this.get('is_expanded') && this.get('show_link')) {
@@ -50,6 +50,10 @@ define(['backbone', 'underscore.string'], function (Backbone) {
}
return message;
+ },
+
+ getText: function () {
+ return Utils.nl2br(this.get('text'));
}
});
diff --git a/lms/static/js/edxnotes/utils/utils.js b/lms/static/js/edxnotes/utils/utils.js
new file mode 100644
index 0000000000..a134f4a9c8
--- /dev/null
+++ b/lms/static/js/edxnotes/utils/utils.js
@@ -0,0 +1,24 @@
+;(function (define, undefined) {
+'use strict';
+define([], function($, _) {
+ /**
+ * Replaces all newlines in a string by HTML line breaks.
+ * @param {String} str The input string.
+ * @return `String` with '
' instead all newlines (\r\n, \n\r, \n and \r).
+ * @example
+ * nl2br("This\r\nis\n\ra\nstring\r")
+ * Output:
+ * This
+ * is
+ * a
+ * string
+ */
+ var nl2br = function (str) {
+ return (str + '').replace(/(\r\n|\n\r|\r|\n)/g, '
');
+ }
+
+ return {
+ nl2br: nl2br
+ };
+});
+}).call(this, define || RequireJS.define);
diff --git a/lms/static/js/edxnotes/views/note_item.js b/lms/static/js/edxnotes/views/note_item.js
index 9488496c63..9f83a615c1 100644
--- a/lms/static/js/edxnotes/views/note_item.js
+++ b/lms/static/js/edxnotes/views/note_item.js
@@ -29,9 +29,10 @@ define([
},
getContext: function () {
- return $.extend({
- message: this.model.getNoteText()
- }, this.model.toJSON());
+ return $.extend({}, this.model.toJSON(), {
+ message: this.model.getQuote(),
+ text: this.model.getText()
+ });
},
toggleNote: function () {
diff --git a/lms/static/js/edxnotes/views/shim.js b/lms/static/js/edxnotes/views/shim.js
index a17fe606ac..b86e5cdd9e 100644
--- a/lms/static/js/edxnotes/views/shim.js
+++ b/lms/static/js/edxnotes/views/shim.js
@@ -1,6 +1,8 @@
;(function (define, undefined) {
'use strict';
-define(['jquery', 'underscore', 'annotator'], function ($, _, Annotator) {
+define([
+ 'jquery', 'underscore', 'annotator', 'js/edxnotes/utils/utils'
+], function ($, _, Annotator, Utils) {
var _t = Annotator._t;
/**
@@ -115,6 +117,36 @@ define(['jquery', 'underscore', 'annotator'], function ($, _, Annotator) {
''
].join('');
+ /**
+ * Overrides Annotator._setupViewer to add a "click" event on viewer and to
+ * improve line breaks.
+ **/
+ Annotator.prototype._setupViewer = function () {
+ var self = this;
+ this.viewer = new Annotator.Viewer({readOnly: this.options.readOnly});
+ this.viewer.element.on('click', _.bind(this.onNoteClick, this));
+ this.viewer.hide()
+ .on("edit", this.onEditAnnotation)
+ .on("delete", this.onDeleteAnnotation)
+ .addField({
+ load: function (field, annotation) {
+ if (annotation.text) {
+ $(field).html(Utils.nl2br(Annotator.Util.escape(annotation.text)));
+ } else {
+ $(field).html('' + _t('No Comment') + '');
+ self.publish('annotationViewerTextField', [field, annotation]);
+ }
+ }
+ })
+ .element.appendTo(this.wrapper).bind({
+ "mouseover": this.clearViewerHideTimer,
+ "mouseout": this.startViewerHideTimer
+ });
+ return this;
+ };
+
+ Annotator.Editor.prototype.isShown = Annotator.Viewer.prototype.isShown;
+
/**
* Modifies Annotator.onHighlightMouseover to avoid showing the viewer if the
* editor is opened.
@@ -131,17 +163,6 @@ define(['jquery', 'underscore', 'annotator'], function ($, _, Annotator) {
Annotator.prototype._setupViewer
);
- /**
- * Modifies Annotator._setupViewer to add a "click" event on viewer.
- **/
- Annotator.prototype._setupViewer = _.compose(
- function () {
- this.viewer.element.on('click', _.bind(this.onNoteClick, this));
- return this;
- },
- Annotator.prototype._setupViewer
- );
-
/**
* Modifies Annotator._setupWrapper to add a "click" event on '.annotator-hl'.
**/
diff --git a/lms/static/js/spec/edxnotes/models/note_spec.js b/lms/static/js/spec/edxnotes/models/note_spec.js
index 285bb090d9..4a491c43e5 100644
--- a/lms/static/js/spec/edxnotes/models/note_spec.js
+++ b/lms/static/js/spec/edxnotes/models/note_spec.js
@@ -5,8 +5,8 @@ define([
describe('EdxNotes NoteModel', function() {
beforeEach(function () {
this.collection = new NotesCollection([
- {quote: Helpers.LONG_TEXT},
- {quote: Helpers.SHORT_TEXT}
+ {quote: Helpers.LONG_TEXT, text: 'text\n with\r\nline\n\rbreaks \r'},
+ {quote: Helpers.SHORT_TEXT, text: 'text\n with\r\nline\n\rbreaks \r'}
]);
});
@@ -17,18 +17,23 @@ define([
expect(this.collection.at(1).get('show_link')).toBeFalsy();
});
- it('can return appropriate note text', function () {
+ it('can return appropriate `quote`', function () {
var model = this.collection.at(0);
// is_expanded = false, show_link = true
- expect(model.getNoteText()).toBe(Helpers.PRUNED_TEXT);
+ expect(model.getQuote()).toBe(Helpers.PRUNED_TEXT);
model.set('is_expanded', true);
// is_expanded = true, show_link = true
- expect(model.getNoteText()).toBe(Helpers.LONG_TEXT);
+ expect(model.getQuote()).toBe(Helpers.LONG_TEXT);
model.set('show_link', false);
model.set('is_expanded', false);
// is_expanded = false, show_link = false
- expect(model.getNoteText()).toBe(Helpers.LONG_TEXT);
+ expect(model.getQuote()).toBe(Helpers.LONG_TEXT);
+ });
+
+ it('can return appropriate `text`', function () {
+ var model = this.collection.at(0);
+ expect(model.getText()).toBe('text
with
line
breaks
');
});
});
});
diff --git a/lms/static/js/spec/edxnotes/views/shim_spec.js b/lms/static/js/spec/edxnotes/views/shim_spec.js
index f1abd7aab9..6d4335391a 100644
--- a/lms/static/js/spec/edxnotes/views/shim_spec.js
+++ b/lms/static/js/spec/edxnotes/views/shim_spec.js
@@ -135,5 +135,88 @@ define([
'click', '.annotator-hl'
);
});
+
+ describe('_setupViewer', function () {
+ var mockViewer = null;
+
+ beforeEach(function () {
+ var element = $('