StrictBlockquote.php 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. <?php
  2. /**
  3. * Takes the contents of blockquote when in strict and reformats for validation.
  4. */
  5. class HTMLPurifier_ChildDef_StrictBlockquote extends HTMLPurifier_ChildDef_Required
  6. {
  7. protected $real_elements;
  8. protected $fake_elements;
  9. public $allow_empty = true;
  10. public $type = 'strictblockquote';
  11. protected $init = false;
  12. /**
  13. * @note We don't want MakeWellFormed to auto-close inline elements since
  14. * they might be allowed.
  15. */
  16. public function getAllowedElements($config) {
  17. $this->init($config);
  18. return $this->fake_elements;
  19. }
  20. public function validateChildren($tokens_of_children, $config, $context) {
  21. $this->init($config);
  22. // trick the parent class into thinking it allows more
  23. $this->elements = $this->fake_elements;
  24. $result = parent::validateChildren($tokens_of_children, $config, $context);
  25. $this->elements = $this->real_elements;
  26. if ($result === false) return array();
  27. if ($result === true) $result = $tokens_of_children;
  28. $def = $config->getHTMLDefinition();
  29. $block_wrap_start = new HTMLPurifier_Token_Start($def->info_block_wrapper);
  30. $block_wrap_end = new HTMLPurifier_Token_End( $def->info_block_wrapper);
  31. $is_inline = false;
  32. $depth = 0;
  33. $ret = array();
  34. // assuming that there are no comment tokens
  35. foreach ($result as $i => $token) {
  36. $token = $result[$i];
  37. // ifs are nested for readability
  38. if (!$is_inline) {
  39. if (!$depth) {
  40. if (
  41. ($token instanceof HTMLPurifier_Token_Text && !$token->is_whitespace) ||
  42. (!$token instanceof HTMLPurifier_Token_Text && !isset($this->elements[$token->name]))
  43. ) {
  44. $is_inline = true;
  45. $ret[] = $block_wrap_start;
  46. }
  47. }
  48. } else {
  49. if (!$depth) {
  50. // starting tokens have been inline text / empty
  51. if ($token instanceof HTMLPurifier_Token_Start || $token instanceof HTMLPurifier_Token_Empty) {
  52. if (isset($this->elements[$token->name])) {
  53. // ended
  54. $ret[] = $block_wrap_end;
  55. $is_inline = false;
  56. }
  57. }
  58. }
  59. }
  60. $ret[] = $token;
  61. if ($token instanceof HTMLPurifier_Token_Start) $depth++;
  62. if ($token instanceof HTMLPurifier_Token_End) $depth--;
  63. }
  64. if ($is_inline) $ret[] = $block_wrap_end;
  65. return $ret;
  66. }
  67. private function init($config) {
  68. if (!$this->init) {
  69. $def = $config->getHTMLDefinition();
  70. // allow all inline elements
  71. $this->real_elements = $this->elements;
  72. $this->fake_elements = $def->info_content_sets['Flow'];
  73. $this->fake_elements['#PCDATA'] = true;
  74. $this->init = true;
  75. }
  76. }
  77. }
  78. // vim: et sw=4 sts=4