Gergő Tisza has uploaded a new change for review. https://gerrit.wikimedia.org/r/130807
Change subject: Handle <th> elements in {{Information}} template ...................................................................... Handle <th> elements in {{Information}} template So far we assumed all cells in the left column of the info template are <td>s, which is not the case (even though COM:MRD does prescribe it). Change-Id: I78071b119eaa808de4a46addf8305136f7639c11 Mingle: https://wikimedia.mingle.thoughtworks.com/projects/multimedia/cards/249 --- M DomNavigator.php M TemplateParser.php M tests/phpunit/DomNavigatorTest.php 3 files changed, 33 insertions(+), 5 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/CommonsMetadata refs/changes/07/130807/1 diff --git a/DomNavigator.php b/DomNavigator.php index d8ff04b..a04b3f9 100644 --- a/DomNavigator.php +++ b/DomNavigator.php @@ -37,12 +37,13 @@ /** * Returns a list of elements of the given type which have the given class. * (In other words, this is equivalent to the CSS selector 'element.class'.) - * @param string $element HTML tag name (* to accept all) + * @param string|array $element HTML tag name (* to accept all) or array of tag names * @param string $class * @param DOMNode $context if present, the method will only search inside this element * @return DOMNodeList|DOMElement[] */ public function findElementsWithClass( $element, $class, DOMNode $context = null ) { + $element = $this->handleElementOrList( $element ); $xpath = "./descendant-or-self::{$element}[contains(concat(' ', normalize-space(@class), ' '), ' $class ')]"; return $this->findByXpath( $xpath, $context ); } @@ -50,12 +51,13 @@ /** * Returns a list of elements of the given type which have the given class and any lang attribute. * (In other words, this is equivalent to the CSS selector 'element.class[lang]'.) - * @param string $element HTML tag name (* to accept all) + * @param string|array $element HTML tag name (* to accept all) or array of tag names * @param string $class * @param DOMNode $context if present, the method will only search inside this element * @return DOMNodeList|DOMElement[] */ public function findElementsWithClassAndLang( $element, $class, DOMNode $context = null ) { + $element = $this->handleElementOrList( $element ); $xpath = "./descendant-or-self::{$element}[@lang and contains(concat(' ', normalize-space(@class), ' '), ' $class ')]"; return $this->findByXpath( $xpath, $context ); } @@ -64,12 +66,13 @@ * Returns a list of elements of the given type which have the given id. * (In other words, this is equivalent to the CSS selector 'element#id'.) * When there are multiple elements with this ID, all are returned. - * @param string $element HTML tag name (* to accept all) + * @param string|array $element HTML tag name (* to accept all) or array of tag names * @param string $id * @param DOMNode $context if present, the method will only search inside this element * @return DOMNodeList|DOMElement[] */ public function findElementsWithId( $element, $id, DOMNode $context = null ) { + $element = $this->handleElementOrList( $element ); $xpath = "./descendant-or-self::{$element}[@id='$id']"; return $this->findByXpath( $xpath, $context ); } @@ -77,12 +80,13 @@ /** * Returns a list of elements of the given type which have an id starting with the given prefix. * (In other words, this is equivalent to the CSS selector 'element[id^=prefix]'.) - * @param string $element HTML tag name (* to accept all) + * @param string|array $element HTML tag name (* to accept all) or array of tag names * @param string $idPrefix * @param DOMNode $context if present, the method will only search inside this element * @return DOMNodeList|DOMElement[] */ public function findElementsWithIdPrefix( $element, $idPrefix, DOMNode $context = null ) { + $element = $this->handleElementOrList( $element ); $xpath = "./descendant-or-self::{$element}[starts-with(@id, '$idPrefix')]"; return $this->findByXpath( $xpath, $context ); } @@ -163,4 +167,19 @@ } return $nextSibling; } + + /** + * Takes an element name or array of element names and returns an XPath expression which can + * be used as an element name, but matches all of the provided elements. + * @param string|array $elmementOrList + * @return string + */ + protected function handleElementOrList( $elmementOrList ) { + if ( is_array( $elmementOrList ) ) { + return '*[' . implode( ' or ', array_map( function ( $el ) { return 'self::' . $el; }, $elmementOrList ) ) . ']'; + } else { + return $elmementOrList; + } + } + } diff --git a/TemplateParser.php b/TemplateParser.php index 8b764fc..d439b1f 100755 --- a/TemplateParser.php +++ b/TemplateParser.php @@ -147,7 +147,7 @@ protected function parseInformationFields( DomNavigator $domNavigator ) { $data = array(); - foreach ( $domNavigator->findElementsWithIdPrefix( 'td', 'fileinfotpl_' ) as $labelField ) { + foreach ( $domNavigator->findElementsWithIdPrefix( array( 'td', 'th' ), 'fileinfotpl_' ) as $labelField ) { $id = $labelField->getAttribute( 'id' ); if ( !isset( self::$informationFieldClasses[$id] ) ) { continue; diff --git a/tests/phpunit/DomNavigatorTest.php b/tests/phpunit/DomNavigatorTest.php index 621453d..73ea47e 100644 --- a/tests/phpunit/DomNavigatorTest.php +++ b/tests/phpunit/DomNavigatorTest.php @@ -81,6 +81,15 @@ $this->assertNodeListTextEquals( array( '2' ), $nodes ); } + public function testMultipleElementNames() { + $navigator = new DomNavigator( '<div><span class="foo">1</span><div class="foo">2</div><span>3</span><p class="foo">4</p></p></div>' ); + $nodes = $navigator->findElementsWithClass( '*', 'foo' ); + $this->assertNodeListTextEquals( array( '1', '2', '4' ), $nodes ); + + $nodes = $navigator->findElementsWithClass( array( 'span', 'div' ), 'foo' ); + $this->assertNodeListTextEquals( array( '1', '2' ), $nodes ); + } + public function testFindElementsWithClassAndLang() { $navigator = new DomNavigator( '<div><span lang="en">1</span><span class="foo">2</span><span lang="en" class="foo">3</span></div>' ); $nodes = $navigator->findElementsWithClassAndLang( 'span', 'foo' ); -- To view, visit https://gerrit.wikimedia.org/r/130807 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I78071b119eaa808de4a46addf8305136f7639c11 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/CommonsMetadata Gerrit-Branch: master Gerrit-Owner: Gergő Tisza <gti...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits