summaryrefslogtreecommitdiff
path: root/resources/mediawiki.action
diff options
context:
space:
mode:
Diffstat (limited to 'resources/mediawiki.action')
-rw-r--r--resources/mediawiki.action/mediawiki.action.edit.js115
-rw-r--r--resources/mediawiki.action/mediawiki.action.history.diff.css61
-rw-r--r--resources/mediawiki.action/mediawiki.action.history.js52
-rw-r--r--resources/mediawiki.action/mediawiki.action.view.metadata.js39
-rw-r--r--resources/mediawiki.action/mediawiki.action.view.rightClickEdit.js2
-rw-r--r--resources/mediawiki.action/mediawiki.action.watch.ajax.js174
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 );