diff --git a/cms/djangoapps/contentstore/views/component.py b/cms/djangoapps/contentstore/views/component.py index ed75ccd25b8f..33bac6c67c7a 100644 --- a/cms/djangoapps/contentstore/views/component.py +++ b/cms/djangoapps/contentstore/views/component.py @@ -48,7 +48,8 @@ "add-xblock-component", "add-xblock-component-button", "add-xblock-component-menu", "add-xblock-component-support-legend", "add-xblock-component-support-level", "add-xblock-component-menu-problem", "xblock-string-field-editor", "xblock-access-editor", "publish-xblock", "publish-history", - "unit-outline", "container-message", "container-access", "license-selector", + "unit-outline", "container-message", "container-access", "license-selector", "copy-clipboard-button", + "edit-title-button", ] diff --git a/cms/static/js/spec/views/modals/edit_xblock_spec.js b/cms/static/js/spec/views/modals/edit_xblock_spec.js index 8a28acab5bcb..e5331e30e486 100644 --- a/cms/static/js/spec/views/modals/edit_xblock_spec.js +++ b/cms/static/js/spec/views/modals/edit_xblock_spec.js @@ -61,7 +61,7 @@ describe('EditXBlockModal', function() { it('shows the correct title', function() { var requests = AjaxHelpers.requests(this); modal = showModal(requests, mockXBlockEditorHtml); - expect(modal.$('.modal-window-title').text()).toBe('Editing: Component'); + expect(modal.$('.modal-window-title span.modal-button-title').text()).toBe('Editing: Component'); }); it('does not show any editor mode buttons', function() { @@ -134,7 +134,7 @@ describe('EditXBlockModal', function() { it('shows the correct title', function() { var requests = AjaxHelpers.requests(this); modal = showModal(requests, mockXModuleEditorHtml); - expect(modal.$('.modal-window-title').text()).toBe('Editing: Component'); + expect(modal.$('.modal-window-title span.modal-button-title').text()).toBe('Editing: Component'); }); it('shows the correct default buttons', function() { diff --git a/cms/static/js/spec_helpers/edit_helpers.js b/cms/static/js/spec_helpers/edit_helpers.js index e46354862ea7..a9cc33445af4 100644 --- a/cms/static/js/spec_helpers/edit_helpers.js +++ b/cms/static/js/spec_helpers/edit_helpers.js @@ -90,6 +90,7 @@ installEditTemplates = function(append) { // Add templates needed by the edit XBlock modal TemplateHelpers.installTemplate('edit-xblock-modal'); TemplateHelpers.installTemplate('editor-mode-button'); + TemplateHelpers.installTemplate('edit-title-button'); // Add templates needed by the settings editor TemplateHelpers.installTemplate('metadata-editor'); diff --git a/cms/static/js/spec_helpers/modal_helpers.js b/cms/static/js/spec_helpers/modal_helpers.js index 3b6c154cb375..89b9b6b066ba 100644 --- a/cms/static/js/spec_helpers/modal_helpers.js +++ b/cms/static/js/spec_helpers/modal_helpers.js @@ -29,7 +29,7 @@ define(['jquery', 'common/js/spec_helpers/template_helpers', 'common/js/spec_hel getModalTitle = function(modal) { var modalElement = getModalElement(modal); - return modalElement.find('.modal-window-title').text(); + return modalElement.find('.modal-window-title span.modal-button-title').text(); }; isShowingModal = function(modal) { diff --git a/cms/static/js/views/modals/base_modal.js b/cms/static/js/views/modals/base_modal.js index 24f703a20261..65b7f06ae021 100644 --- a/cms/static/js/views/modals/base_modal.js +++ b/cms/static/js/views/modals/base_modal.js @@ -63,6 +63,7 @@ define(['jquery', 'underscore', 'gettext', 'js/views/baseview'], }, render: function() { + // xss-lint: disable=javascript-jquery-html this.$el.html(this.modalTemplate({ name: this.options.modalName, type: this.options.modalType, @@ -83,6 +84,7 @@ define(['jquery', 'underscore', 'gettext', 'js/views/baseview'], renderContents: function() { var contentHtml = this.getContentHtml(); + // xss-lint: disable=javascript-jquery-html this.$('.modal-content').html(contentHtml); }, @@ -146,6 +148,7 @@ define(['jquery', 'underscore', 'gettext', 'js/views/baseview'], name: name, isPrimary: isPrimary }); + // xss-lint: disable=javascript-jquery-append this.getActionBar().find('ul').append(html); }, @@ -178,8 +181,8 @@ define(['jquery', 'underscore', 'gettext', 'js/views/baseview'], modalWindow = this.$el.find(this.options.modalWindowClass); availableWidth = $(window).width(); availableHeight = $(window).height(); - maxWidth = availableWidth * 0.80; - maxHeight = availableHeight * 0.80; + maxWidth = availableWidth * 0.98; + maxHeight = availableHeight * 0.98; modalWidth = Math.min(modalWindow.outerWidth(), maxWidth); modalHeight = Math.min(modalWindow.outerHeight(), maxHeight); diff --git a/cms/static/js/views/modals/edit_xblock.js b/cms/static/js/views/modals/edit_xblock.js index af3ead91e619..661a3c090c84 100644 --- a/cms/static/js/views/modals/edit_xblock.js +++ b/cms/static/js/views/modals/edit_xblock.js @@ -11,7 +11,8 @@ define(['jquery', 'underscore', 'backbone', 'gettext', 'js/views/modals/base_mod var EditXBlockModal = BaseModal.extend({ events: _.extend({}, BaseModal.prototype.events, { 'click .action-save': 'save', - 'click .action-modes a': 'changeMode' + 'click .action-modes a': 'changeMode', + 'click .title-edit-button': 'clickTitleButton' }), options: $.extend({}, BaseModal.prototype.options, { @@ -40,6 +41,7 @@ define(['jquery', 'underscore', 'backbone', 'gettext', 'js/views/modals/base_mod this.xblockInfo = XBlockViewUtils.findXBlockInfo(xblockElement, rootXBlockInfo); this.options.modalType = this.xblockInfo.get('category'); this.editOptions = options; + this.render(); this.show(); @@ -68,6 +70,11 @@ define(['jquery', 'underscore', 'backbone', 'gettext', 'js/views/modals/base_mod }); }, + createTitleEditor: function(title) { + // xss-lint: disable=javascript-jquery-html + this.$('.modal-window-title').html(this.loadTemplate('edit-title-button')({title: title})); + }, + onDisplayXBlock: function() { var editorView = this.editorView, title = this.getTitle(), @@ -84,7 +91,7 @@ define(['jquery', 'underscore', 'backbone', 'gettext', 'js/views/modals/base_mod // Update the custom editor's title editorView.$('.component-name').text(title); } else { - this.$('.modal-window-title').text(title); + this.createTitleEditor(title); if (editorView.getDataEditor() && editorView.getMetadataEditor()) { this.addDefaultModes(); // If the plugins content element exists, add a button to reveal it. @@ -103,8 +110,6 @@ define(['jquery', 'underscore', 'backbone', 'gettext', 'js/views/modals/base_mod } this.getActionBar().show(); } - - // Resize the modal to fit the window this.resize(); }, @@ -146,7 +151,6 @@ define(['jquery', 'underscore', 'backbone', 'gettext', 'js/views/modals/base_mod }, changeMode: function(event) { - this.removeCheatsheetVisibility(); var $parent = $(event.target.parentElement), mode = $parent.data('mode'); event.preventDefault(); @@ -207,16 +211,30 @@ define(['jquery', 'underscore', 'backbone', 'gettext', 'js/views/modals/base_mod })); }, - removeCheatsheetVisibility: function() { - var $cheatsheet = $('article.simple-editor-open-ended-cheatsheet'); - if ($cheatsheet.length === 0) { - $cheatsheet = $('article.simple-editor-cheatsheet'); - } - if ($cheatsheet.hasClass('shown')) { - $cheatsheet.removeClass('shown'); - $('.modal-content').removeClass('cheatsheet-is-shown'); - } + clickTitleButton: function(event) { + var self = this, + oldTitle = this.xblockInfo.get('display_name'), + titleElt = this.$('.modal-window-title'), + $input = $(''), + changeFunc = function(evt) { + var newTitle = $(evt.target).val(); + if (oldTitle !== newTitle) { + self.xblockInfo.set('display_name', newTitle); + self.xblockInfo.save({metadata: {display_name: newTitle}}); + } + self.createTitleEditor(self.getTitle()); + return true; + }; + event.preventDefault(); + + $input.val(oldTitle); + $input.change(changeFunc).blur(changeFunc); + titleElt.html($input); // xss-lint: disable=javascript-jquery-html + $input.focus().select(); + $(event.target).remove(); + return true; } + }); return EditXBlockModal; diff --git a/cms/static/js/views/pages/container.js b/cms/static/js/views/pages/container.js index 1fc77092ba79..fd4a05d10f69 100644 --- a/cms/static/js/views/pages/container.js +++ b/cms/static/js/views/pages/container.js @@ -30,6 +30,7 @@ define(['jquery', 'underscore', 'backbone', 'gettext', 'js/views/pages/base_page view: 'container_preview', + defaultViewClass: ContainerView, // Overridable by subclasses-- determines whether the XBlock component diff --git a/cms/static/sass/elements/_modal-window.scss b/cms/static/sass/elements/_modal-window.scss index 4295148d025a..25f655257421 100644 --- a/cms/static/sass/elements/_modal-window.scss +++ b/cms/static/sass/elements/_modal-window.scss @@ -219,6 +219,11 @@ color: $blue-d4; } } + .clipboard-button { + position: absolute; + right: 30px; + bottom: 30px; + } } } @@ -248,7 +253,7 @@ // large modals - component editors and interactives // ------------------------ .modal-lg { - width: 70%; + width: 95%; min-width: ($baseline*27.5); height: auto; @@ -266,7 +271,7 @@ } .editor-modes { - width: 48%; + width: 49%; display: inline-block; @include text-align(right); @@ -378,7 +383,6 @@ } } - // MODAL TYPE: component - video modal (includes special overrides for xblock-related editing view) .modal-lg.modal-type-video { .modal-content { diff --git a/cms/templates/js/copy-clipboard-button.underscore b/cms/templates/js/copy-clipboard-button.underscore new file mode 100644 index 000000000000..6ba471365196 --- /dev/null +++ b/cms/templates/js/copy-clipboard-button.underscore @@ -0,0 +1,5 @@ + + +<%- gettext('Copy Component Location') %> + + \ No newline at end of file diff --git a/cms/templates/js/edit-title-button.underscore b/cms/templates/js/edit-title-button.underscore new file mode 100644 index 000000000000..87fcb1e16c2c --- /dev/null +++ b/cms/templates/js/edit-title-button.underscore @@ -0,0 +1 @@ + diff --git a/cms/templates/js/metadata-editor.underscore b/cms/templates/js/metadata-editor.underscore index da4e32fc73ff..67898a77b63b 100644 --- a/cms/templates/js/metadata-editor.underscore +++ b/cms/templates/js/metadata-editor.underscore @@ -3,10 +3,4 @@
' + p1 + '';
});
diff --git a/common/test/acceptance/pages/studio/problem_editor.py b/common/test/acceptance/pages/studio/problem_editor.py
index c9e4634b97b0..81d7338e3d8b 100644
--- a/common/test/acceptance/pages/studio/problem_editor.py
+++ b/common/test/acceptance/pages/studio/problem_editor.py
@@ -28,7 +28,7 @@ def set_field_val(self, field_display_name, field_value):
"""
If editing, set the value of a field.
"""
- selector = u'.xblock-studio_view li.field label:contains("{}") + input'.format(field_display_name)
+ selector = u'.metadata_edit li.field label:contains("{}") + input'.format(field_display_name)
script = "$(arguments[0]).val(arguments[1]).change();"
self.browser.execute_script(script, selector, field_value)