Skip to content

Commit 4dbd597

Browse files
committed
MC-3775: Button editable state is not consistent with the options panel appearing
- Fix tab focusing
1 parent 2a50aa4 commit 4dbd597

File tree

7 files changed

+61
-117
lines changed

7 files changed

+61
-117
lines changed

app/code/Magento/PageBuilder/view/adminhtml/web/js/binding/live-edit.js

Lines changed: 2 additions & 37 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/code/Magento/PageBuilder/view/adminhtml/web/js/content-type/button-item/preview.js

Lines changed: 18 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/code/Magento/PageBuilder/view/adminhtml/web/js/content-type/buttons/preview.js

Lines changed: 8 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/code/Magento/PageBuilder/view/adminhtml/web/template/content-type/buttons/inline/preview.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
<div class="pagebuilder-content-type pagebuilder-entity pagebuilder-entity-preview pagebuilder-no-blur pagebuilder-live-edit pagebuilder-buttons" event="{ mouseover: onMouseOver, mouseout: onMouseOut }, mouseoverBubble: false">
99
<render args="getOptions().template" />
1010
<div class="element-children buttons-container" each="parent.getChildren()" attr="Object.assign({}, data.main.attributes(), { id: parent.id + '-children' })" ko-style="data.main.style" css="data.main.css" data-bind="sortableChildren: getSortableOptions()">
11-
<div class="pagebuilder-content-type-wrapper" template="{ name: preview.previewTemplate, data: preview, afterRender: function () { preview.dispatchAfterRenderEvent.apply(preview, arguments); } }" attr="{ id: id }" css="{'pagebuilder-content-type-hidden': !preview.display()}"></div>
11+
<div class="pagebuilder-content-type-wrapper"
12+
template="{ name: preview.previewTemplate, data: preview, afterRender: function () { preview.dispatchAfterRenderEvent.apply(preview, arguments); } }"
13+
attr="{ id: id }"
14+
css="{'pagebuilder-content-type-hidden': !preview.display()}"></div>
1215
</div>
1316
</div>

app/code/Magento/PageBuilder/view/adminhtml/web/ts/js/binding/live-edit.ts

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -108,37 +108,10 @@ ko.bindingHandlers.liveEdit = {
108108
event.stopPropagation();
109109
}
110110

111-
debouncedUpdateHandler.call(this);
112-
};
113-
114-
/**
115-
* Debounce the saving of the state to ensure that on save without first unfocusing will succeed
116-
*/
117-
const debouncedUpdateHandler = _.debounce(() => {
118-
const selection = window.getSelection();
119-
const range = document.createRange();
120-
const getCharPosition = (editableDiv: HTMLElement): number => {
121-
let charPosition = 0;
122-
123-
if (window.getSelection) {
124-
if (selection.rangeCount) {
125-
if (selection.getRangeAt(0).commonAncestorContainer.parentNode === editableDiv) {
126-
charPosition = selection.getRangeAt(0).endOffset;
127-
}
128-
}
129-
}
130-
return charPosition;
131-
};
132-
const pos: number = getCharPosition(element);
133-
134111
if (focusedValue !== stripHtml(element.innerHTML)) {
135112
viewModel.updateData(field, stripHtml(element.innerHTML));
136113
}
137-
range.setStart(element.childNodes[0], pos);
138-
range.collapse(true);
139-
selection.removeAllRanges();
140-
selection.addRange(range);
141-
}, 300);
114+
};
142115

143116
/**
144117
* Prevent content from being dropped inside of inline edit area

app/code/Magento/PageBuilder/view/adminhtml/web/ts/js/content-type/button-item/preview.ts

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import $ from "jquery";
77
import ko from "knockout";
88
import $t from "mage/translate";
9+
import _ from "underscore";
910
import ConditionalRemoveOption from "../../content-type-menu/conditional-remove-option";
1011
import {OptionsInterface} from "../../content-type-menu/option.d";
1112
import ButtonsPreview from "../buttons/preview";
@@ -51,22 +52,25 @@ export default class Preview extends BasePreview {
5152
* @param {Event} event
5253
*/
5354
public onFocusOut(index: number, event: JQueryEventObject): void {
54-
const parentPreview = this.parent.parent.preview as ButtonsPreview;
55-
if (!event.relatedTarget) {
56-
if (parentPreview.focusedButton() === index) {
57-
window.getSelection().removeAllRanges();
58-
parentPreview.focusedButton(null);
59-
}
60-
} else {
61-
// Have we moved the focus onto another button in the current group?
62-
if ($.contains(parentPreview.wrapperElement, event.relatedTarget)) {
63-
const buttonItem = ko.dataFor(event.relatedTarget) as Preview;
64-
if (buttonItem) {
65-
$(buttonItem.wrapperElement).find("[contenteditable]").focus();
55+
if (this.parent && this.parent.parent) {
56+
const parentPreview = this.parent.parent.preview as ButtonsPreview;
57+
if (!event.relatedTarget) {
58+
if (parentPreview.focusedButton() === index) {
59+
window.getSelection().removeAllRanges();
60+
parentPreview.focusedButton(null);
6661
}
6762
} else {
68-
window.getSelection().removeAllRanges();
69-
parentPreview.focusedButton(null);
63+
// Have we moved the focus onto another button in the current group?
64+
if ($.contains(parentPreview.wrapperElement, event.relatedTarget)) {
65+
const buttonItem = ko.dataFor(event.relatedTarget) as Preview;
66+
if (buttonItem) {
67+
const newIndex = buttonItem.parent.parent.children().indexOf(buttonItem.parent);
68+
parentPreview.focusedButton(newIndex);
69+
}
70+
} else {
71+
window.getSelection().removeAllRanges();
72+
parentPreview.focusedButton(null);
73+
}
7074
}
7175
}
7276
}

app/code/Magento/PageBuilder/view/adminhtml/web/ts/js/content-type/buttons/preview.ts

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,6 @@ import PreviewCollection from "../preview-collection";
3232
export default class Preview extends PreviewCollection {
3333
public focusedButton: KnockoutObservable<number> = ko.observable();
3434

35-
/**
36-
* Keeps track of number of button item to disable sortable if there is only 1.
37-
*/
38-
public disableSorting: KnockoutComputed<void> = ko.computed(() => {
39-
const sortableElement = $(this.wrapperElement).find(".buttons-container");
40-
if (this.parent.children().length <= 1) {
41-
sortableElement.sortable("disable");
42-
} else {
43-
sortableElement.sortable("enable");
44-
}
45-
});
46-
4735
private debouncedResizeHandler = _.debounce(() => {
4836
this.resizeChildButtons();
4937
}, 350);
@@ -60,6 +48,16 @@ export default class Preview extends PreviewCollection {
6048
) {
6149
super(parent, config, observableUpdater);
6250

51+
// Keeps track of number of button item to disable sortable if there is only 1.
52+
this.parent.children.subscribe(() => {
53+
const sortableElement = $(this.wrapperElement).find(".buttons-container");
54+
if (this.parent.children().length <= 1) {
55+
sortableElement.sortable("disable");
56+
} else {
57+
sortableElement.sortable("enable");
58+
}
59+
});
60+
6361
// Monitor focus tab to start / stop interaction on the stage, debounce to avoid duplicate calls
6462
this.focusedButton.subscribe(_.debounce((index: number) => {
6563
if (index !== null) {

0 commit comments

Comments
 (0)