From 6f4404030b043e5278ae87ec16887f09c1c600a5 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Fri, 31 Mar 2023 05:25:40 +0200 Subject: [PATCH 01/14] Do not use `mb_convert_encoding` with `HTML-ENTITIES` as target encoding This is deprecated since PHP 8.2: Deprecated: mb_convert_encoding(): Handling HTML entities via mbstring is deprecated; use htmlspecialchars, htmlentities, or mb_encode_numericentity/mb_decode_numericentity instead It was used because `DOMDocument`, which uses libxml2 internally, will parse the HTML as ISO-8859-1, unless the document contains an XML encoding declaration or HTML meta tag setting character set. Since first such element wins, putting the `meta[charset]` up front will ensure the parser uses the correct encoding, even if the document contains incorrect meta tag (e.g. when the document is converted to UTF-8 without also updating the metadata by the software passing it to Readability). https://stackoverflow.com/a/39148511/160386 (cherry picked from commit f14428e4c0fa34b28f6b8a7696e62790bcde363e) --- src/JSLikeHTMLElement.php | 3 +-- src/Readability.php | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/JSLikeHTMLElement.php b/src/JSLikeHTMLElement.php index 3f382e1..bb5c9ea 100644 --- a/src/JSLikeHTMLElement.php +++ b/src/JSLikeHTMLElement.php @@ -79,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 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 tags which we don't really want to keep. // Note: despite the warning, if loadHTML succeeds it will return true. - $result = $f->loadHTML('' . $value . ''); + $result = $f->loadHTML('' . $value . ''); if ($result) { $import = $f->getElementsByTagName('htmlfragment')->item(0); diff --git a/src/Readability.php b/src/Readability.php index 8c1e62b..08963c0 100644 --- a/src/Readability.php +++ b/src/Readability.php @@ -1430,7 +1430,7 @@ class Readability implements LoggerAwareInterface unset($tidy); } - $this->html = mb_convert_encoding($this->html, 'HTML-ENTITIES', 'UTF-8'); + $this->html = '' . (string) $this->html; if ('html5lib' === $this->parser || 'html5' === $this->parser) { $this->dom = (new HTML5())->loadHTML($this->html); From f4550ccc468e658c83583cbd53536e7665aa950b Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sun, 23 Feb 2025 01:24:56 +0100 Subject: [PATCH 02/14] ci: Enable on 1.x branch --- .github/workflows/coding-standards.yml | 2 ++ .github/workflows/continuous-integration.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index cd666ae..82853b8 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -4,9 +4,11 @@ on: pull_request: branches: - master + - 1.x push: branches: - master + - 1.x env: SYMFONY_PHPUNIT_VERSION: 7.5 diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 1424248..2538995 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -4,9 +4,11 @@ on: pull_request: branches: - "master" + - "1.x" push: branches: - "master" + - "1.x" env: fail-fast: true From 2112dd95d143c3d18fa6fa9eddbddedde8fcb3f5 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sat, 16 Mar 2024 16:00:54 +0100 Subject: [PATCH 03/14] ci: Update actions Mostly just of nodejs bump: - https://github.com/actions/checkout/releases/tag/v4.0.0 - https://github.com/ramsey/composer-install/releases/tag/3.0.0 (cherry picked from commit 7f4c6cfcbd549f43d35d388e93092b78b248f768, resolving conflicts with previous bump in 82083c872b879aea8af05d7d4937d1997dcc4347) --- .github/workflows/coding-standards.yml | 6 +++--- .github/workflows/continuous-integration.yml | 18 +++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 82853b8..0778a21 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -16,7 +16,7 @@ env: jobs: coding-standards: name: "CS Fixer & PHPStan" - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" strategy: matrix: @@ -25,7 +25,7 @@ jobs: steps: - name: "Checkout" - uses: "actions/checkout@v2" + uses: "actions/checkout@v4" - name: "Install PHP" uses: "shivammathur/setup-php@v2" @@ -41,7 +41,7 @@ jobs: run: "composer require phpstan/phpstan phpstan/phpstan-phpunit --dev --no-progress --no-suggest" - name: "Install dependencies with Composer" - uses: "ramsey/composer-install@v1" + uses: "ramsey/composer-install@v3" with: composer-options: "--optimize-autoloader --prefer-dist" diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 2538995..a190059 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -16,7 +16,7 @@ env: jobs: phpunit: name: "PHPUnit (PHP ${{ matrix.php }})" - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" strategy: matrix: @@ -31,7 +31,7 @@ jobs: steps: - name: "Checkout" - uses: "actions/checkout@v2" + uses: "actions/checkout@v4" with: fetch-depth: 2 @@ -56,7 +56,7 @@ jobs: run: "composer remove friendsofphp/php-cs-fixer --dev --no-progress --no-update" - name: "Install dependencies with Composer" - uses: "ramsey/composer-install@v1" + uses: "ramsey/composer-install@v3" with: composer-options: "--optimize-autoloader --prefer-dist" @@ -68,7 +68,7 @@ jobs: phpunit-coverage: name: "PHPUnit coverage (PHP ${{ matrix.php }})" - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" strategy: matrix: @@ -77,7 +77,7 @@ jobs: steps: - name: "Checkout" - uses: "actions/checkout@v2" + uses: "actions/checkout@v4" with: fetch-depth: 2 @@ -96,7 +96,7 @@ jobs: run: "composer remove friendsofphp/php-cs-fixer --dev --no-progress --no-update" - name: "Install dependencies with Composer" - uses: "ramsey/composer-install@v1" + uses: "ramsey/composer-install@v3" with: composer-options: "--optimize-autoloader --prefer-dist" @@ -121,7 +121,7 @@ jobs: phpunit-lowest: name: "PHPUnit lowest deps (PHP ${{ matrix.php }})" - runs-on: "ubuntu-20.04" + runs-on: "ubuntu-22.04" strategy: matrix: @@ -130,7 +130,7 @@ jobs: steps: - name: "Checkout" - uses: "actions/checkout@v2" + uses: "actions/checkout@v4" with: fetch-depth: 2 @@ -149,7 +149,7 @@ jobs: run: "composer remove friendsofphp/php-cs-fixer --dev --no-progress --no-update" - name: "Install dependencies with Composer" - uses: "ramsey/composer-install@v1" + uses: "ramsey/composer-install@v3" with: composer-options: "--optimize-autoloader --prefer-dist" dependency-versions: "lowest" From baa0a78ab60daaceaeb7ea673105683e3b106977 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sun, 23 Feb 2025 01:33:55 +0100 Subject: [PATCH 04/14] ci: Switch to composer v2 Composer v1 is not compatible with PHP 8.4. master switched in 66215a6c809ba63a59b5d598c4ddd7842bb3d52b. --- .github/workflows/continuous-integration.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index a190059..602db34 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -40,7 +40,7 @@ jobs: with: php-version: "${{ matrix.php }}" coverage: "none" - tools: composer:v1 + tools: composer:v2 extensions: tidy ini-values: "date.timezone=Europe/Paris" env: @@ -86,7 +86,7 @@ jobs: with: php-version: "${{ matrix.php }}" coverage: "xdebug" - tools: composer:v1 + tools: composer:v2 extensions: tidy ini-values: "date.timezone=Europe/Paris" env: @@ -139,7 +139,7 @@ jobs: with: php-version: "${{ matrix.php }}" coverage: "none" - tools: composer:v1 + tools: composer:v2 extensions: tidy ini-values: "date.timezone=Europe/Paris" env: @@ -163,7 +163,7 @@ jobs: SYMFONY_PHPUNIT_VERSION: 7.5 phpunit-composerv2: - name: "PHPUnit with Composer v2 (PHP ${{ matrix.php }})" + name: "PHPUnit with Composer v1 (PHP ${{ matrix.php }})" runs-on: "ubuntu-20.04" strategy: @@ -182,7 +182,7 @@ jobs: with: php-version: "${{ matrix.php }}" coverage: "none" - tools: composer:v2 + tools: composer:v1 extensions: tidy ini-values: "date.timezone=Europe/Paris" env: From 4adb0a96aa034d2887c9692e986b77acb27f8501 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Fri, 31 Mar 2023 02:54:59 +0200 Subject: [PATCH 05/14] PHPStan: Use stable PHPUnit path phpunit-bridge will create a symlink. (cherry picked from commit 2c6c6d59874c16e199a4b810060e7cabaf5371c3) --- phpstan.neon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpstan.neon b/phpstan.neon index 7c1f51c..7e5d5d8 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -6,7 +6,7 @@ parameters: # https://github.com/phpstan/phpstan/issues/694#issuecomment-350724288 bootstrapFiles: - - vendor/bin/.phpunit/phpunit-7.5-0/vendor/autoload.php + - vendor/bin/.phpunit/phpunit/vendor/autoload.php includes: - vendor/phpstan/phpstan-phpunit/extension.neon From ae87c8ca8c8d5ebb13f63eddc20e282fc501169b Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sun, 23 Feb 2025 01:37:24 +0100 Subject: [PATCH 06/14] ci: Do not force PHPUnit version It should no longer be necessary and PHPUnit 7.5 is not compatible with PHP 8.4. master did that in 66215a6c809ba63a59b5d598c4ddd7842bb3d52b. --- .github/workflows/continuous-integration.yml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 602db34..8515ee8 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -46,12 +46,6 @@ jobs: 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" @@ -105,8 +99,6 @@ jobs: - 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" @@ -159,8 +151,6 @@ jobs: - name: "Run PHPUnit" run: "php vendor/bin/simple-phpunit -v" - env: - SYMFONY_PHPUNIT_VERSION: 7.5 phpunit-composerv2: name: "PHPUnit with Composer v1 (PHP ${{ matrix.php }})" @@ -201,5 +191,3 @@ jobs: - name: "Run PHPUnit" run: "php vendor/bin/simple-phpunit -v" - env: - SYMFONY_PHPUNIT_VERSION: 7.5 From 66864279fdb62e6fb380373e6f0c1231984622a8 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Fri, 31 Mar 2023 02:54:25 +0200 Subject: [PATCH 07/14] composer: Add scripts for development (cherry picked from commit c5407ec07c9ee5fbc062cf07434e34285096f6e6, except for rector) --- composer.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/composer.json b/composer.json index d32d576..508105e 100644 --- a/composer.json +++ b/composer.json @@ -42,5 +42,10 @@ }, "autoload-dev": { "psr-4": { "Tests\\Readability\\": "tests/" } + }, + "scripts": { + "fix": "php-cs-fixer fix --verbose --diff", + "phpstan": "phpstan analyze --memory-limit 512M", + "test": "simple-phpunit -v" } } From 8421ed5962ac03ad613b2d55348f116b67dc8f83 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sat, 16 Mar 2024 16:42:54 +0100 Subject: [PATCH 08/14] Update coding style for upcoming PHP-CS-Fixer changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Once we bump minimum PHP version, we will get newer PHP-CS-Fixer, which will try to apply this cleanups. (partially cherry picked from commit 648d8c605b21c54fbcd395354181ed1b044cc664) Though avoid disabling `modernize_strpos` since it was only introduced in PHP-CS-Fixer 3.2.0: https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/commit/2ca22a27c4ffb8cc46f20e7110b1dfcbb0c8c47c Also had to disable `visibility_required` for constants since those require PHP ≥ 7.1: https://cs.symfony.com/doc/rules/class_notation/visibility_required.html And remove type hint from `grabArticle` since implicitly nullable types were deprecated in PHP 8.4: https://wiki.php.net/rfc/deprecate-implicitly-nullable-types But we cannot use explicitly nullable types, which require PHP ≥ 7.1: https://wiki.php.net/rfc/nullable_types Also switch code blocks to Markdown syntax to work around `phpdoc_separation`, ApiGen uses Markdown these days anyway. (partially cherry picked from commit 9ed89bde92764babdde6d10b16fffcb225944bcc) --- .php-cs-fixer.php | 4 ++++ src/JSLikeHTMLElement.php | 8 ++++---- src/Readability.php | 30 ++++++++++++++++-------------- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index 19cd18d..93f51fe 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -26,6 +26,10 @@ return (new PhpCsFixer\Config()) 'strict_comparison' => true, 'strict_param' => true, 'concat_space' => ['spacing' => 'one'], + // Pulled in by @Symfony, we cannot add property types until we bump PHP to ≥ 7.4 + 'no_null_property_initialization' => false, + // Pulled in by @Symfony with `const` but const visibility requires PHP ≥ 7.1 + 'visibility_required' => ['elements' => ['method', 'property']], ]) ->setFinder($finder) ; diff --git a/src/JSLikeHTMLElement.php b/src/JSLikeHTMLElement.php index bb5c9ea..18116a6 100644 --- a/src/JSLikeHTMLElement.php +++ b/src/JSLikeHTMLElement.php @@ -39,9 +39,9 @@ class JSLikeHTMLElement extends \DOMElement /** * Used for setting innerHTML like it's done in JavaScript:. * - * @code + * ```php * $div->innerHTML = '

Chapter 2

The story begins...

'; - * @endcode + * ``` */ public function __set($name, $value) { @@ -104,9 +104,9 @@ class JSLikeHTMLElement extends \DOMElement /** * Used for getting innerHTML like it's done in JavaScript:. * - * @code + * ```php * $string = $div->innerHTML; - * @endcode + * ``` */ public function __get($name) { diff --git a/src/Readability.php b/src/Readability.php index 08963c0..1d2d2f5 100644 --- a/src/Readability.php +++ b/src/Readability.php @@ -144,7 +144,7 @@ class Readability implements LoggerAwareInterface // HACK: replace linebreaks plus br's with p's '!(]*>[ \r\n\s]*){2,}!i' => '

', // replace noscripts - //'!!is' => '', + // '!!is' => '', // replace fonts to spans '!<(/?)font[^>]*>!is' => '<\\1span>', ]; @@ -155,8 +155,8 @@ class Readability implements LoggerAwareInterface // replace empty tags that break layouts '!<(?:a|div|p|figure)[^>]+/>!is' => '', // remove all attributes on text tags - //'!<(\s*/?\s*(?:blockquote|br|hr|code|div|article|span|footer|aside|p|pre|dl|li|ul|ol)) [^>]+>!is' => "<\\1>", - //single newlines cleanup + // '!<(\s*/?\s*(?:blockquote|br|hr|code|div|article|span|footer|aside|p|pre|dl|li|ul|ol)) [^>]+>!is' => "<\\1>", + // single newlines cleanup "/\n+/" => "\n", // modern web... '!]*>\s* 'setAttribute('style', 'color: inherit; text-decoration: none;'); $articleLink->setAttribute('name', 'readabilityLink-' . $linkCount); $footnote->setInnerHtml('^ '); - $footnoteLink->setInnerHtml(('' !== $footnoteLink->getAttribute('title') ? $footnoteLink->getAttribute('title') : $linkText)); + $footnoteLink->setInnerHtml('' !== $footnoteLink->getAttribute('title') ? $footnoteLink->getAttribute('title') : $linkText); $footnoteLink->setAttribute('name', 'readabilityFootnoteLink-' . $linkCount); $footnote->appendChild($footnoteLink); @@ -796,7 +796,7 @@ class Readability implements LoggerAwareInterface */ public function addFlag($flag) { - $this->flags = $this->flags | $flag; + $this->flags |= $flag; } /** @@ -806,13 +806,14 @@ class Readability implements LoggerAwareInterface */ public function removeFlag($flag) { - $this->flags = $this->flags & ~$flag; + $this->flags &= ~$flag; } /** * Debug. * * @deprecated use $this->logger->debug() instead + * * @codeCoverageIgnore */ protected function dbg($msg) @@ -824,6 +825,7 @@ class Readability implements LoggerAwareInterface * Dump debug info. * * @deprecated since Monolog gather log, we don't need it + * * @codeCoverageIgnore */ protected function dump_dbg() @@ -973,11 +975,11 @@ class Readability implements LoggerAwareInterface * Using a variety of metrics (content score, classname, element types), find the content that is * most likely to be the stuff a user wants to read. Then return it wrapped up in a div. * - * @param \DOMElement $page + * @param ?\DOMElement $page * * @return \DOMElement|false */ - protected function grabArticle(\DOMElement $page = null) + protected function grabArticle($page = null) { if (!$page) { $page = $this->dom; @@ -992,7 +994,7 @@ class Readability implements LoggerAwareInterface $allElements = $page->getElementsByTagName('*'); - for ($nodeIndex = 0; ($node = $allElements->item($nodeIndex)); ++$nodeIndex) { + for ($nodeIndex = 0; $node = $allElements->item($nodeIndex); ++$nodeIndex) { $tagName = $node->tagName; $nodeContent = $node->getInnerHTML(); @@ -1136,9 +1138,9 @@ class Readability implements LoggerAwareInterface // Remove unlikely candidates $unlikelyMatchString = $node->getAttribute('class') . ' ' . $node->getAttribute('id') . ' ' . $node->getAttribute('style'); - if (mb_strlen($unlikelyMatchString) > 3 && // don't process "empty" strings - preg_match($this->regexps['unlikelyCandidates'], $unlikelyMatchString) && - !preg_match($this->regexps['okMaybeItsACandidate'], $unlikelyMatchString) + if (mb_strlen($unlikelyMatchString) > 3 // don't process "empty" strings + && preg_match($this->regexps['unlikelyCandidates'], $unlikelyMatchString) + && !preg_match($this->regexps['okMaybeItsACandidate'], $unlikelyMatchString) ) { $this->logger->debug('Removing unlikely candidate (using conf) ' . $node->getNodePath() . ' by "' . $unlikelyMatchString . '" with readability ' . ($node->hasAttribute('readability') ? (int) $node->getAttributeNode('readability')->value : 0)); $node->parentNode->removeChild($node); @@ -1289,8 +1291,8 @@ class Readability implements LoggerAwareInterface // To ensure a node does not interfere with readability styles, remove its classnames & ids. // Now done via RegExp post_filter. - //$nodeToAppend->removeAttribute('class'); - //$nodeToAppend->removeAttribute('id'); + // $nodeToAppend->removeAttribute('class'); + // $nodeToAppend->removeAttribute('id'); // Append sibling and subtract from our list as appending removes a node. $articleContent->appendChild($nodeToAppend); } From a209429e8b4c66124ef32101f5e0e292f321ac1b Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Fri, 31 Mar 2023 03:19:14 +0200 Subject: [PATCH 09/14] =?UTF-8?q?tests:=20Fix=20=E2=80=9CTHE=20ERROR=20HAN?= =?UTF-8?q?DLER=20HAS=20CHANGED!=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 23f824a1cea9500fe367c9dc1868c0245d00dc98) --- tests/ReadabilityTest.php | 70 ++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/tests/ReadabilityTest.php b/tests/ReadabilityTest.php index a8e8cfb..56f04da 100644 --- a/tests/ReadabilityTest.php +++ b/tests/ReadabilityTest.php @@ -332,28 +332,31 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase public function testAutoClosingIframeNotThrowingException() { - error_reporting(\E_ALL | \E_STRICT); - ini_set('display_errors', true); + $oldErrorReporting = error_reporting(\E_ALL | \E_STRICT); + $oldDisplayErrors = ini_set('display_errors', true); set_error_handler([$this, 'error2Exception'], \E_ALL | \E_STRICT); - $data = ' - - - - - - - - -

-
-
-

3D Touch — будущее мобильных игр

- -
-

Компания Apple представила новую технологию 3D Touch, которая является прямым потомком более ранней версии Force Touch — последняя, напомним, используется сейчас в трекпадах Macbook Pro и Macbook 2015. Теперь управлять устройством стало в разы проще, и Force Touch открывает перед пользователями новые возможности, но при этом 3D Touch — это про другое. Дело в том, что теперь и на мобильных устройствах интерфейс будет постепенно меняться, кардинальные перемены ждут мобильный гейминг, потому что здесь разработчики действительно могут разгуляться.

-

-

Итак, просто представьте себе, что iPhone 6S — это, по большому счету, отличная игровая приставка, которую вы носите с собой, а еще она может выдавать невероятной красоты картинку. Но проблема заключается, пожалуй, в том, что управлять персонажем в играх довольно трудно — он неповоротлив, обладает заторможенной реакцией, а игровой клиент зачастую требует перегруза интерфейса для того, чтобы обеспечить максимально большое количество возможностей. Благодаря трехуровневому нажатию можно избавиться от лишних кнопок и обеспечить более качественный обзор местности, и при этом пользователь будет закрывать пальцами минимальное пространство.

+ try { + $data = ' + + + + + + + + +
+
+
+

3D Touch — будущее мобильных игр

+ +
+

Компания Apple представила новую технологию 3D Touch, которая является прямым потомком более ранней версии Force Touch — последняя, напомним, используется сейчас в трекпадах Macbook Pro и Macbook 2015. Теперь управлять устройством стало в разы проще, и Force Touch открывает перед пользователями новые возможности, но при этом 3D Touch — это про другое. Дело в том, что теперь и на мобильных устройствах интерфейс будет постепенно меняться, кардинальные перемены ждут мобильный гейминг, потому что здесь разработчики действительно могут разгуляться.

+

+

Итак, просто представьте себе, что iPhone 6S — это, по большому счету, отличная игровая приставка, которую вы носите с собой, а еще она может выдавать невероятной красоты картинку. Но проблема заключается, пожалуй, в том, что управлять персонажем в играх довольно трудно — он неповоротлив, обладает заторможенной реакцией, а игровой клиент зачастую требует перегруза интерфейса для того, чтобы обеспечить максимально большое количество возможностей. Благодаря трехуровневому нажатию можно избавиться от лишних кнопок и обеспечить более качественный обзор местности, и при этом пользователь будет закрывать пальцами минимальное пространство.

+
+
@@ -361,16 +364,23 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase '; - $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->assertStringContainsString('', $readability->getContent()->getInnerHtml()); - $this->assertStringContainsString('3D Touch', $readability->getTitle()->getInnerHtml()); + $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->assertStringContainsString('', $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); + } } /** From f5e25f3c9c8406b32510a785647e194ea1b0e43d Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Thu, 10 Oct 2024 01:25:41 +0200 Subject: [PATCH 10/14] Avoid E_STRICT constant It will be deprecated in PHP 8.4 and it is meaningless nowadays anyway: https://wiki.php.net/rfc/deprecations_php_8_4#remove_e_strict_error_level_and_deprecate_e_strict_constant The use of the constant was introduced in 175196d6c2e2a2cc920c5e1720639b770a2edd10. (cherry picked from commit c7b10dcc45b3729d5a2d6469cb2b26495b45edd6) --- tests/ReadabilityTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ReadabilityTest.php b/tests/ReadabilityTest.php index 56f04da..542ae5c 100644 --- a/tests/ReadabilityTest.php +++ b/tests/ReadabilityTest.php @@ -332,9 +332,9 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase public function testAutoClosingIframeNotThrowingException() { - $oldErrorReporting = error_reporting(\E_ALL | \E_STRICT); + $oldErrorReporting = error_reporting(\E_ALL); $oldDisplayErrors = ini_set('display_errors', true); - set_error_handler([$this, 'error2Exception'], \E_ALL | \E_STRICT); + set_error_handler([$this, 'error2Exception']); try { $data = ' From 2ae758555a9bef7508a113d7eb05ef7696b5ffa9 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Thu, 10 Oct 2024 08:42:00 +0200 Subject: [PATCH 11/14] Remove extra set_error_handler callback argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is unused and would cause an error on PHP ≥ 8.0: https://www.php.net/manual/en/function.set-error-handler.php#refsect1-function.set-error-handler-parameters Not sure if the handler is even necessary – it was introduced in 175196d6c2e2a2cc920c5e1720639b770a2edd10 but I did not manage to reproduce the original error (Entity 'nbsp' not defined). It was probably fixed by f2a43b476c039105cd0a4370b35b0244826913fa. (based on commit da755013aadc3745ba5a13e9e77f6463ba959949) --- tests/ReadabilityTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ReadabilityTest.php b/tests/ReadabilityTest.php index 542ae5c..b190a8e 100644 --- a/tests/ReadabilityTest.php +++ b/tests/ReadabilityTest.php @@ -325,7 +325,7 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase } // dummy function to be used to the next test - public function error2Exception($code, $string, $file, $line, $context) + public function error2Exception($code, $string, $file, $line) { throw new \Exception($string, $code); } From 84220bff990361bd5ff6717ccc86f685ac6b66f0 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Thu, 10 Oct 2024 01:06:13 +0200 Subject: [PATCH 12/14] ci: Add PHP 8.1 through 8.4 - 8.1 was introduced in 66215a6c809ba63a59b5d598c4ddd7842bb3d52b - 8.2 and 8.3 was introduced in 9bdd3b6b2eca914aec4a57f7c070e4bea3e428e8 - 8.4 cherry picked from commit 5b9551d1e325f4a7060e1e64ee20bdbfcb632b8f --- .github/workflows/continuous-integration.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 8515ee8..15e0217 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -28,6 +28,10 @@ jobs: - "7.3" - "7.4" - "8.0" + - "8.1" + - "8.2" + - "8.3" + - "8.4" steps: - name: "Checkout" From ae0c20ab18298c059b0f7b89206b340fd7e9ef0e Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sun, 23 Feb 2025 02:25:14 +0100 Subject: [PATCH 13/14] composer: Allow phpunit-bridge 6.0 and 7.0 This is required for PHP 8.4 support. On master this was done in 66215a6c809ba63a59b5d598c4ddd7842bb3d52b and 1ac761d708d3dfee187461feaf9c39667678c965. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 508105e..b3116b7 100644 --- a/composer.json +++ b/composer.json @@ -32,7 +32,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "^2.14", "monolog/monolog": "^1.24|^2.1", - "symfony/phpunit-bridge": "^4.4|^5.3" + "symfony/phpunit-bridge": "^4.4|^5.3|^6.0|^7.0" }, "suggest": { "ext-tidy": "Used to clean up given HTML and to avoid problems with bad HTML structure." From 0bae41248f565e7f1b4ae1487fcf503de40ac8e7 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sun, 23 Feb 2025 02:46:57 +0100 Subject: [PATCH 14/14] phpstan: Use standard config path This allows developer to create their own own config file, e.g. for setting `editorUrl`: https://phpstan.org/user-guide/output-format#opening-file-in-an-editor (cherry picked from commit 1d7cdf3a1250eb970133af5dfa341c12fe2e11b3) --- .gitignore | 1 + phpstan.neon => phpstan.dist.neon | 0 2 files changed, 1 insertion(+) rename phpstan.neon => phpstan.dist.neon (100%) diff --git a/.gitignore b/.gitignore index 160e7cc..6a7bae5 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ coverage/ composer.lock .php_cs.cache .phpunit.result.cache +phpstan.neon diff --git a/phpstan.neon b/phpstan.dist.neon similarity index 100% rename from phpstan.neon rename to phpstan.dist.neon