Skip to content

Commit 5689f8b

Browse files
authored
Merge branch 'master' into fix-e-html-output
2 parents e01b98e + 2c6677d commit 5689f8b

File tree

3 files changed

+138
-15
lines changed

3 files changed

+138
-15
lines changed

Mf2/Parser.php

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ function unicodeTrim($str) {
130130
function mfNamesFromClass($class, $prefix='h-') {
131131
$class = str_replace(array(' ', ' ', "\n"), ' ', $class);
132132
$classes = explode(' ', $class);
133-
$classes = preg_grep('#^[a-z\-]+$#', $classes);
133+
$classes = preg_grep('#^(h|p|u|dt|e)-([a-z0-9]+-)?[a-z]+(-[a-z]+)*$#', $classes);
134134
$matches = array();
135135

136136
foreach ($classes as $classname) {
@@ -1257,16 +1257,15 @@ public function parseRelsAndAlternates() {
12571257

12581258
// Iterate through all a, area and link elements with rel attributes
12591259
foreach ($this->xpath->query('//a[@rel and @href] | //link[@rel and @href] | //area[@rel and @href]') as $hyperlink) {
1260-
if ($hyperlink->getAttribute('rel') == '') {
1260+
// Parse the set of rels for the current link
1261+
$linkRels = array_unique(array_filter(preg_split('/[\t\n\f\r ]/', $hyperlink->getAttribute('rel'))));
1262+
if (count($linkRels) === 0) {
12611263
continue;
12621264
}
12631265

12641266
// Resolve the href
12651267
$href = $this->resolveUrl($hyperlink->getAttribute('href'));
12661268

1267-
// Split up the rel into space-separated values
1268-
$linkRels = array_filter(explode(' ', $hyperlink->getAttribute('rel')));
1269-
12701269
$rel_attributes = array();
12711270

12721271
if ($hyperlink->hasAttribute('media')) {
@@ -1285,8 +1284,8 @@ public function parseRelsAndAlternates() {
12851284
$rel_attributes['type'] = $hyperlink->getAttribute('type');
12861285
}
12871286

1288-
if ($hyperlink->nodeValue) {
1289-
$rel_attributes['text'] = $hyperlink->nodeValue;
1287+
if (strlen($hyperlink->textContent) > 0) {
1288+
$rel_attributes['text'] = $hyperlink->textContent;
12901289
}
12911290

12921291
if ($this->enableAlternates) {
@@ -1303,16 +1302,34 @@ public function parseRelsAndAlternates() {
13031302
}
13041303

13051304
foreach ($linkRels as $rel) {
1306-
$rels[$rel][] = $href;
1305+
if (!array_key_exists($rel, $rels)) {
1306+
$rels[$rel] = array($href);
1307+
} elseif (!in_array($href, $rels[$rel])) {
1308+
$rels[$rel][] = $href;
1309+
}
13071310
}
13081311

1309-
if (!in_array($href, $rel_urls)) {
1310-
$rel_urls[$href] = array_merge(
1311-
$rel_attributes,
1312-
array('rels' => $linkRels)
1313-
);
1312+
if (!array_key_exists($href, $rel_urls)) {
1313+
$rel_urls[$href] = array('rels' => array());
13141314
}
13151315

1316+
// Add the attributes collected only if they were not already set
1317+
$rel_urls[$href] = array_merge(
1318+
$rel_attributes,
1319+
$rel_urls[$href]
1320+
);
1321+
1322+
// Merge current rels with those already set
1323+
$rel_urls[$href]['rels'] = array_merge(
1324+
$rel_urls[$href]['rels'],
1325+
$linkRels
1326+
);
1327+
}
1328+
1329+
// Alphabetically sort the rels arrays after removing duplicates
1330+
foreach ($rel_urls as $href => $object) {
1331+
$rel_urls[$href]['rels'] = array_unique($rel_urls[$href]['rels']);
1332+
sort($rel_urls[$href]['rels']);
13161333
}
13171334

13181335
if (empty($rels) and $this->jsonMode) {
@@ -1321,8 +1338,8 @@ public function parseRelsAndAlternates() {
13211338

13221339
if (empty($rel_urls) and $this->jsonMode) {
13231340
$rel_urls = new stdClass();
1324-
}
1325-
1341+
}
1342+
13261343
return array($rels, $rel_urls, $alternates);
13271344
}
13281345

tests/Mf2/ParserTest.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,5 +703,68 @@ public function testNoErrantWhitespaceOnEHtml()
703703
$output = Mf2\parse($input);
704704
$this->assertEquals('<p>1</p><p>2</p>', $output['items'][0]['properties']['content'][0]['html']);
705705
}
706+
707+
/**
708+
* @see https://github.com/indieweb/php-mf2/issues/158
709+
*/
710+
public function testPrefixWithNumbers() {
711+
$input = '<li class="h-entry">
712+
<data class="p-name" value="Coffee"></data>
713+
<div class="p-p3k-drank h-p3k-food">
714+
<span class="value">Coffee</span>
715+
</div>
716+
</li>';
717+
$output = Mf2\parse($input);
718+
719+
$this->assertArrayHasKey('p3k-drank', $output['items'][0]['properties']);
720+
$this->assertCount(1, $output['items'][0]['properties']['p3k-drank']);
721+
$this->assertEquals('h-p3k-food', $output['items'][0]['properties']['p3k-drank'][0]['type'][0]);
722+
}
723+
724+
/**
725+
* @see https://github.com/indieweb/php-mf2/issues/160
726+
*/
727+
public function testConsecutiveDashes() {
728+
$input = '<div class="h-entry h-----">
729+
<p> <a href="http://example.com/post" class="u-in-reply--to">http://example.com/post posted:</a> </p>
730+
<span class="p-name">Too many dashes</span>
731+
<span class="p--acme-leading">leading dash</span>
732+
<span class="p-acme--middle">middle dash</span>
733+
<span class="p-acme-trailing-">trailing dash</span>
734+
</div>';
735+
$output = Mf2\parse($input);
736+
737+
$this->assertCount(1, $output['items'][0]['type']);
738+
$this->assertEquals('h-entry', $output['items'][0]['type'][0]);
739+
$this->assertCount(1, $output['items'][0]['properties']);
740+
$this->assertArrayHasKey('name', $output['items'][0]['properties']);
741+
}
742+
743+
/**
744+
* Additional test from mf2py. Covers consecutive dashes, numbers in vendor prefix, and capital letters.
745+
* Added markup for numbers-only prefix and capital letter in prefix
746+
* @see https://github.com/kartikprabhu/mf2py/blob/experimental/test/examples/class_names_format.html
747+
* @see https://github.com/indieweb/php-mf2/issues/160
748+
* @see https://github.com/indieweb/php-mf2/issues/158
749+
*/
750+
public function testMfClassRegex() {
751+
$input = '<article class="h-x-test h-p3k-entry h-feed h-Entry h-p3k-fEed h--d h-test-">
752+
<a class="u-url u-Url u-p3k-url u--url u-url- u-123-url u-123A-url" href="example.com" >URL </a>
753+
<span class="p-name p-nAme p-p3k-name p--name p-name-" >name</span>
754+
</article>';
755+
$output = Mf2\parse($input);
756+
757+
$this->assertCount(3, $output['items'][0]['type']);
758+
$this->assertContains('h-feed', $output['items'][0]['type']);
759+
$this->assertContains('h-p3k-entry', $output['items'][0]['type']);
760+
$this->assertContains('h-x-test', $output['items'][0]['type']);
761+
$this->assertCount(5, $output['items'][0]['properties']);
762+
$this->assertArrayHasKey('url', $output['items'][0]['properties']);
763+
$this->assertArrayHasKey('p3k-url', $output['items'][0]['properties']);
764+
$this->assertArrayHasKey('name', $output['items'][0]['properties']);
765+
$this->assertArrayHasKey('p3k-name', $output['items'][0]['properties']);
766+
$this->assertArrayHasKey('123-url', $output['items'][0]['properties']);
767+
}
768+
706769
}
707770

tests/Mf2/RelTest.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,4 +176,47 @@ public function testRelURLs() {
176176
$this->assertArrayHasKey('rels', $output['rel-urls']['http://example.com/articles.atom']);
177177
}
178178

179+
/**
180+
* @see https://github.com/microformats/microformats2-parsing/issues/29
181+
* @see https://github.com/microformats/microformats2-parsing/issues/30
182+
*/
183+
public function testRelURLsRelsUniqueAndSorted() {
184+
$input = '<a href="#" rel="me bookmark"></a>
185+
<a href="#" rel="bookmark archived"></a>';
186+
$parser = new Parser($input);
187+
$output = $parser->parse();
188+
$this->assertEquals($output['rel-urls']['#']['rels'], array('archived', 'bookmark', 'me'));
189+
}
190+
191+
public function testRelURLsInfoMergesCorrectly() {
192+
$input = '<a href="#" rel="a">This nodeValue</a>
193+
<a href="#" rel="a" hreflang="en">Not this nodeValue</a>';
194+
$parser = new Parser($input);
195+
$output = $parser->parse();
196+
$this->assertEquals($output['rel-urls']['#']['hreflang'], 'en');
197+
$this->assertArrayNotHasKey('media', $output['rel-urls']['#']);
198+
$this->assertArrayNotHasKey('title', $output['rel-urls']['#']);
199+
$this->assertArrayNotHasKey('type', $output['rel-urls']['#']);
200+
$this->assertEquals($output['rel-urls']['#']['text'], 'This nodeValue');
201+
}
202+
203+
public function testRelURLsNoDuplicates() {
204+
$input = '<a href="#a" rel="a"></a>
205+
<a href="#b" rel="a"></a>
206+
<a href="#a" rel="a"></a>';
207+
$parser = new Parser($input);
208+
$output = $parser->parse();
209+
$this->assertEquals($output['rels']['a'], array('#a', '#b'));
210+
}
211+
212+
public function testRelURLsFalsyTextVSEmpty() {
213+
$input = '<a href="#a" rel="a">0</a>
214+
<a href="#b" rel="b"></a>';
215+
$parser = new Parser($input);
216+
$output = $parser->parse();
217+
$this->assertArrayHasKey('text', $output['rel-urls']['#a']);
218+
$this->assertEquals($output['rel-urls']['#a']['text'], '0');
219+
$this->assertArrayNotHasKey('text', $output['rel-urls']['#b']);
220+
}
221+
179222
}

0 commit comments

Comments
 (0)