Jarry1250 has uploaded a new change for review.
https://gerrit.wikimedia.org/r/213799
Change subject: Overhaul replaceIndicesRecursive, adding tests
......................................................................
Overhaul replaceIndicesRecursive, adding tests
Despite the fact that I wrote it, I'm not sure exactly what capabilities
this function was supposed to have. Per TDD, add tests to specify
that (in particular) recursive/multi-layer replacement is required, and
reimplement the underlying function to provide this functionality.
Note that the relatively clunky syntax is a result of the difference
Zend's and HipHop's DOM implementations.
Change-Id: Ie9759089ba76c1294fda73570e2df5a588ff2e4f
---
M SVGFile.php
M tests/phpunit/SVGFileTest.php
M tests/phpunit/SVGMessageGroupTest.php
3 files changed, 72 insertions(+), 18 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/TranslateSvg
refs/changes/99/213799/1
diff --git a/SVGFile.php b/SVGFile.php
index 8daa201..eb270a2 100644
--- a/SVGFile.php
+++ b/SVGFile.php
@@ -636,7 +636,10 @@
/**
* Recursively replaces $1, $2, etc. with text tags, if required. Text
content
- * is formalised as actual text nodes
+ * is formalised as actual text nodes. The basic approach is to jump to
recursively split
+ * on each dollar tag, working through each segment in turn.
+ *
+ * Note that because we're using appendChild(), timing matter: we work
precisely beginning to end.
*
* @param string $text The text to search for $1, $2 etc.
* @param array &$newNodes An array of DOMNodes, indexed by which $
number they represent
@@ -645,27 +648,40 @@
* @return void
*/
public static function replaceIndicesRecursive( $text, &$newNodes,
DOMNode &$parentNode, DOMDocument $document ) {
+ preg_match_all( '/\$([0-9]+)/', $text, $matches );
+
// If nothing to replace, just fire back a text node
- if ( count( $newNodes ) === 0 ) {
- if ( strlen( $text ) > 0 ) {
+ if ( count( $matches[0] ) === 0 ) {
+ if( $parentNode->nodeValue !== $text ){
$parentNode->appendChild(
$document->createTextNode( $text ) );
}
+ return;
}
- // Otherwise, loop through $1, $2, etc. replacing each
- preg_match_all( '/\$([0-9]+)/', $text, $matches );
- foreach ( $newNodes as $index => $node ) {
- // One-indexed (no $0)
- $realIndex = $index + 1;
- if ( !in_array( $realIndex, $matches[1] ) ) {
- // Sanity check
- continue;
- }
- list( $before, $after ) = preg_split( '/\$' .
$realIndex . '(?=[^0-9]|$)/', $text );
- $newNodeToProcess = $newNodes[$index];
- unset( $newNodes[$index] );
+ if( $parentNode->nodeValue == $text ){
+ // Original structure is still present -- remove it so
we have a clean slate
+ // (details are safely stashed in $text)
+ $parentNode->parentNode->replaceChild(
+ $n = $parentNode->cloneNode( false ),
+ $parentNode
+ );
+ $parentNode = $n;
+ }
+
+ // Replace first match and recurse. before-current-after order
matters.
+ $index = $matches[1][0];
+ list( $before, $after ) = preg_split( '/\$' . $index .
'(?=[^0-9]|$)/', $text );
+ if( strlen( $before ) > 0 ){
self::replaceIndicesRecursive( $before, $newNodes,
$parentNode, $document );
- $parentNode->appendChild( $newNodeToProcess );
+ }
+ if( isset( $newNodes[$index-1] ) ){
+ // Implicitly, if $9 doesn't exist, leave a blank space
+ $newNode = $newNodes[$index - 1];
+ $parentNode->appendChild( $newNode );
+ $newNode = $parentNode->lastChild;
+ self::replaceIndicesRecursive( $newNode->nodeValue,
$newNodes, $newNode, $document );
+ }
+ if( strlen( $after ) > 0 ){
self::replaceIndicesRecursive( $after, $newNodes,
$parentNode, $document );
}
}
diff --git a/tests/phpunit/SVGFileTest.php b/tests/phpunit/SVGFileTest.php
index 6b8fa58..92ddef5 100644
--- a/tests/phpunit/SVGFileTest.php
+++ b/tests/phpunit/SVGFileTest.php
@@ -443,6 +443,45 @@
$this->assertArrayEquals( $expected,
$this->svg->getFilteredTextNodes() );
}
+ public function testReplaceIndicesRecursive () {
+ $document = new DOMDocument( '1.0' );
+ $fragment = $document->createTextNode( 'foo' );
+
+ // Simple: single replacement case
+ $parent = $document->createElement( 'text' );
+ $nodes = array( $fragment->cloneNode( true ) );
+ $this->svg->replaceIndicesRecursive( '$1', $nodes, $parent,
$document );
+ $this->assertEquals( 'foo', $parent->nodeValue );
+
+ // Simple multiple replacement case
+ $parent = $document->createElement( 'text' );
+ $nodes = array( $fragment->cloneNode( true ),
$fragment->cloneNode( true ) );
+ $this->svg->replaceIndicesRecursive( '$1bar$2', $nodes,
$parent, $document );
+ $this->assertEquals( 'foobarfoo', $parent->nodeValue );
+
+ // Harder: nested.
+ $parent = $document->createElement( 'text' );
+ $tspan = $document->createElement( 'tspan' );
+ $tspan->appendChild( $document->createTextNode( 'mum$2nun' ) );
+ $tspan2 = $document->createElement( 'tspan' );
+ $tspan2->appendChild( $fragment->cloneNode( true ) );
+ $nodes = array( $tspan, $tspan2 );
+ $this->svg->replaceIndicesRecursive( 'bar$1baz', $nodes,
$parent, $document );
+ $document->appendChild( $parent );
+ $this->assertEquals( '<?xml version="1.0"?>' . "\n" .
'<text>bar<tspan>mum<tspan>foo</tspan>nun</tspan>baz</text>'."\n",
$document->saveXML() );
+
+ // Harder: check attributes are preserved
+ $document = new DOMDocument( '1.0' );
+ $parent = $document->createElement( 'text' );
+ $node = $document->createElement( 'tspan' );
+ $node->setAttribute( 'style', 'font-weight:bold' );
+ $node->appendChild( $document->createTextNode( 'foo' ) );
+ $nodes = array( $node );
+ $this->svg->replaceIndicesRecursive( 'bar$1baz', $nodes,
$parent, $document );
+ $document->appendChild( $parent );
+ $this->assertEquals( '<?xml version="1.0"?>' . "\n" .
'<text>bar<tspan style="font-weight:bold">foo</tspan>baz</text>'."\n",
$document->saveXML() );
+ }
+
public function testSwitchTranslationSetRoundtrip() {
// Functions already tested above
$current = $this->svg->getInFileTranslations();
diff --git a/tests/phpunit/SVGMessageGroupTest.php
b/tests/phpunit/SVGMessageGroupTest.php
index 40b8418..5b48273 100644
--- a/tests/phpunit/SVGMessageGroupTest.php
+++ b/tests/phpunit/SVGMessageGroupTest.php
@@ -73,8 +73,7 @@
public function testGetDescription() {
// Should be normalised to spaces
$name = str_replace( '_', ' ', self::$name );
- $expected = "[[File:$name|thumb|right|upright|275x275px]]
-<div style=\"overflow:auto; padding:2px;\">Created during testing</div>";
+ $expected = "[[File:$name|thumb|right|upright|275x275px]]\n<div
style=\"overflow:auto; padding:2px;\">Created during testing</div>";
$this->assertEquals( $expected,
$this->messageGroup->getDescription() );
}
}
\ No newline at end of file
--
To view, visit https://gerrit.wikimedia.org/r/213799
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie9759089ba76c1294fda73570e2df5a588ff2e4f
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/TranslateSvg
Gerrit-Branch: master
Gerrit-Owner: Jarry1250 <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits