1: | <?php
|
2: |
|
3: | class HTMLPurifier_Injector_RemoveEmpty extends HTMLPurifier_Injector
|
4: | {
|
5: | |
6: | |
7: |
|
8: | private $context;
|
9: |
|
10: | |
11: | |
12: |
|
13: | private $config;
|
14: |
|
15: | |
16: | |
17: |
|
18: | private $attrValidator;
|
19: |
|
20: | |
21: | |
22: |
|
23: | private $removeNbsp;
|
24: |
|
25: | |
26: | |
27: |
|
28: | private $removeNbspExceptions;
|
29: |
|
30: | |
31: | |
32: | |
33: |
|
34: | private $exclude;
|
35: |
|
36: | |
37: | |
38: | |
39: | |
40: |
|
41: | public function prepare($config, $context)
|
42: | {
|
43: | parent::prepare($config, $context);
|
44: | $this->config = $config;
|
45: | $this->context = $context;
|
46: | $this->removeNbsp = $config->get('AutoFormat.RemoveEmpty.RemoveNbsp');
|
47: | $this->removeNbspExceptions = $config->get('AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions');
|
48: | $this->exclude = $config->get('AutoFormat.RemoveEmpty.Predicate');
|
49: | foreach ($this->exclude as $key => $attrs) {
|
50: | if (!is_array($attrs)) {
|
51: |
|
52: | $this->exclude[$key] = explode(';', $attrs);
|
53: | }
|
54: | }
|
55: | $this->attrValidator = new HTMLPurifier_AttrValidator();
|
56: | }
|
57: |
|
58: | |
59: | |
60: |
|
61: | public function handleElement(&$token)
|
62: | {
|
63: | if (!$token instanceof HTMLPurifier_Token_Start) {
|
64: | return;
|
65: | }
|
66: | $next = false;
|
67: | $deleted = 1;
|
68: | for ($i = count($this->inputZipper->back) - 1; $i >= 0; $i--, $deleted++) {
|
69: | $next = $this->inputZipper->back[$i];
|
70: | if ($next instanceof HTMLPurifier_Token_Text) {
|
71: | if ($next->is_whitespace) {
|
72: | continue;
|
73: | }
|
74: | if ($this->removeNbsp && !isset($this->removeNbspExceptions[$token->name])) {
|
75: | $plain = str_replace("\xC2\xA0", "", $next->data);
|
76: | $isWsOrNbsp = $plain === '' || ctype_space($plain);
|
77: | if ($isWsOrNbsp) {
|
78: | continue;
|
79: | }
|
80: | }
|
81: | }
|
82: | break;
|
83: | }
|
84: | if (!$next || ($next instanceof HTMLPurifier_Token_End && $next->name == $token->name)) {
|
85: | $this->attrValidator->validateToken($token, $this->config, $this->context);
|
86: | $token->armor['ValidateAttributes'] = true;
|
87: | if (isset($this->exclude[$token->name])) {
|
88: | $r = true;
|
89: | foreach ($this->exclude[$token->name] as $elem) {
|
90: | if (!isset($token->attr[$elem])) $r = false;
|
91: | }
|
92: | if ($r) return;
|
93: | }
|
94: | if (isset($token->attr['id']) || isset($token->attr['name'])) {
|
95: | return;
|
96: | }
|
97: | $token = $deleted + 1;
|
98: | for ($b = 0, $c = count($this->inputZipper->front); $b < $c; $b++) {
|
99: | $prev = $this->inputZipper->front[$b];
|
100: | if ($prev instanceof HTMLPurifier_Token_Text && $prev->is_whitespace) {
|
101: | continue;
|
102: | }
|
103: | break;
|
104: | }
|
105: |
|
106: | $this->rewindOffset($b+$deleted);
|
107: | return;
|
108: | }
|
109: | }
|
110: | }
|
111: |
|
112: |
|
113: | |