Completed
Push — master ( 33d351...8596bd )
by Lars
14:12
created

CssToInlineStyles::splitIntoProperties()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 4

Importance

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

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
221
  {
222
    // init
223 52
    $outputXHTML = (bool)$outputXHTML;
224
225
    // validate
226 52
    if (!$this->html) {
227 1
      throw new Exception('No HTML provided.');
228
    }
229
230
    // use local variables
231 51
    $css = $this->css;
232
233
    // create new HtmlDomParser
234 51
    $dom = HtmlDomParser::str_get_html($this->html);
0 ignored issues
show
Unused Code introduced by
The call to HtmlDomParser::str_get_html() has too many arguments starting with $this->html.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
235
236
    // check if there is some link css reference
237 51
    if ($this->loadCSSFromHTML) {
238 1
      foreach ($dom->find('link') as $node) {
239
240 1
        $file = ($path ?: __DIR__) . '/' . $node->getAttribute('href');
241
242 1
        if (file_exists($file)) {
243 1
          $css .= file_get_contents($file);
244
245
          // converting to inline css because we don't need/want to load css files, so remove the link
246 1
          $node->outertext = '';
247 1
        }
248 1
      }
249 1
    }
250
251
    // should we use inline style-block
252 51
    if ($this->useInlineStylesBlock) {
253
254 29
      if (true === $this->excludeConditionalInlineStylesBlock) {
255 25
        $this->html = preg_replace(self::$excludeConditionalInlineStylesBlockRegEx, '', $this->html);
256 25
      }
257
258 29
      $css .= $this->getCssFromInlineHtmlStyleBlock($this->html);
259 29
    }
260
261
    // process css
262 51
    $cssRules = $this->processCSS($css);
263
264
    // create new XPath
265 51
    $xPath = $this->createXPath($dom->getDocument(), $cssRules);
266
267
    // strip original style tags if we need to
268 51
    if ($this->stripOriginalStyleTags === true) {
269 13
      $this->stripOriginalStyleTags($xPath);
270 13
    }
271
272
    // cleanup the HTML if we need to
273 51
    if (true === $this->cleanup) {
274 3
      $this->cleanupHTML($xPath);
275 3
    }
276
277
    // should we output XHTML?
278 51
    if (true === $outputXHTML) {
279 6
      return $dom->xml();
280
    }
281
282
    // just regular HTML 4.01 as it should be used in newsletters
283 46
    return $dom->html();
284
  }
285
286
  /**
287
   * get css from inline-html style-block
288
   *
289
   * @param string $html
290
   *
291
   * @return string
292
   */
293 31
  public function getCssFromInlineHtmlStyleBlock($html)
294
  {
295
    // init var
296 31
    $css = '';
297 31
    $matches = array();
298
299
    // match the style blocks
300 31
    preg_match_all(self::$styleTagRegEx, $html, $matches);
301
302
    // any style-blocks found?
303 31
    if (!empty($matches[1])) {
304
      // add
305 30
      foreach ($matches[1] as $match) {
306 30
        $css .= trim($match) . "\n";
307 30
      }
308 30
    }
309
310 31
    return $css;
311
  }
312
313
  /**
314
   * Process the loaded CSS
315
   *
316
   * @param string $css
317
   *
318
   * @return array
319
   */
320 51
  private function processCSS($css)
321
  {
322
    //reset current set of rules
323 51
    $cssRules = array();
324
325
    // init vars
326 51
    $css = (string)$css;
327
328 51
    $css = $this->doCleanup($css);
329
330
    // rules are splitted by }
331 51
    $rules = (array)explode('}', $css);
332
333
    // init var
334 51
    $i = 1;
335
336
    // loop rules
337 51
    foreach ($rules as $rule) {
338
      // split into chunks
339 51
      $chunks = explode('{', $rule);
340
341
      // invalid rule?
342 51
      if (!isset($chunks[1])) {
343 51
        continue;
344
      }
345
346
      // set the selectors
347 38
      $selectors = trim($chunks[0]);
348
349
      // get cssProperties
350 38
      $cssProperties = trim($chunks[1]);
351
352
      // split multiple selectors
353 38
      $selectors = (array)explode(',', $selectors);
354
355
      // loop selectors
356 38
      foreach ($selectors as $selector) {
357
        // cleanup
358 38
        $selector = trim($selector);
359
360
        // build an array for each selector
361 38
        $ruleSet = array();
362
363
        // store selector
364 38
        $ruleSet['selector'] = $selector;
365
366
        // process the properties
367 38
        $ruleSet['properties'] = $this->processCSSProperties($cssProperties);
368
369
370
        // calculate specificity
371 38
        $ruleSet['specificity'] = Specificity::fromSelector($selector);
372
373
        // remember the order in which the rules appear
374 38
        $ruleSet['order'] = $i;
375
376
        // add into rules
377 38
        $cssRules[] = $ruleSet;
378
379
        // increment
380 38
        $i++;
381 38
      }
382 51
    }
383
384
    // sort based on specificity
385 51
    if (0 !== count($cssRules)) {
386 38
      usort($cssRules, array(__CLASS__, 'sortOnSpecificity'));
387 38
    }
388
389 51
    return $cssRules;
390
  }
391
392
  /**
393
   * @param string $css
394
   *
395
   * @return string
396
   */
397 51
  private function doCleanup($css)
398
  {
399
    // remove newlines & replace double quotes by single quotes
400 51
    $css = str_replace(
401 51
        array("\r", "\n", '"'),
402 51
        array('', '', '\''),
403
        $css
404 51
    );
405
406
    // remove comments
407 51
    $css = preg_replace(self::$styleCommentRegEx, '', $css);
408
409
    // remove spaces
410 51
    $css = preg_replace('/\s\s+/', ' ', $css);
411
412
    // remove css charset
413 51
    if (true === $this->excludeCssCharset) {
414 51
      $css = $this->stripeCharsetInCss($css);
415 51
    }
416
417
    // remove css media queries
418 51
    if (true === $this->excludeMediaQueries) {
419 50
      $css = $this->stripeMediaQueries($css);
420 50
    }
421
422 51
    return (string)$css;
423
  }
424
425
  /**
426
   * remove css media queries from the string
427
   *
428
   * @param string $css
429
   *
430
   * @return string
431
   */
432 50
  private function stripeMediaQueries($css)
433
  {
434
    // remove comments previously to matching media queries
435 50
    $css = preg_replace(self::$styleCommentRegEx, '', $css);
436
437 50
    return (string)preg_replace(self::$cssMediaQueriesRegEx, '', $css);
438
  }
439
440
  /**
441
   * remove charset from the string
442
   *
443
   * @param string $css
444
   *
445
   * @return string
446
   */
447 51
  private function stripeCharsetInCss($css)
448
  {
449 51
    return (string)preg_replace(self::$cssCharsetRegEx, '', $css);
450
  }
451
452
  /**
453
   * Process the CSS-properties
454
   *
455
   * @return array
456
   *
457
   * @param  string $propertyString The CSS-properties.
458
   */
459 38
  private function processCSSProperties($propertyString)
460
  {
461
    // split into chunks
462 38
    $properties = $this->splitIntoProperties($propertyString);
463
464
    // init var
465 38
    $pairs = array();
466
467
    // loop properties
468 38
    foreach ($properties as $property) {
469
      // split into chunks
470 38
      $chunks = (array)explode(':', $property, 2);
471
472
      // validate
473 38
      if (!isset($chunks[1])) {
474 32
        continue;
475
      }
476
477
      // cleanup
478 37
      $chunks[0] = trim($chunks[0]);
479 37
      $chunks[1] = trim($chunks[1]);
480
481
      // add to pairs array
482
      if (
483 37
          !isset($pairs[$chunks[0]])
484 37
          ||
485 4
          !in_array($chunks[1], $pairs[$chunks[0]], true)
486 37
      ) {
487 37
        $pairs[$chunks[0]][] = $chunks[1];
488 37
      }
489 38
    }
490
491
    // sort the pairs
492 38
    ksort($pairs);
493
494
    // return
495 38
    return $pairs;
496
  }
497
498
  /**
499
   * Split a style string into an array of properties.
500
   * The returned array can contain empty strings.
501
   *
502
   * @param string $styles ex: 'color:blue;font-size:12px;'
503
   *
504
   * @return array an array of strings containing css property ex: array('color:blue','font-size:12px')
505
   */
506 38
  private function splitIntoProperties($styles)
507
  {
508 38
    $properties = (array)explode(';', $styles);
509 38
    $propertiesCount = count($properties);
510
511
    /** @noinspection ForeachInvariantsInspection */
512 38
    for ($i = 0; $i < $propertiesCount; $i++) {
513
      // If next property begins with base64,
514
      // Then the ';' was part of this property (and we should not have split on it).
515
      if (
516 38
          isset($properties[$i + 1])
517 38
          &&
518 31
          strpos($properties[$i + 1], 'base64,') !== false
519 38
      ) {
520 1
        $properties[$i] .= ';' . $properties[$i + 1];
521 1
        $properties[$i + 1] = '';
522 1
        ++$i;
523 1
      }
524 38
    }
525
526 38
    return $properties;
527
  }
528
529
  /**
530
   * create XPath
531
   *
532
   * @param \DOMDocument $document
533
   * @param array        $cssRules
534
   *
535
   * @return \DOMXPath
536
   */
537 51
  private function createXPath(\DOMDocument $document, array $cssRules)
538
  {
539 51
    $propertyStorage = new \SplObjectStorage();
540 51
    $xPath = new \DOMXPath($document);
541
542
    // any rules?
543 51
    if (0 !== count($cssRules)) {
544
      // loop rules
545 38
      foreach ($cssRules as $rule) {
546
547 38
        $ruleSelector = $rule['selector'];
548 38
        $ruleProperties = $rule['properties'];
549
550 38
        if (!$ruleSelector || !$ruleProperties) {
551 3
          continue;
552
        }
553
554
        try {
555 37
          $query = $this->cssConverter->toXPath($ruleSelector);
556 37
        } catch (ExceptionInterface $e) {
557 4
          $query = null;
558
        }
559
560
        // validate query
561 37
        if (null === $query) {
562 4
          continue;
563
        }
564
565
        // search elements
566 36
        $elements = $xPath->query($query);
567
568
        // validate elements
569 36
        if (false === $elements) {
570
          continue;
571
        }
572
573
        // loop found elements
574 36
        foreach ($elements as $element) {
575
576
          /**
577
           * @var $element \DOMElement
578
           */
579
580
          if (
581
              $ruleSelector == '*'
582 36
              &&
583
              (
584 1
                  $element->tagName == 'html'
585 1
                  || $element->tagName === 'title'
586 1
                  || $element->tagName == 'meta'
587 1
                  || $element->tagName == 'head'
588 1
                  || $element->tagName == 'style'
589 1
                  || $element->tagName == 'script'
590 1
                  || $element->tagName == 'link'
591 1
              )
592 36
          ) {
593 1
            continue;
594
          }
595
596
          // no styles stored?
597 36
          if (!isset($propertyStorage[$element])) {
598
599
            // init var
600 36
            $originalStyle = $element->attributes->getNamedItem('style');
601
602 36
            if ($originalStyle) {
603 10
              $originalStyle = $originalStyle->value;
0 ignored issues
show
Bug introduced by
The property value does not seem to exist in DOMNode.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
604 10
            } else {
605 33
              $originalStyle = '';
606
            }
607
608
            // store original styles
609 36
            $propertyStorage->attach($element, $originalStyle);
610
611
            // clear the styles
612 36
            $element->setAttribute('style', '');
613 36
          }
614
615
          // set attribute
616 36
          $propertiesString = $this->createPropertyChunks($element, $ruleProperties);
617 36
          if ($propertiesString) {
618 36
            $element->setAttribute('style', $propertiesString);
619 36
          }
620 36
        }
621 38
      }
622
623
      //var_dump($propertyStorage);
624
625 38
      foreach ($propertyStorage as $element) {
626 36
        $originalStyle = $propertyStorage->getInfo();
627
628 36
        if ($originalStyle) {
629 10
          $originalStyles = $this->splitIntoProperties($originalStyle);
630
631 10
          $originalProperties = $this->splitStyleIntoChunks($originalStyles);
632
633
          // set attribute
634 10
          $propertiesString = $this->createPropertyChunks($element, $originalProperties);
635 10
          if ($propertiesString) {
636 10
            $element->setAttribute('style', $propertiesString);
637 10
          }
638 10
        }
639 38
      }
640 38
    }
641
642 51
    return $xPath;
643
  }
644
645
  /**
646
   * @param \DOMElement $element
647
   * @param array       $ruleProperties
648
   *
649
   * @return string
650
   */
651 36
  private function createPropertyChunks(\DOMElement $element, array $ruleProperties)
652
  {
653
    // init var
654 36
    $properties = array();
655
656
    // get current styles
657 36
    $stylesAttribute = $element->attributes->getNamedItem('style');
658
659
    // any styles defined before?
660 36
    if (null !== $stylesAttribute) {
661
      // get value for the styles attribute
662 36
      $definedStyles = (string)$stylesAttribute->value;
0 ignored issues
show
Bug introduced by
The property value does not seem to exist in DOMNode.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
663
664
      // split into properties
665 36
      $definedProperties = $this->splitIntoProperties($definedStyles);
666
667 36
      $properties = $this->splitStyleIntoChunks($definedProperties);
668 36
    }
669
670
    // add new properties into the list
671 36
    foreach ($ruleProperties as $key => $value) {
672
      // If one of the rules is already set and is !important, don't apply it,
673
      // except if the new rule is also important.
674
      if (
675 36
          !isset($properties[$key])
676 36
          ||
677 11
          false === stripos($properties[$key], '!important')
678 11
          ||
679 6
          false !== stripos(implode('', (array)$value), '!important')
680 36
      ) {
681 36
        $properties[$key] = $value;
682 36
      }
683 36
    }
684
685
    // build string
686 36
    $propertyChunks = array();
687
688
    // build chunks
689 36
    foreach ($properties as $key => $values) {
690 36
      foreach ((array)$values as $value) {
691 36
        $propertyChunks[] = $key . ': ' . $value . ';';
692 36
      }
693 36
    }
694
695 36
    return implode(' ', $propertyChunks);
696
  }
697
698
  /**
699
   * @param array $definedProperties
700
   *
701
   * @return array
702
   */
703 36
  private function splitStyleIntoChunks(array $definedProperties)
704
  {
705
    // init var
706 36
    $properties = array();
707
708
    // loop properties
709 36
    foreach ($definedProperties as $property) {
710
      // validate property
711
      if (
712
          !$property
713 36
          ||
714 18
          strpos($property, ':') === false
715 36
      ) {
716 36
        continue;
717
      }
718
719
      // split into chunks
720 18
      $chunks = (array)explode(':', trim($property), 2);
721
722
      // validate
723 18
      if (!isset($chunks[1])) {
724
        continue;
725
      }
726
727
      // loop chunks
728 18
      $properties[$chunks[0]] = trim($chunks[1]);
729 36
    }
730
731 36
    return $properties;
732
  }
733
734
  /**
735
   * Strip style tags into the generated HTML.
736
   *
737
   * @param  \DOMXPath $xPath The DOMXPath for the entire document.
738
   */
739 13
  private function stripOriginalStyleTags(\DOMXPath $xPath)
740
  {
741
    // get all style tags
742 13
    $nodes = $xPath->query('descendant-or-self::style');
743 13
    foreach ($nodes as $node) {
744 12
      if ($this->excludeMediaQueries === true) {
745
746
        // remove comments previously to matching media queries
747 11
        $node->nodeValue = preg_replace(self::$styleCommentRegEx, '', $node->nodeValue);
748
749
        // search for Media Queries
750 11
        preg_match_all(self::$cssMediaQueriesRegEx, $node->nodeValue, $mqs);
751
752
        // replace the nodeValue with just the Media Queries
753 11
        $node->nodeValue = implode("\n", $mqs[0]);
754
755 11
      } else {
756
        // remove the entire style tag
757 1
        $node->parentNode->removeChild($node);
758
      }
759 13
    }
760 13
  }
761
762
  /**
763
   * Remove id and class attributes.
764
   *
765
   * @param  \DOMXPath $xPath The DOMXPath for the entire document.
766
   */
767 3
  private function cleanupHTML(\DOMXPath $xPath)
768
  {
769 3
    $nodes = $xPath->query('//@class | //@id');
770 3
    foreach ($nodes as $node) {
771 3
      $node->ownerElement->removeAttributeNode($node);
772 3
    }
773 3
  }
774
775
  /**
776
   * Should the IDs and classes be removed?
777
   *
778
   * @param  bool $on Should we enable cleanup?
779
   *
780
   * @return $this
781
   */
782 3
  public function setCleanup($on = true)
783
  {
784 3
    $this->cleanup = (bool)$on;
785
786 3
    return $this;
787
  }
788
789
  /**
790
   * Set the encoding to use with the DOMDocument.
791
   *
792
   * @param  string $encoding The encoding to use.
793
   *
794
   * @return $this
795
   *
796
   * @deprecated Doesn't have any effect
797
   */
798
  public function setEncoding($encoding)
799
  {
800
    $this->encoding = (string)$encoding;
801
802
    return $this;
803
  }
804
805
  /**
806
   * Set use of inline styles block.
807
   *
808
   * Info: If this is enabled the class will use the style-block in the HTML.
809
   *
810
   * @param  bool $on Should we process inline styles?
811
   *
812
   * @return $this
813
   */
814 29
  public function setUseInlineStylesBlock($on = true)
815
  {
816 29
    $this->useInlineStylesBlock = (bool)$on;
817
818 29
    return $this;
819
  }
820
821
  /**
822
   * Set use of inline link block.
823
   *
824
   * Info: If this is enabled the class will use the links reference in the HTML.
825
   *
826
   * @param  bool [optional] $on Should we process link styles?
827
   *
828
   * @return $this
829
   */
830 2
  public function setLoadCSSFromHTML($on = true)
831
  {
832 2
    $this->loadCSSFromHTML = (bool)$on;
833
834 2
    return $this;
835
  }
836
837
  /**
838
   * Set strip original style tags.
839
   *
840
   * Info: If this is enabled the class will remove all style tags in the HTML.
841
   *
842
   * @param  bool $on Should we process inline styles?
843
   *
844
   * @return $this
845
   */
846 17
  public function setStripOriginalStyleTags($on = true)
847
  {
848 17
    $this->stripOriginalStyleTags = (bool)$on;
849
850 17
    return $this;
851
  }
852
853
  /**
854
   * Set exclude media queries.
855
   *
856
   * Info: If this is enabled the media queries will be removed before inlining the rules.
857
   *
858
   * WARNING: If you use inline styles block "<style>" the this option will keep the media queries.
859
   *
860
   * @param bool $on
861
   *
862
   * @return $this
863
   */
864 14
  public function setExcludeMediaQueries($on = true)
865
  {
866 14
    $this->excludeMediaQueries = (bool)$on;
867
868 14
    return $this;
869
  }
870
871
  /**
872
   * Set exclude charset.
873
   *
874
   * @param bool $on
875
   *
876
   * @return $this
877
   */
878 1
  public function setExcludeCssCharset($on = true)
879
  {
880 1
    $this->excludeCssCharset = (bool)$on;
881
882 1
    return $this;
883
  }
884
885
  /**
886
   * Set exclude conditional inline-style blocks.
887
   *
888
   * e.g.: <!--[if gte mso 9]><style>.foo { bar } </style><![endif]-->
889
   *
890
   * @param bool $on
891
   *
892
   * @return $this
893
   */
894 6
  public function setExcludeConditionalInlineStylesBlock($on = true)
895
  {
896 6
    $this->excludeConditionalInlineStylesBlock = (bool)$on;
897
898 6
    return $this;
899
  }
900
}
901