mediawiki.Title: Add isTalkPage/getTalkPage methods to mw.Title.js
authorEd Sanders <esanders@wikimedia.org>
Thu, 13 Sep 2018 18:21:30 +0000 (19:21 +0100)
committerEd Sanders <esanders@wikimedia.org>
Mon, 17 Sep 2018 19:52:00 +0000 (20:52 +0100)
These are identical to methods in Title.php

Change-Id: Ie57243bac1aa5e23bc8b1c027bcb1b83090ee433

resources/src/mediawiki.Title/Title.js
tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js

index 4491634..b80928d 100644 (file)
                return null;
        };
 
+       /**
+        * Check if a given namespace is a talk namespace
+        * @param {number} namespaceId Namespace ID
+        * @return {boolean} Namespace is a talk namespace
+        */
+       Title.isTalkNamespace = function ( namespaceId ) {
+               return !!( namespaceId > NS_MAIN && namespaceId % 2 );
+       };
+
        /**
         * Whether this title exists on the wiki.
         *
         * @static
         * @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 ) {
                var match,
                        }
                },
 
+               /**
+                * 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 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.
                 *
index 8d67b4b..ea278f7 100644 (file)
                assert.strictEqual( title.toString(), 'Penguins:Flightless_yet_cute.jpg' );
        } );
 
+       QUnit.test( 'isTalkPage/getTalkPage/getSubjectPage', function ( assert ) {
+               var title;
+
+               title = new mw.Title( 'User:Foo' );
+               assert.strictEqual( title.isTalkPage(), false, 'Non-talk page detected as such' );
+               assert.strictEqual( title.getSubjectPage().getPrefixedText(), 'User:Foo', 'getSubjectPage on a subject page is a no-op' );
+
+               title = title.getTalkPage();
+               assert.strictEqual( title.getPrefixedText(), 'User talk:Foo', 'getTalkPage creates correct title' );
+               assert.strictEqual( title.getTalkPage().getPrefixedText(), 'User talk:Foo', 'getTalkPage on a talk page is a no-op' );
+               assert.strictEqual( title.isTalkPage(), true, 'Talk page is detected as such' );
+
+               title = title.getSubjectPage();
+               assert.strictEqual( title.getPrefixedText(), 'User:Foo', 'getSubjectPage creates correct title' );
+
+               title = new mw.Title( 'Special:AllPages' );
+               assert.strictEqual( title.isTalkPage(), false, 'Special page is not a talk page' );
+               assert.strictEqual( title.getTalkPage(), null, 'getTalkPage not valid for this namespace' );
+               assert.strictEqual( title.getSubjectPage().getPrefixedText(), 'Special:AllPages', 'getSubjectPage is self for special pages' );
+
+               title = new mw.Title( 'Category:Project:Maintenance' );
+               assert.strictEqual( title.getTalkPage().getPrefixedText(), 'Category talk:Project:Maintenance', 'getTalkPage is not confused by colon in main text' );
+               title = new mw.Title( 'Category talk:Project:Maintenance' );
+               assert.strictEqual( title.getSubjectPage().getPrefixedText(), 'Category:Project:Maintenance', 'getSubjectPage is not confused by colon in main text' );
+
+               title = new mw.Title( 'Foo#Caption' );
+               assert.strictEqual( title.getFragment(), 'Caption', 'Subject page has a fragment' );
+               title = title.getTalkPage();
+               assert.strictEqual( title.getPrefixedText(), 'Talk:Foo', 'getTalkPage creates correct title' );
+               assert.strictEqual( title.getFragment(), null, 'getTalkPage does not copy the fragment' );
+       } );
+
        QUnit.test( 'Throw error on invalid title', function ( assert ) {
                assert.throws( function () {
                        return new mw.Title( '' );