Skip to content

Commit 2484d99

Browse files
authored
Merge pull request #210 from magento-l3/PR-2023-02-24
Pr 2023 02 24 - PB CE
2 parents 64fd0a7 + 51f0445 commit 2484d99

File tree

17 files changed

+227
-18
lines changed

17 files changed

+227
-18
lines changed

app/code/Magento/PageBuilder/Test/Mftf/Test/AdminPageBuilderBannerCommonTest/BannerTextContainingPageBuilderMarkupWontBreakStageTest.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,15 @@
3838
<dontSeeElement selector="{{HtmlOnStage.base('1')}}" stepKey="dontSeeHtmlCode"/>
3939
<waitForElementVisible selector="{{BannerOnBackend.base('1')}}" stepKey="waitForBannerVisible"/>
4040
<seeElement selector="{{BannerOnBackend.messageContent('1', PageBuilderBannerMessageProperty.value)}}" stepKey="seeTestStringInBanner"/>
41+
<actionGroup ref="exitPageBuilderFullScreen" stepKey="exitPageBuilderFullScreenDesktop"/>
42+
<actionGroup ref="AdminSaveAndContinueEditCmsPageActionGroup" stepKey="saveAndContinueEditCmsPageDesktop"/>
43+
<actionGroup ref="switchToPageBuilderStage" stepKey="switchToPageBuilderStage"/>
44+
<actionGroup ref="dragContentTypeToStage" stepKey="dragRowToRootContainer">
45+
<argument name="contentType" value="PageBuilderRowContentType"/>
46+
<argument name="containerTargetType" value="PageBuilderRootContainerContentType"/>
47+
</actionGroup>
48+
<dontSeeElement selector="{{HtmlOnStage.base('1')}}" stepKey="dontSeeHtmlCodeAfterSave"/>
49+
<waitForElementVisible selector="{{BannerOnBackend.base('1')}}" stepKey="waitForBannerVisibleAfterSave"/>
50+
<seeElement selector="{{BannerOnBackend.messageContent('1', PageBuilderBannerMessageProperty.value)}}" stepKey="seeTestStringInBannerAfterSave"/>
4151
</test>
4252
</tests>

app/code/Magento/PageBuilder/Test/Mftf/Test/AdminPageBuilderSlideItemCommonTest/SlideItemTextContainingPageBuilderMarkupWontBreakStageTest.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,15 @@
4040
<dontSeeElement selector="{{HtmlOnStage.base('1')}}" stepKey="dontSeeHtmlCode"/>
4141
<waitForElementVisible selector="{{SlideOnBackend.base('1')}}" stepKey="waitForSlideItemVisible"/>
4242
<seeElement selector="{{SlideOnBackend.messageContent('1', PageBuilderSlideItemButtonText_Common.value)}}" stepKey="seeTestStringInSlideItem"/>
43+
<actionGroup ref="exitPageBuilderFullScreen" stepKey="exitPageBuilderFullScreenDesktop"/>
44+
<actionGroup ref="AdminSaveAndContinueEditCmsPageActionGroup" stepKey="saveAndContinueEditCmsPageDesktop"/>
45+
<actionGroup ref="switchToPageBuilderStage" stepKey="switchToPageBuilderStage"/>
46+
<actionGroup ref="dragContentTypeToStage" stepKey="dragRowToRootContainer">
47+
<argument name="contentType" value="PageBuilderRowContentType"/>
48+
<argument name="containerTargetType" value="PageBuilderRootContainerContentType"/>
49+
</actionGroup>
50+
<dontSeeElement selector="{{HtmlOnStage.base('1')}}" stepKey="dontSeeHtmlCodeAfterSave"/>
51+
<waitForElementVisible selector="{{SlideOnBackend.base('1')}}" stepKey="waitForSlideItemVisibleAfterSave"/>
52+
<seeElement selector="{{SlideOnBackend.messageContent('1', PageBuilderSlideItemButtonText_Common.value)}}" stepKey="seeTestStringInSlideItemAfterSave"/>
4353
</test>
4454
</tests>

app/code/Magento/PageBuilder/Test/Mftf/Test/AdminPageBuilderTextTest/TextContainingPageBuilderMarkupWontBreakStageTest.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,16 @@
4040
<waitForElementVisible selector="{{TextOnStage.base('1')}}" stepKey="waitForTextVisible"/>
4141
<seeElement selector="{{TextOnStage.base('1')}}" stepKey="seeText"/>
4242
<seeElement selector="{{TextOnStage.text('1', PageBuilderTextProperty.value)}}" stepKey="seeTestStringInText"/>
43+
<actionGroup ref="exitPageBuilderFullScreen" stepKey="exitPageBuilderFullScreenDesktop"/>
44+
<actionGroup ref="AdminSaveAndContinueEditCmsPageActionGroup" stepKey="saveAndContinueEditCmsPageDesktop"/>
45+
<actionGroup ref="switchToPageBuilderStage" stepKey="switchToPageBuilderStage"/>
46+
<actionGroup ref="dragContentTypeToStage" stepKey="dragRowToRootContainer">
47+
<argument name="contentType" value="PageBuilderRowContentType"/>
48+
<argument name="containerTargetType" value="PageBuilderRootContainerContentType"/>
49+
</actionGroup>
50+
<dontSeeElement selector="{{HtmlOnStage.base('1')}}" stepKey="dontSeeHtmlCodeAfterSave"/>
51+
<waitForElementVisible selector="{{TextOnStage.base('1')}}" stepKey="waitForTextVisibleAfterSave"/>
52+
<seeElement selector="{{TextOnStage.base('1')}}" stepKey="seeTextAfterSave"/>
53+
<seeElement selector="{{TextOnStage.text('1', PageBuilderTextProperty.value)}}" stepKey="seeTestStringInTextAfterSave"/>
4354
</test>
4455
</tests>

app/code/Magento/PageBuilder/etc/adminhtml/di.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,10 @@
556556
<item name="category" xsi:type="string">Category</item>
557557
<item name="block" xsi:type="string">Block</item>
558558
</item>
559+
<item name="reserved_html_attributes" xsi:type="array">
560+
<item name="data-content-type" xsi:type="string">data-content-type</item>
561+
<item name="contenteditable" xsi:type="string">contenteditable</item>
562+
</item>
559563
</argument>
560564
<argument name="rootContainerConfig" xsi:type="array">
561565
<item name="label" xsi:type="string">Root Container</item>

app/code/Magento/PageBuilder/etc/di.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@
414414
<item name="data-video-overlay-color" xsi:type="string">data-video-overlay-color</item>
415415
<item name="data-video-play-only-visible" xsi:type="string">data-video-play-only-visible</item>
416416
<item name="data-video-src" xsi:type="string">data-video-src</item>
417+
<item name="data-placeholder" xsi:type="string">data-placeholder</item>
417418
<item name="href" xsi:type="string">href</item>
418419
<item name="id" xsi:type="string">id</item>
419420
<item name="role" xsi:type="string">role</item>

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

Lines changed: 8 additions & 0 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/column-group/preview.js

Lines changed: 3 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/content-type/slide/preview.js

Lines changed: 8 additions & 0 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/text/preview.js

Lines changed: 5 additions & 4 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/utils/editor.js

Lines changed: 40 additions & 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/ts/js/content-type/banner/preview.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
isWysiwygSupported,
2525
lockImageSize,
2626
moveToBookmark,
27+
removeReservedHtmlAttributes,
2728
unlockImageSize,
2829
} from "../../utils/editor";
2930
import nestingLinkDialog from "../../utils/nesting-link-dialog";
@@ -493,6 +494,14 @@ export default class Preview extends BasePreview {
493494
* @inheritDoc
494495
*/
495496
protected bindEvents() {
497+
this.contentType.dataStore.subscribe((state: DataObject) => {
498+
const sanitizedContent = removeReservedHtmlAttributes(state.message);
499+
500+
if (sanitizedContent !== state.message) {
501+
state.message = sanitizedContent;
502+
}
503+
}, "message");
504+
496505
super.bindEvents();
497506
events.on("banner:mountAfter", (args: ContentTypeReadyEventParamsInterface) => {
498507
if (args.id === this.contentType.id) {

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {DataObject} from "../../data-store";
2121
import {moveContentType} from "../../drag-drop/move-content-type";
2222
import {getDraggedContentTypeConfig} from "../../drag-drop/registry";
2323
import {hiddenClass} from "../../drag-drop/sortable";
24+
import checkStageFullScreen from "../../utils/check-stage-full-screen";
2425
import {createStyleSheet} from "../../utils/create-stylesheet";
2526
import {default as ColumnGroupPreview} from "../column-group/preview";
2627
import {BindResizeHandleEventParamsInterface, InitElementEventParamsInterface} from "../column/column-events.types";
@@ -134,7 +135,7 @@ export default class Preview extends PreviewCollection {
134135
});
135136

136137
events.on(
137-
`stage:${this.contentType.stageId}:fullScreenModeChangeAfter`,
138+
`stage:${this.contentType.stageId}:readyAfter`,
138139
this.moveContentsToNewColumnGroup.bind(this),
139140
);
140141

@@ -624,7 +625,7 @@ export default class Preview extends PreviewCollection {
624625
private hasColumnLine(contentType: ContentTypeInterface | ContentTypeCollectionInterface): boolean {
625626
const children = this.contentType.getChildren()();
626627
let hasColumnLine = false;
627-
if (children.length === 0) {
628+
if (children.length === 0 && checkStageFullScreen(contentType.stageId)) {
628629
// new column group, so it has a column line
629630
hasColumnLine = true;
630631
}

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
isWysiwygSupported,
2626
lockImageSize,
2727
moveToBookmark,
28+
removeReservedHtmlAttributes,
2829
unlockImageSize,
2930
} from "../../utils/editor";
3031
import nestingLinkDialog from "../../utils/nesting-link-dialog";
@@ -488,6 +489,14 @@ export default class Preview extends BasePreview {
488489
* @inheritDoc
489490
*/
490491
protected bindEvents() {
492+
this.contentType.dataStore.subscribe((state: DataObject) => {
493+
const sanitizedContent = removeReservedHtmlAttributes(state.content);
494+
495+
if (sanitizedContent !== state.content) {
496+
state.content = sanitizedContent;
497+
}
498+
}, "content");
499+
491500
super.bindEvents();
492501

493502
events.on("slide:mountAfter", (args: ContentTypeReadyEventParamsInterface) => {

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
isWysiwygSupported,
2121
lockImageSize,
2222
moveToBookmark,
23+
removeReservedHtmlAttributes,
2324
replaceDoubleQuoteWithSingleQuoteWithinVariableDirective,
2425
unlockImageSize,
2526
} from "../../utils/editor";
@@ -340,17 +341,19 @@ export default class Preview extends BasePreview {
340341
* Bind events
341342
*/
342343
protected bindEvents() {
343-
super.bindEvents();
344-
345344
this.contentType.dataStore.subscribe((state: DataObject) => {
346-
const sanitizedContent = replaceDoubleQuoteWithSingleQuoteWithinVariableDirective(
347-
escapeDoubleQuoteWithinWidgetDirective(state.content),
348-
);
345+
const sanitizedContent = removeReservedHtmlAttributes(
346+
replaceDoubleQuoteWithSingleQuoteWithinVariableDirective(
347+
escapeDoubleQuoteWithinWidgetDirective(state.content),
348+
),
349+
);
349350

350351
if (sanitizedContent !== state.content) {
351352
state.content = sanitizedContent;
352353
}
353-
});
354+
}, "content");
355+
356+
super.bindEvents();
354357

355358
// After drop of new content type open TinyMCE and focus
356359
events.on("text:dropAfter", (args: ContentTypeMountEventParamsInterface) => {

app/code/Magento/PageBuilder/view/adminhtml/web/ts/js/utils/editor.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,40 @@ export function replaceDoubleQuoteWithSingleQuoteWithinVariableDirective(content
469469
);
470470
}
471471

472+
/**
473+
* Remove Page Builder reserved html tag attributes from the content
474+
*
475+
* @param {string} content
476+
* @returns {string}
477+
*/
478+
export function removeReservedHtmlAttributes(content: string): string
479+
{
480+
const attributes: {[key: string]: string} = Config.getConfig("stage_config").reserved_html_attributes || {};
481+
for (const attribute of Object.keys(attributes)) {
482+
content = removeHtmlTagAttribute(content, attribute);
483+
}
484+
return content;
485+
}
486+
487+
/**
488+
* Remove attribute from html tags
489+
*
490+
* @param {string} content
491+
* @param {string} name
492+
* @returns {string}
493+
*/
494+
function removeHtmlTagAttribute(content: string, name: string): string
495+
{
496+
if (typeof content === "string" && content.indexOf(`${name}=`) !== -1) {
497+
const html = new DOMParser().parseFromString(content, "text/html");
498+
html.querySelectorAll(`[${name}]`).forEach((child: Element) => {
499+
child.removeAttribute(name);
500+
});
501+
content = html.body.innerHTML;
502+
}
503+
return content;
504+
}
505+
472506
interface IdBookmark {
473507
id: string;
474508
keep?: boolean;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
/* eslint-disable max-nested-callbacks */
7+
define([
8+
'ko',
9+
'jquery',
10+
'Magento_PageBuilder/js/content-type/column-group/preview',
11+
'Magento_PageBuilder/js/config',
12+
'Magento_PageBuilder/js/events'
13+
], function (ko,$, Preview, Config, Events) {
14+
'use strict';
15+
16+
describe('Magento_PageBuilder/js/content-type/column-group/preview', function () {
17+
var model;
18+
19+
beforeEach(function () {
20+
Config.config = {content_types: {}};
21+
model = new Preview(
22+
{
23+
dataStore: {subscribe: jasmine.createSpy()},
24+
getChildren: function () {
25+
return ko.observableArray([]);
26+
},
27+
children: {subscribe: jasmine.createSpy()},
28+
stageId: 'STAGEID'
29+
},
30+
{config: {content_types: {}}});
31+
});
32+
33+
describe('Stage readyAfter event', function () {
34+
it('Should call methods to upgrade to column-line if needed', function () {
35+
spyOn(model, 'getCurrentIndexInParent');
36+
spyOn(model, 'hasColumnLine');
37+
Events.trigger('stage:' + model.contentType.stageId + ':readyAfter');
38+
expect(model.getCurrentIndexInParent).toHaveBeenCalled();
39+
expect(model.hasColumnLine).toHaveBeenCalled();
40+
});
41+
});
42+
});
43+
});

0 commit comments

Comments
 (0)