diff options
Diffstat (limited to 'resources/mediawiki.action')
6 files changed, 417 insertions, 26 deletions
diff --git a/resources/mediawiki.action/mediawiki.action.edit.js b/resources/mediawiki.action/mediawiki.action.edit.js index e5b50958..b121d34f 100644 --- a/resources/mediawiki.action/mediawiki.action.edit.js +++ b/resources/mediawiki.action/mediawiki.action.edit.js @@ -1,30 +1,101 @@ -/* Note, there is still stuff in skins/common/edit.js that - * has not been jQuery-ized. - */ - (function( $ ) { - //make sure edit summary does not exceed byte limit - $( '#wpSummary' ).attr( 'maxLength', 250 ).keypress( function( e ) { - // first check to see if this is actually a character key - // being pressed. - // Based on key-event info from http://unixpapa.com/js/key.html - // JQuery should also normalize e.which to be consistent cross-browser, - // however the same check is still needed regardless of jQuery. + // currentFocus is used to determine where to insert tags + var currentFocused = $( '#wpTextbox1' ); + + mw.toolbar = { + $toolbar : $( '#toolbar' ), + buttons : [], + // If you want to add buttons, use + // mw.toolbar.addButton( imageFile, speedTip, tagOpen, tagClose, sampleText, imageId, selectText ); + addButton : function() { + this.buttons.push( [].slice.call( arguments ) ); + }, + insertButton : function( imageFile, speedTip, tagOpen, tagClose, sampleText, imageId, selectText ) { + var image = $('<img>', { + width : 23, + height : 22, + src : imageFile, + alt : speedTip, + title : speedTip, + id : imageId || '', + 'class': 'mw-toolbar-editbutton' + } ).click( function() { + mw.toolbar.insertTags( tagOpen, tagClose, sampleText, selectText ); + return false; + } ); + + this.$toolbar.append( image ); + return true; + }, - if ( e.which === 0 || e.charCode === 0 || e.ctrlKey || e.altKey || e.metaKey ) { - return true; //a special key (backspace, etc) so don't interfere. + // apply tagOpen/tagClose to selection in textarea, + // use sampleText instead of selection if there is none + insertTags : function( tagOpen, tagClose, sampleText, selectText) { + if ( currentFocused.length ) { + currentFocused.textSelection( + 'encapsulateSelection', { 'pre': tagOpen, 'peri': sampleText, 'post': tagClose } + ); + } + }, + init : function() { + // Legacy + // Merge buttons from mwCustomEditButtons + var buttons = [].concat( this.buttons, window.mwCustomEditButtons ); + for ( var i = 0; i < buttons.length; i++ ) { + if ( $.isArray( buttons[i] ) ) { + // Passes our button array as arguments + mw.toolbar.insertButton.apply( this, buttons[i] ); + } else { + // Legacy mwCustomEditButtons is an object + var c = buttons[i]; + mw.toolbar.insertButton( c.imageFile, c.speedTip, c.tagOpen, c.tagClose, c.sampleText, c.imageId, c.selectText ); + } + } + return true; } + }; - // This basically figures out how many bytes a UTF-16 string (which is what js sees) - // will take in UTF-8 by replacing a 2 byte character with 2 *'s, etc, and counting that. - // Note, surrogate (\uD800-\uDFFF) characters are counted as 2 bytes, since there's two of them - // and the actual character takes 4 bytes in UTF-8 (2*2=4). Might not work perfectly in edge cases - // such as illegal sequences, but that should never happen. + //Legacy + window.addButton = mw.toolbar.addButton; + window.insertTags = mw.toolbar.insertTags; + + //make sure edit summary does not exceed byte limit + $( '#wpSummary' ).byteLimit( 250 ); + + $( document ).ready( function() { + /** + * Restore the edit box scroll state following a preview operation, + * and set up a form submission handler to remember this state + */ + var scrollEditBox = function() { + var editBox = document.getElementById( 'wpTextbox1' ); + var scrollTop = document.getElementById( 'wpScrolltop' ); + var $editForm = $( '#editform' ); + if( $editForm.length && editBox && scrollTop ) { + if( scrollTop.value ) { + editBox.scrollTop = scrollTop.value; + } + $editForm.submit( function() { + scrollTop.value = editBox.scrollTop; + }); + } + }; + scrollEditBox(); + + // Create button bar + mw.toolbar.init(); + + $( 'textarea, input:text' ).focus( function() { + currentFocused = $(this); + }); - var len = this.value.replace( /[\u0080-\u07FF\uD800-\uDFFF]/g, '**' ).replace( /[\u0800-\uD7FF\uE000-\uFFFF]/g, '***' ).length; - //247 as this doesn't count character about to be inserted. - if ( len > 247 ) { - e.preventDefault(); + // HACK: make currentFocused work with the usability iframe + // With proper focus detection support (HTML 5!) this'll be much cleaner + var iframe = $( '.wikiEditor-ui-text iframe' ); + if ( iframe.length > 0 ) { + $( iframe.get( 0 ).contentWindow.document ) + .add( iframe.get( 0 ).contentWindow.document.body ) // for IE + .focus( function() { currentFocused = iframe; } ); } }); })(jQuery); diff --git a/resources/mediawiki.action/mediawiki.action.history.diff.css b/resources/mediawiki.action/mediawiki.action.history.diff.css new file mode 100644 index 00000000..3907a5f4 --- /dev/null +++ b/resources/mediawiki.action/mediawiki.action.history.diff.css @@ -0,0 +1,61 @@ +/* +** Diff rendering +*/ +table.diff, td.diff-otitle, td.diff-ntitle { + background-color: white; +} +td.diff-otitle, +td.diff-ntitle { + text-align: center; +} +td.diff-marker { + text-align: right; +} +td.diff-lineno { + font-weight: bold; +} +td.diff-addedline { + background: #cfc; + font-size: smaller; +} +td.diff-deletedline { + background: #ffa; + font-size: smaller; +} +td.diff-context { + background: #eee; + font-size: smaller; +} +.diffchange { + color: red; + font-weight: bold; + white-space: -moz-pre-wrap; + white-space: pre-wrap; + text-decoration: none; +} + +table.diff { + border: none; + width: 98%; + border-spacing: 4px; + + /* Ensure that colums are of equal width */ + table-layout: fixed; +} +table.diff td { + padding: 0; +} +table.diff col.diff-marker { + width: 2%; +} +table.diff col.diff-content { + width: 48%; +} +table.diff td div { + /* Force-wrap very long lines such as URLs or page-widening char strings.*/ + word-wrap: break-word; + + /* As fallback (FF<3.5, Opera <10.5), scrollbars will be added for very wide cells + instead of text overflowing or widening */ + overflow: auto; +} diff --git a/resources/mediawiki.action/mediawiki.action.history.js b/resources/mediawiki.action/mediawiki.action.history.js index 66f90b07..1b5b3a00 100644 --- a/resources/mediawiki.action/mediawiki.action.history.js +++ b/resources/mediawiki.action/mediawiki.action.history.js @@ -1,7 +1,53 @@ /* * JavaScript for History action */ +jQuery( function( $ ) { + var $lis = $( 'ul#pagehistory li' ); + var updateDiffRadios = function() { + var diffLi = false, // the li where the diff radio is checked + oldLi = false; // the li where the oldid radio is checked -// Replaces histrowinit -$( '#pagehistory li input[name=diff], #pagehistory li input[name=oldid]' ).click( diffcheck ); -diffcheck();
\ No newline at end of file + if ( !$lis.length ) { + return true; + } + $lis.removeClass( 'selected' ); + $lis.each( function() { + var $this = $(this); + var $inputs = $this.find( 'input[type="radio"]' ); + if ( $inputs.length !== 2 ) { + return true; + } + + // this row has a checked radio button + if ( $inputs.get(0).checked ) { + oldLi = true; + $this.addClass( 'selected' ); + $inputs.eq(0).css( 'visibility', 'visible' ); + $inputs.eq(1).css( 'visibility', 'hidden' ); + } else if ( $inputs.get(1).checked ) { + diffLi = true; + $this.addClass( 'selected' ); + $inputs.eq(0).css( 'visibility', 'hidden' ); + $inputs.eq(1).css( 'visibility', 'visible' ); + } else { + // no radio is checked in this row + if ( diffLi && oldLi ) { + // We're below the selected radios + $inputs.eq(0).css( 'visibility', 'visible' ); + $inputs.eq(1).css( 'visibility', 'hidden' ); + } else if ( diffLi ) { + // We're between the selected radios + $inputs.css( 'visibility', 'visible' ); + } else { + // We're above the selected radios + $inputs.eq(1).css( 'visibility', 'visible' ); + $inputs.eq(0).css( 'visibility', 'hidden' ); + } + } + }); + return true; + }; + + $( '#pagehistory li input[name="diff"], #pagehistory li input[name="oldid"]' ).click( updateDiffRadios ); + updateDiffRadios(); +});
\ No newline at end of file diff --git a/resources/mediawiki.action/mediawiki.action.view.metadata.js b/resources/mediawiki.action/mediawiki.action.view.metadata.js new file mode 100644 index 00000000..378dd155 --- /dev/null +++ b/resources/mediawiki.action/mediawiki.action.view.metadata.js @@ -0,0 +1,39 @@ +// Exif metadata display for MediaWiki file uploads +// +// Add an expand/collapse link and collapse by default if set to +// (with JS disabled, user will see all items) +// + +jQuery( document ).ready( function( $ ) { + var showText = mw.msg( 'metadata-expand' ); + var hideText = mw.msg( 'metadata-collapse' ); + + var $table = $( '#mw_metadata' ); + var $tbody = $table.find( 'tbody' ); + if ( !$tbody.length ) { + return; + } + + var $row = $( '<tr></tr>' ); + var $col = $( '<td colspan="2"></td>' ); + + var $link = $( '<a></a>', { + 'text': showText, + 'href': '#' + }).click(function() { + if ( $table.hasClass( 'collapsed' ) ) { + $( this ).text( hideText ); + } else { + $( this ).text( showText ); + } + $table.toggleClass( 'expanded collapsed' ); + return false; + }); + + $col.append( $link ); + $row.append( $col ); + $tbody.append( $row ); + + // And collapse! + $table.addClass( 'collapsed' ); +} ); diff --git a/resources/mediawiki.action/mediawiki.action.view.rightClickEdit.js b/resources/mediawiki.action/mediawiki.action.view.rightClickEdit.js index 5a7c777f..caf9a9f2 100644 --- a/resources/mediawiki.action/mediawiki.action.view.rightClickEdit.js +++ b/resources/mediawiki.action/mediawiki.action.view.rightClickEdit.js @@ -1,7 +1,7 @@ /* * JavaScript to enable right click edit functionality */ -$( function() { +jQuery( function( $ ) { // Select all h1-h6 elements that contain editsection links $( 'h1:has(.editsection a), ' + 'h2:has(.editsection a), ' + diff --git a/resources/mediawiki.action/mediawiki.action.watch.ajax.js b/resources/mediawiki.action/mediawiki.action.watch.ajax.js new file mode 100644 index 00000000..93aa29c9 --- /dev/null +++ b/resources/mediawiki.action/mediawiki.action.watch.ajax.js @@ -0,0 +1,174 @@ +/** + * Animate watch/unwatch links to use asynchronous API requests to + * watch pages, rather than clicking on links. Requires jQuery. + */ +( function( $ ) { +var $links; + +var setLinkText = function( $link, action ) { + if ( action == 'watch' || action == 'unwatch' ) { + // save the accesskey from the title + var keyCommand = $link.attr( 'title' ).match( /\[.*?\]$/ ) ? $link.attr( 'title' ).match( /\[.*?\]$/ )[0] : ''; + $link.attr( 'title', mw.msg( 'tooltip-ca-' + action ) + ' ' + keyCommand ); + } + if ( $link.data( 'icon' ) ) { + $link.attr( 'alt', mw.msg( action ) ); + if ( action == 'watching' || action == 'unwatching' ) { + $link.addClass( 'loading' ); + } else { + $link.removeClass( 'loading' ); + } + } else { + $link.html( mw.msg( action ) ); + } +}; + +var errorHandler = function( $link ) { + + // Reset link text to whatever it was before we switching it to the '(un)watch'+ing message. + setLinkText( $link, $link.data( 'action' ) ); + + // Format error message + var cleanTitle = mw.config.get( 'wgPageName' ).replace( /_/g, ' ' ); + var link = mw.html.element( + 'a', { + 'href': mw.util.wikiGetlink( mw.config.get( 'wgPageName' ) ), + 'title': cleanTitle + }, cleanTitle + ); + var msg = mw.msg( 'watcherrortext', link ); + + // Report to user about the error + mw.util.jsMessage( msg, 'watch' ); +}; + +/** + * Process the result of the API watch action. + * + * @param response Data object from API request. + * @param $link jQuery object of the watch link. + * @return Boolean true on success, false otherwise. + */ +var processResult = function( response, $link ) { + + if ( ( 'error' in response ) || !response.watch ) { + errorHandler( $link ); + return false; + } + + var watchResponse = response.watch; + + // To ensure we set the same status for all watch links with the + // same target we trigger a custom event on *all* watch links. + if ( watchResponse.watched !== undefined ) { + $links.trigger( 'mw-ajaxwatch', [watchResponse.title, 'watch', $link] ); + } else if ( watchResponse.unwatched !== undefined ) { + $links.trigger( 'mw-ajaxwatch', [watchResponse.title, 'unwatch', $link] ); + } else { + // Either we got an error code or it just plain broke. + window.location.href = $link[0].href; + return false; + } + + mw.util.jsMessage( watchResponse.message, 'watch' ); + + // Bug 12395 - update the watch checkbox on edit pages when the + // page is watched or unwatched via the tab. + if ( watchResponse.watched !== undefined ) { + $( '#wpWatchthis' ).attr( 'checked', 'checked' ); + } else { + $( '#wpWatchthis' ).removeAttr( 'checked' ); + } + return true; +}; + +$( document ).ready( function() { + $links = $( '.mw-watchlink a, a.mw-watchlink' ); + // BC with older skins + $links = $links + .add( '#ca-watch a, #ca-unwatch a, a#mw-unwatch-link1, ' + + 'a#mw-unwatch-link2, a#mw-watch-link2, a#mw-watch-link1' ); + // allowing people to add inline animated links is a little scary + $links = $links.filter( ':not( #bodyContent *, #content * )' ); + + $links.each( function() { + var $link = $( this ); + var link = this; + $link + .data( 'icon', $link.closest( 'li' ).hasClass( 'icon' ) ) + .data( 'action', mw.util.getParamValue( 'action', link.href ) == 'unwatch' ? 'unwatch' : 'watch' ); + var title = mw.util.getParamValue( 'title', link.href ); + $link.data( 'target', title.replace( /_/g, ' ' ) ); + }); + + $links.click( function( event ) { + var $link = $( this ); + + if ( !mw.config.get( 'wgEnableWriteAPI' ) ) { + // Lazy initialization so we don't toss up + // ActiveX warnings on initial page load + // for IE 6 users with security settings. + $links.unbind( 'click' ); + return true; + } + + setLinkText( $link, $link.data( 'action' ) + 'ing' ); + + var reqData = { + 'action': 'watch', + 'format': 'json', + 'title': $link.data( 'target' ), + 'token': mw.user.tokens.get( 'watchToken' ), + // API return contains a localized data.watch.message string. + 'uselang': mw.config.get( 'wgUserLanguage' ) + }; + + if ( $link.data( 'action' ) == 'unwatch' ) { + reqData.unwatch = ''; + } + + $.ajax({ + url: mw.util.wikiScript( 'api' ), + dataType: 'json', + type: 'POST', + data: reqData, + success: function( data, textStatus, xhr ) { + processResult( data, $link ); + }, + error: function(){ + processResult( {}, $link ); + } + }); + + return false; + }); + + // When a request returns, a custom event 'mw-ajaxwatch' is triggered + // on *all* watch links, so they can be updated if necessary + $links.bind( 'mw-ajaxwatch', function( event, target, action, $link ) { + var foo = $link.data( 'target' ); + if ( $link.data( 'target' ) == target ) { + var otheraction = action == 'watch' + ? 'unwatch' + : 'watch'; + + $link.data( 'action', otheraction ); + setLinkText( $link, otheraction ); + $link.attr( 'href', + mw.config.get( 'wgScript' ) + + '?title=' + mw.util.wikiUrlencode( mw.config.get( 'wgPageName' ) ) + + '&action=' + otheraction + ); + if ( $link.closest( 'li' ).attr( 'id' ) == 'ca-' + action ) { + $link.closest( 'li' ).attr( 'id', 'ca-' + otheraction ); + // update the link text with the new message + $link.text( mw.msg( otheraction ) ); + } + } + + return false; + }); + +}); + +})( jQuery ); |