Aude has uploaded a new change for review. https://gerrit.wikimedia.org/r/115191
Change subject: Remove the toolbar controller's own event system ...................................................................... Remove the toolbar controller's own event system The toolbar controller has an own event system which is complex, extremely slow and not used. For me, this change reduces loading time of the Italy item from ~170s to ~18s. Also, there were several bugs in this implementation. Event handlers were called multiple times and the filtering on selector did not work at all. Bug: 61850 Change-Id: Idb6432e6857069058d4e6fe519ebbc31c883acf2 (cherry picked from commit 5a7d4489ff30da010fd7a24fa7d7d042475cea47) --- M lib/resources/jquery.wikibase/toolbar/toolbarcontroller.js 1 file changed, 9 insertions(+), 156 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase refs/changes/91/115191/1 diff --git a/lib/resources/jquery.wikibase/toolbar/toolbarcontroller.js b/lib/resources/jquery.wikibase/toolbar/toolbarcontroller.js index 96643eb..514a9e9 100644 --- a/lib/resources/jquery.wikibase/toolbar/toolbarcontroller.js +++ b/lib/resources/jquery.wikibase/toolbar/toolbarcontroller.js @@ -56,11 +56,6 @@ }, /** - * @type {Object} - */ - _registeredEventHandlers: {}, - - /** * @see jQuery.Widget._create * * @throws {Error} in case a given toolbar ID is not registered for the toolbar type given. @@ -94,151 +89,27 @@ * for a toolbar type with a specific id: For one toolbar, no additional * handler should be registered with exactly the same eventNames string. * @param {Function} callback - * @param {boolean} [replace] If true, the event handler currently registered for the - * specified argument combination will be replaced. * * @throws {Error} if the callback provided in an event definition is not a function. */ - registerEventHandler: function( toolbarType, toolbarId, eventNames, callback, replace ) { + registerEventHandler: function( toolbarType, toolbarId, eventNames, callback ) { if( !$.isFunction( callback ) ) { throw new Error( 'No callback or known default action given for event "' + eventNames + '"' ); } - if( !this._registeredEventHandlers[toolbarType] ) { - this._registeredEventHandlers[toolbarType] = {}; - } - - if( !this._registeredEventHandlers[toolbarType][toolbarId] ) { - this._registeredEventHandlers[toolbarType][toolbarId] = {}; - } - - if( !replace && this._registeredEventHandlers[toolbarType][toolbarId][eventNames] ) { - return; - } - var self = this; + var def = $.wikibase.toolbarcontroller.definition( toolbarType, toolbarId ); - // The namespace needs to be very specific since instances of the the same - // toolbar may listen to the same event(s) on the same node: - var eventNamespaces = [this.widgetName, this.widgetName + toolbarType + toolbarId], - namespacedEventNames = assignNamespaces( eventNames, eventNamespaces ); + this.element.on( eventNames, def.selector, function( event ) { + event.data = event.data || {}; + event.data.toolbar = { + id: toolbarId, + type: toolbarType + }; - this.element - // Prevent attaching event handlers twice: - .off( namespacedEventNames ) - .on( namespacedEventNames, function( event ) { - var callbacks = self._findCallbacks( event ); - - if( callbacks ) { - event.data = event.data || {}; - - event.data.toolbar = { - id: toolbarId, - type: toolbarType - }; - - for( var i = 0; i < callbacks.length; i++ ) { - callbacks[i]( event, self ); - } - } + callback( event, self ); } ); - - this._registeredEventHandlers[toolbarType][toolbarId][eventNames] = callback; - }, - - /** - * Deregister an event handler for certain events and removes the actual event handler - * registration from the toolbar controller's node if the event is not referenced by - * remaining handlers. - * @since 0.5 - * - * @param {string} toolbarType - * @param {string} toolbarId - * @param {string} eventNames It is assumed that the specified eventNames string is exactly - * the same as the one specified when registering a handler. - * - * @throws {Error} if no event handler is registered for the specified set of arguments. - */ - deregisterEventHandler: function( toolbarType, toolbarId, eventNames ) { - if( - !this._registeredEventHandlers[toolbarType] - || !this._registeredEventHandlers[toolbarType][toolbarId] - || !this._registeredEventHandlers[toolbarType][toolbarId][eventNames] - ) { - throw new Error( 'No event handler registered for event names "' + eventNames + '" ' - + ' on ' + toolbarType + ' with id ' + toolbarId ); - } - - // Remove handler from registered event handler cache: - delete this._registeredEventHandlers[toolbarType][toolbarId][eventNames]; - - // Check each single event name if is not not used by another callback: - var registeredHandlers = this._registeredEventHandlers[toolbarType][toolbarId], - eventNamesToRemove = eventNames.split( ' ' ); - - $.each( registeredHandlers, function( regEventNames, c ) { - var regSingleEventNames = regEventNames.split( ' ' ); - - eventNamesToRemove = $.grep( eventNamesToRemove, function( eventName ) { - return ( $.inArray( eventName, regSingleEventNames ) === -1 ); - } ); - - if( !eventNamesToRemove.length ) { - // No event names to remove left. - return false; - } - } ); - - if( !eventNamesToRemove.length ) { - // All events whose handlers shall be removed are still referenced by other - // handlers. - return; - } - - var eventNamespaces = [this.widgetName, this.widgetName + toolbarType + toolbarId], - namespacedEventNamesToRemove = assignNamespaces( - eventNamesToRemove.join( ' ' ), eventNamespaces - ); - - this.element.off( namespacedEventNamesToRemove ); - }, - - /** - * Finds the event handler callback(s) for a certain event. - * @since 0.5 - * - * @param {jQuery.Event} event - * @return {Function[]|null} - */ - _findCallbacks: function( event ) { - var self = this, - $target = $( event.target ), - callbacks = []; - - $.each( TOOLBAR_TYPES, function( i, type ) { - $.each( self.options[type], function( j, id ) { - var def = $.wikibase.toolbarcontroller.definition( type, id ); - - if( - !self._registeredEventHandlers[type] - || !self._registeredEventHandlers[type][id] - ) { - return true; - } - - $.each( self._registeredEventHandlers[type][id], function( eventNames, c ) { - var eventNameMatch = $.inArray( event.type, eventNames.split( ' ' ) ) !== -1, - selectorMatch = self.element.find( def.selector ).has( $target ); - - if( eventNameMatch && selectorMatch ) { - callbacks.push( c ); - } - } ); - } ); - } ); - - return ( callbacks.length ) ? callbacks : null; }, /** @@ -258,22 +129,4 @@ } } ); - - /** - * Assigns namespaces to event names passed in as a string. - * @since 0.4 - * - * @param {string} eventNames - * @param {string[]} namespaces - * @return {string} - */ - function assignNamespaces( eventNames, namespaces ) { - eventNames = eventNames.split( ' ' ); - - // Add an empty string to assign namespaces to the last non-empty event name via join(): - eventNames.push( '' ); - - return eventNames.join( '.' + namespaces.join( '.' ) + ' ' ); - } - }( jQuery ) ); -- To view, visit https://gerrit.wikimedia.org/r/115191 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Idb6432e6857069058d4e6fe519ebbc31c883acf2 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Wikibase Gerrit-Branch: mw1.23-wmf15 Gerrit-Owner: Aude <aude.w...@gmail.com> Gerrit-Reviewer: Adrian Lang <adrian.l...@wikimedia.de> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits