Page MenuHomeWickedGov Phorge

DataParsoid.php
No OneTemporary

Size
12 KB
Referenced Files
None
Subscribers
None

DataParsoid.php

<?php
declare( strict_types = 1 );
namespace Wikimedia\Parsoid\NodeData;
use Wikimedia\JsonCodec\Hint;
use Wikimedia\JsonCodec\JsonCodecable;
use Wikimedia\JsonCodec\JsonCodecableTrait;
use Wikimedia\Parsoid\Core\DomSourceRange;
use Wikimedia\Parsoid\Tokens\SourceRange;
use Wikimedia\Parsoid\Tokens\Token;
use Wikimedia\Parsoid\Utils\Utils;
/**
* Parsoid data for a DOM node. Managed by DOMDataUtils::get/setDataParsoid().
*
* To reduce memory usage, most the properties need to be undeclared, but we can
* use the property declarations below to satisfy phan and to provide type
* information to IDEs.
*
* TODO: Declaring common properties would be beneficial for memory usage, but
* changes the JSON serialized output and breaks tests.
*
* == Miscellaneous / General properties ==
*
* Used to emit original wikitext in some scenarios (entities, placeholder spans)
* Porting note: this can be '0', handle emptiness checks with care
* @property string|null $src
*
* Tag widths for all tokens.
* Temporarily present in data-parsoid, but not in final DOM output.
* @see ComputeDSR::computeNodeDSR()
* @property SourceRange|null $tsr
*
* Wikitext source ranges that generated this DOM node.
* In the form [ start-offset, end-offset ] or
* [ start-offset, end-offset, start-tag-width, end-tag-width ].
*
* Consider input wikitext: `abcdef ''foo'' something else`. Let us look at the `''foo''`
* part of the input. It generates `<i data-parsoid='{"dsr":[7,14,2,2]}'>foo</i>` . The dsr
* property of the data-parsoid attribute of this i-tag tells us the following. This HTML node
* maps to input wikitext substring 7..14. The opening tag <i> was 2 characters wide in wikitext
* and the closing tag </i> was also 2 characters wide in wikitext.
* @property DomSourceRange|null $dsr
*
* Denotes special syntax. Possible values:
* - 'html' for html tags. Ex: `<div>foo</div>`
* - 'row' for dt/dd that show on the same line. Ex: `;a:b` (but not `;a\n:b`)
* - 'piped' for piped wikilinks with explicit content Ex: `[[Foo|bar]]` (but not `[[Foo]]`)
* - 'magiclink', 'url' - legacy, not used anymore
* @property string|null $stx
*
* Template parameter infos produced by TemplateHandler. After unserialization,
* the objects are not fully populated.
* @property ParamInfo[][]|null $pi
*
* Expanded template HTML (native preprocessor only).
* @property string|null $html
*
* On mw:Entity spans this is set to the decoded entity value.
* @property string|null $srcContent
*
* An array of associative arrays describing image rendering options, attached
* to the image container (span or figure).
* - ck: Canonical key for the image option.
* - ak: Aliased key.
* @property array|null $optList
*
* Rendered attributes (shadow info). The key is the attribute name. The value
* is documented as "mixed" but seems to be coerced to string in
* Sanitizer::sanitizeTagAttrs().
* @property array|null $a Rendered attributes
*
* Source attributes (shadow info). The key is the attribute name. The value
* is documented as "mixed" but may possibly be a nullable string.
* @property array|null $sa Source attributes
*
* FIXME never written
* @property bool|null $strippedNL
*
* The number of extra dashes in the source of an hr
* @property int|null $extra_dashes
*
* The complete text of a double-underscore behavior switch
* @property string|null $magicSrc
*
* True if the input heading element had an id attribute, preventing automatic
* assignment of a new id attribute.
* @property bool|null $reusedId
*
* FIXME: Get rid of this property and the code that reads it after content
* version 2.2.0 has expired from caches.
* @property mixed $liHackSrc
*
* The link token associated with a redirect
* @property Token|null $linkTk
*
* On a meta mw:EmptyLine, the associated comment and whitespace tokens. Used
* in this sense by both the tokenizer and TokenStreamPatcher.
* @property array $tokens
*
* This is set to "extlink" on auto URL (external hotlink) image links.
* @property string|null $type
*
* On a meta mw:Placeholder/StrippedTag, this is the name of the stripped tag.
* @property string|null $name
*
* This is set on image containers in which a template expands to multiple
* image parameters. It is converted to a typeof attribute later in the same
* function, so it's unclear why it needs to persist in data-parsoid.
* @property bool|null $uneditable
*
* == WrapTemplates ==
*
* The wikitext source which was not included in a template wrapper.
* @property string|null $unwrappedWT
*
* The token or DOM node name, optionally suffixed with the syntax name from
* $this->stx, of the first node within the encapsulated content.
* @property string|null $firstWikitextNode
*
* == Extensions ==
*
* Offsets of opening and closing tags for extension tags, in the form
* [ opening tag start , closing tag end, opening tag width, closing tag width ]
* Temporarily present in data-parsoid, but not in final DOM output.
* @property DomSourceRange|null $extTagOffsets
*
* This is true on the extension output wrapper if the extension input wikitext
* was an empty string. Consumed by <references/>.
* @property bool $empty
*
* The reference group. This is attached to the <ol> or its wrapper <div>,
* redundantly with the data-mw-group attribute on the <ol>. It is produced by
* the extension's sourceToDom() and consumed by wtPostprocess().
* @property string $group
*
* == Annotations ==
* This is used on annotation meta tags to indicate that the corresponding
* tag has been moved compared to it's initial location defined by wikitext.
* An annotation tag can be moved either as the result of fostering or as
* the result of annotation range extension to enclose a contiguous DOM
* forest.
* @property bool|null $wasMoved
*
* == HTML tags ==
*
* Are void tags self-closed? (Ex: `<br>` vs `<br />`)
* @property bool|null $selfClose
*
* Void tags that are not self-closed (Ex: `<br>`)
* @property bool|null $noClose
*
* Whether this start HTML tag has no corresponding wikitext and was auto-inserted by a token
* handler to generate well-formed html. Usually happens when a token handler fixes up misnesting.
* @property bool|null $autoInsertedStartToken
*
* Whether this end HTML tag has no corresponding wikitext and was auto-inserted by a token
* handler to generate well-formed html. Usually happens when a token handler fixes up misnesting.
* @property bool|null $autoInsertedEndToken
*
* Whether this start HTML tag has no corresponding wikitext and was auto-inserted to generate
* well-formed html. Usually happens when treebuilder fixes up badly nested HTML.
* @property bool|null $autoInsertedStart
*
* Whether this end HTML tag has no corresponding wikitext and was auto-inserted to generate
* well-formed html. Ex: `<tr>`, `<th>`, `<td>`, `<li>`, etc. that have no explicit closing
* markup. Or, html tags that aren't closed.
* @property bool|null $autoInsertedEnd
*
* Source tag name for HTML tags. Records case variations (`<div>` vs `<DiV>` vs `<DIV>`).
* @property string|null $srcTagName
*
* UnpackDomFragments sets this on misnested elements
* @property bool|null $misnested
*
* This is set by MarkFosteredContent to indicate fostered content and content
* wrappers.
* @property bool|null $fostered
*
* == Links ==
*
* Link trail source (Ex: the "l" in `[[Foo]]l`)
* Porting note: this can be '0', handle emptiness checks with care
* @property string|null $tail
*
* Link prefix source
* Porting note: this can be '0', handle emptiness checks with care
* @property string|null $prefix
*
* True if the link was a pipetrick (`[[Foo|]]`).
* @note This will likely be removed soon since this should not show up in saved wikitext since
* this is a pre-save transformation trick.
* @property bool|null $pipeTrick
*
* Did the link use interwiki syntax?
* Probably redundant with the rel=mw:WikiLink/Interwiki
* @property bool|null $isIW
*
* == Tables ==
*
* Source for start-text separators in table wikitext.
* @property string|null $startTagSrc
*
* Source for end-text separators in table wikitext.
* @property string|null $endTagSrc
*
* Source for attribute-text separators in table wikitext.
* @property string|null $attrSepSrc
*
* 'row' for td/th cells that show up on the same line, null otherwise
* @property string|null $stx_v
*
* == Language variant token properties ==
*
* @property array|null $flags Flags with their human-readable names
* @property array|null $variants The variant names
* @property array|null $original Original flags
* @property array|null $flagSp Spaces around flags, uncompressed
*
* An array of associative arrays describing the parts of the variant rule.
* - text: (string) The text
* - semi: (bool) A semicolon marker
* - sp: (array|string) An array of strings containing spaces
* - oneway: (bool) A one-way rule definition
* - twoway: (bool) A two-way rule definition
* - from: (array) An associative array:
* - tokens: (array) A token array
* - srcOffsets: SourceRange
* - to: (array) An associative array same as "from"
* - lang: (string)
* @property array|null $texts
*
* == Language variant data-parsoid properties ==
*
* @property array|null $flSp Spaces around flags, compressed with compressSpArray().
* @property array|null $tSp Spaces around texts, compressed with compressSpArray().
* @property array|null $fl Original flags, copied from $this->original on the token.
*/
#[\AllowDynamicProperties]
class DataParsoid implements JsonCodecable {
use JsonCodecableTrait;
/**
* Holds a number of transient properties in the wt->html pipeline to pass information between
* stages. Dropped before serialization.
* @var TempData|null
*/
public $tmp;
/**
* Deeply clone this object
*
* @return DataParsoid
*/
public function clone(): self {
$dp = clone $this;
// Properties that need deep cloning
if ( isset( $dp->tmp ) ) {
$dp->tmp = Utils::clone( $dp->tmp );
}
if ( isset( $dp->linkTk ) ) {
$dp->linkTk = Utils::clone( $dp->linkTk );
}
if ( isset( $dp->tokens ) ) {
$dp->tokens = Utils::clone( $dp->tokens );
}
// Properties that need shallow cloning
if ( isset( $dp->tsr ) ) {
$dp->tsr = clone $dp->tsr;
}
if ( isset( $dp->dsr ) ) {
$dp->dsr = clone $dp->dsr;
}
if ( isset( $dp->extTagOffsets ) ) {
$dp->extTagOffsets = clone $dp->extTagOffsets;
}
// The remaining properties were sufficiently handled by the clone operator
return $dp;
}
public function isModified(): bool {
// NOTE: strict equality will not work in this comparison
// @phan-suppress-next-line PhanPluginComparisonObjectEqualityNotStrict
return $this != new self;
}
/**
* Get a lazy-initialized object to which temporary properties can be written.
* @return TempData
*/
public function getTemp(): TempData {
// tmp can be unset despite being declared
$this->tmp ??= new TempData();
return $this->tmp;
}
/**
* Check whether a bit is set in $this->tmp->bits
*
* @param int $flag
* @return bool
*/
public function getTempFlag( $flag ): bool {
return isset( $this->tmp ) && ( $this->tmp->bits & $flag );
}
/**
* Set a bit in $this->tmp->bits
*
* @param int $flag
* @param bool $value
*/
public function setTempFlag( $flag, $value = true ): void {
if ( $value ) {
if ( !isset( $this->tmp ) ) {
$tmp = new TempData;
$tmp->bits = $flag;
$this->tmp = $tmp;
} else {
$this->tmp->bits |= $flag;
}
} elseif ( isset( $this->tmp ) ) {
$this->tmp->bits &= ~$flag;
}
}
/** @inheritDoc */
public function toJsonArray(): array {
static $clearNullsFrom = [
'dsr', 'tsr', 'extTagOffsets',
];
$result = (array)$this;
unset( $result['tmp'] );
// Conciseness: don't include `null` values from certain properties.
foreach ( $clearNullsFrom as $prop ) {
if ( !isset( $result[$prop] ) ) {
unset( $result[$prop] );
}
}
return $result;
}
/** @inheritDoc */
public static function jsonClassHintFor( string $keyname ) {
static $hints = null;
if ( $hints === null ) {
$dsr = Hint::build( DomSourceRange::class, Hint::USE_SQUARE );
$sr = Hint::build( SourceRange::class, Hint::USE_SQUARE );
$hints = [
'dsr' => $dsr,
'extTagOffsets' => $dsr,
'tsr' => $sr,
'pi' => Hint::build( ParamInfo::class, Hint::LIST, Hint::LIST ),
'linkTk' => Token::class,
];
}
return $hints[$keyname] ?? null;
}
/** @inheritDoc */
public static function newFromJsonArray( array $json ): DataParsoid {
$dp = new DataParsoid;
foreach ( $json as $key => $value ) {
switch ( $key ) {
case 'dsr':
case 'extTagOffsets':
case 'tsr':
// For backward compatibility, leave these unset if null.
if ( $value !== null ) {
$dp->$key = $value;
}
break;
case 'tmp':
// This isn't serialized, but we can deserialize it
// for tests.
$tmp = new TempData;
foreach ( $value as $key2 => $value2 ) {
$tmp->$key2 = $value2;
}
$dp->$key = $tmp;
break;
default:
$dp->$key = $value;
break;
}
}
return $dp;
}
}

File Metadata

Mime Type
text/x-php
Expires
Tue, Aug 18, 20:12 (2 w, 3 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
c3/39/22c1ce89b33b9a92975dfc0e0e54
Default Alt Text
DataParsoid.php (12 KB)

Event Timeline