aboutsummaryrefslogtreecommitdiffstats
path: root/includes/tidy/RemexCompatMunger.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/tidy/RemexCompatMunger.php')
-rw-r--r--includes/tidy/RemexCompatMunger.php27
1 files changed, 26 insertions, 1 deletions
diff --git a/includes/tidy/RemexCompatMunger.php b/includes/tidy/RemexCompatMunger.php
index 73bc5f8493ed..c06eea01b18c 100644
--- a/includes/tidy/RemexCompatMunger.php
+++ b/includes/tidy/RemexCompatMunger.php
@@ -174,6 +174,10 @@ class RemexCompatMunger implements TreeHandler {
$length, $sourceStart, $sourceLength );
}
+ private function trace( $msg ) {
+ // echo "[RCM] $msg\n";
+ }
+
/**
* Insert or reparent an element. Create p-wrappers or split the tag stack
* as necessary.
@@ -242,6 +246,7 @@ class RemexCompatMunger implements TreeHandler {
if ( $under && $parentData->isPWrapper && !$inline ) {
// [B/b] The element is non-inline and the parent is a p-wrapper,
// close the parent and insert into its parent instead
+ $this->trace( 'insert B/b' );
$newParent = $this->serializer->getParentNode( $parent );
$parent = $newParent;
$parentData = $parent->snData;
@@ -255,12 +260,14 @@ class RemexCompatMunger implements TreeHandler {
// [CS/b, DS/i] The parent is splittable and the current element is
// inline in block context, or if the current element is a block
// under a p-wrapper, split the tag stack.
+ $this->trace( $inline ? 'insert DS/i' : 'insert CS/b' );
$newRef = $this->splitTagStack( $newRef, $inline, $sourceStart );
$parent = $newRef;
$parentData = $parent->snData;
} elseif ( $under && $parentData->needsPWrapping && $inline ) {
// [A/i] If the element is inline and we are in body/blockquote,
// we need to create a p-wrapper
+ $this->trace( 'insert A/i' );
$newRef = $this->insertPWrapper( $newRef, $sourceStart );
$parent = $newRef;
$parentData = $parent->snData;
@@ -268,9 +275,12 @@ class RemexCompatMunger implements TreeHandler {
// [CU/b] If the element is non-inline and (despite attempting to
// split above) there is still an ancestor p-wrap, disable that
// p-wrap
+ $this->trace( 'insert CU/b' );
$this->disablePWrapper( $parent, $sourceStart );
+ } else {
+ // [A/b, B/i, C/i, D/b, DU/i] insert as normal
+ $this->trace( 'insert normal' );
}
- // else [A/b, B/i, C/i, D/b, DU/i] insert as normal
// An element with element children is a non-blank element
$parentData->nonblankNodeCount++;
@@ -457,6 +467,20 @@ class RemexCompatMunger implements TreeHandler {
public function reparentChildren( Element $element, Element $newParent, $sourceStart ) {
$self = $element->userData;
+ if ( $self->snData->childPElement ) {
+ // Reparent under the p-wrapper instead, so that e.g.
+ // <blockquote><mw:p-wrap>...</mw:p-wrap></blockquote>
+ // becomes
+ // <blockquote><mw:p-wrap><i>...</i></mw:p-wrap></blockquote>
+
+ // The formatting element should not be the parent of the p-wrap.
+ // Without this special case, the insertElement() of the <i> below
+ // would be diverted into the p-wrapper, causing infinite recursion
+ // (T178632)
+ $this->reparentChildren( $self->snData->childPElement, $newParent, $sourceStart );
+ return;
+ }
+
$children = $self->children;
$self->children = [];
$this->insertElement( TreeBuilder::UNDER, $element, $newParent, false, $sourceStart, 0 );
@@ -464,6 +488,7 @@ class RemexCompatMunger implements TreeHandler {
$newParentId = $newParentNode->id;
foreach ( $children as $child ) {
if ( is_object( $child ) ) {
+ $this->trace( "reparent <{$child->name}>" );
$child->parentId = $newParentId;
}
}