diff --git a/common/static/common/js/discussion/views/discussion_topic_menu_view.js b/common/static/common/js/discussion/views/discussion_topic_menu_view.js index 5c2bd591ff..5b701822b4 100644 --- a/common/static/common/js/discussion/views/discussion_topic_menu_view.js +++ b/common/static/common/js/discussion/views/discussion_topic_menu_view.js @@ -16,7 +16,7 @@ initialize: function(options) { this.course_settings = options.course_settings; this.currentTopicId = options.topicId; - this.maxNameWidth = 100; + this.maxNameWidth = 26; _.bindAll(this, 'toggleTopicDropdown', 'handleTopicEvent', 'hideTopicDropdown', 'ignoreClick' ); @@ -90,9 +90,6 @@ this.dropdownButton.addClass('dropped'); this.topicMenu.show(); $(document.body).on('click.topicMenu', this.hideTopicDropdown); - // Set here because 1) the window might get resized and things could - // change and 2) can't set in initialize because the button is hidden - this.maxNameWidth = this.dropdownButton.width() - 40; return this; }, @@ -127,7 +124,7 @@ }, setSelectedTopicName: function(text) { - return this.selectedTopic.html(this.fitName(text)); + return this.selectedTopic.text(this.fitName(text)); }, /** * Return full name for the `topicElement` if it is passed. @@ -148,29 +145,12 @@ } }, - // @TODO move into utils.coffee - getNameWidth: function(name) { - var $test = $('
'), - width; - - $test.css({ - 'font-size': this.dropdownButton.css('font-size'), - 'opacity': 0, - 'position': 'absolute', - 'left': -1000, - 'top': -1000 - }).html(name).appendTo(document.body); - width = $test.width(); - $test.remove(); - return width; - }, - // @TODO move into utils.coffee fitName: function(name) { var ellipsisText = gettext('…'), - partialName, path, rawName; + partialName, path, rawName, concatedLength; - if (this.getNameWidth(name) < this.maxNameWidth) { + if (name.length < this.maxNameWidth) { return name; } else { path = _.map(name.split('/'), function(item){ @@ -178,15 +158,16 @@ }); while (path.length > 1) { path.shift(); - partialName = ellipsisText + ' / ' + path.join(' / '); - if (this.getNameWidth(partialName) < this.maxNameWidth) { - return partialName; + partialName = ellipsisText + '/' + path.join('/'); + if (partialName.length < this.maxNameWidth) { + return partialName; } } rawName = path[0]; name = ellipsisText + ' / ' + rawName; - while (this.getNameWidth(name) > this.maxNameWidth) { - rawName = rawName.slice(0, -1); + if (name.length > this.maxNameWidth) { + concatedLength = ellipsisText.length + ' / '.length + ellipsisText.length; + rawName = rawName.slice(0, this.maxNameWidth - concatedLength); name = ellipsisText + ' / ' + rawName + ' ' + ellipsisText; } } diff --git a/common/static/common/js/spec/discussion/view/discussion_topic_menu_view_spec.js b/common/static/common/js/spec/discussion/view/discussion_topic_menu_view_spec.js index 36a0481041..69f949367a 100644 --- a/common/static/common/js/spec/discussion/view/discussion_topic_menu_view_spec.js +++ b/common/static/common/js/spec/discussion/view/discussion_topic_menu_view_spec.js @@ -10,7 +10,7 @@ }, options); this.view = new DiscussionTopicMenuView(options); this.view.render().appendTo('#fixture-element'); - this.defaultTextWidth = this.view.getNameWidth(this.completeText); + this.defaultTextWidth = this.completeText.length; }; this.openMenu = function() { @@ -34,7 +34,13 @@ 'subcategories': { 'Basic Question Types': { 'subcategories': {}, - 'children': ['Selection From Options', 'Numerical Input'], + 'children': [ + 'Selection From Options', + 'Numerical Input', + 'Very long category name', + 'Very very very very long category name', + 'Name with HTML' + ], 'entries': { 'Selection From Options': { 'sort_key': null, @@ -45,11 +51,40 @@ 'sort_key': null, 'is_cohorted': false, 'id': 'c49f0dfb8fc94c9c8d9999cc95190c56' + }, + 'Very long category name': { + 'sort_key': null, + 'is_cohorted': false, + 'id': 'c49f0dfb8fc94c9c8d9999cc95190c59' + }, + 'Very very very very long category name': { + 'sort_key': null, + 'is_cohorted': false, + 'id': 'c49f0dfb8fc94c9c8d9999cc95190e32' + }, + 'Name with HTML': { + 'sort_key': null, + 'is_cohorted': false, + 'id': 'c49f0dfb8fc94c9c8d9999cc95190363' + } + + } + }, + 'Example Inline Discussion': { + 'subcategories': {}, + 'children': [ + 'What Are Your Goals for Creating a MOOC?', + ], + 'entries': { + 'What Are Your Goals for Creating a MOOC?': { + 'sort_key': null, + 'is_cohorted': true, + 'id': 'cba3e4cd91d0466b9ac50926e495b931' } } } }, - 'children': ['Basic Question Types'], + 'children': ['Basic Question Types', 'Example Inline Discussion'], 'entries': {} }, 'is_cohorted': true @@ -68,31 +103,38 @@ expect(this.completeText).toEqual(dropdownText); }); - it('completely show just sub-category', function() { + it('truncation happens with specific title lengths', function() { var dropdownText; this.createTopicView(); - this.view.maxNameWidth = this.defaultTextWidth - 10; - this.view.$el.find('a.topic-title').first().click(); + this.view.$el.find('a.topic-title')[2].click(); dropdownText = this.view.$el.find('.js-selected-topic').text(); - expect(dropdownText.indexOf('…')).toEqual(0); - expect(dropdownText).toContain(this.selectedOptionText); + expect(dropdownText).toEqual('…/Very long category name'); + + this.view.$el.find('a.topic-title')[5].click(); + dropdownText = this.view.$el.find('.js-selected-topic').text(); + expect(dropdownText).toEqual('… / What Are Your Goals f …'); }); - it('partially show sub-category', function() { + it('truncation happens with longer title lengths', function() { + var dropdownText; this.createTopicView(); - var parentWidth = this.view.getNameWidth(this.parentCategoryText), - dropdownText; - this.view.maxNameWidth = this.defaultTextWidth - parentWidth; - this.view.$el.find('a.topic-title').first().click(); + this.view.$el.find('a.topic-title')[3].click(); dropdownText = this.view.$el.find('.js-selected-topic').text(); - expect(dropdownText.indexOf('…')).toEqual(0); - expect(dropdownText.lastIndexOf('…')).toBeGreaterThan(0); + expect(dropdownText).toEqual('… / Very very very very l …'); + }); + + it('titles are escaped before display', function() { + var dropdownText; + this.createTopicView(); + this.view.$el.find('a.topic-title')[4].click(); + dropdownText = this.view.$el.find('.js-selected-topic').text(); + expect(dropdownText).toContain('em>'); }); it('broken span doesn\'t occur', function() { var dropdownText; this.createTopicView(); - this.view.maxNameWidth = this.view.getNameWidth(this.selectedOptionText) + 100; + this.view.maxNameWidth = this.selectedOptionText.length + 100; this.view.$el.find('a.topic-title').first().click(); dropdownText = this.view.$el.find('.js-selected-topic').text(); expect(dropdownText.indexOf('/ span>')).toEqual(-1);