diff options
Diffstat (limited to 'resources/mediawiki.special')
25 files changed, 740 insertions, 390 deletions
diff --git a/resources/mediawiki.special/images/arrow-collapsed-ltr.png b/resources/mediawiki.special/images/arrow-collapsed-ltr.png Binary files differdeleted file mode 100644 index 467a555a..00000000 --- a/resources/mediawiki.special/images/arrow-collapsed-ltr.png +++ /dev/null diff --git a/resources/mediawiki.special/images/arrow-collapsed-rtl.png b/resources/mediawiki.special/images/arrow-collapsed-rtl.png Binary files differdeleted file mode 100644 index 2246254f..00000000 --- a/resources/mediawiki.special/images/arrow-collapsed-rtl.png +++ /dev/null diff --git a/resources/mediawiki.special/images/arrow-expanded.png b/resources/mediawiki.special/images/arrow-expanded.png Binary files differdeleted file mode 100644 index 58a9fc66..00000000 --- a/resources/mediawiki.special/images/arrow-expanded.png +++ /dev/null diff --git a/resources/mediawiki.special/images/glyph-people-large.png b/resources/mediawiki.special/images/glyph-people-large.png Binary files differnew file mode 100644 index 00000000..0578be0b --- /dev/null +++ b/resources/mediawiki.special/images/glyph-people-large.png diff --git a/resources/mediawiki.special/images/icon-contributors.png b/resources/mediawiki.special/images/icon-contributors.png Binary files differnew file mode 100644 index 00000000..f933aa69 --- /dev/null +++ b/resources/mediawiki.special/images/icon-contributors.png diff --git a/resources/mediawiki.special/images/icon-edits.png b/resources/mediawiki.special/images/icon-edits.png Binary files differnew file mode 100644 index 00000000..39f4f2de --- /dev/null +++ b/resources/mediawiki.special/images/icon-edits.png diff --git a/resources/mediawiki.special/images/icon-lock.png b/resources/mediawiki.special/images/icon-lock.png Binary files differnew file mode 100644 index 00000000..03f0eecd --- /dev/null +++ b/resources/mediawiki.special/images/icon-lock.png diff --git a/resources/mediawiki.special/images/icon-pages.png b/resources/mediawiki.special/images/icon-pages.png Binary files differnew file mode 100644 index 00000000..59513db2 --- /dev/null +++ b/resources/mediawiki.special/images/icon-pages.png diff --git a/resources/mediawiki.special/mediawiki.special.block.js b/resources/mediawiki.special/mediawiki.special.block.js index 6f79929b..b8bcf177 100644 --- a/resources/mediawiki.special/mediawiki.special.block.js +++ b/resources/mediawiki.special/mediawiki.special.block.js @@ -1,46 +1,46 @@ -/* JavaScript for Special:Block */ +/** + * 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' ); -jQuery( function( $ ) { + 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+$/ ); - var DO_INSTANT = true, - $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' ); - - var updateBlockOptions = function( instant ) { - if ( !$blockTarget.length ) { - return; + 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 ); + } } - var blocktarget = $.trim( $blockTarget.val() ); - var isEmpty = ( blocktarget === '' ); - var isIp = mw.util.isIPv4Address( blocktarget, true ) || mw.util.isIPv6Address( blocktarget, true ); - var isIpRange = isIp && blocktarget.match( /\/\d+$/ ); + if ( $blockTarget.length ) { + // Bind functions so they're checked whenever stuff changes + $blockTarget.keyup( updateBlockOptions ); - 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 ); + // Call them now to set initial state (ie. Special:Block/Foobar?wpBlockExpiry=2+hours) + updateBlockOptions( /* instant= */ true ); } - if ( isIpRange && !isEmpty ) { - $watchUser.goOut( instant ); - } else { - $watchUser.goIn( instant ); - } - }; - - // Bind functions so they're checked whenever stuff changes - $blockTarget.keyup( updateBlockOptions ); + } ); +}( mediaWiki, jQuery ) ); - // Call them now to set initial state (ie. Special:Block/Foobar?wpBlockExpiry=2+hours) - updateBlockOptions( DO_INSTANT ); -}); diff --git a/resources/mediawiki.special/mediawiki.special.changeemail.js b/resources/mediawiki.special/mediawiki.special.changeemail.js index cab0bbd3..2d22bad0 100644 --- a/resources/mediawiki.special/mediawiki.special.changeemail.js +++ b/resources/mediawiki.special/mediawiki.special.changeemail.js @@ -1,42 +1,42 @@ -/* +/** * JavaScript for Special:ChangeEmail */ ( function ( mw, $ ) { + /** + * Given an email validity status (true, false, null) update the label CSS class + */ + function updateMailValidityLabel( mail ) { + var isValid = mw.util.validateEmail( mail ), + $label = $( '#mw-emailaddress-validity' ); -/** - * Given an email validity status (true, false, null) update the label CSS class - */ -function updateMailValidityLabel( mail ) { - var isValid = mw.util.validateEmail( mail ), - $label = $( '#mw-emailaddress-validity' ); - - // We allow empty address - if( isValid === null ) { - $label.text( '' ).removeClass( 'valid invalid' ); + // 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' ); + // 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' ); + // Not valid + } else { + $label.text( mw.msg( 'email-address-validity-invalid' ) ).addClass( 'invalid' ).removeClass( 'valid' ); + } } -} -$( document ).ready( function () { - // 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 direct feedback if it was invalid onblur - $( '#wpNewEmail' ).one( 'blur', function () { - if ( $( '#mw-emailaddress-validity' ).length === 0 ) { - $(this).after( '<label for="wpNewEmail" id="mw-emailaddress-validity"></label>' ); - } - updateMailValidityLabel( $(this).val() ); - $(this).keyup( function () { - updateMailValidityLabel( $(this).val() ); + $( function () { + // 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. + $( '#wpNewEmail' ).one( 'blur', function () { + var $this = $( this ); + if ( $( '#mw-emailaddress-validity' ).length === 0 ) { + $this.after( '<label for="wpNewEmail" id="mw-emailaddress-validity"></label>' ); + } + + updateMailValidityLabel( $this.val() ); + $this.keyup( function () { + updateMailValidityLabel( $this.val() ); + } ); } ); } ); -} ); - }( mediaWiki, jQuery ) ); diff --git a/resources/mediawiki.special/mediawiki.special.changeslist.css b/resources/mediawiki.special/mediawiki.special.changeslist.css index 8a5421e8..5e4af7b6 100644 --- a/resources/mediawiki.special/mediawiki.special.changeslist.css +++ b/resources/mediawiki.special/mediawiki.special.changeslist.css @@ -2,62 +2,6 @@ * Styling for Special:Watchlist and Special:RecentChanges */ -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 arrow shouldn't be shown */ -.client-nojs .mw-enhancedchanges-arrow.mw-collapsible-toggle { - display: none; -} - -.mw-enhancedchanges-arrow { - display: inline-block; - *display: inline; /* IE7 and below */ - zoom: 1; - width: 15px; - height: 15px; -} - -.mw-enhancedchanges-arrow.mw-enhancedchanges-arrow-space { - background: none; -} - -.mw-enhancedchanges-arrow.mw-collapsible-toggle-collapsed { - /* @embed */ - background: url(images/arrow-collapsed-ltr.png) no-repeat left center; -} - -.mw-enhancedchanges-arrow.mw-collapsible-toggle-expanded { - /* @embed */ - background: url(images/arrow-expanded.png) no-repeat left center; -} - .mw-changeslist-line-watched .mw-title { font-weight: bold; } diff --git a/resources/mediawiki.special/mediawiki.special.changeslist.enhanced.css b/resources/mediawiki.special/mediawiki.special.changeslist.enhanced.css new file mode 100644 index 00000000..bed580d7 --- /dev/null +++ b/resources/mediawiki.special/mediawiki.special.changeslist.enhanced.css @@ -0,0 +1,66 @@ +/** + * 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; +} + +/* let it look like it is clickable */ +.mw-enhancedchanges-arrow.mw-collapsible-toggle { + cursor: pointer; +} + +.mw-enhanced-watched .mw-enhanced-rc-time { + font-weight: bold; +} diff --git a/resources/mediawiki.special/mediawiki.special.createAccount.css b/resources/mediawiki.special/mediawiki.special.createAccount.css new file mode 100644 index 00000000..11d00e75 --- /dev/null +++ b/resources/mediawiki.special/mediawiki.special.createAccount.css @@ -0,0 +1,89 @@ +/* Disable the underline that Vector puts on h2 headings, and bold them. */ +.mw-ui-container h2 { + border: 0; + font-weight: bold; +} + +/**** shuffled CAPTCHA ****/ +#wpCaptchaWord { + margin-top: 6px; +} + +.mw-createacct-captcha-container { + background-color: #f8f8f8; + border: 1px solid #c9c9c9; + padding: 10px; + text-align: center; +} + +.mw-createacct-captcha-assisted { + display: block; + margin-top: 0.5em; +} + +/* Put a border around the fancycaptcha-image-container. */ +.mw-createacct-captcha-and-reload { + border: 1px solid #c9c9c9; + display: table-cell; /* Other display formats end up too wide */ + width: 270px; + background-color: #FFF; +} + +/* Make the fancycaptcha-image-container full-width within its parent. */ +.fancycaptcha-image-container +{ + width: 100%; +} + +/**** Benefits column CSS to the right (if it fits) of the form. ****/ +.mw-ui-container #userloginForm { + float: left; +} + +div.mw-createacct-benefits-container { + /* Keeps this column compact and close to the form, but tends to squish contents. */ + float: left; +} + +div.mw-createacct-benefits-container h2 { + margin-bottom: 30px; +} + +.mw-number-text.icon-edits { + /* @embed */ + background: url(images/icon-edits.png) no-repeat left center; +} + +.mw-number-text.icon-pages { + /* @embed */ + background: url(images/icon-pages.png) no-repeat left center; +} + +.mw-number-text.icon-contributors { + /* @embed */ + background: url(images/icon-contributors.png) no-repeat left center; +} + +/* Special font for numbers in benefits*/ +div.mw-number-text h3 { + top: 0; + margin: 0; + padding: 0; + color: #252525; + font-family: 'Georgia', serif; + font-weight: normal; + font-size: 2.2em; + line-height: 1.2; + text-align: center; +} + +/* Contains a number and explanatory text, with space for an icon */ +div.mw-number-text { + display: block; + font-size: 1.2em; + color: #444; + margin-top: 1em; + padding: 0 0 0 95px; /* 80px wide icon plus "margin" */ + min-height: 75px; /* matches max icon height, ensures icon emblem is visible */ + text-align: center; +} diff --git a/resources/mediawiki.special/mediawiki.special.createAccount.js b/resources/mediawiki.special/mediawiki.special.createAccount.js new file mode 100644 index 00000000..5cbb1ee0 --- /dev/null +++ b/resources/mediawiki.special/mediawiki.special.createAccount.js @@ -0,0 +1,112 @@ +/** + * JavaScript for Create account form (Special:UserLogin?type=signup). + */ +( function ( mw, $ ) { + + // When sending password by email, hide the password input fields. + // This function doesn't need to be loaded early by ResourceLoader, but is tiny. + function hidePasswordOnEmail() { + // Always required if checked, otherwise it depends, so we use the original + var $emailLabel = $( 'label[for="wpEmail"]' ), + originalText = $emailLabel.text(), + requiredText = mw.message( 'createacct-emailrequired' ).text(), + $createByMailCheckbox = $( '#wpCreateaccountMail' ), + $beforePwds = $( '.mw-row-password:first' ).prev(), + $pwds; + + function updateForCheckbox() { + var checked = $createByMailCheckbox.prop( 'checked' ); + if ( checked ) { + $pwds = $( '.mw-row-password' ).detach(); + $emailLabel.text( requiredText ); + } else { + if ( $pwds ) { + $beforePwds.after( $pwds ); + $pwds = null; + } + $emailLabel.text( originalText ); + } + } + + $createByMailCheckbox.on( 'change', updateForCheckbox ); + updateForCheckbox(); + } + + // Move the FancyCaptcha image into a more attractive container. + // This function does need to be run early by ResourceLoader. + function adjustFancyCaptcha() { + var $content = $( '#mw-content-text' ), + $submit = $content.find( '#wpCreateaccount' ), + tabIndex, + $captchaStuff, + $captchaImageContainer, + // JavaScript can't yet parse the message createacct-imgcaptcha-help when it + // contains a MediaWiki transclusion, so PHP parses it and sends the HTML. + helpMsg = mw.config.get( 'wgCreateacctImgcaptchaHelp' ), + helpHtml = ''; + + /* + * CAPTCHA + * The CAPTCHA is in a div style="captcha" at the top of the form. + * If it's a FancyCaptcha, then we remove it and insert it lower down, + * in a customized div with just what we need (e.g. no + * fancycaptcha-createaccount message). + */ + if ( !$submit.length) { + return; + } + tabIndex = $submit.prop( 'tabindex' ) - 1; + $captchaStuff = $content.find ( '.captcha' ); + + if ( $captchaStuff.length ) { + + // The FancyCaptcha has this class in the ConfirmEdit extension + // after 2013-04-18. + $captchaImageContainer = $captchaStuff.find( '.fancycaptcha-image-container' ); + if ( $captchaImageContainer.length !== 1 ) { + return; + } + + $captchaStuff.remove(); + + if ( helpMsg) { + helpHtml = '<small class="mw-createacct-captcha-assisted">' + helpMsg + '</small>'; + } + + // Insert another div before the submit button that will include the + // repositioned FancyCaptcha div, an input field, and possible help. + $submit.closest( 'div' ) + .before( [ + '<div>', + '<label for="wpCaptchaWord">' + mw.message( 'createacct-captcha' ).escaped() + '</label>', + '<div class="mw-createacct-captcha-container">', + '<div class="mw-createacct-captcha-and-reload" />', + '<input id="wpCaptchaWord" name="wpCaptchaWord" type="text" placeholder="' + + mw.message( 'createacct-imgcaptcha-ph' ).escaped() + + '" tabindex="' + tabIndex + '" autocapitalize="off" autocorrect="off">', + helpHtml, + '</div>', + '</div>' + ].join( '' ) + ); + + // Stick the FancyCaptcha container inside our bordered and framed parents. + $captchaImageContainer + .prependTo( $content.find( '.mw-createacct-captcha-and-reload' ) ); + + // Find the input field, add the text (if any) of the existing CAPTCHA + // field (although usually it's blanked out on every redisplay), + // and after it move over the hidden field that tells the CAPTCHA + // what to do. + $content.find( '#wpCaptchaWord' ) + .val( $captchaStuff.find( '#wpCaptchaWord' ).val() ) + .after( $captchaStuff.find( '#wpCaptchaId' ) ); + } + } + + $( function () { + adjustFancyCaptcha(); + hidePasswordOnEmail(); + } ); + +}( mediaWiki, jQuery ) ); diff --git a/resources/mediawiki.special/mediawiki.special.javaScriptTest.js b/resources/mediawiki.special/mediawiki.special.javaScriptTest.js index 808d5fe8..a560ca95 100644 --- a/resources/mediawiki.special/mediawiki.special.javaScriptTest.js +++ b/resources/mediawiki.special/mediawiki.special.javaScriptTest.js @@ -8,7 +8,7 @@ // (only if a framework was found, not on error pages). $( '#mw-javascripttest-summary.mw-javascripttest-frameworkfound' ).append( function () { - var $html = $( '<p><label for="useskin">' + var $html = $( '<p><label for="useskin">' + mw.message( 'javascripttest-pagetext-skins' ).escaped() + ' ' + '</label></p>' ), diff --git a/resources/mediawiki.special/mediawiki.special.js b/resources/mediawiki.special/mediawiki.special.js index 3526cef4..8edb1cbe 100644 --- a/resources/mediawiki.special/mediawiki.special.js +++ b/resources/mediawiki.special/mediawiki.special.js @@ -1 +1,5 @@ -mw.special = {}; +/* + * Namespace for mediawiki.special.* modules + */ + +mediaWiki.special = {}; diff --git a/resources/mediawiki.special/mediawiki.special.movePage.js b/resources/mediawiki.special/mediawiki.special.movePage.js index 68c2ed07..922eba5e 100644 --- a/resources/mediawiki.special/mediawiki.special.movePage.js +++ b/resources/mediawiki.special/mediawiki.special.movePage.js @@ -1,5 +1,6 @@ -/* JavaScript for Special:MovePage */ - -jQuery( function( $ ) { +/** + * JavaScript for Special:MovePage + */ +jQuery( function ( $ ) { $( '#wpReason, #wpNewTitleMain' ).byteLimit(); -}); +} ); diff --git a/resources/mediawiki.special/mediawiki.special.pagesWithProp.css b/resources/mediawiki.special/mediawiki.special.pagesWithProp.css new file mode 100644 index 00000000..7ef75d0c --- /dev/null +++ b/resources/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/mediawiki.special/mediawiki.special.preferences.js b/resources/mediawiki.special/mediawiki.special.preferences.js index 47872907..03d93d00 100644 --- a/resources/mediawiki.special/mediawiki.special.preferences.js +++ b/resources/mediawiki.special/mediawiki.special.preferences.js @@ -1,175 +1,199 @@ -/* +/** * JavaScript for Special:Preferences */ -jQuery( document ).ready( function ( $ ) { -$( '#prefsubmit' ).attr( 'id', 'prefcontrol' ); -var $preftoc = $('<ul id="preftoc"></ul>'); -var $preferences = $( '#preferences' ) - .addClass( 'jsprefs' ) - .before( $preftoc ); - -var $fieldsets = $preferences.children( 'fieldset' ) - .hide() - .addClass( 'prefsection' ); +jQuery( function ( $ ) { + var $preftoc, $preferences, $fieldsets, $legends, + hash, + $tzSelect, $tzTextbox, $localtimeHolder, servertime; + + $( '#prefsubmit' ).attr( 'id', 'prefcontrol' ); + + $preftoc = $('<ul id="preftoc"></ul>'); + $preferences = $( '#preferences' ) + .addClass( 'jsprefs' ) + .before( $preftoc ); + $fieldsets = $preferences.children( 'fieldset' ) + .hide() + .addClass( 'prefsection' ); + $legends = $fieldsets + .children( 'legend' ) + .addClass( 'mainLegend' ); + + /** + * It uses document.getElementById for security reasons (HTML injections in $()). + * + * @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' ); + $tab = $( document.getElementById( 'preftab-' + name ) ); + if ( $tab.length ) { + $tab.parent().addClass( 'selected' ); + $preferences.children( 'fieldset' ).hide(); + $( document.getElementById( 'mw-prefsection-' + name ) ).show(); + } + } -var $legends = $fieldsets.children( 'legend' ) - .addClass( 'mainLegend' ); + // 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 = $( '<li>' ) + .addClass( i === 0 ? 'selected' : '' ); + $a = $( '<a>' ) + .attr( { + id: ident.replace( 'mw-prefsection', 'preftab' ), + href: '#' + ident + } ) + .text( $legend.text() ); + $li.append( $a ); + $preftoc.append( $li ); + } ); + + // 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-' , '' ) ); + } -/** - * It uses document.getElementById for security reasons (html injections in - * jQuery()). - * - * @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; + // In browsers that support the onhashchange event we will not bind click + // handlers and instead let the browser do the default behavior (clicking the + // <a href="#.."> 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(); + }); } - $( window ).scrollTop( scrollTop ); - - $preftoc.find( 'li' ).removeClass( 'selected' ); - $tab = $( document.getElementById( 'preftab-' + name ) ); - if ( $tab.length ) { - $tab.parent().addClass( 'selected' ); - $preferences.children( 'fieldset' ).hide(); - $( document.getElementById( 'mw-prefsection-' + name ) ).show(); + + /** + * 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; } -} -// Populate the prefToc -$legends.each( function ( i, legend ) { - var $legend = $(legend); - if ( i === 0 ) { - $legend.parent().show(); + 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; + } } - var ident = $legend.parent().attr( 'id' ); - - var $li = $( '<li/>', { - 'class' : ( i === 0 ) ? 'selected' : null - }); - var $a = $( '<a/>', { - text : $legend.text(), - id : ident.replace( 'mw-prefsection', 'preftab' ), - href : '#' + ident - }); - $li.append( $a ); - $preftoc.append( $li ); -} ); -// If we've reloaded the page or followed an open-in-new-window, -// make the selected tab visible. -var 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 -// <a href="#.."> 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). -if ( 'onhashchange' in window ) { - $(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' ); + 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 ) ); } - }); -// 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 -*/ - -var $tzSelect = $( '#mw-input-wptimecorrection' ); -var $tzTextbox = $( '#mw-input-wptimecorrection-other' ); - -var $localtimeHolder = $( '#wpLocalTime' ); -var servertime = parseInt( $( 'input[name=wpServerTime]' ).val(), 10 ); -var minuteDiff = 0; - -var minutesToHours = function ( min ) { - var tzHour = Math.floor( Math.abs( min ) / 60 ); - var tzMin = Math.abs( min ) % 60; - var tzString = ( ( min >= 0 ) ? '' : '-' ) + ( ( tzHour < 10 ) ? '0' : '' ) + tzHour + - ':' + ( ( tzMin < 10 ) ? '0' : '' ) + tzMin; - return tzString; -}; - -var hoursToMinutes = function ( hour ) { - var arr = hour.split( ':' ); - arr[0] = parseInt( arr[0], 10 ); - - var minutes; - 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; + // 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( minutesToHours( localTime ) ); } - // Gracefully handle non-numbers. - if ( isNaN( minutes ) ) { - return 0; - } else { - return minutes; - } -}; - -var updateTimezoneSelection = function () { - var type = $tzSelect.val(); - if ( type == 'guess' ) { - // Get browser timezone & fill it in - minuteDiff = -new Date().getTimezoneOffset(); - $tzTextbox.val( minutesToHours( minuteDiff ) ); - $tzSelect.val( 'other' ); - $tzTextbox.get( 0 ).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 ) ); + + if ( $tzSelect.length && $tzTextbox.length ) { + $tzSelect.change( updateTimezoneSelection ); + $tzTextbox.blur( updateTimezoneSelection ); + updateTimezoneSelection(); } - // Determine local time from server time and minutes difference, for display. - var localTime = servertime + minuteDiff; + // 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' ); - // Bring time within the [0,1440) range. - while ( localTime < 0 ) { - localTime += 1440; - } - while ( localTime >= 1440 ) { - localTime -= 1440; + $( '#mw-prefs-form' ).submit( function () { + var storageData = $( $preftoc ).find( 'li.selected a' ).attr( 'id' ).replace( 'preftab-', '' ); + sessionStorage.setItem( 'mediawikiPreferencesTab', storageData ); + } ); } - $localtimeHolder.text( minutesToHours( localTime ) ); -}; - -if ( $tzSelect.length && $tzTextbox.length ) { - $tzSelect.change( function () { updateTimezoneSelection(); } ); - $tzTextbox.blur( function () { updateTimezoneSelection(); } ); - updateTimezoneSelection(); -} } ); diff --git a/resources/mediawiki.special/mediawiki.special.recentchanges.js b/resources/mediawiki.special/mediawiki.special.recentchanges.js index 7996d935..79d793af 100644 --- a/resources/mediawiki.special/mediawiki.special.recentchanges.js +++ b/resources/mediawiki.special/mediawiki.special.recentchanges.js @@ -1,39 +1,34 @@ -/* JavaScript for Special:RecentChanges */ +/** + * JavaScript for Special:RecentChanges + */ ( function ( mw, $ ) { + var rc, $checkboxes, $select; - var checkboxes = [ 'nsassociated', 'nsinvert' ]; - - /** - * @var select {jQuery} - */ - var $select = null; - - var rc = mw.special.recentchanges = { - + 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.find('option:selected').val() === ''; + var isAllNS = $select.val() === ''; // Iterates over checkboxes and propagate the selected option - $.each( checkboxes, function ( i, id ) { - $( '#' + id ).prop( 'disabled', isAllNS ); - }); + $checkboxes.prop( 'disabled', isAllNS ); }, init: function () { - // Populate $select = $( '#namespace' ); + $checkboxes = $( '#nsassociated, #nsinvert' ); // Bind to change event, and trigger once to set the initial state of the checkboxes. - $select.change( rc.updateCheckboxes ).change(); + rc.updateCheckboxes(); + $select.change( rc.updateCheckboxes ); } }; - // Run when document is ready $( rc.init ); + mw.special.recentchanges = rc; + }( mediaWiki, jQuery ) ); diff --git a/resources/mediawiki.special/mediawiki.special.search.js b/resources/mediawiki.special/mediawiki.special.search.js index 04954e8d..035252bf 100644 --- a/resources/mediawiki.special/mediawiki.special.search.js +++ b/resources/mediawiki.special/mediawiki.special.search.js @@ -1,49 +1,53 @@ -/* +/** * JavaScript for Special:Search */ -( function( $, mw ) { $( function() { +( function ( mw, $ ) { + $( function () { + var $checkboxes, $headerLinks; -// Emulate HTML5 autofocus behavior in non HTML5 compliant browsers -if ( !( 'autofocus' in document.createElement( 'input' ) ) ) { - $( 'input[autofocus]:first' ).focus(); -} + // 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 -var $checkboxes = $('#powersearch input[id^=mw-search-ns]'); -$('#mw-search-togglebox').append( - $('<label />') - .text(mw.msg('powersearch-togglelabel')) -).append( - $('<input type="button" />') - .attr('id', 'mw-search-toggleall') - .attr('value', mw.msg('powersearch-toggleall')) - .click( function() { - $checkboxes.prop('checked', true); - } ) -).append( - $('<input type="button" />') - .attr('id', 'mw-search-togglenone') - .attr('value', mw.msg('powersearch-togglenone')) - .click( function() { - $checkboxes.prop('checked', false); - } ) -); + // Create check all/none button + $checkboxes = $('#powersearch input[id^=mw-search-ns]'); + $('#mw-search-togglebox').append( + $('<label>') + .text(mw.msg('powersearch-togglelabel')) + ).append( + $('<input type="button" />') + .attr( 'id', 'mw-search-toggleall' ) + .prop( 'value', mw.msg('powersearch-toggleall' ) ) + .click( function () { + $checkboxes.prop('checked', true); + } ) + ).append( + $('<input type="button" />') + .attr( 'id', 'mw-search-togglenone' ) + .prop( 'value', mw.msg('powersearch-togglenone' ) ) + .click( function() { + $checkboxes.prop( 'checked', false ); + } ) + ); -// Change the header search links to what user entered -var headerLinks = $('.search-types a'); -$('#searchText, #powerSearchText').change(function() { - var searchterm = $(this).val(); - headerLinks.each( function() { - var parts = $(this).attr('href').split( 'search=' ); - var lastpart = ''; - var prefix = 'search='; - if( parts.length > 1 && parts[1].indexOf('&') >= 0 ) { - lastpart = parts[1].substring( parts[1].indexOf('&') ); - } else { - prefix = '&search='; - } - this.href = parts[0] + prefix + encodeURIComponent( searchterm ) + lastpart; - }); -}).trigger('change'); + // Change the header search links to what user entered + $headerLinks = $( '.search-types a' ); + $( '#searchText, #powerSearchText' ).change( function () { + var searchterm = $(this).val(); + $headerLinks.each( function () { + var parts = $(this).attr('href').split( 'search=' ), + lastpart = '', + prefix = 'search='; + if ( parts.length > 1 && parts[1].indexOf('&') >= 0 ) { + lastpart = parts[1].substring( parts[1].indexOf('&') ); + } else { + prefix = '&search='; + } + this.href = parts[0] + prefix + encodeURIComponent( searchterm ) + lastpart; + }); + }).trigger( 'change' ); + + } ); -} ); } )( jQuery, mediaWiki ); +}( mediaWiki, jQuery ) ); diff --git a/resources/mediawiki.special/mediawiki.special.undelete.js b/resources/mediawiki.special/mediawiki.special.undelete.js index 33b80275..0dea3ef9 100644 --- a/resources/mediawiki.special/mediawiki.special.undelete.js +++ b/resources/mediawiki.special/mediawiki.special.undelete.js @@ -1,10 +1,11 @@ -/* - * JavaScript for Specical:Undelete +/** + * JavaScript for Special:Undelete */ -jQuery( document ).ready( function( $ ) { - $( '#mw-undelete-invert' ).click( function( e ) { +jQuery( function ( $ ) { + $( '#mw-undelete-invert' ).click( function ( e ) { + $( '#undelete input[type="checkbox"]' ).prop( 'checked', function ( i, val ) { + return !val; + } ); e.preventDefault(); - $( '#undelete' ).find( 'input:checkbox' ) - .prop( 'checked', function( i, val ) { return !val; } ); } ); } ); diff --git a/resources/mediawiki.special/mediawiki.special.upload.js b/resources/mediawiki.special/mediawiki.special.upload.js index 63e89713..3f40c549 100644 --- a/resources/mediawiki.special/mediawiki.special.upload.js +++ b/resources/mediawiki.special/mediawiki.special.upload.js @@ -6,12 +6,12 @@ /** * Add a preview to the upload form */ - $( function ( $ ) { + $( function () { /** * Is the FileAPI available with sufficient functionality? */ function hasFileAPI() { - return typeof window.FileReader !== 'undefined'; + return window.FileReader !== undefined; } /** @@ -25,7 +25,7 @@ * @return boolean */ function fileIsPreviewable( file ) { - var known = ['image/png', 'image/gif', 'image/jpeg', 'image/svg+xml'], + var known = ['image/png', 'image/gif', 'image/jpeg', 'image/svg+xml'], tooHuge = 10 * 1024 * 1024; return ( $.inArray( file.type, known ) !== -1 ) && file.size > 0 && file.size < tooHuge; } @@ -43,23 +43,26 @@ * @param {File} file */ function showPreview( file ) { - var previewSize = 180, + var $canvas, + ctx, + meta, + previewSize = 180, thumb = $( '<div id="mw-upload-thumbnail" class="thumb tright">' + '<div class="thumbinner">' + '<div class="mw-small-spinner" style="width: 180px; height: 180px"></div>' + '<div class="thumbcaption"><div class="filename"></div><div class="fileinfo"></div></div>' + '</div>' + '</div>' ); + thumb.find( '.filename' ).text( file.name ).end() .find( '.fileinfo' ).text( prettySize( file.size ) ).end(); - var $canvas = $('<canvas width="' + previewSize + '" height="' + previewSize + '" ></canvas>'), - ctx = $canvas[0].getContext( '2d' ); + $canvas = $('<canvas width="' + previewSize + '" height="' + previewSize + '" ></canvas>'); + ctx = $canvas[0].getContext( '2d' ); $( '#mw-htmlform-source' ).parent().prepend( thumb ); - var meta; - fetchPreview( file, function( dataURL ) { - var img = new Image(), + fetchPreview( file, function ( dataURL ) { + var img = new Image(), rotation = 0; if ( meta && meta.tiff && meta.tiff.Orientation ) { @@ -79,7 +82,8 @@ } img.onload = function () { - var width, height, x, y, dx, dy, logicalWidth, logicalHeight; + var info, width, height, x, y, dx, dy, logicalWidth, logicalHeight; + // Fit the image within the previewSizexpreviewSize box if ( img.width > img.height ) { width = previewSize; @@ -129,12 +133,14 @@ thumb.find('.mw-small-spinner').replaceWith($canvas); // Image size - var info = mw.msg( 'widthheight', logicalWidth, logicalHeight ) + + info = mw.msg( 'widthheight', logicalWidth, logicalHeight ) + ', ' + prettySize( file.size ); + $( '#mw-upload-thumbnail .fileinfo' ).text( info ); }; img.src = dataURL; }, mw.config.get( 'wgFileCanRotate' ) ? function ( data ) { + /*jshint camelcase: false, nomen: false */ try { meta = mw.libs.jpegmeta( data, file.fileName ); meta._binary_data = null; @@ -171,9 +177,10 @@ // However, our JPEG metadata library wants a string. // So, this is going to be an ugly conversion. reader.onload = function() { - var buffer = new Uint8Array( reader.result ), + var i, + buffer = new Uint8Array( reader.result ), string = ''; - for ( var i = 0; i < buffer.byteLength; i++ ) { + for ( i = 0; i < buffer.byteLength; i++ ) { string += String.fromCharCode( buffer[i] ); } callbackBinary( string ); @@ -196,7 +203,7 @@ } else { // This ends up decoding the file to base-64 and back again, which // feels horribly inefficient. - reader.onload = function() { + reader.onload = function () { callback( reader.result ); }; reader.readAsDataURL( file ); @@ -230,22 +237,29 @@ * Check if the file does not exceed the maximum size */ function checkMaxUploadSize( file ) { + var maxSize, $error; + function getMaxUploadSize( type ) { var sizes = mw.config.get( 'wgMaxUploadSize' ); + if ( sizes[type] !== undefined ) { return sizes[type]; } return sizes['*']; } + $( '.mw-upload-source-error' ).remove(); - var maxSize = getMaxUploadSize( 'file' ); + maxSize = getMaxUploadSize( 'file' ); if ( file.size > maxSize ) { - var error = $( '<p class="error mw-upload-source-error" id="wpSourceTypeFile-error">' + - mw.message( 'largefileserver', file.size, maxSize ).escaped() + '</p>' ); - $( '#wpUploadFile' ).after( error ); + $error = $( '<p class="error mw-upload-source-error" id="wpSourceTypeFile-error">' + + mw.message( 'largefileserver', file.size, maxSize ).escaped() + '</p>' ); + + $( '#wpUploadFile' ).after( $error ); + return false; } + return true; } @@ -276,23 +290,30 @@ /** * Disable all upload source fields except the selected one */ - $( function ( $ ) { - var i, row, - rows = $( '.mw-htmlform-field-UploadSourceField' ); - for ( i = rows.length; i; i-- ) { - row = rows[i - 1]; - $( 'input[name="wpSourceType"]', row ).change( ( function () { - var currentRow = row; // Store current row in our own scope - return function () { - $( '.mw-upload-source-error' ).remove(); - if ( this.checked ) { - // Disable all inputs - $( 'input[name!="wpSourceType"]', rows ).prop( 'disabled', true ); - // Re-enable the current one - $( 'input', currentRow ).prop( 'disabled', false ); - } - }; - }() ) ); + $( function () { + var i, $row, + $rows = $( '.mw-htmlform-field-UploadSourceField' ); + + function createHandler( $currentRow ) { + /** + * @param {jQuery.Event} + */ + return function () { + $( '.mw-upload-source-error' ).remove(); + if ( this.checked ) { + // Disable all inputs + $rows.find( 'input[name!="wpSourceType"]' ).prop( 'disabled', true ); + // Re-enable the current one + $currentRow.find( 'input' ).prop( 'disabled', false ); + } + }; + } + + for ( i = $rows.length; i; i-- ) { + $row = $rows.eq(i - 1); + $row + .find( 'input[name="wpSourceType"]' ) + .change( createHandler( $row ) ); } } ); diff --git a/resources/mediawiki.special/mediawiki.special.userLogin.css b/resources/mediawiki.special/mediawiki.special.userLogin.css new file mode 100644 index 00000000..24c8d771 --- /dev/null +++ b/resources/mediawiki.special/mediawiki.special.userLogin.css @@ -0,0 +1,39 @@ +/* Styles just for VForm user login */ +#mw-userlogin-help { + text-align: center; +} + +.mw-ui-vform .mw-secure { + /* @embed */ + background: url(images/icon-lock.png) no-repeat scroll left center transparent; + margin: 0 0 0 1px; + padding: 0 0 0 11px; +} + +/* The login form invites users to create an account */ +#mw-createaccount-cta { + width: 20em; + height: 10em; + /* @embed */ + background: url(images/glyph-people-large.png) no-repeat 50%; + margin: 0 auto; +} + +#mw-createaccount-cta h3, +#mw-createaccount-another h3 { + font-size: 0.9em; + font-weight: normal; + text-align: center; +} + +#mw-createaccount-cta h3 { + padding-top: 4em; +} + +#mw-createaccount-join { + margin-left: 0.75em; + /* Separate from background image */ + box-shadow: 4px 4px 4px 4px rgba(255, 255, 255, 1); + width: auto; + display: inline-block; +} diff --git a/resources/mediawiki.special/mediawiki.special.vforms.css b/resources/mediawiki.special/mediawiki.special.vforms.css new file mode 100644 index 00000000..768a9c6e --- /dev/null +++ b/resources/mediawiki.special/mediawiki.special.vforms.css @@ -0,0 +1,46 @@ +/* + * When inside the VForm style, disable the border that Vector and other skins + * put on the div surrounding the login/create account form. + * Also disable the margin and padding that Vector puts around the form. + */ +.mw-ui-container #userloginForm, +.mw-ui-container #userlogin { + border: 0; + margin: 0; + padding: 0; +} + +/* Reposition and resize language links, which appear on a per-wiki basis */ +.mw-ui-container #languagelinks { + margin-bottom: 2em; + font-size: 0.8em; +} + +/* Put some space under template's header, which may contain CAPTCHA HTML.*/ +section.mw-form-header { + margin-bottom: 10px; +} + +/* + * Styles for information boxes. + */ +.mw-ui-vform .errorbox, +.mw-ui-vform .warningbox, +.mw-ui-vform .successbox { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + font-size: 0.9em; + margin: 0 0 1em 0; + padding: 0.5em; + word-wrap: break-word; +} + +/* + * Override the right margin of the form to give space in case a benefits + * column appears to the side. + * + */ +.mw-ui-container #userloginForm { + margin-right: 100px; +} |