mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Popups
synced 2024-11-27 17:00:37 +00:00
694b96a19f
Used for tracking baseline stats in the Cite extension. Also fixed the wireing of the Reference Preview type constant so that the settings can be tracked. Not sure where this should go best in the new code. Bug: T353798 Change-Id: I1c434f0098ae23bd62256686a658e3d5ef7f70b9
1 line
20 KiB
JSON
1 line
20 KiB
JSON
{"version":3,"file":"referencePreviews.js","mappings":"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","sources":["/w/extensions/Popups/./src/ext.popups.referencePreviews/constants.js","/w/extensions/Popups/./src/ext.popups.referencePreviews/referencePreviews.js","/w/extensions/Popups/./src/ext.popups.referencePreviews/createReferencePreview.js","/w/extensions/Popups/./src/ext.popups.referencePreviews/setUserConfigFlags.js","/w/extensions/Popups/./src/ext.popups.referencePreviews/index.js","/w/extensions/Popups/./src/ext.popups.referencePreviews/isReferencePreviewsEnabled.js","/w/extensions/Popups/./src/ext.popups.referencePreviews/createReferenceGateway.js"],"sourcesContent":["export const TYPE_REFERENCE = 'reference';\nexport const FETCH_DELAY_REFERENCE_TYPE = 150; // ms.\n","let isTracking = false;\n\nexport const LOGGING_SCHEMA = 'event.ReferencePreviewsPopups';\n\n/**\n * Run once the preview is initialized.\n */\nexport function initReferencePreviewsInstrumentation() {\n\tif ( mw.config.get( 'wgPopupsReferencePreviews' ) &&\n\t\tnavigator.sendBeacon &&\n\t\tmw.config.get( 'wgIsArticle' ) &&\n\t\t!isTracking\n\t) {\n\t\tisTracking = true;\n\t\tmw.track( LOGGING_SCHEMA, { action: 'pageview' } );\n\t}\n}\n\nexport function isTrackingEnabled() {\n\treturn isTracking;\n}\n","/**\n * @module referencePreview\n */\nimport { isTrackingEnabled, LOGGING_SCHEMA } from './referencePreviews';\n\nconst TEMPLATE = document.createElement( 'template' );\nTEMPLATE.innerHTML = `\n<div class=\"mwe-popups mwe-popups mwe-popups-type-reference\" aria-hidden>\n\t<div class=\"mwe-popups-container\">\n\t\t<div class=\"mwe-popups-extract\">\n\t\t\t<div class=\"mwe-popups-scroll\">\n\t\t\t\t<strong class=\"mwe-popups-title\">\n\t\t\t\t\t<span class=\"popups-icon\"></span>\n\t\t\t\t\t<span class=\"mwe-popups-title-placeholder\"></span>\n\t\t\t\t</strong>\n\t\t\t\t<bdi><div class=\"mw-parser-output\"></div></bdi>\n\t\t\t</div>\n\t\t\t<div class=\"mwe-popups-fade\"></div>\n\t\t</div>\n\t\t<footer>\n\t\t\t<div class=\"mwe-popups-settings\"></div>\n\t\t</footer>\n\t</div>\n</div>`;\n\n/**\n * @param {HTMLElement} node\n * @param {HTMLElement|string} htmlOrOtherNode\n */\nconst replaceWith = ( node, htmlOrOtherNode ) => {\n\tif ( typeof htmlOrOtherNode === 'string' ) {\n\t\tnode.insertAdjacentHTML( 'afterend', htmlOrOtherNode );\n\t} else {\n\t\tnode.parentNode.appendChild( htmlOrOtherNode );\n\t}\n\tnode.remove();\n};\n\n/**\n * @param {ext.popups.ReferencePreviewModel} model\n * @return {jQuery}\n */\nfunction renderReferencePreview(\n\tmodel\n) {\n\tconst type = model.referenceType || 'generic';\n\t// The following messages are used here:\n\t// * popups-refpreview-book\n\t// * popups-refpreview-journal\n\t// * popups-refpreview-news\n\t// * popups-refpreview-note\n\t// * popups-refpreview-web\n\tlet titleMsg = mw.message( `popups-refpreview-${ type }` );\n\tif ( !titleMsg.exists() ) {\n\t\ttitleMsg = mw.message( 'popups-refpreview-reference' );\n\t}\n\n\tconst el = TEMPLATE.content.cloneNode( true ).children[ 0 ];\n\n\treplaceWith(\n\t\tel.querySelector( '.mwe-popups-title-placeholder' ),\n\t\tmw.html.escape( titleMsg.text() )\n\t);\n\t// The following classes are used here:\n\t// * popups-icon--reference-generic\n\t// * popups-icon--reference-book\n\t// * popups-icon--reference-journal\n\t// * popups-icon--reference-news\n\t// * popups-icon--reference-note\n\t// * popups-icon--reference-web\n\tel.querySelector( '.mwe-popups-title .popups-icon' )\n\t\t.classList.add( `popups-icon--reference-${ type }` );\n\tel.querySelector( '.mw-parser-output' )\n\t\t.innerHTML = model.extract;\n\n\t// Make sure to not destroy existing targets, if any\n\tArray.prototype.forEach.call(\n\t\tel.querySelectorAll( '.mwe-popups-extract a[href][class~=\"external\"]:not([target])' ),\n\t\t( a ) => {\n\t\t\ta.target = '_blank';\n\t\t\t// Don't let the external site access and possibly manipulate window.opener.location\n\t\t\ta.rel = `${ a.rel ? `${ a.rel } ` : '' }noopener`;\n\t\t}\n\t);\n\n\t// We assume elements that benefit from being collapsible are to large for the popup\n\tArray.prototype.forEach.call( el.querySelectorAll( '.mw-collapsible' ), ( node ) => {\n\t\tconst otherNode = document.createElement( 'div' );\n\t\totherNode.classList.add( 'mwe-collapsible-placeholder' );\n\t\tconst icon = document.createElement( 'span' );\n\t\ticon.classList.add( 'popups-icon', 'popups-icon--infoFilled' );\n\t\tconst label = document.createElement( 'span' );\n\t\tlabel.classList.add( 'mwe-collapsible-placeholder-label' );\n\t\tlabel.textContent = mw.msg( 'popups-refpreview-collapsible-placeholder' );\n\t\totherNode.appendChild( icon );\n\t\totherNode.appendChild( label );\n\t\treplaceWith( node, otherNode );\n\t} );\n\n\t// Undo remaining effects from the jquery.tablesorter.js plugin\n\tconst undoHeaderSort = ( headerSort ) => {\n\t\theaderSort.classList.remove( 'headerSort' );\n\t\theaderSort.removeAttribute( 'tabindex' );\n\t\theaderSort.removeAttribute( 'title' );\n\t};\n\tArray.prototype.forEach.call( el.querySelectorAll( 'table.sortable' ), ( node ) => {\n\t\tnode.classList.remove( 'sortable', 'jquery-tablesorter' );\n\t\tArray.prototype.forEach.call( node.querySelectorAll( '.headerSort' ), undoHeaderSort );\n\t} );\n\n\t// TODO: Do not remove this but move it up into the templateHTML constant!\n\tconst settingsButton = document.createElement( 'a' );\n\tsettingsButton.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' );\n\tconst settingsIcon = document.createElement( 'span' );\n\tsettingsIcon.classList.add( 'popups-icon', 'popups-icon--size-small', 'popups-icon--settings' );\n\tconst settingsButtonLabel = document.createElement( 'span' );\n\tsettingsButtonLabel.textContent = mw.msg( 'popups-settings-icon-gear-title' );\n\tsettingsButton.append( settingsIcon );\n\tsettingsButton.append( settingsButtonLabel );\n\tel.querySelector( '.mwe-popups-settings' ).appendChild( settingsButton );\n\n\tif ( isTrackingEnabled() ) {\n\t\tel.querySelector( '.mw-parser-output' ).addEventListener( 'click', ( ev ) => {\n\t\t\tif ( !ev.target.matches( 'a' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tmw.track( LOGGING_SCHEMA, {\n\t\t\t\taction: 'clickedReferencePreviewsContentLink'\n\t\t\t} );\n\t\t} );\n\t}\n\n\tel.querySelector( '.mwe-popups-scroll' ).addEventListener( 'scroll', function ( e ) {\n\t\tconst element = e.target,\n\t\t\t// We are dealing with floating point numbers here when the page is zoomed!\n\t\t\tscrolledToBottom = element.scrollTop >= element.scrollHeight - element.clientHeight - 1;\n\n\t\tif ( isTrackingEnabled() ) {\n\t\t\tif ( !element.isOpenRecorded ) {\n\t\t\t\tmw.track( LOGGING_SCHEMA, {\n\t\t\t\t\taction: 'poppedOpen',\n\t\t\t\t\tscrollbarsPresent: element.scrollHeight > element.clientHeight\n\t\t\t\t} );\n\t\t\t\telement.isOpenRecorded = true;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\telement.scrollTop > 0 &&\n\t\t\t\t!element.isScrollRecorded\n\t\t\t) {\n\t\t\t\tmw.track( LOGGING_SCHEMA, {\n\t\t\t\t\taction: 'scrolled'\n\t\t\t\t} );\n\t\t\t\telement.isScrollRecorded = true;\n\t\t\t}\n\t\t}\n\n\t\tif ( !scrolledToBottom && element.isScrolling ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst extract = element.parentNode,\n\t\t\thasHorizontalScroll = element.scrollWidth > element.clientWidth,\n\t\t\tscrollbarHeight = element.offsetHeight - element.clientHeight,\n\t\t\thasVerticalScroll = element.scrollHeight > element.clientHeight,\n\t\t\tscrollbarWidth = element.offsetWidth - element.clientWidth;\n\t\tconst fade = extract.querySelector( '.mwe-popups-fade' );\n\t\tfade.style.bottom = hasHorizontalScroll ? `${ scrollbarHeight }px` : 0;\n\t\tfade.style.right = hasVerticalScroll ? `${ scrollbarWidth }px` : 0;\n\n\t\telement.isScrolling = !scrolledToBottom;\n\t\textract.classList.toggle( 'mwe-popups-fade-out', element.isScrolling );\n\t\textract.setAttribute( 'lang', mw.config.get( 'wgPageContentLanguage' ) );\n\t} );\n\n\treturn el;\n}\n\n/**\n * @param {ext.popups.ReferencePreviewModel} model\n * @return {ext.popups.Preview}\n */\nexport default function createReferencePreview( model ) {\n\treturn {\n\t\tel: renderReferencePreview( model ),\n\t\thasThumbnail: false,\n\t\tisTall: false\n\t};\n}\n","/**\n * @module setUserConfigFlags\n */\n\n/**\n * Same as in includes/PopupsContext.php\n */\nconst REF_TOOLTIPS_ENABLED = 2,\n\tREFERENCE_PREVIEWS_ENABLED = 4;\n\n/**\n * Decodes the bitmask that represents preferences to the related config options.\n *\n * @param {mw.Map} config\n */\nexport default function setUserConfigFlags( config ) {\n\tconst popupsFlags = parseInt( config.get( 'wgPopupsFlags' ), 10 );\n\n\t/* eslint-disable no-bitwise */\n\tconfig.set(\n\t\t'wgPopupsConflictsWithRefTooltipsGadget',\n\t\t!!( popupsFlags & REF_TOOLTIPS_ENABLED )\n\t);\n\tconfig.set(\n\t\t'wgPopupsReferencePreviews',\n\t\t!!( popupsFlags & REFERENCE_PREVIEWS_ENABLED )\n\t);\n\t/* eslint-enable no-bitwise */\n}\n","import isReferencePreviewsEnabled from './isReferencePreviewsEnabled';\nimport { initReferencePreviewsInstrumentation } from './referencePreviews';\nimport createReferenceGateway from './createReferenceGateway';\nimport renderFn from './createReferencePreview';\nimport { TYPE_REFERENCE, FETCH_DELAY_REFERENCE_TYPE } from './constants';\nimport setUserConfigFlags from './setUserConfigFlags';\n\nsetUserConfigFlags( mw.config );\nconst referencePreviewsState = isReferencePreviewsEnabled(\n\tmw.user, mw.popups.isEnabled,\n\tmw.config\n);\nconst gateway = createReferenceGateway();\n\n// For tracking baseline stats in the Cite extension https://phabricator.wikimedia.org/T353798\n// FIXME: This might be obsolete when the code moves to the Cite extension and the tracking there\n// can check that state differently.\nmw.config.set( 'wgPopupsReferencePreviewsVisible', !!referencePreviewsState );\n\nwindow.refPreviews = referencePreviewsState !== null ? {\n\ttype: TYPE_REFERENCE,\n\tselector: '#mw-content-text .reference a[ href*=\"#\" ]',\n\tdelay: FETCH_DELAY_REFERENCE_TYPE,\n\tgateway,\n\trenderFn,\n\tinit: () => {\n\t\tinitReferencePreviewsInstrumentation();\n\t}\n} : null;\n","import { TYPE_REFERENCE } from './constants.js';\n\n/**\n * @module isReferencePreviewsEnabled\n */\n\n/**\n * Given the global state of the application, creates a function that gets\n * whether or not the user should have Reference Previews enabled.\n *\n * @param {mw.User} user The `mw.user` singleton instance\n * @param {Function} isPreviewTypeEnabled check whether preview has been disabled or enabled.\n * @param {mw.Map} config\n *\n * @return {boolean|null} Null when there is no way the popup type can be enabled at run-time.\n */\nexport default function isReferencePreviewsEnabled( user, isPreviewTypeEnabled, config ) {\n\t// TODO: This and the final `mw.user.options` check are currently redundant. Only this here\n\t// should be removed when the wgPopupsReferencePreviews feature flag is not needed any more.\n\tif ( !config.get( 'wgPopupsReferencePreviews' ) ) {\n\t\treturn null;\n\t}\n\n\t// T265872: Unavailable when in conflict with (one of the) reference tooltips gadgets.\n\tif ( config.get( 'wgPopupsConflictsWithRefTooltipsGadget' ) ||\n\t\tconfig.get( 'wgPopupsConflictsWithNavPopupGadget' ) ||\n\t\t// T243822: Temporarily disabled in the mobile skin\n\t\tconfig.get( 'skin' ) === 'minerva'\n\t) {\n\t\treturn null;\n\t}\n\n\tif ( user.isAnon() ) {\n\t\treturn isPreviewTypeEnabled( TYPE_REFERENCE );\n\t}\n\n\t// Registered users never can enable popup types at run-time.\n\treturn user.options.get( 'popups-reference-previews' ) === '1' ? true : null;\n}\n","/**\n * @module gateway/reference\n */\n\nimport { TYPE_REFERENCE } from './constants.js';\n\n/**\n * @return {Gateway}\n */\nexport default function createReferenceGateway() {\n\n\t/**\n\t * @param {string} id\n\t * @return {HTMLElement}\n\t */\n\tfunction scrapeReferenceText( id ) {\n\t\tconst idSelector = `#${ CSS.escape( id ) }`;\n\n\t\t/**\n\t\t * Same alternative selectors with and without mw-… as in the RESTbased endpoint.\n\t\t *\n\t\t * @see https://phabricator.wikimedia.org/diffusion/GMOA/browse/master/lib/transformations/references/structureReferenceListContent.js$138\n\t\t */\n\t\treturn document.querySelector( `${ idSelector } .mw-reference-text, ${ idSelector } .reference-text` );\n\t}\n\n\t/**\n\t * Attempts to find a single reference type identifier, limited to a list of known types.\n\t * - When a `class=\"…\"` attribute mentions multiple known types, the last one is used, following\n\t * CSS semantics.\n\t * - When there are multiple <cite> tags, the first with a known type is used.\n\t *\n\t * @param {HTMLElement} referenceText\n\t * @return {string|null}\n\t */\n\tfunction scrapeReferenceType( referenceText ) {\n\t\tconst KNOWN_TYPES = [ 'book', 'journal', 'news', 'note', 'web' ];\n\t\tlet type = null;\n\t\tconst citeTags = referenceText.querySelectorAll( 'cite[class]' );\n\t\tArray.prototype.forEach.call( citeTags, ( element ) => {\n\t\t\t// don't need to keep scanning if one is found.\n\t\t\tif ( type ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst classNames = element.className.split( /\\s+/ );\n\t\t\tfor ( let i = classNames.length; i--; ) {\n\t\t\t\tif ( KNOWN_TYPES.indexOf( classNames[ i ] ) !== -1 ) {\n\t\t\t\t\ttype = classNames[ i ];\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t\treturn type;\n\t}\n\n\t/**\n\t * @param {mw.Title} title\n\t * @param {HTMLAnchorElement} el\n\t * @return {AbortPromise<ReferencePreviewModel>}\n\t */\n\tfunction fetchPreviewForTitle( title, el ) {\n\t\t// Need to encode the fragment again as mw.Title returns it as decoded text\n\t\tconst id = title.getFragment().replace( / /g, '_' ),\n\t\t\treferenceNode = scrapeReferenceText( id );\n\n\t\tif ( !referenceNode ||\n\t\t\t// Skip references that don't contain anything but whitespace, e.g. a single \n\t\t\t( !referenceNode.textContent.trim() && !referenceNode.children.length )\n\t\t) {\n\t\t\treturn Promise.reject(\n\t\t\t\t// Required to set `showNullPreview` to false and not open an error popup\n\t\t\t\t{ textStatus: 'abort', textContext: 'Footnote not found or empty', xhr: { readyState: 0 } }\n\t\t\t);\n\t\t}\n\n\t\tconst model = {\n\t\t\turl: `#${ id }`,\n\t\t\textract: referenceNode.innerHTML,\n\t\t\ttype: TYPE_REFERENCE,\n\t\t\treferenceType: scrapeReferenceType( referenceNode ),\n\t\t\t// Note: Even the top-most HTMLHtmlElement is guaranteed to have a parent.\n\t\t\tsourceElementId: el.parentNode.id\n\t\t};\n\n\t\t// Make promise abortable.\n\t\tconst promise = Promise.resolve( model );\n\t\tpromise.abort = () => {};\n\t\treturn promise;\n\t}\n\n\treturn {\n\t\tfetchPreviewForTitle\n\t};\n}\n"],"names":["TYPE_REFERENCE","isTracking","LOGGING_SCHEMA","isTrackingEnabled","TEMPLATE","document","createElement","innerHTML","config","popupsFlags","replaceWith","node","htmlOrOtherNode","insertAdjacentHTML","parentNode","appendChild","remove","renderReferencePreview","model","type","referenceType","titleMsg","mw","message","concat","exists","el","content","cloneNode","children","querySelector","html","escape","text","classList","add","extract","Array","prototype","forEach","call","querySelectorAll","a","target","rel","otherNode","icon","label","textContent","msg","undoHeaderSort","headerSort","removeAttribute","settingsButton","settingsIcon","settingsButtonLabel","append","addEventListener","ev","matches","track","action","e","element","scrolledToBottom","scrollTop","scrollHeight","clientHeight","isOpenRecorded","scrollbarsPresent","isScrollRecorded","isScrolling","hasHorizontalScroll","scrollWidth","clientWidth","scrollbarHeight","offsetHeight","hasVerticalScroll","scrollbarWidth","offsetWidth","fade","style","bottom","right","toggle","setAttribute","get","parseInt","set","referencePreviewsState","user","isPreviewTypeEnabled","isAnon","options","isReferencePreviewsEnabled","popups","isEnabled","gateway","fetchPreviewForTitle","title","id","getFragment","replace","referenceNode","idSelector","CSS","scrapeReferenceText","trim","length","Promise","reject","textStatus","textContext","xhr","readyState","referenceText","KNOWN_TYPES","citeTags","url","classNames","className","split","i","indexOf","sourceElementId","promise","resolve","abort","window","refPreviews","selector","delay","renderFn","hasThumbnail","isTall","init","navigator","sendBeacon"],"sourceRoot":""} |