Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into jill/fal-4008-edit-…
Browse files Browse the repository at this point in the history
…tags-broken-link
  • Loading branch information
pomegranited committed Feb 11, 2025
2 parents af6a549 + 9257164 commit 3f9a78c
Show file tree
Hide file tree
Showing 14 changed files with 525 additions and 375 deletions.
195 changes: 173 additions & 22 deletions cms/static/js/views/pages/container.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,40 @@ function($, _, Backbone, gettext, BasePage,

if (this.options.isIframeEmbed) {
window.addEventListener('message', (event) => {
if (event.data && event.data.type === 'refreshXBlock') {
this.render();
}
});
const { data } = event;

if (!data) return;

let xblockElement;
let xblockWrapper;

if (data.payload && data.payload.locator) {
xblockElement = $(`[data-locator="${data.payload.locator}"]`);
xblockWrapper = $("li.studio-xblock-wrapper[data-locator='" + data.payload.locator + "']");
} else {
xblockWrapper = $();
}

switch (data.type) {
case 'refreshXBlock':
this.render();
break;
case 'completeManageXBlockAccess':
this.refreshXBlock(xblockElement, false);
break;
case 'completeXBlockMoving':
xblockWrapper.hide();
break;
case 'rollbackMovedXBlock':
xblockWrapper.show();
break;
case 'addXBlock':
this.createComponent(this, xblockElement, data);
break;
default:
console.warn('Unhandled message type:', data.type);
}
});
}

this.listenTo(Backbone, 'move:onXBlockMoved', this.onXBlockMoved);
Expand Down Expand Up @@ -199,6 +229,25 @@ function($, _, Backbone, gettext, BasePage,
target.scrollIntoView({ behavior: 'smooth', inline: 'center' });
}

if (self.options.isIframeEmbed) {
const scrollOffsetString = localStorage.getItem('modalEditLastYPosition');
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);
}
}
}
},
block_added: options && options.block_added
});
Expand Down Expand Up @@ -395,8 +444,16 @@ function($, _, Backbone, gettext, BasePage,
const isAccessButton = event.currentTarget.className === 'access-button';
const primaryHeader = $(event.target).closest('.xblock-header-primary, .nav-actions');
const usageId = encodeURI(primaryHeader.attr('data-usage-id'));

try {
if (this.options.isIframeEmbed && isAccessButton) {
window.parent.postMessage(
{
type: 'toggleCourseXBlockDropdown',
message: 'Adjust the height of the dropdown menu',
payload: { courseXBlockDropdownHeight: 0 }
}, document.referrer
);
return window.parent.postMessage(
{
type: 'manageXBlockAccess',
Expand All @@ -422,11 +479,12 @@ function($, _, Backbone, gettext, BasePage,
|| (useNewProblemEditor === 'True' && blockType === 'problem')
) {
var destinationUrl = primaryHeader.attr('authoring_MFE_base_url')
+ '/' + blockType
+ '/' + encodeURI(primaryHeader.attr('data-usage-id'));
+ '/' + blockType
+ '/' + encodeURI(primaryHeader.attr('data-usage-id'));

try {
if (this.options.isIframeEmbed) {
localStorage.setItem('modalEditLastYPosition', event.clientY.toString());
return window.parent.postMessage(
{
type: 'newXBlockEditor',
Expand Down Expand Up @@ -615,7 +673,7 @@ function($, _, Backbone, gettext, BasePage,
type: 'toggleCourseXBlockDropdown',
message: 'Adjust the height of the dropdown menu',
payload: {
courseXBlockDropdownHeight: courseXBlockDropdownHeight / 2,
courseXBlockDropdownHeight: courseXBlockDropdownHeight / 2,
},
}, document.referrer
);
Expand Down Expand Up @@ -735,13 +793,26 @@ function($, _, Backbone, gettext, BasePage,
const usageId = encodeURI(primaryHeader.attr('data-usage-id'));
try {
if (this.options.isIframeEmbed) {
return window.parent.postMessage(
window.parent.postMessage(
{
type: 'duplicateXBlock',
message: 'Duplicate the XBlock',
payload: { blockType, usageId }
}, document.referrer
);
window.parent.postMessage(
{
type: 'toggleCourseXBlockDropdown',
message: 'Adjust the height of the dropdown menu',
payload: { courseXBlockDropdownHeight: 0 }
}, document.referrer
);
// Saves the height of the XBlock during duplication with the new editor.
// After closing the editor, the page scrolls to the newly created copy of the XBlock.
if (['html', 'problem', 'video'].includes(blockType)) {
const scrollHeight = event.clientY + this.findXBlockElement(event.target).height();
localStorage.setItem('modalEditLastYPosition', scrollHeight.toString());
}
}
} catch (e) {
console.error(e);
Expand All @@ -768,17 +839,24 @@ function($, _, Backbone, gettext, BasePage,
type: 'showMoveXBlockModal',
payload: {
sourceXBlockInfo: {
id: sourceXBlockInfo.attributes.id,
displayName: sourceXBlockInfo.attributes.display_name,
id: sourceXBlockInfo.attributes.id,
displayName: sourceXBlockInfo.attributes.display_name,
},
sourceParentXBlockInfo: {
id: sourceParentXBlockInfo.attributes.id,
category: sourceParentXBlockInfo.attributes.category,
hasChildren: sourceParentXBlockInfo.attributes.has_children,
id: sourceParentXBlockInfo.attributes.id,
category: sourceParentXBlockInfo.attributes.category,
hasChildren: sourceParentXBlockInfo.attributes.has_children,
},
},
}, document.referrer
);
window.parent.postMessage(
{
type: 'toggleCourseXBlockDropdown',
message: 'Adjust the height of the dropdown menu',
payload: { courseXBlockDropdownHeight: 0 }
}, document.referrer
);
return true;
}
} catch (e) {
Expand All @@ -795,35 +873,63 @@ function($, _, Backbone, gettext, BasePage,
const usageId = encodeURI(primaryHeader.attr('data-usage-id'));
try {
if (this.options.isIframeEmbed) {
return window.parent.postMessage(
window.parent.postMessage(
{
type: 'deleteXBlock',
message: 'Delete the XBlock',
payload: { usageId }
}, document.referrer
);
window.parent.postMessage(
{
type: 'toggleCourseXBlockDropdown',
message: 'Adjust the height of the dropdown menu',
payload: { courseXBlockDropdownHeight: 0 }
}, document.referrer
);
}
} catch (e) {
console.error(e);
}
this.deleteComponent(this.findXBlockElement(event.target));
},

createComponent: function(template, 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),
parentLocator = parentElement.data('locator'),
buttonPanel = target.closest('.add-xblock-component'),
listPanel = buttonPanel.prev(),
scrollOffset = ViewUtils.getScrollOffset(buttonPanel),
buttonPanel = target?.closest('.add-xblock-component'),
listPanel = buttonPanel?.prev(),
$placeholderEl = $(this.createPlaceholderElement()),
requestData = _.extend(template, {
parent_locator: parentLocator
}),
placeholderElement;
placeholderElement = $placeholderEl.appendTo(listPanel);
scrollOffset,
placeholderElement,
$container;

if (this.options.isIframeEmbed) {
$container = $('ol.reorderable-container.ui-sortable');
scrollOffset = 0;
} else {
$container = listPanel;
scrollOffset = ViewUtils.getScrollOffset(buttonPanel);
}

placeholderElement = $placeholderEl.appendTo($container);

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

return $.postJSON(this.getURLRoot() + '/', requestData,
_.bind(this.onNewXBlock, this, placeholderElement, scrollOffset, false))
.fail(function() {
Expand All @@ -843,6 +949,32 @@ function($, _, Backbone, gettext, BasePage,
placeholderElement;

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);
}

const messageHandler = ({ data }) => {
if (data && data.type === 'completeXBlockDuplicating') {
self.onNewXBlock(placeholderElement, null, true, data.payload);
window.removeEventListener('message', messageHandler);
}
};

window.addEventListener('message', messageHandler);

return;
}

XBlockUtils.duplicateXBlock(xblockElement, parentElement)
.done(function(data) {
self.onNewXBlock(placeholderElement, scrollOffset, true, data);
Expand All @@ -858,6 +990,21 @@ function($, _, Backbone, gettext, BasePage,
xblockInfo = new XBlockInfo({
id: xblockElement.data('locator')
});

if (this.options.isIframeEmbed) {
const messageHandler = ({ data }) => {
if (data && data.type === 'completeXBlockDeleting') {
const targetXBlockElement = $(`[data-locator="${data.payload.locator}"]`);
window.removeEventListener('message', messageHandler);
return self.onDelete(targetXBlockElement);
}
};

window.addEventListener('message', messageHandler);

return;
}

XBlockUtils.deleteXBlock(xblockInfo).done(function() {
self.onDelete(xblockElement);
});
Expand Down Expand Up @@ -986,7 +1133,9 @@ function($, _, Backbone, gettext, BasePage,
window.location.href = destinationUrl;
return;
}
ViewUtils.setScrollOffset(xblockElement, scrollOffset);
if (!this.options.isIframeEmbed) {
ViewUtils.setScrollOffset(xblockElement, scrollOffset);
}
xblockElement.data('locator', data.locator);
return this.refreshXBlock(xblockElement, true, is_duplicate);
},
Expand All @@ -1003,7 +1152,9 @@ function($, _, Backbone, gettext, BasePage,
parentElement = xblockElement.parent(),
rootLocator = this.xblockView.model.id;
if (xblockElement.length === 0 || xblockElement.data('locator') === rootLocator) {
this.render({refresh: true, block_added: block_added});
if (block_added) {
this.render({refresh: true, block_added: block_added});
}
} else if (parentElement.hasClass('reorderable-container')) {
this.refreshChildXBlock(xblockElement, block_added, is_duplicate);
} else {
Expand Down
1 change: 0 additions & 1 deletion common/static/sass/_builtin-block-variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@
--shadow-l1: $shadow-l1;
--sidebar-color: $sidebar-color;
--small-font-size: $small-font-size;
--static-path: $static-path;
--submitted: $submitted;
--success: $success;
--tmg-f2: $tmg-f2;
Expand Down
2 changes: 1 addition & 1 deletion openedx/core/djangoapps/password_policy/compliance.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def enforce_compliance_on_login(user, password):
platform_name=settings.PLATFORM_NAME,
deadline=strftime_localized(deadline, DEFAULT_SHORT_DATE_FORMAT),
anchor_tag_open=HTML('<a href="{account_settings_url}">').format(
account_settings_url=settings.LMS_ROOT_URL + "/account/settings"
account_settings_url=settings.ACCOUNT_MICROFRONTEND_URL
),
anchor_tag_close=HTML('</a>')
)
Expand Down
Loading

0 comments on commit 3f9a78c

Please sign in to comment.