Completed
Push — master ( 8d79b4...b48be1 )
by Lars
04:36 queued 02:29
created

CssToInlineStyles::setExcludeMediaQueries()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
namespace voku\CssToInlineStyles;
3
4
use Symfony\Component\CssSelector\CssSelectorConverter;
5
use Symfony\Component\CssSelector\Exception\ExceptionInterface;
6
7
/**
8
 * CSS to Inline Styles class
9
 *
10
 * @author     Tijs Verkoyen <[email protected]>
11
 */
12
class CssToInlineStyles
13
{
14
15
  /**
16
   * regular expression: css media queries
17
   *
18
   * @var string
19
   */
20
  private static $cssMediaQueriesRegEx = '#@media\\s+(?:only\\s)?(?:[\\s{\\(]|screen|all)\\s?[^{]+{.*}\\s*}\\s*#misU';
21
22
  /**
23
   * regular expression: conditional inline style tags
24
   *
25
   * @var string
26
   */
27
  private static $excludeConditionalInlineStylesBlockRegEx = '/<!--.*<style.*?-->/is';
28
29
  /**
30
   * regular expression: inline style tags
31
   *
32
   * @var string
33
   */
34
  private static $styleTagRegEx = '|<style(.*)>(.*)</style>|isU';
35
36
  /**
37
   * regular expression: css-comments
38
   *
39
   * @var string
40
   */
41
  private static $styleCommentRegEx = '/\\/\\*.*\\*\\//sU';
42
43
  /**
44
   * The CSS to use
45
   *
46
   * @var  string
47
   */
48
  private $css;
49
50
  /**
51
   * Should the generated HTML be cleaned
52
   *
53
   * @var  bool
54
   */
55
  private $cleanup = false;
56
57
  /**
58
   * The encoding to use.
59
   *
60
   * @var  string
61
   */
62
  private $encoding = 'UTF-8';
63
64
  /**
65
   * The HTML to process
66
   *
67
   * @var  string
68
   */
69
  private $html;
70
71
  /**
72
   * Use inline-styles block as CSS
73
   *
74
   * @var bool
75
   */
76
  private $useInlineStylesBlock = false;
77
78
  /**
79
   * Use link block reference as CSS
80
   *
81
   * @var bool
82
   */
83
  private $loadCSSFromHTML = false;
84
85
  /**
86
   * Strip original style tags
87
   *
88
   * @var bool
89
   */
90
  private $stripOriginalStyleTags = false;
91
92
  /**
93
   * Exclude conditional inline-style blocks
94
   *
95
   * @var bool
96
   */
97
  private $excludeConditionalInlineStylesBlock = true;
98
99
  /**
100
   * Exclude media queries from "$this->css" and keep media queries for inline-styles blocks
101
   *
102
   * @var bool
103
   */
104
  private $excludeMediaQueries = true;
105
106
  /**
107
   * Creates an instance, you could set the HTML and CSS here, or load it
108
   * later.
109
   *
110
   * @param  null|string $html The HTML to process.
111
   * @param  null|string $css  The CSS to use.
112
   */
113 44
  public function __construct($html = null, $css = null)
114
  {
115 44
    if (null !== $html) {
116 1
      $this->setHTML($html);
117 1
    }
118
119 44
    if (null !== $css) {
120 1
      $this->setCSS($css);
121 1
    }
122 44
  }
123
124
  /**
125
   * Set HTML to process
126
   *
127
   * @param  string $html The HTML to process.
128
   */
129 42
  public function setHTML($html)
130
  {
131
    // strip style definitions, if we use css-class "cleanup" on a style-element
132 42
    $this->html = (string)preg_replace('/<style[^>]+class="cleanup"[^>]*>.*<\/style>/Usi', ' ', $html);
133 42
  }
134
135
  /**
136
   * Set CSS to use
137
   *
138
   * @param  string $css The CSS to use.
139
   */
140 40
  public function setCSS($css)
141
  {
142 40
    $this->css = (string)$css;
143 40
  }
144
145
  /**
146
   * Sort an array on the specificity element
147
   *
148
   * @return int
149
   *
150
   * @param Specificity[] $e1 The first element.
151
   * @param Specificity[] $e2 The second element.
152
   */
153 15
  private static function sortOnSpecificity($e1, $e2)
154
  {
155
    // Compare the specificity
156 15
    $value = $e1['specificity']->compareTo($e2['specificity']);
157
158
    // if the specificity is the same, use the order in which the element appeared
159 15
    if (0 === $value) {
160 10
      $value = $e1['order'] - $e2['order'];
161 10
    }
162
163 15
    return $value;
164
  }
165
166
  /**
167
   * Converts the loaded HTML into an HTML-string with inline styles based on the loaded CSS
168
   *
169
   * @return string
170
   *
171
   * @param  bool $outputXHTML                 [optional] Should we output valid XHTML?
172
   * @param  int  $libXMLOptions               [optional] $libXMLOptions Since PHP 5.4.0 and Libxml 2.6.0, you may also
173
   *                                                      use the options parameter to specify additional Libxml
174
   *                                                      parameters. Recommend these options: LIBXML_HTML_NOIMPLIED |
175
   *                                                      LIBXML_HTML_NODEFDTD
176
   * @param false|string                       [optional] Set the path to your external css-files.
177
   *
178
   * @throws Exception
179
   */
180 42
  public function convert($outputXHTML = false, $libXMLOptions = 0, $path = false)
181
  {
182
    // redefine
183 42
    $outputXHTML = (bool)$outputXHTML;
184
185
    // validate
186 42
    if (!$this->html) {
187 1
      throw new Exception('No HTML provided.');
188
    }
189
190
    // use local variables
191 41
    $css = $this->css;
192
193
    // create new DOMDocument
194 41
    $document = $this->createDOMDocument($this->html, $libXMLOptions);
195
196
    // check if there is some link css reference
197 41
    if ($this->loadCSSFromHTML) {
198 1
      foreach ($document->getElementsByTagName('link') as $node) {
199 1
        $file = ($path ? $path : __DIR__) . '/' .  $node->getAttribute('href');
200
201 1
        if (file_exists($file)) {
202 1
          $css .= file_get_contents($file);
203
204
          // converting to inline css because we don't need/want to load css files, so remove the link
205 1
          $node->parentNode->removeChild($node);
206 1
        }
207 1
      }
208 1
    }
209
210
    // should we use inline style-block
211 41
    if ($this->useInlineStylesBlock) {
212
213 25
      if (true === $this->excludeConditionalInlineStylesBlock) {
214 21
        $this->html = preg_replace(self::$excludeConditionalInlineStylesBlockRegEx, '', $this->html);
215 21
      }
216
217 25
      $css .= $this->getCssFromInlineHtmlStyleBlock($this->html);
218 25
    }
219
220
    // process css
221 41
    $cssRules = $this->processCSS($css);
222
223
    // create new XPath
224 41
    $xPath = $this->createXPath($document, $cssRules);
225
226
    // strip original style tags if we need to
227 41
    if ($this->stripOriginalStyleTags === true) {
228 13
      $this->stripOriginalStyleTags($xPath);
229 13
    }
230
231
    // cleanup the HTML if we need to
232 41
    if (true === $this->cleanup) {
233 3
      $this->cleanupHTML($xPath);
234 3
    }
235
236
    // should we output XHTML?
237 41
    if (true === $outputXHTML) {
238
      // set formatting
239 5
      $document->formatOutput = true;
240
241
      // get the HTML as XML
242 5
      $html = $document->saveXML(null, LIBXML_NOEMPTYTAG);
243
244
      // remove the XML-header
245 5
      return ltrim(preg_replace('/<\?xml.*\?>/', '', $html));
246
    }
247
248
    // just regular HTML 4.01 as it should be used in newsletters
249 36
    return $document->saveHTML();
250
  }
251
252
  /**
253
   * get css from inline-html style-block
254
   *
255
   * @param string $html
256
   *
257
   * @return string
258
   */
259 27
  public function getCssFromInlineHtmlStyleBlock($html)
260
  {
261
    // init var
262 27
    $css = '';
263 27
    $matches = array();
264
265
    // match the style blocks
266 27
    preg_match_all(self::$styleTagRegEx, $html, $matches);
267
268
    // any style-blocks found?
269 27
    if (!empty($matches[2])) {
270
      // add
271 26
      foreach ($matches[2] as $match) {
272 26
        $css .= trim($match) . "\n";
273 26
      }
274 26
    }
275
276 27
    return $css;
277
  }
278
279
  /**
280
   * Process the loaded CSS
281
   *
282
   * @param $css
283
   *
284
   * @return array
285
   */
286 41
  private function processCSS($css)
287
  {
288
    //reset current set of rules
289 41
    $cssRules = array();
290
291
    // init vars
292 41
    $css = (string)$css;
293
294 41
    $css = $this->doCleanup($css);
295
296
    // rules are splitted by }
297 41
    $rules = (array)explode('}', $css);
298
299
    // init var
300 41
    $i = 1;
301
302
    // loop rules
303 41
    foreach ($rules as $rule) {
304
      // split into chunks
305 41
      $chunks = explode('{', $rule);
306
307
      // invalid rule?
308 41
      if (!isset($chunks[1])) {
309 41
        continue;
310
      }
311
312
      // set the selectors
313 31
      $selectors = trim($chunks[0]);
314
315
      // get cssProperties
316 31
      $cssProperties = trim($chunks[1]);
317
318
      // split multiple selectors
319 31
      $selectors = (array)explode(',', $selectors);
320
321
      // loop selectors
322 31
      foreach ($selectors as $selector) {
323
        // cleanup
324 31
        $selector = trim($selector);
325
326
        // build an array for each selector
327 31
        $ruleSet = array();
328
329
        // store selector
330 31
        $ruleSet['selector'] = $selector;
331
332
        // process the properties
333 31
        $ruleSet['properties'] = $this->processCSSProperties($cssProperties);
334
335
336
        // calculate specificity
337 31
        $ruleSet['specificity'] = Specificity::fromSelector($selector);
338
339
        // remember the order in which the rules appear
340 31
        $ruleSet['order'] = $i;
341
342
        // add into rules
343 31
        $cssRules[] = $ruleSet;
344
345
        // increment
346 31
        $i++;
347 31
      }
348 41
    }
349
350
    // sort based on specificity
351 41
    if (0 !== count($cssRules)) {
352 31
      usort($cssRules, array(__CLASS__, 'sortOnSpecificity'));
353 31
    }
354
355 41
    return $cssRules;
356
  }
357
358
  /**
359
   * @param string $css
360
   *
361
   * @return string
362
   */
363 41
  private function doCleanup($css)
364
  {
365
    // remove newlines & replace double quotes by single quotes
366 41
    $css = str_replace(
367 41
        array("\r", "\n", '"'),
368 41
        array('', '', '\''),
369
        $css
370 41
    );
371
372
    // remove comments
373 41
    $css = preg_replace(self::$styleCommentRegEx, '', $css);
374
375
    // remove spaces
376 41
    $css = preg_replace('/\s\s+/', ' ', $css);
377
378
    // remove css media queries
379 41
    if (true === $this->excludeMediaQueries) {
380 40
      $css = $this->stripeMediaQueries($css);
381 40
    }
382
383 41
    return (string)$css;
384
  }
385
386
  /**
387
   * remove css media queries from the string
388
   *
389
   * @param string $css
390
   *
391
   * @return string
392
   */
393 40
  private function stripeMediaQueries($css)
394
  {
395
    // remove comments previously to matching media queries
396 40
    $css = preg_replace(self::$styleCommentRegEx, '', $css);
397
398 40
    return (string)preg_replace(self::$cssMediaQueriesRegEx, '', $css);
399
  }
400
401
  /**
402
   * Process the CSS-properties
403
   *
404
   * @return array
405
   *
406
   * @param  string $propertyString The CSS-properties.
407
   */
408 31
  private function processCSSProperties($propertyString)
409
  {
410
    // split into chunks
411 31
    $properties = $this->splitIntoProperties($propertyString);
412
413
    // init var
414 31
    $pairs = array();
415
416
    // loop properties
417 31
    foreach ($properties as $property) {
418
      // split into chunks
419 31
      $chunks = (array)explode(':', $property, 2);
420
421
      // validate
422 31
      if (!isset($chunks[1])) {
423 25
        continue;
424
      }
425
426
      // cleanup
427 30
      $chunks[0] = trim($chunks[0]);
428 30
      $chunks[1] = trim($chunks[1]);
429
430
      // add to pairs array
431
      if (
432 30
          !isset($pairs[$chunks[0]])
433 30
          ||
434 3
          !in_array($chunks[1], $pairs[$chunks[0]], true)
435 30
      ) {
436 30
        $pairs[$chunks[0]][] = $chunks[1];
437 30
      }
438 31
    }
439
440
    // sort the pairs
441 31
    ksort($pairs);
442
443
    // return
444 31
    return $pairs;
445
  }
446
447
  /**
448
   * Split a style string into an array of properties.
449
   * The returned array can contain empty strings.
450
   *
451
   * @param string $styles ex: 'color:blue;font-size:12px;'
452
   *
453
   * @return array an array of strings containing css property ex: array('color:blue','font-size:12px')
454
   */
455 31
  private function splitIntoProperties($styles)
456
  {
457 31
    $properties = (array)explode(';', $styles);
458 31
    $propertiesCount = count($properties);
459
460 31
    for ($i = 0; $i < $propertiesCount; $i++) {
461
      // If next property begins with base64,
462
      // Then the ';' was part of this property (and we should not have split on it).
463
      if (
464 31
          isset($properties[$i + 1])
465 31
          &&
466 24
          strpos($properties[$i + 1], 'base64,') !== false
467 31
      ) {
468 1
        $properties[$i] .= ';' . $properties[$i + 1];
469 1
        $properties[$i + 1] = '';
470 1
        ++$i;
471 1
      }
472 31
    }
473
474 31
    return $properties;
475
  }
476
477
  /**
478
   * create DOMDocument from HTML
479
   *
480
   * @param string $html
481
   * @param int    $libXMLOptions
482
   *
483
   * @return \DOMDocument
484
   */
485 41
  private function createDOMDocument($html, $libXMLOptions = 0)
486
  {
487
    // create new DOMDocument
488 41
    $document = new \DOMDocument('1.0', $this->getEncoding());
489
490
    // DOMDocument settings
491 41
    $document->preserveWhiteSpace = false;
492 41
    $document->formatOutput = true;
493
494
    // set error level
495 41
    $internalErrors = libxml_use_internal_errors(true);
496
497
    // load HTML
498
    //
499
    // with UTF-8 hack: http://php.net/manual/en/domdocument.loadhtml.php#95251
0 ignored issues
show
Unused Code Comprehensibility introduced by
40% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
500
    //
501 41
    if ($libXMLOptions !== 0) {
502
      $document->loadHTML('<?xml encoding="' . $this->getEncoding() . '">' . $html, $libXMLOptions);
503
    } else {
504 41
      $document->loadHTML('<?xml encoding="' . $this->getEncoding() . '">' . $html);
505
    }
506
507
508
    // remove the "xml-encoding" hack
509 41
    foreach ($document->childNodes as $child) {
510 41
      if ($child->nodeType == XML_PI_NODE) {
511 41
        $document->removeChild($child);
512 41
      }
513 41
    }
514
515
    // set encoding
516 41
    $document->encoding = $this->getEncoding();
517
518
    // restore error level
519 41
    libxml_use_internal_errors($internalErrors);
520
521 41
    return $document;
522
  }
523
524
  /**
525
   * Get the encoding to use
526
   *
527
   * @return string
528
   */
529 41
  private function getEncoding()
530
  {
531 41
    return $this->encoding;
532
  }
533
534
  /**
535
   * create XPath
536
   *
537
   * @param \DOMDocument $document
538
   * @param array        $cssRules
539
   *
540
   * @return \DOMXPath
541
   */
542 41
  private function createXPath(\DOMDocument $document, array $cssRules)
543
  {
544 41
    $xPath = new \DOMXPath($document);
545
546
    // any rules?
547 41
    if (0 !== count($cssRules)) {
548
      // loop rules
549 31
      foreach ($cssRules as $rule) {
550
551
        try {
552 31
          $converter = new CssSelectorConverter();
553 31
          $query = $converter->toXPath($rule['selector']);
554 31
        } catch (ExceptionInterface $e) {
555 4
          $query = null;
556
        }
557 31
        $converter = null;
558
559
        // validate query
560 31
        if (null === $query) {
561 4
          continue;
562
        }
563
564
        // search elements
565 29
        $elements = $xPath->query($query);
566
567
        // validate elements
568 29
        if (false === $elements) {
569
          continue;
570
        }
571
572
        // loop found elements
573 29
        foreach ($elements as $element) {
574
575
          /**
576
           * @var $element \DOMElement
577
           */
578
579
          // no styles stored?
580 29
          if (null === $element->attributes->getNamedItem('data-css-to-inline-styles-original-styles')) {
581
582
            // init var
583 29
            $originalStyle = '';
584
585 29
            if (null !== $element->attributes->getNamedItem('style')) {
586 6
              $originalStyle = $element->attributes->getNamedItem('style')->value;
587 6
            }
588
589
            // store original styles
590 29
            $element->setAttribute('data-css-to-inline-styles-original-styles', $originalStyle);
591
592
            // clear the styles
593 29
            $element->setAttribute('style', '');
594 29
          }
595
596 29
          $propertiesString = $this->createPropertyChunks($element, $rule['properties']);
597
598
          // set attribute
599 29
          if ('' != $propertiesString) {
600 29
            $element->setAttribute('style', $propertiesString);
601 29
          }
602 29
        }
603 31
      }
604
605
      // reapply original styles
606
      // search elements
607 31
      $elements = $xPath->query('//*[@data-css-to-inline-styles-original-styles]');
608
609
      // loop found elements
610 31
      foreach ($elements as $element) {
611
        // get the original styles
612 29
        $originalStyle = $element->attributes->getNamedItem('data-css-to-inline-styles-original-styles')->value;
613
614 29
        if ('' != $originalStyle) {
615 6
          $originalStyles = $this->splitIntoProperties($originalStyle);
616
617 6
          $originalProperties = $this->splitStyleIntoChunks($originalStyles);
618
619 6
          $propertiesString = $this->createPropertyChunks($element, $originalProperties);
620
621
          // set attribute
622 6
          if ('' != $propertiesString) {
623 6
            $element->setAttribute('style', $propertiesString);
624 6
          }
625 6
        }
626
627
        // remove placeholder
628 29
        $element->removeAttribute('data-css-to-inline-styles-original-styles');
629 31
      }
630 31
    }
631
632 41
    return $xPath;
633
  }
634
635
  /**
636
   * @param \DOMElement $element
637
   * @param array       $ruleProperties
638
   *
639
   * @return array
640
   */
641 29
  private function createPropertyChunks(\DOMElement $element, array $ruleProperties)
642
  {
643
    // init var
644 29
    $properties = array();
645
646
    // get current styles
647 29
    $stylesAttribute = $element->attributes->getNamedItem('style');
648
649
    // any styles defined before?
650 29
    if (null !== $stylesAttribute) {
651
      // get value for the styles attribute
652 29
      $definedStyles = (string)$stylesAttribute->value;
653
654
      // split into properties
655 29
      $definedProperties = $this->splitIntoProperties($definedStyles);
656
657 29
      $properties = $this->splitStyleIntoChunks($definedProperties);
658 29
    }
659
660
    // add new properties into the list
661 29
    foreach ($ruleProperties as $key => $value) {
662
      // If one of the rules is already set and is !important, don't apply it,
663
      // except if the new rule is also important.
664
      if (
665 29
          !isset($properties[$key])
666 29
          ||
667 7
          false === stripos($properties[$key], '!important')
668 7
          ||
669 3
          false !== stripos(implode('', (array)$value), '!important')
670 29
      ) {
671 29
        $properties[$key] = $value;
672 29
      }
673 29
    }
674
675
    // build string
676 29
    $propertyChunks = array();
677
678
    // build chunks
679 29
    foreach ($properties as $key => $values) {
680 29
      foreach ((array)$values as $value) {
681 29
        $propertyChunks[] = $key . ': ' . $value . ';';
682 29
      }
683 29
    }
684
685 29
    return implode(' ', $propertyChunks);
686
  }
687
688
  /**
689
   * @param array $definedProperties
690
   *
691
   * @return array
692
   */
693 29
  private function splitStyleIntoChunks(array $definedProperties)
694
  {
695
    // init var
696 29
    $properties = array();
697
698
    // loop properties
699 29
    foreach ($definedProperties as $property) {
700
      // validate property
701
      if (
702
          !$property
703 29
          ||
704 14
          strpos($property, ':') === false
705 29
      ) {
706 29
        continue;
707
      }
708
709
      // split into chunks
710 14
      $chunks = (array)explode(':', trim($property), 2);
711
712
      // validate
713 14
      if (!isset($chunks[1])) {
714
        continue;
715
      }
716
717
      // loop chunks
718 14
      $properties[$chunks[0]] = trim($chunks[1]);
719 29
    }
720
721 29
    return $properties;
722
  }
723
724
  /**
725
   * Strip style tags into the generated HTML
726
   *
727
   * @param  \DOMXPath $xPath The DOMXPath for the entire document.
728
   *
729
   * @return string
730
   */
731 13
  private function stripOriginalStyleTags(\DOMXPath $xPath)
732
  {
733
    // get all style tags
734 13
    $nodes = $xPath->query('descendant-or-self::style');
735 13
    foreach ($nodes as $node) {
736 12
      if ($this->excludeMediaQueries === true) {
737
738
        // remove comments previously to matching media queries
739 11
        $node->nodeValue = preg_replace(self::$styleCommentRegEx, '', $node->nodeValue);
740
741
        // search for Media Queries
742 11
        preg_match_all(self::$cssMediaQueriesRegEx, $node->nodeValue, $mqs);
743
744
        // replace the nodeValue with just the Media Queries
745 11
        $node->nodeValue = implode("\n", $mqs[0]);
746
747 11
      } else {
748
        // remove the entire style tag
749 1
        $node->parentNode->removeChild($node);
750
      }
751 13
    }
752 13
  }
753
754
  /**
755
   * Remove id and class attributes.
756
   *
757
   * @param  \DOMXPath $xPath The DOMXPath for the entire document.
758
   *
759
   * @return string
760
   */
761 3
  private function cleanupHTML(\DOMXPath $xPath)
762
  {
763 3
    $nodes = $xPath->query('//@class | //@id');
764 3
    foreach ($nodes as $node) {
765 3
      $node->ownerElement->removeAttributeNode($node);
766 3
    }
767 3
  }
768
769
  /**
770
   * Should the IDs and classes be removed?
771
   *
772
   * @param  bool $on Should we enable cleanup?
773
   */
774 3
  public function setCleanup($on = true)
775
  {
776 3
    $this->cleanup = (bool)$on;
777 3
  }
778
779
  /**
780
   * Set the encoding to use with the DOMDocument
781
   *
782
   * @param  string $encoding The encoding to use.
783
   *
784
   * @deprecated Doesn't have any effect
785
   */
786
  public function setEncoding($encoding)
787
  {
788
    $this->encoding = (string)$encoding;
789
  }
790
791
  /**
792
   * Set use of inline styles block
793
   * If this is enabled the class will use the style-block in the HTML.
794
   *
795
   * @param  bool $on Should we process inline styles?
796
   */
797 25
  public function setUseInlineStylesBlock($on = true)
798
  {
799 25
    $this->useInlineStylesBlock = (bool)$on;
800 25
  }
801
802
  /**
803
       * Set use of inline link block
804
       * If this is enabled the class will use the links reference in the HTML.
805
       *
806
       * @return void
807
       * @param  bool [optional] $on Should we process link styles?
808
       */
809 1
    public function setLoadCSSFromHTML($on = true)
810
     {
811 1
         $this->loadCSSFromHTML = (bool) $on;
812 1
     }
813
814
  /**
815
   * Set strip original style tags
816
   * If this is enabled the class will remove all style tags in the HTML.
817
   *
818
   * @param  bool $on Should we process inline styles?
819
   */
820 16
  public function setStripOriginalStyleTags($on = true)
821
  {
822 16
    $this->stripOriginalStyleTags = (bool)$on;
823 16
  }
824
825
  /**
826
   * Set exclude media queries
827
   *
828
   * If this is enabled the media queries will be removed before inlining the rules.
829
   *
830
   * WARNING: If you use inline styles block "<style>" the this option will keep the media queries.
831
   *
832
   * @param bool $on
833
   */
834 13
  public function setExcludeMediaQueries($on = true)
835
  {
836 13
    $this->excludeMediaQueries = (bool)$on;
837 13
  }
838
839
  /**
840
   * Set exclude conditional inline-style blocks e.g.: <!--[if gte mso 9]><style>.foo { bar } </style><![endif]-->
841
   *
842
   * @param bool $on
843
   */
844 5
  public function setExcludeConditionalInlineStylesBlock($on = true)
845
  {
846 5
    $this->excludeConditionalInlineStylesBlock = (bool)$on;
847 5
  }
848
849
}
850