Файловый менеджер - Редактировать - /var/www/html/mediawiki-1.43.1/extensions/VisualEditor/lib/ve/src/ce/keydownhandlers/ve.ce.LinearDeleteKeyDownHandler.js
Ðазад
/*! * VisualEditor ContentEditable linear delete key down handler * * @copyright See AUTHORS.txt */ /* istanbul ignore next */ /** * Delete key down handler for linear selections. * * @class * @extends ve.ce.KeyDownHandler * * @constructor */ ve.ce.LinearDeleteKeyDownHandler = function VeCeLinearDeleteKeyDownHandler() { // Parent constructor - never called because class is fully static // ve.ui.LinearDeleteKeyDownHandler.super.apply( this, arguments ); }; /* Inheritance */ OO.inheritClass( ve.ce.LinearDeleteKeyDownHandler, ve.ce.KeyDownHandler ); /* Static properties */ ve.ce.LinearDeleteKeyDownHandler.static.name = 'linearDelete'; ve.ce.LinearDeleteKeyDownHandler.static.keys = [ OO.ui.Keys.BACKSPACE, OO.ui.Keys.DELETE ]; ve.ce.LinearDeleteKeyDownHandler.static.supportedSelections = [ 'linear' ]; /* Static methods */ /** * @inheritdoc * * The handler just schedules a poll to observe the native content removal, unless * one of the following is true: * - The ctrlKey is down; or * - The selection is expanded; or * - We are directly adjacent to an element node in the deletion direction. * In these cases, it will perform the content removal itself. */ ve.ce.LinearDeleteKeyDownHandler.static.execute = function ( surface, e ) { const direction = e.keyCode === OO.ui.Keys.DELETE ? 1 : -1, unit = ( e.altKey === true || e.ctrlKey === true ) ? 'word' : 'character', documentModel = surface.getModel().getDocument(), focusedNode = surface.getFocusedNode(), uiSurface = surface.getSurface(), data = documentModel.data; let offset = 0, rangeToRemove = surface.getModel().getSelection().getRange(); if ( surface.isReadOnly() ) { e.preventDefault(); return true; } if ( direction === 1 && e.shiftKey && ve.getSystemPlatform() !== 'mac' ) { // Shift+Del on non-Mac platforms performs 'cut', so // don't handle it here. return false; } if ( focusedNode ) { const command = uiSurface.commandRegistry.getDeleteCommandForNode( focusedNode ); if ( command ) { command.execute( uiSurface ); e.preventDefault(); return true; } } // Use native behaviour then poll if collapsed, unless we are adjacent to some hard tag // (or CTRL is down, in which case we can't reliably predict whether the native behaviour // would delete far enough to remove some element) if ( rangeToRemove.isCollapsed() && !e.ctrlKey ) { if ( surface.nativeSelection.focusNode === null ) { // Unexplained failures causing log spam: T262303 // How can it be null when this method should only be called for linear selections? e.preventDefault(); return true; } let position = ve.adjacentDomPosition( { node: surface.nativeSelection.focusNode, offset: surface.nativeSelection.focusOffset }, direction, { stop: ve.isHardCursorStep } ); const skipNode = position.steps[ position.steps.length - 1 ].node; if ( skipNode.nodeType === Node.TEXT_NODE ) { surface.eventSequencer.afterOne( { keydown: surface.surfaceObserver.pollOnce.bind( surface.surfaceObserver ) } ); return true; } let range; // If the native action would delete an outside nail, move *two* cursor positions // in the deletion direction, to get inside the link just past the inside nail, // then preventDefault if ( direction > 0 ? skipNode.classList.contains( 've-ce-nail-pre-open' ) : skipNode.classList.contains( 've-ce-nail-post-close' ) ) { position = ve.adjacentDomPosition( position, direction, { stop: ve.isHardCursorStep } ); range = document.createRange(); range.setStart( position.node, position.offset ); surface.nativeSelection.removeAllRanges(); surface.nativeSelection.addRange( range ); surface.updateActiveAnnotations(); e.preventDefault(); return true; } let pairNode; // If inside an empty link, delete it and preventDefault if ( skipNode.classList && skipNode.classList.contains( direction > 0 ? 've-ce-nail-pre-close' : 've-ce-nail-post-open' ) && ( pairNode = ( direction > 0 ? skipNode.previousSibling : skipNode.nextSibling ) ) && pairNode.classList && pairNode.classList.contains( direction > 0 ? 've-ce-nail-post-open' : 've-ce-nail-pre-close' ) ) { const linkNode = skipNode.parentNode; range = document.createRange(); // Set start to link's offset, minus 1 to allow for outer nail deletion // (browsers actually tend to adjust range offsets automatically // for previous sibling deletion, but just in case …) range.setStart( linkNode.parentNode, ve.parentIndex( linkNode ) - 1 ); // Remove the outer nails, then the link itself linkNode.parentNode.removeChild( linkNode.previousSibling ); linkNode.parentNode.removeChild( linkNode.nextSibling ); linkNode.parentNode.removeChild( linkNode ); surface.nativeSelection.removeAllRanges(); surface.nativeSelection.addRange( range ); surface.updateActiveAnnotations(); e.preventDefault(); return true; } // If the native action would delete an inside nail, move *two* cursor positions // in the deletion direction, to get outside the link just past the outside nail, // then preventDefault if ( direction > 0 ? skipNode.classList.contains( 've-ce-nail-pre-close' ) : skipNode.classList.contains( 've-ce-nail-post-open' ) ) { position = ve.adjacentDomPosition( position, direction, { stop: ve.isHardCursorStep } ); range = document.createRange(); range.setStart( position.node, position.offset ); surface.nativeSelection.removeAllRanges(); surface.nativeSelection.addRange( range ); surface.updateActiveAnnotations(); e.preventDefault(); return true; } offset = rangeToRemove.start; if ( !e.ctrlKey && ( ( direction < 0 && !data.isElementData( offset - 1 ) ) || ( direction > 0 && !data.isElementData( offset ) ) ) ) { surface.eventSequencer.afterOne( { keydown: surface.surfaceObserver.pollOnce.bind( surface.surfaceObserver ) } ); return true; } } // Else range is uncollapsed or is adjacent to a non-nail element. if ( rangeToRemove.isCollapsed() ) { const originalRange = new ve.Range( rangeToRemove.from, rangeToRemove.to ); // Expand rangeToRemove rangeToRemove = documentModel.getRelativeRange( rangeToRemove, direction, unit, true ); if ( surface.getActiveNode() && !surface.getActiveNode().getRange().containsRange( rangeToRemove ) ) { e.preventDefault(); return true; } const documentModelSelectedNodes = documentModel.selectNodes( rangeToRemove, 'siblings' ); for ( let i = 0; i < documentModelSelectedNodes.length; i++ ) { const node = documentModelSelectedNodes[ i ].node; const nodeOuterRange = documentModelSelectedNodes[ i ].nodeOuterRange; let adjacentBlockSelection = null; if ( node instanceof ve.dm.TableNode ) { // Prevent backspacing/deleting over table cells if ( rangeToRemove.containsOffset( nodeOuterRange.start ) ) { adjacentBlockSelection = new ve.dm.TableSelection( nodeOuterRange, 0, 0 ); } else { const matrix = node.getMatrix(); const row = matrix.getRowCount() - 1; const col = matrix.getColCount( row ) - 1; adjacentBlockSelection = new ve.dm.TableSelection( nodeOuterRange, col, row ); } } else if ( node.isFocusable() ) { // Prevent backspacing/deleting over focusable nodes adjacentBlockSelection = new ve.dm.LinearSelection( node.getOuterRange() ); } if ( adjacentBlockSelection ) { // Create a fragment from the selection as we might delete first const adjacentFragment = surface.getModel().getFragment( adjacentBlockSelection, true ); const currentNode = documentModel.getDocumentNode().getNodeFromOffset( originalRange.start ); if ( currentNode.canContainContent() && !currentNode.getLength() ) { // If starting in an empty CBN, delete the CBN instead (T338622) surface.getModel().getLinearFragment( currentNode.getOuterRange(), true ).delete( direction ); } adjacentFragment.select(); e.preventDefault(); return true; } } if ( rangeToRemove.isCollapsed() ) { // For some reason (most likely: we're at the beginning or end of the document) we can't // expand the range. So, should we delete something or not? // The rules are: // * if we're literally at the start or end, and are in a content node, don't do anything // * if we're in a plain paragraph, don't do anything // * if we're in a list item and it's empty get rid of the item offset = rangeToRemove.start; const docLength = documentModel.getDocumentRange().getLength(); if ( offset < docLength - 1 ) { while ( offset < docLength - 1 && data.isCloseElementData( offset ) ) { offset++; } } const startNode = documentModel.getDocumentNode().getNodeFromOffset( offset - 1 ); const nodeRange = startNode.getOuterRange(); if ( // The node is not unwrappable (e.g. table cells, text nodes) !startNode.isUnwrappable() || // Content item at the start / end? ( ( startNode.canContainContent() || surface.attachedRoot === startNode ) && ( nodeRange.start === 0 || nodeRange.end === docLength ) ) ) { e.preventDefault(); return true; } else { // Expand our removal to reflect what we actually need to remove switch ( startNode.getType() ) { case 'list': case 'listItem': uiSurface.execute( 'indentation', 'decrease' ); e.preventDefault(); return; default: if ( direction > 0 ) { rangeToRemove = new ve.Range( rangeToRemove.start, nodeRange.end ); } else { rangeToRemove = new ve.Range( nodeRange.start, rangeToRemove.start - 1 ); } } } } } surface.getModel().getLinearFragment( rangeToRemove, true ).delete( direction ).select(); // Rerender selection even if it didn't change // TODO: is any of this necessary? surface.focus(); surface.surfaceObserver.clear(); // Check delete sequences surface.findAndExecuteSequences( false, true ); e.preventDefault(); return true; }; /* Registration */ ve.ce.keyDownHandlerFactory.register( ve.ce.LinearDeleteKeyDownHandler );
| ver. 1.1 | |
.
| PHP 8.4.18 | Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ñтраницы: 0 |
proxy
|
phpinfo
|
ÐаÑтройка