Файловый менеджер - Редактировать - /var/www/html/mediawiki-1.43.1/resources/src/jquery/jquery.textSelection.js
Ðазад
/*! * These plugins provide extra functionality for interaction with textareas. * * - encapsulateSelection: Ported from skins/common/edit.js by Trevor Parscal * © 2009 Wikimedia Foundation (GPLv2) - https://www.wikimedia.org * - getCaretPosition, scrollToCaretPosition: Ported from Wikia's LinkSuggest extension * https://github.com/Wikia/app/blob/c0cd8b763/extensions/wikia/LinkSuggest/js/jquery.wikia.linksuggest.js * © 2010 Inez Korczyński (korczynski@gmail.com) & Jesús Martínez Novo (martineznovo@gmail.com) (GPLv2) */ /** * Do things to the selection in a `<textarea>`, or a textarea-like editable element. * Provided by the `jquery.textSelection` ResourceLoader module. * * @example * mw.loader.using( 'jquery.textSelection' ).then( () => { * const contents = $( '#wpTextbox1' ).textSelection( 'getContents' ); * } ); * * @module jquery.textSelection */ ( function () { /** * Checks if you can try to use insertText (it might still fail). * * @ignore * @return {boolean} */ function supportsInsertText() { return $( this ).data( 'jquery.textSelection' ) === undefined && typeof document.execCommand === 'function' && typeof document.queryCommandSupported === 'function' && document.queryCommandSupported( 'insertText' ); } /** * Insert text into textarea or contenteditable. * * @ignore * @param {HTMLElement} field Field to select. * @param {string} content Text to insert. * @param {Function} fallback To execute as a fallback. */ function execInsertText( field, content, fallback ) { let inserted = false; if ( supportsInsertText() && !( // Support: Chrome, Safari // Inserting multiple lines is very slow in Chrome/Safari (T343795) // If this is ever fixed, remove the dependency on jquery.client $.client.profile().layout === 'webkit' && content.split( '\n' ).length > 100 ) ) { field.focus(); try { if ( // Ensure the field was focused, otherwise we can't use execCommand() to change it. // focus() can fail if e.g. the field is disabled, or its container is inert. document.activeElement === field && // Try to insert document.execCommand( 'insertText', false, content ) ) { inserted = true; } } catch ( e ) {} } // Fallback if ( !inserted ) { fallback.call( field, content ); } } const fn = { /** * Get the contents of the textarea. * * @return {string} * @memberof module:jquery.textSelection */ getContents: function () { return this.val(); }, /** * Set the contents of the textarea, replacing anything that was there before. * * @param {string} content * @return {jQuery} * @chainable * @memberof module:jquery.textSelection */ setContents: function ( content ) { return this.each( function () { const scrollTop = this.scrollTop; this.select(); execInsertText( this, content, function () { $( this ).val( content ); } ); // Setting this.value may scroll the textarea, restore the scroll position this.scrollTop = scrollTop; } ); }, /** * Get the currently selected text in this textarea. * * @return {string} * @memberof module:jquery.textSelection */ getSelection: function () { const el = this.get( 0 ); let val; if ( !el ) { val = ''; } else { val = el.value.slice( el.selectionStart, el.selectionEnd ); } return val; }, /** * Replace the selected text in the textarea with the given text, or insert it at the cursor. * * @param {string} value * @return {jQuery} * @chainable * @memberof module:jquery.textSelection */ replaceSelection: function ( value ) { return this.each( function () { execInsertText( this, value, function () { const allText = $( this ).textSelection( 'getContents' ); const currSelection = $( this ).textSelection( 'getCaretPosition', { startAndEnd: true } ); const startPos = currSelection[ 0 ]; const endPos = currSelection[ 1 ]; $( this ).textSelection( 'setContents', allText.slice( 0, startPos ) + value + allText.slice( endPos ) ); $( this ).textSelection( 'setSelection', { start: startPos, end: startPos + value.length } ); } ); } ); }, /** * Insert text at the beginning and end of a text selection, optionally * inserting text at the caret when selection is empty. * * Also focusses the textarea. * * @param {Object} [options] * @param {string} [options.pre] Text to insert before the cursor/selection * @param {string} [options.peri] Text to insert between pre and post and select afterwards * @param {string} [options.post] Text to insert after the cursor/selection * @param {boolean} [options.ownline=false] Put the inserted text on a line of its own * @param {boolean} [options.replace=false] If there is a selection, replace it with peri * instead of leaving it alone * @param {boolean} [options.selectPeri=true] Select the peri text if it was inserted (but not * if there was a selection and replace==false, or if splitlines==true) * @param {boolean} [options.splitlines=false] If multiple lines are selected, encapsulate * each line individually * @param {number} [options.selectionStart] Position to start selection at * @param {number} [options.selectionEnd=options.selectionStart] Position to end selection at * @return {jQuery} * @chainable * @memberof module:jquery.textSelection */ encapsulateSelection: function ( options ) { return this.each( function () { let selText, isSample, pre = options.pre, post = options.post; /** * Check if the selected text is the same as the insert text * * @ignore */ function checkSelectedText() { if ( !selText ) { selText = options.peri; isSample = true; } else if ( options.replace ) { selText = options.peri; } else { while ( selText.charAt( selText.length - 1 ) === ' ' ) { // Exclude ending space char selText = selText.slice( 0, -1 ); post += ' '; } while ( selText.charAt( 0 ) === ' ' ) { // Exclude prepending space char selText = selText.slice( 1 ); pre = ' ' + pre; } } } /** * Do the splitlines stuff. * * Wrap each line of the selected text with pre and post * * @ignore * @param {string} text Selected text * @param {string} preText Text before * @param {string} postText Text after * @return {string} Wrapped text */ function doSplitLines( text, preText, postText ) { const selTextArr = text.split( '\n' ); let insText = ''; for ( let i = 0; i < selTextArr.length; i++ ) { insText += preText + selTextArr[ i ] + postText; if ( i !== selTextArr.length - 1 ) { insText += '\n'; } } return insText; } isSample = false; $( this ).trigger( 'focus' ); if ( options.selectionStart !== undefined ) { $( this ).textSelection( 'setSelection', { start: options.selectionStart, end: options.selectionEnd } ); } selText = $( this ).textSelection( 'getSelection' ); const allText = $( this ).textSelection( 'getContents' ); const currSelection = $( this ).textSelection( 'getCaretPosition', { startAndEnd: true } ); let startPos = currSelection[ 0 ]; const endPos = currSelection[ 1 ]; checkSelectedText(); let combiningCharSelectionBug = false; if ( options.selectionStart !== undefined && endPos - startPos !== options.selectionEnd - options.selectionStart ) { // This means there is a difference in the selection range returned by browser and what we passed. // This happens for Safari 5.1, Chrome 12 in the case of composite characters. Ref T32130 // Set the startPos to the correct position. startPos = options.selectionStart; combiningCharSelectionBug = true; // TODO: The comment above is from 2011. Is this still a problem for browsers we support today? // Minimal test case: https://jsfiddle.net/z4q7a2ko/ } let insertText = pre + selText + post; if ( options.splitlines ) { insertText = doSplitLines( selText, pre, post ); } if ( options.ownline ) { if ( startPos !== 0 && allText.charAt( startPos - 1 ) !== '\n' && allText.charAt( startPos - 1 ) !== '\r' ) { insertText = '\n' + insertText; pre += '\n'; } if ( allText.charAt( endPos ) !== '\n' && allText.charAt( endPos ) !== '\r' ) { insertText += '\n'; post += '\n'; } } if ( combiningCharSelectionBug ) { $( this ).textSelection( 'setContents', allText.slice( 0, startPos ) + insertText + allText.slice( endPos ) ); } else { $( this ).textSelection( 'replaceSelection', insertText ); } if ( isSample && options.selectPeri && ( !options.splitlines || ( options.splitlines && selText.indexOf( '\n' ) === -1 ) ) ) { $( this ).textSelection( 'setSelection', { start: startPos + pre.length, end: startPos + pre.length + selText.length } ); } else { $( this ).textSelection( 'setSelection', { start: startPos + insertText.length } ); } $( this ).trigger( 'encapsulateSelection', [ options.pre, options.peri, options.post, options.ownline, options.replace, options.splitlines ] ); } ); }, /** * Get the current cursor position (in UTF-16 code units) in a textarea. * * @param {Object} [options] * @param {Object} [options.startAndEnd=false] Return range of the selection rather than just start * @return {number|number[]} * - When `startAndEnd` is `false`: number * - When `startAndEnd` is `true`: array with two numbers, for start and end of selection * @memberof module:jquery.textSelection */ getCaretPosition: function ( options ) { function getCaret( e ) { let caretPos = 0, endPos = 0; if ( e ) { caretPos = e.selectionStart; endPos = e.selectionEnd; } return options.startAndEnd ? [ caretPos, endPos ] : caretPos; } return getCaret( this.get( 0 ) ); }, /** * Set the current cursor position (in UTF-16 code units) in a textarea. * * @param {Object} [options] * @param {number} options.start * @param {number} [options.end=options.start] * @return {jQuery} * @chainable * @memberof module:jquery.textSelection */ setSelection: function ( options ) { return this.each( function () { // Opera 9.0 doesn't allow setting selectionStart past // selectionEnd; any attempts to do that will be ignored // Make sure to set them in the right order if ( options.start > this.selectionEnd ) { this.selectionEnd = options.end; this.selectionStart = options.start; } else { this.selectionStart = options.start; this.selectionEnd = options.end; } } ); }, /** * Scroll a textarea to the current cursor position. You can set the cursor * position with {@link module:jquery.textSelection.setSelection setSelection}. * * @param {Object} [options] * @param {string} [options.force=false] Whether to force a scroll even if the caret position * is already visible. * @return {jQuery} * @chainable * @memberof module:jquery.textSelection */ scrollToCaretPosition: function ( options ) { return this.each( function () { const clientHeight = this.clientHeight, origValue = this.value, origSelectionStart = this.selectionStart, origSelectionEnd = this.selectionEnd, origScrollTop = this.scrollTop; // Delete all text after the selection and scroll the textarea to the end. // This ensures the selection is visible (aligned to the bottom of the textarea). // Then restore the text we deleted without changing scroll position. this.value = this.value.slice( 0, this.selectionEnd ); this.scrollTop = this.scrollHeight; // Chrome likes to adjust scroll position when changing value, so save and re-set later. // Note that this is not equal to scrollHeight, it's scrollHeight minus clientHeight. let calcScrollTop = this.scrollTop; this.value = origValue; this.selectionStart = origSelectionStart; this.selectionEnd = origSelectionEnd; if ( !options.force ) { // Check if all the scrolling was unnecessary and if so, restore previous position. // If the current position is no more than a screenful above the original, // the selection was previously visible on the screen. if ( calcScrollTop < origScrollTop && origScrollTop - calcScrollTop < clientHeight ) { calcScrollTop = origScrollTop; } } this.scrollTop = calcScrollTop; $( this ).trigger( 'scrollToPosition' ); } ); } }; /** * Register an alternative textSelection API for this element. * * @method register * @param {Object} functions Functions to replace. Keys are command names (as in {@link module:jquery.textSelection.textSelection textSelection}, * except 'register' and 'unregister'). Values are functions to execute when a given command is * called. * @memberof module:jquery.textSelection */ /** * Unregister the alternative textSelection API for this element (see {@link module:jquery.textSelection.register register}). * * @method unregister * @memberof module:jquery.textSelection */ /** * Execute a textSelection command about the element. * * @example * var $textbox = $( '#wpTextbox1' ); * $textbox.textSelection( 'setContents', 'This is bold!' ); * $textbox.textSelection( 'setSelection', { start: 8, end: 12 } ); * $textbox.textSelection( 'encapsulateSelection', { pre: '<b>', post: '</b>' } ); * // Result: Textbox contains 'This is <b>bold</b>!', with cursor before the '!' * @memberof module:jquery.textSelection * @method * @param {string} command Command to execute, one of: * * - {@link module:jquery.textSelection.getContents getContents} * - {@link module:jquery.textSelection.setContents setContents} * - {@link module:jquery.textSelection.getSelection getSelection} * - {@link module:jquery.textSelection.replaceSelection replaceSelection} * - {@link module:jquery.textSelection.encapsulateSelection encapsulateSelection} * - {@link module:jquery.textSelection.getCaretPosition getCaretPosition} * - {@link module:jquery.textSelection.setSelection setSelection} * - {@link module:jquery.textSelection.scrollToCaretPosition scrollToCaretPosition} * - {@link module:jquery.textSelection.register register} * - {@link module:jquery.textSelection.unregister unregister} * @param {any} [commandOptions] Options to pass to the command * @return {any} Depending on the command */ $.fn.textSelection = function ( command, commandOptions ) { const alternateFn = $( this ).data( 'jquery.textSelection' ); // Prevent values of `undefined` overwriting defaults (T368102) for ( const key in commandOptions ) { if ( commandOptions[ key ] === undefined ) { delete commandOptions[ key ]; } } // Apply defaults switch ( command ) { // case 'getContents': // no params // case 'setContents': // no params with defaults // case 'getSelection': // no params // case 'replaceSelection': // no params with defaults case 'encapsulateSelection': commandOptions = Object.assign( { pre: '', peri: '', post: '', ownline: false, replace: false, selectPeri: true, splitlines: false, selectionStart: undefined, selectionEnd: undefined }, commandOptions ); break; case 'getCaretPosition': commandOptions = Object.assign( { startAndEnd: false }, commandOptions ); break; case 'setSelection': commandOptions = Object.assign( { start: undefined, end: undefined }, commandOptions ); if ( commandOptions.end === undefined ) { commandOptions.end = commandOptions.start; } break; case 'scrollToCaretPosition': commandOptions = Object.assign( { force: false }, commandOptions ); break; case 'register': if ( alternateFn ) { throw new Error( 'Another textSelection API was already registered' ); } $( this ).data( 'jquery.textSelection', commandOptions ); // No need to update alternateFn as this command only stores the options. // A command that uses it will set it again. return; case 'unregister': $( this ).removeData( 'jquery.textSelection' ); return; } const retval = ( alternateFn && alternateFn[ command ] || fn[ command ] ).call( this, commandOptions ); return retval; }; }() );
| ver. 1.1 | |
.
| PHP 8.4.18 | Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ñтраницы: 0 |
proxy
|
phpinfo
|
ÐаÑтройка