Файловый менеджер - Редактировать - /var/www/html/mediawiki-1.43.1/extensions/VisualEditor/lib/ve/src/ce/keydownhandlers/ve.ce.LinearEnterKeyDownHandler.js
Ðазад
/*! * VisualEditor ContentEditable linear enter key down handler * * @copyright See AUTHORS.txt */ /* istanbul ignore next */ /** * Enter key down handler for linear selections. * * @class * @extends ve.ce.KeyDownHandler * * @constructor */ ve.ce.LinearEnterKeyDownHandler = function VeCeLinearEnterKeyDownHandler() { // Parent constructor - never called because class is fully static // ve.ui.LinearEnterKeyDownHandler.super.apply( this, arguments ); }; /* Inheritance */ OO.inheritClass( ve.ce.LinearEnterKeyDownHandler, ve.ce.KeyDownHandler ); /* Static properties */ ve.ce.LinearEnterKeyDownHandler.static.name = 'linearEnter'; ve.ce.LinearEnterKeyDownHandler.static.keys = [ OO.ui.Keys.ENTER ]; ve.ce.LinearEnterKeyDownHandler.static.supportedSelections = [ 'linear' ]; /* Static methods */ /** * @inheritdoc */ ve.ce.LinearEnterKeyDownHandler.static.execute = function ( surface, e ) { const documentModel = surface.model.getDocument(), emptyParagraph = [ { type: 'paragraph' }, { type: '/paragraph' } ]; let range = surface.model.getSelection().getRange(), cursor = range.from, advanceCursor = true, outermostNode = null, nodeModel = null, nodeModelRange = null; e.preventDefault(); if ( e.ctrlKey || e.metaKey ) { // CTRL+Enter triggers the submit command return false; } const focusedNode = surface.getFocusedNode(); if ( focusedNode ) { if ( focusedNode.getModel().isEditable() ) { focusedNode.executeCommand(); } return true; } if ( surface.isReadOnly() ) { return true; } let node = surface.getDocument().getBranchNodeFromOffset( range.from ); if ( !node.isMultiline() ) { return true; } // Handle removal first if ( !range.isCollapsed() ) { const txRemove = ve.dm.TransactionBuilder.static.newFromRemoval( documentModel, range ); range = txRemove.translateRange( range ); // We do want this to propagate to the surface surface.model.change( txRemove, new ve.dm.LinearSelection( range ) ); // Remove may have changed node at range.from node = surface.getDocument().getBranchNodeFromOffset( range.from ); } if ( node !== null ) { // Assertion: node is certainly a contentBranchNode nodeModel = node.getModel(); nodeModelRange = nodeModel.getRange(); } let txInsert; // Handle insertion if ( node === null ) { throw new Error( 'node === null' ); } else if ( e.shiftKey && nodeModel.hasSignificantWhitespace() ) { // Insert newline txInsert = ve.dm.TransactionBuilder.static.newFromInsertion( documentModel, range.from, '\n' ); } else if ( nodeModel.getType() !== 'paragraph' && ( cursor === nodeModelRange.from || cursor === nodeModelRange.to ) ) { // If we're at the start/end of something that's not a paragraph, insert a paragraph // before/after. Insert after for empty nodes (from === to). if ( cursor === nodeModelRange.to ) { txInsert = ve.dm.TransactionBuilder.static.newFromInsertion( documentModel, nodeModel.getOuterRange().to, emptyParagraph ); } else if ( cursor === nodeModelRange.from ) { txInsert = ve.dm.TransactionBuilder.static.newFromInsertion( documentModel, nodeModel.getOuterRange().from, emptyParagraph ); advanceCursor = false; } } else if ( !node.splitOnEnter() ) { // Cannot split, so insert some appropriate node let insertEmptyParagraph = false; let prevContentOffset; if ( documentModel.hasSlugAtOffset( range.from ) ) { insertEmptyParagraph = true; } else { prevContentOffset = documentModel.data.getNearestContentOffset( cursor, -1 ); if ( prevContentOffset === -1 ) { insertEmptyParagraph = true; } } if ( insertEmptyParagraph ) { txInsert = ve.dm.TransactionBuilder.static.newFromInsertion( documentModel, cursor, emptyParagraph ); } else { // Act as if cursor were at previous content offset cursor = prevContentOffset; node = surface.documentView.getBranchNodeFromOffset( cursor ); txInsert = undefined; // Continue to traverseUpstream below. That will succeed because all // ContentBranchNodes have splitOnEnter === true. } insertEmptyParagraph = undefined; } // Assertion: if txInsert === undefined then node.splitOnEnter() === true function getSplitData( n ) { const stack = []; n.traverseUpstream( ( parent ) => { if ( !parent.splitOnEnter() ) { return false; } stack.splice( stack.length / 2, 0, { type: '/' + parent.type }, parent.getModel().getClonedElement( true, true ) ); outermostNode = parent; if ( e.shiftKey ) { return false; } else { return true; } } ); return stack; } if ( txInsert === undefined ) { // This node has splitOnEnter = true. Traverse upstream until the first node // that has splitOnEnter = false, splitting each node as it is reached. Set // outermostNode to the last splittable node. let splitData = getSplitData( node ); const outerParent = outermostNode.getParent(); const outerChildrenCount = outerParent.getChildren().length; if ( // Parent removes empty last children outerParent.removeEmptyLastChildOnEnter() && // This is the last child outerParent.getChildren()[ outerChildrenCount - 1 ] === outermostNode && ( // Contains one empty ContentBranchNode ( outermostNode.children.length === 1 && node.getModel().length === 0 ) || // ..or is an empty ContentBranchNode ( outermostNode.canContainContent() && outermostNode.getModel().length === 0 ) ) ) { // Enter was pressed in an empty last child const container = outerParent.getParent(); advanceCursor = false; if ( outerChildrenCount === 1 ) { // The item we're about to remove is the only child // Remove the ouerParent txInsert = ve.dm.TransactionBuilder.static.newFromRemoval( documentModel, outerParent.getOuterRange() ); } else { // Remove the item txInsert = ve.dm.TransactionBuilder.static.newFromRemoval( documentModel, outermostNode.getOuterRange() ); } surface.model.change( txInsert ); range = txInsert.translateRange( range ); // The removed item was in a splitOnEnter node, split it if ( container.splitOnEnter() ) { splitData = getSplitData( container ).concat( emptyParagraph ); txInsert = ve.dm.TransactionBuilder.static.newFromInsertion( documentModel, container.getOuterRange().to - 1, splitData ); } else if ( outerParent.getChildren().length ) { // Otherwise just insert a paragraph txInsert = ve.dm.TransactionBuilder.static.newFromInsertion( documentModel, outerParent.getOuterRange().to, emptyParagraph ); } else { // Parent was emptied, nothing more to do txInsert = null; } // Advance the cursor into the new paragraph advanceCursor = true; } else { // We must process the transaction first because getRelativeContentOffset can't help us yet txInsert = ve.dm.TransactionBuilder.static.newFromInsertion( documentModel, range.from, splitData ); } } // Commit the transaction if ( txInsert ) { surface.model.change( txInsert ); range = txInsert.translateRange( range ); } // Now we can move the cursor forward if ( advanceCursor ) { cursor = documentModel.data.getRelativeContentOffset( range.from, 1 ); } else { cursor = documentModel.data.getNearestContentOffset( range.from ); } if ( cursor === -1 ) { // Cursor couldn't be placed in a nearby content node, so create an empty paragraph surface.model.change( ve.dm.TransactionBuilder.static.newFromInsertion( documentModel, range.from, emptyParagraph ) ); surface.model.setLinearSelection( new ve.Range( range.from + 1 ) ); } else { surface.model.setLinearSelection( new ve.Range( cursor ) ); } // Reset and resume polling surface.surfaceObserver.clear(); // TODO: This setTimeout appears to be unnecessary (we're not render-locked) setTimeout( () => { surface.findAndExecuteSequences(); } ); return true; }; /* Registration */ ve.ce.keyDownHandlerFactory.register( ve.ce.LinearEnterKeyDownHandler );
| ver. 1.1 | |
.
| PHP 8.4.18 | Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ñтраницы: 0 |
proxy
|
phpinfo
|
ÐаÑтройка