diff --git a/jsdoc.js b/jsdoc.js index 1c6152668f6..12290e7ed5d 100644 --- a/jsdoc.js +++ b/jsdoc.js @@ -14,6 +14,7 @@ module.exports = { ], source: { include: [ + 'resources/src/mediawiki.page.ready', 'resources/src/mediawiki.Title', 'resources/src/mediawiki.cookie', 'resources/src/mediawiki.storage.js', @@ -42,7 +43,6 @@ module.exports = { 'resources/src/mediawiki.page.media.js', 'resources/src/jquery/*', 'resources/src/jquery.spinner', - 'resources/src/mediawiki.page.ready', 'resources/src/jquery.tablesorter', 'resources/src/mediawiki.page.watch.ajax', 'resources/src/mediawiki.ForeignApi', @@ -132,6 +132,7 @@ module.exports = { Array: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array', Blob: 'https://developer.mozilla.org/en-US/docs/Web/API/Blob', CSSStyleSheet: 'https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet', + Event: 'https://developer.mozilla.org/en-US/docs/Web/API/Event', File: 'https://developer.mozilla.org/en-US/docs/Web/API/File', HTMLElement: 'https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement', HTMLInputElement: 'https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement', @@ -140,6 +141,7 @@ module.exports = { 'jQuery.fn': 'https://api.jquery.com/jQuery/', 'jQuery.Event': 'https://api.jquery.com/Types/#Event', 'jQuery.Promise': 'https://api.jquery.com/Types/#Promise', + Node: 'https://developer.mozilla.org/en-US/docs/Web/API/Node', Promise: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise', Set: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set', URLSearchParams: 'https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams' diff --git a/resources/src/jsdoc.types.js b/resources/src/jsdoc.types.js index f73d5254c93..e19f66191e6 100644 --- a/resources/src/jsdoc.types.js +++ b/resources/src/jsdoc.types.js @@ -4,51 +4,6 @@ * @ignore */ -/** - * The following commonly used hooks are documented here temporarily. - * TODO: Move hook documentation to mediawiki.page.ready.js when that is migrated to JSDoc. - */ - -/** - * Fired when wiki content has been added to the DOM. - * - * This should only be fired after $content has been attached. - * - * This includes the ready event on a page load (including post-edit loads) - * and when content has been previewed with LivePreview. - * - * @event ~'wikipage.content' - * @memberof Hooks - * @param {jQuery} $content The most appropriate element containing the content, such as - * `#mw-content-text` (regular content root) or `#wikiPreview` (live preview root) - */ - -/** - * Fired when categories are being added to the DOM - * - * It is encouraged to fire it before the main DOM is changed (when `$content` - * is still detached). However, this order is not defined either way, so you - * should only rely on `$content` itself. - * - * This includes the ready event on a page load (including post-edit loads) - * and when content has been previewed with LivePreview. - * - * @event ~'wikipage.categories' - * @memberof Hooks - * @param {jQuery} $content The most appropriate element containing the content, such as `.catlinks` - */ - -/** - * Fired when a trusted UI element to perform a logout has been activated. - * - * This will end the user session, and either redirect to the given URL - * on success, or queue an error message via {@link mw.notification}. - * - * @event ~'skin.logout' - * @memberof Hooks - * @param {string} href Full URL - */ - /** * MediaWiki includes the jQuery library. This is extended by a series of plugins. * diff --git a/resources/src/mediawiki.page.ready/checkboxHack.js b/resources/src/mediawiki.page.ready/checkboxHack.js index a4ef2c9208d..c41d1b5986d 100644 --- a/resources/src/mediawiki.page.ready/checkboxHack.js +++ b/resources/src/mediawiki.page.ready/checkboxHack.js @@ -1,4 +1,7 @@ -/*! +/** + * Utility library for managing components using the [CSS checkbox hack]{@link https://css-tricks.com/the-checkbox-hack/}. + * To access call ```require('mediawiki.page.ready').checkboxHack```. + * * The checkbox hack works without JavaScript for graphical user-interface users, but relies on * enhancements to work well for screen reader users. This module provides required a11y * interactivity for updating the `aria-expanded` accessibility state, and optional enhancements @@ -109,20 +112,20 @@ * described as a succeeding sibling of the input, but this requires a mixin implementation that * duplicates the rules for each relation selector. * - * Exposed APIs should be considered stable. @ignore is used for JSDoc compatibility (see T138401). + * Exposed APIs should be considered stable. * * Accompanying checkbox hack styles are tracked in T252774. * * [0]: https://developer.mozilla.org/docs/Web/HTML/Element/details + * + * @namespace CheckboxHack */ - /** * Revise the button's `aria-expanded` state to match the checked state. * + * @memberof CheckboxHack * @param {HTMLInputElement} checkbox * @param {HTMLElement} button - * @return {void} - * @ignore */ function updateAriaExpanded( checkbox, button ) { if ( button ) { @@ -155,13 +158,12 @@ function updateAriaExpanded( checkbox, button ) { * * @param {HTMLInputElement} checkbox * @param {boolean} checked - * @return {void} * @ignore */ function setCheckedState( checkbox, checked ) { - /** @type {Event} @ignore */ checkbox.checked = checked; // Chrome and Firefox sends the builtin Event with .bubbles == true and .composed == true. + /** @type {Event} */ var e; if ( typeof Event === 'function' ) { e = new Event( 'input', { bubbles: true, composed: true } ); @@ -203,7 +205,6 @@ function containsEventTarget( checkbox, button, target, event ) { * @param {HTMLElement} button * @param {Node} target * @param {Event} event - * @return {void} * @ignore */ function dismissIfExternalEventTarget( checkbox, button, target, event ) { @@ -215,10 +216,10 @@ function dismissIfExternalEventTarget( checkbox, button, target, event ) { /** * Update the `aria-expanded` attribute based on checkbox state (target visibility) changes. * + * @memberof CheckboxHack * @param {HTMLInputElement} checkbox * @param {HTMLElement} button * @return {function(): void} Cleanup function that removes the added event listeners. - * @ignore */ function bindUpdateAriaExpandedOnInput( checkbox, button ) { if ( button ) { @@ -237,10 +238,10 @@ function bindUpdateAriaExpandedOnInput( checkbox, button ) { /** * Manually change the checkbox state to avoid a focus change when using a pointing device. * + * @memberof CheckboxHack * @param {HTMLInputElement} checkbox * @param {HTMLElement} button * @return {function(): void} Cleanup function that removes the added event listeners. - * @ignore */ function bindToggleOnClick( checkbox, button ) { function listener( event ) { @@ -259,20 +260,20 @@ function bindToggleOnClick( checkbox, button ) { /** * Manually change the checkbox state when the button is focused and SPACE is pressed. * - * @deprecated + * @deprecated Use `bindToggleOnEnter` instead. + * @memberof CheckboxHack * @param {HTMLInputElement} checkbox * @param {HTMLElement} button * @return {function(): void} Cleanup function that removes the added event listeners. - * @ignore */ function bindToggleOnSpaceEnter( checkbox, button ) { mw.log.warn( '[1.38] bindToggleOnSpaceEnter is deprecated. Use `bindToggleOnEnter` instead.' ); - function isEnterOrSpace( /** @type {KeyboardEvent} @ignore */ event ) { + function isEnterOrSpace( /** @type {KeyboardEvent} */ event ) { return event.key === ' ' || event.key === 'Enter'; } - function onKeydown( /** @type {KeyboardEvent} @ignore */ event ) { + function onKeydown( /** @type {KeyboardEvent} */ event ) { // Only handle SPACE and ENTER. if ( !isEnterOrSpace( event ) ) { return; @@ -285,7 +286,7 @@ function bindToggleOnSpaceEnter( checkbox, button ) { event.preventDefault(); } - function onKeyup( /** @type {KeyboardEvent} @ignore */ event ) { + function onKeyup( /** @type {KeyboardEvent} */ event ) { // Only handle SPACE and ENTER. if ( !isEnterOrSpace( event ) ) { return; @@ -310,12 +311,12 @@ function bindToggleOnSpaceEnter( checkbox, button ) { /** * Manually change the checkbox state when the button is focused and Enter is pressed. * + * @memberof CheckboxHack * @param {HTMLInputElement} checkbox * @return {function(): void} Cleanup function that removes the added event listeners. - * @ignore */ function bindToggleOnEnter( checkbox ) { - function onKeyup( /** @type {KeyboardEvent} @ignore */ event ) { + function onKeyup( /** @type {KeyboardEvent} */ event ) { // Only handle ENTER. if ( event.key !== 'Enter' ) { return; @@ -335,12 +336,12 @@ function bindToggleOnEnter( checkbox ) { * Dismiss the target when clicking elsewhere and update the `aria-expanded` attribute based on * checkbox state (target visibility). * - * @param {Window} window + * @memberof CheckboxHack + * @param {window} window * @param {HTMLInputElement} checkbox * @param {HTMLElement} button * @param {Node} target * @return {function(): void} Cleanup function that removes the added event listeners. - * @ignore */ function bindDismissOnClickOutside( window, checkbox, button, target ) { var listener = dismissIfExternalEventTarget.bind( undefined, checkbox, button, target ); @@ -355,12 +356,12 @@ function bindDismissOnClickOutside( window, checkbox, button, target ) { * Dismiss the target when focusing elsewhere and update the `aria-expanded` attribute based on * checkbox state (target visibility). * - * @param {Window} window + * @param {window} window * @param {HTMLInputElement} checkbox * @param {HTMLElement} button * @param {Node} target * @return {function(): void} Cleanup function that removes the added event listeners. - * @ignore + * @memberof CheckboxHack */ function bindDismissOnFocusLoss( window, checkbox, button, target ) { // If focus is given to any element outside the target, dismiss the target. Setting a focusout @@ -380,7 +381,7 @@ function bindDismissOnFocusLoss( window, checkbox, button, target ) { * @param {HTMLInputElement} checkbox * @param {Node} target * @return {function(): void} Cleanup function that removes the added event listeners. - * @ignore + * @memberof CheckboxHack */ function bindDismissOnClickLink( checkbox, target ) { function dismissIfClickLinkEvent( event ) { @@ -404,14 +405,14 @@ function bindDismissOnClickLink( checkbox, target ) { * This function calls the other bind* functions and is the only expected interaction for most use * cases. It's constituents are provided distinctly for the other use cases. * - * @param {Window} window + * @memberof CheckboxHack + * @param {window} window * @param {HTMLInputElement} checkbox The underlying hidden checkbox that controls target * visibility. * @param {HTMLElement} button The visible label icon associated with the checkbox. This button * toggles the state of the underlying checkbox. * @param {Node} target The Node to toggle visibility of based on checkbox state. * @return {function(): void} Cleanup function that removes the added event listeners. - * @ignore */ function bind( window, checkbox, button, target ) { var cleanups = [ @@ -431,13 +432,13 @@ function bind( window, checkbox, button, target ) { } module.exports = { - updateAriaExpanded: updateAriaExpanded, - bindUpdateAriaExpandedOnInput: bindUpdateAriaExpandedOnInput, - bindToggleOnClick: bindToggleOnClick, - bindToggleOnSpaceEnter: bindToggleOnSpaceEnter, - bindToggleOnEnter: bindToggleOnEnter, - bindDismissOnClickOutside: bindDismissOnClickOutside, - bindDismissOnFocusLoss: bindDismissOnFocusLoss, - bindDismissOnClickLink: bindDismissOnClickLink, - bind: bind + updateAriaExpanded, + bindUpdateAriaExpandedOnInput, + bindToggleOnClick, + bindToggleOnSpaceEnter, + bindToggleOnEnter, + bindDismissOnClickOutside, + bindDismissOnFocusLoss, + bindDismissOnClickLink, + bind }; diff --git a/resources/src/mediawiki.page.ready/checkboxShift.js b/resources/src/mediawiki.page.ready/checkboxShift.js index 6769b6c97ff..703aaa34034 100644 --- a/resources/src/mediawiki.page.ready/checkboxShift.js +++ b/resources/src/mediawiki.page.ready/checkboxShift.js @@ -1,12 +1,9 @@ -/** - * @private - * @class mw.plugin.page.ready - */ /** * Enable checkboxes to be checked or unchecked in a row by clicking one, * holding shift and clicking another one. * * @method checkboxShift + * @memberof mediawiki.page.module:ready * @param {jQuery} $box */ module.exports = function ( $box ) { diff --git a/resources/src/mediawiki.page.ready/ready.js b/resources/src/mediawiki.page.ready/ready.js index c8394bb7054..257b13ba86c 100644 --- a/resources/src/mediawiki.page.ready/ready.js +++ b/resources/src/mediawiki.page.ready/ready.js @@ -86,8 +86,8 @@ $( function () { /** * Fired when indicators are being added to the DOM * - * @event wikipage_indicators - * @member mw.hook + * @event ~'wikipage.indicators' + * @memberof Hooks * @param {jQuery} $content jQuery object with the elements of the indicators */ mw.hook( 'wikipage.indicators' ).fire( $( node.children ) ); @@ -105,12 +105,11 @@ $( function () { * This includes the ready event on a page load (including post-edit loads) * and when content has been previewed with LivePreview. * - * @event wikipage_content - * @member mw.hook + * @event ~'wikipage.content' + * @memberof Hooks * @param {jQuery} $content The most appropriate element containing the content, * such as #mw-content-text (regular content root) or #wikiPreview (live preview * root) - * @todo Remove duplicate doc block in jsdoc.types.js */ mw.hook( 'wikipage.content' ).fire( $content ); } @@ -127,11 +126,10 @@ $( function () { * This includes the ready event on a page load (including post-edit loads) * and when content has been previewed with LivePreview. * - * @event wikipage_categories - * @member mw.hook + * @event ~'wikipage.categories' + * @memberof Hooks * @param {jQuery} $content The most appropriate element containing the content, * such as .catlinks - * @todo Remove duplicate doc block in jsdoc.types.js */ mw.hook( 'wikipage.categories' ).fire( $nodes ); } @@ -141,13 +139,12 @@ $( function () { /** * Fired when the diff is added to a page containing a diff * - * Similar to the {@link mw.hook#event-wikipage_content wikipage.content hook} + * Similar to the {@link Hooks~'wikipage.content' wikipage.content hook} * $diff may still be detached when the hook is fired. * - * @event wikipage_diff - * @member mw.hook + * @event ~'wikipage.diff' + * @memberof Hooks * @param {jQuery} $diff The root element of the MediaWiki diff (`table.diff`). - * @todo Remove duplicate doc block in jsdoc.types.js */ mw.hook( 'wikipage.diff' ).fire( $nodes.eq( 0 ) ); } @@ -176,10 +173,9 @@ $( function () { * This will end the user session, and either redirect to the given URL * on success, or queue an error message via mw.notification. * - * @event skin_logout - * @member mw.hook + * @event ~'skin.logout' + * @memberof Hooks * @param {string} href Full URL - * @todo Remove duplicate doc block in jsdoc.types.js */ var LOGOUT_EVENT = 'skin.logout'; function logoutViaPost( href ) { @@ -213,11 +209,6 @@ $( function () { teleportTarget.attach(); } ); -/** - * @class mw.plugin.page.ready - * @singleton - */ - /** * @private * @param {HTMLElement} element @@ -231,6 +222,7 @@ function isSearchInput( element ) { /** * Load a given module when a search input is focused. * + * @memberof mediawiki.page.module:ready * @param {string} moduleName Name of a module */ function loadSearchModule( moduleName ) { @@ -294,8 +286,17 @@ try { } } catch ( err ) {} +/** + * @exports mediawiki.page.ready + */ module.exports = { - loadSearchModule: loadSearchModule, + loadSearchModule, + /** @type {CheckboxHack} */ checkboxHack: require( './checkboxHack.js' ), + /** + * A container for displaying elements that overlay the page e.g. dialogs. + * + * @type {HTMLElement} + */ teleportTarget: teleportTarget.target };