@@ -1207,13 +1207,13 @@ protected function grabArticle(?JSLikeHTMLElement $page = null)
1207
1207
}
1208
1208
}
1209
1209
1210
- /** @var \DOMNodeList<\DOMElement> */
1211
1210
$ topCandidates = array_filter (
1212
1211
$ topCandidates ,
1213
1212
fn ($ v , $ idx ) => 0 === $ idx || null !== $ v ,
1214
1213
\ARRAY_FILTER_USE_BOTH
1215
1214
);
1216
1215
$ topCandidate = $ topCandidates [0 ];
1216
+ \PHPStan \dumpType ($ topCandidates );
1217
1217
1218
1218
/*
1219
1219
* If we still have no top candidate, just use the body as a last resort.
@@ -1264,11 +1264,17 @@ protected function grabArticle(?JSLikeHTMLElement $page = null)
1264
1264
}
1265
1265
$ parentOfTopCandidate = $ parentOfTopCandidate ->parentNode ;
1266
1266
}
1267
+ // For PHPStan: the loop terminates either when the parent node is body (a HTML element),
1268
+ // or when $parentOfTopCandidate is in at least three candidate ancestor lists.
1269
+ // TODO: Fuzz this.
1270
+ \assert ($ parentOfTopCandidate instanceof JSLikeHTMLElement);
1271
+ \assert ($ topCandidate instanceof JSLikeHTMLElement);
1267
1272
}
1268
1273
if (!$ topCandidate ->hasAttribute ('readability ' )) {
1269
1274
$ this ->initializeNode ($ topCandidate );
1270
1275
}
1271
1276
$ parentOfTopCandidate = $ topCandidate ->parentNode ;
1277
+ \assert ($ parentOfTopCandidate instanceof JSLikeHTMLElement);
1272
1278
$ lastScore = (int ) $ topCandidate ->getAttribute ('readability ' );
1273
1279
$ scoreThreshold = $ lastScore / 3 ;
1274
1280
while ('body ' !== $ parentOfTopCandidate ->nodeName ) {
@@ -1552,6 +1558,9 @@ private function loadHtml(): void
1552
1558
$ this ->dom ->registerNodeClass (\DOMElement::class, JSLikeHTMLElement::class);
1553
1559
}
1554
1560
1561
+ /**
1562
+ * @return array<JSLikeHTMLElement>
1563
+ */
1555
1564
private function getAncestors (JSLikeHTMLElement $ node , int $ maxDepth = 0 ): array
1556
1565
{
1557
1566
$ ancestors = [];
0 commit comments