summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/Cite/modules/ve-cite/ve.ui.MWReference.init.js
blob: c8a6be197faf478b3fd7c0c4408736b5d7b2c19f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*!
 * VisualEditor MediaWiki Cite initialisation code.
 *
 * @copyright 2011-2018 VisualEditor Team's Cite sub-team and others; see AUTHORS.txt
 * @license MIT
 */
( function () {
	var i, j, jLen, toolGroup, toolGroups, linkIndex, target, label, group;

	// HACK: Find the position of the current citation toolbar definition
	// and manipulate it.

	targetLoop:
	for ( i in ve.init.mw ) {
		target = ve.init.mw[ i ];
		if ( !target || !( target.prototype instanceof ve.init.Target ) ) {
			continue;
		}
		toolGroups = target.static.toolbarGroups;
		linkIndex = toolGroups.length;

		if ( mw.config.get( 'wgCiteVisualEditorOtherGroup' ) ) {
			for ( j = 0; j < linkIndex; j++ ) {
				toolGroup = toolGroups[ j ];
				if ( toolGroup.include === '*' && ( !toolGroup.demote || toolGroup.demote.indexOf( 'reference' ) === -1 ) ) {
					toolGroup.demote = toolGroup.demote || [];
					toolGroup.demote.push( { group: 'cite' }, 'reference', 'reference/existing' );
				}
			}
			continue;
		}

		for ( j = 0, jLen = toolGroups.length; j < jLen; j++ ) {
			if ( ve.getProp( toolGroups[ j ], 'include', 0, 'group' ) === 'cite' ) {
				// Skip if the cite group exists already
				linkIndex = -1;
				continue targetLoop;
			}
		}
		// Looking through the object to find what we actually need
		// to replace. This way, if toolbarGroups are changed in VE code
		// we won't have to manually change the index here.
		for ( j = 0, jLen = toolGroups.length; j < jLen; j++ ) {
			if ( ve.getProp( toolGroups[ j ], 'include', 0 ) === 'link' ) {
				linkIndex = j;
				break;
			}
		}

		label = OO.ui.deferMsg( 'cite-ve-toolbar-group-label' );
		group = {
			classes: [ 've-test-toolbar-cite' ],
			type: 'list',
			indicator: 'down',
			include: [ { group: 'cite' }, 'reference', 'reference/existing' ],
			demote: [ 'reference', 'reference/existing' ]
		};

		// Treat mobile targets differently
		if ( ve.init.mw.MobileArticleTarget && target.prototype instanceof ve.init.mw.MobileArticleTarget ) {
			group.header = label;
			group.title = label;
			group.icon = 'reference';
		} else {
			group.label = label;
		}

		// Insert a new group for references after the link group (or at the end).
		toolGroups.splice( linkIndex + 1, 0, group );
	}

	/**
	 * Add reference insertion tools from on-wiki data.
	 *
	 * By adding a definition in JSON to MediaWiki:Visualeditor-cite-tool-definition, the cite menu can
	 * be populated with tools that create refrences containing a 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": "cite-web", "template": "Cite web" }, ... ]
	 *
	 */
	( function () {
		var i, len, item, name, data, tool, tools, dialog, contextItem,
			limit = 5;

		try {
			// Must use mw.message to avoid JSON being parsed as Wikitext
			tools = JSON.parse( mw.message( 'cite-tool-definition.json' ).plain() );
		} catch ( e ) {}
		if ( !tools ) {
			try {
				// Must use mw.message to avoid JSON being parsed as Wikitext
				tools = JSON.parse( mw.message( 'visualeditor-cite-tool-definition.json' ).plain() );
			} catch ( e ) {}
		}

		if ( Array.isArray( tools ) ) {
			for ( i = 0, len = Math.min( limit, tools.length ); i < len; i++ ) {
				item = tools[ i ];
				data = { template: item.template };

				// Generate citation tool
				name = 'cite-' + item.name;
				if ( !ve.ui.toolFactory.lookup( name ) ) {
					tool = function GeneratedMWCitationDialogTool() {
						ve.ui.MWCitationDialogTool.apply( this, arguments );
					};
					OO.inheritClass( tool, ve.ui.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: [ name, data ], supportedSelections: [ 'linear' ] }
						)
					);
				}

				// Generate citation context item
				if ( !ve.ui.contextItemFactory.lookup( name ) ) {
					contextItem = function GeneratedMWCitationContextItem() {
						// Parent constructor
						ve.ui.MWCitationContextItem.apply( this, arguments );
					};
					OO.inheritClass( contextItem, ve.ui.MWCitationContextItem );
					contextItem.static.name = name;
					contextItem.static.icon = item.icon;
					contextItem.static.label = item.title;
					contextItem.static.commandName = name;
					contextItem.static.template = item.template;
					ve.ui.contextItemFactory.register( contextItem );
				}

				// Generate dialog
				if ( !ve.ui.windowFactory.lookup( name ) ) {
					dialog = function GeneratedMWCitationDialog() {
						ve.ui.MWCitationDialog.apply( this, arguments );
					};
					OO.inheritClass( dialog, ve.ui.MWCitationDialog );
					dialog.static.name = name;
					dialog.static.title = item.title;
					ve.ui.windowFactory.register( dialog );
				}
			}
		}
	}() );

}() );