Skip to content

Commit 223eb8b

Browse files
Merge pull request #2 from magento-obsessive-owls/1.5.0-sync
[Imported] [Story] Developer can style content types output differently per viewport
2 parents 09722d1 + d0e6b3f commit 223eb8b

File tree

462 files changed

+26363
-3592
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

462 files changed

+26363
-3592
lines changed

app/code/Magento/PageBuilder/Model/Dom/Adapter/DocumentInterface.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@ public function __toString(): string;
2929
*/
3030
public function createDocumentFragment(): DocumentFragmentInterface;
3131

32+
/**
33+
* Create new document element
34+
*
35+
* @param string $name
36+
* @param string $value [optional]
37+
* @return ElementInterface
38+
*/
39+
public function createElement(string $name, string $value = null);
40+
3241
/**
3342
* Returns the first element matching the specified selector.
3443
*

app/code/Magento/PageBuilder/Model/Dom/Adapter/ElementInterface.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,28 @@
77

88
namespace Magento\PageBuilder\Model\Dom\Adapter;
99

10+
use Gt\Dom\Element as GtDomElement;
11+
1012
/**
1113
* Interface for Element wrappers
1214
*/
1315
interface ElementInterface
1416
{
17+
/**
18+
* Return original element.
19+
*
20+
* @return GtDomElement
21+
*/
22+
public function getOriginalElement(): GtDomElement;
23+
24+
/**
25+
* Adds new child at the end of the children.
26+
*
27+
* @param ElementInterface $element
28+
* @return ElementInterface
29+
*/
30+
public function appendChild(ElementInterface $element): ElementInterface;
31+
1532
/**
1633
* Returns true if the element would be selected by the specified selector string; otherwise, returns false.
1734
*
@@ -45,6 +62,14 @@ public function closest(string $selectors): ?ElementInterface;
4562
*/
4663
public function getAttribute($name): ?string;
4764

65+
/**
66+
* Removes the Specified Attribute
67+
*
68+
* @param string $name
69+
* @return bool|null
70+
*/
71+
public function removeAttribute($name): ?bool;
72+
4873
/**
4974
* Sets the value of the specified attribute
5075
*

app/code/Magento/PageBuilder/Model/Dom/Document.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,17 @@ public function createDocumentFragment(): DocumentFragmentInterface
6262
);
6363
}
6464

65+
/**
66+
* @inheritDoc
67+
*/
68+
public function createElement(string $name, string $value = null): ElementInterface
69+
{
70+
return $this->objectManager->create(
71+
ElementInterface::class,
72+
[ 'element' => $this->document->createElement($name, $value) ]
73+
);
74+
}
75+
6576
/**
6677
* @inheritDoc
6778
*/

app/code/Magento/PageBuilder/Model/Dom/Element.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,25 @@ public function __construct(
4141
$this->element = $element;
4242
}
4343

44+
/**
45+
* @inheritDoc
46+
*/
47+
public function getOriginalElement(): GtDomElement
48+
{
49+
return $this->element;
50+
}
51+
52+
/**
53+
* @inheritDoc
54+
*/
55+
public function appendChild(ElementInterface $element): ElementInterface
56+
{
57+
return $this->objectManager->create(
58+
ElementInterface::class,
59+
[ 'element' => $this->element->appendChild($element->getOriginalElement()) ]
60+
);
61+
}
62+
4463
/**
4564
* @inheritDoc
4665
*/
@@ -79,6 +98,14 @@ public function getAttribute($name): ?string
7998
return $this->element->getAttribute($name);
8099
}
81100

101+
/**
102+
* @inheritDoc
103+
*/
104+
public function removeAttribute($name): ?bool
105+
{
106+
return $this->element->removeAttribute($name);
107+
}
108+
82109
/**
83110
* @inheritDoc
84111
*/
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types = 1);
8+
9+
namespace Magento\PageBuilder\Setup\Converters;
10+
11+
use Magento\Framework\DB\DataConverter\DataConverterInterface;
12+
use Magento\PageBuilder\Model\Dom\Adapter\ElementInterface;
13+
use Magento\PageBuilder\Model\Dom\HtmlDocumentFactory;
14+
15+
/**
16+
* Convert Inline Styles to Internal
17+
*/
18+
class PageBuilderStripStyles implements DataConverterInterface
19+
{
20+
private const BODY_ID = 'html-body';
21+
private const DATA_ATTRIBUTE = 'data-pb-style';
22+
private const QUERY_SELECTOR = '[style]';
23+
24+
/**
25+
* @var HtmlDocumentFactory
26+
*/
27+
private $htmlDocumentFactory;
28+
29+
/**
30+
* @param HtmlDocumentFactory $htmlDocumentFactory
31+
*/
32+
public function __construct(HtmlDocumentFactory $htmlDocumentFactory)
33+
{
34+
$this->htmlDocumentFactory = $htmlDocumentFactory;
35+
}
36+
37+
/**
38+
* Generates `mageUtils.uniqueid()` Naming Convention
39+
*
40+
* @return string
41+
*/
42+
private function generateDataAttribute(): string
43+
{
44+
return \strtoupper(\uniqid());
45+
}
46+
47+
/**
48+
* Converts Inline Styles to Internal Styles
49+
*
50+
* @param array $styleMap
51+
* @return string
52+
*/
53+
private function generateInternalStyles(array $styleMap): string
54+
{
55+
$output = '';
56+
57+
foreach ($styleMap as $selector => $styles) {
58+
$output .= '#' . self::BODY_ID . ' [' . self::DATA_ATTRIBUTE . '="' . $selector . '"]';
59+
$output .= '{' . $styles . '}';
60+
}
61+
62+
return $output;
63+
}
64+
65+
/**
66+
* @inheritDoc
67+
*/
68+
public function convert($value): string
69+
{
70+
$document = $this->htmlDocumentFactory->create([ 'document' => $value ]);
71+
$body = $document->querySelector('body');
72+
$nodes = $document->querySelectorAll(self::QUERY_SELECTOR);
73+
74+
if ($nodes->count() > 0) {
75+
$styleMap = [];
76+
77+
foreach ($nodes as $node) {
78+
/* @var ElementInterface $node */
79+
$styleAttr = $node->getAttribute('style');
80+
81+
if ($styleAttr) {
82+
$generatedDataAttribute = $this->generateDataAttribute();
83+
$node->setAttribute(self::DATA_ATTRIBUTE, $generatedDataAttribute);
84+
$styleMap[$generatedDataAttribute] = $styleAttr; // Amend Array for Internal Style Generation
85+
$node->removeAttribute('style');
86+
}
87+
}
88+
89+
if (count($styleMap) > 0) {
90+
// Style Block Generation
91+
$style = $document->createElement(
92+
'style',
93+
$this->generateInternalStyles($styleMap)
94+
);
95+
$body->appendChild($style);
96+
97+
return $document->stripHtmlWrapperTags();
98+
} else {
99+
return $value;
100+
}
101+
}
102+
103+
return $value;
104+
}
105+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types = 1);
8+
9+
namespace Magento\PageBuilder\Setup\Patch\Data;
10+
11+
use Magento\Framework\DB\FieldDataConversionException;
12+
use Magento\Framework\Setup\Patch\DataPatchInterface;
13+
use Magento\PageBuilder\Setup\Converters\PageBuilderStripStyles;
14+
use Magento\PageBuilder\Setup\UpgradeContentHelper;
15+
16+
/**
17+
* Patch Upgrade Mechanism for Converting Inline Styles to Internal
18+
*/
19+
class UpgradePageBuilderStripStyles implements DataPatchInterface
20+
{
21+
/**
22+
* @var UpgradeContentHelper
23+
*/
24+
private $helper;
25+
26+
/**
27+
* @param UpgradeContentHelper $helper
28+
*/
29+
public function __construct(UpgradeContentHelper $helper)
30+
{
31+
$this->helper = $helper;
32+
}
33+
34+
/**
35+
* Upgrade
36+
*
37+
* @return void
38+
* @throws FieldDataConversionException
39+
*/
40+
public function apply(): void
41+
{
42+
$this->helper->upgrade([
43+
PageBuilderStripStyles::class
44+
]);
45+
}
46+
47+
/**
48+
* @inheritdoc
49+
*/
50+
public function getAliases(): array
51+
{
52+
return [];
53+
}
54+
55+
/**
56+
* @inheritdoc
57+
*/
58+
public static function getDependencies(): array
59+
{
60+
return [];
61+
}
62+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
10+
<actionGroup name="ValidateAdvancedConfigurationAllOptionsActionGroup">
11+
<annotations>
12+
<description value="Validates styles from Advanced configuration in content type settings"/>
13+
</annotations>
14+
<arguments>
15+
<argument name="page" defaultValue=""/>
16+
<argument name="alignment" defaultValue="PageBuilderAdvancedAlignmentPropertyDefault"/>
17+
<argument name="border" defaultValue="PageBuilderAdvancedBorderPropertyNone"/>
18+
<argument name="borderColor" defaultValue=""/>
19+
<argument name="borderWidth" defaultValue="PageBuilderAdvancedBorderWidthPropertyDefault"/>
20+
<argument name="borderRadius" defaultValue="PageBuilderAdvancedBorderRadiusDefaultProperty"/>
21+
<argument name="cssClasses" defaultValue=""/>
22+
<argument name="margin" defaultValue="PageBuilderMarginsPropertyDefault"/>
23+
<argument name="padding" defaultValue="PageBuilderPaddingPropertyDefault"/>
24+
<argument name="index" defaultValue="1" type="string"/>
25+
</arguments>
26+
<waitForElementVisible selector="{{page.base(index)}}" stepKey="waitForElementVisible"/>
27+
<executeJS function="return window.getComputedStyle(document.evaluate('{{page.advancedConfigurationPath(index)}}', document.body).iterateNext()).textAlign" stepKey="grabAlignmentValue"/>
28+
<assertEquals stepKey="assertAlignment">
29+
<expectedResult type="string">{{alignment.value}}</expectedResult>
30+
<actualResult type="variable">grabAlignmentValue</actualResult>
31+
</assertEquals>
32+
<executeJS function="return window.getComputedStyle(document.evaluate('{{page.advancedConfigurationPath(index)}}', document.body).iterateNext()).borderStyle" stepKey="grabBorderStyleValue"/>
33+
<assertEquals stepKey="assertBorderStyle">
34+
<expectedResult type="string">{{border.value}}</expectedResult>
35+
<actualResult type="variable">grabBorderStyleValue</actualResult>
36+
</assertEquals>
37+
<executeJS function="return window.getComputedStyle(document.evaluate('{{page.advancedConfigurationPath(index)}}', document.body).iterateNext()).borderColor" stepKey="grabBorderColorValue"/>
38+
<assertEquals stepKey="assertBorderColor">
39+
<expectedResult type="string">{{borderColor.rgb}}</expectedResult>
40+
<actualResult type="variable">grabBorderColorValue</actualResult>
41+
</assertEquals>
42+
<executeJS function="return window.getComputedStyle(document.evaluate('{{page.advancedConfigurationPath(index)}}', document.body).iterateNext()).borderWidth.replace(&quot;px&quot;, &quot;&quot;)" stepKey="grabBorderWidthValue"/>
43+
<assertEquals stepKey="assertBorderWidth">
44+
<expectedResult type="string">{{borderWidth.value}}</expectedResult>
45+
<actualResult type="variable">grabBorderWidthValue</actualResult>
46+
</assertEquals>
47+
<executeJS function="return window.getComputedStyle(document.evaluate('{{page.advancedConfigurationPath(index)}}', document.body).iterateNext()).borderRadius.replace(/px/g, &quot;&quot;)" stepKey="grabBorderRadiusValue"/>
48+
<assertEquals stepKey="assertBorderRadius">
49+
<expectedResult type="string">{{borderRadius.value}}</expectedResult>
50+
<actualResult type="variable">grabBorderRadiusValue</actualResult>
51+
</assertEquals>
52+
<waitForElementVisible selector="{{page.cssClasses(index, cssClasses.value)}}" stepKey="waitForCSSClassesVisible"/>
53+
<executeJS function="return window.getComputedStyle(document.evaluate('{{page.advancedConfigurationPath(index)}}', document.body).iterateNext()).margin.replace(/px/g, &quot;&quot;)" stepKey="grabMarginValue"/>
54+
<assertEquals stepKey="assertMargin">
55+
<expectedResult type="string">{{margin.value}}</expectedResult>
56+
<actualResult type="variable">grabMarginValue</actualResult>
57+
</assertEquals>
58+
<executeJS function="return window.getComputedStyle(document.evaluate('{{page.advancedConfigurationPath(index)}}', document.body).iterateNext()).padding.replace(/px/g, &quot;&quot;)" stepKey="grabPaddingValue"/>
59+
<assertEquals stepKey="assertPadding">
60+
<expectedResult type="string">{{padding.value}}</expectedResult>
61+
<actualResult type="variable">grabPaddingValue</actualResult>
62+
</assertEquals>
63+
</actionGroup>
64+
</actionGroups>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
10+
<actionGroup name="ValidateAdvancedConfigurationNotSetActionGroup" extends="ValidateAdvancedConfigurationWithAllUpdatedNotVisibleActionGroup">
11+
<annotations>
12+
<description value="Validates Advanced configuration was not set"/>
13+
</annotations>
14+
<waitForElementVisible selector="{{page.noCssClasses(index)}}" stepKey="waitForCSSClasses"/>
15+
<remove keyForRemoval="dontSeeCSSClasses"/>
16+
</actionGroup>
17+
</actionGroups>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
10+
<actionGroup name="ValidateAdvancedConfigurationWithAlignmentActionGroup" extends="ValidateAdvancedConfigurationAllOptionsActionGroup">
11+
<annotations>
12+
<description value="Validates styles from Advanced configuration in without border and css classes"/>
13+
</annotations>
14+
<executeJS function="return window.getComputedStyle(document.evaluate('{{page.advancedConfigurationPath(index)}}', document.body).iterateNext()).color" stepKey="grabColorValue" after="grabBorderColorValue"/>
15+
<remove keyForRemoval="assertBorderColor"/>
16+
<assertEquals stepKey="assertNoBorderColor" after="grabColorValue">
17+
<expectedResult type="variable">grabBorderColorValue</expectedResult>
18+
<actualResult type="variable">grabColorValue</actualResult>
19+
</assertEquals>
20+
<remove keyForRemoval="waitForCSSClassesVisible"/>
21+
<waitForElementVisible selector="{{page.noCssClasses(index)}}" stepKey="waitForNoCSSClassesVisible" after="grabBorderRadiusValue"/>
22+
</actionGroup>
23+
</actionGroups>

0 commit comments

Comments
 (0)