- *
- * @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"