%PDF- %PDF-
Direktori : /www/varak.net/wiki.varak.net/extensions/VisualEditor/lib/ve/src/ui/ |
Current File : /www/varak.net/wiki.varak.net/extensions/VisualEditor/lib/ve/src/ui/ve.ui.Sequence.js |
/*! * VisualEditor UserInterface Sequence class. * * @copyright 2011-2016 VisualEditor Team and others; see http://ve.mit-license.org */ /** * Key sequence. * * @class * * @constructor * @param {string} name Symbolic name * @param {string} commandName Command name this sequence executes * @param {string|Array|RegExp} data Data to match. String, linear data array, or regular expression. * When using a RegularExpression always match the end of the sequence with a '$' so that * only sequences next to the user's cursor match. * @param {number} [strip=0] Number of data elements to strip after execution * (from the right) * @param {boolean} [setSelection=false] Whether to set the selection to the * range matching the sequence before executing the command. */ ve.ui.Sequence = function VeUiSequence( name, commandName, data, strip, setSelection ) { this.name = name; this.commandName = commandName; this.data = data; this.strip = strip; this.setSelection = setSelection; }; /* Inheritance */ OO.initClass( ve.ui.Sequence ); /* Methods */ /** * Check if the sequence matches a given offset in the data * * @param {ve.dm.ElementLinearData} data String or linear data * @param {number} offset Offset * @return {ve.Range|null} Range corresponding to the match, or else null */ ve.ui.Sequence.prototype.match = function ( data, offset, plaintext ) { var i, j = offset - 1; if ( this.data instanceof RegExp ) { i = plaintext.search( this.data ); return ( i < 0 ) ? null : new ve.Range( offset - plaintext.length + i, offset ); } for ( i = this.data.length - 1; i >= 0; i--, j-- ) { if ( typeof this.data[ i ] === 'string' ) { if ( this.data[ i ] !== data.getCharacterData( j ) ) { return null; } } else if ( !ve.compare( this.data[ i ], data.getData( j ), true ) ) { return null; } } return new ve.Range( offset - this.data.length, offset ); }; /** * Execute the command associated with the sequence * * @param {ve.ui.Surface} surface surface * @return {boolean} The command executed */ ve.ui.Sequence.prototype.execute = function ( surface, range ) { var command, stripRange, executed, stripFragment, selection, args, surfaceModel = surface.getModel(); if ( surface.getCommands().indexOf( this.getCommandName() ) === -1 ) { return false; } command = surface.commandRegistry.lookup( this.getCommandName() ); if ( !command ) { return false; } if ( this.strip ) { stripRange = surfaceModel.getSelection().getRange(); stripFragment = surfaceModel.getLinearFragment( // noAutoSelect = true, excludeInsertions = true new ve.Range( stripRange.end, stripRange.end - this.strip ), true, true ); } surfaceModel.breakpoint(); if ( this.setSelection ) { selection = surfaceModel.getSelection(); surfaceModel.setLinearSelection( range ); } // For sequences that trigger dialogs, pass an extra flag so the window knows // to un-strip the sequence if it is closed without action. See ve.ui.WindowAction. if ( command.getAction() === 'window' && command.getMethod() === 'open' ) { args = ve.copy( command.args ); args[ 1 ] = args[ 1 ] || {}; args[ 1 ].strippedSequence = !!this.strip; } executed = command.execute( surface, args ); if ( executed && stripFragment ) { // Strip the typed text. This will be undone if the action triggered was // window/open and the window is dismissed stripFragment.removeContent(); } if ( !executed && selection ) { surfaceModel.setSelection( selection ); } return executed; }; /** * Get the symbolic name of the sequence * * @return {string} Symbolic name */ ve.ui.Sequence.prototype.getName = function () { return this.name; }; /** * Get the command name which the sequence will execute * * @return {string} Command name */ ve.ui.Sequence.prototype.getCommandName = function () { return this.commandName; }; /** * Get a representation of the sequence useful for display * * What this means depends a bit on how the sequence was defined: * * It strips out undisplayable things like the paragraph-start marker. * * Regexps are just returned as a toString of the regexp. * * @param {boolean} explode Whether to return the message split up into some * reasonable sequence of inputs required to trigger the sequence (regexps * in sequences will be considered a single "input" as a toString of * the regexp, because they're hard to display no matter what...) * @return {string} Message for display */ ve.ui.Sequence.prototype.getMessage = function ( explode ) { var data; if ( typeof this.data === 'string' ) { data = this.data.split( '' ); } else if ( this.data instanceof RegExp ) { data = [ this.data.toString() ]; } else { data = this.data.filter( function ( key ) { return !ve.isPlainObject( key ); } ); } return explode ? data : data.join( '' ); };