Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/htmlpurifier/HTMLPurifier/Filter/ExtractStyleBlocks.php
Go to the documentation of this file.
00001 <?php
00002 
00017 class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
00018 {
00019 
00020     public $name = 'ExtractStyleBlocks';
00021     private $_styleMatches = array();
00022     private $_tidy;
00023 
00024     public function __construct() {
00025         $this->_tidy = new csstidy();
00026     }
00027 
00032     protected function styleCallback($matches) {
00033         $this->_styleMatches[] = $matches[1];
00034     }
00035 
00040     public function preFilter($html, $config, $context) {
00041         $tidy = $config->get('Filter.ExtractStyleBlocks.TidyImpl');
00042         if ($tidy !== null) $this->_tidy = $tidy;
00043         $html = preg_replace_callback('#<style(?:\s.*)?>(.+)</style>#isU', array($this, 'styleCallback'), $html);
00044         $style_blocks = $this->_styleMatches;
00045         $this->_styleMatches = array(); // reset
00046         $context->register('StyleBlocks', $style_blocks); // $context must not be reused
00047         if ($this->_tidy) {
00048             foreach ($style_blocks as &$style) {
00049                 $style = $this->cleanCSS($style, $config, $context);
00050             }
00051         }
00052         return $html;
00053     }
00054 
00063     public function cleanCSS($css, $config, $context) {
00064         // prepare scope
00065         $scope = $config->get('Filter.ExtractStyleBlocks.Scope');
00066         if ($scope !== null) {
00067             $scopes = array_map('trim', explode(',', $scope));
00068         } else {
00069             $scopes = array();
00070         }
00071         // remove comments from CSS
00072         $css = trim($css);
00073         if (strncmp('<!--', $css, 4) === 0) {
00074             $css = substr($css, 4);
00075         }
00076         if (strlen($css) > 3 && substr($css, -3) == '-->') {
00077             $css = substr($css, 0, -3);
00078         }
00079         $css = trim($css);
00080         $this->_tidy->parse($css);
00081         $css_definition = $config->getDefinition('CSS');
00082         foreach ($this->_tidy->css as $k => $decls) {
00083             // $decls are all CSS declarations inside an @ selector
00084             $new_decls = array();
00085             foreach ($decls as $selector => $style) {
00086                 $selector = trim($selector);
00087                 if ($selector === '') continue; // should not happen
00088                 if ($selector[0] === '+') {
00089                     if ($selector !== '' && $selector[0] === '+') continue;
00090                 }
00091                 if (!empty($scopes)) {
00092                     $new_selector = array(); // because multiple ones are possible
00093                     $selectors = array_map('trim', explode(',', $selector));
00094                     foreach ($scopes as $s1) {
00095                         foreach ($selectors as $s2) {
00096                             $new_selector[] = "$s1 $s2";
00097                         }
00098                     }
00099                     $selector = implode(', ', $new_selector); // now it's a string
00100                 }
00101                 foreach ($style as $name => $value) {
00102                     if (!isset($css_definition->info[$name])) {
00103                         unset($style[$name]);
00104                         continue;
00105                     }
00106                     $def = $css_definition->info[$name];
00107                     $ret = $def->validate($value, $config, $context);
00108                     if ($ret === false) unset($style[$name]);
00109                     else $style[$name] = $ret;
00110                 }
00111                 $new_decls[$selector] = $style;
00112             }
00113             $this->_tidy->css[$k] = $new_decls;
00114         }
00115         // remove stuff that shouldn't be used, could be reenabled
00116         // after security risks are analyzed
00117         $this->_tidy->import = array();
00118         $this->_tidy->charset = null;
00119         $this->_tidy->namespace = null;
00120         $css = $this->_tidy->print->plain();
00121         // we are going to escape any special characters <>& to ensure
00122         // that no funny business occurs (i.e. </style> in a font-family prop).
00123         if ($config->get('Filter.ExtractStyleBlocks.Escaping')) {
00124             $css = str_replace(
00125                 array('<',    '>',    '&'),
00126                 array('\3C ', '\3E ', '\26 '),
00127                 $css
00128             );
00129         }
00130         return $css;
00131     }
00132 
00133 }
00134 
00135 // vim: et sw=4 sts=4
 All Data Structures Namespaces Files Functions Variables Enumerations