Allow postEdit hook to be triggered asynchronously
authorEd Sanders <esanders@wikimedia.org>
Fri, 21 Jun 2013 12:32:10 +0000 (13:32 +0100)
committerTimo Tijhof <krinklemail@gmail.com>
Mon, 15 Jul 2013 10:26:02 +0000 (12:26 +0200)
This is required by VisualEditor as it doesn't do a page reload
after a save. So we need it to keep listening even if the
initial config and cookie data doesn't show an edit was just
made.

* Allow the message to be overriden, as VE uses its own.
* Using jQuery instead of direct DOM interaction with `div` (and
  renamed to $div accordingly).
* Moved click handler from postedit-close to postedit-container.

Bug: 39632
Change-Id: I778b18bc051c51de355e122d8d4517b5a651ed4c

maintenance/jsduck/config.json
resources/mediawiki.action/mediawiki.action.view.postEdit.css
resources/mediawiki.action/mediawiki.action.view.postEdit.js

index 60522c5..7aff516 100644 (file)
@@ -16,6 +16,7 @@
                "../../resources/mediawiki/mediawiki.notification.js",
                "../../resources/mediawiki/mediawiki.user.js",
                "../../resources/mediawiki.action/mediawiki.action.edit.js",
+               "../../resources/mediawiki.action/mediawiki.action.view.postEdit.js",
                "../../resources/mediawiki.api",
                "../../resources/jquery/jquery.localize.js"
        ]
index d693d80..6c7b2ca 100644 (file)
@@ -7,6 +7,10 @@
        z-index: 1000;
 }
 
+.postedit-container:hover {
+       cursor: pointer;
+}
+
 .postedit {
        position: relative;
        top: 0.6em;
@@ -77,7 +81,6 @@
 .postedit-close:hover {
        color: black;
        text-decoration: none;
-       cursor: pointer;
        opacity: 0.4;
        filter: alpha(opacity=40);
 }
index e7a3e3c..8e67ea9 100644 (file)
@@ -4,42 +4,65 @@
        var config = mw.config.get( [ 'wgAction', 'wgCookiePrefix', 'wgCurRevisionId' ] ),
                // This should match EditPage::POST_EDIT_COOKIE_KEY_PREFIX:
                cookieKey = config.wgCookiePrefix + 'PostEditRevision' + config.wgCurRevisionId,
-               div, id;
+               $div, id;
 
-       if ( config.wgAction !== 'view' || $.cookie( cookieKey ) !== '1' ) {
-               return;
-       }
+       function showConfirmation( data ) {
+               data = data || {};
+               if ( data.message === undefined ) {
+                       data.message = $.parseHTML( mw.message( 'postedit-confirmation', data.user || mw.user ).escaped() );
+               }
 
-       $.cookie( cookieKey, null, { path: '/' } );
-       mw.config.set( 'wgPostEdit', true );
+               $div = $(
+                       '<div class="postedit-container">' +
+                               '<div class="postedit">' +
+                                       '<div class="postedit-icon postedit-icon-checkmark postedit-content"></div>' +
+                                       '<a href="#" class="postedit-close">&times;</a>' +
+                               '</div>' +
+                       '</div>'
+               );
 
-       function removeConfirmation() {
-               div.parentNode.removeChild( div );
-               mw.hook( 'postEdit.afterRemoval' ).fire();
+               if ( typeof data.message === 'string' ) {
+                       $div.find( '.postedit-content' ).text( data.message );
+               } else if ( typeof data.message === 'object' ) {
+                       $div.find( '.postedit-content' ).append( data.message );
+               }
+
+               $div
+                       .click( fadeOutConfirmation )
+                       .prependTo( 'body' );
+
+               id = setTimeout( fadeOutConfirmation, 3000 );
        }
 
        function fadeOutConfirmation() {
                clearTimeout( id );
-               div.firstChild.className = 'postedit postedit-faded';
+               $div.find( '.postedit' ).addClass( 'postedit postedit-faded' );
                setTimeout( removeConfirmation, 500 );
+
                return false;
        }
 
-       function showConfirmation() {
-               div = document.createElement( 'div' );
-               div.className = 'postedit-container';
-               div.innerHTML =
-                       '<div class="postedit">' +
-                               '<div class="postedit-icon postedit-icon-checkmark">' +
-                                       mw.message( 'postedit-confirmation', mw.user ).escaped() +
-                               '</div>' +
-                               '<a href="#" class="postedit-close">&times;</a>' +
-                       '</div>';
-               id = setTimeout( fadeOutConfirmation, 3000 );
-               div.firstChild.lastChild.onclick = fadeOutConfirmation;
-               document.body.insertBefore( div, document.body.firstChild );
+       function removeConfirmation() {
+               $div.remove();
+               mw.hook( 'postEdit.afterRemoval' ).fire();
        }
 
-       mw.hook( 'postEdit' ).add( showConfirmation ).fire();
+       mw.hook( 'postEdit' ).add( showConfirmation );
+
+       if ( config.wgAction === 'view' && $.cookie( cookieKey ) === '1' ) {
+               $.cookie( cookieKey, null, { path: '/' } );
+               mw.config.set( 'wgPostEdit', true );
+
+               /**
+                * @event postEdit
+                * @member mw.hook
+                * @param {Object} [data]
+                * @param {string|jQuery|Array} [data.message] Message that listeners
+                *  should use when displaying notifications. String for plain text,
+                *  use array or jQuery object to pass actual nodes.
+                * @param {string|mw.user} [data.user=mw.user] User that made the edit.
+                */
+               mw.hook( 'postEdit' ).fire();
+       }
 
 } ( mediaWiki, jQuery ) );