diff --git a/.eslintrc.json b/.eslintrc.json index f77c254b5..cdfad6241 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -2,6 +2,6 @@ "root": true, "extends": [ "wikimedia/server", - "wikimedia/jsduck" + "wikimedia/jsdoc" ] } diff --git a/.jsdoc.json b/.jsdoc.json new file mode 100644 index 000000000..2dee61992 --- /dev/null +++ b/.jsdoc.json @@ -0,0 +1,103 @@ +{ + "opts": { + "encoding": "utf8", + "destination": "docs", + "package": "package.json", + "readme": "README.md", + "pedantic": false, + "private": true, + "recurse": true, + "template": "node_modules/jsdoc-wmf-theme", + "class-hierarchy": { + "showList": true + } + }, + "plugins": [ + "plugins/markdown", + "node_modules/jsdoc-wmf-theme/plugins/allow-dots-in-modules", + "node_modules/jsdoc-wmf-theme/plugins/betterlinks", + "node_modules/jsdoc-wmf-theme/plugins/summarize", + "node_modules/jsdoc-class-hierarchy" + ], + "source": { + "include": [ "modules" ] + }, + "templates": { + "cleverLinks": true, + "default": { + "useLongnameInNav": true + }, + "wmf": { + "maintitle": "Echo", + "repository": "https://gerrit.wikimedia.org/g/mediawiki/extensions/Echo/", + "linkMap": { + "Mixed": "#", + + "Array": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array", + "Error": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error", + "Object": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object", + "Promise": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise", + + "Overlay": "https://doc.wikimedia.org/MobileFrontend/master/js/js/Overlay.html", + "View": "https://doc.wikimedia.org/MobileFrontend/master/js/js/View.html", + + "Blob": "https://developer.mozilla.org/en-US/docs/Web/API/Blob", + "DataTransfer": "https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer", + "DataTransferItem": "https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem", + "Event": "https://developer.mozilla.org/en-US/docs/Web/API/Event", + "HTMLDocument": "https://developer.mozilla.org/en-US/docs/Web/API/HTMLDocument", + "HTMLElement": "https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement", + "KeyboardEvent": "https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent", + "MutationRecord": "https://developer.mozilla.org/en-US/docs/Web/API/MutationRecord", + "Node": "https://developer.mozilla.org/en-US/docs/Web/API/Node", + "NodeList": "https://developer.mozilla.org/en-US/docs/Web/API/NodeList", + "Range": "https://developer.mozilla.org/en-US/docs/Web/API/Range", + "Selection": "https://developer.mozilla.org/en-US/docs/Web/API/Selection", + + "mw.Api": "https://doc.wikimedia.org/mediawiki-core/master/js/mw.Api.html", + + "OO.EmitterList": "https://doc.wikimedia.org/oojs/master/OO.EmitterList.html", + "OO.EventEmitter": "https://doc.wikimedia.org/oojs/master/OO.EventEmitter.html", + "OO.Factory": "https://doc.wikimedia.org/oojs/master/OO.Factory.html", + "OO.Registry": "https://doc.wikimedia.org/oojs/master/OO.Registry.html", + "OO.SortedEmitterList": "https://doc.wikimedia.org/oojs/master/OO.SortedEmitterList.html", + + "OO.ui.mixin.GroupElement": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.mixin.GroupElement.html", + "OO.ui.mixin.IconElement": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.mixin.IconElement.html", + "OO.ui.mixin.LabelElement": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.mixin.LabelElement.html", + "OO.ui.mixin.PendingElement": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.mixin.PendingElement.html", + "OO.ui.mixin.TitledElement": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.mixin.TitledElement.html", + "OO.ui.BookletLayout": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.BookletLayout.html", + "OO.ui.ButtonOptionWidget": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.ButtonOptionWidget.html", + "OO.ui.ButtonSelectWidget": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.ButtonSelectWidget.html", + "OO.ui.ButtonWidget": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.ButtonWidget.html", + "OO.ui.DecoratedOptionWidget": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.DecoratedOptionWidget.html", + "OO.ui.Dialog": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.Dialog.html", + "OO.ui.Element": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.Element.html", + "OO.ui.HtmlSnippet": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.HtmlSnippet.html", + "OO.ui.MenuOptionWidget": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.MenuOptionWidget.html", + "OO.ui.MenuSelectWidget": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.MenuSelectWidget.html", + "OO.ui.MessageDialog": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.MessageDialog.html", + "OO.ui.MultilineTextInputWidget": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.MultilineTextInputWidget.html", + "OO.ui.NumberInputWidget": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.NumberInputWidget.html", + "OO.ui.OptionWidget": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.OptionWidget.html", + "OO.ui.PageLayout": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.PageLayout.html", + "OO.ui.PopupTool": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.PopupTool.html", + "OO.ui.Process": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.Process.html", + "OO.ui.ProcessDialog": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.ProcessDialog.html", + "OO.ui.SearchWidget": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.SearchWidget.html", + "OO.ui.SelectWidget": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.SelectWidget.html", + "OO.ui.TextInputWidget": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.TextInputWidget.html", + "OO.ui.Widget": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.Widget.html", + "OO.ui.Window": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.Window.html", + "OO.ui.WindowManager": "https://doc.wikimedia.org/oojs-ui/master/js/OO.ui.WindowManager.html", + + "jQuery": "http://api.jquery.com/", + "jQuery.Deferred": "http://api.jquery.com/jQuery.Deferred/", + "jQuery.Event": "http://api.jquery.com/Types/#Event", + "jQuery.jqXHR": "http://api.jquery.com/Types/#jqXHR", + "jQuery.Promise": "http://api.jquery.com/Types/#Promise" + } + } + } +} diff --git a/README.md b/README.md new file mode 100644 index 000000000..e5b542242 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +The Echo extension provides an in-wiki notification system that can be used by other extensions. diff --git a/jsduck.external.js b/jsduck.external.js deleted file mode 100644 index 6ceaf7b1f..000000000 --- a/jsduck.external.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Source: - * - * @class jQuery - */ - -/** - * Source: - * - * @method ajax - * @static - * @return {jQuery.jqXHR} - */ - -/** - * Source: - * - * @class jQuery.Event - */ - -/** - * Source: - * - * @class jQuery.Promise - */ - -/** - * Source: - * - * @class jQuery.Deferred - * @mixins jQuery.Promise - */ - -/** - * Source: - * - * @class jQuery.jqXHR - * @mixins jQuery.Promise - */ - -/** - * Source: - * - * @class mw.Api - */ - -/** - * Source: - * - * @class mw.Title - */ diff --git a/jsduck.json b/jsduck.json deleted file mode 100644 index e3e7955ba..000000000 --- a/jsduck.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "--title": "Echo - Documentation", - "--processes": "0", - "--warnings-exit-nonzero": true, - "--external": "OO.*", - "--output": "docs", - "--tags": "jsduck_custom_tags.rb", - "--": [ - "jsduck.external.js", - "modules", - "tests" - ] -} diff --git a/jsduck_custom_tags.rb b/jsduck_custom_tags.rb deleted file mode 100644 index 6a4da00ac..000000000 --- a/jsduck_custom_tags.rb +++ /dev/null @@ -1,83 +0,0 @@ -# Custom tags for JSDuck 5.x -# See also: -# - https://github.com/senchalabs/jsduck/wiki/Tags -# - https://github.com/senchalabs/jsduck/wiki/Custom-tags -# - https://github.com/senchalabs/jsduck/wiki/Custom-tags/7f5c32e568eab9edc8e3365e935bcb836cb11f1d -require 'jsduck/tag/tag' - -class CommonTag < JsDuck::Tag::Tag - def initialize - @html_position = POS_DOC + 0.1 - @repeatable = true - end - - def parse_doc(scanner, _position) - if @multiline - return { tagname: @tagname, doc: :multiline } - else - text = scanner.match(/.*$/) - return { tagname: @tagname, doc: text } - end - end - - def process_doc(context, tags, _position) - context[@tagname] = tags - end - - def format(context, formatter) - context[@tagname].each do |tag| - tag[:doc] = formatter.format(tag[:doc]) - end - end -end - -class SeeTag < CommonTag - def initialize - @tagname = :see - @pattern = 'see' - super - end - - def format(context, formatter) - position = context[:files][0] - context[@tagname].each do |tag| - tag[:doc] = '
  • ' + render_long_see(tag[:doc], formatter, position) + '
  • ' - end - end - - def to_html(context) - <<-EOHTML -

    Related

    -
      - #{context[@tagname].map {|tag| tag[:doc]}.join("\n")} -
    - EOHTML - end - - def render_long_see(tag, formatter, position) - match = tag.match(/\A([^\s]+)( .*)?\Z/m) - if match - name = match[1] - doc = match[2] ? ': ' + match[2] : '' - return formatter.format("{@link #{name}} #{doc}") - else - JsDuck::Logger.warn(nil, 'Unexpected @see argument: "' + tag + '"', position) - return tag - end - end -end - -class TodoTag < CommonTag - def initialize - @tagname = :todo - @pattern = 'todo' - super - end - - def to_html(context) - <<-EOHTML -

    TODO

    - #{context[@tagname].last[:doc]} - EOHTML - end -end diff --git a/modules/.eslintrc.json b/modules/.eslintrc.json index 3ac28f162..9b333350d 100644 --- a/modules/.eslintrc.json +++ b/modules/.eslintrc.json @@ -1,15 +1,16 @@ { "root": true, "extends": [ - "wikimedia/client-es5", + "wikimedia/client-es6", "wikimedia/jquery", "wikimedia/mediawiki", - "wikimedia/jsduck" + "wikimedia/jsdoc" ], "env": { "commonjs": true }, "rules": { - "max-len": "off" + "max-len": "off", + "no-var": "off" } } diff --git a/modules/api/mw.echo.api.PromisePrioritizer.js b/modules/api/mw.echo.api.PromisePrioritizer.js index 91e3c0b3a..621a08fe3 100644 --- a/modules/api/mw.echo.api.PromisePrioritizer.js +++ b/modules/api/mw.echo.api.PromisePrioritizer.js @@ -23,7 +23,6 @@ /** * Prioritize a promise * - * @external Promise * @param {jQuery.Promise|Promise} promise Promise * @return {jQuery.Promise} The main deferred object that resolves * or rejects when the latest promise is resolved or rejected. diff --git a/modules/api/mw.echo.api.js b/modules/api/mw.echo.api.js index f5129bce2..544f0a2ab 100644 --- a/modules/api/mw.echo.api.js +++ b/modules/api/mw.echo.api.js @@ -1,4 +1,7 @@ ( function () { mw.echo = mw.echo || {}; + /** + * @namespace + */ mw.echo.api = mw.echo.api || {}; }() ); diff --git a/modules/ext.echo.init.js b/modules/ext.echo.init.js index d2ccf1159..23719231d 100644 --- a/modules/ext.echo.init.js +++ b/modules/ext.echo.init.js @@ -1,3 +1,7 @@ +/** + * @module module:ext.echo.init + */ + /* eslint-disable no-jquery/no-global-selector */ mw.echo = mw.echo || {}; mw.echo.config = mw.echo.config || {}; diff --git a/modules/mobile/list.js b/modules/mobile/list.js index 5a1aad6f4..341d8ba15 100644 --- a/modules/mobile/list.js +++ b/modules/mobile/list.js @@ -3,9 +3,12 @@ var mobile = require( 'mobile.startup' ), promisedView = mobile.promisedView; /** - * This callback is displayed as a global member. - * - * @callback FunctionCountChangeCallback + * @module module:ext.echo.mobile + */ + +/** + * @typedef {Function} FunctionCountChangeCallback + * @memberof module:ext.echo.mobile * @param {number} count a capped (0-99 or 99+) count */ @@ -15,7 +18,7 @@ var mobile = require( 'mobile.startup' ), * @param {mw.echo} echo class * @param {OO.ui.ButtonWidget} markAllReadButton - a button that will be associated with the * read status of the notifications list. - * @param {FunctionCountChangeCallback} onCountChange callback. + * @param {module:ext.echo.mobile.FunctionCountChangeCallback} onCountChange callback. * @return {View} */ function notificationsList( echo, markAllReadButton, onCountChange ) { diff --git a/modules/mobile/notifications.js b/modules/mobile/notifications.js index fc95b6232..46f3e4be4 100644 --- a/modules/mobile/notifications.js +++ b/modules/mobile/notifications.js @@ -1,14 +1,18 @@ var mobile = require( 'mobile.startup' ); /** - * @fires echo.mobile every time the notifications overlay is opened + * @module module:ext.echo.mobile + */ + +/** + * @fires module:ext.echo.mobile#echo.mobile every time the notifications overlay is opened */ function onOpenNotificationsOverlay() { mw.hook( 'echo.mobile' ).fire( true ); } /** - * @fires echo.mobile every time the notifications overlay is closed + * @fires module:ext.echo.mobile#echo.mobile every time the notifications overlay is closed */ function onCloseNotificationsOverlay() { mw.hook( 'echo.mobile' ).fire( false ); diff --git a/modules/mobile/notificationsFilterOverlay.js b/modules/mobile/notificationsFilterOverlay.js index deb26ce3d..15cf76a3b 100644 --- a/modules/mobile/notificationsFilterOverlay.js +++ b/modules/mobile/notificationsFilterOverlay.js @@ -1,13 +1,17 @@ var Overlay = require( 'mobile.startup' ).Overlay; +/** + * @module module:ext.echo.mobile + */ + /** * Overlay for notifications filter * * @class NotificationsFilterOverlay * @param {Object} options * @param {Function} options.onBeforeExit executes before overlay closes - * @param {jQuery.Object} options.$notifReadState - notification read status widgets - * @param {jQuery.Object} options.$crossWikiUnreadFilter - notification unread filter + * @param {jQuery} options.$notifReadState - notification read status widgets + * @param {jQuery} options.$crossWikiUnreadFilter - notification unread filter */ function notificationsFilterOverlay( options ) { // Don't call overlay.hide(), because that doesn't invoke the onBeforeExit callback (T258954) diff --git a/modules/mobile/overlay.js b/modules/mobile/overlay.js index cef1ad941..33800f798 100644 --- a/modules/mobile/overlay.js +++ b/modules/mobile/overlay.js @@ -1,3 +1,7 @@ +/** + * @module module:ext.echo.mobile + */ + var mobile = require( 'mobile.startup' ), Overlay = mobile.Overlay, list = require( './list.js' ), @@ -7,7 +11,6 @@ var mobile = require( 'mobile.startup' ), /** * @param {Overlay} overlay * @param {Function} exit - * @return {void} */ function onBeforeExitAnimation( overlay, exit ) { if ( getComputedStyle( overlay.$el[ 0 ] ).transitionDuration !== '0s' ) { @@ -21,13 +24,6 @@ function onBeforeExitAnimation( overlay, exit ) { } } -/** - * This callback is displayed as a global member. - * - * @callback FunctionCountChangeCallback - * @param {number} count a capped (0-99 or 99+) count - */ - /** * @param {number} count a capped (0-99 or 99+) count. */ diff --git a/modules/model/mw.echo.dm.CrossWikiNotificationItem.js b/modules/model/mw.echo.dm.CrossWikiNotificationItem.js index 2e1e6f97b..d7bdc5e6c 100644 --- a/modules/model/mw.echo.dm.CrossWikiNotificationItem.js +++ b/modules/model/mw.echo.dm.CrossWikiNotificationItem.js @@ -32,10 +32,10 @@ /* Events */ /** - * @event discard - * @param {string} name The symbolic name for the list model that was discarded - * * A sub list has been discarded + * + * @event mw.echo.dm.CrossWikiNotificationItem#discard + * @param {string} name The symbolic name for the list model that was discarded */ /* Methods */ @@ -44,7 +44,7 @@ * Respond to list being removed from the cross-wiki bundle. * * @param {mw.echo.dm.NotificationGroupsList} sourceModel The source model that was removed - * @fires discard + * @fires mw.echo.dm.CrossWikiNotificationItem#discard */ mw.echo.dm.CrossWikiNotificationItem.prototype.onListDiscard = function ( sourceModel ) { this.emit( 'discard', sourceModel.getName() ); diff --git a/modules/model/mw.echo.dm.FiltersModel.js b/modules/model/mw.echo.dm.FiltersModel.js index a58d41356..e2b7b1c10 100644 --- a/modules/model/mw.echo.dm.FiltersModel.js +++ b/modules/model/mw.echo.dm.FiltersModel.js @@ -3,7 +3,7 @@ * Filters model for displaying filtered notification list. * * @class - * @mixins OO.EventEmitter + * @mixes OO.EventEmitter * * @constructor * @param {Object} config Configuration object @@ -32,9 +32,9 @@ /* Events */ /** - * @event update - * * The filters have been updated + * + * @event mw.echo.dm.FiltersModel#update */ /* Methods */ @@ -43,6 +43,7 @@ * Set the read state filter * * @param {string} readState Notifications read state + * @fires mw.echo.dm.FiltersModel#update */ mw.echo.dm.FiltersModel.prototype.setReadState = function ( readState ) { var allowed = [ 'all', 'read', 'unread' ]; diff --git a/modules/model/mw.echo.dm.ModelManager.js b/modules/model/mw.echo.dm.ModelManager.js index 58d5d2729..3d96a978d 100644 --- a/modules/model/mw.echo.dm.ModelManager.js +++ b/modules/model/mw.echo.dm.ModelManager.js @@ -17,7 +17,7 @@ * - getCount - Get a total count of available notifications currently in the model * * @class - * @mixins OO.EventEmitter + * @mixes OO.EventEmitter * * @constructor * @param {mw.echo.dm.UnreadNotificationCounter} counter Unread counter @@ -63,45 +63,45 @@ /* Events */ /** - * @event update - * @param {Object[]} Current available notifications - * * The model has been rebuilt or has been updated - */ - - /** - * @event discard - * @param {string} modelId Discard model id * - * A model has been permanently removed + * @event mw.echo.dm.ModelManager#update + * @param {Object[]} Current available notifications */ /** - * @event seen + * A model has been permanently removed + * + * @event mw.echo.dm.ModelManager#discard + * @param {string} modelId Discard model id + */ + + /** + * All notifications in that source are seen + * + * @event mw.echo.dm.ModelManager#seen * @param {string} source Source where seenTime was updated * @param {number} timestamp The new seen timestamp, as a full UTC ISO 8601 timestamp - * - * All notifications in that source are seen */ /** - * @event allTalkRead - * * There are no more local talk page notifications + * + * @event mw.echo.dm.ModelManager#allTalkRead */ /** - * @event modelItemUpdate + * A specific item inside a notifications model has been updated + * + * @event mw.echo.dm.ModelManager#modelItemUpdate * @param {string} modelId Model ID * @param {mw.echo.dm.NotificationItem} item Updated item - * - * A specific item inside a notifications model has been updated */ /** - * @event localCountChange - * * There was a change in the count of local unread notifications + * + * @event mw.echo.dm.ModelManager#localCountChange */ /* Methods */ @@ -110,7 +110,7 @@ * Respond to seen time change for a given source * * @param {string} timestamp Seen time, as a full UTC ISO 8601 timestamp - * @fires seen + * @fires mw.echo.dm.ModelManager#seen */ mw.echo.dm.ModelManager.prototype.onSeenTimeUpdate = function ( timestamp ) { var models = this.getAllNotificationModels(); @@ -154,6 +154,7 @@ * 'modelId': {mw.echo.dm.SortedList}, * ... * } + * @fires mw.echo.dm.ModelManager#update */ mw.echo.dm.ModelManager.prototype.setNotificationModels = function ( modelDefinitions ) { this.resetNotificationModels(); @@ -176,8 +177,8 @@ * Respond to model update event * * @param {string} modelName Model name - * @param {mw.echo.dm.notificationItem} item Notification item - * @fires modelUpdate + * @param {mw.echo.dm.NotificationItem} item Notification item + * @fires mw.echo.dm.ModelManager#modelItemUpdate */ mw.echo.dm.ModelManager.prototype.onModelItemUpdate = function ( modelName, item ) { this.checkLocalUnreadTalk(); @@ -241,7 +242,7 @@ * Remove a model from the manager * * @param {string} modelName Symbolic name of the model - * @fires remove + * @fires mw.echo.dm.ModelManager#discard */ mw.echo.dm.ModelManager.prototype.removeNotificationModel = function ( modelName ) { delete this.notificationModels[ modelName ]; @@ -301,7 +302,7 @@ * Check whether there are talk notifications, and emit an event * in case there aren't any left. * - * @fires allTalkRead + * @fires mw.echo.dm.ModelManager#allTalkRead */ mw.echo.dm.ModelManager.prototype.checkLocalUnreadTalk = function () { if ( !this.hasLocalUnreadTalk() ) { diff --git a/modules/model/mw.echo.dm.NotificationGroupsList.js b/modules/model/mw.echo.dm.NotificationGroupsList.js index 6f86437b1..9310d3e7f 100644 --- a/modules/model/mw.echo.dm.NotificationGroupsList.js +++ b/modules/model/mw.echo.dm.NotificationGroupsList.js @@ -46,9 +46,9 @@ /* Events */ /** - * @event discard - * * A group was permanently removed + * + * @event mw.echo.dm.NotificationGroupsList#discard */ /* Methods */ @@ -133,7 +133,7 @@ * for the sake of sorting. To avoid ambiguity, we use 'discard' event. * * @param {string} groupName Group name - * @fires discard + * @fires mw.echo.dm.NotificationGroupsList#discard */ mw.echo.dm.NotificationGroupsList.prototype.removeGroup = function ( groupName ) { var group = this.getGroupByName( groupName ); diff --git a/modules/model/mw.echo.dm.NotificationItem.js b/modules/model/mw.echo.dm.NotificationItem.js index 8985d1d0e..7081080ce 100644 --- a/modules/model/mw.echo.dm.NotificationItem.js +++ b/modules/model/mw.echo.dm.NotificationItem.js @@ -4,8 +4,8 @@ * Notification item data structure. * * @class - * @mixins OO.EventEmitter - * @mixins OO.SortedEmitterList + * @mixes OO.EventEmitter + * @mixes OO.SortedEmitterList * * @constructor * @param {number} id Notification id, @@ -74,9 +74,9 @@ /* Events */ /** - * @event update - * * Item details have changed or were updated + * + * @event mw.echo.dm.NotificationItem#update */ /* Methods */ @@ -176,7 +176,8 @@ * * @param {boolean} [read] The current read state. If not given, the state will * become the opposite of its current state. - * @fires update + * @fires mw.echo.dm.NotificationItem#update + * @fires OO.EventEmitter#sortChange */ mw.echo.dm.NotificationItem.prototype.toggleRead = function ( read ) { read = read !== undefined ? read : !this.read; @@ -192,7 +193,7 @@ * * @param {boolean} [seen] The current seen state. If not given, the state will * become the opposite of its current state. - * @fires update + * @fires mw.echo.dm.NotificationItem#update */ mw.echo.dm.NotificationItem.prototype.toggleSeen = function ( seen ) { seen = seen !== undefined ? seen : !this.seen; diff --git a/modules/model/mw.echo.dm.NotificationsList.js b/modules/model/mw.echo.dm.NotificationsList.js index 17c8bf95c..fe079d254 100644 --- a/modules/model/mw.echo.dm.NotificationsList.js +++ b/modules/model/mw.echo.dm.NotificationsList.js @@ -67,24 +67,24 @@ /* Events */ /** - * @event update - * @param {mw.echo.dm.NotificationItem[]} items Current items in the list - * * The list has been updated + * + * @event mw.echo.dm.NotificationsList#update + * @param {mw.echo.dm.NotificationItem[]} items Current items in the list */ /** - * @event itemUpdate - * @param {mw.echo.dm.NotificationItem} item Item that has changed - * * An item in the list has been updated + * + * @event mw.echo.dm.NotificationsList#itemUpdate + * @param {mw.echo.dm.NotificationItem} item Item that has changed */ /** - * @event discard - * @param {mw.echo.dm.NotificationItem} item Item that was discarded - * * An item was discarded + * + * @event mw.echo.dm.NotificationsList#discard + * @param {mw.echo.dm.NotificationItem} item Item that was discarded */ /* Methods */ @@ -93,7 +93,7 @@ * Set the items in this list * * @param {mw.echo.dm.NotificationItem[]} items Items to insert into the list - * @fires update + * @fires mw.echo.dm.NotificationsList#update */ mw.echo.dm.NotificationsList.prototype.setItems = function ( items ) { this.clearItems(); @@ -111,6 +111,7 @@ * temporarily moving them. * * @param {mw.echo.dm.NotificationItem[]} items Items to insert into the list + * @fires mw.echo.dm.NotificationsList#discard */ mw.echo.dm.NotificationsList.prototype.discardItems = function ( items ) { this.removeItems( items ); diff --git a/modules/model/mw.echo.dm.PaginationModel.js b/modules/model/mw.echo.dm.PaginationModel.js index 99a4b514a..18178d797 100644 --- a/modules/model/mw.echo.dm.PaginationModel.js +++ b/modules/model/mw.echo.dm.PaginationModel.js @@ -3,7 +3,7 @@ * Pagination model for echo notifications pages. * * @class - * @mixins OO.EventEmitter + * @mixes OO.EventEmitter * * @constructor * @param {Object} config Configuration object @@ -41,9 +41,9 @@ /* Events */ /** - * @event update - * * Pagination information was updated + * + * @event mw.echo.dm.PaginationModel#update */ /* Methods */ @@ -51,7 +51,7 @@ /** * Reset pagination data * - * @fires update + * @fires mw.echo.dm.PaginationModel#update */ mw.echo.dm.PaginationModel.prototype.reset = function () { this.pagesContinue = []; @@ -65,6 +65,7 @@ * * @param {number} page Page index * @param {string} continueVal Continue string value + * @fires mw.echo.dm.PaginationModel#update */ mw.echo.dm.PaginationModel.prototype.setPageContinue = function ( page, continueVal ) { if ( this.pagesContinue[ page ] !== continueVal ) { @@ -105,7 +106,7 @@ /** * Move forward to the next page * - * @fires update + * @fires mw.echo.dm.PaginationModel#update */ mw.echo.dm.PaginationModel.prototype.forwards = function () { if ( this.hasNextPage() ) { @@ -117,7 +118,7 @@ /** * Move backwards to the previous page * - * @fires update + * @fires mw.echo.dm.PaginationModel#update */ mw.echo.dm.PaginationModel.prototype.backwards = function () { if ( this.hasPrevPage() ) { @@ -184,7 +185,7 @@ * Set the number of items in the current page * * @param {number} count Number of items - * @fires update + * @fires mw.echo.dm.PaginationModel#update */ mw.echo.dm.PaginationModel.prototype.setCurrentPageItemCount = function ( count ) { if ( this.currentPageItemCount !== count ) { diff --git a/modules/model/mw.echo.dm.SeenTimeModel.js b/modules/model/mw.echo.dm.SeenTimeModel.js index 2892b5d96..d4013c667 100644 --- a/modules/model/mw.echo.dm.SeenTimeModel.js +++ b/modules/model/mw.echo.dm.SeenTimeModel.js @@ -28,10 +28,10 @@ /* Events */ /** - * @event update - * @param {string} time Seen time, as a full UTC ISO 8601 timestamp. - * * Seen time has been updated for the given source + * + * @event mw.echo.dm.SeenTimeModel#update + * @param {string} time Seen time, as a full UTC ISO 8601 timestamp. */ /* Methods */ @@ -50,7 +50,7 @@ * * @private * @param {string} time Seen time, as a full UTC ISO 8601 timestamp. - * @fires update + * @fires mw.echo.dm.SeenTimeModel#update */ mw.echo.dm.SeenTimeModel.prototype.setSeenTime = function ( time ) { var model = this, diff --git a/modules/model/mw.echo.dm.SortedList.js b/modules/model/mw.echo.dm.SortedList.js index 758deb112..48af34b00 100644 --- a/modules/model/mw.echo.dm.SortedList.js +++ b/modules/model/mw.echo.dm.SortedList.js @@ -4,8 +4,8 @@ * * @class * @abstract - * @mixins OO.EventEmitter - * @mixins OO.SortedEmitterList + * @mixes OO.EventEmitter + * @mixes OO.SortedEmitterList * * @constructor */ diff --git a/modules/model/mw.echo.dm.SourcePagesModel.js b/modules/model/mw.echo.dm.SourcePagesModel.js index e7528ab75..c919d1587 100644 --- a/modules/model/mw.echo.dm.SourcePagesModel.js +++ b/modules/model/mw.echo.dm.SourcePagesModel.js @@ -3,7 +3,7 @@ * Source pages model for notification filtering * * @class - * @mixins OO.EventEmitter + * @mixes OO.EventEmitter * * @constructor * @param {Object} config Configuration object @@ -29,9 +29,9 @@ /* Events */ /** - * @event update - * * The state of the source page model has changed + * + * @event mw.echo.dm.SourcePagesModel#update */ /* Methods */ @@ -41,7 +41,7 @@ * * @param {string} source New source * @param {string} page New page - * @fires update + * @fires mw.echo.dm.SourcePagesModel#update */ mw.echo.dm.SourcePagesModel.prototype.setCurrentSourcePage = function ( source, page ) { if ( @@ -77,6 +77,7 @@ * previously set information. * * @param {Object} sourceData A detailed object about sources and pages + * @fires mw.echo.dm.SourcePagesModel#update */ mw.echo.dm.SourcePagesModel.prototype.setAllSources = function ( sourceData ) { this.reset(); diff --git a/modules/model/mw.echo.dm.UnreadNotificationCounter.js b/modules/model/mw.echo.dm.UnreadNotificationCounter.js index d0ccd3452..3337889ee 100644 --- a/modules/model/mw.echo.dm.UnreadNotificationCounter.js +++ b/modules/model/mw.echo.dm.UnreadNotificationCounter.js @@ -3,7 +3,7 @@ * Echo notification UnreadNotificationCounter model * * @class - * @mixins OO.EventEmitter + * @mixes OO.EventEmitter * * @constructor * @param {Object} api An instance of EchoAPI. @@ -38,10 +38,10 @@ /* Events */ /** - * @event countChange - * @param {number} count Notification count - * * The number of unread notification represented by this counter has changed. + * + * @event mw.echo.dm.UnreadNotificationCounter#countChange + * @param {number} count Notification count */ /* Methods */ @@ -80,6 +80,7 @@ * * @param {number} count * @param {boolean} isEstimation Whether this number is estimated or accurate + * @fires mw.echo.dm.UnreadNotificationCounter#countChange */ mw.echo.dm.UnreadNotificationCounter.prototype.setCount = function ( count, isEstimation ) { if ( isEstimation ) { diff --git a/modules/model/mw.echo.dm.js b/modules/model/mw.echo.dm.js index 32a99a382..89a5d091f 100644 --- a/modules/model/mw.echo.dm.js +++ b/modules/model/mw.echo.dm.js @@ -1,3 +1,6 @@ ( function () { + /** + * @namespace + */ mw.echo.dm = {}; }() ); diff --git a/modules/ui/mw.echo.ui.BundleNotificationItemWidget.js b/modules/ui/mw.echo.ui.BundleNotificationItemWidget.js index 593ed51fb..9b09d303e 100644 --- a/modules/ui/mw.echo.ui.BundleNotificationItemWidget.js +++ b/modules/ui/mw.echo.ui.BundleNotificationItemWidget.js @@ -129,6 +129,8 @@ /** * Update item state when the item model changes. + * + * @fires OO.EventEmitter#sortChange */ mw.echo.ui.BundleNotificationItemWidget.prototype.updateDataFromModel = function () { this.toggleRead( this.model.isRead() ); diff --git a/modules/ui/mw.echo.ui.CrossWikiNotificationItemWidget.js b/modules/ui/mw.echo.ui.CrossWikiNotificationItemWidget.js index 1258993ce..4ca47af6b 100644 --- a/modules/ui/mw.echo.ui.CrossWikiNotificationItemWidget.js +++ b/modules/ui/mw.echo.ui.CrossWikiNotificationItemWidget.js @@ -10,7 +10,7 @@ * * @class * @extends mw.echo.ui.NotificationItemWidget - * @mixins OO.ui.mixin.PendingElement + * @mixes OO.ui.mixin.PendingElement * * @constructor * @param {mw.echo.Controller} controller Echo notifications controller diff --git a/modules/ui/mw.echo.ui.CrossWikiUnreadFilterWidget.js b/modules/ui/mw.echo.ui.CrossWikiUnreadFilterWidget.js index c9fb62833..24f71c6b7 100644 --- a/modules/ui/mw.echo.ui.CrossWikiUnreadFilterWidget.js +++ b/modules/ui/mw.echo.ui.CrossWikiUnreadFilterWidget.js @@ -4,7 +4,7 @@ * * @class * @extends OO.ui.Widget - * @mixins OO.ui.mixin.PendingElement + * @mixes OO.ui.mixin.PendingElement * * @constructor * @param {mw.echo.Controller} controller Echo controller @@ -76,11 +76,11 @@ /* Events */ /** - * @event filter + * A source page filter was chosen + * + * @event mw.echo.ui.CrossWikiUnreadFilterWidget#filter * @param {string} source Source symbolic name * @param {number} [pageId] Chosen page ID - * - * A source page filter was chosen */ /* Methods */ @@ -90,7 +90,7 @@ * * @param {mw.echo.ui.PageFilterWidget} widget The widget the event originated from * @param {mw.echo.ui.PageNotificationsOptionWidget} item The chosen item - * @fires filter + * @fires mw.echo.ui.CrossWikiUnreadFilterWidget#filter */ mw.echo.ui.CrossWikiUnreadFilterWidget.prototype.onPageFilterChoose = function ( widget, item ) { var source = widget.getSource(), diff --git a/modules/ui/mw.echo.ui.DatedNotificationsWidget.js b/modules/ui/mw.echo.ui.DatedNotificationsWidget.js index 609441107..23f9433d3 100644 --- a/modules/ui/mw.echo.ui.DatedNotificationsWidget.js +++ b/modules/ui/mw.echo.ui.DatedNotificationsWidget.js @@ -4,7 +4,7 @@ * * @class * @extends OO.ui.Widget - * @mixins OO.ui.mixin.PendingElement + * @mixes OO.ui.mixin.PendingElement * * @constructor * @param {mw.echo.Controller} controller Echo controller diff --git a/modules/ui/mw.echo.ui.FooterNoticeWidget.js b/modules/ui/mw.echo.ui.FooterNoticeWidget.js index 473ac525a..186b36c8d 100644 --- a/modules/ui/mw.echo.ui.FooterNoticeWidget.js +++ b/modules/ui/mw.echo.ui.FooterNoticeWidget.js @@ -62,7 +62,7 @@ /** * The notice was dismissed. * - * @event dismiss + * @event mw.echo.ui.FooterNoticeWidget#dismiss */ /* Methods */ @@ -70,7 +70,7 @@ /** * Respond to dismiss button click. * - * @fires dismiss + * @fires mw.echo.ui.FooterNoticeWidget#dismiss */ mw.echo.ui.FooterNoticeWidget.prototype.onDismissButtonClick = function () { this.toggle( false ); diff --git a/modules/ui/mw.echo.ui.MenuItemWidget.js b/modules/ui/mw.echo.ui.MenuItemWidget.js index 4a4462442..c42c4a8bf 100644 --- a/modules/ui/mw.echo.ui.MenuItemWidget.js +++ b/modules/ui/mw.echo.ui.MenuItemWidget.js @@ -4,7 +4,7 @@ * * @class * @extends OO.ui.ButtonOptionWidget - * @mixins OO.ui.mixin.PendingElement + * @mixes OO.ui.mixin.PendingElement * * @constructor * @param {Object} [config] Configuration object @@ -107,6 +107,13 @@ return this.prioritized; }; + /** + * @typedef {Object} ConfirmationMessages + * @memberof mw.echo.ui.MenuItemWidget + * @property {string} title Title for the confirmation dialog + * @property {string} description Description for the confirmation dialog + */ + /** * Get the messages for the confirmation dialog * We expect optionally two messages - title and description. @@ -114,9 +121,7 @@ * NOTE: The messages are parsed as HTML. If user-input is expected * please make sure to properly escape it. * - * @return {Object} Messages for the confirmation dialog - * @return {string} return.title Title for the confirmation dialog - * @return {string} return.description Description for the confirmation dialog + * @return {mw.echo.ui.MenuItemWidget.ConfirmationMessages} Messages for the confirmation dialog */ mw.echo.ui.MenuItemWidget.prototype.getConfirmationMessages = function () { return this.messages.confirmation; diff --git a/modules/ui/mw.echo.ui.NotificationBadgeWidget.js b/modules/ui/mw.echo.ui.NotificationBadgeWidget.js index bc0695060..2a167b577 100644 --- a/modules/ui/mw.echo.ui.NotificationBadgeWidget.js +++ b/modules/ui/mw.echo.ui.NotificationBadgeWidget.js @@ -191,13 +191,15 @@ /* Events */ /** - * @event allRead * All notifications were marked as read + * + * @event mw.echo.ui.NotificationBadgeWidget#allRead */ /** - * @event finishLoading * Notifications have successfully finished being processed and are fully loaded + * + * @event mw.echo.ui.NotificationBadgeWidget#finishLoading */ /* Methods */ @@ -272,7 +274,7 @@ * Extend the response to button click so we can also update the notification list. * * @param {boolean} isVisible The popup is visible - * @fires finishLoading + * @fires mw.echo.ui.NotificationBadgeWidget#finishLoading */ mw.echo.ui.NotificationBadgeWidget.prototype.onPopupToggle = function ( isVisible ) { var widget = this; diff --git a/modules/ui/mw.echo.ui.NotificationsInboxWidget.js b/modules/ui/mw.echo.ui.NotificationsInboxWidget.js index acacb857f..f5296a796 100644 --- a/modules/ui/mw.echo.ui.NotificationsInboxWidget.js +++ b/modules/ui/mw.echo.ui.NotificationsInboxWidget.js @@ -4,7 +4,7 @@ * * @class * @extends OO.ui.Widget - * @mixins OO.ui.mixin.PendingElement + * @mixes OO.ui.mixin.PendingElement * * @constructor * @param {mw.echo.Controller} controller Echo controller diff --git a/modules/ui/mw.echo.ui.NotificationsListWidget.js b/modules/ui/mw.echo.ui.NotificationsListWidget.js index 6e3c81198..764ed06f6 100644 --- a/modules/ui/mw.echo.ui.NotificationsListWidget.js +++ b/modules/ui/mw.echo.ui.NotificationsListWidget.js @@ -76,11 +76,11 @@ /* Events */ /** - * @event modified - * * The content of this list has changed. * This event is to state that not only has the content changed * but the actual DOM has been manipulated. + * + * @event mw.echo.ui.NotificationsListWidget#modified */ /* Methods */ @@ -112,7 +112,7 @@ * * @param {Object} models Object of new models to populate the * list. - * @fires modified + * @fires mw.echo.ui.NotificationsListWidget#modified */ mw.echo.ui.NotificationsListWidget.prototype.resetDataFromModel = function ( models ) { var itemWidgets = [], @@ -213,7 +213,7 @@ * * @param {string} [label] Label for the option widget * @param {string} [link] Link for the option widget - * @fires modified + * @fires mw.echo.ui.NotificationsListWidget#modified */ mw.echo.ui.NotificationsListWidget.prototype.resetLoadingOption = function ( label, link ) { this.loadingOptionWidget.setLabel( label || '' ); diff --git a/modules/ui/mw.echo.ui.NotificationsWrapper.js b/modules/ui/mw.echo.ui.NotificationsWrapper.js index 95f401ca1..2070205ce 100644 --- a/modules/ui/mw.echo.ui.NotificationsWrapper.js +++ b/modules/ui/mw.echo.ui.NotificationsWrapper.js @@ -4,7 +4,7 @@ * * @class * @extends OO.ui.Widget - * @mixins OO.ui.mixin.PendingElement + * @mixes OO.ui.mixin.PendingElement * * @constructor * @param {mw.echo.Controller} controller Echo controller @@ -50,8 +50,9 @@ /* Events */ /** - * @event finishLoading * Notifications have successfully finished being processed and are fully loaded + * + * @event mw.echo.ui.NotificationsWrapper#finishLoading */ /* Methods */ @@ -61,6 +62,7 @@ * * @return {jQuery.Promise} A promise that is resolved when all notifications * were fetched from the API and added to the model and UI. + * @fires mw.echo.ui.NotificationsWrapper#finishLoading */ mw.echo.ui.NotificationsWrapper.prototype.populate = function () { var widget = this; diff --git a/modules/ui/mw.echo.ui.PageNotificationsOptionWidget.js b/modules/ui/mw.echo.ui.PageNotificationsOptionWidget.js index c3039fd6a..796a85aa5 100644 --- a/modules/ui/mw.echo.ui.PageNotificationsOptionWidget.js +++ b/modules/ui/mw.echo.ui.PageNotificationsOptionWidget.js @@ -4,8 +4,8 @@ * * @class * @extends OO.ui.OptionWidget - * @mixins OO.ui.mixin.IconElement - * @mixins OO.ui.mixin.TitledElement + * @mixes OO.ui.mixin.IconElement + * @mixes OO.ui.mixin.TitledElement * * @constructor * @param {Object} [config] Configuration object diff --git a/modules/ui/mw.echo.ui.PaginationWidget.js b/modules/ui/mw.echo.ui.PaginationWidget.js index 46be85d22..ae56845ad 100644 --- a/modules/ui/mw.echo.ui.PaginationWidget.js +++ b/modules/ui/mw.echo.ui.PaginationWidget.js @@ -81,11 +81,11 @@ /* Events */ /** - * @event change + * Pagination changed + * + * @event mw.echo.ui.PaginationWidget#change * @param {string} direction Direction of movement 'prev', * 'next' or 'start' - * - * Pagination changed */ /* Methods */ @@ -94,7 +94,7 @@ * Respond to dir select widget choose event * * @param {OO.ui.ButtonOptionWidget} item Chosen button - * @fires change + * @fires mw.echo.ui.PaginationWidget#change */ mw.echo.ui.PaginationWidget.prototype.onDirSelectWidgetChoose = function ( item ) { var dir = item && item.getData(); @@ -132,6 +132,7 @@ * * @param {boolean} disabled Disable widget * @chainable + * @return {mw.echo.ui.PaginationWidget} */ mw.echo.ui.PaginationWidget.prototype.setDisabled = function ( disabled ) { // Parent method diff --git a/modules/ui/mw.echo.ui.PlaceholderItemWidget.js b/modules/ui/mw.echo.ui.PlaceholderItemWidget.js index ac34399ae..bdd396131 100644 --- a/modules/ui/mw.echo.ui.PlaceholderItemWidget.js +++ b/modules/ui/mw.echo.ui.PlaceholderItemWidget.js @@ -4,7 +4,7 @@ * * @class * @extends OO.ui.Widget - * @mixins OO.ui.mixin.LabelElement + * @mixes OO.ui.mixin.LabelElement * * @constructor * @param {Object} [config] Configuration object diff --git a/modules/ui/mw.echo.ui.ReadStateButtonSelectWidget.js b/modules/ui/mw.echo.ui.ReadStateButtonSelectWidget.js index 56a221bdc..e9315a3bd 100644 --- a/modules/ui/mw.echo.ui.ReadStateButtonSelectWidget.js +++ b/modules/ui/mw.echo.ui.ReadStateButtonSelectWidget.js @@ -40,7 +40,7 @@ /* Events */ /** - * @event filter + * @event mw.echo.ui.ReadStateButtonSelectWidget#filter * @param {string} readState The chosen read state */ @@ -50,7 +50,7 @@ * Respond to choose event * * @param {OO.ui.ButtonOptionWidget} item Chosen item - * @fires filter + * @fires mw.echo.ui.ReadStateButtonSelectWidget#filter */ mw.echo.ui.ReadStateButtonSelectWidget.prototype.onChoose = function ( item ) { var data = item && item.getData(); diff --git a/modules/ui/mw.echo.ui.SingleNotificationItemWidget.js b/modules/ui/mw.echo.ui.SingleNotificationItemWidget.js index d70b11937..602ac9d7b 100644 --- a/modules/ui/mw.echo.ui.SingleNotificationItemWidget.js +++ b/modules/ui/mw.echo.ui.SingleNotificationItemWidget.js @@ -4,7 +4,7 @@ * * @class * @extends mw.echo.ui.NotificationItemWidget - * @mixins OO.ui.mixin.PendingElement + * @mixes OO.ui.mixin.PendingElement * * @constructor * @param {mw.echo.Controller} controller Echo notifications controller @@ -62,7 +62,7 @@ * when its read state was updated * * @inheritdoc - * @fires sortChange + * @fires OO.EventEmitter#sortChange */ mw.echo.ui.SingleNotificationItemWidget.prototype.toggleRead = function ( read ) { var oldState = this.read; diff --git a/modules/ui/mw.echo.ui.SortedListWidget.js b/modules/ui/mw.echo.ui.SortedListWidget.js index 92fa4fcbb..f29bf5dec 100644 --- a/modules/ui/mw.echo.ui.SortedListWidget.js +++ b/modules/ui/mw.echo.ui.SortedListWidget.js @@ -5,7 +5,7 @@ * * @class * @extends OO.ui.Widget - * @mixins OO.SortedEmitterList + * @mixes OO.SortedEmitterList * * @constructor * @param {Function} sortingCallback Callback that compares two items. @@ -154,7 +154,8 @@ * * @param {OO.EventEmitter[]} items Items to remove * @chainable - * @fires remove + * @return {mw.echo.ui.SortedListWidget} + * @fires OO.EmitterList#remove */ mw.echo.ui.SortedListWidget.prototype.removeItems = function ( items ) { var i, item, index; @@ -243,7 +244,8 @@ * Clear all items * * @chainable - * @fires clear + * @return {mw.echo.ui.SortedListWidget} + * @fires OO.EmitterList#clear */ mw.echo.ui.SortedListWidget.prototype.clearItems = function () { var i, len, item; diff --git a/modules/ui/mw.echo.ui.SpecialHelpMenuWidget.js b/modules/ui/mw.echo.ui.SpecialHelpMenuWidget.js index f6bd88342..3f8ae2b48 100644 --- a/modules/ui/mw.echo.ui.SpecialHelpMenuWidget.js +++ b/modules/ui/mw.echo.ui.SpecialHelpMenuWidget.js @@ -64,9 +64,9 @@ /* Events */ /** - * @event markAllRead - * * Mark all notifications as read in the selected wiki + * + * @event mw.echo.ui.SpecialHelpMenuWidget#markAllRead */ /* Methods */ @@ -100,6 +100,7 @@ * Handle menu choose events * * @param {OO.ui.MenuOptionWidget} item Chosen item + * @fires mw.echo.ui.SpecialHelpMenuWidget#markAllRead */ mw.echo.ui.SpecialHelpMenuWidget.prototype.onMenuChoose = function ( item ) { var data = item.getData(); diff --git a/modules/ui/mw.echo.ui.js b/modules/ui/mw.echo.ui.js index 00f45316d..06a0c40f5 100644 --- a/modules/ui/mw.echo.ui.js +++ b/modules/ui/mw.echo.ui.js @@ -1,6 +1,12 @@ ( function () { mw.echo = mw.echo || {}; + /** + * @namespace + */ mw.echo.ui = { + /** + * @property {jQuery} + */ $overlay: $( '
    ' ) .addClass( 'mw-echo-ui-overlay' ) }; diff --git a/package-lock.json b/package-lock.json index 09476fb01..53f210932 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,9 @@ "grunt-contrib-watch": "1.1.0", "grunt-eslint": "24.3.0", "grunt-stylelint": "0.19.0", + "jsdoc": "4.0.2", + "jsdoc-class-hierarchy": "1.1.2", + "jsdoc-wmf-theme": "1.0.0", "stylelint-config-wikimedia": "0.16.1", "svgo": "3.2.0", "wdio-mediawiki": "2.3.0" @@ -136,6 +139,18 @@ "node": ">=4" } }, + "node_modules/@babel/parser": { + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz", + "integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@csstools/css-parser-algorithms": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.3.1.tgz", @@ -359,6 +374,18 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/@jsdoc/salty": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.8.tgz", + "integrity": "sha512-5e+SFVavj1ORKlKaKr2BmTOekmXbelU7dC0cDkQLqag7xfuTPuGMUFx7KWJuv4bYZrTsoL2Z18VVCOKYxzoHcg==", + "dev": true, + "dependencies": { + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=v12.0.0" + } + }, "node_modules/@mdn/browser-compat-data": { "version": "5.4.3", "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.4.3.tgz", @@ -539,6 +566,12 @@ "@types/node": "*" } }, + "node_modules/@types/linkify-it": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz", + "integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==", + "dev": true + }, "node_modules/@types/lodash": { "version": "4.14.178", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz", @@ -572,6 +605,22 @@ "@types/lodash": "*" } }, + "node_modules/@types/markdown-it": { + "version": "12.2.3", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", + "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "dev": true, + "dependencies": { + "@types/linkify-it": "*", + "@types/mdurl": "*" + } + }, + "node_modules/@types/mdurl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz", + "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==", + "dev": true + }, "node_modules/@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", @@ -1101,6 +1150,16 @@ "node": ">=12.0.0" } }, + "node_modules/@wikimedia/codex-design-tokens": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@wikimedia/codex-design-tokens/-/codex-design-tokens-1.1.1.tgz", + "integrity": "sha512-qFX7LcR/l90yqVTBApvrIDY3Xa0WifoMlBJRGD1DoWff8e/yMhLmxF1o2DRcIfQlOvKDg0Vhy8jAttF6MUfMAA==", + "dev": true, + "engines": { + "node": ">=16", + "npm": ">=7.21.0" + } + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -1964,6 +2023,18 @@ "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", "dev": true }, + "node_modules/catharsis": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", + "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", + "dev": true, + "dependencies": { + "lodash": "^4.17.15" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -2866,6 +2937,12 @@ "url": "https://github.com/fb55/domhandler?sponsor=1" } }, + "node_modules/domino": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/domino/-/domino-2.1.6.tgz", + "integrity": "sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ==", + "dev": true + }, "node_modules/domutils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", @@ -5260,12 +5337,56 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/js2xmlparser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", + "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", + "dev": true, + "dependencies": { + "xmlcreate": "^2.0.4" + } + }, "node_modules/jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", "dev": true }, + "node_modules/jsdoc": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.2.tgz", + "integrity": "sha512-e8cIg2z62InH7azBBi3EsSEqrKx+nUtAS5bBcYTSpZFA+vhNPyhv8PTFZ0WsjOPDj04/dOLlm08EDcQJDqaGQg==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.15", + "@jsdoc/salty": "^0.2.1", + "@types/markdown-it": "^12.2.3", + "bluebird": "^3.7.2", + "catharsis": "^0.9.0", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.2", + "klaw": "^3.0.0", + "markdown-it": "^12.3.2", + "markdown-it-anchor": "^8.4.1", + "marked": "^4.0.10", + "mkdirp": "^1.0.4", + "requizzle": "^0.2.3", + "strip-json-comments": "^3.1.0", + "underscore": "~1.13.2" + }, + "bin": { + "jsdoc": "jsdoc.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/jsdoc-class-hierarchy": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/jsdoc-class-hierarchy/-/jsdoc-class-hierarchy-1.1.2.tgz", + "integrity": "sha512-oU7UgWr0Qbtxd2J81/ee1lM8xAdyUU7B1ZosVwZxJwjhPWvtkX9ooHjD1Fk97OyOlpTBXxYVTpptvSCKRt8wvQ==", + "dev": true + }, "node_modules/jsdoc-type-pratt-parser": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", @@ -5275,6 +5396,41 @@ "node": ">=12.0.0" } }, + "node_modules/jsdoc-wmf-theme": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-wmf-theme/-/jsdoc-wmf-theme-1.0.0.tgz", + "integrity": "sha512-DAR0Rna+X5/Hzlmt297Y05BLPGdUfBUBXfdMwiSJjh8cpLZxt9lHjw2SYnzOpPAPuJYWW3t6MkoJMG0i9cv+uQ==", + "dev": true, + "dependencies": { + "@jsdoc/salty": "^0.2.7", + "@wikimedia/codex-design-tokens": "1.1.1", + "domino": "^2.1.6", + "lunr": "2.3.9", + "marked": "^12.0.1", + "normalize.css": "8.0.1" + } + }, + "node_modules/jsdoc-wmf-theme/node_modules/marked": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-12.0.2.tgz", + "integrity": "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==", + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/jsdoc/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/jsesc": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", @@ -5383,6 +5539,15 @@ "node": ">=0.10.0" } }, + "node_modules/klaw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.9" + } + }, "node_modules/known-css-properties": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.27.0.tgz", @@ -5568,6 +5733,15 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "dev": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, "node_modules/livereload-js": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz", @@ -5766,6 +5940,12 @@ "node": ">=10" } }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, "node_modules/make-dir": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", @@ -5811,6 +5991,59 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it-anchor": { + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", + "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", + "dev": true, + "peerDependencies": { + "@types/markdown-it": "*", + "markdown-it": "*" + } + }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/marky": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/marky/-/marky-1.2.4.tgz", @@ -5833,6 +6066,12 @@ "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", "dev": true }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, "node_modules/meow": { "version": "10.1.5", "resolved": "https://registry.npmjs.org/meow/-/meow-10.1.5.tgz", @@ -6312,6 +6551,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/normalize.css": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz", + "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==", + "dev": true + }, "node_modules/nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -7484,6 +7729,15 @@ "node": ">=0.10.5" } }, + "node_modules/requizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", + "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.21" + } + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -8753,6 +9007,12 @@ "node": "*" } }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, "node_modules/unbzip2-stream": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", @@ -8772,6 +9032,12 @@ "node": ">=0.10.0" } }, + "node_modules/underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", + "dev": true + }, "node_modules/underscore.string": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", @@ -9178,6 +9444,12 @@ "node": ">=8.0" } }, + "node_modules/xmlcreate": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", + "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", + "dev": true + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -9551,6 +9823,12 @@ } } }, + "@babel/parser": { + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz", + "integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==", + "dev": true + }, "@csstools/css-parser-algorithms": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.3.1.tgz", @@ -9680,6 +9958,15 @@ "chalk": "^4.0.0" } }, + "@jsdoc/salty": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.8.tgz", + "integrity": "sha512-5e+SFVavj1ORKlKaKr2BmTOekmXbelU7dC0cDkQLqag7xfuTPuGMUFx7KWJuv4bYZrTsoL2Z18VVCOKYxzoHcg==", + "dev": true, + "requires": { + "lodash": "^4.17.21" + } + }, "@mdn/browser-compat-data": { "version": "5.4.3", "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.4.3.tgz", @@ -9839,6 +10126,12 @@ "@types/node": "*" } }, + "@types/linkify-it": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz", + "integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==", + "dev": true + }, "@types/lodash": { "version": "4.14.178", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz", @@ -9872,6 +10165,22 @@ "@types/lodash": "*" } }, + "@types/markdown-it": { + "version": "12.2.3", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", + "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "dev": true, + "requires": { + "@types/linkify-it": "*", + "@types/mdurl": "*" + } + }, + "@types/mdurl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz", + "integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==", + "dev": true + }, "@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", @@ -10297,6 +10606,12 @@ "p-iteration": "^1.1.8" } }, + "@wikimedia/codex-design-tokens": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@wikimedia/codex-design-tokens/-/codex-design-tokens-1.1.1.tgz", + "integrity": "sha512-qFX7LcR/l90yqVTBApvrIDY3Xa0WifoMlBJRGD1DoWff8e/yMhLmxF1o2DRcIfQlOvKDg0Vhy8jAttF6MUfMAA==", + "dev": true + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -10931,6 +11246,15 @@ "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", "dev": true }, + "catharsis": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", + "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -11624,6 +11948,12 @@ "domelementtype": "^2.3.0" } }, + "domino": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/domino/-/domino-2.1.6.tgz", + "integrity": "sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ==", + "dev": true + }, "domutils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", @@ -13427,18 +13757,86 @@ "esprima": "^4.0.0" } }, + "js2xmlparser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", + "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", + "dev": true, + "requires": { + "xmlcreate": "^2.0.4" + } + }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", "dev": true }, + "jsdoc": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.2.tgz", + "integrity": "sha512-e8cIg2z62InH7azBBi3EsSEqrKx+nUtAS5bBcYTSpZFA+vhNPyhv8PTFZ0WsjOPDj04/dOLlm08EDcQJDqaGQg==", + "dev": true, + "requires": { + "@babel/parser": "^7.20.15", + "@jsdoc/salty": "^0.2.1", + "@types/markdown-it": "^12.2.3", + "bluebird": "^3.7.2", + "catharsis": "^0.9.0", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.2", + "klaw": "^3.0.0", + "markdown-it": "^12.3.2", + "markdown-it-anchor": "^8.4.1", + "marked": "^4.0.10", + "mkdirp": "^1.0.4", + "requizzle": "^0.2.3", + "strip-json-comments": "^3.1.0", + "underscore": "~1.13.2" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } + } + }, + "jsdoc-class-hierarchy": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/jsdoc-class-hierarchy/-/jsdoc-class-hierarchy-1.1.2.tgz", + "integrity": "sha512-oU7UgWr0Qbtxd2J81/ee1lM8xAdyUU7B1ZosVwZxJwjhPWvtkX9ooHjD1Fk97OyOlpTBXxYVTpptvSCKRt8wvQ==", + "dev": true + }, "jsdoc-type-pratt-parser": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", "dev": true }, + "jsdoc-wmf-theme": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-wmf-theme/-/jsdoc-wmf-theme-1.0.0.tgz", + "integrity": "sha512-DAR0Rna+X5/Hzlmt297Y05BLPGdUfBUBXfdMwiSJjh8cpLZxt9lHjw2SYnzOpPAPuJYWW3t6MkoJMG0i9cv+uQ==", + "dev": true, + "requires": { + "@jsdoc/salty": "^0.2.7", + "@wikimedia/codex-design-tokens": "1.1.1", + "domino": "^2.1.6", + "lunr": "2.3.9", + "marked": "^12.0.1", + "normalize.css": "8.0.1" + }, + "dependencies": { + "marked": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-12.0.2.tgz", + "integrity": "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==", + "dev": true + } + } + }, "jsesc": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", @@ -13530,6 +13928,15 @@ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, + "klaw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.9" + } + }, "known-css-properties": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.27.0.tgz", @@ -13705,6 +14112,15 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, "livereload-js": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz", @@ -13871,6 +14287,12 @@ "yallist": "^4.0.0" } }, + "lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, "make-dir": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", @@ -13901,6 +14323,46 @@ "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true }, + "markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "dev": true, + "requires": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true + } + } + }, + "markdown-it-anchor": { + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", + "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", + "dev": true, + "requires": {} + }, + "marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "dev": true + }, "marky": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/marky/-/marky-1.2.4.tgz", @@ -13919,6 +14381,12 @@ "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", "dev": true }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, "meow": { "version": "10.1.5", "resolved": "https://registry.npmjs.org/meow/-/meow-10.1.5.tgz", @@ -14276,6 +14744,12 @@ "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", "dev": true }, + "normalize.css": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz", + "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==", + "dev": true + }, "nth-check": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", @@ -15135,6 +15609,15 @@ "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", "dev": true }, + "requizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", + "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", + "dev": true, + "requires": { + "lodash": "^4.17.21" + } + }, "resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -16106,6 +16589,12 @@ "integrity": "sha512-K9mwJm/DaB6mRLZfw6q8IMXipcrmuT6yfhYmwhAkuh+81sChuYstYA+znlgaflUPaYUa3odxKPKGw6Vw/lANew==", "dev": true }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, "unbzip2-stream": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", @@ -16122,6 +16611,12 @@ "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", "dev": true }, + "underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", + "dev": true + }, "underscore.string": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", @@ -16418,6 +16913,12 @@ "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", "dev": true }, + "xmlcreate": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", + "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", + "dev": true + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index a6964df8d..0a8a99a04 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "description": "Build tools for Echo.", "scripts": { "test": "grunt test", - "doc": "jsduck", + "doc": "jsdoc -c .jsdoc.json", "minify:svg": "svgo --config=.svgo.config.js --quiet --recursive --folder modules/icons/", "selenium-test": "wdio tests/selenium/wdio.conf.js", "selenium-daily": "npm run selenium-test -- --mochaOpts.grep @daily" @@ -22,6 +22,9 @@ "grunt-contrib-watch": "1.1.0", "grunt-eslint": "24.3.0", "grunt-stylelint": "0.19.0", + "jsdoc": "4.0.2", + "jsdoc-class-hierarchy": "1.1.2", + "jsdoc-wmf-theme": "1.0.0", "stylelint-config-wikimedia": "0.16.1", "svgo": "3.2.0", "wdio-mediawiki": "2.3.0"