Index: branches/wmf/1.18wmf1/RELEASE-NOTES-1.18 |
— | — | @@ -456,6 +456,7 @@ |
457 | 457 | * (bug 30907) Special:Unusedcategories should sort ascendingly. |
458 | 458 | * (bug 28545) When using the uca-default collation, sortkey's starting with a |
459 | 459 | space (U+20) will sort under an invisible header like in 1.16 rather than a U+6DE |
| 460 | +* (bug 31674) Can't edit watchlist if it contains special pages |
460 | 461 | |
461 | 462 | === API changes in 1.18 === |
462 | 463 | * BREAKING CHANGE: action=watch now requires POST and token. |
Property changes on: branches/wmf/1.18wmf1/RELEASE-NOTES-1.18 |
___________________________________________________________________ |
Modified: svn:mergeinfo |
463 | 464 | Merged /trunk/phase3/RELEASE-NOTES-1.18:r98669,99164,99321,99332,99632,99897,99914,99952,99994,100391,100398,100504,100656,100701,101010 |
Index: branches/wmf/1.18wmf1/extensions/WikiEditor/modules/jquery.wikiEditor.dialogs.config.js |
— | — | @@ -779,8 +779,11 @@ |
780 | 780 | .addClass( 'sortable' ) |
781 | 781 | .insertAfter( $( '#wikieditor-toolbar-table-preview' ) ) |
782 | 782 | .hide(); |
783 | | - if ( typeof jQuery.fn.tablesorter == 'function' ) |
784 | | - $( '#wikieditor-toolbar-table-preview2' ).tablesorter(); |
| 783 | + |
| 784 | + mw.loader.using( 'jquery.tablesorter', function() { |
| 785 | + $( '#wikieditor-toolbar-table-preview2' ).tablesorter(); |
| 786 | + }); |
| 787 | + |
785 | 788 | $( '#wikieditor-toolbar-table-sortable' ).click( function() { |
786 | 789 | // Swap the currently shown one clone with the other one |
787 | 790 | $( '#wikieditor-toolbar-table-preview' ) |
Index: branches/wmf/1.18wmf1/extensions/GlobalBlocking/SpecialGlobalBlock.php |
— | — | @@ -181,7 +181,7 @@ |
182 | 182 | $fields = array (); |
183 | 183 | |
184 | 184 | // Who to block |
185 | | - $fields['ipaddress'] = |
| 185 | + $fields['globalblocking-ipaddress'] = |
186 | 186 | Xml::input( 'wpAddress', |
187 | 187 | 45, |
188 | 188 | $this->mAddress, |
— | — | @@ -246,7 +246,7 @@ |
247 | 247 | // Block all users, or just anonymous ones |
248 | 248 | $fields['globalblocking-block-options'] = |
249 | 249 | Xml::checkLabel( |
250 | | - wfMsg( 'ipbanononly' ), |
| 250 | + wfMsg( 'globalblocking-ipbanononly' ), |
251 | 251 | 'wpAnonOnly', |
252 | 252 | 'mw-globalblock-anon-only', |
253 | 253 | $this->mAnonOnly |
Index: branches/wmf/1.18wmf1/extensions/GlobalBlocking/GlobalBlocking.i18n.php |
— | — | @@ -30,6 +30,8 @@ |
31 | 31 | 'globalblocking-block-expiry-otherfield' => 'Other time:', |
32 | 32 | 'globalblocking-block-legend' => 'Block an IP address globally', |
33 | 33 | 'globalblocking-block-options' => 'Options:', |
| 34 | + 'globalblocking-ipaddress' => 'IP address:', |
| 35 | + 'globalblocking-ipbanononly' => 'Block anonymous users only', |
34 | 36 | 'globalblocking-block-errors' => "Your block was unsuccessful, for the following {{PLURAL:$1|reason|reasons}}:", |
35 | 37 | 'globalblocking-block-ipinvalid' => 'The IP address ($1) you entered is invalid. |
36 | 38 | Please note that you cannot enter a user name!', |
Index: branches/wmf/1.18wmf1/includes/CategoryPage.php |
— | — | @@ -68,14 +68,27 @@ |
69 | 69 | // Use these as defaults for back compat --catrope |
70 | 70 | $oldFrom = $wgRequest->getVal( 'from' ); |
71 | 71 | $oldUntil = $wgRequest->getVal( 'until' ); |
| 72 | + |
| 73 | + $reqArray = $wgRequest->getValues(); |
72 | 74 | |
73 | 75 | $from = $until = array(); |
74 | 76 | foreach ( array( 'page', 'subcat', 'file' ) as $type ) { |
75 | 77 | $from[$type] = $wgRequest->getVal( "{$type}from", $oldFrom ); |
76 | 78 | $until[$type] = $wgRequest->getVal( "{$type}until", $oldUntil ); |
| 79 | + |
| 80 | + // Do not want old-style from/until propagating in nav links. |
| 81 | + if ( !isset( $reqArray["{$type}from"] ) && isset( $reqArray["from"] ) ) { |
| 82 | + $reqArray["{$type}from"] = $reqArray["from"]; |
| 83 | + } |
| 84 | + if ( !isset( $reqArray["{$type}to"] ) && isset( $reqArray["to"] ) ) { |
| 85 | + $reqArray["{$type}to"] = $reqArray["to"]; |
| 86 | + } |
77 | 87 | } |
78 | 88 | |
79 | | - $viewer = new $this->mCategoryViewerClass( $this->mTitle, $from, $until, $wgRequest->getValues() ); |
| 89 | + unset( $reqArray["from"] ); |
| 90 | + unset( $reqArray["to"] ); |
| 91 | + |
| 92 | + $viewer = new $this->mCategoryViewerClass( $this->mTitle, $from, $until, $reqArray ); |
80 | 93 | $wgOut->addHTML( $viewer->getHTML() ); |
81 | 94 | } |
82 | 95 | } |
Property changes on: branches/wmf/1.18wmf1/includes/CategoryPage.php |
___________________________________________________________________ |
Modified: svn:mergeinfo |
83 | 96 | Merged /trunk/phase3/includes/CategoryPage.php:r98669,99164,99321,99332,99632,99897,99914,99952,99994,100391,100398,100504,100656,100701,101010 |
Index: branches/wmf/1.18wmf1/includes/User.php |
— | — | @@ -2571,6 +2571,14 @@ |
2572 | 2572 | } |
2573 | 2573 | |
2574 | 2574 | /** |
| 2575 | + * Cleans up watchlist by removing invalid entries from it |
| 2576 | + */ |
| 2577 | + public function cleanupWatchlist() { |
| 2578 | + $dbw = wfGetDB( DB_MASTER ); |
| 2579 | + $dbw->delete( 'watchlist', array( 'wl_namespace < 0', 'wl_user' => $this->getId() ), __METHOD__ ); |
| 2580 | + } |
| 2581 | + |
| 2582 | + /** |
2575 | 2583 | * Clear the user's notification timestamp for the given title. |
2576 | 2584 | * If e-notif e-mails are on, they will receive notification mails on |
2577 | 2585 | * the next change of the page if it's watched etc. |
Index: branches/wmf/1.18wmf1/includes/db/Database.php |
— | — | @@ -47,7 +47,7 @@ |
48 | 48 | * Fields can be retrieved with $row->fieldname, with fields acting like |
49 | 49 | * member variables. |
50 | 50 | * |
51 | | - * @param $res SQL result object as returned from DatabaseBase::query(), etc. |
| 51 | + * @param $res ResultWrapper|object as returned from DatabaseBase::query(), etc. |
52 | 52 | * @return Row object |
53 | 53 | * @throws DBUnexpectedError Thrown if the database returns an error |
54 | 54 | */ |
Property changes on: branches/wmf/1.18wmf1/includes/db/Database.php |
___________________________________________________________________ |
Modified: svn:mergeinfo |
55 | 55 | Merged /trunk/phase3/includes/db/Database.php:r98669,99164,99321,99332,99632,99897,99914,99952,99994,100391,100398,100504,100656,100701,101010 |
Index: branches/wmf/1.18wmf1/includes/api/ApiWatch.php |
— | — | @@ -49,7 +49,7 @@ |
50 | 50 | $params = $this->extractRequestParams(); |
51 | 51 | $title = Title::newFromText( $params['title'] ); |
52 | 52 | |
53 | | - if ( !$title ) { |
| 53 | + if ( !$title || $title->getNamespace() < 0 ) { |
54 | 54 | $this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) ); |
55 | 55 | } |
56 | 56 | |
Index: branches/wmf/1.18wmf1/includes/media/XMPInfo.php |
— | — | @@ -557,13 +557,16 @@ |
558 | 558 | 'map_group' => 'exif', |
559 | 559 | 'mode' => XMPReader::MODE_SIMPLE, |
560 | 560 | ), |
561 | | - 'Orientation' => array( |
562 | | - 'map_group' => 'exif', |
563 | | - 'mode' => XMPReader::MODE_SIMPLE, |
564 | | - 'validate' => 'validateClosed', |
565 | | - 'choices' => array( '1' => true, '2' => true, '3' => true, '4' => true, 5 => true, |
566 | | - '6' => true, '7' => true, '8' => true ), |
567 | | - ), |
| 561 | + /**** Do not extract this property |
| 562 | + * It interferes with auto exif rotation. |
| 563 | + * 'Orientation' => array( |
| 564 | + * 'map_group' => 'exif', |
| 565 | + * 'mode' => XMPReader::MODE_SIMPLE, |
| 566 | + * 'validate' => 'validateClosed', |
| 567 | + * 'choices' => array( '1' => true, '2' => true, '3' => true, '4' => true, 5 => true, |
| 568 | + * '6' => true, '7' => true, '8' => true ), |
| 569 | + *), |
| 570 | + ******/ |
568 | 571 | 'PhotometricInterpretation' => array( |
569 | 572 | 'map_group' => 'exif', |
570 | 573 | 'mode' => XMPReader::MODE_SIMPLE, |
Index: branches/wmf/1.18wmf1/includes/specials/SpecialEditWatchlist.php |
— | — | @@ -392,8 +392,13 @@ |
393 | 393 | |
394 | 394 | $fields = array(); |
395 | 395 | |
| 396 | + $haveInvalidNamespaces = false; |
396 | 397 | foreach( $this->getWatchlistInfo() as $namespace => $pages ){ |
397 | | - |
| 398 | + if ( $namespace < 0 ) { |
| 399 | + $haveInvalidNamespaces = true; |
| 400 | + continue; |
| 401 | + } |
| 402 | + |
398 | 403 | $namespace == NS_MAIN |
399 | 404 | ? wfMsgHtml( 'blanknamespace' ) |
400 | 405 | : htmlspecialchars( $wgContLang->getFormattedNsText( $namespace ) ); |
— | — | @@ -410,6 +415,10 @@ |
411 | 416 | $fields['TitlesNs'.$namespace]['options'][$text] = $title->getEscapedText(); |
412 | 417 | } |
413 | 418 | } |
| 419 | + if ( $haveInvalidNamespaces ) { |
| 420 | + wfDebug( "User {$this->getContext()->getUser()->getId()} has invalid watchlist entries, clening up...\n" ); |
| 421 | + $this->getContext()->getUser()->cleanupWatchlist(); |
| 422 | + } |
414 | 423 | |
415 | 424 | $form = new EditWatchlistNormalHTMLForm( $fields ); |
416 | 425 | $form->setTitle( $this->getTitle() ); |
Property changes on: branches/wmf/1.18wmf1/includes/specials/SpecialEditWatchlist.php |
___________________________________________________________________ |
Modified: svn:mergeinfo |
417 | 426 | Merged /trunk/phase3/includes/specials/SpecialEditWatchlist.php:r98669,99164,99321,99332,99632,99897,99914,99952,99994,100391,100398,100504,100656,100701,101010 |
Index: branches/wmf/1.18wmf1/includes/Import.php |
— | — | @@ -1286,7 +1286,7 @@ |
1287 | 1287 | # quicker and sorts out user-agent problems which might |
1288 | 1288 | # otherwise prevent importing from large sites, such |
1289 | 1289 | # as the Wikimedia cluster, etc. |
1290 | | - $data = Http::request( $method, $url ); |
| 1290 | + $data = Http::request( $method, $url, array( 'followRedirects' => true ) ); |
1291 | 1291 | if( $data !== false ) { |
1292 | 1292 | $file = tmpfile(); |
1293 | 1293 | fwrite( $file, $data ); |
Index: branches/wmf/1.18wmf1/resources/jquery/jquery.textSelection.js |
— | — | @@ -205,12 +205,20 @@ |
206 | 206 | * Get the position (in resolution of bytes not nessecarily characters) |
207 | 207 | * in a textarea |
208 | 208 | * |
| 209 | + * Will focus the textarea in some browsers (IE/Opera) |
| 210 | + * |
209 | 211 | * @fixme document the options parameters |
210 | 212 | */ |
211 | 213 | getCaretPosition: function( options ) { |
212 | 214 | function getCaret( e ) { |
213 | 215 | var caretPos = 0, endPos = 0; |
214 | 216 | if ( $.browser.msie ) { |
| 217 | + // IE doesn't properly report non-selected caret position through |
| 218 | + // the selection ranges when textarea isn't focused. This can |
| 219 | + // lead to saving a bogus empty selection, which then screws up |
| 220 | + // whatever we do later (bug 31847). |
| 221 | + e.focus(); |
| 222 | + |
215 | 223 | // IE Support |
216 | 224 | var preFinished = false; |
217 | 225 | var periFinished = false; |
Index: branches/wmf/1.18wmf1/resources/jquery/jquery.tablesorter.js |
— | — | @@ -223,19 +223,36 @@ |
224 | 224 | * This only treats a row as a header row if it contains only <th>s (no <td>s) |
225 | 225 | * and if it is preceded entirely by header rows. The algorithm stops when |
226 | 226 | * it encounters the first non-header row. |
| 227 | + * |
| 228 | + * After this, it will look at all rows at the bottom for footer rows |
| 229 | + * And place these in a tfoot using similar rules. |
227 | 230 | * @param $table jQuery object for a <table> |
228 | 231 | */ |
229 | | - function emulateTHead( $table ) { |
230 | | - var $thead = $( '<thead>' ); |
231 | | - $table.find( 'tr' ).each( function() { |
232 | | - if ( $(this).children( 'td' ).length > 0 ) { |
233 | | - // This row contains a <td>, so it's not a header row |
234 | | - // Stop here |
235 | | - return false; |
236 | | - } |
237 | | - $thead.append( this ); |
238 | | - } ); |
239 | | - $table.prepend( $thead ); |
| 232 | + function emulateTHeadAndFoot( $table ) { |
| 233 | + var $rows = $table.find( 'tr' ); |
| 234 | + if( !$table.get(0).tHead ) { |
| 235 | + var $thead = $( '<thead>' ); |
| 236 | + $rows.each( function() { |
| 237 | + if ( $(this).children( 'td' ).length > 0 ) { |
| 238 | + // This row contains a <td>, so it's not a header row |
| 239 | + // Stop here |
| 240 | + return false; |
| 241 | + } |
| 242 | + $thead.append( this ); |
| 243 | + } ); |
| 244 | + $table.prepend( $thead ); |
| 245 | + } |
| 246 | + if( !$table.get(0).tFoot ) { |
| 247 | + var $tfoot = $( '<tfoot>' ); |
| 248 | + var len = $rows.length; |
| 249 | + for ( var i = len-1; i >= 0; i-- ) { |
| 250 | + if( $( $rows[i] ).children( 'td' ).length > 0 ){ |
| 251 | + break; |
| 252 | + } |
| 253 | + $tfoot.prepend( $( $rows[i] )); |
| 254 | + } |
| 255 | + $table.append( $tfoot ); |
| 256 | + } |
240 | 257 | } |
241 | 258 | |
242 | 259 | function buildHeaders( table, msg ) { |
— | — | @@ -531,8 +548,8 @@ |
532 | 549 | } |
533 | 550 | if ( !table.tHead ) { |
534 | 551 | // No thead found. Look for rows with <th>s and |
535 | | - // move them into a <thead> tag |
536 | | - emulateTHead( $table ); |
| 552 | + // move them into a <thead> tag or a <tfoot> tag |
| 553 | + emulateTHeadAndFoot( $table ); |
537 | 554 | |
538 | 555 | // Still no thead? Then quit |
539 | 556 | if ( !table.tHead ) { |
— | — | @@ -567,8 +584,13 @@ |
568 | 585 | cacheRegexs(); |
569 | 586 | |
570 | 587 | // Apply event handling to headers |
571 | | - // this is to big, perhaps break it out? |
| 588 | + // this is too big, perhaps break it out? |
572 | 589 | $headers.click( function( e ) { |
| 590 | + if ( e.target.nodeName.toLowerCase() == 'a' ) { |
| 591 | + // The user clicked on a link inside a table header |
| 592 | + // Do nothing and let the default link click action continue |
| 593 | + return true; |
| 594 | + } |
573 | 595 | |
574 | 596 | if ( firstTime ) { |
575 | 597 | firstTime = false; |
— | — | @@ -578,7 +600,12 @@ |
579 | 601 | // and put the <tfoot> at the end of the <table> |
580 | 602 | var $sortbottoms = $table.find( 'tr.sortbottom' ); |
581 | 603 | if ( $sortbottoms.length ) { |
582 | | - $table.append( $( '<tfoot>' ).append( $sortbottoms ) ) |
| 604 | + var $tfoot = $table.find( 'tfoot' ); |
| 605 | + if( $tfoot.length ) { |
| 606 | + $tfoot.eq(0).prepend( $sortbottoms ); |
| 607 | + } else { |
| 608 | + $table.append( $( '<tfoot>' ).append( $sortbottoms ) ) |
| 609 | + } |
583 | 610 | } |
584 | 611 | |
585 | 612 | explodeRowspans( $table ); |
— | — | @@ -645,12 +672,7 @@ |
646 | 673 | }; |
647 | 674 | return false; |
648 | 675 | } |
649 | | - } ) |
650 | | - // Allow links in headers to be clicked |
651 | | - .find( 'a' ).click( function( e ) { |
652 | | - e.stopPropagation(); |
653 | 676 | } ); |
654 | | - |
655 | 677 | } ); |
656 | 678 | }, |
657 | 679 | |