From c1f9b1f7b1b77776192048005dcc66dcf3df2bfb Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Sat, 27 Dec 2014 15:41:37 +0100 Subject: Update to MediaWiki 1.24.1 --- .../images/glyph-people-large.png | Bin 0 -> 1663 bytes .../mediawiki.special/images/icon-contributors.png | Bin 0 -> 1169 bytes .../src/mediawiki.special/images/icon-edits.png | Bin 0 -> 780 bytes .../src/mediawiki.special/images/icon-lock.png | Bin 0 -> 172 bytes .../src/mediawiki.special/images/icon-pages.png | Bin 0 -> 528 bytes .../mediawiki.special/mediawiki.special.block.css | 11 + .../mediawiki.special/mediawiki.special.block.js | 45 ++ .../mediawiki.special.changeemail.css | 19 + .../mediawiki.special.changeemail.js | 52 ++ .../mediawiki.special.changeslist.css | 7 + .../mediawiki.special.changeslist.enhanced.css | 61 +++ .../mediawiki.special.changeslist.legend.css | 29 ++ .../mediawiki.special.changeslist.legend.js | 25 + .../src/mediawiki.special/mediawiki.special.css | 120 +++++ .../mediawiki.special/mediawiki.special.import.js | 35 ++ .../mediawiki.special.javaScriptTest.js | 36 ++ .../src/mediawiki.special/mediawiki.special.js | 9 + .../mediawiki.special.movePage.js | 6 + .../mediawiki.special.pageLanguage.js | 9 + .../mediawiki.special.pagesWithProp.css | 4 + .../mediawiki.special.preferences.css | 21 + .../mediawiki.special.preferences.js | 305 +++++++++++ .../mediawiki.special.recentchanges.js | 39 ++ .../mediawiki.special/mediawiki.special.search.css | 173 +++++++ .../mediawiki.special/mediawiki.special.search.js | 58 +++ .../mediawiki.special.undelete.js | 11 + .../mediawiki.special.unwatchedPages.css | 9 + .../mediawiki.special.unwatchedPages.js | 52 ++ .../mediawiki.special/mediawiki.special.upload.js | 565 +++++++++++++++++++++ .../mediawiki.special.userlogin.common.css | 66 +++ .../mediawiki.special.userlogin.common.js | 72 +++ .../mediawiki.special.userlogin.login.css | 22 + .../mediawiki.special.userlogin.signup.css | 66 +++ .../mediawiki.special.userlogin.signup.js | 140 +++++ .../mediawiki.special.version.css | 14 + 35 files changed, 2081 insertions(+) create mode 100644 resources/src/mediawiki.special/images/glyph-people-large.png create mode 100644 resources/src/mediawiki.special/images/icon-contributors.png create mode 100644 resources/src/mediawiki.special/images/icon-edits.png create mode 100644 resources/src/mediawiki.special/images/icon-lock.png create mode 100644 resources/src/mediawiki.special/images/icon-pages.png create mode 100644 resources/src/mediawiki.special/mediawiki.special.block.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.block.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.changeemail.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.changeemail.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.changeslist.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.changeslist.enhanced.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.changeslist.legend.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.changeslist.legend.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.import.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.javaScriptTest.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.movePage.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.pageLanguage.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.pagesWithProp.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.preferences.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.preferences.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.recentchanges.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.search.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.search.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.undelete.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.unwatchedPages.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.unwatchedPages.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.upload.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.userlogin.common.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.userlogin.common.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.userlogin.login.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.userlogin.signup.css create mode 100644 resources/src/mediawiki.special/mediawiki.special.userlogin.signup.js create mode 100644 resources/src/mediawiki.special/mediawiki.special.version.css (limited to 'resources/src/mediawiki.special') diff --git a/resources/src/mediawiki.special/images/glyph-people-large.png b/resources/src/mediawiki.special/images/glyph-people-large.png new file mode 100644 index 00000000..0578be0b Binary files /dev/null and b/resources/src/mediawiki.special/images/glyph-people-large.png differ diff --git a/resources/src/mediawiki.special/images/icon-contributors.png b/resources/src/mediawiki.special/images/icon-contributors.png new file mode 100644 index 00000000..f933aa69 Binary files /dev/null and b/resources/src/mediawiki.special/images/icon-contributors.png differ diff --git a/resources/src/mediawiki.special/images/icon-edits.png b/resources/src/mediawiki.special/images/icon-edits.png new file mode 100644 index 00000000..39f4f2de Binary files /dev/null and b/resources/src/mediawiki.special/images/icon-edits.png differ diff --git a/resources/src/mediawiki.special/images/icon-lock.png b/resources/src/mediawiki.special/images/icon-lock.png new file mode 100644 index 00000000..03f0eecd Binary files /dev/null and b/resources/src/mediawiki.special/images/icon-lock.png differ diff --git a/resources/src/mediawiki.special/images/icon-pages.png b/resources/src/mediawiki.special/images/icon-pages.png new file mode 100644 index 00000000..59513db2 Binary files /dev/null and b/resources/src/mediawiki.special/images/icon-pages.png differ diff --git a/resources/src/mediawiki.special/mediawiki.special.block.css b/resources/src/mediawiki.special/mediawiki.special.block.css new file mode 100644 index 00000000..a30a15df --- /dev/null +++ b/resources/src/mediawiki.special/mediawiki.special.block.css @@ -0,0 +1,11 @@ +/*! + * Styling for Special:Block + */ + +label[for="mw-input-wpConfirm"] { + font-weight: bold; +} + +tr.mw-block-hideuser { + font-weight: bold; +} diff --git a/resources/src/mediawiki.special/mediawiki.special.block.js b/resources/src/mediawiki.special/mediawiki.special.block.js new file mode 100644 index 00000000..8579e054 --- /dev/null +++ b/resources/src/mediawiki.special/mediawiki.special.block.js @@ -0,0 +1,45 @@ +/*! + * JavaScript for Special:Block + */ +( function ( mw, $ ) { + $( function () { + var $blockTarget = $( '#mw-bi-target' ), + $anonOnlyRow = $( '#mw-input-wpHardBlock' ).closest( 'tr' ), + $enableAutoblockRow = $( '#mw-input-wpAutoBlock' ).closest( 'tr' ), + $hideUser = $( '#mw-input-wpHideUser' ).closest( 'tr' ), + $watchUser = $( '#mw-input-wpWatch' ).closest( 'tr' ); + + function updateBlockOptions( instant ) { + var blocktarget = $.trim( $blockTarget.val() ), + isEmpty = blocktarget === '', + isIp = mw.util.isIPv4Address( blocktarget, true ) || mw.util.isIPv6Address( blocktarget, true ), + isIpRange = isIp && blocktarget.match( /\/\d+$/ ); + + if ( isIp && !isEmpty ) { + $enableAutoblockRow.goOut( instant ); + $hideUser.goOut( instant ); + } else { + $enableAutoblockRow.goIn( instant ); + $hideUser.goIn( instant ); + } + if ( !isIp && !isEmpty ) { + $anonOnlyRow.goOut( instant ); + } else { + $anonOnlyRow.goIn( instant ); + } + if ( isIpRange && !isEmpty ) { + $watchUser.goOut( instant ); + } else { + $watchUser.goIn( instant ); + } + } + + if ( $blockTarget.length ) { + // Bind functions so they're checked whenever stuff changes + $blockTarget.keyup( updateBlockOptions ); + + // Call them now to set initial state (ie. Special:Block/Foobar?wpBlockExpiry=2+hours) + updateBlockOptions( /* instant= */ true ); + } + } ); +}( mediaWiki, jQuery ) ); diff --git a/resources/src/mediawiki.special/mediawiki.special.changeemail.css b/resources/src/mediawiki.special/mediawiki.special.changeemail.css new file mode 100644 index 00000000..92983dfa --- /dev/null +++ b/resources/src/mediawiki.special/mediawiki.special.changeemail.css @@ -0,0 +1,19 @@ +#mw-emailaddress-validity { + padding: 2px 1em; +} +#mw-emailaddress-validity { + border-bottom-right-radius: 0.8em; + border-top-right-radius: 0.8em; +} + +/* Colors also used in mediawiki.special.preferences.css */ +#mw-emailaddress-validity.valid { + border: 1px solid #80FF80; + background-color: #C0FFC0; + color: black; +} +#mw-emailaddress-validity.invalid { + border: 1px solid #FF8080; + background-color: #FFC0C0; + color: black; +} diff --git a/resources/src/mediawiki.special/mediawiki.special.changeemail.js b/resources/src/mediawiki.special/mediawiki.special.changeemail.js new file mode 100644 index 00000000..67531f78 --- /dev/null +++ b/resources/src/mediawiki.special/mediawiki.special.changeemail.js @@ -0,0 +1,52 @@ +/*! + * JavaScript for Special:ChangeEmail + */ +( function ( mw, $ ) { + /** + * Given an email validity status (true, false, null) update the label CSS class + * @ignore + */ + function updateMailValidityLabel( mail ) { + var isValid = mw.util.validateEmail( mail ), + $label = $( '#mw-emailaddress-validity' ); + + // Set up the validity notice if it doesn't already exist + if ( $label.length === 0 ) { + $label = $( '' ) + .insertAfter( '#wpNewEmail' ); + } + + // We allow empty address + if ( isValid === null ) { + $label.text( '' ).removeClass( 'valid invalid' ); + + // Valid + } else if ( isValid ) { + $label.text( mw.msg( 'email-address-validity-valid' ) ).addClass( 'valid' ).removeClass( 'invalid' ); + + // Not valid + } else { + $label.text( mw.msg( 'email-address-validity-invalid' ) ).addClass( 'invalid' ).removeClass( 'valid' ); + } + } + + $( function () { + $( '#wpNewEmail' ) + // Lame tip to let user know if its email is valid. See bug 22449. + // Only bind once for 'blur' so that the user can fill it in without errors; + // after that, look at every keypress for immediate feedback. + .one( 'blur', function () { + var $this = $( this ); + updateMailValidityLabel( $this.val() ); + $this.keyup( function () { + updateMailValidityLabel( $this.val() ); + } ); + } ) + // Supress built-in validation notice and just call updateMailValidityLabel(), + // to avoid double notice. See bug 40909. + .on( 'invalid', function ( e ) { + e.preventDefault(); + updateMailValidityLabel( $( this ).val() ); + } ); + } ); +}( mediaWiki, jQuery ) ); diff --git a/resources/src/mediawiki.special/mediawiki.special.changeslist.css b/resources/src/mediawiki.special/mediawiki.special.changeslist.css new file mode 100644 index 00000000..c92db167 --- /dev/null +++ b/resources/src/mediawiki.special/mediawiki.special.changeslist.css @@ -0,0 +1,7 @@ +/*! + * Styling for Special:Watchlist and Special:RecentChanges + */ + +.mw-changeslist-line-watched .mw-title { + font-weight: bold; +} diff --git a/resources/src/mediawiki.special/mediawiki.special.changeslist.enhanced.css b/resources/src/mediawiki.special/mediawiki.special.changeslist.enhanced.css new file mode 100644 index 00000000..0e026aff --- /dev/null +++ b/resources/src/mediawiki.special/mediawiki.special.changeslist.enhanced.css @@ -0,0 +1,61 @@ +/*! + * Styling for Special:Watchlist and Special:RecentChanges when preference 'usenewrc' + * a.k.a. Enhanced Recent Changes is enabled. + */ + +table.mw-enhanced-rc { + border: 0; + border-spacing: 0; +} + +table.mw-enhanced-rc th, +table.mw-enhanced-rc td { + padding: 0; + vertical-align: top; +} + +td.mw-enhanced-rc { + white-space: nowrap; + font-family: monospace; +} + +.mw-enhanced-rc-time { + font-family: monospace; +} + +table.mw-enhanced-rc td.mw-enhanced-rc-nested { + padding-left: 1em; +} + +/* Show/hide arrows in enhanced changeslist */ +.mw-enhanced-rc .collapsible-expander { + float: none; +} + +/* If JS is disabled, the arrows or the placeholder space shouldn't be shown */ +.client-nojs .mw-enhancedchanges-arrow-space { + display: none; +} + +/* + * And if it's enabled, let's optimize the collapsing a little: hide the rows + * that would be hidden by jquery.makeCollapsible with CSS to save us some + * reflows and repaints. This doesn't work on browsers that don't fully support + * CSS2 (IE6), but it's okay, this will be done in JavaScript with old degraded + * performance instead. + */ +.client-js table.mw-enhanced-rc.mw-collapsed tr + tr { + display: none; +} + +.mw-enhancedchanges-arrow-space { + display: inline-block; + *display: inline; /* IE7 and below */ + zoom: 1; + width: 15px; + height: 15px; +} + +.mw-enhanced-watched .mw-enhanced-rc-time { + font-weight: bold; +} diff --git a/resources/src/mediawiki.special/mediawiki.special.changeslist.legend.css b/resources/src/mediawiki.special/mediawiki.special.changeslist.legend.css new file mode 100644 index 00000000..6b0bf991 --- /dev/null +++ b/resources/src/mediawiki.special/mediawiki.special.changeslist.legend.css @@ -0,0 +1,29 @@ +/*! + * Styling for changes list legend + */ + +.mw-changeslist-legend { + float: right; + margin-left: 1em; + margin-bottom: 0.5em; + clear: right; + font-size: 85%; + line-height: 1.2em; + padding: 0.5em; + border: 1px solid #ddd; +} + +.mw-changeslist-legend dl { + /* Parent element defines sufficient padding */ + margin-bottom: 0; +} + +.mw-changeslist-legend dt { + float: left; + margin-right: 0.5em; +} + +.mw-changeslist-legend dd { + margin-left: 1.5em; + line-height: 1.3em; +} diff --git a/resources/src/mediawiki.special/mediawiki.special.changeslist.legend.js b/resources/src/mediawiki.special/mediawiki.special.changeslist.legend.js new file mode 100644 index 00000000..c9e55111 --- /dev/null +++ b/resources/src/mediawiki.special/mediawiki.special.changeslist.legend.js @@ -0,0 +1,25 @@ +/*! + * Script for changes list legend + */ + +/* Remember the collapse state of the legend on recent changes and watchlist pages. */ +jQuery( document ).ready( function ( $ ) { + var + cookieName = 'changeslist-state', + cookieOptions = { + expires: 30, + path: '/' + }, + isCollapsed = $.cookie( cookieName ) === 'collapsed'; + + $( '.mw-changeslist-legend' ) + .makeCollapsible( { + collapsed: isCollapsed + } ) + .on( 'beforeExpand.mw-collapsible', function () { + $.cookie( cookieName, 'expanded', cookieOptions ); + } ) + .on( 'beforeCollapse.mw-collapsible', function () { + $.cookie( cookieName, 'collapsed', cookieOptions ); + } ); +} ); diff --git a/resources/src/mediawiki.special/mediawiki.special.css b/resources/src/mediawiki.special/mediawiki.special.css new file mode 100644 index 00000000..0356fc74 --- /dev/null +++ b/resources/src/mediawiki.special/mediawiki.special.css @@ -0,0 +1,120 @@ +/* Special:AllMessages */ +#mw-allmessagestable .allmessages-customised td.am_default { + background-color: #fcffc4; +} + +#mw-allmessagestable tr.allmessages-customised:hover td.am_default { + background-color: #faff90; +} + +#mw-allmessagestable td.am_actual { + background-color: #e2ffe2; +} + +#mw-allmessagestable tr.allmessages-customised:hover + tr.allmessages-customised td.am_actual { + background-color: #b1ffb1; +} + +/* Special:Allpages */ +table.mw-allpages-table-form { + width: 100%; +} +table.mw-allpages-table-form tr { + vertical-align: top; +} +.mw-allpages-nav { + text-align: right; + margin-bottom: 1em; +} + +ul.mw-allpages-chunk { + margin: 0; + padding: 0; +} +ul.mw-allpages-chunk li { + border-top: 1px solid #ccc; + display: inline-block; + margin: 0 1% 0 0; + padding: .2em 0; + vertical-align: top; + width: 31%; +} + +/* Special:BlockList */ +table.mw-blocklist span.mw-usertoollinks, +span.mw-blocklist-actions { + white-space: nowrap; + font-size: 90%; +} + +/* Special:Contributions */ +.mw-uctop { + font-weight: bold; +} + +/* Special:EmailUser */ +td#mw-emailuser-sender, +td#mw-emailuser-recipient { + font-weight: bold; +} + +/* Special:ListGroupRights */ +table.mw-listgrouprights-table tr { + vertical-align: top; +} +.listgrouprights-revoked { + text-decoration: line-through; +} + +/* Special:Prefixindex */ +table.mw-prefixindex-list-table, +table#mw-prefixindex-nav-table { + width: 100%; +} +td#mw-prefixindex-nav-form { + margin-bottom: 1em; + vertical-align: top; +} +.mw-prefixindex-nav { + text-align: right; +} + +/* Special:Specialpages */ +.mw-specialpagerestricted { + font-weight: bold; +} + +.mw-specialpages-table { + margin-top: -1em; + margin-bottom: 1em; +} + +.mw-specialpages-table td { + vertical-align: top; +} + +/* Special:Statistics */ +td.mw-statistics-numbers { + text-align: right; +} + +/* Special:ProtectedPages */ +table.mw-protectedpages span.mw-usertoollinks, +span.mw-protectedpages-length, +span.mw-protectedpages-actions { + white-space: nowrap; + font-size: 90%; +} +span.mw-protectedpages-unknown { + color: grey; + font-size: 90%; +} + +/* Special:UserRights */ +.mw-userrights-disabled { + color: #888; +} +table.mw-userrights-groups * td, +table.mw-userrights-groups * th { + padding-right: 1.5em; +} diff --git a/resources/src/mediawiki.special/mediawiki.special.import.js b/resources/src/mediawiki.special/mediawiki.special.import.js new file mode 100644 index 00000000..a9a985eb --- /dev/null +++ b/resources/src/mediawiki.special/mediawiki.special.import.js @@ -0,0 +1,35 @@ +/*! + * JavaScript for Special:Import + */ +( function ( $ ) { + function updateImportSubprojectList() { + var $projectField = $( '#mw-import-table-interwiki #interwiki' ), + $subprojectField = $projectField.parent().find( '#subproject' ), + $selected = $projectField.find( ':selected' ), + oldValue = $subprojectField.val(), + option, options; + + if ( $selected.attr( 'data-subprojects' ) ) { + options = $.map( $selected.attr( 'data-subprojects' ).split( ' ' ), function ( el ) { + option = document.createElement( 'option' ); + option.appendChild( document.createTextNode( el ) ); + option.setAttribute( 'value', el ); + if ( oldValue === el ) { + option.setAttribute( 'selected', 'selected' ); + } + return option; + } ); + $subprojectField.show().empty().append( options ); + } else { + $subprojectField.hide(); + } + } + + $( function () { + var $projectField = $( '#mw-import-table-interwiki #interwiki' ); + if ( $projectField.length ) { + $projectField.change( updateImportSubprojectList ); + updateImportSubprojectList(); + } + } ); +}( jQuery ) ); diff --git a/resources/src/mediawiki.special/mediawiki.special.javaScriptTest.js b/resources/src/mediawiki.special/mediawiki.special.javaScriptTest.js new file mode 100644 index 00000000..d3e8f299 --- /dev/null +++ b/resources/src/mediawiki.special/mediawiki.special.javaScriptTest.js @@ -0,0 +1,36 @@ +/*! + * JavaScript for Special:JavaScriptTest + */ +( function ( mw, $ ) { + $( function () { + + // Create useskin dropdown menu and reload onchange to the selected skin + // (only if a framework was found, not on error pages). + $( '#mw-javascripttest-summary.mw-javascripttest-frameworkfound' ).append( function () { + + var $html = $( '

' ), + select = ' further + $.each( mw.config.get( 'wgAvailableSkins' ), function ( id ) { + select += ''; + } ); + select += ''; + + // Bind onchange event handler and append to form + $html.append( + $( select ).change( function () { + window.location = QUnit.url( { useskin: $( this ).val() } ); + } ) + ); + + return $html; + } ); + } ); + +}( mediaWiki, jQuery ) ); diff --git a/resources/src/mediawiki.special/mediawiki.special.js b/resources/src/mediawiki.special/mediawiki.special.js new file mode 100644 index 00000000..630d1624 --- /dev/null +++ b/resources/src/mediawiki.special/mediawiki.special.js @@ -0,0 +1,9 @@ +/*! + * Namespace for mediawiki.special.* modules + */ + +/** + * @class mw.special + * @singleton + */ +mediaWiki.special = {}; diff --git a/resources/src/mediawiki.special/mediawiki.special.movePage.js b/resources/src/mediawiki.special/mediawiki.special.movePage.js new file mode 100644 index 00000000..7e56050d --- /dev/null +++ b/resources/src/mediawiki.special/mediawiki.special.movePage.js @@ -0,0 +1,6 @@ +/*! + * JavaScript for Special:MovePage + */ +jQuery( function ( $ ) { + $( '#wpReason, #wpNewTitleMain' ).byteLimit(); +} ); diff --git a/resources/src/mediawiki.special/mediawiki.special.pageLanguage.js b/resources/src/mediawiki.special/mediawiki.special.pageLanguage.js new file mode 100644 index 00000000..ba7f7342 --- /dev/null +++ b/resources/src/mediawiki.special/mediawiki.special.pageLanguage.js @@ -0,0 +1,9 @@ +( function ( $ ) { + $( document ).ready( function () { + + // Select the 'Language select' option if user is trying to select language + $( '#mw-pl-languageselector' ).on( 'click', function () { + $( '#mw-pl-options-2' ).prop( 'checked', true ); + } ); + } ); +} ( jQuery ) ); diff --git a/resources/src/mediawiki.special/mediawiki.special.pagesWithProp.css b/resources/src/mediawiki.special/mediawiki.special.pagesWithProp.css new file mode 100644 index 00000000..7ef75d0c --- /dev/null +++ b/resources/src/mediawiki.special/mediawiki.special.pagesWithProp.css @@ -0,0 +1,4 @@ +/* Distinguish actual data from information about it being hidden visually */ +.prop-value-hidden { + font-style: italic; +} diff --git a/resources/src/mediawiki.special/mediawiki.special.preferences.css b/resources/src/mediawiki.special/mediawiki.special.preferences.css new file mode 100644 index 00000000..e27e34a0 --- /dev/null +++ b/resources/src/mediawiki.special/mediawiki.special.preferences.css @@ -0,0 +1,21 @@ +/* Reuses colors from mediawiki.special.changeemail.css */ +.mw-email-not-authenticated .mw-input, +.mw-email-none .mw-input{ + border: 1px solid #FF8080; + background-color: #FFC0C0; + color: black; +} +/* Authenticated email field has its own class too. Unstyled by default */ +/* +.mw-email-authenticated .mw-input { } +*/ + +/* + * Hide, but keep accessible for screen-readers. + * Like .mw-jump, #jump-to-nav from shared.css + */ +.mw-navigation-hint { + overflow: hidden; + height: 0; + zoom: 1; +} diff --git a/resources/src/mediawiki.special/mediawiki.special.preferences.js b/resources/src/mediawiki.special/mediawiki.special.preferences.js new file mode 100644 index 00000000..1f6429b2 --- /dev/null +++ b/resources/src/mediawiki.special/mediawiki.special.preferences.js @@ -0,0 +1,305 @@ +/*! + * JavaScript for Special:Preferences + */ +jQuery( function ( $ ) { + var $preftoc, $preferences, $fieldsets, $legends, + hash, labelFunc, + $tzSelect, $tzTextbox, $localtimeHolder, servertime, + $checkBoxes, savedWindowOnBeforeUnload; + + labelFunc = function () { + return this.id.replace( /^mw-prefsection/g, 'preftab' ); + }; + + $( '#prefsubmit' ).attr( 'id', 'prefcontrol' ); + $preftoc = $( '' ) + .attr( 'role', 'tablist' ); + $preferences = $( '#preferences' ) + .addClass( 'jsprefs' ) + .before( $preftoc ); + $fieldsets = $preferences.children( 'fieldset' ) + .hide() + .attr( { + role: 'tabpanel', + 'aria-hidden': 'true', + 'aria-labelledby': labelFunc + } ) + .addClass( 'prefsection' ); + $legends = $fieldsets + .children( 'legend' ) + .addClass( 'mainLegend' ); + + // Make sure the accessibility tip is selectable so that screen reader users take notice, + // but hide it per default to reduce interface clutter. Also make sure it becomes visible + // when selected. Similar to jquery.mw-jump + $( '
' ).addClass( 'mw-navigation-hint' ) + .text( mediaWiki.msg( 'prefs-tabs-navigation-hint' ) ) + .attr( 'tabIndex', 0 ) + .on( 'focus blur', function ( e ) { + if ( e.type === 'blur' || e.type === 'focusout' ) { + $( this ).css( 'height', '0' ); + } else { + $( this ).css( 'height', 'auto' ); + } + } ).insertBefore( $preftoc ); + + /** + * It uses document.getElementById for security reasons (HTML injections in $()). + * + * @ignore + * @param String name: the name of a tab without the prefix ("mw-prefsection-") + * @param String mode: [optional] A hash will be set according to the current + * open section. Set mode 'noHash' to surpress this. + */ + function switchPrefTab( name, mode ) { + var $tab, scrollTop; + // Handle hash manually to prevent jumping, + // therefore save and restore scrollTop to prevent jumping. + scrollTop = $( window ).scrollTop(); + if ( mode !== 'noHash' ) { + window.location.hash = '#mw-prefsection-' + name; + } + $( window ).scrollTop( scrollTop ); + + $preftoc.find( 'li' ).removeClass( 'selected' ) + .find( 'a' ).attr( { + tabIndex: -1, + 'aria-selected': 'false' + } ); + + $tab = $( document.getElementById( 'preftab-' + name ) ); + if ( $tab.length ) { + $tab.attr( { + tabIndex: 0, + 'aria-selected': 'true' + } ) + .focus() + .parent().addClass( 'selected' ); + + $preferences.children( 'fieldset' ).hide().attr( 'aria-hidden', 'true' ); + $( document.getElementById( 'mw-prefsection-' + name ) ).show().attr( 'aria-hidden', 'false' ); + } + } + + // Populate the prefToc + $legends.each( function ( i, legend ) { + var $legend = $( legend ), + ident, $li, $a; + if ( i === 0 ) { + $legend.parent().show(); + } + ident = $legend.parent().attr( 'id' ); + + $li = $( '
  • ' ) + .attr( 'role', 'presentation' ) + .addClass( i === 0 ? 'selected' : '' ); + $a = $( '' ) + .attr( { + id: ident.replace( 'mw-prefsection', 'preftab' ), + href: '#' + ident, + role: 'tab', + tabIndex: i === 0 ? 0 : -1, + 'aria-selected': i === 0 ? 'true' : 'false', + 'aria-controls': ident + } ) + .text( $legend.text() ); + $li.append( $a ); + $preftoc.append( $li ); + } ); + + // Enable keyboard users to use left and right keys to switch tabs + $preftoc.on( 'keydown', function ( event ) { + var keyLeft = 37, + keyRight = 39, + $el; + + if ( event.keyCode === keyLeft ) { + $el = $( '#preftoc li.selected' ).prev().find( 'a' ); + } else if ( event.keyCode === keyRight ) { + $el = $( '#preftoc li.selected' ).next().find( 'a' ); + } else { + return; + } + if ( $el.length > 0 ) { + switchPrefTab( $el.attr( 'href' ).replace( '#mw-prefsection-', '' ) ); + } + } ); + + // If we've reloaded the page or followed an open-in-new-window, + // make the selected tab visible. + hash = window.location.hash; + if ( hash.match( /^#mw-prefsection-[\w\-]+/ ) ) { + switchPrefTab( hash.replace( '#mw-prefsection-', '' ) ); + } + + // In browsers that support the onhashchange event we will not bind click + // handlers and instead let the browser do the default behavior (clicking the + // will naturally set the hash, handled by onhashchange. + // But other things that change the hash will also be catched (e.g. using + // the Back and Forward browser navigation). + // Note the special check for IE "compatibility" mode. + if ( 'onhashchange' in window && + ( document.documentMode === undefined || document.documentMode >= 8 ) + ) { + $( window ).on( 'hashchange', function () { + var hash = window.location.hash; + if ( hash.match( /^#mw-prefsection-[\w\-]+/ ) ) { + switchPrefTab( hash.replace( '#mw-prefsection-', '' ) ); + } else if ( hash === '' ) { + switchPrefTab( 'personal', 'noHash' ); + } + } ); + // In older browsers we'll bind a click handler as fallback. + // We must not have onhashchange *and* the click handlers, other wise + // the click handler calls switchPrefTab() which sets the hash value, + // which triggers onhashcange and calls switchPrefTab() again. + } else { + $preftoc.on( 'click', 'li a', function ( e ) { + switchPrefTab( $( this ).attr( 'href' ).replace( '#mw-prefsection-', '' ) ); + e.preventDefault(); + } ); + } + + // Timezone functions. + // Guesses Timezone from browser and updates fields onchange. + + $tzSelect = $( '#mw-input-wptimecorrection' ); + $tzTextbox = $( '#mw-input-wptimecorrection-other' ); + $localtimeHolder = $( '#wpLocalTime' ); + servertime = parseInt( $( 'input[name="wpServerTime"]' ).val(), 10 ); + + function minutesToHours( min ) { + var tzHour = Math.floor( Math.abs( min ) / 60 ), + tzMin = Math.abs( min ) % 60, + tzString = ( ( min >= 0 ) ? '' : '-' ) + ( ( tzHour < 10 ) ? '0' : '' ) + tzHour + + ':' + ( ( tzMin < 10 ) ? '0' : '' ) + tzMin; + return tzString; + } + + function hoursToMinutes( hour ) { + var minutes, + arr = hour.split( ':' ); + + arr[0] = parseInt( arr[0], 10 ); + + if ( arr.length === 1 ) { + // Specification is of the form [-]XX + minutes = arr[0] * 60; + } else { + // Specification is of the form [-]XX:XX + minutes = Math.abs( arr[0] ) * 60 + parseInt( arr[1], 10 ); + if ( arr[0] < 0 ) { + minutes *= -1; + } + } + // Gracefully handle non-numbers. + if ( isNaN( minutes ) ) { + return 0; + } else { + return minutes; + } + } + + function updateTimezoneSelection() { + var minuteDiff, localTime, + type = $tzSelect.val(); + + if ( type === 'guess' ) { + // Get browser timezone & fill it in + minuteDiff = -( new Date().getTimezoneOffset() ); + $tzTextbox.val( minutesToHours( minuteDiff ) ); + $tzSelect.val( 'other' ); + $tzTextbox.prop( 'disabled', false ); + } else if ( type === 'other' ) { + // Grab data from the textbox, parse it. + minuteDiff = hoursToMinutes( $tzTextbox.val() ); + } else { + // Grab data from the $tzSelect value + minuteDiff = parseInt( type.split( '|' )[1], 10 ) || 0; + $tzTextbox.val( minutesToHours( minuteDiff ) ); + } + + // Determine local time from server time and minutes difference, for display. + localTime = servertime + minuteDiff; + + // Bring time within the [0,1440) range. + while ( localTime < 0 ) { + localTime += 1440; + } + while ( localTime >= 1440 ) { + localTime -= 1440; + } + $localtimeHolder.text( mediaWiki.language.convertNumber( minutesToHours( localTime ) ) ); + } + + if ( $tzSelect.length && $tzTextbox.length ) { + $tzSelect.change( updateTimezoneSelection ); + $tzTextbox.blur( updateTimezoneSelection ); + updateTimezoneSelection(); + } + + // Preserve the tab after saving the preferences + // Not using cookies, because their deletion results are inconsistent. + // Not using jStorage due to its enormous size (for this feature) + if ( window.sessionStorage ) { + if ( sessionStorage.getItem( 'mediawikiPreferencesTab' ) !== null ) { + switchPrefTab( sessionStorage.getItem( 'mediawikiPreferencesTab' ), 'noHash' ); + } + // Deleting the key, the tab states should be reset until we press Save + sessionStorage.removeItem( 'mediawikiPreferencesTab' ); + + $( '#mw-prefs-form' ).submit( function () { + var storageData = $( $preftoc ).find( 'li.selected a' ).attr( 'id' ).replace( 'preftab-', '' ); + sessionStorage.setItem( 'mediawikiPreferencesTab', storageData ); + } ); + } + + // To disable all 'namespace' checkboxes in Search preferences + // when 'Search in all namespaces' checkbox is ticked. + $checkBoxes = $( '#mw-htmlform-advancedsearchoptions input[id^=mw-input-wpsearchnamespaces]' ); + if ( $( '#mw-input-wpsearcheverything' ).prop( 'checked' ) ) { + $checkBoxes.prop( 'disabled', true ); + } + $( '#mw-input-wpsearcheverything' ).change( function () { + $checkBoxes.prop( 'disabled', $( this ).prop( 'checked' ) ); + } ); + + // Set up a message to notify users if they try to leave the page without + // saving. + $( '#mw-prefs-form' ).data( 'origdata', $( '#mw-prefs-form' ).serialize() ); + $( window ) + .on( 'beforeunload.prefswarning', function () { + var retval; + + // Check if anything changed + if ( $( '#mw-prefs-form' ).serialize() !== $( '#mw-prefs-form' ).data( 'origdata' ) ) { + // Return our message + retval = mediaWiki.msg( 'prefswarning-warning', mediaWiki.msg( 'saveprefs' ) ); + } + + // Unset the onbeforeunload handler so we don't break page caching in Firefox + savedWindowOnBeforeUnload = window.onbeforeunload; + window.onbeforeunload = null; + if ( retval !== undefined ) { + // ...but if the user chooses not to leave the page, we need to rebind it + setTimeout( function () { + window.onbeforeunload = savedWindowOnBeforeUnload; + }, 1 ); + return retval; + } + } ) + .on( 'pageshow.prefswarning', function () { + // Re-add onbeforeunload handler + if ( !window.onbeforeunload ) { + window.onbeforeunload = savedWindowOnBeforeUnload; + } + } ); + $( '#mw-prefs-form' ).submit( function () { + // Unbind our beforeunload handler + $( window ).off( '.prefswarning' ); + } ); + $( '#mw-prefs-restoreprefs' ).click( function () { + // Unbind our beforeunload handler + $( window ).off( '.prefswarning' ); + } ); +} ); diff --git a/resources/src/mediawiki.special/mediawiki.special.recentchanges.js b/resources/src/mediawiki.special/mediawiki.special.recentchanges.js new file mode 100644 index 00000000..d43b62b0 --- /dev/null +++ b/resources/src/mediawiki.special/mediawiki.special.recentchanges.js @@ -0,0 +1,39 @@ +/*! + * JavaScript for Special:RecentChanges + */ +( function ( mw, $ ) { + var rc, $checkboxes, $select; + + /** + * @class mw.special.recentchanges + * @singleton + */ + rc = { + /** + * Handler to disable/enable the namespace selector checkboxes when the + * special 'all' namespace is selected/unselected respectively. + */ + updateCheckboxes: function () { + // The option element for the 'all' namespace has an empty value + var isAllNS = $select.val() === ''; + + // Iterates over checkboxes and propagate the selected option + $checkboxes.prop( 'disabled', isAllNS ); + }, + + /** */ + init: function () { + $select = $( '#namespace' ); + $checkboxes = $( '#nsassociated, #nsinvert' ); + + // Bind to change event, and trigger once to set the initial state of the checkboxes. + rc.updateCheckboxes(); + $select.change( rc.updateCheckboxes ); + } + }; + + $( rc.init ); + + mw.special.recentchanges = rc; + +}( mediaWiki, jQuery ) ); diff --git a/resources/src/mediawiki.special/mediawiki.special.search.css b/resources/src/mediawiki.special/mediawiki.special.search.css new file mode 100644 index 00000000..ef955077 --- /dev/null +++ b/resources/src/mediawiki.special/mediawiki.special.search.css @@ -0,0 +1,173 @@ +/* Special:Search */ + +/* + * Fixes sister projects box moving down the extract + * of the first result (bug #16886). + * It only happens when the window is small and + * This changes slightly the layout for big screens + * where there was space for the extracts and the + * sister projects and thus it showed like in any + * other browser. + * + * This will only affect IE 7 and lower + */ +.searchresult { + display: inline !ie; +} +.searchresults { +} +.searchresults p { + margin-left: 0.4em; + margin-top: 1em; + margin-bottom: 1.2em; +} +div.searchresult { + font-size: 95%; + width: 38em; +} +.mw-search-results { + margin-left: 0.4em; +} +.mw-search-results li { + padding-bottom: 1.2em; + list-style: none; + list-style-image: none; +} +.mw-search-results li a { + font-size: 108%; +} +.mw-search-result-data { + color: green; + font-size: 97%; +} +.mw-search-formheader { + background-color: #f3f3f3; + margin-top: 1em; + border: 1px solid silver; +} +.mw-search-formheader div.search-types { + float: left; + padding-left: 0.25em; +} +.mw-search-formheader div.search-types ul { + margin: 0 !important; + padding: 0 !important; + list-style: none !important; +} +.mw-search-formheader div.search-types ul li { + float: left; + margin: 0; + padding: 0; +} +.mw-search-formheader div.search-types ul li a { + display: block; + padding: 0.5em; +} +.mw-search-formheader div.search-types ul li.current a { + color: #333333; + cursor: default; +} +.mw-search-formheader div.search-types ul li.current a:hover { + text-decoration: none; +} +#mw-search-top-table div.results-info { + float: right; + padding: 0.5em; + padding-right: 0.75em; + color: #666; + font-size: 95%; +} + +fieldset#mw-searchoptions { + margin: 0; + padding: 0.5em 0.75em 0.75em 0.75em !important; + border: none; + background-color: #f9f9f9; + border: 1px solid silver !important; + border-top-width: 0 !important; +} +fieldset#mw-searchoptions legend { + display: none; +} +fieldset#mw-searchoptions h4 { + padding: 0; + margin: 0; + float: left; +} +fieldset#mw-searchoptions div#mw-search-togglebox { + float: right; +} +fieldset#mw-searchoptions div#mw-search-togglebox label { + margin-right: 0.25em; +} +fieldset#mw-searchoptions div#mw-search-togglebox input { + margin-left: 0.25em; +} +fieldset#mw-searchoptions table { + float: left; + margin-right: 3em; +} +fieldset#mw-searchoptions table td { + padding-right: 1em; + white-space: nowrap; +} +fieldset#mw-searchoptions div.divider { + clear: both; + border-bottom: 1px solid #DDDDDD; + padding-top: 0.5em; + margin-bottom: 0.5em; +} +td#mw-search-menu { + padding-left:6em; + font-size:85%; +} +div#mw-search-interwiki { + float: right; + width: 18em; + border: 1px solid #AAAAAA; + margin-top: 2ex; +} +div#mw-search-interwiki li { + font-size: 95%; +} +.mw-search-interwiki-more { + float: right; + font-size: 90%; +} +div#mw-search-interwiki-caption { + text-align: center; + font-weight: bold; + font-size: 95%; +} +.mw-search-interwiki-project { + font-size: 97%; + text-align: left; + padding: 0.15em 0.15em 0.2em 0.2em; + background-color: #ececec; + border-top: 1px solid #BBBBBB; +} +span.searchalttitle { + font-size: 95%; +} +div.searchdidyoumean { + font-size: 127%; + margin-top: 0.8em; + /* Note that this color won't affect the link, as desired. */ + color: #c00; +} +div.searchdidyoumean em { + font-weight: bold; +} +.searchmatch { + font-weight: bold; +} +/* Advanced PowerSearch box */ +td#mw-search-togglebox { + text-align: right; +} +table#mw-search-powertable { + width: 100%; +} +form#powersearch { + clear: both; +} diff --git a/resources/src/mediawiki.special/mediawiki.special.search.js b/resources/src/mediawiki.special/mediawiki.special.search.js new file mode 100644 index 00000000..b27fe349 --- /dev/null +++ b/resources/src/mediawiki.special/mediawiki.special.search.js @@ -0,0 +1,58 @@ +/*! + * JavaScript for Special:Search + */ +( function ( mw, $ ) { + $( function () { + var $checkboxes, $headerLinks; + + // Emulate HTML5 autofocus behavior in non HTML5 compliant browsers + if ( !( 'autofocus' in document.createElement( 'input' ) ) ) { + $( 'input[autofocus]' ).eq( 0 ).focus(); + } + + // Create check all/none button + $checkboxes = $( '#powersearch input[id^=mw-search-ns]' ); + $( '#mw-search-togglebox' ).append( + $( '