'use strict'; /*! * VisualEditor MediaWiki Cite initialisation code. * * @copyright 2011-2018 VisualEditor Team's Cite sub-team and others; see AUTHORS.txt * @license MIT */ ( function () { const MWCitationContextItem = require( './ve.ui.MWCitationContextItem.js' ); const MWCitationDialogTool = require( './ve.ui.MWCitationDialogTool.js' ); const modifiedToolbarGroups = []; mw.hook( 've.newTarget' ).add( ( target ) => { if ( ![ 'article', 'cx' ].includes( target.constructor.static.name ) ) { return; } const toolbarGroups = target.constructor.static.toolbarGroups; if ( modifiedToolbarGroups.includes( toolbarGroups ) ) { return; } if ( mw.config.get( 'wgCiteVisualEditorOtherGroup' ) || // Mobile doesn't have room for a top-level reference group, so place in the 'insert' menu as well ( ve.init.mw.MobileArticleTarget && target instanceof ve.init.mw.MobileArticleTarget ) ) { // Add to the insert group (demoted) const insertGroup = toolbarGroups.find( ( toolbarGroup ) => toolbarGroup.name === 'insert' || // Name used in CX. // TODO: Change this to 'insert' toolbarGroup.name === 'extra' ); if ( insertGroup ) { insertGroup.demote = [ ...( insertGroup.demote || [] ), { group: 'cite' }, 'reference', 'reference/existing' ]; } } else { // Add after the link group const index = toolbarGroups.findIndex( ( toolbarGroup ) => toolbarGroup.name === 'link' ); if ( index !== -1 ) { const group = { name: 'cite', type: 'list', title: OO.ui.deferMsg( 'cite-ve-toolbar-group-label' ), label: OO.ui.deferMsg( 'cite-ve-toolbar-group-label' ), include: [ { group: 'cite' }, 'reference', 'reference/existing' ], demote: [ 'reference', 'reference/existing' ] }; toolbarGroups.splice( index + 1, 0, group ); } else { mw.log.warn( 'No link group find in toolbar to place reference tools next to.' ); } } modifiedToolbarGroups.push( toolbarGroups ); } ); /** * Add reference insertion tools from on-wiki data. * * By adding a definition in JSON to MediaWiki:Cite-tool-definition.json, the cite menu can * be populated with tools that create references containing specific templates. The * content of the definition should be an array containing a series of * objects, one for each tool. Each object must contain a `name`, `icon` and * `template` property. An optional `title` property can also be used to * define the tool title in plain text. The `name` property is a unique * identifier for the tool, and also provides a fallback title for the tool by * being transformed into a message key. The name is prefixed with * `visualeditor-cite-tool-name-`, and messages can be defined on Wiki. Some * common messages are pre-defined for tool names such as `web`, `book`, * `news` and `journal`. * * Example: * [ { "name": "web", "icon": "browser", "template": "Cite web" }, ... ] */ /** Maps deprecated icon names to supported OOUI icon names */ const deprecatedIcons = { 'ref-cite-book': 'book', 'ref-cite-journal': 'journal', 'ref-cite-news': 'newspaper', 'ref-cite-web': 'browser', 'reference-existing': 'referenceExisting' }; /** Maps pre-defined citation tool names to OOUI icon names */ const defaultIcons = { book: 'book', journal: 'journal', news: 'newspaper', web: 'browser' }; // TODO: Replace with require( './ve.ui.MWCitationTools.json' ); ve.ui.mwCitationTools.forEach( ( item ) => { const hasOwn = Object.prototype.hasOwnProperty; const data = { template: item.template, title: item.title }; if ( !item.icon && hasOwn.call( defaultIcons, item.name ) ) { item.icon = defaultIcons[ item.name ]; } if ( hasOwn.call( deprecatedIcons, item.icon ) ) { item.icon = deprecatedIcons[ item.icon ]; } // Generate citation tool const name = 'cite-' + item.name; if ( !ve.ui.toolFactory.lookup( name ) ) { const tool = function GeneratedMWCitationDialogTool() { MWCitationDialogTool.apply( this, arguments ); }; OO.inheritClass( tool, MWCitationDialogTool ); tool.static.group = 'cite'; tool.static.name = name; tool.static.icon = item.icon; if ( mw.config.get( 'wgCiteVisualEditorOtherGroup' ) ) { tool.static.title = mw.msg( 'cite-ve-othergroup-item', item.title ); } else { tool.static.title = item.title; } tool.static.commandName = name; tool.static.template = item.template; tool.static.autoAddToCatchall = false; tool.static.autoAddToGroup = true; tool.static.associatedWindows = [ name ]; ve.ui.toolFactory.register( tool ); ve.ui.commandRegistry.register( new ve.ui.Command( name, 'mwcite', 'open', { args: [ data ], supportedSelections: [ 'linear' ] } ) ); } // Generate citation context item if ( !ve.ui.contextItemFactory.lookup( name ) ) { const contextItem = function GeneratedMWCitationContextItem() { // Parent constructor MWCitationContextItem.apply( this, arguments ); }; OO.inheritClass( contextItem, MWCitationContextItem ); contextItem.static.name = name; contextItem.static.icon = item.icon; contextItem.static.label = item.title; contextItem.static.commandName = name; contextItem.static.template = item.template; // If the grand-parent class (ve.ui.MWReferenceContextItem) is extended // and re-registered (e.g. by Citoid), then the inheritance chain is // broken, and the generic 'reference' context item would show. Instead // manually specify that that context should never show when a more // specific context item is shown. contextItem.static.suppresses = [ 'reference' ]; ve.ui.contextItemFactory.register( contextItem ); } } ); }() );