2019-04-02 22:06:21 +00:00
|
|
|
<?php
|
2019-05-25 22:24:47 +00:00
|
|
|
declare( strict_types = 1 );
|
2019-04-02 22:06:21 +00:00
|
|
|
|
2020-02-03 18:52:06 +00:00
|
|
|
namespace Wikimedia\Parsoid\Ext\Cite;
|
2019-04-02 22:06:21 +00:00
|
|
|
|
2020-05-28 22:26:31 +00:00
|
|
|
use DOMElement;
|
2019-05-25 22:24:47 +00:00
|
|
|
use stdClass;
|
2020-03-04 21:40:55 +00:00
|
|
|
use Wikimedia\Parsoid\Ext\ParsoidExtensionAPI;
|
2019-04-02 22:06:21 +00:00
|
|
|
|
|
|
|
class ReferencesData {
|
2019-05-25 22:24:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var int
|
|
|
|
*/
|
2020-10-23 14:28:18 +00:00
|
|
|
private $index = 0;
|
2019-05-25 22:24:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var RefGroup[]
|
|
|
|
*/
|
2020-10-23 14:28:18 +00:00
|
|
|
private $refGroups = [];
|
2019-05-25 22:24:47 +00:00
|
|
|
|
2020-11-05 16:53:34 +00:00
|
|
|
/** @var array */
|
|
|
|
public $embeddedErrors = [];
|
|
|
|
|
|
|
|
/** @var array */
|
2020-11-20 01:55:39 +00:00
|
|
|
private $inEmbeddedContent = [];
|
2020-10-02 19:18:59 +00:00
|
|
|
|
2020-11-24 15:08:35 +00:00
|
|
|
/** @var string */
|
|
|
|
public $referencesGroup = '';
|
|
|
|
|
2020-11-20 01:55:39 +00:00
|
|
|
/**
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function inReferencesContent(): bool {
|
|
|
|
return $this->inEmbeddedContent( 'references' );
|
2020-10-23 14:28:18 +00:00
|
|
|
}
|
|
|
|
|
2020-11-20 01:55:39 +00:00
|
|
|
/**
|
|
|
|
* @param ?string $needle
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function inEmbeddedContent( ?string $needle = null ): bool {
|
|
|
|
if ( $needle ) {
|
|
|
|
return in_array( $needle, $this->inEmbeddedContent, true );
|
|
|
|
} else {
|
|
|
|
return count( $this->inEmbeddedContent ) > 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $needle
|
|
|
|
*/
|
|
|
|
public function pushInEmbeddedContent( string $needle = 'embed' ) {
|
|
|
|
array_unshift( $this->inEmbeddedContent, $needle );
|
2020-10-23 14:28:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function popInEmbeddedContent() {
|
|
|
|
array_shift( $this->inEmbeddedContent );
|
2019-04-02 22:06:21 +00:00
|
|
|
}
|
|
|
|
|
2019-05-25 22:24:47 +00:00
|
|
|
/**
|
|
|
|
* @param string $groupName
|
|
|
|
* @param bool $allocIfMissing
|
2020-11-05 15:38:16 +00:00
|
|
|
* @return ?RefGroup
|
2019-05-25 22:24:47 +00:00
|
|
|
*/
|
2020-11-05 15:38:16 +00:00
|
|
|
public function getRefGroup(
|
|
|
|
string $groupName, bool $allocIfMissing = false
|
|
|
|
): ?RefGroup {
|
2019-05-25 22:24:47 +00:00
|
|
|
if ( !isset( $this->refGroups[$groupName] ) && $allocIfMissing ) {
|
|
|
|
$this->refGroups[$groupName] = new RefGroup( $groupName );
|
2019-04-02 22:06:21 +00:00
|
|
|
}
|
2019-05-25 22:24:47 +00:00
|
|
|
return $this->refGroups[$groupName] ?? null;
|
2019-04-02 22:06:21 +00:00
|
|
|
}
|
|
|
|
|
2019-05-25 22:24:47 +00:00
|
|
|
/**
|
2020-11-05 15:38:16 +00:00
|
|
|
* @param string $groupName
|
2019-05-25 22:24:47 +00:00
|
|
|
*/
|
2020-11-05 15:38:16 +00:00
|
|
|
public function removeRefGroup( string $groupName ): void {
|
|
|
|
// '' is a valid group (the default group)
|
|
|
|
unset( $this->refGroups[$groupName] );
|
2019-04-02 22:06:21 +00:00
|
|
|
}
|
|
|
|
|
2019-05-25 22:24:47 +00:00
|
|
|
/**
|
2020-02-07 16:17:42 +00:00
|
|
|
* @param ParsoidExtensionAPI $extApi
|
2019-05-25 22:24:47 +00:00
|
|
|
* @param string $groupName
|
|
|
|
* @param string $refName
|
|
|
|
* @param string $about
|
2020-05-28 22:26:31 +00:00
|
|
|
* @param DOMElement $linkBack
|
2019-05-25 22:24:47 +00:00
|
|
|
* @return stdClass
|
|
|
|
*/
|
|
|
|
public function add(
|
2020-07-08 22:48:02 +00:00
|
|
|
ParsoidExtensionAPI $extApi, string $groupName, string $refName,
|
2020-11-05 14:35:53 +00:00
|
|
|
string $about, DOMElement $linkBack
|
2019-05-25 22:24:47 +00:00
|
|
|
): stdClass {
|
2019-04-02 22:06:21 +00:00
|
|
|
$group = $this->getRefGroup( $groupName, true );
|
2019-08-14 22:59:28 +00:00
|
|
|
$hasRefName = strlen( $refName ) > 0;
|
2019-04-02 22:06:21 +00:00
|
|
|
|
2019-08-14 22:59:28 +00:00
|
|
|
if ( $hasRefName && isset( $group->indexByName[$refName] ) ) {
|
2019-05-25 22:24:47 +00:00
|
|
|
$ref = $group->indexByName[$refName];
|
2020-02-07 16:17:42 +00:00
|
|
|
if ( $ref->contentId && !$ref->hasMultiples ) {
|
2019-04-02 22:06:21 +00:00
|
|
|
$ref->hasMultiples = true;
|
2020-07-28 21:35:18 +00:00
|
|
|
$c = $extApi->getContentDOM( $ref->contentId )->firstChild;
|
|
|
|
$ref->cachedHtml = $extApi->domToHtml( $c, true, false );
|
2019-04-02 22:06:21 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// The ids produced Cite.php have some particulars:
|
|
|
|
// Simple refs get 'cite_ref-' + index
|
|
|
|
// Refs with names get 'cite_ref-' + name + '_' + index + (backlink num || 0)
|
|
|
|
// Notes (references) whose ref doesn't have a name are 'cite_note-' + index
|
|
|
|
// Notes whose ref has a name are 'cite_note-' + name + '-' + index
|
|
|
|
$n = $this->index;
|
2019-05-25 22:24:47 +00:00
|
|
|
$refKey = strval( 1 + $n );
|
2019-08-14 22:59:28 +00:00
|
|
|
$refIdBase = 'cite_ref-' . ( $hasRefName ? $refName . '_' . $refKey : $refKey );
|
|
|
|
$noteId = 'cite_note-' . ( $hasRefName ? $refName . '-' . $refKey : $refKey );
|
2019-04-02 22:06:21 +00:00
|
|
|
|
|
|
|
// bump index
|
|
|
|
$this->index += 1;
|
|
|
|
|
2019-05-25 22:24:47 +00:00
|
|
|
$ref = (object)[
|
2020-02-07 16:17:42 +00:00
|
|
|
'contentId' => null,
|
2019-04-02 22:06:21 +00:00
|
|
|
'dir' => '',
|
|
|
|
'group' => $group->name,
|
|
|
|
'groupIndex' => count( $group->refs ) + 1,
|
|
|
|
'index' => $n,
|
|
|
|
'key' => $refIdBase,
|
2019-08-14 22:59:28 +00:00
|
|
|
'id' => $hasRefName ? $refIdBase . '-0' : $refIdBase,
|
2019-04-02 22:06:21 +00:00
|
|
|
'linkbacks' => [],
|
|
|
|
'name' => $refName,
|
|
|
|
'target' => $noteId,
|
|
|
|
'hasMultiples' => false,
|
|
|
|
// Just used for comparison when we have multiples
|
2020-05-28 22:26:31 +00:00
|
|
|
'cachedHtml' => '',
|
|
|
|
'nodes' => [],
|
2020-11-05 16:53:34 +00:00
|
|
|
'embeddedNodes' => [],
|
2019-04-02 22:06:21 +00:00
|
|
|
];
|
|
|
|
$group->refs[] = $ref;
|
2020-05-28 22:26:31 +00:00
|
|
|
if ( $hasRefName ) {
|
2019-05-25 22:24:47 +00:00
|
|
|
$group->indexByName[$refName] = $ref;
|
2019-04-02 22:06:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-05 16:53:34 +00:00
|
|
|
if ( $this->inEmbeddedContent() ) {
|
|
|
|
$ref->embeddedNodes[] = $about;
|
|
|
|
} else {
|
2020-11-05 15:52:32 +00:00
|
|
|
$ref->nodes[] = $linkBack;
|
2019-04-02 22:06:21 +00:00
|
|
|
$ref->linkbacks[] = $ref->key . '-' . count( $ref->linkbacks );
|
|
|
|
}
|
2020-05-28 22:26:31 +00:00
|
|
|
|
2019-04-02 22:06:21 +00:00
|
|
|
return $ref;
|
|
|
|
}
|
|
|
|
|
2019-05-25 22:24:47 +00:00
|
|
|
/**
|
|
|
|
* @return RefGroup[]
|
|
|
|
*/
|
|
|
|
public function getRefGroups(): array {
|
|
|
|
return $this->refGroups;
|
|
|
|
}
|
|
|
|
}
|