Файловый менеджер - Редактировать - /var/www/html/mediawiki-1.43.1/extensions/VisualEditor/lib/ve/src/ui/widgets/ve.ui.CompletionWidget.js
Ðазад
/*! * VisualEditor UserInterface CompletionWidget class. * * @copyright See AUTHORS.txt */ /** * Widget that displays autocompletion suggestions * * @class * @extends OO.ui.Widget * * @constructor * @param {ve.ui.Surface} surface Surface to complete into * @param {Object} [config] Configuration options * @param {Object} [config.validate] Validation pattern passed to TextInputWidgets * @param {boolean} [config.readOnly=false] Prevent changes to the value of the widget. */ ve.ui.CompletionWidget = function VeUiCompletionWidget( surface, config ) { this.surface = surface; this.surfaceModel = surface.getModel(); // Configuration config = config || { anchor: false }; // Parent constructor ve.ui.CompletionWidget.super.call( this, config ); this.$tabIndexed = this.$element; const $doc = surface.getView().getDocument().getDocumentNode().$element; this.popup = new OO.ui.PopupWidget( { anchor: false, align: 'forwards', hideWhenOutOfView: false, autoFlip: false, width: null, $container: config.$popupContainer || this.surface.$element, containerPadding: config.popupPadding } ); this.input = new OO.ui.TextInputWidget(); this.menu = new OO.ui.MenuSelectWidget( { widget: this, $input: $doc.add( this.input.$input ) } ); // This may be better semantically as a MenuSectionOptionWidget, // but that causes all subsequent options to be indented. this.header = new OO.ui.MenuOptionWidget( { classes: [ 've-ui-completionWidget-header' ], disabled: true } ); this.noResults = new OO.ui.MenuOptionWidget( { label: ve.msg( 'visualeditor-completionwidget-noresults' ), classes: [ 've-ui-completionWidget-noresults' ], disabled: true } ); // Events this.menu.connect( this, { choose: 'onMenuChoose', toggle: 'onMenuToggle' } ); this.input.connect( this, { change: 'update' } ); this.popup.$element.prepend( this.input.$element ); this.popup.$body.append( this.menu.$element ); // Setup this.$element.addClass( 've-ui-completionWidget' ) .append( this.popup.$element ); }; /* Inheritance */ OO.inheritClass( ve.ui.CompletionWidget, OO.ui.Widget ); /** * Setup the completion widget * * @param {ve.ui.Action} action Action which opened the widget * @param {boolean} [isolateInput] Isolate input from the surface */ ve.ui.CompletionWidget.prototype.setup = function ( action, isolateInput ) { const range = this.surfaceModel.getSelection().getCoveringRange(); this.action = action; this.isolateInput = !!isolateInput; this.sequenceLength = this.action.getSequenceLength(); this.initialOffset = range.end - this.sequenceLength; this.input.toggle( this.isolateInput ); if ( this.isolateInput ) { this.wasActive = !this.surface.getView().isDeactivated(); this.surface.getView().deactivate(); this.input.setValue( '' ); setTimeout( () => { this.input.focus(); }, 1 ); } else { this.wasActive = false; } this.update(); this.surfaceModel.connect( this, { select: 'onModelSelect' } ); }; /** * Teardown the completion widget */ ve.ui.CompletionWidget.prototype.teardown = function () { this.tearingDown = true; this.popup.toggle( false ); this.surfaceModel.disconnect( this ); if ( this.wasActive ) { this.surface.getView().activate(); } this.action = undefined; this.tearingDown = false; }; /** * Update the completion widget after the input has changed */ ve.ui.CompletionWidget.prototype.update = function () { const direction = this.surface.getDir(), range = this.getCompletionRange(), boundingRect = this.surface.getView().getSelection( new ve.dm.LinearSelection( range ) ).getSelectionBoundingRect(), style = { top: boundingRect.bottom }; let input; if ( this.isolateInput ) { input = this.input.getValue(); } else { const data = this.surfaceModel.getDocument().data; input = data.getText( false, range ); } if ( direction === 'rtl' ) { // This works because this.$element is a 0x0px box, with the menu positioned relative to it. // If this style was applied to the menu, we'd need to do some math here to align the right // edge of the menu with the right edge of the selection. style.left = boundingRect.right; } else { style.left = boundingRect.left; } this.$element.css( style ); this.updateMenu( input ); this.action.getSuggestions( input ).then( ( suggestions ) => { if ( !this.action ) { // Check widget hasn't been torn down return; } this.menu.clearItems(); let menuItems = suggestions.map( this.action.getMenuItemForSuggestion.bind( this.action ) ); menuItems = this.action.updateMenuItems( menuItems ); this.menu.addItems( menuItems ); this.menu.highlightItem( this.menu.findFirstSelectableItem() ); this.updateMenu( input, suggestions ); } ); }; /** * Update the widget's menu with the latest suggestions * * @param {string} input Input text * @param {Array} suggestions Suggestions */ ve.ui.CompletionWidget.prototype.updateMenu = function ( input, suggestions ) { // Update the header based on the input const label = this.action.getHeaderLabel( input, suggestions ); if ( label !== undefined ) { this.header.setLabel( label ); } if ( this.header.getLabel() !== null ) { this.menu.addItems( [ this.header ], 0 ); } else { this.menu.removeItems( [ this.header ] ); } if ( !this.isolateInput ) { // If there is a header or menu items, show the menu if ( this.menu.items.length ) { this.menu.toggle( true ); this.popup.toggle( true ); // Menu may have changed size, so recalculate position this.popup.updateDimensions(); } else { this.popup.toggle( false ); } } else { if ( !this.menu.items.length ) { this.menu.addItems( [ this.noResults ], 0 ); } this.menu.toggle( true ); this.popup.toggle( true ); this.popup.updateDimensions(); } }; /** * Handle choose events from the menu * * @param {OO.ui.MenuOptionWidget} item Chosen option */ ve.ui.CompletionWidget.prototype.onMenuChoose = function ( item ) { this.action.chooseItem( item, this.getCompletionRange( true ) ); this.teardown(); }; /** * Handle toggle events from the menu * * @param {boolean} visible Menu is visible */ ve.ui.CompletionWidget.prototype.onMenuToggle = function ( visible ) { if ( !visible && !this.tearingDown ) { // Menu was hidden by the user (e.g. pressed ESC) - trigger a teardown this.teardown(); } }; /** * Handle select events from the document model * * @param {ve.dm.Selection} selection Selection */ ve.ui.CompletionWidget.prototype.onModelSelect = function () { const range = this.getCompletionRange(); const countMatches = () => { let matches = this.menu.getItems().length; if ( this.header.getLabel() !== null ) { matches--; } if ( this.action.constructor.static.alwaysIncludeInput ) { matches--; } return matches; }; if ( !range || range.isBackwards() || this.action.shouldAbandon( this.surfaceModel.getDocument().data.getText( false, range ), countMatches() ) ) { this.teardown(); } else { this.update(); } }; /** * Get the range where the user has entered text in the document since opening the widget * * @param {boolean} [withSequence] Include the triggering sequence text in the range * @return {ve.Range|null} Range, null if not valid */ ve.ui.CompletionWidget.prototype.getCompletionRange = function ( withSequence ) { const range = this.surfaceModel.getSelection().getCoveringRange(); if ( !range || !this.action ) { return null; } return new ve.Range( this.initialOffset + ( withSequence ? 0 : this.sequenceLength ), range.end ); };
| ver. 1.1 | |
.
| PHP 8.4.18 | Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ñтраницы: 0 |
proxy
|
phpinfo
|
ÐаÑтройка