From: jenkins-bot Date: Fri, 18 Nov 2016 19:14:27 +0000 (+0000) Subject: Merge "Rename getSlaveDB() FileRepo method to getReplicaDB()" X-Git-Tag: 1.31.0-rc.0~4823 X-Git-Url: https://git.cyclocoop.org/%7B%24www_url%7Dadmin/compta/banques/?a=commitdiff_plain;h=eb5af5346d939494a75b133fc984bd08cbd0414d;hp=f525c725908bcb21e75240d79ce7b488af23e3df;p=lhc%2Fweb%2Fwiklou.git Merge "Rename getSlaveDB() FileRepo method to getReplicaDB()" --- diff --git a/docs/hooks.txt b/docs/hooks.txt index b8d92956ef..a73d50f9bd 100644 --- a/docs/hooks.txt +++ b/docs/hooks.txt @@ -3224,6 +3224,15 @@ $engine: the search engine message key to use in the name column, $context: IContextSource object +'SpecialTrackingCategories::preprocess': Called after LinkBatch on Special:TrackingCategories +$specialPage: The SpecialTrackingCategories object +$trackingCategories: Array of data from Special:TrackingCategories with msg and cats + +'SpecialTrackingCategories::generateCatLink': Called for each cat link on Special:TrackingCategories +$specialPage: The SpecialTrackingCategories object +$catTitle: The Title object of the linked category +&$html: The Result html + 'SpecialUploadComplete': Called after successfully uploading a file from Special:Upload. &$form: The SpecialUpload object diff --git a/includes/htmlform/fields/HTMLAutoCompleteSelectField.php b/includes/htmlform/fields/HTMLAutoCompleteSelectField.php index 0f86ee8bae..b0890c6778 100644 --- a/includes/htmlform/fields/HTMLAutoCompleteSelectField.php +++ b/includes/htmlform/fields/HTMLAutoCompleteSelectField.php @@ -18,35 +18,55 @@ * options-messages - As for HTMLSelectField * options - As for HTMLSelectField * options-message - As for HTMLSelectField - * autocomplete - Associative array mapping display text to values. - * autocomplete-messages - Like autocomplete, but keys are message names. + * autocomplete-data - Associative array mapping display text to values. + * autocomplete-data-messages - Like autocomplete, but keys are message names. * require-match - Boolean, if true the value must be in the options or the * autocomplete. * other-message - Message to use instead of htmlform-selectorother-other for * the 'other' message. * other - Raw text to use for the 'other' message + * + * The old name of autocomplete-data[-messages] was autocomplete[-messages] which is still + * recognized but deprecated since MediaWiki 1.29 since it conflicts with how autocomplete is + * used in HTMLTextField. */ class HTMLAutoCompleteSelectField extends HTMLTextField { - protected $autocomplete = []; + protected $autocompleteData = []; public function __construct( $params ) { $params += [ 'require-match' => false, ]; + // FIXME B/C, remove in 1.30 + if ( + array_key_exists( 'autocomplete', $params ) + && !array_key_exists( 'autocomplete-data', $params ) + ) { + $params['autocomplete-data'] = $params['autocomplete']; + unset( $params['autocomplete'] ); + } + if ( + array_key_exists( 'autocomplete-messages', $params ) + && !array_key_exists( 'autocomplete-data-messages', $params ) + ) { + $params['autocomplete-data-messages'] = $params['autocomplete-messages']; + unset( $params['autocomplete-messages'] ); + } + parent::__construct( $params ); - if ( array_key_exists( 'autocomplete-messages', $this->mParams ) ) { - foreach ( $this->mParams['autocomplete-messages'] as $key => $value ) { + if ( array_key_exists( 'autocomplete-data-messages', $this->mParams ) ) { + foreach ( $this->mParams['autocomplete-data-messages'] as $key => $value ) { $key = $this->msg( $key )->plain(); - $this->autocomplete[$key] = strval( $value ); + $this->autocompleteData[$key] = strval( $value ); } - } elseif ( array_key_exists( 'autocomplete', $this->mParams ) ) { - foreach ( $this->mParams['autocomplete'] as $key => $value ) { - $this->autocomplete[$key] = strval( $value ); + } elseif ( array_key_exists( 'autocomplete-data', $this->mParams ) ) { + foreach ( $this->mParams['autocomplete-data'] as $key => $value ) { + $this->autocompleteData[$key] = strval( $value ); } } - if ( !is_array( $this->autocomplete ) || !$this->autocomplete ) { + if ( !is_array( $this->autocompleteData ) || !$this->autocompleteData ) { throw new MWException( 'HTMLAutoCompleteSelectField called without any autocompletions' ); } @@ -69,8 +89,8 @@ class HTMLAutoCompleteSelectField extends HTMLTextField { if ( $val === 'other' ) { $val = $request->getText( $this->mName ); - if ( isset( $this->autocomplete[$val] ) ) { - $val = $this->autocomplete[$val]; + if ( isset( $this->autocompleteData[$val] ) ) { + $val = $this->autocompleteData[$val]; } } @@ -87,11 +107,11 @@ class HTMLAutoCompleteSelectField extends HTMLTextField { return $p; } - $validOptions = HTMLFormField::flattenOptions( $this->getOptions() ); + $validOptions = HTMLFormField::flattenOptions( $this->getOptions() ?: [] ); if ( in_array( strval( $value ), $validOptions, true ) ) { return true; - } elseif ( in_array( strval( $value ), $this->autocomplete, true ) ) { + } elseif ( in_array( strval( $value ), $this->autocompleteData, true ) ) { return true; } elseif ( $this->mParams['require-match'] ) { return $this->msg( 'htmlform-select-badoption' )->parse(); @@ -104,7 +124,7 @@ class HTMLAutoCompleteSelectField extends HTMLTextField { public function getAttributes( array $list ) { $attribs = [ 'type' => 'text', - 'data-autocomplete' => FormatJson::encode( array_keys( $this->autocomplete ) ), + 'data-autocomplete' => FormatJson::encode( array_keys( $this->autocompleteData ) ), ] + parent::getAttributes( $list ); if ( $this->getOptions() ) { @@ -152,7 +172,7 @@ class HTMLAutoCompleteSelectField extends HTMLTextField { if ( $valInSelect ) { $value = ''; } else { - $key = array_search( strval( $value ), $this->autocomplete, true ); + $key = array_search( strval( $value ), $this->autocompleteData, true ); if ( $key !== false ) { $value = $key; } diff --git a/includes/htmlform/fields/HTMLTextField.php b/includes/htmlform/fields/HTMLTextField.php index 88f5ec586c..c3da74618b 100644 --- a/includes/htmlform/fields/HTMLTextField.php +++ b/includes/htmlform/fields/HTMLTextField.php @@ -1,8 +1,19 @@ field. + * + * Besides the parameters recognized by HTMLFormField, the following are + * recognized: + * autocomplete - HTML autocomplete value (a boolean for on/off or a string according to + * https://html.spec.whatwg.org/multipage/forms.html#autofill ) + */ class HTMLTextField extends HTMLFormField { protected $mPlaceholder = ''; + /** @var bool HTML autocomplete attribute */ + protected $autocomplete; + /** * @param array $params * - type: HTML textfield type @@ -13,6 +24,10 @@ class HTMLTextField extends HTMLFormField { * for password fields) */ public function __construct( $params ) { + if ( isset( $params['autocomplete'] ) && is_bool( $params['autocomplete'] ) ) { + $params['autocomplete'] = $params['autocomplete'] ? 'on' : 'off'; + } + parent::__construct( $params ); if ( isset( $params['placeholder-message'] ) ) { @@ -80,7 +95,8 @@ class HTMLTextField extends HTMLFormField { 'required', 'autofocus', 'multiple', - 'readonly' + 'readonly', + 'autocomplete', ]; $attribs += $this->getAttributes( $allowedParams ); @@ -146,12 +162,24 @@ class HTMLTextField extends HTMLFormField { 'required', 'tabindex', 'type', + 'autocomplete', ]; $attribs += OOUI\Element::configFromHtmlAttributes( $this->getAttributes( $allowedParams ) ); + // FIXME T150983 downgrade autocomplete + if ( isset( $attribs['autocomplete'] ) ) { + if ( $attribs['autocomplete'] === 'on' ) { + $attribs['autocomplete'] = true; + } elseif ( $attribs['autocomplete'] === 'off' ) { + $attribs['autocomplete'] = false; + } else { + unset( $attribs['autocomplete'] ); + } + } + $type = $this->getType( $attribs ); return $this->getInputWidget( [ diff --git a/includes/specials/SpecialTrackingCategories.php b/includes/specials/SpecialTrackingCategories.php index 3b502f8960..4c6a3457db 100644 --- a/includes/specials/SpecialTrackingCategories.php +++ b/includes/specials/SpecialTrackingCategories.php @@ -87,6 +87,8 @@ class SpecialTrackingCategories extends SpecialPage { } $batch->execute(); + Hooks::run( 'SpecialTrackingCategories::preprocess', [ $this, $trackingCategories ] ); + foreach ( $trackingCategories as $catMsg => $data ) { $allMsgs = []; $catDesc = $catMsg . '-desc'; @@ -97,11 +99,15 @@ class SpecialTrackingCategories extends SpecialPage { ); foreach ( $data['cats'] as $catTitle ) { - $catTitleText = Linker::link( + $html = Linker::link( $catTitle, htmlspecialchars( $catTitle->getText() ) ); - $allMsgs[] = $catTitleText; + + Hooks::run( 'SpecialTrackingCategories::generateCatLink', + [ $this, $catTitle, &$html ] ); + + $allMsgs[] = $html; } # Extra message, when no category was found diff --git a/resources/src/mediawiki/mediawiki.js b/resources/src/mediawiki/mediawiki.js index c7993fde1d..2d73042597 100644 --- a/resources/src/mediawiki/mediawiki.js +++ b/resources/src/mediawiki/mediawiki.js @@ -1171,6 +1171,7 @@ * @private * @param {string[]} modules Array of string module names * @return {Array} List of dependencies, including 'module'. + * @throws {Error} If an unregistered module or a dependency loop is encountered */ function resolve( modules ) { var resolved = []; @@ -2000,8 +2001,12 @@ deferred.fail( error ); } - // Resolve entire dependency map - dependencies = resolve( dependencies ); + try { + // Resolve entire dependency map + dependencies = resolve( dependencies ); + } catch ( e ) { + return deferred.reject( e ).promise(); + } if ( allReady( dependencies ) ) { // Run ready immediately deferred.resolve( mw.loader.require ); diff --git a/tests/phpunit/includes/htmlform/HTMLAutoCompleteSelectFieldTest.php b/tests/phpunit/includes/htmlform/HTMLAutoCompleteSelectFieldTest.php index fbabf7ffad..33e3a257d2 100644 --- a/tests/phpunit/includes/htmlform/HTMLAutoCompleteSelectFieldTest.php +++ b/tests/phpunit/includes/htmlform/HTMLAutoCompleteSelectFieldTest.php @@ -49,9 +49,9 @@ class HtmlAutoCompleteSelectFieldTest extends MediaWikiTestCase { */ function testOptionalSelectElement() { $params = [ - 'fieldname' => 'Test', - 'autocomplete' => $this->options, - 'options' => $this->options, + 'fieldname' => 'Test', + 'autocomplete-data' => $this->options, + 'options' => $this->options, ]; $field = new HTMLAutoCompleteSelectField( $params ); diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.loader.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.loader.test.js index 505d9a17fb..92d13260e9 100644 --- a/tests/qunit/suites/resources/mediawiki/mediawiki.loader.test.js +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.loader.test.js @@ -134,6 +134,48 @@ } ); } ); + QUnit.test( '.using() Error: Circular dependency', function ( assert ) { + mw.loader.register( [ + [ 'test.circle1', '0', [ 'test.circle2' ] ], + [ 'test.circle2', '0', [ 'test.circle3' ] ], + [ 'test.circle3', '0', [ 'test.circle1' ] ] + ] ); + mw.loader.using( 'test.circle3' ).then( + function done() { + assert.ok( false, 'Unexpected resolution, expected error.' ); + }, + function fail( e ) { + assert.ok( /Circular/.test( String( e ) ), 'Detect circular dependency' ); + } + ); + } ); + + QUnit.test( '.load() - Error: Circular dependency', function ( assert ) { + mw.loader.register( [ + [ 'test.circleA', '0', [ 'test.circleB' ] ], + [ 'test.circleB', '0', [ 'test.circleC' ] ], + [ 'test.circleC', '0', [ 'test.circleA' ] ] + ] ); + assert.throws( function () { + mw.loader.load( 'test.circleC' ); + }, /Circular/, 'Detect circular dependency' ); + } ); + + QUnit.test( '.using() - Error: Unregistered', function ( assert ) { + mw.loader.using( 'test.using.unreg' ).then( + function done() { + assert.ok( false, 'Unexpected resolution, expected error.' ); + }, + function fail( e ) { + assert.ok( /Unknown/.test( String( e ) ), 'Detect unknown dependency' ); + } + ); + } ); + + QUnit.test( '.load() - Error: Unregistered (ignored)', 0, function ( assert ) { + mw.loader.load( 'test.using.unreg2' ); + } ); + QUnit.test( '.implement( styles={ "css": [text, ..] } )', 2, function ( assert ) { var $element = $( '
' ).appendTo( '#qunit-fixture' ); @@ -420,17 +462,6 @@ assert.strictEqual( mw.track.callCount, 1 ); } ); - QUnit.test( 'Circular dependency', 1, function ( assert ) { - mw.loader.register( [ - [ 'test.circle1', '0', [ 'test.circle2' ] ], - [ 'test.circle2', '0', [ 'test.circle3' ] ], - [ 'test.circle3', '0', [ 'test.circle1' ] ] - ] ); - assert.throws( function () { - mw.loader.using( 'test.circle3' ); - }, /Circular/, 'Detect circular dependency' ); - } ); - QUnit.test( 'Out-of-order implementation', 9, function ( assert ) { mw.loader.register( [ [ 'test.module4', '0' ],