Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
0.00% |
0 / 13 |
CRAP | |
0.00% |
0 / 38 |
DomSourceRange | |
0.00% |
0 / 1 |
|
0.00% |
0 / 13 |
600 | |
0.00% |
0 / 38 |
__construct | |
0.00% |
0 / 1 |
30 | |
0.00% |
0 / 6 |
|||
innerSubstr | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
innerStart | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
innerEnd | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
innerLength | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
openSubstr | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
closeSubstr | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
stripTags | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 7 |
|||
offset | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 7 |
|||
hasValidTagWidths | |
0.00% |
0 / 1 |
20 | |
0.00% |
0 / 2 |
|||
fromTsr | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
fromArray | |
0.00% |
0 / 1 |
12 | |
0.00% |
0 / 4 |
|||
jsonSerialize | |
0.00% |
0 / 1 |
12 | |
0.00% |
0 / 5 |
<?php | |
declare( strict_types = 1 ); | |
namespace Wikimedia\Parsoid\Core; | |
use Wikimedia\Assert\Assert; | |
use Wikimedia\Parsoid\Tokens\SourceRange; | |
use Wikimedia\Parsoid\Utils\PHPUtils; | |
/** | |
* Represents a DOM source range. That is, for a given DOM tree, gives | |
* the source offset range in the original wikitext for this DOM tree, | |
* as well as the opening and closing tag widths if appropriate. | |
*/ | |
class DomSourceRange extends SourceRange { | |
/** | |
* Opening tag width. | |
* @var ?int | |
*/ | |
public $openWidth; | |
/** | |
* Closing tag width. | |
* @var ?int | |
*/ | |
public $closeWidth; | |
/** | |
* Width of trimmed whitespace between opening tag & first child. | |
* Defaults to zero since for most nodes, there is no ws trimming. | |
* -1 indicates that this information is invalid and should not be used. | |
* @var int | |
*/ | |
public $leadingWS = 0; | |
/** | |
* Width of trimmed whitespace between last child & closing tag. | |
* Defaults to zero since for most nodes, there is no ws trimming. | |
* -1 indicates that this information is invalid and should not be used. | |
* @var int | |
*/ | |
public $trailingWS = 0; | |
/** | |
* Create a new DOM source offset. | |
* @param ?int $start The starting index (UTF-8 byte count, inclusive) | |
* @param ?int $end The ending index (UTF-8 byte count, exclusive) | |
* @param ?int $openWidth The width of the open container tag | |
* @param ?int $closeWidth The width of the close container tag | |
* @param int $leadingWS The width of WS chars between opening tag & first child | |
* @param int $trailingWS The width of WS chars between last child & closing tag | |
*/ | |
public function __construct( | |
?int $start, ?int $end, ?int $openWidth, ?int $closeWidth, | |
int $leadingWS = 0, | |
int $trailingWS = 0 | |
) { | |
parent::__construct( $start, $end ); | |
$this->openWidth = $openWidth; | |
$this->closeWidth = $closeWidth; | |
$this->leadingWS = $leadingWS; | |
$this->trailingWS = $trailingWS; | |
} | |
/** | |
* Return the substring of the given string corresponding to the | |
* inner portion of this range (that is, not including the opening | |
* and closing tag widths). | |
* @param string $str The source text string | |
* @return string | |
*/ | |
public function innerSubstr( string $str ): string { | |
return PHPUtils::safeSubstr( $str, $this->innerStart(), $this->innerLength() ); | |
} | |
/** | |
* Return the "inner start", that is, the start offset plus the open width. | |
* @return int | |
*/ | |
public function innerStart(): int { | |
return $this->start + ( $this->openWidth ?? 0 ); | |
} | |
/** | |
* Return the "inner end", that is, the end offset minus the close width. | |
* @return int | |
*/ | |
public function innerEnd(): int { | |
return $this->end - ( $this->closeWidth ?? 0 ); | |
} | |
/** | |
* Return the length of this source range, excluding the open and close | |
* tag widths. | |
* @return int | |
*/ | |
public function innerLength(): int { | |
return $this->innerEnd() - $this->innerStart(); | |
} | |
/** | |
* Return the substring of the given string corresponding to the | |
* open portion of this range. | |
* @param string $str The source text string | |
* @return string | |
*/ | |
public function openSubstr( string $str ): string { | |
return PHPUtils::safeSubstr( $str, $this->start, $this->openWidth ); | |
} | |
/** | |
* Return the substring of the given string corresponding to the | |
* close portion of this range. | |
* @param string $str The source text string | |
* @return string | |
*/ | |
public function closeSubstr( string $str ): string { | |
return PHPUtils::safeSubstr( $str, $this->innerEnd(), $this->closeWidth ); | |
} | |
/** | |
* Strip the tag open and close from the beginning and end of the | |
* provided string. This is similar to `DomSourceRange::innerSubstr()` | |
* but we assume that the string before `$this->start` and after | |
* `$this->end` has already been removed. (That is, that the input | |
* is `$this->substr( $originalWikitextSource )`.) | |
* | |
* @param string $src The source text string from `$this->start` | |
* (inclusive) to `$this->end` (exclusive). | |
* @return string | |
*/ | |
public function stripTags( string $src ): string { | |
Assert::invariant( | |
strlen( $src ) === $this->length(), | |
"Input string not the expected length" | |
); | |
return PHPUtils::safeSubstr( | |
$src, | |
$this->openWidth, | |
-$this->closeWidth | |
); | |
} | |
/** | |
* Return a new DOM source range shifted by $amount. | |
* @param int $amount The amount to shift by | |
* @return DomSourceRange | |
*/ | |
public function offset( int $amount ): DomSourceRange { | |
return new DomSourceRange( | |
$this->start + $amount, | |
$this->end + $amount, | |
$this->openWidth, | |
$this->closeWidth, | |
$this->leadingWS, | |
$this->trailingWS | |
); | |
} | |
/** | |
* @return bool True if the tag widths are valid. | |
*/ | |
public function hasValidTagWidths(): bool { | |
return $this->openWidth !== null && $this->closeWidth !== null && | |
$this->openWidth >= 0 && $this->closeWidth >= 0; | |
} | |
/** | |
* Convert a TSR to a DSR with zero-width container open/close tags. | |
* @param SourceRange $tsr | |
* @return DomSourceRange | |
*/ | |
public static function fromTsr( SourceRange $tsr ): DomSourceRange { | |
return new DomSourceRange( $tsr->start, $tsr->end, null, null ); | |
} | |
/** | |
* Create a new DomSourceRange from an array of integers/null (such as | |
* created during JSON serialization). | |
* @param array<int|null> $dsr | |
* @return DomSourceRange | |
*/ | |
public static function fromArray( array $dsr ): DomSourceRange { | |
$n = count( $dsr ); | |
Assert::invariant( $n === 2 || $n === 4 || $n === 6, 'Not enough elements in DSR array' ); | |
return new DomSourceRange( | |
$dsr[0], $dsr[1], $dsr[2] ?? null, $dsr[3] ?? null, $dsr[4] ?? 0, $dsr[5] ?? 0 | |
); | |
} | |
/** | |
* @inheritDoc | |
*/ | |
public function jsonSerialize(): array { | |
$a = [ $this->start, $this->end, $this->openWidth, $this->closeWidth ]; | |
if ( $this->leadingWS !== 0 || $this->trailingWS !== 0 ) { | |
$a[] = $this->leadingWS; | |
$a[] = $this->trailingWS; | |
} | |
return $a; | |
} | |
} |