:# D1':"Q S$RGΏ 2VqM8a*WI-YJ"j7TW Szy"ǵCjJ(mYvn4zӯ!-r~PYcTyIR7c*h9<"C}`ۣ^EĞof0pOn+#ӒC|XU*SԴXI|mэE WfwRKtfgc(ѷ3`=/Zΐ-hLUmYsB˘hYh2 hw5 x˱c5'4(6q0oe1+S\{o螯DI\ݟ6|.7^7$YɩcR3vG~;p 2+?=i6>Ŗ!9omdp7^7$YɩięcMyk|_&OX<~CN4׃QoB91^+Mvy7!zJ]v:R ZhYWU@A"Oe܆ϿEcͷięcMyk|_9L\rd2'?< J\a89׵\.%adtߺR<ǵũۡ.?af]%](N4QHE0n֋WǯR xHLnvзbÒ?%ihYxA,؏R wڀ/Fx(~C⋢eQx}G+"&Ż?<,| ks&n^c2̀4GfbP\ G^Zcm2´i'5`.a58 ކ/KaɪgGg_A_St G]+΅g쥎mvgJ7+Ad2'?< a\q*BS$T^W&?s/? Ғ&UבX&0z<\ypc!l>Apq5PU[tOu!QyH*2hco: TQoB91^+Mބz\V5@p퉿e>TNL1$  n$iHYs |b3\=7*ʢ\V\kGpdEK' 8c*_Ky88.<<ʸ~Xޞ֣o]BB`Ĭ,țYX{?jZ>:`|Yi0~0>xJVoXiT2Zd\usB^_ !,4e_2 gS)'/e ,>yxaW>!Kx=0jda(<_ro$'1hEAm4#m(e(CWF >=~AWQ2Jq}6J F"^2+c㊏:3\U.e<1$#Vϼ"jqYg4ȱuCv9 h0UL'h?@I3bͲ)l( 5 fKO&7p}gDtdl VZO;x22y@y=rma0/KI|jcm2´i'5`z` :n=,+ W.Juq};䵦@)x1xf6 ߛہÇ`gJ1k%l,$ o if(tj)D0|ptd>ICpq_2NRU<:¨(EG \Pc:w*eܤi`wʭ} ]ZN(҇\g6RۍDH [ÃR( }{ EyxaW>!K&]Y{^."ox(-mAUdCQi}bKBpK4DLFk/>z@ 5,XZvE3 rSaѯxkjܼzBCv9 h0UL'h?@I3bͲ)l( X-i.*}r:~8z@kj`e蒼)RCv9  jz688/{uG~X:':۝ ig;zFXӁ?kC'CBλW0հ'^; pnSF5(|s4}Ʀ65f{'Ma^_)!^ cS;bwU.8n;Lhhw1_!ෑ!e3:q/CF.B 4q {1nB ZJwA(3,1Q: Jke52y@y=rmj"Oȥ,{%Pg-'7CP}jF2NF, kȭle: Ԗ4ѻw|Ҙ iwQi!V9 83]+HNFt\wtoί,є U {t4Q iqytrzRzsO5f1kQ*Q|_C o&n^c2̀4Gfb]8L&Uϭz#HhNK_o}d2jب(_$w$S Yucbt:۝ ig59#L E6OO|HMYj&@^EqޘbGtU!#j3Y.Iat=6s:n7t%3-_%uDWFo)D o~ 5f{'Ma^_)!^ cS;bwU.8n;Lh*ȲOT:W};ݟh$ rPҷNcue ,>yxaW>!KLD̲_qC&*;iv@ 5,X"9x=<&(wZzѻ'_EWge Ó܈M"JnEQZ,\[)vcX7Vȅ0!!Dݡ!ug`)H7<]Yʾ7p+9z~H(3d42y@y=rm<9$M']!kQ|HMYj&@ y07+ܿF-gth]m[6P(k&u&n^c2̀4Gfb8$.9:1u`e;yq<`O?5׈$name => $def) { $ret .= $this->start('tr'); $ret .= $this->element('th', "<$name>", array('class' => 'heavy', 'colspan' => 2)); $ret .= $this->end('tr'); $ret .= $this->start('tr'); $ret .= $this->element('th', 'Inline content'); $ret .= $this->element('td', $def->descendants_are_inline ? 'Yes' : 'No'); $ret .= $this->end('tr'); if (!empty($def->excludes)) { $ret .= $this->start('tr'); $ret .= $this->element('th', 'Excludes'); $ret .= $this->element('td', $this->listifyTagLookup($def->excludes)); $ret .= $this->end('tr'); } if (!empty($def->attr_transform_pre)) { $ret .= $this->start('tr'); $ret .= $this->element('th', 'Pre-AttrTransform'); $ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_pre)); $ret .= $this->end('tr'); } if (!empty($def->attr_transform_post)) { $ret .= $this->start('tr'); $ret .= $this->element('th', 'Post-AttrTransform'); $ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_post)); $ret .= $this->end('tr'); } if (!empty($def->auto_close)) { $ret .= $this->start('tr'); $ret .= $this->element('th', 'Auto closed by'); $ret .= $this->element('td', $this->listifyTagLookup($def->auto_close)); $ret .= $this->end('tr'); } $ret .= $this->start('tr'); $ret .= $this->element('th', 'Allowed attributes'); $ret .= $this->element('td', $this->listifyAttr($def->attr), array(), 0); $ret .= $this->end('tr'); if (!empty($def->required_attr)) { $ret .= $this->row('Required attributes', $this->listify($def->required_attr)); } $ret .= $this->renderChildren($def->child); } $ret .= $this->end('table'); return $ret; } /** * Renders a row describing the allowed children of an element * @param HTMLPurifier_ChildDef $def HTMLPurifier_ChildDef of pertinent element * @return string */ protected function renderChildren($def) { $context = new HTMLPurifier_Context(); $ret = ''; $ret .= $this->start('tr'); $elements = array(); $attr = array(); if (isset($def->elements)) { if ($def->type == 'strictblockquote') { $def->validateChildren(array(), $this->config, $context); } $elements = $def->elements; } if ($def->type == 'chameleon') { $attr['rowspan'] = 2; } elseif ($def->type == 'empty') { $elements = array(); } elseif ($def->type == 'table') { $elements = array_flip( array( 'col', 'caption', 'colgroup', 'thead', 'tfoot', 'tbody', 'tr' ) ); } $ret .= $this->element('th', 'Allowed children', $attr); if ($def->type == 'chameleon') { $ret .= $this->element( 'td', 'Block: ' . $this->escape($this->listifyTagLookup($def->block->elements)), null, 0 ); $ret .= $this->end('tr'); $ret .= $this->start('tr'); $ret .= $this->element( 'td', 'Inline: ' . $this->escape($this->listifyTagLookup($def->inline->elements)), null, 0 ); } elseif ($def->type == 'custom') { $ret .= $this->element( 'td', '' . ucfirst($def->type) . ': ' . $def->dtd_regex ); } else { $ret .= $this->element( 'td', '' . ucfirst($def->type) . ': ' . $this->escape($this->listifyTagLookup($elements)), null, 0 ); } $ret .= $this->end('tr'); return $ret; } /** * Listifies a tag lookup table. * @param array $array Tag lookup array in form of array('tagname' => true) * @return string */ protected function listifyTagLookup($array) { ksort($array); $list = array(); foreach ($array as $name => $discard) { if ($name !== '#PCDATA' && !isset($this->def->info[$name])) { continue; } $list[] = $name; } return $this->listify($list); } /** * Listifies a list of objects by retrieving class names and internal state * @param array $array List of objects * @return string * @todo Also add information about internal state */ protected function listifyObjectList($array) { ksort($array); $list = array(); foreach ($array as $obj) { $list[] = $this->getClass($obj, 'AttrTransform_'); } return $this->listify($list); } /** * Listifies a hash of attributes to AttrDef classes * @param array $array Array hash in form of array('attrname' => HTMLPurifier_AttrDef) * @return string */ protected function listifyAttr($array) { ksort($array); $list = array(); foreach ($array as $name => $obj) { if ($obj === false) { continue; } $list[] = "$name = " . $this->getClass($obj, 'AttrDef_') . ''; } return $this->listify($list); } /** * Creates a heavy header row * @param string $text * @param int $num * @return string */ protected function heavyHeader($text, $num = 1) { $ret = ''; $ret .= $this->start('tr'); $ret .= $this->element('th', $text, array('colspan' => $num, 'class' => 'heavy')); $ret .= $this->end('tr'); return $ret; } } // vim: et sw=4 sts=4