Krinkle has uploaded a new change for review. https://gerrit.wikimedia.org/r/177076
Change subject: mediawiki.Uri: Implement support for a mutable defaultUri ...................................................................... mediawiki.Uri: Implement support for a mutable defaultUri Bug: T74334 Change-Id: Ib512774091626c810b25af03c15f84efaca1c633 --- M resources/src/mediawiki/mediawiki.Uri.js M tests/qunit/suites/resources/mediawiki/mediawiki.Uri.test.js 2 files changed, 85 insertions(+), 9 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core refs/changes/76/177076/1 diff --git a/resources/src/mediawiki/mediawiki.Uri.js b/resources/src/mediawiki/mediawiki.Uri.js index bb5ddfc..abfb279 100644 --- a/resources/src/mediawiki/mediawiki.Uri.js +++ b/resources/src/mediawiki/mediawiki.Uri.js @@ -127,15 +127,29 @@ */ /** - * A factory method to create a variation of mw.Uri with a different default location (for - * relative URLs, including protocol-relative URLs). Used so the library is still testable & - * purely functional. + * A factory method to create a Uri class with a default location to resolve relative URLs + * against (including protocol-relative URLs). * * @method + * @param {string|Function} documentLocation A full url, or function returning one. + * If passed a function, the return value may change over time and this will be honoured. (T74334) * @member mw */ mw.UriRelative = function ( documentLocation ) { - var defaultUri; + var getDefaultUri = ( function () { + // Cache + var href, uri; + + return function () { + var hrefCur = typeof documentLocation === 'string' ? documentLocation : documentLocation(); + if ( href === hrefCur ) { + return uri; + } + href = hrefCur; + uri = new Uri( href ); + return uri; + }; + }() ); /** * @class mw.Uri @@ -156,6 +170,9 @@ * override each other (`true`) or automagically convert them to an array (`false`). */ function Uri( uri, options ) { + var prop, + defaultUri = getDefaultUri(); + options = typeof options === 'object' ? options : { strictMode: !!options }; options = $.extend( { strictMode: false, @@ -167,7 +184,7 @@ this.parse( uri, options ); } else if ( typeof uri === 'object' ) { // Copy data over from existing URI object - for ( var prop in uri ) { + for ( prop in uri ) { // Only copy direct properties, not inherited ones if ( uri.hasOwnProperty( prop ) ) { // Deep copy object properties @@ -390,12 +407,12 @@ } }; - defaultUri = new Uri( documentLocation ); - return Uri; }; // Default to the current browsing location (for relative URLs). - mw.Uri = mw.UriRelative( location.href ); + mw.Uri = mw.UriRelative( function () { + return location.href; + } ); }( mediaWiki, jQuery ) ); diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.Uri.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.Uri.test.js index 7a58d38..ba36655 100644 --- a/tests/qunit/suites/resources/mediawiki/mediawiki.Uri.test.js +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.Uri.test.js @@ -314,6 +314,66 @@ assert.equal( uri.toString(), 'http://www.example.com/dir/', 'empty array value is ommitted' ); } ); + QUnit.test( 'Variable defaultUri', 2, function ( assert ) { + var uri, + href = 'http://example.org/w/index.php#here', + UriClass = mw.UriRelative( function () { + return href; + } ); + + uri = new UriClass(); + assert.deepEqual( + { + protocol: uri.protocol, + user: uri.user, + password: uri.password, + host: uri.host, + port: uri.port, + path: uri.path, + query: uri.query, + fragment: uri.fragment + }, + { + protocol: 'http', + user: undefined, + password: undefined, + host: 'example.org', + port: undefined, + path: '/w/index.php', + query: {}, + fragment: 'here' + }, + 'basic object properties' + ); + + // Default URI may change, e.g. via history.replaceState, pushState or location.hash (T74334) + href = 'https://example.com/wiki/Foo?v=2'; + uri = new UriClass(); + assert.deepEqual( + { + protocol: uri.protocol, + user: uri.user, + password: uri.password, + host: uri.host, + port: uri.port, + path: uri.path, + query: uri.query, + fragment: uri.fragment + }, + { + protocol: 'https', + user: undefined, + password: undefined, + host: 'example.com', + port: undefined, + path: '/wiki/Foo', + query: { 'v': '2' }, + fragment: undefined + }, + 'basic object properties' + ); + } ); + QUnit.test( 'Advanced URL', 11, function ( assert ) { var uri, queryString, relativePath; @@ -429,6 +489,5 @@ uri = new UriClass( testPath ); href = uri.toString(); assert.equal( href, testProtocol + testServer + ':' + testPort + testPath, 'Root-relative URL gets host, protocol, and port supplied' ); - } ); }( mediaWiki, jQuery ) ); -- To view, visit https://gerrit.wikimedia.org/r/177076 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ib512774091626c810b25af03c15f84efaca1c633 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/core Gerrit-Branch: master Gerrit-Owner: Krinkle <krinklem...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits