setAttribute( 'data-parsoid', '{}' ); } private static $blockElementTypes = [ 'div', 'p', // Tables 'table', 'tbody', 'thead', 'tfoot', 'caption', 'th', 'tr', 'td', // Lists 'ul', 'ol', 'li', 'dl', 'dt', 'dd', // HTML5 heading content 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hgroup', // HTML5 sectioning content 'article', 'aside', 'body', 'nav', 'section', 'footer', 'header', 'figure', 'figcaption', 'fieldset', 'details', 'blockquote', // Other 'hr', 'button', 'canvas', 'center', 'col', 'colgroup', 'embed', 'map', 'object', 'pre', 'progress', 'video' ]; /** * @param DOMNode $node Node * @return bool Node is a block element */ private static function isBlockElement( DOMNode $node ) : bool { return $node instanceof DOMElement && in_array( strtolower( $node->tagName ), self::$blockElementTypes ); } /** * Given a comment and a reply link, add the reply link to its document's DOM tree, at the end of * the comment. * * @param CommentItem $comment Comment data returned by parser#groupThreads * @param DOMElement $linkNode Reply link */ public static function addReplyLink( CommentItem $comment, DOMElement $linkNode ) : void { $target = $comment->getRange()->endContainer; // Skip to the end of the "paragraph". This only looks at tag names and can be fooled by CSS, but // avoiding that would be more difficult and slower. while ( $target->nextSibling && !self::isBlockElement( $target->nextSibling ) ) { $target = $target->nextSibling; } // Insert the link before trailing whitespace. // In the MediaWiki parser output,