Page MenuHomeWickedGov Phorge

PageBundle.php
No OneTemporary

Size
5 KB
Referenced Files
None
Subscribers
None

PageBundle.php

<?php
declare( strict_types = 1 );
namespace Wikimedia\Parsoid\Core;
use Composer\Semver\Semver;
use Wikimedia\Parsoid\DOM\Document;
use Wikimedia\Parsoid\DOM\Element;
use Wikimedia\Parsoid\DOM\Node;
use Wikimedia\Parsoid\Utils\ContentUtils;
use Wikimedia\Parsoid\Utils\DOMCompat;
use Wikimedia\Parsoid\Utils\DOMDataUtils;
use Wikimedia\Parsoid\Utils\DOMUtils;
use Wikimedia\Parsoid\Utils\PHPUtils;
/**
* PORT-FIXME: This is just a placeholder for data that was previously passed
* to entrypoint in JavaScript. Who will construct these objects and whether
* this is the correct interface is yet to be determined.
*
* Note that the parsoid/mw properties of the page bundle are in "serialized
* array" form; that is, they are flat arrays appropriate for json-encoding
* and do not contain DataParsoid or DataMw objects.
*/
class PageBundle {
/** @var string */
public $html;
/**
* A map from ID to the array serialization of DataParsoid for the Node
* with that ID.
*
* @var null|array{counter?:int,offsetType?:string,ids:array<string,array>}
*/
public $parsoid;
/**
* A map from ID to the array serialization of DataMw for the Node
* with that ID.
*
* @var null|array{ids:array<string,array>}
*/
public $mw;
/** @var ?string */
public $version;
/**
* A map of HTTP headers: both name and value should be strings.
* @var array<string,string>|null
*/
public $headers;
/** @var string|null */
public $contentmodel;
public function __construct(
string $html, ?array $parsoid = null, ?array $mw = null,
?string $version = null, ?array $headers = null,
?string $contentmodel = null
) {
$this->html = $html;
$this->parsoid = $parsoid;
$this->mw = $mw;
$this->version = $version;
$this->headers = $headers;
$this->contentmodel = $contentmodel;
}
public function toDom(): Document {
$doc = DOMUtils::parseHTML( $this->html );
self::apply( $doc, $this );
return $doc;
}
public function toHtml(): string {
return ContentUtils::toXML( $this->toDom() );
}
/**
* Check if this pagebundle is valid.
* @param string $contentVersion Document content version to validate against.
* @param ?string &$errorMessage Error message will be returned here.
* @return bool
*/
public function validate(
string $contentVersion, ?string &$errorMessage = null
) {
if ( !$this->parsoid || !isset( $this->parsoid['ids'] ) ) {
$errorMessage = 'Invalid data-parsoid was provided.';
return false;
} elseif ( Semver::satisfies( $contentVersion, '^999.0.0' )
&& ( !$this->mw || !isset( $this->mw['ids'] ) )
) {
$errorMessage = 'Invalid data-mw was provided.';
return false;
}
return true;
}
/**
* @return array
*/
public function responseData() {
$responseData = [
'contentmodel' => $this->contentmodel ?? '',
'html' => [
'headers' => array_merge( [
'content-type' => 'text/html; charset=utf-8; '
. 'profile="https://www.mediawiki.org/wiki/Specs/HTML/'
. $this->version . '"',
], $this->headers ?? [] ),
'body' => $this->html,
],
'data-parsoid' => [
'headers' => [
'content-type' => 'application/json; charset=utf-8; '
. 'profile="https://www.mediawiki.org/wiki/Specs/data-parsoid/'
. $this->version . '"',
],
'body' => $this->parsoid,
],
];
if ( Semver::satisfies( $this->version, '^999.0.0' ) ) {
$responseData['data-mw'] = [
'headers' => [
'content-type' => 'application/json; charset=utf-8; ' .
'profile="https://www.mediawiki.org/wiki/Specs/data-mw/' .
$this->version . '"',
],
'body' => $this->mw,
];
}
return $responseData;
}
/**
* Applies the `data-*` attributes JSON structure to the document.
* Leaves `id` attributes behind -- they are used by citation code to
* extract `<ref>` body from the DOM.
*
* @param Document $doc doc
* @param PageBundle $pb page bundle
*/
public static function apply( Document $doc, PageBundle $pb ): void {
DOMUtils::visitDOM(
DOMCompat::getBody( $doc ),
static function ( Node $node ) use ( $pb ): void {
if ( $node instanceof Element ) {
$id = DOMCompat::getAttribute( $node, 'id' );
if ( $id === null ) {
return;
}
if ( isset( $pb->parsoid['ids'][$id] ) ) {
DOMDataUtils::setJSONAttribute(
$node, 'data-parsoid', $pb->parsoid['ids'][$id]
);
}
if ( isset( $pb->mw['ids'][$id] ) ) {
// Only apply if it isn't already set. This means
// earlier applications of the pagebundle have higher
// precedence, inline data being the highest.
if ( !$node->hasAttribute( 'data-mw' ) ) {
DOMDataUtils::setJSONAttribute(
$node, 'data-mw', $pb->mw['ids'][$id]
);
}
}
}
}
);
}
/**
* Encode some of these properties for emitting in the <head> element of a doc
* @return string
*/
public function encodeForHeadElement(): string {
// Note that $this->parsoid and $this->mw are already serialized arrays
// so a naive jsonEncode is sufficient. We don't need a codec.
return PHPUtils::jsonEncode( [ 'parsoid' => $this->parsoid ?? [], 'mw' => $this->mw ?? [] ] );
}
}

File Metadata

Mime Type
text/x-php
Expires
Aug 19 2026, 20:19 (7 w, 1 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
6b/5f/baf3094778394ad6cdb675e4b672
Default Alt Text
PageBundle.php (5 KB)

Event Timeline