Файловый менеджер - Редактировать - /var/www/html/mediawiki-1.43.1/resources/src/mediawiki.Title/Title.js
Ðазад
/*! * @author Neil Kandalgaonkar, 2010 * @since 1.18 */ /* Private members */ let toUpperMap; const mwString = require( 'mediawiki.String' ), namespaceIds = mw.config.get( 'wgNamespaceIds' ), /** * @private * @static * @property {number} NS_MAIN */ NS_MAIN = namespaceIds[ '' ], /** * @private * @static * @property {number} NS_TALK */ NS_TALK = namespaceIds.talk, /** * @private * @static * @property {number} NS_SPECIAL */ NS_SPECIAL = namespaceIds.special, /** * @private * @static * @property {number} NS_MEDIA */ NS_MEDIA = namespaceIds.media, /** * @private * @static * @property {number} NS_FILE */ NS_FILE = namespaceIds.file, /** * @private * @static * @property {number} FILENAME_MAX_BYTES */ FILENAME_MAX_BYTES = 240, /** * @private * @static * @property {number} TITLE_MAX_BYTES */ TITLE_MAX_BYTES = 255, /** * Get the namespace id from a namespace name (either from the localized, canonical or alias * name). * * Example: On a German wiki this would return 6 for any of 'File', 'Datei', 'Image' or * even 'Bild'. * * @private * @static * @method getNsIdByName * @param {string} ns Namespace name (case insensitive, leading/trailing space ignored) * @return {number|boolean} Namespace id or boolean false */ getNsIdByName = function ( ns ) { // Don't cast non-strings to strings, because null or undefined should not result in // returning the id of a potential namespace called "Null:" (e.g. on null.example.org/wiki) // Also, toLowerCase throws exception on null/undefined, because it is a String method. if ( typeof ns !== 'string' ) { return false; } // TODO: Should just use the local variable namespaceIds here, but it // breaks test which modify the config const id = mw.config.get( 'wgNamespaceIds' )[ ns.toLowerCase() ]; if ( id === undefined ) { return false; } return id; }, /** * @private * @method isKnownNamespace * @param {number} namespace that may or may not exist * @return {boolean} */ isKnownNamespace = function ( namespace ) { return namespace === NS_MAIN || mw.config.get( 'wgFormattedNamespaces' )[ namespace ] !== undefined; }, /** * @private * @method getNamespacePrefix * @param {number} namespace that is valid and known. Callers should call * `isKnownNamespace` before executing this method. * @return {string} */ getNamespacePrefix = function ( namespace ) { return namespace === NS_MAIN ? '' : ( mw.config.get( 'wgFormattedNamespaces' )[ namespace ].replace( / /g, '_' ) + ':' ); }, rUnderscoreTrim = /^_+|_+$/g, rSplit = /^(.+?)_*:_*(.*)$/, // See MediaWikiTitleCodec.php#getTitleInvalidRegex rInvalid = new RegExp( '[^' + mw.config.get( 'wgLegalTitleChars' ) + ']' + // URL percent encoding sequences interfere with the ability // to round-trip titles -- you can't link to them consistently. '|%[\\dA-Fa-f]{2}' + // XML/HTML character references produce similar issues. '|&[\\dA-Za-z\u0080-\uFFFF]+;' ), // From MediaWikiTitleCodec::splitTitleString() in PHP // Note that this is not equivalent to /\s/, e.g. underscore is included, tab is not included. rWhitespace = /[ _\u00A0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]+/g, // From MediaWikiTitleCodec::splitTitleString() in PHP rUnicodeBidi = /[\u200E\u200F\u202A-\u202E]+/g, /** * Slightly modified from Flinfo. Credit goes to Lupo and Flominator. * * @private * @static * @property {Object[]} sanitationRules */ sanitationRules = [ // "signature" { pattern: /~{3}/g, replace: '', generalRule: true }, // control characters { // eslint-disable-next-line no-control-regex pattern: /[\x00-\x1f\x7f]/g, replace: '', generalRule: true }, // URL encoding (possibly) { pattern: /%([\dA-Fa-f]{2})/g, replace: '% $1', generalRule: true }, // HTML-character-entities { pattern: /&(([\dA-Za-z\x80-\xff]+|#\d+|#x[\dA-Fa-f]+);)/g, replace: '& $1', generalRule: true }, // slash, colon (not supported by file systems like NTFS/Windows, Mac OS 9 [:], ext4 [/]) { pattern: new RegExp( '[' + mw.config.get( 'wgIllegalFileChars', '' ) + ']', 'g' ), replace: '-', fileRule: true }, // brackets, greater than { pattern: /[}\]>]/g, replace: ')', generalRule: true }, // brackets, lower than { pattern: /[{[<]/g, replace: '(', generalRule: true }, // everything that wasn't covered yet { pattern: new RegExp( rInvalid.source, 'g' ), replace: '-', generalRule: true }, // directory structures { pattern: /^(\.|\.\.|\.\/.*|\.\.\/.*|.*\/\.\/.*|.*\/\.\.\/.*|.*\/\.|.*\/\.\.)$/g, replace: '', generalRule: true } ], /** * Internal helper for #constructor and #newFromText. * * Based on Title.php#secureAndSplit * * @private * @static * @method parse * @param {string} title * @param {number} [defaultNamespace=NS_MAIN] * @return {Object|boolean} */ parse = function ( title, defaultNamespace ) { let namespace = defaultNamespace === undefined ? NS_MAIN : defaultNamespace; title = title // Strip Unicode bidi override characters .replace( rUnicodeBidi, '' ) // Normalise whitespace to underscores and remove duplicates .replace( rWhitespace, '_' ) // Trim underscores .replace( rUnderscoreTrim, '' ); if ( title.indexOf( '\uFFFD' ) !== -1 ) { // Contained illegal UTF-8 sequences or forbidden Unicode chars. // Commonly occurs when the text was obtained using the `URL` API, and the 'title' parameter // was using a legacy 8-bit encoding, for example: // new URL( 'https://en.wikipedia.org/w/index.php?title=Apollo%96Soyuz' ).searchParams.get( 'title' ) return false; } // Process initial colon if ( title !== '' && title[ 0 ] === ':' ) { // Initial colon means main namespace instead of specified default namespace = NS_MAIN; title = title // Strip colon .slice( 1 ) // Trim underscores .replace( rUnderscoreTrim, '' ); } if ( title === '' ) { return false; } // Process namespace prefix (if any) let m = title.match( rSplit ); if ( m ) { const id = getNsIdByName( m[ 1 ] ); if ( id !== false ) { // Ordinary namespace namespace = id; title = m[ 2 ]; // For Talk:X pages, make sure X has no "namespace" prefix if ( namespace === NS_TALK && ( m = title.match( rSplit ) ) ) { // Disallow titles like Talk:File:x (subject should roundtrip: talk:file:x -> file:x -> file_talk:x) if ( getNsIdByName( m[ 1 ] ) !== false ) { return false; } } } } // Process fragment const i = title.indexOf( '#' ); let fragment; if ( i === -1 ) { fragment = null; } else { fragment = title // Get segment starting after the hash .slice( i + 1 ) // Convert to text // NB: Must not be trimmed ("Example#_foo" is not the same as "Example#foo") .replace( /_/g, ' ' ); title = title // Strip hash .slice( 0, i ) // Trim underscores, again (strips "_" from "bar" in "Foo_bar_#quux") .replace( rUnderscoreTrim, '' ); } // Reject illegal characters if ( rInvalid.test( title ) ) { return false; } // Disallow titles that browsers or servers might resolve as directory navigation if ( title.indexOf( '.' ) !== -1 && ( title === '.' || title === '..' || title.indexOf( './' ) === 0 || title.indexOf( '../' ) === 0 || title.indexOf( '/./' ) !== -1 || title.indexOf( '/../' ) !== -1 || title.slice( -2 ) === '/.' || title.slice( -3 ) === '/..' ) ) { return false; } // Disallow magic tilde sequence if ( title.indexOf( '~~~' ) !== -1 ) { return false; } // Disallow titles exceeding the TITLE_MAX_BYTES byte size limit (size of underlying database field) // Except for special pages, e.g. [[Special:Block/Long name]] // Note: The PHP implementation also asserts that even in NS_SPECIAL, the title should // be less than 512 bytes. if ( namespace !== NS_SPECIAL && mwString.byteLength( title ) > TITLE_MAX_BYTES ) { return false; } // Can't make a link to a namespace alone. if ( title === '' && namespace !== NS_MAIN ) { return false; } // Any remaining initial :s are illegal. if ( title[ 0 ] === ':' ) { return false; } return { namespace: namespace, title: title, fragment: fragment }; }, /** * Convert db-key to readable text. * * @private * @static * @method text * @param {string} s * @return {string} */ text = function ( s ) { return s.replace( /_/g, ' ' ); }, /** * Sanitizes a string based on a rule set and a filter * * @private * @static * @method sanitize * @param {string} s * @param {Array} filter * @return {string} */ sanitize = function ( s, filter ) { const rules = sanitationRules; for ( let i = 0, ruleLength = rules.length; i < ruleLength; ++i ) { const rule = rules[ i ]; for ( let m = 0, filterLength = filter.length; m < filterLength; ++m ) { if ( rule[ filter[ m ] ] ) { s = s.replace( rule.pattern, rule.replace ); } } } return s; }, /** * Cuts a string to a specific byte length, assuming UTF-8 * or less, if the last character is a multi-byte one * * @private * @static * @method trimToByteLength * @param {string} s * @param {number} length * @return {string} */ trimToByteLength = function ( s, length ) { return mwString.trimByteLength( '', s, length ).newVal; }, /** * Cuts a file name to a specific byte length * * @private * @static * @method trimFileNameToByteLength * @param {string} name without extension * @param {string} extension file extension * @return {string} The full name, including extension */ trimFileNameToByteLength = function ( name, extension ) { // There is a special byte limit for file names and ... remember the dot return trimToByteLength( name, FILENAME_MAX_BYTES - extension.length - 1 ) + '.' + extension; }; /** * @class mw.Title * @classdesc Library for constructing MediaWiki titles. * * @example * new mw.Title( 'Foo', NS_TEMPLATE ).getPrefixedText(); * // => 'Template:Foo' * mw.Title.newFromText( 'Foo', NS_TEMPLATE ).getPrefixedText(); * // => 'Template:Foo' * mw.Title.makeTitle( NS_TEMPLATE, 'Foo' ).getPrefixedText(); * // => 'Template:Foo' * * new mw.Title( 'Category:Foo', NS_TEMPLATE ).getPrefixedText(); * // => 'Category:Foo' * mw.Title.newFromText( 'Category:Foo', NS_TEMPLATE ).getPrefixedText(); * // => 'Category:Foo' * mw.Title.makeTitle( NS_TEMPLATE, 'Category:Foo' ).getPrefixedText(); * // => 'Template:Category:Foo' * * new mw.Title( 'Template:Foo', NS_TEMPLATE ).getPrefixedText(); * // => 'Template:Foo' * mw.Title.newFromText( 'Template:Foo', NS_TEMPLATE ).getPrefixedText(); * // => 'Template:Foo' * mw.Title.makeTitle( NS_TEMPLATE, 'Template:Foo' ).getPrefixedText(); * // => 'Template:Template:Foo' * * @constructor * @description Parse titles into an object structure. Note that when using the constructor * directly, passing invalid titles will result in an exception. * Use [newFromText]{@link mw.Title.newFromText} to use the * logic directly and get null for invalid titles which is easier to work with. * * Note that in the constructor and [newFromText]{@link mw.Title.newFromText} method, * `namespace` is the **default** namespace only, and can be overridden by a namespace * prefix in `title`. If you do not want this behavior, * use [makeTitle]{@link mw.Title.makeTitle}. * * @param {string} title Title of the page. If no second argument given, * this will be searched for a namespace * @param {number} [namespace=NS_MAIN] If given, will used as default namespace for the given title * @throws {Error} When the title is invalid */ function Title( title, namespace ) { const parsed = parse( title, namespace ); if ( !parsed ) { throw new Error( 'Unable to parse title' ); } this.namespace = parsed.namespace; this.title = parsed.title; this.fragment = parsed.fragment; } /* Static members */ /** * Constructor for Title objects with a null return instead of an exception for invalid titles. * * Note that `namespace` is the **default** namespace only, and can be overridden by a namespace * prefix in `title`. If you do not want this behavior, use #makeTitle. See #constructor for * details. * * @name mw.Title.newFromText * @method * @param {string} title * @param {number} [namespace=NS_MAIN] Default namespace * @return {mw.Title|null} A valid Title object or null if the title is invalid */ Title.newFromText = function ( title, namespace ) { const parsed = parse( title, namespace ); if ( !parsed ) { return null; } const t = Object.create( Title.prototype ); t.namespace = parsed.namespace; t.title = parsed.title; t.fragment = parsed.fragment; return t; }; /** * Constructor for Title objects with predefined namespace. * * Unlike [newFromText]{@link mw.Title.newFromText} or the constructor, this function doesn't allow the given `namespace` to be * overridden by a namespace prefix in `title`. See the constructor documentation for details about this behavior. * * The single exception to this is when `namespace` is 0, indicating the main namespace. The * function behaves like [newFromText]{@link mw.Title.newFromText} in that case. * * @name mw.Title.makeTitle * @method * @param {number} namespace Namespace to use for the title * @param {string} title * @return {mw.Title|null} A valid Title object or null if the title is invalid */ Title.makeTitle = function ( namespace, title ) { if ( !isKnownNamespace( namespace ) ) { return null; } else { return mw.Title.newFromText( getNamespacePrefix( namespace ) + title ); } }; /** * Constructor for Title objects from user input altering that input to * produce a title that MediaWiki will accept as legal. * * @name mw.Title.newFromUserInput * @method * @param {string} title * @param {number} [defaultNamespace=NS_MAIN] * If given, will used as default namespace for the given title. * @param {Object} [options] additional options * @param {boolean} [options.forUploading=true] * Makes sure that a file is uploadable under the title returned. * There are pages in the file namespace under which file upload is impossible. * Automatically assumed if the title is created in the Media namespace. * @return {mw.Title|null} A valid Title object or null if the input cannot be turned into a valid title */ Title.newFromUserInput = function ( title, defaultNamespace, options ) { let namespace = parseInt( defaultNamespace ) || NS_MAIN; // merge options into defaults options = Object.assign( { forUploading: true }, options ); // Normalise additional whitespace title = title.replace( /\s/g, ' ' ).trim(); // Process initial colon if ( title !== '' && title[ 0 ] === ':' ) { // Initial colon means main namespace instead of specified default namespace = NS_MAIN; title = title // Strip colon .slice( 1 ) // Trim underscores .replace( rUnderscoreTrim, '' ); } // Process namespace prefix (if any) const m = title.match( rSplit ); if ( m ) { const id = getNsIdByName( m[ 1 ] ); if ( id !== false ) { // Ordinary namespace namespace = id; title = m[ 2 ]; } } if ( namespace === NS_MEDIA || ( options.forUploading && ( namespace === NS_FILE ) ) ) { title = sanitize( title, [ 'generalRule', 'fileRule' ] ); // Operate on the file extension // Although it is possible having spaces between the name and the ".ext" this isn't nice for // operating systems hiding file extensions -> strip them later on const lastDot = title.lastIndexOf( '.' ); // No or empty file extension if ( lastDot === -1 || lastDot >= title.length - 1 ) { return null; } // Get the last part, which is supposed to be the file extension const ext = title.slice( lastDot + 1 ); // Remove whitespace of the name part (that without extension) title = title.slice( 0, lastDot ).trim(); // Cut, if too long and append file extension title = trimFileNameToByteLength( title, ext ); } else { title = sanitize( title, [ 'generalRule' ] ); // Cut titles exceeding the TITLE_MAX_BYTES byte size limit // (size of underlying database field) if ( namespace !== NS_SPECIAL ) { title = trimToByteLength( title, TITLE_MAX_BYTES ); } } // Any remaining initial :s are illegal. title = title.replace( /^:+/, '' ); return Title.newFromText( title, namespace ); }; /** * Sanitizes a file name as supplied by the user, originating in the user's file system * so it is most likely a valid MediaWiki title and file name after processing. * Returns null on fatal errors. * * @name mw.Title.newFromFileName * @method * @param {string} uncleanName The unclean file name including file extension but * without namespace * @return {mw.Title|null} A valid Title object or null if the title is invalid */ Title.newFromFileName = function ( uncleanName ) { return Title.newFromUserInput( 'File:' + uncleanName ); }; /** * Get the file title from an image element. * * @example * const title = mw.Title.newFromImg( imageNode ); * * @name mw.Title.newFromImg * @method * @param {HTMLElement|jQuery} img The image to use as a base * @return {mw.Title|null} The file title or null if unsuccessful */ Title.newFromImg = function ( img ) { const src = img.jquery ? img[ 0 ].src : img.src, data = mw.util.parseImageUrl( src ); return data ? mw.Title.newFromText( 'File:' + data.name ) : null; }; /** * Check if a given namespace is a talk namespace. * * See NamespaceInfo::isTalk in PHP * * @name mw.Title.isTalkNamespace * @method * @param {number} namespaceId Namespace ID * @return {boolean} Namespace is a talk namespace */ Title.isTalkNamespace = function ( namespaceId ) { return namespaceId > NS_MAIN && namespaceId % 2 === 1; }; /** * Check if signature buttons should be shown in a given namespace. * * See NamespaceInfo::wantSignatures in PHP * * @name mw.Title.wantSignaturesNamespace * @method * @param {number} namespaceId Namespace ID * @return {boolean} Namespace is a signature namespace */ Title.wantSignaturesNamespace = function ( namespaceId ) { return Title.isTalkNamespace( namespaceId ) || mw.config.get( 'wgExtraSignatureNamespaces' ).indexOf( namespaceId ) !== -1; }; /** * Whether this title exists on the wiki. * * @name mw.Title.exists * @method * @param {string|mw.Title} title prefixed db-key name (string) or instance of Title * @return {boolean|null} Boolean if the information is available, otherwise null * @throws {Error} If title is not a string or mw.Title */ Title.exists = function ( title ) { const obj = Title.exist.pages; let match; if ( typeof title === 'string' ) { match = obj[ title ]; } else if ( title instanceof Title ) { match = obj[ title.toString() ]; } else { throw new Error( 'mw.Title.exists: title must be a string or an instance of Title' ); } if ( typeof match !== 'boolean' ) { return null; } return match; }; /** * @typedef {Object} mw.Title~TitleExistenceStore * @property {Object} pages Keyed by title. Boolean true value indicates page does exist. * * @property {Function} set The setter function. Returns a boolean. * * Example to declare existing titles: * ``` * Title.exist.set( ['User:John_Doe', ...] ); * ``` * * Example to declare titles nonexistent: * ``` * Title.exist.set( ['File:Foo_bar.jpg', ...], false ); * ``` * * @property {string|string[]} set.titles Title(s) in strict prefixedDb title form * @property {boolean} [set.state=true] State of the given titles */ /** * @name mw.Title.exist * @type {mw.Title~TitleExistenceStore} */ Title.exist = { pages: {}, set: function ( titles, state ) { const pages = this.pages; titles = Array.isArray( titles ) ? titles : [ titles ]; state = state === undefined ? true : !!state; for ( let i = 0, len = titles.length; i < len; i++ ) { pages[ titles[ i ] ] = state; } return true; } }; /** * Normalize a file extension to the common form, making it lowercase and checking some synonyms, * and ensure it's clean. Extensions with non-alphanumeric characters will be discarded. * Keep in sync with File::normalizeExtension() in PHP. * * @name mw.Title.normalizeExtension * @method * @param {string} extension File extension (without the leading dot) * @return {string} File extension in canonical form */ Title.normalizeExtension = function ( extension ) { const lower = extension.toLowerCase(), normalizations = { htm: 'html', jpeg: 'jpg', mpeg: 'mpg', tiff: 'tif', ogv: 'ogg' }; if ( Object.hasOwnProperty.call( normalizations, lower ) ) { return normalizations[ lower ]; } else if ( /^[\da-z]+$/.test( lower ) ) { return lower; } else { return ''; } }; /** * PHP's strtoupper differs from String.toUpperCase in a number of cases (T147646). * * @name mw.Title.phpCharToUpper * @method * @param {string} chr Unicode character * @return {string} Unicode character, in upper case, according to the same rules as in PHP */ Title.phpCharToUpper = function ( chr ) { if ( !toUpperMap ) { toUpperMap = require( './phpCharToUpper.json' ); } if ( toUpperMap[ chr ] === 0 ) { // Optimisation: When the override is to keep the character unchanged, // we use 0 in JSON. This reduces the data by 50%. return chr; } return toUpperMap[ chr ] || chr.toUpperCase(); }; /* Public members */ Title.prototype = /** @lends mw.Title.prototype */ { constructor: Title, /** * Get the namespace number. * * Example: 6 for "File:Example_image.svg". * * @return {number} */ getNamespaceId: function () { return this.namespace; }, /** * Get the namespace prefix (in the content language). * * Example: "File:" for "File:Example_image.svg". * In `NS_MAIN` this is '', otherwise namespace name plus ':' * * @return {string} */ getNamespacePrefix: function () { return getNamespacePrefix( this.namespace ); }, /** * Get the page name as if it is a file name, without extension or namespace prefix, * in the canonical form with underscores instead of spaces. For example, the title * `File:Example_image.svg` will be returned as `Example_image`. * * Note that this method will work for non-file titles but probably give nonsensical results. * A title like `User:Dr._J._Fail` will be returned as `Dr._J`! Use [getMain]{@link mw.Title#getMain} instead. * * @return {string} */ getFileNameWithoutExtension: function () { const ext = this.getExtension(); if ( ext === null ) { return this.getMain(); } return this.getMain().slice( 0, -ext.length - 1 ); }, /** * Get the page name as if it is a file name, without extension or namespace prefix, * in the human-readable form with spaces instead of underscores. For example, the title * `File:Example_image.svg` will be returned as "Example image". * * Note that this method will work for non-file titles but probably give nonsensical results. * A title like `User:Dr._J._Fail` will be returned as `Dr. J`! Use [getMainText]{@link mw.Title#getMainText} instead. * * @return {string} */ getFileNameTextWithoutExtension: function () { return text( this.getFileNameWithoutExtension() ); }, /** * Get the page name as if it is a file name, without extension or namespace prefix. Warning, * this is usually not what you want! A title like `User:Dr._J._Fail` will be returned as * `Dr. J`! Use [getMain]{@link mw.Title#getMain} or [getMainText]{@link mw.Title#getMainText} for the actual page name. * * @return {string} File name without file extension, in the canonical form with underscores * instead of spaces. For example, the title `File:Example_image.svg` will be returned as * `Example_image`. * @deprecated since 1.40, use [getFileNameWithoutExtension]{@link mw.Title#getFileNameWithoutExtension} instead */ getName: function () { return this.getFileNameWithoutExtension(); }, /** * Get the page name as if it is a file name, without extension or namespace prefix. Warning, * this is usually not what you want! A title like `User:Dr._J._Fail` will be returned as * `Dr. J`! Use [getMainText]{@link mw.Title#getMainText} for the actual page name. * * @return {string} File name without file extension, formatted with spaces instead of * underscores. For example, the title `File:Example_image.svg` will be returned as * `Example image`. * @deprecated since 1.40, use [getFileNameTextWithoutExtension]{@link mw.Title#getFileNameTextWithoutExtension} instead */ getNameText: function () { return text( this.getFileNameTextWithoutExtension() ); }, /** * Get the extension of the page name (if any). * * @return {string|null} Name extension or null if there is none */ getExtension: function () { const lastDot = this.title.lastIndexOf( '.' ); if ( lastDot === -1 ) { return null; } return this.title.slice( lastDot + 1 ) || null; }, /** * Get the main page name. * * Example: `Example_image.svg` for `File:Example_image.svg`. * * @return {string} */ getMain: function () { if ( mw.config.get( 'wgCaseSensitiveNamespaces' ).indexOf( this.namespace ) !== -1 || !this.title.length ) { return this.title; } const firstChar = mwString.charAt( this.title, 0 ); return mw.Title.phpCharToUpper( firstChar ) + this.title.slice( firstChar.length ); }, /** * Get the main page name (transformed by text()). * * Example: `Example image.svg` for `File:Example_image.svg`. * * @return {string} */ getMainText: function () { return text( this.getMain() ); }, /** * Get the full page name. * * Example: `File:Example_image.svg`. * Most useful for API calls, anything that must identify the "title". * * @return {string} */ getPrefixedDb: function () { return this.getNamespacePrefix() + this.getMain(); }, /** * Get the full page name (transformed by [text]{@link mw.Title#text}). * * Example: `File:Example image.svg` for `File:Example_image.svg`. * * @return {string} */ getPrefixedText: function () { return text( this.getPrefixedDb() ); }, /** * Get the page name relative to a namespace. * * Example: * * - "Foo:Bar" relative to the Foo namespace becomes "Bar". * - "Bar" relative to any non-main namespace becomes ":Bar". * - "Foo:Bar" relative to any namespace other than Foo stays "Foo:Bar". * * @param {number} namespace The namespace to be relative to * @return {string} */ getRelativeText: function ( namespace ) { if ( this.getNamespaceId() === namespace ) { return this.getMainText(); } else if ( this.getNamespaceId() === NS_MAIN ) { return ':' + this.getPrefixedText(); } else { return this.getPrefixedText(); } }, /** * Get the fragment (if any). * * Note that this method (by design) does not include the hash character and * the value is not url encoded. * * @return {string|null} */ getFragment: function () { return this.fragment; }, /** * Get the URL to this title. * * @see [mw.util.getUrl]{@link module:mediawiki.util.getUrl} * @param {Object} [params] A mapping of query parameter names to values, * e.g. `{ action: 'edit' }`. * @return {string} */ getUrl: function ( params ) { const fragment = this.getFragment(); if ( fragment ) { return mw.util.getUrl( this.toString() + '#' + fragment, params ); } else { return mw.util.getUrl( this.toString(), params ); } }, /** * Check if the title is in a talk namespace. * * @return {boolean} The title is in a talk namespace */ isTalkPage: function () { return Title.isTalkNamespace( this.getNamespaceId() ); }, /** * Get the title for the associated talk page. * * @return {mw.Title|null} The title for the associated talk page, null if not available */ getTalkPage: function () { if ( !this.canHaveTalkPage() ) { return null; } return this.isTalkPage() ? this : Title.makeTitle( this.getNamespaceId() + 1, this.getMainText() ); }, /** * Get the title for the subject page of a talk page. * * @return {mw.Title|null} The title for the subject page of a talk page, null if not available */ getSubjectPage: function () { return this.isTalkPage() ? Title.makeTitle( this.getNamespaceId() - 1, this.getMainText() ) : this; }, /** * Check the title can have an associated talk page. * * @return {boolean} The title can have an associated talk page */ canHaveTalkPage: function () { return this.getNamespaceId() >= NS_MAIN; }, /** * Whether this title exists on the wiki. * * @see mw.Title.exists * @return {boolean|null} Boolean if the information is available, otherwise null */ exists: function () { return Title.exists( this ); } }; /** * Alias of [getPrefixedDb]{@link mw.Title#getPrefixedDb}. * * @name mw.Title.prototype.toString * @method */ Title.prototype.toString = Title.prototype.getPrefixedDb; /** * Alias of [getPrefixedText]{@link mw.Title#getPrefixedText}. * * @name mw.Title.prototype.toText * @method */ Title.prototype.toText = Title.prototype.getPrefixedText; // Expose mw.Title = Title;
| ver. 1.1 | |
.
| PHP 8.4.18 | Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ñтраницы: 0 |
proxy
|
phpinfo
|
ÐаÑтройка