PSR-2 reformatting PHPDoc corrections
[htmlpurifier.git] / library / HTMLPurifier / ChildDef / List.php
blobc9b021b59b1de2f2138c3ac230905bb1c5acac7b
1 <?php
3 /**
4 * Definition for list containers ul and ol.
5 */
6 class HTMLPurifier_ChildDef_List extends HTMLPurifier_ChildDef
8 /**
9 * @type string
11 public $type = 'list';
12 /**
13 * @type array
15 // lying a little bit, so that we can handle ul and ol ourselves
16 // XXX: This whole business with 'wrap' is all a bit unsatisfactory
17 public $elements = array('li' => true, 'ul' => true, 'ol' => true);
19 /**
20 * @param array $tokens_of_children
21 * @param HTMLPurifier_Config $config
22 * @param HTMLPurifier_Context $context
23 * @return array
25 public function validateChildren($tokens_of_children, $config, $context)
27 // Flag for subclasses
28 $this->whitespace = false;
30 // if there are no tokens, delete parent node
31 if (empty($tokens_of_children)) {
32 return false;
35 // the new set of children
36 $result = array();
38 // current depth into the nest
39 $nesting = 0;
41 // a little sanity check to make sure it's not ALL whitespace
42 $all_whitespace = true;
44 $seen_li = false;
45 $need_close_li = false;
47 foreach ($tokens_of_children as $token) {
48 if (!empty($token->is_whitespace)) {
49 $result[] = $token;
50 continue;
52 $all_whitespace = false; // phew, we're not talking about whitespace
54 if ($nesting == 1 && $need_close_li) {
55 $result[] = new HTMLPurifier_Token_End('li');
56 $nesting--;
57 $need_close_li = false;
60 $is_child = ($nesting == 0);
62 if ($token instanceof HTMLPurifier_Token_Start) {
63 $nesting++;
64 } elseif ($token instanceof HTMLPurifier_Token_End) {
65 $nesting--;
68 if ($is_child) {
69 if ($token->name === 'li') {
70 // good
71 $seen_li = true;
72 } elseif ($token->name === 'ul' || $token->name === 'ol') {
73 // we want to tuck this into the previous li
74 $need_close_li = true;
75 $nesting++;
76 if (!$seen_li) {
77 // create a new li element
78 $result[] = new HTMLPurifier_Token_Start('li');
79 } else {
80 // backtrack until </li> found
81 while (true) {
82 $t = array_pop($result);
83 if ($t instanceof HTMLPurifier_Token_End) {
84 // XXX actually, these invariants could very plausibly be violated
85 // if we are doing silly things with modifying the set of allowed elements.
86 // FORTUNATELY, it doesn't make a difference, since the allowed
87 // elements are hard-coded here!
88 if ($t->name !== 'li') {
89 trigger_error("Only li present invariant violated in List ChildDef", E_USER_ERROR);
90 return false;
92 break;
93 } elseif ($t instanceof HTMLPurifier_Token_Empty) { // bleagh
94 if ($t->name !== 'li') {
95 trigger_error("Only li present invariant violated in List ChildDef", E_USER_ERROR);
96 return false;
98 // XXX this should have a helper for it...
99 $result[] = new HTMLPurifier_Token_Start('li', $t->attr, $t->line, $t->col, $t->armor);
100 break;
101 } else {
102 if (!$t->is_whitespace) {
103 trigger_error(
104 "Only whitespace present invariant violated in List ChildDef",
105 E_USER_ERROR
107 return false;
112 } else {
113 // start wrapping (this doesn't precisely mimic
114 // browser behavior, but what browsers do is kind of
115 // hard to mimic in a standards compliant way
116 // XXX Actually, this has no impact in practice,
117 // because this gets handled earlier. Arguably,
118 // we should rip out all of that processing
119 $result[] = new HTMLPurifier_Token_Start('li');
120 $nesting++;
121 $seen_li = true;
122 $need_close_li = true;
125 $result[] = $token;
127 if ($need_close_li) {
128 $result[] = new HTMLPurifier_Token_End('li');
130 if (empty($result)) {
131 return false;
133 if ($all_whitespace) {
134 return false;
136 if ($tokens_of_children == $result) {
137 return true;
139 return $result;
143 // vim: et sw=4 sts=4