File indexing completed on 2024-05-12 06:02:05

0001 <?php
0002 
0003 class HTMLPurifier_Injector_RemoveEmpty extends HTMLPurifier_Injector
0004 {
0005     /**
0006      * @type HTMLPurifier_Context
0007      */
0008     private $context;
0009 
0010     /**
0011      * @type HTMLPurifier_Config
0012      */
0013     private $config;
0014 
0015     /**
0016      * @type HTMLPurifier_AttrValidator
0017      */
0018     private $attrValidator;
0019 
0020     /**
0021      * @type bool
0022      */
0023     private $removeNbsp;
0024 
0025     /**
0026      * @type bool
0027      */
0028     private $removeNbspExceptions;
0029 
0030     /**
0031      * Cached contents of %AutoFormat.RemoveEmpty.Predicate
0032      * @type array
0033      */
0034     private $exclude;
0035 
0036     /**
0037      * @param HTMLPurifier_Config $config
0038      * @param HTMLPurifier_Context $context
0039      * @return void
0040      */
0041     public function prepare($config, $context)
0042     {
0043         parent::prepare($config, $context);
0044         $this->config = $config;
0045         $this->context = $context;
0046         $this->removeNbsp = $config->get('AutoFormat.RemoveEmpty.RemoveNbsp');
0047         $this->removeNbspExceptions = $config->get('AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions');
0048         $this->exclude = $config->get('AutoFormat.RemoveEmpty.Predicate');
0049         foreach ($this->exclude as $key => $attrs) {
0050             if (!is_array($attrs)) {
0051                 // HACK, see HTMLPurifier/Printer/ConfigForm.php
0052                 $this->exclude[$key] = explode(';', $attrs);
0053             }
0054         }
0055         $this->attrValidator = new HTMLPurifier_AttrValidator();
0056     }
0057 
0058     /**
0059      * @param HTMLPurifier_Token $token
0060      */
0061     public function handleElement(&$token)
0062     {
0063         if (!$token instanceof HTMLPurifier_Token_Start) {
0064             return;
0065         }
0066         $next = false;
0067         $deleted = 1; // the current tag
0068         for ($i = count($this->inputZipper->back) - 1; $i >= 0; $i--, $deleted++) {
0069             $next = $this->inputZipper->back[$i];
0070             if ($next instanceof HTMLPurifier_Token_Text) {
0071                 if ($next->is_whitespace) {
0072                     continue;
0073                 }
0074                 if ($this->removeNbsp && !isset($this->removeNbspExceptions[$token->name])) {
0075                     $plain = str_replace("\xC2\xA0", "", $next->data);
0076                     $isWsOrNbsp = $plain === '' || ctype_space($plain);
0077                     if ($isWsOrNbsp) {
0078                         continue;
0079                     }
0080                 }
0081             }
0082             break;
0083         }
0084         if (!$next || ($next instanceof HTMLPurifier_Token_End && $next->name == $token->name)) {
0085             $this->attrValidator->validateToken($token, $this->config, $this->context);
0086             $token->armor['ValidateAttributes'] = true;
0087             if (isset($this->exclude[$token->name])) {
0088                 $r = true;
0089                 foreach ($this->exclude[$token->name] as $elem) {
0090                     if (!isset($token->attr[$elem])) $r = false;
0091                 }
0092                 if ($r) return;
0093             }
0094             if (isset($token->attr['id']) || isset($token->attr['name'])) {
0095                 return;
0096             }
0097             $token = $deleted + 1;
0098             for ($b = 0, $c = count($this->inputZipper->front); $b < $c; $b++) {
0099                 $prev = $this->inputZipper->front[$b];
0100                 if ($prev instanceof HTMLPurifier_Token_Text && $prev->is_whitespace) {
0101                     continue;
0102                 }
0103                 break;
0104             }
0105             // This is safe because we removed the token that triggered this.
0106             $this->rewindOffset($b+$deleted);
0107             return;
0108         }
0109     }
0110 }
0111 
0112 // vim: et sw=4 sts=4