/*!
* VisualEditor UserInterface TriggerRegistry class.
*
* @copyright See AUTHORS.txt
*/
/**
* Trigger registry.
*
* @class
* @extends OO.Registry
* @constructor
*/
ve.ui.TriggerRegistry = function VeUiTriggerRegistry() {
// Parent constructor
ve.ui.TriggerRegistry.super.call( this );
this.triggersByString = {};
};
/* Inheritance */
OO.inheritClass( ve.ui.TriggerRegistry, OO.Registry );
/* Methods */
/**
* Register a constructor with the factory.
*
* The only supported platforms are 'mac' and 'pc'. All platforms not identified as 'mac' will be
* considered to be 'pc', including 'win', 'linux', 'solaris', etc.
*
* @param {string|string[]} name Symbolic name or list of symbolic names. Will trigger a command with
* the same name.
* @param {ve.ui.Trigger[]|Object} triggers Trigger object(s) or map of trigger object(s) keyed by
* platform name e.g. 'mac' or 'pc'
* @throws {Error} Trigger must be an instance of ve.ui.Trigger
* @throws {Error} Incomplete trigger
*/
ve.ui.TriggerRegistry.prototype.register = function ( name, triggers ) {
const platform = ve.getSystemPlatform(),
platformKey = platform === 'mac' ? 'mac' : 'pc';
let triggerList;
if ( ve.isPlainObject( triggers ) ) {
if ( Object.prototype.hasOwnProperty.call( triggers, platformKey ) ) {
triggerList = Array.isArray( triggers[ platformKey ] ) ? triggers[ platformKey ] : [ triggers[ platformKey ] ];
} else {
return;
}
} else {
triggerList = Array.isArray( triggers ) ? triggers : [ triggers ];
}
// Validate arguments
for ( let i = 0, l = triggerList.length; i < l; i++ ) {
const trigger = triggerList[ i ];
if ( !( triggerList[ i ] instanceof ve.ui.Trigger ) ) {
throw new Error( 'Trigger must be an instance of ve.ui.Trigger' );
}
if ( !triggerList[ i ].isComplete() ) {
throw new Error( 'Incomplete trigger' );
}
this.triggersByString[ trigger.toString() ] = name;
}
ve.ui.TriggerRegistry.super.prototype.register.call( this, name, triggerList );
};
/**
* Get trigger name from its string representation
*
* @param {string} triggerString Normalized trigger string (generated by Trigger.toString)
* @return {string|undefined} Trigger name, if found
*/
ve.ui.TriggerRegistry.prototype.getNameByTrigger = function ( triggerString ) {
return this.triggersByString[ triggerString ];
};
/**
* Get trigger messages for a trigger by name
*
* @param {string} name Symbolic name
* @return {string[]} List of trigger messages
*/
ve.ui.TriggerRegistry.prototype.getMessages = function ( name ) {
return ( this.lookup( name ) || [] ).map( ( trigger ) => trigger.getMessage() );
};
/* Initialization */
ve.ui.triggerRegistry = new ve.ui.TriggerRegistry();
/* Registrations */
ve.ui.triggerRegistry.register(
'undo', { mac: new ve.ui.Trigger( 'cmd+z' ), pc: new ve.ui.Trigger( 'ctrl+z' ) }
);
ve.ui.triggerRegistry.register(
'redo', {
mac: [
new ve.ui.Trigger( 'cmd+shift+z' ),
new ve.ui.Trigger( 'cmd+y' )
],
pc: [
new ve.ui.Trigger( 'ctrl+shift+z' ),
new ve.ui.Trigger( 'ctrl+y' )
]
}
);
ve.ui.triggerRegistry.register(
'bold', { mac: new ve.ui.Trigger( 'cmd+b' ), pc: new ve.ui.Trigger( 'ctrl+b' ) }
);
ve.ui.triggerRegistry.register(
'italic', { mac: new ve.ui.Trigger( 'cmd+i' ), pc: new ve.ui.Trigger( 'ctrl+i' ) }
);
ve.ui.triggerRegistry.register(
'link', { mac: new ve.ui.Trigger( 'cmd+k' ), pc: new ve.ui.Trigger( 'ctrl+k' ) }
);
ve.ui.triggerRegistry.register(
'clear', {
mac: [
new ve.ui.Trigger( 'cmd+\\' )
],
pc: [
new ve.ui.Trigger( 'ctrl+\\' ),
new ve.ui.Trigger( 'ctrl+m' )
]
}
);
ve.ui.triggerRegistry.register(
'underline', { mac: new ve.ui.Trigger( 'cmd+u' ), pc: new ve.ui.Trigger( 'ctrl+u' ) }
);
ve.ui.triggerRegistry.register(
'code', { mac: new ve.ui.Trigger( 'cmd+shift+6' ), pc: new ve.ui.Trigger( 'ctrl+shift+6' ) }
);
ve.ui.triggerRegistry.register(
'strikethrough', { mac: new ve.ui.Trigger( 'cmd+shift+5' ), pc: new ve.ui.Trigger( 'ctrl+shift+5' ) }
);
ve.ui.triggerRegistry.register(
'subscript', { mac: new ve.ui.Trigger( 'cmd+,' ), pc: new ve.ui.Trigger( 'ctrl+,' ) }
);
ve.ui.triggerRegistry.register(
'superscript', { mac: new ve.ui.Trigger( 'cmd+.' ), pc: new ve.ui.Trigger( 'ctrl+.' ) }
);
ve.ui.triggerRegistry.register(
'indent', {
mac: [
new ve.ui.Trigger( 'tab' ),
new ve.ui.Trigger( 'cmd+]' )
],
pc: [
new ve.ui.Trigger( 'tab' ),
new ve.ui.Trigger( 'ctrl+]' )
]
}
);
ve.ui.triggerRegistry.register(
'outdent', {
mac: [
new ve.ui.Trigger( 'shift+tab' ),
new ve.ui.Trigger( 'cmd+[' )
],
pc: [
new ve.ui.Trigger( 'shift+tab' ),
new ve.ui.Trigger( 'ctrl+[' )
]
}
);
ve.ui.triggerRegistry.register(
'commandHelp', {
mac: [
new ve.ui.Trigger( 'cmd+/' ),
new ve.ui.Trigger( 'cmd+shift+/' ) // =cmd+? on most systems, but not all
],
pc: [
new ve.ui.Trigger( 'ctrl+/' ),
new ve.ui.Trigger( 'ctrl+shift+/' ) // =ctrl+? on most systems, but not all
]
}
);
// Ctrl+0-7 below are not mapped to Cmd+0-7 on Mac because Chrome reserves those for switching tabs
ve.ui.triggerRegistry.register(
'paragraph', new ve.ui.Trigger( 'ctrl+0' )
);
ve.ui.triggerRegistry.register(
'heading1', new ve.ui.Trigger( 'ctrl+1' )
);
ve.ui.triggerRegistry.register(
'heading2', new ve.ui.Trigger( 'ctrl+2' )
);
ve.ui.triggerRegistry.register(
'heading3', new ve.ui.Trigger( 'ctrl+3' )
);
ve.ui.triggerRegistry.register(
'heading4', new ve.ui.Trigger( 'ctrl+4' )
);
ve.ui.triggerRegistry.register(
'heading5', new ve.ui.Trigger( 'ctrl+5' )
);
ve.ui.triggerRegistry.register(
'heading6', new ve.ui.Trigger( 'ctrl+6' )
);
ve.ui.triggerRegistry.register(
'preformatted', new ve.ui.Trigger( 'ctrl+7' )
);
ve.ui.triggerRegistry.register(
'blockquote', new ve.ui.Trigger( 'ctrl+8' )
);
ve.ui.triggerRegistry.register(
'selectAll', { mac: new ve.ui.Trigger( 'cmd+a' ), pc: new ve.ui.Trigger( 'ctrl+a' ) }
);
ve.ui.triggerRegistry.register(
'delete', { mac: new ve.ui.Trigger( 'ctrl+d' ) }
);
ve.ui.triggerRegistry.register(
'pasteSpecial', {
mac: new ve.ui.Trigger( 'cmd+option+shift+v' ),
pc: new ve.ui.Trigger( 'ctrl+shift+v' )
}
);
// Clipboard handlers are registered for use by the commandHelpRegistry.
// Cut/copy/paste are handled by native events.
ve.ui.triggerRegistry.register(
'cut', {
mac: new ve.ui.Trigger( 'cmd+x' ),
pc: new ve.ui.Trigger( 'ctrl+x' )
}
);
ve.ui.triggerRegistry.register(
'copy', {
mac: new ve.ui.Trigger( 'cmd+c' ),
pc: new ve.ui.Trigger( 'ctrl+c' )
}
);
ve.ui.triggerRegistry.register(
'paste', {
mac: new ve.ui.Trigger( 'cmd+v' ),
pc: new ve.ui.Trigger( 'ctrl+v' )
}
);
ve.ui.triggerRegistry.register(
'findAndReplace', { mac: new ve.ui.Trigger( 'cmd+f' ), pc: new ve.ui.Trigger( 'ctrl+f' ) }
);
ve.ui.triggerRegistry.register(
'changeDirectionality', { mac: new ve.ui.Trigger( 'cmd+shift+x' ), pc: new ve.ui.Trigger( 'ctrl+shift+x' ) }
);
ve.ui.triggerRegistry.register(
'findNext', {
mac: new ve.ui.Trigger( 'cmd+g' ),
pc: [
new ve.ui.Trigger( 'ctrl+g' ),
new ve.ui.Trigger( 'f3' )
]
}
);
ve.ui.triggerRegistry.register(
'findPrevious', {
mac: new ve.ui.Trigger( 'cmd+shift+g' ),
pc: [
new ve.ui.Trigger( 'shift+ctrl+g' ),
new ve.ui.Trigger( 'shift+f3' )
]
}
);
ve.ui.triggerRegistry.register(
'enterTableCell', [
new ve.ui.Trigger( 'enter' ),
new ve.ui.Trigger( 'shift+enter' ),
new ve.ui.Trigger( 'f2' )
]
);
ve.ui.triggerRegistry.register(
'submit', {
mac: new ve.ui.Trigger( 'cmd+enter' ),
pc: new ve.ui.Trigger( 'ctrl+enter' )
}
);
ve.ui.triggerRegistry.register(
'cancel', new ve.ui.Trigger( 'escape' )
);
ve.ui.triggerRegistry.register(
'focusContext', {
mac: new ve.ui.Trigger( 'cmd+shift+enter' ),
pc: new ve.ui.Trigger( 'ctrl+shift+enter' )
}
);