Page MenuHomePhabricator

Don’t use entityLoaded hook in LexemeHeader
Open, Stalled, Needs TriagePublic

Description

The LexemeHeader currently initializes itself from the data of the wikibase.entityPage.entityLoaded hook:

$.Deferred( function ( deferred ) {
    mw.hook( 'wikibase.entityPage.entityLoaded' ).add( function ( wbEntity ) {
        deferred.resolve( hydrateLexeme( wbEntity ) );
    } );
} )
    .then( init )
    .fail( function ( reason ) {
        // FIXME: Change to lexeme-extension-specific logger once defined                                                                                                             
        mw.log.error( 'LexemeHeader could not be initialized from wikibase.entityPage.entityLoaded', reason );
    } )
;

This makes it depend on global state and also delays its initialization so that, as @Nikki reports, it sometimes completes only after the wikibase.entityPage.entityView.rendered hook has fired, which means that gadgets and user scripts can’t reliably manipulate the lexeme header.

As far as I can tell, this is completely unnecessary. At the point where its initialization is hooked up, in ControllerViewFactory

SELF.prototype.getEntityView = function ( startEditingCallback, lexeme, $entityview ) {
    return this._getView(
        'lexemeview',
        $entityview,
        {
            buildEntityTermsView: this.getEntityTermsView.bind( this, startEditingCallback ),
            buildSitelinkGroupListView: this.getSitelinkGroupListView.bind( this, startEditingCallback ),
            buildStatementGroupListView: this.getStatementGroupListView.bind( this, startEditingCallback ),
            buildFormListView: this.getFormListView.bind( this, lexeme, startEditingCallback ),
            buildSenseListView: this.getSenseListView.bind( this, lexeme, startEditingCallback ),
            buildLexemeHeader: wb.lexeme.widgets.buildLexemeHeader,
            value: lexeme
        }
    );
};

…we already have the lexeme available for the form and sense list views, so I don’t see why we couldn’t use the same data to build the lexeme header, without waiting for the entityLoaded hook to fire.

Event Timeline

Sadly, this is not as easy as it looks… in ControllerViewFactory, the lexeme is a wikibase.lexeme.datamodel.Lexeme object; in LexemeHeader, it’s at first the entity JSON serialization, which is then “hydrated” into some other format (undocumented AFAICT) before being passed into newLexemeHeaderStore, where it is again transformed into another, slightly different format (ditto) and finally stored in Vuex. According to ADR 0002, that Vuex store is the way of the future, but unfortunately, as far as I can tell, we can’t convert a datamodel Lexeme object into this store format (whatever it looks like) because the store format has language and lexical category, and the datamodel Lexeme doesn’t have those.

I guess this will have to wait for us to migrate more components to the Vuex store model… :/

Lydia_Pintscher changed the task status from Open to Stalled.Jan 4 2019, 10:49 AM
Lydia_Pintscher subscribed.

Marking as stalled then.

I guess this will have to wait for us to migrate more components to the Vuex store model… :/

@Lucas_Werkmeister_WMDE / @Lydia_Pintscher : 27 months later, has that happened in the meantime maybe?
If not, what are the IDs of tasks tracking that store model migration that this task should depend on?

As far as I’m aware, nothing significant has happened towards unstalling this task.

I also happened to attend VueConf Toronto last week, and there the general impression was that Vuex should mostly not be used anymore, because it’s better to use the new Vue 3 composition API. So we might need a new ADR for WikibaseLexeme, not sure.