Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F4106084
RefGroup.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
RefGroup.php
View Options
<?php
declare
(
strict_types
=
1
);
namespace
Cite\Parsoid
;
use
Wikimedia\Parsoid\Core\Sanitizer
;
use
Wikimedia\Parsoid\DOM\Document
;
use
Wikimedia\Parsoid\DOM\Element
;
use
Wikimedia\Parsoid\Ext\DOMDataUtils
;
use
Wikimedia\Parsoid\Ext\DOMUtils
;
use
Wikimedia\Parsoid\Ext\ParsoidExtensionAPI
;
use
Wikimedia\Parsoid\Utils\DOMCompat
;
/**
* Helper class used by `<references>` implementation.
* @license GPL-2.0-or-later
*/
class
RefGroup
{
public
string
$name
;
/** @var RefGroupItem[] */
public
array
$refs
=
[];
/** @var array<string,RefGroupItem> Lookup map only for named refs */
public
array
$indexByName
=
[];
/** @var int Counter to track order of ref appearance in article */
private
int
$nextIndex
=
1
;
/** @var array<string,int> Counter to provide subreference indexes */
private
array
$subRefCountByName
=
[];
public
function
__construct
(
string
$group
=
''
)
{
$this
->
name
=
$group
;
}
public
function
lookupRefByName
(
string
$name
):
?
RefGroupItem
{
return
$this
->
indexByName
[
$name
]
??
null
;
}
/**
* Generate leading linkbacks
*/
private
static
function
createLinkback
(
ParsoidExtensionAPI
$extApi
,
string
$target
,
?
string
$group
,
string
$text
,
Document
$ownerDoc
):
Element
{
$a
=
$ownerDoc
->
createElement
(
'a'
);
$span
=
$ownerDoc
->
createElement
(
'span'
);
$a
->
setAttribute
(
'href'
,
$extApi
->
getPageUri
()
.
'#'
.
Sanitizer
::
escapeIdForLink
(
$target
)
);
$span
->
setAttribute
(
'class'
,
'mw-linkback-text'
);
if
(
$group
)
{
$a
->
setAttribute
(
'data-mw-group'
,
$group
);
}
$span
->
appendChild
(
$ownerDoc
->
createTextNode
(
$text
.
' '
)
);
$a
->
appendChild
(
$span
);
return
$a
;
}
public
function
renderLine
(
ParsoidExtensionAPI
$extApi
,
Element
$refsList
,
RefGroupItem
$ref
):
void
{
$ownerDoc
=
$refsList
->
ownerDocument
;
// Generate the li and set ref content first, so the HTML gets parsed.
// We then append the rest of the ref nodes before the first node
$li
=
$ownerDoc
->
createElement
(
'li'
);
$refDir
=
$ref
->
dir
;
$noteId
=
ParsoidAnchorFormatter
::
getNoteIdentifier
(
$ref
);
$refContentId
=
$ref
->
contentId
;
$refGroup
=
$ref
->
group
;
DOMUtils
::
addAttributes
(
$li
,
[
'about'
=>
'#'
.
$noteId
,
'id'
=>
$noteId
,
'class'
=>
(
$refDir
===
'rtl'
||
$refDir
===
'ltr'
)
?
'mw-cite-dir-'
.
$refDir
:
null
]
);
$reftextSpan
=
$ownerDoc
->
createElement
(
'span'
);
DOMUtils
::
addAttributes
(
$reftextSpan
,
[
'id'
=>
ParsoidAnchorFormatter
::
getNoteTextIdentifier
(
$ref
),
// Add both mw-reference-text & reference-text for b/c.
// We will remove duplicate classes in the future.
'class'
=>
'mw-reference-text reference-text'
,
]
);
if
(
$refContentId
)
{
// `sup` is the wrapper created by RefTagHandler::sourceToDom()'s call to
// `extApi->extTagToDOM()`. Only its contents are relevant.
$sup
=
$extApi
->
getContentDOM
(
$refContentId
)->
firstChild
;
DOMUtils
::
migrateChildren
(
$sup
,
$reftextSpan
);
'@phan-var Element $sup'
;
/** @var Element $sup */
DOMCompat
::
remove
(
$sup
);
$extApi
->
clearContentDOM
(
$refContentId
);
}
elseif
(
$ref
->
externalFragment
)
{
DOMUtils
::
migrateChildren
(
$ref
->
externalFragment
,
$reftextSpan
);
}
$li
->
appendChild
(
$reftextSpan
);
$errorUtils
=
new
ErrorUtils
(
$extApi
);
// It seems counter-productive to go through hoops to not display all the errors considering that rendering
// only the first one is considered deprecated in the legacy code. However, displaying the same error
// multiple times for the same reference is also useless. Hence, we avoid displaying the same error
// multiple times.
$reported
=
[];
foreach
(
$ref
->
nodes
as
$node
)
{
foreach
(
DOMDataUtils
::
getDataMw
(
$node
)->
errors
??
[]
as
$error
)
{
if
(
in_array
(
$error
,
$reported
)
)
{
continue
;
}
$reported
[]
=
$error
;
$errorFragment
=
$errorUtils
->
renderParsoidError
(
$error
);
$li
->
appendChild
(
$errorFragment
);
}
}
// mw:referencedBy is added to the <span> for the named refs case
// and to the <a> tag to the unnamed refs case. This difference
// is used by CSS to style backlinks in MediaWiki:Common.css
// of various wikis.
$linkbackSpan
=
$ownerDoc
->
createElement
(
'span'
);
if
(
$ref
->
visibleNodes
===
1
)
{
// Can be an unnamed reference or a named one that's just never reused
$lb
=
ParsoidAnchorFormatter
::
getBackLinkIdentifier
(
$ref
);
$linkback
=
self
::
createLinkback
(
$extApi
,
$lb
,
$refGroup
,
"↑"
,
$ownerDoc
);
DOMUtils
::
addRel
(
$linkback
,
'mw:referencedBy'
);
$linkbackSpan
->
appendChild
(
$linkback
);
}
else
{
DOMUtils
::
addRel
(
$linkbackSpan
,
'mw:referencedBy'
);
for
(
$i
=
1
;
$i
<=
$ref
->
visibleNodes
;
$i
++
)
{
$lb
=
ParsoidAnchorFormatter
::
getBackLinkIdentifier
(
$ref
,
$i
);
$linkbackSpan
->
appendChild
(
self
::
createLinkback
(
$extApi
,
$lb
,
$refGroup
,
(
string
)
$i
,
$ownerDoc
)
);
}
}
DOMCompat
::
getClassList
(
$linkbackSpan
)->
add
(
'mw-cite-backlink'
);
$li
->
insertBefore
(
$linkbackSpan
,
$reftextSpan
);
// Space before content node
$li
->
insertBefore
(
$ownerDoc
->
createTextNode
(
' '
),
$reftextSpan
);
// Add it to the ref list
$refsList
->
appendChild
(
$li
);
// Backward-compatibility: add newline (T372889)
$refsList
->
appendChild
(
$ownerDoc
->
createTextNode
(
"
\n
"
)
);
}
/** @internal only for {@see ReferencesData} */
public
function
getNextIndex
():
int
{
return
$this
->
nextIndex
++;
}
/** @internal only for {@see ReferencesData} */
public
function
getNextSubrefSequence
(
string
$parentName
):
int
{
$this
->
subRefCountByName
[
$parentName
]
??=
0
;
return
++
$this
->
subRefCountByName
[
$parentName
];
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Tue, Aug 18, 19:17 (2 w, 4 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
43/af/170bbd0be2c362c1df6ed2a43950
Default Alt Text
RefGroup.php (5 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment