jenkins-bot has submitted this change and it was merged.

Change subject: Introduce StructureEditorFactory
......................................................................


Introduce StructureEditorFactory

Change-Id: I6f934845058d7a376a7b87a99ad08d5d9de24dcf
---
M repo/resources/Resources.php
M repo/resources/wikibase.ui.entityViewInit.js
M view/resources/wikibase/view/ControllerViewFactory.js
A view/resources/wikibase/view/StructureEditorFactory.js
M view/resources/wikibase/view/ToolbarFactory.js
M view/resources/wikibase/view/ToolbarViewController.js
M view/resources/wikibase/view/ViewFactory.js
M view/resources/wikibase/view/resources.php
M view/tests/qunit/wikibase/view/ToolbarViewController.tests.js
M view/tests/qunit/wikibase/view/ViewFactory.tests.js
10 files changed, 199 insertions(+), 61 deletions(-)

Approvals:
  Jonas Kress (WMDE): Looks good to me, approved
  Thiemo Mättig (WMDE): Looks good to me, but someone else must approve
  jenkins-bot: Verified



diff --git a/repo/resources/Resources.php b/repo/resources/Resources.php
index 97a10d4..c49854c 100644
--- a/repo/resources/Resources.php
+++ b/repo/resources/Resources.php
@@ -111,6 +111,7 @@
                                'wikibase.store.CachingEntityStore',
                                'wikibase.store.CombiningEntityStore',
                                'wikibase.view.ControllerViewFactory',
+                               'wikibase.view.StructureEditorFactory',
                                'wikibase.view.ToolbarFactory',
                                'wikibase.WikibaseContentLanguages'
                        ),
diff --git a/repo/resources/wikibase.ui.entityViewInit.js 
b/repo/resources/wikibase.ui.entityViewInit.js
index c91611e..12222f1 100644
--- a/repo/resources/wikibase.ui.entityViewInit.js
+++ b/repo/resources/wikibase.ui.entityViewInit.js
@@ -113,8 +113,11 @@
                        htmlDataValueEntityIdFormatter = 
formatterFactory.getFormatter( null, null, 'text/html' ),
                        plaintextDataValueEntityIdFormatter = 
formatterFactory.getFormatter( null, null, 'text/plain' ),
                        entityIdParser = new ( parserStore.getParser( 
wb.datamodel.EntityId.TYPE ) )( { lang: userLanguages[0] } ),
+                       toolbarFactory = new wb.view.ToolbarFactory(),
+                       structureEditorFactory = new 
wb.view.StructureEditorFactory( toolbarFactory ),
                        viewFactoryClass = wb.view.ViewFactory,
                        viewFactoryArguments = [
+                               structureEditorFactory,
                                contentLanguages,
                                dataTypeStore,
                                new 
wb.entityIdFormatter.CachingEntityIdHtmlFormatter(
@@ -134,7 +137,10 @@
                                parserStore,
                                userLanguages,
                                repoApiUrl
-                       ];
+                       ],
+                       startEditingCallback = function() {
+                               return $.Deferred().resolve().promise();
+                       };
 
                if ( isEditable() ) {
                        viewFactoryClass = wb.view.ControllerViewFactory;
@@ -146,7 +152,7 @@
 
                viewFactoryArguments.unshift( null );
                var viewFactory = new ( Function.prototype.bind.apply( 
viewFactoryClass, viewFactoryArguments ) );
-               var entityView = viewFactory.getEntityView( entity, $entityview 
);
+               var entityView = viewFactory.getEntityView( 
startEditingCallback, entity, $entityview );
 
                return entityView.widgetName;
        }
diff --git a/view/resources/wikibase/view/ControllerViewFactory.js 
b/view/resources/wikibase/view/ControllerViewFactory.js
index 8de5505..0b51fcd 100644
--- a/view/resources/wikibase/view/ControllerViewFactory.js
+++ b/view/resources/wikibase/view/ControllerViewFactory.js
@@ -12,8 +12,12 @@
        }
 );
 
-SELF.prototype.getEntityTermsView = function( value, $entitytermsview ) {
-       var view = PARENT.prototype.getEntityTermsView.apply( this, arguments );
+SELF.prototype.getEntityTermsView = function( startEditingCallback, value, 
$entitytermsview ) {
+       var controller;
+       var startEditingController = function() {
+               return controller.startEditing();
+       };
+       var view = PARENT.prototype.getEntityTermsView.call( this, 
startEditingController, value, $entitytermsview );
        var $container = this._toolbarFactory.getToolbarContainer( view.element 
);
        $container.sticknode( {
                $container: view.$entitytermsforlanguagelistview,
@@ -67,13 +71,23 @@
        } );
 
        var entityTermsChanger = 
this._entityChangersFactory.getEntityTermsChanger();
-       this._getController( $container, view, entityTermsChanger, null, value 
);
+       controller = this._getController( $container, view, entityTermsChanger, 
null, value, startEditingCallback );
        return view;
 };
 
-SELF.prototype.getStatementView = function( entityId, propertyId, value, $dom 
) {
+SELF.prototype.getStatementView = function( startEditingCallback, entityId, 
propertyId, value, $dom ) {
        var controller;
-       var statementview = PARENT.prototype.getStatementView.apply( this, 
arguments );
+       var startEditingController = function() {
+               return controller.startEditing();
+       };
+       var statementview = PARENT.prototype.getStatementView.call(
+               this,
+               startEditingController,
+               entityId,
+               propertyId,
+               value,
+               $dom
+       );
 
        var removeFromListView = function( statementview ) {
                var $statementlistview = statementview.element.closest( 
':wikibase-statementlistview' ),
@@ -89,7 +103,8 @@
                statementview,
                statementsChanger,
                removeFromListView.bind( null, statementview ),
-               value
+               value,
+               startEditingCallback
        );
 
        if ( !value ) {
@@ -98,20 +113,25 @@
        return statementview;
 };
 
-SELF.prototype.getSitelinkGroupView = function( groupName, value, 
$sitelinkgroupview ) {
-       var view = PARENT.prototype.getSitelinkGroupView.apply( this, arguments 
);
+SELF.prototype.getSitelinkGroupView = function( startEditingCallback, 
groupName, value, $sitelinkgroupview ) {
+       var controller;
+       var startEditingController = function() {
+               return controller.startEditing();
+       };
+       var view = PARENT.prototype.getSitelinkGroupView.call( this, 
startEditingController, groupName, value, $sitelinkgroupview );
        var siteLinkSetsChanger = 
this._entityChangersFactory.getSiteLinkSetsChanger();
-       this._getController(
+       controller = this._getController(
                this._toolbarFactory.getToolbarContainer( view.element.find( 
'.wikibase-sitelinkgroupview-heading-container' ) ),
                view,
                siteLinkSetsChanger,
                null,
-               value
+               value,
+               startEditingCallback
        );
        return view;
 };
 
-SELF.prototype._getController = function( $container, view, model, onRemove, 
value ) {
+SELF.prototype._getController = function( $container, view, model, onRemove, 
value, startEditingCallback ) {
        var edittoolbar = this._toolbarFactory.getEditToolbar(
                {
                        $container: $container,
@@ -120,7 +140,7 @@
                view.element
        );
 
-       var controller = new wb.view.ToolbarViewController( model, edittoolbar, 
view, onRemove );
+       var controller = new wb.view.ToolbarViewController( model, edittoolbar, 
view, onRemove, startEditingCallback );
        edittoolbar.setController( controller );
        controller.setValue( value );
 
diff --git a/view/resources/wikibase/view/StructureEditorFactory.js 
b/view/resources/wikibase/view/StructureEditorFactory.js
new file mode 100644
index 0000000..c36659f
--- /dev/null
+++ b/view/resources/wikibase/view/StructureEditorFactory.js
@@ -0,0 +1,42 @@
+( function( wb ) {
+       'use strict';
+
+       var MODULE = wb.view;
+
+       /**
+        * A factory for creating structure editors
+        *
+        * @class wikibase.view.StructureEditorFactory
+        * @license GPL-2.0+
+        * @since 0.5
+        * @author Adrian Heine <adrian.he...@wikimedia.de>
+        * @constructor
+        */
+       var SELF = MODULE.StructureEditorFactory = function 
StructureEditorFactory( toolbarFactory ) {
+               this._toolbarFactory = toolbarFactory;
+       };
+
+       SELF.prototype.getAdder = function( add, $dom, label ) {
+               var options = { label: label };
+               $dom = this._toolbarFactory.getToolbarContainer( $dom );
+               $dom.on(
+                       'addtoolbaradd.addtoolbar',
+                       function( event ) {
+                               if ( event.target !== $dom.get( 0 ) ) {
+                                       // This is a different toolbar than we 
thought
+                                       return;
+                               }
+                               add();
+                       }
+               );
+               return this._toolbarFactory.getAddToolbar( options, $dom );
+       };
+
+       SELF.prototype.getRemover = function( remove, $dom, title ) {
+               var options = { title: title };
+               $dom = this._toolbarFactory.getToolbarContainer( $dom );
+               $dom.on( 'removetoolbarremove.removetoolbar', remove );
+               return this._toolbarFactory.getRemoveToolbar( options, $dom );
+       };
+
+}( wikibase ) );
diff --git a/view/resources/wikibase/view/ToolbarFactory.js 
b/view/resources/wikibase/view/ToolbarFactory.js
index e9879cd..68edbdb 100644
--- a/view/resources/wikibase/view/ToolbarFactory.js
+++ b/view/resources/wikibase/view/ToolbarFactory.js
@@ -15,6 +15,17 @@
        var SELF = MODULE.ToolbarFactory = function ToolbarFactory() {};
 
        /**
+        * Create a addtoolbar
+        *
+        * @param {Object} options
+        * @param {jQuery} $dom
+        * @return {jQuery.wikibase.addtoolbar} The addtoolbar
+        **/
+       SELF.prototype.getAddToolbar = function( options, $dom ) {
+               return this._getToolbar( 'add', $dom, options );
+       };
+
+       /**
         * Create an edittoolbar
         *
         * @param {Object} options
@@ -26,6 +37,17 @@
        };
 
        /**
+        * Create a removetoolbar
+        *
+        * @param {Object} options
+        * @param {jQuery} $dom
+        * @return {jQuery.wikibase.removetoolbar} The removetoolbar
+        **/
+       SELF.prototype.getRemoveToolbar = function( options, $dom ) {
+               return this._getToolbar( 'remove', $dom, options );
+       };
+
+       /**
         * Find or append a toolbar container
         *
         * @param {jQuery} $root
diff --git a/view/resources/wikibase/view/ToolbarViewController.js 
b/view/resources/wikibase/view/ToolbarViewController.js
index 2015975..c5ce239 100644
--- a/view/resources/wikibase/view/ToolbarViewController.js
+++ b/view/resources/wikibase/view/ToolbarViewController.js
@@ -20,14 +20,16 @@
  * @param {jQuery.wikibase.edittoolbar} toolbar
  * @param {jQuery.ui.EditableTemplatedWidget} view
  * @param {Function} removeView
+ * @param {Function} startEditingCallback
  */
 var SELF = util.inherit(
        wb.view.ViewController,
-       function( model, toolbar, view, removeView ) {
+       function( model, toolbar, view, removeView, startEditingCallback ) {
                this._model = model;
                this._toolbar = toolbar;
                this._view = view;
                this._removeView = removeView;
+               this._startEditingCallback = startEditingCallback;
        }
 );
 
@@ -62,6 +64,12 @@
 SELF.prototype._removeView = null;
 
 /**
+ * @property {Function}
+ * @private
+ */
+SELF.prototype._startEditingCallback = null;
+
+/**
  * @param {Object|null} value A wikibase.datamodel object supporting at least 
an equals method.
  */
 SELF.prototype.setValue = function( value ) {
@@ -86,6 +94,7 @@
                this._view.widgetEventPrefix + 'disable',
                $.proxy( this._updateToolbarState, this )
        );
+       result.done( this._startEditingCallback );
        return result;
 };
 
diff --git a/view/resources/wikibase/view/ViewFactory.js 
b/view/resources/wikibase/view/ViewFactory.js
index f482b01..883359c 100644
--- a/view/resources/wikibase/view/ViewFactory.js
+++ b/view/resources/wikibase/view/ViewFactory.js
@@ -12,6 +12,7 @@
         * @author Adrian Heine <adrian.he...@wikimedia.de>
         * @constructor
         *
+        * @param {wikibase.view.StructureEditorFactory} structureEditorFactory
         * @param {util.ContentLanguages} contentLanguages
         *        Required by the `ValueView` for limiting the list of 
available languages for
         *        particular `jQuery.valueview.Expert` instances like the 
`Expert` responsible
@@ -39,6 +40,7 @@
         * @param {string|null} [vocabularyLookupApiUrl=null]
         */
        var SELF = MODULE.ViewFactory = function ViewFactory(
+               structureEditorFactory,
                contentLanguages,
                dataTypeStore,
                entityIdHtmlFormatter,
@@ -51,6 +53,7 @@
                userLanguages,
                vocabularyLookupApiUrl
        ) {
+               this._structureEditorFactory = structureEditorFactory;
                this._contentLanguages = contentLanguages;
                this._dataTypeStore = dataTypeStore;
                this._entityIdHtmlFormatter = entityIdHtmlFormatter;
@@ -65,6 +68,12 @@
                this._vocabularyLookupApiUrl = vocabularyLookupApiUrl || null;
                this._eventSingletonManager = new 
$.util.EventSingletonManager();
        };
+
+       /**
+        * @property {wikibase.view.StructureEditorFactory}
+        * @private
+        **/
+       SELF.prototype._structureEditorFactory = null;
 
        /**
         * @property {util.ContentLanguages}
@@ -141,20 +150,21 @@
        /**
         * Construct a suitable view for the given entity on the given DOM 
element
         *
+        * @param {Function} startEditingCallback
         * @param {wikibase.datamodel.Entity} entity
         * @param {jQuery} $entityview
         * @return {jQuery.wikibase.entityview} The constructed entity view
         * @throws {Error} If there is no view for the given entity type
         **/
-       SELF.prototype.getEntityView = function( entity, $entityview ) {
+       SELF.prototype.getEntityView = function( startEditingCallback, entity, 
$entityview ) {
                return this._getView(
                        // Typically "itemview" or "propertyview".
                        entity.getType() + 'view',
                        $entityview,
                        {
-                               buildEntityTermsView: $.proxy( 
this.getEntityTermsView, this ),
-                               buildSitelinkGroupListView: $.proxy( 
this.getSitelinkGroupListView, this ),
-                               buildStatementGroupListView: $.proxy( 
this.getStatementGroupListView, this ),
+                               buildEntityTermsView: 
this.getEntityTermsView.bind( this, startEditingCallback ),
+                               buildSitelinkGroupListView: 
this.getSitelinkGroupListView.bind( this, startEditingCallback ),
+                               buildStatementGroupListView: 
this.getStatementGroupListView.bind( this, startEditingCallback ),
                                value: entity
                        }
                );
@@ -163,11 +173,12 @@
        /**
         * Construct a suitable terms view for the given fingerprint on the 
given DOM element
         *
+        * @param {Function} startEditingCallback
         * @param {wikibase.datamodel.Fingerprint} fingerprint
         * @param {jQuery} $entitytermsview
         * @return {jQuery.wikibase.entitytermsview} The constructed entity 
terms view
         **/
-       SELF.prototype.getEntityTermsView = function( fingerprint, 
$entitytermsview ) {
+       SELF.prototype.getEntityTermsView = function( startEditingCallback, 
fingerprint, $entitytermsview ) {
                return this._getView(
                        'entitytermsview',
                        $entitytermsview,
@@ -182,11 +193,12 @@
        /**
         * Construct a suitable view for the given sitelink set on the given 
DOM element
         *
+        * @param {Function} startEditingCallback
         * @param {wikibase.datamodel.SiteLinkSet} sitelinkSet
         * @param {jQuery} $sitelinkgrouplistview
         * @return {jQuery.wikibase.sitelinkgrouplistview} The constructed 
sitelinkgrouplistview
         **/
-       SELF.prototype.getSitelinkGroupListView = function( sitelinkSet, 
$sitelinkgrouplistview ) {
+       SELF.prototype.getSitelinkGroupListView = function( 
startEditingCallback, sitelinkSet, $sitelinkgrouplistview ) {
                var self = this;
 
                return this._getView(
@@ -197,7 +209,7 @@
                                listItemAdapter: new 
$.wikibase.listview.ListItemAdapter( {
                                        listItemWidget: 
$.wikibase.sitelinkgroupview,
                                        getNewItem: function( value, dom ) {
-                                               return 
self.getSitelinkGroupView( value.group, value.siteLinks, $( dom ) );
+                                               return 
self.getSitelinkGroupView( startEditingCallback, value.group, value.siteLinks, 
$( dom ) );
                                        }
                                } )
                        }
@@ -207,19 +219,20 @@
        /**
         * Construct a suitable view for the given sitelink group on the given 
DOM element
         *
+        * @param {Function} startEditingCallback
         * @param {string} groupName
         * @param {wikibase.datamodel.SiteLinkSet} siteLinks
         * @param {jQuery} $sitelinkgroupview
         * @return {jQuery.wikibase.sitelinkgroupview} The constructed 
sitelinkgroupview
         **/
-       SELF.prototype.getSitelinkGroupView = function( groupName, siteLinks, 
$sitelinkgroupview ) {
+       SELF.prototype.getSitelinkGroupView = function( startEditingCallback, 
groupName, siteLinks, $sitelinkgroupview ) {
                return this._getView(
                        'sitelinkgroupview',
                        $sitelinkgroupview,
                        {
                                groupName: groupName,
                                value: siteLinks,
-                               getSiteLinkListView: 
this.getSiteLinkListView.bind( this )
+                               getSiteLinkListView: 
this.getSiteLinkListView.bind( this, startEditingCallback )
                        }
                );
        };
@@ -227,13 +240,14 @@
        /**
         * Construct a suitable view for the given sitelink list on the given 
DOM element
         *
+        * @param {Function} startEditingCallback
         * @param {wikibase.datamodel.SiteLink[]} siteLinks
         * @param {jQuery} $sitelinklistview
         * @param {string[]} allowedSiteIds
         * @param {jQuery} $counter
         * @return {jQuery.wikibase.sitelinklistview} The constructed 
sitelinklistview
         **/
-       SELF.prototype.getSiteLinkListView = function( siteLinks, 
$sitelinklistview, allowedSiteIds, $counter ) {
+       SELF.prototype.getSiteLinkListView = function( startEditingCallback, 
siteLinks, $sitelinklistview, allowedSiteIds, $counter ) {
                return this._getView(
                        'sitelinklistview',
                        $sitelinklistview,
@@ -242,17 +256,18 @@
                                allowedSiteIds: allowedSiteIds,
                                encapsulate: true,
                                eventSingletonManager: 
this._eventSingletonManager,
-                               getListItemAdapter: 
this.getListItemAdapterForSiteLinkView.bind( this ),
+                               getListItemAdapter: 
this.getListItemAdapterForSiteLinkView.bind( this, startEditingCallback ),
                                value: siteLinks
                        }
                );
        };
 
        /**
+        * @param {Function} startEditingCallback
         * @param {Function} getAllowedSites
         * @return {jQuery.wikibase.listview.ListItemAdapter}
         */
-       SELF.prototype.getListItemAdapterForSiteLinkView = function( 
getAllowedSites ) {
+       SELF.prototype.getListItemAdapterForSiteLinkView = function( 
startEditingCallback, getAllowedSites ) {
                var self = this;
                return new $.wikibase.listview.ListItemAdapter( {
                        listItemWidget: $.wikibase.sitelinkview,
@@ -274,11 +289,12 @@
        /**
         * Construct a suitable view for the list of statement groups for the 
given entity on the given DOM element
         *
+        * @param {Function} startEditingCallback
         * @param {wikibase.datamodel.Item|wikibase.datamodel.Property} entity
         * @param {jQuery} $statementgrouplistview
         * @return {jQuery.wikibase.statementgrouplistview} The constructed 
statementgrouplistview
         **/
-       SELF.prototype.getStatementGroupListView = function( entity, 
$statementgrouplistview ) {
+       SELF.prototype.getStatementGroupListView = function( 
startEditingCallback, entity, $statementgrouplistview ) {
                var statementGroupSet = entity.getStatements();
                return this._getView(
                        'statementgrouplistview',
@@ -287,6 +303,7 @@
                                // If we have no HTML to initialize on, pass 
the raw data
                                value: $statementgrouplistview.is( ':empty' ) ? 
statementGroupSet : null,
                                listItemAdapter: 
this.getListItemAdapterForStatementGroupView(
+                                       startEditingCallback,
                                        entity.getId(),
                                        function( guid ) {
                                                var res = null;
@@ -310,18 +327,19 @@
        /**
         * Construct a `ListItemAdapter` for `statementgroupview`s
         *
+        * @param {Function} startEditingCallback
         * @param {string} entityId
         * @param {Function} getStatementForGuid A function returning a 
`wikibase.datamodel.Statement` for a given GUID
         * @return {jQuery.wikibase.listview.ListItemAdapter} The constructed 
ListItemAdapter
         **/
-       SELF.prototype.getListItemAdapterForStatementGroupView = function( 
entityId, getStatementForGuid ) {
+       SELF.prototype.getListItemAdapterForStatementGroupView = function( 
startEditingCallback, entityId, getStatementForGuid ) {
                return new $.wikibase.listview.ListItemAdapter( {
                        listItemWidget: $.wikibase.statementgroupview,
                        newItemOptionsFn: $.proxy( function( value ) {
                                return {
                                        value: value,
                                        entityIdHtmlFormatter: 
this._entityIdHtmlFormatter,
-                                       buildStatementListView: $.proxy( 
this.getStatementListView, this, entityId, value && value.getKey(), 
getStatementForGuid )
+                                       buildStatementListView: $.proxy( 
this.getStatementListView, this, startEditingCallback, entityId, value && 
value.getKey(), getStatementForGuid )
                                };
                        }, this )
                } );
@@ -330,6 +348,7 @@
        /**
         * Construct a suitable view for the given list of statements on the 
given DOM element
         *
+        * @param {Function} startEditingCallback
         * @param {string} entityId
         * @param {string|null} propertyId Optionally specifies a property
         *                                                      all statements 
should be on or are on
@@ -338,7 +357,7 @@
         * @param {jQuery} $statementlistview
         * @return {jQuery.wikibase.statementgroupview} The constructed 
statementlistview
         **/
-       SELF.prototype.getStatementListView = function( entityId, propertyId, 
getStatementForGuid, value, $statementlistview ) {
+       SELF.prototype.getStatementListView = function( startEditingCallback, 
entityId, propertyId, getStatementForGuid, value, $statementlistview ) {
                propertyId = propertyId || $statementlistview.closest( 
'.wikibase-statementgroupview' ).attr( 'id' );
 
                return this._getView(
@@ -347,6 +366,7 @@
                        {
                                value: value.length === 0 ? null : value,
                                listItemAdapter: 
this.getListItemAdapterForStatementView(
+                                       startEditingCallback,
                                        entityId,
                                        function( dom ) {
                                                var guidMatch = 
dom.className.match( /wikibase-statement-(\S+)/ );
@@ -361,25 +381,26 @@
        /**
         * Construct a `ListItemAdapter` for `statementview`s
         *
+        * @param {Function} startEditingCallback
         * @param {string} entityId
         * @param {Function} getValueForDom A function returning a 
`wikibase.datamodel.Statement` or `null`
         *                                  for a given DOM element
         * @param {string|null} [propertyId] Optionally a property all 
statements are or should be on
         * @return {jQuery.wikibase.listview.ListItemAdapter} The constructed 
ListItemAdapter
         **/
-       SELF.prototype.getListItemAdapterForStatementView = function( entityId, 
getValueForDom, propertyId ) {
+       SELF.prototype.getListItemAdapterForStatementView = function( 
startEditingCallback, entityId, getValueForDom, propertyId ) {
                var listItemAdapter = new $.wikibase.listview.ListItemAdapter( {
                        listItemWidget: $.wikibase.statementview,
                        getNewItem: $.proxy( function( value, dom ) {
                                value = value || getValueForDom( dom );
-                               var view = this.getStatementView( entityId, 
propertyId, value, $( dom ) );
+                               var view = this.getStatementView( 
startEditingCallback, entityId, propertyId, value, $( dom ) );
                                return view;
                        }, this )
                } );
                return listItemAdapter;
        };
 
-       SELF.prototype.getStatementView = function( entityId, propertyId, 
value, $dom ) {
+       SELF.prototype.getStatementView = function( startEditingCallback, 
entityId, propertyId, value, $dom ) {
                var currentPropertyId = value ? 
value.getClaim().getMainSnak().getPropertyId() : propertyId;
                var view = this._getView(
                        'statementview',
@@ -397,15 +418,16 @@
                                        }
                                },
 
-                               buildReferenceListItemAdapter: $.proxy( 
this.getListItemAdapterForReferenceView, this ),
+                               buildReferenceListItemAdapter: $.proxy( 
this.getListItemAdapterForReferenceView, this, startEditingCallback ),
                                buildSnakView: $.proxy(
                                        this.getSnakView,
                                        this,
+                                       startEditingCallback,
                                        false
                                ),
                                entityIdPlainFormatter: 
this._entityIdPlainFormatter,
                                guidGenerator: new 
wb.utilities.ClaimGuidGenerator( entityId ),
-                               qualifiersListItemAdapter: 
this.getListItemAdapterForSnakListView()
+                               qualifiersListItemAdapter: 
this.getListItemAdapterForSnakListView( startEditingCallback )
                        }
                );
                return view;
@@ -416,13 +438,13 @@
         *
         * @return {jQuery.wikibase.listview.ListItemAdapter} The constructed 
ListItemAdapter
         */
-       SELF.prototype.getListItemAdapterForReferenceView = function() {
+       SELF.prototype.getListItemAdapterForReferenceView = function( 
startEditingCallback ) {
                return new $.wikibase.listview.ListItemAdapter( {
                        listItemWidget: $.wikibase.referenceview,
                        newItemOptionsFn: $.proxy( function( value ) {
                                return {
                                        value: value || null,
-                                       listItemAdapter: 
this.getListItemAdapterForSnakListView()
+                                       listItemAdapter: 
this.getListItemAdapterForSnakListView( startEditingCallback )
                                };
                        }, this )
                } );
@@ -433,14 +455,14 @@
         *
         * @return {jQuery.wikibase.listview.ListItemAdapter} The constructed 
ListItemAdapter
         */
-       SELF.prototype.getListItemAdapterForSnakListView = function() {
+       SELF.prototype.getListItemAdapterForSnakListView = function( 
startEditingCallback ) {
                return new $.wikibase.listview.ListItemAdapter( {
                        listItemWidget: $.wikibase.snaklistview,
                        newItemOptionsFn: $.proxy( function( value ) {
                                return {
                                        value: value || undefined,
                                        singleProperty: true,
-                                       listItemAdapter: 
this.getListItemAdapterForSnakView()
+                                       listItemAdapter: 
this.getListItemAdapterForSnakView( startEditingCallback )
                                };
                        }, this )
                } );
@@ -451,7 +473,7 @@
         *
         * @return {jQuery.wikibase.listview.ListItemAdapter} The constructed 
ListItemAdapter
         */
-       SELF.prototype.getListItemAdapterForSnakView = function() {
+       SELF.prototype.getListItemAdapterForSnakView = function( 
startEditingCallback ) {
                return new $.wikibase.listview.ListItemAdapter( {
                        listItemWidget: $.wikibase.snakview,
                        newItemOptionsFn: $.proxy( function( value ) {
@@ -475,13 +497,14 @@
        /**
         * Construct a suitable view for the given snak on the given DOM element
         *
+        * @param {Function} startEditingCallback
         * @param {boolean} drawProperty Whether the snakview should draw its 
property
         * @param {Object} options An object with keys `locked` and 
`autoStartEditing`
         * @param {wikibase.datamodel.Snak|null} snak
         * @param {jQuery} $snakview
         * @return {jQuery.wikibase.snakview} The constructed snakview
         */
-       SELF.prototype.getSnakView = function( drawProperty, options, snak, 
$snakview ) {
+       SELF.prototype.getSnakView = function( startEditingCallback, 
drawProperty, options, snak, $snakview ) {
                return this._getView(
                        'snakview',
                        $snakview,
diff --git a/view/resources/wikibase/view/resources.php 
b/view/resources/wikibase/view/resources.php
index 37851a3..7aed023 100644
--- a/view/resources/wikibase/view/resources.php
+++ b/view/resources/wikibase/view/resources.php
@@ -33,10 +33,19 @@
                        )
                ),
 
+               'wikibase.view.StructureEditorFactory' => $moduleTemplate + 
array(
+                       'scripts' => 'StructureEditorFactory.js',
+                       'dependencies' => array(
+                               'wikibase.view.__namespace',
+                       )
+               ),
+
                'wikibase.view.ToolbarFactory' => $moduleTemplate + array(
                        'scripts' => 'ToolbarFactory.js',
                        'dependencies' => array(
+                               'jquery.wikibase.addtoolbar',
                                'jquery.wikibase.edittoolbar',
+                               'jquery.wikibase.removetoolbar',
                                'wikibase.view.__namespace',
                        )
                ),
diff --git a/view/tests/qunit/wikibase/view/ToolbarViewController.tests.js 
b/view/tests/qunit/wikibase/view/ToolbarViewController.tests.js
index 5b75a78..f94ceb3 100644
--- a/view/tests/qunit/wikibase/view/ToolbarViewController.tests.js
+++ b/view/tests/qunit/wikibase/view/ToolbarViewController.tests.js
@@ -34,7 +34,9 @@
                        enable: function() {},
                        isValid: function() {},
                        setError: function() {},
-                       startEditing: function() {},
+                       startEditing: function() {
+                               return $.Deferred();
+                       },
                        stopEditing: function() {},
                        value: function() {}
                },
diff --git a/view/tests/qunit/wikibase/view/ViewFactory.tests.js 
b/view/tests/qunit/wikibase/view/ViewFactory.tests.js
index 4b4be5f..24bc4a4 100644
--- a/view/tests/qunit/wikibase/view/ViewFactory.tests.js
+++ b/view/tests/qunit/wikibase/view/ViewFactory.tests.js
@@ -19,13 +19,13 @@
        QUnit.test( 'getEntityView constructs correct views', function( assert 
) {
                assert.expect( 2 );
                var entityStore = new wb.store.EntityStore(),
-                       viewFactory = new ViewFactory( null, null, null, null, 
entityStore ),
+                       viewFactory = new ViewFactory( null, null, null, null, 
null, entityStore ),
                        fooView = {},
                        $dom = $( '<div/>' ),
                        FooView = $dom.fooview = $.wikibase.fooview = 
sinon.spy();
                $dom.data = sinon.spy( function() { return fooView; } );
 
-               var res = viewFactory.getEntityView( getEntityStub( 'foo' ), 
$dom );
+               var res = viewFactory.getEntityView( null, getEntityStub( 'foo' 
), $dom );
 
                assert.strictEqual( res, fooView );
                sinon.assert.calledOnce( FooView );
@@ -34,11 +34,11 @@
        QUnit.test( 'getEntityView throws on incorrect views', function( assert 
) {
                assert.expect( 1 );
                var entityStore = new wb.store.EntityStore(),
-                       viewFactory = new ViewFactory( null, null, null, null, 
entityStore );
+                       viewFactory = new ViewFactory( null, null, null, null, 
null, entityStore );
 
                assert.throws(
                        function() {
-                               viewFactory.getEntityView( getEntityStub( 
'unknown' ) );
+                               viewFactory.getEntityView( null, getEntityStub( 
'unknown' ) );
                        },
                        new Error( 'View unknownview does not exist' )
                );
@@ -51,7 +51,7 @@
                        $dom = $( '<div/>' ),
                        FooView = $dom.fooview = $.wikibase.fooview = 
sinon.spy();
 
-               viewFactory.getEntityView( entity, $dom );
+               viewFactory.getEntityView( null, entity, $dom );
 
                sinon.assert.calledWith( FooView, sinon.match( {
                        buildEntityTermsView: sinon.match.func,
@@ -70,7 +70,7 @@
                sinon.spy( $.wikibase, 'sitelinkgrouplistview' );
                $dom.sitelinkgrouplistview = $.wikibase.sitelinkgrouplistview;
 
-               viewFactory.getSitelinkGroupListView( sitelinkSet, $dom );
+               viewFactory.getSitelinkGroupListView( null, sitelinkSet, $dom );
 
                sinon.assert.calledWith( $.wikibase.sitelinkgrouplistview, 
sinon.match( {
                        value: sitelinkSet
@@ -89,7 +89,7 @@
                sinon.stub( $.wikibase, 'sitelinkgroupview' );
                $dom.sitelinkgroupview = $.wikibase.sitelinkgroupview;
 
-               viewFactory.getSitelinkGroupView( groupName, siteLinks, $dom );
+               viewFactory.getSitelinkGroupView( null, groupName, siteLinks, 
$dom );
 
                sinon.assert.calledWith( $.wikibase.sitelinkgroupview, 
sinon.match( {
                        groupName: groupName,
@@ -109,7 +109,7 @@
                sinon.spy( $.wikibase, 'sitelinklistview' );
                $dom.sitelinklistview = $.wikibase.sitelinklistview;
 
-               viewFactory.getSiteLinkListView( siteLinks, $dom );
+               viewFactory.getSiteLinkListView( null, siteLinks, $dom );
 
                sinon.assert.calledWith( $.wikibase.sitelinklistview, 
sinon.match( {
                        value: siteLinks,
@@ -127,7 +127,7 @@
 
                $dom.statementgrouplistview = sinon.stub( $.wikibase, 
'statementgrouplistview' );
 
-               viewFactory.getStatementGroupListView( entity, $dom );
+               viewFactory.getStatementGroupListView( null, entity, $dom );
 
                sinon.assert.calledWith( $.wikibase.statementgrouplistview, 
sinon.match( {
                        listItemAdapter: sinon.match.instanceOf( 
$.wikibase.listview.ListItemAdapter )
@@ -140,11 +140,11 @@
                assert.expect( 3 );
                var entityId = 'Q1',
                        entityIdHtmlFormatter = {},
-                       viewFactory = new ViewFactory( null, null, 
entityIdHtmlFormatter ),
+                       viewFactory = new ViewFactory( null, null, null, 
entityIdHtmlFormatter ),
                        ListItemAdapter = sinon.spy( $.wikibase.listview, 
'ListItemAdapter' ),
                        value = new wb.datamodel.StatementGroup( 'P1' );
 
-               viewFactory.getListItemAdapterForStatementGroupView( entityId );
+               viewFactory.getListItemAdapterForStatementGroupView( null, 
entityId );
 
                sinon.assert.calledWith(
                        ListItemAdapter,
@@ -182,7 +182,7 @@
                sinon.stub( $.wikibase.listview, 'ListItemAdapter' );
                sinon.stub( viewFactory, '_getView' );
 
-               viewFactory.getStatementListView( entityId, null, function () 
{}, value, $dom );
+               viewFactory.getStatementListView( null, entityId, null, 
function () {}, value, $dom );
 
                sinon.assert.calledWith(
                        viewFactory._getView,
@@ -210,7 +210,7 @@
                sinon.stub( $.wikibase.listview, 'ListItemAdapter' );
                $dom.statementlistview = sinon.stub( $.wikibase, 
'statementlistview' );
 
-               viewFactory.getStatementListView( entityId, null, function () 
{}, value, $dom );
+               viewFactory.getStatementListView( null, entityId, null, 
function () {}, value, $dom );
 
                sinon.assert.calledWith(
                        $.wikibase.statementlistview,
@@ -232,6 +232,7 @@
                                null,
                                null,
                                null,
+                               null,
                                entityIdPlainFormatter
                        ),
                        ListItemAdapter = sinon.stub( $.wikibase.listview, 
'ListItemAdapter' ),
@@ -240,7 +241,7 @@
 
                sinon.stub( viewFactory, '_getView' );
 
-               viewFactory.getListItemAdapterForStatementView( entityId, 
function () { return statement; } );
+               viewFactory.getListItemAdapterForStatementView( null, entityId, 
function () { return statement; } );
 
                sinon.assert.calledWith(
                        ListItemAdapter,
@@ -292,7 +293,7 @@
 
                sinon.stub( viewFactory, '_getView' );
 
-               viewFactory.getListItemAdapterForStatementView( entityId, 
function () {}, propertyId );
+               viewFactory.getListItemAdapterForStatementView( null, entityId, 
function () {}, propertyId );
 
                ListItemAdapter.args[0][0].getNewItem( value, dom );
 
@@ -320,7 +321,7 @@
 
                sinon.stub( viewFactory, '_getView' );
 
-               viewFactory.getListItemAdapterForStatementView( 'Q1', function 
() {}, null );
+               viewFactory.getListItemAdapterForStatementView( null, 'Q1', 
function () {}, null );
 
                ListItemAdapter.args[0][0].getNewItem( value, dom );
 
@@ -415,6 +416,7 @@
                        parserStore = {},
                        userLanguages = [],
                        viewFactory = new ViewFactory(
+                               null,
                                contentLanguages,
                                dataTypeStore,
                                entityIdHtmlFormatter,
@@ -489,6 +491,7 @@
                        parserStore = {},
                        userLanguages = [],
                        viewFactory = new ViewFactory(
+                               null,
                                contentLanguages,
                                dataTypeStore,
                                entityIdHtmlFormatter,
@@ -507,7 +510,7 @@
 
                sinon.spy( wb, 'ValueViewBuilder' );
 
-               viewFactory.getSnakView( false, options, value, $dom );
+               viewFactory.getSnakView( null, false, options, value, $dom );
 
                sinon.assert.calledWith(
                        $.wikibase.snakview,
@@ -546,6 +549,7 @@
                        messageProvider = { getMessage: function() { return 
message; } },
                        userLanguages = [],
                        viewFactory = new ViewFactory(
+                               null,
                                contentLanguages,
                                null,
                                null,
@@ -562,7 +566,7 @@
                sinon.spy( $.wikibase, 'entitytermsview' );
                $dom.entitytermsview = $.wikibase.entitytermsview;
 
-               viewFactory.getEntityTermsView( fingerprint, $dom );
+               viewFactory.getEntityTermsView( null, fingerprint, $dom );
 
                sinon.assert.calledWith( $.wikibase.entitytermsview, 
sinon.match( {
                        value: fingerprint,

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I6f934845058d7a376a7b87a99ad08d5d9de24dcf
Gerrit-PatchSet: 14
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Adrian Heine <m...@adrianheine.de>
Gerrit-Reviewer: Jonas Kress (WMDE) <jonas.kr...@wikimedia.de>
Gerrit-Reviewer: Thiemo Mättig (WMDE) <thiemo.maet...@wikimedia.de>
Gerrit-Reviewer: jenkins-bot <>

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

Reply via email to