Completed
Push — master ( 4b0766...3f5e73 )
by Lars
02:48
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 4
Bugs 2 Features 0
Metric Value
c 4
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
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: css charset
24
   *
25
   * @var string
26
   */
27
  private static $cssCharsetRegEx = '/@charset [\'"][^\'"]+[\'"];/i';
28
29
30
  /**
31
   * regular expression: conditional inline style tags
32
   *
33
   * @var string
34
   */
35
  private static $excludeConditionalInlineStylesBlockRegEx = '/<!--.*<style.*?-->/isU';
36
37
  /**
38
   * regular expression: inline style tags
39
   *
40
   * @var string
41
   */
42
  private static $styleTagRegEx = '|<style(.*)>(.*)</style>|isU';
43
44
  /**
45
   * regular expression: css-comments
46
   *
47
   * @var string
48
   */
49
  private static $styleCommentRegEx = '/\\/\\*.*\\*\\//sU';
50
51
  /**
52
   * The CSS to use
53
   *
54
   * @var  string
55
   */
56
  private $css;
57
58
  /**
59
   * Should the generated HTML be cleaned
60
   *
61
   * @var  bool
62
   */
63
  private $cleanup = false;
64
65
  /**
66
   * The encoding to use.
67
   *
68
   * @var  string
69
   */
70
  private $encoding = 'UTF-8';
71
72
  /**
73
   * The HTML to process
74
   *
75
   * @var  string
76
   */
77
  private $html;
78
79
  /**
80
   * Use inline-styles block as CSS
81
   *
82
   * @var bool
83
   */
84
  private $useInlineStylesBlock = false;
85
86
  /**
87
   * Use link block reference as CSS
88
   *
89
   * @var bool
90
   */
91
  private $loadCSSFromHTML = false;
92
93
  /**
94
   * Strip original style tags
95
   *
96
   * @var bool
97
   */
98
  private $stripOriginalStyleTags = false;
99
100
  /**
101
   * Exclude conditional inline-style blocks
102
   *
103
   * @var bool
104
   */
105
  private $excludeConditionalInlineStylesBlock = true;
106
107
  /**
108
   * Exclude media queries from "$this->css" and keep media queries for inline-styles blocks
109
   *
110
   * @var bool
111
   */
112
  private $excludeMediaQueries = true;
113
114
  /**
115
   * Exclude media queries from "$this->css" and keep media queries for inline-styles blocks
116
   *
117
   * @var bool
118
   */
119
  private $excludeCssCharset = true;
120
121
  /**
122
   * Creates an instance, you could set the HTML and CSS here, or load it
123
   * later.
124
   *
125
   * @param  null|string $html The HTML to process.
126
   * @param  null|string $css  The CSS to use.
127
   */
128 46
  public function __construct($html = null, $css = null)
129
  {
130 46
    if (null !== $html) {
131 1
      $this->setHTML($html);
132 1
    }
133
134 46
    if (null !== $css) {
135 1
      $this->setCSS($css);
136 1
    }
137 46
  }
138
139
  /**
140
   * Set HTML to process
141
   *
142
   * @param  string $html The HTML to process.
143
   */
144 44
  public function setHTML($html)
145
  {
146
    // strip style definitions, if we use css-class "cleanup" on a style-element
147 44
    $this->html = (string)preg_replace('/<style[^>]+class="cleanup"[^>]*>.*<\/style>/Usi', ' ', $html);
148 44
  }
149
150
  /**
151
   * Set CSS to use
152
   *
153
   * @param  string $css The CSS to use.
154
   */
155 42
  public function setCSS($css)
156
  {
157 42
    $this->css = (string)$css;
158 42
  }
159
160
  /**
161
   * Sort an array on the specificity element
162
   *
163
   * @return int
164
   *
165
   * @param Specificity[] $e1 The first element.
166
   * @param Specificity[] $e2 The second element.
167
   */
168 15
  private static function sortOnSpecificity($e1, $e2)
169
  {
170
    // Compare the specificity
171 15
    $value = $e1['specificity']->compareTo($e2['specificity']);
172
173
    // if the specificity is the same, use the order in which the element appeared
174 15
    if (0 === $value) {
175 10
      $value = $e1['order'] - $e2['order'];
176 10
    }
177
178 15
    return $value;
179
  }
180
181
  /**
182
   * Converts the loaded HTML into an HTML-string with inline styles based on the loaded CSS
183
   *
184
   * @param bool $outputXHTML                             [optional] Should we output valid XHTML?
185
   * @param int  $libXMLOptions                           [optional] $libXMLOptions Since PHP 5.4.0 and Libxml 2.6.0,
186
   *                                                      you may also use the options parameter to specify additional
187
   *                                                      Libxml parameters. Recommend these options:
188
   *                                                      LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD
189
   * @param bool $path                                    [optional] Set the path to your external css-files.
190
   *
191
   * @return string
192
   *
193
   * @throws Exception
194
   */
195 44
  public function convert($outputXHTML = false, $libXMLOptions = 0, $path = false)
196
  {
197
    // redefine
198 44
    $outputXHTML = (bool)$outputXHTML;
199
200
    // validate
201 44
    if (!$this->html) {
202 1
      throw new Exception('No HTML provided.');
203
    }
204
205
    // use local variables
206 43
    $css = $this->css;
207
208
    // create new DOMDocument
209 43
    $document = $this->createDOMDocument($this->html, $libXMLOptions);
210
211
    // check if there is some link css reference
212 43
    if ($this->loadCSSFromHTML) {
213 1
      foreach ($document->getElementsByTagName('link') as $node) {
214
        
215
        /** @noinspection PhpUndefinedMethodInspection */
216 1
        $file = ($path ?: __DIR__) . '/' . $node->getAttribute('href');
217
218 1
        if (file_exists($file)) {
219 1
          $css .= file_get_contents($file);
220
221
          // converting to inline css because we don't need/want to load css files, so remove the link
222 1
          $node->parentNode->removeChild($node);
223 1
        }
224 1
      }
225 1
    }
226
227
    // should we use inline style-block
228 43
    if ($this->useInlineStylesBlock) {
229
230 26
      if (true === $this->excludeConditionalInlineStylesBlock) {
231 22
        $this->html = preg_replace(self::$excludeConditionalInlineStylesBlockRegEx, '', $this->html);
232 22
      }
233
234 26
      $css .= $this->getCssFromInlineHtmlStyleBlock($this->html);
235 26
    }
236
237
    // process css
238 43
    $cssRules = $this->processCSS($css);
239
240
    // create new XPath
241 43
    $xPath = $this->createXPath($document, $cssRules);
242
243
    // strip original style tags if we need to
244 43
    if ($this->stripOriginalStyleTags === true) {
245 13
      $this->stripOriginalStyleTags($xPath);
246 13
    }
247
248
    // cleanup the HTML if we need to
249 43
    if (true === $this->cleanup) {
250 3
      $this->cleanupHTML($xPath);
251 3
    }
252
253
    // should we output XHTML?
254 43
    if (true === $outputXHTML) {
255
      // set formatting
256 5
      $document->formatOutput = true;
257
258
      // get the HTML as XML
259 5
      $html = $document->saveXML(null, LIBXML_NOEMPTYTAG);
260
261
      // remove the XML-header
262 5
      return ltrim(preg_replace('/<\?xml.*\?>/', '', $html));
263
    }
264
265
    // just regular HTML 4.01 as it should be used in newsletters
266 38
    return $document->saveHTML();
267
  }
268
269
  /**
270
   * get css from inline-html style-block
271
   *
272
   * @param string $html
273
   *
274
   * @return string
275
   */
276 28
  public function getCssFromInlineHtmlStyleBlock($html)
277
  {
278
    // init var
279 28
    $css = '';
280 28
    $matches = array();
281
282
    // match the style blocks
283 28
    preg_match_all(self::$styleTagRegEx, $html, $matches);
284
285
    // any style-blocks found?
286 28
    if (!empty($matches[2])) {
287
      // add
288 26
      foreach ($matches[2] as $match) {
289 26
        $css .= trim($match) . "\n";
290 26
      }
291 26
    }
292
293 28
    return $css;
294
  }
295
296
  /**
297
   * Process the loaded CSS
298
   *
299
   * @param $css
300
   *
301
   * @return array
302
   */
303 43
  private function processCSS($css)
304
  {
305
    //reset current set of rules
306 43
    $cssRules = array();
307
308
    // init vars
309 43
    $css = (string)$css;
310
311 43
    $css = $this->doCleanup($css);
312
313
    // rules are splitted by }
314 43
    $rules = (array)explode('}', $css);
315
316
    // init var
317 43
    $i = 1;
318
319
    // loop rules
320 43
    foreach ($rules as $rule) {
321
      // split into chunks
322 43
      $chunks = explode('{', $rule);
323
324
      // invalid rule?
325 43
      if (!isset($chunks[1])) {
326 43
        continue;
327
      }
328
329
      // set the selectors
330 32
      $selectors = trim($chunks[0]);
331
332
      // get cssProperties
333 32
      $cssProperties = trim($chunks[1]);
334
335
      // split multiple selectors
336 32
      $selectors = (array)explode(',', $selectors);
337
338
      // loop selectors
339 32
      foreach ($selectors as $selector) {
340
        // cleanup
341 32
        $selector = trim($selector);
342
343
        // build an array for each selector
344 32
        $ruleSet = array();
345
346
        // store selector
347 32
        $ruleSet['selector'] = $selector;
348
349
        // process the properties
350 32
        $ruleSet['properties'] = $this->processCSSProperties($cssProperties);
351
352
353
        // calculate specificity
354 32
        $ruleSet['specificity'] = Specificity::fromSelector($selector);
355
356
        // remember the order in which the rules appear
357 32
        $ruleSet['order'] = $i;
358
359
        // add into rules
360 32
        $cssRules[] = $ruleSet;
361
362
        // increment
363 32
        $i++;
364 32
      }
365 43
    }
366
367
    // sort based on specificity
368 43
    if (0 !== count($cssRules)) {
369 32
      usort($cssRules, array(__CLASS__, 'sortOnSpecificity'));
370 32
    }
371
372 43
    return $cssRules;
373
  }
374
375
  /**
376
   * @param string $css
377
   *
378
   * @return string
379
   */
380 43
  private function doCleanup($css)
381
  {
382
    // remove newlines & replace double quotes by single quotes
383 43
    $css = str_replace(
384 43
        array("\r", "\n", '"'),
385 43
        array('', '', '\''),
386
        $css
387 43
    );
388
389
    // remove comments
390 43
    $css = preg_replace(self::$styleCommentRegEx, '', $css);
391
392
    // remove spaces
393 43
    $css = preg_replace('/\s\s+/', ' ', $css);
394
395
    // remove css charset
396 43
    if (true === $this->excludeCssCharset) {
397 43
      $css = $this->stripeCharsetInCss($css);
398 43
    }
399
400
    // remove css media queries
401 43
    if (true === $this->excludeMediaQueries) {
402 42
      $css = $this->stripeMediaQueries($css);
403 42
    }
404
405 43
    return (string)$css;
406
  }
407
408
  /**
409
   * remove css media queries from the string
410
   *
411
   * @param string $css
412
   *
413
   * @return string
414
   */
415 42
  private function stripeMediaQueries($css)
416
  {
417
    // remove comments previously to matching media queries
418 42
    $css = preg_replace(self::$styleCommentRegEx, '', $css);
419
420 42
    return (string)preg_replace(self::$cssMediaQueriesRegEx, '', $css);
421
  }
422
423
  /**
424
   * remove charset from the string
425
   *
426
   * @param $css
427
   *
428
   * @return string
429
   */
430 43
  private function stripeCharsetInCss($css)
431
  {
432 43
    return (string)preg_replace(self::$cssCharsetRegEx, '', $css);
433
  }
434
435
  /**
436
   * Process the CSS-properties
437
   *
438
   * @return array
439
   *
440
   * @param  string $propertyString The CSS-properties.
441
   */
442 32
  private function processCSSProperties($propertyString)
443
  {
444
    // split into chunks
445 32
    $properties = $this->splitIntoProperties($propertyString);
446
447
    // init var
448 32
    $pairs = array();
449
450
    // loop properties
451 32
    foreach ($properties as $property) {
452
      // split into chunks
453 32
      $chunks = (array)explode(':', $property, 2);
454
455
      // validate
456 32
      if (!isset($chunks[1])) {
457 26
        continue;
458
      }
459
460
      // cleanup
461 31
      $chunks[0] = trim($chunks[0]);
462 31
      $chunks[1] = trim($chunks[1]);
463
464
      // add to pairs array
465
      if (
466 31
          !isset($pairs[$chunks[0]])
467 31
          ||
468 3
          !in_array($chunks[1], $pairs[$chunks[0]], true)
469 31
      ) {
470 31
        $pairs[$chunks[0]][] = $chunks[1];
471 31
      }
472 32
    }
473
474
    // sort the pairs
475 32
    ksort($pairs);
476
477
    // return
478 32
    return $pairs;
479
  }
480
481
  /**
482
   * Split a style string into an array of properties.
483
   * The returned array can contain empty strings.
484
   *
485
   * @param string $styles ex: 'color:blue;font-size:12px;'
486
   *
487
   * @return array an array of strings containing css property ex: array('color:blue','font-size:12px')
488
   */
489 32
  private function splitIntoProperties($styles)
490
  {
491 32
    $properties = (array)explode(';', $styles);
492 32
    $propertiesCount = count($properties);
493
494
    /** @noinspection ForeachInvariantsInspection */
495 32
    for ($i = 0; $i < $propertiesCount; $i++) {
496
      // If next property begins with base64,
497
      // Then the ';' was part of this property (and we should not have split on it).
498
      if (
499 32
          isset($properties[$i + 1])
500 32
          &&
501 25
          strpos($properties[$i + 1], 'base64,') !== false
502 32
      ) {
503 1
        $properties[$i] .= ';' . $properties[$i + 1];
504 1
        $properties[$i + 1] = '';
505 1
        ++$i;
506 1
      }
507 32
    }
508
509 32
    return $properties;
510
  }
511
512
  /**
513
   * create DOMDocument from HTML
514
   *
515
   * @param string $html
516
   * @param int    $libXMLOptions
517
   *
518
   * @return \DOMDocument
519
   */
520 43
  private function createDOMDocument($html, $libXMLOptions = 0)
521
  {
522
    // create new DOMDocument
523 43
    $document = new \DOMDocument('1.0', $this->getEncoding());
524
525
    // DOMDocument settings
526 43
    $document->preserveWhiteSpace = false;
527 43
    $document->formatOutput = true;
528
529
    // set error level
530 43
    $internalErrors = libxml_use_internal_errors(true);
531
532
    // load HTML
533
    //
534
    // with UTF-8 hack: http://php.net/manual/en/domdocument.loadhtml.php#95251
535
    //
536 43
    if ($libXMLOptions !== 0) {
537
      $document->loadHTML('<?xml encoding="' . $this->getEncoding() . '">' . $html, $libXMLOptions);
538
    } else {
539 43
      $document->loadHTML('<?xml encoding="' . $this->getEncoding() . '">' . $html);
540
    }
541
542
543
    // remove the "xml-encoding" hack
544 43
    foreach ($document->childNodes as $child) {
545 43
      if ($child->nodeType == XML_PI_NODE) {
546 43
        $document->removeChild($child);
547 43
      }
548 43
    }
549
550
    // set encoding
551 43
    $document->encoding = $this->getEncoding();
552
553
    // restore error level
554 43
    libxml_use_internal_errors($internalErrors);
555
556 43
    return $document;
557
  }
558
559
  /**
560
   * Get the encoding to use
561
   *
562
   * @return string
563
   */
564 43
  private function getEncoding()
565
  {
566 43
    return $this->encoding;
567
  }
568
569
  /**
570
   * create XPath
571
   *
572
   * @param \DOMDocument $document
573
   * @param array        $cssRules
574
   *
575
   * @return \DOMXPath
576
   */
577 43
  private function createXPath(\DOMDocument $document, array $cssRules)
578
  {
579 43
    $xPath = new \DOMXPath($document);
580
581
    // any rules?
582 43
    if (0 !== count($cssRules)) {
583
      // loop rules
584 32
      foreach ($cssRules as $rule) {
585
586
        try {
587 32
          $converter = new CssSelectorConverter();
588 32
          $query = $converter->toXPath($rule['selector']);
589 32
        } catch (ExceptionInterface $e) {
590 4
          $query = null;
591
        }
592 32
        $converter = null;
593
594
        // validate query
595 32
        if (null === $query) {
596 4
          continue;
597
        }
598
599
        // search elements
600 30
        $elements = $xPath->query($query);
601
602
        // validate elements
603 30
        if (false === $elements) {
604
          continue;
605
        }
606
607
        // loop found elements
608 30
        foreach ($elements as $element) {
609
610
          /**
611
           * @var $element \DOMElement
612
           */
613
614
          // no styles stored?
615 30
          if (null === $element->attributes->getNamedItem('data-css-to-inline-styles-original-styles')) {
616
617
            // init var
618 30
            $originalStyle = '';
619
620 30
            if (null !== $element->attributes->getNamedItem('style')) {
621
              /** @noinspection PhpUndefinedFieldInspection */
622 7
              $originalStyle = $element->attributes->getNamedItem('style')->value;
623 7
            }
624
625
            // store original styles
626 30
            $element->setAttribute('data-css-to-inline-styles-original-styles', $originalStyle);
627
628
            // clear the styles
629 30
            $element->setAttribute('style', '');
630 30
          }
631
632 30
          $propertiesString = $this->createPropertyChunks($element, $rule['properties']);
633
634
          // set attribute
635 30
          if ('' != $propertiesString) {
636 30
            $element->setAttribute('style', $propertiesString);
637 30
          }
638 30
        }
639 32
      }
640
641
      // reapply original styles
642
      // search elements
643 32
      $elements = $xPath->query('//*[@data-css-to-inline-styles-original-styles]');
644
645
      // loop found elements
646 32
      foreach ($elements as $element) {
647
        // get the original styles
648
        /** @noinspection PhpUndefinedFieldInspection */
649 30
        $originalStyle = $element->attributes->getNamedItem('data-css-to-inline-styles-original-styles')->value;
650
651 30
        if ('' != $originalStyle) {
652 7
          $originalStyles = $this->splitIntoProperties($originalStyle);
653
654 7
          $originalProperties = $this->splitStyleIntoChunks($originalStyles);
655
656 7
          $propertiesString = $this->createPropertyChunks($element, $originalProperties);
657
658
          // set attribute
659 7
          if ('' != $propertiesString) {
660 7
            $element->setAttribute('style', $propertiesString);
661 7
          }
662 7
        }
663
664
        // remove placeholder
665 30
        $element->removeAttribute('data-css-to-inline-styles-original-styles');
666 32
      }
667 32
    }
668
669 43
    return $xPath;
670
  }
671
672
  /**
673
   * @param \DOMElement $element
674
   * @param array       $ruleProperties
675
   *
676
   * @return array
677
   */
678 30
  private function createPropertyChunks(\DOMElement $element, array $ruleProperties)
679
  {
680
    // init var
681 30
    $properties = array();
682
683
    // get current styles
684 30
    $stylesAttribute = $element->attributes->getNamedItem('style');
685
686
    // any styles defined before?
687 30
    if (null !== $stylesAttribute) {
688
      // get value for the styles attribute
689
      /** @noinspection PhpUndefinedFieldInspection */
690 30
      $definedStyles = (string)$stylesAttribute->value;
691
692
      // split into properties
693 30
      $definedProperties = $this->splitIntoProperties($definedStyles);
694
695 30
      $properties = $this->splitStyleIntoChunks($definedProperties);
696 30
    }
697
698
    // add new properties into the list
699 30
    foreach ($ruleProperties as $key => $value) {
700
      // If one of the rules is already set and is !important, don't apply it,
701
      // except if the new rule is also important.
702
      if (
703 30
          !isset($properties[$key])
704 30
          ||
705 8
          false === stripos($properties[$key], '!important')
706 8
          ||
707 3
          false !== stripos(implode('', (array)$value), '!important')
708 30
      ) {
709 30
        $properties[$key] = $value;
710 30
      }
711 30
    }
712
713
    // build string
714 30
    $propertyChunks = array();
715
716
    // build chunks
717 30
    foreach ($properties as $key => $values) {
718 30
      foreach ((array)$values as $value) {
719 30
        $propertyChunks[] = $key . ': ' . $value . ';';
720 30
      }
721 30
    }
722
723 30
    return implode(' ', $propertyChunks);
724
  }
725
726
  /**
727
   * @param array $definedProperties
728
   *
729
   * @return array
730
   */
731 30
  private function splitStyleIntoChunks(array $definedProperties)
732
  {
733
    // init var
734 30
    $properties = array();
735
736
    // loop properties
737 30
    foreach ($definedProperties as $property) {
738
      // validate property
739
      if (
740
          !$property
741 30
          ||
742 15
          strpos($property, ':') === false
743 30
      ) {
744 30
        continue;
745
      }
746
747
      // split into chunks
748 15
      $chunks = (array)explode(':', trim($property), 2);
749
750
      // validate
751 15
      if (!isset($chunks[1])) {
752
        continue;
753
      }
754
755
      // loop chunks
756 15
      $properties[$chunks[0]] = trim($chunks[1]);
757 30
    }
758
759 30
    return $properties;
760
  }
761
762
  /**
763
   * Strip style tags into the generated HTML
764
   *
765
   * @param  \DOMXPath $xPath The DOMXPath for the entire document.
766
   *
767
   * @return string
768
   */
769 13
  private function stripOriginalStyleTags(\DOMXPath $xPath)
770
  {
771
    // get all style tags
772 13
    $nodes = $xPath->query('descendant-or-self::style');
773 13
    foreach ($nodes as $node) {
774 12
      if ($this->excludeMediaQueries === true) {
775
776
        // remove comments previously to matching media queries
777 11
        $node->nodeValue = preg_replace(self::$styleCommentRegEx, '', $node->nodeValue);
778
779
        // search for Media Queries
780 11
        preg_match_all(self::$cssMediaQueriesRegEx, $node->nodeValue, $mqs);
781
782
        // replace the nodeValue with just the Media Queries
783 11
        $node->nodeValue = implode("\n", $mqs[0]);
784
785 11
      } else {
786
        // remove the entire style tag
787 1
        $node->parentNode->removeChild($node);
788
      }
789 13
    }
790 13
  }
791
792
  /**
793
   * Remove id and class attributes.
794
   *
795
   * @param  \DOMXPath $xPath The DOMXPath for the entire document.
796
   *
797
   * @return string
798
   */
799 3
  private function cleanupHTML(\DOMXPath $xPath)
800
  {
801 3
    $nodes = $xPath->query('//@class | //@id');
802 3
    foreach ($nodes as $node) {
803 3
      $node->ownerElement->removeAttributeNode($node);
804 3
    }
805 3
  }
806
807
  /**
808
   * Should the IDs and classes be removed?
809
   *
810
   * @param  bool $on Should we enable cleanup?
811
   */
812 3
  public function setCleanup($on = true)
813
  {
814 3
    $this->cleanup = (bool)$on;
815 3
  }
816
817
  /**
818
   * Set the encoding to use with the DOMDocument
819
   *
820
   * @param  string $encoding The encoding to use.
821
   *
822
   * @deprecated Doesn't have any effect
823
   */
824
  public function setEncoding($encoding)
825
  {
826
    $this->encoding = (string)$encoding;
827
  }
828
829
  /**
830
   * Set use of inline styles block
831
   * If this is enabled the class will use the style-block in the HTML.
832
   *
833
   * @param  bool $on Should we process inline styles?
834
   */
835 26
  public function setUseInlineStylesBlock($on = true)
836
  {
837 26
    $this->useInlineStylesBlock = (bool)$on;
838 26
  }
839
840
  /**
841
   * Set use of inline link block
842
   * If this is enabled the class will use the links reference in the HTML.
843
   *
844
   * @return void
845
   *
846
   * @param  bool [optional] $on Should we process link styles?
847
   */
848 2
  public function setLoadCSSFromHTML($on = true)
849
  {
850 2
    $this->loadCSSFromHTML = (bool)$on;
851 2
  }
852
853
  /**
854
   * Set strip original style tags
855
   * If this is enabled the class will remove all style tags in the HTML.
856
   *
857
   * @param  bool $on Should we process inline styles?
858
   */
859 17
  public function setStripOriginalStyleTags($on = true)
860
  {
861 17
    $this->stripOriginalStyleTags = (bool)$on;
862 17
  }
863
864
  /**
865
   * Set exclude media queries
866
   *
867
   * If this is enabled the media queries will be removed before inlining the rules.
868
   *
869
   * WARNING: If you use inline styles block "<style>" the this option will keep the media queries.
870
   *
871
   * @param bool $on
872
   */
873 14
  public function setExcludeMediaQueries($on = true)
874
  {
875 14
    $this->excludeMediaQueries = (bool)$on;
876 14
  }
877
878
  /**
879
   * Set exclude charset
880
   *
881
   * @param bool $on
882
   */
883 1
  public function setExcludeCssCharset($on = true)
884
  {
885 1
    $this->excludeCssCharset = (bool)$on;
886 1
  }
887
888
  /**
889
   * Set exclude conditional inline-style blocks e.g.: <!--[if gte mso 9]><style>.foo { bar } </style><![endif]-->
890
   *
891
   * @param bool $on
892
   */
893 6
  public function setExcludeConditionalInlineStylesBlock($on = true)
894
  {
895 6
    $this->excludeConditionalInlineStylesBlock = (bool)$on;
896 6
  }
897
898
}
899