Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [FC-0070] add events and style for rendering Split xblock in chromeless template #35813

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions cms/static/images/advanced-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions cms/static/images/drag-and-drop-v2-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions cms/static/images/itembank-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions cms/static/images/library-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions cms/static/images/library_v2-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions cms/static/images/openassessment-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions cms/static/images/problem-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions cms/static/images/text-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions cms/static/images/video-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 28 additions & 1 deletion cms/static/js/views/components/add_xblock.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,37 @@ function($, _, gettext, BaseView, ViewUtils, AddXBlockButton, AddXBlockMenu, Add
},

showComponentTemplates: function(event) {
var type;
var type, parentLocator, model;
event.preventDefault();
event.stopPropagation();

type = $(event.currentTarget).data('type');
parentLocator = $(event.currentTarget).closest('.xblock[data-usage-id]').data('usage-id');
model = this.collection.models.find(function(item) { return item.type === type; }) || {};

try {
if (this.options.isIframeEmbed) {
window.parent.postMessage(
{
type: 'showComponentTemplates',
payload: {
type: type,
parentLocator: parentLocator,
model: {
type: model.type,
display_name: model.display_name,
templates: model.templates,
support_legend: model.support_legend,
},
}
}, document.referrer
);
}
return true;
} catch (e) {
console.error(e);
}

this.$('.new-component').slideUp(250);
this.$('.new-component-' + type).slideDown(250);
this.$('.new-component-' + type + ' div').focus();
Expand Down
183 changes: 88 additions & 95 deletions cms/static/js/views/pages/container.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ function($, _, Backbone, gettext, BasePage,
initialize: function(options) {
BasePage.prototype.initialize.call(this, options);
this.viewClass = options.viewClass || this.defaultViewClass;
this.isLibraryPage = (this.model.attributes.category === 'library');
this.isLibraryContentPage = (this.model.attributes.category === 'library_content');
this.isLibraryPage = this.model.attributes.category === 'library';
this.isLibraryContentPage = this.model.attributes.category === 'library_content';
this.isSplitTestContentPage = this.model.attributes.category === 'split_test';
this.nameEditor = new XBlockStringFieldEditor({
el: this.$('.wrapper-xblock-field'),
model: this.model
Expand Down Expand Up @@ -173,6 +174,17 @@ function($, _, Backbone, gettext, BasePage,
this.listenTo(Backbone, 'move:onXBlockMoved', this.onXBlockMoved);
},

postMessageToParent: function(body, callbackFn = null) {
try {
window.parent.postMessage(body, document.referrer);
if (callbackFn) {
callbackFn();
}
} catch (e) {
console.error('Failed to post message:', e);
}
},

getViewParameters: function() {
return {
el: this.$('.wrapper-xblock'),
Expand Down Expand Up @@ -237,18 +249,14 @@ function($, _, Backbone, gettext, BasePage,
const scrollOffset = scrollOffsetString ? parseInt(scrollOffsetString, 10) : 0;

if (scrollOffset) {
try {
window.parent.postMessage(
{
type: 'scrollToXBlock',
message: 'Scroll to XBlock',
payload: { scrollOffset }
}, document.referrer
);
localStorage.removeItem('modalEditLastYPosition');
} catch (e) {
console.error(e);
}
self.postMessageToParent(
{
type: 'scrollToXBlock',
message: 'Scroll to XBlock',
payload: { scrollOffset }
},
() => localStorage.removeItem('modalEditLastYPosition')
);
}
}
},
Expand All @@ -272,13 +280,14 @@ function($, _, Backbone, gettext, BasePage,

renderAddXBlockComponents: function() {
var self = this;
if (self.options.canEdit && !self.options.isIframeEmbed) {
if (self.options.canEdit && (!self.options.isIframeEmbed || self.isSplitTestContentPage)) {
this.$('.add-xblock-component').each(function(index, element) {
var component = new AddXBlockComponent({
el: element,
createComponent: _.bind(self.createComponent, self),
collection: self.options.templates,
libraryContentPickerUrl: self.options.libraryContentPickerUrl,
isIframeEmbed: self.options.isIframeEmbed,
});
component.render();
});
Expand All @@ -288,7 +297,7 @@ function($, _, Backbone, gettext, BasePage,
},

initializePasteButton() {
if (this.options.canEdit && !this.options.isIframeEmbed) {
if (this.options.canEdit && (!this.options.isIframeEmbed || this.isSplitTestContentPage)) {
// We should have the user's clipboard status.
const data = this.options.clipboardData;
this.refreshPasteButton(data);
Expand All @@ -305,7 +314,7 @@ function($, _, Backbone, gettext, BasePage,
refreshPasteButton(data) {
// Do not perform any changes on paste button since they are not
// rendered on Library or LibraryContent pages
if (!this.isLibraryPage && !this.isLibraryContentPage && !this.options.isIframeEmbed) {
if (!this.isLibraryPage && !this.isLibraryContentPage && (!this.options.isIframeEmbed || this.isSplitTestContentPage)) {
// 'data' is the same data returned by the "get clipboard status" API endpoint
// i.e. /api/content-staging/v1/clipboard/
if (this.options.canEdit && data.content) {
Expand Down Expand Up @@ -340,17 +349,11 @@ function($, _, Backbone, gettext, BasePage,
/** The user has clicked on the "Paste Component button" */
pasteComponent(event) {
event.preventDefault();
try {
if (this.options.isIframeEmbed) {
window.parent.postMessage(
{
type: 'pasteComponent',
payload: {}
}, document.referrer
);
}
} catch (e) {
console.error(e);
if (this.options.isIframeEmbed) {
this.postMessageToParent({
type: 'pasteComponent',
payload: {},
});
}
// Get the ID of the container (usually a unit/vertical) that we're pasting into:
const parentElement = this.findXBlockElement(event.target);
Expand All @@ -375,6 +378,13 @@ function($, _, Backbone, gettext, BasePage,
placeholderElement.remove();
});
}).done((data) => {
if (this.options.isIframeEmbed) {
this.postMessageToParent({
type: 'hideProcessingNotification',
message: 'Hide processing notification',
payload: {},
});
}
const {
conflicting_files: conflictingFiles,
error_files: errorFiles,
Expand Down Expand Up @@ -646,17 +656,11 @@ function($, _, Backbone, gettext, BasePage,
subMenu.classList.toggle('is-shown');

if (!subMenu.classList.contains('is-shown') && this.options.isIframeEmbed) {
try {
window.parent.postMessage(
{
type: 'toggleCourseXBlockDropdown',
message: 'Adjust the height of the dropdown menu',
payload: { courseXBlockDropdownHeight: 0 }
}, document.referrer
);
} catch (error) {
console.error(error);
}
this.postMessageToParent({
type: 'toggleCourseXBlockDropdown',
message: 'Adjust the height of the dropdown menu',
payload: { courseXBlockDropdownHeight: 0 }
});
}

// Calculate the viewport height and the dropdown menu height.
Expand All @@ -668,33 +672,21 @@ function($, _, Backbone, gettext, BasePage,

if (courseUnitXBlockIframeHeight < courseXBlockDropdownHeight) {
// If the dropdown menu is taller than the iframe, adjust the height of the dropdown menu.
try {
window.parent.postMessage(
{
type: 'toggleCourseXBlockDropdown',
message: 'Adjust the height of the dropdown menu',
payload: { courseXBlockDropdownHeight },
}, document.referrer
);
} catch (error) {
console.error(error);
}
this.postMessageToParent({
type: 'toggleCourseXBlockDropdown',
message: 'Adjust the height of the dropdown menu',
payload: { courseXBlockDropdownHeight },
});
} else if ((courseXBlockDropdownHeight + clickYPosition) > courseUnitXBlockIframeHeight) {
if (courseXBlockDropdownHeight > courseUnitXBlockIframeHeight / 2) {
// If the dropdown menu is taller than half the iframe, send a message to adjust its height.
try {
window.parent.postMessage(
{
type: 'toggleCourseXBlockDropdown',
message: 'Adjust the height of the dropdown menu',
payload: {
courseXBlockDropdownHeight: courseXBlockDropdownHeight / 2,
},
}, document.referrer
);
} catch (error) {
console.error(error);
}
this.postMessageToParent({
type: 'toggleCourseXBlockDropdown',
message: 'Adjust the height of the dropdown menu',
payload: {
courseXBlockDropdownHeight: courseXBlockDropdownHeight / 2,
},
});
} else {
// Move the dropdown menu upward to prevent it from overflowing out of the viewport.
if (this.options.isIframeEmbed) {
Expand All @@ -719,17 +711,11 @@ function($, _, Backbone, gettext, BasePage,
},

openManageTags: function(event) {
try {
if (this.options.isIframeEmbed) {
window.parent.postMessage(
{
type: 'openManageTags',
payload: {}
}, document.referrer
);
}
} catch (e) {
console.error(e);
if (this.options.isIframeEmbed) {
this.postMessageToParent({
type: 'openManageTags',
payload: {},
});
}
const taxonomyTagsWidgetUrl = this.model.get('taxonomy_tags_widget_url');
const contentId = this.findXBlockElement(event.target).data('locator');
Expand Down Expand Up @@ -909,15 +895,12 @@ function($, _, Backbone, gettext, BasePage,
this.deleteComponent(this.findXBlockElement(event.target));
},

createPlaceholderElement: function() {
return $('<div/>', {class: 'studio-xblock-wrapper'});
},

createComponent: function(template, target, iframeMessageData) {
// A placeholder element is created in the correct location for the new xblock
// and then onNewXBlock will replace it with a rendering of the xblock. Note that
// for xblocks that can't be replaced inline, the entire parent will be refreshed.
var parentElement = this.findXBlockElement(target),
self = this,
parentLocator = parentElement.data('locator'),
buttonPanel = target?.closest('.add-xblock-component'),
listPanel = buttonPanel?.prev(),
Expand All @@ -929,7 +912,7 @@ function($, _, Backbone, gettext, BasePage,
placeholderElement,
$container;

if (this.options.isIframeEmbed) {
if (this.options.isIframeEmbed && !this.isSplitTestContentPage) {
$container = $('ol.reorderable-container.ui-sortable');
scrollOffset = 0;
} else {
Expand All @@ -939,14 +922,31 @@ function($, _, Backbone, gettext, BasePage,

placeholderElement = $placeholderEl.appendTo($container);

if (this.options.isIframeEmbed) {
if (iframeMessageData.payload.data && iframeMessageData.type === 'addXBlock') {
return this.onNewXBlock(placeholderElement, scrollOffset, false, iframeMessageData.payload.data);
}
if (this.options.isIframeEmbed && !this.isSplitTestContentPage) {
if (iframeMessageData.payload.data && iframeMessageData.type === 'addXBlock') {
return this.onNewXBlock(placeholderElement, scrollOffset, false, iframeMessageData.payload.data);
}
}

if (this.options.isIframeEmbed && this.isSplitTestContentPage) {
this.postMessageToParent({
type: 'addNewComponent',
message: 'Add new XBlock',
payload: {},
});
}

return $.postJSON(this.getURLRoot() + '/', requestData,
_.bind(this.onNewXBlock, this, placeholderElement, scrollOffset, false))
.success(function () {
if (self.options.isIframeEmbed && self.isSplitTestContentPage) {
self.postMessageToParent({
type: 'hideProcessingNotification',
message: 'Hide processing notification',
payload: {}
});
}
})
.fail(function() {
// Remove the placeholder if the update failed
placeholderElement.remove();
Expand All @@ -966,17 +966,11 @@ function($, _, Backbone, gettext, BasePage,
placeholderElement = $placeholderEl.insertAfter(xblockElement);

if (this.options.isIframeEmbed) {
try {
window.parent.postMessage(
{
type: 'scrollToXBlock',
message: 'Scroll to XBlock',
payload: { scrollOffset: xblockElement.height() }
}, document.referrer
);
} catch (e) {
console.error(e);
}
this.postMessageToParent({
type: 'scrollToXBlock',
message: 'Scroll to XBlock',
payload: { scrollOffset: xblockElement.height() }
});

const messageHandler = ({ data }) => {
if (data && data.type === 'completeXBlockDuplicating') {
Expand Down Expand Up @@ -1028,7 +1022,6 @@ function($, _, Backbone, gettext, BasePage,
getSelectedLibraryComponents: function() {
var self = this;
var locator = this.$el.find('.studio-xblock-wrapper').data('locator');
console.log(ModuleUtils);
$.getJSON(
ModuleUtils.getUpdateUrl(locator) + '/handler/get_block_ids',
function(data) {
Expand Down
Loading
Loading