all files / src/src/ ToolFactory.js

9.09% Statements 4/44
0% Branches 0/34
0% Functions 0/3
10% Lines 4/40
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                                                                                                                                                                                                                                                                         
/**
 * A ToolFactory creates tools on demand. All tools ({@link OO.ui.Tool Tools},
 * {@link OO.ui.PopupTool PopupTools}, and {@link OO.ui.ToolGroupTool ToolGroupTools}) must be
 * registered with a tool factory. Tools are registered by their symbolic name. See
 * {@link OO.ui.Toolbar toolbars} for an example.
 *
 * For more information about toolbars in general, please see the
 * [OOUI documentation on MediaWiki][1].
 *
 * [1]: https://www.mediawiki.org/wiki/OOUI/Toolbars
 *
 * @class
 * @extends OO.Factory
 * @constructor
 */
OO.ui.ToolFactory = function OoUiToolFactory() {
	// Parent constructor
	OO.ui.ToolFactory.super.call( this );
};
 
/* Setup */
 
OO.inheritClass( OO.ui.ToolFactory, OO.Factory );
 
/* Methods */
 
/**
 * Get tools from the factory.
 *
 * @param {Array|string} include Included tools, see #extract for format
 * @param {Array|string} exclude Excluded tools, see #extract for format
 * @param {Array|string} promote Promoted tools, see #extract for format
 * @param {Array|string} demote Demoted tools, see #extract for format
 * @return {string[]} List of tools
 */
OO.ui.ToolFactory.prototype.getTools = function ( include, exclude, promote, demote ) {
	const auto = [],
		used = {};
 
	// Collect included and not excluded tools
	const included = OO.simpleArrayDifference( this.extract( include ), this.extract( exclude ) );
 
	// Promotion
	const promoted = this.extract( promote, used );
	const demoted = this.extract( demote, used );
 
	// Auto
	for ( let i = 0, len = included.length; i < len; i++ ) {
		if ( !used[ included[ i ] ] ) {
			auto.push( included[ i ] );
		}
	}
 
	return promoted.concat( auto ).concat( demoted );
};
 
/**
 * Get a flat list of names from a list of names or groups.
 *
 * Normally, `collection` is an array of tool specifications. Tools can be specified in the
 * following ways:
 *
 * - To include an individual tool, use the symbolic name: `{ name: 'tool-name' }` or `'tool-name'`.
 * - To include all tools in a group, use the group name: `{ group: 'group-name' }`. (To assign the
 *   tool to a group, use OO.ui.Tool.static.group.)
 *
 * Alternatively, to include all tools that are not yet assigned to any other toolgroup, use the
 * catch-all selector `'*'`.
 *
 * If `used` is passed, tool names that appear as properties in this object will be considered
 * already assigned, and will not be returned even if specified otherwise. The tool names extracted
 * by this function call will be added as new properties in the object.
 *
 * @private
 * @param {Array|string} collection List of tools, see above
 * @param {Object.<string,boolean>} [used] Object containing information about used tools, see above
 * @return {string[]} List of extracted tool names
 */
OO.ui.ToolFactory.prototype.extract = function ( collection, used ) {
	const names = [];
 
	collection = !Array.isArray( collection ) ? [ collection ] : collection;
 
	for ( let i = 0, len = collection.length; i < len; i++ ) {
		let item = collection[ i ],
			name, tool;
		if ( item === '*' ) {
			for ( name in this.registry ) {
				tool = this.registry[ name ];
				if (
					// Only add tools by group name when auto-add is enabled
					tool.static.autoAddToCatchall &&
					// Exclude already used tools
					( !used || !used[ name ] )
				) {
					names.push( name );
					if ( used ) {
						used[ name ] = true;
					}
				}
			}
		} else {
			// Allow plain strings as shorthand for named tools
			if ( typeof item === 'string' ) {
				item = { name: item };
			}
			if ( OO.isPlainObject( item ) ) {
				if ( item.group ) {
					for ( name in this.registry ) {
						tool = this.registry[ name ];
						if (
							// Include tools with matching group
							tool.static.group === item.group &&
							// Only add tools by group name when auto-add is enabled
							tool.static.autoAddToGroup &&
							// Exclude already used tools
							( !used || !used[ name ] )
						) {
							names.push( name );
							if ( used ) {
								used[ name ] = true;
							}
						}
					}
				// Include tools with matching name and exclude already used tools
				} else if ( item.name && ( !used || !used[ item.name ] ) ) {
					names.push( item.name );
					if ( used ) {
						used[ item.name ] = true;
					}
				}
			}
		}
	}
	return names;
};