* @param array $attribs Attributes of the element
*/
public function __construct( $namespaceURI, $localName, array $attribs ) {
- Assert::parameterType( 'string', $namespaceURI, '$namespaceURI' );
- Assert::parameterType( 'string', $localName, '$localName' );
-
$this->localName = $localName;
$this->namespaceURI = $namespaceURI;
$this->attribs = $attribs;
* Remove the given child from this element.
* @param BalanceElement $elt
*/
- private function removeChild( $elt ) {
+ private function removeChild( BalanceElement $elt ) {
Assert::precondition(
$this->parent !== 'flat', "Can't removeChild after flattening $this"
);
- Assert::parameterType( 'MediaWiki\Tidy\BalanceElement', $elt, '$elt' );
Assert::parameter(
$elt->parent === $this, 'elt', 'must have $this as a parent'
);
* @param BalanceElement $a
* @param BalanceElement|string $b
*/
- public function insertBefore( $a, $b ) {
+ public function insertBefore( BalanceElement $a, $b ) {
Assert::precondition(
$this->parent !== 'flat', "Can't insertBefore after flattening."
);
- Assert::parameterType( 'MediaWiki\Tidy\BalanceElement', $a, '$a' );
- Assert::parameterType( 'MediaWiki\Tidy\BalanceElement|string', $b, '$b' );
$idx = array_search( $a, $this->children, true );
Assert::parameter( $idx !== false, '$a', 'must be a child of $this' );
if ( is_string( $b ) ) {
Assert::precondition(
$this->parent !== 'flat', "Can't appendChild after flattening."
);
- Assert::parameterType( 'MediaWiki\Tidy\BalanceElement|string', $elt, '$elt' );
if ( is_string( $elt ) ) {
array_push( $this->children, $elt );
return;
* Transfer all of the children of $elt to $this.
* @param BalanceElement $elt
*/
- public function adoptChildren( $elt ) {
- Assert::parameterType( 'MediaWiki\Tidy\BalanceElement', $elt, '$elt' );
+ public function adoptChildren( BalanceElement $elt ) {
Assert::precondition(
$elt->parent !== 'flat', "Can't adoptChildren after flattening."
);
$blank = false;
}
}
- if ( $this->isA( 'mw:p-wrap' ) ) {
+ if ( $this->isHtmlNamed( 'mw:p-wrap' ) ) {
$this->localName = 'p';
} elseif ( $blank ) {
// Add 'mw-empty-elt' class so elements can be hidden via CSS
* @return bool
*/
public function isA( $set ) {
- Assert::parameterType( 'MediaWiki\Tidy\BalanceElement|array|string', $set, '$set' );
if ( $set instanceof BalanceElement ) {
return $this === $set;
} elseif ( is_array( $set ) ) {
}
}
+ /**
+ * Determine if this element is an HTML element with the specified name
+ * @param string $tagName
+ * @return bool
+ */
+ public function isHtmlNamed( $tagName ) {
+ return $this->namespaceURI === BalanceSets::HTML_NAMESPACE
+ && $this->localName === $tagName;
+ }
+
/**
* Determine if $this represents an element in the HTML namespace.
*
* @see https://html.spec.whatwg.org/multipage/syntax.html#appropriate-place-for-inserting-a-node
*/
public function insertText( $value ) {
- Assert::parameterType( 'string', $value, '$value' );
if (
$this->fosterParentMode &&
$this->currentNode->isA( BalanceSets::$tableSectionRowSet )
* @return BalanceElement
* @see https://html.spec.whatwg.org/multipage/syntax.html#appropriate-place-for-inserting-a-node
*/
- public function insertElement( $elt ) {
- Assert::parameterType( 'MediaWiki\Tidy\BalanceElement', $elt, '$elt' );
+ public function insertElement( BalanceElement $elt ) {
if (
- $this->currentNode->isA( 'mw:p-wrap' ) &&
+ $this->currentNode->isHtmlNamed( 'mw:p-wrap' ) &&
!$elt->isA( BalanceSets::$tidyInlineSet )
) {
// Tidy compatibility.
/**
* Generate implied end tags.
- * @param BalanceElement|array|string|null $butnot
+ * @param string $butnot
* @param bool $thorough True if we should generate end tags thoroughly.
* @see https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
*/
$endTagSet = $thorough ?
BalanceSets::$thoroughImpliedEndTagsSet :
BalanceSets::$impliedEndTagsSet;
- while ( $this->length() > 0 ) {
- if ( $butnot !== null && $this->currentNode->isA( $butnot ) ) {
+ while ( $this->currentNode ) {
+ if ( $butnot !== null && $this->currentNode->isHtmlNamed( $butnot ) ) {
break;
}
if ( !$this->currentNode->isA( $endTagSet ) ) {
* Return the adjusted current node.
*/
public function adjustedCurrentNode( $fragmentContext ) {
- return ( $fragmentContext && $this->length() === 1 ) ?
+ return ( $fragmentContext && count( $this->elements ) === 1 ) ?
$fragmentContext : $this->currentNode;
}
* @param int $idx
* @param BalanceElement $elt
*/
- public function replaceAt( $idx, $elt ) {
- Assert::parameterType( 'MediaWiki\Tidy\BalanceElement', $elt, '$elt' );
+ public function replaceAt( $idx, BalanceElement $elt ) {
Assert::precondition(
$this->elements[$idx]->parent !== 'flat',
'Replaced element should not have already been flattened.'
} else {
$this->currentNode = null;
}
- if ( !$elt->isA( 'mw:p-wrap' ) ) {
+ if ( !$elt->isHtmlNamed( 'mw:p-wrap' ) ) {
$elt->flatten( $this->tidyCompat );
}
}
* @param int $idx
*/
public function popTo( $idx ) {
- while ( $this->length() > $idx ) {
+ $length = count( $this->elements );
+ for ( $length = count( $this->elements ); $length > $idx; $length-- ) {
$this->pop();
}
}
* @param BalanceElement|array|string $tag
*/
public function popTag( $tag ) {
- while ( $this->length() > 0 ) {
+ while ( $this->currentNode ) {
if ( $this->currentNode->isA( $tag ) ) {
$this->pop();
break;
*/
public function clearToContext( $set ) {
// Note that we don't loop to 0. Never pop the <html> elt off.
- while ( $this->length() > 1 ) {
+ for ( $length = count( $this->elements ); $length > 1; $length-- ) {
if ( $this->currentNode->isA( $set ) ) {
break;
}
* @param BalanceElement $elt The element to remove.
* @param bool $flatten Whether to flatten the removed element.
*/
- public function removeElement( $elt, $flatten = true ) {
- Assert::parameterType( 'MediaWiki\Tidy\BalanceElement', $elt, '$elt' );
+ public function removeElement( BalanceElement $elt, $flatten = true ) {
Assert::parameter(
$elt->parent !== 'flat',
'$elt',
* @param BalanceElement $a
* @param BalanceElement $b
*/
- public function insertAfter( $a, $b ) {
- Assert::parameterType( 'MediaWiki\Tidy\BalanceElement', $a, '$a' );
- Assert::parameterType( 'MediaWiki\Tidy\BalanceElement', $b, '$b' );
+ public function insertAfter( BalanceElement $a, BalanceElement $b ) {
$idx = $this->indexOf( $a );
Assert::parameter( $idx !== false, '$a', 'must be in stack' );
if ( $idx === count( $this->elements ) - 1 ) {
* @see https://html.spec.whatwg.org/multipage/syntax.html#foster-parent
*/
private function fosterParent( $elt ) {
- Assert::parameterType( 'MediaWiki\Tidy\BalanceElement|string', $elt, '$elt' );
$lastTable = $this->indexOf( 'table' );
$lastTemplate = $this->indexOf( 'template' );
$parent = null;
}
} else {
// We're fostering an element; do we need to merge p-wrappers?
- if ( $elt->isA( 'mw:p-wrap' ) ) {
+ if ( $elt->isHtmlNamed( 'mw:p-wrap' ) ) {
$idx = $before ?
array_search( $before, $parent->children, true ) :
count( $parent->children );
$after = $idx > 0 ? $parent->children[$idx - 1] : '';
if (
$after instanceof BalanceElement &&
- $after->isA( 'mw:p-wrap' )
+ $after->isHtmlNamed( 'mw:p-wrap' )
) {
return $after; // Re-use existing p-wrapper.
}
// elements, then pop the current node off the stack of open
// elements and abort these steps.
if (
- $this->currentNode->isA( $tag ) &&
+ $this->currentNode->isHtmlNamed( $tag ) &&
!$afe->isInList( $this->currentNode )
) {
$this->pop();
$stacklen = $this->stack->length();
for ( $j = $i + 1; $j < $stacklen-1; $j++ ) {
$ancestor = $this->stack->node( $stacklen-$j-1 );
- if ( $ancestor->isA( 'template' ) ) {
+ if ( $ancestor->isHtmlNamed( 'template' ) ) {
break;
}
- if ( $ancestor->isA( 'table' ) ) {
+ if ( $ancestor->isHtmlNamed( 'table' ) ) {
$this->switchMode( 'inSelectInTableMode' );
return;
}
case 'li':
# OMITTED: frameset_ok
foreach ( $this->stack as $node ) {
- if ( $node->isA( 'li' ) ) {
+ if ( $node->isHtmlNamed( 'li' ) ) {
$this->inBodyMode( 'endtag', 'li' );
break;
}
case 'dt':
# OMITTED: frameset_ok
foreach ( $this->stack as $node ) {
- if ( $node->isA( 'dd' ) ) {
+ if ( $node->isHtmlNamed( 'dd' ) ) {
$this->inBodyMode( 'endtag', 'dd' );
break;
}
- if ( $node->isA( 'dt' ) ) {
+ if ( $node->isHtmlNamed( 'dt' ) ) {
$this->inBodyMode( 'endtag', 'dt' );
break;
}
case 'optgroup':
case 'option':
- if ( $this->stack->currentNode->isA( 'option' ) ) {
+ if ( $this->stack->currentNode->isHtmlNamed( 'option' ) ) {
$this->inBodyMode( 'endtag', 'option' );
}
$this->afe->reconstruct( $this->stack );
// Any other end tag goes here
foreach ( $this->stack as $i => $node ) {
- if ( $node->isA( $value ) ) {
+ if ( $node->isHtmlNamed( $value ) ) {
$this->stack->generateImpliedEndTags( $value );
$this->stack->popTo( $i ); # including $i
break;
} elseif ( $token === 'endtag' ) {
switch ( $value ) {
case 'colgroup':
- if ( !$this->stack->currentNode->isA( 'colgroup' ) ) {
+ if ( !$this->stack->currentNode->isHtmlNamed( 'colgroup' ) ) {
return true; // Ignore the token.
}
$this->stack->pop();
}
// Anything else
- if ( !$this->stack->currentNode->isA( 'colgroup' ) ) {
+ if ( !$this->stack->currentNode->isHtmlNamed( 'colgroup' ) ) {
return true; // Ignore the token.
}
$this->inColumnGroupMode( 'endtag', 'colgroup' );