Skip to content
2 changes: 0 additions & 2 deletions .php-cs-fixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
'concat_space' => ['spacing' => 'one'],
// Pulled in by @Symfony:risky but we still support PHP 7.4
'modernize_strpos' => false,
// Pulled in by @Symfony, we cannot add property types until we bump PHP to ≥ 7.4
'no_null_property_initialization' => false,
])
->setFinder($finder)
;
2 changes: 1 addition & 1 deletion phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
parameters:
level: 1
level: 5
paths:
- src
- tests
Expand Down
100 changes: 31 additions & 69 deletions src/JSLikeHTMLElement.php
Original file line number Diff line number Diff line change
@@ -1,57 +1,43 @@
<?php

declare(strict_types=1);

// SPDX-FileCopyrightText: 2011 Keyvan Minoukadeh - http://www.keyvan.net - [email protected]
// SPDX-License-Identifier: Apache-2.0

namespace Readability;

/**
* JavaScript-like HTML DOM Element.
* Wrapper for DOMElement adding methods for accessing string representation of inner HTML contents.
*
* This class extends PHP's DOMElement to allow
* users to get and set the innerHTML property of
* HTML elements in the same way it's done in
* JavaScript.
* Inspired by JavaScript innerHTML property.
* https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML
*
* Example usage:
* require_once 'JSLikeHTMLElement.php';
* header('Content-Type: text/plain');
* $doc = new DOMDocument();
* $doc->registerNodeClass('DOMElement', 'JSLikeHTMLElement');
* $doc->loadHTML('<div><p>Para 1</p><p>Para 2</p></div>');
* $elem = $doc->getElementsByTagName('div')->item(0);
*
* // print innerHTML
* echo $elem->innerHTML; // prints '<p>Para 1</p><p>Para 2</p>'
* echo "\n\n";
*
* // set innerHTML
* $elem->innerHTML = '<a href="http://fivefilters.org">FiveFilters.org</a>';
* echo $elem->innerHTML; // prints '<a href="http://fivefilters.org">FiveFilters.org</a>'
* echo "\n\n";
* ```php
* $doc = new DOMDocument();
* $doc->loadHTML('<div><p>Para 1</p><p>Para 2</p></div>');
* $elem = $doc->getElementsByTagName('div')->item(0);
*
* // print document (with our changes)
* echo $doc->saveXML();
* // Get inner HTML
* assert($elem->getInnerHtml() === '<p>Para 1</p><p>Para 2</p>');
*
* @author Keyvan Minoukadeh - http://www.keyvan.net - [email protected]
* // Set inner HTML
* $elem->setInnerHtml('<a href="http://fivefilters.org">FiveFilters.org</a>');
* assert($elem->getInnerHtml() === '<a href="http://fivefilters.org">FiveFilters.org</a>');
*
* @see http://fivefilters.org (the project this was written for)
* // print document (with our changes)
* echo $doc->saveXML();
* ```
*/
class JSLikeHTMLElement extends \DOMElement
final class JSLikeHTMLElement extends \DOMElement
{
/**
* Used for setting innerHTML like it's done in JavaScript:.
*
* ```php
* $div->innerHTML = '<h2>Chapter 2</h2><p>The story begins...</p>';
* ```
* Sets inner HTML.
*/
public function __set($name, $value)
public function setInnerHtml(string $value): void
{
if ('innerHTML' !== $name) {
$trace = debug_backtrace();
trigger_error('Undefined property via __set(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], \E_USER_NOTICE);

return;
}

// first, empty the element
if (isset($this->childNodes)) {
for ($x = $this->childNodes->length - 1; $x >= 0; --$x) {
Expand Down Expand Up @@ -81,7 +67,7 @@ public function __set($name, $value)
$f = new \DOMDocument();

// Using <htmlfragment> will generate a warning, but so will bad HTML
// (and by this point, bad HTML is what we've got).
// (and by element point, bad HTML is what we've got).
// We use it (and suppress the warning) because an HTML fragment will
// be wrapped around <html><body> tags which we don't really want to keep.
// Note: despite the warning, if loadHTML succeeds it will return true.
Expand All @@ -102,42 +88,18 @@ public function __set($name, $value)
}

/**
* Used for getting innerHTML like it's done in JavaScript:.
*
* ```php
* $string = $div->innerHTML;
* ```
* Gets inner HTML.
*/
public function __get($name)
public function getInnerHtml(): string
{
if ('innerHTML' === $name) {
$inner = '';
$inner = '';

if (isset($this->childNodes)) {
foreach ($this->childNodes as $child) {
$inner .= $this->ownerDocument->saveXML($child);
}
if (isset($this->childNodes)) {
foreach ($this->childNodes as $child) {
$inner .= $this->ownerDocument->saveXML($child);
}

return $inner;
}

$trace = debug_backtrace();
trigger_error('Undefined property via __get(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], \E_USER_NOTICE);
}

public function __toString()
{
return '[' . $this->tagName . ']';
}

public function getInnerHtml()
{
return $this->__get('innerHTML');
}

public function setInnerHtml($value)
{
return $this->__set('innerHTML', $value);
return $inner;
}
}
Loading