Example #1
1
 /**
  * Translates CSS into XPath.
  *
  * @param string|array $locator current selector locator
  *
  * @return string
  */
 public function translateToXPath($locator)
 {
     if (!is_string($locator)) {
         throw new \InvalidArgumentException('The CssSelector expects to get a string as locator');
     }
     // Symfony 2.8+ API
     if (class_exists('Symfony\\Component\\CssSelector\\CssSelectorConverter')) {
         $converter = new CssSelectorConverter();
         return $converter->toXPath($locator);
     }
     // old static API for Symfony 2.7 and older
     return CSS::toXPath($locator);
 }
 /**
  * @param \DOMNode $node
  * @param string $selector
  * @return \DOMNodeList
  */
 public function findAll($node, $selector)
 {
     $domXPath = new \DOMXPath($node->ownerDocument);
     $converter = new CssSelectorConverter();
     $xpath = $converter->toXPath($selector);
     return $domXPath->query($xpath, $node);
 }
 /**
  * Ensures that attributes can be placed for form element label.
  */
 public function testAttributes() {
   $render_array = [
     '#type' => 'label',
     '#attributes' => ['class' => ['kitten']],
     '#title' => 'Kittens',
     '#title_display' => 'above',
   ];
   $css_selector_converter = new CssSelectorConverter();
   $this->render($render_array);
   $elements = $this->xpath($css_selector_converter->toXPath('.kitten'));
   $this->assertCount(1, $elements);
 }
 public function toXpath($selector, $contextMode = self::CONTEXT_CHILDREN, $isHtml = FALSE)
 {
     $converter = new CssSelectorConverter($isHtml);
     $result = $converter->toXPath($selector);
     switch ($contextMode) {
         case self::CONTEXT_DOCUMENT:
             $result = '//' . $result;
             break;
         case self::CONTEXT_CHILDREN:
             $result = './' . $result;
             break;
     }
     return $result;
 }
 public function toXPath()
 {
     try {
         if (class_exists('Symfony\\Component\\CssSelector\\CssSelectorConverter')) {
             $converter = new CssSelectorConverter();
             $query = $converter->toXPath($this->selector);
         } else {
             $query = CssSelector::toXPath($this->selector);
         }
     } catch (ExceptionInterface $e) {
         $query = null;
     }
     return $query;
 }
Example #6
0
 /**
  * select multiple elements from dom using css style selectors
  * @param string $selector
  * @return NodeCollection
  */
 public function querySelectorAll($selector)
 {
     $converter = new CssSelectorConverter();
     $xpathQuery = $converter->toXPath($selector);
     $results = $this->xpath->query($xpathQuery);
     if (!$results->item(0)) {
         return [];
     }
     $return = new NodeCollection();
     for ($i = 0; $i < $results->length; $i++) {
         $node = new Node($results->item($i));
         $return->append($node);
     }
     return $return;
 }
 /**
  * @param string $cssExpr
  * @return string
  */
 public function convertToXpath($cssExpr)
 {
     preg_match('!(.+) (@.+|.+\\(\\))$!', $cssExpr, $data);
     if (empty($data[2])) {
         return parent::toXPath($cssExpr);
     }
     return parent::toXPath($data[1]) . '/' . $data[2];
 }
Example #8
0
 public function query($selector)
 {
     $selector = trim($selector);
     $converter = new CssSelectorConverter();
     $prefix = '//';
     if ($selector[0] == '>') {
         $selector = trim(substr($selector, 1));
         $prefix = '';
     }
     $xPath = $converter->toXPath($selector, $prefix);
     $parser = new \DOMXPath($this->getDocument());
     $nodeList = [];
     foreach ($this->nodeList as $node) {
         $nodeList = array_merge($nodeList, iterator_to_array($parser->query($xPath, $node)));
     }
     $className = get_class($this);
     return (new $className())->fromNodeList($nodeList);
 }
 public function matchesNode($node)
 {
     $matches_node = parent::matchesNode($node);
     if ($matches_node && $this->childSelector) {
         $matches_node = false;
         if ($node->hasChildNodes()) {
             foreach ($node->childNodes as $child) {
                 $domXPath = new \DOMXPath($child->ownerDocument);
                 $converter = new CssSelectorConverter();
                 $xpath = $converter->toXPath($this->childSelector);
                 $results = $domXPath->query($xpath, $node);
                 foreach ($results as $result) {
                     if ($result === $child) {
                         $matches_node = true;
                     }
                 }
             }
         }
     }
     return $matches_node;
 }
 public static function toXPath($selector)
 {
     if (isset(self::$compiled[$selector])) {
         return self::$compiled[$selector];
     }
     // Select DOMText
     if ($selector === 'text') {
         return '//text()';
     }
     // Select DOMComment
     if ($selector === 'comment') {
         return '//comment()';
     }
     if (!class_exists('Symfony\\Component\\CssSelector\\CssSelectorConverter')) {
         throw new \RuntimeException('Unable to filter with a CSS selector as the Symfony CssSelector 2.8+ is not installed (you can use filterXPath instead).');
     }
     $converter = new CssSelectorConverter(true);
     $xPathQuery = $converter->toXPath($selector);
     self::$compiled[$selector] = $xPathQuery;
     return $xPathQuery;
 }
Example #11
0
 public function doValidation(Response $response)
 {
     $domDocument = new \DOMDocument();
     @$domDocument->loadHTML((string) $response->getBody());
     $domXPath = new \DOMXPath($domDocument);
     $error = false;
     $snotFoundSelectors = array();
     foreach ($this->cssSelectors as $selector) {
         $converter = new CssSelectorConverter();
         $selectorAsXPath = $converter->toXPath($selector['pattern']);
         $count = $domXPath->query($selectorAsXPath)->length;
         if ($count === 0) {
             $error = true;
             $snotFoundSelectors[] = $selector['pattern'];
         }
     }
     if ($error === true) {
         $allNotFoundSelectors = implode('", "', $snotFoundSelectors);
         throw new ValidationFailedException('CSS Selector "' . $allNotFoundSelectors . '" not found in DOM.');
     }
 }
 protected function compare()
 {
     $bench = new Ubench();
     $url = 'tests/templated-retrospect/index.html';
     $file = 'test.html';
     if (!file_exists($file)) {
         $htmlstr = file_get_contents($url);
         file_put_contents($file, $htmlstr);
     }
     $htmlstr = file_get_contents($file);
     $this->log('', true);
     $this->log('Measuring Simple HTML DOM Parser...');
     $resultsSimpleHtmlDomParser = $bench->run(function ($htmlstr) {
         $results = [];
         $html = HtmlDomParser::str_get_html($htmlstr);
         $html->find('title', 0)->innertext('New Title');
         $results[1] = $html->__toString();
         $tpl = HtmlDomParser::str_get_html(file_get_contents('tests/templated-retrospect/index.html'));
         foreach ($tpl->find('link') as $elem) {
             $elem->href = '//localhost/xparser/tests/templated-retrospect/' . $elem->href;
         }
         foreach ($tpl->find('img, script') as $elem) {
             $elem->src = '//localhost/xparser/tests/templated-retrospect/' . $elem->src;
         }
         $results[2] = $tpl->__toString();
         return $results;
     }, $htmlstr);
     //$this->log('distance: ' . similar_text($htmlstr, $result));
     $this->logBench($bench);
     $this->log('', true);
     $this->log('Measuring XParser...');
     $resultsXParser = $bench->run(function ($htmlstr) {
         $results = [];
         $html = new XNode($htmlstr);
         $html->find('title')->inner('New Title');
         $results[1] = $html->__toString();
         $tpl = new XNode(file_get_contents('tests/templated-retrospect/index.html'));
         foreach ($tpl('link') as $elem) {
             $elem->href = '//localhost/xparser/tests/templated-retrospect/' . $elem->href;
         }
         foreach ($tpl('img, script') as $elem) {
             $elem->src = '//localhost/xparser/tests/templated-retrospect/' . $elem->src;
         }
         $results[2] = $tpl->__toString();
         return $results;
     }, $htmlstr);
     //$this->log('distance: ' . similar_text($htmlstr, $result));
     $this->logBench($bench);
     $this->log('', true);
     $this->log('Measuring Ganon...');
     $resultsGanon = $bench->run(function ($htmlstr) {
         $html = str_get_dom($htmlstr);
         foreach ($html('title') as $title) {
             $title->setInnerText('New Title');
         }
         $results[1] = $html->__toString();
         $tpl = new XNode(file_get_contents('tests/templated-retrospect/index.html'));
         foreach ($tpl('link') as $elem) {
             $elem->href = '//localhost/xparser/tests/templated-retrospect/' . $elem->href;
         }
         foreach ($tpl('img, script') as $elem) {
             $elem->src = '//localhost/xparser/tests/templated-retrospect/' . $elem->src;
         }
         $results[2] = $tpl->__toString();
         return $results;
     }, $htmlstr);
     //$this->log('distance: ' . similar_text($htmlstr, $result));
     $this->logBench($bench);
     $this->log('', true);
     $this->log('Symfony CSS Selector combined with DOMDocument and DOMXPath...');
     $resultsXParser = $bench->run(function ($htmlstr) {
         $results = [];
         $html = new DOMDocument();
         libxml_use_internal_errors(true);
         $html->loadHTML($htmlstr);
         $converter = new CssSelectorConverter();
         $xpath = new DOMXPath($html);
         $elements = $xpath->query($converter->toXPath('title'));
         foreach ($elements as $element) {
             $element->innserHTML = 'New Title';
         }
         $results[1] = $html->saveHTML();
         $tpl = new DOMDocument();
         $tpl->load('tests/templated-retrospect/index.html');
         foreach ($xpath->query($converter->toXPath('link')) as $elem) {
             $elem->setAttribute('href', '//localhost/xparser/tests/templated-retrospect/' . $elem->getAttribute('href'));
         }
         foreach ($xpath->query($converter->toXPath('img, script')) as $elem) {
             $elem->setAttribute('src', '//localhost/xparser/tests/templated-retrospect/' . $elem->getAttribute('src'));
         }
         $results[2] = $tpl->saveHTML();
         return $results;
     }, $htmlstr);
     //$this->log('distance: ' . similar_text($htmlstr, $result));
     $this->logBench($bench);
     $this->log('', true);
     $this->log('Simple HTML DOM Parser vs Ganon distance: ' . similar_text($resultsSimpleHtmlDomParser[2], $resultsGanon[2]));
     $this->log('Simple HTML DOM Parser vs XParser distance: ' . similar_text($resultsSimpleHtmlDomParser[2], $resultsXParser[2]));
     $this->log('Ganon vs XParser distance: ' . similar_text($resultsGanon[2], $resultsXParser[2]));
     $this->log('', true);
     $this->log('', true);
 }
Example #13
0
 /**
  * Return the xpath representaiton of the selector, using the appropriate method
  * @return string
  */
 public function xpath()
 {
     if (!$this->_xpath) {
         $ccv = new CssSelectorConverter(true);
         switch ($this->type()) {
             case 'css':
                 $this->_xpath = '//' . $ccv->toXPath($this->selector());
                 break;
             case 'xpath':
                 $this->_xpath = $this->selector();
                 break;
             case 'field':
                 $this->_xpath = $this->field_to_xpath($this->selector());
                 break;
             case 'label':
                 $this->_xpath = $this->label_to_xpath($this->selector());
                 break;
             case 'link':
                 $this->_xpath = $this->link_to_xpath($this->selector());
                 break;
             case 'button':
                 $this->_xpath = $this->button_to_xpath($this->selector());
                 break;
             default:
                 throw new Exception('Locator type ":type" does not exist', array(':type' => $this->_type));
         }
     }
     return $this->_xpath;
 }
 /**
  * @dataProvider getCssToXPathWithoutPrefixTestData
  */
 public function testCssToXPathWithoutPrefix($css, $xpath)
 {
     $converter = new CssSelectorConverter();
     $this->assertEquals($xpath, $converter->toXPath($css, ''), '->parse() parses an input string and returns a node');
 }
Example #15
0
 /**
  * @param string $selectors CSS selector(s)
  * @param string $prefix
  * @return HTMLCollection
  */
 private function css(string $selectors, string $prefix = "descendant-or-self::") : HTMLCollection
 {
     $converter = new CssSelectorConverter();
     $xPathSelector = $converter->toXPath($selectors, $prefix);
     return $this->xPath($xPathSelector);
 }
Example #16
0
 public function getXpath($query, $prefix = NULL)
 {
     $search = array('@<script[^>]*?>.*?</script>@si', '@<[\\/\\!]*?[^<>]*?>@si', '#:(contains|first|last|parent|gt|lt|submit|button|hidden|visible|has|eq)(?!-)\\b([\\(](.*?)[\\)])?#x');
     '/<(' . $tag . '*)\\b([^>]*)>(?:(.*?)(<\\/\\1>))?/ix';
     $query = preg_replace($search, '', $query);
     $x = new CssSelectorConverter();
     $path = $x->toXPath($query, $prefix);
     //var_dump(func_get_arg(0).'=>'.$query);
     return $path;
 }
Example #17
0
 /**
  * Convert a CSS selector to XPath.
  * Uses Symfony CSS Selector 2.8 and above API if possible.
  * Otherwise fallback to pre-2.8 static interface.
  *
  * @param  string $css_selector CSS selector
  * @return string XPath selector
  */
 private function convert_css_selector_to_xpath($css_selector)
 {
     if (class_exists('Symfony\\Component\\CssSelector\\CssSelectorConverter')) {
         $converter = new CssSelector\CssSelectorConverter();
         return $converter->toXPath($this->selector());
     }
     return CssSelector\CssSelector::toXPath($this->selector());
 }
 /**
  * create XPath
  *
  * @param \DOMDocument $document
  * @param array        $cssRules
  *
  * @return \DOMXPath
  */
 private function createXPath(\DOMDocument $document, array $cssRules)
 {
     $propertyStorage = new \SplObjectStorage();
     $xPath = new \DOMXPath($document);
     // any rules?
     if (0 !== count($cssRules)) {
         // loop rules
         foreach ($cssRules as $rule) {
             $ruleSelector = $rule['selector'];
             $ruleProperties = $rule['properties'];
             if (!$ruleSelector || !$ruleProperties) {
                 continue;
             }
             try {
                 $query = $this->cssConverter->toXPath($ruleSelector);
             } catch (ExceptionInterface $e) {
                 $query = null;
             }
             // validate query
             if (null === $query) {
                 continue;
             }
             // search elements
             $elements = $xPath->query($query);
             // validate elements
             if (false === $elements) {
                 continue;
             }
             // loop found elements
             foreach ($elements as $element) {
                 /**
                  * @var $element \DOMElement
                  */
                 if ($ruleSelector == '*' && ($element->tagName == 'html' || $element->tagName === 'title' || $element->tagName == 'meta' || $element->tagName == 'head' || $element->tagName == 'style' || $element->tagName == 'script' || $element->tagName == 'link')) {
                     continue;
                 }
                 // no styles stored?
                 if (!isset($propertyStorage[$element])) {
                     // init var
                     $originalStyle = $element->attributes->getNamedItem('style');
                     if ($originalStyle) {
                         $originalStyle = $originalStyle->value;
                     } else {
                         $originalStyle = '';
                     }
                     // store original styles
                     $propertyStorage->attach($element, $originalStyle);
                     // clear the styles
                     $element->setAttribute('style', '');
                 }
                 // set attribute
                 $propertiesString = $this->createPropertyChunks($element, $ruleProperties);
                 if ($propertiesString) {
                     $element->setAttribute('style', $propertiesString);
                 }
             }
         }
         foreach ($propertyStorage as $element) {
             $originalStyle = $propertyStorage->getInfo();
             if ($originalStyle) {
                 $originalStyles = $this->splitIntoProperties($originalStyle);
                 $originalProperties = $this->splitStyleIntoChunks($originalStyles);
                 // set attribute
                 $propertiesString = $this->createPropertyChunks($element, $originalProperties);
                 if ($propertiesString) {
                     $element->setAttribute('style', $propertiesString);
                 }
             }
         }
     }
     return $xPath;
 }
Example #19
0
<?php

require_once __DIR__ . DELIMITER_DIR . '/jqueryphpmanager.php';
require_once __DIR__ . '/abstracts/selector/CssSelectorConverter.php';
use Symfony\Component\CssSelector\CssSelectorConverter as CssSelector;
CssSelector::autoload();
JqueryBoxManager::autoload();
$backtrace = debug_backtrace();
$namespaceTokens = isset($backtrace[2]) ? $backtrace[2] : NULL;
if (isset($namespaceTokens['class'])) {
    JqueryBoxManager::setNamespace('Loader_' . $namespaceTokens['line'] . '_' . $namespaceTokens['class']);
}
self::$classes[self::$caller] = new JqueryBoxManager();
if (!defined('jqmdoc')) {
    define('jqmdoc', 'jqueryphp_abstracts_document');
}
if (!defined('jqmel')) {
    define('jqmel', 'jqueryphp_abstracts_element');
}
if (!defined('jqmnull')) {
    define('jqmnull', 'jqueryphp_abstracts_prevObject');
}
if (!defined('jqmlist')) {
    define('jqmlist', 'jqueryphp_abstracts_nodelist');
}
if (!defined('jqmwin')) {
    define('jqmwin', 'jqueryphp_abstracts_window');
}
if (!function_exists('jqm')) {
    function jqm($input, $parent = '*')
    {
 /**
  * Helper to convert css path to xpath using Symfony component.
  *
  * @param string $selector
  *   CSS selector string.
  *
  * @return string
  *   Xpath string.
  */
 protected function cssToXpath($selector)
 {
     // Use CssSelector class from Symfony framework.
     if (!class_exists('Symfony\\Component\\CssSelector\\CssSelectorConverter')) {
         throw new Exception(t('Unable to load class Symfony\\Component\\CssSelector\\CssSelectorConverter'));
     }
     $converter = new CssSelectorConverter();
     return $converter->toXpath($selector);
 }
Example #21
0
 /**
  * Returns a list of the elements within the document that match the specified group of selectors.
  * 
  * @param string  $filename  CSS Selector
  * 
  * @return DOMNodeList  List of matching elements (will be empty if no matches are found).
  */
 public function querySelectorAll($cssSelectors)
 {
     $xpathQuery = $this->converter->toXPath($cssSelectors);
     return $this->query($xpathQuery);
 }
Example #22
0
        };
        $array2query = function ($new) {
            $arr = array();
            foreach ($new as $k => $v) {
                $arr[] = $k . '=' . $v;
            }
            return implode('&', $arr);
        };
        $new = $query2array($d['query'], 3);
        asort($new);
        return $d['scheme'] . '://' . $d['host'] . '/?' . $array2query($new) . '&url=' . $d['path'];
    }
    return '<pre>' . print_r(array('param' => $url, 'res' => urlT($url)), true) . '</pre>';
});
$app->get('/test3/', function () {
    $converter = new CssSelectorConverter();
    return '<pre>' . $converter->toXPath('div.item > h4 > a') . '</pre>';
});
$app->post('/game.php', function (Request $request) {
    $game = new Game\GomokuGame();
    $reset = $request->get('reset');
    $x = $request->get('x');
    $y = $request->get('y');
    if (isset($reset) && !empty($reset)) {
        $game->reset();
        return new JsonResponse(array('reset' => $reset));
    } elseif ($x >= 0 && $y >= 0) {
        try {
            $game->makeMove((int) $x, (int) $y);
            $machineMove = $game->machineMove();
            $game->checkWinner();
Example #23
0
 /**
  * Filters the list of nodes with a CSS selector.
  *
  * This method only works if you have installed the CssSelector Symfony Component.
  *
  * @param string $selector A CSS selector
  *
  * @return Crawler A new instance of Crawler with the filtered list of nodes
  *
  * @throws \RuntimeException if the CssSelector Component is not available
  */
 public function filter($selector)
 {
     if (!class_exists('Symfony\\Component\\CssSelector\\CssSelectorConverter')) {
         throw new \RuntimeException('Unable to filter with a CSS selector as the Symfony CssSelector 2.8+ is not installed (you can use filterXPath instead).');
     }
     $converter = new CssSelectorConverter($this->isHtml);
     // The CssSelector already prefixes the selector with descendant-or-self::
     return $this->filterRelativeXPath($converter->toXPath($selector));
 }
 public function testCssToXPathXml()
 {
     $converter = new CssSelectorConverter(false);
     $this->assertEquals('descendant-or-self::H1', $converter->toXPath('H1'));
 }
Example #25
0
 private function findViaXPath($select, $html = null)
 {
     $document = new DOMDocument();
     libxml_use_internal_errors(true);
     $document->loadHTML(is_null($html) ? $this->__xhtml : $html);
     $converter = new CssSelectorConverter();
     $xpath = new DOMXPath($document);
     $elems = $xpath->query($converter->toXPath($select));
     return $elems;
 }
 /**
  * Converts the loaded HTML into an HTML-string with inline styles based on the loaded CSS
  *
  * @return string
  * @param  bool [optional] $outputXHTML Should we output valid XHTML?
  */
 public function convert($outputXHTML = false)
 {
     // redefine
     $outputXHTML = (bool) $outputXHTML;
     // validate
     if ($this->html == null) {
         throw new Exception('No HTML provided.');
     }
     // should we use inline style-block
     if ($this->useInlineStylesBlock) {
         // init var
         $matches = array();
         // match the style blocks
         preg_match_all('|<style(.*)>(.*)</style>|isU', $this->html, $matches);
         // any style-blocks found?
         if (!empty($matches[2])) {
             // add
             foreach ($matches[2] as $match) {
                 $this->css .= trim($match) . "\n";
             }
         }
     }
     // process css
     $cssRules = $this->processCSS();
     // create new DOMDocument
     $document = new \DOMDocument('1.0', $this->getEncoding());
     // set error level
     $internalErrors = libxml_use_internal_errors(true);
     // load HTML
     $document->loadHTML($this->html);
     // Restore error level
     libxml_use_internal_errors($internalErrors);
     // create new XPath
     $xPath = new \DOMXPath($document);
     // any rules?
     if (!empty($cssRules)) {
         // loop rules
         foreach ($cssRules as $rule) {
             try {
                 if (class_exists("Symfony\\Component\\CssSelector\\CssSelectorConverter")) {
                     // Symfony >= 2.8
                     $cssSelector = new CssSelectorConverter();
                     $query = $cssSelector->toXPath($rule['selector']);
                 } else {
                     // Symfony < 2.8
                     $query = CssSelector::toXPath($rule['selector']);
                 }
             } catch (ExceptionInterface $e) {
                 continue;
             }
             // search elements
             $elements = $xPath->query($query);
             // validate elements
             if ($elements === false) {
                 continue;
             }
             // loop found elements
             foreach ($elements as $element) {
                 // no styles stored?
                 if ($element->attributes->getNamedItem('data-css-to-inline-styles-original-styles') == null) {
                     // init var
                     $originalStyle = '';
                     if ($element->attributes->getNamedItem('style') !== null) {
                         $originalStyle = $element->attributes->getNamedItem('style')->value;
                     }
                     // store original styles
                     $element->setAttribute('data-css-to-inline-styles-original-styles', $originalStyle);
                     // clear the styles
                     $element->setAttribute('style', '');
                 }
                 // init var
                 $properties = array();
                 // get current styles
                 $stylesAttribute = $element->attributes->getNamedItem('style');
                 // any styles defined before?
                 if ($stylesAttribute !== null) {
                     // get value for the styles attribute
                     $definedStyles = (string) $stylesAttribute->value;
                     // split into properties
                     $definedProperties = $this->splitIntoProperties($definedStyles);
                     // loop properties
                     foreach ($definedProperties as $property) {
                         // validate property
                         if ($property == '') {
                             continue;
                         }
                         // split into chunks
                         $chunks = (array) explode(':', trim($property), 2);
                         // validate
                         if (!isset($chunks[1])) {
                             continue;
                         }
                         // loop chunks
                         $properties[$chunks[0]] = trim($chunks[1]);
                     }
                 }
                 // add new properties into the list
                 foreach ($rule['properties'] as $key => $value) {
                     // If one of the rules is already set and is !important, don't apply it,
                     // except if the new rule is also important.
                     if (!isset($properties[$key]) || stristr($properties[$key], '!important') === false || stristr(implode('', $value), '!important') !== false) {
                         $properties[$key] = $value;
                     }
                 }
                 // build string
                 $propertyChunks = array();
                 // build chunks
                 foreach ($properties as $key => $values) {
                     foreach ((array) $values as $value) {
                         $propertyChunks[] = $key . ': ' . $value . ';';
                     }
                 }
                 // build properties string
                 $propertiesString = implode(' ', $propertyChunks);
                 // set attribute
                 if ($propertiesString != '') {
                     $element->setAttribute('style', $propertiesString);
                 }
             }
         }
         // reapply original styles
         // search elements
         $elements = $xPath->query('//*[@data-css-to-inline-styles-original-styles]');
         // loop found elements
         foreach ($elements as $element) {
             // get the original styles
             $originalStyle = $element->attributes->getNamedItem('data-css-to-inline-styles-original-styles')->value;
             if ($originalStyle != '') {
                 $originalProperties = array();
                 $originalStyles = $this->splitIntoProperties($originalStyle);
                 foreach ($originalStyles as $property) {
                     // validate property
                     if ($property == '') {
                         continue;
                     }
                     // split into chunks
                     $chunks = (array) explode(':', trim($property), 2);
                     // validate
                     if (!isset($chunks[1])) {
                         continue;
                     }
                     // loop chunks
                     $originalProperties[$chunks[0]] = trim($chunks[1]);
                 }
                 // get current styles
                 $stylesAttribute = $element->attributes->getNamedItem('style');
                 $properties = array();
                 // any styles defined before?
                 if ($stylesAttribute !== null) {
                     // get value for the styles attribute
                     $definedStyles = (string) $stylesAttribute->value;
                     // split into properties
                     $definedProperties = $this->splitIntoProperties($definedStyles);
                     // loop properties
                     foreach ($definedProperties as $property) {
                         // validate property
                         if ($property == '') {
                             continue;
                         }
                         // split into chunks
                         $chunks = (array) explode(':', trim($property), 2);
                         // validate
                         if (!isset($chunks[1])) {
                             continue;
                         }
                         // loop chunks
                         $properties[$chunks[0]] = trim($chunks[1]);
                     }
                 }
                 // add new properties into the list
                 foreach ($originalProperties as $key => $value) {
                     $properties[$key] = $value;
                 }
                 // build string
                 $propertyChunks = array();
                 // build chunks
                 foreach ($properties as $key => $values) {
                     foreach ((array) $values as $value) {
                         $propertyChunks[] = $key . ': ' . $value . ';';
                     }
                 }
                 // build properties string
                 $propertiesString = implode(' ', $propertyChunks);
                 // set attribute
                 if ($propertiesString != '') {
                     $element->setAttribute('style', $propertiesString);
                 }
             }
             // remove placeholder
             $element->removeAttribute('data-css-to-inline-styles-original-styles');
         }
     }
     // strip original style tags if we need to
     if ($this->stripOriginalStyleTags) {
         $this->stripOriginalStyleTags($xPath);
     }
     // cleanup the HTML if we need to
     if ($this->cleanup) {
         $this->cleanupHTML($xPath);
     }
     // should we output XHTML?
     if ($outputXHTML) {
         // set formating
         $document->formatOutput = true;
         // get the HTML as XML
         $html = $document->saveXML(null, LIBXML_NOEMPTYTAG);
         // remove the XML-header
         $html = ltrim(preg_replace('/<\\?xml (.*)\\?>/', '', $html));
     } else {
         // get the HTML
         $html = $document->saveHTML();
     }
     // return
     return $html;
 }