Catrope has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/208323

Change subject: Revert "Get rid over queryMap overrides"
......................................................................

Revert "Get rid over queryMap overrides"

This reverts commit 6f72ea39562aeff94636b81185f099e20d9aa871.

Change-Id: I204dc80a02e7fb220b4fb6cc5e8b058b6c61fe15
---
M modules/engine/components/board/base/flow-board-api-events.js
M modules/engine/components/board/features/flow-board-loadmore.js
M modules/engine/components/board/features/flow-board-toc.js
M modules/engine/components/common/flow-component-events.js
M modules/engine/misc/flow-api.js
5 files changed, 122 insertions(+), 83 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Flow 
refs/changes/23/208323/1

diff --git a/modules/engine/components/board/base/flow-board-api-events.js 
b/modules/engine/components/board/base/flow-board-api-events.js
index a2ea262..e0de540 100644
--- a/modules/engine/components/board/base/flow-board-api-events.js
+++ b/modules/engine/components/board/base/flow-board-api-events.js
@@ -34,11 +34,9 @@
         * real editor can be anything, depending on the type of editor)
         *
         * @param {Event} event
-        * @param {Object} info
-        * @param {Object} queryMap
         * @return {Object}
         */
-       
FlowBoardComponentApiEventsMixin.UI.events.globalApiPreHandlers.prepareEditor = 
function ( event, info, queryMap ) {
+       
FlowBoardComponentApiEventsMixin.UI.events.globalApiPreHandlers.prepareEditor = 
function ( event ) {
                var $textareas = $( this ).closest( 'form' ).find( 'textarea' ),
                        override = {};
 
@@ -61,7 +59,7 @@
                        // add its own nodes, which may be picked up by 
serializeArray()
                } );
 
-               return $.extend( {}, queryMap, override );
+               return override;
        };
 
        /**
@@ -70,16 +68,14 @@
         * This will prepare the data-to-be-submitted so that the override is
         * submitted against the most current revision ID.
         * @param {Event} event
-        * @param {Object} info
-        * @param {Object} queryMap
         * @return {Object}
         */
-       
FlowBoardComponentApiEventsMixin.UI.events.globalApiPreHandlers.prepareEditConflict
 = function ( event, info, queryMap ) {
+       
FlowBoardComponentApiEventsMixin.UI.events.globalApiPreHandlers.prepareEditConflict
 = function ( event ) {
                var $form = $( this ).closest( 'form' ),
                        prevRevisionId = $form.data( 'flow-prev-revision' );
 
                if ( !prevRevisionId ) {
-                       return queryMap;
+                       return {};
                }
 
                // Get rid of the temp-saved new revision ID
@@ -91,78 +87,71 @@
                 * be properly applied for the respective API call; e.g.
                 * epprev_revision (for edit post)
                 */
-               return $.extend( {}, queryMap, {
+               return {
                        flow_prev_revision: prevRevisionId
-               } );
+               };
        };
 
        /**
         * Before activating header, sends an overrideObject to the API to 
modify the request params.
         * @param {Event} event
-        * @param {Object} info
-        * @param {Object} queryMap
         * @return {Object}
         */
-       
FlowBoardComponentApiEventsMixin.UI.events.apiPreHandlers.activateEditHeader = 
function ( event, info, queryMap ) {
-               return $.extend( {}, queryMap, {
+       
FlowBoardComponentApiEventsMixin.UI.events.apiPreHandlers.activateEditHeader = 
function () {
+               return {
                        submodule: 'view-header', // href submodule is 
edit-header
                        vhformat: mw.flow.editor.getFormat() // href does not 
have this param
-               } );
+               };
        };
 
        /**
         * Before activating topic, sends an overrideObject to the API to 
modify the request params.
         *
         * @param {Event} event
-        * @param {Object} info
-        * @param {Object} queryMap
         * @return {Object}
         */
-       
FlowBoardComponentApiEventsMixin.UI.events.apiPreHandlers.activateEditTitle = 
function ( event, info, queryMap ) {
+       
FlowBoardComponentApiEventsMixin.UI.events.apiPreHandlers.activateEditTitle = 
function ( event ) {
                // Use view-post API for topic as well; we only want this on
                // particular (title) post revision, not the full topic
-               return $.extend( {}, queryMap, {
+               return {
                        submodule: "view-post",
                        vppostId: $( this ).closest( '.flow-topic' ).data( 
'flow-id' ),
                        vpformat: mw.flow.editor.getFormat()
-               } );
+               };
        };
 
        /**
         * Before activating post, sends an overrideObject to the API to modify 
the request params.
         * @param {Event} event
-        * @param {Object} info
-        * @param {Object} queryMap
         * @return {Object}
         */
-       
FlowBoardComponentApiEventsMixin.UI.events.apiPreHandlers.activateEditPost = 
function ( event, info, queryMap ) {
-               return $.extend( {}, queryMap, {
+       
FlowBoardComponentApiEventsMixin.UI.events.apiPreHandlers.activateEditPost = 
function ( event ) {
+               return {
                        submodule: 'view-post',
                        vppostId: $( this ).closest( '.flow-post' ).data( 
'flow-id' ),
                        vpformat: mw.flow.editor.getFormat()
-               } );
+               };
        };
 
        /**
         * Adjusts query params to use global watch action, and specifies it 
should use a watch token.
         * @param {Event} event
-        * @param {Object} info
-        * @param {Object} queryMap
-        * @returns {Object}
+        * @returns {Function}
         */
-       FlowBoardComponentApiEventsMixin.UI.events.apiPreHandlers.watchItem = 
function ( event, info, queryMap ) {
-               var params = {
-                       action: 'watch',
-                       titles: queryMap.page,
-                       _internal: {
-                               tokenType: 'watch'
+       FlowBoardComponentApiEventsMixin.UI.events.apiPreHandlers.watchItem = 
function ( event ) {
+               return function ( queryMap ) {
+                       var params = {
+                               action: 'watch',
+                               titles: queryMap.page,
+                               _internal: {
+                                       tokenType: 'watch'
+                               }
+                       };
+                       if ( queryMap.submodule === 'unwatch' ) {
+                               params.unwatch = 1;
                        }
+                       return params;
                };
-               if ( queryMap.submodule === 'unwatch' ) {
-                       params.unwatch = 1;
-               }
-
-               return params;
        };
 
        /**
@@ -170,10 +159,9 @@
         * API to modify the request params.
         * @param {Event} event
         * @param {Object} info
-        * @param {Object} queryMap
         * @return {Object}
         */
-       
FlowBoardComponentApiEventsMixin.UI.events.apiPreHandlers.activateSummarizeTopic
 = function ( event, info, queryMap ) {
+       
FlowBoardComponentApiEventsMixin.UI.events.apiPreHandlers.activateSummarizeTopic
 = function ( event, info ) {
                if ( info.$target.find( 'form' ).length ) {
                        // Form already open; cancel the old form
                        var flowBoard = mw.flow.getPrototypeMethod( 'board', 
'getInstanceByElement' )( $( this ) );
@@ -181,31 +169,29 @@
                        return false;
                }
 
-               return $.extend( {}, queryMap, {
+               return {
                        // href submodule is edit-topic-summary
                        submodule: 'view-topic-summary',
                        // href does not have this param
                        vtsformat: mw.flow.editor.getFormat()
-               } );
+               };
        };
 
        /**
         * Before activating lock/unlock edit form, sends an overrideObject
         * to the API to modify the request params.
         * @param {Event} event
-        * @param {Object} info
-        * @param {Object} queryMap
         * @return {Object}
         */
-       
FlowBoardComponentApiEventsMixin.UI.events.apiPreHandlers.activateLockTopic = 
function ( event, info, queryMap ) {
-               return $.extend( {}, queryMap, {
+       
FlowBoardComponentApiEventsMixin.UI.events.apiPreHandlers.activateLockTopic = 
function ( event ) {
+               return {
                        // href submodule is lock-topic
                        submodule: 'view-post',
                        // href does not have this param
                        vpformat: 'wikitext',
                        // request just the data for this topic
                        vppostId: $( this ).data( 'flow-id' )
-               } );
+               };
        };
 
        //
diff --git a/modules/engine/components/board/features/flow-board-loadmore.js 
b/modules/engine/components/board/features/flow-board-loadmore.js
index c08c0f8..c7024a5 100644
--- a/modules/engine/components/board/features/flow-board-loadmore.js
+++ b/modules/engine/components/board/features/flow-board-loadmore.js
@@ -159,10 +159,9 @@
         * @param {Event} event
         * @param {Object} info
         * @param {jQuery} info.$target
-        * @param {object} queryMap
         * @param {FlowBoardComponent} info.component
         */
-       function flowBoardComponentLoadMoreFeatureBoardApiPreHandler( event, 
info, queryMap ) {
+       function flowBoardComponentLoadMoreFeatureBoardApiPreHandler( event, 
info ) {
                // Backup the topic data
                info.component.renderedTopicsBackup = 
info.component.renderedTopics;
                info.component.topicTitlesByIdBackup = 
info.component.topicTitlesById;
diff --git a/modules/engine/components/board/features/flow-board-toc.js 
b/modules/engine/components/board/features/flow-board-toc.js
index c9019dc..4d64730 100644
--- a/modules/engine/components/board/features/flow-board-toc.js
+++ b/modules/engine/components/board/features/flow-board-toc.js
@@ -38,10 +38,9 @@
         * @param {Event} event
         * @param {Object} info
         * @param {jQuery} info.$target
-        * @param {object} queryMap
         * @param {FlowBoardComponent} info.component
         */
-       function flowBoardComponentTocFeatureMixinBoardApiPreHandler( event, 
info, queryMap ) {
+       function flowBoardComponentTocFeatureMixinBoardApiPreHandler( event, 
info ) {
                info.component.topicIdsInTocBackup = 
info.component.topicIdsInToc;
                info.component.lastTopicIdInTocBackup = 
info.component.lastTopicIdInToc;
 
@@ -61,10 +60,9 @@
         * @param {Event} event
         * @param {Object} info
         * @param {jQuery} info.$target
-        * @param {object} queryMap
         * @param {FlowBoardComponent} info.component
         */
-       function flowBoardComponentTocFeatureMixinTopicListApiPreHandler( 
event, info, queryMap, extraParameters ) {
+       function flowBoardComponentTocFeatureMixinTopicListApiPreHandler( 
event, info, extraParameters ) {
                var $this = $( this ),
                        isLoadMoreButton = $this.data( 'flow-load-handler' ) 
=== 'loadMore',
                        overrides;
@@ -101,7 +99,7 @@
                        delete overrides.topiclist_sortby;
                }
 
-               return $.extend( {}, queryMap, overrides );
+               return overrides;
        }
        FlowBoardComponentTocFeatureMixin.UI.events.apiPreHandlers.topicList = 
flowBoardComponentTocFeatureMixinTopicListApiPreHandler;
 
diff --git a/modules/engine/components/common/flow-component-events.js 
b/modules/engine/components/common/flow-component-events.js
index 226fbd4..8a20709 100644
--- a/modules/engine/components/common/flow-component-events.js
+++ b/modules/engine/components/common/flow-component-events.js
@@ -265,13 +265,13 @@
                        flowComponent = mw.flow.getPrototypeMethod( 
'component', 'getInstanceByElement' )( $this ),
                        dataParams = $this.data(),
                        handlerName = dataParams.flowApiHandler,
+                       preHandlerReturns = [],
                        info = {
                                $target: null,
                                status: null,
                                component: flowComponent
                        },
-                       args = Array.prototype.slice.call( arguments, 0 ),
-                       queryMap = flowComponent.Api.getQueryMap( self.href || 
self );
+                       args = Array.prototype.slice.call( arguments, 0 );
 
                event.preventDefault();
 
@@ -285,10 +285,8 @@
                        $target = $this;
                }
 
-               // insert queryMap & info into args for prehandler
                info.$target = $target;
-               args.splice( 1, 0, info );
-               args.splice( 2, 0, queryMap );
+               args.splice( 1, 0, info ); // insert info into args for 
prehandler
 
                // Make sure an API call is not already in progress for this 
target
                if ( $target.closest( '.flow-api-inprogress' ).length ) {
@@ -303,7 +301,7 @@
                // Let generic pre-handler take care of edit conflicts
                $.each( flowComponent.UI.events.globalApiPreHandlers, function( 
key, callbackArray ) {
                        $.each( callbackArray, function ( i, callbackFn ) {
-                               queryMap = callbackFn.apply( self, args );
+                               preHandlerReturns.push( callbackFn.apply( self, 
args ) );
                        } );
                } );
 
@@ -315,18 +313,15 @@
                if ( flowComponent.UI.events.apiPreHandlers[ handlerName ] ) {
                        // apiPreHandlers can return FALSE to prevent 
processing,
                        // nothing at all to proceed,
-                       // or new queryMap (= API params)
+                       // or OBJECT to add param overrides to the API
+                       // or FUNCTION to modify API params
                        $.each( flowComponent.UI.events.apiPreHandlers[ 
handlerName ], function ( i, callbackFn ) {
-                               // make sure queryMap is up to date (may have 
been altered by
-                               // previous preHandler)
-                               args.splice( 2, 1, queryMap );
                                preHandlerReturn = callbackFn.apply( self, args 
);
+                               preHandlerReturns.push( preHandlerReturn );
 
                                if ( preHandlerReturn === false ) {
                                        // Callback returned false; break out 
of this loop
                                        return false;
-                               } else {
-                                       queryMap = preHandlerReturn;
                                }
                        } );
 
@@ -335,7 +330,7 @@
                                flowComponent.debug( false, 'apiPreHandler 
returned false', handlerName, args );
 
                                // Abort any old request in flight; this is 
normally done automatically by requestFromNode
-                               flowComponent.Api.abortOldRequestFromNode( 
self, queryMap, null );
+                               flowComponent.Api.abortOldRequestFromNode( 
self, null, null, preHandlerReturns );
 
                                // @todo support for multiple indicators on 
same target
                                $target.removeClass( 'flow-api-inprogress' );
@@ -346,7 +341,7 @@
                }
 
                // Make the request
-               $deferred = flowComponent.Api.requestFromNode( self, queryMap );
+               $deferred = flowComponent.Api.requestFromNode( self, 
preHandlerReturns );
                if ( !$deferred ) {
                        mw.flow.debug( '[FlowApi] [interactiveHandlers] 
apiRequest element is not anchor or form element' );
                        $deferred = $.Deferred();
diff --git a/modules/engine/misc/flow-api.js b/modules/engine/misc/flow-api.js
index 1949950..d01c6ee 100644
--- a/modules/engine/misc/flow-api.js
+++ b/modules/engine/misc/flow-api.js
@@ -155,12 +155,39 @@
        FlowApi.prototype.setDefaultSubmodule = flowApiSetDefaultSubmodule;
 
        /**
+        * Overrides (values of) queryMap with a provided override, which can 
come
+        * in the form of an object (which the queryMap will be extended with) 
or as
+        * a function (whose return value will replace queryMap)
+        *
+        * @param {Object} [queryMap]
+        * @param {Function|Object} [override]
+        * @returns {Object}
+        */
+       function flowOverrideQueryMap( queryMap, override ) {
+               if ( override ) {
+                       switch ( typeof override ) {
+                               // If given an override object, extend our 
queryMap with it
+                               case 'object':
+                                       $.extend( queryMap, override );
+                                       break;
+                               // If given an override function, call it and 
make it return the new queryMap
+                               case 'function':
+                                       queryMap = override( queryMap );
+                                       break;
+                       }
+               }
+
+               return queryMap;
+       }
+
+       /**
         * With a url (a://b.c/d?e=f&g#h) will return an object of key-value 
pairs ({e:'f', g:''}).
         * @param {String|Element} url
         * @param {Object} [queryMap]
+        * @param {Array<(Function|Object)>} [overrides]
         * @returns {Object}
         */
-       function flowApiGetQueryMap( url, queryMap ) {
+       function flowApiGetQueryMap( url, queryMap, overrides ) {
                var uri,
                        queryKey,
                        queryValue,
@@ -168,6 +195,7 @@
                        $node, $form, formData;
 
                queryMap = queryMap || {};
+               overrides = overrides || [];
 
                // If URL is an Element...
                if ( typeof url !== 'string' ) {
@@ -233,6 +261,11 @@
                // Default action is flow
                queryMap.action = queryMap.action || 'flow';
 
+               // Override the automatically generated queryMap
+               for ( i = 0; i < overrides.length; i++ ) {
+                       queryMap = flowOverrideQueryMap( queryMap, overrides[i] 
);
+               }
+
                // Use the API map to transform this data if necessary, eg.
                queryMap = flowApiTransformMap( queryMap );
 
@@ -245,13 +278,24 @@
         * Using a given form, parses its action, serializes the data, and 
sends it as GET or POST depending on form method.
         * With button, its name=value is serialized in. If button is an Event, 
it will attempt to find the clicked button.
         * Additional params can be set with data-flow-api-params on both the 
clicked button or the form.
-        * @param {Event|Element} button
-        * @param {Object} queryMap
+        * @param {Event|Element} [button]
+        * @param {Array<(Function|Object)>} [overrides]
         * @return {$.Deferred}
         */
-       function flowApiRequestFromForm( button, queryMap ) {
-               var $button = $( button ),
-                       method = $button.closest( 'form' ).attr( 'method' ) || 
'GET';
+       function flowApiRequestFromForm( button, overrides ) {
+               var $deferred = $.Deferred(),
+                       $button = $( button ),
+                       method = $button.closest( 'form' ).attr( 'method' ) || 
'GET',
+                       queryMap;
+
+               // Parse the form action to get the rest of the queryMap
+               if ( !( queryMap = this.getQueryMap( button, null, overrides ) 
) ) {
+                       return $deferred.rejectWith( { error: 'Invalid form 
action' } );
+               }
+
+               if ( !( queryMap.action ) ) {
+                       return $deferred.rejectWith( { error: 'Unknown action 
for form' } );
+               }
 
                // Cancel any old form request, and also trigger a new one
                return this.abortOldRequestFromNode( $button, queryMap, method 
);
@@ -263,12 +307,20 @@
         * Using a given anchor, parses its URL and sends it as a GET (default) 
or POST depending on data-flow-api-method.
         * Additional params can be set with data-flow-api-params.
         * @param {Element} anchor
-        * @param {Object} queryMap
+        * @param {Array<(Function|Object)>} [overrides]
         * @return {$.Deferred}
         */
-       function flowApiRequestFromAnchor( anchor, queryMap ) {
+       function flowApiRequestFromAnchor( anchor, overrides ) {
                var $anchor = $( anchor ),
+                       $deferred = $.Deferred(),
+                       queryMap,
                        method = $anchor.data( 'flow-api-method' ) || 'GET';
+
+               // Build the query map from this anchor's HREF
+               if ( !( queryMap = this.getQueryMap( anchor.href, null, 
overrides ) ) ) {
+                       mw.flow.debug( '[FlowApi] requestFromAnchor error: 
invalid href', arguments );
+                       return $deferred.rejectWith( { error: 'Invalid href' } 
);
+               }
 
                // Abort any old requests, and have it issue a new one via GET 
or POST
                return this.abortOldRequestFromNode( $anchor, queryMap, method 
);
@@ -279,10 +331,10 @@
        /**
         * Automatically calls requestFromAnchor or requestFromForm depending 
on the type of node given.
         * @param {Element} node
-        * @param {Object} queryMap
-        * @return {$.Deferred}
+        * @param {Array<(Function|Object)>} [overrides]
+        * @return {$.Deferred|bool}
         */
-       function flowApiRequestFromNode( node, queryMap ) {
+       function flowApiRequestFromNode( node, overrides ) {
                var $node = $( node );
 
                if ( $node.is( 'a' ) ) {
@@ -290,7 +342,7 @@
                } else if ( $node.is( 'form, input, button, textarea, select, 
option' ) ) {
                        return this.requestFromForm.apply( this, arguments );
                } else {
-                       return $.Deferred().reject();
+                       return false;
                }
        }
 
@@ -300,13 +352,22 @@
         * Handles aborting an old in-flight API request.
         * If startNewMethod is given, this method also STARTS a new API call 
and stores it for later abortion if needed.
         * @param {jQuery|Element} $node
-        * @param {Object} queryMap
+        * @param {Object} [queryMap]
         * @param {String} [startNewMethod] If given: starts, stores, and 
returns a new API call
+        * @param {Array<(Function|Object)>} [overrides]
         * @return {undefined|$.Deferred}
         */
-       function flowApiAbortOldRequestFromNode( $node, queryMap, 
startNewMethod ) {
+       function flowApiAbortOldRequestFromNode( $node, queryMap, 
startNewMethod, overrides ) {
                $node = $( $node );
 
+               if ( !queryMap ) {
+                       // Get the queryMap automatically if one wasn't given
+                       if ( !( queryMap = this.getQueryMap( $node, null, 
overrides ) ) ) {
+                               mw.flow.debug( '[FlowApi] 
abortOldRequestFromNode failed to find a queryMap', arguments );
+                               return;
+                       }
+               }
+
                // If this anchor already has a request in flight, abort it
                var str = 'flow-api-query-temp-' + queryMap.action + '-' + 
queryMap.submodule,
                        prevApiCall = $node.data( str ),

-- 
To view, visit https://gerrit.wikimedia.org/r/208323
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I204dc80a02e7fb220b4fb6cc5e8b058b6c61fe15
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Flow
Gerrit-Branch: master
Gerrit-Owner: Catrope <roan.katt...@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to