Merge pull request #781 from mailpoet/form_css_fix
Fixes some from CSS styles not being saved [MAILPOET-784]
This commit is contained in:
@ -14,7 +14,8 @@
|
|||||||
"swiftmailer/swiftmailer": "^5.4",
|
"swiftmailer/swiftmailer": "^5.4",
|
||||||
"mtdowling/cron-expression": "^1.1",
|
"mtdowling/cron-expression": "^1.1",
|
||||||
"nesbot/carbon": "^1.21",
|
"nesbot/carbon": "^1.21",
|
||||||
"soundasleep/html2text": "dev-master"
|
"soundasleep/html2text": "dev-master",
|
||||||
|
"sabberworm/php-css-parser": "^8.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"codeception/codeception": "*",
|
"codeception/codeception": "*",
|
||||||
@ -37,4 +38,4 @@
|
|||||||
"post-update-cmd": "rm -rf vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/PHPCompatibility; cp -rpd vendor/wimg/php-compatibility vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/PHPCompatibility",
|
"post-update-cmd": "rm -rf vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/PHPCompatibility; cp -rpd vendor/wimg/php-compatibility vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/PHPCompatibility",
|
||||||
"post-install-cmd": "rm -rf vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/PHPCompatibility; cp -rpd vendor/wimg/php-compatibility vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/PHPCompatibility"
|
"post-install-cmd": "rm -rf vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/PHPCompatibility; cp -rpd vendor/wimg/php-compatibility vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/PHPCompatibility"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
606
composer.lock
generated
606
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -35,7 +35,7 @@ class Renderer {
|
|||||||
&& strlen(trim($form['styles'])) > 0) {
|
&& strlen(trim($form['styles'])) > 0) {
|
||||||
return strip_tags($form['styles']);
|
return strip_tags($form['styles']);
|
||||||
} else {
|
} else {
|
||||||
return Util\Styles::$defaults;
|
return Util\Styles::$default_styles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace MailPoet\Form\Util;
|
namespace MailPoet\Form\Util;
|
||||||
|
|
||||||
class Styles {
|
use Sabberworm\CSS\Parser as CSSParser;
|
||||||
private $_stylesheet = null;
|
|
||||||
private $_styles = array();
|
|
||||||
|
|
||||||
static $defaults =<<<EOL
|
class Styles {
|
||||||
|
public $styles;
|
||||||
|
static $default_styles = <<<EOL
|
||||||
/* form */
|
/* form */
|
||||||
.mailpoet_form {
|
.mailpoet_form {
|
||||||
|
|
||||||
@ -49,130 +49,25 @@ class Styles {
|
|||||||
EOL;
|
EOL;
|
||||||
|
|
||||||
function __construct($stylesheet = null) {
|
function __construct($stylesheet = null) {
|
||||||
// store raw styles
|
$this->stylesheet = $stylesheet;
|
||||||
$this->setStylesheet($stylesheet);
|
|
||||||
|
|
||||||
// extract rules/properties
|
|
||||||
$this->parseStyles();
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function render($prefix = '') {
|
function render($prefix = '') {
|
||||||
$styles = $this->getStyles();
|
if(!$this->stylesheet) return;
|
||||||
if(!empty($styles)) {
|
$styles = new CSSParser($this->stylesheet);
|
||||||
$output = array();
|
$styles = $styles->parse();
|
||||||
|
$formatted_styles = array();
|
||||||
// add prefix on each selector
|
foreach($styles->getAllDeclarationBlocks() as $style_declaration) {
|
||||||
foreach($styles as $style) {
|
$selectors = array_map(function($selector) use ($prefix) {
|
||||||
// check if selector is an array
|
return sprintf('%s %s', $prefix, $selector->__toString());
|
||||||
if(is_array($style['selector'])) {
|
}, $style_declaration->getSelectors());
|
||||||
$selector = join(",\n", array_map(function($value) use ($prefix) {
|
$selectors = implode(', ', $selectors);
|
||||||
return $prefix.' '.$value;
|
$rules = array_map(function($rule) {
|
||||||
}, $style['selector']));
|
return $rule->__toString();
|
||||||
} else {
|
}, $style_declaration->getRules());
|
||||||
$selector = $prefix.' '.$style['selector'];
|
$rules = sprintf('{ %s }', implode(' ', $rules));
|
||||||
}
|
$formatted_styles[] = sprintf('%s %s', $selectors, $rules);
|
||||||
|
|
||||||
// format selector
|
|
||||||
$output[] = $selector . ' {';
|
|
||||||
|
|
||||||
// format rules
|
|
||||||
if(!empty($style['rules'])) {
|
|
||||||
$rules = join("\n", array_map(function($rule) {
|
|
||||||
return "\t".$rule['property'] . ': ' . $rule['value'].';';
|
|
||||||
}, $style['rules']));
|
|
||||||
|
|
||||||
$output[] = $rules;
|
|
||||||
}
|
|
||||||
|
|
||||||
$output[] = '}';
|
|
||||||
}
|
|
||||||
|
|
||||||
return join("\n", $output);
|
|
||||||
}
|
}
|
||||||
|
return implode(PHP_EOL, $formatted_styles);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private function setStylesheet($stylesheet) {
|
|
||||||
$this->_stylesheet = $this->stripComments($stylesheet);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function stripComments($stylesheet) {
|
|
||||||
// remove comments
|
|
||||||
return preg_replace('!/\*.*?\*/!s', '', $stylesheet);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getStylesheet() {
|
|
||||||
return $this->_stylesheet;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function setStyles($styles) {
|
|
||||||
$this->_styles = $styles;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getStyles() {
|
|
||||||
return $this->_styles;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function parseStyles() {
|
|
||||||
if($this->getStylesheet() !== null) {
|
|
||||||
// extract selectors and rules
|
|
||||||
preg_match_all( '/(?ims)([a-z0-9\s\.\:#_\-@,]+)\{([^\}]*)\}/',
|
|
||||||
$this->getStylesheet(),
|
|
||||||
$matches
|
|
||||||
);
|
|
||||||
$selectors = $matches[1];
|
|
||||||
$rules = $matches[2];
|
|
||||||
|
|
||||||
// extracted styles
|
|
||||||
$styles = array();
|
|
||||||
|
|
||||||
// loop through each selector
|
|
||||||
foreach($selectors as $index => $selector) {
|
|
||||||
// trim selector
|
|
||||||
$selector = trim($selector);
|
|
||||||
// get selector rules
|
|
||||||
$selector_rules = array_filter(array_map(function($value) {
|
|
||||||
if(strlen(trim($value)) > 0) {
|
|
||||||
// split property / value
|
|
||||||
$pair = explode(':', trim($value));
|
|
||||||
if(isset($pair[0]) && isset($pair[1])) {
|
|
||||||
return array(
|
|
||||||
'property' => $pair[0],
|
|
||||||
'value' => $pair[1]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, explode(';', trim($rules[$index]))));
|
|
||||||
|
|
||||||
// check if we have multiple selectors
|
|
||||||
if(strpos($selector, ',') !== false) {
|
|
||||||
$selectors_array = array_filter(array_map(function($value) {
|
|
||||||
return trim($value);
|
|
||||||
}, explode(',', $selector)));
|
|
||||||
|
|
||||||
// multiple selectors
|
|
||||||
$styles[$index] = array(
|
|
||||||
'selector' => $selectors_array,
|
|
||||||
'rules' => $selector_rules
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// it's a single selector
|
|
||||||
$styles[$index] = array(
|
|
||||||
'selector' => $selector,
|
|
||||||
'rules' => $selector_rules
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->setStyles($styles);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function __toString() {
|
|
||||||
$this->stripComments();
|
|
||||||
return $this->render();
|
|
||||||
}
|
|
||||||
}
|
|
28
tests/unit/Form/Util/StylesTest.php
Normal file
28
tests/unit/Form/Util/StylesTest.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use MailPoet\Form\Util\Styles;
|
||||||
|
|
||||||
|
class StylesTest extends MailPoetTest {
|
||||||
|
function testItSetsDefaultCSSStyles() {
|
||||||
|
expect(property_exists('MailPoet\Form\Util\Styles', 'default_styles'))->true();
|
||||||
|
expect(Styles::$default_styles)->notEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItProcessesAndRendersStyles() {
|
||||||
|
$stylesheet = '
|
||||||
|
/* some comment */
|
||||||
|
input[name=first_name] , input.some_class, .some_class { color: red ; background: blue; } .another_style { fonT-siZe: 20px }
|
||||||
|
';
|
||||||
|
$style_processer = new Styles($stylesheet);
|
||||||
|
$extracted_and_prefixed_styles = $style_processer->render($prefix = 'mailpoet');
|
||||||
|
// 1. comments should be stripped
|
||||||
|
// 2. each selector should be refixed
|
||||||
|
// 3. multiple spaces, missing semicolons should be fixed
|
||||||
|
// 4. each style should be on a separate line
|
||||||
|
$expected_result = <<<EOL
|
||||||
|
mailpoet input[name=first_name], mailpoet input.some_class, mailpoet .some_class { color: red; background: blue; }
|
||||||
|
mailpoet .another_style { font-size: 20px; }
|
||||||
|
EOL;
|
||||||
|
expect($extracted_and_prefixed_styles)->equals($expected_result);
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,8 @@ use MailPoet\Util\License\License;
|
|||||||
|
|
||||||
class LicenseTest extends MailPoetTest {
|
class LicenseTest extends MailPoetTest {
|
||||||
function testItGetsLicense() {
|
function testItGetsLicense() {
|
||||||
expect(License::getLicense())->false();
|
if(defined('MAILPOET_PREMIUM_LICENSE')) return;
|
||||||
expect(License::getLicense('valid'))->equals('valid');
|
expect(License::getLicense())->false();
|
||||||
|
expect(License::getLicense('valid'))->equals('valid');
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user