Completed
Push — master ( 1a1062...716332 )
by Lars
02:20 queued 01:14
created

src/CssToInlineStyles.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
declare(strict_types=1);
4
5
namespace voku\CssToInlineStyles;
6
7
use Symfony\Component\CssSelector\CssSelectorConverter;
8
use Symfony\Component\CssSelector\Exception\ExceptionInterface;
9
use voku\helper\HtmlDomParser;
10
11
/**
12
 * CSS to Inline Styles class
13
 *
14
 * @author     Tijs Verkoyen <[email protected]>
15
 */
16
class CssToInlineStyles
17
{
18
19
  /**
20
   * @var CssSelectorConverter
21
   */
22
  private $cssConverter;
23
24
  /**
25
   * regular expression: css media queries
26
   *
27
   * @var string
28
   */
29
  private static $cssMediaQueriesRegEx = '#@media\\s+(?:only\\s)?(?:[\\s{\\(]|screen|all)\\s?[^{]+{.*}\\s*}\\s*#misU';
30
31
  /**
32
   * regular expression: css charset
33
   *
34
   * @var string
35
   */
36
  private static $cssCharsetRegEx = '/@charset [\'"][^\'"]+[\'"];/i';
37
38
  /**
39
   * regular expression: conditional inline style tags
40
   *
41
   * @var string
42
   */
43
  private static $excludeConditionalInlineStylesBlockRegEx = '/<!--\[if.*<style.*-->/isU';
44
45
  /**
46
   * regular expression: inline style tags
47
   *
48
   * @var string
49
   */
50
  private static $styleTagRegEx = '|<style(?:\s.*)?>(.*)</style>|isU';
51
52
  /**
53
   * regular expression: html-comments without conditional comments
54
   *
55
   * @var string
56
   */
57
  private static $htmlCommentWithoutConditionalCommentRegEx = '|<!--(?!\[if).*-->|isU';
58
59
  /**
60
   * regular expression: style-tag with 'cleanup'-css-class
61
   *
62
   * @var string
63
   */
64
  private static $styleTagWithCleanupClassRegEx = '|<style[^>]+class="cleanup"[^>]*>.*</style>|isU';
65
66
  /**
67
   * regular expression: css-comments
68
   *
69
   * @var string
70
   */
71
  private static $styleCommentRegEx = '/\\/\\*.*\\*\\//sU';
72
73
  /**
74
   * The CSS to use.
75
   *
76
   * @var string
77
   */
78
  private $css;
79
80
  /**
81
   * The CSS-Media-Queries to use.
82
   *
83
   * @var string
84
   */
85
  private $css_media_queries;
86
87
  /**
88
   * Should the generated HTML be cleaned.
89
   *
90
   * @var bool
91
   */
92
  private $cleanup = false;
93
94
  /**
95
   * The encoding to use.
96
   *
97
   * @var string
98
   */
99
  private $encoding = 'UTF-8';
100
101
  /**
102
   * The HTML to process.
103
   *
104
   * @var string
105
   */
106
  private $html;
107
108
  /**
109
   * Use inline-styles block as CSS.
110
   *
111
   * @var bool
112
   */
113
  private $useInlineStylesBlock = false;
114
115
  /**
116
   * Use link block reference as CSS.
117
   *
118
   * @var bool
119
   */
120
  private $loadCSSFromHTML = false;
121
122
  /**
123
   * Strip original style tags.
124
   *
125
   * @var bool
126
   */
127
  private $stripOriginalStyleTags = false;
128
129
  /**
130
   * Exclude conditional inline-style blocks.
131
   *
132
   * @var bool
133
   */
134
  private $excludeConditionalInlineStylesBlock = true;
135
136
  /**
137
   * Exclude media queries from "$this->css" and keep media queries for inline-styles blocks.
138
   *
139
   * @var bool
140
   */
141
  private $excludeMediaQueries = true;
142
143
  /**
144
   * Exclude media queries from "$this->css" and keep media queries for inline-styles blocks.
145
   *
146
   * @var bool
147
   */
148
  private $excludeCssCharset = true;
149
150
  /**
151
   * Creates an instance, you could set the HTML and CSS here, or load it later.
152
   *
153
   * @param  null|string $html The HTML to process.
154 56
   * @param  null|string $css  The CSS to use.
155
   */
156 56
  public function __construct(string $html = null, string $css = null)
157 2
  {
158
    if (null !== $html) {
159
      $this->setHTML($html);
160 56
    }
161 2
162
    if (null !== $css) {
163
      $this->setCSS($css);
164 56
    }
165 56
166
    if (\class_exists(CssSelectorConverter::class)) {
167 56
      $this->cssConverter = new CssSelectorConverter();
168
    }
169
  }
170
171
  /**
172
   * Set HTML to process.
173
   *
174
   * @param string $html <p>The HTML to process.</p>
175
   *
176 54
   * @return $this
177
   */
178
  public function setHTML(string $html)
179 54
  {
180
    // strip style definitions, if we use css-class "cleanup" on a style-element
181 54
    $this->html = (string)\preg_replace(self::$styleTagWithCleanupClassRegEx, ' ', $html);
182
183
    return $this;
184
  }
185
186
  /**
187
   * Set CSS to use.
188
   *
189
   * @param string $css <p>The CSS to use.</p>
190
   *
191 49
   * @return $this
192
   */
193 49
  public function setCSS(string $css)
194
  {
195 49
    $this->css = $css;
196
197 49
    $this->css_media_queries = $this->getMediaQueries($css);
198
199
    return $this;
200
  }
201
202
  /**
203
   * Sort an array on the specificity element in an ascending way.
204
   *
205
   * INFO: Lower specificity will be sorted to the beginning of the array.
206
   *
207
   * @param Specificity[] $e1 The first element.
208
   * @param Specificity[] $e2 The second element.
209
   *
210 23
   * @return int
211
   */
212
  private static function sortOnSpecificity(array $e1, array $e2): int
213 23
  {
214
    // Compare the specificity
215
    $value = $e1['specificity']->compareTo($e2['specificity']);
0 ignored issues
show
$e2['specificity'] is of type object<voku\CssToInlineStyles\Specificity>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
216 23
217 18
    // if the specificity is the same, use the order in which the element appeared
218
    if (0 === $value) {
219
      $value = $e1['order'] - $e2['order'];
220 23
    }
221
222
    return $value;
223
  }
224
225
  /**
226
   * Converts the loaded HTML into an HTML-string with inline styles based on the loaded CSS.
227
   *
228
   * @param bool        $outputXHTML         [optional] <p>Should we output valid XHTML?</p>
229
   * @param int|null    $libXMLExtraOptions  [optional] <p>$libXMLExtraOptions Since PHP 5.4.0 and Libxml 2.6.0,
230
   *                                         you may also use the options parameter to specify additional
231
   *                                         Libxml parameters.
232
   *                                         </p>
233
   * @param string|null $path                [optional] <p>Set the path to your external css-files.</p>
234
   *
235
   * @return string
236 54
   *
237
   * @throws Exception
238
   */
239 54
  public function convert(bool $outputXHTML = false, int $libXMLExtraOptions = null, $path = null): string
240
  {
241
    // validate
242 54
    if (!$this->html) {
243 1
      throw new Exception('No HTML provided.');
244
    }
245
246
    // use local variables
247 53
    $css = $this->css;
248
249
    // create new HtmlDomParser
250 53
    $dom = HtmlDomParser::str_get_html($this->html, $libXMLExtraOptions);
251
252
    // check if there is some link css reference
253 53
    if ($this->loadCSSFromHTML) {
254 1
      foreach ($dom->find('link') as $node) {
255
256 1
        $file = ($path ?: __DIR__) . '/' . $node->getAttribute('href');
257
258 1
        if (\file_exists($file)) {
259 1
          $css .= \file_get_contents($file);
260
261
          // converting to inline css because we don't need/want to load css files, so remove the link
262 1
          $node->outertext = '';
263
        }
264
      }
265
    }
266
267
    // should we use inline style-block
268 53
    if ($this->useInlineStylesBlock) {
269
270 30
      if (true === $this->excludeConditionalInlineStylesBlock) {
271 26
        $this->html = \preg_replace(self::$excludeConditionalInlineStylesBlockRegEx, '', $this->html);
272
      }
273
274 30
      $css .= $this->getCssFromInlineHtmlStyleBlock($this->html);
275
    }
276
277
    // process css
278 53
    $cssRules = $this->processCSS($css);
279
280
    // create new XPath
281 53
    $xPath = $this->createXPath($dom->getDocument(), $cssRules);
282
283
    // strip original style tags if we need to
284 53
    if ($this->stripOriginalStyleTags === true) {
285 13
      $this->stripOriginalStyleTags($xPath);
286
    }
287
288
    // cleanup the HTML if we need to
289 53
    if (true === $this->cleanup) {
290 3
      $this->cleanupHTML($xPath);
291
    }
292
293
    // should we output XHTML?
294 53
    if (true === $outputXHTML) {
295 6
      return $dom->xml();
296
    }
297
298
    // just regular HTML 4.01 as it should be used in newsletters
299 48
    $html = $dom->html();
300
301
    // add css media queries from "$this->setCSS()"
302
    if (
303 48
        $this->stripOriginalStyleTags === false
304
        &&
305 48
        $this->css_media_queries
306
    ) {
307 3
      $html = \str_ireplace('</head>', "\n" . '<style type="text/css">' . "\n" . $this->css_media_queries . "\n" . '</style>' . "\n" . '</head>', $html);
308
    }
309
310 48
    return $html;
311
  }
312
313
  /**
314
   * get css from inline-html style-block
315
   *
316
   * @param string $html
317
   *
318
   * @return string
319
   */
320 32
  public function getCssFromInlineHtmlStyleBlock($html): string
321
  {
322
    // init var
323 32
    $css = '';
324 32
    $matches = [];
325
326 32
    $htmlNoComments = \preg_replace(self::$htmlCommentWithoutConditionalCommentRegEx, '', $html);
327
328
    // match the style blocks
329 32
    \preg_match_all(self::$styleTagRegEx, $htmlNoComments, $matches);
330
331
    // any style-blocks found?
332 32
    if (!empty($matches[1])) {
333
      // add
334 31
      foreach ($matches[1] as $match) {
335 31
        $css .= \trim($match) . "\n";
336
      }
337
    }
338
339 32
    return $css;
340
  }
341
342
  /**
343
   * Process the loaded CSS
344
   *
345
   * @param string $css
346
   *
347
   * @return array
348
   */
349 53
  private function processCSS($css): array
350
  {
351
    //reset current set of rules
352 53
    $cssRules = [];
353
354
    // init vars
355 53
    $css = (string)$css;
356
357 53
    $css = $this->doCleanup($css);
358
359
    // rules are splitted by }
360 53
    $rules = \explode('}', $css);
361
362
    // init var
363 53
    $i = 1;
364
365
    // loop rules
366 53
    foreach ($rules as $rule) {
367
      // split into chunks
368 53
      $chunks = \explode('{', $rule);
369
370
      // invalid rule?
371 53
      if (!isset($chunks[1])) {
372 53
        continue;
373
      }
374
375
      // set the selectors
376 40
      $selectors = \trim($chunks[0]);
377
378
      // get css-properties
379 40
      $cssProperties = \trim($chunks[1]);
380
381
      // split multiple selectors
382 40
      $selectors = \explode(',', $selectors);
383
384
      // loop selectors
385 40
      foreach ($selectors as $selector) {
386
        // cleanup
387 40
        $selector = \trim($selector);
388
389
        // build an array for each selector
390 40
        $ruleSet = [];
391
392
        // store selector
393 40
        $ruleSet['selector'] = $selector;
394
395
        // process the properties
396 40
        $ruleSet['properties'] = $this->processCSSProperties($cssProperties);
397
398
        // calculate specificity
399 40
        $ruleSet['specificity'] = Specificity::fromSelector($selector);
400
401
        // remember the order in which the rules appear
402 40
        $ruleSet['order'] = $i;
403
404
        // add into rules
405 40
        $cssRules[] = $ruleSet;
406
407
        // increment
408 40
        $i++;
409
      }
410
    }
411
412
    // sort based on specificity
413 53
    if (0 !== \count($cssRules)) {
414 40
      \usort($cssRules, [__CLASS__, 'sortOnSpecificity']);
415
    }
416
417 53
    return $cssRules;
418
  }
419
420
  /**
421
   * @param string $css
422
   *
423
   * @return string
424
   */
425 53
  private function doCleanup($css): string
426
  {
427
    // remove newlines & replace double quotes by single quotes
428 53
    $css = \str_replace(
429 53
        ["\r", "\n", '"'],
430 53
        ['', '', '\''],
431
        $css
432
    );
433
434
    // remove comments
435 53
    $css = \preg_replace(self::$styleCommentRegEx, '', $css);
436
437
    // remove spaces
438 53
    $css = \preg_replace('/\s\s+/', ' ', $css);
439
440
    // remove css charset
441 53
    if (true === $this->excludeCssCharset) {
442 53
      $css = $this->stripeCharsetInCss($css);
443
    }
444
445
    // remove css media queries
446 53
    if (true === $this->excludeMediaQueries) {
447 51
      $css = $this->stripeMediaQueries($css);
448
    }
449
450 53
    return (string)$css;
451
  }
452
453
  /**
454
   * remove css media queries from the string
455
   *
456
   * @param string $css
457
   *
458
   * @return string
459
   */
460 51
  private function stripeMediaQueries($css): string
461
  {
462
    // remove comments previously to matching media queries
463 51
    $css = \preg_replace(self::$styleCommentRegEx, '', $css);
464
465 51
    return (string)\preg_replace(self::$cssMediaQueriesRegEx, '', $css);
466
  }
467
468
  /**
469
   * get css media queries from the string
470
   *
471
   * @param string $css
472
   *
473
   * @return string
474
   */
475 49
  private function getMediaQueries($css): string
476
  {
477
    // remove comments previously to matching media queries
478 49
    $css = \preg_replace(self::$styleCommentRegEx, '', $css);
479
480 49
    \preg_match_all(self::$cssMediaQueriesRegEx, $css, $matches);
481
482 49
    return \implode("\n", $matches[0]);
483
  }
484
485
  /**
486
   * remove charset from the string
487
   *
488
   * @param string $css
489
   *
490
   * @return string
491
   */
492 53
  private function stripeCharsetInCss($css): string
493
  {
494 53
    return (string)\preg_replace(self::$cssCharsetRegEx, '', $css);
495
  }
496
497
  /**
498
   * Process the CSS-properties
499
   *
500
   * @return array
501
   *
502
   * @param  string $propertyString The CSS-properties.
503
   */
504 40
  private function processCSSProperties($propertyString): array
505
  {
506
    // split into chunks
507 40
    $properties = $this->splitIntoProperties($propertyString);
508
509
    // init var
510 40
    $pairs = [];
511
512
    // loop properties
513 40
    foreach ($properties as $property) {
514
      // split into chunks
515 40
      $chunks = \explode(':', $property, 2);
516
517
      // validate
518 40
      if (!isset($chunks[1])) {
519 34
        continue;
520
      }
521
522
      // cleanup
523 39
      $chunks[0] = \trim($chunks[0]);
524 39
      $chunks[1] = \trim($chunks[1]);
525
526
      // add to pairs array
527
      if (
528 39
          !isset($pairs[$chunks[0]])
529
          ||
530 39
          !\in_array($chunks[1], $pairs[$chunks[0]], true)
531
      ) {
532 39
        $pairs[$chunks[0]][] = $chunks[1];
533
      }
534
    }
535
536
    // sort the pairs
537 40
    \ksort($pairs);
538
539
    // return
540 40
    return $pairs;
541
  }
542
543
  /**
544
   * Split a style string into an array of properties.
545
   * The returned array can contain empty strings.
546
   *
547
   * @param string $styles ex: 'color:blue;font-size:12px;'
548
   *
549
   * @return array an array of strings containing css property ex: array('color:blue','font-size:12px')
550
   */
551 40
  private function splitIntoProperties($styles): array
552
  {
553 40
    $properties = \explode(';', $styles);
554 40
    $propertiesCount = \count($properties);
555
556
    /** @noinspection ForeachInvariantsInspection */
557 40
    for ($i = 0; $i < $propertiesCount; $i++) {
558
      // If next property begins with base64,
559
      // Then the ';' was part of this property (and we should not have split on it).
560
      if (
561 40
          isset($properties[$i + 1])
562
          &&
563 40
          \strpos($properties[$i + 1], 'base64,') !== false
564
      ) {
565 1
        $properties[$i] .= ';' . $properties[$i + 1];
566 1
        $properties[$i + 1] = '';
567 1
        ++$i;
568
      }
569
    }
570
571 40
    return $properties;
572
  }
573
574
  /**
575
   * create XPath
576
   *
577
   * @param \DOMDocument $document
578
   * @param array        $cssRules
579
   *
580
   * @return \DOMXPath
581
   */
582 53
  private function createXPath(\DOMDocument $document, array $cssRules): \DOMXPath
583
  {
584 53
    $propertyStorage = new \SplObjectStorage();
585 53
    $xPath = new \DOMXPath($document);
586
587
    // any rules?
588 53
    if (0 !== \count($cssRules)) {
589
      // loop rules
590 40
      foreach ($cssRules as $rule) {
591
592 40
        $ruleSelector = $rule['selector'];
593 40
        $ruleProperties = $rule['properties'];
594
595 40
        if (!$ruleSelector || !$ruleProperties) {
596 4
          continue;
597
        }
598
599
        try {
600 39
          $query = $this->cssConverter->toXPath($ruleSelector);
601 5
        } catch (ExceptionInterface $e) {
602 5
          $query = null;
603
        }
604
605
        // validate query
606 39
        if (null === $query) {
607 5
          continue;
608
        }
609
610
        // search elements
611 38
        $elements = $xPath->query($query);
612
613
        // validate elements
614 38
        if (false === $elements) {
615
          continue;
616
        }
617
618
        // loop found elements
619 38
        foreach ($elements as $element) {
620
621
          /**
622
           * @var $element \DOMElement
623
           */
624
625
          if (
626 38
              $ruleSelector == '*'
627
              &&
628
              (
629 2
                  $element->tagName == 'html'
630 2
                  || $element->tagName === 'title'
631 2
                  || $element->tagName == 'meta'
632 2
                  || $element->tagName == 'head'
633 2
                  || $element->tagName == 'style'
634 2
                  || $element->tagName == 'script'
635 38
                  || $element->tagName == 'link'
636
              )
637
          ) {
638 2
            continue;
639
          }
640
641
          // no styles stored?
642 38
          if (!isset($propertyStorage[$element])) {
643
644
            // init var
645 38
            $originalStyle = $element->attributes->getNamedItem('style');
646
647 38
            if ($originalStyle) {
648 12
              /** @noinspection PhpUndefinedFieldInspection */
649
              $originalStyle = (string)$originalStyle->value;
650 36
            } else {
651
              $originalStyle = '';
652
            }
653
654 38
            // store original styles
655
            $propertyStorage->attach($element, $originalStyle);
656
657 38
            // clear the styles
658
            $element->setAttribute('style', '');
659
          }
660
661 38
          // set attribute
662 38
          $propertiesString = $this->createPropertyChunks($element, $ruleProperties);
663 38
          if ($propertiesString) {
664
            $element->setAttribute('style', $propertiesString);
665
          }
666
        }
667
      }
668 40
669 38
      foreach ($propertyStorage as $element) {
670 38
        $originalStyle = $propertyStorage->getInfo();
671 12
        if ($originalStyle) {
672 12
          $originalStyles = $this->splitIntoProperties($originalStyle);
673
          $originalProperties = $this->splitStyleIntoChunks($originalStyles);
674
675 12
          // set attribute
676 12
          $propertiesString = $this->createPropertyChunks($element, $originalProperties);
677 38
          if ($propertiesString) {
678
            $element->setAttribute('style', $propertiesString);
679
          }
680
        }
681
      }
682
    }
683 53
684
    return $xPath;
685
  }
686
687
  /**
688
   * @param \DOMElement $element
689
   * @param array       $ruleProperties
690
   *
691
   * @return string
692 38
   */
693
  private function createPropertyChunks(\DOMElement $element, array $ruleProperties): string
694
  {
695 38
    // init var
696
    $properties = [];
697
698 38
    // get current styles
699
    $stylesAttribute = $element->attributes->getNamedItem('style');
700
701 38
    // any styles defined before?
702
    if (null !== $stylesAttribute) {
703 38
      // get value for the styles attribute
704
      /** @noinspection PhpUndefinedFieldInspection */
705
      $definedStyles = (string)$stylesAttribute->value;
706 38
707
      // split into properties
708 38
      $definedProperties = $this->splitIntoProperties($definedStyles);
709
710
      $properties = $this->splitStyleIntoChunks($definedProperties);
711
    }
712 38
713
    // add new properties into the list
714
    foreach ($ruleProperties as $key => $value) {
715
      // If one of the rules is already set and is !important, don't apply it,
716 38
      // except if the new rule is also important.
717
      if (
718 12
          !isset($properties[$key])
719
          ||
720 38
          false === \stripos($properties[$key], '!important')
721
          ||
722 38
          false !== \stripos(\implode('', (array)$value), '!important')
723 38
      ) {
724
        unset($properties[$key]);
725
        $properties[$key] = $value;
726
      }
727
    }
728 38
729
    // build string
730
    $propertyChunks = [];
731 38
732 38
    // build chunks
733 38
    foreach ($properties as $key => $values) {
734
      foreach ((array)$values as $value) {
735
        $propertyChunks[] = $key . ': ' . $value . ';';
736
      }
737 38
    }
738
739
    return \implode(' ', $propertyChunks);
740
  }
741
742
  /**
743
   * @param array $definedProperties
744
   *
745 38
   * @return array
746
   */
747
  private function splitStyleIntoChunks(array $definedProperties): array
748 38
  {
749
    // init var
750
    $properties = [];
751 38
752
    // loop properties
753
    foreach ($definedProperties as $property) {
754 38
      // validate property
755
      if (
756 38
          !$property
757
          ||
758 38
          \strpos($property, ':') === false
759
      ) {
760
        continue;
761
      }
762 20
763
      // split into chunks
764
      $chunks = \explode(':', \trim($property), 2);
765 20
766
      // validate
767
      if (!isset($chunks[1])) {
768
        continue;
769
      }
770 20
771
      // loop chunks
772
      $properties[$chunks[0]] = \trim($chunks[1]);
773 38
    }
774
775
    return $properties;
776
  }
777
778
  /**
779
   * Strip style tags into the generated HTML.
780
   *
781 13
   * @param  \DOMXPath $xPath The DOMXPath for the entire document.
782
   */
783
  private function stripOriginalStyleTags(\DOMXPath $xPath)
784 13
  {
785 13
    // get all style tags
786 12
    $nodes = $xPath->query('descendant-or-self::style');
787
    foreach ($nodes as $node) {
788
      if ($this->excludeMediaQueries === true) {
789 11
790
        // remove comments previously to matching media queries
791
        $node->nodeValue = \preg_replace(self::$styleCommentRegEx, '', $node->nodeValue);
792 11
793
        // search for Media Queries
794
        \preg_match_all(self::$cssMediaQueriesRegEx, $node->nodeValue, $mqs);
795 11
796
        // replace the nodeValue with just the Media Queries
797
        $node->nodeValue = \implode("\n", $mqs[0]);
798
799 12
      } else {
800
        // remove the entire style tag
801
        $node->parentNode->removeChild($node);
802 13
      }
803
    }
804
  }
805
806
  /**
807
   * Remove id and class attributes.
808
   *
809 3
   * @param  \DOMXPath $xPath The DOMXPath for the entire document.
810
   */
811 3
  private function cleanupHTML(\DOMXPath $xPath)
812 3
  {
813 3
    $nodes = $xPath->query('//@class | //@id');
814
    foreach ($nodes as $node) {
815 3
      $node->ownerElement->removeAttributeNode($node);
816
    }
817
  }
818
819
  /**
820
   * Should the IDs and classes be removed?
821
   *
822
   * @param  bool $on Should we enable cleanup?
823
   *
824 3
   * @return $this
825
   */
826 3
  public function setCleanup(bool $on = true)
827
  {
828 3
    $this->cleanup = $on;
829
830
    return $this;
831
  }
832
833
  /**
834
   * Set the encoding to use with the DOMDocument.
835
   *
836
   * @param  string $encoding The encoding to use.
837
   *
838
   * @return $this
839
   *
840
   * @deprecated Doesn't have any effect
841
   */
842
  public function setEncoding(string $encoding)
843
  {
844
    $this->encoding = $encoding;
845
846
    return $this;
847
  }
848
849
  /**
850
   * Set use of inline styles block.
851
   *
852
   * Info: If this is enabled the class will use the style-block in the HTML.
853
   *
854
   * @param  bool $on Should we process inline styles?
855
   *
856 30
   * @return $this
857
   */
858 30
  public function setUseInlineStylesBlock(bool $on = true)
859
  {
860 30
    $this->useInlineStylesBlock = $on;
861
862
    return $this;
863
  }
864
865
  /**
866
   * Set use of inline link block.
867
   *
868
   * Info: If this is enabled the class will use the links reference in the HTML.
869
   *
870
   * @param  bool [optional] $on Should we process link styles?
871
   *
872 2
   * @return $this
873
   */
874 2
  public function setLoadCSSFromHTML(bool $on = true)
875
  {
876 2
    $this->loadCSSFromHTML = $on;
877
878
    return $this;
879
  }
880
881
  /**
882
   * Set strip original style tags.
883
   *
884
   * Info: If this is enabled the class will remove all style tags in the HTML.
885
   *
886
   * @param  bool $on Should we process inline styles?
887
   *
888 17
   * @return $this
889
   */
890 17
  public function setStripOriginalStyleTags(bool $on = true)
891
  {
892 17
    $this->stripOriginalStyleTags = $on;
893
894
    return $this;
895
  }
896
897
  /**
898
   * Set exclude media queries.
899
   *
900
   * Info: If this is enabled the media queries will be removed before inlining the rules.
901
   *
902
   * WARNING: If you use inline styles block "<style>" the this option will keep the media queries.
903
   *
904
   * @param bool $on
905
   *
906 15
   * @return $this
907
   */
908 15
  public function setExcludeMediaQueries(bool $on = true)
909
  {
910 15
    $this->excludeMediaQueries = $on;
911
912
    return $this;
913
  }
914
915
  /**
916
   * Set exclude charset.
917
   *
918
   * @param bool $on
919
   *
920 1
   * @return $this
921
   */
922 1
  public function setExcludeCssCharset(bool $on = true)
923
  {
924 1
    $this->excludeCssCharset = $on;
925
926
    return $this;
927
  }
928
929
  /**
930
   * Set exclude conditional inline-style blocks.
931
   *
932
   * e.g.: <!--[if gte mso 9]><style>.foo { bar } </style><![endif]-->
933
   *
934
   * @param bool $on
935
   *
936 6
   * @return $this
937
   */
938 6
  public function setExcludeConditionalInlineStylesBlock(bool $on = true)
939
  {
940 6
    $this->excludeConditionalInlineStylesBlock = $on;
941
942
    return $this;
943
  }
944
}
945