Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F5974853
createReferencePreview.js
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
createReferencePreview.js
View Options
/**
* @module referencePreview
*/
const
{
isTrackingEnabled
,
LOGGING_SCHEMA
}
=
require
(
'./referencePreviewsInstrumentation.js'
);
const
TEMPLATE
=
document
.
createElement
(
'template'
);
TEMPLATE
.
innerHTML
=
`
<div class="mwe-popups mwe-popups mwe-popups-type-reference" aria-hidden>
<div class="mwe-popups-container">
<div class="mwe-popups-extract">
<div class="mwe-popups-scroll">
<strong class="mwe-popups-title">
<span class="popups-icon"></span>
<span class="mwe-popups-title-placeholder"></span>
</strong>
<bdi><div class="mw-parser-output"></div></bdi>
</div>
<div class="mwe-popups-fade"></div>
</div>
<footer>
<div class="mwe-popups-settings"></div>
</footer>
</div>
</div>`
;
/**
* @param {HTMLElement} node
* @param {HTMLElement|string} htmlOrOtherNode
*/
const
replaceWith
=
(
node
,
htmlOrOtherNode
)
=>
{
if
(
typeof
htmlOrOtherNode
===
'string'
)
{
node
.
insertAdjacentHTML
(
'afterend'
,
htmlOrOtherNode
);
}
else
{
node
.
parentNode
.
appendChild
(
htmlOrOtherNode
);
}
node
.
remove
();
};
/**
* @param {ext.popups.PreviewModel} model
* @return {jQuery}
*/
function
renderReferencePreview
(
model
)
{
const
type
=
model
.
referenceType
||
'generic'
;
// The following messages are used here:
// * cite-reference-previews-book
// * cite-reference-previews-journal
// * cite-reference-previews-news
// * cite-reference-previews-note
// * cite-reference-previews-web
let
titleMsg
=
mw
.
message
(
`cite-reference-previews-
${
type
}
`
);
if
(
!
titleMsg
.
exists
()
)
{
titleMsg
=
mw
.
message
(
'cite-reference-previews-reference'
);
}
const
el
=
TEMPLATE
.
content
.
cloneNode
(
true
).
children
[
0
];
replaceWith
(
el
.
querySelector
(
'.mwe-popups-title-placeholder'
),
mw
.
html
.
escape
(
titleMsg
.
text
()
)
);
// The following classes are used here:
// * popups-icon--reference-generic
// * popups-icon--reference-book
// * popups-icon--reference-journal
// * popups-icon--reference-news
// * popups-icon--reference-note
// * popups-icon--reference-web
el
.
querySelector
(
'.mwe-popups-title .popups-icon'
)
.
classList
.
add
(
`popups-icon--reference-
${
type
}
`
);
el
.
querySelector
(
'.mw-parser-output'
)
.
innerHTML
=
model
.
extract
;
// Make sure to not destroy existing targets, if any
Array
.
prototype
.
forEach
.
call
(
el
.
querySelectorAll
(
'.mwe-popups-extract a[href][class~="external"]:not([target])'
),
(
a
)
=>
{
a
.
target
=
'_blank'
;
// Don't let the external site access and possibly manipulate window.opener.location
a
.
rel
=
`
${
a
.
rel
?
`
${
a
.
rel
}
`
:
''
}
noopener`
;
}
);
// We assume elements that benefit from being collapsible are to large for the popup
Array
.
prototype
.
forEach
.
call
(
el
.
querySelectorAll
(
'.mw-collapsible'
),
(
node
)
=>
{
const
otherNode
=
document
.
createElement
(
'div'
);
otherNode
.
classList
.
add
(
'mwe-collapsible-placeholder'
);
const
icon
=
document
.
createElement
(
'span'
);
icon
.
classList
.
add
(
'popups-icon'
,
'popups-icon--infoFilled'
);
const
label
=
document
.
createElement
(
'span'
);
label
.
classList
.
add
(
'mwe-collapsible-placeholder-label'
);
label
.
textContent
=
mw
.
msg
(
'cite-reference-previews-collapsible-placeholder'
);
otherNode
.
appendChild
(
icon
);
otherNode
.
appendChild
(
label
);
replaceWith
(
node
,
otherNode
);
}
);
// Undo remaining effects from the jquery.tablesorter.js plugin
const
undoHeaderSort
=
(
headerSort
)
=>
{
headerSort
.
classList
.
remove
(
'headerSort'
);
headerSort
.
removeAttribute
(
'tabindex'
);
headerSort
.
removeAttribute
(
'title'
);
};
Array
.
prototype
.
forEach
.
call
(
el
.
querySelectorAll
(
'table.sortable'
),
(
node
)
=>
{
node
.
classList
.
remove
(
'sortable'
,
'jquery-tablesorter'
);
Array
.
prototype
.
forEach
.
call
(
node
.
querySelectorAll
(
'.headerSort'
),
undoHeaderSort
);
}
);
// TODO: Do not remove this but move it up into the templateHTML constant!
const
settingsButton
=
document
.
createElement
(
'a'
);
settingsButton
.
classList
.
add
(
'cdx-button'
,
'cdx-button--fake-button'
,
'cdx-button--fake-button--enabled'
,
'cdx-button--weight-quiet'
,
'cdx-button--icon-only'
,
'mwe-popups-settings-button'
);
const
settingsIcon
=
document
.
createElement
(
'span'
);
settingsIcon
.
classList
.
add
(
'popups-icon'
,
'popups-icon--size-small'
,
'popups-icon--settings'
);
const
settingsButtonLabel
=
document
.
createElement
(
'span'
);
settingsButtonLabel
.
textContent
=
mw
.
msg
(
'popups-settings-icon-gear-title'
);
settingsButton
.
append
(
settingsIcon
);
settingsButton
.
append
(
settingsButtonLabel
);
el
.
querySelector
(
'.mwe-popups-settings'
).
appendChild
(
settingsButton
);
if
(
isTrackingEnabled
()
)
{
el
.
querySelector
(
'.mw-parser-output'
).
addEventListener
(
'click'
,
(
ev
)
=>
{
if
(
!
ev
.
target
.
matches
(
'a'
)
)
{
return
;
}
mw
.
track
(
LOGGING_SCHEMA
,
{
action
:
'clickedReferencePreviewsContentLink'
}
);
}
);
}
el
.
querySelector
(
'.mwe-popups-scroll'
).
addEventListener
(
'scroll'
,
(
e
)
=>
{
const
element
=
e
.
target
,
// We are dealing with floating point numbers here when the page is zoomed!
scrolledToBottom
=
element
.
scrollTop
>=
element
.
scrollHeight
-
element
.
clientHeight
-
1
;
if
(
isTrackingEnabled
()
)
{
if
(
!
element
.
isOpenRecorded
)
{
mw
.
track
(
LOGGING_SCHEMA
,
{
action
:
'poppedOpen'
,
scrollbarsPresent
:
element
.
scrollHeight
>
element
.
clientHeight
}
);
element
.
isOpenRecorded
=
true
;
}
if
(
element
.
scrollTop
>
0
&&
!
element
.
isScrollRecorded
)
{
mw
.
track
(
LOGGING_SCHEMA
,
{
action
:
'scrolled'
}
);
element
.
isScrollRecorded
=
true
;
}
}
if
(
!
scrolledToBottom
&&
element
.
isScrolling
)
{
return
;
}
const
extract
=
element
.
parentNode
,
hasHorizontalScroll
=
element
.
scrollWidth
>
element
.
clientWidth
,
scrollbarHeight
=
element
.
offsetHeight
-
element
.
clientHeight
,
hasVerticalScroll
=
element
.
scrollHeight
>
element
.
clientHeight
,
scrollbarWidth
=
element
.
offsetWidth
-
element
.
clientWidth
;
const
fade
=
extract
.
querySelector
(
'.mwe-popups-fade'
);
fade
.
style
.
bottom
=
hasHorizontalScroll
?
`
${
scrollbarHeight
}
px`
:
0
;
fade
.
style
.
right
=
hasVerticalScroll
?
`
${
scrollbarWidth
}
px`
:
0
;
element
.
isScrolling
=
!
scrolledToBottom
;
extract
.
classList
.
toggle
(
'mwe-popups-fade-out'
,
element
.
isScrolling
);
extract
.
setAttribute
(
'lang'
,
mw
.
config
.
get
(
'wgPageContentLanguage'
)
);
}
);
return
el
;
}
/**
* @param {ext.popups.PreviewModel} model
* @return {ext.popups.Preview}
*/
function
createReferencePreview
(
model
)
{
return
{
el
:
renderReferencePreview
(
model
),
hasThumbnail
:
false
,
isTall
:
false
};
}
module
.
exports
=
createReferencePreview
;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Oct 3, 17:47 (22 h, 13 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
41/44/37e316a29cbdb9949051fac4e308
Default Alt Text
createReferencePreview.js (6 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment