Skip to content

Commit 828b488

Browse files
committed
MC-5691: Implement better developer error reporting
- Handle invalid mark up present in field before load - Remove deprecated usage of previewData
1 parent 7f134f3 commit 828b488

File tree

9 files changed

+84
-31
lines changed

9 files changed

+84
-31
lines changed

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

Lines changed: 1 addition & 1 deletion
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/master-format/read/configurable.js

Lines changed: 22 additions & 3 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/stage-builder.js

Lines changed: 9 additions & 7 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/ts/js/content-type-factory.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ export default function createContentType(
3636
): Promise<ContentTypeInterface | ContentTypeCollectionInterface> {
3737
return new Promise(
3838
(resolve: (contentType: ContentType | ContentTypeCollection) => void,
39-
reject: (error: string) => void
40-
)=> {
39+
reject: (error: string) => void,
40+
) => {
4141
loadModule([config.component], (contentTypeComponent: typeof ContentType | typeof ContentTypeCollection) => {
4242
try {
4343
const contentType = new contentTypeComponent(

app/code/Magento/PageBuilder/view/adminhtml/web/ts/js/content-type/master-factory.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
*/
55

66
import loadModule from "Magento_PageBuilder/js/utils/loader";
7+
import ContentTypeCollectionInterface from "../content-type-collection.d";
78
import ContentTypeConfigInterface from "../content-type-config.d";
89
import ContentTypeInterface from "../content-type.d";
9-
import ContentTypeCollectionInterface from "../content-type-collection.d";
1010
import converterResolver from "./converter-resolver";
1111
import Master from "./master";
1212
import MasterCollection from "./master-collection";
@@ -24,7 +24,7 @@ export default function create(
2424
config: ContentTypeConfigInterface,
2525
): Promise<Master | MasterCollection> {
2626
return new Promise(
27-
(resolve: (masterComponent: Master | MasterCollection) => void, reject: (error: string) => void
27+
(resolve: (masterComponent: Master | MasterCollection) => void, reject: (error: string) => void,
2828
) => {
2929
observableUpdaterFactory(config, converterResolver).then((observableUpdater) => {
3030
loadModule([config.master_component], (masterComponent: typeof Master | typeof MasterCollection) => {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
*/
55

66
import loadModule from "Magento_PageBuilder/js/utils/loader";
7+
import ContentTypeCollectionInterface from "../content-type-collection.d";
78
import ContentTypeConfigInterface from "../content-type-config.d";
89
import ContentTypeInterface from "../content-type.d";
9-
import ContentTypeCollectionInterface from "../content-type-collection.d";
1010
import observableUpdaterFactory from "./observable-updater-factory";
1111
import Preview from "./preview";
1212
import PreviewCollection from "./preview-collection";
@@ -24,7 +24,7 @@ export default function create(
2424
config: ContentTypeConfigInterface,
2525
): Promise<Preview | PreviewCollection> {
2626
return new Promise(
27-
(resolve: (previewComponent: Preview | PreviewCollection) => void, reject: (e: string) => void
27+
(resolve: (previewComponent: Preview | PreviewCollection) => void, reject: (e: string) => void,
2828
) => {
2929
observableUpdaterFactory(config, previewConverterResolver).then((observableUpdater) => {
3030
loadModule([config.preview_component], (previewComponent: typeof Preview | typeof PreviewCollection) => {

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,13 @@ export default class Preview {
9393
* @returns {string}
9494
*/
9595
get previewTemplate(): string {
96-
const appearance = this.previewData.appearance ? this.previewData.appearance() as string : undefined;
97-
return appearanceConfig(this.config.name, appearance).preview_template;
96+
const appearance = this.parent.dataStore.get("appearance") ?
97+
this.parent.dataStore.get("appearance").toString() : undefined;
98+
99+
return appearanceConfig(
100+
this.config.name,
101+
appearance
102+
).preview_template;
98103
}
99104

100105
/**

app/code/Magento/PageBuilder/view/adminhtml/web/ts/js/master-format/read/configurable.ts

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import MassConverterPool from "../../mass-converter/converter-pool";
1414
import massConverterPoolFactory from "../../mass-converter/converter-pool-factory";
1515
import propertyReaderPoolFactory from "../../property/property-reader-pool-factory";
1616
import {ReadInterface} from "../read-interface";
17+
import Config from "../../config";
1718

1819
/**
1920
* @api
@@ -27,7 +28,7 @@ export default class Configurable implements ReadInterface {
2728
* @returns {Promise<any>}
2829
*/
2930
public read(element: HTMLElement): Promise<any> {
30-
const role = element.getAttribute("data-role");
31+
const role = element.getAttribute(Config.getConfig("dataRoleAttributeName"));
3132
const config = appearanceConfig(role, element.getAttribute("data-appearance"));
3233
const componentsPromise: Array<Promise<any>> = [
3334
propertyReaderPoolFactory(role),
@@ -40,13 +41,13 @@ export default class Configurable implements ReadInterface {
4041
let data = {};
4142
for (const elementName of Object.keys(config.elements)) {
4243
const elementConfig = config.elements[elementName];
43-
const currentElement = element.getAttribute("data-element") === elementName
44-
? element
45-
: element.querySelector<HTMLElement>("[data-element = '" + elementName + "']");
44+
const currentElement = this.findElementByName(element, elementName);
4645

46+
// If we cannot locate the current element skip trying to read any attributes from it
4747
if (currentElement === null || currentElement === undefined) {
4848
continue;
4949
}
50+
5051
if (elementConfig.style.length) {
5152
data = this.readStyle(
5253
elementConfig.style,
@@ -56,6 +57,7 @@ export default class Configurable implements ReadInterface {
5657
converterPool,
5758
);
5859
}
60+
5961
if (elementConfig.attributes.length) {
6062
data = this.readAttributes(
6163
elementConfig.attributes,
@@ -65,16 +67,20 @@ export default class Configurable implements ReadInterface {
6567
converterPool,
6668
);
6769
}
70+
6871
if (undefined !== elementConfig.html.var) {
6972
data = this.readHtml(elementConfig, currentElement, data, converterPool);
7073
}
74+
7175
if (undefined !== elementConfig.tag.var) {
7276
data = this.readHtmlTag(elementConfig, currentElement, data);
7377
}
78+
7479
if (undefined !== elementConfig.css.var) {
7580
data = this.readCss(elementConfig, currentElement, data);
7681
}
7782
}
83+
7884
data = this.convertData(config, data, massConverterPool);
7985
resolve(data);
8086
}).catch((error) => {
@@ -83,6 +89,25 @@ export default class Configurable implements ReadInterface {
8389
});
8490
}
8591

92+
/**
93+
* Find the element for the current content type by it's name, avoiding searching in other content types by
94+
* removing any other element which contains it's own data-role.
95+
*
96+
* @param {HTMLElement} element
97+
* @param {string} name
98+
* @returns {HTMLElement}
99+
*/
100+
private findElementByName(element: HTMLElement, name: string): HTMLElement {
101+
const currentElement = $(element).clone();
102+
// Remove all child instances of data-role elements
103+
currentElement.find(`[${Config.getConfig("dataRoleAttributeName")}]`).remove();
104+
105+
// Find the element in the modified close with a matching element name
106+
return currentElement.attr("data-element") === name
107+
? currentElement[0]
108+
: currentElement[0].querySelector<HTMLElement>(`[data-element=${name}]`);
109+
}
110+
86111
/**
87112
* Read attributes for element
88113
*

app/code/Magento/PageBuilder/view/adminhtml/web/ts/js/stage-builder.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ function createElementContentType(
8787
parent = parent || stage;
8888
const role = element.getAttribute(Config.getConfig("dataRoleAttributeName"));
8989
if (!role) {
90-
return Promise.reject(`Invalid master format: Content type element does not contain
90+
return Promise.reject(`Invalid master format: Content type element does not contain
9191
${Config.getConfig("dataRoleAttributeName")} attribute.`);
9292
}
9393

@@ -120,8 +120,8 @@ function getElementData(element: HTMLElement, config: ContentTypeConfigInterface
120120
return "";
121121
});
122122

123-
return new Promise((resolve: (result: object) => void, reject: (e: string) => void) => {
124-
const role = element.dataset.role;
123+
return new Promise((resolve: (result: object) => void) => {
124+
const role = element.getAttribute(Config.getConfig("dataRoleAttributeName"));
125125
if (!Config.getConfig("content_types").hasOwnProperty(role)) {
126126
resolve(result);
127127
} else {
@@ -147,15 +147,17 @@ function getElementData(element: HTMLElement, config: ContentTypeConfigInterface
147147
* @param {HTMLElement} element
148148
* @returns {Array<HTMLElement>}
149149
*/
150-
function getElementChildren(element: HTMLElement): Array<HTMLElement> {
150+
function getElementChildren(element: HTMLElement): HTMLElement[] {
151151
if (element.hasChildNodes()) {
152152
let children: any[] = [];
153153

154154
_.forEach(element.childNodes, (child: HTMLElement) => {
155-
if (child.hasAttribute(Config.getConfig("dataRoleAttributeName"))) {
156-
children.push(child);
157-
} else {
158-
children = getElementChildren(child);
155+
if (child.nodeType === Node.ELEMENT_NODE) {
156+
if (child.hasAttribute(Config.getConfig("dataRoleAttributeName"))) {
157+
children.push(child);
158+
} else {
159+
children = getElementChildren(child);
160+
}
159161
}
160162
});
161163

0 commit comments

Comments
 (0)