Compare commits

..
23 Commits
Author SHA1 Message Date
Jérémy BenoistandGitHub 9632c4df8c Merge pull request #61 from j0k3r/github-actions
Ditch Travis to use GitHub Actions
2020-11-30 14:34:46 +01:00
Jeremy Benoist bd9ca1b2cd Ditch Travis to use GitHub Actions 2020-11-30 14:18:40 +01:00
Jérémy BenoistandGitHub 6c917794a7 Merge pull request #60 from jtojnar/patch-1
readability: stop tidy from wrapping noscript text
2020-11-16 12:02:02 +01:00
Jan TojnarandGitHub 7cea79c23a readability: stop tidy from wrapping noscript text
HTML 4.01 Strict only allows block-level elements within noscript, form and
blockquote. The `enclose-block-text` option fixes the instances when those
elements contain inline elements or text by wrapping the children in paragraphs.

HTML 5 has looser content model and allows noscript elements basically anywhere,
including paragraphs, making the noscript elements inherit the parent element’s
content model. This means that tidy will produce invalid HTML nesting paragraphs
for `p > noscript > text`, a structure that would be invalid on two counts
in HTML 4 Strict profile but is completely valid in HTML 5.

Popular WordPress image lazy-loading code produces precisely that structure
so tidy “corrects” it to invalid code. In a proper HTML parser, the produced
code would force close the outer paragraph, making the noscript element
its sibling instead of a child. The only reason this does not break Graby’s code
for stripping the lazy-loading HTML is that libxml2 contains a bug
counteracting this:

https://gitlab.gnome.org/GNOME/libxml2/-/issues/205

Since all three elements allow flow content in HTML 5, it does not make much
sense to enable this option any more. The only possible issues that could occur
is producing HTML code not conforming to 4.01 Strict but that was never guaranteed,
as our example shows, and having blockquotes contain text nodes not wrapped
in paragraphs, which might be expected by some ancient stylesheets
but that is only minor and easily fixable visual backwards incompatibility.
2020-11-14 22:13:53 +01:00
Jérémy BenoistandGitHub c6425cc28b Merge pull request #58 from j0k3r/fix/test-php8
Enable tests for PHP 8
2020-06-08 09:58:28 +02:00
Jeremy Benoist e6ad806460 Enable tests on PHP 8 2020-06-08 09:24:50 +02:00
Jérémy BenoistandGitHub 3fa88461a0 Merge pull request #57 from j0k3r/fix/html5-parser
Use a new deps for HTML5 parser
2020-06-08 07:59:42 +02:00
Jeremy Benoist 6a8ecf232f Use a new deps for HTML5 parser
`electrolinux/php-html5lib` was quite old and incompatible with the upcoming Composer 2.0.
Jumping to `masterminds/html5` for the same result. Also the lib is maintained.

Also:
- keep README in vendors
- use new Scrutinizer engine
- test with lower deps
- remove php-coveralls dev deps and download the phar during the CI build
2020-06-08 07:04:00 +02:00
Jérémy BenoistandGitHub 52b1ddba57 Merge pull request #55 from j0k3r/fix/cleanup-travis
Cleanup travis
2020-04-12 16:38:09 +02:00
Jeremy Benoist 90c625bb57 Cleanup travis 2020-04-12 16:30:02 +02:00
Jérémy BenoistandGitHub 4d1c3b1777 Merge pull request #54 from j0k3r/fix/phpstan
Fix PHPStan (again)
2020-01-06 14:26:41 +01:00
Jeremy Benoist d649b59414 Fixing PHPUnit versions 2020-01-06 14:22:15 +01:00
Jeremy Benoist 44bebfc3d6 Only install PHPStan when we need it
This is to avoid error when installing it on PHP < 7.1
2020-01-06 14:03:30 +01:00
Jeremy Benoist b1acc9ed73 Fix PHPStan (again)
Also cleanup
2019-11-19 14:09:29 +01:00
Jérémy BenoistandGitHub 9306996b47 Merge pull request #53 from j0k3r/openload.co
Add openload.co to media detection
2019-06-25 17:15:37 +02:00
Jeremy Benoist bb75b4f089 Fix PHPStan 2019-06-25 17:06:49 +02:00
Jeremy Benoist 11d2946904 Add openload.co to media detection 2019-06-25 16:54:38 +02:00
Jérémy BenoistandGitHub f808c1b0a2 Merge pull request #50 from j0k3r/fix/non-well-formed-numeric-value
Fix “A non well formed numeric value encountered”
2019-05-11 22:07:19 +02:00
Jeremy Benoist bb65caf864 Fix “A non well formed numeric value encountered” 2019-05-11 21:58:11 +02:00
Jérémy BenoistandGitHub de1b1d9775 Merge pull request #48 from Simounet/feature/out-removed-from-negative
\bout removed from negative content
2019-04-23 10:45:13 +02:00
Simounet 2e20f76195 \bout removed from negative content 2019-04-19 12:12:41 +02:00
Jérémy BenoistandGitHub 3c0289bf89 Merge pull request #46 from j0k3r/phpstan
Enable PHPStan
2019-02-07 16:08:33 +01:00
Jeremy Benoist 74d9cc605a Enable PHPStan 2019-02-07 15:51:31 +01:00
14 changed files with 451 additions and 181 deletions
+3 -2
View File
@@ -4,9 +4,10 @@ root = true
; Unix-style newlines ; Unix-style newlines
[*] [*]
end_of_line = LF end_of_line = LF
[*.php]
indent_style = space indent_style = space
indent_size = 4 indent_size = 4
trim_trailing_whitespace = true trim_trailing_whitespace = true
insert_final_newline = true insert_final_newline = true
[.github/**.yml]
indent_size = 2
+2 -1
View File
@@ -4,6 +4,7 @@
/.scrutinizer.yml export-ignore /.scrutinizer.yml export-ignore
/.travis.yml export-ignore /.travis.yml export-ignore
/.php_cs export-ignore /.php_cs export-ignore
/README.md export-ignore
/phpunit.xml.dist export-ignore /phpunit.xml.dist export-ignore
/phpstan.neon export-ignore
/.github export-ignore
/tests export-ignore /tests export-ignore
+53
View File
@@ -0,0 +1,53 @@
name: "CS"
on:
pull_request:
branches:
- master
push:
branches:
- master
env:
SYMFONY_PHPUNIT_VERSION: 7.5
jobs:
coding-standards:
name: "CS Fixer & PHPStan"
runs-on: "ubuntu-18.04"
strategy:
matrix:
php:
- "7.3"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "${{ matrix.php }}"
tools: cs2pr, composer:v1
ini-values: "date.timezone=Europe/Paris"
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: "Add PHPStan"
run: "composer require phpstan/phpstan phpstan/phpstan-phpunit --dev --no-progress --no-suggest"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v1"
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,202 @@
name: "CI"
on:
pull_request:
branches:
- "master"
push:
branches:
- "master"
env:
fail-fast: true
jobs:
phpunit:
name: "PHPUnit (PHP ${{ matrix.php }})"
runs-on: "ubuntu-18.04"
strategy:
matrix:
php:
- "5.6"
- "7.0"
- "7.1"
- "7.2"
- "7.3"
- "7.4"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
with:
fetch-depth: 2
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php }}"
coverage: "none"
tools: composer:v1
extensions: tidy
ini-values: "date.timezone=Europe/Paris"
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: "Force PHPUnit version"
if: matrix.php >= '7.2'
run: "echo $SYMFONY_PHPUNIT_VERSION"
env:
SYMFONY_PHPUNIT_VERSION: 7.5
- 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@v1"
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-18.04"
strategy:
matrix:
php:
- "7.4"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
with:
fetch-depth: 2
- name: "Install PHP with Xdebug"
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php }}"
coverage: "xdebug"
tools: composer:v1
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@v1"
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"
env:
SYMFONY_PHPUNIT_VERSION: 7.5
- name: "Retrieve Coveralls phar"
run: "wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.4.2/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-18.04"
strategy:
matrix:
php:
- "7.2"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
with:
fetch-depth: 2
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php }}"
coverage: "none"
tools: composer:v1
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@v1"
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"
env:
SYMFONY_PHPUNIT_VERSION: 7.5
phpunit-composerv2:
name: "PHPUnit with Composer v2 (PHP ${{ matrix.php }})"
runs-on: "ubuntu-18.04"
strategy:
matrix:
php:
- "7.4"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
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@v1"
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"
env:
SYMFONY_PHPUNIT_VERSION: 7.5
+1
View File
@@ -2,3 +2,4 @@ vendor/
coverage/ coverage/
composer.lock composer.lock
.php_cs.cache .php_cs.cache
.phpunit.result.cache
+10
View File
@@ -1,2 +1,12 @@
tools: tools:
external_code_coverage: false external_code_coverage: false
build:
nodes:
analysis:
tests:
override:
- php-scrutinizer-run
environment:
php:
version: 7.2
+16 -22
View File
@@ -1,40 +1,34 @@
dist: xenial
os: linux
language: php language: php
php: # avoid double Travis build when the PR is created on upstream
- 5.6 if: |
- 7.0 type = pull_request OR \
- 7.1 branch = master
- 7.2
- 7.3
- nightly
matrix: jobs:
include: include:
- php: 7.2 - php: 8.0
env: CS_FIXER=run env: SYMFONY_PHPUNIT_VERSION=7.5
fast_finish: true fast_finish: true
allow_failures: allow_failures:
- php: nightly - php: 8.0
# cache vendor dirs
cache: cache:
directories: directories:
- vendor - $HOME/.composer/cache/files
- $HOME/.composer/cache
before_install: before_install:
- if [ -n "$GH_TOKEN" ]; then composer config github-oauth.github.com ${GH_TOKEN}; fi; - if [ -n "$GH_TOKEN" ]; then composer config github-oauth.github.com ${GH_TOKEN}; fi;
install: install:
- composer self-update - if [ "$CS_FIXER" != "run" ]; then composer remove friendsofphp/php-cs-fixer --dev --no-progress --no-update ; fi;
- composer update --prefer-dist --no-progress --no-suggest -o $
- php vendor/bin/simple-phpunit install
before_script: before_script:
- composer install -o --prefer-dist --no-interaction - mkdir -p build/logs
script: script:
- mkdir -p build/logs - php vendor/bin/simple-phpunit -v
- 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;
after_script:
- php vendor/bin/php-coveralls -v -x build/logs/clover.xml
+1
View File
@@ -1,5 +1,6 @@
# Readability # Readability
![CI](https://github.com/j0k3r/php-readability/workflows/CI/badge.svg)
[![Build Status](https://travis-ci.org/j0k3r/php-readability.svg?branch=master)](https://travis-ci.org/j0k3r/php-readability) [![Build Status](https://travis-ci.org/j0k3r/php-readability.svg?branch=master)](https://travis-ci.org/j0k3r/php-readability)
[![Coverage Status](https://coveralls.io/repos/j0k3r/php-readability/badge.svg?branch=master&service=github)](https://coveralls.io/github/j0k3r/php-readability/?branch=master) [![Coverage Status](https://coveralls.io/repos/j0k3r/php-readability/badge.svg?branch=master&service=github)](https://coveralls.io/github/j0k3r/php-readability/?branch=master)
[![Total Downloads](https://poser.pugx.org/j0k3r/php-readability/downloads)](https://packagist.org/packages/j0k3r/php-readability) [![Total Downloads](https://poser.pugx.org/j0k3r/php-readability/downloads)](https://packagist.org/packages/j0k3r/php-readability)
+5 -3
View File
@@ -27,12 +27,11 @@
"php": ">=5.6.0", "php": ">=5.6.0",
"ext-mbstring": "*", "ext-mbstring": "*",
"psr/log": "^1.0", "psr/log": "^1.0",
"electrolinux/php-html5lib": "^0.1.0" "masterminds/html5": "^2.7"
}, },
"require-dev": { "require-dev": {
"php-coveralls/php-coveralls": "^2.1",
"friendsofphp/php-cs-fixer": "^2.14", "friendsofphp/php-cs-fixer": "^2.14",
"monolog/monolog": "^1.24", "monolog/monolog": "^1.24|^2.1",
"symfony/phpunit-bridge": "^4.2.3" "symfony/phpunit-bridge": "^4.2.3"
}, },
"suggest": { "suggest": {
@@ -40,5 +39,8 @@
}, },
"autoload": { "autoload": {
"psr-4": { "Readability\\": "src/" } "psr-4": { "Readability\\": "src/" }
},
"autoload-dev": {
"psr-4": { "Tests\\Readability\\": "tests/" }
} }
} }
+13
View File
@@ -0,0 +1,13 @@
parameters:
level: 1
paths:
- src
- tests
# https://github.com/phpstan/phpstan/issues/694#issuecomment-350724288
bootstrapFiles:
- vendor/bin/.phpunit/phpunit-7.5-0/vendor/autoload.php
includes:
- vendor/phpstan/phpstan-phpunit/extension.neon
- vendor/phpstan/phpstan-phpunit/rules.neon
+1 -2
View File
@@ -7,7 +7,6 @@
convertWarningsToExceptions="true" convertWarningsToExceptions="true"
processIsolation="false" processIsolation="false"
stopOnFailure="false" stopOnFailure="false"
syntaxCheck="false"
bootstrap="vendor/autoload.php" bootstrap="vendor/autoload.php"
> >
@@ -27,6 +26,6 @@
</filter> </filter>
<!-- <logging> <!-- <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> --> </logging> -->
</phpunit> </phpunit>
+10
View File
@@ -127,4 +127,14 @@ class JSLikeHTMLElement extends \DOMElement
{ {
return '[' . $this->tagName . ']'; return '[' . $this->tagName . ']';
} }
public function getInnerHtml()
{
return $this->__get('innerHTML');
}
public function setInnerHtml($value)
{
return $this->__set('innerHTML', $value);
}
} }
+63 -80
View File
@@ -2,7 +2,7 @@
namespace Readability; namespace Readability;
use HTML5Lib\Parser; use Masterminds\HTML5;
use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger; use Psr\Log\NullLogger;
@@ -61,7 +61,7 @@ class Readability implements LoggerAwareInterface
// constants // constants
const SCORE_CHARS_IN_PARAGRAPH = 100; const SCORE_CHARS_IN_PARAGRAPH = 100;
const SCORE_WORDS_IN_PARAGRAPH = 20; const SCORE_WORDS_IN_PARAGRAPH = 20;
const GRANDPARENT_SCORE_DIVISOR = 2.2; const GRANDPARENT_SCORE_DIVISOR = 2;
const MIN_PARAGRAPH_LENGTH = 20; const MIN_PARAGRAPH_LENGTH = 20;
const MIN_COMMAS_IN_PARAGRAPH = 6; const MIN_COMMAS_IN_PARAGRAPH = 6;
const MIN_ARTICLE_LENGTH = 200; const MIN_ARTICLE_LENGTH = 200;
@@ -72,6 +72,9 @@ class Readability implements LoggerAwareInterface
public $articleTitle; public $articleTitle;
public $articleContent; public $articleContent;
public $original_html; public $original_html;
/**
* @var \DOMDocument
*/
public $dom; public $dom;
// optional - URL where HTML was retrieved // optional - URL where HTML was retrieved
public $url = null; public $url = null;
@@ -89,10 +92,10 @@ class Readability implements LoggerAwareInterface
'unlikelyCandidates' => '/display\s*:\s*none|ignore|\binfos?\b|annoy|clock|date|time|author|intro|hidd?e|about|archive|\bprint|bookmark|tags|tag-list|share|search|social|robot|published|combx|comment|mast(?:head)|subscri|community|category|disqus|extra|head|head(?:er|note)|floor|foot(?:er|note)|menu|tool\b|function|nav|remark|rss|shoutbox|widget|meta|banner|sponsor|adsense|inner-?ad|ad-|sponsor|\badv\b|\bads\b|agr?egate?|pager|sidebar|popup|tweet|twitter/i', 'unlikelyCandidates' => '/display\s*:\s*none|ignore|\binfos?\b|annoy|clock|date|time|author|intro|hidd?e|about|archive|\bprint|bookmark|tags|tag-list|share|search|social|robot|published|combx|comment|mast(?:head)|subscri|community|category|disqus|extra|head|head(?:er|note)|floor|foot(?:er|note)|menu|tool\b|function|nav|remark|rss|shoutbox|widget|meta|banner|sponsor|adsense|inner-?ad|ad-|sponsor|\badv\b|\bads\b|agr?egate?|pager|sidebar|popup|tweet|twitter/i',
'okMaybeItsACandidate' => '/article\b|contain|\bcontent|column|general|detail|shadow|lightbox|blog|body|entry|main|page|footnote/i', 'okMaybeItsACandidate' => '/article\b|contain|\bcontent|column|general|detail|shadow|lightbox|blog|body|entry|main|page|footnote/i',
'positive' => '/read|full|article|body|\bcontent|contain|entry|main|markdown|media|page|attach|pagination|post|text|blog|story/i', 'positive' => '/read|full|article|body|\bcontent|contain|entry|main|markdown|media|page|attach|pagination|post|text|blog|story/i',
'negative' => '/bottom|stat|info|discuss|e[\-]?mail|comment|reply|log.{2}(n|ed)|sign|single|combx|com-|contact|_nav|link|media|\bout|promo|\bad-|related|scroll|shoutbox|sidebar|sponsor|shopping|teaser|recommend/i', 'negative' => '/bottom|stat|info|discuss|e[\-]?mail|comment|reply|log.{2}(n|ed)|sign|single|combx|com-|contact|_nav|link|media|promo|\bad-|related|scroll|shoutbox|sidebar|sponsor|shopping|teaser|recommend/i',
'divToPElements' => '/<(?:blockquote|header|section|code|div|article|footer|aside|img|p|pre|dl|ol|ul)/mi', 'divToPElements' => '/<(?:blockquote|header|section|code|div|article|footer|aside|img|p|pre|dl|ol|ul)/mi',
'killBreaks' => '/(<br\s*\/?>([ \r\n\s]|&nbsp;?)*)+/', 'killBreaks' => '/(<br\s*\/?>([ \r\n\s]|&nbsp;?)*)+/',
'media' => '!//(?:[^\.\?/]+\.)?(?:youtu(?:be)?|giphy|soundcloud|dailymotion|vimeo|pornhub|xvideos|twitvid|rutube|viddler)\.(?:com|be|org|net)/!i', 'media' => '!//(?:[^\.\?/]+\.)?(?:youtu(?:be)?|giphy|soundcloud|dailymotion|vimeo|pornhub|xvideos|twitvid|rutube|openload\.co|viddler)\.(?:com|be|org|net)/!i',
'skipFootnoteLink' => '/^\s*(\[?[a-z0-9]{1,2}\]?|^|edit|citation needed)\s*$/i', 'skipFootnoteLink' => '/^\s*(\[?[a-z0-9]{1,2}\]?|^|edit|citation needed)\s*$/i',
]; ];
public $tidy_config = [ public $tidy_config = [
@@ -113,7 +116,6 @@ class Readability implements LoggerAwareInterface
'drop-empty-paras' => true, 'drop-empty-paras' => true,
'drop-proprietary-attributes' => false, 'drop-proprietary-attributes' => false,
'enclose-text' => true, 'enclose-text' => true,
'enclose-block-text' => true,
'merge-divs' => true, 'merge-divs' => true,
// 'merge-spans' => true, // 'merge-spans' => true,
'input-encoding' => '????', 'input-encoding' => '????',
@@ -169,10 +171,10 @@ class Readability implements LoggerAwareInterface
/** /**
* Create instance of Readability. * Create instance of Readability.
* *
* @param string UTF-8 encoded string * @param string $html UTF-8 encoded string
* @param string (optional) URL associated with HTML (for footnotes) * @param string $url URL associated with HTML (for footnotes)
* @param string (optional) Which parser to use for turning raw HTML into a DOMDocument * @param string $parser Which parser to use for turning raw HTML into a DOMDocument
* @param bool (optional) Use tidy * @param bool $use_tidy Use tidy
*/ */
public function __construct($html, $url = null, $parser = 'libxml', $use_tidy = true) public function __construct($html, $url = null, $parser = 'libxml', $use_tidy = true)
{ {
@@ -213,8 +215,8 @@ class Readability implements LoggerAwareInterface
/** /**
* Add pre filter for raw input HTML processing. * Add pre filter for raw input HTML processing.
* *
* @param string RegExp for replace * @param string $filter RegExp for replace
* @param string (optional) Replacer * @param string $replacer Replacer
*/ */
public function addPreFilter($filter, $replacer = '') public function addPreFilter($filter, $replacer = '')
{ {
@@ -224,8 +226,8 @@ class Readability implements LoggerAwareInterface
/** /**
* Add post filter for raw output HTML processing. * Add post filter for raw output HTML processing.
* *
* @param string RegExp for replace * @param string $filter RegExp for replace
* @param string (optional) Replacer * @param string $replacer Replacer
*/ */
public function addPostFilter($filter, $replacer = '') public function addPostFilter($filter, $replacer = '')
{ {
@@ -258,7 +260,7 @@ class Readability implements LoggerAwareInterface
if (null === $this->bodyCache) { if (null === $this->bodyCache) {
$this->bodyCache = ''; $this->bodyCache = '';
foreach ($bodyElems as $bodyNode) { foreach ($bodyElems as $bodyNode) {
$this->bodyCache .= trim($bodyNode->innerHTML); $this->bodyCache .= trim($bodyNode->getInnerHTML());
} }
} }
@@ -278,7 +280,7 @@ class Readability implements LoggerAwareInterface
$this->success = false; $this->success = false;
$articleContent = $this->dom->createElement('div'); $articleContent = $this->dom->createElement('div');
$articleContent->setAttribute('class', 'readability-content'); $articleContent->setAttribute('class', 'readability-content');
$articleContent->innerHTML = '<p>Sorry, Readability was unable to parse this page for content.</p>'; $articleContent->setInnerHtml('<p>Sorry, Readability was unable to parse this page for content.</p>');
} }
$overlay->setAttribute('class', 'readOverlay'); $overlay->setAttribute('class', 'readOverlay');
@@ -290,7 +292,7 @@ class Readability implements LoggerAwareInterface
$overlay->appendChild($innerDiv); $overlay->appendChild($innerDiv);
// Clear the old HTML, insert the new content. // Clear the old HTML, insert the new content.
$this->body->innerHTML = ''; $this->body->setInnerHtml('');
$this->body->appendChild($overlay); $this->body->appendChild($overlay);
$this->body->removeAttribute('style'); $this->body->removeAttribute('style');
$this->postProcessContent($articleContent); $this->postProcessContent($articleContent);
@@ -304,10 +306,8 @@ class Readability implements LoggerAwareInterface
/** /**
* Run any post-process modifications to article content as necessary. * Run any post-process modifications to article content as necessary.
*
* @param \DOMElement $articleContent
*/ */
public function postProcessContent($articleContent) public function postProcessContent(\DOMElement $articleContent)
{ {
if ($this->convertLinksToFootnotes && !preg_match('/\bwiki/', $this->url)) { if ($this->convertLinksToFootnotes && !preg_match('/\bwiki/', $this->url)) {
$this->addFootnotes($articleContent); $this->addFootnotes($articleContent);
@@ -318,14 +318,12 @@ class Readability implements LoggerAwareInterface
* For easier reading, convert this document to have footnotes at the bottom rather than inline links. * For easier reading, convert this document to have footnotes at the bottom rather than inline links.
* *
* @see http://www.roughtype.com/archives/2010/05/experiments_in.php * @see http://www.roughtype.com/archives/2010/05/experiments_in.php
*
* @param \DOMElement $articleContent
*/ */
public function addFootnotes($articleContent) public function addFootnotes(\DOMElement $articleContent)
{ {
$footnotesWrapper = $this->dom->createElement('footer'); $footnotesWrapper = $this->dom->createElement('footer');
$footnotesWrapper->setAttribute('class', 'readability-footnotes'); $footnotesWrapper->setAttribute('class', 'readability-footnotes');
$footnotesWrapper->innerHTML = '<h3>References</h3>'; $footnotesWrapper->setInnerHtml('<h3>References</h3>');
$articleFootnotes = $this->dom->createElement('ol'); $articleFootnotes = $this->dom->createElement('ol');
$articleFootnotes->setAttribute('class', 'readability-footnotes-list'); $articleFootnotes->setAttribute('class', 'readability-footnotes-list');
$footnotesWrapper->appendChild($articleFootnotes); $footnotesWrapper->appendChild($articleFootnotes);
@@ -351,7 +349,7 @@ class Readability implements LoggerAwareInterface
// Add a superscript reference after the article link. // Add a superscript reference after the article link.
$refLink->setAttribute('href', '#readabilityFootnoteLink-' . $linkCount); $refLink->setAttribute('href', '#readabilityFootnoteLink-' . $linkCount);
$refLink->innerHTML = '<small><sup>[' . $linkCount . ']</sup></small>'; $refLink->setInnerHtml('<small><sup>[' . $linkCount . ']</sup></small>');
$refLink->setAttribute('class', 'readability-DoNotFootnote'); $refLink->setAttribute('class', 'readability-DoNotFootnote');
$refLink->setAttribute('style', 'color: inherit;'); $refLink->setAttribute('style', 'color: inherit;');
@@ -363,13 +361,13 @@ class Readability implements LoggerAwareInterface
$articleLink->setAttribute('style', 'color: inherit; text-decoration: none;'); $articleLink->setAttribute('style', 'color: inherit; text-decoration: none;');
$articleLink->setAttribute('name', 'readabilityLink-' . $linkCount); $articleLink->setAttribute('name', 'readabilityLink-' . $linkCount);
$footnote->innerHTML = '<small><sup><a href="#readabilityLink-' . $linkCount . '" title="Jump to Link in Article">^</a></sup></small> '; $footnote->setInnerHtml('<small><sup><a href="#readabilityLink-' . $linkCount . '" title="Jump to Link in Article">^</a></sup></small> ');
$footnoteLink->innerHTML = ('' !== $footnoteLink->getAttribute('title') ? $footnoteLink->getAttribute('title') : $linkText); $footnoteLink->setInnerHtml(('' !== $footnoteLink->getAttribute('title') ? $footnoteLink->getAttribute('title') : $linkText));
$footnoteLink->setAttribute('name', 'readabilityFootnoteLink-' . $linkCount); $footnoteLink->setAttribute('name', 'readabilityFootnoteLink-' . $linkCount);
$footnote->appendChild($footnoteLink); $footnote->appendChild($footnoteLink);
if ($linkDomain) { if ($linkDomain) {
$footnote->innerHTML = $footnote->innerHTML . '<small> (' . $linkDomain . ')</small>'; $footnote->setInnerHtml($footnote->getInnerHTML() . '<small> (' . $linkDomain . ')</small>');
} }
$articleFootnotes->appendChild($footnote); $articleFootnotes->appendChild($footnote);
} }
@@ -382,11 +380,13 @@ class Readability implements LoggerAwareInterface
/** /**
* Prepare the article node for display. Clean out any inline styles, * Prepare the article node for display. Clean out any inline styles,
* iframes, forms, strip extraneous <p> tags, etc. * iframes, forms, strip extraneous <p> tags, etc.
*
* @param \DOMElement $articleContent
*/ */
public function prepArticle($articleContent) public function prepArticle(\DOMNode $articleContent)
{ {
if (!$articleContent instanceof \DOMElement) {
return;
}
$this->logger->debug($this->lightClean ? 'Light clean enabled.' : 'Standard clean enabled.'); $this->logger->debug($this->lightClean ? 'Light clean enabled.' : 'Standard clean enabled.');
$this->cleanStyles($articleContent); $this->cleanStyles($articleContent);
@@ -467,7 +467,7 @@ class Readability implements LoggerAwareInterface
if (!$this->flagIsActive(self::FLAG_DISABLE_POSTFILTER)) { if (!$this->flagIsActive(self::FLAG_DISABLE_POSTFILTER)) {
try { try {
foreach ($this->post_filters as $search => $replace) { foreach ($this->post_filters as $search => $replace) {
$articleContent->innerHTML = preg_replace($search, $replace, $articleContent->innerHTML); $articleContent->setInnerHtml(preg_replace($search, $replace, $articleContent->getInnerHTML()));
} }
unset($search, $replace); unset($search, $replace);
} catch (\Exception $e) { } catch (\Exception $e) {
@@ -551,12 +551,11 @@ class Readability implements LoggerAwareInterface
* This is the amount of text that is inside a link divided by the total text in the node. * This is the amount of text that is inside a link divided by the total text in the node.
* Can exclude external references to differentiate between simple text and menus/infoblocks. * Can exclude external references to differentiate between simple text and menus/infoblocks.
* *
* @param \DOMElement $e * @param bool $excludeExternal
* @param string $excludeExternal
* *
* @return int * @return int
*/ */
public function getLinkDensity($e, $excludeExternal = false) public function getLinkDensity(\DOMElement $e, $excludeExternal = false)
{ {
$links = $e->getElementsByTagName('a'); $links = $e->getElementsByTagName('a');
$textLength = mb_strlen($this->getInnerText($e, true, true)); $textLength = mb_strlen($this->getInnerText($e, true, true));
@@ -579,11 +578,9 @@ class Readability implements LoggerAwareInterface
/** /**
* Get an element relative weight. * Get an element relative weight.
* *
* @param \DOMElement $e
*
* @return int * @return int
*/ */
public function getWeight($e) public function getWeight(\DOMElement $e)
{ {
if (!$this->flagIsActive(self::FLAG_WEIGHT_ATTRIBUTES)) { if (!$this->flagIsActive(self::FLAG_WEIGHT_ATTRIBUTES)) {
return 0; return 0;
@@ -600,14 +597,12 @@ class Readability implements LoggerAwareInterface
/** /**
* Remove extraneous break tags from a node. * Remove extraneous break tags from a node.
*
* @param \DOMElement $node
*/ */
public function killBreaks($node) public function killBreaks(\DOMElement $node)
{ {
$html = $node->innerHTML; $html = $node->getInnerHTML();
$html = preg_replace($this->regexps['killBreaks'], '<br />', $html); $html = preg_replace($this->regexps['killBreaks'], '<br />', $html);
$node->innerHTML = $html; $node->setInnerHtml($html);
} }
/** /**
@@ -616,12 +611,10 @@ class Readability implements LoggerAwareInterface
* *
* Updated 2012-09-18 to preserve youtube/vimeo iframes * Updated 2012-09-18 to preserve youtube/vimeo iframes
* *
* @param \DOMElement $e
* @param string $tag * @param string $tag
*/ */
public function clean($e, $tag) public function clean(\DOMElement $e, $tag)
{ {
$currentItem = null;
$targetList = $e->getElementsByTagName($tag); $targetList = $e->getElementsByTagName($tag);
$isEmbed = ('audio' === $tag || 'video' === $tag || 'iframe' === $tag || 'object' === $tag || 'embed' === $tag); $isEmbed = ('audio' === $tag || 'video' === $tag || 'iframe' === $tag || 'object' === $tag || 'embed' === $tag);
@@ -638,7 +631,7 @@ class Readability implements LoggerAwareInterface
} }
// Then check the elements inside this element for the same. // Then check the elements inside this element for the same.
if (preg_match($this->regexps['media'], $targetList->item($y)->innerHTML)) { if (preg_match($this->regexps['media'], $targetList->item($y)->getInnerHTML())) {
continue; continue;
} }
} }
@@ -652,10 +645,9 @@ class Readability implements LoggerAwareInterface
* "Fishy" is an algorithm based on content length, classnames, * "Fishy" is an algorithm based on content length, classnames,
* link density, number of images & embeds, etc. * link density, number of images & embeds, etc.
* *
* @param \DOMElement $e
* @param string $tag * @param string $tag
*/ */
public function cleanConditionally($e, $tag) public function cleanConditionally(\DOMElement $e, $tag)
{ {
if (!$this->flagIsActive(self::FLAG_CLEAN_CONDITIONALLY)) { if (!$this->flagIsActive(self::FLAG_CLEAN_CONDITIONALLY)) {
return; return;
@@ -663,7 +655,6 @@ class Readability implements LoggerAwareInterface
$tagsList = $e->getElementsByTagName($tag); $tagsList = $e->getElementsByTagName($tag);
$curTagsLength = $tagsList->length; $curTagsLength = $tagsList->length;
$node = null;
/* /*
* Gather counts for other typical elements embedded within. * Gather counts for other typical elements embedded within.
@@ -765,10 +756,8 @@ class Readability implements LoggerAwareInterface
/** /**
* Clean out spurious headers from an Element. Checks things like classnames and link density. * Clean out spurious headers from an Element. Checks things like classnames and link density.
*
* @param \DOMElement $e
*/ */
public function cleanHeaders($e) public function cleanHeaders(\DOMElement $e)
{ {
for ($headerIndex = 1; $headerIndex < 3; ++$headerIndex) { for ($headerIndex = 1; $headerIndex < 3; ++$headerIndex) {
$headers = $e->getElementsByTagName('h' . $headerIndex); $headers = $e->getElementsByTagName('h' . $headerIndex);
@@ -871,7 +860,7 @@ class Readability implements LoggerAwareInterface
} }
$articleTitle = $this->dom->createElement('h1'); $articleTitle = $this->dom->createElement('h1');
$articleTitle->innerHTML = $curTitle; $articleTitle->setInnerHtml($curTitle);
return $articleTitle; return $articleTitle;
} }
@@ -908,10 +897,8 @@ class Readability implements LoggerAwareInterface
/** /**
* Initialize a node with the readability object. Also checks the * Initialize a node with the readability object. Also checks the
* className/id for special names to add to its score. * className/id for special names to add to its score.
*
* @param \DOMElement $node
*/ */
protected function initializeNode($node) protected function initializeNode(\DOMElement $node)
{ {
if (!isset($node->tagName)) { if (!isset($node->tagName)) {
return; return;
@@ -981,9 +968,9 @@ class Readability implements LoggerAwareInterface
* *
* @param \DOMElement $page * @param \DOMElement $page
* *
* @return \DOMElement|bool * @return \DOMElement|false
*/ */
protected function grabArticle($page = null) protected function grabArticle(\DOMElement $page = null)
{ {
if (!$page) { if (!$page) {
$page = $this->dom; $page = $this->dom;
@@ -1009,11 +996,11 @@ class Readability implements LoggerAwareInterface
// Turn divs into P tags where they have been used inappropriately // Turn divs into P tags where they have been used inappropriately
// (as in, where they contain no other block level elements). // (as in, where they contain no other block level elements).
if (0 === strcasecmp($tagName, 'div') || 0 === strcasecmp($tagName, 'article') || 0 === strcasecmp($tagName, 'section')) { if (0 === strcasecmp($tagName, 'div') || 0 === strcasecmp($tagName, 'article') || 0 === strcasecmp($tagName, 'section')) {
if (!preg_match($this->regexps['divToPElements'], $node->innerHTML)) { if (!preg_match($this->regexps['divToPElements'], $node->getInnerHTML())) {
$newNode = $this->dom->createElement('p'); $newNode = $this->dom->createElement('p');
try { try {
$newNode->innerHTML = $node->innerHTML; $newNode->setInnerHtml($node->getInnerHTML());
$node->parentNode->replaceChild($newNode, $node); $node->parentNode->replaceChild($newNode, $node);
--$nodeIndex; --$nodeIndex;
@@ -1040,7 +1027,7 @@ class Readability implements LoggerAwareInterface
if (XML_TEXT_NODE === $childNode->nodeType) { if (XML_TEXT_NODE === $childNode->nodeType) {
$p = $this->dom->createElement('p'); $p = $this->dom->createElement('p');
$p->innerHTML = $childNode->nodeValue; $p->setInnerHtml($childNode->nodeValue);
$p->setAttribute('data-readability-styled', 'true'); $p->setAttribute('data-readability-styled', 'true');
$childNode->parentNode->replaceChild($p, $childNode); $childNode->parentNode->replaceChild($p, $childNode);
} }
@@ -1108,7 +1095,7 @@ class Readability implements LoggerAwareInterface
// Add the score to the parent. The grandparent gets half. // Add the score to the parent. The grandparent gets half.
$parentNode->getAttributeNode('readability')->value += $contentScore; $parentNode->getAttributeNode('readability')->value += $contentScore;
if ($grandParentNode) { if ($grandParentNode) {
$grandParentNode->getAttributeNode('readability')->value += $contentScore / self::GRANDPARENT_SCORE_DIVISOR; $grandParentNode->getAttributeNode('readability')->value += round($contentScore / self::GRANDPARENT_SCORE_DIVISOR);
} }
} }
@@ -1118,7 +1105,6 @@ class Readability implements LoggerAwareInterface
*/ */
if ($this->flagIsActive(self::FLAG_STRIP_UNLIKELYS) && $xpath) { if ($this->flagIsActive(self::FLAG_STRIP_UNLIKELYS) && $xpath) {
$candidates = $xpath->query('.//*[(self::footer and count(//footer)<2) or (self::aside and count(//aside)<2)]', $page->documentElement); $candidates = $xpath->query('.//*[(self::footer and count(//footer)<2) or (self::aside and count(//aside)<2)]', $page->documentElement);
$node = null;
for ($c = $candidates->length - 1; $c >= 0; --$c) { for ($c = $candidates->length - 1; $c >= 0; --$c) {
$node = $candidates->item($c); $node = $candidates->item($c);
@@ -1130,7 +1116,6 @@ class Readability implements LoggerAwareInterface
} }
$candidates = $xpath->query('.//*[not(self::body) and (@class or @id or @style) and ((number(@readability) < 40) or not(@readability))]', $page->documentElement); $candidates = $xpath->query('.//*[not(self::body) and (@class or @id or @style) and ((number(@readability) < 40) or not(@readability))]', $page->documentElement);
$node = null;
for ($c = $candidates->length - 1; $c >= 0; --$c) { for ($c = $candidates->length - 1; $c >= 0; --$c) {
$node = $candidates->item($c); $node = $candidates->item($c);
@@ -1190,14 +1175,14 @@ class Readability implements LoggerAwareInterface
$this->logger->debug('The page has no body!'); $this->logger->debug('The page has no body!');
} else { } else {
$this->logger->debug('Setting body to a raw HTML of original page!'); $this->logger->debug('Setting body to a raw HTML of original page!');
$topCandidate->innerHTML = $page->documentElement->innerHTML; $topCandidate->setInnerHtml($page->documentElement->getInnerHTML());
$page->documentElement->innerHTML = ''; $page->documentElement->setInnerHtml('');
$this->reinitBody(); $this->reinitBody();
$page->documentElement->appendChild($topCandidate); $page->documentElement->appendChild($topCandidate);
} }
} else { } else {
$topCandidate->innerHTML = $page->innerHTML; $topCandidate->setInnerHtml($page->getInnerHTML());
$page->innerHTML = ''; $page->setInnerHtml('');
$page->appendChild($topCandidate); $page->appendChild($topCandidate);
} }
@@ -1229,8 +1214,8 @@ class Readability implements LoggerAwareInterface
$siblingScoreThreshold = max(10, ((int) $topCandidate->getAttribute('readability')) * 0.2); $siblingScoreThreshold = max(10, ((int) $topCandidate->getAttribute('readability')) * 0.2);
$siblingNodes = $topCandidate->parentNode->childNodes; $siblingNodes = $topCandidate->parentNode->childNodes;
if (!isset($siblingNodes)) { if (null === $siblingNodes) {
$siblingNodes = new stdClass(); $siblingNodes = new \stdClass();
$siblingNodes->length = 0; $siblingNodes->length = 0;
} }
@@ -1276,7 +1261,7 @@ class Readability implements LoggerAwareInterface
try { try {
$nodeToAppend->setAttribute('alt', $siblingNodeName); $nodeToAppend->setAttribute('alt', $siblingNodeName);
$nodeToAppend->innerHTML = $siblingNode->innerHTML; $nodeToAppend->setInnerHtml($siblingNode->getInnerHTML());
} catch (\Exception $e) { } catch (\Exception $e) {
$this->logger->debug('Could not alter siblingNode "' . $siblingNodeName . '" to "div", reverting to original.'); $this->logger->debug('Could not alter siblingNode "' . $siblingNodeName . '" to "div", reverting to original.');
$nodeToAppend = $siblingNode; $nodeToAppend = $siblingNode;
@@ -1339,12 +1324,11 @@ class Readability implements LoggerAwareInterface
* Get an element weight by attribute. * Get an element weight by attribute.
* Uses regular expressions to tell if this element looks good or bad. * Uses regular expressions to tell if this element looks good or bad.
* *
* @param \DOMElement $element
* @param string $attribute * @param string $attribute
* *
* @return int * @return int
*/ */
protected function weightAttribute($element, $attribute) protected function weightAttribute(\DOMElement $element, $attribute)
{ {
if (!$element->hasAttribute($attribute)) { if (!$element->hasAttribute($attribute)) {
return 0; return 0;
@@ -1379,7 +1363,7 @@ class Readability implements LoggerAwareInterface
{ {
if (!isset($this->body->childNodes)) { if (!isset($this->body->childNodes)) {
$this->body = $this->dom->createElement('body'); $this->body = $this->dom->createElement('body');
$this->body->innerHTML = $this->bodyCache; $this->body->setInnerHtml($this->bodyCache);
} }
} }
@@ -1435,17 +1419,16 @@ class Readability implements LoggerAwareInterface
$this->html = mb_convert_encoding($this->html, 'HTML-ENTITIES', 'UTF-8'); $this->html = mb_convert_encoding($this->html, 'HTML-ENTITIES', 'UTF-8');
if (!('html5lib' === $this->parser && ($this->dom = Parser::parse($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); libxml_use_internal_errors(true);
$this->dom = new \DOMDocument(); $this->dom = new \DOMDocument();
$this->dom->preserveWhiteSpace = false; $this->dom->preserveWhiteSpace = false;
if (\PHP_VERSION_ID >= 50400) {
$this->dom->loadHTML($this->html, LIBXML_NOBLANKS | LIBXML_COMPACT | LIBXML_NOERROR); $this->dom->loadHTML($this->html, LIBXML_NOBLANKS | LIBXML_COMPACT | LIBXML_NOERROR);
} else {
$this->dom->loadHTML($this->html);
}
libxml_use_internal_errors(false); libxml_use_internal_errors(false);
} }
+67 -67
View File
@@ -73,8 +73,8 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$this->assertFalse($res); $this->assertFalse($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertEmpty($readability->getTitle()->innerHTML); $this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('Sorry, Readability was unable to parse this page for content.', $readability->getContent()->innerHTML); $this->assertContains('Sorry, Readability was unable to parse this page for content.', $readability->getContent()->getInnerHtml());
} }
public function testInitP() public function testInitP()
@@ -85,9 +85,9 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($res); $this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertContains('<div readability=', $readability->getContent()->innerHTML); $this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
$this->assertEmpty($readability->getTitle()->innerHTML); $this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is the awesome content :)', $readability->getContent()->innerHTML); $this->assertContains('This is the awesome content :)', $readability->getContent()->getInnerHtml());
} }
public function testInitDivP() public function testInitDivP()
@@ -98,9 +98,9 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($res); $this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertContains('<div readability=', $readability->getContent()->innerHTML); $this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
$this->assertEmpty($readability->getTitle()->innerHTML); $this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is the awesome content :)', $readability->getContent()->innerHTML); $this->assertContains('This is the awesome content :)', $readability->getContent()->getInnerHtml());
} }
public function testInitDiv() public function testInitDiv()
@@ -112,9 +112,9 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($res); $this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertContains('<div readability=', $readability->getContent()->innerHTML); $this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
$this->assertEmpty($readability->getTitle()->innerHTML); $this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is the awesome content :)', $readability->getContent()->innerHTML); $this->assertContains('This is the awesome content :)', $readability->getContent()->getInnerHtml());
} }
public function testWithFootnotes() public function testWithFootnotes()
@@ -127,11 +127,11 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($res); $this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertContains('<div readability=', $readability->getContent()->innerHTML); $this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
$this->assertEmpty($readability->getTitle()->innerHTML); $this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML); $this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
$this->assertContains('readabilityFootnoteLink', $readability->getContent()->innerHTML); $this->assertContains('readabilityFootnoteLink', $readability->getContent()->getInnerHtml());
$this->assertContains('readabilityLink-3', $readability->getContent()->innerHTML); $this->assertContains('readabilityLink-3', $readability->getContent()->getInnerHtml());
} }
public function testStandardClean() public function testStandardClean()
@@ -144,11 +144,11 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($res); $this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertContains('<div readability=', $readability->getContent()->innerHTML); $this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
$this->assertEmpty($readability->getTitle()->innerHTML); $this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML); $this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
$this->assertContains('will NOT be removed', $readability->getContent()->innerHTML); $this->assertContains('will NOT be removed', $readability->getContent()->getInnerHtml());
$this->assertNotContains('<h2>', $readability->getContent()->innerHTML); $this->assertNotContains('<h2>', $readability->getContent()->getInnerHtml());
} }
public function testWithIframe() public function testWithIframe()
@@ -160,10 +160,10 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($res); $this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertContains('<div readability=', $readability->getContent()->innerHTML); $this->assertContains('<div readability=', $readability->getContent()->getInnerHtml());
$this->assertEmpty($readability->getTitle()->innerHTML); $this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML); $this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
$this->assertContains('nofollow', $readability->getContent()->innerHTML); $this->assertContains('nofollow', $readability->getContent()->getInnerHtml());
} }
public function testWithArticle() public function testWithArticle()
@@ -175,10 +175,10 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($res); $this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertContains('alt="article"', $readability->getContent()->innerHTML); $this->assertContains('alt="article"', $readability->getContent()->getInnerHtml());
$this->assertEmpty($readability->getTitle()->innerHTML); $this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML); $this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
$this->assertContains('nofollow', $readability->getContent()->innerHTML); $this->assertContains('nofollow', $readability->getContent()->getInnerHtml());
} }
public function testWithAside() public function testWithAside()
@@ -190,10 +190,10 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($res); $this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertEmpty($readability->getTitle()->innerHTML); $this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML); $this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
$this->assertNotContains('<aside>', $readability->getContent()->innerHTML); $this->assertNotContains('<aside>', $readability->getContent()->getInnerHtml());
$this->assertContains('<footer readability="4"/>', $readability->getContent()->innerHTML); $this->assertContains('<footer readability="5"/>', $readability->getContent()->getInnerHtml());
} }
public function testWithClasses() public function testWithClasses()
@@ -205,10 +205,10 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($res); $this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertContains('alt="article"', $readability->getContent()->innerHTML); $this->assertContains('alt="article"', $readability->getContent()->getInnerHtml());
$this->assertEmpty($readability->getTitle()->innerHTML); $this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML); $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()->innerHTML); $this->assertNotContains('This text should be removed', $readability->getContent()->getInnerHtml());
} }
public function testWithClassesWithoutLightClean() public function testWithClassesWithoutLightClean()
@@ -221,10 +221,10 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($res); $this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertContains('alt="article"', $readability->getContent()->innerHTML); $this->assertContains('alt="article"', $readability->getContent()->getInnerHtml());
$this->assertEmpty($readability->getTitle()->innerHTML); $this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML); $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()->innerHTML); $this->assertNotContains('This text should be removed', $readability->getContent()->getInnerHtml());
} }
public function testWithTd() public function testWithTd()
@@ -236,8 +236,8 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($res); $this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertEmpty($readability->getTitle()->innerHTML); $this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML); $this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->getInnerHtml());
} }
public function testWithSameClasses() public function testWithSameClasses()
@@ -249,9 +249,9 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($res); $this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertEmpty($readability->getTitle()->innerHTML); $this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML); $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()->innerHTML); $this->assertContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
} }
public function testWithScript() public function testWithScript()
@@ -263,9 +263,9 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($res); $this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertEmpty($readability->getTitle()->innerHTML); $this->assertEmpty($readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML); $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()->innerHTML); $this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
} }
public function testTitle() public function testTitle()
@@ -277,9 +277,9 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($res); $this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertEquals('this is my title', $readability->getTitle()->innerHTML); $this->assertEquals('this is my title', $readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML); $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()->innerHTML); $this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
} }
public function testTitleWithDash() public function testTitleWithDash()
@@ -291,9 +291,9 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($res); $this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertEquals('title2 - title3', $readability->getTitle()->innerHTML); $this->assertEquals('title2 - title3', $readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML); $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()->innerHTML); $this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
} }
public function testTitleWithDoubleDot() public function testTitleWithDoubleDot()
@@ -305,9 +305,9 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($res); $this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertEquals('title2 : title3', $readability->getTitle()->innerHTML); $this->assertEquals('title2 : title3', $readability->getTitle()->getInnerHtml());
$this->assertContains('This is an awesome text with some links, here there are', $readability->getContent()->innerHTML); $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()->innerHTML); $this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
} }
public function testTitleTooShortUseH1() public function testTitleTooShortUseH1()
@@ -319,9 +319,9 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($res); $this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle());
$this->assertEquals('this is my h1 title !', $readability->getTitle()->innerHTML); $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()->innerHTML); $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()->innerHTML); $this->assertNotContains('This text is also an awesome text and you should know that', $readability->getContent()->getInnerHtml());
} }
// dummy function to be used to the next test // dummy function to be used to the next test
@@ -369,8 +369,8 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$this->assertTrue($res); $this->assertTrue($res);
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent()); $this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getContent());
$this->assertInstanceOf('Readability\JSLikeHTMLElement', $readability->getTitle()); $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()->innerHTML); $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()->innerHTML); $this->assertContains('3D Touch', $readability->getTitle()->getInnerHtml());
} }
/** /**
@@ -440,7 +440,7 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$res = $readability->init(); $res = $readability->init();
$this->assertTrue($res); $this->assertTrue($res);
$this->assertContains('This the awesome content :)', $readability->getContent()->innerHTML); $this->assertContains('This the awesome content :)', $readability->getContent()->getInnerHtml());
} }
public function testPreFilters() public function testPreFilters()
@@ -453,7 +453,7 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$res = $readability->init(); $res = $readability->init();
$this->assertTrue($res); $this->assertTrue($res);
$this->assertContains('This the awesome and WONDERFUL content :)', $readability->getContent()->innerHTML); $this->assertContains('This the awesome and WONDERFUL content :)', $readability->getContent()->getInnerHtml());
} }
public function testChildNodeGoneNull() public function testChildNodeGoneNull()
@@ -479,8 +479,8 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
$res = $readability->init(); $res = $readability->init();
$this->assertTrue($res); $this->assertTrue($res);
$this->assertContains('<sup id="fnref1:fnfeed_2"><a href="#fn:fnfeed_2" class="footnote-ref">2</a></sup>', $readability->getContent()->innerHTML); $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()->innerHTML); $this->assertContains('<a href="#fnref1:fnfeed_2" rev="footnote"', $readability->getContent()->getInnerHtml());
} }
private function getReadability($html, $url = null, $parser = 'libxml', $useTidy = true) private function getReadability($html, $url = null, $parser = 'libxml', $useTidy = true)