mirror of
https://github.com/j0k3r/php-readability.git
synced 2026-09-27 06:26:17 +00:00
Compare commits
130
Commits
1.2.4
..
6abe0c4054
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6abe0c4054 | ||
|
|
00a4d5f34d | ||
|
|
959c0680a8 | ||
|
|
74c7b80b32 | ||
|
|
33b69bdb6b | ||
|
|
f8aabce4e0 | ||
|
|
2e9d05c239 | ||
|
|
85fbb6cbf3 | ||
|
|
67a2b07505 | ||
|
|
b71d73f0e0 | ||
|
|
1dc5f6bc78 | ||
|
|
f19d7ba19e | ||
|
|
a93488d727 | ||
|
|
ac24ef54a4 | ||
|
|
76547fef78 | ||
|
|
228bc7ee1d | ||
|
|
35b87585e7 | ||
|
|
4230b2d7ca | ||
|
|
85be584f94 | ||
|
|
03a960daf0 | ||
|
|
6f62bcf662 | ||
|
|
3e3114a492 | ||
|
|
f98247ed14 | ||
|
|
5a6e525ff5 | ||
|
|
0de328760a | ||
|
|
5aa9da6843 | ||
|
|
1bb7eec83c | ||
|
|
049bd07074 | ||
|
|
ca1b105f40 | ||
|
|
5ad159ebb1 | ||
|
|
1312ffbced | ||
|
|
266e36c187 | ||
|
|
a8b08d8cb2 | ||
|
|
7db754debe | ||
|
|
18bfe842f8 | ||
|
|
63a0db9109 | ||
|
|
63d6ef1a47 | ||
|
|
116b6c839a | ||
|
|
a35f00ebb3 | ||
|
|
0f9f971556 | ||
|
|
fd1eaf61a7 | ||
|
|
3e40d78a67 | ||
|
|
03533f5e4f | ||
|
|
009b4ab9b8 | ||
|
|
f9e73fb49a | ||
|
|
3042990efc | ||
|
|
8b89d70b1a | ||
|
|
3e9b15db46 | ||
|
|
7413a38ff0 | ||
|
|
a18cd0f2a9 | ||
|
|
efbbc86df9 | ||
|
|
541fab34a0 | ||
|
|
90869d877e | ||
|
|
c7208f6ad2 | ||
|
|
4258559b8a | ||
|
|
1ac761d708 | ||
|
|
d3053fbce4 | ||
|
|
4c929754e9 | ||
|
|
1d7cdf3a12 | ||
|
|
f825dcf55a | ||
|
|
9a9373de4b | ||
|
|
d454c3a462 | ||
|
|
8b1ef07401 | ||
|
|
5885dbbe78 | ||
|
|
6947999782 | ||
|
|
da755013aa | ||
|
|
5b9551d1e3 | ||
|
|
c7b10dcc45 | ||
|
|
80adfe870b | ||
|
|
cb6b6ac577 | ||
|
|
677f3f096e | ||
|
|
29122763db | ||
|
|
89d3b74259 | ||
|
|
e792644fe8 | ||
|
|
648d8c605b | ||
|
|
f28191a728 | ||
|
|
2103853a1b | ||
|
|
7f4c6cfcbd | ||
|
|
38870cdff1 | ||
|
|
9bdd3b6b2e | ||
|
|
f14428e4c0 | ||
|
|
23f824a1ce | ||
|
|
2a57124528 | ||
|
|
0975574bdb | ||
|
|
9ed89bde92 | ||
|
|
2c6c6d5987 | ||
|
|
c5407ec07c | ||
|
|
7cd8476d38 | ||
|
|
82083c872b | ||
|
|
6689f19956 | ||
|
|
0c0653dad6 | ||
|
|
2ab87d7445 | ||
|
|
8af69ad68c | ||
|
|
c2a1639b34 | ||
|
|
ccf1b336c5 | ||
|
|
a44c4e5482 | ||
|
|
b580cf216d | ||
|
|
2e9349f076 | ||
|
|
c4bba53dbe | ||
|
|
66215a6c80 | ||
|
|
b1a20a9575 | ||
|
|
97c02e8ad4 | ||
|
|
c506b7ebd7 | ||
|
|
d0af21814a | ||
|
|
5b1eba79bd | ||
|
|
fabf096ce6 | ||
|
|
8ce1663238 | ||
|
|
eb72a315c4 | ||
|
|
d5330a9c28 | ||
|
|
635f8963dc | ||
|
|
19b2a25d96 | ||
|
|
9a490fac07 | ||
|
|
6f6b1f9e2b | ||
|
|
ea1368fac0 | ||
|
|
be81eb2a4f | ||
|
|
9632c4df8c | ||
|
|
bd9ca1b2cd | ||
|
|
6c917794a7 | ||
|
|
7cea79c23a | ||
|
|
c6425cc28b | ||
|
|
e6ad806460 | ||
|
|
3fa88461a0 | ||
|
|
6a8ecf232f | ||
|
|
52b1ddba57 | ||
|
|
90c625bb57 | ||
|
|
4d1c3b1777 | ||
|
|
d649b59414 | ||
|
|
44bebfc3d6 | ||
|
|
b1acc9ed73 | ||
|
|
ff78c63e6d |
+3
-2
@@ -4,9 +4,10 @@ root = true
|
||||
; Unix-style newlines
|
||||
[*]
|
||||
end_of_line = LF
|
||||
|
||||
[*.php]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[.github/**.yml]
|
||||
indent_size = 2
|
||||
|
||||
+3
-2
@@ -4,7 +4,8 @@
|
||||
/.scrutinizer.yml export-ignore
|
||||
/.travis.yml export-ignore
|
||||
/.php_cs export-ignore
|
||||
/README.md export-ignore
|
||||
/phpunit.xml.dist export-ignore
|
||||
/tests export-ignore
|
||||
/phpstan.neon export-ignore
|
||||
/rector.php export-ignore
|
||||
/.github export-ignore
|
||||
/tests export-ignore
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
github: j0k3r
|
||||
@@ -0,0 +1,6 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "composer"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
@@ -0,0 +1,47 @@
|
||||
name: "CS"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
coding-standards:
|
||||
name: "CS Fixer & PHPStan"
|
||||
runs-on: "ubuntu-22.04"
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php:
|
||||
- "7.4"
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v4"
|
||||
|
||||
- name: "Install PHP"
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
with:
|
||||
coverage: "none"
|
||||
php-version: "${{ matrix.php }}"
|
||||
tools: cs2pr, composer:v2
|
||||
ini-values: "date.timezone=Europe/Paris"
|
||||
env:
|
||||
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: "Install dependencies with Composer"
|
||||
uses: "ramsey/composer-install@v3"
|
||||
with:
|
||||
composer-options: "--optimize-autoloader --prefer-dist"
|
||||
|
||||
- name: "Run PHP CS Fixer"
|
||||
run: "php vendor/bin/php-cs-fixer fix --verbose --dry-run --format=checkstyle | cs2pr"
|
||||
|
||||
- name: "Install PHPUnit for PHPStan"
|
||||
run: "php vendor/bin/simple-phpunit install"
|
||||
|
||||
- name: "Run PHPStan"
|
||||
run: "php vendor/bin/phpstan analyse --error-format=checkstyle | cs2pr"
|
||||
@@ -0,0 +1,151 @@
|
||||
name: "CI"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- "master"
|
||||
push:
|
||||
branches:
|
||||
- "master"
|
||||
|
||||
env:
|
||||
fail-fast: true
|
||||
|
||||
jobs:
|
||||
phpunit:
|
||||
name: "PHPUnit (PHP ${{ matrix.php }})"
|
||||
runs-on: "ubuntu-22.04"
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php:
|
||||
- "7.4"
|
||||
- "8.0"
|
||||
- "8.1"
|
||||
- "8.2"
|
||||
- "8.3"
|
||||
- "8.4"
|
||||
- "8.5"
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v4"
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: "Install PHP"
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
with:
|
||||
php-version: "${{ matrix.php }}"
|
||||
coverage: "none"
|
||||
tools: composer:v2
|
||||
extensions: tidy
|
||||
ini-values: "date.timezone=Europe/Paris"
|
||||
env:
|
||||
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: "Remove useless deps"
|
||||
run: "composer remove friendsofphp/php-cs-fixer --dev --no-progress --no-update"
|
||||
|
||||
- name: "Install dependencies with Composer"
|
||||
uses: "ramsey/composer-install@v3"
|
||||
with:
|
||||
composer-options: "--optimize-autoloader --prefer-dist"
|
||||
|
||||
- name: "Setup logs"
|
||||
run: "mkdir -p build/logs"
|
||||
|
||||
- name: "Run PHPUnit"
|
||||
run: "php vendor/bin/simple-phpunit -v"
|
||||
|
||||
phpunit-coverage:
|
||||
name: "PHPUnit coverage (PHP ${{ matrix.php }})"
|
||||
runs-on: "ubuntu-22.04"
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php:
|
||||
- "8.0"
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v4"
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: "Install PHP with Xdebug"
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
with:
|
||||
php-version: "${{ matrix.php }}"
|
||||
coverage: "xdebug"
|
||||
tools: composer:v2
|
||||
extensions: tidy
|
||||
ini-values: "date.timezone=Europe/Paris"
|
||||
env:
|
||||
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: "Remove useless deps"
|
||||
run: "composer remove friendsofphp/php-cs-fixer --dev --no-progress --no-update"
|
||||
|
||||
- name: "Install dependencies with Composer"
|
||||
uses: "ramsey/composer-install@v3"
|
||||
with:
|
||||
composer-options: "--optimize-autoloader --prefer-dist"
|
||||
|
||||
- name: "Setup logs"
|
||||
run: "mkdir -p build/logs"
|
||||
|
||||
- name: "Run PHPUnit (with coverage)"
|
||||
run: "php vendor/bin/simple-phpunit -v --coverage-clover build/logs/clover.xml"
|
||||
|
||||
- name: "Retrieve Coveralls phar"
|
||||
run: "wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.7.0/php-coveralls.phar"
|
||||
|
||||
- name: "Enable Coveralls phar"
|
||||
run: "chmod +x php-coveralls.phar"
|
||||
|
||||
- name: "Upload to Coveralls"
|
||||
run: "php php-coveralls.phar -v -x build/logs/clover.xml"
|
||||
env:
|
||||
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
phpunit-lowest:
|
||||
name: "PHPUnit lowest deps (PHP ${{ matrix.php }})"
|
||||
runs-on: "ubuntu-22.04"
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
php:
|
||||
- "7.4"
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v4"
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: "Install PHP"
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
with:
|
||||
php-version: "${{ matrix.php }}"
|
||||
coverage: "none"
|
||||
tools: composer:v2
|
||||
extensions: tidy
|
||||
ini-values: "date.timezone=Europe/Paris"
|
||||
env:
|
||||
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: "Remove useless deps"
|
||||
run: "composer remove friendsofphp/php-cs-fixer --dev --no-progress --no-update"
|
||||
|
||||
- name: "Install dependencies with Composer"
|
||||
uses: "ramsey/composer-install@v3"
|
||||
with:
|
||||
composer-options: "--optimize-autoloader --prefer-dist"
|
||||
dependency-versions: "lowest"
|
||||
|
||||
- name: "Setup logs"
|
||||
run: "mkdir -p build/logs"
|
||||
|
||||
- name: "Run PHPUnit"
|
||||
run: "php vendor/bin/simple-phpunit -v"
|
||||
@@ -2,3 +2,6 @@ vendor/
|
||||
coverage/
|
||||
composer.lock
|
||||
.php_cs.cache
|
||||
.php-cs-fixer.cache
|
||||
.phpunit.result.cache
|
||||
phpstan.neon
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
$finder = (new PhpCsFixer\Finder())
|
||||
->in(__DIR__)
|
||||
->exclude(['vendor', 'var', 'web'])
|
||||
;
|
||||
|
||||
return (new PhpCsFixer\Config())
|
||||
->setUsingCache(true)
|
||||
->setRiskyAllowed(true)
|
||||
->setRules([
|
||||
'@Symfony' => true,
|
||||
'@Symfony:risky' => true,
|
||||
'array_syntax' => ['syntax' => 'short'],
|
||||
'combine_consecutive_unsets' => true,
|
||||
'heredoc_to_nowdoc' => true,
|
||||
'no_extra_blank_lines' => ['tokens' => ['break', 'continue', 'extra', 'return', 'throw', 'use', 'parenthesis_brace_block', 'square_brace_block', 'curly_brace_block']],
|
||||
'no_unreachable_default_argument_value' => true,
|
||||
'no_useless_else' => true,
|
||||
'no_useless_return' => true,
|
||||
'ordered_class_elements' => true,
|
||||
'ordered_imports' => true,
|
||||
'php_unit_strict' => false,
|
||||
'phpdoc_order' => true,
|
||||
// 'psr4' => true,
|
||||
'strict_comparison' => true,
|
||||
'strict_param' => true,
|
||||
'concat_space' => ['spacing' => 'one'],
|
||||
// Pulled in by @Symfony:risky but we still support PHP 7.4
|
||||
'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)
|
||||
;
|
||||
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
return PhpCsFixer\Config::create()
|
||||
->setUsingCache(true)
|
||||
->setRiskyAllowed(true)
|
||||
->setRules([
|
||||
'@Symfony' => true,
|
||||
'@Symfony:risky' => true,
|
||||
'array_syntax' => ['syntax' => 'short'],
|
||||
'combine_consecutive_unsets' => true,
|
||||
'heredoc_to_nowdoc' => true,
|
||||
'no_extra_consecutive_blank_lines' => ['break', 'continue', 'extra', 'return', 'throw', 'use', 'parenthesis_brace_block', 'square_brace_block', 'curly_brace_block'],
|
||||
'no_unreachable_default_argument_value' => true,
|
||||
'no_useless_else' => true,
|
||||
'no_useless_return' => true,
|
||||
'ordered_class_elements' => true,
|
||||
'ordered_imports' => true,
|
||||
'php_unit_strict' => false,
|
||||
'phpdoc_order' => true,
|
||||
// 'psr4' => true,
|
||||
'strict_comparison' => true,
|
||||
'strict_param' => true,
|
||||
'concat_space' => ['spacing' => 'one'],
|
||||
])
|
||||
->setFinder(
|
||||
PhpCsFixer\Finder::create()
|
||||
->exclude(['vendor'])
|
||||
->in(__DIR__)
|
||||
)
|
||||
;
|
||||
@@ -1,2 +0,0 @@
|
||||
tools:
|
||||
external_code_coverage: false
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 5.6
|
||||
- 7.0
|
||||
- 7.1
|
||||
- 7.2
|
||||
- 7.3
|
||||
- nightly
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- php: 7.2
|
||||
env: CS_FIXER=run
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- php: nightly
|
||||
|
||||
# cache vendor dirs
|
||||
cache:
|
||||
directories:
|
||||
- vendor
|
||||
- $HOME/.composer/cache
|
||||
|
||||
before_install:
|
||||
- if [ -n "$GH_TOKEN" ]; then composer config github-oauth.github.com ${GH_TOKEN}; fi;
|
||||
|
||||
install:
|
||||
- composer self-update
|
||||
|
||||
before_script:
|
||||
- if [ "$CS_FIXER" = "run" ]; then composer require phpstan/phpstan phpstan/phpstan-phpunit --dev -n ; fi;
|
||||
- composer install -o --prefer-dist --no-interaction
|
||||
|
||||
script:
|
||||
- mkdir -p build/logs
|
||||
- php vendor/bin/simple-phpunit -v --coverage-clover build/logs/clover.xml
|
||||
- if [ "$CS_FIXER" = "run" ]; then php vendor/bin/php-cs-fixer fix --verbose --dry-run ; fi;
|
||||
- if [ "$CS_FIXER" = "run" ]; then php vendor/bin/phpstan analyse src tests --no-progress --level 1 ; fi;
|
||||
|
||||
after_script:
|
||||
- php vendor/bin/php-coveralls -v -x build/logs/clover.xml
|
||||
@@ -1,11 +1,11 @@
|
||||
# Readability
|
||||
|
||||
[](https://travis-ci.org/j0k3r/php-readability)
|
||||

|
||||
[](https://coveralls.io/github/j0k3r/php-readability/?branch=master)
|
||||
[](https://packagist.org/packages/j0k3r/php-readability)
|
||||
[](https://packagist.org/packages/j0k3r/php-readability)
|
||||
|
||||
This is an extract of the Readability class from this [full-text-rss](https://github.com/Dither/full-text-rss) fork. It can be defined as a better version of the original [php-readability](https://bitbucket.org/fivefilters/php-readability/overview).
|
||||
This is an extract of the Readability class from this [full-text-rss](https://github.com/Dither/full-text-rss) fork. It can be defined as a better version of the original [php-readability](https://bitbucket.org/fivefilters/php-readability).
|
||||
|
||||
## Differences
|
||||
|
||||
|
||||
+18
-7
@@ -24,16 +24,18 @@
|
||||
"role": "Developer (original JS version)"
|
||||
}],
|
||||
"require": {
|
||||
"php": ">=5.6.0",
|
||||
"php": ">=7.4.0",
|
||||
"ext-mbstring": "*",
|
||||
"psr/log": "^1.0",
|
||||
"electrolinux/php-html5lib": "^0.1.0"
|
||||
"psr/log": "^1.0.1 || ^2.0 || ^3.0",
|
||||
"masterminds/html5": "^2.7"
|
||||
},
|
||||
"require-dev": {
|
||||
"php-coveralls/php-coveralls": "^2.1",
|
||||
"friendsofphp/php-cs-fixer": "^2.14",
|
||||
"monolog/monolog": "^1.24",
|
||||
"symfony/phpunit-bridge": "^4.2.3"
|
||||
"friendsofphp/php-cs-fixer": "3.95.19",
|
||||
"monolog/monolog": "^1.24|^2.1",
|
||||
"symfony/phpunit-bridge": "^4.4|^5.3|^6.0|^7.0",
|
||||
"phpstan/phpstan": "2.2.8",
|
||||
"phpstan/phpstan-phpunit": "2.0.18",
|
||||
"rector/rector": "2.6.2"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-tidy": "Used to clean up given HTML and to avoid problems with bad HTML structure."
|
||||
@@ -43,5 +45,14 @@
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": { "Tests\\Readability\\": "tests/" }
|
||||
},
|
||||
"config": {
|
||||
"lock": false
|
||||
},
|
||||
"scripts": {
|
||||
"fix": "php-cs-fixer fix --verbose --diff",
|
||||
"phpstan": "phpstan analyze --memory-limit 512M",
|
||||
"rector": "rector process",
|
||||
"test": "simple-phpunit -v"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
parameters:
|
||||
level: 1
|
||||
paths:
|
||||
- src
|
||||
- tests
|
||||
|
||||
# https://github.com/phpstan/phpstan/issues/694#issuecomment-350724288
|
||||
bootstrapFiles:
|
||||
- vendor/bin/.phpunit/phpunit/vendor/autoload.php
|
||||
|
||||
includes:
|
||||
- vendor/phpstan/phpstan-phpunit/extension.neon
|
||||
- vendor/phpstan/phpstan-phpunit/rules.neon
|
||||
|
||||
parameters:
|
||||
# https://github.com/phpstan/phpstan/issues/694#issuecomment-350724288
|
||||
autoload_files:
|
||||
- vendor/bin/.phpunit/phpunit-7.4/vendor/autoload.php
|
||||
+2
-2
@@ -11,7 +11,7 @@
|
||||
>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="Readability Test Suite">
|
||||
<testsuite name="Readability">
|
||||
<directory>./tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
@@ -26,6 +26,6 @@
|
||||
</filter>
|
||||
|
||||
<!-- <logging>
|
||||
<log type="coverage-html" target="coverage" title="Readability" charset="UTF-8" yui="true" highlight="true" lowUpperBound="35" highLowerBound="70"/>
|
||||
<log type="coverage-html" target="coverage" lowUpperBound="35" highLowerBound="70"/>
|
||||
</logging> -->
|
||||
</phpunit>
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\Config\RectorConfig;
|
||||
use Rector\Set\ValueObject\LevelSetList;
|
||||
|
||||
return RectorConfig::configure()
|
||||
->withPaths([
|
||||
__DIR__ . '/src',
|
||||
__DIR__ . '/tests',
|
||||
])
|
||||
->withBootstrapFiles([
|
||||
__DIR__ . '/vendor/bin/.phpunit/phpunit/vendor/autoload.php',
|
||||
__DIR__ . '/vendor/autoload.php',
|
||||
])
|
||||
->withSets([LevelSetList::UP_TO_PHP_74])
|
||||
;
|
||||
+19
-14
@@ -39,23 +39,25 @@ class JSLikeHTMLElement extends \DOMElement
|
||||
/**
|
||||
* Used for setting innerHTML like it's done in JavaScript:.
|
||||
*
|
||||
* @code
|
||||
* ```php
|
||||
* $div->innerHTML = '<h2>Chapter 2</h2><p>The story begins...</p>';
|
||||
* @endcode
|
||||
* ```
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
public function __set(string $name, string $value): void
|
||||
{
|
||||
if ('innerHTML' !== $name) {
|
||||
$trace = debug_backtrace();
|
||||
trigger_error('Undefined property via __set(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_NOTICE);
|
||||
trigger_error('Undefined property via __set(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], \E_USER_NOTICE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// first, empty the element
|
||||
if (isset($this->childNodes)) {
|
||||
for ($x = $this->childNodes->length - 1; $x >= 0; --$x) {
|
||||
$this->removeChild($this->childNodes->item($x));
|
||||
}
|
||||
}
|
||||
|
||||
// $value holds our new inner HTML
|
||||
$value = trim($value);
|
||||
@@ -77,14 +79,13 @@ class JSLikeHTMLElement extends \DOMElement
|
||||
} else {
|
||||
// $value is probably ill-formed
|
||||
$f = new \DOMDocument();
|
||||
$value = mb_convert_encoding($value, 'HTML-ENTITIES', 'UTF-8');
|
||||
|
||||
// Using <htmlfragment> will generate a warning, but so will bad HTML
|
||||
// (and by this point, bad HTML is what we've got).
|
||||
// We use it (and suppress the warning) because an HTML fragment will
|
||||
// be wrapped around <html><body> tags which we don't really want to keep.
|
||||
// Note: despite the warning, if loadHTML succeeds it will return true.
|
||||
$result = $f->loadHTML('<htmlfragment>' . $value . '</htmlfragment>');
|
||||
$result = $f->loadHTML('<meta charset="utf-8"><htmlfragment>' . $value . '</htmlfragment>');
|
||||
|
||||
if ($result) {
|
||||
$import = $f->getElementsByTagName('htmlfragment')->item(0);
|
||||
@@ -103,38 +104,42 @@ class JSLikeHTMLElement extends \DOMElement
|
||||
/**
|
||||
* Used for getting innerHTML like it's done in JavaScript:.
|
||||
*
|
||||
* @code
|
||||
* ```php
|
||||
* $string = $div->innerHTML;
|
||||
* @endcode
|
||||
* ```
|
||||
*/
|
||||
public function __get($name)
|
||||
public function __get(string $name): string
|
||||
{
|
||||
if ('innerHTML' === $name) {
|
||||
$inner = '';
|
||||
|
||||
if (isset($this->childNodes)) {
|
||||
foreach ($this->childNodes as $child) {
|
||||
$inner .= $this->ownerDocument->saveXML($child);
|
||||
}
|
||||
}
|
||||
|
||||
return $inner;
|
||||
}
|
||||
|
||||
$trace = debug_backtrace();
|
||||
trigger_error('Undefined property via __get(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_NOTICE);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
+433
-351
File diff suppressed because it is too large
Load Diff
+330
-169
@@ -4,338 +4,331 @@ namespace Tests\Readability;
|
||||
|
||||
use Monolog\Handler\TestHandler;
|
||||
use Monolog\Logger;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Readability\JSLikeHTMLElement;
|
||||
use Readability\Readability;
|
||||
|
||||
class ReadabilityTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
/** @var TestHandler */
|
||||
public $logHandler;
|
||||
/** @var LoggerInterface */
|
||||
public $logger;
|
||||
|
||||
/**
|
||||
* @requires extension tidy
|
||||
*/
|
||||
public function testConstructDefault()
|
||||
public function testConstructDefault(): void
|
||||
{
|
||||
$readability = $this->getReadability('');
|
||||
$this->assertSame('utf8', $readability->tidy_config['input-encoding']);
|
||||
$readability->init();
|
||||
|
||||
$this->assertNull($readability->url);
|
||||
$this->assertInstanceOf('DomDocument', $readability->dom);
|
||||
$this->assertInstanceOf(\DOMDocument::class, $readability->dom);
|
||||
}
|
||||
|
||||
public function testConstructHtml5Parser()
|
||||
public function testConstructHtml5Parser(): void
|
||||
{
|
||||
$readability = $this->getReadability('<html/>', 'http://0.0.0.0', 'html5lib');
|
||||
$readability->init();
|
||||
|
||||
$this->assertEquals('http://0.0.0.0', $readability->url);
|
||||
$this->assertInstanceOf('DomDocument', $readability->dom);
|
||||
$this->assertEquals('<html/>', $readability->original_html);
|
||||
$this->assertSame('http://0.0.0.0', $readability->url);
|
||||
$this->assertInstanceOf(\DOMDocument::class, $readability->dom);
|
||||
$this->assertSame('<html/>', $readability->original_html);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires extension tidy
|
||||
*/
|
||||
public function testConstructSimple()
|
||||
public function testConstructSimple(): void
|
||||
{
|
||||
$readability = $this->getReadability('<html/>', 'http://0.0.0.0');
|
||||
$readability->init();
|
||||
|
||||
$this->assertEquals('http://0.0.0.0', $readability->url);
|
||||
$this->assertInstanceOf('DomDocument', $readability->dom);
|
||||
$this->assertEquals('<html/>', $readability->original_html);
|
||||
$this->assertSame('http://0.0.0.0', $readability->url);
|
||||
$this->assertInstanceOf(\DOMDocument::class, $readability->dom);
|
||||
$this->assertSame('<html/>', $readability->original_html);
|
||||
$this->assertTrue($readability->tidied);
|
||||
}
|
||||
|
||||
public function testConstructDefaultWithoutTidy()
|
||||
public function testConstructDefaultWithoutTidy(): void
|
||||
{
|
||||
$readability = $this->getReadability('', null, 'libxml', false);
|
||||
$readability->init();
|
||||
|
||||
$this->assertNull($readability->url);
|
||||
$this->assertEquals('', $readability->original_html);
|
||||
$this->assertSame('', $readability->original_html);
|
||||
$this->assertFalse($readability->tidied);
|
||||
|
||||
$this->assertInstanceOf('DomDocument', $readability->dom);
|
||||
$this->assertInstanceOf(\DOMDocument::class, $readability->dom);
|
||||
}
|
||||
|
||||
public function testConstructSimpleWithoutTidy()
|
||||
public function testConstructSimpleWithoutTidy(): void
|
||||
{
|
||||
$readability = $this->getReadability('<html/>', 'http://0.0.0.0', 'libxml', false);
|
||||
$readability->init();
|
||||
|
||||
$this->assertEquals('http://0.0.0.0', $readability->url);
|
||||
$this->assertInstanceOf('DomDocument', $readability->dom);
|
||||
$this->assertEquals('<html/>', $readability->original_html);
|
||||
$this->assertSame('http://0.0.0.0', $readability->url);
|
||||
$this->assertInstanceOf(\DOMDocument::class, $readability->dom);
|
||||
$this->assertSame('<html/>', $readability->original_html);
|
||||
$this->assertFalse($readability->tidied);
|
||||
}
|
||||
|
||||
public function testInitNoContent()
|
||||
public function testInitNoContent(): void
|
||||
{
|
||||
$readability = $this->getReadability('<html/>', 'http://0.0.0.0');
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertFalse($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->assertEmpty($readability->getTitle()->getInnerHtml());
|
||||
$this->assertContains('Sorry, Readability was unable to parse this page for content.', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('Sorry, Readability was unable to parse this page for content.', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function testInitP()
|
||||
public function testInitP(): void
|
||||
{
|
||||
$readability = $this->getReadability(str_repeat('<p>This is the awesome content :)</p>', 7), 'http://0.0.0.0');
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
||||
$this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
||||
$this->assertStringContainsString('<div readability=', $readability->getContent()->getInnerHtml());
|
||||
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
||||
$this->assertContains('This is the awesome content :)', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('This is the awesome content :)', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function testInitDivP()
|
||||
public function testInitDivP(): void
|
||||
{
|
||||
$readability = $this->getReadability('<div>' . str_repeat('<p>This is the awesome content :)</p>', 7) . '</div>', 'http://0.0.0.0');
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
||||
$this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
||||
$this->assertStringContainsString('<div readability=', $readability->getContent()->getInnerHtml());
|
||||
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
||||
$this->assertContains('This is the awesome content :)', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('This is the awesome content :)', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function testInitDiv()
|
||||
public function testInitDiv(): void
|
||||
{
|
||||
$readability = $this->getReadability('<div>' . str_repeat('This is the awesome content :)', 7) . '</div>', 'http://0.0.0.0');
|
||||
$readability->debug = true;
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
||||
$this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
||||
$this->assertStringContainsString('<div readability=', $readability->getContent()->getInnerHtml());
|
||||
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
||||
$this->assertContains('This is the awesome content :)', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('This is the awesome content :)', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function testWithFootnotes()
|
||||
public function testWithFootnotes(): void
|
||||
{
|
||||
$readability = $this->getReadability('<div>' . str_repeat('<p>This is an awesome text with some links, here there are: <a href="http://0.0.0.0/test.html">the awesome</a></p>', 7) . '</div>', 'http://0.0.0.0');
|
||||
$readability->debug = true;
|
||||
$readability->convertLinksToFootnotes = true;
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
||||
$this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
||||
$this->assertStringContainsString('<div readability=', $readability->getContent()->getInnerHtml());
|
||||
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
||||
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertContains('readabilityFootnoteLink', $readability->getContent()->getInnerHtml());
|
||||
$this->assertContains('readabilityLink-3', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('readabilityFootnoteLink', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('readabilityLink-3', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function testStandardClean()
|
||||
public function testStandardClean(): void
|
||||
{
|
||||
$readability = $this->getReadability('<div><h2>Title</h2>' . str_repeat('<p>This is an awesome text with some links, here there are: <a href="http://0.0.0.0/test.html">the awesome</a></p>', 7) . '<a href="#nofollow" rel="nofollow">will NOT be removed</a></div>', 'http://0.0.0.0');
|
||||
$readability->debug = true;
|
||||
$readability->lightClean = false;
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
||||
$this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
||||
$this->assertStringContainsString('<div readability=', $readability->getContent()->getInnerHtml());
|
||||
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
||||
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertContains('will NOT be removed', $readability->getContent()->getInnerHtml());
|
||||
$this->assertNotContains('<h2>', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('will NOT be removed', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringNotContainsString('<h2>', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function testWithIframe()
|
||||
public function testWithIframe(): void
|
||||
{
|
||||
$readability = $this->getReadability('<div><h2>Title</h2>' . str_repeat('<p>This is an awesome text with some links, here there are: <a href="http://0.0.0.0/test.html">the awesome</a></p>', 7) . '<p>This is an awesome text with some links, here there are <iframe src="http://youtube.com/test" href="#nofollow" rel="nofollow"></iframe><iframe>http://soundcloud.com/test</iframe></p></div>', 'http://0.0.0.0');
|
||||
$readability->debug = true;
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
||||
$this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
||||
$this->assertStringContainsString('<div readability=', $readability->getContent()->getInnerHtml());
|
||||
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
||||
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertContains('nofollow', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('nofollow', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function testWithArticle()
|
||||
public function testWithArticle(): void
|
||||
{
|
||||
$readability = $this->getReadability('<article><p>' . str_repeat('This is an awesome text with some links, here there are: the awesome', 20) . '</p><p>This is an awesome text with some links, here there are <iframe src="http://youtube.com/test" href="#nofollow" rel="nofollow"></iframe></p></article>', 'http://0.0.0.0');
|
||||
$readability->debug = true;
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
||||
$this->assertContains('alt="article"', $readability->getContent()->getInnerHtml());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
||||
$this->assertStringContainsString('alt="article"', $readability->getContent()->getInnerHtml());
|
||||
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
||||
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertContains('nofollow', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('nofollow', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function testWithAside()
|
||||
public function testWithAside(): void
|
||||
{
|
||||
$readability = $this->getReadability('<article>' . str_repeat('<p>This is an awesome text with some links, here there are: <a href="http://0.0.0.0/test.html">the awesome</a></p>', 7) . '<footer><aside>' . str_repeat('<p>This is an awesome text with some links, here there are</p>', 8) . '</aside></footer></article>', 'http://0.0.0.0');
|
||||
$readability->debug = true;
|
||||
$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->assertEmpty($readability->getTitle()->getInnerHtml());
|
||||
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertNotContains('<aside>', $readability->getContent()->getInnerHtml());
|
||||
$this->assertContains('<footer readability="5"/>', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringNotContainsString('<aside>', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('<footer readability="9"/>', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function testWithClasses()
|
||||
public function testWithClasses(): void
|
||||
{
|
||||
$readability = $this->getReadability('<article>' . str_repeat('<p>This is an awesome text with some links, here there are: <a href="http://0.0.0.0/test.html">the awesome</a></p>', 7) . '<div style="display:none">' . str_repeat('<p class="clock">This text should be removed</p>', 10) . '</div></article>', 'http://0.0.0.0');
|
||||
$readability->debug = true;
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
||||
$this->assertContains('alt="article"', $readability->getContent()->getInnerHtml());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
||||
$this->assertStringContainsString('alt="article"', $readability->getContent()->getInnerHtml());
|
||||
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
||||
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertNotContains('This text should be removed', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringNotContainsString('This text should be removed', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function testWithClassesWithoutLightClean()
|
||||
public function testWithClassesWithoutLightClean(): void
|
||||
{
|
||||
$readability = $this->getReadability('<article>' . str_repeat('<p>This is an awesome text with some links, here there are: <a href="http://0.0.0.0/test.html">the awesome</a></p>', 7) . '<div style="display:none">' . str_repeat('<p class="clock">This text should be removed</p>', 10) . '</div></article>', 'http://0.0.0.0');
|
||||
$readability->debug = true;
|
||||
$readability->lightClean = false;
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
||||
$this->assertContains('alt="article"', $readability->getContent()->getInnerHtml());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
||||
$this->assertStringContainsString('alt="article"', $readability->getContent()->getInnerHtml());
|
||||
$this->assertEmpty($readability->getTitle()->getInnerHtml());
|
||||
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertNotContains('This text should be removed', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringNotContainsString('This text should be removed', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function testWithTd()
|
||||
public function testWithTd(): void
|
||||
{
|
||||
$readability = $this->getReadability('<table><tr>' . str_repeat('<td><p>This is an awesome text with some links, here there are the awesome</td>', 7) . '</tr></table>', 'http://0.0.0.0');
|
||||
$readability->debug = true;
|
||||
$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->assertEmpty($readability->getTitle()->getInnerHtml());
|
||||
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function testWithSameClasses()
|
||||
public function testWithSameClasses(): void
|
||||
{
|
||||
$readability = $this->getReadability('<article class="awesomecontent">' . str_repeat('<p>This is an awesome text with some links, here there are the awesome</p>', 7) . '<div class="awesomecontent">This text is also an awesome text and you should know that !</div></article>', 'http://0.0.0.0');
|
||||
$readability->debug = true;
|
||||
$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->assertEmpty($readability->getTitle()->getInnerHtml());
|
||||
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function testWithScript()
|
||||
public function testWithScript(): void
|
||||
{
|
||||
$readability = $this->getReadability('<article class="awesomecontent">' . str_repeat('<p>This is an awesome text with some links, here there are the awesome</p>', 7) . '<p><script>This text is also an awesome text and you should know that !</script></p></article>', 'http://0.0.0.0');
|
||||
$readability->debug = true;
|
||||
$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->assertEmpty($readability->getTitle()->getInnerHtml());
|
||||
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringNotContainsString('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function testTitle()
|
||||
public function testTitle(): void
|
||||
{
|
||||
$readability = $this->getReadability('<title>this is my title</title><article class="awesomecontent">' . str_repeat('<p>This is an awesome text with some links, here there are the awesome</p>', 7) . '<p></p></article>', 'http://0.0.0.0');
|
||||
$readability->debug = true;
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
||||
$this->assertEquals('this is my title', $readability->getTitle()->getInnerHtml());
|
||||
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
||||
$this->assertSame('this is my title', $readability->getTitle()->getInnerHtml());
|
||||
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringNotContainsString('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function testTitleWithDash()
|
||||
public function testTitleWithDash(): void
|
||||
{
|
||||
$readability = $this->getReadability('<title> title2 - title3 </title><article class="awesomecontent">' . str_repeat('<p>This is an awesome text with some links, here there are the awesome</p>', 7) . '<p></p></article>', 'http://0.0.0.0');
|
||||
$readability->debug = true;
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
||||
$this->assertEquals('title2 - title3', $readability->getTitle()->getInnerHtml());
|
||||
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
||||
$this->assertSame('title2 - title3', $readability->getTitle()->getInnerHtml());
|
||||
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringNotContainsString('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function testTitleWithDoubleDot()
|
||||
public function testTitleWithDoubleDot(): void
|
||||
{
|
||||
$readability = $this->getReadability('<title> title2 : title3 </title><article class="awesomecontent">' . str_repeat('<p>This is an awesome text with some links, here there are the awesome</p>', 7) . '<p></p></article>', 'http://0.0.0.0');
|
||||
$readability->debug = true;
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
||||
$this->assertEquals('title2 : title3', $readability->getTitle()->getInnerHtml());
|
||||
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
||||
$this->assertSame('title2 : title3', $readability->getTitle()->getInnerHtml());
|
||||
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringNotContainsString('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function testTitleTooShortUseH1()
|
||||
public function testTitleTooShortUseH1(): void
|
||||
{
|
||||
$readability = $this->getReadability('<title>too short</title><h1>this is my h1 title !</h1><article class="awesomecontent">' . str_repeat('<p>This is an awesome text with some links, here there are the awesome</p>', 7) . '<p></p></article>', 'http://0.0.0.0');
|
||||
$readability->debug = true;
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
||||
$this->assertEquals('this is my h1 title !', $readability->getTitle()->getInnerHtml());
|
||||
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
||||
$this->assertSame('this is my h1 title !', $readability->getTitle()->getInnerHtml());
|
||||
$this->assertStringContainsString('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringNotContainsString('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function testAutoClosingIframeNotThrowingException(): void
|
||||
{
|
||||
$oldErrorReporting = error_reporting(\E_ALL);
|
||||
$oldDisplayErrors = ini_set('display_errors', '1');
|
||||
// dummy function to be used to the next test
|
||||
public function error2Exception($code, $string, $file, $line, $context)
|
||||
{
|
||||
throw new \Exception($string, $code);
|
||||
}
|
||||
|
||||
public function testAutoClosingIframeNotThrowingException()
|
||||
{
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
ini_set('display_errors', true);
|
||||
set_error_handler([$this, 'error2Exception'], E_ALL | E_STRICT);
|
||||
set_error_handler(static function (int $errno, string $errstr, string $errfile, int $errline) {
|
||||
throw new \Exception($errstr, $errno);
|
||||
});
|
||||
|
||||
try {
|
||||
$data = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="ru-RU" prefix="og: http://ogp.me/ns#">
|
||||
|
||||
@@ -362,21 +355,27 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
|
||||
</html>';
|
||||
|
||||
$readability = $this->getReadability($data, 'http://iosgames.ru/?p=22030');
|
||||
$readability->debug = true;
|
||||
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
|
||||
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
|
||||
$this->assertContains('<iframe src="https://www.youtube.com/embed/PUep6xNeKjA" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen"> </iframe>', $readability->getContent()->getInnerHtml());
|
||||
$this->assertContains('3D Touch', $readability->getTitle()->getInnerHtml());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getTitle());
|
||||
$this->assertStringContainsString('<iframe src="https://www.youtube.com/embed/PUep6xNeKjA" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen"> </iframe>', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('3D Touch', $readability->getTitle()->getInnerHtml());
|
||||
} finally {
|
||||
restore_error_handler();
|
||||
if (false !== $oldDisplayErrors) {
|
||||
ini_set('display_errors', $oldDisplayErrors);
|
||||
}
|
||||
error_reporting($oldErrorReporting);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This should generate an Exception "DOMElement::setAttribute(): ID post-60 already defined".
|
||||
*/
|
||||
public function testAppendIdAlreadyHere()
|
||||
public function testAppendIdAlreadyHere(): void
|
||||
{
|
||||
$data = '<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
@@ -423,16 +422,15 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
|
||||
</html>';
|
||||
|
||||
$readability = $this->getReadability($data, 'http://0.0.0.0');
|
||||
$readability->debug = true;
|
||||
|
||||
$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());
|
||||
}
|
||||
|
||||
public function testPostFilters()
|
||||
public function testPostFilters(): void
|
||||
{
|
||||
$readability = $this->getReadability('<div>' . str_repeat('<p>This <strong>is</strong> the awesome content :)</p>', 10) . '</div>', 'http://0.0.0.0');
|
||||
$readability->addPostFilter('!<strong[^>]*>(.*?)</strong>!is', '');
|
||||
@@ -440,50 +438,213 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertContains('This the awesome content :)', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('This the awesome content :)', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function testPreFilters()
|
||||
public function testPreFilters(): void
|
||||
{
|
||||
$this->markTestSkipped('Won\'t work until loadHtml() is moved in init() instead of __construct()');
|
||||
|
||||
$readability = $this->getReadability('<div>' . str_repeat('<p>This <b>is</b> the awesome and WONDERFUL content :)</p>', 7) . '</div>', 'http://0.0.0.0');
|
||||
$readability->addPreFilter('!<b[^>]*>(.*?)</b>!is', '');
|
||||
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertContains('This the awesome and WONDERFUL content :)', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('This the awesome and WONDERFUL content :)', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function testChildNodeGoneNull()
|
||||
public function testChildNodeGoneNull(): void
|
||||
{
|
||||
// from http://www.ayyaantuu.net/ethiopia-targets-opposition-lawmakers/
|
||||
$html = file_get_contents('tests/fixtures/childNodeGoesNull.html');
|
||||
$html = (string) file_get_contents('tests/fixtures/childNodeGoesNull.html');
|
||||
|
||||
$readability = $this->getReadability($html, 'http://0.0.0.0');
|
||||
$readability->debug = true;
|
||||
$readability->convertLinksToFootnotes = true;
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertTrue($res);
|
||||
}
|
||||
|
||||
public function testKeepFootnotes()
|
||||
public function dataForHasSingleTagInsideElement(): array
|
||||
{
|
||||
// from https://www.schreibdichte.de/blog/feed-aggregator-und-spaeter-lesen-dienst-im-team
|
||||
$html = file_get_contents('tests/fixtures/keepFootnotes.html');
|
||||
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,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
$readability = $this->getReadability($html, 'http://0.0.0.0');
|
||||
$readability->debug = true;
|
||||
/**
|
||||
* @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->assertContains('<sup id="fnref1:fnfeed_2"><a href="#fn:fnfeed_2" class="footnote-ref">2</a></sup>', $readability->getContent()->getInnerHtml());
|
||||
$this->assertContains('<a href="#fnref1:fnfeed_2" rev="footnote"', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('some code snippet', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('Padded real article text', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
private function getReadability($html, $url = null, $parser = 'libxml', $useTidy = true)
|
||||
public function testKeepFootnotes(): void
|
||||
{
|
||||
// from https://www.schreibdichte.de/blog/feed-aggregator-und-spaeter-lesen-dienst-im-team
|
||||
$html = (string) file_get_contents('tests/fixtures/keepFootnotes.html');
|
||||
|
||||
$readability = $this->getReadability($html, 'http://0.0.0.0');
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertStringContainsString('<sup id="fnref1:fnfeed_2"><a href="#fn:fnfeed_2" class="footnote-ref">2</a></sup>', $readability->getContent()->getInnerHtml());
|
||||
$this->assertStringContainsString('<a href="#fnref1:fnfeed_2" rev="footnote"', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function testWithWipedBody(): void
|
||||
{
|
||||
// from https://www.cs.cmu.edu/~rgs/alice-table.html
|
||||
$html = (string) file_get_contents('tests/fixtures/wipedBody.html');
|
||||
|
||||
$readability = $this->getReadability($html, 'http://0.0.0.0', 'libxml', false);
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertStringContainsString('<a href="alice-I.html">Down the Rabbit-Hole</a>', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
public function dataForVisibleNode(): array
|
||||
{
|
||||
return [
|
||||
'visible node' => [
|
||||
'<div>' . str_repeat('<p>This <b>is</b> the awesome and WONDERFUL content :)</p>', 7) . '</div>',
|
||||
true,
|
||||
],
|
||||
'display=none' => [
|
||||
'<div style="display:none;">' . str_repeat('<p>This <b>is</b> the awesome and WONDERFUL content :)</p>', 7) . '</div>',
|
||||
false,
|
||||
],
|
||||
'display=inline' => [
|
||||
'<div style="display:inline;">' . str_repeat('<p>This <b>is</b> the awesome and WONDERFUL content :)</p>', 7) . '</div>',
|
||||
true,
|
||||
],
|
||||
'hidden attribute' => [
|
||||
'<div hidden>' . str_repeat('<p>This <b>is</b> the awesome and WONDERFUL content :)</p>', 7) . '</div>',
|
||||
false,
|
||||
],
|
||||
'missing display' => [
|
||||
'<div style="color:#ccc;">' . str_repeat('<p>This <b>is</b> the awesome and WONDERFUL content :)</p>', 7) . '</div>',
|
||||
true,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataForVisibleNode
|
||||
*/
|
||||
public function testVisibleNode(string $content, bool $shouldBeVisible): void
|
||||
{
|
||||
$readability = $this->getReadability($content, 'http://0.0.0.0');
|
||||
$res = $readability->init();
|
||||
|
||||
if ($shouldBeVisible) {
|
||||
$this->assertStringContainsString('WONDERFUL content', $readability->getContent()->getInnerHtml());
|
||||
} else {
|
||||
$this->assertStringNotContainsString('WONDERFUL content', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/wallabag/wallabag/issues/8158
|
||||
public function testCharsetAfterTitle(): void
|
||||
{
|
||||
$readability = $this->getReadability('<!DOCTYPE html><html lang="et"><head><title>Tõde ja õigus I</title> <meta charset="utf-8"></head><body><p>See oli läinud aastasaja kolmanda veerandi lõpul. Päike lähenes silmapiirile, seistes sedavõrd madalas, et enam ei ulatunud valgustama ei mäkke ronivat hobust, kes puutelgedega vankrit vedas, ei vankril istuvat noort naist ega ka ligi kolmekümnelist meest, kes kõndis vankri kõrval.</p></body></html>', 'https://et.wikisource.org/wiki/T%C3%B5de_ja_%C3%B5igus_I/I');
|
||||
$readability->convertLinksToFootnotes = true;
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$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());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, array{0: string, 1: string, 2?: bool}>
|
||||
*/
|
||||
public function dataForHtmlLang(): array
|
||||
{
|
||||
return [
|
||||
'meta' => [
|
||||
'<html lang="fr"><head><meta charset="utf-8"></head><body><article>' . str_repeat('<p>Tous les êtres humains naissent libres et égaux en dignité et en droits. Ils sont doués de raison et de conscience et doivent agir les uns envers les autres dans un esprit de fraternité.</p>', 7) . '</article></body></html>',
|
||||
'fr',
|
||||
],
|
||||
'head' => [
|
||||
'<html lang="fr"><head><title>Foo</title></head><body><article>' . str_repeat('<p>Tous les êtres humains naissent libres et égaux en dignité et en droits. Ils sont doués de raison et de conscience et doivent agir les uns envers les autres dans un esprit de fraternité.</p>', 7) . '</article></body></html>',
|
||||
'fr',
|
||||
],
|
||||
'headless' => [
|
||||
'<html lang="fr"><body><article>' . str_repeat('<p>Tous les êtres humains naissent libres et égaux en dignité et en droits. Ils sont doués de raison et de conscience et doivent agir les uns envers les autres dans un esprit de fraternité.</p>', 7) . '</article></body></html>',
|
||||
'fr',
|
||||
// tidy would add <head> tag.
|
||||
false,
|
||||
],
|
||||
'fragment' => [
|
||||
'<article>' . str_repeat('<p>Tous les êtres humains naissent libres et égaux en dignité et en droits. Ils sont doués de raison et de conscience et doivent agir les uns envers les autres dans un esprit de fraternité.</p>', 7) . '</article>',
|
||||
'',
|
||||
// tidy would add <html>.
|
||||
false,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataForHtmlLang
|
||||
*/
|
||||
public function testHtmlLang(string $html, string $lang, bool $useTidy = true): void
|
||||
{
|
||||
$readability = $this->getReadability($html, 'http://0.0.0.0', 'libxml', $useTidy);
|
||||
$res = $readability->init();
|
||||
|
||||
$this->assertTrue($res);
|
||||
$this->assertInstanceOf(\DOMDocument::class, $readability->dom);
|
||||
$this->assertSame($lang, $readability->dom->documentElement->getAttribute('lang'));
|
||||
$this->assertInstanceOf(JSLikeHTMLElement::class, $readability->getContent());
|
||||
$this->assertStringContainsString('êtres', $readability->getContent()->getInnerHtml());
|
||||
}
|
||||
|
||||
private function getReadability(string $html, ?string $url = null, string $parser = 'libxml', bool $useTidy = true): Readability
|
||||
{
|
||||
$readability = new Readability($html, $url, $parser, $useTidy);
|
||||
|
||||
|
||||
Vendored
+67
@@ -0,0 +1,67 @@
|
||||
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Alice's Adventures in Wonderland (Project Gutenberg)</TITLE>
|
||||
</HEAD>
|
||||
|
||||
<frameset Rows="50, *">
|
||||
<frame src="alice-finfo.html">
|
||||
<frame src="alice-ftitle.html" name="alice-main">
|
||||
</frameset>
|
||||
|
||||
<noframes>
|
||||
<BODY>
|
||||
<H1>Alice's Adventures in Wonderland</H1>
|
||||
<H1>Lewis Carroll</H1>
|
||||
<H1>The Millennium Fulcrum Edition 3.0</H1>
|
||||
|
||||
NOTE: This is a hypertext formatted version of the Project Gutenberg edition.
|
||||
For more information, check the
|
||||
<A HREF="alice-small.txt">small print</A>
|
||||
or check out the
|
||||
<A HREF="ftp://uiarchive.cso.uiuc.edu/pub/etext/gutenberg/etext91/alice30.txt">
|
||||
full ascii text</A>. The original Tenniel illustrations are also available
|
||||
due to the efforts of Project Gutenberg. You can if you like, grab them as a
|
||||
<A HREF="ftp://uiarchive.cso.uiuc.edu/pub/etext/gutenberg/etext94/algif10.zip">
|
||||
"zip file"</A> or read the <A HREF="algif-small.txt">small print</A>
|
||||
that comes with them.
|
||||
This document is part of a small, but growing collection of html formatted
|
||||
etexts. (Others may be found in either my <A
|
||||
HREF="http://www.cs.cmu.edu/Web/People/rgs/rgs-home.html">home page</A> or
|
||||
John Ockerbloom's indexes by <A
|
||||
HREF="http://www.cs.cmu.edu/Web/bookauthors.html">author</A> and <A
|
||||
HREF="http://www.cs.cmu.edu/Web/booktitles.html">title</A>.)
|
||||
I am still trying to figure out whether anyone else is interested in these
|
||||
on-line readable documents. If you appreciate this document or would like to
|
||||
see more such, send me mail at "rgs@cs.cmu.edu".
|
||||
<P>
|
||||
<A HREF="alice01a.gif"><IMG SRC="alice01th.gif"></A>
|
||||
<P>
|
||||
<H2>CONTENTS</H2>
|
||||
<PRE>
|
||||
CHAPTER I: <A HREF="alice-I.html">Down the Rabbit-Hole</A>
|
||||
CHAPTER II: <A HREF="alice-II.html">The Pool of Tears</A>
|
||||
CHAPTER III: <A HREF="alice-III.html">A Caucus-Race and a Long Tale</A>
|
||||
CHAPTER IV: <A HREF="alice-IV.html">The Rabbit Sends in a Little Bill</A>
|
||||
CHAPTER V: <A HREF="alice-V.html">Advice from a Caterpillar</A>
|
||||
CHAPTER VI: <A HREF="alice-VI.html">Pig and Pepper</A>
|
||||
CHAPTER VII: <A HREF="alice-VII.html">A Mad Tea-Party</A>
|
||||
CHAPTER VIII: <A HREF="alice-VIII.html">The Queen's Croquet-Ground</A>
|
||||
CHAPTER IX: <A HREF="alice-IX.html">The Mock Turtle's Story</A>
|
||||
CHAPTER X: <A HREF="alice-X.html">The Lobster Quadrille</A>
|
||||
CHAPTER XI: <A HREF="alice-XI.html">Who Stole the Tarts?</A>
|
||||
CHAPTER XII: <A HREF="alice-XII.html">Alice's Evidence</A>
|
||||
</PRE>
|
||||
|
||||
<ADDRESS><A HREF="mailto:rgs@cs.cmu.edu">Robert Stockton</A></ADDRESS>
|
||||
<P>
|
||||
<!- Access counter added 5/25 1:49am ->
|
||||
<A href="http://www.dbasics.com/cgi-bin/pages.cgi?143205747"><IMG SRC="http://www.dbasics.com/cgi-bin/counter.cgi?143205747.2&(none)"></A> Access statistics from htmlZine
|
||||
<!- This page has been visited
|
||||
A HREF="http://counter.digits.com/wc?--info=yes&--name=rgsalice"
|
||||
IMG SRC="http://counter.digits.com/wc/-d/4/-r/-z/rgsalice"
|
||||
ALIGN=absmiddle WIDTH=60 HEIGHT=20 BORDER=0 HSPACE=4 ALT="????"/A
|
||||
times since March 2, 1996. ->
|
||||
</BODY>
|
||||
</noframes>
|
||||
</HTML>
|
||||
Reference in New Issue
Block a user