Compare commits

..
63 Commits
Author SHA1 Message Date
Jérémy BenoistandGitHub 7701717086 Merge pull request #148 from j0k3r/dependabot/composer/phpstan/phpstan-2.2.14 2026-09-18 09:12:38 +02:00
Jérémy BenoistandGitHub 0dab8c72c4 Merge pull request #147 from j0k3r/dependabot/composer/friendsofphp/php-cs-fixer-3.95.25 2026-09-18 09:12:29 +02:00
dependabot[bot]andGitHub 4c0b341bff build(deps-dev): update phpstan/phpstan requirement
Updates the requirements on [phpstan/phpstan](https://github.com/phpstan/phpstan-phar-composer-source) to permit the latest version.
- [Commits](https://github.com/phpstan/phpstan-phar-composer-source/commits)

---
updated-dependencies:
- dependency-name: phpstan/phpstan
  dependency-version: 2.2.14
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-18 05:33:46 +00:00
dependabot[bot]andGitHub 9736f08a12 build(deps-dev): update friendsofphp/php-cs-fixer requirement
Updates the requirements on [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) to permit the latest version.
- [Release notes](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases)
- [Changelog](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.95.24...v3.95.25)

---
updated-dependencies:
- dependency-name: friendsofphp/php-cs-fixer
  dependency-version: 3.95.25
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-18 05:33:44 +00:00
Jérémy BenoistandGitHub 3e159d4e24 Merge pull request #146 from j0k3r/dependabot/composer/phpstan/phpstan-2.2.13
build(deps-dev): update phpstan/phpstan requirement from 2.2.12 to 2.2.13
2026-09-11 09:47:10 +02:00
Jérémy BenoistandGitHub 3677c91b29 Merge pull request #145 from j0k3r/dependabot/composer/rector/rector-2.6.6
build(deps-dev): update rector/rector requirement from 2.6.3 to 2.6.6
2026-09-11 09:46:59 +02:00
dependabot[bot]andGitHub c88b196ee6 build(deps-dev): update phpstan/phpstan requirement
Updates the requirements on [phpstan/phpstan](https://github.com/phpstan/phpstan-phar-composer-source) to permit the latest version.
- [Commits](https://github.com/phpstan/phpstan-phar-composer-source/commits)

---
updated-dependencies:
- dependency-name: phpstan/phpstan
  dependency-version: 2.2.13
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-11 05:36:40 +00:00
dependabot[bot]andGitHub ad05b00797 build(deps-dev): update rector/rector requirement from 2.6.3 to 2.6.6
Updates the requirements on [rector/rector](https://github.com/rectorphp/rector) to permit the latest version.
- [Release notes](https://github.com/rectorphp/rector/releases)
- [Commits](https://github.com/rectorphp/rector/compare/2.6.3...2.6.6)

---
updated-dependencies:
- dependency-name: rector/rector
  dependency-version: 2.6.6
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-11 05:36:38 +00:00
Jérémy BenoistandGitHub cbad259ba2 Merge pull request #143 from j0k3r/dependabot/composer/friendsofphp/php-cs-fixer-3.95.24 2026-09-04 08:06:22 +02:00
Jérémy BenoistandGitHub a3cc317102 Merge pull request #144 from j0k3r/dependabot/composer/phpstan/phpstan-2.2.12 2026-09-04 08:06:08 +02:00
dependabot[bot]andGitHub 425a42f239 build(deps-dev): update phpstan/phpstan requirement from 2.2.9 to 2.2.12
Updates the requirements on [phpstan/phpstan](https://github.com/phpstan/phpstan-phar-composer-source) to permit the latest version.
- [Commits](https://github.com/phpstan/phpstan-phar-composer-source/commits)

---
updated-dependencies:
- dependency-name: phpstan/phpstan
  dependency-version: 2.2.12
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-04 05:34:09 +00:00
dependabot[bot]andGitHub 9a8d33c6ba build(deps-dev): update friendsofphp/php-cs-fixer requirement
Updates the requirements on [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) to permit the latest version.
- [Release notes](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases)
- [Changelog](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.95.22...v3.95.24)

---
updated-dependencies:
- dependency-name: friendsofphp/php-cs-fixer
  dependency-version: 3.95.24
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-04 05:33:58 +00:00
Jérémy BenoistandGitHub ced50c9c10 Merge pull request #141 from j0k3r/dependabot/composer/phpstan/phpstan-2.2.9 2026-08-28 08:12:47 +02:00
Jérémy BenoistandGitHub f991d80b5a Merge pull request #142 from j0k3r/dependabot/composer/rector/rector-2.6.3 2026-08-28 08:12:32 +02:00
dependabot[bot]andGitHub 1697cdbeee build(deps-dev): update phpstan/phpstan requirement from 2.2.8 to 2.2.9
Updates the requirements on [phpstan/phpstan](https://github.com/phpstan/phpstan-phar-composer-source) to permit the latest version.
- [Commits](https://github.com/phpstan/phpstan-phar-composer-source/commits)

---
updated-dependencies:
- dependency-name: phpstan/phpstan
  dependency-version: 2.2.9
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-28 05:42:17 +00:00
Jérémy BenoistandGitHub eb9d8d067c Merge pull request #140 from j0k3r/dependabot/composer/friendsofphp/php-cs-fixer-3.95.22 2026-08-28 07:40:21 +02:00
dependabot[bot]andGitHub 9052618a31 build(deps-dev): update rector/rector requirement from 2.6.2 to 2.6.3
Updates the requirements on [rector/rector](https://github.com/rectorphp/rector) to permit the latest version.
- [Release notes](https://github.com/rectorphp/rector/releases)
- [Commits](https://github.com/rectorphp/rector/compare/2.6.2...2.6.3)

---
updated-dependencies:
- dependency-name: rector/rector
  dependency-version: 2.6.3
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-28 05:34:19 +00:00
dependabot[bot]andGitHub 3d332b4056 build(deps-dev): update friendsofphp/php-cs-fixer requirement
Updates the requirements on [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) to permit the latest version.
- [Release notes](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases)
- [Changelog](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.95.19...v3.95.22)

---
updated-dependencies:
- dependency-name: friendsofphp/php-cs-fixer
  dependency-version: 3.95.22
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-28 05:34:10 +00:00
Jérémy BenoistandGitHub 6abe0c4054 Merge pull request #139 from j0k3r/dependabot/composer/rector/rector-2.6.2 2026-08-21 07:56:31 +02:00
Jérémy BenoistandGitHub 00a4d5f34d Merge pull request #138 from j0k3r/dependabot/composer/friendsofphp/php-cs-fixer-3.95.19 2026-08-21 07:56:21 +02:00
dependabot[bot]andGitHub 959c0680a8 Update rector/rector requirement from 2.5.7 to 2.6.2
Updates the requirements on [rector/rector](https://github.com/rectorphp/rector) to permit the latest version.
- [Release notes](https://github.com/rectorphp/rector/releases)
- [Commits](https://github.com/rectorphp/rector/compare/2.5.7...2.6.2)

---
updated-dependencies:
- dependency-name: rector/rector
  dependency-version: 2.6.2
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-21 05:35:43 +00:00
dependabot[bot]andGitHub 74c7b80b32 Update friendsofphp/php-cs-fixer requirement from 3.95.18 to 3.95.19
Updates the requirements on [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) to permit the latest version.
- [Release notes](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases)
- [Changelog](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.95.18...v3.95.19)

---
updated-dependencies:
- dependency-name: friendsofphp/php-cs-fixer
  dependency-version: 3.95.19
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-21 05:35:39 +00:00
Jérémy BenoistandGitHub 33b69bdb6b Merge pull request #135 from j0k3r/dependabot/composer/friendsofphp/php-cs-fixer-3.95.18
Update friendsofphp/php-cs-fixer requirement from 3.95.15 to 3.95.18
2026-08-18 09:45:17 +02:00
Jérémy BenoistandGitHub f8aabce4e0 Merge pull request #137 from j0k3r/dependabot/composer/phpstan/phpstan-2.2.8
Update phpstan/phpstan requirement from 2.2.5 to 2.2.8
2026-08-18 09:45:05 +02:00
dependabot[bot]andGitHub 2e9d05c239 Update phpstan/phpstan requirement from 2.2.5 to 2.2.8
Updates the requirements on [phpstan/phpstan](https://github.com/phpstan/phpstan-phar-composer-source) to permit the latest version.
- [Commits](https://github.com/phpstan/phpstan-phar-composer-source/commits)

---
updated-dependencies:
- dependency-name: phpstan/phpstan
  dependency-version: 2.2.8
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-14 05:34:13 +00:00
dependabot[bot]andGitHub 85fbb6cbf3 Update friendsofphp/php-cs-fixer requirement from 3.95.15 to 3.95.18
Updates the requirements on [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) to permit the latest version.
- [Release notes](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases)
- [Changelog](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.95.15...v3.95.18)

---
updated-dependencies:
- dependency-name: friendsofphp/php-cs-fixer
  dependency-version: 3.95.18
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-07 05:34:21 +00:00
Jérémy BenoistandGitHub 67a2b07505 Merge pull request #131 from j0k3r/dependabot/composer/rector/rector-2.5.7 2026-07-20 07:20:12 +02:00
Jérémy BenoistandGitHub b71d73f0e0 Merge pull request #132 from j0k3r/dependabot/composer/friendsofphp/php-cs-fixer-3.95.15 2026-07-20 07:20:01 +02:00
dependabot[bot]andGitHub 1dc5f6bc78 Update friendsofphp/php-cs-fixer requirement from 3.95.12 to 3.95.15
Updates the requirements on [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) to permit the latest version.
- [Release notes](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases)
- [Changelog](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.95.12...v3.95.15)

---
updated-dependencies:
- dependency-name: friendsofphp/php-cs-fixer
  dependency-version: 3.95.15
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-17 05:34:54 +00:00
dependabot[bot]andGitHub f19d7ba19e Update rector/rector requirement from 2.5.5 to 2.5.7
Updates the requirements on [rector/rector](https://github.com/rectorphp/rector) to permit the latest version.
- [Release notes](https://github.com/rectorphp/rector/releases)
- [Commits](https://github.com/rectorphp/rector/compare/2.5.5...2.5.7)

---
updated-dependencies:
- dependency-name: rector/rector
  dependency-version: 2.5.7
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-17 05:34:36 +00:00
Kevin DecherfandGitHub a93488d727 Merge pull request #113 from Kdecherf/fix/loadHtml
Change visibility of Readability::loadHtml() and prevent DOM reset in init()
2026-07-11 21:40:14 +02:00
Kevin Decherf ac24ef54a4 Fix php-cs-fixer
Signed-off-by: Kevin Decherf <kevin@kdecherf.com>
2026-07-11 21:37:25 +02:00
Kevin Decherf 76547fef78 Prevent Readability::init() from resetting DOM if already set
Letting init() resetting the DOM may lead to unexpected behaviors in
libraries like Graby.

Related to https://github.com/j0k3r/graby/pull/392

Signed-off-by: Kevin Decherf <kevin@kdecherf.com>
2026-07-11 21:37:25 +02:00
Kevin Decherf 228bc7ee1d Change visibility of Readability::loadHtml() to public
This change is required for usecases where we want to load the DOM
without going through the whole init() process

Related to https://github.com/j0k3r/graby/pull/392

Signed-off-by: Kevin Decherf <kevin@kdecherf.com>
2026-07-11 21:37:25 +02:00
Jérémy BenoistandGitHub 35b87585e7 Merge pull request #128 from j0k3r/dependabot/composer/phpstan/phpstan-phpunit-2.0.18
Update phpstan/phpstan-phpunit requirement from 2.0.16 to 2.0.18
2026-07-10 09:45:01 +02:00
dependabot[bot]andGitHub 4230b2d7ca Update phpstan/phpstan-phpunit requirement from 2.0.16 to 2.0.18
Updates the requirements on [phpstan/phpstan-phpunit](https://github.com/phpstan/phpstan-phpunit) to permit the latest version.
- [Release notes](https://github.com/phpstan/phpstan-phpunit/releases)
- [Commits](https://github.com/phpstan/phpstan-phpunit/compare/2.0.16...2.0.18)

---
updated-dependencies:
- dependency-name: phpstan/phpstan-phpunit
  dependency-version: 2.0.18
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-10 07:26:54 +00:00
Jérémy BenoistandGitHub 85be584f94 Merge pull request #130 from j0k3r/dependabot/composer/friendsofphp/php-cs-fixer-3.95.12
Update friendsofphp/php-cs-fixer requirement from 3.95.11 to 3.95.12
2026-07-10 09:25:25 +02:00
Jérémy BenoistandGitHub 03a960daf0 Merge pull request #129 from j0k3r/dependabot/composer/rector/rector-2.5.5
Update rector/rector requirement from 2.5.2 to 2.5.5
2026-07-10 09:25:14 +02:00
Jérémy BenoistandGitHub 6f62bcf662 Merge pull request #127 from j0k3r/dependabot/composer/phpstan/phpstan-2.2.5
Update phpstan/phpstan requirement from 2.2.3 to 2.2.5
2026-07-10 09:24:55 +02:00
dependabot[bot]andGitHub 3e3114a492 Update friendsofphp/php-cs-fixer requirement from 3.95.11 to 3.95.12
Updates the requirements on [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) to permit the latest version.
- [Release notes](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases)
- [Changelog](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.95.11...v3.95.12)

---
updated-dependencies:
- dependency-name: friendsofphp/php-cs-fixer
  dependency-version: 3.95.12
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-10 05:35:20 +00:00
dependabot[bot]andGitHub f98247ed14 Update rector/rector requirement from 2.5.2 to 2.5.5
Updates the requirements on [rector/rector](https://github.com/rectorphp/rector) to permit the latest version.
- [Release notes](https://github.com/rectorphp/rector/releases)
- [Commits](https://github.com/rectorphp/rector/compare/2.5.2...2.5.5)

---
updated-dependencies:
- dependency-name: rector/rector
  dependency-version: 2.5.5
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-10 05:34:54 +00:00
dependabot[bot]andGitHub 5a6e525ff5 Update phpstan/phpstan requirement from 2.2.3 to 2.2.5
Updates the requirements on [phpstan/phpstan](https://github.com/phpstan/phpstan-phar-composer-source) to permit the latest version.
- [Commits](https://github.com/phpstan/phpstan-phar-composer-source/commits)

---
updated-dependencies:
- dependency-name: phpstan/phpstan
  dependency-version: 2.2.5
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-10 05:34:41 +00:00
Jérémy BenoistandGitHub 0de328760a Merge pull request #126 from j0k3r/dependabot/composer/phpstan/phpstan-2.2.3 2026-07-03 07:56:04 +02:00
dependabot[bot]andGitHub 5aa9da6843 Update phpstan/phpstan requirement from 2.2.2 to 2.2.3
Updates the requirements on [phpstan/phpstan](https://github.com/phpstan/phpstan-phar-composer-source) to permit the latest version.
- [Commits](https://github.com/phpstan/phpstan-phar-composer-source/commits)

---
updated-dependencies:
- dependency-name: phpstan/phpstan
  dependency-version: 2.2.3
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-03 05:34:19 +00:00
Jérémy BenoistandGitHub 1bb7eec83c Merge pull request #125 from j0k3r/dependabot/composer/rector/rector-2.5.2
Update rector/rector requirement from 2.4.6 to 2.5.2
2026-06-26 08:58:17 +02:00
Jérémy BenoistandGitHub 049bd07074 Merge pull request #124 from j0k3r/dependabot/composer/friendsofphp/php-cs-fixer-3.95.11
Update friendsofphp/php-cs-fixer requirement from 3.95.8 to 3.95.11
2026-06-26 08:58:05 +02:00
dependabot[bot]andGitHub ca1b105f40 Update rector/rector requirement from 2.4.6 to 2.5.2
Updates the requirements on [rector/rector](https://github.com/rectorphp/rector) to permit the latest version.
- [Release notes](https://github.com/rectorphp/rector/releases)
- [Commits](https://github.com/rectorphp/rector/compare/2.4.6...2.5.2)

---
updated-dependencies:
- dependency-name: rector/rector
  dependency-version: 2.5.2
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-26 05:34:17 +00:00
dependabot[bot]andGitHub 5ad159ebb1 Update friendsofphp/php-cs-fixer requirement from 3.95.8 to 3.95.11
Updates the requirements on [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) to permit the latest version.
- [Release notes](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases)
- [Changelog](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.95.8...v3.95.11)

---
updated-dependencies:
- dependency-name: friendsofphp/php-cs-fixer
  dependency-version: 3.95.11
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-26 05:34:09 +00:00
Kevin DecherfandGitHub 1312ffbced Merge pull request #123 from Kdecherf/fix/singletag-type-error
Fix a TypeError when tidy is disabled
2026-06-23 14:12:03 +02:00
Kevin Decherf 266e36c187 Fix a TypeError when tidy is disabled
A logic tries to replace a node with its child node if it is the only
element of the node. However in some cases, especially when tidy is
disabled, children items other than DOMElement may survive (e.g.
DOMComment), leading to a TypeError.

Fixes #122

Signed-off-by: Kevin Decherf <kevin@kdecherf.com>
2026-06-22 15:51:06 +02:00
Kevin DecherfandGitHub a8b08d8cb2 Merge pull request #114 from Kdecherf/fix/array-filter
Fix "Undefined array key 0" error
2026-06-21 22:46:10 +02:00
Kevin Decherf 7db754debe Fix "Undefined array key 0" error
If a matching element isn't the first child (e.g. preceded by a whitespace
text node), it may sit at a key other than 0 after some cleanup, leading to
a "Undefined array key 0" error.

This fix is now covered by 6 tests.

Fixes #96

Signed-off-by: Kevin Decherf <kevin@kdecherf.com>
2026-06-21 17:06:38 +02:00
Jérémy BenoistandGitHub 18bfe842f8 Merge pull request #121 from j0k3r/dependabot/composer/friendsofphp/php-cs-fixer-3.95.8
Update friendsofphp/php-cs-fixer requirement from 3.94.2 to 3.95.8
2026-06-19 10:18:22 +02:00
dependabot[bot]andGitHub 63a0db9109 Update friendsofphp/php-cs-fixer requirement from 3.94.2 to 3.95.8
Updates the requirements on [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) to permit the latest version.
- [Release notes](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases)
- [Changelog](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.94.2...v3.95.8)

---
updated-dependencies:
- dependency-name: friendsofphp/php-cs-fixer
  dependency-version: 3.95.8
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-19 08:08:54 +00:00
Jan Tojnar 63d6ef1a47 .github: Set up Dependabot
This will make GitHub check dependencies in `composer.json` once a week
and open PRs trying to bump each of them whenever a new version is released.
If the CI fails, as is likely the case with PHP-CS-Fixer, we will need
to fix is manually before the PR can be merged.

https://docs.github.com/en/code-security/tutorials/secure-your-dependencies/dependabot-quickstart
2026-06-19 10:05:13 +02:00
Jan Tojnar 116b6c839a JSLikeHTMLElement: Add types to methods
PHP-CS-Fixer 3.95.0 added `void_return` rule to `@Symfony:risky` ruleset.

https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases/tag/v3.95.0
https://cs.symfony.com/doc/rules/function_notation/void_return.html

`void` type declaration is available since PHP 7.1:
https://www.php.net/manual/en/language.types.void.php

Magic methods can have type annotations but they must be compatible with the default ones
(not enforced prior to PHP 8.0):
https://php.watch/versions/8.0/magic-method-signatures

Let’s just type all the methods.

This could technically be a BC break if someone is extending
the `JSLikeHTMLElement` class, overriding the methods that previously
did not have return type hint without adding it, and calling
`registerNodeClass` on the public `dom` property but I think it is
pretty unlikely – at least there seem to be no public instances on GitHub.
2026-06-19 10:00:39 +02:00
Jan Tojnar a35f00ebb3 php-cs-fixer: Prevent removing strict_types declaration
PHP-CS-Fixer 3.95.0 started removing the declarations as a part of
`@Symfony:risky` ruleset.

We currently only use it in `rector.php` but it works there so no point
in following Symfony code style on that.

We will probably want to enable `strict_types` globally eventually,
but let’s at least stop removing them for now so that we can bump
PHP-CS-Fixer.

https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases/tag/v3.95.0
https://cs.symfony.com/doc/rules/strict/declare_strict_types.html
2026-06-19 09:51:35 +02:00
Jan Tojnar 0f9f971556 tests: Use class constants instead of strings
Fixed using `composer rector` and then `composer fix`:

https://getrector.com/rule-detail/string-class-name-to-class-constant-rector
2026-06-19 09:50:01 +02:00
Jan Tojnar fd1eaf61a7 composer: Stop using lock file
Since we are a library that supports wide range of PHP versions,
we cannot lock into a single set of versions of run-time dependencies.

https://getcomposer.org/doc/02-libraries.md#lock-file

Composer 1.10.0 introduced `lock` option to prevent generation of `composer.lock` file:

https://github.com/composer/composer/releases/tag/1.10.0
https://getcomposer.org/doc/06-config.md#lock

This will basically make `composer install` work the same way as `composer update`.
2026-06-19 05:36:17 +02:00
Jan Tojnar 3e40d78a67 Pin development dependencies
PHP-CS-Fixer, PHPStan and Rector regularly introduce changes which break CI
in minor versions, forcing us to mix unrelated changes with CI fixes.

Let’s pin the minor version and update it on our own time e.g. with Dependabot.

This is also what PHPStan suggests for projects not using `composer.lock`:
https://phpstan.org/user-guide/backward-compatibility-promise#minimizing-impact-of-type-inference-changes
2026-06-19 05:17:48 +02:00
Jérémy BenoistandGitHub 03533f5e4f Merge pull request #111 from j0k3r/fix/tidy-php85
Fix bad encoding for `tidy_repair_string`
2026-03-27 20:34:19 +01:00
Jeremy Benoist 009b4ab9b8 Add PHP 8.5 on CI 2026-03-27 20:31:52 +01:00
Jeremy Benoist f9e73fb49a Fix bad encoding for tidy_repair_string
Tidy on PHP 8.5 is more restrictive on what can be given as input encoding. Before, it worked as an unknown value was converted to `utf8`.
2026-03-27 20:29:09 +01:00
7 changed files with 174 additions and 90 deletions
+6
View File
@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "composer"
directory: "/"
schedule:
interval: "weekly"
@@ -25,6 +25,7 @@ jobs:
- "8.2"
- "8.3"
- "8.4"
- "8.5"
steps:
- name: "Checkout"
+2
View File
@@ -30,6 +30,8 @@ return (new PhpCsFixer\Config())
'modernize_strpos' => false,
// Pulled in by @Symfony, we cannot add property types until we bump PHP to ≥ 7.4
'no_null_property_initialization' => false,
// @Symfony:risky started removing them but we will probably want to go the opposite direction.
'declare_strict_types' => false,
])
->setFinder($finder)
;
+7 -4
View File
@@ -30,12 +30,12 @@
"masterminds/html5": "^2.7"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.0",
"friendsofphp/php-cs-fixer": "3.95.25",
"monolog/monolog": "^1.24|^2.1",
"symfony/phpunit-bridge": "^4.4|^5.3|^6.0|^7.0",
"phpstan/phpstan": "^2.0",
"phpstan/phpstan-phpunit": "^2.0",
"rector/rector": "^2.0.0"
"phpstan/phpstan": "2.2.14",
"phpstan/phpstan-phpunit": "2.0.18",
"rector/rector": "2.6.6"
},
"suggest": {
"ext-tidy": "Used to clean up given HTML and to avoid problems with bad HTML structure."
@@ -46,6 +46,9 @@
"autoload-dev": {
"psr-4": { "Tests\\Readability\\": "tests/" }
},
"config": {
"lock": false
},
"scripts": {
"fix": "php-cs-fixer fix --verbose --diff",
"phpstan": "phpstan analyze --memory-limit 512M",
+8 -6
View File
@@ -43,7 +43,7 @@ class JSLikeHTMLElement extends \DOMElement
* $div->innerHTML = '<h2>Chapter 2</h2><p>The story begins...</p>';
* ```
*/
public function __set($name, $value)
public function __set(string $name, string $value): void
{
if ('innerHTML' !== $name) {
$trace = debug_backtrace();
@@ -108,7 +108,7 @@ class JSLikeHTMLElement extends \DOMElement
* $string = $div->innerHTML;
* ```
*/
public function __get($name)
public function __get(string $name): string
{
if ('innerHTML' === $name) {
$inner = '';
@@ -124,20 +124,22 @@ class JSLikeHTMLElement extends \DOMElement
$trace = debug_backtrace();
trigger_error('Undefined property via __get(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], \E_USER_NOTICE);
return '';
}
public function __toString()
public function __toString(): string
{
return '[' . $this->tagName . ']';
}
public function getInnerHtml()
public function getInnerHtml(): string
{
return $this->__get('innerHTML');
}
public function setInnerHtml($value)
public function setInnerHtml(string $value): void
{
return $this->__set('innerHTML', $value);
$this->__set('innerHTML', $value);
}
}
+88 -75
View File
@@ -88,7 +88,7 @@ class Readability implements LoggerAwareInterface
'enclose-text' => true,
'merge-divs' => true,
// 'merge-spans' => true,
'input-encoding' => '????',
'input-encoding' => 'utf8',
'output-encoding' => 'utf8',
'hide-comments' => true,
];
@@ -213,7 +213,9 @@ class Readability implements LoggerAwareInterface
*/
public function init(): bool
{
if (!isset($this->dom)) {
$this->loadHtml();
}
if (!isset($this->dom->documentElement)) {
return false;
@@ -751,6 +753,76 @@ class Readability implements LoggerAwareInterface
$this->flags &= ~$flag;
}
/**
* Load HTML in a DOMDocument.
* Apply Pre filters
* Cleanup HTML using Tidy (or not).
*/
public function loadHtml(): void
{
$this->original_html = $this->html;
$this->logger->debug('Parsing URL: ' . $this->url);
if ($this->url) {
$host = parse_url($this->url, \PHP_URL_HOST);
if (null !== $host) {
$this->domainRegExp = '/' . strtr((string) preg_replace('/www\d*\./', '', $host), ['.' => '\.']) . '/';
}
}
mb_internal_encoding('UTF-8');
mb_http_output('UTF-8');
mb_regex_encoding('UTF-8');
// HACK: dirty cleanup to replace some stuff; shouldn't use regexps with HTML but well...
if (!$this->flagIsActive(self::FLAG_DISABLE_PREFILTER)) {
foreach ($this->pre_filters as $search => $replace) {
$this->html = preg_replace($search, $replace, $this->html);
}
unset($search, $replace);
}
if ('' === trim($this->html)) {
$this->html = '<html></html>';
}
/*
* Use tidy (if it exists).
* This fixes problems with some sites which would otherwise trouble DOMDocument's HTML parsing.
* Although sometimes it makes matters worse, which is why there is an option to disable it.
*/
if ($this->useTidy) {
$this->logger->debug('Tidying document');
$tidy = tidy_repair_string($this->html, $this->tidy_config, 'UTF8');
if (false !== $tidy && $this->html !== $tidy) {
$this->tidied = true;
$this->html = $tidy;
$this->html = preg_replace('/[\r\n]+/is', "\n", $this->html);
}
unset($tidy);
}
$this->html = self::entitizeNonAscii((string) $this->html);
if ('html5lib' === $this->parser || 'html5' === $this->parser) {
$this->dom = (new HTML5())->loadHTML($this->html);
}
if ('libxml' === $this->parser) {
libxml_use_internal_errors(true);
$this->dom = new \DOMDocument();
$this->dom->preserveWhiteSpace = false;
$this->dom->loadHTML($this->html, \LIBXML_NOBLANKS | \LIBXML_COMPACT | \LIBXML_NOERROR);
libxml_use_internal_errors(false);
}
$this->dom->registerNodeClass(\DOMElement::class, JSLikeHTMLElement::class);
}
/**
* Get the article title as an H1.
*
@@ -1003,7 +1075,11 @@ class Readability implements LoggerAwareInterface
}
if ($this->hasSingleTagInsideElement($node, 'p') && $this->getLinkDensity($node) < 0.25) {
$newNode = $node->childNodes->item(0);
// In some cases when tidy is disabled the first item may not be a DOMElement so we apply a filter
$newNode = array_values(array_filter(
iterator_to_array($node->childNodes),
static fn ($childNode) => $childNode instanceof \DOMElement
))[0];
$node->parentNode->replaceChild($newNode, $node);
$nodesToScore[] = $newNode;
}
@@ -1118,7 +1194,7 @@ class Readability implements LoggerAwareInterface
$topCandidates = array_filter(
$topCandidates,
fn ($v, $idx) => 0 === $idx || null !== $v,
static fn ($v, $idx) => 0 === $idx || null !== $v,
\ARRAY_FILTER_USE_BOTH
);
$topCandidate = $topCandidates[0];
@@ -1371,76 +1447,6 @@ class Readability implements LoggerAwareInterface
}
}
/**
* Load HTML in a DOMDocument.
* Apply Pre filters
* Cleanup HTML using Tidy (or not).
*/
private function loadHtml(): void
{
$this->original_html = $this->html;
$this->logger->debug('Parsing URL: ' . $this->url);
if ($this->url) {
$host = parse_url($this->url, \PHP_URL_HOST);
if (null !== $host) {
$this->domainRegExp = '/' . strtr((string) preg_replace('/www\d*\./', '', $host), ['.' => '\.']) . '/';
}
}
mb_internal_encoding('UTF-8');
mb_http_output('UTF-8');
mb_regex_encoding('UTF-8');
// HACK: dirty cleanup to replace some stuff; shouldn't use regexps with HTML but well...
if (!$this->flagIsActive(self::FLAG_DISABLE_PREFILTER)) {
foreach ($this->pre_filters as $search => $replace) {
$this->html = preg_replace($search, $replace, $this->html);
}
unset($search, $replace);
}
if ('' === trim($this->html)) {
$this->html = '<html></html>';
}
/*
* Use tidy (if it exists).
* This fixes problems with some sites which would otherwise trouble DOMDocument's HTML parsing.
* Although sometimes it makes matters worse, which is why there is an option to disable it.
*/
if ($this->useTidy) {
$this->logger->debug('Tidying document');
$tidy = tidy_repair_string($this->html, $this->tidy_config, 'UTF8');
if (false !== $tidy && $this->html !== $tidy) {
$this->tidied = true;
$this->html = $tidy;
$this->html = preg_replace('/[\r\n]+/is', "\n", $this->html);
}
unset($tidy);
}
$this->html = self::entitizeNonAscii((string) $this->html);
if ('html5lib' === $this->parser || 'html5' === $this->parser) {
$this->dom = (new HTML5())->loadHTML($this->html);
}
if ('libxml' === $this->parser) {
libxml_use_internal_errors(true);
$this->dom = new \DOMDocument();
$this->dom->preserveWhiteSpace = false;
$this->dom->loadHTML($this->html, \LIBXML_NOBLANKS | \LIBXML_COMPACT | \LIBXML_NOERROR);
libxml_use_internal_errors(false);
}
$this->dom->registerNodeClass(\DOMElement::class, JSLikeHTMLElement::class);
}
private function getAncestors(\DOMElement $node, int $maxDepth = 0): array
{
$ancestors = [];
@@ -1481,10 +1487,17 @@ class Readability implements LoggerAwareInterface
private function hasSingleTagInsideElement(\DOMElement $node, string $tag): bool
{
$childNodes = iterator_to_array($node->childNodes);
$children = array_filter($childNodes, fn ($childNode) => $childNode instanceof \DOMElement);
$children = array_filter($childNodes, static fn ($childNode) => $childNode instanceof \DOMElement);
// array_first() has been added in PHP 8.5, failing back for older versions
if (!\function_exists('array_first')) {
$firstChild = $children ? $children[array_key_first($children)] : null;
} else {
$firstChild = array_first($children);
}
// There should be exactly 1 element child with given tag
if (1 !== \count($children) || $children[0]->nodeName !== $tag) {
if (1 !== \count($children) || $firstChild->nodeName !== $tag) {
return false;
}
+61 -4
View File
@@ -21,6 +21,7 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
public function testConstructDefault(): void
{
$readability = $this->getReadability('');
$this->assertSame('utf8', $readability->tidy_config['input-encoding']);
$readability->init();
$this->assertNull($readability->url);
@@ -323,7 +324,7 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$oldErrorReporting = error_reporting(\E_ALL);
$oldDisplayErrors = ini_set('display_errors', '1');
// dummy function to be used to the next test
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline) {
set_error_handler(static function (int $errno, string $errstr, string $errfile, int $errline) {
throw new \Exception($errstr, $errno);
});
@@ -463,6 +464,62 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($res);
}
public function dataForHasSingleTagInsideElement(): array
{
return [
'single matching tag, no other content' => [
'<div><p>Some text</p></div>', 'p', true,
],
'single matching tag with comment' => [
'<div><!-- comment --><p>Some text</p></div>', 'p', true,
],
'whitespace-only text around single matching tag' => [
'<div> <p>Some text</p> </div>', 'p', true,
],
'two matching tags' => [
'<div><p>One</p><p>Two</p></div>', 'p', false,
],
'non-whitespace text alongside the single tag' => [
'<div>Some text<p>One</p></div>', 'p', false,
],
'single tag with a different name' => [
'<div><span>One</span></div>', 'p', false,
],
];
}
/**
* @dataProvider dataForHasSingleTagInsideElement
*/
public function testHasSingleTagInsideElement(string $html, string $tag, bool $expected): void
{
$dom = new \DOMDocument();
$dom->loadHTML('<html><body>' . $html . '</body></html>');
$node = $dom->getElementsByTagName('div')->item(0);
$readability = $this->getReadability('', '', 'libxml', false);
$method = new \ReflectionMethod($readability, 'hasSingleTagInsideElement');
if (\PHP_VERSION_ID < 80100) {
$method->setAccessible(true);
}
$this->assertSame($expected, $method->invoke($readability, $node, $tag));
}
public function testDivToPElementWithComment(): void
{
$text = str_repeat('Padded real article text to reach decent length for content scoring threshold here. ', 8);
$html = '<div><!-- comment --><code>some code snippet</code> ' . $text . '</div>';
$readability = $this->getReadability($html, 'http://0.0.0.0', 'libxml', false);
$res = $readability->init();
$this->assertTrue($res);
$this->assertStringContainsString('some code snippet', $readability->getContent()->getInnerHtml());
$this->assertStringContainsString('Padded real article text', $readability->getContent()->getInnerHtml());
}
public function testKeepFootnotes(): void
{
// from https://www.schreibdichte.de/blog/feed-aggregator-und-spaeter-lesen-dienst-im-team
@@ -537,8 +594,8 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$res = $readability->init();
$this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
$this->assertSame('Tõde ja õigus I', $readability->getTitle()->getInnerHtml());
$this->assertStringContainsString('Päike lähenes', $readability->getContent()->getInnerHtml());
}
@@ -583,7 +640,7 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($res);
$this->assertInstanceOf(\DOMDocument::class, $readability->dom);
$this->assertSame($lang, $readability->dom->documentElement->getAttribute('lang'));
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
$this->assertStringContainsString('êtres', $readability->getContent()->getInnerHtml());
}